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