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>
This commit is contained in:
parent
69cce1d140
commit
d3aaeb38c4
8 changed files with 52 additions and 16 deletions
|
@ -38,15 +38,6 @@ static inline struct neighbour *__ipv4_neigh_lookup(struct neigh_table *tbl, str
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline struct neighbour *ipv4_neigh_lookup(struct neigh_table *tbl, struct net_device *dev, const __be32 *pkey)
|
|
||||||
{
|
|
||||||
struct neighbour *n = __ipv4_neigh_lookup(tbl, dev,
|
|
||||||
*(__force u32 *)pkey);
|
|
||||||
if (n)
|
|
||||||
return n;
|
|
||||||
return neigh_create(tbl, pkey, dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern void arp_init(void);
|
extern void arp_init(void);
|
||||||
extern int arp_find(unsigned char *haddr, struct sk_buff *skb);
|
extern int arp_find(unsigned char *haddr, struct sk_buff *skb);
|
||||||
extern int arp_ioctl(struct net *net, unsigned int cmd, void __user *arg);
|
extern int arp_ioctl(struct net *net, unsigned int cmd, void __user *arg);
|
||||||
|
|
|
@ -387,6 +387,11 @@ static inline void dst_confirm(struct dst_entry *dst)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline struct neighbour *dst_neigh_lookup(const struct dst_entry *dst, const void *daddr)
|
||||||
|
{
|
||||||
|
return dst->ops->neigh_lookup(dst, daddr);
|
||||||
|
}
|
||||||
|
|
||||||
static inline void dst_link_failure(struct sk_buff *skb)
|
static inline void dst_link_failure(struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
struct dst_entry *dst = skb_dst(skb);
|
struct dst_entry *dst = skb_dst(skb);
|
||||||
|
|
|
@ -26,6 +26,7 @@ struct dst_ops {
|
||||||
void (*link_failure)(struct sk_buff *);
|
void (*link_failure)(struct sk_buff *);
|
||||||
void (*update_pmtu)(struct dst_entry *dst, u32 mtu);
|
void (*update_pmtu)(struct dst_entry *dst, u32 mtu);
|
||||||
int (*local_out)(struct sk_buff *skb);
|
int (*local_out)(struct sk_buff *skb);
|
||||||
|
struct neighbour * (*neigh_lookup)(const struct dst_entry *dst, const void *daddr);
|
||||||
|
|
||||||
struct kmem_cache *kmem_cachep;
|
struct kmem_cache *kmem_cachep;
|
||||||
|
|
||||||
|
|
|
@ -109,11 +109,17 @@ static u32 *fake_cow_metrics(struct dst_entry *dst, unsigned long old)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct neighbour *fake_neigh_lookup(const struct dst_entry *dst, const void *daddr)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static struct dst_ops fake_dst_ops = {
|
static struct dst_ops fake_dst_ops = {
|
||||||
.family = AF_INET,
|
.family = AF_INET,
|
||||||
.protocol = cpu_to_be16(ETH_P_IP),
|
.protocol = cpu_to_be16(ETH_P_IP),
|
||||||
.update_pmtu = fake_update_pmtu,
|
.update_pmtu = fake_update_pmtu,
|
||||||
.cow_metrics = fake_cow_metrics,
|
.cow_metrics = fake_cow_metrics,
|
||||||
|
.neigh_lookup = fake_neigh_lookup,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -116,6 +116,7 @@ static void dn_dst_destroy(struct dst_entry *);
|
||||||
static struct dst_entry *dn_dst_negative_advice(struct dst_entry *);
|
static struct dst_entry *dn_dst_negative_advice(struct dst_entry *);
|
||||||
static void dn_dst_link_failure(struct sk_buff *);
|
static void dn_dst_link_failure(struct sk_buff *);
|
||||||
static void dn_dst_update_pmtu(struct dst_entry *dst, u32 mtu);
|
static void dn_dst_update_pmtu(struct dst_entry *dst, u32 mtu);
|
||||||
|
static struct neighbour *dn_dst_neigh_lookup(const struct dst_entry *dst, const void *daddr);
|
||||||
static int dn_route_input(struct sk_buff *);
|
static int dn_route_input(struct sk_buff *);
|
||||||
static void dn_run_flush(unsigned long dummy);
|
static void dn_run_flush(unsigned long dummy);
|
||||||
|
|
||||||
|
@ -139,6 +140,7 @@ static struct dst_ops dn_dst_ops = {
|
||||||
.negative_advice = dn_dst_negative_advice,
|
.negative_advice = dn_dst_negative_advice,
|
||||||
.link_failure = dn_dst_link_failure,
|
.link_failure = dn_dst_link_failure,
|
||||||
.update_pmtu = dn_dst_update_pmtu,
|
.update_pmtu = dn_dst_update_pmtu,
|
||||||
|
.neigh_lookup = dn_dst_neigh_lookup,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void dn_dst_destroy(struct dst_entry *dst)
|
static void dn_dst_destroy(struct dst_entry *dst)
|
||||||
|
@ -827,6 +829,11 @@ static unsigned int dn_dst_default_mtu(const struct dst_entry *dst)
|
||||||
return dst->dev->mtu;
|
return dst->dev->mtu;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct neighbour *dn_dst_neigh_lookup(const struct dst_entry *dst, const void *daddr)
|
||||||
|
{
|
||||||
|
return __neigh_lookup_errno(&dn_neigh_table, daddr, dst->dev);
|
||||||
|
}
|
||||||
|
|
||||||
static int dn_rt_set_next_hop(struct dn_route *rt, struct dn_fib_res *res)
|
static int dn_rt_set_next_hop(struct dn_route *rt, struct dn_fib_res *res)
|
||||||
{
|
{
|
||||||
struct dn_fib_info *fi = res->fi;
|
struct dn_fib_info *fi = res->fi;
|
||||||
|
|
|
@ -185,6 +185,8 @@ static u32 *ipv4_cow_metrics(struct dst_entry *dst, unsigned long old)
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct neighbour *ipv4_neigh_lookup(const struct dst_entry *dst, const void *daddr);
|
||||||
|
|
||||||
static struct dst_ops ipv4_dst_ops = {
|
static struct dst_ops ipv4_dst_ops = {
|
||||||
.family = AF_INET,
|
.family = AF_INET,
|
||||||
.protocol = cpu_to_be16(ETH_P_IP),
|
.protocol = cpu_to_be16(ETH_P_IP),
|
||||||
|
@ -199,6 +201,7 @@ static struct dst_ops ipv4_dst_ops = {
|
||||||
.link_failure = ipv4_link_failure,
|
.link_failure = ipv4_link_failure,
|
||||||
.update_pmtu = ip_rt_update_pmtu,
|
.update_pmtu = ip_rt_update_pmtu,
|
||||||
.local_out = __ip_local_out,
|
.local_out = __ip_local_out,
|
||||||
|
.neigh_lookup = ipv4_neigh_lookup,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define ECN_OR_COST(class) TC_PRIO_##class
|
#define ECN_OR_COST(class) TC_PRIO_##class
|
||||||
|
@ -1008,22 +1011,30 @@ static int slow_chain_length(const struct rtable *head)
|
||||||
return length >> FRACT_BITS;
|
return length >> FRACT_BITS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rt_bind_neighbour(struct rtable *rt)
|
static struct neighbour *ipv4_neigh_lookup(const struct dst_entry *dst, const void *daddr)
|
||||||
{
|
{
|
||||||
static const __be32 inaddr_any = 0;
|
|
||||||
struct net_device *dev = rt->dst.dev;
|
|
||||||
struct neigh_table *tbl = &arp_tbl;
|
struct neigh_table *tbl = &arp_tbl;
|
||||||
const __be32 *nexthop;
|
static const __be32 inaddr_any = 0;
|
||||||
|
struct net_device *dev = dst->dev;
|
||||||
|
const __be32 *pkey = daddr;
|
||||||
struct neighbour *n;
|
struct neighbour *n;
|
||||||
|
|
||||||
#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
|
#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
|
||||||
if (dev->type == ARPHRD_ATM)
|
if (dev->type == ARPHRD_ATM)
|
||||||
tbl = clip_tbl_hook;
|
tbl = clip_tbl_hook;
|
||||||
#endif
|
#endif
|
||||||
nexthop = &rt->rt_gateway;
|
|
||||||
if (dev->flags & (IFF_LOOPBACK | IFF_POINTOPOINT))
|
if (dev->flags & (IFF_LOOPBACK | IFF_POINTOPOINT))
|
||||||
nexthop = &inaddr_any;
|
pkey = &inaddr_any;
|
||||||
n = ipv4_neigh_lookup(tbl, dev, nexthop);
|
|
||||||
|
n = __ipv4_neigh_lookup(tbl, dev, *(__force u32 *)pkey);
|
||||||
|
if (n)
|
||||||
|
return n;
|
||||||
|
return neigh_create(tbl, pkey, dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rt_bind_neighbour(struct rtable *rt)
|
||||||
|
{
|
||||||
|
struct neighbour *n = ipv4_neigh_lookup(&rt->dst, &rt->rt_gateway);
|
||||||
if (IS_ERR(n))
|
if (IS_ERR(n))
|
||||||
return PTR_ERR(n);
|
return PTR_ERR(n);
|
||||||
dst_set_neighbour(&rt->dst, n);
|
dst_set_neighbour(&rt->dst, n);
|
||||||
|
@ -2734,6 +2745,7 @@ static struct dst_ops ipv4_dst_blackhole_ops = {
|
||||||
.default_advmss = ipv4_default_advmss,
|
.default_advmss = ipv4_default_advmss,
|
||||||
.update_pmtu = ipv4_rt_blackhole_update_pmtu,
|
.update_pmtu = ipv4_rt_blackhole_update_pmtu,
|
||||||
.cow_metrics = ipv4_rt_blackhole_cow_metrics,
|
.cow_metrics = ipv4_rt_blackhole_cow_metrics,
|
||||||
|
.neigh_lookup = ipv4_neigh_lookup,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_orig)
|
struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_orig)
|
||||||
|
|
|
@ -127,6 +127,11 @@ static u32 *ipv6_cow_metrics(struct dst_entry *dst, unsigned long old)
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct neighbour *ip6_neigh_lookup(const struct dst_entry *dst, const void *daddr)
|
||||||
|
{
|
||||||
|
return __neigh_lookup_errno(&nd_tbl, daddr, dst->dev);
|
||||||
|
}
|
||||||
|
|
||||||
static struct dst_ops ip6_dst_ops_template = {
|
static struct dst_ops ip6_dst_ops_template = {
|
||||||
.family = AF_INET6,
|
.family = AF_INET6,
|
||||||
.protocol = cpu_to_be16(ETH_P_IPV6),
|
.protocol = cpu_to_be16(ETH_P_IPV6),
|
||||||
|
@ -142,6 +147,7 @@ static struct dst_ops ip6_dst_ops_template = {
|
||||||
.link_failure = ip6_link_failure,
|
.link_failure = ip6_link_failure,
|
||||||
.update_pmtu = ip6_rt_update_pmtu,
|
.update_pmtu = ip6_rt_update_pmtu,
|
||||||
.local_out = __ip6_local_out,
|
.local_out = __ip6_local_out,
|
||||||
|
.neigh_lookup = ip6_neigh_lookup,
|
||||||
};
|
};
|
||||||
|
|
||||||
static unsigned int ip6_blackhole_default_mtu(const struct dst_entry *dst)
|
static unsigned int ip6_blackhole_default_mtu(const struct dst_entry *dst)
|
||||||
|
@ -168,6 +174,7 @@ static struct dst_ops ip6_dst_blackhole_ops = {
|
||||||
.default_advmss = ip6_default_advmss,
|
.default_advmss = ip6_default_advmss,
|
||||||
.update_pmtu = ip6_rt_blackhole_update_pmtu,
|
.update_pmtu = ip6_rt_blackhole_update_pmtu,
|
||||||
.cow_metrics = ip6_rt_blackhole_cow_metrics,
|
.cow_metrics = ip6_rt_blackhole_cow_metrics,
|
||||||
|
.neigh_lookup = ip6_neigh_lookup,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const u32 ip6_template_metrics[RTAX_MAX] = {
|
static const u32 ip6_template_metrics[RTAX_MAX] = {
|
||||||
|
|
|
@ -2385,6 +2385,11 @@ static unsigned int xfrm_default_mtu(const struct dst_entry *dst)
|
||||||
return dst_mtu(dst->path);
|
return dst_mtu(dst->path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct neighbour *xfrm_neigh_lookup(const struct dst_entry *dst, const void *daddr)
|
||||||
|
{
|
||||||
|
return dst_neigh_lookup(dst->path, daddr);
|
||||||
|
}
|
||||||
|
|
||||||
int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo)
|
int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo)
|
||||||
{
|
{
|
||||||
struct net *net;
|
struct net *net;
|
||||||
|
@ -2410,6 +2415,8 @@ int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo)
|
||||||
dst_ops->negative_advice = xfrm_negative_advice;
|
dst_ops->negative_advice = xfrm_negative_advice;
|
||||||
if (likely(dst_ops->link_failure == NULL))
|
if (likely(dst_ops->link_failure == NULL))
|
||||||
dst_ops->link_failure = xfrm_link_failure;
|
dst_ops->link_failure = xfrm_link_failure;
|
||||||
|
if (likely(dst_ops->neigh_lookup == NULL))
|
||||||
|
dst_ops->neigh_lookup = xfrm_neigh_lookup;
|
||||||
if (likely(afinfo->garbage_collect == NULL))
|
if (likely(afinfo->garbage_collect == NULL))
|
||||||
afinfo->garbage_collect = __xfrm_garbage_collect;
|
afinfo->garbage_collect = __xfrm_garbage_collect;
|
||||||
xfrm_policy_afinfo[afinfo->family] = afinfo;
|
xfrm_policy_afinfo[afinfo->family] = afinfo;
|
||||||
|
|
Loading…
Reference in a new issue