summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoranlan_cs <vic.lan@pica8.com>2023-05-30 16:45:45 +0800
committeranlan_cs <vic.lan@pica8.com>2023-05-30 17:29:38 +0800
commitb016b552a6169e0e2f6c3a8d10429f9fe63b4add (patch)
treeeffa29f553a6fdf59a391b1dea68c47672424b02
parent2fccc9fa10d94a1f8b434e1dec06bee3ac352245 (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>
-rw-r--r--pimd/pim_iface.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/pimd/pim_iface.c b/pimd/pim_iface.c
index b1beb45630..660acbe5e6 100644
--- a/pimd/pim_iface.c
+++ b/pimd/pim_iface.c
@@ -1495,9 +1495,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