diff options
Diffstat (limited to 'net/ipv6/addrconf.c')
-rw-r--r-- | net/ipv6/addrconf.c | 27 |
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); |
155 | static int addrconf_ifdown(struct net_device *dev, int how); | 155 | static int addrconf_ifdown(struct net_device *dev, int how); |
156 | 156 | ||
157 | static 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 | |||
157 | static void addrconf_dad_start(struct inet6_ifaddr *ifp); | 162 | static void addrconf_dad_start(struct inet6_ifaddr *ifp); |
158 | static void addrconf_dad_timer(unsigned long data); | 163 | static void addrconf_dad_timer(unsigned long data); |
159 | static void addrconf_dad_completed(struct inet6_ifaddr *ifp); | 164 | static 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 */ | ||
254 | static inline int addrconf_is_prefix_route(const struct rt6_info *rt) | ||
255 | { | ||
256 | return (rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0; | ||
257 | } | ||
258 | |||
259 | static void addrconf_del_timer(struct inet6_ifaddr *ifp) | 258 | static 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; |