diff options
| author | Rajasekar Raja <rajasekarr@nvidia.com> | 2024-07-05 16:02:12 -0700 |
|---|---|---|
| committer | Rajasekar Raja <rajasekarr@nvidia.com> | 2024-07-12 14:25:33 -0700 |
| commit | c77e15710d6a3a9be71f41a9ce608f06b2795dfb (patch) | |
| tree | 66bcb7df141faa7741107788563b30d33eced65b /zebra/interface.c | |
| parent | d7d491537a936333830c7c2fa3cb52df7e5476a9 (diff) | |
zebra: Fix to avoid two Vrfs with same table ids
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 <sharpd@nvidia.com>
Signed-off-by: Rajasekar Raja <rajasekarr@nvidia.com>
Diffstat (limited to 'zebra/interface.c')
| -rw-r--r-- | zebra/interface.c | 36 |
1 files changed, 20 insertions, 16 deletions
diff --git a/zebra/interface.c b/zebra/interface.c index f1f24cc29f..b3adc4483e 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -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); } } |
