On 8/26/20 10:48 AM, Ido Schimmel wrote: > From: Ido Schimmel <ido...@nvidia.com> > > Each nexthop group contains an indication if it has IPv4 nexthops > ('has_v4'). Its purpose is to prevent IPv6 routes from using groups with > IPv4 nexthops. > > However, the indication is not updated when a nexthop is removed. This > results in the kernel wrongly rejecting IPv6 routes from pointing to > groups that only contain IPv6 nexthops. Example: > > # ip nexthop replace id 1 via 192.0.2.2 dev dummy10 > # ip nexthop replace id 2 via 2001:db8:1::2 dev dummy10 > # ip nexthop replace id 10 group 1/2 > # ip nexthop del id 1 > # ip route replace 2001:db8:10::/64 nhid 10 > Error: IPv6 routes can not use an IPv4 nexthop. > > Solve this by updating the indication according to the new set of > member nexthops. > > Signed-off-by: Ido Schimmel <ido...@nvidia.com> > --- > net/ipv4/nexthop.c | 8 +++++++- > 1 file changed, 7 insertions(+), 1 deletion(-) > > diff --git a/net/ipv4/nexthop.c b/net/ipv4/nexthop.c > index 1b736e3e1baa..5199a2815df6 100644 > --- a/net/ipv4/nexthop.c > +++ b/net/ipv4/nexthop.c > @@ -797,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; > @@ -806,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; >
Reviewed-by: David Ahern <dsah...@gmail.com>