mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-04-02 20:44:00 +00:00
net/ipv6: Create a neigh_lookup for FIB entries
The router discovery code has a FIB entry and wants to validate the gateway has a neighbor entry. Refactor the existing dst_neigh_lookup for IPv6 and create a new function that takes the gateway and device and returns a neighbor entry. Use the new function in ndisc_router_discovery to validate the gateway. Signed-off-by: David Ahern <dsahern@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
3b6761d18b
commit
f8a1b43b70
3 changed files with 29 additions and 15 deletions
|
@ -279,4 +279,7 @@ static inline bool rt6_duplicate_nexthop(struct rt6_info *a, struct rt6_info *b)
|
||||||
!lwtunnel_cmp_encap(a->fib6_nh.nh_lwtstate, b->fib6_nh.nh_lwtstate);
|
!lwtunnel_cmp_encap(a->fib6_nh.nh_lwtstate, b->fib6_nh.nh_lwtstate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct neighbour *ip6_neigh_lookup(const struct in6_addr *gw,
|
||||||
|
struct net_device *dev, struct sk_buff *skb,
|
||||||
|
const void *daddr);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1276,7 +1276,9 @@ static void ndisc_router_discovery(struct sk_buff *skb)
|
||||||
rt = rt6_get_dflt_router(net, &ipv6_hdr(skb)->saddr, skb->dev);
|
rt = rt6_get_dflt_router(net, &ipv6_hdr(skb)->saddr, skb->dev);
|
||||||
|
|
||||||
if (rt) {
|
if (rt) {
|
||||||
neigh = dst_neigh_lookup(&rt->dst, &ipv6_hdr(skb)->saddr);
|
neigh = ip6_neigh_lookup(&rt->fib6_nh.nh_gw,
|
||||||
|
rt->fib6_nh.nh_dev, NULL,
|
||||||
|
&ipv6_hdr(skb)->saddr);
|
||||||
if (!neigh) {
|
if (!neigh) {
|
||||||
ND_PRINTK(0, err,
|
ND_PRINTK(0, err,
|
||||||
"RA: %s got default router without neighbour\n",
|
"RA: %s got default router without neighbour\n",
|
||||||
|
@ -1304,7 +1306,9 @@ static void ndisc_router_discovery(struct sk_buff *skb)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
neigh = dst_neigh_lookup(&rt->dst, &ipv6_hdr(skb)->saddr);
|
neigh = ip6_neigh_lookup(&rt->fib6_nh.nh_gw,
|
||||||
|
rt->fib6_nh.nh_dev, NULL,
|
||||||
|
&ipv6_hdr(skb)->saddr);
|
||||||
if (!neigh) {
|
if (!neigh) {
|
||||||
ND_PRINTK(0, err,
|
ND_PRINTK(0, err,
|
||||||
"RA: %s got default router without neighbour\n",
|
"RA: %s got default router without neighbour\n",
|
||||||
|
|
|
@ -182,12 +182,10 @@ static void rt6_uncached_list_flush_dev(struct net *net, struct net_device *dev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline const void *choose_neigh_daddr(struct rt6_info *rt,
|
static inline const void *choose_neigh_daddr(const struct in6_addr *p,
|
||||||
struct sk_buff *skb,
|
struct sk_buff *skb,
|
||||||
const void *daddr)
|
const void *daddr)
|
||||||
{
|
{
|
||||||
struct in6_addr *p = &rt->rt6i_gateway;
|
|
||||||
|
|
||||||
if (!ipv6_addr_any(p))
|
if (!ipv6_addr_any(p))
|
||||||
return (const void *) p;
|
return (const void *) p;
|
||||||
else if (skb)
|
else if (skb)
|
||||||
|
@ -195,18 +193,27 @@ static inline const void *choose_neigh_daddr(struct rt6_info *rt,
|
||||||
return daddr;
|
return daddr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct neighbour *ip6_neigh_lookup(const struct dst_entry *dst,
|
struct neighbour *ip6_neigh_lookup(const struct in6_addr *gw,
|
||||||
struct sk_buff *skb,
|
struct net_device *dev,
|
||||||
const void *daddr)
|
struct sk_buff *skb,
|
||||||
|
const void *daddr)
|
||||||
{
|
{
|
||||||
struct rt6_info *rt = (struct rt6_info *) dst;
|
|
||||||
struct neighbour *n;
|
struct neighbour *n;
|
||||||
|
|
||||||
daddr = choose_neigh_daddr(rt, skb, daddr);
|
daddr = choose_neigh_daddr(gw, skb, daddr);
|
||||||
n = __ipv6_neigh_lookup(dst->dev, daddr);
|
n = __ipv6_neigh_lookup(dev, daddr);
|
||||||
if (n)
|
if (n)
|
||||||
return n;
|
return n;
|
||||||
return neigh_create(&nd_tbl, daddr, dst->dev);
|
return neigh_create(&nd_tbl, daddr, dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct neighbour *ip6_dst_neigh_lookup(const struct dst_entry *dst,
|
||||||
|
struct sk_buff *skb,
|
||||||
|
const void *daddr)
|
||||||
|
{
|
||||||
|
const struct rt6_info *rt = container_of(dst, struct rt6_info, dst);
|
||||||
|
|
||||||
|
return ip6_neigh_lookup(&rt->rt6i_gateway, dst->dev, skb, daddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ip6_confirm_neigh(const struct dst_entry *dst, const void *daddr)
|
static void ip6_confirm_neigh(const struct dst_entry *dst, const void *daddr)
|
||||||
|
@ -214,7 +221,7 @@ static void ip6_confirm_neigh(const struct dst_entry *dst, const void *daddr)
|
||||||
struct net_device *dev = dst->dev;
|
struct net_device *dev = dst->dev;
|
||||||
struct rt6_info *rt = (struct rt6_info *)dst;
|
struct rt6_info *rt = (struct rt6_info *)dst;
|
||||||
|
|
||||||
daddr = choose_neigh_daddr(rt, NULL, daddr);
|
daddr = choose_neigh_daddr(&rt->rt6i_gateway, NULL, daddr);
|
||||||
if (!daddr)
|
if (!daddr)
|
||||||
return;
|
return;
|
||||||
if (dev->flags & (IFF_NOARP | IFF_LOOPBACK))
|
if (dev->flags & (IFF_NOARP | IFF_LOOPBACK))
|
||||||
|
@ -239,7 +246,7 @@ static struct dst_ops ip6_dst_ops_template = {
|
||||||
.update_pmtu = ip6_rt_update_pmtu,
|
.update_pmtu = ip6_rt_update_pmtu,
|
||||||
.redirect = rt6_do_redirect,
|
.redirect = rt6_do_redirect,
|
||||||
.local_out = __ip6_local_out,
|
.local_out = __ip6_local_out,
|
||||||
.neigh_lookup = ip6_neigh_lookup,
|
.neigh_lookup = ip6_dst_neigh_lookup,
|
||||||
.confirm_neigh = ip6_confirm_neigh,
|
.confirm_neigh = ip6_confirm_neigh,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -269,7 +276,7 @@ static struct dst_ops ip6_dst_blackhole_ops = {
|
||||||
.update_pmtu = ip6_rt_blackhole_update_pmtu,
|
.update_pmtu = ip6_rt_blackhole_update_pmtu,
|
||||||
.redirect = ip6_rt_blackhole_redirect,
|
.redirect = ip6_rt_blackhole_redirect,
|
||||||
.cow_metrics = dst_cow_metrics_generic,
|
.cow_metrics = dst_cow_metrics_generic,
|
||||||
.neigh_lookup = ip6_neigh_lookup,
|
.neigh_lookup = ip6_dst_neigh_lookup,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const u32 ip6_template_metrics[RTAX_MAX] = {
|
static const u32 ip6_template_metrics[RTAX_MAX] = {
|
||||||
|
|
Loading…
Add table
Reference in a new issue