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 (5-600)",
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 (5-600)",
7199 "pim multicast routing\n"
7200 "Join Prune Send Interval\n"
7203 char jp_default_timer
[5];
7205 snprintf(jp_default_timer
, sizeof(jp_default_timer
), "%d",
7206 PIM_DEFAULT_T_PERIODIC
);
7208 nb_cli_enqueue_change(vty
, "/frr-pim:pim/join-prune-interval",
7209 NB_OP_MODIFY
, jp_default_timer
);
7211 return nb_cli_apply_changes(vty
, NULL
);
7214 DEFUN (ip_pim_register_suppress
,
7215 ip_pim_register_suppress_cmd
,
7216 "ip pim register-suppress-time (5-60000)",
7218 "pim multicast routing\n"
7219 "Register Suppress Timer\n"
7222 nb_cli_enqueue_change(vty
, "/frr-pim:pim/register-suppress-time",
7223 NB_OP_MODIFY
, argv
[3]->arg
);
7225 return nb_cli_apply_changes(vty
, NULL
);
7228 DEFUN (no_ip_pim_register_suppress
,
7229 no_ip_pim_register_suppress_cmd
,
7230 "no ip pim register-suppress-time (5-60000)",
7233 "pim multicast routing\n"
7234 "Register Suppress Timer\n"
7237 char rs_default_timer
[5];
7239 snprintf(rs_default_timer
, sizeof(rs_default_timer
), "%d",
7240 PIM_REGISTER_SUPPRESSION_TIME_DEFAULT
);
7242 nb_cli_enqueue_change(vty
, "/frr-pim:pim/register-suppress-time",
7243 NB_OP_MODIFY
, rs_default_timer
);
7245 return nb_cli_apply_changes(vty
, NULL
);
7248 DEFUN (ip_pim_rp_keep_alive
,
7249 ip_pim_rp_keep_alive_cmd
,
7250 "ip pim rp keep-alive-timer (31-60000)",
7252 "pim multicast routing\n"
7254 "Keep alive Timer\n"
7257 const char *vrfname
;
7258 char rp_ka_timer_xpath
[XPATH_MAXLEN
];
7260 vrfname
= pim_cli_get_vrf_name(vty
);
7261 if (vrfname
== NULL
)
7262 return CMD_WARNING_CONFIG_FAILED
;
7264 snprintf(rp_ka_timer_xpath
, sizeof(rp_ka_timer_xpath
),
7265 FRR_PIM_XPATH
, "frr-pim:pimd", "pim", vrfname
);
7266 strlcat(rp_ka_timer_xpath
, "/rp-keep-alive-timer",
7267 sizeof(rp_ka_timer_xpath
));
7269 nb_cli_enqueue_change(vty
, rp_ka_timer_xpath
, NB_OP_MODIFY
,
7272 return nb_cli_apply_changes(vty
, NULL
);
7275 DEFUN (no_ip_pim_rp_keep_alive
,
7276 no_ip_pim_rp_keep_alive_cmd
,
7277 "no ip pim rp keep-alive-timer (31-60000)",
7280 "pim multicast routing\n"
7282 "Keep alive Timer\n"
7285 const char *vrfname
;
7286 char rp_ka_timer
[5];
7287 char rp_ka_timer_xpath
[XPATH_MAXLEN
];
7289 snprintf(rp_ka_timer
, sizeof(rp_ka_timer
), "%d",
7290 PIM_RP_KEEPALIVE_PERIOD
);
7292 vrfname
= pim_cli_get_vrf_name(vty
);
7293 if (vrfname
== NULL
)
7294 return CMD_WARNING_CONFIG_FAILED
;
7296 snprintf(rp_ka_timer_xpath
, sizeof(rp_ka_timer_xpath
),
7297 FRR_PIM_XPATH
, "frr-pim:pimd", "pim", vrfname
);
7298 strlcat(rp_ka_timer_xpath
, "/rp-keep-alive-timer",
7299 sizeof(rp_ka_timer_xpath
));
7301 nb_cli_enqueue_change(vty
, rp_ka_timer_xpath
, NB_OP_MODIFY
,
7304 return nb_cli_apply_changes(vty
, NULL
);
7307 DEFUN (ip_pim_keep_alive
,
7308 ip_pim_keep_alive_cmd
,
7309 "ip pim keep-alive-timer (31-60000)",
7311 "pim multicast routing\n"
7312 "Keep alive Timer\n"
7315 const char *vrfname
;
7316 char ka_timer_xpath
[XPATH_MAXLEN
];
7318 vrfname
= pim_cli_get_vrf_name(vty
);
7319 if (vrfname
== NULL
)
7320 return CMD_WARNING_CONFIG_FAILED
;
7322 snprintf(ka_timer_xpath
, sizeof(ka_timer_xpath
), FRR_PIM_XPATH
,
7323 "frr-pim:pimd", "pim", vrfname
);
7324 strlcat(ka_timer_xpath
, "/keep-alive-timer", sizeof(ka_timer_xpath
));
7326 nb_cli_enqueue_change(vty
, ka_timer_xpath
, NB_OP_MODIFY
,
7329 return nb_cli_apply_changes(vty
, NULL
);
7332 DEFUN (no_ip_pim_keep_alive
,
7333 no_ip_pim_keep_alive_cmd
,
7334 "no ip pim keep-alive-timer (31-60000)",
7337 "pim multicast routing\n"
7338 "Keep alive Timer\n"
7341 const char *vrfname
;
7343 char ka_timer_xpath
[XPATH_MAXLEN
];
7345 snprintf(ka_timer
, sizeof(ka_timer
), "%d", PIM_KEEPALIVE_PERIOD
);
7347 vrfname
= pim_cli_get_vrf_name(vty
);
7348 if (vrfname
== NULL
)
7349 return CMD_WARNING_CONFIG_FAILED
;
7351 snprintf(ka_timer_xpath
, sizeof(ka_timer_xpath
), FRR_PIM_XPATH
,
7352 "frr-pim:pimd", "pim", vrfname
);
7353 strlcat(ka_timer_xpath
, "/keep-alive-timer", sizeof(ka_timer_xpath
));
7355 nb_cli_enqueue_change(vty
, ka_timer_xpath
, NB_OP_MODIFY
,
7358 return nb_cli_apply_changes(vty
, NULL
);
7361 DEFUN (ip_pim_packets
,
7363 "ip pim packets (1-100)",
7365 "pim multicast routing\n"
7366 "packets to process at one time per fd\n"
7367 "Number of packets\n")
7369 nb_cli_enqueue_change(vty
, "/frr-pim:pim/packets", NB_OP_MODIFY
,
7372 return nb_cli_apply_changes(vty
, NULL
);
7375 DEFUN (no_ip_pim_packets
,
7376 no_ip_pim_packets_cmd
,
7377 "no ip pim packets (1-100)",
7380 "pim multicast routing\n"
7381 "packets to process at one time per fd\n"
7382 "Number of packets\n")
7384 char default_packet
[3];
7386 snprintf(default_packet
, sizeof(default_packet
), "%d",
7387 PIM_DEFAULT_PACKET_PROCESS
);
7389 nb_cli_enqueue_change(vty
, "/frr-pim:pim/packets", NB_OP_MODIFY
,
7392 return nb_cli_apply_changes(vty
, NULL
);
7395 DEFPY (igmp_group_watermark
,
7396 igmp_group_watermark_cmd
,
7397 "ip igmp watermark-warn (10-60000)$limit",
7400 "Configure group limit for watermark warning\n"
7401 "Group count to generate watermark warning\n")
7403 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7404 pim
->igmp_watermark_limit
= limit
;
7409 DEFPY (no_igmp_group_watermark
,
7410 no_igmp_group_watermark_cmd
,
7411 "no ip igmp watermark-warn [(10-60000)$limit]",
7415 "Unconfigure group limit for watermark warning\n"
7416 "Group count to generate watermark warning\n")
7418 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7419 pim
->igmp_watermark_limit
= 0;
7424 DEFUN (ip_pim_v6_secondary
,
7425 ip_pim_v6_secondary_cmd
,
7426 "ip pim send-v6-secondary",
7428 "pim multicast routing\n"
7429 "Send v6 secondary addresses\n")
7431 const char *vrfname
;
7432 char send_v6_secondary_xpath
[XPATH_MAXLEN
];
7434 vrfname
= pim_cli_get_vrf_name(vty
);
7435 if (vrfname
== NULL
)
7436 return CMD_WARNING_CONFIG_FAILED
;
7438 snprintf(send_v6_secondary_xpath
, sizeof(send_v6_secondary_xpath
),
7440 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4");
7441 strlcat(send_v6_secondary_xpath
, "/send-v6-secondary",
7442 sizeof(send_v6_secondary_xpath
));
7444 nb_cli_enqueue_change(vty
, send_v6_secondary_xpath
, NB_OP_MODIFY
,
7447 return nb_cli_apply_changes(vty
, NULL
);
7450 DEFUN (no_ip_pim_v6_secondary
,
7451 no_ip_pim_v6_secondary_cmd
,
7452 "no ip pim send-v6-secondary",
7455 "pim multicast routing\n"
7456 "Send v6 secondary addresses\n")
7458 const char *vrfname
;
7459 char send_v6_secondary_xpath
[XPATH_MAXLEN
];
7461 vrfname
= pim_cli_get_vrf_name(vty
);
7462 if (vrfname
== NULL
)
7463 return CMD_WARNING_CONFIG_FAILED
;
7465 snprintf(send_v6_secondary_xpath
, sizeof(send_v6_secondary_xpath
),
7467 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4");
7468 strlcat(send_v6_secondary_xpath
, "/send-v6-secondary",
7469 sizeof(send_v6_secondary_xpath
));
7471 nb_cli_enqueue_change(vty
, send_v6_secondary_xpath
, NB_OP_MODIFY
,
7474 return nb_cli_apply_changes(vty
, NULL
);
7479 "ip pim rp A.B.C.D [A.B.C.D/M]",
7481 "pim multicast routing\n"
7483 "ip address of RP\n"
7484 "Group Address range to cover\n")
7486 const char *vrfname
;
7487 int idx_rp
= 3, idx_group
= 4;
7488 char rp_group_xpath
[XPATH_MAXLEN
];
7490 struct prefix group
;
7491 struct in_addr rp_addr
;
7492 const char *group_str
=
7493 (argc
== 5) ? argv
[idx_group
]->arg
: "224.0.0.0/4";
7495 result
= str2prefix(group_str
, &group
);
7499 prefix_copy(&temp
, &group
);
7501 if (!prefix_same(&group
, &temp
)) {
7502 vty_out(vty
, "%% Inconsistent address and mask: %s\n",
7504 return CMD_WARNING_CONFIG_FAILED
;
7509 vty_out(vty
, "%% Bad group address specified: %s\n",
7511 return CMD_WARNING_CONFIG_FAILED
;
7514 result
= inet_pton(AF_INET
, argv
[idx_rp
]->arg
, &rp_addr
);
7516 vty_out(vty
, "%% Bad RP address specified: %s\n",
7518 return CMD_WARNING_CONFIG_FAILED
;
7521 vrfname
= pim_cli_get_vrf_name(vty
);
7522 if (vrfname
== NULL
)
7523 return CMD_WARNING_CONFIG_FAILED
;
7525 snprintf(rp_group_xpath
, sizeof(rp_group_xpath
),
7526 FRR_PIM_STATIC_RP_XPATH
,
7527 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4",
7529 strlcat(rp_group_xpath
, "/group-list", sizeof(rp_group_xpath
));
7531 nb_cli_enqueue_change(vty
, rp_group_xpath
, NB_OP_CREATE
, group_str
);
7533 return nb_cli_apply_changes(vty
, NULL
);
7536 DEFUN (ip_pim_rp_prefix_list
,
7537 ip_pim_rp_prefix_list_cmd
,
7538 "ip pim rp A.B.C.D prefix-list WORD",
7540 "pim multicast routing\n"
7542 "ip address of RP\n"
7543 "group prefix-list filter\n"
7544 "Name of a prefix-list\n")
7546 int idx_rp
= 3, idx_plist
= 5;
7547 const char *vrfname
;
7548 char rp_plist_xpath
[XPATH_MAXLEN
];
7550 vrfname
= pim_cli_get_vrf_name(vty
);
7551 if (vrfname
== NULL
)
7552 return CMD_WARNING_CONFIG_FAILED
;
7554 snprintf(rp_plist_xpath
, sizeof(rp_plist_xpath
),
7555 FRR_PIM_STATIC_RP_XPATH
,
7556 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4",
7558 strlcat(rp_plist_xpath
, "/prefix-list", sizeof(rp_plist_xpath
));
7560 nb_cli_enqueue_change(vty
, rp_plist_xpath
, NB_OP_MODIFY
,
7561 argv
[idx_plist
]->arg
);
7563 return nb_cli_apply_changes(vty
, NULL
);
7566 DEFUN (no_ip_pim_rp
,
7568 "no ip pim rp A.B.C.D [A.B.C.D/M]",
7571 "pim multicast routing\n"
7573 "ip address of RP\n"
7574 "Group Address range to cover\n")
7576 int idx_rp
= 4, idx_group
= 5;
7577 const char *group_str
=
7578 (argc
== 6) ? argv
[idx_group
]->arg
: "224.0.0.0/4";
7579 char group_list_xpath
[XPATH_MAXLEN
+ 32];
7580 char group_xpath
[XPATH_MAXLEN
+ 64];
7581 char rp_xpath
[XPATH_MAXLEN
];
7582 const char *vrfname
;
7583 const struct lyd_node
*group_dnode
;
7585 vrfname
= pim_cli_get_vrf_name(vty
);
7586 if (vrfname
== NULL
)
7587 return CMD_WARNING_CONFIG_FAILED
;
7589 snprintf(rp_xpath
, sizeof(rp_xpath
), FRR_PIM_STATIC_RP_XPATH
,
7590 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4",
7593 snprintf(group_list_xpath
, sizeof(group_list_xpath
), "%s/group-list",
7596 snprintf(group_xpath
, sizeof(group_xpath
), "%s[.='%s']",
7597 group_list_xpath
, group_str
);
7599 if (!yang_dnode_exists(vty
->candidate_config
->dnode
, group_xpath
)) {
7600 vty_out(vty
, "%% Unable to find specified RP\n");
7604 group_dnode
= yang_dnode_get(vty
->candidate_config
->dnode
, group_xpath
);
7606 if (yang_is_last_list_dnode(group_dnode
))
7607 nb_cli_enqueue_change(vty
, rp_xpath
, NB_OP_DESTROY
, NULL
);
7609 nb_cli_enqueue_change(vty
, group_list_xpath
, NB_OP_DESTROY
,
7612 return nb_cli_apply_changes(vty
, NULL
);
7615 DEFUN (no_ip_pim_rp_prefix_list
,
7616 no_ip_pim_rp_prefix_list_cmd
,
7617 "no ip pim rp A.B.C.D prefix-list WORD",
7620 "pim multicast routing\n"
7622 "ip address of RP\n"
7623 "group prefix-list filter\n"
7624 "Name of a prefix-list\n")
7628 char rp_xpath
[XPATH_MAXLEN
];
7629 char plist_xpath
[XPATH_MAXLEN
];
7630 const char *vrfname
;
7631 const struct lyd_node
*plist_dnode
;
7634 vrfname
= pim_cli_get_vrf_name(vty
);
7635 if (vrfname
== NULL
)
7636 return CMD_WARNING_CONFIG_FAILED
;
7638 snprintf(rp_xpath
, sizeof(rp_xpath
), FRR_PIM_STATIC_RP_XPATH
,
7639 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4",
7642 snprintf(plist_xpath
, sizeof(plist_xpath
), FRR_PIM_STATIC_RP_XPATH
,
7643 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4",
7645 strlcat(plist_xpath
, "/prefix-list", sizeof(plist_xpath
));
7647 plist_dnode
= yang_dnode_get(vty
->candidate_config
->dnode
, plist_xpath
);
7649 vty_out(vty
, "%% Unable to find specified RP\n");
7653 plist
= yang_dnode_get_string(plist_dnode
, plist_xpath
);
7654 if (strcmp(argv
[idx_plist
]->arg
, plist
)) {
7655 vty_out(vty
, "%% Unable to find specified RP\n");
7659 nb_cli_enqueue_change(vty
, rp_xpath
, NB_OP_DESTROY
, NULL
);
7661 return nb_cli_apply_changes(vty
, NULL
);
7664 DEFUN (ip_pim_ssm_prefix_list
,
7665 ip_pim_ssm_prefix_list_cmd
,
7666 "ip pim ssm prefix-list WORD",
7668 "pim multicast routing\n"
7669 "Source Specific Multicast\n"
7670 "group range prefix-list filter\n"
7671 "Name of a prefix-list\n")
7673 const char *vrfname
;
7674 char ssm_plist_xpath
[XPATH_MAXLEN
];
7676 vrfname
= pim_cli_get_vrf_name(vty
);
7677 if (vrfname
== NULL
)
7678 return CMD_WARNING_CONFIG_FAILED
;
7680 snprintf(ssm_plist_xpath
, sizeof(ssm_plist_xpath
), FRR_PIM_AF_XPATH
,
7681 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4");
7682 strlcat(ssm_plist_xpath
, "/ssm-prefix-list", sizeof(ssm_plist_xpath
));
7684 nb_cli_enqueue_change(vty
, ssm_plist_xpath
, NB_OP_MODIFY
, argv
[4]->arg
);
7686 return nb_cli_apply_changes(vty
, NULL
);
7689 DEFUN (no_ip_pim_ssm_prefix_list
,
7690 no_ip_pim_ssm_prefix_list_cmd
,
7691 "no ip pim ssm prefix-list",
7694 "pim multicast routing\n"
7695 "Source Specific Multicast\n"
7696 "group range prefix-list filter\n")
7698 const char *vrfname
;
7699 char ssm_plist_xpath
[XPATH_MAXLEN
];
7701 vrfname
= pim_cli_get_vrf_name(vty
);
7702 if (vrfname
== NULL
)
7703 return CMD_WARNING_CONFIG_FAILED
;
7705 snprintf(ssm_plist_xpath
, sizeof(ssm_plist_xpath
),
7707 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4");
7708 strlcat(ssm_plist_xpath
, "/ssm-prefix-list", sizeof(ssm_plist_xpath
));
7710 nb_cli_enqueue_change(vty
, ssm_plist_xpath
, NB_OP_DESTROY
, NULL
);
7712 return nb_cli_apply_changes(vty
, NULL
);
7715 DEFUN (no_ip_pim_ssm_prefix_list_name
,
7716 no_ip_pim_ssm_prefix_list_name_cmd
,
7717 "no ip pim ssm prefix-list WORD",
7720 "pim multicast routing\n"
7721 "Source Specific Multicast\n"
7722 "group range prefix-list filter\n"
7723 "Name of a prefix-list\n")
7725 const char *vrfname
;
7726 const struct lyd_node
*ssm_plist_dnode
;
7727 char ssm_plist_xpath
[XPATH_MAXLEN
];
7728 const char *ssm_plist_name
;
7730 vrfname
= pim_cli_get_vrf_name(vty
);
7731 if (vrfname
== NULL
)
7732 return CMD_WARNING_CONFIG_FAILED
;
7734 snprintf(ssm_plist_xpath
, sizeof(ssm_plist_xpath
),
7736 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4");
7737 strlcat(ssm_plist_xpath
, "/ssm-prefix-list", sizeof(ssm_plist_xpath
));
7738 ssm_plist_dnode
= yang_dnode_get(vty
->candidate_config
->dnode
,
7741 if (!ssm_plist_dnode
) {
7743 "%% pim ssm prefix-list %s doesn't exist\n",
7745 return CMD_WARNING_CONFIG_FAILED
;
7748 ssm_plist_name
= yang_dnode_get_string(ssm_plist_dnode
, ".");
7750 if (ssm_plist_name
&& !strcmp(ssm_plist_name
, argv
[5]->arg
)) {
7751 nb_cli_enqueue_change(vty
, ssm_plist_xpath
, NB_OP_DESTROY
,
7754 return nb_cli_apply_changes(vty
, NULL
);
7757 vty_out(vty
, "%% pim ssm prefix-list %s doesn't exist\n", argv
[5]->arg
);
7759 return CMD_WARNING_CONFIG_FAILED
;
7762 static void ip_pim_ssm_show_group_range(struct pim_instance
*pim
,
7763 struct vty
*vty
, bool uj
)
7765 struct pim_ssm
*ssm
= pim
->ssm_info
;
7766 const char *range_str
=
7767 ssm
->plist_name
? ssm
->plist_name
: PIM_SSM_STANDARD_RANGE
;
7771 json
= json_object_new_object();
7772 json_object_string_add(json
, "ssmGroups", range_str
);
7773 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
7774 json
, JSON_C_TO_STRING_PRETTY
));
7775 json_object_free(json
);
7777 vty_out(vty
, "SSM group range : %s\n", range_str
);
7780 DEFUN (show_ip_pim_ssm_range
,
7781 show_ip_pim_ssm_range_cmd
,
7782 "show ip pim [vrf NAME] group-type [json]",
7791 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
7792 bool uj
= use_json(argc
, argv
);
7797 ip_pim_ssm_show_group_range(vrf
->info
, vty
, uj
);
7802 static void ip_pim_ssm_show_group_type(struct pim_instance
*pim
,
7803 struct vty
*vty
, bool uj
,
7806 struct in_addr group_addr
;
7807 const char *type_str
;
7810 result
= inet_pton(AF_INET
, group
, &group_addr
);
7812 type_str
= "invalid";
7814 if (pim_is_group_224_4(group_addr
))
7816 pim_is_grp_ssm(pim
, group_addr
) ? "SSM" : "ASM";
7818 type_str
= "not-multicast";
7823 json
= json_object_new_object();
7824 json_object_string_add(json
, "groupType", type_str
);
7825 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
7826 json
, JSON_C_TO_STRING_PRETTY
));
7827 json_object_free(json
);
7829 vty_out(vty
, "Group type : %s\n", type_str
);
7832 DEFUN (show_ip_pim_group_type
,
7833 show_ip_pim_group_type_cmd
,
7834 "show ip pim [vrf NAME] group-type A.B.C.D [json]",
7839 "multicast group type\n"
7844 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
7845 bool uj
= use_json(argc
, argv
);
7850 argv_find(argv
, argc
, "A.B.C.D", &idx
);
7851 ip_pim_ssm_show_group_type(vrf
->info
, vty
, uj
, argv
[idx
]->arg
);
7856 DEFUN (show_ip_pim_bsr
,
7857 show_ip_pim_bsr_cmd
,
7858 "show ip pim bsr [json]",
7862 "boot-strap router information\n"
7866 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
7867 bool uj
= use_json(argc
, argv
);
7872 pim_show_bsr(vrf
->info
, vty
, uj
);
7879 "ip ssmpingd [A.B.C.D]",
7885 const char *source_str
= (argc
== 3) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
7886 const char *vrfname
;
7887 char ssmpingd_ip_xpath
[XPATH_MAXLEN
];
7889 vrfname
= pim_cli_get_vrf_name(vty
);
7890 if (vrfname
== NULL
)
7891 return CMD_WARNING_CONFIG_FAILED
;
7893 snprintf(ssmpingd_ip_xpath
, sizeof(ssmpingd_ip_xpath
),
7895 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4");
7896 strlcat(ssmpingd_ip_xpath
, "/ssm-pingd-source-ip",
7897 sizeof(ssmpingd_ip_xpath
));
7899 nb_cli_enqueue_change(vty
, ssmpingd_ip_xpath
, NB_OP_CREATE
,
7902 return nb_cli_apply_changes(vty
, NULL
);
7905 DEFUN (no_ip_ssmpingd
,
7907 "no ip ssmpingd [A.B.C.D]",
7913 const char *vrfname
;
7915 const char *source_str
= (argc
== 4) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
7916 char ssmpingd_ip_xpath
[XPATH_MAXLEN
];
7918 vrfname
= pim_cli_get_vrf_name(vty
);
7919 if (vrfname
== NULL
)
7920 return CMD_WARNING_CONFIG_FAILED
;
7922 snprintf(ssmpingd_ip_xpath
, sizeof(ssmpingd_ip_xpath
),
7924 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4");
7925 strlcat(ssmpingd_ip_xpath
, "/ssm-pingd-source-ip",
7926 sizeof(ssmpingd_ip_xpath
));
7928 nb_cli_enqueue_change(vty
, ssmpingd_ip_xpath
, NB_OP_DESTROY
,
7931 return nb_cli_apply_changes(vty
, NULL
);
7938 "pim multicast routing\n"
7939 "Enable PIM ECMP \n")
7941 const char *vrfname
;
7942 char ecmp_xpath
[XPATH_MAXLEN
];
7944 vrfname
= pim_cli_get_vrf_name(vty
);
7945 if (vrfname
== NULL
)
7946 return CMD_WARNING_CONFIG_FAILED
;
7948 snprintf(ecmp_xpath
, sizeof(ecmp_xpath
), FRR_PIM_XPATH
,
7949 "frr-pim:pimd", "pim", vrfname
);
7950 strlcat(ecmp_xpath
, "/ecmp", sizeof(ecmp_xpath
));
7952 nb_cli_enqueue_change(vty
, ecmp_xpath
, NB_OP_MODIFY
, "true");
7953 return nb_cli_apply_changes(vty
, NULL
);
7956 DEFUN (no_ip_pim_ecmp
,
7961 "pim multicast routing\n"
7962 "Disable PIM ECMP \n")
7964 const char *vrfname
;
7965 char ecmp_xpath
[XPATH_MAXLEN
];
7967 vrfname
= pim_cli_get_vrf_name(vty
);
7968 if (vrfname
== NULL
)
7969 return CMD_WARNING_CONFIG_FAILED
;
7971 snprintf(ecmp_xpath
, sizeof(ecmp_xpath
), FRR_PIM_XPATH
,
7972 "frr-pim:pimd", "pim", vrfname
);
7973 strlcat(ecmp_xpath
, "/ecmp", sizeof(ecmp_xpath
));
7975 nb_cli_enqueue_change(vty
, ecmp_xpath
, NB_OP_MODIFY
, "false");
7977 return nb_cli_apply_changes(vty
, NULL
);
7980 DEFUN (ip_pim_ecmp_rebalance
,
7981 ip_pim_ecmp_rebalance_cmd
,
7982 "ip pim ecmp rebalance",
7984 "pim multicast routing\n"
7985 "Enable PIM ECMP \n"
7986 "Enable PIM ECMP Rebalance\n")
7988 const char *vrfname
;
7989 char ecmp_xpath
[XPATH_MAXLEN
];
7990 char ecmp_rebalance_xpath
[XPATH_MAXLEN
];
7992 vrfname
= pim_cli_get_vrf_name(vty
);
7993 if (vrfname
== NULL
)
7994 return CMD_WARNING_CONFIG_FAILED
;
7996 snprintf(ecmp_xpath
, sizeof(ecmp_xpath
), FRR_PIM_XPATH
,
7997 "frr-pim:pimd", "pim", vrfname
);
7998 strlcat(ecmp_xpath
, "/ecmp", sizeof(ecmp_xpath
));
7999 snprintf(ecmp_rebalance_xpath
, sizeof(ecmp_rebalance_xpath
),
8001 "frr-pim:pimd", "pim", vrfname
);
8002 strlcat(ecmp_rebalance_xpath
, "/ecmp-rebalance",
8003 sizeof(ecmp_rebalance_xpath
));
8005 nb_cli_enqueue_change(vty
, ecmp_xpath
, NB_OP_MODIFY
, "true");
8006 nb_cli_enqueue_change(vty
, ecmp_rebalance_xpath
, NB_OP_MODIFY
, "true");
8008 return nb_cli_apply_changes(vty
, NULL
);
8011 DEFUN (no_ip_pim_ecmp_rebalance
,
8012 no_ip_pim_ecmp_rebalance_cmd
,
8013 "no ip pim ecmp rebalance",
8016 "pim multicast routing\n"
8017 "Disable PIM ECMP \n"
8018 "Disable PIM ECMP Rebalance\n")
8020 const char *vrfname
;
8021 char ecmp_rebalance_xpath
[XPATH_MAXLEN
];
8023 vrfname
= pim_cli_get_vrf_name(vty
);
8024 if (vrfname
== NULL
)
8025 return CMD_WARNING_CONFIG_FAILED
;
8027 snprintf(ecmp_rebalance_xpath
, sizeof(ecmp_rebalance_xpath
),
8029 "frr-pim:pimd", "pim", vrfname
);
8030 strlcat(ecmp_rebalance_xpath
, "/ecmp-rebalance",
8031 sizeof(ecmp_rebalance_xpath
));
8033 nb_cli_enqueue_change(vty
, ecmp_rebalance_xpath
, NB_OP_MODIFY
, "false");
8035 return nb_cli_apply_changes(vty
, NULL
);
8038 DEFUN (interface_ip_igmp
,
8039 interface_ip_igmp_cmd
,
8044 nb_cli_enqueue_change(vty
, "./igmp-enable", NB_OP_MODIFY
, "true");
8046 return nb_cli_apply_changes(vty
, "./frr-igmp:igmp");
8049 DEFUN (interface_no_ip_igmp
,
8050 interface_no_ip_igmp_cmd
,
8056 const struct lyd_node
*pim_enable_dnode
;
8057 char pim_if_xpath
[XPATH_MAXLEN
+ 20];
8059 snprintf(pim_if_xpath
, sizeof(pim_if_xpath
),
8060 "%s/frr-pim:pim", VTY_CURR_XPATH
);
8062 pim_enable_dnode
= yang_dnode_getf(vty
->candidate_config
->dnode
,
8063 "%s/pim-enable", pim_if_xpath
);
8064 if (!pim_enable_dnode
) {
8065 nb_cli_enqueue_change(vty
, pim_if_xpath
, NB_OP_DESTROY
, NULL
);
8066 nb_cli_enqueue_change(vty
, ".", NB_OP_DESTROY
, NULL
);
8068 if (!yang_dnode_get_bool(pim_enable_dnode
, ".")) {
8069 nb_cli_enqueue_change(vty
, pim_if_xpath
, NB_OP_DESTROY
,
8071 nb_cli_enqueue_change(vty
, ".", NB_OP_DESTROY
, NULL
);
8073 nb_cli_enqueue_change(vty
, "./igmp-enable",
8074 NB_OP_MODIFY
, "false");
8077 return nb_cli_apply_changes(vty
, "./frr-igmp:igmp");
8080 DEFUN (interface_ip_igmp_join
,
8081 interface_ip_igmp_join_cmd
,
8082 "ip igmp join A.B.C.D [A.B.C.D]",
8085 "IGMP join multicast group\n"
8086 "Multicast group address\n"
8091 const char *source_str
;
8092 char xpath
[XPATH_MAXLEN
];
8095 source_str
= argv
[idx_source
]->arg
;
8097 if (strcmp(source_str
, "0.0.0.0") == 0) {
8098 vty_out(vty
, "Bad source address %s\n",
8099 argv
[idx_source
]->arg
);
8100 return CMD_WARNING_CONFIG_FAILED
;
8103 source_str
= "0.0.0.0";
8105 snprintf(xpath
, sizeof(xpath
), FRR_IGMP_JOIN_XPATH
,
8106 "frr-routing:ipv4", argv
[idx_group
]->arg
, source_str
);
8108 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
8110 return nb_cli_apply_changes(vty
, NULL
);
8113 DEFUN (interface_no_ip_igmp_join
,
8114 interface_no_ip_igmp_join_cmd
,
8115 "no ip igmp join A.B.C.D [A.B.C.D]",
8119 "IGMP join multicast group\n"
8120 "Multicast group address\n"
8125 const char *source_str
;
8126 char xpath
[XPATH_MAXLEN
];
8129 source_str
= argv
[idx_source
]->arg
;
8131 if (strcmp(source_str
, "0.0.0.0") == 0) {
8132 vty_out(vty
, "Bad source address %s\n",
8133 argv
[idx_source
]->arg
);
8134 return CMD_WARNING_CONFIG_FAILED
;
8137 source_str
= "0.0.0.0";
8139 snprintf(xpath
, sizeof(xpath
), FRR_IGMP_JOIN_XPATH
,
8140 "frr-routing:ipv4", argv
[idx_group
]->arg
, source_str
);
8142 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
8144 return nb_cli_apply_changes(vty
, NULL
);
8147 DEFUN (interface_ip_igmp_query_interval
,
8148 interface_ip_igmp_query_interval_cmd
,
8149 "ip igmp query-interval (1-1800)",
8152 IFACE_IGMP_QUERY_INTERVAL_STR
8153 "Query interval in seconds\n")
8155 const struct lyd_node
*pim_enable_dnode
;
8158 yang_dnode_getf(vty
->candidate_config
->dnode
,
8159 "%s/frr-pim:pim/pim-enable", VTY_CURR_XPATH
);
8160 if (!pim_enable_dnode
) {
8161 nb_cli_enqueue_change(vty
, "./igmp-enable", NB_OP_MODIFY
,
8164 if (!yang_dnode_get_bool(pim_enable_dnode
, "."))
8165 nb_cli_enqueue_change(vty
, "./igmp-enable",
8166 NB_OP_MODIFY
, "true");
8169 nb_cli_enqueue_change(vty
, "./query-interval", NB_OP_MODIFY
,
8172 return nb_cli_apply_changes(vty
, "./frr-igmp:igmp");
8175 DEFUN (interface_no_ip_igmp_query_interval
,
8176 interface_no_ip_igmp_query_interval_cmd
,
8177 "no ip igmp query-interval",
8181 IFACE_IGMP_QUERY_INTERVAL_STR
)
8183 char default_query_interval
[5];
8185 snprintf(default_query_interval
, sizeof(default_query_interval
), "%d",
8186 IGMP_GENERAL_QUERY_INTERVAL
);
8188 nb_cli_enqueue_change(vty
, "./query-interval", NB_OP_MODIFY
,
8189 default_query_interval
);
8191 return nb_cli_apply_changes(vty
, "./frr-igmp:igmp");
8194 DEFUN (interface_ip_igmp_version
,
8195 interface_ip_igmp_version_cmd
,
8196 "ip igmp version (2-3)",
8200 "IGMP version number\n")
8202 nb_cli_enqueue_change(vty
, "./igmp-enable", NB_OP_MODIFY
,
8204 nb_cli_enqueue_change(vty
, "./version", NB_OP_MODIFY
, argv
[3]->arg
);
8206 return nb_cli_apply_changes(vty
, "./frr-igmp:igmp");
8209 DEFUN (interface_no_ip_igmp_version
,
8210 interface_no_ip_igmp_version_cmd
,
8211 "no ip igmp version (2-3)",
8216 "IGMP version number\n")
8218 nb_cli_enqueue_change(vty
, "./version", NB_OP_DESTROY
, NULL
);
8220 return nb_cli_apply_changes(vty
, "./frr-igmp:igmp");
8223 DEFUN (interface_ip_igmp_query_max_response_time
,
8224 interface_ip_igmp_query_max_response_time_cmd
,
8225 "ip igmp query-max-response-time (10-250)",
8228 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
8229 "Query response value in deci-seconds\n")
8231 const struct lyd_node
*pim_enable_dnode
;
8234 yang_dnode_getf(vty
->candidate_config
->dnode
,
8235 "%s/frr-pim:pim/pim-enable", VTY_CURR_XPATH
);
8237 if (!pim_enable_dnode
) {
8238 nb_cli_enqueue_change(vty
, "./igmp-enable", NB_OP_MODIFY
,
8241 if (!yang_dnode_get_bool(pim_enable_dnode
, "."))
8242 nb_cli_enqueue_change(vty
, "./igmp-enable",
8243 NB_OP_MODIFY
, "true");
8246 nb_cli_enqueue_change(vty
, "./query-max-response-time", NB_OP_MODIFY
,
8249 return nb_cli_apply_changes(vty
, "./frr-igmp:igmp");
8252 DEFUN (interface_no_ip_igmp_query_max_response_time
,
8253 interface_no_ip_igmp_query_max_response_time_cmd
,
8254 "no ip igmp query-max-response-time (10-250)",
8258 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
8259 "Time for response in deci-seconds\n")
8261 char default_query_max_response_time
[4];
8263 snprintf(default_query_max_response_time
,
8264 sizeof(default_query_max_response_time
),
8265 "%d", IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
8267 nb_cli_enqueue_change(vty
, "./query-max-response-time", NB_OP_MODIFY
,
8268 default_query_max_response_time
);
8269 return nb_cli_apply_changes(vty
, "./frr-igmp:igmp");
8272 DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec
,
8273 interface_ip_igmp_query_max_response_time_dsec_cmd
,
8274 "ip igmp query-max-response-time-dsec (10-250)",
8277 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
8278 "Query response value in deciseconds\n")
8280 const struct lyd_node
*pim_enable_dnode
;
8283 yang_dnode_getf(vty
->candidate_config
->dnode
,
8284 "%s/frr-pim:pim/pim-enable", VTY_CURR_XPATH
);
8285 if (!pim_enable_dnode
) {
8286 nb_cli_enqueue_change(vty
, "./igmp-enable", NB_OP_MODIFY
,
8289 if (!yang_dnode_get_bool(pim_enable_dnode
, "."))
8290 nb_cli_enqueue_change(vty
, "./igmp-enable",
8291 NB_OP_MODIFY
, "true");
8294 nb_cli_enqueue_change(vty
, "./query-max-response-time", NB_OP_MODIFY
,
8297 return nb_cli_apply_changes(vty
, "./frr-igmp:igmp");
8300 DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec
,
8301 interface_no_ip_igmp_query_max_response_time_dsec_cmd
,
8302 "no ip igmp query-max-response-time-dsec",
8306 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
)
8308 char default_query_max_response_time
[4];
8310 snprintf(default_query_max_response_time
,
8311 sizeof(default_query_max_response_time
),
8312 "%d", IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
8314 nb_cli_enqueue_change(vty
, "./query-max-response-time", NB_OP_MODIFY
,
8315 default_query_max_response_time
);
8317 return nb_cli_apply_changes(vty
, "./frr-igmp:igmp");
8320 DEFUN (interface_ip_igmp_last_member_query_count
,
8321 interface_ip_igmp_last_member_query_count_cmd
,
8322 "ip igmp last-member-query-count (1-7)",
8325 IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR
8326 "Last member query count\n")
8328 const struct lyd_node
*pim_enable_dnode
;
8331 yang_dnode_getf(vty
->candidate_config
->dnode
,
8332 "%s/frr-pim:pim/pim-enable", VTY_CURR_XPATH
);
8333 if (!pim_enable_dnode
) {
8334 nb_cli_enqueue_change(vty
, "./igmp-enable", NB_OP_MODIFY
,
8337 if (!yang_dnode_get_bool(pim_enable_dnode
, "."))
8338 nb_cli_enqueue_change(vty
, "./igmp-enable",
8339 NB_OP_MODIFY
, "true");
8342 nb_cli_enqueue_change(vty
, "./robustness-variable", NB_OP_MODIFY
,
8345 return nb_cli_apply_changes(vty
, "./frr-igmp:igmp");
8348 DEFUN (interface_no_ip_igmp_last_member_query_count
,
8349 interface_no_ip_igmp_last_member_query_count_cmd
,
8350 "no ip igmp last-member-query-count [(1-7)]",
8354 IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR
8355 "Last member query count\n")
8357 char default_robustness
[2];
8359 snprintf(default_robustness
, sizeof(default_robustness
), "%d",
8360 IGMP_DEFAULT_ROBUSTNESS_VARIABLE
);
8362 nb_cli_enqueue_change(vty
, "./robustness-variable", NB_OP_MODIFY
,
8363 default_robustness
);
8365 return nb_cli_apply_changes(vty
, "./frr-igmp:igmp");
8368 DEFUN (interface_ip_igmp_last_member_query_interval
,
8369 interface_ip_igmp_last_member_query_interval_cmd
,
8370 "ip igmp last-member-query-interval (1-255)",
8373 IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR
8374 "Last member query interval in deciseconds\n")
8376 const struct lyd_node
*pim_enable_dnode
;
8379 yang_dnode_getf(vty
->candidate_config
->dnode
,
8380 "%s/frr-pim:pim/pim-enable", VTY_CURR_XPATH
);
8381 if (!pim_enable_dnode
) {
8382 nb_cli_enqueue_change(vty
, "./igmp-enable", NB_OP_MODIFY
,
8385 if (!yang_dnode_get_bool(pim_enable_dnode
, "."))
8386 nb_cli_enqueue_change(vty
, "./igmp-enable",
8387 NB_OP_MODIFY
, "true");
8390 nb_cli_enqueue_change(vty
, "./last-member-query-interval", NB_OP_MODIFY
,
8393 return nb_cli_apply_changes(vty
, "./frr-igmp:igmp");
8396 DEFUN (interface_no_ip_igmp_last_member_query_interval
,
8397 interface_no_ip_igmp_last_member_query_interval_cmd
,
8398 "no ip igmp last-member-query-interval [(1-255)]",
8402 IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR
8403 "Last member query interval in deciseconds\n")
8405 char default_last_member_query_count
[4];
8407 snprintf(default_last_member_query_count
,
8408 sizeof(default_last_member_query_count
),
8409 "%d", IGMP_SPECIFIC_QUERY_MAX_RESPONSE_TIME_DSEC
);
8411 nb_cli_enqueue_change(vty
, "./last-member-query-interval", NB_OP_MODIFY
,
8412 default_last_member_query_count
);
8414 return nb_cli_apply_changes(vty
, "./frr-igmp:igmp");
8417 DEFUN (interface_ip_pim_drprio
,
8418 interface_ip_pim_drprio_cmd
,
8419 "ip pim drpriority (1-4294967295)",
8422 "Set the Designated Router Election Priority\n"
8423 "Value of the new DR Priority\n")
8427 nb_cli_enqueue_change(vty
, "./dr-priority", NB_OP_MODIFY
,
8428 argv
[idx_number
]->arg
);
8430 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
8433 DEFUN (interface_no_ip_pim_drprio
,
8434 interface_no_ip_pim_drprio_cmd
,
8435 "no ip pim drpriority [(1-4294967295)]",
8439 "Revert the Designated Router Priority to default\n"
8440 "Old Value of the Priority\n")
8442 char default_priority
[10];
8444 snprintf(default_priority
, sizeof(default_priority
), "%d",
8445 PIM_DEFAULT_DR_PRIORITY
);
8447 nb_cli_enqueue_change(vty
, "./dr-priority", NB_OP_MODIFY
,
8450 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
8453 DEFPY_HIDDEN (interface_ip_igmp_query_generate
,
8454 interface_ip_igmp_query_generate_cmd
,
8455 "ip igmp generate-query-once [version (2-3)]",
8458 "Generate igmp general query once\n"
8460 "IGMP version number\n")
8462 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8463 int igmp_version
= 2;
8466 vty_out(vty
, "IGMP/PIM is not enabled on the interface %s\n",
8468 return CMD_WARNING_CONFIG_FAILED
;
8472 igmp_version
= atoi(argv
[4]->arg
);
8474 igmp_send_query_on_intf(ifp
, igmp_version
);
8479 DEFPY_HIDDEN (pim_test_sg_keepalive
,
8480 pim_test_sg_keepalive_cmd
,
8481 "test pim [vrf NAME$name] keepalive-reset A.B.C.D$source A.B.C.D$group",
8485 "Reset the Keepalive Timer\n"
8486 "The Source we are resetting\n"
8487 "The Group we are resetting\n")
8489 struct pim_upstream
*up
;
8490 struct pim_instance
*pim
;
8491 struct prefix_sg sg
;
8497 pim
= pim_get_pim_instance(VRF_DEFAULT
);
8499 struct vrf
*vrf
= vrf_lookup_by_name(name
);
8502 vty_out(vty
, "%% Vrf specified: %s does not exist\n",
8507 pim
= pim_get_pim_instance(vrf
->vrf_id
);
8511 vty_out(vty
, "%% Unable to find pim instance\n");
8515 up
= pim_upstream_find(pim
, &sg
);
8517 vty_out(vty
, "%% Unable to find %s specified\n",
8518 pim_str_sg_dump(&sg
));
8522 vty_out(vty
, "Setting %s to current keep alive time: %d\n",
8523 pim_str_sg_dump(&sg
), pim
->keep_alive_time
);
8524 pim_upstream_keep_alive_timer_start(up
, pim
->keep_alive_time
);
8529 DEFPY (interface_ip_pim_activeactive
,
8530 interface_ip_pim_activeactive_cmd
,
8531 "[no$no] ip pim active-active",
8535 "Mark interface as Active-Active for MLAG operations, Hidden because not finished yet\n")
8538 nb_cli_enqueue_change(vty
, "./active-active", NB_OP_MODIFY
,
8541 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
,
8544 nb_cli_enqueue_change(vty
, "./active-active", NB_OP_MODIFY
,
8548 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
8551 DEFUN_HIDDEN (interface_ip_pim_ssm
,
8552 interface_ip_pim_ssm_cmd
,
8560 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
, "true");
8562 ret
= nb_cli_apply_changes(vty
, "./frr-pim:pim");
8568 "WARN: Enabled PIM SM on interface; configure PIM SSM range if needed\n");
8573 DEFUN_HIDDEN (interface_ip_pim_sm
,
8574 interface_ip_pim_sm_cmd
,
8580 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
, "true");
8582 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
8585 DEFUN (interface_ip_pim
,
8586 interface_ip_pim_cmd
,
8591 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
, "true");
8593 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
8596 DEFUN_HIDDEN (interface_no_ip_pim_ssm
,
8597 interface_no_ip_pim_ssm_cmd
,
8604 const struct lyd_node
*igmp_enable_dnode
;
8605 char igmp_if_xpath
[XPATH_MAXLEN
+ 20];
8607 snprintf(igmp_if_xpath
, sizeof(igmp_if_xpath
),
8608 "%s/frr-igmp:igmp", VTY_CURR_XPATH
);
8609 igmp_enable_dnode
= yang_dnode_getf(vty
->candidate_config
->dnode
,
8610 "%s/igmp-enable", igmp_if_xpath
);
8612 if (!igmp_enable_dnode
) {
8613 nb_cli_enqueue_change(vty
, igmp_if_xpath
, NB_OP_DESTROY
, NULL
);
8614 nb_cli_enqueue_change(vty
, ".", NB_OP_DESTROY
, NULL
);
8616 if (!yang_dnode_get_bool(igmp_enable_dnode
, ".")) {
8617 nb_cli_enqueue_change(vty
, igmp_if_xpath
, NB_OP_DESTROY
,
8619 nb_cli_enqueue_change(vty
, ".", NB_OP_DESTROY
, NULL
);
8621 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
,
8625 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
8628 DEFUN_HIDDEN (interface_no_ip_pim_sm
,
8629 interface_no_ip_pim_sm_cmd
,
8636 const struct lyd_node
*igmp_enable_dnode
;
8637 char igmp_if_xpath
[XPATH_MAXLEN
+ 20];
8639 snprintf(igmp_if_xpath
, sizeof(igmp_if_xpath
),
8640 "%s/frr-igmp:igmp", VTY_CURR_XPATH
);
8641 igmp_enable_dnode
= yang_dnode_getf(vty
->candidate_config
->dnode
,
8642 "%s/igmp-enable", igmp_if_xpath
);
8644 if (!igmp_enable_dnode
) {
8645 nb_cli_enqueue_change(vty
, igmp_if_xpath
, NB_OP_DESTROY
, NULL
);
8646 nb_cli_enqueue_change(vty
, ".", NB_OP_DESTROY
, NULL
);
8648 if (!yang_dnode_get_bool(igmp_enable_dnode
, ".")) {
8649 nb_cli_enqueue_change(vty
, igmp_if_xpath
, NB_OP_DESTROY
,
8651 nb_cli_enqueue_change(vty
, ".", NB_OP_DESTROY
, NULL
);
8653 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
,
8657 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
8660 DEFUN (interface_no_ip_pim
,
8661 interface_no_ip_pim_cmd
,
8667 const struct lyd_node
*igmp_enable_dnode
;
8668 char igmp_if_xpath
[XPATH_MAXLEN
+ 20];
8670 snprintf(igmp_if_xpath
, sizeof(igmp_if_xpath
),
8671 "%s/frr-igmp:igmp", VTY_CURR_XPATH
);
8672 igmp_enable_dnode
= yang_dnode_getf(vty
->candidate_config
->dnode
,
8673 "%s/igmp-enable", igmp_if_xpath
);
8675 if (!igmp_enable_dnode
) {
8676 nb_cli_enqueue_change(vty
, igmp_if_xpath
, NB_OP_DESTROY
, NULL
);
8677 nb_cli_enqueue_change(vty
, ".", NB_OP_DESTROY
, NULL
);
8679 if (!yang_dnode_get_bool(igmp_enable_dnode
, ".")) {
8680 nb_cli_enqueue_change(vty
, igmp_if_xpath
, NB_OP_DESTROY
,
8682 nb_cli_enqueue_change(vty
, ".", NB_OP_DESTROY
, NULL
);
8684 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
,
8688 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
8692 DEFUN(interface_ip_pim_boundary_oil
,
8693 interface_ip_pim_boundary_oil_cmd
,
8694 "ip multicast boundary oil WORD",
8696 "Generic multicast configuration options\n"
8697 "Define multicast boundary\n"
8698 "Filter OIL by group using prefix list\n"
8699 "Prefix list to filter OIL with\n")
8701 nb_cli_enqueue_change(vty
, "./multicast-boundary-oil", NB_OP_MODIFY
,
8704 return nb_cli_apply_changes(vty
,
8705 "./frr-pim:pim/address-family[address-family='%s']",
8706 "frr-routing:ipv4");
8710 DEFUN(interface_no_ip_pim_boundary_oil
,
8711 interface_no_ip_pim_boundary_oil_cmd
,
8712 "no ip multicast boundary oil [WORD]",
8715 "Generic multicast configuration options\n"
8716 "Define multicast boundary\n"
8717 "Filter OIL by group using prefix list\n"
8718 "Prefix list to filter OIL with\n")
8720 nb_cli_enqueue_change(vty
, "./multicast-boundary-oil", NB_OP_DESTROY
,
8723 return nb_cli_apply_changes(vty
,
8724 "./frr-pim:pim/address-family[address-family='%s']",
8725 "frr-routing:ipv4");
8728 DEFUN (interface_ip_mroute
,
8729 interface_ip_mroute_cmd
,
8730 "ip mroute INTERFACE A.B.C.D [A.B.C.D]",
8732 "Add multicast route\n"
8733 "Outgoing interface name\n"
8737 int idx_interface
= 2;
8739 const char *source_str
;
8741 if (argc
== (idx_ipv4
+ 1))
8742 source_str
= "0.0.0.0";
8744 source_str
= argv
[idx_ipv4
+ 1]->arg
;
8746 nb_cli_enqueue_change(vty
, "./oif", NB_OP_MODIFY
,
8747 argv
[idx_interface
]->arg
);
8749 return nb_cli_apply_changes(vty
,
8750 "./frr-pim:pim/address-family[address-family='%s']/mroute[source-addr='%s'][group-addr='%s']",
8751 "frr-routing:ipv4", source_str
,
8752 argv
[idx_ipv4
]->arg
);
8755 DEFUN (interface_no_ip_mroute
,
8756 interface_no_ip_mroute_cmd
,
8757 "no ip mroute INTERFACE A.B.C.D [A.B.C.D]",
8760 "Add multicast route\n"
8761 "Outgoing interface name\n"
8766 const char *source_str
;
8768 if (argc
== (idx_ipv4
+ 1))
8769 source_str
= "0.0.0.0";
8771 source_str
= argv
[idx_ipv4
+ 1]->arg
;
8773 nb_cli_enqueue_change(vty
, ".", NB_OP_DESTROY
, NULL
);
8775 return nb_cli_apply_changes(vty
,
8776 "./frr-pim:pim/address-family[address-family='%s']/mroute[source-addr='%s'][group-addr='%s']",
8777 "frr-routing:ipv4", source_str
,
8778 argv
[idx_ipv4
]->arg
);
8781 DEFUN (interface_ip_pim_hello
,
8782 interface_ip_pim_hello_cmd
,
8783 "ip pim hello (1-180) [(1-630)]",
8787 IFACE_PIM_HELLO_TIME_STR
8788 IFACE_PIM_HELLO_HOLD_STR
)
8792 const struct lyd_node
*igmp_enable_dnode
;
8795 yang_dnode_getf(vty
->candidate_config
->dnode
,
8796 "%s/frr-igmp:igmp/igmp-enable", VTY_CURR_XPATH
);
8797 if (!igmp_enable_dnode
) {
8798 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
,
8801 if (!yang_dnode_get_bool(igmp_enable_dnode
, "."))
8802 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
,
8806 nb_cli_enqueue_change(vty
, "./hello-interval", NB_OP_MODIFY
,
8807 argv
[idx_time
]->arg
);
8809 if (argc
== idx_hold
+ 1)
8810 nb_cli_enqueue_change(vty
, "./hello-holdtime", NB_OP_MODIFY
,
8811 argv
[idx_hold
]->arg
);
8813 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
8816 DEFUN (interface_no_ip_pim_hello
,
8817 interface_no_ip_pim_hello_cmd
,
8818 "no ip pim hello [(1-180) [(1-630)]]",
8823 IFACE_PIM_HELLO_TIME_STR
8824 IFACE_PIM_HELLO_HOLD_STR
)
8826 char hello_default_timer
[3];
8828 snprintf(hello_default_timer
, sizeof(hello_default_timer
), "%d",
8829 PIM_DEFAULT_HELLO_PERIOD
);
8831 nb_cli_enqueue_change(vty
, "./hello-interval", NB_OP_MODIFY
,
8832 hello_default_timer
);
8833 nb_cli_enqueue_change(vty
, "./hello-holdtime", NB_OP_DESTROY
, NULL
);
8835 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
8844 PIM_DO_DEBUG_IGMP_EVENTS
;
8845 PIM_DO_DEBUG_IGMP_PACKETS
;
8846 PIM_DO_DEBUG_IGMP_TRACE
;
8850 DEFUN (no_debug_igmp
,
8857 PIM_DONT_DEBUG_IGMP_EVENTS
;
8858 PIM_DONT_DEBUG_IGMP_PACKETS
;
8859 PIM_DONT_DEBUG_IGMP_TRACE
;
8864 DEFUN (debug_igmp_events
,
8865 debug_igmp_events_cmd
,
8866 "debug igmp events",
8869 DEBUG_IGMP_EVENTS_STR
)
8871 PIM_DO_DEBUG_IGMP_EVENTS
;
8875 DEFUN (no_debug_igmp_events
,
8876 no_debug_igmp_events_cmd
,
8877 "no debug igmp events",
8881 DEBUG_IGMP_EVENTS_STR
)
8883 PIM_DONT_DEBUG_IGMP_EVENTS
;
8888 DEFUN (debug_igmp_packets
,
8889 debug_igmp_packets_cmd
,
8890 "debug igmp packets",
8893 DEBUG_IGMP_PACKETS_STR
)
8895 PIM_DO_DEBUG_IGMP_PACKETS
;
8899 DEFUN (no_debug_igmp_packets
,
8900 no_debug_igmp_packets_cmd
,
8901 "no debug igmp packets",
8905 DEBUG_IGMP_PACKETS_STR
)
8907 PIM_DONT_DEBUG_IGMP_PACKETS
;
8912 DEFUN (debug_igmp_trace
,
8913 debug_igmp_trace_cmd
,
8917 DEBUG_IGMP_TRACE_STR
)
8919 PIM_DO_DEBUG_IGMP_TRACE
;
8923 DEFUN (no_debug_igmp_trace
,
8924 no_debug_igmp_trace_cmd
,
8925 "no debug igmp trace",
8929 DEBUG_IGMP_TRACE_STR
)
8931 PIM_DONT_DEBUG_IGMP_TRACE
;
8936 DEFUN (debug_mroute
,
8942 PIM_DO_DEBUG_MROUTE
;
8946 DEFUN (debug_mroute_detail
,
8947 debug_mroute_detail_cmd
,
8948 "debug mroute detail",
8953 PIM_DO_DEBUG_MROUTE_DETAIL
;
8957 DEFUN (no_debug_mroute
,
8958 no_debug_mroute_cmd
,
8964 PIM_DONT_DEBUG_MROUTE
;
8968 DEFUN (no_debug_mroute_detail
,
8969 no_debug_mroute_detail_cmd
,
8970 "no debug mroute detail",
8976 PIM_DONT_DEBUG_MROUTE_DETAIL
;
8980 DEFUN (debug_pim_static
,
8981 debug_pim_static_cmd
,
8987 PIM_DO_DEBUG_STATIC
;
8991 DEFUN (no_debug_pim_static
,
8992 no_debug_pim_static_cmd
,
8993 "no debug pim static",
8999 PIM_DONT_DEBUG_STATIC
;
9010 PIM_DO_DEBUG_PIM_EVENTS
;
9011 PIM_DO_DEBUG_PIM_PACKETS
;
9012 PIM_DO_DEBUG_PIM_TRACE
;
9013 PIM_DO_DEBUG_MSDP_EVENTS
;
9014 PIM_DO_DEBUG_MSDP_PACKETS
;
9019 DEFUN (no_debug_pim
,
9026 PIM_DONT_DEBUG_PIM_EVENTS
;
9027 PIM_DONT_DEBUG_PIM_PACKETS
;
9028 PIM_DONT_DEBUG_PIM_TRACE
;
9029 PIM_DONT_DEBUG_MSDP_EVENTS
;
9030 PIM_DONT_DEBUG_MSDP_PACKETS
;
9032 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
9033 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
9039 DEFUN (debug_pim_nht
,
9044 "Nexthop Tracking\n")
9046 PIM_DO_DEBUG_PIM_NHT
;
9050 DEFUN (no_debug_pim_nht
,
9051 no_debug_pim_nht_cmd
,
9056 "Nexthop Tracking\n")
9058 PIM_DONT_DEBUG_PIM_NHT
;
9062 DEFUN (debug_pim_nht_rp
,
9063 debug_pim_nht_rp_cmd
,
9067 "Nexthop Tracking\n"
9068 "RP Nexthop Tracking\n")
9070 PIM_DO_DEBUG_PIM_NHT_RP
;
9074 DEFUN (no_debug_pim_nht_rp
,
9075 no_debug_pim_nht_rp_cmd
,
9076 "no debug pim nht rp",
9080 "Nexthop Tracking\n"
9081 "RP Nexthop Tracking\n")
9083 PIM_DONT_DEBUG_PIM_NHT_RP
;
9087 DEFUN (debug_pim_events
,
9088 debug_pim_events_cmd
,
9092 DEBUG_PIM_EVENTS_STR
)
9094 PIM_DO_DEBUG_PIM_EVENTS
;
9098 DEFUN (no_debug_pim_events
,
9099 no_debug_pim_events_cmd
,
9100 "no debug pim events",
9104 DEBUG_PIM_EVENTS_STR
)
9106 PIM_DONT_DEBUG_PIM_EVENTS
;
9110 DEFUN (debug_pim_packets
,
9111 debug_pim_packets_cmd
,
9112 "debug pim packets [<hello|joins|register>]",
9115 DEBUG_PIM_PACKETS_STR
9116 DEBUG_PIM_HELLO_PACKETS_STR
9117 DEBUG_PIM_J_P_PACKETS_STR
9118 DEBUG_PIM_PIM_REG_PACKETS_STR
)
9121 if (argv_find(argv
, argc
, "hello", &idx
)) {
9122 PIM_DO_DEBUG_PIM_HELLO
;
9123 vty_out(vty
, "PIM Hello debugging is on\n");
9124 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
9125 PIM_DO_DEBUG_PIM_J_P
;
9126 vty_out(vty
, "PIM Join/Prune debugging is on\n");
9127 } else if (argv_find(argv
, argc
, "register", &idx
)) {
9128 PIM_DO_DEBUG_PIM_REG
;
9129 vty_out(vty
, "PIM Register debugging is on\n");
9131 PIM_DO_DEBUG_PIM_PACKETS
;
9132 vty_out(vty
, "PIM Packet debugging is on \n");
9137 DEFUN (no_debug_pim_packets
,
9138 no_debug_pim_packets_cmd
,
9139 "no debug pim packets [<hello|joins|register>]",
9143 DEBUG_PIM_PACKETS_STR
9144 DEBUG_PIM_HELLO_PACKETS_STR
9145 DEBUG_PIM_J_P_PACKETS_STR
9146 DEBUG_PIM_PIM_REG_PACKETS_STR
)
9149 if (argv_find(argv
, argc
, "hello", &idx
)) {
9150 PIM_DONT_DEBUG_PIM_HELLO
;
9151 vty_out(vty
, "PIM Hello debugging is off \n");
9152 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
9153 PIM_DONT_DEBUG_PIM_J_P
;
9154 vty_out(vty
, "PIM Join/Prune debugging is off \n");
9155 } else if (argv_find(argv
, argc
, "register", &idx
)) {
9156 PIM_DONT_DEBUG_PIM_REG
;
9157 vty_out(vty
, "PIM Register debugging is off\n");
9159 PIM_DONT_DEBUG_PIM_PACKETS
;
9165 DEFUN (debug_pim_packetdump_send
,
9166 debug_pim_packetdump_send_cmd
,
9167 "debug pim packet-dump send",
9170 DEBUG_PIM_PACKETDUMP_STR
9171 DEBUG_PIM_PACKETDUMP_SEND_STR
)
9173 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND
;
9177 DEFUN (no_debug_pim_packetdump_send
,
9178 no_debug_pim_packetdump_send_cmd
,
9179 "no debug pim packet-dump send",
9183 DEBUG_PIM_PACKETDUMP_STR
9184 DEBUG_PIM_PACKETDUMP_SEND_STR
)
9186 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
9190 DEFUN (debug_pim_packetdump_recv
,
9191 debug_pim_packetdump_recv_cmd
,
9192 "debug pim packet-dump receive",
9195 DEBUG_PIM_PACKETDUMP_STR
9196 DEBUG_PIM_PACKETDUMP_RECV_STR
)
9198 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV
;
9202 DEFUN (no_debug_pim_packetdump_recv
,
9203 no_debug_pim_packetdump_recv_cmd
,
9204 "no debug pim packet-dump receive",
9208 DEBUG_PIM_PACKETDUMP_STR
9209 DEBUG_PIM_PACKETDUMP_RECV_STR
)
9211 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
9215 DEFUN (debug_pim_trace
,
9216 debug_pim_trace_cmd
,
9220 DEBUG_PIM_TRACE_STR
)
9222 PIM_DO_DEBUG_PIM_TRACE
;
9226 DEFUN (debug_pim_trace_detail
,
9227 debug_pim_trace_detail_cmd
,
9228 "debug pim trace detail",
9232 "Detailed Information\n")
9234 PIM_DO_DEBUG_PIM_TRACE_DETAIL
;
9238 DEFUN (no_debug_pim_trace
,
9239 no_debug_pim_trace_cmd
,
9240 "no debug pim trace",
9244 DEBUG_PIM_TRACE_STR
)
9246 PIM_DONT_DEBUG_PIM_TRACE
;
9250 DEFUN (no_debug_pim_trace_detail
,
9251 no_debug_pim_trace_detail_cmd
,
9252 "no debug pim trace detail",
9257 "Detailed Information\n")
9259 PIM_DONT_DEBUG_PIM_TRACE_DETAIL
;
9263 DEFUN (debug_ssmpingd
,
9269 PIM_DO_DEBUG_SSMPINGD
;
9273 DEFUN (no_debug_ssmpingd
,
9274 no_debug_ssmpingd_cmd
,
9275 "no debug ssmpingd",
9280 PIM_DONT_DEBUG_SSMPINGD
;
9284 DEFUN (debug_pim_zebra
,
9285 debug_pim_zebra_cmd
,
9289 DEBUG_PIM_ZEBRA_STR
)
9295 DEFUN (no_debug_pim_zebra
,
9296 no_debug_pim_zebra_cmd
,
9297 "no debug pim zebra",
9301 DEBUG_PIM_ZEBRA_STR
)
9303 PIM_DONT_DEBUG_ZEBRA
;
9307 DEFUN(debug_pim_mlag
, debug_pim_mlag_cmd
, "debug pim mlag",
9308 DEBUG_STR DEBUG_PIM_STR DEBUG_PIM_MLAG_STR
)
9314 DEFUN(no_debug_pim_mlag
, no_debug_pim_mlag_cmd
, "no debug pim mlag",
9315 NO_STR DEBUG_STR DEBUG_PIM_STR DEBUG_PIM_MLAG_STR
)
9317 PIM_DONT_DEBUG_MLAG
;
9321 DEFUN (debug_pim_vxlan
,
9322 debug_pim_vxlan_cmd
,
9326 DEBUG_PIM_VXLAN_STR
)
9332 DEFUN (no_debug_pim_vxlan
,
9333 no_debug_pim_vxlan_cmd
,
9334 "no debug pim vxlan",
9338 DEBUG_PIM_VXLAN_STR
)
9340 PIM_DONT_DEBUG_VXLAN
;
9350 PIM_DO_DEBUG_MSDP_EVENTS
;
9351 PIM_DO_DEBUG_MSDP_PACKETS
;
9355 DEFUN (no_debug_msdp
,
9362 PIM_DONT_DEBUG_MSDP_EVENTS
;
9363 PIM_DONT_DEBUG_MSDP_PACKETS
;
9367 DEFUN (debug_msdp_events
,
9368 debug_msdp_events_cmd
,
9369 "debug msdp events",
9372 DEBUG_MSDP_EVENTS_STR
)
9374 PIM_DO_DEBUG_MSDP_EVENTS
;
9378 DEFUN (no_debug_msdp_events
,
9379 no_debug_msdp_events_cmd
,
9380 "no debug msdp events",
9384 DEBUG_MSDP_EVENTS_STR
)
9386 PIM_DONT_DEBUG_MSDP_EVENTS
;
9390 DEFUN (debug_msdp_packets
,
9391 debug_msdp_packets_cmd
,
9392 "debug msdp packets",
9395 DEBUG_MSDP_PACKETS_STR
)
9397 PIM_DO_DEBUG_MSDP_PACKETS
;
9401 DEFUN (no_debug_msdp_packets
,
9402 no_debug_msdp_packets_cmd
,
9403 "no debug msdp packets",
9407 DEBUG_MSDP_PACKETS_STR
)
9409 PIM_DONT_DEBUG_MSDP_PACKETS
;
9413 DEFUN (debug_mtrace
,
9419 PIM_DO_DEBUG_MTRACE
;
9423 DEFUN (no_debug_mtrace
,
9424 no_debug_mtrace_cmd
,
9430 PIM_DONT_DEBUG_MTRACE
;
9445 DEFUN (no_debug_bsm
,
9458 DEFUN_NOSH (show_debugging_pim
,
9459 show_debugging_pim_cmd
,
9460 "show debugging [pim]",
9465 vty_out(vty
, "PIM debugging status\n");
9467 pim_debug_config_write(vty
);
9472 DEFUN (interface_pim_use_source
,
9473 interface_pim_use_source_cmd
,
9474 "ip pim use-source A.B.C.D",
9477 "Configure primary IP address\n"
9478 "source ip address\n")
9480 nb_cli_enqueue_change(vty
, "./use-source", NB_OP_MODIFY
, argv
[3]->arg
);
9482 return nb_cli_apply_changes(vty
,
9483 "./frr-pim:pim/address-family[address-family='%s']",
9484 "frr-routing:ipv4");
9487 DEFUN (interface_no_pim_use_source
,
9488 interface_no_pim_use_source_cmd
,
9489 "no ip pim use-source [A.B.C.D]",
9493 "Delete source IP address\n"
9494 "source ip address\n")
9496 nb_cli_enqueue_change(vty
, "./use-source", NB_OP_MODIFY
, "0.0.0.0");
9498 return nb_cli_apply_changes(vty
,
9499 "./frr-pim:pim/address-family[address-family='%s']",
9500 "frr-routing:ipv4");
9505 "ip pim bfd [profile BFDPROF$prof]",
9508 "Enables BFD support\n"
9510 "Use BFD profile name\n")
9512 const struct lyd_node
*igmp_enable_dnode
;
9515 yang_dnode_getf(vty
->candidate_config
->dnode
,
9516 "%s/frr-igmp:igmp/igmp-enable", VTY_CURR_XPATH
);
9517 if (!igmp_enable_dnode
)
9518 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
,
9521 if (!yang_dnode_get_bool(igmp_enable_dnode
, "."))
9522 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
,
9526 nb_cli_enqueue_change(vty
, "./bfd", NB_OP_CREATE
, NULL
);
9528 nb_cli_enqueue_change(vty
, "./bfd/profile", NB_OP_MODIFY
, prof
);
9530 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
9533 DEFPY(no_ip_pim_bfd_profile
, no_ip_pim_bfd_profile_cmd
,
9534 "no ip pim bfd profile [BFDPROF]",
9538 "Enables BFD support\n"
9539 "Disable BFD profile\n"
9540 "BFD Profile name\n")
9542 nb_cli_enqueue_change(vty
, "./bfd/profile", NB_OP_DESTROY
, NULL
);
9544 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
9547 DEFUN (no_ip_pim_bfd
,
9553 "Disables BFD support\n")
9555 nb_cli_enqueue_change(vty
, "./bfd", NB_OP_DESTROY
, NULL
);
9557 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
9565 "Enables BSM support on the interface\n")
9567 const struct lyd_node
*igmp_enable_dnode
;
9570 yang_dnode_getf(vty
->candidate_config
->dnode
,
9571 "%s/frr-igmp:igmp/igmp-enable", VTY_CURR_XPATH
);
9572 if (!igmp_enable_dnode
)
9573 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
,
9576 if (!yang_dnode_get_bool(igmp_enable_dnode
, "."))
9577 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
,
9581 nb_cli_enqueue_change(vty
, "./bsm", NB_OP_MODIFY
, "true");
9583 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
9586 DEFUN (no_ip_pim_bsm
,
9592 "Disables BSM support\n")
9594 nb_cli_enqueue_change(vty
, "./bsm", NB_OP_MODIFY
, "false");
9596 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
9599 DEFUN (ip_pim_ucast_bsm
,
9600 ip_pim_ucast_bsm_cmd
,
9601 "ip pim unicast-bsm",
9604 "Accept/Send unicast BSM on the interface\n")
9606 const struct lyd_node
*igmp_enable_dnode
;
9609 yang_dnode_getf(vty
->candidate_config
->dnode
,
9610 "%s/frr-igmp:igmp/igmp-enable", VTY_CURR_XPATH
);
9611 if (!igmp_enable_dnode
)
9612 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
,
9615 if (!yang_dnode_get_bool(igmp_enable_dnode
, "."))
9616 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
,
9620 nb_cli_enqueue_change(vty
, "./unicast-bsm", NB_OP_MODIFY
, "true");
9622 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
9625 DEFUN (no_ip_pim_ucast_bsm
,
9626 no_ip_pim_ucast_bsm_cmd
,
9627 "no ip pim unicast-bsm",
9631 "Block send/receive unicast BSM on this interface\n")
9633 nb_cli_enqueue_change(vty
, "./unicast-bsm", NB_OP_MODIFY
, "false");
9635 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
9641 ip_pim_bfd_param_cmd
,
9642 "ip pim bfd (2-255) (50-60000) (50-60000)",
9645 "Enables BFD support\n"
9646 "Detect Multiplier\n"
9647 "Required min receive interval\n"
9648 "Desired min transmit interval\n")
9652 ip_pim_bfd_param_cmd
,
9653 "ip pim bfd (2-255) (50-60000) (50-60000)",
9656 "Enables BFD support\n"
9657 "Detect Multiplier\n"
9658 "Required min receive interval\n"
9659 "Desired min transmit interval\n")
9660 #endif /* HAVE_BFDD */
9663 int idx_number_2
= 4;
9664 int idx_number_3
= 5;
9665 const struct lyd_node
*igmp_enable_dnode
;
9668 yang_dnode_getf(vty
->candidate_config
->dnode
,
9669 "%s/frr-igmp:igmp/igmp-enable", VTY_CURR_XPATH
);
9670 if (!igmp_enable_dnode
)
9671 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
,
9674 if (!yang_dnode_get_bool(igmp_enable_dnode
, "."))
9675 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
,
9679 nb_cli_enqueue_change(vty
, "./bfd", NB_OP_CREATE
, NULL
);
9680 nb_cli_enqueue_change(vty
, "./bfd/min-rx-interval", NB_OP_MODIFY
,
9681 argv
[idx_number_2
]->arg
);
9682 nb_cli_enqueue_change(vty
, "./bfd/min-tx-interval", NB_OP_MODIFY
,
9683 argv
[idx_number_3
]->arg
);
9684 nb_cli_enqueue_change(vty
, "./bfd/detect_mult", NB_OP_MODIFY
,
9685 argv
[idx_number
]->arg
);
9687 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
9691 ALIAS(no_ip_pim_bfd
, no_ip_pim_bfd_param_cmd
,
9692 "no ip pim bfd (2-255) (50-60000) (50-60000)", NO_STR IP_STR PIM_STR
9693 "Enables BFD support\n"
9694 "Detect Multiplier\n"
9695 "Required min receive interval\n"
9696 "Desired min transmit interval\n")
9697 #endif /* !HAVE_BFDD */
9699 DEFPY(ip_msdp_peer
, ip_msdp_peer_cmd
,
9700 "ip msdp peer A.B.C.D$peer source A.B.C.D$source",
9703 "Configure MSDP peer\n"
9705 "Source address for TCP connection\n"
9706 "Local IP address\n")
9708 const char *vrfname
;
9709 char temp_xpath
[XPATH_MAXLEN
];
9710 char msdp_peer_source_xpath
[XPATH_MAXLEN
];
9712 vrfname
= pim_cli_get_vrf_name(vty
);
9713 if (vrfname
== NULL
)
9714 return CMD_WARNING_CONFIG_FAILED
;
9716 snprintf(msdp_peer_source_xpath
, sizeof(msdp_peer_source_xpath
),
9717 FRR_PIM_AF_XPATH
, "frr-pim:pimd", "pim", vrfname
,
9718 "frr-routing:ipv4");
9719 snprintf(temp_xpath
, sizeof(temp_xpath
),
9720 "/msdp-peer[peer-ip='%s']/source-ip", peer_str
);
9721 strlcat(msdp_peer_source_xpath
, temp_xpath
,
9722 sizeof(msdp_peer_source_xpath
));
9724 nb_cli_enqueue_change(vty
, msdp_peer_source_xpath
, NB_OP_MODIFY
,
9727 return nb_cli_apply_changes(vty
, NULL
);
9730 DEFPY(ip_msdp_timers
, ip_msdp_timers_cmd
,
9731 "ip msdp timers (2-600)$keepalive (3-600)$holdtime [(1-600)$connretry]",
9734 "MSDP timers configuration\n"
9735 "Keep alive period (in seconds)\n"
9736 "Hold time period (in seconds)\n"
9737 "Connection retry period (in seconds)\n")
9739 const char *vrfname
;
9740 char xpath
[XPATH_MAXLEN
];
9742 vrfname
= pim_cli_get_vrf_name(vty
);
9743 if (vrfname
== NULL
)
9744 return CMD_WARNING_CONFIG_FAILED
;
9746 snprintf(xpath
, sizeof(xpath
), FRR_PIM_MSDP_XPATH
, "frr-pim:pimd",
9747 "pim", vrfname
, "frr-routing:ipv4");
9748 nb_cli_enqueue_change(vty
, "./hold-time", NB_OP_MODIFY
, holdtime_str
);
9749 nb_cli_enqueue_change(vty
, "./keep-alive", NB_OP_MODIFY
, keepalive_str
);
9751 nb_cli_enqueue_change(vty
, "./connection-retry", NB_OP_MODIFY
,
9754 nb_cli_enqueue_change(vty
, "./connection-retry", NB_OP_DESTROY
,
9757 nb_cli_apply_changes(vty
, xpath
);
9762 DEFUN (no_ip_msdp_peer
,
9763 no_ip_msdp_peer_cmd
,
9764 "no ip msdp peer A.B.C.D",
9768 "Delete MSDP peer\n"
9769 "peer ip address\n")
9771 const char *vrfname
;
9772 char msdp_peer_xpath
[XPATH_MAXLEN
];
9773 char temp_xpath
[XPATH_MAXLEN
];
9775 vrfname
= pim_cli_get_vrf_name(vty
);
9776 if (vrfname
== NULL
)
9777 return CMD_WARNING_CONFIG_FAILED
;
9779 snprintf(msdp_peer_xpath
, sizeof(msdp_peer_xpath
),
9781 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4");
9782 snprintf(temp_xpath
, sizeof(temp_xpath
),
9783 "/msdp-peer[peer-ip='%s']",
9786 strlcat(msdp_peer_xpath
, temp_xpath
, sizeof(msdp_peer_xpath
));
9788 nb_cli_enqueue_change(vty
, msdp_peer_xpath
, NB_OP_DESTROY
, NULL
);
9790 return nb_cli_apply_changes(vty
, NULL
);
9793 DEFPY(ip_msdp_mesh_group_member
,
9794 ip_msdp_mesh_group_member_cmd
,
9795 "ip msdp mesh-group WORD$gname member A.B.C.D$maddr",
9798 "Configure MSDP mesh-group\n"
9800 "Mesh group member\n"
9801 "Peer IP address\n")
9803 const char *vrfname
;
9804 char xpath_value
[XPATH_MAXLEN
];
9806 vrfname
= pim_cli_get_vrf_name(vty
);
9807 if (vrfname
== NULL
)
9808 return CMD_WARNING_CONFIG_FAILED
;
9810 /* Create mesh group. */
9811 snprintf(xpath_value
, sizeof(xpath_value
),
9812 FRR_PIM_AF_XPATH
"/msdp-mesh-groups[name='%s']",
9813 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4", gname
);
9814 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_CREATE
, NULL
);
9816 /* Create mesh group member. */
9817 strlcat(xpath_value
, "/members[address='", sizeof(xpath_value
));
9818 strlcat(xpath_value
, maddr_str
, sizeof(xpath_value
));
9819 strlcat(xpath_value
, "']", sizeof(xpath_value
));
9820 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_CREATE
, NULL
);
9822 return nb_cli_apply_changes(vty
, NULL
);
9825 DEFPY(no_ip_msdp_mesh_group_member
,
9826 no_ip_msdp_mesh_group_member_cmd
,
9827 "no ip msdp mesh-group WORD$gname member A.B.C.D$maddr",
9831 "Delete MSDP mesh-group member\n"
9833 "Mesh group member\n"
9834 "Peer IP address\n")
9836 const char *vrfname
;
9837 char xpath_value
[XPATH_MAXLEN
];
9838 char xpath_member_value
[XPATH_MAXLEN
];
9840 vrfname
= pim_cli_get_vrf_name(vty
);
9841 if (vrfname
== NULL
)
9842 return CMD_WARNING_CONFIG_FAILED
;
9844 /* Get mesh group base XPath. */
9845 snprintf(xpath_value
, sizeof(xpath_value
),
9846 FRR_PIM_AF_XPATH
"/msdp-mesh-groups[name='%s']",
9847 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4", gname
);
9849 if (!yang_dnode_exists(vty
->candidate_config
->dnode
, xpath_value
)) {
9850 vty_out(vty
, "%% mesh-group does not exist\n");
9851 return CMD_WARNING_CONFIG_FAILED
;
9854 /* Remove mesh group member. */
9855 strlcpy(xpath_member_value
, xpath_value
, sizeof(xpath_member_value
));
9856 strlcat(xpath_member_value
, "/members[address='",
9857 sizeof(xpath_member_value
));
9858 strlcat(xpath_member_value
, maddr_str
, sizeof(xpath_member_value
));
9859 strlcat(xpath_member_value
, "']", sizeof(xpath_member_value
));
9860 if (!yang_dnode_exists(vty
->candidate_config
->dnode
,
9861 xpath_member_value
)) {
9862 vty_out(vty
, "%% mesh-group member does not exist\n");
9863 return CMD_WARNING_CONFIG_FAILED
;
9866 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_DESTROY
, NULL
);
9869 * If this is the last member, then we must remove the group altogether
9870 * to not break legacy CLI behaviour.
9872 pim_cli_legacy_mesh_group_behavior(vty
, gname
);
9874 return nb_cli_apply_changes(vty
, NULL
);
9877 DEFPY(ip_msdp_mesh_group_source
,
9878 ip_msdp_mesh_group_source_cmd
,
9879 "ip msdp mesh-group WORD$gname source A.B.C.D$saddr",
9882 "Configure MSDP mesh-group\n"
9884 "Mesh group local address\n"
9885 "Source IP address for the TCP connection\n")
9887 const char *vrfname
;
9888 char xpath_value
[XPATH_MAXLEN
];
9890 vrfname
= pim_cli_get_vrf_name(vty
);
9891 if (vrfname
== NULL
)
9892 return CMD_WARNING_CONFIG_FAILED
;
9894 /* Create mesh group. */
9895 snprintf(xpath_value
, sizeof(xpath_value
),
9896 FRR_PIM_AF_XPATH
"/msdp-mesh-groups[name='%s']",
9897 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4", gname
);
9898 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_CREATE
, NULL
);
9900 /* Create mesh group member. */
9901 strlcat(xpath_value
, "/source", sizeof(xpath_value
));
9902 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_MODIFY
, saddr_str
);
9904 return nb_cli_apply_changes(vty
, NULL
);
9907 DEFPY(no_ip_msdp_mesh_group_source
,
9908 no_ip_msdp_mesh_group_source_cmd
,
9909 "no ip msdp mesh-group WORD$gname source [A.B.C.D]",
9913 "Delete MSDP mesh-group source\n"
9915 "Mesh group source\n"
9916 "Mesh group local address\n")
9918 const char *vrfname
;
9919 char xpath_value
[XPATH_MAXLEN
];
9921 vrfname
= pim_cli_get_vrf_name(vty
);
9922 if (vrfname
== NULL
)
9923 return CMD_WARNING_CONFIG_FAILED
;
9925 /* Get mesh group base XPath. */
9926 snprintf(xpath_value
, sizeof(xpath_value
),
9927 FRR_PIM_AF_XPATH
"/msdp-mesh-groups[name='%s']",
9928 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4", gname
);
9929 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_CREATE
, NULL
);
9931 /* Create mesh group member. */
9932 strlcat(xpath_value
, "/source", sizeof(xpath_value
));
9933 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_DESTROY
, NULL
);
9936 * If this is the last member, then we must remove the group altogether
9937 * to not break legacy CLI behaviour.
9939 pim_cli_legacy_mesh_group_behavior(vty
, gname
);
9941 return nb_cli_apply_changes(vty
, NULL
);
9944 DEFPY(no_ip_msdp_mesh_group
,
9945 no_ip_msdp_mesh_group_cmd
,
9946 "no ip msdp mesh-group WORD$gname",
9950 "Delete MSDP mesh-group\n"
9953 const char *vrfname
;
9954 char xpath_value
[XPATH_MAXLEN
];
9956 vrfname
= pim_cli_get_vrf_name(vty
);
9957 if (vrfname
== NULL
)
9958 return CMD_WARNING_CONFIG_FAILED
;
9960 /* Get mesh group base XPath. */
9961 snprintf(xpath_value
, sizeof(xpath_value
),
9962 FRR_PIM_AF_XPATH
"/msdp-mesh-groups[name='%s']",
9963 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4", gname
);
9964 if (!yang_dnode_exists(vty
->candidate_config
->dnode
, xpath_value
))
9967 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_DESTROY
, NULL
);
9968 return nb_cli_apply_changes(vty
, NULL
);
9971 static void ip_msdp_show_mesh_group(struct vty
*vty
, struct pim_msdp_mg
*mg
,
9972 struct json_object
*json
)
9974 struct listnode
*mbrnode
;
9975 struct pim_msdp_mg_mbr
*mbr
;
9976 char mbr_str
[INET_ADDRSTRLEN
];
9977 char src_str
[INET_ADDRSTRLEN
];
9978 char state_str
[PIM_MSDP_STATE_STRLEN
];
9979 enum pim_msdp_peer_state state
;
9980 json_object
*json_mg_row
= NULL
;
9981 json_object
*json_members
= NULL
;
9982 json_object
*json_row
= NULL
;
9984 pim_inet4_dump("<source?>", mg
->src_ip
, src_str
, sizeof(src_str
));
9986 /* currently there is only one mesh group but we should still
9988 * it a dict with mg-name as key */
9989 json_mg_row
= json_object_new_object();
9990 json_object_string_add(json_mg_row
, "name",
9991 mg
->mesh_group_name
);
9992 json_object_string_add(json_mg_row
, "source", src_str
);
9994 vty_out(vty
, "Mesh group : %s\n", mg
->mesh_group_name
);
9995 vty_out(vty
, " Source : %s\n", src_str
);
9996 vty_out(vty
, " Member State\n");
9999 for (ALL_LIST_ELEMENTS_RO(mg
->mbr_list
, mbrnode
, mbr
)) {
10000 pim_inet4_dump("<mbr?>", mbr
->mbr_ip
, mbr_str
, sizeof(mbr_str
));
10002 state
= mbr
->mp
->state
;
10004 state
= PIM_MSDP_DISABLED
;
10006 pim_msdp_state_dump(state
, state_str
, sizeof(state_str
));
10008 json_row
= json_object_new_object();
10009 json_object_string_add(json_row
, "member", mbr_str
);
10010 json_object_string_add(json_row
, "state", state_str
);
10011 if (!json_members
) {
10012 json_members
= json_object_new_object();
10013 json_object_object_add(json_mg_row
, "members",
10016 json_object_object_add(json_members
, mbr_str
, json_row
);
10018 vty_out(vty
, " %-15s %11s\n", mbr_str
, state_str
);
10023 json_object_object_add(json
, mg
->mesh_group_name
, json_mg_row
);
10026 DEFUN (show_ip_msdp_mesh_group
,
10027 show_ip_msdp_mesh_group_cmd
,
10028 "show ip msdp [vrf NAME] mesh-group [json]",
10033 "MSDP mesh-group information\n"
10036 bool uj
= use_json(argc
, argv
);
10038 struct pim_msdp_mg
*mg
;
10039 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10040 struct pim_instance
*pim
= vrf
->info
;
10041 struct json_object
*json
= NULL
;
10044 return CMD_WARNING
;
10046 /* Quick case: list is empty. */
10047 if (SLIST_EMPTY(&pim
->msdp
.mglist
)) {
10049 vty_out(vty
, "{}\n");
10051 return CMD_SUCCESS
;
10055 json
= json_object_new_object();
10057 SLIST_FOREACH (mg
, &pim
->msdp
.mglist
, mg_entry
)
10058 ip_msdp_show_mesh_group(vty
, mg
, json
);
10061 vty_out(vty
, "%s\n",
10062 json_object_to_json_string_ext(
10063 json
, JSON_C_TO_STRING_PRETTY
));
10064 json_object_free(json
);
10067 return CMD_SUCCESS
;
10070 DEFUN (show_ip_msdp_mesh_group_vrf_all
,
10071 show_ip_msdp_mesh_group_vrf_all_cmd
,
10072 "show ip msdp vrf all mesh-group [json]",
10077 "MSDP mesh-group information\n"
10080 bool uj
= use_json(argc
, argv
);
10081 struct json_object
*json
= NULL
, *vrf_json
= NULL
;
10082 struct pim_instance
*pim
;
10083 struct pim_msdp_mg
*mg
;
10087 json
= json_object_new_object();
10089 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
10091 vrf_json
= json_object_new_object();
10092 json_object_object_add(json
, vrf
->name
, vrf_json
);
10094 vty_out(vty
, "VRF: %s\n", vrf
->name
);
10097 SLIST_FOREACH (mg
, &pim
->msdp
.mglist
, mg_entry
)
10098 ip_msdp_show_mesh_group(vty
, mg
, vrf_json
);
10102 vty_out(vty
, "%s\n",
10103 json_object_to_json_string_ext(
10104 json
, JSON_C_TO_STRING_PRETTY
));
10105 json_object_free(json
);
10108 return CMD_SUCCESS
;
10111 static void ip_msdp_show_peers(struct pim_instance
*pim
, struct vty
*vty
,
10114 struct listnode
*mpnode
;
10115 struct pim_msdp_peer
*mp
;
10116 char peer_str
[INET_ADDRSTRLEN
];
10117 char local_str
[INET_ADDRSTRLEN
];
10118 char state_str
[PIM_MSDP_STATE_STRLEN
];
10119 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
10121 json_object
*json
= NULL
;
10122 json_object
*json_row
= NULL
;
10126 json
= json_object_new_object();
10129 "Peer Local State Uptime SaCnt\n");
10132 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
10133 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
10134 now
= pim_time_monotonic_sec();
10135 pim_time_uptime(timebuf
, sizeof(timebuf
),
10138 strlcpy(timebuf
, "-", sizeof(timebuf
));
10140 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
10141 pim_inet4_dump("<local?>", mp
->local
, local_str
,
10142 sizeof(local_str
));
10143 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
10145 json_row
= json_object_new_object();
10146 json_object_string_add(json_row
, "peer", peer_str
);
10147 json_object_string_add(json_row
, "local", local_str
);
10148 json_object_string_add(json_row
, "state", state_str
);
10149 json_object_string_add(json_row
, "upTime", timebuf
);
10150 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
10151 json_object_object_add(json
, peer_str
, json_row
);
10153 vty_out(vty
, "%-15s %15s %11s %8s %6d\n", peer_str
,
10154 local_str
, state_str
, timebuf
, mp
->sa_cnt
);
10159 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10160 json
, JSON_C_TO_STRING_PRETTY
));
10161 json_object_free(json
);
10165 static void ip_msdp_show_peers_detail(struct pim_instance
*pim
, struct vty
*vty
,
10166 const char *peer
, bool uj
)
10168 struct listnode
*mpnode
;
10169 struct pim_msdp_peer
*mp
;
10170 char peer_str
[INET_ADDRSTRLEN
];
10171 char local_str
[INET_ADDRSTRLEN
];
10172 char state_str
[PIM_MSDP_STATE_STRLEN
];
10173 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
10174 char katimer
[PIM_MSDP_TIMER_STRLEN
];
10175 char crtimer
[PIM_MSDP_TIMER_STRLEN
];
10176 char holdtimer
[PIM_MSDP_TIMER_STRLEN
];
10178 json_object
*json
= NULL
;
10179 json_object
*json_row
= NULL
;
10182 json
= json_object_new_object();
10185 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
10186 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
10187 if (strcmp(peer
, "detail") && strcmp(peer
, peer_str
))
10190 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
10191 now
= pim_time_monotonic_sec();
10192 pim_time_uptime(timebuf
, sizeof(timebuf
),
10195 strlcpy(timebuf
, "-", sizeof(timebuf
));
10197 pim_inet4_dump("<local?>", mp
->local
, local_str
,
10198 sizeof(local_str
));
10199 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
10200 pim_time_timer_to_hhmmss(katimer
, sizeof(katimer
),
10202 pim_time_timer_to_hhmmss(crtimer
, sizeof(crtimer
),
10204 pim_time_timer_to_hhmmss(holdtimer
, sizeof(holdtimer
),
10208 json_row
= json_object_new_object();
10209 json_object_string_add(json_row
, "peer", peer_str
);
10210 json_object_string_add(json_row
, "local", local_str
);
10211 if (mp
->flags
& PIM_MSDP_PEERF_IN_GROUP
)
10212 json_object_string_add(json_row
,
10214 mp
->mesh_group_name
);
10215 json_object_string_add(json_row
, "state", state_str
);
10216 json_object_string_add(json_row
, "upTime", timebuf
);
10217 json_object_string_add(json_row
, "keepAliveTimer",
10219 json_object_string_add(json_row
, "connRetryTimer",
10221 json_object_string_add(json_row
, "holdTimer",
10223 json_object_string_add(json_row
, "lastReset",
10225 json_object_int_add(json_row
, "connAttempts",
10226 mp
->conn_attempts
);
10227 json_object_int_add(json_row
, "establishedChanges",
10229 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
10230 json_object_int_add(json_row
, "kaSent", mp
->ka_tx_cnt
);
10231 json_object_int_add(json_row
, "kaRcvd", mp
->ka_rx_cnt
);
10232 json_object_int_add(json_row
, "saSent", mp
->sa_tx_cnt
);
10233 json_object_int_add(json_row
, "saRcvd", mp
->sa_rx_cnt
);
10234 json_object_object_add(json
, peer_str
, json_row
);
10236 vty_out(vty
, "Peer : %s\n", peer_str
);
10237 vty_out(vty
, " Local : %s\n", local_str
);
10238 if (mp
->flags
& PIM_MSDP_PEERF_IN_GROUP
)
10239 vty_out(vty
, " Mesh Group : %s\n",
10240 mp
->mesh_group_name
);
10241 vty_out(vty
, " State : %s\n", state_str
);
10242 vty_out(vty
, " Uptime : %s\n", timebuf
);
10244 vty_out(vty
, " Keepalive Timer : %s\n", katimer
);
10245 vty_out(vty
, " Conn Retry Timer : %s\n", crtimer
);
10246 vty_out(vty
, " Hold Timer : %s\n", holdtimer
);
10247 vty_out(vty
, " Last Reset : %s\n",
10249 vty_out(vty
, " Conn Attempts : %d\n",
10250 mp
->conn_attempts
);
10251 vty_out(vty
, " Established Changes : %d\n",
10253 vty_out(vty
, " SA Count : %d\n",
10255 vty_out(vty
, " Statistics :\n");
10258 vty_out(vty
, " Keepalives : %10d %10d\n",
10259 mp
->ka_tx_cnt
, mp
->ka_rx_cnt
);
10260 vty_out(vty
, " SAs : %10d %10d\n",
10261 mp
->sa_tx_cnt
, mp
->sa_rx_cnt
);
10262 vty_out(vty
, "\n");
10267 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10268 json
, JSON_C_TO_STRING_PRETTY
));
10269 json_object_free(json
);
10273 DEFUN (show_ip_msdp_peer_detail
,
10274 show_ip_msdp_peer_detail_cmd
,
10275 "show ip msdp [vrf NAME] peer [detail|A.B.C.D] [json]",
10280 "MSDP peer information\n"
10281 "Detailed output\n"
10282 "peer ip address\n"
10285 bool uj
= use_json(argc
, argv
);
10287 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10290 return CMD_WARNING
;
10294 if (argv_find(argv
, argc
, "detail", &idx
))
10295 arg
= argv
[idx
]->text
;
10296 else if (argv_find(argv
, argc
, "A.B.C.D", &idx
))
10297 arg
= argv
[idx
]->arg
;
10300 ip_msdp_show_peers_detail(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
10302 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
10304 return CMD_SUCCESS
;
10307 DEFUN (show_ip_msdp_peer_detail_vrf_all
,
10308 show_ip_msdp_peer_detail_vrf_all_cmd
,
10309 "show ip msdp vrf all peer [detail|A.B.C.D] [json]",
10314 "MSDP peer information\n"
10315 "Detailed output\n"
10316 "peer ip address\n"
10320 bool uj
= use_json(argc
, argv
);
10325 vty_out(vty
, "{ ");
10326 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
10329 vty_out(vty
, ", ");
10330 vty_out(vty
, " \"%s\": ", vrf
->name
);
10333 vty_out(vty
, "VRF: %s\n", vrf
->name
);
10334 if (argv_find(argv
, argc
, "detail", &idx
)
10335 || argv_find(argv
, argc
, "A.B.C.D", &idx
))
10336 ip_msdp_show_peers_detail(vrf
->info
, vty
,
10337 argv
[idx
]->arg
, uj
);
10339 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
10342 vty_out(vty
, "}\n");
10344 return CMD_SUCCESS
;
10347 static void ip_msdp_show_sa(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
10349 struct listnode
*sanode
;
10350 struct pim_msdp_sa
*sa
;
10351 char src_str
[INET_ADDRSTRLEN
];
10352 char grp_str
[INET_ADDRSTRLEN
];
10353 char rp_str
[INET_ADDRSTRLEN
];
10354 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
10358 json_object
*json
= NULL
;
10359 json_object
*json_group
= NULL
;
10360 json_object
*json_row
= NULL
;
10363 json
= json_object_new_object();
10366 "Source Group RP Local SPT Uptime\n");
10369 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
10370 now
= pim_time_monotonic_sec();
10371 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
10372 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
10373 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
10374 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
10375 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
10377 strlcpy(spt_str
, "yes", sizeof(spt_str
));
10379 strlcpy(spt_str
, "no", sizeof(spt_str
));
10382 strlcpy(rp_str
, "-", sizeof(rp_str
));
10383 strlcpy(spt_str
, "-", sizeof(spt_str
));
10385 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
10386 strlcpy(local_str
, "yes", sizeof(local_str
));
10388 strlcpy(local_str
, "no", sizeof(local_str
));
10391 json_object_object_get_ex(json
, grp_str
, &json_group
);
10394 json_group
= json_object_new_object();
10395 json_object_object_add(json
, grp_str
,
10399 json_row
= json_object_new_object();
10400 json_object_string_add(json_row
, "source", src_str
);
10401 json_object_string_add(json_row
, "group", grp_str
);
10402 json_object_string_add(json_row
, "rp", rp_str
);
10403 json_object_string_add(json_row
, "local", local_str
);
10404 json_object_string_add(json_row
, "sptSetup", spt_str
);
10405 json_object_string_add(json_row
, "upTime", timebuf
);
10406 json_object_object_add(json_group
, src_str
, json_row
);
10408 vty_out(vty
, "%-15s %15s %15s %5c %3c %8s\n",
10409 src_str
, grp_str
, rp_str
, local_str
[0],
10410 spt_str
[0], timebuf
);
10415 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10416 json
, JSON_C_TO_STRING_PRETTY
));
10417 json_object_free(json
);
10421 static void ip_msdp_show_sa_entry_detail(struct pim_msdp_sa
*sa
,
10422 const char *src_str
,
10423 const char *grp_str
, struct vty
*vty
,
10424 bool uj
, json_object
*json
)
10426 char rp_str
[INET_ADDRSTRLEN
];
10427 char peer_str
[INET_ADDRSTRLEN
];
10428 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
10431 char statetimer
[PIM_MSDP_TIMER_STRLEN
];
10433 json_object
*json_group
= NULL
;
10434 json_object
*json_row
= NULL
;
10436 now
= pim_time_monotonic_sec();
10437 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
10438 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
10439 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
10440 pim_inet4_dump("<peer?>", sa
->peer
, peer_str
, sizeof(peer_str
));
10442 strlcpy(spt_str
, "yes", sizeof(spt_str
));
10444 strlcpy(spt_str
, "no", sizeof(spt_str
));
10447 strlcpy(rp_str
, "-", sizeof(rp_str
));
10448 strlcpy(peer_str
, "-", sizeof(peer_str
));
10449 strlcpy(spt_str
, "-", sizeof(spt_str
));
10451 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
10452 strlcpy(local_str
, "yes", sizeof(local_str
));
10454 strlcpy(local_str
, "no", sizeof(local_str
));
10456 pim_time_timer_to_hhmmss(statetimer
, sizeof(statetimer
),
10457 sa
->sa_state_timer
);
10459 json_object_object_get_ex(json
, grp_str
, &json_group
);
10462 json_group
= json_object_new_object();
10463 json_object_object_add(json
, grp_str
, json_group
);
10466 json_row
= json_object_new_object();
10467 json_object_string_add(json_row
, "source", src_str
);
10468 json_object_string_add(json_row
, "group", grp_str
);
10469 json_object_string_add(json_row
, "rp", rp_str
);
10470 json_object_string_add(json_row
, "local", local_str
);
10471 json_object_string_add(json_row
, "sptSetup", spt_str
);
10472 json_object_string_add(json_row
, "upTime", timebuf
);
10473 json_object_string_add(json_row
, "stateTimer", statetimer
);
10474 json_object_object_add(json_group
, src_str
, json_row
);
10476 vty_out(vty
, "SA : %s\n", sa
->sg_str
);
10477 vty_out(vty
, " RP : %s\n", rp_str
);
10478 vty_out(vty
, " Peer : %s\n", peer_str
);
10479 vty_out(vty
, " Local : %s\n", local_str
);
10480 vty_out(vty
, " SPT Setup : %s\n", spt_str
);
10481 vty_out(vty
, " Uptime : %s\n", timebuf
);
10482 vty_out(vty
, " State Timer : %s\n", statetimer
);
10483 vty_out(vty
, "\n");
10487 static void ip_msdp_show_sa_detail(struct pim_instance
*pim
, struct vty
*vty
,
10490 struct listnode
*sanode
;
10491 struct pim_msdp_sa
*sa
;
10492 char src_str
[INET_ADDRSTRLEN
];
10493 char grp_str
[INET_ADDRSTRLEN
];
10494 json_object
*json
= NULL
;
10497 json
= json_object_new_object();
10500 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
10501 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
10502 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
10503 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
, uj
,
10508 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10509 json
, JSON_C_TO_STRING_PRETTY
));
10510 json_object_free(json
);
10514 DEFUN (show_ip_msdp_sa_detail
,
10515 show_ip_msdp_sa_detail_cmd
,
10516 "show ip msdp [vrf NAME] sa detail [json]",
10521 "MSDP active-source information\n"
10522 "Detailed output\n"
10525 bool uj
= use_json(argc
, argv
);
10527 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10530 return CMD_WARNING
;
10532 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
10534 return CMD_SUCCESS
;
10537 DEFUN (show_ip_msdp_sa_detail_vrf_all
,
10538 show_ip_msdp_sa_detail_vrf_all_cmd
,
10539 "show ip msdp vrf all sa detail [json]",
10544 "MSDP active-source information\n"
10545 "Detailed output\n"
10548 bool uj
= use_json(argc
, argv
);
10553 vty_out(vty
, "{ ");
10554 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
10557 vty_out(vty
, ", ");
10558 vty_out(vty
, " \"%s\": ", vrf
->name
);
10561 vty_out(vty
, "VRF: %s\n", vrf
->name
);
10562 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
10565 vty_out(vty
, "}\n");
10567 return CMD_SUCCESS
;
10570 static void ip_msdp_show_sa_addr(struct pim_instance
*pim
, struct vty
*vty
,
10571 const char *addr
, bool uj
)
10573 struct listnode
*sanode
;
10574 struct pim_msdp_sa
*sa
;
10575 char src_str
[INET_ADDRSTRLEN
];
10576 char grp_str
[INET_ADDRSTRLEN
];
10577 json_object
*json
= NULL
;
10580 json
= json_object_new_object();
10583 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
10584 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
10585 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
10586 if (!strcmp(addr
, src_str
) || !strcmp(addr
, grp_str
)) {
10587 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
10593 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10594 json
, JSON_C_TO_STRING_PRETTY
));
10595 json_object_free(json
);
10599 static void ip_msdp_show_sa_sg(struct pim_instance
*pim
, struct vty
*vty
,
10600 const char *src
, const char *grp
, bool uj
)
10602 struct listnode
*sanode
;
10603 struct pim_msdp_sa
*sa
;
10604 char src_str
[INET_ADDRSTRLEN
];
10605 char grp_str
[INET_ADDRSTRLEN
];
10606 json_object
*json
= NULL
;
10609 json
= json_object_new_object();
10612 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
10613 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
10614 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
10615 if (!strcmp(src
, src_str
) && !strcmp(grp
, grp_str
)) {
10616 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
10622 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10623 json
, JSON_C_TO_STRING_PRETTY
));
10624 json_object_free(json
);
10628 DEFUN (show_ip_msdp_sa_sg
,
10629 show_ip_msdp_sa_sg_cmd
,
10630 "show ip msdp [vrf NAME] sa [A.B.C.D [A.B.C.D]] [json]",
10635 "MSDP active-source information\n"
10636 "source or group ip\n"
10640 bool uj
= use_json(argc
, argv
);
10644 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10647 return CMD_WARNING
;
10649 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
10651 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
10655 if (src_ip
&& grp_ip
)
10656 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
10658 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
10660 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
10662 return CMD_SUCCESS
;
10665 DEFUN (show_ip_msdp_sa_sg_vrf_all
,
10666 show_ip_msdp_sa_sg_vrf_all_cmd
,
10667 "show ip msdp vrf all sa [A.B.C.D [A.B.C.D]] [json]",
10672 "MSDP active-source information\n"
10673 "source or group ip\n"
10677 bool uj
= use_json(argc
, argv
);
10682 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
10684 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
10689 vty_out(vty
, "{ ");
10690 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
10693 vty_out(vty
, ", ");
10694 vty_out(vty
, " \"%s\": ", vrf
->name
);
10697 vty_out(vty
, "VRF: %s\n", vrf
->name
);
10699 if (src_ip
&& grp_ip
)
10700 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
10702 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
10704 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
10707 vty_out(vty
, "}\n");
10709 return CMD_SUCCESS
;
10712 struct pim_sg_cache_walk_data
{
10715 json_object
*json_group
;
10716 struct in_addr addr
;
10720 static void pim_show_vxlan_sg_entry(struct pim_vxlan_sg
*vxlan_sg
,
10721 struct pim_sg_cache_walk_data
*cwd
)
10723 struct vty
*vty
= cwd
->vty
;
10724 json_object
*json
= cwd
->json
;
10725 char src_str
[INET_ADDRSTRLEN
];
10726 char grp_str
[INET_ADDRSTRLEN
];
10727 json_object
*json_row
;
10728 bool installed
= (vxlan_sg
->up
) ? true : false;
10729 const char *iif_name
= vxlan_sg
->iif
?vxlan_sg
->iif
->name
:"-";
10730 const char *oif_name
;
10732 if (pim_vxlan_is_orig_mroute(vxlan_sg
))
10733 oif_name
= vxlan_sg
->orig_oif
?vxlan_sg
->orig_oif
->name
:"";
10735 oif_name
= vxlan_sg
->term_oif
?vxlan_sg
->term_oif
->name
:"";
10737 if (cwd
->addr_match
&& (vxlan_sg
->sg
.src
.s_addr
!= cwd
->addr
.s_addr
) &&
10738 (vxlan_sg
->sg
.grp
.s_addr
!= cwd
->addr
.s_addr
)) {
10741 pim_inet4_dump("<src?>", vxlan_sg
->sg
.src
, src_str
, sizeof(src_str
));
10742 pim_inet4_dump("<grp?>", vxlan_sg
->sg
.grp
, grp_str
, sizeof(grp_str
));
10744 json_object_object_get_ex(json
, grp_str
, &cwd
->json_group
);
10746 if (!cwd
->json_group
) {
10747 cwd
->json_group
= json_object_new_object();
10748 json_object_object_add(json
, grp_str
,
10752 json_row
= json_object_new_object();
10753 json_object_string_add(json_row
, "source", src_str
);
10754 json_object_string_add(json_row
, "group", grp_str
);
10755 json_object_string_add(json_row
, "input", iif_name
);
10756 json_object_string_add(json_row
, "output", oif_name
);
10758 json_object_boolean_true_add(json_row
, "installed");
10760 json_object_boolean_false_add(json_row
, "installed");
10761 json_object_object_add(cwd
->json_group
, src_str
, json_row
);
10763 vty_out(vty
, "%-15s %-15s %-15s %-15s %-5s\n",
10764 src_str
, grp_str
, iif_name
, oif_name
,
10769 static void pim_show_vxlan_sg_hash_entry(struct hash_bucket
*bucket
, void *arg
)
10771 pim_show_vxlan_sg_entry((struct pim_vxlan_sg
*)bucket
->data
,
10772 (struct pim_sg_cache_walk_data
*)arg
);
10775 static void pim_show_vxlan_sg(struct pim_instance
*pim
,
10776 struct vty
*vty
, bool uj
)
10778 json_object
*json
= NULL
;
10779 struct pim_sg_cache_walk_data cwd
;
10782 json
= json_object_new_object();
10784 vty_out(vty
, "Codes: I -> installed\n");
10786 "Source Group Input Output Flags\n");
10789 memset(&cwd
, 0, sizeof(cwd
));
10792 hash_iterate(pim
->vxlan
.sg_hash
, pim_show_vxlan_sg_hash_entry
, &cwd
);
10795 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10796 json
, JSON_C_TO_STRING_PRETTY
));
10797 json_object_free(json
);
10801 static void pim_show_vxlan_sg_match_addr(struct pim_instance
*pim
,
10802 struct vty
*vty
, char *addr_str
,
10805 json_object
*json
= NULL
;
10806 struct pim_sg_cache_walk_data cwd
;
10809 memset(&cwd
, 0, sizeof(cwd
));
10810 result
= inet_pton(AF_INET
, addr_str
, &cwd
.addr
);
10812 vty_out(vty
, "Bad address %s: errno=%d: %s\n", addr_str
,
10813 errno
, safe_strerror(errno
));
10818 json
= json_object_new_object();
10820 vty_out(vty
, "Codes: I -> installed\n");
10822 "Source Group Input Output Flags\n");
10827 cwd
.addr_match
= true;
10828 hash_iterate(pim
->vxlan
.sg_hash
, pim_show_vxlan_sg_hash_entry
, &cwd
);
10831 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10832 json
, JSON_C_TO_STRING_PRETTY
));
10833 json_object_free(json
);
10837 static void pim_show_vxlan_sg_one(struct pim_instance
*pim
,
10838 struct vty
*vty
, char *src_str
, char *grp_str
,
10841 json_object
*json
= NULL
;
10842 struct prefix_sg sg
;
10844 struct pim_vxlan_sg
*vxlan_sg
;
10845 const char *iif_name
;
10847 const char *oif_name
;
10849 result
= inet_pton(AF_INET
, src_str
, &sg
.src
);
10851 vty_out(vty
, "Bad src address %s: errno=%d: %s\n", src_str
,
10852 errno
, safe_strerror(errno
));
10855 result
= inet_pton(AF_INET
, grp_str
, &sg
.grp
);
10857 vty_out(vty
, "Bad grp address %s: errno=%d: %s\n", grp_str
,
10858 errno
, safe_strerror(errno
));
10862 sg
.family
= AF_INET
;
10863 sg
.prefixlen
= IPV4_MAX_BITLEN
;
10865 json
= json_object_new_object();
10867 vxlan_sg
= pim_vxlan_sg_find(pim
, &sg
);
10869 installed
= (vxlan_sg
->up
) ? true : false;
10870 iif_name
= vxlan_sg
->iif
?vxlan_sg
->iif
->name
:"-";
10872 if (pim_vxlan_is_orig_mroute(vxlan_sg
))
10874 vxlan_sg
->orig_oif
?vxlan_sg
->orig_oif
->name
:"";
10877 vxlan_sg
->term_oif
?vxlan_sg
->term_oif
->name
:"";
10880 json_object_string_add(json
, "source", src_str
);
10881 json_object_string_add(json
, "group", grp_str
);
10882 json_object_string_add(json
, "input", iif_name
);
10883 json_object_string_add(json
, "output", oif_name
);
10885 json_object_boolean_true_add(json
, "installed");
10887 json_object_boolean_false_add(json
,
10890 vty_out(vty
, "SG : %s\n", vxlan_sg
->sg_str
);
10891 vty_out(vty
, " Input : %s\n", iif_name
);
10892 vty_out(vty
, " Output : %s\n", oif_name
);
10893 vty_out(vty
, " installed : %s\n",
10894 installed
?"yes":"no");
10899 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10900 json
, JSON_C_TO_STRING_PRETTY
));
10901 json_object_free(json
);
10905 DEFUN (show_ip_pim_vxlan_sg
,
10906 show_ip_pim_vxlan_sg_cmd
,
10907 "show ip pim [vrf NAME] vxlan-groups [A.B.C.D [A.B.C.D]] [json]",
10912 "VxLAN BUM groups\n"
10913 "source or group ip\n"
10917 bool uj
= use_json(argc
, argv
);
10921 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10924 return CMD_WARNING
;
10926 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ?
10927 argv
[idx
++]->arg
:NULL
;
10928 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
) ?
10929 argv
[idx
]->arg
:NULL
;
10931 if (src_ip
&& grp_ip
)
10932 pim_show_vxlan_sg_one(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
10934 pim_show_vxlan_sg_match_addr(vrf
->info
, vty
, src_ip
, uj
);
10936 pim_show_vxlan_sg(vrf
->info
, vty
, uj
);
10938 return CMD_SUCCESS
;
10941 static void pim_show_vxlan_sg_work(struct pim_instance
*pim
,
10942 struct vty
*vty
, bool uj
)
10944 json_object
*json
= NULL
;
10945 struct pim_sg_cache_walk_data cwd
;
10946 struct listnode
*node
;
10947 struct pim_vxlan_sg
*vxlan_sg
;
10950 json
= json_object_new_object();
10952 vty_out(vty
, "Codes: I -> installed\n");
10954 "Source Group Input Flags\n");
10957 memset(&cwd
, 0, sizeof(cwd
));
10960 for (ALL_LIST_ELEMENTS_RO(pim_vxlan_p
->work_list
, node
, vxlan_sg
))
10961 pim_show_vxlan_sg_entry(vxlan_sg
, &cwd
);
10964 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10965 json
, JSON_C_TO_STRING_PRETTY
));
10966 json_object_free(json
);
10970 DEFUN_HIDDEN (show_ip_pim_vxlan_sg_work
,
10971 show_ip_pim_vxlan_sg_work_cmd
,
10972 "show ip pim [vrf NAME] vxlan-work [json]",
10977 "VxLAN work list\n"
10980 bool uj
= use_json(argc
, argv
);
10984 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10987 return CMD_WARNING
;
10989 pim_show_vxlan_sg_work(vrf
->info
, vty
, uj
);
10991 return CMD_SUCCESS
;
10994 DEFUN_HIDDEN (no_ip_pim_mlag
,
10995 no_ip_pim_mlag_cmd
,
11002 char mlag_xpath
[XPATH_MAXLEN
];
11004 snprintf(mlag_xpath
, sizeof(mlag_xpath
), FRR_PIM_AF_XPATH
,
11005 "frr-pim:pimd", "pim", "default", "frr-routing:ipv4");
11006 strlcat(mlag_xpath
, "/mlag", sizeof(mlag_xpath
));
11008 nb_cli_enqueue_change(vty
, mlag_xpath
, NB_OP_DESTROY
, NULL
);
11011 return nb_cli_apply_changes(vty
, NULL
);
11014 DEFUN_HIDDEN (ip_pim_mlag
,
11016 "ip pim mlag INTERFACE role [primary|secondary] state [up|down] addr A.B.C.D",
11020 "peerlink sub interface\n"
11022 "MLAG role primary\n"
11023 "MLAG role secondary\n"
11024 "peer session state\n"
11025 "peer session state up\n"
11026 "peer session state down\n"
11028 "unique ip address\n")
11031 char mlag_peerlink_rif_xpath
[XPATH_MAXLEN
];
11032 char mlag_my_role_xpath
[XPATH_MAXLEN
];
11033 char mlag_peer_state_xpath
[XPATH_MAXLEN
];
11034 char mlag_reg_address_xpath
[XPATH_MAXLEN
];
11036 snprintf(mlag_peerlink_rif_xpath
, sizeof(mlag_peerlink_rif_xpath
),
11038 "frr-pim:pimd", "pim", "default", "frr-routing:ipv4");
11039 strlcat(mlag_peerlink_rif_xpath
, "/mlag/peerlink-rif",
11040 sizeof(mlag_peerlink_rif_xpath
));
11043 nb_cli_enqueue_change(vty
, mlag_peerlink_rif_xpath
, NB_OP_MODIFY
,
11046 snprintf(mlag_my_role_xpath
, sizeof(mlag_my_role_xpath
),
11048 "frr-pim:pimd", "pim", "default", "frr-routing:ipv4");
11049 strlcat(mlag_my_role_xpath
, "/mlag/my-role",
11050 sizeof(mlag_my_role_xpath
));
11053 if (!strcmp(argv
[idx
]->arg
, "primary")) {
11054 nb_cli_enqueue_change(vty
, mlag_my_role_xpath
, NB_OP_MODIFY
,
11055 "MLAG_ROLE_PRIMARY");
11057 } else if (!strcmp(argv
[idx
]->arg
, "secondary")) {
11058 nb_cli_enqueue_change(vty
, mlag_my_role_xpath
, NB_OP_MODIFY
,
11059 "MLAG_ROLE_SECONDARY");
11062 vty_out(vty
, "unknown MLAG role %s\n", argv
[idx
]->arg
);
11063 return CMD_WARNING
;
11066 snprintf(mlag_peer_state_xpath
, sizeof(mlag_peer_state_xpath
),
11068 "frr-pim:pimd", "pim", "default", "frr-routing:ipv4");
11069 strlcat(mlag_peer_state_xpath
, "/mlag/peer-state",
11070 sizeof(mlag_peer_state_xpath
));
11073 if (!strcmp(argv
[idx
]->arg
, "up")) {
11074 nb_cli_enqueue_change(vty
, mlag_peer_state_xpath
, NB_OP_MODIFY
,
11077 } else if (strcmp(argv
[idx
]->arg
, "down")) {
11078 nb_cli_enqueue_change(vty
, mlag_peer_state_xpath
, NB_OP_MODIFY
,
11082 vty_out(vty
, "unknown MLAG state %s\n", argv
[idx
]->arg
);
11083 return CMD_WARNING
;
11086 snprintf(mlag_reg_address_xpath
, sizeof(mlag_reg_address_xpath
),
11088 "frr-pim:pimd", "pim", "default", "frr-routing:ipv4");
11089 strlcat(mlag_reg_address_xpath
, "/mlag/reg-address",
11090 sizeof(mlag_reg_address_xpath
));
11093 nb_cli_enqueue_change(vty
, mlag_reg_address_xpath
, NB_OP_MODIFY
,
11096 return nb_cli_apply_changes(vty
, NULL
);
11099 void pim_cmd_init(void)
11101 if_cmd_init(pim_interface_config_write
);
11103 install_node(&debug_node
);
11105 install_element(ENABLE_NODE
, &pim_test_sg_keepalive_cmd
);
11107 install_element(CONFIG_NODE
, &ip_pim_rp_cmd
);
11108 install_element(VRF_NODE
, &ip_pim_rp_cmd
);
11109 install_element(CONFIG_NODE
, &no_ip_pim_rp_cmd
);
11110 install_element(VRF_NODE
, &no_ip_pim_rp_cmd
);
11111 install_element(CONFIG_NODE
, &ip_pim_rp_prefix_list_cmd
);
11112 install_element(VRF_NODE
, &ip_pim_rp_prefix_list_cmd
);
11113 install_element(CONFIG_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
11114 install_element(VRF_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
11115 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
11116 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
11117 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
11118 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
11119 install_element(CONFIG_NODE
, &ip_pim_ssm_prefix_list_cmd
);
11120 install_element(VRF_NODE
, &ip_pim_ssm_prefix_list_cmd
);
11121 install_element(CONFIG_NODE
, &ip_pim_register_suppress_cmd
);
11122 install_element(CONFIG_NODE
, &no_ip_pim_register_suppress_cmd
);
11123 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
11124 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
11125 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
11126 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
11127 install_element(CONFIG_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
11128 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
11129 install_element(CONFIG_NODE
,
11130 &no_ip_pim_spt_switchover_infinity_plist_cmd
);
11131 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_plist_cmd
);
11132 install_element(CONFIG_NODE
, &pim_register_accept_list_cmd
);
11133 install_element(VRF_NODE
, &pim_register_accept_list_cmd
);
11134 install_element(CONFIG_NODE
, &ip_pim_joinprune_time_cmd
);
11135 install_element(CONFIG_NODE
, &no_ip_pim_joinprune_time_cmd
);
11136 install_element(CONFIG_NODE
, &ip_pim_keep_alive_cmd
);
11137 install_element(VRF_NODE
, &ip_pim_keep_alive_cmd
);
11138 install_element(CONFIG_NODE
, &ip_pim_rp_keep_alive_cmd
);
11139 install_element(VRF_NODE
, &ip_pim_rp_keep_alive_cmd
);
11140 install_element(CONFIG_NODE
, &no_ip_pim_keep_alive_cmd
);
11141 install_element(VRF_NODE
, &no_ip_pim_keep_alive_cmd
);
11142 install_element(CONFIG_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
11143 install_element(VRF_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
11144 install_element(CONFIG_NODE
, &ip_pim_packets_cmd
);
11145 install_element(CONFIG_NODE
, &no_ip_pim_packets_cmd
);
11146 install_element(CONFIG_NODE
, &ip_pim_v6_secondary_cmd
);
11147 install_element(VRF_NODE
, &ip_pim_v6_secondary_cmd
);
11148 install_element(CONFIG_NODE
, &no_ip_pim_v6_secondary_cmd
);
11149 install_element(VRF_NODE
, &no_ip_pim_v6_secondary_cmd
);
11150 install_element(CONFIG_NODE
, &ip_ssmpingd_cmd
);
11151 install_element(VRF_NODE
, &ip_ssmpingd_cmd
);
11152 install_element(CONFIG_NODE
, &no_ip_ssmpingd_cmd
);
11153 install_element(VRF_NODE
, &no_ip_ssmpingd_cmd
);
11154 install_element(CONFIG_NODE
, &ip_msdp_peer_cmd
);
11155 install_element(VRF_NODE
, &ip_msdp_peer_cmd
);
11156 install_element(CONFIG_NODE
, &no_ip_msdp_peer_cmd
);
11157 install_element(VRF_NODE
, &no_ip_msdp_peer_cmd
);
11158 install_element(CONFIG_NODE
, &ip_pim_ecmp_cmd
);
11159 install_element(VRF_NODE
, &ip_pim_ecmp_cmd
);
11160 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_cmd
);
11161 install_element(VRF_NODE
, &no_ip_pim_ecmp_cmd
);
11162 install_element(CONFIG_NODE
, &ip_pim_ecmp_rebalance_cmd
);
11163 install_element(VRF_NODE
, &ip_pim_ecmp_rebalance_cmd
);
11164 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
11165 install_element(VRF_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
11166 install_element(CONFIG_NODE
, &ip_pim_mlag_cmd
);
11167 install_element(CONFIG_NODE
, &no_ip_pim_mlag_cmd
);
11168 install_element(CONFIG_NODE
, &igmp_group_watermark_cmd
);
11169 install_element(VRF_NODE
, &igmp_group_watermark_cmd
);
11170 install_element(CONFIG_NODE
, &no_igmp_group_watermark_cmd
);
11171 install_element(VRF_NODE
, &no_igmp_group_watermark_cmd
);
11173 install_element(INTERFACE_NODE
, &interface_ip_igmp_cmd
);
11174 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_cmd
);
11175 install_element(INTERFACE_NODE
, &interface_ip_igmp_join_cmd
);
11176 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_join_cmd
);
11177 install_element(INTERFACE_NODE
, &interface_ip_igmp_version_cmd
);
11178 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_version_cmd
);
11179 install_element(INTERFACE_NODE
, &interface_ip_igmp_query_interval_cmd
);
11180 install_element(INTERFACE_NODE
,
11181 &interface_no_ip_igmp_query_interval_cmd
);
11182 install_element(INTERFACE_NODE
,
11183 &interface_ip_igmp_query_max_response_time_cmd
);
11184 install_element(INTERFACE_NODE
,
11185 &interface_no_ip_igmp_query_max_response_time_cmd
);
11186 install_element(INTERFACE_NODE
,
11187 &interface_ip_igmp_query_max_response_time_dsec_cmd
);
11188 install_element(INTERFACE_NODE
,
11189 &interface_no_ip_igmp_query_max_response_time_dsec_cmd
);
11190 install_element(INTERFACE_NODE
,
11191 &interface_ip_igmp_last_member_query_count_cmd
);
11192 install_element(INTERFACE_NODE
,
11193 &interface_no_ip_igmp_last_member_query_count_cmd
);
11194 install_element(INTERFACE_NODE
,
11195 &interface_ip_igmp_last_member_query_interval_cmd
);
11196 install_element(INTERFACE_NODE
,
11197 &interface_no_ip_igmp_last_member_query_interval_cmd
);
11198 install_element(INTERFACE_NODE
, &interface_ip_pim_activeactive_cmd
);
11199 install_element(INTERFACE_NODE
, &interface_ip_pim_ssm_cmd
);
11200 install_element(INTERFACE_NODE
, &interface_no_ip_pim_ssm_cmd
);
11201 install_element(INTERFACE_NODE
, &interface_ip_pim_sm_cmd
);
11202 install_element(INTERFACE_NODE
, &interface_no_ip_pim_sm_cmd
);
11203 install_element(INTERFACE_NODE
, &interface_ip_pim_cmd
);
11204 install_element(INTERFACE_NODE
, &interface_no_ip_pim_cmd
);
11205 install_element(INTERFACE_NODE
, &interface_ip_pim_drprio_cmd
);
11206 install_element(INTERFACE_NODE
, &interface_no_ip_pim_drprio_cmd
);
11207 install_element(INTERFACE_NODE
, &interface_ip_pim_hello_cmd
);
11208 install_element(INTERFACE_NODE
, &interface_no_ip_pim_hello_cmd
);
11209 install_element(INTERFACE_NODE
, &interface_ip_pim_boundary_oil_cmd
);
11210 install_element(INTERFACE_NODE
, &interface_no_ip_pim_boundary_oil_cmd
);
11211 install_element(INTERFACE_NODE
, &interface_ip_igmp_query_generate_cmd
);
11213 // Static mroutes NEB
11214 install_element(INTERFACE_NODE
, &interface_ip_mroute_cmd
);
11215 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_cmd
);
11217 install_element(VIEW_NODE
, &show_ip_igmp_interface_cmd
);
11218 install_element(VIEW_NODE
, &show_ip_igmp_interface_vrf_all_cmd
);
11219 install_element(VIEW_NODE
, &show_ip_igmp_join_cmd
);
11220 install_element(VIEW_NODE
, &show_ip_igmp_join_vrf_all_cmd
);
11221 install_element(VIEW_NODE
, &show_ip_igmp_groups_cmd
);
11222 install_element(VIEW_NODE
, &show_ip_igmp_groups_vrf_all_cmd
);
11223 install_element(VIEW_NODE
, &show_ip_igmp_groups_retransmissions_cmd
);
11224 install_element(VIEW_NODE
, &show_ip_igmp_sources_cmd
);
11225 install_element(VIEW_NODE
, &show_ip_igmp_sources_retransmissions_cmd
);
11226 install_element(VIEW_NODE
, &show_ip_igmp_statistics_cmd
);
11227 install_element(VIEW_NODE
, &show_ip_pim_assert_cmd
);
11228 install_element(VIEW_NODE
, &show_ip_pim_assert_internal_cmd
);
11229 install_element(VIEW_NODE
, &show_ip_pim_assert_metric_cmd
);
11230 install_element(VIEW_NODE
, &show_ip_pim_assert_winner_metric_cmd
);
11231 install_element(VIEW_NODE
, &show_ip_pim_interface_traffic_cmd
);
11232 install_element(VIEW_NODE
, &show_ip_pim_interface_cmd
);
11233 install_element(VIEW_NODE
, &show_ip_pim_interface_vrf_all_cmd
);
11234 install_element(VIEW_NODE
, &show_ip_pim_join_cmd
);
11235 install_element(VIEW_NODE
, &show_ip_pim_join_vrf_all_cmd
);
11236 install_element(VIEW_NODE
, &show_ip_pim_jp_agg_cmd
);
11237 install_element(VIEW_NODE
, &show_ip_pim_local_membership_cmd
);
11238 install_element(VIEW_NODE
, &show_ip_pim_mlag_summary_cmd
);
11239 install_element(VIEW_NODE
, &show_ip_pim_mlag_up_cmd
);
11240 install_element(VIEW_NODE
, &show_ip_pim_mlag_up_vrf_all_cmd
);
11241 install_element(VIEW_NODE
, &show_ip_pim_neighbor_cmd
);
11242 install_element(VIEW_NODE
, &show_ip_pim_neighbor_vrf_all_cmd
);
11243 install_element(VIEW_NODE
, &show_ip_pim_rpf_cmd
);
11244 install_element(VIEW_NODE
, &show_ip_pim_rpf_vrf_all_cmd
);
11245 install_element(VIEW_NODE
, &show_ip_pim_secondary_cmd
);
11246 install_element(VIEW_NODE
, &show_ip_pim_state_cmd
);
11247 install_element(VIEW_NODE
, &show_ip_pim_state_vrf_all_cmd
);
11248 install_element(VIEW_NODE
, &show_ip_pim_upstream_cmd
);
11249 install_element(VIEW_NODE
, &show_ip_pim_upstream_vrf_all_cmd
);
11250 install_element(VIEW_NODE
, &show_ip_pim_channel_cmd
);
11251 install_element(VIEW_NODE
, &show_ip_pim_upstream_join_desired_cmd
);
11252 install_element(VIEW_NODE
, &show_ip_pim_upstream_rpf_cmd
);
11253 install_element(VIEW_NODE
, &show_ip_pim_rp_cmd
);
11254 install_element(VIEW_NODE
, &show_ip_pim_rp_vrf_all_cmd
);
11255 install_element(VIEW_NODE
, &show_ip_pim_bsr_cmd
);
11256 install_element(VIEW_NODE
, &show_ip_multicast_cmd
);
11257 install_element(VIEW_NODE
, &show_ip_multicast_vrf_all_cmd
);
11258 install_element(VIEW_NODE
, &show_ip_multicast_count_cmd
);
11259 install_element(VIEW_NODE
, &show_ip_multicast_count_vrf_all_cmd
);
11260 install_element(VIEW_NODE
, &show_ip_mroute_cmd
);
11261 install_element(VIEW_NODE
, &show_ip_mroute_vrf_all_cmd
);
11262 install_element(VIEW_NODE
, &show_ip_mroute_count_cmd
);
11263 install_element(VIEW_NODE
, &show_ip_mroute_count_vrf_all_cmd
);
11264 install_element(VIEW_NODE
, &show_ip_mroute_summary_cmd
);
11265 install_element(VIEW_NODE
, &show_ip_mroute_summary_vrf_all_cmd
);
11266 install_element(VIEW_NODE
, &show_ip_rib_cmd
);
11267 install_element(VIEW_NODE
, &show_ip_ssmpingd_cmd
);
11268 install_element(VIEW_NODE
, &show_ip_pim_nexthop_cmd
);
11269 install_element(VIEW_NODE
, &show_ip_pim_nexthop_lookup_cmd
);
11270 install_element(VIEW_NODE
, &show_ip_pim_bsrp_cmd
);
11271 install_element(VIEW_NODE
, &show_ip_pim_bsm_db_cmd
);
11272 install_element(VIEW_NODE
, &show_ip_pim_statistics_cmd
);
11274 install_element(ENABLE_NODE
, &clear_ip_mroute_count_cmd
);
11275 install_element(ENABLE_NODE
, &clear_ip_interfaces_cmd
);
11276 install_element(ENABLE_NODE
, &clear_ip_igmp_interfaces_cmd
);
11277 install_element(ENABLE_NODE
, &clear_ip_mroute_cmd
);
11278 install_element(ENABLE_NODE
, &clear_ip_pim_interfaces_cmd
);
11279 install_element(ENABLE_NODE
, &clear_ip_pim_interface_traffic_cmd
);
11280 install_element(ENABLE_NODE
, &clear_ip_pim_oil_cmd
);
11281 install_element(ENABLE_NODE
, &clear_ip_pim_statistics_cmd
);
11282 install_element(ENABLE_NODE
, &clear_ip_pim_bsr_db_cmd
);
11284 install_element(ENABLE_NODE
, &show_debugging_pim_cmd
);
11286 install_element(ENABLE_NODE
, &debug_igmp_cmd
);
11287 install_element(ENABLE_NODE
, &no_debug_igmp_cmd
);
11288 install_element(ENABLE_NODE
, &debug_igmp_events_cmd
);
11289 install_element(ENABLE_NODE
, &no_debug_igmp_events_cmd
);
11290 install_element(ENABLE_NODE
, &debug_igmp_packets_cmd
);
11291 install_element(ENABLE_NODE
, &no_debug_igmp_packets_cmd
);
11292 install_element(ENABLE_NODE
, &debug_igmp_trace_cmd
);
11293 install_element(ENABLE_NODE
, &no_debug_igmp_trace_cmd
);
11294 install_element(ENABLE_NODE
, &debug_mroute_cmd
);
11295 install_element(ENABLE_NODE
, &debug_mroute_detail_cmd
);
11296 install_element(ENABLE_NODE
, &no_debug_mroute_cmd
);
11297 install_element(ENABLE_NODE
, &no_debug_mroute_detail_cmd
);
11298 install_element(ENABLE_NODE
, &debug_pim_static_cmd
);
11299 install_element(ENABLE_NODE
, &no_debug_pim_static_cmd
);
11300 install_element(ENABLE_NODE
, &debug_pim_cmd
);
11301 install_element(ENABLE_NODE
, &no_debug_pim_cmd
);
11302 install_element(ENABLE_NODE
, &debug_pim_nht_cmd
);
11303 install_element(ENABLE_NODE
, &no_debug_pim_nht_cmd
);
11304 install_element(ENABLE_NODE
, &debug_pim_nht_rp_cmd
);
11305 install_element(ENABLE_NODE
, &no_debug_pim_nht_rp_cmd
);
11306 install_element(ENABLE_NODE
, &debug_pim_events_cmd
);
11307 install_element(ENABLE_NODE
, &no_debug_pim_events_cmd
);
11308 install_element(ENABLE_NODE
, &debug_pim_packets_cmd
);
11309 install_element(ENABLE_NODE
, &no_debug_pim_packets_cmd
);
11310 install_element(ENABLE_NODE
, &debug_pim_packetdump_send_cmd
);
11311 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_send_cmd
);
11312 install_element(ENABLE_NODE
, &debug_pim_packetdump_recv_cmd
);
11313 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_recv_cmd
);
11314 install_element(ENABLE_NODE
, &debug_pim_trace_cmd
);
11315 install_element(ENABLE_NODE
, &no_debug_pim_trace_cmd
);
11316 install_element(ENABLE_NODE
, &debug_pim_trace_detail_cmd
);
11317 install_element(ENABLE_NODE
, &no_debug_pim_trace_detail_cmd
);
11318 install_element(ENABLE_NODE
, &debug_ssmpingd_cmd
);
11319 install_element(ENABLE_NODE
, &no_debug_ssmpingd_cmd
);
11320 install_element(ENABLE_NODE
, &debug_pim_zebra_cmd
);
11321 install_element(ENABLE_NODE
, &no_debug_pim_zebra_cmd
);
11322 install_element(ENABLE_NODE
, &debug_pim_mlag_cmd
);
11323 install_element(ENABLE_NODE
, &no_debug_pim_mlag_cmd
);
11324 install_element(ENABLE_NODE
, &debug_pim_vxlan_cmd
);
11325 install_element(ENABLE_NODE
, &no_debug_pim_vxlan_cmd
);
11326 install_element(ENABLE_NODE
, &debug_msdp_cmd
);
11327 install_element(ENABLE_NODE
, &no_debug_msdp_cmd
);
11328 install_element(ENABLE_NODE
, &debug_msdp_events_cmd
);
11329 install_element(ENABLE_NODE
, &no_debug_msdp_events_cmd
);
11330 install_element(ENABLE_NODE
, &debug_msdp_packets_cmd
);
11331 install_element(ENABLE_NODE
, &no_debug_msdp_packets_cmd
);
11332 install_element(ENABLE_NODE
, &debug_mtrace_cmd
);
11333 install_element(ENABLE_NODE
, &no_debug_mtrace_cmd
);
11334 install_element(ENABLE_NODE
, &debug_bsm_cmd
);
11335 install_element(ENABLE_NODE
, &no_debug_bsm_cmd
);
11337 install_element(CONFIG_NODE
, &debug_igmp_cmd
);
11338 install_element(CONFIG_NODE
, &no_debug_igmp_cmd
);
11339 install_element(CONFIG_NODE
, &debug_igmp_events_cmd
);
11340 install_element(CONFIG_NODE
, &no_debug_igmp_events_cmd
);
11341 install_element(CONFIG_NODE
, &debug_igmp_packets_cmd
);
11342 install_element(CONFIG_NODE
, &no_debug_igmp_packets_cmd
);
11343 install_element(CONFIG_NODE
, &debug_igmp_trace_cmd
);
11344 install_element(CONFIG_NODE
, &no_debug_igmp_trace_cmd
);
11345 install_element(CONFIG_NODE
, &debug_mroute_cmd
);
11346 install_element(CONFIG_NODE
, &debug_mroute_detail_cmd
);
11347 install_element(CONFIG_NODE
, &no_debug_mroute_cmd
);
11348 install_element(CONFIG_NODE
, &no_debug_mroute_detail_cmd
);
11349 install_element(CONFIG_NODE
, &debug_pim_static_cmd
);
11350 install_element(CONFIG_NODE
, &no_debug_pim_static_cmd
);
11351 install_element(CONFIG_NODE
, &debug_pim_cmd
);
11352 install_element(CONFIG_NODE
, &no_debug_pim_cmd
);
11353 install_element(CONFIG_NODE
, &debug_pim_nht_cmd
);
11354 install_element(CONFIG_NODE
, &no_debug_pim_nht_cmd
);
11355 install_element(CONFIG_NODE
, &debug_pim_nht_rp_cmd
);
11356 install_element(CONFIG_NODE
, &no_debug_pim_nht_rp_cmd
);
11357 install_element(CONFIG_NODE
, &debug_pim_events_cmd
);
11358 install_element(CONFIG_NODE
, &no_debug_pim_events_cmd
);
11359 install_element(CONFIG_NODE
, &debug_pim_packets_cmd
);
11360 install_element(CONFIG_NODE
, &no_debug_pim_packets_cmd
);
11361 install_element(CONFIG_NODE
, &debug_pim_trace_cmd
);
11362 install_element(CONFIG_NODE
, &no_debug_pim_trace_cmd
);
11363 install_element(CONFIG_NODE
, &debug_pim_trace_detail_cmd
);
11364 install_element(CONFIG_NODE
, &no_debug_pim_trace_detail_cmd
);
11365 install_element(CONFIG_NODE
, &debug_ssmpingd_cmd
);
11366 install_element(CONFIG_NODE
, &no_debug_ssmpingd_cmd
);
11367 install_element(CONFIG_NODE
, &debug_pim_zebra_cmd
);
11368 install_element(CONFIG_NODE
, &no_debug_pim_zebra_cmd
);
11369 install_element(CONFIG_NODE
, &debug_pim_mlag_cmd
);
11370 install_element(CONFIG_NODE
, &no_debug_pim_mlag_cmd
);
11371 install_element(CONFIG_NODE
, &debug_pim_vxlan_cmd
);
11372 install_element(CONFIG_NODE
, &no_debug_pim_vxlan_cmd
);
11373 install_element(CONFIG_NODE
, &debug_msdp_cmd
);
11374 install_element(CONFIG_NODE
, &no_debug_msdp_cmd
);
11375 install_element(CONFIG_NODE
, &debug_msdp_events_cmd
);
11376 install_element(CONFIG_NODE
, &no_debug_msdp_events_cmd
);
11377 install_element(CONFIG_NODE
, &debug_msdp_packets_cmd
);
11378 install_element(CONFIG_NODE
, &no_debug_msdp_packets_cmd
);
11379 install_element(CONFIG_NODE
, &debug_mtrace_cmd
);
11380 install_element(CONFIG_NODE
, &no_debug_mtrace_cmd
);
11381 install_element(CONFIG_NODE
, &debug_bsm_cmd
);
11382 install_element(CONFIG_NODE
, &no_debug_bsm_cmd
);
11384 install_element(CONFIG_NODE
, &ip_msdp_timers_cmd
);
11385 install_element(VRF_NODE
, &ip_msdp_timers_cmd
);
11386 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_member_cmd
);
11387 install_element(VRF_NODE
, &ip_msdp_mesh_group_member_cmd
);
11388 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
11389 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
11390 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_source_cmd
);
11391 install_element(VRF_NODE
, &ip_msdp_mesh_group_source_cmd
);
11392 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
11393 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
11394 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_cmd
);
11395 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_cmd
);
11396 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_cmd
);
11397 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_vrf_all_cmd
);
11398 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_cmd
);
11399 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_vrf_all_cmd
);
11400 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_cmd
);
11401 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_vrf_all_cmd
);
11402 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_cmd
);
11403 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_vrf_all_cmd
);
11404 install_element(VIEW_NODE
, &show_ip_pim_ssm_range_cmd
);
11405 install_element(VIEW_NODE
, &show_ip_pim_group_type_cmd
);
11406 install_element(VIEW_NODE
, &show_ip_pim_vxlan_sg_cmd
);
11407 install_element(VIEW_NODE
, &show_ip_pim_vxlan_sg_work_cmd
);
11408 install_element(INTERFACE_NODE
, &interface_pim_use_source_cmd
);
11409 install_element(INTERFACE_NODE
, &interface_no_pim_use_source_cmd
);
11410 /* Install BSM command */
11411 install_element(INTERFACE_NODE
, &ip_pim_bsm_cmd
);
11412 install_element(INTERFACE_NODE
, &no_ip_pim_bsm_cmd
);
11413 install_element(INTERFACE_NODE
, &ip_pim_ucast_bsm_cmd
);
11414 install_element(INTERFACE_NODE
, &no_ip_pim_ucast_bsm_cmd
);
11415 /* Install BFD command */
11416 install_element(INTERFACE_NODE
, &ip_pim_bfd_cmd
);
11417 install_element(INTERFACE_NODE
, &ip_pim_bfd_param_cmd
);
11418 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_profile_cmd
);
11419 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_cmd
);
11421 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_param_cmd
);
11422 #endif /* !HAVE_BFDD */