Skip to content

Commit

Permalink
zebra: Fix to avoid two Vrfs with same table ids
Browse files Browse the repository at this point in the history
During internal testing, when the following sequence is followed, two
non default vrfs end up pointing to the same table-id

 - Initially vrf201 has table id 1002
 - ip link add dev vrf202 type vrf table 1002
 - ip link set dev vrf202 up
 - ip link set dev <intrerface> master vrf202

This will ideally lead to zebra exit since this is a misconfiguration as
expected.

However if we perform a restart frr.service at this point, we end up
having two vrfs pointing to same table-id and bad things can happen.
This is because in the interface_vrf_change, we incorrectly check for
vrf_lookup_by_id() to evaluate if there is a misconfig. This works well
for a non restart case but not for the startup case.

root@mlx-3700-20:mgmt:/var/log/frr# sudo vtysh -c "sh vrf"
vrf mgmt id 37 table 1001
vrf vrf201 id 46 table 1002
vrf vrf202 id 59 table 1002 >>>>

Fix: in all cases of misconfiguration, exit zebra as expected.

Ticket :#3970414

Signed-off-by: Donald Sharp <[email protected]>

Signed-off-by: Rajasekar Raja <[email protected]>
  • Loading branch information
raja-rajasekar committed Jul 12, 2024
1 parent d7d4915 commit c77e157
Showing 1 changed file with 20 additions and 16 deletions.
36 changes: 20 additions & 16 deletions zebra/interface.c
Original file line number Diff line number Diff line change
Expand Up @@ -1483,23 +1483,27 @@ static void interface_vrf_change(enum dplane_op_e op, ifindex_t ifindex,
"DPLANE_OP_INTF_UPDATE for VRF %s(%u) table %u",
name, ifindex, tableid);

if (!vrf_lookup_by_id((vrf_id_t)ifindex)) {
vrf_id_t exist_id;

exist_id = zebra_vrf_lookup_by_table(tableid, ns_id);
if (exist_id != VRF_DEFAULT) {
vrf = vrf_lookup_by_id(exist_id);

if (vrf)
flog_err(EC_ZEBRA_VRF_MISCONFIGURED,
"VRF %s id %u table id overlaps existing vrf %s(%d), misconfiguration exiting",
name, ifindex, vrf->name,
vrf->vrf_id);
else
flog_err(EC_ZEBRA_VRF_NOT_FOUND,
"VRF %s id %u does not exist",
name, ifindex);
/*
* For a given tableid, if there already exists a vrf and it
* is different from the current vrf to be operated, then there
* is a misconfiguration and zebra will exit.
*/
vrf_id_t exist_id = zebra_vrf_lookup_by_table(tableid, ns_id);

if (exist_id != VRF_DEFAULT) {
vrf = vrf_lookup_by_id(exist_id);

if (!vrf_lookup_by_id((vrf_id_t)ifindex) && !vrf) {
flog_err(EC_ZEBRA_VRF_NOT_FOUND,
"VRF %s id %u does not exist", name,
ifindex);
exit(-1);
}

if (vrf && strcmp(name, vrf->name)) {
flog_err(EC_ZEBRA_VRF_MISCONFIGURED,
"VRF %s id %u table id overlaps existing vrf %s(%d), misconfiguration exiting",
name, ifindex, vrf->name, vrf->vrf_id);
exit(-1);
}
}
Expand Down

0 comments on commit c77e157

Please sign in to comment.