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