aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/arp.h9
-rw-r--r--include/net/dst.h5
-rw-r--r--include/net/dst_ops.h1
-rw-r--r--net/bridge/br_netfilter.c6
-rw-r--r--net/decnet/dn_route.c7
-rw-r--r--net/ipv4/route.c26
-rw-r--r--net/ipv6/route.c7
-rw-r--r--net/xfrm/xfrm_policy.c7
8 files changed, 52 insertions, 16 deletions
diff --git a/include/net/arp.h b/include/net/arp.h
index 5e669e6ffb42..4979af8b1559 100644
--- a/include/net/arp.h
+++ b/include/net/arp.h
@@ -38,15 +38,6 @@ static inline struct neighbour *__ipv4_neigh_lookup(struct neigh_table *tbl, str
38 return n; 38 return n;
39} 39}
40 40
41static 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
50extern void arp_init(void); 41extern void arp_init(void);
51extern int arp_find(unsigned char *haddr, struct sk_buff *skb); 42extern int arp_find(unsigned char *haddr, struct sk_buff *skb);
52extern int arp_ioctl(struct net *net, unsigned int cmd, void __user *arg); 43extern int arp_ioctl(struct net *net, unsigned int cmd, void __user *arg);
diff --git a/include/net/dst.h b/include/net/dst.h
index 8147206eefb9..29e255796ce1 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -387,6 +387,11 @@ static inline void dst_confirm(struct dst_entry *dst)
387 } 387 }
388} 388}
389 389
390static 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
390static inline void dst_link_failure(struct sk_buff *skb) 395static inline void dst_link_failure(struct sk_buff *skb)
391{ 396{
392 struct dst_entry *dst = skb_dst(skb); 397 struct dst_entry *dst = skb_dst(skb);
diff --git a/include/net/dst_ops.h b/include/net/dst_ops.h
index dc0746328947..9adb99845a56 100644
--- a/include/net/dst_ops.h
+++ b/include/net/dst_ops.h
@@ -26,6 +26,7 @@ struct dst_ops {
26 void (*link_failure)(struct sk_buff *); 26 void (*link_failure)(struct sk_buff *);
27 void (*update_pmtu)(struct dst_entry *dst, u32 mtu); 27 void (*update_pmtu)(struct dst_entry *dst, u32 mtu);
28 int (*local_out)(struct sk_buff *skb); 28 int (*local_out)(struct sk_buff *skb);
29 struct neighbour * (*neigh_lookup)(const struct dst_entry *dst, const void *daddr);
29 30
30 struct kmem_cache *kmem_cachep; 31 struct kmem_cache *kmem_cachep;
31 32
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index b1a5f9777b7e..d6ec3720c77e 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -109,11 +109,17 @@ static u32 *fake_cow_metrics(struct dst_entry *dst, unsigned long old)
109 return NULL; 109 return NULL;
110} 110}
111 111
112static struct neighbour *fake_neigh_lookup(const struct dst_entry *dst, const void *daddr)
113{
114 return NULL;
115}
116
112static struct dst_ops fake_dst_ops = { 117static struct dst_ops fake_dst_ops = {
113 .family = AF_INET, 118 .family = AF_INET,
114 .protocol = cpu_to_be16(ETH_P_IP), 119 .protocol = cpu_to_be16(ETH_P_IP),
115 .update_pmtu = fake_update_pmtu, 120 .update_pmtu = fake_update_pmtu,
116 .cow_metrics = fake_cow_metrics, 121 .cow_metrics = fake_cow_metrics,
122 .neigh_lookup = fake_neigh_lookup,
117}; 123};
118 124
119/* 125/*
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c
index 9bd45fcb3b8e..43450c100226 100644
--- a/net/decnet/dn_route.c
+++ b/net/decnet/dn_route.c
@@ -116,6 +116,7 @@ static void dn_dst_destroy(struct dst_entry *);
116static struct dst_entry *dn_dst_negative_advice(struct dst_entry *); 116static struct dst_entry *dn_dst_negative_advice(struct dst_entry *);
117static void dn_dst_link_failure(struct sk_buff *); 117static void dn_dst_link_failure(struct sk_buff *);
118static void dn_dst_update_pmtu(struct dst_entry *dst, u32 mtu); 118static void dn_dst_update_pmtu(struct dst_entry *dst, u32 mtu);
119static struct neighbour *dn_dst_neigh_lookup(const struct dst_entry *dst, const void *daddr);
119static int dn_route_input(struct sk_buff *); 120static int dn_route_input(struct sk_buff *);
120static void dn_run_flush(unsigned long dummy); 121static void dn_run_flush(unsigned long dummy);
121 122
@@ -139,6 +140,7 @@ static struct dst_ops dn_dst_ops = {
139 .negative_advice = dn_dst_negative_advice, 140 .negative_advice = dn_dst_negative_advice,
140 .link_failure = dn_dst_link_failure, 141 .link_failure = dn_dst_link_failure,
141 .update_pmtu = dn_dst_update_pmtu, 142 .update_pmtu = dn_dst_update_pmtu,
143 .neigh_lookup = dn_dst_neigh_lookup,
142}; 144};
143 145
144static void dn_dst_destroy(struct dst_entry *dst) 146static void dn_dst_destroy(struct dst_entry *dst)
@@ -827,6 +829,11 @@ static unsigned int dn_dst_default_mtu(const struct dst_entry *dst)
827 return dst->dev->mtu; 829 return dst->dev->mtu;
828} 830}
829 831
832static struct neighbour *dn_dst_neigh_lookup(const struct dst_entry *dst, const void *daddr)
833{
834 return __neigh_lookup_errno(&dn_neigh_table, daddr, dst->dev);
835}
836
830static int dn_rt_set_next_hop(struct dn_route *rt, struct dn_fib_res *res) 837static int dn_rt_set_next_hop(struct dn_route *rt, struct dn_fib_res *res)
831{ 838{
832 struct dn_fib_info *fi = res->fi; 839 struct dn_fib_info *fi = res->fi;
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 1d4cd3b4fd69..33137307d52a 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -185,6 +185,8 @@ static u32 *ipv4_cow_metrics(struct dst_entry *dst, unsigned long old)
185 return p; 185 return p;
186} 186}
187 187
188static struct neighbour *ipv4_neigh_lookup(const struct dst_entry *dst, const void *daddr);
189
188static struct dst_ops ipv4_dst_ops = { 190static struct dst_ops ipv4_dst_ops = {
189 .family = AF_INET, 191 .family = AF_INET,
190 .protocol = cpu_to_be16(ETH_P_IP), 192 .protocol = cpu_to_be16(ETH_P_IP),
@@ -199,6 +201,7 @@ static struct dst_ops ipv4_dst_ops = {
199 .link_failure = ipv4_link_failure, 201 .link_failure = ipv4_link_failure,
200 .update_pmtu = ip_rt_update_pmtu, 202 .update_pmtu = ip_rt_update_pmtu,
201 .local_out = __ip_local_out, 203 .local_out = __ip_local_out,
204 .neigh_lookup = ipv4_neigh_lookup,
202}; 205};
203 206
204#define ECN_OR_COST(class) TC_PRIO_##class 207#define ECN_OR_COST(class) TC_PRIO_##class
@@ -1008,22 +1011,30 @@ static int slow_chain_length(const struct rtable *head)
1008 return length >> FRACT_BITS; 1011 return length >> FRACT_BITS;
1009} 1012}
1010 1013
1011static int rt_bind_neighbour(struct rtable *rt) 1014static struct neighbour *ipv4_neigh_lookup(const struct dst_entry *dst, const void *daddr)
1012{ 1015{
1013 static const __be32 inaddr_any = 0;
1014 struct net_device *dev = rt->dst.dev;
1015 struct neigh_table *tbl = &arp_tbl; 1016 struct neigh_table *tbl = &arp_tbl;
1016 const __be32 *nexthop; 1017 static const __be32 inaddr_any = 0;
1018 struct net_device *dev = dst->dev;
1019 const __be32 *pkey = daddr;
1017 struct neighbour *n; 1020 struct neighbour *n;
1018 1021
1019#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE) 1022#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
1020 if (dev->type == ARPHRD_ATM) 1023 if (dev->type == ARPHRD_ATM)
1021 tbl = clip_tbl_hook; 1024 tbl = clip_tbl_hook;
1022#endif 1025#endif
1023 nexthop = &rt->rt_gateway;
1024 if (dev->flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) 1026 if (dev->flags & (IFF_LOOPBACK | IFF_POINTOPOINT))
1025 nexthop = &inaddr_any; 1027 pkey = &inaddr_any;
1026 n = ipv4_neigh_lookup(tbl, dev, nexthop); 1028
1029 n = __ipv4_neigh_lookup(tbl, dev, *(__force u32 *)pkey);
1030 if (n)
1031 return n;
1032 return neigh_create(tbl, pkey, dev);
1033}
1034
1035static int rt_bind_neighbour(struct rtable *rt)
1036{
1037 struct neighbour *n = ipv4_neigh_lookup(&rt->dst, &rt->rt_gateway);
1027 if (IS_ERR(n)) 1038 if (IS_ERR(n))
1028 return PTR_ERR(n); 1039 return PTR_ERR(n);
1029 dst_set_neighbour(&rt->dst, n); 1040 dst_set_neighbour(&rt->dst, n);
@@ -2734,6 +2745,7 @@ static struct dst_ops ipv4_dst_blackhole_ops = {
2734 .default_advmss = ipv4_default_advmss, 2745 .default_advmss = ipv4_default_advmss,
2735 .update_pmtu = ipv4_rt_blackhole_update_pmtu, 2746 .update_pmtu = ipv4_rt_blackhole_update_pmtu,
2736 .cow_metrics = ipv4_rt_blackhole_cow_metrics, 2747 .cow_metrics = ipv4_rt_blackhole_cow_metrics,
2748 .neigh_lookup = ipv4_neigh_lookup,
2737}; 2749};
2738 2750
2739struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_orig) 2751struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_orig)
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 2998cb5be90b..ddef80f568b0 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -127,6 +127,11 @@ static u32 *ipv6_cow_metrics(struct dst_entry *dst, unsigned long old)
127 return p; 127 return p;
128} 128}
129 129
130static 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
130static struct dst_ops ip6_dst_ops_template = { 135static struct dst_ops ip6_dst_ops_template = {
131 .family = AF_INET6, 136 .family = AF_INET6,
132 .protocol = cpu_to_be16(ETH_P_IPV6), 137 .protocol = cpu_to_be16(ETH_P_IPV6),
@@ -142,6 +147,7 @@ static struct dst_ops ip6_dst_ops_template = {
142 .link_failure = ip6_link_failure, 147 .link_failure = ip6_link_failure,
143 .update_pmtu = ip6_rt_update_pmtu, 148 .update_pmtu = ip6_rt_update_pmtu,
144 .local_out = __ip6_local_out, 149 .local_out = __ip6_local_out,
150 .neigh_lookup = ip6_neigh_lookup,
145}; 151};
146 152
147static unsigned int ip6_blackhole_default_mtu(const struct dst_entry *dst) 153static unsigned int ip6_blackhole_default_mtu(const struct dst_entry *dst)
@@ -168,6 +174,7 @@ static struct dst_ops ip6_dst_blackhole_ops = {
168 .default_advmss = ip6_default_advmss, 174 .default_advmss = ip6_default_advmss,
169 .update_pmtu = ip6_rt_blackhole_update_pmtu, 175 .update_pmtu = ip6_rt_blackhole_update_pmtu,
170 .cow_metrics = ip6_rt_blackhole_cow_metrics, 176 .cow_metrics = ip6_rt_blackhole_cow_metrics,
177 .neigh_lookup = ip6_neigh_lookup,
171}; 178};
172 179
173static const u32 ip6_template_metrics[RTAX_MAX] = { 180static const u32 ip6_template_metrics[RTAX_MAX] = {
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 7803eb6af414..94fdcc7f1030 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -2385,6 +2385,11 @@ static unsigned int xfrm_default_mtu(const struct dst_entry *dst)
2385 return dst_mtu(dst->path); 2385 return dst_mtu(dst->path);
2386} 2386}
2387 2387
2388static struct neighbour *xfrm_neigh_lookup(const struct dst_entry *dst, const void *daddr)
2389{
2390 return dst_neigh_lookup(dst->path, daddr);
2391}
2392
2388int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo) 2393int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo)
2389{ 2394{
2390 struct net *net; 2395 struct net *net;
@@ -2410,6 +2415,8 @@ int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo)
2410 dst_ops->negative_advice = xfrm_negative_advice; 2415 dst_ops->negative_advice = xfrm_negative_advice;
2411 if (likely(dst_ops->link_failure == NULL)) 2416 if (likely(dst_ops->link_failure == NULL))
2412 dst_ops->link_failure = xfrm_link_failure; 2417 dst_ops->link_failure = xfrm_link_failure;
2418 if (likely(dst_ops->neigh_lookup == NULL))
2419 dst_ops->neigh_lookup = xfrm_neigh_lookup;
2413 if (likely(afinfo->garbage_collect == NULL)) 2420 if (likely(afinfo->garbage_collect == NULL))
2414 afinfo->garbage_collect = __xfrm_garbage_collect; 2421 afinfo->garbage_collect = __xfrm_garbage_collect;
2415 xfrm_policy_afinfo[afinfo->family] = afinfo; 2422 xfrm_policy_afinfo[afinfo->family] = afinfo;