Skip to contentSkip to conversation

ipv6 route: Do not attach neighbour on route.

RFC In review YOSHIFUJI Hideaki 2 participants 2 messages Jan 14, 2013 – Jan 15, 2013

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

RFC 1/1 ipv6 route: Do not attach neighbour on route.

Not tested, just an RFC.
Depends on previous new_neigh removal from netevent patch (sorry).

--yoshfuji

---
 include/net/ip6_fib.h   |    2 -
 include/net/ip6_route.h |    8 ++++
 net/ipv6/ip6_output.c   |   20 ++++++--
 net/ipv6/route.c        |  120 ++++++++++++-----------------------------------
 net/ipv6/xfrm6_policy.c |    1 -
 5 files changed, 52 insertions(+), 99 deletions(-)
include/net/ip6_fib.h +0 -2
index fdc48a9..6919a50 100644
@@ -89,8 +89,6 @@ struct fib6_table;
 struct rt6_info {
 	struct dst_entry		dst;
 
-	struct neighbour		*n;
-
 	/*
 	 * Tail elements of dst_entry (__refcnt etc.)
 	 * and these elements (rarely used in hot path) are in
include/net/ip6_route.h +8 -0
index 27d8318..439928d 100644
@@ -21,6 +21,7 @@ struct route_info {
 #include <net/flow.h>
 #include <net/ip6_fib.h>
 #include <net/sock.h>
+#include <linux/route.h>
 #include <linux/ip.h>
 #include <linux/ipv6.h>
 
@@ -137,6 +138,13 @@ extern void ip6_sk_update_pmtu(struct sk_buff *skb, struct sock *sk,
 extern void ip6_redirect(struct sk_buff *skb, struct net *net, int oif, u32 mark);
 extern void ip6_sk_redirect(struct sk_buff *skb, struct sock *sk);
 
+static inline struct in6_addr *rt6_nexthop(struct rt6_info *rt, struct in6_addr *dst)
+{
+	if (rt->rt6i_flags & RTF_GATEWAY)
+		return &rt->rt6i_gateway;
+	return dst;
+}
+
 struct netlink_callback;
 
 struct rt6_rtnl_dump_arg {
net/ipv6/ip6_output.c +15 -5
index 9581ffa..af2376d 100644
@@ -123,10 +123,17 @@ static int ip6_finish_output2(struct sk_buff *skb)
 				skb->len);
 	}
 
+
 	rt = (struct rt6_info *) dst;
-	neigh = rt->n;
-	if (neigh)
-		return dst_neigh_output(dst, neigh, skb);
+	rcu_read_lock_bh();
+	neigh = __ipv6_neigh_lookup_noref(rt->rt6i_idev->dev,
+					  rt6_nexthop(rt, &ipv6_hdr(skb)->daddr));
+	if (neigh) {
+		int ret = dst_neigh_output(dst, neigh, skb);
+		rcu_read_unlock_bh();
+		return ret;
+	}
+	rcu_read_unlock_bh();
 
 	IP6_INC_STATS_BH(dev_net(dst->dev),
 			 ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES);
@@ -912,9 +919,12 @@ static int ip6_dst_lookup_tail(struct sock *sk,
 	 * dst entry and replace it instead with the
 	 * dst entry of the nexthop router
 	 */
+	rcu_read_lock_bh();
 	rt = (struct rt6_info *) *dst;
-	n = rt->n;
-	if (n && !(n->nud_state & NUD_VALID)) {
+	n = __ipv6_neigh_lookup_noref(rt->rt6i_idev->dev, rt6_nexthop(rt, &fl6->daddr));
+	err = n && n->nud_state & NUD_VALID ? 0 : -EINVAL;
+	rcu_read_unlock_bh();
+	if (!err) {
 		struct inet6_ifaddr *ifp;
 		struct flowi6 fl_gw6;
 		int redirect;
net/ipv6/route.c +29 -91

263 lines not on this page · raw message

net/ipv6/xfrm6_policy.c +0 -1
index c984413..1282737 100644
@@ -110,7 +110,6 @@ static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev,
 
 	/* Sheit... I remember I did this right. Apparently,
 	 * it was magically lost, so this code needs audit */
-	xdst->u.rt6.n = neigh_clone(rt->n);
 	xdst->u.rt6.rt6i_flags = rt->rt6i_flags & (RTF_ANYCAST |
 						   RTF_LOCAL);
 	xdst->u.rt6.rt6i_metric = rt->rt6i_metric;
Signature · 1 line
1.7.9.5
#1 lore raw
Quoted 3 lines · YOSHIFUJI Hideaki

Not tested, just an RFC.
Depends on previous new_neigh removal from netevent patch (sorry).

Forgot to define __ipv6_neigh_lookup_noref()?