Commit bf82d565 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'ipv4-nexthop-Various-improvements'



Ido Schimmel says:

====================
ipv4: nexthop: Various improvements

This patch set contains various improvements that I made to the nexthop
object code while studying it towards my upcoming changes.

While patches #4 and #6 fix bugs, they are not regressions (never
worked). They also do not occur to me as critical issues, which is why I
am targeting them at net-next.

Tested with fib_nexthops.sh:

Tests passed: 134
Tests failed:   0
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 751e4251 041bc0dc
Loading
Loading
Loading
Loading
+42 −7
Original line number Diff line number Diff line
@@ -133,12 +133,9 @@ static struct nexthop *nexthop_alloc(void)

static struct nh_group *nexthop_grp_alloc(u16 num_nh)
{
	size_t sz = offsetof(struct nexthop, nh_grp)
		    + sizeof(struct nh_group)
		    + sizeof(struct nh_grp_entry) * num_nh;
	struct nh_group *nhg;

	nhg = kzalloc(sz, GFP_KERNEL);
	nhg = kzalloc(struct_size(nhg, nh_entries, num_nh), GFP_KERNEL);
	if (nhg)
		nhg->num_nh = num_nh;

@@ -279,7 +276,7 @@ static int nh_fill_node(struct sk_buff *skb, struct nexthop *nh,
	case AF_INET:
		fib_nh = &nhi->fib_nh;
		if (fib_nh->fib_nh_gw_family &&
		    nla_put_u32(skb, NHA_GATEWAY, fib_nh->fib_nh_gw4))
		    nla_put_be32(skb, NHA_GATEWAY, fib_nh->fib_nh_gw4))
			goto nla_put_failure;
		break;

@@ -800,7 +797,7 @@ static void remove_nh_grp_entry(struct net *net, struct nh_grp_entry *nhge,
		return;
	}

	newg->has_v4 = nhg->has_v4;
	newg->has_v4 = false;
	newg->mpath = nhg->mpath;
	newg->fdb_nh = nhg->fdb_nh;
	newg->num_nh = nhg->num_nh;
@@ -809,12 +806,18 @@ static void remove_nh_grp_entry(struct net *net, struct nh_grp_entry *nhge,
	nhges = nhg->nh_entries;
	new_nhges = newg->nh_entries;
	for (i = 0, j = 0; i < nhg->num_nh; ++i) {
		struct nh_info *nhi;

		/* current nexthop getting removed */
		if (nhg->nh_entries[i].nh == nh) {
			newg->num_nh--;
			continue;
		}

		nhi = rtnl_dereference(nhges[i].nh->nh_info);
		if (nhi->family == AF_INET)
			newg->has_v4 = true;

		list_del(&nhges[i].nh_list);
		new_nhges[j].nh_parent = nhges[i].nh_parent;
		new_nhges[j].nh = nhges[i].nh;
@@ -961,6 +964,23 @@ static int replace_nexthop_grp(struct net *net, struct nexthop *old,
	return 0;
}

static void nh_group_v4_update(struct nh_group *nhg)
{
	struct nh_grp_entry *nhges;
	bool has_v4 = false;
	int i;

	nhges = nhg->nh_entries;
	for (i = 0; i < nhg->num_nh; i++) {
		struct nh_info *nhi;

		nhi = rtnl_dereference(nhges[i].nh->nh_info);
		if (nhi->family == AF_INET)
			has_v4 = true;
	}
	nhg->has_v4 = has_v4;
}

static int replace_nexthop_single(struct net *net, struct nexthop *old,
				  struct nexthop *new,
				  struct netlink_ext_ack *extack)
@@ -984,6 +1004,21 @@ static int replace_nexthop_single(struct net *net, struct nexthop *old,
	rcu_assign_pointer(old->nh_info, newi);
	rcu_assign_pointer(new->nh_info, oldi);

	/* When replacing an IPv4 nexthop with an IPv6 nexthop, potentially
	 * update IPv4 indication in all the groups using the nexthop.
	 */
	if (oldi->family == AF_INET && newi->family == AF_INET6) {
		struct nh_grp_entry *nhge;

		list_for_each_entry(nhge, &old->grp_list, nh_list) {
			struct nexthop *nhp = nhge->nh_parent;
			struct nh_group *nhg;

			nhg = rtnl_dereference(nhp->nh_grp);
			nh_group_v4_update(nhg);
		}
	}

	return 0;
}

@@ -1101,7 +1136,7 @@ static int insert_nexthop(struct net *net, struct nexthop *new_nh,
	while (1) {
		struct nexthop *nh;

		next = rtnl_dereference(*pp);
		next = *pp;
		if (!next)
			break;

+30 −0
Original line number Diff line number Diff line
@@ -739,6 +739,36 @@ ipv6_fcnal_runtime()
	run_cmd "$IP nexthop replace id 81 via 172.16.1.1 dev veth1"
	log_test $? 2 "Nexthop replace of group entry - v6 route, v4 nexthop"

	run_cmd "$IP nexthop add id 86 via 2001:db8:92::2 dev veth3"
	run_cmd "$IP nexthop add id 87 via 172.16.1.1 dev veth1"
	run_cmd "$IP nexthop add id 88 via 172.16.1.1 dev veth1"
	run_cmd "$IP nexthop add id 124 group 86/87/88"
	run_cmd "$IP ro replace 2001:db8:101::1/128 nhid 124"
	log_test $? 2 "IPv6 route can not have a group with v4 and v6 gateways"

	run_cmd "$IP nexthop del id 88"
	run_cmd "$IP ro replace 2001:db8:101::1/128 nhid 124"
	log_test $? 2 "IPv6 route can not have a group with v4 and v6 gateways"

	run_cmd "$IP nexthop del id 87"
	run_cmd "$IP ro replace 2001:db8:101::1/128 nhid 124"
	log_test $? 0 "IPv6 route using a group after removing v4 gateways"

	run_cmd "$IP ro delete 2001:db8:101::1/128"
	run_cmd "$IP nexthop add id 87 via 172.16.1.1 dev veth1"
	run_cmd "$IP nexthop add id 88 via 172.16.1.1 dev veth1"
	run_cmd "$IP nexthop replace id 124 group 86/87/88"
	run_cmd "$IP ro replace 2001:db8:101::1/128 nhid 124"
	log_test $? 2 "IPv6 route can not have a group with v4 and v6 gateways"

	run_cmd "$IP nexthop replace id 88 via 2001:db8:92::2 dev veth3"
	run_cmd "$IP ro replace 2001:db8:101::1/128 nhid 124"
	log_test $? 2 "IPv6 route can not have a group with v4 and v6 gateways"

	run_cmd "$IP nexthop replace id 87 via 2001:db8:92::2 dev veth3"
	run_cmd "$IP ro replace 2001:db8:101::1/128 nhid 124"
	log_test $? 0 "IPv6 route using a group after replacing v4 gateways"

	$IP nexthop flush >/dev/null 2>&1

	#