]> git.proxmox.com Git - mirror_frr.git/blob - pimd/pim_cmd.c
Merge pull request #12798 from donaldsharp/rib_match_multicast
[mirror_frr.git] / pimd / pim_cmd.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * PIM for Quagga
4 * Copyright (C) 2008 Everton da Silva Marques
5 */
6
7 #include <zebra.h>
8
9 #include "lib/json.h"
10 #include "command.h"
11 #include "if.h"
12 #include "prefix.h"
13 #include "zclient.h"
14 #include "plist.h"
15 #include "hash.h"
16 #include "nexthop.h"
17 #include "vrf.h"
18 #include "ferr.h"
19
20 #include "pimd.h"
21 #include "pim_mroute.h"
22 #include "pim_cmd.h"
23 #include "pim_iface.h"
24 #include "pim_vty.h"
25 #include "pim_mroute.h"
26 #include "pim_str.h"
27 #include "pim_igmp.h"
28 #include "pim_igmpv3.h"
29 #include "pim_sock.h"
30 #include "pim_time.h"
31 #include "pim_util.h"
32 #include "pim_oil.h"
33 #include "pim_neighbor.h"
34 #include "pim_pim.h"
35 #include "pim_ifchannel.h"
36 #include "pim_hello.h"
37 #include "pim_msg.h"
38 #include "pim_upstream.h"
39 #include "pim_rpf.h"
40 #include "pim_macro.h"
41 #include "pim_ssmpingd.h"
42 #include "pim_zebra.h"
43 #include "pim_static.h"
44 #include "pim_rp.h"
45 #include "pim_zlookup.h"
46 #include "pim_msdp.h"
47 #include "pim_ssm.h"
48 #include "pim_nht.h"
49 #include "pim_bfd.h"
50 #include "pim_vxlan.h"
51 #include "pim_mlag.h"
52 #include "bfd.h"
53 #include "pim_bsm.h"
54 #include "lib/northbound_cli.h"
55 #include "pim_errors.h"
56 #include "pim_nb.h"
57 #include "pim_addr.h"
58 #include "pim_cmd_common.h"
59
60 #include "pimd/pim_cmd_clippy.c"
61
62 static struct cmd_node debug_node = {
63 .name = "debug",
64 .node = DEBUG_NODE,
65 .prompt = "",
66 .config_write = pim_debug_config_write,
67 };
68
69 static struct vrf *pim_cmd_lookup_vrf(struct vty *vty, struct cmd_token *argv[],
70 const int argc, int *idx)
71 {
72 struct vrf *vrf;
73
74 if (argv_find(argv, argc, "NAME", idx))
75 vrf = vrf_lookup_by_name(argv[*idx]->arg);
76 else
77 vrf = vrf_lookup_by_id(VRF_DEFAULT);
78
79 if (!vrf)
80 vty_out(vty, "Specified VRF: %s does not exist\n",
81 argv[*idx]->arg);
82
83 return vrf;
84 }
85
86 static void pim_show_assert_helper(struct vty *vty,
87 struct pim_interface *pim_ifp,
88 struct pim_ifchannel *ch, time_t now)
89 {
90 char winner_str[INET_ADDRSTRLEN];
91 struct in_addr ifaddr;
92 char uptime[10];
93 char timer[10];
94 char buf[PREFIX_STRLEN];
95
96 ifaddr = pim_ifp->primary_address;
97
98 pim_inet4_dump("<assrt_win?>", ch->ifassert_winner, winner_str,
99 sizeof(winner_str));
100
101 pim_time_uptime(uptime, sizeof(uptime), now - ch->ifassert_creation);
102 pim_time_timer_to_mmss(timer, sizeof(timer), ch->t_ifassert_timer);
103
104 vty_out(vty, "%-16s %-15s %-15pPAs %-15pPAs %-6s %-15s %-8s %-5s\n",
105 ch->interface->name,
106 inet_ntop(AF_INET, &ifaddr, buf, sizeof(buf)), &ch->sg.src,
107 &ch->sg.grp, pim_ifchannel_ifassert_name(ch->ifassert_state),
108 winner_str, uptime, timer);
109 }
110
111 static void pim_show_assert(struct pim_instance *pim, struct vty *vty)
112 {
113 struct pim_interface *pim_ifp;
114 struct pim_ifchannel *ch;
115 struct interface *ifp;
116 time_t now;
117
118 now = pim_time_monotonic_sec();
119
120 vty_out(vty,
121 "Interface Address Source Group State Winner Uptime Timer\n");
122
123 FOR_ALL_INTERFACES (pim->vrf, ifp) {
124 pim_ifp = ifp->info;
125 if (!pim_ifp)
126 continue;
127
128 RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
129 if (ch->ifassert_state == PIM_IFASSERT_NOINFO)
130 continue;
131
132 pim_show_assert_helper(vty, pim_ifp, ch, now);
133 } /* scan interface channels */
134 }
135 }
136
137 static void pim_show_assert_internal_helper(struct vty *vty,
138 struct pim_interface *pim_ifp,
139 struct pim_ifchannel *ch)
140 {
141 struct in_addr ifaddr;
142 char buf[PREFIX_STRLEN];
143
144 ifaddr = pim_ifp->primary_address;
145
146 vty_out(vty, "%-16s %-15s %-15pPAs %-15pPAs %-3s %-3s %-3s %-4s\n",
147 ch->interface->name,
148 inet_ntop(AF_INET, &ifaddr, buf, sizeof(buf)), &ch->sg.src,
149 &ch->sg.grp,
150 PIM_IF_FLAG_TEST_COULD_ASSERT(ch->flags) ? "yes" : "no",
151 pim_macro_ch_could_assert_eval(ch) ? "yes" : "no",
152 PIM_IF_FLAG_TEST_ASSERT_TRACKING_DESIRED(ch->flags) ? "yes"
153 : "no",
154 pim_macro_assert_tracking_desired_eval(ch) ? "yes" : "no");
155 }
156
157 static void pim_show_assert_internal(struct pim_instance *pim, struct vty *vty)
158 {
159 struct pim_interface *pim_ifp;
160 struct pim_ifchannel *ch;
161 struct interface *ifp;
162
163 vty_out(vty,
164 "CA: CouldAssert\n"
165 "ECA: Evaluate CouldAssert\n"
166 "ATD: AssertTrackingDesired\n"
167 "eATD: Evaluate AssertTrackingDesired\n\n");
168
169 vty_out(vty,
170 "Interface Address Source Group CA eCA ATD eATD\n");
171 FOR_ALL_INTERFACES (pim->vrf, ifp) {
172 pim_ifp = ifp->info;
173 if (!pim_ifp)
174 continue;
175
176 RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
177 pim_show_assert_internal_helper(vty, pim_ifp, ch);
178 } /* scan interface channels */
179 }
180 }
181
182 static void pim_show_assert_metric_helper(struct vty *vty,
183 struct pim_interface *pim_ifp,
184 struct pim_ifchannel *ch)
185 {
186 char addr_str[INET_ADDRSTRLEN];
187 struct pim_assert_metric am;
188 struct in_addr ifaddr;
189 char buf[PREFIX_STRLEN];
190
191 ifaddr = pim_ifp->primary_address;
192
193 am = pim_macro_spt_assert_metric(&ch->upstream->rpf,
194 pim_ifp->primary_address);
195
196 pim_inet4_dump("<addr?>", am.ip_address, addr_str, sizeof(addr_str));
197
198 vty_out(vty, "%-16s %-15s %-15pPAs %-15pPAs %-3s %4u %6u %-15s\n",
199 ch->interface->name,
200 inet_ntop(AF_INET, &ifaddr, buf, sizeof(buf)), &ch->sg.src,
201 &ch->sg.grp, am.rpt_bit_flag ? "yes" : "no",
202 am.metric_preference, am.route_metric, addr_str);
203 }
204
205 static void pim_show_assert_metric(struct pim_instance *pim, struct vty *vty)
206 {
207 struct pim_interface *pim_ifp;
208 struct pim_ifchannel *ch;
209 struct interface *ifp;
210
211 vty_out(vty,
212 "Interface Address Source Group RPT Pref Metric Address \n");
213
214 FOR_ALL_INTERFACES (pim->vrf, ifp) {
215 pim_ifp = ifp->info;
216 if (!pim_ifp)
217 continue;
218
219 RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
220 pim_show_assert_metric_helper(vty, pim_ifp, ch);
221 } /* scan interface channels */
222 }
223 }
224
225 static void pim_show_assert_winner_metric_helper(struct vty *vty,
226 struct pim_interface *pim_ifp,
227 struct pim_ifchannel *ch)
228 {
229 char addr_str[INET_ADDRSTRLEN];
230 struct pim_assert_metric *am;
231 struct in_addr ifaddr;
232 char pref_str[16];
233 char metr_str[16];
234 char buf[PREFIX_STRLEN];
235
236 ifaddr = pim_ifp->primary_address;
237
238 am = &ch->ifassert_winner_metric;
239
240 pim_inet4_dump("<addr?>", am->ip_address, addr_str, sizeof(addr_str));
241
242 if (am->metric_preference == PIM_ASSERT_METRIC_PREFERENCE_MAX)
243 snprintf(pref_str, sizeof(pref_str), "INFI");
244 else
245 snprintf(pref_str, sizeof(pref_str), "%4u",
246 am->metric_preference);
247
248 if (am->route_metric == PIM_ASSERT_ROUTE_METRIC_MAX)
249 snprintf(metr_str, sizeof(metr_str), "INFI");
250 else
251 snprintf(metr_str, sizeof(metr_str), "%6u", am->route_metric);
252
253 vty_out(vty, "%-16s %-15s %-15pPAs %-15pPAs %-3s %-4s %-6s %-15s\n",
254 ch->interface->name,
255 inet_ntop(AF_INET, &ifaddr, buf, sizeof(buf)), &ch->sg.src,
256 &ch->sg.grp, am->rpt_bit_flag ? "yes" : "no", pref_str,
257 metr_str, addr_str);
258 }
259
260 static void pim_show_assert_winner_metric(struct pim_instance *pim,
261 struct vty *vty)
262 {
263 struct pim_interface *pim_ifp;
264 struct pim_ifchannel *ch;
265 struct interface *ifp;
266
267 vty_out(vty,
268 "Interface Address Source Group RPT Pref Metric Address \n");
269
270 FOR_ALL_INTERFACES (pim->vrf, ifp) {
271 pim_ifp = ifp->info;
272 if (!pim_ifp)
273 continue;
274
275 RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
276 pim_show_assert_winner_metric_helper(vty, pim_ifp, ch);
277 } /* scan interface channels */
278 }
279 }
280
281 static void igmp_show_interfaces(struct pim_instance *pim, struct vty *vty,
282 bool uj)
283 {
284 struct interface *ifp;
285 time_t now;
286 char buf[PREFIX_STRLEN];
287 json_object *json = NULL;
288 json_object *json_row = NULL;
289
290 now = pim_time_monotonic_sec();
291
292 if (uj)
293 json = json_object_new_object();
294 else
295 vty_out(vty,
296 "Interface State Address V Querier QuerierIp Query Timer Uptime\n");
297
298 FOR_ALL_INTERFACES (pim->vrf, ifp) {
299 struct pim_interface *pim_ifp;
300 struct listnode *sock_node;
301 struct gm_sock *igmp;
302
303 pim_ifp = ifp->info;
304
305 if (!pim_ifp)
306 continue;
307
308 for (ALL_LIST_ELEMENTS_RO(pim_ifp->gm_socket_list, sock_node,
309 igmp)) {
310 char uptime[10];
311 char query_hhmmss[10];
312
313 pim_time_uptime(uptime, sizeof(uptime),
314 now - igmp->sock_creation);
315 pim_time_timer_to_hhmmss(query_hhmmss,
316 sizeof(query_hhmmss),
317 igmp->t_igmp_query_timer);
318
319 if (uj) {
320 json_row = json_object_new_object();
321 json_object_pim_ifp_add(json_row, ifp);
322 json_object_string_add(json_row, "upTime",
323 uptime);
324 json_object_int_add(json_row, "version",
325 pim_ifp->igmp_version);
326
327 if (igmp->t_igmp_query_timer) {
328 json_object_boolean_true_add(json_row,
329 "querier");
330 json_object_string_add(json_row,
331 "queryTimer",
332 query_hhmmss);
333 }
334 json_object_string_addf(json_row, "querierIp",
335 "%pI4",
336 &igmp->querier_addr);
337
338 json_object_object_add(json, ifp->name,
339 json_row);
340
341 if (igmp->mtrace_only) {
342 json_object_boolean_true_add(
343 json_row, "mtraceOnly");
344 }
345 } else {
346 vty_out(vty,
347 "%-16s %5s %15s %d %7s %17pI4 %11s %8s\n",
348 ifp->name,
349 if_is_up(ifp)
350 ? (igmp->mtrace_only ? "mtrc"
351 : "up")
352 : "down",
353 inet_ntop(AF_INET, &igmp->ifaddr, buf,
354 sizeof(buf)),
355 pim_ifp->igmp_version,
356 igmp->t_igmp_query_timer ? "local"
357 : "other",
358 &igmp->querier_addr, query_hhmmss,
359 uptime);
360 }
361 }
362 }
363
364 if (uj)
365 vty_json(vty, json);
366 }
367
368 static void igmp_show_interfaces_single(struct pim_instance *pim,
369 struct vty *vty, const char *ifname,
370 bool uj)
371 {
372 struct gm_sock *igmp;
373 struct interface *ifp;
374 struct listnode *sock_node;
375 struct pim_interface *pim_ifp;
376 char uptime[10];
377 char query_hhmmss[10];
378 char other_hhmmss[10];
379 int found_ifname = 0;
380 int sqi;
381 long gmi_msec; /* Group Membership Interval */
382 long lmqt_msec;
383 long ohpi_msec;
384 long oqpi_msec; /* Other Querier Present Interval */
385 long qri_msec;
386 time_t now;
387 int lmqc;
388
389 json_object *json = NULL;
390 json_object *json_row = NULL;
391
392 if (uj)
393 json = json_object_new_object();
394
395 now = pim_time_monotonic_sec();
396
397 FOR_ALL_INTERFACES (pim->vrf, ifp) {
398 pim_ifp = ifp->info;
399
400 if (!pim_ifp)
401 continue;
402
403 if (strcmp(ifname, "detail") && strcmp(ifname, ifp->name))
404 continue;
405
406 for (ALL_LIST_ELEMENTS_RO(pim_ifp->gm_socket_list, sock_node,
407 igmp)) {
408 found_ifname = 1;
409 pim_time_uptime(uptime, sizeof(uptime),
410 now - igmp->sock_creation);
411 pim_time_timer_to_hhmmss(query_hhmmss,
412 sizeof(query_hhmmss),
413 igmp->t_igmp_query_timer);
414 pim_time_timer_to_hhmmss(other_hhmmss,
415 sizeof(other_hhmmss),
416 igmp->t_other_querier_timer);
417
418 gmi_msec = PIM_IGMP_GMI_MSEC(
419 igmp->querier_robustness_variable,
420 igmp->querier_query_interval,
421 pim_ifp->gm_query_max_response_time_dsec);
422
423 sqi = PIM_IGMP_SQI(pim_ifp->gm_default_query_interval);
424
425 oqpi_msec = PIM_IGMP_OQPI_MSEC(
426 igmp->querier_robustness_variable,
427 igmp->querier_query_interval,
428 pim_ifp->gm_query_max_response_time_dsec);
429
430 lmqt_msec = PIM_IGMP_LMQT_MSEC(
431 pim_ifp->gm_specific_query_max_response_time_dsec,
432 pim_ifp->gm_last_member_query_count);
433
434 ohpi_msec =
435 PIM_IGMP_OHPI_DSEC(
436 igmp->querier_robustness_variable,
437 igmp->querier_query_interval,
438 pim_ifp->gm_query_max_response_time_dsec) *
439 100;
440
441 qri_msec =
442 pim_ifp->gm_query_max_response_time_dsec * 100;
443 lmqc = pim_ifp->gm_last_member_query_count;
444
445 if (uj) {
446 json_row = json_object_new_object();
447 json_object_pim_ifp_add(json_row, ifp);
448 json_object_string_add(json_row, "upTime",
449 uptime);
450 json_object_string_add(json_row, "querier",
451 igmp->t_igmp_query_timer
452 ? "local"
453 : "other");
454 json_object_string_addf(json_row, "querierIp",
455 "%pI4",
456 &igmp->querier_addr);
457 json_object_int_add(json_row, "queryStartCount",
458 igmp->startup_query_count);
459 json_object_string_add(json_row,
460 "queryQueryTimer",
461 query_hhmmss);
462 json_object_string_add(json_row,
463 "queryOtherTimer",
464 other_hhmmss);
465 json_object_int_add(json_row, "version",
466 pim_ifp->igmp_version);
467 json_object_int_add(
468 json_row,
469 "timerGroupMembershipIntervalMsec",
470 gmi_msec);
471 json_object_int_add(json_row,
472 "lastMemberQueryCount",
473 lmqc);
474 json_object_int_add(json_row,
475 "timerLastMemberQueryMsec",
476 lmqt_msec);
477 json_object_int_add(
478 json_row,
479 "timerOlderHostPresentIntervalMsec",
480 ohpi_msec);
481 json_object_int_add(
482 json_row,
483 "timerOtherQuerierPresentIntervalMsec",
484 oqpi_msec);
485 json_object_int_add(
486 json_row, "timerQueryInterval",
487 igmp->querier_query_interval);
488 json_object_int_add(
489 json_row,
490 "timerQueryResponseIntervalMsec",
491 qri_msec);
492 json_object_int_add(
493 json_row, "timerRobustnessVariable",
494 igmp->querier_robustness_variable);
495 json_object_int_add(json_row,
496 "timerStartupQueryInterval",
497 sqi);
498
499 json_object_object_add(json, ifp->name,
500 json_row);
501
502 if (igmp->mtrace_only) {
503 json_object_boolean_true_add(
504 json_row, "mtraceOnly");
505 }
506 } else {
507 vty_out(vty, "Interface : %s\n", ifp->name);
508 vty_out(vty, "State : %s\n",
509 if_is_up(ifp) ? (igmp->mtrace_only ?
510 "mtrace"
511 : "up")
512 : "down");
513 vty_out(vty, "Address : %pI4\n",
514 &pim_ifp->primary_address);
515 vty_out(vty, "Uptime : %s\n", uptime);
516 vty_out(vty, "Version : %d\n",
517 pim_ifp->igmp_version);
518 vty_out(vty, "\n");
519 vty_out(vty, "\n");
520
521 vty_out(vty, "Querier\n");
522 vty_out(vty, "-------\n");
523 vty_out(vty, "Querier : %s\n",
524 igmp->t_igmp_query_timer ? "local"
525 : "other");
526 vty_out(vty, "QuerierIp : %pI4",
527 &igmp->querier_addr);
528 if (pim_ifp->primary_address.s_addr
529 == igmp->querier_addr.s_addr)
530 vty_out(vty, " (this router)\n");
531 else
532 vty_out(vty, "\n");
533
534 vty_out(vty, "Start Count : %d\n",
535 igmp->startup_query_count);
536 vty_out(vty, "Query Timer : %s\n",
537 query_hhmmss);
538 vty_out(vty, "Other Timer : %s\n",
539 other_hhmmss);
540 vty_out(vty, "\n");
541 vty_out(vty, "\n");
542
543 vty_out(vty, "Timers\n");
544 vty_out(vty, "------\n");
545 vty_out(vty,
546 "Group Membership Interval : %lis\n",
547 gmi_msec / 1000);
548 vty_out(vty,
549 "Last Member Query Count : %d\n",
550 lmqc);
551 vty_out(vty,
552 "Last Member Query Time : %lis\n",
553 lmqt_msec / 1000);
554 vty_out(vty,
555 "Older Host Present Interval : %lis\n",
556 ohpi_msec / 1000);
557 vty_out(vty,
558 "Other Querier Present Interval : %lis\n",
559 oqpi_msec / 1000);
560 vty_out(vty,
561 "Query Interval : %ds\n",
562 igmp->querier_query_interval);
563 vty_out(vty,
564 "Query Response Interval : %lis\n",
565 qri_msec / 1000);
566 vty_out(vty,
567 "Robustness Variable : %d\n",
568 igmp->querier_robustness_variable);
569 vty_out(vty,
570 "Startup Query Interval : %ds\n",
571 sqi);
572 vty_out(vty, "\n");
573 vty_out(vty, "\n");
574
575 pim_print_ifp_flags(vty, ifp);
576 }
577 }
578 }
579
580 if (uj)
581 vty_json(vty, json);
582 else if (!found_ifname)
583 vty_out(vty, "%% No such interface\n");
584 }
585
586 static void igmp_show_interface_join(struct pim_instance *pim, struct vty *vty,
587 bool uj)
588 {
589 struct interface *ifp;
590 time_t now;
591 json_object *json = NULL;
592 json_object *json_iface = NULL;
593 json_object *json_grp = NULL;
594 json_object *json_grp_arr = NULL;
595
596 now = pim_time_monotonic_sec();
597
598 if (uj) {
599 json = json_object_new_object();
600 json_object_string_add(json, "vrf",
601 vrf_id_to_name(pim->vrf->vrf_id));
602 } else {
603 vty_out(vty,
604 "Interface Address Source Group Socket Uptime \n");
605 }
606
607 FOR_ALL_INTERFACES (pim->vrf, ifp) {
608 struct pim_interface *pim_ifp;
609 struct listnode *join_node;
610 struct gm_join *ij;
611 struct in_addr pri_addr;
612 char pri_addr_str[INET_ADDRSTRLEN];
613
614 pim_ifp = ifp->info;
615
616 if (!pim_ifp)
617 continue;
618
619 if (!pim_ifp->gm_join_list)
620 continue;
621
622 pri_addr = pim_find_primary_addr(ifp);
623 pim_inet4_dump("<pri?>", pri_addr, pri_addr_str,
624 sizeof(pri_addr_str));
625
626 for (ALL_LIST_ELEMENTS_RO(pim_ifp->gm_join_list, join_node,
627 ij)) {
628 char group_str[INET_ADDRSTRLEN];
629 char source_str[INET_ADDRSTRLEN];
630 char uptime[10];
631
632 pim_time_uptime(uptime, sizeof(uptime),
633 now - ij->sock_creation);
634 pim_inet4_dump("<grp?>", ij->group_addr, group_str,
635 sizeof(group_str));
636 pim_inet4_dump("<src?>", ij->source_addr, source_str,
637 sizeof(source_str));
638
639 if (uj) {
640 json_object_object_get_ex(json, ifp->name,
641 &json_iface);
642
643 if (!json_iface) {
644 json_iface = json_object_new_object();
645 json_object_string_add(
646 json_iface, "name", ifp->name);
647 json_object_object_add(json, ifp->name,
648 json_iface);
649 json_grp_arr = json_object_new_array();
650 json_object_object_add(json_iface,
651 "groups",
652 json_grp_arr);
653 }
654
655 json_grp = json_object_new_object();
656 json_object_string_add(json_grp, "source",
657 source_str);
658 json_object_string_add(json_grp, "group",
659 group_str);
660 json_object_string_add(json_grp, "primaryAddr",
661 pri_addr_str);
662 json_object_int_add(json_grp, "sockFd",
663 ij->sock_fd);
664 json_object_string_add(json_grp, "upTime",
665 uptime);
666 json_object_array_add(json_grp_arr, json_grp);
667 } else {
668 vty_out(vty,
669 "%-16s %-15s %-15s %-15s %6d %8s\n",
670 ifp->name, pri_addr_str, source_str,
671 group_str, ij->sock_fd, uptime);
672 }
673 } /* for (pim_ifp->gm_join_list) */
674
675 } /* for (iflist) */
676
677 if (uj)
678 vty_json(vty, json);
679 }
680
681 static void igmp_show_statistics(struct pim_instance *pim, struct vty *vty,
682 const char *ifname, bool uj)
683 {
684 struct interface *ifp;
685 struct igmp_stats igmp_stats;
686 bool found_ifname = false;
687 json_object *json = NULL;
688
689 igmp_stats_init(&igmp_stats);
690
691 if (uj)
692 json = json_object_new_object();
693
694 FOR_ALL_INTERFACES (pim->vrf, ifp) {
695 struct pim_interface *pim_ifp;
696 struct listnode *sock_node, *source_node, *group_node;
697 struct gm_sock *igmp;
698 struct gm_group *group;
699 struct gm_source *src;
700
701 pim_ifp = ifp->info;
702
703 if (!pim_ifp)
704 continue;
705
706 if (ifname && strcmp(ifname, ifp->name))
707 continue;
708
709 found_ifname = true;
710
711 igmp_stats.joins_failed += pim_ifp->igmp_ifstat_joins_failed;
712 igmp_stats.joins_sent += pim_ifp->igmp_ifstat_joins_sent;
713 igmp_stats.total_groups +=
714 pim_ifp->gm_group_list
715 ? listcount(pim_ifp->gm_group_list)
716 : 0;
717 igmp_stats.peak_groups += pim_ifp->igmp_peak_group_count;
718
719
720 for (ALL_LIST_ELEMENTS_RO(pim_ifp->gm_group_list, group_node,
721 group)) {
722 for (ALL_LIST_ELEMENTS_RO(group->group_source_list,
723 source_node, src)) {
724 if (pim_addr_is_any(src->source_addr))
725 continue;
726
727 igmp_stats.total_source_groups++;
728 }
729 }
730
731 for (ALL_LIST_ELEMENTS_RO(pim_ifp->gm_socket_list, sock_node,
732 igmp)) {
733 igmp_stats_add(&igmp_stats, &igmp->igmp_stats);
734 }
735 }
736
737 if (!found_ifname) {
738 if (uj)
739 vty_json(vty, json);
740 else
741 vty_out(vty, "%% No such interface\n");
742 return;
743 }
744
745 if (uj) {
746 json_object *json_row = json_object_new_object();
747
748 json_object_string_add(json_row, "name",
749 ifname ? ifname : "global");
750 json_object_int_add(json_row, "queryV1", igmp_stats.query_v1);
751 json_object_int_add(json_row, "queryV2", igmp_stats.query_v2);
752 json_object_int_add(json_row, "queryV3", igmp_stats.query_v3);
753 json_object_int_add(json_row, "leaveV2", igmp_stats.leave_v2);
754 json_object_int_add(json_row, "reportV1", igmp_stats.report_v1);
755 json_object_int_add(json_row, "reportV2", igmp_stats.report_v2);
756 json_object_int_add(json_row, "reportV3", igmp_stats.report_v3);
757 json_object_int_add(json_row, "mtraceResponse",
758 igmp_stats.mtrace_rsp);
759 json_object_int_add(json_row, "mtraceRequest",
760 igmp_stats.mtrace_req);
761 json_object_int_add(json_row, "unsupported",
762 igmp_stats.unsupported);
763 json_object_int_add(json_row, "totalReceivedMessages",
764 igmp_stats.total_recv_messages);
765 json_object_int_add(json_row, "peakGroups",
766 igmp_stats.peak_groups);
767 json_object_int_add(json_row, "totalGroups",
768 igmp_stats.total_groups);
769 json_object_int_add(json_row, "totalSourceGroups",
770 igmp_stats.total_source_groups);
771 json_object_int_add(json_row, "joinsFailed",
772 igmp_stats.joins_failed);
773 json_object_int_add(json_row, "joinsSent",
774 igmp_stats.joins_sent);
775 json_object_int_add(json_row, "generalQueriesSent",
776 igmp_stats.general_queries_sent);
777 json_object_int_add(json_row, "groupQueriesSent",
778 igmp_stats.group_queries_sent);
779 json_object_object_add(json, ifname ? ifname : "global",
780 json_row);
781 vty_json(vty, json);
782 } else {
783 vty_out(vty, "IGMP statistics\n");
784 vty_out(vty, "Interface : %s\n",
785 ifname ? ifname : "global");
786 vty_out(vty, "V1 query : %u\n",
787 igmp_stats.query_v1);
788 vty_out(vty, "V2 query : %u\n",
789 igmp_stats.query_v2);
790 vty_out(vty, "V3 query : %u\n",
791 igmp_stats.query_v3);
792 vty_out(vty, "V2 leave : %u\n",
793 igmp_stats.leave_v2);
794 vty_out(vty, "V1 report : %u\n",
795 igmp_stats.report_v1);
796 vty_out(vty, "V2 report : %u\n",
797 igmp_stats.report_v2);
798 vty_out(vty, "V3 report : %u\n",
799 igmp_stats.report_v3);
800 vty_out(vty, "mtrace response : %u\n",
801 igmp_stats.mtrace_rsp);
802 vty_out(vty, "mtrace request : %u\n",
803 igmp_stats.mtrace_req);
804 vty_out(vty, "unsupported : %u\n",
805 igmp_stats.unsupported);
806 vty_out(vty, "total received messages : %u\n",
807 igmp_stats.total_recv_messages);
808 vty_out(vty, "joins failed : %u\n",
809 igmp_stats.joins_failed);
810 vty_out(vty, "joins sent : %u\n",
811 igmp_stats.joins_sent);
812 vty_out(vty, "general queries sent : %u\n",
813 igmp_stats.general_queries_sent);
814 vty_out(vty, "group queries sent : %u\n",
815 igmp_stats.group_queries_sent);
816 vty_out(vty, "peak groups : %u\n",
817 igmp_stats.peak_groups);
818 vty_out(vty, "total groups : %u\n",
819 igmp_stats.total_groups);
820 vty_out(vty, "total source groups : %u\n",
821 igmp_stats.total_source_groups);
822 }
823 }
824
825 static void igmp_show_groups(struct pim_instance *pim, struct vty *vty, bool uj)
826 {
827 struct interface *ifp;
828 time_t now;
829 json_object *json = NULL;
830 json_object *json_iface = NULL;
831 json_object *json_group = NULL;
832 json_object *json_groups = NULL;
833
834 now = pim_time_monotonic_sec();
835
836 if (uj) {
837 json = json_object_new_object();
838 json_object_int_add(json, "totalGroups", pim->gm_group_count);
839 json_object_int_add(json, "watermarkLimit",
840 pim->gm_watermark_limit);
841 } else {
842 vty_out(vty, "Total IGMP groups: %u\n", pim->gm_group_count);
843 vty_out(vty, "Watermark warn limit(%s): %u\n",
844 pim->gm_watermark_limit ? "Set" : "Not Set",
845 pim->gm_watermark_limit);
846 vty_out(vty,
847 "Interface Group Mode Timer Srcs V Uptime \n");
848 }
849
850 /* scan interfaces */
851 FOR_ALL_INTERFACES (pim->vrf, ifp) {
852 struct pim_interface *pim_ifp = ifp->info;
853 struct listnode *grpnode;
854 struct gm_group *grp;
855
856 if (!pim_ifp)
857 continue;
858
859 /* scan igmp groups */
860 for (ALL_LIST_ELEMENTS_RO(pim_ifp->gm_group_list, grpnode,
861 grp)) {
862 char group_str[INET_ADDRSTRLEN];
863 char hhmmss[10];
864 char uptime[10];
865
866 pim_inet4_dump("<group?>", grp->group_addr, group_str,
867 sizeof(group_str));
868 pim_time_timer_to_hhmmss(hhmmss, sizeof(hhmmss),
869 grp->t_group_timer);
870 pim_time_uptime(uptime, sizeof(uptime),
871 now - grp->group_creation);
872
873 if (uj) {
874 json_object_object_get_ex(json, ifp->name,
875 &json_iface);
876
877 if (!json_iface) {
878 json_iface = json_object_new_object();
879 json_object_pim_ifp_add(json_iface,
880 ifp);
881 json_object_object_add(json, ifp->name,
882 json_iface);
883 json_groups = json_object_new_array();
884 json_object_object_add(json_iface,
885 "groups",
886 json_groups);
887 }
888
889 json_group = json_object_new_object();
890 json_object_string_add(json_group, "group",
891 group_str);
892
893 if (grp->igmp_version == 3)
894 json_object_string_add(
895 json_group, "mode",
896 grp->group_filtermode_isexcl
897 ? "EXCLUDE"
898 : "INCLUDE");
899
900 json_object_string_add(json_group, "timer",
901 hhmmss);
902 json_object_int_add(
903 json_group, "sourcesCount",
904 grp->group_source_list ? listcount(
905 grp->group_source_list)
906 : 0);
907 json_object_int_add(json_group, "version",
908 grp->igmp_version);
909 json_object_string_add(json_group, "uptime",
910 uptime);
911 json_object_array_add(json_groups, json_group);
912 } else {
913 vty_out(vty, "%-16s %-15s %4s %8s %4d %d %8s\n",
914 ifp->name, group_str,
915 grp->igmp_version == 3
916 ? (grp->group_filtermode_isexcl
917 ? "EXCL"
918 : "INCL")
919 : "----",
920 hhmmss,
921 grp->group_source_list ? listcount(
922 grp->group_source_list)
923 : 0,
924 grp->igmp_version, uptime);
925 }
926 } /* scan igmp groups */
927 } /* scan interfaces */
928
929 if (uj)
930 vty_json(vty, json);
931 }
932
933 static void igmp_show_group_retransmission(struct pim_instance *pim,
934 struct vty *vty)
935 {
936 struct interface *ifp;
937
938 vty_out(vty,
939 "Interface Group RetTimer Counter RetSrcs\n");
940
941 /* scan interfaces */
942 FOR_ALL_INTERFACES (pim->vrf, ifp) {
943 struct pim_interface *pim_ifp = ifp->info;
944 struct listnode *grpnode;
945 struct gm_group *grp;
946
947 if (!pim_ifp)
948 continue;
949
950 /* scan igmp groups */
951 for (ALL_LIST_ELEMENTS_RO(pim_ifp->gm_group_list, grpnode,
952 grp)) {
953 char group_str[INET_ADDRSTRLEN];
954 char grp_retr_mmss[10];
955 struct listnode *src_node;
956 struct gm_source *src;
957 int grp_retr_sources = 0;
958
959 pim_inet4_dump("<group?>", grp->group_addr, group_str,
960 sizeof(group_str));
961 pim_time_timer_to_mmss(
962 grp_retr_mmss, sizeof(grp_retr_mmss),
963 grp->t_group_query_retransmit_timer);
964
965
966 /* count group sources with retransmission state
967 */
968 for (ALL_LIST_ELEMENTS_RO(grp->group_source_list,
969 src_node, src)) {
970 if (src->source_query_retransmit_count > 0) {
971 ++grp_retr_sources;
972 }
973 }
974
975 vty_out(vty, "%-16s %-15s %-8s %7d %7d\n", ifp->name,
976 group_str, grp_retr_mmss,
977 grp->group_specific_query_retransmit_count,
978 grp_retr_sources);
979
980 } /* scan igmp groups */
981 } /* scan interfaces */
982 }
983
984 static void igmp_show_sources(struct pim_instance *pim, struct vty *vty,
985 bool uj)
986 {
987 struct interface *ifp;
988 time_t now;
989 json_object *json = NULL;
990 json_object *json_iface = NULL;
991 json_object *json_group = NULL;
992 json_object *json_source = NULL;
993 json_object *json_sources = NULL;
994
995 now = pim_time_monotonic_sec();
996
997 if (uj)
998 json = json_object_new_object();
999 else
1000 vty_out(vty,
1001 "Interface Group Source Timer Fwd Uptime \n");
1002
1003 /* scan interfaces */
1004 FOR_ALL_INTERFACES (pim->vrf, ifp) {
1005 struct pim_interface *pim_ifp = ifp->info;
1006 struct listnode *grpnode;
1007 struct gm_group *grp;
1008
1009 if (!pim_ifp)
1010 continue;
1011
1012 /* scan igmp groups */
1013 for (ALL_LIST_ELEMENTS_RO(pim_ifp->gm_group_list, grpnode,
1014 grp)) {
1015 char group_str[INET_ADDRSTRLEN];
1016 struct listnode *srcnode;
1017 struct gm_source *src;
1018
1019 pim_inet4_dump("<group?>", grp->group_addr, group_str,
1020 sizeof(group_str));
1021
1022 /* scan group sources */
1023 for (ALL_LIST_ELEMENTS_RO(grp->group_source_list,
1024 srcnode, src)) {
1025 char source_str[INET_ADDRSTRLEN];
1026 char mmss[10];
1027 char uptime[10];
1028
1029 pim_inet4_dump("<source?>", src->source_addr,
1030 source_str, sizeof(source_str));
1031
1032 pim_time_timer_to_mmss(mmss, sizeof(mmss),
1033 src->t_source_timer);
1034
1035 pim_time_uptime(uptime, sizeof(uptime),
1036 now - src->source_creation);
1037
1038 if (uj) {
1039 json_object_object_get_ex(
1040 json, ifp->name, &json_iface);
1041 if (!json_iface) {
1042 json_iface =
1043 json_object_new_object();
1044 json_object_string_add(
1045 json_iface, "name",
1046 ifp->name);
1047 json_object_object_add(
1048 json, ifp->name,
1049 json_iface);
1050 }
1051 json_object_object_get_ex(json_iface,
1052 group_str,
1053 &json_group);
1054
1055 if (!json_group) {
1056 json_group =
1057 json_object_new_object();
1058 json_object_string_add(
1059 json_group, "group",
1060 group_str);
1061 json_object_object_add(
1062 json_iface, group_str,
1063 json_group);
1064 json_sources =
1065 json_object_new_array();
1066 json_object_object_add(
1067 json_group, "sources",
1068 json_sources);
1069 }
1070 json_source = json_object_new_object();
1071 json_object_string_add(json_source,
1072 "source",
1073 source_str);
1074 json_object_string_add(json_source,
1075 "timer", mmss);
1076 json_object_boolean_add(
1077 json_source, "forwarded",
1078 IGMP_SOURCE_TEST_FORWARDING(
1079 src->source_flags));
1080 json_object_string_add(
1081 json_source, "uptime", uptime);
1082 json_object_array_add(json_sources,
1083 json_source);
1084
1085 } else {
1086 vty_out(vty,
1087 "%-16s %-15s %-15s %5s %3s %8s\n",
1088 ifp->name, group_str,
1089 source_str, mmss,
1090 IGMP_SOURCE_TEST_FORWARDING(
1091 src->source_flags)
1092 ? "Y"
1093 : "N",
1094 uptime);
1095 }
1096
1097 } /* scan group sources */
1098 } /* scan igmp groups */
1099 } /* scan interfaces */
1100 if (uj)
1101 vty_json(vty, json);
1102 }
1103
1104 static void igmp_show_source_retransmission(struct pim_instance *pim,
1105 struct vty *vty)
1106 {
1107 struct interface *ifp;
1108
1109 vty_out(vty,
1110 "Interface Group Source Counter\n");
1111
1112 /* scan interfaces */
1113 FOR_ALL_INTERFACES (pim->vrf, ifp) {
1114 struct pim_interface *pim_ifp = ifp->info;
1115 struct listnode *grpnode;
1116 struct gm_group *grp;
1117
1118 if (!pim_ifp)
1119 continue;
1120
1121 /* scan igmp groups */
1122 for (ALL_LIST_ELEMENTS_RO(pim_ifp->gm_group_list, grpnode,
1123 grp)) {
1124 char group_str[INET_ADDRSTRLEN];
1125 struct listnode *srcnode;
1126 struct gm_source *src;
1127
1128 pim_inet4_dump("<group?>", grp->group_addr, group_str,
1129 sizeof(group_str));
1130
1131 /* scan group sources */
1132 for (ALL_LIST_ELEMENTS_RO(grp->group_source_list,
1133 srcnode, src)) {
1134 char source_str[INET_ADDRSTRLEN];
1135
1136 pim_inet4_dump("<source?>", src->source_addr,
1137 source_str, sizeof(source_str));
1138
1139 vty_out(vty, "%-16s %-15s %-15s %7d\n",
1140 ifp->name, group_str, source_str,
1141 src->source_query_retransmit_count);
1142
1143 } /* scan group sources */
1144 } /* scan igmp groups */
1145 } /* scan interfaces */
1146 }
1147
1148 static void clear_igmp_interfaces(struct pim_instance *pim)
1149 {
1150 struct interface *ifp;
1151
1152 FOR_ALL_INTERFACES (pim->vrf, ifp)
1153 pim_if_addr_del_all_igmp(ifp);
1154
1155 FOR_ALL_INTERFACES (pim->vrf, ifp)
1156 pim_if_addr_add_all(ifp);
1157 }
1158
1159 static void clear_interfaces(struct pim_instance *pim)
1160 {
1161 clear_igmp_interfaces(pim);
1162 clear_pim_interfaces(pim);
1163 }
1164
1165 #define PIM_GET_PIM_INTERFACE(pim_ifp, ifp) \
1166 pim_ifp = ifp->info; \
1167 if (!pim_ifp) { \
1168 vty_out(vty, \
1169 "%% Enable PIM and/or IGMP on this interface first\n"); \
1170 return CMD_WARNING_CONFIG_FAILED; \
1171 }
1172
1173 /**
1174 * Compatibility function to keep the legacy mesh group CLI behavior:
1175 * Delete group when there are no more configurations in it.
1176 *
1177 * NOTE:
1178 * Don't forget to call `nb_cli_apply_changes` after this.
1179 */
1180 static void pim_cli_legacy_mesh_group_behavior(struct vty *vty,
1181 const char *gname)
1182 {
1183 const char *vrfname;
1184 char xpath_value[XPATH_MAXLEN];
1185 char xpath_member_value[XPATH_MAXLEN];
1186 const struct lyd_node *member_dnode;
1187
1188 vrfname = pim_cli_get_vrf_name(vty);
1189 if (vrfname == NULL)
1190 return;
1191
1192 /* Get mesh group base XPath. */
1193 snprintf(xpath_value, sizeof(xpath_value),
1194 FRR_PIM_VRF_XPATH "/msdp-mesh-groups[name='%s']",
1195 "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4", gname);
1196 /* Group must exists, otherwise just quit. */
1197 if (!yang_dnode_exists(vty->candidate_config->dnode, xpath_value))
1198 return;
1199
1200 /* Group members check: */
1201 strlcpy(xpath_member_value, xpath_value, sizeof(xpath_member_value));
1202 strlcat(xpath_member_value, "/members", sizeof(xpath_member_value));
1203 if (yang_dnode_exists(vty->candidate_config->dnode,
1204 xpath_member_value)) {
1205 member_dnode = yang_dnode_get(vty->candidate_config->dnode,
1206 xpath_member_value);
1207 if (!member_dnode || !yang_is_last_list_dnode(member_dnode))
1208 return;
1209 }
1210
1211 /* Source address check: */
1212 strlcpy(xpath_member_value, xpath_value, sizeof(xpath_member_value));
1213 strlcat(xpath_member_value, "/source", sizeof(xpath_member_value));
1214 if (yang_dnode_exists(vty->candidate_config->dnode, xpath_member_value))
1215 return;
1216
1217 /* No configurations found: delete it. */
1218 nb_cli_enqueue_change(vty, xpath_value, NB_OP_DESTROY, NULL);
1219 }
1220
1221 DEFUN (clear_ip_interfaces,
1222 clear_ip_interfaces_cmd,
1223 "clear ip interfaces [vrf NAME]",
1224 CLEAR_STR
1225 IP_STR
1226 "Reset interfaces\n"
1227 VRF_CMD_HELP_STR)
1228 {
1229 int idx = 2;
1230 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
1231
1232 if (!vrf)
1233 return CMD_WARNING;
1234
1235 clear_interfaces(vrf->info);
1236
1237 return CMD_SUCCESS;
1238 }
1239
1240 DEFUN (clear_ip_igmp_interfaces,
1241 clear_ip_igmp_interfaces_cmd,
1242 "clear ip igmp [vrf NAME] interfaces",
1243 CLEAR_STR
1244 IP_STR
1245 CLEAR_IP_IGMP_STR
1246 VRF_CMD_HELP_STR
1247 "Reset IGMP interfaces\n")
1248 {
1249 int idx = 2;
1250 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
1251
1252 if (!vrf)
1253 return CMD_WARNING;
1254
1255 clear_igmp_interfaces(vrf->info);
1256
1257 return CMD_SUCCESS;
1258 }
1259
1260 DEFPY (clear_ip_pim_statistics,
1261 clear_ip_pim_statistics_cmd,
1262 "clear ip pim statistics [vrf NAME]$name",
1263 CLEAR_STR
1264 IP_STR
1265 CLEAR_IP_PIM_STR
1266 VRF_CMD_HELP_STR
1267 "Reset PIM statistics\n")
1268 {
1269 struct vrf *v = pim_cmd_lookup(vty, name);
1270
1271 if (!v)
1272 return CMD_WARNING;
1273
1274 clear_pim_statistics(v->info);
1275
1276 return CMD_SUCCESS;
1277 }
1278
1279 DEFPY (clear_ip_mroute,
1280 clear_ip_mroute_cmd,
1281 "clear ip mroute [vrf NAME]$name",
1282 CLEAR_STR
1283 IP_STR
1284 MROUTE_STR
1285 VRF_CMD_HELP_STR)
1286 {
1287 struct vrf *v = pim_cmd_lookup(vty, name);
1288
1289 if (!v)
1290 return CMD_WARNING;
1291
1292 clear_mroute(v->info);
1293
1294 return CMD_SUCCESS;
1295 }
1296
1297 DEFPY (clear_ip_pim_interfaces,
1298 clear_ip_pim_interfaces_cmd,
1299 "clear ip pim [vrf NAME] interfaces",
1300 CLEAR_STR
1301 IP_STR
1302 CLEAR_IP_PIM_STR
1303 VRF_CMD_HELP_STR
1304 "Reset PIM interfaces\n")
1305 {
1306 struct vrf *v = pim_cmd_lookup(vty, vrf);
1307
1308 if (!v)
1309 return CMD_WARNING;
1310
1311 clear_pim_interfaces(v->info);
1312
1313 return CMD_SUCCESS;
1314 }
1315
1316 DEFPY (clear_ip_pim_interface_traffic,
1317 clear_ip_pim_interface_traffic_cmd,
1318 "clear ip pim [vrf NAME] interface traffic",
1319 CLEAR_STR
1320 IP_STR
1321 CLEAR_IP_PIM_STR
1322 VRF_CMD_HELP_STR
1323 "Reset PIM interfaces\n"
1324 "Reset Protocol Packet counters\n")
1325 {
1326 return clear_pim_interface_traffic(vrf, vty);
1327 }
1328
1329 DEFPY (clear_ip_pim_oil,
1330 clear_ip_pim_oil_cmd,
1331 "clear ip pim [vrf NAME]$name oil",
1332 CLEAR_STR
1333 IP_STR
1334 CLEAR_IP_PIM_STR
1335 VRF_CMD_HELP_STR
1336 "Rescan PIM OIL (output interface list)\n")
1337 {
1338 struct vrf *v = pim_cmd_lookup(vty, name);
1339
1340 if (!v)
1341 return CMD_WARNING;
1342
1343 pim_scan_oil(v->info);
1344
1345 return CMD_SUCCESS;
1346 }
1347
1348 DEFUN (clear_ip_pim_bsr_db,
1349 clear_ip_pim_bsr_db_cmd,
1350 "clear ip pim [vrf NAME] bsr-data",
1351 CLEAR_STR
1352 IP_STR
1353 CLEAR_IP_PIM_STR
1354 VRF_CMD_HELP_STR
1355 "Reset pim bsr data\n")
1356 {
1357 int idx = 2;
1358 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
1359
1360 if (!vrf)
1361 return CMD_WARNING;
1362
1363 pim_bsm_clear(vrf->info);
1364
1365 return CMD_SUCCESS;
1366 }
1367
1368 DEFUN (show_ip_igmp_interface,
1369 show_ip_igmp_interface_cmd,
1370 "show ip igmp [vrf NAME] interface [detail|WORD] [json]",
1371 SHOW_STR
1372 IP_STR
1373 IGMP_STR
1374 VRF_CMD_HELP_STR
1375 "IGMP interface information\n"
1376 "Detailed output\n"
1377 "interface name\n"
1378 JSON_STR)
1379 {
1380 int idx = 2;
1381 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
1382 bool uj = use_json(argc, argv);
1383
1384 if (!vrf)
1385 return CMD_WARNING;
1386
1387 if (argv_find(argv, argc, "detail", &idx)
1388 || argv_find(argv, argc, "WORD", &idx))
1389 igmp_show_interfaces_single(vrf->info, vty, argv[idx]->arg, uj);
1390 else
1391 igmp_show_interfaces(vrf->info, vty, uj);
1392
1393 return CMD_SUCCESS;
1394 }
1395
1396 DEFUN (show_ip_igmp_interface_vrf_all,
1397 show_ip_igmp_interface_vrf_all_cmd,
1398 "show ip igmp vrf all interface [detail|WORD] [json]",
1399 SHOW_STR
1400 IP_STR
1401 IGMP_STR
1402 VRF_CMD_HELP_STR
1403 "IGMP interface information\n"
1404 "Detailed output\n"
1405 "interface name\n"
1406 JSON_STR)
1407 {
1408 int idx = 2;
1409 bool uj = use_json(argc, argv);
1410 struct vrf *vrf;
1411 bool first = true;
1412
1413 if (uj)
1414 vty_out(vty, "{ ");
1415 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
1416 if (uj) {
1417 if (!first)
1418 vty_out(vty, ", ");
1419 vty_out(vty, " \"%s\": ", vrf->name);
1420 first = false;
1421 } else
1422 vty_out(vty, "VRF: %s\n", vrf->name);
1423 if (argv_find(argv, argc, "detail", &idx)
1424 || argv_find(argv, argc, "WORD", &idx))
1425 igmp_show_interfaces_single(vrf->info, vty,
1426 argv[idx]->arg, uj);
1427 else
1428 igmp_show_interfaces(vrf->info, vty, uj);
1429 }
1430 if (uj)
1431 vty_out(vty, "}\n");
1432
1433 return CMD_SUCCESS;
1434 }
1435
1436 DEFUN (show_ip_igmp_join,
1437 show_ip_igmp_join_cmd,
1438 "show ip igmp [vrf NAME] join [json]",
1439 SHOW_STR
1440 IP_STR
1441 IGMP_STR
1442 VRF_CMD_HELP_STR
1443 "IGMP static join information\n"
1444 JSON_STR)
1445 {
1446 int idx = 2;
1447 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
1448 bool uj = use_json(argc, argv);
1449
1450 if (!vrf)
1451 return CMD_WARNING;
1452
1453 igmp_show_interface_join(vrf->info, vty, uj);
1454
1455 return CMD_SUCCESS;
1456 }
1457
1458 DEFUN (show_ip_igmp_join_vrf_all,
1459 show_ip_igmp_join_vrf_all_cmd,
1460 "show ip igmp vrf all join [json]",
1461 SHOW_STR
1462 IP_STR
1463 IGMP_STR
1464 VRF_CMD_HELP_STR
1465 "IGMP static join information\n"
1466 JSON_STR)
1467 {
1468 bool uj = use_json(argc, argv);
1469 struct vrf *vrf;
1470 bool first = true;
1471
1472 if (uj)
1473 vty_out(vty, "{ ");
1474 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
1475 if (uj) {
1476 if (!first)
1477 vty_out(vty, ", ");
1478 vty_out(vty, " \"%s\": ", vrf->name);
1479 first = false;
1480 } else
1481 vty_out(vty, "VRF: %s\n", vrf->name);
1482 igmp_show_interface_join(vrf->info, vty, uj);
1483 }
1484 if (uj)
1485 vty_out(vty, "}\n");
1486
1487 return CMD_SUCCESS;
1488 }
1489
1490 DEFUN (show_ip_igmp_groups,
1491 show_ip_igmp_groups_cmd,
1492 "show ip igmp [vrf NAME] groups [json]",
1493 SHOW_STR
1494 IP_STR
1495 IGMP_STR
1496 VRF_CMD_HELP_STR
1497 IGMP_GROUP_STR
1498 JSON_STR)
1499 {
1500 int idx = 2;
1501 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
1502 bool uj = use_json(argc, argv);
1503
1504 if (!vrf)
1505 return CMD_WARNING;
1506
1507 igmp_show_groups(vrf->info, vty, uj);
1508
1509 return CMD_SUCCESS;
1510 }
1511
1512 DEFUN (show_ip_igmp_groups_vrf_all,
1513 show_ip_igmp_groups_vrf_all_cmd,
1514 "show ip igmp vrf all groups [json]",
1515 SHOW_STR
1516 IP_STR
1517 IGMP_STR
1518 VRF_CMD_HELP_STR
1519 IGMP_GROUP_STR
1520 JSON_STR)
1521 {
1522 bool uj = use_json(argc, argv);
1523 struct vrf *vrf;
1524 bool first = true;
1525
1526 if (uj)
1527 vty_out(vty, "{ ");
1528 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
1529 if (uj) {
1530 if (!first)
1531 vty_out(vty, ", ");
1532 vty_out(vty, " \"%s\": ", vrf->name);
1533 first = false;
1534 } else
1535 vty_out(vty, "VRF: %s\n", vrf->name);
1536 igmp_show_groups(vrf->info, vty, uj);
1537 }
1538 if (uj)
1539 vty_out(vty, "}\n");
1540
1541 return CMD_SUCCESS;
1542 }
1543
1544 DEFUN (show_ip_igmp_groups_retransmissions,
1545 show_ip_igmp_groups_retransmissions_cmd,
1546 "show ip igmp [vrf NAME] groups retransmissions",
1547 SHOW_STR
1548 IP_STR
1549 IGMP_STR
1550 VRF_CMD_HELP_STR
1551 IGMP_GROUP_STR
1552 "IGMP group retransmissions\n")
1553 {
1554 int idx = 2;
1555 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
1556
1557 if (!vrf)
1558 return CMD_WARNING;
1559
1560 igmp_show_group_retransmission(vrf->info, vty);
1561
1562 return CMD_SUCCESS;
1563 }
1564
1565 DEFUN (show_ip_igmp_sources,
1566 show_ip_igmp_sources_cmd,
1567 "show ip igmp [vrf NAME] sources [json]",
1568 SHOW_STR
1569 IP_STR
1570 IGMP_STR
1571 VRF_CMD_HELP_STR
1572 IGMP_SOURCE_STR
1573 JSON_STR)
1574 {
1575 int idx = 2;
1576 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
1577
1578 if (!vrf)
1579 return CMD_WARNING;
1580
1581 igmp_show_sources(vrf->info, vty, use_json(argc, argv));
1582
1583 return CMD_SUCCESS;
1584 }
1585
1586 DEFUN (show_ip_igmp_sources_retransmissions,
1587 show_ip_igmp_sources_retransmissions_cmd,
1588 "show ip igmp [vrf NAME] sources retransmissions",
1589 SHOW_STR
1590 IP_STR
1591 IGMP_STR
1592 VRF_CMD_HELP_STR
1593 IGMP_SOURCE_STR
1594 "IGMP source retransmissions\n")
1595 {
1596 int idx = 2;
1597 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
1598
1599 if (!vrf)
1600 return CMD_WARNING;
1601
1602 igmp_show_source_retransmission(vrf->info, vty);
1603
1604 return CMD_SUCCESS;
1605 }
1606
1607 DEFUN (show_ip_igmp_statistics,
1608 show_ip_igmp_statistics_cmd,
1609 "show ip igmp [vrf NAME] statistics [interface WORD] [json]",
1610 SHOW_STR
1611 IP_STR
1612 IGMP_STR
1613 VRF_CMD_HELP_STR
1614 "IGMP statistics\n"
1615 "interface\n"
1616 "IGMP interface\n"
1617 JSON_STR)
1618 {
1619 int idx = 2;
1620 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
1621 bool uj = use_json(argc, argv);
1622
1623 if (!vrf)
1624 return CMD_WARNING;
1625
1626 if (argv_find(argv, argc, "WORD", &idx))
1627 igmp_show_statistics(vrf->info, vty, argv[idx]->arg, uj);
1628 else
1629 igmp_show_statistics(vrf->info, vty, NULL, uj);
1630
1631 return CMD_SUCCESS;
1632 }
1633
1634 DEFUN (show_ip_pim_mlag_summary,
1635 show_ip_pim_mlag_summary_cmd,
1636 "show ip pim mlag summary [json]",
1637 SHOW_STR
1638 IP_STR
1639 PIM_STR
1640 "MLAG\n"
1641 "status and stats\n"
1642 JSON_STR)
1643 {
1644 bool uj = use_json(argc, argv);
1645 char role_buf[MLAG_ROLE_STRSIZE];
1646 char addr_buf[INET_ADDRSTRLEN];
1647
1648 if (uj) {
1649 json_object *json = NULL;
1650 json_object *json_stat = NULL;
1651
1652 json = json_object_new_object();
1653 if (router->mlag_flags & PIM_MLAGF_LOCAL_CONN_UP)
1654 json_object_boolean_true_add(json, "mlagConnUp");
1655 if (router->mlag_flags & PIM_MLAGF_PEER_CONN_UP)
1656 json_object_boolean_true_add(json, "mlagPeerConnUp");
1657 if (router->mlag_flags & PIM_MLAGF_PEER_ZEBRA_UP)
1658 json_object_boolean_true_add(json, "mlagPeerZebraUp");
1659 json_object_string_add(json, "mlagRole",
1660 mlag_role2str(router->mlag_role,
1661 role_buf, sizeof(role_buf)));
1662 inet_ntop(AF_INET, &router->local_vtep_ip,
1663 addr_buf, INET_ADDRSTRLEN);
1664 json_object_string_add(json, "localVtepIp", addr_buf);
1665 inet_ntop(AF_INET, &router->anycast_vtep_ip,
1666 addr_buf, INET_ADDRSTRLEN);
1667 json_object_string_add(json, "anycastVtepIp", addr_buf);
1668 json_object_string_add(json, "peerlinkRif",
1669 router->peerlink_rif);
1670
1671 json_stat = json_object_new_object();
1672 json_object_int_add(json_stat, "mlagConnFlaps",
1673 router->mlag_stats.mlagd_session_downs);
1674 json_object_int_add(json_stat, "mlagPeerConnFlaps",
1675 router->mlag_stats.peer_session_downs);
1676 json_object_int_add(json_stat, "mlagPeerZebraFlaps",
1677 router->mlag_stats.peer_zebra_downs);
1678 json_object_int_add(json_stat, "mrouteAddRx",
1679 router->mlag_stats.msg.mroute_add_rx);
1680 json_object_int_add(json_stat, "mrouteAddTx",
1681 router->mlag_stats.msg.mroute_add_tx);
1682 json_object_int_add(json_stat, "mrouteDelRx",
1683 router->mlag_stats.msg.mroute_del_rx);
1684 json_object_int_add(json_stat, "mrouteDelTx",
1685 router->mlag_stats.msg.mroute_del_tx);
1686 json_object_int_add(json_stat, "mlagStatusUpdates",
1687 router->mlag_stats.msg.mlag_status_updates);
1688 json_object_int_add(json_stat, "peerZebraStatusUpdates",
1689 router->mlag_stats.msg.peer_zebra_status_updates);
1690 json_object_int_add(json_stat, "pimStatusUpdates",
1691 router->mlag_stats.msg.pim_status_updates);
1692 json_object_int_add(json_stat, "vxlanUpdates",
1693 router->mlag_stats.msg.vxlan_updates);
1694 json_object_object_add(json, "connStats", json_stat);
1695
1696 vty_json(vty, json);
1697 return CMD_SUCCESS;
1698 }
1699
1700 vty_out(vty, "MLAG daemon connection: %s\n",
1701 (router->mlag_flags & PIM_MLAGF_LOCAL_CONN_UP)
1702 ? "up" : "down");
1703 vty_out(vty, "MLAG peer state: %s\n",
1704 (router->mlag_flags & PIM_MLAGF_PEER_CONN_UP)
1705 ? "up" : "down");
1706 vty_out(vty, "Zebra peer state: %s\n",
1707 (router->mlag_flags & PIM_MLAGF_PEER_ZEBRA_UP)
1708 ? "up" : "down");
1709 vty_out(vty, "MLAG role: %s\n",
1710 mlag_role2str(router->mlag_role, role_buf, sizeof(role_buf)));
1711 inet_ntop(AF_INET, &router->local_vtep_ip,
1712 addr_buf, INET_ADDRSTRLEN);
1713 vty_out(vty, "Local VTEP IP: %s\n", addr_buf);
1714 inet_ntop(AF_INET, &router->anycast_vtep_ip,
1715 addr_buf, INET_ADDRSTRLEN);
1716 vty_out(vty, "Anycast VTEP IP: %s\n", addr_buf);
1717 vty_out(vty, "Peerlink: %s\n", router->peerlink_rif);
1718 vty_out(vty, "Session flaps: mlagd: %d mlag-peer: %d zebra-peer: %d\n",
1719 router->mlag_stats.mlagd_session_downs,
1720 router->mlag_stats.peer_session_downs,
1721 router->mlag_stats.peer_zebra_downs);
1722 vty_out(vty, "Message Statistics:\n");
1723 vty_out(vty, " mroute adds: rx: %d, tx: %d\n",
1724 router->mlag_stats.msg.mroute_add_rx,
1725 router->mlag_stats.msg.mroute_add_tx);
1726 vty_out(vty, " mroute dels: rx: %d, tx: %d\n",
1727 router->mlag_stats.msg.mroute_del_rx,
1728 router->mlag_stats.msg.mroute_del_tx);
1729 vty_out(vty, " peer zebra status updates: %d\n",
1730 router->mlag_stats.msg.peer_zebra_status_updates);
1731 vty_out(vty, " PIM status updates: %d\n",
1732 router->mlag_stats.msg.pim_status_updates);
1733 vty_out(vty, " VxLAN updates: %d\n",
1734 router->mlag_stats.msg.vxlan_updates);
1735
1736 return CMD_SUCCESS;
1737 }
1738
1739 DEFUN (show_ip_pim_assert,
1740 show_ip_pim_assert_cmd,
1741 "show ip pim [vrf NAME] assert",
1742 SHOW_STR
1743 IP_STR
1744 PIM_STR
1745 VRF_CMD_HELP_STR
1746 "PIM interface assert\n")
1747 {
1748 int idx = 2;
1749 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
1750
1751 if (!vrf)
1752 return CMD_WARNING;
1753
1754 pim_show_assert(vrf->info, vty);
1755
1756 return CMD_SUCCESS;
1757 }
1758
1759 DEFUN (show_ip_pim_assert_internal,
1760 show_ip_pim_assert_internal_cmd,
1761 "show ip pim [vrf NAME] assert-internal",
1762 SHOW_STR
1763 IP_STR
1764 PIM_STR
1765 VRF_CMD_HELP_STR
1766 "PIM interface internal assert state\n")
1767 {
1768 int idx = 2;
1769 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
1770
1771 if (!vrf)
1772 return CMD_WARNING;
1773
1774 pim_show_assert_internal(vrf->info, vty);
1775
1776 return CMD_SUCCESS;
1777 }
1778
1779 DEFUN (show_ip_pim_assert_metric,
1780 show_ip_pim_assert_metric_cmd,
1781 "show ip pim [vrf NAME] assert-metric",
1782 SHOW_STR
1783 IP_STR
1784 PIM_STR
1785 VRF_CMD_HELP_STR
1786 "PIM interface assert metric\n")
1787 {
1788 int idx = 2;
1789 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
1790
1791 if (!vrf)
1792 return CMD_WARNING;
1793
1794 pim_show_assert_metric(vrf->info, vty);
1795
1796 return CMD_SUCCESS;
1797 }
1798
1799 DEFUN (show_ip_pim_assert_winner_metric,
1800 show_ip_pim_assert_winner_metric_cmd,
1801 "show ip pim [vrf NAME] assert-winner-metric",
1802 SHOW_STR
1803 IP_STR
1804 PIM_STR
1805 VRF_CMD_HELP_STR
1806 "PIM interface assert winner metric\n")
1807 {
1808 int idx = 2;
1809 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
1810
1811 if (!vrf)
1812 return CMD_WARNING;
1813
1814 pim_show_assert_winner_metric(vrf->info, vty);
1815
1816 return CMD_SUCCESS;
1817 }
1818
1819 DEFPY (show_ip_pim_interface,
1820 show_ip_pim_interface_cmd,
1821 "show ip pim [mlag$mlag] [vrf NAME] interface [detail|WORD]$interface [json$json]",
1822 SHOW_STR
1823 IP_STR
1824 PIM_STR
1825 "MLAG\n"
1826 VRF_CMD_HELP_STR
1827 "PIM interface information\n"
1828 "Detailed output\n"
1829 "interface name\n"
1830 JSON_STR)
1831 {
1832 return pim_show_interface_cmd_helper(vrf, vty, !!json, !!mlag,
1833 interface);
1834 }
1835
1836 DEFPY (show_ip_pim_interface_vrf_all,
1837 show_ip_pim_interface_vrf_all_cmd,
1838 "show ip pim [mlag$mlag] vrf all interface [detail|WORD]$interface [json$json]",
1839 SHOW_STR
1840 IP_STR
1841 PIM_STR
1842 "MLAG\n"
1843 VRF_CMD_HELP_STR
1844 "PIM interface information\n"
1845 "Detailed output\n"
1846 "interface name\n"
1847 JSON_STR)
1848 {
1849 return pim_show_interface_vrf_all_cmd_helper(vty, !!json, !!mlag,
1850 interface);
1851 }
1852
1853 DEFPY (show_ip_pim_join,
1854 show_ip_pim_join_cmd,
1855 "show ip pim [vrf NAME] join [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
1856 SHOW_STR
1857 IP_STR
1858 PIM_STR
1859 VRF_CMD_HELP_STR
1860 "PIM interface join information\n"
1861 "The Source or Group\n"
1862 "The Group\n"
1863 JSON_STR)
1864 {
1865 return pim_show_join_cmd_helper(vrf, vty, s_or_g, g, json);
1866 }
1867
1868 DEFPY (show_ip_pim_join_vrf_all,
1869 show_ip_pim_join_vrf_all_cmd,
1870 "show ip pim vrf all join [json$json]",
1871 SHOW_STR
1872 IP_STR
1873 PIM_STR
1874 VRF_CMD_HELP_STR
1875 "PIM interface join information\n"
1876 JSON_STR)
1877 {
1878 return pim_show_join_vrf_all_cmd_helper(vty, json);
1879 }
1880
1881 DEFPY (show_ip_pim_jp_agg,
1882 show_ip_pim_jp_agg_cmd,
1883 "show ip pim [vrf NAME] jp-agg",
1884 SHOW_STR
1885 IP_STR
1886 PIM_STR
1887 VRF_CMD_HELP_STR
1888 "join prune aggregation list\n")
1889 {
1890 return pim_show_jp_agg_list_cmd_helper(vrf, vty);
1891 }
1892
1893 DEFPY (show_ip_pim_local_membership,
1894 show_ip_pim_local_membership_cmd,
1895 "show ip pim [vrf NAME] local-membership [json$json]",
1896 SHOW_STR
1897 IP_STR
1898 PIM_STR
1899 VRF_CMD_HELP_STR
1900 "PIM interface local-membership\n"
1901 JSON_STR)
1902 {
1903 return pim_show_membership_cmd_helper(vrf, vty, !!json);
1904 }
1905
1906 static void pim_show_mlag_up_entry_detail(struct vrf *vrf,
1907 struct vty *vty,
1908 struct pim_upstream *up,
1909 char *src_str, char *grp_str,
1910 json_object *json)
1911 {
1912 if (json) {
1913 json_object *json_row = NULL;
1914 json_object *own_list = NULL;
1915 json_object *json_group = NULL;
1916
1917
1918 json_object_object_get_ex(json, grp_str, &json_group);
1919 if (!json_group) {
1920 json_group = json_object_new_object();
1921 json_object_object_add(json, grp_str,
1922 json_group);
1923 }
1924
1925 json_row = json_object_new_object();
1926 json_object_string_add(json_row, "source", src_str);
1927 json_object_string_add(json_row, "group", grp_str);
1928
1929 own_list = json_object_new_array();
1930 if (pim_up_mlag_is_local(up))
1931 json_object_array_add(own_list,
1932 json_object_new_string("local"));
1933 if (up->flags & (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER))
1934 json_object_array_add(own_list,
1935 json_object_new_string("peer"));
1936 if (up->flags & (PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE))
1937 json_object_array_add(
1938 own_list, json_object_new_string("Interface"));
1939 json_object_object_add(json_row, "owners", own_list);
1940
1941 json_object_int_add(json_row, "localCost",
1942 pim_up_mlag_local_cost(up));
1943 json_object_int_add(json_row, "peerCost",
1944 pim_up_mlag_peer_cost(up));
1945 if (PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up->flags))
1946 json_object_boolean_false_add(json_row, "df");
1947 else
1948 json_object_boolean_true_add(json_row, "df");
1949 json_object_object_add(json_group, src_str, json_row);
1950 } else {
1951 char own_str[6];
1952
1953 own_str[0] = '\0';
1954 if (pim_up_mlag_is_local(up))
1955 strlcat(own_str, "L", sizeof(own_str));
1956 if (up->flags & (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER))
1957 strlcat(own_str, "P", sizeof(own_str));
1958 if (up->flags & (PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE))
1959 strlcat(own_str, "I", sizeof(own_str));
1960 /* XXX - fixup, print paragraph output */
1961 vty_out(vty,
1962 "%-15s %-15s %-6s %-11u %-10d %2s\n",
1963 src_str, grp_str, own_str,
1964 pim_up_mlag_local_cost(up),
1965 pim_up_mlag_peer_cost(up),
1966 PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up->flags)
1967 ? "n" : "y");
1968 }
1969 }
1970
1971 static void pim_show_mlag_up_detail(struct vrf *vrf,
1972 struct vty *vty, const char *src_or_group,
1973 const char *group, bool uj)
1974 {
1975 char src_str[PIM_ADDRSTRLEN];
1976 char grp_str[PIM_ADDRSTRLEN];
1977 struct pim_upstream *up;
1978 struct pim_instance *pim = vrf->info;
1979 json_object *json = NULL;
1980
1981 if (uj)
1982 json = json_object_new_object();
1983 else
1984 vty_out(vty,
1985 "Source Group Owner Local-cost Peer-cost DF\n");
1986
1987 frr_each (rb_pim_upstream, &pim->upstream_head, up) {
1988 if (!(up->flags & PIM_UPSTREAM_FLAG_MASK_MLAG_PEER)
1989 && !(up->flags & PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE)
1990 && !pim_up_mlag_is_local(up))
1991 continue;
1992
1993 snprintfrr(grp_str, sizeof(grp_str), "%pPAs", &up->sg.grp);
1994 snprintfrr(src_str, sizeof(src_str), "%pPAs", &up->sg.src);
1995
1996 /* XXX: strcmps are clearly inefficient. we should do uint comps
1997 * here instead.
1998 */
1999 if (group) {
2000 if (strcmp(src_str, src_or_group) ||
2001 strcmp(grp_str, group))
2002 continue;
2003 } else {
2004 if (strcmp(src_str, src_or_group) &&
2005 strcmp(grp_str, src_or_group))
2006 continue;
2007 }
2008 pim_show_mlag_up_entry_detail(vrf, vty, up,
2009 src_str, grp_str, json);
2010 }
2011
2012 if (uj)
2013 vty_json(vty, json);
2014 }
2015
2016 static void pim_show_mlag_up_vrf(struct vrf *vrf, struct vty *vty, bool uj)
2017 {
2018 json_object *json = NULL;
2019 json_object *json_row;
2020 struct pim_upstream *up;
2021 struct pim_instance *pim = vrf->info;
2022 json_object *json_group = NULL;
2023
2024 if (uj) {
2025 json = json_object_new_object();
2026 } else {
2027 vty_out(vty,
2028 "Source Group Owner Local-cost Peer-cost DF\n");
2029 }
2030
2031 frr_each (rb_pim_upstream, &pim->upstream_head, up) {
2032 if (!(up->flags & PIM_UPSTREAM_FLAG_MASK_MLAG_PEER)
2033 && !(up->flags & PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE)
2034 && !pim_up_mlag_is_local(up))
2035 continue;
2036 if (uj) {
2037 char src_str[PIM_ADDRSTRLEN];
2038 char grp_str[PIM_ADDRSTRLEN];
2039 json_object *own_list = NULL;
2040
2041 snprintfrr(grp_str, sizeof(grp_str), "%pPAs",
2042 &up->sg.grp);
2043 snprintfrr(src_str, sizeof(src_str), "%pPAs",
2044 &up->sg.src);
2045
2046 json_object_object_get_ex(json, grp_str, &json_group);
2047 if (!json_group) {
2048 json_group = json_object_new_object();
2049 json_object_object_add(json, grp_str,
2050 json_group);
2051 }
2052
2053 json_row = json_object_new_object();
2054 json_object_string_add(json_row, "vrf", vrf->name);
2055 json_object_string_add(json_row, "source", src_str);
2056 json_object_string_add(json_row, "group", grp_str);
2057
2058 own_list = json_object_new_array();
2059 if (pim_up_mlag_is_local(up)) {
2060
2061 json_object_array_add(own_list,
2062 json_object_new_string(
2063 "local"));
2064 }
2065 if (up->flags & (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER)) {
2066 json_object_array_add(own_list,
2067 json_object_new_string(
2068 "peer"));
2069 }
2070 json_object_object_add(json_row, "owners", own_list);
2071
2072 json_object_int_add(json_row, "localCost",
2073 pim_up_mlag_local_cost(up));
2074 json_object_int_add(json_row, "peerCost",
2075 pim_up_mlag_peer_cost(up));
2076 if (PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up->flags))
2077 json_object_boolean_false_add(json_row, "df");
2078 else
2079 json_object_boolean_true_add(json_row, "df");
2080 json_object_object_add(json_group, src_str, json_row);
2081 } else {
2082 char own_str[6];
2083
2084 own_str[0] = '\0';
2085 if (pim_up_mlag_is_local(up))
2086 strlcat(own_str, "L", sizeof(own_str));
2087 if (up->flags & (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER))
2088 strlcat(own_str, "P", sizeof(own_str));
2089 if (up->flags & (PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE))
2090 strlcat(own_str, "I", sizeof(own_str));
2091 vty_out(vty,
2092 "%-15pPAs %-15pPAs %-6s %-11u %-10u %2s\n",
2093 &up->sg.src, &up->sg.grp, own_str,
2094 pim_up_mlag_local_cost(up),
2095 pim_up_mlag_peer_cost(up),
2096 PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up->flags)
2097 ? "n" : "y");
2098 }
2099 }
2100 if (uj)
2101 vty_json(vty, json);
2102 }
2103
2104 static void pim_show_mlag_help_string(struct vty *vty, bool uj)
2105 {
2106 if (!uj) {
2107 vty_out(vty, "Owner codes:\n");
2108 vty_out(vty,
2109 "L: EVPN-MLAG Entry, I:PIM-MLAG Entry, P: Peer Entry\n");
2110 }
2111 }
2112
2113
2114 DEFUN(show_ip_pim_mlag_up, show_ip_pim_mlag_up_cmd,
2115 "show ip pim [vrf NAME] mlag upstream [A.B.C.D [A.B.C.D]] [json]",
2116 SHOW_STR
2117 IP_STR
2118 PIM_STR
2119 VRF_CMD_HELP_STR
2120 "MLAG\n"
2121 "upstream\n"
2122 "Unicast or Multicast address\n"
2123 "Multicast address\n" JSON_STR)
2124 {
2125 const char *src_or_group = NULL;
2126 const char *group = NULL;
2127 int idx = 2;
2128 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
2129 bool uj = use_json(argc, argv);
2130
2131 if (!vrf || !vrf->info) {
2132 vty_out(vty, "%s: VRF or Info missing\n", __func__);
2133 return CMD_WARNING;
2134 }
2135
2136 if (uj)
2137 argc--;
2138
2139 if (argv_find(argv, argc, "A.B.C.D", &idx)) {
2140 src_or_group = argv[idx]->arg;
2141 if (idx + 1 < argc)
2142 group = argv[idx + 1]->arg;
2143 }
2144
2145 pim_show_mlag_help_string(vty, uj);
2146
2147 if (src_or_group)
2148 pim_show_mlag_up_detail(vrf, vty, src_or_group, group, uj);
2149 else
2150 pim_show_mlag_up_vrf(vrf, vty, uj);
2151
2152 return CMD_SUCCESS;
2153 }
2154
2155
2156 DEFUN(show_ip_pim_mlag_up_vrf_all, show_ip_pim_mlag_up_vrf_all_cmd,
2157 "show ip pim vrf all mlag upstream [json]",
2158 SHOW_STR IP_STR PIM_STR VRF_CMD_HELP_STR
2159 "MLAG\n"
2160 "upstream\n" JSON_STR)
2161 {
2162 struct vrf *vrf;
2163 bool uj = use_json(argc, argv);
2164
2165 pim_show_mlag_help_string(vty, uj);
2166 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
2167 pim_show_mlag_up_vrf(vrf, vty, uj);
2168 }
2169
2170 return CMD_SUCCESS;
2171 }
2172
2173 DEFPY (show_ip_pim_neighbor,
2174 show_ip_pim_neighbor_cmd,
2175 "show ip pim [vrf NAME] neighbor [detail|WORD]$interface [json$json]",
2176 SHOW_STR
2177 IP_STR
2178 PIM_STR
2179 VRF_CMD_HELP_STR
2180 "PIM neighbor information\n"
2181 "Detailed output\n"
2182 "Name of interface or neighbor\n"
2183 JSON_STR)
2184 {
2185 return pim_show_neighbors_cmd_helper(vrf, vty, json, interface);
2186 }
2187
2188 DEFPY (show_ip_pim_neighbor_vrf_all,
2189 show_ip_pim_neighbor_vrf_all_cmd,
2190 "show ip pim vrf all neighbor [detail|WORD]$interface [json$json]",
2191 SHOW_STR
2192 IP_STR
2193 PIM_STR
2194 VRF_CMD_HELP_STR
2195 "PIM neighbor information\n"
2196 "Detailed output\n"
2197 "Name of interface or neighbor\n"
2198 JSON_STR)
2199 {
2200 return pim_show_neighbors_vrf_all_cmd_helper(vty, json, interface);
2201 }
2202
2203 DEFPY (show_ip_pim_secondary,
2204 show_ip_pim_secondary_cmd,
2205 "show ip pim [vrf NAME] secondary",
2206 SHOW_STR
2207 IP_STR
2208 PIM_STR
2209 VRF_CMD_HELP_STR
2210 "PIM neighbor addresses\n")
2211 {
2212 return pim_show_secondary_helper(vrf, vty);
2213 }
2214
2215 DEFPY (show_ip_pim_state,
2216 show_ip_pim_state_cmd,
2217 "show ip pim [vrf NAME] state [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
2218 SHOW_STR
2219 IP_STR
2220 PIM_STR
2221 VRF_CMD_HELP_STR
2222 "PIM state information\n"
2223 "Unicast or Multicast address\n"
2224 "Multicast address\n"
2225 JSON_STR)
2226 {
2227 return pim_show_state_helper(vrf, vty, s_or_g_str, g_str, !!json);
2228 }
2229
2230 DEFPY (show_ip_pim_state_vrf_all,
2231 show_ip_pim_state_vrf_all_cmd,
2232 "show ip pim vrf all state [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
2233 SHOW_STR
2234 IP_STR
2235 PIM_STR
2236 VRF_CMD_HELP_STR
2237 "PIM state information\n"
2238 "Unicast or Multicast address\n"
2239 "Multicast address\n"
2240 JSON_STR)
2241 {
2242 return pim_show_state_vrf_all_helper(vty, s_or_g_str, g_str, !!json);
2243 }
2244
2245 DEFPY (show_ip_pim_upstream,
2246 show_ip_pim_upstream_cmd,
2247 "show ip pim [vrf NAME] upstream [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
2248 SHOW_STR
2249 IP_STR
2250 PIM_STR
2251 VRF_CMD_HELP_STR
2252 "PIM upstream information\n"
2253 "The Source or Group\n"
2254 "The Group\n"
2255 JSON_STR)
2256 {
2257 return pim_show_upstream_helper(vrf, vty, s_or_g, g, !!json);
2258 }
2259
2260 DEFPY (show_ip_pim_upstream_vrf_all,
2261 show_ip_pim_upstream_vrf_all_cmd,
2262 "show ip pim vrf all upstream [json$json]",
2263 SHOW_STR
2264 IP_STR
2265 PIM_STR
2266 VRF_CMD_HELP_STR
2267 "PIM upstream information\n"
2268 JSON_STR)
2269 {
2270 return pim_show_upstream_vrf_all_helper(vty, !!json);
2271 }
2272
2273 DEFPY (show_ip_pim_channel,
2274 show_ip_pim_channel_cmd,
2275 "show ip pim [vrf NAME] channel [json$json]",
2276 SHOW_STR
2277 IP_STR
2278 PIM_STR
2279 VRF_CMD_HELP_STR
2280 "PIM downstream channel info\n"
2281 JSON_STR)
2282 {
2283 return pim_show_channel_cmd_helper(vrf, vty, !!json);
2284 }
2285
2286 DEFPY (show_ip_pim_upstream_join_desired,
2287 show_ip_pim_upstream_join_desired_cmd,
2288 "show ip pim [vrf NAME] upstream-join-desired [json$json]",
2289 SHOW_STR
2290 IP_STR
2291 PIM_STR
2292 VRF_CMD_HELP_STR
2293 "PIM upstream join-desired\n"
2294 JSON_STR)
2295 {
2296 return pim_show_upstream_join_desired_helper(vrf, vty, !!json);
2297 }
2298
2299 DEFPY (show_ip_pim_upstream_rpf,
2300 show_ip_pim_upstream_rpf_cmd,
2301 "show ip pim [vrf NAME] upstream-rpf [json$json]",
2302 SHOW_STR
2303 IP_STR
2304 PIM_STR
2305 VRF_CMD_HELP_STR
2306 "PIM upstream source rpf\n"
2307 JSON_STR)
2308 {
2309 return pim_show_upstream_rpf_helper(vrf, vty, !!json);
2310 }
2311
2312 DEFPY (show_ip_pim_rp,
2313 show_ip_pim_rp_cmd,
2314 "show ip pim [vrf NAME] rp-info [A.B.C.D/M$group] [json$json]",
2315 SHOW_STR
2316 IP_STR
2317 PIM_STR
2318 VRF_CMD_HELP_STR
2319 "PIM RP information\n"
2320 "Multicast Group range\n"
2321 JSON_STR)
2322 {
2323 return pim_show_rp_helper(vrf, vty, group_str, (struct prefix *)group,
2324 !!json);
2325 }
2326
2327 DEFPY (show_ip_pim_rp_vrf_all,
2328 show_ip_pim_rp_vrf_all_cmd,
2329 "show ip pim vrf all rp-info [A.B.C.D/M$group] [json$json]",
2330 SHOW_STR
2331 IP_STR
2332 PIM_STR
2333 VRF_CMD_HELP_STR
2334 "PIM RP information\n"
2335 "Multicast Group range\n"
2336 JSON_STR)
2337 {
2338 return pim_show_rp_vrf_all_helper(vty, group_str,
2339 (struct prefix *)group, !!json);
2340 }
2341
2342 DEFPY (show_ip_pim_rpf,
2343 show_ip_pim_rpf_cmd,
2344 "show ip pim [vrf NAME] rpf [json$json]",
2345 SHOW_STR
2346 IP_STR
2347 PIM_STR
2348 VRF_CMD_HELP_STR
2349 "PIM cached source rpf information\n"
2350 JSON_STR)
2351 {
2352 return pim_show_rpf_helper(vrf, vty, !!json);
2353 }
2354
2355 DEFPY (show_ip_pim_rpf_vrf_all,
2356 show_ip_pim_rpf_vrf_all_cmd,
2357 "show ip pim vrf all rpf [json$json]",
2358 SHOW_STR
2359 IP_STR
2360 PIM_STR
2361 VRF_CMD_HELP_STR
2362 "PIM cached source rpf information\n"
2363 JSON_STR)
2364 {
2365 return pim_show_rpf_vrf_all_helper(vty, !!json);
2366 }
2367
2368 DEFPY (show_ip_pim_nexthop,
2369 show_ip_pim_nexthop_cmd,
2370 "show ip pim [vrf NAME] nexthop [json$json]",
2371 SHOW_STR
2372 IP_STR
2373 PIM_STR
2374 VRF_CMD_HELP_STR
2375 "PIM cached nexthop rpf information\n"
2376 JSON_STR)
2377 {
2378 return pim_show_nexthop_cmd_helper(vrf, vty, !!json);
2379 }
2380
2381 DEFPY (show_ip_pim_nexthop_lookup,
2382 show_ip_pim_nexthop_lookup_cmd,
2383 "show ip pim [vrf NAME] nexthop-lookup A.B.C.D$source A.B.C.D$group",
2384 SHOW_STR
2385 IP_STR
2386 PIM_STR
2387 VRF_CMD_HELP_STR
2388 "PIM cached nexthop rpf lookup\n"
2389 "Source/RP address\n"
2390 "Multicast Group address\n")
2391 {
2392 return pim_show_nexthop_lookup_cmd_helper(vrf, vty, source, group);
2393 }
2394
2395 DEFPY (show_ip_pim_interface_traffic,
2396 show_ip_pim_interface_traffic_cmd,
2397 "show ip pim [vrf NAME] interface traffic [WORD$if_name] [json$json]",
2398 SHOW_STR
2399 IP_STR
2400 PIM_STR
2401 VRF_CMD_HELP_STR
2402 "PIM interface information\n"
2403 "Protocol Packet counters\n"
2404 "Interface name\n"
2405 JSON_STR)
2406 {
2407 return pim_show_interface_traffic_helper(vrf, if_name, vty, !!json);
2408 }
2409
2410 DEFPY (show_ip_pim_bsm_db,
2411 show_ip_pim_bsm_db_cmd,
2412 "show ip pim bsm-database [vrf NAME] [json$json]",
2413 SHOW_STR
2414 IP_STR
2415 PIM_STR
2416 "PIM cached bsm packets information\n"
2417 VRF_CMD_HELP_STR
2418 JSON_STR)
2419 {
2420 return pim_show_bsm_db_helper(vrf, vty, !!json);
2421 }
2422
2423 DEFPY (show_ip_pim_bsrp,
2424 show_ip_pim_bsrp_cmd,
2425 "show ip pim bsrp-info [vrf NAME] [json$json]",
2426 SHOW_STR
2427 IP_STR
2428 PIM_STR
2429 "PIM cached group-rp mappings information\n"
2430 VRF_CMD_HELP_STR
2431 JSON_STR)
2432 {
2433 return pim_show_group_rp_mappings_info_helper(vrf, vty, !!json);
2434 }
2435
2436 DEFPY (show_ip_pim_statistics,
2437 show_ip_pim_statistics_cmd,
2438 "show ip pim [vrf NAME] statistics [interface WORD$word] [json$json]",
2439 SHOW_STR
2440 IP_STR
2441 PIM_STR
2442 VRF_CMD_HELP_STR
2443 "PIM statistics\n"
2444 INTERFACE_STR
2445 "PIM interface\n"
2446 JSON_STR)
2447 {
2448 return pim_show_statistics_helper(vrf, vty, word, !!json);
2449 }
2450
2451 DEFPY (show_ip_multicast,
2452 show_ip_multicast_cmd,
2453 "show ip multicast [vrf NAME]",
2454 SHOW_STR
2455 IP_STR
2456 "Multicast global information\n"
2457 VRF_CMD_HELP_STR)
2458 {
2459 return pim_show_multicast_helper(vrf, vty);
2460 }
2461
2462 DEFPY (show_ip_multicast_vrf_all,
2463 show_ip_multicast_vrf_all_cmd,
2464 "show ip multicast vrf all",
2465 SHOW_STR
2466 IP_STR
2467 "Multicast global information\n"
2468 VRF_CMD_HELP_STR)
2469 {
2470 return pim_show_multicast_vrf_all_helper(vty);
2471 }
2472
2473 DEFPY (show_ip_multicast_count,
2474 show_ip_multicast_count_cmd,
2475 "show ip multicast count [vrf NAME] [json$json]",
2476 SHOW_STR
2477 IP_STR
2478 "Multicast global information\n"
2479 "Data packet count\n"
2480 VRF_CMD_HELP_STR
2481 JSON_STR)
2482 {
2483 return pim_show_multicast_count_helper(vrf, vty, !!json);
2484 }
2485
2486 DEFPY (show_ip_multicast_count_vrf_all,
2487 show_ip_multicast_count_vrf_all_cmd,
2488 "show ip multicast count vrf all [json$json]",
2489 SHOW_STR
2490 IP_STR
2491 "Multicast global information\n"
2492 "Data packet count\n"
2493 VRF_CMD_HELP_STR
2494 JSON_STR)
2495 {
2496 return pim_show_multicast_count_vrf_all_helper(vty, !!json);
2497 }
2498
2499 DEFPY (show_ip_mroute,
2500 show_ip_mroute_cmd,
2501 "show ip mroute [vrf NAME] [A.B.C.D$s_or_g [A.B.C.D$g]] [fill$fill] [json$json]",
2502 SHOW_STR
2503 IP_STR
2504 MROUTE_STR
2505 VRF_CMD_HELP_STR
2506 "The Source or Group\n"
2507 "The Group\n"
2508 "Fill in Assumed data\n"
2509 JSON_STR)
2510 {
2511 return pim_show_mroute_helper(vrf, vty, s_or_g, g, !!fill, !!json);
2512 }
2513
2514 DEFPY (show_ip_mroute_vrf_all,
2515 show_ip_mroute_vrf_all_cmd,
2516 "show ip mroute vrf all [fill$fill] [json$json]",
2517 SHOW_STR
2518 IP_STR
2519 MROUTE_STR
2520 VRF_CMD_HELP_STR
2521 "Fill in Assumed data\n"
2522 JSON_STR)
2523 {
2524 return pim_show_mroute_vrf_all_helper(vty, !!fill, !!json);
2525 }
2526
2527 DEFPY (clear_ip_mroute_count,
2528 clear_ip_mroute_count_cmd,
2529 "clear ip mroute [vrf NAME]$name count",
2530 CLEAR_STR
2531 IP_STR
2532 MROUTE_STR
2533 VRF_CMD_HELP_STR
2534 "Route and packet count data\n")
2535 {
2536 return clear_ip_mroute_count_command(vty, name);
2537 }
2538
2539 DEFPY (show_ip_mroute_count,
2540 show_ip_mroute_count_cmd,
2541 "show ip mroute [vrf NAME] count [json$json]",
2542 SHOW_STR
2543 IP_STR
2544 MROUTE_STR
2545 VRF_CMD_HELP_STR
2546 "Route and packet count data\n"
2547 JSON_STR)
2548 {
2549 return pim_show_mroute_count_helper(vrf, vty, !!json);
2550 }
2551
2552 DEFPY (show_ip_mroute_count_vrf_all,
2553 show_ip_mroute_count_vrf_all_cmd,
2554 "show ip mroute vrf all count [json$json]",
2555 SHOW_STR
2556 IP_STR
2557 MROUTE_STR
2558 VRF_CMD_HELP_STR
2559 "Route and packet count data\n"
2560 JSON_STR)
2561 {
2562 return pim_show_mroute_count_vrf_all_helper(vty, !!json);
2563 }
2564
2565 DEFPY (show_ip_mroute_summary,
2566 show_ip_mroute_summary_cmd,
2567 "show ip mroute [vrf NAME] summary [json$json]",
2568 SHOW_STR
2569 IP_STR
2570 MROUTE_STR
2571 VRF_CMD_HELP_STR
2572 "Summary of all mroutes\n"
2573 JSON_STR)
2574 {
2575 return pim_show_mroute_summary_helper(vrf, vty, !!json);
2576 }
2577
2578 DEFPY (show_ip_mroute_summary_vrf_all,
2579 show_ip_mroute_summary_vrf_all_cmd,
2580 "show ip mroute vrf all summary [json$json]",
2581 SHOW_STR
2582 IP_STR
2583 MROUTE_STR
2584 VRF_CMD_HELP_STR
2585 "Summary of all mroutes\n"
2586 JSON_STR)
2587 {
2588 return pim_show_mroute_summary_vrf_all_helper(vty, !!json);
2589 }
2590
2591 DEFUN (show_ip_rib,
2592 show_ip_rib_cmd,
2593 "show ip rib [vrf NAME] A.B.C.D",
2594 SHOW_STR
2595 IP_STR
2596 RIB_STR
2597 VRF_CMD_HELP_STR
2598 "Unicast address\n")
2599 {
2600 int idx = 2;
2601 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
2602 struct in_addr addr;
2603 const char *addr_str;
2604 struct pim_nexthop nexthop;
2605 int result;
2606
2607 if (!vrf)
2608 return CMD_WARNING;
2609
2610 memset(&nexthop, 0, sizeof(nexthop));
2611 argv_find(argv, argc, "A.B.C.D", &idx);
2612 addr_str = argv[idx]->arg;
2613 result = inet_pton(AF_INET, addr_str, &addr);
2614 if (result <= 0) {
2615 vty_out(vty, "Bad unicast address %s: errno=%d: %s\n", addr_str,
2616 errno, safe_strerror(errno));
2617 return CMD_WARNING;
2618 }
2619
2620 if (!pim_nexthop_lookup(vrf->info, &nexthop, addr, 0)) {
2621 vty_out(vty,
2622 "Failure querying RIB nexthop for unicast address %s\n",
2623 addr_str);
2624 return CMD_WARNING;
2625 }
2626
2627 vty_out(vty,
2628 "Address NextHop Interface Metric Preference\n");
2629
2630 vty_out(vty, "%-15s %-15pPAs %-9s %6d %10d\n", addr_str,
2631 &nexthop.mrib_nexthop_addr,
2632 nexthop.interface ? nexthop.interface->name : "<ifname?>",
2633 nexthop.mrib_route_metric, nexthop.mrib_metric_preference);
2634
2635 return CMD_SUCCESS;
2636 }
2637
2638 static void show_ssmpingd(struct pim_instance *pim, struct vty *vty)
2639 {
2640 struct listnode *node;
2641 struct ssmpingd_sock *ss;
2642 time_t now;
2643
2644 vty_out(vty,
2645 "Source Socket Address Port Uptime Requests\n");
2646
2647 if (!pim->ssmpingd_list)
2648 return;
2649
2650 now = pim_time_monotonic_sec();
2651
2652 for (ALL_LIST_ELEMENTS_RO(pim->ssmpingd_list, node, ss)) {
2653 char source_str[INET_ADDRSTRLEN];
2654 char ss_uptime[10];
2655 struct sockaddr_in bind_addr;
2656 socklen_t len = sizeof(bind_addr);
2657 char bind_addr_str[INET_ADDRSTRLEN];
2658
2659 pim_inet4_dump("<src?>", ss->source_addr, source_str,
2660 sizeof(source_str));
2661
2662 if (pim_socket_getsockname(
2663 ss->sock_fd, (struct sockaddr *)&bind_addr, &len)) {
2664 vty_out(vty,
2665 "%% Failure reading socket name for ssmpingd source %s on fd=%d\n",
2666 source_str, ss->sock_fd);
2667 }
2668
2669 pim_inet4_dump("<addr?>", bind_addr.sin_addr, bind_addr_str,
2670 sizeof(bind_addr_str));
2671 pim_time_uptime(ss_uptime, sizeof(ss_uptime),
2672 now - ss->creation);
2673
2674 vty_out(vty, "%-15s %6d %-15s %5d %8s %8lld\n", source_str,
2675 ss->sock_fd, bind_addr_str, ntohs(bind_addr.sin_port),
2676 ss_uptime, (long long)ss->requests);
2677 }
2678 }
2679
2680 DEFUN (show_ip_ssmpingd,
2681 show_ip_ssmpingd_cmd,
2682 "show ip ssmpingd [vrf NAME]",
2683 SHOW_STR
2684 IP_STR
2685 SHOW_SSMPINGD_STR
2686 VRF_CMD_HELP_STR)
2687 {
2688 int idx = 2;
2689 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
2690
2691 if (!vrf)
2692 return CMD_WARNING;
2693
2694 show_ssmpingd(vrf->info, vty);
2695 return CMD_SUCCESS;
2696 }
2697
2698 DEFUN (ip_pim_spt_switchover_infinity,
2699 ip_pim_spt_switchover_infinity_cmd,
2700 "ip pim spt-switchover infinity-and-beyond",
2701 IP_STR
2702 PIM_STR
2703 "SPT-Switchover\n"
2704 "Never switch to SPT Tree\n")
2705 {
2706 return pim_process_spt_switchover_infinity_cmd(vty);
2707 }
2708
2709 DEFPY (ip_pim_spt_switchover_infinity_plist,
2710 ip_pim_spt_switchover_infinity_plist_cmd,
2711 "ip pim spt-switchover infinity-and-beyond prefix-list WORD$plist",
2712 IP_STR
2713 PIM_STR
2714 "SPT-Switchover\n"
2715 "Never switch to SPT Tree\n"
2716 "Prefix-List to control which groups to switch\n"
2717 "Prefix-List name\n")
2718 {
2719 return pim_process_spt_switchover_prefixlist_cmd(vty, plist);
2720 }
2721
2722 DEFUN (no_ip_pim_spt_switchover_infinity,
2723 no_ip_pim_spt_switchover_infinity_cmd,
2724 "no ip pim spt-switchover infinity-and-beyond",
2725 NO_STR
2726 IP_STR
2727 PIM_STR
2728 "SPT_Switchover\n"
2729 "Never switch to SPT Tree\n")
2730 {
2731 return pim_process_no_spt_switchover_cmd(vty);
2732 }
2733
2734 DEFUN (no_ip_pim_spt_switchover_infinity_plist,
2735 no_ip_pim_spt_switchover_infinity_plist_cmd,
2736 "no ip pim spt-switchover infinity-and-beyond prefix-list WORD",
2737 NO_STR
2738 IP_STR
2739 PIM_STR
2740 "SPT_Switchover\n"
2741 "Never switch to SPT Tree\n"
2742 "Prefix-List to control which groups to switch\n"
2743 "Prefix-List name\n")
2744 {
2745 return pim_process_no_spt_switchover_cmd(vty);
2746 }
2747
2748 DEFPY (pim_register_accept_list,
2749 pim_register_accept_list_cmd,
2750 "[no] ip pim register-accept-list WORD$word",
2751 NO_STR
2752 IP_STR
2753 PIM_STR
2754 "Only accept registers from a specific source prefix list\n"
2755 "Prefix-List name\n")
2756 {
2757 const char *vrfname;
2758 char reg_alist_xpath[XPATH_MAXLEN];
2759
2760 vrfname = pim_cli_get_vrf_name(vty);
2761 if (vrfname == NULL)
2762 return CMD_WARNING_CONFIG_FAILED;
2763
2764 snprintf(reg_alist_xpath, sizeof(reg_alist_xpath),
2765 FRR_PIM_VRF_XPATH, "frr-pim:pimd", "pim", vrfname,
2766 "frr-routing:ipv4");
2767 strlcat(reg_alist_xpath, "/register-accept-list",
2768 sizeof(reg_alist_xpath));
2769
2770 if (no)
2771 nb_cli_enqueue_change(vty, reg_alist_xpath,
2772 NB_OP_DESTROY, NULL);
2773 else
2774 nb_cli_enqueue_change(vty, reg_alist_xpath,
2775 NB_OP_MODIFY, word);
2776
2777 return nb_cli_apply_changes(vty, NULL);
2778 }
2779
2780 DEFPY (ip_pim_joinprune_time,
2781 ip_pim_joinprune_time_cmd,
2782 "ip pim join-prune-interval (1-65535)$jpi",
2783 IP_STR
2784 "pim multicast routing\n"
2785 "Join Prune Send Interval\n"
2786 "Seconds\n")
2787 {
2788 return pim_process_join_prune_cmd(vty, jpi_str);
2789 }
2790
2791 DEFUN (no_ip_pim_joinprune_time,
2792 no_ip_pim_joinprune_time_cmd,
2793 "no ip pim join-prune-interval [(1-65535)]",
2794 NO_STR
2795 IP_STR
2796 "pim multicast routing\n"
2797 "Join Prune Send Interval\n"
2798 IGNORED_IN_NO_STR)
2799 {
2800 return pim_process_no_join_prune_cmd(vty);
2801 }
2802
2803 DEFPY (ip_pim_register_suppress,
2804 ip_pim_register_suppress_cmd,
2805 "ip pim register-suppress-time (1-65535)$rst",
2806 IP_STR
2807 "pim multicast routing\n"
2808 "Register Suppress Timer\n"
2809 "Seconds\n")
2810 {
2811 return pim_process_register_suppress_cmd(vty, rst_str);
2812 }
2813
2814 DEFUN (no_ip_pim_register_suppress,
2815 no_ip_pim_register_suppress_cmd,
2816 "no ip pim register-suppress-time [(1-65535)]",
2817 NO_STR
2818 IP_STR
2819 "pim multicast routing\n"
2820 "Register Suppress Timer\n"
2821 IGNORED_IN_NO_STR)
2822 {
2823 return pim_process_no_register_suppress_cmd(vty);
2824 }
2825
2826 DEFPY (ip_pim_rp_keep_alive,
2827 ip_pim_rp_keep_alive_cmd,
2828 "ip pim rp keep-alive-timer (1-65535)$kat",
2829 IP_STR
2830 "pim multicast routing\n"
2831 "Rendezvous Point\n"
2832 "Keep alive Timer\n"
2833 "Seconds\n")
2834 {
2835 return pim_process_rp_kat_cmd(vty, kat_str);
2836 }
2837
2838 DEFUN (no_ip_pim_rp_keep_alive,
2839 no_ip_pim_rp_keep_alive_cmd,
2840 "no ip pim rp keep-alive-timer [(1-65535)]",
2841 NO_STR
2842 IP_STR
2843 "pim multicast routing\n"
2844 "Rendezvous Point\n"
2845 "Keep alive Timer\n"
2846 IGNORED_IN_NO_STR)
2847 {
2848 return pim_process_no_rp_kat_cmd(vty);
2849 }
2850
2851 DEFPY (ip_pim_keep_alive,
2852 ip_pim_keep_alive_cmd,
2853 "ip pim keep-alive-timer (1-65535)$kat",
2854 IP_STR
2855 "pim multicast routing\n"
2856 "Keep alive Timer\n"
2857 "Seconds\n")
2858 {
2859 return pim_process_keepalivetimer_cmd(vty, kat_str);
2860 }
2861
2862 DEFUN (no_ip_pim_keep_alive,
2863 no_ip_pim_keep_alive_cmd,
2864 "no ip pim keep-alive-timer [(1-65535)]",
2865 NO_STR
2866 IP_STR
2867 "pim multicast routing\n"
2868 "Keep alive Timer\n"
2869 IGNORED_IN_NO_STR)
2870 {
2871 return pim_process_no_keepalivetimer_cmd(vty);
2872 }
2873
2874 DEFPY (ip_pim_packets,
2875 ip_pim_packets_cmd,
2876 "ip pim packets (1-255)",
2877 IP_STR
2878 "pim multicast routing\n"
2879 "packets to process at one time per fd\n"
2880 "Number of packets\n")
2881 {
2882 return pim_process_pim_packet_cmd(vty, packets_str);
2883 }
2884
2885 DEFUN (no_ip_pim_packets,
2886 no_ip_pim_packets_cmd,
2887 "no ip pim packets [(1-255)]",
2888 NO_STR
2889 IP_STR
2890 "pim multicast routing\n"
2891 "packets to process at one time per fd\n"
2892 IGNORED_IN_NO_STR)
2893 {
2894 return pim_process_no_pim_packet_cmd(vty);
2895 }
2896
2897 DEFPY (ip_igmp_group_watermark,
2898 ip_igmp_group_watermark_cmd,
2899 "ip igmp watermark-warn (1-65535)$limit",
2900 IP_STR
2901 IGMP_STR
2902 "Configure group limit for watermark warning\n"
2903 "Group count to generate watermark warning\n")
2904 {
2905 PIM_DECLVAR_CONTEXT_VRF(vrf, pim);
2906 pim->gm_watermark_limit = limit;
2907
2908 return CMD_SUCCESS;
2909 }
2910
2911 DEFPY (no_ip_igmp_group_watermark,
2912 no_ip_igmp_group_watermark_cmd,
2913 "no ip igmp watermark-warn [(1-65535)$limit]",
2914 NO_STR
2915 IP_STR
2916 IGMP_STR
2917 "Unconfigure group limit for watermark warning\n"
2918 IGNORED_IN_NO_STR)
2919 {
2920 PIM_DECLVAR_CONTEXT_VRF(vrf, pim);
2921 pim->gm_watermark_limit = 0;
2922
2923 return CMD_SUCCESS;
2924 }
2925
2926 DEFUN (ip_pim_v6_secondary,
2927 ip_pim_v6_secondary_cmd,
2928 "ip pim send-v6-secondary",
2929 IP_STR
2930 "pim multicast routing\n"
2931 "Send v6 secondary addresses\n")
2932 {
2933 const char *vrfname;
2934 char send_v6_secondary_xpath[XPATH_MAXLEN];
2935
2936 vrfname = pim_cli_get_vrf_name(vty);
2937 if (vrfname == NULL)
2938 return CMD_WARNING_CONFIG_FAILED;
2939
2940 snprintf(send_v6_secondary_xpath, sizeof(send_v6_secondary_xpath),
2941 FRR_PIM_VRF_XPATH,
2942 "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
2943 strlcat(send_v6_secondary_xpath, "/send-v6-secondary",
2944 sizeof(send_v6_secondary_xpath));
2945
2946 nb_cli_enqueue_change(vty, send_v6_secondary_xpath, NB_OP_MODIFY,
2947 "true");
2948
2949 return nb_cli_apply_changes(vty, NULL);
2950 }
2951
2952 DEFUN (no_ip_pim_v6_secondary,
2953 no_ip_pim_v6_secondary_cmd,
2954 "no ip pim send-v6-secondary",
2955 NO_STR
2956 IP_STR
2957 "pim multicast routing\n"
2958 "Send v6 secondary addresses\n")
2959 {
2960 const char *vrfname;
2961 char send_v6_secondary_xpath[XPATH_MAXLEN];
2962
2963 vrfname = pim_cli_get_vrf_name(vty);
2964 if (vrfname == NULL)
2965 return CMD_WARNING_CONFIG_FAILED;
2966
2967 snprintf(send_v6_secondary_xpath, sizeof(send_v6_secondary_xpath),
2968 FRR_PIM_VRF_XPATH,
2969 "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
2970 strlcat(send_v6_secondary_xpath, "/send-v6-secondary",
2971 sizeof(send_v6_secondary_xpath));
2972
2973 nb_cli_enqueue_change(vty, send_v6_secondary_xpath, NB_OP_MODIFY,
2974 "false");
2975
2976 return nb_cli_apply_changes(vty, NULL);
2977 }
2978
2979 DEFPY (ip_pim_rp,
2980 ip_pim_rp_cmd,
2981 "ip pim rp A.B.C.D$rp [A.B.C.D/M]$gp",
2982 IP_STR
2983 "pim multicast routing\n"
2984 "Rendezvous Point\n"
2985 "ip address of RP\n"
2986 "Group Address range to cover\n")
2987 {
2988 const char *group_str = (gp_str) ? gp_str : "224.0.0.0/4";
2989
2990 return pim_process_rp_cmd(vty, rp_str, group_str);
2991 }
2992
2993 DEFPY (ip_pim_rp_prefix_list,
2994 ip_pim_rp_prefix_list_cmd,
2995 "ip pim rp A.B.C.D$rp prefix-list WORD$plist",
2996 IP_STR
2997 "pim multicast routing\n"
2998 "Rendezvous Point\n"
2999 "ip address of RP\n"
3000 "group prefix-list filter\n"
3001 "Name of a prefix-list\n")
3002 {
3003 return pim_process_rp_plist_cmd(vty, rp_str, plist);
3004 }
3005
3006 DEFPY (no_ip_pim_rp,
3007 no_ip_pim_rp_cmd,
3008 "no ip pim rp A.B.C.D$rp [A.B.C.D/M]$gp",
3009 NO_STR
3010 IP_STR
3011 "pim multicast routing\n"
3012 "Rendezvous Point\n"
3013 "ip address of RP\n"
3014 "Group Address range to cover\n")
3015 {
3016 const char *group_str = (gp_str) ? gp_str : "224.0.0.0/4";
3017
3018 return pim_process_no_rp_cmd(vty, rp_str, group_str);
3019 }
3020
3021 DEFPY (no_ip_pim_rp_prefix_list,
3022 no_ip_pim_rp_prefix_list_cmd,
3023 "no ip pim rp A.B.C.D$rp prefix-list WORD$plist",
3024 NO_STR
3025 IP_STR
3026 "pim multicast routing\n"
3027 "Rendezvous Point\n"
3028 "ip address of RP\n"
3029 "group prefix-list filter\n"
3030 "Name of a prefix-list\n")
3031 {
3032 return pim_process_no_rp_plist_cmd(vty, rp_str, plist);
3033 }
3034
3035 DEFUN (ip_pim_ssm_prefix_list,
3036 ip_pim_ssm_prefix_list_cmd,
3037 "ip pim ssm prefix-list WORD",
3038 IP_STR
3039 "pim multicast routing\n"
3040 "Source Specific Multicast\n"
3041 "group range prefix-list filter\n"
3042 "Name of a prefix-list\n")
3043 {
3044 const char *vrfname;
3045 char ssm_plist_xpath[XPATH_MAXLEN];
3046
3047 vrfname = pim_cli_get_vrf_name(vty);
3048 if (vrfname == NULL)
3049 return CMD_WARNING_CONFIG_FAILED;
3050
3051 snprintf(ssm_plist_xpath, sizeof(ssm_plist_xpath), FRR_PIM_VRF_XPATH,
3052 "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
3053 strlcat(ssm_plist_xpath, "/ssm-prefix-list", sizeof(ssm_plist_xpath));
3054
3055 nb_cli_enqueue_change(vty, ssm_plist_xpath, NB_OP_MODIFY, argv[4]->arg);
3056
3057 return nb_cli_apply_changes(vty, NULL);
3058 }
3059
3060 DEFUN (no_ip_pim_ssm_prefix_list,
3061 no_ip_pim_ssm_prefix_list_cmd,
3062 "no ip pim ssm prefix-list",
3063 NO_STR
3064 IP_STR
3065 "pim multicast routing\n"
3066 "Source Specific Multicast\n"
3067 "group range prefix-list filter\n")
3068 {
3069 const char *vrfname;
3070 char ssm_plist_xpath[XPATH_MAXLEN];
3071
3072 vrfname = pim_cli_get_vrf_name(vty);
3073 if (vrfname == NULL)
3074 return CMD_WARNING_CONFIG_FAILED;
3075
3076 snprintf(ssm_plist_xpath, sizeof(ssm_plist_xpath),
3077 FRR_PIM_VRF_XPATH,
3078 "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
3079 strlcat(ssm_plist_xpath, "/ssm-prefix-list", sizeof(ssm_plist_xpath));
3080
3081 nb_cli_enqueue_change(vty, ssm_plist_xpath, NB_OP_DESTROY, NULL);
3082
3083 return nb_cli_apply_changes(vty, NULL);
3084 }
3085
3086 DEFUN (no_ip_pim_ssm_prefix_list_name,
3087 no_ip_pim_ssm_prefix_list_name_cmd,
3088 "no ip pim ssm prefix-list WORD",
3089 NO_STR
3090 IP_STR
3091 "pim multicast routing\n"
3092 "Source Specific Multicast\n"
3093 "group range prefix-list filter\n"
3094 "Name of a prefix-list\n")
3095 {
3096 const char *vrfname;
3097 const struct lyd_node *ssm_plist_dnode;
3098 char ssm_plist_xpath[XPATH_MAXLEN];
3099 const char *ssm_plist_name;
3100
3101 vrfname = pim_cli_get_vrf_name(vty);
3102 if (vrfname == NULL)
3103 return CMD_WARNING_CONFIG_FAILED;
3104
3105 snprintf(ssm_plist_xpath, sizeof(ssm_plist_xpath),
3106 FRR_PIM_VRF_XPATH,
3107 "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
3108 strlcat(ssm_plist_xpath, "/ssm-prefix-list", sizeof(ssm_plist_xpath));
3109 ssm_plist_dnode = yang_dnode_get(vty->candidate_config->dnode,
3110 ssm_plist_xpath);
3111
3112 if (!ssm_plist_dnode) {
3113 vty_out(vty,
3114 "%% pim ssm prefix-list %s doesn't exist\n",
3115 argv[5]->arg);
3116 return CMD_WARNING_CONFIG_FAILED;
3117 }
3118
3119 ssm_plist_name = yang_dnode_get_string(ssm_plist_dnode, ".");
3120
3121 if (ssm_plist_name && !strcmp(ssm_plist_name, argv[5]->arg)) {
3122 nb_cli_enqueue_change(vty, ssm_plist_xpath, NB_OP_DESTROY,
3123 NULL);
3124
3125 return nb_cli_apply_changes(vty, NULL);
3126 }
3127
3128 vty_out(vty, "%% pim ssm prefix-list %s doesn't exist\n", argv[5]->arg);
3129
3130 return CMD_WARNING_CONFIG_FAILED;
3131 }
3132
3133 DEFUN (show_ip_pim_ssm_range,
3134 show_ip_pim_ssm_range_cmd,
3135 "show ip pim [vrf NAME] group-type [json]",
3136 SHOW_STR
3137 IP_STR
3138 PIM_STR
3139 VRF_CMD_HELP_STR
3140 "PIM group type\n"
3141 JSON_STR)
3142 {
3143 int idx = 2;
3144 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3145 bool uj = use_json(argc, argv);
3146
3147 if (!vrf)
3148 return CMD_WARNING;
3149
3150 ip_pim_ssm_show_group_range(vrf->info, vty, uj);
3151
3152 return CMD_SUCCESS;
3153 }
3154
3155 static void ip_pim_ssm_show_group_type(struct pim_instance *pim,
3156 struct vty *vty, bool uj,
3157 const char *group)
3158 {
3159 struct in_addr group_addr;
3160 const char *type_str;
3161 int result;
3162
3163 result = inet_pton(AF_INET, group, &group_addr);
3164 if (result <= 0)
3165 type_str = "invalid";
3166 else {
3167 if (pim_is_group_224_4(group_addr))
3168 type_str =
3169 pim_is_grp_ssm(pim, group_addr) ? "SSM" : "ASM";
3170 else
3171 type_str = "not-multicast";
3172 }
3173
3174 if (uj) {
3175 json_object *json;
3176 json = json_object_new_object();
3177 json_object_string_add(json, "groupType", type_str);
3178 vty_json(vty, json);
3179 } else
3180 vty_out(vty, "Group type : %s\n", type_str);
3181 }
3182
3183 DEFUN (show_ip_pim_group_type,
3184 show_ip_pim_group_type_cmd,
3185 "show ip pim [vrf NAME] group-type A.B.C.D [json]",
3186 SHOW_STR
3187 IP_STR
3188 PIM_STR
3189 VRF_CMD_HELP_STR
3190 "multicast group type\n"
3191 "group address\n"
3192 JSON_STR)
3193 {
3194 int idx = 2;
3195 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3196 bool uj = use_json(argc, argv);
3197
3198 if (!vrf)
3199 return CMD_WARNING;
3200
3201 argv_find(argv, argc, "A.B.C.D", &idx);
3202 ip_pim_ssm_show_group_type(vrf->info, vty, uj, argv[idx]->arg);
3203
3204 return CMD_SUCCESS;
3205 }
3206
3207 DEFPY (show_ip_pim_bsr,
3208 show_ip_pim_bsr_cmd,
3209 "show ip pim bsr [vrf NAME] [json$json]",
3210 SHOW_STR
3211 IP_STR
3212 PIM_STR
3213 "boot-strap router information\n"
3214 VRF_CMD_HELP_STR
3215 JSON_STR)
3216 {
3217 return pim_show_bsr_helper(vrf, vty, !!json);
3218 }
3219
3220 DEFUN (ip_ssmpingd,
3221 ip_ssmpingd_cmd,
3222 "ip ssmpingd [A.B.C.D]",
3223 IP_STR
3224 CONF_SSMPINGD_STR
3225 "Source address\n")
3226 {
3227 int idx_ipv4 = 2;
3228 const char *src_str = (argc == 3) ? argv[idx_ipv4]->arg : "0.0.0.0";
3229
3230 return pim_process_ssmpingd_cmd(vty, NB_OP_CREATE, src_str);
3231 }
3232
3233 DEFUN (no_ip_ssmpingd,
3234 no_ip_ssmpingd_cmd,
3235 "no ip ssmpingd [A.B.C.D]",
3236 NO_STR
3237 IP_STR
3238 CONF_SSMPINGD_STR
3239 "Source address\n")
3240 {
3241 int idx_ipv4 = 3;
3242 const char *src_str = (argc == 4) ? argv[idx_ipv4]->arg : "0.0.0.0";
3243
3244 return pim_process_ssmpingd_cmd(vty, NB_OP_DESTROY, src_str);
3245 }
3246
3247 DEFUN (ip_pim_ecmp,
3248 ip_pim_ecmp_cmd,
3249 "ip pim ecmp",
3250 IP_STR
3251 "pim multicast routing\n"
3252 "Enable PIM ECMP \n")
3253 {
3254 const char *vrfname;
3255 char ecmp_xpath[XPATH_MAXLEN];
3256
3257 vrfname = pim_cli_get_vrf_name(vty);
3258 if (vrfname == NULL)
3259 return CMD_WARNING_CONFIG_FAILED;
3260
3261 snprintf(ecmp_xpath, sizeof(ecmp_xpath), FRR_PIM_VRF_XPATH,
3262 "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
3263 strlcat(ecmp_xpath, "/ecmp", sizeof(ecmp_xpath));
3264
3265 nb_cli_enqueue_change(vty, ecmp_xpath, NB_OP_MODIFY, "true");
3266 return nb_cli_apply_changes(vty, NULL);
3267 }
3268
3269 DEFUN (no_ip_pim_ecmp,
3270 no_ip_pim_ecmp_cmd,
3271 "no ip pim ecmp",
3272 NO_STR
3273 IP_STR
3274 "pim multicast routing\n"
3275 "Disable PIM ECMP \n")
3276 {
3277 const char *vrfname;
3278 char ecmp_xpath[XPATH_MAXLEN];
3279
3280 vrfname = pim_cli_get_vrf_name(vty);
3281 if (vrfname == NULL)
3282 return CMD_WARNING_CONFIG_FAILED;
3283
3284 snprintf(ecmp_xpath, sizeof(ecmp_xpath), FRR_PIM_VRF_XPATH,
3285 "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
3286 strlcat(ecmp_xpath, "/ecmp", sizeof(ecmp_xpath));
3287
3288 nb_cli_enqueue_change(vty, ecmp_xpath, NB_OP_MODIFY, "false");
3289
3290 return nb_cli_apply_changes(vty, NULL);
3291 }
3292
3293 DEFUN (ip_pim_ecmp_rebalance,
3294 ip_pim_ecmp_rebalance_cmd,
3295 "ip pim ecmp rebalance",
3296 IP_STR
3297 "pim multicast routing\n"
3298 "Enable PIM ECMP \n"
3299 "Enable PIM ECMP Rebalance\n")
3300 {
3301 const char *vrfname;
3302 char ecmp_xpath[XPATH_MAXLEN];
3303 char ecmp_rebalance_xpath[XPATH_MAXLEN];
3304
3305 vrfname = pim_cli_get_vrf_name(vty);
3306 if (vrfname == NULL)
3307 return CMD_WARNING_CONFIG_FAILED;
3308
3309 snprintf(ecmp_xpath, sizeof(ecmp_xpath), FRR_PIM_VRF_XPATH,
3310 "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
3311 strlcat(ecmp_xpath, "/ecmp", sizeof(ecmp_xpath));
3312 snprintf(ecmp_rebalance_xpath, sizeof(ecmp_rebalance_xpath),
3313 FRR_PIM_VRF_XPATH,
3314 "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
3315 strlcat(ecmp_rebalance_xpath, "/ecmp-rebalance",
3316 sizeof(ecmp_rebalance_xpath));
3317
3318 nb_cli_enqueue_change(vty, ecmp_xpath, NB_OP_MODIFY, "true");
3319 nb_cli_enqueue_change(vty, ecmp_rebalance_xpath, NB_OP_MODIFY, "true");
3320
3321 return nb_cli_apply_changes(vty, NULL);
3322 }
3323
3324 DEFUN (no_ip_pim_ecmp_rebalance,
3325 no_ip_pim_ecmp_rebalance_cmd,
3326 "no ip pim ecmp rebalance",
3327 NO_STR
3328 IP_STR
3329 "pim multicast routing\n"
3330 "Disable PIM ECMP \n"
3331 "Disable PIM ECMP Rebalance\n")
3332 {
3333 const char *vrfname;
3334 char ecmp_rebalance_xpath[XPATH_MAXLEN];
3335
3336 vrfname = pim_cli_get_vrf_name(vty);
3337 if (vrfname == NULL)
3338 return CMD_WARNING_CONFIG_FAILED;
3339
3340 snprintf(ecmp_rebalance_xpath, sizeof(ecmp_rebalance_xpath),
3341 FRR_PIM_VRF_XPATH,
3342 "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
3343 strlcat(ecmp_rebalance_xpath, "/ecmp-rebalance",
3344 sizeof(ecmp_rebalance_xpath));
3345
3346 nb_cli_enqueue_change(vty, ecmp_rebalance_xpath, NB_OP_MODIFY, "false");
3347
3348 return nb_cli_apply_changes(vty, NULL);
3349 }
3350
3351 DEFUN (interface_ip_igmp,
3352 interface_ip_igmp_cmd,
3353 "ip igmp",
3354 IP_STR
3355 IFACE_IGMP_STR)
3356 {
3357 nb_cli_enqueue_change(vty, "./enable", NB_OP_MODIFY, "true");
3358
3359 return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
3360 "frr-routing:ipv4");
3361 }
3362
3363 DEFUN (interface_no_ip_igmp,
3364 interface_no_ip_igmp_cmd,
3365 "no ip igmp",
3366 NO_STR
3367 IP_STR
3368 IFACE_IGMP_STR)
3369 {
3370 const struct lyd_node *pim_enable_dnode;
3371 char pim_if_xpath[XPATH_MAXLEN];
3372
3373 int printed =
3374 snprintf(pim_if_xpath, sizeof(pim_if_xpath),
3375 "%s/frr-pim:pim/address-family[address-family='%s']",
3376 VTY_CURR_XPATH, "frr-routing:ipv4");
3377
3378 if (printed >= (int)(sizeof(pim_if_xpath))) {
3379 vty_out(vty, "Xpath too long (%d > %u)", printed + 1,
3380 XPATH_MAXLEN);
3381 return CMD_WARNING_CONFIG_FAILED;
3382 }
3383
3384 pim_enable_dnode = yang_dnode_getf(vty->candidate_config->dnode,
3385 FRR_PIM_ENABLE_XPATH, VTY_CURR_XPATH,
3386 "frr-routing:ipv4");
3387 if (!pim_enable_dnode) {
3388 nb_cli_enqueue_change(vty, pim_if_xpath, NB_OP_DESTROY, NULL);
3389 nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
3390 } else {
3391 if (!yang_dnode_get_bool(pim_enable_dnode, ".")) {
3392 nb_cli_enqueue_change(vty, pim_if_xpath, NB_OP_DESTROY,
3393 NULL);
3394 nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
3395 } else
3396 nb_cli_enqueue_change(vty, "./enable",
3397 NB_OP_MODIFY, "false");
3398 }
3399
3400 return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
3401 "frr-routing:ipv4");
3402 }
3403
3404 DEFUN (interface_ip_igmp_join,
3405 interface_ip_igmp_join_cmd,
3406 "ip igmp join A.B.C.D [A.B.C.D]",
3407 IP_STR
3408 IFACE_IGMP_STR
3409 "IGMP join multicast group\n"
3410 "Multicast group address\n"
3411 "Source address\n")
3412 {
3413 int idx_group = 3;
3414 int idx_source = 4;
3415 const char *source_str;
3416 char xpath[XPATH_MAXLEN];
3417
3418 if (argc == 5) {
3419 source_str = argv[idx_source]->arg;
3420
3421 if (strcmp(source_str, "0.0.0.0") == 0) {
3422 vty_out(vty, "Bad source address %s\n",
3423 argv[idx_source]->arg);
3424 return CMD_WARNING_CONFIG_FAILED;
3425 }
3426 } else
3427 source_str = "0.0.0.0";
3428
3429 snprintf(xpath, sizeof(xpath), FRR_GMP_JOIN_XPATH,
3430 "frr-routing:ipv4", argv[idx_group]->arg, source_str);
3431
3432 nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
3433
3434 return nb_cli_apply_changes(vty, NULL);
3435 }
3436
3437 DEFUN (interface_no_ip_igmp_join,
3438 interface_no_ip_igmp_join_cmd,
3439 "no ip igmp join A.B.C.D [A.B.C.D]",
3440 NO_STR
3441 IP_STR
3442 IFACE_IGMP_STR
3443 "IGMP join multicast group\n"
3444 "Multicast group address\n"
3445 "Source address\n")
3446 {
3447 int idx_group = 4;
3448 int idx_source = 5;
3449 const char *source_str;
3450 char xpath[XPATH_MAXLEN];
3451
3452 if (argc == 6) {
3453 source_str = argv[idx_source]->arg;
3454
3455 if (strcmp(source_str, "0.0.0.0") == 0) {
3456 vty_out(vty, "Bad source address %s\n",
3457 argv[idx_source]->arg);
3458 return CMD_WARNING_CONFIG_FAILED;
3459 }
3460 } else
3461 source_str = "0.0.0.0";
3462
3463 snprintf(xpath, sizeof(xpath), FRR_GMP_JOIN_XPATH,
3464 "frr-routing:ipv4", argv[idx_group]->arg, source_str);
3465
3466 nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
3467
3468 return nb_cli_apply_changes(vty, NULL);
3469 }
3470
3471 DEFUN (interface_ip_igmp_query_interval,
3472 interface_ip_igmp_query_interval_cmd,
3473 "ip igmp query-interval (1-65535)",
3474 IP_STR
3475 IFACE_IGMP_STR
3476 IFACE_IGMP_QUERY_INTERVAL_STR
3477 "Query interval in seconds\n")
3478 {
3479 const struct lyd_node *pim_enable_dnode;
3480
3481 pim_enable_dnode =
3482 yang_dnode_getf(vty->candidate_config->dnode,
3483 FRR_PIM_ENABLE_XPATH, VTY_CURR_XPATH,
3484 "frr-routing:ipv4");
3485 if (!pim_enable_dnode) {
3486 nb_cli_enqueue_change(vty, "./enable", NB_OP_MODIFY,
3487 "true");
3488 } else {
3489 if (!yang_dnode_get_bool(pim_enable_dnode, "."))
3490 nb_cli_enqueue_change(vty, "./enable",
3491 NB_OP_MODIFY, "true");
3492 }
3493
3494 nb_cli_enqueue_change(vty, "./query-interval", NB_OP_MODIFY,
3495 argv[3]->arg);
3496
3497 return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
3498 "frr-routing:ipv4");
3499 }
3500
3501 DEFUN (interface_no_ip_igmp_query_interval,
3502 interface_no_ip_igmp_query_interval_cmd,
3503 "no ip igmp query-interval [(1-65535)]",
3504 NO_STR
3505 IP_STR
3506 IFACE_IGMP_STR
3507 IFACE_IGMP_QUERY_INTERVAL_STR
3508 IGNORED_IN_NO_STR)
3509 {
3510 nb_cli_enqueue_change(vty, "./query-interval", NB_OP_DESTROY, NULL);
3511
3512 return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
3513 "frr-routing:ipv4");
3514 }
3515
3516 DEFUN (interface_ip_igmp_version,
3517 interface_ip_igmp_version_cmd,
3518 "ip igmp version (2-3)",
3519 IP_STR
3520 IFACE_IGMP_STR
3521 "IGMP version\n"
3522 "IGMP version number\n")
3523 {
3524 nb_cli_enqueue_change(vty, "./enable", NB_OP_MODIFY,
3525 "true");
3526 nb_cli_enqueue_change(vty, "./igmp-version", NB_OP_MODIFY,
3527 argv[3]->arg);
3528
3529 return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
3530 "frr-routing:ipv4");
3531 }
3532
3533 DEFUN (interface_no_ip_igmp_version,
3534 interface_no_ip_igmp_version_cmd,
3535 "no ip igmp version (2-3)",
3536 NO_STR
3537 IP_STR
3538 IFACE_IGMP_STR
3539 "IGMP version\n"
3540 "IGMP version number\n")
3541 {
3542 nb_cli_enqueue_change(vty, "./igmp-version", NB_OP_DESTROY, NULL);
3543
3544 return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
3545 "frr-routing:ipv4");
3546 }
3547
3548 DEFPY (interface_ip_igmp_query_max_response_time,
3549 interface_ip_igmp_query_max_response_time_cmd,
3550 "ip igmp query-max-response-time (1-65535)$qmrt",
3551 IP_STR
3552 IFACE_IGMP_STR
3553 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
3554 "Query response value in deci-seconds\n")
3555 {
3556 return gm_process_query_max_response_time_cmd(vty, qmrt_str);
3557 }
3558
3559 DEFUN (interface_no_ip_igmp_query_max_response_time,
3560 interface_no_ip_igmp_query_max_response_time_cmd,
3561 "no ip igmp query-max-response-time [(1-65535)]",
3562 NO_STR
3563 IP_STR
3564 IFACE_IGMP_STR
3565 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
3566 IGNORED_IN_NO_STR)
3567 {
3568 return gm_process_no_query_max_response_time_cmd(vty);
3569 }
3570
3571 DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec,
3572 interface_ip_igmp_query_max_response_time_dsec_cmd,
3573 "ip igmp query-max-response-time-dsec (1-65535)",
3574 IP_STR
3575 IFACE_IGMP_STR
3576 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
3577 "Query response value in deciseconds\n")
3578 {
3579 const struct lyd_node *pim_enable_dnode;
3580
3581 pim_enable_dnode =
3582 yang_dnode_getf(vty->candidate_config->dnode,
3583 FRR_PIM_ENABLE_XPATH, VTY_CURR_XPATH,
3584 "frr-routing:ipv4");
3585 if (!pim_enable_dnode) {
3586 nb_cli_enqueue_change(vty, "./enable", NB_OP_MODIFY,
3587 "true");
3588 } else {
3589 if (!yang_dnode_get_bool(pim_enable_dnode, "."))
3590 nb_cli_enqueue_change(vty, "./enable",
3591 NB_OP_MODIFY, "true");
3592 }
3593
3594 nb_cli_enqueue_change(vty, "./query-max-response-time", NB_OP_MODIFY,
3595 argv[3]->arg);
3596
3597 return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
3598 "frr-routing:ipv4");
3599 }
3600
3601 DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec,
3602 interface_no_ip_igmp_query_max_response_time_dsec_cmd,
3603 "no ip igmp query-max-response-time-dsec [(1-65535)]",
3604 NO_STR
3605 IP_STR
3606 IFACE_IGMP_STR
3607 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
3608 IGNORED_IN_NO_STR)
3609 {
3610 nb_cli_enqueue_change(vty, "./query-max-response-time", NB_OP_DESTROY,
3611 NULL);
3612
3613 return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
3614 "frr-routing:ipv4");
3615 }
3616
3617 DEFPY (interface_ip_igmp_last_member_query_count,
3618 interface_ip_igmp_last_member_query_count_cmd,
3619 "ip igmp last-member-query-count (1-255)$lmqc",
3620 IP_STR
3621 IFACE_IGMP_STR
3622 IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR
3623 "Last member query count\n")
3624 {
3625 return gm_process_last_member_query_count_cmd(vty, lmqc_str);
3626 }
3627
3628 DEFUN (interface_no_ip_igmp_last_member_query_count,
3629 interface_no_ip_igmp_last_member_query_count_cmd,
3630 "no ip igmp last-member-query-count [(1-255)]",
3631 NO_STR
3632 IP_STR
3633 IFACE_IGMP_STR
3634 IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR
3635 IGNORED_IN_NO_STR)
3636 {
3637 return gm_process_no_last_member_query_count_cmd(vty);
3638 }
3639
3640 DEFPY (interface_ip_igmp_last_member_query_interval,
3641 interface_ip_igmp_last_member_query_interval_cmd,
3642 "ip igmp last-member-query-interval (1-65535)$lmqi",
3643 IP_STR
3644 IFACE_IGMP_STR
3645 IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR
3646 "Last member query interval in deciseconds\n")
3647 {
3648 return gm_process_last_member_query_interval_cmd(vty, lmqi_str);
3649 }
3650
3651 DEFUN (interface_no_ip_igmp_last_member_query_interval,
3652 interface_no_ip_igmp_last_member_query_interval_cmd,
3653 "no ip igmp last-member-query-interval [(1-65535)]",
3654 NO_STR
3655 IP_STR
3656 IFACE_IGMP_STR
3657 IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR
3658 IGNORED_IN_NO_STR)
3659 {
3660 return gm_process_no_last_member_query_interval_cmd(vty);
3661 }
3662
3663 DEFUN (interface_ip_pim_drprio,
3664 interface_ip_pim_drprio_cmd,
3665 "ip pim drpriority (1-4294967295)",
3666 IP_STR
3667 PIM_STR
3668 "Set the Designated Router Election Priority\n"
3669 "Value of the new DR Priority\n")
3670 {
3671 int idx_number = 3;
3672
3673 return pim_process_ip_pim_drprio_cmd(vty, argv[idx_number]->arg);
3674 }
3675
3676 DEFUN (interface_no_ip_pim_drprio,
3677 interface_no_ip_pim_drprio_cmd,
3678 "no ip pim drpriority [(1-4294967295)]",
3679 NO_STR
3680 IP_STR
3681 PIM_STR
3682 "Revert the Designated Router Priority to default\n"
3683 "Old Value of the Priority\n")
3684 {
3685 return pim_process_no_ip_pim_drprio_cmd(vty);
3686 }
3687
3688 DEFPY_HIDDEN (interface_ip_igmp_query_generate,
3689 interface_ip_igmp_query_generate_cmd,
3690 "ip igmp generate-query-once [version (2-3)]",
3691 IP_STR
3692 IFACE_IGMP_STR
3693 "Generate igmp general query once\n"
3694 "IGMP version\n"
3695 "IGMP version number\n")
3696 {
3697 #if PIM_IPV == 4
3698 VTY_DECLVAR_CONTEXT(interface, ifp);
3699 int igmp_version;
3700 struct pim_interface *pim_ifp = ifp->info;
3701
3702 if (!ifp->info) {
3703 vty_out(vty, "IGMP/PIM is not enabled on the interface %s\n",
3704 ifp->name);
3705 return CMD_WARNING_CONFIG_FAILED;
3706 }
3707
3708 /* It takes the igmp version configured on the interface as default */
3709 igmp_version = pim_ifp->igmp_version;
3710
3711 if (argc > 3)
3712 igmp_version = atoi(argv[4]->arg);
3713
3714 igmp_send_query_on_intf(ifp, igmp_version);
3715 #endif
3716 return CMD_SUCCESS;
3717 }
3718
3719 DEFPY_HIDDEN (pim_test_sg_keepalive,
3720 pim_test_sg_keepalive_cmd,
3721 "test pim [vrf NAME$name] keepalive-reset A.B.C.D$source A.B.C.D$group",
3722 "Test code\n"
3723 PIM_STR
3724 VRF_CMD_HELP_STR
3725 "Reset the Keepalive Timer\n"
3726 "The Source we are resetting\n"
3727 "The Group we are resetting\n")
3728 {
3729 struct pim_upstream *up;
3730 struct vrf *vrf;
3731 struct pim_instance *pim;
3732 pim_sgaddr sg;
3733
3734 sg.src = source;
3735 sg.grp = group;
3736
3737 vrf = vrf_lookup_by_name(name ? name : VRF_DEFAULT_NAME);
3738 if (!vrf) {
3739 vty_out(vty, "%% Vrf specified: %s does not exist\n", name);
3740 return CMD_WARNING;
3741 }
3742
3743 pim = vrf->info;
3744
3745 if (!pim) {
3746 vty_out(vty, "%% Unable to find pim instance\n");
3747 return CMD_WARNING;
3748 }
3749
3750 up = pim_upstream_find(pim, &sg);
3751 if (!up) {
3752 vty_out(vty, "%% Unable to find %pSG specified\n", &sg);
3753 return CMD_WARNING;
3754 }
3755
3756 vty_out(vty, "Setting %pSG to current keep alive time: %d\n", &sg,
3757 pim->keep_alive_time);
3758 pim_upstream_keep_alive_timer_start(up, pim->keep_alive_time);
3759
3760 return CMD_SUCCESS;
3761 }
3762
3763 DEFPY (interface_ip_pim_activeactive,
3764 interface_ip_pim_activeactive_cmd,
3765 "[no$no] ip pim active-active",
3766 NO_STR
3767 IP_STR
3768 PIM_STR
3769 "Mark interface as Active-Active for MLAG operations, Hidden because not finished yet\n")
3770 {
3771 return pim_process_ip_pim_activeactive_cmd(vty, no);
3772 }
3773
3774 DEFUN_HIDDEN (interface_ip_pim_ssm,
3775 interface_ip_pim_ssm_cmd,
3776 "ip pim ssm",
3777 IP_STR
3778 PIM_STR
3779 IFACE_PIM_STR)
3780 {
3781 int ret;
3782
3783 ret = pim_process_ip_pim_cmd(vty);
3784
3785 if (ret != NB_OK)
3786 return ret;
3787
3788 vty_out(vty,
3789 "WARN: Enabled PIM SM on interface; configure PIM SSM range if needed\n");
3790
3791 return NB_OK;
3792 }
3793
3794 DEFUN_HIDDEN (interface_ip_pim_sm,
3795 interface_ip_pim_sm_cmd,
3796 "ip pim sm",
3797 IP_STR
3798 PIM_STR
3799 IFACE_PIM_SM_STR)
3800 {
3801 return pim_process_ip_pim_cmd(vty);
3802 }
3803
3804 DEFPY (interface_ip_pim,
3805 interface_ip_pim_cmd,
3806 "ip pim [passive$passive]",
3807 IP_STR
3808 PIM_STR
3809 "Disable exchange of protocol packets\n")
3810 {
3811 int ret;
3812
3813 ret = pim_process_ip_pim_cmd(vty);
3814
3815 if (ret != NB_OK)
3816 return ret;
3817
3818 if (passive)
3819 return pim_process_ip_pim_passive_cmd(vty, true);
3820
3821 return CMD_SUCCESS;
3822 }
3823
3824 DEFUN_HIDDEN (interface_no_ip_pim_ssm,
3825 interface_no_ip_pim_ssm_cmd,
3826 "no ip pim ssm",
3827 NO_STR
3828 IP_STR
3829 PIM_STR
3830 IFACE_PIM_STR)
3831 {
3832 return pim_process_no_ip_pim_cmd(vty);
3833 }
3834
3835 DEFUN_HIDDEN (interface_no_ip_pim_sm,
3836 interface_no_ip_pim_sm_cmd,
3837 "no ip pim sm",
3838 NO_STR
3839 IP_STR
3840 PIM_STR
3841 IFACE_PIM_SM_STR)
3842 {
3843 return pim_process_no_ip_pim_cmd(vty);
3844 }
3845
3846 DEFPY (interface_no_ip_pim,
3847 interface_no_ip_pim_cmd,
3848 "no ip pim [passive$passive]",
3849 NO_STR
3850 IP_STR
3851 PIM_STR
3852 "Disable exchange of protocol packets\n")
3853 {
3854 if (passive)
3855 return pim_process_ip_pim_passive_cmd(vty, false);
3856
3857 return pim_process_no_ip_pim_cmd(vty);
3858 }
3859
3860 /* boundaries */
3861 DEFUN(interface_ip_pim_boundary_oil,
3862 interface_ip_pim_boundary_oil_cmd,
3863 "ip multicast boundary oil WORD",
3864 IP_STR
3865 "Generic multicast configuration options\n"
3866 "Define multicast boundary\n"
3867 "Filter OIL by group using prefix list\n"
3868 "Prefix list to filter OIL with\n")
3869 {
3870 return pim_process_ip_pim_boundary_oil_cmd(vty, argv[4]->arg);
3871 }
3872
3873 DEFUN(interface_no_ip_pim_boundary_oil,
3874 interface_no_ip_pim_boundary_oil_cmd,
3875 "no ip multicast boundary oil [WORD]",
3876 NO_STR
3877 IP_STR
3878 "Generic multicast configuration options\n"
3879 "Define multicast boundary\n"
3880 "Filter OIL by group using prefix list\n"
3881 "Prefix list to filter OIL with\n")
3882 {
3883 return pim_process_no_ip_pim_boundary_oil_cmd(vty);
3884 }
3885
3886 DEFUN (interface_ip_mroute,
3887 interface_ip_mroute_cmd,
3888 "ip mroute INTERFACE A.B.C.D [A.B.C.D]",
3889 IP_STR
3890 "Add multicast route\n"
3891 "Outgoing interface name\n"
3892 "Group address\n"
3893 "Source address\n")
3894 {
3895 int idx_interface = 2;
3896 int idx_ipv4 = 3;
3897 const char *source_str;
3898
3899 if (argc == (idx_ipv4 + 1))
3900 source_str = "0.0.0.0";
3901 else
3902 source_str = argv[idx_ipv4 + 1]->arg;
3903
3904 return pim_process_ip_mroute_cmd(vty, argv[idx_interface]->arg,
3905 argv[idx_ipv4]->arg, source_str);
3906 }
3907
3908 DEFUN (interface_no_ip_mroute,
3909 interface_no_ip_mroute_cmd,
3910 "no ip mroute INTERFACE A.B.C.D [A.B.C.D]",
3911 NO_STR
3912 IP_STR
3913 "Add multicast route\n"
3914 "Outgoing interface name\n"
3915 "Group Address\n"
3916 "Source Address\n")
3917 {
3918 int idx_interface = 3;
3919 int idx_ipv4 = 4;
3920 const char *source_str;
3921
3922 if (argc == (idx_ipv4 + 1))
3923 source_str = "0.0.0.0";
3924 else
3925 source_str = argv[idx_ipv4 + 1]->arg;
3926
3927 return pim_process_no_ip_mroute_cmd(vty, argv[idx_interface]->arg,
3928 argv[idx_ipv4]->arg, source_str);
3929 }
3930
3931 DEFUN (interface_ip_pim_hello,
3932 interface_ip_pim_hello_cmd,
3933 "ip pim hello (1-65535) [(1-65535)]",
3934 IP_STR
3935 PIM_STR
3936 IFACE_PIM_HELLO_STR
3937 IFACE_PIM_HELLO_TIME_STR
3938 IFACE_PIM_HELLO_HOLD_STR)
3939 {
3940 int idx_time = 3;
3941 int idx_hold = 4;
3942
3943 if (argc == idx_hold + 1)
3944 return pim_process_ip_pim_hello_cmd(vty, argv[idx_time]->arg,
3945 argv[idx_hold]->arg);
3946
3947 else
3948 return pim_process_ip_pim_hello_cmd(vty, argv[idx_time]->arg,
3949 NULL);
3950 }
3951
3952 DEFUN (interface_no_ip_pim_hello,
3953 interface_no_ip_pim_hello_cmd,
3954 "no ip pim hello [(1-65535) [(1-65535)]]",
3955 NO_STR
3956 IP_STR
3957 PIM_STR
3958 IFACE_PIM_HELLO_STR
3959 IGNORED_IN_NO_STR
3960 IGNORED_IN_NO_STR)
3961 {
3962 return pim_process_no_ip_pim_hello_cmd(vty);
3963 }
3964
3965 DEFUN (debug_igmp,
3966 debug_igmp_cmd,
3967 "debug igmp",
3968 DEBUG_STR
3969 DEBUG_IGMP_STR)
3970 {
3971 PIM_DO_DEBUG_GM_EVENTS;
3972 PIM_DO_DEBUG_GM_PACKETS;
3973 PIM_DO_DEBUG_GM_TRACE;
3974 return CMD_SUCCESS;
3975 }
3976
3977 DEFUN (no_debug_igmp,
3978 no_debug_igmp_cmd,
3979 "no debug igmp",
3980 NO_STR
3981 DEBUG_STR
3982 DEBUG_IGMP_STR)
3983 {
3984 PIM_DONT_DEBUG_GM_EVENTS;
3985 PIM_DONT_DEBUG_GM_PACKETS;
3986 PIM_DONT_DEBUG_GM_TRACE;
3987 return CMD_SUCCESS;
3988 }
3989
3990
3991 DEFUN (debug_igmp_events,
3992 debug_igmp_events_cmd,
3993 "debug igmp events",
3994 DEBUG_STR
3995 DEBUG_IGMP_STR
3996 DEBUG_IGMP_EVENTS_STR)
3997 {
3998 PIM_DO_DEBUG_GM_EVENTS;
3999 return CMD_SUCCESS;
4000 }
4001
4002 DEFUN (no_debug_igmp_events,
4003 no_debug_igmp_events_cmd,
4004 "no debug igmp events",
4005 NO_STR
4006 DEBUG_STR
4007 DEBUG_IGMP_STR
4008 DEBUG_IGMP_EVENTS_STR)
4009 {
4010 PIM_DONT_DEBUG_GM_EVENTS;
4011 return CMD_SUCCESS;
4012 }
4013
4014
4015 DEFUN (debug_igmp_packets,
4016 debug_igmp_packets_cmd,
4017 "debug igmp packets",
4018 DEBUG_STR
4019 DEBUG_IGMP_STR
4020 DEBUG_IGMP_PACKETS_STR)
4021 {
4022 PIM_DO_DEBUG_GM_PACKETS;
4023 return CMD_SUCCESS;
4024 }
4025
4026 DEFUN (no_debug_igmp_packets,
4027 no_debug_igmp_packets_cmd,
4028 "no debug igmp packets",
4029 NO_STR
4030 DEBUG_STR
4031 DEBUG_IGMP_STR
4032 DEBUG_IGMP_PACKETS_STR)
4033 {
4034 PIM_DONT_DEBUG_GM_PACKETS;
4035 return CMD_SUCCESS;
4036 }
4037
4038
4039 DEFUN (debug_igmp_trace,
4040 debug_igmp_trace_cmd,
4041 "debug igmp trace",
4042 DEBUG_STR
4043 DEBUG_IGMP_STR
4044 DEBUG_IGMP_TRACE_STR)
4045 {
4046 PIM_DO_DEBUG_GM_TRACE;
4047 return CMD_SUCCESS;
4048 }
4049
4050 DEFUN (no_debug_igmp_trace,
4051 no_debug_igmp_trace_cmd,
4052 "no debug igmp trace",
4053 NO_STR
4054 DEBUG_STR
4055 DEBUG_IGMP_STR
4056 DEBUG_IGMP_TRACE_STR)
4057 {
4058 PIM_DONT_DEBUG_GM_TRACE;
4059 return CMD_SUCCESS;
4060 }
4061
4062
4063 DEFUN (debug_igmp_trace_detail,
4064 debug_igmp_trace_detail_cmd,
4065 "debug igmp trace detail",
4066 DEBUG_STR
4067 DEBUG_IGMP_STR
4068 DEBUG_IGMP_TRACE_STR
4069 "detailed\n")
4070 {
4071 PIM_DO_DEBUG_GM_TRACE_DETAIL;
4072 return CMD_SUCCESS;
4073 }
4074
4075 DEFUN (no_debug_igmp_trace_detail,
4076 no_debug_igmp_trace_detail_cmd,
4077 "no debug igmp trace detail",
4078 NO_STR
4079 DEBUG_STR
4080 DEBUG_IGMP_STR
4081 DEBUG_IGMP_TRACE_STR
4082 "detailed\n")
4083 {
4084 PIM_DONT_DEBUG_GM_TRACE_DETAIL;
4085 return CMD_SUCCESS;
4086 }
4087
4088
4089 DEFUN (debug_mroute,
4090 debug_mroute_cmd,
4091 "debug mroute",
4092 DEBUG_STR
4093 DEBUG_MROUTE_STR)
4094 {
4095 PIM_DO_DEBUG_MROUTE;
4096 return CMD_SUCCESS;
4097 }
4098
4099 DEFUN (debug_mroute_detail,
4100 debug_mroute_detail_cmd,
4101 "debug mroute detail",
4102 DEBUG_STR
4103 DEBUG_MROUTE_STR
4104 "detailed\n")
4105 {
4106 PIM_DO_DEBUG_MROUTE_DETAIL;
4107 return CMD_SUCCESS;
4108 }
4109
4110 DEFUN (no_debug_mroute,
4111 no_debug_mroute_cmd,
4112 "no debug mroute",
4113 NO_STR
4114 DEBUG_STR
4115 DEBUG_MROUTE_STR)
4116 {
4117 PIM_DONT_DEBUG_MROUTE;
4118 return CMD_SUCCESS;
4119 }
4120
4121 DEFUN (no_debug_mroute_detail,
4122 no_debug_mroute_detail_cmd,
4123 "no debug mroute detail",
4124 NO_STR
4125 DEBUG_STR
4126 DEBUG_MROUTE_STR
4127 "detailed\n")
4128 {
4129 PIM_DONT_DEBUG_MROUTE_DETAIL;
4130 return CMD_SUCCESS;
4131 }
4132
4133 DEFUN (debug_pim_static,
4134 debug_pim_static_cmd,
4135 "debug pim static",
4136 DEBUG_STR
4137 DEBUG_PIM_STR
4138 DEBUG_STATIC_STR)
4139 {
4140 PIM_DO_DEBUG_STATIC;
4141 return CMD_SUCCESS;
4142 }
4143
4144 DEFUN (no_debug_pim_static,
4145 no_debug_pim_static_cmd,
4146 "no debug pim static",
4147 NO_STR
4148 DEBUG_STR
4149 DEBUG_PIM_STR
4150 DEBUG_STATIC_STR)
4151 {
4152 PIM_DONT_DEBUG_STATIC;
4153 return CMD_SUCCESS;
4154 }
4155
4156
4157 DEFPY (debug_pim,
4158 debug_pim_cmd,
4159 "[no] debug pim",
4160 NO_STR
4161 DEBUG_STR
4162 DEBUG_PIM_STR)
4163 {
4164 if (!no)
4165 return pim_debug_pim_cmd();
4166 else
4167 return pim_no_debug_pim_cmd();
4168 }
4169
4170 DEFPY (debug_pim_nht,
4171 debug_pim_nht_cmd,
4172 "[no] debug pim nht",
4173 NO_STR
4174 DEBUG_STR
4175 DEBUG_PIM_STR
4176 "Nexthop Tracking\n")
4177 {
4178 if (!no)
4179 PIM_DO_DEBUG_PIM_NHT;
4180 else
4181 PIM_DONT_DEBUG_PIM_NHT;
4182 return CMD_SUCCESS;
4183 }
4184
4185 DEFPY (debug_pim_nht_det,
4186 debug_pim_nht_det_cmd,
4187 "[no] debug pim nht detail",
4188 NO_STR
4189 DEBUG_STR
4190 DEBUG_PIM_STR
4191 "Nexthop Tracking\n"
4192 "Detailed Information\n")
4193 {
4194 if (!no)
4195 PIM_DO_DEBUG_PIM_NHT_DETAIL;
4196 else
4197 PIM_DONT_DEBUG_PIM_NHT_DETAIL;
4198 return CMD_SUCCESS;
4199 }
4200
4201 DEFUN (debug_pim_nht_rp,
4202 debug_pim_nht_rp_cmd,
4203 "debug pim nht rp",
4204 DEBUG_STR
4205 DEBUG_PIM_STR
4206 "Nexthop Tracking\n"
4207 "RP Nexthop Tracking\n")
4208 {
4209 PIM_DO_DEBUG_PIM_NHT_RP;
4210 return CMD_SUCCESS;
4211 }
4212
4213 DEFUN (no_debug_pim_nht_rp,
4214 no_debug_pim_nht_rp_cmd,
4215 "no debug pim nht rp",
4216 NO_STR
4217 DEBUG_STR
4218 DEBUG_PIM_STR
4219 "Nexthop Tracking\n"
4220 "RP Nexthop Tracking\n")
4221 {
4222 PIM_DONT_DEBUG_PIM_NHT_RP;
4223 return CMD_SUCCESS;
4224 }
4225
4226 DEFPY (debug_pim_events,
4227 debug_pim_events_cmd,
4228 "[no] debug pim events",
4229 NO_STR
4230 DEBUG_STR
4231 DEBUG_PIM_STR
4232 DEBUG_PIM_EVENTS_STR)
4233 {
4234 if (!no)
4235 PIM_DO_DEBUG_PIM_EVENTS;
4236 else
4237 PIM_DONT_DEBUG_PIM_EVENTS;
4238 return CMD_SUCCESS;
4239 }
4240
4241 DEFPY (debug_pim_packets,
4242 debug_pim_packets_cmd,
4243 "[no] debug pim packets [<hello$hello|joins$joins|register$registers>]",
4244 NO_STR DEBUG_STR
4245 DEBUG_PIM_STR
4246 DEBUG_PIM_PACKETS_STR
4247 DEBUG_PIM_HELLO_PACKETS_STR
4248 DEBUG_PIM_J_P_PACKETS_STR
4249 DEBUG_PIM_PIM_REG_PACKETS_STR)
4250 {
4251 if (!no)
4252 return pim_debug_pim_packets_cmd(hello, joins, registers, vty);
4253 else
4254 return pim_no_debug_pim_packets_cmd(hello, joins, registers,
4255 vty);
4256 }
4257
4258 DEFPY (debug_pim_packetdump_send,
4259 debug_pim_packetdump_send_cmd,
4260 "[no] debug pim packet-dump send",
4261 NO_STR
4262 DEBUG_STR
4263 DEBUG_PIM_STR
4264 DEBUG_PIM_PACKETDUMP_STR
4265 DEBUG_PIM_PACKETDUMP_SEND_STR)
4266 {
4267 if (!no)
4268 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND;
4269 else
4270 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND;
4271 return CMD_SUCCESS;
4272 }
4273
4274 DEFPY (debug_pim_packetdump_recv,
4275 debug_pim_packetdump_recv_cmd,
4276 "[no] debug pim packet-dump receive",
4277 NO_STR
4278 DEBUG_STR
4279 DEBUG_PIM_STR
4280 DEBUG_PIM_PACKETDUMP_STR
4281 DEBUG_PIM_PACKETDUMP_RECV_STR)
4282 {
4283 if (!no)
4284 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV;
4285 else
4286 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV;
4287 return CMD_SUCCESS;
4288 }
4289
4290 DEFPY (debug_pim_trace,
4291 debug_pim_trace_cmd,
4292 "[no] debug pim trace",
4293 NO_STR
4294 DEBUG_STR
4295 DEBUG_PIM_STR
4296 DEBUG_PIM_TRACE_STR)
4297 {
4298 if (!no)
4299 PIM_DO_DEBUG_PIM_TRACE;
4300 else
4301 PIM_DONT_DEBUG_PIM_TRACE;
4302 return CMD_SUCCESS;
4303 }
4304
4305 DEFPY (debug_pim_trace_detail,
4306 debug_pim_trace_detail_cmd,
4307 "[no] debug pim trace detail",
4308 NO_STR
4309 DEBUG_STR
4310 DEBUG_PIM_STR
4311 DEBUG_PIM_TRACE_STR
4312 "Detailed Information\n")
4313 {
4314 if (!no)
4315 PIM_DO_DEBUG_PIM_TRACE_DETAIL;
4316 else
4317 PIM_DONT_DEBUG_PIM_TRACE_DETAIL;
4318 return CMD_SUCCESS;
4319 }
4320
4321 DEFUN (debug_ssmpingd,
4322 debug_ssmpingd_cmd,
4323 "debug ssmpingd",
4324 DEBUG_STR
4325 DEBUG_SSMPINGD_STR)
4326 {
4327 PIM_DO_DEBUG_SSMPINGD;
4328 return CMD_SUCCESS;
4329 }
4330
4331 DEFUN (no_debug_ssmpingd,
4332 no_debug_ssmpingd_cmd,
4333 "no debug ssmpingd",
4334 NO_STR
4335 DEBUG_STR
4336 DEBUG_SSMPINGD_STR)
4337 {
4338 PIM_DONT_DEBUG_SSMPINGD;
4339 return CMD_SUCCESS;
4340 }
4341
4342 DEFPY (debug_pim_zebra,
4343 debug_pim_zebra_cmd,
4344 "[no] debug pim zebra",
4345 NO_STR
4346 DEBUG_STR
4347 DEBUG_PIM_STR
4348 DEBUG_PIM_ZEBRA_STR)
4349 {
4350 if (!no)
4351 PIM_DO_DEBUG_ZEBRA;
4352 else
4353 PIM_DONT_DEBUG_ZEBRA;
4354 return CMD_SUCCESS;
4355 }
4356
4357 DEFUN(debug_pim_mlag, debug_pim_mlag_cmd, "debug pim mlag",
4358 DEBUG_STR DEBUG_PIM_STR DEBUG_PIM_MLAG_STR)
4359 {
4360 PIM_DO_DEBUG_MLAG;
4361 return CMD_SUCCESS;
4362 }
4363
4364 DEFUN(no_debug_pim_mlag, no_debug_pim_mlag_cmd, "no debug pim mlag",
4365 NO_STR DEBUG_STR DEBUG_PIM_STR DEBUG_PIM_MLAG_STR)
4366 {
4367 PIM_DONT_DEBUG_MLAG;
4368 return CMD_SUCCESS;
4369 }
4370
4371 DEFUN (debug_pim_vxlan,
4372 debug_pim_vxlan_cmd,
4373 "debug pim vxlan",
4374 DEBUG_STR
4375 DEBUG_PIM_STR
4376 DEBUG_PIM_VXLAN_STR)
4377 {
4378 PIM_DO_DEBUG_VXLAN;
4379 return CMD_SUCCESS;
4380 }
4381
4382 DEFUN (no_debug_pim_vxlan,
4383 no_debug_pim_vxlan_cmd,
4384 "no debug pim vxlan",
4385 NO_STR
4386 DEBUG_STR
4387 DEBUG_PIM_STR
4388 DEBUG_PIM_VXLAN_STR)
4389 {
4390 PIM_DONT_DEBUG_VXLAN;
4391 return CMD_SUCCESS;
4392 }
4393
4394 DEFUN (debug_msdp,
4395 debug_msdp_cmd,
4396 "debug msdp",
4397 DEBUG_STR
4398 DEBUG_MSDP_STR)
4399 {
4400 PIM_DO_DEBUG_MSDP_EVENTS;
4401 PIM_DO_DEBUG_MSDP_PACKETS;
4402 return CMD_SUCCESS;
4403 }
4404
4405 DEFUN (no_debug_msdp,
4406 no_debug_msdp_cmd,
4407 "no debug msdp",
4408 NO_STR
4409 DEBUG_STR
4410 DEBUG_MSDP_STR)
4411 {
4412 PIM_DONT_DEBUG_MSDP_EVENTS;
4413 PIM_DONT_DEBUG_MSDP_PACKETS;
4414 return CMD_SUCCESS;
4415 }
4416
4417 DEFUN (debug_msdp_events,
4418 debug_msdp_events_cmd,
4419 "debug msdp events",
4420 DEBUG_STR
4421 DEBUG_MSDP_STR
4422 DEBUG_MSDP_EVENTS_STR)
4423 {
4424 PIM_DO_DEBUG_MSDP_EVENTS;
4425 return CMD_SUCCESS;
4426 }
4427
4428 DEFUN (no_debug_msdp_events,
4429 no_debug_msdp_events_cmd,
4430 "no debug msdp events",
4431 NO_STR
4432 DEBUG_STR
4433 DEBUG_MSDP_STR
4434 DEBUG_MSDP_EVENTS_STR)
4435 {
4436 PIM_DONT_DEBUG_MSDP_EVENTS;
4437 return CMD_SUCCESS;
4438 }
4439
4440 DEFUN (debug_msdp_packets,
4441 debug_msdp_packets_cmd,
4442 "debug msdp packets",
4443 DEBUG_STR
4444 DEBUG_MSDP_STR
4445 DEBUG_MSDP_PACKETS_STR)
4446 {
4447 PIM_DO_DEBUG_MSDP_PACKETS;
4448 return CMD_SUCCESS;
4449 }
4450
4451 DEFUN (no_debug_msdp_packets,
4452 no_debug_msdp_packets_cmd,
4453 "no debug msdp packets",
4454 NO_STR
4455 DEBUG_STR
4456 DEBUG_MSDP_STR
4457 DEBUG_MSDP_PACKETS_STR)
4458 {
4459 PIM_DONT_DEBUG_MSDP_PACKETS;
4460 return CMD_SUCCESS;
4461 }
4462
4463 DEFUN (debug_mtrace,
4464 debug_mtrace_cmd,
4465 "debug mtrace",
4466 DEBUG_STR
4467 DEBUG_MTRACE_STR)
4468 {
4469 PIM_DO_DEBUG_MTRACE;
4470 return CMD_SUCCESS;
4471 }
4472
4473 DEFUN (no_debug_mtrace,
4474 no_debug_mtrace_cmd,
4475 "no debug mtrace",
4476 NO_STR
4477 DEBUG_STR
4478 DEBUG_MTRACE_STR)
4479 {
4480 PIM_DONT_DEBUG_MTRACE;
4481 return CMD_SUCCESS;
4482 }
4483
4484 DEFUN (debug_bsm,
4485 debug_bsm_cmd,
4486 "debug pim bsm",
4487 DEBUG_STR
4488 DEBUG_PIM_STR
4489 DEBUG_PIM_BSM_STR)
4490 {
4491 PIM_DO_DEBUG_BSM;
4492 return CMD_SUCCESS;
4493 }
4494
4495 DEFUN (no_debug_bsm,
4496 no_debug_bsm_cmd,
4497 "no debug pim bsm",
4498 NO_STR
4499 DEBUG_STR
4500 DEBUG_PIM_STR
4501 DEBUG_PIM_BSM_STR)
4502 {
4503 PIM_DONT_DEBUG_BSM;
4504 return CMD_SUCCESS;
4505 }
4506
4507
4508 DEFUN_NOSH (show_debugging_pim,
4509 show_debugging_pim_cmd,
4510 "show debugging [pim]",
4511 SHOW_STR
4512 DEBUG_STR
4513 PIM_STR)
4514 {
4515 vty_out(vty, "PIM debugging status\n");
4516
4517 pim_debug_config_write(vty);
4518
4519 cmd_show_lib_debugs(vty);
4520 return CMD_SUCCESS;
4521 }
4522
4523 DEFUN (interface_pim_use_source,
4524 interface_pim_use_source_cmd,
4525 "ip pim use-source A.B.C.D",
4526 IP_STR
4527 PIM_STR
4528 "Configure primary IP address\n"
4529 "source ip address\n")
4530 {
4531 nb_cli_enqueue_change(vty, "./use-source", NB_OP_MODIFY, argv[3]->arg);
4532
4533 return nb_cli_apply_changes(vty,
4534 FRR_PIM_INTERFACE_XPATH,
4535 "frr-routing:ipv4");
4536 }
4537
4538 DEFUN (interface_no_pim_use_source,
4539 interface_no_pim_use_source_cmd,
4540 "no ip pim use-source [A.B.C.D]",
4541 NO_STR
4542 IP_STR
4543 PIM_STR
4544 "Delete source IP address\n"
4545 "source ip address\n")
4546 {
4547 nb_cli_enqueue_change(vty, "./use-source", NB_OP_MODIFY, "0.0.0.0");
4548
4549 return nb_cli_apply_changes(vty,
4550 FRR_PIM_INTERFACE_XPATH,
4551 "frr-routing:ipv4");
4552 }
4553
4554 DEFPY (ip_pim_bfd,
4555 ip_pim_bfd_cmd,
4556 "ip pim bfd [profile BFDPROF$prof]",
4557 IP_STR
4558 PIM_STR
4559 "Enables BFD support\n"
4560 "Use BFD profile\n"
4561 "Use BFD profile name\n")
4562 {
4563 const struct lyd_node *igmp_enable_dnode;
4564
4565 igmp_enable_dnode =
4566 yang_dnode_getf(vty->candidate_config->dnode,
4567 FRR_GMP_ENABLE_XPATH, VTY_CURR_XPATH,
4568 "frr-routing:ipv4");
4569 if (!igmp_enable_dnode)
4570 nb_cli_enqueue_change(vty, "./pim-enable", NB_OP_MODIFY,
4571 "true");
4572 else {
4573 if (!yang_dnode_get_bool(igmp_enable_dnode, "."))
4574 nb_cli_enqueue_change(vty, "./pim-enable", NB_OP_MODIFY,
4575 "true");
4576 }
4577
4578 nb_cli_enqueue_change(vty, "./bfd", NB_OP_CREATE, NULL);
4579 if (prof)
4580 nb_cli_enqueue_change(vty, "./bfd/profile", NB_OP_MODIFY, prof);
4581
4582 return nb_cli_apply_changes(vty,
4583 FRR_PIM_INTERFACE_XPATH,
4584 "frr-routing:ipv4");
4585 }
4586
4587 DEFPY(no_ip_pim_bfd_profile, no_ip_pim_bfd_profile_cmd,
4588 "no ip pim bfd profile [BFDPROF]",
4589 NO_STR
4590 IP_STR
4591 PIM_STR
4592 "Enables BFD support\n"
4593 "Disable BFD profile\n"
4594 "BFD Profile name\n")
4595 {
4596 nb_cli_enqueue_change(vty, "./bfd/profile", NB_OP_DESTROY, NULL);
4597
4598 return nb_cli_apply_changes(vty,
4599 FRR_PIM_INTERFACE_XPATH,
4600 "frr-routing:ipv4");
4601 }
4602
4603 DEFUN (no_ip_pim_bfd,
4604 no_ip_pim_bfd_cmd,
4605 "no ip pim bfd",
4606 NO_STR
4607 IP_STR
4608 PIM_STR
4609 "Disables BFD support\n")
4610 {
4611 nb_cli_enqueue_change(vty, "./bfd", NB_OP_DESTROY, NULL);
4612
4613 return nb_cli_apply_changes(vty,
4614 FRR_PIM_INTERFACE_XPATH,
4615 "frr-routing:ipv4");
4616 }
4617
4618 DEFUN (ip_pim_bsm,
4619 ip_pim_bsm_cmd,
4620 "ip pim bsm",
4621 IP_STR
4622 PIM_STR
4623 "Enable BSM support on the interface\n")
4624 {
4625 return pim_process_bsm_cmd(vty);
4626 }
4627 DEFUN (no_ip_pim_bsm,
4628 no_ip_pim_bsm_cmd,
4629 "no ip pim bsm",
4630 NO_STR
4631 IP_STR
4632 PIM_STR
4633 "Enable BSM support on the interface\n")
4634 {
4635 return pim_process_no_bsm_cmd(vty);
4636 }
4637
4638 DEFUN (ip_pim_ucast_bsm,
4639 ip_pim_ucast_bsm_cmd,
4640 "ip pim unicast-bsm",
4641 IP_STR
4642 PIM_STR
4643 "Accept/Send unicast BSM on the interface\n")
4644 {
4645 return pim_process_unicast_bsm_cmd(vty);
4646 }
4647
4648 DEFUN (no_ip_pim_ucast_bsm,
4649 no_ip_pim_ucast_bsm_cmd,
4650 "no ip pim unicast-bsm",
4651 NO_STR
4652 IP_STR
4653 PIM_STR
4654 "Accept/Send unicast BSM on the interface\n")
4655 {
4656 return pim_process_no_unicast_bsm_cmd(vty);
4657 }
4658
4659 #if HAVE_BFDD > 0
4660 DEFUN_HIDDEN (
4661 ip_pim_bfd_param,
4662 ip_pim_bfd_param_cmd,
4663 "ip pim bfd (2-255) (1-65535) (1-65535)",
4664 IP_STR
4665 PIM_STR
4666 "Enables BFD support\n"
4667 "Detect Multiplier\n"
4668 "Required min receive interval\n"
4669 "Desired min transmit interval\n")
4670 #else
4671 DEFUN(
4672 ip_pim_bfd_param,
4673 ip_pim_bfd_param_cmd,
4674 "ip pim bfd (2-255) (1-65535) (1-65535)",
4675 IP_STR
4676 PIM_STR
4677 "Enables BFD support\n"
4678 "Detect Multiplier\n"
4679 "Required min receive interval\n"
4680 "Desired min transmit interval\n")
4681 #endif /* HAVE_BFDD */
4682 {
4683 int idx_number = 3;
4684 int idx_number_2 = 4;
4685 int idx_number_3 = 5;
4686 const struct lyd_node *igmp_enable_dnode;
4687
4688 igmp_enable_dnode =
4689 yang_dnode_getf(vty->candidate_config->dnode,
4690 FRR_GMP_ENABLE_XPATH, VTY_CURR_XPATH,
4691 "frr-routing:ipv4");
4692 if (!igmp_enable_dnode)
4693 nb_cli_enqueue_change(vty, "./pim-enable", NB_OP_MODIFY,
4694 "true");
4695 else {
4696 if (!yang_dnode_get_bool(igmp_enable_dnode, "."))
4697 nb_cli_enqueue_change(vty, "./pim-enable", NB_OP_MODIFY,
4698 "true");
4699 }
4700
4701 nb_cli_enqueue_change(vty, "./bfd", NB_OP_CREATE, NULL);
4702 nb_cli_enqueue_change(vty, "./bfd/min-rx-interval", NB_OP_MODIFY,
4703 argv[idx_number_2]->arg);
4704 nb_cli_enqueue_change(vty, "./bfd/min-tx-interval", NB_OP_MODIFY,
4705 argv[idx_number_3]->arg);
4706 nb_cli_enqueue_change(vty, "./bfd/detect_mult", NB_OP_MODIFY,
4707 argv[idx_number]->arg);
4708
4709 return nb_cli_apply_changes(vty,
4710 FRR_PIM_INTERFACE_XPATH, "frr-routing:ipv4");
4711 }
4712
4713 #if HAVE_BFDD == 0
4714 ALIAS(no_ip_pim_bfd, no_ip_pim_bfd_param_cmd,
4715 "no ip pim bfd (2-255) (1-65535) (1-65535)",
4716 NO_STR
4717 IP_STR
4718 PIM_STR
4719 "Enables BFD support\n"
4720 "Detect Multiplier\n"
4721 "Required min receive interval\n"
4722 "Desired min transmit interval\n")
4723 #endif /* !HAVE_BFDD */
4724
4725 DEFPY(ip_msdp_peer, ip_msdp_peer_cmd,
4726 "ip msdp peer A.B.C.D$peer source A.B.C.D$source",
4727 IP_STR
4728 CFG_MSDP_STR
4729 "Configure MSDP peer\n"
4730 "Peer IP address\n"
4731 "Source address for TCP connection\n"
4732 "Local IP address\n")
4733 {
4734 const char *vrfname;
4735 char temp_xpath[XPATH_MAXLEN];
4736 char msdp_peer_source_xpath[XPATH_MAXLEN];
4737
4738 vrfname = pim_cli_get_vrf_name(vty);
4739 if (vrfname == NULL)
4740 return CMD_WARNING_CONFIG_FAILED;
4741
4742 snprintf(msdp_peer_source_xpath, sizeof(msdp_peer_source_xpath),
4743 FRR_PIM_VRF_XPATH, "frr-pim:pimd", "pim", vrfname,
4744 "frr-routing:ipv4");
4745 snprintf(temp_xpath, sizeof(temp_xpath),
4746 "/msdp-peer[peer-ip='%s']/source-ip", peer_str);
4747 strlcat(msdp_peer_source_xpath, temp_xpath,
4748 sizeof(msdp_peer_source_xpath));
4749
4750 nb_cli_enqueue_change(vty, msdp_peer_source_xpath, NB_OP_MODIFY,
4751 source_str);
4752
4753 return nb_cli_apply_changes(vty,
4754 FRR_PIM_INTERFACE_XPATH, "frr-routing:ipv4");
4755 }
4756
4757 DEFPY(ip_msdp_timers, ip_msdp_timers_cmd,
4758 "ip msdp timers (1-65535)$keepalive (1-65535)$holdtime [(1-65535)$connretry]",
4759 IP_STR
4760 CFG_MSDP_STR
4761 "MSDP timers configuration\n"
4762 "Keep alive period (in seconds)\n"
4763 "Hold time period (in seconds)\n"
4764 "Connection retry period (in seconds)\n")
4765 {
4766 const char *vrfname;
4767
4768 vrfname = pim_cli_get_vrf_name(vty);
4769 if (vrfname == NULL)
4770 return CMD_WARNING_CONFIG_FAILED;
4771
4772 nb_cli_enqueue_change(vty, "./hold-time", NB_OP_MODIFY, holdtime_str);
4773 nb_cli_enqueue_change(vty, "./keep-alive", NB_OP_MODIFY, keepalive_str);
4774 if (connretry_str)
4775 nb_cli_enqueue_change(vty, "./connection-retry", NB_OP_MODIFY,
4776 connretry_str);
4777 else
4778 nb_cli_enqueue_change(vty, "./connection-retry", NB_OP_DESTROY,
4779 NULL);
4780
4781 nb_cli_apply_changes(vty, FRR_PIM_MSDP_XPATH, "frr-pim:pimd", "pim",
4782 vrfname, "frr-routing:ipv4");
4783 return CMD_SUCCESS;
4784 }
4785
4786 DEFPY(no_ip_msdp_timers, no_ip_msdp_timers_cmd,
4787 "no ip msdp timers [(1-65535) (1-65535) [(1-65535)]]",
4788 NO_STR
4789 IP_STR
4790 CFG_MSDP_STR
4791 "MSDP timers configuration\n"
4792 IGNORED_IN_NO_STR
4793 IGNORED_IN_NO_STR
4794 IGNORED_IN_NO_STR)
4795 {
4796 const char *vrfname;
4797
4798 vrfname = pim_cli_get_vrf_name(vty);
4799 if (vrfname == NULL)
4800 return CMD_WARNING_CONFIG_FAILED;
4801
4802 nb_cli_enqueue_change(vty, "./hold-time", NB_OP_DESTROY, NULL);
4803 nb_cli_enqueue_change(vty, "./keep-alive", NB_OP_DESTROY, NULL);
4804 nb_cli_enqueue_change(vty, "./connection-retry", NB_OP_DESTROY, NULL);
4805
4806 nb_cli_apply_changes(vty, FRR_PIM_MSDP_XPATH, "frr-pim:pimd", "pim",
4807 vrfname, "frr-routing:ipv4");
4808
4809 return CMD_SUCCESS;
4810 }
4811
4812 DEFUN (no_ip_msdp_peer,
4813 no_ip_msdp_peer_cmd,
4814 "no ip msdp peer A.B.C.D",
4815 NO_STR
4816 IP_STR
4817 CFG_MSDP_STR
4818 "Delete MSDP peer\n"
4819 "peer ip address\n")
4820 {
4821 const char *vrfname;
4822 char msdp_peer_xpath[XPATH_MAXLEN];
4823 char temp_xpath[XPATH_MAXLEN];
4824
4825 vrfname = pim_cli_get_vrf_name(vty);
4826 if (vrfname == NULL)
4827 return CMD_WARNING_CONFIG_FAILED;
4828
4829 snprintf(msdp_peer_xpath, sizeof(msdp_peer_xpath),
4830 FRR_PIM_VRF_XPATH,
4831 "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
4832 snprintf(temp_xpath, sizeof(temp_xpath),
4833 "/msdp-peer[peer-ip='%s']",
4834 argv[4]->arg);
4835
4836 strlcat(msdp_peer_xpath, temp_xpath, sizeof(msdp_peer_xpath));
4837
4838 nb_cli_enqueue_change(vty, msdp_peer_xpath, NB_OP_DESTROY, NULL);
4839
4840 return nb_cli_apply_changes(vty, NULL);
4841 }
4842
4843 DEFPY(ip_msdp_mesh_group_member,
4844 ip_msdp_mesh_group_member_cmd,
4845 "ip msdp mesh-group WORD$gname member A.B.C.D$maddr",
4846 IP_STR
4847 CFG_MSDP_STR
4848 "Configure MSDP mesh-group\n"
4849 "Mesh group name\n"
4850 "Mesh group member\n"
4851 "Peer IP address\n")
4852 {
4853 const char *vrfname;
4854 char xpath_value[XPATH_MAXLEN];
4855
4856 vrfname = pim_cli_get_vrf_name(vty);
4857 if (vrfname == NULL)
4858 return CMD_WARNING_CONFIG_FAILED;
4859
4860 /* Create mesh group. */
4861 snprintf(xpath_value, sizeof(xpath_value),
4862 FRR_PIM_VRF_XPATH "/msdp-mesh-groups[name='%s']",
4863 "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4", gname);
4864 nb_cli_enqueue_change(vty, xpath_value, NB_OP_CREATE, NULL);
4865
4866 /* Create mesh group member. */
4867 strlcat(xpath_value, "/members[address='", sizeof(xpath_value));
4868 strlcat(xpath_value, maddr_str, sizeof(xpath_value));
4869 strlcat(xpath_value, "']", sizeof(xpath_value));
4870 nb_cli_enqueue_change(vty, xpath_value, NB_OP_CREATE, NULL);
4871
4872 return nb_cli_apply_changes(vty, NULL);
4873 }
4874
4875 DEFPY(no_ip_msdp_mesh_group_member,
4876 no_ip_msdp_mesh_group_member_cmd,
4877 "no ip msdp mesh-group WORD$gname member A.B.C.D$maddr",
4878 NO_STR
4879 IP_STR
4880 CFG_MSDP_STR
4881 "Delete MSDP mesh-group member\n"
4882 "Mesh group name\n"
4883 "Mesh group member\n"
4884 "Peer IP address\n")
4885 {
4886 const char *vrfname;
4887 char xpath_value[XPATH_MAXLEN];
4888 char xpath_member_value[XPATH_MAXLEN];
4889
4890 vrfname = pim_cli_get_vrf_name(vty);
4891 if (vrfname == NULL)
4892 return CMD_WARNING_CONFIG_FAILED;
4893
4894 /* Get mesh group base XPath. */
4895 snprintf(xpath_value, sizeof(xpath_value),
4896 FRR_PIM_VRF_XPATH "/msdp-mesh-groups[name='%s']",
4897 "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4", gname);
4898
4899 if (!yang_dnode_exists(vty->candidate_config->dnode, xpath_value)) {
4900 vty_out(vty, "%% mesh-group does not exist\n");
4901 return CMD_WARNING_CONFIG_FAILED;
4902 }
4903
4904 /* Remove mesh group member. */
4905 strlcpy(xpath_member_value, xpath_value, sizeof(xpath_member_value));
4906 strlcat(xpath_member_value, "/members[address='",
4907 sizeof(xpath_member_value));
4908 strlcat(xpath_member_value, maddr_str, sizeof(xpath_member_value));
4909 strlcat(xpath_member_value, "']", sizeof(xpath_member_value));
4910 if (!yang_dnode_exists(vty->candidate_config->dnode,
4911 xpath_member_value)) {
4912 vty_out(vty, "%% mesh-group member does not exist\n");
4913 return CMD_WARNING_CONFIG_FAILED;
4914 }
4915
4916 nb_cli_enqueue_change(vty, xpath_member_value, NB_OP_DESTROY, NULL);
4917
4918 /*
4919 * If this is the last member, then we must remove the group altogether
4920 * to not break legacy CLI behaviour.
4921 */
4922 pim_cli_legacy_mesh_group_behavior(vty, gname);
4923
4924 return nb_cli_apply_changes(vty, NULL);
4925 }
4926
4927 DEFPY(ip_msdp_mesh_group_source,
4928 ip_msdp_mesh_group_source_cmd,
4929 "ip msdp mesh-group WORD$gname source A.B.C.D$saddr",
4930 IP_STR
4931 CFG_MSDP_STR
4932 "Configure MSDP mesh-group\n"
4933 "Mesh group name\n"
4934 "Mesh group local address\n"
4935 "Source IP address for the TCP connection\n")
4936 {
4937 const char *vrfname;
4938 char xpath_value[XPATH_MAXLEN];
4939
4940 vrfname = pim_cli_get_vrf_name(vty);
4941 if (vrfname == NULL)
4942 return CMD_WARNING_CONFIG_FAILED;
4943
4944 /* Create mesh group. */
4945 snprintf(xpath_value, sizeof(xpath_value),
4946 FRR_PIM_VRF_XPATH "/msdp-mesh-groups[name='%s']",
4947 "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4", gname);
4948 nb_cli_enqueue_change(vty, xpath_value, NB_OP_CREATE, NULL);
4949
4950 /* Create mesh group source. */
4951 strlcat(xpath_value, "/source", sizeof(xpath_value));
4952 nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, saddr_str);
4953
4954 return nb_cli_apply_changes(vty, NULL);
4955 }
4956
4957 DEFPY(no_ip_msdp_mesh_group_source,
4958 no_ip_msdp_mesh_group_source_cmd,
4959 "no ip msdp mesh-group WORD$gname source [A.B.C.D]",
4960 NO_STR
4961 IP_STR
4962 CFG_MSDP_STR
4963 "Delete MSDP mesh-group source\n"
4964 "Mesh group name\n"
4965 "Mesh group source\n"
4966 "Mesh group local address\n")
4967 {
4968 const char *vrfname;
4969 char xpath_value[XPATH_MAXLEN];
4970
4971 vrfname = pim_cli_get_vrf_name(vty);
4972 if (vrfname == NULL)
4973 return CMD_WARNING_CONFIG_FAILED;
4974
4975 /* Get mesh group base XPath. */
4976 snprintf(xpath_value, sizeof(xpath_value),
4977 FRR_PIM_VRF_XPATH "/msdp-mesh-groups[name='%s']",
4978 "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4", gname);
4979 nb_cli_enqueue_change(vty, xpath_value, NB_OP_CREATE, NULL);
4980
4981 /* Create mesh group source. */
4982 strlcat(xpath_value, "/source", sizeof(xpath_value));
4983 nb_cli_enqueue_change(vty, xpath_value, NB_OP_DESTROY, NULL);
4984
4985 /*
4986 * If this is the last member, then we must remove the group altogether
4987 * to not break legacy CLI behaviour.
4988 */
4989 pim_cli_legacy_mesh_group_behavior(vty, gname);
4990
4991 return nb_cli_apply_changes(vty, NULL);
4992 }
4993
4994 DEFPY(no_ip_msdp_mesh_group,
4995 no_ip_msdp_mesh_group_cmd,
4996 "no ip msdp mesh-group WORD$gname",
4997 NO_STR
4998 IP_STR
4999 CFG_MSDP_STR
5000 "Delete MSDP mesh-group\n"
5001 "Mesh group name\n")
5002 {
5003 const char *vrfname;
5004 char xpath_value[XPATH_MAXLEN];
5005
5006 vrfname = pim_cli_get_vrf_name(vty);
5007 if (vrfname == NULL)
5008 return CMD_WARNING_CONFIG_FAILED;
5009
5010 /* Get mesh group base XPath. */
5011 snprintf(xpath_value, sizeof(xpath_value),
5012 FRR_PIM_VRF_XPATH "/msdp-mesh-groups[name='%s']",
5013 "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4", gname);
5014 if (!yang_dnode_exists(vty->candidate_config->dnode, xpath_value))
5015 return CMD_SUCCESS;
5016
5017 nb_cli_enqueue_change(vty, xpath_value, NB_OP_DESTROY, NULL);
5018 return nb_cli_apply_changes(vty, NULL);
5019 }
5020
5021 static void ip_msdp_show_mesh_group(struct vty *vty, struct pim_msdp_mg *mg,
5022 struct json_object *json)
5023 {
5024 struct listnode *mbrnode;
5025 struct pim_msdp_mg_mbr *mbr;
5026 char mbr_str[INET_ADDRSTRLEN];
5027 char src_str[INET_ADDRSTRLEN];
5028 char state_str[PIM_MSDP_STATE_STRLEN];
5029 enum pim_msdp_peer_state state;
5030 json_object *json_mg_row = NULL;
5031 json_object *json_members = NULL;
5032 json_object *json_row = NULL;
5033
5034 pim_inet4_dump("<source?>", mg->src_ip, src_str, sizeof(src_str));
5035 if (json) {
5036 /* currently there is only one mesh group but we should still
5037 * make
5038 * it a dict with mg-name as key */
5039 json_mg_row = json_object_new_object();
5040 json_object_string_add(json_mg_row, "name",
5041 mg->mesh_group_name);
5042 json_object_string_add(json_mg_row, "source", src_str);
5043 } else {
5044 vty_out(vty, "Mesh group : %s\n", mg->mesh_group_name);
5045 vty_out(vty, " Source : %s\n", src_str);
5046 vty_out(vty, " Member State\n");
5047 }
5048
5049 for (ALL_LIST_ELEMENTS_RO(mg->mbr_list, mbrnode, mbr)) {
5050 pim_inet4_dump("<mbr?>", mbr->mbr_ip, mbr_str, sizeof(mbr_str));
5051 if (mbr->mp) {
5052 state = mbr->mp->state;
5053 } else {
5054 state = PIM_MSDP_DISABLED;
5055 }
5056 pim_msdp_state_dump(state, state_str, sizeof(state_str));
5057 if (json) {
5058 json_row = json_object_new_object();
5059 json_object_string_add(json_row, "member", mbr_str);
5060 json_object_string_add(json_row, "state", state_str);
5061 if (!json_members) {
5062 json_members = json_object_new_object();
5063 json_object_object_add(json_mg_row, "members",
5064 json_members);
5065 }
5066 json_object_object_add(json_members, mbr_str, json_row);
5067 } else {
5068 vty_out(vty, " %-15s %11s\n", mbr_str, state_str);
5069 }
5070 }
5071
5072 if (json)
5073 json_object_object_add(json, mg->mesh_group_name, json_mg_row);
5074 }
5075
5076 DEFUN (show_ip_msdp_mesh_group,
5077 show_ip_msdp_mesh_group_cmd,
5078 "show ip msdp [vrf NAME] mesh-group [json]",
5079 SHOW_STR
5080 IP_STR
5081 MSDP_STR
5082 VRF_CMD_HELP_STR
5083 "MSDP mesh-group information\n"
5084 JSON_STR)
5085 {
5086 bool uj = use_json(argc, argv);
5087 int idx = 2;
5088 struct pim_msdp_mg *mg;
5089 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
5090 struct pim_instance *pim;
5091 struct json_object *json = NULL;
5092
5093 if (!vrf)
5094 return CMD_WARNING;
5095
5096 pim = vrf->info;
5097 /* Quick case: list is empty. */
5098 if (SLIST_EMPTY(&pim->msdp.mglist)) {
5099 if (uj)
5100 vty_out(vty, "{}\n");
5101
5102 return CMD_SUCCESS;
5103 }
5104
5105 if (uj)
5106 json = json_object_new_object();
5107
5108 SLIST_FOREACH (mg, &pim->msdp.mglist, mg_entry)
5109 ip_msdp_show_mesh_group(vty, mg, json);
5110
5111 if (uj)
5112 vty_json(vty, json);
5113
5114 return CMD_SUCCESS;
5115 }
5116
5117 DEFUN (show_ip_msdp_mesh_group_vrf_all,
5118 show_ip_msdp_mesh_group_vrf_all_cmd,
5119 "show ip msdp vrf all mesh-group [json]",
5120 SHOW_STR
5121 IP_STR
5122 MSDP_STR
5123 VRF_CMD_HELP_STR
5124 "MSDP mesh-group information\n"
5125 JSON_STR)
5126 {
5127 bool uj = use_json(argc, argv);
5128 struct json_object *json = NULL, *vrf_json = NULL;
5129 struct pim_instance *pim;
5130 struct pim_msdp_mg *mg;
5131 struct vrf *vrf;
5132
5133 if (uj)
5134 json = json_object_new_object();
5135
5136 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
5137 if (uj) {
5138 vrf_json = json_object_new_object();
5139 json_object_object_add(json, vrf->name, vrf_json);
5140 } else
5141 vty_out(vty, "VRF: %s\n", vrf->name);
5142
5143 pim = vrf->info;
5144 SLIST_FOREACH (mg, &pim->msdp.mglist, mg_entry)
5145 ip_msdp_show_mesh_group(vty, mg, vrf_json);
5146 }
5147
5148 if (uj)
5149 vty_json(vty, json);
5150
5151
5152 return CMD_SUCCESS;
5153 }
5154
5155 static void ip_msdp_show_peers(struct pim_instance *pim, struct vty *vty,
5156 bool uj)
5157 {
5158 struct listnode *mpnode;
5159 struct pim_msdp_peer *mp;
5160 char peer_str[INET_ADDRSTRLEN];
5161 char local_str[INET_ADDRSTRLEN];
5162 char state_str[PIM_MSDP_STATE_STRLEN];
5163 char timebuf[PIM_MSDP_UPTIME_STRLEN];
5164 int64_t now;
5165 json_object *json = NULL;
5166 json_object *json_row = NULL;
5167
5168
5169 if (uj) {
5170 json = json_object_new_object();
5171 } else {
5172 vty_out(vty,
5173 "Peer Local State Uptime SaCnt\n");
5174 }
5175
5176 for (ALL_LIST_ELEMENTS_RO(pim->msdp.peer_list, mpnode, mp)) {
5177 if (mp->state == PIM_MSDP_ESTABLISHED) {
5178 now = pim_time_monotonic_sec();
5179 pim_time_uptime(timebuf, sizeof(timebuf),
5180 now - mp->uptime);
5181 } else {
5182 strlcpy(timebuf, "-", sizeof(timebuf));
5183 }
5184 pim_inet4_dump("<peer?>", mp->peer, peer_str, sizeof(peer_str));
5185 pim_inet4_dump("<local?>", mp->local, local_str,
5186 sizeof(local_str));
5187 pim_msdp_state_dump(mp->state, state_str, sizeof(state_str));
5188 if (uj) {
5189 json_row = json_object_new_object();
5190 json_object_string_add(json_row, "peer", peer_str);
5191 json_object_string_add(json_row, "local", local_str);
5192 json_object_string_add(json_row, "state", state_str);
5193 json_object_string_add(json_row, "upTime", timebuf);
5194 json_object_int_add(json_row, "saCount", mp->sa_cnt);
5195 json_object_object_add(json, peer_str, json_row);
5196 } else {
5197 vty_out(vty, "%-15s %15s %11s %8s %6d\n", peer_str,
5198 local_str, state_str, timebuf, mp->sa_cnt);
5199 }
5200 }
5201
5202 if (uj)
5203 vty_json(vty, json);
5204 }
5205
5206 static void ip_msdp_show_peers_detail(struct pim_instance *pim, struct vty *vty,
5207 const char *peer, bool uj)
5208 {
5209 struct listnode *mpnode;
5210 struct pim_msdp_peer *mp;
5211 char peer_str[INET_ADDRSTRLEN];
5212 char local_str[INET_ADDRSTRLEN];
5213 char state_str[PIM_MSDP_STATE_STRLEN];
5214 char timebuf[PIM_MSDP_UPTIME_STRLEN];
5215 char katimer[PIM_MSDP_TIMER_STRLEN];
5216 char crtimer[PIM_MSDP_TIMER_STRLEN];
5217 char holdtimer[PIM_MSDP_TIMER_STRLEN];
5218 int64_t now;
5219 json_object *json = NULL;
5220 json_object *json_row = NULL;
5221
5222 if (uj) {
5223 json = json_object_new_object();
5224 }
5225
5226 for (ALL_LIST_ELEMENTS_RO(pim->msdp.peer_list, mpnode, mp)) {
5227 pim_inet4_dump("<peer?>", mp->peer, peer_str, sizeof(peer_str));
5228 if (strcmp(peer, "detail") && strcmp(peer, peer_str))
5229 continue;
5230
5231 if (mp->state == PIM_MSDP_ESTABLISHED) {
5232 now = pim_time_monotonic_sec();
5233 pim_time_uptime(timebuf, sizeof(timebuf),
5234 now - mp->uptime);
5235 } else {
5236 strlcpy(timebuf, "-", sizeof(timebuf));
5237 }
5238 pim_inet4_dump("<local?>", mp->local, local_str,
5239 sizeof(local_str));
5240 pim_msdp_state_dump(mp->state, state_str, sizeof(state_str));
5241 pim_time_timer_to_hhmmss(katimer, sizeof(katimer),
5242 mp->ka_timer);
5243 pim_time_timer_to_hhmmss(crtimer, sizeof(crtimer),
5244 mp->cr_timer);
5245 pim_time_timer_to_hhmmss(holdtimer, sizeof(holdtimer),
5246 mp->hold_timer);
5247
5248 if (uj) {
5249 json_row = json_object_new_object();
5250 json_object_string_add(json_row, "peer", peer_str);
5251 json_object_string_add(json_row, "local", local_str);
5252 if (mp->flags & PIM_MSDP_PEERF_IN_GROUP)
5253 json_object_string_add(json_row,
5254 "meshGroupName",
5255 mp->mesh_group_name);
5256 json_object_string_add(json_row, "state", state_str);
5257 json_object_string_add(json_row, "upTime", timebuf);
5258 json_object_string_add(json_row, "keepAliveTimer",
5259 katimer);
5260 json_object_string_add(json_row, "connRetryTimer",
5261 crtimer);
5262 json_object_string_add(json_row, "holdTimer",
5263 holdtimer);
5264 json_object_string_add(json_row, "lastReset",
5265 mp->last_reset);
5266 json_object_int_add(json_row, "connAttempts",
5267 mp->conn_attempts);
5268 json_object_int_add(json_row, "establishedChanges",
5269 mp->est_flaps);
5270 json_object_int_add(json_row, "saCount", mp->sa_cnt);
5271 json_object_int_add(json_row, "kaSent", mp->ka_tx_cnt);
5272 json_object_int_add(json_row, "kaRcvd", mp->ka_rx_cnt);
5273 json_object_int_add(json_row, "saSent", mp->sa_tx_cnt);
5274 json_object_int_add(json_row, "saRcvd", mp->sa_rx_cnt);
5275 json_object_object_add(json, peer_str, json_row);
5276 } else {
5277 vty_out(vty, "Peer : %s\n", peer_str);
5278 vty_out(vty, " Local : %s\n", local_str);
5279 if (mp->flags & PIM_MSDP_PEERF_IN_GROUP)
5280 vty_out(vty, " Mesh Group : %s\n",
5281 mp->mesh_group_name);
5282 vty_out(vty, " State : %s\n", state_str);
5283 vty_out(vty, " Uptime : %s\n", timebuf);
5284
5285 vty_out(vty, " Keepalive Timer : %s\n", katimer);
5286 vty_out(vty, " Conn Retry Timer : %s\n", crtimer);
5287 vty_out(vty, " Hold Timer : %s\n", holdtimer);
5288 vty_out(vty, " Last Reset : %s\n",
5289 mp->last_reset);
5290 vty_out(vty, " Conn Attempts : %d\n",
5291 mp->conn_attempts);
5292 vty_out(vty, " Established Changes : %d\n",
5293 mp->est_flaps);
5294 vty_out(vty, " SA Count : %d\n",
5295 mp->sa_cnt);
5296 vty_out(vty, " Statistics :\n");
5297 vty_out(vty,
5298 " Sent Rcvd\n");
5299 vty_out(vty, " Keepalives : %10d %10d\n",
5300 mp->ka_tx_cnt, mp->ka_rx_cnt);
5301 vty_out(vty, " SAs : %10d %10d\n",
5302 mp->sa_tx_cnt, mp->sa_rx_cnt);
5303 vty_out(vty, "\n");
5304 }
5305 }
5306
5307 if (uj)
5308 vty_json(vty, json);
5309 }
5310
5311 DEFUN (show_ip_msdp_peer_detail,
5312 show_ip_msdp_peer_detail_cmd,
5313 "show ip msdp [vrf NAME] peer [detail|A.B.C.D] [json]",
5314 SHOW_STR
5315 IP_STR
5316 MSDP_STR
5317 VRF_CMD_HELP_STR
5318 "MSDP peer information\n"
5319 "Detailed output\n"
5320 "peer ip address\n"
5321 JSON_STR)
5322 {
5323 bool uj = use_json(argc, argv);
5324 int idx = 2;
5325 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
5326
5327 if (!vrf)
5328 return CMD_WARNING;
5329
5330 char *arg = NULL;
5331
5332 if (argv_find(argv, argc, "detail", &idx))
5333 arg = argv[idx]->text;
5334 else if (argv_find(argv, argc, "A.B.C.D", &idx))
5335 arg = argv[idx]->arg;
5336
5337 if (arg)
5338 ip_msdp_show_peers_detail(vrf->info, vty, argv[idx]->arg, uj);
5339 else
5340 ip_msdp_show_peers(vrf->info, vty, uj);
5341
5342 return CMD_SUCCESS;
5343 }
5344
5345 DEFUN (show_ip_msdp_peer_detail_vrf_all,
5346 show_ip_msdp_peer_detail_vrf_all_cmd,
5347 "show ip msdp vrf all peer [detail|A.B.C.D] [json]",
5348 SHOW_STR
5349 IP_STR
5350 MSDP_STR
5351 VRF_CMD_HELP_STR
5352 "MSDP peer information\n"
5353 "Detailed output\n"
5354 "peer ip address\n"
5355 JSON_STR)
5356 {
5357 int idx = 2;
5358 bool uj = use_json(argc, argv);
5359 struct vrf *vrf;
5360 bool first = true;
5361
5362 if (uj)
5363 vty_out(vty, "{ ");
5364 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
5365 if (uj) {
5366 if (!first)
5367 vty_out(vty, ", ");
5368 vty_out(vty, " \"%s\": ", vrf->name);
5369 first = false;
5370 } else
5371 vty_out(vty, "VRF: %s\n", vrf->name);
5372 if (argv_find(argv, argc, "detail", &idx)
5373 || argv_find(argv, argc, "A.B.C.D", &idx))
5374 ip_msdp_show_peers_detail(vrf->info, vty,
5375 argv[idx]->arg, uj);
5376 else
5377 ip_msdp_show_peers(vrf->info, vty, uj);
5378 }
5379 if (uj)
5380 vty_out(vty, "}\n");
5381
5382 return CMD_SUCCESS;
5383 }
5384
5385 static void ip_msdp_show_sa(struct pim_instance *pim, struct vty *vty, bool uj)
5386 {
5387 struct listnode *sanode;
5388 struct pim_msdp_sa *sa;
5389 char rp_str[INET_ADDRSTRLEN];
5390 char timebuf[PIM_MSDP_UPTIME_STRLEN];
5391 char spt_str[8];
5392 char local_str[8];
5393 int64_t now;
5394 json_object *json = NULL;
5395 json_object *json_group = NULL;
5396 json_object *json_row = NULL;
5397
5398 if (uj) {
5399 json = json_object_new_object();
5400 } else {
5401 vty_out(vty,
5402 "Source Group RP Local SPT Uptime\n");
5403 }
5404
5405 for (ALL_LIST_ELEMENTS_RO(pim->msdp.sa_list, sanode, sa)) {
5406 now = pim_time_monotonic_sec();
5407 pim_time_uptime(timebuf, sizeof(timebuf), now - sa->uptime);
5408 if (sa->flags & PIM_MSDP_SAF_PEER) {
5409 pim_inet4_dump("<rp?>", sa->rp, rp_str, sizeof(rp_str));
5410 if (sa->up) {
5411 strlcpy(spt_str, "yes", sizeof(spt_str));
5412 } else {
5413 strlcpy(spt_str, "no", sizeof(spt_str));
5414 }
5415 } else {
5416 strlcpy(rp_str, "-", sizeof(rp_str));
5417 strlcpy(spt_str, "-", sizeof(spt_str));
5418 }
5419 if (sa->flags & PIM_MSDP_SAF_LOCAL) {
5420 strlcpy(local_str, "yes", sizeof(local_str));
5421 } else {
5422 strlcpy(local_str, "no", sizeof(local_str));
5423 }
5424 if (uj) {
5425 char src_str[PIM_ADDRSTRLEN];
5426 char grp_str[PIM_ADDRSTRLEN];
5427
5428 snprintfrr(grp_str, sizeof(grp_str), "%pPAs",
5429 &sa->sg.grp);
5430 snprintfrr(src_str, sizeof(src_str), "%pPAs",
5431 &sa->sg.src);
5432
5433 json_object_object_get_ex(json, grp_str, &json_group);
5434
5435 if (!json_group) {
5436 json_group = json_object_new_object();
5437 json_object_object_add(json, grp_str,
5438 json_group);
5439 }
5440
5441 json_row = json_object_new_object();
5442 json_object_string_add(json_row, "source", src_str);
5443 json_object_string_add(json_row, "group", grp_str);
5444 json_object_string_add(json_row, "rp", rp_str);
5445 json_object_string_add(json_row, "local", local_str);
5446 json_object_string_add(json_row, "sptSetup", spt_str);
5447 json_object_string_add(json_row, "upTime", timebuf);
5448 json_object_object_add(json_group, src_str, json_row);
5449 } else {
5450 vty_out(vty, "%-15pPAs %15pPAs %15s %5c %3c %8s\n",
5451 &sa->sg.src, &sa->sg.grp, rp_str, local_str[0],
5452 spt_str[0], timebuf);
5453 }
5454 }
5455
5456 if (uj)
5457 vty_json(vty, json);
5458 }
5459
5460 static void ip_msdp_show_sa_entry_detail(struct pim_msdp_sa *sa,
5461 const char *src_str,
5462 const char *grp_str, struct vty *vty,
5463 bool uj, json_object *json)
5464 {
5465 char rp_str[INET_ADDRSTRLEN];
5466 char peer_str[INET_ADDRSTRLEN];
5467 char timebuf[PIM_MSDP_UPTIME_STRLEN];
5468 char spt_str[8];
5469 char local_str[8];
5470 char statetimer[PIM_MSDP_TIMER_STRLEN];
5471 int64_t now;
5472 json_object *json_group = NULL;
5473 json_object *json_row = NULL;
5474
5475 now = pim_time_monotonic_sec();
5476 pim_time_uptime(timebuf, sizeof(timebuf), now - sa->uptime);
5477 if (sa->flags & PIM_MSDP_SAF_PEER) {
5478 pim_inet4_dump("<rp?>", sa->rp, rp_str, sizeof(rp_str));
5479 pim_inet4_dump("<peer?>", sa->peer, peer_str, sizeof(peer_str));
5480 if (sa->up) {
5481 strlcpy(spt_str, "yes", sizeof(spt_str));
5482 } else {
5483 strlcpy(spt_str, "no", sizeof(spt_str));
5484 }
5485 } else {
5486 strlcpy(rp_str, "-", sizeof(rp_str));
5487 strlcpy(peer_str, "-", sizeof(peer_str));
5488 strlcpy(spt_str, "-", sizeof(spt_str));
5489 }
5490 if (sa->flags & PIM_MSDP_SAF_LOCAL) {
5491 strlcpy(local_str, "yes", sizeof(local_str));
5492 } else {
5493 strlcpy(local_str, "no", sizeof(local_str));
5494 }
5495 pim_time_timer_to_hhmmss(statetimer, sizeof(statetimer),
5496 sa->sa_state_timer);
5497 if (uj) {
5498 json_object_object_get_ex(json, grp_str, &json_group);
5499
5500 if (!json_group) {
5501 json_group = json_object_new_object();
5502 json_object_object_add(json, grp_str, json_group);
5503 }
5504
5505 json_row = json_object_new_object();
5506 json_object_string_add(json_row, "source", src_str);
5507 json_object_string_add(json_row, "group", grp_str);
5508 json_object_string_add(json_row, "rp", rp_str);
5509 json_object_string_add(json_row, "local", local_str);
5510 json_object_string_add(json_row, "sptSetup", spt_str);
5511 json_object_string_add(json_row, "upTime", timebuf);
5512 json_object_string_add(json_row, "stateTimer", statetimer);
5513 json_object_object_add(json_group, src_str, json_row);
5514 } else {
5515 vty_out(vty, "SA : %s\n", sa->sg_str);
5516 vty_out(vty, " RP : %s\n", rp_str);
5517 vty_out(vty, " Peer : %s\n", peer_str);
5518 vty_out(vty, " Local : %s\n", local_str);
5519 vty_out(vty, " SPT Setup : %s\n", spt_str);
5520 vty_out(vty, " Uptime : %s\n", timebuf);
5521 vty_out(vty, " State Timer : %s\n", statetimer);
5522 vty_out(vty, "\n");
5523 }
5524 }
5525
5526 static void ip_msdp_show_sa_detail(struct pim_instance *pim, struct vty *vty,
5527 bool uj)
5528 {
5529 struct listnode *sanode;
5530 struct pim_msdp_sa *sa;
5531 json_object *json = NULL;
5532
5533 if (uj) {
5534 json = json_object_new_object();
5535 }
5536
5537 for (ALL_LIST_ELEMENTS_RO(pim->msdp.sa_list, sanode, sa)) {
5538 char src_str[PIM_ADDRSTRLEN];
5539 char grp_str[PIM_ADDRSTRLEN];
5540
5541 snprintfrr(grp_str, sizeof(grp_str), "%pPAs", &sa->sg.grp);
5542 snprintfrr(src_str, sizeof(src_str), "%pPAs", &sa->sg.src);
5543
5544 ip_msdp_show_sa_entry_detail(sa, src_str, grp_str, vty, uj,
5545 json);
5546 }
5547
5548 if (uj)
5549 vty_json(vty, json);
5550 }
5551
5552 DEFUN (show_ip_msdp_sa_detail,
5553 show_ip_msdp_sa_detail_cmd,
5554 "show ip msdp [vrf NAME] sa detail [json]",
5555 SHOW_STR
5556 IP_STR
5557 MSDP_STR
5558 VRF_CMD_HELP_STR
5559 "MSDP active-source information\n"
5560 "Detailed output\n"
5561 JSON_STR)
5562 {
5563 bool uj = use_json(argc, argv);
5564 int idx = 2;
5565 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
5566
5567 if (!vrf)
5568 return CMD_WARNING;
5569
5570 ip_msdp_show_sa_detail(vrf->info, vty, uj);
5571
5572 return CMD_SUCCESS;
5573 }
5574
5575 DEFUN (show_ip_msdp_sa_detail_vrf_all,
5576 show_ip_msdp_sa_detail_vrf_all_cmd,
5577 "show ip msdp vrf all sa detail [json]",
5578 SHOW_STR
5579 IP_STR
5580 MSDP_STR
5581 VRF_CMD_HELP_STR
5582 "MSDP active-source information\n"
5583 "Detailed output\n"
5584 JSON_STR)
5585 {
5586 bool uj = use_json(argc, argv);
5587 struct vrf *vrf;
5588 bool first = true;
5589
5590 if (uj)
5591 vty_out(vty, "{ ");
5592 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
5593 if (uj) {
5594 if (!first)
5595 vty_out(vty, ", ");
5596 vty_out(vty, " \"%s\": ", vrf->name);
5597 first = false;
5598 } else
5599 vty_out(vty, "VRF: %s\n", vrf->name);
5600 ip_msdp_show_sa_detail(vrf->info, vty, uj);
5601 }
5602 if (uj)
5603 vty_out(vty, "}\n");
5604
5605 return CMD_SUCCESS;
5606 }
5607
5608 static void ip_msdp_show_sa_addr(struct pim_instance *pim, struct vty *vty,
5609 const char *addr, bool uj)
5610 {
5611 struct listnode *sanode;
5612 struct pim_msdp_sa *sa;
5613 json_object *json = NULL;
5614
5615 if (uj) {
5616 json = json_object_new_object();
5617 }
5618
5619 for (ALL_LIST_ELEMENTS_RO(pim->msdp.sa_list, sanode, sa)) {
5620 char src_str[PIM_ADDRSTRLEN];
5621 char grp_str[PIM_ADDRSTRLEN];
5622
5623 snprintfrr(grp_str, sizeof(grp_str), "%pPAs", &sa->sg.grp);
5624 snprintfrr(src_str, sizeof(src_str), "%pPAs", &sa->sg.src);
5625
5626 if (!strcmp(addr, src_str) || !strcmp(addr, grp_str)) {
5627 ip_msdp_show_sa_entry_detail(sa, src_str, grp_str, vty,
5628 uj, json);
5629 }
5630 }
5631
5632 if (uj)
5633 vty_json(vty, json);
5634 }
5635
5636 static void ip_msdp_show_sa_sg(struct pim_instance *pim, struct vty *vty,
5637 const char *src, const char *grp, bool uj)
5638 {
5639 struct listnode *sanode;
5640 struct pim_msdp_sa *sa;
5641 json_object *json = NULL;
5642
5643 if (uj) {
5644 json = json_object_new_object();
5645 }
5646
5647 for (ALL_LIST_ELEMENTS_RO(pim->msdp.sa_list, sanode, sa)) {
5648 char src_str[PIM_ADDRSTRLEN];
5649 char grp_str[PIM_ADDRSTRLEN];
5650
5651 snprintfrr(grp_str, sizeof(grp_str), "%pPAs", &sa->sg.grp);
5652 snprintfrr(src_str, sizeof(src_str), "%pPAs", &sa->sg.src);
5653
5654 if (!strcmp(src, src_str) && !strcmp(grp, grp_str)) {
5655 ip_msdp_show_sa_entry_detail(sa, src_str, grp_str, vty,
5656 uj, json);
5657 }
5658 }
5659
5660 if (uj)
5661 vty_json(vty, json);
5662 }
5663
5664 DEFUN (show_ip_msdp_sa_sg,
5665 show_ip_msdp_sa_sg_cmd,
5666 "show ip msdp [vrf NAME] sa [A.B.C.D [A.B.C.D]] [json]",
5667 SHOW_STR
5668 IP_STR
5669 MSDP_STR
5670 VRF_CMD_HELP_STR
5671 "MSDP active-source information\n"
5672 "source or group ip\n"
5673 "group ip\n"
5674 JSON_STR)
5675 {
5676 bool uj = use_json(argc, argv);
5677 struct vrf *vrf;
5678 int idx = 2;
5679
5680 vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
5681
5682 if (!vrf)
5683 return CMD_WARNING;
5684
5685 char *src_ip = argv_find(argv, argc, "A.B.C.D", &idx) ? argv[idx++]->arg
5686 : NULL;
5687 char *grp_ip = idx < argc && argv_find(argv, argc, "A.B.C.D", &idx)
5688 ? argv[idx]->arg
5689 : NULL;
5690
5691 if (src_ip && grp_ip)
5692 ip_msdp_show_sa_sg(vrf->info, vty, src_ip, grp_ip, uj);
5693 else if (src_ip)
5694 ip_msdp_show_sa_addr(vrf->info, vty, src_ip, uj);
5695 else
5696 ip_msdp_show_sa(vrf->info, vty, uj);
5697
5698 return CMD_SUCCESS;
5699 }
5700
5701 DEFUN (show_ip_msdp_sa_sg_vrf_all,
5702 show_ip_msdp_sa_sg_vrf_all_cmd,
5703 "show ip msdp vrf all sa [A.B.C.D [A.B.C.D]] [json]",
5704 SHOW_STR
5705 IP_STR
5706 MSDP_STR
5707 VRF_CMD_HELP_STR
5708 "MSDP active-source information\n"
5709 "source or group ip\n"
5710 "group ip\n"
5711 JSON_STR)
5712 {
5713 bool uj = use_json(argc, argv);
5714 struct vrf *vrf;
5715 bool first = true;
5716 int idx = 2;
5717
5718 char *src_ip = argv_find(argv, argc, "A.B.C.D", &idx) ? argv[idx++]->arg
5719 : NULL;
5720 char *grp_ip = idx < argc && argv_find(argv, argc, "A.B.C.D", &idx)
5721 ? argv[idx]->arg
5722 : NULL;
5723
5724 if (uj)
5725 vty_out(vty, "{ ");
5726 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
5727 if (uj) {
5728 if (!first)
5729 vty_out(vty, ", ");
5730 vty_out(vty, " \"%s\": ", vrf->name);
5731 first = false;
5732 } else
5733 vty_out(vty, "VRF: %s\n", vrf->name);
5734
5735 if (src_ip && grp_ip)
5736 ip_msdp_show_sa_sg(vrf->info, vty, src_ip, grp_ip, uj);
5737 else if (src_ip)
5738 ip_msdp_show_sa_addr(vrf->info, vty, src_ip, uj);
5739 else
5740 ip_msdp_show_sa(vrf->info, vty, uj);
5741 }
5742 if (uj)
5743 vty_out(vty, "}\n");
5744
5745 return CMD_SUCCESS;
5746 }
5747
5748 struct pim_sg_cache_walk_data {
5749 struct vty *vty;
5750 json_object *json;
5751 json_object *json_group;
5752 struct in_addr addr;
5753 bool addr_match;
5754 };
5755
5756 static void pim_show_vxlan_sg_entry(struct pim_vxlan_sg *vxlan_sg,
5757 struct pim_sg_cache_walk_data *cwd)
5758 {
5759 struct vty *vty = cwd->vty;
5760 json_object *json = cwd->json;
5761 json_object *json_row;
5762 bool installed = (vxlan_sg->up) ? true : false;
5763 const char *iif_name = vxlan_sg->iif?vxlan_sg->iif->name:"-";
5764 const char *oif_name;
5765
5766 if (pim_vxlan_is_orig_mroute(vxlan_sg))
5767 oif_name = vxlan_sg->orig_oif?vxlan_sg->orig_oif->name:"";
5768 else
5769 oif_name = vxlan_sg->term_oif?vxlan_sg->term_oif->name:"";
5770
5771 if (cwd->addr_match && pim_addr_cmp(vxlan_sg->sg.src, cwd->addr) &&
5772 pim_addr_cmp(vxlan_sg->sg.grp, cwd->addr)) {
5773 return;
5774 }
5775 if (json) {
5776 char src_str[PIM_ADDRSTRLEN];
5777 char grp_str[PIM_ADDRSTRLEN];
5778
5779 snprintfrr(grp_str, sizeof(grp_str), "%pPAs",
5780 &vxlan_sg->sg.grp);
5781 snprintfrr(src_str, sizeof(src_str), "%pPAs",
5782 &vxlan_sg->sg.src);
5783
5784 json_object_object_get_ex(json, grp_str, &cwd->json_group);
5785
5786 if (!cwd->json_group) {
5787 cwd->json_group = json_object_new_object();
5788 json_object_object_add(json, grp_str,
5789 cwd->json_group);
5790 }
5791
5792 json_row = json_object_new_object();
5793 json_object_string_add(json_row, "source", src_str);
5794 json_object_string_add(json_row, "group", grp_str);
5795 json_object_string_add(json_row, "input", iif_name);
5796 json_object_string_add(json_row, "output", oif_name);
5797 if (installed)
5798 json_object_boolean_true_add(json_row, "installed");
5799 else
5800 json_object_boolean_false_add(json_row, "installed");
5801 json_object_object_add(cwd->json_group, src_str, json_row);
5802 } else {
5803 vty_out(vty, "%-15pPAs %-15pPAs %-15s %-15s %-5s\n",
5804 &vxlan_sg->sg.src, &vxlan_sg->sg.grp, iif_name,
5805 oif_name, installed ? "I" : "");
5806 }
5807 }
5808
5809 static void pim_show_vxlan_sg_hash_entry(struct hash_bucket *bucket, void *arg)
5810 {
5811 pim_show_vxlan_sg_entry((struct pim_vxlan_sg *)bucket->data,
5812 (struct pim_sg_cache_walk_data *)arg);
5813 }
5814
5815 static void pim_show_vxlan_sg(struct pim_instance *pim,
5816 struct vty *vty, bool uj)
5817 {
5818 json_object *json = NULL;
5819 struct pim_sg_cache_walk_data cwd;
5820
5821 if (uj) {
5822 json = json_object_new_object();
5823 } else {
5824 vty_out(vty, "Codes: I -> installed\n");
5825 vty_out(vty,
5826 "Source Group Input Output Flags\n");
5827 }
5828
5829 memset(&cwd, 0, sizeof(cwd));
5830 cwd.vty = vty;
5831 cwd.json = json;
5832 hash_iterate(pim->vxlan.sg_hash, pim_show_vxlan_sg_hash_entry, &cwd);
5833
5834 if (uj)
5835 vty_json(vty, json);
5836 }
5837
5838 static void pim_show_vxlan_sg_match_addr(struct pim_instance *pim,
5839 struct vty *vty, char *addr_str,
5840 bool uj)
5841 {
5842 json_object *json = NULL;
5843 struct pim_sg_cache_walk_data cwd;
5844 int result = 0;
5845
5846 memset(&cwd, 0, sizeof(cwd));
5847 result = inet_pton(AF_INET, addr_str, &cwd.addr);
5848 if (result <= 0) {
5849 vty_out(vty, "Bad address %s: errno=%d: %s\n", addr_str,
5850 errno, safe_strerror(errno));
5851 return;
5852 }
5853
5854 if (uj) {
5855 json = json_object_new_object();
5856 } else {
5857 vty_out(vty, "Codes: I -> installed\n");
5858 vty_out(vty,
5859 "Source Group Input Output Flags\n");
5860 }
5861
5862 cwd.vty = vty;
5863 cwd.json = json;
5864 cwd.addr_match = true;
5865 hash_iterate(pim->vxlan.sg_hash, pim_show_vxlan_sg_hash_entry, &cwd);
5866
5867 if (uj)
5868 vty_json(vty, json);
5869 }
5870
5871 static void pim_show_vxlan_sg_one(struct pim_instance *pim,
5872 struct vty *vty, char *src_str, char *grp_str,
5873 bool uj)
5874 {
5875 json_object *json = NULL;
5876 pim_sgaddr sg;
5877 int result = 0;
5878 struct pim_vxlan_sg *vxlan_sg;
5879 const char *iif_name;
5880 bool installed;
5881 const char *oif_name;
5882
5883 result = inet_pton(AF_INET, src_str, &sg.src);
5884 if (result <= 0) {
5885 vty_out(vty, "Bad src address %s: errno=%d: %s\n", src_str,
5886 errno, safe_strerror(errno));
5887 return;
5888 }
5889 result = inet_pton(AF_INET, grp_str, &sg.grp);
5890 if (result <= 0) {
5891 vty_out(vty, "Bad grp address %s: errno=%d: %s\n", grp_str,
5892 errno, safe_strerror(errno));
5893 return;
5894 }
5895
5896 if (uj)
5897 json = json_object_new_object();
5898
5899 vxlan_sg = pim_vxlan_sg_find(pim, &sg);
5900 if (vxlan_sg) {
5901 installed = (vxlan_sg->up) ? true : false;
5902 iif_name = vxlan_sg->iif?vxlan_sg->iif->name:"-";
5903
5904 if (pim_vxlan_is_orig_mroute(vxlan_sg))
5905 oif_name =
5906 vxlan_sg->orig_oif?vxlan_sg->orig_oif->name:"";
5907 else
5908 oif_name =
5909 vxlan_sg->term_oif?vxlan_sg->term_oif->name:"";
5910
5911 if (uj) {
5912 json_object_string_add(json, "source", src_str);
5913 json_object_string_add(json, "group", grp_str);
5914 json_object_string_add(json, "input", iif_name);
5915 json_object_string_add(json, "output", oif_name);
5916 if (installed)
5917 json_object_boolean_true_add(json, "installed");
5918 else
5919 json_object_boolean_false_add(json,
5920 "installed");
5921 } else {
5922 vty_out(vty, "SG : %s\n", vxlan_sg->sg_str);
5923 vty_out(vty, " Input : %s\n", iif_name);
5924 vty_out(vty, " Output : %s\n", oif_name);
5925 vty_out(vty, " installed : %s\n",
5926 installed?"yes":"no");
5927 }
5928 }
5929
5930 if (uj)
5931 vty_json(vty, json);
5932 }
5933
5934 DEFUN (show_ip_pim_vxlan_sg,
5935 show_ip_pim_vxlan_sg_cmd,
5936 "show ip pim [vrf NAME] vxlan-groups [A.B.C.D [A.B.C.D]] [json]",
5937 SHOW_STR
5938 IP_STR
5939 PIM_STR
5940 VRF_CMD_HELP_STR
5941 "VxLAN BUM groups\n"
5942 "source or group ip\n"
5943 "group ip\n"
5944 JSON_STR)
5945 {
5946 bool uj = use_json(argc, argv);
5947 struct vrf *vrf;
5948 int idx = 2;
5949
5950 vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
5951
5952 if (!vrf)
5953 return CMD_WARNING;
5954
5955 char *src_ip = argv_find(argv, argc, "A.B.C.D", &idx) ?
5956 argv[idx++]->arg:NULL;
5957 char *grp_ip = idx < argc && argv_find(argv, argc, "A.B.C.D", &idx) ?
5958 argv[idx]->arg:NULL;
5959
5960 if (src_ip && grp_ip)
5961 pim_show_vxlan_sg_one(vrf->info, vty, src_ip, grp_ip, uj);
5962 else if (src_ip)
5963 pim_show_vxlan_sg_match_addr(vrf->info, vty, src_ip, uj);
5964 else
5965 pim_show_vxlan_sg(vrf->info, vty, uj);
5966
5967 return CMD_SUCCESS;
5968 }
5969
5970 static void pim_show_vxlan_sg_work(struct pim_instance *pim,
5971 struct vty *vty, bool uj)
5972 {
5973 json_object *json = NULL;
5974 struct pim_sg_cache_walk_data cwd;
5975 struct listnode *node;
5976 struct pim_vxlan_sg *vxlan_sg;
5977
5978 if (uj) {
5979 json = json_object_new_object();
5980 } else {
5981 vty_out(vty, "Codes: I -> installed\n");
5982 vty_out(vty,
5983 "Source Group Input Flags\n");
5984 }
5985
5986 memset(&cwd, 0, sizeof(cwd));
5987 cwd.vty = vty;
5988 cwd.json = json;
5989 for (ALL_LIST_ELEMENTS_RO(pim_vxlan_p->work_list, node, vxlan_sg))
5990 pim_show_vxlan_sg_entry(vxlan_sg, &cwd);
5991
5992 if (uj)
5993 vty_json(vty, json);
5994 }
5995
5996 DEFUN_HIDDEN (show_ip_pim_vxlan_sg_work,
5997 show_ip_pim_vxlan_sg_work_cmd,
5998 "show ip pim [vrf NAME] vxlan-work [json]",
5999 SHOW_STR
6000 IP_STR
6001 PIM_STR
6002 VRF_CMD_HELP_STR
6003 "VxLAN work list\n"
6004 JSON_STR)
6005 {
6006 bool uj = use_json(argc, argv);
6007 struct vrf *vrf;
6008 int idx = 2;
6009
6010 vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
6011
6012 if (!vrf)
6013 return CMD_WARNING;
6014
6015 pim_show_vxlan_sg_work(vrf->info, vty, uj);
6016
6017 return CMD_SUCCESS;
6018 }
6019
6020 DEFUN_HIDDEN (no_ip_pim_mlag,
6021 no_ip_pim_mlag_cmd,
6022 "no ip pim mlag",
6023 NO_STR
6024 IP_STR
6025 PIM_STR
6026 "MLAG\n")
6027 {
6028 char mlag_xpath[XPATH_MAXLEN];
6029
6030 snprintf(mlag_xpath, sizeof(mlag_xpath), FRR_PIM_VRF_XPATH,
6031 "frr-pim:pimd", "pim", "default", "frr-routing:ipv4");
6032 strlcat(mlag_xpath, "/mlag", sizeof(mlag_xpath));
6033
6034 nb_cli_enqueue_change(vty, mlag_xpath, NB_OP_DESTROY, NULL);
6035
6036
6037 return nb_cli_apply_changes(vty, NULL);
6038 }
6039
6040 DEFUN_HIDDEN (ip_pim_mlag,
6041 ip_pim_mlag_cmd,
6042 "ip pim mlag INTERFACE role [primary|secondary] state [up|down] addr A.B.C.D",
6043 IP_STR
6044 PIM_STR
6045 "MLAG\n"
6046 "peerlink sub interface\n"
6047 "MLAG role\n"
6048 "MLAG role primary\n"
6049 "MLAG role secondary\n"
6050 "peer session state\n"
6051 "peer session state up\n"
6052 "peer session state down\n"
6053 "configure PIP\n"
6054 "unique ip address\n")
6055 {
6056 int idx;
6057 char mlag_peerlink_rif_xpath[XPATH_MAXLEN];
6058 char mlag_my_role_xpath[XPATH_MAXLEN];
6059 char mlag_peer_state_xpath[XPATH_MAXLEN];
6060 char mlag_reg_address_xpath[XPATH_MAXLEN];
6061
6062 snprintf(mlag_peerlink_rif_xpath, sizeof(mlag_peerlink_rif_xpath),
6063 FRR_PIM_VRF_XPATH,
6064 "frr-pim:pimd", "pim", "default", "frr-routing:ipv4");
6065 strlcat(mlag_peerlink_rif_xpath, "/mlag/peerlink-rif",
6066 sizeof(mlag_peerlink_rif_xpath));
6067
6068 idx = 3;
6069 nb_cli_enqueue_change(vty, mlag_peerlink_rif_xpath, NB_OP_MODIFY,
6070 argv[idx]->arg);
6071
6072 snprintf(mlag_my_role_xpath, sizeof(mlag_my_role_xpath),
6073 FRR_PIM_VRF_XPATH,
6074 "frr-pim:pimd", "pim", "default", "frr-routing:ipv4");
6075 strlcat(mlag_my_role_xpath, "/mlag/my-role",
6076 sizeof(mlag_my_role_xpath));
6077
6078 idx += 2;
6079 if (!strcmp(argv[idx]->arg, "primary")) {
6080 nb_cli_enqueue_change(vty, mlag_my_role_xpath, NB_OP_MODIFY,
6081 "MLAG_ROLE_PRIMARY");
6082
6083 } else if (!strcmp(argv[idx]->arg, "secondary")) {
6084 nb_cli_enqueue_change(vty, mlag_my_role_xpath, NB_OP_MODIFY,
6085 "MLAG_ROLE_SECONDARY");
6086
6087 } else {
6088 vty_out(vty, "unknown MLAG role %s\n", argv[idx]->arg);
6089 return CMD_WARNING;
6090 }
6091
6092 snprintf(mlag_peer_state_xpath, sizeof(mlag_peer_state_xpath),
6093 FRR_PIM_VRF_XPATH,
6094 "frr-pim:pimd", "pim", "default", "frr-routing:ipv4");
6095 strlcat(mlag_peer_state_xpath, "/mlag/peer-state",
6096 sizeof(mlag_peer_state_xpath));
6097
6098 idx += 2;
6099 if (!strcmp(argv[idx]->arg, "up")) {
6100 nb_cli_enqueue_change(vty, mlag_peer_state_xpath, NB_OP_MODIFY,
6101 "true");
6102
6103 } else if (strcmp(argv[idx]->arg, "down")) {
6104 nb_cli_enqueue_change(vty, mlag_peer_state_xpath, NB_OP_MODIFY,
6105 "false");
6106
6107 } else {
6108 vty_out(vty, "unknown MLAG state %s\n", argv[idx]->arg);
6109 return CMD_WARNING;
6110 }
6111
6112 snprintf(mlag_reg_address_xpath, sizeof(mlag_reg_address_xpath),
6113 FRR_PIM_VRF_XPATH,
6114 "frr-pim:pimd", "pim", "default", "frr-routing:ipv4");
6115 strlcat(mlag_reg_address_xpath, "/mlag/reg-address",
6116 sizeof(mlag_reg_address_xpath));
6117
6118 idx += 2;
6119 nb_cli_enqueue_change(vty, mlag_reg_address_xpath, NB_OP_MODIFY,
6120 argv[idx]->arg);
6121
6122 return nb_cli_apply_changes(vty, NULL);
6123 }
6124
6125 void pim_cmd_init(void)
6126 {
6127 if_cmd_init(pim_interface_config_write);
6128
6129 install_node(&debug_node);
6130
6131 install_element(ENABLE_NODE, &pim_test_sg_keepalive_cmd);
6132
6133 install_element(CONFIG_NODE, &ip_pim_rp_cmd);
6134 install_element(VRF_NODE, &ip_pim_rp_cmd);
6135 install_element(CONFIG_NODE, &no_ip_pim_rp_cmd);
6136 install_element(VRF_NODE, &no_ip_pim_rp_cmd);
6137 install_element(CONFIG_NODE, &ip_pim_rp_prefix_list_cmd);
6138 install_element(VRF_NODE, &ip_pim_rp_prefix_list_cmd);
6139 install_element(CONFIG_NODE, &no_ip_pim_rp_prefix_list_cmd);
6140 install_element(VRF_NODE, &no_ip_pim_rp_prefix_list_cmd);
6141 install_element(CONFIG_NODE, &no_ip_pim_ssm_prefix_list_cmd);
6142 install_element(VRF_NODE, &no_ip_pim_ssm_prefix_list_cmd);
6143 install_element(CONFIG_NODE, &no_ip_pim_ssm_prefix_list_name_cmd);
6144 install_element(VRF_NODE, &no_ip_pim_ssm_prefix_list_name_cmd);
6145 install_element(CONFIG_NODE, &ip_pim_ssm_prefix_list_cmd);
6146 install_element(VRF_NODE, &ip_pim_ssm_prefix_list_cmd);
6147 install_element(CONFIG_NODE, &ip_pim_register_suppress_cmd);
6148 install_element(CONFIG_NODE, &no_ip_pim_register_suppress_cmd);
6149 install_element(CONFIG_NODE, &ip_pim_spt_switchover_infinity_cmd);
6150 install_element(VRF_NODE, &ip_pim_spt_switchover_infinity_cmd);
6151 install_element(CONFIG_NODE, &ip_pim_spt_switchover_infinity_plist_cmd);
6152 install_element(VRF_NODE, &ip_pim_spt_switchover_infinity_plist_cmd);
6153 install_element(CONFIG_NODE, &no_ip_pim_spt_switchover_infinity_cmd);
6154 install_element(VRF_NODE, &no_ip_pim_spt_switchover_infinity_cmd);
6155 install_element(CONFIG_NODE,
6156 &no_ip_pim_spt_switchover_infinity_plist_cmd);
6157 install_element(VRF_NODE, &no_ip_pim_spt_switchover_infinity_plist_cmd);
6158 install_element(CONFIG_NODE, &pim_register_accept_list_cmd);
6159 install_element(VRF_NODE, &pim_register_accept_list_cmd);
6160 install_element(CONFIG_NODE, &ip_pim_joinprune_time_cmd);
6161 install_element(CONFIG_NODE, &no_ip_pim_joinprune_time_cmd);
6162 install_element(CONFIG_NODE, &ip_pim_keep_alive_cmd);
6163 install_element(VRF_NODE, &ip_pim_keep_alive_cmd);
6164 install_element(CONFIG_NODE, &ip_pim_rp_keep_alive_cmd);
6165 install_element(VRF_NODE, &ip_pim_rp_keep_alive_cmd);
6166 install_element(CONFIG_NODE, &no_ip_pim_keep_alive_cmd);
6167 install_element(VRF_NODE, &no_ip_pim_keep_alive_cmd);
6168 install_element(CONFIG_NODE, &no_ip_pim_rp_keep_alive_cmd);
6169 install_element(VRF_NODE, &no_ip_pim_rp_keep_alive_cmd);
6170 install_element(CONFIG_NODE, &ip_pim_packets_cmd);
6171 install_element(CONFIG_NODE, &no_ip_pim_packets_cmd);
6172 install_element(CONFIG_NODE, &ip_pim_v6_secondary_cmd);
6173 install_element(VRF_NODE, &ip_pim_v6_secondary_cmd);
6174 install_element(CONFIG_NODE, &no_ip_pim_v6_secondary_cmd);
6175 install_element(VRF_NODE, &no_ip_pim_v6_secondary_cmd);
6176 install_element(CONFIG_NODE, &ip_ssmpingd_cmd);
6177 install_element(VRF_NODE, &ip_ssmpingd_cmd);
6178 install_element(CONFIG_NODE, &no_ip_ssmpingd_cmd);
6179 install_element(VRF_NODE, &no_ip_ssmpingd_cmd);
6180 install_element(CONFIG_NODE, &ip_msdp_peer_cmd);
6181 install_element(VRF_NODE, &ip_msdp_peer_cmd);
6182 install_element(CONFIG_NODE, &no_ip_msdp_peer_cmd);
6183 install_element(VRF_NODE, &no_ip_msdp_peer_cmd);
6184 install_element(CONFIG_NODE, &ip_pim_ecmp_cmd);
6185 install_element(VRF_NODE, &ip_pim_ecmp_cmd);
6186 install_element(CONFIG_NODE, &no_ip_pim_ecmp_cmd);
6187 install_element(VRF_NODE, &no_ip_pim_ecmp_cmd);
6188 install_element(CONFIG_NODE, &ip_pim_ecmp_rebalance_cmd);
6189 install_element(VRF_NODE, &ip_pim_ecmp_rebalance_cmd);
6190 install_element(CONFIG_NODE, &no_ip_pim_ecmp_rebalance_cmd);
6191 install_element(VRF_NODE, &no_ip_pim_ecmp_rebalance_cmd);
6192 install_element(CONFIG_NODE, &ip_pim_mlag_cmd);
6193 install_element(CONFIG_NODE, &no_ip_pim_mlag_cmd);
6194 install_element(CONFIG_NODE, &ip_igmp_group_watermark_cmd);
6195 install_element(VRF_NODE, &ip_igmp_group_watermark_cmd);
6196 install_element(CONFIG_NODE, &no_ip_igmp_group_watermark_cmd);
6197 install_element(VRF_NODE, &no_ip_igmp_group_watermark_cmd);
6198
6199 install_element(INTERFACE_NODE, &interface_ip_igmp_cmd);
6200 install_element(INTERFACE_NODE, &interface_no_ip_igmp_cmd);
6201 install_element(INTERFACE_NODE, &interface_ip_igmp_join_cmd);
6202 install_element(INTERFACE_NODE, &interface_no_ip_igmp_join_cmd);
6203 install_element(INTERFACE_NODE, &interface_ip_igmp_version_cmd);
6204 install_element(INTERFACE_NODE, &interface_no_ip_igmp_version_cmd);
6205 install_element(INTERFACE_NODE, &interface_ip_igmp_query_interval_cmd);
6206 install_element(INTERFACE_NODE,
6207 &interface_no_ip_igmp_query_interval_cmd);
6208 install_element(INTERFACE_NODE,
6209 &interface_ip_igmp_query_max_response_time_cmd);
6210 install_element(INTERFACE_NODE,
6211 &interface_no_ip_igmp_query_max_response_time_cmd);
6212 install_element(INTERFACE_NODE,
6213 &interface_ip_igmp_query_max_response_time_dsec_cmd);
6214 install_element(INTERFACE_NODE,
6215 &interface_no_ip_igmp_query_max_response_time_dsec_cmd);
6216 install_element(INTERFACE_NODE,
6217 &interface_ip_igmp_last_member_query_count_cmd);
6218 install_element(INTERFACE_NODE,
6219 &interface_no_ip_igmp_last_member_query_count_cmd);
6220 install_element(INTERFACE_NODE,
6221 &interface_ip_igmp_last_member_query_interval_cmd);
6222 install_element(INTERFACE_NODE,
6223 &interface_no_ip_igmp_last_member_query_interval_cmd);
6224 install_element(INTERFACE_NODE, &interface_ip_pim_activeactive_cmd);
6225 install_element(INTERFACE_NODE, &interface_ip_pim_ssm_cmd);
6226 install_element(INTERFACE_NODE, &interface_no_ip_pim_ssm_cmd);
6227 install_element(INTERFACE_NODE, &interface_ip_pim_sm_cmd);
6228 install_element(INTERFACE_NODE, &interface_no_ip_pim_sm_cmd);
6229 install_element(INTERFACE_NODE, &interface_ip_pim_cmd);
6230 install_element(INTERFACE_NODE, &interface_no_ip_pim_cmd);
6231 install_element(INTERFACE_NODE, &interface_ip_pim_drprio_cmd);
6232 install_element(INTERFACE_NODE, &interface_no_ip_pim_drprio_cmd);
6233 install_element(INTERFACE_NODE, &interface_ip_pim_hello_cmd);
6234 install_element(INTERFACE_NODE, &interface_no_ip_pim_hello_cmd);
6235 install_element(INTERFACE_NODE, &interface_ip_pim_boundary_oil_cmd);
6236 install_element(INTERFACE_NODE, &interface_no_ip_pim_boundary_oil_cmd);
6237 install_element(INTERFACE_NODE, &interface_ip_igmp_query_generate_cmd);
6238
6239 // Static mroutes NEB
6240 install_element(INTERFACE_NODE, &interface_ip_mroute_cmd);
6241 install_element(INTERFACE_NODE, &interface_no_ip_mroute_cmd);
6242
6243 install_element(VIEW_NODE, &show_ip_igmp_interface_cmd);
6244 install_element(VIEW_NODE, &show_ip_igmp_interface_vrf_all_cmd);
6245 install_element(VIEW_NODE, &show_ip_igmp_join_cmd);
6246 install_element(VIEW_NODE, &show_ip_igmp_join_vrf_all_cmd);
6247 install_element(VIEW_NODE, &show_ip_igmp_groups_cmd);
6248 install_element(VIEW_NODE, &show_ip_igmp_groups_vrf_all_cmd);
6249 install_element(VIEW_NODE, &show_ip_igmp_groups_retransmissions_cmd);
6250 install_element(VIEW_NODE, &show_ip_igmp_sources_cmd);
6251 install_element(VIEW_NODE, &show_ip_igmp_sources_retransmissions_cmd);
6252 install_element(VIEW_NODE, &show_ip_igmp_statistics_cmd);
6253 install_element(VIEW_NODE, &show_ip_pim_assert_cmd);
6254 install_element(VIEW_NODE, &show_ip_pim_assert_internal_cmd);
6255 install_element(VIEW_NODE, &show_ip_pim_assert_metric_cmd);
6256 install_element(VIEW_NODE, &show_ip_pim_assert_winner_metric_cmd);
6257 install_element(VIEW_NODE, &show_ip_pim_interface_traffic_cmd);
6258 install_element(VIEW_NODE, &show_ip_pim_interface_cmd);
6259 install_element(VIEW_NODE, &show_ip_pim_interface_vrf_all_cmd);
6260 install_element(VIEW_NODE, &show_ip_pim_join_cmd);
6261 install_element(VIEW_NODE, &show_ip_pim_join_vrf_all_cmd);
6262 install_element(VIEW_NODE, &show_ip_pim_jp_agg_cmd);
6263 install_element(VIEW_NODE, &show_ip_pim_local_membership_cmd);
6264 install_element(VIEW_NODE, &show_ip_pim_mlag_summary_cmd);
6265 install_element(VIEW_NODE, &show_ip_pim_mlag_up_cmd);
6266 install_element(VIEW_NODE, &show_ip_pim_mlag_up_vrf_all_cmd);
6267 install_element(VIEW_NODE, &show_ip_pim_neighbor_cmd);
6268 install_element(VIEW_NODE, &show_ip_pim_neighbor_vrf_all_cmd);
6269 install_element(VIEW_NODE, &show_ip_pim_rpf_cmd);
6270 install_element(VIEW_NODE, &show_ip_pim_rpf_vrf_all_cmd);
6271 install_element(VIEW_NODE, &show_ip_pim_secondary_cmd);
6272 install_element(VIEW_NODE, &show_ip_pim_state_cmd);
6273 install_element(VIEW_NODE, &show_ip_pim_state_vrf_all_cmd);
6274 install_element(VIEW_NODE, &show_ip_pim_upstream_cmd);
6275 install_element(VIEW_NODE, &show_ip_pim_upstream_vrf_all_cmd);
6276 install_element(VIEW_NODE, &show_ip_pim_channel_cmd);
6277 install_element(VIEW_NODE, &show_ip_pim_upstream_join_desired_cmd);
6278 install_element(VIEW_NODE, &show_ip_pim_upstream_rpf_cmd);
6279 install_element(VIEW_NODE, &show_ip_pim_rp_cmd);
6280 install_element(VIEW_NODE, &show_ip_pim_rp_vrf_all_cmd);
6281 install_element(VIEW_NODE, &show_ip_pim_bsr_cmd);
6282 install_element(VIEW_NODE, &show_ip_multicast_cmd);
6283 install_element(VIEW_NODE, &show_ip_multicast_vrf_all_cmd);
6284 install_element(VIEW_NODE, &show_ip_multicast_count_cmd);
6285 install_element(VIEW_NODE, &show_ip_multicast_count_vrf_all_cmd);
6286 install_element(VIEW_NODE, &show_ip_mroute_cmd);
6287 install_element(VIEW_NODE, &show_ip_mroute_vrf_all_cmd);
6288 install_element(VIEW_NODE, &show_ip_mroute_count_cmd);
6289 install_element(VIEW_NODE, &show_ip_mroute_count_vrf_all_cmd);
6290 install_element(VIEW_NODE, &show_ip_mroute_summary_cmd);
6291 install_element(VIEW_NODE, &show_ip_mroute_summary_vrf_all_cmd);
6292 install_element(VIEW_NODE, &show_ip_rib_cmd);
6293 install_element(VIEW_NODE, &show_ip_ssmpingd_cmd);
6294 install_element(VIEW_NODE, &show_ip_pim_nexthop_cmd);
6295 install_element(VIEW_NODE, &show_ip_pim_nexthop_lookup_cmd);
6296 install_element(VIEW_NODE, &show_ip_pim_bsrp_cmd);
6297 install_element(VIEW_NODE, &show_ip_pim_bsm_db_cmd);
6298 install_element(VIEW_NODE, &show_ip_pim_statistics_cmd);
6299
6300 install_element(ENABLE_NODE, &clear_ip_mroute_count_cmd);
6301 install_element(ENABLE_NODE, &clear_ip_interfaces_cmd);
6302 install_element(ENABLE_NODE, &clear_ip_igmp_interfaces_cmd);
6303 install_element(ENABLE_NODE, &clear_ip_mroute_cmd);
6304 install_element(ENABLE_NODE, &clear_ip_pim_interfaces_cmd);
6305 install_element(ENABLE_NODE, &clear_ip_pim_interface_traffic_cmd);
6306 install_element(ENABLE_NODE, &clear_ip_pim_oil_cmd);
6307 install_element(ENABLE_NODE, &clear_ip_pim_statistics_cmd);
6308 install_element(ENABLE_NODE, &clear_ip_pim_bsr_db_cmd);
6309
6310 install_element(ENABLE_NODE, &show_debugging_pim_cmd);
6311
6312 install_element(ENABLE_NODE, &debug_igmp_cmd);
6313 install_element(ENABLE_NODE, &no_debug_igmp_cmd);
6314 install_element(ENABLE_NODE, &debug_igmp_events_cmd);
6315 install_element(ENABLE_NODE, &no_debug_igmp_events_cmd);
6316 install_element(ENABLE_NODE, &debug_igmp_packets_cmd);
6317 install_element(ENABLE_NODE, &no_debug_igmp_packets_cmd);
6318 install_element(ENABLE_NODE, &debug_igmp_trace_cmd);
6319 install_element(ENABLE_NODE, &no_debug_igmp_trace_cmd);
6320 install_element(ENABLE_NODE, &debug_igmp_trace_detail_cmd);
6321 install_element(ENABLE_NODE, &no_debug_igmp_trace_detail_cmd);
6322 install_element(ENABLE_NODE, &debug_mroute_cmd);
6323 install_element(ENABLE_NODE, &debug_mroute_detail_cmd);
6324 install_element(ENABLE_NODE, &no_debug_mroute_cmd);
6325 install_element(ENABLE_NODE, &no_debug_mroute_detail_cmd);
6326 install_element(ENABLE_NODE, &debug_pim_static_cmd);
6327 install_element(ENABLE_NODE, &no_debug_pim_static_cmd);
6328 install_element(ENABLE_NODE, &debug_pim_cmd);
6329 install_element(ENABLE_NODE, &debug_pim_nht_cmd);
6330 install_element(ENABLE_NODE, &debug_pim_nht_det_cmd);
6331 install_element(ENABLE_NODE, &debug_pim_nht_rp_cmd);
6332 install_element(ENABLE_NODE, &no_debug_pim_nht_rp_cmd);
6333 install_element(ENABLE_NODE, &debug_pim_events_cmd);
6334 install_element(ENABLE_NODE, &debug_pim_packets_cmd);
6335 install_element(ENABLE_NODE, &debug_pim_packetdump_send_cmd);
6336 install_element(ENABLE_NODE, &debug_pim_packetdump_recv_cmd);
6337 install_element(ENABLE_NODE, &debug_pim_trace_cmd);
6338 install_element(ENABLE_NODE, &debug_pim_trace_detail_cmd);
6339 install_element(ENABLE_NODE, &debug_ssmpingd_cmd);
6340 install_element(ENABLE_NODE, &no_debug_ssmpingd_cmd);
6341 install_element(ENABLE_NODE, &debug_pim_zebra_cmd);
6342 install_element(ENABLE_NODE, &debug_pim_mlag_cmd);
6343 install_element(ENABLE_NODE, &no_debug_pim_mlag_cmd);
6344 install_element(ENABLE_NODE, &debug_pim_vxlan_cmd);
6345 install_element(ENABLE_NODE, &no_debug_pim_vxlan_cmd);
6346 install_element(ENABLE_NODE, &debug_msdp_cmd);
6347 install_element(ENABLE_NODE, &no_debug_msdp_cmd);
6348 install_element(ENABLE_NODE, &debug_msdp_events_cmd);
6349 install_element(ENABLE_NODE, &no_debug_msdp_events_cmd);
6350 install_element(ENABLE_NODE, &debug_msdp_packets_cmd);
6351 install_element(ENABLE_NODE, &no_debug_msdp_packets_cmd);
6352 install_element(ENABLE_NODE, &debug_mtrace_cmd);
6353 install_element(ENABLE_NODE, &no_debug_mtrace_cmd);
6354 install_element(ENABLE_NODE, &debug_bsm_cmd);
6355 install_element(ENABLE_NODE, &no_debug_bsm_cmd);
6356
6357 install_element(CONFIG_NODE, &debug_igmp_cmd);
6358 install_element(CONFIG_NODE, &no_debug_igmp_cmd);
6359 install_element(CONFIG_NODE, &debug_igmp_events_cmd);
6360 install_element(CONFIG_NODE, &no_debug_igmp_events_cmd);
6361 install_element(CONFIG_NODE, &debug_igmp_packets_cmd);
6362 install_element(CONFIG_NODE, &no_debug_igmp_packets_cmd);
6363 install_element(CONFIG_NODE, &debug_igmp_trace_cmd);
6364 install_element(CONFIG_NODE, &no_debug_igmp_trace_cmd);
6365 install_element(CONFIG_NODE, &debug_igmp_trace_detail_cmd);
6366 install_element(CONFIG_NODE, &no_debug_igmp_trace_detail_cmd);
6367 install_element(CONFIG_NODE, &debug_mroute_cmd);
6368 install_element(CONFIG_NODE, &debug_mroute_detail_cmd);
6369 install_element(CONFIG_NODE, &no_debug_mroute_cmd);
6370 install_element(CONFIG_NODE, &no_debug_mroute_detail_cmd);
6371 install_element(CONFIG_NODE, &debug_pim_static_cmd);
6372 install_element(CONFIG_NODE, &no_debug_pim_static_cmd);
6373 install_element(CONFIG_NODE, &debug_pim_cmd);
6374 install_element(CONFIG_NODE, &debug_pim_nht_cmd);
6375 install_element(CONFIG_NODE, &debug_pim_nht_det_cmd);
6376 install_element(CONFIG_NODE, &debug_pim_nht_rp_cmd);
6377 install_element(CONFIG_NODE, &no_debug_pim_nht_rp_cmd);
6378 install_element(CONFIG_NODE, &debug_pim_events_cmd);
6379 install_element(CONFIG_NODE, &debug_pim_packets_cmd);
6380 install_element(CONFIG_NODE, &debug_pim_packetdump_send_cmd);
6381 install_element(CONFIG_NODE, &debug_pim_packetdump_recv_cmd);
6382 install_element(CONFIG_NODE, &debug_pim_trace_cmd);
6383 install_element(CONFIG_NODE, &debug_pim_trace_detail_cmd);
6384 install_element(CONFIG_NODE, &debug_ssmpingd_cmd);
6385 install_element(CONFIG_NODE, &no_debug_ssmpingd_cmd);
6386 install_element(CONFIG_NODE, &debug_pim_zebra_cmd);
6387 install_element(CONFIG_NODE, &debug_pim_mlag_cmd);
6388 install_element(CONFIG_NODE, &no_debug_pim_mlag_cmd);
6389 install_element(CONFIG_NODE, &debug_pim_vxlan_cmd);
6390 install_element(CONFIG_NODE, &no_debug_pim_vxlan_cmd);
6391 install_element(CONFIG_NODE, &debug_msdp_cmd);
6392 install_element(CONFIG_NODE, &no_debug_msdp_cmd);
6393 install_element(CONFIG_NODE, &debug_msdp_events_cmd);
6394 install_element(CONFIG_NODE, &no_debug_msdp_events_cmd);
6395 install_element(CONFIG_NODE, &debug_msdp_packets_cmd);
6396 install_element(CONFIG_NODE, &no_debug_msdp_packets_cmd);
6397 install_element(CONFIG_NODE, &debug_mtrace_cmd);
6398 install_element(CONFIG_NODE, &no_debug_mtrace_cmd);
6399 install_element(CONFIG_NODE, &debug_bsm_cmd);
6400 install_element(CONFIG_NODE, &no_debug_bsm_cmd);
6401
6402 install_element(CONFIG_NODE, &ip_msdp_timers_cmd);
6403 install_element(VRF_NODE, &ip_msdp_timers_cmd);
6404 install_element(CONFIG_NODE, &no_ip_msdp_timers_cmd);
6405 install_element(VRF_NODE, &no_ip_msdp_timers_cmd);
6406 install_element(CONFIG_NODE, &ip_msdp_mesh_group_member_cmd);
6407 install_element(VRF_NODE, &ip_msdp_mesh_group_member_cmd);
6408 install_element(CONFIG_NODE, &no_ip_msdp_mesh_group_member_cmd);
6409 install_element(VRF_NODE, &no_ip_msdp_mesh_group_member_cmd);
6410 install_element(CONFIG_NODE, &ip_msdp_mesh_group_source_cmd);
6411 install_element(VRF_NODE, &ip_msdp_mesh_group_source_cmd);
6412 install_element(CONFIG_NODE, &no_ip_msdp_mesh_group_source_cmd);
6413 install_element(VRF_NODE, &no_ip_msdp_mesh_group_source_cmd);
6414 install_element(CONFIG_NODE, &no_ip_msdp_mesh_group_cmd);
6415 install_element(VRF_NODE, &no_ip_msdp_mesh_group_cmd);
6416 install_element(VIEW_NODE, &show_ip_msdp_peer_detail_cmd);
6417 install_element(VIEW_NODE, &show_ip_msdp_peer_detail_vrf_all_cmd);
6418 install_element(VIEW_NODE, &show_ip_msdp_sa_detail_cmd);
6419 install_element(VIEW_NODE, &show_ip_msdp_sa_detail_vrf_all_cmd);
6420 install_element(VIEW_NODE, &show_ip_msdp_sa_sg_cmd);
6421 install_element(VIEW_NODE, &show_ip_msdp_sa_sg_vrf_all_cmd);
6422 install_element(VIEW_NODE, &show_ip_msdp_mesh_group_cmd);
6423 install_element(VIEW_NODE, &show_ip_msdp_mesh_group_vrf_all_cmd);
6424 install_element(VIEW_NODE, &show_ip_pim_ssm_range_cmd);
6425 install_element(VIEW_NODE, &show_ip_pim_group_type_cmd);
6426 install_element(VIEW_NODE, &show_ip_pim_vxlan_sg_cmd);
6427 install_element(VIEW_NODE, &show_ip_pim_vxlan_sg_work_cmd);
6428 install_element(INTERFACE_NODE, &interface_pim_use_source_cmd);
6429 install_element(INTERFACE_NODE, &interface_no_pim_use_source_cmd);
6430 /* Install BSM command */
6431 install_element(INTERFACE_NODE, &ip_pim_bsm_cmd);
6432 install_element(INTERFACE_NODE, &no_ip_pim_bsm_cmd);
6433 install_element(INTERFACE_NODE, &ip_pim_ucast_bsm_cmd);
6434 install_element(INTERFACE_NODE, &no_ip_pim_ucast_bsm_cmd);
6435 /* Install BFD command */
6436 install_element(INTERFACE_NODE, &ip_pim_bfd_cmd);
6437 install_element(INTERFACE_NODE, &ip_pim_bfd_param_cmd);
6438 install_element(INTERFACE_NODE, &no_ip_pim_bfd_profile_cmd);
6439 install_element(INTERFACE_NODE, &no_ip_pim_bfd_cmd);
6440 #if HAVE_BFDD == 0
6441 install_element(INTERFACE_NODE, &no_ip_pim_bfd_param_cmd);
6442 #endif /* !HAVE_BFDD */
6443 }