#include "pim_bfd.h"
#include "pim_vxlan.h"
#include "bfd.h"
+#include "pim_bsm.h"
#ifndef VTYSH_EXTRACT_PL
#include "pimd/pim_cmd_clippy.c"
long oqpi_msec; /* Other Querier Present Interval */
long qri_msec;
time_t now;
+ int lmqc;
json_object *json = NULL;
json_object *json_row = NULL;
pim_ifp->igmp_query_max_response_time_dsec);
lmqt_msec = PIM_IGMP_LMQT_MSEC(
- pim_ifp->igmp_query_max_response_time_dsec,
- igmp->querier_robustness_variable);
+ pim_ifp->igmp_specific_query_max_response_time_dsec,
+ pim_ifp->igmp_last_member_query_count);
ohpi_msec =
PIM_IGMP_OHPI_DSEC(
pim_ifp->pim_sock_fd);
else
mloop = 0;
+ lmqc = pim_ifp->igmp_last_member_query_count;
if (uj) {
json_row = json_object_new_object();
json_row,
"timerGroupMembershipIntervalMsec",
gmi_msec);
+ json_object_int_add(json_row,
+ "lastMemberQueryCount",
+ lmqc);
json_object_int_add(json_row,
"timerLastMemberQueryMsec",
lmqt_msec);
vty_out(vty,
"Group Membership Interval : %lis\n",
gmi_msec / 1000);
+ vty_out(vty,
+ "Last Member Query Count : %d\n",
+ lmqc);
vty_out(vty,
"Last Member Query Time : %lis\n",
lmqt_msec / 1000);
json = json_object_new_object();
else {
vty_out(vty, "\n");
- vty_out(vty, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s\n",
+ vty_out(vty, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s%-17s\n",
"Interface", " HELLO", " JOIN",
" PRUNE", " REGISTER", "REGISTER-STOP",
- " ASSERT");
- vty_out(vty, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s\n", "",
+ " ASSERT", " BSM");
+ vty_out(vty, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s%-17s\n", "",
" Rx/Tx", " Rx/Tx", " Rx/Tx",
- " Rx/Tx", " Rx/Tx", " Rx/Tx");
+ " Rx/Tx", " Rx/Tx", " Rx/Tx",
+ " Rx/Tx");
vty_out(vty,
"---------------------------------------------------------------------------------------------------------------\n");
}
json_object_int_add(json_row, "assertRx",
pim_ifp->pim_ifstat_assert_recv);
json_object_int_add(json_row, "assertTx",
- pim_ifp->pim_ifstat_assert_send);
-
+ pim_ifp->pim_ifstat_assert_send);
+ json_object_int_add(json_row, "bsmRx",
+ pim_ifp->pim_ifstat_bsm_rx);
+ json_object_int_add(json_row, "bsmTx",
+ pim_ifp->pim_ifstat_bsm_tx);
json_object_object_add(json, ifp->name, json_row);
} else {
vty_out(vty,
- "%-16s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u \n",
+ "%-16s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7" PRIu64 "/%-7" PRIu64 "\n",
ifp->name, pim_ifp->pim_ifstat_hello_recv,
pim_ifp->pim_ifstat_hello_sent,
pim_ifp->pim_ifstat_join_recv,
pim_ifp->pim_ifstat_reg_stop_recv,
pim_ifp->pim_ifstat_reg_stop_send,
pim_ifp->pim_ifstat_assert_recv,
- pim_ifp->pim_ifstat_assert_send);
+ pim_ifp->pim_ifstat_assert_send,
+ pim_ifp->pim_ifstat_bsm_rx,
+ pim_ifp->pim_ifstat_bsm_tx);
}
}
if (uj) {
json = json_object_new_object();
else {
vty_out(vty, "\n");
- vty_out(vty, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s\n",
+ vty_out(vty, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s%-17s\n",
"Interface", " HELLO", " JOIN", " PRUNE",
- " REGISTER", " REGISTER-STOP", " ASSERT");
- vty_out(vty, "%-14s%-18s%-17s%-17s%-17s%-17s%-17s\n", "",
+ " REGISTER", " REGISTER-STOP", " ASSERT",
+ " BSM");
+ vty_out(vty, "%-14s%-18s%-17s%-17s%-17s%-17s%-17s%-17s\n", "",
" Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
- " Rx/Tx", " Rx/Tx");
+ " Rx/Tx", " Rx/Tx", " Rx/Tx");
vty_out(vty,
- "---------------------------------------------------------------------------------------------------------------------\n");
+ "-------------------------------------------------------------------------------------------------------------------------------\n");
}
FOR_ALL_INTERFACES (pim->vrf, ifp) {
pim_ifp->pim_ifstat_assert_recv);
json_object_int_add(json_row, "assertTx",
pim_ifp->pim_ifstat_assert_send);
+ json_object_int_add(json_row, "bsmRx",
+ pim_ifp->pim_ifstat_bsm_rx);
+ json_object_int_add(json_row, "bsmTx",
+ pim_ifp->pim_ifstat_bsm_tx);
json_object_object_add(json, ifp->name, json_row);
} else {
vty_out(vty,
- "%-16s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u \n",
+ "%-16s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7" PRIu64 "/%-7" PRIu64 "\n",
ifp->name, pim_ifp->pim_ifstat_hello_recv,
pim_ifp->pim_ifstat_hello_sent,
pim_ifp->pim_ifstat_join_recv,
pim_ifp->pim_ifstat_reg_stop_recv,
pim_ifp->pim_ifstat_reg_stop_send,
pim_ifp->pim_ifstat_assert_recv,
- pim_ifp->pim_ifstat_assert_send);
+ pim_ifp->pim_ifstat_assert_send,
+ pim_ifp->pim_ifstat_bsm_rx,
+ pim_ifp->pim_ifstat_bsm_tx);
}
}
if (uj) {
ifp_in = pim_if_find_by_vif_index(pim, c_oil->oil.mfcc_parent);
if (ifp_in)
- strcpy(in_ifname, ifp_in->name);
+ strlcpy(in_ifname, ifp_in->name, sizeof(in_ifname));
else
- strcpy(in_ifname, "<iif?>");
+ strlcpy(in_ifname, "<iif?>", sizeof(in_ifname));
if (src_or_group) {
if (strcmp(src_or_group, src_str)
now - c_oil->oif_creation[oif_vif_index]);
if (ifp_out)
- strcpy(out_ifname, ifp_out->name);
+ strlcpy(out_ifname, ifp_out->name, sizeof(out_ifname));
else
- strcpy(out_ifname, "<oif?>");
+ strlcpy(out_ifname, "<oif?>", sizeof(out_ifname));
if (uj) {
json_ifp_out = json_object_new_object();
} else {
if (first_oif) {
first_oif = 0;
- vty_out(vty, "%s(%c%c%c%c%c)", out_ifname,
+ vty_out(vty, "%s(%c%c%c%c)", out_ifname,
(c_oil->oif_flags[oif_vif_index]
& PIM_OIF_FLAG_PROTO_IGMP)
? 'I'
& PIM_OIF_FLAG_PROTO_VXLAN)
? 'V'
: ' ',
- (c_oil->oif_flags[oif_vif_index]
- & PIM_OIF_FLAG_PROTO_SOURCE)
- ? 'S'
- : ' ',
(c_oil->oif_flags[oif_vif_index]
& PIM_OIF_FLAG_PROTO_STAR)
? '*'
: ' ');
} else
- vty_out(vty, ", %s(%c%c%c%c%c)",
+ vty_out(vty, ", %s(%c%c%c%c)",
out_ifname,
(c_oil->oif_flags[oif_vif_index]
& PIM_OIF_FLAG_PROTO_IGMP)
& PIM_OIF_FLAG_PROTO_VXLAN)
? 'V'
: ' ',
- (c_oil->oif_flags[oif_vif_index]
- & PIM_OIF_FLAG_PROTO_SOURCE)
- ? 'S'
- : ' ',
(c_oil->oif_flags[oif_vif_index]
& PIM_OIF_FLAG_PROTO_STAR)
? '*'
static const char *
pim_upstream_state2brief_str(enum pim_upstream_state join_state,
- char *state_str)
+ char *state_str, size_t state_str_len)
{
switch (join_state) {
case PIM_UPSTREAM_NOTJOINED:
- strcpy(state_str, "NotJ");
+ strlcpy(state_str, "NotJ", state_str_len);
break;
case PIM_UPSTREAM_JOINED:
- strcpy(state_str, "J");
+ strlcpy(state_str, "J", state_str_len);
break;
default:
- strcpy(state_str, "Unk");
+ strlcpy(state_str, "Unk", state_str_len);
}
return state_str;
}
static const char *pim_reg_state2brief_str(enum pim_reg_state reg_state,
- char *state_str)
+ char *state_str, size_t state_str_len)
{
switch (reg_state) {
case PIM_REG_NOINFO:
- strcpy(state_str, "RegNI");
+ strlcpy(state_str, "RegNI", state_str_len);
break;
case PIM_REG_JOIN:
- strcpy(state_str, "RegJ");
+ strlcpy(state_str, "RegJ", state_str_len);
break;
case PIM_REG_JOIN_PENDING:
case PIM_REG_PRUNE:
- strcpy(state_str, "RegP");
+ strlcpy(state_str, "RegP", state_str_len);
break;
default:
- strcpy(state_str, "Unk");
+ strlcpy(state_str, "Unk", state_str_len);
}
return state_str;
}
pim_time_timer_to_hhmmss(msdp_reg_timer, sizeof(msdp_reg_timer),
up->t_msdp_reg_timer);
- pim_upstream_state2brief_str(up->join_state, state_str);
+ pim_upstream_state2brief_str(up->join_state, state_str, sizeof(state_str));
if (up->reg_state != PIM_REG_NOINFO) {
char tmp_str[PIM_REG_STATE_STR_LEN];
sprintf(state_str + strlen(state_str), ",%s",
- pim_reg_state2brief_str(up->reg_state,
- tmp_str));
+ pim_reg_state2brief_str(up->reg_state, tmp_str,
+ sizeof(tmp_str)));
}
if (uj) {
pim_upstream_state2str(up->join_state));
json_object_string_add(
json_row, "regState",
- pim_reg_state2str(up->reg_state, state_str));
+ pim_reg_state2str(up->reg_state, state_str, sizeof(state_str)));
json_object_string_add(json_row, "upTime", uptime);
json_object_string_add(json_row, "joinTimer",
join_timer);
hash_walk(pim->rpf_hash, pim_print_pnc_cache_walkcb, &cwd);
}
+/* Display the bsm database details */
+static void pim_show_bsm_db(struct pim_instance *pim, struct vty *vty, bool uj)
+{
+ struct listnode *bsmnode;
+ int count = 0;
+ int fragment = 1;
+ struct bsm_info *bsm;
+ json_object *json = NULL;
+ json_object *json_group = NULL;
+ json_object *json_row = NULL;
+
+ count = pim->global_scope.bsm_list->count;
+
+ if (uj) {
+ json = json_object_new_object();
+ json_object_int_add(json, "Number of the fragments", count);
+ } else {
+ vty_out(vty, "Scope Zone: Global\n");
+ vty_out(vty, "Number of the fragments: %d\n", count);
+ vty_out(vty, "\n");
+ }
+
+ for (ALL_LIST_ELEMENTS_RO(pim->global_scope.bsm_list, bsmnode, bsm)) {
+ char grp_str[INET_ADDRSTRLEN];
+ char rp_str[INET_ADDRSTRLEN];
+ char bsr_str[INET_ADDRSTRLEN];
+ struct bsmmsg_grpinfo *group;
+ struct bsmmsg_rpinfo *rpaddr;
+ struct prefix grp;
+ struct bsm_hdr *hdr;
+ uint32_t offset = 0;
+ uint8_t *buf;
+ uint32_t len = 0;
+ uint32_t frag_rp_cnt = 0;
+
+ buf = bsm->bsm;
+ len = bsm->size;
+
+ /* skip pim header */
+ buf += PIM_MSG_HEADER_LEN;
+ len -= PIM_MSG_HEADER_LEN;
+
+ hdr = (struct bsm_hdr *)buf;
+
+ /* BSM starts with bsr header */
+ buf += sizeof(struct bsm_hdr);
+ len -= sizeof(struct bsm_hdr);
+
+ pim_inet4_dump("<BSR Address?>", hdr->bsr_addr.addr, bsr_str,
+ sizeof(bsr_str));
+
+
+ if (uj) {
+ json_object_string_add(json, "BSR address", bsr_str);
+ json_object_int_add(json, "BSR priority",
+ hdr->bsr_prio);
+ json_object_int_add(json, "Hashmask Length",
+ hdr->hm_len);
+ json_object_int_add(json, "Fragment Tag",
+ ntohs(hdr->frag_tag));
+ } else {
+ vty_out(vty, "BSM Fragment : %d\n", fragment);
+ vty_out(vty, "------------------\n");
+ vty_out(vty, "%-15s %-15s %-15s %-15s\n", "BSR-Address",
+ "BSR-Priority", "Hashmask-len", "Fragment-Tag");
+ vty_out(vty, "%-15s %-15d %-15d %-15d\n", bsr_str,
+ hdr->bsr_prio, hdr->hm_len,
+ ntohs(hdr->frag_tag));
+ }
+
+ vty_out(vty, "\n");
+
+ while (offset < len) {
+ group = (struct bsmmsg_grpinfo *)buf;
+
+ if (group->group.family == PIM_MSG_ADDRESS_FAMILY_IPV4)
+ grp.family = AF_INET;
+
+ grp.prefixlen = group->group.mask;
+ grp.u.prefix4.s_addr = group->group.addr.s_addr;
+
+ prefix2str(&grp, grp_str, sizeof(grp_str));
+
+ buf += sizeof(struct bsmmsg_grpinfo);
+ offset += sizeof(struct bsmmsg_grpinfo);
+
+ if (uj) {
+ json_object_object_get_ex(json, grp_str,
+ &json_group);
+ if (!json_group) {
+ json_group = json_object_new_object();
+ json_object_int_add(json_group,
+ "Rp Count",
+ group->rp_count);
+ json_object_int_add(
+ json_group, "Fragment Rp count",
+ group->frag_rp_count);
+ json_object_object_add(json, grp_str,
+ json_group);
+ }
+ } else {
+ vty_out(vty, "Group : %s\n", grp_str);
+ vty_out(vty, "-------------------\n");
+ vty_out(vty, "Rp Count:%d\n", group->rp_count);
+ vty_out(vty, "Fragment Rp Count : %d\n",
+ group->frag_rp_count);
+ }
+
+ frag_rp_cnt = group->frag_rp_count;
+
+ if (!frag_rp_cnt)
+ continue;
+
+ if (!uj)
+ vty_out(vty,
+ "RpAddress HoldTime Priority\n");
+
+ while (frag_rp_cnt--) {
+ rpaddr = (struct bsmmsg_rpinfo *)buf;
+
+ buf += sizeof(struct bsmmsg_rpinfo);
+ offset += sizeof(struct bsmmsg_rpinfo);
+
+ pim_inet4_dump("<Rp addr?>",
+ rpaddr->rpaddr.addr, rp_str,
+ sizeof(rp_str));
+
+ if (uj) {
+ json_row = json_object_new_object();
+ json_object_string_add(
+ json_row, "Rp Address", rp_str);
+ json_object_int_add(
+ json_row, "Rp HoldTime",
+ ntohs(rpaddr->rp_holdtime));
+ json_object_int_add(json_row,
+ "Rp Priority",
+ rpaddr->rp_pri);
+ json_object_object_add(
+ json_group, rp_str, json_row);
+ } else {
+ vty_out(vty, "%-15s %-12d %d\n", rp_str,
+ ntohs(rpaddr->rp_holdtime),
+ rpaddr->rp_pri);
+ }
+ }
+ vty_out(vty, "\n");
+ }
+
+ fragment++;
+ }
+
+ if (uj) {
+ vty_out(vty, "%s\n", json_object_to_json_string_ext(
+ json, JSON_C_TO_STRING_PRETTY));
+ json_object_free(json);
+ }
+}
+
+/*Display the group-rp mappings */
+static void pim_show_group_rp_mappings_info(struct pim_instance *pim,
+ struct vty *vty, bool uj)
+{
+ struct bsgrp_node *bsgrp;
+ struct listnode *rpnode;
+ struct bsm_rpinfo *bsm_rp;
+ struct route_node *rn;
+ char bsr_str[INET_ADDRSTRLEN];
+ json_object *json = NULL;
+ json_object *json_group = NULL;
+ json_object *json_row = NULL;
+
+ if (pim->global_scope.current_bsr.s_addr == INADDR_ANY)
+ strlcpy(bsr_str, "0.0.0.0", sizeof(bsr_str));
+
+ else
+ pim_inet4_dump("<bsr?>", pim->global_scope.current_bsr, bsr_str,
+ sizeof(bsr_str));
+
+ if (uj) {
+ json = json_object_new_object();
+ json_object_string_add(json, "BSR Address", bsr_str);
+ } else {
+ vty_out(vty, "BSR Address %s\n", bsr_str);
+ }
+
+ for (rn = route_top(pim->global_scope.bsrp_table); rn;
+ rn = route_next(rn)) {
+ bsgrp = (struct bsgrp_node *)rn->info;
+
+ if (!bsgrp)
+ continue;
+
+ char grp_str[INET_ADDRSTRLEN];
+
+ prefix2str(&bsgrp->group, grp_str, sizeof(grp_str));
+
+ if (uj) {
+ json_object_object_get_ex(json, grp_str, &json_group);
+ if (!json_group) {
+ json_group = json_object_new_object();
+ json_object_object_add(json, grp_str,
+ json_group);
+ }
+ } else {
+ vty_out(vty, "Group Address %s\n", grp_str);
+ vty_out(vty, "--------------------------\n");
+ vty_out(vty, "%-15s %-15s %-15s %-15s\n", "Rp Address",
+ "priority", "Holdtime", "Hash");
+
+ vty_out(vty, "(ACTIVE)\n");
+ }
+
+ if (bsgrp->bsrp_list) {
+ for (ALL_LIST_ELEMENTS_RO(bsgrp->bsrp_list, rpnode,
+ bsm_rp)) {
+ char rp_str[INET_ADDRSTRLEN];
+
+ pim_inet4_dump("<Rp Address?>",
+ bsm_rp->rp_address, rp_str,
+ sizeof(rp_str));
+
+ if (uj) {
+ json_row = json_object_new_object();
+ json_object_string_add(
+ json_row, "Rp Address", rp_str);
+ json_object_int_add(
+ json_row, "Rp HoldTime",
+ bsm_rp->rp_holdtime);
+ json_object_int_add(json_row,
+ "Rp Priority",
+ bsm_rp->rp_prio);
+ json_object_int_add(json_row,
+ "Hash Val",
+ bsm_rp->hash);
+ json_object_object_add(
+ json_group, rp_str, json_row);
+
+ } else {
+ vty_out(vty,
+ "%-15s %-15u %-15u %-15u\n",
+ rp_str, bsm_rp->rp_prio,
+ bsm_rp->rp_holdtime,
+ bsm_rp->hash);
+ }
+ }
+ if (!bsgrp->bsrp_list->count && !uj)
+ vty_out(vty, "Active List is empty.\n");
+ }
+
+ if (uj) {
+ json_object_int_add(json_group, "Pending RP count",
+ bsgrp->pend_rp_cnt);
+ } else {
+ vty_out(vty, "(PENDING)\n");
+ vty_out(vty, "Pending RP count :%d\n",
+ bsgrp->pend_rp_cnt);
+ if (bsgrp->pend_rp_cnt)
+ vty_out(vty, "%-15s %-15s %-15s %-15s\n",
+ "Rp Address", "priority", "Holdtime",
+ "Hash");
+ }
+
+ if (bsgrp->partial_bsrp_list) {
+ for (ALL_LIST_ELEMENTS_RO(bsgrp->partial_bsrp_list,
+ rpnode, bsm_rp)) {
+ char rp_str[INET_ADDRSTRLEN];
+
+ pim_inet4_dump("<Rp Addr?>", bsm_rp->rp_address,
+ rp_str, sizeof(rp_str));
+
+ if (uj) {
+ json_row = json_object_new_object();
+ json_object_string_add(
+ json_row, "Rp Address", rp_str);
+ json_object_int_add(
+ json_row, "Rp HoldTime",
+ bsm_rp->rp_holdtime);
+ json_object_int_add(json_row,
+ "Rp Priority",
+ bsm_rp->rp_prio);
+ json_object_int_add(json_row,
+ "Hash Val",
+ bsm_rp->hash);
+ json_object_object_add(
+ json_group, rp_str, json_row);
+ } else {
+ vty_out(vty,
+ "%-15s %-15u %-15u %-15u\n",
+ rp_str, bsm_rp->rp_prio,
+ bsm_rp->rp_holdtime,
+ bsm_rp->hash);
+ }
+ }
+ if (!bsgrp->partial_bsrp_list->count && !uj)
+ vty_out(vty, "Partial List is empty\n");
+ }
+
+ if (!uj)
+ vty_out(vty, "\n");
+ }
+
+ if (uj) {
+ vty_out(vty, "%s\n", json_object_to_json_string_ext(
+ json, JSON_C_TO_STRING_PRETTY));
+ json_object_free(json);
+ }
+}
+
+/* pim statistics - just adding only bsm related now.
+ * We can continue to add all pim related stats here.
+ */
+static void pim_show_statistics(struct pim_instance *pim, struct vty *vty,
+ const char *ifname, bool uj)
+{
+ json_object *json = NULL;
+ struct interface *ifp;
+
+ if (uj) {
+ json = json_object_new_object();
+ json_object_int_add(json, "Number of Received BSMs",
+ pim->bsm_rcvd);
+ json_object_int_add(json, "Number of Forwared BSMs",
+ pim->bsm_sent);
+ json_object_int_add(json, "Number of Dropped BSMs",
+ pim->bsm_dropped);
+ } else {
+ vty_out(vty, "BSM Statistics :\n");
+ vty_out(vty, "----------------\n");
+ vty_out(vty, "Number of Received BSMs : %" PRIu64 "\n",
+ pim->bsm_rcvd);
+ vty_out(vty, "Number of Forwared BSMs : %" PRIu64 "\n",
+ pim->bsm_sent);
+ vty_out(vty, "Number of Dropped BSMs : %" PRIu64 "\n",
+ pim->bsm_dropped);
+ }
+
+ vty_out(vty, "\n");
+
+ /* scan interfaces */
+ FOR_ALL_INTERFACES (pim->vrf, ifp) {
+ struct pim_interface *pim_ifp = ifp->info;
+
+ if (ifname && strcmp(ifname, ifp->name))
+ continue;
+
+ if (!pim_ifp)
+ continue;
+
+ if (!uj) {
+ vty_out(vty, "Interface : %s\n", ifp->name);
+ vty_out(vty, "-------------------\n");
+ vty_out(vty,
+ "Number of BSMs dropped due to config miss : %u\n",
+ pim_ifp->pim_ifstat_bsm_cfg_miss);
+ vty_out(vty, "Number of unicast BSMs dropped : %u\n",
+ pim_ifp->pim_ifstat_ucast_bsm_cfg_miss);
+ vty_out(vty,
+ "Number of BSMs dropped due to invalid scope zone : %u\n",
+ pim_ifp->pim_ifstat_bsm_invalid_sz);
+ } else {
+
+ json_object *json_row = NULL;
+
+ json_row = json_object_new_object();
+
+ json_object_string_add(json_row, "If Name", ifp->name);
+ json_object_int_add(
+ json_row,
+ "Number of BSMs dropped due to config miss",
+ pim_ifp->pim_ifstat_bsm_cfg_miss);
+ json_object_int_add(
+ json_row, "Number of unicast BSMs dropped",
+ pim_ifp->pim_ifstat_ucast_bsm_cfg_miss);
+ json_object_int_add(json_row,
+ "Number of BSMs dropped due to invalid scope zone",
+ pim_ifp->pim_ifstat_bsm_invalid_sz);
+ json_object_object_add(json, ifp->name, json_row);
+ }
+ vty_out(vty, "\n");
+ }
+
+ if (uj) {
+ vty_out(vty, "%s\n", json_object_to_json_string_ext(
+ json, JSON_C_TO_STRING_PRETTY));
+ json_object_free(json);
+ }
+}
+
+static void clear_pim_statistics(struct pim_instance *pim)
+{
+ struct interface *ifp;
+
+ pim->bsm_rcvd = 0;
+ pim->bsm_sent = 0;
+ pim->bsm_dropped = 0;
+
+ /* scan interfaces */
+ FOR_ALL_INTERFACES (pim->vrf, ifp) {
+ struct pim_interface *pim_ifp = ifp->info;
+
+ if (!pim_ifp)
+ continue;
+
+ pim_ifp->pim_ifstat_bsm_cfg_miss = 0;
+ pim_ifp->pim_ifstat_ucast_bsm_cfg_miss = 0;
+ pim_ifp->pim_ifstat_bsm_invalid_sz = 0;
+ }
+}
+
static void igmp_show_groups(struct pim_instance *pim, struct vty *vty, bool uj)
{
struct interface *ifp;
} /* scan interfaces */
}
+static void pim_show_bsr(struct pim_instance *pim,
+ struct vty *vty,
+ bool uj)
+{
+ char uptime[10];
+ char last_bsm_seen[10];
+ time_t now;
+ char bsr_state[20];
+ char bsr_str[PREFIX_STRLEN];
+ json_object *json = NULL;
+
+ vty_out(vty, "PIMv2 Bootstrap information\n");
+
+ if (pim->global_scope.current_bsr.s_addr == INADDR_ANY) {
+ strlcpy(bsr_str, "0.0.0.0", sizeof(bsr_str));
+ pim_time_uptime(uptime, sizeof(uptime),
+ pim->global_scope.current_bsr_first_ts);
+ pim_time_uptime(last_bsm_seen, sizeof(last_bsm_seen),
+ pim->global_scope.current_bsr_last_ts);
+ }
+
+ else {
+ pim_inet4_dump("<bsr?>", pim->global_scope.current_bsr,
+ bsr_str, sizeof(bsr_str));
+ now = pim_time_monotonic_sec();
+ pim_time_uptime(uptime, sizeof(uptime),
+ (now - pim->global_scope.current_bsr_first_ts));
+ pim_time_uptime(last_bsm_seen, sizeof(last_bsm_seen),
+ now - pim->global_scope.current_bsr_last_ts);
+ }
+
+ switch (pim->global_scope.state) {
+ case NO_INFO:
+ strlcpy(bsr_state, "NO_INFO", sizeof(bsr_state));
+ break;
+ case ACCEPT_ANY:
+ strlcpy(bsr_state, "ACCEPT_ANY", sizeof(bsr_state));
+ break;
+ case ACCEPT_PREFERRED:
+ strlcpy(bsr_state, "ACCEPT_PREFERRED", sizeof(bsr_state));
+ break;
+ default:
+ strlcpy(bsr_state, "", sizeof(bsr_state));
+ }
+
+ if (uj) {
+ json = json_object_new_object();
+ json_object_string_add(json, "bsr", bsr_str);
+ json_object_int_add(json, "priority",
+ pim->global_scope.current_bsr_prio);
+ json_object_int_add(json, "fragment_tag",
+ pim->global_scope.bsm_frag_tag);
+ json_object_string_add(json, "state", bsr_state);
+ json_object_string_add(json, "upTime", uptime);
+ json_object_string_add(json, "last_bsm_seen", last_bsm_seen);
+ }
+
+ else {
+ vty_out(vty, "Current preferred BSR address: %s\n", bsr_str);
+ vty_out(vty,
+ "Priority Fragment-Tag State UpTime\n");
+ vty_out(vty, " %-12d %-12d %-13s %7s\n",
+ pim->global_scope.current_bsr_prio,
+ pim->global_scope.bsm_frag_tag,
+ bsr_state,
+ uptime);
+ vty_out(vty, "Last BSM seen: %s\n", last_bsm_seen);
+ }
+
+ if (uj) {
+ vty_out(vty, "%s\n", json_object_to_json_string_ext(
+ json, JSON_C_TO_STRING_PRETTY));
+ json_object_free(json);
+ }
+}
+
static void clear_igmp_interfaces(struct pim_instance *pim)
{
struct interface *ifp;
return CMD_SUCCESS;
}
-static void mroute_add_all(struct pim_instance *pim)
+DEFUN (clear_ip_pim_statistics,
+ clear_ip_pim_statistics_cmd,
+ "clear ip pim statistics [vrf NAME]",
+ CLEAR_STR
+ IP_STR
+ CLEAR_IP_PIM_STR
+ VRF_CMD_HELP_STR
+ "Reset PIM statistics\n")
{
- struct listnode *node;
- struct channel_oil *c_oil;
+ int idx = 2;
+ struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
- for (ALL_LIST_ELEMENTS_RO(pim->channel_oil_list, node, c_oil)) {
- if (pim_mroute_add(c_oil, __PRETTY_FUNCTION__)) {
- /* just log warning */
- char source_str[INET_ADDRSTRLEN];
- char group_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin,
- source_str, sizeof(source_str));
- pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp,
- group_str, sizeof(group_str));
- zlog_warn("%s %s: (S,G)=(%s,%s) failure writing MFC",
- __FILE__, __PRETTY_FUNCTION__, source_str,
- group_str);
- }
- }
+ if (!vrf)
+ return CMD_WARNING;
+
+ clear_pim_statistics(vrf->info);
+ return CMD_SUCCESS;
}
-static void mroute_del_all(struct pim_instance *pim)
+static void clear_mroute(struct pim_instance *pim)
{
- struct listnode *node;
- struct channel_oil *c_oil;
+ struct pim_upstream *up;
+ struct interface *ifp;
- for (ALL_LIST_ELEMENTS_RO(pim->channel_oil_list, node, c_oil)) {
- if (pim_mroute_del(c_oil, __PRETTY_FUNCTION__)) {
- /* just log warning */
- char source_str[INET_ADDRSTRLEN];
- char group_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin,
- source_str, sizeof(source_str));
- pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp,
- group_str, sizeof(group_str));
- zlog_warn("%s %s: (S,G)=(%s,%s) failure clearing MFC",
- __FILE__, __PRETTY_FUNCTION__, source_str,
- group_str);
+ /* scan interfaces */
+ FOR_ALL_INTERFACES (pim->vrf, ifp) {
+ struct pim_interface *pim_ifp = ifp->info;
+ struct listnode *sock_node;
+ struct igmp_sock *igmp;
+ struct pim_ifchannel *ch;
+
+ if (!pim_ifp)
+ continue;
+
+ /* deleting all ifchannels */
+ while (!RB_EMPTY(pim_ifchannel_rb, &pim_ifp->ifchannel_rb)) {
+ ch = RB_ROOT(pim_ifchannel_rb, &pim_ifp->ifchannel_rb);
+
+ pim_ifchannel_delete(ch);
+ }
+
+ /* clean up all igmp groups */
+ /* scan igmp sockets */
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node,
+ igmp)) {
+
+ struct igmp_group *grp;
+
+ if (igmp->igmp_group_list) {
+ while (igmp->igmp_group_list->count) {
+ grp = listnode_head(
+ igmp->igmp_group_list);
+ igmp_group_delete(grp);
+ }
+ }
+
+ }
+ }
+
+ /* clean up all upstreams*/
+ if (pim->upstream_list) {
+ while (pim->upstream_list->count) {
+ up = listnode_head(pim->upstream_list);
+ pim_upstream_del(pim, up, __PRETTY_FUNCTION__);
}
}
}
if (!vrf)
return CMD_WARNING;
- mroute_del_all(vrf->info);
- mroute_add_all(vrf->info);
+ clear_mroute(vrf->info);
return CMD_SUCCESS;
}
pim_ifp->pim_ifstat_reg_stop_send = 0;
pim_ifp->pim_ifstat_assert_recv = 0;
pim_ifp->pim_ifstat_assert_send = 0;
+ pim_ifp->pim_ifstat_bsm_rx = 0;
+ pim_ifp->pim_ifstat_bsm_tx = 0;
}
return CMD_SUCCESS;
return CMD_SUCCESS;
}
+DEFUN (show_ip_pim_bsm_db,
+ show_ip_pim_bsm_db_cmd,
+ "show ip pim bsm-database [vrf NAME] [json]",
+ SHOW_STR
+ IP_STR
+ PIM_STR
+ VRF_CMD_HELP_STR
+ "PIM cached bsm packets information\n"
+ JSON_STR)
+{
+ int idx = 2;
+ struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
+ bool uj = use_json(argc, argv);
+
+ if (!vrf)
+ return CMD_WARNING;
+
+ pim_show_bsm_db(vrf->info, vty, uj);
+ return CMD_SUCCESS;
+}
+
+DEFUN (show_ip_pim_bsrp,
+ show_ip_pim_bsrp_cmd,
+ "show ip pim bsrp-info [vrf NAME] [json]",
+ SHOW_STR
+ IP_STR
+ PIM_STR
+ VRF_CMD_HELP_STR
+ "PIM cached group-rp mappings information\n"
+ JSON_STR)
+{
+ int idx = 2;
+ struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
+ bool uj = use_json(argc, argv);
+
+ if (!vrf)
+ return CMD_WARNING;
+
+ pim_show_group_rp_mappings_info(vrf->info, vty, uj);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (show_ip_pim_statistics,
+ show_ip_pim_statistics_cmd,
+ "show ip pim [vrf NAME] statistics [interface WORD] [json]",
+ SHOW_STR
+ IP_STR
+ PIM_STR
+ VRF_CMD_HELP_STR
+ "PIM statistics\n"
+ "interface\n"
+ "PIM interface\n"
+ JSON_STR)
+{
+ int idx = 2;
+ struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
+ bool uj = use_json(argc, argv);
+
+ if (!vrf)
+ return CMD_WARNING;
+
+ if (argv_find(argv, argc, "WORD", &idx))
+ pim_show_statistics(vrf->info, vty, argv[idx]->arg, uj);
+ else
+ pim_show_statistics(vrf->info, vty, NULL, uj);
+
+ return CMD_SUCCESS;
+}
+
static void show_multicast_interfaces(struct pim_instance *pim, struct vty *vty)
{
struct interface *ifp;
ifp_in = pim_if_find_by_vif_index(pim, c_oil->oil.mfcc_parent);
if (ifp_in)
- strcpy(in_ifname, ifp_in->name);
+ strlcpy(in_ifname, ifp_in->name, sizeof(in_ifname));
else
- strcpy(in_ifname, "<iif?>");
+ strlcpy(in_ifname, "<iif?>", sizeof(in_ifname));
if (uj) {
found_oif = 1;
if (ifp_out)
- strcpy(out_ifname, ifp_out->name);
+ strlcpy(out_ifname, ifp_out->name, sizeof(out_ifname));
else
- strcpy(out_ifname, "<oif?>");
+ strlcpy(out_ifname, "<oif?>", sizeof(out_ifname));
if (uj) {
json_ifp_out = json_object_new_object();
json_object_boolean_true_add(
json_ifp_out, "protocolVxlan");
- if (c_oil->oif_flags[oif_vif_index]
- & PIM_OIF_FLAG_PROTO_SOURCE)
- json_object_boolean_true_add(
- json_ifp_out, "protocolSource");
-
if (c_oil->oif_flags[oif_vif_index]
& PIM_OIF_FLAG_PROTO_STAR)
json_object_boolean_true_add(
} else {
if (c_oil->oif_flags[oif_vif_index]
& PIM_OIF_FLAG_PROTO_PIM) {
- strcpy(proto, "PIM");
+ strlcpy(proto, "PIM", sizeof(proto));
}
if (c_oil->oif_flags[oif_vif_index]
& PIM_OIF_FLAG_PROTO_IGMP) {
- strcpy(proto, "IGMP");
+ strlcpy(proto, "IGMP", sizeof(proto));
}
if (c_oil->oif_flags[oif_vif_index]
& PIM_OIF_FLAG_PROTO_VXLAN) {
- strcpy(proto, "VxLAN");
- }
-
- if (c_oil->oif_flags[oif_vif_index]
- & PIM_OIF_FLAG_PROTO_SOURCE) {
- strcpy(proto, "SRC");
+ strlcpy(proto, "VxLAN", sizeof(proto));
}
if (c_oil->oif_flags[oif_vif_index]
& PIM_OIF_FLAG_PROTO_STAR) {
- strcpy(proto, "STAR");
+ strlcpy(proto, "STAR", sizeof(proto));
}
vty_out(vty,
found_oif = 0;
if (ifp_in)
- strcpy(in_ifname, ifp_in->name);
+ strlcpy(in_ifname, ifp_in->name, sizeof(in_ifname));
else
- strcpy(in_ifname, "<iif?>");
+ strlcpy(in_ifname, "<iif?>", sizeof(in_ifname));
if (uj) {
json_object_string_add(json_source, "iif", in_ifname);
json_oil = NULL;
} else {
- strcpy(proto, "STATIC");
+ strlcpy(proto, "STATIC", sizeof(proto));
}
for (oif_vif_index = 0; oif_vif_index < MAXVIFS;
found_oif = 1;
if (ifp_out)
- strcpy(out_ifname, ifp_out->name);
+ strlcpy(out_ifname, ifp_out->name, sizeof(out_ifname));
else
- strcpy(out_ifname, "<oif?>");
+ strlcpy(out_ifname, "<oif?>", sizeof(out_ifname));
if (uj) {
json_ifp_out = json_object_new_object();
if (argv_find(argv, argc, "fill", &idx))
fill = true;
- if (uj)
- vty_out(vty, "{ ");
- RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
- if (uj) {
- if (!first)
- vty_out(vty, ", ");
- vty_out(vty, " \"%s\": ", vrf->name);
- first = false;
- } else
- vty_out(vty, "VRF: %s\n", vrf->name);
- show_mroute(vrf->info, vty, &sg, fill, uj);
+ if (uj)
+ vty_out(vty, "{ ");
+ RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
+ if (uj) {
+ if (!first)
+ vty_out(vty, ", ");
+ vty_out(vty, " \"%s\": ", vrf->name);
+ first = false;
+ } else
+ vty_out(vty, "VRF: %s\n", vrf->name);
+ show_mroute(vrf->info, vty, &sg, fill, uj);
+ }
+ if (uj)
+ vty_out(vty, "}\n");
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (clear_ip_mroute_count,
+ clear_ip_mroute_count_cmd,
+ "clear ip mroute [vrf NAME] count",
+ CLEAR_STR
+ IP_STR
+ MROUTE_STR
+ VRF_CMD_HELP_STR
+ "Route and packet count data\n")
+{
+ int idx = 2;
+ struct listnode *node;
+ struct channel_oil *c_oil;
+ struct static_route *sr;
+ struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
+ struct pim_instance *pim;
+
+ if (!vrf)
+ return CMD_WARNING;
+
+ pim = vrf->info;
+ for (ALL_LIST_ELEMENTS_RO(pim->channel_oil_list, node, c_oil)) {
+ if (!c_oil->installed)
+ continue;
+
+ pim_mroute_update_counters(c_oil);
+ c_oil->cc.origpktcnt = c_oil->cc.pktcnt;
+ c_oil->cc.origbytecnt = c_oil->cc.bytecnt;
+ c_oil->cc.origwrong_if = c_oil->cc.wrong_if;
}
- if (uj)
- vty_out(vty, "}\n");
+ for (ALL_LIST_ELEMENTS_RO(pim->static_routes, node, sr)) {
+ if (!sr->c_oil.installed)
+ continue;
+
+ pim_mroute_update_counters(&sr->c_oil);
+
+ sr->c_oil.cc.origpktcnt = sr->c_oil.cc.pktcnt;
+ sr->c_oil.cc.origbytecnt = sr->c_oil.cc.bytecnt;
+ sr->c_oil.cc.origwrong_if = sr->c_oil.cc.wrong_if;
+ }
return CMD_SUCCESS;
}
{
struct listnode *node;
struct channel_oil *c_oil;
- struct static_route *s_route;
+ struct static_route *sr;
vty_out(vty, "\n");
vty_out(vty, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
source_str, group_str, c_oil->cc.lastused / 100,
- c_oil->cc.pktcnt, c_oil->cc.bytecnt,
- c_oil->cc.wrong_if);
+ c_oil->cc.pktcnt - c_oil->cc.origpktcnt,
+ c_oil->cc.bytecnt - c_oil->cc.origbytecnt,
+ c_oil->cc.wrong_if - c_oil->cc.origwrong_if);
}
- for (ALL_LIST_ELEMENTS_RO(pim->static_routes, node, s_route)) {
+ for (ALL_LIST_ELEMENTS_RO(pim->static_routes, node, sr)) {
char group_str[INET_ADDRSTRLEN];
char source_str[INET_ADDRSTRLEN];
- if (!s_route->c_oil.installed)
+ if (!sr->c_oil.installed)
continue;
- pim_mroute_update_counters(&s_route->c_oil);
+ pim_mroute_update_counters(&sr->c_oil);
- pim_inet4_dump("<group?>", s_route->c_oil.oil.mfcc_mcastgrp,
+ pim_inet4_dump("<group?>", sr->c_oil.oil.mfcc_mcastgrp,
group_str, sizeof(group_str));
- pim_inet4_dump("<source?>", s_route->c_oil.oil.mfcc_origin,
+ pim_inet4_dump("<source?>", sr->c_oil.oil.mfcc_origin,
source_str, sizeof(source_str));
vty_out(vty, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
- source_str, group_str, s_route->c_oil.cc.lastused,
- s_route->c_oil.cc.pktcnt, s_route->c_oil.cc.bytecnt,
- s_route->c_oil.cc.wrong_if);
+ source_str, group_str, sr->c_oil.cc.lastused,
+ sr->c_oil.cc.pktcnt - sr->c_oil.cc.origpktcnt,
+ sr->c_oil.cc.bytecnt - sr->c_oil.cc.origbytecnt,
+ sr->c_oil.cc.wrong_if - sr->c_oil.cc.origwrong_if);
}
}
return CMD_SUCCESS;
}
+static void show_mroute_summary(struct pim_instance *pim, struct vty *vty)
+{
+ struct listnode *node;
+ struct channel_oil *c_oil;
+ struct static_route *s_route;
+ uint32_t starg_sw_mroute_cnt = 0;
+ uint32_t sg_sw_mroute_cnt = 0;
+ uint32_t starg_hw_mroute_cnt = 0;
+ uint32_t sg_hw_mroute_cnt = 0;
+
+ vty_out(vty, "Mroute Type Installed/Total\n");
+
+ for (ALL_LIST_ELEMENTS_RO(pim->channel_oil_list, node, c_oil)) {
+ if (!c_oil->installed) {
+ if (c_oil->oil.mfcc_origin.s_addr == INADDR_ANY)
+ starg_sw_mroute_cnt++;
+ else
+ sg_sw_mroute_cnt++;
+ } else {
+ if (c_oil->oil.mfcc_origin.s_addr == INADDR_ANY)
+ starg_hw_mroute_cnt++;
+ else
+ sg_hw_mroute_cnt++;
+ }
+ }
+
+ for (ALL_LIST_ELEMENTS_RO(pim->static_routes, node, s_route)) {
+ if (!s_route->c_oil.installed) {
+ if (s_route->c_oil.oil.mfcc_origin.s_addr == INADDR_ANY)
+ starg_sw_mroute_cnt++;
+ else
+ sg_sw_mroute_cnt++;
+ } else {
+ if (s_route->c_oil.oil.mfcc_origin.s_addr == INADDR_ANY)
+ starg_hw_mroute_cnt++;
+ else
+ sg_hw_mroute_cnt++;
+ }
+ }
+
+ vty_out(vty, "%-20s %d/%d\n", "(*, G)", starg_hw_mroute_cnt,
+ starg_sw_mroute_cnt + starg_hw_mroute_cnt);
+ vty_out(vty, "%-20s %d/%d\n", "(S, G)", sg_hw_mroute_cnt,
+ sg_sw_mroute_cnt + sg_hw_mroute_cnt);
+ vty_out(vty, "------\n");
+ vty_out(vty, "%-20s %d/%d\n", "Total",
+ (starg_hw_mroute_cnt + sg_hw_mroute_cnt),
+ (starg_sw_mroute_cnt +
+ starg_hw_mroute_cnt +
+ sg_sw_mroute_cnt +
+ sg_hw_mroute_cnt));
+}
+
+DEFUN (show_ip_mroute_summary,
+ show_ip_mroute_summary_cmd,
+ "show ip mroute [vrf NAME] summary",
+ SHOW_STR
+ IP_STR
+ MROUTE_STR
+ VRF_CMD_HELP_STR
+ "Summary of all mroutes\n")
+{
+ int idx = 2;
+ struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
+
+ if (!vrf)
+ return CMD_WARNING;
+
+ show_mroute_summary(vrf->info, vty);
+ return CMD_SUCCESS;
+}
+
+DEFUN (show_ip_mroute_summary_vrf_all,
+ show_ip_mroute_summary_vrf_all_cmd,
+ "show ip mroute vrf all summary",
+ SHOW_STR
+ IP_STR
+ MROUTE_STR
+ VRF_CMD_HELP_STR
+ "Summary of all mroutes\n")
+{
+ struct vrf *vrf;
+
+ RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
+ vty_out(vty, "VRF: %s\n", vrf->name);
+ show_mroute_summary(vrf->info, vty);
+ }
+
+ return CMD_SUCCESS;
+}
+
DEFUN (show_ip_rib,
show_ip_rib_cmd,
"show ip rib [vrf NAME] A.B.C.D",
{
int result;
- result = pim_rp_new(pim, rp, group, plist);
+ result = pim_rp_new_config(pim, rp, group, plist);
+
+ if (result == PIM_GROUP_BAD_ADDR_MASK_COMBO) {
+ vty_out(vty, "%% Inconsistent address and mask: %s\n",
+ group);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
if (result == PIM_GROUP_BAD_ADDRESS) {
vty_out(vty, "%% Bad group address specified: %s\n", group);
const char *rp, const char *group,
const char *plist)
{
- int result = pim_rp_del(pim, rp, group, plist);
+ int result = pim_rp_del_config(pim, rp, group, plist);
if (result == PIM_GROUP_BAD_ADDRESS) {
vty_out(vty, "%% Bad group address specified: %s\n", group);
return CMD_SUCCESS;
}
+DEFUN (show_ip_pim_bsr,
+ show_ip_pim_bsr_cmd,
+ "show ip pim bsr [json]",
+ SHOW_STR
+ IP_STR
+ PIM_STR
+ "boot-strap router information\n"
+ JSON_STR)
+{
+ int idx = 2;
+ struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
+ bool uj = use_json(argc, argv);
+
+ if (!vrf)
+ return CMD_WARNING;
+
+ pim_show_bsr(vrf->info, vty, uj);
+
+ return CMD_SUCCESS;
+}
+
DEFUN (ip_ssmpingd,
ip_ssmpingd_cmd,
"ip ssmpingd [A.B.C.D]",
return CMD_SUCCESS;
}
+#define IGMP_LAST_MEMBER_QUERY_COUNT_MIN (1)
+#define IGMP_LAST_MEMBER_QUERY_COUNT_MAX (7)
+
+DEFUN (interface_ip_igmp_last_member_query_count,
+ interface_ip_igmp_last_member_query_count_cmd,
+ "ip igmp last-member-query-count (1-7)",
+ IP_STR
+ IFACE_IGMP_STR
+ IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR
+ "Last member query count\n")
+{
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct pim_interface *pim_ifp = ifp->info;
+ int last_member_query_count;
+ int ret;
+
+ if (!pim_ifp) {
+ ret = pim_cmd_igmp_start(vty, ifp);
+ if (ret != CMD_SUCCESS)
+ return ret;
+ pim_ifp = ifp->info;
+ }
+
+ last_member_query_count = atoi(argv[3]->arg);
+
+ pim_ifp->igmp_last_member_query_count = last_member_query_count;
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (interface_no_ip_igmp_last_member_query_count,
+ interface_no_ip_igmp_last_member_query_count_cmd,
+ "no ip igmp last-member-query-count",
+ NO_STR
+ IP_STR
+ IFACE_IGMP_STR
+ IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR)
+{
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct pim_interface *pim_ifp = ifp->info;
+
+ if (!pim_ifp)
+ return CMD_SUCCESS;
+
+ pim_ifp->igmp_last_member_query_count =
+ IGMP_DEFAULT_ROBUSTNESS_VARIABLE;
+
+ return CMD_SUCCESS;
+}
+
+#define IGMP_LAST_MEMBER_QUERY_INTERVAL_MIN (1)
+#define IGMP_LAST_MEMBER_QUERY_INTERVAL_MAX (255)
+
+DEFUN (interface_ip_igmp_last_member_query_interval,
+ interface_ip_igmp_last_member_query_interval_cmd,
+ "ip igmp last-member-query-interval (1-255)",
+ IP_STR
+ IFACE_IGMP_STR
+ IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR
+ "Last member query interval in deciseconds\n")
+{
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct pim_interface *pim_ifp = ifp->info;
+ int last_member_query_interval;
+ int ret;
+
+ if (!pim_ifp) {
+ ret = pim_cmd_igmp_start(vty, ifp);
+ if (ret != CMD_SUCCESS)
+ return ret;
+ pim_ifp = ifp->info;
+ }
+
+ last_member_query_interval = atoi(argv[3]->arg);
+ pim_ifp->igmp_specific_query_max_response_time_dsec
+ = last_member_query_interval;
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (interface_no_ip_igmp_last_member_query_interval,
+ interface_no_ip_igmp_last_member_query_interval_cmd,
+ "no ip igmp last-member-query-interval",
+ NO_STR
+ IP_STR
+ IFACE_IGMP_STR
+ IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR)
+{
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct pim_interface *pim_ifp = ifp->info;
+
+ if (!pim_ifp)
+ return CMD_SUCCESS;
+
+ pim_ifp->igmp_specific_query_max_response_time_dsec =
+ IGMP_SPECIFIC_QUERY_MAX_RESPONSE_TIME_DSEC;
+
+ return CMD_SUCCESS;
+}
+
DEFUN (interface_ip_pim_drprio,
interface_ip_pim_drprio_cmd,
"ip pim drpriority (1-4294967295)",
pim = pim_ifp->pim;
oifname = argv[idx_interface]->arg;
- oif = if_lookup_by_name(oifname, pim->vrf_id);
+ oif = if_lookup_by_name(oifname, pim->vrf);
if (!oif) {
vty_out(vty, "No such interface name %s\n", oifname);
return CMD_WARNING;
pim = pim_ifp->pim;
oifname = argv[idx_interface]->arg;
- oif = if_lookup_by_name(oifname, pim->vrf_id);
+ oif = if_lookup_by_name(oifname, pim->vrf);
if (!oif) {
vty_out(vty, "No such interface name %s\n", oifname);
return CMD_WARNING;
pim = pim_ifp->pim;
oifname = argv[idx_interface]->arg;
- oif = if_lookup_by_name(oifname, pim->vrf_id);
+ oif = if_lookup_by_name(oifname, pim->vrf);
if (!oif) {
vty_out(vty, "No such interface name %s\n", oifname);
return CMD_WARNING;
pim = pim_ifp->pim;
oifname = argv[idx_interface]->arg;
- oif = if_lookup_by_name(oifname, pim->vrf_id);
+ oif = if_lookup_by_name(oifname, pim->vrf);
if (!oif) {
vty_out(vty, "No such interface name %s\n", oifname);
return CMD_WARNING;
PIM_DO_DEBUG_PIM_TRACE;
PIM_DO_DEBUG_MSDP_EVENTS;
PIM_DO_DEBUG_MSDP_PACKETS;
+ PIM_DO_DEBUG_BSM;
return CMD_SUCCESS;
}
PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND;
PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV;
+ PIM_DONT_DEBUG_BSM;
return CMD_SUCCESS;
}
return CMD_SUCCESS;
}
+DEFUN (debug_bsm,
+ debug_bsm_cmd,
+ "debug pim bsm",
+ DEBUG_STR
+ DEBUG_PIM_STR
+ DEBUG_PIM_BSM_STR)
+{
+ PIM_DO_DEBUG_BSM;
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_debug_bsm,
+ no_debug_bsm_cmd,
+ "no debug pim bsm",
+ NO_STR
+ DEBUG_STR
+ DEBUG_PIM_STR
+ DEBUG_PIM_BSM_STR)
+{
+ PIM_DONT_DEBUG_BSM;
+ return CMD_SUCCESS;
+}
+
+
DEFUN_NOSH (show_debugging_pim,
show_debugging_pim_cmd,
"show debugging [pim]",
return CMD_SUCCESS;
}
+DEFUN (ip_pim_bsm,
+ ip_pim_bsm_cmd,
+ "ip pim bsm",
+ IP_STR
+ PIM_STR
+ "Enables BSM support on the interface\n")
+{
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct pim_interface *pim_ifp = ifp->info;
+
+ if (!pim_ifp) {
+ if (!pim_cmd_interface_add(ifp)) {
+ vty_out(vty, "Could not enable PIM SM on interface\n");
+ return CMD_WARNING;
+ }
+ }
+
+ pim_ifp = ifp->info;
+ pim_ifp->bsm_enable = true;
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_ip_pim_bsm,
+ no_ip_pim_bsm_cmd,
+ "no ip pim bsm",
+ NO_STR
+ IP_STR
+ PIM_STR
+ "Disables BSM support\n")
+{
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct pim_interface *pim_ifp = ifp->info;
+
+ if (!pim_ifp) {
+ vty_out(vty, "Pim not enabled on this interface\n");
+ return CMD_WARNING;
+ }
+
+ pim_ifp->bsm_enable = false;
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (ip_pim_ucast_bsm,
+ ip_pim_ucast_bsm_cmd,
+ "ip pim unicast-bsm",
+ IP_STR
+ PIM_STR
+ "Accept/Send unicast BSM on the interface\n")
+{
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct pim_interface *pim_ifp = ifp->info;
+
+ if (!pim_ifp) {
+ if (!pim_cmd_interface_add(ifp)) {
+ vty_out(vty, "Could not enable PIM SM on interface\n");
+ return CMD_WARNING;
+ }
+ }
+
+ pim_ifp = ifp->info;
+ pim_ifp->ucast_bsm_accept = true;
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_ip_pim_ucast_bsm,
+ no_ip_pim_ucast_bsm_cmd,
+ "no ip pim unicast-bsm",
+ NO_STR
+ IP_STR
+ PIM_STR
+ "Block send/receive unicast BSM on this interface\n")
+{
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct pim_interface *pim_ifp = ifp->info;
+
+ if (!pim_ifp) {
+ vty_out(vty, "Pim not enabled on this interface\n");
+ return CMD_WARNING;
+ }
+
+ pim_ifp->ucast_bsm_accept = false;
+
+ return CMD_SUCCESS;
+}
+
#if HAVE_BFDD > 0
DEFUN_HIDDEN(
+ ip_pim_bfd_param,
+ ip_pim_bfd_param_cmd,
+ "ip pim bfd (2-255) (50-60000) (50-60000)",
+ IP_STR
+ PIM_STR
+ "Enables BFD support\n"
+ "Detect Multiplier\n"
+ "Required min receive interval\n"
+ "Desired min transmit interval\n")
#else
DEFUN(
-#endif /* HAVE_BFDD */
ip_pim_bfd_param,
ip_pim_bfd_param_cmd,
"ip pim bfd (2-255) (50-60000) (50-60000)",
"Detect Multiplier\n"
"Required min receive interval\n"
"Desired min transmit interval\n")
+#endif /* HAVE_BFDD */
{
VTY_DECLVAR_CONTEXT(interface, ifp);
int idx_number = 3;
pim_time_uptime(timebuf, sizeof(timebuf),
now - mp->uptime);
} else {
- strcpy(timebuf, "-");
+ strlcpy(timebuf, "-", sizeof(timebuf));
}
pim_inet4_dump("<peer?>", mp->peer, peer_str, sizeof(peer_str));
pim_inet4_dump("<local?>", mp->local, local_str,
pim_time_uptime(timebuf, sizeof(timebuf),
now - mp->uptime);
} else {
- strcpy(timebuf, "-");
+ strlcpy(timebuf, "-", sizeof(timebuf));
}
pim_inet4_dump("<local?>", mp->local, local_str,
sizeof(local_str));
if (sa->flags & PIM_MSDP_SAF_PEER) {
pim_inet4_dump("<rp?>", sa->rp, rp_str, sizeof(rp_str));
if (sa->up) {
- strcpy(spt_str, "yes");
+ strlcpy(spt_str, "yes", sizeof(spt_str));
} else {
- strcpy(spt_str, "no");
+ strlcpy(spt_str, "no", sizeof(spt_str));
}
} else {
- strcpy(rp_str, "-");
- strcpy(spt_str, "-");
+ strlcpy(rp_str, "-", sizeof(rp_str));
+ strlcpy(spt_str, "-", sizeof(spt_str));
}
if (sa->flags & PIM_MSDP_SAF_LOCAL) {
- strcpy(local_str, "yes");
+ strlcpy(local_str, "yes", sizeof(local_str));
} else {
- strcpy(local_str, "no");
+ strlcpy(local_str, "no", sizeof(local_str));
}
if (uj) {
json_object_object_get_ex(json, grp_str, &json_group);
pim_inet4_dump("<rp?>", sa->rp, rp_str, sizeof(rp_str));
pim_inet4_dump("<peer?>", sa->peer, peer_str, sizeof(peer_str));
if (sa->up) {
- strcpy(spt_str, "yes");
+ strlcpy(spt_str, "yes", sizeof(spt_str));
} else {
- strcpy(spt_str, "no");
+ strlcpy(spt_str, "no", sizeof(spt_str));
}
} else {
- strcpy(rp_str, "-");
- strcpy(peer_str, "-");
- strcpy(spt_str, "-");
+ strlcpy(rp_str, "-", sizeof(rp_str));
+ strlcpy(peer_str, "-", sizeof(peer_str));
+ strlcpy(spt_str, "-", sizeof(spt_str));
}
if (sa->flags & PIM_MSDP_SAF_LOCAL) {
- strcpy(local_str, "yes");
+ strlcpy(local_str, "yes", sizeof(local_str));
} else {
- strcpy(local_str, "no");
+ strlcpy(local_str, "no", sizeof(local_str));
}
pim_time_timer_to_hhmmss(statetimer, sizeof(statetimer),
sa->sa_state_timer);
idx = 3;
peerlink = argv[idx]->arg;
- ifp = if_lookup_by_name(peerlink, VRF_DEFAULT);
+ ifp = if_lookup_by_name(peerlink, vrf_lookup_by_id(VRF_DEFAULT));
if (!ifp) {
vty_out(vty, "No such interface name %s\n", peerlink);
return CMD_WARNING;
&interface_ip_igmp_query_max_response_time_dsec_cmd);
install_element(INTERFACE_NODE,
&interface_no_ip_igmp_query_max_response_time_dsec_cmd);
+ install_element(INTERFACE_NODE,
+ &interface_ip_igmp_last_member_query_count_cmd);
+ install_element(INTERFACE_NODE,
+ &interface_no_ip_igmp_last_member_query_count_cmd);
+ install_element(INTERFACE_NODE,
+ &interface_ip_igmp_last_member_query_interval_cmd);
+ install_element(INTERFACE_NODE,
+ &interface_no_ip_igmp_last_member_query_interval_cmd);
install_element(INTERFACE_NODE, &interface_ip_pim_activeactive_cmd);
install_element(INTERFACE_NODE, &interface_ip_pim_ssm_cmd);
install_element(INTERFACE_NODE, &interface_no_ip_pim_ssm_cmd);
install_element(VIEW_NODE, &show_ip_pim_upstream_rpf_cmd);
install_element(VIEW_NODE, &show_ip_pim_rp_cmd);
install_element(VIEW_NODE, &show_ip_pim_rp_vrf_all_cmd);
+ install_element(VIEW_NODE, &show_ip_pim_bsr_cmd);
install_element(VIEW_NODE, &show_ip_multicast_cmd);
install_element(VIEW_NODE, &show_ip_multicast_vrf_all_cmd);
install_element(VIEW_NODE, &show_ip_mroute_cmd);
install_element(VIEW_NODE, &show_ip_mroute_vrf_all_cmd);
install_element(VIEW_NODE, &show_ip_mroute_count_cmd);
install_element(VIEW_NODE, &show_ip_mroute_count_vrf_all_cmd);
+ install_element(VIEW_NODE, &show_ip_mroute_summary_cmd);
+ install_element(VIEW_NODE, &show_ip_mroute_summary_vrf_all_cmd);
install_element(VIEW_NODE, &show_ip_rib_cmd);
install_element(VIEW_NODE, &show_ip_ssmpingd_cmd);
install_element(VIEW_NODE, &show_debugging_pim_cmd);
install_element(VIEW_NODE, &show_ip_pim_nexthop_cmd);
install_element(VIEW_NODE, &show_ip_pim_nexthop_lookup_cmd);
+ install_element(VIEW_NODE, &show_ip_pim_bsrp_cmd);
+ install_element(VIEW_NODE, &show_ip_pim_bsm_db_cmd);
+ install_element(VIEW_NODE, &show_ip_pim_statistics_cmd);
+ install_element(ENABLE_NODE, &clear_ip_mroute_count_cmd);
install_element(ENABLE_NODE, &clear_ip_interfaces_cmd);
install_element(ENABLE_NODE, &clear_ip_igmp_interfaces_cmd);
install_element(ENABLE_NODE, &clear_ip_mroute_cmd);
install_element(ENABLE_NODE, &clear_ip_pim_interfaces_cmd);
install_element(ENABLE_NODE, &clear_ip_pim_interface_traffic_cmd);
install_element(ENABLE_NODE, &clear_ip_pim_oil_cmd);
+ install_element(ENABLE_NODE, &clear_ip_pim_statistics_cmd);
install_element(ENABLE_NODE, &debug_igmp_cmd);
install_element(ENABLE_NODE, &no_debug_igmp_cmd);
install_element(ENABLE_NODE, &no_debug_msdp_packets_cmd);
install_element(ENABLE_NODE, &debug_mtrace_cmd);
install_element(ENABLE_NODE, &no_debug_mtrace_cmd);
+ install_element(ENABLE_NODE, &debug_bsm_cmd);
+ install_element(ENABLE_NODE, &no_debug_bsm_cmd);
install_element(CONFIG_NODE, &debug_igmp_cmd);
install_element(CONFIG_NODE, &no_debug_igmp_cmd);
install_element(CONFIG_NODE, &no_debug_msdp_packets_cmd);
install_element(CONFIG_NODE, &debug_mtrace_cmd);
install_element(CONFIG_NODE, &no_debug_mtrace_cmd);
+ install_element(CONFIG_NODE, &debug_bsm_cmd);
+ install_element(CONFIG_NODE, &no_debug_bsm_cmd);
install_element(CONFIG_NODE, &ip_msdp_mesh_group_member_cmd);
install_element(VRF_NODE, &ip_msdp_mesh_group_member_cmd);
install_element(VIEW_NODE, &show_ip_pim_vxlan_sg_work_cmd);
install_element(INTERFACE_NODE, &interface_pim_use_source_cmd);
install_element(INTERFACE_NODE, &interface_no_pim_use_source_cmd);
+ /* Install BSM command */
+ install_element(INTERFACE_NODE, &ip_pim_bsm_cmd);
+ install_element(INTERFACE_NODE, &no_ip_pim_bsm_cmd);
+ install_element(INTERFACE_NODE, &ip_pim_ucast_bsm_cmd);
+ install_element(INTERFACE_NODE, &no_ip_pim_ucast_bsm_cmd);
/* Install BFD command */
install_element(INTERFACE_NODE, &ip_pim_bfd_cmd);
install_element(INTERFACE_NODE, &ip_pim_bfd_param_cmd);