Commit 5e670d84 authored by David Ahern's avatar David Ahern Committed by David S. Miller

net/ipv6: Move nexthop data to fib6_nh

Introduce fib6_nh structure and move nexthop related data from
rt6_info and rt6_info.dst to fib6_nh. References to dev, gateway or
lwtstate from a FIB lookup perspective are converted to use fib6_nh;
datapath references to dst version are left as is.
Signed-off-by: default avatarDavid Ahern <dsahern@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent e8478e80
...@@ -2770,9 +2770,9 @@ mlxsw_sp_nexthop6_group_cmp(const struct mlxsw_sp_nexthop_group *nh_grp, ...@@ -2770,9 +2770,9 @@ mlxsw_sp_nexthop6_group_cmp(const struct mlxsw_sp_nexthop_group *nh_grp,
struct in6_addr *gw; struct in6_addr *gw;
int ifindex, weight; int ifindex, weight;
ifindex = mlxsw_sp_rt6->rt->dst.dev->ifindex; ifindex = mlxsw_sp_rt6->rt->fib6_nh.nh_dev->ifindex;
weight = mlxsw_sp_rt6->rt->rt6i_nh_weight; weight = mlxsw_sp_rt6->rt->fib6_nh.nh_weight;
gw = &mlxsw_sp_rt6->rt->rt6i_gateway; gw = &mlxsw_sp_rt6->rt->fib6_nh.nh_gw;
if (!mlxsw_sp_nexthop6_group_has_nexthop(nh_grp, gw, ifindex, if (!mlxsw_sp_nexthop6_group_has_nexthop(nh_grp, gw, ifindex,
weight)) weight))
return false; return false;
...@@ -2838,7 +2838,7 @@ mlxsw_sp_nexthop6_group_hash(struct mlxsw_sp_fib6_entry *fib6_entry, u32 seed) ...@@ -2838,7 +2838,7 @@ mlxsw_sp_nexthop6_group_hash(struct mlxsw_sp_fib6_entry *fib6_entry, u32 seed)
struct net_device *dev; struct net_device *dev;
list_for_each_entry(mlxsw_sp_rt6, &fib6_entry->rt6_list, list) { list_for_each_entry(mlxsw_sp_rt6, &fib6_entry->rt6_list, list) {
dev = mlxsw_sp_rt6->rt->dst.dev; dev = mlxsw_sp_rt6->rt->fib6_nh.nh_dev;
val ^= dev->ifindex; val ^= dev->ifindex;
} }
...@@ -3836,9 +3836,9 @@ mlxsw_sp_rt6_nexthop(struct mlxsw_sp_nexthop_group *nh_grp, ...@@ -3836,9 +3836,9 @@ mlxsw_sp_rt6_nexthop(struct mlxsw_sp_nexthop_group *nh_grp,
struct mlxsw_sp_nexthop *nh = &nh_grp->nexthops[i]; struct mlxsw_sp_nexthop *nh = &nh_grp->nexthops[i];
struct rt6_info *rt = mlxsw_sp_rt6->rt; struct rt6_info *rt = mlxsw_sp_rt6->rt;
if (nh->rif && nh->rif->dev == rt->dst.dev && if (nh->rif && nh->rif->dev == rt->fib6_nh.nh_dev &&
ipv6_addr_equal((const struct in6_addr *) &nh->gw_addr, ipv6_addr_equal((const struct in6_addr *) &nh->gw_addr,
&rt->rt6i_gateway)) &rt->fib6_nh.nh_gw))
return nh; return nh;
continue; continue;
} }
...@@ -3895,7 +3895,7 @@ mlxsw_sp_fib6_entry_offload_set(struct mlxsw_sp_fib_entry *fib_entry) ...@@ -3895,7 +3895,7 @@ mlxsw_sp_fib6_entry_offload_set(struct mlxsw_sp_fib_entry *fib_entry)
if (fib_entry->type == MLXSW_SP_FIB_ENTRY_TYPE_LOCAL) { if (fib_entry->type == MLXSW_SP_FIB_ENTRY_TYPE_LOCAL) {
list_first_entry(&fib6_entry->rt6_list, struct mlxsw_sp_rt6, list_first_entry(&fib6_entry->rt6_list, struct mlxsw_sp_rt6,
list)->rt->rt6i_nh_flags |= RTNH_F_OFFLOAD; list)->rt->fib6_nh.nh_flags |= RTNH_F_OFFLOAD;
return; return;
} }
...@@ -3905,9 +3905,9 @@ mlxsw_sp_fib6_entry_offload_set(struct mlxsw_sp_fib_entry *fib_entry) ...@@ -3905,9 +3905,9 @@ mlxsw_sp_fib6_entry_offload_set(struct mlxsw_sp_fib_entry *fib_entry)
nh = mlxsw_sp_rt6_nexthop(nh_grp, mlxsw_sp_rt6); nh = mlxsw_sp_rt6_nexthop(nh_grp, mlxsw_sp_rt6);
if (nh && nh->offloaded) if (nh && nh->offloaded)
mlxsw_sp_rt6->rt->rt6i_nh_flags |= RTNH_F_OFFLOAD; mlxsw_sp_rt6->rt->fib6_nh.nh_flags |= RTNH_F_OFFLOAD;
else else
mlxsw_sp_rt6->rt->rt6i_nh_flags &= ~RTNH_F_OFFLOAD; mlxsw_sp_rt6->rt->fib6_nh.nh_flags &= ~RTNH_F_OFFLOAD;
} }
} }
...@@ -3922,7 +3922,7 @@ mlxsw_sp_fib6_entry_offload_unset(struct mlxsw_sp_fib_entry *fib_entry) ...@@ -3922,7 +3922,7 @@ mlxsw_sp_fib6_entry_offload_unset(struct mlxsw_sp_fib_entry *fib_entry)
list_for_each_entry(mlxsw_sp_rt6, &fib6_entry->rt6_list, list) { list_for_each_entry(mlxsw_sp_rt6, &fib6_entry->rt6_list, list) {
struct rt6_info *rt = mlxsw_sp_rt6->rt; struct rt6_info *rt = mlxsw_sp_rt6->rt;
rt->rt6i_nh_flags &= ~RTNH_F_OFFLOAD; rt->fib6_nh.nh_flags &= ~RTNH_F_OFFLOAD;
} }
} }
...@@ -4818,8 +4818,8 @@ static bool mlxsw_sp_nexthop6_ipip_type(const struct mlxsw_sp *mlxsw_sp, ...@@ -4818,8 +4818,8 @@ static bool mlxsw_sp_nexthop6_ipip_type(const struct mlxsw_sp *mlxsw_sp,
const struct rt6_info *rt, const struct rt6_info *rt,
enum mlxsw_sp_ipip_type *ret) enum mlxsw_sp_ipip_type *ret)
{ {
return rt->dst.dev && return rt->fib6_nh.nh_dev &&
mlxsw_sp_netdev_ipip_type(mlxsw_sp, rt->dst.dev, ret); mlxsw_sp_netdev_ipip_type(mlxsw_sp, rt->fib6_nh.nh_dev, ret);
} }
static int mlxsw_sp_nexthop6_type_init(struct mlxsw_sp *mlxsw_sp, static int mlxsw_sp_nexthop6_type_init(struct mlxsw_sp *mlxsw_sp,
...@@ -4829,7 +4829,7 @@ static int mlxsw_sp_nexthop6_type_init(struct mlxsw_sp *mlxsw_sp, ...@@ -4829,7 +4829,7 @@ static int mlxsw_sp_nexthop6_type_init(struct mlxsw_sp *mlxsw_sp,
{ {
const struct mlxsw_sp_ipip_ops *ipip_ops; const struct mlxsw_sp_ipip_ops *ipip_ops;
struct mlxsw_sp_ipip_entry *ipip_entry; struct mlxsw_sp_ipip_entry *ipip_entry;
struct net_device *dev = rt->dst.dev; struct net_device *dev = rt->fib6_nh.nh_dev;
struct mlxsw_sp_rif *rif; struct mlxsw_sp_rif *rif;
int err; int err;
...@@ -4872,11 +4872,11 @@ static int mlxsw_sp_nexthop6_init(struct mlxsw_sp *mlxsw_sp, ...@@ -4872,11 +4872,11 @@ static int mlxsw_sp_nexthop6_init(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop *nh, struct mlxsw_sp_nexthop *nh,
const struct rt6_info *rt) const struct rt6_info *rt)
{ {
struct net_device *dev = rt->dst.dev; struct net_device *dev = rt->fib6_nh.nh_dev;
nh->nh_grp = nh_grp; nh->nh_grp = nh_grp;
nh->nh_weight = rt->rt6i_nh_weight; nh->nh_weight = rt->fib6_nh.nh_weight;
memcpy(&nh->gw_addr, &rt->rt6i_gateway, sizeof(nh->gw_addr)); memcpy(&nh->gw_addr, &rt->fib6_nh.nh_gw, sizeof(nh->gw_addr));
mlxsw_sp_nexthop_counter_alloc(mlxsw_sp, nh); mlxsw_sp_nexthop_counter_alloc(mlxsw_sp, nh);
list_add_tail(&nh->router_list_node, &mlxsw_sp->router->nexthop_list); list_add_tail(&nh->router_list_node, &mlxsw_sp->router->nexthop_list);
......
...@@ -127,6 +127,16 @@ struct rt6_exception { ...@@ -127,6 +127,16 @@ struct rt6_exception {
#define FIB6_EXCEPTION_BUCKET_SIZE (1 << FIB6_EXCEPTION_BUCKET_SIZE_SHIFT) #define FIB6_EXCEPTION_BUCKET_SIZE (1 << FIB6_EXCEPTION_BUCKET_SIZE_SHIFT)
#define FIB6_MAX_DEPTH 5 #define FIB6_MAX_DEPTH 5
struct fib6_nh {
struct in6_addr nh_gw;
struct net_device *nh_dev;
struct lwtunnel_state *nh_lwtstate;
unsigned int nh_flags;
atomic_t nh_upper_bound;
int nh_weight;
};
struct rt6_info { struct rt6_info {
struct dst_entry dst; struct dst_entry dst;
struct rt6_info __rcu *rt6_next; struct rt6_info __rcu *rt6_next;
...@@ -149,12 +159,9 @@ struct rt6_info { ...@@ -149,12 +159,9 @@ struct rt6_info {
*/ */
struct list_head rt6i_siblings; struct list_head rt6i_siblings;
unsigned int rt6i_nsiblings; unsigned int rt6i_nsiblings;
atomic_t rt6i_nh_upper_bound;
atomic_t rt6i_ref; atomic_t rt6i_ref;
unsigned int rt6i_nh_flags;
/* These are in a separate cache line. */ /* These are in a separate cache line. */
struct rt6key rt6i_dst ____cacheline_aligned_in_smp; struct rt6key rt6i_dst ____cacheline_aligned_in_smp;
u32 rt6i_flags; u32 rt6i_flags;
...@@ -171,13 +178,14 @@ struct rt6_info { ...@@ -171,13 +178,14 @@ struct rt6_info {
u32 rt6i_metric; u32 rt6i_metric;
u32 rt6i_pmtu; u32 rt6i_pmtu;
/* more non-fragment space at head required */ /* more non-fragment space at head required */
int rt6i_nh_weight;
unsigned short rt6i_nfheader_len; unsigned short rt6i_nfheader_len;
u8 rt6i_protocol; u8 rt6i_protocol;
u8 fib6_type; u8 fib6_type;
u8 exception_bucket_flushed:1, u8 exception_bucket_flushed:1,
should_flush:1, should_flush:1,
unused:6; unused:6;
struct fib6_nh fib6_nh;
}; };
#define for_each_fib6_node_rt_rcu(fn) \ #define for_each_fib6_node_rt_rcu(fn) \
......
...@@ -273,10 +273,10 @@ static inline struct in6_addr *rt6_nexthop(struct rt6_info *rt, ...@@ -273,10 +273,10 @@ static inline struct in6_addr *rt6_nexthop(struct rt6_info *rt,
static inline bool rt6_duplicate_nexthop(struct rt6_info *a, struct rt6_info *b) static inline bool rt6_duplicate_nexthop(struct rt6_info *a, struct rt6_info *b)
{ {
return a->dst.dev == b->dst.dev && return a->fib6_nh.nh_dev == b->fib6_nh.nh_dev &&
a->rt6i_idev == b->rt6i_idev && a->rt6i_idev == b->rt6i_idev &&
ipv6_addr_equal(&a->rt6i_gateway, &b->rt6i_gateway) && ipv6_addr_equal(&a->fib6_nh.nh_gw, &b->fib6_nh.nh_gw) &&
!lwtunnel_cmp_encap(a->dst.lwtstate, b->dst.lwtstate); !lwtunnel_cmp_encap(a->fib6_nh.nh_lwtstate, b->fib6_nh.nh_lwtstate);
} }
#endif #endif
...@@ -2369,7 +2369,7 @@ static struct rt6_info *addrconf_get_prefix_route(const struct in6_addr *pfx, ...@@ -2369,7 +2369,7 @@ static struct rt6_info *addrconf_get_prefix_route(const struct in6_addr *pfx,
goto out; goto out;
for_each_fib6_node_rt_rcu(fn) { for_each_fib6_node_rt_rcu(fn) {
if (rt->dst.dev->ifindex != dev->ifindex) if (rt->fib6_nh.nh_dev->ifindex != dev->ifindex)
continue; continue;
if ((rt->rt6i_flags & flags) != flags) if ((rt->rt6i_flags & flags) != flags)
continue; continue;
......
...@@ -2221,6 +2221,7 @@ static int ipv6_route_seq_show(struct seq_file *seq, void *v) ...@@ -2221,6 +2221,7 @@ static int ipv6_route_seq_show(struct seq_file *seq, void *v)
{ {
struct rt6_info *rt = v; struct rt6_info *rt = v;
struct ipv6_route_iter *iter = seq->private; struct ipv6_route_iter *iter = seq->private;
const struct net_device *dev;
seq_printf(seq, "%pi6 %02x ", &rt->rt6i_dst.addr, rt->rt6i_dst.plen); seq_printf(seq, "%pi6 %02x ", &rt->rt6i_dst.addr, rt->rt6i_dst.plen);
...@@ -2230,14 +2231,15 @@ static int ipv6_route_seq_show(struct seq_file *seq, void *v) ...@@ -2230,14 +2231,15 @@ static int ipv6_route_seq_show(struct seq_file *seq, void *v)
seq_puts(seq, "00000000000000000000000000000000 00 "); seq_puts(seq, "00000000000000000000000000000000 00 ");
#endif #endif
if (rt->rt6i_flags & RTF_GATEWAY) if (rt->rt6i_flags & RTF_GATEWAY)
seq_printf(seq, "%pi6", &rt->rt6i_gateway); seq_printf(seq, "%pi6", &rt->fib6_nh.nh_gw);
else else
seq_puts(seq, "00000000000000000000000000000000"); seq_puts(seq, "00000000000000000000000000000000");
dev = rt->fib6_nh.nh_dev;
seq_printf(seq, " %08x %08x %08x %08x %8s\n", seq_printf(seq, " %08x %08x %08x %08x %8s\n",
rt->rt6i_metric, atomic_read(&rt->dst.__refcnt), rt->rt6i_metric, atomic_read(&rt->dst.__refcnt),
rt->dst.__use, rt->rt6i_flags, rt->dst.__use, rt->rt6i_flags,
rt->dst.dev ? rt->dst.dev->name : ""); dev ? dev->name : "");
iter->w.leaf = NULL; iter->w.leaf = NULL;
return 0; return 0;
} }
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment