diff options
Diffstat (limited to 'pimd/pim_cmd_common.c')
| -rw-r--r-- | pimd/pim_cmd_common.c | 669 |
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; } |
