aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/addrconf.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/addrconf.c')
-rw-r--r--net/ipv6/addrconf.c27
1 files changed, 12 insertions, 15 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 408cac4ae00a..420e56326384 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -154,6 +154,11 @@ static void addrconf_type_change(struct net_device *dev,
154 unsigned long event); 154 unsigned long event);
155static int addrconf_ifdown(struct net_device *dev, int how); 155static int addrconf_ifdown(struct net_device *dev, int how);
156 156
157static struct rt6_info *addrconf_get_prefix_route(const struct in6_addr *pfx,
158 int plen,
159 const struct net_device *dev,
160 u32 flags, u32 noflags);
161
157static void addrconf_dad_start(struct inet6_ifaddr *ifp); 162static void addrconf_dad_start(struct inet6_ifaddr *ifp);
158static void addrconf_dad_timer(unsigned long data); 163static void addrconf_dad_timer(unsigned long data);
159static void addrconf_dad_completed(struct inet6_ifaddr *ifp); 164static void addrconf_dad_completed(struct inet6_ifaddr *ifp);
@@ -250,12 +255,6 @@ static inline bool addrconf_qdisc_ok(const struct net_device *dev)
250 return !qdisc_tx_is_noop(dev); 255 return !qdisc_tx_is_noop(dev);
251} 256}
252 257
253/* Check if a route is valid prefix route */
254static inline int addrconf_is_prefix_route(const struct rt6_info *rt)
255{
256 return (rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0;
257}
258
259static void addrconf_del_timer(struct inet6_ifaddr *ifp) 258static void addrconf_del_timer(struct inet6_ifaddr *ifp)
260{ 259{
261 if (del_timer(&ifp->timer)) 260 if (del_timer(&ifp->timer))
@@ -941,17 +940,15 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp)
941 if ((ifp->flags & IFA_F_PERMANENT) && onlink < 1) { 940 if ((ifp->flags & IFA_F_PERMANENT) && onlink < 1) {
942 struct in6_addr prefix; 941 struct in6_addr prefix;
943 struct rt6_info *rt; 942 struct rt6_info *rt;
944 struct net *net = dev_net(ifp->idev->dev);
945 struct flowi6 fl6 = {};
946 943
947 ipv6_addr_prefix(&prefix, &ifp->addr, ifp->prefix_len); 944 ipv6_addr_prefix(&prefix, &ifp->addr, ifp->prefix_len);
948 fl6.flowi6_oif = ifp->idev->dev->ifindex;
949 fl6.daddr = prefix;
950 rt = (struct rt6_info *)ip6_route_lookup(net, &fl6,
951 RT6_LOOKUP_F_IFACE);
952 945
953 if (rt != net->ipv6.ip6_null_entry && 946 rt = addrconf_get_prefix_route(&prefix,
954 addrconf_is_prefix_route(rt)) { 947 ifp->prefix_len,
948 ifp->idev->dev,
949 0, RTF_GATEWAY | RTF_DEFAULT);
950
951 if (rt) {
955 if (onlink == 0) { 952 if (onlink == 0) {
956 ip6_del_rt(rt); 953 ip6_del_rt(rt);
957 rt = NULL; 954 rt = NULL;
@@ -1877,7 +1874,7 @@ static struct rt6_info *addrconf_get_prefix_route(const struct in6_addr *pfx,
1877 continue; 1874 continue;
1878 if ((rt->rt6i_flags & flags) != flags) 1875 if ((rt->rt6i_flags & flags) != flags)
1879 continue; 1876 continue;
1880 if ((noflags != 0) && ((rt->rt6i_flags & flags) != 0)) 1877 if ((rt->rt6i_flags & noflags) != 0)
1881 continue; 1878 continue;
1882 dst_hold(&rt->dst); 1879 dst_hold(&rt->dst);
1883 break; 1880 break;