sit: link local routes are missing
authorNicolas Dichtel <nicolas.dichtel@6wind.com>
Thu, 14 Nov 2013 12:51:06 +0000 (13:51 +0100)
committerDavid S. Miller <davem@davemloft.net>
Thu, 14 Nov 2013 21:59:16 +0000 (16:59 -0500)
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>
net/ipv6/addrconf.c

index 27fedc3e4449c6550e69eca6a77d2b8bcb03034d..5969ca19a6c82d186d568ecb170e8fb747f55c5a 100644 (file)
@@ -1982,23 +1982,6 @@ static void addrconf_add_mroute(struct net_device *dev)
        ip6_route_add(&cfg);
 }
 
-#if IS_ENABLED(CONFIG_IPV6_SIT)
-static void sit_route_add(struct net_device *dev)
-{
-       struct fib6_config cfg = {
-               .fc_table = RT6_TABLE_MAIN,
-               .fc_metric = IP6_RT_PRIO_ADDRCONF,
-               .fc_ifindex = dev->ifindex,
-               .fc_dst_len = 96,
-               .fc_flags = RTF_UP | RTF_NONEXTHOP,
-               .fc_nlinfo.nl_net = dev_net(dev),
-       };
-
-       /* prefix length - 96 bits "::d.d.d.d" */
-       ip6_route_add(&cfg);
-}
-#endif
-
 static struct inet6_dev *addrconf_add_dev(struct net_device *dev)
 {
        struct inet6_dev *idev;
@@ -2529,6 +2512,7 @@ static void sit_add_v4_addrs(struct inet6_dev *idev)
        struct net_device *dev;
        struct net *net = dev_net(idev->dev);
        int scope, plen;
+       u32 pflags = 0;
 
        ASSERT_RTNL();
 
@@ -2542,10 +2526,12 @@ static void sit_add_v4_addrs(struct inet6_dev *idev)
        } else {
                scope = IPV6_ADDR_COMPATv4;
                plen = 96;
+               pflags |= RTF_NONEXTHOP;
        }
 
        if (addr.s6_addr32[3]) {
                add_addr(idev, &addr, plen, scope);
+               addrconf_prefix_route(&addr, plen, idev->dev, 0, pflags);
                return;
        }
 
@@ -2569,6 +2555,8 @@ static void sit_add_v4_addrs(struct inet6_dev *idev)
                                }
 
                                add_addr(idev, &addr, plen, flag);
+                               addrconf_prefix_route(&addr, plen, idev->dev, 0,
+                                                     pflags);
                        }
                }
        }
@@ -2704,8 +2692,6 @@ static void addrconf_sit_config(struct net_device *dev)
 
        if (dev->flags&IFF_POINTOPOINT)
                addrconf_add_mroute(dev);
-       else
-               sit_route_add(dev);
 }
 #endif