#include "pim_ssm.h"
#include "pim_nht.h"
#include "pim_bfd.h"
+#include "pim_vxlan.h"
#include "bfd.h"
#ifndef VTYSH_EXTRACT_PL
pim_time_uptime(uptime, sizeof(uptime), now - ch->ifassert_creation);
pim_time_timer_to_mmss(timer, sizeof(timer), ch->t_ifassert_timer);
- vty_out(vty, "%-9s %-15s %-15s %-15s %-6s %-15s %-8s %-5s\n",
+ vty_out(vty, "%-16s %-15s %-15s %-15s %-6s %-15s %-8s %-5s\n",
ch->interface->name, inet_ntoa(ifaddr), ch_src_str, ch_grp_str,
pim_ifchannel_ifassert_name(ch->ifassert_state), winner_str,
uptime, timer);
now = pim_time_monotonic_sec();
vty_out(vty,
- "Interface Address Source Group State Winner Uptime Timer\n");
+ "Interface Address Source Group State Winner Uptime Timer\n");
FOR_ALL_INTERFACES (pim->vrf, ifp) {
pim_ifp = ifp->info;
pim_inet4_dump("<ch_src?>", ch->sg.src, ch_src_str, sizeof(ch_src_str));
pim_inet4_dump("<ch_grp?>", ch->sg.grp, ch_grp_str, sizeof(ch_grp_str));
- vty_out(vty, "%-9s %-15s %-15s %-15s %-3s %-3s %-3s %-4s\n",
+ vty_out(vty, "%-16s %-15s %-15s %-15s %-3s %-3s %-3s %-4s\n",
ch->interface->name, inet_ntoa(ifaddr), ch_src_str, ch_grp_str,
PIM_IF_FLAG_TEST_COULD_ASSERT(ch->flags) ? "yes" : "no",
pim_macro_ch_could_assert_eval(ch) ? "yes" : "no",
"eATD: Evaluate AssertTrackingDesired\n\n");
vty_out(vty,
- "Interface Address Source Group CA eCA ATD eATD\n");
+ "Interface Address Source Group CA eCA ATD eATD\n");
FOR_ALL_INTERFACES (pim->vrf, ifp) {
pim_ifp = ifp->info;
if (!pim_ifp)
pim_inet4_dump("<ch_grp?>", ch->sg.grp, ch_grp_str, sizeof(ch_grp_str));
pim_inet4_dump("<addr?>", am.ip_address, addr_str, sizeof(addr_str));
- vty_out(vty, "%-9s %-15s %-15s %-15s %-3s %4u %6u %-15s\n",
+ vty_out(vty, "%-16s %-15s %-15s %-15s %-3s %4u %6u %-15s\n",
ch->interface->name, inet_ntoa(ifaddr), ch_src_str, ch_grp_str,
am.rpt_bit_flag ? "yes" : "no", am.metric_preference,
am.route_metric, addr_str);
struct interface *ifp;
vty_out(vty,
- "Interface Address Source Group RPT Pref Metric Address \n");
+ "Interface Address Source Group RPT Pref Metric Address \n");
FOR_ALL_INTERFACES (pim->vrf, ifp) {
pim_ifp = ifp->info;
else
snprintf(metr_str, sizeof(metr_str), "%6u", am->route_metric);
- vty_out(vty, "%-9s %-15s %-15s %-15s %-3s %-4s %-6s %-15s\n",
+ vty_out(vty, "%-16s %-15s %-15s %-15s %-3s %-4s %-6s %-15s\n",
ch->interface->name, inet_ntoa(ifaddr), ch_src_str, ch_grp_str,
am->rpt_bit_flag ? "yes" : "no", pref_str, metr_str, addr_str);
}
struct interface *ifp;
vty_out(vty,
- "Interface Address Source Group RPT Pref Metric Address \n");
+ "Interface Address Source Group RPT Pref Metric Address \n");
FOR_ALL_INTERFACES (pim->vrf, ifp) {
pim_ifp = ifp->info;
json, JSON_C_TO_STRING_PRETTY));
} else {
vty_out(vty,
- "Interface Address Source Group Membership\n");
+ "Interface Address Source Group Membership\n");
/*
* Example of the json data we are traversing
type = json_object_get_type(if_field_val);
if (type == json_type_object) {
- vty_out(vty, "%-9s ", key);
+ vty_out(vty, "%-16s ", key);
json_object_object_get_ex(
val, "address", &json_tmp);
json = json_object_new_object();
else
vty_out(vty,
- "Interface State Address V Querier Query Timer Uptime\n");
+ "Interface State Address V Querier Query Timer Uptime\n");
FOR_ALL_INTERFACES (pim->vrf, ifp) {
struct pim_interface *pim_ifp;
}
} else {
vty_out(vty,
- "%-9s %5s %15s %d %7s %11s %8s\n",
+ "%-16s %5s %15s %d %7s %11s %8s\n",
ifp->name,
if_is_up(ifp)
? (igmp->mtrace_only ? "mtrc"
now = pim_time_monotonic_sec();
vty_out(vty,
- "Interface Address Source Group Socket Uptime \n");
+ "Interface Address Source Group Socket Uptime \n");
FOR_ALL_INTERFACES (pim->vrf, ifp) {
struct pim_interface *pim_ifp;
pim_inet4_dump("<src?>", ij->source_addr, source_str,
sizeof(source_str));
- vty_out(vty, "%-9s %-15s %-15s %-15s %6d %8s\n",
+ vty_out(vty, "%-16s %-15s %-15s %-15s %6d %8s\n",
ifp->name, pri_addr_str, source_str, group_str,
ij->sock_fd, uptime);
} /* for (pim_ifp->igmp_join_list) */
print_header = 1;
for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, upnode,
up)) {
+ if (!up->rpf.source_nexthop.interface)
+ continue;
if (strcmp(ifp->name,
up->rpf.source_nexthop
json, JSON_C_TO_STRING_PRETTY));
} else {
vty_out(vty,
- "Interface State Address PIM Nbrs PIM DR FHR IfChannels\n");
+ "Interface State Address PIM Nbrs PIM DR FHR IfChannels\n");
json_object_object_foreach(json, key, val)
{
- vty_out(vty, "%-9s ", key);
+ vty_out(vty, "%-16s ", key);
json_object_object_get_ex(val, "state", &json_tmp);
vty_out(vty, "%5s ", json_object_get_string(json_tmp));
json = json_object_new_object();
else {
vty_out(vty, "\n");
- vty_out(vty, "%-12s%-17s%-17s%-17s%-17s%-17s%-17s\n",
- "Interface", " HELLO", " JOIN", " PRUNE",
- " REGISTER", " REGISTER-STOP", " ASSERT");
- vty_out(vty, "%-10s%-18s%-17s%-17s%-17s%-17s%-17s\n", "",
- " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
- " Rx/Tx", " Rx/Tx");
+ vty_out(vty, "%-16s%-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", "",
+ " Rx/Tx", " Rx/Tx", " Rx/Tx",
+ " Rx/Tx", " Rx/Tx", " Rx/Tx");
vty_out(vty,
"---------------------------------------------------------------------------------------------------------------\n");
}
json_object_object_add(json, ifp->name, json_row);
} else {
vty_out(vty,
- "%-10s %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 \n",
ifp->name, pim_ifp->pim_ifstat_hello_recv,
pim_ifp->pim_ifstat_hello_sent,
pim_ifp->pim_ifstat_join_recv,
json = json_object_new_object();
else {
vty_out(vty, "\n");
- vty_out(vty, "%-12s%-17s%-17s%-17s%-17s%-17s%-17s\n",
+ vty_out(vty, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s\n",
"Interface", " HELLO", " JOIN", " PRUNE",
" REGISTER", " REGISTER-STOP", " ASSERT");
- vty_out(vty, "%-10s%-18s%-17s%-17s%-17s%-17s%-17s\n", "",
+ vty_out(vty, "%-14s%-18s%-17s%-17s%-17s%-17s%-17s\n", "",
" Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
" Rx/Tx", " Rx/Tx");
vty_out(vty,
- "---------------------------------------------------------------------------------------------------------------\n");
+ "---------------------------------------------------------------------------------------------------------------------\n");
}
FOR_ALL_INTERFACES (pim->vrf, ifp) {
json_object_object_add(json, ifp->name, json_row);
} else {
vty_out(vty,
- "%-10s %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 \n",
ifp->name, pim_ifp->pim_ifstat_hello_recv,
pim_ifp->pim_ifstat_hello_sent,
pim_ifp->pim_ifstat_join_recv,
} else
json_object_object_add(json_grp, ch_src_str, json_row);
} else {
- vty_out(vty, "%-9s %-15s %-15s %-15s %-10s %8s %-6s %5s\n",
+ vty_out(vty, "%-16s %-15s %-15s %-15s %-10s %8s %-6s %5s\n",
ch->interface->name, inet_ntoa(ifaddr), ch_src_str,
ch_grp_str,
pim_ifchannel_ifjoin_name(ch->ifjoin_state, ch->flags),
}
}
-static void pim_show_join(struct pim_instance *pim, struct vty *vty, bool uj)
+static void pim_show_join(struct pim_instance *pim, struct vty *vty,
+ struct prefix_sg *sg, bool uj)
{
struct pim_interface *pim_ifp;
struct pim_ifchannel *ch;
json = json_object_new_object();
else
vty_out(vty,
- "Interface Address Source Group State Uptime Expire Prune\n");
+ "Interface Address Source Group State Uptime Expire Prune\n");
FOR_ALL_INTERFACES (pim->vrf, ifp) {
pim_ifp = ifp->info;
continue;
RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
+ if (sg->grp.s_addr != 0
+ && sg->grp.s_addr != ch->sg.grp.s_addr)
+ continue;
+ if (sg->src.s_addr != 0
+ && sg->src.s_addr != ch->sg.src.s_addr)
+ continue;
pim_show_join_helper(vty, pim_ifp, ch, json, now, uj);
} /* scan interface channels */
}
json = json_object_new_object();
} else {
vty_out(vty,
- "Codes: J -> Pim Join, I -> IGMP Report, S -> Source, * -> Inherited from (*,G)");
+ "Codes: J -> Pim Join, I -> IGMP Report, S -> Source, * -> Inherited from (*,G), V -> VxLAN");
vty_out(vty,
- "\nInstalled Source Group IIF OIL\n");
+ "\nInstalled Source Group IIF OIL\n");
}
for (ALL_LIST_ELEMENTS_RO(pim->channel_oil_list, node, c_oil)) {
c_oil->cc.wrong_if);
}
} else {
- vty_out(vty, "%-9d %-15s %-15s %-7s ",
- c_oil->installed, src_str, grp_str,
- in_ifname);
+ vty_out(vty, "%-9d %-15s %-15s %-16s ",
+ c_oil->installed, src_str, grp_str, in_ifname);
}
for (oif_vif_index = 0; oif_vif_index < MAXVIFS;
} else {
if (first_oif) {
first_oif = 0;
- vty_out(vty, "%s(%c%c%c%c)", out_ifname,
+ vty_out(vty, "%s(%c%c%c%c%c)", out_ifname,
(c_oil->oif_flags[oif_vif_index]
& PIM_OIF_FLAG_PROTO_IGMP)
? 'I'
& PIM_OIF_FLAG_PROTO_PIM)
? 'J'
: ' ',
+ (c_oil->oif_flags[oif_vif_index]
+ & PIM_OIF_FLAG_PROTO_VXLAN)
+ ? 'V'
+ : ' ',
(c_oil->oif_flags[oif_vif_index]
& PIM_OIF_FLAG_PROTO_SOURCE)
? 'S'
? '*'
: ' ');
} else
- vty_out(vty, ", %s(%c%c%c%c)",
+ vty_out(vty, ", %s(%c%c%c%c%c)",
out_ifname,
(c_oil->oif_flags[oif_vif_index]
& PIM_OIF_FLAG_PROTO_IGMP)
& PIM_OIF_FLAG_PROTO_PIM)
? 'J'
: ' ',
+ (c_oil->oif_flags[oif_vif_index]
+ & PIM_OIF_FLAG_PROTO_VXLAN)
+ ? 'V'
+ : ' ',
(c_oil->oif_flags[oif_vif_index]
& PIM_OIF_FLAG_PROTO_SOURCE)
? 'S'
json = json_object_new_object();
} else {
vty_out(vty,
- "Interface Neighbor Uptime Holdtime DR Pri\n");
+ "Interface Neighbor Uptime Holdtime DR Pri\n");
}
FOR_ALL_INTERFACES (pim->vrf, ifp) {
neigh_src_str, json_row);
} else {
- vty_out(vty, "%-9s %15s %8s %8s %6d\n",
+ vty_out(vty, "%-16s %15s %8s %8s %6d\n",
ifp->name, neigh_src_str, uptime,
expire, neigh->dr_priority);
}
struct interface *ifp;
vty_out(vty,
- "Interface Address Neighbor Secondary \n");
+ "Interface Address Neighbor Secondary \n");
FOR_ALL_INTERFACES (pim->vrf, ifp) {
struct pim_interface *pim_ifp;
prefix2str(p, neigh_sec_str,
sizeof(neigh_sec_str));
- vty_out(vty, "%-9s %-15s %-15s %-15s\n",
+ vty_out(vty, "%-16s %-15s %-15s %-15s\n",
ifp->name, inet_ntoa(ifaddr),
neigh_src_str, neigh_sec_str);
}
/* XXX: need to print ths flag in the plain text display as well */
if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_MSDP)
json_object_boolean_true_add(json, "sourceMsdp");
+
+ if (up->flags & PIM_UPSTREAM_FLAG_MASK_SEND_SG_RPT_PRUNE)
+ json_object_boolean_true_add(json, "sendSGRptPrune");
+
+ if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_LHR)
+ json_object_boolean_true_add(json, "lastHopRouter");
+
+ if (up->flags & PIM_UPSTREAM_FLAG_MASK_DISABLE_KAT_EXPIRY)
+ json_object_boolean_true_add(json, "disableKATExpiry");
+
+ if (up->flags & PIM_UPSTREAM_FLAG_MASK_STATIC_IIF)
+ json_object_boolean_true_add(json, "staticIncomingInterface");
+
+ if (up->flags & PIM_UPSTREAM_FLAG_MASK_ALLOW_IIF_IN_OIL)
+ json_object_boolean_true_add(json,
+ "allowIncomingInterfaceinOil");
+
+ if (up->flags & PIM_UPSTREAM_FLAG_MASK_NO_PIMREG_DATA)
+ json_object_boolean_true_add(json, "noPimRegistrationData");
+
+ if (up->flags & PIM_UPSTREAM_FLAG_MASK_FORCE_PIMREG)
+ json_object_boolean_true_add(json, "forcePimRegistration");
+
+ if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_ORIG)
+ json_object_boolean_true_add(json, "sourceVxlanOrigination");
+
+ if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_TERM)
+ json_object_boolean_true_add(json, "sourceVxlanTermination");
+
+ if (up->flags & PIM_UPSTREAM_FLAG_MASK_MLAG_VXLAN)
+ json_object_boolean_true_add(json, "mlagVxlan");
+
+ if (up->flags & PIM_UPSTREAM_FLAG_MASK_MLAG_NON_DF)
+ json_object_boolean_true_add(json,
+ "mlagNonDesignatedForwarder");
}
static const char *
}
static void pim_show_upstream(struct pim_instance *pim, struct vty *vty,
- bool uj)
+ struct prefix_sg *sg, bool uj)
{
struct listnode *upnode;
struct pim_upstream *up;
json = json_object_new_object();
else
vty_out(vty,
- "Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt\n");
+ "Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt\n");
for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, upnode, up)) {
char src_str[INET_ADDRSTRLEN];
char msdp_reg_timer[10];
char state_str[PIM_REG_STATE_STR_LEN];
+ if (sg->grp.s_addr != 0 && sg->grp.s_addr != up->sg.grp.s_addr)
+ continue;
+ if (sg->src.s_addr != 0 && sg->src.s_addr != up->sg.src.s_addr)
+ continue;
+
pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
pim_time_uptime(uptime, sizeof(uptime),
json_object_object_add(json_group, src_str, json_row);
} else {
vty_out(vty,
- "%-10s%-15s %-15s %-11s %-8s %-9s %-9s %-9s %6d\n",
+ "%-16s%-15s %-15s %-11s %-8s %-9s %-9s %-9s %6d\n",
up->rpf.source_nexthop.interface
? up->rpf.source_nexthop.interface->name
: "Unknown",
json_object_object_add(json_group, src_str, json_row);
} else {
- vty_out(vty, "%-9s %-15s %-15s %-10s %-5s %-10s %-11s %-6s\n",
+ vty_out(vty, "%-16s %-15s %-15s %-10s %-5s %-10s %-11s %-6s\n",
ch->interface->name, src_str, grp_str,
pim_macro_ch_lost_assert(ch) ? "yes" : "no",
pim_macro_chisin_joins(ch) ? "yes" : "no",
json = json_object_new_object();
else
vty_out(vty,
- "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD\n");
+ "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD\n");
/* scan per-interface (S,G) state */
FOR_ALL_INTERFACES (pim->vrf, ifp) {
json = json_object_new_object();
else
vty_out(vty,
- "Source Group RpfIface RibNextHop RpfAddress \n");
+ "Source Group RpfIface RibNextHop RpfAddress \n");
for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, upnode, up)) {
char src_str[INET_ADDRSTRLEN];
rpf_addr_str);
json_object_object_add(json_group, src_str, json_row);
} else {
- vty_out(vty, "%-15s %-15s %-8s %-15s %-15s\n", src_str,
+ vty_out(vty, "%-15s %-15s %-16s %-15s %-15s\n", src_str,
grp_str, rpf_ifname, rpf_nexthop_str,
rpf_addr_str);
}
show_rpf_refresh_stats(vty, pim, now, json);
vty_out(vty, "\n");
vty_out(vty,
- "Source Group RpfIface RpfAddress RibNextHop Metric Pref\n");
+ "Source Group RpfIface RpfAddress RibNextHop Metric Pref\n");
}
for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, up_node, up)) {
json_object_object_add(json_group, src_str, json_row);
} else {
- vty_out(vty, "%-15s %-15s %-8s %-15s %-15s %6d %4d\n",
+ vty_out(vty, "%-15s %-15s %-16s %-15s %-15s %6d %4d\n",
src_str, grp_str, rpf_ifname, rpf_addr_str,
rib_nexthop_str,
rpf->source_nexthop.mrib_route_metric,
ifp = if_lookup_by_index(first_ifindex, pim->vrf_id);
vty_out(vty, "%-15s ", inet_ntoa(pnc->rpf.rpf_addr.u.prefix4));
- vty_out(vty, "%-14s ", ifp ? ifp->name : "NULL");
+ vty_out(vty, "%-16s ", ifp ? ifp->name : "NULL");
vty_out(vty, "%s ", inet_ntoa(nh_node->gate.ipv4));
vty_out(vty, "\n");
}
cwd.pim = pim;
vty_out(vty, "Number of registered addresses: %lu\n",
pim->rpf_hash->count);
- vty_out(vty, "Address Interface Nexthop\n");
- vty_out(vty, "-------------------------------------------\n");
+ vty_out(vty, "Address Interface Nexthop\n");
+ vty_out(vty, "---------------------------------------------\n");
hash_walk(pim->rpf_hash, pim_print_pnc_cache_walkcb, &cwd);
}
json = json_object_new_object();
else
vty_out(vty,
- "Interface Address Group Mode Timer Srcs V Uptime \n");
+ "Interface Address Group Mode Timer Srcs V Uptime \n");
/* scan interfaces */
FOR_ALL_INTERFACES (pim->vrf, ifp) {
} else {
vty_out(vty,
- "%-9s %-15s %-15s %4s %8s %4d %d %8s\n",
+ "%-16s %-15s %-15s %4s %8s %4d %d %8s\n",
ifp->name, ifaddr_str,
group_str,
grp->igmp_version == 3
struct interface *ifp;
vty_out(vty,
- "Interface Address Group RetTimer Counter RetSrcs\n");
+ "Interface Address Group RetTimer Counter RetSrcs\n");
/* scan interfaces */
FOR_ALL_INTERFACES (pim->vrf, ifp) {
}
}
- vty_out(vty, "%-9s %-15s %-15s %-8s %7d %7d\n",
+ vty_out(vty, "%-16s %-15s %-15s %-8s %7d %7d\n",
ifp->name, ifaddr_str, group_str,
grp_retr_mmss,
grp->group_specific_query_retransmit_count,
now = pim_time_monotonic_sec();
vty_out(vty,
- "Interface Address Group Source Timer Fwd Uptime \n");
+ "Interface Address Group Source Timer Fwd Uptime \n");
/* scan interfaces */
FOR_ALL_INTERFACES (pim->vrf, ifp) {
now - src->source_creation);
vty_out(vty,
- "%-9s %-15s %-15s %-15s %5s %3s %8s\n",
+ "%-16s %-15s %-15s %-15s %5s %3s %8s\n",
ifp->name, ifaddr_str,
group_str, source_str, mmss,
IGMP_SOURCE_TEST_FORWARDING(
struct interface *ifp;
vty_out(vty,
- "Interface Address Group Source Counter\n");
+ "Interface Address Group Source Counter\n");
/* scan interfaces */
FOR_ALL_INTERFACES (pim->vrf, ifp) {
source_str, sizeof(source_str));
vty_out(vty,
- "%-9s %-15s %-15s %-15s %7d\n",
+ "%-16s %-15s %-15s %-15s %7d\n",
ifp->name, ifaddr_str,
group_str, source_str,
src->source_query_retransmit_count);
return CMD_SUCCESS;
}
-DEFUN (show_ip_pim_join,
+DEFPY (show_ip_pim_join,
show_ip_pim_join_cmd,
- "show ip pim [vrf NAME] join [json]",
+ "show ip pim [vrf NAME] join [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
SHOW_STR
IP_STR
PIM_STR
VRF_CMD_HELP_STR
"PIM interface join information\n"
+ "The Source or Group\n"
+ "The Group\n"
JSON_STR)
{
- int idx = 2;
- struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
- bool uj = use_json(argc, argv);
+ struct prefix_sg sg = {0};
+ struct vrf *v;
+ bool uj = !!json;
+ struct pim_instance *pim;
- if (!vrf)
+ v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
+
+ if (!v) {
+ vty_out(vty, "%% Vrf specified: %s does not exist\n", vrf);
return CMD_WARNING;
+ }
+ pim = pim_get_pim_instance(v->vrf_id);
- pim_show_join(vrf->info, vty, uj);
+ if (!pim) {
+ vty_out(vty, "%% Unable to find pim instance\n");
+ return CMD_WARNING;
+ }
+
+ if (s_or_g.s_addr != 0) {
+ if (g.s_addr != 0) {
+ sg.src = s_or_g;
+ sg.grp = g;
+ } else
+ sg.grp = s_or_g;
+ }
+
+ pim_show_join(pim, vty, &sg, uj);
return CMD_SUCCESS;
}
"PIM interface join information\n"
JSON_STR)
{
+ struct prefix_sg sg = {0};
bool uj = use_json(argc, argv);
struct vrf *vrf;
bool first = true;
first = false;
} else
vty_out(vty, "VRF: %s\n", vrf->name);
- pim_show_join(vrf->info, vty, uj);
+ pim_show_join(vrf->info, vty, &sg, uj);
}
if (uj)
vty_out(vty, "}\n");
return CMD_SUCCESS;
}
-DEFUN (show_ip_pim_upstream,
+DEFPY (show_ip_pim_upstream,
show_ip_pim_upstream_cmd,
- "show ip pim [vrf NAME] upstream [json]",
+ "show ip pim [vrf NAME] upstream [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
SHOW_STR
IP_STR
PIM_STR
VRF_CMD_HELP_STR
"PIM upstream information\n"
+ "The Source or Group\n"
+ "The Group\n"
JSON_STR)
{
- int idx = 2;
- struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
- bool uj = use_json(argc, argv);
+ struct prefix_sg sg = {0};
+ struct vrf *v;
+ bool uj = !!json;
+ struct pim_instance *pim;
- if (!vrf)
+ v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
+
+ if (!v) {
+ vty_out(vty, "%% Vrf specified: %s does not exist\n", vrf);
return CMD_WARNING;
+ }
+ pim = pim_get_pim_instance(v->vrf_id);
- pim_show_upstream(vrf->info, vty, uj);
+ if (!pim) {
+ vty_out(vty, "%% Unable to find pim instance\n");
+ return CMD_WARNING;
+ }
+
+ if (s_or_g.s_addr != 0) {
+ if (g.s_addr != 0) {
+ sg.src = s_or_g;
+ sg.grp = g;
+ } else
+ sg.grp = s_or_g;
+ }
+ pim_show_upstream(pim, vty, &sg, uj);
return CMD_SUCCESS;
}
"PIM upstream information\n"
JSON_STR)
{
+ struct prefix_sg sg = {0};
bool uj = use_json(argc, argv);
struct vrf *vrf;
bool first = true;
first = false;
} else
vty_out(vty, "VRF: %s\n", vrf->name);
- pim_show_upstream(vrf->info, vty, uj);
+ pim_show_upstream(vrf->info, vty, &sg, uj);
}
return CMD_SUCCESS;
"Source/RP address\n"
"Multicast Group address\n")
{
- struct pim_nexthop_cache *pnc = NULL;
struct prefix nht_p;
int result = 0;
struct in_addr src_addr, grp_addr;
char grp_str[PREFIX_STRLEN];
int idx = 2;
struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
- struct pim_rpf rpf;
if (!vrf)
return CMD_WARNING;
grp.u.prefix4 = grp_addr;
memset(&nexthop, 0, sizeof(nexthop));
- 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 = vif_source;
-
- pnc = pim_nexthop_cache_find(vrf->info, &rpf);
- if (pnc)
- result = pim_ecmp_nexthop_search(vrf->info, pnc, &nexthop,
- &nht_p, &grp, 0);
- else
- result = pim_ecmp_nexthop_lookup(vrf->info, &nexthop, &nht_p,
- &grp, 0);
+ result = pim_ecmp_nexthop_lookup(vrf->info, &nexthop, &nht_p, &grp, 0);
if (!result) {
vty_out(vty,
vty_out(vty, "\n");
vty_out(vty,
- "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut\n");
+ "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut\n");
FOR_ALL_INTERFACES (pim->vrf, ifp) {
struct pim_interface *pim_ifp;
ifaddr = pim_ifp->primary_address;
- vty_out(vty, "%-12s %-15s %3d %3d %7lu %7lu %10lu %10lu\n",
+ vty_out(vty, "%-16s %-15s %3d %3d %7lu %7lu %10lu %10lu\n",
ifp->name, inet_ntoa(ifaddr), ifp->ifindex,
pim_ifp->mroute_vif_index, (unsigned long)vreq.icount,
(unsigned long)vreq.ocount, (unsigned long)vreq.ibytes,
return CMD_SUCCESS;
}
-static void show_mroute(struct pim_instance *pim, struct vty *vty, bool fill,
- bool uj)
+static void show_mroute(struct pim_instance *pim, struct vty *vty,
+ struct prefix_sg *sg, bool fill, bool uj)
{
struct listnode *node;
struct channel_oil *c_oil;
json = json_object_new_object();
} else {
vty_out(vty,
- "Source Group Proto Input Output TTL Uptime\n");
+ "Source Group Proto Input Output TTL Uptime\n");
}
now = pim_time_monotonic_sec();
if (!c_oil->installed && !uj)
continue;
+ if (sg->grp.s_addr != 0 &&
+ sg->grp.s_addr != c_oil->oil.mfcc_mcastgrp.s_addr)
+ continue;
+ if (sg->src.s_addr != 0 &&
+ sg->src.s_addr != c_oil->oil.mfcc_origin.s_addr)
+ continue;
+
pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, grp_str,
sizeof(grp_str));
pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, src_str,
for (oif_vif_index = 0; oif_vif_index < MAXVIFS;
++oif_vif_index) {
struct interface *ifp_out;
- char oif_uptime[10];
+ char mroute_uptime[10];
int ttl;
ttl = c_oil->oil.mfcc_ttls[oif_vif_index];
ifp_out = pim_if_find_by_vif_index(pim, oif_vif_index);
pim_time_uptime(
- oif_uptime, sizeof(oif_uptime),
- now - c_oil->oif_creation[oif_vif_index]);
+ mroute_uptime, sizeof(mroute_uptime),
+ now - c_oil->mroute_creation);
found_oif = 1;
if (ifp_out)
json_object_boolean_true_add(
json_ifp_out, "protocolIgmp");
+ if (c_oil->oif_flags[oif_vif_index]
+ & PIM_OIF_FLAG_PROTO_VXLAN)
+ 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(
oif_vif_index);
json_object_int_add(json_ifp_out, "ttl", ttl);
json_object_string_add(json_ifp_out, "upTime",
- oif_uptime);
+ mroute_uptime);
if (!json_oil) {
json_oil = json_object_new_object();
json_object_object_add(json_source,
strcpy(proto, "IGMP");
}
+ 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");
}
vty_out(vty,
- "%-15s %-15s %-6s %-10s %-10s %-3d %8s\n",
+ "%-15s %-15s %-6s %-16s %-16s %-3d %8s\n",
src_str, grp_str, proto, in_ifname,
- out_ifname, ttl, oif_uptime);
+ out_ifname, ttl, mroute_uptime);
if (first) {
src_str[0] = '\0';
}
if (!uj && !found_oif) {
- vty_out(vty, "%-15s %-15s %-6s %-10s %-10s %-3d %8s\n",
+ vty_out(vty, "%-15s %-15s %-6s %-16s %-16s %-3d %8s\n",
src_str, grp_str, "none", in_ifname, "none", 0,
"--:--:--");
}
json_ifp_out);
} else {
vty_out(vty,
- "%-15s %-15s %-6s %-10s %-10s %-3d %8s %s\n",
+ "%-15s %-15s %-6s %-16s %-16s %-3d %8s %s\n",
src_str, grp_str, proto, in_ifname,
out_ifname, ttl, oif_uptime,
pim->vrf->name);
if (!uj && !found_oif) {
vty_out(vty,
- "%-15s %-15s %-6s %-10s %-10s %-3d %8s %s\n",
+ "%-15s %-15s %-6s %-16s %-16s %-3d %8s %s\n",
src_str, grp_str, proto, in_ifname, "none", 0,
"--:--:--", pim->vrf->name);
}
}
}
-DEFUN (show_ip_mroute,
+DEFPY (show_ip_mroute,
show_ip_mroute_cmd,
- "show ip mroute [vrf NAME] [fill] [json]",
+ "show ip mroute [vrf NAME] [A.B.C.D$s_or_g [A.B.C.D$g]] [fill$fill] [json$json]",
SHOW_STR
IP_STR
MROUTE_STR
VRF_CMD_HELP_STR
+ "The Source or Group\n"
+ "The Group\n"
"Fill in Assumed data\n"
JSON_STR)
{
- bool uj = use_json(argc, argv);
- bool fill = false;
- int idx = 2;
- struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
+ struct prefix_sg sg = {0};
+ struct pim_instance *pim;
+ struct vrf *v;
- if (!vrf)
+ v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
+
+ if (!v) {
+ vty_out(vty, "%% Vrf specified: %s does not exist\n", vrf);
return CMD_WARNING;
+ }
+ pim = pim_get_pim_instance(v->vrf_id);
- if (argv_find(argv, argc, "fill", &idx))
- fill = true;
+ if (!pim) {
+ vty_out(vty, "%% Unable to find pim instance\n");
+ return CMD_WARNING;
+ }
- show_mroute(vrf->info, vty, fill, uj);
+ if (s_or_g.s_addr != 0) {
+ if (g.s_addr != 0) {
+ sg.src = s_or_g;
+ sg.grp = g;
+ } else
+ sg.grp = s_or_g;
+ }
+ show_mroute(pim, vty, &sg, !!fill, !!json);
return CMD_SUCCESS;
}
"Fill in Assumed data\n"
JSON_STR)
{
+ struct prefix_sg sg = {0};
bool uj = use_json(argc, argv);
int idx = 4;
struct vrf *vrf;
first = false;
} else
vty_out(vty, "VRF: %s\n", vrf->name);
- show_mroute(vrf->info, vty, fill, uj);
+ show_mroute(vrf->info, vty, &sg, fill, uj);
}
if (uj)
vty_out(vty, "}\n");
return CMD_WARNING;
}
- if (pim_nexthop_lookup(vrf->info, &nexthop, addr, 0)) {
+ if (!pim_nexthop_lookup(vrf->info, &nexthop, addr, 0)) {
vty_out(vty,
"Failure querying RIB nexthop for unicast address %s\n",
addr_str);
pim_ifp = ifp->info;
if (!pim_ifp) {
- pim_ifp = pim_if_new(ifp, true, false, false);
+ pim_ifp = pim_if_new(ifp, true, false, false,
+ false /*vxlan_term*/);
if (!pim_ifp) {
vty_out(vty, "Could not enable IGMP on interface %s\n",
ifp->name);
struct pim_interface *pim_ifp = ifp->info;
if (!pim_ifp) {
- pim_ifp = pim_if_new(ifp, false, true, false);
+ pim_ifp = pim_if_new(ifp, false, true, false,
+ false /*vxlan_term*/);
if (!pim_ifp) {
return 0;
}
pim_if_addr_add_all(ifp);
pim_if_membership_refresh(ifp);
+
+ pim_if_create_pimreg(pim_ifp->pim);
return 1;
}
return CMD_SUCCESS;
}
-DEFUN (debug_static,
- debug_static_cmd,
- "debug static",
+DEFUN (debug_pim_static,
+ debug_pim_static_cmd,
+ "debug pim static",
DEBUG_STR
+ DEBUG_PIM_STR
DEBUG_STATIC_STR)
{
PIM_DO_DEBUG_STATIC;
return CMD_SUCCESS;
}
-DEFUN (no_debug_static,
- no_debug_static_cmd,
- "no debug static",
+DEFUN (no_debug_pim_static,
+ no_debug_pim_static_cmd,
+ "no debug pim static",
NO_STR
DEBUG_STR
+ DEBUG_PIM_STR
DEBUG_STATIC_STR)
{
PIM_DONT_DEBUG_STATIC;
return CMD_SUCCESS;
}
+DEFUN (debug_pim_vxlan,
+ debug_pim_vxlan_cmd,
+ "debug pim vxlan",
+ DEBUG_STR
+ DEBUG_PIM_STR
+ DEBUG_PIM_VXLAN_STR)
+{
+ PIM_DO_DEBUG_VXLAN;
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_debug_pim_vxlan,
+ no_debug_pim_vxlan_cmd,
+ "no debug pim vxlan",
+ NO_STR
+ DEBUG_STR
+ DEBUG_PIM_STR
+ DEBUG_PIM_VXLAN_STR)
+{
+ PIM_DONT_DEBUG_VXLAN;
+ return CMD_SUCCESS;
+}
+
DEFUN (debug_msdp,
debug_msdp_cmd,
"debug msdp",
return CMD_SUCCESS;
}
-#if CONFDATE > 20190402
-CPP_NOTICE("bgpd: time to remove undebug commands")
-#endif
-ALIAS_HIDDEN (no_debug_msdp,
- undebug_msdp_cmd,
- "undebug msdp",
- UNDEBUG_STR DEBUG_MSDP_STR)
-
DEFUN (debug_msdp_events,
debug_msdp_events_cmd,
"debug msdp events",
return CMD_SUCCESS;
}
-#if CONFDATE > 20190402
-CPP_NOTICE("bgpd: time to remove undebug commands")
-#endif
-ALIAS_HIDDEN (no_debug_msdp_events,
- undebug_msdp_events_cmd,
- "undebug msdp events",
- UNDEBUG_STR
- DEBUG_MSDP_STR
- DEBUG_MSDP_EVENTS_STR)
-
DEFUN (debug_msdp_packets,
debug_msdp_packets_cmd,
"debug msdp packets",
return CMD_SUCCESS;
}
-#if CONFDATE > 20190402
-CPP_NOTICE("bgpd: time to remove undebug commands")
-#endif
-ALIAS_HIDDEN (no_debug_msdp_packets,
- undebug_msdp_packets_cmd,
- "undebug msdp packets",
- UNDEBUG_STR
- DEBUG_MSDP_STR
- DEBUG_MSDP_PACKETS_STR)
-
DEFUN (debug_mtrace,
debug_mtrace_cmd,
"debug mtrace",
return CMD_SUCCESS;
}
+struct pim_sg_cache_walk_data {
+ struct vty *vty;
+ json_object *json;
+ json_object *json_group;
+ struct in_addr addr;
+ bool addr_match;
+};
+
+static void pim_show_vxlan_sg_entry(struct pim_vxlan_sg *vxlan_sg,
+ struct pim_sg_cache_walk_data *cwd)
+{
+ struct vty *vty = cwd->vty;
+ json_object *json = cwd->json;
+ char src_str[INET_ADDRSTRLEN];
+ char grp_str[INET_ADDRSTRLEN];
+ json_object *json_row;
+ bool installed = (vxlan_sg->up) ? true : false;
+ const char *iif_name = vxlan_sg->iif?vxlan_sg->iif->name:"-";
+ const char *oif_name;
+
+ if (pim_vxlan_is_orig_mroute(vxlan_sg))
+ oif_name = vxlan_sg->orig_oif?vxlan_sg->orig_oif->name:"";
+ else
+ oif_name = vxlan_sg->term_oif?vxlan_sg->term_oif->name:"";
+
+ if (cwd->addr_match && (vxlan_sg->sg.src.s_addr != cwd->addr.s_addr) &&
+ (vxlan_sg->sg.grp.s_addr != cwd->addr.s_addr)) {
+ return;
+ }
+ pim_inet4_dump("<src?>", vxlan_sg->sg.src, src_str, sizeof(src_str));
+ pim_inet4_dump("<grp?>", vxlan_sg->sg.grp, grp_str, sizeof(grp_str));
+ if (json) {
+ json_object_object_get_ex(json, grp_str, &cwd->json_group);
+
+ if (!cwd->json_group) {
+ cwd->json_group = json_object_new_object();
+ json_object_object_add(json, grp_str,
+ cwd->json_group);
+ }
+
+ json_row = json_object_new_object();
+ json_object_string_add(json_row, "source", src_str);
+ json_object_string_add(json_row, "group", grp_str);
+ json_object_string_add(json_row, "input", iif_name);
+ json_object_string_add(json_row, "output", oif_name);
+ if (installed)
+ json_object_boolean_true_add(json_row, "installed");
+ else
+ json_object_boolean_false_add(json_row, "installed");
+ json_object_object_add(cwd->json_group, src_str, json_row);
+ } else {
+ vty_out(vty, "%-15s %-15s %-15s %-15s %-5s\n",
+ src_str, grp_str, iif_name, oif_name,
+ installed?"I":"");
+ }
+}
+
+static void pim_show_vxlan_sg_hash_entry(struct hash_backet *backet, void *arg)
+{
+ pim_show_vxlan_sg_entry((struct pim_vxlan_sg *)backet->data,
+ (struct pim_sg_cache_walk_data *)arg);
+}
+
+static void pim_show_vxlan_sg(struct pim_instance *pim,
+ struct vty *vty, bool uj)
+{
+ json_object *json = NULL;
+ struct pim_sg_cache_walk_data cwd;
+
+ if (uj) {
+ json = json_object_new_object();
+ } else {
+ vty_out(vty, "Codes: I -> installed\n");
+ vty_out(vty,
+ "Source Group Input Output Flags\n");
+ }
+
+ memset(&cwd, 0, sizeof(cwd));
+ cwd.vty = vty;
+ cwd.json = json;
+ hash_iterate(pim->vxlan.sg_hash, pim_show_vxlan_sg_hash_entry, &cwd);
+
+ 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 pim_show_vxlan_sg_match_addr(struct pim_instance *pim,
+ struct vty *vty, char *addr_str, bool uj)
+{
+ json_object *json = NULL;
+ struct pim_sg_cache_walk_data cwd;
+ int result = 0;
+
+ memset(&cwd, 0, sizeof(cwd));
+ result = inet_pton(AF_INET, addr_str, &cwd.addr);
+ if (result <= 0) {
+ vty_out(vty, "Bad address %s: errno=%d: %s\n", addr_str,
+ errno, safe_strerror(errno));
+ return;
+ }
+
+ if (uj) {
+ json = json_object_new_object();
+ } else {
+ vty_out(vty, "Codes: I -> installed\n");
+ vty_out(vty,
+ "Source Group Input Output Flags\n");
+ }
+
+ cwd.vty = vty;
+ cwd.json = json;
+ cwd.addr_match = true;
+ hash_iterate(pim->vxlan.sg_hash, pim_show_vxlan_sg_hash_entry, &cwd);
+
+ 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 pim_show_vxlan_sg_one(struct pim_instance *pim,
+ struct vty *vty, char *src_str, char *grp_str, bool uj)
+{
+ json_object *json = NULL;
+ struct prefix_sg sg;
+ int result = 0;
+ struct pim_vxlan_sg *vxlan_sg;
+ const char *iif_name;
+ bool installed;
+ const char *oif_name;
+
+ result = inet_pton(AF_INET, src_str, &sg.src);
+ if (result <= 0) {
+ vty_out(vty, "Bad src address %s: errno=%d: %s\n", src_str,
+ errno, safe_strerror(errno));
+ return;
+ }
+ result = inet_pton(AF_INET, grp_str, &sg.grp);
+ if (result <= 0) {
+ vty_out(vty, "Bad grp address %s: errno=%d: %s\n", grp_str,
+ errno, safe_strerror(errno));
+ return;
+ }
+
+ sg.family = AF_INET;
+ sg.prefixlen = IPV4_MAX_BITLEN;
+ if (uj)
+ json = json_object_new_object();
+
+ vxlan_sg = pim_vxlan_sg_find(pim, &sg);
+ if (vxlan_sg) {
+ installed = (vxlan_sg->up) ? true : false;
+ iif_name = vxlan_sg->iif?vxlan_sg->iif->name:"-";
+
+ if (pim_vxlan_is_orig_mroute(vxlan_sg))
+ oif_name =
+ vxlan_sg->orig_oif?vxlan_sg->orig_oif->name:"";
+ else
+ oif_name =
+ vxlan_sg->term_oif?vxlan_sg->term_oif->name:"";
+
+ if (uj) {
+ json_object_string_add(json, "source", src_str);
+ json_object_string_add(json, "group", grp_str);
+ json_object_string_add(json, "input", iif_name);
+ json_object_string_add(json, "output", oif_name);
+ if (installed)
+ json_object_boolean_true_add(json, "installed");
+ else
+ json_object_boolean_false_add(json,
+ "installed");
+ } else {
+ vty_out(vty, "SG : %s\n", vxlan_sg->sg_str);
+ vty_out(vty, " Input : %s\n", iif_name);
+ vty_out(vty, " Output : %s\n", oif_name);
+ vty_out(vty, " installed : %s\n",
+ installed?"yes":"no");
+ }
+ }
+
+ if (uj) {
+ vty_out(vty, "%s\n", json_object_to_json_string_ext(
+ json, JSON_C_TO_STRING_PRETTY));
+ json_object_free(json);
+ }
+}
+
+DEFUN (show_ip_pim_vxlan_sg,
+ show_ip_pim_vxlan_sg_cmd,
+ "show ip pim [vrf NAME] vxlan-groups [A.B.C.D [A.B.C.D]] [json]",
+ SHOW_STR
+ IP_STR
+ PIM_STR
+ VRF_CMD_HELP_STR
+ "VxLAN BUM groups\n"
+ "source or group ip\n"
+ "group ip\n"
+ JSON_STR)
+{
+ bool uj = use_json(argc, argv);
+ struct vrf *vrf;
+ int idx = 2;
+
+ vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
+
+ if (!vrf)
+ return CMD_WARNING;
+
+ char *src_ip = argv_find(argv, argc, "A.B.C.D", &idx) ?
+ argv[idx++]->arg:NULL;
+ char *grp_ip = idx < argc && argv_find(argv, argc, "A.B.C.D", &idx) ?
+ argv[idx]->arg:NULL;
+
+ if (src_ip && grp_ip)
+ pim_show_vxlan_sg_one(vrf->info, vty, src_ip, grp_ip, uj);
+ else if (src_ip)
+ pim_show_vxlan_sg_match_addr(vrf->info, vty, src_ip, uj);
+ else
+ pim_show_vxlan_sg(vrf->info, vty, uj);
+
+ return CMD_SUCCESS;
+}
+
+static void pim_show_vxlan_sg_work(struct pim_instance *pim,
+ struct vty *vty, bool uj)
+{
+ json_object *json = NULL;
+ struct pim_sg_cache_walk_data cwd;
+ struct listnode *node;
+ struct pim_vxlan_sg *vxlan_sg;
+
+ if (uj) {
+ json = json_object_new_object();
+ } else {
+ vty_out(vty, "Codes: I -> installed\n");
+ vty_out(vty,
+ "Source Group Input Flags\n");
+ }
+
+ memset(&cwd, 0, sizeof(cwd));
+ cwd.vty = vty;
+ cwd.json = json;
+ for (ALL_LIST_ELEMENTS_RO(pim_vxlan_p->work_list, node, vxlan_sg))
+ pim_show_vxlan_sg_entry(vxlan_sg, &cwd);
+
+ if (uj) {
+ vty_out(vty, "%s\n", json_object_to_json_string_ext(
+ json, JSON_C_TO_STRING_PRETTY));
+ json_object_free(json);
+ }
+}
+
+DEFUN_HIDDEN (show_ip_pim_vxlan_sg_work,
+ show_ip_pim_vxlan_sg_work_cmd,
+ "show ip pim [vrf NAME] vxlan-work [json]",
+ SHOW_STR
+ IP_STR
+ PIM_STR
+ VRF_CMD_HELP_STR
+ "VxLAN work list\n"
+ JSON_STR)
+{
+ bool uj = use_json(argc, argv);
+ struct vrf *vrf;
+ int idx = 2;
+
+ vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
+
+ if (!vrf)
+ return CMD_WARNING;
+
+ pim_show_vxlan_sg_work(vrf->info, vty, uj);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN_HIDDEN (no_ip_pim_mlag,
+ no_ip_pim_mlag_cmd,
+ "no ip pim mlag",
+ NO_STR
+ IP_STR
+ PIM_STR
+ "MLAG\n")
+{
+ struct in_addr addr;
+
+ addr.s_addr = 0;
+ pim_vxlan_mlag_update(true/*mlag_enable*/,
+ false/*peer_state*/, PIM_VXLAN_MLAG_ROLE_SECONDARY,
+ NULL/*peerlink*/, &addr);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN_HIDDEN (ip_pim_mlag,
+ ip_pim_mlag_cmd,
+ "ip pim mlag INTERFACE role [primary|secondary] state [up|down] addr A.B.C.D",
+ IP_STR
+ PIM_STR
+ "MLAG\n"
+ "peerlink sub interface\n"
+ "MLAG role\n"
+ "MLAG role primary\n"
+ "MLAG role secondary\n"
+ "peer session state\n"
+ "peer session state up\n"
+ "peer session state down\n"
+ "configure PIP\n"
+ "unique ip address\n")
+{
+ struct interface *ifp;
+ const char *peerlink;
+ uint32_t role;
+ int idx;
+ bool peer_state;
+ int result;
+ struct in_addr reg_addr;
+
+ idx = 3;
+ peerlink = argv[idx]->arg;
+ ifp = if_lookup_by_name(peerlink, VRF_DEFAULT);
+ if (!ifp) {
+ vty_out(vty, "No such interface name %s\n", peerlink);
+ return CMD_WARNING;
+ }
+
+ idx += 2;
+ if (!strcmp(argv[idx]->arg, "primary")) {
+ role = PIM_VXLAN_MLAG_ROLE_PRIMARY;
+ } else if (!strcmp(argv[idx]->arg, "secondary")) {
+ role = PIM_VXLAN_MLAG_ROLE_SECONDARY;
+ } else {
+ vty_out(vty, "unknown MLAG role %s\n", argv[idx]->arg);
+ return CMD_WARNING;
+ }
+
+ idx += 2;
+ if (!strcmp(argv[idx]->arg, "up")) {
+ peer_state = true;
+ } else if (strcmp(argv[idx]->arg, "down")) {
+ peer_state = false;
+ } else {
+ vty_out(vty, "unknown MLAG state %s\n", argv[idx]->arg);
+ return CMD_WARNING;
+ }
+
+ idx += 2;
+ result = inet_pton(AF_INET, argv[idx]->arg, ®_addr);
+ if (result <= 0) {
+ vty_out(vty, "%% Bad reg address %s: errno=%d: %s\n",
+ argv[idx]->arg,
+ errno, safe_strerror(errno));
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ pim_vxlan_mlag_update(true, peer_state, role, ifp, ®_addr);
+
+ return CMD_SUCCESS;
+}
+
void pim_cmd_init(void)
{
install_node(&interface_node,
install_element(VRF_NODE, &ip_pim_ecmp_rebalance_cmd);
install_element(CONFIG_NODE, &no_ip_pim_ecmp_rebalance_cmd);
install_element(VRF_NODE, &no_ip_pim_ecmp_rebalance_cmd);
+ install_element(CONFIG_NODE, &ip_pim_mlag_cmd);
+ install_element(CONFIG_NODE, &no_ip_pim_mlag_cmd);
install_element(INTERFACE_NODE, &interface_ip_igmp_cmd);
install_element(INTERFACE_NODE, &interface_no_ip_igmp_cmd);
install_element(ENABLE_NODE, &debug_mroute_detail_cmd);
install_element(ENABLE_NODE, &no_debug_mroute_cmd);
install_element(ENABLE_NODE, &no_debug_mroute_detail_cmd);
- install_element(ENABLE_NODE, &debug_static_cmd);
- install_element(ENABLE_NODE, &no_debug_static_cmd);
+ install_element(ENABLE_NODE, &debug_pim_static_cmd);
+ install_element(ENABLE_NODE, &no_debug_pim_static_cmd);
install_element(ENABLE_NODE, &debug_pim_cmd);
install_element(ENABLE_NODE, &no_debug_pim_cmd);
install_element(ENABLE_NODE, &debug_pim_nht_cmd);
install_element(ENABLE_NODE, &no_debug_ssmpingd_cmd);
install_element(ENABLE_NODE, &debug_pim_zebra_cmd);
install_element(ENABLE_NODE, &no_debug_pim_zebra_cmd);
+ install_element(ENABLE_NODE, &debug_pim_vxlan_cmd);
+ install_element(ENABLE_NODE, &no_debug_pim_vxlan_cmd);
install_element(ENABLE_NODE, &debug_msdp_cmd);
install_element(ENABLE_NODE, &no_debug_msdp_cmd);
- install_element(ENABLE_NODE, &undebug_msdp_cmd);
install_element(ENABLE_NODE, &debug_msdp_events_cmd);
install_element(ENABLE_NODE, &no_debug_msdp_events_cmd);
- install_element(ENABLE_NODE, &undebug_msdp_events_cmd);
install_element(ENABLE_NODE, &debug_msdp_packets_cmd);
install_element(ENABLE_NODE, &no_debug_msdp_packets_cmd);
- install_element(ENABLE_NODE, &undebug_msdp_packets_cmd);
install_element(ENABLE_NODE, &debug_mtrace_cmd);
install_element(ENABLE_NODE, &no_debug_mtrace_cmd);
install_element(CONFIG_NODE, &debug_mroute_detail_cmd);
install_element(CONFIG_NODE, &no_debug_mroute_cmd);
install_element(CONFIG_NODE, &no_debug_mroute_detail_cmd);
- install_element(CONFIG_NODE, &debug_static_cmd);
- install_element(CONFIG_NODE, &no_debug_static_cmd);
+ install_element(CONFIG_NODE, &debug_pim_static_cmd);
+ install_element(CONFIG_NODE, &no_debug_pim_static_cmd);
install_element(CONFIG_NODE, &debug_pim_cmd);
install_element(CONFIG_NODE, &no_debug_pim_cmd);
install_element(CONFIG_NODE, &debug_pim_nht_cmd);
install_element(CONFIG_NODE, &no_debug_ssmpingd_cmd);
install_element(CONFIG_NODE, &debug_pim_zebra_cmd);
install_element(CONFIG_NODE, &no_debug_pim_zebra_cmd);
+ install_element(CONFIG_NODE, &debug_pim_vxlan_cmd);
+ install_element(CONFIG_NODE, &no_debug_pim_vxlan_cmd);
install_element(CONFIG_NODE, &debug_msdp_cmd);
install_element(CONFIG_NODE, &no_debug_msdp_cmd);
- install_element(CONFIG_NODE, &undebug_msdp_cmd);
install_element(CONFIG_NODE, &debug_msdp_events_cmd);
install_element(CONFIG_NODE, &no_debug_msdp_events_cmd);
- install_element(CONFIG_NODE, &undebug_msdp_events_cmd);
install_element(CONFIG_NODE, &debug_msdp_packets_cmd);
install_element(CONFIG_NODE, &no_debug_msdp_packets_cmd);
- install_element(CONFIG_NODE, &undebug_msdp_packets_cmd);
install_element(CONFIG_NODE, &debug_mtrace_cmd);
install_element(CONFIG_NODE, &no_debug_mtrace_cmd);
install_element(VIEW_NODE, &show_ip_msdp_mesh_group_vrf_all_cmd);
install_element(VIEW_NODE, &show_ip_pim_ssm_range_cmd);
install_element(VIEW_NODE, &show_ip_pim_group_type_cmd);
+ install_element(VIEW_NODE, &show_ip_pim_vxlan_sg_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 BFD command */