diff options
| author | anlan_cs <vic.lan@pica8.com> | 2023-05-30 16:45:45 +0800 |
|---|---|---|
| committer | Mergify <37929162+mergify[bot]@users.noreply.github.com> | 2023-10-10 16:52:23 +0000 |
| commit | 8593ef268cd90b1feec8cfcc6fa923f1fac4b8e3 (patch) | |
| tree | 288f1b8e3db9ead41ddcf1e5d7bbacd754b2a8fe | |
| parent | 1c508bba8b78f6e512faaa2896e9074ecfd6a4d8 (diff) | |
pimd: Fix missing pimreg interface
`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)
| -rw-r--r-- | pimd/pim_iface.c | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/pimd/pim_iface.c b/pimd/pim_iface.c index cc1ca77d65..dcb3afd3d8 100644 --- a/pimd/pim_iface.c +++ b/pimd/pim_iface.c @@ -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 |
