From 0a2dcc1c41093600b2cccbaca916fa6c71316ce8 Mon Sep 17 00:00:00 2001 From: Anuradha Karuppiah Date: Sun, 24 Mar 2019 08:50:50 -0700 Subject: pimd: setup multicast vxlan tunnel termination device An interface needs to be designated as "termination device" and added to the termination mroute's OIL. This is used by kernel and ASIC backends to vxlan-decaps matching flows. The default termination device is expected to have the prefix (start sub-string) "ipmr-lo". This can be made configurable if needed - root@TORS1:~# ip -d link show ipmr-lo 28: ipmr-lo: mtu 1500 qdisc noqueue state UNKNOWN mode DEFAULT group default link/ether 12:5a:ae:74:51:a2 brd ff:ff:ff:ff:ff:ff promiscuity 0 dummy addrgenmode eui64 root@TORS1:~# ip mr This commit includes the changes to enable pim implicitly on the device and set it up as the vxlan-term device per-pim-instance. Signed-off-by: Anuradha Karuppiah --- pimd/pim_vxlan.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 69 insertions(+), 1 deletion(-) (limited to 'pimd/pim_vxlan.c') diff --git a/pimd/pim_vxlan.c b/pimd/pim_vxlan.c index 02878b505..e3cd0b915 100644 --- a/pimd/pim_vxlan.c +++ b/pimd/pim_vxlan.c @@ -779,7 +779,6 @@ void pim_vxlan_add_vif(struct interface *ifp) struct pim_interface *pim_ifp = ifp->info; struct pim_instance *pim = pim_ifp->pim; - pim = ((struct pim_interface *)ifp->info)->pim; if (pim->vrf_id != VRF_DEFAULT) return; @@ -806,6 +805,75 @@ void pim_vxlan_del_vif(struct interface *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); +} + +void pim_vxlan_add_term_dev(struct pim_instance *pim, + struct interface *ifp) +{ + struct pim_interface *pim_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 : "-"); + + /* enable pim on the term ifp */ + pim_ifp = (struct pim_interface *)ifp->info; + if (pim_ifp) + PIM_IF_DO_PIM(pim_ifp->options); + else + pim_ifp = pim_if_new(ifp, false /*igmp*/, true /*pim*/, + false /*pimreg*/, true /*vxlan_term*/); + + pim->vxlan.term_if = ifp; + hash_iterate(pim_ifp->pim->vxlan.sg_hash, + pim_vxlan_term_mr_oif_update, ifp); +} + +void pim_vxlan_del_term_dev(struct pim_instance *pim) +{ + struct interface *ifp = pim->vxlan.term_if; + struct pim_interface *pim_ifp; + + if (PIM_DEBUG_VXLAN) + zlog_debug("vxlan term oif changed from %s to -", ifp->name); + + pim->vxlan.term_if = NULL; + hash_iterate(pim->vxlan.sg_hash, + pim_vxlan_term_mr_oif_update, NULL); + + pim_ifp = (struct pim_interface *)ifp->info; + if (pim_ifp) { + PIM_IF_DONT_PIM(pim_ifp->options); + if (!PIM_IF_TEST_IGMP(pim_ifp->options)) + pim_if_delete(ifp); + } + +} + void pim_vxlan_init(struct pim_instance *pim) { char hash_name[64]; -- cgit v1.2.3