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);
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);
}
}
/* 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 */
#include "vty.h"
#include "zclient.h"
+#include "pim_instance.h"
#include "pim_cmd.h"
#include "pim_vty.h"
#include "pim_iface.h"
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
// 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)
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++;
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];
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");
up->flags)
? "yes"
: "no",
- pim_upstream_evaluate_join_desired(up) ? "yes"
- : "no");
+ pim_upstream_evaluate_join_desired(pimg, up)
+ ? "yes"
+ : "no");
}
}
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];
"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];
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);
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,
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);
}
}
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);
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(
child)) {
struct channel_oil *c_oil =
child->channel_oil;
- struct pim_interface *pim_ifp =
- ch->interface->info;
if (PIM_DEBUG_PIM_TRACE)
zlog_debug(
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);
}
/*
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);
}
}
}
*/
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);
}
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;
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);
}
"%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;
}
*/
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.
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)
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);
}
/*
&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:
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;
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;
if (pim->static_routes)
list_free(pim->static_routes);
+ pim_upstream_terminate(pim);
+
XFREE(MTYPE_PIM_PIM_INSTANCE, pimg);
}
pim_mroute_socket_enable(pim);
+ pim_upstream_init(pim);
return pim;
}
// 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);
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,
}
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)
}
#endif
- up = pim_upstream_find(&sg);
+ up = pim_upstream_find(pim_ifp->pim, &sg);
if (up) {
struct pim_upstream *parent;
struct pim_nexthop source;
* 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;
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__);
}
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;
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);
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;
}
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
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;
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 */
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);
}
}
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
*/
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;
}
/* 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 */
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;
}
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);
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;
}
}
}
- struct pim_upstream *upstream = pim_upstream_find(&sg);
+ struct pim_upstream *upstream =
+ pim_upstream_find(pim_ifp->pim, &sg);
/*
* If we don't have a place to send ignore the packet
*/
if ((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;
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);
}
* will
* disappear in time for SSM groups.
*/
- pim_upstream_register_reevaluate();
+ pim_upstream_register_reevaluate(pimg);
igmp_source_forward_reevaluate_all();
}
#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);
* 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;
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;
* 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;
&& (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)) {
* 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;
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);
}
}
-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;
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;
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);
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);
/* 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
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;
}
"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;
}
{
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));
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;
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) {
"%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;
}
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;
}
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(
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;
}
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)) {
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;
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;
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;
/*
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
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;
/*
* 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];
/* 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;
/* 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;
/* 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;
&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;
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;
* 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
* 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;
/*
* 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(
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)
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);
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);
}
}
* 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;
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;
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;
}
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);
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);
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);
#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 */
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);
}
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)
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,
{
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()
pim_oil_terminate();
- pim_upstream_terminate();
-
pim_if_terminate();
pim_rp_free();
pim_oil_init();
- pim_upstream_init();
-
/*
RFC 4601: 4.6.3. Assert Metrics