aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2012-07-03 01:43:47 -0400
committerDavid S. Miller <davem@davemloft.net>2012-07-05 05:41:58 -0400
commit97cac0821af4474ec4ba3a9e7a36b98ed9b6db88 (patch)
tree49c33db384053e154ce37839d07eae93f9cd4eae /net
parent534cb283efef9fdbd9f70f4615054d26aa444dd6 (diff)
ipv6: Store route neighbour in rt6_info struct.
This makes for a simplified conversion away from dst_get_neighbour*(). All code outside of ipv6 will use neigh lookups via dst_neigh_lookup*(). Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/ipv6/ip6_output.c8
-rw-r--r--net/ipv6/route.c42
-rw-r--r--net/ipv6/xfrm6_policy.c1
3 files changed, 33 insertions, 18 deletions
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index c94e4aabe11b..6d9c0abc8c20 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -88,6 +88,7 @@ static int ip6_finish_output2(struct sk_buff *skb)
88 struct dst_entry *dst = skb_dst(skb); 88 struct dst_entry *dst = skb_dst(skb);
89 struct net_device *dev = dst->dev; 89 struct net_device *dev = dst->dev;
90 struct neighbour *neigh; 90 struct neighbour *neigh;
91 struct rt6_info *rt;
91 92
92 skb->protocol = htons(ETH_P_IPV6); 93 skb->protocol = htons(ETH_P_IPV6);
93 skb->dev = dev; 94 skb->dev = dev;
@@ -123,7 +124,8 @@ static int ip6_finish_output2(struct sk_buff *skb)
123 } 124 }
124 125
125 rcu_read_lock(); 126 rcu_read_lock();
126 neigh = dst_get_neighbour_noref(dst); 127 rt = (struct rt6_info *) dst;
128 neigh = rt->n;
127 if (neigh) { 129 if (neigh) {
128 int res = dst_neigh_output(dst, neigh, skb); 130 int res = dst_neigh_output(dst, neigh, skb);
129 131
@@ -944,6 +946,7 @@ static int ip6_dst_lookup_tail(struct sock *sk,
944 struct net *net = sock_net(sk); 946 struct net *net = sock_net(sk);
945#ifdef CONFIG_IPV6_OPTIMISTIC_DAD 947#ifdef CONFIG_IPV6_OPTIMISTIC_DAD
946 struct neighbour *n; 948 struct neighbour *n;
949 struct rt6_info *rt;
947#endif 950#endif
948 int err; 951 int err;
949 952
@@ -972,7 +975,8 @@ static int ip6_dst_lookup_tail(struct sock *sk,
972 * dst entry of the nexthop router 975 * dst entry of the nexthop router
973 */ 976 */
974 rcu_read_lock(); 977 rcu_read_lock();
975 n = dst_get_neighbour_noref(*dst); 978 rt = (struct rt6_info *) dst;
979 n = rt->n;
976 if (n && !(n->nud_state & NUD_VALID)) { 980 if (n && !(n->nud_state & NUD_VALID)) {
977 struct inet6_ifaddr *ifp; 981 struct inet6_ifaddr *ifp;
978 struct flowi6 fl_gw6; 982 struct flowi6 fl_gw6;
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 34b29881e22d..ceff71d24f8e 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -155,7 +155,7 @@ static int rt6_bind_neighbour(struct rt6_info *rt, struct net_device *dev)
155 if (IS_ERR(n)) 155 if (IS_ERR(n))
156 return PTR_ERR(n); 156 return PTR_ERR(n);
157 } 157 }
158 dst_set_neighbour(&rt->dst, n); 158 rt->n = n;
159 159
160 return 0; 160 return 0;
161} 161}
@@ -285,6 +285,9 @@ static void ip6_dst_destroy(struct dst_entry *dst)
285 struct rt6_info *rt = (struct rt6_info *)dst; 285 struct rt6_info *rt = (struct rt6_info *)dst;
286 struct inet6_dev *idev = rt->rt6i_idev; 286 struct inet6_dev *idev = rt->rt6i_idev;
287 287
288 if (rt->n)
289 neigh_release(rt->n);
290
288 if (!(rt->dst.flags & DST_HOST)) 291 if (!(rt->dst.flags & DST_HOST))
289 dst_destroy_metrics_generic(dst); 292 dst_destroy_metrics_generic(dst);
290 293
@@ -335,12 +338,19 @@ static void ip6_dst_ifdown(struct dst_entry *dst, struct net_device *dev,
335 struct net_device *loopback_dev = 338 struct net_device *loopback_dev =
336 dev_net(dev)->loopback_dev; 339 dev_net(dev)->loopback_dev;
337 340
338 if (dev != loopback_dev && idev && idev->dev == dev) { 341 if (dev != loopback_dev) {
339 struct inet6_dev *loopback_idev = 342 if (idev && idev->dev == dev) {
340 in6_dev_get(loopback_dev); 343 struct inet6_dev *loopback_idev =
341 if (loopback_idev) { 344 in6_dev_get(loopback_dev);
342 rt->rt6i_idev = loopback_idev; 345 if (loopback_idev) {
343 in6_dev_put(idev); 346 rt->rt6i_idev = loopback_idev;
347 in6_dev_put(idev);
348 }
349 }
350 if (rt->n && rt->n->dev == dev) {
351 rt->n->dev = loopback_dev;
352 dev_hold(loopback_dev);
353 dev_put(dev);
344 } 354 }
345 } 355 }
346} 356}
@@ -430,7 +440,7 @@ static void rt6_probe(struct rt6_info *rt)
430 * to no more than one per minute. 440 * to no more than one per minute.
431 */ 441 */
432 rcu_read_lock(); 442 rcu_read_lock();
433 neigh = rt ? dst_get_neighbour_noref(&rt->dst) : NULL; 443 neigh = rt ? rt->n : NULL;
434 if (!neigh || (neigh->nud_state & NUD_VALID)) 444 if (!neigh || (neigh->nud_state & NUD_VALID))
435 goto out; 445 goto out;
436 read_lock_bh(&neigh->lock); 446 read_lock_bh(&neigh->lock);
@@ -477,7 +487,7 @@ static inline int rt6_check_neigh(struct rt6_info *rt)
477 int m; 487 int m;
478 488
479 rcu_read_lock(); 489 rcu_read_lock();
480 neigh = dst_get_neighbour_noref(&rt->dst); 490 neigh = rt->n;
481 if (rt->rt6i_flags & RTF_NONEXTHOP || 491 if (rt->rt6i_flags & RTF_NONEXTHOP ||
482 !(rt->rt6i_flags & RTF_GATEWAY)) 492 !(rt->rt6i_flags & RTF_GATEWAY))
483 m = 1; 493 m = 1;
@@ -824,7 +834,7 @@ static struct rt6_info *rt6_alloc_clone(struct rt6_info *ort,
824 834
825 if (rt) { 835 if (rt) {
826 rt->rt6i_flags |= RTF_CACHE; 836 rt->rt6i_flags |= RTF_CACHE;
827 dst_set_neighbour(&rt->dst, neigh_clone(dst_get_neighbour_noref_raw(&ort->dst))); 837 rt->n = neigh_clone(ort->n);
828 } 838 }
829 return rt; 839 return rt;
830} 840}
@@ -858,7 +868,7 @@ restart:
858 dst_hold(&rt->dst); 868 dst_hold(&rt->dst);
859 read_unlock_bh(&table->tb6_lock); 869 read_unlock_bh(&table->tb6_lock);
860 870
861 if (!dst_get_neighbour_noref_raw(&rt->dst) && !(rt->rt6i_flags & RTF_NONEXTHOP)) 871 if (!rt->n && !(rt->rt6i_flags & RTF_NONEXTHOP))
862 nrt = rt6_alloc_cow(rt, &fl6->daddr, &fl6->saddr); 872 nrt = rt6_alloc_cow(rt, &fl6->daddr, &fl6->saddr);
863 else if (!(rt->dst.flags & DST_HOST)) 873 else if (!(rt->dst.flags & DST_HOST))
864 nrt = rt6_alloc_clone(rt, &fl6->daddr); 874 nrt = rt6_alloc_clone(rt, &fl6->daddr);
@@ -1178,7 +1188,7 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev,
1178 1188
1179 rt->dst.flags |= DST_HOST; 1189 rt->dst.flags |= DST_HOST;
1180 rt->dst.output = ip6_output; 1190 rt->dst.output = ip6_output;
1181 dst_set_neighbour(&rt->dst, neigh); 1191 rt->n = neigh;
1182 atomic_set(&rt->dst.__refcnt, 1); 1192 atomic_set(&rt->dst.__refcnt, 1);
1183 rt->rt6i_dst.addr = fl6->daddr; 1193 rt->rt6i_dst.addr = fl6->daddr;
1184 rt->rt6i_dst.plen = 128; 1194 rt->rt6i_dst.plen = 128;
@@ -1715,7 +1725,7 @@ void rt6_redirect(const struct in6_addr *dest, const struct in6_addr *src,
1715 dst_confirm(&rt->dst); 1725 dst_confirm(&rt->dst);
1716 1726
1717 /* Duplicate redirect: silently ignore. */ 1727 /* Duplicate redirect: silently ignore. */
1718 old_neigh = dst_get_neighbour_noref_raw(&rt->dst); 1728 old_neigh = rt->n;
1719 if (neigh == old_neigh) 1729 if (neigh == old_neigh)
1720 goto out; 1730 goto out;
1721 1731
@@ -1728,7 +1738,7 @@ void rt6_redirect(const struct in6_addr *dest, const struct in6_addr *src,
1728 nrt->rt6i_flags &= ~RTF_GATEWAY; 1738 nrt->rt6i_flags &= ~RTF_GATEWAY;
1729 1739
1730 nrt->rt6i_gateway = *(struct in6_addr *)neigh->primary_key; 1740 nrt->rt6i_gateway = *(struct in6_addr *)neigh->primary_key;
1731 dst_set_neighbour(&nrt->dst, neigh_clone(neigh)); 1741 nrt->n = neigh_clone(neigh);
1732 1742
1733 if (ip6_ins_rt(nrt)) 1743 if (ip6_ins_rt(nrt))
1734 goto out; 1744 goto out;
@@ -2442,7 +2452,7 @@ static int rt6_fill_node(struct net *net,
2442 goto nla_put_failure; 2452 goto nla_put_failure;
2443 2453
2444 rcu_read_lock(); 2454 rcu_read_lock();
2445 n = dst_get_neighbour_noref(&rt->dst); 2455 n = rt->n;
2446 if (n) { 2456 if (n) {
2447 if (nla_put(skb, RTA_GATEWAY, 16, &n->primary_key) < 0) { 2457 if (nla_put(skb, RTA_GATEWAY, 16, &n->primary_key) < 0) {
2448 rcu_read_unlock(); 2458 rcu_read_unlock();
@@ -2666,7 +2676,7 @@ static int rt6_info_route(struct rt6_info *rt, void *p_arg)
2666 seq_puts(m, "00000000000000000000000000000000 00 "); 2676 seq_puts(m, "00000000000000000000000000000000 00 ");
2667#endif 2677#endif
2668 rcu_read_lock(); 2678 rcu_read_lock();
2669 n = dst_get_neighbour_noref(&rt->dst); 2679 n = rt->n;
2670 if (n) { 2680 if (n) {
2671 seq_printf(m, "%pi6", n->primary_key); 2681 seq_printf(m, "%pi6", n->primary_key);
2672 } else { 2682 } else {
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index d7494845efbf..bb02038b822b 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -103,6 +103,7 @@ static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev,
103 103
104 /* Sheit... I remember I did this right. Apparently, 104 /* Sheit... I remember I did this right. Apparently,
105 * it was magically lost, so this code needs audit */ 105 * it was magically lost, so this code needs audit */
106 xdst->u.rt6.n = neigh_clone(rt->n);
106 xdst->u.rt6.rt6i_flags = rt->rt6i_flags & (RTF_ANYCAST | 107 xdst->u.rt6.rt6i_flags = rt->rt6i_flags & (RTF_ANYCAST |
107 RTF_LOCAL); 108 RTF_LOCAL);
108 xdst->u.rt6.rt6i_metric = rt->rt6i_metric; 109 xdst->u.rt6.rt6i_metric = rt->rt6i_metric;