@@ -3209,13 +3209,16 @@ static void add_v4_addrs(struct inet6_dev *idev)
32093209 struct in6_addr addr ;
32103210 struct net_device * dev ;
32113211 struct net * net = dev_net (idev -> dev );
3212- int scope , plen ;
3212+ int scope , plen , offset = 0 ;
32133213 u32 pflags = 0 ;
32143214
32153215 ASSERT_RTNL ();
32163216
32173217 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 );
32193222
32203223 if (!(idev -> dev -> flags & IFF_POINTOPOINT ) && idev -> dev -> type == ARPHRD_SIT ) {
32213224 scope = IPV6_ADDR_COMPATv4 ;
@@ -3526,13 +3529,7 @@ static void addrconf_gre_config(struct net_device *dev)
35263529 return ;
35273530 }
35283531
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 ) {
35363533 addrconf_addr_gen (idev , true);
35373534 return ;
35383535 }
0 commit comments