diff --git a/doc/user/pim.rst b/doc/user/pim.rst index f4611c520b..df884a7883 100644 --- a/doc/user/pim.rst +++ b/doc/user/pim.rst @@ -333,10 +333,12 @@ cause great confusion. Display information about interfaces PIM is using. -.. index:: show ip pim join +.. index:: show ip pim [vrf NAME] join [A.B.C.D [A.B.C.D]] [json] .. clicmd:: show ip pim join - Display information about PIM joins received. + Display information about PIM joins received. If one address is specified + then we assume it is the Group we are interested in displaying data on. + If the second address is specified then it is Source Group. .. index:: show ip pim local-membership .. clicmd:: show ip pim local-membership @@ -383,10 +385,11 @@ cause great confusion. Display information about known S,G's and incoming interface as well as the OIL and how they were chosen. -.. index:: show ip pim upstream +.. index:: show ip pim [vrf NAME] upstream [A.B.C.D [A.B.C.D]] [json] .. clicmd:: show ip pim upstream - Display upstream information about a S,G mroute. + Display upstream information about a S,G mroute. Allow the user to + specify sub Source and Groups that we are only interested in. .. index:: show ip pim upstream-join-desired .. clicmd:: show ip pim upstream-join-desired diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index 2d5acb87a9..110408001f 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -1696,7 +1696,8 @@ static void pim_show_join_helper(struct vty *vty, struct pim_interface *pim_ifp, } } -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; @@ -1718,6 +1719,12 @@ static void pim_show_join(struct pim_instance *pim, struct vty *vty, bool uj) 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 */ } @@ -2335,7 +2342,7 @@ static const char *pim_reg_state2brief_str(enum pim_reg_state reg_state, } 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; @@ -2362,6 +2369,11 @@ static void pim_show_upstream(struct pim_instance *pim, struct vty *vty, 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("", up->sg.src, src_str, sizeof(src_str)); pim_inet4_dump("", up->sg.grp, grp_str, sizeof(grp_str)); pim_time_uptime(uptime, sizeof(uptime), @@ -3777,24 +3789,45 @@ DEFUN (show_ip_pim_interface_vrf_all, 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; } @@ -3809,6 +3842,7 @@ DEFUN (show_ip_pim_join_vrf_all, "PIM interface join information\n" JSON_STR) { + struct prefix_sg sg = {0}; bool uj = use_json(argc, argv); struct vrf *vrf; bool first = true; @@ -3823,7 +3857,7 @@ DEFUN (show_ip_pim_join_vrf_all, 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"); @@ -4022,24 +4056,44 @@ DEFUN (show_ip_pim_state_vrf_all, 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; } @@ -4054,6 +4108,7 @@ DEFUN (show_ip_pim_upstream_vrf_all, "PIM upstream information\n" JSON_STR) { + struct prefix_sg sg = {0}; bool uj = use_json(argc, argv); struct vrf *vrf; bool first = true; @@ -4068,7 +4123,7 @@ DEFUN (show_ip_pim_upstream_vrf_all, 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;