]> git.proxmox.com Git - mirror_frr.git/blame - pimd/pim_cmd.c
Merge pull request #4430 from lkrishnamoor/hostname_crash
[mirror_frr.git] / pimd / pim_cmd.c
CommitLineData
12e41d03 1/*
896014f4
DL
2 * PIM for Quagga
3 * Copyright (C) 2008 Everton da Silva Marques
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; see the file COPYING; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
12e41d03 19
12e41d03
DL
20#include <zebra.h>
21
9bf3c633 22#include "lib/json.h"
12e41d03
DL
23#include "command.h"
24#include "if.h"
25#include "prefix.h"
26#include "zclient.h"
dfe43e25 27#include "plist.h"
cba44481
CS
28#include "hash.h"
29#include "nexthop.h"
02a16316 30#include "vrf.h"
37664928 31#include "ferr.h"
12e41d03
DL
32
33#include "pimd.h"
9867746a 34#include "pim_mroute.h"
12e41d03
DL
35#include "pim_cmd.h"
36#include "pim_iface.h"
37#include "pim_vty.h"
38#include "pim_mroute.h"
39#include "pim_str.h"
40#include "pim_igmp.h"
41#include "pim_igmpv3.h"
42#include "pim_sock.h"
43#include "pim_time.h"
44#include "pim_util.h"
45#include "pim_oil.h"
46#include "pim_neighbor.h"
47#include "pim_pim.h"
48#include "pim_ifchannel.h"
49#include "pim_hello.h"
50#include "pim_msg.h"
51#include "pim_upstream.h"
52#include "pim_rpf.h"
53#include "pim_macro.h"
54#include "pim_ssmpingd.h"
55#include "pim_zebra.h"
6250610a 56#include "pim_static.h"
a920d6e7 57#include "pim_rp.h"
05b0d0d0 58#include "pim_zlookup.h"
2a333e0f 59#include "pim_msdp.h"
15a5dafe 60#include "pim_ssm.h"
cba44481 61#include "pim_nht.h"
ba4eb1bc 62#include "pim_bfd.h"
f1e2901a 63#include "pim_vxlan.h"
ba4eb1bc 64#include "bfd.h"
4616b2e9 65#include "pim_bsm.h"
12e41d03 66
414d885a
DS
67#ifndef VTYSH_EXTRACT_PL
68#include "pimd/pim_cmd_clippy.c"
69#endif
70
12e41d03 71static struct cmd_node interface_node = {
d62a17ae 72 INTERFACE_NODE, "%s(config-if)# ", 1 /* vtysh ? yes */
12e41d03
DL
73};
74
d62a17ae 75static struct cmd_node debug_node = {DEBUG_NODE, "", 1};
eb7a976a 76
02a16316
DS
77static struct vrf *pim_cmd_lookup_vrf(struct vty *vty, struct cmd_token *argv[],
78 const int argc, int *idx)
79{
80 struct vrf *vrf;
81
82 if (argv_find(argv, argc, "NAME", idx))
83 vrf = vrf_lookup_by_name(argv[*idx]->arg);
84 else
85 vrf = vrf_lookup_by_id(VRF_DEFAULT);
86
87 if (!vrf)
88 vty_out(vty, "Specified VRF: %s does not exist\n",
89 argv[*idx]->arg);
90
91 return vrf;
92}
93
12e41d03
DL
94static void pim_if_membership_clear(struct interface *ifp)
95{
d62a17ae 96 struct pim_interface *pim_ifp;
12e41d03 97
d62a17ae 98 pim_ifp = ifp->info;
99 zassert(pim_ifp);
12e41d03 100
d62a17ae 101 if (PIM_IF_TEST_PIM(pim_ifp->options)
102 && PIM_IF_TEST_IGMP(pim_ifp->options)) {
103 return;
104 }
12e41d03 105
d62a17ae 106 pim_ifchannel_membership_clear(ifp);
12e41d03
DL
107}
108
109/*
110 When PIM is disabled on interface, IGMPv3 local membership
111 information is not injected into PIM interface state.
112
113 The function pim_if_membership_refresh() fetches all IGMPv3 local
114 membership information into PIM. It is intented to be called
115 whenever PIM is enabled on the interface in order to collect missed
116 local membership information.
117 */
118static void pim_if_membership_refresh(struct interface *ifp)
119{
d62a17ae 120 struct pim_interface *pim_ifp;
121 struct listnode *sock_node;
122 struct igmp_sock *igmp;
12e41d03 123
d62a17ae 124 pim_ifp = ifp->info;
125 zassert(pim_ifp);
12e41d03 126
d62a17ae 127 if (!PIM_IF_TEST_PIM(pim_ifp->options))
128 return;
129 if (!PIM_IF_TEST_IGMP(pim_ifp->options))
130 return;
12e41d03 131
d62a17ae 132 /*
133 First clear off membership from all PIM (S,G) entries on the
134 interface
135 */
12e41d03 136
d62a17ae 137 pim_ifchannel_membership_clear(ifp);
12e41d03 138
d62a17ae 139 /*
140 Then restore PIM (S,G) membership from all IGMPv3 (S,G) entries on
141 the interface
142 */
12e41d03 143
d62a17ae 144 /* scan igmp sockets */
145 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
146 struct listnode *grpnode;
147 struct igmp_group *grp;
12e41d03 148
d62a17ae 149 /* scan igmp groups */
150 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grpnode,
151 grp)) {
152 struct listnode *srcnode;
153 struct igmp_source *src;
69283639 154
d62a17ae 155 /* scan group sources */
156 for (ALL_LIST_ELEMENTS_RO(grp->group_source_list,
157 srcnode, src)) {
158
159 if (IGMP_SOURCE_TEST_FORWARDING(
160 src->source_flags)) {
161 struct prefix_sg sg;
162
163 memset(&sg, 0,
164 sizeof(struct prefix_sg));
165 sg.src = src->source_addr;
166 sg.grp = grp->group_addr;
167 pim_ifchannel_local_membership_add(ifp,
168 &sg);
169 }
12e41d03 170
d62a17ae 171 } /* scan group sources */
172 } /* scan igmp groups */
173 } /* scan igmp sockets */
12e41d03 174
d62a17ae 175 /*
176 Finally delete every PIM (S,G) entry lacking all state info
177 */
12e41d03 178
d62a17ae 179 pim_ifchannel_delete_on_noinfo(ifp);
12e41d03
DL
180}
181
1a8a3da8
DS
182static void pim_show_assert_helper(struct vty *vty,
183 struct pim_interface *pim_ifp,
996c9314 184 struct pim_ifchannel *ch, time_t now)
1a8a3da8
DS
185{
186 char ch_src_str[INET_ADDRSTRLEN];
187 char ch_grp_str[INET_ADDRSTRLEN];
188 char winner_str[INET_ADDRSTRLEN];
189 struct in_addr ifaddr;
190 char uptime[10];
191 char timer[10];
192
193 ifaddr = pim_ifp->primary_address;
194
996c9314
LB
195 pim_inet4_dump("<ch_src?>", ch->sg.src, ch_src_str, sizeof(ch_src_str));
196 pim_inet4_dump("<ch_grp?>", ch->sg.grp, ch_grp_str, sizeof(ch_grp_str));
1a8a3da8
DS
197 pim_inet4_dump("<assrt_win?>", ch->ifassert_winner, winner_str,
198 sizeof(winner_str));
199
996c9314
LB
200 pim_time_uptime(uptime, sizeof(uptime), now - ch->ifassert_creation);
201 pim_time_timer_to_mmss(timer, sizeof(timer), ch->t_ifassert_timer);
1a8a3da8 202
ff415346 203 vty_out(vty, "%-16s %-15s %-15s %-15s %-6s %-15s %-8s %-5s\n",
996c9314
LB
204 ch->interface->name, inet_ntoa(ifaddr), ch_src_str, ch_grp_str,
205 pim_ifchannel_ifassert_name(ch->ifassert_state), winner_str,
206 uptime, timer);
1a8a3da8
DS
207}
208
64c86530 209static void pim_show_assert(struct pim_instance *pim, struct vty *vty)
12e41d03 210{
d62a17ae 211 struct pim_interface *pim_ifp;
212 struct pim_ifchannel *ch;
1a8a3da8 213 struct interface *ifp;
d62a17ae 214 time_t now;
215
216 now = pim_time_monotonic_sec();
217
218 vty_out(vty,
ff415346 219 "Interface Address Source Group State Winner Uptime Timer\n");
d62a17ae 220
451fda4f 221 FOR_ALL_INTERFACES (pim->vrf, ifp) {
1a8a3da8 222 pim_ifp = ifp->info;
d62a17ae 223 if (!pim_ifp)
224 continue;
225
a2addae8 226 RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
1a8a3da8
DS
227 pim_show_assert_helper(vty, pim_ifp, ch, now);
228 } /* scan interface channels */
229 }
230}
d62a17ae 231
1a8a3da8
DS
232static void pim_show_assert_internal_helper(struct vty *vty,
233 struct pim_interface *pim_ifp,
234 struct pim_ifchannel *ch)
235{
236 char ch_src_str[INET_ADDRSTRLEN];
237 char ch_grp_str[INET_ADDRSTRLEN];
238 struct in_addr ifaddr;
d62a17ae 239
1a8a3da8
DS
240 ifaddr = pim_ifp->primary_address;
241
996c9314
LB
242 pim_inet4_dump("<ch_src?>", ch->sg.src, ch_src_str, sizeof(ch_src_str));
243 pim_inet4_dump("<ch_grp?>", ch->sg.grp, ch_grp_str, sizeof(ch_grp_str));
ff415346 244 vty_out(vty, "%-16s %-15s %-15s %-15s %-3s %-3s %-3s %-4s\n",
996c9314 245 ch->interface->name, inet_ntoa(ifaddr), ch_src_str, ch_grp_str,
1a8a3da8
DS
246 PIM_IF_FLAG_TEST_COULD_ASSERT(ch->flags) ? "yes" : "no",
247 pim_macro_ch_could_assert_eval(ch) ? "yes" : "no",
996c9314
LB
248 PIM_IF_FLAG_TEST_ASSERT_TRACKING_DESIRED(ch->flags) ? "yes"
249 : "no",
250 pim_macro_assert_tracking_desired_eval(ch) ? "yes" : "no");
12e41d03
DL
251}
252
64c86530 253static void pim_show_assert_internal(struct pim_instance *pim, struct vty *vty)
12e41d03 254{
d62a17ae 255 struct pim_interface *pim_ifp;
d62a17ae 256 struct pim_ifchannel *ch;
1a8a3da8 257 struct interface *ifp;
d62a17ae 258
259 vty_out(vty,
260 "CA: CouldAssert\n"
261 "ECA: Evaluate CouldAssert\n"
262 "ATD: AssertTrackingDesired\n"
263 "eATD: Evaluate AssertTrackingDesired\n\n");
264
265 vty_out(vty,
ff415346 266 "Interface Address Source Group CA eCA ATD eATD\n");
451fda4f 267 FOR_ALL_INTERFACES (pim->vrf, ifp) {
1a8a3da8 268 pim_ifp = ifp->info;
d62a17ae 269 if (!pim_ifp)
270 continue;
271
a2addae8 272 RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
1a8a3da8
DS
273 pim_show_assert_internal_helper(vty, pim_ifp, ch);
274 } /* scan interface channels */
275 }
276}
277
278static void pim_show_assert_metric_helper(struct vty *vty,
279 struct pim_interface *pim_ifp,
280 struct pim_ifchannel *ch)
281{
282 char ch_src_str[INET_ADDRSTRLEN];
283 char ch_grp_str[INET_ADDRSTRLEN];
284 char addr_str[INET_ADDRSTRLEN];
285 struct pim_assert_metric am;
286 struct in_addr ifaddr;
287
288 ifaddr = pim_ifp->primary_address;
289
290 am = pim_macro_spt_assert_metric(&ch->upstream->rpf,
291 pim_ifp->primary_address);
d62a17ae 292
996c9314
LB
293 pim_inet4_dump("<ch_src?>", ch->sg.src, ch_src_str, sizeof(ch_src_str));
294 pim_inet4_dump("<ch_grp?>", ch->sg.grp, ch_grp_str, sizeof(ch_grp_str));
295 pim_inet4_dump("<addr?>", am.ip_address, addr_str, sizeof(addr_str));
1a8a3da8 296
ff415346 297 vty_out(vty, "%-16s %-15s %-15s %-15s %-3s %4u %6u %-15s\n",
996c9314
LB
298 ch->interface->name, inet_ntoa(ifaddr), ch_src_str, ch_grp_str,
299 am.rpt_bit_flag ? "yes" : "no", am.metric_preference,
300 am.route_metric, addr_str);
12e41d03
DL
301}
302
64c86530 303static void pim_show_assert_metric(struct pim_instance *pim, struct vty *vty)
12e41d03 304{
d62a17ae 305 struct pim_interface *pim_ifp;
d62a17ae 306 struct pim_ifchannel *ch;
1a8a3da8 307 struct interface *ifp;
ea4a71fc 308
d62a17ae 309 vty_out(vty,
ff415346 310 "Interface Address Source Group RPT Pref Metric Address \n");
12e41d03 311
451fda4f 312 FOR_ALL_INTERFACES (pim->vrf, ifp) {
1a8a3da8 313 pim_ifp = ifp->info;
d62a17ae 314 if (!pim_ifp)
315 continue;
12e41d03 316
a2addae8 317 RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
1a8a3da8
DS
318 pim_show_assert_metric_helper(vty, pim_ifp, ch);
319 } /* scan interface channels */
320 }
321}
12e41d03 322
1a8a3da8
DS
323static void pim_show_assert_winner_metric_helper(struct vty *vty,
324 struct pim_interface *pim_ifp,
325 struct pim_ifchannel *ch)
326{
327 char ch_src_str[INET_ADDRSTRLEN];
328 char ch_grp_str[INET_ADDRSTRLEN];
329 char addr_str[INET_ADDRSTRLEN];
330 struct pim_assert_metric *am;
331 struct in_addr ifaddr;
a2dc7057
DL
332 char pref_str[16];
333 char metr_str[16];
1a8a3da8
DS
334
335 ifaddr = pim_ifp->primary_address;
336
337 am = &ch->ifassert_winner_metric;
338
996c9314
LB
339 pim_inet4_dump("<ch_src?>", ch->sg.src, ch_src_str, sizeof(ch_src_str));
340 pim_inet4_dump("<ch_grp?>", ch->sg.grp, ch_grp_str, sizeof(ch_grp_str));
341 pim_inet4_dump("<addr?>", am->ip_address, addr_str, sizeof(addr_str));
1a8a3da8
DS
342
343 if (am->metric_preference == PIM_ASSERT_METRIC_PREFERENCE_MAX)
344 snprintf(pref_str, sizeof(pref_str), "INFI");
345 else
346 snprintf(pref_str, sizeof(pref_str), "%4u",
347 am->metric_preference);
348
349 if (am->route_metric == PIM_ASSERT_ROUTE_METRIC_MAX)
350 snprintf(metr_str, sizeof(metr_str), "INFI");
351 else
996c9314 352 snprintf(metr_str, sizeof(metr_str), "%6u", am->route_metric);
1a8a3da8 353
ff415346 354 vty_out(vty, "%-16s %-15s %-15s %-15s %-3s %-4s %-6s %-15s\n",
996c9314
LB
355 ch->interface->name, inet_ntoa(ifaddr), ch_src_str, ch_grp_str,
356 am->rpt_bit_flag ? "yes" : "no", pref_str, metr_str, addr_str);
12e41d03
DL
357}
358
64c86530
DS
359static void pim_show_assert_winner_metric(struct pim_instance *pim,
360 struct vty *vty)
12e41d03 361{
d62a17ae 362 struct pim_interface *pim_ifp;
d62a17ae 363 struct pim_ifchannel *ch;
1a8a3da8 364 struct interface *ifp;
d62a17ae 365
366 vty_out(vty,
ff415346 367 "Interface Address Source Group RPT Pref Metric Address \n");
d62a17ae 368
451fda4f 369 FOR_ALL_INTERFACES (pim->vrf, ifp) {
1a8a3da8 370 pim_ifp = ifp->info;
d62a17ae 371 if (!pim_ifp)
372 continue;
12e41d03 373
a2addae8 374 RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
1a8a3da8
DS
375 pim_show_assert_winner_metric_helper(vty, pim_ifp, ch);
376 } /* scan interface channels */
377 }
12e41d03
DL
378}
379
d62a17ae 380static void json_object_pim_ifp_add(struct json_object *json,
381 struct interface *ifp)
e775c0a4 382{
d62a17ae 383 struct pim_interface *pim_ifp;
e775c0a4 384
d62a17ae 385 pim_ifp = ifp->info;
386 json_object_string_add(json, "name", ifp->name);
387 json_object_string_add(json, "state", if_is_up(ifp) ? "up" : "down");
388 json_object_string_add(json, "address",
389 inet_ntoa(pim_ifp->primary_address));
390 json_object_int_add(json, "index", ifp->ifindex);
e775c0a4 391
d62a17ae 392 if (if_is_multicast(ifp))
393 json_object_boolean_true_add(json, "flagMulticast");
e775c0a4 394
d62a17ae 395 if (if_is_broadcast(ifp))
396 json_object_boolean_true_add(json, "flagBroadcast");
e775c0a4 397
d62a17ae 398 if (ifp->flags & IFF_ALLMULTI)
399 json_object_boolean_true_add(json, "flagAllMulticast");
e775c0a4 400
d62a17ae 401 if (ifp->flags & IFF_PROMISC)
402 json_object_boolean_true_add(json, "flagPromiscuous");
e775c0a4 403
d62a17ae 404 if (PIM_IF_IS_DELETED(ifp))
405 json_object_boolean_true_add(json, "flagDeleted");
e775c0a4 406
d62a17ae 407 if (pim_if_lan_delay_enabled(ifp))
408 json_object_boolean_true_add(json, "lanDelayEnabled");
e775c0a4
DW
409}
410
1a8a3da8
DS
411static void pim_show_membership_helper(struct vty *vty,
412 struct pim_interface *pim_ifp,
413 struct pim_ifchannel *ch,
414 struct json_object *json)
415{
416 char ch_src_str[INET_ADDRSTRLEN];
417 char ch_grp_str[INET_ADDRSTRLEN];
418 json_object *json_iface = NULL;
419 json_object *json_row = NULL;
420
996c9314
LB
421 pim_inet4_dump("<ch_src?>", ch->sg.src, ch_src_str, sizeof(ch_src_str));
422 pim_inet4_dump("<ch_grp?>", ch->sg.grp, ch_grp_str, sizeof(ch_grp_str));
1a8a3da8 423
996c9314 424 json_object_object_get_ex(json, ch->interface->name, &json_iface);
1a8a3da8
DS
425 if (!json_iface) {
426 json_iface = json_object_new_object();
427 json_object_pim_ifp_add(json_iface, ch->interface);
996c9314 428 json_object_object_add(json, ch->interface->name, json_iface);
1a8a3da8
DS
429 }
430
431 json_row = json_object_new_object();
432 json_object_string_add(json_row, "source", ch_src_str);
433 json_object_string_add(json_row, "group", ch_grp_str);
996c9314
LB
434 json_object_string_add(json_row, "localMembership",
435 ch->local_ifmembership == PIM_IFMEMBERSHIP_NOINFO
436 ? "NOINFO"
437 : "INCLUDE");
1a8a3da8 438 json_object_object_add(json_iface, ch_grp_str, json_row);
1a8a3da8 439}
64c86530 440static void pim_show_membership(struct pim_instance *pim, struct vty *vty,
088f1098 441 bool uj)
12e41d03 442{
d62a17ae 443 struct pim_interface *pim_ifp;
d62a17ae 444 struct pim_ifchannel *ch;
1a8a3da8 445 struct interface *ifp;
d62a17ae 446 enum json_type type;
447 json_object *json = NULL;
d62a17ae 448 json_object *json_tmp = NULL;
449
450 json = json_object_new_object();
451
451fda4f 452 FOR_ALL_INTERFACES (pim->vrf, ifp) {
1a8a3da8 453 pim_ifp = ifp->info;
d62a17ae 454 if (!pim_ifp)
455 continue;
456
a2addae8 457 RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
1a8a3da8
DS
458 pim_show_membership_helper(vty, pim_ifp, ch, json);
459 } /* scan interface channels */
460 }
d62a17ae 461
462 if (uj) {
9d303b37
DL
463 vty_out(vty, "%s\n", json_object_to_json_string_ext(
464 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 465 } else {
466 vty_out(vty,
ff415346 467 "Interface Address Source Group Membership\n");
d62a17ae 468
469 /*
470 * Example of the json data we are traversing
471 *
472 * {
473 * "swp3":{
474 * "name":"swp3",
475 * "state":"up",
476 * "address":"10.1.20.1",
477 * "index":5,
478 * "flagMulticast":true,
479 * "flagBroadcast":true,
480 * "lanDelayEnabled":true,
481 * "226.10.10.10":{
482 * "source":"*",
483 * "group":"226.10.10.10",
484 * "localMembership":"INCLUDE"
485 * }
486 * }
487 * }
488 */
489
490 /* foreach interface */
491 json_object_object_foreach(json, key, val)
492 {
493
494 /* Find all of the keys where the val is an object. In
495 * the example
496 * above the only one is 226.10.10.10
497 */
498 json_object_object_foreach(val, if_field_key,
499 if_field_val)
500 {
501 type = json_object_get_type(if_field_val);
502
503 if (type == json_type_object) {
ff415346 504 vty_out(vty, "%-16s ", key);
d62a17ae 505
506 json_object_object_get_ex(
507 val, "address", &json_tmp);
508 vty_out(vty, "%-15s ",
509 json_object_get_string(
510 json_tmp));
511
512 json_object_object_get_ex(if_field_val,
513 "source",
514 &json_tmp);
515 vty_out(vty, "%-15s ",
516 json_object_get_string(
517 json_tmp));
518
519 /* Group */
520 vty_out(vty, "%-15s ", if_field_key);
521
522 json_object_object_get_ex(
523 if_field_val, "localMembership",
524 &json_tmp);
525 vty_out(vty, "%-10s\n",
526 json_object_get_string(
527 json_tmp));
528 }
529 }
530 }
531 }
532
533 json_object_free(json);
534}
535
536static void pim_print_ifp_flags(struct vty *vty, struct interface *ifp,
537 int mloop)
538{
539 vty_out(vty, "Flags\n");
540 vty_out(vty, "-----\n");
541 vty_out(vty, "All Multicast : %s\n",
542 (ifp->flags & IFF_ALLMULTI) ? "yes" : "no");
543 vty_out(vty, "Broadcast : %s\n",
544 if_is_broadcast(ifp) ? "yes" : "no");
545 vty_out(vty, "Deleted : %s\n",
546 PIM_IF_IS_DELETED(ifp) ? "yes" : "no");
547 vty_out(vty, "Interface Index : %d\n", ifp->ifindex);
548 vty_out(vty, "Multicast : %s\n",
549 if_is_multicast(ifp) ? "yes" : "no");
550 vty_out(vty, "Multicast Loop : %d\n", mloop);
551 vty_out(vty, "Promiscuous : %s\n",
552 (ifp->flags & IFF_PROMISC) ? "yes" : "no");
553 vty_out(vty, "\n");
554 vty_out(vty, "\n");
a268493f
DW
555}
556
64c86530 557static void igmp_show_interfaces(struct pim_instance *pim, struct vty *vty,
088f1098 558 bool uj)
12e41d03 559{
d62a17ae 560 struct interface *ifp;
561 time_t now;
562 json_object *json = NULL;
563 json_object *json_row = NULL;
564
565 now = pim_time_monotonic_sec();
566
567 if (uj)
568 json = json_object_new_object();
569 else
570 vty_out(vty,
ff415346 571 "Interface State Address V Querier Query Timer Uptime\n");
d62a17ae 572
451fda4f 573 FOR_ALL_INTERFACES (pim->vrf, ifp) {
d62a17ae 574 struct pim_interface *pim_ifp;
575 struct listnode *sock_node;
576 struct igmp_sock *igmp;
577
578 pim_ifp = ifp->info;
579
580 if (!pim_ifp)
581 continue;
582
583 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node,
584 igmp)) {
585 char uptime[10];
586 char query_hhmmss[10];
587
588 pim_time_uptime(uptime, sizeof(uptime),
589 now - igmp->sock_creation);
590 pim_time_timer_to_hhmmss(query_hhmmss,
591 sizeof(query_hhmmss),
592 igmp->t_igmp_query_timer);
593
594 if (uj) {
595 json_row = json_object_new_object();
596 json_object_pim_ifp_add(json_row, ifp);
597 json_object_string_add(json_row, "upTime",
598 uptime);
599 json_object_int_add(json_row, "version",
600 pim_ifp->igmp_version);
601
602 if (igmp->t_igmp_query_timer) {
603 json_object_boolean_true_add(json_row,
604 "querier");
605 json_object_string_add(json_row,
606 "queryTimer",
607 query_hhmmss);
608 }
609
610 json_object_object_add(json, ifp->name,
611 json_row);
612
f83f3966
MS
613 if (igmp->mtrace_only) {
614 json_object_boolean_true_add(
615 json_row, "mtraceOnly");
616 }
d62a17ae 617 } else {
618 vty_out(vty,
ff415346 619 "%-16s %5s %15s %d %7s %11s %8s\n",
d62a17ae 620 ifp->name,
f83f3966
MS
621 if_is_up(ifp)
622 ? (igmp->mtrace_only ? "mtrc"
623 : "up")
624 : "down",
d62a17ae 625 inet_ntoa(igmp->ifaddr),
626 pim_ifp->igmp_version,
627 igmp->t_igmp_query_timer ? "local"
628 : "other",
629 query_hhmmss, uptime);
630 }
631 }
632 }
633
634 if (uj) {
9d303b37
DL
635 vty_out(vty, "%s\n", json_object_to_json_string_ext(
636 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 637 json_object_free(json);
638 }
639}
640
64c86530
DS
641static void igmp_show_interfaces_single(struct pim_instance *pim,
642 struct vty *vty, const char *ifname,
088f1098 643 bool uj)
d62a17ae 644{
645 struct igmp_sock *igmp;
646 struct interface *ifp;
d62a17ae 647 struct listnode *sock_node;
648 struct pim_interface *pim_ifp;
649 char uptime[10];
650 char query_hhmmss[10];
651 char other_hhmmss[10];
652 int found_ifname = 0;
653 int sqi;
96ceedc7 654 int mloop = 0;
d62a17ae 655 long gmi_msec; /* Group Membership Interval */
656 long lmqt_msec;
657 long ohpi_msec;
658 long oqpi_msec; /* Other Querier Present Interval */
659 long qri_msec;
660 time_t now;
59115451 661 int lmqc;
d62a17ae 662
663 json_object *json = NULL;
664 json_object *json_row = NULL;
665
666 if (uj)
667 json = json_object_new_object();
668
669 now = pim_time_monotonic_sec();
670
451fda4f 671 FOR_ALL_INTERFACES (pim->vrf, ifp) {
d62a17ae 672 pim_ifp = ifp->info;
673
674 if (!pim_ifp)
675 continue;
676
677 if (strcmp(ifname, "detail") && strcmp(ifname, ifp->name))
678 continue;
679
680 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node,
681 igmp)) {
682 found_ifname = 1;
683 pim_time_uptime(uptime, sizeof(uptime),
684 now - igmp->sock_creation);
685 pim_time_timer_to_hhmmss(query_hhmmss,
686 sizeof(query_hhmmss),
687 igmp->t_igmp_query_timer);
688 pim_time_timer_to_hhmmss(other_hhmmss,
689 sizeof(other_hhmmss),
690 igmp->t_other_querier_timer);
691
692 gmi_msec = PIM_IGMP_GMI_MSEC(
693 igmp->querier_robustness_variable,
694 igmp->querier_query_interval,
695 pim_ifp->igmp_query_max_response_time_dsec);
696
697 sqi = PIM_IGMP_SQI(
698 pim_ifp->igmp_default_query_interval);
699
700 oqpi_msec = PIM_IGMP_OQPI_MSEC(
701 igmp->querier_robustness_variable,
702 igmp->querier_query_interval,
703 pim_ifp->igmp_query_max_response_time_dsec);
704
705 lmqt_msec = PIM_IGMP_LMQT_MSEC(
59115451
SP
706 pim_ifp->igmp_specific_query_max_response_time_dsec,
707 pim_ifp->igmp_last_member_query_count);
d62a17ae 708
709 ohpi_msec =
710 PIM_IGMP_OHPI_DSEC(
711 igmp->querier_robustness_variable,
712 igmp->querier_query_interval,
713 pim_ifp->igmp_query_max_response_time_dsec)
714 * 100;
715
716 qri_msec = pim_ifp->igmp_query_max_response_time_dsec
717 * 100;
96ceedc7
CS
718 if (pim_ifp->pim_sock_fd >= 0)
719 mloop = pim_socket_mcastloop_get(
720 pim_ifp->pim_sock_fd);
721 else
722 mloop = 0;
59115451 723 lmqc = pim_ifp->igmp_last_member_query_count;
d62a17ae 724
725 if (uj) {
726 json_row = json_object_new_object();
727 json_object_pim_ifp_add(json_row, ifp);
728 json_object_string_add(json_row, "upTime",
729 uptime);
730 json_object_string_add(json_row, "querier",
731 igmp->t_igmp_query_timer
732 ? "local"
733 : "other");
734 json_object_int_add(json_row, "queryStartCount",
735 igmp->startup_query_count);
736 json_object_string_add(json_row,
737 "queryQueryTimer",
738 query_hhmmss);
739 json_object_string_add(json_row,
740 "queryOtherTimer",
741 other_hhmmss);
742 json_object_int_add(json_row, "version",
743 pim_ifp->igmp_version);
744 json_object_int_add(
745 json_row,
746 "timerGroupMembershipIntervalMsec",
747 gmi_msec);
59115451
SP
748 json_object_int_add(json_row,
749 "lastMemberQueryCount",
750 lmqc);
d62a17ae 751 json_object_int_add(json_row,
752 "timerLastMemberQueryMsec",
753 lmqt_msec);
754 json_object_int_add(
755 json_row,
756 "timerOlderHostPresentIntervalMsec",
757 ohpi_msec);
758 json_object_int_add(
759 json_row,
760 "timerOtherQuerierPresentIntervalMsec",
761 oqpi_msec);
762 json_object_int_add(
763 json_row, "timerQueryInterval",
764 igmp->querier_query_interval);
765 json_object_int_add(
766 json_row,
767 "timerQueryResponseIntervalMsec",
768 qri_msec);
769 json_object_int_add(
770 json_row, "timerRobustnessVariable",
771 igmp->querier_robustness_variable);
772 json_object_int_add(json_row,
773 "timerStartupQueryInterval",
774 sqi);
775
776 json_object_object_add(json, ifp->name,
777 json_row);
778
f83f3966
MS
779 if (igmp->mtrace_only) {
780 json_object_boolean_true_add(
781 json_row, "mtraceOnly");
782 }
d62a17ae 783 } else {
784 vty_out(vty, "Interface : %s\n", ifp->name);
785 vty_out(vty, "State : %s\n",
f83f3966
MS
786 if_is_up(ifp)
787 ? (igmp->mtrace_only ? "mtrace"
788 : "up")
789 : "down");
d62a17ae 790 vty_out(vty, "Address : %s\n",
791 inet_ntoa(pim_ifp->primary_address));
792 vty_out(vty, "Uptime : %s\n", uptime);
793 vty_out(vty, "Version : %d\n",
794 pim_ifp->igmp_version);
795 vty_out(vty, "\n");
796 vty_out(vty, "\n");
797
798 vty_out(vty, "Querier\n");
799 vty_out(vty, "-------\n");
800 vty_out(vty, "Querier : %s\n",
801 igmp->t_igmp_query_timer ? "local"
802 : "other");
803 vty_out(vty, "Start Count : %d\n",
804 igmp->startup_query_count);
805 vty_out(vty, "Query Timer : %s\n",
806 query_hhmmss);
807 vty_out(vty, "Other Timer : %s\n",
808 other_hhmmss);
809 vty_out(vty, "\n");
810 vty_out(vty, "\n");
811
812 vty_out(vty, "Timers\n");
813 vty_out(vty, "------\n");
814 vty_out(vty,
815 "Group Membership Interval : %lis\n",
816 gmi_msec / 1000);
59115451
SP
817 vty_out(vty,
818 "Last Member Query Count : %d\n",
819 lmqc);
d62a17ae 820 vty_out(vty,
821 "Last Member Query Time : %lis\n",
822 lmqt_msec / 1000);
823 vty_out(vty,
824 "Older Host Present Interval : %lis\n",
825 ohpi_msec / 1000);
826 vty_out(vty,
827 "Other Querier Present Interval : %lis\n",
828 oqpi_msec / 1000);
829 vty_out(vty,
830 "Query Interval : %ds\n",
831 igmp->querier_query_interval);
832 vty_out(vty,
833 "Query Response Interval : %lis\n",
834 qri_msec / 1000);
835 vty_out(vty,
836 "Robustness Variable : %d\n",
837 igmp->querier_robustness_variable);
838 vty_out(vty,
839 "Startup Query Interval : %ds\n",
840 sqi);
841 vty_out(vty, "\n");
842 vty_out(vty, "\n");
843
844 pim_print_ifp_flags(vty, ifp, mloop);
845 }
846 }
847 }
848
849 if (uj) {
9d303b37
DL
850 vty_out(vty, "%s\n", json_object_to_json_string_ext(
851 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 852 json_object_free(json);
853 } else {
854 if (!found_ifname)
855 vty_out(vty, "%% No such interface\n");
856 }
12e41d03
DL
857}
858
64c86530 859static void igmp_show_interface_join(struct pim_instance *pim, struct vty *vty)
12e41d03 860{
d62a17ae 861 struct interface *ifp;
862 time_t now;
863
864 now = pim_time_monotonic_sec();
865
866 vty_out(vty,
ff415346 867 "Interface Address Source Group Socket Uptime \n");
d62a17ae 868
451fda4f 869 FOR_ALL_INTERFACES (pim->vrf, ifp) {
d62a17ae 870 struct pim_interface *pim_ifp;
871 struct listnode *join_node;
872 struct igmp_join *ij;
873 struct in_addr pri_addr;
874 char pri_addr_str[INET_ADDRSTRLEN];
875
876 pim_ifp = ifp->info;
877
878 if (!pim_ifp)
879 continue;
880
881 if (!pim_ifp->igmp_join_list)
882 continue;
883
884 pri_addr = pim_find_primary_addr(ifp);
885 pim_inet4_dump("<pri?>", pri_addr, pri_addr_str,
886 sizeof(pri_addr_str));
887
888 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_join_list, join_node,
889 ij)) {
890 char group_str[INET_ADDRSTRLEN];
891 char source_str[INET_ADDRSTRLEN];
892 char uptime[10];
893
894 pim_time_uptime(uptime, sizeof(uptime),
895 now - ij->sock_creation);
896 pim_inet4_dump("<grp?>", ij->group_addr, group_str,
897 sizeof(group_str));
898 pim_inet4_dump("<src?>", ij->source_addr, source_str,
899 sizeof(source_str));
900
ff415346 901 vty_out(vty, "%-16s %-15s %-15s %-15s %6d %8s\n",
d62a17ae 902 ifp->name, pri_addr_str, source_str, group_str,
903 ij->sock_fd, uptime);
904 } /* for (pim_ifp->igmp_join_list) */
905
906 } /* for (iflist) */
907}
908
64c86530
DS
909static void pim_show_interfaces_single(struct pim_instance *pim,
910 struct vty *vty, const char *ifname,
088f1098 911 bool uj)
d62a17ae 912{
913 struct in_addr ifaddr;
914 struct interface *ifp;
915 struct listnode *neighnode;
d62a17ae 916 struct listnode *upnode;
917 struct pim_interface *pim_ifp;
918 struct pim_neighbor *neigh;
919 struct pim_upstream *up;
920 time_t now;
921 char dr_str[INET_ADDRSTRLEN];
922 char dr_uptime[10];
923 char expire[10];
924 char grp_str[INET_ADDRSTRLEN];
925 char hello_period[10];
926 char hello_timer[10];
927 char neigh_src_str[INET_ADDRSTRLEN];
928 char src_str[INET_ADDRSTRLEN];
929 char stat_uptime[10];
930 char uptime[10];
96ceedc7 931 int mloop = 0;
d62a17ae 932 int found_ifname = 0;
933 int print_header;
934 json_object *json = NULL;
935 json_object *json_row = NULL;
936 json_object *json_pim_neighbor = NULL;
937 json_object *json_pim_neighbors = NULL;
938 json_object *json_group = NULL;
939 json_object *json_group_source = NULL;
940 json_object *json_fhr_sources = NULL;
941 struct pim_secondary_addr *sec_addr;
942 struct listnode *sec_node;
943
944 now = pim_time_monotonic_sec();
945
946 if (uj)
947 json = json_object_new_object();
948
451fda4f 949 FOR_ALL_INTERFACES (pim->vrf, ifp) {
d62a17ae 950 pim_ifp = ifp->info;
951
952 if (!pim_ifp)
953 continue;
954
d62a17ae 955 if (strcmp(ifname, "detail") && strcmp(ifname, ifp->name))
956 continue;
957
958 found_ifname = 1;
959 ifaddr = pim_ifp->primary_address;
960 pim_inet4_dump("<dr?>", pim_ifp->pim_dr_addr, dr_str,
961 sizeof(dr_str));
962 pim_time_uptime_begin(dr_uptime, sizeof(dr_uptime), now,
963 pim_ifp->pim_dr_election_last);
964 pim_time_timer_to_hhmmss(hello_timer, sizeof(hello_timer),
965 pim_ifp->t_pim_hello_timer);
966 pim_time_mmss(hello_period, sizeof(hello_period),
967 pim_ifp->pim_hello_period);
968 pim_time_uptime(stat_uptime, sizeof(stat_uptime),
969 now - pim_ifp->pim_ifstat_start);
96ceedc7
CS
970 if (pim_ifp->pim_sock_fd >= 0)
971 mloop = pim_socket_mcastloop_get(pim_ifp->pim_sock_fd);
972 else
973 mloop = 0;
d62a17ae 974
975 if (uj) {
976 char pbuf[PREFIX2STR_BUFFER];
977 json_row = json_object_new_object();
978 json_object_pim_ifp_add(json_row, ifp);
979
980 if (pim_ifp->update_source.s_addr != INADDR_ANY) {
981 json_object_string_add(
982 json_row, "useSource",
983 inet_ntoa(pim_ifp->update_source));
984 }
985 if (pim_ifp->sec_addr_list) {
986 json_object *sec_list = NULL;
987
988 sec_list = json_object_new_array();
989 for (ALL_LIST_ELEMENTS_RO(
990 pim_ifp->sec_addr_list, sec_node,
991 sec_addr)) {
992 json_object_array_add(
993 sec_list,
994 json_object_new_string(
995 prefix2str(
996 &sec_addr->addr,
997 pbuf,
998 sizeof(pbuf))));
999 }
1000 json_object_object_add(json_row,
1001 "secondaryAddressList",
1002 sec_list);
1003 }
1004
1005 // PIM neighbors
1006 if (pim_ifp->pim_neighbor_list->count) {
1007 json_pim_neighbors = json_object_new_object();
1008
1009 for (ALL_LIST_ELEMENTS_RO(
1010 pim_ifp->pim_neighbor_list,
1011 neighnode, neigh)) {
1012 json_pim_neighbor =
1013 json_object_new_object();
1014 pim_inet4_dump("<src?>",
1015 neigh->source_addr,
1016 neigh_src_str,
1017 sizeof(neigh_src_str));
1018 pim_time_uptime(uptime, sizeof(uptime),
1019 now - neigh->creation);
1020 pim_time_timer_to_hhmmss(
1021 expire, sizeof(expire),
1022 neigh->t_expire_timer);
1023
1024 json_object_string_add(
1025 json_pim_neighbor, "address",
1026 neigh_src_str);
1027 json_object_string_add(
1028 json_pim_neighbor, "upTime",
1029 uptime);
1030 json_object_string_add(
1031 json_pim_neighbor, "holdtime",
1032 expire);
1033
1034 json_object_object_add(
1035 json_pim_neighbors,
1036 neigh_src_str,
1037 json_pim_neighbor);
1038 }
1039
1040 json_object_object_add(json_row, "neighbors",
1041 json_pim_neighbors);
1042 }
1043
1044 json_object_string_add(json_row, "drAddress", dr_str);
1045 json_object_int_add(json_row, "drPriority",
1046 pim_ifp->pim_dr_priority);
1047 json_object_string_add(json_row, "drUptime", dr_uptime);
1048 json_object_int_add(json_row, "drElections",
1049 pim_ifp->pim_dr_election_count);
1050 json_object_int_add(json_row, "drChanges",
1051 pim_ifp->pim_dr_election_changes);
1052
1053 // FHR
c68ba0d7 1054 for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, upnode,
d62a17ae 1055 up)) {
5fe58e3d
DS
1056 if (ifp != up->rpf.source_nexthop.interface)
1057 continue;
1058
1059 if (!(up->flags & PIM_UPSTREAM_FLAG_MASK_FHR))
1060 continue;
1061
1062 if (!json_fhr_sources)
1063 json_fhr_sources =
1064 json_object_new_object();
1065
996c9314
LB
1066 pim_inet4_dump("<src?>", up->sg.src, src_str,
1067 sizeof(src_str));
1068 pim_inet4_dump("<grp?>", up->sg.grp, grp_str,
1069 sizeof(grp_str));
5fe58e3d
DS
1070 pim_time_uptime(uptime, sizeof(uptime),
1071 now - up->state_transition);
1072
1073 /*
1074 * Does this group live in json_fhr_sources?
1075 * If not create it.
1076 */
1077 json_object_object_get_ex(json_fhr_sources,
996c9314 1078 grp_str, &json_group);
5fe58e3d
DS
1079
1080 if (!json_group) {
1081 json_group = json_object_new_object();
996c9314
LB
1082 json_object_object_add(json_fhr_sources,
1083 grp_str,
1084 json_group);
d62a17ae 1085 }
5fe58e3d
DS
1086
1087 json_group_source = json_object_new_object();
1088 json_object_string_add(json_group_source,
1089 "source", src_str);
1090 json_object_string_add(json_group_source,
1091 "group", grp_str);
1092 json_object_string_add(json_group_source,
1093 "upTime", uptime);
1094 json_object_object_add(json_group, src_str,
1095 json_group_source);
d62a17ae 1096 }
1097
1098 if (json_fhr_sources) {
1099 json_object_object_add(json_row,
1100 "firstHopRouter",
1101 json_fhr_sources);
1102 }
1103
1104 json_object_int_add(json_row, "helloPeriod",
1105 pim_ifp->pim_hello_period);
1106 json_object_string_add(json_row, "helloTimer",
1107 hello_timer);
1108 json_object_string_add(json_row, "helloStatStart",
1109 stat_uptime);
1110 json_object_int_add(json_row, "helloReceived",
1111 pim_ifp->pim_ifstat_hello_recv);
1112 json_object_int_add(json_row, "helloReceivedFailed",
1113 pim_ifp->pim_ifstat_hello_recvfail);
1114 json_object_int_add(json_row, "helloSend",
1115 pim_ifp->pim_ifstat_hello_sent);
1116 json_object_int_add(json_row, "hellosendFailed",
1117 pim_ifp->pim_ifstat_hello_sendfail);
1118 json_object_int_add(json_row, "helloGenerationId",
1119 pim_ifp->pim_generation_id);
1120 json_object_int_add(json_row, "flagMulticastLoop",
1121 mloop);
1122
1123 json_object_int_add(
1124 json_row, "effectivePropagationDelay",
1125 pim_if_effective_propagation_delay_msec(ifp));
1126 json_object_int_add(
1127 json_row, "effectiveOverrideInterval",
1128 pim_if_effective_override_interval_msec(ifp));
1129 json_object_int_add(
1130 json_row, "joinPruneOverrideInterval",
1131 pim_if_jp_override_interval_msec(ifp));
1132
1133 json_object_int_add(
1134 json_row, "propagationDelay",
1135 pim_ifp->pim_propagation_delay_msec);
1136 json_object_int_add(
1137 json_row, "propagationDelayHighest",
1138 pim_ifp->pim_neighbors_highest_propagation_delay_msec);
1139 json_object_int_add(
1140 json_row, "overrideInterval",
1141 pim_ifp->pim_override_interval_msec);
1142 json_object_int_add(
1143 json_row, "overrideIntervalHighest",
1144 pim_ifp->pim_neighbors_highest_override_interval_msec);
1145 json_object_object_add(json, ifp->name, json_row);
1146
1147 } else {
1148 vty_out(vty, "Interface : %s\n", ifp->name);
1149 vty_out(vty, "State : %s\n",
1150 if_is_up(ifp) ? "up" : "down");
1151 if (pim_ifp->update_source.s_addr != INADDR_ANY) {
1152 vty_out(vty, "Use Source : %s\n",
1153 inet_ntoa(pim_ifp->update_source));
1154 }
1155 if (pim_ifp->sec_addr_list) {
1156 char pbuf[PREFIX2STR_BUFFER];
1157 vty_out(vty, "Address : %s (primary)\n",
1158 inet_ntoa(ifaddr));
1159 for (ALL_LIST_ELEMENTS_RO(
1160 pim_ifp->sec_addr_list, sec_node,
1161 sec_addr)) {
1162 vty_out(vty, " %s\n",
1163 prefix2str(&sec_addr->addr,
1164 pbuf, sizeof(pbuf)));
1165 }
1166 } else {
1167 vty_out(vty, "Address : %s\n",
1168 inet_ntoa(ifaddr));
1169 }
1170 vty_out(vty, "\n");
1171
1172 // PIM neighbors
1173 print_header = 1;
1174
1175 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list,
1176 neighnode, neigh)) {
1177
1178 if (print_header) {
1179 vty_out(vty, "PIM Neighbors\n");
1180 vty_out(vty, "-------------\n");
1181 print_header = 0;
1182 }
1183
1184 pim_inet4_dump("<src?>", neigh->source_addr,
1185 neigh_src_str,
1186 sizeof(neigh_src_str));
1187 pim_time_uptime(uptime, sizeof(uptime),
1188 now - neigh->creation);
1189 pim_time_timer_to_hhmmss(expire, sizeof(expire),
1190 neigh->t_expire_timer);
1191 vty_out(vty,
1192 "%-15s : up for %s, holdtime expires in %s\n",
1193 neigh_src_str, uptime, expire);
1194 }
1195
1196 if (!print_header) {
1197 vty_out(vty, "\n");
1198 vty_out(vty, "\n");
1199 }
1200
1201 vty_out(vty, "Designated Router\n");
1202 vty_out(vty, "-----------------\n");
1203 vty_out(vty, "Address : %s\n", dr_str);
f116689e 1204 vty_out(vty, "Priority : %u(%d)\n",
a0bf54c7
DS
1205 pim_ifp->pim_dr_priority,
1206 pim_ifp->pim_dr_num_nondrpri_neighbors);
d62a17ae 1207 vty_out(vty, "Uptime : %s\n", dr_uptime);
1208 vty_out(vty, "Elections : %d\n",
1209 pim_ifp->pim_dr_election_count);
1210 vty_out(vty, "Changes : %d\n",
1211 pim_ifp->pim_dr_election_changes);
1212 vty_out(vty, "\n");
1213 vty_out(vty, "\n");
1214
1215 // FHR
1216 print_header = 1;
c68ba0d7 1217 for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, upnode,
d62a17ae 1218 up)) {
859ea2de
DS
1219 if (!up->rpf.source_nexthop.interface)
1220 continue;
5fe58e3d
DS
1221
1222 if (strcmp(ifp->name,
996c9314
LB
1223 up->rpf.source_nexthop
1224 .interface->name)
1225 != 0)
5fe58e3d
DS
1226 continue;
1227
1228 if (!(up->flags & PIM_UPSTREAM_FLAG_MASK_FHR))
1229 continue;
1230
1231 if (print_header) {
1232 vty_out(vty,
1233 "FHR - First Hop Router\n");
1234 vty_out(vty,
1235 "----------------------\n");
1236 print_header = 0;
d62a17ae 1237 }
5fe58e3d 1238
996c9314
LB
1239 pim_inet4_dump("<src?>", up->sg.src, src_str,
1240 sizeof(src_str));
1241 pim_inet4_dump("<grp?>", up->sg.grp, grp_str,
1242 sizeof(grp_str));
5fe58e3d
DS
1243 pim_time_uptime(uptime, sizeof(uptime),
1244 now - up->state_transition);
1245 vty_out(vty,
1246 "%s : %s is a source, uptime is %s\n",
996c9314 1247 grp_str, src_str, uptime);
d62a17ae 1248 }
1249
1250 if (!print_header) {
1251 vty_out(vty, "\n");
1252 vty_out(vty, "\n");
1253 }
1254
1255 vty_out(vty, "Hellos\n");
1256 vty_out(vty, "------\n");
1257 vty_out(vty, "Period : %d\n",
1258 pim_ifp->pim_hello_period);
1259 vty_out(vty, "Timer : %s\n", hello_timer);
1260 vty_out(vty, "StatStart : %s\n", stat_uptime);
1261 vty_out(vty, "Receive : %d\n",
1262 pim_ifp->pim_ifstat_hello_recv);
1263 vty_out(vty, "Receive Failed : %d\n",
1264 pim_ifp->pim_ifstat_hello_recvfail);
1265 vty_out(vty, "Send : %d\n",
1266 pim_ifp->pim_ifstat_hello_sent);
1267 vty_out(vty, "Send Failed : %d\n",
1268 pim_ifp->pim_ifstat_hello_sendfail);
1269 vty_out(vty, "Generation ID : %08x\n",
1270 pim_ifp->pim_generation_id);
1271 vty_out(vty, "\n");
1272 vty_out(vty, "\n");
1273
1274 pim_print_ifp_flags(vty, ifp, mloop);
1275
1276 vty_out(vty, "Join Prune Interval\n");
1277 vty_out(vty, "-------------------\n");
1278 vty_out(vty, "LAN Delay : %s\n",
1279 pim_if_lan_delay_enabled(ifp) ? "yes" : "no");
1280 vty_out(vty, "Effective Propagation Delay : %d msec\n",
1281 pim_if_effective_propagation_delay_msec(ifp));
1282 vty_out(vty, "Effective Override Interval : %d msec\n",
1283 pim_if_effective_override_interval_msec(ifp));
1284 vty_out(vty, "Join Prune Override Interval : %d msec\n",
1285 pim_if_jp_override_interval_msec(ifp));
1286 vty_out(vty, "\n");
1287 vty_out(vty, "\n");
1288
1289 vty_out(vty, "LAN Prune Delay\n");
1290 vty_out(vty, "---------------\n");
1291 vty_out(vty, "Propagation Delay : %d msec\n",
1292 pim_ifp->pim_propagation_delay_msec);
1293 vty_out(vty, "Propagation Delay (Highest) : %d msec\n",
1294 pim_ifp->pim_neighbors_highest_propagation_delay_msec);
1295 vty_out(vty, "Override Interval : %d msec\n",
1296 pim_ifp->pim_override_interval_msec);
1297 vty_out(vty, "Override Interval (Highest) : %d msec\n",
1298 pim_ifp->pim_neighbors_highest_override_interval_msec);
1299 vty_out(vty, "\n");
1300 vty_out(vty, "\n");
1301 }
1302 }
1303
1304 if (uj) {
9d303b37
DL
1305 vty_out(vty, "%s\n", json_object_to_json_string_ext(
1306 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 1307 json_object_free(json);
1308 } else {
1309 if (!found_ifname)
1310 vty_out(vty, "%% No such interface\n");
1311 }
12e41d03
DL
1312}
1313
21313cbf 1314static void igmp_show_statistics(struct pim_instance *pim, struct vty *vty,
088f1098 1315 const char *ifname, bool uj)
21313cbf
MS
1316{
1317 struct interface *ifp;
1318 struct igmp_stats rx_stats;
1319
1320 igmp_stats_init(&rx_stats);
1321
1322 FOR_ALL_INTERFACES (pim->vrf, ifp) {
1323 struct pim_interface *pim_ifp;
1324 struct listnode *sock_node;
1325 struct igmp_sock *igmp;
1326
1327 pim_ifp = ifp->info;
1328
1329 if (!pim_ifp)
1330 continue;
1331
1332 if (ifname && strcmp(ifname, ifp->name))
1333 continue;
1334
1335 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node,
1336 igmp)) {
1337 igmp_stats_add(&rx_stats, &igmp->rx_stats);
1338 }
1339 }
1340 if (uj) {
1341 json_object *json = NULL;
1342 json_object *json_row = NULL;
1343
1344 json = json_object_new_object();
1345 json_row = json_object_new_object();
1346
1347 json_object_string_add(json_row, "name", ifname ? ifname :
1348 "global");
1349 json_object_int_add(json_row, "queryV1", rx_stats.query_v1);
1350 json_object_int_add(json_row, "queryV2", rx_stats.query_v2);
1351 json_object_int_add(json_row, "queryV3", rx_stats.query_v3);
1352 json_object_int_add(json_row, "leaveV3", rx_stats.leave_v2);
1353 json_object_int_add(json_row, "reportV1", rx_stats.report_v1);
1354 json_object_int_add(json_row, "reportV2", rx_stats.report_v2);
1355 json_object_int_add(json_row, "reportV3", rx_stats.report_v3);
1356 json_object_int_add(json_row, "mtraceResponse",
1357 rx_stats.mtrace_rsp);
1358 json_object_int_add(json_row, "mtraceRequest",
1359 rx_stats.mtrace_req);
1360 json_object_int_add(json_row, "unsupported",
1361 rx_stats.unsupported);
1362 json_object_object_add(json, ifname ? ifname : "global",
1363 json_row);
1364 vty_out(vty, "%s\n", json_object_to_json_string_ext(
1365 json, JSON_C_TO_STRING_PRETTY));
1366 json_object_free(json);
1367 } else {
1368 vty_out(vty, "IGMP RX statistics\n");
1369 vty_out(vty, "Interface : %s\n",
1370 ifname ? ifname : "global");
1371 vty_out(vty, "V1 query : %u\n", rx_stats.query_v1);
1372 vty_out(vty, "V2 query : %u\n", rx_stats.query_v2);
1373 vty_out(vty, "V3 query : %u\n", rx_stats.query_v3);
1374 vty_out(vty, "V2 leave : %u\n", rx_stats.leave_v2);
1375 vty_out(vty, "V1 report : %u\n", rx_stats.report_v1);
1376 vty_out(vty, "V2 report : %u\n", rx_stats.report_v2);
1377 vty_out(vty, "V3 report : %u\n", rx_stats.report_v3);
1378 vty_out(vty, "mtrace response : %u\n", rx_stats.mtrace_rsp);
1379 vty_out(vty, "mtrace request : %u\n", rx_stats.mtrace_req);
1380 vty_out(vty, "unsupported : %u\n", rx_stats.unsupported);
1381 }
1382}
1383
64c86530 1384static void pim_show_interfaces(struct pim_instance *pim, struct vty *vty,
088f1098 1385 bool uj)
12e41d03 1386{
d62a17ae 1387 struct interface *ifp;
d62a17ae 1388 struct listnode *upnode;
1389 struct pim_interface *pim_ifp;
1390 struct pim_upstream *up;
1391 int fhr = 0;
1392 int pim_nbrs = 0;
1393 int pim_ifchannels = 0;
1394 json_object *json = NULL;
1395 json_object *json_row = NULL;
1396 json_object *json_tmp;
1397
1398 json = json_object_new_object();
1399
451fda4f 1400 FOR_ALL_INTERFACES (pim->vrf, ifp) {
d62a17ae 1401 pim_ifp = ifp->info;
1402
1403 if (!pim_ifp)
1404 continue;
1405
d62a17ae 1406 pim_nbrs = pim_ifp->pim_neighbor_list->count;
ad7b74c4 1407 pim_ifchannels = pim_if_ifchannel_count(pim_ifp);
d62a17ae 1408 fhr = 0;
1409
c68ba0d7 1410 for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, upnode, up))
d62a17ae 1411 if (ifp == up->rpf.source_nexthop.interface)
1412 if (up->flags & PIM_UPSTREAM_FLAG_MASK_FHR)
1413 fhr++;
1414
1415 json_row = json_object_new_object();
1416 json_object_pim_ifp_add(json_row, ifp);
1417 json_object_int_add(json_row, "pimNeighbors", pim_nbrs);
1418 json_object_int_add(json_row, "pimIfChannels", pim_ifchannels);
15507b63 1419 json_object_int_add(json_row, "firstHopRouterCount", fhr);
d62a17ae 1420 json_object_string_add(json_row, "pimDesignatedRouter",
1421 inet_ntoa(pim_ifp->pim_dr_addr));
1422
1423 if (pim_ifp->pim_dr_addr.s_addr
1424 == pim_ifp->primary_address.s_addr)
1425 json_object_boolean_true_add(
1426 json_row, "pimDesignatedRouterLocal");
1427
1428 json_object_object_add(json, ifp->name, json_row);
1429 }
1430
1431 if (uj) {
9d303b37
DL
1432 vty_out(vty, "%s\n", json_object_to_json_string_ext(
1433 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 1434 } else {
1435 vty_out(vty,
ff415346 1436 "Interface State Address PIM Nbrs PIM DR FHR IfChannels\n");
d62a17ae 1437
1438 json_object_object_foreach(json, key, val)
1439 {
ff415346 1440 vty_out(vty, "%-16s ", key);
d62a17ae 1441
1442 json_object_object_get_ex(val, "state", &json_tmp);
1443 vty_out(vty, "%5s ", json_object_get_string(json_tmp));
1444
1445 json_object_object_get_ex(val, "address", &json_tmp);
1446 vty_out(vty, "%15s ",
1447 json_object_get_string(json_tmp));
1448
1449 json_object_object_get_ex(val, "pimNeighbors",
1450 &json_tmp);
1451 vty_out(vty, "%8d ", json_object_get_int(json_tmp));
1452
1453 if (json_object_object_get_ex(
1454 val, "pimDesignatedRouterLocal",
1455 &json_tmp)) {
1456 vty_out(vty, "%15s ", "local");
1457 } else {
1458 json_object_object_get_ex(
1459 val, "pimDesignatedRouter", &json_tmp);
1460 vty_out(vty, "%15s ",
1461 json_object_get_string(json_tmp));
1462 }
1463
1464 json_object_object_get_ex(val, "firstHopRouter",
1465 &json_tmp);
1466 vty_out(vty, "%3d ", json_object_get_int(json_tmp));
1467
1468 json_object_object_get_ex(val, "pimIfChannels",
1469 &json_tmp);
1470 vty_out(vty, "%9d\n", json_object_get_int(json_tmp));
1471 }
1472 }
1473
1474 json_object_free(json);
1475}
1476
64c86530 1477static void pim_show_interface_traffic(struct pim_instance *pim,
088f1098 1478 struct vty *vty, bool uj)
d62a17ae 1479{
1480 struct interface *ifp = NULL;
1481 struct pim_interface *pim_ifp = NULL;
d62a17ae 1482 json_object *json = NULL;
1483 json_object *json_row = NULL;
1484
1485 if (uj)
1486 json = json_object_new_object();
1487 else {
1488 vty_out(vty, "\n");
4616b2e9 1489 vty_out(vty, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s%-17s\n",
ff415346
DS
1490 "Interface", " HELLO", " JOIN",
1491 " PRUNE", " REGISTER", "REGISTER-STOP",
4616b2e9 1492 " ASSERT", " BSM");
1493 vty_out(vty, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s%-17s\n", "",
ff415346 1494 " Rx/Tx", " Rx/Tx", " Rx/Tx",
4616b2e9 1495 " Rx/Tx", " Rx/Tx", " Rx/Tx",
1496 " Rx/Tx");
d62a17ae 1497 vty_out(vty,
1498 "---------------------------------------------------------------------------------------------------------------\n");
1499 }
1500
451fda4f 1501 FOR_ALL_INTERFACES (pim->vrf, ifp) {
d62a17ae 1502 pim_ifp = ifp->info;
1503
1504 if (!pim_ifp)
1505 continue;
1506
1507 if (pim_ifp->pim_sock_fd < 0)
1508 continue;
1509 if (uj) {
1510 json_row = json_object_new_object();
1511 json_object_pim_ifp_add(json_row, ifp);
1512 json_object_int_add(json_row, "helloRx",
1513 pim_ifp->pim_ifstat_hello_recv);
1514 json_object_int_add(json_row, "helloTx",
1515 pim_ifp->pim_ifstat_hello_sent);
1516 json_object_int_add(json_row, "joinRx",
1517 pim_ifp->pim_ifstat_join_recv);
1518 json_object_int_add(json_row, "joinTx",
1519 pim_ifp->pim_ifstat_join_send);
1520 json_object_int_add(json_row, "registerRx",
1521 pim_ifp->pim_ifstat_reg_recv);
1522 json_object_int_add(json_row, "registerTx",
1523 pim_ifp->pim_ifstat_reg_recv);
1524 json_object_int_add(json_row, "registerStopRx",
1525 pim_ifp->pim_ifstat_reg_stop_recv);
1526 json_object_int_add(json_row, "registerStopTx",
1527 pim_ifp->pim_ifstat_reg_stop_send);
1528 json_object_int_add(json_row, "assertRx",
1529 pim_ifp->pim_ifstat_assert_recv);
1530 json_object_int_add(json_row, "assertTx",
4616b2e9 1531 pim_ifp->pim_ifstat_assert_send);
1532 json_object_int_add(json_row, "bsmRx",
1533 pim_ifp->pim_ifstat_bsm_rx);
1534 json_object_int_add(json_row, "bsmTx",
1535 pim_ifp->pim_ifstat_bsm_tx);
d62a17ae 1536 json_object_object_add(json, ifp->name, json_row);
1537 } else {
1538 vty_out(vty,
4616b2e9 1539 "%-16s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7lu/%-7lu \n",
d62a17ae 1540 ifp->name, pim_ifp->pim_ifstat_hello_recv,
1541 pim_ifp->pim_ifstat_hello_sent,
1542 pim_ifp->pim_ifstat_join_recv,
1543 pim_ifp->pim_ifstat_join_send,
1544 pim_ifp->pim_ifstat_prune_recv,
1545 pim_ifp->pim_ifstat_prune_send,
1546 pim_ifp->pim_ifstat_reg_recv,
1547 pim_ifp->pim_ifstat_reg_send,
1548 pim_ifp->pim_ifstat_reg_stop_recv,
1549 pim_ifp->pim_ifstat_reg_stop_send,
1550 pim_ifp->pim_ifstat_assert_recv,
4616b2e9 1551 pim_ifp->pim_ifstat_assert_send,
1552 pim_ifp->pim_ifstat_bsm_rx,
1553 pim_ifp->pim_ifstat_bsm_tx);
d62a17ae 1554 }
1555 }
1556 if (uj) {
9d303b37
DL
1557 vty_out(vty, "%s\n", json_object_to_json_string_ext(
1558 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 1559 json_object_free(json);
1560 }
1561}
1562
64c86530
DS
1563static void pim_show_interface_traffic_single(struct pim_instance *pim,
1564 struct vty *vty,
088f1098 1565 const char *ifname, bool uj)
d62a17ae 1566{
1567 struct interface *ifp = NULL;
1568 struct pim_interface *pim_ifp = NULL;
d62a17ae 1569 json_object *json = NULL;
1570 json_object *json_row = NULL;
1571 uint8_t found_ifname = 0;
1572
1573 if (uj)
1574 json = json_object_new_object();
1575 else {
1576 vty_out(vty, "\n");
4616b2e9 1577 vty_out(vty, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s%-17s\n",
d62a17ae 1578 "Interface", " HELLO", " JOIN", " PRUNE",
4616b2e9 1579 " REGISTER", " REGISTER-STOP", " ASSERT",
1580 " BSM");
1581 vty_out(vty, "%-14s%-18s%-17s%-17s%-17s%-17s%-17s%-17s\n", "",
d62a17ae 1582 " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
4616b2e9 1583 " Rx/Tx", " Rx/Tx", " Rx/Tx");
d62a17ae 1584 vty_out(vty,
4616b2e9 1585 "-------------------------------------------------------------------------------------------------------------------------------\n");
d62a17ae 1586 }
1587
451fda4f 1588 FOR_ALL_INTERFACES (pim->vrf, ifp) {
d62a17ae 1589 if (strcmp(ifname, ifp->name))
1590 continue;
1591
1592 pim_ifp = ifp->info;
1593
1594 if (!pim_ifp)
1595 continue;
1596
1597 if (pim_ifp->pim_sock_fd < 0)
1598 continue;
1599
1600 found_ifname = 1;
1601 if (uj) {
1602 json_row = json_object_new_object();
1603 json_object_pim_ifp_add(json_row, ifp);
1604 json_object_int_add(json_row, "helloRx",
1605 pim_ifp->pim_ifstat_hello_recv);
1606 json_object_int_add(json_row, "helloTx",
1607 pim_ifp->pim_ifstat_hello_sent);
1608 json_object_int_add(json_row, "joinRx",
1609 pim_ifp->pim_ifstat_join_recv);
1610 json_object_int_add(json_row, "joinTx",
1611 pim_ifp->pim_ifstat_join_send);
1612 json_object_int_add(json_row, "registerRx",
1613 pim_ifp->pim_ifstat_reg_recv);
1614 json_object_int_add(json_row, "registerTx",
1615 pim_ifp->pim_ifstat_reg_recv);
1616 json_object_int_add(json_row, "registerStopRx",
1617 pim_ifp->pim_ifstat_reg_stop_recv);
1618 json_object_int_add(json_row, "registerStopTx",
1619 pim_ifp->pim_ifstat_reg_stop_send);
1620 json_object_int_add(json_row, "assertRx",
1621 pim_ifp->pim_ifstat_assert_recv);
1622 json_object_int_add(json_row, "assertTx",
1623 pim_ifp->pim_ifstat_assert_send);
4616b2e9 1624 json_object_int_add(json_row, "bsmRx",
1625 pim_ifp->pim_ifstat_bsm_rx);
1626 json_object_int_add(json_row, "bsmTx",
1627 pim_ifp->pim_ifstat_bsm_tx);
d62a17ae 1628
1629 json_object_object_add(json, ifp->name, json_row);
1630 } else {
1631 vty_out(vty,
4616b2e9 1632 "%-16s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7lu/%-7lu \n",
d62a17ae 1633 ifp->name, pim_ifp->pim_ifstat_hello_recv,
1634 pim_ifp->pim_ifstat_hello_sent,
1635 pim_ifp->pim_ifstat_join_recv,
1636 pim_ifp->pim_ifstat_join_send,
1637 pim_ifp->pim_ifstat_prune_recv,
1638 pim_ifp->pim_ifstat_prune_send,
1639 pim_ifp->pim_ifstat_reg_recv,
1640 pim_ifp->pim_ifstat_reg_send,
1641 pim_ifp->pim_ifstat_reg_stop_recv,
1642 pim_ifp->pim_ifstat_reg_stop_send,
1643 pim_ifp->pim_ifstat_assert_recv,
4616b2e9 1644 pim_ifp->pim_ifstat_assert_send,
1645 pim_ifp->pim_ifstat_bsm_rx,
1646 pim_ifp->pim_ifstat_bsm_tx);
d62a17ae 1647 }
1648 }
1649 if (uj) {
9d303b37
DL
1650 vty_out(vty, "%s\n", json_object_to_json_string_ext(
1651 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 1652 json_object_free(json);
1653 } else {
1654 if (!found_ifname)
1655 vty_out(vty, "%% No such interface\n");
1656 }
39438188
CS
1657}
1658
996c9314
LB
1659static void pim_show_join_helper(struct vty *vty, struct pim_interface *pim_ifp,
1660 struct pim_ifchannel *ch, json_object *json,
088f1098 1661 time_t now, bool uj)
1a8a3da8
DS
1662{
1663 char ch_src_str[INET_ADDRSTRLEN];
1664 char ch_grp_str[INET_ADDRSTRLEN];
1665 json_object *json_iface = NULL;
1666 json_object *json_row = NULL;
1667 json_object *json_grp = NULL;
1668 struct in_addr ifaddr;
1669 char uptime[10];
1670 char expire[10];
1671 char prune[10];
1672
1673 ifaddr = pim_ifp->primary_address;
1674
996c9314
LB
1675 pim_inet4_dump("<ch_src?>", ch->sg.src, ch_src_str, sizeof(ch_src_str));
1676 pim_inet4_dump("<ch_grp?>", ch->sg.grp, ch_grp_str, sizeof(ch_grp_str));
1a8a3da8 1677
996c9314 1678 pim_time_uptime_begin(uptime, sizeof(uptime), now, ch->ifjoin_creation);
1a8a3da8
DS
1679 pim_time_timer_to_mmss(expire, sizeof(expire),
1680 ch->t_ifjoin_expiry_timer);
1681 pim_time_timer_to_mmss(prune, sizeof(prune),
1682 ch->t_ifjoin_prune_pending_timer);
1683
1684 if (uj) {
1685 json_object_object_get_ex(json, ch->interface->name,
1686 &json_iface);
1687
1688 if (!json_iface) {
1689 json_iface = json_object_new_object();
996c9314
LB
1690 json_object_pim_ifp_add(json_iface, ch->interface);
1691 json_object_object_add(json, ch->interface->name,
1692 json_iface);
1a8a3da8
DS
1693 }
1694
1695 json_row = json_object_new_object();
1696 json_object_string_add(json_row, "source", ch_src_str);
1697 json_object_string_add(json_row, "group", ch_grp_str);
1698 json_object_string_add(json_row, "upTime", uptime);
1699 json_object_string_add(json_row, "expire", expire);
1700 json_object_string_add(json_row, "prune", prune);
1701 json_object_string_add(
1702 json_row, "channelJoinName",
996c9314 1703 pim_ifchannel_ifjoin_name(ch->ifjoin_state, ch->flags));
1a8a3da8
DS
1704 if (PIM_IF_FLAG_TEST_S_G_RPT(ch->flags))
1705 json_object_int_add(json_row, "SGRpt", 1);
1706
996c9314 1707 json_object_object_get_ex(json_iface, ch_grp_str, &json_grp);
1a8a3da8
DS
1708 if (!json_grp) {
1709 json_grp = json_object_new_object();
996c9314 1710 json_object_object_add(json_grp, ch_src_str, json_row);
1a8a3da8
DS
1711 json_object_object_add(json_iface, ch_grp_str,
1712 json_grp);
1713 } else
996c9314 1714 json_object_object_add(json_grp, ch_src_str, json_row);
1a8a3da8 1715 } else {
ff415346 1716 vty_out(vty, "%-16s %-15s %-15s %-15s %-10s %8s %-6s %5s\n",
996c9314
LB
1717 ch->interface->name, inet_ntoa(ifaddr), ch_src_str,
1718 ch_grp_str,
1719 pim_ifchannel_ifjoin_name(ch->ifjoin_state, ch->flags),
1a8a3da8
DS
1720 uptime, expire, prune);
1721 }
1722}
1723
6de45bcc
DS
1724static void pim_show_join(struct pim_instance *pim, struct vty *vty,
1725 struct prefix_sg *sg, bool uj)
12e41d03 1726{
d62a17ae 1727 struct pim_interface *pim_ifp;
d62a17ae 1728 struct pim_ifchannel *ch;
1a8a3da8 1729 struct interface *ifp;
d62a17ae 1730 time_t now;
1731 json_object *json = NULL;
d62a17ae 1732
1733 now = pim_time_monotonic_sec();
1734
1735 if (uj)
1736 json = json_object_new_object();
1737 else
1738 vty_out(vty,
ff415346 1739 "Interface Address Source Group State Uptime Expire Prune\n");
d62a17ae 1740
451fda4f 1741 FOR_ALL_INTERFACES (pim->vrf, ifp) {
1a8a3da8 1742 pim_ifp = ifp->info;
d62a17ae 1743 if (!pim_ifp)
1744 continue;
1745
a2addae8 1746 RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
6de45bcc
DS
1747 if (sg->grp.s_addr != 0
1748 && sg->grp.s_addr != ch->sg.grp.s_addr)
1749 continue;
1750 if (sg->src.s_addr != 0
1751 && sg->src.s_addr != ch->sg.src.s_addr)
1752 continue;
a2addae8 1753 pim_show_join_helper(vty, pim_ifp, ch, json, now, uj);
1a8a3da8
DS
1754 } /* scan interface channels */
1755 }
d62a17ae 1756
1757 if (uj) {
9d303b37 1758 vty_out(vty, "%s\n", json_object_to_json_string_ext(
996c9314 1759 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 1760 json_object_free(json);
1761 }
1762}
1763
64c86530 1764static void pim_show_neighbors_single(struct pim_instance *pim, struct vty *vty,
088f1098 1765 const char *neighbor, bool uj)
d62a17ae 1766{
d62a17ae 1767 struct listnode *neighnode;
1768 struct interface *ifp;
1769 struct pim_interface *pim_ifp;
1770 struct pim_neighbor *neigh;
1771 time_t now;
1772 int found_neighbor = 0;
1773 int option_address_list;
1774 int option_dr_priority;
1775 int option_generation_id;
1776 int option_holdtime;
1777 int option_lan_prune_delay;
1778 int option_t_bit;
1779 char uptime[10];
1780 char expire[10];
1781 char neigh_src_str[INET_ADDRSTRLEN];
1782
1783 json_object *json = NULL;
1784 json_object *json_ifp = NULL;
1785 json_object *json_row = NULL;
1786
1787 now = pim_time_monotonic_sec();
1788
1789 if (uj)
1790 json = json_object_new_object();
1791
451fda4f 1792 FOR_ALL_INTERFACES (pim->vrf, ifp) {
d62a17ae 1793 pim_ifp = ifp->info;
1794
1795 if (!pim_ifp)
1796 continue;
1797
1798 if (pim_ifp->pim_sock_fd < 0)
1799 continue;
1800
1801 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode,
1802 neigh)) {
1803 pim_inet4_dump("<src?>", neigh->source_addr,
1804 neigh_src_str, sizeof(neigh_src_str));
1805
1806 /*
1807 * The user can specify either the interface name or the
1808 * PIM neighbor IP.
1809 * If this pim_ifp matches neither then skip.
1810 */
1811 if (strcmp(neighbor, "detail")
1812 && strcmp(neighbor, ifp->name)
1813 && strcmp(neighbor, neigh_src_str))
1814 continue;
1815
1816 found_neighbor = 1;
1817 pim_time_uptime(uptime, sizeof(uptime),
1818 now - neigh->creation);
1819 pim_time_timer_to_hhmmss(expire, sizeof(expire),
1820 neigh->t_expire_timer);
1821
1822 option_address_list = 0;
1823 option_dr_priority = 0;
1824 option_generation_id = 0;
1825 option_holdtime = 0;
1826 option_lan_prune_delay = 0;
1827 option_t_bit = 0;
1828
1829 if (PIM_OPTION_IS_SET(neigh->hello_options,
1830 PIM_OPTION_MASK_ADDRESS_LIST))
1831 option_address_list = 1;
1832
1833 if (PIM_OPTION_IS_SET(neigh->hello_options,
1834 PIM_OPTION_MASK_DR_PRIORITY))
1835 option_dr_priority = 1;
1836
1837 if (PIM_OPTION_IS_SET(neigh->hello_options,
1838 PIM_OPTION_MASK_GENERATION_ID))
1839 option_generation_id = 1;
1840
1841 if (PIM_OPTION_IS_SET(neigh->hello_options,
1842 PIM_OPTION_MASK_HOLDTIME))
1843 option_holdtime = 1;
1844
1845 if (PIM_OPTION_IS_SET(neigh->hello_options,
1846 PIM_OPTION_MASK_LAN_PRUNE_DELAY))
1847 option_lan_prune_delay = 1;
1848
1849 if (PIM_OPTION_IS_SET(
1850 neigh->hello_options,
1851 PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION))
1852 option_t_bit = 1;
1853
1854 if (uj) {
1855
1856 /* Does this ifp live in json? If not create
1857 * it. */
1858 json_object_object_get_ex(json, ifp->name,
1859 &json_ifp);
1860
1861 if (!json_ifp) {
1862 json_ifp = json_object_new_object();
1863 json_object_pim_ifp_add(json_ifp, ifp);
1864 json_object_object_add(json, ifp->name,
1865 json_ifp);
1866 }
1867
1868 json_row = json_object_new_object();
1869 json_object_string_add(json_row, "interface",
1870 ifp->name);
1871 json_object_string_add(json_row, "address",
1872 neigh_src_str);
1873 json_object_string_add(json_row, "upTime",
1874 uptime);
1875 json_object_string_add(json_row, "holdtime",
1876 expire);
1877 json_object_int_add(json_row, "drPriority",
1878 neigh->dr_priority);
1879 json_object_int_add(json_row, "generationId",
1880 neigh->generation_id);
1881
1882 if (option_address_list)
1883 json_object_boolean_true_add(
1884 json_row,
1885 "helloOptionAddressList");
1886
1887 if (option_dr_priority)
1888 json_object_boolean_true_add(
1889 json_row,
1890 "helloOptionDrPriority");
1891
1892 if (option_generation_id)
1893 json_object_boolean_true_add(
1894 json_row,
1895 "helloOptionGenerationId");
1896
1897 if (option_holdtime)
1898 json_object_boolean_true_add(
1899 json_row,
1900 "helloOptionHoldtime");
1901
1902 if (option_lan_prune_delay)
1903 json_object_boolean_true_add(
1904 json_row,
1905 "helloOptionLanPruneDelay");
1906
1907 if (option_t_bit)
1908 json_object_boolean_true_add(
1909 json_row, "helloOptionTBit");
1910
1911 json_object_object_add(json_ifp, neigh_src_str,
1912 json_row);
1913
1914 } else {
1915 vty_out(vty, "Interface : %s\n", ifp->name);
1916 vty_out(vty, "Neighbor : %s\n", neigh_src_str);
1917 vty_out(vty,
1918 " Uptime : %s\n",
1919 uptime);
1920 vty_out(vty,
1921 " Holdtime : %s\n",
1922 expire);
1923 vty_out(vty,
1924 " DR Priority : %d\n",
1925 neigh->dr_priority);
1926 vty_out(vty,
1927 " Generation ID : %08x\n",
1928 neigh->generation_id);
1929 vty_out(vty,
1930 " Override Interval (msec) : %d\n",
1931 neigh->override_interval_msec);
1932 vty_out(vty,
1933 " Propagation Delay (msec) : %d\n",
1934 neigh->propagation_delay_msec);
1935 vty_out(vty,
1936 " Hello Option - Address List : %s\n",
1937 option_address_list ? "yes" : "no");
1938 vty_out(vty,
1939 " Hello Option - DR Priority : %s\n",
1940 option_dr_priority ? "yes" : "no");
1941 vty_out(vty,
1942 " Hello Option - Generation ID : %s\n",
1943 option_generation_id ? "yes" : "no");
1944 vty_out(vty,
1945 " Hello Option - Holdtime : %s\n",
1946 option_holdtime ? "yes" : "no");
1947 vty_out(vty,
1948 " Hello Option - LAN Prune Delay : %s\n",
1949 option_lan_prune_delay ? "yes" : "no");
1950 vty_out(vty,
1951 " Hello Option - T-bit : %s\n",
1952 option_t_bit ? "yes" : "no");
1953 pim_bfd_show_info(vty, neigh->bfd_info,
1954 json_ifp, uj, 0);
1955 vty_out(vty, "\n");
1956 }
1957 }
1958 }
1959
1960 if (uj) {
9d303b37
DL
1961 vty_out(vty, "%s\n", json_object_to_json_string_ext(
1962 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 1963 json_object_free(json);
1964 } else {
1965 {
1966 if (!found_neighbor)
1967 vty_out(vty,
1968 "%% No such interface or neighbor\n");
1969 }
1970 }
1971}
1972
64c86530 1973static void pim_show_state(struct pim_instance *pim, struct vty *vty,
088f1098 1974 const char *src_or_group, const char *group, bool uj)
d62a17ae 1975{
1976 struct channel_oil *c_oil;
1977 struct listnode *node;
1978 json_object *json = NULL;
1979 json_object *json_group = NULL;
1980 json_object *json_ifp_in = NULL;
1981 json_object *json_ifp_out = NULL;
1982 json_object *json_source = NULL;
1983 time_t now;
1984 int first_oif;
1985 now = pim_time_monotonic_sec();
1986
1987 if (uj) {
1988 json = json_object_new_object();
1989 } else {
1990 vty_out(vty,
ee31c9fd 1991 "Codes: J -> Pim Join, I -> IGMP Report, S -> Source, * -> Inherited from (*,G), V -> VxLAN");
d62a17ae 1992 vty_out(vty,
ff415346 1993 "\nInstalled Source Group IIF OIL\n");
d62a17ae 1994 }
1995
c68ba0d7 1996 for (ALL_LIST_ELEMENTS_RO(pim->channel_oil_list, node, c_oil)) {
d62a17ae 1997 char grp_str[INET_ADDRSTRLEN];
1998 char src_str[INET_ADDRSTRLEN];
1999 char in_ifname[INTERFACE_NAMSIZ + 1];
2000 char out_ifname[INTERFACE_NAMSIZ + 1];
2001 int oif_vif_index;
2002 struct interface *ifp_in;
2003 first_oif = 1;
2004
2005 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, grp_str,
2006 sizeof(grp_str));
2007 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, src_str,
2008 sizeof(src_str));
7cfc7bcf 2009 ifp_in = pim_if_find_by_vif_index(pim, c_oil->oil.mfcc_parent);
d62a17ae 2010
2011 if (ifp_in)
c35b7e6b 2012 strlcpy(in_ifname, ifp_in->name, sizeof(in_ifname));
d62a17ae 2013 else
c35b7e6b 2014 strlcpy(in_ifname, "<iif?>", sizeof(in_ifname));
d62a17ae 2015
2016 if (src_or_group) {
2017 if (strcmp(src_or_group, src_str)
2018 && strcmp(src_or_group, grp_str))
2019 continue;
2020
2021 if (group && strcmp(group, grp_str))
2022 continue;
2023 }
2024
2025 if (uj) {
2026
2027 /* Find the group, create it if it doesn't exist */
2028 json_object_object_get_ex(json, grp_str, &json_group);
2029
2030 if (!json_group) {
2031 json_group = json_object_new_object();
2032 json_object_object_add(json, grp_str,
2033 json_group);
2034 }
2035
2036 /* Find the source nested under the group, create it if
2037 * it doesn't exist */
2038 json_object_object_get_ex(json_group, src_str,
2039 &json_source);
2040
2041 if (!json_source) {
2042 json_source = json_object_new_object();
2043 json_object_object_add(json_group, src_str,
2044 json_source);
2045 }
2046
2047 /* Find the inbound interface nested under the source,
2048 * create it if it doesn't exist */
2049 json_object_object_get_ex(json_source, in_ifname,
2050 &json_ifp_in);
2051
2052 if (!json_ifp_in) {
2053 json_ifp_in = json_object_new_object();
2054 json_object_object_add(json_source, in_ifname,
2055 json_ifp_in);
2056 json_object_int_add(json_source, "Installed",
2057 c_oil->installed);
2058 json_object_int_add(json_source, "RefCount",
2059 c_oil->oil_ref_count);
2060 json_object_int_add(json_source, "OilListSize",
2061 c_oil->oil_size);
2062 json_object_int_add(
2063 json_source, "OilRescan",
2064 c_oil->oil_inherited_rescan);
2065 json_object_int_add(json_source, "LastUsed",
2066 c_oil->cc.lastused);
2067 json_object_int_add(json_source, "PacketCount",
2068 c_oil->cc.pktcnt);
2069 json_object_int_add(json_source, "ByteCount",
2070 c_oil->cc.bytecnt);
2071 json_object_int_add(json_source,
2072 "WrongInterface",
2073 c_oil->cc.wrong_if);
2074 }
2075 } else {
ff415346
DS
2076 vty_out(vty, "%-9d %-15s %-15s %-16s ",
2077 c_oil->installed, src_str, grp_str, in_ifname);
d62a17ae 2078 }
2079
2080 for (oif_vif_index = 0; oif_vif_index < MAXVIFS;
2081 ++oif_vif_index) {
2082 struct interface *ifp_out;
2083 char oif_uptime[10];
2084 int ttl;
2085
2086 ttl = c_oil->oil.mfcc_ttls[oif_vif_index];
2087 if (ttl < 1)
2088 continue;
2089
7cfc7bcf 2090 ifp_out = pim_if_find_by_vif_index(pim, oif_vif_index);
d62a17ae 2091 pim_time_uptime(
2092 oif_uptime, sizeof(oif_uptime),
2093 now - c_oil->oif_creation[oif_vif_index]);
2094
2095 if (ifp_out)
c35b7e6b 2096 strlcpy(out_ifname, ifp_out->name, sizeof(out_ifname));
d62a17ae 2097 else
c35b7e6b 2098 strlcpy(out_ifname, "<oif?>", sizeof(out_ifname));
d62a17ae 2099
2100 if (uj) {
2101 json_ifp_out = json_object_new_object();
2102 json_object_string_add(json_ifp_out, "source",
2103 src_str);
2104 json_object_string_add(json_ifp_out, "group",
2105 grp_str);
2106 json_object_string_add(json_ifp_out,
2107 "inboundInterface",
2108 in_ifname);
2109 json_object_string_add(json_ifp_out,
2110 "outboundInterface",
2111 out_ifname);
2112 json_object_int_add(json_ifp_out, "installed",
2113 c_oil->installed);
2114
2115 json_object_object_add(json_ifp_in, out_ifname,
2116 json_ifp_out);
2117 } else {
2118 if (first_oif) {
2119 first_oif = 0;
ee31c9fd 2120 vty_out(vty, "%s(%c%c%c%c%c)", out_ifname,
d62a17ae 2121 (c_oil->oif_flags[oif_vif_index]
2122 & PIM_OIF_FLAG_PROTO_IGMP)
2123 ? 'I'
2124 : ' ',
2125 (c_oil->oif_flags[oif_vif_index]
2126 & PIM_OIF_FLAG_PROTO_PIM)
2127 ? 'J'
2128 : ' ',
ee31c9fd
AK
2129 (c_oil->oif_flags[oif_vif_index]
2130 & PIM_OIF_FLAG_PROTO_VXLAN)
2131 ? 'V'
2132 : ' ',
d62a17ae 2133 (c_oil->oif_flags[oif_vif_index]
2134 & PIM_OIF_FLAG_PROTO_SOURCE)
2135 ? 'S'
2136 : ' ',
2137 (c_oil->oif_flags[oif_vif_index]
2138 & PIM_OIF_FLAG_PROTO_STAR)
2139 ? '*'
2140 : ' ');
2141 } else
ee31c9fd 2142 vty_out(vty, ", %s(%c%c%c%c%c)",
d62a17ae 2143 out_ifname,
2144 (c_oil->oif_flags[oif_vif_index]
2145 & PIM_OIF_FLAG_PROTO_IGMP)
2146 ? 'I'
2147 : ' ',
2148 (c_oil->oif_flags[oif_vif_index]
2149 & PIM_OIF_FLAG_PROTO_PIM)
2150 ? 'J'
2151 : ' ',
ee31c9fd
AK
2152 (c_oil->oif_flags[oif_vif_index]
2153 & PIM_OIF_FLAG_PROTO_VXLAN)
2154 ? 'V'
2155 : ' ',
d62a17ae 2156 (c_oil->oif_flags[oif_vif_index]
2157 & PIM_OIF_FLAG_PROTO_SOURCE)
2158 ? 'S'
2159 : ' ',
2160 (c_oil->oif_flags[oif_vif_index]
2161 & PIM_OIF_FLAG_PROTO_STAR)
2162 ? '*'
2163 : ' ');
2164 }
2165 }
2166
2167 if (!uj)
2168 vty_out(vty, "\n");
2169 }
2170
2171
2172 if (uj) {
9d303b37
DL
2173 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2174 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 2175 json_object_free(json);
2176 } else {
2177 vty_out(vty, "\n");
2178 }
31a21c9c
DW
2179}
2180
64c86530 2181static void pim_show_neighbors(struct pim_instance *pim, struct vty *vty,
088f1098 2182 bool uj)
12e41d03 2183{
d62a17ae 2184 struct listnode *neighnode;
2185 struct interface *ifp;
2186 struct pim_interface *pim_ifp;
2187 struct pim_neighbor *neigh;
2188 time_t now;
2189 char uptime[10];
2190 char expire[10];
2191 char neigh_src_str[INET_ADDRSTRLEN];
2192 json_object *json = NULL;
2193 json_object *json_ifp_rows = NULL;
2194 json_object *json_row = NULL;
2195
2196 now = pim_time_monotonic_sec();
2197
2198 if (uj) {
2199 json = json_object_new_object();
2200 } else {
2201 vty_out(vty,
ff415346 2202 "Interface Neighbor Uptime Holdtime DR Pri\n");
d62a17ae 2203 }
2204
451fda4f 2205 FOR_ALL_INTERFACES (pim->vrf, ifp) {
d62a17ae 2206 pim_ifp = ifp->info;
2207
2208 if (!pim_ifp)
2209 continue;
2210
2211 if (pim_ifp->pim_sock_fd < 0)
2212 continue;
2213
2214 if (uj)
2215 json_ifp_rows = json_object_new_object();
2216
2217 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode,
2218 neigh)) {
2219 pim_inet4_dump("<src?>", neigh->source_addr,
2220 neigh_src_str, sizeof(neigh_src_str));
2221 pim_time_uptime(uptime, sizeof(uptime),
2222 now - neigh->creation);
2223 pim_time_timer_to_hhmmss(expire, sizeof(expire),
2224 neigh->t_expire_timer);
2225
2226 if (uj) {
2227 json_row = json_object_new_object();
2228 json_object_string_add(json_row, "interface",
2229 ifp->name);
2230 json_object_string_add(json_row, "neighbor",
2231 neigh_src_str);
2232 json_object_string_add(json_row, "upTime",
2233 uptime);
2234 json_object_string_add(json_row, "holdTime",
2235 expire);
2236 json_object_int_add(json_row, "holdTimeMax",
2237 neigh->holdtime);
2238 json_object_int_add(json_row, "drPriority",
2239 neigh->dr_priority);
2240 json_object_object_add(json_ifp_rows,
2241 neigh_src_str, json_row);
2242
2243 } else {
ff415346 2244 vty_out(vty, "%-16s %15s %8s %8s %6d\n",
d62a17ae 2245 ifp->name, neigh_src_str, uptime,
2246 expire, neigh->dr_priority);
2247 }
2248 }
2249
2250 if (uj) {
2251 json_object_object_add(json, ifp->name, json_ifp_rows);
2252 json_ifp_rows = NULL;
2253 }
2254 }
2255
2256 if (uj) {
9d303b37
DL
2257 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2258 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 2259 json_object_free(json);
2260 }
12e41d03
DL
2261}
2262
64c86530
DS
2263static void pim_show_neighbors_secondary(struct pim_instance *pim,
2264 struct vty *vty)
12e41d03 2265{
d62a17ae 2266 struct interface *ifp;
12e41d03 2267
d62a17ae 2268 vty_out(vty,
ff415346 2269 "Interface Address Neighbor Secondary \n");
12e41d03 2270
451fda4f 2271 FOR_ALL_INTERFACES (pim->vrf, ifp) {
d62a17ae 2272 struct pim_interface *pim_ifp;
2273 struct in_addr ifaddr;
2274 struct listnode *neighnode;
2275 struct pim_neighbor *neigh;
12e41d03 2276
d62a17ae 2277 pim_ifp = ifp->info;
12e41d03 2278
d62a17ae 2279 if (!pim_ifp)
2280 continue;
12e41d03 2281
d62a17ae 2282 if (pim_ifp->pim_sock_fd < 0)
2283 continue;
12e41d03 2284
d62a17ae 2285 ifaddr = pim_ifp->primary_address;
12e41d03 2286
d62a17ae 2287 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode,
2288 neigh)) {
2289 char neigh_src_str[INET_ADDRSTRLEN];
2290 struct listnode *prefix_node;
2291 struct prefix *p;
12e41d03 2292
d62a17ae 2293 if (!neigh->prefix_list)
2294 continue;
12e41d03 2295
d62a17ae 2296 pim_inet4_dump("<src?>", neigh->source_addr,
2297 neigh_src_str, sizeof(neigh_src_str));
12e41d03 2298
d62a17ae 2299 for (ALL_LIST_ELEMENTS_RO(neigh->prefix_list,
2300 prefix_node, p)) {
2301 char neigh_sec_str[PREFIX2STR_BUFFER];
12e41d03 2302
d62a17ae 2303 prefix2str(p, neigh_sec_str,
2304 sizeof(neigh_sec_str));
2305
ff415346 2306 vty_out(vty, "%-16s %-15s %-15s %-15s\n",
d62a17ae 2307 ifp->name, inet_ntoa(ifaddr),
2308 neigh_src_str, neigh_sec_str);
2309 }
2310 }
2311 }
12e41d03
DL
2312}
2313
d62a17ae 2314static void json_object_pim_upstream_add(json_object *json,
2315 struct pim_upstream *up)
9bf3c633 2316{
d62a17ae 2317 if (up->flags & PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED)
2318 json_object_boolean_true_add(json, "drJoinDesired");
9bf3c633 2319
d62a17ae 2320 if (up->flags & PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED)
2321 json_object_boolean_true_add(json, "drJoinDesiredUpdated");
9bf3c633 2322
d62a17ae 2323 if (up->flags & PIM_UPSTREAM_FLAG_MASK_FHR)
2324 json_object_boolean_true_add(json, "firstHopRouter");
9bf3c633 2325
d62a17ae 2326 if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_IGMP)
2327 json_object_boolean_true_add(json, "sourceIgmp");
9bf3c633 2328
d62a17ae 2329 if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_PIM)
2330 json_object_boolean_true_add(json, "sourcePim");
7667c556 2331
d62a17ae 2332 if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_STREAM)
2333 json_object_boolean_true_add(json, "sourceStream");
9bf3c633 2334
d62a17ae 2335 /* XXX: need to print ths flag in the plain text display as well */
2336 if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_MSDP)
2337 json_object_boolean_true_add(json, "sourceMsdp");
e134b399
DS
2338
2339 if (up->flags & PIM_UPSTREAM_FLAG_MASK_SEND_SG_RPT_PRUNE)
2340 json_object_boolean_true_add(json, "sendSGRptPrune");
2341
2342 if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_LHR)
2343 json_object_boolean_true_add(json, "lastHopRouter");
2344
2345 if (up->flags & PIM_UPSTREAM_FLAG_MASK_DISABLE_KAT_EXPIRY)
2346 json_object_boolean_true_add(json, "disableKATExpiry");
2347
2348 if (up->flags & PIM_UPSTREAM_FLAG_MASK_STATIC_IIF)
2349 json_object_boolean_true_add(json, "staticIncomingInterface");
2350
2351 if (up->flags & PIM_UPSTREAM_FLAG_MASK_ALLOW_IIF_IN_OIL)
2352 json_object_boolean_true_add(json,
2353 "allowIncomingInterfaceinOil");
2354
2355 if (up->flags & PIM_UPSTREAM_FLAG_MASK_NO_PIMREG_DATA)
2356 json_object_boolean_true_add(json, "noPimRegistrationData");
2357
2358 if (up->flags & PIM_UPSTREAM_FLAG_MASK_FORCE_PIMREG)
2359 json_object_boolean_true_add(json, "forcePimRegistration");
2360
2361 if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_ORIG)
2362 json_object_boolean_true_add(json, "sourceVxlanOrigination");
2363
2364 if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_TERM)
2365 json_object_boolean_true_add(json, "sourceVxlanTermination");
2366
2367 if (up->flags & PIM_UPSTREAM_FLAG_MASK_MLAG_VXLAN)
2368 json_object_boolean_true_add(json, "mlagVxlan");
2369
2370 if (up->flags & PIM_UPSTREAM_FLAG_MASK_MLAG_NON_DF)
2371 json_object_boolean_true_add(json,
2372 "mlagNonDesignatedForwarder");
755210ab 2373}
2374
2375static const char *
d62a17ae 2376pim_upstream_state2brief_str(enum pim_upstream_state join_state,
c35b7e6b 2377 char *state_str, size_t state_str_len)
d62a17ae 2378{
2379 switch (join_state) {
2380 case PIM_UPSTREAM_NOTJOINED:
c35b7e6b 2381 strlcpy(state_str, "NotJ", state_str_len);
d62a17ae 2382 break;
2383 case PIM_UPSTREAM_JOINED:
c35b7e6b 2384 strlcpy(state_str, "J", state_str_len);
d62a17ae 2385 break;
2386 default:
c35b7e6b 2387 strlcpy(state_str, "Unk", state_str_len);
d62a17ae 2388 }
2389 return state_str;
2390}
2391
2392static const char *pim_reg_state2brief_str(enum pim_reg_state reg_state,
c35b7e6b 2393 char *state_str, size_t state_str_len)
d62a17ae 2394{
2395 switch (reg_state) {
2396 case PIM_REG_NOINFO:
c35b7e6b 2397 strlcpy(state_str, "RegNI", state_str_len);
d62a17ae 2398 break;
2399 case PIM_REG_JOIN:
c35b7e6b 2400 strlcpy(state_str, "RegJ", state_str_len);
d62a17ae 2401 break;
2402 case PIM_REG_JOIN_PENDING:
2403 case PIM_REG_PRUNE:
c35b7e6b 2404 strlcpy(state_str, "RegP", state_str_len);
d62a17ae 2405 break;
2406 default:
c35b7e6b 2407 strlcpy(state_str, "Unk", state_str_len);
d62a17ae 2408 }
2409 return state_str;
755210ab 2410}
2411
64c86530 2412static void pim_show_upstream(struct pim_instance *pim, struct vty *vty,
dff5cedb 2413 struct prefix_sg *sg, bool uj)
12e41d03 2414{
d62a17ae 2415 struct listnode *upnode;
2416 struct pim_upstream *up;
2417 time_t now;
2418 json_object *json = NULL;
2419 json_object *json_group = NULL;
2420 json_object *json_row = NULL;
2421
2422 now = pim_time_monotonic_sec();
2423
2424 if (uj)
2425 json = json_object_new_object();
2426 else
2427 vty_out(vty,
ff415346 2428 "Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt\n");
d62a17ae 2429
c3169ac7 2430 for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, upnode, up)) {
d62a17ae 2431 char src_str[INET_ADDRSTRLEN];
2432 char grp_str[INET_ADDRSTRLEN];
2433 char uptime[10];
2434 char join_timer[10];
2435 char rs_timer[10];
2436 char ka_timer[10];
2437 char msdp_reg_timer[10];
2438 char state_str[PIM_REG_STATE_STR_LEN];
2439
dff5cedb
DS
2440 if (sg->grp.s_addr != 0 && sg->grp.s_addr != up->sg.grp.s_addr)
2441 continue;
2442 if (sg->src.s_addr != 0 && sg->src.s_addr != up->sg.src.s_addr)
2443 continue;
2444
d62a17ae 2445 pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
2446 pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
2447 pim_time_uptime(uptime, sizeof(uptime),
2448 now - up->state_transition);
2449 pim_time_timer_to_hhmmss(join_timer, sizeof(join_timer),
2450 up->t_join_timer);
2451
2452 /*
d8bed89d
SP
2453 * If the upstream is not dummy and it has a J/P timer for the
2454 * neighbor display that
d62a17ae 2455 */
d8bed89d 2456 if (!up->t_join_timer && up->rpf.source_nexthop.interface) {
d62a17ae 2457 struct pim_neighbor *nbr;
2458
2459 nbr = pim_neighbor_find(
2460 up->rpf.source_nexthop.interface,
2461 up->rpf.rpf_addr.u.prefix4);
2462 if (nbr)
2463 pim_time_timer_to_hhmmss(join_timer,
2464 sizeof(join_timer),
2465 nbr->jp_timer);
2466 }
2467
2468 pim_time_timer_to_hhmmss(rs_timer, sizeof(rs_timer),
2469 up->t_rs_timer);
2470 pim_time_timer_to_hhmmss(ka_timer, sizeof(ka_timer),
2471 up->t_ka_timer);
2472 pim_time_timer_to_hhmmss(msdp_reg_timer, sizeof(msdp_reg_timer),
2473 up->t_msdp_reg_timer);
2474
c35b7e6b 2475 pim_upstream_state2brief_str(up->join_state, state_str, sizeof(state_str));
d62a17ae 2476 if (up->reg_state != PIM_REG_NOINFO) {
2477 char tmp_str[PIM_REG_STATE_STR_LEN];
2478
2479 sprintf(state_str + strlen(state_str), ",%s",
c35b7e6b
QY
2480 pim_reg_state2brief_str(up->reg_state, tmp_str,
2481 sizeof(tmp_str)));
d62a17ae 2482 }
2483
2484 if (uj) {
2485 json_object_object_get_ex(json, grp_str, &json_group);
2486
2487 if (!json_group) {
2488 json_group = json_object_new_object();
2489 json_object_object_add(json, grp_str,
2490 json_group);
2491 }
2492
2493 json_row = json_object_new_object();
2494 json_object_pim_upstream_add(json_row, up);
2495 json_object_string_add(
d8bed89d
SP
2496 json_row, "inboundInterface",
2497 up->rpf.source_nexthop.interface
2498 ? up->rpf.source_nexthop.interface->name
2499 : "Unknown");
48f41fe8
DS
2500
2501 /*
2502 * The RPF address we use is slightly different
2503 * based upon what we are looking up.
2504 * If we have a S, list that unless
2505 * we are the FHR, else we just put
2506 * the RP as the rpfAddress
2507 */
996c9314
LB
2508 if (up->flags & PIM_UPSTREAM_FLAG_MASK_FHR
2509 || up->sg.src.s_addr == INADDR_ANY) {
48f41fe8
DS
2510 char rpf[PREFIX_STRLEN];
2511 struct pim_rpf *rpg;
2512
2513 rpg = RP(pim, up->sg.grp);
2514 pim_inet4_dump("<rpf?>",
996c9314
LB
2515 rpg->rpf_addr.u.prefix4, rpf,
2516 sizeof(rpf));
2517 json_object_string_add(json_row, "rpfAddress",
2518 rpf);
48f41fe8 2519 } else {
996c9314
LB
2520 json_object_string_add(json_row, "rpfAddress",
2521 src_str);
48f41fe8
DS
2522 }
2523
d62a17ae 2524 json_object_string_add(json_row, "source", src_str);
2525 json_object_string_add(json_row, "group", grp_str);
2526 json_object_string_add(json_row, "state", state_str);
2527 json_object_string_add(
2528 json_row, "joinState",
2529 pim_upstream_state2str(up->join_state));
2530 json_object_string_add(
2531 json_row, "regState",
c35b7e6b 2532 pim_reg_state2str(up->reg_state, state_str, sizeof(state_str)));
d62a17ae 2533 json_object_string_add(json_row, "upTime", uptime);
2534 json_object_string_add(json_row, "joinTimer",
2535 join_timer);
2536 json_object_string_add(json_row, "resetTimer",
2537 rs_timer);
2538 json_object_string_add(json_row, "keepaliveTimer",
2539 ka_timer);
2540 json_object_string_add(json_row, "msdpRegTimer",
2541 msdp_reg_timer);
2542 json_object_int_add(json_row, "refCount",
2543 up->ref_count);
2544 json_object_int_add(json_row, "sptBit", up->sptbit);
2545 json_object_object_add(json_group, src_str, json_row);
2546 } else {
2547 vty_out(vty,
ff415346 2548 "%-16s%-15s %-15s %-11s %-8s %-9s %-9s %-9s %6d\n",
d8bed89d
SP
2549 up->rpf.source_nexthop.interface
2550 ? up->rpf.source_nexthop.interface->name
2551 : "Unknown",
2552 src_str, grp_str, state_str, uptime, join_timer,
d62a17ae 2553 rs_timer, ka_timer, up->ref_count);
2554 }
2555 }
2556
2557 if (uj) {
9d303b37
DL
2558 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2559 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 2560 json_object_free(json);
2561 }
12e41d03
DL
2562}
2563
1a8a3da8
DS
2564static void pim_show_join_desired_helper(struct pim_instance *pim,
2565 struct vty *vty,
2566 struct pim_interface *pim_ifp,
2567 struct pim_ifchannel *ch,
088f1098 2568 json_object *json, bool uj)
12e41d03 2569{
1a8a3da8
DS
2570 struct pim_upstream *up = ch->upstream;
2571 json_object *json_group = NULL;
d62a17ae 2572 char src_str[INET_ADDRSTRLEN];
2573 char grp_str[INET_ADDRSTRLEN];
d62a17ae 2574 json_object *json_row = NULL;
2575
1a8a3da8
DS
2576 pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
2577 pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
d62a17ae 2578
1a8a3da8
DS
2579 if (uj) {
2580 json_object_object_get_ex(json, grp_str, &json_group);
d62a17ae 2581
1a8a3da8
DS
2582 if (!json_group) {
2583 json_group = json_object_new_object();
996c9314 2584 json_object_object_add(json, grp_str, json_group);
1a8a3da8 2585 }
d62a17ae 2586
1a8a3da8
DS
2587 json_row = json_object_new_object();
2588 json_object_pim_upstream_add(json_row, up);
2589 json_object_string_add(json_row, "interface",
2590 ch->interface->name);
2591 json_object_string_add(json_row, "source", src_str);
2592 json_object_string_add(json_row, "group", grp_str);
d62a17ae 2593
1a8a3da8 2594 if (pim_macro_ch_lost_assert(ch))
996c9314 2595 json_object_boolean_true_add(json_row, "lostAssert");
d62a17ae 2596
1a8a3da8
DS
2597 if (pim_macro_chisin_joins(ch))
2598 json_object_boolean_true_add(json_row, "joins");
d62a17ae 2599
1a8a3da8 2600 if (pim_macro_chisin_pim_include(ch))
996c9314 2601 json_object_boolean_true_add(json_row, "pimInclude");
d62a17ae 2602
1a8a3da8 2603 if (pim_upstream_evaluate_join_desired(pim, up))
996c9314
LB
2604 json_object_boolean_true_add(json_row,
2605 "evaluateJoinDesired");
d62a17ae 2606
1a8a3da8 2607 json_object_object_add(json_group, src_str, json_row);
d62a17ae 2608
1a8a3da8 2609 } else {
ff415346 2610 vty_out(vty, "%-16s %-15s %-15s %-10s %-5s %-10s %-11s %-6s\n",
1a8a3da8
DS
2611 ch->interface->name, src_str, grp_str,
2612 pim_macro_ch_lost_assert(ch) ? "yes" : "no",
2613 pim_macro_chisin_joins(ch) ? "yes" : "no",
2614 pim_macro_chisin_pim_include(ch) ? "yes" : "no",
996c9314
LB
2615 PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(up->flags)
2616 ? "yes"
2617 : "no",
2618 pim_upstream_evaluate_join_desired(pim, up) ? "yes"
2619 : "no");
1a8a3da8
DS
2620 }
2621}
d62a17ae 2622
1a8a3da8 2623static void pim_show_join_desired(struct pim_instance *pim, struct vty *vty,
088f1098 2624 bool uj)
1a8a3da8 2625{
1a8a3da8
DS
2626 struct pim_interface *pim_ifp;
2627 struct pim_ifchannel *ch;
2628 struct interface *ifp;
d62a17ae 2629
1a8a3da8 2630 json_object *json = NULL;
d62a17ae 2631
1a8a3da8
DS
2632 if (uj)
2633 json = json_object_new_object();
2634 else
2635 vty_out(vty,
ff415346 2636 "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD\n");
1a8a3da8
DS
2637
2638 /* scan per-interface (S,G) state */
451fda4f 2639 FOR_ALL_INTERFACES (pim->vrf, ifp) {
1a8a3da8
DS
2640 pim_ifp = ifp->info;
2641 if (!pim_ifp)
2642 continue;
2643
ad7b74c4 2644
a2addae8 2645 RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
1a8a3da8 2646 /* scan all interfaces */
996c9314 2647 pim_show_join_desired_helper(pim, vty, pim_ifp, ch,
1a8a3da8 2648 json, uj);
d62a17ae 2649 }
2650 }
2651
2652 if (uj) {
9d303b37
DL
2653 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2654 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 2655 json_object_free(json);
2656 }
12e41d03
DL
2657}
2658
64c86530 2659static void pim_show_upstream_rpf(struct pim_instance *pim, struct vty *vty,
088f1098 2660 bool uj)
12e41d03 2661{
d62a17ae 2662 struct listnode *upnode;
2663 struct pim_upstream *up;
2664 json_object *json = NULL;
2665 json_object *json_group = NULL;
2666 json_object *json_row = NULL;
2667
2668 if (uj)
2669 json = json_object_new_object();
2670 else
2671 vty_out(vty,
ff415346 2672 "Source Group RpfIface RibNextHop RpfAddress \n");
d62a17ae 2673
c68ba0d7 2674 for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, upnode, up)) {
d62a17ae 2675 char src_str[INET_ADDRSTRLEN];
2676 char grp_str[INET_ADDRSTRLEN];
2677 char rpf_nexthop_str[PREFIX_STRLEN];
2678 char rpf_addr_str[PREFIX_STRLEN];
2679 struct pim_rpf *rpf;
2680 const char *rpf_ifname;
2681
2682 rpf = &up->rpf;
2683
2684 pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
2685 pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
2686 pim_addr_dump("<nexthop?>",
2687 &rpf->source_nexthop.mrib_nexthop_addr,
2688 rpf_nexthop_str, sizeof(rpf_nexthop_str));
2689 pim_addr_dump("<rpf?>", &rpf->rpf_addr, rpf_addr_str,
2690 sizeof(rpf_addr_str));
2691
9d303b37 2692 rpf_ifname = rpf->source_nexthop.interface ? rpf->source_nexthop.interface->name : "<ifname?>";
d62a17ae 2693
2694 if (uj) {
2695 json_object_object_get_ex(json, grp_str, &json_group);
2696
2697 if (!json_group) {
2698 json_group = json_object_new_object();
2699 json_object_object_add(json, grp_str,
2700 json_group);
2701 }
2702
2703 json_row = json_object_new_object();
2704 json_object_pim_upstream_add(json_row, up);
2705 json_object_string_add(json_row, "source", src_str);
2706 json_object_string_add(json_row, "group", grp_str);
2707 json_object_string_add(json_row, "rpfInterface",
2708 rpf_ifname);
2709 json_object_string_add(json_row, "ribNexthop",
2710 rpf_nexthop_str);
2711 json_object_string_add(json_row, "rpfAddress",
2712 rpf_addr_str);
2713 json_object_object_add(json_group, src_str, json_row);
2714 } else {
ff415346 2715 vty_out(vty, "%-15s %-15s %-16s %-15s %-15s\n", src_str,
d62a17ae 2716 grp_str, rpf_ifname, rpf_nexthop_str,
2717 rpf_addr_str);
2718 }
2719 }
2720
2721 if (uj) {
9d303b37
DL
2722 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2723 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 2724 json_object_free(json);
2725 }
2726}
2727
da11e325
DS
2728static void show_rpf_refresh_stats(struct vty *vty, struct pim_instance *pim,
2729 time_t now, json_object *json)
d62a17ae 2730{
2731 char refresh_uptime[10];
2732
2733 pim_time_uptime_begin(refresh_uptime, sizeof(refresh_uptime), now,
bfc92019 2734 pim->rpf_cache_refresh_last);
d62a17ae 2735
2736 if (json) {
2737 json_object_int_add(json, "rpfCacheRefreshDelayMsecs",
da03883e 2738 router->rpf_cache_refresh_delay_msec);
d62a17ae 2739 json_object_int_add(
2740 json, "rpfCacheRefreshTimer",
da11e325 2741 pim_time_timer_remain_msec(pim->rpf_cache_refresher));
d62a17ae 2742 json_object_int_add(json, "rpfCacheRefreshRequests",
bfc92019 2743 pim->rpf_cache_refresh_requests);
d62a17ae 2744 json_object_int_add(json, "rpfCacheRefreshEvents",
bfc92019 2745 pim->rpf_cache_refresh_events);
d62a17ae 2746 json_object_string_add(json, "rpfCacheRefreshLast",
2747 refresh_uptime);
2748 json_object_int_add(json, "nexthopLookups",
bfc92019 2749 pim->nexthop_lookups);
d62a17ae 2750 json_object_int_add(json, "nexthopLookupsAvoided",
bfc92019 2751 pim->nexthop_lookups_avoided);
d62a17ae 2752 } else {
2753 vty_out(vty,
2754 "RPF Cache Refresh Delay: %ld msecs\n"
2755 "RPF Cache Refresh Timer: %ld msecs\n"
2756 "RPF Cache Refresh Requests: %lld\n"
2757 "RPF Cache Refresh Events: %lld\n"
2758 "RPF Cache Refresh Last: %s\n"
2759 "Nexthop Lookups: %lld\n"
2760 "Nexthop Lookups Avoided: %lld\n",
da03883e 2761 router->rpf_cache_refresh_delay_msec,
da11e325 2762 pim_time_timer_remain_msec(pim->rpf_cache_refresher),
bfc92019
DS
2763 (long long)pim->rpf_cache_refresh_requests,
2764 (long long)pim->rpf_cache_refresh_events,
2765 refresh_uptime, (long long)pim->nexthop_lookups,
2766 (long long)pim->nexthop_lookups_avoided);
d62a17ae 2767 }
12e41d03
DL
2768}
2769
64c86530 2770static void show_scan_oil_stats(struct pim_instance *pim, struct vty *vty,
c68ba0d7 2771 time_t now)
12e41d03 2772{
d62a17ae 2773 char uptime_scan_oil[10];
2774 char uptime_mroute_add[10];
2775 char uptime_mroute_del[10];
12e41d03 2776
d62a17ae 2777 pim_time_uptime_begin(uptime_scan_oil, sizeof(uptime_scan_oil), now,
bfc92019 2778 pim->scan_oil_last);
d62a17ae 2779 pim_time_uptime_begin(uptime_mroute_add, sizeof(uptime_mroute_add), now,
c68ba0d7 2780 pim->mroute_add_last);
d62a17ae 2781 pim_time_uptime_begin(uptime_mroute_del, sizeof(uptime_mroute_del), now,
c68ba0d7 2782 pim->mroute_del_last);
12e41d03 2783
d62a17ae 2784 vty_out(vty,
2785 "Scan OIL - Last: %s Events: %lld\n"
2786 "MFC Add - Last: %s Events: %lld\n"
2787 "MFC Del - Last: %s Events: %lld\n",
bfc92019 2788 uptime_scan_oil, (long long)pim->scan_oil_events,
c68ba0d7
DS
2789 uptime_mroute_add, (long long)pim->mroute_add_events,
2790 uptime_mroute_del, (long long)pim->mroute_del_events);
12e41d03
DL
2791}
2792
088f1098 2793static void pim_show_rpf(struct pim_instance *pim, struct vty *vty, bool uj)
12e41d03 2794{
d62a17ae 2795 struct listnode *up_node;
2796 struct pim_upstream *up;
2797 time_t now = pim_time_monotonic_sec();
2798 json_object *json = NULL;
2799 json_object *json_group = NULL;
2800 json_object *json_row = NULL;
2801
2802 if (uj) {
2803 json = json_object_new_object();
da11e325 2804 show_rpf_refresh_stats(vty, pim, now, json);
d62a17ae 2805 } else {
da11e325 2806 show_rpf_refresh_stats(vty, pim, now, json);
d62a17ae 2807 vty_out(vty, "\n");
2808 vty_out(vty,
ff415346 2809 "Source Group RpfIface RpfAddress RibNextHop Metric Pref\n");
d62a17ae 2810 }
cba44481 2811
c68ba0d7 2812 for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, up_node, up)) {
d62a17ae 2813 char src_str[INET_ADDRSTRLEN];
2814 char grp_str[INET_ADDRSTRLEN];
2815 char rpf_addr_str[PREFIX_STRLEN];
2816 char rib_nexthop_str[PREFIX_STRLEN];
2817 const char *rpf_ifname;
2818 struct pim_rpf *rpf = &up->rpf;
2819
2820 pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
2821 pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
2822 pim_addr_dump("<rpf?>", &rpf->rpf_addr, rpf_addr_str,
2823 sizeof(rpf_addr_str));
2824 pim_addr_dump("<nexthop?>",
2825 &rpf->source_nexthop.mrib_nexthop_addr,
2826 rib_nexthop_str, sizeof(rib_nexthop_str));
2827
9d303b37 2828 rpf_ifname = rpf->source_nexthop.interface ? rpf->source_nexthop.interface->name : "<ifname?>";
d62a17ae 2829
2830 if (uj) {
2831 json_object_object_get_ex(json, grp_str, &json_group);
2832
2833 if (!json_group) {
2834 json_group = json_object_new_object();
2835 json_object_object_add(json, grp_str,
2836 json_group);
2837 }
2838
2839 json_row = json_object_new_object();
2840 json_object_string_add(json_row, "source", src_str);
2841 json_object_string_add(json_row, "group", grp_str);
2842 json_object_string_add(json_row, "rpfInterface",
2843 rpf_ifname);
2844 json_object_string_add(json_row, "rpfAddress",
2845 rpf_addr_str);
2846 json_object_string_add(json_row, "ribNexthop",
2847 rib_nexthop_str);
2848 json_object_int_add(
2849 json_row, "routeMetric",
2850 rpf->source_nexthop.mrib_route_metric);
2851 json_object_int_add(
2852 json_row, "routePreference",
2853 rpf->source_nexthop.mrib_metric_preference);
2854 json_object_object_add(json_group, src_str, json_row);
2855
2856 } else {
ff415346 2857 vty_out(vty, "%-15s %-15s %-16s %-15s %-15s %6d %4d\n",
d62a17ae 2858 src_str, grp_str, rpf_ifname, rpf_addr_str,
2859 rib_nexthop_str,
2860 rpf->source_nexthop.mrib_route_metric,
2861 rpf->source_nexthop.mrib_metric_preference);
2862 }
2863 }
2864
2865 if (uj) {
9d303b37
DL
2866 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2867 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 2868 json_object_free(json);
2869 }
cba44481
CS
2870}
2871
c68ba0d7
DS
2872struct pnc_cache_walk_data {
2873 struct vty *vty;
2874 struct pim_instance *pim;
2875};
2876
e3b78da8 2877static int pim_print_pnc_cache_walkcb(struct hash_bucket *bucket, void *arg)
12e41d03 2878{
e3b78da8 2879 struct pim_nexthop_cache *pnc = bucket->data;
c68ba0d7
DS
2880 struct pnc_cache_walk_data *cwd = arg;
2881 struct vty *vty = cwd->vty;
2882 struct pim_instance *pim = cwd->pim;
d62a17ae 2883 struct nexthop *nh_node = NULL;
2884 ifindex_t first_ifindex;
2885 struct interface *ifp = NULL;
2886
d62a17ae 2887 for (nh_node = pnc->nexthop; nh_node; nh_node = nh_node->next) {
2888 first_ifindex = nh_node->ifindex;
c68ba0d7 2889 ifp = if_lookup_by_index(first_ifindex, pim->vrf_id);
d62a17ae 2890
2891 vty_out(vty, "%-15s ", inet_ntoa(pnc->rpf.rpf_addr.u.prefix4));
ff415346 2892 vty_out(vty, "%-16s ", ifp ? ifp->name : "NULL");
d62a17ae 2893 vty_out(vty, "%s ", inet_ntoa(nh_node->gate.ipv4));
2894 vty_out(vty, "\n");
2895 }
2896 return CMD_SUCCESS;
2897}
2898
64c86530 2899static void pim_show_nexthop(struct pim_instance *pim, struct vty *vty)
d62a17ae 2900{
c68ba0d7 2901 struct pnc_cache_walk_data cwd;
d62a17ae 2902
c68ba0d7
DS
2903 cwd.vty = vty;
2904 cwd.pim = pim;
2905 vty_out(vty, "Number of registered addresses: %lu\n",
2906 pim->rpf_hash->count);
ff415346
DS
2907 vty_out(vty, "Address Interface Nexthop\n");
2908 vty_out(vty, "---------------------------------------------\n");
12e41d03 2909
c68ba0d7 2910 hash_walk(pim->rpf_hash, pim_print_pnc_cache_walkcb, &cwd);
d62a17ae 2911}
2912
0d1a4e24 2913/* Display the bsm database details */
2914static void pim_show_bsm_db(struct pim_instance *pim, struct vty *vty, bool uj)
2915{
2916 struct listnode *bsmnode;
2917 int count = 0;
2918 int fragment = 1;
2919 struct bsm_info *bsm;
2920 json_object *json = NULL;
2921 json_object *json_group = NULL;
2922 json_object *json_row = NULL;
2923
2924 count = pim->global_scope.bsm_list->count;
2925
2926 if (uj) {
2927 json = json_object_new_object();
2928 json_object_int_add(json, "Number of the fragments", count);
2929 } else {
2930 vty_out(vty, "Scope Zone: Global\n");
2931 vty_out(vty, "Number of the fragments: %d\n", count);
2932 vty_out(vty, "\n");
2933 }
2934
2935 for (ALL_LIST_ELEMENTS_RO(pim->global_scope.bsm_list, bsmnode, bsm)) {
2936 char grp_str[INET_ADDRSTRLEN];
2937 char rp_str[INET_ADDRSTRLEN];
2938 char bsr_str[INET_ADDRSTRLEN];
2939 struct bsmmsg_grpinfo *group;
2940 struct bsmmsg_rpinfo *rpaddr;
2941 struct prefix grp;
2942 struct bsm_hdr *hdr;
2943 uint32_t offset = 0;
2944 uint8_t *buf;
2945 uint32_t len = 0;
2946 uint32_t frag_rp_cnt = 0;
2947
2948 buf = bsm->bsm;
2949 len = bsm->size;
2950
2951 /* skip pim header */
2952 buf += PIM_MSG_HEADER_LEN;
2953 len -= PIM_MSG_HEADER_LEN;
2954
2955 hdr = (struct bsm_hdr *)buf;
2956
2957 /* BSM starts with bsr header */
2958 buf += sizeof(struct bsm_hdr);
2959 len -= sizeof(struct bsm_hdr);
2960
2961 pim_inet4_dump("<BSR Address?>", hdr->bsr_addr.addr, bsr_str,
2962 sizeof(bsr_str));
2963
2964
2965 if (uj) {
2966 json_object_string_add(json, "BSR address", bsr_str);
2967 json_object_int_add(json, "BSR priority",
2968 hdr->bsr_prio);
2969 json_object_int_add(json, "Hashmask Length",
2970 hdr->hm_len);
2971 json_object_int_add(json, "Fragment Tag",
2972 ntohs(hdr->frag_tag));
2973 } else {
2974 vty_out(vty, "BSM Fragment : %d\n", fragment);
2975 vty_out(vty, "------------------\n");
2976 vty_out(vty, "%-15s %-15s %-15s %-15s\n", "BSR-Address",
2977 "BSR-Priority", "Hashmask-len", "Fragment-Tag");
2978 vty_out(vty, "%-15s %-15d %-15d %-15d\n", bsr_str,
2979 hdr->bsr_prio, hdr->hm_len,
2980 ntohs(hdr->frag_tag));
2981 }
2982
2983 vty_out(vty, "\n");
2984
2985 while (offset < len) {
2986 group = (struct bsmmsg_grpinfo *)buf;
2987
2988 if (group->group.family == PIM_MSG_ADDRESS_FAMILY_IPV4)
2989 grp.family = AF_INET;
2990
2991 grp.prefixlen = group->group.mask;
2992 grp.u.prefix4.s_addr = group->group.addr.s_addr;
2993
2994 prefix2str(&grp, grp_str, sizeof(grp_str));
2995
2996 buf += sizeof(struct bsmmsg_grpinfo);
2997 offset += sizeof(struct bsmmsg_grpinfo);
2998
2999 if (uj) {
3000 json_object_object_get_ex(json, grp_str,
3001 &json_group);
3002 if (!json_group) {
3003 json_group = json_object_new_object();
3004 json_object_int_add(json_group,
3005 "Rp Count",
3006 group->rp_count);
3007 json_object_int_add(
3008 json_group, "Fragment Rp count",
3009 group->frag_rp_count);
3010 json_object_object_add(json, grp_str,
3011 json_group);
3012 }
3013 } else {
3014 vty_out(vty, "Group : %s\n", grp_str);
3015 vty_out(vty, "-------------------\n");
3016 vty_out(vty, "Rp Count:%d\n", group->rp_count);
3017 vty_out(vty, "Fragment Rp Count : %d\n",
3018 group->frag_rp_count);
3019 }
3020
3021 frag_rp_cnt = group->frag_rp_count;
3022
3023 if (!frag_rp_cnt)
3024 continue;
3025
3026 if (!uj)
3027 vty_out(vty,
3028 "RpAddress HoldTime Priority\n");
3029
3030 while (frag_rp_cnt--) {
3031 rpaddr = (struct bsmmsg_rpinfo *)buf;
3032
3033 buf += sizeof(struct bsmmsg_rpinfo);
3034 offset += sizeof(struct bsmmsg_rpinfo);
3035
3036 pim_inet4_dump("<Rp addr?>",
3037 rpaddr->rpaddr.addr, rp_str,
3038 sizeof(rp_str));
3039
3040 if (uj) {
3041 json_row = json_object_new_object();
3042 json_object_string_add(
3043 json_row, "Rp Address", rp_str);
3044 json_object_int_add(
3045 json_row, "Rp HoldTime",
3046 ntohs(rpaddr->rp_holdtime));
3047 json_object_int_add(json_row,
3048 "Rp Priority",
3049 rpaddr->rp_pri);
3050 json_object_object_add(
3051 json_group, rp_str, json_row);
3052 } else {
3053 vty_out(vty, "%-15s %-12d %d\n", rp_str,
3054 ntohs(rpaddr->rp_holdtime),
3055 rpaddr->rp_pri);
3056 }
3057 }
3058 vty_out(vty, "\n");
3059 }
3060
3061 fragment++;
3062 }
3063
3064 if (uj) {
3065 vty_out(vty, "%s\n", json_object_to_json_string_ext(
3066 json, JSON_C_TO_STRING_PRETTY));
3067 json_object_free(json);
3068 }
3069}
3070
321295c1 3071/*Display the group-rp mappings */
3072static void pim_show_group_rp_mappings_info(struct pim_instance *pim,
3073 struct vty *vty, bool uj)
3074{
3075 struct bsgrp_node *bsgrp;
3076 struct listnode *rpnode;
3077 struct bsm_rpinfo *bsm_rp;
3078 struct route_node *rn;
3079 char bsr_str[INET_ADDRSTRLEN];
3080 json_object *json = NULL;
3081 json_object *json_group = NULL;
3082 json_object *json_row = NULL;
3083
3084 if (pim->global_scope.current_bsr.s_addr == INADDR_ANY)
3085 strncpy(bsr_str, "0.0.0.0", sizeof(bsr_str));
3086
3087 else
3088 pim_inet4_dump("<bsr?>", pim->global_scope.current_bsr, bsr_str,
3089 sizeof(bsr_str));
3090
3091 if (uj) {
3092 json = json_object_new_object();
3093 json_object_string_add(json, "BSR Address", bsr_str);
3094 } else {
3095 vty_out(vty, "BSR Address %s\n", bsr_str);
3096 }
3097
3098 for (rn = route_top(pim->global_scope.bsrp_table); rn;
3099 rn = route_next(rn)) {
3100 bsgrp = (struct bsgrp_node *)rn->info;
3101
3102 if (!bsgrp)
3103 continue;
3104
3105 char grp_str[INET_ADDRSTRLEN];
3106
3107 prefix2str(&bsgrp->group, grp_str, sizeof(grp_str));
3108
3109 if (uj) {
3110 json_object_object_get_ex(json, grp_str, &json_group);
3111 if (!json_group) {
3112 json_group = json_object_new_object();
3113 json_object_object_add(json, grp_str,
3114 json_group);
3115 }
3116 } else {
3117 vty_out(vty, "Group Address %s\n", grp_str);
3118 vty_out(vty, "--------------------------\n");
3119 vty_out(vty, "%-15s %-15s %-15s %-15s\n", "Rp Address",
3120 "priority", "Holdtime", "Hash");
3121
3122 vty_out(vty, "(ACTIVE)\n");
3123 }
3124
3125 if (bsgrp->bsrp_list) {
3126 for (ALL_LIST_ELEMENTS_RO(bsgrp->bsrp_list, rpnode,
3127 bsm_rp)) {
3128 char rp_str[INET_ADDRSTRLEN];
3129
3130 pim_inet4_dump("<Rp Address?>",
3131 bsm_rp->rp_address, rp_str,
3132 sizeof(rp_str));
3133
3134 if (uj) {
3135 json_row = json_object_new_object();
3136 json_object_string_add(
3137 json_row, "Rp Address", rp_str);
3138 json_object_int_add(
3139 json_row, "Rp HoldTime",
3140 bsm_rp->rp_holdtime);
3141 json_object_int_add(json_row,
3142 "Rp Priority",
3143 bsm_rp->rp_prio);
3144 json_object_int_add(json_row,
3145 "Hash Val",
3146 bsm_rp->hash);
3147 json_object_object_add(
3148 json_group, rp_str, json_row);
3149
3150 } else {
3151 vty_out(vty,
3152 "%-15s %-15u %-15u %-15u\n",
3153 rp_str, bsm_rp->rp_prio,
3154 bsm_rp->rp_holdtime,
3155 bsm_rp->hash);
3156 }
3157 }
3158 if (!bsgrp->bsrp_list->count && !uj)
3159 vty_out(vty, "Active List is empty.\n");
3160 }
3161
3162 if (uj) {
3163 json_object_int_add(json_group, "Pending RP count",
3164 bsgrp->pend_rp_cnt);
3165 } else {
3166 vty_out(vty, "(PENDING)\n");
3167 vty_out(vty, "Pending RP count :%d\n",
3168 bsgrp->pend_rp_cnt);
3169 if (bsgrp->pend_rp_cnt)
3170 vty_out(vty, "%-15s %-15s %-15s %-15s\n",
3171 "Rp Address", "priority", "Holdtime",
3172 "Hash");
3173 }
3174
3175 if (bsgrp->partial_bsrp_list) {
3176 for (ALL_LIST_ELEMENTS_RO(bsgrp->partial_bsrp_list,
3177 rpnode, bsm_rp)) {
3178 char rp_str[INET_ADDRSTRLEN];
3179
3180 pim_inet4_dump("<Rp Addr?>", bsm_rp->rp_address,
3181 rp_str, sizeof(rp_str));
3182
3183 if (uj) {
3184 json_row = json_object_new_object();
3185 json_object_string_add(
3186 json_row, "Rp Address", rp_str);
3187 json_object_int_add(
3188 json_row, "Rp HoldTime",
3189 bsm_rp->rp_holdtime);
3190 json_object_int_add(json_row,
3191 "Rp Priority",
3192 bsm_rp->rp_prio);
3193 json_object_int_add(json_row,
3194 "Hash Val",
3195 bsm_rp->hash);
3196 json_object_object_add(
3197 json_group, rp_str, json_row);
3198 } else {
3199 vty_out(vty,
3200 "%-15s %-15u %-15u %-15u\n",
3201 rp_str, bsm_rp->rp_prio,
3202 bsm_rp->rp_holdtime,
3203 bsm_rp->hash);
3204 }
3205 }
3206 if (!bsgrp->partial_bsrp_list->count && !uj)
3207 vty_out(vty, "Partial List is empty\n");
3208 }
3209
3210 if (!uj)
3211 vty_out(vty, "\n");
3212 }
3213
3214 if (uj) {
3215 vty_out(vty, "%s\n", json_object_to_json_string_ext(
3216 json, JSON_C_TO_STRING_PRETTY));
3217 json_object_free(json);
3218 }
3219}
3220
415f6350 3221/* pim statistics - just adding only bsm related now.
3222 * We can continue to add all pim related stats here.
3223 */
3224static void pim_show_statistics(struct pim_instance *pim, struct vty *vty,
3225 const char *ifname, bool uj)
3226{
3227 json_object *json = NULL;
3228 struct interface *ifp;
3229
3230 if (uj) {
3231 json = json_object_new_object();
3232 json_object_int_add(json, "Number of Received BSMs",
3233 pim->bsm_rcvd);
3234 json_object_int_add(json, "Number of Forwared BSMs",
3235 pim->bsm_sent);
3236 json_object_int_add(json, "Number of Dropped BSMs",
3237 pim->bsm_dropped);
3238 } else {
3239 vty_out(vty, "BSM Statistics :\n");
3240 vty_out(vty, "----------------\n");
3241 vty_out(vty, "Number of Received BSMs : %ld\n", pim->bsm_rcvd);
3242 vty_out(vty, "Number of Forwared BSMs : %ld\n", pim->bsm_sent);
3243 vty_out(vty, "Number of Dropped BSMs : %ld\n",
3244 pim->bsm_dropped);
3245 }
3246
3247 vty_out(vty, "\n");
3248
3249 /* scan interfaces */
3250 FOR_ALL_INTERFACES (pim->vrf, ifp) {
3251 struct pim_interface *pim_ifp = ifp->info;
3252
3253 if (ifname && strcmp(ifname, ifp->name))
3254 continue;
3255
3256 if (!pim_ifp)
3257 continue;
3258
3259 if (!uj) {
3260 vty_out(vty, "Interface : %s\n", ifp->name);
3261 vty_out(vty, "-------------------\n");
3262 vty_out(vty,
3263 "Number of BSMs dropped due to config miss : %u\n",
3264 pim_ifp->pim_ifstat_bsm_cfg_miss);
3265 vty_out(vty, "Number of unicast BSMs dropped : %u\n",
3266 pim_ifp->pim_ifstat_ucast_bsm_cfg_miss);
3267 vty_out(vty,
3268 "Number of BSMs dropped due to invalid scope zone : %u\n",
3269 pim_ifp->pim_ifstat_bsm_invalid_sz);
3270 } else {
3271
3272 json_object *json_row = NULL;
3273
3274 json_row = json_object_new_object();
3275
3276 json_object_string_add(json_row, "If Name", ifp->name);
3277 json_object_int_add(
3278 json_row,
3279 "Number of BSMs dropped due to config miss",
3280 pim_ifp->pim_ifstat_bsm_cfg_miss);
3281 json_object_int_add(
3282 json_row, "Number of unicast BSMs dropped",
3283 pim_ifp->pim_ifstat_ucast_bsm_cfg_miss);
3284 json_object_int_add(json_row,
3285 "Number of BSMs dropped due to invalid scope zone",
3286 pim_ifp->pim_ifstat_bsm_invalid_sz);
3287 json_object_object_add(json, ifp->name, json_row);
3288 }
3289 vty_out(vty, "\n");
3290 }
3291
3292 if (uj) {
3293 vty_out(vty, "%s\n", json_object_to_json_string_ext(
3294 json, JSON_C_TO_STRING_PRETTY));
3295 json_object_free(json);
3296 }
3297}
3298
3299static void clear_pim_statistics(struct pim_instance *pim)
3300{
3301 struct interface *ifp;
3302
3303 pim->bsm_rcvd = 0;
3304 pim->bsm_sent = 0;
3305 pim->bsm_dropped = 0;
3306
3307 /* scan interfaces */
3308 FOR_ALL_INTERFACES (pim->vrf, ifp) {
3309 struct pim_interface *pim_ifp = ifp->info;
3310
3311 if (!pim_ifp)
3312 continue;
3313
3314 pim_ifp->pim_ifstat_bsm_cfg_miss = 0;
3315 pim_ifp->pim_ifstat_ucast_bsm_cfg_miss = 0;
3316 pim_ifp->pim_ifstat_bsm_invalid_sz = 0;
3317 }
3318}
3319
088f1098 3320static void igmp_show_groups(struct pim_instance *pim, struct vty *vty, bool uj)
d62a17ae 3321{
d62a17ae 3322 struct interface *ifp;
3323 time_t now;
3324 json_object *json = NULL;
3325 json_object *json_iface = NULL;
3326 json_object *json_row = NULL;
3327
3328 now = pim_time_monotonic_sec();
3329
3330 if (uj)
3331 json = json_object_new_object();
3332 else
3333 vty_out(vty,
ff415346 3334 "Interface Address Group Mode Timer Srcs V Uptime \n");
d62a17ae 3335
3336 /* scan interfaces */
451fda4f 3337 FOR_ALL_INTERFACES (pim->vrf, ifp) {
d62a17ae 3338 struct pim_interface *pim_ifp = ifp->info;
3339 struct listnode *sock_node;
3340 struct igmp_sock *igmp;
3341
3342 if (!pim_ifp)
3343 continue;
3344
3345 /* scan igmp sockets */
3346 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node,
3347 igmp)) {
3348 char ifaddr_str[INET_ADDRSTRLEN];
3349 struct listnode *grpnode;
3350 struct igmp_group *grp;
3351
3352 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str,
3353 sizeof(ifaddr_str));
3354
3355 /* scan igmp groups */
3356 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list,
3357 grpnode, grp)) {
3358 char group_str[INET_ADDRSTRLEN];
3359 char hhmmss[10];
3360 char uptime[10];
3361
3362 pim_inet4_dump("<group?>", grp->group_addr,
3363 group_str, sizeof(group_str));
3364 pim_time_timer_to_hhmmss(hhmmss, sizeof(hhmmss),
3365 grp->t_group_timer);
3366 pim_time_uptime(uptime, sizeof(uptime),
3367 now - grp->group_creation);
3368
3369 if (uj) {
3370 json_object_object_get_ex(
3371 json, ifp->name, &json_iface);
3372
3373 if (!json_iface) {
3374 json_iface =
3375 json_object_new_object();
3376 json_object_pim_ifp_add(
3377 json_iface, ifp);
3378 json_object_object_add(
3379 json, ifp->name,
3380 json_iface);
3381 }
3382
3383 json_row = json_object_new_object();
3384 json_object_string_add(
3385 json_row, "source", ifaddr_str);
3386 json_object_string_add(
3387 json_row, "group", group_str);
3388
3389 if (grp->igmp_version == 3)
3390 json_object_string_add(
3391 json_row, "mode",
3392 grp->group_filtermode_isexcl
3393 ? "EXCLUDE"
3394 : "INCLUDE");
3395
3396 json_object_string_add(json_row,
3397 "timer", hhmmss);
3398 json_object_int_add(
3399 json_row, "sourcesCount",
3400 grp->group_source_list
3401 ? listcount(
3402 grp->group_source_list)
3403 : 0);
3404 json_object_int_add(json_row, "version",
3405 grp->igmp_version);
3406 json_object_string_add(
3407 json_row, "uptime", uptime);
3408 json_object_object_add(json_iface,
3409 group_str,
3410 json_row);
3411
3412 } else {
3413 vty_out(vty,
ff415346 3414 "%-16s %-15s %-15s %4s %8s %4d %d %8s\n",
d62a17ae 3415 ifp->name, ifaddr_str,
3416 group_str,
3417 grp->igmp_version == 3
3418 ? (grp->group_filtermode_isexcl
3419 ? "EXCL"
3420 : "INCL")
3421 : "----",
3422 hhmmss,
3423 grp->group_source_list
3424 ? listcount(
3425 grp->group_source_list)
3426 : 0,
3427 grp->igmp_version, uptime);
3428 }
3429 } /* scan igmp groups */
3430 } /* scan igmp sockets */
3431 } /* scan interfaces */
3432
3433 if (uj) {
9d303b37
DL
3434 vty_out(vty, "%s\n", json_object_to_json_string_ext(
3435 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 3436 json_object_free(json);
3437 }
12e41d03
DL
3438}
3439
64c86530
DS
3440static void igmp_show_group_retransmission(struct pim_instance *pim,
3441 struct vty *vty)
12e41d03 3442{
d62a17ae 3443 struct interface *ifp;
3444
3445 vty_out(vty,
ff415346 3446 "Interface Address Group RetTimer Counter RetSrcs\n");
d62a17ae 3447
3448 /* scan interfaces */
451fda4f 3449 FOR_ALL_INTERFACES (pim->vrf, ifp) {
d62a17ae 3450 struct pim_interface *pim_ifp = ifp->info;
3451 struct listnode *sock_node;
3452 struct igmp_sock *igmp;
3453
3454 if (!pim_ifp)
3455 continue;
3456
3457 /* scan igmp sockets */
3458 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node,
3459 igmp)) {
3460 char ifaddr_str[INET_ADDRSTRLEN];
3461 struct listnode *grpnode;
3462 struct igmp_group *grp;
3463
3464 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str,
3465 sizeof(ifaddr_str));
3466
3467 /* scan igmp groups */
3468 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list,
3469 grpnode, grp)) {
3470 char group_str[INET_ADDRSTRLEN];
3471 char grp_retr_mmss[10];
3472 struct listnode *src_node;
3473 struct igmp_source *src;
3474 int grp_retr_sources = 0;
3475
3476 pim_inet4_dump("<group?>", grp->group_addr,
3477 group_str, sizeof(group_str));
3478 pim_time_timer_to_mmss(
3479 grp_retr_mmss, sizeof(grp_retr_mmss),
3480 grp->t_group_query_retransmit_timer);
3481
3482
3483 /* count group sources with retransmission state
3484 */
3485 for (ALL_LIST_ELEMENTS_RO(
3486 grp->group_source_list, src_node,
3487 src)) {
3488 if (src->source_query_retransmit_count
3489 > 0) {
3490 ++grp_retr_sources;
3491 }
3492 }
3493
ff415346 3494 vty_out(vty, "%-16s %-15s %-15s %-8s %7d %7d\n",
d62a17ae 3495 ifp->name, ifaddr_str, group_str,
3496 grp_retr_mmss,
3497 grp->group_specific_query_retransmit_count,
3498 grp_retr_sources);
3499
3500 } /* scan igmp groups */
3501 } /* scan igmp sockets */
3502 } /* scan interfaces */
12e41d03
DL
3503}
3504
64c86530 3505static void igmp_show_sources(struct pim_instance *pim, struct vty *vty)
12e41d03 3506{
d62a17ae 3507 struct interface *ifp;
3508 time_t now;
3509
3510 now = pim_time_monotonic_sec();
3511
3512 vty_out(vty,
ff415346 3513 "Interface Address Group Source Timer Fwd Uptime \n");
d62a17ae 3514
3515 /* scan interfaces */
451fda4f 3516 FOR_ALL_INTERFACES (pim->vrf, ifp) {
d62a17ae 3517 struct pim_interface *pim_ifp = ifp->info;
3518 struct listnode *sock_node;
3519 struct igmp_sock *igmp;
3520
3521 if (!pim_ifp)
3522 continue;
3523
3524 /* scan igmp sockets */
3525 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node,
3526 igmp)) {
3527 char ifaddr_str[INET_ADDRSTRLEN];
3528 struct listnode *grpnode;
3529 struct igmp_group *grp;
3530
3531 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str,
3532 sizeof(ifaddr_str));
3533
3534 /* scan igmp groups */
3535 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list,
3536 grpnode, grp)) {
3537 char group_str[INET_ADDRSTRLEN];
3538 struct listnode *srcnode;
3539 struct igmp_source *src;
3540
3541 pim_inet4_dump("<group?>", grp->group_addr,
3542 group_str, sizeof(group_str));
3543
3544 /* scan group sources */
3545 for (ALL_LIST_ELEMENTS_RO(
3546 grp->group_source_list, srcnode,
3547 src)) {
3548 char source_str[INET_ADDRSTRLEN];
3549 char mmss[10];
3550 char uptime[10];
3551
3552 pim_inet4_dump(
3553 "<source?>", src->source_addr,
3554 source_str, sizeof(source_str));
3555
3556 pim_time_timer_to_mmss(
3557 mmss, sizeof(mmss),
3558 src->t_source_timer);
3559
3560 pim_time_uptime(
3561 uptime, sizeof(uptime),
3562 now - src->source_creation);
3563
3564 vty_out(vty,
ff415346 3565 "%-16s %-15s %-15s %-15s %5s %3s %8s\n",
d62a17ae 3566 ifp->name, ifaddr_str,
3567 group_str, source_str, mmss,
3568 IGMP_SOURCE_TEST_FORWARDING(
3569 src->source_flags)
3570 ? "Y"
3571 : "N",
3572 uptime);
3573
3574 } /* scan group sources */
3575 } /* scan igmp groups */
3576 } /* scan igmp sockets */
3577 } /* scan interfaces */
12e41d03
DL
3578}
3579
64c86530
DS
3580static void igmp_show_source_retransmission(struct pim_instance *pim,
3581 struct vty *vty)
12e41d03 3582{
d62a17ae 3583 struct interface *ifp;
3584
3585 vty_out(vty,
ff415346 3586 "Interface Address Group Source Counter\n");
d62a17ae 3587
3588 /* scan interfaces */
451fda4f 3589 FOR_ALL_INTERFACES (pim->vrf, ifp) {
d62a17ae 3590 struct pim_interface *pim_ifp = ifp->info;
3591 struct listnode *sock_node;
3592 struct igmp_sock *igmp;
3593
3594 if (!pim_ifp)
3595 continue;
3596
3597 /* scan igmp sockets */
3598 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node,
3599 igmp)) {
3600 char ifaddr_str[INET_ADDRSTRLEN];
3601 struct listnode *grpnode;
3602 struct igmp_group *grp;
3603
3604 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str,
3605 sizeof(ifaddr_str));
3606
3607 /* scan igmp groups */
3608 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list,
3609 grpnode, grp)) {
3610 char group_str[INET_ADDRSTRLEN];
3611 struct listnode *srcnode;
3612 struct igmp_source *src;
3613
3614 pim_inet4_dump("<group?>", grp->group_addr,
3615 group_str, sizeof(group_str));
3616
3617 /* scan group sources */
3618 for (ALL_LIST_ELEMENTS_RO(
3619 grp->group_source_list, srcnode,
3620 src)) {
3621 char source_str[INET_ADDRSTRLEN];
3622
3623 pim_inet4_dump(
3624 "<source?>", src->source_addr,
3625 source_str, sizeof(source_str));
3626
3627 vty_out(vty,
ff415346 3628 "%-16s %-15s %-15s %-15s %7d\n",
d62a17ae 3629 ifp->name, ifaddr_str,
3630 group_str, source_str,
3631 src->source_query_retransmit_count);
3632
3633 } /* scan group sources */
3634 } /* scan igmp groups */
3635 } /* scan igmp sockets */
3636 } /* scan interfaces */
12e41d03
DL
3637}
3638
256392eb 3639static void pim_show_bsr(struct pim_instance *pim,
3640 struct vty *vty,
3641 bool uj)
3642{
3643 char uptime[10];
3644 char last_bsm_seen[10];
3645 time_t now;
3646 char bsr_state[20];
3647 char bsr_str[PREFIX_STRLEN];
3648 json_object *json = NULL;
3649
3650 vty_out(vty, "PIMv2 Bootstrap information\n");
3651
3652 if (pim->global_scope.current_bsr.s_addr == INADDR_ANY) {
3653 strncpy(bsr_str, "0.0.0.0", sizeof(bsr_str));
3654 pim_time_uptime(uptime, sizeof(uptime),
3655 pim->global_scope.current_bsr_first_ts);
3656 pim_time_uptime(last_bsm_seen, sizeof(last_bsm_seen),
3657 pim->global_scope.current_bsr_last_ts);
3658 }
3659
3660 else {
3661 pim_inet4_dump("<bsr?>", pim->global_scope.current_bsr,
3662 bsr_str, sizeof(bsr_str));
3663 now = pim_time_monotonic_sec();
3664 pim_time_uptime(uptime, sizeof(uptime),
3665 (now - pim->global_scope.current_bsr_first_ts));
3666 pim_time_uptime(last_bsm_seen, sizeof(last_bsm_seen),
3667 now - pim->global_scope.current_bsr_last_ts);
3668 }
3669
3670 switch (pim->global_scope.state) {
3671 case NO_INFO:
3672 strncpy(bsr_state, "NO_INFO", sizeof(bsr_state));
3673 break;
3674 case ACCEPT_ANY:
3675 strncpy(bsr_state, "ACCEPT_ANY", sizeof(bsr_state));
3676 break;
3677 case ACCEPT_PREFERRED:
3678 strncpy(bsr_state, "ACCEPT_PREFERRED", sizeof(bsr_state));
3679 break;
3680 default:
3681 strncpy(bsr_state, "", sizeof(bsr_state));
3682 }
3683
3684 if (uj) {
3685 json = json_object_new_object();
3686 json_object_string_add(json, "bsr", bsr_str);
3687 json_object_int_add(json, "priority",
3688 pim->global_scope.current_bsr_prio);
3689 json_object_int_add(json, "fragment_tag",
3690 pim->global_scope.bsm_frag_tag);
3691 json_object_string_add(json, "state", bsr_state);
3692 json_object_string_add(json, "upTime", uptime);
3693 json_object_string_add(json, "last_bsm_seen", last_bsm_seen);
3694 }
3695
3696 else {
3697 vty_out(vty, "Current preferred BSR address: %s\n", bsr_str);
3698 vty_out(vty,
3699 "Priority Fragment-Tag State UpTime\n");
3700 vty_out(vty, " %-12d %-12d %-13s %7s\n",
3701 pim->global_scope.current_bsr_prio,
3702 pim->global_scope.bsm_frag_tag,
3703 bsr_state,
3704 uptime);
3705 vty_out(vty, "Last BSM seen: %s\n", last_bsm_seen);
3706 }
3707
3708 if (uj) {
3709 vty_out(vty, "%s\n", json_object_to_json_string_ext(
3710 json, JSON_C_TO_STRING_PRETTY));
3711 json_object_free(json);
3712 }
3713}
3714
c68ba0d7 3715static void clear_igmp_interfaces(struct pim_instance *pim)
12e41d03 3716{
d62a17ae 3717 struct interface *ifp;
12e41d03 3718
451fda4f 3719 FOR_ALL_INTERFACES (pim->vrf, ifp)
d62a17ae 3720 pim_if_addr_del_all_igmp(ifp);
12e41d03 3721
451fda4f 3722 FOR_ALL_INTERFACES (pim->vrf, ifp)
d62a17ae 3723 pim_if_addr_add_all(ifp);
12e41d03
DL
3724}
3725
c68ba0d7 3726static void clear_pim_interfaces(struct pim_instance *pim)
12e41d03 3727{
d62a17ae 3728 struct interface *ifp;
12e41d03 3729
451fda4f 3730 FOR_ALL_INTERFACES (pim->vrf, ifp) {
d62a17ae 3731 if (ifp->info) {
3732 pim_neighbor_delete_all(ifp, "interface cleared");
3733 }
3734 }
12e41d03
DL
3735}
3736
c68ba0d7 3737static void clear_interfaces(struct pim_instance *pim)
12e41d03 3738{
c68ba0d7
DS
3739 clear_igmp_interfaces(pim);
3740 clear_pim_interfaces(pim);
12e41d03
DL
3741}
3742
996c9314
LB
3743#define PIM_GET_PIM_INTERFACE(pim_ifp, ifp) \
3744 pim_ifp = ifp->info; \
3745 if (!pim_ifp) { \
3746 vty_out(vty, \
21b3e44e 3747 "%% Enable PIM and/or IGMP on this interface first\n"); \
996c9314 3748 return CMD_WARNING_CONFIG_FAILED; \
21b3e44e
QY
3749 }
3750
12e41d03
DL
3751DEFUN (clear_ip_interfaces,
3752 clear_ip_interfaces_cmd,
20a7e5fd 3753 "clear ip interfaces [vrf NAME]",
12e41d03
DL
3754 CLEAR_STR
3755 IP_STR
c68ba0d7
DS
3756 "Reset interfaces\n"
3757 VRF_CMD_HELP_STR)
12e41d03 3758{
c68ba0d7
DS
3759 int idx = 2;
3760 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3761
3762 if (!vrf)
3763 return CMD_WARNING;
3764
3765 clear_interfaces(vrf->info);
12e41d03 3766
d62a17ae 3767 return CMD_SUCCESS;
12e41d03
DL
3768}
3769
3770DEFUN (clear_ip_igmp_interfaces,
3771 clear_ip_igmp_interfaces_cmd,
20a7e5fd 3772 "clear ip igmp [vrf NAME] interfaces",
12e41d03
DL
3773 CLEAR_STR
3774 IP_STR
3775 CLEAR_IP_IGMP_STR
c68ba0d7 3776 VRF_CMD_HELP_STR
12e41d03
DL
3777 "Reset IGMP interfaces\n")
3778{
c68ba0d7
DS
3779 int idx = 2;
3780 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3781
3782 if (!vrf)
3783 return CMD_WARNING;
3784
3785 clear_igmp_interfaces(vrf->info);
12e41d03 3786
d62a17ae 3787 return CMD_SUCCESS;
12e41d03
DL
3788}
3789
415f6350 3790DEFUN (clear_ip_pim_statistics,
3791 clear_ip_pim_statistics_cmd,
3792 "clear ip pim statistics [vrf NAME]",
3793 CLEAR_STR
3794 IP_STR
3795 CLEAR_IP_PIM_STR
3796 VRF_CMD_HELP_STR
3797 "Reset PIM statistics\n")
3798{
3799 int idx = 2;
3800 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3801
3802 if (!vrf)
3803 return CMD_WARNING;
3804
3805 clear_pim_statistics(vrf->info);
3806 return CMD_SUCCESS;
3807}
3808
c68ba0d7 3809static void mroute_add_all(struct pim_instance *pim)
12e41d03 3810{
d62a17ae 3811 struct listnode *node;
3812 struct channel_oil *c_oil;
3813
c68ba0d7 3814 for (ALL_LIST_ELEMENTS_RO(pim->channel_oil_list, node, c_oil)) {
d62a17ae 3815 if (pim_mroute_add(c_oil, __PRETTY_FUNCTION__)) {
3816 /* just log warning */
3817 char source_str[INET_ADDRSTRLEN];
3818 char group_str[INET_ADDRSTRLEN];
3819 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin,
3820 source_str, sizeof(source_str));
3821 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp,
3822 group_str, sizeof(group_str));
3823 zlog_warn("%s %s: (S,G)=(%s,%s) failure writing MFC",
3824 __FILE__, __PRETTY_FUNCTION__, source_str,
3825 group_str);
3826 }
3827 }
12e41d03
DL
3828}
3829
c68ba0d7 3830static void mroute_del_all(struct pim_instance *pim)
12e41d03 3831{
d62a17ae 3832 struct listnode *node;
3833 struct channel_oil *c_oil;
3834
c68ba0d7 3835 for (ALL_LIST_ELEMENTS_RO(pim->channel_oil_list, node, c_oil)) {
d62a17ae 3836 if (pim_mroute_del(c_oil, __PRETTY_FUNCTION__)) {
3837 /* just log warning */
3838 char source_str[INET_ADDRSTRLEN];
3839 char group_str[INET_ADDRSTRLEN];
3840 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin,
3841 source_str, sizeof(source_str));
3842 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp,
3843 group_str, sizeof(group_str));
3844 zlog_warn("%s %s: (S,G)=(%s,%s) failure clearing MFC",
3845 __FILE__, __PRETTY_FUNCTION__, source_str,
3846 group_str);
3847 }
3848 }
12e41d03
DL
3849}
3850
3851DEFUN (clear_ip_mroute,
3852 clear_ip_mroute_cmd,
20a7e5fd 3853 "clear ip mroute [vrf NAME]",
12e41d03
DL
3854 CLEAR_STR
3855 IP_STR
c68ba0d7
DS
3856 "Reset multicast routes\n"
3857 VRF_CMD_HELP_STR)
12e41d03 3858{
c68ba0d7
DS
3859 int idx = 2;
3860 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3861
3862 if (!vrf)
3863 return CMD_WARNING;
3864
3865 mroute_del_all(vrf->info);
3866 mroute_add_all(vrf->info);
12e41d03 3867
d62a17ae 3868 return CMD_SUCCESS;
12e41d03
DL
3869}
3870
3871DEFUN (clear_ip_pim_interfaces,
3872 clear_ip_pim_interfaces_cmd,
20a7e5fd 3873 "clear ip pim [vrf NAME] interfaces",
12e41d03
DL
3874 CLEAR_STR
3875 IP_STR
3876 CLEAR_IP_PIM_STR
c68ba0d7 3877 VRF_CMD_HELP_STR
12e41d03
DL
3878 "Reset PIM interfaces\n")
3879{
c68ba0d7
DS
3880 int idx = 2;
3881 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3882
3883 if (!vrf)
3884 return CMD_WARNING;
3885
3886 clear_pim_interfaces(vrf->info);
12e41d03 3887
d62a17ae 3888 return CMD_SUCCESS;
12e41d03
DL
3889}
3890
39438188
CS
3891DEFUN (clear_ip_pim_interface_traffic,
3892 clear_ip_pim_interface_traffic_cmd,
20a7e5fd 3893 "clear ip pim [vrf NAME] interface traffic",
39438188
CS
3894 "Reset functions\n"
3895 "IP information\n"
3896 "PIM clear commands\n"
c68ba0d7 3897 VRF_CMD_HELP_STR
39438188
CS
3898 "Reset PIM interfaces\n"
3899 "Reset Protocol Packet counters\n")
3900{
c68ba0d7
DS
3901 int idx = 2;
3902 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
d62a17ae 3903 struct interface *ifp = NULL;
3904 struct pim_interface *pim_ifp = NULL;
3905
c68ba0d7
DS
3906 if (!vrf)
3907 return CMD_WARNING;
3908
451fda4f 3909 FOR_ALL_INTERFACES (vrf, ifp) {
d62a17ae 3910 pim_ifp = ifp->info;
3911
3912 if (!pim_ifp)
3913 continue;
3914
3915 pim_ifp->pim_ifstat_hello_recv = 0;
3916 pim_ifp->pim_ifstat_hello_sent = 0;
3917 pim_ifp->pim_ifstat_join_recv = 0;
3918 pim_ifp->pim_ifstat_join_send = 0;
3919 pim_ifp->pim_ifstat_prune_recv = 0;
3920 pim_ifp->pim_ifstat_prune_send = 0;
3921 pim_ifp->pim_ifstat_reg_recv = 0;
3922 pim_ifp->pim_ifstat_reg_send = 0;
3923 pim_ifp->pim_ifstat_reg_stop_recv = 0;
3924 pim_ifp->pim_ifstat_reg_stop_send = 0;
3925 pim_ifp->pim_ifstat_assert_recv = 0;
3926 pim_ifp->pim_ifstat_assert_send = 0;
5164ad1e 3927 pim_ifp->pim_ifstat_bsm_rx = 0;
3928 pim_ifp->pim_ifstat_bsm_tx = 0;
d62a17ae 3929 }
39438188 3930
d62a17ae 3931 return CMD_SUCCESS;
39438188
CS
3932}
3933
12e41d03
DL
3934DEFUN (clear_ip_pim_oil,
3935 clear_ip_pim_oil_cmd,
20a7e5fd 3936 "clear ip pim [vrf NAME] oil",
12e41d03
DL
3937 CLEAR_STR
3938 IP_STR
3939 CLEAR_IP_PIM_STR
c68ba0d7 3940 VRF_CMD_HELP_STR
12e41d03
DL
3941 "Rescan PIM OIL (output interface list)\n")
3942{
c68ba0d7
DS
3943 int idx = 2;
3944 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3945
3946 if (!vrf)
3947 return CMD_WARNING;
3948
3949 pim_scan_oil(vrf->info);
12e41d03 3950
d62a17ae 3951 return CMD_SUCCESS;
12e41d03
DL
3952}
3953
3954DEFUN (show_ip_igmp_interface,
3955 show_ip_igmp_interface_cmd,
20a7e5fd 3956 "show ip igmp [vrf NAME] interface [detail|WORD] [json]",
12e41d03
DL
3957 SHOW_STR
3958 IP_STR
3959 IGMP_STR
c68ba0d7 3960 VRF_CMD_HELP_STR
a268493f 3961 "IGMP interface information\n"
9b91bb50 3962 "Detailed output\n"
a268493f 3963 "interface name\n"
f5da2cc2 3964 JSON_STR)
12e41d03 3965{
c68ba0d7
DS
3966 int idx = 2;
3967 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9f049418 3968 bool uj = use_json(argc, argv);
c68ba0d7
DS
3969
3970 if (!vrf)
3971 return CMD_WARNING;
72e81cf4 3972
d62a17ae 3973 if (argv_find(argv, argc, "detail", &idx)
3974 || argv_find(argv, argc, "WORD", &idx))
64c86530 3975 igmp_show_interfaces_single(vrf->info, vty, argv[idx]->arg, uj);
d62a17ae 3976 else
64c86530 3977 igmp_show_interfaces(vrf->info, vty, uj);
12e41d03 3978
d62a17ae 3979 return CMD_SUCCESS;
12e41d03
DL
3980}
3981
a25de56b
DS
3982DEFUN (show_ip_igmp_interface_vrf_all,
3983 show_ip_igmp_interface_vrf_all_cmd,
3984 "show ip igmp vrf all interface [detail|WORD] [json]",
3985 SHOW_STR
3986 IP_STR
3987 IGMP_STR
3988 VRF_CMD_HELP_STR
3989 "IGMP interface information\n"
3990 "Detailed output\n"
3991 "interface name\n"
f5da2cc2 3992 JSON_STR)
a25de56b
DS
3993{
3994 int idx = 2;
9f049418 3995 bool uj = use_json(argc, argv);
a25de56b
DS
3996 struct vrf *vrf;
3997 bool first = true;
3998
3999 if (uj)
4000 vty_out(vty, "{ ");
a2addae8 4001 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
a25de56b
DS
4002 if (uj) {
4003 if (!first)
4004 vty_out(vty, ", ");
4005 vty_out(vty, " \"%s\": ", vrf->name);
4006 first = false;
4007 } else
4008 vty_out(vty, "VRF: %s\n", vrf->name);
4009 if (argv_find(argv, argc, "detail", &idx)
4010 || argv_find(argv, argc, "WORD", &idx))
4011 igmp_show_interfaces_single(vrf->info, vty,
4012 argv[idx]->arg, uj);
4013 else
4014 igmp_show_interfaces(vrf->info, vty, uj);
4015 }
4016 if (uj)
4017 vty_out(vty, "}\n");
4018
4019 return CMD_SUCCESS;
4020}
4021
12e41d03
DL
4022DEFUN (show_ip_igmp_join,
4023 show_ip_igmp_join_cmd,
20a7e5fd 4024 "show ip igmp [vrf NAME] join",
12e41d03
DL
4025 SHOW_STR
4026 IP_STR
4027 IGMP_STR
c68ba0d7 4028 VRF_CMD_HELP_STR
12e41d03
DL
4029 "IGMP static join information\n")
4030{
c68ba0d7
DS
4031 int idx = 2;
4032 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4033
4034 if (!vrf)
4035 return CMD_WARNING;
4036
64c86530 4037 igmp_show_interface_join(vrf->info, vty);
12e41d03 4038
d62a17ae 4039 return CMD_SUCCESS;
12e41d03
DL
4040}
4041
a25de56b
DS
4042DEFUN (show_ip_igmp_join_vrf_all,
4043 show_ip_igmp_join_vrf_all_cmd,
4044 "show ip igmp vrf all join",
4045 SHOW_STR
4046 IP_STR
4047 IGMP_STR
4048 VRF_CMD_HELP_STR
4049 "IGMP static join information\n")
4050{
9f049418 4051 bool uj = use_json(argc, argv);
a25de56b
DS
4052 struct vrf *vrf;
4053 bool first = true;
4054
4055 if (uj)
4056 vty_out(vty, "{ ");
a2addae8 4057 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
a25de56b
DS
4058 if (uj) {
4059 if (!first)
4060 vty_out(vty, ", ");
4061 vty_out(vty, " \"%s\": ", vrf->name);
4062 first = false;
4063 } else
4064 vty_out(vty, "VRF: %s\n", vrf->name);
4065 igmp_show_interface_join(vrf->info, vty);
4066 }
4067 if (uj)
4068 vty_out(vty, "}\n");
4069
4070 return CMD_SUCCESS;
4071}
4072
12e41d03
DL
4073DEFUN (show_ip_igmp_groups,
4074 show_ip_igmp_groups_cmd,
20a7e5fd 4075 "show ip igmp [vrf NAME] groups [json]",
12e41d03
DL
4076 SHOW_STR
4077 IP_STR
4078 IGMP_STR
c68ba0d7 4079 VRF_CMD_HELP_STR
9b91bb50 4080 IGMP_GROUP_STR
f5da2cc2 4081 JSON_STR)
12e41d03 4082{
c68ba0d7
DS
4083 int idx = 2;
4084 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9f049418 4085 bool uj = use_json(argc, argv);
c68ba0d7
DS
4086
4087 if (!vrf)
4088 return CMD_WARNING;
4089
64c86530 4090 igmp_show_groups(vrf->info, vty, uj);
12e41d03 4091
d62a17ae 4092 return CMD_SUCCESS;
12e41d03
DL
4093}
4094
a25de56b
DS
4095DEFUN (show_ip_igmp_groups_vrf_all,
4096 show_ip_igmp_groups_vrf_all_cmd,
4097 "show ip igmp vrf all groups [json]",
4098 SHOW_STR
4099 IP_STR
4100 IGMP_STR
4101 VRF_CMD_HELP_STR
4102 IGMP_GROUP_STR
f5da2cc2 4103 JSON_STR)
a25de56b 4104{
9f049418 4105 bool uj = use_json(argc, argv);
a25de56b
DS
4106 struct vrf *vrf;
4107 bool first = true;
4108
4109 if (uj)
4110 vty_out(vty, "{ ");
a2addae8 4111 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
a25de56b
DS
4112 if (uj) {
4113 if (!first)
4114 vty_out(vty, ", ");
4115 vty_out(vty, " \"%s\": ", vrf->name);
4116 first = false;
4117 } else
4118 vty_out(vty, "VRF: %s\n", vrf->name);
4119 igmp_show_groups(vrf->info, vty, uj);
4120 }
4121 if (uj)
4122 vty_out(vty, "}\n");
4123
4124 return CMD_SUCCESS;
4125}
4126
12e41d03
DL
4127DEFUN (show_ip_igmp_groups_retransmissions,
4128 show_ip_igmp_groups_retransmissions_cmd,
20a7e5fd 4129 "show ip igmp [vrf NAME] groups retransmissions",
12e41d03
DL
4130 SHOW_STR
4131 IP_STR
4132 IGMP_STR
c68ba0d7 4133 VRF_CMD_HELP_STR
12e41d03
DL
4134 IGMP_GROUP_STR
4135 "IGMP group retransmissions\n")
4136{
c68ba0d7
DS
4137 int idx = 2;
4138 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4139
4140 if (!vrf)
4141 return CMD_WARNING;
4142
64c86530 4143 igmp_show_group_retransmission(vrf->info, vty);
12e41d03 4144
d62a17ae 4145 return CMD_SUCCESS;
12e41d03
DL
4146}
4147
12e41d03
DL
4148DEFUN (show_ip_igmp_sources,
4149 show_ip_igmp_sources_cmd,
20a7e5fd 4150 "show ip igmp [vrf NAME] sources",
12e41d03
DL
4151 SHOW_STR
4152 IP_STR
4153 IGMP_STR
c68ba0d7 4154 VRF_CMD_HELP_STR
12e41d03
DL
4155 IGMP_SOURCE_STR)
4156{
c68ba0d7
DS
4157 int idx = 2;
4158 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4159
4160 if (!vrf)
4161 return CMD_WARNING;
4162
64c86530 4163 igmp_show_sources(vrf->info, vty);
12e41d03 4164
d62a17ae 4165 return CMD_SUCCESS;
12e41d03
DL
4166}
4167
4168DEFUN (show_ip_igmp_sources_retransmissions,
4169 show_ip_igmp_sources_retransmissions_cmd,
20a7e5fd 4170 "show ip igmp [vrf NAME] sources retransmissions",
12e41d03
DL
4171 SHOW_STR
4172 IP_STR
4173 IGMP_STR
c68ba0d7 4174 VRF_CMD_HELP_STR
12e41d03
DL
4175 IGMP_SOURCE_STR
4176 "IGMP source retransmissions\n")
4177{
c68ba0d7
DS
4178 int idx = 2;
4179 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4180
4181 if (!vrf)
4182 return CMD_WARNING;
4183
64c86530 4184 igmp_show_source_retransmission(vrf->info, vty);
12e41d03 4185
d62a17ae 4186 return CMD_SUCCESS;
12e41d03
DL
4187}
4188
21313cbf
MS
4189DEFUN (show_ip_igmp_statistics,
4190 show_ip_igmp_statistics_cmd,
4191 "show ip igmp [vrf NAME] statistics [interface WORD] [json]",
4192 SHOW_STR
4193 IP_STR
4194 IGMP_STR
4195 VRF_CMD_HELP_STR
4196 "IGMP statistics\n"
4197 "interface\n"
4198 "IGMP interface\n"
4199 JSON_STR)
4200{
4201 int idx = 2;
4202 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9f049418 4203 bool uj = use_json(argc, argv);
21313cbf
MS
4204
4205 if (!vrf)
4206 return CMD_WARNING;
4207
4208 if (argv_find(argv, argc, "WORD", &idx))
4209 igmp_show_statistics(vrf->info, vty, argv[idx]->arg, uj);
4210 else
4211 igmp_show_statistics(vrf->info, vty, NULL, uj);
4212
4213 return CMD_SUCCESS;
4214}
4215
12e41d03
DL
4216DEFUN (show_ip_pim_assert,
4217 show_ip_pim_assert_cmd,
20a7e5fd 4218 "show ip pim [vrf NAME] assert",
12e41d03
DL
4219 SHOW_STR
4220 IP_STR
4221 PIM_STR
c68ba0d7 4222 VRF_CMD_HELP_STR
12e41d03
DL
4223 "PIM interface assert\n")
4224{
c68ba0d7
DS
4225 int idx = 2;
4226 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4227
4228 if (!vrf)
4229 return CMD_WARNING;
4230
64c86530 4231 pim_show_assert(vrf->info, vty);
12e41d03 4232
d62a17ae 4233 return CMD_SUCCESS;
12e41d03
DL
4234}
4235
4236DEFUN (show_ip_pim_assert_internal,
4237 show_ip_pim_assert_internal_cmd,
20a7e5fd 4238 "show ip pim [vrf NAME] assert-internal",
12e41d03
DL
4239 SHOW_STR
4240 IP_STR
4241 PIM_STR
c68ba0d7 4242 VRF_CMD_HELP_STR
12e41d03
DL
4243 "PIM interface internal assert state\n")
4244{
c68ba0d7
DS
4245 int idx = 2;
4246 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4247
4248 if (!vrf)
4249 return CMD_WARNING;
4250
64c86530 4251 pim_show_assert_internal(vrf->info, vty);
12e41d03 4252
d62a17ae 4253 return CMD_SUCCESS;
12e41d03
DL
4254}
4255
4256DEFUN (show_ip_pim_assert_metric,
4257 show_ip_pim_assert_metric_cmd,
20a7e5fd 4258 "show ip pim [vrf NAME] assert-metric",
12e41d03
DL
4259 SHOW_STR
4260 IP_STR
4261 PIM_STR
c68ba0d7 4262 VRF_CMD_HELP_STR
12e41d03
DL
4263 "PIM interface assert metric\n")
4264{
c68ba0d7
DS
4265 int idx = 2;
4266 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4267
4268 if (!vrf)
4269 return CMD_WARNING;
4270
64c86530 4271 pim_show_assert_metric(vrf->info, vty);
12e41d03 4272
d62a17ae 4273 return CMD_SUCCESS;
12e41d03
DL
4274}
4275
4276DEFUN (show_ip_pim_assert_winner_metric,
4277 show_ip_pim_assert_winner_metric_cmd,
20a7e5fd 4278 "show ip pim [vrf NAME] assert-winner-metric",
12e41d03
DL
4279 SHOW_STR
4280 IP_STR
4281 PIM_STR
c68ba0d7 4282 VRF_CMD_HELP_STR
12e41d03
DL
4283 "PIM interface assert winner metric\n")
4284{
c68ba0d7
DS
4285 int idx = 2;
4286 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4287
4288 if (!vrf)
4289 return CMD_WARNING;
4290
64c86530 4291 pim_show_assert_winner_metric(vrf->info, vty);
12e41d03 4292
d62a17ae 4293 return CMD_SUCCESS;
12e41d03
DL
4294}
4295
12e41d03
DL
4296DEFUN (show_ip_pim_interface,
4297 show_ip_pim_interface_cmd,
20a7e5fd 4298 "show ip pim [vrf NAME] interface [detail|WORD] [json]",
12e41d03
DL
4299 SHOW_STR
4300 IP_STR
4301 PIM_STR
c68ba0d7 4302 VRF_CMD_HELP_STR
a268493f 4303 "PIM interface information\n"
9b91bb50 4304 "Detailed output\n"
a268493f 4305 "interface name\n"
f5da2cc2 4306 JSON_STR)
12e41d03 4307{
c68ba0d7
DS
4308 int idx = 2;
4309 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9f049418 4310 bool uj = use_json(argc, argv);
c68ba0d7
DS
4311
4312 if (!vrf)
4313 return CMD_WARNING;
72e81cf4 4314
d62a17ae 4315 if (argv_find(argv, argc, "WORD", &idx)
4316 || argv_find(argv, argc, "detail", &idx))
64c86530 4317 pim_show_interfaces_single(vrf->info, vty, argv[idx]->arg, uj);
d62a17ae 4318 else
64c86530 4319 pim_show_interfaces(vrf->info, vty, uj);
12e41d03 4320
d62a17ae 4321 return CMD_SUCCESS;
12e41d03
DL
4322}
4323
a25de56b
DS
4324DEFUN (show_ip_pim_interface_vrf_all,
4325 show_ip_pim_interface_vrf_all_cmd,
4326 "show ip pim vrf all interface [detail|WORD] [json]",
4327 SHOW_STR
4328 IP_STR
4329 PIM_STR
4330 VRF_CMD_HELP_STR
4331 "PIM interface information\n"
4332 "Detailed output\n"
4333 "interface name\n"
f5da2cc2 4334 JSON_STR)
a25de56b
DS
4335{
4336 int idx = 6;
9f049418 4337 bool uj = use_json(argc, argv);
a25de56b
DS
4338 struct vrf *vrf;
4339 bool first = true;
4340
4341 if (uj)
4342 vty_out(vty, "{ ");
a2addae8 4343 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
a25de56b
DS
4344 if (uj) {
4345 if (!first)
4346 vty_out(vty, ", ");
4347 vty_out(vty, " \"%s\": ", vrf->name);
4348 first = false;
4349 } else
4350 vty_out(vty, "VRF: %s\n", vrf->name);
4351 if (argv_find(argv, argc, "WORD", &idx)
4352 || argv_find(argv, argc, "detail", &idx))
4353 pim_show_interfaces_single(vrf->info, vty,
4354 argv[idx]->arg, uj);
4355 else
4356 pim_show_interfaces(vrf->info, vty, uj);
4357 }
4358 if (uj)
4359 vty_out(vty, "}\n");
4360
4361 return CMD_SUCCESS;
4362}
4363
6de45bcc 4364DEFPY (show_ip_pim_join,
12e41d03 4365 show_ip_pim_join_cmd,
6de45bcc 4366 "show ip pim [vrf NAME] join [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
12e41d03
DL
4367 SHOW_STR
4368 IP_STR
4369 PIM_STR
c68ba0d7 4370 VRF_CMD_HELP_STR
a957a05b 4371 "PIM interface join information\n"
6de45bcc
DS
4372 "The Source or Group\n"
4373 "The Group\n"
a957a05b 4374 JSON_STR)
12e41d03 4375{
6de45bcc
DS
4376 struct prefix_sg sg = {0};
4377 struct vrf *v;
4378 bool uj = !!json;
4379 struct pim_instance *pim;
c68ba0d7 4380
6de45bcc
DS
4381 v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
4382
4383 if (!v) {
4384 vty_out(vty, "%% Vrf specified: %s does not exist\n", vrf);
c68ba0d7 4385 return CMD_WARNING;
6de45bcc
DS
4386 }
4387 pim = pim_get_pim_instance(v->vrf_id);
4388
4389 if (!pim) {
4390 vty_out(vty, "%% Unable to find pim instance\n");
4391 return CMD_WARNING;
4392 }
4393
4394 if (s_or_g.s_addr != 0) {
4395 if (g.s_addr != 0) {
4396 sg.src = s_or_g;
4397 sg.grp = g;
4398 } else
4399 sg.grp = s_or_g;
4400 }
c68ba0d7 4401
6de45bcc 4402 pim_show_join(pim, vty, &sg, uj);
12e41d03 4403
d62a17ae 4404 return CMD_SUCCESS;
12e41d03
DL
4405}
4406
a25de56b
DS
4407DEFUN (show_ip_pim_join_vrf_all,
4408 show_ip_pim_join_vrf_all_cmd,
4409 "show ip pim vrf all join [json]",
4410 SHOW_STR
4411 IP_STR
4412 PIM_STR
4413 VRF_CMD_HELP_STR
4414 "PIM interface join information\n"
4415 JSON_STR)
4416{
6de45bcc 4417 struct prefix_sg sg = {0};
9f049418 4418 bool uj = use_json(argc, argv);
a25de56b
DS
4419 struct vrf *vrf;
4420 bool first = true;
4421
4422 if (uj)
4423 vty_out(vty, "{ ");
a2addae8 4424 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
a25de56b
DS
4425 if (uj) {
4426 if (!first)
4427 vty_out(vty, ", ");
4428 vty_out(vty, " \"%s\": ", vrf->name);
4429 first = false;
4430 } else
4431 vty_out(vty, "VRF: %s\n", vrf->name);
6de45bcc 4432 pim_show_join(vrf->info, vty, &sg, uj);
a25de56b
DS
4433 }
4434 if (uj)
4435 vty_out(vty, "}\n");
4436
4437 return CMD_WARNING;
4438}
4439
12e41d03
DL
4440DEFUN (show_ip_pim_local_membership,
4441 show_ip_pim_local_membership_cmd,
20a7e5fd 4442 "show ip pim [vrf NAME] local-membership [json]",
12e41d03
DL
4443 SHOW_STR
4444 IP_STR
4445 PIM_STR
c68ba0d7 4446 VRF_CMD_HELP_STR
a957a05b
DS
4447 "PIM interface local-membership\n"
4448 JSON_STR)
12e41d03 4449{
c68ba0d7
DS
4450 int idx = 2;
4451 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9f049418 4452 bool uj = use_json(argc, argv);
c68ba0d7
DS
4453
4454 if (!vrf)
4455 return CMD_WARNING;
4456
64c86530 4457 pim_show_membership(vrf->info, vty, uj);
12e41d03 4458
d62a17ae 4459 return CMD_SUCCESS;
12e41d03
DL
4460}
4461
12e41d03
DL
4462DEFUN (show_ip_pim_neighbor,
4463 show_ip_pim_neighbor_cmd,
20a7e5fd 4464 "show ip pim [vrf NAME] neighbor [detail|WORD] [json]",
12e41d03
DL
4465 SHOW_STR
4466 IP_STR
4467 PIM_STR
c68ba0d7 4468 VRF_CMD_HELP_STR
a268493f 4469 "PIM neighbor information\n"
9b91bb50 4470 "Detailed output\n"
a268493f 4471 "Name of interface or neighbor\n"
f5da2cc2 4472 JSON_STR)
12e41d03 4473{
c68ba0d7
DS
4474 int idx = 2;
4475 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9f049418 4476 bool uj = use_json(argc, argv);
c68ba0d7
DS
4477
4478 if (!vrf)
4479 return CMD_WARNING;
72e81cf4 4480
d62a17ae 4481 if (argv_find(argv, argc, "detail", &idx)
4482 || argv_find(argv, argc, "WORD", &idx))
64c86530 4483 pim_show_neighbors_single(vrf->info, vty, argv[idx]->arg, uj);
d62a17ae 4484 else
64c86530 4485 pim_show_neighbors(vrf->info, vty, uj);
12e41d03 4486
d62a17ae 4487 return CMD_SUCCESS;
12e41d03
DL
4488}
4489
a25de56b
DS
4490DEFUN (show_ip_pim_neighbor_vrf_all,
4491 show_ip_pim_neighbor_vrf_all_cmd,
4492 "show ip pim vrf all neighbor [detail|WORD] [json]",
4493 SHOW_STR
4494 IP_STR
4495 PIM_STR
4496 VRF_CMD_HELP_STR
4497 "PIM neighbor information\n"
4498 "Detailed output\n"
4499 "Name of interface or neighbor\n"
f5da2cc2 4500 JSON_STR)
a25de56b
DS
4501{
4502 int idx = 2;
9f049418 4503 bool uj = use_json(argc, argv);
a25de56b
DS
4504 struct vrf *vrf;
4505 bool first = true;
4506
4507 if (uj)
4508 vty_out(vty, "{ ");
a2addae8 4509 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
a25de56b
DS
4510 if (uj) {
4511 if (!first)
4512 vty_out(vty, ", ");
4513 vty_out(vty, " \"%s\": ", vrf->name);
4514 first = false;
4515 } else
4516 vty_out(vty, "VRF: %s\n", vrf->name);
4517 if (argv_find(argv, argc, "detail", &idx)
4518 || argv_find(argv, argc, "WORD", &idx))
4519 pim_show_neighbors_single(vrf->info, vty,
4520 argv[idx]->arg, uj);
4521 else
4522 pim_show_neighbors(vrf->info, vty, uj);
4523 }
4524 if (uj)
4525 vty_out(vty, "}\n");
4526
4527 return CMD_SUCCESS;
4528}
4529
12e41d03
DL
4530DEFUN (show_ip_pim_secondary,
4531 show_ip_pim_secondary_cmd,
20a7e5fd 4532 "show ip pim [vrf NAME] secondary",
12e41d03
DL
4533 SHOW_STR
4534 IP_STR
4535 PIM_STR
c68ba0d7 4536 VRF_CMD_HELP_STR
12e41d03
DL
4537 "PIM neighbor addresses\n")
4538{
c68ba0d7
DS
4539 int idx = 2;
4540 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4541
4542 if (!vrf)
4543 return CMD_WARNING;
4544
64c86530 4545 pim_show_neighbors_secondary(vrf->info, vty);
12e41d03 4546
d62a17ae 4547 return CMD_SUCCESS;
12e41d03
DL
4548}
4549
31a21c9c
DW
4550DEFUN (show_ip_pim_state,
4551 show_ip_pim_state_cmd,
20a7e5fd 4552 "show ip pim [vrf NAME] state [A.B.C.D [A.B.C.D]] [json]",
31a21c9c
DW
4553 SHOW_STR
4554 IP_STR
4555 PIM_STR
c68ba0d7 4556 VRF_CMD_HELP_STR
31a21c9c
DW
4557 "PIM state information\n"
4558 "Unicast or Multicast address\n"
4559 "Multicast address\n"
f5da2cc2 4560 JSON_STR)
31a21c9c 4561{
d62a17ae 4562 const char *src_or_group = NULL;
4563 const char *group = NULL;
c68ba0d7
DS
4564 int idx = 2;
4565 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9f049418 4566 bool uj = use_json(argc, argv);
c68ba0d7
DS
4567
4568 if (!vrf)
4569 return CMD_WARNING;
4570
d62a17ae 4571 if (uj)
4572 argc--;
31a21c9c 4573
56243c3a
DS
4574 if (argv_find(argv, argc, "A.B.C.D", &idx)) {
4575 src_or_group = argv[idx]->arg;
4576 if (idx + 1 < argc)
4577 group = argv[idx + 1]->arg;
4578 }
31a21c9c 4579
64c86530 4580 pim_show_state(vrf->info, vty, src_or_group, group, uj);
31a21c9c 4581
d62a17ae 4582 return CMD_SUCCESS;
31a21c9c
DW
4583}
4584
a25de56b
DS
4585DEFUN (show_ip_pim_state_vrf_all,
4586 show_ip_pim_state_vrf_all_cmd,
4587 "show ip pim vrf all state [A.B.C.D [A.B.C.D]] [json]",
4588 SHOW_STR
4589 IP_STR
4590 PIM_STR
4591 VRF_CMD_HELP_STR
4592 "PIM state information\n"
4593 "Unicast or Multicast address\n"
4594 "Multicast address\n"
f5da2cc2 4595 JSON_STR)
a25de56b
DS
4596{
4597 const char *src_or_group = NULL;
4598 const char *group = NULL;
4599 int idx = 2;
9f049418 4600 bool uj = use_json(argc, argv);
a25de56b
DS
4601 struct vrf *vrf;
4602 bool first = true;
4603
4604 if (uj) {
4605 vty_out(vty, "{ ");
4606 argc--;
4607 }
4608
4609 if (argv_find(argv, argc, "A.B.C.D", &idx)) {
4610 src_or_group = argv[idx]->arg;
4611 if (idx + 1 < argc)
4612 group = argv[idx + 1]->arg;
4613 }
4614
a2addae8 4615 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
a25de56b
DS
4616 if (uj) {
4617 if (!first)
4618 vty_out(vty, ", ");
4619 vty_out(vty, " \"%s\": ", vrf->name);
4620 first = false;
4621 } else
4622 vty_out(vty, "VRF: %s\n", vrf->name);
4623 pim_show_state(vrf->info, vty, src_or_group, group, uj);
4624 }
4625 if (uj)
4626 vty_out(vty, "}\n");
4627
4628 return CMD_SUCCESS;
4629}
4630
dff5cedb 4631DEFPY (show_ip_pim_upstream,
12e41d03 4632 show_ip_pim_upstream_cmd,
dff5cedb 4633 "show ip pim [vrf NAME] upstream [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
12e41d03
DL
4634 SHOW_STR
4635 IP_STR
4636 PIM_STR
c68ba0d7 4637 VRF_CMD_HELP_STR
a268493f 4638 "PIM upstream information\n"
dff5cedb
DS
4639 "The Source or Group\n"
4640 "The Group\n"
f5da2cc2 4641 JSON_STR)
12e41d03 4642{
dff5cedb
DS
4643 struct prefix_sg sg = {0};
4644 struct vrf *v;
4645 bool uj = !!json;
4646 struct pim_instance *pim;
c68ba0d7 4647
dff5cedb
DS
4648 v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
4649
4650 if (!v) {
4651 vty_out(vty, "%% Vrf specified: %s does not exist\n", vrf);
c68ba0d7 4652 return CMD_WARNING;
dff5cedb
DS
4653 }
4654 pim = pim_get_pim_instance(v->vrf_id);
c68ba0d7 4655
dff5cedb
DS
4656 if (!pim) {
4657 vty_out(vty, "%% Unable to find pim instance\n");
4658 return CMD_WARNING;
4659 }
4660
4661 if (s_or_g.s_addr != 0) {
4662 if (g.s_addr != 0) {
4663 sg.src = s_or_g;
4664 sg.grp = g;
4665 } else
4666 sg.grp = s_or_g;
4667 }
4668 pim_show_upstream(pim, vty, &sg, uj);
12e41d03 4669
d62a17ae 4670 return CMD_SUCCESS;
12e41d03
DL
4671}
4672
a25de56b
DS
4673DEFUN (show_ip_pim_upstream_vrf_all,
4674 show_ip_pim_upstream_vrf_all_cmd,
4675 "show ip pim vrf all upstream [json]",
4676 SHOW_STR
4677 IP_STR
4678 PIM_STR
4679 VRF_CMD_HELP_STR
4680 "PIM upstream information\n"
4681 JSON_STR)
4682{
dff5cedb 4683 struct prefix_sg sg = {0};
9f049418 4684 bool uj = use_json(argc, argv);
a25de56b
DS
4685 struct vrf *vrf;
4686 bool first = true;
4687
4688 if (uj)
4689 vty_out(vty, "{ ");
a2addae8 4690 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
a25de56b
DS
4691 if (uj) {
4692 if (!first)
4693 vty_out(vty, ", ");
4694 vty_out(vty, " \"%s\": ", vrf->name);
4695 first = false;
4696 } else
4697 vty_out(vty, "VRF: %s\n", vrf->name);
dff5cedb 4698 pim_show_upstream(vrf->info, vty, &sg, uj);
a25de56b
DS
4699 }
4700
4701 return CMD_SUCCESS;
4702}
4703
12e41d03
DL
4704DEFUN (show_ip_pim_upstream_join_desired,
4705 show_ip_pim_upstream_join_desired_cmd,
20a7e5fd 4706 "show ip pim [vrf NAME] upstream-join-desired [json]",
12e41d03
DL
4707 SHOW_STR
4708 IP_STR
4709 PIM_STR
c68ba0d7 4710 VRF_CMD_HELP_STR
a268493f 4711 "PIM upstream join-desired\n"
f5da2cc2 4712 JSON_STR)
12e41d03 4713{
c68ba0d7
DS
4714 int idx = 2;
4715 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9f049418 4716 bool uj = use_json(argc, argv);
c68ba0d7
DS
4717
4718 if (!vrf)
4719 return CMD_WARNING;
4720
64c86530 4721 pim_show_join_desired(vrf->info, vty, uj);
12e41d03 4722
d62a17ae 4723 return CMD_SUCCESS;
12e41d03
DL
4724}
4725
4726DEFUN (show_ip_pim_upstream_rpf,
4727 show_ip_pim_upstream_rpf_cmd,
20a7e5fd 4728 "show ip pim [vrf NAME] upstream-rpf [json]",
12e41d03
DL
4729 SHOW_STR
4730 IP_STR
4731 PIM_STR
c68ba0d7 4732 VRF_CMD_HELP_STR
a268493f 4733 "PIM upstream source rpf\n"
f5da2cc2 4734 JSON_STR)
12e41d03 4735{
c68ba0d7
DS
4736 int idx = 2;
4737 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9f049418 4738 bool uj = use_json(argc, argv);
c68ba0d7
DS
4739
4740 if (!vrf)
4741 return CMD_WARNING;
4742
64c86530 4743 pim_show_upstream_rpf(vrf->info, vty, uj);
12e41d03 4744
d62a17ae 4745 return CMD_SUCCESS;
12e41d03
DL
4746}
4747
00d07c6f
DS
4748DEFUN (show_ip_pim_rp,
4749 show_ip_pim_rp_cmd,
20a7e5fd 4750 "show ip pim [vrf NAME] rp-info [json]",
00d07c6f
DS
4751 SHOW_STR
4752 IP_STR
4753 PIM_STR
c68ba0d7 4754 VRF_CMD_HELP_STR
a268493f 4755 "PIM RP information\n"
f5da2cc2 4756 JSON_STR)
00d07c6f 4757{
c68ba0d7
DS
4758 int idx = 2;
4759 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9f049418 4760 bool uj = use_json(argc, argv);
c68ba0d7
DS
4761
4762 if (!vrf)
4763 return CMD_WARNING;
4764
64c86530 4765 pim_rp_show_information(vrf->info, vty, uj);
00d07c6f 4766
d62a17ae 4767 return CMD_SUCCESS;
00d07c6f
DS
4768}
4769
a25de56b
DS
4770DEFUN (show_ip_pim_rp_vrf_all,
4771 show_ip_pim_rp_vrf_all_cmd,
4772 "show ip pim vrf all rp-info [json]",
4773 SHOW_STR
4774 IP_STR
4775 PIM_STR
4776 VRF_CMD_HELP_STR
4777 "PIM RP information\n"
f5da2cc2 4778 JSON_STR)
a25de56b 4779{
9f049418 4780 bool uj = use_json(argc, argv);
a25de56b
DS
4781 struct vrf *vrf;
4782 bool first = true;
4783
4784 if (uj)
4785 vty_out(vty, "{ ");
a2addae8 4786 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
a25de56b
DS
4787 if (uj) {
4788 if (!first)
4789 vty_out(vty, ", ");
4790 vty_out(vty, " \"%s\": ", vrf->name);
4791 first = false;
4792 } else
4793 vty_out(vty, "VRF: %s\n", vrf->name);
4794 pim_rp_show_information(vrf->info, vty, uj);
4795 }
4796 if (uj)
4797 vty_out(vty, "}\n");
4798
4799 return CMD_SUCCESS;
4800}
4801
12e41d03
DL
4802DEFUN (show_ip_pim_rpf,
4803 show_ip_pim_rpf_cmd,
20a7e5fd 4804 "show ip pim [vrf NAME] rpf [json]",
12e41d03
DL
4805 SHOW_STR
4806 IP_STR
4807 PIM_STR
c68ba0d7 4808 VRF_CMD_HELP_STR
a268493f 4809 "PIM cached source rpf information\n"
f5da2cc2 4810 JSON_STR)
12e41d03 4811{
c68ba0d7
DS
4812 int idx = 2;
4813 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9f049418 4814 bool uj = use_json(argc, argv);
c68ba0d7
DS
4815
4816 if (!vrf)
4817 return CMD_WARNING;
4818
64c86530 4819 pim_show_rpf(vrf->info, vty, uj);
12e41d03 4820
d62a17ae 4821 return CMD_SUCCESS;
12e41d03
DL
4822}
4823
a25de56b
DS
4824DEFUN (show_ip_pim_rpf_vrf_all,
4825 show_ip_pim_rpf_vrf_all_cmd,
4826 "show ip pim vrf all rpf [json]",
4827 SHOW_STR
4828 IP_STR
4829 PIM_STR
4830 VRF_CMD_HELP_STR
4831 "PIM cached source rpf information\n"
f5da2cc2 4832 JSON_STR)
a25de56b 4833{
9f049418 4834 bool uj = use_json(argc, argv);
a25de56b
DS
4835 struct vrf *vrf;
4836 bool first = true;
4837
4838 if (uj)
4839 vty_out(vty, "{ ");
a2addae8 4840 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
a25de56b
DS
4841 if (uj) {
4842 if (!first)
4843 vty_out(vty, ", ");
4844 vty_out(vty, " \"%s\": ", vrf->name);
4845 first = false;
4846 } else
4847 vty_out(vty, "VRF: %s\n", vrf->name);
4848 pim_show_rpf(vrf->info, vty, uj);
4849 }
4850 if (uj)
4851 vty_out(vty, "}\n");
4852
4853 return CMD_SUCCESS;
4854}
4855
cba44481
CS
4856DEFUN (show_ip_pim_nexthop,
4857 show_ip_pim_nexthop_cmd,
20a7e5fd 4858 "show ip pim [vrf NAME] nexthop",
cba44481
CS
4859 SHOW_STR
4860 IP_STR
4861 PIM_STR
c68ba0d7 4862 VRF_CMD_HELP_STR
cba44481
CS
4863 "PIM cached nexthop rpf information\n")
4864{
c68ba0d7
DS
4865 int idx = 2;
4866 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4867
4868 if (!vrf)
4869 return CMD_WARNING;
4870
64c86530 4871 pim_show_nexthop(vrf->info, vty);
cba44481 4872
d62a17ae 4873 return CMD_SUCCESS;
cba44481
CS
4874}
4875
4876DEFUN (show_ip_pim_nexthop_lookup,
4877 show_ip_pim_nexthop_lookup_cmd,
20a7e5fd 4878 "show ip pim [vrf NAME] nexthop-lookup A.B.C.D A.B.C.D",
cba44481
CS
4879 SHOW_STR
4880 IP_STR
4881 PIM_STR
c68ba0d7 4882 VRF_CMD_HELP_STR
cba44481
CS
4883 "PIM cached nexthop rpf lookup\n"
4884 "Source/RP address\n"
4885 "Multicast Group address\n")
4886{
d62a17ae 4887 struct prefix nht_p;
4888 int result = 0;
4889 struct in_addr src_addr, grp_addr;
4890 struct in_addr vif_source;
4891 const char *addr_str, *addr_str1;
4892 struct prefix grp;
4893 struct pim_nexthop nexthop;
4894 char nexthop_addr_str[PREFIX_STRLEN];
4895 char grp_str[PREFIX_STRLEN];
c68ba0d7
DS
4896 int idx = 2;
4897 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
d62a17ae 4898
c68ba0d7
DS
4899 if (!vrf)
4900 return CMD_WARNING;
4901
4902 argv_find(argv, argc, "A.B.C.D", &idx);
4903 addr_str = argv[idx]->arg;
d62a17ae 4904 result = inet_pton(AF_INET, addr_str, &src_addr);
4905 if (result <= 0) {
4906 vty_out(vty, "Bad unicast address %s: errno=%d: %s\n", addr_str,
4907 errno, safe_strerror(errno));
4908 return CMD_WARNING;
4909 }
4910
4911 if (pim_is_group_224_4(src_addr)) {
4912 vty_out(vty,
4913 "Invalid argument. Expected Valid Source Address.\n");
4914 return CMD_WARNING;
4915 }
4916
c68ba0d7 4917 addr_str1 = argv[idx + 1]->arg;
d62a17ae 4918 result = inet_pton(AF_INET, addr_str1, &grp_addr);
4919 if (result <= 0) {
4920 vty_out(vty, "Bad unicast address %s: errno=%d: %s\n", addr_str,
4921 errno, safe_strerror(errno));
4922 return CMD_WARNING;
4923 }
4924
4925 if (!pim_is_group_224_4(grp_addr)) {
4926 vty_out(vty,
4927 "Invalid argument. Expected Valid Multicast Group Address.\n");
4928 return CMD_WARNING;
4929 }
4930
c68ba0d7
DS
4931 if (!pim_rp_set_upstream_addr(vrf->info, &vif_source, src_addr,
4932 grp_addr))
d62a17ae 4933 return CMD_SUCCESS;
4934
d62a17ae 4935 nht_p.family = AF_INET;
4936 nht_p.prefixlen = IPV4_MAX_BITLEN;
4937 nht_p.u.prefix4 = vif_source;
4938 grp.family = AF_INET;
4939 grp.prefixlen = IPV4_MAX_BITLEN;
4940 grp.u.prefix4 = grp_addr;
4941 memset(&nexthop, 0, sizeof(nexthop));
4942
43763b11 4943 result = pim_ecmp_nexthop_lookup(vrf->info, &nexthop, &nht_p, &grp, 0);
9993f22c
DS
4944
4945 if (!result) {
996c9314
LB
4946 vty_out(vty,
4947 "Nexthop Lookup failed, no usable routes returned.\n");
9993f22c
DS
4948 return CMD_SUCCESS;
4949 }
d62a17ae 4950
4951 pim_addr_dump("<grp?>", &grp, grp_str, sizeof(grp_str));
4952 pim_addr_dump("<nexthop?>", &nexthop.mrib_nexthop_addr,
4953 nexthop_addr_str, sizeof(nexthop_addr_str));
4954 vty_out(vty, "Group %s --- Nexthop %s Interface %s \n", grp_str,
4955 nexthop_addr_str, nexthop.interface->name);
4956
4957 return CMD_SUCCESS;
cba44481
CS
4958}
4959
39438188
CS
4960DEFUN (show_ip_pim_interface_traffic,
4961 show_ip_pim_interface_traffic_cmd,
20a7e5fd 4962 "show ip pim [vrf NAME] interface traffic [WORD] [json]",
39438188
CS
4963 SHOW_STR
4964 IP_STR
4965 PIM_STR
c68ba0d7 4966 VRF_CMD_HELP_STR
39438188
CS
4967 "PIM interface information\n"
4968 "Protocol Packet counters\n"
17d86e50 4969 "Interface name\n"
f5da2cc2 4970 JSON_STR)
39438188 4971{
c68ba0d7
DS
4972 int idx = 2;
4973 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9f049418 4974 bool uj = use_json(argc, argv);
c68ba0d7
DS
4975
4976 if (!vrf)
4977 return CMD_WARNING;
39438188 4978
d62a17ae 4979 if (argv_find(argv, argc, "WORD", &idx))
64c86530 4980 pim_show_interface_traffic_single(vrf->info, vty,
c68ba0d7 4981 argv[idx]->arg, uj);
d62a17ae 4982 else
64c86530 4983 pim_show_interface_traffic(vrf->info, vty, uj);
39438188 4984
d62a17ae 4985 return CMD_SUCCESS;
39438188
CS
4986}
4987
0d1a4e24 4988DEFUN (show_ip_pim_bsm_db,
4989 show_ip_pim_bsm_db_cmd,
4990 "show ip pim bsm-database [vrf NAME] [json]",
4991 SHOW_STR
4992 IP_STR
4993 PIM_STR
4994 VRF_CMD_HELP_STR
4995 "PIM cached bsm packets information\n"
4996 JSON_STR)
4997{
4998 int idx = 2;
4999 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
5000 bool uj = use_json(argc, argv);
5001
5002 if (!vrf)
5003 return CMD_WARNING;
5004
5005 pim_show_bsm_db(vrf->info, vty, uj);
5006 return CMD_SUCCESS;
5007}
321295c1 5008
5009DEFUN (show_ip_pim_bsrp,
5010 show_ip_pim_bsrp_cmd,
5011 "show ip pim bsrp-info [vrf NAME] [json]",
5012 SHOW_STR
5013 IP_STR
5014 PIM_STR
5015 VRF_CMD_HELP_STR
5016 "PIM cached group-rp mappings information\n"
5017 JSON_STR)
5018{
5019 int idx = 2;
5020 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
5021 bool uj = use_json(argc, argv);
5022
5023 if (!vrf)
5024 return CMD_WARNING;
5025
5026 pim_show_group_rp_mappings_info(vrf->info, vty, uj);
5027
5028 return CMD_SUCCESS;
5029}
5030
415f6350 5031DEFUN (show_ip_pim_statistics,
5032 show_ip_pim_statistics_cmd,
5033 "show ip pim [vrf NAME] statistics [interface WORD] [json]",
5034 SHOW_STR
5035 IP_STR
5036 PIM_STR
5037 VRF_CMD_HELP_STR
5038 "PIM statistics\n"
5039 "interface\n"
5040 "PIM interface\n"
5041 JSON_STR)
5042{
5043 int idx = 2;
5044 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
5045 bool uj = use_json(argc, argv);
5046
5047 if (!vrf)
5048 return CMD_WARNING;
5049
5050 if (argv_find(argv, argc, "WORD", &idx))
5051 pim_show_statistics(vrf->info, vty, argv[idx]->arg, uj);
5052 else
5053 pim_show_statistics(vrf->info, vty, NULL, uj);
5054
5055 return CMD_SUCCESS;
5056}
5057
64c86530 5058static void show_multicast_interfaces(struct pim_instance *pim, struct vty *vty)
12e41d03 5059{
d62a17ae 5060 struct interface *ifp;
5061
5062 vty_out(vty, "\n");
5063
5064 vty_out(vty,
ff415346 5065 "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut\n");
d62a17ae 5066
451fda4f 5067 FOR_ALL_INTERFACES (pim->vrf, ifp) {
c68ba0d7
DS
5068 struct pim_interface *pim_ifp;
5069 struct in_addr ifaddr;
5070 struct sioc_vif_req vreq;
d62a17ae 5071
c68ba0d7 5072 pim_ifp = ifp->info;
d62a17ae 5073
c68ba0d7
DS
5074 if (!pim_ifp)
5075 continue;
d62a17ae 5076
c68ba0d7
DS
5077 memset(&vreq, 0, sizeof(vreq));
5078 vreq.vifi = pim_ifp->mroute_vif_index;
d62a17ae 5079
c68ba0d7
DS
5080 if (ioctl(pim->mroute_socket, SIOCGETVIFCNT, &vreq)) {
5081 zlog_warn(
5082 "ioctl(SIOCGETVIFCNT=%lu) failure for interface %s vif_index=%d: errno=%d: %s",
5083 (unsigned long)SIOCGETVIFCNT, ifp->name,
5084 pim_ifp->mroute_vif_index, errno,
5085 safe_strerror(errno));
5086 }
ecca97ac 5087
c68ba0d7 5088 ifaddr = pim_ifp->primary_address;
d62a17ae 5089
ff415346 5090 vty_out(vty, "%-16s %-15s %3d %3d %7lu %7lu %10lu %10lu\n",
c68ba0d7
DS
5091 ifp->name, inet_ntoa(ifaddr), ifp->ifindex,
5092 pim_ifp->mroute_vif_index, (unsigned long)vreq.icount,
5093 (unsigned long)vreq.ocount, (unsigned long)vreq.ibytes,
5094 (unsigned long)vreq.obytes);
d62a17ae 5095 }
12e41d03
DL
5096}
5097
a25de56b
DS
5098static void pim_cmd_show_ip_multicast_helper(struct pim_instance *pim,
5099 struct vty *vty)
12e41d03 5100{
a25de56b 5101 struct vrf *vrf = pim->vrf;
d62a17ae 5102 time_t now = pim_time_monotonic_sec();
d62a17ae 5103 char uptime[10];
afec9bba 5104 char mlag_role[80];
d62a17ae 5105
bc14b6c7
DS
5106 pim = vrf->info;
5107
afec9bba
DS
5108 vty_out(vty, "Router MLAG Role: %s\n",
5109 mlag_role2str(router->role, mlag_role, sizeof(mlag_role)));
ecca97ac
DS
5110 vty_out(vty, "Mroute socket descriptor:");
5111
c68ba0d7 5112 vty_out(vty, " %d(%s)\n", pim->mroute_socket, vrf->name);
12e41d03 5113
d62a17ae 5114 pim_time_uptime(uptime, sizeof(uptime),
c68ba0d7 5115 now - pim->mroute_socket_creation);
d62a17ae 5116 vty_out(vty, "Mroute socket uptime: %s\n", uptime);
12e41d03 5117
d62a17ae 5118 vty_out(vty, "\n");
12e41d03 5119
d62a17ae 5120 pim_zebra_zclient_update(vty);
5121 pim_zlookup_show_ip_multicast(vty);
05b0d0d0 5122
d62a17ae 5123 vty_out(vty, "\n");
5124 vty_out(vty, "Maximum highest VifIndex: %d\n", PIM_MAX_USABLE_VIFS);
12e41d03 5125
d62a17ae 5126 vty_out(vty, "\n");
5b45753e 5127 vty_out(vty, "Upstream Join Timer: %d secs\n", router->t_periodic);
d62a17ae 5128 vty_out(vty, "Join/Prune Holdtime: %d secs\n", PIM_JP_HOLDTIME);
4795fff7 5129 vty_out(vty, "PIM ECMP: %s\n", pim->ecmp_enable ? "Enable" : "Disable");
d62a17ae 5130 vty_out(vty, "PIM ECMP Rebalance: %s\n",
4795fff7 5131 pim->ecmp_rebalance_enable ? "Enable" : "Disable");
12e41d03 5132
d62a17ae 5133 vty_out(vty, "\n");
12e41d03 5134
da11e325 5135 show_rpf_refresh_stats(vty, pim, now, NULL);
12e41d03 5136
d62a17ae 5137 vty_out(vty, "\n");
12e41d03 5138
64c86530 5139 show_scan_oil_stats(pim, vty, now);
12e41d03 5140
64c86530 5141 show_multicast_interfaces(pim, vty);
a25de56b
DS
5142}
5143
5144DEFUN (show_ip_multicast,
5145 show_ip_multicast_cmd,
5146 "show ip multicast [vrf NAME]",
5147 SHOW_STR
5148 IP_STR
5149 VRF_CMD_HELP_STR
5150 "Multicast global information\n")
5151{
5152 int idx = 2;
5153 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
5154
5155 if (!vrf)
5156 return CMD_WARNING;
5157
5158 pim_cmd_show_ip_multicast_helper(vrf->info, vty);
5159
5160 return CMD_SUCCESS;
5161}
5162
5163DEFUN (show_ip_multicast_vrf_all,
5164 show_ip_multicast_vrf_all_cmd,
5165 "show ip multicast vrf all",
5166 SHOW_STR
5167 IP_STR
5168 VRF_CMD_HELP_STR
5169 "Multicast global information\n")
5170{
9f049418 5171 bool uj = use_json(argc, argv);
a25de56b
DS
5172 struct vrf *vrf;
5173 bool first = true;
5174
5175 if (uj)
5176 vty_out(vty, "{ ");
a2addae8 5177 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
a25de56b
DS
5178 if (uj) {
5179 if (!first)
5180 vty_out(vty, ", ");
5181 vty_out(vty, " \"%s\": ", vrf->name);
5182 first = false;
5183 } else
5184 vty_out(vty, "VRF: %s\n", vrf->name);
5185 pim_cmd_show_ip_multicast_helper(vrf->info, vty);
5186 }
5187 if (uj)
5188 vty_out(vty, "}\n");
12e41d03 5189
d62a17ae 5190 return CMD_SUCCESS;
12e41d03
DL
5191}
5192
c23c1d39
DS
5193static void show_mroute(struct pim_instance *pim, struct vty *vty,
5194 struct prefix_sg *sg, bool fill, bool uj)
12e41d03 5195{
d62a17ae 5196 struct listnode *node;
5197 struct channel_oil *c_oil;
5198 struct static_route *s_route;
5199 time_t now;
5200 json_object *json = NULL;
5201 json_object *json_group = NULL;
5202 json_object *json_source = NULL;
5203 json_object *json_oil = NULL;
5204 json_object *json_ifp_out = NULL;
a2b6e694 5205 int found_oif;
5206 int first;
d62a17ae 5207 char grp_str[INET_ADDRSTRLEN];
5208 char src_str[INET_ADDRSTRLEN];
5209 char in_ifname[INTERFACE_NAMSIZ + 1];
5210 char out_ifname[INTERFACE_NAMSIZ + 1];
5211 int oif_vif_index;
5212 struct interface *ifp_in;
5213 char proto[100];
5214
5215 if (uj) {
5216 json = json_object_new_object();
5217 } else {
5218 vty_out(vty,
ff415346 5219 "Source Group Proto Input Output TTL Uptime\n");
d62a17ae 5220 }
5221
5222 now = pim_time_monotonic_sec();
5223
5224 /* print list of PIM and IGMP routes */
c68ba0d7 5225 for (ALL_LIST_ELEMENTS_RO(pim->channel_oil_list, node, c_oil)) {
d62a17ae 5226 found_oif = 0;
5227 first = 1;
5228 if (!c_oil->installed && !uj)
5229 continue;
5230
c23c1d39
DS
5231 if (sg->grp.s_addr != 0 &&
5232 sg->grp.s_addr != c_oil->oil.mfcc_mcastgrp.s_addr)
5233 continue;
5234 if (sg->src.s_addr != 0 &&
5235 sg->src.s_addr != c_oil->oil.mfcc_origin.s_addr)
5236 continue;
5237
d62a17ae 5238 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, grp_str,
5239 sizeof(grp_str));
5240 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, src_str,
5241 sizeof(src_str));
7cfc7bcf 5242 ifp_in = pim_if_find_by_vif_index(pim, c_oil->oil.mfcc_parent);
d62a17ae 5243
5244 if (ifp_in)
c35b7e6b 5245 strlcpy(in_ifname, ifp_in->name, sizeof(in_ifname));
d62a17ae 5246 else
c35b7e6b 5247 strlcpy(in_ifname, "<iif?>", sizeof(in_ifname));
d62a17ae 5248
5249 if (uj) {
5250
5251 /* Find the group, create it if it doesn't exist */
5252 json_object_object_get_ex(json, grp_str, &json_group);
5253
5254 if (!json_group) {
5255 json_group = json_object_new_object();
5256 json_object_object_add(json, grp_str,
5257 json_group);
5258 }
5259
5260 /* Find the source nested under the group, create it if
5261 * it doesn't exist */
5262 json_object_object_get_ex(json_group, src_str,
5263 &json_source);
5264
5265 if (!json_source) {
5266 json_source = json_object_new_object();
5267 json_object_object_add(json_group, src_str,
5268 json_source);
5269 }
5270
5271 /* Find the inbound interface nested under the source,
5272 * create it if it doesn't exist */
5273 json_object_int_add(json_source, "installed",
5274 c_oil->installed);
5275 json_object_int_add(json_source, "refCount",
5276 c_oil->oil_ref_count);
5277 json_object_int_add(json_source, "oilSize",
5278 c_oil->oil_size);
5279 json_object_int_add(json_source, "OilInheritedRescan",
5280 c_oil->oil_inherited_rescan);
5281 json_object_string_add(json_source, "iif", in_ifname);
5282 json_oil = NULL;
5283 }
5284
5285 for (oif_vif_index = 0; oif_vif_index < MAXVIFS;
5286 ++oif_vif_index) {
5287 struct interface *ifp_out;
e7cd85bd 5288 char mroute_uptime[10];
d62a17ae 5289 int ttl;
5290
5291 ttl = c_oil->oil.mfcc_ttls[oif_vif_index];
5292 if (ttl < 1)
5293 continue;
5294
7cfc7bcf 5295 ifp_out = pim_if_find_by_vif_index(pim, oif_vif_index);
d62a17ae 5296 pim_time_uptime(
e7cd85bd
SP
5297 mroute_uptime, sizeof(mroute_uptime),
5298 now - c_oil->mroute_creation);
d62a17ae 5299 found_oif = 1;
5300
5301 if (ifp_out)
c35b7e6b 5302 strlcpy(out_ifname, ifp_out->name, sizeof(out_ifname));
d62a17ae 5303 else
c35b7e6b 5304 strlcpy(out_ifname, "<oif?>", sizeof(out_ifname));
d62a17ae 5305
5306 if (uj) {
5307 json_ifp_out = json_object_new_object();
5308 json_object_string_add(json_ifp_out, "source",
5309 src_str);
5310 json_object_string_add(json_ifp_out, "group",
5311 grp_str);
5312
5313 if (c_oil->oif_flags[oif_vif_index]
5314 & PIM_OIF_FLAG_PROTO_PIM)
5315 json_object_boolean_true_add(
5316 json_ifp_out, "protocolPim");
5317
5318 if (c_oil->oif_flags[oif_vif_index]
5319 & PIM_OIF_FLAG_PROTO_IGMP)
5320 json_object_boolean_true_add(
5321 json_ifp_out, "protocolIgmp");
5322
ee31c9fd
AK
5323 if (c_oil->oif_flags[oif_vif_index]
5324 & PIM_OIF_FLAG_PROTO_VXLAN)
5325 json_object_boolean_true_add(
5326 json_ifp_out, "protocolVxlan");
5327
d62a17ae 5328 if (c_oil->oif_flags[oif_vif_index]
5329 & PIM_OIF_FLAG_PROTO_SOURCE)
5330 json_object_boolean_true_add(
5331 json_ifp_out, "protocolSource");
5332
5333 if (c_oil->oif_flags[oif_vif_index]
5334 & PIM_OIF_FLAG_PROTO_STAR)
5335 json_object_boolean_true_add(
5336 json_ifp_out,
5337 "protocolInherited");
5338
5339 json_object_string_add(json_ifp_out,
5340 "inboundInterface",
5341 in_ifname);
5342 json_object_int_add(json_ifp_out, "iVifI",
5343 c_oil->oil.mfcc_parent);
5344 json_object_string_add(json_ifp_out,
5345 "outboundInterface",
5346 out_ifname);
5347 json_object_int_add(json_ifp_out, "oVifI",
5348 oif_vif_index);
5349 json_object_int_add(json_ifp_out, "ttl", ttl);
5350 json_object_string_add(json_ifp_out, "upTime",
e7cd85bd 5351 mroute_uptime);
d62a17ae 5352 if (!json_oil) {
5353 json_oil = json_object_new_object();
5354 json_object_object_add(json_source,
5355 "oil", json_oil);
5356 }
5357 json_object_object_add(json_oil, out_ifname,
5358 json_ifp_out);
5359 } else {
5360 if (c_oil->oif_flags[oif_vif_index]
5361 & PIM_OIF_FLAG_PROTO_PIM) {
c35b7e6b 5362 strlcpy(proto, "PIM", sizeof(proto));
d62a17ae 5363 }
5364
5365 if (c_oil->oif_flags[oif_vif_index]
5366 & PIM_OIF_FLAG_PROTO_IGMP) {
c35b7e6b 5367 strlcpy(proto, "IGMP", sizeof(proto));
d62a17ae 5368 }
5369
ee31c9fd
AK
5370 if (c_oil->oif_flags[oif_vif_index]
5371 & PIM_OIF_FLAG_PROTO_VXLAN) {
c35b7e6b 5372 strlcpy(proto, "VxLAN", sizeof(proto));
ee31c9fd
AK
5373 }
5374
d62a17ae 5375 if (c_oil->oif_flags[oif_vif_index]
5376 & PIM_OIF_FLAG_PROTO_SOURCE) {
c35b7e6b 5377 strlcpy(proto, "SRC", sizeof(proto));
d62a17ae 5378 }
5379
5380 if (c_oil->oif_flags[oif_vif_index]
5381 & PIM_OIF_FLAG_PROTO_STAR) {
c35b7e6b 5382 strlcpy(proto, "STAR", sizeof(proto));
d62a17ae 5383 }
5384
5385 vty_out(vty,
ff415346 5386 "%-15s %-15s %-6s %-16s %-16s %-3d %8s\n",
d62a17ae 5387 src_str, grp_str, proto, in_ifname,
e7cd85bd 5388 out_ifname, ttl, mroute_uptime);
d62a17ae 5389
5390 if (first) {
5391 src_str[0] = '\0';
5392 grp_str[0] = '\0';
5393 in_ifname[0] = '\0';
5394 first = 0;
5395 }
5396 }
5397 }
5398
5399 if (!uj && !found_oif) {
ff415346 5400 vty_out(vty, "%-15s %-15s %-6s %-16s %-16s %-3d %8s\n",
d62a17ae 5401 src_str, grp_str, "none", in_ifname, "none", 0,
5402 "--:--:--");
5403 }
5404 }
5405
5406 /* Print list of static routes */
7cfc7bcf
DS
5407 for (ALL_LIST_ELEMENTS_RO(pim->static_routes, node, s_route)) {
5408 first = 1;
5409
5410 if (!s_route->c_oil.installed)
d62a17ae 5411 continue;
5412
7cfc7bcf
DS
5413 pim_inet4_dump("<group?>", s_route->group, grp_str,
5414 sizeof(grp_str));
5415 pim_inet4_dump("<source?>", s_route->source, src_str,
5416 sizeof(src_str));
5417 ifp_in = pim_if_find_by_vif_index(pim, s_route->iif);
5418 found_oif = 0;
d62a17ae 5419
7cfc7bcf 5420 if (ifp_in)
c35b7e6b 5421 strlcpy(in_ifname, ifp_in->name, sizeof(in_ifname));
7cfc7bcf 5422 else
c35b7e6b 5423 strlcpy(in_ifname, "<iif?>", sizeof(in_ifname));
d62a17ae 5424
7cfc7bcf 5425 if (uj) {
d62a17ae 5426
7cfc7bcf
DS
5427 /* Find the group, create it if it doesn't exist */
5428 json_object_object_get_ex(json, grp_str, &json_group);
d62a17ae 5429
7cfc7bcf
DS
5430 if (!json_group) {
5431 json_group = json_object_new_object();
5432 json_object_object_add(json, grp_str,
5433 json_group);
5434 }
d62a17ae 5435
7cfc7bcf
DS
5436 /* Find the source nested under the group, create it if
5437 * it doesn't exist */
5438 json_object_object_get_ex(json_group, src_str,
5439 &json_source);
d62a17ae 5440
7cfc7bcf
DS
5441 if (!json_source) {
5442 json_source = json_object_new_object();
5443 json_object_object_add(json_group, src_str,
5444 json_source);
5445 }
d62a17ae 5446
7cfc7bcf
DS
5447 json_object_string_add(json_source, "iif", in_ifname);
5448 json_oil = NULL;
5449 } else {
c35b7e6b 5450 strlcpy(proto, "STATIC", sizeof(proto));
7cfc7bcf 5451 }
d62a17ae 5452
7cfc7bcf
DS
5453 for (oif_vif_index = 0; oif_vif_index < MAXVIFS;
5454 ++oif_vif_index) {
5455 struct interface *ifp_out;
5456 char oif_uptime[10];
5457 int ttl;
d62a17ae 5458
7cfc7bcf
DS
5459 ttl = s_route->oif_ttls[oif_vif_index];
5460 if (ttl < 1)
5461 continue;
5462
5463 ifp_out = pim_if_find_by_vif_index(pim, oif_vif_index);
996c9314
LB
5464 pim_time_uptime(
5465 oif_uptime, sizeof(oif_uptime),
5466 now
5467 - s_route->c_oil
5468 .oif_creation[oif_vif_index]);
7cfc7bcf 5469 found_oif = 1;
d62a17ae 5470
7cfc7bcf 5471 if (ifp_out)
c35b7e6b 5472 strlcpy(out_ifname, ifp_out->name, sizeof(out_ifname));
7cfc7bcf 5473 else
c35b7e6b 5474 strlcpy(out_ifname, "<oif?>", sizeof(out_ifname));
d62a17ae 5475
7cfc7bcf
DS
5476 if (uj) {
5477 json_ifp_out = json_object_new_object();
5478 json_object_string_add(json_ifp_out, "source",
5479 src_str);
5480 json_object_string_add(json_ifp_out, "group",
5481 grp_str);
5482 json_object_boolean_true_add(json_ifp_out,
5483 "protocolStatic");
5484 json_object_string_add(json_ifp_out,
5485 "inboundInterface",
5486 in_ifname);
5487 json_object_int_add(
5488 json_ifp_out, "iVifI",
5489 s_route->c_oil.oil.mfcc_parent);
5490 json_object_string_add(json_ifp_out,
5491 "outboundInterface",
5492 out_ifname);
5493 json_object_int_add(json_ifp_out, "oVifI",
5494 oif_vif_index);
5495 json_object_int_add(json_ifp_out, "ttl", ttl);
5496 json_object_string_add(json_ifp_out, "upTime",
5497 oif_uptime);
5498 if (!json_oil) {
5499 json_oil = json_object_new_object();
5500 json_object_object_add(json_source,
5501 "oil", json_oil);
d62a17ae 5502 }
7cfc7bcf
DS
5503 json_object_object_add(json_oil, out_ifname,
5504 json_ifp_out);
5505 } else {
d62a17ae 5506 vty_out(vty,
ff415346 5507 "%-15s %-15s %-6s %-16s %-16s %-3d %8s %s\n",
d62a17ae 5508 src_str, grp_str, proto, in_ifname,
7cfc7bcf
DS
5509 out_ifname, ttl, oif_uptime,
5510 pim->vrf->name);
45b7b092 5511 if (first && !fill) {
7cfc7bcf
DS
5512 src_str[0] = '\0';
5513 grp_str[0] = '\0';
5514 in_ifname[0] = '\0';
5515 first = 0;
5516 }
d62a17ae 5517 }
5518 }
7cfc7bcf
DS
5519
5520 if (!uj && !found_oif) {
5521 vty_out(vty,
ff415346 5522 "%-15s %-15s %-6s %-16s %-16s %-3d %8s %s\n",
7cfc7bcf
DS
5523 src_str, grp_str, proto, in_ifname, "none", 0,
5524 "--:--:--", pim->vrf->name);
5525 }
d62a17ae 5526 }
5527
5528 if (uj) {
9d303b37
DL
5529 vty_out(vty, "%s\n", json_object_to_json_string_ext(
5530 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 5531 json_object_free(json);
5532 }
12e41d03
DL
5533}
5534
c23c1d39 5535DEFPY (show_ip_mroute,
12e41d03 5536 show_ip_mroute_cmd,
c23c1d39 5537 "show ip mroute [vrf NAME] [A.B.C.D$s_or_g [A.B.C.D$g]] [fill$fill] [json$json]",
12e41d03
DL
5538 SHOW_STR
5539 IP_STR
a957a05b 5540 MROUTE_STR
c3169ac7 5541 VRF_CMD_HELP_STR
c23c1d39
DS
5542 "The Source or Group\n"
5543 "The Group\n"
45b7b092 5544 "Fill in Assumed data\n"
a957a05b 5545 JSON_STR)
12e41d03 5546{
c23c1d39
DS
5547 struct prefix_sg sg = {0};
5548 struct pim_instance *pim;
5549 struct vrf *v;
c68ba0d7 5550
c23c1d39
DS
5551 v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
5552
5553 if (!v) {
5554 vty_out(vty, "%% Vrf specified: %s does not exist\n", vrf);
c68ba0d7 5555 return CMD_WARNING;
c23c1d39
DS
5556 }
5557 pim = pim_get_pim_instance(v->vrf_id);
c68ba0d7 5558
c23c1d39
DS
5559 if (!pim) {
5560 vty_out(vty, "%% Unable to find pim instance\n");
5561 return CMD_WARNING;
5562 }
45b7b092 5563
c23c1d39
DS
5564 if (s_or_g.s_addr != 0) {
5565 if (g.s_addr != 0) {
5566 sg.src = s_or_g;
5567 sg.grp = g;
5568 } else
5569 sg.grp = s_or_g;
5570 }
5571 show_mroute(pim, vty, &sg, !!fill, !!json);
d62a17ae 5572 return CMD_SUCCESS;
12e41d03
DL
5573}
5574
b283a4ca
DS
5575DEFUN (show_ip_mroute_vrf_all,
5576 show_ip_mroute_vrf_all_cmd,
45b7b092 5577 "show ip mroute vrf all [fill] [json]",
b283a4ca
DS
5578 SHOW_STR
5579 IP_STR
5580 MROUTE_STR
5581 VRF_CMD_HELP_STR
45b7b092 5582 "Fill in Assumed data\n"
b283a4ca
DS
5583 JSON_STR)
5584{
c23c1d39 5585 struct prefix_sg sg = {0};
9f049418 5586 bool uj = use_json(argc, argv);
45b7b092 5587 int idx = 4;
b283a4ca
DS
5588 struct vrf *vrf;
5589 bool first = true;
45b7b092
DS
5590 bool fill = false;
5591
5592 if (argv_find(argv, argc, "fill", &idx))
5593 fill = true;
b283a4ca
DS
5594
5595 if (uj)
5596 vty_out(vty, "{ ");
a2addae8 5597 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
b283a4ca
DS
5598 if (uj) {
5599 if (!first)
5600 vty_out(vty, ", ");
5601 vty_out(vty, " \"%s\": ", vrf->name);
5602 first = false;
5603 } else
5604 vty_out(vty, "VRF: %s\n", vrf->name);
c23c1d39 5605 show_mroute(vrf->info, vty, &sg, fill, uj);
b283a4ca
DS
5606 }
5607 if (uj)
5cef40fc 5608 vty_out(vty, "}\n");
b283a4ca
DS
5609
5610 return CMD_SUCCESS;
5611}
5612
64c86530 5613static void show_mroute_count(struct pim_instance *pim, struct vty *vty)
12e41d03 5614{
d62a17ae 5615 struct listnode *node;
5616 struct channel_oil *c_oil;
5617 struct static_route *s_route;
12e41d03 5618
d62a17ae 5619 vty_out(vty, "\n");
12e41d03 5620
d62a17ae 5621 vty_out(vty,
5622 "Source Group LastUsed Packets Bytes WrongIf \n");
12e41d03 5623
d62a17ae 5624 /* Print PIM and IGMP route counts */
c68ba0d7 5625 for (ALL_LIST_ELEMENTS_RO(pim->channel_oil_list, node, c_oil)) {
d62a17ae 5626 char group_str[INET_ADDRSTRLEN];
5627 char source_str[INET_ADDRSTRLEN];
58302dc7 5628
d62a17ae 5629 if (!c_oil->installed)
5630 continue;
12e41d03 5631
d62a17ae 5632 pim_mroute_update_counters(c_oil);
12e41d03 5633
d62a17ae 5634 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str,
5635 sizeof(group_str));
5636 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str,
5637 sizeof(source_str));
6250610a 5638
d62a17ae 5639 vty_out(vty, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
5640 source_str, group_str, c_oil->cc.lastused / 100,
5641 c_oil->cc.pktcnt, c_oil->cc.bytecnt,
5642 c_oil->cc.wrong_if);
5643 }
5644
c68ba0d7
DS
5645 for (ALL_LIST_ELEMENTS_RO(pim->static_routes, node, s_route)) {
5646 char group_str[INET_ADDRSTRLEN];
5647 char source_str[INET_ADDRSTRLEN];
6250610a 5648
c68ba0d7
DS
5649 if (!s_route->c_oil.installed)
5650 continue;
6250610a 5651
c68ba0d7 5652 pim_mroute_update_counters(&s_route->c_oil);
4e0bc0f0 5653
c68ba0d7
DS
5654 pim_inet4_dump("<group?>", s_route->c_oil.oil.mfcc_mcastgrp,
5655 group_str, sizeof(group_str));
5656 pim_inet4_dump("<source?>", s_route->c_oil.oil.mfcc_origin,
5657 source_str, sizeof(source_str));
4e0bc0f0 5658
c68ba0d7
DS
5659 vty_out(vty, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
5660 source_str, group_str, s_route->c_oil.cc.lastused,
5661 s_route->c_oil.cc.pktcnt, s_route->c_oil.cc.bytecnt,
5662 s_route->c_oil.cc.wrong_if);
d62a17ae 5663 }
12e41d03
DL
5664}
5665
5666DEFUN (show_ip_mroute_count,
5667 show_ip_mroute_count_cmd,
20a7e5fd 5668 "show ip mroute [vrf NAME] count",
12e41d03
DL
5669 SHOW_STR
5670 IP_STR
5671 MROUTE_STR
c68ba0d7 5672 VRF_CMD_HELP_STR
12e41d03
DL
5673 "Route and packet count data\n")
5674{
c68ba0d7
DS
5675 int idx = 2;
5676 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
5677
e691f179
DS
5678 if (!vrf)
5679 return CMD_WARNING;
5680
64c86530 5681 show_mroute_count(vrf->info, vty);
d62a17ae 5682 return CMD_SUCCESS;
12e41d03
DL
5683}
5684
5c3aac90
DS
5685DEFUN (show_ip_mroute_count_vrf_all,
5686 show_ip_mroute_count_vrf_all_cmd,
5687 "show ip mroute vrf all count",
5688 SHOW_STR
5689 IP_STR
5690 MROUTE_STR
5691 VRF_CMD_HELP_STR
5692 "Route and packet count data\n")
5693{
9f049418 5694 bool uj = use_json(argc, argv);
5c3aac90
DS
5695 struct vrf *vrf;
5696 bool first = true;
5697
5698 if (uj)
5699 vty_out(vty, "{ ");
a2addae8 5700 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
5c3aac90
DS
5701 if (uj) {
5702 if (!first)
5703 vty_out(vty, ", ");
5704 vty_out(vty, " \"%s\": ", vrf->name);
5705 first = false;
5706 } else
5707 vty_out(vty, "VRF: %s\n", vrf->name);
5708 show_mroute_count(vrf->info, vty);
5709 }
5710 if (uj)
5711 vty_out(vty, "}\n");
5712
5713 return CMD_SUCCESS;
5714}
5715
468b6f44
SP
5716static void show_mroute_summary(struct pim_instance *pim, struct vty *vty)
5717{
5718 struct listnode *node;
5719 struct channel_oil *c_oil;
5720 struct static_route *s_route;
5721 uint32_t starg_sw_mroute_cnt = 0;
5722 uint32_t sg_sw_mroute_cnt = 0;
5723 uint32_t starg_hw_mroute_cnt = 0;
5724 uint32_t sg_hw_mroute_cnt = 0;
5725
5726 vty_out(vty, "Mroute Type Installed/Total\n");
5727
5728 for (ALL_LIST_ELEMENTS_RO(pim->channel_oil_list, node, c_oil)) {
5729 if (!c_oil->installed) {
5730 if (c_oil->oil.mfcc_origin.s_addr == INADDR_ANY)
5731 starg_sw_mroute_cnt++;
5732 else
5733 sg_sw_mroute_cnt++;
5734 } else {
5735 if (c_oil->oil.mfcc_origin.s_addr == INADDR_ANY)
5736 starg_hw_mroute_cnt++;
5737 else
5738 sg_hw_mroute_cnt++;
5739 }
5740 }
5741
5742 for (ALL_LIST_ELEMENTS_RO(pim->static_routes, node, s_route)) {
5743 if (!s_route->c_oil.installed) {
5744 if (s_route->c_oil.oil.mfcc_origin.s_addr == INADDR_ANY)
5745 starg_sw_mroute_cnt++;
5746 else
5747 sg_sw_mroute_cnt++;
5748 } else {
5749 if (s_route->c_oil.oil.mfcc_origin.s_addr == INADDR_ANY)
5750 starg_hw_mroute_cnt++;
5751 else
5752 sg_hw_mroute_cnt++;
5753 }
5754 }
5755
5756 vty_out(vty, "%-20s %d/%d\n", "(*, G)", starg_hw_mroute_cnt,
5757 starg_sw_mroute_cnt + starg_hw_mroute_cnt);
5758 vty_out(vty, "%-20s %d/%d\n", "(S, G)", sg_hw_mroute_cnt,
5759 sg_sw_mroute_cnt + sg_hw_mroute_cnt);
5760 vty_out(vty, "------\n");
5761 vty_out(vty, "%-20s %d/%d\n", "Total",
5762 (starg_hw_mroute_cnt + sg_hw_mroute_cnt),
5763 (starg_sw_mroute_cnt +
5764 starg_hw_mroute_cnt +
5765 sg_sw_mroute_cnt +
5766 sg_hw_mroute_cnt));
5767}
5768
5769DEFUN (show_ip_mroute_summary,
5770 show_ip_mroute_summary_cmd,
5771 "show ip mroute [vrf NAME] summary",
5772 SHOW_STR
5773 IP_STR
5774 MROUTE_STR
5775 VRF_CMD_HELP_STR
5776 "Summary of all mroutes\n")
5777{
5778 int idx = 2;
5779 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
5780
5781 if (!vrf)
5782 return CMD_WARNING;
5783
5784 show_mroute_summary(vrf->info, vty);
5785 return CMD_SUCCESS;
5786}
5787
5788DEFUN (show_ip_mroute_summary_vrf_all,
5789 show_ip_mroute_summary_vrf_all_cmd,
5790 "show ip mroute vrf all summary",
5791 SHOW_STR
5792 IP_STR
5793 MROUTE_STR
5794 VRF_CMD_HELP_STR
5795 "Summary of all mroutes\n")
5796{
5797 struct vrf *vrf;
5798
5799 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
5800 vty_out(vty, "VRF: %s\n", vrf->name);
5801 show_mroute_summary(vrf->info, vty);
5802 }
5803
5804 return CMD_SUCCESS;
5805}
5806
12e41d03
DL
5807DEFUN (show_ip_rib,
5808 show_ip_rib_cmd,
20a7e5fd 5809 "show ip rib [vrf NAME] A.B.C.D",
12e41d03
DL
5810 SHOW_STR
5811 IP_STR
5812 RIB_STR
c68ba0d7 5813 VRF_CMD_HELP_STR
12e41d03
DL
5814 "Unicast address\n")
5815{
c68ba0d7
DS
5816 int idx = 2;
5817 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
d62a17ae 5818 struct in_addr addr;
5819 const char *addr_str;
5820 struct pim_nexthop nexthop;
5821 char nexthop_addr_str[PREFIX_STRLEN];
5822 int result;
5823
c68ba0d7
DS
5824 if (!vrf)
5825 return CMD_WARNING;
5826
d62a17ae 5827 memset(&nexthop, 0, sizeof(nexthop));
c68ba0d7
DS
5828 argv_find(argv, argc, "A.B.C.D", &idx);
5829 addr_str = argv[idx]->arg;
d62a17ae 5830 result = inet_pton(AF_INET, addr_str, &addr);
5831 if (result <= 0) {
5832 vty_out(vty, "Bad unicast address %s: errno=%d: %s\n", addr_str,
5833 errno, safe_strerror(errno));
5834 return CMD_WARNING;
5835 }
12e41d03 5836
ade155e1 5837 if (!pim_nexthop_lookup(vrf->info, &nexthop, addr, 0)) {
d62a17ae 5838 vty_out(vty,
5839 "Failure querying RIB nexthop for unicast address %s\n",
5840 addr_str);
5841 return CMD_WARNING;
5842 }
12e41d03 5843
d62a17ae 5844 vty_out(vty,
5845 "Address NextHop Interface Metric Preference\n");
12e41d03 5846
d62a17ae 5847 pim_addr_dump("<nexthop?>", &nexthop.mrib_nexthop_addr,
5848 nexthop_addr_str, sizeof(nexthop_addr_str));
12e41d03 5849
d62a17ae 5850 vty_out(vty, "%-15s %-15s %-9s %6d %10d\n", addr_str, nexthop_addr_str,
5851 nexthop.interface ? nexthop.interface->name : "<ifname?>",
5852 nexthop.mrib_route_metric, nexthop.mrib_metric_preference);
12e41d03 5853
d62a17ae 5854 return CMD_SUCCESS;
12e41d03
DL
5855}
5856
64c86530 5857static void show_ssmpingd(struct pim_instance *pim, struct vty *vty)
12e41d03 5858{
d62a17ae 5859 struct listnode *node;
5860 struct ssmpingd_sock *ss;
5861 time_t now;
12e41d03 5862
d62a17ae 5863 vty_out(vty,
5864 "Source Socket Address Port Uptime Requests\n");
12e41d03 5865
71ad9915 5866 if (!pim->ssmpingd_list)
d62a17ae 5867 return;
12e41d03 5868
d62a17ae 5869 now = pim_time_monotonic_sec();
12e41d03 5870
71ad9915 5871 for (ALL_LIST_ELEMENTS_RO(pim->ssmpingd_list, node, ss)) {
d62a17ae 5872 char source_str[INET_ADDRSTRLEN];
5873 char ss_uptime[10];
5874 struct sockaddr_in bind_addr;
5875 socklen_t len = sizeof(bind_addr);
5876 char bind_addr_str[INET_ADDRSTRLEN];
12e41d03 5877
d62a17ae 5878 pim_inet4_dump("<src?>", ss->source_addr, source_str,
5879 sizeof(source_str));
12e41d03 5880
d62a17ae 5881 if (pim_socket_getsockname(
5882 ss->sock_fd, (struct sockaddr *)&bind_addr, &len)) {
5883 vty_out(vty,
5884 "%% Failure reading socket name for ssmpingd source %s on fd=%d\n",
5885 source_str, ss->sock_fd);
5886 }
12e41d03 5887
d62a17ae 5888 pim_inet4_dump("<addr?>", bind_addr.sin_addr, bind_addr_str,
5889 sizeof(bind_addr_str));
5890 pim_time_uptime(ss_uptime, sizeof(ss_uptime),
5891 now - ss->creation);
12e41d03 5892
d62a17ae 5893 vty_out(vty, "%-15s %6d %-15s %5d %8s %8lld\n", source_str,
5894 ss->sock_fd, bind_addr_str, ntohs(bind_addr.sin_port),
5895 ss_uptime, (long long)ss->requests);
5896 }
12e41d03
DL
5897}
5898
5899DEFUN (show_ip_ssmpingd,
5900 show_ip_ssmpingd_cmd,
20a7e5fd 5901 "show ip ssmpingd [vrf NAME]",
12e41d03
DL
5902 SHOW_STR
5903 IP_STR
c68ba0d7
DS
5904 SHOW_SSMPINGD_STR
5905 VRF_CMD_HELP_STR)
12e41d03 5906{
c68ba0d7
DS
5907 int idx = 2;
5908 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
5909
5910 if (!vrf)
5911 return CMD_WARNING;
5912
64c86530 5913 show_ssmpingd(vrf->info, vty);
d62a17ae 5914 return CMD_SUCCESS;
12e41d03
DL
5915}
5916
64c86530 5917static int pim_rp_cmd_worker(struct pim_instance *pim, struct vty *vty,
9ecb7b77 5918 const char *rp, const char *group,
d62a17ae 5919 const char *plist)
36d6bd7d 5920{
d62a17ae 5921 int result;
36d6bd7d 5922
d0e418b4 5923 result = pim_rp_new_config(pim, rp, group, plist);
5924
5925 if (result == PIM_GROUP_BAD_ADDR_MASK_COMBO) {
5926 vty_out(vty, "%% Inconsistent address and mask: %s\n",
5927 group);
5928 return CMD_WARNING_CONFIG_FAILED;
5929 }
dfe43e25 5930
d62a17ae 5931 if (result == PIM_GROUP_BAD_ADDRESS) {
5932 vty_out(vty, "%% Bad group address specified: %s\n", group);
5933 return CMD_WARNING_CONFIG_FAILED;
5934 }
dfe43e25 5935
d62a17ae 5936 if (result == PIM_RP_BAD_ADDRESS) {
5937 vty_out(vty, "%% Bad RP address specified: %s\n", rp);
5938 return CMD_WARNING_CONFIG_FAILED;
5939 }
36d6bd7d 5940
d62a17ae 5941 if (result == PIM_RP_NO_PATH) {
5942 vty_out(vty, "%% No Path to RP address specified: %s\n", rp);
c6e7b952 5943 return CMD_WARNING;
d62a17ae 5944 }
dfe43e25 5945
d62a17ae 5946 if (result == PIM_GROUP_OVERLAP) {
996c9314
LB
5947 vty_out(vty,
5948 "%% Group range specified cannot exact match another\n");
d62a17ae 5949 return CMD_WARNING_CONFIG_FAILED;
5950 }
dfe43e25 5951
d62a17ae 5952 if (result == PIM_GROUP_PFXLIST_OVERLAP) {
5953 vty_out(vty,
5954 "%% This group is already covered by a RP prefix-list\n");
5955 return CMD_WARNING_CONFIG_FAILED;
5956 }
36d6bd7d 5957
d62a17ae 5958 if (result == PIM_RP_PFXLIST_IN_USE) {
5959 vty_out(vty,
5960 "%% The same prefix-list cannot be applied to multiple RPs\n");
5961 return CMD_WARNING_CONFIG_FAILED;
5962 }
36d6bd7d 5963
6b44b401
SP
5964 if (result == PIM_GROUP_BAD_ADDR_MASK_COMBO) {
5965 vty_out(vty, "%% Inconsistent address and mask: %s\n",
5966 group);
5967 return CMD_WARNING_CONFIG_FAILED;
5968 }
5969
d62a17ae 5970 return CMD_SUCCESS;
36d6bd7d
DS
5971}
5972
4f9f3925
DS
5973static int pim_cmd_spt_switchover(struct pim_instance *pim,
5974 enum pim_spt_switchover spt,
d62a17ae 5975 const char *plist)
df94f9a9 5976{
4f9f3925 5977 pim->spt.switchover = spt;
df94f9a9 5978
4f9f3925 5979 switch (pim->spt.switchover) {
d62a17ae 5980 case PIM_SPT_IMMEDIATE:
0a22ddfb 5981 XFREE(MTYPE_PIM_SPT_PLIST_NAME, pim->spt.plist);
df94f9a9 5982
4f9f3925 5983 pim_upstream_add_lhr_star_pimreg(pim);
d62a17ae 5984 break;
5985 case PIM_SPT_INFINITY:
4f9f3925 5986 pim_upstream_remove_lhr_star_pimreg(pim, plist);
df94f9a9 5987
0a22ddfb 5988 XFREE(MTYPE_PIM_SPT_PLIST_NAME, pim->spt.plist);
df94f9a9 5989
d62a17ae 5990 if (plist)
c68ba0d7 5991 pim->spt.plist =
d62a17ae 5992 XSTRDUP(MTYPE_PIM_SPT_PLIST_NAME, plist);
5993 break;
5994 }
df94f9a9 5995
d62a17ae 5996 return CMD_SUCCESS;
df94f9a9
DS
5997}
5998
a7b2b1e2
DS
5999DEFUN (ip_pim_spt_switchover_infinity,
6000 ip_pim_spt_switchover_infinity_cmd,
6001 "ip pim spt-switchover infinity-and-beyond",
6002 IP_STR
6003 PIM_STR
6004 "SPT-Switchover\n"
6005 "Never switch to SPT Tree\n")
6006{
4f9f3925
DS
6007 PIM_DECLVAR_CONTEXT(vrf, pim);
6008 return pim_cmd_spt_switchover(pim, PIM_SPT_INFINITY, NULL);
df94f9a9 6009}
a7b2b1e2 6010
df94f9a9
DS
6011DEFUN (ip_pim_spt_switchover_infinity_plist,
6012 ip_pim_spt_switchover_infinity_plist_cmd,
6013 "ip pim spt-switchover infinity-and-beyond prefix-list WORD",
6014 IP_STR
6015 PIM_STR
6016 "SPT-Switchover\n"
6017 "Never switch to SPT Tree\n"
6018 "Prefix-List to control which groups to switch\n"
6019 "Prefix-List name\n")
6020{
4f9f3925
DS
6021 PIM_DECLVAR_CONTEXT(vrf, pim);
6022 return pim_cmd_spt_switchover(pim, PIM_SPT_INFINITY, argv[5]->arg);
a7b2b1e2
DS
6023}
6024
6025DEFUN (no_ip_pim_spt_switchover_infinity,
6026 no_ip_pim_spt_switchover_infinity_cmd,
6027 "no ip pim spt-switchover infinity-and-beyond",
6028 NO_STR
6029 IP_STR
6030 PIM_STR
6031 "SPT_Switchover\n"
6032 "Never switch to SPT Tree\n")
6033{
4f9f3925
DS
6034 PIM_DECLVAR_CONTEXT(vrf, pim);
6035 return pim_cmd_spt_switchover(pim, PIM_SPT_IMMEDIATE, NULL);
df94f9a9 6036}
a7b2b1e2 6037
df94f9a9
DS
6038DEFUN (no_ip_pim_spt_switchover_infinity_plist,
6039 no_ip_pim_spt_switchover_infinity_plist_cmd,
6040 "no ip pim spt-switchover infinity-and-beyond prefix-list WORD",
6041 NO_STR
6042 IP_STR
6043 PIM_STR
6044 "SPT_Switchover\n"
6045 "Never switch to SPT Tree\n"
6046 "Prefix-List to control which groups to switch\n"
6047 "Prefix-List name\n")
6048{
4f9f3925
DS
6049 PIM_DECLVAR_CONTEXT(vrf, pim);
6050 return pim_cmd_spt_switchover(pim, PIM_SPT_IMMEDIATE, NULL);
a7b2b1e2
DS
6051}
6052
ee1a0718
DS
6053DEFUN (ip_pim_joinprune_time,
6054 ip_pim_joinprune_time_cmd,
ebe94743 6055 "ip pim join-prune-interval (60-600)",
ee1a0718
DS
6056 IP_STR
6057 "pim multicast routing\n"
6058 "Join Prune Send Interval\n"
6059 "Seconds\n")
6060{
4f9f3925 6061 PIM_DECLVAR_CONTEXT(vrf, pim);
5b45753e 6062 router->t_periodic = atoi(argv[3]->arg);
d62a17ae 6063 return CMD_SUCCESS;
ee1a0718
DS
6064}
6065
6066DEFUN (no_ip_pim_joinprune_time,
6067 no_ip_pim_joinprune_time_cmd,
ebe94743 6068 "no ip pim join-prune-interval (60-600)",
ee1a0718
DS
6069 NO_STR
6070 IP_STR
6071 "pim multicast routing\n"
6072 "Join Prune Send Interval\n"
6073 "Seconds\n")
6074{
4f9f3925 6075 PIM_DECLVAR_CONTEXT(vrf, pim);
5b45753e 6076 router->t_periodic = PIM_DEFAULT_T_PERIODIC;
d62a17ae 6077 return CMD_SUCCESS;
ee1a0718
DS
6078}
6079
191f5695
DS
6080DEFUN (ip_pim_register_suppress,
6081 ip_pim_register_suppress_cmd,
ebe94743 6082 "ip pim register-suppress-time (5-60000)",
4304f95c
DS
6083 IP_STR
6084 "pim multicast routing\n"
191f5695
DS
6085 "Register Suppress Timer\n"
6086 "Seconds\n")
4304f95c 6087{
4f9f3925 6088 PIM_DECLVAR_CONTEXT(vrf, pim);
2925dff5 6089 router->register_suppress_time = atoi(argv[3]->arg);
d62a17ae 6090 return CMD_SUCCESS;
4304f95c
DS
6091}
6092
191f5695
DS
6093DEFUN (no_ip_pim_register_suppress,
6094 no_ip_pim_register_suppress_cmd,
ebe94743 6095 "no ip pim register-suppress-time (5-60000)",
4304f95c
DS
6096 NO_STR
6097 IP_STR
6098 "pim multicast routing\n"
191f5695 6099 "Register Suppress Timer\n"
01408ede 6100 "Seconds\n")
4304f95c 6101{
4f9f3925 6102 PIM_DECLVAR_CONTEXT(vrf, pim);
2925dff5 6103 router->register_suppress_time = PIM_REGISTER_SUPPRESSION_TIME_DEFAULT;
d62a17ae 6104 return CMD_SUCCESS;
4304f95c
DS
6105}
6106
cc14df13
DS
6107DEFUN (ip_pim_rp_keep_alive,
6108 ip_pim_rp_keep_alive_cmd,
6109 "ip pim rp keep-alive-timer (31-60000)",
6110 IP_STR
6111 "pim multicast routing\n"
6112 "Rendevous Point\n"
6113 "Keep alive Timer\n"
6114 "Seconds\n")
6115{
6116 PIM_DECLVAR_CONTEXT(vrf, pim);
9643e2c7 6117 pim->rp_keep_alive_time = atoi(argv[4]->arg);
cc14df13
DS
6118 return CMD_SUCCESS;
6119}
6120
6121DEFUN (no_ip_pim_rp_keep_alive,
6122 no_ip_pim_rp_keep_alive_cmd,
6123 "no ip pim rp keep-alive-timer (31-60000)",
6124 NO_STR
6125 IP_STR
6126 "pim multicast routing\n"
6127 "Rendevous Point\n"
6128 "Keep alive Timer\n"
6129 "Seconds\n")
6130{
6131 PIM_DECLVAR_CONTEXT(vrf, pim);
6132 pim->rp_keep_alive_time = PIM_KEEPALIVE_PERIOD;
6133 return CMD_SUCCESS;
6134}
6135
191f5695
DS
6136DEFUN (ip_pim_keep_alive,
6137 ip_pim_keep_alive_cmd,
ebe94743 6138 "ip pim keep-alive-timer (31-60000)",
01408ede
DS
6139 IP_STR
6140 "pim multicast routing\n"
01408ede
DS
6141 "Keep alive Timer\n"
6142 "Seconds\n")
6143{
4f9f3925 6144 PIM_DECLVAR_CONTEXT(vrf, pim);
19b807ca 6145 pim->keep_alive_time = atoi(argv[3]->arg);
d62a17ae 6146 return CMD_SUCCESS;
01408ede
DS
6147}
6148
191f5695
DS
6149DEFUN (no_ip_pim_keep_alive,
6150 no_ip_pim_keep_alive_cmd,
ebe94743 6151 "no ip pim keep-alive-timer (31-60000)",
01408ede
DS
6152 NO_STR
6153 IP_STR
6154 "pim multicast routing\n"
01408ede
DS
6155 "Keep alive Timer\n"
6156 "Seconds\n")
6157{
4f9f3925 6158 PIM_DECLVAR_CONTEXT(vrf, pim);
19b807ca 6159 pim->keep_alive_time = PIM_KEEPALIVE_PERIOD;
d62a17ae 6160 return CMD_SUCCESS;
01408ede
DS
6161}
6162
8e4c9ef3
DS
6163DEFUN (ip_pim_packets,
6164 ip_pim_packets_cmd,
ebe94743 6165 "ip pim packets (1-100)",
8e4c9ef3
DS
6166 IP_STR
6167 "pim multicast routing\n"
a957a05b
DS
6168 "packets to process at one time per fd\n"
6169 "Number of packets\n")
8e4c9ef3 6170{
4f9f3925 6171 PIM_DECLVAR_CONTEXT(vrf, pim);
75373cca 6172 router->packet_process = atoi(argv[3]->arg);
d62a17ae 6173 return CMD_SUCCESS;
8e4c9ef3
DS
6174}
6175
6176DEFUN (no_ip_pim_packets,
6177 no_ip_pim_packets_cmd,
ebe94743 6178 "no ip pim packets (1-100)",
8e4c9ef3
DS
6179 NO_STR
6180 IP_STR
6181 "pim multicast routing\n"
a957a05b
DS
6182 "packets to process at one time per fd\n"
6183 "Number of packets\n")
8e4c9ef3 6184{
4f9f3925 6185 PIM_DECLVAR_CONTEXT(vrf, pim);
75373cca 6186 router->packet_process = PIM_DEFAULT_PACKET_PROCESS;
d62a17ae 6187 return CMD_SUCCESS;
8e4c9ef3
DS
6188}
6189
71bbe73d
DS
6190DEFUN (ip_pim_v6_secondary,
6191 ip_pim_v6_secondary_cmd,
6192 "ip pim send-v6-secondary",
6193 IP_STR
6194 "pim multicast routing\n"
6195 "Send v6 secondary addresses\n")
6196{
4f9f3925 6197 PIM_DECLVAR_CONTEXT(vrf, pim);
c68ba0d7 6198 pim->send_v6_secondary = 1;
71bbe73d 6199
d62a17ae 6200 return CMD_SUCCESS;
71bbe73d
DS
6201}
6202
6203DEFUN (no_ip_pim_v6_secondary,
6204 no_ip_pim_v6_secondary_cmd,
6205 "no ip pim send-v6-secondary",
6206 NO_STR
6207 IP_STR
6208 "pim multicast routing\n"
6209 "Send v6 secondary addresses\n")
6210{
4f9f3925 6211 PIM_DECLVAR_CONTEXT(vrf, pim);
c68ba0d7 6212 pim->send_v6_secondary = 0;
71bbe73d 6213
d62a17ae 6214 return CMD_SUCCESS;
71bbe73d
DS
6215}
6216
981d6c7a
DS
6217DEFUN (ip_pim_rp,
6218 ip_pim_rp_cmd,
75a26779 6219 "ip pim rp A.B.C.D [A.B.C.D/M]",
981d6c7a 6220 IP_STR
9b34069d
QY
6221 "pim multicast routing\n"
6222 "Rendevous Point\n"
a957a05b
DS
6223 "ip address of RP\n"
6224 "Group Address range to cover\n")
981d6c7a 6225{
ae4a6b57 6226 PIM_DECLVAR_CONTEXT(vrf, pim);
d62a17ae 6227 int idx_ipv4 = 3;
846ef662 6228
d62a17ae 6229 if (argc == (idx_ipv4 + 1))
64c86530 6230 return pim_rp_cmd_worker(pim, vty, argv[idx_ipv4]->arg, NULL,
9ecb7b77 6231 NULL);
d62a17ae 6232 else
64c86530 6233 return pim_rp_cmd_worker(pim, vty, argv[idx_ipv4]->arg,
d62a17ae 6234 argv[idx_ipv4 + 1]->arg, NULL);
dfe43e25
DW
6235}
6236
6237DEFUN (ip_pim_rp_prefix_list,
6238 ip_pim_rp_prefix_list_cmd,
6239 "ip pim rp A.B.C.D prefix-list WORD",
6240 IP_STR
6241 "pim multicast routing\n"
6242 "Rendevous Point\n"
6243 "ip address of RP\n"
6244 "group prefix-list filter\n"
6245 "Name of a prefix-list\n")
6246{
4f9f3925 6247 PIM_DECLVAR_CONTEXT(vrf, pim);
64c86530 6248 return pim_rp_cmd_worker(pim, vty, argv[3]->arg, NULL, argv[5]->arg);
36d6bd7d 6249}
981d6c7a 6250
64c86530 6251static int pim_no_rp_cmd_worker(struct pim_instance *pim, struct vty *vty,
4f9f3925
DS
6252 const char *rp, const char *group,
6253 const char *plist)
36d6bd7d 6254{
d0e418b4 6255 int result = pim_rp_del_config(pim, rp, group, plist);
dfe43e25 6256
d62a17ae 6257 if (result == PIM_GROUP_BAD_ADDRESS) {
6258 vty_out(vty, "%% Bad group address specified: %s\n", group);
6259 return CMD_WARNING_CONFIG_FAILED;
6260 }
75a26779 6261
d62a17ae 6262 if (result == PIM_RP_BAD_ADDRESS) {
6263 vty_out(vty, "%% Bad RP address specified: %s\n", rp);
6264 return CMD_WARNING_CONFIG_FAILED;
6265 }
981d6c7a 6266
d62a17ae 6267 if (result == PIM_RP_NOT_FOUND) {
6268 vty_out(vty, "%% Unable to find specified RP\n");
6269 return CMD_WARNING_CONFIG_FAILED;
6270 }
c8ae3ce8 6271
d62a17ae 6272 return CMD_SUCCESS;
981d6c7a
DS
6273}
6274
6275DEFUN (no_ip_pim_rp,
6276 no_ip_pim_rp_cmd,
75a26779 6277 "no ip pim rp A.B.C.D [A.B.C.D/M]",
981d6c7a
DS
6278 NO_STR
6279 IP_STR
9b34069d
QY
6280 "pim multicast routing\n"
6281 "Rendevous Point\n"
a957a05b
DS
6282 "ip address of RP\n"
6283 "Group Address range to cover\n")
981d6c7a 6284{
4f9f3925 6285 PIM_DECLVAR_CONTEXT(vrf, pim);
d62a17ae 6286 int idx_ipv4 = 4, idx_group = 0;
72e81cf4 6287
d62a17ae 6288 if (argv_find(argv, argc, "A.B.C.D/M", &idx_group))
64c86530 6289 return pim_no_rp_cmd_worker(pim, vty, argv[idx_ipv4]->arg,
d62a17ae 6290 argv[idx_group]->arg, NULL);
6291 else
64c86530 6292 return pim_no_rp_cmd_worker(pim, vty, argv[idx_ipv4]->arg, NULL,
d62a17ae 6293 NULL);
dfe43e25
DW
6294}
6295
6296DEFUN (no_ip_pim_rp_prefix_list,
6297 no_ip_pim_rp_prefix_list_cmd,
6298 "no ip pim rp A.B.C.D prefix-list WORD",
6299 NO_STR
6300 IP_STR
6301 "pim multicast routing\n"
6302 "Rendevous Point\n"
6303 "ip address of RP\n"
6304 "group prefix-list filter\n"
6305 "Name of a prefix-list\n")
6306{
4f9f3925 6307 PIM_DECLVAR_CONTEXT(vrf, pim);
64c86530 6308 return pim_no_rp_cmd_worker(pim, vty, argv[4]->arg, NULL, argv[6]->arg);
981d6c7a
DS
6309}
6310
6f439a70
DS
6311static int pim_ssm_cmd_worker(struct pim_instance *pim, struct vty *vty,
6312 const char *plist)
15a5dafe 6313{
6f439a70 6314 int result = pim_ssm_range_set(pim, pim->vrf_id, plist);
15a5dafe 6315
d62a17ae 6316 if (result == PIM_SSM_ERR_NONE)
6317 return CMD_SUCCESS;
15a5dafe 6318
d62a17ae 6319 switch (result) {
6320 case PIM_SSM_ERR_NO_VRF:
6321 vty_out(vty, "%% VRF doesn't exist\n");
6322 break;
6323 case PIM_SSM_ERR_DUP:
6324 vty_out(vty, "%% duplicate config\n");
6325 break;
6326 default:
6327 vty_out(vty, "%% ssm range config failed\n");
6328 }
15a5dafe 6329
d62a17ae 6330 return CMD_WARNING_CONFIG_FAILED;
15a5dafe 6331}
6332
6333DEFUN (ip_pim_ssm_prefix_list,
6334 ip_pim_ssm_prefix_list_cmd,
6335 "ip pim ssm prefix-list WORD",
6336 IP_STR
6337 "pim multicast routing\n"
6338 "Source Specific Multicast\n"
6339 "group range prefix-list filter\n"
6340 "Name of a prefix-list\n")
6341{
4f9f3925 6342 PIM_DECLVAR_CONTEXT(vrf, pim);
9643e2c7 6343 return pim_ssm_cmd_worker(pim, vty, argv[4]->arg);
15a5dafe 6344}
6345
6346DEFUN (no_ip_pim_ssm_prefix_list,
6347 no_ip_pim_ssm_prefix_list_cmd,
6348 "no ip pim ssm prefix-list",
6349 NO_STR
6350 IP_STR
6351 "pim multicast routing\n"
6352 "Source Specific Multicast\n"
6353 "group range prefix-list filter\n")
6354{
4f9f3925
DS
6355 PIM_DECLVAR_CONTEXT(vrf, pim);
6356 return pim_ssm_cmd_worker(pim, vty, NULL);
15a5dafe 6357}
6358
6359DEFUN (no_ip_pim_ssm_prefix_list_name,
6360 no_ip_pim_ssm_prefix_list_name_cmd,
6361 "no ip pim ssm prefix-list WORD",
6362 NO_STR
6363 IP_STR
6364 "pim multicast routing\n"
6365 "Source Specific Multicast\n"
6366 "group range prefix-list filter\n"
6367 "Name of a prefix-list\n")
6368{
4f9f3925
DS
6369 PIM_DECLVAR_CONTEXT(vrf, pim);
6370 struct pim_ssm *ssm = pim->ssm_info;
15a5dafe 6371
9643e2c7 6372 if (ssm->plist_name && !strcmp(ssm->plist_name, argv[5]->arg))
4f9f3925 6373 return pim_ssm_cmd_worker(pim, vty, NULL);
15a5dafe 6374
9643e2c7 6375 vty_out(vty, "%% pim ssm prefix-list %s doesn't exist\n", argv[5]->arg);
15a5dafe 6376
d62a17ae 6377 return CMD_WARNING_CONFIG_FAILED;
15a5dafe 6378}
6379
64c86530 6380static void ip_pim_ssm_show_group_range(struct pim_instance *pim,
088f1098 6381 struct vty *vty, bool uj)
15a5dafe 6382{
c68ba0d7 6383 struct pim_ssm *ssm = pim->ssm_info;
d62a17ae 6384 const char *range_str =
6385 ssm->plist_name ? ssm->plist_name : PIM_SSM_STANDARD_RANGE;
15a5dafe 6386
d62a17ae 6387 if (uj) {
6388 json_object *json;
6389 json = json_object_new_object();
6390 json_object_string_add(json, "ssmGroups", range_str);
9d303b37
DL
6391 vty_out(vty, "%s\n", json_object_to_json_string_ext(
6392 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 6393 json_object_free(json);
6394 } else
6395 vty_out(vty, "SSM group range : %s\n", range_str);
15a5dafe 6396}
6397
6398DEFUN (show_ip_pim_ssm_range,
6399 show_ip_pim_ssm_range_cmd,
20a7e5fd 6400 "show ip pim [vrf NAME] group-type [json]",
15a5dafe 6401 SHOW_STR
6402 IP_STR
6403 PIM_STR
c68ba0d7 6404 VRF_CMD_HELP_STR
15a5dafe 6405 "PIM group type\n"
f5da2cc2 6406 JSON_STR)
15a5dafe 6407{
c68ba0d7
DS
6408 int idx = 2;
6409 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9f049418 6410 bool uj = use_json(argc, argv);
c68ba0d7
DS
6411
6412 if (!vrf)
6413 return CMD_WARNING;
6414
64c86530 6415 ip_pim_ssm_show_group_range(vrf->info, vty, uj);
15a5dafe 6416
d62a17ae 6417 return CMD_SUCCESS;
15a5dafe 6418}
6419
64c86530 6420static void ip_pim_ssm_show_group_type(struct pim_instance *pim,
088f1098 6421 struct vty *vty, bool uj,
d62a17ae 6422 const char *group)
15a5dafe 6423{
d62a17ae 6424 struct in_addr group_addr;
6425 const char *type_str;
6426 int result;
15a5dafe 6427
d62a17ae 6428 result = inet_pton(AF_INET, group, &group_addr);
6429 if (result <= 0)
6430 type_str = "invalid";
6431 else {
6432 if (pim_is_group_224_4(group_addr))
c68ba0d7
DS
6433 type_str =
6434 pim_is_grp_ssm(pim, group_addr) ? "SSM" : "ASM";
d62a17ae 6435 else
6436 type_str = "not-multicast";
6437 }
15a5dafe 6438
d62a17ae 6439 if (uj) {
6440 json_object *json;
6441 json = json_object_new_object();
6442 json_object_string_add(json, "groupType", type_str);
9d303b37
DL
6443 vty_out(vty, "%s\n", json_object_to_json_string_ext(
6444 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 6445 json_object_free(json);
6446 } else
6447 vty_out(vty, "Group type : %s\n", type_str);
15a5dafe 6448}
6449
6450DEFUN (show_ip_pim_group_type,
6451 show_ip_pim_group_type_cmd,
20a7e5fd 6452 "show ip pim [vrf NAME] group-type A.B.C.D [json]",
15a5dafe 6453 SHOW_STR
6454 IP_STR
6455 PIM_STR
c68ba0d7 6456 VRF_CMD_HELP_STR
15a5dafe 6457 "multicast group type\n"
6458 "group address\n"
f5da2cc2 6459 JSON_STR)
15a5dafe 6460{
c68ba0d7
DS
6461 int idx = 2;
6462 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9f049418 6463 bool uj = use_json(argc, argv);
c68ba0d7
DS
6464
6465 if (!vrf)
6466 return CMD_WARNING;
6467
6468 argv_find(argv, argc, "A.B.C.D", &idx);
64c86530 6469 ip_pim_ssm_show_group_type(vrf->info, vty, uj, argv[idx]->arg);
15a5dafe 6470
d62a17ae 6471 return CMD_SUCCESS;
15a5dafe 6472}
6473
256392eb 6474DEFUN (show_ip_pim_bsr,
6475 show_ip_pim_bsr_cmd,
6476 "show ip pim bsr [json]",
6477 SHOW_STR
6478 IP_STR
6479 PIM_STR
6480 "boot-strap router information\n"
6481 JSON_STR)
6482{
6483 int idx = 2;
6484 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
6485 bool uj = use_json(argc, argv);
6486
6487 if (!vrf)
6488 return CMD_WARNING;
6489
6490 pim_show_bsr(vrf->info, vty, uj);
6491
6492 return CMD_SUCCESS;
6493}
6494
12e41d03
DL
6495DEFUN (ip_ssmpingd,
6496 ip_ssmpingd_cmd,
6497 "ip ssmpingd [A.B.C.D]",
6498 IP_STR
6499 CONF_SSMPINGD_STR
6500 "Source address\n")
6501{
4f9f3925 6502 PIM_DECLVAR_CONTEXT(vrf, pim);
d62a17ae 6503 int idx_ipv4 = 2;
6504 int result;
6505 struct in_addr source_addr;
6506 const char *source_str = (argc == 3) ? argv[idx_ipv4]->arg : "0.0.0.0";
12e41d03 6507
d62a17ae 6508 result = inet_pton(AF_INET, source_str, &source_addr);
6509 if (result <= 0) {
6510 vty_out(vty, "%% Bad source address %s: errno=%d: %s\n",
6511 source_str, errno, safe_strerror(errno));
6512 return CMD_WARNING_CONFIG_FAILED;
6513 }
12e41d03 6514
4f9f3925 6515 result = pim_ssmpingd_start(pim, source_addr);
d62a17ae 6516 if (result) {
6517 vty_out(vty, "%% Failure starting ssmpingd for source %s: %d\n",
6518 source_str, result);
6519 return CMD_WARNING_CONFIG_FAILED;
6520 }
12e41d03 6521
d62a17ae 6522 return CMD_SUCCESS;
12e41d03
DL
6523}
6524
6525DEFUN (no_ip_ssmpingd,
6526 no_ip_ssmpingd_cmd,
6527 "no ip ssmpingd [A.B.C.D]",
6528 NO_STR
6529 IP_STR
6530 CONF_SSMPINGD_STR
6531 "Source address\n")
6532{
4f9f3925 6533 PIM_DECLVAR_CONTEXT(vrf, pim);
d62a17ae 6534 int idx_ipv4 = 3;
6535 int result;
6536 struct in_addr source_addr;
6537 const char *source_str = (argc == 4) ? argv[idx_ipv4]->arg : "0.0.0.0";
12e41d03 6538
d62a17ae 6539 result = inet_pton(AF_INET, source_str, &source_addr);
6540 if (result <= 0) {
6541 vty_out(vty, "%% Bad source address %s: errno=%d: %s\n",
6542 source_str, errno, safe_strerror(errno));
6543 return CMD_WARNING_CONFIG_FAILED;
6544 }
12e41d03 6545
4f9f3925 6546 result = pim_ssmpingd_stop(pim, source_addr);
d62a17ae 6547 if (result) {
6548 vty_out(vty, "%% Failure stopping ssmpingd for source %s: %d\n",
6549 source_str, result);
6550 return CMD_WARNING_CONFIG_FAILED;
6551 }
12e41d03 6552
d62a17ae 6553 return CMD_SUCCESS;
12e41d03
DL
6554}
6555
cba44481
CS
6556DEFUN (ip_pim_ecmp,
6557 ip_pim_ecmp_cmd,
6558 "ip pim ecmp",
6559 IP_STR
6560 "pim multicast routing\n"
6561 "Enable PIM ECMP \n")
6562{
4f9f3925 6563 PIM_DECLVAR_CONTEXT(vrf, pim);
4795fff7 6564 pim->ecmp_enable = true;
cba44481 6565
d62a17ae 6566 return CMD_SUCCESS;
cba44481
CS
6567}
6568
6569DEFUN (no_ip_pim_ecmp,
6570 no_ip_pim_ecmp_cmd,
6571 "no ip pim ecmp",
6572 NO_STR
6573 IP_STR
6574 "pim multicast routing\n"
6575 "Disable PIM ECMP \n")
6576{
4f9f3925 6577 PIM_DECLVAR_CONTEXT(vrf, pim);
4795fff7 6578 pim->ecmp_enable = false;
cba44481 6579
d62a17ae 6580 return CMD_SUCCESS;
cba44481
CS
6581}
6582
6583DEFUN (ip_pim_ecmp_rebalance,
6584 ip_pim_ecmp_rebalance_cmd,
6585 "ip pim ecmp rebalance",
6586 IP_STR
6587 "pim multicast routing\n"
6588 "Enable PIM ECMP \n"
6589 "Enable PIM ECMP Rebalance\n")
6590{
4f9f3925 6591 PIM_DECLVAR_CONTEXT(vrf, pim);
4795fff7
DS
6592 pim->ecmp_enable = true;
6593 pim->ecmp_rebalance_enable = true;
cba44481 6594
d62a17ae 6595 return CMD_SUCCESS;
cba44481
CS
6596}
6597
6598DEFUN (no_ip_pim_ecmp_rebalance,
6599 no_ip_pim_ecmp_rebalance_cmd,
6600 "no ip pim ecmp rebalance",
6601 NO_STR
6602 IP_STR
6603 "pim multicast routing\n"
6604 "Disable PIM ECMP \n"
6605 "Disable PIM ECMP Rebalance\n")
6606{
4f9f3925 6607 PIM_DECLVAR_CONTEXT(vrf, pim);
4795fff7 6608 pim->ecmp_rebalance_enable = false;
cba44481 6609
d62a17ae 6610 return CMD_SUCCESS;
cba44481
CS
6611}
6612
d62a17ae 6613static int pim_cmd_igmp_start(struct vty *vty, struct interface *ifp)
12e41d03 6614{
d62a17ae 6615 struct pim_interface *pim_ifp;
6616 uint8_t need_startup = 0;
12e41d03 6617
d62a17ae 6618 pim_ifp = ifp->info;
12e41d03 6619
d62a17ae 6620 if (!pim_ifp) {
b1891fa0
AK
6621 pim_ifp = pim_if_new(ifp, true, false, false,
6622 false /*vxlan_term*/);
d62a17ae 6623 if (!pim_ifp) {
6624 vty_out(vty, "Could not enable IGMP on interface %s\n",
6625 ifp->name);
6626 return CMD_WARNING_CONFIG_FAILED;
6627 }
6628 need_startup = 1;
6629 } else {
6630 if (!PIM_IF_TEST_IGMP(pim_ifp->options)) {
6631 PIM_IF_DO_IGMP(pim_ifp->options);
6632 need_startup = 1;
6633 }
6634 }
12e41d03 6635
d62a17ae 6636 /* 'ip igmp' executed multiple times, with need_startup
6637 avoid multiple if add all and membership refresh */
6638 if (need_startup) {
6639 pim_if_addr_add_all(ifp);
6640 pim_if_membership_refresh(ifp);
6641 }
12e41d03 6642
d62a17ae 6643 return CMD_SUCCESS;
12e41d03
DL
6644}
6645
21419f59
DS
6646DEFUN (interface_ip_igmp,
6647 interface_ip_igmp_cmd,
6648 "ip igmp",
6649 IP_STR
6650 IFACE_IGMP_STR)
6651{
d62a17ae 6652 VTY_DECLVAR_CONTEXT(interface, ifp);
21419f59 6653
d62a17ae 6654 return pim_cmd_igmp_start(vty, ifp);
21419f59
DS
6655}
6656
12e41d03
DL
6657DEFUN (interface_no_ip_igmp,
6658 interface_no_ip_igmp_cmd,
6659 "no ip igmp",
6660 NO_STR
6661 IP_STR
6662 IFACE_IGMP_STR)
6663{
d62a17ae 6664 VTY_DECLVAR_CONTEXT(interface, ifp);
6665 struct pim_interface *pim_ifp = ifp->info;
12e41d03 6666
d62a17ae 6667 if (!pim_ifp)
6668 return CMD_SUCCESS;
12e41d03 6669
d62a17ae 6670 PIM_IF_DONT_IGMP(pim_ifp->options);
12e41d03 6671
d62a17ae 6672 pim_if_membership_clear(ifp);
12e41d03 6673
d62a17ae 6674 pim_if_addr_del_all_igmp(ifp);
12e41d03 6675
d62a17ae 6676 if (!PIM_IF_TEST_PIM(pim_ifp->options)) {
6677 pim_if_delete(ifp);
6678 }
12e41d03 6679
d62a17ae 6680 return CMD_SUCCESS;
12e41d03
DL
6681}
6682
6683DEFUN (interface_ip_igmp_join,
6684 interface_ip_igmp_join_cmd,
6685 "ip igmp join A.B.C.D A.B.C.D",
6686 IP_STR
6687 IFACE_IGMP_STR
6688 "IGMP join multicast group\n"
6689 "Multicast group address\n"
6690 "Source address\n")
6691{
d62a17ae 6692 VTY_DECLVAR_CONTEXT(interface, ifp);
6693 int idx_ipv4 = 3;
6694 int idx_ipv4_2 = 4;
6695 const char *group_str;
6696 const char *source_str;
6697 struct in_addr group_addr;
6698 struct in_addr source_addr;
6699 int result;
6700
6701 /* Group address */
6702 group_str = argv[idx_ipv4]->arg;
6703 result = inet_pton(AF_INET, group_str, &group_addr);
6704 if (result <= 0) {
6705 vty_out(vty, "Bad group address %s: errno=%d: %s\n", group_str,
6706 errno, safe_strerror(errno));
6707 return CMD_WARNING_CONFIG_FAILED;
6708 }
6709
6710 /* Source address */
6711 source_str = argv[idx_ipv4_2]->arg;
6712 result = inet_pton(AF_INET, source_str, &source_addr);
6713 if (result <= 0) {
6714 vty_out(vty, "Bad source address %s: errno=%d: %s\n",
6715 source_str, errno, safe_strerror(errno));
6716 return CMD_WARNING_CONFIG_FAILED;
6717 }
6718
37664928
DS
6719 CMD_FERR_RETURN(pim_if_igmp_join_add(ifp, group_addr, source_addr),
6720 "Failure joining IGMP group: $ERR");
d62a17ae 6721
6722 return CMD_SUCCESS;
12e41d03
DL
6723}
6724
6725DEFUN (interface_no_ip_igmp_join,
6726 interface_no_ip_igmp_join_cmd,
6727 "no ip igmp join A.B.C.D A.B.C.D",
6728 NO_STR
6729 IP_STR
6730 IFACE_IGMP_STR
6731 "IGMP join multicast group\n"
6732 "Multicast group address\n"
6733 "Source address\n")
6734{
d62a17ae 6735 VTY_DECLVAR_CONTEXT(interface, ifp);
6736 int idx_ipv4 = 4;
6737 int idx_ipv4_2 = 5;
6738 const char *group_str;
6739 const char *source_str;
6740 struct in_addr group_addr;
6741 struct in_addr source_addr;
6742 int result;
6743
6744 /* Group address */
6745 group_str = argv[idx_ipv4]->arg;
6746 result = inet_pton(AF_INET, group_str, &group_addr);
6747 if (result <= 0) {
6748 vty_out(vty, "Bad group address %s: errno=%d: %s\n", group_str,
6749 errno, safe_strerror(errno));
6750 return CMD_WARNING_CONFIG_FAILED;
6751 }
6752
6753 /* Source address */
6754 source_str = argv[idx_ipv4_2]->arg;
6755 result = inet_pton(AF_INET, source_str, &source_addr);
6756 if (result <= 0) {
6757 vty_out(vty, "Bad source address %s: errno=%d: %s\n",
6758 source_str, errno, safe_strerror(errno));
6759 return CMD_WARNING_CONFIG_FAILED;
6760 }
6761
6762 result = pim_if_igmp_join_del(ifp, group_addr, source_addr);
6763 if (result) {
6764 vty_out(vty,
6765 "%% Failure leaving IGMP group %s source %s on interface %s: %d\n",
6766 group_str, source_str, ifp->name, result);
6767 return CMD_WARNING_CONFIG_FAILED;
6768 }
6769
6770 return CMD_SUCCESS;
12e41d03
DL
6771}
6772
6773/*
6774 CLI reconfiguration affects the interface level (struct pim_interface).
6775 This function propagates the reconfiguration to every active socket
6776 for that interface.
6777 */
6778static void igmp_sock_query_interval_reconfig(struct igmp_sock *igmp)
6779{
d62a17ae 6780 struct interface *ifp;
6781 struct pim_interface *pim_ifp;
12e41d03 6782
d62a17ae 6783 zassert(igmp);
12e41d03 6784
d62a17ae 6785 /* other querier present? */
12e41d03 6786
d62a17ae 6787 if (igmp->t_other_querier_timer)
6788 return;
12e41d03 6789
d62a17ae 6790 /* this is the querier */
12e41d03 6791
d62a17ae 6792 zassert(igmp->interface);
6793 zassert(igmp->interface->info);
12e41d03 6794
d62a17ae 6795 ifp = igmp->interface;
6796 pim_ifp = ifp->info;
12e41d03 6797
d62a17ae 6798 if (PIM_DEBUG_IGMP_TRACE) {
6799 char ifaddr_str[INET_ADDRSTRLEN];
6800 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str,
6801 sizeof(ifaddr_str));
6802 zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
6803 __PRETTY_FUNCTION__, ifaddr_str, ifp->name,
6804 pim_ifp->igmp_default_query_interval);
6805 }
12e41d03 6806
d62a17ae 6807 /*
6808 igmp_startup_mode_on() will reset QQI:
12e41d03 6809
d62a17ae 6810 igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
6811 */
6812 igmp_startup_mode_on(igmp);
12e41d03
DL
6813}
6814
6815static void igmp_sock_query_reschedule(struct igmp_sock *igmp)
6816{
d62a17ae 6817 if (igmp->t_igmp_query_timer) {
6818 /* other querier present */
6819 zassert(igmp->t_igmp_query_timer);
6820 zassert(!igmp->t_other_querier_timer);
12e41d03 6821
d62a17ae 6822 pim_igmp_general_query_off(igmp);
6823 pim_igmp_general_query_on(igmp);
12e41d03 6824
d62a17ae 6825 zassert(igmp->t_igmp_query_timer);
6826 zassert(!igmp->t_other_querier_timer);
6827 } else {
6828 /* this is the querier */
12e41d03 6829
d62a17ae 6830 zassert(!igmp->t_igmp_query_timer);
6831 zassert(igmp->t_other_querier_timer);
12e41d03 6832
d62a17ae 6833 pim_igmp_other_querier_timer_off(igmp);
6834 pim_igmp_other_querier_timer_on(igmp);
12e41d03 6835
d62a17ae 6836 zassert(!igmp->t_igmp_query_timer);
6837 zassert(igmp->t_other_querier_timer);
6838 }
12e41d03
DL
6839}
6840
6841static void change_query_interval(struct pim_interface *pim_ifp,
6842 int query_interval)
6843{
d62a17ae 6844 struct listnode *sock_node;
6845 struct igmp_sock *igmp;
12e41d03 6846
d62a17ae 6847 pim_ifp->igmp_default_query_interval = query_interval;
12e41d03 6848
d62a17ae 6849 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
6850 igmp_sock_query_interval_reconfig(igmp);
6851 igmp_sock_query_reschedule(igmp);
6852 }
12e41d03
DL
6853}
6854
6855static void change_query_max_response_time(struct pim_interface *pim_ifp,
6856 int query_max_response_time_dsec)
6857{
d62a17ae 6858 struct listnode *sock_node;
6859 struct igmp_sock *igmp;
6860
6861 pim_ifp->igmp_query_max_response_time_dsec =
6862 query_max_response_time_dsec;
6863
6864 /*
6865 Below we modify socket/group/source timers in order to quickly
6866 reflect the change. Otherwise, those timers would eventually catch
6867 up.
6868 */
6869
6870 /* scan all sockets */
6871 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
6872 struct listnode *grp_node;
6873 struct igmp_group *grp;
6874
6875 /* reschedule socket general query */
6876 igmp_sock_query_reschedule(igmp);
6877
6878 /* scan socket groups */
6879 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grp_node,
6880 grp)) {
6881 struct listnode *src_node;
6882 struct igmp_source *src;
6883
6884 /* reset group timers for groups in EXCLUDE mode */
6885 if (grp->group_filtermode_isexcl) {
6886 igmp_group_reset_gmi(grp);
6887 }
6888
6889 /* scan group sources */
6890 for (ALL_LIST_ELEMENTS_RO(grp->group_source_list,
6891 src_node, src)) {
6892
6893 /* reset source timers for sources with running
6894 * timers */
6895 if (src->t_source_timer) {
6896 igmp_source_reset_gmi(igmp, grp, src);
6897 }
6898 }
6899 }
12e41d03 6900 }
12e41d03
DL
6901}
6902
6903#define IGMP_QUERY_INTERVAL_MIN (1)
6904#define IGMP_QUERY_INTERVAL_MAX (1800)
6905
6906DEFUN (interface_ip_igmp_query_interval,
6907 interface_ip_igmp_query_interval_cmd,
9ccf14f7 6908 "ip igmp query-interval (1-1800)",
12e41d03
DL
6909 IP_STR
6910 IFACE_IGMP_STR
6911 IFACE_IGMP_QUERY_INTERVAL_STR
6912 "Query interval in seconds\n")
6913{
d62a17ae 6914 VTY_DECLVAR_CONTEXT(interface, ifp);
6915 struct pim_interface *pim_ifp = ifp->info;
6916 int query_interval;
6917 int query_interval_dsec;
6918 int ret;
6919
6920 if (!pim_ifp) {
6921 ret = pim_cmd_igmp_start(vty, ifp);
6922 if (ret != CMD_SUCCESS)
6923 return ret;
6924 pim_ifp = ifp->info;
6925 }
6926
6927 query_interval = atoi(argv[3]->arg);
6928 query_interval_dsec = 10 * query_interval;
6929
6930 /*
6931 It seems we don't need to check bounds since command.c does it
6932 already, but we verify them anyway for extra safety.
6933 */
6934 if (query_interval < IGMP_QUERY_INTERVAL_MIN) {
6935 vty_out(vty,
6936 "General query interval %d lower than minimum %d\n",
6937 query_interval, IGMP_QUERY_INTERVAL_MIN);
6938 return CMD_WARNING_CONFIG_FAILED;
6939 }
6940 if (query_interval > IGMP_QUERY_INTERVAL_MAX) {
6941 vty_out(vty,
6942 "General query interval %d higher than maximum %d\n",
6943 query_interval, IGMP_QUERY_INTERVAL_MAX);
6944 return CMD_WARNING_CONFIG_FAILED;
6945 }
6946
6947 if (query_interval_dsec <= pim_ifp->igmp_query_max_response_time_dsec) {
6948 vty_out(vty,
6949 "Can't set general query interval %d dsec <= query max response time %d dsec.\n",
6950 query_interval_dsec,
6951 pim_ifp->igmp_query_max_response_time_dsec);
6952 return CMD_WARNING_CONFIG_FAILED;
6953 }
6954
6955 change_query_interval(pim_ifp, query_interval);
6956
6957 return CMD_SUCCESS;
12e41d03
DL
6958}
6959
6960DEFUN (interface_no_ip_igmp_query_interval,
6961 interface_no_ip_igmp_query_interval_cmd,
9ccf14f7 6962 "no ip igmp query-interval",
12e41d03
DL
6963 NO_STR
6964 IP_STR
6965 IFACE_IGMP_STR
6966 IFACE_IGMP_QUERY_INTERVAL_STR)
6967{
d62a17ae 6968 VTY_DECLVAR_CONTEXT(interface, ifp);
6969 struct pim_interface *pim_ifp = ifp->info;
6970 int default_query_interval_dsec;
12e41d03 6971
d62a17ae 6972 if (!pim_ifp)
6973 return CMD_SUCCESS;
12e41d03 6974
d62a17ae 6975 default_query_interval_dsec = IGMP_GENERAL_QUERY_INTERVAL * 10;
12e41d03 6976
d62a17ae 6977 if (default_query_interval_dsec
6978 <= pim_ifp->igmp_query_max_response_time_dsec) {
6979 vty_out(vty,
6980 "Can't set default general query interval %d dsec <= query max response time %d dsec.\n",
6981 default_query_interval_dsec,
6982 pim_ifp->igmp_query_max_response_time_dsec);
6983 return CMD_WARNING_CONFIG_FAILED;
6984 }
12e41d03 6985
d62a17ae 6986 change_query_interval(pim_ifp, IGMP_GENERAL_QUERY_INTERVAL);
12e41d03 6987
d62a17ae 6988 return CMD_SUCCESS;
12e41d03
DL
6989}
6990
b05b72e8
DW
6991DEFUN (interface_ip_igmp_version,
6992 interface_ip_igmp_version_cmd,
72e81cf4 6993 "ip igmp version (2-3)",
b05b72e8
DW
6994 IP_STR
6995 IFACE_IGMP_STR
6996 "IGMP version\n"
6997 "IGMP version number\n")
6998{
d62a17ae 6999 VTY_DECLVAR_CONTEXT(interface, ifp);
7000 struct pim_interface *pim_ifp = ifp->info;
7001 int igmp_version, old_version = 0;
7002 int ret;
7003
7004 if (!pim_ifp) {
7005 ret = pim_cmd_igmp_start(vty, ifp);
7006 if (ret != CMD_SUCCESS)
7007 return ret;
7008 pim_ifp = ifp->info;
7009 }
7010
7011 igmp_version = atoi(argv[3]->arg);
7012 old_version = pim_ifp->igmp_version;
7013 pim_ifp->igmp_version = igmp_version;
7014
7015 // Check if IGMP is Enabled otherwise, enable on interface
7016 if (!PIM_IF_TEST_IGMP(pim_ifp->options)) {
7017 PIM_IF_DO_IGMP(pim_ifp->options);
7018 pim_if_addr_add_all(ifp);
7019 pim_if_membership_refresh(ifp);
3a6351a3
LB
7020 old_version = igmp_version;
7021 // avoid refreshing membership again.
d62a17ae 7022 }
7023 /* Current and new version is different refresh existing
7024 membership. Going from 3 -> 2 or 2 -> 3. */
7025 if (old_version != igmp_version)
7026 pim_if_membership_refresh(ifp);
7027
7028 return CMD_SUCCESS;
b05b72e8
DW
7029}
7030
7031DEFUN (interface_no_ip_igmp_version,
7032 interface_no_ip_igmp_version_cmd,
72e81cf4 7033 "no ip igmp version (2-3)",
b05b72e8
DW
7034 NO_STR
7035 IP_STR
7036 IFACE_IGMP_STR
7037 "IGMP version\n"
7038 "IGMP version number\n")
7039{
d62a17ae 7040 VTY_DECLVAR_CONTEXT(interface, ifp);
7041 struct pim_interface *pim_ifp = ifp->info;
b05b72e8 7042
d62a17ae 7043 if (!pim_ifp)
7044 return CMD_SUCCESS;
b05b72e8 7045
d62a17ae 7046 pim_ifp->igmp_version = IGMP_DEFAULT_VERSION;
b05b72e8 7047
d62a17ae 7048 return CMD_SUCCESS;
b05b72e8
DW
7049}
7050
58344b65
DS
7051#define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
7052#define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
12e41d03
DL
7053
7054DEFUN (interface_ip_igmp_query_max_response_time,
7055 interface_ip_igmp_query_max_response_time_cmd,
58344b65 7056 "ip igmp query-max-response-time (10-250)",
12e41d03
DL
7057 IP_STR
7058 IFACE_IGMP_STR
7059 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
58344b65 7060 "Query response value in deci-seconds\n")
12e41d03 7061{
d62a17ae 7062 VTY_DECLVAR_CONTEXT(interface, ifp);
7063 struct pim_interface *pim_ifp = ifp->info;
7064 int query_max_response_time;
7065 int ret;
12e41d03 7066
d62a17ae 7067 if (!pim_ifp) {
7068 ret = pim_cmd_igmp_start(vty, ifp);
7069 if (ret != CMD_SUCCESS)
7070 return ret;
7071 pim_ifp = ifp->info;
7072 }
12e41d03 7073
d62a17ae 7074 query_max_response_time = atoi(argv[3]->arg);
12e41d03 7075
d62a17ae 7076 if (query_max_response_time
7077 >= pim_ifp->igmp_default_query_interval * 10) {
7078 vty_out(vty,
7079 "Can't set query max response time %d sec >= general query interval %d sec\n",
7080 query_max_response_time,
7081 pim_ifp->igmp_default_query_interval);
7082 return CMD_WARNING_CONFIG_FAILED;
7083 }
12e41d03 7084
d62a17ae 7085 change_query_max_response_time(pim_ifp, query_max_response_time);
12e41d03 7086
d62a17ae 7087 return CMD_SUCCESS;
12e41d03
DL
7088}
7089
7090DEFUN (interface_no_ip_igmp_query_max_response_time,
7091 interface_no_ip_igmp_query_max_response_time_cmd,
72e81cf4 7092 "no ip igmp query-max-response-time (10-250)",
12e41d03
DL
7093 NO_STR
7094 IP_STR
7095 IFACE_IGMP_STR
a957a05b
DS
7096 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
7097 "Time for response in deci-seconds\n")
12e41d03 7098{
d62a17ae 7099 VTY_DECLVAR_CONTEXT(interface, ifp);
7100 struct pim_interface *pim_ifp = ifp->info;
12e41d03 7101
d62a17ae 7102 if (!pim_ifp)
7103 return CMD_SUCCESS;
12e41d03 7104
d62a17ae 7105 change_query_max_response_time(pim_ifp,
7106 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC);
12e41d03 7107
d62a17ae 7108 return CMD_SUCCESS;
12e41d03
DL
7109}
7110
7111#define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
7112#define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
7113
58344b65
DS
7114DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec,
7115 interface_ip_igmp_query_max_response_time_dsec_cmd,
7116 "ip igmp query-max-response-time-dsec (10-250)",
7117 IP_STR
7118 IFACE_IGMP_STR
7119 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
7120 "Query response value in deciseconds\n")
12e41d03 7121{
d62a17ae 7122 VTY_DECLVAR_CONTEXT(interface, ifp);
7123 struct pim_interface *pim_ifp = ifp->info;
7124 int query_max_response_time_dsec;
7125 int default_query_interval_dsec;
7126 int ret;
7127
7128 if (!pim_ifp) {
7129 ret = pim_cmd_igmp_start(vty, ifp);
7130 if (ret != CMD_SUCCESS)
7131 return ret;
7132 pim_ifp = ifp->info;
7133 }
12e41d03 7134
d62a17ae 7135 query_max_response_time_dsec = atoi(argv[4]->arg);
12e41d03 7136
d62a17ae 7137 default_query_interval_dsec = 10 * pim_ifp->igmp_default_query_interval;
12e41d03 7138
d62a17ae 7139 if (query_max_response_time_dsec >= default_query_interval_dsec) {
7140 vty_out(vty,
7141 "Can't set query max response time %d dsec >= general query interval %d dsec\n",
7142 query_max_response_time_dsec,
7143 default_query_interval_dsec);
7144 return CMD_WARNING_CONFIG_FAILED;
7145 }
12e41d03 7146
d62a17ae 7147 change_query_max_response_time(pim_ifp, query_max_response_time_dsec);
12e41d03 7148
d62a17ae 7149 return CMD_SUCCESS;
12e41d03
DL
7150}
7151
58344b65
DS
7152DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec,
7153 interface_no_ip_igmp_query_max_response_time_dsec_cmd,
7154 "no ip igmp query-max-response-time-dsec",
7155 NO_STR
7156 IP_STR
7157 IFACE_IGMP_STR
7158 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR)
12e41d03 7159{
d62a17ae 7160 VTY_DECLVAR_CONTEXT(interface, ifp);
7161 struct pim_interface *pim_ifp = ifp->info;
12e41d03 7162
d62a17ae 7163 if (!pim_ifp)
7164 return CMD_SUCCESS;
12e41d03 7165
d62a17ae 7166 change_query_max_response_time(pim_ifp,
7167 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC);
12e41d03 7168
d62a17ae 7169 return CMD_SUCCESS;
12e41d03
DL
7170}
7171
59115451
SP
7172#define IGMP_LAST_MEMBER_QUERY_COUNT_MIN (1)
7173#define IGMP_LAST_MEMBER_QUERY_COUNT_MAX (7)
7174
7175DEFUN (interface_ip_igmp_last_member_query_count,
7176 interface_ip_igmp_last_member_query_count_cmd,
7177 "ip igmp last-member-query-count (1-7)",
7178 IP_STR
7179 IFACE_IGMP_STR
7180 IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR
7181 "Last member query count\n")
7182{
7183 VTY_DECLVAR_CONTEXT(interface, ifp);
7184 struct pim_interface *pim_ifp = ifp->info;
7185 int last_member_query_count;
7186 int ret;
7187
7188 if (!pim_ifp) {
7189 ret = pim_cmd_igmp_start(vty, ifp);
7190 if (ret != CMD_SUCCESS)
7191 return ret;
7192 pim_ifp = ifp->info;
7193 }
7194
7195 last_member_query_count = atoi(argv[3]->arg);
7196
7197 pim_ifp->igmp_last_member_query_count = last_member_query_count;
7198
7199 return CMD_SUCCESS;
7200}
7201
7202DEFUN (interface_no_ip_igmp_last_member_query_count,
7203 interface_no_ip_igmp_last_member_query_count_cmd,
7204 "no ip igmp last-member-query-count",
7205 NO_STR
7206 IP_STR
7207 IFACE_IGMP_STR
7208 IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR)
7209{
7210 VTY_DECLVAR_CONTEXT(interface, ifp);
7211 struct pim_interface *pim_ifp = ifp->info;
7212
7213 if (!pim_ifp)
7214 return CMD_SUCCESS;
7215
7216 pim_ifp->igmp_last_member_query_count =
7217 IGMP_DEFAULT_ROBUSTNESS_VARIABLE;
7218
7219 return CMD_SUCCESS;
7220}
7221
7222#define IGMP_LAST_MEMBER_QUERY_INTERVAL_MIN (1)
7223#define IGMP_LAST_MEMBER_QUERY_INTERVAL_MAX (255)
7224
7225DEFUN (interface_ip_igmp_last_member_query_interval,
7226 interface_ip_igmp_last_member_query_interval_cmd,
7227 "ip igmp last-member-query-interval (1-255)",
7228 IP_STR
7229 IFACE_IGMP_STR
7230 IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR
7231 "Last member query interval in deciseconds\n")
7232{
7233 VTY_DECLVAR_CONTEXT(interface, ifp);
7234 struct pim_interface *pim_ifp = ifp->info;
7235 int last_member_query_interval;
7236 int ret;
7237
7238 if (!pim_ifp) {
7239 ret = pim_cmd_igmp_start(vty, ifp);
7240 if (ret != CMD_SUCCESS)
7241 return ret;
7242 pim_ifp = ifp->info;
7243 }
7244
7245 last_member_query_interval = atoi(argv[3]->arg);
7246 pim_ifp->igmp_specific_query_max_response_time_dsec
7247 = last_member_query_interval;
7248
7249 return CMD_SUCCESS;
7250}
7251
7252DEFUN (interface_no_ip_igmp_last_member_query_interval,
7253 interface_no_ip_igmp_last_member_query_interval_cmd,
7254 "no ip igmp last-member-query-interval",
7255 NO_STR
7256 IP_STR
7257 IFACE_IGMP_STR
7258 IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR)
7259{
7260 VTY_DECLVAR_CONTEXT(interface, ifp);
7261 struct pim_interface *pim_ifp = ifp->info;
7262
7263 if (!pim_ifp)
7264 return CMD_SUCCESS;
7265
7266 pim_ifp->igmp_specific_query_max_response_time_dsec =
7267 IGMP_SPECIFIC_QUERY_MAX_RESPONSE_TIME_DSEC;
7268
7269 return CMD_SUCCESS;
7270}
7271
dedccda6
DS
7272DEFUN (interface_ip_pim_drprio,
7273 interface_ip_pim_drprio_cmd,
b181fa04 7274 "ip pim drpriority (1-4294967295)",
dedccda6
DS
7275 IP_STR
7276 PIM_STR
7277 "Set the Designated Router Election Priority\n"
7278 "Value of the new DR Priority\n")
7279{
d62a17ae 7280 VTY_DECLVAR_CONTEXT(interface, ifp);
7281 int idx_number = 3;
7282 struct pim_interface *pim_ifp = ifp->info;
7283 uint32_t old_dr_prio;
dedccda6 7284
d62a17ae 7285 if (!pim_ifp) {
7286 vty_out(vty, "Please enable PIM on interface, first\n");
7287 return CMD_WARNING_CONFIG_FAILED;
7288 }
dedccda6 7289
d62a17ae 7290 old_dr_prio = pim_ifp->pim_dr_priority;
dedccda6 7291
d62a17ae 7292 pim_ifp->pim_dr_priority = strtol(argv[idx_number]->arg, NULL, 10);
dedccda6 7293
d62a17ae 7294 if (old_dr_prio != pim_ifp->pim_dr_priority) {
3de70812
DS
7295 pim_if_dr_election(ifp);
7296 pim_hello_restart_now(ifp);
d62a17ae 7297 }
dedccda6 7298
d62a17ae 7299 return CMD_SUCCESS;
dedccda6
DS
7300}
7301
7302DEFUN (interface_no_ip_pim_drprio,
7303 interface_no_ip_pim_drprio_cmd,
b181fa04 7304 "no ip pim drpriority [(1-4294967295)]",
d7fa34c1 7305 NO_STR
dedccda6
DS
7306 IP_STR
7307 PIM_STR
7308 "Revert the Designated Router Priority to default\n"
7309 "Old Value of the Priority\n")
7310{
d62a17ae 7311 VTY_DECLVAR_CONTEXT(interface, ifp);
7312 struct pim_interface *pim_ifp = ifp->info;
dedccda6 7313
d62a17ae 7314 if (!pim_ifp) {
7315 vty_out(vty, "Pim not enabled on this interface\n");
7316 return CMD_WARNING_CONFIG_FAILED;
7317 }
dedccda6 7318
d62a17ae 7319 if (pim_ifp->pim_dr_priority != PIM_DEFAULT_DR_PRIORITY) {
7320 pim_ifp->pim_dr_priority = PIM_DEFAULT_DR_PRIORITY;
3de70812
DS
7321 pim_if_dr_election(ifp);
7322 pim_hello_restart_now(ifp);
d62a17ae 7323 }
dedccda6 7324
d62a17ae 7325 return CMD_SUCCESS;
dedccda6
DS
7326}
7327
d62a17ae 7328static int pim_cmd_interface_add(struct interface *ifp)
12e41d03 7329{
d62a17ae 7330 struct pim_interface *pim_ifp = ifp->info;
12e41d03 7331
d62a17ae 7332 if (!pim_ifp) {
b1891fa0
AK
7333 pim_ifp = pim_if_new(ifp, false, true, false,
7334 false /*vxlan_term*/);
d62a17ae 7335 if (!pim_ifp) {
7336 return 0;
7337 }
7338 } else {
7339 PIM_IF_DO_PIM(pim_ifp->options);
7340 }
12e41d03 7341
d62a17ae 7342 pim_if_addr_add_all(ifp);
7343 pim_if_membership_refresh(ifp);
7344 return 1;
981d6c7a
DS
7345}
7346
70fd22bd
DS
7347DEFPY_HIDDEN (pim_test_sg_keepalive,
7348 pim_test_sg_keepalive_cmd,
7349 "test pim [vrf NAME$name] keepalive-reset A.B.C.D$source A.B.C.D$group",
7350 "Test code\n"
7351 PIM_STR
7352 VRF_CMD_HELP_STR
7353 "Reset the Keepalive Timer\n"
7354 "The Source we are resetting\n"
7355 "The Group we are resetting\n")
7356{
7357 struct pim_upstream *up;
7358 struct pim_instance *pim;
7359 struct prefix_sg sg;
7360
7361 sg.src = source;
7362 sg.grp = group;
7363
7364 if (!name)
7365 pim = pim_get_pim_instance(VRF_DEFAULT);
7366 else {
7367 struct vrf *vrf = vrf_lookup_by_name(name);
7368
7369 if (!vrf) {
7370 vty_out(vty, "%% Vrf specified: %s does not exist\n",
7371 name);
7372 return CMD_WARNING;
7373 }
7374
7375 pim = pim_get_pim_instance(vrf->vrf_id);
7376 }
7377
7378 if (!pim) {
7379 vty_out(vty, "%% Unable to find pim instance\n");
7380 return CMD_WARNING;
7381 }
7382
7383 up = pim_upstream_find(pim, &sg);
7384 if (!up) {
7385 vty_out(vty, "%% Unable to find %s specified\n",
7386 pim_str_sg_dump(&sg));
7387 return CMD_WARNING;
7388 }
7389
7390 vty_out(vty, "Setting %s to current keep alive time: %d\n",
7391 pim_str_sg_dump(&sg), pim->keep_alive_time);
7392 pim_upstream_keep_alive_timer_start(up, pim->keep_alive_time);
7393
7394 return CMD_SUCCESS;
7395}
7396
414d885a
DS
7397DEFPY_HIDDEN (interface_ip_pim_activeactive,
7398 interface_ip_pim_activeactive_cmd,
7399 "[no$no] ip pim active-active",
7400 NO_STR
7401 IP_STR
7402 PIM_STR
7403 "Mark interface as Active-Active for MLAG operations, Hidden because not finished yet\n")
7404{
7405 VTY_DECLVAR_CONTEXT(interface, ifp);
7406 struct pim_interface *pim_ifp;
7407
7408 if (!no && !pim_cmd_interface_add(ifp)) {
7409 vty_out(vty, "Could not enable PIM SM active-active on interface\n");
7410 return CMD_WARNING_CONFIG_FAILED;
7411 }
7412
7413 pim_ifp = ifp->info;
7414 if (no)
7415 pim_ifp->activeactive = false;
7416 else
7417 pim_ifp->activeactive = true;
7418
7419 return CMD_SUCCESS;
7420}
7421
d2772e7b 7422DEFUN_HIDDEN (interface_ip_pim_ssm,
981d6c7a
DS
7423 interface_ip_pim_ssm_cmd,
7424 "ip pim ssm",
7425 IP_STR
7426 PIM_STR
7427 IFACE_PIM_STR)
7428{
d62a17ae 7429 VTY_DECLVAR_CONTEXT(interface, ifp);
981d6c7a 7430
d62a17ae 7431 if (!pim_cmd_interface_add(ifp)) {
7432 vty_out(vty, "Could not enable PIM SM on interface\n");
7433 return CMD_WARNING_CONFIG_FAILED;
7434 }
981d6c7a 7435
d62a17ae 7436 vty_out(vty,
7437 "WARN: Enabled PIM SM on interface; configure PIM SSM "
7438 "range if needed\n");
7439 return CMD_SUCCESS;
12e41d03
DL
7440}
7441
2f5e937c 7442static int interface_ip_pim_helper(struct vty *vty)
12e41d03 7443{
43e40fdf
DS
7444 struct pim_interface *pim_ifp;
7445
d62a17ae 7446 VTY_DECLVAR_CONTEXT(interface, ifp);
2f5e937c 7447
d62a17ae 7448 if (!pim_cmd_interface_add(ifp)) {
7449 vty_out(vty, "Could not enable PIM SM on interface\n");
7450 return CMD_WARNING_CONFIG_FAILED;
7451 }
981d6c7a 7452
43e40fdf 7453 pim_ifp = ifp->info;
ecca97ac 7454
43e40fdf 7455 pim_if_create_pimreg(pim_ifp->pim);
c992c9a0 7456
d62a17ae 7457 return CMD_SUCCESS;
981d6c7a
DS
7458}
7459
2f5e937c 7460DEFUN_HIDDEN (interface_ip_pim_sm,
7461 interface_ip_pim_sm_cmd,
7462 "ip pim sm",
7463 IP_STR
7464 PIM_STR
7465 IFACE_PIM_SM_STR)
7466{
7467 return interface_ip_pim_helper(vty);
7468}
7469
7470DEFUN (interface_ip_pim,
7471 interface_ip_pim_cmd,
7472 "ip pim",
7473 IP_STR
7474 PIM_STR)
7475{
7476 return interface_ip_pim_helper(vty);
7477}
7478
d62a17ae 7479static int pim_cmd_interface_delete(struct interface *ifp)
981d6c7a 7480{
d62a17ae 7481 struct pim_interface *pim_ifp = ifp->info;
981d6c7a 7482
d62a17ae 7483 if (!pim_ifp)
7484 return 1;
12e41d03 7485
d62a17ae 7486 PIM_IF_DONT_PIM(pim_ifp->options);
12e41d03 7487
d62a17ae 7488 pim_if_membership_clear(ifp);
12e41d03 7489
d62a17ae 7490 /*
7491 pim_sock_delete() removes all neighbors from
7492 pim_ifp->pim_neighbor_list.
7493 */
7494 pim_sock_delete(ifp, "pim unconfigured on interface");
12e41d03 7495
d62a17ae 7496 if (!PIM_IF_TEST_IGMP(pim_ifp->options)) {
7497 pim_if_addr_del_all(ifp);
7498 pim_if_delete(ifp);
7499 }
12e41d03 7500
d62a17ae 7501 return 1;
981d6c7a
DS
7502}
7503
2f5e937c 7504static int interface_no_ip_pim_helper(struct vty *vty)
7505{
eccdcfe2
SP
7506 VTY_DECLVAR_CONTEXT(interface, ifp);
7507 if (!pim_cmd_interface_delete(ifp)) {
7508 vty_out(vty, "Unable to delete interface information\n");
7509 return CMD_WARNING_CONFIG_FAILED;
7510 }
2f5e937c 7511
eccdcfe2 7512 return CMD_SUCCESS;
2f5e937c 7513}
7514
d2772e7b 7515DEFUN_HIDDEN (interface_no_ip_pim_ssm,
981d6c7a
DS
7516 interface_no_ip_pim_ssm_cmd,
7517 "no ip pim ssm",
7518 NO_STR
7519 IP_STR
7520 PIM_STR
7521 IFACE_PIM_STR)
7522{
2f5e937c 7523 return interface_no_ip_pim_helper(vty);
981d6c7a
DS
7524}
7525
2f5e937c 7526DEFUN_HIDDEN (interface_no_ip_pim_sm,
981d6c7a
DS
7527 interface_no_ip_pim_sm_cmd,
7528 "no ip pim sm",
7529 NO_STR
7530 IP_STR
7531 PIM_STR
8371bd60 7532 IFACE_PIM_SM_STR)
981d6c7a 7533{
2f5e937c 7534 return interface_no_ip_pim_helper(vty);
7535}
981d6c7a 7536
2f5e937c 7537DEFUN (interface_no_ip_pim,
7538 interface_no_ip_pim_cmd,
7539 "no ip pim",
7540 NO_STR
7541 IP_STR
7542 PIM_STR)
7543{
7544 return interface_no_ip_pim_helper(vty);
12e41d03
DL
7545}
7546
b0f525a8
QY
7547/* boundaries */
7548DEFUN(interface_ip_pim_boundary_oil,
7549 interface_ip_pim_boundary_oil_cmd,
7550 "ip multicast boundary oil WORD",
7551 IP_STR
7552 "Generic multicast configuration options\n"
7553 "Define multicast boundary\n"
7554 "Filter OIL by group using prefix list\n"
513c8462 7555 "Prefix list to filter OIL with\n")
b0f525a8
QY
7556{
7557 VTY_DECLVAR_CONTEXT(interface, iif);
7558 struct pim_interface *pim_ifp;
7559 int idx = 0;
7560
7561 argv_find(argv, argc, "WORD", &idx);
7562
7563 PIM_GET_PIM_INTERFACE(pim_ifp, iif);
7564
7565 if (pim_ifp->boundary_oil_plist)
7566 XFREE(MTYPE_PIM_INTERFACE, pim_ifp->boundary_oil_plist);
7567
7568 pim_ifp->boundary_oil_plist =
7569 XSTRDUP(MTYPE_PIM_INTERFACE, argv[idx]->arg);
7570
7571 /* Interface will be pruned from OIL on next Join */
7572 return CMD_SUCCESS;
7573}
7574
7575DEFUN(interface_no_ip_pim_boundary_oil,
7576 interface_no_ip_pim_boundary_oil_cmd,
7577 "no ip multicast boundary oil [WORD]",
7578 NO_STR
7579 IP_STR
7580 "Generic multicast configuration options\n"
7581 "Define multicast boundary\n"
7582 "Filter OIL by group using prefix list\n"
513c8462 7583 "Prefix list to filter OIL with\n")
b0f525a8
QY
7584{
7585 VTY_DECLVAR_CONTEXT(interface, iif);
7586 struct pim_interface *pim_ifp;
be1d57fc 7587 int idx = 0;
b0f525a8
QY
7588
7589 argv_find(argv, argc, "WORD", &idx);
7590
7591 PIM_GET_PIM_INTERFACE(pim_ifp, iif);
7592
7593 if (pim_ifp->boundary_oil_plist)
7594 XFREE(MTYPE_PIM_INTERFACE, pim_ifp->boundary_oil_plist);
7595
7596 return CMD_SUCCESS;
7597}
7598
6250610a
JAG
7599DEFUN (interface_ip_mroute,
7600 interface_ip_mroute_cmd,
7601 "ip mroute INTERFACE A.B.C.D",
7602 IP_STR
7603 "Add multicast route\n"
7604 "Outgoing interface name\n"
7605 "Group address\n")
7606{
d62a17ae 7607 VTY_DECLVAR_CONTEXT(interface, iif);
4e0bc0f0
DS
7608 struct pim_interface *pim_ifp;
7609 struct pim_instance *pim;
d62a17ae 7610 int idx_interface = 2;
7611 int idx_ipv4 = 3;
7612 struct interface *oif;
7613 const char *oifname;
7614 const char *grp_str;
7615 struct in_addr grp_addr;
7616 struct in_addr src_addr;
7617 int result;
7618
21b3e44e 7619 PIM_GET_PIM_INTERFACE(pim_ifp, iif);
4e0bc0f0
DS
7620 pim = pim_ifp->pim;
7621
d62a17ae 7622 oifname = argv[idx_interface]->arg;
4e0bc0f0 7623 oif = if_lookup_by_name(oifname, pim->vrf_id);
d62a17ae 7624 if (!oif) {
7625 vty_out(vty, "No such interface name %s\n", oifname);
4e0bc0f0 7626 return CMD_WARNING;
d62a17ae 7627 }
7628
7629 grp_str = argv[idx_ipv4]->arg;
7630 result = inet_pton(AF_INET, grp_str, &grp_addr);
7631 if (result <= 0) {
7632 vty_out(vty, "Bad group address %s: errno=%d: %s\n", grp_str,
7633 errno, safe_strerror(errno));
4e0bc0f0 7634 return CMD_WARNING;
d62a17ae 7635 }
7636
7637 src_addr.s_addr = INADDR_ANY;
7638
4e0bc0f0 7639 if (pim_static_add(pim, iif, oif, grp_addr, src_addr)) {
d62a17ae 7640 vty_out(vty, "Failed to add route\n");
4e0bc0f0 7641 return CMD_WARNING;
d62a17ae 7642 }
7643
7644 return CMD_SUCCESS;
6250610a
JAG
7645}
7646
7647DEFUN (interface_ip_mroute_source,
7648 interface_ip_mroute_source_cmd,
7649 "ip mroute INTERFACE A.B.C.D A.B.C.D",
7650 IP_STR
7651 "Add multicast route\n"
7652 "Outgoing interface name\n"
7653 "Group address\n"
7654 "Source address\n")
7655{
d62a17ae 7656 VTY_DECLVAR_CONTEXT(interface, iif);
4e0bc0f0
DS
7657 struct pim_interface *pim_ifp;
7658 struct pim_instance *pim;
d62a17ae 7659 int idx_interface = 2;
7660 int idx_ipv4 = 3;
7661 int idx_ipv4_2 = 4;
7662 struct interface *oif;
7663 const char *oifname;
7664 const char *grp_str;
7665 struct in_addr grp_addr;
7666 const char *src_str;
7667 struct in_addr src_addr;
7668 int result;
7669
21b3e44e 7670 PIM_GET_PIM_INTERFACE(pim_ifp, iif);
4e0bc0f0
DS
7671 pim = pim_ifp->pim;
7672
d62a17ae 7673 oifname = argv[idx_interface]->arg;
4e0bc0f0 7674 oif = if_lookup_by_name(oifname, pim->vrf_id);
d62a17ae 7675 if (!oif) {
7676 vty_out(vty, "No such interface name %s\n", oifname);
4e0bc0f0 7677 return CMD_WARNING;
d62a17ae 7678 }
7679
7680 grp_str = argv[idx_ipv4]->arg;
7681 result = inet_pton(AF_INET, grp_str, &grp_addr);
7682 if (result <= 0) {
7683 vty_out(vty, "Bad group address %s: errno=%d: %s\n", grp_str,
7684 errno, safe_strerror(errno));
4e0bc0f0 7685 return CMD_WARNING;
d62a17ae 7686 }
7687
7688 src_str = argv[idx_ipv4_2]->arg;
7689 result = inet_pton(AF_INET, src_str, &src_addr);
7690 if (result <= 0) {
7691 vty_out(vty, "Bad source address %s: errno=%d: %s\n", src_str,
7692 errno, safe_strerror(errno));
4e0bc0f0 7693 return CMD_WARNING;
d62a17ae 7694 }
7695
4e0bc0f0 7696 if (pim_static_add(pim, iif, oif, grp_addr, src_addr)) {
d62a17ae 7697 vty_out(vty, "Failed to add route\n");
4e0bc0f0 7698 return CMD_WARNING;
d62a17ae 7699 }
7700
7701 return CMD_SUCCESS;
6250610a
JAG
7702}
7703
7704DEFUN (interface_no_ip_mroute,
7705 interface_no_ip_mroute_cmd,
7706 "no ip mroute INTERFACE A.B.C.D",
7707 NO_STR
7708 IP_STR
7709 "Add multicast route\n"
7710 "Outgoing interface name\n"
7711 "Group Address\n")
7712{
d62a17ae 7713 VTY_DECLVAR_CONTEXT(interface, iif);
4e0bc0f0
DS
7714 struct pim_interface *pim_ifp;
7715 struct pim_instance *pim;
d62a17ae 7716 int idx_interface = 3;
7717 int idx_ipv4 = 4;
7718 struct interface *oif;
7719 const char *oifname;
7720 const char *grp_str;
7721 struct in_addr grp_addr;
7722 struct in_addr src_addr;
7723 int result;
7724
21b3e44e 7725 PIM_GET_PIM_INTERFACE(pim_ifp, iif);
4e0bc0f0
DS
7726 pim = pim_ifp->pim;
7727
d62a17ae 7728 oifname = argv[idx_interface]->arg;
4e0bc0f0 7729 oif = if_lookup_by_name(oifname, pim->vrf_id);
d62a17ae 7730 if (!oif) {
7731 vty_out(vty, "No such interface name %s\n", oifname);
4e0bc0f0 7732 return CMD_WARNING;
d62a17ae 7733 }
7734
7735 grp_str = argv[idx_ipv4]->arg;
7736 result = inet_pton(AF_INET, grp_str, &grp_addr);
7737 if (result <= 0) {
7738 vty_out(vty, "Bad group address %s: errno=%d: %s\n", grp_str,
7739 errno, safe_strerror(errno));
4e0bc0f0 7740 return CMD_WARNING;
d62a17ae 7741 }
7742
7743 src_addr.s_addr = INADDR_ANY;
7744
4e0bc0f0 7745 if (pim_static_del(pim, iif, oif, grp_addr, src_addr)) {
d62a17ae 7746 vty_out(vty, "Failed to remove route\n");
4e0bc0f0 7747 return CMD_WARNING;
d62a17ae 7748 }
7749
7750 return CMD_SUCCESS;
6250610a
JAG
7751}
7752
7753DEFUN (interface_no_ip_mroute_source,
7754 interface_no_ip_mroute_source_cmd,
7755 "no ip mroute INTERFACE A.B.C.D A.B.C.D",
7756 NO_STR
7757 IP_STR
7758 "Add multicast route\n"
7759 "Outgoing interface name\n"
7760 "Group Address\n"
7761 "Source Address\n")
7762{
d62a17ae 7763 VTY_DECLVAR_CONTEXT(interface, iif);
4e0bc0f0
DS
7764 struct pim_interface *pim_ifp;
7765 struct pim_instance *pim;
d62a17ae 7766 int idx_interface = 3;
7767 int idx_ipv4 = 4;
7768 int idx_ipv4_2 = 5;
7769 struct interface *oif;
7770 const char *oifname;
7771 const char *grp_str;
7772 struct in_addr grp_addr;
7773 const char *src_str;
7774 struct in_addr src_addr;
7775 int result;
7776
21b3e44e 7777 PIM_GET_PIM_INTERFACE(pim_ifp, iif);
4e0bc0f0
DS
7778 pim = pim_ifp->pim;
7779
d62a17ae 7780 oifname = argv[idx_interface]->arg;
4e0bc0f0 7781 oif = if_lookup_by_name(oifname, pim->vrf_id);
d62a17ae 7782 if (!oif) {
7783 vty_out(vty, "No such interface name %s\n", oifname);
4e0bc0f0 7784 return CMD_WARNING;
d62a17ae 7785 }
7786
7787 grp_str = argv[idx_ipv4]->arg;
7788 result = inet_pton(AF_INET, grp_str, &grp_addr);
7789 if (result <= 0) {
7790 vty_out(vty, "Bad group address %s: errno=%d: %s\n", grp_str,
7791 errno, safe_strerror(errno));
4e0bc0f0 7792 return CMD_WARNING;
d62a17ae 7793 }
7794
7795 src_str = argv[idx_ipv4_2]->arg;
7796 result = inet_pton(AF_INET, src_str, &src_addr);
7797 if (result <= 0) {
7798 vty_out(vty, "Bad source address %s: errno=%d: %s\n", src_str,
7799 errno, safe_strerror(errno));
4e0bc0f0 7800 return CMD_WARNING;
d62a17ae 7801 }
7802
4e0bc0f0 7803 if (pim_static_del(pim, iif, oif, grp_addr, src_addr)) {
d62a17ae 7804 vty_out(vty, "Failed to remove route\n");
4e0bc0f0 7805 return CMD_WARNING;
d62a17ae 7806 }
7807
7808 return CMD_SUCCESS;
6250610a
JAG
7809}
7810
7960fa8f
DS
7811DEFUN (interface_ip_pim_hello,
7812 interface_ip_pim_hello_cmd,
80d3d26b 7813 "ip pim hello (1-180) [(1-180)]",
7960fa8f
DS
7814 IP_STR
7815 PIM_STR
7816 IFACE_PIM_HELLO_STR
80d3d26b
DW
7817 IFACE_PIM_HELLO_TIME_STR
7818 IFACE_PIM_HELLO_HOLD_STR)
7960fa8f 7819{
d62a17ae 7820 VTY_DECLVAR_CONTEXT(interface, ifp);
7821 int idx_time = 3;
7822 int idx_hold = 4;
7823 struct pim_interface *pim_ifp = ifp->info;
7960fa8f 7824
d62a17ae 7825 if (!pim_ifp) {
7826 if (!pim_cmd_interface_add(ifp)) {
7827 vty_out(vty, "Could not enable PIM SM on interface\n");
7828 return CMD_WARNING_CONFIG_FAILED;
7829 }
7830 }
7960fa8f 7831
d62a17ae 7832 pim_ifp = ifp->info;
7833 pim_ifp->pim_hello_period = strtol(argv[idx_time]->arg, NULL, 10);
7960fa8f 7834
d62a17ae 7835 if (argc == idx_hold + 1)
7836 pim_ifp->pim_default_holdtime =
7837 strtol(argv[idx_hold]->arg, NULL, 10);
7960fa8f 7838
d62a17ae 7839 return CMD_SUCCESS;
7960fa8f
DS
7840}
7841
7960fa8f
DS
7842DEFUN (interface_no_ip_pim_hello,
7843 interface_no_ip_pim_hello_cmd,
b181fa04 7844 "no ip pim hello [(1-180) (1-180)]",
7960fa8f
DS
7845 NO_STR
7846 IP_STR
7847 PIM_STR
7848 IFACE_PIM_HELLO_STR
7849 IFACE_PIM_HELLO_TIME_STR
7850 IFACE_PIM_HELLO_HOLD_STR)
7851{
d62a17ae 7852 VTY_DECLVAR_CONTEXT(interface, ifp);
7853 struct pim_interface *pim_ifp = ifp->info;
7960fa8f 7854
d62a17ae 7855 if (!pim_ifp) {
7856 vty_out(vty, "Pim not enabled on this interface\n");
7857 return CMD_WARNING_CONFIG_FAILED;
7858 }
7960fa8f 7859
d62a17ae 7860 pim_ifp->pim_hello_period = PIM_DEFAULT_HELLO_PERIOD;
7861 pim_ifp->pim_default_holdtime = -1;
7960fa8f 7862
d62a17ae 7863 return CMD_SUCCESS;
7960fa8f
DS
7864}
7865
12e41d03
DL
7866DEFUN (debug_igmp,
7867 debug_igmp_cmd,
7868 "debug igmp",
7869 DEBUG_STR
7870 DEBUG_IGMP_STR)
7871{
d62a17ae 7872 PIM_DO_DEBUG_IGMP_EVENTS;
7873 PIM_DO_DEBUG_IGMP_PACKETS;
7874 PIM_DO_DEBUG_IGMP_TRACE;
7875 return CMD_SUCCESS;
12e41d03
DL
7876}
7877
7878DEFUN (no_debug_igmp,
7879 no_debug_igmp_cmd,
7880 "no debug igmp",
7881 NO_STR
7882 DEBUG_STR
7883 DEBUG_IGMP_STR)
7884{
d62a17ae 7885 PIM_DONT_DEBUG_IGMP_EVENTS;
7886 PIM_DONT_DEBUG_IGMP_PACKETS;
7887 PIM_DONT_DEBUG_IGMP_TRACE;
7888 return CMD_SUCCESS;
12e41d03
DL
7889}
7890
12e41d03
DL
7891
7892DEFUN (debug_igmp_events,
7893 debug_igmp_events_cmd,
7894 "debug igmp events",
7895 DEBUG_STR
7896 DEBUG_IGMP_STR
7897 DEBUG_IGMP_EVENTS_STR)
7898{
d62a17ae 7899 PIM_DO_DEBUG_IGMP_EVENTS;
7900 return CMD_SUCCESS;
12e41d03
DL
7901}
7902
7903DEFUN (no_debug_igmp_events,
7904 no_debug_igmp_events_cmd,
7905 "no debug igmp events",
7906 NO_STR
7907 DEBUG_STR
7908 DEBUG_IGMP_STR
7909 DEBUG_IGMP_EVENTS_STR)
7910{
d62a17ae 7911 PIM_DONT_DEBUG_IGMP_EVENTS;
7912 return CMD_SUCCESS;
12e41d03
DL
7913}
7914
12e41d03
DL
7915
7916DEFUN (debug_igmp_packets,
7917 debug_igmp_packets_cmd,
7918 "debug igmp packets",
7919 DEBUG_STR
7920 DEBUG_IGMP_STR
7921 DEBUG_IGMP_PACKETS_STR)
7922{
d62a17ae 7923 PIM_DO_DEBUG_IGMP_PACKETS;
7924 return CMD_SUCCESS;
12e41d03
DL
7925}
7926
7927DEFUN (no_debug_igmp_packets,
7928 no_debug_igmp_packets_cmd,
7929 "no debug igmp packets",
7930 NO_STR
7931 DEBUG_STR
7932 DEBUG_IGMP_STR
7933 DEBUG_IGMP_PACKETS_STR)
7934{
d62a17ae 7935 PIM_DONT_DEBUG_IGMP_PACKETS;
7936 return CMD_SUCCESS;
12e41d03
DL
7937}
7938
12e41d03
DL
7939
7940DEFUN (debug_igmp_trace,
7941 debug_igmp_trace_cmd,
7942 "debug igmp trace",
7943 DEBUG_STR
7944 DEBUG_IGMP_STR
7945 DEBUG_IGMP_TRACE_STR)
7946{
d62a17ae 7947 PIM_DO_DEBUG_IGMP_TRACE;
7948 return CMD_SUCCESS;
12e41d03
DL
7949}
7950
7951DEFUN (no_debug_igmp_trace,
7952 no_debug_igmp_trace_cmd,
7953 "no debug igmp trace",
7954 NO_STR
7955 DEBUG_STR
7956 DEBUG_IGMP_STR
7957 DEBUG_IGMP_TRACE_STR)
7958{
d62a17ae 7959 PIM_DONT_DEBUG_IGMP_TRACE;
7960 return CMD_SUCCESS;
12e41d03
DL
7961}
7962
12e41d03
DL
7963
7964DEFUN (debug_mroute,
7965 debug_mroute_cmd,
7966 "debug mroute",
7967 DEBUG_STR
7968 DEBUG_MROUTE_STR)
7969{
d62a17ae 7970 PIM_DO_DEBUG_MROUTE;
7971 return CMD_SUCCESS;
12e41d03
DL
7972}
7973
6c7197b1
DS
7974DEFUN (debug_mroute_detail,
7975 debug_mroute_detail_cmd,
7976 "debug mroute detail",
7977 DEBUG_STR
7978 DEBUG_MROUTE_STR
7979 "detailed\n")
7980{
d62a17ae 7981 PIM_DO_DEBUG_MROUTE_DETAIL;
7982 return CMD_SUCCESS;
6c7197b1
DS
7983}
7984
12e41d03
DL
7985DEFUN (no_debug_mroute,
7986 no_debug_mroute_cmd,
7987 "no debug mroute",
7988 NO_STR
7989 DEBUG_STR
7990 DEBUG_MROUTE_STR)
7991{
d62a17ae 7992 PIM_DONT_DEBUG_MROUTE;
7993 return CMD_SUCCESS;
12e41d03
DL
7994}
7995
6c7197b1
DS
7996DEFUN (no_debug_mroute_detail,
7997 no_debug_mroute_detail_cmd,
7998 "no debug mroute detail",
7999 NO_STR
8000 DEBUG_STR
8001 DEBUG_MROUTE_STR
8002 "detailed\n")
8003{
d62a17ae 8004 PIM_DONT_DEBUG_MROUTE_DETAIL;
8005 return CMD_SUCCESS;
6c7197b1 8006}
12e41d03 8007
35a12720
MS
8008DEFUN (debug_pim_static,
8009 debug_pim_static_cmd,
8010 "debug pim static",
6250610a 8011 DEBUG_STR
35a12720 8012 DEBUG_PIM_STR
6250610a
JAG
8013 DEBUG_STATIC_STR)
8014{
d62a17ae 8015 PIM_DO_DEBUG_STATIC;
8016 return CMD_SUCCESS;
6250610a
JAG
8017}
8018
35a12720
MS
8019DEFUN (no_debug_pim_static,
8020 no_debug_pim_static_cmd,
8021 "no debug pim static",
6250610a
JAG
8022 NO_STR
8023 DEBUG_STR
35a12720 8024 DEBUG_PIM_STR
6250610a
JAG
8025 DEBUG_STATIC_STR)
8026{
d62a17ae 8027 PIM_DONT_DEBUG_STATIC;
8028 return CMD_SUCCESS;
6250610a
JAG
8029}
8030
6250610a 8031
12e41d03
DL
8032DEFUN (debug_pim,
8033 debug_pim_cmd,
8034 "debug pim",
8035 DEBUG_STR
8036 DEBUG_PIM_STR)
8037{
d62a17ae 8038 PIM_DO_DEBUG_PIM_EVENTS;
8039 PIM_DO_DEBUG_PIM_PACKETS;
8040 PIM_DO_DEBUG_PIM_TRACE;
8041 PIM_DO_DEBUG_MSDP_EVENTS;
8042 PIM_DO_DEBUG_MSDP_PACKETS;
09524ccf 8043 PIM_DO_DEBUG_BSM;
d62a17ae 8044 return CMD_SUCCESS;
12e41d03
DL
8045}
8046
8047DEFUN (no_debug_pim,
8048 no_debug_pim_cmd,
8049 "no debug pim",
8050 NO_STR
8051 DEBUG_STR
8052 DEBUG_PIM_STR)
8053{
d62a17ae 8054 PIM_DONT_DEBUG_PIM_EVENTS;
8055 PIM_DONT_DEBUG_PIM_PACKETS;
8056 PIM_DONT_DEBUG_PIM_TRACE;
8057 PIM_DONT_DEBUG_MSDP_EVENTS;
8058 PIM_DONT_DEBUG_MSDP_PACKETS;
12e41d03 8059
d62a17ae 8060 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND;
8061 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV;
09524ccf 8062 PIM_DONT_DEBUG_BSM;
12e41d03 8063
d62a17ae 8064 return CMD_SUCCESS;
12e41d03
DL
8065}
8066
40f1f31b
DS
8067DEFUN (debug_pim_nht,
8068 debug_pim_nht_cmd,
8069 "debug pim nht",
8070 DEBUG_STR
8071 DEBUG_PIM_STR
8072 "Nexthop Tracking\n")
8073{
8074 PIM_DO_DEBUG_PIM_NHT;
8075 return CMD_SUCCESS;
8076}
8077
8078DEFUN (no_debug_pim_nht,
8079 no_debug_pim_nht_cmd,
8080 "no debug pim nht",
8081 NO_STR
8082 DEBUG_STR
8083 DEBUG_PIM_STR
8084 "Nexthop Tracking\n")
8085{
8086 PIM_DONT_DEBUG_PIM_NHT;
8087 return CMD_SUCCESS;
8088}
12e41d03 8089
3d225d48
DS
8090DEFUN (debug_pim_nht_rp,
8091 debug_pim_nht_rp_cmd,
8092 "debug pim nht rp",
8093 DEBUG_STR
8094 DEBUG_PIM_STR
8095 "Nexthop Tracking\n"
8096 "RP Nexthop Tracking\n")
8097{
8098 PIM_DO_DEBUG_PIM_NHT_RP;
8099 return CMD_SUCCESS;
8100}
8101
8102DEFUN (no_debug_pim_nht_rp,
8103 no_debug_pim_nht_rp_cmd,
8104 "no debug pim nht rp",
8105 NO_STR
8106 DEBUG_STR
8107 DEBUG_PIM_STR
8108 "Nexthop Tracking\n"
8109 "RP Nexthop Tracking\n")
8110{
8111 PIM_DONT_DEBUG_PIM_NHT_RP;
8112 return CMD_SUCCESS;
8113}
8114
12e41d03
DL
8115DEFUN (debug_pim_events,
8116 debug_pim_events_cmd,
8117 "debug pim events",
8118 DEBUG_STR
8119 DEBUG_PIM_STR
8120 DEBUG_PIM_EVENTS_STR)
8121{
d62a17ae 8122 PIM_DO_DEBUG_PIM_EVENTS;
8123 return CMD_SUCCESS;
12e41d03
DL
8124}
8125
8126DEFUN (no_debug_pim_events,
8127 no_debug_pim_events_cmd,
8128 "no debug pim events",
8129 NO_STR
8130 DEBUG_STR
8131 DEBUG_PIM_STR
8132 DEBUG_PIM_EVENTS_STR)
8133{
d62a17ae 8134 PIM_DONT_DEBUG_PIM_EVENTS;
8135 return CMD_SUCCESS;
12e41d03
DL
8136}
8137
12e41d03
DL
8138DEFUN (debug_pim_packets,
8139 debug_pim_packets_cmd,
a957a05b 8140 "debug pim packets [<hello|joins|register>]",
12e41d03
DL
8141 DEBUG_STR
8142 DEBUG_PIM_STR
8143 DEBUG_PIM_PACKETS_STR
8144 DEBUG_PIM_HELLO_PACKETS_STR
9add3b88
DS
8145 DEBUG_PIM_J_P_PACKETS_STR
8146 DEBUG_PIM_PIM_REG_PACKETS_STR)
12e41d03 8147{
d62a17ae 8148 int idx = 0;
8149 if (argv_find(argv, argc, "hello", &idx)) {
8150 PIM_DO_DEBUG_PIM_HELLO;
8151 vty_out(vty, "PIM Hello debugging is on\n");
8152 } else if (argv_find(argv, argc, "joins", &idx)) {
8153 PIM_DO_DEBUG_PIM_J_P;
8154 vty_out(vty, "PIM Join/Prune debugging is on\n");
8155 } else if (argv_find(argv, argc, "register", &idx)) {
8156 PIM_DO_DEBUG_PIM_REG;
8157 vty_out(vty, "PIM Register debugging is on\n");
8158 } else {
8159 PIM_DO_DEBUG_PIM_PACKETS;
8160 vty_out(vty, "PIM Packet debugging is on \n");
8161 }
8162 return CMD_SUCCESS;
12e41d03
DL
8163}
8164
8165DEFUN (no_debug_pim_packets,
8166 no_debug_pim_packets_cmd,
a957a05b 8167 "no debug pim packets [<hello|joins|register>]",
12e41d03
DL
8168 NO_STR
8169 DEBUG_STR
8170 DEBUG_PIM_STR
8171 DEBUG_PIM_PACKETS_STR
8172 DEBUG_PIM_HELLO_PACKETS_STR
a957a05b
DS
8173 DEBUG_PIM_J_P_PACKETS_STR
8174 DEBUG_PIM_PIM_REG_PACKETS_STR)
12e41d03 8175{
d62a17ae 8176 int idx = 0;
8177 if (argv_find(argv, argc, "hello", &idx)) {
8178 PIM_DONT_DEBUG_PIM_HELLO;
8179 vty_out(vty, "PIM Hello debugging is off \n");
8180 } else if (argv_find(argv, argc, "joins", &idx)) {
8181 PIM_DONT_DEBUG_PIM_J_P;
8182 vty_out(vty, "PIM Join/Prune debugging is off \n");
8183 } else if (argv_find(argv, argc, "register", &idx)) {
8184 PIM_DONT_DEBUG_PIM_REG;
8185 vty_out(vty, "PIM Register debugging is off\n");
8186 } else
8187 PIM_DONT_DEBUG_PIM_PACKETS;
8188
8189 return CMD_SUCCESS;
12e41d03
DL
8190}
8191
12e41d03
DL
8192
8193DEFUN (debug_pim_packetdump_send,
8194 debug_pim_packetdump_send_cmd,
8195 "debug pim packet-dump send",
8196 DEBUG_STR
8197 DEBUG_PIM_STR
8198 DEBUG_PIM_PACKETDUMP_STR
8199 DEBUG_PIM_PACKETDUMP_SEND_STR)
8200{
d62a17ae 8201 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND;
8202 return CMD_SUCCESS;
12e41d03
DL
8203}
8204
8205DEFUN (no_debug_pim_packetdump_send,
8206 no_debug_pim_packetdump_send_cmd,
8207 "no debug pim packet-dump send",
8208 NO_STR
8209 DEBUG_STR
8210 DEBUG_PIM_STR
8211 DEBUG_PIM_PACKETDUMP_STR
8212 DEBUG_PIM_PACKETDUMP_SEND_STR)
8213{
d62a17ae 8214 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND;
8215 return CMD_SUCCESS;
12e41d03
DL
8216}
8217
12e41d03
DL
8218DEFUN (debug_pim_packetdump_recv,
8219 debug_pim_packetdump_recv_cmd,
8220 "debug pim packet-dump receive",
8221 DEBUG_STR
8222 DEBUG_PIM_STR
8223 DEBUG_PIM_PACKETDUMP_STR
8224 DEBUG_PIM_PACKETDUMP_RECV_STR)
8225{
d62a17ae 8226 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV;
8227 return CMD_SUCCESS;
12e41d03
DL
8228}
8229
8230DEFUN (no_debug_pim_packetdump_recv,
8231 no_debug_pim_packetdump_recv_cmd,
8232 "no debug pim packet-dump receive",
8233 NO_STR
8234 DEBUG_STR
8235 DEBUG_PIM_STR
8236 DEBUG_PIM_PACKETDUMP_STR
8237 DEBUG_PIM_PACKETDUMP_RECV_STR)
8238{
d62a17ae 8239 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV;
8240 return CMD_SUCCESS;
12e41d03
DL
8241}
8242
12e41d03
DL
8243DEFUN (debug_pim_trace,
8244 debug_pim_trace_cmd,
8245 "debug pim trace",
8246 DEBUG_STR
8247 DEBUG_PIM_STR
8248 DEBUG_PIM_TRACE_STR)
8249{
d62a17ae 8250 PIM_DO_DEBUG_PIM_TRACE;
8251 return CMD_SUCCESS;
12e41d03
DL
8252}
8253
56c238c9
DS
8254DEFUN (debug_pim_trace_detail,
8255 debug_pim_trace_detail_cmd,
8256 "debug pim trace detail",
8257 DEBUG_STR
8258 DEBUG_PIM_STR
5f40dada
DS
8259 DEBUG_PIM_TRACE_STR
8260 "Detailed Information\n")
56c238c9
DS
8261{
8262 PIM_DO_DEBUG_PIM_TRACE_DETAIL;
8263 return CMD_SUCCESS;
8264}
8265
12e41d03
DL
8266DEFUN (no_debug_pim_trace,
8267 no_debug_pim_trace_cmd,
8268 "no debug pim trace",
8269 NO_STR
8270 DEBUG_STR
8271 DEBUG_PIM_STR
8272 DEBUG_PIM_TRACE_STR)
8273{
d62a17ae 8274 PIM_DONT_DEBUG_PIM_TRACE;
8275 return CMD_SUCCESS;
12e41d03
DL
8276}
8277
56c238c9
DS
8278DEFUN (no_debug_pim_trace_detail,
8279 no_debug_pim_trace_detail_cmd,
9853a7a5 8280 "no debug pim trace detail",
56c238c9
DS
8281 NO_STR
8282 DEBUG_STR
8283 DEBUG_PIM_STR
bd4d05c5
DS
8284 DEBUG_PIM_TRACE_STR
8285 "Detailed Information\n")
56c238c9
DS
8286{
8287 PIM_DONT_DEBUG_PIM_TRACE_DETAIL;
8288 return CMD_SUCCESS;
8289}
8290
12e41d03
DL
8291DEFUN (debug_ssmpingd,
8292 debug_ssmpingd_cmd,
8293 "debug ssmpingd",
8294 DEBUG_STR
12e41d03
DL
8295 DEBUG_SSMPINGD_STR)
8296{
d62a17ae 8297 PIM_DO_DEBUG_SSMPINGD;
8298 return CMD_SUCCESS;
12e41d03
DL
8299}
8300
8301DEFUN (no_debug_ssmpingd,
8302 no_debug_ssmpingd_cmd,
8303 "no debug ssmpingd",
8304 NO_STR
8305 DEBUG_STR
12e41d03
DL
8306 DEBUG_SSMPINGD_STR)
8307{
d62a17ae 8308 PIM_DONT_DEBUG_SSMPINGD;
8309 return CMD_SUCCESS;
12e41d03
DL
8310}
8311
12e41d03
DL
8312DEFUN (debug_pim_zebra,
8313 debug_pim_zebra_cmd,
8314 "debug pim zebra",
8315 DEBUG_STR
8316 DEBUG_PIM_STR
8317 DEBUG_PIM_ZEBRA_STR)
8318{
d62a17ae 8319 PIM_DO_DEBUG_ZEBRA;
8320 return CMD_SUCCESS;
12e41d03
DL
8321}
8322
8323DEFUN (no_debug_pim_zebra,
8324 no_debug_pim_zebra_cmd,
8325 "no debug pim zebra",
8326 NO_STR
8327 DEBUG_STR
8328 DEBUG_PIM_STR
8329 DEBUG_PIM_ZEBRA_STR)
8330{
d62a17ae 8331 PIM_DONT_DEBUG_ZEBRA;
8332 return CMD_SUCCESS;
12e41d03
DL
8333}
8334
4d913fa6
AK
8335DEFUN (debug_pim_vxlan,
8336 debug_pim_vxlan_cmd,
8337 "debug pim vxlan",
8338 DEBUG_STR
8339 DEBUG_PIM_STR
8340 DEBUG_PIM_VXLAN_STR)
8341{
8342 PIM_DO_DEBUG_VXLAN;
8343 return CMD_SUCCESS;
8344}
8345
8346DEFUN (no_debug_pim_vxlan,
8347 no_debug_pim_vxlan_cmd,
8348 "no debug pim vxlan",
8349 NO_STR
8350 DEBUG_STR
8351 DEBUG_PIM_STR
8352 DEBUG_PIM_VXLAN_STR)
8353{
8354 PIM_DONT_DEBUG_VXLAN;
8355 return CMD_SUCCESS;
8356}
8357
2a333e0f 8358DEFUN (debug_msdp,
8359 debug_msdp_cmd,
8360 "debug msdp",
8361 DEBUG_STR
8362 DEBUG_MSDP_STR)
8363{
d62a17ae 8364 PIM_DO_DEBUG_MSDP_EVENTS;
8365 PIM_DO_DEBUG_MSDP_PACKETS;
8366 return CMD_SUCCESS;
2a333e0f 8367}
8368
8369DEFUN (no_debug_msdp,
8370 no_debug_msdp_cmd,
8371 "no debug msdp",
8372 NO_STR
8373 DEBUG_STR
8374 DEBUG_MSDP_STR)
8375{
d62a17ae 8376 PIM_DONT_DEBUG_MSDP_EVENTS;
8377 PIM_DONT_DEBUG_MSDP_PACKETS;
8378 return CMD_SUCCESS;
2a333e0f 8379}
8380
2a333e0f 8381DEFUN (debug_msdp_events,
8382 debug_msdp_events_cmd,
8383 "debug msdp events",
8384 DEBUG_STR
8385 DEBUG_MSDP_STR
8386 DEBUG_MSDP_EVENTS_STR)
8387{
d62a17ae 8388 PIM_DO_DEBUG_MSDP_EVENTS;
8389 return CMD_SUCCESS;
2a333e0f 8390}
8391
8392DEFUN (no_debug_msdp_events,
8393 no_debug_msdp_events_cmd,
8394 "no debug msdp events",
8395 NO_STR
8396 DEBUG_STR
8397 DEBUG_MSDP_STR
8398 DEBUG_MSDP_EVENTS_STR)
8399{
d62a17ae 8400 PIM_DONT_DEBUG_MSDP_EVENTS;
8401 return CMD_SUCCESS;
2a333e0f 8402}
8403
2a333e0f 8404DEFUN (debug_msdp_packets,
8405 debug_msdp_packets_cmd,
8406 "debug msdp packets",
8407 DEBUG_STR
8408 DEBUG_MSDP_STR
8409 DEBUG_MSDP_PACKETS_STR)
8410{
d62a17ae 8411 PIM_DO_DEBUG_MSDP_PACKETS;
8412 return CMD_SUCCESS;
2a333e0f 8413}
8414
8415DEFUN (no_debug_msdp_packets,
8416 no_debug_msdp_packets_cmd,
8417 "no debug msdp packets",
8418 NO_STR
8419 DEBUG_STR
8420 DEBUG_MSDP_STR
8421 DEBUG_MSDP_PACKETS_STR)
8422{
d62a17ae 8423 PIM_DONT_DEBUG_MSDP_PACKETS;
8424 return CMD_SUCCESS;
2a333e0f 8425}
8426
4d9ad5dc
MS
8427DEFUN (debug_mtrace,
8428 debug_mtrace_cmd,
8429 "debug mtrace",
8430 DEBUG_STR
8431 DEBUG_MTRACE_STR)
8432{
8433 PIM_DO_DEBUG_MTRACE;
8434 return CMD_SUCCESS;
8435}
8436
8437DEFUN (no_debug_mtrace,
8438 no_debug_mtrace_cmd,
8439 "no debug mtrace",
8440 NO_STR
8441 DEBUG_STR
8442 DEBUG_MTRACE_STR)
8443{
8444 PIM_DONT_DEBUG_MTRACE;
8445 return CMD_SUCCESS;
8446}
8447
09524ccf 8448DEFUN (debug_bsm,
8449 debug_bsm_cmd,
8450 "debug pim bsm",
8451 DEBUG_STR
8452 DEBUG_PIM_STR
8453 DEBUG_PIM_BSM_STR)
8454{
8455 PIM_DO_DEBUG_BSM;
8456 return CMD_SUCCESS;
8457}
8458
8459DEFUN (no_debug_bsm,
8460 no_debug_bsm_cmd,
8461 "no debug pim bsm",
8462 NO_STR
8463 DEBUG_STR
8464 DEBUG_PIM_STR
8465 DEBUG_PIM_BSM_STR)
8466{
8467 PIM_DONT_DEBUG_BSM;
8468 return CMD_SUCCESS;
8469}
8470
8471
87f6dc50
DS
8472DEFUN_NOSH (show_debugging_pim,
8473 show_debugging_pim_cmd,
8474 "show debugging [pim]",
8475 SHOW_STR
8476 DEBUG_STR
8477 PIM_STR)
12e41d03 8478{
87f6dc50
DS
8479 vty_out(vty, "PIM debugging status\n");
8480
d62a17ae 8481 pim_debug_config_write(vty);
87f6dc50 8482
d62a17ae 8483 return CMD_SUCCESS;
12e41d03
DL
8484}
8485
d62a17ae 8486static int interface_pim_use_src_cmd_worker(struct vty *vty, const char *source)
4763cd0e 8487{
d62a17ae 8488 int result;
8489 struct in_addr source_addr;
23f1c68b 8490 int ret = CMD_SUCCESS;
d62a17ae 8491 VTY_DECLVAR_CONTEXT(interface, ifp);
4763cd0e 8492
d62a17ae 8493 result = inet_pton(AF_INET, source, &source_addr);
8494 if (result <= 0) {
8495 vty_out(vty, "%% Bad source address %s: errno=%d: %s\n", source,
8496 errno, safe_strerror(errno));
8497 return CMD_WARNING_CONFIG_FAILED;
8498 }
4763cd0e 8499
d62a17ae 8500 result = pim_update_source_set(ifp, source_addr);
8501 switch (result) {
8502 case PIM_SUCCESS:
8503 break;
8504 case PIM_IFACE_NOT_FOUND:
23f1c68b 8505 ret = CMD_WARNING_CONFIG_FAILED;
d62a17ae 8506 vty_out(vty, "Pim not enabled on this interface\n");
8507 break;
8508 case PIM_UPDATE_SOURCE_DUP:
23f1c68b 8509 ret = CMD_WARNING;
d62a17ae 8510 vty_out(vty, "%% Source already set to %s\n", source);
8511 break;
8512 default:
23f1c68b 8513 ret = CMD_WARNING_CONFIG_FAILED;
d62a17ae 8514 vty_out(vty, "%% Source set failed\n");
8515 }
4763cd0e 8516
23f1c68b 8517 return ret;
4763cd0e 8518}
8519
8520DEFUN (interface_pim_use_source,
8521 interface_pim_use_source_cmd,
8522 "ip pim use-source A.B.C.D",
8523 IP_STR
2f5e937c 8524 PIM_STR
4763cd0e 8525 "Configure primary IP address\n"
8526 "source ip address\n")
8527{
d62a17ae 8528 return interface_pim_use_src_cmd_worker(vty, argv[3]->arg);
4763cd0e 8529}
8530
8531DEFUN (interface_no_pim_use_source,
8532 interface_no_pim_use_source_cmd,
2243bb17 8533 "no ip pim use-source [A.B.C.D]",
4763cd0e 8534 NO_STR
8535 IP_STR
2f5e937c 8536 PIM_STR
2243bb17
DS
8537 "Delete source IP address\n"
8538 "source ip address\n")
4763cd0e 8539{
d62a17ae 8540 return interface_pim_use_src_cmd_worker(vty, "0.0.0.0");
4763cd0e 8541}
8542
ba4eb1bc
CS
8543DEFUN (ip_pim_bfd,
8544 ip_pim_bfd_cmd,
8545 "ip pim bfd",
8546 IP_STR
8547 PIM_STR
8548 "Enables BFD support\n")
8549{
d62a17ae 8550 VTY_DECLVAR_CONTEXT(interface, ifp);
8551 struct pim_interface *pim_ifp = ifp->info;
8552 struct bfd_info *bfd_info = NULL;
ba4eb1bc 8553
2fd8de7d
CS
8554 if (!pim_ifp) {
8555 if (!pim_cmd_interface_add(ifp)) {
8556 vty_out(vty, "Could not enable PIM SM on interface\n");
8557 return CMD_WARNING;
8558 }
8559 }
8560 pim_ifp = ifp->info;
8561
d62a17ae 8562 bfd_info = pim_ifp->bfd_info;
ba4eb1bc 8563
d62a17ae 8564 if (!bfd_info || !CHECK_FLAG(bfd_info->flags, BFD_FLAG_PARAM_CFG))
8565 pim_bfd_if_param_set(ifp, BFD_DEF_MIN_RX, BFD_DEF_MIN_TX,
8566 BFD_DEF_DETECT_MULT, 1);
ba4eb1bc 8567
d62a17ae 8568 return CMD_SUCCESS;
ba4eb1bc
CS
8569}
8570
8571DEFUN (no_ip_pim_bfd,
8572 no_ip_pim_bfd_cmd,
8573 "no ip pim bfd",
8574 NO_STR
8575 IP_STR
8576 PIM_STR
8577 "Disables BFD support\n")
8578{
d62a17ae 8579 VTY_DECLVAR_CONTEXT(interface, ifp);
8580 struct pim_interface *pim_ifp = ifp->info;
ba4eb1bc 8581
2fd8de7d
CS
8582 if (!pim_ifp) {
8583 vty_out(vty, "Pim not enabled on this interface\n");
8584 return CMD_WARNING;
8585 }
ba4eb1bc 8586
d62a17ae 8587 if (pim_ifp->bfd_info) {
8588 pim_bfd_reg_dereg_all_nbr(ifp, ZEBRA_BFD_DEST_DEREGISTER);
8589 bfd_info_free(&(pim_ifp->bfd_info));
8590 }
ba4eb1bc 8591
d62a17ae 8592 return CMD_SUCCESS;
ba4eb1bc
CS
8593}
8594
16c926c8 8595DEFUN (ip_pim_bsm,
8596 ip_pim_bsm_cmd,
8597 "ip pim bsm",
8598 IP_STR
8599 PIM_STR
8600 "Enables BSM support on the interface\n")
8601{
8602 VTY_DECLVAR_CONTEXT(interface, ifp);
8603 struct pim_interface *pim_ifp = ifp->info;
8604
8605 if (!pim_ifp) {
8606 if (!pim_cmd_interface_add(ifp)) {
8607 vty_out(vty, "Could not enable PIM SM on interface\n");
8608 return CMD_WARNING;
8609 }
8610 }
8611
8612 pim_ifp = ifp->info;
8613 pim_ifp->bsm_enable = true;
8614
8615 return CMD_SUCCESS;
8616}
8617
8618DEFUN (no_ip_pim_bsm,
8619 no_ip_pim_bsm_cmd,
8620 "no ip pim bsm",
8621 NO_STR
8622 IP_STR
8623 PIM_STR
8624 "Disables BSM support\n")
8625{
8626 VTY_DECLVAR_CONTEXT(interface, ifp);
8627 struct pim_interface *pim_ifp = ifp->info;
8628
8629 if (!pim_ifp) {
8630 vty_out(vty, "Pim not enabled on this interface\n");
8631 return CMD_WARNING;
8632 }
8633
8634 pim_ifp->bsm_enable = false;
8635
8636 return CMD_SUCCESS;
8637}
8638
8639DEFUN (ip_pim_ucast_bsm,
8640 ip_pim_ucast_bsm_cmd,
8641 "ip pim unicast-bsm",
8642 IP_STR
8643 PIM_STR
8644 "Accept/Send unicast BSM on the interface\n")
8645{
8646 VTY_DECLVAR_CONTEXT(interface, ifp);
8647 struct pim_interface *pim_ifp = ifp->info;
8648
8649 if (!pim_ifp) {
8650 if (!pim_cmd_interface_add(ifp)) {
8651 vty_out(vty, "Could not enable PIM SM on interface\n");
8652 return CMD_WARNING;
8653 }
8654 }
8655
8656 pim_ifp = ifp->info;
8657 pim_ifp->ucast_bsm_accept = true;
8658
8659 return CMD_SUCCESS;
8660}
8661
8662DEFUN (no_ip_pim_ucast_bsm,
8663 no_ip_pim_ucast_bsm_cmd,
8664 "no ip pim unicast-bsm",
8665 NO_STR
8666 IP_STR
8667 PIM_STR
8668 "Block send/receive unicast BSM on this interface\n")
8669{
8670 VTY_DECLVAR_CONTEXT(interface, ifp);
8671 struct pim_interface *pim_ifp = ifp->info;
8672
8673 if (!pim_ifp) {
8674 vty_out(vty, "Pim not enabled on this interface\n");
8675 return CMD_WARNING;
8676 }
8677
8678 pim_ifp->ucast_bsm_accept = false;
8679
8680 return CMD_SUCCESS;
8681}
8682
64dc4b2d
RZ
8683#if HAVE_BFDD > 0
8684DEFUN_HIDDEN(
8685#else
8686DEFUN(
8687#endif /* HAVE_BFDD */
8688 ip_pim_bfd_param,
ba4eb1bc
CS
8689 ip_pim_bfd_param_cmd,
8690 "ip pim bfd (2-255) (50-60000) (50-60000)",
8691 IP_STR
8692 PIM_STR
8693 "Enables BFD support\n"
8694 "Detect Multiplier\n"
8695 "Required min receive interval\n"
8696 "Desired min transmit interval\n")
8697{
d62a17ae 8698 VTY_DECLVAR_CONTEXT(interface, ifp);
8699 int idx_number = 3;
8700 int idx_number_2 = 4;
8701 int idx_number_3 = 5;
d7c0a89a
QY
8702 uint32_t rx_val;
8703 uint32_t tx_val;
8704 uint8_t dm_val;
d62a17ae 8705 int ret;
2fd8de7d 8706 struct pim_interface *pim_ifp = ifp->info;
ba4eb1bc 8707
2fd8de7d
CS
8708 if (!pim_ifp) {
8709 if (!pim_cmd_interface_add(ifp)) {
8710 vty_out(vty, "Could not enable PIM SM on interface\n");
8711 return CMD_WARNING;
8712 }
8713 }
ba4eb1bc 8714
d62a17ae 8715 if ((ret = bfd_validate_param(
8716 vty, argv[idx_number]->arg, argv[idx_number_2]->arg,
8717 argv[idx_number_3]->arg, &dm_val, &rx_val, &tx_val))
8718 != CMD_SUCCESS)
8719 return ret;
ba4eb1bc 8720
d62a17ae 8721 pim_bfd_if_param_set(ifp, rx_val, tx_val, dm_val, 0);
ba4eb1bc 8722
d62a17ae 8723 return CMD_SUCCESS;
ba4eb1bc
CS
8724}
8725
64dc4b2d 8726#if HAVE_BFDD == 0
d62a17ae 8727ALIAS(no_ip_pim_bfd, no_ip_pim_bfd_param_cmd,
9d303b37 8728 "no ip pim bfd (2-255) (50-60000) (50-60000)", NO_STR IP_STR PIM_STR
d62a17ae 8729 "Enables BFD support\n"
8730 "Detect Multiplier\n"
8731 "Required min receive interval\n"
8732 "Desired min transmit interval\n")
64dc4b2d 8733#endif /* !HAVE_BFDD */
d62a17ae 8734
64c86530 8735static int ip_msdp_peer_cmd_worker(struct pim_instance *pim, struct vty *vty,
4f9f3925 8736 const char *peer, const char *local)
d62a17ae 8737{
8738 enum pim_msdp_err result;
8739 struct in_addr peer_addr;
8740 struct in_addr local_addr;
01841ed3 8741 int ret = CMD_SUCCESS;
d62a17ae 8742
8743 result = inet_pton(AF_INET, peer, &peer_addr);
8744 if (result <= 0) {
8745 vty_out(vty, "%% Bad peer address %s: errno=%d: %s\n", peer,
8746 errno, safe_strerror(errno));
8747 return CMD_WARNING_CONFIG_FAILED;
8748 }
8749
8750 result = inet_pton(AF_INET, local, &local_addr);
8751 if (result <= 0) {
8752 vty_out(vty, "%% Bad source address %s: errno=%d: %s\n", local,
8753 errno, safe_strerror(errno));
8754 return CMD_WARNING_CONFIG_FAILED;
8755 }
ba4eb1bc 8756
4f9f3925 8757 result = pim_msdp_peer_add(pim, peer_addr, local_addr, "default",
d62a17ae 8758 NULL /* mp_p */);
8759 switch (result) {
8760 case PIM_MSDP_ERR_NONE:
8761 break;
8762 case PIM_MSDP_ERR_OOM:
01841ed3 8763 ret = CMD_WARNING_CONFIG_FAILED;
d62a17ae 8764 vty_out(vty, "%% Out of memory\n");
8765 break;
8766 case PIM_MSDP_ERR_PEER_EXISTS:
01841ed3 8767 ret = CMD_WARNING;
d62a17ae 8768 vty_out(vty, "%% Peer exists\n");
8769 break;
8770 case PIM_MSDP_ERR_MAX_MESH_GROUPS:
01841ed3 8771 ret = CMD_WARNING_CONFIG_FAILED;
d62a17ae 8772 vty_out(vty, "%% Only one mesh-group allowed currently\n");
8773 break;
8774 default:
01841ed3 8775 ret = CMD_WARNING_CONFIG_FAILED;
d62a17ae 8776 vty_out(vty, "%% peer add failed\n");
8777 }
8778
01841ed3 8779 return ret;
2a333e0f 8780}
8781
977d71cc 8782DEFUN_HIDDEN (ip_msdp_peer,
2a333e0f 8783 ip_msdp_peer_cmd,
8784 "ip msdp peer A.B.C.D source A.B.C.D",
8785 IP_STR
8786 CFG_MSDP_STR
8787 "Configure MSDP peer\n"
8788 "peer ip address\n"
8789 "Source address for TCP connection\n"
8790 "local ip address\n")
8791{
4f9f3925 8792 PIM_DECLVAR_CONTEXT(vrf, pim);
64c86530 8793 return ip_msdp_peer_cmd_worker(pim, vty, argv[3]->arg, argv[5]->arg);
2a333e0f 8794}
8795
64c86530 8796static int ip_no_msdp_peer_cmd_worker(struct pim_instance *pim, struct vty *vty,
4f9f3925 8797 const char *peer)
2a333e0f 8798{
d62a17ae 8799 enum pim_msdp_err result;
8800 struct in_addr peer_addr;
2a333e0f 8801
d62a17ae 8802 result = inet_pton(AF_INET, peer, &peer_addr);
8803 if (result <= 0) {
8804 vty_out(vty, "%% Bad peer address %s: errno=%d: %s\n", peer,
8805 errno, safe_strerror(errno));
8806 return CMD_WARNING_CONFIG_FAILED;
8807 }
2a333e0f 8808
4f9f3925 8809 result = pim_msdp_peer_del(pim, peer_addr);
d62a17ae 8810 switch (result) {
8811 case PIM_MSDP_ERR_NONE:
8812 break;
8813 case PIM_MSDP_ERR_NO_PEER:
8814 vty_out(vty, "%% Peer does not exist\n");
8815 break;
8816 default:
8817 vty_out(vty, "%% peer del failed\n");
8818 }
2a333e0f 8819
d62a17ae 8820 return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
2a333e0f 8821}
8822
977d71cc 8823DEFUN_HIDDEN (no_ip_msdp_peer,
2a333e0f 8824 no_ip_msdp_peer_cmd,
8825 "no ip msdp peer A.B.C.D",
977d71cc 8826 NO_STR
2a333e0f 8827 IP_STR
8828 CFG_MSDP_STR
8829 "Delete MSDP peer\n"
8830 "peer ip address\n")
8831{
4f9f3925 8832 PIM_DECLVAR_CONTEXT(vrf, pim);
64c86530 8833 return ip_no_msdp_peer_cmd_worker(pim, vty, argv[4]->arg);
2a333e0f 8834}
8835
64c86530
DS
8836static int ip_msdp_mesh_group_member_cmd_worker(struct pim_instance *pim,
8837 struct vty *vty, const char *mg,
8838 const char *mbr)
977d71cc 8839{
d62a17ae 8840 enum pim_msdp_err result;
8841 struct in_addr mbr_ip;
01841ed3 8842 int ret = CMD_SUCCESS;
977d71cc 8843
d62a17ae 8844 result = inet_pton(AF_INET, mbr, &mbr_ip);
8845 if (result <= 0) {
8846 vty_out(vty, "%% Bad member address %s: errno=%d: %s\n", mbr,
8847 errno, safe_strerror(errno));
8848 return CMD_WARNING_CONFIG_FAILED;
8849 }
977d71cc 8850
02a16316 8851 result = pim_msdp_mg_mbr_add(pim, mg, mbr_ip);
d62a17ae 8852 switch (result) {
8853 case PIM_MSDP_ERR_NONE:
8854 break;
8855 case PIM_MSDP_ERR_OOM:
01841ed3 8856 ret = CMD_WARNING_CONFIG_FAILED;
d62a17ae 8857 vty_out(vty, "%% Out of memory\n");
8858 break;
8859 case PIM_MSDP_ERR_MG_MBR_EXISTS:
01841ed3 8860 ret = CMD_WARNING;
d62a17ae 8861 vty_out(vty, "%% mesh-group member exists\n");
8862 break;
8863 case PIM_MSDP_ERR_MAX_MESH_GROUPS:
01841ed3 8864 ret = CMD_WARNING_CONFIG_FAILED;
d62a17ae 8865 vty_out(vty, "%% Only one mesh-group allowed currently\n");
8866 break;
8867 default:
01841ed3 8868 ret = CMD_WARNING_CONFIG_FAILED;
d62a17ae 8869 vty_out(vty, "%% member add failed\n");
8870 }
977d71cc 8871
01841ed3 8872 return ret;
977d71cc 8873}
8874
8875DEFUN (ip_msdp_mesh_group_member,
8876 ip_msdp_mesh_group_member_cmd,
8877 "ip msdp mesh-group WORD member A.B.C.D",
8878 IP_STR
8879 CFG_MSDP_STR
8880 "Configure MSDP mesh-group\n"
8881 "mesh group name\n"
8882 "mesh group member\n"
8883 "peer ip address\n")
8884{
02a16316 8885 PIM_DECLVAR_CONTEXT(vrf, pim);
64c86530 8886 return ip_msdp_mesh_group_member_cmd_worker(pim, vty, argv[3]->arg,
d62a17ae 8887 argv[5]->arg);
977d71cc 8888}
8889
64c86530
DS
8890static int ip_no_msdp_mesh_group_member_cmd_worker(struct pim_instance *pim,
8891 struct vty *vty,
d62a17ae 8892 const char *mg,
8893 const char *mbr)
977d71cc 8894{
d62a17ae 8895 enum pim_msdp_err result;
8896 struct in_addr mbr_ip;
977d71cc 8897
d62a17ae 8898 result = inet_pton(AF_INET, mbr, &mbr_ip);
8899 if (result <= 0) {
8900 vty_out(vty, "%% Bad member address %s: errno=%d: %s\n", mbr,
8901 errno, safe_strerror(errno));
8902 return CMD_WARNING_CONFIG_FAILED;
8903 }
977d71cc 8904
02a16316 8905 result = pim_msdp_mg_mbr_del(pim, mg, mbr_ip);
d62a17ae 8906 switch (result) {
8907 case PIM_MSDP_ERR_NONE:
8908 break;
8909 case PIM_MSDP_ERR_NO_MG:
8910 vty_out(vty, "%% mesh-group does not exist\n");
8911 break;
8912 case PIM_MSDP_ERR_NO_MG_MBR:
8913 vty_out(vty, "%% mesh-group member does not exist\n");
8914 break;
8915 default:
8916 vty_out(vty, "%% mesh-group member del failed\n");
8917 }
977d71cc 8918
d62a17ae 8919 return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
977d71cc 8920}
8921DEFUN (no_ip_msdp_mesh_group_member,
8922 no_ip_msdp_mesh_group_member_cmd,
8923 "no ip msdp mesh-group WORD member A.B.C.D",
8924 NO_STR
8925 IP_STR
8926 CFG_MSDP_STR
8927 "Delete MSDP mesh-group member\n"
8928 "mesh group name\n"
8929 "mesh group member\n"
8930 "peer ip address\n")
8931{
02a16316 8932 PIM_DECLVAR_CONTEXT(vrf, pim);
64c86530 8933 return ip_no_msdp_mesh_group_member_cmd_worker(pim, vty, argv[4]->arg,
d62a17ae 8934 argv[6]->arg);
977d71cc 8935}
8936
64c86530
DS
8937static int ip_msdp_mesh_group_source_cmd_worker(struct pim_instance *pim,
8938 struct vty *vty, const char *mg,
8939 const char *src)
977d71cc 8940{
d62a17ae 8941 enum pim_msdp_err result;
8942 struct in_addr src_ip;
977d71cc 8943
d62a17ae 8944 result = inet_pton(AF_INET, src, &src_ip);
8945 if (result <= 0) {
8946 vty_out(vty, "%% Bad source address %s: errno=%d: %s\n", src,
8947 errno, safe_strerror(errno));
8948 return CMD_WARNING_CONFIG_FAILED;
8949 }
977d71cc 8950
02a16316 8951 result = pim_msdp_mg_src_add(pim, mg, src_ip);
d62a17ae 8952 switch (result) {
8953 case PIM_MSDP_ERR_NONE:
8954 break;
8955 case PIM_MSDP_ERR_OOM:
8956 vty_out(vty, "%% Out of memory\n");
8957 break;
8958 case PIM_MSDP_ERR_MAX_MESH_GROUPS:
8959 vty_out(vty, "%% Only one mesh-group allowed currently\n");
8960 break;
8961 default:
8962 vty_out(vty, "%% source add failed\n");
8963 }
977d71cc 8964
d62a17ae 8965 return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
977d71cc 8966}
8967
8968
8969DEFUN (ip_msdp_mesh_group_source,
8970 ip_msdp_mesh_group_source_cmd,
8971 "ip msdp mesh-group WORD source A.B.C.D",
8972 IP_STR
8973 CFG_MSDP_STR
8974 "Configure MSDP mesh-group\n"
8975 "mesh group name\n"
8976 "mesh group local address\n"
8977 "source ip address for the TCP connection\n")
8978{
02a16316 8979 PIM_DECLVAR_CONTEXT(vrf, pim);
64c86530 8980 return ip_msdp_mesh_group_source_cmd_worker(pim, vty, argv[3]->arg,
d62a17ae 8981 argv[5]->arg);
977d71cc 8982}
8983
64c86530
DS
8984static int ip_no_msdp_mesh_group_source_cmd_worker(struct pim_instance *pim,
8985 struct vty *vty,
d62a17ae 8986 const char *mg)
977d71cc 8987{
d62a17ae 8988 enum pim_msdp_err result;
977d71cc 8989
02a16316 8990 result = pim_msdp_mg_src_del(pim, mg);
d62a17ae 8991 switch (result) {
8992 case PIM_MSDP_ERR_NONE:
8993 break;
8994 case PIM_MSDP_ERR_NO_MG:
8995 vty_out(vty, "%% mesh-group does not exist\n");
8996 break;
8997 default:
8998 vty_out(vty, "%% mesh-group source del failed\n");
8999 }
977d71cc 9000
d62a17ae 9001 return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
977d71cc 9002}
9003
64c86530
DS
9004static int ip_no_msdp_mesh_group_cmd_worker(struct pim_instance *pim,
9005 struct vty *vty, const char *mg)
977d71cc 9006{
d62a17ae 9007 enum pim_msdp_err result;
977d71cc 9008
02a16316 9009 result = pim_msdp_mg_del(pim, mg);
d62a17ae 9010 switch (result) {
9011 case PIM_MSDP_ERR_NONE:
9012 break;
9013 case PIM_MSDP_ERR_NO_MG:
9014 vty_out(vty, "%% mesh-group does not exist\n");
9015 break;
9016 default:
9017 vty_out(vty, "%% mesh-group source del failed\n");
9018 }
977d71cc 9019
d62a17ae 9020 return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
977d71cc 9021}
9022
58344b65
DS
9023DEFUN (no_ip_msdp_mesh_group_source,
9024 no_ip_msdp_mesh_group_source_cmd,
9025 "no ip msdp mesh-group WORD source [A.B.C.D]",
977d71cc 9026 NO_STR
9027 IP_STR
9028 CFG_MSDP_STR
58344b65
DS
9029 "Delete MSDP mesh-group source\n"
9030 "mesh group name\n"
a957a05b 9031 "mesh group source\n"
58344b65 9032 "mesh group local address\n")
977d71cc 9033{
02a16316 9034 PIM_DECLVAR_CONTEXT(vrf, pim);
d62a17ae 9035 if (argc == 7)
64c86530 9036 return ip_no_msdp_mesh_group_cmd_worker(pim, vty, argv[6]->arg);
d62a17ae 9037 else
64c86530 9038 return ip_no_msdp_mesh_group_source_cmd_worker(pim, vty,
d62a17ae 9039 argv[4]->arg);
9040}
9041
9042static void print_empty_json_obj(struct vty *vty)
9043{
9044 json_object *json;
9045 json = json_object_new_object();
9046 vty_out(vty, "%s\n",
9047 json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY));
9048 json_object_free(json);
9049}
9050
64c86530 9051static void ip_msdp_show_mesh_group(struct pim_instance *pim, struct vty *vty,
088f1098 9052 bool uj)
d62a17ae 9053{
9054 struct listnode *mbrnode;
9055 struct pim_msdp_mg_mbr *mbr;
02a16316 9056 struct pim_msdp_mg *mg = pim->msdp.mg;
d62a17ae 9057 char mbr_str[INET_ADDRSTRLEN];
9058 char src_str[INET_ADDRSTRLEN];
9059 char state_str[PIM_MSDP_STATE_STRLEN];
9060 enum pim_msdp_peer_state state;
9061 json_object *json = NULL;
9062 json_object *json_mg_row = NULL;
9063 json_object *json_members = NULL;
9064 json_object *json_row = NULL;
9065
9066 if (!mg) {
9067 if (uj)
9068 print_empty_json_obj(vty);
9069 return;
9070 }
9071
9072 pim_inet4_dump("<source?>", mg->src_ip, src_str, sizeof(src_str));
9073 if (uj) {
9074 json = json_object_new_object();
9075 /* currently there is only one mesh group but we should still
9076 * make
9077 * it a dict with mg-name as key */
9078 json_mg_row = json_object_new_object();
9079 json_object_string_add(json_mg_row, "name",
9080 mg->mesh_group_name);
9081 json_object_string_add(json_mg_row, "source", src_str);
9082 } else {
9083 vty_out(vty, "Mesh group : %s\n", mg->mesh_group_name);
9084 vty_out(vty, " Source : %s\n", src_str);
9085 vty_out(vty, " Member State\n");
9086 }
9087
9088 for (ALL_LIST_ELEMENTS_RO(mg->mbr_list, mbrnode, mbr)) {
9089 pim_inet4_dump("<mbr?>", mbr->mbr_ip, mbr_str, sizeof(mbr_str));
9090 if (mbr->mp) {
9091 state = mbr->mp->state;
9092 } else {
9093 state = PIM_MSDP_DISABLED;
9094 }
9095 pim_msdp_state_dump(state, state_str, sizeof(state_str));
9096 if (uj) {
9097 json_row = json_object_new_object();
9098 json_object_string_add(json_row, "member", mbr_str);
9099 json_object_string_add(json_row, "state", state_str);
9100 if (!json_members) {
9101 json_members = json_object_new_object();
9102 json_object_object_add(json_mg_row, "members",
9103 json_members);
9104 }
9105 json_object_object_add(json_members, mbr_str, json_row);
9106 } else {
9107 vty_out(vty, " %-15s %11s\n", mbr_str, state_str);
9108 }
9109 }
9110
9111 if (uj) {
9112 json_object_object_add(json, mg->mesh_group_name, json_mg_row);
9d303b37
DL
9113 vty_out(vty, "%s\n", json_object_to_json_string_ext(
9114 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 9115 json_object_free(json);
9116 }
977d71cc 9117}
9118
9119DEFUN (show_ip_msdp_mesh_group,
9120 show_ip_msdp_mesh_group_cmd,
20a7e5fd 9121 "show ip msdp [vrf NAME] mesh-group [json]",
977d71cc 9122 SHOW_STR
9123 IP_STR
9124 MSDP_STR
f02d59db 9125 VRF_CMD_HELP_STR
977d71cc 9126 "MSDP mesh-group information\n"
f5da2cc2 9127 JSON_STR)
977d71cc 9128{
9f049418 9129 bool uj = use_json(argc, argv);
c68ba0d7 9130 int idx = 2;
02a16316
DS
9131 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9132
9133 if (!vrf)
9134 return CMD_WARNING;
9135
64c86530 9136 ip_msdp_show_mesh_group(vrf->info, vty, uj);
d62a17ae 9137
9138 return CMD_SUCCESS;
9139}
9140
a25de56b
DS
9141DEFUN (show_ip_msdp_mesh_group_vrf_all,
9142 show_ip_msdp_mesh_group_vrf_all_cmd,
9143 "show ip msdp vrf all mesh-group [json]",
9144 SHOW_STR
9145 IP_STR
9146 MSDP_STR
9147 VRF_CMD_HELP_STR
9148 "MSDP mesh-group information\n"
f5da2cc2 9149 JSON_STR)
a25de56b 9150{
9f049418 9151 bool uj = use_json(argc, argv);
a25de56b
DS
9152 struct vrf *vrf;
9153 bool first = true;
9154
9155 if (uj)
9156 vty_out(vty, "{ ");
a2addae8 9157 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
a25de56b
DS
9158 if (uj) {
9159 if (!first)
9160 vty_out(vty, ", ");
9161 vty_out(vty, " \"%s\": ", vrf->name);
9162 first = false;
9163 } else
9164 vty_out(vty, "VRF: %s\n", vrf->name);
9165 ip_msdp_show_mesh_group(vrf->info, vty, uj);
9166 }
9167 if (uj)
9168 vty_out(vty, "}\n");
9169
9170 return CMD_SUCCESS;
9171}
9172
64c86530 9173static void ip_msdp_show_peers(struct pim_instance *pim, struct vty *vty,
088f1098 9174 bool uj)
d62a17ae 9175{
9176 struct listnode *mpnode;
9177 struct pim_msdp_peer *mp;
9178 char peer_str[INET_ADDRSTRLEN];
9179 char local_str[INET_ADDRSTRLEN];
9180 char state_str[PIM_MSDP_STATE_STRLEN];
9181 char timebuf[PIM_MSDP_UPTIME_STRLEN];
9182 int64_t now;
9183 json_object *json = NULL;
9184 json_object *json_row = NULL;
9185
9186
9187 if (uj) {
9188 json = json_object_new_object();
9189 } else {
9190 vty_out(vty,
9191 "Peer Local State Uptime SaCnt\n");
9192 }
9193
02a16316 9194 for (ALL_LIST_ELEMENTS_RO(pim->msdp.peer_list, mpnode, mp)) {
d62a17ae 9195 if (mp->state == PIM_MSDP_ESTABLISHED) {
9196 now = pim_time_monotonic_sec();
9197 pim_time_uptime(timebuf, sizeof(timebuf),
9198 now - mp->uptime);
9199 } else {
c35b7e6b 9200 strlcpy(timebuf, "-", sizeof(timebuf));
d62a17ae 9201 }
9202 pim_inet4_dump("<peer?>", mp->peer, peer_str, sizeof(peer_str));
9203 pim_inet4_dump("<local?>", mp->local, local_str,
9204 sizeof(local_str));
9205 pim_msdp_state_dump(mp->state, state_str, sizeof(state_str));
9206 if (uj) {
9207 json_row = json_object_new_object();
9208 json_object_string_add(json_row, "peer", peer_str);
9209 json_object_string_add(json_row, "local", local_str);
9210 json_object_string_add(json_row, "state", state_str);
9211 json_object_string_add(json_row, "upTime", timebuf);
9212 json_object_int_add(json_row, "saCount", mp->sa_cnt);
9213 json_object_object_add(json, peer_str, json_row);
9214 } else {
9215 vty_out(vty, "%-15s %15s %11s %8s %6d\n", peer_str,
9216 local_str, state_str, timebuf, mp->sa_cnt);
9217 }
9218 }
9219
9220 if (uj) {
9d303b37
DL
9221 vty_out(vty, "%s\n", json_object_to_json_string_ext(
9222 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 9223 json_object_free(json);
9224 }
9225}
9226
64c86530 9227static void ip_msdp_show_peers_detail(struct pim_instance *pim, struct vty *vty,
088f1098 9228 const char *peer, bool uj)
d62a17ae 9229{
9230 struct listnode *mpnode;
9231 struct pim_msdp_peer *mp;
9232 char peer_str[INET_ADDRSTRLEN];
9233 char local_str[INET_ADDRSTRLEN];
9234 char state_str[PIM_MSDP_STATE_STRLEN];
9235 char timebuf[PIM_MSDP_UPTIME_STRLEN];
9236 char katimer[PIM_MSDP_TIMER_STRLEN];
9237 char crtimer[PIM_MSDP_TIMER_STRLEN];
9238 char holdtimer[PIM_MSDP_TIMER_STRLEN];
9239 int64_t now;
9240 json_object *json = NULL;
9241 json_object *json_row = NULL;
9242
9243 if (uj) {
9244 json = json_object_new_object();
9245 }
9246
02a16316 9247 for (ALL_LIST_ELEMENTS_RO(pim->msdp.peer_list, mpnode, mp)) {
d62a17ae 9248 pim_inet4_dump("<peer?>", mp->peer, peer_str, sizeof(peer_str));
9249 if (strcmp(peer, "detail") && strcmp(peer, peer_str))
9250 continue;
9251
9252 if (mp->state == PIM_MSDP_ESTABLISHED) {
9253 now = pim_time_monotonic_sec();
9254 pim_time_uptime(timebuf, sizeof(timebuf),
9255 now - mp->uptime);
9256 } else {
c35b7e6b 9257 strlcpy(timebuf, "-", sizeof(timebuf));
d62a17ae 9258 }
9259 pim_inet4_dump("<local?>", mp->local, local_str,
9260 sizeof(local_str));
9261 pim_msdp_state_dump(mp->state, state_str, sizeof(state_str));
9262 pim_time_timer_to_hhmmss(katimer, sizeof(katimer),
9263 mp->ka_timer);
9264 pim_time_timer_to_hhmmss(crtimer, sizeof(crtimer),
9265 mp->cr_timer);
9266 pim_time_timer_to_hhmmss(holdtimer, sizeof(holdtimer),
9267 mp->hold_timer);
9268
9269 if (uj) {
9270 json_row = json_object_new_object();
9271 json_object_string_add(json_row, "peer", peer_str);
9272 json_object_string_add(json_row, "local", local_str);
9273 json_object_string_add(json_row, "meshGroupName",
9274 mp->mesh_group_name);
9275 json_object_string_add(json_row, "state", state_str);
9276 json_object_string_add(json_row, "upTime", timebuf);
9277 json_object_string_add(json_row, "keepAliveTimer",
9278 katimer);
9279 json_object_string_add(json_row, "connRetryTimer",
9280 crtimer);
9281 json_object_string_add(json_row, "holdTimer",
9282 holdtimer);
9283 json_object_string_add(json_row, "lastReset",
9284 mp->last_reset);
9285 json_object_int_add(json_row, "connAttempts",
9286 mp->conn_attempts);
9287 json_object_int_add(json_row, "establishedChanges",
9288 mp->est_flaps);
9289 json_object_int_add(json_row, "saCount", mp->sa_cnt);
9290 json_object_int_add(json_row, "kaSent", mp->ka_tx_cnt);
9291 json_object_int_add(json_row, "kaRcvd", mp->ka_rx_cnt);
9292 json_object_int_add(json_row, "saSent", mp->sa_tx_cnt);
9293 json_object_int_add(json_row, "saRcvd", mp->sa_rx_cnt);
9294 json_object_object_add(json, peer_str, json_row);
9295 } else {
9296 vty_out(vty, "Peer : %s\n", peer_str);
9297 vty_out(vty, " Local : %s\n", local_str);
9298 vty_out(vty, " Mesh Group : %s\n",
9299 mp->mesh_group_name);
9300 vty_out(vty, " State : %s\n", state_str);
9301 vty_out(vty, " Uptime : %s\n", timebuf);
9302
9303 vty_out(vty, " Keepalive Timer : %s\n", katimer);
9304 vty_out(vty, " Conn Retry Timer : %s\n", crtimer);
9305 vty_out(vty, " Hold Timer : %s\n", holdtimer);
9306 vty_out(vty, " Last Reset : %s\n",
9307 mp->last_reset);
9308 vty_out(vty, " Conn Attempts : %d\n",
9309 mp->conn_attempts);
9310 vty_out(vty, " Established Changes : %d\n",
9311 mp->est_flaps);
9312 vty_out(vty, " SA Count : %d\n",
9313 mp->sa_cnt);
9314 vty_out(vty, " Statistics :\n");
9315 vty_out(vty,
9316 " Sent Rcvd\n");
9317 vty_out(vty, " Keepalives : %10d %10d\n",
9318 mp->ka_tx_cnt, mp->ka_rx_cnt);
9319 vty_out(vty, " SAs : %10d %10d\n",
9320 mp->sa_tx_cnt, mp->sa_rx_cnt);
9321 vty_out(vty, "\n");
9322 }
9323 }
9324
9325 if (uj) {
9d303b37
DL
9326 vty_out(vty, "%s\n", json_object_to_json_string_ext(
9327 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 9328 json_object_free(json);
9329 }
977d71cc 9330}
9331
9332DEFUN (show_ip_msdp_peer_detail,
9333 show_ip_msdp_peer_detail_cmd,
20a7e5fd 9334 "show ip msdp [vrf NAME] peer [detail|A.B.C.D] [json]",
2a333e0f 9335 SHOW_STR
9336 IP_STR
9337 MSDP_STR
f02d59db 9338 VRF_CMD_HELP_STR
2a333e0f 9339 "MSDP peer information\n"
977d71cc 9340 "Detailed output\n"
9341 "peer ip address\n"
f5da2cc2 9342 JSON_STR)
2a333e0f 9343{
9f049418 9344 bool uj = use_json(argc, argv);
c68ba0d7 9345 int idx = 2;
02a16316 9346 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
d62a17ae 9347
07a29355
QY
9348 if (!vrf)
9349 return CMD_WARNING;
9350
9351 char *arg = NULL;
9352
9353 if (argv_find(argv, argc, "detail", &idx))
9354 arg = argv[idx]->text;
9355 else if (argv_find(argv, argc, "A.B.C.D", &idx))
9356 arg = argv[idx]->arg;
9357
9358 if (arg)
64c86530 9359 ip_msdp_show_peers_detail(vrf->info, vty, argv[idx]->arg, uj);
d62a17ae 9360 else
64c86530 9361 ip_msdp_show_peers(vrf->info, vty, uj);
d62a17ae 9362
9363 return CMD_SUCCESS;
9364}
9365
a25de56b
DS
9366DEFUN (show_ip_msdp_peer_detail_vrf_all,
9367 show_ip_msdp_peer_detail_vrf_all_cmd,
9368 "show ip msdp vrf all peer [detail|A.B.C.D] [json]",
9369 SHOW_STR
9370 IP_STR
9371 MSDP_STR
9372 VRF_CMD_HELP_STR
9373 "MSDP peer information\n"
9374 "Detailed output\n"
9375 "peer ip address\n"
f5da2cc2 9376 JSON_STR)
a25de56b
DS
9377{
9378 int idx = 2;
9f049418 9379 bool uj = use_json(argc, argv);
a25de56b
DS
9380 struct vrf *vrf;
9381 bool first = true;
9382
9383 if (uj)
9384 vty_out(vty, "{ ");
a2addae8 9385 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
a25de56b
DS
9386 if (uj) {
9387 if (!first)
9388 vty_out(vty, ", ");
9389 vty_out(vty, " \"%s\": ", vrf->name);
9390 first = false;
9391 } else
9392 vty_out(vty, "VRF: %s\n", vrf->name);
9393 if (argv_find(argv, argc, "detail", &idx)
9394 || argv_find(argv, argc, "A.B.C.D", &idx))
9395 ip_msdp_show_peers_detail(vrf->info, vty,
9396 argv[idx]->arg, uj);
9397 else
9398 ip_msdp_show_peers(vrf->info, vty, uj);
9399 }
9400 if (uj)
9401 vty_out(vty, "}\n");
9402
9403 return CMD_SUCCESS;
9404}
9405
088f1098 9406static void ip_msdp_show_sa(struct pim_instance *pim, struct vty *vty, bool uj)
d62a17ae 9407{
9408 struct listnode *sanode;
9409 struct pim_msdp_sa *sa;
9410 char src_str[INET_ADDRSTRLEN];
9411 char grp_str[INET_ADDRSTRLEN];
9412 char rp_str[INET_ADDRSTRLEN];
9413 char timebuf[PIM_MSDP_UPTIME_STRLEN];
9414 char spt_str[8];
9415 char local_str[8];
9416 int64_t now;
9417 json_object *json = NULL;
9418 json_object *json_group = NULL;
9419 json_object *json_row = NULL;
9420
9421 if (uj) {
9422 json = json_object_new_object();
9423 } else {
9424 vty_out(vty,
9425 "Source Group RP Local SPT Uptime\n");
9426 }
9427
02a16316 9428 for (ALL_LIST_ELEMENTS_RO(pim->msdp.sa_list, sanode, sa)) {
d62a17ae 9429 now = pim_time_monotonic_sec();
9430 pim_time_uptime(timebuf, sizeof(timebuf), now - sa->uptime);
9431 pim_inet4_dump("<src?>", sa->sg.src, src_str, sizeof(src_str));
9432 pim_inet4_dump("<grp?>", sa->sg.grp, grp_str, sizeof(grp_str));
9433 if (sa->flags & PIM_MSDP_SAF_PEER) {
9434 pim_inet4_dump("<rp?>", sa->rp, rp_str, sizeof(rp_str));
9435 if (sa->up) {
c35b7e6b 9436 strlcpy(spt_str, "yes", sizeof(spt_str));
d62a17ae 9437 } else {
c35b7e6b 9438 strlcpy(spt_str, "no", sizeof(spt_str));
d62a17ae 9439 }
9440 } else {
c35b7e6b
QY
9441 strlcpy(rp_str, "-", sizeof(rp_str));
9442 strlcpy(spt_str, "-", sizeof(spt_str));
d62a17ae 9443 }
9444 if (sa->flags & PIM_MSDP_SAF_LOCAL) {
c35b7e6b 9445 strlcpy(local_str, "yes", sizeof(local_str));
d62a17ae 9446 } else {
c35b7e6b 9447 strlcpy(local_str, "no", sizeof(local_str));
d62a17ae 9448 }
9449 if (uj) {
9450 json_object_object_get_ex(json, grp_str, &json_group);
9451
9452 if (!json_group) {
9453 json_group = json_object_new_object();
9454 json_object_object_add(json, grp_str,
9455 json_group);
9456 }
9457
9458 json_row = json_object_new_object();
9459 json_object_string_add(json_row, "source", src_str);
9460 json_object_string_add(json_row, "group", grp_str);
9461 json_object_string_add(json_row, "rp", rp_str);
9462 json_object_string_add(json_row, "local", local_str);
9463 json_object_string_add(json_row, "sptSetup", spt_str);
9464 json_object_string_add(json_row, "upTime", timebuf);
9465 json_object_object_add(json_group, src_str, json_row);
9466 } else {
9467 vty_out(vty, "%-15s %15s %15s %5c %3c %8s\n",
9468 src_str, grp_str, rp_str, local_str[0],
9469 spt_str[0], timebuf);
9470 }
9471 }
9472
d62a17ae 9473 if (uj) {
9d303b37
DL
9474 vty_out(vty, "%s\n", json_object_to_json_string_ext(
9475 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 9476 json_object_free(json);
9477 }
9478}
9479
9480static void ip_msdp_show_sa_entry_detail(struct pim_msdp_sa *sa,
9481 const char *src_str,
9482 const char *grp_str, struct vty *vty,
088f1098 9483 bool uj, json_object *json)
d62a17ae 9484{
9485 char rp_str[INET_ADDRSTRLEN];
9486 char peer_str[INET_ADDRSTRLEN];
9487 char timebuf[PIM_MSDP_UPTIME_STRLEN];
9488 char spt_str[8];
9489 char local_str[8];
9490 char statetimer[PIM_MSDP_TIMER_STRLEN];
9491 int64_t now;
9492 json_object *json_group = NULL;
9493 json_object *json_row = NULL;
9494
9495 now = pim_time_monotonic_sec();
9496 pim_time_uptime(timebuf, sizeof(timebuf), now - sa->uptime);
9497 if (sa->flags & PIM_MSDP_SAF_PEER) {
9498 pim_inet4_dump("<rp?>", sa->rp, rp_str, sizeof(rp_str));
9499 pim_inet4_dump("<peer?>", sa->peer, peer_str, sizeof(peer_str));
9500 if (sa->up) {
c35b7e6b 9501 strlcpy(spt_str, "yes", sizeof(spt_str));
d62a17ae 9502 } else {
c35b7e6b 9503 strlcpy(spt_str, "no", sizeof(spt_str));
d62a17ae 9504 }
9505 } else {
c35b7e6b
QY
9506 strlcpy(rp_str, "-", sizeof(rp_str));
9507 strlcpy(peer_str, "-", sizeof(peer_str));
9508 strlcpy(spt_str, "-", sizeof(spt_str));
d62a17ae 9509 }
9510 if (sa->flags & PIM_MSDP_SAF_LOCAL) {
c35b7e6b 9511 strlcpy(local_str, "yes", sizeof(local_str));
d62a17ae 9512 } else {
c35b7e6b 9513 strlcpy(local_str, "no", sizeof(local_str));
d62a17ae 9514 }
9515 pim_time_timer_to_hhmmss(statetimer, sizeof(statetimer),
9516 sa->sa_state_timer);
9517 if (uj) {
9518 json_object_object_get_ex(json, grp_str, &json_group);
9519
9520 if (!json_group) {
9521 json_group = json_object_new_object();
9522 json_object_object_add(json, grp_str, json_group);
9523 }
9524
9525 json_row = json_object_new_object();
9526 json_object_string_add(json_row, "source", src_str);
9527 json_object_string_add(json_row, "group", grp_str);
9528 json_object_string_add(json_row, "rp", rp_str);
9529 json_object_string_add(json_row, "local", local_str);
9530 json_object_string_add(json_row, "sptSetup", spt_str);
9531 json_object_string_add(json_row, "upTime", timebuf);
9532 json_object_string_add(json_row, "stateTimer", statetimer);
9533 json_object_object_add(json_group, src_str, json_row);
9534 } else {
9535 vty_out(vty, "SA : %s\n", sa->sg_str);
9536 vty_out(vty, " RP : %s\n", rp_str);
9537 vty_out(vty, " Peer : %s\n", peer_str);
9538 vty_out(vty, " Local : %s\n", local_str);
9539 vty_out(vty, " SPT Setup : %s\n", spt_str);
9540 vty_out(vty, " Uptime : %s\n", timebuf);
9541 vty_out(vty, " State Timer : %s\n", statetimer);
9542 vty_out(vty, "\n");
9543 }
9544}
9545
64c86530 9546static void ip_msdp_show_sa_detail(struct pim_instance *pim, struct vty *vty,
088f1098 9547 bool uj)
d62a17ae 9548{
9549 struct listnode *sanode;
9550 struct pim_msdp_sa *sa;
9551 char src_str[INET_ADDRSTRLEN];
9552 char grp_str[INET_ADDRSTRLEN];
9553 json_object *json = NULL;
9554
9555 if (uj) {
9556 json = json_object_new_object();
9557 }
9558
02a16316 9559 for (ALL_LIST_ELEMENTS_RO(pim->msdp.sa_list, sanode, sa)) {
d62a17ae 9560 pim_inet4_dump("<src?>", sa->sg.src, src_str, sizeof(src_str));
9561 pim_inet4_dump("<grp?>", sa->sg.grp, grp_str, sizeof(grp_str));
9562 ip_msdp_show_sa_entry_detail(sa, src_str, grp_str, vty, uj,
9563 json);
9564 }
9565
9566 if (uj) {
9d303b37
DL
9567 vty_out(vty, "%s\n", json_object_to_json_string_ext(
9568 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 9569 json_object_free(json);
9570 }
977d71cc 9571}
9572
9573DEFUN (show_ip_msdp_sa_detail,
9574 show_ip_msdp_sa_detail_cmd,
20a7e5fd 9575 "show ip msdp [vrf NAME] sa detail [json]",
3c72d654 9576 SHOW_STR
9577 IP_STR
9578 MSDP_STR
f02d59db 9579 VRF_CMD_HELP_STR
3c72d654 9580 "MSDP active-source information\n"
977d71cc 9581 "Detailed output\n"
f5da2cc2 9582 JSON_STR)
3c72d654 9583{
9f049418 9584 bool uj = use_json(argc, argv);
c68ba0d7 9585 int idx = 2;
02a16316
DS
9586 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9587
9588 if (!vrf)
9589 return CMD_WARNING;
9590
64c86530 9591 ip_msdp_show_sa_detail(vrf->info, vty, uj);
977d71cc 9592
d62a17ae 9593 return CMD_SUCCESS;
977d71cc 9594}
9595
a25de56b
DS
9596DEFUN (show_ip_msdp_sa_detail_vrf_all,
9597 show_ip_msdp_sa_detail_vrf_all_cmd,
9598 "show ip msdp vrf all sa detail [json]",
9599 SHOW_STR
9600 IP_STR
9601 MSDP_STR
9602 VRF_CMD_HELP_STR
9603 "MSDP active-source information\n"
9604 "Detailed output\n"
f5da2cc2 9605 JSON_STR)
a25de56b 9606{
9f049418 9607 bool uj = use_json(argc, argv);
a25de56b
DS
9608 struct vrf *vrf;
9609 bool first = true;
9610
9611 if (uj)
9612 vty_out(vty, "{ ");
a2addae8 9613 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
a25de56b
DS
9614 if (uj) {
9615 if (!first)
9616 vty_out(vty, ", ");
9617 vty_out(vty, " \"%s\": ", vrf->name);
9618 first = false;
9619 } else
9620 vty_out(vty, "VRF: %s\n", vrf->name);
9621 ip_msdp_show_sa_detail(vrf->info, vty, uj);
9622 }
9623 if (uj)
9624 vty_out(vty, "}\n");
9625
9626 return CMD_SUCCESS;
9627}
9628
64c86530 9629static void ip_msdp_show_sa_addr(struct pim_instance *pim, struct vty *vty,
088f1098 9630 const char *addr, bool uj)
977d71cc 9631{
d62a17ae 9632 struct listnode *sanode;
9633 struct pim_msdp_sa *sa;
9634 char src_str[INET_ADDRSTRLEN];
9635 char grp_str[INET_ADDRSTRLEN];
9636 json_object *json = NULL;
977d71cc 9637
d62a17ae 9638 if (uj) {
9639 json = json_object_new_object();
9640 }
977d71cc 9641
02a16316 9642 for (ALL_LIST_ELEMENTS_RO(pim->msdp.sa_list, sanode, sa)) {
d62a17ae 9643 pim_inet4_dump("<src?>", sa->sg.src, src_str, sizeof(src_str));
9644 pim_inet4_dump("<grp?>", sa->sg.grp, grp_str, sizeof(grp_str));
9645 if (!strcmp(addr, src_str) || !strcmp(addr, grp_str)) {
9646 ip_msdp_show_sa_entry_detail(sa, src_str, grp_str, vty,
9647 uj, json);
9648 }
9649 }
977d71cc 9650
d62a17ae 9651 if (uj) {
9d303b37
DL
9652 vty_out(vty, "%s\n", json_object_to_json_string_ext(
9653 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 9654 json_object_free(json);
9655 }
977d71cc 9656}
9657
64c86530 9658static void ip_msdp_show_sa_sg(struct pim_instance *pim, struct vty *vty,
088f1098 9659 const char *src, const char *grp, bool uj)
977d71cc 9660{
d62a17ae 9661 struct listnode *sanode;
9662 struct pim_msdp_sa *sa;
9663 char src_str[INET_ADDRSTRLEN];
9664 char grp_str[INET_ADDRSTRLEN];
9665 json_object *json = NULL;
977d71cc 9666
d62a17ae 9667 if (uj) {
9668 json = json_object_new_object();
9669 }
977d71cc 9670
02a16316 9671 for (ALL_LIST_ELEMENTS_RO(pim->msdp.sa_list, sanode, sa)) {
d62a17ae 9672 pim_inet4_dump("<src?>", sa->sg.src, src_str, sizeof(src_str));
9673 pim_inet4_dump("<grp?>", sa->sg.grp, grp_str, sizeof(grp_str));
9674 if (!strcmp(src, src_str) && !strcmp(grp, grp_str)) {
9675 ip_msdp_show_sa_entry_detail(sa, src_str, grp_str, vty,
9676 uj, json);
9677 }
9678 }
977d71cc 9679
d62a17ae 9680 if (uj) {
9d303b37
DL
9681 vty_out(vty, "%s\n", json_object_to_json_string_ext(
9682 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 9683 json_object_free(json);
9684 }
977d71cc 9685}
9686
9687DEFUN (show_ip_msdp_sa_sg,
9688 show_ip_msdp_sa_sg_cmd,
20a7e5fd 9689 "show ip msdp [vrf NAME] sa [A.B.C.D [A.B.C.D]] [json]",
977d71cc 9690 SHOW_STR
9691 IP_STR
9692 MSDP_STR
f02d59db 9693 VRF_CMD_HELP_STR
977d71cc 9694 "MSDP active-source information\n"
9695 "source or group ip\n"
a957a05b 9696 "group ip\n"
f5da2cc2 9697 JSON_STR)
977d71cc 9698{
9f049418 9699 bool uj = use_json(argc, argv);
02a16316 9700 struct vrf *vrf;
c68ba0d7 9701 int idx = 2;
02a16316
DS
9702
9703 vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9704
9705 if (!vrf)
9706 return CMD_WARNING;
9707
d62a17ae 9708 char *src_ip = argv_find(argv, argc, "A.B.C.D", &idx) ? argv[idx++]->arg
9709 : NULL;
9710 char *grp_ip = idx < argc && argv_find(argv, argc, "A.B.C.D", &idx)
9711 ? argv[idx]->arg
9712 : NULL;
9ea49d61 9713
d62a17ae 9714 if (src_ip && grp_ip)
64c86530 9715 ip_msdp_show_sa_sg(vrf->info, vty, src_ip, grp_ip, uj);
d62a17ae 9716 else if (src_ip)
64c86530 9717 ip_msdp_show_sa_addr(vrf->info, vty, src_ip, uj);
d62a17ae 9718 else
64c86530 9719 ip_msdp_show_sa(vrf->info, vty, uj);
3c72d654 9720
d62a17ae 9721 return CMD_SUCCESS;
3c72d654 9722}
9723
47bf9e21
DS
9724DEFUN (show_ip_msdp_sa_sg_vrf_all,
9725 show_ip_msdp_sa_sg_vrf_all_cmd,
9726 "show ip msdp vrf all sa [A.B.C.D [A.B.C.D]] [json]",
9727 SHOW_STR
9728 IP_STR
9729 MSDP_STR
9730 VRF_CMD_HELP_STR
9731 "MSDP active-source information\n"
9732 "source or group ip\n"
9733 "group ip\n"
9734 JSON_STR)
9735{
9f049418 9736 bool uj = use_json(argc, argv);
47bf9e21
DS
9737 struct vrf *vrf;
9738 bool first = true;
9739 int idx = 2;
9740
9741 char *src_ip = argv_find(argv, argc, "A.B.C.D", &idx) ? argv[idx++]->arg
996c9314 9742 : NULL;
47bf9e21 9743 char *grp_ip = idx < argc && argv_find(argv, argc, "A.B.C.D", &idx)
996c9314
LB
9744 ? argv[idx]->arg
9745 : NULL;
47bf9e21
DS
9746
9747 if (uj)
9748 vty_out(vty, "{ ");
a2addae8 9749 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
47bf9e21
DS
9750 if (uj) {
9751 if (!first)
9752 vty_out(vty, ", ");
9753 vty_out(vty, " \"%s\": ", vrf->name);
9754 first = false;
9755 } else
9756 vty_out(vty, "VRF: %s\n", vrf->name);
9757
9758 if (src_ip && grp_ip)
9759 ip_msdp_show_sa_sg(vrf->info, vty, src_ip, grp_ip, uj);
9760 else if (src_ip)
9761 ip_msdp_show_sa_addr(vrf->info, vty, src_ip, uj);
9762 else
9763 ip_msdp_show_sa(vrf->info, vty, uj);
9764 }
9765 if (uj)
9766 vty_out(vty, "}\n");
9767
9768 return CMD_SUCCESS;
9769}
9770
f1e2901a
AK
9771struct pim_sg_cache_walk_data {
9772 struct vty *vty;
9773 json_object *json;
9774 json_object *json_group;
9775 struct in_addr addr;
9776 bool addr_match;
9777};
9778
9779static void pim_show_vxlan_sg_entry(struct pim_vxlan_sg *vxlan_sg,
9780 struct pim_sg_cache_walk_data *cwd)
9781{
9782 struct vty *vty = cwd->vty;
9783 json_object *json = cwd->json;
9784 char src_str[INET_ADDRSTRLEN];
9785 char grp_str[INET_ADDRSTRLEN];
9786 json_object *json_row;
9787 bool installed = (vxlan_sg->up)?TRUE:FALSE;
9788 const char *iif_name = vxlan_sg->iif?vxlan_sg->iif->name:"-";
9789 const char *oif_name;
9790
9791 if (pim_vxlan_is_orig_mroute(vxlan_sg))
9792 oif_name = vxlan_sg->orig_oif?vxlan_sg->orig_oif->name:"";
9793 else
9794 oif_name = vxlan_sg->term_oif?vxlan_sg->term_oif->name:"";
9795
9796 if (cwd->addr_match && (vxlan_sg->sg.src.s_addr != cwd->addr.s_addr) &&
9797 (vxlan_sg->sg.grp.s_addr != cwd->addr.s_addr)) {
9798 return;
9799 }
9800 pim_inet4_dump("<src?>", vxlan_sg->sg.src, src_str, sizeof(src_str));
9801 pim_inet4_dump("<grp?>", vxlan_sg->sg.grp, grp_str, sizeof(grp_str));
9802 if (json) {
9803 json_object_object_get_ex(json, grp_str, &cwd->json_group);
9804
9805 if (!cwd->json_group) {
9806 cwd->json_group = json_object_new_object();
9807 json_object_object_add(json, grp_str,
9808 cwd->json_group);
9809 }
9810
9811 json_row = json_object_new_object();
9812 json_object_string_add(json_row, "source", src_str);
9813 json_object_string_add(json_row, "group", grp_str);
9814 json_object_string_add(json_row, "input", iif_name);
9815 json_object_string_add(json_row, "output", oif_name);
9816 if (installed)
9817 json_object_boolean_true_add(json_row, "installed");
9818 else
9819 json_object_boolean_false_add(json_row, "installed");
9820 json_object_object_add(cwd->json_group, src_str, json_row);
9821 } else {
9822 vty_out(vty, "%-15s %-15s %-15s %-15s %-5s\n",
9823 src_str, grp_str, iif_name, oif_name,
9824 installed?"I":"");
9825 }
9826}
9827
9828static void pim_show_vxlan_sg_hash_entry(struct hash_backet *backet, void *arg)
9829{
9830 pim_show_vxlan_sg_entry((struct pim_vxlan_sg *)backet->data,
9831 (struct pim_sg_cache_walk_data *)arg);
9832}
9833
9834static void pim_show_vxlan_sg(struct pim_instance *pim,
9835 struct vty *vty, bool uj)
9836{
9837 json_object *json = NULL;
9838 struct pim_sg_cache_walk_data cwd;
9839
9840 if (uj) {
9841 json = json_object_new_object();
9842 } else {
9843 vty_out(vty, "Codes: I -> installed\n");
9844 vty_out(vty,
9845 "Source Group Input Output Flags\n");
9846 }
9847
9848 memset(&cwd, 0, sizeof(cwd));
9849 cwd.vty = vty;
9850 cwd.json = json;
9851 hash_iterate(pim->vxlan.sg_hash, pim_show_vxlan_sg_hash_entry, &cwd);
9852
9853 if (uj) {
9854 vty_out(vty, "%s\n", json_object_to_json_string_ext(
9855 json, JSON_C_TO_STRING_PRETTY));
9856 json_object_free(json);
9857 }
9858}
9859
9860static void pim_show_vxlan_sg_match_addr(struct pim_instance *pim,
9861 struct vty *vty, char *addr_str, bool uj)
9862{
9863 json_object *json = NULL;
9864 struct pim_sg_cache_walk_data cwd;
9865 int result = 0;
9866
9867 memset(&cwd, 0, sizeof(cwd));
9868 result = inet_pton(AF_INET, addr_str, &cwd.addr);
9869 if (result <= 0) {
9870 vty_out(vty, "Bad address %s: errno=%d: %s\n", addr_str,
9871 errno, safe_strerror(errno));
9872 return;
9873 }
9874
9875 if (uj) {
9876 json = json_object_new_object();
9877 } else {
9878 vty_out(vty, "Codes: I -> installed\n");
9879 vty_out(vty,
9880 "Source Group Input Output Flags\n");
9881 }
9882
9883 cwd.vty = vty;
9884 cwd.json = json;
9885 cwd.addr_match = TRUE;
9886 hash_iterate(pim->vxlan.sg_hash, pim_show_vxlan_sg_hash_entry, &cwd);
9887
9888 if (uj) {
9889 vty_out(vty, "%s\n", json_object_to_json_string_ext(
9890 json, JSON_C_TO_STRING_PRETTY));
9891 json_object_free(json);
9892 }
9893}
9894
9895static void pim_show_vxlan_sg_one(struct pim_instance *pim,
9896 struct vty *vty, char *src_str, char *grp_str, bool uj)
9897{
9898 json_object *json = NULL;
9899 struct prefix_sg sg;
9900 int result = 0;
9901 struct pim_vxlan_sg *vxlan_sg;
9902 const char *iif_name;
9903 bool installed;
9904 const char *oif_name;
9905
9906 result = inet_pton(AF_INET, src_str, &sg.src);
9907 if (result <= 0) {
9908 vty_out(vty, "Bad src address %s: errno=%d: %s\n", src_str,
9909 errno, safe_strerror(errno));
9910 return;
9911 }
9912 result = inet_pton(AF_INET, grp_str, &sg.grp);
9913 if (result <= 0) {
9914 vty_out(vty, "Bad grp address %s: errno=%d: %s\n", grp_str,
9915 errno, safe_strerror(errno));
9916 return;
9917 }
9918
9919 sg.family = AF_INET;
9920 sg.prefixlen = IPV4_MAX_BITLEN;
9921 if (uj)
9922 json = json_object_new_object();
9923
9924 vxlan_sg = pim_vxlan_sg_find(pim, &sg);
9925 if (vxlan_sg) {
9926 installed = (vxlan_sg->up)?TRUE:FALSE;
9927 iif_name = vxlan_sg->iif?vxlan_sg->iif->name:"-";
9928
9929 if (pim_vxlan_is_orig_mroute(vxlan_sg))
9930 oif_name =
9931 vxlan_sg->orig_oif?vxlan_sg->orig_oif->name:"";
9932 else
9933 oif_name =
9934 vxlan_sg->term_oif?vxlan_sg->term_oif->name:"";
9935
9936 if (uj) {
9937 json_object_string_add(json, "source", src_str);
9938 json_object_string_add(json, "group", grp_str);
9939 json_object_string_add(json, "input", iif_name);
9940 json_object_string_add(json, "output", oif_name);
9941 if (installed)
9942 json_object_boolean_true_add(json, "installed");
9943 else
9944 json_object_boolean_false_add(json,
9945 "installed");
9946 } else {
9947 vty_out(vty, "SG : %s\n", vxlan_sg->sg_str);
9948 vty_out(vty, " Input : %s\n", iif_name);
9949 vty_out(vty, " Output : %s\n", oif_name);
9950 vty_out(vty, " installed : %s\n",
9951 installed?"yes":"no");
9952 }
9953 }
9954
9955 if (uj) {
9956 vty_out(vty, "%s\n", json_object_to_json_string_ext(
9957 json, JSON_C_TO_STRING_PRETTY));
9958 json_object_free(json);
9959 }
9960}
9961
9962DEFUN (show_ip_pim_vxlan_sg,
9963 show_ip_pim_vxlan_sg_cmd,
9964 "show ip pim [vrf NAME] vxlan-groups [A.B.C.D [A.B.C.D]] [json]",
9965 SHOW_STR
9966 IP_STR
9967 PIM_STR
9968 VRF_CMD_HELP_STR
9969 "VxLAN BUM groups\n"
9970 "source or group ip\n"
9971 "group ip\n"
9972 JSON_STR)
9973{
9974 bool uj = use_json(argc, argv);
9975 struct vrf *vrf;
9976 int idx = 2;
9977
9978 vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9979
9980 if (!vrf)
9981 return CMD_WARNING;
9982
9983 char *src_ip = argv_find(argv, argc, "A.B.C.D", &idx) ?
9984 argv[idx++]->arg:NULL;
9985 char *grp_ip = idx < argc && argv_find(argv, argc, "A.B.C.D", &idx) ?
9986 argv[idx]->arg:NULL;
9987
9988 if (src_ip && grp_ip)
9989 pim_show_vxlan_sg_one(vrf->info, vty, src_ip, grp_ip, uj);
9990 else if (src_ip)
9991 pim_show_vxlan_sg_match_addr(vrf->info, vty, src_ip, uj);
9992 else
9993 pim_show_vxlan_sg(vrf->info, vty, uj);
9994
9995 return CMD_SUCCESS;
9996}
9997
9998static void pim_show_vxlan_sg_work(struct pim_instance *pim,
9999 struct vty *vty, bool uj)
10000{
10001 json_object *json = NULL;
10002 struct pim_sg_cache_walk_data cwd;
10003 struct listnode *node;
10004 struct pim_vxlan_sg *vxlan_sg;
10005
10006 if (uj) {
10007 json = json_object_new_object();
10008 } else {
10009 vty_out(vty, "Codes: I -> installed\n");
10010 vty_out(vty,
10011 "Source Group Input Flags\n");
10012 }
10013
10014 memset(&cwd, 0, sizeof(cwd));
10015 cwd.vty = vty;
10016 cwd.json = json;
10017 for (ALL_LIST_ELEMENTS_RO(pim_vxlan_p->work_list, node, vxlan_sg))
10018 pim_show_vxlan_sg_entry(vxlan_sg, &cwd);
10019
10020 if (uj) {
10021 vty_out(vty, "%s\n", json_object_to_json_string_ext(
10022 json, JSON_C_TO_STRING_PRETTY));
10023 json_object_free(json);
10024 }
10025}
10026
10027DEFUN_HIDDEN (show_ip_pim_vxlan_sg_work,
10028 show_ip_pim_vxlan_sg_work_cmd,
10029 "show ip pim [vrf NAME] vxlan-work [json]",
10030 SHOW_STR
10031 IP_STR
10032 PIM_STR
10033 VRF_CMD_HELP_STR
10034 "VxLAN work list\n"
10035 JSON_STR)
10036{
10037 bool uj = use_json(argc, argv);
10038 struct vrf *vrf;
10039 int idx = 2;
10040
10041 vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
10042
10043 if (!vrf)
10044 return CMD_WARNING;
10045
10046 pim_show_vxlan_sg_work(vrf->info, vty, uj);
10047
10048 return CMD_SUCCESS;
10049}
10050
7c85225c
AK
10051DEFUN_HIDDEN (no_ip_pim_mlag,
10052 no_ip_pim_mlag_cmd,
10053 "no ip pim mlag",
10054 NO_STR
10055 IP_STR
10056 PIM_STR
10057 "MLAG\n")
10058{
10059 struct in_addr addr;
10060
10061 addr.s_addr = 0;
10062 pim_vxlan_mlag_update(TRUE /*mlag_enable*/,
10063 FALSE /*peer_state*/, PIM_VXLAN_MLAG_ROLE_SECONDARY,
10064 NULL/*peerlink*/, &addr);
10065
10066 return CMD_SUCCESS;
10067}
10068
10069DEFUN_HIDDEN (ip_pim_mlag,
10070 ip_pim_mlag_cmd,
10071 "ip pim mlag INTERFACE role [primary|secondary] state [up|down] addr A.B.C.D",
10072 IP_STR
10073 PIM_STR
10074 "MLAG\n"
10075 "peerlink sub interface\n"
10076 "MLAG role\n"
10077 "MLAG role primary\n"
10078 "MLAG role secondary\n"
10079 "peer session state\n"
10080 "peer session state up\n"
10081 "peer session state down\n"
10082 "configure PIP\n"
10083 "unique ip address\n")
10084{
10085 struct interface *ifp;
10086 const char *peerlink;
10087 uint32_t role;
10088 int idx;
10089 bool peer_state;
10090 int result;
10091 struct in_addr reg_addr;
10092
10093 idx = 3;
10094 peerlink = argv[idx]->arg;
10095 ifp = if_lookup_by_name(peerlink, VRF_DEFAULT);
10096 if (!ifp) {
10097 vty_out(vty, "No such interface name %s\n", peerlink);
10098 return CMD_WARNING;
10099 }
10100
10101 idx += 2;
10102 if (!strcmp(argv[idx]->arg, "primary")) {
10103 role = PIM_VXLAN_MLAG_ROLE_PRIMARY;
10104 } else if (!strcmp(argv[idx]->arg, "secondary")) {
10105 role = PIM_VXLAN_MLAG_ROLE_SECONDARY;
10106 } else {
10107 vty_out(vty, "unknown MLAG role %s\n", argv[idx]->arg);
10108 return CMD_WARNING;
10109 }
10110
10111 idx += 2;
10112 if (!strcmp(argv[idx]->arg, "up")) {
10113 peer_state = TRUE;
10114 } else if (strcmp(argv[idx]->arg, "down")) {
10115 peer_state = FALSE;
10116 } else {
10117 vty_out(vty, "unknown MLAG state %s\n", argv[idx]->arg);
10118 return CMD_WARNING;
10119 }
10120
10121 idx += 2;
10122 result = inet_pton(AF_INET, argv[idx]->arg, &reg_addr);
10123 if (result <= 0) {
10124 vty_out(vty, "%% Bad reg address %s: errno=%d: %s\n",
10125 argv[idx]->arg,
10126 errno, safe_strerror(errno));
10127 return CMD_WARNING_CONFIG_FAILED;
10128 }
10129 pim_vxlan_mlag_update(TRUE, peer_state, role, ifp, &reg_addr);
10130
10131 return CMD_SUCCESS;
10132}
10133
c68ba0d7 10134void pim_cmd_init(void)
12e41d03 10135{
d62a17ae 10136 install_node(&interface_node,
10137 pim_interface_config_write); /* INTERFACE_NODE */
10138 if_cmd_init();
10139
10140 install_node(&debug_node, pim_debug_config_write);
10141
70fd22bd
DS
10142 install_element(ENABLE_NODE, &pim_test_sg_keepalive_cmd);
10143
d62a17ae 10144 install_element(CONFIG_NODE, &ip_pim_rp_cmd);
9ecb7b77 10145 install_element(VRF_NODE, &ip_pim_rp_cmd);
d62a17ae 10146 install_element(CONFIG_NODE, &no_ip_pim_rp_cmd);
9ecb7b77 10147 install_element(VRF_NODE, &no_ip_pim_rp_cmd);
d62a17ae 10148 install_element(CONFIG_NODE, &ip_pim_rp_prefix_list_cmd);
4f9f3925 10149 install_element(VRF_NODE, &ip_pim_rp_prefix_list_cmd);
d62a17ae 10150 install_element(CONFIG_NODE, &no_ip_pim_rp_prefix_list_cmd);
4f9f3925 10151 install_element(VRF_NODE, &no_ip_pim_rp_prefix_list_cmd);
d62a17ae 10152 install_element(CONFIG_NODE, &no_ip_pim_ssm_prefix_list_cmd);
4f9f3925 10153 install_element(VRF_NODE, &no_ip_pim_ssm_prefix_list_cmd);
d62a17ae 10154 install_element(CONFIG_NODE, &no_ip_pim_ssm_prefix_list_name_cmd);
4f9f3925 10155 install_element(VRF_NODE, &no_ip_pim_ssm_prefix_list_name_cmd);
d62a17ae 10156 install_element(CONFIG_NODE, &ip_pim_ssm_prefix_list_cmd);
4f9f3925 10157 install_element(VRF_NODE, &ip_pim_ssm_prefix_list_cmd);
d62a17ae 10158 install_element(CONFIG_NODE, &ip_pim_register_suppress_cmd);
4f9f3925 10159 install_element(VRF_NODE, &ip_pim_register_suppress_cmd);
d62a17ae 10160 install_element(CONFIG_NODE, &no_ip_pim_register_suppress_cmd);
4f9f3925 10161 install_element(VRF_NODE, &no_ip_pim_register_suppress_cmd);
d62a17ae 10162 install_element(CONFIG_NODE, &ip_pim_spt_switchover_infinity_cmd);
4f9f3925 10163 install_element(VRF_NODE, &ip_pim_spt_switchover_infinity_cmd);
d62a17ae 10164 install_element(CONFIG_NODE, &ip_pim_spt_switchover_infinity_plist_cmd);
4f9f3925 10165 install_element(VRF_NODE, &ip_pim_spt_switchover_infinity_plist_cmd);
d62a17ae 10166 install_element(CONFIG_NODE, &no_ip_pim_spt_switchover_infinity_cmd);
4f9f3925 10167 install_element(VRF_NODE, &no_ip_pim_spt_switchover_infinity_cmd);
d62a17ae 10168 install_element(CONFIG_NODE,
10169 &no_ip_pim_spt_switchover_infinity_plist_cmd);
4f9f3925 10170 install_element(VRF_NODE, &no_ip_pim_spt_switchover_infinity_plist_cmd);
d62a17ae 10171 install_element(CONFIG_NODE, &ip_pim_joinprune_time_cmd);
4f9f3925 10172 install_element(VRF_NODE, &ip_pim_joinprune_time_cmd);
d62a17ae 10173 install_element(CONFIG_NODE, &no_ip_pim_joinprune_time_cmd);
4f9f3925 10174 install_element(VRF_NODE, &no_ip_pim_joinprune_time_cmd);
d62a17ae 10175 install_element(CONFIG_NODE, &ip_pim_keep_alive_cmd);
4f9f3925 10176 install_element(VRF_NODE, &ip_pim_keep_alive_cmd);
cc14df13
DS
10177 install_element(CONFIG_NODE, &ip_pim_rp_keep_alive_cmd);
10178 install_element(VRF_NODE, &ip_pim_rp_keep_alive_cmd);
d62a17ae 10179 install_element(CONFIG_NODE, &no_ip_pim_keep_alive_cmd);
4f9f3925 10180 install_element(VRF_NODE, &no_ip_pim_keep_alive_cmd);
cc14df13
DS
10181 install_element(CONFIG_NODE, &no_ip_pim_rp_keep_alive_cmd);
10182 install_element(VRF_NODE, &no_ip_pim_rp_keep_alive_cmd);
d62a17ae 10183 install_element(CONFIG_NODE, &ip_pim_packets_cmd);
4f9f3925 10184 install_element(VRF_NODE, &ip_pim_packets_cmd);
d62a17ae 10185 install_element(CONFIG_NODE, &no_ip_pim_packets_cmd);
4f9f3925 10186 install_element(VRF_NODE, &no_ip_pim_packets_cmd);
d62a17ae 10187 install_element(CONFIG_NODE, &ip_pim_v6_secondary_cmd);
4f9f3925 10188 install_element(VRF_NODE, &ip_pim_v6_secondary_cmd);
d62a17ae 10189 install_element(CONFIG_NODE, &no_ip_pim_v6_secondary_cmd);
4f9f3925 10190 install_element(VRF_NODE, &no_ip_pim_v6_secondary_cmd);
d62a17ae 10191 install_element(CONFIG_NODE, &ip_ssmpingd_cmd);
4f9f3925 10192 install_element(VRF_NODE, &ip_ssmpingd_cmd);
d62a17ae 10193 install_element(CONFIG_NODE, &no_ip_ssmpingd_cmd);
4f9f3925 10194 install_element(VRF_NODE, &no_ip_ssmpingd_cmd);
d62a17ae 10195 install_element(CONFIG_NODE, &ip_msdp_peer_cmd);
4f9f3925 10196 install_element(VRF_NODE, &ip_msdp_peer_cmd);
d62a17ae 10197 install_element(CONFIG_NODE, &no_ip_msdp_peer_cmd);
4f9f3925 10198 install_element(VRF_NODE, &no_ip_msdp_peer_cmd);
d62a17ae 10199 install_element(CONFIG_NODE, &ip_pim_ecmp_cmd);
4f9f3925 10200 install_element(VRF_NODE, &ip_pim_ecmp_cmd);
d62a17ae 10201 install_element(CONFIG_NODE, &no_ip_pim_ecmp_cmd);
4f9f3925 10202 install_element(VRF_NODE, &no_ip_pim_ecmp_cmd);
d62a17ae 10203 install_element(CONFIG_NODE, &ip_pim_ecmp_rebalance_cmd);
4f9f3925 10204 install_element(VRF_NODE, &ip_pim_ecmp_rebalance_cmd);
d62a17ae 10205 install_element(CONFIG_NODE, &no_ip_pim_ecmp_rebalance_cmd);
4f9f3925 10206 install_element(VRF_NODE, &no_ip_pim_ecmp_rebalance_cmd);
7c85225c
AK
10207 install_element(CONFIG_NODE, &ip_pim_mlag_cmd);
10208 install_element(CONFIG_NODE, &no_ip_pim_mlag_cmd);
d62a17ae 10209
10210 install_element(INTERFACE_NODE, &interface_ip_igmp_cmd);
10211 install_element(INTERFACE_NODE, &interface_no_ip_igmp_cmd);
10212 install_element(INTERFACE_NODE, &interface_ip_igmp_join_cmd);
10213 install_element(INTERFACE_NODE, &interface_no_ip_igmp_join_cmd);
10214 install_element(INTERFACE_NODE, &interface_ip_igmp_version_cmd);
10215 install_element(INTERFACE_NODE, &interface_no_ip_igmp_version_cmd);
10216 install_element(INTERFACE_NODE, &interface_ip_igmp_query_interval_cmd);
10217 install_element(INTERFACE_NODE,
10218 &interface_no_ip_igmp_query_interval_cmd);
10219 install_element(INTERFACE_NODE,
10220 &interface_ip_igmp_query_max_response_time_cmd);
10221 install_element(INTERFACE_NODE,
10222 &interface_no_ip_igmp_query_max_response_time_cmd);
10223 install_element(INTERFACE_NODE,
10224 &interface_ip_igmp_query_max_response_time_dsec_cmd);
10225 install_element(INTERFACE_NODE,
10226 &interface_no_ip_igmp_query_max_response_time_dsec_cmd);
59115451
SP
10227 install_element(INTERFACE_NODE,
10228 &interface_ip_igmp_last_member_query_count_cmd);
10229 install_element(INTERFACE_NODE,
10230 &interface_no_ip_igmp_last_member_query_count_cmd);
10231 install_element(INTERFACE_NODE,
10232 &interface_ip_igmp_last_member_query_interval_cmd);
10233 install_element(INTERFACE_NODE,
10234 &interface_no_ip_igmp_last_member_query_interval_cmd);
414d885a 10235 install_element(INTERFACE_NODE, &interface_ip_pim_activeactive_cmd);
d62a17ae 10236 install_element(INTERFACE_NODE, &interface_ip_pim_ssm_cmd);
10237 install_element(INTERFACE_NODE, &interface_no_ip_pim_ssm_cmd);
10238 install_element(INTERFACE_NODE, &interface_ip_pim_sm_cmd);
10239 install_element(INTERFACE_NODE, &interface_no_ip_pim_sm_cmd);
2f5e937c 10240 install_element(INTERFACE_NODE, &interface_ip_pim_cmd);
10241 install_element(INTERFACE_NODE, &interface_no_ip_pim_cmd);
d62a17ae 10242 install_element(INTERFACE_NODE, &interface_ip_pim_drprio_cmd);
10243 install_element(INTERFACE_NODE, &interface_no_ip_pim_drprio_cmd);
10244 install_element(INTERFACE_NODE, &interface_ip_pim_hello_cmd);
10245 install_element(INTERFACE_NODE, &interface_no_ip_pim_hello_cmd);
b0f525a8
QY
10246 install_element(INTERFACE_NODE, &interface_ip_pim_boundary_oil_cmd);
10247 install_element(INTERFACE_NODE, &interface_no_ip_pim_boundary_oil_cmd);
d62a17ae 10248
10249 // Static mroutes NEB
10250 install_element(INTERFACE_NODE, &interface_ip_mroute_cmd);
10251 install_element(INTERFACE_NODE, &interface_ip_mroute_source_cmd);
10252 install_element(INTERFACE_NODE, &interface_no_ip_mroute_cmd);
10253 install_element(INTERFACE_NODE, &interface_no_ip_mroute_source_cmd);
10254
10255 install_element(VIEW_NODE, &show_ip_igmp_interface_cmd);
a25de56b 10256 install_element(VIEW_NODE, &show_ip_igmp_interface_vrf_all_cmd);
d62a17ae 10257 install_element(VIEW_NODE, &show_ip_igmp_join_cmd);
a25de56b 10258 install_element(VIEW_NODE, &show_ip_igmp_join_vrf_all_cmd);
d62a17ae 10259 install_element(VIEW_NODE, &show_ip_igmp_groups_cmd);
a25de56b 10260 install_element(VIEW_NODE, &show_ip_igmp_groups_vrf_all_cmd);
d62a17ae 10261 install_element(VIEW_NODE, &show_ip_igmp_groups_retransmissions_cmd);
10262 install_element(VIEW_NODE, &show_ip_igmp_sources_cmd);
10263 install_element(VIEW_NODE, &show_ip_igmp_sources_retransmissions_cmd);
21313cbf 10264 install_element(VIEW_NODE, &show_ip_igmp_statistics_cmd);
d62a17ae 10265 install_element(VIEW_NODE, &show_ip_pim_assert_cmd);
10266 install_element(VIEW_NODE, &show_ip_pim_assert_internal_cmd);
10267 install_element(VIEW_NODE, &show_ip_pim_assert_metric_cmd);
10268 install_element(VIEW_NODE, &show_ip_pim_assert_winner_metric_cmd);
10269 install_element(VIEW_NODE, &show_ip_pim_interface_traffic_cmd);
10270 install_element(VIEW_NODE, &show_ip_pim_interface_cmd);
a25de56b 10271 install_element(VIEW_NODE, &show_ip_pim_interface_vrf_all_cmd);
d62a17ae 10272 install_element(VIEW_NODE, &show_ip_pim_join_cmd);
a25de56b 10273 install_element(VIEW_NODE, &show_ip_pim_join_vrf_all_cmd);
d62a17ae 10274 install_element(VIEW_NODE, &show_ip_pim_local_membership_cmd);
10275 install_element(VIEW_NODE, &show_ip_pim_neighbor_cmd);
a25de56b 10276 install_element(VIEW_NODE, &show_ip_pim_neighbor_vrf_all_cmd);
d62a17ae 10277 install_element(VIEW_NODE, &show_ip_pim_rpf_cmd);
a25de56b 10278 install_element(VIEW_NODE, &show_ip_pim_rpf_vrf_all_cmd);
d62a17ae 10279 install_element(VIEW_NODE, &show_ip_pim_secondary_cmd);
10280 install_element(VIEW_NODE, &show_ip_pim_state_cmd);
a25de56b 10281 install_element(VIEW_NODE, &show_ip_pim_state_vrf_all_cmd);
d62a17ae 10282 install_element(VIEW_NODE, &show_ip_pim_upstream_cmd);
a25de56b 10283 install_element(VIEW_NODE, &show_ip_pim_upstream_vrf_all_cmd);
d62a17ae 10284 install_element(VIEW_NODE, &show_ip_pim_upstream_join_desired_cmd);
10285 install_element(VIEW_NODE, &show_ip_pim_upstream_rpf_cmd);
10286 install_element(VIEW_NODE, &show_ip_pim_rp_cmd);
a25de56b 10287 install_element(VIEW_NODE, &show_ip_pim_rp_vrf_all_cmd);
256392eb 10288 install_element(VIEW_NODE, &show_ip_pim_bsr_cmd);
d62a17ae 10289 install_element(VIEW_NODE, &show_ip_multicast_cmd);
a25de56b 10290 install_element(VIEW_NODE, &show_ip_multicast_vrf_all_cmd);
d62a17ae 10291 install_element(VIEW_NODE, &show_ip_mroute_cmd);
b283a4ca 10292 install_element(VIEW_NODE, &show_ip_mroute_vrf_all_cmd);
d62a17ae 10293 install_element(VIEW_NODE, &show_ip_mroute_count_cmd);
5c3aac90 10294 install_element(VIEW_NODE, &show_ip_mroute_count_vrf_all_cmd);
468b6f44
SP
10295 install_element(VIEW_NODE, &show_ip_mroute_summary_cmd);
10296 install_element(VIEW_NODE, &show_ip_mroute_summary_vrf_all_cmd);
d62a17ae 10297 install_element(VIEW_NODE, &show_ip_rib_cmd);
10298 install_element(VIEW_NODE, &show_ip_ssmpingd_cmd);
10299 install_element(VIEW_NODE, &show_debugging_pim_cmd);
10300 install_element(VIEW_NODE, &show_ip_pim_nexthop_cmd);
10301 install_element(VIEW_NODE, &show_ip_pim_nexthop_lookup_cmd);
321295c1 10302 install_element(VIEW_NODE, &show_ip_pim_bsrp_cmd);
0d1a4e24 10303 install_element(VIEW_NODE, &show_ip_pim_bsm_db_cmd);
415f6350 10304 install_element(VIEW_NODE, &show_ip_pim_statistics_cmd);
d62a17ae 10305
10306 install_element(ENABLE_NODE, &clear_ip_interfaces_cmd);
10307 install_element(ENABLE_NODE, &clear_ip_igmp_interfaces_cmd);
10308 install_element(ENABLE_NODE, &clear_ip_mroute_cmd);
10309 install_element(ENABLE_NODE, &clear_ip_pim_interfaces_cmd);
10310 install_element(ENABLE_NODE, &clear_ip_pim_interface_traffic_cmd);
10311 install_element(ENABLE_NODE, &clear_ip_pim_oil_cmd);
415f6350 10312 install_element(ENABLE_NODE, &clear_ip_pim_statistics_cmd);
d62a17ae 10313
10314 install_element(ENABLE_NODE, &debug_igmp_cmd);
10315 install_element(ENABLE_NODE, &no_debug_igmp_cmd);
10316 install_element(ENABLE_NODE, &debug_igmp_events_cmd);
10317 install_element(ENABLE_NODE, &no_debug_igmp_events_cmd);
10318 install_element(ENABLE_NODE, &debug_igmp_packets_cmd);
10319 install_element(ENABLE_NODE, &no_debug_igmp_packets_cmd);
10320 install_element(ENABLE_NODE, &debug_igmp_trace_cmd);
10321 install_element(ENABLE_NODE, &no_debug_igmp_trace_cmd);
10322 install_element(ENABLE_NODE, &debug_mroute_cmd);
10323 install_element(ENABLE_NODE, &debug_mroute_detail_cmd);
10324 install_element(ENABLE_NODE, &no_debug_mroute_cmd);
10325 install_element(ENABLE_NODE, &no_debug_mroute_detail_cmd);
35a12720
MS
10326 install_element(ENABLE_NODE, &debug_pim_static_cmd);
10327 install_element(ENABLE_NODE, &no_debug_pim_static_cmd);
d62a17ae 10328 install_element(ENABLE_NODE, &debug_pim_cmd);
10329 install_element(ENABLE_NODE, &no_debug_pim_cmd);
40f1f31b
DS
10330 install_element(ENABLE_NODE, &debug_pim_nht_cmd);
10331 install_element(ENABLE_NODE, &no_debug_pim_nht_cmd);
3d225d48
DS
10332 install_element(ENABLE_NODE, &debug_pim_nht_rp_cmd);
10333 install_element(ENABLE_NODE, &no_debug_pim_nht_rp_cmd);
d62a17ae 10334 install_element(ENABLE_NODE, &debug_pim_events_cmd);
10335 install_element(ENABLE_NODE, &no_debug_pim_events_cmd);
10336 install_element(ENABLE_NODE, &debug_pim_packets_cmd);
10337 install_element(ENABLE_NODE, &no_debug_pim_packets_cmd);
10338 install_element(ENABLE_NODE, &debug_pim_packetdump_send_cmd);
10339 install_element(ENABLE_NODE, &no_debug_pim_packetdump_send_cmd);
10340 install_element(ENABLE_NODE, &debug_pim_packetdump_recv_cmd);
10341 install_element(ENABLE_NODE, &no_debug_pim_packetdump_recv_cmd);
10342 install_element(ENABLE_NODE, &debug_pim_trace_cmd);
10343 install_element(ENABLE_NODE, &no_debug_pim_trace_cmd);
56c238c9
DS
10344 install_element(ENABLE_NODE, &debug_pim_trace_detail_cmd);
10345 install_element(ENABLE_NODE, &no_debug_pim_trace_detail_cmd);
d62a17ae 10346 install_element(ENABLE_NODE, &debug_ssmpingd_cmd);
10347 install_element(ENABLE_NODE, &no_debug_ssmpingd_cmd);
10348 install_element(ENABLE_NODE, &debug_pim_zebra_cmd);
10349 install_element(ENABLE_NODE, &no_debug_pim_zebra_cmd);
4d913fa6
AK
10350 install_element(ENABLE_NODE, &debug_pim_vxlan_cmd);
10351 install_element(ENABLE_NODE, &no_debug_pim_vxlan_cmd);
d62a17ae 10352 install_element(ENABLE_NODE, &debug_msdp_cmd);
10353 install_element(ENABLE_NODE, &no_debug_msdp_cmd);
d62a17ae 10354 install_element(ENABLE_NODE, &debug_msdp_events_cmd);
10355 install_element(ENABLE_NODE, &no_debug_msdp_events_cmd);
d62a17ae 10356 install_element(ENABLE_NODE, &debug_msdp_packets_cmd);
10357 install_element(ENABLE_NODE, &no_debug_msdp_packets_cmd);
4d9ad5dc
MS
10358 install_element(ENABLE_NODE, &debug_mtrace_cmd);
10359 install_element(ENABLE_NODE, &no_debug_mtrace_cmd);
09524ccf 10360 install_element(ENABLE_NODE, &debug_bsm_cmd);
10361 install_element(ENABLE_NODE, &no_debug_bsm_cmd);
d62a17ae 10362
10363 install_element(CONFIG_NODE, &debug_igmp_cmd);
10364 install_element(CONFIG_NODE, &no_debug_igmp_cmd);
10365 install_element(CONFIG_NODE, &debug_igmp_events_cmd);
10366 install_element(CONFIG_NODE, &no_debug_igmp_events_cmd);
10367 install_element(CONFIG_NODE, &debug_igmp_packets_cmd);
10368 install_element(CONFIG_NODE, &no_debug_igmp_packets_cmd);
10369 install_element(CONFIG_NODE, &debug_igmp_trace_cmd);
10370 install_element(CONFIG_NODE, &no_debug_igmp_trace_cmd);
10371 install_element(CONFIG_NODE, &debug_mroute_cmd);
10372 install_element(CONFIG_NODE, &debug_mroute_detail_cmd);
10373 install_element(CONFIG_NODE, &no_debug_mroute_cmd);
10374 install_element(CONFIG_NODE, &no_debug_mroute_detail_cmd);
35a12720
MS
10375 install_element(CONFIG_NODE, &debug_pim_static_cmd);
10376 install_element(CONFIG_NODE, &no_debug_pim_static_cmd);
d62a17ae 10377 install_element(CONFIG_NODE, &debug_pim_cmd);
10378 install_element(CONFIG_NODE, &no_debug_pim_cmd);
40f1f31b
DS
10379 install_element(CONFIG_NODE, &debug_pim_nht_cmd);
10380 install_element(CONFIG_NODE, &no_debug_pim_nht_cmd);
3d225d48
DS
10381 install_element(CONFIG_NODE, &debug_pim_nht_rp_cmd);
10382 install_element(CONFIG_NODE, &no_debug_pim_nht_rp_cmd);
d62a17ae 10383 install_element(CONFIG_NODE, &debug_pim_events_cmd);
10384 install_element(CONFIG_NODE, &no_debug_pim_events_cmd);
10385 install_element(CONFIG_NODE, &debug_pim_packets_cmd);
10386 install_element(CONFIG_NODE, &no_debug_pim_packets_cmd);
10387 install_element(CONFIG_NODE, &debug_pim_trace_cmd);
10388 install_element(CONFIG_NODE, &no_debug_pim_trace_cmd);
56c238c9
DS
10389 install_element(CONFIG_NODE, &debug_pim_trace_detail_cmd);
10390 install_element(CONFIG_NODE, &no_debug_pim_trace_detail_cmd);
d62a17ae 10391 install_element(CONFIG_NODE, &debug_ssmpingd_cmd);
10392 install_element(CONFIG_NODE, &no_debug_ssmpingd_cmd);
10393 install_element(CONFIG_NODE, &debug_pim_zebra_cmd);
10394 install_element(CONFIG_NODE, &no_debug_pim_zebra_cmd);
4d913fa6
AK
10395 install_element(CONFIG_NODE, &debug_pim_vxlan_cmd);
10396 install_element(CONFIG_NODE, &no_debug_pim_vxlan_cmd);
d62a17ae 10397 install_element(CONFIG_NODE, &debug_msdp_cmd);
10398 install_element(CONFIG_NODE, &no_debug_msdp_cmd);
d62a17ae 10399 install_element(CONFIG_NODE, &debug_msdp_events_cmd);
10400 install_element(CONFIG_NODE, &no_debug_msdp_events_cmd);
d62a17ae 10401 install_element(CONFIG_NODE, &debug_msdp_packets_cmd);
10402 install_element(CONFIG_NODE, &no_debug_msdp_packets_cmd);
4d9ad5dc
MS
10403 install_element(CONFIG_NODE, &debug_mtrace_cmd);
10404 install_element(CONFIG_NODE, &no_debug_mtrace_cmd);
09524ccf 10405 install_element(CONFIG_NODE, &debug_bsm_cmd);
10406 install_element(CONFIG_NODE, &no_debug_bsm_cmd);
02a16316 10407
d62a17ae 10408 install_element(CONFIG_NODE, &ip_msdp_mesh_group_member_cmd);
02a16316 10409 install_element(VRF_NODE, &ip_msdp_mesh_group_member_cmd);
d62a17ae 10410 install_element(CONFIG_NODE, &no_ip_msdp_mesh_group_member_cmd);
1b973cb7 10411 install_element(VRF_NODE, &no_ip_msdp_mesh_group_member_cmd);
d62a17ae 10412 install_element(CONFIG_NODE, &ip_msdp_mesh_group_source_cmd);
02a16316 10413 install_element(VRF_NODE, &ip_msdp_mesh_group_source_cmd);
d62a17ae 10414 install_element(CONFIG_NODE, &no_ip_msdp_mesh_group_source_cmd);
02a16316 10415 install_element(VRF_NODE, &no_ip_msdp_mesh_group_source_cmd);
d62a17ae 10416 install_element(VIEW_NODE, &show_ip_msdp_peer_detail_cmd);
a25de56b 10417 install_element(VIEW_NODE, &show_ip_msdp_peer_detail_vrf_all_cmd);
d62a17ae 10418 install_element(VIEW_NODE, &show_ip_msdp_sa_detail_cmd);
a25de56b 10419 install_element(VIEW_NODE, &show_ip_msdp_sa_detail_vrf_all_cmd);
d62a17ae 10420 install_element(VIEW_NODE, &show_ip_msdp_sa_sg_cmd);
47bf9e21 10421 install_element(VIEW_NODE, &show_ip_msdp_sa_sg_vrf_all_cmd);
d62a17ae 10422 install_element(VIEW_NODE, &show_ip_msdp_mesh_group_cmd);
a25de56b 10423 install_element(VIEW_NODE, &show_ip_msdp_mesh_group_vrf_all_cmd);
d62a17ae 10424 install_element(VIEW_NODE, &show_ip_pim_ssm_range_cmd);
10425 install_element(VIEW_NODE, &show_ip_pim_group_type_cmd);
f1e2901a
AK
10426 install_element(VIEW_NODE, &show_ip_pim_vxlan_sg_cmd);
10427 install_element(VIEW_NODE, &show_ip_pim_vxlan_sg_work_cmd);
d62a17ae 10428 install_element(INTERFACE_NODE, &interface_pim_use_source_cmd);
10429 install_element(INTERFACE_NODE, &interface_no_pim_use_source_cmd);
16c926c8 10430 /* Install BSM command */
10431 install_element(INTERFACE_NODE, &ip_pim_bsm_cmd);
10432 install_element(INTERFACE_NODE, &no_ip_pim_bsm_cmd);
10433 install_element(INTERFACE_NODE, &ip_pim_ucast_bsm_cmd);
10434 install_element(INTERFACE_NODE, &no_ip_pim_ucast_bsm_cmd);
d62a17ae 10435 /* Install BFD command */
10436 install_element(INTERFACE_NODE, &ip_pim_bfd_cmd);
10437 install_element(INTERFACE_NODE, &ip_pim_bfd_param_cmd);
10438 install_element(INTERFACE_NODE, &no_ip_pim_bfd_cmd);
64dc4b2d 10439#if HAVE_BFDD == 0
d62a17ae 10440 install_element(INTERFACE_NODE, &no_ip_pim_bfd_param_cmd);
64dc4b2d 10441#endif /* !HAVE_BFDD */
12e41d03 10442}