Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+16 −16
Original line number Diff line number Diff line
@@ -2770,9 +2770,9 @@ mlxsw_sp_nexthop6_group_cmp(const struct mlxsw_sp_nexthop_group *nh_grp,
		struct in6_addr *gw;
		int ifindex, weight;

		ifindex = mlxsw_sp_rt6->rt->dst.dev->ifindex;
		weight = mlxsw_sp_rt6->rt->rt6i_nh_weight;
		gw = &mlxsw_sp_rt6->rt->rt6i_gateway;
		ifindex = mlxsw_sp_rt6->rt->fib6_nh.nh_dev->ifindex;
		weight = mlxsw_sp_rt6->rt->fib6_nh.nh_weight;
		gw = &mlxsw_sp_rt6->rt->fib6_nh.nh_gw;
		if (!mlxsw_sp_nexthop6_group_has_nexthop(nh_grp, gw, ifindex,
							 weight))
			return false;
@@ -2838,7 +2838,7 @@ mlxsw_sp_nexthop6_group_hash(struct mlxsw_sp_fib6_entry *fib6_entry, u32 seed)
	struct net_device *dev;

	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;
	}

@@ -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 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,
				    &rt->rt6i_gateway))
				    &rt->fib6_nh.nh_gw))
			return nh;
		continue;
	}
@@ -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) {
		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;
	}

@@ -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);
		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
			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)
	list_for_each_entry(mlxsw_sp_rt6, &fib6_entry->rt6_list, list) {
		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,
					const struct rt6_info *rt,
					enum mlxsw_sp_ipip_type *ret)
{
	return rt->dst.dev &&
	       mlxsw_sp_netdev_ipip_type(mlxsw_sp, rt->dst.dev, ret);
	return rt->fib6_nh.nh_dev &&
	       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,
@@ -4829,7 +4829,7 @@ static int mlxsw_sp_nexthop6_type_init(struct mlxsw_sp *mlxsw_sp,
{
	const struct mlxsw_sp_ipip_ops *ipip_ops;
	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;
	int err;

@@ -4872,11 +4872,11 @@ static int mlxsw_sp_nexthop6_init(struct mlxsw_sp *mlxsw_sp,
				  struct mlxsw_sp_nexthop *nh,
				  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_weight = rt->rt6i_nh_weight;
	memcpy(&nh->gw_addr, &rt->rt6i_gateway, sizeof(nh->gw_addr));
	nh->nh_weight = rt->fib6_nh.nh_weight;
	memcpy(&nh->gw_addr, &rt->fib6_nh.nh_gw, sizeof(nh->gw_addr));
	mlxsw_sp_nexthop_counter_alloc(mlxsw_sp, nh);

	list_add_tail(&nh->router_list_node, &mlxsw_sp->router->nexthop_list);
+12 −4
Original line number Diff line number Diff line
@@ -127,6 +127,16 @@ struct rt6_exception {
#define FIB6_EXCEPTION_BUCKET_SIZE (1 << FIB6_EXCEPTION_BUCKET_SIZE_SHIFT)
#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 dst_entry		dst;
	struct rt6_info __rcu		*rt6_next;
@@ -149,12 +159,9 @@ struct rt6_info {
	 */
	struct list_head		rt6i_siblings;
	unsigned int			rt6i_nsiblings;
	atomic_t			rt6i_nh_upper_bound;

	atomic_t			rt6i_ref;

	unsigned int			rt6i_nh_flags;

	/* These are in a separate cache line. */
	struct rt6key			rt6i_dst ____cacheline_aligned_in_smp;
	u32				rt6i_flags;
@@ -171,13 +178,14 @@ struct rt6_info {
	u32				rt6i_metric;
	u32				rt6i_pmtu;
	/* more non-fragment space at head required */
	int				rt6i_nh_weight;
	unsigned short			rt6i_nfheader_len;
	u8				rt6i_protocol;
	u8				fib6_type;
	u8				exception_bucket_flushed:1,
					should_flush:1,
					unused:6;

	struct fib6_nh			fib6_nh;
};

#define for_each_fib6_node_rt_rcu(fn)					\
+3 −3
Original line number Diff line number Diff line
@@ -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)
{
	return a->dst.dev == b->dst.dev &&
	return a->fib6_nh.nh_dev == b->fib6_nh.nh_dev &&
	       a->rt6i_idev == b->rt6i_idev &&
	       ipv6_addr_equal(&a->rt6i_gateway, &b->rt6i_gateway) &&
	       !lwtunnel_cmp_encap(a->dst.lwtstate, b->dst.lwtstate);
	       ipv6_addr_equal(&a->fib6_nh.nh_gw, &b->fib6_nh.nh_gw) &&
	       !lwtunnel_cmp_encap(a->fib6_nh.nh_lwtstate, b->fib6_nh.nh_lwtstate);
}

#endif
+1 −1
Original line number Diff line number Diff line
@@ -2369,7 +2369,7 @@ static struct rt6_info *addrconf_get_prefix_route(const struct in6_addr *pfx,
		goto out;

	for_each_fib6_node_rt_rcu(fn) {
		if (rt->dst.dev->ifindex != dev->ifindex)
		if (rt->fib6_nh.nh_dev->ifindex != dev->ifindex)
			continue;
		if ((rt->rt6i_flags & flags) != flags)
			continue;
+4 −2
Original line number Diff line number Diff line
@@ -2221,6 +2221,7 @@ static int ipv6_route_seq_show(struct seq_file *seq, void *v)
{
	struct rt6_info *rt = v;
	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);

@@ -2230,14 +2231,15 @@ static int ipv6_route_seq_show(struct seq_file *seq, void *v)
	seq_puts(seq, "00000000000000000000000000000000 00 ");
#endif
	if (rt->rt6i_flags & RTF_GATEWAY)
		seq_printf(seq, "%pi6", &rt->rt6i_gateway);
		seq_printf(seq, "%pi6", &rt->fib6_nh.nh_gw);
	else
		seq_puts(seq, "00000000000000000000000000000000");

	dev = rt->fib6_nh.nh_dev;
	seq_printf(seq, " %08x %08x %08x %08x %8s\n",
		   rt->rt6i_metric, atomic_read(&rt->dst.__refcnt),
		   rt->dst.__use, rt->rt6i_flags,
		   rt->dst.dev ? rt->dst.dev->name : "");
		   dev ? dev->name : "");
	iter->w.leaf = NULL;
	return 0;
}
Loading