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