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