From 448139e704cced85b242990fcec161721dec5c1a Mon Sep 17 00:00:00 2001 From: Anuradha Karuppiah Date: Thu, 6 Feb 2020 09:30:51 -0800 Subject: [PATCH] pimd: stop overloading SRC_IGMP upstream for vxlan local membership A local membership is created on the vxlan termination device ipmr-lo. This is done to - 1. Pull multicast vxlan tunnel traffic to the VTEP for termination by triggering JoinDesired on the BUM multicast group. 2. Include the OIF in the mroute to signal to the dataplane component that flow needs to be vxlan terminated. Earlier we were overloading the PIM_UPSTREAM_FLAG_MASK_SRC_IGMP for this local membership creation but that is creating confusion both in the state machine and in the show outputs. To avoid that we use the more apparent PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_TERM. With this change - 1. We get LHR functionality for VXLAN_TERM mroutes 2. OIF is populated with PIM_OIF_FLAG_PROTO_PIM only Signed-off-by: Anuradha Karuppiah --- pimd/pim_cmd.c | 2 +- pimd/pim_ifchannel.c | 12 ++++++++---- pimd/pim_ifchannel.h | 2 +- pimd/pim_mroute.c | 2 +- pimd/pim_upstream.c | 4 ++-- pimd/pim_upstream.h | 1 + pimd/pim_vxlan.c | 2 +- pimd/pim_zebra.c | 6 ++++-- 8 files changed, 19 insertions(+), 12 deletions(-) diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index 1fa674a6f7..295b5e379d 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -166,7 +166,7 @@ static void pim_if_membership_refresh(struct interface *ifp) sg.src = src->source_addr; sg.grp = grp->group_addr; pim_ifchannel_local_membership_add(ifp, - &sg); + &sg, false /*is_vxlan*/); } } /* scan group sources */ diff --git a/pimd/pim_ifchannel.c b/pimd/pim_ifchannel.c index 22d6e6298e..2ea1f4e9a4 100644 --- a/pimd/pim_ifchannel.c +++ b/pimd/pim_ifchannel.c @@ -854,8 +854,9 @@ void pim_ifchannel_join_add(struct interface *ifp, struct in_addr neigh_addr, /* * If we are going to be a LHR, we need to note it */ - if (ch->upstream->parent && (ch->upstream->parent->flags - & PIM_UPSTREAM_FLAG_MASK_SRC_IGMP) + if (ch->upstream->parent && + (PIM_UPSTREAM_FLAG_TEST_CAN_BE_LHR( + ch->upstream->parent->flags)) && !(ch->upstream->flags & PIM_UPSTREAM_FLAG_MASK_SRC_LHR)) { pim_upstream_ref(ch->upstream, @@ -1042,11 +1043,12 @@ void pim_ifchannel_prune(struct interface *ifp, struct in_addr upstream, } int pim_ifchannel_local_membership_add(struct interface *ifp, - struct prefix_sg *sg) + struct prefix_sg *sg, bool is_vxlan) { struct pim_ifchannel *ch, *starch; struct pim_interface *pim_ifp; struct pim_instance *pim; + int up_flags; /* PIM enabled on interface? */ pim_ifp = ifp->info; @@ -1080,7 +1082,9 @@ int pim_ifchannel_local_membership_add(struct interface *ifp, } } - ch = pim_ifchannel_add(ifp, sg, 0, PIM_UPSTREAM_FLAG_MASK_SRC_IGMP); + up_flags = is_vxlan ? PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_TERM : + PIM_UPSTREAM_FLAG_MASK_SRC_IGMP; + ch = pim_ifchannel_add(ifp, sg, 0, up_flags); ifmembership_set(ch, PIM_IFMEMBERSHIP_INCLUDE); diff --git a/pimd/pim_ifchannel.h b/pimd/pim_ifchannel.h index b36c3236b0..3d5cbd8ecf 100644 --- a/pimd/pim_ifchannel.h +++ b/pimd/pim_ifchannel.h @@ -130,7 +130,7 @@ void pim_ifchannel_prune(struct interface *ifp, struct in_addr upstream, struct prefix_sg *sg, uint8_t source_flags, uint16_t holdtime); int pim_ifchannel_local_membership_add(struct interface *ifp, - struct prefix_sg *sg); + struct prefix_sg *sg, bool is_vxlan); void pim_ifchannel_local_membership_del(struct interface *ifp, struct prefix_sg *sg); diff --git a/pimd/pim_mroute.c b/pimd/pim_mroute.c index 3459abbc19..4afd05ab76 100644 --- a/pimd/pim_mroute.c +++ b/pimd/pim_mroute.c @@ -262,7 +262,7 @@ static int pim_mroute_msg_wholepkt(int fd, struct interface *ifp, up = pim_upstream_find(pim_ifp->pim, &star); - if (up && PIM_UPSTREAM_FLAG_TEST_SRC_IGMP(up->flags)) { + if (up && PIM_UPSTREAM_FLAG_TEST_CAN_BE_LHR(up->flags)) { up = pim_upstream_add(pim_ifp->pim, &sg, ifp, PIM_UPSTREAM_FLAG_MASK_SRC_LHR, __PRETTY_FUNCTION__, NULL); diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c index ec1888f1f7..444ab938f2 100644 --- a/pimd/pim_upstream.c +++ b/pimd/pim_upstream.c @@ -2032,7 +2032,7 @@ void pim_upstream_add_lhr_star_pimreg(struct pim_instance *pim) if (up->sg.src.s_addr != INADDR_ANY) continue; - if (!PIM_UPSTREAM_FLAG_TEST_SRC_IGMP(up->flags)) + if (!PIM_UPSTREAM_FLAG_TEST_CAN_BE_LHR(up->flags)) continue; pim_channel_add_oif(up->channel_oil, pim->regiface, @@ -2079,7 +2079,7 @@ void pim_upstream_remove_lhr_star_pimreg(struct pim_instance *pim, if (up->sg.src.s_addr != INADDR_ANY) continue; - if (!PIM_UPSTREAM_FLAG_TEST_SRC_IGMP(up->flags)) + if (!PIM_UPSTREAM_FLAG_TEST_CAN_BE_LHR(up->flags)) continue; if (!nlist) { diff --git a/pimd/pim_upstream.h b/pimd/pim_upstream.h index 0e718a3c31..8d7508287d 100644 --- a/pimd/pim_upstream.h +++ b/pimd/pim_upstream.h @@ -113,6 +113,7 @@ #define PIM_UPSTREAM_FLAG_TEST_MLAG_PEER(flags) ((flags) & PIM_UPSTREAM_FLAG_MASK_MLAG_PEER) #define PIM_UPSTREAM_FLAG_TEST_SRC_NOCACHE(flags) ((flags) &PIM_UPSTREAM_FLAG_MASK_SRC_NOCACHE) #define PIM_UPSTREAM_FLAG_TEST_USE_RPT(flags) ((flags) & PIM_UPSTREAM_FLAG_MASK_USE_RPT) +#define PIM_UPSTREAM_FLAG_TEST_CAN_BE_LHR(flags) ((flags) & (PIM_UPSTREAM_FLAG_MASK_SRC_IGMP | PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_TERM)) #define PIM_UPSTREAM_FLAG_SET_DR_JOIN_DESIRED(flags) ((flags) |= PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED) #define PIM_UPSTREAM_FLAG_SET_DR_JOIN_DESIRED_UPDATED(flags) ((flags) |= PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED) diff --git a/pimd/pim_vxlan.c b/pimd/pim_vxlan.c index 5c085cc416..41a57c267c 100644 --- a/pimd/pim_vxlan.c +++ b/pimd/pim_vxlan.c @@ -531,7 +531,7 @@ static void pim_vxlan_term_mr_oif_add(struct pim_vxlan_sg *vxlan_sg) vxlan_sg->sg_str, vxlan_sg->term_oif->name); if (pim_ifchannel_local_membership_add(vxlan_sg->term_oif, - &vxlan_sg->sg)) { + &vxlan_sg->sg, true /*is_vxlan */)) { vxlan_sg->flags |= PIM_VXLAN_SGF_OIF_INSTALLED; /* update the inherited OIL */ /* XXX - I don't see the inherited OIL updated when a local diff --git a/pimd/pim_zebra.c b/pimd/pim_zebra.c index 7eb648ab86..baa6216df2 100644 --- a/pimd/pim_zebra.c +++ b/pimd/pim_zebra.c @@ -547,7 +547,8 @@ static void igmp_source_forward_reevaluate_one(struct pim_instance *pim, "local membership add for %s as G is now ASM", pim_str_sg_dump(&sg)); pim_ifchannel_local_membership_add( - group->group_igmp_sock->interface, &sg); + group->group_igmp_sock->interface, &sg, + false /*is_vxlan*/); } } } @@ -765,7 +766,8 @@ void igmp_source_forward_start(struct pim_instance *pim, per-interface (S,G) state. */ if (!pim_ifchannel_local_membership_add( - group->group_igmp_sock->interface, &sg)) { + group->group_igmp_sock->interface, &sg, + false /*is_vxlan*/)) { if (PIM_DEBUG_MROUTE) zlog_warn("%s: Failure to add local membership for %s", __PRETTY_FUNCTION__, pim_str_sg_dump(&sg)); -- 2.39.5