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

Commit 071fb37e authored by David Miller's avatar David Miller Committed by David S. Miller
Browse files

ipv6: Move rt6_next from dst_entry into ipv6 route structure.

parent fe736e77
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -101,7 +101,6 @@ struct dst_entry {
	struct lwtunnel_state   *lwtstate;
	union {
		struct dst_entry	*next;
		struct rt6_info __rcu	*rt6_next;
	};
};

+3 −2
Original line number Diff line number Diff line
@@ -129,6 +129,7 @@ struct rt6_exception {

struct rt6_info {
	struct dst_entry		dst;
	struct rt6_info __rcu		*rt6_next;

	/*
	 * Tail elements of dst_entry (__refcnt etc.)
@@ -176,11 +177,11 @@ struct rt6_info {

#define for_each_fib6_node_rt_rcu(fn)					\
	for (rt = rcu_dereference((fn)->leaf); rt;			\
	     rt = rcu_dereference(rt->dst.rt6_next))
	     rt = rcu_dereference(rt->rt6_next))

#define for_each_fib6_walker_rt(w)					\
	for (rt = (w)->leaf; rt;					\
	     rt = rcu_dereference_protected(rt->dst.rt6_next, 1))
	     rt = rcu_dereference_protected(rt->rt6_next, 1))

static inline struct inet6_dev *ip6_dst_idev(struct dst_entry *dst)
{
+13 −13
Original line number Diff line number Diff line
@@ -893,7 +893,7 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,
	ins = &fn->leaf;

	for (iter = leaf; iter;
	     iter = rcu_dereference_protected(iter->dst.rt6_next,
	     iter = rcu_dereference_protected(iter->rt6_next,
				lockdep_is_held(&rt->rt6i_table->tb6_lock))) {
		/*
		 *	Search for duplicates
@@ -950,7 +950,7 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,
			break;

next_iter:
		ins = &iter->dst.rt6_next;
		ins = &iter->rt6_next;
	}

	if (fallback_ins && !found) {
@@ -979,7 +979,7 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,
					      &sibling->rt6i_siblings);
				break;
			}
			sibling = rcu_dereference_protected(sibling->dst.rt6_next,
			sibling = rcu_dereference_protected(sibling->rt6_next,
				    lockdep_is_held(&rt->rt6i_table->tb6_lock));
		}
		/* For each sibling in the list, increment the counter of
@@ -1009,7 +1009,7 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,
		if (err)
			return err;

		rcu_assign_pointer(rt->dst.rt6_next, iter);
		rcu_assign_pointer(rt->rt6_next, iter);
		atomic_inc(&rt->rt6i_ref);
		rcu_assign_pointer(rt->rt6i_node, fn);
		rcu_assign_pointer(*ins, rt);
@@ -1040,7 +1040,7 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,

		atomic_inc(&rt->rt6i_ref);
		rcu_assign_pointer(rt->rt6i_node, fn);
		rt->dst.rt6_next = iter->dst.rt6_next;
		rt->rt6_next = iter->rt6_next;
		rcu_assign_pointer(*ins, rt);
		call_fib6_entry_notifiers(info->nl_net, FIB_EVENT_ENTRY_REPLACE,
					  rt, extack);
@@ -1059,14 +1059,14 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,

		if (nsiblings) {
			/* Replacing an ECMP route, remove all siblings */
			ins = &rt->dst.rt6_next;
			ins = &rt->rt6_next;
			iter = rcu_dereference_protected(*ins,
				    lockdep_is_held(&rt->rt6i_table->tb6_lock));
			while (iter) {
				if (iter->rt6i_metric > rt->rt6i_metric)
					break;
				if (rt6_qualify_for_ecmp(iter)) {
					*ins = iter->dst.rt6_next;
					*ins = iter->rt6_next;
					iter->rt6i_node = NULL;
					fib6_purge_rt(iter, fn, info->nl_net);
					if (rcu_access_pointer(fn->rr_ptr) == iter)
@@ -1075,7 +1075,7 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,
					nsiblings--;
					info->nl_net->ipv6.rt6_stats->fib_rt_entries--;
				} else {
					ins = &iter->dst.rt6_next;
					ins = &iter->rt6_next;
				}
				iter = rcu_dereference_protected(*ins,
					lockdep_is_held(&rt->rt6i_table->tb6_lock));
@@ -1644,7 +1644,7 @@ static void fib6_del_route(struct fib6_table *table, struct fib6_node *fn,
	WARN_ON_ONCE(rt->rt6i_flags & RTF_CACHE);

	/* Unlink it */
	*rtp = rt->dst.rt6_next;
	*rtp = rt->rt6_next;
	rt->rt6i_node = NULL;
	net->ipv6.rt6_stats->fib_rt_entries--;
	net->ipv6.rt6_stats->fib_discarded_routes++;
@@ -1672,7 +1672,7 @@ static void fib6_del_route(struct fib6_table *table, struct fib6_node *fn,
	FOR_WALKERS(net, w) {
		if (w->state == FWS_C && w->leaf == rt) {
			RT6_TRACE("walker %p adjusted by delroute\n", w);
			w->leaf = rcu_dereference_protected(rt->dst.rt6_next,
			w->leaf = rcu_dereference_protected(rt->rt6_next,
					    lockdep_is_held(&table->tb6_lock));
			if (!w->leaf)
				w->state = FWS_U;
@@ -1731,7 +1731,7 @@ int fib6_del(struct rt6_info *rt, struct nl_info *info)
			fib6_del_route(table, fn, rtp, info);
			return 0;
		}
		rtp_next = &cur->dst.rt6_next;
		rtp_next = &cur->rt6_next;
	}
	return -ENOENT;
}
@@ -2208,7 +2208,7 @@ static int ipv6_route_yield(struct fib6_walker *w)

	do {
		iter->w.leaf = rcu_dereference_protected(
				iter->w.leaf->dst.rt6_next,
				iter->w.leaf->rt6_next,
				lockdep_is_held(&iter->tbl->tb6_lock));
		iter->skip--;
		if (!iter->skip && iter->w.leaf)
@@ -2274,7 +2274,7 @@ static void *ipv6_route_seq_next(struct seq_file *seq, void *v, loff_t *pos)
	if (!v)
		goto iter_table;

	n = rcu_dereference_bh(((struct rt6_info *)v)->dst.rt6_next);
	n = rcu_dereference_bh(((struct rt6_info *)v)->rt6_next);
	if (n) {
		++*pos;
		return n;
+5 −5
Original line number Diff line number Diff line
@@ -502,7 +502,7 @@ static inline struct rt6_info *rt6_device_match(struct net *net,
	if (!oif && ipv6_addr_any(saddr))
		goto out;

	for (sprt = rt; sprt; sprt = rcu_dereference(sprt->dst.rt6_next)) {
	for (sprt = rt; sprt; sprt = rcu_dereference(sprt->rt6_next)) {
		struct net_device *dev = sprt->dst.dev;

		if (oif) {
@@ -721,7 +721,7 @@ static struct rt6_info *find_rr_leaf(struct fib6_node *fn,

	match = NULL;
	cont = NULL;
	for (rt = rr_head; rt; rt = rcu_dereference(rt->dst.rt6_next)) {
	for (rt = rr_head; rt; rt = rcu_dereference(rt->rt6_next)) {
		if (rt->rt6i_metric != metric) {
			cont = rt;
			break;
@@ -731,7 +731,7 @@ static struct rt6_info *find_rr_leaf(struct fib6_node *fn,
	}

	for (rt = leaf; rt && rt != rr_head;
	     rt = rcu_dereference(rt->dst.rt6_next)) {
	     rt = rcu_dereference(rt->rt6_next)) {
		if (rt->rt6i_metric != metric) {
			cont = rt;
			break;
@@ -743,7 +743,7 @@ static struct rt6_info *find_rr_leaf(struct fib6_node *fn,
	if (match || !cont)
		return match;

	for (rt = cont; rt; rt = rcu_dereference(rt->dst.rt6_next))
	for (rt = cont; rt; rt = rcu_dereference(rt->rt6_next))
		match = find_match(rt, oif, strict, &mpri, match, do_rr);

	return match;
@@ -781,7 +781,7 @@ static struct rt6_info *rt6_select(struct net *net, struct fib6_node *fn,
			     &do_rr);

	if (do_rr) {
		struct rt6_info *next = rcu_dereference(rt0->dst.rt6_next);
		struct rt6_info *next = rcu_dereference(rt0->rt6_next);

		/* no entries matched; do round-robin */
		if (!next || next->rt6i_metric != rt0->rt6i_metric)