diff options
author | Anuradha Karuppiah <anuradhak@cumulusnetworks.com> | 2019-03-24 16:50:50 +0100 |
---|---|---|
committer | Anuradha Karuppiah <anuradhak@cumulusnetworks.com> | 2019-04-20 17:33:23 +0200 |
commit | 0a2dcc1c41093600b2cccbaca916fa6c71316ce8 (patch) | |
tree | 14d3d4d3816fb378e3b204274ae6308148150b00 /pimd/pim_vxlan.c | |
parent | pimd: update vxlan mroute entries when the lo or peerlink vif is updated (diff) | |
download | frr-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.c | 70 |
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]; |