mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-05 15:10:38 +00:00
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:
parent
fec883d95a
commit
9b29ea95fc
@ -47,6 +47,7 @@ void pim_ifassert_winner_set(struct pim_ifchannel *ch,
|
||||
struct in_addr winner,
|
||||
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 metric_changed = !pim_assert_metric_match(
|
||||
&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();
|
||||
|
||||
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_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 */
|
||||
pim_write_uint32(pim_msg_curr,
|
||||
rpt_bit_flag ? metric_preference | 0x80000000
|
||||
: metric_preference);
|
||||
pim_write_uint32(pim_msg_curr, rpt_bit_flag
|
||||
? metric_preference | 0x80000000
|
||||
: metric_preference);
|
||||
pim_msg_curr += 4;
|
||||
|
||||
/* Route metric */
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "vty.h"
|
||||
#include "zclient.h"
|
||||
|
||||
#include "pim_instance.h"
|
||||
#include "pim_cmd.h"
|
||||
#include "pim_vty.h"
|
||||
#include "pim_iface.h"
|
||||
|
@ -989,7 +989,7 @@ static void pim_show_interfaces_single(struct vty *vty, const char *ifname,
|
||||
pim_ifp->pim_dr_election_changes);
|
||||
|
||||
// FHR
|
||||
for (ALL_LIST_ELEMENTS_RO(pim_upstream_list, upnode,
|
||||
for (ALL_LIST_ELEMENTS_RO(pimg->upstream_list, upnode,
|
||||
up)) {
|
||||
if (ifp == up->rpf.source_nexthop.interface) {
|
||||
if (up->flags
|
||||
@ -1163,7 +1163,7 @@ static void pim_show_interfaces_single(struct vty *vty, const char *ifname,
|
||||
|
||||
// FHR
|
||||
print_header = 1;
|
||||
for (ALL_LIST_ELEMENTS_RO(pim_upstream_list, upnode,
|
||||
for (ALL_LIST_ELEMENTS_RO(pimg->upstream_list, upnode,
|
||||
up)) {
|
||||
if (strcmp(ifp->name, up->rpf.source_nexthop
|
||||
.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;
|
||||
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 (up->flags & PIM_UPSTREAM_FLAG_MASK_FHR)
|
||||
fhr++;
|
||||
@ -2251,7 +2251,7 @@ static void pim_show_upstream(struct vty *vty, u_char uj)
|
||||
vty_out(vty,
|
||||
"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 grp_str[INET_ADDRSTRLEN];
|
||||
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,
|
||||
"pimInclude");
|
||||
|
||||
if (pim_upstream_evaluate_join_desired(up))
|
||||
if (pim_upstream_evaluate_join_desired(pimg, up))
|
||||
json_object_boolean_true_add(
|
||||
json_row, "evaluateJoinDesired");
|
||||
|
||||
@ -2424,8 +2424,9 @@ static void pim_show_join_desired(struct vty *vty, u_char uj)
|
||||
up->flags)
|
||||
? "yes"
|
||||
: "no",
|
||||
pim_upstream_evaluate_join_desired(up) ? "yes"
|
||||
: "no");
|
||||
pim_upstream_evaluate_join_desired(pimg, up)
|
||||
? "yes"
|
||||
: "no");
|
||||
}
|
||||
}
|
||||
|
||||
@ -2450,7 +2451,7 @@ static void pim_show_upstream_rpf(struct vty *vty, u_char uj)
|
||||
vty_out(vty,
|
||||
"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 grp_str[INET_ADDRSTRLEN];
|
||||
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");
|
||||
}
|
||||
|
||||
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 grp_str[INET_ADDRSTRLEN];
|
||||
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)
|
||||
XFREE(MTYPE_PIM_SPT_PLIST_NAME, pimg->spt.plist);
|
||||
|
||||
pim_upstream_add_lhr_star_pimreg();
|
||||
pim_upstream_add_lhr_star_pimreg(pimg);
|
||||
break;
|
||||
case PIM_SPT_INFINITY:
|
||||
pim_upstream_remove_lhr_star_pimreg(plist);
|
||||
pim_upstream_remove_lhr_star_pimreg(pimg, plist);
|
||||
|
||||
if (pimg->spt.plist)
|
||||
XFREE(MTYPE_PIM_SPT_PLIST_NAME, pimg->spt.plist);
|
||||
|
@ -395,7 +395,8 @@ int pim_hello_recv(struct interface *ifp, struct in_addr src_addr,
|
||||
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");
|
||||
neigh = pim_neighbor_add(ifp, src_addr, hello_options,
|
||||
|
@ -1546,7 +1546,7 @@ void pim_if_update_join_desired(struct pim_interface *pim_ifp)
|
||||
continue;
|
||||
|
||||
/* 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);
|
||||
}
|
||||
}
|
||||
|
@ -171,14 +171,14 @@ void pim_ifchannel_delete(struct pim_ifchannel *ch)
|
||||
listnode_delete(ch->upstream->ifchannels, ch);
|
||||
|
||||
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
|
||||
ifchannel list is empty before deleting upstream_del
|
||||
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;
|
||||
|
||||
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 old_state = ch->ifjoin_state;
|
||||
struct pim_interface *pim_ifp = ch->interface->info;
|
||||
|
||||
if (PIM_DEBUG_PIM_EVENTS)
|
||||
zlog_debug(
|
||||
@ -266,8 +267,6 @@ void pim_ifchannel_ifjoin_switch(const char *caller, struct pim_ifchannel *ch,
|
||||
child)) {
|
||||
struct channel_oil *c_oil =
|
||||
child->channel_oil;
|
||||
struct pim_interface *pim_ifp =
|
||||
ch->interface->info;
|
||||
|
||||
if (PIM_DEBUG_PIM_TRACE)
|
||||
zlog_debug(
|
||||
@ -280,12 +279,12 @@ void pim_ifchannel_ifjoin_switch(const char *caller, struct pim_ifchannel *ch,
|
||||
continue;
|
||||
|
||||
if (!pim_upstream_evaluate_join_desired(
|
||||
child)) {
|
||||
pim_ifp->pim, child)) {
|
||||
pim_channel_del_oif(
|
||||
c_oil, ch->interface,
|
||||
PIM_OIF_FLAG_PROTO_STAR);
|
||||
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);
|
||||
|
||||
if (pim_upstream_evaluate_join_desired(
|
||||
child)) {
|
||||
pim_ifp->pim, child)) {
|
||||
pim_channel_add_oif(
|
||||
child->channel_oil,
|
||||
ch->interface,
|
||||
PIM_OIF_FLAG_PROTO_STAR);
|
||||
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();
|
||||
|
||||
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_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,
|
||||
enum pim_ifmembership membership)
|
||||
{
|
||||
struct pim_interface *pim_ifp = ch->interface->info;
|
||||
|
||||
if (ch->local_ifmembership == membership)
|
||||
return;
|
||||
|
||||
@ -446,7 +447,7 @@ static void ifmembership_set(struct pim_ifchannel *ch,
|
||||
|
||||
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_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",
|
||||
__PRETTY_FUNCTION__, up->sg_str, ifp->name);
|
||||
|
||||
pim_upstream_del(up, __PRETTY_FUNCTION__);
|
||||
pim_upstream_del(pim_ifp->pim, up, __PRETTY_FUNCTION__);
|
||||
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 (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_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)
|
||||
{
|
||||
struct pim_upstream *up;
|
||||
struct pim_interface *pim_ifp = recv_ifp->info;
|
||||
|
||||
/* Upstream (S,G) in Joined state ? */
|
||||
up = pim_upstream_find(sg);
|
||||
up = pim_upstream_find(pim_ifp->pim, sg);
|
||||
if (!up)
|
||||
return;
|
||||
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_IFJOIN_JOIN);
|
||||
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);
|
||||
}
|
||||
/*
|
||||
@ -941,7 +945,8 @@ void pim_ifchannel_prune(struct interface *ifp, struct in_addr upstream,
|
||||
&ch->t_ifjoin_prune_pending_timer);
|
||||
thread_add_timer(master, on_ifjoin_expiry_timer, ch,
|
||||
holdtime, &ch->t_ifjoin_expiry_timer);
|
||||
pim_upstream_update_join_desired(ch->upstream);
|
||||
pim_upstream_update_join_desired(pim_ifp->pim,
|
||||
ch->upstream);
|
||||
}
|
||||
break;
|
||||
case PIM_IFJOIN_PRUNE_PENDING:
|
||||
@ -1029,7 +1034,7 @@ int pim_ifchannel_local_membership_add(struct interface *ifp,
|
||||
ifmembership_set(ch, PIM_IFMEMBERSHIP_INCLUDE);
|
||||
|
||||
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 listnode *up_node;
|
||||
|
||||
@ -1095,7 +1100,7 @@ void pim_ifchannel_local_membership_del(struct interface *ifp,
|
||||
ifmembership_set(ch, PIM_IFMEMBERSHIP_NOINFO);
|
||||
|
||||
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 listnode *up_node, *up_nnode;
|
||||
|
||||
|
@ -48,6 +48,8 @@ static void pim_instance_terminate(struct pim_instance *pim)
|
||||
if (pim->static_routes)
|
||||
list_free(pim->static_routes);
|
||||
|
||||
pim_upstream_terminate(pim);
|
||||
|
||||
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_upstream_init(pim);
|
||||
return pim;
|
||||
}
|
||||
|
||||
|
@ -56,6 +56,11 @@ struct pim_instance {
|
||||
|
||||
// List of 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);
|
||||
|
@ -214,18 +214,20 @@ static int pim_mroute_msg_wholepkt(int fd, struct interface *ifp,
|
||||
const struct ip *ip_hdr;
|
||||
struct pim_upstream *up;
|
||||
|
||||
pim_ifp = ifp->info;
|
||||
|
||||
ip_hdr = (const struct ip *)buf;
|
||||
|
||||
memset(&sg, 0, sizeof(struct prefix_sg));
|
||||
sg.src = ip_hdr->ip_src;
|
||||
sg.grp = ip_hdr->ip_dst;
|
||||
|
||||
up = pim_upstream_find(&sg);
|
||||
up = pim_upstream_find(pim_ifp->pim, &sg);
|
||||
if (!up) {
|
||||
struct prefix_sg star = sg;
|
||||
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)) {
|
||||
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(
|
||||
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);
|
||||
|
||||
if (PIM_DEBUG_MROUTE)
|
||||
@ -433,7 +435,7 @@ static int pim_mroute_msg_wrvifwhole(int fd, struct interface *ifp,
|
||||
}
|
||||
#endif
|
||||
|
||||
up = pim_upstream_find(&sg);
|
||||
up = pim_upstream_find(pim_ifp->pim, &sg);
|
||||
if (up) {
|
||||
struct pim_upstream *parent;
|
||||
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
|
||||
* it.
|
||||
*/
|
||||
parent = pim_upstream_find(&star_g);
|
||||
parent = pim_upstream_find(pim_ifp->pim, &star_g);
|
||||
if (parent && parent->rpf.source_nexthop.interface == ifp)
|
||||
return 0;
|
||||
|
||||
@ -469,7 +471,7 @@ static int pim_mroute_msg_wrvifwhole(int fd, struct interface *ifp,
|
||||
if (!up->channel_oil)
|
||||
up->channel_oil = pim_channel_oil_add(
|
||||
&sg, pim_ifp->mroute_vif_index);
|
||||
pim_upstream_inherited_olist(up);
|
||||
pim_upstream_inherited_olist(pim_ifp->pim, up);
|
||||
if (!up->channel_oil->installed)
|
||||
pim_mroute_add(up->channel_oil,
|
||||
__PRETTY_FUNCTION__);
|
||||
@ -487,7 +489,7 @@ static int pim_mroute_msg_wrvifwhole(int fd, struct interface *ifp,
|
||||
}
|
||||
pim_upstream_keep_alive_timer_start(
|
||||
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);
|
||||
}
|
||||
return 0;
|
||||
@ -512,7 +514,7 @@ static int pim_mroute_msg_wrvifwhole(int fd, struct interface *ifp,
|
||||
up->channel_oil = oil;
|
||||
up->channel_oil->cc.pktcnt++;
|
||||
pim_register_join(up);
|
||||
pim_upstream_inherited_olist(up);
|
||||
pim_upstream_inherited_olist(pim_ifp->pim, up);
|
||||
|
||||
// Send the packet to the RP
|
||||
pim_mroute_msg_wholepkt(fd, ifp, buf);
|
||||
|
@ -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)) {
|
||||
PIM_UPSTREAM_FLAG_UNSET_SRC_MSDP(up->flags);
|
||||
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;
|
||||
}
|
||||
|
||||
@ -149,7 +149,7 @@ static bool pim_msdp_sa_upstream_add_ok(struct pim_msdp_sa *sa,
|
||||
memset(&sg, 0, sizeof(sg));
|
||||
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)) {
|
||||
/* 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;
|
||||
}
|
||||
|
||||
up = pim_upstream_find(&sa->sg);
|
||||
up = pim_upstream_find(pimg, &sa->sg);
|
||||
if (up && (PIM_UPSTREAM_FLAG_TEST_SRC_MSDP(up->flags))) {
|
||||
/* somehow we lost track of the upstream ptr? best log it */
|
||||
sa->up = up;
|
||||
@ -206,7 +206,7 @@ static void pim_msdp_sa_upstream_update(struct pim_msdp_sa *sa,
|
||||
sa->up = up;
|
||||
if (up) {
|
||||
/* 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
|
||||
* when the
|
||||
* SA ages out */
|
||||
@ -555,7 +555,7 @@ static void pim_msdp_sa_local_setup(void)
|
||||
struct pim_upstream *up;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -545,7 +545,7 @@ pim_neighbor_add(struct interface *ifp, struct in_addr source_addr,
|
||||
else
|
||||
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
|
||||
in that case nexthop cache would not consider this neighbor
|
||||
|
@ -389,7 +389,7 @@ static int pim_update_upstream_nh(struct pim_instance *pim,
|
||||
*/
|
||||
if (up->channel_oil
|
||||
&& 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;
|
||||
}
|
||||
|
||||
@ -431,7 +431,7 @@ static int pim_update_upstream_nh(struct pim_instance *pim,
|
||||
/* FIXME can join_desired actually be changed by
|
||||
pim_rpf_update()
|
||||
returning PIM_RPF_CHANGED ? */
|
||||
pim_upstream_update_join_desired(up);
|
||||
pim_upstream_update_join_desired(pim, up);
|
||||
|
||||
} /* PIM_RPF_CHANGED */
|
||||
|
||||
|
@ -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_ref_count;
|
||||
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;
|
||||
}
|
||||
|
||||
@ -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_ref_count = 1;
|
||||
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);
|
||||
|
||||
|
@ -123,7 +123,7 @@ int pim_register_stop_recv(uint8_t *buf, int buf_size)
|
||||
pim_parse_addr_ucast(&source, buf, buf_size);
|
||||
sg.src = source.u.prefix4;
|
||||
|
||||
upstream = pim_upstream_find(&sg);
|
||||
upstream = pim_upstream_find(pimg, &sg);
|
||||
if (!upstream) {
|
||||
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
|
||||
*/
|
||||
@ -375,7 +376,8 @@ int pim_register_recv(struct interface *ifp, struct in_addr dest_addr,
|
||||
|
||||
if ((upstream->sptbit == PIM_UPSTREAM_SPTBIT_TRUE)
|
||||
|| ((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_register_stop_send(ifp, &sg, dest_addr, src_addr);
|
||||
sentRegisterStop = 1;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
pim_upstream_update_join_desired(up);
|
||||
pim_upstream_update_join_desired(pimg, up);
|
||||
pim_upstream_update_could_assert(up);
|
||||
pim_upstream_update_my_assert_metric(up);
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ static void pim_ssm_range_reevaluate(void)
|
||||
* will
|
||||
* disappear in time for SSM groups.
|
||||
*/
|
||||
pim_upstream_register_reevaluate();
|
||||
pim_upstream_register_reevaluate(pimg);
|
||||
igmp_source_forward_reevaluate_all();
|
||||
}
|
||||
|
||||
|
@ -54,10 +54,6 @@
|
||||
#include "pim_nht.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
|
||||
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
|
||||
* 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;
|
||||
|
||||
@ -79,7 +76,8 @@ static void pim_upstream_remove_children(struct pim_upstream *up)
|
||||
listnode_delete(up->sources, child);
|
||||
if (PIM_UPSTREAM_FLAG_TEST_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)
|
||||
child->parent = NULL;
|
||||
@ -93,7 +91,8 @@ static void pim_upstream_remove_children(struct pim_upstream *up)
|
||||
* Find the children that would point
|
||||
* 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 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))
|
||||
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)
|
||||
&& (child->sg.grp.s_addr == up->sg.grp.s_addr)
|
||||
&& (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 (*,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 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)
|
||||
&& (child->sg.grp.s_addr != INADDR_ANY)) {
|
||||
any.src.s_addr = INADDR_ANY;
|
||||
up = pim_upstream_find(&any);
|
||||
up = pim_upstream_find(pim, &any);
|
||||
|
||||
if (up)
|
||||
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;
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
pim_upstream_remove_children(up);
|
||||
pim_upstream_remove_children(pim, up);
|
||||
if (up->sources)
|
||||
list_delete(up->sources);
|
||||
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);
|
||||
up->parent = NULL;
|
||||
|
||||
listnode_delete(pim_upstream_list, up);
|
||||
hash_release(pim_upstream_hash, up);
|
||||
listnode_delete(pim->upstream_list, up);
|
||||
hash_release(pim->upstream_hash, up);
|
||||
|
||||
if (notify_msdp) {
|
||||
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",
|
||||
__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);
|
||||
|
||||
@ -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
|
||||
* 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 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
|
||||
* is actually active; if it is not kat setup will trigger
|
||||
* source
|
||||
@ -491,7 +492,7 @@ void pim_upstream_register_reevaluate(void)
|
||||
up->sg_str);
|
||||
/* remove regiface from the OIL if it is there*/
|
||||
pim_channel_del_oif(up->channel_oil,
|
||||
pimg->regiface,
|
||||
pim->regiface,
|
||||
PIM_OIF_FLAG_PROTO_PIM);
|
||||
up->reg_state = PIM_REG_NOINFO;
|
||||
}
|
||||
@ -503,7 +504,7 @@ void pim_upstream_register_reevaluate(void)
|
||||
"Register %s as G is now ASM",
|
||||
up->sg_str);
|
||||
pim_channel_add_oif(up->channel_oil,
|
||||
pimg->regiface,
|
||||
pim->regiface,
|
||||
PIM_OIF_FLAG_PROTO_PIM);
|
||||
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;
|
||||
struct pim_interface *pim_ifp;
|
||||
struct pim_instance *pim;
|
||||
struct pim_upstream *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;
|
||||
}
|
||||
|
||||
pim_ifp = incoming->info;
|
||||
pim = pim_ifp->pim;
|
||||
up->sg = *sg;
|
||||
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_DEBUG_TRACE)
|
||||
zlog_debug("%s: Received a (*,G) with no RP configured",
|
||||
__PRETTY_FUNCTION__);
|
||||
|
||||
hash_release(pim_upstream_hash, up);
|
||||
hash_release(pim->upstream_hash, up);
|
||||
XFREE(MTYPE_PIM_UPSTREAM, up);
|
||||
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) {
|
||||
up->sources = list_new();
|
||||
up->sources->cmp = pim_upstream_compare;
|
||||
} else
|
||||
up->sources = NULL;
|
||||
|
||||
pim_upstream_find_new_children(up);
|
||||
pim_upstream_find_new_children(pim, up);
|
||||
up->flags = flags;
|
||||
up->ref_count = 1;
|
||||
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;
|
||||
|
||||
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);
|
||||
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",
|
||||
__PRETTY_FUNCTION__, up->sg_str);
|
||||
|
||||
pim_ifp = incoming->info;
|
||||
nht_p.family = AF_INET;
|
||||
nht_p.prefixlen = IPV4_MAX_BITLEN;
|
||||
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)
|
||||
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)
|
||||
list_delete(up->sources);
|
||||
|
||||
hash_release(pim_upstream_hash, up);
|
||||
hash_release(pim->upstream_hash, up);
|
||||
XFREE(MTYPE_PIM_UPSTREAM, up);
|
||||
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->sg, pim_ifp->mroute_vif_index);
|
||||
}
|
||||
listnode_add_sort(pim_upstream_list, up);
|
||||
listnode_add_sort(pim->upstream_list, up);
|
||||
|
||||
if (PIM_DEBUG_TRACE) {
|
||||
zlog_debug(
|
||||
@ -712,13 +715,14 @@ pim_upstream_new(struct prefix_sg *sg, struct interface *incoming, int flags)
|
||||
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 *up = NULL;
|
||||
|
||||
lookup.sg = *sg;
|
||||
up = hash_lookup(pim_upstream_hash, &lookup);
|
||||
up = hash_lookup(pim->upstream_hash, &lookup);
|
||||
return up;
|
||||
}
|
||||
|
||||
@ -727,8 +731,11 @@ struct pim_upstream *pim_upstream_find_or_add(struct prefix_sg *sg,
|
||||
int flags, const char *name)
|
||||
{
|
||||
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->flags & flags)) {
|
||||
@ -761,8 +768,11 @@ struct pim_upstream *pim_upstream_add(struct prefix_sg *sg,
|
||||
const char *name)
|
||||
{
|
||||
struct pim_upstream *up = NULL;
|
||||
struct pim_interface *pim_ifp;
|
||||
int found = 0;
|
||||
up = pim_upstream_find(sg);
|
||||
|
||||
pim_ifp = incoming->info;
|
||||
up = pim_upstream_find(pim_ifp->pim, sg);
|
||||
if (up) {
|
||||
pim_upstream_ref(up, flags, name);
|
||||
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.
|
||||
*/
|
||||
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 listnode *node;
|
||||
@ -851,7 +862,7 @@ int pim_upstream_evaluate_join_desired(struct pim_upstream *up)
|
||||
struct pim_upstream *starup = up->parent;
|
||||
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)
|
||||
continue;
|
||||
|
||||
@ -875,14 +886,15 @@ int pim_upstream_evaluate_join_desired(struct pim_upstream *up)
|
||||
/*
|
||||
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 is_join_desired; /* boolean */
|
||||
|
||||
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)
|
||||
PIM_UPSTREAM_FLAG_SET_DR_JOIN_DESIRED(up->flags);
|
||||
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
|
||||
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_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
|
||||
*/
|
||||
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) {
|
||||
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
|
||||
* transition the (S, G) on FHR to NI state and remove reg tunnel
|
||||
* 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))
|
||||
return;
|
||||
@ -1033,7 +1047,7 @@ static void pim_upstream_fhr_kat_expiry(struct pim_upstream *up)
|
||||
/* stop reg-stop timer */
|
||||
THREAD_OFF(up->t_rs_timer);
|
||||
/* 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);
|
||||
/* clear the register state */
|
||||
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 (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)
|
||||
zlog_debug("kat expired on %s; remove stream reference",
|
||||
up->sg_str);
|
||||
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)) {
|
||||
PIM_UPSTREAM_FLAG_UNSET_SRC_LHR(up->flags);
|
||||
pim_upstream_del(up, __PRETTY_FUNCTION__);
|
||||
pim_upstream_del(pimg, up, __PRETTY_FUNCTION__);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -1381,7 +1395,8 @@ void pim_upstream_start_register_stop_timer(struct pim_upstream *up,
|
||||
&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 pim_interface *pim_ifp = NULL;
|
||||
@ -1401,7 +1416,7 @@ int pim_upstream_inherited_olist_decide(struct pim_upstream *up)
|
||||
up->channel_oil =
|
||||
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)
|
||||
continue;
|
||||
|
||||
@ -1446,9 +1461,10 @@ int pim_upstream_inherited_olist_decide(struct pim_upstream *up)
|
||||
* return 1 if there are 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
|
||||
@ -1475,7 +1491,7 @@ int pim_upstream_empty_inherited_olist(struct pim_upstream *up)
|
||||
* set and see if the new neighbor allows
|
||||
* 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_nextnode;
|
||||
@ -1484,7 +1500,7 @@ void pim_upstream_find_new_rpf(void)
|
||||
/*
|
||||
* 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_DEBUG_TRACE)
|
||||
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);
|
||||
}
|
||||
|
||||
void pim_upstream_terminate(void)
|
||||
void pim_upstream_terminate(struct pim_instance *pim)
|
||||
{
|
||||
if (pim_upstream_list)
|
||||
list_delete(pim_upstream_list);
|
||||
pim_upstream_list = NULL;
|
||||
if (pim->upstream_list)
|
||||
list_delete(pim->upstream_list);
|
||||
pim->upstream_list = NULL;
|
||||
|
||||
if (pim_upstream_hash)
|
||||
hash_free(pim_upstream_hash);
|
||||
pim_upstream_hash = NULL;
|
||||
if (pim->upstream_hash)
|
||||
hash_free(pim->upstream_hash);
|
||||
pim->upstream_hash = NULL;
|
||||
}
|
||||
|
||||
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(
|
||||
"%s: Handling unscanned inherited_olist for %s",
|
||||
__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;
|
||||
}
|
||||
pim_mroute_update_counters(up->channel_oil);
|
||||
@ -1639,29 +1655,30 @@ static void pim_upstream_sg_running(void *arg)
|
||||
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 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)
|
||||
continue;
|
||||
|
||||
if (!PIM_UPSTREAM_FLAG_TEST_SRC_IGMP(up->flags))
|
||||
continue;
|
||||
|
||||
pim_channel_add_oif(up->channel_oil, pimg->regiface,
|
||||
pim_channel_add_oif(up->channel_oil, pim->regiface,
|
||||
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);
|
||||
|
||||
if (pimg->spt.plist && strcmp(pimg->spt.plist, pname) == 0) {
|
||||
pim_upstream_remove_lhr_star_pimreg(pname);
|
||||
if (pim->spt.plist && strcmp(pim->spt.plist, pname) == 0) {
|
||||
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
|
||||
*
|
||||
*/
|
||||
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 listnode *node;
|
||||
@ -1690,7 +1708,7 @@ void pim_upstream_remove_lhr_star_pimreg(const char *nlist)
|
||||
g.family = AF_INET;
|
||||
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)
|
||||
continue;
|
||||
|
||||
@ -1698,30 +1716,30 @@ void pim_upstream_remove_lhr_star_pimreg(const char *nlist)
|
||||
continue;
|
||||
|
||||
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);
|
||||
continue;
|
||||
}
|
||||
g.u.prefix4 = up->sg.grp;
|
||||
apply_new = prefix_list_apply(np, &g);
|
||||
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);
|
||||
else
|
||||
pim_channel_del_oif(up->channel_oil, pimg->regiface,
|
||||
pim_channel_del_oif(up->channel_oil, pim->regiface,
|
||||
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,
|
||||
pim_upstream_sg_running);
|
||||
pim_upstream_hash = hash_create_size(8192, pim_upstream_hash_key,
|
||||
pim_upstream_equal, NULL);
|
||||
pim->upstream_hash = hash_create_size(8192, pim_upstream_hash_key,
|
||||
pim_upstream_equal, NULL);
|
||||
|
||||
pim_upstream_list = list_new();
|
||||
pim_upstream_list->del = (void (*)(void *))pim_upstream_free;
|
||||
pim_upstream_list->cmp = pim_upstream_compare;
|
||||
pim->upstream_list = list_new();
|
||||
pim->upstream_list->del = (void (*)(void *))pim_upstream_free;
|
||||
pim->upstream_list->cmp = pim_upstream_compare;
|
||||
}
|
||||
|
@ -137,11 +137,9 @@ struct pim_upstream {
|
||||
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);
|
||||
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 interface *ifp, int flags,
|
||||
const char *name);
|
||||
@ -149,14 +147,17 @@ struct pim_upstream *pim_upstream_add(struct prefix_sg *sg,
|
||||
struct interface *ifp, 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);
|
||||
|
||||
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,
|
||||
struct pim_ifchannel *ch,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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
|
||||
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(struct pim_upstream *up);
|
||||
int pim_upstream_inherited_olist_decide(struct pim_instance *pim,
|
||||
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);
|
||||
|
||||
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_init(void);
|
||||
void pim_upstream_terminate(void);
|
||||
void pim_upstream_init(struct pim_instance *pim);
|
||||
void pim_upstream_terminate(struct pim_instance *pim);
|
||||
|
||||
void join_timer_start(struct pim_upstream *up);
|
||||
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_remove_lhr_star_pimreg(const char *nlist);
|
||||
void pim_upstream_add_lhr_star_pimreg(struct pim_instance *pim);
|
||||
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 */
|
||||
|
189
pimd/pim_zebra.c
189
pimd/pim_zebra.c
@ -292,8 +292,8 @@ static int pim_zebra_if_address_add(int command, struct zclient *zclient,
|
||||
struct listnode *ifnode;
|
||||
struct interface *ifp;
|
||||
|
||||
for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pimg->vrf_id), ifnode,
|
||||
ifp)) {
|
||||
for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim_ifp->pim->vrf_id),
|
||||
ifnode, ifp)) {
|
||||
if (!if_is_loopback(ifp) && if_is_operative(ifp))
|
||||
pim_if_addr_add_all(ifp);
|
||||
}
|
||||
@ -357,99 +357,128 @@ static void scan_upstream_rpf_cache()
|
||||
struct listnode *node;
|
||||
struct pim_upstream *up;
|
||||
struct interface *ifp;
|
||||
struct vrf *vrf;
|
||||
struct pim_instance *pim;
|
||||
|
||||
for (ALL_LIST_ELEMENTS(pim_upstream_list, up_node, up_nextnode, up)) {
|
||||
enum pim_rpf_result rpf_result;
|
||||
struct pim_rpf old;
|
||||
struct prefix nht_p;
|
||||
|
||||
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)
|
||||
RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name)
|
||||
{
|
||||
pim = vrf->info;
|
||||
if (!pim)
|
||||
continue;
|
||||
|
||||
if (rpf_result == PIM_RPF_CHANGED) {
|
||||
struct pim_neighbor *nbr;
|
||||
for (ALL_LIST_ELEMENTS(pim->upstream_list, up_node, up_nextnode,
|
||||
up)) {
|
||||
enum pim_rpf_result rpf_result;
|
||||
struct pim_rpf old;
|
||||
struct prefix nht_p;
|
||||
|
||||
nbr = pim_neighbor_find(old.source_nexthop.interface,
|
||||
old.rpf_addr.u.prefix4);
|
||||
if (nbr)
|
||||
pim_jp_agg_remove_group(nbr->upstream_jp_agg,
|
||||
up);
|
||||
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(pim, &nht_p);
|
||||
|
||||
/*
|
||||
* We have detected a case where we might need to rescan
|
||||
* the inherited o_list so do it.
|
||||
*/
|
||||
if (up->channel_oil->oil_inherited_rescan) {
|
||||
pim_upstream_inherited_olist_decide(up);
|
||||
up->channel_oil->oil_inherited_rescan = 0;
|
||||
}
|
||||
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 (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__);
|
||||
if (rpf_result == PIM_RPF_FAILURE)
|
||||
continue;
|
||||
|
||||
if (rpf_result == PIM_RPF_CHANGED) {
|
||||
struct pim_neighbor *nbr;
|
||||
|
||||
nbr = pim_neighbor_find(
|
||||
old.source_nexthop.interface,
|
||||
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
|
||||
* Messages
|
||||
*
|
||||
* 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.
|
||||
* We have detected a case where we might need
|
||||
* to rescan
|
||||
* the inherited o_list so do it.
|
||||
*/
|
||||
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);
|
||||
} /* up->join_state == PIM_UPSTREAM_JOINED */
|
||||
if (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()
|
||||
returning PIM_RPF_CHANGED ? */
|
||||
pim_upstream_update_join_desired(up);
|
||||
/*
|
||||
* RFC 4601: 4.5.7. Sending (S,G)
|
||||
* Join/Prune Messages
|
||||
*
|
||||
* 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))
|
||||
if (ifp->info) {
|
||||
struct pim_interface *pim_ifp = ifp->info;
|
||||
struct pim_iface_upstream_switch *us;
|
||||
} /* PIM_RPF_CHANGED */
|
||||
|
||||
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);
|
||||
} /* for (qpim_upstream_list) */
|
||||
}
|
||||
|
||||
RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name)
|
||||
{
|
||||
pim = vrf->info;
|
||||
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)
|
||||
@ -875,7 +904,7 @@ void igmp_source_forward_start(struct igmp_source *source)
|
||||
if (pim_find_or_track_nexthop(pimg, &nht_p, NULL, NULL,
|
||||
&out_pnc)) {
|
||||
if (out_pnc.nexthop_num) {
|
||||
up = pim_upstream_find(&sg);
|
||||
up = pim_upstream_find(pimg, &sg);
|
||||
memset(&nexthop, 0, sizeof(nexthop));
|
||||
if (up)
|
||||
memcpy(&nexthop,
|
||||
|
@ -75,7 +75,7 @@ void pim_prefix_list_update(struct prefix_list *plist)
|
||||
{
|
||||
pim_rp_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()
|
||||
@ -84,8 +84,6 @@ static void pim_free()
|
||||
|
||||
pim_oil_terminate();
|
||||
|
||||
pim_upstream_terminate();
|
||||
|
||||
pim_if_terminate();
|
||||
pim_rp_free();
|
||||
|
||||
@ -113,8 +111,6 @@ void pim_init()
|
||||
|
||||
pim_oil_init();
|
||||
|
||||
pim_upstream_init();
|
||||
|
||||
/*
|
||||
RFC 4601: 4.6.3. Assert Metrics
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user