diff options
author | Nicolas Dichtel <nicolas.dichtel@6wind.com> | 2013-11-14 07:51:06 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-11-14 16:59:16 -0500 |
commit | f0e2acfa30920fc9b902734baba71e58f2fd844a (patch) | |
tree | b1170691501d18748d1aa47c005e9042be803861 /net/ipv6 | |
parent | 929c9cf310565a97ec9bc685abbfeaed5fceb557 (diff) |
sit: link local routes are missing
When a link local address was added to a sit interface, the corresponding route
was not configured. This breaks routing protocols that use the link local
address, like OSPFv3.
To ease the code reading, I remove sit_route_add(), which only adds v4 mapped
routes, and add this kind of route directly in sit_add_v4_addrs(). Thus link
local and v4 mapped routes are configured in the same place.
Reported-by: Li Hongjun <hongjun.li@6wind.com>
Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/addrconf.c | 24 |
1 files changed, 5 insertions, 19 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 27fedc3e4449..5969ca19a6c8 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -1982,23 +1982,6 @@ static void addrconf_add_mroute(struct net_device *dev) | |||
1982 | ip6_route_add(&cfg); | 1982 | ip6_route_add(&cfg); |
1983 | } | 1983 | } |
1984 | 1984 | ||
1985 | #if IS_ENABLED(CONFIG_IPV6_SIT) | ||
1986 | static void sit_route_add(struct net_device *dev) | ||
1987 | { | ||
1988 | struct fib6_config cfg = { | ||
1989 | .fc_table = RT6_TABLE_MAIN, | ||
1990 | .fc_metric = IP6_RT_PRIO_ADDRCONF, | ||
1991 | .fc_ifindex = dev->ifindex, | ||
1992 | .fc_dst_len = 96, | ||
1993 | .fc_flags = RTF_UP | RTF_NONEXTHOP, | ||
1994 | .fc_nlinfo.nl_net = dev_net(dev), | ||
1995 | }; | ||
1996 | |||
1997 | /* prefix length - 96 bits "::d.d.d.d" */ | ||
1998 | ip6_route_add(&cfg); | ||
1999 | } | ||
2000 | #endif | ||
2001 | |||
2002 | static struct inet6_dev *addrconf_add_dev(struct net_device *dev) | 1985 | static struct inet6_dev *addrconf_add_dev(struct net_device *dev) |
2003 | { | 1986 | { |
2004 | struct inet6_dev *idev; | 1987 | struct inet6_dev *idev; |
@@ -2529,6 +2512,7 @@ static void sit_add_v4_addrs(struct inet6_dev *idev) | |||
2529 | struct net_device *dev; | 2512 | struct net_device *dev; |
2530 | struct net *net = dev_net(idev->dev); | 2513 | struct net *net = dev_net(idev->dev); |
2531 | int scope, plen; | 2514 | int scope, plen; |
2515 | u32 pflags = 0; | ||
2532 | 2516 | ||
2533 | ASSERT_RTNL(); | 2517 | ASSERT_RTNL(); |
2534 | 2518 | ||
@@ -2542,10 +2526,12 @@ static void sit_add_v4_addrs(struct inet6_dev *idev) | |||
2542 | } else { | 2526 | } else { |
2543 | scope = IPV6_ADDR_COMPATv4; | 2527 | scope = IPV6_ADDR_COMPATv4; |
2544 | plen = 96; | 2528 | plen = 96; |
2529 | pflags |= RTF_NONEXTHOP; | ||
2545 | } | 2530 | } |
2546 | 2531 | ||
2547 | if (addr.s6_addr32[3]) { | 2532 | if (addr.s6_addr32[3]) { |
2548 | add_addr(idev, &addr, plen, scope); | 2533 | add_addr(idev, &addr, plen, scope); |
2534 | addrconf_prefix_route(&addr, plen, idev->dev, 0, pflags); | ||
2549 | return; | 2535 | return; |
2550 | } | 2536 | } |
2551 | 2537 | ||
@@ -2569,6 +2555,8 @@ static void sit_add_v4_addrs(struct inet6_dev *idev) | |||
2569 | } | 2555 | } |
2570 | 2556 | ||
2571 | add_addr(idev, &addr, plen, flag); | 2557 | add_addr(idev, &addr, plen, flag); |
2558 | addrconf_prefix_route(&addr, plen, idev->dev, 0, | ||
2559 | pflags); | ||
2572 | } | 2560 | } |
2573 | } | 2561 | } |
2574 | } | 2562 | } |
@@ -2704,8 +2692,6 @@ static void addrconf_sit_config(struct net_device *dev) | |||
2704 | 2692 | ||
2705 | if (dev->flags&IFF_POINTOPOINT) | 2693 | if (dev->flags&IFF_POINTOPOINT) |
2706 | addrconf_add_mroute(dev); | 2694 | addrconf_add_mroute(dev); |
2707 | else | ||
2708 | sit_route_add(dev); | ||
2709 | } | 2695 | } |
2710 | #endif | 2696 | #endif |
2711 | 2697 | ||