summaryrefslogtreecommitdiffstats
path: root/pimd
diff options
context:
space:
mode:
Diffstat (limited to 'pimd')
-rw-r--r--pimd/pim_bsm.c269
-rw-r--r--pimd/pim_bsm.h6
-rw-r--r--pimd/pim_cmd.c173
-rw-r--r--pimd/pim_ifchannel.c11
-rw-r--r--pimd/pim_igmp.c2
-rw-r--r--pimd/pim_igmp_mtrace.c4
-rw-r--r--pimd/pim_join.c10
-rw-r--r--pimd/pim_jp_agg.c2
-rw-r--r--pimd/pim_msdp.c7
-rw-r--r--pimd/pim_msdp_packet.h3
-rw-r--r--pimd/pim_nht.c393
-rw-r--r--pimd/pim_nht.h25
-rw-r--r--pimd/pim_pim.c4
-rw-r--r--pimd/pim_register.c12
-rw-r--r--pimd/pim_rp.c69
-rw-r--r--pimd/pim_rpf.c2
-rw-r--r--pimd/pim_signals.c2
-rw-r--r--pimd/pim_signals.h2
-rw-r--r--pimd/pim_time.c4
-rw-r--r--pimd/pim_upstream.c8
-rw-r--r--pimd/pim_vxlan.c6
-rw-r--r--pimd/pim_vxlan.h2
-rw-r--r--pimd/pim_zebra.c26
-rw-r--r--pimd/pim_zebra.h2
-rw-r--r--pimd/pimd.h2
-rw-r--r--pimd/subdir.am16
26 files changed, 505 insertions, 557 deletions
diff --git a/pimd/pim_bsm.c b/pimd/pim_bsm.c
index a3a3426f3..238c19d2c 100644
--- a/pimd/pim_bsm.c
+++ b/pimd/pim_bsm.c
@@ -35,6 +35,7 @@
#include "pim_nht.h"
#include "pim_bsm.h"
#include "pim_time.h"
+#include "pim_zebra.h"
/* Functions forward declaration */
static void pim_bs_timer_start(struct bsm_scope *scope, int bs_timeout);
@@ -70,7 +71,7 @@ static void pim_bsm_rpinfo_free(struct bsm_rpinfo *bsrp_info)
XFREE(MTYPE_PIM_BSRP_INFO, bsrp_info);
}
-void pim_bsm_rpinfos_free(struct bsm_rpinfos_head *head)
+static void pim_bsm_rpinfos_free(struct bsm_rpinfos_head *head)
{
struct bsm_rpinfo *bsrp_info;
@@ -78,14 +79,14 @@ void pim_bsm_rpinfos_free(struct bsm_rpinfos_head *head)
pim_bsm_rpinfo_free(bsrp_info);
}
-void pim_free_bsgrp_data(struct bsgrp_node *bsgrp_node)
+static void pim_free_bsgrp_data(struct bsgrp_node *bsgrp_node)
{
pim_bsm_rpinfos_free(bsgrp_node->bsrp_list);
pim_bsm_rpinfos_free(bsgrp_node->partial_bsrp_list);
XFREE(MTYPE_PIM_BSGRP_NODE, bsgrp_node);
}
-void pim_free_bsgrp_node(struct route_table *rt, struct prefix *grp)
+static void pim_free_bsgrp_node(struct route_table *rt, struct prefix *grp)
{
struct route_node *rn;
@@ -102,7 +103,7 @@ static void pim_bsm_frag_free(struct bsm_frag *bsfrag)
XFREE(MTYPE_PIM_BSM_FRAG, bsfrag);
}
-void pim_bsm_frags_free(struct bsm_scope *scope)
+static void pim_bsm_frags_free(struct bsm_scope *scope)
{
struct bsm_frag *bsfrag;
@@ -162,8 +163,6 @@ static int pim_on_bs_timer(struct thread *t)
struct bsm_scope *scope;
struct bsgrp_node *bsgrp_node;
struct bsm_rpinfo *bsrp;
- struct prefix nht_p;
- bool is_bsr_tracking = true;
scope = THREAD_ARG(t);
THREAD_OFF(scope->bs_timer);
@@ -172,15 +171,7 @@ static int pim_on_bs_timer(struct thread *t)
zlog_debug("%s: Bootstrap Timer expired for scope: %d",
__func__, scope->sz_id);
- /* Remove next hop tracking for the bsr */
- nht_p.family = AF_INET;
- nht_p.prefixlen = IPV4_MAX_BITLEN;
- nht_p.u.prefix4 = scope->current_bsr;
- if (PIM_DEBUG_BSM)
- zlog_debug("%s: Deregister BSR addr %pFX with Zebra NHT",
- __func__, &nht_p);
- pim_delete_tracked_nexthop(scope->pim, &nht_p, NULL, NULL,
- is_bsr_tracking);
+ pim_nht_bsr_del(scope->pim, scope->current_bsr);
/* Reset scope zone data */
scope->accept_nofwd_bsm = false;
@@ -212,7 +203,7 @@ static int pim_on_bs_timer(struct thread *t)
return 0;
}
-void pim_bs_timer_stop(struct bsm_scope *scope)
+static void pim_bs_timer_stop(struct bsm_scope *scope)
{
if (PIM_DEBUG_BSM)
zlog_debug("%s : BS timer being stopped of sz: %d", __func__,
@@ -543,35 +534,6 @@ static void pim_instate_pend_list(struct bsgrp_node *bsgrp_node)
pim_bsm_rpinfos_free(bsgrp_node->partial_bsrp_list);
}
-static bool pim_bsr_rpf_check(struct pim_instance *pim, struct in_addr bsr,
- struct in_addr ip_src_addr)
-{
- struct pim_nexthop nexthop;
- int result;
-
- memset(&nexthop, 0, sizeof(nexthop));
-
- /* New BSR recived */
- if (bsr.s_addr != pim->global_scope.current_bsr.s_addr) {
- result = pim_nexthop_match(pim, bsr, ip_src_addr);
-
- /* Nexthop lookup pass for the new BSR address */
- if (result)
- return true;
-
- if (PIM_DEBUG_BSM) {
- char bsr_str[INET_ADDRSTRLEN];
-
- pim_inet4_dump("<bsr?>", bsr, bsr_str, sizeof(bsr_str));
- zlog_debug("%s : No route to BSR address %s", __func__,
- bsr_str);
- }
- return false;
- }
-
- return pim_nexthop_match_nht_cache(pim, bsr, ip_src_addr);
-}
-
static bool is_preferred_bsr(struct pim_instance *pim, struct in_addr bsr,
uint32_t bsr_prio)
{
@@ -594,35 +556,11 @@ static bool is_preferred_bsr(struct pim_instance *pim, struct in_addr bsr,
static void pim_bsm_update(struct pim_instance *pim, struct in_addr bsr,
uint32_t bsr_prio)
{
- struct pim_nexthop_cache pnc;
-
if (bsr.s_addr != pim->global_scope.current_bsr.s_addr) {
- struct prefix nht_p;
- bool is_bsr_tracking = true;
-
- /* De-register old BSR and register new BSR with Zebra NHT */
- nht_p.family = AF_INET;
- nht_p.prefixlen = IPV4_MAX_BITLEN;
+ if (pim->global_scope.current_bsr.s_addr)
+ pim_nht_bsr_del(pim, pim->global_scope.current_bsr);
+ pim_nht_bsr_add(pim, bsr);
- if (pim->global_scope.current_bsr.s_addr != INADDR_ANY) {
- nht_p.u.prefix4 = pim->global_scope.current_bsr;
- if (PIM_DEBUG_BSM)
- zlog_debug(
- "%s: Deregister BSR addr %pFX with Zebra NHT",
- __func__, &nht_p);
- pim_delete_tracked_nexthop(pim, &nht_p, NULL, NULL,
- is_bsr_tracking);
- }
-
- nht_p.u.prefix4 = bsr;
- if (PIM_DEBUG_BSM)
- zlog_debug(
- "%s: NHT Register BSR addr %pFX with Zebra NHT",
- __func__, &nht_p);
-
- memset(&pnc, 0, sizeof(struct pim_nexthop_cache));
- pim_find_or_track_nexthop(pim, &nht_p, NULL, NULL,
- is_bsr_tracking, &pnc);
pim->global_scope.current_bsr = bsr;
pim->global_scope.current_bsr_first_ts =
pim_time_monotonic_sec();
@@ -632,6 +570,127 @@ static void pim_bsm_update(struct pim_instance *pim, struct in_addr bsr,
pim->global_scope.current_bsr_last_ts = pim_time_monotonic_sec();
}
+void pim_bsm_clear(struct pim_instance *pim)
+{
+ struct route_node *rn;
+ struct route_node *rpnode;
+ struct bsgrp_node *bsgrp;
+ struct prefix nht_p;
+ struct prefix g_all;
+ struct rp_info *rp_all;
+ struct pim_upstream *up;
+ struct rp_info *rp_info;
+ bool upstream_updated = false;
+
+ if (pim->global_scope.current_bsr.s_addr)
+ pim_nht_bsr_del(pim, pim->global_scope.current_bsr);
+
+ /* Reset scope zone data */
+ pim->global_scope.accept_nofwd_bsm = false;
+ pim->global_scope.state = ACCEPT_ANY;
+ pim->global_scope.current_bsr.s_addr = INADDR_ANY;
+ pim->global_scope.current_bsr_prio = 0;
+ pim->global_scope.current_bsr_first_ts = 0;
+ pim->global_scope.current_bsr_last_ts = 0;
+ pim->global_scope.bsm_frag_tag = 0;
+ pim_bsm_frags_free(&pim->global_scope);
+
+ pim_bs_timer_stop(&pim->global_scope);
+
+ for (rn = route_top(pim->global_scope.bsrp_table); rn;
+ rn = route_next(rn)) {
+ bsgrp = rn->info;
+ if (!bsgrp)
+ continue;
+
+ rpnode = route_node_lookup(pim->rp_table, &bsgrp->group);
+
+ if (!rpnode) {
+ pim_free_bsgrp_node(bsgrp->scope->bsrp_table,
+ &bsgrp->group);
+ pim_free_bsgrp_data(bsgrp);
+ continue;
+ }
+
+ rp_info = (struct rp_info *)rpnode->info;
+
+ if ((!rp_info) || (rp_info->rp_src != RP_SRC_BSR)) {
+ pim_free_bsgrp_node(bsgrp->scope->bsrp_table,
+ &bsgrp->group);
+ pim_free_bsgrp_data(bsgrp);
+ continue;
+ }
+
+ /* Deregister addr with Zebra NHT */
+ nht_p.family = AF_INET;
+ nht_p.prefixlen = IPV4_MAX_BITLEN;
+ nht_p.u.prefix4 = rp_info->rp.rpf_addr.u.prefix4;
+
+ if (PIM_DEBUG_PIM_NHT_RP) {
+ zlog_debug("%s: Deregister RP addr %pFX with Zebra ",
+ __func__, &nht_p);
+ }
+
+ pim_delete_tracked_nexthop(pim, &nht_p, NULL, rp_info);
+
+ if (!str2prefix("224.0.0.0/4", &g_all))
+ return;
+
+ rp_all = pim_rp_find_match_group(pim, &g_all);
+
+ if (rp_all == rp_info) {
+ rp_all->rp.rpf_addr.family = AF_INET;
+ rp_all->rp.rpf_addr.u.prefix4.s_addr = INADDR_NONE;
+ rp_all->i_am_rp = 0;
+ } else {
+ /* Delete the rp_info from rp-list */
+ listnode_delete(pim->rp_list, rp_info);
+
+ /* Delete the rp node from rp_table */
+ rpnode->info = NULL;
+ route_unlock_node(rpnode);
+ route_unlock_node(rpnode);
+ XFREE(MTYPE_PIM_RP, rp_info);
+ }
+
+ pim_free_bsgrp_node(bsgrp->scope->bsrp_table, &bsgrp->group);
+ pim_free_bsgrp_data(bsgrp);
+ }
+ pim_rp_refresh_group_to_rp_mapping(pim);
+
+
+ frr_each (rb_pim_upstream, &pim->upstream_head, up) {
+ /* Find the upstream (*, G) whose upstream address is same as
+ * the RP
+ */
+ if (up->sg.src.s_addr != INADDR_ANY)
+ continue;
+
+ struct prefix grp;
+ struct rp_info *trp_info;
+
+ grp.family = AF_INET;
+ grp.prefixlen = IPV4_MAX_BITLEN;
+ grp.u.prefix4 = up->sg.grp;
+
+ trp_info = pim_rp_find_match_group(pim, &grp);
+
+ /* RP not found for the group grp */
+ if (pim_rpf_addr_is_inaddr_none(&trp_info->rp)) {
+ pim_upstream_rpf_clear(pim, up);
+ pim_rp_set_upstream_addr(pim, &up->upstream_addr,
+ up->sg.src, up->sg.grp);
+ } else {
+ /* RP found for the group grp */
+ pim_upstream_update(pim, up);
+ upstream_updated = true;
+ }
+ }
+
+ if (upstream_updated)
+ pim_zebra_update_all_interfaces(pim);
+}
+
static bool pim_bsm_send_intf(uint8_t *buf, int len, struct interface *ifp,
struct in_addr dst_addr)
{
@@ -1115,18 +1174,6 @@ static bool pim_bsm_parse_install_g2rp(struct bsm_scope *scope, uint8_t *buf,
buf += sizeof(struct bsmmsg_grpinfo);
offset += sizeof(struct bsmmsg_grpinfo);
- if (grpinfo.rp_count == 0) {
- if (PIM_DEBUG_BSM) {
- char grp_str[INET_ADDRSTRLEN];
-
- pim_inet4_dump("<Group?>", grpinfo.group.addr,
- grp_str, sizeof(grp_str));
- zlog_debug("%s, Rp count is zero for group: %s",
- __func__, grp_str);
- }
- return false;
- }
-
group.family = AF_INET;
if (grpinfo.group.mask > IPV4_MAX_BITLEN) {
if (PIM_DEBUG_BSM)
@@ -1141,6 +1188,32 @@ static bool pim_bsm_parse_install_g2rp(struct bsm_scope *scope, uint8_t *buf,
/* Get the Group node for the BSM rp table */
bsgrp = pim_bsm_get_bsgrp_node(scope, &group);
+ if (grpinfo.rp_count == 0) {
+ struct bsm_rpinfo *old_rpinfo;
+
+ /* BSR explicitly no longer has RPs for this group */
+ if (!bsgrp)
+ continue;
+
+ if (PIM_DEBUG_BSM) {
+ char grp_str[INET_ADDRSTRLEN];
+
+ pim_inet4_dump("<Group?>", grpinfo.group.addr,
+ grp_str, sizeof(grp_str));
+ zlog_debug("%s, Rp count is zero for group: %s",
+ __func__, grp_str);
+ }
+
+ old_rpinfo = bsm_rpinfos_first(bsgrp->bsrp_list);
+ if (old_rpinfo)
+ pim_rp_del(scope->pim, old_rpinfo->rp_address,
+ group, NULL, RP_SRC_BSR);
+
+ pim_free_bsgrp_node(scope->bsrp_table, &bsgrp->group);
+ pim_free_bsgrp_data(bsgrp);
+ continue;
+ }
+
if (!bsgrp) {
if (PIM_DEBUG_BSM)
zlog_debug("%s, Create new BSM Group node.",
@@ -1310,21 +1383,23 @@ int pim_bsm_process(struct interface *ifp, struct ip *ip_hdr, uint8_t *buf,
}
}
- /* Mulicast BSM received */
if (ip_hdr->ip_dst.s_addr == qpim_all_pim_routers_addr.s_addr) {
- if (!no_fwd) {
- if (!pim_bsr_rpf_check(pim, bshdr->bsr_addr.addr,
- ip_hdr->ip_src)) {
- if (PIM_DEBUG_BSM)
- zlog_debug(
- "%s : RPF check fail for BSR address %s",
- __func__, bsr_str);
- pim->bsm_dropped++;
- return -1;
- }
+ /* Multicast BSMs are only accepted if source interface & IP
+ * match RPF towards the BSR's IP address, or they have
+ * no-forward set
+ */
+ if (!no_fwd
+ && !pim_nht_bsr_rpf_check(pim, bshdr->bsr_addr.addr, ifp,
+ ip_hdr->ip_src)) {
+ if (PIM_DEBUG_BSM)
+ zlog_debug(
+ "BSM check: RPF to BSR %s is not %pI4%%%s",
+ bsr_str, &ip_hdr->ip_src, ifp->name);
+ pim->bsm_dropped++;
+ return -1;
}
- } else if (if_lookup_exact_address(&ip_hdr->ip_dst, AF_INET,
- pim->vrf->vrf_id)) {
+ } else if (if_address_is_local(&ip_hdr->ip_dst, AF_INET,
+ pim->vrf->vrf_id)) {
/* Unicast BSM received - if ucast bsm not enabled on
* the interface, drop it
*/
diff --git a/pimd/pim_bsm.h b/pimd/pim_bsm.h
index dbfeeceec..a536b5068 100644
--- a/pimd/pim_bsm.h
+++ b/pimd/pim_bsm.h
@@ -205,6 +205,7 @@ struct bsmmsg_rpinfo {
/* API */
void pim_bsm_proc_init(struct pim_instance *pim);
void pim_bsm_proc_free(struct pim_instance *pim);
+void pim_bsm_clear(struct pim_instance *pim);
void pim_bsm_write_config(struct vty *vty, struct interface *ifp);
int pim_bsm_process(struct interface *ifp,
struct ip *ip_hdr,
@@ -214,9 +215,4 @@ int pim_bsm_process(struct interface *ifp,
bool pim_bsm_new_nbr_fwd(struct pim_neighbor *neigh, struct interface *ifp);
struct bsgrp_node *pim_bsm_get_bsgrp_node(struct bsm_scope *scope,
struct prefix *grp);
-void pim_bs_timer_stop(struct bsm_scope *scope);
-void pim_bsm_frags_free(struct bsm_scope *scope);
-void pim_bsm_rpinfos_free(struct bsm_rpinfos_head *head);
-void pim_free_bsgrp_data(struct bsgrp_node *bsgrp_node);
-void pim_free_bsgrp_node(struct route_table *rt, struct prefix *grp);
#endif
diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c
index 4cd94e0df..501d69dbf 100644
--- a/pimd/pim_cmd.c
+++ b/pimd/pim_cmd.c
@@ -308,14 +308,12 @@ static void json_object_pim_ifp_add(struct json_object *json,
struct interface *ifp)
{
struct pim_interface *pim_ifp;
- char buf[PREFIX_STRLEN];
pim_ifp = ifp->info;
json_object_string_add(json, "name", ifp->name);
json_object_string_add(json, "state", if_is_up(ifp) ? "up" : "down");
- json_object_string_add(json, "address",
- inet_ntop(AF_INET, &pim_ifp->primary_address,
- buf, sizeof(buf)));
+ json_object_string_addf(json, "address", "%pI4",
+ &pim_ifp->primary_address);
json_object_int_add(json, "index", ifp->ifindex);
if (if_is_multicast(ifp))
@@ -489,7 +487,6 @@ static void igmp_show_interfaces(struct pim_instance *pim, struct vty *vty,
struct interface *ifp;
time_t now;
char buf[PREFIX_STRLEN];
- char quer_buf[PREFIX_STRLEN];
json_object *json = NULL;
json_object *json_row = NULL;
@@ -537,10 +534,9 @@ static void igmp_show_interfaces(struct pim_instance *pim, struct vty *vty,
"queryTimer",
query_hhmmss);
}
- json_object_string_add(
- json_row, "querierIp",
- inet_ntop(AF_INET, &igmp->querier_addr,
- quer_buf, sizeof(quer_buf)));
+ json_object_string_addf(json_row, "querierIp",
+ "%pI4",
+ &igmp->querier_addr);
json_object_object_add(json, ifp->name,
json_row);
@@ -584,7 +580,6 @@ static void igmp_show_interfaces_single(struct pim_instance *pim,
struct listnode *sock_node;
struct pim_interface *pim_ifp;
char uptime[10];
- char quer_buf[PREFIX_STRLEN];
char query_hhmmss[10];
char other_hhmmss[10];
int found_ifname = 0;
@@ -669,10 +664,9 @@ static void igmp_show_interfaces_single(struct pim_instance *pim,
igmp->t_igmp_query_timer
? "local"
: "other");
- json_object_string_add(
- json_row, "querierIp",
- inet_ntop(AF_INET, &igmp->querier_addr,
- quer_buf, sizeof(quer_buf)));
+ json_object_string_addf(json_row, "querierIp",
+ "%pI4",
+ &igmp->querier_addr);
json_object_int_add(json_row, "queryStartCount",
igmp->startup_query_count);
json_object_string_add(json_row,
@@ -928,7 +922,6 @@ static void pim_show_interfaces_single(struct pim_instance *pim,
int mloop = 0;
int found_ifname = 0;
int print_header;
- char buf[PREFIX_STRLEN];
json_object *json = NULL;
json_object *json_row = NULL;
json_object *json_pim_neighbor = NULL;
@@ -979,11 +972,9 @@ static void pim_show_interfaces_single(struct pim_instance *pim,
json_object_pim_ifp_add(json_row, ifp);
if (pim_ifp->update_source.s_addr != INADDR_ANY) {
- json_object_string_add(
- json_row, "useSource",
- inet_ntop(AF_INET,
- &pim_ifp->update_source,
- buf, sizeof(buf)));
+ json_object_string_addf(
+ json_row, "useSource", "%pI4",
+ &pim_ifp->update_source);
}
if (pim_ifp->sec_addr_list) {
json_object *sec_list = NULL;
@@ -1407,7 +1398,6 @@ static void pim_show_interfaces(struct pim_instance *pim, struct vty *vty,
int fhr = 0;
int pim_nbrs = 0;
int pim_ifchannels = 0;
- char buf[PREFIX_STRLEN];
json_object *json = NULL;
json_object *json_row = NULL;
json_object *json_tmp;
@@ -1437,10 +1427,8 @@ static void pim_show_interfaces(struct pim_instance *pim, struct vty *vty,
json_object_int_add(json_row, "pimNeighbors", pim_nbrs);
json_object_int_add(json_row, "pimIfChannels", pim_ifchannels);
json_object_int_add(json_row, "firstHopRouterCount", fhr);
- json_object_string_add(json_row, "pimDesignatedRouter",
- inet_ntop(AF_INET,
- &pim_ifp->pim_dr_addr, buf,
- sizeof(buf)));
+ json_object_string_addf(json_row, "pimDesignatedRouter", "%pI4",
+ &pim_ifp->pim_dr_addr);
if (pim_ifp->pim_dr_addr.s_addr
== pim_ifp->primary_address.s_addr)
@@ -2446,8 +2434,6 @@ static const char *pim_reg_state2brief_str(enum pim_reg_state reg_state,
case PIM_REG_PRUNE:
strlcpy(state_str, "RegP", state_str_len);
break;
- default:
- strlcpy(state_str, "Unk", state_str_len);
}
return state_str;
}
@@ -4053,131 +4039,6 @@ DEFUN (clear_ip_pim_oil,
return CMD_SUCCESS;
}
-static void clear_pim_bsr_db(struct pim_instance *pim)
-{
- struct route_node *rn;
- struct route_node *rpnode;
- struct bsgrp_node *bsgrp;
- struct prefix nht_p;
- struct prefix g_all;
- struct rp_info *rp_all;
- struct pim_upstream *up;
- struct rp_info *rp_info;
- bool is_bsr_tracking = true;
-
- /* Remove next hop tracking for the bsr */
- nht_p.family = AF_INET;
- nht_p.prefixlen = IPV4_MAX_BITLEN;
- nht_p.u.prefix4 = pim->global_scope.current_bsr;
- if (PIM_DEBUG_BSM) {
- zlog_debug("%s: Deregister BSR addr %pFX with Zebra NHT",
- __func__, &nht_p);
- }
- pim_delete_tracked_nexthop(pim, &nht_p, NULL, NULL, is_bsr_tracking);
-
- /* Reset scope zone data */
- pim->global_scope.accept_nofwd_bsm = false;
- pim->global_scope.state = ACCEPT_ANY;
- pim->global_scope.current_bsr.s_addr = INADDR_ANY;
- pim->global_scope.current_bsr_prio = 0;
- pim->global_scope.current_bsr_first_ts = 0;
- pim->global_scope.current_bsr_last_ts = 0;
- pim->global_scope.bsm_frag_tag = 0;
- pim_bsm_frags_free(&pim->global_scope);
-
- pim_bs_timer_stop(&pim->global_scope);
-
- for (rn = route_top(pim->global_scope.bsrp_table); rn;
- rn = route_next(rn)) {
- bsgrp = rn->info;
- if (!bsgrp)
- continue;
-
- rpnode = route_node_lookup(pim->rp_table, &bsgrp->group);
-
- if (!rpnode) {
- pim_free_bsgrp_node(bsgrp->scope->bsrp_table,
- &bsgrp->group);
- pim_free_bsgrp_data(bsgrp);
- continue;
- }
-
- rp_info = (struct rp_info *)rpnode->info;
-
- if ((!rp_info) || (rp_info->rp_src != RP_SRC_BSR)) {
- pim_free_bsgrp_node(bsgrp->scope->bsrp_table,
- &bsgrp->group);
- pim_free_bsgrp_data(bsgrp);
- continue;
- }
-
- /* Deregister addr with Zebra NHT */
- nht_p.family = AF_INET;
- nht_p.prefixlen = IPV4_MAX_BITLEN;
- nht_p.u.prefix4 = rp_info->rp.rpf_addr.u.prefix4;
-
- if (PIM_DEBUG_PIM_NHT_RP) {
- zlog_debug("%s: Deregister RP addr %pFX with Zebra ",
- __func__, &nht_p);
- }
-
- pim_delete_tracked_nexthop(pim, &nht_p, NULL, rp_info, false);
-
- if (!str2prefix("224.0.0.0/4", &g_all))
- return;
-
- rp_all = pim_rp_find_match_group(pim, &g_all);
-
- if (rp_all == rp_info) {
- rp_all->rp.rpf_addr.family = AF_INET;
- rp_all->rp.rpf_addr.u.prefix4.s_addr = INADDR_NONE;
- rp_all->i_am_rp = 0;
- } else {
- /* Delete the rp_info from rp-list */
- listnode_delete(pim->rp_list, rp_info);
-
- /* Delete the rp node from rp_table */
- rpnode->info = NULL;
- route_unlock_node(rpnode);
- route_unlock_node(rpnode);
- XFREE(MTYPE_PIM_RP, rp_info);
- }
-
- pim_free_bsgrp_node(bsgrp->scope->bsrp_table, &bsgrp->group);
- pim_free_bsgrp_data(bsgrp);
- }
- pim_rp_refresh_group_to_rp_mapping(pim);
-
-
- frr_each (rb_pim_upstream, &pim->upstream_head, up) {
- /* Find the upstream (*, G) whose upstream address is same as
- * the RP
- */
- if (up->sg.src.s_addr != INADDR_ANY)
- continue;
-
- struct prefix grp;
- struct rp_info *trp_info;
-
- grp.family = AF_INET;
- grp.prefixlen = IPV4_MAX_BITLEN;
- grp.u.prefix4 = up->sg.grp;
-
- trp_info = pim_rp_find_match_group(pim, &grp);
-
- /* RP not found for the group grp */
- if (pim_rpf_addr_is_inaddr_none(&trp_info->rp)) {
- pim_upstream_rpf_clear(pim, up);
- pim_rp_set_upstream_addr(pim, &up->upstream_addr,
- up->sg.src, up->sg.grp);
- } else {
- /* RP found for the group grp */
- pim_upstream_update(pim, up);
- }
- }
-}
-
-
DEFUN (clear_ip_pim_bsr_db,
clear_ip_pim_bsr_db_cmd,
"clear ip pim [vrf NAME] bsr-data",
@@ -4193,7 +4054,7 @@ DEFUN (clear_ip_pim_bsr_db,
if (!vrf)
return CMD_WARNING;
- clear_pim_bsr_db(vrf->info);
+ pim_bsm_clear(vrf->info);
return CMD_SUCCESS;
}
@@ -5842,10 +5703,8 @@ static void show_multicast_interfaces(struct pim_instance *pim, struct vty *vty,
json_object_string_add(json_row, "name", ifp->name);
json_object_string_add(json_row, "state",
if_is_up(ifp) ? "up" : "down");
- json_object_string_add(
- json_row, "address",
- inet_ntop(AF_INET, &pim_ifp->primary_address,
- buf, sizeof(buf)));
+ json_object_string_addf(json_row, "address", "%pI4",
+ &pim_ifp->primary_address);
json_object_int_add(json_row, "ifIndex", ifp->ifindex);
json_object_int_add(json_row, "vif",
pim_ifp->mroute_vif_index);
diff --git a/pimd/pim_ifchannel.c b/pimd/pim_ifchannel.c
index 86f897aed..3163f7f54 100644
--- a/pimd/pim_ifchannel.c
+++ b/pimd/pim_ifchannel.c
@@ -651,18 +651,17 @@ struct pim_ifchannel *pim_ifchannel_add(struct interface *ifp,
return ch;
}
-static void ifjoin_to_noinfo(struct pim_ifchannel *ch, bool ch_del)
+static void ifjoin_to_noinfo(struct pim_ifchannel *ch)
{
- pim_forward_stop(ch, !ch_del);
pim_ifchannel_ifjoin_switch(__func__, ch, PIM_IFJOIN_NOINFO);
+ pim_forward_stop(ch);
if (ch->upstream)
PIM_UPSTREAM_FLAG_UNSET_SRC_PIM(ch->upstream->flags);
PIM_IF_FLAG_UNSET_PROTO_PIM(ch->flags);
- if (ch_del)
- delete_on_noinfo(ch);
+ delete_on_noinfo(ch);
}
static int on_ifjoin_expiry_timer(struct thread *t)
@@ -675,7 +674,7 @@ static int on_ifjoin_expiry_timer(struct thread *t)
zlog_debug("%s: ifchannel %s expiry timer", __func__,
ch->sg_str);
- ifjoin_to_noinfo(ch, true);
+ ifjoin_to_noinfo(ch);
/* ch may have been deleted */
return 0;
@@ -714,7 +713,7 @@ static int on_ifjoin_prune_pending_timer(struct thread *t)
&rpf, ch->upstream, 0);
}
- ifjoin_to_noinfo(ch, true);
+ ifjoin_to_noinfo(ch);
} else {
/* If SGRpt flag is set on ifchannel, Trigger SGRpt
* message on RP path upon prune timer expiry.
diff --git a/pimd/pim_igmp.c b/pimd/pim_igmp.c
index 795c96c83..cd905b3cb 100644
--- a/pimd/pim_igmp.c
+++ b/pimd/pim_igmp.c
@@ -324,7 +324,7 @@ static int igmp_recv_query(struct igmp_sock *igmp, int query_version,
return 0;
}
- if (if_lookup_exact_address(&from, AF_INET, ifp->vrf_id)) {
+ if (if_address_is_local(&from, AF_INET, ifp->vrf_id)) {
if (PIM_DEBUG_IGMP_PACKETS)
zlog_debug("Recv IGMP query on interface: %s from ourself %s",
ifp->name, from_str);
diff --git a/pimd/pim_igmp_mtrace.c b/pimd/pim_igmp_mtrace.c
index 73af44fc4..42101bc48 100644
--- a/pimd/pim_igmp_mtrace.c
+++ b/pimd/pim_igmp_mtrace.c
@@ -596,8 +596,8 @@ int igmp_mtrace_recv_qry_req(struct igmp_sock *igmp, struct ip *ip_hdr,
* if applicable
*/
if (!IPV4_CLASS_DE(ntohl(ip_hdr->ip_dst.s_addr)))
- if (!if_lookup_exact_address(&ip_hdr->ip_dst, AF_INET,
- pim->vrf->vrf_id))
+ if (!if_address_is_local(&ip_hdr->ip_dst, AF_INET,
+ pim->vrf->vrf_id))
return mtrace_forward_packet(pim, ip_hdr);
if (igmp_msg_len < (int)sizeof(struct igmp_mtrace)) {
diff --git a/pimd/pim_join.c b/pimd/pim_join.c
index c7a80ca8e..4606aec6a 100644
--- a/pimd/pim_join.c
+++ b/pimd/pim_join.c
@@ -1,3 +1,5 @@
+
+
/*
* PIM for Quagga
* Copyright (C) 2008 Everton da Silva Marques
@@ -39,6 +41,7 @@
#include "pim_rp.h"
#include "pim_jp_agg.h"
#include "pim_util.h"
+#include "pim_ssm.h"
static void on_trace(const char *label, struct interface *ifp,
struct in_addr src)
@@ -105,6 +108,13 @@ static void recv_join(struct interface *ifp, struct pim_neighbor *neigh,
return;
}
+ if (pim_is_grp_ssm(pim_ifp->pim, sg->grp)) {
+ zlog_warn(
+ "%s: Specified Group(%pI4) in join is now in SSM, not allowed to create PIM state",
+ __func__, &sg->grp);
+ return;
+ }
+
sg->src.s_addr = INADDR_ANY;
}
diff --git a/pimd/pim_jp_agg.c b/pimd/pim_jp_agg.c
index d95d9dd25..5c6f55e99 100644
--- a/pimd/pim_jp_agg.c
+++ b/pimd/pim_jp_agg.c
@@ -368,7 +368,7 @@ void pim_jp_agg_single_upstream_send(struct pim_rpf *rpf,
if (!up || !rpf->source_nexthop.interface ||
pim_if_connected_to_source(rpf->source_nexthop.interface,
up->sg.src) ||
- if_is_loopback_or_vrf(rpf->source_nexthop.interface))
+ if_is_loopback(rpf->source_nexthop.interface))
return;
memset(&groups, 0, sizeof(groups));
diff --git a/pimd/pim_msdp.c b/pimd/pim_msdp.c
index ddba33ff9..fa7f1da79 100644
--- a/pimd/pim_msdp.c
+++ b/pimd/pim_msdp.c
@@ -1304,7 +1304,6 @@ int pim_msdp_config_write(struct pim_instance *pim, struct vty *vty,
struct pim_msdp_mg *mg;
struct listnode *mbrnode;
struct pim_msdp_mg_mbr *mbr;
- char mbr_str[INET_ADDRSTRLEN];
char src_str[INET_ADDRSTRLEN];
int count = 0;
@@ -1321,10 +1320,8 @@ int pim_msdp_config_write(struct pim_instance *pim, struct vty *vty,
}
for (ALL_LIST_ELEMENTS_RO(mg->mbr_list, mbrnode, mbr)) {
- pim_inet4_dump("<mbr?>", mbr->mbr_ip, mbr_str,
- sizeof(mbr_str));
- vty_out(vty, "%sip msdp mesh-group %s member %s\n",
- spaces, mg->mesh_group_name, mbr_str);
+ vty_out(vty, "%sip msdp mesh-group %s member %pI4\n",
+ spaces, mg->mesh_group_name, &mbr->mbr_ip);
++count;
}
}
diff --git a/pimd/pim_msdp_packet.h b/pimd/pim_msdp_packet.h
index f5af8d114..10b7ca419 100644
--- a/pimd/pim_msdp_packet.h
+++ b/pimd/pim_msdp_packet.h
@@ -58,7 +58,8 @@
* fragmentation */
#define PIM_MSDP_SA_MAX_ENTRY_CNT 120
-#define PIM_MSDP_MAX_PACKET_SIZE max(PIM_MSDP_SA_TLV_MAX_SIZE, PIM_MSDP_KA_TLV_MAX_SIZE)
+#define PIM_MSDP_MAX_PACKET_SIZE \
+ MAX(PIM_MSDP_SA_TLV_MAX_SIZE, PIM_MSDP_KA_TLV_MAX_SIZE)
#define PIM_MSDP_PKT_TYPE_STRLEN 16
diff --git a/pimd/pim_nht.c b/pimd/pim_nht.c
index 50cfc297d..cd6f4c45f 100644
--- a/pimd/pim_nht.c
+++ b/pimd/pim_nht.c
@@ -110,22 +110,11 @@ static struct pim_nexthop_cache *pim_nexthop_cache_add(struct pim_instance *pim,
return pnc;
}
-/*
- * pim_find_or_track_nexthop
- *
- * This API is used to Register an address with Zebra
- *
- * 1 -> Success
- * 0 -> Failure
- */
-int pim_find_or_track_nexthop(struct pim_instance *pim, struct prefix *addr,
- struct pim_upstream *up, struct rp_info *rp,
- bool bsr_track_needed,
- struct pim_nexthop_cache *out_pnc)
+static struct pim_nexthop_cache *pim_nht_get(struct pim_instance *pim,
+ struct prefix *addr)
{
struct pim_nexthop_cache *pnc = NULL;
struct pim_rpf rpf;
- struct listnode *ch_node = NULL;
struct zclient *zclient = NULL;
zclient = pim_zebra_zclient_get();
@@ -145,6 +134,23 @@ int pim_find_or_track_nexthop(struct pim_instance *pim, struct prefix *addr,
__func__, addr, pim->vrf->name);
}
+ return pnc;
+}
+
+/* TBD: this does several distinct things and should probably be split up.
+ * (checking state vs. returning pnc vs. adding upstream vs. adding rp)
+ */
+int pim_find_or_track_nexthop(struct pim_instance *pim, struct prefix *addr,
+ struct pim_upstream *up, struct rp_info *rp,
+ struct pim_nexthop_cache *out_pnc)
+{
+ struct pim_nexthop_cache *pnc;
+ struct listnode *ch_node = NULL;
+
+ pnc = pim_nht_get(pim, addr);
+
+ assertf(up || rp, "addr=%pFX", addr);
+
if (rp != NULL) {
ch_node = listnode_lookup(pnc->rp_list, rp);
if (ch_node == NULL)
@@ -154,9 +160,6 @@ int pim_find_or_track_nexthop(struct pim_instance *pim, struct prefix *addr,
if (up != NULL)
hash_get(pnc->upstream_hash, up, hash_alloc_intern);
- if (bsr_track_needed)
- pnc->bsr_tracking = true;
-
if (CHECK_FLAG(pnc->flags, PIM_NEXTHOP_VALID)) {
if (out_pnc)
memcpy(out_pnc, pnc, sizeof(struct pim_nexthop_cache));
@@ -166,232 +169,226 @@ int pim_find_or_track_nexthop(struct pim_instance *pim, struct prefix *addr,
return 0;
}
+void pim_nht_bsr_add(struct pim_instance *pim, struct in_addr addr)
+{
+ struct pim_nexthop_cache *pnc;
+ struct prefix pfx;
+
+ pfx.family = AF_INET;
+ pfx.prefixlen = IPV4_MAX_BITLEN;
+ pfx.u.prefix4 = addr;
+
+ pnc = pim_nht_get(pim, &pfx);
+
+ pnc->bsr_count++;
+}
+
+static void pim_nht_drop_maybe(struct pim_instance *pim,
+ struct pim_nexthop_cache *pnc)
+{
+ if (PIM_DEBUG_PIM_NHT)
+ zlog_debug(
+ "%s: NHT %pFX(%s) rp_list count:%d upstream count:%ld BSR count:%u",
+ __func__, &pnc->rpf.rpf_addr, pim->vrf->name,
+ pnc->rp_list->count, pnc->upstream_hash->count,
+ pnc->bsr_count);
+
+ if (pnc->rp_list->count == 0 && pnc->upstream_hash->count == 0
+ && pnc->bsr_count == 0) {
+ struct zclient *zclient = pim_zebra_zclient_get();
+
+ pim_sendmsg_zebra_rnh(pim, zclient, pnc,
+ ZEBRA_NEXTHOP_UNREGISTER);
+
+ list_delete(&pnc->rp_list);
+ hash_free(pnc->upstream_hash);
+
+ hash_release(pim->rpf_hash, pnc);
+ if (pnc->nexthop)
+ nexthops_free(pnc->nexthop);
+ XFREE(MTYPE_PIM_NEXTHOP_CACHE, pnc);
+ }
+}
+
void pim_delete_tracked_nexthop(struct pim_instance *pim, struct prefix *addr,
- struct pim_upstream *up, struct rp_info *rp,
- bool del_bsr_tracking)
+ struct pim_upstream *up, struct rp_info *rp)
{
struct pim_nexthop_cache *pnc = NULL;
struct pim_nexthop_cache lookup;
- struct zclient *zclient = NULL;
struct pim_upstream *upstream = NULL;
- zclient = pim_zebra_zclient_get();
-
/* Remove from RPF hash if it is the last entry */
lookup.rpf.rpf_addr = *addr;
pnc = hash_lookup(pim->rpf_hash, &lookup);
- if (pnc) {
- if (rp) {
- /* Release the (*, G)upstream from pnc->upstream_hash,
- * whose Group belongs to the RP getting deleted
- */
- frr_each (rb_pim_upstream, &pim->upstream_head,
- upstream) {
- struct prefix grp;
- struct rp_info *trp_info;
-
- if (upstream->sg.src.s_addr != INADDR_ANY)
- continue;
-
- grp.family = AF_INET;
- grp.prefixlen = IPV4_MAX_BITLEN;
- grp.u.prefix4 = upstream->sg.grp;
-
- trp_info = pim_rp_find_match_group(pim, &grp);
- if (trp_info == rp)
- hash_release(pnc->upstream_hash,
- upstream);
- }
- listnode_delete(pnc->rp_list, rp);
- }
+ if (!pnc) {
+ zlog_warn("attempting to delete nonexistent NHT entry %pFX",
+ addr);
+ return;
+ }
- if (up)
- hash_release(pnc->upstream_hash, up);
+ if (rp) {
+ /* Release the (*, G)upstream from pnc->upstream_hash,
+ * whose Group belongs to the RP getting deleted
+ */
+ frr_each (rb_pim_upstream, &pim->upstream_head, upstream) {
+ struct prefix grp;
+ struct rp_info *trp_info;
- if (del_bsr_tracking)
- pnc->bsr_tracking = false;
+ if (upstream->sg.src.s_addr != INADDR_ANY)
+ continue;
- if (PIM_DEBUG_PIM_NHT)
- zlog_debug(
- "%s: NHT %pFX(%s) rp_list count:%d upstream count:%ld",
- __func__, addr, pim->vrf->name,
- pnc->rp_list->count, pnc->upstream_hash->count);
-
- if (pnc->rp_list->count == 0
- && pnc->upstream_hash->count == 0
- && pnc->bsr_tracking == false) {
- pim_sendmsg_zebra_rnh(pim, zclient, pnc,
- ZEBRA_NEXTHOP_UNREGISTER);
-
- list_delete(&pnc->rp_list);
- hash_free(pnc->upstream_hash);
-
- hash_release(pim->rpf_hash, pnc);
- if (pnc->nexthop)
- nexthops_free(pnc->nexthop);
- XFREE(MTYPE_PIM_NEXTHOP_CACHE, pnc);
+ grp.family = AF_INET;
+ grp.prefixlen = IPV4_MAX_BITLEN;
+ grp.u.prefix4 = upstream->sg.grp;
+
+ trp_info = pim_rp_find_match_group(pim, &grp);
+ if (trp_info == rp)
+ hash_release(pnc->upstream_hash, upstream);
}
+ listnode_delete(pnc->rp_list, rp);
}
+
+ if (up)
+ hash_release(pnc->upstream_hash, up);
+
+ pim_nht_drop_maybe(pim, pnc);
}
-/* Given a source address and a neighbor address, check if the neighbor is one
- * of the next hop to reach the source. search from zebra route database
- */
-bool pim_nexthop_match(struct pim_instance *pim, struct in_addr addr,
- struct in_addr ip_src)
+void pim_nht_bsr_del(struct pim_instance *pim, struct in_addr addr)
{
- struct pim_zlookup_nexthop nexthop_tab[MULTIPATH_NUM];
- int i = 0;
- ifindex_t first_ifindex = 0;
- struct interface *ifp = NULL;
- struct pim_neighbor *nbr = NULL;
- int num_ifindex;
+ struct pim_nexthop_cache *pnc = NULL;
+ struct pim_nexthop_cache lookup;
- if (addr.s_addr == INADDR_NONE)
- return false;
+ lookup.rpf.rpf_addr.family = AF_INET;
+ lookup.rpf.rpf_addr.prefixlen = IPV4_MAX_BITLEN;
+ lookup.rpf.rpf_addr.u.prefix4 = addr;
- memset(nexthop_tab, 0,
- sizeof(struct pim_zlookup_nexthop) * MULTIPATH_NUM);
- num_ifindex = zclient_lookup_nexthop(pim, nexthop_tab, MULTIPATH_NUM,
- addr, PIM_NEXTHOP_LOOKUP_MAX);
- if (num_ifindex < 1) {
- char addr_str[INET_ADDRSTRLEN];
+ pnc = hash_lookup(pim->rpf_hash, &lookup);
- pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
- zlog_warn(
- "%s %s: could not find nexthop ifindex for address %s",
- __FILE__, __func__, addr_str);
- return false;
+ if (!pnc) {
+ zlog_warn("attempting to delete nonexistent NHT BSR entry %pI4",
+ &addr);
+ return;
}
- while (i < num_ifindex) {
- first_ifindex = nexthop_tab[i].ifindex;
+ assertf(pnc->bsr_count > 0, "addr=%pI4", &addr);
+ pnc->bsr_count--;
- ifp = if_lookup_by_index(first_ifindex, pim->vrf->vrf_id);
- if (!ifp) {
- if (PIM_DEBUG_ZEBRA) {
- char addr_str[INET_ADDRSTRLEN];
+ pim_nht_drop_maybe(pim, pnc);
+}
- pim_inet4_dump("<addr?>", addr, addr_str,
- sizeof(addr_str));
- zlog_debug(
- "%s %s: could not find interface for ifindex %d (address %s)",
- __FILE__, __func__, first_ifindex,
- addr_str);
- }
- i++;
- continue;
- }
+bool pim_nht_bsr_rpf_check(struct pim_instance *pim, struct in_addr bsr_addr,
+ struct interface *src_ifp, struct in_addr src_ip)
+{
+ struct pim_nexthop_cache *pnc = NULL;
+ struct pim_nexthop_cache lookup;
+ struct pim_neighbor *nbr = NULL;
+ struct nexthop *nh;
+ struct interface *ifp;
- if (!ifp->info) {
- if (PIM_DEBUG_ZEBRA) {
- char addr_str[INET_ADDRSTRLEN];
+ lookup.rpf.rpf_addr.family = AF_INET;
+ lookup.rpf.rpf_addr.prefixlen = IPV4_MAX_BITLEN;
+ lookup.rpf.rpf_addr.u.prefix4 = bsr_addr;
- pim_inet4_dump("<addr?>", addr, addr_str,
- sizeof(addr_str));
- zlog_debug(
- "%s: multicast not enabled on input interface %s (ifindex=%d, RPF for source %s)",
- __func__, ifp->name, first_ifindex,
- addr_str);
- }
- i++;
- continue;
- }
+ pnc = hash_lookup(pim->rpf_hash, &lookup);
+ if (!pnc || !CHECK_FLAG(pnc->flags, PIM_NEXTHOP_ANSWER_RECEIVED)) {
+ /* BSM from a new freshly registered BSR - do a synchronous
+ * zebra query since otherwise we'd drop the first packet,
+ * leading to additional delay in picking up BSM data
+ */
- if (!pim_if_connected_to_source(ifp, addr)) {
- nbr = pim_neighbor_find(
- ifp, nexthop_tab[i].nexthop_addr.u.prefix4);
- if (PIM_DEBUG_PIM_TRACE_DETAIL)
- zlog_debug("ifp name: %s, pim nbr: %p",
- ifp->name, nbr);
- if (!nbr && !if_is_loopback(ifp)) {
- i++;
+ /* FIXME: this should really be moved into a generic NHT
+ * function that does "add and get immediate result" or maybe
+ * "check cache or get immediate result." But until that can
+ * be worked in, here's a copy of the code below :(
+ */
+ struct pim_zlookup_nexthop nexthop_tab[MULTIPATH_NUM];
+ ifindex_t i;
+ struct interface *ifp = NULL;
+ int num_ifindex;
+
+ memset(nexthop_tab, 0, sizeof(nexthop_tab));
+ num_ifindex = zclient_lookup_nexthop(pim, nexthop_tab,
+ MULTIPATH_NUM, bsr_addr,
+ PIM_NEXTHOP_LOOKUP_MAX);
+
+ if (num_ifindex <= 0)
+ return false;
+
+ for (i = 0; i < num_ifindex; i++) {
+ struct pim_zlookup_nexthop *znh = &nexthop_tab[i];
+
+ /* pim_zlookup_nexthop has no ->type */
+
+ /* 1:1 match code below with znh instead of nh */
+ ifp = if_lookup_by_index(znh->ifindex,
+ pim->vrf->vrf_id);
+
+ if (!ifp || !ifp->info)
continue;
- }
- }
- if (nexthop_tab[i].nexthop_addr.u.prefix4.s_addr
- == ip_src.s_addr)
- return true;
+ if (if_is_loopback(ifp) && if_is_loopback(src_ifp))
+ return true;
- i++;
+ nbr = pim_neighbor_find(ifp,
+ znh->nexthop_addr.u.prefix4);
+ if (!nbr)
+ continue;
+
+ return znh->ifindex == src_ifp->ifindex
+ && znh->nexthop_addr.u.prefix4.s_addr
+ == src_ip.s_addr;
+ }
+ return false;
}
- return false;
-}
+ if (!CHECK_FLAG(pnc->flags, PIM_NEXTHOP_VALID))
+ return false;
-/* Given a source address and a neighbor address, check if the neighbor is one
- * of the next hop to reach the source. search from pim next hop cache
- */
-bool pim_nexthop_match_nht_cache(struct pim_instance *pim, struct in_addr addr,
- struct in_addr ip_src)
-{
- struct pim_rpf rpf;
- ifindex_t first_ifindex;
- struct interface *ifp = NULL;
- uint8_t nh_iter = 0;
- struct pim_neighbor *nbr = NULL;
- struct nexthop *nh_node = NULL;
- struct pim_nexthop_cache *pnc = NULL;
+ /* if we accept BSMs from more than one ECMP nexthop, this will cause
+ * BSM message "multiplication" for each ECMP hop. i.e. if you have
+ * 4-way ECMP and 4 hops you end up with 256 copies of each BSM
+ * message.
+ *
+ * so... only accept the first (IPv4) valid nexthop as source.
+ */
- memset(&rpf, 0, sizeof(struct pim_rpf));
- rpf.rpf_addr.family = AF_INET;
- rpf.rpf_addr.prefixlen = IPV4_MAX_BITLEN;
- rpf.rpf_addr.u.prefix4 = addr;
+ for (nh = pnc->nexthop; nh; nh = nh->next) {
+ struct in_addr nhaddr;
- pnc = pim_nexthop_cache_find(pim, &rpf);
- if (!pnc || !pnc->nexthop_num)
- return false;
+ switch (nh->type) {
+ case NEXTHOP_TYPE_IPV4:
+ if (nh->ifindex == IFINDEX_INTERNAL)
+ continue;
- for (nh_node = pnc->nexthop; nh_node; nh_node = nh_node->next) {
- first_ifindex = nh_node->ifindex;
- ifp = if_lookup_by_index(first_ifindex, pim->vrf->vrf_id);
- if (!ifp) {
- if (PIM_DEBUG_PIM_NHT) {
- char addr_str[INET_ADDRSTRLEN];
+ /* fallthru */
+ case NEXTHOP_TYPE_IPV4_IFINDEX:
+ nhaddr = nh->gate.ipv4;
+ break;
- pim_inet4_dump("<addr?>", addr, addr_str,
- sizeof(addr_str));
- zlog_debug(
- "%s %s: could not find interface for ifindex %d (address %s(%s))",
- __FILE__, __func__, first_ifindex,
- addr_str, pim->vrf->name);
- }
- nh_iter++;
- continue;
- }
- if (!ifp->info) {
- if (PIM_DEBUG_PIM_NHT) {
- char addr_str[INET_ADDRSTRLEN];
+ case NEXTHOP_TYPE_IFINDEX:
+ nhaddr = bsr_addr;
+ break;
- pim_inet4_dump("<addr?>", addr, addr_str,
- sizeof(addr_str));
- zlog_debug(
- "%s: multicast not enabled on input interface %s(%s) (ifindex=%d, RPF for source %s)",
- __func__, ifp->name, pim->vrf->name,
- first_ifindex, addr_str);
- }
- nh_iter++;
+ default:
continue;
}
- if (!pim_if_connected_to_source(ifp, addr)) {
- nbr = pim_neighbor_find(ifp, nh_node->gate.ipv4);
- if (!nbr && !if_is_loopback(ifp)) {
- if (PIM_DEBUG_PIM_NHT)
- zlog_debug(
- "%s: pim nbr not found on input interface %s(%s)",
- __func__, ifp->name,
- pim->vrf->name);
- nh_iter++;
- continue;
- }
- }
+ ifp = if_lookup_by_index(nh->ifindex, pim->vrf->vrf_id);
+ if (!ifp || !ifp->info)
+ continue;
- if (nh_node->gate.ipv4.s_addr == ip_src.s_addr)
+ if (if_is_loopback(ifp) && if_is_loopback(src_ifp))
return true;
- }
+ /* MRIB (IGP) may be pointing at a router where PIM is down */
+ nbr = pim_neighbor_find(ifp, nhaddr);
+ if (!nbr)
+ continue;
+
+ return nh->ifindex == src_ifp->ifindex
+ && nhaddr.s_addr == src_ip.s_addr;
+ }
return false;
}
diff --git a/pimd/pim_nht.h b/pimd/pim_nht.h
index 12dbf167d..568c2eb23 100644
--- a/pimd/pim_nht.h
+++ b/pimd/pim_nht.h
@@ -45,22 +45,20 @@ struct pim_nexthop_cache {
struct list *rp_list;
struct hash *upstream_hash;
- /* Ideally this has to be list of scope zone. But for now we can just
- * have as a bool variable to say bsr_tracking.
- * Later this variable can be changed as a list of scope zones for
- * tracking same bsr for multiple scope zones.
+
+ /* bsr_count won't currently go above 1 as we only have global_scope,
+ * but if anyone adds scope support multiple scopes may NHT-track the
+ * same BSR
*/
- bool bsr_tracking;
+ uint32_t bsr_count;
};
int pim_parse_nexthop_update(ZAPI_CALLBACK_ARGS);
int pim_find_or_track_nexthop(struct pim_instance *pim, struct prefix *addr,
struct pim_upstream *up, struct rp_info *rp,
- bool bsr_track_needed,
struct pim_nexthop_cache *out_pnc);
void pim_delete_tracked_nexthop(struct pim_instance *pim, struct prefix *addr,
- struct pim_upstream *up, struct rp_info *rp,
- bool del_bsr_tracking);
+ struct pim_upstream *up, struct rp_info *rp);
struct pim_nexthop_cache *pim_nexthop_cache_find(struct pim_instance *pim,
struct pim_rpf *rpf);
uint32_t pim_compute_ecmp_hash(struct prefix *src, struct prefix *grp);
@@ -72,9 +70,12 @@ void pim_sendmsg_zebra_rnh(struct pim_instance *pim, struct zclient *zclient,
int pim_ecmp_fib_lookup_if_vif_index(struct pim_instance *pim,
struct prefix *src, struct prefix *grp);
void pim_rp_nexthop_del(struct rp_info *rp_info);
-bool pim_nexthop_match(struct pim_instance *pim, struct in_addr addr,
- struct in_addr ip_src);
-bool pim_nexthop_match_nht_cache(struct pim_instance *pim, struct in_addr addr,
- struct in_addr ip_src);
+
+/* for RPF check on BSM message receipt */
+void pim_nht_bsr_add(struct pim_instance *pim, struct in_addr bsr_addr);
+void pim_nht_bsr_del(struct pim_instance *pim, struct in_addr bsr_addr);
+/* RPF(bsr_addr) == src_ip%src_ifp? */
+bool pim_nht_bsr_rpf_check(struct pim_instance *pim, struct in_addr bsr_addr,
+ struct interface *src_ifp, struct in_addr src_ip);
#endif
diff --git a/pimd/pim_pim.c b/pimd/pim_pim.c
index 3df7dc41c..30dc6b3e9 100644
--- a/pimd/pim_pim.c
+++ b/pimd/pim_pim.c
@@ -692,7 +692,7 @@ int pim_hello_send(struct interface *ifp, uint16_t holdtime)
{
struct pim_interface *pim_ifp = ifp->info;
- if (if_is_loopback_or_vrf(ifp))
+ if (if_is_loopback(ifp))
return 0;
if (hello_send(ifp, holdtime)) {
@@ -794,7 +794,7 @@ void pim_hello_restart_triggered(struct interface *ifp)
/*
* No need to ever start loopback or vrf device hello's
*/
- if (if_is_loopback_or_vrf(ifp))
+ if (if_is_loopback(ifp))
return;
/*
diff --git a/pimd/pim_register.c b/pimd/pim_register.c
index 9d5b864ab..cc0dace7c 100644
--- a/pimd/pim_register.c
+++ b/pimd/pim_register.c
@@ -327,7 +327,7 @@ int pim_register_recv(struct interface *ifp, struct in_addr dest_addr,
#define PIM_MSG_REGISTER_BIT_RESERVED_LEN 4
ip_hdr = (struct ip *)(tlv_buf + PIM_MSG_REGISTER_BIT_RESERVED_LEN);
- if (!pim_rp_check_is_my_ip_address(pim, dest_addr)) {
+ if (!if_address_is_local(&dest_addr, AF_INET, pim->vrf->vrf_id)) {
if (PIM_DEBUG_PIM_REG) {
char dest[INET_ADDRSTRLEN];
@@ -381,6 +381,16 @@ int pim_register_recv(struct interface *ifp, struct in_addr dest_addr,
pim_str_sg_dump(&sg), src_str, ifp->name, i_am_rp);
}
+ if (pim_is_grp_ssm(pim_ifp->pim, sg.grp)) {
+ if (sg.src.s_addr == INADDR_ANY) {
+ zlog_warn(
+ "%s: Received Register message for Group(%pI4) is now in SSM, dropping the packet",
+ __func__, &sg.grp);
+ /* Drop Packet Silently */
+ return 0;
+ }
+ }
+
if (i_am_rp
&& (dest_addr.s_addr
== ((RP(pim, sg.grp))->rpf_addr.u.prefix4.s_addr))) {
diff --git a/pimd/pim_rp.c b/pimd/pim_rp.c
index f2a969e04..4865b0ed4 100644
--- a/pimd/pim_rp.c
+++ b/pimd/pim_rp.c
@@ -392,7 +392,7 @@ void pim_upstream_update(struct pim_instance *pim, struct pim_upstream *up)
zlog_debug(
"%s: Deregister upstream %s addr %pFX with Zebra NHT",
__func__, up->sg_str, &nht_p);
- pim_delete_tracked_nexthop(pim, &nht_p, up, NULL, false);
+ pim_delete_tracked_nexthop(pim, &nht_p, up, NULL);
}
/* Update the upstream address */
@@ -413,7 +413,6 @@ void pim_upstream_update(struct pim_instance *pim, struct pim_upstream *up)
old_rpf.source_nexthop.interface))
pim_zebra_upstream_rpf_changed(pim, up, &old_rpf);
- pim_zebra_update_all_interfaces(pim);
}
int pim_rp_new(struct pim_instance *pim, struct in_addr rp_addr,
@@ -431,6 +430,7 @@ int pim_rp_new(struct pim_instance *pim, struct in_addr rp_addr,
struct prefix nht_p;
struct route_node *rn;
struct pim_upstream *up;
+ bool upstream_updated = false;
if (rp_addr.s_addr == INADDR_ANY ||
rp_addr.s_addr == INADDR_NONE)
@@ -547,15 +547,19 @@ int pim_rp_new(struct pim_instance *pim, struct in_addr rp_addr,
grp.u.prefix4 = up->sg.grp;
trp_info = pim_rp_find_match_group(
pim, &grp);
- if (trp_info == rp_all)
+ if (trp_info == rp_all) {
pim_upstream_update(pim, up);
+ upstream_updated = true;
+ }
}
}
+ if (upstream_updated)
+ pim_zebra_update_all_interfaces(pim);
pim_rp_check_interfaces(pim, rp_all);
pim_rp_refresh_group_to_rp_mapping(pim);
pim_find_or_track_nexthop(pim, &nht_p, NULL, rp_all,
- false, NULL);
+ NULL);
if (!pim_ecmp_nexthop_lookup(pim,
&rp_all->rp.source_nexthop,
@@ -634,11 +638,16 @@ int pim_rp_new(struct pim_instance *pim, struct in_addr rp_addr,
grp.u.prefix4 = up->sg.grp;
trp_info = pim_rp_find_match_group(pim, &grp);
- if (trp_info == rp_info)
+ if (trp_info == rp_info) {
pim_upstream_update(pim, up);
+ upstream_updated = true;
+ }
}
}
+ if (upstream_updated)
+ pim_zebra_update_all_interfaces(pim);
+
pim_rp_check_interfaces(pim, rp_info);
pim_rp_refresh_group_to_rp_mapping(pim);
@@ -649,7 +658,7 @@ int pim_rp_new(struct pim_instance *pim, struct in_addr rp_addr,
if (PIM_DEBUG_PIM_NHT_RP)
zlog_debug("%s: NHT Register RP addr %pFX grp %pFX with Zebra ",
__func__, &nht_p, &rp_info->group);
- pim_find_or_track_nexthop(pim, &nht_p, NULL, rp_info, false, NULL);
+ pim_find_or_track_nexthop(pim, &nht_p, NULL, rp_info, NULL);
if (!pim_ecmp_nexthop_lookup(pim, &rp_info->rp.source_nexthop, &nht_p,
&rp_info->group, 1))
return PIM_RP_NO_PATH;
@@ -695,6 +704,7 @@ int pim_rp_del(struct pim_instance *pim, struct in_addr rp_addr,
struct bsgrp_node *bsgrp = NULL;
struct bsm_rpinfo *bsrp = NULL;
char rp_str[INET_ADDRSTRLEN];
+ bool upstream_updated = false;
if (!inet_ntop(AF_INET, &rp_addr, rp_str, sizeof(rp_str)))
snprintf(rp_str, sizeof(rp_str), "<rp?>");
@@ -757,7 +767,7 @@ int pim_rp_del(struct pim_instance *pim, struct in_addr rp_addr,
if (PIM_DEBUG_PIM_NHT_RP)
zlog_debug("%s: Deregister RP addr %pFX with Zebra ", __func__,
&nht_p);
- pim_delete_tracked_nexthop(pim, &nht_p, NULL, rp_info, false);
+ pim_delete_tracked_nexthop(pim, &nht_p, NULL, rp_info);
if (!str2prefix("224.0.0.0/4", &g_all))
return PIM_RP_BAD_ADDRESS;
@@ -837,11 +847,16 @@ int pim_rp_del(struct pim_instance *pim, struct in_addr rp_addr,
}
/* RP found for the group grp */
- else
+ else {
pim_upstream_update(pim, up);
+ upstream_updated = true;
+ }
}
}
+ if (upstream_updated)
+ pim_zebra_update_all_interfaces(pim);
+
XFREE(MTYPE_PIM_RP, rp_info);
return PIM_SUCCESS;
}
@@ -854,6 +869,7 @@ int pim_rp_change(struct pim_instance *pim, struct in_addr new_rp_addr,
int result = 0;
struct rp_info *rp_info = NULL;
struct pim_upstream *up;
+ bool upstream_updated = false;
rn = route_node_lookup(pim->rp_table, &group);
if (!rn) {
@@ -886,7 +902,7 @@ int pim_rp_change(struct pim_instance *pim, struct in_addr new_rp_addr,
if (PIM_DEBUG_PIM_NHT_RP)
zlog_debug("%s: Deregister RP addr %pFX with Zebra ",
__func__, &nht_p);
- pim_delete_tracked_nexthop(pim, &nht_p, NULL, rp_info, false);
+ pim_delete_tracked_nexthop(pim, &nht_p, NULL, rp_info);
}
pim_rp_nexthop_del(rp_info);
@@ -908,18 +924,23 @@ int pim_rp_change(struct pim_instance *pim, struct in_addr new_rp_addr,
grp.u.prefix4 = up->sg.grp;
trp_info = pim_rp_find_match_group(pim, &grp);
- if (trp_info == rp_info)
+ if (trp_info == rp_info) {
pim_upstream_update(pim, up);
+ upstream_updated = true;
+ }
}
}
+ if (upstream_updated)
+ pim_zebra_update_all_interfaces(pim);
+
/* Register new RP addr with Zebra NHT */
nht_p.u.prefix4 = rp_info->rp.rpf_addr.u.prefix4;
if (PIM_DEBUG_PIM_NHT_RP)
zlog_debug("%s: NHT Register RP addr %pFX grp %pFX with Zebra ",
__func__, &nht_p, &rp_info->group);
- pim_find_or_track_nexthop(pim, &nht_p, NULL, rp_info, false, NULL);
+ pim_find_or_track_nexthop(pim, &nht_p, NULL, rp_info, NULL);
if (!pim_ecmp_nexthop_lookup(pim, &rp_info->rp.source_nexthop, &nht_p,
&rp_info->group, 1)) {
route_unlock_node(rn);
@@ -949,8 +970,7 @@ void pim_rp_setup(struct pim_instance *pim)
nht_p.prefixlen = IPV4_MAX_BITLEN;
nht_p.u.prefix4 = rp_info->rp.rpf_addr.u.prefix4;
- pim_find_or_track_nexthop(pim, &nht_p, NULL, rp_info, false,
- NULL);
+ pim_find_or_track_nexthop(pim, &nht_p, NULL, rp_info, NULL);
if (!pim_ecmp_nexthop_lookup(pim, &rp_info->rp.source_nexthop,
&nht_p, &rp_info->group, 1))
if (PIM_DEBUG_PIM_NHT_RP)
@@ -1097,8 +1117,7 @@ struct pim_rpf *pim_rp_g(struct pim_instance *pim, struct in_addr group)
zlog_debug(
"%s: NHT Register RP addr %pFX grp %pFX with Zebra",
__func__, &nht_p, &rp_info->group);
- pim_find_or_track_nexthop(pim, &nht_p, NULL, rp_info, false,
- NULL);
+ pim_find_or_track_nexthop(pim, &nht_p, NULL, rp_info, NULL);
pim_rpf_set_refresh_time(pim);
(void)pim_ecmp_nexthop_lookup(pim, &rp_info->rp.source_nexthop,
&nht_p, &rp_info->group, 1);
@@ -1178,15 +1197,6 @@ int pim_rp_config_write(struct pim_instance *pim, struct vty *vty,
return count;
}
-bool pim_rp_check_is_my_ip_address(struct pim_instance *pim,
- struct in_addr dest_addr)
-{
- if (if_lookup_exact_address(&dest_addr, AF_INET, pim->vrf->vrf_id))
- return true;
-
- return false;
-}
-
void pim_rp_show_information(struct pim_instance *pim, struct vty *vty, bool uj)
{
struct rp_info *rp_info;
@@ -1239,12 +1249,9 @@ void pim_rp_show_information(struct pim_instance *pim, struct vty *vty, bool uj)
json_rp_rows = json_object_new_array();
json_row = json_object_new_object();
- json_object_string_add(
- json_row, "rpAddress",
- inet_ntop(AF_INET,
- &rp_info->rp.rpf_addr.u
- .prefix4,
- buf, sizeof(buf)));
+ json_object_string_addf(
+ json_row, "rpAddress", "%pI4",
+ &rp_info->rp.rpf_addr.u.prefix4);
if (rp_info->rp.source_nexthop.interface)
json_object_string_add(
json_row, "outboundInterface",
@@ -1337,7 +1344,7 @@ void pim_resolve_rp_nh(struct pim_instance *pim, struct pim_neighbor *nbr)
nht_p.u.prefix4 = rp_info->rp.rpf_addr.u.prefix4;
memset(&pnc, 0, sizeof(struct pim_nexthop_cache));
if (!pim_find_or_track_nexthop(pim, &nht_p, NULL, rp_info,
- false, &pnc))
+ &pnc))
continue;
for (nh_node = pnc.nexthop; nh_node; nh_node = nh_node->next) {
diff --git a/pimd/pim_rpf.c b/pimd/pim_rpf.c
index b93f85e48..aa89431d3 100644
--- a/pimd/pim_rpf.c
+++ b/pimd/pim_rpf.c
@@ -262,7 +262,7 @@ enum pim_rpf_result pim_rpf_update(struct pim_instance *pim,
if ((up->sg.src.s_addr == INADDR_ANY && I_am_RP(pim, up->sg.grp)) ||
PIM_UPSTREAM_FLAG_TEST_FHR(up->flags))
neigh_needed = false;
- pim_find_or_track_nexthop(pim, &nht_p, up, NULL, false, NULL);
+ pim_find_or_track_nexthop(pim, &nht_p, up, NULL, NULL);
if (!pim_ecmp_nexthop_lookup(pim, &rpf->source_nexthop, &src, &grp,
neigh_needed)) {
/* Route is Deleted in Zebra, reset the stored NH data */
diff --git a/pimd/pim_signals.c b/pimd/pim_signals.c
index 38387d38c..47220ccac 100644
--- a/pimd/pim_signals.c
+++ b/pimd/pim_signals.c
@@ -57,7 +57,7 @@ static void pim_sigusr1(void)
zlog_rotate();
}
-struct quagga_signal_t pimd_signals[] = {
+struct frr_signal_t pimd_signals[] = {
{
.signal = SIGHUP,
.handler = &pim_sighup,
diff --git a/pimd/pim_signals.h b/pimd/pim_signals.h
index a82915691..ebc5b8eb2 100644
--- a/pimd/pim_signals.h
+++ b/pimd/pim_signals.h
@@ -21,6 +21,6 @@
#define PIM_SIGNALS_H
#include "sigevent.h"
-extern struct quagga_signal_t pimd_signals[];
+extern struct frr_signal_t pimd_signals[];
#endif /* PIM_SIGNALS_H */
diff --git a/pimd/pim_time.c b/pimd/pim_time.c
index c88ee7554..93aaffb6a 100644
--- a/pimd/pim_time.c
+++ b/pimd/pim_time.c
@@ -171,9 +171,7 @@ void pim_time_uptime_begin(char *buf, int buf_size, int64_t now, int64_t begin)
long pim_time_timer_remain_msec(struct thread *t_timer)
{
- /* FIXME: Actually fetch msec resolution from thread */
-
/* no timer thread running means timer has expired: return 0 */
- return t_timer ? 1000 * thread_timer_remain_second(t_timer) : 0;
+ return t_timer ? thread_timer_remain_msec(t_timer) : 0;
}
diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c
index b9cddd74f..e59dbba9d 100644
--- a/pimd/pim_upstream.c
+++ b/pimd/pim_upstream.c
@@ -271,7 +271,7 @@ struct pim_upstream *pim_upstream_del(struct pim_instance *pim,
zlog_debug(
"%s: Deregister upstream %s addr %pFX with Zebra NHT",
__func__, up->sg_str, &nht_p);
- pim_delete_tracked_nexthop(pim, &nht_p, up, NULL, false);
+ pim_delete_tracked_nexthop(pim, &nht_p, up, NULL);
}
XFREE(MTYPE_PIM_UPSTREAM, up);
@@ -561,7 +561,7 @@ static void forward_off(struct pim_upstream *up)
/* scan per-interface (S,G) state */
for (ALL_LIST_ELEMENTS(up->ifchannels, chnode, chnextnode, ch)) {
- pim_forward_stop(ch, false);
+ pim_forward_stop(ch);
} /* scan iface channel list */
}
@@ -1720,8 +1720,6 @@ const char *pim_reg_state2str(enum pim_reg_state reg_state, char *state_str,
case PIM_REG_PRUNE:
strlcpy(state_str, "RegPrune", state_str_len);
break;
- default:
- strlcpy(state_str, "RegUnknown", state_str_len);
}
return state_str;
}
@@ -1785,7 +1783,7 @@ static int pim_upstream_register_stop_timer(struct thread *t)
}
pim_null_register_send(up);
break;
- default:
+ case PIM_REG_NOINFO:
break;
}
diff --git a/pimd/pim_vxlan.c b/pimd/pim_vxlan.c
index 5d5ea1bfe..4c8a96a84 100644
--- a/pimd/pim_vxlan.c
+++ b/pimd/pim_vxlan.c
@@ -357,8 +357,8 @@ static void pim_vxlan_orig_mr_up_add(struct pim_vxlan_sg *vxlan_sg)
nht_p.family = AF_INET;
nht_p.prefixlen = IPV4_MAX_BITLEN;
nht_p.u.prefix4 = up->upstream_addr;
- pim_delete_tracked_nexthop(vxlan_sg->pim,
- &nht_p, up, NULL, false);
+ pim_delete_tracked_nexthop(vxlan_sg->pim, &nht_p, up,
+ NULL);
}
/* We are acting FHR; clear out use_rpt setting if any */
pim_upstream_update_use_rpt(up, false /*update_mroute*/);
@@ -1079,7 +1079,7 @@ void pim_vxlan_add_vif(struct interface *ifp)
if (pim->vrf->vrf_id != VRF_DEFAULT)
return;
- if (if_is_loopback_or_vrf(ifp))
+ if (if_is_loopback(ifp))
pim_vxlan_set_default_iif(pim, ifp);
if (vxlan_mlag.flags & PIM_VXLAN_MLAGF_ENABLED &&
diff --git a/pimd/pim_vxlan.h b/pimd/pim_vxlan.h
index ce9054cd2..d17de8e3d 100644
--- a/pimd/pim_vxlan.h
+++ b/pimd/pim_vxlan.h
@@ -116,7 +116,7 @@ static inline bool pim_vxlan_is_local_sip(struct pim_upstream *up)
{
return (up->sg.src.s_addr != INADDR_ANY) &&
up->rpf.source_nexthop.interface &&
- if_is_loopback_or_vrf(up->rpf.source_nexthop.interface);
+ if_is_loopback(up->rpf.source_nexthop.interface);
}
static inline bool pim_vxlan_is_term_dev_cfg(struct pim_instance *pim,
diff --git a/pimd/pim_zebra.c b/pimd/pim_zebra.c
index 1da33af00..3a08c6aee 100644
--- a/pimd/pim_zebra.c
+++ b/pimd/pim_zebra.c
@@ -164,7 +164,7 @@ static int pim_zebra_if_address_add(ZAPI_CALLBACK_ARGS)
}
if (if_is_loopback(c->ifp)) {
- struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
+ struct vrf *vrf = vrf_lookup_by_id(vrf_id);
struct interface *ifp;
FOR_ALL_INTERFACES (vrf, ifp) {
@@ -548,6 +548,7 @@ void igmp_source_forward_reevaluate_all(struct pim_instance *pim)
struct pim_interface *pim_ifp = ifp->info;
struct listnode *grpnode;
struct igmp_group *grp;
+ struct pim_ifchannel *ch, *ch_temp;
if (!pim_ifp)
continue;
@@ -562,9 +563,17 @@ void igmp_source_forward_reevaluate_all(struct pim_instance *pim)
for (ALL_LIST_ELEMENTS_RO(grp->group_source_list,
srcnode, src)) {
igmp_source_forward_reevaluate_one(pim, src);
- } /* scan group sources */
- } /* scan igmp groups */
- } /* scan interfaces */
+ } /* scan group sources */
+ } /* scan igmp groups */
+
+ RB_FOREACH_SAFE (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb,
+ ch_temp) {
+ if (pim_is_grp_ssm(pim, ch->sg.grp)) {
+ if (ch->sg.src.s_addr == INADDR_ANY)
+ pim_ifchannel_delete(ch);
+ }
+ }
+ } /* scan interfaces */
}
void igmp_source_forward_start(struct pim_instance *pim,
@@ -836,14 +845,14 @@ void pim_forward_start(struct pim_ifchannel *ch)
mask, __func__);
}
-void pim_forward_stop(struct pim_ifchannel *ch, bool install_it)
+void pim_forward_stop(struct pim_ifchannel *ch)
{
struct pim_upstream *up = ch->upstream;
if (PIM_DEBUG_PIM_TRACE) {
- zlog_debug("%s: (S,G)=%s oif=%s install_it: %d installed: %d",
+ zlog_debug("%s: (S,G)=%s oif=%s installed: %d",
__func__, ch->sg_str, ch->interface->name,
- install_it, up->channel_oil->installed);
+ up->channel_oil->installed);
}
/*
@@ -856,9 +865,6 @@ void pim_forward_stop(struct pim_ifchannel *ch, bool install_it)
else
pim_channel_del_oif(up->channel_oil, ch->interface,
PIM_OIF_FLAG_PROTO_PIM, __func__);
-
- if (install_it && !up->channel_oil->installed)
- pim_upstream_mroute_add(up->channel_oil, __func__);
}
void pim_zebra_zclient_update(struct vty *vty)
diff --git a/pimd/pim_zebra.h b/pimd/pim_zebra.h
index 0f216cf5c..349903cc6 100644
--- a/pimd/pim_zebra.h
+++ b/pimd/pim_zebra.h
@@ -42,7 +42,7 @@ void igmp_source_forward_stop(struct igmp_source *source);
void igmp_source_forward_reevaluate_all(struct pim_instance *pim);
void pim_forward_start(struct pim_ifchannel *ch);
-void pim_forward_stop(struct pim_ifchannel *ch, bool install_it);
+void pim_forward_stop(struct pim_ifchannel *ch);
void sched_rpf_cache_refresh(struct pim_instance *pim);
struct zclient *pim_zebra_zclient_get(void);
diff --git a/pimd/pimd.h b/pimd/pimd.h
index 4cb860a6b..675c0ebc6 100644
--- a/pimd/pimd.h
+++ b/pimd/pimd.h
@@ -85,8 +85,6 @@
#define PIM_INADDR_IS_ANY(addr) (addr).s_addr == PIM_NET_INADDR_ANY
#define PIM_INADDR_ISNOT_ANY(addr) ((addr).s_addr != PIM_NET_INADDR_ANY) /* struct in_addr addr */
-#define max(x,y) ((x) > (y) ? (x) : (y))
-
#define PIM_MASK_PIM_EVENTS (1 << 0)
#define PIM_MASK_PIM_EVENTS_DETAIL (1 << 1)
#define PIM_MASK_PIM_PACKETS (1 << 2)
diff --git a/pimd/subdir.am b/pimd/subdir.am
index 9910642ff..f8bc0ff08 100644
--- a/pimd/subdir.am
+++ b/pimd/subdir.am
@@ -3,7 +3,6 @@
#
if PIMD
-noinst_LIBRARIES += pimd/libpim.a
sbin_PROGRAMS += pimd/pimd
bin_PROGRAMS += pimd/mtracebis
noinst_PROGRAMS += pimd/test_igmpv3_join
@@ -13,7 +12,7 @@ man8 += $(MANBUILD)/frr-pimd.8
man8 += $(MANBUILD)/mtracebis.8
endif
-pimd_libpim_a_SOURCES = \
+pimd_pimd_SOURCES = \
pimd/pim_assert.c \
pimd/pim_bfd.c \
pimd/pim_br.c \
@@ -33,6 +32,7 @@ pimd_libpim_a_SOURCES = \
pimd/pim_join.c \
pimd/pim_jp_agg.c \
pimd/pim_macro.c \
+ pimd/pim_main.c \
pimd/pim_memory.c \
pimd/pim_mlag.c \
pimd/pim_mroute.c \
@@ -66,6 +66,9 @@ pimd_libpim_a_SOURCES = \
pimd/pim_vxlan.c \
pimd/pim_zpthread.c \
pimd/pimd.c \
+ # end
+
+nodist_pimd_pimd_SOURCES = \
yang/frr-pim.yang.c \
yang/frr-pim-rp.yang.c \
yang/frr-igmp.yang.c \
@@ -131,14 +134,7 @@ clippy_scan += \
pimd/pim_cmd.c \
# end
-nodist_pimd_pimd_SOURCES = \
- yang/frr-igmp.yang.c \
- yang/frr-pim.yang.c \
- yang/frr-pim-rp.yang.c \
- # end
-
-pimd_pimd_LDADD = pimd/libpim.a lib/libfrr.la $(LIBCAP)
-pimd_pimd_SOURCES = pimd/pim_main.c
+pimd_pimd_LDADD = lib/libfrr.la $(LIBCAP)
pimd_test_igmpv3_join_LDADD = lib/libfrr.la
pimd_test_igmpv3_join_SOURCES = pimd/test_igmpv3_join.c