summaryrefslogtreecommitdiff
path: root/pimd/pim_cmd_common.c
diff options
context:
space:
mode:
Diffstat (limited to 'pimd/pim_cmd_common.c')
-rw-r--r--pimd/pim_cmd_common.c669
1 files changed, 470 insertions, 199 deletions
diff --git a/pimd/pim_cmd_common.c b/pimd/pim_cmd_common.c
index b7bd7375c5..9283016d08 100644
--- a/pimd/pim_cmd_common.c
+++ b/pimd/pim_cmd_common.c
@@ -32,6 +32,7 @@
#include "ferr.h"
#include "lib/srcdest_table.h"
#include "lib/linklist.h"
+#include "termtable.h"
#include "pimd.h"
#include "pim_instance.h"
@@ -56,6 +57,7 @@
#include "pim_addr.h"
#include "pim_static.h"
#include "pim_util.h"
+#include "pim6_mld.h"
/**
* Get current node VRF name.
@@ -886,6 +888,8 @@ void pim_show_rpf(struct pim_instance *pim, struct vty *vty, json_object *json)
{
struct pim_upstream *up;
time_t now = pim_time_monotonic_sec();
+ struct ttable *tt = NULL;
+ char *table = NULL;
json_object *json_group = NULL;
json_object *json_row = NULL;
@@ -893,8 +897,15 @@ void pim_show_rpf(struct pim_instance *pim, struct vty *vty, json_object *json)
if (!json) {
vty_out(vty, "\n");
- vty_out(vty,
- "Source Group RpfIface RpfAddress RibNextHop Metric Pref\n");
+
+ /* Prepare table. */
+ tt = ttable_new(&ttable_styles[TTSTYLE_BLANK]);
+ ttable_add_row(
+ tt,
+ "Source|Group|RpfIface|RpfAddress|RibNextHop|Metric|Pref");
+ tt->style.cell.rpad = 2;
+ tt->style.corner = '+';
+ ttable_restyle(tt);
}
frr_each (rb_pim_upstream, &pim->upstream_head, up) {
@@ -942,8 +953,8 @@ void pim_show_rpf(struct pim_instance *pim, struct vty *vty, json_object *json)
json_object_object_add(json_group, src_str, json_row);
} else {
- vty_out(vty,
- "%-15pPAs %-15pPAs %-16s %-15pPA %-15pPAs %6d %4d\n",
+ ttable_add_row(
+ tt, "%pPAs|%pPAs|%s|%pPA|%pPAs|%d|%d",
&up->sg.src, &up->sg.grp, rpf_ifname,
&rpf->rpf_addr,
&rpf->source_nexthop.mrib_nexthop_addr,
@@ -951,14 +962,27 @@ void pim_show_rpf(struct pim_instance *pim, struct vty *vty, json_object *json)
rpf->source_nexthop.mrib_metric_preference);
}
}
+ /* Dump the generated table. */
+ if (!json) {
+ table = ttable_dump(tt, "\n");
+ vty_out(vty, "%s\n", table);
+ XFREE(MTYPE_TMP, table);
+ ttable_del(tt);
+ }
}
void pim_show_neighbors_secondary(struct pim_instance *pim, struct vty *vty)
{
struct interface *ifp;
+ struct ttable *tt = NULL;
+ char *table = NULL;
- vty_out(vty,
- "Interface Address Neighbor Secondary \n");
+ /* Prepare table. */
+ tt = ttable_new(&ttable_styles[TTSTYLE_BLANK]);
+ ttable_add_row(tt, "Interface|Address|Neighbor|Secondary");
+ tt->style.cell.rpad = 2;
+ tt->style.corner = '+';
+ ttable_restyle(tt);
FOR_ALL_INTERFACES (pim->vrf, ifp) {
struct pim_interface *pim_ifp;
@@ -986,12 +1010,16 @@ void pim_show_neighbors_secondary(struct pim_instance *pim, struct vty *vty)
for (ALL_LIST_ELEMENTS_RO(neigh->prefix_list,
prefix_node, p))
- vty_out(vty,
- "%-16s %-15pPAs %-15pPAs %-15pFX\n",
- ifp->name, &ifaddr, &neigh->source_addr,
- p);
+ ttable_add_row(tt, "%s|%pPAs|%pPAs|%pFX",
+ ifp->name, &ifaddr,
+ &neigh->source_addr, p);
}
}
+ /* Dump the generated table. */
+ table = ttable_dump(tt, "\n");
+ vty_out(vty, "%s\n", table);
+ XFREE(MTYPE_TMP, table);
+ ttable_del(tt);
}
void pim_show_state(struct pim_instance *pim, struct vty *vty,
@@ -999,6 +1027,11 @@ void pim_show_state(struct pim_instance *pim, struct vty *vty,
json_object *json)
{
struct channel_oil *c_oil;
+#if PIM_IPV != 4
+ struct ttable *tt = NULL;
+ char *table = NULL;
+#endif
+ char flag[50];
json_object *json_group = NULL;
json_object *json_ifp_in = NULL;
json_object *json_ifp_out = NULL;
@@ -1010,9 +1043,18 @@ void pim_show_state(struct pim_instance *pim, struct vty *vty,
if (!json) {
vty_out(vty,
- "Codes: J -> Pim Join, I -> IGMP Report, S -> Source, * -> Inherited from (*,G), V -> VxLAN, M -> Muted");
+ "Codes: J -> Pim Join, I -> " GM " Report, S -> Source, * -> Inherited from (*,G), V -> VxLAN, M -> Muted\n");
+#if PIM_IPV == 4
vty_out(vty,
- "\nActive Source Group RPT IIF OIL\n");
+ "Active Source Group RPT IIF OIL\n");
+#else
+ /* Prepare table. */
+ tt = ttable_new(&ttable_styles[TTSTYLE_BLANK]);
+ ttable_add_row(tt, "Active|Source|Group|RPT|IIF|OIL");
+ tt->style.cell.rpad = 2;
+ tt->style.corner = '+';
+ ttable_restyle(tt);
+#endif
}
frr_each (rb_pim_oil, &pim->channel_oil_head, c_oil) {
@@ -1125,11 +1167,14 @@ void pim_show_state(struct pim_instance *pim, struct vty *vty,
"wrongInterface",
c_oil->cc.wrong_if);
}
- } else
+ }
+#if PIM_IPV == 4
+ else
vty_out(vty, "%-6d %-15pPAs %-15pPAs %-3s %-16s ",
c_oil->installed, oil_origin(c_oil),
oil_mcastgrp(c_oil), isRpt ? "y" : "n",
in_ifname);
+#endif
for (oif_vif_index = 0; oif_vif_index < MAXVIFS;
++oif_vif_index) {
@@ -1171,72 +1216,72 @@ void pim_show_state(struct pim_instance *pim, struct vty *vty,
json_object_object_add(json_ifp_in, out_ifname,
json_ifp_out);
} else {
+ flag[0] = '\0';
+ snprintf(flag, sizeof(flag), "(%c%c%c%c%c)",
+ (c_oil->oif_flags[oif_vif_index] &
+ PIM_OIF_FLAG_PROTO_GM)
+ ? 'I'
+ : ' ',
+ (c_oil->oif_flags[oif_vif_index] &
+ 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_STAR)
+ ? '*'
+ : ' ',
+ (c_oil->oif_flags[oif_vif_index] &
+ PIM_OIF_FLAG_MUTE)
+ ? 'M'
+ : ' ');
+
if (first_oif) {
first_oif = 0;
- vty_out(vty, "%s(%c%c%c%c%c)",
- out_ifname,
- (c_oil->oif_flags
- [oif_vif_index] &
- PIM_OIF_FLAG_PROTO_GM)
- ? 'I'
- : ' ',
- (c_oil->oif_flags
- [oif_vif_index] &
- 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_STAR)
- ? '*'
- : ' ',
- (c_oil->oif_flags
- [oif_vif_index] &
- PIM_OIF_FLAG_MUTE)
- ? 'M'
- : ' ');
- } else
- vty_out(vty, ", %s(%c%c%c%c%c)",
- out_ifname,
- (c_oil->oif_flags
- [oif_vif_index] &
- PIM_OIF_FLAG_PROTO_GM)
- ? 'I'
- : ' ',
- (c_oil->oif_flags
- [oif_vif_index] &
- 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_STAR)
- ? '*'
- : ' ',
- (c_oil->oif_flags
- [oif_vif_index] &
- PIM_OIF_FLAG_MUTE)
- ? 'M'
- : ' ');
+#if PIM_IPV == 4
+ vty_out(vty, "%s%s", out_ifname, flag);
+#else
+ ttable_add_row(
+ tt, "%d|%pPAs|%pPAs|%s|%s|%s%s",
+ c_oil->installed,
+ oil_origin(c_oil),
+ oil_mcastgrp(c_oil),
+ isRpt ? "y" : "n", in_ifname,
+ out_ifname, flag);
+#endif
+ } else {
+#if PIM_IPV == 4
+ vty_out(vty, ", %s%s", out_ifname,
+ flag);
+#else
+ ttable_add_row(tt,
+ "%c|%c|%c|%c|%c|%s%s",
+ ' ', ' ', ' ', ' ', ' ',
+ out_ifname, flag);
+#endif
+ }
}
}
-
+#if PIM_IPV == 4
if (!json)
vty_out(vty, "\n");
+#endif
}
- if (!json)
+ /* Dump the generated table. */
+ if (!json) {
+#if PIM_IPV == 4
vty_out(vty, "\n");
+#else
+ table = ttable_dump(tt, "\n");
+ vty_out(vty, "%s\n", table);
+ XFREE(MTYPE_TMP, table);
+ ttable_del(tt);
+#endif
+ }
}
/* pim statistics - just adding only bsm related now.
@@ -1315,15 +1360,24 @@ void pim_show_upstream(struct pim_instance *pim, struct vty *vty,
pim_sgaddr *sg, json_object *json)
{
struct pim_upstream *up;
+ struct ttable *tt = NULL;
+ char *table = NULL;
time_t now;
json_object *json_group = NULL;
json_object *json_row = NULL;
now = pim_time_monotonic_sec();
- if (!json)
- vty_out(vty,
- "Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt\n");
+ if (!json) {
+ /* Prepare table. */
+ tt = ttable_new(&ttable_styles[TTSTYLE_BLANK]);
+ ttable_add_row(
+ tt,
+ "Iif|Source|Group|State|Uptime|JoinTimer|RSTimer|KATimer|RefCnt");
+ tt->style.cell.rpad = 2;
+ tt->style.corner = '+';
+ ttable_restyle(tt);
+ }
frr_each (rb_pim_upstream, &pim->upstream_head, up) {
char uptime[10];
@@ -1444,8 +1498,8 @@ void pim_show_upstream(struct pim_instance *pim, struct vty *vty,
json_object_int_add(json_row, "sptBit", up->sptbit);
json_object_object_add(json_group, src_str, json_row);
} else {
- vty_out(vty,
- "%-16s%-15pPAs %-15pPAs %-11s %-8s %-9s %-9s %-9s %6d\n",
+ ttable_add_row(tt,
+ "%s|%pPAs|%pPAs|%s|%s|%s|%s|%s|%d",
up->rpf.source_nexthop.interface
? up->rpf.source_nexthop.interface->name
: "Unknown",
@@ -1453,12 +1507,20 @@ void pim_show_upstream(struct pim_instance *pim, struct vty *vty,
join_timer, rs_timer, ka_timer, up->ref_count);
}
}
+ /* Dump the generated table. */
+ if (!json) {
+ table = ttable_dump(tt, "\n");
+ vty_out(vty, "%s\n", table);
+ XFREE(MTYPE_TMP, table);
+ ttable_del(tt);
+ }
}
static void pim_show_join_desired_helper(struct pim_instance *pim,
struct vty *vty,
struct pim_upstream *up,
- json_object *json, bool uj)
+ json_object *json, bool uj,
+ struct ttable *tt)
{
json_object *json_group = NULL;
json_object *json_row = NULL;
@@ -1489,45 +1551,68 @@ static void pim_show_join_desired_helper(struct pim_instance *pim,
json_object_object_add(json_group, src_str, json_row);
} else {
- vty_out(vty, "%-15pPAs %-15pPAs %-6s\n", &up->sg.src,
- &up->sg.grp,
- pim_upstream_evaluate_join_desired(pim, up) ? "yes"
- : "no");
+ ttable_add_row(tt, "%pPAs|%pPAs|%s", &up->sg.src, &up->sg.grp,
+ pim_upstream_evaluate_join_desired(pim, up)
+ ? "yes"
+ : "no");
}
}
void pim_show_join_desired(struct pim_instance *pim, struct vty *vty, bool uj)
{
struct pim_upstream *up;
+ struct ttable *tt = NULL;
+ char *table = NULL;
json_object *json = NULL;
if (uj)
json = json_object_new_object();
- else
- vty_out(vty, "Source Group EvalJD\n");
+ else {
+ /* Prepare table. */
+ tt = ttable_new(&ttable_styles[TTSTYLE_BLANK]);
+ ttable_add_row(tt, "Source|Group|EvalJD");
+ tt->style.cell.rpad = 2;
+ tt->style.corner = '+';
+ ttable_restyle(tt);
+ }
frr_each (rb_pim_upstream, &pim->upstream_head, up) {
/* scan all interfaces */
- pim_show_join_desired_helper(pim, vty, up, json, uj);
+ pim_show_join_desired_helper(pim, vty, up, json, uj, tt);
}
if (uj)
vty_json(vty, json);
+ else {
+ /* Dump the generated table. */
+ table = ttable_dump(tt, "\n");
+ vty_out(vty, "%s\n", table);
+ XFREE(MTYPE_TMP, table);
+ ttable_del(tt);
+ }
}
void pim_show_upstream_rpf(struct pim_instance *pim, struct vty *vty, bool uj)
{
struct pim_upstream *up;
+ struct ttable *tt = NULL;
+ char *table = NULL;
json_object *json = NULL;
json_object *json_group = NULL;
json_object *json_row = NULL;
if (uj)
json = json_object_new_object();
- else
- vty_out(vty,
- "Source Group RpfIface RibNextHop RpfAddress \n");
+ else {
+ /* Prepare table. */
+ tt = ttable_new(&ttable_styles[TTSTYLE_BLANK]);
+ ttable_add_row(tt,
+ "Source|Group|RpfIface|RibNextHop|RpfAddress");
+ tt->style.cell.rpad = 2;
+ tt->style.corner = '+';
+ ttable_restyle(tt);
+ }
frr_each (rb_pim_upstream, &pim->upstream_head, up) {
struct pim_rpf *rpf;
@@ -1569,21 +1654,27 @@ void pim_show_upstream_rpf(struct pim_instance *pim, struct vty *vty, bool uj)
&rpf->rpf_addr);
json_object_object_add(json_group, src_str, json_row);
} else {
- vty_out(vty,
- "%-15pPAs %-15pPAs %-16s %-15pPA %-15pPA\n",
- &up->sg.src, &up->sg.grp, rpf_ifname,
- &rpf->source_nexthop.mrib_nexthop_addr,
- &rpf->rpf_addr);
+ ttable_add_row(tt, "%pPAs|%pPAs|%s|%pPA|%pPA",
+ &up->sg.src, &up->sg.grp, rpf_ifname,
+ &rpf->source_nexthop.mrib_nexthop_addr,
+ &rpf->rpf_addr);
}
}
if (uj)
vty_json(vty, json);
+ else {
+ /* Dump the generated table. */
+ table = ttable_dump(tt, "\n");
+ vty_out(vty, "%s\n", table);
+ XFREE(MTYPE_TMP, table);
+ ttable_del(tt);
+ }
}
-static void pim_show_join_helper(struct vty *vty, struct pim_interface *pim_ifp,
+static void pim_show_join_helper(struct pim_interface *pim_ifp,
struct pim_ifchannel *ch, json_object *json,
- time_t now)
+ time_t now, struct ttable *tt)
{
json_object *json_iface = NULL;
json_object *json_row = NULL;
@@ -1650,8 +1741,8 @@ static void pim_show_join_helper(struct vty *vty, struct pim_interface *pim_ifp,
json_object_object_addf(json_grp, json_row, "%pPAs",
&ch->sg.src);
} else {
- vty_out(vty,
- "%-16s %-15pPAs %-15pPAs %-15pPAs %-10s %8s %-6s %5s\n",
+ ttable_add_row(
+ tt, "%s|%pPAs|%pPAs|%pPAs|%s|%s|%s|%s",
ch->interface->name, &ifaddr, &ch->sg.src, &ch->sg.grp,
pim_ifchannel_ifjoin_name(ch->ifjoin_state, ch->flags),
uptime, expire, prune);
@@ -1732,12 +1823,21 @@ void pim_show_join(struct pim_instance *pim, struct vty *vty, pim_sgaddr *sg,
struct pim_ifchannel *ch;
struct interface *ifp;
time_t now;
+ struct ttable *tt = NULL;
+ char *table = NULL;
now = pim_time_monotonic_sec();
- if (!json)
- vty_out(vty,
- "Interface Address Source Group State Uptime Expire Prune\n");
+ if (!json) {
+ /* Prepare table. */
+ tt = ttable_new(&ttable_styles[TTSTYLE_BLANK]);
+ ttable_add_row(
+ tt,
+ "Interface|Address|Source|Group|State|Uptime|Expire|Prune");
+ tt->style.cell.rpad = 2;
+ tt->style.corner = '+';
+ ttable_restyle(tt);
+ }
FOR_ALL_INTERFACES (pim->vrf, ifp) {
pim_ifp = ifp->info;
@@ -1748,18 +1848,26 @@ void pim_show_join(struct pim_instance *pim, struct vty *vty, pim_sgaddr *sg,
if (!pim_sgaddr_match(ch->sg, *sg))
continue;
- pim_show_join_helper(vty, pim_ifp, ch, json, now);
+ pim_show_join_helper(pim_ifp, ch, json, now, tt);
} /* scan interface channels */
}
+ /* Dump the generated table. */
+ if (!json) {
+ table = ttable_dump(tt, "\n");
+ vty_out(vty, "%s\n", table);
+ XFREE(MTYPE_TMP, table);
+ ttable_del(tt);
+ }
}
-static void pim_show_jp_agg_helper(struct vty *vty, struct interface *ifp,
+static void pim_show_jp_agg_helper(struct interface *ifp,
struct pim_neighbor *neigh,
- struct pim_upstream *up, int is_join)
+ struct pim_upstream *up, int is_join,
+ struct ttable *tt)
{
- vty_out(vty, "%-16s %-15pPAs %-15pPAs %-15pPAs %5s\n", ifp->name,
- &neigh->source_addr, &up->sg.src, &up->sg.grp,
- is_join ? "J" : "P");
+ ttable_add_row(tt, "%s|%pPAs|%pPAs|%pPAs|%s", ifp->name,
+ &neigh->source_addr, &up->sg.src, &up->sg.grp,
+ is_join ? "J" : "P");
}
int pim_show_jp_agg_list_cmd_helper(const char *vrf, struct vty *vty)
@@ -1795,9 +1903,15 @@ void pim_show_jp_agg_list(struct pim_instance *pim, struct vty *vty)
struct pim_jp_agg_group *jag;
struct listnode *js_node;
struct pim_jp_sources *js;
+ struct ttable *tt;
+ char *table;
- vty_out(vty,
- "Interface RPF Nbr Source Group State\n");
+ /* Prepare table. */
+ tt = ttable_new(&ttable_styles[TTSTYLE_BLANK]);
+ ttable_add_row(tt, "Interface|RPF Nbr|Source|Group|State");
+ tt->style.cell.rpad = 2;
+ tt->style.corner = '+';
+ ttable_restyle(tt);
FOR_ALL_INTERFACES (pim->vrf, ifp) {
pim_ifp = ifp->info;
@@ -1810,13 +1924,19 @@ void pim_show_jp_agg_list(struct pim_instance *pim, struct vty *vty)
jag_node, jag)) {
for (ALL_LIST_ELEMENTS_RO(jag->sources, js_node,
js)) {
- pim_show_jp_agg_helper(vty, ifp, neigh,
+ pim_show_jp_agg_helper(ifp, neigh,
js->up,
- js->is_join);
+ js->is_join, tt);
}
}
}
}
+
+ /* Dump the generated table. */
+ table = ttable_dump(tt, "\n");
+ vty_out(vty, "%s\n", table);
+ XFREE(MTYPE_TMP, table);
+ ttable_del(tt);
}
int pim_show_membership_cmd_helper(const char *vrf, struct vty *vty, bool uj)
@@ -1866,6 +1986,8 @@ void pim_show_membership(struct pim_instance *pim, struct vty *vty, bool uj)
enum json_type type;
json_object *json = NULL;
json_object *json_tmp = NULL;
+ struct ttable *tt = NULL;
+ char *table = NULL;
json = json_object_new_object();
@@ -1882,8 +2004,12 @@ void pim_show_membership(struct pim_instance *pim, struct vty *vty, bool uj)
if (uj) {
vty_json(vty, json);
} else {
- vty_out(vty,
- "Interface Address Source Group Membership\n");
+ /* Prepare table. */
+ tt = ttable_new(&ttable_styles[TTSTYLE_BLANK]);
+ ttable_add_row(tt, "Interface|Address|Source|Group|Membership");
+ tt->style.cell.rpad = 2;
+ tt->style.corner = '+';
+ ttable_restyle(tt);
/*
* Example of the json data we are traversing
@@ -1920,41 +2046,47 @@ void pim_show_membership(struct pim_instance *pim, struct vty *vty, bool uj)
type = json_object_get_type(if_field_val);
if (type == json_type_object) {
- vty_out(vty, "%-16s ", key);
+ const char *address, *source,
+ *localMembership;
json_object_object_get_ex(
val, "address", &json_tmp);
- vty_out(vty, "%-15s ",
- json_object_get_string(
- json_tmp));
+ address = json_object_get_string(
+ json_tmp);
json_object_object_get_ex(if_field_val,
"source",
&json_tmp);
- vty_out(vty, "%-15s ",
- json_object_get_string(
- json_tmp));
-
- /* Group */
- vty_out(vty, "%-15s ", if_field_key);
+ source = json_object_get_string(
+ json_tmp);
json_object_object_get_ex(
if_field_val, "localMembership",
&json_tmp);
- vty_out(vty, "%-10s\n",
+ localMembership =
json_object_get_string(
- json_tmp));
+ json_tmp);
+
+ ttable_add_row(tt, "%s|%s|%s|%s|%s",
+ key, address, source,
+ if_field_key,
+ localMembership);
}
}
}
json_object_free(json);
+ /* Dump the generated table. */
+ table = ttable_dump(tt, "\n");
+ vty_out(vty, "%s\n", table);
+ XFREE(MTYPE_TMP, table);
+ ttable_del(tt);
}
}
-static void pim_show_channel_helper(struct pim_instance *pim, struct vty *vty,
+static void pim_show_channel_helper(struct pim_instance *pim,
struct pim_interface *pim_ifp,
struct pim_ifchannel *ch, json_object *json,
- bool uj)
+ bool uj, struct ttable *tt)
{
struct pim_upstream *up = ch->upstream;
json_object *json_group = NULL;
@@ -1997,17 +2129,17 @@ static void pim_show_channel_helper(struct pim_instance *pim, struct vty *vty,
&up->sg.src);
} else {
- vty_out(vty,
- "%-16s %-15pPAs %-15pPAs %-10s %-5s %-10s %-11s %-6s\n",
- ch->interface->name, &up->sg.src, &up->sg.grp,
- pim_macro_ch_lost_assert(ch) ? "yes" : "no",
- pim_macro_chisin_joins(ch) ? "yes" : "no",
- pim_macro_chisin_pim_include(ch) ? "yes" : "no",
- PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(up->flags)
- ? "yes"
- : "no",
- pim_upstream_evaluate_join_desired(pim, up) ? "yes"
- : "no");
+ ttable_add_row(tt, "%s|%pPAs|%pPAs|%s|%s|%s|%s|%s",
+ ch->interface->name, &up->sg.src, &up->sg.grp,
+ pim_macro_ch_lost_assert(ch) ? "yes" : "no",
+ pim_macro_chisin_joins(ch) ? "yes" : "no",
+ pim_macro_chisin_pim_include(ch) ? "yes" : "no",
+ PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(up->flags)
+ ? "yes"
+ : "no",
+ pim_upstream_evaluate_join_desired(pim, up)
+ ? "yes"
+ : "no");
}
}
@@ -2016,14 +2148,22 @@ void pim_show_channel(struct pim_instance *pim, struct vty *vty, bool uj)
struct pim_interface *pim_ifp;
struct pim_ifchannel *ch;
struct interface *ifp;
-
+ struct ttable *tt = NULL;
json_object *json = NULL;
+ char *table = NULL;
if (uj)
json = json_object_new_object();
- else
- vty_out(vty,
- "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD\n");
+ else {
+ /* Prepare table. */
+ tt = ttable_new(&ttable_styles[TTSTYLE_BLANK]);
+ ttable_add_row(
+ tt,
+ "Interface|Source|Group|LostAssert|Joins|PimInclude|JoinDesired|EvalJD");
+ tt->style.cell.rpad = 2;
+ tt->style.corner = '+';
+ ttable_restyle(tt);
+ }
/* scan per-interface (S,G) state */
FOR_ALL_INTERFACES (pim->vrf, ifp) {
@@ -2031,16 +2171,21 @@ void pim_show_channel(struct pim_instance *pim, struct vty *vty, bool uj)
if (!pim_ifp)
continue;
-
RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
/* scan all interfaces */
- pim_show_channel_helper(pim, vty, pim_ifp, ch, json,
- uj);
+ pim_show_channel_helper(pim, pim_ifp, ch, json, uj, tt);
}
}
if (uj)
vty_json(vty, json);
+ else {
+ /* Dump the generated table. */
+ table = ttable_dump(tt, "\n");
+ vty_out(vty, "%s\n", table);
+ XFREE(MTYPE_TMP, table);
+ ttable_del(tt);
+ }
}
int pim_show_channel_cmd_helper(const char *vrf, struct vty *vty, bool uj)
@@ -2124,6 +2269,8 @@ void pim_show_interfaces(struct pim_instance *pim, struct vty *vty, bool mlag,
int pim_nbrs = 0;
int pim_ifchannels = 0;
bool uj = true;
+ struct ttable *tt = NULL;
+ char *table = NULL;
json_object *json_row = NULL;
json_object *json_tmp;
@@ -2167,43 +2314,61 @@ void pim_show_interfaces(struct pim_instance *pim, struct vty *vty, bool mlag,
}
if (!uj) {
- vty_out(vty,
- "Interface State Address PIM Nbrs PIM DR FHR IfChannels\n");
+
+ /* Prepare table. */
+ tt = ttable_new(&ttable_styles[TTSTYLE_BLANK]);
+ ttable_add_row(
+ tt,
+ "Interface|State|Address|PIM Nbrs|PIM DR|FHR|IfChannels");
+ tt->style.cell.rpad = 2;
+ tt->style.corner = '+';
+ ttable_restyle(tt);
json_object_object_foreach(json, key, val)
{
- vty_out(vty, "%-16s ", key);
+ const char *state, *address, *pimdr;
+ int neighbors, firsthpr, pimifchnl;
json_object_object_get_ex(val, "state", &json_tmp);
- vty_out(vty, "%5s ", json_object_get_string(json_tmp));
+ state = json_object_get_string(json_tmp);
json_object_object_get_ex(val, "address", &json_tmp);
- vty_out(vty, "%15s ",
- json_object_get_string(json_tmp));
+ address = json_object_get_string(json_tmp);
json_object_object_get_ex(val, "pimNeighbors",
&json_tmp);
- vty_out(vty, "%8d ", json_object_get_int(json_tmp));
+ neighbors = json_object_get_int(json_tmp);
if (json_object_object_get_ex(
val, "pimDesignatedRouterLocal",
&json_tmp)) {
- vty_out(vty, "%15s ", "local");
+ pimdr = "local";
} else {
json_object_object_get_ex(
val, "pimDesignatedRouter", &json_tmp);
- vty_out(vty, "%15s ",
- json_object_get_string(json_tmp));
+ pimdr = json_object_get_string(json_tmp);
}
json_object_object_get_ex(val, "firstHopRouter",
&json_tmp);
- vty_out(vty, "%3d ", json_object_get_int(json_tmp));
+ firsthpr = json_object_get_int(json_tmp);
json_object_object_get_ex(val, "pimIfChannels",
&json_tmp);
- vty_out(vty, "%9d\n", json_object_get_int(json_tmp));
+ pimifchnl = json_object_get_int(json_tmp);
+
+ ttable_add_row(tt, "%s|%s|%s|%d|%s|%d|%d", key, state,
+ address, neighbors, pimdr, firsthpr,
+ pimifchnl);
}
+ json_object_free(json);
+
+ /* Dump the generated table. */
+ table = ttable_dump(tt, "\n");
+ vty_out(vty, "%s\n", table);
+ XFREE(MTYPE_TMP, table);
+
+ ttable_del(tt);
}
}
@@ -3059,6 +3224,8 @@ void pim_show_neighbors(struct pim_instance *pim, struct vty *vty,
struct interface *ifp;
struct pim_interface *pim_ifp;
struct pim_neighbor *neigh;
+ struct ttable *tt = NULL;
+ char *table = NULL;
time_t now;
char uptime[10];
char expire[10];
@@ -3069,8 +3236,12 @@ void pim_show_neighbors(struct pim_instance *pim, struct vty *vty,
now = pim_time_monotonic_sec();
if (!json) {
- vty_out(vty,
- "Interface Neighbor Uptime Holdtime DR Pri\n");
+ /* Prepare table. */
+ tt = ttable_new(&ttable_styles[TTSTYLE_BLANK]);
+ ttable_add_row(tt, "Interface|Neighbor|Uptime|Holdtime|DR Pri");
+ tt->style.cell.rpad = 2;
+ tt->style.corner = '+';
+ ttable_restyle(tt);
}
FOR_ALL_INTERFACES (pim->vrf, ifp) {
@@ -3112,9 +3283,10 @@ void pim_show_neighbors(struct pim_instance *pim, struct vty *vty,
neigh_src_str, json_row);
} else {
- vty_out(vty, "%-16s %15s %8s %8s %6d\n",
- ifp->name, neigh_src_str, uptime,
- expire, neigh->dr_priority);
+ ttable_add_row(tt, "%s|%pPAs|%s|%s|%d",
+ ifp->name, &neigh->source_addr,
+ uptime, expire,
+ neigh->dr_priority);
}
}
@@ -3123,6 +3295,13 @@ void pim_show_neighbors(struct pim_instance *pim, struct vty *vty,
json_ifp_rows = NULL;
}
}
+ /* Dump the generated table. */
+ if (!json) {
+ table = ttable_dump(tt, "\n");
+ vty_out(vty, "%s\n", table);
+ XFREE(MTYPE_TMP, table);
+ ttable_del(tt);
+ }
}
int gm_process_query_max_response_time_cmd(struct vty *vty,
@@ -3264,13 +3443,22 @@ void show_multicast_interfaces(struct pim_instance *pim, struct vty *vty,
json_object *json)
{
struct interface *ifp;
+ struct ttable *tt = NULL;
+ char *table = NULL;
json_object *json_row = NULL;
vty_out(vty, "\n");
- if (!json)
- vty_out(vty,
- "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut\n");
+ if (!json) {
+ /* Prepare table. */
+ tt = ttable_new(&ttable_styles[TTSTYLE_BLANK]);
+ ttable_add_row(
+ tt,
+ "Interface|Address|ifi|Vif|PktsIn|PktsOut|BytesIn|BytesOut");
+ tt->style.cell.rpad = 2;
+ tt->style.corner = '+';
+ ttable_restyle(tt);
+ }
FOR_ALL_INTERFACES (pim->vrf, ifp) {
struct pim_interface *pim_ifp;
@@ -3326,16 +3514,22 @@ void show_multicast_interfaces(struct pim_instance *pim, struct vty *vty,
(unsigned long)vreq.obytes);
json_object_object_add(json, ifp->name, json_row);
} else {
- vty_out(vty,
- "%-16s %-15pPAs %3d %3d %7lu %7lu %10lu %10lu\n",
- ifp->name, &pim_ifp->primary_address,
- ifp->ifindex, pim_ifp->mroute_vif_index,
- (unsigned long)vreq.icount,
- (unsigned long)vreq.ocount,
- (unsigned long)vreq.ibytes,
- (unsigned long)vreq.obytes);
+ ttable_add_row(tt, "%s|%pPAs|%d|%d|%lu|%lu|%lu|%lu",
+ ifp->name, &pim_ifp->primary_address,
+ ifp->ifindex, pim_ifp->mroute_vif_index,
+ (unsigned long)vreq.icount,
+ (unsigned long)vreq.ocount,
+ (unsigned long)vreq.ibytes,
+ (unsigned long)vreq.obytes);
}
}
+ /* Dump the generated table. */
+ if (!json) {
+ table = ttable_dump(tt, "\n");
+ vty_out(vty, "%s\n", table);
+ XFREE(MTYPE_TMP, table);
+ ttable_del(tt);
+ }
}
void pim_cmd_show_ip_multicast_helper(struct pim_instance *pim, struct vty *vty)
@@ -3352,6 +3546,8 @@ void pim_cmd_show_ip_multicast_helper(struct pim_instance *pim, struct vty *vty)
vty_out(vty, "Mroute socket descriptor:");
vty_out(vty, " %d(%s)\n", pim->mroute_socket, vrf->name);
+ vty_out(vty, "PIM Register socket descriptor:");
+ vty_out(vty, " %d(%s)\n", pim->reg_sock, vrf->name);
pim_time_uptime(uptime, sizeof(uptime),
now - pim->mroute_socket_creation);
@@ -3389,6 +3585,8 @@ void show_mroute(struct pim_instance *pim, struct vty *vty, pim_sgaddr *sg,
struct listnode *node;
struct channel_oil *c_oil;
struct static_route *s_route;
+ struct ttable *tt = NULL;
+ char *table = NULL;
time_t now;
json_object *json_group = NULL;
json_object *json_source = NULL;
@@ -3411,8 +3609,14 @@ void show_mroute(struct pim_instance *pim, struct vty *vty, pim_sgaddr *sg,
vty_out(vty, "Flags: S - Sparse, C - Connected, P - Pruned\n");
vty_out(vty,
" R - SGRpt Pruned, F - Register flag, T - SPT-bit set\n");
- vty_out(vty,
- "\nSource Group Flags Proto Input Output TTL Uptime\n");
+
+ /* Prepare table. */
+ tt = ttable_new(&ttable_styles[TTSTYLE_BLANK]);
+ ttable_add_row(
+ tt, "Source|Group|Flags|Proto|Input|Output|TTL|Uptime");
+ tt->style.cell.rpad = 2;
+ tt->style.corner = '+';
+ ttable_restyle(tt);
}
now = pim_time_monotonic_sec();
@@ -3616,11 +3820,10 @@ void show_mroute(struct pim_instance *pim, struct vty *vty, pim_sgaddr *sg,
strlcpy(proto, "STAR", sizeof(proto));
}
- vty_out(vty,
- "%-15s %-15s %-8s %-6s %-16s %-16s %-3d %8s\n",
- src_str, grp_str, state_str, proto,
- in_ifname, out_ifname, ttl,
- mroute_uptime);
+ ttable_add_row(tt, "%s|%s|%s|%s|%s|%s|%d|%s",
+ src_str, grp_str, state_str,
+ proto, in_ifname, out_ifname,
+ ttl, mroute_uptime);
if (first) {
src_str[0] = '\0';
@@ -3634,11 +3837,10 @@ void show_mroute(struct pim_instance *pim, struct vty *vty, pim_sgaddr *sg,
}
if (!json && !found_oif) {
- vty_out(vty,
- "%-15pPAs %-15pPAs %-8s %-6s %-16s %-16s %-3d %8s\n",
- oil_origin(c_oil), oil_mcastgrp(c_oil),
- state_str, "none", in_ifname, "none", 0,
- "--:--:--");
+ ttable_add_row(tt, "%pPAs|%pPAs|%s|%s|%s|%s|%d|%s",
+ oil_origin(c_oil), oil_mcastgrp(c_oil),
+ state_str, "none", in_ifname, "none", 0,
+ "--:--:--");
}
}
@@ -3742,8 +3944,8 @@ void show_mroute(struct pim_instance *pim, struct vty *vty, pim_sgaddr *sg,
json_object_object_add(json_oil, out_ifname,
json_ifp_out);
} else {
- vty_out(vty,
- "%-15pPAs %-15pPAs %-8s %-6s %-16s %-16s %-3d %8s\n",
+ ttable_add_row(
+ tt, "%pPAs|%pPAs|%s|%s|%s|%s|%d|%s",
&s_route->source, &s_route->group, "-",
proto, in_ifname, out_ifname, ttl,
oif_uptime);
@@ -3757,17 +3959,23 @@ void show_mroute(struct pim_instance *pim, struct vty *vty, pim_sgaddr *sg,
}
if (!json && !found_oif) {
- vty_out(vty,
- "%-15pPAs %-15pPAs %-8s %-6s %-16s %-16s %-3d %8s\n",
- &s_route->source, &s_route->group, "-", proto,
- in_ifname, "none", 0, "--:--:--");
+ ttable_add_row(tt, "%pPAs|%pPAs|%s|%s|%s|%s|%d|%s",
+ &s_route->source, &s_route->group, "-",
+ proto, in_ifname, "none", 0, "--:--:--");
}
}
+ /* Dump the generated table. */
+ if (!json) {
+ table = ttable_dump(tt, "\n");
+ vty_out(vty, "%s\n", table);
+ XFREE(MTYPE_TMP, table);
+ ttable_del(tt);
+ }
}
static void show_mroute_count_per_channel_oil(struct channel_oil *c_oil,
json_object *json,
- struct vty *vty)
+ struct ttable *tt)
{
json_object *json_group = NULL;
json_object *json_source = NULL;
@@ -3802,12 +4010,12 @@ static void show_mroute_count_per_channel_oil(struct channel_oil *c_oil,
json_object_int_add(json_source, "wrongIf", c_oil->cc.wrong_if);
} else {
- vty_out(vty, "%-15pPAs %-15pPAs %-8llu %-7ld %-10ld %-7ld\n",
- oil_origin(c_oil), oil_mcastgrp(c_oil),
- c_oil->cc.lastused / 100,
- 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);
+ ttable_add_row(tt, "%pPAs|%pPAs|%llu|%ld|%ld|%ld",
+ oil_origin(c_oil), oil_mcastgrp(c_oil),
+ c_oil->cc.lastused / 100,
+ 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);
}
}
@@ -3817,20 +4025,35 @@ void show_mroute_count(struct pim_instance *pim, struct vty *vty,
struct listnode *node;
struct channel_oil *c_oil;
struct static_route *sr;
+ struct ttable *tt = NULL;
+ char *table = NULL;
if (!json) {
vty_out(vty, "\n");
- vty_out(vty,
- "Source Group LastUsed Packets Bytes WrongIf \n");
+ /* Prepare table. */
+ tt = ttable_new(&ttable_styles[TTSTYLE_BLANK]);
+ ttable_add_row(tt,
+ "Source|Group|LastUsed|Packets|Bytes|WrongIf");
+ tt->style.cell.rpad = 2;
+ tt->style.corner = '+';
+ ttable_restyle(tt);
}
/* Print PIM and IGMP route counts */
frr_each (rb_pim_oil, &pim->channel_oil_head, c_oil)
- show_mroute_count_per_channel_oil(c_oil, json, vty);
+ show_mroute_count_per_channel_oil(c_oil, json, tt);
for (ALL_LIST_ELEMENTS_RO(pim->static_routes, node, sr))
- show_mroute_count_per_channel_oil(&sr->c_oil, json, vty);
+ show_mroute_count_per_channel_oil(&sr->c_oil, json, tt);
+
+ /* Dump the generated table. */
+ if (!json) {
+ table = ttable_dump(tt, "\n");
+ vty_out(vty, "%s\n", table);
+ XFREE(MTYPE_TMP, table);
+ ttable_del(tt);
+ }
}
void show_mroute_summary(struct pim_instance *pim, struct vty *vty,
@@ -3994,6 +4217,12 @@ void clear_mroute(struct pim_instance *pim)
igmp_group_delete(grp);
}
}
+#else
+ struct gm_if *gm_ifp;
+
+ gm_ifp = pim_ifp->mld;
+ if (gm_ifp)
+ gm_group_delete(gm_ifp);
#endif
}
@@ -4023,6 +4252,46 @@ void clear_pim_statistics(struct pim_instance *pim)
}
}
+int clear_pim_interface_traffic(const char *vrf, struct vty *vty)
+{
+ struct interface *ifp = NULL;
+ struct pim_interface *pim_ifp = NULL;
+
+ struct vrf *v = pim_cmd_lookup(vty, vrf);
+
+ if (!v)
+ return CMD_WARNING;
+
+ FOR_ALL_INTERFACES (v, ifp) {
+ pim_ifp = ifp->info;
+
+ if (!pim_ifp)
+ continue;
+
+ pim_ifp->pim_ifstat_hello_recv = 0;
+ pim_ifp->pim_ifstat_hello_sent = 0;
+ pim_ifp->pim_ifstat_join_recv = 0;
+ pim_ifp->pim_ifstat_join_send = 0;
+ pim_ifp->pim_ifstat_prune_recv = 0;
+ pim_ifp->pim_ifstat_prune_send = 0;
+ pim_ifp->pim_ifstat_reg_recv = 0;
+ pim_ifp->pim_ifstat_reg_send = 0;
+ pim_ifp->pim_ifstat_reg_stop_recv = 0;
+ 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;
+#if PIM_IPV == 4
+ pim_ifp->igmp_ifstat_joins_sent = 0;
+ pim_ifp->igmp_ifstat_joins_failed = 0;
+ pim_ifp->igmp_peak_group_count = 0;
+#endif
+ }
+
+ return CMD_SUCCESS;
+}
+
int pim_debug_pim_cmd(void)
{
PIM_DO_DEBUG_PIM_EVENTS;
@@ -4045,6 +4314,8 @@ int pim_no_debug_pim_cmd(void)
PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND;
PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV;
+ PIM_DONT_DEBUG_BSM;
+ PIM_DONT_DEBUG_VXLAN;
return CMD_SUCCESS;
}