summaryrefslogtreecommitdiffstats
path: root/pimd/pim_vxlan.c
diff options
context:
space:
mode:
authorAnuradha Karuppiah <anuradhak@cumulusnetworks.com>2019-03-24 16:50:50 +0100
committerAnuradha Karuppiah <anuradhak@cumulusnetworks.com>2019-04-20 17:33:23 +0200
commit0a2dcc1c41093600b2cccbaca916fa6c71316ce8 (patch)
tree14d3d4d3816fb378e3b204274ae6308148150b00 /pimd/pim_vxlan.c
parentpimd: update vxlan mroute entries when the lo or peerlink vif is updated (diff)
downloadfrr-0a2dcc1c41093600b2cccbaca916fa6c71316ce8.tar.xz
frr-0a2dcc1c41093600b2cccbaca916fa6c71316ce8.zip
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: <BROADCAST,NOARP,UP,LOWER_UP> 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 <anuradhak@cumulusnetworks.com>
Diffstat (limited to 'pimd/pim_vxlan.c')
-rw-r--r--pimd/pim_vxlan.c70
1 files changed, 69 insertions, 1 deletions
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];