pimd: Remove pimg from pim_upstream.c

Move the upstream_list, hash and wheel into 'struct pim_instance'
Remove all pimg to pim in pim_upstream

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This commit is contained in:
Donald Sharp 2017-05-19 19:36:53 -04:00
parent fec883d95a
commit 9b29ea95fc
20 changed files with 306 additions and 236 deletions

View File

@ -47,6 +47,7 @@ void pim_ifassert_winner_set(struct pim_ifchannel *ch,
struct in_addr winner, struct in_addr winner,
struct pim_assert_metric winner_metric) struct pim_assert_metric winner_metric)
{ {
struct pim_interface *pim_ifp = ch->interface->info;
int winner_changed = (ch->ifassert_winner.s_addr != winner.s_addr); int winner_changed = (ch->ifassert_winner.s_addr != winner.s_addr);
int metric_changed = !pim_assert_metric_match( int metric_changed = !pim_assert_metric_match(
&ch->ifassert_winner_metric, &winner_metric); &ch->ifassert_winner_metric, &winner_metric);
@ -81,7 +82,7 @@ void pim_ifassert_winner_set(struct pim_ifchannel *ch,
ch->ifassert_creation = pim_time_monotonic_sec(); ch->ifassert_creation = pim_time_monotonic_sec();
if (winner_changed || metric_changed) { if (winner_changed || metric_changed) {
pim_upstream_update_join_desired(ch->upstream); pim_upstream_update_join_desired(pim_ifp->pim, ch->upstream);
pim_ifchannel_update_could_assert(ch); pim_ifchannel_update_could_assert(ch);
pim_ifchannel_update_assert_tracking_desired(ch); pim_ifchannel_update_assert_tracking_desired(ch);
} }
@ -404,9 +405,9 @@ int pim_assert_build_msg(uint8_t *pim_msg, int buf_size, struct interface *ifp,
} }
/* Metric preference */ /* Metric preference */
pim_write_uint32(pim_msg_curr, pim_write_uint32(pim_msg_curr, rpt_bit_flag
rpt_bit_flag ? metric_preference | 0x80000000 ? metric_preference | 0x80000000
: metric_preference); : metric_preference);
pim_msg_curr += 4; pim_msg_curr += 4;
/* Route metric */ /* Route metric */

View File

@ -27,6 +27,7 @@
#include "vty.h" #include "vty.h"
#include "zclient.h" #include "zclient.h"
#include "pim_instance.h"
#include "pim_cmd.h" #include "pim_cmd.h"
#include "pim_vty.h" #include "pim_vty.h"
#include "pim_iface.h" #include "pim_iface.h"

View File

@ -989,7 +989,7 @@ static void pim_show_interfaces_single(struct vty *vty, const char *ifname,
pim_ifp->pim_dr_election_changes); pim_ifp->pim_dr_election_changes);
// FHR // FHR
for (ALL_LIST_ELEMENTS_RO(pim_upstream_list, upnode, for (ALL_LIST_ELEMENTS_RO(pimg->upstream_list, upnode,
up)) { up)) {
if (ifp == up->rpf.source_nexthop.interface) { if (ifp == up->rpf.source_nexthop.interface) {
if (up->flags if (up->flags
@ -1163,7 +1163,7 @@ static void pim_show_interfaces_single(struct vty *vty, const char *ifname,
// FHR // FHR
print_header = 1; print_header = 1;
for (ALL_LIST_ELEMENTS_RO(pim_upstream_list, upnode, for (ALL_LIST_ELEMENTS_RO(pimg->upstream_list, upnode,
up)) { up)) {
if (strcmp(ifp->name, up->rpf.source_nexthop if (strcmp(ifp->name, up->rpf.source_nexthop
.interface->name) .interface->name)
@ -1291,7 +1291,7 @@ static void pim_show_interfaces(struct vty *vty, u_char uj)
pim_ifchannels = pim_ifp->pim_ifchannel_list->count; pim_ifchannels = pim_ifp->pim_ifchannel_list->count;
fhr = 0; fhr = 0;
for (ALL_LIST_ELEMENTS_RO(pim_upstream_list, upnode, up)) for (ALL_LIST_ELEMENTS_RO(pimg->upstream_list, upnode, up))
if (ifp == up->rpf.source_nexthop.interface) if (ifp == up->rpf.source_nexthop.interface)
if (up->flags & PIM_UPSTREAM_FLAG_MASK_FHR) if (up->flags & PIM_UPSTREAM_FLAG_MASK_FHR)
fhr++; fhr++;
@ -2251,7 +2251,7 @@ static void pim_show_upstream(struct vty *vty, u_char uj)
vty_out(vty, vty_out(vty,
"Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt\n"); "Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt\n");
for (ALL_LIST_ELEMENTS_RO(pim_upstream_list, upnode, up)) { for (ALL_LIST_ELEMENTS_RO(pimg->upstream_list, upnode, up)) {
char src_str[INET_ADDRSTRLEN]; char src_str[INET_ADDRSTRLEN];
char grp_str[INET_ADDRSTRLEN]; char grp_str[INET_ADDRSTRLEN];
char uptime[10]; char uptime[10];
@ -2407,7 +2407,7 @@ static void pim_show_join_desired(struct vty *vty, u_char uj)
json_object_boolean_true_add(json_row, json_object_boolean_true_add(json_row,
"pimInclude"); "pimInclude");
if (pim_upstream_evaluate_join_desired(up)) if (pim_upstream_evaluate_join_desired(pimg, up))
json_object_boolean_true_add( json_object_boolean_true_add(
json_row, "evaluateJoinDesired"); json_row, "evaluateJoinDesired");
@ -2424,8 +2424,9 @@ static void pim_show_join_desired(struct vty *vty, u_char uj)
up->flags) up->flags)
? "yes" ? "yes"
: "no", : "no",
pim_upstream_evaluate_join_desired(up) ? "yes" pim_upstream_evaluate_join_desired(pimg, up)
: "no"); ? "yes"
: "no");
} }
} }
@ -2450,7 +2451,7 @@ static void pim_show_upstream_rpf(struct vty *vty, u_char uj)
vty_out(vty, vty_out(vty,
"Source Group RpfIface RibNextHop RpfAddress \n"); "Source Group RpfIface RibNextHop RpfAddress \n");
for (ALL_LIST_ELEMENTS_RO(pim_upstream_list, upnode, up)) { for (ALL_LIST_ELEMENTS_RO(pimg->upstream_list, upnode, up)) {
char src_str[INET_ADDRSTRLEN]; char src_str[INET_ADDRSTRLEN];
char grp_str[INET_ADDRSTRLEN]; char grp_str[INET_ADDRSTRLEN];
char rpf_nexthop_str[PREFIX_STRLEN]; char rpf_nexthop_str[PREFIX_STRLEN];
@ -2587,7 +2588,7 @@ static void pim_show_rpf(struct vty *vty, u_char uj)
"Source Group RpfIface RpfAddress RibNextHop Metric Pref\n"); "Source Group RpfIface RpfAddress RibNextHop Metric Pref\n");
} }
for (ALL_LIST_ELEMENTS_RO(pim_upstream_list, up_node, up)) { for (ALL_LIST_ELEMENTS_RO(pimg->upstream_list, up_node, up)) {
char src_str[INET_ADDRSTRLEN]; char src_str[INET_ADDRSTRLEN];
char grp_str[INET_ADDRSTRLEN]; char grp_str[INET_ADDRSTRLEN];
char rpf_addr_str[PREFIX_STRLEN]; char rpf_addr_str[PREFIX_STRLEN];
@ -4339,10 +4340,10 @@ static int pim_cmd_spt_switchover(enum pim_spt_switchover spt,
if (pimg->spt.plist) if (pimg->spt.plist)
XFREE(MTYPE_PIM_SPT_PLIST_NAME, pimg->spt.plist); XFREE(MTYPE_PIM_SPT_PLIST_NAME, pimg->spt.plist);
pim_upstream_add_lhr_star_pimreg(); pim_upstream_add_lhr_star_pimreg(pimg);
break; break;
case PIM_SPT_INFINITY: case PIM_SPT_INFINITY:
pim_upstream_remove_lhr_star_pimreg(plist); pim_upstream_remove_lhr_star_pimreg(pimg, plist);
if (pimg->spt.plist) if (pimg->spt.plist)
XFREE(MTYPE_PIM_SPT_PLIST_NAME, pimg->spt.plist); XFREE(MTYPE_PIM_SPT_PLIST_NAME, pimg->spt.plist);

View File

@ -395,7 +395,8 @@ int pim_hello_recv(struct interface *ifp, struct in_addr src_addr,
ifp->name); ifp->name);
} }
pim_upstream_rpf_genid_changed(neigh->source_addr); pim_upstream_rpf_genid_changed(pim_ifp->pim,
neigh->source_addr);
pim_neighbor_delete(ifp, neigh, "GenID mismatch"); pim_neighbor_delete(ifp, neigh, "GenID mismatch");
neigh = pim_neighbor_add(ifp, src_addr, hello_options, neigh = pim_neighbor_add(ifp, src_addr, hello_options,

View File

@ -1546,7 +1546,7 @@ void pim_if_update_join_desired(struct pim_interface *pim_ifp)
continue; continue;
/* update join_desired for the global (S,G) state */ /* update join_desired for the global (S,G) state */
pim_upstream_update_join_desired(up); pim_upstream_update_join_desired(pim_ifp->pim, up);
PIM_UPSTREAM_FLAG_SET_DR_JOIN_DESIRED_UPDATED(up->flags); PIM_UPSTREAM_FLAG_SET_DR_JOIN_DESIRED_UPDATED(up->flags);
} }
} }

View File

@ -171,14 +171,14 @@ void pim_ifchannel_delete(struct pim_ifchannel *ch)
listnode_delete(ch->upstream->ifchannels, ch); listnode_delete(ch->upstream->ifchannels, ch);
if (ch->ifjoin_state != PIM_IFJOIN_NOINFO) { if (ch->ifjoin_state != PIM_IFJOIN_NOINFO) {
pim_upstream_update_join_desired(ch->upstream); pim_upstream_update_join_desired(pim_ifp->pim, ch->upstream);
} }
/* upstream is common across ifchannels, check if upstream's /* upstream is common across ifchannels, check if upstream's
ifchannel list is empty before deleting upstream_del ifchannel list is empty before deleting upstream_del
ref count will take care of it. ref count will take care of it.
*/ */
pim_upstream_del(ch->upstream, __PRETTY_FUNCTION__); pim_upstream_del(pim_ifp->pim, ch->upstream, __PRETTY_FUNCTION__);
ch->upstream = NULL; ch->upstream = NULL;
THREAD_OFF(ch->t_ifjoin_expiry_timer); THREAD_OFF(ch->t_ifjoin_expiry_timer);
@ -234,6 +234,7 @@ void pim_ifchannel_ifjoin_switch(const char *caller, struct pim_ifchannel *ch,
enum pim_ifjoin_state new_state) enum pim_ifjoin_state new_state)
{ {
enum pim_ifjoin_state old_state = ch->ifjoin_state; enum pim_ifjoin_state old_state = ch->ifjoin_state;
struct pim_interface *pim_ifp = ch->interface->info;
if (PIM_DEBUG_PIM_EVENTS) if (PIM_DEBUG_PIM_EVENTS)
zlog_debug( zlog_debug(
@ -266,8 +267,6 @@ void pim_ifchannel_ifjoin_switch(const char *caller, struct pim_ifchannel *ch,
child)) { child)) {
struct channel_oil *c_oil = struct channel_oil *c_oil =
child->channel_oil; child->channel_oil;
struct pim_interface *pim_ifp =
ch->interface->info;
if (PIM_DEBUG_PIM_TRACE) if (PIM_DEBUG_PIM_TRACE)
zlog_debug( zlog_debug(
@ -280,12 +279,12 @@ void pim_ifchannel_ifjoin_switch(const char *caller, struct pim_ifchannel *ch,
continue; continue;
if (!pim_upstream_evaluate_join_desired( if (!pim_upstream_evaluate_join_desired(
child)) { pim_ifp->pim, child)) {
pim_channel_del_oif( pim_channel_del_oif(
c_oil, ch->interface, c_oil, ch->interface,
PIM_OIF_FLAG_PROTO_STAR); PIM_OIF_FLAG_PROTO_STAR);
pim_upstream_update_join_desired( pim_upstream_update_join_desired(
child); pim_ifp->pim, child);
} }
/* /*
@ -315,13 +314,13 @@ void pim_ifchannel_ifjoin_switch(const char *caller, struct pim_ifchannel *ch,
up->sg_str); up->sg_str);
if (pim_upstream_evaluate_join_desired( if (pim_upstream_evaluate_join_desired(
child)) { pim_ifp->pim, child)) {
pim_channel_add_oif( pim_channel_add_oif(
child->channel_oil, child->channel_oil,
ch->interface, ch->interface,
PIM_OIF_FLAG_PROTO_STAR); PIM_OIF_FLAG_PROTO_STAR);
pim_upstream_update_join_desired( pim_upstream_update_join_desired(
child); pim_ifp->pim, child);
} }
} }
} }
@ -343,7 +342,7 @@ void pim_ifchannel_ifjoin_switch(const char *caller, struct pim_ifchannel *ch,
*/ */
ch->ifjoin_creation = pim_time_monotonic_sec(); ch->ifjoin_creation = pim_time_monotonic_sec();
pim_upstream_update_join_desired(ch->upstream); pim_upstream_update_join_desired(pim_ifp->pim, ch->upstream);
pim_ifchannel_update_could_assert(ch); pim_ifchannel_update_could_assert(ch);
pim_ifchannel_update_assert_tracking_desired(ch); pim_ifchannel_update_assert_tracking_desired(ch);
} }
@ -433,6 +432,8 @@ struct pim_ifchannel *pim_ifchannel_find(struct interface *ifp,
static void ifmembership_set(struct pim_ifchannel *ch, static void ifmembership_set(struct pim_ifchannel *ch,
enum pim_ifmembership membership) enum pim_ifmembership membership)
{ {
struct pim_interface *pim_ifp = ch->interface->info;
if (ch->local_ifmembership == membership) if (ch->local_ifmembership == membership)
return; return;
@ -446,7 +447,7 @@ static void ifmembership_set(struct pim_ifchannel *ch,
ch->local_ifmembership = membership; ch->local_ifmembership = membership;
pim_upstream_update_join_desired(ch->upstream); pim_upstream_update_join_desired(pim_ifp->pim, ch->upstream);
pim_ifchannel_update_could_assert(ch); pim_ifchannel_update_could_assert(ch);
pim_ifchannel_update_assert_tracking_desired(ch); pim_ifchannel_update_assert_tracking_desired(ch);
} }
@ -534,7 +535,7 @@ struct pim_ifchannel *pim_ifchannel_add(struct interface *ifp,
"%s: pim_ifchannel_new() failure for (S,G)=%s on interface %s", "%s: pim_ifchannel_new() failure for (S,G)=%s on interface %s",
__PRETTY_FUNCTION__, up->sg_str, ifp->name); __PRETTY_FUNCTION__, up->sg_str, ifp->name);
pim_upstream_del(up, __PRETTY_FUNCTION__); pim_upstream_del(pim_ifp->pim, up, __PRETTY_FUNCTION__);
return NULL; return NULL;
} }
@ -639,7 +640,8 @@ static int on_ifjoin_prune_pending_timer(struct thread *t)
*/ */
if (PIM_IF_FLAG_TEST_S_G_RPT(ch->flags)) { if (PIM_IF_FLAG_TEST_S_G_RPT(ch->flags)) {
if (ch->upstream) if (ch->upstream)
pim_upstream_update_join_desired(ch->upstream); pim_upstream_update_join_desired(pim_ifp->pim,
ch->upstream);
/* /*
ch->ifjoin_state transition to NOINFO state ch->ifjoin_state transition to NOINFO state
ch_del is set to 0 for not deleteing from here. ch_del is set to 0 for not deleteing from here.
@ -664,9 +666,10 @@ static void check_recv_upstream(int is_join, struct interface *recv_ifp,
uint8_t source_flags, int holdtime) uint8_t source_flags, int holdtime)
{ {
struct pim_upstream *up; struct pim_upstream *up;
struct pim_interface *pim_ifp = recv_ifp->info;
/* Upstream (S,G) in Joined state ? */ /* Upstream (S,G) in Joined state ? */
up = pim_upstream_find(sg); up = pim_upstream_find(pim_ifp->pim, sg);
if (!up) if (!up)
return; return;
if (up->join_state != PIM_UPSTREAM_JOINED) if (up->join_state != PIM_UPSTREAM_JOINED)
@ -807,7 +810,8 @@ void pim_ifchannel_join_add(struct interface *ifp, struct in_addr neigh_addr,
pim_ifchannel_ifjoin_switch(__PRETTY_FUNCTION__, ch, pim_ifchannel_ifjoin_switch(__PRETTY_FUNCTION__, ch,
PIM_IFJOIN_JOIN); PIM_IFJOIN_JOIN);
if (pim_macro_chisin_oiflist(ch)) { if (pim_macro_chisin_oiflist(ch)) {
pim_upstream_inherited_olist(ch->upstream); pim_upstream_inherited_olist(pim_ifp->pim,
ch->upstream);
pim_forward_start(ch); pim_forward_start(ch);
} }
/* /*
@ -941,7 +945,8 @@ void pim_ifchannel_prune(struct interface *ifp, struct in_addr upstream,
&ch->t_ifjoin_prune_pending_timer); &ch->t_ifjoin_prune_pending_timer);
thread_add_timer(master, on_ifjoin_expiry_timer, ch, thread_add_timer(master, on_ifjoin_expiry_timer, ch,
holdtime, &ch->t_ifjoin_expiry_timer); holdtime, &ch->t_ifjoin_expiry_timer);
pim_upstream_update_join_desired(ch->upstream); pim_upstream_update_join_desired(pim_ifp->pim,
ch->upstream);
} }
break; break;
case PIM_IFJOIN_PRUNE_PENDING: case PIM_IFJOIN_PRUNE_PENDING:
@ -1029,7 +1034,7 @@ int pim_ifchannel_local_membership_add(struct interface *ifp,
ifmembership_set(ch, PIM_IFMEMBERSHIP_INCLUDE); ifmembership_set(ch, PIM_IFMEMBERSHIP_INCLUDE);
if (sg->src.s_addr == INADDR_ANY) { if (sg->src.s_addr == INADDR_ANY) {
struct pim_upstream *up = pim_upstream_find(sg); struct pim_upstream *up = pim_upstream_find(pim, sg);
struct pim_upstream *child; struct pim_upstream *child;
struct listnode *up_node; struct listnode *up_node;
@ -1095,7 +1100,7 @@ void pim_ifchannel_local_membership_del(struct interface *ifp,
ifmembership_set(ch, PIM_IFMEMBERSHIP_NOINFO); ifmembership_set(ch, PIM_IFMEMBERSHIP_NOINFO);
if (sg->src.s_addr == INADDR_ANY) { if (sg->src.s_addr == INADDR_ANY) {
struct pim_upstream *up = pim_upstream_find(sg); struct pim_upstream *up = pim_upstream_find(pim_ifp->pim, sg);
struct pim_upstream *child; struct pim_upstream *child;
struct listnode *up_node, *up_nnode; struct listnode *up_node, *up_nnode;

View File

@ -48,6 +48,8 @@ static void pim_instance_terminate(struct pim_instance *pim)
if (pim->static_routes) if (pim->static_routes)
list_free(pim->static_routes); list_free(pim->static_routes);
pim_upstream_terminate(pim);
XFREE(MTYPE_PIM_PIM_INSTANCE, pimg); XFREE(MTYPE_PIM_PIM_INSTANCE, pimg);
} }
@ -93,6 +95,7 @@ static struct pim_instance *pim_instance_init(struct vrf *vrf)
pim_mroute_socket_enable(pim); pim_mroute_socket_enable(pim);
pim_upstream_init(pim);
return pim; return pim;
} }

View File

@ -56,6 +56,11 @@ struct pim_instance {
// List of static routes; // List of static routes;
struct list *static_routes; struct list *static_routes;
// Upstream vrf specific information
struct list *upstream_list;
struct hash *upstream_hash;
struct timer_wheel *upstream_sg_wheel;
}; };
void pim_vrf_init(void); void pim_vrf_init(void);

View File

@ -214,18 +214,20 @@ static int pim_mroute_msg_wholepkt(int fd, struct interface *ifp,
const struct ip *ip_hdr; const struct ip *ip_hdr;
struct pim_upstream *up; struct pim_upstream *up;
pim_ifp = ifp->info;
ip_hdr = (const struct ip *)buf; ip_hdr = (const struct ip *)buf;
memset(&sg, 0, sizeof(struct prefix_sg)); memset(&sg, 0, sizeof(struct prefix_sg));
sg.src = ip_hdr->ip_src; sg.src = ip_hdr->ip_src;
sg.grp = ip_hdr->ip_dst; sg.grp = ip_hdr->ip_dst;
up = pim_upstream_find(&sg); up = pim_upstream_find(pim_ifp->pim, &sg);
if (!up) { if (!up) {
struct prefix_sg star = sg; struct prefix_sg star = sg;
star.src.s_addr = INADDR_ANY; star.src.s_addr = INADDR_ANY;
up = pim_upstream_find(&star); up = pim_upstream_find(pim_ifp->pim, &star);
if (up && PIM_UPSTREAM_FLAG_TEST_SRC_IGMP(up->flags)) { if (up && PIM_UPSTREAM_FLAG_TEST_SRC_IGMP(up->flags)) {
up = pim_upstream_add(&sg, ifp, up = pim_upstream_add(&sg, ifp,
@ -241,7 +243,7 @@ static int pim_mroute_msg_wholepkt(int fd, struct interface *ifp,
} }
pim_upstream_keep_alive_timer_start( pim_upstream_keep_alive_timer_start(
up, qpim_keep_alive_time); up, qpim_keep_alive_time);
pim_upstream_inherited_olist(up); pim_upstream_inherited_olist(pim_ifp->pim, up);
pim_upstream_switch(up, PIM_UPSTREAM_JOINED); pim_upstream_switch(up, PIM_UPSTREAM_JOINED);
if (PIM_DEBUG_MROUTE) if (PIM_DEBUG_MROUTE)
@ -433,7 +435,7 @@ static int pim_mroute_msg_wrvifwhole(int fd, struct interface *ifp,
} }
#endif #endif
up = pim_upstream_find(&sg); up = pim_upstream_find(pim_ifp->pim, &sg);
if (up) { if (up) {
struct pim_upstream *parent; struct pim_upstream *parent;
struct pim_nexthop source; struct pim_nexthop source;
@ -447,7 +449,7 @@ static int pim_mroute_msg_wrvifwhole(int fd, struct interface *ifp,
* tree, let's check and if so we can safely drop * tree, let's check and if so we can safely drop
* it. * it.
*/ */
parent = pim_upstream_find(&star_g); parent = pim_upstream_find(pim_ifp->pim, &star_g);
if (parent && parent->rpf.source_nexthop.interface == ifp) if (parent && parent->rpf.source_nexthop.interface == ifp)
return 0; return 0;
@ -469,7 +471,7 @@ static int pim_mroute_msg_wrvifwhole(int fd, struct interface *ifp,
if (!up->channel_oil) if (!up->channel_oil)
up->channel_oil = pim_channel_oil_add( up->channel_oil = pim_channel_oil_add(
&sg, pim_ifp->mroute_vif_index); &sg, pim_ifp->mroute_vif_index);
pim_upstream_inherited_olist(up); pim_upstream_inherited_olist(pim_ifp->pim, up);
if (!up->channel_oil->installed) if (!up->channel_oil->installed)
pim_mroute_add(up->channel_oil, pim_mroute_add(up->channel_oil,
__PRETTY_FUNCTION__); __PRETTY_FUNCTION__);
@ -487,7 +489,7 @@ static int pim_mroute_msg_wrvifwhole(int fd, struct interface *ifp,
} }
pim_upstream_keep_alive_timer_start( pim_upstream_keep_alive_timer_start(
up, qpim_keep_alive_time); up, qpim_keep_alive_time);
pim_upstream_inherited_olist(up); pim_upstream_inherited_olist(pim_ifp->pim, up);
pim_mroute_msg_wholepkt(fd, ifp, buf); pim_mroute_msg_wholepkt(fd, ifp, buf);
} }
return 0; return 0;
@ -512,7 +514,7 @@ static int pim_mroute_msg_wrvifwhole(int fd, struct interface *ifp,
up->channel_oil = oil; up->channel_oil = oil;
up->channel_oil->cc.pktcnt++; up->channel_oil->cc.pktcnt++;
pim_register_join(up); pim_register_join(up);
pim_upstream_inherited_olist(up); pim_upstream_inherited_olist(pim_ifp->pim, up);
// Send the packet to the RP // Send the packet to the RP
pim_mroute_msg_wholepkt(fd, ifp, buf); pim_mroute_msg_wholepkt(fd, ifp, buf);

View File

@ -121,7 +121,7 @@ static void pim_msdp_sa_upstream_del(struct pim_msdp_sa *sa)
if (PIM_UPSTREAM_FLAG_TEST_SRC_MSDP(up->flags)) { if (PIM_UPSTREAM_FLAG_TEST_SRC_MSDP(up->flags)) {
PIM_UPSTREAM_FLAG_UNSET_SRC_MSDP(up->flags); PIM_UPSTREAM_FLAG_UNSET_SRC_MSDP(up->flags);
sa->flags |= PIM_MSDP_SAF_UP_DEL_IN_PROG; sa->flags |= PIM_MSDP_SAF_UP_DEL_IN_PROG;
pim_upstream_del(up, __PRETTY_FUNCTION__); pim_upstream_del(pimg, up, __PRETTY_FUNCTION__);
sa->flags &= ~PIM_MSDP_SAF_UP_DEL_IN_PROG; sa->flags &= ~PIM_MSDP_SAF_UP_DEL_IN_PROG;
} }
@ -149,7 +149,7 @@ static bool pim_msdp_sa_upstream_add_ok(struct pim_msdp_sa *sa,
memset(&sg, 0, sizeof(sg)); memset(&sg, 0, sizeof(sg));
sg.grp = sa->sg.grp; sg.grp = sa->sg.grp;
xg_up = pim_upstream_find(&sg); xg_up = pim_upstream_find(pimg, &sg);
} }
if (!xg_up || (xg_up->join_state != PIM_UPSTREAM_JOINED)) { if (!xg_up || (xg_up->join_state != PIM_UPSTREAM_JOINED)) {
/* join desired will be true for such (*, G) entries so we will /* join desired will be true for such (*, G) entries so we will
@ -186,7 +186,7 @@ static void pim_msdp_sa_upstream_update(struct pim_msdp_sa *sa,
return; return;
} }
up = pim_upstream_find(&sa->sg); up = pim_upstream_find(pimg, &sa->sg);
if (up && (PIM_UPSTREAM_FLAG_TEST_SRC_MSDP(up->flags))) { if (up && (PIM_UPSTREAM_FLAG_TEST_SRC_MSDP(up->flags))) {
/* somehow we lost track of the upstream ptr? best log it */ /* somehow we lost track of the upstream ptr? best log it */
sa->up = up; sa->up = up;
@ -206,7 +206,7 @@ static void pim_msdp_sa_upstream_update(struct pim_msdp_sa *sa,
sa->up = up; sa->up = up;
if (up) { if (up) {
/* update inherited oil */ /* update inherited oil */
pim_upstream_inherited_olist(up); pim_upstream_inherited_olist(pimg, up);
/* should we also start the kat in parallel? we will need it /* should we also start the kat in parallel? we will need it
* when the * when the
* SA ages out */ * SA ages out */
@ -555,7 +555,7 @@ static void pim_msdp_sa_local_setup(void)
struct pim_upstream *up; struct pim_upstream *up;
struct listnode *up_node; struct listnode *up_node;
for (ALL_LIST_ELEMENTS_RO(pim_upstream_list, up_node, up)) { for (ALL_LIST_ELEMENTS_RO(pimg->upstream_list, up_node, up)) {
pim_msdp_sa_local_update(up); pim_msdp_sa_local_update(up);
} }
} }

View File

@ -545,7 +545,7 @@ pim_neighbor_add(struct interface *ifp, struct in_addr source_addr,
else else
pim_hello_restart_triggered(neigh->interface); pim_hello_restart_triggered(neigh->interface);
pim_upstream_find_new_rpf(); pim_upstream_find_new_rpf(pim_ifp->pim);
/* RNH can send nexthop update prior to PIM neibhor UP /* RNH can send nexthop update prior to PIM neibhor UP
in that case nexthop cache would not consider this neighbor in that case nexthop cache would not consider this neighbor

View File

@ -389,7 +389,7 @@ static int pim_update_upstream_nh(struct pim_instance *pim,
*/ */
if (up->channel_oil if (up->channel_oil
&& up->channel_oil->oil_inherited_rescan) { && up->channel_oil->oil_inherited_rescan) {
pim_upstream_inherited_olist_decide(up); pim_upstream_inherited_olist_decide(pim, up);
up->channel_oil->oil_inherited_rescan = 0; up->channel_oil->oil_inherited_rescan = 0;
} }
@ -431,7 +431,7 @@ static int pim_update_upstream_nh(struct pim_instance *pim,
/* FIXME can join_desired actually be changed by /* FIXME can join_desired actually be changed by
pim_rpf_update() pim_rpf_update()
returning PIM_RPF_CHANGED ? */ returning PIM_RPF_CHANGED ? */
pim_upstream_update_join_desired(up); pim_upstream_update_join_desired(pim, up);
} /* PIM_RPF_CHANGED */ } /* PIM_RPF_CHANGED */

View File

@ -165,7 +165,7 @@ struct channel_oil *pim_channel_oil_add(struct prefix_sg *sg,
c_oil->oil.mfcc_parent = input_vif_index; c_oil->oil.mfcc_parent = input_vif_index;
++c_oil->oil_ref_count; ++c_oil->oil_ref_count;
c_oil->up = pim_upstream_find( c_oil->up = pim_upstream_find(
sg); // channel might be present prior to upstream pimg, sg); // channel might be present prior to upstream
return c_oil; return c_oil;
} }
@ -191,7 +191,7 @@ struct channel_oil *pim_channel_oil_add(struct prefix_sg *sg,
c_oil->oil.mfcc_parent = input_vif_index; c_oil->oil.mfcc_parent = input_vif_index;
c_oil->oil_ref_count = 1; c_oil->oil_ref_count = 1;
c_oil->installed = 0; c_oil->installed = 0;
c_oil->up = pim_upstream_find(sg); c_oil->up = pim_upstream_find(pimg, sg);
listnode_add_sort(pim_channel_oil_list, c_oil); listnode_add_sort(pim_channel_oil_list, c_oil);

View File

@ -123,7 +123,7 @@ int pim_register_stop_recv(uint8_t *buf, int buf_size)
pim_parse_addr_ucast(&source, buf, buf_size); pim_parse_addr_ucast(&source, buf, buf_size);
sg.src = source.u.prefix4; sg.src = source.u.prefix4;
upstream = pim_upstream_find(&sg); upstream = pim_upstream_find(pimg, &sg);
if (!upstream) { if (!upstream) {
return 0; return 0;
} }
@ -357,7 +357,8 @@ int pim_register_recv(struct interface *ifp, struct in_addr dest_addr,
} }
} }
struct pim_upstream *upstream = pim_upstream_find(&sg); struct pim_upstream *upstream =
pim_upstream_find(pim_ifp->pim, &sg);
/* /*
* If we don't have a place to send ignore the packet * If we don't have a place to send ignore the packet
*/ */
@ -375,7 +376,8 @@ int pim_register_recv(struct interface *ifp, struct in_addr dest_addr,
if ((upstream->sptbit == PIM_UPSTREAM_SPTBIT_TRUE) if ((upstream->sptbit == PIM_UPSTREAM_SPTBIT_TRUE)
|| ((SwitchToSptDesired(&sg)) || ((SwitchToSptDesired(&sg))
&& pim_upstream_inherited_olist(upstream) == 0)) { && pim_upstream_inherited_olist(pim_ifp->pim, upstream)
== 0)) {
// pim_scan_individual_oil (upstream->channel_oil); // pim_scan_individual_oil (upstream->channel_oil);
pim_register_stop_send(ifp, &sg, dest_addr, src_addr); pim_register_stop_send(ifp, &sg, dest_addr, src_addr);
sentRegisterStop = 1; sentRegisterStop = 1;

View File

@ -263,7 +263,7 @@ enum pim_rpf_result pim_rpf_update(struct pim_upstream *up, struct pim_rpf *old,
rpf->source_nexthop.mrib_route_metric); rpf->source_nexthop.mrib_route_metric);
} }
pim_upstream_update_join_desired(up); pim_upstream_update_join_desired(pimg, up);
pim_upstream_update_could_assert(up); pim_upstream_update_could_assert(up);
pim_upstream_update_my_assert_metric(up); pim_upstream_update_my_assert_metric(up);
} }

View File

@ -47,7 +47,7 @@ static void pim_ssm_range_reevaluate(void)
* will * will
* disappear in time for SSM groups. * disappear in time for SSM groups.
*/ */
pim_upstream_register_reevaluate(); pim_upstream_register_reevaluate(pimg);
igmp_source_forward_reevaluate_all(); igmp_source_forward_reevaluate_all();
} }

View File

@ -54,10 +54,6 @@
#include "pim_nht.h" #include "pim_nht.h"
#include "pim_ssm.h" #include "pim_ssm.h"
struct hash *pim_upstream_hash = NULL;
struct list *pim_upstream_list = NULL;
struct timer_wheel *pim_upstream_sg_wheel = NULL;
static void join_timer_stop(struct pim_upstream *up); static void join_timer_stop(struct pim_upstream *up);
static void static void
pim_upstream_update_assert_tracking_desired(struct pim_upstream *up); pim_upstream_update_assert_tracking_desired(struct pim_upstream *up);
@ -67,7 +63,8 @@ pim_upstream_update_assert_tracking_desired(struct pim_upstream *up);
* remove the parent pointer from * remove the parent pointer from
* those pointing at us * those pointing at us
*/ */
static void pim_upstream_remove_children(struct pim_upstream *up) static void pim_upstream_remove_children(struct pim_instance *pim,
struct pim_upstream *up)
{ {
struct pim_upstream *child; struct pim_upstream *child;
@ -79,7 +76,8 @@ static void pim_upstream_remove_children(struct pim_upstream *up)
listnode_delete(up->sources, child); listnode_delete(up->sources, child);
if (PIM_UPSTREAM_FLAG_TEST_SRC_LHR(child->flags)) { if (PIM_UPSTREAM_FLAG_TEST_SRC_LHR(child->flags)) {
PIM_UPSTREAM_FLAG_UNSET_SRC_LHR(child->flags); PIM_UPSTREAM_FLAG_UNSET_SRC_LHR(child->flags);
child = pim_upstream_del(child, __PRETTY_FUNCTION__); child = pim_upstream_del(pim, child,
__PRETTY_FUNCTION__);
} }
if (child) if (child)
child->parent = NULL; child->parent = NULL;
@ -93,7 +91,8 @@ static void pim_upstream_remove_children(struct pim_upstream *up)
* Find the children that would point * Find the children that would point
* at us. * at us.
*/ */
static void pim_upstream_find_new_children(struct pim_upstream *up) static void pim_upstream_find_new_children(struct pim_instance *pim,
struct pim_upstream *up)
{ {
struct pim_upstream *child; struct pim_upstream *child;
struct listnode *ch_node; struct listnode *ch_node;
@ -106,7 +105,7 @@ static void pim_upstream_find_new_children(struct pim_upstream *up)
&& (up->sg.grp.s_addr == INADDR_ANY)) && (up->sg.grp.s_addr == INADDR_ANY))
return; return;
for (ALL_LIST_ELEMENTS_RO(pim_upstream_list, ch_node, child)) { for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, ch_node, child)) {
if ((up->sg.grp.s_addr != INADDR_ANY) if ((up->sg.grp.s_addr != INADDR_ANY)
&& (child->sg.grp.s_addr == up->sg.grp.s_addr) && (child->sg.grp.s_addr == up->sg.grp.s_addr)
&& (child != up)) { && (child != up)) {
@ -121,7 +120,8 @@ static void pim_upstream_find_new_children(struct pim_upstream *up)
* If we have a (S,G), find the (*,G) * If we have a (S,G), find the (*,G)
* If we have a (*,G), find the (*,*) * If we have a (*,G), find the (*,*)
*/ */
static struct pim_upstream *pim_upstream_find_parent(struct pim_upstream *child) static struct pim_upstream *pim_upstream_find_parent(struct pim_instance *pim,
struct pim_upstream *child)
{ {
struct prefix_sg any = child->sg; struct prefix_sg any = child->sg;
struct pim_upstream *up = NULL; struct pim_upstream *up = NULL;
@ -130,7 +130,7 @@ static struct pim_upstream *pim_upstream_find_parent(struct pim_upstream *child)
if ((child->sg.src.s_addr != INADDR_ANY) if ((child->sg.src.s_addr != INADDR_ANY)
&& (child->sg.grp.s_addr != INADDR_ANY)) { && (child->sg.grp.s_addr != INADDR_ANY)) {
any.src.s_addr = INADDR_ANY; any.src.s_addr = INADDR_ANY;
up = pim_upstream_find(&any); up = pim_upstream_find(pim, &any);
if (up) if (up)
listnode_add(up->sources, child); listnode_add(up->sources, child);
@ -158,7 +158,8 @@ static void upstream_channel_oil_detach(struct pim_upstream *up)
} }
} }
struct pim_upstream *pim_upstream_del(struct pim_upstream *up, const char *name) struct pim_upstream *pim_upstream_del(struct pim_instance *pim,
struct pim_upstream *up, const char *name)
{ {
bool notify_msdp = false; bool notify_msdp = false;
struct prefix nht_p; struct prefix nht_p;
@ -194,11 +195,11 @@ struct pim_upstream *pim_upstream_del(struct pim_upstream *up, const char *name)
up->rpf.source_nexthop.interface = NULL; up->rpf.source_nexthop.interface = NULL;
if (up->sg.src.s_addr != INADDR_ANY) { if (up->sg.src.s_addr != INADDR_ANY) {
wheel_remove_item(pim_upstream_sg_wheel, up); wheel_remove_item(pim->upstream_sg_wheel, up);
notify_msdp = true; notify_msdp = true;
} }
pim_upstream_remove_children(up); pim_upstream_remove_children(pim, up);
if (up->sources) if (up->sources)
list_delete(up->sources); list_delete(up->sources);
up->sources = NULL; up->sources = NULL;
@ -217,8 +218,8 @@ struct pim_upstream *pim_upstream_del(struct pim_upstream *up, const char *name)
listnode_delete(up->parent->sources, up); listnode_delete(up->parent->sources, up);
up->parent = NULL; up->parent = NULL;
listnode_delete(pim_upstream_list, up); listnode_delete(pim->upstream_list, up);
hash_release(pim_upstream_hash, up); hash_release(pim->upstream_hash, up);
if (notify_msdp) { if (notify_msdp) {
pim_msdp_up_del(&up->sg); pim_msdp_up_del(&up->sg);
@ -234,7 +235,7 @@ struct pim_upstream *pim_upstream_del(struct pim_upstream *up, const char *name)
zlog_debug("%s: Deregister upstream %s addr %s with Zebra NHT", zlog_debug("%s: Deregister upstream %s addr %s with Zebra NHT",
__PRETTY_FUNCTION__, up->sg_str, buf); __PRETTY_FUNCTION__, up->sg_str, buf);
} }
pim_delete_tracked_nexthop(pimg, &nht_p, up, NULL); pim_delete_tracked_nexthop(pim, &nht_p, up, NULL);
pim_upstream_free(up); pim_upstream_free(up);
@ -469,12 +470,12 @@ static int pim_upstream_could_register(struct pim_upstream *up)
/* Source registration is supressed for SSM groups. When the SSM range changes /* Source registration is supressed for SSM groups. When the SSM range changes
* we re-revaluate register setup for existing upstream entries */ * we re-revaluate register setup for existing upstream entries */
void pim_upstream_register_reevaluate(void) void pim_upstream_register_reevaluate(struct pim_instance *pim)
{ {
struct listnode *upnode; struct listnode *upnode;
struct pim_upstream *up; struct pim_upstream *up;
for (ALL_LIST_ELEMENTS_RO(pim_upstream_list, upnode, up)) { for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, upnode, up)) {
/* If FHR is set CouldRegister is True. Also check if the flow /* If FHR is set CouldRegister is True. Also check if the flow
* is actually active; if it is not kat setup will trigger * is actually active; if it is not kat setup will trigger
* source * source
@ -491,7 +492,7 @@ void pim_upstream_register_reevaluate(void)
up->sg_str); up->sg_str);
/* remove regiface from the OIL if it is there*/ /* remove regiface from the OIL if it is there*/
pim_channel_del_oif(up->channel_oil, pim_channel_del_oif(up->channel_oil,
pimg->regiface, pim->regiface,
PIM_OIF_FLAG_PROTO_PIM); PIM_OIF_FLAG_PROTO_PIM);
up->reg_state = PIM_REG_NOINFO; up->reg_state = PIM_REG_NOINFO;
} }
@ -503,7 +504,7 @@ void pim_upstream_register_reevaluate(void)
"Register %s as G is now ASM", "Register %s as G is now ASM",
up->sg_str); up->sg_str);
pim_channel_add_oif(up->channel_oil, pim_channel_add_oif(up->channel_oil,
pimg->regiface, pim->regiface,
PIM_OIF_FLAG_PROTO_PIM); PIM_OIF_FLAG_PROTO_PIM);
up->reg_state = PIM_REG_JOIN; up->reg_state = PIM_REG_JOIN;
} }
@ -603,6 +604,7 @@ pim_upstream_new(struct prefix_sg *sg, struct interface *incoming, int flags)
{ {
enum pim_rpf_result rpf_result; enum pim_rpf_result rpf_result;
struct pim_interface *pim_ifp; struct pim_interface *pim_ifp;
struct pim_instance *pim;
struct pim_upstream *up; struct pim_upstream *up;
up = XCALLOC(MTYPE_PIM_UPSTREAM, sizeof(*up)); up = XCALLOC(MTYPE_PIM_UPSTREAM, sizeof(*up));
@ -612,27 +614,29 @@ pim_upstream_new(struct prefix_sg *sg, struct interface *incoming, int flags)
return NULL; return NULL;
} }
pim_ifp = incoming->info;
pim = pim_ifp->pim;
up->sg = *sg; up->sg = *sg;
pim_str_sg_set(sg, up->sg_str); pim_str_sg_set(sg, up->sg_str);
up = hash_get(pim_upstream_hash, up, hash_alloc_intern); up = hash_get(pim->upstream_hash, up, hash_alloc_intern);
if (!pim_rp_set_upstream_addr(&up->upstream_addr, sg->src, sg->grp)) { if (!pim_rp_set_upstream_addr(&up->upstream_addr, sg->src, sg->grp)) {
if (PIM_DEBUG_TRACE) if (PIM_DEBUG_TRACE)
zlog_debug("%s: Received a (*,G) with no RP configured", zlog_debug("%s: Received a (*,G) with no RP configured",
__PRETTY_FUNCTION__); __PRETTY_FUNCTION__);
hash_release(pim_upstream_hash, up); hash_release(pim->upstream_hash, up);
XFREE(MTYPE_PIM_UPSTREAM, up); XFREE(MTYPE_PIM_UPSTREAM, up);
return NULL; return NULL;
} }
up->parent = pim_upstream_find_parent(up); up->parent = pim_upstream_find_parent(pim, up);
if (up->sg.src.s_addr == INADDR_ANY) { if (up->sg.src.s_addr == INADDR_ANY) {
up->sources = list_new(); up->sources = list_new();
up->sources->cmp = pim_upstream_compare; up->sources->cmp = pim_upstream_compare;
} else } else
up->sources = NULL; up->sources = NULL;
pim_upstream_find_new_children(up); pim_upstream_find_new_children(pim, up);
up->flags = flags; up->flags = flags;
up->ref_count = 1; up->ref_count = 1;
up->t_join_timer = NULL; up->t_join_timer = NULL;
@ -660,7 +664,7 @@ pim_upstream_new(struct prefix_sg *sg, struct interface *incoming, int flags)
up->ifchannels->cmp = (int (*)(void *, void *))pim_ifchannel_compare; up->ifchannels->cmp = (int (*)(void *, void *))pim_ifchannel_compare;
if (up->sg.src.s_addr != INADDR_ANY) if (up->sg.src.s_addr != INADDR_ANY)
wheel_add_item(pim_upstream_sg_wheel, up); wheel_add_item(pim->upstream_sg_wheel, up);
rpf_result = pim_rpf_update(up, NULL, 1); rpf_result = pim_rpf_update(up, NULL, 1);
if (rpf_result == PIM_RPF_FAILURE) { if (rpf_result == PIM_RPF_FAILURE) {
@ -671,7 +675,6 @@ pim_upstream_new(struct prefix_sg *sg, struct interface *incoming, int flags)
"%s: Attempting to create upstream(%s), Unable to RPF for source", "%s: Attempting to create upstream(%s), Unable to RPF for source",
__PRETTY_FUNCTION__, up->sg_str); __PRETTY_FUNCTION__, up->sg_str);
pim_ifp = incoming->info;
nht_p.family = AF_INET; nht_p.family = AF_INET;
nht_p.prefixlen = IPV4_MAX_BITLEN; nht_p.prefixlen = IPV4_MAX_BITLEN;
nht_p.u.prefix4 = up->upstream_addr; nht_p.u.prefix4 = up->upstream_addr;
@ -683,13 +686,13 @@ pim_upstream_new(struct prefix_sg *sg, struct interface *incoming, int flags)
} }
if (up->sg.src.s_addr != INADDR_ANY) if (up->sg.src.s_addr != INADDR_ANY)
wheel_remove_item(pim_upstream_sg_wheel, up); wheel_remove_item(pim->upstream_sg_wheel, up);
pim_upstream_remove_children(up); pim_upstream_remove_children(pim, up);
if (up->sources) if (up->sources)
list_delete(up->sources); list_delete(up->sources);
hash_release(pim_upstream_hash, up); hash_release(pim->upstream_hash, up);
XFREE(MTYPE_PIM_UPSTREAM, up); XFREE(MTYPE_PIM_UPSTREAM, up);
return NULL; return NULL;
} }
@ -700,7 +703,7 @@ pim_upstream_new(struct prefix_sg *sg, struct interface *incoming, int flags)
up->channel_oil = pim_channel_oil_add( up->channel_oil = pim_channel_oil_add(
&up->sg, pim_ifp->mroute_vif_index); &up->sg, pim_ifp->mroute_vif_index);
} }
listnode_add_sort(pim_upstream_list, up); listnode_add_sort(pim->upstream_list, up);
if (PIM_DEBUG_TRACE) { if (PIM_DEBUG_TRACE) {
zlog_debug( zlog_debug(
@ -712,13 +715,14 @@ pim_upstream_new(struct prefix_sg *sg, struct interface *incoming, int flags)
return up; return up;
} }
struct pim_upstream *pim_upstream_find(struct prefix_sg *sg) struct pim_upstream *pim_upstream_find(struct pim_instance *pim,
struct prefix_sg *sg)
{ {
struct pim_upstream lookup; struct pim_upstream lookup;
struct pim_upstream *up = NULL; struct pim_upstream *up = NULL;
lookup.sg = *sg; lookup.sg = *sg;
up = hash_lookup(pim_upstream_hash, &lookup); up = hash_lookup(pim->upstream_hash, &lookup);
return up; return up;
} }
@ -727,8 +731,11 @@ struct pim_upstream *pim_upstream_find_or_add(struct prefix_sg *sg,
int flags, const char *name) int flags, const char *name)
{ {
struct pim_upstream *up; struct pim_upstream *up;
struct pim_interface *pim_ifp;
up = pim_upstream_find(sg); pim_ifp = incoming->info;
up = pim_upstream_find(pim_ifp->pim, sg);
if (up) { if (up) {
if (!(up->flags & flags)) { if (!(up->flags & flags)) {
@ -761,8 +768,11 @@ struct pim_upstream *pim_upstream_add(struct prefix_sg *sg,
const char *name) const char *name)
{ {
struct pim_upstream *up = NULL; struct pim_upstream *up = NULL;
struct pim_interface *pim_ifp;
int found = 0; int found = 0;
up = pim_upstream_find(sg);
pim_ifp = incoming->info;
up = pim_upstream_find(pim_ifp->pim, sg);
if (up) { if (up) {
pim_upstream_ref(up, flags, name); pim_upstream_ref(up, flags, name);
found = 1; found = 1;
@ -843,7 +853,8 @@ int pim_upstream_evaluate_join_desired_interface(struct pim_upstream *up,
See also pim_upstream_update_join_desired() below. See also pim_upstream_update_join_desired() below.
*/ */
int pim_upstream_evaluate_join_desired(struct pim_upstream *up) int pim_upstream_evaluate_join_desired(struct pim_instance *pim,
struct pim_upstream *up)
{ {
struct interface *ifp; struct interface *ifp;
struct listnode *node; struct listnode *node;
@ -851,7 +862,7 @@ int pim_upstream_evaluate_join_desired(struct pim_upstream *up)
struct pim_upstream *starup = up->parent; struct pim_upstream *starup = up->parent;
int ret = 0; int ret = 0;
for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pimg->vrf_id), node, ifp)) { for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), node, ifp)) {
if (!ifp->info) if (!ifp->info)
continue; continue;
@ -875,14 +886,15 @@ int pim_upstream_evaluate_join_desired(struct pim_upstream *up)
/* /*
See also pim_upstream_evaluate_join_desired() above. See also pim_upstream_evaluate_join_desired() above.
*/ */
void pim_upstream_update_join_desired(struct pim_upstream *up) void pim_upstream_update_join_desired(struct pim_instance *pim,
struct pim_upstream *up)
{ {
int was_join_desired; /* boolean */ int was_join_desired; /* boolean */
int is_join_desired; /* boolean */ int is_join_desired; /* boolean */
was_join_desired = PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(up->flags); was_join_desired = PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(up->flags);
is_join_desired = pim_upstream_evaluate_join_desired(up); is_join_desired = pim_upstream_evaluate_join_desired(pim, up);
if (is_join_desired) if (is_join_desired)
PIM_UPSTREAM_FLAG_SET_DR_JOIN_DESIRED(up->flags); PIM_UPSTREAM_FLAG_SET_DR_JOIN_DESIRED(up->flags);
else else
@ -910,7 +922,8 @@ void pim_upstream_update_join_desired(struct pim_upstream *up)
Join Timer is set to expire in more than t_override seconds, reset Join Timer is set to expire in more than t_override seconds, reset
it so that it expires after t_override seconds. it so that it expires after t_override seconds.
*/ */
void pim_upstream_rpf_genid_changed(struct in_addr neigh_addr) void pim_upstream_rpf_genid_changed(struct pim_instance *pim,
struct in_addr neigh_addr)
{ {
struct listnode *up_node; struct listnode *up_node;
struct listnode *up_nextnode; struct listnode *up_nextnode;
@ -919,7 +932,7 @@ void pim_upstream_rpf_genid_changed(struct in_addr neigh_addr)
/* /*
* Scan all (S,G) upstreams searching for RPF'(S,G)=neigh_addr * Scan all (S,G) upstreams searching for RPF'(S,G)=neigh_addr
*/ */
for (ALL_LIST_ELEMENTS(pim_upstream_list, up_node, up_nextnode, up)) { for (ALL_LIST_ELEMENTS(pim->upstream_list, up_node, up_nextnode, up)) {
if (PIM_DEBUG_TRACE) { if (PIM_DEBUG_TRACE) {
char neigh_str[INET_ADDRSTRLEN]; char neigh_str[INET_ADDRSTRLEN];
@ -1021,7 +1034,8 @@ static void pim_upstream_update_assert_tracking_desired(struct pim_upstream *up)
/* When kat is stopped CouldRegister goes to false so we need to /* When kat is stopped CouldRegister goes to false so we need to
* transition the (S, G) on FHR to NI state and remove reg tunnel * transition the (S, G) on FHR to NI state and remove reg tunnel
* from the OIL */ * from the OIL */
static void pim_upstream_fhr_kat_expiry(struct pim_upstream *up) static void pim_upstream_fhr_kat_expiry(struct pim_instance *pim,
struct pim_upstream *up)
{ {
if (!PIM_UPSTREAM_FLAG_TEST_FHR(up->flags)) if (!PIM_UPSTREAM_FLAG_TEST_FHR(up->flags))
return; return;
@ -1033,7 +1047,7 @@ static void pim_upstream_fhr_kat_expiry(struct pim_upstream *up)
/* stop reg-stop timer */ /* stop reg-stop timer */
THREAD_OFF(up->t_rs_timer); THREAD_OFF(up->t_rs_timer);
/* remove regiface from the OIL if it is there*/ /* remove regiface from the OIL if it is there*/
pim_channel_del_oif(up->channel_oil, pimg->regiface, pim_channel_del_oif(up->channel_oil, pim->regiface,
PIM_OIF_FLAG_PROTO_PIM); PIM_OIF_FLAG_PROTO_PIM);
/* clear the register state */ /* clear the register state */
up->reg_state = PIM_REG_NOINFO; up->reg_state = PIM_REG_NOINFO;
@ -1082,15 +1096,15 @@ static int pim_upstream_keep_alive_timer(struct thread *t)
/* if entry was created because of activity we need to deref it */ /* if entry was created because of activity we need to deref it */
if (PIM_UPSTREAM_FLAG_TEST_SRC_STREAM(up->flags)) { if (PIM_UPSTREAM_FLAG_TEST_SRC_STREAM(up->flags)) {
pim_upstream_fhr_kat_expiry(up); pim_upstream_fhr_kat_expiry(pimg, up);
if (PIM_DEBUG_TRACE) if (PIM_DEBUG_TRACE)
zlog_debug("kat expired on %s; remove stream reference", zlog_debug("kat expired on %s; remove stream reference",
up->sg_str); up->sg_str);
PIM_UPSTREAM_FLAG_UNSET_SRC_STREAM(up->flags); PIM_UPSTREAM_FLAG_UNSET_SRC_STREAM(up->flags);
pim_upstream_del(up, __PRETTY_FUNCTION__); pim_upstream_del(pimg, up, __PRETTY_FUNCTION__);
} else if (PIM_UPSTREAM_FLAG_TEST_SRC_LHR(up->flags)) { } else if (PIM_UPSTREAM_FLAG_TEST_SRC_LHR(up->flags)) {
PIM_UPSTREAM_FLAG_UNSET_SRC_LHR(up->flags); PIM_UPSTREAM_FLAG_UNSET_SRC_LHR(up->flags);
pim_upstream_del(up, __PRETTY_FUNCTION__); pim_upstream_del(pimg, up, __PRETTY_FUNCTION__);
} }
return 0; return 0;
@ -1381,7 +1395,8 @@ void pim_upstream_start_register_stop_timer(struct pim_upstream *up,
&up->t_rs_timer); &up->t_rs_timer);
} }
int pim_upstream_inherited_olist_decide(struct pim_upstream *up) int pim_upstream_inherited_olist_decide(struct pim_instance *pim,
struct pim_upstream *up)
{ {
struct interface *ifp; struct interface *ifp;
struct pim_interface *pim_ifp = NULL; struct pim_interface *pim_ifp = NULL;
@ -1401,7 +1416,7 @@ int pim_upstream_inherited_olist_decide(struct pim_upstream *up)
up->channel_oil = up->channel_oil =
pim_channel_oil_add(&up->sg, pim_ifp->mroute_vif_index); pim_channel_oil_add(&up->sg, pim_ifp->mroute_vif_index);
for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pimg->vrf_id), node, ifp)) { for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), node, ifp)) {
if (!ifp->info) if (!ifp->info)
continue; continue;
@ -1446,9 +1461,10 @@ int pim_upstream_inherited_olist_decide(struct pim_upstream *up)
* return 1 if there are any output interfaces * return 1 if there are any output interfaces
* return 0 if there are not any output interfaces * return 0 if there are not any output interfaces
*/ */
int pim_upstream_inherited_olist(struct pim_upstream *up) int pim_upstream_inherited_olist(struct pim_instance *pim,
struct pim_upstream *up)
{ {
int output_intf = pim_upstream_inherited_olist_decide(up); int output_intf = pim_upstream_inherited_olist_decide(pim, up);
/* /*
* If we have output_intf switch state to Join and work like normal * If we have output_intf switch state to Join and work like normal
@ -1475,7 +1491,7 @@ int pim_upstream_empty_inherited_olist(struct pim_upstream *up)
* set and see if the new neighbor allows * set and see if the new neighbor allows
* the join to be sent * the join to be sent
*/ */
void pim_upstream_find_new_rpf(void) void pim_upstream_find_new_rpf(struct pim_instance *pim)
{ {
struct listnode *up_node; struct listnode *up_node;
struct listnode *up_nextnode; struct listnode *up_nextnode;
@ -1484,7 +1500,7 @@ void pim_upstream_find_new_rpf(void)
/* /*
* Scan all (S,G) upstreams searching for RPF'(S,G)=neigh_addr * Scan all (S,G) upstreams searching for RPF'(S,G)=neigh_addr
*/ */
for (ALL_LIST_ELEMENTS(pim_upstream_list, up_node, up_nextnode, up)) { for (ALL_LIST_ELEMENTS(pim->upstream_list, up_node, up_nextnode, up)) {
if (pim_rpf_addr_is_inaddr_any(&up->rpf)) { if (pim_rpf_addr_is_inaddr_any(&up->rpf)) {
if (PIM_DEBUG_TRACE) if (PIM_DEBUG_TRACE)
zlog_debug( zlog_debug(
@ -1502,15 +1518,15 @@ static unsigned int pim_upstream_hash_key(void *arg)
return jhash_2words(up->sg.src.s_addr, up->sg.grp.s_addr, 0); return jhash_2words(up->sg.src.s_addr, up->sg.grp.s_addr, 0);
} }
void pim_upstream_terminate(void) void pim_upstream_terminate(struct pim_instance *pim)
{ {
if (pim_upstream_list) if (pim->upstream_list)
list_delete(pim_upstream_list); list_delete(pim->upstream_list);
pim_upstream_list = NULL; pim->upstream_list = NULL;
if (pim_upstream_hash) if (pim->upstream_hash)
hash_free(pim_upstream_hash); hash_free(pim->upstream_hash);
pim_upstream_hash = NULL; pim->upstream_hash = NULL;
} }
static int pim_upstream_equal(const void *arg1, const void *arg2) static int pim_upstream_equal(const void *arg1, const void *arg2)
@ -1596,7 +1612,7 @@ static void pim_upstream_sg_running(void *arg)
zlog_debug( zlog_debug(
"%s: Handling unscanned inherited_olist for %s", "%s: Handling unscanned inherited_olist for %s",
__PRETTY_FUNCTION__, up->sg_str); __PRETTY_FUNCTION__, up->sg_str);
pim_upstream_inherited_olist_decide(up); pim_upstream_inherited_olist_decide(pimg, up);
up->channel_oil->oil_inherited_rescan = 0; up->channel_oil->oil_inherited_rescan = 0;
} }
pim_mroute_update_counters(up->channel_oil); pim_mroute_update_counters(up->channel_oil);
@ -1639,29 +1655,30 @@ static void pim_upstream_sg_running(void *arg)
return; return;
} }
void pim_upstream_add_lhr_star_pimreg(void) void pim_upstream_add_lhr_star_pimreg(struct pim_instance *pim)
{ {
struct pim_upstream *up; struct pim_upstream *up;
struct listnode *node; struct listnode *node;
for (ALL_LIST_ELEMENTS_RO(pim_upstream_list, node, up)) { for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, node, up)) {
if (up->sg.src.s_addr != INADDR_ANY) if (up->sg.src.s_addr != INADDR_ANY)
continue; continue;
if (!PIM_UPSTREAM_FLAG_TEST_SRC_IGMP(up->flags)) if (!PIM_UPSTREAM_FLAG_TEST_SRC_IGMP(up->flags))
continue; continue;
pim_channel_add_oif(up->channel_oil, pimg->regiface, pim_channel_add_oif(up->channel_oil, pim->regiface,
PIM_OIF_FLAG_PROTO_IGMP); PIM_OIF_FLAG_PROTO_IGMP);
} }
} }
void pim_upstream_spt_prefix_list_update(struct prefix_list *pl) void pim_upstream_spt_prefix_list_update(struct pim_instance *pim,
struct prefix_list *pl)
{ {
const char *pname = prefix_list_name(pl); const char *pname = prefix_list_name(pl);
if (pimg->spt.plist && strcmp(pimg->spt.plist, pname) == 0) { if (pim->spt.plist && strcmp(pim->spt.plist, pname) == 0) {
pim_upstream_remove_lhr_star_pimreg(pname); pim_upstream_remove_lhr_star_pimreg(pim, pname);
} }
} }
@ -1677,7 +1694,8 @@ void pim_upstream_spt_prefix_list_update(struct prefix_list *pl)
* the interface * the interface
* *
*/ */
void pim_upstream_remove_lhr_star_pimreg(const char *nlist) void pim_upstream_remove_lhr_star_pimreg(struct pim_instance *pim,
const char *nlist)
{ {
struct pim_upstream *up; struct pim_upstream *up;
struct listnode *node; struct listnode *node;
@ -1690,7 +1708,7 @@ void pim_upstream_remove_lhr_star_pimreg(const char *nlist)
g.family = AF_INET; g.family = AF_INET;
g.prefixlen = IPV4_MAX_PREFIXLEN; g.prefixlen = IPV4_MAX_PREFIXLEN;
for (ALL_LIST_ELEMENTS_RO(pim_upstream_list, node, up)) { for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, node, up)) {
if (up->sg.src.s_addr != INADDR_ANY) if (up->sg.src.s_addr != INADDR_ANY)
continue; continue;
@ -1698,30 +1716,30 @@ void pim_upstream_remove_lhr_star_pimreg(const char *nlist)
continue; continue;
if (!nlist) { if (!nlist) {
pim_channel_del_oif(up->channel_oil, pimg->regiface, pim_channel_del_oif(up->channel_oil, pim->regiface,
PIM_OIF_FLAG_PROTO_IGMP); PIM_OIF_FLAG_PROTO_IGMP);
continue; continue;
} }
g.u.prefix4 = up->sg.grp; g.u.prefix4 = up->sg.grp;
apply_new = prefix_list_apply(np, &g); apply_new = prefix_list_apply(np, &g);
if (apply_new == PREFIX_DENY) if (apply_new == PREFIX_DENY)
pim_channel_add_oif(up->channel_oil, pimg->regiface, pim_channel_add_oif(up->channel_oil, pim->regiface,
PIM_OIF_FLAG_PROTO_IGMP); PIM_OIF_FLAG_PROTO_IGMP);
else else
pim_channel_del_oif(up->channel_oil, pimg->regiface, pim_channel_del_oif(up->channel_oil, pim->regiface,
PIM_OIF_FLAG_PROTO_IGMP); PIM_OIF_FLAG_PROTO_IGMP);
} }
} }
void pim_upstream_init(void) void pim_upstream_init(struct pim_instance *pim)
{ {
pim_upstream_sg_wheel = pim->upstream_sg_wheel =
wheel_init(master, 31000, 100, pim_upstream_hash_key, wheel_init(master, 31000, 100, pim_upstream_hash_key,
pim_upstream_sg_running); pim_upstream_sg_running);
pim_upstream_hash = hash_create_size(8192, pim_upstream_hash_key, pim->upstream_hash = hash_create_size(8192, pim_upstream_hash_key,
pim_upstream_equal, NULL); pim_upstream_equal, NULL);
pim_upstream_list = list_new(); pim->upstream_list = list_new();
pim_upstream_list->del = (void (*)(void *))pim_upstream_free; pim->upstream_list->del = (void (*)(void *))pim_upstream_free;
pim_upstream_list->cmp = pim_upstream_compare; pim->upstream_list->cmp = pim_upstream_compare;
} }

View File

@ -137,11 +137,9 @@ struct pim_upstream {
int64_t state_transition; /* Record current state uptime */ int64_t state_transition; /* Record current state uptime */
}; };
struct list *pim_upstream_list;
struct hash *pim_upstream_hash;
void pim_upstream_free(struct pim_upstream *up); void pim_upstream_free(struct pim_upstream *up);
struct pim_upstream *pim_upstream_find(struct prefix_sg *sg); struct pim_upstream *pim_upstream_find(struct pim_instance *pim,
struct prefix_sg *sg);
struct pim_upstream *pim_upstream_find_or_add(struct prefix_sg *sg, struct pim_upstream *pim_upstream_find_or_add(struct prefix_sg *sg,
struct interface *ifp, int flags, struct interface *ifp, int flags,
const char *name); const char *name);
@ -149,14 +147,17 @@ struct pim_upstream *pim_upstream_add(struct prefix_sg *sg,
struct interface *ifp, int flags, struct interface *ifp, int flags,
const char *name); const char *name);
void pim_upstream_ref(struct pim_upstream *up, int flags, const char *name); void pim_upstream_ref(struct pim_upstream *up, int flags, const char *name);
struct pim_upstream *pim_upstream_del(struct pim_upstream *up, struct pim_upstream *pim_upstream_del(struct pim_instance *pim,
struct pim_upstream *up,
const char *name); const char *name);
int pim_upstream_evaluate_join_desired(struct pim_upstream *up); int pim_upstream_evaluate_join_desired(struct pim_instance *pim,
struct pim_upstream *up);
int pim_upstream_evaluate_join_desired_interface(struct pim_upstream *up, int pim_upstream_evaluate_join_desired_interface(struct pim_upstream *up,
struct pim_ifchannel *ch, struct pim_ifchannel *ch,
struct pim_ifchannel *starch); struct pim_ifchannel *starch);
void pim_upstream_update_join_desired(struct pim_upstream *up); void pim_upstream_update_join_desired(struct pim_instance *pim,
struct pim_upstream *up);
void pim_upstream_join_suppress(struct pim_upstream *up, void pim_upstream_join_suppress(struct pim_upstream *up,
struct in_addr rpf_addr, int holdtime); struct in_addr rpf_addr, int holdtime);
@ -166,7 +167,8 @@ void pim_upstream_join_timer_decrease_to_t_override(const char *debug_label,
void pim_upstream_join_timer_restart(struct pim_upstream *up, void pim_upstream_join_timer_restart(struct pim_upstream *up,
struct pim_rpf *old); struct pim_rpf *old);
void pim_upstream_rpf_genid_changed(struct in_addr neigh_addr); void pim_upstream_rpf_genid_changed(struct pim_instance *pim,
struct in_addr neigh_addr);
void pim_upstream_rpf_interface_changed(struct pim_upstream *up, void pim_upstream_rpf_interface_changed(struct pim_upstream *up,
struct interface *old_rpf_ifp); struct interface *old_rpf_ifp);
@ -195,22 +197,26 @@ const char *pim_upstream_state2str(enum pim_upstream_state join_state);
#define PIM_REG_STATE_STR_LEN 12 #define PIM_REG_STATE_STR_LEN 12
const char *pim_reg_state2str(enum pim_reg_state state, char *state_str); const char *pim_reg_state2str(enum pim_reg_state state, char *state_str);
int pim_upstream_inherited_olist_decide(struct pim_upstream *up); int pim_upstream_inherited_olist_decide(struct pim_instance *pim,
int pim_upstream_inherited_olist(struct pim_upstream *up); struct pim_upstream *up);
int pim_upstream_inherited_olist(struct pim_instance *pim,
struct pim_upstream *up);
int pim_upstream_empty_inherited_olist(struct pim_upstream *up); int pim_upstream_empty_inherited_olist(struct pim_upstream *up);
void pim_upstream_find_new_rpf(void); void pim_upstream_find_new_rpf(struct pim_instance *pim);
void pim_upstream_msdp_reg_timer_start(struct pim_upstream *up); void pim_upstream_msdp_reg_timer_start(struct pim_upstream *up);
void pim_upstream_init(void); void pim_upstream_init(struct pim_instance *pim);
void pim_upstream_terminate(void); void pim_upstream_terminate(struct pim_instance *pim);
void join_timer_start(struct pim_upstream *up); void join_timer_start(struct pim_upstream *up);
int pim_upstream_compare(void *arg1, void *arg2); int pim_upstream_compare(void *arg1, void *arg2);
void pim_upstream_register_reevaluate(void); void pim_upstream_register_reevaluate(struct pim_instance *pim);
void pim_upstream_add_lhr_star_pimreg(void); void pim_upstream_add_lhr_star_pimreg(struct pim_instance *pim);
void pim_upstream_remove_lhr_star_pimreg(const char *nlist); void pim_upstream_remove_lhr_star_pimreg(struct pim_instance *pim,
const char *nlist);
void pim_upstream_spt_prefix_list_update(struct prefix_list *pl); void pim_upstream_spt_prefix_list_update(struct pim_instance *pim,
struct prefix_list *pl);
#endif /* PIM_UPSTREAM_H */ #endif /* PIM_UPSTREAM_H */

View File

@ -292,8 +292,8 @@ static int pim_zebra_if_address_add(int command, struct zclient *zclient,
struct listnode *ifnode; struct listnode *ifnode;
struct interface *ifp; struct interface *ifp;
for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pimg->vrf_id), ifnode, for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim_ifp->pim->vrf_id),
ifp)) { ifnode, ifp)) {
if (!if_is_loopback(ifp) && if_is_operative(ifp)) if (!if_is_loopback(ifp) && if_is_operative(ifp))
pim_if_addr_add_all(ifp); pim_if_addr_add_all(ifp);
} }
@ -357,99 +357,128 @@ static void scan_upstream_rpf_cache()
struct listnode *node; struct listnode *node;
struct pim_upstream *up; struct pim_upstream *up;
struct interface *ifp; struct interface *ifp;
struct vrf *vrf;
struct pim_instance *pim;
for (ALL_LIST_ELEMENTS(pim_upstream_list, up_node, up_nextnode, up)) { RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name)
enum pim_rpf_result rpf_result; {
struct pim_rpf old; pim = vrf->info;
struct prefix nht_p; if (!pim)
nht_p.family = AF_INET;
nht_p.prefixlen = IPV4_MAX_BITLEN;
nht_p.u.prefix4.s_addr = up->upstream_addr.s_addr;
pim_resolve_upstream_nh(pimg, &nht_p);
old.source_nexthop.interface = up->rpf.source_nexthop.interface;
old.source_nexthop.nbr = up->rpf.source_nexthop.nbr;
rpf_result = pim_rpf_update(up, &old, 0);
if (rpf_result == PIM_RPF_FAILURE)
continue; continue;
if (rpf_result == PIM_RPF_CHANGED) { for (ALL_LIST_ELEMENTS(pim->upstream_list, up_node, up_nextnode,
struct pim_neighbor *nbr; up)) {
enum pim_rpf_result rpf_result;
struct pim_rpf old;
struct prefix nht_p;
nbr = pim_neighbor_find(old.source_nexthop.interface, nht_p.family = AF_INET;
old.rpf_addr.u.prefix4); nht_p.prefixlen = IPV4_MAX_BITLEN;
if (nbr) nht_p.u.prefix4.s_addr = up->upstream_addr.s_addr;
pim_jp_agg_remove_group(nbr->upstream_jp_agg, pim_resolve_upstream_nh(pim, &nht_p);
up);
/* old.source_nexthop.interface =
* We have detected a case where we might need to rescan up->rpf.source_nexthop.interface;
* the inherited o_list so do it. old.source_nexthop.nbr = up->rpf.source_nexthop.nbr;
*/ rpf_result = pim_rpf_update(up, &old, 0);
if (up->channel_oil->oil_inherited_rescan) {
pim_upstream_inherited_olist_decide(up);
up->channel_oil->oil_inherited_rescan = 0;
}
if (up->join_state == PIM_UPSTREAM_JOINED) { if (rpf_result == PIM_RPF_FAILURE)
/* continue;
* If we come up real fast we can be here
* where the mroute has not been installed if (rpf_result == PIM_RPF_CHANGED) {
* so install it. struct pim_neighbor *nbr;
*/
if (!up->channel_oil->installed) nbr = pim_neighbor_find(
pim_mroute_add(up->channel_oil, old.source_nexthop.interface,
__PRETTY_FUNCTION__); old.rpf_addr.u.prefix4);
if (nbr)
pim_jp_agg_remove_group(
nbr->upstream_jp_agg, up);
/* /*
* RFC 4601: 4.5.7. Sending (S,G) Join/Prune * We have detected a case where we might need
* Messages * to rescan
* * the inherited o_list so do it.
* Transitions from Joined State
*
* RPF'(S,G) changes not due to an Assert
*
* The upstream (S,G) state machine remains in
* Joined
* state. Send Join(S,G) to the new upstream
* neighbor, which is
* the new value of RPF'(S,G). Send Prune(S,G)
* to the old
* upstream neighbor, which is the old value of
* RPF'(S,G). Set
* the Join Timer (JT) to expire after
* t_periodic seconds.
*/ */
pim_jp_agg_switch_interface(&old, &up->rpf, up); if (up->channel_oil->oil_inherited_rescan) {
pim_upstream_inherited_olist_decide(pim,
up);
up->channel_oil->oil_inherited_rescan =
0;
}
pim_upstream_join_timer_restart(up, &old); if (up->join_state == PIM_UPSTREAM_JOINED) {
} /* up->join_state == PIM_UPSTREAM_JOINED */ /*
* If we come up real fast we can be
* here
* where the mroute has not been
* installed
* so install it.
*/
if (!up->channel_oil->installed)
pim_mroute_add(
up->channel_oil,
__PRETTY_FUNCTION__);
/* FIXME can join_desired actually be changed by /*
pim_rpf_update() * RFC 4601: 4.5.7. Sending (S,G)
returning PIM_RPF_CHANGED ? */ * Join/Prune Messages
pim_upstream_update_join_desired(up); *
* Transitions from Joined State
*
* RPF'(S,G) changes not due to an
* Assert
*
* The upstream (S,G) state machine
* remains in Joined
* state. Send Join(S,G) to the new
* upstream neighbor, which is
* the new value of RPF'(S,G). Send
* Prune(S,G) to the old
* upstream neighbor, which is the old
* value of RPF'(S,G). Set
* the Join Timer (JT) to expire after
* t_periodic seconds.
*/
pim_jp_agg_switch_interface(
&old, &up->rpf, up);
} /* PIM_RPF_CHANGED */ pim_upstream_join_timer_restart(up,
&old);
} /* up->join_state == PIM_UPSTREAM_JOINED */
} /* for (qpim_upstream_list) */ /* FIXME can join_desired actually be changed by
pim_rpf_update()
returning PIM_RPF_CHANGED ? */
pim_upstream_update_join_desired(pim, up);
for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pimg->vrf_id), ifnode, ifp)) } /* PIM_RPF_CHANGED */
if (ifp->info) {
struct pim_interface *pim_ifp = ifp->info;
struct pim_iface_upstream_switch *us;
for (ALL_LIST_ELEMENTS_RO(pim_ifp->upstream_switch_list, } /* for (qpim_upstream_list) */
node, us)) { }
struct pim_rpf rpf;
rpf.source_nexthop.interface = ifp; RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name)
rpf.rpf_addr.u.prefix4 = us->address; {
pim_joinprune_send(&rpf, us->us); pim = vrf->info;
pim_jp_agg_clear_group(us->us); if (!pim)
continue;
for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), ifnode, ifp))
if (ifp->info) {
struct pim_interface *pim_ifp = ifp->info;
struct pim_iface_upstream_switch *us;
for (ALL_LIST_ELEMENTS_RO(
pim_ifp->upstream_switch_list,
node, us)) {
struct pim_rpf rpf;
rpf.source_nexthop.interface = ifp;
rpf.rpf_addr.u.prefix4 = us->address;
pim_joinprune_send(&rpf, us->us);
pim_jp_agg_clear_group(us->us);
}
} }
} }
} }
void pim_scan_individual_oil(struct channel_oil *c_oil, int in_vif_index) void pim_scan_individual_oil(struct channel_oil *c_oil, int in_vif_index)
@ -875,7 +904,7 @@ void igmp_source_forward_start(struct igmp_source *source)
if (pim_find_or_track_nexthop(pimg, &nht_p, NULL, NULL, if (pim_find_or_track_nexthop(pimg, &nht_p, NULL, NULL,
&out_pnc)) { &out_pnc)) {
if (out_pnc.nexthop_num) { if (out_pnc.nexthop_num) {
up = pim_upstream_find(&sg); up = pim_upstream_find(pimg, &sg);
memset(&nexthop, 0, sizeof(nexthop)); memset(&nexthop, 0, sizeof(nexthop));
if (up) if (up)
memcpy(&nexthop, memcpy(&nexthop,

View File

@ -75,7 +75,7 @@ void pim_prefix_list_update(struct prefix_list *plist)
{ {
pim_rp_prefix_list_update(plist); pim_rp_prefix_list_update(plist);
pim_ssm_prefix_list_update(plist); pim_ssm_prefix_list_update(plist);
pim_upstream_spt_prefix_list_update(plist); pim_upstream_spt_prefix_list_update(pimg, plist);
} }
static void pim_free() static void pim_free()
@ -84,8 +84,6 @@ static void pim_free()
pim_oil_terminate(); pim_oil_terminate();
pim_upstream_terminate();
pim_if_terminate(); pim_if_terminate();
pim_rp_free(); pim_rp_free();
@ -113,8 +111,6 @@ void pim_init()
pim_oil_init(); pim_oil_init();
pim_upstream_init();
/* /*
RFC 4601: 4.6.3. Assert Metrics RFC 4601: 4.6.3. Assert Metrics