zebra: tear down old L3VNI before adding new one on VNI value change - #21757
Conversation
aee45d9 to
110a937
Compare
Greptile SummaryThis PR fixes an orphaned L3VNI bug triggered when a VRF's L3VNI is changed in-place via a northbound Confidence Score: 5/5Safe to merge β the fix correctly tears down the old L3VNI before adding the new one, matching the same pattern used by the destroy handler. The change is minimal and targeted. Logic is sound: guard condition avoids spurious teardown when VNI hasn't changed, old VNI is removed from the global hash and bgpd is notified before the new one is added, and zvrf->l3vni is zeroed by the delete path before the add sets it to the new value. The only remaining note (assert reachability) is a pre-existing issue in the called function, not introduced by this PR. No files require special attention; the assert(zl3vni) concern in zebra_vxlan.c is pre-existing. Important Files Changed
Sequence DiagramsequenceDiagram
participant NB as Northbound NB_CB_MODIFY
participant MH as lib_vrf_zebra_l3vni_id_modify
participant VX as zebra_vxlan_process_vrf_vni_cmd
participant BG as bgpd
NB->>MH: NB_EV_APPLY new_vni
alt zvrf->l3vni set AND differs from new_vni
MH->>VX: old_vni add=0
VX->>VX: oper_down + delete rmacs/nexthops
VX->>VX: zvrf->l3vni=0 zl3vni_del
VX-->>BG: ZEBRA_L3VNI_DEL old_vni
end
MH->>VX: new_vni add=1
VX->>VX: zl3vni_add + map interfaces
VX->>VX: zvrf->l3vni=new_vni
VX-->>BG: ZEBRA_L3VNI_ADD new_vni
Prompt To Fix All With AIThis is a comment left during a code review.
Path: zebra/zebra_nb_config.c
Line: 3969
Comment:
**Defensive guard before assert(zl3vni) in delete path**
`zebra_vxlan_process_vrf_vni_cmd` with `add=0` calls `assert(zl3vni)` immediately after `zl3vni_lookup(vni)`. If state is ever inconsistent β `zvrf->l3vni` is non-zero but the corresponding entry was never inserted into the global hash (e.g., a previous partial add), this assert will crash zebra. The existing destroy handler is exposed to the same risk, but this new call site makes the path more reachable. A NULL-check + `zlog_warn` before the teardown call would be more resilient than a hard assert in a modify path.
How can I resolve this? If you propose a fix, please make it concise.Reviews (1): Last reviewed commit: "zebra: tear down old L3VNI before adding..." | Re-trigger Greptile |
110a937 to
9ffbf54
Compare
9ffbf54 to
6607883
Compare
6607883 to
66df6ca
Compare
|
ci:rerun |
When a VRF's L3VNI value is changed via a single "vni <new>" command
(without first issuing "no vni <old>"), the northbound system generates
a single NB_CB_MODIFY callback for the l3vni-id leaf. The modify handler
lib_vrf_zebra_l3vni_id_modify() calls zebra_vxlan_process_vrf_vni_cmd()
with add=1 for the new VNI, but never tears down the old one.
This leaves the old L3VNI entry orphaned in zrouter.l3vni_table. No
ZEBRA_L3VNI_DEL is sent to bgpd, so bgpd retains stale EVPN state for
the old VNI. The VRF appears to have the correct VNI in running config,
but the control plane is broken until FRR is fully restarted.
This path is triggered when config management systems (e.g. NVUE) apply
the full frr.conf to a running daemon, causing the NB diff to see a leaf
value replace ('r') rather than the explicit destroy+create that
frr-reload.py would generate.
Fix by checking zvrf->l3vni before the add. If the VRF already has a
different L3VNI, call zebra_vxlan_process_vrf_vni_cmd() with add=0 for
the old VNI first, which removes it from the global hash table and
notifies bgpd via ZEBRA_L3VNI_DEL.
Signed-off-by: Eyal Nissim <enissim@nvidia.com>
66df6ca to
c09a1f9
Compare
|
@Mergifyio backport stable/10.6 stable/10.5 stable/10.4 |
β Backports have been createdDetails
|
|
Hi everyone, Could you please take a look at my GitHub PR when you have a moment and share your review/comments? Iβd really appreciate your feedback. Thanks! |
|
Hi, |
zebra: tear down old L3VNI before adding new one on VNI value change (backport #21757)
zebra: tear down old L3VNI before adding new one on VNI value change (backport #21757)
zebra: tear down old L3VNI before adding new one on VNI value change (backport #21757)
When a VRF's L3VNI value is changed via a single "vni " command (without first issuing "no vni "), the northbound system generates a single NB_CB_MODIFY callback for the l3vni-id leaf. The modify handler lib_vrf_zebra_l3vni_id_modify() calls zebra_vxlan_process_vrf_vni_cmd() with add=1 for the new VNI, but never tears down the old one.
This leaves the old L3VNI entry orphaned in zrouter.l3vni_table. No ZEBRA_L3VNI_DEL is sent to bgpd, so bgpd retains stale EVPN state for the old VNI. The VRF appears to have the correct VNI in running config, but the control plane is broken until FRR is fully restarted.
This path is triggered when config management systems (e.g. NVUE) apply the full frr.conf to a running daemon, causing the NB diff to see a leaf value replace ('r') rather than the explicit destroy+create that frr-reload.py would generate.
Fix by checking zvrf->l3vni before the add. If the VRF already has a different L3VNI, call zebra_vxlan_process_vrf_vni_cmd() with add=0 for the old VNI first, which removes it from the global hash table and notifies bgpd via ZEBRA_L3VNI_DEL.