@@ -3209,13 +3209,16 @@ static void add_v4_addrs(struct inet6_dev *idev)
3209
3209
struct in6_addr addr ;
3210
3210
struct net_device * dev ;
3211
3211
struct net * net = dev_net (idev -> dev );
3212
- int scope , plen ;
3212
+ int scope , plen , offset = 0 ;
3213
3213
u32 pflags = 0 ;
3214
3214
3215
3215
ASSERT_RTNL ();
3216
3216
3217
3217
memset (& addr , 0 , sizeof (struct in6_addr ));
3218
- memcpy (& addr .s6_addr32 [3 ], idev -> dev -> dev_addr , 4 );
3218
+ /* in case of IP6GRE the dev_addr is an IPv6 and therefore we use only the last 4 bytes */
3219
+ if (idev -> dev -> addr_len == sizeof (struct in6_addr ))
3220
+ offset = sizeof (struct in6_addr ) - 4 ;
3221
+ memcpy (& addr .s6_addr32 [3 ], idev -> dev -> dev_addr + offset , 4 );
3219
3222
3220
3223
if (!(idev -> dev -> flags & IFF_POINTOPOINT ) && idev -> dev -> type == ARPHRD_SIT ) {
3221
3224
scope = IPV6_ADDR_COMPATv4 ;
@@ -3526,13 +3529,7 @@ static void addrconf_gre_config(struct net_device *dev)
3526
3529
return ;
3527
3530
}
3528
3531
3529
- /* Generate the IPv6 link-local address using addrconf_addr_gen(),
3530
- * unless we have an IPv4 GRE device not bound to an IP address and
3531
- * which is in EUI64 mode (as __ipv6_isatap_ifid() would fail in this
3532
- * case). Such devices fall back to add_v4_addrs() instead.
3533
- */
3534
- if (!(dev -> type == ARPHRD_IPGRE && * (__be32 * )dev -> dev_addr == 0 &&
3535
- idev -> cnf .addr_gen_mode == IN6_ADDR_GEN_MODE_EUI64 )) {
3532
+ if (dev -> type == ARPHRD_ETHER ) {
3536
3533
addrconf_addr_gen (idev , true);
3537
3534
return ;
3538
3535
}
0 commit comments