Skip to content

Commit e5dd729

Browse files
ordexdavem330
authored andcommitted
ip/ip6_gre: use the same logic as SIT interfaces when computing v6LL address
GRE interfaces are not Ether-like and therefore it is not possible to generate the v6LL address the same way as (for example) GRETAP devices. With default settings, a GRE interface will attempt generating its v6LL address using the EUI64 approach, but this will fail when the local endpoint of the GRE tunnel is set to "any". In this case the GRE interface will end up with no v6LL address, thus violating RFC4291. SIT interfaces already implement a different logic to ensure that a v6LL address is always computed. Change the GRE v6LL generation logic to follow the same approach as SIT. This way GRE interfaces will always have a v6LL address as well. Behaviour of GRETAP interfaces has not been changed as they behave like classic Ether-like interfaces. To avoid code duplication sit_add_v4_addrs() has been renamed to add_v4_addrs() and adapted to handle also the IP6GRE/GRE cases. Signed-off-by: Antonio Quartulli <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 81d0885 commit e5dd729

File tree

1 file changed

+18
-10
lines changed

1 file changed

+18
-10
lines changed

net/ipv6/addrconf.c

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3092,19 +3092,22 @@ static void add_addr(struct inet6_dev *idev, const struct in6_addr *addr,
30923092
}
30933093
}
30943094

3095-
#if IS_ENABLED(CONFIG_IPV6_SIT)
3096-
static void sit_add_v4_addrs(struct inet6_dev *idev)
3095+
#if IS_ENABLED(CONFIG_IPV6_SIT) || IS_ENABLED(CONFIG_NET_IPGRE) || IS_ENABLED(CONFIG_IPV6_GRE)
3096+
static void add_v4_addrs(struct inet6_dev *idev)
30973097
{
30983098
struct in6_addr addr;
30993099
struct net_device *dev;
31003100
struct net *net = dev_net(idev->dev);
3101-
int scope, plen;
3101+
int scope, plen, offset = 0;
31023102
u32 pflags = 0;
31033103

31043104
ASSERT_RTNL();
31053105

31063106
memset(&addr, 0, sizeof(struct in6_addr));
3107-
memcpy(&addr.s6_addr32[3], idev->dev->dev_addr, 4);
3107+
/* in case of IP6GRE the dev_addr is an IPv6 and therefore we use only the last 4 bytes */
3108+
if (idev->dev->addr_len == sizeof(struct in6_addr))
3109+
offset = sizeof(struct in6_addr) - 4;
3110+
memcpy(&addr.s6_addr32[3], idev->dev->dev_addr + offset, 4);
31083111

31093112
if (idev->dev->flags&IFF_POINTOPOINT) {
31103113
addr.s6_addr32[0] = htonl(0xfe800000);
@@ -3342,8 +3345,6 @@ static void addrconf_dev_config(struct net_device *dev)
33423345
(dev->type != ARPHRD_IEEE1394) &&
33433346
(dev->type != ARPHRD_TUNNEL6) &&
33443347
(dev->type != ARPHRD_6LOWPAN) &&
3345-
(dev->type != ARPHRD_IP6GRE) &&
3346-
(dev->type != ARPHRD_IPGRE) &&
33473348
(dev->type != ARPHRD_TUNNEL) &&
33483349
(dev->type != ARPHRD_NONE) &&
33493350
(dev->type != ARPHRD_RAWIP)) {
@@ -3391,14 +3392,14 @@ static void addrconf_sit_config(struct net_device *dev)
33913392
return;
33923393
}
33933394

3394-
sit_add_v4_addrs(idev);
3395+
add_v4_addrs(idev);
33953396

33963397
if (dev->flags&IFF_POINTOPOINT)
33973398
addrconf_add_mroute(dev);
33983399
}
33993400
#endif
34003401

3401-
#if IS_ENABLED(CONFIG_NET_IPGRE)
3402+
#if IS_ENABLED(CONFIG_NET_IPGRE) || IS_ENABLED(CONFIG_IPV6_GRE)
34023403
static void addrconf_gre_config(struct net_device *dev)
34033404
{
34043405
struct inet6_dev *idev;
@@ -3411,7 +3412,13 @@ static void addrconf_gre_config(struct net_device *dev)
34113412
return;
34123413
}
34133414

3414-
addrconf_addr_gen(idev, true);
3415+
if (dev->type == ARPHRD_ETHER) {
3416+
addrconf_addr_gen(idev, true);
3417+
return;
3418+
}
3419+
3420+
add_v4_addrs(idev);
3421+
34153422
if (dev->flags & IFF_POINTOPOINT)
34163423
addrconf_add_mroute(dev);
34173424
}
@@ -3587,7 +3594,8 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
35873594
addrconf_sit_config(dev);
35883595
break;
35893596
#endif
3590-
#if IS_ENABLED(CONFIG_NET_IPGRE)
3597+
#if IS_ENABLED(CONFIG_NET_IPGRE) || IS_ENABLED(CONFIG_IPV6_GRE)
3598+
case ARPHRD_IP6GRE:
35913599
case ARPHRD_IPGRE:
35923600
addrconf_gre_config(dev);
35933601
break;

0 commit comments

Comments
 (0)