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