ipv6: Make fib6_nh optional at the end of fib6_info
Move fib6_nh to the end of fib6_info and make it an array of size 0. Pass a flag to fib6_info_alloc indicating if the allocation needs to add space for a fib6_nh. The current code path always has a fib6_nh allocated with a fib6_info; with nexthop objects they will be separate. Signed-off-by: David Ahern <dsahern@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:

committed by
David S. Miller

parent
cc5c073a69
commit
1cf844c747
134
net/ipv6/route.c
134
net/ipv6/route.c
@@ -441,12 +441,12 @@ void fib6_select_path(const struct net *net, struct fib6_result *res,
|
||||
if (!fl6->mp_hash)
|
||||
fl6->mp_hash = rt6_multipath_hash(net, fl6, skb, NULL);
|
||||
|
||||
if (fl6->mp_hash <= atomic_read(&match->fib6_nh.fib_nh_upper_bound))
|
||||
if (fl6->mp_hash <= atomic_read(&match->fib6_nh->fib_nh_upper_bound))
|
||||
goto out;
|
||||
|
||||
list_for_each_entry_safe(sibling, next_sibling, &match->fib6_siblings,
|
||||
fib6_siblings) {
|
||||
const struct fib6_nh *nh = &sibling->fib6_nh;
|
||||
const struct fib6_nh *nh = sibling->fib6_nh;
|
||||
int nh_upper_bound;
|
||||
|
||||
nh_upper_bound = atomic_read(&nh->fib_nh_upper_bound);
|
||||
@@ -460,7 +460,7 @@ void fib6_select_path(const struct net *net, struct fib6_result *res,
|
||||
|
||||
out:
|
||||
res->f6i = match;
|
||||
res->nh = &match->fib6_nh;
|
||||
res->nh = match->fib6_nh;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -496,13 +496,13 @@ static void rt6_device_match(struct net *net, struct fib6_result *res,
|
||||
struct fib6_nh *nh;
|
||||
|
||||
if (!oif && ipv6_addr_any(saddr)) {
|
||||
nh = &f6i->fib6_nh;
|
||||
nh = f6i->fib6_nh;
|
||||
if (!(nh->fib_nh_flags & RTNH_F_DEAD))
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (spf6i = f6i; spf6i; spf6i = rcu_dereference(spf6i->fib6_next)) {
|
||||
nh = &spf6i->fib6_nh;
|
||||
nh = spf6i->fib6_nh;
|
||||
if (__rt6_device_match(net, nh, saddr, oif, flags)) {
|
||||
res->f6i = spf6i;
|
||||
goto out;
|
||||
@@ -511,14 +511,14 @@ static void rt6_device_match(struct net *net, struct fib6_result *res,
|
||||
|
||||
if (oif && flags & RT6_LOOKUP_F_IFACE) {
|
||||
res->f6i = net->ipv6.fib6_null_entry;
|
||||
nh = &res->f6i->fib6_nh;
|
||||
nh = res->f6i->fib6_nh;
|
||||
goto out;
|
||||
}
|
||||
|
||||
nh = &f6i->fib6_nh;
|
||||
nh = f6i->fib6_nh;
|
||||
if (nh->fib_nh_flags & RTNH_F_DEAD) {
|
||||
res->f6i = net->ipv6.fib6_null_entry;
|
||||
nh = &res->f6i->fib6_nh;
|
||||
nh = res->f6i->fib6_nh;
|
||||
}
|
||||
out:
|
||||
res->nh = nh;
|
||||
@@ -714,7 +714,7 @@ static void __find_rr_leaf(struct fib6_info *f6i_start,
|
||||
if (fib6_check_expired(f6i))
|
||||
continue;
|
||||
|
||||
nh = &f6i->fib6_nh;
|
||||
nh = f6i->fib6_nh;
|
||||
if (find_match(nh, f6i->fib6_flags, oif, strict, mpri, do_rr)) {
|
||||
res->f6i = f6i;
|
||||
res->nh = nh;
|
||||
@@ -796,7 +796,7 @@ static void rt6_select(struct net *net, struct fib6_node *fn, int oif,
|
||||
out:
|
||||
if (!res->f6i) {
|
||||
res->f6i = net->ipv6.fib6_null_entry;
|
||||
res->nh = &res->f6i->fib6_nh;
|
||||
res->nh = res->f6i->fib6_nh;
|
||||
res->fib6_flags = res->f6i->fib6_flags;
|
||||
res->fib6_type = res->f6i->fib6_type;
|
||||
}
|
||||
@@ -1626,7 +1626,7 @@ out:
|
||||
|
||||
void rt6_flush_exceptions(struct fib6_info *f6i)
|
||||
{
|
||||
fib6_nh_flush_exceptions(&f6i->fib6_nh, f6i);
|
||||
fib6_nh_flush_exceptions(f6i->fib6_nh, f6i);
|
||||
}
|
||||
|
||||
/* Find cached rt in the hash table inside passed in rt
|
||||
@@ -1721,7 +1721,7 @@ static int rt6_remove_exception_rt(struct rt6_info *rt)
|
||||
if (!from || !(rt->rt6i_flags & RTF_CACHE))
|
||||
return -EINVAL;
|
||||
|
||||
return fib6_nh_remove_exception(&from->fib6_nh,
|
||||
return fib6_nh_remove_exception(from->fib6_nh,
|
||||
from->fib6_src.plen, rt);
|
||||
}
|
||||
|
||||
@@ -1761,7 +1761,7 @@ static void rt6_update_exception_stamp_rt(struct rt6_info *rt)
|
||||
if (!from || !(rt->rt6i_flags & RTF_CACHE))
|
||||
goto unlock;
|
||||
|
||||
fib6_nh_update_exception(&from->fib6_nh, from->fib6_src.plen, rt);
|
||||
fib6_nh_update_exception(from->fib6_nh, from->fib6_src.plen, rt);
|
||||
unlock:
|
||||
rcu_read_unlock();
|
||||
}
|
||||
@@ -1927,7 +1927,7 @@ void rt6_age_exceptions(struct fib6_info *f6i,
|
||||
struct fib6_gc_args *gc_args,
|
||||
unsigned long now)
|
||||
{
|
||||
fib6_nh_age_exceptions(&f6i->fib6_nh, gc_args, now);
|
||||
fib6_nh_age_exceptions(f6i->fib6_nh, gc_args, now);
|
||||
}
|
||||
|
||||
/* must be called with rcu lock held */
|
||||
@@ -2456,7 +2456,7 @@ static void __ip6_rt_update_pmtu(struct dst_entry *dst, const struct sock *sk,
|
||||
rcu_read_unlock();
|
||||
return;
|
||||
}
|
||||
res.nh = &res.f6i->fib6_nh;
|
||||
res.nh = res.f6i->fib6_nh;
|
||||
res.fib6_flags = res.f6i->fib6_flags;
|
||||
res.fib6_type = res.f6i->fib6_type;
|
||||
|
||||
@@ -2599,7 +2599,7 @@ static struct rt6_info *__ip6_route_redirect(struct net *net,
|
||||
restart:
|
||||
for_each_fib6_node_rt_rcu(fn) {
|
||||
res.f6i = rt;
|
||||
res.nh = &rt->fib6_nh;
|
||||
res.nh = rt->fib6_nh;
|
||||
|
||||
if (fib6_check_expired(rt))
|
||||
continue;
|
||||
@@ -2623,7 +2623,7 @@ restart:
|
||||
}
|
||||
|
||||
res.f6i = rt;
|
||||
res.nh = &rt->fib6_nh;
|
||||
res.nh = rt->fib6_nh;
|
||||
out:
|
||||
if (ret) {
|
||||
ip6_hold_safe(net, &ret);
|
||||
@@ -3264,7 +3264,7 @@ static struct fib6_info *ip6_route_info_create(struct fib6_config *cfg,
|
||||
goto out;
|
||||
|
||||
err = -ENOMEM;
|
||||
rt = fib6_info_alloc(gfp_flags);
|
||||
rt = fib6_info_alloc(gfp_flags, true);
|
||||
if (!rt)
|
||||
goto out;
|
||||
|
||||
@@ -3304,7 +3304,7 @@ static struct fib6_info *ip6_route_info_create(struct fib6_config *cfg,
|
||||
ipv6_addr_prefix(&rt->fib6_src.addr, &cfg->fc_src, cfg->fc_src_len);
|
||||
rt->fib6_src.plen = cfg->fc_src_len;
|
||||
#endif
|
||||
err = fib6_nh_init(net, &rt->fib6_nh, cfg, gfp_flags, extack);
|
||||
err = fib6_nh_init(net, rt->fib6_nh, cfg, gfp_flags, extack);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
@@ -3312,7 +3312,7 @@ static struct fib6_info *ip6_route_info_create(struct fib6_config *cfg,
|
||||
* they would result in kernel looping; promote them to reject routes
|
||||
*/
|
||||
addr_type = ipv6_addr_type(&cfg->fc_dst);
|
||||
if (fib6_is_reject(cfg->fc_flags, rt->fib6_nh.fib_nh_dev, addr_type))
|
||||
if (fib6_is_reject(cfg->fc_flags, rt->fib6_nh->fib_nh_dev, addr_type))
|
||||
rt->fib6_flags = RTF_REJECT | RTF_NONEXTHOP;
|
||||
|
||||
if (!ipv6_addr_any(&cfg->fc_prefsrc)) {
|
||||
@@ -3472,7 +3472,7 @@ static int ip6_route_del(struct fib6_config *cfg,
|
||||
for_each_fib6_node_rt_rcu(fn) {
|
||||
struct fib6_nh *nh;
|
||||
|
||||
nh = &rt->fib6_nh;
|
||||
nh = rt->fib6_nh;
|
||||
if (cfg->fc_flags & RTF_CACHE) {
|
||||
struct fib6_result res = {
|
||||
.f6i = rt,
|
||||
@@ -3614,7 +3614,7 @@ static void rt6_do_redirect(struct dst_entry *dst, struct sock *sk, struct sk_bu
|
||||
if (!res.f6i)
|
||||
goto out;
|
||||
|
||||
res.nh = &res.f6i->fib6_nh;
|
||||
res.nh = res.f6i->fib6_nh;
|
||||
res.fib6_flags = res.f6i->fib6_flags;
|
||||
res.fib6_type = res.f6i->fib6_type;
|
||||
nrt = ip6_rt_cache_alloc(&res, &msg->dest, NULL);
|
||||
@@ -3666,12 +3666,12 @@ static struct fib6_info *rt6_get_route_info(struct net *net,
|
||||
goto out;
|
||||
|
||||
for_each_fib6_node_rt_rcu(fn) {
|
||||
if (rt->fib6_nh.fib_nh_dev->ifindex != ifindex)
|
||||
if (rt->fib6_nh->fib_nh_dev->ifindex != ifindex)
|
||||
continue;
|
||||
if (!(rt->fib6_flags & RTF_ROUTEINFO) ||
|
||||
!rt->fib6_nh.fib_nh_gw_family)
|
||||
!rt->fib6_nh->fib_nh_gw_family)
|
||||
continue;
|
||||
if (!ipv6_addr_equal(&rt->fib6_nh.fib_nh_gw6, gwaddr))
|
||||
if (!ipv6_addr_equal(&rt->fib6_nh->fib_nh_gw6, gwaddr))
|
||||
continue;
|
||||
if (!fib6_info_hold_safe(rt))
|
||||
continue;
|
||||
@@ -3729,7 +3729,7 @@ struct fib6_info *rt6_get_dflt_router(struct net *net,
|
||||
|
||||
rcu_read_lock();
|
||||
for_each_fib6_node_rt_rcu(&table->tb6_root) {
|
||||
struct fib6_nh *nh = &rt->fib6_nh;
|
||||
struct fib6_nh *nh = rt->fib6_nh;
|
||||
|
||||
if (dev == nh->fib_nh_dev &&
|
||||
((rt->fib6_flags & (RTF_ADDRCONF | RTF_DEFAULT)) == (RTF_ADDRCONF | RTF_DEFAULT)) &&
|
||||
@@ -3981,7 +3981,7 @@ static int fib6_remove_prefsrc(struct fib6_info *rt, void *arg)
|
||||
struct net *net = ((struct arg_dev_net_ip *)arg)->net;
|
||||
struct in6_addr *addr = ((struct arg_dev_net_ip *)arg)->addr;
|
||||
|
||||
if (((void *)rt->fib6_nh.fib_nh_dev == dev || !dev) &&
|
||||
if (((void *)rt->fib6_nh->fib_nh_dev == dev || !dev) &&
|
||||
rt != net->ipv6.fib6_null_entry &&
|
||||
ipv6_addr_equal(addr, &rt->fib6_prefsrc.addr)) {
|
||||
spin_lock_bh(&rt6_exception_lock);
|
||||
@@ -4009,7 +4009,7 @@ void rt6_remove_prefsrc(struct inet6_ifaddr *ifp)
|
||||
static int fib6_clean_tohost(struct fib6_info *rt, void *arg)
|
||||
{
|
||||
struct in6_addr *gateway = (struct in6_addr *)arg;
|
||||
struct fib6_nh *nh = &rt->fib6_nh;
|
||||
struct fib6_nh *nh = rt->fib6_nh;
|
||||
|
||||
if (((rt->fib6_flags & RTF_RA_ROUTER) == RTF_RA_ROUTER) &&
|
||||
nh->fib_nh_gw_family && ipv6_addr_equal(gateway, &nh->fib_nh_gw6))
|
||||
@@ -4059,9 +4059,9 @@ static struct fib6_info *rt6_multipath_first_sibling(const struct fib6_info *rt)
|
||||
|
||||
static bool rt6_is_dead(const struct fib6_info *rt)
|
||||
{
|
||||
if (rt->fib6_nh.fib_nh_flags & RTNH_F_DEAD ||
|
||||
(rt->fib6_nh.fib_nh_flags & RTNH_F_LINKDOWN &&
|
||||
ip6_ignore_linkdown(rt->fib6_nh.fib_nh_dev)))
|
||||
if (rt->fib6_nh->fib_nh_flags & RTNH_F_DEAD ||
|
||||
(rt->fib6_nh->fib_nh_flags & RTNH_F_LINKDOWN &&
|
||||
ip6_ignore_linkdown(rt->fib6_nh->fib_nh_dev)))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
@@ -4073,11 +4073,11 @@ static int rt6_multipath_total_weight(const struct fib6_info *rt)
|
||||
int total = 0;
|
||||
|
||||
if (!rt6_is_dead(rt))
|
||||
total += rt->fib6_nh.fib_nh_weight;
|
||||
total += rt->fib6_nh->fib_nh_weight;
|
||||
|
||||
list_for_each_entry(iter, &rt->fib6_siblings, fib6_siblings) {
|
||||
if (!rt6_is_dead(iter))
|
||||
total += iter->fib6_nh.fib_nh_weight;
|
||||
total += iter->fib6_nh->fib_nh_weight;
|
||||
}
|
||||
|
||||
return total;
|
||||
@@ -4088,11 +4088,11 @@ static void rt6_upper_bound_set(struct fib6_info *rt, int *weight, int total)
|
||||
int upper_bound = -1;
|
||||
|
||||
if (!rt6_is_dead(rt)) {
|
||||
*weight += rt->fib6_nh.fib_nh_weight;
|
||||
*weight += rt->fib6_nh->fib_nh_weight;
|
||||
upper_bound = DIV_ROUND_CLOSEST_ULL((u64) (*weight) << 31,
|
||||
total) - 1;
|
||||
}
|
||||
atomic_set(&rt->fib6_nh.fib_nh_upper_bound, upper_bound);
|
||||
atomic_set(&rt->fib6_nh->fib_nh_upper_bound, upper_bound);
|
||||
}
|
||||
|
||||
static void rt6_multipath_upper_bound_set(struct fib6_info *rt, int total)
|
||||
@@ -4136,8 +4136,8 @@ static int fib6_ifup(struct fib6_info *rt, void *p_arg)
|
||||
struct net *net = dev_net(arg->dev);
|
||||
|
||||
if (rt != net->ipv6.fib6_null_entry &&
|
||||
rt->fib6_nh.fib_nh_dev == arg->dev) {
|
||||
rt->fib6_nh.fib_nh_flags &= ~arg->nh_flags;
|
||||
rt->fib6_nh->fib_nh_dev == arg->dev) {
|
||||
rt->fib6_nh->fib_nh_flags &= ~arg->nh_flags;
|
||||
fib6_update_sernum_upto_root(net, rt);
|
||||
rt6_multipath_rebalance(rt);
|
||||
}
|
||||
@@ -4165,10 +4165,10 @@ static bool rt6_multipath_uses_dev(const struct fib6_info *rt,
|
||||
{
|
||||
struct fib6_info *iter;
|
||||
|
||||
if (rt->fib6_nh.fib_nh_dev == dev)
|
||||
if (rt->fib6_nh->fib_nh_dev == dev)
|
||||
return true;
|
||||
list_for_each_entry(iter, &rt->fib6_siblings, fib6_siblings)
|
||||
if (iter->fib6_nh.fib_nh_dev == dev)
|
||||
if (iter->fib6_nh->fib_nh_dev == dev)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
@@ -4189,12 +4189,12 @@ static unsigned int rt6_multipath_dead_count(const struct fib6_info *rt,
|
||||
struct fib6_info *iter;
|
||||
unsigned int dead = 0;
|
||||
|
||||
if (rt->fib6_nh.fib_nh_dev == down_dev ||
|
||||
rt->fib6_nh.fib_nh_flags & RTNH_F_DEAD)
|
||||
if (rt->fib6_nh->fib_nh_dev == down_dev ||
|
||||
rt->fib6_nh->fib_nh_flags & RTNH_F_DEAD)
|
||||
dead++;
|
||||
list_for_each_entry(iter, &rt->fib6_siblings, fib6_siblings)
|
||||
if (iter->fib6_nh.fib_nh_dev == down_dev ||
|
||||
iter->fib6_nh.fib_nh_flags & RTNH_F_DEAD)
|
||||
if (iter->fib6_nh->fib_nh_dev == down_dev ||
|
||||
iter->fib6_nh->fib_nh_flags & RTNH_F_DEAD)
|
||||
dead++;
|
||||
|
||||
return dead;
|
||||
@@ -4206,11 +4206,11 @@ static void rt6_multipath_nh_flags_set(struct fib6_info *rt,
|
||||
{
|
||||
struct fib6_info *iter;
|
||||
|
||||
if (rt->fib6_nh.fib_nh_dev == dev)
|
||||
rt->fib6_nh.fib_nh_flags |= nh_flags;
|
||||
if (rt->fib6_nh->fib_nh_dev == dev)
|
||||
rt->fib6_nh->fib_nh_flags |= nh_flags;
|
||||
list_for_each_entry(iter, &rt->fib6_siblings, fib6_siblings)
|
||||
if (iter->fib6_nh.fib_nh_dev == dev)
|
||||
iter->fib6_nh.fib_nh_flags |= nh_flags;
|
||||
if (iter->fib6_nh->fib_nh_dev == dev)
|
||||
iter->fib6_nh->fib_nh_flags |= nh_flags;
|
||||
}
|
||||
|
||||
/* called with write lock held for table with rt */
|
||||
@@ -4225,12 +4225,12 @@ static int fib6_ifdown(struct fib6_info *rt, void *p_arg)
|
||||
|
||||
switch (arg->event) {
|
||||
case NETDEV_UNREGISTER:
|
||||
return rt->fib6_nh.fib_nh_dev == dev ? -1 : 0;
|
||||
return rt->fib6_nh->fib_nh_dev == dev ? -1 : 0;
|
||||
case NETDEV_DOWN:
|
||||
if (rt->should_flush)
|
||||
return -1;
|
||||
if (!rt->fib6_nsiblings)
|
||||
return rt->fib6_nh.fib_nh_dev == dev ? -1 : 0;
|
||||
return rt->fib6_nh->fib_nh_dev == dev ? -1 : 0;
|
||||
if (rt6_multipath_uses_dev(rt, dev)) {
|
||||
unsigned int count;
|
||||
|
||||
@@ -4246,10 +4246,10 @@ static int fib6_ifdown(struct fib6_info *rt, void *p_arg)
|
||||
}
|
||||
return -2;
|
||||
case NETDEV_CHANGE:
|
||||
if (rt->fib6_nh.fib_nh_dev != dev ||
|
||||
if (rt->fib6_nh->fib_nh_dev != dev ||
|
||||
rt->fib6_flags & (RTF_LOCAL | RTF_ANYCAST))
|
||||
break;
|
||||
rt->fib6_nh.fib_nh_flags |= RTNH_F_LINKDOWN;
|
||||
rt->fib6_nh->fib_nh_flags |= RTNH_F_LINKDOWN;
|
||||
rt6_multipath_rebalance(rt);
|
||||
break;
|
||||
}
|
||||
@@ -4331,7 +4331,7 @@ static int rt6_mtu_change_route(struct fib6_info *f6i, void *p_arg)
|
||||
return 0;
|
||||
|
||||
arg->f6i = f6i;
|
||||
return fib6_nh_mtu_change(&f6i->fib6_nh, arg);
|
||||
return fib6_nh_mtu_change(f6i->fib6_nh, arg);
|
||||
}
|
||||
|
||||
void rt6_mtu_change(struct net_device *dev, unsigned int mtu)
|
||||
@@ -4611,7 +4611,7 @@ static int ip6_route_multipath_add(struct fib6_config *cfg,
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
rt->fib6_nh.fib_nh_weight = rtnh->rtnh_hops + 1;
|
||||
rt->fib6_nh->fib_nh_weight = rtnh->rtnh_hops + 1;
|
||||
|
||||
err = ip6_route_info_append(info->nl_net, &rt6_nh_list,
|
||||
rt, &r_cfg);
|
||||
@@ -4778,7 +4778,7 @@ static size_t rt6_nlmsg_size(struct fib6_info *rt)
|
||||
nexthop_len = nla_total_size(0) /* RTA_MULTIPATH */
|
||||
+ NLA_ALIGN(sizeof(struct rtnexthop))
|
||||
+ nla_total_size(16) /* RTA_GATEWAY */
|
||||
+ lwtunnel_get_encap_size(rt->fib6_nh.fib_nh_lws);
|
||||
+ lwtunnel_get_encap_size(rt->fib6_nh->fib_nh_lws);
|
||||
|
||||
nexthop_len *= rt->fib6_nsiblings;
|
||||
}
|
||||
@@ -4796,7 +4796,7 @@ static size_t rt6_nlmsg_size(struct fib6_info *rt)
|
||||
+ nla_total_size(sizeof(struct rta_cacheinfo))
|
||||
+ nla_total_size(TCP_CA_NAME_MAX) /* RTAX_CC_ALGO */
|
||||
+ nla_total_size(1) /* RTA_PREF */
|
||||
+ lwtunnel_get_encap_size(rt->fib6_nh.fib_nh_lws)
|
||||
+ lwtunnel_get_encap_size(rt->fib6_nh->fib_nh_lws)
|
||||
+ nexthop_len;
|
||||
}
|
||||
|
||||
@@ -4916,14 +4916,14 @@ static int rt6_fill_node(struct net *net, struct sk_buff *skb,
|
||||
if (!mp)
|
||||
goto nla_put_failure;
|
||||
|
||||
if (fib_add_nexthop(skb, &rt->fib6_nh.nh_common,
|
||||
rt->fib6_nh.fib_nh_weight) < 0)
|
||||
if (fib_add_nexthop(skb, &rt->fib6_nh->nh_common,
|
||||
rt->fib6_nh->fib_nh_weight) < 0)
|
||||
goto nla_put_failure;
|
||||
|
||||
list_for_each_entry_safe(sibling, next_sibling,
|
||||
&rt->fib6_siblings, fib6_siblings) {
|
||||
if (fib_add_nexthop(skb, &sibling->fib6_nh.nh_common,
|
||||
sibling->fib6_nh.fib_nh_weight) < 0)
|
||||
if (fib_add_nexthop(skb, &sibling->fib6_nh->nh_common,
|
||||
sibling->fib6_nh->fib_nh_weight) < 0)
|
||||
goto nla_put_failure;
|
||||
}
|
||||
|
||||
@@ -4931,7 +4931,7 @@ static int rt6_fill_node(struct net *net, struct sk_buff *skb,
|
||||
} else {
|
||||
unsigned char nh_flags = 0;
|
||||
|
||||
if (fib_nexthop_info(skb, &rt->fib6_nh.nh_common,
|
||||
if (fib_nexthop_info(skb, &rt->fib6_nh->nh_common,
|
||||
&nh_flags, false) < 0)
|
||||
goto nla_put_failure;
|
||||
|
||||
@@ -4961,7 +4961,7 @@ nla_put_failure:
|
||||
static bool fib6_info_uses_dev(const struct fib6_info *f6i,
|
||||
const struct net_device *dev)
|
||||
{
|
||||
if (f6i->fib6_nh.fib_nh_dev == dev)
|
||||
if (f6i->fib6_nh->fib_nh_dev == dev)
|
||||
return true;
|
||||
|
||||
if (f6i->fib6_nsiblings) {
|
||||
@@ -4969,7 +4969,7 @@ static bool fib6_info_uses_dev(const struct fib6_info *f6i,
|
||||
|
||||
list_for_each_entry_safe(sibling, next_sibling,
|
||||
&f6i->fib6_siblings, fib6_siblings) {
|
||||
if (sibling->fib6_nh.fib_nh_dev == dev)
|
||||
if (sibling->fib6_nh->fib_nh_dev == dev)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -5290,7 +5290,7 @@ static int ip6_route_dev_notify(struct notifier_block *this,
|
||||
return NOTIFY_OK;
|
||||
|
||||
if (event == NETDEV_REGISTER) {
|
||||
net->ipv6.fib6_null_entry->fib6_nh.fib_nh_dev = dev;
|
||||
net->ipv6.fib6_null_entry->fib6_nh->fib_nh_dev = dev;
|
||||
net->ipv6.ip6_null_entry->dst.dev = dev;
|
||||
net->ipv6.ip6_null_entry->rt6i_idev = in6_dev_get(dev);
|
||||
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
|
||||
@@ -5484,11 +5484,11 @@ static int __net_init ip6_route_net_init(struct net *net)
|
||||
if (dst_entries_init(&net->ipv6.ip6_dst_ops) < 0)
|
||||
goto out_ip6_dst_ops;
|
||||
|
||||
net->ipv6.fib6_null_entry = kmemdup(&fib6_null_entry_template,
|
||||
sizeof(*net->ipv6.fib6_null_entry),
|
||||
GFP_KERNEL);
|
||||
net->ipv6.fib6_null_entry = fib6_info_alloc(GFP_KERNEL, true);
|
||||
if (!net->ipv6.fib6_null_entry)
|
||||
goto out_ip6_dst_entries;
|
||||
memcpy(net->ipv6.fib6_null_entry, &fib6_null_entry_template,
|
||||
sizeof(*net->ipv6.fib6_null_entry));
|
||||
|
||||
net->ipv6.ip6_null_entry = kmemdup(&ip6_null_entry_template,
|
||||
sizeof(*net->ipv6.ip6_null_entry),
|
||||
@@ -5625,7 +5625,7 @@ void __init ip6_route_init_special_entries(void)
|
||||
/* Registering of the loopback is done before this portion of code,
|
||||
* the loopback reference in rt6_info will not be taken, do it
|
||||
* manually for init_net */
|
||||
init_net.ipv6.fib6_null_entry->fib6_nh.fib_nh_dev = init_net.loopback_dev;
|
||||
init_net.ipv6.fib6_null_entry->fib6_nh->fib_nh_dev = init_net.loopback_dev;
|
||||
init_net.ipv6.ip6_null_entry->dst.dev = init_net.loopback_dev;
|
||||
init_net.ipv6.ip6_null_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
|
||||
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
|
||||
|
Reference in New Issue
Block a user