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