Skip to content

Commit

Permalink
Merge pull request FRRouting#4691 from donaldsharp/pim_upstream_ref
Browse files Browse the repository at this point in the history
Pim upstream ref
  • Loading branch information
Jafaral authored Jul 24, 2019
2 parents 6879c08 + 02434c4 commit e72ce28
Show file tree
Hide file tree
Showing 8 changed files with 103 additions and 102 deletions.
31 changes: 13 additions & 18 deletions pimd/pim_mroute.c
Original file line number Diff line number Diff line change
Expand Up @@ -190,8 +190,6 @@ static int pim_mroute_msg_nocache(int fd, struct interface *ifp,
sg.grp = msg->im_dst;

if (!(PIM_I_am_DR(pim_ifp))) {
struct channel_oil *c_oil;

if (PIM_DEBUG_MROUTE_DETAIL)
zlog_debug("%s: Interface is not the DR blackholing incoming traffic for %s",
__PRETTY_FUNCTION__, pim_str_sg_dump(&sg));
Expand All @@ -206,10 +204,10 @@ static int pim_mroute_msg_nocache(int fd, struct interface *ifp,
* that I see no way to get rid of. Just noting
* this for future reference.
*/
c_oil = pim_channel_oil_add(pim_ifp->pim, &sg,
pim_ifp->mroute_vif_index,
__PRETTY_FUNCTION__);
pim_mroute_add(c_oil, __PRETTY_FUNCTION__);
up = pim_upstream_find_or_add(
&sg, ifp, PIM_UPSTREAM_FLAG_MASK_SRC_NOCACHE,
__PRETTY_FUNCTION__);
pim_mroute_add(up->channel_oil, __PRETTY_FUNCTION__);

return 0;
}
Expand Down Expand Up @@ -238,7 +236,8 @@ static int pim_mroute_msg_nocache(int fd, struct interface *ifp,
vif_index = pim_if_find_vifindex_by_ifindex(
pim_ifp->pim,
up->rpf.source_nexthop.interface->ifindex);
up->channel_oil->oil.mfcc_parent = vif_index;
pim_channel_oil_change_iif(pim_ifp->pim, up->channel_oil,
vif_index, __PRETTY_FUNCTION__);
}
pim_register_join(up);

Expand Down Expand Up @@ -453,7 +452,6 @@ static int pim_mroute_msg_wrvifwhole(int fd, struct interface *ifp,
struct pim_upstream *up;
struct prefix_sg star_g;
struct prefix_sg sg;
struct channel_oil *oil;

pim_ifp = ifp->info;

Expand Down Expand Up @@ -517,11 +515,7 @@ static int pim_mroute_msg_wrvifwhole(int fd, struct interface *ifp,
up->upstream_register);
up->sptbit = PIM_UPSTREAM_SPTBIT_TRUE;
}
if (!up->channel_oil)
up->channel_oil = pim_channel_oil_add(
pim_ifp->pim, &sg,
pim_ifp->mroute_vif_index,
__PRETTY_FUNCTION__);

pim_upstream_inherited_olist(pim_ifp->pim, up);
if (!up->channel_oil->installed)
pim_mroute_add(up->channel_oil,
Expand All @@ -546,10 +540,6 @@ static int pim_mroute_msg_wrvifwhole(int fd, struct interface *ifp,
}

pim_ifp = ifp->info;
oil = pim_channel_oil_add(pim_ifp->pim, &sg, pim_ifp->mroute_vif_index,
__PRETTY_FUNCTION__);
if (!oil->installed)
pim_mroute_add(oil, __PRETTY_FUNCTION__);
if (pim_if_connected_to_source(ifp, sg.src)) {
up = pim_upstream_add(pim_ifp->pim, &sg, ifp,
PIM_UPSTREAM_FLAG_MASK_FHR,
Expand All @@ -564,13 +554,18 @@ static int pim_mroute_msg_wrvifwhole(int fd, struct interface *ifp,
PIM_UPSTREAM_FLAG_SET_SRC_STREAM(up->flags);
pim_upstream_keep_alive_timer_start(
up, pim_ifp->pim->keep_alive_time);
up->channel_oil = oil;
up->channel_oil->cc.pktcnt++;
pim_register_join(up);
pim_upstream_inherited_olist(pim_ifp->pim, up);

// Send the packet to the RP
pim_mroute_msg_wholepkt(fd, ifp, buf);
} else {
up = pim_upstream_add(pim_ifp->pim, &sg, ifp,
PIM_UPSTREAM_FLAG_MASK_SRC_NOCACHE,
__PRETTY_FUNCTION__, NULL);
if (!up->channel_oil->installed)
pim_mroute_add(up->channel_oil, __PRETTY_FUNCTION__);
}

return 0;
Expand Down
40 changes: 39 additions & 1 deletion pimd/pim_oil.c
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,43 @@ struct channel_oil *pim_find_channel_oil(struct pim_instance *pim,
return c_oil;
}

void pim_channel_oil_change_iif(struct pim_instance *pim,
struct channel_oil *c_oil,
int input_vif_index,
const char *name)
{
int old_vif_index = c_oil->oil.mfcc_parent;
struct prefix_sg sg = {.src = c_oil->oil.mfcc_mcastgrp,
.grp = c_oil->oil.mfcc_origin};

if (c_oil->oil.mfcc_parent == input_vif_index) {
if (PIM_DEBUG_MROUTE_DETAIL)
zlog_debug("%s(%s): Existing channel oil %pSG4 already using %d as IIF",
__PRETTY_FUNCTION__, name, &sg,
input_vif_index);

return;
}

if (PIM_DEBUG_MROUTE_DETAIL)
zlog_debug("%s(%s): Changing channel oil %pSG4 IIF from %d to %d installed: %d",
__PRETTY_FUNCTION__, name, &sg,
c_oil->oil.mfcc_parent, input_vif_index,
c_oil->installed);

c_oil->oil.mfcc_parent = input_vif_index;
if (c_oil->installed) {
if (input_vif_index == MAXVIFS)
pim_mroute_del(c_oil, name);
else
pim_mroute_add(c_oil, name);
} else
if (old_vif_index == MAXVIFS)
pim_mroute_add(c_oil, name);

return;
}

struct channel_oil *pim_channel_oil_add(struct pim_instance *pim,
struct prefix_sg *sg,
int input_vif_index, const char *name)
Expand All @@ -164,7 +201,8 @@ struct channel_oil *pim_channel_oil_add(struct pim_instance *pim,
c_oil->oil.mfcc_parent,
input_vif_index);
}
c_oil->oil.mfcc_parent = input_vif_index;
pim_channel_oil_change_iif(pim, c_oil, input_vif_index,
name);
++c_oil->oil_ref_count;
/* channel might be present prior to upstream */
c_oil->up = pim_upstream_find(pim, sg);
Expand Down
3 changes: 3 additions & 0 deletions pimd/pim_oil.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,9 @@ struct channel_oil *pim_find_channel_oil(struct pim_instance *pim,
struct channel_oil *pim_channel_oil_add(struct pim_instance *pim,
struct prefix_sg *sg,
int input_vif_index, const char *name);
void pim_channel_oil_change_iif(struct pim_instance *pim,
struct channel_oil *c_oil, int input_vif_index,
const char *name);
void pim_channel_oil_del(struct channel_oil *c_oil, const char *name);

int pim_channel_add_oif(struct channel_oil *c_oil, struct interface *oif,
Expand Down
8 changes: 4 additions & 4 deletions pimd/pim_rpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -307,11 +307,11 @@ void pim_upstream_rpf_clear(struct pim_instance *pim,
struct pim_upstream *up)
{
if (up->rpf.source_nexthop.interface) {
if (up->channel_oil) {
up->channel_oil->oil.mfcc_parent = MAXVIFS;
pim_mroute_del(up->channel_oil, __PRETTY_FUNCTION__);
if (up->channel_oil)
pim_channel_oil_change_iif(pim, up->channel_oil,
MAXVIFS,
__PRETTY_FUNCTION__);

}
pim_upstream_switch(pim, up, PIM_UPSTREAM_NOTJOINED);
up->rpf.source_nexthop.interface = NULL;
up->rpf.source_nexthop.mrib_nexthop_addr.u.prefix4.s_addr =
Expand Down
4 changes: 3 additions & 1 deletion pimd/pim_static.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,9 @@ int pim_static_add(struct pim_instance *pim, struct interface *iif,
} else {
/* input interface changed */
s_route->iif = iif_index;
s_route->c_oil.oil.mfcc_parent = iif_index;
pim_channel_oil_change_iif(pim, &s_route->c_oil,
iif_index,
__PRETTY_FUNCTION__);

#ifdef PIM_ENFORCE_LOOPFREE_MFC
/* check to make sure the new input was not an
Expand Down
64 changes: 23 additions & 41 deletions pimd/pim_upstream.c
Original file line number Diff line number Diff line change
Expand Up @@ -716,7 +716,8 @@ static struct pim_upstream *pim_upstream_new(struct pim_instance *pim,
up->join_state = PIM_UPSTREAM_NOTJOINED;
up->reg_state = PIM_REG_NOINFO;
up->state_transition = pim_time_monotonic_sec();
up->channel_oil = NULL;
up->channel_oil =
pim_channel_oil_add(pim, &up->sg, MAXVIFS, __PRETTY_FUNCTION__);
up->sptbit = PIM_UPSTREAM_SPTBIT_FALSE;

up->rpf.source_nexthop.interface = NULL;
Expand All @@ -736,52 +737,34 @@ static struct pim_upstream *pim_upstream_new(struct pim_instance *pim,
if (up->sg.src.s_addr != INADDR_ANY)
wheel_add_item(pim->upstream_sg_wheel, up);

if (PIM_UPSTREAM_FLAG_TEST_STATIC_IIF(up->flags)) {
if (PIM_UPSTREAM_FLAG_TEST_STATIC_IIF(up->flags)
|| PIM_UPSTREAM_FLAG_TEST_SRC_NOCACHE(up->flags)) {
pim_upstream_fill_static_iif(up, incoming);
pim_ifp = up->rpf.source_nexthop.interface->info;
assert(pim_ifp);
up->channel_oil = pim_channel_oil_add(pim, &up->sg,
pim_ifp->mroute_vif_index,
__PRETTY_FUNCTION__);
} else if (up->upstream_addr.s_addr == INADDR_ANY) {
/* Create a dummmy channel oil with incoming ineterface MAXVIFS,
* since RP is not configured
*/
up->channel_oil = pim_channel_oil_add(pim, &up->sg, MAXVIFS,
__PRETTY_FUNCTION__);

} else {
pim_channel_oil_change_iif(pim, up->channel_oil,
pim_ifp->mroute_vif_index,
__PRETTY_FUNCTION__);

if (PIM_UPSTREAM_FLAG_TEST_SRC_NOCACHE(up->flags))
pim_upstream_keep_alive_timer_start(
up, pim->keep_alive_time);
} else if (up->upstream_addr.s_addr != INADDR_ANY) {
rpf_result = pim_rpf_update(pim, up, NULL);
if (rpf_result == PIM_RPF_FAILURE) {
if (PIM_DEBUG_TRACE)
zlog_debug(
"%s: Attempting to create upstream(%s), Unable to RPF for source",
__PRETTY_FUNCTION__, up->sg_str);
/* Create a dummmy channel oil with incoming ineterface
* MAXVIFS, since RP is not reachable
*/
up->channel_oil = pim_channel_oil_add(
pim, &up->sg, MAXVIFS, __PRETTY_FUNCTION__);
}

if (up->rpf.source_nexthop.interface) {
pim_ifp = up->rpf.source_nexthop.interface->info;
if (pim_ifp)
up->channel_oil = pim_channel_oil_add(
pim, &up->sg, pim_ifp->mroute_vif_index,
__PRETTY_FUNCTION__);
else {
/*
* Yeah this should not happen
* but let's be sure that we are not
* doing something stupid, all paths
* through upstream creation will
* create a channel oil
*/
up->channel_oil = pim_channel_oil_add(
pim, &up->sg, MAXVIFS,
pim_channel_oil_change_iif(
pim, up->channel_oil,
pim_ifp->mroute_vif_index,
__PRETTY_FUNCTION__);
}
}
}

Expand Down Expand Up @@ -1201,6 +1184,13 @@ struct pim_upstream *pim_upstream_keep_alive_timer_proc(
if (!pim_upstream_del(pim, up, __PRETTY_FUNCTION__))
return NULL;
}
if (PIM_UPSTREAM_FLAG_TEST_SRC_NOCACHE(up->flags)) {
PIM_UPSTREAM_FLAG_UNSET_SRC_NOCACHE(up->flags);

if (!pim_upstream_del(pim, up, __PRETTY_FUNCTION__))
return NULL;
}

/* upstream reference would have been added to track the local
* membership if it is LHR. We have to clear it when KAT expires.
* Otherwise would result in stale entry with uncleared ref count.
Expand Down Expand Up @@ -1526,22 +1516,14 @@ int pim_upstream_inherited_olist_decide(struct pim_instance *pim,
struct pim_upstream *up)
{
struct interface *ifp;
struct pim_interface *pim_ifp = NULL;
struct pim_ifchannel *ch, *starch;
struct pim_upstream *starup = up->parent;
int output_intf = 0;

if (up->rpf.source_nexthop.interface)
pim_ifp = up->rpf.source_nexthop.interface->info;
else {
if (!up->rpf.source_nexthop.interface)
if (PIM_DEBUG_TRACE)
zlog_debug("%s: up %s RPF is not present",
__PRETTY_FUNCTION__, up->sg_str);
}
if (pim_ifp && !up->channel_oil)
up->channel_oil = pim_channel_oil_add(pim, &up->sg,
pim_ifp->mroute_vif_index,
__PRETTY_FUNCTION__);

FOR_ALL_INTERFACES (pim->vrf, ifp) {
if (!ifp->info)
Expand Down
9 changes: 9 additions & 0 deletions pimd/pim_upstream.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,13 @@
* blackholing the traffic pulled down to the LHR.
*/
#define PIM_UPSTREAM_FLAG_MASK_MLAG_NON_DF (1 << 17)
/*
* We are creating a non-joined upstream data structure
* for this S,G as that we want to have a channel oil
* associated with an upstream
*/
#define PIM_UPSTREAM_FLAG_MASK_SRC_NOCACHE (1 << 19)

#define PIM_UPSTREAM_FLAG_ALL 0xFFFFFFFF

#define PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(flags) ((flags) & PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED)
Expand All @@ -95,6 +102,7 @@
#define PIM_UPSTREAM_FLAG_TEST_SRC_VXLAN(flags) ((flags) & (PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_ORIG | PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_TERM))
#define PIM_UPSTREAM_FLAG_TEST_MLAG_VXLAN(flags) ((flags) & PIM_UPSTREAM_FLAG_MASK_MLAG_VXLAN)
#define PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(flags) ((flags) & PIM_UPSTREAM_FLAG_MASK_MLAG_NON_DF)
#define PIM_UPSTREAM_FLAG_TEST_SRC_NOCACHE(flags) ((flags) &PIM_UPSTREAM_FLAG_MASK_SRC_NOCACHE)

#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)
Expand Down Expand Up @@ -133,6 +141,7 @@
#define PIM_UPSTREAM_FLAG_UNSET_SRC_VXLAN_TERM(flags) ((flags) &= ~PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_TERM)
#define PIM_UPSTREAM_FLAG_UNSET_MLAG_VXLAN(flags) ((flags) &= ~PIM_UPSTREAM_FLAG_MASK_MLAG_VXLAN)
#define PIM_UPSTREAM_FLAG_UNSET_MLAG_NON_DF(flags) ((flags) &= ~PIM_UPSTREAM_FLAG_MASK_MLAG_NON_DF)
#define PIM_UPSTREAM_FLAG_UNSET_SRC_NOCACHE(flags) ((flags) &= ~PIM_UPSTREAM_FLAG_MASK_SRC_NOCACHE)

enum pim_upstream_state {
PIM_UPSTREAM_NOTJOINED,
Expand Down
46 changes: 9 additions & 37 deletions pimd/pim_zebra.c
Original file line number Diff line number Diff line change
Expand Up @@ -601,7 +601,6 @@ void pim_scan_individual_oil(struct channel_oil *c_oil, int in_vif_index)
{
struct in_addr vif_source;
int input_iface_vif_index;
int old_vif_index;

pim_rp_set_upstream_addr(c_oil->pim, &vif_source,
c_oil->oil.mfcc_origin,
Expand Down Expand Up @@ -701,33 +700,9 @@ void pim_scan_individual_oil(struct channel_oil *c_oil, int in_vif_index)
}

/* update iif vif_index */
old_vif_index = c_oil->oil.mfcc_parent;
c_oil->oil.mfcc_parent = input_iface_vif_index;

/* update kernel multicast forwarding cache (MFC) */
if (pim_mroute_add(c_oil, __PRETTY_FUNCTION__)) {
if (PIM_DEBUG_MROUTE) {
/* just log warning */
struct interface *old_iif = pim_if_find_by_vif_index(
c_oil->pim, old_vif_index);
struct interface *new_iif = pim_if_find_by_vif_index(
c_oil->pim, input_iface_vif_index);
char source_str[INET_ADDRSTRLEN];
char group_str[INET_ADDRSTRLEN];
pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin,
source_str, sizeof(source_str));
pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp,
group_str, sizeof(group_str));
zlog_debug(
"%s %s: (S,G)=(%s,%s) failure updating input interface from %s vif_index=%d to %s vif_index=%d",
__FILE__, __PRETTY_FUNCTION__, source_str,
group_str,
old_iif ? old_iif->name : "<old_iif?>",
c_oil->oil.mfcc_parent,
new_iif ? new_iif->name : "<new_iif?>",
input_iface_vif_index);
}
}
pim_channel_oil_change_iif(c_oil->pim, c_oil, input_iface_vif_index,
__PRETTY_FUNCTION__);
pim_mroute_add(c_oil, __PRETTY_FUNCTION__);
}

void pim_scan_oil(struct pim_instance *pim)
Expand Down Expand Up @@ -1256,14 +1231,15 @@ void pim_forward_start(struct pim_ifchannel *ch)
__FILE__, __PRETTY_FUNCTION__,
source_str);
}
up->channel_oil = pim_channel_oil_add(
pim, &up->sg, MAXVIFS, __PRETTY_FUNCTION__);
pim_channel_oil_change_iif(pim, up->channel_oil,
MAXVIFS,
__PRETTY_FUNCTION__);
}

else
up->channel_oil = pim_channel_oil_add(
pim, &up->sg, input_iface_vif_index,
__PRETTY_FUNCTION__);
pim_channel_oil_change_iif(pim, up->channel_oil,
input_iface_vif_index,
__PRETTY_FUNCTION__);

if (PIM_DEBUG_TRACE) {
struct interface *in_intf = pim_if_find_by_vif_index(
Expand All @@ -1274,10 +1250,6 @@ void pim_forward_start(struct pim_ifchannel *ch)
in_intf ? in_intf->name : "Unknown",
input_iface_vif_index, up->sg_str);
}

up->channel_oil =
pim_channel_oil_add(pim, &up->sg, input_iface_vif_index,
__PRETTY_FUNCTION__);
}

if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_IGMP)
Expand Down

0 comments on commit e72ce28

Please sign in to comment.