From 9b29ea95fc5b03de64cf9de55a89894deaed17e7 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Fri, 19 May 2017 19:36:53 -0400 Subject: [PATCH] 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 --- pimd/pim_assert.c | 9 +- pimd/pim_bfd.c | 1 + pimd/pim_cmd.c | 23 +++--- pimd/pim_hello.c | 3 +- pimd/pim_iface.c | 2 +- pimd/pim_ifchannel.c | 39 +++++---- pimd/pim_instance.c | 3 + pimd/pim_instance.h | 5 ++ pimd/pim_mroute.c | 18 ++-- pimd/pim_msdp.c | 10 +-- pimd/pim_neighbor.c | 2 +- pimd/pim_nht.c | 4 +- pimd/pim_oil.c | 4 +- pimd/pim_register.c | 8 +- pimd/pim_rpf.c | 2 +- pimd/pim_ssm.c | 2 +- pimd/pim_upstream.c | 172 +++++++++++++++++++++----------------- pimd/pim_upstream.h | 40 +++++---- pimd/pim_zebra.c | 191 +++++++++++++++++++++++++------------------ pimd/pimd.c | 6 +- 20 files changed, 307 insertions(+), 237 deletions(-) diff --git a/pimd/pim_assert.c b/pimd/pim_assert.c index f68c252a3..6af52bbf4 100644 --- a/pimd/pim_assert.c +++ b/pimd/pim_assert.c @@ -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 */ diff --git a/pimd/pim_bfd.c b/pimd/pim_bfd.c index e4c50a18b..1dfb558f4 100644 --- a/pimd/pim_bfd.c +++ b/pimd/pim_bfd.c @@ -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" diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index 1520f0873..cb72dbd45 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -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); diff --git a/pimd/pim_hello.c b/pimd/pim_hello.c index 2592514f3..bfa57d7f9 100644 --- a/pimd/pim_hello.c +++ b/pimd/pim_hello.c @@ -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, diff --git a/pimd/pim_iface.c b/pimd/pim_iface.c index dc0ffd5a6..43f8c08b4 100644 --- a/pimd/pim_iface.c +++ b/pimd/pim_iface.c @@ -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); } } diff --git a/pimd/pim_ifchannel.c b/pimd/pim_ifchannel.c index 099c7eef7..ccfc41ee2 100644 --- a/pimd/pim_ifchannel.c +++ b/pimd/pim_ifchannel.c @@ -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; diff --git a/pimd/pim_instance.c b/pimd/pim_instance.c index 84fc9b925..c2ca20d81 100644 --- a/pimd/pim_instance.c +++ b/pimd/pim_instance.c @@ -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; } diff --git a/pimd/pim_instance.h b/pimd/pim_instance.h index 83c8b3be9..79a0de79b 100644 --- a/pimd/pim_instance.h +++ b/pimd/pim_instance.h @@ -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); diff --git a/pimd/pim_mroute.c b/pimd/pim_mroute.c index 7f657fae3..c77f312c9 100644 --- a/pimd/pim_mroute.c +++ b/pimd/pim_mroute.c @@ -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); diff --git a/pimd/pim_msdp.c b/pimd/pim_msdp.c index 0f653e70a..3f8ab3749 100644 --- a/pimd/pim_msdp.c +++ b/pimd/pim_msdp.c @@ -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); } } diff --git a/pimd/pim_neighbor.c b/pimd/pim_neighbor.c index 90652af2d..04e3e10ff 100644 --- a/pimd/pim_neighbor.c +++ b/pimd/pim_neighbor.c @@ -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 diff --git a/pimd/pim_nht.c b/pimd/pim_nht.c index ccb48aae5..eb8bfa711 100644 --- a/pimd/pim_nht.c +++ b/pimd/pim_nht.c @@ -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 */ diff --git a/pimd/pim_oil.c b/pimd/pim_oil.c index aeef0ff4e..d4398d1c2 100644 --- a/pimd/pim_oil.c +++ b/pimd/pim_oil.c @@ -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); diff --git a/pimd/pim_register.c b/pimd/pim_register.c index a9c1ab913..ce81db954 100644 --- a/pimd/pim_register.c +++ b/pimd/pim_register.c @@ -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; diff --git a/pimd/pim_rpf.c b/pimd/pim_rpf.c index 22741230d..dfdf3b950 100644 --- a/pimd/pim_rpf.c +++ b/pimd/pim_rpf.c @@ -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); } diff --git a/pimd/pim_ssm.c b/pimd/pim_ssm.c index b11b498aa..35d588abd 100644 --- a/pimd/pim_ssm.c +++ b/pimd/pim_ssm.c @@ -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(); } diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c index 99f2435f4..bedfe0e93 100644 --- a/pimd/pim_upstream.c +++ b/pimd/pim_upstream.c @@ -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; + + pim_ifp = incoming->info; - up = pim_upstream_find(sg); + 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; } diff --git a/pimd/pim_upstream.h b/pimd/pim_upstream.h index b6a9729f0..62bd212e9 100644 --- a/pimd/pim_upstream.h +++ b/pimd/pim_upstream.h @@ -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 */ diff --git a/pimd/pim_zebra.c b/pimd/pim_zebra.c index 979aaa76a..11ec9eb35 100644 --- a/pimd/pim_zebra.c +++ b/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); + RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name) + { + pim = vrf->info; + if (!pim) + continue; - 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); + 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; - if (rpf_result == PIM_RPF_FAILURE) - continue; + 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); - if (rpf_result == PIM_RPF_CHANGED) { - struct pim_neighbor *nbr; + 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); - 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); + if (rpf_result == PIM_RPF_FAILURE) + continue; - /* - * 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; - } + if (rpf_result == PIM_RPF_CHANGED) { + struct pim_neighbor *nbr; - 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__); + 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); - - pim_upstream_join_timer_restart(up, &old); - } /* up->join_state == PIM_UPSTREAM_JOINED */ + if (up->channel_oil->oil_inherited_rescan) { + pim_upstream_inherited_olist_decide(pim, + up); + up->channel_oil->oil_inherited_rescan = + 0; + } - /* FIXME can join_desired actually be changed by - pim_rpf_update() - returning PIM_RPF_CHANGED ? */ - pim_upstream_update_join_desired(up); + 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__); + + /* + * 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_upstream_join_timer_restart(up, + &old); + } /* up->join_state == PIM_UPSTREAM_JOINED */ + + /* FIXME can join_desired actually be changed by + pim_rpf_update() + returning PIM_RPF_CHANGED ? */ + pim_upstream_update_join_desired(pim, up); + + } /* PIM_RPF_CHANGED */ + + } /* for (qpim_upstream_list) */ + } - } /* PIM_RPF_CHANGED */ + RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name) + { + pim = vrf->info; + if (!pim) + continue; - } /* for (qpim_upstream_list) */ + 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(vrf_iflist(pimg->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); + 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, diff --git a/pimd/pimd.c b/pimd/pimd.c index 64a16b098..91cf17d74 100644 --- a/pimd/pimd.c +++ b/pimd/pimd.c @@ -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 -- 2.39.5