Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: Add ->neigh_lookup() operation to dst_ops

In the future dst entries will be neigh-less. In that environment we
need to have an easy transition point for current users of
dst->neighbour outside of the packet output fast path.

Signed-off-by: David S. Miller <davem@davemloft.net>

+52 -16
-9
include/net/arp.h
··· 38 38 return n; 39 39 } 40 40 41 - static inline struct neighbour *ipv4_neigh_lookup(struct neigh_table *tbl, struct net_device *dev, const __be32 *pkey) 42 - { 43 - struct neighbour *n = __ipv4_neigh_lookup(tbl, dev, 44 - *(__force u32 *)pkey); 45 - if (n) 46 - return n; 47 - return neigh_create(tbl, pkey, dev); 48 - } 49 - 50 41 extern void arp_init(void); 51 42 extern int arp_find(unsigned char *haddr, struct sk_buff *skb); 52 43 extern int arp_ioctl(struct net *net, unsigned int cmd, void __user *arg);
+5
include/net/dst.h
··· 387 387 } 388 388 } 389 389 390 + static inline struct neighbour *dst_neigh_lookup(const struct dst_entry *dst, const void *daddr) 391 + { 392 + return dst->ops->neigh_lookup(dst, daddr); 393 + } 394 + 390 395 static inline void dst_link_failure(struct sk_buff *skb) 391 396 { 392 397 struct dst_entry *dst = skb_dst(skb);
+1
include/net/dst_ops.h
··· 26 26 void (*link_failure)(struct sk_buff *); 27 27 void (*update_pmtu)(struct dst_entry *dst, u32 mtu); 28 28 int (*local_out)(struct sk_buff *skb); 29 + struct neighbour * (*neigh_lookup)(const struct dst_entry *dst, const void *daddr); 29 30 30 31 struct kmem_cache *kmem_cachep; 31 32
+6
net/bridge/br_netfilter.c
··· 109 109 return NULL; 110 110 } 111 111 112 + static struct neighbour *fake_neigh_lookup(const struct dst_entry *dst, const void *daddr) 113 + { 114 + return NULL; 115 + } 116 + 112 117 static struct dst_ops fake_dst_ops = { 113 118 .family = AF_INET, 114 119 .protocol = cpu_to_be16(ETH_P_IP), 115 120 .update_pmtu = fake_update_pmtu, 116 121 .cow_metrics = fake_cow_metrics, 122 + .neigh_lookup = fake_neigh_lookup, 117 123 }; 118 124 119 125 /*
+7
net/decnet/dn_route.c
··· 116 116 static struct dst_entry *dn_dst_negative_advice(struct dst_entry *); 117 117 static void dn_dst_link_failure(struct sk_buff *); 118 118 static void dn_dst_update_pmtu(struct dst_entry *dst, u32 mtu); 119 + static struct neighbour *dn_dst_neigh_lookup(const struct dst_entry *dst, const void *daddr); 119 120 static int dn_route_input(struct sk_buff *); 120 121 static void dn_run_flush(unsigned long dummy); 121 122 ··· 140 139 .negative_advice = dn_dst_negative_advice, 141 140 .link_failure = dn_dst_link_failure, 142 141 .update_pmtu = dn_dst_update_pmtu, 142 + .neigh_lookup = dn_dst_neigh_lookup, 143 143 }; 144 144 145 145 static void dn_dst_destroy(struct dst_entry *dst) ··· 827 825 static unsigned int dn_dst_default_mtu(const struct dst_entry *dst) 828 826 { 829 827 return dst->dev->mtu; 828 + } 829 + 830 + static struct neighbour *dn_dst_neigh_lookup(const struct dst_entry *dst, const void *daddr) 831 + { 832 + return __neigh_lookup_errno(&dn_neigh_table, daddr, dst->dev); 830 833 } 831 834 832 835 static int dn_rt_set_next_hop(struct dn_route *rt, struct dn_fib_res *res)
+19 -7
net/ipv4/route.c
··· 185 185 return p; 186 186 } 187 187 188 + static struct neighbour *ipv4_neigh_lookup(const struct dst_entry *dst, const void *daddr); 189 + 188 190 static struct dst_ops ipv4_dst_ops = { 189 191 .family = AF_INET, 190 192 .protocol = cpu_to_be16(ETH_P_IP), ··· 201 199 .link_failure = ipv4_link_failure, 202 200 .update_pmtu = ip_rt_update_pmtu, 203 201 .local_out = __ip_local_out, 202 + .neigh_lookup = ipv4_neigh_lookup, 204 203 }; 205 204 206 205 #define ECN_OR_COST(class) TC_PRIO_##class ··· 1011 1008 return length >> FRACT_BITS; 1012 1009 } 1013 1010 1014 - static int rt_bind_neighbour(struct rtable *rt) 1011 + static struct neighbour *ipv4_neigh_lookup(const struct dst_entry *dst, const void *daddr) 1015 1012 { 1016 - static const __be32 inaddr_any = 0; 1017 - struct net_device *dev = rt->dst.dev; 1018 1013 struct neigh_table *tbl = &arp_tbl; 1019 - const __be32 *nexthop; 1014 + static const __be32 inaddr_any = 0; 1015 + struct net_device *dev = dst->dev; 1016 + const __be32 *pkey = daddr; 1020 1017 struct neighbour *n; 1021 1018 1022 1019 #if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE) 1023 1020 if (dev->type == ARPHRD_ATM) 1024 1021 tbl = clip_tbl_hook; 1025 1022 #endif 1026 - nexthop = &rt->rt_gateway; 1027 1023 if (dev->flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) 1028 - nexthop = &inaddr_any; 1029 - n = ipv4_neigh_lookup(tbl, dev, nexthop); 1024 + pkey = &inaddr_any; 1025 + 1026 + n = __ipv4_neigh_lookup(tbl, dev, *(__force u32 *)pkey); 1027 + if (n) 1028 + return n; 1029 + return neigh_create(tbl, pkey, dev); 1030 + } 1031 + 1032 + static int rt_bind_neighbour(struct rtable *rt) 1033 + { 1034 + struct neighbour *n = ipv4_neigh_lookup(&rt->dst, &rt->rt_gateway); 1030 1035 if (IS_ERR(n)) 1031 1036 return PTR_ERR(n); 1032 1037 dst_set_neighbour(&rt->dst, n); ··· 2745 2734 .default_advmss = ipv4_default_advmss, 2746 2735 .update_pmtu = ipv4_rt_blackhole_update_pmtu, 2747 2736 .cow_metrics = ipv4_rt_blackhole_cow_metrics, 2737 + .neigh_lookup = ipv4_neigh_lookup, 2748 2738 }; 2749 2739 2750 2740 struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_orig)
+7
net/ipv6/route.c
··· 127 127 return p; 128 128 } 129 129 130 + static struct neighbour *ip6_neigh_lookup(const struct dst_entry *dst, const void *daddr) 131 + { 132 + return __neigh_lookup_errno(&nd_tbl, daddr, dst->dev); 133 + } 134 + 130 135 static struct dst_ops ip6_dst_ops_template = { 131 136 .family = AF_INET6, 132 137 .protocol = cpu_to_be16(ETH_P_IPV6), ··· 147 142 .link_failure = ip6_link_failure, 148 143 .update_pmtu = ip6_rt_update_pmtu, 149 144 .local_out = __ip6_local_out, 145 + .neigh_lookup = ip6_neigh_lookup, 150 146 }; 151 147 152 148 static unsigned int ip6_blackhole_default_mtu(const struct dst_entry *dst) ··· 174 168 .default_advmss = ip6_default_advmss, 175 169 .update_pmtu = ip6_rt_blackhole_update_pmtu, 176 170 .cow_metrics = ip6_rt_blackhole_cow_metrics, 171 + .neigh_lookup = ip6_neigh_lookup, 177 172 }; 178 173 179 174 static const u32 ip6_template_metrics[RTAX_MAX] = {
+7
net/xfrm/xfrm_policy.c
··· 2385 2385 return dst_mtu(dst->path); 2386 2386 } 2387 2387 2388 + static struct neighbour *xfrm_neigh_lookup(const struct dst_entry *dst, const void *daddr) 2389 + { 2390 + return dst_neigh_lookup(dst->path, daddr); 2391 + } 2392 + 2388 2393 int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo) 2389 2394 { 2390 2395 struct net *net; ··· 2415 2410 dst_ops->negative_advice = xfrm_negative_advice; 2416 2411 if (likely(dst_ops->link_failure == NULL)) 2417 2412 dst_ops->link_failure = xfrm_link_failure; 2413 + if (likely(dst_ops->neigh_lookup == NULL)) 2414 + dst_ops->neigh_lookup = xfrm_neigh_lookup; 2418 2415 if (likely(afinfo->garbage_collect == NULL)) 2419 2416 afinfo->garbage_collect = __xfrm_garbage_collect; 2420 2417 xfrm_policy_afinfo[afinfo->family] = afinfo;