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

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
...@@ -133,12 +133,9 @@ static struct nexthop *nexthop_alloc(void) ...@@ -133,12 +133,9 @@ static struct nexthop *nexthop_alloc(void)
static struct nh_group *nexthop_grp_alloc(u16 num_nh) 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; struct nh_group *nhg;
nhg = kzalloc(sz, GFP_KERNEL); nhg = kzalloc(struct_size(nhg, nh_entries, num_nh), GFP_KERNEL);
if (nhg) if (nhg)
nhg->num_nh = num_nh; nhg->num_nh = num_nh;
...@@ -279,7 +276,7 @@ static int nh_fill_node(struct sk_buff *skb, struct nexthop *nh, ...@@ -279,7 +276,7 @@ static int nh_fill_node(struct sk_buff *skb, struct nexthop *nh,
case AF_INET: case AF_INET:
fib_nh = &nhi->fib_nh; fib_nh = &nhi->fib_nh;
if (fib_nh->fib_nh_gw_family && 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; goto nla_put_failure;
break; break;
...@@ -800,7 +797,7 @@ static void remove_nh_grp_entry(struct net *net, struct nh_grp_entry *nhge, ...@@ -800,7 +797,7 @@ static void remove_nh_grp_entry(struct net *net, struct nh_grp_entry *nhge,
return; return;
} }
newg->has_v4 = nhg->has_v4; newg->has_v4 = false;
newg->mpath = nhg->mpath; newg->mpath = nhg->mpath;
newg->fdb_nh = nhg->fdb_nh; newg->fdb_nh = nhg->fdb_nh;
newg->num_nh = nhg->num_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, ...@@ -809,12 +806,18 @@ static void remove_nh_grp_entry(struct net *net, struct nh_grp_entry *nhge,
nhges = nhg->nh_entries; nhges = nhg->nh_entries;
new_nhges = newg->nh_entries; new_nhges = newg->nh_entries;
for (i = 0, j = 0; i < nhg->num_nh; ++i) { for (i = 0, j = 0; i < nhg->num_nh; ++i) {
struct nh_info *nhi;
/* current nexthop getting removed */ /* current nexthop getting removed */
if (nhg->nh_entries[i].nh == nh) { if (nhg->nh_entries[i].nh == nh) {
newg->num_nh--; newg->num_nh--;
continue; continue;
} }
nhi = rtnl_dereference(nhges[i].nh->nh_info);
if (nhi->family == AF_INET)
newg->has_v4 = true;
list_del(&nhges[i].nh_list); list_del(&nhges[i].nh_list);
new_nhges[j].nh_parent = nhges[i].nh_parent; new_nhges[j].nh_parent = nhges[i].nh_parent;
new_nhges[j].nh = nhges[i].nh; new_nhges[j].nh = nhges[i].nh;
...@@ -961,6 +964,23 @@ static int replace_nexthop_grp(struct net *net, struct nexthop *old, ...@@ -961,6 +964,23 @@ static int replace_nexthop_grp(struct net *net, struct nexthop *old,
return 0; 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, static int replace_nexthop_single(struct net *net, struct nexthop *old,
struct nexthop *new, struct nexthop *new,
struct netlink_ext_ack *extack) struct netlink_ext_ack *extack)
...@@ -984,6 +1004,21 @@ static int replace_nexthop_single(struct net *net, struct nexthop *old, ...@@ -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(old->nh_info, newi);
rcu_assign_pointer(new->nh_info, oldi); 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; return 0;
} }
...@@ -1101,7 +1136,7 @@ static int insert_nexthop(struct net *net, struct nexthop *new_nh, ...@@ -1101,7 +1136,7 @@ static int insert_nexthop(struct net *net, struct nexthop *new_nh,
while (1) { while (1) {
struct nexthop *nh; struct nexthop *nh;
next = rtnl_dereference(*pp); next = *pp;
if (!next) if (!next)
break; break;
......
...@@ -739,6 +739,36 @@ ipv6_fcnal_runtime() ...@@ -739,6 +739,36 @@ ipv6_fcnal_runtime()
run_cmd "$IP nexthop replace id 81 via 172.16.1.1 dev veth1" 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" 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 $IP nexthop flush >/dev/null 2>&1
# #
......
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