mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-02 16:57:58 +00:00
pimd: add termination mroutes for each vxlan multicast tunnels
To terminate a multicast VxLAN tunnel entry we setup a mroute with ipmr-lo in the OIL - (0.0.0.0, 239.1.1.100) Iif: uplink-1 Oifs: uplink-1 ipmr-lo This is done by the vxlan component that add ipmr-lo as a local member to termination SG entries. In addition termination entries are also subject to MLAG DF election on the anycast VxLAN-AA setup. Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
This commit is contained in:
parent
f376b70161
commit
332087df41
128
pimd/pim_vxlan.c
128
pimd/pim_vxlan.c
@ -468,6 +468,130 @@ static void pim_vxlan_orig_mr_del(struct pim_vxlan_sg *vxlan_sg)
|
||||
pim_vxlan_orig_mr_up_del(vxlan_sg);
|
||||
}
|
||||
|
||||
/**************************** vxlan termination mroutes ***********************
|
||||
* For every bum-mcast-grp registered by evpn a *G termination
|
||||
* mroute is setup by pimd. The purpose of this mroute is to pull down vxlan
|
||||
* packets with the bum-mcast-grp dip from the underlay and terminate the
|
||||
* tunnel. This is done by including the vxlan termination device (ipmr-lo) in
|
||||
* its OIL. The vxlan de-capsulated packets are subject to subsequent overlay
|
||||
* bridging.
|
||||
*
|
||||
* Sample mroute:
|
||||
* (0.0.0.0, 239.1.1.100) Iif: uplink-1 Oifs: ipmr-lo, uplink-1
|
||||
*****************************************************************************/
|
||||
struct pim_interface *pim_vxlan_get_term_ifp(struct pim_instance *pim)
|
||||
{
|
||||
return pim->vxlan.term_if ?
|
||||
(struct pim_interface *)pim->vxlan.term_if->info : NULL;
|
||||
}
|
||||
|
||||
static void pim_vxlan_term_mr_oif_add(struct pim_vxlan_sg *vxlan_sg)
|
||||
{
|
||||
if (vxlan_sg->flags & PIM_VXLAN_SGF_OIF_INSTALLED)
|
||||
return;
|
||||
|
||||
if (PIM_DEBUG_VXLAN)
|
||||
zlog_debug("vxlan SG %s term-oif %s add",
|
||||
vxlan_sg->sg_str, vxlan_sg->term_oif->name);
|
||||
|
||||
if (pim_ifchannel_local_membership_add(vxlan_sg->term_oif,
|
||||
&vxlan_sg->sg)) {
|
||||
vxlan_sg->flags |= PIM_VXLAN_SGF_OIF_INSTALLED;
|
||||
} else {
|
||||
zlog_warn("vxlan SG %s term-oif %s add failed",
|
||||
vxlan_sg->sg_str, vxlan_sg->term_oif->name);
|
||||
}
|
||||
}
|
||||
|
||||
static void pim_vxlan_term_mr_oif_del(struct pim_vxlan_sg *vxlan_sg)
|
||||
{
|
||||
if (!(vxlan_sg->flags & PIM_VXLAN_SGF_OIF_INSTALLED))
|
||||
return;
|
||||
|
||||
if (PIM_DEBUG_VXLAN)
|
||||
zlog_debug("vxlan SG %s oif %s del",
|
||||
vxlan_sg->sg_str, vxlan_sg->term_oif->name);
|
||||
|
||||
vxlan_sg->flags &= ~PIM_VXLAN_SGF_OIF_INSTALLED;
|
||||
pim_ifchannel_local_membership_del(vxlan_sg->term_oif, &vxlan_sg->sg);
|
||||
}
|
||||
|
||||
static void pim_vxlan_term_mr_up_add(struct pim_vxlan_sg *vxlan_sg)
|
||||
{
|
||||
struct pim_upstream *up;
|
||||
int flags = 0;
|
||||
|
||||
if (vxlan_sg->up) {
|
||||
/* nothing to do */
|
||||
return;
|
||||
}
|
||||
|
||||
if (PIM_DEBUG_VXLAN)
|
||||
zlog_debug("vxlan SG %s term mroute-up add",
|
||||
vxlan_sg->sg_str);
|
||||
|
||||
PIM_UPSTREAM_FLAG_SET_SRC_VXLAN_TERM(flags);
|
||||
/* enable MLAG designated-forwarder election on termination mroutes */
|
||||
PIM_UPSTREAM_FLAG_SET_MLAG_VXLAN(flags);
|
||||
|
||||
up = pim_upstream_add(vxlan_sg->pim, &vxlan_sg->sg,
|
||||
NULL /* iif */, flags,
|
||||
__PRETTY_FUNCTION__, NULL);
|
||||
vxlan_sg->up = up;
|
||||
|
||||
if (!up) {
|
||||
zlog_warn("vxlan SG %s term mroute-up add failed",
|
||||
vxlan_sg->sg_str);
|
||||
}
|
||||
}
|
||||
|
||||
static void pim_vxlan_term_mr_up_del(struct pim_vxlan_sg *vxlan_sg)
|
||||
{
|
||||
struct pim_upstream *up = vxlan_sg->up;
|
||||
|
||||
if (!up)
|
||||
return;
|
||||
|
||||
if (PIM_DEBUG_VXLAN)
|
||||
zlog_debug("vxlan SG %s term mroute-up del",
|
||||
vxlan_sg->sg_str);
|
||||
vxlan_sg->up = NULL;
|
||||
if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_TERM) {
|
||||
/* clear out all the vxlan related flags */
|
||||
up->flags &= ~(PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_TERM |
|
||||
PIM_UPSTREAM_FLAG_MASK_MLAG_VXLAN);
|
||||
|
||||
pim_upstream_del(vxlan_sg->pim, up,
|
||||
__PRETTY_FUNCTION__);
|
||||
}
|
||||
}
|
||||
|
||||
static void pim_vxlan_term_mr_add(struct pim_vxlan_sg *vxlan_sg)
|
||||
{
|
||||
if (PIM_DEBUG_VXLAN)
|
||||
zlog_debug("vxlan SG %s term mroute add", vxlan_sg->sg_str);
|
||||
|
||||
vxlan_sg->term_oif = vxlan_sg->pim->vxlan.term_if;
|
||||
if (!vxlan_sg->term_oif)
|
||||
/* defer termination mroute till we have a termination device */
|
||||
return;
|
||||
|
||||
pim_vxlan_term_mr_up_add(vxlan_sg);
|
||||
/* set up local membership for the term-oif */
|
||||
pim_vxlan_term_mr_oif_add(vxlan_sg);
|
||||
}
|
||||
|
||||
static void pim_vxlan_term_mr_del(struct pim_vxlan_sg *vxlan_sg)
|
||||
{
|
||||
if (PIM_DEBUG_VXLAN)
|
||||
zlog_debug("vxlan SG %s term mroute del", vxlan_sg->sg_str);
|
||||
|
||||
/* remove local membership associated with the term oif */
|
||||
pim_vxlan_term_mr_oif_del(vxlan_sg);
|
||||
/* remove references to the upstream entry */
|
||||
pim_vxlan_term_mr_up_del(vxlan_sg);
|
||||
}
|
||||
|
||||
/************************** vxlan SG cache management ************************/
|
||||
static unsigned int pim_vxlan_sg_hash_key_make(void *p)
|
||||
{
|
||||
@ -527,6 +651,8 @@ struct pim_vxlan_sg *pim_vxlan_sg_add(struct pim_instance *pim,
|
||||
|
||||
if (pim_vxlan_is_orig_mroute(vxlan_sg))
|
||||
pim_vxlan_orig_mr_add(vxlan_sg);
|
||||
else
|
||||
pim_vxlan_term_mr_add(vxlan_sg);
|
||||
|
||||
return vxlan_sg;
|
||||
}
|
||||
@ -545,6 +671,8 @@ void pim_vxlan_sg_del(struct pim_instance *pim, struct prefix_sg *sg)
|
||||
|
||||
if (pim_vxlan_is_orig_mroute(vxlan_sg))
|
||||
pim_vxlan_orig_mr_del(vxlan_sg);
|
||||
else
|
||||
pim_vxlan_term_mr_del(vxlan_sg);
|
||||
|
||||
hash_release(vxlan_sg->pim->vxlan.sg_hash, vxlan_sg);
|
||||
|
||||
|
@ -122,5 +122,6 @@ extern struct pim_vxlan_sg *pim_vxlan_sg_add(struct pim_instance *pim,
|
||||
extern void pim_vxlan_sg_del(struct pim_instance *pim, struct prefix_sg *sg);
|
||||
extern void pim_vxlan_update_sg_reg_state(struct pim_instance *pim,
|
||||
struct pim_upstream *up, bool reg_join);
|
||||
extern struct pim_interface *pim_vxlan_get_term_ifp(struct pim_instance *pim);
|
||||
|
||||
#endif /* PIM_VXLAN_H */
|
||||
|
Loading…
Reference in New Issue
Block a user