diff options
| -rw-r--r-- | pimd/pim_iface.c | 8 | ||||
| -rw-r--r-- | pimd/pim_vxlan.c | 105 | ||||
| -rw-r--r-- | pimd/pim_vxlan.h | 6 | ||||
| -rw-r--r-- | pimd/pim_vxlan_instance.h | 1 |
4 files changed, 76 insertions, 44 deletions
diff --git a/pimd/pim_iface.c b/pimd/pim_iface.c index c615540149..8cc720c535 100644 --- a/pimd/pim_iface.c +++ b/pimd/pim_iface.c @@ -498,6 +498,7 @@ void pim_if_addr_add(struct connected *ifc) struct pim_interface *pim_ifp; struct interface *ifp; struct in_addr ifaddr; + bool vxlan_term; zassert(ifc); @@ -635,7 +636,8 @@ void pim_if_addr_add(struct connected *ifc) address assigned, then try to create a vif_index. */ if (pim_ifp->mroute_vif_index < 0) { - pim_if_add_vif(ifp, false, false /*vxlan_term*/); + vxlan_term = pim_vxlan_is_term_dev_cfg(pim_ifp->pim, ifp); + pim_if_add_vif(ifp, false, vxlan_term); } pim_ifchannel_scan_forward_start(ifp); } @@ -730,6 +732,7 @@ void pim_if_addr_add_all(struct interface *ifp) int v4_addrs = 0; int v6_addrs = 0; struct pim_interface *pim_ifp = ifp->info; + bool vxlan_term; /* PIM/IGMP enabled ? */ @@ -768,7 +771,8 @@ void pim_if_addr_add_all(struct interface *ifp) * address assigned, then try to create a vif_index. */ if (pim_ifp->mroute_vif_index < 0) { - pim_if_add_vif(ifp, false, false /*vxlan_term*/); + vxlan_term = pim_vxlan_is_term_dev_cfg(pim_ifp->pim, ifp); + pim_if_add_vif(ifp, false, vxlan_term); } pim_ifchannel_scan_forward_start(ifp); diff --git a/pimd/pim_vxlan.c b/pimd/pim_vxlan.c index bd6998c4b8..1de0dda9da 100644 --- a/pimd/pim_vxlan.c +++ b/pimd/pim_vxlan.c @@ -1012,6 +1012,45 @@ static void pim_vxlan_set_peerlink_rif(struct pim_instance *pim, } } +static void pim_vxlan_term_mr_oif_update(struct hash_backet *backet, void *arg) +{ + struct interface *ifp = (struct interface *)arg; + struct pim_vxlan_sg *vxlan_sg = (struct pim_vxlan_sg *)backet->data; + + if (pim_vxlan_is_orig_mroute(vxlan_sg)) + return; + + if (vxlan_sg->term_oif == ifp) + return; + + if (PIM_DEBUG_VXLAN) + zlog_debug("vxlan SG %s term oif changed from %s to %s", + vxlan_sg->sg_str, + vxlan_sg->term_oif ? vxlan_sg->term_oif->name : "-", + ifp ? ifp->name : "-"); + + pim_vxlan_term_mr_del(vxlan_sg); + vxlan_sg->term_oif = ifp; + pim_vxlan_term_mr_add(vxlan_sg); +} + +static void pim_vxlan_term_oif_update(struct pim_instance *pim, + struct interface *ifp) +{ + if (pim->vxlan.term_if == ifp) + return; + + if (PIM_DEBUG_VXLAN) + zlog_debug("vxlan term oif changed from %s to %s", + pim->vxlan.term_if ? pim->vxlan.term_if->name : "-", + ifp ? ifp->name : "-"); + + pim->vxlan.term_if = ifp; + if (pim->vxlan.sg_hash) + hash_iterate(pim->vxlan.sg_hash, + pim_vxlan_term_mr_oif_update, ifp); +} + void pim_vxlan_add_vif(struct interface *ifp) { struct pim_interface *pim_ifp = ifp->info; @@ -1026,6 +1065,9 @@ void pim_vxlan_add_vif(struct interface *ifp) if (vxlan_mlag.flags & PIM_VXLAN_MLAGF_ENABLED && (ifp == vxlan_mlag.peerlink_rif)) pim_vxlan_set_peerlink_rif(pim, ifp); + + if (pim->vxlan.term_if_cfg == ifp) + pim_vxlan_term_oif_update(pim, ifp); } void pim_vxlan_del_vif(struct interface *ifp) @@ -1041,76 +1083,56 @@ void pim_vxlan_del_vif(struct interface *ifp) if (pim->vxlan.peerlink_rif == ifp) pim_vxlan_set_peerlink_rif(pim, NULL); -} - -static void pim_vxlan_term_mr_oif_update(struct hash_backet *backet, void *arg) -{ - struct interface *ifp = (struct interface *)arg; - struct pim_vxlan_sg *vxlan_sg = (struct pim_vxlan_sg *)backet->data; - - if (pim_vxlan_is_orig_mroute(vxlan_sg)) - return; - - if (vxlan_sg->term_oif == ifp) - return; - - if (PIM_DEBUG_VXLAN) - zlog_debug("vxlan SG %s term oif changed from %s to %s", - vxlan_sg->sg_str, - vxlan_sg->term_oif ? vxlan_sg->term_oif->name : "-", - ifp ? ifp->name : "-"); - pim_vxlan_term_mr_del(vxlan_sg); - vxlan_sg->term_oif = ifp; - pim_vxlan_term_mr_add(vxlan_sg); + if (pim->vxlan.term_if == ifp) + pim_vxlan_term_oif_update(pim, NULL); } +/* enable pim implicitly on the termination device add */ void pim_vxlan_add_term_dev(struct pim_instance *pim, struct interface *ifp) { struct pim_interface *pim_ifp; - if (pim->vxlan.term_if == ifp) + if (pim->vxlan.term_if_cfg == ifp) return; if (PIM_DEBUG_VXLAN) - zlog_debug("vxlan term oif changed from %s to %s", - pim->vxlan.term_if ? pim->vxlan.term_if->name : "-", - ifp->name); + zlog_debug("vxlan term oif cfg changed from %s to %s", + pim->vxlan.term_if_cfg ? + pim->vxlan.term_if_cfg->name : "-", + ifp->name); + + pim->vxlan.term_if_cfg = ifp; /* enable pim on the term ifp */ pim_ifp = (struct pim_interface *)ifp->info; if (pim_ifp) { PIM_IF_DO_PIM(pim_ifp->options); + /* ifp is already oper up; activate it as a term dev */ + if (pim_ifp->mroute_vif_index >= 0) + pim_vxlan_term_oif_update(pim, ifp); } else { - pim_ifp = pim_if_new(ifp, false /*igmp*/, true /*pim*/, - false /*pimreg*/, true /*vxlan_term*/); - /* ensure that pimreg existss before using the newly created + /* ensure that pimreg exists before using the newly created * vxlan termination device */ pim_if_create_pimreg(pim); + pim_ifp = pim_if_new(ifp, false /*igmp*/, true /*pim*/, + false /*pimreg*/, true /*vxlan_term*/); } - - pim->vxlan.term_if = ifp; - - if (pim->vxlan.sg_hash) - hash_iterate(pim_ifp->pim->vxlan.sg_hash, - pim_vxlan_term_mr_oif_update, ifp); } +/* disable pim implicitly, if needed, on the termination device deletion */ void pim_vxlan_del_term_dev(struct pim_instance *pim) { - struct interface *ifp = pim->vxlan.term_if; + struct interface *ifp = pim->vxlan.term_if_cfg; struct pim_interface *pim_ifp; if (PIM_DEBUG_VXLAN) - zlog_debug("vxlan term oif changed from %s to -", ifp->name); + zlog_debug("vxlan term oif cfg changed from %s to -", + ifp->name); - pim->vxlan.term_if = NULL; - - if (pim->vxlan.sg_hash) - hash_iterate(pim->vxlan.sg_hash, - pim_vxlan_term_mr_oif_update, NULL); + pim->vxlan.term_if_cfg = NULL; pim_ifp = (struct pim_interface *)ifp->info; if (pim_ifp) { @@ -1118,7 +1140,6 @@ void pim_vxlan_del_term_dev(struct pim_instance *pim) if (!PIM_IF_TEST_IGMP(pim_ifp->options)) pim_if_delete(ifp); } - } void pim_vxlan_init(struct pim_instance *pim) diff --git a/pimd/pim_vxlan.h b/pimd/pim_vxlan.h index 7adba2eee2..198d1c3281 100644 --- a/pimd/pim_vxlan.h +++ b/pimd/pim_vxlan.h @@ -119,6 +119,12 @@ static inline bool pim_vxlan_is_local_sip(struct pim_upstream *up) if_is_loopback_or_vrf(up->rpf.source_nexthop.interface); } +static inline bool pim_vxlan_is_term_dev_cfg(struct pim_instance *pim, + struct interface *ifp) +{ + return pim->vxlan.term_if_cfg == ifp; +} + extern struct pim_vxlan *pim_vxlan_p; extern struct pim_vxlan_sg *pim_vxlan_sg_find(struct pim_instance *pim, struct prefix_sg *sg); diff --git a/pimd/pim_vxlan_instance.h b/pimd/pim_vxlan_instance.h index 3f99483fbe..5b35bcbeaa 100644 --- a/pimd/pim_vxlan_instance.h +++ b/pimd/pim_vxlan_instance.h @@ -36,6 +36,7 @@ struct pim_vxlan_instance { /* device used by the dataplane to terminate multicast encapsulated * vxlan traffic */ + struct interface *term_if_cfg; struct interface *term_if; }; |
