void pim_jp_agg_group_list_free(struct pim_jp_agg_group *jag)
{
- list_delete(jag->sources);
+ list_delete(&jag->sources);
XFREE(MTYPE_PIM_JP_AGG_GROUP, jag);
}
js->up = NULL;
XFREE(MTYPE_PIM_JP_AGG_SOURCE, js);
}
- list_delete(jag->sources);
- jag->sources = NULL;
+ list_delete(&jag->sources);
listnode_delete(group, jag);
XFREE(MTYPE_PIM_JP_AGG_GROUP, jag);
}
static struct pim_iface_upstream_switch *
pim_jp_agg_get_interface_upstream_switch_list(struct pim_rpf *rpf)
{
- struct pim_interface *pim_ifp = rpf->source_nexthop.interface->info;
+ struct interface *ifp = rpf->source_nexthop.interface;
+ struct pim_interface *pim_ifp;
struct pim_iface_upstream_switch *pius;
struct listnode *node, *nnode;
+ if (!ifp)
+ return NULL;
+
+ pim_ifp = ifp->info;
+
/* Old interface is pim disabled */
if (!pim_ifp)
return NULL;
return pius;
}
-void pim_jp_agg_remove_group(struct list *group, struct pim_upstream *up)
+void pim_jp_agg_remove_group(struct list *group, struct pim_upstream *up,
+ struct pim_neighbor *nbr)
{
struct listnode *node, *nnode;
struct pim_jp_agg_group *jag = NULL;
break;
}
+ if (nbr) {
+ if (PIM_DEBUG_TRACE) {
+ char src_str[INET_ADDRSTRLEN];
+
+ pim_inet4_dump("<src?>", nbr->source_addr, src_str,
+ sizeof(src_str));
+ zlog_debug(
+ "up %s remove from nbr %s/%s jp-agg-list",
+ up->sg_str,
+ nbr->interface->name,
+ src_str);
+ }
+ }
+
if (js) {
js->up = NULL;
listnode_delete(jag->sources, js);
}
if (jag->sources->count == 0) {
- list_delete(jag->sources);
- jag->sources = NULL;
+ list_delete(&jag->sources);
listnode_delete(group, jag);
XFREE(MTYPE_PIM_JP_AGG_GROUP, jag);
}
void pim_jp_agg_upstream_verification(struct pim_upstream *up, bool ignore)
{
#ifdef PIM_JP_AGG_DEBUG
- struct listnode *node;
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_PIM_TRACE)
+ zlog_debug("%s: up %s RPF is not present",
+ __PRETTY_FUNCTION__, up->sg_str);
+ return;
+ }
- for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), node, ifp)) {
+ pim_ifp = up->rpf.source_nexthop.interface->info;
+ pim = pim_ifp->pim;
+
+ FOR_ALL_INTERFACES (pim->vrf, ifp) {
pim_ifp = ifp->info;
struct listnode *nnode;
}
void pim_jp_agg_add_group(struct list *group, struct pim_upstream *up,
- bool is_join)
+ bool is_join, struct pim_neighbor *nbr)
{
struct listnode *node, *nnode;
struct pim_jp_agg_group *jag = NULL;
break;
}
+ if (nbr) {
+ if (PIM_DEBUG_TRACE) {
+ char src_str[INET_ADDRSTRLEN];
+
+ pim_inet4_dump("<src?>", nbr->source_addr, src_str,
+ sizeof(src_str));
+ zlog_debug(
+ "up %s add to nbr %s/%s jp-agg-list",
+ up->sg_str,
+ up->rpf.source_nexthop.interface->name,
+ src_str);
+ }
+ }
+
if (!js) {
js = XCALLOC(MTYPE_PIM_JP_AGG_SOURCE,
sizeof(struct pim_jp_sources));
/* send Prune(S,G) to the old upstream neighbor */
if (opius)
- pim_jp_agg_add_group(opius->us, up, false);
+ pim_jp_agg_add_group(opius->us, up, false, NULL);
/* send Join(S,G) to the current upstream neighbor */
- pim_jp_agg_add_group(npius->us, up, true);
+ if (npius)
+ pim_jp_agg_add_group(npius->us, up, true, NULL);
}
static bool first = true;
/* skip JP upstream messages if source is directly connected */
- if (!up || !rpf->source_nexthop.interface || pim_if_connected_to_source(
- rpf->source_nexthop
- .interface,
- up->sg.src))
+ if (!up || !rpf->source_nexthop.interface ||
+ pim_if_connected_to_source(rpf->source_nexthop.interface,
+ up->sg.src) ||
+ if_is_loopback_or_vrf(rpf->source_nexthop.interface))
return;
if (first) {
groups = list_new();
-
jag.sources = list_new();
listnode_add(groups, &jag);