3 * Copyright (C) 2008 Everton da Silva Marques
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.
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.
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
34 #include "pim_mroute.h"
36 #include "pim_iface.h"
38 #include "pim_mroute.h"
41 #include "pim_igmpv3.h"
46 #include "pim_neighbor.h"
48 #include "pim_ifchannel.h"
49 #include "pim_hello.h"
51 #include "pim_upstream.h"
53 #include "pim_macro.h"
54 #include "pim_ssmpingd.h"
55 #include "pim_zebra.h"
56 #include "pim_static.h"
58 #include "pim_zlookup.h"
63 #include "pim_vxlan.h"
67 #include "lib/northbound_cli.h"
68 #include "pim_errors.h"
71 #ifndef VTYSH_EXTRACT_PL
72 #include "pimd/pim_cmd_clippy.c"
75 static struct cmd_node debug_node
= {
79 .config_write
= pim_debug_config_write
,
82 static struct vrf
*pim_cmd_lookup_vrf(struct vty
*vty
, struct cmd_token
*argv
[],
83 const int argc
, int *idx
)
87 if (argv_find(argv
, argc
, "NAME", idx
))
88 vrf
= vrf_lookup_by_name(argv
[*idx
]->arg
);
90 vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
93 vty_out(vty
, "Specified VRF: %s does not exist\n",
99 static void pim_show_assert_helper(struct vty
*vty
,
100 struct pim_interface
*pim_ifp
,
101 struct pim_ifchannel
*ch
, time_t now
)
103 char ch_src_str
[INET_ADDRSTRLEN
];
104 char ch_grp_str
[INET_ADDRSTRLEN
];
105 char winner_str
[INET_ADDRSTRLEN
];
106 struct in_addr ifaddr
;
109 char buf
[PREFIX_STRLEN
];
111 ifaddr
= pim_ifp
->primary_address
;
113 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
114 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
115 pim_inet4_dump("<assrt_win?>", ch
->ifassert_winner
, winner_str
,
118 pim_time_uptime(uptime
, sizeof(uptime
), now
- ch
->ifassert_creation
);
119 pim_time_timer_to_mmss(timer
, sizeof(timer
), ch
->t_ifassert_timer
);
121 vty_out(vty
, "%-16s %-15s %-15s %-15s %-6s %-15s %-8s %-5s\n",
123 inet_ntop(AF_INET
, &ifaddr
, buf
, sizeof(buf
)), ch_src_str
,
124 ch_grp_str
, pim_ifchannel_ifassert_name(ch
->ifassert_state
),
125 winner_str
, uptime
, timer
);
128 static void pim_show_assert(struct pim_instance
*pim
, struct vty
*vty
)
130 struct pim_interface
*pim_ifp
;
131 struct pim_ifchannel
*ch
;
132 struct interface
*ifp
;
135 now
= pim_time_monotonic_sec();
138 "Interface Address Source Group State Winner Uptime Timer\n");
140 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
145 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
146 pim_show_assert_helper(vty
, pim_ifp
, ch
, now
);
147 } /* scan interface channels */
151 static void pim_show_assert_internal_helper(struct vty
*vty
,
152 struct pim_interface
*pim_ifp
,
153 struct pim_ifchannel
*ch
)
155 char ch_src_str
[INET_ADDRSTRLEN
];
156 char ch_grp_str
[INET_ADDRSTRLEN
];
157 struct in_addr ifaddr
;
158 char buf
[PREFIX_STRLEN
];
160 ifaddr
= pim_ifp
->primary_address
;
162 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
163 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
164 vty_out(vty
, "%-16s %-15s %-15s %-15s %-3s %-3s %-3s %-4s\n",
166 inet_ntop(AF_INET
, &ifaddr
, buf
, sizeof(buf
)),
167 ch_src_str
, ch_grp_str
,
168 PIM_IF_FLAG_TEST_COULD_ASSERT(ch
->flags
) ? "yes" : "no",
169 pim_macro_ch_could_assert_eval(ch
) ? "yes" : "no",
170 PIM_IF_FLAG_TEST_ASSERT_TRACKING_DESIRED(ch
->flags
) ? "yes"
172 pim_macro_assert_tracking_desired_eval(ch
) ? "yes" : "no");
175 static void pim_show_assert_internal(struct pim_instance
*pim
, struct vty
*vty
)
177 struct pim_interface
*pim_ifp
;
178 struct pim_ifchannel
*ch
;
179 struct interface
*ifp
;
183 "ECA: Evaluate CouldAssert\n"
184 "ATD: AssertTrackingDesired\n"
185 "eATD: Evaluate AssertTrackingDesired\n\n");
188 "Interface Address Source Group CA eCA ATD eATD\n");
189 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
194 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
195 pim_show_assert_internal_helper(vty
, pim_ifp
, ch
);
196 } /* scan interface channels */
200 static void pim_show_assert_metric_helper(struct vty
*vty
,
201 struct pim_interface
*pim_ifp
,
202 struct pim_ifchannel
*ch
)
204 char ch_src_str
[INET_ADDRSTRLEN
];
205 char ch_grp_str
[INET_ADDRSTRLEN
];
206 char addr_str
[INET_ADDRSTRLEN
];
207 struct pim_assert_metric am
;
208 struct in_addr ifaddr
;
209 char buf
[PREFIX_STRLEN
];
211 ifaddr
= pim_ifp
->primary_address
;
213 am
= pim_macro_spt_assert_metric(&ch
->upstream
->rpf
,
214 pim_ifp
->primary_address
);
216 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
217 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
218 pim_inet4_dump("<addr?>", am
.ip_address
, addr_str
, sizeof(addr_str
));
220 vty_out(vty
, "%-16s %-15s %-15s %-15s %-3s %4u %6u %-15s\n",
222 inet_ntop(AF_INET
, &ifaddr
, buf
, sizeof(buf
)),
223 ch_src_str
, ch_grp_str
, am
.rpt_bit_flag
? "yes" : "no",
224 am
.metric_preference
, am
.route_metric
, addr_str
);
227 static void pim_show_assert_metric(struct pim_instance
*pim
, struct vty
*vty
)
229 struct pim_interface
*pim_ifp
;
230 struct pim_ifchannel
*ch
;
231 struct interface
*ifp
;
234 "Interface Address Source Group RPT Pref Metric Address \n");
236 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
241 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
242 pim_show_assert_metric_helper(vty
, pim_ifp
, ch
);
243 } /* scan interface channels */
247 static void pim_show_assert_winner_metric_helper(struct vty
*vty
,
248 struct pim_interface
*pim_ifp
,
249 struct pim_ifchannel
*ch
)
251 char ch_src_str
[INET_ADDRSTRLEN
];
252 char ch_grp_str
[INET_ADDRSTRLEN
];
253 char addr_str
[INET_ADDRSTRLEN
];
254 struct pim_assert_metric
*am
;
255 struct in_addr ifaddr
;
258 char buf
[PREFIX_STRLEN
];
260 ifaddr
= pim_ifp
->primary_address
;
262 am
= &ch
->ifassert_winner_metric
;
264 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
265 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
266 pim_inet4_dump("<addr?>", am
->ip_address
, addr_str
, sizeof(addr_str
));
268 if (am
->metric_preference
== PIM_ASSERT_METRIC_PREFERENCE_MAX
)
269 snprintf(pref_str
, sizeof(pref_str
), "INFI");
271 snprintf(pref_str
, sizeof(pref_str
), "%4u",
272 am
->metric_preference
);
274 if (am
->route_metric
== PIM_ASSERT_ROUTE_METRIC_MAX
)
275 snprintf(metr_str
, sizeof(metr_str
), "INFI");
277 snprintf(metr_str
, sizeof(metr_str
), "%6u", am
->route_metric
);
279 vty_out(vty
, "%-16s %-15s %-15s %-15s %-3s %-4s %-6s %-15s\n",
281 inet_ntop(AF_INET
, &ifaddr
, buf
, sizeof(buf
)), ch_src_str
,
282 ch_grp_str
, am
->rpt_bit_flag
? "yes" : "no", pref_str
, metr_str
,
286 static void pim_show_assert_winner_metric(struct pim_instance
*pim
,
289 struct pim_interface
*pim_ifp
;
290 struct pim_ifchannel
*ch
;
291 struct interface
*ifp
;
294 "Interface Address Source Group RPT Pref Metric Address \n");
296 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
301 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
302 pim_show_assert_winner_metric_helper(vty
, pim_ifp
, ch
);
303 } /* scan interface channels */
307 static void json_object_pim_ifp_add(struct json_object
*json
,
308 struct interface
*ifp
)
310 struct pim_interface
*pim_ifp
;
311 char buf
[PREFIX_STRLEN
];
314 json_object_string_add(json
, "name", ifp
->name
);
315 json_object_string_add(json
, "state", if_is_up(ifp
) ? "up" : "down");
316 json_object_string_add(json
, "address",
317 inet_ntop(AF_INET
, &pim_ifp
->primary_address
,
319 json_object_int_add(json
, "index", ifp
->ifindex
);
321 if (if_is_multicast(ifp
))
322 json_object_boolean_true_add(json
, "flagMulticast");
324 if (if_is_broadcast(ifp
))
325 json_object_boolean_true_add(json
, "flagBroadcast");
327 if (ifp
->flags
& IFF_ALLMULTI
)
328 json_object_boolean_true_add(json
, "flagAllMulticast");
330 if (ifp
->flags
& IFF_PROMISC
)
331 json_object_boolean_true_add(json
, "flagPromiscuous");
333 if (PIM_IF_IS_DELETED(ifp
))
334 json_object_boolean_true_add(json
, "flagDeleted");
336 if (pim_if_lan_delay_enabled(ifp
))
337 json_object_boolean_true_add(json
, "lanDelayEnabled");
340 static void pim_show_membership_helper(struct vty
*vty
,
341 struct pim_interface
*pim_ifp
,
342 struct pim_ifchannel
*ch
,
343 struct json_object
*json
)
345 char ch_src_str
[INET_ADDRSTRLEN
];
346 char ch_grp_str
[INET_ADDRSTRLEN
];
347 json_object
*json_iface
= NULL
;
348 json_object
*json_row
= NULL
;
350 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
351 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
353 json_object_object_get_ex(json
, ch
->interface
->name
, &json_iface
);
355 json_iface
= json_object_new_object();
356 json_object_pim_ifp_add(json_iface
, ch
->interface
);
357 json_object_object_add(json
, ch
->interface
->name
, json_iface
);
360 json_row
= json_object_new_object();
361 json_object_string_add(json_row
, "source", ch_src_str
);
362 json_object_string_add(json_row
, "group", ch_grp_str
);
363 json_object_string_add(json_row
, "localMembership",
364 ch
->local_ifmembership
== PIM_IFMEMBERSHIP_NOINFO
367 json_object_object_add(json_iface
, ch_grp_str
, json_row
);
369 static void pim_show_membership(struct pim_instance
*pim
, struct vty
*vty
,
372 struct pim_interface
*pim_ifp
;
373 struct pim_ifchannel
*ch
;
374 struct interface
*ifp
;
376 json_object
*json
= NULL
;
377 json_object
*json_tmp
= NULL
;
379 json
= json_object_new_object();
381 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
386 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
387 pim_show_membership_helper(vty
, pim_ifp
, ch
, json
);
388 } /* scan interface channels */
392 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
393 json
, JSON_C_TO_STRING_PRETTY
));
396 "Interface Address Source Group Membership\n");
399 * Example of the json data we are traversing
405 * "address":"10.1.20.1",
407 * "flagMulticast":true,
408 * "flagBroadcast":true,
409 * "lanDelayEnabled":true,
412 * "group":"226.10.10.10",
413 * "localMembership":"INCLUDE"
419 /* foreach interface */
420 json_object_object_foreach(json
, key
, val
)
423 /* Find all of the keys where the val is an object. In
425 * above the only one is 226.10.10.10
427 json_object_object_foreach(val
, if_field_key
,
430 type
= json_object_get_type(if_field_val
);
432 if (type
== json_type_object
) {
433 vty_out(vty
, "%-16s ", key
);
435 json_object_object_get_ex(
436 val
, "address", &json_tmp
);
437 vty_out(vty
, "%-15s ",
438 json_object_get_string(
441 json_object_object_get_ex(if_field_val
,
444 vty_out(vty
, "%-15s ",
445 json_object_get_string(
449 vty_out(vty
, "%-15s ", if_field_key
);
451 json_object_object_get_ex(
452 if_field_val
, "localMembership",
454 vty_out(vty
, "%-10s\n",
455 json_object_get_string(
462 json_object_free(json
);
465 static void pim_print_ifp_flags(struct vty
*vty
, struct interface
*ifp
,
468 vty_out(vty
, "Flags\n");
469 vty_out(vty
, "-----\n");
470 vty_out(vty
, "All Multicast : %s\n",
471 (ifp
->flags
& IFF_ALLMULTI
) ? "yes" : "no");
472 vty_out(vty
, "Broadcast : %s\n",
473 if_is_broadcast(ifp
) ? "yes" : "no");
474 vty_out(vty
, "Deleted : %s\n",
475 PIM_IF_IS_DELETED(ifp
) ? "yes" : "no");
476 vty_out(vty
, "Interface Index : %d\n", ifp
->ifindex
);
477 vty_out(vty
, "Multicast : %s\n",
478 if_is_multicast(ifp
) ? "yes" : "no");
479 vty_out(vty
, "Multicast Loop : %d\n", mloop
);
480 vty_out(vty
, "Promiscuous : %s\n",
481 (ifp
->flags
& IFF_PROMISC
) ? "yes" : "no");
486 static void igmp_show_interfaces(struct pim_instance
*pim
, struct vty
*vty
,
489 struct interface
*ifp
;
491 char buf
[PREFIX_STRLEN
];
492 char quer_buf
[PREFIX_STRLEN
];
493 json_object
*json
= NULL
;
494 json_object
*json_row
= NULL
;
496 now
= pim_time_monotonic_sec();
499 json
= json_object_new_object();
502 "Interface State Address V Querier QuerierIp Query Timer Uptime\n");
504 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
505 struct pim_interface
*pim_ifp
;
506 struct listnode
*sock_node
;
507 struct igmp_sock
*igmp
;
514 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
517 char query_hhmmss
[10];
519 pim_time_uptime(uptime
, sizeof(uptime
),
520 now
- igmp
->sock_creation
);
521 pim_time_timer_to_hhmmss(query_hhmmss
,
522 sizeof(query_hhmmss
),
523 igmp
->t_igmp_query_timer
);
526 json_row
= json_object_new_object();
527 json_object_pim_ifp_add(json_row
, ifp
);
528 json_object_string_add(json_row
, "upTime",
530 json_object_int_add(json_row
, "version",
531 pim_ifp
->igmp_version
);
533 if (igmp
->t_igmp_query_timer
) {
534 json_object_boolean_true_add(json_row
,
536 json_object_string_add(json_row
,
540 json_object_string_add(
541 json_row
, "querierIp",
542 inet_ntop(AF_INET
, &igmp
->querier_addr
,
543 quer_buf
, sizeof(quer_buf
)));
545 json_object_object_add(json
, ifp
->name
,
548 if (igmp
->mtrace_only
) {
549 json_object_boolean_true_add(
550 json_row
, "mtraceOnly");
554 "%-16s %5s %15s %d %7s %17pI4 %11s %8s\n",
557 ? (igmp
->mtrace_only
? "mtrc"
560 inet_ntop(AF_INET
, &igmp
->ifaddr
, buf
,
562 pim_ifp
->igmp_version
,
563 igmp
->t_igmp_query_timer
? "local"
565 &igmp
->querier_addr
, query_hhmmss
,
572 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
573 json
, JSON_C_TO_STRING_PRETTY
));
574 json_object_free(json
);
578 static void igmp_show_interfaces_single(struct pim_instance
*pim
,
579 struct vty
*vty
, const char *ifname
,
582 struct igmp_sock
*igmp
;
583 struct interface
*ifp
;
584 struct listnode
*sock_node
;
585 struct pim_interface
*pim_ifp
;
587 char quer_buf
[PREFIX_STRLEN
];
588 char query_hhmmss
[10];
589 char other_hhmmss
[10];
590 int found_ifname
= 0;
593 long gmi_msec
; /* Group Membership Interval */
596 long oqpi_msec
; /* Other Querier Present Interval */
601 json_object
*json
= NULL
;
602 json_object
*json_row
= NULL
;
605 json
= json_object_new_object();
607 now
= pim_time_monotonic_sec();
609 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
615 if (strcmp(ifname
, "detail") && strcmp(ifname
, ifp
->name
))
618 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
621 pim_time_uptime(uptime
, sizeof(uptime
),
622 now
- igmp
->sock_creation
);
623 pim_time_timer_to_hhmmss(query_hhmmss
,
624 sizeof(query_hhmmss
),
625 igmp
->t_igmp_query_timer
);
626 pim_time_timer_to_hhmmss(other_hhmmss
,
627 sizeof(other_hhmmss
),
628 igmp
->t_other_querier_timer
);
630 gmi_msec
= PIM_IGMP_GMI_MSEC(
631 igmp
->querier_robustness_variable
,
632 igmp
->querier_query_interval
,
633 pim_ifp
->igmp_query_max_response_time_dsec
);
636 pim_ifp
->igmp_default_query_interval
);
638 oqpi_msec
= PIM_IGMP_OQPI_MSEC(
639 igmp
->querier_robustness_variable
,
640 igmp
->querier_query_interval
,
641 pim_ifp
->igmp_query_max_response_time_dsec
);
643 lmqt_msec
= PIM_IGMP_LMQT_MSEC(
644 pim_ifp
->igmp_specific_query_max_response_time_dsec
,
645 pim_ifp
->igmp_last_member_query_count
);
649 igmp
->querier_robustness_variable
,
650 igmp
->querier_query_interval
,
651 pim_ifp
->igmp_query_max_response_time_dsec
)
654 qri_msec
= pim_ifp
->igmp_query_max_response_time_dsec
656 if (pim_ifp
->pim_sock_fd
>= 0)
657 mloop
= pim_socket_mcastloop_get(
658 pim_ifp
->pim_sock_fd
);
661 lmqc
= pim_ifp
->igmp_last_member_query_count
;
664 json_row
= json_object_new_object();
665 json_object_pim_ifp_add(json_row
, ifp
);
666 json_object_string_add(json_row
, "upTime",
668 json_object_string_add(json_row
, "querier",
669 igmp
->t_igmp_query_timer
672 json_object_string_add(
673 json_row
, "querierIp",
674 inet_ntop(AF_INET
, &igmp
->querier_addr
,
675 quer_buf
, sizeof(quer_buf
)));
676 json_object_int_add(json_row
, "queryStartCount",
677 igmp
->startup_query_count
);
678 json_object_string_add(json_row
,
681 json_object_string_add(json_row
,
684 json_object_int_add(json_row
, "version",
685 pim_ifp
->igmp_version
);
688 "timerGroupMembershipIntervalMsec",
690 json_object_int_add(json_row
,
691 "lastMemberQueryCount",
693 json_object_int_add(json_row
,
694 "timerLastMemberQueryMsec",
698 "timerOlderHostPresentIntervalMsec",
702 "timerOtherQuerierPresentIntervalMsec",
705 json_row
, "timerQueryInterval",
706 igmp
->querier_query_interval
);
709 "timerQueryResponseIntervalMsec",
712 json_row
, "timerRobustnessVariable",
713 igmp
->querier_robustness_variable
);
714 json_object_int_add(json_row
,
715 "timerStartupQueryInterval",
718 json_object_object_add(json
, ifp
->name
,
721 if (igmp
->mtrace_only
) {
722 json_object_boolean_true_add(
723 json_row
, "mtraceOnly");
726 vty_out(vty
, "Interface : %s\n", ifp
->name
);
727 vty_out(vty
, "State : %s\n",
728 if_is_up(ifp
) ? (igmp
->mtrace_only
?
732 vty_out(vty
, "Address : %pI4\n",
733 &pim_ifp
->primary_address
);
734 vty_out(vty
, "Uptime : %s\n", uptime
);
735 vty_out(vty
, "Version : %d\n",
736 pim_ifp
->igmp_version
);
740 vty_out(vty
, "Querier\n");
741 vty_out(vty
, "-------\n");
742 vty_out(vty
, "Querier : %s\n",
743 igmp
->t_igmp_query_timer
? "local"
745 vty_out(vty
, "QuerierIp : %pI4",
746 &igmp
->querier_addr
);
747 if (pim_ifp
->primary_address
.s_addr
748 == igmp
->querier_addr
.s_addr
)
749 vty_out(vty
, " (this router)\n");
753 vty_out(vty
, "Start Count : %d\n",
754 igmp
->startup_query_count
);
755 vty_out(vty
, "Query Timer : %s\n",
757 vty_out(vty
, "Other Timer : %s\n",
762 vty_out(vty
, "Timers\n");
763 vty_out(vty
, "------\n");
765 "Group Membership Interval : %lis\n",
768 "Last Member Query Count : %d\n",
771 "Last Member Query Time : %lis\n",
774 "Older Host Present Interval : %lis\n",
777 "Other Querier Present Interval : %lis\n",
780 "Query Interval : %ds\n",
781 igmp
->querier_query_interval
);
783 "Query Response Interval : %lis\n",
786 "Robustness Variable : %d\n",
787 igmp
->querier_robustness_variable
);
789 "Startup Query Interval : %ds\n",
794 pim_print_ifp_flags(vty
, ifp
, mloop
);
800 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
801 json
, JSON_C_TO_STRING_PRETTY
));
802 json_object_free(json
);
805 vty_out(vty
, "%% No such interface\n");
809 static void igmp_show_interface_join(struct pim_instance
*pim
, struct vty
*vty
,
812 struct interface
*ifp
;
814 json_object
*json
= NULL
;
815 json_object
*json_iface
= NULL
;
816 json_object
*json_grp
= NULL
;
817 json_object
*json_grp_arr
= NULL
;
819 now
= pim_time_monotonic_sec();
822 json
= json_object_new_object();
823 json_object_string_add(json
, "vrf",
824 vrf_id_to_name(pim
->vrf
->vrf_id
));
827 "Interface Address Source Group Socket Uptime \n");
830 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
831 struct pim_interface
*pim_ifp
;
832 struct listnode
*join_node
;
833 struct igmp_join
*ij
;
834 struct in_addr pri_addr
;
835 char pri_addr_str
[INET_ADDRSTRLEN
];
842 if (!pim_ifp
->igmp_join_list
)
845 pri_addr
= pim_find_primary_addr(ifp
);
846 pim_inet4_dump("<pri?>", pri_addr
, pri_addr_str
,
847 sizeof(pri_addr_str
));
849 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_join_list
, join_node
,
851 char group_str
[INET_ADDRSTRLEN
];
852 char source_str
[INET_ADDRSTRLEN
];
855 pim_time_uptime(uptime
, sizeof(uptime
),
856 now
- ij
->sock_creation
);
857 pim_inet4_dump("<grp?>", ij
->group_addr
, group_str
,
859 pim_inet4_dump("<src?>", ij
->source_addr
, source_str
,
863 json_object_object_get_ex(json
, ifp
->name
,
867 json_iface
= json_object_new_object();
868 json_object_string_add(
869 json_iface
, "name", ifp
->name
);
870 json_object_object_add(json
, ifp
->name
,
872 json_grp_arr
= json_object_new_array();
873 json_object_object_add(json_iface
,
878 json_grp
= json_object_new_object();
879 json_object_string_add(json_grp
, "source",
881 json_object_string_add(json_grp
, "group",
883 json_object_string_add(json_grp
, "primaryAddr",
885 json_object_int_add(json_grp
, "sockFd",
887 json_object_string_add(json_grp
, "upTime",
889 json_object_array_add(json_grp_arr
, json_grp
);
892 "%-16s %-15s %-15s %-15s %6d %8s\n",
893 ifp
->name
, pri_addr_str
, source_str
,
894 group_str
, ij
->sock_fd
, uptime
);
896 } /* for (pim_ifp->igmp_join_list) */
901 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
902 json
, JSON_C_TO_STRING_PRETTY
));
903 json_object_free(json
);
907 static void pim_show_interfaces_single(struct pim_instance
*pim
,
908 struct vty
*vty
, const char *ifname
,
911 struct in_addr ifaddr
;
912 struct interface
*ifp
;
913 struct listnode
*neighnode
;
914 struct pim_interface
*pim_ifp
;
915 struct pim_neighbor
*neigh
;
916 struct pim_upstream
*up
;
918 char dr_str
[INET_ADDRSTRLEN
];
921 char grp_str
[INET_ADDRSTRLEN
];
922 char hello_period
[10];
923 char hello_timer
[10];
924 char neigh_src_str
[INET_ADDRSTRLEN
];
925 char src_str
[INET_ADDRSTRLEN
];
926 char stat_uptime
[10];
929 int found_ifname
= 0;
931 char buf
[PREFIX_STRLEN
];
932 json_object
*json
= NULL
;
933 json_object
*json_row
= NULL
;
934 json_object
*json_pim_neighbor
= NULL
;
935 json_object
*json_pim_neighbors
= NULL
;
936 json_object
*json_group
= NULL
;
937 json_object
*json_group_source
= NULL
;
938 json_object
*json_fhr_sources
= NULL
;
939 struct pim_secondary_addr
*sec_addr
;
940 struct listnode
*sec_node
;
942 now
= pim_time_monotonic_sec();
945 json
= json_object_new_object();
947 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
953 if (mlag
== true && pim_ifp
->activeactive
== false)
956 if (strcmp(ifname
, "detail") && strcmp(ifname
, ifp
->name
))
960 ifaddr
= pim_ifp
->primary_address
;
961 pim_inet4_dump("<dr?>", pim_ifp
->pim_dr_addr
, dr_str
,
963 pim_time_uptime_begin(dr_uptime
, sizeof(dr_uptime
), now
,
964 pim_ifp
->pim_dr_election_last
);
965 pim_time_timer_to_hhmmss(hello_timer
, sizeof(hello_timer
),
966 pim_ifp
->t_pim_hello_timer
);
967 pim_time_mmss(hello_period
, sizeof(hello_period
),
968 pim_ifp
->pim_hello_period
);
969 pim_time_uptime(stat_uptime
, sizeof(stat_uptime
),
970 now
- pim_ifp
->pim_ifstat_start
);
971 if (pim_ifp
->pim_sock_fd
>= 0)
972 mloop
= pim_socket_mcastloop_get(pim_ifp
->pim_sock_fd
);
977 char pbuf
[PREFIX2STR_BUFFER
];
978 json_row
= json_object_new_object();
979 json_object_pim_ifp_add(json_row
, ifp
);
981 if (pim_ifp
->update_source
.s_addr
!= INADDR_ANY
) {
982 json_object_string_add(
983 json_row
, "useSource",
985 &pim_ifp
->update_source
,
988 if (pim_ifp
->sec_addr_list
) {
989 json_object
*sec_list
= NULL
;
991 sec_list
= json_object_new_array();
992 for (ALL_LIST_ELEMENTS_RO(
993 pim_ifp
->sec_addr_list
, sec_node
,
995 json_object_array_add(
997 json_object_new_string(
1003 json_object_object_add(json_row
,
1004 "secondaryAddressList",
1009 if (pim_ifp
->pim_neighbor_list
->count
) {
1010 json_pim_neighbors
= json_object_new_object();
1012 for (ALL_LIST_ELEMENTS_RO(
1013 pim_ifp
->pim_neighbor_list
,
1014 neighnode
, neigh
)) {
1016 json_object_new_object();
1017 pim_inet4_dump("<src?>",
1020 sizeof(neigh_src_str
));
1021 pim_time_uptime(uptime
, sizeof(uptime
),
1022 now
- neigh
->creation
);
1023 pim_time_timer_to_hhmmss(
1024 expire
, sizeof(expire
),
1025 neigh
->t_expire_timer
);
1027 json_object_string_add(
1028 json_pim_neighbor
, "address",
1030 json_object_string_add(
1031 json_pim_neighbor
, "upTime",
1033 json_object_string_add(
1034 json_pim_neighbor
, "holdtime",
1037 json_object_object_add(
1043 json_object_object_add(json_row
, "neighbors",
1044 json_pim_neighbors
);
1047 json_object_string_add(json_row
, "drAddress", dr_str
);
1048 json_object_int_add(json_row
, "drPriority",
1049 pim_ifp
->pim_dr_priority
);
1050 json_object_string_add(json_row
, "drUptime", dr_uptime
);
1051 json_object_int_add(json_row
, "drElections",
1052 pim_ifp
->pim_dr_election_count
);
1053 json_object_int_add(json_row
, "drChanges",
1054 pim_ifp
->pim_dr_election_changes
);
1057 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
1058 if (ifp
!= up
->rpf
.source_nexthop
.interface
)
1061 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
))
1064 if (!json_fhr_sources
)
1066 json_object_new_object();
1068 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
,
1070 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
,
1072 pim_time_uptime(uptime
, sizeof(uptime
),
1073 now
- up
->state_transition
);
1076 * Does this group live in json_fhr_sources?
1079 json_object_object_get_ex(json_fhr_sources
,
1080 grp_str
, &json_group
);
1083 json_group
= json_object_new_object();
1084 json_object_object_add(json_fhr_sources
,
1089 json_group_source
= json_object_new_object();
1090 json_object_string_add(json_group_source
,
1092 json_object_string_add(json_group_source
,
1094 json_object_string_add(json_group_source
,
1096 json_object_object_add(json_group
, src_str
,
1100 if (json_fhr_sources
) {
1101 json_object_object_add(json_row
,
1106 json_object_int_add(json_row
, "helloPeriod",
1107 pim_ifp
->pim_hello_period
);
1108 json_object_int_add(json_row
, "holdTime",
1109 PIM_IF_DEFAULT_HOLDTIME(pim_ifp
));
1110 json_object_string_add(json_row
, "helloTimer",
1112 json_object_string_add(json_row
, "helloStatStart",
1114 json_object_int_add(json_row
, "helloReceived",
1115 pim_ifp
->pim_ifstat_hello_recv
);
1116 json_object_int_add(json_row
, "helloReceivedFailed",
1117 pim_ifp
->pim_ifstat_hello_recvfail
);
1118 json_object_int_add(json_row
, "helloSend",
1119 pim_ifp
->pim_ifstat_hello_sent
);
1120 json_object_int_add(json_row
, "hellosendFailed",
1121 pim_ifp
->pim_ifstat_hello_sendfail
);
1122 json_object_int_add(json_row
, "helloGenerationId",
1123 pim_ifp
->pim_generation_id
);
1124 json_object_int_add(json_row
, "flagMulticastLoop",
1127 json_object_int_add(
1128 json_row
, "effectivePropagationDelay",
1129 pim_if_effective_propagation_delay_msec(ifp
));
1130 json_object_int_add(
1131 json_row
, "effectiveOverrideInterval",
1132 pim_if_effective_override_interval_msec(ifp
));
1133 json_object_int_add(
1134 json_row
, "joinPruneOverrideInterval",
1135 pim_if_jp_override_interval_msec(ifp
));
1137 json_object_int_add(
1138 json_row
, "propagationDelay",
1139 pim_ifp
->pim_propagation_delay_msec
);
1140 json_object_int_add(
1141 json_row
, "propagationDelayHighest",
1142 pim_ifp
->pim_neighbors_highest_propagation_delay_msec
);
1143 json_object_int_add(
1144 json_row
, "overrideInterval",
1145 pim_ifp
->pim_override_interval_msec
);
1146 json_object_int_add(
1147 json_row
, "overrideIntervalHighest",
1148 pim_ifp
->pim_neighbors_highest_override_interval_msec
);
1149 if (pim_ifp
->bsm_enable
)
1150 json_object_boolean_true_add(json_row
,
1152 if (pim_ifp
->ucast_bsm_accept
)
1153 json_object_boolean_true_add(json_row
,
1155 json_object_object_add(json
, ifp
->name
, json_row
);
1158 vty_out(vty
, "Interface : %s\n", ifp
->name
);
1159 vty_out(vty
, "State : %s\n",
1160 if_is_up(ifp
) ? "up" : "down");
1161 if (pim_ifp
->update_source
.s_addr
!= INADDR_ANY
) {
1162 vty_out(vty
, "Use Source : %pI4\n",
1163 &pim_ifp
->update_source
);
1165 if (pim_ifp
->sec_addr_list
) {
1166 vty_out(vty
, "Address : %pI4 (primary)\n",
1168 for (ALL_LIST_ELEMENTS_RO(
1169 pim_ifp
->sec_addr_list
, sec_node
,
1171 vty_out(vty
, " %pFX\n",
1174 vty_out(vty
, "Address : %pI4\n",
1182 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
,
1183 neighnode
, neigh
)) {
1186 vty_out(vty
, "PIM Neighbors\n");
1187 vty_out(vty
, "-------------\n");
1191 pim_inet4_dump("<src?>", neigh
->source_addr
,
1193 sizeof(neigh_src_str
));
1194 pim_time_uptime(uptime
, sizeof(uptime
),
1195 now
- neigh
->creation
);
1196 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
1197 neigh
->t_expire_timer
);
1199 "%-15s : up for %s, holdtime expires in %s\n",
1200 neigh_src_str
, uptime
, expire
);
1203 if (!print_header
) {
1208 vty_out(vty
, "Designated Router\n");
1209 vty_out(vty
, "-----------------\n");
1210 vty_out(vty
, "Address : %s\n", dr_str
);
1211 vty_out(vty
, "Priority : %u(%d)\n",
1212 pim_ifp
->pim_dr_priority
,
1213 pim_ifp
->pim_dr_num_nondrpri_neighbors
);
1214 vty_out(vty
, "Uptime : %s\n", dr_uptime
);
1215 vty_out(vty
, "Elections : %d\n",
1216 pim_ifp
->pim_dr_election_count
);
1217 vty_out(vty
, "Changes : %d\n",
1218 pim_ifp
->pim_dr_election_changes
);
1224 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
1225 if (!up
->rpf
.source_nexthop
.interface
)
1228 if (strcmp(ifp
->name
,
1229 up
->rpf
.source_nexthop
1234 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
))
1239 "FHR - First Hop Router\n");
1241 "----------------------\n");
1245 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
,
1247 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
,
1249 pim_time_uptime(uptime
, sizeof(uptime
),
1250 now
- up
->state_transition
);
1252 "%s : %s is a source, uptime is %s\n",
1253 grp_str
, src_str
, uptime
);
1256 if (!print_header
) {
1261 vty_out(vty
, "Hellos\n");
1262 vty_out(vty
, "------\n");
1263 vty_out(vty
, "Period : %d\n",
1264 pim_ifp
->pim_hello_period
);
1265 vty_out(vty
, "HoldTime : %d\n",
1266 PIM_IF_DEFAULT_HOLDTIME(pim_ifp
));
1267 vty_out(vty
, "Timer : %s\n", hello_timer
);
1268 vty_out(vty
, "StatStart : %s\n", stat_uptime
);
1269 vty_out(vty
, "Receive : %d\n",
1270 pim_ifp
->pim_ifstat_hello_recv
);
1271 vty_out(vty
, "Receive Failed : %d\n",
1272 pim_ifp
->pim_ifstat_hello_recvfail
);
1273 vty_out(vty
, "Send : %d\n",
1274 pim_ifp
->pim_ifstat_hello_sent
);
1275 vty_out(vty
, "Send Failed : %d\n",
1276 pim_ifp
->pim_ifstat_hello_sendfail
);
1277 vty_out(vty
, "Generation ID : %08x\n",
1278 pim_ifp
->pim_generation_id
);
1282 pim_print_ifp_flags(vty
, ifp
, mloop
);
1284 vty_out(vty
, "Join Prune Interval\n");
1285 vty_out(vty
, "-------------------\n");
1286 vty_out(vty
, "LAN Delay : %s\n",
1287 pim_if_lan_delay_enabled(ifp
) ? "yes" : "no");
1288 vty_out(vty
, "Effective Propagation Delay : %d msec\n",
1289 pim_if_effective_propagation_delay_msec(ifp
));
1290 vty_out(vty
, "Effective Override Interval : %d msec\n",
1291 pim_if_effective_override_interval_msec(ifp
));
1292 vty_out(vty
, "Join Prune Override Interval : %d msec\n",
1293 pim_if_jp_override_interval_msec(ifp
));
1297 vty_out(vty
, "LAN Prune Delay\n");
1298 vty_out(vty
, "---------------\n");
1299 vty_out(vty
, "Propagation Delay : %d msec\n",
1300 pim_ifp
->pim_propagation_delay_msec
);
1301 vty_out(vty
, "Propagation Delay (Highest) : %d msec\n",
1302 pim_ifp
->pim_neighbors_highest_propagation_delay_msec
);
1303 vty_out(vty
, "Override Interval : %d msec\n",
1304 pim_ifp
->pim_override_interval_msec
);
1305 vty_out(vty
, "Override Interval (Highest) : %d msec\n",
1306 pim_ifp
->pim_neighbors_highest_override_interval_msec
);
1310 vty_out(vty
, "BSM Status\n");
1311 vty_out(vty
, "----------\n");
1312 vty_out(vty
, "Bsm Enabled : %s\n",
1313 pim_ifp
->bsm_enable
? "yes" : "no");
1314 vty_out(vty
, "Unicast Bsm Enabled : %s\n",
1315 pim_ifp
->ucast_bsm_accept
? "yes" : "no");
1322 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1323 json
, JSON_C_TO_STRING_PRETTY
));
1324 json_object_free(json
);
1327 vty_out(vty
, "%% No such interface\n");
1331 static void igmp_show_statistics(struct pim_instance
*pim
, struct vty
*vty
,
1332 const char *ifname
, bool uj
)
1334 struct interface
*ifp
;
1335 struct igmp_stats rx_stats
;
1337 igmp_stats_init(&rx_stats
);
1339 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1340 struct pim_interface
*pim_ifp
;
1341 struct listnode
*sock_node
;
1342 struct igmp_sock
*igmp
;
1344 pim_ifp
= ifp
->info
;
1349 if (ifname
&& strcmp(ifname
, ifp
->name
))
1352 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
1354 igmp_stats_add(&rx_stats
, &igmp
->rx_stats
);
1358 json_object
*json
= NULL
;
1359 json_object
*json_row
= NULL
;
1361 json
= json_object_new_object();
1362 json_row
= json_object_new_object();
1364 json_object_string_add(json_row
, "name", ifname
? ifname
:
1366 json_object_int_add(json_row
, "queryV1", rx_stats
.query_v1
);
1367 json_object_int_add(json_row
, "queryV2", rx_stats
.query_v2
);
1368 json_object_int_add(json_row
, "queryV3", rx_stats
.query_v3
);
1369 json_object_int_add(json_row
, "leaveV3", rx_stats
.leave_v2
);
1370 json_object_int_add(json_row
, "reportV1", rx_stats
.report_v1
);
1371 json_object_int_add(json_row
, "reportV2", rx_stats
.report_v2
);
1372 json_object_int_add(json_row
, "reportV3", rx_stats
.report_v3
);
1373 json_object_int_add(json_row
, "mtraceResponse",
1374 rx_stats
.mtrace_rsp
);
1375 json_object_int_add(json_row
, "mtraceRequest",
1376 rx_stats
.mtrace_req
);
1377 json_object_int_add(json_row
, "unsupported",
1378 rx_stats
.unsupported
);
1379 json_object_object_add(json
, ifname
? ifname
: "global",
1381 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1382 json
, JSON_C_TO_STRING_PRETTY
));
1383 json_object_free(json
);
1385 vty_out(vty
, "IGMP RX statistics\n");
1386 vty_out(vty
, "Interface : %s\n",
1387 ifname
? ifname
: "global");
1388 vty_out(vty
, "V1 query : %u\n", rx_stats
.query_v1
);
1389 vty_out(vty
, "V2 query : %u\n", rx_stats
.query_v2
);
1390 vty_out(vty
, "V3 query : %u\n", rx_stats
.query_v3
);
1391 vty_out(vty
, "V2 leave : %u\n", rx_stats
.leave_v2
);
1392 vty_out(vty
, "V1 report : %u\n", rx_stats
.report_v1
);
1393 vty_out(vty
, "V2 report : %u\n", rx_stats
.report_v2
);
1394 vty_out(vty
, "V3 report : %u\n", rx_stats
.report_v3
);
1395 vty_out(vty
, "mtrace response : %u\n", rx_stats
.mtrace_rsp
);
1396 vty_out(vty
, "mtrace request : %u\n", rx_stats
.mtrace_req
);
1397 vty_out(vty
, "unsupported : %u\n", rx_stats
.unsupported
);
1401 static void pim_show_interfaces(struct pim_instance
*pim
, struct vty
*vty
,
1404 struct interface
*ifp
;
1405 struct pim_interface
*pim_ifp
;
1406 struct pim_upstream
*up
;
1409 int pim_ifchannels
= 0;
1410 char buf
[PREFIX_STRLEN
];
1411 json_object
*json
= NULL
;
1412 json_object
*json_row
= NULL
;
1413 json_object
*json_tmp
;
1415 json
= json_object_new_object();
1417 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1418 pim_ifp
= ifp
->info
;
1423 if (mlag
== true && pim_ifp
->activeactive
== false)
1426 pim_nbrs
= pim_ifp
->pim_neighbor_list
->count
;
1427 pim_ifchannels
= pim_if_ifchannel_count(pim_ifp
);
1430 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
)
1431 if (ifp
== up
->rpf
.source_nexthop
.interface
)
1432 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
1435 json_row
= json_object_new_object();
1436 json_object_pim_ifp_add(json_row
, ifp
);
1437 json_object_int_add(json_row
, "pimNeighbors", pim_nbrs
);
1438 json_object_int_add(json_row
, "pimIfChannels", pim_ifchannels
);
1439 json_object_int_add(json_row
, "firstHopRouterCount", fhr
);
1440 json_object_string_add(json_row
, "pimDesignatedRouter",
1442 &pim_ifp
->pim_dr_addr
, buf
,
1445 if (pim_ifp
->pim_dr_addr
.s_addr
1446 == pim_ifp
->primary_address
.s_addr
)
1447 json_object_boolean_true_add(
1448 json_row
, "pimDesignatedRouterLocal");
1450 json_object_object_add(json
, ifp
->name
, json_row
);
1454 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1455 json
, JSON_C_TO_STRING_PRETTY
));
1458 "Interface State Address PIM Nbrs PIM DR FHR IfChannels\n");
1460 json_object_object_foreach(json
, key
, val
)
1462 vty_out(vty
, "%-16s ", key
);
1464 json_object_object_get_ex(val
, "state", &json_tmp
);
1465 vty_out(vty
, "%5s ", json_object_get_string(json_tmp
));
1467 json_object_object_get_ex(val
, "address", &json_tmp
);
1468 vty_out(vty
, "%15s ",
1469 json_object_get_string(json_tmp
));
1471 json_object_object_get_ex(val
, "pimNeighbors",
1473 vty_out(vty
, "%8d ", json_object_get_int(json_tmp
));
1475 if (json_object_object_get_ex(
1476 val
, "pimDesignatedRouterLocal",
1478 vty_out(vty
, "%15s ", "local");
1480 json_object_object_get_ex(
1481 val
, "pimDesignatedRouter", &json_tmp
);
1482 vty_out(vty
, "%15s ",
1483 json_object_get_string(json_tmp
));
1486 json_object_object_get_ex(val
, "firstHopRouter",
1488 vty_out(vty
, "%3d ", json_object_get_int(json_tmp
));
1490 json_object_object_get_ex(val
, "pimIfChannels",
1492 vty_out(vty
, "%9d\n", json_object_get_int(json_tmp
));
1496 json_object_free(json
);
1499 static void pim_show_interface_traffic(struct pim_instance
*pim
,
1500 struct vty
*vty
, bool uj
)
1502 struct interface
*ifp
= NULL
;
1503 struct pim_interface
*pim_ifp
= NULL
;
1504 json_object
*json
= NULL
;
1505 json_object
*json_row
= NULL
;
1508 json
= json_object_new_object();
1511 vty_out(vty
, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s%-17s\n",
1512 "Interface", " HELLO", " JOIN",
1513 " PRUNE", " REGISTER", "REGISTER-STOP",
1515 vty_out(vty
, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s%-17s\n", "",
1516 " Rx/Tx", " Rx/Tx", " Rx/Tx",
1517 " Rx/Tx", " Rx/Tx", " Rx/Tx",
1520 "---------------------------------------------------------------------------------------------------------------\n");
1523 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1524 pim_ifp
= ifp
->info
;
1529 if (pim_ifp
->pim_sock_fd
< 0)
1532 json_row
= json_object_new_object();
1533 json_object_pim_ifp_add(json_row
, ifp
);
1534 json_object_int_add(json_row
, "helloRx",
1535 pim_ifp
->pim_ifstat_hello_recv
);
1536 json_object_int_add(json_row
, "helloTx",
1537 pim_ifp
->pim_ifstat_hello_sent
);
1538 json_object_int_add(json_row
, "joinRx",
1539 pim_ifp
->pim_ifstat_join_recv
);
1540 json_object_int_add(json_row
, "joinTx",
1541 pim_ifp
->pim_ifstat_join_send
);
1542 json_object_int_add(json_row
, "pruneTx",
1543 pim_ifp
->pim_ifstat_prune_send
);
1544 json_object_int_add(json_row
, "pruneRx",
1545 pim_ifp
->pim_ifstat_prune_recv
);
1546 json_object_int_add(json_row
, "registerRx",
1547 pim_ifp
->pim_ifstat_reg_recv
);
1548 json_object_int_add(json_row
, "registerTx",
1549 pim_ifp
->pim_ifstat_reg_recv
);
1550 json_object_int_add(json_row
, "registerStopRx",
1551 pim_ifp
->pim_ifstat_reg_stop_recv
);
1552 json_object_int_add(json_row
, "registerStopTx",
1553 pim_ifp
->pim_ifstat_reg_stop_send
);
1554 json_object_int_add(json_row
, "assertRx",
1555 pim_ifp
->pim_ifstat_assert_recv
);
1556 json_object_int_add(json_row
, "assertTx",
1557 pim_ifp
->pim_ifstat_assert_send
);
1558 json_object_int_add(json_row
, "bsmRx",
1559 pim_ifp
->pim_ifstat_bsm_rx
);
1560 json_object_int_add(json_row
, "bsmTx",
1561 pim_ifp
->pim_ifstat_bsm_tx
);
1562 json_object_object_add(json
, ifp
->name
, json_row
);
1565 "%-16s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7" PRIu64
"/%-7" PRIu64
"\n",
1566 ifp
->name
, pim_ifp
->pim_ifstat_hello_recv
,
1567 pim_ifp
->pim_ifstat_hello_sent
,
1568 pim_ifp
->pim_ifstat_join_recv
,
1569 pim_ifp
->pim_ifstat_join_send
,
1570 pim_ifp
->pim_ifstat_prune_recv
,
1571 pim_ifp
->pim_ifstat_prune_send
,
1572 pim_ifp
->pim_ifstat_reg_recv
,
1573 pim_ifp
->pim_ifstat_reg_send
,
1574 pim_ifp
->pim_ifstat_reg_stop_recv
,
1575 pim_ifp
->pim_ifstat_reg_stop_send
,
1576 pim_ifp
->pim_ifstat_assert_recv
,
1577 pim_ifp
->pim_ifstat_assert_send
,
1578 pim_ifp
->pim_ifstat_bsm_rx
,
1579 pim_ifp
->pim_ifstat_bsm_tx
);
1583 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1584 json
, JSON_C_TO_STRING_PRETTY
));
1585 json_object_free(json
);
1589 static void pim_show_interface_traffic_single(struct pim_instance
*pim
,
1591 const char *ifname
, bool uj
)
1593 struct interface
*ifp
= NULL
;
1594 struct pim_interface
*pim_ifp
= NULL
;
1595 json_object
*json
= NULL
;
1596 json_object
*json_row
= NULL
;
1597 uint8_t found_ifname
= 0;
1600 json
= json_object_new_object();
1603 vty_out(vty
, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s%-17s\n",
1604 "Interface", " HELLO", " JOIN", " PRUNE",
1605 " REGISTER", " REGISTER-STOP", " ASSERT",
1607 vty_out(vty
, "%-14s%-18s%-17s%-17s%-17s%-17s%-17s%-17s\n", "",
1608 " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1609 " Rx/Tx", " Rx/Tx", " Rx/Tx");
1611 "-------------------------------------------------------------------------------------------------------------------------------\n");
1614 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1615 if (strcmp(ifname
, ifp
->name
))
1618 pim_ifp
= ifp
->info
;
1623 if (pim_ifp
->pim_sock_fd
< 0)
1628 json_row
= json_object_new_object();
1629 json_object_pim_ifp_add(json_row
, ifp
);
1630 json_object_int_add(json_row
, "helloRx",
1631 pim_ifp
->pim_ifstat_hello_recv
);
1632 json_object_int_add(json_row
, "helloTx",
1633 pim_ifp
->pim_ifstat_hello_sent
);
1634 json_object_int_add(json_row
, "joinRx",
1635 pim_ifp
->pim_ifstat_join_recv
);
1636 json_object_int_add(json_row
, "joinTx",
1637 pim_ifp
->pim_ifstat_join_send
);
1638 json_object_int_add(json_row
, "registerRx",
1639 pim_ifp
->pim_ifstat_reg_recv
);
1640 json_object_int_add(json_row
, "registerTx",
1641 pim_ifp
->pim_ifstat_reg_recv
);
1642 json_object_int_add(json_row
, "registerStopRx",
1643 pim_ifp
->pim_ifstat_reg_stop_recv
);
1644 json_object_int_add(json_row
, "registerStopTx",
1645 pim_ifp
->pim_ifstat_reg_stop_send
);
1646 json_object_int_add(json_row
, "assertRx",
1647 pim_ifp
->pim_ifstat_assert_recv
);
1648 json_object_int_add(json_row
, "assertTx",
1649 pim_ifp
->pim_ifstat_assert_send
);
1650 json_object_int_add(json_row
, "bsmRx",
1651 pim_ifp
->pim_ifstat_bsm_rx
);
1652 json_object_int_add(json_row
, "bsmTx",
1653 pim_ifp
->pim_ifstat_bsm_tx
);
1655 json_object_object_add(json
, ifp
->name
, json_row
);
1658 "%-16s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7" PRIu64
"/%-7" PRIu64
"\n",
1659 ifp
->name
, pim_ifp
->pim_ifstat_hello_recv
,
1660 pim_ifp
->pim_ifstat_hello_sent
,
1661 pim_ifp
->pim_ifstat_join_recv
,
1662 pim_ifp
->pim_ifstat_join_send
,
1663 pim_ifp
->pim_ifstat_prune_recv
,
1664 pim_ifp
->pim_ifstat_prune_send
,
1665 pim_ifp
->pim_ifstat_reg_recv
,
1666 pim_ifp
->pim_ifstat_reg_send
,
1667 pim_ifp
->pim_ifstat_reg_stop_recv
,
1668 pim_ifp
->pim_ifstat_reg_stop_send
,
1669 pim_ifp
->pim_ifstat_assert_recv
,
1670 pim_ifp
->pim_ifstat_assert_send
,
1671 pim_ifp
->pim_ifstat_bsm_rx
,
1672 pim_ifp
->pim_ifstat_bsm_tx
);
1676 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1677 json
, JSON_C_TO_STRING_PRETTY
));
1678 json_object_free(json
);
1681 vty_out(vty
, "%% No such interface\n");
1685 static void pim_show_join_helper(struct vty
*vty
, struct pim_interface
*pim_ifp
,
1686 struct pim_ifchannel
*ch
, json_object
*json
,
1687 time_t now
, bool uj
)
1689 char ch_src_str
[INET_ADDRSTRLEN
];
1690 char ch_grp_str
[INET_ADDRSTRLEN
];
1691 json_object
*json_iface
= NULL
;
1692 json_object
*json_row
= NULL
;
1693 json_object
*json_grp
= NULL
;
1694 struct in_addr ifaddr
;
1698 char buf
[PREFIX_STRLEN
];
1700 ifaddr
= pim_ifp
->primary_address
;
1702 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
1703 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
1705 pim_time_uptime_begin(uptime
, sizeof(uptime
), now
, ch
->ifjoin_creation
);
1706 pim_time_timer_to_mmss(expire
, sizeof(expire
),
1707 ch
->t_ifjoin_expiry_timer
);
1708 pim_time_timer_to_mmss(prune
, sizeof(prune
),
1709 ch
->t_ifjoin_prune_pending_timer
);
1712 json_object_object_get_ex(json
, ch
->interface
->name
,
1716 json_iface
= json_object_new_object();
1717 json_object_pim_ifp_add(json_iface
, ch
->interface
);
1718 json_object_object_add(json
, ch
->interface
->name
,
1722 json_row
= json_object_new_object();
1723 json_object_string_add(json_row
, "source", ch_src_str
);
1724 json_object_string_add(json_row
, "group", ch_grp_str
);
1725 json_object_string_add(json_row
, "upTime", uptime
);
1726 json_object_string_add(json_row
, "expire", expire
);
1727 json_object_string_add(json_row
, "prune", prune
);
1728 json_object_string_add(
1729 json_row
, "channelJoinName",
1730 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
, ch
->flags
));
1731 if (PIM_IF_FLAG_TEST_S_G_RPT(ch
->flags
))
1732 json_object_int_add(json_row
, "SGRpt", 1);
1733 if (PIM_IF_FLAG_TEST_PROTO_PIM(ch
->flags
))
1734 json_object_int_add(json_row
, "protocolPim", 1);
1735 if (PIM_IF_FLAG_TEST_PROTO_IGMP(ch
->flags
))
1736 json_object_int_add(json_row
, "protocolIgmp", 1);
1737 json_object_object_get_ex(json_iface
, ch_grp_str
, &json_grp
);
1739 json_grp
= json_object_new_object();
1740 json_object_object_add(json_grp
, ch_src_str
, json_row
);
1741 json_object_object_add(json_iface
, ch_grp_str
,
1744 json_object_object_add(json_grp
, ch_src_str
, json_row
);
1746 vty_out(vty
, "%-16s %-15s %-15s %-15s %-10s %8s %-6s %5s\n",
1747 ch
->interface
->name
,
1748 inet_ntop(AF_INET
, &ifaddr
, buf
, sizeof(buf
)),
1749 ch_src_str
, ch_grp_str
,
1750 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
, ch
->flags
),
1751 uptime
, expire
, prune
);
1755 static void pim_show_join(struct pim_instance
*pim
, struct vty
*vty
,
1756 struct prefix_sg
*sg
, bool uj
)
1758 struct pim_interface
*pim_ifp
;
1759 struct pim_ifchannel
*ch
;
1760 struct interface
*ifp
;
1762 json_object
*json
= NULL
;
1764 now
= pim_time_monotonic_sec();
1767 json
= json_object_new_object();
1770 "Interface Address Source Group State Uptime Expire Prune\n");
1772 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1773 pim_ifp
= ifp
->info
;
1777 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
1778 if (sg
->grp
.s_addr
!= INADDR_ANY
1779 && sg
->grp
.s_addr
!= ch
->sg
.grp
.s_addr
)
1781 if (sg
->src
.s_addr
!= INADDR_ANY
1782 && sg
->src
.s_addr
!= ch
->sg
.src
.s_addr
)
1784 pim_show_join_helper(vty
, pim_ifp
, ch
, json
, now
, uj
);
1785 } /* scan interface channels */
1789 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1790 json
, JSON_C_TO_STRING_PRETTY
));
1791 json_object_free(json
);
1795 static void pim_show_neighbors_single(struct pim_instance
*pim
, struct vty
*vty
,
1796 const char *neighbor
, bool uj
)
1798 struct listnode
*neighnode
;
1799 struct interface
*ifp
;
1800 struct pim_interface
*pim_ifp
;
1801 struct pim_neighbor
*neigh
;
1803 int found_neighbor
= 0;
1804 int option_address_list
;
1805 int option_dr_priority
;
1806 int option_generation_id
;
1807 int option_holdtime
;
1808 int option_lan_prune_delay
;
1812 char neigh_src_str
[INET_ADDRSTRLEN
];
1814 json_object
*json
= NULL
;
1815 json_object
*json_ifp
= NULL
;
1816 json_object
*json_row
= NULL
;
1818 now
= pim_time_monotonic_sec();
1821 json
= json_object_new_object();
1823 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1824 pim_ifp
= ifp
->info
;
1829 if (pim_ifp
->pim_sock_fd
< 0)
1832 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
1834 pim_inet4_dump("<src?>", neigh
->source_addr
,
1835 neigh_src_str
, sizeof(neigh_src_str
));
1838 * The user can specify either the interface name or the
1840 * If this pim_ifp matches neither then skip.
1842 if (strcmp(neighbor
, "detail")
1843 && strcmp(neighbor
, ifp
->name
)
1844 && strcmp(neighbor
, neigh_src_str
))
1848 pim_time_uptime(uptime
, sizeof(uptime
),
1849 now
- neigh
->creation
);
1850 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
1851 neigh
->t_expire_timer
);
1853 option_address_list
= 0;
1854 option_dr_priority
= 0;
1855 option_generation_id
= 0;
1856 option_holdtime
= 0;
1857 option_lan_prune_delay
= 0;
1860 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1861 PIM_OPTION_MASK_ADDRESS_LIST
))
1862 option_address_list
= 1;
1864 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1865 PIM_OPTION_MASK_DR_PRIORITY
))
1866 option_dr_priority
= 1;
1868 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1869 PIM_OPTION_MASK_GENERATION_ID
))
1870 option_generation_id
= 1;
1872 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1873 PIM_OPTION_MASK_HOLDTIME
))
1874 option_holdtime
= 1;
1876 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1877 PIM_OPTION_MASK_LAN_PRUNE_DELAY
))
1878 option_lan_prune_delay
= 1;
1880 if (PIM_OPTION_IS_SET(
1881 neigh
->hello_options
,
1882 PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION
))
1887 /* Does this ifp live in json? If not create
1889 json_object_object_get_ex(json
, ifp
->name
,
1893 json_ifp
= json_object_new_object();
1894 json_object_pim_ifp_add(json_ifp
, ifp
);
1895 json_object_object_add(json
, ifp
->name
,
1899 json_row
= json_object_new_object();
1900 json_object_string_add(json_row
, "interface",
1902 json_object_string_add(json_row
, "address",
1904 json_object_string_add(json_row
, "upTime",
1906 json_object_string_add(json_row
, "holdtime",
1908 json_object_int_add(json_row
, "drPriority",
1909 neigh
->dr_priority
);
1910 json_object_int_add(json_row
, "generationId",
1911 neigh
->generation_id
);
1913 if (option_address_list
)
1914 json_object_boolean_true_add(
1916 "helloOptionAddressList");
1918 if (option_dr_priority
)
1919 json_object_boolean_true_add(
1921 "helloOptionDrPriority");
1923 if (option_generation_id
)
1924 json_object_boolean_true_add(
1926 "helloOptionGenerationId");
1928 if (option_holdtime
)
1929 json_object_boolean_true_add(
1931 "helloOptionHoldtime");
1933 if (option_lan_prune_delay
)
1934 json_object_boolean_true_add(
1936 "helloOptionLanPruneDelay");
1939 json_object_boolean_true_add(
1940 json_row
, "helloOptionTBit");
1942 json_object_object_add(json_ifp
, neigh_src_str
,
1946 vty_out(vty
, "Interface : %s\n", ifp
->name
);
1947 vty_out(vty
, "Neighbor : %s\n", neigh_src_str
);
1955 " DR Priority : %d\n",
1956 neigh
->dr_priority
);
1958 " Generation ID : %08x\n",
1959 neigh
->generation_id
);
1961 " Override Interval (msec) : %d\n",
1962 neigh
->override_interval_msec
);
1964 " Propagation Delay (msec) : %d\n",
1965 neigh
->propagation_delay_msec
);
1967 " Hello Option - Address List : %s\n",
1968 option_address_list
? "yes" : "no");
1970 " Hello Option - DR Priority : %s\n",
1971 option_dr_priority
? "yes" : "no");
1973 " Hello Option - Generation ID : %s\n",
1974 option_generation_id
? "yes" : "no");
1976 " Hello Option - Holdtime : %s\n",
1977 option_holdtime
? "yes" : "no");
1979 " Hello Option - LAN Prune Delay : %s\n",
1980 option_lan_prune_delay
? "yes" : "no");
1982 " Hello Option - T-bit : %s\n",
1983 option_t_bit
? "yes" : "no");
1984 bfd_sess_show(vty
, json_ifp
,
1985 neigh
->bfd_session
);
1992 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1993 json
, JSON_C_TO_STRING_PRETTY
));
1994 json_object_free(json
);
1997 if (!found_neighbor
)
1999 "%% No such interface or neighbor\n");
2004 static void pim_show_state(struct pim_instance
*pim
, struct vty
*vty
,
2005 const char *src_or_group
, const char *group
, bool uj
)
2007 struct channel_oil
*c_oil
;
2008 json_object
*json
= NULL
;
2009 json_object
*json_group
= NULL
;
2010 json_object
*json_ifp_in
= NULL
;
2011 json_object
*json_ifp_out
= NULL
;
2012 json_object
*json_source
= NULL
;
2015 now
= pim_time_monotonic_sec();
2018 json
= json_object_new_object();
2021 "Codes: J -> Pim Join, I -> IGMP Report, S -> Source, * -> Inherited from (*,G), V -> VxLAN, M -> Muted");
2023 "\nActive Source Group RPT IIF OIL\n");
2026 frr_each (rb_pim_oil
, &pim
->channel_oil_head
, c_oil
) {
2027 char grp_str
[INET_ADDRSTRLEN
];
2028 char src_str
[INET_ADDRSTRLEN
];
2029 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
2030 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
2032 struct interface
*ifp_in
;
2037 PIM_UPSTREAM_FLAG_TEST_USE_RPT(c_oil
->up
->flags
)) ||
2038 c_oil
->oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
2043 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
2045 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
2047 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
2050 strlcpy(in_ifname
, ifp_in
->name
, sizeof(in_ifname
));
2052 strlcpy(in_ifname
, "<iif?>", sizeof(in_ifname
));
2055 if (strcmp(src_or_group
, src_str
)
2056 && strcmp(src_or_group
, grp_str
))
2059 if (group
&& strcmp(group
, grp_str
))
2065 /* Find the group, create it if it doesn't exist */
2066 json_object_object_get_ex(json
, grp_str
, &json_group
);
2069 json_group
= json_object_new_object();
2070 json_object_object_add(json
, grp_str
,
2074 /* Find the source nested under the group, create it if
2075 * it doesn't exist */
2076 json_object_object_get_ex(json_group
, src_str
,
2080 json_source
= json_object_new_object();
2081 json_object_object_add(json_group
, src_str
,
2085 /* Find the inbound interface nested under the source,
2086 * create it if it doesn't exist */
2087 json_object_object_get_ex(json_source
, in_ifname
,
2091 json_ifp_in
= json_object_new_object();
2092 json_object_object_add(json_source
, in_ifname
,
2094 json_object_int_add(json_source
, "Installed",
2097 json_object_boolean_true_add(
2098 json_source
, "isRpt");
2100 json_object_boolean_false_add(
2101 json_source
, "isRpt");
2102 json_object_int_add(json_source
, "RefCount",
2103 c_oil
->oil_ref_count
);
2104 json_object_int_add(json_source
, "OilListSize",
2106 json_object_int_add(
2107 json_source
, "OilRescan",
2108 c_oil
->oil_inherited_rescan
);
2109 json_object_int_add(json_source
, "LastUsed",
2110 c_oil
->cc
.lastused
);
2111 json_object_int_add(json_source
, "PacketCount",
2113 json_object_int_add(json_source
, "ByteCount",
2115 json_object_int_add(json_source
,
2117 c_oil
->cc
.wrong_if
);
2120 vty_out(vty
, "%-6d %-15s %-15s %-3s %-16s ",
2121 c_oil
->installed
, src_str
, grp_str
,
2122 isRpt
? "y" : "n", in_ifname
);
2125 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
2127 struct interface
*ifp_out
;
2128 char oif_uptime
[10];
2131 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
2135 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
2137 oif_uptime
, sizeof(oif_uptime
),
2138 now
- c_oil
->oif_creation
[oif_vif_index
]);
2141 strlcpy(out_ifname
, ifp_out
->name
, sizeof(out_ifname
));
2143 strlcpy(out_ifname
, "<oif?>", sizeof(out_ifname
));
2146 json_ifp_out
= json_object_new_object();
2147 json_object_string_add(json_ifp_out
, "source",
2149 json_object_string_add(json_ifp_out
, "group",
2151 json_object_string_add(json_ifp_out
,
2154 json_object_string_add(json_ifp_out
,
2155 "outboundInterface",
2157 json_object_int_add(json_ifp_out
, "installed",
2160 json_object_object_add(json_ifp_in
, out_ifname
,
2165 vty_out(vty
, "%s(%c%c%c%c%c)",
2167 (c_oil
->oif_flags
[oif_vif_index
]
2168 & PIM_OIF_FLAG_PROTO_IGMP
)
2171 (c_oil
->oif_flags
[oif_vif_index
]
2172 & PIM_OIF_FLAG_PROTO_PIM
)
2175 (c_oil
->oif_flags
[oif_vif_index
]
2176 & PIM_OIF_FLAG_PROTO_VXLAN
)
2179 (c_oil
->oif_flags
[oif_vif_index
]
2180 & PIM_OIF_FLAG_PROTO_STAR
)
2183 (c_oil
->oif_flags
[oif_vif_index
]
2184 & PIM_OIF_FLAG_MUTE
)
2188 vty_out(vty
, ", %s(%c%c%c%c%c)",
2190 (c_oil
->oif_flags
[oif_vif_index
]
2191 & PIM_OIF_FLAG_PROTO_IGMP
)
2194 (c_oil
->oif_flags
[oif_vif_index
]
2195 & PIM_OIF_FLAG_PROTO_PIM
)
2198 (c_oil
->oif_flags
[oif_vif_index
]
2199 & PIM_OIF_FLAG_PROTO_VXLAN
)
2202 (c_oil
->oif_flags
[oif_vif_index
]
2203 & PIM_OIF_FLAG_PROTO_STAR
)
2206 (c_oil
->oif_flags
[oif_vif_index
]
2207 & PIM_OIF_FLAG_MUTE
)
2219 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2220 json
, JSON_C_TO_STRING_PRETTY
));
2221 json_object_free(json
);
2227 static void pim_show_neighbors(struct pim_instance
*pim
, struct vty
*vty
,
2230 struct listnode
*neighnode
;
2231 struct interface
*ifp
;
2232 struct pim_interface
*pim_ifp
;
2233 struct pim_neighbor
*neigh
;
2237 char neigh_src_str
[INET_ADDRSTRLEN
];
2238 json_object
*json
= NULL
;
2239 json_object
*json_ifp_rows
= NULL
;
2240 json_object
*json_row
= NULL
;
2242 now
= pim_time_monotonic_sec();
2245 json
= json_object_new_object();
2248 "Interface Neighbor Uptime Holdtime DR Pri\n");
2251 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2252 pim_ifp
= ifp
->info
;
2257 if (pim_ifp
->pim_sock_fd
< 0)
2261 json_ifp_rows
= json_object_new_object();
2263 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
2265 pim_inet4_dump("<src?>", neigh
->source_addr
,
2266 neigh_src_str
, sizeof(neigh_src_str
));
2267 pim_time_uptime(uptime
, sizeof(uptime
),
2268 now
- neigh
->creation
);
2269 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
2270 neigh
->t_expire_timer
);
2273 json_row
= json_object_new_object();
2274 json_object_string_add(json_row
, "interface",
2276 json_object_string_add(json_row
, "neighbor",
2278 json_object_string_add(json_row
, "upTime",
2280 json_object_string_add(json_row
, "holdTime",
2282 json_object_int_add(json_row
, "holdTimeMax",
2284 json_object_int_add(json_row
, "drPriority",
2285 neigh
->dr_priority
);
2286 json_object_object_add(json_ifp_rows
,
2287 neigh_src_str
, json_row
);
2290 vty_out(vty
, "%-16s %15s %8s %8s %6d\n",
2291 ifp
->name
, neigh_src_str
, uptime
,
2292 expire
, neigh
->dr_priority
);
2297 json_object_object_add(json
, ifp
->name
, json_ifp_rows
);
2298 json_ifp_rows
= NULL
;
2303 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2304 json
, JSON_C_TO_STRING_PRETTY
));
2305 json_object_free(json
);
2309 static void pim_show_neighbors_secondary(struct pim_instance
*pim
,
2312 struct interface
*ifp
;
2315 "Interface Address Neighbor Secondary \n");
2317 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2318 struct pim_interface
*pim_ifp
;
2319 struct in_addr ifaddr
;
2320 struct listnode
*neighnode
;
2321 struct pim_neighbor
*neigh
;
2322 char buf
[PREFIX_STRLEN
];
2324 pim_ifp
= ifp
->info
;
2329 if (pim_ifp
->pim_sock_fd
< 0)
2332 ifaddr
= pim_ifp
->primary_address
;
2334 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
2336 char neigh_src_str
[INET_ADDRSTRLEN
];
2337 struct listnode
*prefix_node
;
2340 if (!neigh
->prefix_list
)
2343 pim_inet4_dump("<src?>", neigh
->source_addr
,
2344 neigh_src_str
, sizeof(neigh_src_str
));
2346 for (ALL_LIST_ELEMENTS_RO(neigh
->prefix_list
,
2348 vty_out(vty
, "%-16s %-15s %-15s %-15pFX\n",
2350 inet_ntop(AF_INET
, &ifaddr
,
2357 static void json_object_pim_upstream_add(json_object
*json
,
2358 struct pim_upstream
*up
)
2360 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED
)
2361 json_object_boolean_true_add(json
, "drJoinDesired");
2363 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED
)
2364 json_object_boolean_true_add(json
, "drJoinDesiredUpdated");
2366 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
2367 json_object_boolean_true_add(json
, "firstHopRouter");
2369 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_IGMP
)
2370 json_object_boolean_true_add(json
, "sourceIgmp");
2372 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_PIM
)
2373 json_object_boolean_true_add(json
, "sourcePim");
2375 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_STREAM
)
2376 json_object_boolean_true_add(json
, "sourceStream");
2378 /* XXX: need to print ths flag in the plain text display as well */
2379 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_MSDP
)
2380 json_object_boolean_true_add(json
, "sourceMsdp");
2382 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SEND_SG_RPT_PRUNE
)
2383 json_object_boolean_true_add(json
, "sendSGRptPrune");
2385 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_LHR
)
2386 json_object_boolean_true_add(json
, "lastHopRouter");
2388 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DISABLE_KAT_EXPIRY
)
2389 json_object_boolean_true_add(json
, "disableKATExpiry");
2391 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_STATIC_IIF
)
2392 json_object_boolean_true_add(json
, "staticIncomingInterface");
2394 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_ALLOW_IIF_IN_OIL
)
2395 json_object_boolean_true_add(json
,
2396 "allowIncomingInterfaceinOil");
2398 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_NO_PIMREG_DATA
)
2399 json_object_boolean_true_add(json
, "noPimRegistrationData");
2401 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FORCE_PIMREG
)
2402 json_object_boolean_true_add(json
, "forcePimRegistration");
2404 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_ORIG
)
2405 json_object_boolean_true_add(json
, "sourceVxlanOrigination");
2407 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_TERM
)
2408 json_object_boolean_true_add(json
, "sourceVxlanTermination");
2410 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_VXLAN
)
2411 json_object_boolean_true_add(json
, "mlagVxlan");
2413 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_NON_DF
)
2414 json_object_boolean_true_add(json
,
2415 "mlagNonDesignatedForwarder");
2419 pim_upstream_state2brief_str(enum pim_upstream_state join_state
,
2420 char *state_str
, size_t state_str_len
)
2422 switch (join_state
) {
2423 case PIM_UPSTREAM_NOTJOINED
:
2424 strlcpy(state_str
, "NotJ", state_str_len
);
2426 case PIM_UPSTREAM_JOINED
:
2427 strlcpy(state_str
, "J", state_str_len
);
2430 strlcpy(state_str
, "Unk", state_str_len
);
2435 static const char *pim_reg_state2brief_str(enum pim_reg_state reg_state
,
2436 char *state_str
, size_t state_str_len
)
2438 switch (reg_state
) {
2439 case PIM_REG_NOINFO
:
2440 strlcpy(state_str
, "RegNI", state_str_len
);
2443 strlcpy(state_str
, "RegJ", state_str_len
);
2445 case PIM_REG_JOIN_PENDING
:
2447 strlcpy(state_str
, "RegP", state_str_len
);
2450 strlcpy(state_str
, "Unk", state_str_len
);
2455 static void pim_show_upstream(struct pim_instance
*pim
, struct vty
*vty
,
2456 struct prefix_sg
*sg
, bool uj
)
2458 struct pim_upstream
*up
;
2460 json_object
*json
= NULL
;
2461 json_object
*json_group
= NULL
;
2462 json_object
*json_row
= NULL
;
2464 now
= pim_time_monotonic_sec();
2467 json
= json_object_new_object();
2470 "Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt\n");
2472 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
2473 char src_str
[INET_ADDRSTRLEN
];
2474 char grp_str
[INET_ADDRSTRLEN
];
2476 char join_timer
[10];
2479 char msdp_reg_timer
[10];
2480 char state_str
[PIM_REG_STATE_STR_LEN
];
2482 if (sg
->grp
.s_addr
!= INADDR_ANY
2483 && sg
->grp
.s_addr
!= up
->sg
.grp
.s_addr
)
2485 if (sg
->src
.s_addr
!= INADDR_ANY
2486 && sg
->src
.s_addr
!= up
->sg
.src
.s_addr
)
2489 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2490 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2491 pim_time_uptime(uptime
, sizeof(uptime
),
2492 now
- up
->state_transition
);
2493 pim_time_timer_to_hhmmss(join_timer
, sizeof(join_timer
),
2497 * If the upstream is not dummy and it has a J/P timer for the
2498 * neighbor display that
2500 if (!up
->t_join_timer
&& up
->rpf
.source_nexthop
.interface
) {
2501 struct pim_neighbor
*nbr
;
2503 nbr
= pim_neighbor_find(
2504 up
->rpf
.source_nexthop
.interface
,
2505 up
->rpf
.rpf_addr
.u
.prefix4
);
2507 pim_time_timer_to_hhmmss(join_timer
,
2512 pim_time_timer_to_hhmmss(rs_timer
, sizeof(rs_timer
),
2514 pim_time_timer_to_hhmmss(ka_timer
, sizeof(ka_timer
),
2516 pim_time_timer_to_hhmmss(msdp_reg_timer
, sizeof(msdp_reg_timer
),
2517 up
->t_msdp_reg_timer
);
2519 pim_upstream_state2brief_str(up
->join_state
, state_str
, sizeof(state_str
));
2520 if (up
->reg_state
!= PIM_REG_NOINFO
) {
2521 char tmp_str
[PIM_REG_STATE_STR_LEN
];
2522 char tmp
[sizeof(state_str
) + 1];
2524 snprintf(tmp
, sizeof(tmp
), ",%s",
2525 pim_reg_state2brief_str(up
->reg_state
, tmp_str
,
2527 strlcat(state_str
, tmp
, sizeof(state_str
));
2531 json_object_object_get_ex(json
, grp_str
, &json_group
);
2534 json_group
= json_object_new_object();
2535 json_object_object_add(json
, grp_str
,
2539 json_row
= json_object_new_object();
2540 json_object_pim_upstream_add(json_row
, up
);
2541 json_object_string_add(
2542 json_row
, "inboundInterface",
2543 up
->rpf
.source_nexthop
.interface
2544 ? up
->rpf
.source_nexthop
.interface
->name
2548 * The RPF address we use is slightly different
2549 * based upon what we are looking up.
2550 * If we have a S, list that unless
2551 * we are the FHR, else we just put
2552 * the RP as the rpfAddress
2554 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
2555 || up
->sg
.src
.s_addr
== INADDR_ANY
) {
2556 char rpf
[PREFIX_STRLEN
];
2557 struct pim_rpf
*rpg
;
2559 rpg
= RP(pim
, up
->sg
.grp
);
2560 pim_inet4_dump("<rpf?>",
2561 rpg
->rpf_addr
.u
.prefix4
, rpf
,
2563 json_object_string_add(json_row
, "rpfAddress",
2566 json_object_string_add(json_row
, "rpfAddress",
2570 json_object_string_add(json_row
, "source", src_str
);
2571 json_object_string_add(json_row
, "group", grp_str
);
2572 json_object_string_add(json_row
, "state", state_str
);
2573 json_object_string_add(
2574 json_row
, "joinState",
2575 pim_upstream_state2str(up
->join_state
));
2576 json_object_string_add(
2577 json_row
, "regState",
2578 pim_reg_state2str(up
->reg_state
, state_str
, sizeof(state_str
)));
2579 json_object_string_add(json_row
, "upTime", uptime
);
2580 json_object_string_add(json_row
, "joinTimer",
2582 json_object_string_add(json_row
, "resetTimer",
2584 json_object_string_add(json_row
, "keepaliveTimer",
2586 json_object_string_add(json_row
, "msdpRegTimer",
2588 json_object_int_add(json_row
, "refCount",
2590 json_object_int_add(json_row
, "sptBit", up
->sptbit
);
2591 json_object_object_add(json_group
, src_str
, json_row
);
2594 "%-16s%-15s %-15s %-11s %-8s %-9s %-9s %-9s %6d\n",
2595 up
->rpf
.source_nexthop
.interface
2596 ? up
->rpf
.source_nexthop
.interface
->name
2598 src_str
, grp_str
, state_str
, uptime
, join_timer
,
2599 rs_timer
, ka_timer
, up
->ref_count
);
2604 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2605 json
, JSON_C_TO_STRING_PRETTY
));
2606 json_object_free(json
);
2610 static void pim_show_channel_helper(struct pim_instance
*pim
,
2612 struct pim_interface
*pim_ifp
,
2613 struct pim_ifchannel
*ch
,
2614 json_object
*json
, bool uj
)
2616 struct pim_upstream
*up
= ch
->upstream
;
2617 json_object
*json_group
= NULL
;
2618 char src_str
[INET_ADDRSTRLEN
];
2619 char grp_str
[INET_ADDRSTRLEN
];
2620 json_object
*json_row
= NULL
;
2622 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2623 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2626 json_object_object_get_ex(json
, grp_str
, &json_group
);
2629 json_group
= json_object_new_object();
2630 json_object_object_add(json
, grp_str
, json_group
);
2633 json_row
= json_object_new_object();
2634 json_object_pim_upstream_add(json_row
, up
);
2635 json_object_string_add(json_row
, "interface",
2636 ch
->interface
->name
);
2637 json_object_string_add(json_row
, "source", src_str
);
2638 json_object_string_add(json_row
, "group", grp_str
);
2640 if (pim_macro_ch_lost_assert(ch
))
2641 json_object_boolean_true_add(json_row
, "lostAssert");
2643 if (pim_macro_chisin_joins(ch
))
2644 json_object_boolean_true_add(json_row
, "joins");
2646 if (pim_macro_chisin_pim_include(ch
))
2647 json_object_boolean_true_add(json_row
, "pimInclude");
2649 if (pim_upstream_evaluate_join_desired(pim
, up
))
2650 json_object_boolean_true_add(json_row
,
2651 "evaluateJoinDesired");
2653 json_object_object_add(json_group
, src_str
, json_row
);
2656 vty_out(vty
, "%-16s %-15s %-15s %-10s %-5s %-10s %-11s %-6s\n",
2657 ch
->interface
->name
, src_str
, grp_str
,
2658 pim_macro_ch_lost_assert(ch
) ? "yes" : "no",
2659 pim_macro_chisin_joins(ch
) ? "yes" : "no",
2660 pim_macro_chisin_pim_include(ch
) ? "yes" : "no",
2661 PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(up
->flags
)
2664 pim_upstream_evaluate_join_desired(pim
, up
) ? "yes"
2669 static void pim_show_channel(struct pim_instance
*pim
, struct vty
*vty
,
2672 struct pim_interface
*pim_ifp
;
2673 struct pim_ifchannel
*ch
;
2674 struct interface
*ifp
;
2676 json_object
*json
= NULL
;
2679 json
= json_object_new_object();
2682 "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD\n");
2684 /* scan per-interface (S,G) state */
2685 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2686 pim_ifp
= ifp
->info
;
2691 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
2692 /* scan all interfaces */
2693 pim_show_channel_helper(pim
, vty
, pim_ifp
, ch
,
2699 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2700 json
, JSON_C_TO_STRING_PRETTY
));
2701 json_object_free(json
);
2705 static void pim_show_join_desired_helper(struct pim_instance
*pim
,
2707 struct pim_upstream
*up
,
2708 json_object
*json
, bool uj
)
2710 json_object
*json_group
= NULL
;
2711 char src_str
[INET_ADDRSTRLEN
];
2712 char grp_str
[INET_ADDRSTRLEN
];
2713 json_object
*json_row
= NULL
;
2715 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2716 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2719 json_object_object_get_ex(json
, grp_str
, &json_group
);
2722 json_group
= json_object_new_object();
2723 json_object_object_add(json
, grp_str
, json_group
);
2726 json_row
= json_object_new_object();
2727 json_object_pim_upstream_add(json_row
, up
);
2728 json_object_string_add(json_row
, "source", src_str
);
2729 json_object_string_add(json_row
, "group", grp_str
);
2731 if (pim_upstream_evaluate_join_desired(pim
, up
))
2732 json_object_boolean_true_add(json_row
,
2733 "evaluateJoinDesired");
2735 json_object_object_add(json_group
, src_str
, json_row
);
2738 vty_out(vty
, "%-15s %-15s %-6s\n",
2740 pim_upstream_evaluate_join_desired(pim
, up
) ? "yes"
2745 static void pim_show_join_desired(struct pim_instance
*pim
, struct vty
*vty
,
2748 struct pim_upstream
*up
;
2750 json_object
*json
= NULL
;
2753 json
= json_object_new_object();
2756 "Source Group EvalJD\n");
2758 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
2759 /* scan all interfaces */
2760 pim_show_join_desired_helper(pim
, vty
, up
,
2765 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2766 json
, JSON_C_TO_STRING_PRETTY
));
2767 json_object_free(json
);
2771 static void pim_show_upstream_rpf(struct pim_instance
*pim
, struct vty
*vty
,
2774 struct pim_upstream
*up
;
2775 json_object
*json
= NULL
;
2776 json_object
*json_group
= NULL
;
2777 json_object
*json_row
= NULL
;
2780 json
= json_object_new_object();
2783 "Source Group RpfIface RibNextHop RpfAddress \n");
2785 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
2786 char src_str
[INET_ADDRSTRLEN
];
2787 char grp_str
[INET_ADDRSTRLEN
];
2788 char rpf_nexthop_str
[PREFIX_STRLEN
];
2789 char rpf_addr_str
[PREFIX_STRLEN
];
2790 struct pim_rpf
*rpf
;
2791 const char *rpf_ifname
;
2795 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2796 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2797 pim_addr_dump("<nexthop?>",
2798 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2799 rpf_nexthop_str
, sizeof(rpf_nexthop_str
));
2800 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2801 sizeof(rpf_addr_str
));
2803 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2806 json_object_object_get_ex(json
, grp_str
, &json_group
);
2809 json_group
= json_object_new_object();
2810 json_object_object_add(json
, grp_str
,
2814 json_row
= json_object_new_object();
2815 json_object_pim_upstream_add(json_row
, up
);
2816 json_object_string_add(json_row
, "source", src_str
);
2817 json_object_string_add(json_row
, "group", grp_str
);
2818 json_object_string_add(json_row
, "rpfInterface",
2820 json_object_string_add(json_row
, "ribNexthop",
2822 json_object_string_add(json_row
, "rpfAddress",
2824 json_object_object_add(json_group
, src_str
, json_row
);
2826 vty_out(vty
, "%-15s %-15s %-16s %-15s %-15s\n", src_str
,
2827 grp_str
, rpf_ifname
, rpf_nexthop_str
,
2833 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2834 json
, JSON_C_TO_STRING_PRETTY
));
2835 json_object_free(json
);
2839 static void show_rpf_refresh_stats(struct vty
*vty
, struct pim_instance
*pim
,
2840 time_t now
, json_object
*json
)
2842 char refresh_uptime
[10];
2844 pim_time_uptime_begin(refresh_uptime
, sizeof(refresh_uptime
), now
,
2845 pim
->rpf_cache_refresh_last
);
2848 json_object_int_add(json
, "rpfCacheRefreshDelayMsecs",
2849 router
->rpf_cache_refresh_delay_msec
);
2850 json_object_int_add(
2851 json
, "rpfCacheRefreshTimer",
2852 pim_time_timer_remain_msec(pim
->rpf_cache_refresher
));
2853 json_object_int_add(json
, "rpfCacheRefreshRequests",
2854 pim
->rpf_cache_refresh_requests
);
2855 json_object_int_add(json
, "rpfCacheRefreshEvents",
2856 pim
->rpf_cache_refresh_events
);
2857 json_object_string_add(json
, "rpfCacheRefreshLast",
2859 json_object_int_add(json
, "nexthopLookups",
2860 pim
->nexthop_lookups
);
2861 json_object_int_add(json
, "nexthopLookupsAvoided",
2862 pim
->nexthop_lookups_avoided
);
2865 "RPF Cache Refresh Delay: %ld msecs\n"
2866 "RPF Cache Refresh Timer: %ld msecs\n"
2867 "RPF Cache Refresh Requests: %lld\n"
2868 "RPF Cache Refresh Events: %lld\n"
2869 "RPF Cache Refresh Last: %s\n"
2870 "Nexthop Lookups: %lld\n"
2871 "Nexthop Lookups Avoided: %lld\n",
2872 router
->rpf_cache_refresh_delay_msec
,
2873 pim_time_timer_remain_msec(pim
->rpf_cache_refresher
),
2874 (long long)pim
->rpf_cache_refresh_requests
,
2875 (long long)pim
->rpf_cache_refresh_events
,
2876 refresh_uptime
, (long long)pim
->nexthop_lookups
,
2877 (long long)pim
->nexthop_lookups_avoided
);
2881 static void show_scan_oil_stats(struct pim_instance
*pim
, struct vty
*vty
,
2884 char uptime_scan_oil
[10];
2885 char uptime_mroute_add
[10];
2886 char uptime_mroute_del
[10];
2888 pim_time_uptime_begin(uptime_scan_oil
, sizeof(uptime_scan_oil
), now
,
2889 pim
->scan_oil_last
);
2890 pim_time_uptime_begin(uptime_mroute_add
, sizeof(uptime_mroute_add
), now
,
2891 pim
->mroute_add_last
);
2892 pim_time_uptime_begin(uptime_mroute_del
, sizeof(uptime_mroute_del
), now
,
2893 pim
->mroute_del_last
);
2896 "Scan OIL - Last: %s Events: %lld\n"
2897 "MFC Add - Last: %s Events: %lld\n"
2898 "MFC Del - Last: %s Events: %lld\n",
2899 uptime_scan_oil
, (long long)pim
->scan_oil_events
,
2900 uptime_mroute_add
, (long long)pim
->mroute_add_events
,
2901 uptime_mroute_del
, (long long)pim
->mroute_del_events
);
2904 static void pim_show_rpf(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
2906 struct pim_upstream
*up
;
2907 time_t now
= pim_time_monotonic_sec();
2908 json_object
*json
= NULL
;
2909 json_object
*json_group
= NULL
;
2910 json_object
*json_row
= NULL
;
2913 json
= json_object_new_object();
2914 show_rpf_refresh_stats(vty
, pim
, now
, json
);
2916 show_rpf_refresh_stats(vty
, pim
, now
, json
);
2919 "Source Group RpfIface RpfAddress RibNextHop Metric Pref\n");
2922 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
2923 char src_str
[INET_ADDRSTRLEN
];
2924 char grp_str
[INET_ADDRSTRLEN
];
2925 char rpf_addr_str
[PREFIX_STRLEN
];
2926 char rib_nexthop_str
[PREFIX_STRLEN
];
2927 const char *rpf_ifname
;
2928 struct pim_rpf
*rpf
= &up
->rpf
;
2930 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2931 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2932 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2933 sizeof(rpf_addr_str
));
2934 pim_addr_dump("<nexthop?>",
2935 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2936 rib_nexthop_str
, sizeof(rib_nexthop_str
));
2938 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2941 json_object_object_get_ex(json
, grp_str
, &json_group
);
2944 json_group
= json_object_new_object();
2945 json_object_object_add(json
, grp_str
,
2949 json_row
= json_object_new_object();
2950 json_object_string_add(json_row
, "source", src_str
);
2951 json_object_string_add(json_row
, "group", grp_str
);
2952 json_object_string_add(json_row
, "rpfInterface",
2954 json_object_string_add(json_row
, "rpfAddress",
2956 json_object_string_add(json_row
, "ribNexthop",
2958 json_object_int_add(
2959 json_row
, "routeMetric",
2960 rpf
->source_nexthop
.mrib_route_metric
);
2961 json_object_int_add(
2962 json_row
, "routePreference",
2963 rpf
->source_nexthop
.mrib_metric_preference
);
2964 json_object_object_add(json_group
, src_str
, json_row
);
2967 vty_out(vty
, "%-15s %-15s %-16s %-15s %-15s %6d %4d\n",
2968 src_str
, grp_str
, rpf_ifname
, rpf_addr_str
,
2970 rpf
->source_nexthop
.mrib_route_metric
,
2971 rpf
->source_nexthop
.mrib_metric_preference
);
2976 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2977 json
, JSON_C_TO_STRING_PRETTY
));
2978 json_object_free(json
);
2982 struct pnc_cache_walk_data
{
2984 struct pim_instance
*pim
;
2987 static int pim_print_pnc_cache_walkcb(struct hash_bucket
*bucket
, void *arg
)
2989 struct pim_nexthop_cache
*pnc
= bucket
->data
;
2990 struct pnc_cache_walk_data
*cwd
= arg
;
2991 struct vty
*vty
= cwd
->vty
;
2992 struct pim_instance
*pim
= cwd
->pim
;
2993 struct nexthop
*nh_node
= NULL
;
2994 ifindex_t first_ifindex
;
2995 struct interface
*ifp
= NULL
;
2996 char buf
[PREFIX_STRLEN
];
2998 for (nh_node
= pnc
->nexthop
; nh_node
; nh_node
= nh_node
->next
) {
2999 first_ifindex
= nh_node
->ifindex
;
3000 ifp
= if_lookup_by_index(first_ifindex
, pim
->vrf
->vrf_id
);
3002 vty_out(vty
, "%-15s ", inet_ntop(AF_INET
,
3003 &pnc
->rpf
.rpf_addr
.u
.prefix4
,
3005 vty_out(vty
, "%-16s ", ifp
? ifp
->name
: "NULL");
3006 vty_out(vty
, "%pI4 ", &nh_node
->gate
.ipv4
);
3012 static void pim_show_nexthop(struct pim_instance
*pim
, struct vty
*vty
)
3014 struct pnc_cache_walk_data cwd
;
3018 vty_out(vty
, "Number of registered addresses: %lu\n",
3019 pim
->rpf_hash
->count
);
3020 vty_out(vty
, "Address Interface Nexthop\n");
3021 vty_out(vty
, "---------------------------------------------\n");
3023 hash_walk(pim
->rpf_hash
, pim_print_pnc_cache_walkcb
, &cwd
);
3026 /* Display the bsm database details */
3027 static void pim_show_bsm_db(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
3031 struct bsm_frag
*bsfrag
;
3032 json_object
*json
= NULL
;
3033 json_object
*json_group
= NULL
;
3034 json_object
*json_row
= NULL
;
3036 count
= bsm_frags_count(pim
->global_scope
.bsm_frags
);
3039 json
= json_object_new_object();
3040 json_object_int_add(json
, "Number of the fragments", count
);
3042 vty_out(vty
, "Scope Zone: Global\n");
3043 vty_out(vty
, "Number of the fragments: %d\n", count
);
3047 frr_each (bsm_frags
, pim
->global_scope
.bsm_frags
, bsfrag
) {
3048 char grp_str
[PREFIX_STRLEN
];
3049 char rp_str
[INET_ADDRSTRLEN
];
3050 char bsr_str
[INET_ADDRSTRLEN
];
3051 struct bsmmsg_grpinfo
*group
;
3052 struct bsmmsg_rpinfo
*rpaddr
;
3054 struct bsm_hdr
*hdr
;
3055 uint32_t offset
= 0;
3058 uint32_t frag_rp_cnt
= 0;
3063 /* skip pim header */
3064 buf
+= PIM_MSG_HEADER_LEN
;
3065 len
-= PIM_MSG_HEADER_LEN
;
3067 hdr
= (struct bsm_hdr
*)buf
;
3069 /* BSM starts with bsr header */
3070 buf
+= sizeof(struct bsm_hdr
);
3071 len
-= sizeof(struct bsm_hdr
);
3073 pim_inet4_dump("<BSR Address?>", hdr
->bsr_addr
.addr
, bsr_str
,
3078 json_object_string_add(json
, "BSR address", bsr_str
);
3079 json_object_int_add(json
, "BSR priority",
3081 json_object_int_add(json
, "Hashmask Length",
3083 json_object_int_add(json
, "Fragment Tag",
3084 ntohs(hdr
->frag_tag
));
3086 vty_out(vty
, "BSM Fragment : %d\n", fragment
);
3087 vty_out(vty
, "------------------\n");
3088 vty_out(vty
, "%-15s %-15s %-15s %-15s\n", "BSR-Address",
3089 "BSR-Priority", "Hashmask-len", "Fragment-Tag");
3090 vty_out(vty
, "%-15s %-15d %-15d %-15d\n", bsr_str
,
3091 hdr
->bsr_prio
, hdr
->hm_len
,
3092 ntohs(hdr
->frag_tag
));
3097 while (offset
< len
) {
3098 group
= (struct bsmmsg_grpinfo
*)buf
;
3100 if (group
->group
.family
== PIM_MSG_ADDRESS_FAMILY_IPV4
)
3101 grp
.family
= AF_INET
;
3103 grp
.prefixlen
= group
->group
.mask
;
3104 grp
.u
.prefix4
.s_addr
= group
->group
.addr
.s_addr
;
3106 prefix2str(&grp
, grp_str
, sizeof(grp_str
));
3108 buf
+= sizeof(struct bsmmsg_grpinfo
);
3109 offset
+= sizeof(struct bsmmsg_grpinfo
);
3112 json_object_object_get_ex(json
, grp_str
,
3115 json_group
= json_object_new_object();
3116 json_object_int_add(json_group
,
3119 json_object_int_add(
3120 json_group
, "Fragment Rp count",
3121 group
->frag_rp_count
);
3122 json_object_object_add(json
, grp_str
,
3126 vty_out(vty
, "Group : %s\n", grp_str
);
3127 vty_out(vty
, "-------------------\n");
3128 vty_out(vty
, "Rp Count:%d\n", group
->rp_count
);
3129 vty_out(vty
, "Fragment Rp Count : %d\n",
3130 group
->frag_rp_count
);
3133 frag_rp_cnt
= group
->frag_rp_count
;
3140 "RpAddress HoldTime Priority\n");
3142 while (frag_rp_cnt
--) {
3143 rpaddr
= (struct bsmmsg_rpinfo
*)buf
;
3145 buf
+= sizeof(struct bsmmsg_rpinfo
);
3146 offset
+= sizeof(struct bsmmsg_rpinfo
);
3148 pim_inet4_dump("<Rp addr?>",
3149 rpaddr
->rpaddr
.addr
, rp_str
,
3153 json_row
= json_object_new_object();
3154 json_object_string_add(
3155 json_row
, "Rp Address", rp_str
);
3156 json_object_int_add(
3157 json_row
, "Rp HoldTime",
3158 ntohs(rpaddr
->rp_holdtime
));
3159 json_object_int_add(json_row
,
3162 json_object_object_add(
3163 json_group
, rp_str
, json_row
);
3165 vty_out(vty
, "%-15s %-12d %d\n", rp_str
,
3166 ntohs(rpaddr
->rp_holdtime
),
3177 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3178 json
, JSON_C_TO_STRING_PRETTY
));
3179 json_object_free(json
);
3183 /*Display the group-rp mappings */
3184 static void pim_show_group_rp_mappings_info(struct pim_instance
*pim
,
3185 struct vty
*vty
, bool uj
)
3187 struct bsgrp_node
*bsgrp
;
3188 struct bsm_rpinfo
*bsm_rp
;
3189 struct route_node
*rn
;
3190 char bsr_str
[INET_ADDRSTRLEN
];
3191 json_object
*json
= NULL
;
3192 json_object
*json_group
= NULL
;
3193 json_object
*json_row
= NULL
;
3195 if (pim
->global_scope
.current_bsr
.s_addr
== INADDR_ANY
)
3196 strlcpy(bsr_str
, "0.0.0.0", sizeof(bsr_str
));
3199 pim_inet4_dump("<bsr?>", pim
->global_scope
.current_bsr
, bsr_str
,
3203 json
= json_object_new_object();
3204 json_object_string_add(json
, "BSR Address", bsr_str
);
3206 vty_out(vty
, "BSR Address %s\n", bsr_str
);
3209 for (rn
= route_top(pim
->global_scope
.bsrp_table
); rn
;
3210 rn
= route_next(rn
)) {
3211 bsgrp
= (struct bsgrp_node
*)rn
->info
;
3216 char grp_str
[PREFIX_STRLEN
];
3218 prefix2str(&bsgrp
->group
, grp_str
, sizeof(grp_str
));
3221 json_object_object_get_ex(json
, grp_str
, &json_group
);
3223 json_group
= json_object_new_object();
3224 json_object_object_add(json
, grp_str
,
3228 vty_out(vty
, "Group Address %pFX\n", &bsgrp
->group
);
3229 vty_out(vty
, "--------------------------\n");
3230 vty_out(vty
, "%-15s %-15s %-15s %-15s\n", "Rp Address",
3231 "priority", "Holdtime", "Hash");
3233 vty_out(vty
, "(ACTIVE)\n");
3236 frr_each (bsm_rpinfos
, bsgrp
->bsrp_list
, bsm_rp
) {
3237 char rp_str
[INET_ADDRSTRLEN
];
3239 pim_inet4_dump("<Rp Address?>", bsm_rp
->rp_address
,
3240 rp_str
, sizeof(rp_str
));
3243 json_row
= json_object_new_object();
3244 json_object_string_add(json_row
, "Rp Address",
3246 json_object_int_add(json_row
, "Rp HoldTime",
3247 bsm_rp
->rp_holdtime
);
3248 json_object_int_add(json_row
, "Rp Priority",
3250 json_object_int_add(json_row
, "Hash Val",
3252 json_object_object_add(json_group
, rp_str
,
3256 vty_out(vty
, "%-15s %-15u %-15u %-15u\n",
3257 rp_str
, bsm_rp
->rp_prio
,
3258 bsm_rp
->rp_holdtime
, bsm_rp
->hash
);
3261 if (!bsm_rpinfos_count(bsgrp
->bsrp_list
) && !uj
)
3262 vty_out(vty
, "Active List is empty.\n");
3265 json_object_int_add(json_group
, "Pending RP count",
3266 bsgrp
->pend_rp_cnt
);
3268 vty_out(vty
, "(PENDING)\n");
3269 vty_out(vty
, "Pending RP count :%d\n",
3270 bsgrp
->pend_rp_cnt
);
3271 if (bsgrp
->pend_rp_cnt
)
3272 vty_out(vty
, "%-15s %-15s %-15s %-15s\n",
3273 "Rp Address", "priority", "Holdtime",
3277 frr_each (bsm_rpinfos
, bsgrp
->partial_bsrp_list
, bsm_rp
) {
3278 char rp_str
[INET_ADDRSTRLEN
];
3280 pim_inet4_dump("<Rp Addr?>", bsm_rp
->rp_address
, rp_str
,
3284 json_row
= json_object_new_object();
3285 json_object_string_add(json_row
, "Rp Address",
3287 json_object_int_add(json_row
, "Rp HoldTime",
3288 bsm_rp
->rp_holdtime
);
3289 json_object_int_add(json_row
, "Rp Priority",
3291 json_object_int_add(json_row
, "Hash Val",
3293 json_object_object_add(json_group
, rp_str
,
3296 vty_out(vty
, "%-15s %-15u %-15u %-15u\n",
3297 rp_str
, bsm_rp
->rp_prio
,
3298 bsm_rp
->rp_holdtime
, bsm_rp
->hash
);
3301 if (!bsm_rpinfos_count(bsgrp
->partial_bsrp_list
) && !uj
)
3302 vty_out(vty
, "Partial List is empty\n");
3309 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3310 json
, JSON_C_TO_STRING_PRETTY
));
3311 json_object_free(json
);
3315 /* pim statistics - just adding only bsm related now.
3316 * We can continue to add all pim related stats here.
3318 static void pim_show_statistics(struct pim_instance
*pim
, struct vty
*vty
,
3319 const char *ifname
, bool uj
)
3321 json_object
*json
= NULL
;
3322 struct interface
*ifp
;
3325 json
= json_object_new_object();
3326 json_object_int_add(json
, "bsmRx", pim
->bsm_rcvd
);
3327 json_object_int_add(json
, "bsmTx", pim
->bsm_sent
);
3328 json_object_int_add(json
, "bsmDropped", pim
->bsm_dropped
);
3330 vty_out(vty
, "BSM Statistics :\n");
3331 vty_out(vty
, "----------------\n");
3332 vty_out(vty
, "Number of Received BSMs : %" PRIu64
"\n",
3334 vty_out(vty
, "Number of Forwared BSMs : %" PRIu64
"\n",
3336 vty_out(vty
, "Number of Dropped BSMs : %" PRIu64
"\n",
3342 /* scan interfaces */
3343 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3344 struct pim_interface
*pim_ifp
= ifp
->info
;
3346 if (ifname
&& strcmp(ifname
, ifp
->name
))
3353 vty_out(vty
, "Interface : %s\n", ifp
->name
);
3354 vty_out(vty
, "-------------------\n");
3356 "Number of BSMs dropped due to config miss : %u\n",
3357 pim_ifp
->pim_ifstat_bsm_cfg_miss
);
3358 vty_out(vty
, "Number of unicast BSMs dropped : %u\n",
3359 pim_ifp
->pim_ifstat_ucast_bsm_cfg_miss
);
3361 "Number of BSMs dropped due to invalid scope zone : %u\n",
3362 pim_ifp
->pim_ifstat_bsm_invalid_sz
);
3365 json_object
*json_row
= NULL
;
3367 json_row
= json_object_new_object();
3369 json_object_string_add(json_row
, "If Name", ifp
->name
);
3370 json_object_int_add(json_row
, "bsmDroppedConfig",
3371 pim_ifp
->pim_ifstat_bsm_cfg_miss
);
3372 json_object_int_add(
3373 json_row
, "bsmDroppedUnicast",
3374 pim_ifp
->pim_ifstat_ucast_bsm_cfg_miss
);
3375 json_object_int_add(json_row
,
3376 "bsmDroppedInvalidScopeZone",
3377 pim_ifp
->pim_ifstat_bsm_invalid_sz
);
3378 json_object_object_add(json
, ifp
->name
, json_row
);
3384 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3385 json
, JSON_C_TO_STRING_PRETTY
));
3386 json_object_free(json
);
3390 static void clear_pim_statistics(struct pim_instance
*pim
)
3392 struct interface
*ifp
;
3396 pim
->bsm_dropped
= 0;
3398 /* scan interfaces */
3399 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3400 struct pim_interface
*pim_ifp
= ifp
->info
;
3405 pim_ifp
->pim_ifstat_bsm_cfg_miss
= 0;
3406 pim_ifp
->pim_ifstat_ucast_bsm_cfg_miss
= 0;
3407 pim_ifp
->pim_ifstat_bsm_invalid_sz
= 0;
3411 static void igmp_show_groups(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
3413 struct interface
*ifp
;
3415 json_object
*json
= NULL
;
3416 json_object
*json_iface
= NULL
;
3417 json_object
*json_group
= NULL
;
3418 json_object
*json_groups
= NULL
;
3420 now
= pim_time_monotonic_sec();
3423 json
= json_object_new_object();
3424 json_object_int_add(json
, "totalGroups", pim
->igmp_group_count
);
3425 json_object_int_add(json
, "watermarkLimit",
3426 pim
->igmp_watermark_limit
);
3428 vty_out(vty
, "Total IGMP groups: %u\n", pim
->igmp_group_count
);
3429 vty_out(vty
, "Watermark warn limit(%s): %u\n",
3430 pim
->igmp_watermark_limit
? "Set" : "Not Set",
3431 pim
->igmp_watermark_limit
);
3433 "Interface Address Group Mode Timer Srcs V Uptime \n");
3436 /* scan interfaces */
3437 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3438 struct pim_interface
*pim_ifp
= ifp
->info
;
3439 struct listnode
*sock_node
;
3440 struct igmp_sock
*igmp
;
3445 /* scan igmp sockets */
3446 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3448 char ifaddr_str
[INET_ADDRSTRLEN
];
3449 struct listnode
*grpnode
;
3450 struct igmp_group
*grp
;
3452 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3453 sizeof(ifaddr_str
));
3455 /* scan igmp groups */
3456 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3458 char group_str
[INET_ADDRSTRLEN
];
3462 pim_inet4_dump("<group?>", grp
->group_addr
,
3463 group_str
, sizeof(group_str
));
3464 pim_time_timer_to_hhmmss(hhmmss
, sizeof(hhmmss
),
3465 grp
->t_group_timer
);
3466 pim_time_uptime(uptime
, sizeof(uptime
),
3467 now
- grp
->group_creation
);
3470 json_object_object_get_ex(
3471 json
, ifp
->name
, &json_iface
);
3475 json_object_new_object();
3476 json_object_pim_ifp_add(
3478 json_object_object_add(
3482 json_object_new_array();
3483 json_object_object_add(
3489 json_group
= json_object_new_object();
3490 json_object_string_add(json_group
,
3493 json_object_string_add(json_group
,
3497 if (grp
->igmp_version
== 3)
3498 json_object_string_add(
3500 grp
->group_filtermode_isexcl
3504 json_object_string_add(json_group
,
3506 json_object_int_add(
3507 json_group
, "sourcesCount",
3508 grp
->group_source_list
3510 grp
->group_source_list
)
3512 json_object_int_add(
3513 json_group
, "version",
3515 json_object_string_add(
3516 json_group
, "uptime", uptime
);
3517 json_object_array_add(json_groups
,
3521 "%-16s %-15s %-15s %4s %8s %4d %d %8s\n",
3522 ifp
->name
, ifaddr_str
,
3524 grp
->igmp_version
== 3
3525 ? (grp
->group_filtermode_isexcl
3530 grp
->group_source_list
3532 grp
->group_source_list
)
3534 grp
->igmp_version
, uptime
);
3536 } /* scan igmp groups */
3537 } /* scan igmp sockets */
3538 } /* scan interfaces */
3541 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3542 json
, JSON_C_TO_STRING_PRETTY
));
3543 json_object_free(json
);
3547 static void igmp_show_group_retransmission(struct pim_instance
*pim
,
3550 struct interface
*ifp
;
3553 "Interface Address Group RetTimer Counter RetSrcs\n");
3555 /* scan interfaces */
3556 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3557 struct pim_interface
*pim_ifp
= ifp
->info
;
3558 struct listnode
*sock_node
;
3559 struct igmp_sock
*igmp
;
3564 /* scan igmp sockets */
3565 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3567 char ifaddr_str
[INET_ADDRSTRLEN
];
3568 struct listnode
*grpnode
;
3569 struct igmp_group
*grp
;
3571 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3572 sizeof(ifaddr_str
));
3574 /* scan igmp groups */
3575 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3577 char group_str
[INET_ADDRSTRLEN
];
3578 char grp_retr_mmss
[10];
3579 struct listnode
*src_node
;
3580 struct igmp_source
*src
;
3581 int grp_retr_sources
= 0;
3583 pim_inet4_dump("<group?>", grp
->group_addr
,
3584 group_str
, sizeof(group_str
));
3585 pim_time_timer_to_mmss(
3586 grp_retr_mmss
, sizeof(grp_retr_mmss
),
3587 grp
->t_group_query_retransmit_timer
);
3590 /* count group sources with retransmission state
3592 for (ALL_LIST_ELEMENTS_RO(
3593 grp
->group_source_list
, src_node
,
3595 if (src
->source_query_retransmit_count
3601 vty_out(vty
, "%-16s %-15s %-15s %-8s %7d %7d\n",
3602 ifp
->name
, ifaddr_str
, group_str
,
3604 grp
->group_specific_query_retransmit_count
,
3607 } /* scan igmp groups */
3608 } /* scan igmp sockets */
3609 } /* scan interfaces */
3612 static void igmp_show_sources(struct pim_instance
*pim
, struct vty
*vty
)
3614 struct interface
*ifp
;
3617 now
= pim_time_monotonic_sec();
3620 "Interface Address Group Source Timer Fwd Uptime \n");
3622 /* scan interfaces */
3623 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3624 struct pim_interface
*pim_ifp
= ifp
->info
;
3625 struct listnode
*sock_node
;
3626 struct igmp_sock
*igmp
;
3631 /* scan igmp sockets */
3632 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3634 char ifaddr_str
[INET_ADDRSTRLEN
];
3635 struct listnode
*grpnode
;
3636 struct igmp_group
*grp
;
3638 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3639 sizeof(ifaddr_str
));
3641 /* scan igmp groups */
3642 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3644 char group_str
[INET_ADDRSTRLEN
];
3645 struct listnode
*srcnode
;
3646 struct igmp_source
*src
;
3648 pim_inet4_dump("<group?>", grp
->group_addr
,
3649 group_str
, sizeof(group_str
));
3651 /* scan group sources */
3652 for (ALL_LIST_ELEMENTS_RO(
3653 grp
->group_source_list
, srcnode
,
3655 char source_str
[INET_ADDRSTRLEN
];
3660 "<source?>", src
->source_addr
,
3661 source_str
, sizeof(source_str
));
3663 pim_time_timer_to_mmss(
3665 src
->t_source_timer
);
3668 uptime
, sizeof(uptime
),
3669 now
- src
->source_creation
);
3672 "%-16s %-15s %-15s %-15s %5s %3s %8s\n",
3673 ifp
->name
, ifaddr_str
,
3674 group_str
, source_str
, mmss
,
3675 IGMP_SOURCE_TEST_FORWARDING(
3681 } /* scan group sources */
3682 } /* scan igmp groups */
3683 } /* scan igmp sockets */
3684 } /* scan interfaces */
3687 static void igmp_show_source_retransmission(struct pim_instance
*pim
,
3690 struct interface
*ifp
;
3693 "Interface Address Group Source Counter\n");
3695 /* scan interfaces */
3696 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3697 struct pim_interface
*pim_ifp
= ifp
->info
;
3698 struct listnode
*sock_node
;
3699 struct igmp_sock
*igmp
;
3704 /* scan igmp sockets */
3705 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3707 char ifaddr_str
[INET_ADDRSTRLEN
];
3708 struct listnode
*grpnode
;
3709 struct igmp_group
*grp
;
3711 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3712 sizeof(ifaddr_str
));
3714 /* scan igmp groups */
3715 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3717 char group_str
[INET_ADDRSTRLEN
];
3718 struct listnode
*srcnode
;
3719 struct igmp_source
*src
;
3721 pim_inet4_dump("<group?>", grp
->group_addr
,
3722 group_str
, sizeof(group_str
));
3724 /* scan group sources */
3725 for (ALL_LIST_ELEMENTS_RO(
3726 grp
->group_source_list
, srcnode
,
3728 char source_str
[INET_ADDRSTRLEN
];
3731 "<source?>", src
->source_addr
,
3732 source_str
, sizeof(source_str
));
3735 "%-16s %-15s %-15s %-15s %7d\n",
3736 ifp
->name
, ifaddr_str
,
3737 group_str
, source_str
,
3738 src
->source_query_retransmit_count
);
3740 } /* scan group sources */
3741 } /* scan igmp groups */
3742 } /* scan igmp sockets */
3743 } /* scan interfaces */
3746 static void pim_show_bsr(struct pim_instance
*pim
,
3751 char last_bsm_seen
[10];
3754 char bsr_str
[PREFIX_STRLEN
];
3755 json_object
*json
= NULL
;
3757 if (pim
->global_scope
.current_bsr
.s_addr
== INADDR_ANY
) {
3758 strlcpy(bsr_str
, "0.0.0.0", sizeof(bsr_str
));
3759 pim_time_uptime(uptime
, sizeof(uptime
),
3760 pim
->global_scope
.current_bsr_first_ts
);
3761 pim_time_uptime(last_bsm_seen
, sizeof(last_bsm_seen
),
3762 pim
->global_scope
.current_bsr_last_ts
);
3766 pim_inet4_dump("<bsr?>", pim
->global_scope
.current_bsr
,
3767 bsr_str
, sizeof(bsr_str
));
3768 now
= pim_time_monotonic_sec();
3769 pim_time_uptime(uptime
, sizeof(uptime
),
3770 (now
- pim
->global_scope
.current_bsr_first_ts
));
3771 pim_time_uptime(last_bsm_seen
, sizeof(last_bsm_seen
),
3772 now
- pim
->global_scope
.current_bsr_last_ts
);
3775 switch (pim
->global_scope
.state
) {
3777 strlcpy(bsr_state
, "NO_INFO", sizeof(bsr_state
));
3780 strlcpy(bsr_state
, "ACCEPT_ANY", sizeof(bsr_state
));
3782 case ACCEPT_PREFERRED
:
3783 strlcpy(bsr_state
, "ACCEPT_PREFERRED", sizeof(bsr_state
));
3786 strlcpy(bsr_state
, "", sizeof(bsr_state
));
3790 json
= json_object_new_object();
3791 json_object_string_add(json
, "bsr", bsr_str
);
3792 json_object_int_add(json
, "priority",
3793 pim
->global_scope
.current_bsr_prio
);
3794 json_object_int_add(json
, "fragmentTag",
3795 pim
->global_scope
.bsm_frag_tag
);
3796 json_object_string_add(json
, "state", bsr_state
);
3797 json_object_string_add(json
, "upTime", uptime
);
3798 json_object_string_add(json
, "lastBsmSeen", last_bsm_seen
);
3802 vty_out(vty
, "PIMv2 Bootstrap information\n");
3803 vty_out(vty
, "Current preferred BSR address: %s\n", bsr_str
);
3805 "Priority Fragment-Tag State UpTime\n");
3806 vty_out(vty
, " %-12d %-12d %-13s %7s\n",
3807 pim
->global_scope
.current_bsr_prio
,
3808 pim
->global_scope
.bsm_frag_tag
,
3811 vty_out(vty
, "Last BSM seen: %s\n", last_bsm_seen
);
3815 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3816 json
, JSON_C_TO_STRING_PRETTY
));
3817 json_object_free(json
);
3821 static void clear_igmp_interfaces(struct pim_instance
*pim
)
3823 struct interface
*ifp
;
3825 FOR_ALL_INTERFACES (pim
->vrf
, ifp
)
3826 pim_if_addr_del_all_igmp(ifp
);
3828 FOR_ALL_INTERFACES (pim
->vrf
, ifp
)
3829 pim_if_addr_add_all(ifp
);
3832 static void clear_pim_interfaces(struct pim_instance
*pim
)
3834 struct interface
*ifp
;
3836 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3838 pim_neighbor_delete_all(ifp
, "interface cleared");
3843 static void clear_interfaces(struct pim_instance
*pim
)
3845 clear_igmp_interfaces(pim
);
3846 clear_pim_interfaces(pim
);
3849 #define PIM_GET_PIM_INTERFACE(pim_ifp, ifp) \
3850 pim_ifp = ifp->info; \
3853 "%% Enable PIM and/or IGMP on this interface first\n"); \
3854 return CMD_WARNING_CONFIG_FAILED; \
3858 * Get current node VRF name.
3861 * In case of failure it will print error message to user.
3863 * \returns name or NULL if failed to get VRF.
3865 static const char *pim_cli_get_vrf_name(struct vty
*vty
)
3867 const struct lyd_node
*vrf_node
;
3869 /* Not inside any VRF context. */
3870 if (vty
->xpath_index
== 0)
3871 return VRF_DEFAULT_NAME
;
3873 vrf_node
= yang_dnode_get(vty
->candidate_config
->dnode
, VTY_CURR_XPATH
);
3874 if (vrf_node
== NULL
) {
3875 vty_out(vty
, "%% Failed to get vrf dnode in configuration\n");
3879 return yang_dnode_get_string(vrf_node
, "./name");
3883 * Compatibility function to keep the legacy mesh group CLI behavior:
3884 * Delete group when there are no more configurations in it.
3887 * Don't forget to call `nb_cli_apply_changes` after this.
3889 static void pim_cli_legacy_mesh_group_behavior(struct vty
*vty
,
3892 const char *vrfname
;
3893 char xpath_value
[XPATH_MAXLEN
];
3894 char xpath_member_value
[XPATH_MAXLEN
];
3895 const struct lyd_node
*member_dnode
;
3897 vrfname
= pim_cli_get_vrf_name(vty
);
3898 if (vrfname
== NULL
)
3901 /* Get mesh group base XPath. */
3902 snprintf(xpath_value
, sizeof(xpath_value
),
3903 FRR_PIM_AF_XPATH
"/msdp-mesh-groups[name='%s']",
3904 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4", gname
);
3905 /* Group must exists, otherwise just quit. */
3906 if (!yang_dnode_exists(vty
->candidate_config
->dnode
, xpath_value
))
3909 /* Group members check: */
3910 strlcpy(xpath_member_value
, xpath_value
, sizeof(xpath_member_value
));
3911 strlcat(xpath_member_value
, "/members", sizeof(xpath_member_value
));
3912 if (yang_dnode_exists(vty
->candidate_config
->dnode
,
3913 xpath_member_value
)) {
3914 member_dnode
= yang_dnode_get(vty
->candidate_config
->dnode
,
3915 xpath_member_value
);
3916 if (!yang_is_last_list_dnode(member_dnode
))
3920 /* Source address check: */
3921 strlcpy(xpath_member_value
, xpath_value
, sizeof(xpath_member_value
));
3922 strlcat(xpath_member_value
, "/source", sizeof(xpath_member_value
));
3923 if (yang_dnode_exists(vty
->candidate_config
->dnode
, xpath_member_value
))
3926 /* No configurations found: delete it. */
3927 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_DESTROY
, NULL
);
3930 DEFUN (clear_ip_interfaces
,
3931 clear_ip_interfaces_cmd
,
3932 "clear ip interfaces [vrf NAME]",
3935 "Reset interfaces\n"
3939 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3944 clear_interfaces(vrf
->info
);
3949 DEFUN (clear_ip_igmp_interfaces
,
3950 clear_ip_igmp_interfaces_cmd
,
3951 "clear ip igmp [vrf NAME] interfaces",
3956 "Reset IGMP interfaces\n")
3959 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3964 clear_igmp_interfaces(vrf
->info
);
3969 DEFUN (clear_ip_pim_statistics
,
3970 clear_ip_pim_statistics_cmd
,
3971 "clear ip pim statistics [vrf NAME]",
3976 "Reset PIM statistics\n")
3979 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3984 clear_pim_statistics(vrf
->info
);
3988 static void clear_mroute(struct pim_instance
*pim
)
3990 struct pim_upstream
*up
;
3991 struct interface
*ifp
;
3993 /* scan interfaces */
3994 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3995 struct pim_interface
*pim_ifp
= ifp
->info
;
3996 struct listnode
*sock_node
;
3997 struct igmp_sock
*igmp
;
3998 struct pim_ifchannel
*ch
;
4003 /* deleting all ifchannels */
4004 while (!RB_EMPTY(pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
)) {
4005 ch
= RB_ROOT(pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
);
4007 pim_ifchannel_delete(ch
);
4010 /* clean up all igmp groups */
4011 /* scan igmp sockets */
4012 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
4015 struct igmp_group
*grp
;
4017 if (igmp
->igmp_group_list
) {
4018 while (igmp
->igmp_group_list
->count
) {
4019 grp
= listnode_head(
4020 igmp
->igmp_group_list
);
4021 igmp_group_delete(grp
);
4028 /* clean up all upstreams*/
4029 while ((up
= rb_pim_upstream_first(&pim
->upstream_head
)))
4030 pim_upstream_del(pim
, up
, __func__
);
4034 DEFUN (clear_ip_mroute
,
4035 clear_ip_mroute_cmd
,
4036 "clear ip mroute [vrf NAME]",
4039 "Reset multicast routes\n"
4043 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4048 clear_mroute(vrf
->info
);
4053 DEFUN (clear_ip_pim_interfaces
,
4054 clear_ip_pim_interfaces_cmd
,
4055 "clear ip pim [vrf NAME] interfaces",
4060 "Reset PIM interfaces\n")
4063 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4068 clear_pim_interfaces(vrf
->info
);
4073 DEFUN (clear_ip_pim_interface_traffic
,
4074 clear_ip_pim_interface_traffic_cmd
,
4075 "clear ip pim [vrf NAME] interface traffic",
4078 "PIM clear commands\n"
4080 "Reset PIM interfaces\n"
4081 "Reset Protocol Packet counters\n")
4084 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4085 struct interface
*ifp
= NULL
;
4086 struct pim_interface
*pim_ifp
= NULL
;
4091 FOR_ALL_INTERFACES (vrf
, ifp
) {
4092 pim_ifp
= ifp
->info
;
4097 pim_ifp
->pim_ifstat_hello_recv
= 0;
4098 pim_ifp
->pim_ifstat_hello_sent
= 0;
4099 pim_ifp
->pim_ifstat_join_recv
= 0;
4100 pim_ifp
->pim_ifstat_join_send
= 0;
4101 pim_ifp
->pim_ifstat_prune_recv
= 0;
4102 pim_ifp
->pim_ifstat_prune_send
= 0;
4103 pim_ifp
->pim_ifstat_reg_recv
= 0;
4104 pim_ifp
->pim_ifstat_reg_send
= 0;
4105 pim_ifp
->pim_ifstat_reg_stop_recv
= 0;
4106 pim_ifp
->pim_ifstat_reg_stop_send
= 0;
4107 pim_ifp
->pim_ifstat_assert_recv
= 0;
4108 pim_ifp
->pim_ifstat_assert_send
= 0;
4109 pim_ifp
->pim_ifstat_bsm_rx
= 0;
4110 pim_ifp
->pim_ifstat_bsm_tx
= 0;
4116 DEFUN (clear_ip_pim_oil
,
4117 clear_ip_pim_oil_cmd
,
4118 "clear ip pim [vrf NAME] oil",
4123 "Rescan PIM OIL (output interface list)\n")
4126 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4131 pim_scan_oil(vrf
->info
);
4136 static void clear_pim_bsr_db(struct pim_instance
*pim
)
4138 struct route_node
*rn
;
4139 struct route_node
*rpnode
;
4140 struct bsgrp_node
*bsgrp
;
4141 struct prefix nht_p
;
4142 struct prefix g_all
;
4143 struct rp_info
*rp_all
;
4144 struct pim_upstream
*up
;
4145 struct rp_info
*rp_info
;
4146 bool is_bsr_tracking
= true;
4148 /* Remove next hop tracking for the bsr */
4149 nht_p
.family
= AF_INET
;
4150 nht_p
.prefixlen
= IPV4_MAX_BITLEN
;
4151 nht_p
.u
.prefix4
= pim
->global_scope
.current_bsr
;
4152 if (PIM_DEBUG_BSM
) {
4153 zlog_debug("%s: Deregister BSR addr %pFX with Zebra NHT",
4156 pim_delete_tracked_nexthop(pim
, &nht_p
, NULL
, NULL
, is_bsr_tracking
);
4158 /* Reset scope zone data */
4159 pim
->global_scope
.accept_nofwd_bsm
= false;
4160 pim
->global_scope
.state
= ACCEPT_ANY
;
4161 pim
->global_scope
.current_bsr
.s_addr
= INADDR_ANY
;
4162 pim
->global_scope
.current_bsr_prio
= 0;
4163 pim
->global_scope
.current_bsr_first_ts
= 0;
4164 pim
->global_scope
.current_bsr_last_ts
= 0;
4165 pim
->global_scope
.bsm_frag_tag
= 0;
4166 pim_bsm_frags_free(&pim
->global_scope
);
4168 pim_bs_timer_stop(&pim
->global_scope
);
4170 for (rn
= route_top(pim
->global_scope
.bsrp_table
); rn
;
4171 rn
= route_next(rn
)) {
4176 rpnode
= route_node_lookup(pim
->rp_table
, &bsgrp
->group
);
4179 pim_free_bsgrp_node(bsgrp
->scope
->bsrp_table
,
4181 pim_free_bsgrp_data(bsgrp
);
4185 rp_info
= (struct rp_info
*)rpnode
->info
;
4187 if ((!rp_info
) || (rp_info
->rp_src
!= RP_SRC_BSR
)) {
4188 pim_free_bsgrp_node(bsgrp
->scope
->bsrp_table
,
4190 pim_free_bsgrp_data(bsgrp
);
4194 /* Deregister addr with Zebra NHT */
4195 nht_p
.family
= AF_INET
;
4196 nht_p
.prefixlen
= IPV4_MAX_BITLEN
;
4197 nht_p
.u
.prefix4
= rp_info
->rp
.rpf_addr
.u
.prefix4
;
4199 if (PIM_DEBUG_PIM_NHT_RP
) {
4200 zlog_debug("%s: Deregister RP addr %pFX with Zebra ",
4204 pim_delete_tracked_nexthop(pim
, &nht_p
, NULL
, rp_info
, false);
4206 if (!str2prefix("224.0.0.0/4", &g_all
))
4209 rp_all
= pim_rp_find_match_group(pim
, &g_all
);
4211 if (rp_all
== rp_info
) {
4212 rp_all
->rp
.rpf_addr
.family
= AF_INET
;
4213 rp_all
->rp
.rpf_addr
.u
.prefix4
.s_addr
= INADDR_NONE
;
4214 rp_all
->i_am_rp
= 0;
4216 /* Delete the rp_info from rp-list */
4217 listnode_delete(pim
->rp_list
, rp_info
);
4219 /* Delete the rp node from rp_table */
4220 rpnode
->info
= NULL
;
4221 route_unlock_node(rpnode
);
4222 route_unlock_node(rpnode
);
4225 XFREE(MTYPE_PIM_RP
, rp_info
);
4227 pim_free_bsgrp_node(bsgrp
->scope
->bsrp_table
, &bsgrp
->group
);
4228 pim_free_bsgrp_data(bsgrp
);
4230 pim_rp_refresh_group_to_rp_mapping(pim
);
4233 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
4234 /* Find the upstream (*, G) whose upstream address is same as
4237 if (up
->sg
.src
.s_addr
!= INADDR_ANY
)
4241 struct rp_info
*trp_info
;
4243 grp
.family
= AF_INET
;
4244 grp
.prefixlen
= IPV4_MAX_BITLEN
;
4245 grp
.u
.prefix4
= up
->sg
.grp
;
4247 trp_info
= pim_rp_find_match_group(pim
, &grp
);
4249 /* RP not found for the group grp */
4250 if (pim_rpf_addr_is_inaddr_none(&trp_info
->rp
)) {
4251 pim_upstream_rpf_clear(pim
, up
);
4252 pim_rp_set_upstream_addr(pim
, &up
->upstream_addr
,
4253 up
->sg
.src
, up
->sg
.grp
);
4255 /* RP found for the group grp */
4256 pim_upstream_update(pim
, up
);
4262 DEFUN (clear_ip_pim_bsr_db
,
4263 clear_ip_pim_bsr_db_cmd
,
4264 "clear ip pim [vrf NAME] bsr-data",
4269 "Reset pim bsr data\n")
4272 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4277 clear_pim_bsr_db(vrf
->info
);
4282 DEFUN (show_ip_igmp_interface
,
4283 show_ip_igmp_interface_cmd
,
4284 "show ip igmp [vrf NAME] interface [detail|WORD] [json]",
4289 "IGMP interface information\n"
4295 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4296 bool uj
= use_json(argc
, argv
);
4301 if (argv_find(argv
, argc
, "detail", &idx
)
4302 || argv_find(argv
, argc
, "WORD", &idx
))
4303 igmp_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
4305 igmp_show_interfaces(vrf
->info
, vty
, uj
);
4310 DEFUN (show_ip_igmp_interface_vrf_all
,
4311 show_ip_igmp_interface_vrf_all_cmd
,
4312 "show ip igmp vrf all interface [detail|WORD] [json]",
4317 "IGMP interface information\n"
4323 bool uj
= use_json(argc
, argv
);
4329 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4333 vty_out(vty
, " \"%s\": ", vrf
->name
);
4336 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4337 if (argv_find(argv
, argc
, "detail", &idx
)
4338 || argv_find(argv
, argc
, "WORD", &idx
))
4339 igmp_show_interfaces_single(vrf
->info
, vty
,
4340 argv
[idx
]->arg
, uj
);
4342 igmp_show_interfaces(vrf
->info
, vty
, uj
);
4345 vty_out(vty
, "}\n");
4350 DEFUN (show_ip_igmp_join
,
4351 show_ip_igmp_join_cmd
,
4352 "show ip igmp [vrf NAME] join [json]",
4357 "IGMP static join information\n"
4361 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4362 bool uj
= use_json(argc
, argv
);
4367 igmp_show_interface_join(vrf
->info
, vty
, uj
);
4372 DEFUN (show_ip_igmp_join_vrf_all
,
4373 show_ip_igmp_join_vrf_all_cmd
,
4374 "show ip igmp vrf all join [json]",
4379 "IGMP static join information\n"
4382 bool uj
= use_json(argc
, argv
);
4388 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4392 vty_out(vty
, " \"%s\": ", vrf
->name
);
4395 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4396 igmp_show_interface_join(vrf
->info
, vty
, uj
);
4399 vty_out(vty
, "}\n");
4404 DEFUN (show_ip_igmp_groups
,
4405 show_ip_igmp_groups_cmd
,
4406 "show ip igmp [vrf NAME] groups [json]",
4415 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4416 bool uj
= use_json(argc
, argv
);
4421 igmp_show_groups(vrf
->info
, vty
, uj
);
4426 DEFUN (show_ip_igmp_groups_vrf_all
,
4427 show_ip_igmp_groups_vrf_all_cmd
,
4428 "show ip igmp vrf all groups [json]",
4436 bool uj
= use_json(argc
, argv
);
4442 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4446 vty_out(vty
, " \"%s\": ", vrf
->name
);
4449 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4450 igmp_show_groups(vrf
->info
, vty
, uj
);
4453 vty_out(vty
, "}\n");
4458 DEFUN (show_ip_igmp_groups_retransmissions
,
4459 show_ip_igmp_groups_retransmissions_cmd
,
4460 "show ip igmp [vrf NAME] groups retransmissions",
4466 "IGMP group retransmissions\n")
4469 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4474 igmp_show_group_retransmission(vrf
->info
, vty
);
4479 DEFUN (show_ip_igmp_sources
,
4480 show_ip_igmp_sources_cmd
,
4481 "show ip igmp [vrf NAME] sources",
4489 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4494 igmp_show_sources(vrf
->info
, vty
);
4499 DEFUN (show_ip_igmp_sources_retransmissions
,
4500 show_ip_igmp_sources_retransmissions_cmd
,
4501 "show ip igmp [vrf NAME] sources retransmissions",
4507 "IGMP source retransmissions\n")
4510 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4515 igmp_show_source_retransmission(vrf
->info
, vty
);
4520 DEFUN (show_ip_igmp_statistics
,
4521 show_ip_igmp_statistics_cmd
,
4522 "show ip igmp [vrf NAME] statistics [interface WORD] [json]",
4533 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4534 bool uj
= use_json(argc
, argv
);
4539 if (argv_find(argv
, argc
, "WORD", &idx
))
4540 igmp_show_statistics(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
4542 igmp_show_statistics(vrf
->info
, vty
, NULL
, uj
);
4547 DEFUN (show_ip_pim_mlag_summary
,
4548 show_ip_pim_mlag_summary_cmd
,
4549 "show ip pim mlag summary [json]",
4554 "status and stats\n"
4557 bool uj
= use_json(argc
, argv
);
4558 char role_buf
[MLAG_ROLE_STRSIZE
];
4559 char addr_buf
[INET_ADDRSTRLEN
];
4562 json_object
*json
= NULL
;
4563 json_object
*json_stat
= NULL
;
4565 json
= json_object_new_object();
4566 if (router
->mlag_flags
& PIM_MLAGF_LOCAL_CONN_UP
)
4567 json_object_boolean_true_add(json
, "mlagConnUp");
4568 if (router
->mlag_flags
& PIM_MLAGF_PEER_CONN_UP
)
4569 json_object_boolean_true_add(json
, "mlagPeerConnUp");
4570 if (router
->mlag_flags
& PIM_MLAGF_PEER_ZEBRA_UP
)
4571 json_object_boolean_true_add(json
, "mlagPeerZebraUp");
4572 json_object_string_add(json
, "mlagRole",
4573 mlag_role2str(router
->mlag_role
,
4574 role_buf
, sizeof(role_buf
)));
4575 inet_ntop(AF_INET
, &router
->local_vtep_ip
,
4576 addr_buf
, INET_ADDRSTRLEN
);
4577 json_object_string_add(json
, "localVtepIp", addr_buf
);
4578 inet_ntop(AF_INET
, &router
->anycast_vtep_ip
,
4579 addr_buf
, INET_ADDRSTRLEN
);
4580 json_object_string_add(json
, "anycastVtepIp", addr_buf
);
4581 json_object_string_add(json
, "peerlinkRif",
4582 router
->peerlink_rif
);
4584 json_stat
= json_object_new_object();
4585 json_object_int_add(json_stat
, "mlagConnFlaps",
4586 router
->mlag_stats
.mlagd_session_downs
);
4587 json_object_int_add(json_stat
, "mlagPeerConnFlaps",
4588 router
->mlag_stats
.peer_session_downs
);
4589 json_object_int_add(json_stat
, "mlagPeerZebraFlaps",
4590 router
->mlag_stats
.peer_zebra_downs
);
4591 json_object_int_add(json_stat
, "mrouteAddRx",
4592 router
->mlag_stats
.msg
.mroute_add_rx
);
4593 json_object_int_add(json_stat
, "mrouteAddTx",
4594 router
->mlag_stats
.msg
.mroute_add_tx
);
4595 json_object_int_add(json_stat
, "mrouteDelRx",
4596 router
->mlag_stats
.msg
.mroute_del_rx
);
4597 json_object_int_add(json_stat
, "mrouteDelTx",
4598 router
->mlag_stats
.msg
.mroute_del_tx
);
4599 json_object_int_add(json_stat
, "mlagStatusUpdates",
4600 router
->mlag_stats
.msg
.mlag_status_updates
);
4601 json_object_int_add(json_stat
, "peerZebraStatusUpdates",
4602 router
->mlag_stats
.msg
.peer_zebra_status_updates
);
4603 json_object_int_add(json_stat
, "pimStatusUpdates",
4604 router
->mlag_stats
.msg
.pim_status_updates
);
4605 json_object_int_add(json_stat
, "vxlanUpdates",
4606 router
->mlag_stats
.msg
.vxlan_updates
);
4607 json_object_object_add(json
, "connStats", json_stat
);
4609 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4610 json
, JSON_C_TO_STRING_PRETTY
));
4611 json_object_free(json
);
4615 vty_out(vty
, "MLAG daemon connection: %s\n",
4616 (router
->mlag_flags
& PIM_MLAGF_LOCAL_CONN_UP
)
4618 vty_out(vty
, "MLAG peer state: %s\n",
4619 (router
->mlag_flags
& PIM_MLAGF_PEER_CONN_UP
)
4621 vty_out(vty
, "Zebra peer state: %s\n",
4622 (router
->mlag_flags
& PIM_MLAGF_PEER_ZEBRA_UP
)
4624 vty_out(vty
, "MLAG role: %s\n",
4625 mlag_role2str(router
->mlag_role
, role_buf
, sizeof(role_buf
)));
4626 inet_ntop(AF_INET
, &router
->local_vtep_ip
,
4627 addr_buf
, INET_ADDRSTRLEN
);
4628 vty_out(vty
, "Local VTEP IP: %s\n", addr_buf
);
4629 inet_ntop(AF_INET
, &router
->anycast_vtep_ip
,
4630 addr_buf
, INET_ADDRSTRLEN
);
4631 vty_out(vty
, "Anycast VTEP IP: %s\n", addr_buf
);
4632 vty_out(vty
, "Peerlink: %s\n", router
->peerlink_rif
);
4633 vty_out(vty
, "Session flaps: mlagd: %d mlag-peer: %d zebra-peer: %d\n",
4634 router
->mlag_stats
.mlagd_session_downs
,
4635 router
->mlag_stats
.peer_session_downs
,
4636 router
->mlag_stats
.peer_zebra_downs
);
4637 vty_out(vty
, "Message Statistics:\n");
4638 vty_out(vty
, " mroute adds: rx: %d, tx: %d\n",
4639 router
->mlag_stats
.msg
.mroute_add_rx
,
4640 router
->mlag_stats
.msg
.mroute_add_tx
);
4641 vty_out(vty
, " mroute dels: rx: %d, tx: %d\n",
4642 router
->mlag_stats
.msg
.mroute_del_rx
,
4643 router
->mlag_stats
.msg
.mroute_del_tx
);
4644 vty_out(vty
, " peer zebra status updates: %d\n",
4645 router
->mlag_stats
.msg
.peer_zebra_status_updates
);
4646 vty_out(vty
, " PIM status updates: %d\n",
4647 router
->mlag_stats
.msg
.pim_status_updates
);
4648 vty_out(vty
, " VxLAN updates: %d\n",
4649 router
->mlag_stats
.msg
.vxlan_updates
);
4654 DEFUN (show_ip_pim_assert
,
4655 show_ip_pim_assert_cmd
,
4656 "show ip pim [vrf NAME] assert",
4661 "PIM interface assert\n")
4664 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4669 pim_show_assert(vrf
->info
, vty
);
4674 DEFUN (show_ip_pim_assert_internal
,
4675 show_ip_pim_assert_internal_cmd
,
4676 "show ip pim [vrf NAME] assert-internal",
4681 "PIM interface internal assert state\n")
4684 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4689 pim_show_assert_internal(vrf
->info
, vty
);
4694 DEFUN (show_ip_pim_assert_metric
,
4695 show_ip_pim_assert_metric_cmd
,
4696 "show ip pim [vrf NAME] assert-metric",
4701 "PIM interface assert metric\n")
4704 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4709 pim_show_assert_metric(vrf
->info
, vty
);
4714 DEFUN (show_ip_pim_assert_winner_metric
,
4715 show_ip_pim_assert_winner_metric_cmd
,
4716 "show ip pim [vrf NAME] assert-winner-metric",
4721 "PIM interface assert winner metric\n")
4724 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4729 pim_show_assert_winner_metric(vrf
->info
, vty
);
4734 DEFUN (show_ip_pim_interface
,
4735 show_ip_pim_interface_cmd
,
4736 "show ip pim [mlag] [vrf NAME] interface [detail|WORD] [json]",
4742 "PIM interface information\n"
4748 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4749 bool uj
= use_json(argc
, argv
);
4755 if (argv_find(argv
, argc
, "mlag", &idx
))
4758 if (argv_find(argv
, argc
, "WORD", &idx
)
4759 || argv_find(argv
, argc
, "detail", &idx
))
4760 pim_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, mlag
,
4763 pim_show_interfaces(vrf
->info
, vty
, mlag
, uj
);
4768 DEFUN (show_ip_pim_interface_vrf_all
,
4769 show_ip_pim_interface_vrf_all_cmd
,
4770 "show ip pim [mlag] vrf all interface [detail|WORD] [json]",
4776 "PIM interface information\n"
4782 bool uj
= use_json(argc
, argv
);
4787 if (argv_find(argv
, argc
, "mlag", &idx
))
4793 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4797 vty_out(vty
, " \"%s\": ", vrf
->name
);
4800 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4801 if (argv_find(argv
, argc
, "WORD", &idx
)
4802 || argv_find(argv
, argc
, "detail", &idx
))
4803 pim_show_interfaces_single(vrf
->info
, vty
,
4804 argv
[idx
]->arg
, mlag
, uj
);
4806 pim_show_interfaces(vrf
->info
, vty
, mlag
, uj
);
4809 vty_out(vty
, "}\n");
4814 DEFPY (show_ip_pim_join
,
4815 show_ip_pim_join_cmd
,
4816 "show ip pim [vrf NAME] join [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
4821 "PIM interface join information\n"
4822 "The Source or Group\n"
4826 struct prefix_sg sg
= {0};
4829 struct pim_instance
*pim
;
4831 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
4834 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
4837 pim
= pim_get_pim_instance(v
->vrf_id
);
4840 vty_out(vty
, "%% Unable to find pim instance\n");
4844 if (s_or_g
.s_addr
!= INADDR_ANY
) {
4845 if (g
.s_addr
!= INADDR_ANY
) {
4852 pim_show_join(pim
, vty
, &sg
, uj
);
4857 DEFUN (show_ip_pim_join_vrf_all
,
4858 show_ip_pim_join_vrf_all_cmd
,
4859 "show ip pim vrf all join [json]",
4864 "PIM interface join information\n"
4867 struct prefix_sg sg
= {0};
4868 bool uj
= use_json(argc
, argv
);
4874 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4878 vty_out(vty
, " \"%s\": ", vrf
->name
);
4881 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4882 pim_show_join(vrf
->info
, vty
, &sg
, uj
);
4885 vty_out(vty
, "}\n");
4890 static void pim_show_jp_agg_helper(struct vty
*vty
,
4891 struct interface
*ifp
,
4892 struct pim_neighbor
*neigh
,
4893 struct pim_upstream
*up
,
4896 char src_str
[INET_ADDRSTRLEN
];
4897 char grp_str
[INET_ADDRSTRLEN
];
4898 char rpf_str
[INET_ADDRSTRLEN
];
4900 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
4901 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
4902 /* pius->address.s_addr */
4903 pim_inet4_dump("<rpf?>", neigh
->source_addr
, rpf_str
, sizeof(rpf_str
));
4905 vty_out(vty
, "%-16s %-15s %-15s %-15s %5s\n",
4906 ifp
->name
, rpf_str
, src_str
,
4907 grp_str
, is_join
?"J":"P");
4910 static void pim_show_jp_agg_list(struct pim_instance
*pim
, struct vty
*vty
)
4912 struct interface
*ifp
;
4913 struct pim_interface
*pim_ifp
;
4914 struct listnode
*n_node
;
4915 struct pim_neighbor
*neigh
;
4916 struct listnode
*jag_node
;
4917 struct pim_jp_agg_group
*jag
;
4918 struct listnode
*js_node
;
4919 struct pim_jp_sources
*js
;
4922 "Interface RPF Nbr Source Group State\n");
4924 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
4925 pim_ifp
= ifp
->info
;
4929 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
,
4931 for (ALL_LIST_ELEMENTS_RO(neigh
->upstream_jp_agg
,
4933 for (ALL_LIST_ELEMENTS_RO(jag
->sources
,
4935 pim_show_jp_agg_helper(vty
,
4944 DEFPY (show_ip_pim_jp_agg
,
4945 show_ip_pim_jp_agg_cmd
,
4946 "show ip pim [vrf NAME] jp-agg",
4951 "join prune aggregation list\n")
4954 struct pim_instance
*pim
;
4956 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
4959 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
4962 pim
= pim_get_pim_instance(v
->vrf_id
);
4965 vty_out(vty
, "%% Unable to find pim instance\n");
4969 pim_show_jp_agg_list(pim
, vty
);
4974 DEFUN (show_ip_pim_local_membership
,
4975 show_ip_pim_local_membership_cmd
,
4976 "show ip pim [vrf NAME] local-membership [json]",
4981 "PIM interface local-membership\n"
4985 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4986 bool uj
= use_json(argc
, argv
);
4991 pim_show_membership(vrf
->info
, vty
, uj
);
4996 static void pim_show_mlag_up_entry_detail(struct vrf
*vrf
,
4998 struct pim_upstream
*up
,
4999 char *src_str
, char *grp_str
,
5003 json_object
*json_row
= NULL
;
5004 json_object
*own_list
= NULL
;
5005 json_object
*json_group
= NULL
;
5008 json_object_object_get_ex(json
, grp_str
, &json_group
);
5010 json_group
= json_object_new_object();
5011 json_object_object_add(json
, grp_str
,
5015 json_row
= json_object_new_object();
5016 json_object_string_add(json_row
, "source", src_str
);
5017 json_object_string_add(json_row
, "group", grp_str
);
5019 own_list
= json_object_new_array();
5020 if (pim_up_mlag_is_local(up
))
5021 json_object_array_add(own_list
,
5022 json_object_new_string("local"));
5023 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
))
5024 json_object_array_add(own_list
,
5025 json_object_new_string("peer"));
5026 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE
))
5027 json_object_array_add(
5028 own_list
, json_object_new_string("Interface"));
5029 json_object_object_add(json_row
, "owners", own_list
);
5031 json_object_int_add(json_row
, "localCost",
5032 pim_up_mlag_local_cost(up
));
5033 json_object_int_add(json_row
, "peerCost",
5034 pim_up_mlag_peer_cost(up
));
5035 if (PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up
->flags
))
5036 json_object_boolean_false_add(json_row
, "df");
5038 json_object_boolean_true_add(json_row
, "df");
5039 json_object_object_add(json_group
, src_str
, json_row
);
5044 if (pim_up_mlag_is_local(up
))
5045 strlcat(own_str
, "L", sizeof(own_str
));
5046 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
))
5047 strlcat(own_str
, "P", sizeof(own_str
));
5048 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE
))
5049 strlcat(own_str
, "I", sizeof(own_str
));
5050 /* XXX - fixup, print paragraph output */
5052 "%-15s %-15s %-6s %-11u %-10d %2s\n",
5053 src_str
, grp_str
, own_str
,
5054 pim_up_mlag_local_cost(up
),
5055 pim_up_mlag_peer_cost(up
),
5056 PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up
->flags
)
5061 static void pim_show_mlag_up_detail(struct vrf
*vrf
,
5062 struct vty
*vty
, const char *src_or_group
,
5063 const char *group
, bool uj
)
5065 char src_str
[INET_ADDRSTRLEN
];
5066 char grp_str
[INET_ADDRSTRLEN
];
5067 struct pim_upstream
*up
;
5068 struct pim_instance
*pim
= vrf
->info
;
5069 json_object
*json
= NULL
;
5072 json
= json_object_new_object();
5075 "Source Group Owner Local-cost Peer-cost DF\n");
5077 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
5078 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
)
5079 && !(up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE
)
5080 && !pim_up_mlag_is_local(up
))
5083 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
5084 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
5085 /* XXX: strcmps are clearly inefficient. we should do uint comps
5089 if (strcmp(src_str
, src_or_group
) ||
5090 strcmp(grp_str
, group
))
5093 if (strcmp(src_str
, src_or_group
) &&
5094 strcmp(grp_str
, src_or_group
))
5097 pim_show_mlag_up_entry_detail(vrf
, vty
, up
,
5098 src_str
, grp_str
, json
);
5102 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5103 json
, JSON_C_TO_STRING_PRETTY
));
5104 json_object_free(json
);
5108 static void pim_show_mlag_up_vrf(struct vrf
*vrf
, struct vty
*vty
, bool uj
)
5110 json_object
*json
= NULL
;
5111 json_object
*json_row
;
5112 struct pim_upstream
*up
;
5113 char src_str
[INET_ADDRSTRLEN
];
5114 char grp_str
[INET_ADDRSTRLEN
];
5115 struct pim_instance
*pim
= vrf
->info
;
5116 json_object
*json_group
= NULL
;
5119 json
= json_object_new_object();
5122 "Source Group Owner Local-cost Peer-cost DF\n");
5125 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
5126 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
)
5127 && !(up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE
)
5128 && !pim_up_mlag_is_local(up
))
5130 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
5131 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
5133 json_object
*own_list
= NULL
;
5135 json_object_object_get_ex(json
, grp_str
, &json_group
);
5137 json_group
= json_object_new_object();
5138 json_object_object_add(json
, grp_str
,
5142 json_row
= json_object_new_object();
5143 json_object_string_add(json_row
, "vrf", vrf
->name
);
5144 json_object_string_add(json_row
, "source", src_str
);
5145 json_object_string_add(json_row
, "group", grp_str
);
5147 own_list
= json_object_new_array();
5148 if (pim_up_mlag_is_local(up
)) {
5150 json_object_array_add(own_list
,
5151 json_object_new_string(
5154 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
)) {
5155 json_object_array_add(own_list
,
5156 json_object_new_string(
5159 json_object_object_add(json_row
, "owners", own_list
);
5161 json_object_int_add(json_row
, "localCost",
5162 pim_up_mlag_local_cost(up
));
5163 json_object_int_add(json_row
, "peerCost",
5164 pim_up_mlag_peer_cost(up
));
5165 if (PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up
->flags
))
5166 json_object_boolean_false_add(json_row
, "df");
5168 json_object_boolean_true_add(json_row
, "df");
5169 json_object_object_add(json_group
, src_str
, json_row
);
5174 if (pim_up_mlag_is_local(up
))
5175 strlcat(own_str
, "L", sizeof(own_str
));
5176 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
))
5177 strlcat(own_str
, "P", sizeof(own_str
));
5178 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE
))
5179 strlcat(own_str
, "I", sizeof(own_str
));
5181 "%-15s %-15s %-6s %-11u %-10u %2s\n",
5182 src_str
, grp_str
, own_str
,
5183 pim_up_mlag_local_cost(up
),
5184 pim_up_mlag_peer_cost(up
),
5185 PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up
->flags
)
5190 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5191 json
, JSON_C_TO_STRING_PRETTY
));
5192 json_object_free(json
);
5196 static void pim_show_mlag_help_string(struct vty
*vty
, bool uj
)
5199 vty_out(vty
, "Owner codes:\n");
5201 "L: EVPN-MLAG Entry, I:PIM-MLAG Entry, P: Peer Entry\n");
5206 DEFUN(show_ip_pim_mlag_up
, show_ip_pim_mlag_up_cmd
,
5207 "show ip pim [vrf NAME] mlag upstream [A.B.C.D [A.B.C.D]] [json]",
5214 "Unicast or Multicast address\n"
5215 "Multicast address\n" JSON_STR
)
5217 const char *src_or_group
= NULL
;
5218 const char *group
= NULL
;
5220 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5221 bool uj
= use_json(argc
, argv
);
5223 if (!vrf
|| !vrf
->info
) {
5224 vty_out(vty
, "%s: VRF or Info missing\n", __func__
);
5231 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
5232 src_or_group
= argv
[idx
]->arg
;
5234 group
= argv
[idx
+ 1]->arg
;
5237 pim_show_mlag_help_string(vty
, uj
);
5240 pim_show_mlag_up_detail(vrf
, vty
, src_or_group
, group
, uj
);
5242 pim_show_mlag_up_vrf(vrf
, vty
, uj
);
5248 DEFUN(show_ip_pim_mlag_up_vrf_all
, show_ip_pim_mlag_up_vrf_all_cmd
,
5249 "show ip pim vrf all mlag upstream [json]",
5250 SHOW_STR IP_STR PIM_STR VRF_CMD_HELP_STR
5252 "upstream\n" JSON_STR
)
5255 bool uj
= use_json(argc
, argv
);
5257 pim_show_mlag_help_string(vty
, uj
);
5258 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5259 pim_show_mlag_up_vrf(vrf
, vty
, uj
);
5265 DEFUN (show_ip_pim_neighbor
,
5266 show_ip_pim_neighbor_cmd
,
5267 "show ip pim [vrf NAME] neighbor [detail|WORD] [json]",
5272 "PIM neighbor information\n"
5274 "Name of interface or neighbor\n"
5278 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5279 bool uj
= use_json(argc
, argv
);
5284 if (argv_find(argv
, argc
, "detail", &idx
)
5285 || argv_find(argv
, argc
, "WORD", &idx
))
5286 pim_show_neighbors_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
5288 pim_show_neighbors(vrf
->info
, vty
, uj
);
5293 DEFUN (show_ip_pim_neighbor_vrf_all
,
5294 show_ip_pim_neighbor_vrf_all_cmd
,
5295 "show ip pim vrf all neighbor [detail|WORD] [json]",
5300 "PIM neighbor information\n"
5302 "Name of interface or neighbor\n"
5306 bool uj
= use_json(argc
, argv
);
5312 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5316 vty_out(vty
, " \"%s\": ", vrf
->name
);
5319 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5320 if (argv_find(argv
, argc
, "detail", &idx
)
5321 || argv_find(argv
, argc
, "WORD", &idx
))
5322 pim_show_neighbors_single(vrf
->info
, vty
,
5323 argv
[idx
]->arg
, uj
);
5325 pim_show_neighbors(vrf
->info
, vty
, uj
);
5328 vty_out(vty
, "}\n");
5333 DEFUN (show_ip_pim_secondary
,
5334 show_ip_pim_secondary_cmd
,
5335 "show ip pim [vrf NAME] secondary",
5340 "PIM neighbor addresses\n")
5343 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5348 pim_show_neighbors_secondary(vrf
->info
, vty
);
5353 DEFUN (show_ip_pim_state
,
5354 show_ip_pim_state_cmd
,
5355 "show ip pim [vrf NAME] state [A.B.C.D [A.B.C.D]] [json]",
5360 "PIM state information\n"
5361 "Unicast or Multicast address\n"
5362 "Multicast address\n"
5365 const char *src_or_group
= NULL
;
5366 const char *group
= NULL
;
5368 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5369 bool uj
= use_json(argc
, argv
);
5377 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
5378 src_or_group
= argv
[idx
]->arg
;
5380 group
= argv
[idx
+ 1]->arg
;
5383 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
5388 DEFUN (show_ip_pim_state_vrf_all
,
5389 show_ip_pim_state_vrf_all_cmd
,
5390 "show ip pim vrf all state [A.B.C.D [A.B.C.D]] [json]",
5395 "PIM state information\n"
5396 "Unicast or Multicast address\n"
5397 "Multicast address\n"
5400 const char *src_or_group
= NULL
;
5401 const char *group
= NULL
;
5403 bool uj
= use_json(argc
, argv
);
5412 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
5413 src_or_group
= argv
[idx
]->arg
;
5415 group
= argv
[idx
+ 1]->arg
;
5418 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5422 vty_out(vty
, " \"%s\": ", vrf
->name
);
5425 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5426 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
5429 vty_out(vty
, "}\n");
5434 DEFPY (show_ip_pim_upstream
,
5435 show_ip_pim_upstream_cmd
,
5436 "show ip pim [vrf NAME] upstream [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
5441 "PIM upstream information\n"
5442 "The Source or Group\n"
5446 struct prefix_sg sg
= {0};
5449 struct pim_instance
*pim
;
5451 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
5454 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
5457 pim
= pim_get_pim_instance(v
->vrf_id
);
5460 vty_out(vty
, "%% Unable to find pim instance\n");
5464 if (s_or_g
.s_addr
!= INADDR_ANY
) {
5465 if (g
.s_addr
!= INADDR_ANY
) {
5471 pim_show_upstream(pim
, vty
, &sg
, uj
);
5476 DEFUN (show_ip_pim_upstream_vrf_all
,
5477 show_ip_pim_upstream_vrf_all_cmd
,
5478 "show ip pim vrf all upstream [json]",
5483 "PIM upstream information\n"
5486 struct prefix_sg sg
= {0};
5487 bool uj
= use_json(argc
, argv
);
5493 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5497 vty_out(vty
, " \"%s\": ", vrf
->name
);
5500 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5501 pim_show_upstream(vrf
->info
, vty
, &sg
, uj
);
5507 DEFUN (show_ip_pim_channel
,
5508 show_ip_pim_channel_cmd
,
5509 "show ip pim [vrf NAME] channel [json]",
5514 "PIM downstream channel info\n"
5518 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5519 bool uj
= use_json(argc
, argv
);
5524 pim_show_channel(vrf
->info
, vty
, uj
);
5529 DEFUN (show_ip_pim_upstream_join_desired
,
5530 show_ip_pim_upstream_join_desired_cmd
,
5531 "show ip pim [vrf NAME] upstream-join-desired [json]",
5536 "PIM upstream join-desired\n"
5540 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5541 bool uj
= use_json(argc
, argv
);
5546 pim_show_join_desired(vrf
->info
, vty
, uj
);
5551 DEFUN (show_ip_pim_upstream_rpf
,
5552 show_ip_pim_upstream_rpf_cmd
,
5553 "show ip pim [vrf NAME] upstream-rpf [json]",
5558 "PIM upstream source rpf\n"
5562 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5563 bool uj
= use_json(argc
, argv
);
5568 pim_show_upstream_rpf(vrf
->info
, vty
, uj
);
5573 DEFUN (show_ip_pim_rp
,
5575 "show ip pim [vrf NAME] rp-info [json]",
5580 "PIM RP information\n"
5584 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5585 bool uj
= use_json(argc
, argv
);
5590 pim_rp_show_information(vrf
->info
, vty
, uj
);
5595 DEFUN (show_ip_pim_rp_vrf_all
,
5596 show_ip_pim_rp_vrf_all_cmd
,
5597 "show ip pim vrf all rp-info [json]",
5602 "PIM RP information\n"
5605 bool uj
= use_json(argc
, argv
);
5611 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5615 vty_out(vty
, " \"%s\": ", vrf
->name
);
5618 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5619 pim_rp_show_information(vrf
->info
, vty
, uj
);
5622 vty_out(vty
, "}\n");
5627 DEFUN (show_ip_pim_rpf
,
5628 show_ip_pim_rpf_cmd
,
5629 "show ip pim [vrf NAME] rpf [json]",
5634 "PIM cached source rpf information\n"
5638 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5639 bool uj
= use_json(argc
, argv
);
5644 pim_show_rpf(vrf
->info
, vty
, uj
);
5649 DEFUN (show_ip_pim_rpf_vrf_all
,
5650 show_ip_pim_rpf_vrf_all_cmd
,
5651 "show ip pim vrf all rpf [json]",
5656 "PIM cached source rpf information\n"
5659 bool uj
= use_json(argc
, argv
);
5665 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5669 vty_out(vty
, " \"%s\": ", vrf
->name
);
5672 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5673 pim_show_rpf(vrf
->info
, vty
, uj
);
5676 vty_out(vty
, "}\n");
5681 DEFUN (show_ip_pim_nexthop
,
5682 show_ip_pim_nexthop_cmd
,
5683 "show ip pim [vrf NAME] nexthop",
5688 "PIM cached nexthop rpf information\n")
5691 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5696 pim_show_nexthop(vrf
->info
, vty
);
5701 DEFUN (show_ip_pim_nexthop_lookup
,
5702 show_ip_pim_nexthop_lookup_cmd
,
5703 "show ip pim [vrf NAME] nexthop-lookup A.B.C.D A.B.C.D",
5708 "PIM cached nexthop rpf lookup\n"
5709 "Source/RP address\n"
5710 "Multicast Group address\n")
5712 struct prefix nht_p
;
5714 struct in_addr src_addr
, grp_addr
;
5715 struct in_addr vif_source
;
5716 const char *addr_str
, *addr_str1
;
5718 struct pim_nexthop nexthop
;
5719 char nexthop_addr_str
[PREFIX_STRLEN
];
5720 char grp_str
[PREFIX_STRLEN
];
5722 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5727 argv_find(argv
, argc
, "A.B.C.D", &idx
);
5728 addr_str
= argv
[idx
]->arg
;
5729 result
= inet_pton(AF_INET
, addr_str
, &src_addr
);
5731 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
5732 errno
, safe_strerror(errno
));
5736 if (pim_is_group_224_4(src_addr
)) {
5738 "Invalid argument. Expected Valid Source Address.\n");
5742 addr_str1
= argv
[idx
+ 1]->arg
;
5743 result
= inet_pton(AF_INET
, addr_str1
, &grp_addr
);
5745 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
5746 errno
, safe_strerror(errno
));
5750 if (!pim_is_group_224_4(grp_addr
)) {
5752 "Invalid argument. Expected Valid Multicast Group Address.\n");
5756 if (!pim_rp_set_upstream_addr(vrf
->info
, &vif_source
, src_addr
,
5760 nht_p
.family
= AF_INET
;
5761 nht_p
.prefixlen
= IPV4_MAX_BITLEN
;
5762 nht_p
.u
.prefix4
= vif_source
;
5763 grp
.family
= AF_INET
;
5764 grp
.prefixlen
= IPV4_MAX_BITLEN
;
5765 grp
.u
.prefix4
= grp_addr
;
5766 memset(&nexthop
, 0, sizeof(nexthop
));
5768 result
= pim_ecmp_nexthop_lookup(vrf
->info
, &nexthop
, &nht_p
, &grp
, 0);
5772 "Nexthop Lookup failed, no usable routes returned.\n");
5776 pim_addr_dump("<grp?>", &grp
, grp_str
, sizeof(grp_str
));
5777 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
5778 nexthop_addr_str
, sizeof(nexthop_addr_str
));
5779 vty_out(vty
, "Group %s --- Nexthop %s Interface %s \n", grp_str
,
5780 nexthop_addr_str
, nexthop
.interface
->name
);
5785 DEFUN (show_ip_pim_interface_traffic
,
5786 show_ip_pim_interface_traffic_cmd
,
5787 "show ip pim [vrf NAME] interface traffic [WORD] [json]",
5792 "PIM interface information\n"
5793 "Protocol Packet counters\n"
5798 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5799 bool uj
= use_json(argc
, argv
);
5804 if (argv_find(argv
, argc
, "WORD", &idx
))
5805 pim_show_interface_traffic_single(vrf
->info
, vty
,
5806 argv
[idx
]->arg
, uj
);
5808 pim_show_interface_traffic(vrf
->info
, vty
, uj
);
5813 DEFUN (show_ip_pim_bsm_db
,
5814 show_ip_pim_bsm_db_cmd
,
5815 "show ip pim bsm-database [vrf NAME] [json]",
5819 "PIM cached bsm packets information\n"
5824 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5825 bool uj
= use_json(argc
, argv
);
5830 pim_show_bsm_db(vrf
->info
, vty
, uj
);
5834 DEFUN (show_ip_pim_bsrp
,
5835 show_ip_pim_bsrp_cmd
,
5836 "show ip pim bsrp-info [vrf NAME] [json]",
5840 "PIM cached group-rp mappings information\n"
5845 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5846 bool uj
= use_json(argc
, argv
);
5851 pim_show_group_rp_mappings_info(vrf
->info
, vty
, uj
);
5856 DEFUN (show_ip_pim_statistics
,
5857 show_ip_pim_statistics_cmd
,
5858 "show ip pim [vrf NAME] statistics [interface WORD] [json]",
5869 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5870 bool uj
= use_json(argc
, argv
);
5875 if (argv_find(argv
, argc
, "WORD", &idx
))
5876 pim_show_statistics(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
5878 pim_show_statistics(vrf
->info
, vty
, NULL
, uj
);
5883 static void show_multicast_interfaces(struct pim_instance
*pim
, struct vty
*vty
,
5886 struct interface
*ifp
;
5887 char buf
[PREFIX_STRLEN
];
5888 json_object
*json
= NULL
;
5889 json_object
*json_row
= NULL
;
5894 json
= json_object_new_object();
5897 "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut\n");
5899 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
5900 struct pim_interface
*pim_ifp
;
5901 struct in_addr ifaddr
;
5902 struct sioc_vif_req vreq
;
5904 pim_ifp
= ifp
->info
;
5909 memset(&vreq
, 0, sizeof(vreq
));
5910 vreq
.vifi
= pim_ifp
->mroute_vif_index
;
5912 if (ioctl(pim
->mroute_socket
, SIOCGETVIFCNT
, &vreq
)) {
5914 "ioctl(SIOCGETVIFCNT=%lu) failure for interface %s vif_index=%d: errno=%d: %s",
5915 (unsigned long)SIOCGETVIFCNT
, ifp
->name
,
5916 pim_ifp
->mroute_vif_index
, errno
,
5917 safe_strerror(errno
));
5920 ifaddr
= pim_ifp
->primary_address
;
5922 json_row
= json_object_new_object();
5923 json_object_string_add(json_row
, "name", ifp
->name
);
5924 json_object_string_add(json_row
, "state",
5925 if_is_up(ifp
) ? "up" : "down");
5926 json_object_string_add(
5927 json_row
, "address",
5928 inet_ntop(AF_INET
, &pim_ifp
->primary_address
,
5930 json_object_int_add(json_row
, "ifIndex", ifp
->ifindex
);
5931 json_object_int_add(json_row
, "vif",
5932 pim_ifp
->mroute_vif_index
);
5933 json_object_int_add(json_row
, "pktsIn",
5934 (unsigned long)vreq
.icount
);
5935 json_object_int_add(json_row
, "pktsOut",
5936 (unsigned long)vreq
.ocount
);
5937 json_object_int_add(json_row
, "bytesIn",
5938 (unsigned long)vreq
.ibytes
);
5939 json_object_int_add(json_row
, "bytesOut",
5940 (unsigned long)vreq
.obytes
);
5941 json_object_object_add(json
, ifp
->name
, json_row
);
5944 "%-16s %-15s %3d %3d %7lu %7lu %10lu %10lu\n",
5946 inet_ntop(AF_INET
, &ifaddr
, buf
, sizeof(buf
)),
5947 ifp
->ifindex
, pim_ifp
->mroute_vif_index
,
5948 (unsigned long)vreq
.icount
,
5949 (unsigned long)vreq
.ocount
,
5950 (unsigned long)vreq
.ibytes
,
5951 (unsigned long)vreq
.obytes
);
5956 vty_out(vty
, "%s\n",
5957 json_object_to_json_string_ext(
5958 json
, JSON_C_TO_STRING_PRETTY
));
5959 json_object_free(json
);
5963 static void pim_cmd_show_ip_multicast_helper(struct pim_instance
*pim
,
5966 struct vrf
*vrf
= pim
->vrf
;
5967 time_t now
= pim_time_monotonic_sec();
5973 vty_out(vty
, "Router MLAG Role: %s\n",
5974 mlag_role2str(router
->mlag_role
, mlag_role
, sizeof(mlag_role
)));
5975 vty_out(vty
, "Mroute socket descriptor:");
5977 vty_out(vty
, " %d(%s)\n", pim
->mroute_socket
, vrf
->name
);
5979 pim_time_uptime(uptime
, sizeof(uptime
),
5980 now
- pim
->mroute_socket_creation
);
5981 vty_out(vty
, "Mroute socket uptime: %s\n", uptime
);
5985 pim_zebra_zclient_update(vty
);
5986 pim_zlookup_show_ip_multicast(vty
);
5989 vty_out(vty
, "Maximum highest VifIndex: %d\n", PIM_MAX_USABLE_VIFS
);
5992 vty_out(vty
, "Upstream Join Timer: %d secs\n", router
->t_periodic
);
5993 vty_out(vty
, "Join/Prune Holdtime: %d secs\n", PIM_JP_HOLDTIME
);
5994 vty_out(vty
, "PIM ECMP: %s\n", pim
->ecmp_enable
? "Enable" : "Disable");
5995 vty_out(vty
, "PIM ECMP Rebalance: %s\n",
5996 pim
->ecmp_rebalance_enable
? "Enable" : "Disable");
6000 show_rpf_refresh_stats(vty
, pim
, now
, NULL
);
6004 show_scan_oil_stats(pim
, vty
, now
);
6006 show_multicast_interfaces(pim
, vty
, false);
6009 DEFUN (show_ip_multicast
,
6010 show_ip_multicast_cmd
,
6011 "show ip multicast [vrf NAME]",
6015 "Multicast global information\n")
6018 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6023 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
6028 DEFUN (show_ip_multicast_vrf_all
,
6029 show_ip_multicast_vrf_all_cmd
,
6030 "show ip multicast vrf all",
6034 "Multicast global information\n")
6036 bool uj
= use_json(argc
, argv
);
6042 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
6046 vty_out(vty
, " \"%s\": ", vrf
->name
);
6049 vty_out(vty
, "VRF: %s\n", vrf
->name
);
6050 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
6053 vty_out(vty
, "}\n");
6058 DEFUN(show_ip_multicast_count
,
6059 show_ip_multicast_count_cmd
,
6060 "show ip multicast count [vrf NAME] [json]",
6062 "Multicast global information\n"
6063 "Data packet count\n"
6064 VRF_CMD_HELP_STR JSON_STR
)
6067 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6068 bool uj
= use_json(argc
, argv
);
6073 show_multicast_interfaces(vrf
->info
, vty
, uj
);
6078 DEFUN(show_ip_multicast_count_vrf_all
,
6079 show_ip_multicast_count_vrf_all_cmd
,
6080 "show ip multicast count vrf all [json]",
6082 "Multicast global information\n"
6083 "Data packet count\n"
6084 VRF_CMD_HELP_STR JSON_STR
)
6086 bool uj
= use_json(argc
, argv
);
6093 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
6098 vty_out(vty
, " \"%s\": ", vrf
->name
);
6101 vty_out(vty
, "VRF: %s\n", vrf
->name
);
6103 show_multicast_interfaces(vrf
->info
, vty
, uj
);
6107 vty_out(vty
, "}\n");
6112 static void show_mroute(struct pim_instance
*pim
, struct vty
*vty
,
6113 struct prefix_sg
*sg
, bool fill
, bool uj
)
6115 struct listnode
*node
;
6116 struct channel_oil
*c_oil
;
6117 struct static_route
*s_route
;
6119 json_object
*json
= NULL
;
6120 json_object
*json_group
= NULL
;
6121 json_object
*json_source
= NULL
;
6122 json_object
*json_oil
= NULL
;
6123 json_object
*json_ifp_out
= NULL
;
6126 char grp_str
[INET_ADDRSTRLEN
];
6127 char src_str
[INET_ADDRSTRLEN
];
6128 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
6129 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
6131 struct interface
*ifp_in
;
6133 char state_str
[PIM_REG_STATE_STR_LEN
];
6134 char mroute_uptime
[10];
6137 json
= json_object_new_object();
6139 vty_out(vty
, "IP Multicast Routing Table\n");
6140 vty_out(vty
, "Flags: S - Sparse, C - Connected, P - Pruned\n");
6142 " R - SGRpt Pruned, F - Register flag, T - SPT-bit set\n");
6144 "\nSource Group Flags Proto Input Output TTL Uptime\n");
6147 now
= pim_time_monotonic_sec();
6149 /* print list of PIM and IGMP routes */
6150 frr_each (rb_pim_oil
, &pim
->channel_oil_head
, c_oil
) {
6153 if (!c_oil
->installed
)
6156 if (sg
->grp
.s_addr
!= INADDR_ANY
6157 && sg
->grp
.s_addr
!= c_oil
->oil
.mfcc_mcastgrp
.s_addr
)
6159 if (sg
->src
.s_addr
!= INADDR_ANY
6160 && sg
->src
.s_addr
!= c_oil
->oil
.mfcc_origin
.s_addr
)
6163 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
6165 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
6168 strlcpy(state_str
, "S", sizeof(state_str
));
6169 /* When a non DR receives a igmp join, it creates a (*,G)
6170 * channel_oil without any upstream creation */
6172 if (PIM_UPSTREAM_FLAG_TEST_SRC_IGMP(c_oil
->up
->flags
))
6173 strlcat(state_str
, "C", sizeof(state_str
));
6174 if (pim_upstream_is_sg_rpt(c_oil
->up
))
6175 strlcat(state_str
, "R", sizeof(state_str
));
6176 if (PIM_UPSTREAM_FLAG_TEST_FHR(c_oil
->up
->flags
))
6177 strlcat(state_str
, "F", sizeof(state_str
));
6178 if (c_oil
->up
->sptbit
== PIM_UPSTREAM_SPTBIT_TRUE
)
6179 strlcat(state_str
, "T", sizeof(state_str
));
6181 if (pim_channel_oil_empty(c_oil
))
6182 strlcat(state_str
, "P", sizeof(state_str
));
6184 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
6187 strlcpy(in_ifname
, ifp_in
->name
, sizeof(in_ifname
));
6189 strlcpy(in_ifname
, "<iif?>", sizeof(in_ifname
));
6192 pim_time_uptime(mroute_uptime
, sizeof(mroute_uptime
),
6193 now
- c_oil
->mroute_creation
);
6197 /* Find the group, create it if it doesn't exist */
6198 json_object_object_get_ex(json
, grp_str
, &json_group
);
6201 json_group
= json_object_new_object();
6202 json_object_object_add(json
, grp_str
,
6206 /* Find the source nested under the group, create it if
6209 json_object_object_get_ex(json_group
, src_str
,
6213 json_source
= json_object_new_object();
6214 json_object_object_add(json_group
, src_str
,
6218 /* Find the inbound interface nested under the source,
6219 * create it if it doesn't exist */
6220 json_object_int_add(json_source
, "installed",
6222 json_object_int_add(json_source
, "refCount",
6223 c_oil
->oil_ref_count
);
6224 json_object_int_add(json_source
, "oilSize",
6226 json_object_int_add(json_source
, "OilInheritedRescan",
6227 c_oil
->oil_inherited_rescan
);
6228 json_object_string_add(json_source
, "iif", in_ifname
);
6229 json_object_string_add(json_source
, "upTime",
6234 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
6236 struct interface
*ifp_out
;
6239 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
6243 /* do not display muted OIFs */
6244 if (c_oil
->oif_flags
[oif_vif_index
]
6245 & PIM_OIF_FLAG_MUTE
)
6248 if (c_oil
->oil
.mfcc_parent
== oif_vif_index
&&
6249 !pim_mroute_allow_iif_in_oil(c_oil
,
6253 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
6257 strlcpy(out_ifname
, ifp_out
->name
, sizeof(out_ifname
));
6259 strlcpy(out_ifname
, "<oif?>", sizeof(out_ifname
));
6262 json_ifp_out
= json_object_new_object();
6263 json_object_string_add(json_ifp_out
, "source",
6265 json_object_string_add(json_ifp_out
, "group",
6268 if (c_oil
->oif_flags
[oif_vif_index
]
6269 & PIM_OIF_FLAG_PROTO_PIM
)
6270 json_object_boolean_true_add(
6271 json_ifp_out
, "protocolPim");
6273 if (c_oil
->oif_flags
[oif_vif_index
]
6274 & PIM_OIF_FLAG_PROTO_IGMP
)
6275 json_object_boolean_true_add(
6276 json_ifp_out
, "protocolIgmp");
6278 if (c_oil
->oif_flags
[oif_vif_index
]
6279 & PIM_OIF_FLAG_PROTO_VXLAN
)
6280 json_object_boolean_true_add(
6281 json_ifp_out
, "protocolVxlan");
6283 if (c_oil
->oif_flags
[oif_vif_index
]
6284 & PIM_OIF_FLAG_PROTO_STAR
)
6285 json_object_boolean_true_add(
6287 "protocolInherited");
6289 json_object_string_add(json_ifp_out
,
6292 json_object_int_add(json_ifp_out
, "iVifI",
6293 c_oil
->oil
.mfcc_parent
);
6294 json_object_string_add(json_ifp_out
,
6295 "outboundInterface",
6297 json_object_int_add(json_ifp_out
, "oVifI",
6299 json_object_int_add(json_ifp_out
, "ttl", ttl
);
6300 json_object_string_add(json_ifp_out
, "upTime",
6302 json_object_string_add(json_source
, "flags",
6305 json_oil
= json_object_new_object();
6306 json_object_object_add(json_source
,
6309 json_object_object_add(json_oil
, out_ifname
,
6313 if (c_oil
->oif_flags
[oif_vif_index
]
6314 & PIM_OIF_FLAG_PROTO_PIM
) {
6315 strlcpy(proto
, "PIM", sizeof(proto
));
6318 if (c_oil
->oif_flags
[oif_vif_index
]
6319 & PIM_OIF_FLAG_PROTO_IGMP
) {
6320 strlcpy(proto
, "IGMP", sizeof(proto
));
6323 if (c_oil
->oif_flags
[oif_vif_index
]
6324 & PIM_OIF_FLAG_PROTO_VXLAN
) {
6325 strlcpy(proto
, "VxLAN", sizeof(proto
));
6328 if (c_oil
->oif_flags
[oif_vif_index
]
6329 & PIM_OIF_FLAG_PROTO_STAR
) {
6330 strlcpy(proto
, "STAR", sizeof(proto
));
6334 "%-15s %-15s %-8s %-6s %-16s %-16s %-3d %8s\n",
6335 src_str
, grp_str
, state_str
, proto
,
6336 in_ifname
, out_ifname
, ttl
,
6342 in_ifname
[0] = '\0';
6343 state_str
[0] = '\0';
6344 mroute_uptime
[0] = '\0';
6350 if (!uj
&& !found_oif
) {
6352 "%-15s %-15s %-8s %-6s %-16s %-16s %-3d %8s\n",
6353 src_str
, grp_str
, state_str
, "none", in_ifname
,
6354 "none", 0, "--:--:--");
6358 /* Print list of static routes */
6359 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
6362 if (!s_route
->c_oil
.installed
)
6365 pim_inet4_dump("<group?>", s_route
->group
, grp_str
,
6367 pim_inet4_dump("<source?>", s_route
->source
, src_str
,
6369 ifp_in
= pim_if_find_by_vif_index(pim
, s_route
->iif
);
6373 strlcpy(in_ifname
, ifp_in
->name
, sizeof(in_ifname
));
6375 strlcpy(in_ifname
, "<iif?>", sizeof(in_ifname
));
6379 /* Find the group, create it if it doesn't exist */
6380 json_object_object_get_ex(json
, grp_str
, &json_group
);
6383 json_group
= json_object_new_object();
6384 json_object_object_add(json
, grp_str
,
6388 /* Find the source nested under the group, create it if
6389 * it doesn't exist */
6390 json_object_object_get_ex(json_group
, src_str
,
6394 json_source
= json_object_new_object();
6395 json_object_object_add(json_group
, src_str
,
6399 json_object_string_add(json_source
, "iif", in_ifname
);
6402 strlcpy(proto
, "STATIC", sizeof(proto
));
6405 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
6407 struct interface
*ifp_out
;
6408 char oif_uptime
[10];
6411 ttl
= s_route
->oif_ttls
[oif_vif_index
];
6415 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
6417 oif_uptime
, sizeof(oif_uptime
),
6420 .oif_creation
[oif_vif_index
]);
6424 strlcpy(out_ifname
, ifp_out
->name
, sizeof(out_ifname
));
6426 strlcpy(out_ifname
, "<oif?>", sizeof(out_ifname
));
6429 json_ifp_out
= json_object_new_object();
6430 json_object_string_add(json_ifp_out
, "source",
6432 json_object_string_add(json_ifp_out
, "group",
6434 json_object_boolean_true_add(json_ifp_out
,
6436 json_object_string_add(json_ifp_out
,
6439 json_object_int_add(
6440 json_ifp_out
, "iVifI",
6441 s_route
->c_oil
.oil
.mfcc_parent
);
6442 json_object_string_add(json_ifp_out
,
6443 "outboundInterface",
6445 json_object_int_add(json_ifp_out
, "oVifI",
6447 json_object_int_add(json_ifp_out
, "ttl", ttl
);
6448 json_object_string_add(json_ifp_out
, "upTime",
6451 json_oil
= json_object_new_object();
6452 json_object_object_add(json_source
,
6455 json_object_object_add(json_oil
, out_ifname
,
6459 "%-15s %-15s %-8s %-6s %-16s %-16s %-3d %8s\n",
6460 src_str
, grp_str
, "-", proto
, in_ifname
,
6461 out_ifname
, ttl
, oif_uptime
);
6462 if (first
&& !fill
) {
6465 in_ifname
[0] = '\0';
6471 if (!uj
&& !found_oif
) {
6473 "%-15s %-15s %-8s %-6s %-16s %-16s %-3d %8s\n",
6474 src_str
, grp_str
, "-", proto
, in_ifname
, "none",
6480 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
6481 json
, JSON_C_TO_STRING_PRETTY
));
6482 json_object_free(json
);
6486 DEFPY (show_ip_mroute
,
6488 "show ip mroute [vrf NAME] [A.B.C.D$s_or_g [A.B.C.D$g]] [fill$fill] [json$json]",
6493 "The Source or Group\n"
6495 "Fill in Assumed data\n"
6498 struct prefix_sg sg
= {0};
6499 struct pim_instance
*pim
;
6502 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
6505 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
6508 pim
= pim_get_pim_instance(v
->vrf_id
);
6511 vty_out(vty
, "%% Unable to find pim instance\n");
6515 if (s_or_g
.s_addr
!= INADDR_ANY
) {
6516 if (g
.s_addr
!= INADDR_ANY
) {
6522 show_mroute(pim
, vty
, &sg
, !!fill
, !!json
);
6526 DEFUN (show_ip_mroute_vrf_all
,
6527 show_ip_mroute_vrf_all_cmd
,
6528 "show ip mroute vrf all [fill] [json]",
6533 "Fill in Assumed data\n"
6536 struct prefix_sg sg
= {0};
6537 bool uj
= use_json(argc
, argv
);
6543 if (argv_find(argv
, argc
, "fill", &idx
))
6548 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
6552 vty_out(vty
, " \"%s\": ", vrf
->name
);
6555 vty_out(vty
, "VRF: %s\n", vrf
->name
);
6556 show_mroute(vrf
->info
, vty
, &sg
, fill
, uj
);
6559 vty_out(vty
, "}\n");
6564 DEFUN (clear_ip_mroute_count
,
6565 clear_ip_mroute_count_cmd
,
6566 "clear ip mroute [vrf NAME] count",
6571 "Route and packet count data\n")
6574 struct listnode
*node
;
6575 struct channel_oil
*c_oil
;
6576 struct static_route
*sr
;
6577 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6578 struct pim_instance
*pim
;
6584 frr_each(rb_pim_oil
, &pim
->channel_oil_head
, c_oil
) {
6585 if (!c_oil
->installed
)
6588 pim_mroute_update_counters(c_oil
);
6589 c_oil
->cc
.origpktcnt
= c_oil
->cc
.pktcnt
;
6590 c_oil
->cc
.origbytecnt
= c_oil
->cc
.bytecnt
;
6591 c_oil
->cc
.origwrong_if
= c_oil
->cc
.wrong_if
;
6594 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, sr
)) {
6595 if (!sr
->c_oil
.installed
)
6598 pim_mroute_update_counters(&sr
->c_oil
);
6600 sr
->c_oil
.cc
.origpktcnt
= sr
->c_oil
.cc
.pktcnt
;
6601 sr
->c_oil
.cc
.origbytecnt
= sr
->c_oil
.cc
.bytecnt
;
6602 sr
->c_oil
.cc
.origwrong_if
= sr
->c_oil
.cc
.wrong_if
;
6607 static void show_mroute_count_per_channel_oil(struct channel_oil
*c_oil
,
6611 char group_str
[INET_ADDRSTRLEN
];
6612 char source_str
[INET_ADDRSTRLEN
];
6613 json_object
*json_group
= NULL
;
6614 json_object
*json_source
= NULL
;
6616 if (!c_oil
->installed
)
6619 pim_mroute_update_counters(c_oil
);
6621 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, group_str
,
6623 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, source_str
,
6624 sizeof(source_str
));
6627 json_object_object_get_ex(json
, group_str
, &json_group
);
6630 json_group
= json_object_new_object();
6631 json_object_object_add(json
, group_str
, json_group
);
6634 json_source
= json_object_new_object();
6635 json_object_object_add(json_group
, source_str
, json_source
);
6636 json_object_int_add(json_source
, "lastUsed",
6637 c_oil
->cc
.lastused
/ 100);
6638 json_object_int_add(json_source
, "packets", c_oil
->cc
.pktcnt
);
6639 json_object_int_add(json_source
, "bytes", c_oil
->cc
.bytecnt
);
6640 json_object_int_add(json_source
, "wrongIf", c_oil
->cc
.wrong_if
);
6643 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
6644 source_str
, group_str
, c_oil
->cc
.lastused
/ 100,
6645 c_oil
->cc
.pktcnt
- c_oil
->cc
.origpktcnt
,
6646 c_oil
->cc
.bytecnt
- c_oil
->cc
.origbytecnt
,
6647 c_oil
->cc
.wrong_if
- c_oil
->cc
.origwrong_if
);
6651 static void show_mroute_count(struct pim_instance
*pim
, struct vty
*vty
,
6654 struct listnode
*node
;
6655 struct channel_oil
*c_oil
;
6656 struct static_route
*sr
;
6657 json_object
*json
= NULL
;
6660 json
= json_object_new_object();
6665 "Source Group LastUsed Packets Bytes WrongIf \n");
6668 /* Print PIM and IGMP route counts */
6669 frr_each (rb_pim_oil
, &pim
->channel_oil_head
, c_oil
)
6670 show_mroute_count_per_channel_oil(c_oil
, json
, vty
);
6672 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, sr
))
6673 show_mroute_count_per_channel_oil(&sr
->c_oil
, json
, vty
);
6676 vty_out(vty
, "%s\n",
6677 json_object_to_json_string_ext(
6678 json
, JSON_C_TO_STRING_PRETTY
));
6679 json_object_free(json
);
6683 DEFUN (show_ip_mroute_count
,
6684 show_ip_mroute_count_cmd
,
6685 "show ip mroute [vrf NAME] count [json]",
6690 "Route and packet count data\n"
6694 bool uj
= use_json(argc
, argv
);
6695 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6700 show_mroute_count(vrf
->info
, vty
, uj
);
6704 DEFUN (show_ip_mroute_count_vrf_all
,
6705 show_ip_mroute_count_vrf_all_cmd
,
6706 "show ip mroute vrf all count [json]",
6711 "Route and packet count data\n"
6714 bool uj
= use_json(argc
, argv
);
6720 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
6724 vty_out(vty
, " \"%s\": ", vrf
->name
);
6727 vty_out(vty
, "VRF: %s\n", vrf
->name
);
6728 show_mroute_count(vrf
->info
, vty
, uj
);
6731 vty_out(vty
, "}\n");
6736 static void show_mroute_summary(struct pim_instance
*pim
, struct vty
*vty
,
6739 struct listnode
*node
;
6740 struct channel_oil
*c_oil
;
6741 struct static_route
*s_route
;
6742 uint32_t starg_sw_mroute_cnt
= 0;
6743 uint32_t sg_sw_mroute_cnt
= 0;
6744 uint32_t starg_hw_mroute_cnt
= 0;
6745 uint32_t sg_hw_mroute_cnt
= 0;
6746 json_object
*json_starg
= NULL
;
6747 json_object
*json_sg
= NULL
;
6750 vty_out(vty
, "Mroute Type Installed/Total\n");
6752 frr_each (rb_pim_oil
, &pim
->channel_oil_head
, c_oil
) {
6753 if (!c_oil
->installed
) {
6754 if (c_oil
->oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
6755 starg_sw_mroute_cnt
++;
6759 if (c_oil
->oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
6760 starg_hw_mroute_cnt
++;
6766 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
6767 if (!s_route
->c_oil
.installed
) {
6768 if (s_route
->c_oil
.oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
6769 starg_sw_mroute_cnt
++;
6773 if (s_route
->c_oil
.oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
6774 starg_hw_mroute_cnt
++;
6781 vty_out(vty
, "%-20s %u/%u\n", "(*, G)", starg_hw_mroute_cnt
,
6782 starg_sw_mroute_cnt
+ starg_hw_mroute_cnt
);
6783 vty_out(vty
, "%-20s %u/%u\n", "(S, G)", sg_hw_mroute_cnt
,
6784 sg_sw_mroute_cnt
+ sg_hw_mroute_cnt
);
6785 vty_out(vty
, "------\n");
6786 vty_out(vty
, "%-20s %u/%u\n", "Total",
6787 (starg_hw_mroute_cnt
+ sg_hw_mroute_cnt
),
6788 (starg_sw_mroute_cnt
+ starg_hw_mroute_cnt
6789 + sg_sw_mroute_cnt
+ sg_hw_mroute_cnt
));
6791 /* (*,G) route details */
6792 json_starg
= json_object_new_object();
6793 json_object_object_add(json
, "wildcardGroup", json_starg
);
6795 json_object_int_add(json_starg
, "installed",
6796 starg_hw_mroute_cnt
);
6797 json_object_int_add(json_starg
, "total",
6798 starg_sw_mroute_cnt
+ starg_hw_mroute_cnt
);
6800 /* (S, G) route details */
6801 json_sg
= json_object_new_object();
6802 json_object_object_add(json
, "sourceGroup", json_sg
);
6804 json_object_int_add(json_sg
, "installed", sg_hw_mroute_cnt
);
6805 json_object_int_add(json_sg
, "total",
6806 sg_sw_mroute_cnt
+ sg_hw_mroute_cnt
);
6808 json_object_int_add(json
, "totalNumOfInstalledMroutes",
6809 starg_hw_mroute_cnt
+ sg_hw_mroute_cnt
);
6810 json_object_int_add(json
, "totalNumOfMroutes",
6811 starg_sw_mroute_cnt
+ starg_hw_mroute_cnt
6813 + sg_hw_mroute_cnt
);
6817 DEFUN (show_ip_mroute_summary
,
6818 show_ip_mroute_summary_cmd
,
6819 "show ip mroute [vrf NAME] summary [json]",
6824 "Summary of all mroutes\n"
6828 bool uj
= use_json(argc
, argv
);
6829 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6830 json_object
*json
= NULL
;
6833 json
= json_object_new_object();
6838 show_mroute_summary(vrf
->info
, vty
, json
);
6841 vty_out(vty
, "%s\n",
6842 json_object_to_json_string_ext(
6843 json
, JSON_C_TO_STRING_PRETTY
));
6844 json_object_free(json
);
6849 DEFUN (show_ip_mroute_summary_vrf_all
,
6850 show_ip_mroute_summary_vrf_all_cmd
,
6851 "show ip mroute vrf all summary [json]",
6856 "Summary of all mroutes\n"
6860 bool uj
= use_json(argc
, argv
);
6861 json_object
*json
= NULL
;
6862 json_object
*json_vrf
= NULL
;
6865 json
= json_object_new_object();
6867 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
6869 json_vrf
= json_object_new_object();
6871 vty_out(vty
, "VRF: %s\n", vrf
->name
);
6873 show_mroute_summary(vrf
->info
, vty
, json_vrf
);
6876 json_object_object_add(json
, vrf
->name
, json_vrf
);
6880 vty_out(vty
, "%s\n",
6881 json_object_to_json_string_ext(
6882 json
, JSON_C_TO_STRING_PRETTY
));
6883 json_object_free(json
);
6891 "show ip rib [vrf NAME] A.B.C.D",
6896 "Unicast address\n")
6899 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6900 struct in_addr addr
;
6901 const char *addr_str
;
6902 struct pim_nexthop nexthop
;
6903 char nexthop_addr_str
[PREFIX_STRLEN
];
6909 memset(&nexthop
, 0, sizeof(nexthop
));
6910 argv_find(argv
, argc
, "A.B.C.D", &idx
);
6911 addr_str
= argv
[idx
]->arg
;
6912 result
= inet_pton(AF_INET
, addr_str
, &addr
);
6914 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
6915 errno
, safe_strerror(errno
));
6919 if (!pim_nexthop_lookup(vrf
->info
, &nexthop
, addr
, 0)) {
6921 "Failure querying RIB nexthop for unicast address %s\n",
6927 "Address NextHop Interface Metric Preference\n");
6929 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
6930 nexthop_addr_str
, sizeof(nexthop_addr_str
));
6932 vty_out(vty
, "%-15s %-15s %-9s %6d %10d\n", addr_str
, nexthop_addr_str
,
6933 nexthop
.interface
? nexthop
.interface
->name
: "<ifname?>",
6934 nexthop
.mrib_route_metric
, nexthop
.mrib_metric_preference
);
6939 static void show_ssmpingd(struct pim_instance
*pim
, struct vty
*vty
)
6941 struct listnode
*node
;
6942 struct ssmpingd_sock
*ss
;
6946 "Source Socket Address Port Uptime Requests\n");
6948 if (!pim
->ssmpingd_list
)
6951 now
= pim_time_monotonic_sec();
6953 for (ALL_LIST_ELEMENTS_RO(pim
->ssmpingd_list
, node
, ss
)) {
6954 char source_str
[INET_ADDRSTRLEN
];
6956 struct sockaddr_in bind_addr
;
6957 socklen_t len
= sizeof(bind_addr
);
6958 char bind_addr_str
[INET_ADDRSTRLEN
];
6960 pim_inet4_dump("<src?>", ss
->source_addr
, source_str
,
6961 sizeof(source_str
));
6963 if (pim_socket_getsockname(
6964 ss
->sock_fd
, (struct sockaddr
*)&bind_addr
, &len
)) {
6966 "%% Failure reading socket name for ssmpingd source %s on fd=%d\n",
6967 source_str
, ss
->sock_fd
);
6970 pim_inet4_dump("<addr?>", bind_addr
.sin_addr
, bind_addr_str
,
6971 sizeof(bind_addr_str
));
6972 pim_time_uptime(ss_uptime
, sizeof(ss_uptime
),
6973 now
- ss
->creation
);
6975 vty_out(vty
, "%-15s %6d %-15s %5d %8s %8lld\n", source_str
,
6976 ss
->sock_fd
, bind_addr_str
, ntohs(bind_addr
.sin_port
),
6977 ss_uptime
, (long long)ss
->requests
);
6981 DEFUN (show_ip_ssmpingd
,
6982 show_ip_ssmpingd_cmd
,
6983 "show ip ssmpingd [vrf NAME]",
6990 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6995 show_ssmpingd(vrf
->info
, vty
);
6999 DEFUN (ip_pim_spt_switchover_infinity
,
7000 ip_pim_spt_switchover_infinity_cmd
,
7001 "ip pim spt-switchover infinity-and-beyond",
7005 "Never switch to SPT Tree\n")
7007 const char *vrfname
;
7008 char spt_plist_xpath
[XPATH_MAXLEN
];
7009 char spt_action_xpath
[XPATH_MAXLEN
];
7011 vrfname
= pim_cli_get_vrf_name(vty
);
7012 if (vrfname
== NULL
)
7013 return CMD_WARNING_CONFIG_FAILED
;
7015 snprintf(spt_plist_xpath
, sizeof(spt_plist_xpath
),
7016 FRR_PIM_AF_XPATH
, "frr-pim:pimd", "pim", vrfname
,
7017 "frr-routing:ipv4");
7018 strlcat(spt_plist_xpath
, "/spt-switchover/spt-infinity-prefix-list",
7019 sizeof(spt_plist_xpath
));
7021 snprintf(spt_action_xpath
, sizeof(spt_action_xpath
),
7022 FRR_PIM_AF_XPATH
, "frr-pim:pimd", "pim", vrfname
,
7023 "frr-routing:ipv4");
7024 strlcat(spt_action_xpath
, "/spt-switchover/spt-action",
7025 sizeof(spt_action_xpath
));
7027 if (yang_dnode_exists(vty
->candidate_config
->dnode
, spt_plist_xpath
))
7028 nb_cli_enqueue_change(vty
, spt_plist_xpath
, NB_OP_DESTROY
,
7030 nb_cli_enqueue_change(vty
, spt_action_xpath
, NB_OP_MODIFY
,
7031 "PIM_SPT_INFINITY");
7033 return nb_cli_apply_changes(vty
, NULL
);
7036 DEFUN (ip_pim_spt_switchover_infinity_plist
,
7037 ip_pim_spt_switchover_infinity_plist_cmd
,
7038 "ip pim spt-switchover infinity-and-beyond prefix-list WORD",
7042 "Never switch to SPT Tree\n"
7043 "Prefix-List to control which groups to switch\n"
7044 "Prefix-List name\n")
7046 const char *vrfname
;
7047 char spt_plist_xpath
[XPATH_MAXLEN
];
7048 char spt_action_xpath
[XPATH_MAXLEN
];
7050 vrfname
= pim_cli_get_vrf_name(vty
);
7051 if (vrfname
== NULL
)
7052 return CMD_WARNING_CONFIG_FAILED
;
7054 snprintf(spt_plist_xpath
, sizeof(spt_plist_xpath
),
7055 FRR_PIM_AF_XPATH
, "frr-pim:pimd", "pim", vrfname
,
7056 "frr-routing:ipv4");
7057 strlcat(spt_plist_xpath
, "/spt-switchover/spt-infinity-prefix-list",
7058 sizeof(spt_plist_xpath
));
7060 snprintf(spt_action_xpath
, sizeof(spt_action_xpath
),
7061 FRR_PIM_AF_XPATH
, "frr-pim:pimd", "pim", vrfname
,
7062 "frr-routing:ipv4");
7063 strlcat(spt_action_xpath
, "/spt-switchover/spt-action",
7064 sizeof(spt_action_xpath
));
7066 nb_cli_enqueue_change(vty
, spt_action_xpath
, NB_OP_MODIFY
,
7067 "PIM_SPT_INFINITY");
7068 nb_cli_enqueue_change(vty
, spt_plist_xpath
, NB_OP_MODIFY
,
7071 return nb_cli_apply_changes(vty
, NULL
);
7074 DEFUN (no_ip_pim_spt_switchover_infinity
,
7075 no_ip_pim_spt_switchover_infinity_cmd
,
7076 "no ip pim spt-switchover infinity-and-beyond",
7081 "Never switch to SPT Tree\n")
7083 const char *vrfname
;
7084 char spt_plist_xpath
[XPATH_MAXLEN
];
7085 char spt_action_xpath
[XPATH_MAXLEN
];
7087 vrfname
= pim_cli_get_vrf_name(vty
);
7088 if (vrfname
== NULL
)
7089 return CMD_WARNING_CONFIG_FAILED
;
7091 snprintf(spt_plist_xpath
, sizeof(spt_plist_xpath
),
7092 FRR_PIM_AF_XPATH
, "frr-pim:pimd", "pim", vrfname
,
7093 "frr-routing:ipv4");
7094 strlcat(spt_plist_xpath
, "/spt-switchover/spt-infinity-prefix-list",
7095 sizeof(spt_plist_xpath
));
7097 snprintf(spt_action_xpath
, sizeof(spt_action_xpath
),
7098 FRR_PIM_AF_XPATH
, "frr-pim:pimd", "pim", vrfname
,
7099 "frr-routing:ipv4");
7100 strlcat(spt_action_xpath
, "/spt-switchover/spt-action",
7101 sizeof(spt_action_xpath
));
7103 nb_cli_enqueue_change(vty
, spt_plist_xpath
, NB_OP_DESTROY
, NULL
);
7104 nb_cli_enqueue_change(vty
, spt_action_xpath
, NB_OP_MODIFY
,
7105 "PIM_SPT_IMMEDIATE");
7107 return nb_cli_apply_changes(vty
, NULL
);
7110 DEFUN (no_ip_pim_spt_switchover_infinity_plist
,
7111 no_ip_pim_spt_switchover_infinity_plist_cmd
,
7112 "no ip pim spt-switchover infinity-and-beyond prefix-list WORD",
7117 "Never switch to SPT Tree\n"
7118 "Prefix-List to control which groups to switch\n"
7119 "Prefix-List name\n")
7121 const char *vrfname
;
7122 char spt_plist_xpath
[XPATH_MAXLEN
];
7123 char spt_action_xpath
[XPATH_MAXLEN
];
7125 vrfname
= pim_cli_get_vrf_name(vty
);
7126 if (vrfname
== NULL
)
7127 return CMD_WARNING_CONFIG_FAILED
;
7129 snprintf(spt_plist_xpath
, sizeof(spt_plist_xpath
),
7130 FRR_PIM_AF_XPATH
, "frr-pim:pimd", "pim", vrfname
,
7131 "frr-routing:ipv4");
7132 strlcat(spt_plist_xpath
, "/spt-switchover/spt-infinity-prefix-list",
7133 sizeof(spt_plist_xpath
));
7135 snprintf(spt_action_xpath
, sizeof(spt_action_xpath
),
7136 FRR_PIM_AF_XPATH
, "frr-pim:pimd", "pim", vrfname
,
7137 "frr-routing:ipv4");
7138 strlcat(spt_action_xpath
, "/spt-switchover/spt-action",
7139 sizeof(spt_action_xpath
));
7141 nb_cli_enqueue_change(vty
, spt_plist_xpath
, NB_OP_DESTROY
, NULL
);
7142 nb_cli_enqueue_change(vty
, spt_action_xpath
, NB_OP_MODIFY
,
7143 "PIM_SPT_IMMEDIATE");
7145 return nb_cli_apply_changes(vty
, NULL
);
7148 DEFPY (pim_register_accept_list
,
7149 pim_register_accept_list_cmd
,
7150 "[no] ip pim register-accept-list WORD$word",
7154 "Only accept registers from a specific source prefix list\n"
7155 "Prefix-List name\n")
7157 const char *vrfname
;
7158 char reg_alist_xpath
[XPATH_MAXLEN
];
7160 vrfname
= pim_cli_get_vrf_name(vty
);
7161 if (vrfname
== NULL
)
7162 return CMD_WARNING_CONFIG_FAILED
;
7164 snprintf(reg_alist_xpath
, sizeof(reg_alist_xpath
),
7165 FRR_PIM_AF_XPATH
, "frr-pim:pimd", "pim", vrfname
,
7166 "frr-routing:ipv4");
7167 strlcat(reg_alist_xpath
, "/register-accept-list",
7168 sizeof(reg_alist_xpath
));
7171 nb_cli_enqueue_change(vty
, reg_alist_xpath
,
7172 NB_OP_DESTROY
, NULL
);
7174 nb_cli_enqueue_change(vty
, reg_alist_xpath
,
7175 NB_OP_MODIFY
, word
);
7177 return nb_cli_apply_changes(vty
, NULL
);
7180 DEFUN (ip_pim_joinprune_time
,
7181 ip_pim_joinprune_time_cmd
,
7182 "ip pim join-prune-interval (1-65535)",
7184 "pim multicast routing\n"
7185 "Join Prune Send Interval\n"
7188 nb_cli_enqueue_change(vty
, "/frr-pim:pim/join-prune-interval",
7189 NB_OP_MODIFY
, argv
[3]->arg
);
7191 return nb_cli_apply_changes(vty
, NULL
);
7194 DEFUN (no_ip_pim_joinprune_time
,
7195 no_ip_pim_joinprune_time_cmd
,
7196 "no ip pim join-prune-interval [(1-65535)]",
7199 "pim multicast routing\n"
7200 "Join Prune Send Interval\n"
7203 nb_cli_enqueue_change(vty
, "/frr-pim:pim/join-prune-interval",
7204 NB_OP_DESTROY
, NULL
);
7206 return nb_cli_apply_changes(vty
, NULL
);
7209 DEFUN (ip_pim_register_suppress
,
7210 ip_pim_register_suppress_cmd
,
7211 "ip pim register-suppress-time (1-65535)",
7213 "pim multicast routing\n"
7214 "Register Suppress Timer\n"
7217 nb_cli_enqueue_change(vty
, "/frr-pim:pim/register-suppress-time",
7218 NB_OP_MODIFY
, argv
[3]->arg
);
7220 return nb_cli_apply_changes(vty
, NULL
);
7223 DEFUN (no_ip_pim_register_suppress
,
7224 no_ip_pim_register_suppress_cmd
,
7225 "no ip pim register-suppress-time [(1-65535)]",
7228 "pim multicast routing\n"
7229 "Register Suppress Timer\n"
7232 nb_cli_enqueue_change(vty
, "/frr-pim:pim/register-suppress-time",
7233 NB_OP_DESTROY
, NULL
);
7235 return nb_cli_apply_changes(vty
, NULL
);
7238 DEFUN (ip_pim_rp_keep_alive
,
7239 ip_pim_rp_keep_alive_cmd
,
7240 "ip pim rp keep-alive-timer (1-65535)",
7242 "pim multicast routing\n"
7244 "Keep alive Timer\n"
7247 const char *vrfname
;
7248 char rp_ka_timer_xpath
[XPATH_MAXLEN
];
7250 vrfname
= pim_cli_get_vrf_name(vty
);
7251 if (vrfname
== NULL
)
7252 return CMD_WARNING_CONFIG_FAILED
;
7254 snprintf(rp_ka_timer_xpath
, sizeof(rp_ka_timer_xpath
),
7255 FRR_PIM_XPATH
, "frr-pim:pimd", "pim", vrfname
);
7256 strlcat(rp_ka_timer_xpath
, "/rp-keep-alive-timer",
7257 sizeof(rp_ka_timer_xpath
));
7259 nb_cli_enqueue_change(vty
, rp_ka_timer_xpath
, NB_OP_MODIFY
,
7262 return nb_cli_apply_changes(vty
, NULL
);
7265 DEFUN (no_ip_pim_rp_keep_alive
,
7266 no_ip_pim_rp_keep_alive_cmd
,
7267 "no ip pim rp keep-alive-timer [(1-65535)]",
7270 "pim multicast routing\n"
7272 "Keep alive Timer\n"
7275 const char *vrfname
;
7276 char rp_ka_timer
[6];
7277 char rp_ka_timer_xpath
[XPATH_MAXLEN
];
7281 v
= yang_dnode_get_uint16(vty
->candidate_config
->dnode
,
7282 "/frr-pim:pim/register-suppress-time");
7283 v
= 3 * v
+ PIM_REGISTER_PROBE_TIME_DEFAULT
;
7286 snprintf(rp_ka_timer
, sizeof(rp_ka_timer
), "%u", v
);
7288 vrfname
= pim_cli_get_vrf_name(vty
);
7289 if (vrfname
== NULL
)
7290 return CMD_WARNING_CONFIG_FAILED
;
7292 snprintf(rp_ka_timer_xpath
, sizeof(rp_ka_timer_xpath
),
7293 FRR_PIM_XPATH
, "frr-pim:pimd", "pim", vrfname
);
7294 strlcat(rp_ka_timer_xpath
, "/rp-keep-alive-timer",
7295 sizeof(rp_ka_timer_xpath
));
7297 nb_cli_enqueue_change(vty
, rp_ka_timer_xpath
, NB_OP_MODIFY
,
7300 return nb_cli_apply_changes(vty
, NULL
);
7303 DEFUN (ip_pim_keep_alive
,
7304 ip_pim_keep_alive_cmd
,
7305 "ip pim keep-alive-timer (1-65535)",
7307 "pim multicast routing\n"
7308 "Keep alive Timer\n"
7311 const char *vrfname
;
7312 char ka_timer_xpath
[XPATH_MAXLEN
];
7314 vrfname
= pim_cli_get_vrf_name(vty
);
7315 if (vrfname
== NULL
)
7316 return CMD_WARNING_CONFIG_FAILED
;
7318 snprintf(ka_timer_xpath
, sizeof(ka_timer_xpath
), FRR_PIM_XPATH
,
7319 "frr-pim:pimd", "pim", vrfname
);
7320 strlcat(ka_timer_xpath
, "/keep-alive-timer", sizeof(ka_timer_xpath
));
7322 nb_cli_enqueue_change(vty
, ka_timer_xpath
, NB_OP_MODIFY
,
7325 return nb_cli_apply_changes(vty
, NULL
);
7328 DEFUN (no_ip_pim_keep_alive
,
7329 no_ip_pim_keep_alive_cmd
,
7330 "no ip pim keep-alive-timer [(1-65535)]",
7333 "pim multicast routing\n"
7334 "Keep alive Timer\n"
7337 const char *vrfname
;
7338 char ka_timer_xpath
[XPATH_MAXLEN
];
7340 vrfname
= pim_cli_get_vrf_name(vty
);
7341 if (vrfname
== NULL
)
7342 return CMD_WARNING_CONFIG_FAILED
;
7344 snprintf(ka_timer_xpath
, sizeof(ka_timer_xpath
), FRR_PIM_XPATH
,
7345 "frr-pim:pimd", "pim", vrfname
);
7346 strlcat(ka_timer_xpath
, "/keep-alive-timer", sizeof(ka_timer_xpath
));
7348 nb_cli_enqueue_change(vty
, ka_timer_xpath
, NB_OP_DESTROY
, NULL
);
7350 return nb_cli_apply_changes(vty
, NULL
);
7353 DEFUN (ip_pim_packets
,
7355 "ip pim packets (1-255)",
7357 "pim multicast routing\n"
7358 "packets to process at one time per fd\n"
7359 "Number of packets\n")
7361 nb_cli_enqueue_change(vty
, "/frr-pim:pim/packets", NB_OP_MODIFY
,
7364 return nb_cli_apply_changes(vty
, NULL
);
7367 DEFUN (no_ip_pim_packets
,
7368 no_ip_pim_packets_cmd
,
7369 "no ip pim packets [(1-255)]",
7372 "pim multicast routing\n"
7373 "packets to process at one time per fd\n"
7376 nb_cli_enqueue_change(vty
, "/frr-pim:pim/packets", NB_OP_DESTROY
, NULL
);
7378 return nb_cli_apply_changes(vty
, NULL
);
7381 DEFPY (igmp_group_watermark
,
7382 igmp_group_watermark_cmd
,
7383 "ip igmp watermark-warn (1-65535)$limit",
7386 "Configure group limit for watermark warning\n"
7387 "Group count to generate watermark warning\n")
7389 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7390 pim
->igmp_watermark_limit
= limit
;
7395 DEFPY (no_igmp_group_watermark
,
7396 no_igmp_group_watermark_cmd
,
7397 "no ip igmp watermark-warn [(1-65535)$limit]",
7401 "Unconfigure group limit for watermark warning\n"
7404 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7405 pim
->igmp_watermark_limit
= 0;
7410 DEFUN (ip_pim_v6_secondary
,
7411 ip_pim_v6_secondary_cmd
,
7412 "ip pim send-v6-secondary",
7414 "pim multicast routing\n"
7415 "Send v6 secondary addresses\n")
7417 const char *vrfname
;
7418 char send_v6_secondary_xpath
[XPATH_MAXLEN
];
7420 vrfname
= pim_cli_get_vrf_name(vty
);
7421 if (vrfname
== NULL
)
7422 return CMD_WARNING_CONFIG_FAILED
;
7424 snprintf(send_v6_secondary_xpath
, sizeof(send_v6_secondary_xpath
),
7426 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4");
7427 strlcat(send_v6_secondary_xpath
, "/send-v6-secondary",
7428 sizeof(send_v6_secondary_xpath
));
7430 nb_cli_enqueue_change(vty
, send_v6_secondary_xpath
, NB_OP_MODIFY
,
7433 return nb_cli_apply_changes(vty
, NULL
);
7436 DEFUN (no_ip_pim_v6_secondary
,
7437 no_ip_pim_v6_secondary_cmd
,
7438 "no ip pim send-v6-secondary",
7441 "pim multicast routing\n"
7442 "Send v6 secondary addresses\n")
7444 const char *vrfname
;
7445 char send_v6_secondary_xpath
[XPATH_MAXLEN
];
7447 vrfname
= pim_cli_get_vrf_name(vty
);
7448 if (vrfname
== NULL
)
7449 return CMD_WARNING_CONFIG_FAILED
;
7451 snprintf(send_v6_secondary_xpath
, sizeof(send_v6_secondary_xpath
),
7453 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4");
7454 strlcat(send_v6_secondary_xpath
, "/send-v6-secondary",
7455 sizeof(send_v6_secondary_xpath
));
7457 nb_cli_enqueue_change(vty
, send_v6_secondary_xpath
, NB_OP_MODIFY
,
7460 return nb_cli_apply_changes(vty
, NULL
);
7465 "ip pim rp A.B.C.D [A.B.C.D/M]",
7467 "pim multicast routing\n"
7469 "ip address of RP\n"
7470 "Group Address range to cover\n")
7472 const char *vrfname
;
7473 int idx_rp
= 3, idx_group
= 4;
7474 char rp_group_xpath
[XPATH_MAXLEN
];
7476 struct prefix group
;
7477 struct in_addr rp_addr
;
7478 const char *group_str
=
7479 (argc
== 5) ? argv
[idx_group
]->arg
: "224.0.0.0/4";
7481 result
= str2prefix(group_str
, &group
);
7485 prefix_copy(&temp
, &group
);
7487 if (!prefix_same(&group
, &temp
)) {
7488 vty_out(vty
, "%% Inconsistent address and mask: %s\n",
7490 return CMD_WARNING_CONFIG_FAILED
;
7495 vty_out(vty
, "%% Bad group address specified: %s\n",
7497 return CMD_WARNING_CONFIG_FAILED
;
7500 result
= inet_pton(AF_INET
, argv
[idx_rp
]->arg
, &rp_addr
);
7502 vty_out(vty
, "%% Bad RP address specified: %s\n",
7504 return CMD_WARNING_CONFIG_FAILED
;
7507 vrfname
= pim_cli_get_vrf_name(vty
);
7508 if (vrfname
== NULL
)
7509 return CMD_WARNING_CONFIG_FAILED
;
7511 snprintf(rp_group_xpath
, sizeof(rp_group_xpath
),
7512 FRR_PIM_STATIC_RP_XPATH
,
7513 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4",
7515 strlcat(rp_group_xpath
, "/group-list", sizeof(rp_group_xpath
));
7517 nb_cli_enqueue_change(vty
, rp_group_xpath
, NB_OP_CREATE
, group_str
);
7519 return nb_cli_apply_changes(vty
, NULL
);
7522 DEFUN (ip_pim_rp_prefix_list
,
7523 ip_pim_rp_prefix_list_cmd
,
7524 "ip pim rp A.B.C.D prefix-list WORD",
7526 "pim multicast routing\n"
7528 "ip address of RP\n"
7529 "group prefix-list filter\n"
7530 "Name of a prefix-list\n")
7532 int idx_rp
= 3, idx_plist
= 5;
7533 const char *vrfname
;
7534 char rp_plist_xpath
[XPATH_MAXLEN
];
7536 vrfname
= pim_cli_get_vrf_name(vty
);
7537 if (vrfname
== NULL
)
7538 return CMD_WARNING_CONFIG_FAILED
;
7540 snprintf(rp_plist_xpath
, sizeof(rp_plist_xpath
),
7541 FRR_PIM_STATIC_RP_XPATH
,
7542 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4",
7544 strlcat(rp_plist_xpath
, "/prefix-list", sizeof(rp_plist_xpath
));
7546 nb_cli_enqueue_change(vty
, rp_plist_xpath
, NB_OP_MODIFY
,
7547 argv
[idx_plist
]->arg
);
7549 return nb_cli_apply_changes(vty
, NULL
);
7552 DEFUN (no_ip_pim_rp
,
7554 "no ip pim rp A.B.C.D [A.B.C.D/M]",
7557 "pim multicast routing\n"
7559 "ip address of RP\n"
7560 "Group Address range to cover\n")
7562 int idx_rp
= 4, idx_group
= 5;
7563 const char *group_str
=
7564 (argc
== 6) ? argv
[idx_group
]->arg
: "224.0.0.0/4";
7565 char group_list_xpath
[XPATH_MAXLEN
+ 32];
7566 char group_xpath
[XPATH_MAXLEN
+ 64];
7567 char rp_xpath
[XPATH_MAXLEN
];
7568 const char *vrfname
;
7569 const struct lyd_node
*group_dnode
;
7571 vrfname
= pim_cli_get_vrf_name(vty
);
7572 if (vrfname
== NULL
)
7573 return CMD_WARNING_CONFIG_FAILED
;
7575 snprintf(rp_xpath
, sizeof(rp_xpath
), FRR_PIM_STATIC_RP_XPATH
,
7576 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4",
7579 snprintf(group_list_xpath
, sizeof(group_list_xpath
), "%s/group-list",
7582 snprintf(group_xpath
, sizeof(group_xpath
), "%s[.='%s']",
7583 group_list_xpath
, group_str
);
7585 if (!yang_dnode_exists(vty
->candidate_config
->dnode
, group_xpath
)) {
7586 vty_out(vty
, "%% Unable to find specified RP\n");
7590 group_dnode
= yang_dnode_get(vty
->candidate_config
->dnode
, group_xpath
);
7592 if (yang_is_last_list_dnode(group_dnode
))
7593 nb_cli_enqueue_change(vty
, rp_xpath
, NB_OP_DESTROY
, NULL
);
7595 nb_cli_enqueue_change(vty
, group_list_xpath
, NB_OP_DESTROY
,
7598 return nb_cli_apply_changes(vty
, NULL
);
7601 DEFUN (no_ip_pim_rp_prefix_list
,
7602 no_ip_pim_rp_prefix_list_cmd
,
7603 "no ip pim rp A.B.C.D prefix-list WORD",
7606 "pim multicast routing\n"
7608 "ip address of RP\n"
7609 "group prefix-list filter\n"
7610 "Name of a prefix-list\n")
7614 char rp_xpath
[XPATH_MAXLEN
];
7615 char plist_xpath
[XPATH_MAXLEN
];
7616 const char *vrfname
;
7617 const struct lyd_node
*plist_dnode
;
7620 vrfname
= pim_cli_get_vrf_name(vty
);
7621 if (vrfname
== NULL
)
7622 return CMD_WARNING_CONFIG_FAILED
;
7624 snprintf(rp_xpath
, sizeof(rp_xpath
), FRR_PIM_STATIC_RP_XPATH
,
7625 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4",
7628 snprintf(plist_xpath
, sizeof(plist_xpath
), FRR_PIM_STATIC_RP_XPATH
,
7629 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4",
7631 strlcat(plist_xpath
, "/prefix-list", sizeof(plist_xpath
));
7633 plist_dnode
= yang_dnode_get(vty
->candidate_config
->dnode
, plist_xpath
);
7635 vty_out(vty
, "%% Unable to find specified RP\n");
7639 plist
= yang_dnode_get_string(plist_dnode
, plist_xpath
);
7640 if (strcmp(argv
[idx_plist
]->arg
, plist
)) {
7641 vty_out(vty
, "%% Unable to find specified RP\n");
7645 nb_cli_enqueue_change(vty
, rp_xpath
, NB_OP_DESTROY
, NULL
);
7647 return nb_cli_apply_changes(vty
, NULL
);
7650 DEFUN (ip_pim_ssm_prefix_list
,
7651 ip_pim_ssm_prefix_list_cmd
,
7652 "ip pim ssm prefix-list WORD",
7654 "pim multicast routing\n"
7655 "Source Specific Multicast\n"
7656 "group range prefix-list filter\n"
7657 "Name of a prefix-list\n")
7659 const char *vrfname
;
7660 char ssm_plist_xpath
[XPATH_MAXLEN
];
7662 vrfname
= pim_cli_get_vrf_name(vty
);
7663 if (vrfname
== NULL
)
7664 return CMD_WARNING_CONFIG_FAILED
;
7666 snprintf(ssm_plist_xpath
, sizeof(ssm_plist_xpath
), FRR_PIM_AF_XPATH
,
7667 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4");
7668 strlcat(ssm_plist_xpath
, "/ssm-prefix-list", sizeof(ssm_plist_xpath
));
7670 nb_cli_enqueue_change(vty
, ssm_plist_xpath
, NB_OP_MODIFY
, argv
[4]->arg
);
7672 return nb_cli_apply_changes(vty
, NULL
);
7675 DEFUN (no_ip_pim_ssm_prefix_list
,
7676 no_ip_pim_ssm_prefix_list_cmd
,
7677 "no ip pim ssm prefix-list",
7680 "pim multicast routing\n"
7681 "Source Specific Multicast\n"
7682 "group range prefix-list filter\n")
7684 const char *vrfname
;
7685 char ssm_plist_xpath
[XPATH_MAXLEN
];
7687 vrfname
= pim_cli_get_vrf_name(vty
);
7688 if (vrfname
== NULL
)
7689 return CMD_WARNING_CONFIG_FAILED
;
7691 snprintf(ssm_plist_xpath
, sizeof(ssm_plist_xpath
),
7693 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4");
7694 strlcat(ssm_plist_xpath
, "/ssm-prefix-list", sizeof(ssm_plist_xpath
));
7696 nb_cli_enqueue_change(vty
, ssm_plist_xpath
, NB_OP_DESTROY
, NULL
);
7698 return nb_cli_apply_changes(vty
, NULL
);
7701 DEFUN (no_ip_pim_ssm_prefix_list_name
,
7702 no_ip_pim_ssm_prefix_list_name_cmd
,
7703 "no ip pim ssm prefix-list WORD",
7706 "pim multicast routing\n"
7707 "Source Specific Multicast\n"
7708 "group range prefix-list filter\n"
7709 "Name of a prefix-list\n")
7711 const char *vrfname
;
7712 const struct lyd_node
*ssm_plist_dnode
;
7713 char ssm_plist_xpath
[XPATH_MAXLEN
];
7714 const char *ssm_plist_name
;
7716 vrfname
= pim_cli_get_vrf_name(vty
);
7717 if (vrfname
== NULL
)
7718 return CMD_WARNING_CONFIG_FAILED
;
7720 snprintf(ssm_plist_xpath
, sizeof(ssm_plist_xpath
),
7722 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4");
7723 strlcat(ssm_plist_xpath
, "/ssm-prefix-list", sizeof(ssm_plist_xpath
));
7724 ssm_plist_dnode
= yang_dnode_get(vty
->candidate_config
->dnode
,
7727 if (!ssm_plist_dnode
) {
7729 "%% pim ssm prefix-list %s doesn't exist\n",
7731 return CMD_WARNING_CONFIG_FAILED
;
7734 ssm_plist_name
= yang_dnode_get_string(ssm_plist_dnode
, ".");
7736 if (ssm_plist_name
&& !strcmp(ssm_plist_name
, argv
[5]->arg
)) {
7737 nb_cli_enqueue_change(vty
, ssm_plist_xpath
, NB_OP_DESTROY
,
7740 return nb_cli_apply_changes(vty
, NULL
);
7743 vty_out(vty
, "%% pim ssm prefix-list %s doesn't exist\n", argv
[5]->arg
);
7745 return CMD_WARNING_CONFIG_FAILED
;
7748 static void ip_pim_ssm_show_group_range(struct pim_instance
*pim
,
7749 struct vty
*vty
, bool uj
)
7751 struct pim_ssm
*ssm
= pim
->ssm_info
;
7752 const char *range_str
=
7753 ssm
->plist_name
? ssm
->plist_name
: PIM_SSM_STANDARD_RANGE
;
7757 json
= json_object_new_object();
7758 json_object_string_add(json
, "ssmGroups", range_str
);
7759 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
7760 json
, JSON_C_TO_STRING_PRETTY
));
7761 json_object_free(json
);
7763 vty_out(vty
, "SSM group range : %s\n", range_str
);
7766 DEFUN (show_ip_pim_ssm_range
,
7767 show_ip_pim_ssm_range_cmd
,
7768 "show ip pim [vrf NAME] group-type [json]",
7777 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
7778 bool uj
= use_json(argc
, argv
);
7783 ip_pim_ssm_show_group_range(vrf
->info
, vty
, uj
);
7788 static void ip_pim_ssm_show_group_type(struct pim_instance
*pim
,
7789 struct vty
*vty
, bool uj
,
7792 struct in_addr group_addr
;
7793 const char *type_str
;
7796 result
= inet_pton(AF_INET
, group
, &group_addr
);
7798 type_str
= "invalid";
7800 if (pim_is_group_224_4(group_addr
))
7802 pim_is_grp_ssm(pim
, group_addr
) ? "SSM" : "ASM";
7804 type_str
= "not-multicast";
7809 json
= json_object_new_object();
7810 json_object_string_add(json
, "groupType", type_str
);
7811 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
7812 json
, JSON_C_TO_STRING_PRETTY
));
7813 json_object_free(json
);
7815 vty_out(vty
, "Group type : %s\n", type_str
);
7818 DEFUN (show_ip_pim_group_type
,
7819 show_ip_pim_group_type_cmd
,
7820 "show ip pim [vrf NAME] group-type A.B.C.D [json]",
7825 "multicast group type\n"
7830 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
7831 bool uj
= use_json(argc
, argv
);
7836 argv_find(argv
, argc
, "A.B.C.D", &idx
);
7837 ip_pim_ssm_show_group_type(vrf
->info
, vty
, uj
, argv
[idx
]->arg
);
7842 DEFUN (show_ip_pim_bsr
,
7843 show_ip_pim_bsr_cmd
,
7844 "show ip pim bsr [json]",
7848 "boot-strap router information\n"
7852 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
7853 bool uj
= use_json(argc
, argv
);
7858 pim_show_bsr(vrf
->info
, vty
, uj
);
7865 "ip ssmpingd [A.B.C.D]",
7871 const char *source_str
= (argc
== 3) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
7872 const char *vrfname
;
7873 char ssmpingd_ip_xpath
[XPATH_MAXLEN
];
7875 vrfname
= pim_cli_get_vrf_name(vty
);
7876 if (vrfname
== NULL
)
7877 return CMD_WARNING_CONFIG_FAILED
;
7879 snprintf(ssmpingd_ip_xpath
, sizeof(ssmpingd_ip_xpath
),
7881 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4");
7882 strlcat(ssmpingd_ip_xpath
, "/ssm-pingd-source-ip",
7883 sizeof(ssmpingd_ip_xpath
));
7885 nb_cli_enqueue_change(vty
, ssmpingd_ip_xpath
, NB_OP_CREATE
,
7888 return nb_cli_apply_changes(vty
, NULL
);
7891 DEFUN (no_ip_ssmpingd
,
7893 "no ip ssmpingd [A.B.C.D]",
7899 const char *vrfname
;
7901 const char *source_str
= (argc
== 4) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
7902 char ssmpingd_ip_xpath
[XPATH_MAXLEN
];
7904 vrfname
= pim_cli_get_vrf_name(vty
);
7905 if (vrfname
== NULL
)
7906 return CMD_WARNING_CONFIG_FAILED
;
7908 snprintf(ssmpingd_ip_xpath
, sizeof(ssmpingd_ip_xpath
),
7910 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4");
7911 strlcat(ssmpingd_ip_xpath
, "/ssm-pingd-source-ip",
7912 sizeof(ssmpingd_ip_xpath
));
7914 nb_cli_enqueue_change(vty
, ssmpingd_ip_xpath
, NB_OP_DESTROY
,
7917 return nb_cli_apply_changes(vty
, NULL
);
7924 "pim multicast routing\n"
7925 "Enable PIM ECMP \n")
7927 const char *vrfname
;
7928 char ecmp_xpath
[XPATH_MAXLEN
];
7930 vrfname
= pim_cli_get_vrf_name(vty
);
7931 if (vrfname
== NULL
)
7932 return CMD_WARNING_CONFIG_FAILED
;
7934 snprintf(ecmp_xpath
, sizeof(ecmp_xpath
), FRR_PIM_XPATH
,
7935 "frr-pim:pimd", "pim", vrfname
);
7936 strlcat(ecmp_xpath
, "/ecmp", sizeof(ecmp_xpath
));
7938 nb_cli_enqueue_change(vty
, ecmp_xpath
, NB_OP_MODIFY
, "true");
7939 return nb_cli_apply_changes(vty
, NULL
);
7942 DEFUN (no_ip_pim_ecmp
,
7947 "pim multicast routing\n"
7948 "Disable PIM ECMP \n")
7950 const char *vrfname
;
7951 char ecmp_xpath
[XPATH_MAXLEN
];
7953 vrfname
= pim_cli_get_vrf_name(vty
);
7954 if (vrfname
== NULL
)
7955 return CMD_WARNING_CONFIG_FAILED
;
7957 snprintf(ecmp_xpath
, sizeof(ecmp_xpath
), FRR_PIM_XPATH
,
7958 "frr-pim:pimd", "pim", vrfname
);
7959 strlcat(ecmp_xpath
, "/ecmp", sizeof(ecmp_xpath
));
7961 nb_cli_enqueue_change(vty
, ecmp_xpath
, NB_OP_MODIFY
, "false");
7963 return nb_cli_apply_changes(vty
, NULL
);
7966 DEFUN (ip_pim_ecmp_rebalance
,
7967 ip_pim_ecmp_rebalance_cmd
,
7968 "ip pim ecmp rebalance",
7970 "pim multicast routing\n"
7971 "Enable PIM ECMP \n"
7972 "Enable PIM ECMP Rebalance\n")
7974 const char *vrfname
;
7975 char ecmp_xpath
[XPATH_MAXLEN
];
7976 char ecmp_rebalance_xpath
[XPATH_MAXLEN
];
7978 vrfname
= pim_cli_get_vrf_name(vty
);
7979 if (vrfname
== NULL
)
7980 return CMD_WARNING_CONFIG_FAILED
;
7982 snprintf(ecmp_xpath
, sizeof(ecmp_xpath
), FRR_PIM_XPATH
,
7983 "frr-pim:pimd", "pim", vrfname
);
7984 strlcat(ecmp_xpath
, "/ecmp", sizeof(ecmp_xpath
));
7985 snprintf(ecmp_rebalance_xpath
, sizeof(ecmp_rebalance_xpath
),
7987 "frr-pim:pimd", "pim", vrfname
);
7988 strlcat(ecmp_rebalance_xpath
, "/ecmp-rebalance",
7989 sizeof(ecmp_rebalance_xpath
));
7991 nb_cli_enqueue_change(vty
, ecmp_xpath
, NB_OP_MODIFY
, "true");
7992 nb_cli_enqueue_change(vty
, ecmp_rebalance_xpath
, NB_OP_MODIFY
, "true");
7994 return nb_cli_apply_changes(vty
, NULL
);
7997 DEFUN (no_ip_pim_ecmp_rebalance
,
7998 no_ip_pim_ecmp_rebalance_cmd
,
7999 "no ip pim ecmp rebalance",
8002 "pim multicast routing\n"
8003 "Disable PIM ECMP \n"
8004 "Disable PIM ECMP Rebalance\n")
8006 const char *vrfname
;
8007 char ecmp_rebalance_xpath
[XPATH_MAXLEN
];
8009 vrfname
= pim_cli_get_vrf_name(vty
);
8010 if (vrfname
== NULL
)
8011 return CMD_WARNING_CONFIG_FAILED
;
8013 snprintf(ecmp_rebalance_xpath
, sizeof(ecmp_rebalance_xpath
),
8015 "frr-pim:pimd", "pim", vrfname
);
8016 strlcat(ecmp_rebalance_xpath
, "/ecmp-rebalance",
8017 sizeof(ecmp_rebalance_xpath
));
8019 nb_cli_enqueue_change(vty
, ecmp_rebalance_xpath
, NB_OP_MODIFY
, "false");
8021 return nb_cli_apply_changes(vty
, NULL
);
8024 DEFUN (interface_ip_igmp
,
8025 interface_ip_igmp_cmd
,
8030 nb_cli_enqueue_change(vty
, "./igmp-enable", NB_OP_MODIFY
, "true");
8032 return nb_cli_apply_changes(vty
, "./frr-igmp:igmp");
8035 DEFUN (interface_no_ip_igmp
,
8036 interface_no_ip_igmp_cmd
,
8042 const struct lyd_node
*pim_enable_dnode
;
8043 char pim_if_xpath
[XPATH_MAXLEN
+ 20];
8045 snprintf(pim_if_xpath
, sizeof(pim_if_xpath
),
8046 "%s/frr-pim:pim", VTY_CURR_XPATH
);
8048 pim_enable_dnode
= yang_dnode_getf(vty
->candidate_config
->dnode
,
8049 "%s/pim-enable", pim_if_xpath
);
8050 if (!pim_enable_dnode
) {
8051 nb_cli_enqueue_change(vty
, pim_if_xpath
, NB_OP_DESTROY
, NULL
);
8052 nb_cli_enqueue_change(vty
, ".", NB_OP_DESTROY
, NULL
);
8054 if (!yang_dnode_get_bool(pim_enable_dnode
, ".")) {
8055 nb_cli_enqueue_change(vty
, pim_if_xpath
, NB_OP_DESTROY
,
8057 nb_cli_enqueue_change(vty
, ".", NB_OP_DESTROY
, NULL
);
8059 nb_cli_enqueue_change(vty
, "./igmp-enable",
8060 NB_OP_MODIFY
, "false");
8063 return nb_cli_apply_changes(vty
, "./frr-igmp:igmp");
8066 DEFUN (interface_ip_igmp_join
,
8067 interface_ip_igmp_join_cmd
,
8068 "ip igmp join A.B.C.D [A.B.C.D]",
8071 "IGMP join multicast group\n"
8072 "Multicast group address\n"
8077 const char *source_str
;
8078 char xpath
[XPATH_MAXLEN
];
8081 source_str
= argv
[idx_source
]->arg
;
8083 if (strcmp(source_str
, "0.0.0.0") == 0) {
8084 vty_out(vty
, "Bad source address %s\n",
8085 argv
[idx_source
]->arg
);
8086 return CMD_WARNING_CONFIG_FAILED
;
8089 source_str
= "0.0.0.0";
8091 snprintf(xpath
, sizeof(xpath
), FRR_IGMP_JOIN_XPATH
,
8092 "frr-routing:ipv4", argv
[idx_group
]->arg
, source_str
);
8094 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
8096 return nb_cli_apply_changes(vty
, NULL
);
8099 DEFUN (interface_no_ip_igmp_join
,
8100 interface_no_ip_igmp_join_cmd
,
8101 "no ip igmp join A.B.C.D [A.B.C.D]",
8105 "IGMP join multicast group\n"
8106 "Multicast group address\n"
8111 const char *source_str
;
8112 char xpath
[XPATH_MAXLEN
];
8115 source_str
= argv
[idx_source
]->arg
;
8117 if (strcmp(source_str
, "0.0.0.0") == 0) {
8118 vty_out(vty
, "Bad source address %s\n",
8119 argv
[idx_source
]->arg
);
8120 return CMD_WARNING_CONFIG_FAILED
;
8123 source_str
= "0.0.0.0";
8125 snprintf(xpath
, sizeof(xpath
), FRR_IGMP_JOIN_XPATH
,
8126 "frr-routing:ipv4", argv
[idx_group
]->arg
, source_str
);
8128 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
8130 return nb_cli_apply_changes(vty
, NULL
);
8133 DEFUN (interface_ip_igmp_query_interval
,
8134 interface_ip_igmp_query_interval_cmd
,
8135 "ip igmp query-interval (1-65535)",
8138 IFACE_IGMP_QUERY_INTERVAL_STR
8139 "Query interval in seconds\n")
8141 const struct lyd_node
*pim_enable_dnode
;
8144 yang_dnode_getf(vty
->candidate_config
->dnode
,
8145 "%s/frr-pim:pim/pim-enable", VTY_CURR_XPATH
);
8146 if (!pim_enable_dnode
) {
8147 nb_cli_enqueue_change(vty
, "./igmp-enable", NB_OP_MODIFY
,
8150 if (!yang_dnode_get_bool(pim_enable_dnode
, "."))
8151 nb_cli_enqueue_change(vty
, "./igmp-enable",
8152 NB_OP_MODIFY
, "true");
8155 nb_cli_enqueue_change(vty
, "./query-interval", NB_OP_MODIFY
,
8158 return nb_cli_apply_changes(vty
, "./frr-igmp:igmp");
8161 DEFUN (interface_no_ip_igmp_query_interval
,
8162 interface_no_ip_igmp_query_interval_cmd
,
8163 "no ip igmp query-interval [(1-65535)]",
8167 IFACE_IGMP_QUERY_INTERVAL_STR
8170 nb_cli_enqueue_change(vty
, "./query-interval", NB_OP_DESTROY
, NULL
);
8172 return nb_cli_apply_changes(vty
, "./frr-igmp:igmp");
8175 DEFUN (interface_ip_igmp_version
,
8176 interface_ip_igmp_version_cmd
,
8177 "ip igmp version (2-3)",
8181 "IGMP version number\n")
8183 nb_cli_enqueue_change(vty
, "./igmp-enable", NB_OP_MODIFY
,
8185 nb_cli_enqueue_change(vty
, "./version", NB_OP_MODIFY
, argv
[3]->arg
);
8187 return nb_cli_apply_changes(vty
, "./frr-igmp:igmp");
8190 DEFUN (interface_no_ip_igmp_version
,
8191 interface_no_ip_igmp_version_cmd
,
8192 "no ip igmp version (2-3)",
8197 "IGMP version number\n")
8199 nb_cli_enqueue_change(vty
, "./version", NB_OP_DESTROY
, NULL
);
8201 return nb_cli_apply_changes(vty
, "./frr-igmp:igmp");
8204 DEFUN (interface_ip_igmp_query_max_response_time
,
8205 interface_ip_igmp_query_max_response_time_cmd
,
8206 "ip igmp query-max-response-time (1-65535)",
8209 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
8210 "Query response value in deci-seconds\n")
8212 const struct lyd_node
*pim_enable_dnode
;
8215 yang_dnode_getf(vty
->candidate_config
->dnode
,
8216 "%s/frr-pim:pim/pim-enable", VTY_CURR_XPATH
);
8218 if (!pim_enable_dnode
) {
8219 nb_cli_enqueue_change(vty
, "./igmp-enable", NB_OP_MODIFY
,
8222 if (!yang_dnode_get_bool(pim_enable_dnode
, "."))
8223 nb_cli_enqueue_change(vty
, "./igmp-enable",
8224 NB_OP_MODIFY
, "true");
8227 nb_cli_enqueue_change(vty
, "./query-max-response-time", NB_OP_MODIFY
,
8230 return nb_cli_apply_changes(vty
, "./frr-igmp:igmp");
8233 DEFUN (interface_no_ip_igmp_query_max_response_time
,
8234 interface_no_ip_igmp_query_max_response_time_cmd
,
8235 "no ip igmp query-max-response-time [(1-65535)]",
8239 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
8242 nb_cli_enqueue_change(vty
, "./query-max-response-time", NB_OP_DESTROY
,
8244 return nb_cli_apply_changes(vty
, "./frr-igmp:igmp");
8247 DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec
,
8248 interface_ip_igmp_query_max_response_time_dsec_cmd
,
8249 "ip igmp query-max-response-time-dsec (1-65535)",
8252 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
8253 "Query response value in deciseconds\n")
8255 const struct lyd_node
*pim_enable_dnode
;
8258 yang_dnode_getf(vty
->candidate_config
->dnode
,
8259 "%s/frr-pim:pim/pim-enable", VTY_CURR_XPATH
);
8260 if (!pim_enable_dnode
) {
8261 nb_cli_enqueue_change(vty
, "./igmp-enable", NB_OP_MODIFY
,
8264 if (!yang_dnode_get_bool(pim_enable_dnode
, "."))
8265 nb_cli_enqueue_change(vty
, "./igmp-enable",
8266 NB_OP_MODIFY
, "true");
8269 nb_cli_enqueue_change(vty
, "./query-max-response-time", NB_OP_MODIFY
,
8272 return nb_cli_apply_changes(vty
, "./frr-igmp:igmp");
8275 DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec
,
8276 interface_no_ip_igmp_query_max_response_time_dsec_cmd
,
8277 "no ip igmp query-max-response-time-dsec [(1-65535)]",
8281 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
8284 nb_cli_enqueue_change(vty
, "./query-max-response-time", NB_OP_DESTROY
,
8287 return nb_cli_apply_changes(vty
, "./frr-igmp:igmp");
8290 DEFUN (interface_ip_igmp_last_member_query_count
,
8291 interface_ip_igmp_last_member_query_count_cmd
,
8292 "ip igmp last-member-query-count (1-255)",
8295 IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR
8296 "Last member query count\n")
8298 const struct lyd_node
*pim_enable_dnode
;
8301 yang_dnode_getf(vty
->candidate_config
->dnode
,
8302 "%s/frr-pim:pim/pim-enable", VTY_CURR_XPATH
);
8303 if (!pim_enable_dnode
) {
8304 nb_cli_enqueue_change(vty
, "./igmp-enable", NB_OP_MODIFY
,
8307 if (!yang_dnode_get_bool(pim_enable_dnode
, "."))
8308 nb_cli_enqueue_change(vty
, "./igmp-enable",
8309 NB_OP_MODIFY
, "true");
8312 nb_cli_enqueue_change(vty
, "./robustness-variable", NB_OP_MODIFY
,
8315 return nb_cli_apply_changes(vty
, "./frr-igmp:igmp");
8318 DEFUN (interface_no_ip_igmp_last_member_query_count
,
8319 interface_no_ip_igmp_last_member_query_count_cmd
,
8320 "no ip igmp last-member-query-count [(1-255)]",
8324 IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR
8327 nb_cli_enqueue_change(vty
, "./robustness-variable", NB_OP_DESTROY
,
8330 return nb_cli_apply_changes(vty
, "./frr-igmp:igmp");
8333 DEFUN (interface_ip_igmp_last_member_query_interval
,
8334 interface_ip_igmp_last_member_query_interval_cmd
,
8335 "ip igmp last-member-query-interval (1-65535)",
8338 IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR
8339 "Last member query interval in deciseconds\n")
8341 const struct lyd_node
*pim_enable_dnode
;
8344 yang_dnode_getf(vty
->candidate_config
->dnode
,
8345 "%s/frr-pim:pim/pim-enable", VTY_CURR_XPATH
);
8346 if (!pim_enable_dnode
) {
8347 nb_cli_enqueue_change(vty
, "./igmp-enable", NB_OP_MODIFY
,
8350 if (!yang_dnode_get_bool(pim_enable_dnode
, "."))
8351 nb_cli_enqueue_change(vty
, "./igmp-enable",
8352 NB_OP_MODIFY
, "true");
8355 nb_cli_enqueue_change(vty
, "./last-member-query-interval", NB_OP_MODIFY
,
8358 return nb_cli_apply_changes(vty
, "./frr-igmp:igmp");
8361 DEFUN (interface_no_ip_igmp_last_member_query_interval
,
8362 interface_no_ip_igmp_last_member_query_interval_cmd
,
8363 "no ip igmp last-member-query-interval [(1-65535)]",
8367 IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR
8370 nb_cli_enqueue_change(vty
, "./last-member-query-interval",
8371 NB_OP_DESTROY
, NULL
);
8373 return nb_cli_apply_changes(vty
, "./frr-igmp:igmp");
8376 DEFUN (interface_ip_pim_drprio
,
8377 interface_ip_pim_drprio_cmd
,
8378 "ip pim drpriority (1-4294967295)",
8381 "Set the Designated Router Election Priority\n"
8382 "Value of the new DR Priority\n")
8386 nb_cli_enqueue_change(vty
, "./dr-priority", NB_OP_MODIFY
,
8387 argv
[idx_number
]->arg
);
8389 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
8392 DEFUN (interface_no_ip_pim_drprio
,
8393 interface_no_ip_pim_drprio_cmd
,
8394 "no ip pim drpriority [(1-4294967295)]",
8398 "Revert the Designated Router Priority to default\n"
8399 "Old Value of the Priority\n")
8401 nb_cli_enqueue_change(vty
, "./dr-priority", NB_OP_DESTROY
, NULL
);
8403 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
8406 DEFPY_HIDDEN (interface_ip_igmp_query_generate
,
8407 interface_ip_igmp_query_generate_cmd
,
8408 "ip igmp generate-query-once [version (2-3)]",
8411 "Generate igmp general query once\n"
8413 "IGMP version number\n")
8415 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8416 int igmp_version
= 2;
8419 vty_out(vty
, "IGMP/PIM is not enabled on the interface %s\n",
8421 return CMD_WARNING_CONFIG_FAILED
;
8425 igmp_version
= atoi(argv
[4]->arg
);
8427 igmp_send_query_on_intf(ifp
, igmp_version
);
8432 DEFPY_HIDDEN (pim_test_sg_keepalive
,
8433 pim_test_sg_keepalive_cmd
,
8434 "test pim [vrf NAME$name] keepalive-reset A.B.C.D$source A.B.C.D$group",
8438 "Reset the Keepalive Timer\n"
8439 "The Source we are resetting\n"
8440 "The Group we are resetting\n")
8442 struct pim_upstream
*up
;
8443 struct pim_instance
*pim
;
8444 struct prefix_sg sg
;
8450 pim
= pim_get_pim_instance(VRF_DEFAULT
);
8452 struct vrf
*vrf
= vrf_lookup_by_name(name
);
8455 vty_out(vty
, "%% Vrf specified: %s does not exist\n",
8460 pim
= pim_get_pim_instance(vrf
->vrf_id
);
8464 vty_out(vty
, "%% Unable to find pim instance\n");
8468 up
= pim_upstream_find(pim
, &sg
);
8470 vty_out(vty
, "%% Unable to find %s specified\n",
8471 pim_str_sg_dump(&sg
));
8475 vty_out(vty
, "Setting %s to current keep alive time: %d\n",
8476 pim_str_sg_dump(&sg
), pim
->keep_alive_time
);
8477 pim_upstream_keep_alive_timer_start(up
, pim
->keep_alive_time
);
8482 DEFPY (interface_ip_pim_activeactive
,
8483 interface_ip_pim_activeactive_cmd
,
8484 "[no$no] ip pim active-active",
8488 "Mark interface as Active-Active for MLAG operations, Hidden because not finished yet\n")
8491 nb_cli_enqueue_change(vty
, "./active-active", NB_OP_MODIFY
,
8494 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
,
8497 nb_cli_enqueue_change(vty
, "./active-active", NB_OP_MODIFY
,
8501 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
8504 DEFUN_HIDDEN (interface_ip_pim_ssm
,
8505 interface_ip_pim_ssm_cmd
,
8513 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
, "true");
8515 ret
= nb_cli_apply_changes(vty
, "./frr-pim:pim");
8521 "WARN: Enabled PIM SM on interface; configure PIM SSM range if needed\n");
8526 DEFUN_HIDDEN (interface_ip_pim_sm
,
8527 interface_ip_pim_sm_cmd
,
8533 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
, "true");
8535 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
8538 DEFUN (interface_ip_pim
,
8539 interface_ip_pim_cmd
,
8544 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
, "true");
8546 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
8549 DEFUN_HIDDEN (interface_no_ip_pim_ssm
,
8550 interface_no_ip_pim_ssm_cmd
,
8557 const struct lyd_node
*igmp_enable_dnode
;
8558 char igmp_if_xpath
[XPATH_MAXLEN
+ 20];
8560 snprintf(igmp_if_xpath
, sizeof(igmp_if_xpath
),
8561 "%s/frr-igmp:igmp", VTY_CURR_XPATH
);
8562 igmp_enable_dnode
= yang_dnode_getf(vty
->candidate_config
->dnode
,
8563 "%s/igmp-enable", igmp_if_xpath
);
8565 if (!igmp_enable_dnode
) {
8566 nb_cli_enqueue_change(vty
, igmp_if_xpath
, NB_OP_DESTROY
, NULL
);
8567 nb_cli_enqueue_change(vty
, ".", NB_OP_DESTROY
, NULL
);
8569 if (!yang_dnode_get_bool(igmp_enable_dnode
, ".")) {
8570 nb_cli_enqueue_change(vty
, igmp_if_xpath
, NB_OP_DESTROY
,
8572 nb_cli_enqueue_change(vty
, ".", NB_OP_DESTROY
, NULL
);
8574 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
,
8578 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
8581 DEFUN_HIDDEN (interface_no_ip_pim_sm
,
8582 interface_no_ip_pim_sm_cmd
,
8589 const struct lyd_node
*igmp_enable_dnode
;
8590 char igmp_if_xpath
[XPATH_MAXLEN
+ 20];
8592 snprintf(igmp_if_xpath
, sizeof(igmp_if_xpath
),
8593 "%s/frr-igmp:igmp", VTY_CURR_XPATH
);
8594 igmp_enable_dnode
= yang_dnode_getf(vty
->candidate_config
->dnode
,
8595 "%s/igmp-enable", igmp_if_xpath
);
8597 if (!igmp_enable_dnode
) {
8598 nb_cli_enqueue_change(vty
, igmp_if_xpath
, NB_OP_DESTROY
, NULL
);
8599 nb_cli_enqueue_change(vty
, ".", NB_OP_DESTROY
, NULL
);
8601 if (!yang_dnode_get_bool(igmp_enable_dnode
, ".")) {
8602 nb_cli_enqueue_change(vty
, igmp_if_xpath
, NB_OP_DESTROY
,
8604 nb_cli_enqueue_change(vty
, ".", NB_OP_DESTROY
, NULL
);
8606 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
,
8610 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
8613 DEFUN (interface_no_ip_pim
,
8614 interface_no_ip_pim_cmd
,
8620 const struct lyd_node
*igmp_enable_dnode
;
8621 char igmp_if_xpath
[XPATH_MAXLEN
+ 20];
8623 snprintf(igmp_if_xpath
, sizeof(igmp_if_xpath
),
8624 "%s/frr-igmp:igmp", VTY_CURR_XPATH
);
8625 igmp_enable_dnode
= yang_dnode_getf(vty
->candidate_config
->dnode
,
8626 "%s/igmp-enable", igmp_if_xpath
);
8628 if (!igmp_enable_dnode
) {
8629 nb_cli_enqueue_change(vty
, igmp_if_xpath
, NB_OP_DESTROY
, NULL
);
8630 nb_cli_enqueue_change(vty
, ".", NB_OP_DESTROY
, NULL
);
8632 if (!yang_dnode_get_bool(igmp_enable_dnode
, ".")) {
8633 nb_cli_enqueue_change(vty
, igmp_if_xpath
, NB_OP_DESTROY
,
8635 nb_cli_enqueue_change(vty
, ".", NB_OP_DESTROY
, NULL
);
8637 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
,
8641 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
8645 DEFUN(interface_ip_pim_boundary_oil
,
8646 interface_ip_pim_boundary_oil_cmd
,
8647 "ip multicast boundary oil WORD",
8649 "Generic multicast configuration options\n"
8650 "Define multicast boundary\n"
8651 "Filter OIL by group using prefix list\n"
8652 "Prefix list to filter OIL with\n")
8654 nb_cli_enqueue_change(vty
, "./multicast-boundary-oil", NB_OP_MODIFY
,
8657 return nb_cli_apply_changes(vty
,
8658 "./frr-pim:pim/address-family[address-family='%s']",
8659 "frr-routing:ipv4");
8663 DEFUN(interface_no_ip_pim_boundary_oil
,
8664 interface_no_ip_pim_boundary_oil_cmd
,
8665 "no ip multicast boundary oil [WORD]",
8668 "Generic multicast configuration options\n"
8669 "Define multicast boundary\n"
8670 "Filter OIL by group using prefix list\n"
8671 "Prefix list to filter OIL with\n")
8673 nb_cli_enqueue_change(vty
, "./multicast-boundary-oil", NB_OP_DESTROY
,
8676 return nb_cli_apply_changes(vty
,
8677 "./frr-pim:pim/address-family[address-family='%s']",
8678 "frr-routing:ipv4");
8681 DEFUN (interface_ip_mroute
,
8682 interface_ip_mroute_cmd
,
8683 "ip mroute INTERFACE A.B.C.D [A.B.C.D]",
8685 "Add multicast route\n"
8686 "Outgoing interface name\n"
8690 int idx_interface
= 2;
8692 const char *source_str
;
8694 if (argc
== (idx_ipv4
+ 1))
8695 source_str
= "0.0.0.0";
8697 source_str
= argv
[idx_ipv4
+ 1]->arg
;
8699 nb_cli_enqueue_change(vty
, "./oif", NB_OP_MODIFY
,
8700 argv
[idx_interface
]->arg
);
8702 return nb_cli_apply_changes(vty
,
8703 "./frr-pim:pim/address-family[address-family='%s']/mroute[source-addr='%s'][group-addr='%s']",
8704 "frr-routing:ipv4", source_str
,
8705 argv
[idx_ipv4
]->arg
);
8708 DEFUN (interface_no_ip_mroute
,
8709 interface_no_ip_mroute_cmd
,
8710 "no ip mroute INTERFACE A.B.C.D [A.B.C.D]",
8713 "Add multicast route\n"
8714 "Outgoing interface name\n"
8719 const char *source_str
;
8721 if (argc
== (idx_ipv4
+ 1))
8722 source_str
= "0.0.0.0";
8724 source_str
= argv
[idx_ipv4
+ 1]->arg
;
8726 nb_cli_enqueue_change(vty
, ".", NB_OP_DESTROY
, NULL
);
8728 return nb_cli_apply_changes(vty
,
8729 "./frr-pim:pim/address-family[address-family='%s']/mroute[source-addr='%s'][group-addr='%s']",
8730 "frr-routing:ipv4", source_str
,
8731 argv
[idx_ipv4
]->arg
);
8734 DEFUN (interface_ip_pim_hello
,
8735 interface_ip_pim_hello_cmd
,
8736 "ip pim hello (1-65535) [(1-65535)]",
8740 IFACE_PIM_HELLO_TIME_STR
8741 IFACE_PIM_HELLO_HOLD_STR
)
8745 const struct lyd_node
*igmp_enable_dnode
;
8748 yang_dnode_getf(vty
->candidate_config
->dnode
,
8749 "%s/frr-igmp:igmp/igmp-enable", VTY_CURR_XPATH
);
8750 if (!igmp_enable_dnode
) {
8751 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
,
8754 if (!yang_dnode_get_bool(igmp_enable_dnode
, "."))
8755 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
,
8759 nb_cli_enqueue_change(vty
, "./hello-interval", NB_OP_MODIFY
,
8760 argv
[idx_time
]->arg
);
8762 if (argc
== idx_hold
+ 1)
8763 nb_cli_enqueue_change(vty
, "./hello-holdtime", NB_OP_MODIFY
,
8764 argv
[idx_hold
]->arg
);
8766 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
8769 DEFUN (interface_no_ip_pim_hello
,
8770 interface_no_ip_pim_hello_cmd
,
8771 "no ip pim hello [(1-65535) [(1-65535)]]",
8779 nb_cli_enqueue_change(vty
, "./hello-interval", NB_OP_DESTROY
, NULL
);
8780 nb_cli_enqueue_change(vty
, "./hello-holdtime", NB_OP_DESTROY
, NULL
);
8782 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
8791 PIM_DO_DEBUG_IGMP_EVENTS
;
8792 PIM_DO_DEBUG_IGMP_PACKETS
;
8793 PIM_DO_DEBUG_IGMP_TRACE
;
8797 DEFUN (no_debug_igmp
,
8804 PIM_DONT_DEBUG_IGMP_EVENTS
;
8805 PIM_DONT_DEBUG_IGMP_PACKETS
;
8806 PIM_DONT_DEBUG_IGMP_TRACE
;
8811 DEFUN (debug_igmp_events
,
8812 debug_igmp_events_cmd
,
8813 "debug igmp events",
8816 DEBUG_IGMP_EVENTS_STR
)
8818 PIM_DO_DEBUG_IGMP_EVENTS
;
8822 DEFUN (no_debug_igmp_events
,
8823 no_debug_igmp_events_cmd
,
8824 "no debug igmp events",
8828 DEBUG_IGMP_EVENTS_STR
)
8830 PIM_DONT_DEBUG_IGMP_EVENTS
;
8835 DEFUN (debug_igmp_packets
,
8836 debug_igmp_packets_cmd
,
8837 "debug igmp packets",
8840 DEBUG_IGMP_PACKETS_STR
)
8842 PIM_DO_DEBUG_IGMP_PACKETS
;
8846 DEFUN (no_debug_igmp_packets
,
8847 no_debug_igmp_packets_cmd
,
8848 "no debug igmp packets",
8852 DEBUG_IGMP_PACKETS_STR
)
8854 PIM_DONT_DEBUG_IGMP_PACKETS
;
8859 DEFUN (debug_igmp_trace
,
8860 debug_igmp_trace_cmd
,
8864 DEBUG_IGMP_TRACE_STR
)
8866 PIM_DO_DEBUG_IGMP_TRACE
;
8870 DEFUN (no_debug_igmp_trace
,
8871 no_debug_igmp_trace_cmd
,
8872 "no debug igmp trace",
8876 DEBUG_IGMP_TRACE_STR
)
8878 PIM_DONT_DEBUG_IGMP_TRACE
;
8883 DEFUN (debug_mroute
,
8889 PIM_DO_DEBUG_MROUTE
;
8893 DEFUN (debug_mroute_detail
,
8894 debug_mroute_detail_cmd
,
8895 "debug mroute detail",
8900 PIM_DO_DEBUG_MROUTE_DETAIL
;
8904 DEFUN (no_debug_mroute
,
8905 no_debug_mroute_cmd
,
8911 PIM_DONT_DEBUG_MROUTE
;
8915 DEFUN (no_debug_mroute_detail
,
8916 no_debug_mroute_detail_cmd
,
8917 "no debug mroute detail",
8923 PIM_DONT_DEBUG_MROUTE_DETAIL
;
8927 DEFUN (debug_pim_static
,
8928 debug_pim_static_cmd
,
8934 PIM_DO_DEBUG_STATIC
;
8938 DEFUN (no_debug_pim_static
,
8939 no_debug_pim_static_cmd
,
8940 "no debug pim static",
8946 PIM_DONT_DEBUG_STATIC
;
8957 PIM_DO_DEBUG_PIM_EVENTS
;
8958 PIM_DO_DEBUG_PIM_PACKETS
;
8959 PIM_DO_DEBUG_PIM_TRACE
;
8960 PIM_DO_DEBUG_MSDP_EVENTS
;
8961 PIM_DO_DEBUG_MSDP_PACKETS
;
8966 DEFUN (no_debug_pim
,
8973 PIM_DONT_DEBUG_PIM_EVENTS
;
8974 PIM_DONT_DEBUG_PIM_PACKETS
;
8975 PIM_DONT_DEBUG_PIM_TRACE
;
8976 PIM_DONT_DEBUG_MSDP_EVENTS
;
8977 PIM_DONT_DEBUG_MSDP_PACKETS
;
8979 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
8980 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
8986 DEFUN (debug_pim_nht
,
8991 "Nexthop Tracking\n")
8993 PIM_DO_DEBUG_PIM_NHT
;
8997 DEFUN (no_debug_pim_nht
,
8998 no_debug_pim_nht_cmd
,
9003 "Nexthop Tracking\n")
9005 PIM_DONT_DEBUG_PIM_NHT
;
9009 DEFUN (debug_pim_nht_rp
,
9010 debug_pim_nht_rp_cmd
,
9014 "Nexthop Tracking\n"
9015 "RP Nexthop Tracking\n")
9017 PIM_DO_DEBUG_PIM_NHT_RP
;
9021 DEFUN (no_debug_pim_nht_rp
,
9022 no_debug_pim_nht_rp_cmd
,
9023 "no debug pim nht rp",
9027 "Nexthop Tracking\n"
9028 "RP Nexthop Tracking\n")
9030 PIM_DONT_DEBUG_PIM_NHT_RP
;
9034 DEFUN (debug_pim_events
,
9035 debug_pim_events_cmd
,
9039 DEBUG_PIM_EVENTS_STR
)
9041 PIM_DO_DEBUG_PIM_EVENTS
;
9045 DEFUN (no_debug_pim_events
,
9046 no_debug_pim_events_cmd
,
9047 "no debug pim events",
9051 DEBUG_PIM_EVENTS_STR
)
9053 PIM_DONT_DEBUG_PIM_EVENTS
;
9057 DEFUN (debug_pim_packets
,
9058 debug_pim_packets_cmd
,
9059 "debug pim packets [<hello|joins|register>]",
9062 DEBUG_PIM_PACKETS_STR
9063 DEBUG_PIM_HELLO_PACKETS_STR
9064 DEBUG_PIM_J_P_PACKETS_STR
9065 DEBUG_PIM_PIM_REG_PACKETS_STR
)
9068 if (argv_find(argv
, argc
, "hello", &idx
)) {
9069 PIM_DO_DEBUG_PIM_HELLO
;
9070 vty_out(vty
, "PIM Hello debugging is on\n");
9071 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
9072 PIM_DO_DEBUG_PIM_J_P
;
9073 vty_out(vty
, "PIM Join/Prune debugging is on\n");
9074 } else if (argv_find(argv
, argc
, "register", &idx
)) {
9075 PIM_DO_DEBUG_PIM_REG
;
9076 vty_out(vty
, "PIM Register debugging is on\n");
9078 PIM_DO_DEBUG_PIM_PACKETS
;
9079 vty_out(vty
, "PIM Packet debugging is on \n");
9084 DEFUN (no_debug_pim_packets
,
9085 no_debug_pim_packets_cmd
,
9086 "no debug pim packets [<hello|joins|register>]",
9090 DEBUG_PIM_PACKETS_STR
9091 DEBUG_PIM_HELLO_PACKETS_STR
9092 DEBUG_PIM_J_P_PACKETS_STR
9093 DEBUG_PIM_PIM_REG_PACKETS_STR
)
9096 if (argv_find(argv
, argc
, "hello", &idx
)) {
9097 PIM_DONT_DEBUG_PIM_HELLO
;
9098 vty_out(vty
, "PIM Hello debugging is off \n");
9099 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
9100 PIM_DONT_DEBUG_PIM_J_P
;
9101 vty_out(vty
, "PIM Join/Prune debugging is off \n");
9102 } else if (argv_find(argv
, argc
, "register", &idx
)) {
9103 PIM_DONT_DEBUG_PIM_REG
;
9104 vty_out(vty
, "PIM Register debugging is off\n");
9106 PIM_DONT_DEBUG_PIM_PACKETS
;
9112 DEFUN (debug_pim_packetdump_send
,
9113 debug_pim_packetdump_send_cmd
,
9114 "debug pim packet-dump send",
9117 DEBUG_PIM_PACKETDUMP_STR
9118 DEBUG_PIM_PACKETDUMP_SEND_STR
)
9120 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND
;
9124 DEFUN (no_debug_pim_packetdump_send
,
9125 no_debug_pim_packetdump_send_cmd
,
9126 "no debug pim packet-dump send",
9130 DEBUG_PIM_PACKETDUMP_STR
9131 DEBUG_PIM_PACKETDUMP_SEND_STR
)
9133 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
9137 DEFUN (debug_pim_packetdump_recv
,
9138 debug_pim_packetdump_recv_cmd
,
9139 "debug pim packet-dump receive",
9142 DEBUG_PIM_PACKETDUMP_STR
9143 DEBUG_PIM_PACKETDUMP_RECV_STR
)
9145 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV
;
9149 DEFUN (no_debug_pim_packetdump_recv
,
9150 no_debug_pim_packetdump_recv_cmd
,
9151 "no debug pim packet-dump receive",
9155 DEBUG_PIM_PACKETDUMP_STR
9156 DEBUG_PIM_PACKETDUMP_RECV_STR
)
9158 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
9162 DEFUN (debug_pim_trace
,
9163 debug_pim_trace_cmd
,
9167 DEBUG_PIM_TRACE_STR
)
9169 PIM_DO_DEBUG_PIM_TRACE
;
9173 DEFUN (debug_pim_trace_detail
,
9174 debug_pim_trace_detail_cmd
,
9175 "debug pim trace detail",
9179 "Detailed Information\n")
9181 PIM_DO_DEBUG_PIM_TRACE_DETAIL
;
9185 DEFUN (no_debug_pim_trace
,
9186 no_debug_pim_trace_cmd
,
9187 "no debug pim trace",
9191 DEBUG_PIM_TRACE_STR
)
9193 PIM_DONT_DEBUG_PIM_TRACE
;
9197 DEFUN (no_debug_pim_trace_detail
,
9198 no_debug_pim_trace_detail_cmd
,
9199 "no debug pim trace detail",
9204 "Detailed Information\n")
9206 PIM_DONT_DEBUG_PIM_TRACE_DETAIL
;
9210 DEFUN (debug_ssmpingd
,
9216 PIM_DO_DEBUG_SSMPINGD
;
9220 DEFUN (no_debug_ssmpingd
,
9221 no_debug_ssmpingd_cmd
,
9222 "no debug ssmpingd",
9227 PIM_DONT_DEBUG_SSMPINGD
;
9231 DEFUN (debug_pim_zebra
,
9232 debug_pim_zebra_cmd
,
9236 DEBUG_PIM_ZEBRA_STR
)
9242 DEFUN (no_debug_pim_zebra
,
9243 no_debug_pim_zebra_cmd
,
9244 "no debug pim zebra",
9248 DEBUG_PIM_ZEBRA_STR
)
9250 PIM_DONT_DEBUG_ZEBRA
;
9254 DEFUN(debug_pim_mlag
, debug_pim_mlag_cmd
, "debug pim mlag",
9255 DEBUG_STR DEBUG_PIM_STR DEBUG_PIM_MLAG_STR
)
9261 DEFUN(no_debug_pim_mlag
, no_debug_pim_mlag_cmd
, "no debug pim mlag",
9262 NO_STR DEBUG_STR DEBUG_PIM_STR DEBUG_PIM_MLAG_STR
)
9264 PIM_DONT_DEBUG_MLAG
;
9268 DEFUN (debug_pim_vxlan
,
9269 debug_pim_vxlan_cmd
,
9273 DEBUG_PIM_VXLAN_STR
)
9279 DEFUN (no_debug_pim_vxlan
,
9280 no_debug_pim_vxlan_cmd
,
9281 "no debug pim vxlan",
9285 DEBUG_PIM_VXLAN_STR
)
9287 PIM_DONT_DEBUG_VXLAN
;
9297 PIM_DO_DEBUG_MSDP_EVENTS
;
9298 PIM_DO_DEBUG_MSDP_PACKETS
;
9302 DEFUN (no_debug_msdp
,
9309 PIM_DONT_DEBUG_MSDP_EVENTS
;
9310 PIM_DONT_DEBUG_MSDP_PACKETS
;
9314 DEFUN (debug_msdp_events
,
9315 debug_msdp_events_cmd
,
9316 "debug msdp events",
9319 DEBUG_MSDP_EVENTS_STR
)
9321 PIM_DO_DEBUG_MSDP_EVENTS
;
9325 DEFUN (no_debug_msdp_events
,
9326 no_debug_msdp_events_cmd
,
9327 "no debug msdp events",
9331 DEBUG_MSDP_EVENTS_STR
)
9333 PIM_DONT_DEBUG_MSDP_EVENTS
;
9337 DEFUN (debug_msdp_packets
,
9338 debug_msdp_packets_cmd
,
9339 "debug msdp packets",
9342 DEBUG_MSDP_PACKETS_STR
)
9344 PIM_DO_DEBUG_MSDP_PACKETS
;
9348 DEFUN (no_debug_msdp_packets
,
9349 no_debug_msdp_packets_cmd
,
9350 "no debug msdp packets",
9354 DEBUG_MSDP_PACKETS_STR
)
9356 PIM_DONT_DEBUG_MSDP_PACKETS
;
9360 DEFUN (debug_mtrace
,
9366 PIM_DO_DEBUG_MTRACE
;
9370 DEFUN (no_debug_mtrace
,
9371 no_debug_mtrace_cmd
,
9377 PIM_DONT_DEBUG_MTRACE
;
9392 DEFUN (no_debug_bsm
,
9405 DEFUN_NOSH (show_debugging_pim
,
9406 show_debugging_pim_cmd
,
9407 "show debugging [pim]",
9412 vty_out(vty
, "PIM debugging status\n");
9414 pim_debug_config_write(vty
);
9419 DEFUN (interface_pim_use_source
,
9420 interface_pim_use_source_cmd
,
9421 "ip pim use-source A.B.C.D",
9424 "Configure primary IP address\n"
9425 "source ip address\n")
9427 nb_cli_enqueue_change(vty
, "./use-source", NB_OP_MODIFY
, argv
[3]->arg
);
9429 return nb_cli_apply_changes(vty
,
9430 "./frr-pim:pim/address-family[address-family='%s']",
9431 "frr-routing:ipv4");
9434 DEFUN (interface_no_pim_use_source
,
9435 interface_no_pim_use_source_cmd
,
9436 "no ip pim use-source [A.B.C.D]",
9440 "Delete source IP address\n"
9441 "source ip address\n")
9443 nb_cli_enqueue_change(vty
, "./use-source", NB_OP_MODIFY
, "0.0.0.0");
9445 return nb_cli_apply_changes(vty
,
9446 "./frr-pim:pim/address-family[address-family='%s']",
9447 "frr-routing:ipv4");
9452 "ip pim bfd [profile BFDPROF$prof]",
9455 "Enables BFD support\n"
9457 "Use BFD profile name\n")
9459 const struct lyd_node
*igmp_enable_dnode
;
9462 yang_dnode_getf(vty
->candidate_config
->dnode
,
9463 "%s/frr-igmp:igmp/igmp-enable", VTY_CURR_XPATH
);
9464 if (!igmp_enable_dnode
)
9465 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
,
9468 if (!yang_dnode_get_bool(igmp_enable_dnode
, "."))
9469 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
,
9473 nb_cli_enqueue_change(vty
, "./bfd", NB_OP_CREATE
, NULL
);
9475 nb_cli_enqueue_change(vty
, "./bfd/profile", NB_OP_MODIFY
, prof
);
9477 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
9480 DEFPY(no_ip_pim_bfd_profile
, no_ip_pim_bfd_profile_cmd
,
9481 "no ip pim bfd profile [BFDPROF]",
9485 "Enables BFD support\n"
9486 "Disable BFD profile\n"
9487 "BFD Profile name\n")
9489 nb_cli_enqueue_change(vty
, "./bfd/profile", NB_OP_DESTROY
, NULL
);
9491 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
9494 DEFUN (no_ip_pim_bfd
,
9500 "Disables BFD support\n")
9502 nb_cli_enqueue_change(vty
, "./bfd", NB_OP_DESTROY
, NULL
);
9504 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
9512 "Enables BSM support on the interface\n")
9514 const struct lyd_node
*igmp_enable_dnode
;
9517 yang_dnode_getf(vty
->candidate_config
->dnode
,
9518 "%s/frr-igmp:igmp/igmp-enable", VTY_CURR_XPATH
);
9519 if (!igmp_enable_dnode
)
9520 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
,
9523 if (!yang_dnode_get_bool(igmp_enable_dnode
, "."))
9524 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
,
9528 nb_cli_enqueue_change(vty
, "./bsm", NB_OP_MODIFY
, "true");
9530 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
9533 DEFUN (no_ip_pim_bsm
,
9539 "Disables BSM support\n")
9541 nb_cli_enqueue_change(vty
, "./bsm", NB_OP_MODIFY
, "false");
9543 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
9546 DEFUN (ip_pim_ucast_bsm
,
9547 ip_pim_ucast_bsm_cmd
,
9548 "ip pim unicast-bsm",
9551 "Accept/Send unicast BSM on the interface\n")
9553 const struct lyd_node
*igmp_enable_dnode
;
9556 yang_dnode_getf(vty
->candidate_config
->dnode
,
9557 "%s/frr-igmp:igmp/igmp-enable", VTY_CURR_XPATH
);
9558 if (!igmp_enable_dnode
)
9559 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
,
9562 if (!yang_dnode_get_bool(igmp_enable_dnode
, "."))
9563 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
,
9567 nb_cli_enqueue_change(vty
, "./unicast-bsm", NB_OP_MODIFY
, "true");
9569 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
9572 DEFUN (no_ip_pim_ucast_bsm
,
9573 no_ip_pim_ucast_bsm_cmd
,
9574 "no ip pim unicast-bsm",
9578 "Block send/receive unicast BSM on this interface\n")
9580 nb_cli_enqueue_change(vty
, "./unicast-bsm", NB_OP_MODIFY
, "false");
9582 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
9588 ip_pim_bfd_param_cmd
,
9589 "ip pim bfd (2-255) (1-65535) (1-65535)",
9592 "Enables BFD support\n"
9593 "Detect Multiplier\n"
9594 "Required min receive interval\n"
9595 "Desired min transmit interval\n")
9599 ip_pim_bfd_param_cmd
,
9600 "ip pim bfd (2-255) (1-65535) (1-65535)",
9603 "Enables BFD support\n"
9604 "Detect Multiplier\n"
9605 "Required min receive interval\n"
9606 "Desired min transmit interval\n")
9607 #endif /* HAVE_BFDD */
9610 int idx_number_2
= 4;
9611 int idx_number_3
= 5;
9612 const struct lyd_node
*igmp_enable_dnode
;
9615 yang_dnode_getf(vty
->candidate_config
->dnode
,
9616 "%s/frr-igmp:igmp/igmp-enable", VTY_CURR_XPATH
);
9617 if (!igmp_enable_dnode
)
9618 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
,
9621 if (!yang_dnode_get_bool(igmp_enable_dnode
, "."))
9622 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
,
9626 nb_cli_enqueue_change(vty
, "./bfd", NB_OP_CREATE
, NULL
);
9627 nb_cli_enqueue_change(vty
, "./bfd/min-rx-interval", NB_OP_MODIFY
,
9628 argv
[idx_number_2
]->arg
);
9629 nb_cli_enqueue_change(vty
, "./bfd/min-tx-interval", NB_OP_MODIFY
,
9630 argv
[idx_number_3
]->arg
);
9631 nb_cli_enqueue_change(vty
, "./bfd/detect_mult", NB_OP_MODIFY
,
9632 argv
[idx_number
]->arg
);
9634 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
9638 ALIAS(no_ip_pim_bfd
, no_ip_pim_bfd_param_cmd
,
9639 "no ip pim bfd (2-255) (1-65535) (1-65535)",
9643 "Enables BFD support\n"
9644 "Detect Multiplier\n"
9645 "Required min receive interval\n"
9646 "Desired min transmit interval\n")
9647 #endif /* !HAVE_BFDD */
9649 DEFPY(ip_msdp_peer
, ip_msdp_peer_cmd
,
9650 "ip msdp peer A.B.C.D$peer source A.B.C.D$source",
9653 "Configure MSDP peer\n"
9655 "Source address for TCP connection\n"
9656 "Local IP address\n")
9658 const char *vrfname
;
9659 char temp_xpath
[XPATH_MAXLEN
];
9660 char msdp_peer_source_xpath
[XPATH_MAXLEN
];
9662 vrfname
= pim_cli_get_vrf_name(vty
);
9663 if (vrfname
== NULL
)
9664 return CMD_WARNING_CONFIG_FAILED
;
9666 snprintf(msdp_peer_source_xpath
, sizeof(msdp_peer_source_xpath
),
9667 FRR_PIM_AF_XPATH
, "frr-pim:pimd", "pim", vrfname
,
9668 "frr-routing:ipv4");
9669 snprintf(temp_xpath
, sizeof(temp_xpath
),
9670 "/msdp-peer[peer-ip='%s']/source-ip", peer_str
);
9671 strlcat(msdp_peer_source_xpath
, temp_xpath
,
9672 sizeof(msdp_peer_source_xpath
));
9674 nb_cli_enqueue_change(vty
, msdp_peer_source_xpath
, NB_OP_MODIFY
,
9677 return nb_cli_apply_changes(vty
, NULL
);
9680 DEFPY(ip_msdp_timers
, ip_msdp_timers_cmd
,
9681 "ip msdp timers (1-65535)$keepalive (1-65535)$holdtime [(1-65535)$connretry]",
9684 "MSDP timers configuration\n"
9685 "Keep alive period (in seconds)\n"
9686 "Hold time period (in seconds)\n"
9687 "Connection retry period (in seconds)\n")
9689 const char *vrfname
;
9690 char xpath
[XPATH_MAXLEN
];
9692 vrfname
= pim_cli_get_vrf_name(vty
);
9693 if (vrfname
== NULL
)
9694 return CMD_WARNING_CONFIG_FAILED
;
9696 snprintf(xpath
, sizeof(xpath
), FRR_PIM_MSDP_XPATH
, "frr-pim:pimd",
9697 "pim", vrfname
, "frr-routing:ipv4");
9698 nb_cli_enqueue_change(vty
, "./hold-time", NB_OP_MODIFY
, holdtime_str
);
9699 nb_cli_enqueue_change(vty
, "./keep-alive", NB_OP_MODIFY
, keepalive_str
);
9701 nb_cli_enqueue_change(vty
, "./connection-retry", NB_OP_MODIFY
,
9704 nb_cli_enqueue_change(vty
, "./connection-retry", NB_OP_DESTROY
,
9707 nb_cli_apply_changes(vty
, xpath
);
9712 DEFPY(no_ip_msdp_timers
, no_ip_msdp_timers_cmd
,
9713 "no ip msdp timers [(1-65535) (1-65535) [(1-65535)]]",
9717 "MSDP timers configuration\n"
9722 const char *vrfname
;
9723 char xpath
[XPATH_MAXLEN
];
9725 vrfname
= pim_cli_get_vrf_name(vty
);
9726 if (vrfname
== NULL
)
9727 return CMD_WARNING_CONFIG_FAILED
;
9729 snprintf(xpath
, sizeof(xpath
), FRR_PIM_MSDP_XPATH
, "frr-pim:pimd",
9730 "pim", vrfname
, "frr-routing:ipv4");
9732 nb_cli_enqueue_change(vty
, "./hold-time", NB_OP_DESTROY
, NULL
);
9733 nb_cli_enqueue_change(vty
, "./keep-alive", NB_OP_DESTROY
, NULL
);
9734 nb_cli_enqueue_change(vty
, "./connection-retry", NB_OP_DESTROY
, NULL
);
9736 nb_cli_apply_changes(vty
, xpath
);
9741 DEFUN (no_ip_msdp_peer
,
9742 no_ip_msdp_peer_cmd
,
9743 "no ip msdp peer A.B.C.D",
9747 "Delete MSDP peer\n"
9748 "peer ip address\n")
9750 const char *vrfname
;
9751 char msdp_peer_xpath
[XPATH_MAXLEN
];
9752 char temp_xpath
[XPATH_MAXLEN
];
9754 vrfname
= pim_cli_get_vrf_name(vty
);
9755 if (vrfname
== NULL
)
9756 return CMD_WARNING_CONFIG_FAILED
;
9758 snprintf(msdp_peer_xpath
, sizeof(msdp_peer_xpath
),
9760 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4");
9761 snprintf(temp_xpath
, sizeof(temp_xpath
),
9762 "/msdp-peer[peer-ip='%s']",
9765 strlcat(msdp_peer_xpath
, temp_xpath
, sizeof(msdp_peer_xpath
));
9767 nb_cli_enqueue_change(vty
, msdp_peer_xpath
, NB_OP_DESTROY
, NULL
);
9769 return nb_cli_apply_changes(vty
, NULL
);
9772 DEFPY(ip_msdp_mesh_group_member
,
9773 ip_msdp_mesh_group_member_cmd
,
9774 "ip msdp mesh-group WORD$gname member A.B.C.D$maddr",
9777 "Configure MSDP mesh-group\n"
9779 "Mesh group member\n"
9780 "Peer IP address\n")
9782 const char *vrfname
;
9783 char xpath_value
[XPATH_MAXLEN
];
9785 vrfname
= pim_cli_get_vrf_name(vty
);
9786 if (vrfname
== NULL
)
9787 return CMD_WARNING_CONFIG_FAILED
;
9789 /* Create mesh group. */
9790 snprintf(xpath_value
, sizeof(xpath_value
),
9791 FRR_PIM_AF_XPATH
"/msdp-mesh-groups[name='%s']",
9792 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4", gname
);
9793 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_CREATE
, NULL
);
9795 /* Create mesh group member. */
9796 strlcat(xpath_value
, "/members[address='", sizeof(xpath_value
));
9797 strlcat(xpath_value
, maddr_str
, sizeof(xpath_value
));
9798 strlcat(xpath_value
, "']", sizeof(xpath_value
));
9799 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_CREATE
, NULL
);
9801 return nb_cli_apply_changes(vty
, NULL
);
9804 DEFPY(no_ip_msdp_mesh_group_member
,
9805 no_ip_msdp_mesh_group_member_cmd
,
9806 "no ip msdp mesh-group WORD$gname member A.B.C.D$maddr",
9810 "Delete MSDP mesh-group member\n"
9812 "Mesh group member\n"
9813 "Peer IP address\n")
9815 const char *vrfname
;
9816 char xpath_value
[XPATH_MAXLEN
];
9817 char xpath_member_value
[XPATH_MAXLEN
];
9819 vrfname
= pim_cli_get_vrf_name(vty
);
9820 if (vrfname
== NULL
)
9821 return CMD_WARNING_CONFIG_FAILED
;
9823 /* Get mesh group base XPath. */
9824 snprintf(xpath_value
, sizeof(xpath_value
),
9825 FRR_PIM_AF_XPATH
"/msdp-mesh-groups[name='%s']",
9826 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4", gname
);
9828 if (!yang_dnode_exists(vty
->candidate_config
->dnode
, xpath_value
)) {
9829 vty_out(vty
, "%% mesh-group does not exist\n");
9830 return CMD_WARNING_CONFIG_FAILED
;
9833 /* Remove mesh group member. */
9834 strlcpy(xpath_member_value
, xpath_value
, sizeof(xpath_member_value
));
9835 strlcat(xpath_member_value
, "/members[address='",
9836 sizeof(xpath_member_value
));
9837 strlcat(xpath_member_value
, maddr_str
, sizeof(xpath_member_value
));
9838 strlcat(xpath_member_value
, "']", sizeof(xpath_member_value
));
9839 if (!yang_dnode_exists(vty
->candidate_config
->dnode
,
9840 xpath_member_value
)) {
9841 vty_out(vty
, "%% mesh-group member does not exist\n");
9842 return CMD_WARNING_CONFIG_FAILED
;
9845 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_DESTROY
, NULL
);
9848 * If this is the last member, then we must remove the group altogether
9849 * to not break legacy CLI behaviour.
9851 pim_cli_legacy_mesh_group_behavior(vty
, gname
);
9853 return nb_cli_apply_changes(vty
, NULL
);
9856 DEFPY(ip_msdp_mesh_group_source
,
9857 ip_msdp_mesh_group_source_cmd
,
9858 "ip msdp mesh-group WORD$gname source A.B.C.D$saddr",
9861 "Configure MSDP mesh-group\n"
9863 "Mesh group local address\n"
9864 "Source IP address for the TCP connection\n")
9866 const char *vrfname
;
9867 char xpath_value
[XPATH_MAXLEN
];
9869 vrfname
= pim_cli_get_vrf_name(vty
);
9870 if (vrfname
== NULL
)
9871 return CMD_WARNING_CONFIG_FAILED
;
9873 /* Create mesh group. */
9874 snprintf(xpath_value
, sizeof(xpath_value
),
9875 FRR_PIM_AF_XPATH
"/msdp-mesh-groups[name='%s']",
9876 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4", gname
);
9877 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_CREATE
, NULL
);
9879 /* Create mesh group member. */
9880 strlcat(xpath_value
, "/source", sizeof(xpath_value
));
9881 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_MODIFY
, saddr_str
);
9883 return nb_cli_apply_changes(vty
, NULL
);
9886 DEFPY(no_ip_msdp_mesh_group_source
,
9887 no_ip_msdp_mesh_group_source_cmd
,
9888 "no ip msdp mesh-group WORD$gname source [A.B.C.D]",
9892 "Delete MSDP mesh-group source\n"
9894 "Mesh group source\n"
9895 "Mesh group local address\n")
9897 const char *vrfname
;
9898 char xpath_value
[XPATH_MAXLEN
];
9900 vrfname
= pim_cli_get_vrf_name(vty
);
9901 if (vrfname
== NULL
)
9902 return CMD_WARNING_CONFIG_FAILED
;
9904 /* Get mesh group base XPath. */
9905 snprintf(xpath_value
, sizeof(xpath_value
),
9906 FRR_PIM_AF_XPATH
"/msdp-mesh-groups[name='%s']",
9907 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4", gname
);
9908 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_CREATE
, NULL
);
9910 /* Create mesh group member. */
9911 strlcat(xpath_value
, "/source", sizeof(xpath_value
));
9912 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_DESTROY
, NULL
);
9915 * If this is the last member, then we must remove the group altogether
9916 * to not break legacy CLI behaviour.
9918 pim_cli_legacy_mesh_group_behavior(vty
, gname
);
9920 return nb_cli_apply_changes(vty
, NULL
);
9923 DEFPY(no_ip_msdp_mesh_group
,
9924 no_ip_msdp_mesh_group_cmd
,
9925 "no ip msdp mesh-group WORD$gname",
9929 "Delete MSDP mesh-group\n"
9932 const char *vrfname
;
9933 char xpath_value
[XPATH_MAXLEN
];
9935 vrfname
= pim_cli_get_vrf_name(vty
);
9936 if (vrfname
== NULL
)
9937 return CMD_WARNING_CONFIG_FAILED
;
9939 /* Get mesh group base XPath. */
9940 snprintf(xpath_value
, sizeof(xpath_value
),
9941 FRR_PIM_AF_XPATH
"/msdp-mesh-groups[name='%s']",
9942 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4", gname
);
9943 if (!yang_dnode_exists(vty
->candidate_config
->dnode
, xpath_value
))
9946 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_DESTROY
, NULL
);
9947 return nb_cli_apply_changes(vty
, NULL
);
9950 static void ip_msdp_show_mesh_group(struct vty
*vty
, struct pim_msdp_mg
*mg
,
9951 struct json_object
*json
)
9953 struct listnode
*mbrnode
;
9954 struct pim_msdp_mg_mbr
*mbr
;
9955 char mbr_str
[INET_ADDRSTRLEN
];
9956 char src_str
[INET_ADDRSTRLEN
];
9957 char state_str
[PIM_MSDP_STATE_STRLEN
];
9958 enum pim_msdp_peer_state state
;
9959 json_object
*json_mg_row
= NULL
;
9960 json_object
*json_members
= NULL
;
9961 json_object
*json_row
= NULL
;
9963 pim_inet4_dump("<source?>", mg
->src_ip
, src_str
, sizeof(src_str
));
9965 /* currently there is only one mesh group but we should still
9967 * it a dict with mg-name as key */
9968 json_mg_row
= json_object_new_object();
9969 json_object_string_add(json_mg_row
, "name",
9970 mg
->mesh_group_name
);
9971 json_object_string_add(json_mg_row
, "source", src_str
);
9973 vty_out(vty
, "Mesh group : %s\n", mg
->mesh_group_name
);
9974 vty_out(vty
, " Source : %s\n", src_str
);
9975 vty_out(vty
, " Member State\n");
9978 for (ALL_LIST_ELEMENTS_RO(mg
->mbr_list
, mbrnode
, mbr
)) {
9979 pim_inet4_dump("<mbr?>", mbr
->mbr_ip
, mbr_str
, sizeof(mbr_str
));
9981 state
= mbr
->mp
->state
;
9983 state
= PIM_MSDP_DISABLED
;
9985 pim_msdp_state_dump(state
, state_str
, sizeof(state_str
));
9987 json_row
= json_object_new_object();
9988 json_object_string_add(json_row
, "member", mbr_str
);
9989 json_object_string_add(json_row
, "state", state_str
);
9990 if (!json_members
) {
9991 json_members
= json_object_new_object();
9992 json_object_object_add(json_mg_row
, "members",
9995 json_object_object_add(json_members
, mbr_str
, json_row
);
9997 vty_out(vty
, " %-15s %11s\n", mbr_str
, state_str
);
10002 json_object_object_add(json
, mg
->mesh_group_name
, json_mg_row
);
10005 DEFUN (show_ip_msdp_mesh_group
,
10006 show_ip_msdp_mesh_group_cmd
,
10007 "show ip msdp [vrf NAME] mesh-group [json]",
10012 "MSDP mesh-group information\n"
10015 bool uj
= use_json(argc
, argv
);
10017 struct pim_msdp_mg
*mg
;
10018 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10019 struct pim_instance
*pim
= vrf
->info
;
10020 struct json_object
*json
= NULL
;
10023 return CMD_WARNING
;
10025 /* Quick case: list is empty. */
10026 if (SLIST_EMPTY(&pim
->msdp
.mglist
)) {
10028 vty_out(vty
, "{}\n");
10030 return CMD_SUCCESS
;
10034 json
= json_object_new_object();
10036 SLIST_FOREACH (mg
, &pim
->msdp
.mglist
, mg_entry
)
10037 ip_msdp_show_mesh_group(vty
, mg
, json
);
10040 vty_out(vty
, "%s\n",
10041 json_object_to_json_string_ext(
10042 json
, JSON_C_TO_STRING_PRETTY
));
10043 json_object_free(json
);
10046 return CMD_SUCCESS
;
10049 DEFUN (show_ip_msdp_mesh_group_vrf_all
,
10050 show_ip_msdp_mesh_group_vrf_all_cmd
,
10051 "show ip msdp vrf all mesh-group [json]",
10056 "MSDP mesh-group information\n"
10059 bool uj
= use_json(argc
, argv
);
10060 struct json_object
*json
= NULL
, *vrf_json
= NULL
;
10061 struct pim_instance
*pim
;
10062 struct pim_msdp_mg
*mg
;
10066 json
= json_object_new_object();
10068 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
10070 vrf_json
= json_object_new_object();
10071 json_object_object_add(json
, vrf
->name
, vrf_json
);
10073 vty_out(vty
, "VRF: %s\n", vrf
->name
);
10076 SLIST_FOREACH (mg
, &pim
->msdp
.mglist
, mg_entry
)
10077 ip_msdp_show_mesh_group(vty
, mg
, vrf_json
);
10081 vty_out(vty
, "%s\n",
10082 json_object_to_json_string_ext(
10083 json
, JSON_C_TO_STRING_PRETTY
));
10084 json_object_free(json
);
10087 return CMD_SUCCESS
;
10090 static void ip_msdp_show_peers(struct pim_instance
*pim
, struct vty
*vty
,
10093 struct listnode
*mpnode
;
10094 struct pim_msdp_peer
*mp
;
10095 char peer_str
[INET_ADDRSTRLEN
];
10096 char local_str
[INET_ADDRSTRLEN
];
10097 char state_str
[PIM_MSDP_STATE_STRLEN
];
10098 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
10100 json_object
*json
= NULL
;
10101 json_object
*json_row
= NULL
;
10105 json
= json_object_new_object();
10108 "Peer Local State Uptime SaCnt\n");
10111 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
10112 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
10113 now
= pim_time_monotonic_sec();
10114 pim_time_uptime(timebuf
, sizeof(timebuf
),
10117 strlcpy(timebuf
, "-", sizeof(timebuf
));
10119 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
10120 pim_inet4_dump("<local?>", mp
->local
, local_str
,
10121 sizeof(local_str
));
10122 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
10124 json_row
= json_object_new_object();
10125 json_object_string_add(json_row
, "peer", peer_str
);
10126 json_object_string_add(json_row
, "local", local_str
);
10127 json_object_string_add(json_row
, "state", state_str
);
10128 json_object_string_add(json_row
, "upTime", timebuf
);
10129 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
10130 json_object_object_add(json
, peer_str
, json_row
);
10132 vty_out(vty
, "%-15s %15s %11s %8s %6d\n", peer_str
,
10133 local_str
, state_str
, timebuf
, mp
->sa_cnt
);
10138 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10139 json
, JSON_C_TO_STRING_PRETTY
));
10140 json_object_free(json
);
10144 static void ip_msdp_show_peers_detail(struct pim_instance
*pim
, struct vty
*vty
,
10145 const char *peer
, bool uj
)
10147 struct listnode
*mpnode
;
10148 struct pim_msdp_peer
*mp
;
10149 char peer_str
[INET_ADDRSTRLEN
];
10150 char local_str
[INET_ADDRSTRLEN
];
10151 char state_str
[PIM_MSDP_STATE_STRLEN
];
10152 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
10153 char katimer
[PIM_MSDP_TIMER_STRLEN
];
10154 char crtimer
[PIM_MSDP_TIMER_STRLEN
];
10155 char holdtimer
[PIM_MSDP_TIMER_STRLEN
];
10157 json_object
*json
= NULL
;
10158 json_object
*json_row
= NULL
;
10161 json
= json_object_new_object();
10164 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
10165 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
10166 if (strcmp(peer
, "detail") && strcmp(peer
, peer_str
))
10169 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
10170 now
= pim_time_monotonic_sec();
10171 pim_time_uptime(timebuf
, sizeof(timebuf
),
10174 strlcpy(timebuf
, "-", sizeof(timebuf
));
10176 pim_inet4_dump("<local?>", mp
->local
, local_str
,
10177 sizeof(local_str
));
10178 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
10179 pim_time_timer_to_hhmmss(katimer
, sizeof(katimer
),
10181 pim_time_timer_to_hhmmss(crtimer
, sizeof(crtimer
),
10183 pim_time_timer_to_hhmmss(holdtimer
, sizeof(holdtimer
),
10187 json_row
= json_object_new_object();
10188 json_object_string_add(json_row
, "peer", peer_str
);
10189 json_object_string_add(json_row
, "local", local_str
);
10190 if (mp
->flags
& PIM_MSDP_PEERF_IN_GROUP
)
10191 json_object_string_add(json_row
,
10193 mp
->mesh_group_name
);
10194 json_object_string_add(json_row
, "state", state_str
);
10195 json_object_string_add(json_row
, "upTime", timebuf
);
10196 json_object_string_add(json_row
, "keepAliveTimer",
10198 json_object_string_add(json_row
, "connRetryTimer",
10200 json_object_string_add(json_row
, "holdTimer",
10202 json_object_string_add(json_row
, "lastReset",
10204 json_object_int_add(json_row
, "connAttempts",
10205 mp
->conn_attempts
);
10206 json_object_int_add(json_row
, "establishedChanges",
10208 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
10209 json_object_int_add(json_row
, "kaSent", mp
->ka_tx_cnt
);
10210 json_object_int_add(json_row
, "kaRcvd", mp
->ka_rx_cnt
);
10211 json_object_int_add(json_row
, "saSent", mp
->sa_tx_cnt
);
10212 json_object_int_add(json_row
, "saRcvd", mp
->sa_rx_cnt
);
10213 json_object_object_add(json
, peer_str
, json_row
);
10215 vty_out(vty
, "Peer : %s\n", peer_str
);
10216 vty_out(vty
, " Local : %s\n", local_str
);
10217 if (mp
->flags
& PIM_MSDP_PEERF_IN_GROUP
)
10218 vty_out(vty
, " Mesh Group : %s\n",
10219 mp
->mesh_group_name
);
10220 vty_out(vty
, " State : %s\n", state_str
);
10221 vty_out(vty
, " Uptime : %s\n", timebuf
);
10223 vty_out(vty
, " Keepalive Timer : %s\n", katimer
);
10224 vty_out(vty
, " Conn Retry Timer : %s\n", crtimer
);
10225 vty_out(vty
, " Hold Timer : %s\n", holdtimer
);
10226 vty_out(vty
, " Last Reset : %s\n",
10228 vty_out(vty
, " Conn Attempts : %d\n",
10229 mp
->conn_attempts
);
10230 vty_out(vty
, " Established Changes : %d\n",
10232 vty_out(vty
, " SA Count : %d\n",
10234 vty_out(vty
, " Statistics :\n");
10237 vty_out(vty
, " Keepalives : %10d %10d\n",
10238 mp
->ka_tx_cnt
, mp
->ka_rx_cnt
);
10239 vty_out(vty
, " SAs : %10d %10d\n",
10240 mp
->sa_tx_cnt
, mp
->sa_rx_cnt
);
10241 vty_out(vty
, "\n");
10246 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10247 json
, JSON_C_TO_STRING_PRETTY
));
10248 json_object_free(json
);
10252 DEFUN (show_ip_msdp_peer_detail
,
10253 show_ip_msdp_peer_detail_cmd
,
10254 "show ip msdp [vrf NAME] peer [detail|A.B.C.D] [json]",
10259 "MSDP peer information\n"
10260 "Detailed output\n"
10261 "peer ip address\n"
10264 bool uj
= use_json(argc
, argv
);
10266 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10269 return CMD_WARNING
;
10273 if (argv_find(argv
, argc
, "detail", &idx
))
10274 arg
= argv
[idx
]->text
;
10275 else if (argv_find(argv
, argc
, "A.B.C.D", &idx
))
10276 arg
= argv
[idx
]->arg
;
10279 ip_msdp_show_peers_detail(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
10281 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
10283 return CMD_SUCCESS
;
10286 DEFUN (show_ip_msdp_peer_detail_vrf_all
,
10287 show_ip_msdp_peer_detail_vrf_all_cmd
,
10288 "show ip msdp vrf all peer [detail|A.B.C.D] [json]",
10293 "MSDP peer information\n"
10294 "Detailed output\n"
10295 "peer ip address\n"
10299 bool uj
= use_json(argc
, argv
);
10304 vty_out(vty
, "{ ");
10305 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
10308 vty_out(vty
, ", ");
10309 vty_out(vty
, " \"%s\": ", vrf
->name
);
10312 vty_out(vty
, "VRF: %s\n", vrf
->name
);
10313 if (argv_find(argv
, argc
, "detail", &idx
)
10314 || argv_find(argv
, argc
, "A.B.C.D", &idx
))
10315 ip_msdp_show_peers_detail(vrf
->info
, vty
,
10316 argv
[idx
]->arg
, uj
);
10318 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
10321 vty_out(vty
, "}\n");
10323 return CMD_SUCCESS
;
10326 static void ip_msdp_show_sa(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
10328 struct listnode
*sanode
;
10329 struct pim_msdp_sa
*sa
;
10330 char src_str
[INET_ADDRSTRLEN
];
10331 char grp_str
[INET_ADDRSTRLEN
];
10332 char rp_str
[INET_ADDRSTRLEN
];
10333 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
10337 json_object
*json
= NULL
;
10338 json_object
*json_group
= NULL
;
10339 json_object
*json_row
= NULL
;
10342 json
= json_object_new_object();
10345 "Source Group RP Local SPT Uptime\n");
10348 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
10349 now
= pim_time_monotonic_sec();
10350 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
10351 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
10352 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
10353 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
10354 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
10356 strlcpy(spt_str
, "yes", sizeof(spt_str
));
10358 strlcpy(spt_str
, "no", sizeof(spt_str
));
10361 strlcpy(rp_str
, "-", sizeof(rp_str
));
10362 strlcpy(spt_str
, "-", sizeof(spt_str
));
10364 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
10365 strlcpy(local_str
, "yes", sizeof(local_str
));
10367 strlcpy(local_str
, "no", sizeof(local_str
));
10370 json_object_object_get_ex(json
, grp_str
, &json_group
);
10373 json_group
= json_object_new_object();
10374 json_object_object_add(json
, grp_str
,
10378 json_row
= json_object_new_object();
10379 json_object_string_add(json_row
, "source", src_str
);
10380 json_object_string_add(json_row
, "group", grp_str
);
10381 json_object_string_add(json_row
, "rp", rp_str
);
10382 json_object_string_add(json_row
, "local", local_str
);
10383 json_object_string_add(json_row
, "sptSetup", spt_str
);
10384 json_object_string_add(json_row
, "upTime", timebuf
);
10385 json_object_object_add(json_group
, src_str
, json_row
);
10387 vty_out(vty
, "%-15s %15s %15s %5c %3c %8s\n",
10388 src_str
, grp_str
, rp_str
, local_str
[0],
10389 spt_str
[0], timebuf
);
10394 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10395 json
, JSON_C_TO_STRING_PRETTY
));
10396 json_object_free(json
);
10400 static void ip_msdp_show_sa_entry_detail(struct pim_msdp_sa
*sa
,
10401 const char *src_str
,
10402 const char *grp_str
, struct vty
*vty
,
10403 bool uj
, json_object
*json
)
10405 char rp_str
[INET_ADDRSTRLEN
];
10406 char peer_str
[INET_ADDRSTRLEN
];
10407 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
10410 char statetimer
[PIM_MSDP_TIMER_STRLEN
];
10412 json_object
*json_group
= NULL
;
10413 json_object
*json_row
= NULL
;
10415 now
= pim_time_monotonic_sec();
10416 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
10417 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
10418 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
10419 pim_inet4_dump("<peer?>", sa
->peer
, peer_str
, sizeof(peer_str
));
10421 strlcpy(spt_str
, "yes", sizeof(spt_str
));
10423 strlcpy(spt_str
, "no", sizeof(spt_str
));
10426 strlcpy(rp_str
, "-", sizeof(rp_str
));
10427 strlcpy(peer_str
, "-", sizeof(peer_str
));
10428 strlcpy(spt_str
, "-", sizeof(spt_str
));
10430 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
10431 strlcpy(local_str
, "yes", sizeof(local_str
));
10433 strlcpy(local_str
, "no", sizeof(local_str
));
10435 pim_time_timer_to_hhmmss(statetimer
, sizeof(statetimer
),
10436 sa
->sa_state_timer
);
10438 json_object_object_get_ex(json
, grp_str
, &json_group
);
10441 json_group
= json_object_new_object();
10442 json_object_object_add(json
, grp_str
, json_group
);
10445 json_row
= json_object_new_object();
10446 json_object_string_add(json_row
, "source", src_str
);
10447 json_object_string_add(json_row
, "group", grp_str
);
10448 json_object_string_add(json_row
, "rp", rp_str
);
10449 json_object_string_add(json_row
, "local", local_str
);
10450 json_object_string_add(json_row
, "sptSetup", spt_str
);
10451 json_object_string_add(json_row
, "upTime", timebuf
);
10452 json_object_string_add(json_row
, "stateTimer", statetimer
);
10453 json_object_object_add(json_group
, src_str
, json_row
);
10455 vty_out(vty
, "SA : %s\n", sa
->sg_str
);
10456 vty_out(vty
, " RP : %s\n", rp_str
);
10457 vty_out(vty
, " Peer : %s\n", peer_str
);
10458 vty_out(vty
, " Local : %s\n", local_str
);
10459 vty_out(vty
, " SPT Setup : %s\n", spt_str
);
10460 vty_out(vty
, " Uptime : %s\n", timebuf
);
10461 vty_out(vty
, " State Timer : %s\n", statetimer
);
10462 vty_out(vty
, "\n");
10466 static void ip_msdp_show_sa_detail(struct pim_instance
*pim
, struct vty
*vty
,
10469 struct listnode
*sanode
;
10470 struct pim_msdp_sa
*sa
;
10471 char src_str
[INET_ADDRSTRLEN
];
10472 char grp_str
[INET_ADDRSTRLEN
];
10473 json_object
*json
= NULL
;
10476 json
= json_object_new_object();
10479 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
10480 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
10481 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
10482 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
, uj
,
10487 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10488 json
, JSON_C_TO_STRING_PRETTY
));
10489 json_object_free(json
);
10493 DEFUN (show_ip_msdp_sa_detail
,
10494 show_ip_msdp_sa_detail_cmd
,
10495 "show ip msdp [vrf NAME] sa detail [json]",
10500 "MSDP active-source information\n"
10501 "Detailed output\n"
10504 bool uj
= use_json(argc
, argv
);
10506 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10509 return CMD_WARNING
;
10511 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
10513 return CMD_SUCCESS
;
10516 DEFUN (show_ip_msdp_sa_detail_vrf_all
,
10517 show_ip_msdp_sa_detail_vrf_all_cmd
,
10518 "show ip msdp vrf all sa detail [json]",
10523 "MSDP active-source information\n"
10524 "Detailed output\n"
10527 bool uj
= use_json(argc
, argv
);
10532 vty_out(vty
, "{ ");
10533 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
10536 vty_out(vty
, ", ");
10537 vty_out(vty
, " \"%s\": ", vrf
->name
);
10540 vty_out(vty
, "VRF: %s\n", vrf
->name
);
10541 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
10544 vty_out(vty
, "}\n");
10546 return CMD_SUCCESS
;
10549 static void ip_msdp_show_sa_addr(struct pim_instance
*pim
, struct vty
*vty
,
10550 const char *addr
, bool uj
)
10552 struct listnode
*sanode
;
10553 struct pim_msdp_sa
*sa
;
10554 char src_str
[INET_ADDRSTRLEN
];
10555 char grp_str
[INET_ADDRSTRLEN
];
10556 json_object
*json
= NULL
;
10559 json
= json_object_new_object();
10562 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
10563 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
10564 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
10565 if (!strcmp(addr
, src_str
) || !strcmp(addr
, grp_str
)) {
10566 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
10572 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10573 json
, JSON_C_TO_STRING_PRETTY
));
10574 json_object_free(json
);
10578 static void ip_msdp_show_sa_sg(struct pim_instance
*pim
, struct vty
*vty
,
10579 const char *src
, const char *grp
, bool uj
)
10581 struct listnode
*sanode
;
10582 struct pim_msdp_sa
*sa
;
10583 char src_str
[INET_ADDRSTRLEN
];
10584 char grp_str
[INET_ADDRSTRLEN
];
10585 json_object
*json
= NULL
;
10588 json
= json_object_new_object();
10591 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
10592 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
10593 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
10594 if (!strcmp(src
, src_str
) && !strcmp(grp
, grp_str
)) {
10595 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
10601 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10602 json
, JSON_C_TO_STRING_PRETTY
));
10603 json_object_free(json
);
10607 DEFUN (show_ip_msdp_sa_sg
,
10608 show_ip_msdp_sa_sg_cmd
,
10609 "show ip msdp [vrf NAME] sa [A.B.C.D [A.B.C.D]] [json]",
10614 "MSDP active-source information\n"
10615 "source or group ip\n"
10619 bool uj
= use_json(argc
, argv
);
10623 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10626 return CMD_WARNING
;
10628 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
10630 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
10634 if (src_ip
&& grp_ip
)
10635 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
10637 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
10639 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
10641 return CMD_SUCCESS
;
10644 DEFUN (show_ip_msdp_sa_sg_vrf_all
,
10645 show_ip_msdp_sa_sg_vrf_all_cmd
,
10646 "show ip msdp vrf all sa [A.B.C.D [A.B.C.D]] [json]",
10651 "MSDP active-source information\n"
10652 "source or group ip\n"
10656 bool uj
= use_json(argc
, argv
);
10661 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
10663 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
10668 vty_out(vty
, "{ ");
10669 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
10672 vty_out(vty
, ", ");
10673 vty_out(vty
, " \"%s\": ", vrf
->name
);
10676 vty_out(vty
, "VRF: %s\n", vrf
->name
);
10678 if (src_ip
&& grp_ip
)
10679 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
10681 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
10683 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
10686 vty_out(vty
, "}\n");
10688 return CMD_SUCCESS
;
10691 struct pim_sg_cache_walk_data
{
10694 json_object
*json_group
;
10695 struct in_addr addr
;
10699 static void pim_show_vxlan_sg_entry(struct pim_vxlan_sg
*vxlan_sg
,
10700 struct pim_sg_cache_walk_data
*cwd
)
10702 struct vty
*vty
= cwd
->vty
;
10703 json_object
*json
= cwd
->json
;
10704 char src_str
[INET_ADDRSTRLEN
];
10705 char grp_str
[INET_ADDRSTRLEN
];
10706 json_object
*json_row
;
10707 bool installed
= (vxlan_sg
->up
) ? true : false;
10708 const char *iif_name
= vxlan_sg
->iif
?vxlan_sg
->iif
->name
:"-";
10709 const char *oif_name
;
10711 if (pim_vxlan_is_orig_mroute(vxlan_sg
))
10712 oif_name
= vxlan_sg
->orig_oif
?vxlan_sg
->orig_oif
->name
:"";
10714 oif_name
= vxlan_sg
->term_oif
?vxlan_sg
->term_oif
->name
:"";
10716 if (cwd
->addr_match
&& (vxlan_sg
->sg
.src
.s_addr
!= cwd
->addr
.s_addr
) &&
10717 (vxlan_sg
->sg
.grp
.s_addr
!= cwd
->addr
.s_addr
)) {
10720 pim_inet4_dump("<src?>", vxlan_sg
->sg
.src
, src_str
, sizeof(src_str
));
10721 pim_inet4_dump("<grp?>", vxlan_sg
->sg
.grp
, grp_str
, sizeof(grp_str
));
10723 json_object_object_get_ex(json
, grp_str
, &cwd
->json_group
);
10725 if (!cwd
->json_group
) {
10726 cwd
->json_group
= json_object_new_object();
10727 json_object_object_add(json
, grp_str
,
10731 json_row
= json_object_new_object();
10732 json_object_string_add(json_row
, "source", src_str
);
10733 json_object_string_add(json_row
, "group", grp_str
);
10734 json_object_string_add(json_row
, "input", iif_name
);
10735 json_object_string_add(json_row
, "output", oif_name
);
10737 json_object_boolean_true_add(json_row
, "installed");
10739 json_object_boolean_false_add(json_row
, "installed");
10740 json_object_object_add(cwd
->json_group
, src_str
, json_row
);
10742 vty_out(vty
, "%-15s %-15s %-15s %-15s %-5s\n",
10743 src_str
, grp_str
, iif_name
, oif_name
,
10748 static void pim_show_vxlan_sg_hash_entry(struct hash_bucket
*bucket
, void *arg
)
10750 pim_show_vxlan_sg_entry((struct pim_vxlan_sg
*)bucket
->data
,
10751 (struct pim_sg_cache_walk_data
*)arg
);
10754 static void pim_show_vxlan_sg(struct pim_instance
*pim
,
10755 struct vty
*vty
, bool uj
)
10757 json_object
*json
= NULL
;
10758 struct pim_sg_cache_walk_data cwd
;
10761 json
= json_object_new_object();
10763 vty_out(vty
, "Codes: I -> installed\n");
10765 "Source Group Input Output Flags\n");
10768 memset(&cwd
, 0, sizeof(cwd
));
10771 hash_iterate(pim
->vxlan
.sg_hash
, pim_show_vxlan_sg_hash_entry
, &cwd
);
10774 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10775 json
, JSON_C_TO_STRING_PRETTY
));
10776 json_object_free(json
);
10780 static void pim_show_vxlan_sg_match_addr(struct pim_instance
*pim
,
10781 struct vty
*vty
, char *addr_str
,
10784 json_object
*json
= NULL
;
10785 struct pim_sg_cache_walk_data cwd
;
10788 memset(&cwd
, 0, sizeof(cwd
));
10789 result
= inet_pton(AF_INET
, addr_str
, &cwd
.addr
);
10791 vty_out(vty
, "Bad address %s: errno=%d: %s\n", addr_str
,
10792 errno
, safe_strerror(errno
));
10797 json
= json_object_new_object();
10799 vty_out(vty
, "Codes: I -> installed\n");
10801 "Source Group Input Output Flags\n");
10806 cwd
.addr_match
= true;
10807 hash_iterate(pim
->vxlan
.sg_hash
, pim_show_vxlan_sg_hash_entry
, &cwd
);
10810 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10811 json
, JSON_C_TO_STRING_PRETTY
));
10812 json_object_free(json
);
10816 static void pim_show_vxlan_sg_one(struct pim_instance
*pim
,
10817 struct vty
*vty
, char *src_str
, char *grp_str
,
10820 json_object
*json
= NULL
;
10821 struct prefix_sg sg
;
10823 struct pim_vxlan_sg
*vxlan_sg
;
10824 const char *iif_name
;
10826 const char *oif_name
;
10828 result
= inet_pton(AF_INET
, src_str
, &sg
.src
);
10830 vty_out(vty
, "Bad src address %s: errno=%d: %s\n", src_str
,
10831 errno
, safe_strerror(errno
));
10834 result
= inet_pton(AF_INET
, grp_str
, &sg
.grp
);
10836 vty_out(vty
, "Bad grp address %s: errno=%d: %s\n", grp_str
,
10837 errno
, safe_strerror(errno
));
10841 sg
.family
= AF_INET
;
10842 sg
.prefixlen
= IPV4_MAX_BITLEN
;
10844 json
= json_object_new_object();
10846 vxlan_sg
= pim_vxlan_sg_find(pim
, &sg
);
10848 installed
= (vxlan_sg
->up
) ? true : false;
10849 iif_name
= vxlan_sg
->iif
?vxlan_sg
->iif
->name
:"-";
10851 if (pim_vxlan_is_orig_mroute(vxlan_sg
))
10853 vxlan_sg
->orig_oif
?vxlan_sg
->orig_oif
->name
:"";
10856 vxlan_sg
->term_oif
?vxlan_sg
->term_oif
->name
:"";
10859 json_object_string_add(json
, "source", src_str
);
10860 json_object_string_add(json
, "group", grp_str
);
10861 json_object_string_add(json
, "input", iif_name
);
10862 json_object_string_add(json
, "output", oif_name
);
10864 json_object_boolean_true_add(json
, "installed");
10866 json_object_boolean_false_add(json
,
10869 vty_out(vty
, "SG : %s\n", vxlan_sg
->sg_str
);
10870 vty_out(vty
, " Input : %s\n", iif_name
);
10871 vty_out(vty
, " Output : %s\n", oif_name
);
10872 vty_out(vty
, " installed : %s\n",
10873 installed
?"yes":"no");
10878 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10879 json
, JSON_C_TO_STRING_PRETTY
));
10880 json_object_free(json
);
10884 DEFUN (show_ip_pim_vxlan_sg
,
10885 show_ip_pim_vxlan_sg_cmd
,
10886 "show ip pim [vrf NAME] vxlan-groups [A.B.C.D [A.B.C.D]] [json]",
10891 "VxLAN BUM groups\n"
10892 "source or group ip\n"
10896 bool uj
= use_json(argc
, argv
);
10900 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10903 return CMD_WARNING
;
10905 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ?
10906 argv
[idx
++]->arg
:NULL
;
10907 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
) ?
10908 argv
[idx
]->arg
:NULL
;
10910 if (src_ip
&& grp_ip
)
10911 pim_show_vxlan_sg_one(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
10913 pim_show_vxlan_sg_match_addr(vrf
->info
, vty
, src_ip
, uj
);
10915 pim_show_vxlan_sg(vrf
->info
, vty
, uj
);
10917 return CMD_SUCCESS
;
10920 static void pim_show_vxlan_sg_work(struct pim_instance
*pim
,
10921 struct vty
*vty
, bool uj
)
10923 json_object
*json
= NULL
;
10924 struct pim_sg_cache_walk_data cwd
;
10925 struct listnode
*node
;
10926 struct pim_vxlan_sg
*vxlan_sg
;
10929 json
= json_object_new_object();
10931 vty_out(vty
, "Codes: I -> installed\n");
10933 "Source Group Input Flags\n");
10936 memset(&cwd
, 0, sizeof(cwd
));
10939 for (ALL_LIST_ELEMENTS_RO(pim_vxlan_p
->work_list
, node
, vxlan_sg
))
10940 pim_show_vxlan_sg_entry(vxlan_sg
, &cwd
);
10943 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10944 json
, JSON_C_TO_STRING_PRETTY
));
10945 json_object_free(json
);
10949 DEFUN_HIDDEN (show_ip_pim_vxlan_sg_work
,
10950 show_ip_pim_vxlan_sg_work_cmd
,
10951 "show ip pim [vrf NAME] vxlan-work [json]",
10956 "VxLAN work list\n"
10959 bool uj
= use_json(argc
, argv
);
10963 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10966 return CMD_WARNING
;
10968 pim_show_vxlan_sg_work(vrf
->info
, vty
, uj
);
10970 return CMD_SUCCESS
;
10973 DEFUN_HIDDEN (no_ip_pim_mlag
,
10974 no_ip_pim_mlag_cmd
,
10981 char mlag_xpath
[XPATH_MAXLEN
];
10983 snprintf(mlag_xpath
, sizeof(mlag_xpath
), FRR_PIM_AF_XPATH
,
10984 "frr-pim:pimd", "pim", "default", "frr-routing:ipv4");
10985 strlcat(mlag_xpath
, "/mlag", sizeof(mlag_xpath
));
10987 nb_cli_enqueue_change(vty
, mlag_xpath
, NB_OP_DESTROY
, NULL
);
10990 return nb_cli_apply_changes(vty
, NULL
);
10993 DEFUN_HIDDEN (ip_pim_mlag
,
10995 "ip pim mlag INTERFACE role [primary|secondary] state [up|down] addr A.B.C.D",
10999 "peerlink sub interface\n"
11001 "MLAG role primary\n"
11002 "MLAG role secondary\n"
11003 "peer session state\n"
11004 "peer session state up\n"
11005 "peer session state down\n"
11007 "unique ip address\n")
11010 char mlag_peerlink_rif_xpath
[XPATH_MAXLEN
];
11011 char mlag_my_role_xpath
[XPATH_MAXLEN
];
11012 char mlag_peer_state_xpath
[XPATH_MAXLEN
];
11013 char mlag_reg_address_xpath
[XPATH_MAXLEN
];
11015 snprintf(mlag_peerlink_rif_xpath
, sizeof(mlag_peerlink_rif_xpath
),
11017 "frr-pim:pimd", "pim", "default", "frr-routing:ipv4");
11018 strlcat(mlag_peerlink_rif_xpath
, "/mlag/peerlink-rif",
11019 sizeof(mlag_peerlink_rif_xpath
));
11022 nb_cli_enqueue_change(vty
, mlag_peerlink_rif_xpath
, NB_OP_MODIFY
,
11025 snprintf(mlag_my_role_xpath
, sizeof(mlag_my_role_xpath
),
11027 "frr-pim:pimd", "pim", "default", "frr-routing:ipv4");
11028 strlcat(mlag_my_role_xpath
, "/mlag/my-role",
11029 sizeof(mlag_my_role_xpath
));
11032 if (!strcmp(argv
[idx
]->arg
, "primary")) {
11033 nb_cli_enqueue_change(vty
, mlag_my_role_xpath
, NB_OP_MODIFY
,
11034 "MLAG_ROLE_PRIMARY");
11036 } else if (!strcmp(argv
[idx
]->arg
, "secondary")) {
11037 nb_cli_enqueue_change(vty
, mlag_my_role_xpath
, NB_OP_MODIFY
,
11038 "MLAG_ROLE_SECONDARY");
11041 vty_out(vty
, "unknown MLAG role %s\n", argv
[idx
]->arg
);
11042 return CMD_WARNING
;
11045 snprintf(mlag_peer_state_xpath
, sizeof(mlag_peer_state_xpath
),
11047 "frr-pim:pimd", "pim", "default", "frr-routing:ipv4");
11048 strlcat(mlag_peer_state_xpath
, "/mlag/peer-state",
11049 sizeof(mlag_peer_state_xpath
));
11052 if (!strcmp(argv
[idx
]->arg
, "up")) {
11053 nb_cli_enqueue_change(vty
, mlag_peer_state_xpath
, NB_OP_MODIFY
,
11056 } else if (strcmp(argv
[idx
]->arg
, "down")) {
11057 nb_cli_enqueue_change(vty
, mlag_peer_state_xpath
, NB_OP_MODIFY
,
11061 vty_out(vty
, "unknown MLAG state %s\n", argv
[idx
]->arg
);
11062 return CMD_WARNING
;
11065 snprintf(mlag_reg_address_xpath
, sizeof(mlag_reg_address_xpath
),
11067 "frr-pim:pimd", "pim", "default", "frr-routing:ipv4");
11068 strlcat(mlag_reg_address_xpath
, "/mlag/reg-address",
11069 sizeof(mlag_reg_address_xpath
));
11072 nb_cli_enqueue_change(vty
, mlag_reg_address_xpath
, NB_OP_MODIFY
,
11075 return nb_cli_apply_changes(vty
, NULL
);
11078 void pim_cmd_init(void)
11080 if_cmd_init(pim_interface_config_write
);
11082 install_node(&debug_node
);
11084 install_element(ENABLE_NODE
, &pim_test_sg_keepalive_cmd
);
11086 install_element(CONFIG_NODE
, &ip_pim_rp_cmd
);
11087 install_element(VRF_NODE
, &ip_pim_rp_cmd
);
11088 install_element(CONFIG_NODE
, &no_ip_pim_rp_cmd
);
11089 install_element(VRF_NODE
, &no_ip_pim_rp_cmd
);
11090 install_element(CONFIG_NODE
, &ip_pim_rp_prefix_list_cmd
);
11091 install_element(VRF_NODE
, &ip_pim_rp_prefix_list_cmd
);
11092 install_element(CONFIG_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
11093 install_element(VRF_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
11094 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
11095 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
11096 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
11097 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
11098 install_element(CONFIG_NODE
, &ip_pim_ssm_prefix_list_cmd
);
11099 install_element(VRF_NODE
, &ip_pim_ssm_prefix_list_cmd
);
11100 install_element(CONFIG_NODE
, &ip_pim_register_suppress_cmd
);
11101 install_element(CONFIG_NODE
, &no_ip_pim_register_suppress_cmd
);
11102 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
11103 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
11104 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
11105 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
11106 install_element(CONFIG_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
11107 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
11108 install_element(CONFIG_NODE
,
11109 &no_ip_pim_spt_switchover_infinity_plist_cmd
);
11110 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_plist_cmd
);
11111 install_element(CONFIG_NODE
, &pim_register_accept_list_cmd
);
11112 install_element(VRF_NODE
, &pim_register_accept_list_cmd
);
11113 install_element(CONFIG_NODE
, &ip_pim_joinprune_time_cmd
);
11114 install_element(CONFIG_NODE
, &no_ip_pim_joinprune_time_cmd
);
11115 install_element(CONFIG_NODE
, &ip_pim_keep_alive_cmd
);
11116 install_element(VRF_NODE
, &ip_pim_keep_alive_cmd
);
11117 install_element(CONFIG_NODE
, &ip_pim_rp_keep_alive_cmd
);
11118 install_element(VRF_NODE
, &ip_pim_rp_keep_alive_cmd
);
11119 install_element(CONFIG_NODE
, &no_ip_pim_keep_alive_cmd
);
11120 install_element(VRF_NODE
, &no_ip_pim_keep_alive_cmd
);
11121 install_element(CONFIG_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
11122 install_element(VRF_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
11123 install_element(CONFIG_NODE
, &ip_pim_packets_cmd
);
11124 install_element(CONFIG_NODE
, &no_ip_pim_packets_cmd
);
11125 install_element(CONFIG_NODE
, &ip_pim_v6_secondary_cmd
);
11126 install_element(VRF_NODE
, &ip_pim_v6_secondary_cmd
);
11127 install_element(CONFIG_NODE
, &no_ip_pim_v6_secondary_cmd
);
11128 install_element(VRF_NODE
, &no_ip_pim_v6_secondary_cmd
);
11129 install_element(CONFIG_NODE
, &ip_ssmpingd_cmd
);
11130 install_element(VRF_NODE
, &ip_ssmpingd_cmd
);
11131 install_element(CONFIG_NODE
, &no_ip_ssmpingd_cmd
);
11132 install_element(VRF_NODE
, &no_ip_ssmpingd_cmd
);
11133 install_element(CONFIG_NODE
, &ip_msdp_peer_cmd
);
11134 install_element(VRF_NODE
, &ip_msdp_peer_cmd
);
11135 install_element(CONFIG_NODE
, &no_ip_msdp_peer_cmd
);
11136 install_element(VRF_NODE
, &no_ip_msdp_peer_cmd
);
11137 install_element(CONFIG_NODE
, &ip_pim_ecmp_cmd
);
11138 install_element(VRF_NODE
, &ip_pim_ecmp_cmd
);
11139 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_cmd
);
11140 install_element(VRF_NODE
, &no_ip_pim_ecmp_cmd
);
11141 install_element(CONFIG_NODE
, &ip_pim_ecmp_rebalance_cmd
);
11142 install_element(VRF_NODE
, &ip_pim_ecmp_rebalance_cmd
);
11143 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
11144 install_element(VRF_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
11145 install_element(CONFIG_NODE
, &ip_pim_mlag_cmd
);
11146 install_element(CONFIG_NODE
, &no_ip_pim_mlag_cmd
);
11147 install_element(CONFIG_NODE
, &igmp_group_watermark_cmd
);
11148 install_element(VRF_NODE
, &igmp_group_watermark_cmd
);
11149 install_element(CONFIG_NODE
, &no_igmp_group_watermark_cmd
);
11150 install_element(VRF_NODE
, &no_igmp_group_watermark_cmd
);
11152 install_element(INTERFACE_NODE
, &interface_ip_igmp_cmd
);
11153 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_cmd
);
11154 install_element(INTERFACE_NODE
, &interface_ip_igmp_join_cmd
);
11155 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_join_cmd
);
11156 install_element(INTERFACE_NODE
, &interface_ip_igmp_version_cmd
);
11157 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_version_cmd
);
11158 install_element(INTERFACE_NODE
, &interface_ip_igmp_query_interval_cmd
);
11159 install_element(INTERFACE_NODE
,
11160 &interface_no_ip_igmp_query_interval_cmd
);
11161 install_element(INTERFACE_NODE
,
11162 &interface_ip_igmp_query_max_response_time_cmd
);
11163 install_element(INTERFACE_NODE
,
11164 &interface_no_ip_igmp_query_max_response_time_cmd
);
11165 install_element(INTERFACE_NODE
,
11166 &interface_ip_igmp_query_max_response_time_dsec_cmd
);
11167 install_element(INTERFACE_NODE
,
11168 &interface_no_ip_igmp_query_max_response_time_dsec_cmd
);
11169 install_element(INTERFACE_NODE
,
11170 &interface_ip_igmp_last_member_query_count_cmd
);
11171 install_element(INTERFACE_NODE
,
11172 &interface_no_ip_igmp_last_member_query_count_cmd
);
11173 install_element(INTERFACE_NODE
,
11174 &interface_ip_igmp_last_member_query_interval_cmd
);
11175 install_element(INTERFACE_NODE
,
11176 &interface_no_ip_igmp_last_member_query_interval_cmd
);
11177 install_element(INTERFACE_NODE
, &interface_ip_pim_activeactive_cmd
);
11178 install_element(INTERFACE_NODE
, &interface_ip_pim_ssm_cmd
);
11179 install_element(INTERFACE_NODE
, &interface_no_ip_pim_ssm_cmd
);
11180 install_element(INTERFACE_NODE
, &interface_ip_pim_sm_cmd
);
11181 install_element(INTERFACE_NODE
, &interface_no_ip_pim_sm_cmd
);
11182 install_element(INTERFACE_NODE
, &interface_ip_pim_cmd
);
11183 install_element(INTERFACE_NODE
, &interface_no_ip_pim_cmd
);
11184 install_element(INTERFACE_NODE
, &interface_ip_pim_drprio_cmd
);
11185 install_element(INTERFACE_NODE
, &interface_no_ip_pim_drprio_cmd
);
11186 install_element(INTERFACE_NODE
, &interface_ip_pim_hello_cmd
);
11187 install_element(INTERFACE_NODE
, &interface_no_ip_pim_hello_cmd
);
11188 install_element(INTERFACE_NODE
, &interface_ip_pim_boundary_oil_cmd
);
11189 install_element(INTERFACE_NODE
, &interface_no_ip_pim_boundary_oil_cmd
);
11190 install_element(INTERFACE_NODE
, &interface_ip_igmp_query_generate_cmd
);
11192 // Static mroutes NEB
11193 install_element(INTERFACE_NODE
, &interface_ip_mroute_cmd
);
11194 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_cmd
);
11196 install_element(VIEW_NODE
, &show_ip_igmp_interface_cmd
);
11197 install_element(VIEW_NODE
, &show_ip_igmp_interface_vrf_all_cmd
);
11198 install_element(VIEW_NODE
, &show_ip_igmp_join_cmd
);
11199 install_element(VIEW_NODE
, &show_ip_igmp_join_vrf_all_cmd
);
11200 install_element(VIEW_NODE
, &show_ip_igmp_groups_cmd
);
11201 install_element(VIEW_NODE
, &show_ip_igmp_groups_vrf_all_cmd
);
11202 install_element(VIEW_NODE
, &show_ip_igmp_groups_retransmissions_cmd
);
11203 install_element(VIEW_NODE
, &show_ip_igmp_sources_cmd
);
11204 install_element(VIEW_NODE
, &show_ip_igmp_sources_retransmissions_cmd
);
11205 install_element(VIEW_NODE
, &show_ip_igmp_statistics_cmd
);
11206 install_element(VIEW_NODE
, &show_ip_pim_assert_cmd
);
11207 install_element(VIEW_NODE
, &show_ip_pim_assert_internal_cmd
);
11208 install_element(VIEW_NODE
, &show_ip_pim_assert_metric_cmd
);
11209 install_element(VIEW_NODE
, &show_ip_pim_assert_winner_metric_cmd
);
11210 install_element(VIEW_NODE
, &show_ip_pim_interface_traffic_cmd
);
11211 install_element(VIEW_NODE
, &show_ip_pim_interface_cmd
);
11212 install_element(VIEW_NODE
, &show_ip_pim_interface_vrf_all_cmd
);
11213 install_element(VIEW_NODE
, &show_ip_pim_join_cmd
);
11214 install_element(VIEW_NODE
, &show_ip_pim_join_vrf_all_cmd
);
11215 install_element(VIEW_NODE
, &show_ip_pim_jp_agg_cmd
);
11216 install_element(VIEW_NODE
, &show_ip_pim_local_membership_cmd
);
11217 install_element(VIEW_NODE
, &show_ip_pim_mlag_summary_cmd
);
11218 install_element(VIEW_NODE
, &show_ip_pim_mlag_up_cmd
);
11219 install_element(VIEW_NODE
, &show_ip_pim_mlag_up_vrf_all_cmd
);
11220 install_element(VIEW_NODE
, &show_ip_pim_neighbor_cmd
);
11221 install_element(VIEW_NODE
, &show_ip_pim_neighbor_vrf_all_cmd
);
11222 install_element(VIEW_NODE
, &show_ip_pim_rpf_cmd
);
11223 install_element(VIEW_NODE
, &show_ip_pim_rpf_vrf_all_cmd
);
11224 install_element(VIEW_NODE
, &show_ip_pim_secondary_cmd
);
11225 install_element(VIEW_NODE
, &show_ip_pim_state_cmd
);
11226 install_element(VIEW_NODE
, &show_ip_pim_state_vrf_all_cmd
);
11227 install_element(VIEW_NODE
, &show_ip_pim_upstream_cmd
);
11228 install_element(VIEW_NODE
, &show_ip_pim_upstream_vrf_all_cmd
);
11229 install_element(VIEW_NODE
, &show_ip_pim_channel_cmd
);
11230 install_element(VIEW_NODE
, &show_ip_pim_upstream_join_desired_cmd
);
11231 install_element(VIEW_NODE
, &show_ip_pim_upstream_rpf_cmd
);
11232 install_element(VIEW_NODE
, &show_ip_pim_rp_cmd
);
11233 install_element(VIEW_NODE
, &show_ip_pim_rp_vrf_all_cmd
);
11234 install_element(VIEW_NODE
, &show_ip_pim_bsr_cmd
);
11235 install_element(VIEW_NODE
, &show_ip_multicast_cmd
);
11236 install_element(VIEW_NODE
, &show_ip_multicast_vrf_all_cmd
);
11237 install_element(VIEW_NODE
, &show_ip_multicast_count_cmd
);
11238 install_element(VIEW_NODE
, &show_ip_multicast_count_vrf_all_cmd
);
11239 install_element(VIEW_NODE
, &show_ip_mroute_cmd
);
11240 install_element(VIEW_NODE
, &show_ip_mroute_vrf_all_cmd
);
11241 install_element(VIEW_NODE
, &show_ip_mroute_count_cmd
);
11242 install_element(VIEW_NODE
, &show_ip_mroute_count_vrf_all_cmd
);
11243 install_element(VIEW_NODE
, &show_ip_mroute_summary_cmd
);
11244 install_element(VIEW_NODE
, &show_ip_mroute_summary_vrf_all_cmd
);
11245 install_element(VIEW_NODE
, &show_ip_rib_cmd
);
11246 install_element(VIEW_NODE
, &show_ip_ssmpingd_cmd
);
11247 install_element(VIEW_NODE
, &show_ip_pim_nexthop_cmd
);
11248 install_element(VIEW_NODE
, &show_ip_pim_nexthop_lookup_cmd
);
11249 install_element(VIEW_NODE
, &show_ip_pim_bsrp_cmd
);
11250 install_element(VIEW_NODE
, &show_ip_pim_bsm_db_cmd
);
11251 install_element(VIEW_NODE
, &show_ip_pim_statistics_cmd
);
11253 install_element(ENABLE_NODE
, &clear_ip_mroute_count_cmd
);
11254 install_element(ENABLE_NODE
, &clear_ip_interfaces_cmd
);
11255 install_element(ENABLE_NODE
, &clear_ip_igmp_interfaces_cmd
);
11256 install_element(ENABLE_NODE
, &clear_ip_mroute_cmd
);
11257 install_element(ENABLE_NODE
, &clear_ip_pim_interfaces_cmd
);
11258 install_element(ENABLE_NODE
, &clear_ip_pim_interface_traffic_cmd
);
11259 install_element(ENABLE_NODE
, &clear_ip_pim_oil_cmd
);
11260 install_element(ENABLE_NODE
, &clear_ip_pim_statistics_cmd
);
11261 install_element(ENABLE_NODE
, &clear_ip_pim_bsr_db_cmd
);
11263 install_element(ENABLE_NODE
, &show_debugging_pim_cmd
);
11265 install_element(ENABLE_NODE
, &debug_igmp_cmd
);
11266 install_element(ENABLE_NODE
, &no_debug_igmp_cmd
);
11267 install_element(ENABLE_NODE
, &debug_igmp_events_cmd
);
11268 install_element(ENABLE_NODE
, &no_debug_igmp_events_cmd
);
11269 install_element(ENABLE_NODE
, &debug_igmp_packets_cmd
);
11270 install_element(ENABLE_NODE
, &no_debug_igmp_packets_cmd
);
11271 install_element(ENABLE_NODE
, &debug_igmp_trace_cmd
);
11272 install_element(ENABLE_NODE
, &no_debug_igmp_trace_cmd
);
11273 install_element(ENABLE_NODE
, &debug_mroute_cmd
);
11274 install_element(ENABLE_NODE
, &debug_mroute_detail_cmd
);
11275 install_element(ENABLE_NODE
, &no_debug_mroute_cmd
);
11276 install_element(ENABLE_NODE
, &no_debug_mroute_detail_cmd
);
11277 install_element(ENABLE_NODE
, &debug_pim_static_cmd
);
11278 install_element(ENABLE_NODE
, &no_debug_pim_static_cmd
);
11279 install_element(ENABLE_NODE
, &debug_pim_cmd
);
11280 install_element(ENABLE_NODE
, &no_debug_pim_cmd
);
11281 install_element(ENABLE_NODE
, &debug_pim_nht_cmd
);
11282 install_element(ENABLE_NODE
, &no_debug_pim_nht_cmd
);
11283 install_element(ENABLE_NODE
, &debug_pim_nht_rp_cmd
);
11284 install_element(ENABLE_NODE
, &no_debug_pim_nht_rp_cmd
);
11285 install_element(ENABLE_NODE
, &debug_pim_events_cmd
);
11286 install_element(ENABLE_NODE
, &no_debug_pim_events_cmd
);
11287 install_element(ENABLE_NODE
, &debug_pim_packets_cmd
);
11288 install_element(ENABLE_NODE
, &no_debug_pim_packets_cmd
);
11289 install_element(ENABLE_NODE
, &debug_pim_packetdump_send_cmd
);
11290 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_send_cmd
);
11291 install_element(ENABLE_NODE
, &debug_pim_packetdump_recv_cmd
);
11292 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_recv_cmd
);
11293 install_element(ENABLE_NODE
, &debug_pim_trace_cmd
);
11294 install_element(ENABLE_NODE
, &no_debug_pim_trace_cmd
);
11295 install_element(ENABLE_NODE
, &debug_pim_trace_detail_cmd
);
11296 install_element(ENABLE_NODE
, &no_debug_pim_trace_detail_cmd
);
11297 install_element(ENABLE_NODE
, &debug_ssmpingd_cmd
);
11298 install_element(ENABLE_NODE
, &no_debug_ssmpingd_cmd
);
11299 install_element(ENABLE_NODE
, &debug_pim_zebra_cmd
);
11300 install_element(ENABLE_NODE
, &no_debug_pim_zebra_cmd
);
11301 install_element(ENABLE_NODE
, &debug_pim_mlag_cmd
);
11302 install_element(ENABLE_NODE
, &no_debug_pim_mlag_cmd
);
11303 install_element(ENABLE_NODE
, &debug_pim_vxlan_cmd
);
11304 install_element(ENABLE_NODE
, &no_debug_pim_vxlan_cmd
);
11305 install_element(ENABLE_NODE
, &debug_msdp_cmd
);
11306 install_element(ENABLE_NODE
, &no_debug_msdp_cmd
);
11307 install_element(ENABLE_NODE
, &debug_msdp_events_cmd
);
11308 install_element(ENABLE_NODE
, &no_debug_msdp_events_cmd
);
11309 install_element(ENABLE_NODE
, &debug_msdp_packets_cmd
);
11310 install_element(ENABLE_NODE
, &no_debug_msdp_packets_cmd
);
11311 install_element(ENABLE_NODE
, &debug_mtrace_cmd
);
11312 install_element(ENABLE_NODE
, &no_debug_mtrace_cmd
);
11313 install_element(ENABLE_NODE
, &debug_bsm_cmd
);
11314 install_element(ENABLE_NODE
, &no_debug_bsm_cmd
);
11316 install_element(CONFIG_NODE
, &debug_igmp_cmd
);
11317 install_element(CONFIG_NODE
, &no_debug_igmp_cmd
);
11318 install_element(CONFIG_NODE
, &debug_igmp_events_cmd
);
11319 install_element(CONFIG_NODE
, &no_debug_igmp_events_cmd
);
11320 install_element(CONFIG_NODE
, &debug_igmp_packets_cmd
);
11321 install_element(CONFIG_NODE
, &no_debug_igmp_packets_cmd
);
11322 install_element(CONFIG_NODE
, &debug_igmp_trace_cmd
);
11323 install_element(CONFIG_NODE
, &no_debug_igmp_trace_cmd
);
11324 install_element(CONFIG_NODE
, &debug_mroute_cmd
);
11325 install_element(CONFIG_NODE
, &debug_mroute_detail_cmd
);
11326 install_element(CONFIG_NODE
, &no_debug_mroute_cmd
);
11327 install_element(CONFIG_NODE
, &no_debug_mroute_detail_cmd
);
11328 install_element(CONFIG_NODE
, &debug_pim_static_cmd
);
11329 install_element(CONFIG_NODE
, &no_debug_pim_static_cmd
);
11330 install_element(CONFIG_NODE
, &debug_pim_cmd
);
11331 install_element(CONFIG_NODE
, &no_debug_pim_cmd
);
11332 install_element(CONFIG_NODE
, &debug_pim_nht_cmd
);
11333 install_element(CONFIG_NODE
, &no_debug_pim_nht_cmd
);
11334 install_element(CONFIG_NODE
, &debug_pim_nht_rp_cmd
);
11335 install_element(CONFIG_NODE
, &no_debug_pim_nht_rp_cmd
);
11336 install_element(CONFIG_NODE
, &debug_pim_events_cmd
);
11337 install_element(CONFIG_NODE
, &no_debug_pim_events_cmd
);
11338 install_element(CONFIG_NODE
, &debug_pim_packets_cmd
);
11339 install_element(CONFIG_NODE
, &no_debug_pim_packets_cmd
);
11340 install_element(CONFIG_NODE
, &debug_pim_trace_cmd
);
11341 install_element(CONFIG_NODE
, &no_debug_pim_trace_cmd
);
11342 install_element(CONFIG_NODE
, &debug_pim_trace_detail_cmd
);
11343 install_element(CONFIG_NODE
, &no_debug_pim_trace_detail_cmd
);
11344 install_element(CONFIG_NODE
, &debug_ssmpingd_cmd
);
11345 install_element(CONFIG_NODE
, &no_debug_ssmpingd_cmd
);
11346 install_element(CONFIG_NODE
, &debug_pim_zebra_cmd
);
11347 install_element(CONFIG_NODE
, &no_debug_pim_zebra_cmd
);
11348 install_element(CONFIG_NODE
, &debug_pim_mlag_cmd
);
11349 install_element(CONFIG_NODE
, &no_debug_pim_mlag_cmd
);
11350 install_element(CONFIG_NODE
, &debug_pim_vxlan_cmd
);
11351 install_element(CONFIG_NODE
, &no_debug_pim_vxlan_cmd
);
11352 install_element(CONFIG_NODE
, &debug_msdp_cmd
);
11353 install_element(CONFIG_NODE
, &no_debug_msdp_cmd
);
11354 install_element(CONFIG_NODE
, &debug_msdp_events_cmd
);
11355 install_element(CONFIG_NODE
, &no_debug_msdp_events_cmd
);
11356 install_element(CONFIG_NODE
, &debug_msdp_packets_cmd
);
11357 install_element(CONFIG_NODE
, &no_debug_msdp_packets_cmd
);
11358 install_element(CONFIG_NODE
, &debug_mtrace_cmd
);
11359 install_element(CONFIG_NODE
, &no_debug_mtrace_cmd
);
11360 install_element(CONFIG_NODE
, &debug_bsm_cmd
);
11361 install_element(CONFIG_NODE
, &no_debug_bsm_cmd
);
11363 install_element(CONFIG_NODE
, &ip_msdp_timers_cmd
);
11364 install_element(VRF_NODE
, &ip_msdp_timers_cmd
);
11365 install_element(CONFIG_NODE
, &no_ip_msdp_timers_cmd
);
11366 install_element(VRF_NODE
, &no_ip_msdp_timers_cmd
);
11367 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_member_cmd
);
11368 install_element(VRF_NODE
, &ip_msdp_mesh_group_member_cmd
);
11369 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
11370 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
11371 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_source_cmd
);
11372 install_element(VRF_NODE
, &ip_msdp_mesh_group_source_cmd
);
11373 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
11374 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
11375 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_cmd
);
11376 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_cmd
);
11377 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_cmd
);
11378 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_vrf_all_cmd
);
11379 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_cmd
);
11380 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_vrf_all_cmd
);
11381 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_cmd
);
11382 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_vrf_all_cmd
);
11383 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_cmd
);
11384 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_vrf_all_cmd
);
11385 install_element(VIEW_NODE
, &show_ip_pim_ssm_range_cmd
);
11386 install_element(VIEW_NODE
, &show_ip_pim_group_type_cmd
);
11387 install_element(VIEW_NODE
, &show_ip_pim_vxlan_sg_cmd
);
11388 install_element(VIEW_NODE
, &show_ip_pim_vxlan_sg_work_cmd
);
11389 install_element(INTERFACE_NODE
, &interface_pim_use_source_cmd
);
11390 install_element(INTERFACE_NODE
, &interface_no_pim_use_source_cmd
);
11391 /* Install BSM command */
11392 install_element(INTERFACE_NODE
, &ip_pim_bsm_cmd
);
11393 install_element(INTERFACE_NODE
, &no_ip_pim_bsm_cmd
);
11394 install_element(INTERFACE_NODE
, &ip_pim_ucast_bsm_cmd
);
11395 install_element(INTERFACE_NODE
, &no_ip_pim_ucast_bsm_cmd
);
11396 /* Install BFD command */
11397 install_element(INTERFACE_NODE
, &ip_pim_bfd_cmd
);
11398 install_element(INTERFACE_NODE
, &ip_pim_bfd_param_cmd
);
11399 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_profile_cmd
);
11400 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_cmd
);
11402 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_param_cmd
);
11403 #endif /* !HAVE_BFDD */