]> git.puffer.fish Git - mirror/frr.git/commitdiff
pimd: Fix missing pimreg interface 14558/head
authoranlan_cs <vic.lan@pica8.com>
Tue, 30 May 2023 08:45:45 +0000 (16:45 +0800)
committerMergify <37929162+mergify[bot]@users.noreply.github.com>
Tue, 10 Oct 2023 16:52:23 +0000 (16:52 +0000)
`pimregX` of specific vrf can be deleted from kernel after this vrf
is deleted.  However, then `pimdregX` will never come back to
kernel after adding it ( the same vrf ) back.  That is to say, it exists
only in daemon, but not in kernel.

The root cause is this `pimregX` is not really deleted for its special
usage, and `pim_if_create_pimreg()` wants reusing it.

I have tried 4 solutions:
1. Remove the `configured` flag of `pimregX`, allow its deletion.
A few timers still use `pimregX` after its deletion.  So, not adopted.
2. Remove `pimregX` by vrf hook in `pim_instance_terminate()`.
It has no vrf id there.  So, not adopted.
3. Reuse `pimregX` in `pim_if_create_pimreg()`.
If `pim->regiface->info` is true, then reuse old `pimregX` and only call
`pim_if_add_vif()` to install it into kernel.  But at that time, it maybe
is in default VRF.  The `pim_zebra_interface_set_master()` doesn't work
at that time because it shouldn't wait there for its changing into
correct VRF.  So, not adopted.
4. Not reuse it.
If `pim->regiface->info` is true, there must have been pim instance with
VRF deleted and created before.  Actually delele old one in
`pim_if_create_pimreg()`, then recreate new one.

Finally, this PR adopted the fourth solution.

Fixes #13454

Signed-off-by: anlan_cs <vic.lan@pica8.com>
(cherry picked from commit b016b552a6169e0e2f6c3a8d10429f9fe63b4add)

pimd/pim_iface.c

index cc1ca77d65d6044a274bf035c7b27a94e2566d54..dcb3afd3d832cb4ed77a6921df63b1d0893dc87c 100644 (file)
@@ -1490,9 +1490,16 @@ void pim_if_create_pimreg(struct pim_instance *pim)
                                               pim->vrf->name);
                pim->regiface->ifindex = PIM_OIF_PIM_REGISTER_VIF;
 
-               if (!pim->regiface->info)
-                       pim_if_new(pim->regiface, false, false, true,
-                                  false /*vxlan_term*/);
+               /*
+                * The pimreg interface might has been removed from
+                * kerenl with the VRF's deletion.  It must be
+                * recreated, so delete the old one first.
+                */
+               if (pim->regiface->info)
+                       pim_if_delete(pim->regiface);
+
+               pim_if_new(pim->regiface, false, false, true,
+                          false /*vxlan_term*/);
 
                /*
                 * On vrf moves we delete the interface if there