Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nl_l3: fix nnhs handling a bit #441

Merged
merged 3 commits into from
Jun 6, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 22 additions & 15 deletions src/netlink/nl_l3.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1849,22 +1849,23 @@ int nl_l3::add_l3_unicast_route(rtnl_route *r, bool update_route) {
this, nh_params{net_params{rtnl_route_get_dst(r), nh.ifindex}, nh});
}

switch (nnhs) {
case 0:
// Not yet determined next-hop, the rule must be installed to the switch
// pointing to controller and then updated after next-hop registration
rv = add_l3_unicast_route(rtnl_route_get_dst(r), 0, false, update_route,
vrf_id);
break;
case 1:
// Single known next-hop
rv = add_l3_unicast_route(rtnl_route_get_dst(r), *l3_interfaces.begin(),
false, update_route, vrf_id);
break;
default:
if (nnhs == 1) {
uint32_t route_dst_interface;

if (l3_interfaces.size() == 0) {
// Not yet resolved next-hop, or on-link route, the rule must be installed
// to the switch pointing to controller and then updated after neighbor
// registration.
route_dst_interface = 0;
} else {
// single, resolved nexthop
route_dst_interface = *l3_interfaces.begin(); /* resolved nexthop */
}
rv = add_l3_unicast_route(rtnl_route_get_dst(r), route_dst_interface, false,
update_route, vrf_id);
} else {
// create ecmp group
rv = add_l3_ecmp_route(r, l3_interfaces, update_route);
break;
}

if (rv < 0) {
Expand Down Expand Up @@ -1926,13 +1927,19 @@ int nl_l3::del_l3_unicast_route(rtnl_route *r, bool keep_route) {
int rv = 0;
auto dst = rtnl_route_get_dst(r);

int nnhs = rtnl_route_get_nnexthops(r);
uint16_t vrf_id = rtnl_route_get_table(r);
// Routing table 254 id matches the main routing table on linux.
// Adding a vrf with this id will collide with the main routing
// table, but will enter the wrong info into the OFDPA tables
if (vrf_id == MAIN_ROUTING_TABLE)
vrf_id = 0;

if (nnhs == 0) {
LOG(WARNING) << __FUNCTION__ << ": no neighbours of route " << r;
return -ENOTSUP;
}

if (rtnl_route_get_priority(r) > 0 &&
rtnl_route_get_protocol(r) != RTPROT_KERNEL) {
nl_route_query rq;
Expand Down Expand Up @@ -2017,7 +2024,7 @@ int nl_l3::del_l3_unicast_route(rtnl_route *r, bool keep_route) {
return rv;
}

if (neighs.size() > 1) {
if (nnhs > 1) {
// get all l3 interfaces
std::set<uint32_t> l3_interfaces; // all create l3 interface ids
for (auto n : neighs) {
Expand Down
Loading