mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-04-29 10:32:00 +00:00
pimd: Handling Null incoming interface of dummy upstream
When FRR receives IGMP/PIM (*, G) join and RP is not configured or not reachable, then we are creating a dummy upstream with incoming interface as NULL and upstream address as INADDR_ANY. Added upstream address and incoming interface validation where it is necessary, before doing any operation on the upstream. Signed-off-by: Sarita Patra <saritap@vmware.com>
This commit is contained in:
parent
d8bed89dca
commit
957d93eaf2
@ -133,6 +133,13 @@ static bool mtrace_fwd_info(struct pim_instance *pim,
|
||||
if (!up)
|
||||
return false;
|
||||
|
||||
if (!up->rpf.source_nexthop.interface) {
|
||||
if (PIM_DEBUG_TRACE)
|
||||
zlog_debug("%s: up %s RPF is not present",
|
||||
__PRETTY_FUNCTION__, up->sg_str);
|
||||
return false;
|
||||
}
|
||||
|
||||
ifp_in = up->rpf.source_nexthop.interface;
|
||||
nh_addr = up->rpf.source_nexthop.mrib_nexthop_addr.u.prefix4;
|
||||
total = htonl(MTRACE_UNKNOWN_COUNT);
|
||||
|
@ -439,9 +439,6 @@ int pim_joinprune_send(struct pim_rpf *rpf, struct list *groups)
|
||||
size_t packet_size = 0;
|
||||
size_t group_size = 0;
|
||||
|
||||
on_trace(__PRETTY_FUNCTION__, rpf->source_nexthop.interface,
|
||||
rpf->rpf_addr.u.prefix4);
|
||||
|
||||
if (rpf->source_nexthop.interface)
|
||||
pim_ifp = rpf->source_nexthop.interface->info;
|
||||
else {
|
||||
@ -450,6 +447,9 @@ int pim_joinprune_send(struct pim_rpf *rpf, struct list *groups)
|
||||
return -1;
|
||||
}
|
||||
|
||||
on_trace(__PRETTY_FUNCTION__, rpf->source_nexthop.interface,
|
||||
rpf->rpf_addr.u.prefix4);
|
||||
|
||||
if (!pim_ifp) {
|
||||
zlog_warn("%s: multicast not enabled on interface %s",
|
||||
__PRETTY_FUNCTION__,
|
||||
|
@ -213,8 +213,18 @@ void pim_jp_agg_upstream_verification(struct pim_upstream *up, bool ignore)
|
||||
{
|
||||
#ifdef PIM_JP_AGG_DEBUG
|
||||
struct interface *ifp;
|
||||
struct pim_interface *pim_ifp = up->rpf.source_nexthop.interface->info;
|
||||
struct pim_instance *pim = pim_ifp->pim;
|
||||
struct pim_interface *pim_ifp;
|
||||
struct pim_instance *pim;
|
||||
|
||||
if (!up->rpf.source_nexthop.interface) {
|
||||
if (PIM_DEBUG_TRACE)
|
||||
zlog_debug("%s: up %s RPF is not present",
|
||||
__PRETTY_FUNCTION__, up->sg_str);
|
||||
return;
|
||||
}
|
||||
|
||||
pim_ifp = up->rpf.source_nexthop.interface->info;
|
||||
pim = pim_ifp->pim;
|
||||
|
||||
FOR_ALL_INTERFACES (pim->vrf, ifp) {
|
||||
pim_ifp = ifp->info;
|
||||
|
@ -234,7 +234,8 @@ static int pim_mroute_msg_nocache(int fd, struct interface *ifp,
|
||||
up->channel_oil->cc.pktcnt++;
|
||||
PIM_UPSTREAM_FLAG_SET_FHR(up->flags);
|
||||
// resolve mfcc_parent prior to mroute_add in channel_add_oif
|
||||
if (up->channel_oil->oil.mfcc_parent >= MAXVIFS) {
|
||||
if (up->rpf.source_nexthop.interface &&
|
||||
up->channel_oil->oil.mfcc_parent >= MAXVIFS) {
|
||||
int vif_index = 0;
|
||||
vif_index = pim_if_find_vifindex_by_ifindex(
|
||||
pim_ifp->pim,
|
||||
@ -301,6 +302,13 @@ static int pim_mroute_msg_wholepkt(int fd, struct interface *ifp,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!up->rpf.source_nexthop.interface) {
|
||||
if (PIM_DEBUG_TRACE)
|
||||
zlog_debug("%s: up %s RPF is not present",
|
||||
__PRETTY_FUNCTION__, up->sg_str);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pim_ifp = up->rpf.source_nexthop.interface->info;
|
||||
|
||||
rpg = pim_ifp ? RP(pim_ifp->pim, sg.grp) : NULL;
|
||||
|
@ -283,7 +283,7 @@ static int pim_update_upstream_nh_helper(struct hash_backet *backet, void *arg)
|
||||
}
|
||||
|
||||
/* update kernel multicast forwarding cache (MFC) */
|
||||
if (up->channel_oil) {
|
||||
if (up->rpf.source_nexthop.interface) {
|
||||
ifindex_t ifindex = up->rpf.source_nexthop.interface->ifindex;
|
||||
|
||||
vif_index = pim_if_find_vifindex_by_ifindex(pim, ifindex);
|
||||
@ -306,9 +306,10 @@ static int pim_update_upstream_nh_helper(struct hash_backet *backet, void *arg)
|
||||
|
||||
if (PIM_DEBUG_PIM_NHT) {
|
||||
zlog_debug("%s: NHT upstream %s(%s) old ifp %s new ifp %s",
|
||||
__PRETTY_FUNCTION__, up->sg_str, pim->vrf->name,
|
||||
old.source_nexthop.interface->name,
|
||||
up->rpf.source_nexthop.interface->name);
|
||||
__PRETTY_FUNCTION__, up->sg_str, pim->vrf->name,
|
||||
old.source_nexthop.interface
|
||||
? old.source_nexthop.interface->name : "Unknwon",
|
||||
up->rpf.source_nexthop.interface->name);
|
||||
}
|
||||
|
||||
return HASHWALK_CONTINUE;
|
||||
|
@ -205,6 +205,12 @@ enum pim_rpf_result pim_rpf_update(struct pim_instance *pim,
|
||||
struct prefix src, grp;
|
||||
bool neigh_needed = true;
|
||||
|
||||
if (up->upstream_addr.s_addr == INADDR_ANY) {
|
||||
zlog_debug("%s: RP is not configured yet for %s",
|
||||
__PRETTY_FUNCTION__, up->sg_str);
|
||||
return PIM_RPF_OK;
|
||||
}
|
||||
|
||||
saved.source_nexthop = rpf->source_nexthop;
|
||||
saved.rpf_addr = rpf->rpf_addr;
|
||||
|
||||
|
@ -238,6 +238,13 @@ struct pim_upstream *pim_upstream_del(struct pim_instance *pim,
|
||||
|
||||
void pim_upstream_send_join(struct pim_upstream *up)
|
||||
{
|
||||
if (!up->rpf.source_nexthop.interface) {
|
||||
if (PIM_DEBUG_TRACE)
|
||||
zlog_debug("%s: up %s RPF is not present",
|
||||
__PRETTY_FUNCTION__, up->sg_str);
|
||||
return;
|
||||
}
|
||||
|
||||
if (PIM_DEBUG_TRACE) {
|
||||
char rpf_str[PREFIX_STRLEN];
|
||||
pim_addr_dump("<rpf?>", &up->rpf.rpf_addr, rpf_str,
|
||||
@ -263,6 +270,13 @@ static int on_join_timer(struct thread *t)
|
||||
|
||||
up = THREAD_ARG(t);
|
||||
|
||||
if (!up->rpf.source_nexthop.interface) {
|
||||
if (PIM_DEBUG_TRACE)
|
||||
zlog_debug("%s: up %s RPF is not present",
|
||||
__PRETTY_FUNCTION__, up->sg_str);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* In the case of a HFR we will not ahve anyone to send this to.
|
||||
*/
|
||||
@ -286,6 +300,13 @@ static void join_timer_stop(struct pim_upstream *up)
|
||||
{
|
||||
struct pim_neighbor *nbr;
|
||||
|
||||
if (!up->rpf.source_nexthop.interface) {
|
||||
if (PIM_DEBUG_TRACE)
|
||||
zlog_debug("%s: up %s RPF is not present",
|
||||
__PRETTY_FUNCTION__, up->sg_str);
|
||||
return;
|
||||
}
|
||||
|
||||
THREAD_OFF(up->t_join_timer);
|
||||
|
||||
nbr = pim_neighbor_find(up->rpf.source_nexthop.interface,
|
||||
@ -301,6 +322,13 @@ void join_timer_start(struct pim_upstream *up)
|
||||
{
|
||||
struct pim_neighbor *nbr = NULL;
|
||||
|
||||
if (!up->rpf.source_nexthop.interface) {
|
||||
if (PIM_DEBUG_TRACE)
|
||||
zlog_debug("%s: up %s RPF is not present",
|
||||
__PRETTY_FUNCTION__, up->sg_str);
|
||||
return;
|
||||
}
|
||||
|
||||
if (up->rpf.source_nexthop.interface) {
|
||||
nbr = pim_neighbor_find(up->rpf.source_nexthop.interface,
|
||||
up->rpf.rpf_addr.u.prefix4);
|
||||
@ -356,6 +384,13 @@ void pim_upstream_join_suppress(struct pim_upstream *up,
|
||||
long t_joinsuppress_msec;
|
||||
long join_timer_remain_msec;
|
||||
|
||||
if (!up->rpf.source_nexthop.interface) {
|
||||
if (PIM_DEBUG_TRACE)
|
||||
zlog_debug("%s: up %s RPF is not present",
|
||||
__PRETTY_FUNCTION__, up->sg_str);
|
||||
return;
|
||||
}
|
||||
|
||||
t_joinsuppress_msec =
|
||||
MIN(pim_if_t_suppressed_msec(up->rpf.source_nexthop.interface),
|
||||
1000 * holdtime);
|
||||
@ -389,6 +424,13 @@ void pim_upstream_join_timer_decrease_to_t_override(const char *debug_label,
|
||||
long join_timer_remain_msec;
|
||||
int t_override_msec;
|
||||
|
||||
if (!up->rpf.source_nexthop.interface) {
|
||||
if (PIM_DEBUG_TRACE)
|
||||
zlog_debug("%s: up %s RPF is not present",
|
||||
__PRETTY_FUNCTION__, up->sg_str);
|
||||
return;
|
||||
}
|
||||
|
||||
join_timer_remain_msec = pim_time_timer_remain_msec(up->t_join_timer);
|
||||
t_override_msec =
|
||||
pim_if_t_override_msec(up->rpf.source_nexthop.interface);
|
||||
@ -511,6 +553,18 @@ void pim_upstream_switch(struct pim_instance *pim, struct pim_upstream *up,
|
||||
{
|
||||
enum pim_upstream_state old_state = up->join_state;
|
||||
|
||||
if (up->upstream_addr.s_addr == INADDR_ANY) {
|
||||
zlog_debug("%s: RPF not configured for %s",
|
||||
__PRETTY_FUNCTION__, up->sg_str);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!up->rpf.source_nexthop.interface) {
|
||||
zlog_debug("%s: RP not reachable for %s",
|
||||
__PRETTY_FUNCTION__, up->sg_str);
|
||||
return;
|
||||
}
|
||||
|
||||
if (PIM_DEBUG_PIM_EVENTS) {
|
||||
zlog_debug("%s: PIM_UPSTREAM_%s: (S,G) old: %s new: %s",
|
||||
__PRETTY_FUNCTION__, up->sg_str,
|
||||
@ -558,11 +612,14 @@ void pim_upstream_switch(struct pim_instance *pim, struct pim_upstream *up,
|
||||
&& !I_am_RP(pim, up->sg.grp)) {
|
||||
if (PIM_DEBUG_PIM_TRACE_DETAIL)
|
||||
zlog_debug(
|
||||
"%s: *,G IIF %s S,G IIF %s ",
|
||||
__PRETTY_FUNCTION__,
|
||||
up->parent->rpf.source_nexthop
|
||||
.interface->name,
|
||||
up->rpf.source_nexthop.interface->name);
|
||||
"%s: *,G IIF %s S,G IIF %s ",
|
||||
__PRETTY_FUNCTION__,
|
||||
up->parent->rpf.source_nexthop.interface ?
|
||||
up->parent->rpf.source_nexthop.interface->name
|
||||
: "Unknown",
|
||||
up->rpf.source_nexthop.interface ?
|
||||
up->rpf.source_nexthop.interface->name :
|
||||
"Unknown");
|
||||
pim_jp_agg_single_upstream_send(&up->parent->rpf,
|
||||
up->parent,
|
||||
1 /* (W,G) Join */);
|
||||
@ -783,7 +840,7 @@ struct pim_upstream *pim_upstream_add(struct pim_instance *pim,
|
||||
zlog_debug("%s(%s): %s, iif %s (%s) found: %d: ref_count: %d",
|
||||
__PRETTY_FUNCTION__, name,
|
||||
up->sg_str, buf, up->rpf.source_nexthop.interface ?
|
||||
up->rpf.source_nexthop.interface->name : "NIL" ,
|
||||
up->rpf.source_nexthop.interface->name : "Unknown" ,
|
||||
found, up->ref_count);
|
||||
} else
|
||||
zlog_debug("%s(%s): (%s) failure to create",
|
||||
@ -973,7 +1030,9 @@ void pim_upstream_rpf_interface_changed(struct pim_upstream *up,
|
||||
(old_rpf_ifp == ch->interface) &&
|
||||
/* RPF_interface(S) stopped being I */
|
||||
(ch->upstream->rpf.source_nexthop
|
||||
.interface != ch->interface)) {
|
||||
.interface) &&
|
||||
(ch->upstream->rpf.source_nexthop
|
||||
.interface != ch->interface)) {
|
||||
assert_action_a5(ch);
|
||||
}
|
||||
} /* PIM_IFASSERT_I_AM_LOSER */
|
||||
@ -1339,6 +1398,13 @@ static int pim_upstream_register_stop_timer(struct thread *t)
|
||||
case PIM_REG_JOIN:
|
||||
break;
|
||||
case PIM_REG_PRUNE:
|
||||
if (!up->rpf.source_nexthop.interface) {
|
||||
if (PIM_DEBUG_TRACE)
|
||||
zlog_debug("%s: up %s RPF is not present",
|
||||
__PRETTY_FUNCTION__, up->sg_str);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pim_ifp = up->rpf.source_nexthop.interface->info;
|
||||
if (!pim_ifp) {
|
||||
if (PIM_DEBUG_TRACE)
|
||||
@ -1515,11 +1581,19 @@ void pim_upstream_find_new_rpf(struct pim_instance *pim)
|
||||
* Scan all (S,G) upstreams searching for RPF'(S,G)=neigh_addr
|
||||
*/
|
||||
for (ALL_LIST_ELEMENTS(pim->upstream_list, up_node, up_nextnode, up)) {
|
||||
if (up->upstream_addr.s_addr == INADDR_ANY) {
|
||||
if (PIM_DEBUG_TRACE)
|
||||
zlog_debug(
|
||||
"%s: RP not configured for Upstream %s",
|
||||
__PRETTY_FUNCTION__, up->sg_str);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pim_rpf_addr_is_inaddr_any(&up->rpf)) {
|
||||
if (PIM_DEBUG_TRACE)
|
||||
zlog_debug(
|
||||
"Upstream %s without a path to send join, checking",
|
||||
up->sg_str);
|
||||
"%s: Upstream %s without a path to send join, checking",
|
||||
__PRETTY_FUNCTION__, up->sg_str);
|
||||
pim_rpf_update(pim, up, NULL, 1);
|
||||
}
|
||||
}
|
||||
@ -1586,7 +1660,8 @@ static bool pim_upstream_kat_start_ok(struct pim_upstream *up)
|
||||
|
||||
/* "iif == RPF_interface(S)" check has to be done by the kernel or hw
|
||||
* so we will skip that here */
|
||||
if (pim_if_connected_to_source(up->rpf.source_nexthop.interface,
|
||||
if (up->rpf.source_nexthop.interface &&
|
||||
pim_if_connected_to_source(up->rpf.source_nexthop.interface,
|
||||
up->sg.src)) {
|
||||
return true;
|
||||
}
|
||||
@ -1679,7 +1754,8 @@ static void pim_upstream_sg_running(void *arg)
|
||||
} else if (PIM_UPSTREAM_FLAG_TEST_SRC_LHR(up->flags))
|
||||
pim_upstream_keep_alive_timer_start(up, pim->keep_alive_time);
|
||||
|
||||
if (up->sptbit != PIM_UPSTREAM_SPTBIT_TRUE) {
|
||||
if ((up->sptbit != PIM_UPSTREAM_SPTBIT_TRUE) &&
|
||||
(up->rpf.source_nexthop.interface)) {
|
||||
pim_upstream_set_sptbit(up, up->rpf.source_nexthop.interface);
|
||||
}
|
||||
return;
|
||||
|
@ -535,6 +535,14 @@ static void scan_upstream_rpf_cache(struct pim_instance *pim)
|
||||
struct pim_rpf old;
|
||||
struct prefix nht_p;
|
||||
|
||||
if (up->upstream_addr.s_addr == INADDR_ANY) {
|
||||
if (PIM_DEBUG_TRACE)
|
||||
zlog_debug(
|
||||
"%s: RP not configured for Upstream %s",
|
||||
__PRETTY_FUNCTION__, up->sg_str);
|
||||
continue;
|
||||
}
|
||||
|
||||
nht_p.family = AF_INET;
|
||||
nht_p.prefixlen = IPV4_MAX_BITLEN;
|
||||
nht_p.u.prefix4.s_addr = up->upstream_addr.s_addr;
|
||||
|
Loading…
Reference in New Issue
Block a user