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 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
*grpnode
;
3440 struct igmp_group
*grp
;
3445 /* scan igmp groups */
3446 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_group_list
, grpnode
,
3448 char group_str
[INET_ADDRSTRLEN
];
3452 pim_inet4_dump("<group?>", grp
->group_addr
, group_str
,
3454 pim_time_timer_to_hhmmss(hhmmss
, sizeof(hhmmss
),
3455 grp
->t_group_timer
);
3456 pim_time_uptime(uptime
, sizeof(uptime
),
3457 now
- grp
->group_creation
);
3460 json_object_object_get_ex(json
, ifp
->name
,
3464 json_iface
= json_object_new_object();
3465 json_object_pim_ifp_add(json_iface
,
3467 json_object_object_add(json
, ifp
->name
,
3469 json_groups
= json_object_new_array();
3470 json_object_object_add(json_iface
,
3475 json_group
= json_object_new_object();
3476 json_object_string_add(json_group
, "group",
3479 if (grp
->igmp_version
== 3)
3480 json_object_string_add(
3482 grp
->group_filtermode_isexcl
3486 json_object_string_add(json_group
, "timer",
3488 json_object_int_add(
3489 json_group
, "sourcesCount",
3490 grp
->group_source_list
? listcount(
3491 grp
->group_source_list
)
3493 json_object_int_add(json_group
, "version",
3495 json_object_string_add(json_group
, "uptime",
3497 json_object_array_add(json_groups
, json_group
);
3499 vty_out(vty
, "%-16s %-15s %4s %8s %4d %d %8s\n",
3500 ifp
->name
, group_str
,
3501 grp
->igmp_version
== 3
3502 ? (grp
->group_filtermode_isexcl
3507 grp
->group_source_list
? listcount(
3508 grp
->group_source_list
)
3510 grp
->igmp_version
, uptime
);
3512 } /* scan igmp groups */
3513 } /* scan interfaces */
3516 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3517 json
, JSON_C_TO_STRING_PRETTY
));
3518 json_object_free(json
);
3522 static void igmp_show_group_retransmission(struct pim_instance
*pim
,
3525 struct interface
*ifp
;
3528 "Interface Group RetTimer Counter RetSrcs\n");
3530 /* scan interfaces */
3531 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3532 struct pim_interface
*pim_ifp
= ifp
->info
;
3533 struct listnode
*grpnode
;
3534 struct igmp_group
*grp
;
3539 /* scan igmp groups */
3540 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_group_list
, grpnode
,
3542 char group_str
[INET_ADDRSTRLEN
];
3543 char grp_retr_mmss
[10];
3544 struct listnode
*src_node
;
3545 struct igmp_source
*src
;
3546 int grp_retr_sources
= 0;
3548 pim_inet4_dump("<group?>", grp
->group_addr
, group_str
,
3550 pim_time_timer_to_mmss(
3551 grp_retr_mmss
, sizeof(grp_retr_mmss
),
3552 grp
->t_group_query_retransmit_timer
);
3555 /* count group sources with retransmission state
3557 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
,
3559 if (src
->source_query_retransmit_count
> 0) {
3564 vty_out(vty
, "%-16s %-15s %-8s %7d %7d\n", ifp
->name
,
3565 group_str
, grp_retr_mmss
,
3566 grp
->group_specific_query_retransmit_count
,
3569 } /* scan igmp groups */
3570 } /* scan interfaces */
3573 static void igmp_show_sources(struct pim_instance
*pim
, struct vty
*vty
)
3575 struct interface
*ifp
;
3578 now
= pim_time_monotonic_sec();
3581 "Interface Group Source Timer Fwd Uptime \n");
3583 /* scan interfaces */
3584 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3585 struct pim_interface
*pim_ifp
= ifp
->info
;
3586 struct listnode
*grpnode
;
3587 struct igmp_group
*grp
;
3592 /* scan igmp groups */
3593 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_group_list
, grpnode
,
3595 char group_str
[INET_ADDRSTRLEN
];
3596 struct listnode
*srcnode
;
3597 struct igmp_source
*src
;
3599 pim_inet4_dump("<group?>", grp
->group_addr
, group_str
,
3602 /* scan group sources */
3603 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
,
3605 char source_str
[INET_ADDRSTRLEN
];
3609 pim_inet4_dump("<source?>", src
->source_addr
,
3610 source_str
, sizeof(source_str
));
3612 pim_time_timer_to_mmss(mmss
, sizeof(mmss
),
3613 src
->t_source_timer
);
3615 pim_time_uptime(uptime
, sizeof(uptime
),
3616 now
- src
->source_creation
);
3618 vty_out(vty
, "%-16s %-15s %-15s %5s %3s %8s\n",
3619 ifp
->name
, group_str
, source_str
, mmss
,
3620 IGMP_SOURCE_TEST_FORWARDING(
3626 } /* scan group sources */
3627 } /* scan igmp groups */
3628 } /* scan interfaces */
3631 static void igmp_show_source_retransmission(struct pim_instance
*pim
,
3634 struct interface
*ifp
;
3637 "Interface Group Source Counter\n");
3639 /* scan interfaces */
3640 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3641 struct pim_interface
*pim_ifp
= ifp
->info
;
3642 struct listnode
*grpnode
;
3643 struct igmp_group
*grp
;
3648 /* scan igmp groups */
3649 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_group_list
, grpnode
,
3651 char group_str
[INET_ADDRSTRLEN
];
3652 struct listnode
*srcnode
;
3653 struct igmp_source
*src
;
3655 pim_inet4_dump("<group?>", grp
->group_addr
, group_str
,
3658 /* scan group sources */
3659 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
,
3661 char source_str
[INET_ADDRSTRLEN
];
3663 pim_inet4_dump("<source?>", src
->source_addr
,
3664 source_str
, sizeof(source_str
));
3666 vty_out(vty
, "%-16s %-15s %-15s %7d\n",
3667 ifp
->name
, group_str
, source_str
,
3668 src
->source_query_retransmit_count
);
3670 } /* scan group sources */
3671 } /* scan igmp groups */
3672 } /* scan interfaces */
3675 static void pim_show_bsr(struct pim_instance
*pim
,
3680 char last_bsm_seen
[10];
3683 char bsr_str
[PREFIX_STRLEN
];
3684 json_object
*json
= NULL
;
3686 if (pim
->global_scope
.current_bsr
.s_addr
== INADDR_ANY
) {
3687 strlcpy(bsr_str
, "0.0.0.0", sizeof(bsr_str
));
3688 pim_time_uptime(uptime
, sizeof(uptime
),
3689 pim
->global_scope
.current_bsr_first_ts
);
3690 pim_time_uptime(last_bsm_seen
, sizeof(last_bsm_seen
),
3691 pim
->global_scope
.current_bsr_last_ts
);
3695 pim_inet4_dump("<bsr?>", pim
->global_scope
.current_bsr
,
3696 bsr_str
, sizeof(bsr_str
));
3697 now
= pim_time_monotonic_sec();
3698 pim_time_uptime(uptime
, sizeof(uptime
),
3699 (now
- pim
->global_scope
.current_bsr_first_ts
));
3700 pim_time_uptime(last_bsm_seen
, sizeof(last_bsm_seen
),
3701 now
- pim
->global_scope
.current_bsr_last_ts
);
3704 switch (pim
->global_scope
.state
) {
3706 strlcpy(bsr_state
, "NO_INFO", sizeof(bsr_state
));
3709 strlcpy(bsr_state
, "ACCEPT_ANY", sizeof(bsr_state
));
3711 case ACCEPT_PREFERRED
:
3712 strlcpy(bsr_state
, "ACCEPT_PREFERRED", sizeof(bsr_state
));
3715 strlcpy(bsr_state
, "", sizeof(bsr_state
));
3719 json
= json_object_new_object();
3720 json_object_string_add(json
, "bsr", bsr_str
);
3721 json_object_int_add(json
, "priority",
3722 pim
->global_scope
.current_bsr_prio
);
3723 json_object_int_add(json
, "fragmentTag",
3724 pim
->global_scope
.bsm_frag_tag
);
3725 json_object_string_add(json
, "state", bsr_state
);
3726 json_object_string_add(json
, "upTime", uptime
);
3727 json_object_string_add(json
, "lastBsmSeen", last_bsm_seen
);
3731 vty_out(vty
, "PIMv2 Bootstrap information\n");
3732 vty_out(vty
, "Current preferred BSR address: %s\n", bsr_str
);
3734 "Priority Fragment-Tag State UpTime\n");
3735 vty_out(vty
, " %-12d %-12d %-13s %7s\n",
3736 pim
->global_scope
.current_bsr_prio
,
3737 pim
->global_scope
.bsm_frag_tag
,
3740 vty_out(vty
, "Last BSM seen: %s\n", last_bsm_seen
);
3744 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3745 json
, JSON_C_TO_STRING_PRETTY
));
3746 json_object_free(json
);
3750 static void clear_igmp_interfaces(struct pim_instance
*pim
)
3752 struct interface
*ifp
;
3754 FOR_ALL_INTERFACES (pim
->vrf
, ifp
)
3755 pim_if_addr_del_all_igmp(ifp
);
3757 FOR_ALL_INTERFACES (pim
->vrf
, ifp
)
3758 pim_if_addr_add_all(ifp
);
3761 static void clear_pim_interfaces(struct pim_instance
*pim
)
3763 struct interface
*ifp
;
3765 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3767 pim_neighbor_delete_all(ifp
, "interface cleared");
3772 static void clear_interfaces(struct pim_instance
*pim
)
3774 clear_igmp_interfaces(pim
);
3775 clear_pim_interfaces(pim
);
3778 #define PIM_GET_PIM_INTERFACE(pim_ifp, ifp) \
3779 pim_ifp = ifp->info; \
3782 "%% Enable PIM and/or IGMP on this interface first\n"); \
3783 return CMD_WARNING_CONFIG_FAILED; \
3787 * Get current node VRF name.
3790 * In case of failure it will print error message to user.
3792 * \returns name or NULL if failed to get VRF.
3794 static const char *pim_cli_get_vrf_name(struct vty
*vty
)
3796 const struct lyd_node
*vrf_node
;
3798 /* Not inside any VRF context. */
3799 if (vty
->xpath_index
== 0)
3800 return VRF_DEFAULT_NAME
;
3802 vrf_node
= yang_dnode_get(vty
->candidate_config
->dnode
, VTY_CURR_XPATH
);
3803 if (vrf_node
== NULL
) {
3804 vty_out(vty
, "%% Failed to get vrf dnode in configuration\n");
3808 return yang_dnode_get_string(vrf_node
, "./name");
3812 * Compatibility function to keep the legacy mesh group CLI behavior:
3813 * Delete group when there are no more configurations in it.
3816 * Don't forget to call `nb_cli_apply_changes` after this.
3818 static void pim_cli_legacy_mesh_group_behavior(struct vty
*vty
,
3821 const char *vrfname
;
3822 char xpath_value
[XPATH_MAXLEN
];
3823 char xpath_member_value
[XPATH_MAXLEN
];
3824 const struct lyd_node
*member_dnode
;
3826 vrfname
= pim_cli_get_vrf_name(vty
);
3827 if (vrfname
== NULL
)
3830 /* Get mesh group base XPath. */
3831 snprintf(xpath_value
, sizeof(xpath_value
),
3832 FRR_PIM_AF_XPATH
"/msdp-mesh-groups[name='%s']",
3833 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4", gname
);
3834 /* Group must exists, otherwise just quit. */
3835 if (!yang_dnode_exists(vty
->candidate_config
->dnode
, xpath_value
))
3838 /* Group members check: */
3839 strlcpy(xpath_member_value
, xpath_value
, sizeof(xpath_member_value
));
3840 strlcat(xpath_member_value
, "/members", sizeof(xpath_member_value
));
3841 if (yang_dnode_exists(vty
->candidate_config
->dnode
,
3842 xpath_member_value
)) {
3843 member_dnode
= yang_dnode_get(vty
->candidate_config
->dnode
,
3844 xpath_member_value
);
3845 if (!member_dnode
|| !yang_is_last_list_dnode(member_dnode
))
3849 /* Source address check: */
3850 strlcpy(xpath_member_value
, xpath_value
, sizeof(xpath_member_value
));
3851 strlcat(xpath_member_value
, "/source", sizeof(xpath_member_value
));
3852 if (yang_dnode_exists(vty
->candidate_config
->dnode
, xpath_member_value
))
3855 /* No configurations found: delete it. */
3856 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_DESTROY
, NULL
);
3859 DEFUN (clear_ip_interfaces
,
3860 clear_ip_interfaces_cmd
,
3861 "clear ip interfaces [vrf NAME]",
3864 "Reset interfaces\n"
3868 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3873 clear_interfaces(vrf
->info
);
3878 DEFUN (clear_ip_igmp_interfaces
,
3879 clear_ip_igmp_interfaces_cmd
,
3880 "clear ip igmp [vrf NAME] interfaces",
3885 "Reset IGMP interfaces\n")
3888 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3893 clear_igmp_interfaces(vrf
->info
);
3898 DEFUN (clear_ip_pim_statistics
,
3899 clear_ip_pim_statistics_cmd
,
3900 "clear ip pim statistics [vrf NAME]",
3905 "Reset PIM statistics\n")
3908 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3913 clear_pim_statistics(vrf
->info
);
3917 static void clear_mroute(struct pim_instance
*pim
)
3919 struct pim_upstream
*up
;
3920 struct interface
*ifp
;
3922 /* scan interfaces */
3923 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3924 struct pim_interface
*pim_ifp
= ifp
->info
;
3925 struct igmp_group
*grp
;
3926 struct pim_ifchannel
*ch
;
3931 /* deleting all ifchannels */
3932 while (!RB_EMPTY(pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
)) {
3933 ch
= RB_ROOT(pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
);
3935 pim_ifchannel_delete(ch
);
3938 /* clean up all igmp groups */
3940 if (pim_ifp
->igmp_group_list
) {
3941 while (pim_ifp
->igmp_group_list
->count
) {
3942 grp
= listnode_head(pim_ifp
->igmp_group_list
);
3943 igmp_group_delete(grp
);
3948 /* clean up all upstreams*/
3949 while ((up
= rb_pim_upstream_first(&pim
->upstream_head
)))
3950 pim_upstream_del(pim
, up
, __func__
);
3954 DEFUN (clear_ip_mroute
,
3955 clear_ip_mroute_cmd
,
3956 "clear ip mroute [vrf NAME]",
3959 "Reset multicast routes\n"
3963 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3968 clear_mroute(vrf
->info
);
3973 DEFUN (clear_ip_pim_interfaces
,
3974 clear_ip_pim_interfaces_cmd
,
3975 "clear ip pim [vrf NAME] interfaces",
3980 "Reset PIM interfaces\n")
3983 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3988 clear_pim_interfaces(vrf
->info
);
3993 DEFUN (clear_ip_pim_interface_traffic
,
3994 clear_ip_pim_interface_traffic_cmd
,
3995 "clear ip pim [vrf NAME] interface traffic",
3998 "PIM clear commands\n"
4000 "Reset PIM interfaces\n"
4001 "Reset Protocol Packet counters\n")
4004 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4005 struct interface
*ifp
= NULL
;
4006 struct pim_interface
*pim_ifp
= NULL
;
4011 FOR_ALL_INTERFACES (vrf
, ifp
) {
4012 pim_ifp
= ifp
->info
;
4017 pim_ifp
->pim_ifstat_hello_recv
= 0;
4018 pim_ifp
->pim_ifstat_hello_sent
= 0;
4019 pim_ifp
->pim_ifstat_join_recv
= 0;
4020 pim_ifp
->pim_ifstat_join_send
= 0;
4021 pim_ifp
->pim_ifstat_prune_recv
= 0;
4022 pim_ifp
->pim_ifstat_prune_send
= 0;
4023 pim_ifp
->pim_ifstat_reg_recv
= 0;
4024 pim_ifp
->pim_ifstat_reg_send
= 0;
4025 pim_ifp
->pim_ifstat_reg_stop_recv
= 0;
4026 pim_ifp
->pim_ifstat_reg_stop_send
= 0;
4027 pim_ifp
->pim_ifstat_assert_recv
= 0;
4028 pim_ifp
->pim_ifstat_assert_send
= 0;
4029 pim_ifp
->pim_ifstat_bsm_rx
= 0;
4030 pim_ifp
->pim_ifstat_bsm_tx
= 0;
4036 DEFUN (clear_ip_pim_oil
,
4037 clear_ip_pim_oil_cmd
,
4038 "clear ip pim [vrf NAME] oil",
4043 "Rescan PIM OIL (output interface list)\n")
4046 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4051 pim_scan_oil(vrf
->info
);
4056 static void clear_pim_bsr_db(struct pim_instance
*pim
)
4058 struct route_node
*rn
;
4059 struct route_node
*rpnode
;
4060 struct bsgrp_node
*bsgrp
;
4061 struct prefix nht_p
;
4062 struct prefix g_all
;
4063 struct rp_info
*rp_all
;
4064 struct pim_upstream
*up
;
4065 struct rp_info
*rp_info
;
4066 bool is_bsr_tracking
= true;
4068 /* Remove next hop tracking for the bsr */
4069 nht_p
.family
= AF_INET
;
4070 nht_p
.prefixlen
= IPV4_MAX_BITLEN
;
4071 nht_p
.u
.prefix4
= pim
->global_scope
.current_bsr
;
4072 if (PIM_DEBUG_BSM
) {
4073 zlog_debug("%s: Deregister BSR addr %pFX with Zebra NHT",
4076 pim_delete_tracked_nexthop(pim
, &nht_p
, NULL
, NULL
, is_bsr_tracking
);
4078 /* Reset scope zone data */
4079 pim
->global_scope
.accept_nofwd_bsm
= false;
4080 pim
->global_scope
.state
= ACCEPT_ANY
;
4081 pim
->global_scope
.current_bsr
.s_addr
= INADDR_ANY
;
4082 pim
->global_scope
.current_bsr_prio
= 0;
4083 pim
->global_scope
.current_bsr_first_ts
= 0;
4084 pim
->global_scope
.current_bsr_last_ts
= 0;
4085 pim
->global_scope
.bsm_frag_tag
= 0;
4086 pim_bsm_frags_free(&pim
->global_scope
);
4088 pim_bs_timer_stop(&pim
->global_scope
);
4090 for (rn
= route_top(pim
->global_scope
.bsrp_table
); rn
;
4091 rn
= route_next(rn
)) {
4096 rpnode
= route_node_lookup(pim
->rp_table
, &bsgrp
->group
);
4099 pim_free_bsgrp_node(bsgrp
->scope
->bsrp_table
,
4101 pim_free_bsgrp_data(bsgrp
);
4105 rp_info
= (struct rp_info
*)rpnode
->info
;
4107 if ((!rp_info
) || (rp_info
->rp_src
!= RP_SRC_BSR
)) {
4108 pim_free_bsgrp_node(bsgrp
->scope
->bsrp_table
,
4110 pim_free_bsgrp_data(bsgrp
);
4114 /* Deregister addr with Zebra NHT */
4115 nht_p
.family
= AF_INET
;
4116 nht_p
.prefixlen
= IPV4_MAX_BITLEN
;
4117 nht_p
.u
.prefix4
= rp_info
->rp
.rpf_addr
.u
.prefix4
;
4119 if (PIM_DEBUG_PIM_NHT_RP
) {
4120 zlog_debug("%s: Deregister RP addr %pFX with Zebra ",
4124 pim_delete_tracked_nexthop(pim
, &nht_p
, NULL
, rp_info
, false);
4126 if (!str2prefix("224.0.0.0/4", &g_all
))
4129 rp_all
= pim_rp_find_match_group(pim
, &g_all
);
4131 if (rp_all
== rp_info
) {
4132 rp_all
->rp
.rpf_addr
.family
= AF_INET
;
4133 rp_all
->rp
.rpf_addr
.u
.prefix4
.s_addr
= INADDR_NONE
;
4134 rp_all
->i_am_rp
= 0;
4136 /* Delete the rp_info from rp-list */
4137 listnode_delete(pim
->rp_list
, rp_info
);
4139 /* Delete the rp node from rp_table */
4140 rpnode
->info
= NULL
;
4141 route_unlock_node(rpnode
);
4142 route_unlock_node(rpnode
);
4143 XFREE(MTYPE_PIM_RP
, rp_info
);
4146 pim_free_bsgrp_node(bsgrp
->scope
->bsrp_table
, &bsgrp
->group
);
4147 pim_free_bsgrp_data(bsgrp
);
4149 pim_rp_refresh_group_to_rp_mapping(pim
);
4152 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
4153 /* Find the upstream (*, G) whose upstream address is same as
4156 if (up
->sg
.src
.s_addr
!= INADDR_ANY
)
4160 struct rp_info
*trp_info
;
4162 grp
.family
= AF_INET
;
4163 grp
.prefixlen
= IPV4_MAX_BITLEN
;
4164 grp
.u
.prefix4
= up
->sg
.grp
;
4166 trp_info
= pim_rp_find_match_group(pim
, &grp
);
4168 /* RP not found for the group grp */
4169 if (pim_rpf_addr_is_inaddr_none(&trp_info
->rp
)) {
4170 pim_upstream_rpf_clear(pim
, up
);
4171 pim_rp_set_upstream_addr(pim
, &up
->upstream_addr
,
4172 up
->sg
.src
, up
->sg
.grp
);
4174 /* RP found for the group grp */
4175 pim_upstream_update(pim
, up
);
4181 DEFUN (clear_ip_pim_bsr_db
,
4182 clear_ip_pim_bsr_db_cmd
,
4183 "clear ip pim [vrf NAME] bsr-data",
4188 "Reset pim bsr data\n")
4191 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4196 clear_pim_bsr_db(vrf
->info
);
4201 DEFUN (show_ip_igmp_interface
,
4202 show_ip_igmp_interface_cmd
,
4203 "show ip igmp [vrf NAME] interface [detail|WORD] [json]",
4208 "IGMP interface information\n"
4214 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4215 bool uj
= use_json(argc
, argv
);
4220 if (argv_find(argv
, argc
, "detail", &idx
)
4221 || argv_find(argv
, argc
, "WORD", &idx
))
4222 igmp_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
4224 igmp_show_interfaces(vrf
->info
, vty
, uj
);
4229 DEFUN (show_ip_igmp_interface_vrf_all
,
4230 show_ip_igmp_interface_vrf_all_cmd
,
4231 "show ip igmp vrf all interface [detail|WORD] [json]",
4236 "IGMP interface information\n"
4242 bool uj
= use_json(argc
, argv
);
4248 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4252 vty_out(vty
, " \"%s\": ", vrf
->name
);
4255 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4256 if (argv_find(argv
, argc
, "detail", &idx
)
4257 || argv_find(argv
, argc
, "WORD", &idx
))
4258 igmp_show_interfaces_single(vrf
->info
, vty
,
4259 argv
[idx
]->arg
, uj
);
4261 igmp_show_interfaces(vrf
->info
, vty
, uj
);
4264 vty_out(vty
, "}\n");
4269 DEFUN (show_ip_igmp_join
,
4270 show_ip_igmp_join_cmd
,
4271 "show ip igmp [vrf NAME] join [json]",
4276 "IGMP static join information\n"
4280 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4281 bool uj
= use_json(argc
, argv
);
4286 igmp_show_interface_join(vrf
->info
, vty
, uj
);
4291 DEFUN (show_ip_igmp_join_vrf_all
,
4292 show_ip_igmp_join_vrf_all_cmd
,
4293 "show ip igmp vrf all join [json]",
4298 "IGMP static join information\n"
4301 bool uj
= use_json(argc
, argv
);
4307 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4311 vty_out(vty
, " \"%s\": ", vrf
->name
);
4314 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4315 igmp_show_interface_join(vrf
->info
, vty
, uj
);
4318 vty_out(vty
, "}\n");
4323 DEFUN (show_ip_igmp_groups
,
4324 show_ip_igmp_groups_cmd
,
4325 "show ip igmp [vrf NAME] groups [json]",
4334 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4335 bool uj
= use_json(argc
, argv
);
4340 igmp_show_groups(vrf
->info
, vty
, uj
);
4345 DEFUN (show_ip_igmp_groups_vrf_all
,
4346 show_ip_igmp_groups_vrf_all_cmd
,
4347 "show ip igmp vrf all groups [json]",
4355 bool uj
= use_json(argc
, argv
);
4361 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4365 vty_out(vty
, " \"%s\": ", vrf
->name
);
4368 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4369 igmp_show_groups(vrf
->info
, vty
, uj
);
4372 vty_out(vty
, "}\n");
4377 DEFUN (show_ip_igmp_groups_retransmissions
,
4378 show_ip_igmp_groups_retransmissions_cmd
,
4379 "show ip igmp [vrf NAME] groups retransmissions",
4385 "IGMP group retransmissions\n")
4388 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4393 igmp_show_group_retransmission(vrf
->info
, vty
);
4398 DEFUN (show_ip_igmp_sources
,
4399 show_ip_igmp_sources_cmd
,
4400 "show ip igmp [vrf NAME] sources",
4408 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4413 igmp_show_sources(vrf
->info
, vty
);
4418 DEFUN (show_ip_igmp_sources_retransmissions
,
4419 show_ip_igmp_sources_retransmissions_cmd
,
4420 "show ip igmp [vrf NAME] sources retransmissions",
4426 "IGMP source retransmissions\n")
4429 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4434 igmp_show_source_retransmission(vrf
->info
, vty
);
4439 DEFUN (show_ip_igmp_statistics
,
4440 show_ip_igmp_statistics_cmd
,
4441 "show ip igmp [vrf NAME] statistics [interface WORD] [json]",
4452 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4453 bool uj
= use_json(argc
, argv
);
4458 if (argv_find(argv
, argc
, "WORD", &idx
))
4459 igmp_show_statistics(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
4461 igmp_show_statistics(vrf
->info
, vty
, NULL
, uj
);
4466 DEFUN (show_ip_pim_mlag_summary
,
4467 show_ip_pim_mlag_summary_cmd
,
4468 "show ip pim mlag summary [json]",
4473 "status and stats\n"
4476 bool uj
= use_json(argc
, argv
);
4477 char role_buf
[MLAG_ROLE_STRSIZE
];
4478 char addr_buf
[INET_ADDRSTRLEN
];
4481 json_object
*json
= NULL
;
4482 json_object
*json_stat
= NULL
;
4484 json
= json_object_new_object();
4485 if (router
->mlag_flags
& PIM_MLAGF_LOCAL_CONN_UP
)
4486 json_object_boolean_true_add(json
, "mlagConnUp");
4487 if (router
->mlag_flags
& PIM_MLAGF_PEER_CONN_UP
)
4488 json_object_boolean_true_add(json
, "mlagPeerConnUp");
4489 if (router
->mlag_flags
& PIM_MLAGF_PEER_ZEBRA_UP
)
4490 json_object_boolean_true_add(json
, "mlagPeerZebraUp");
4491 json_object_string_add(json
, "mlagRole",
4492 mlag_role2str(router
->mlag_role
,
4493 role_buf
, sizeof(role_buf
)));
4494 inet_ntop(AF_INET
, &router
->local_vtep_ip
,
4495 addr_buf
, INET_ADDRSTRLEN
);
4496 json_object_string_add(json
, "localVtepIp", addr_buf
);
4497 inet_ntop(AF_INET
, &router
->anycast_vtep_ip
,
4498 addr_buf
, INET_ADDRSTRLEN
);
4499 json_object_string_add(json
, "anycastVtepIp", addr_buf
);
4500 json_object_string_add(json
, "peerlinkRif",
4501 router
->peerlink_rif
);
4503 json_stat
= json_object_new_object();
4504 json_object_int_add(json_stat
, "mlagConnFlaps",
4505 router
->mlag_stats
.mlagd_session_downs
);
4506 json_object_int_add(json_stat
, "mlagPeerConnFlaps",
4507 router
->mlag_stats
.peer_session_downs
);
4508 json_object_int_add(json_stat
, "mlagPeerZebraFlaps",
4509 router
->mlag_stats
.peer_zebra_downs
);
4510 json_object_int_add(json_stat
, "mrouteAddRx",
4511 router
->mlag_stats
.msg
.mroute_add_rx
);
4512 json_object_int_add(json_stat
, "mrouteAddTx",
4513 router
->mlag_stats
.msg
.mroute_add_tx
);
4514 json_object_int_add(json_stat
, "mrouteDelRx",
4515 router
->mlag_stats
.msg
.mroute_del_rx
);
4516 json_object_int_add(json_stat
, "mrouteDelTx",
4517 router
->mlag_stats
.msg
.mroute_del_tx
);
4518 json_object_int_add(json_stat
, "mlagStatusUpdates",
4519 router
->mlag_stats
.msg
.mlag_status_updates
);
4520 json_object_int_add(json_stat
, "peerZebraStatusUpdates",
4521 router
->mlag_stats
.msg
.peer_zebra_status_updates
);
4522 json_object_int_add(json_stat
, "pimStatusUpdates",
4523 router
->mlag_stats
.msg
.pim_status_updates
);
4524 json_object_int_add(json_stat
, "vxlanUpdates",
4525 router
->mlag_stats
.msg
.vxlan_updates
);
4526 json_object_object_add(json
, "connStats", json_stat
);
4528 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4529 json
, JSON_C_TO_STRING_PRETTY
));
4530 json_object_free(json
);
4534 vty_out(vty
, "MLAG daemon connection: %s\n",
4535 (router
->mlag_flags
& PIM_MLAGF_LOCAL_CONN_UP
)
4537 vty_out(vty
, "MLAG peer state: %s\n",
4538 (router
->mlag_flags
& PIM_MLAGF_PEER_CONN_UP
)
4540 vty_out(vty
, "Zebra peer state: %s\n",
4541 (router
->mlag_flags
& PIM_MLAGF_PEER_ZEBRA_UP
)
4543 vty_out(vty
, "MLAG role: %s\n",
4544 mlag_role2str(router
->mlag_role
, role_buf
, sizeof(role_buf
)));
4545 inet_ntop(AF_INET
, &router
->local_vtep_ip
,
4546 addr_buf
, INET_ADDRSTRLEN
);
4547 vty_out(vty
, "Local VTEP IP: %s\n", addr_buf
);
4548 inet_ntop(AF_INET
, &router
->anycast_vtep_ip
,
4549 addr_buf
, INET_ADDRSTRLEN
);
4550 vty_out(vty
, "Anycast VTEP IP: %s\n", addr_buf
);
4551 vty_out(vty
, "Peerlink: %s\n", router
->peerlink_rif
);
4552 vty_out(vty
, "Session flaps: mlagd: %d mlag-peer: %d zebra-peer: %d\n",
4553 router
->mlag_stats
.mlagd_session_downs
,
4554 router
->mlag_stats
.peer_session_downs
,
4555 router
->mlag_stats
.peer_zebra_downs
);
4556 vty_out(vty
, "Message Statistics:\n");
4557 vty_out(vty
, " mroute adds: rx: %d, tx: %d\n",
4558 router
->mlag_stats
.msg
.mroute_add_rx
,
4559 router
->mlag_stats
.msg
.mroute_add_tx
);
4560 vty_out(vty
, " mroute dels: rx: %d, tx: %d\n",
4561 router
->mlag_stats
.msg
.mroute_del_rx
,
4562 router
->mlag_stats
.msg
.mroute_del_tx
);
4563 vty_out(vty
, " peer zebra status updates: %d\n",
4564 router
->mlag_stats
.msg
.peer_zebra_status_updates
);
4565 vty_out(vty
, " PIM status updates: %d\n",
4566 router
->mlag_stats
.msg
.pim_status_updates
);
4567 vty_out(vty
, " VxLAN updates: %d\n",
4568 router
->mlag_stats
.msg
.vxlan_updates
);
4573 DEFUN (show_ip_pim_assert
,
4574 show_ip_pim_assert_cmd
,
4575 "show ip pim [vrf NAME] assert",
4580 "PIM interface assert\n")
4583 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4588 pim_show_assert(vrf
->info
, vty
);
4593 DEFUN (show_ip_pim_assert_internal
,
4594 show_ip_pim_assert_internal_cmd
,
4595 "show ip pim [vrf NAME] assert-internal",
4600 "PIM interface internal assert state\n")
4603 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4608 pim_show_assert_internal(vrf
->info
, vty
);
4613 DEFUN (show_ip_pim_assert_metric
,
4614 show_ip_pim_assert_metric_cmd
,
4615 "show ip pim [vrf NAME] assert-metric",
4620 "PIM interface assert metric\n")
4623 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4628 pim_show_assert_metric(vrf
->info
, vty
);
4633 DEFUN (show_ip_pim_assert_winner_metric
,
4634 show_ip_pim_assert_winner_metric_cmd
,
4635 "show ip pim [vrf NAME] assert-winner-metric",
4640 "PIM interface assert winner metric\n")
4643 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4648 pim_show_assert_winner_metric(vrf
->info
, vty
);
4653 DEFUN (show_ip_pim_interface
,
4654 show_ip_pim_interface_cmd
,
4655 "show ip pim [mlag] [vrf NAME] interface [detail|WORD] [json]",
4661 "PIM interface information\n"
4667 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4668 bool uj
= use_json(argc
, argv
);
4674 if (argv_find(argv
, argc
, "mlag", &idx
))
4677 if (argv_find(argv
, argc
, "WORD", &idx
)
4678 || argv_find(argv
, argc
, "detail", &idx
))
4679 pim_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, mlag
,
4682 pim_show_interfaces(vrf
->info
, vty
, mlag
, uj
);
4687 DEFUN (show_ip_pim_interface_vrf_all
,
4688 show_ip_pim_interface_vrf_all_cmd
,
4689 "show ip pim [mlag] vrf all interface [detail|WORD] [json]",
4695 "PIM interface information\n"
4701 bool uj
= use_json(argc
, argv
);
4706 if (argv_find(argv
, argc
, "mlag", &idx
))
4712 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4716 vty_out(vty
, " \"%s\": ", vrf
->name
);
4719 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4720 if (argv_find(argv
, argc
, "WORD", &idx
)
4721 || argv_find(argv
, argc
, "detail", &idx
))
4722 pim_show_interfaces_single(vrf
->info
, vty
,
4723 argv
[idx
]->arg
, mlag
, uj
);
4725 pim_show_interfaces(vrf
->info
, vty
, mlag
, uj
);
4728 vty_out(vty
, "}\n");
4733 DEFPY (show_ip_pim_join
,
4734 show_ip_pim_join_cmd
,
4735 "show ip pim [vrf NAME] join [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
4740 "PIM interface join information\n"
4741 "The Source or Group\n"
4745 struct prefix_sg sg
= {0};
4748 struct pim_instance
*pim
;
4750 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
4753 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
4756 pim
= pim_get_pim_instance(v
->vrf_id
);
4759 vty_out(vty
, "%% Unable to find pim instance\n");
4763 if (s_or_g
.s_addr
!= INADDR_ANY
) {
4764 if (g
.s_addr
!= INADDR_ANY
) {
4771 pim_show_join(pim
, vty
, &sg
, uj
);
4776 DEFUN (show_ip_pim_join_vrf_all
,
4777 show_ip_pim_join_vrf_all_cmd
,
4778 "show ip pim vrf all join [json]",
4783 "PIM interface join information\n"
4786 struct prefix_sg sg
= {0};
4787 bool uj
= use_json(argc
, argv
);
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 pim_show_join(vrf
->info
, vty
, &sg
, uj
);
4804 vty_out(vty
, "}\n");
4809 static void pim_show_jp_agg_helper(struct vty
*vty
,
4810 struct interface
*ifp
,
4811 struct pim_neighbor
*neigh
,
4812 struct pim_upstream
*up
,
4815 char src_str
[INET_ADDRSTRLEN
];
4816 char grp_str
[INET_ADDRSTRLEN
];
4817 char rpf_str
[INET_ADDRSTRLEN
];
4819 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
4820 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
4821 /* pius->address.s_addr */
4822 pim_inet4_dump("<rpf?>", neigh
->source_addr
, rpf_str
, sizeof(rpf_str
));
4824 vty_out(vty
, "%-16s %-15s %-15s %-15s %5s\n",
4825 ifp
->name
, rpf_str
, src_str
,
4826 grp_str
, is_join
?"J":"P");
4829 static void pim_show_jp_agg_list(struct pim_instance
*pim
, struct vty
*vty
)
4831 struct interface
*ifp
;
4832 struct pim_interface
*pim_ifp
;
4833 struct listnode
*n_node
;
4834 struct pim_neighbor
*neigh
;
4835 struct listnode
*jag_node
;
4836 struct pim_jp_agg_group
*jag
;
4837 struct listnode
*js_node
;
4838 struct pim_jp_sources
*js
;
4841 "Interface RPF Nbr Source Group State\n");
4843 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
4844 pim_ifp
= ifp
->info
;
4848 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
,
4850 for (ALL_LIST_ELEMENTS_RO(neigh
->upstream_jp_agg
,
4852 for (ALL_LIST_ELEMENTS_RO(jag
->sources
,
4854 pim_show_jp_agg_helper(vty
,
4863 DEFPY (show_ip_pim_jp_agg
,
4864 show_ip_pim_jp_agg_cmd
,
4865 "show ip pim [vrf NAME] jp-agg",
4870 "join prune aggregation list\n")
4873 struct pim_instance
*pim
;
4875 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
4878 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
4881 pim
= pim_get_pim_instance(v
->vrf_id
);
4884 vty_out(vty
, "%% Unable to find pim instance\n");
4888 pim_show_jp_agg_list(pim
, vty
);
4893 DEFUN (show_ip_pim_local_membership
,
4894 show_ip_pim_local_membership_cmd
,
4895 "show ip pim [vrf NAME] local-membership [json]",
4900 "PIM interface local-membership\n"
4904 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4905 bool uj
= use_json(argc
, argv
);
4910 pim_show_membership(vrf
->info
, vty
, uj
);
4915 static void pim_show_mlag_up_entry_detail(struct vrf
*vrf
,
4917 struct pim_upstream
*up
,
4918 char *src_str
, char *grp_str
,
4922 json_object
*json_row
= NULL
;
4923 json_object
*own_list
= NULL
;
4924 json_object
*json_group
= NULL
;
4927 json_object_object_get_ex(json
, grp_str
, &json_group
);
4929 json_group
= json_object_new_object();
4930 json_object_object_add(json
, grp_str
,
4934 json_row
= json_object_new_object();
4935 json_object_string_add(json_row
, "source", src_str
);
4936 json_object_string_add(json_row
, "group", grp_str
);
4938 own_list
= json_object_new_array();
4939 if (pim_up_mlag_is_local(up
))
4940 json_object_array_add(own_list
,
4941 json_object_new_string("local"));
4942 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
))
4943 json_object_array_add(own_list
,
4944 json_object_new_string("peer"));
4945 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE
))
4946 json_object_array_add(
4947 own_list
, json_object_new_string("Interface"));
4948 json_object_object_add(json_row
, "owners", own_list
);
4950 json_object_int_add(json_row
, "localCost",
4951 pim_up_mlag_local_cost(up
));
4952 json_object_int_add(json_row
, "peerCost",
4953 pim_up_mlag_peer_cost(up
));
4954 if (PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up
->flags
))
4955 json_object_boolean_false_add(json_row
, "df");
4957 json_object_boolean_true_add(json_row
, "df");
4958 json_object_object_add(json_group
, src_str
, json_row
);
4963 if (pim_up_mlag_is_local(up
))
4964 strlcat(own_str
, "L", sizeof(own_str
));
4965 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
))
4966 strlcat(own_str
, "P", sizeof(own_str
));
4967 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE
))
4968 strlcat(own_str
, "I", sizeof(own_str
));
4969 /* XXX - fixup, print paragraph output */
4971 "%-15s %-15s %-6s %-11u %-10d %2s\n",
4972 src_str
, grp_str
, own_str
,
4973 pim_up_mlag_local_cost(up
),
4974 pim_up_mlag_peer_cost(up
),
4975 PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up
->flags
)
4980 static void pim_show_mlag_up_detail(struct vrf
*vrf
,
4981 struct vty
*vty
, const char *src_or_group
,
4982 const char *group
, bool uj
)
4984 char src_str
[INET_ADDRSTRLEN
];
4985 char grp_str
[INET_ADDRSTRLEN
];
4986 struct pim_upstream
*up
;
4987 struct pim_instance
*pim
= vrf
->info
;
4988 json_object
*json
= NULL
;
4991 json
= json_object_new_object();
4994 "Source Group Owner Local-cost Peer-cost DF\n");
4996 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
4997 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
)
4998 && !(up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE
)
4999 && !pim_up_mlag_is_local(up
))
5002 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
5003 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
5004 /* XXX: strcmps are clearly inefficient. we should do uint comps
5008 if (strcmp(src_str
, src_or_group
) ||
5009 strcmp(grp_str
, group
))
5012 if (strcmp(src_str
, src_or_group
) &&
5013 strcmp(grp_str
, src_or_group
))
5016 pim_show_mlag_up_entry_detail(vrf
, vty
, up
,
5017 src_str
, grp_str
, json
);
5021 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5022 json
, JSON_C_TO_STRING_PRETTY
));
5023 json_object_free(json
);
5027 static void pim_show_mlag_up_vrf(struct vrf
*vrf
, struct vty
*vty
, bool uj
)
5029 json_object
*json
= NULL
;
5030 json_object
*json_row
;
5031 struct pim_upstream
*up
;
5032 char src_str
[INET_ADDRSTRLEN
];
5033 char grp_str
[INET_ADDRSTRLEN
];
5034 struct pim_instance
*pim
= vrf
->info
;
5035 json_object
*json_group
= NULL
;
5038 json
= json_object_new_object();
5041 "Source Group Owner Local-cost Peer-cost DF\n");
5044 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
5045 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
)
5046 && !(up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE
)
5047 && !pim_up_mlag_is_local(up
))
5049 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
5050 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
5052 json_object
*own_list
= NULL
;
5054 json_object_object_get_ex(json
, grp_str
, &json_group
);
5056 json_group
= json_object_new_object();
5057 json_object_object_add(json
, grp_str
,
5061 json_row
= json_object_new_object();
5062 json_object_string_add(json_row
, "vrf", vrf
->name
);
5063 json_object_string_add(json_row
, "source", src_str
);
5064 json_object_string_add(json_row
, "group", grp_str
);
5066 own_list
= json_object_new_array();
5067 if (pim_up_mlag_is_local(up
)) {
5069 json_object_array_add(own_list
,
5070 json_object_new_string(
5073 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
)) {
5074 json_object_array_add(own_list
,
5075 json_object_new_string(
5078 json_object_object_add(json_row
, "owners", own_list
);
5080 json_object_int_add(json_row
, "localCost",
5081 pim_up_mlag_local_cost(up
));
5082 json_object_int_add(json_row
, "peerCost",
5083 pim_up_mlag_peer_cost(up
));
5084 if (PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up
->flags
))
5085 json_object_boolean_false_add(json_row
, "df");
5087 json_object_boolean_true_add(json_row
, "df");
5088 json_object_object_add(json_group
, src_str
, json_row
);
5093 if (pim_up_mlag_is_local(up
))
5094 strlcat(own_str
, "L", sizeof(own_str
));
5095 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
))
5096 strlcat(own_str
, "P", sizeof(own_str
));
5097 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE
))
5098 strlcat(own_str
, "I", sizeof(own_str
));
5100 "%-15s %-15s %-6s %-11u %-10u %2s\n",
5101 src_str
, grp_str
, own_str
,
5102 pim_up_mlag_local_cost(up
),
5103 pim_up_mlag_peer_cost(up
),
5104 PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up
->flags
)
5109 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5110 json
, JSON_C_TO_STRING_PRETTY
));
5111 json_object_free(json
);
5115 static void pim_show_mlag_help_string(struct vty
*vty
, bool uj
)
5118 vty_out(vty
, "Owner codes:\n");
5120 "L: EVPN-MLAG Entry, I:PIM-MLAG Entry, P: Peer Entry\n");
5125 DEFUN(show_ip_pim_mlag_up
, show_ip_pim_mlag_up_cmd
,
5126 "show ip pim [vrf NAME] mlag upstream [A.B.C.D [A.B.C.D]] [json]",
5133 "Unicast or Multicast address\n"
5134 "Multicast address\n" JSON_STR
)
5136 const char *src_or_group
= NULL
;
5137 const char *group
= NULL
;
5139 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5140 bool uj
= use_json(argc
, argv
);
5142 if (!vrf
|| !vrf
->info
) {
5143 vty_out(vty
, "%s: VRF or Info missing\n", __func__
);
5150 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
5151 src_or_group
= argv
[idx
]->arg
;
5153 group
= argv
[idx
+ 1]->arg
;
5156 pim_show_mlag_help_string(vty
, uj
);
5159 pim_show_mlag_up_detail(vrf
, vty
, src_or_group
, group
, uj
);
5161 pim_show_mlag_up_vrf(vrf
, vty
, uj
);
5167 DEFUN(show_ip_pim_mlag_up_vrf_all
, show_ip_pim_mlag_up_vrf_all_cmd
,
5168 "show ip pim vrf all mlag upstream [json]",
5169 SHOW_STR IP_STR PIM_STR VRF_CMD_HELP_STR
5171 "upstream\n" JSON_STR
)
5174 bool uj
= use_json(argc
, argv
);
5176 pim_show_mlag_help_string(vty
, uj
);
5177 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5178 pim_show_mlag_up_vrf(vrf
, vty
, uj
);
5184 DEFUN (show_ip_pim_neighbor
,
5185 show_ip_pim_neighbor_cmd
,
5186 "show ip pim [vrf NAME] neighbor [detail|WORD] [json]",
5191 "PIM neighbor information\n"
5193 "Name of interface or neighbor\n"
5197 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5198 bool uj
= use_json(argc
, argv
);
5203 if (argv_find(argv
, argc
, "detail", &idx
)
5204 || argv_find(argv
, argc
, "WORD", &idx
))
5205 pim_show_neighbors_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
5207 pim_show_neighbors(vrf
->info
, vty
, uj
);
5212 DEFUN (show_ip_pim_neighbor_vrf_all
,
5213 show_ip_pim_neighbor_vrf_all_cmd
,
5214 "show ip pim vrf all neighbor [detail|WORD] [json]",
5219 "PIM neighbor information\n"
5221 "Name of interface or neighbor\n"
5225 bool uj
= use_json(argc
, argv
);
5231 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5235 vty_out(vty
, " \"%s\": ", vrf
->name
);
5238 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5239 if (argv_find(argv
, argc
, "detail", &idx
)
5240 || argv_find(argv
, argc
, "WORD", &idx
))
5241 pim_show_neighbors_single(vrf
->info
, vty
,
5242 argv
[idx
]->arg
, uj
);
5244 pim_show_neighbors(vrf
->info
, vty
, uj
);
5247 vty_out(vty
, "}\n");
5252 DEFUN (show_ip_pim_secondary
,
5253 show_ip_pim_secondary_cmd
,
5254 "show ip pim [vrf NAME] secondary",
5259 "PIM neighbor addresses\n")
5262 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5267 pim_show_neighbors_secondary(vrf
->info
, vty
);
5272 DEFUN (show_ip_pim_state
,
5273 show_ip_pim_state_cmd
,
5274 "show ip pim [vrf NAME] state [A.B.C.D [A.B.C.D]] [json]",
5279 "PIM state information\n"
5280 "Unicast or Multicast address\n"
5281 "Multicast address\n"
5284 const char *src_or_group
= NULL
;
5285 const char *group
= NULL
;
5287 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5288 bool uj
= use_json(argc
, argv
);
5296 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
5297 src_or_group
= argv
[idx
]->arg
;
5299 group
= argv
[idx
+ 1]->arg
;
5302 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
5307 DEFUN (show_ip_pim_state_vrf_all
,
5308 show_ip_pim_state_vrf_all_cmd
,
5309 "show ip pim vrf all state [A.B.C.D [A.B.C.D]] [json]",
5314 "PIM state information\n"
5315 "Unicast or Multicast address\n"
5316 "Multicast address\n"
5319 const char *src_or_group
= NULL
;
5320 const char *group
= NULL
;
5322 bool uj
= use_json(argc
, argv
);
5331 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
5332 src_or_group
= argv
[idx
]->arg
;
5334 group
= argv
[idx
+ 1]->arg
;
5337 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5341 vty_out(vty
, " \"%s\": ", vrf
->name
);
5344 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5345 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
5348 vty_out(vty
, "}\n");
5353 DEFPY (show_ip_pim_upstream
,
5354 show_ip_pim_upstream_cmd
,
5355 "show ip pim [vrf NAME] upstream [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
5360 "PIM upstream information\n"
5361 "The Source or Group\n"
5365 struct prefix_sg sg
= {0};
5368 struct pim_instance
*pim
;
5370 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
5373 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
5376 pim
= pim_get_pim_instance(v
->vrf_id
);
5379 vty_out(vty
, "%% Unable to find pim instance\n");
5383 if (s_or_g
.s_addr
!= INADDR_ANY
) {
5384 if (g
.s_addr
!= INADDR_ANY
) {
5390 pim_show_upstream(pim
, vty
, &sg
, uj
);
5395 DEFUN (show_ip_pim_upstream_vrf_all
,
5396 show_ip_pim_upstream_vrf_all_cmd
,
5397 "show ip pim vrf all upstream [json]",
5402 "PIM upstream information\n"
5405 struct prefix_sg sg
= {0};
5406 bool uj
= use_json(argc
, argv
);
5412 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5416 vty_out(vty
, " \"%s\": ", vrf
->name
);
5419 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5420 pim_show_upstream(vrf
->info
, vty
, &sg
, uj
);
5426 DEFUN (show_ip_pim_channel
,
5427 show_ip_pim_channel_cmd
,
5428 "show ip pim [vrf NAME] channel [json]",
5433 "PIM downstream channel info\n"
5437 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5438 bool uj
= use_json(argc
, argv
);
5443 pim_show_channel(vrf
->info
, vty
, uj
);
5448 DEFUN (show_ip_pim_upstream_join_desired
,
5449 show_ip_pim_upstream_join_desired_cmd
,
5450 "show ip pim [vrf NAME] upstream-join-desired [json]",
5455 "PIM upstream join-desired\n"
5459 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5460 bool uj
= use_json(argc
, argv
);
5465 pim_show_join_desired(vrf
->info
, vty
, uj
);
5470 DEFUN (show_ip_pim_upstream_rpf
,
5471 show_ip_pim_upstream_rpf_cmd
,
5472 "show ip pim [vrf NAME] upstream-rpf [json]",
5477 "PIM upstream source rpf\n"
5481 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5482 bool uj
= use_json(argc
, argv
);
5487 pim_show_upstream_rpf(vrf
->info
, vty
, uj
);
5492 DEFUN (show_ip_pim_rp
,
5494 "show ip pim [vrf NAME] rp-info [json]",
5499 "PIM RP information\n"
5503 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5504 bool uj
= use_json(argc
, argv
);
5509 pim_rp_show_information(vrf
->info
, vty
, uj
);
5514 DEFUN (show_ip_pim_rp_vrf_all
,
5515 show_ip_pim_rp_vrf_all_cmd
,
5516 "show ip pim vrf all rp-info [json]",
5521 "PIM RP information\n"
5524 bool uj
= use_json(argc
, argv
);
5530 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5534 vty_out(vty
, " \"%s\": ", vrf
->name
);
5537 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5538 pim_rp_show_information(vrf
->info
, vty
, uj
);
5541 vty_out(vty
, "}\n");
5546 DEFUN (show_ip_pim_rpf
,
5547 show_ip_pim_rpf_cmd
,
5548 "show ip pim [vrf NAME] rpf [json]",
5553 "PIM cached source rpf information\n"
5557 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5558 bool uj
= use_json(argc
, argv
);
5563 pim_show_rpf(vrf
->info
, vty
, uj
);
5568 DEFUN (show_ip_pim_rpf_vrf_all
,
5569 show_ip_pim_rpf_vrf_all_cmd
,
5570 "show ip pim vrf all rpf [json]",
5575 "PIM cached source rpf information\n"
5578 bool uj
= use_json(argc
, argv
);
5584 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5588 vty_out(vty
, " \"%s\": ", vrf
->name
);
5591 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5592 pim_show_rpf(vrf
->info
, vty
, uj
);
5595 vty_out(vty
, "}\n");
5600 DEFUN (show_ip_pim_nexthop
,
5601 show_ip_pim_nexthop_cmd
,
5602 "show ip pim [vrf NAME] nexthop",
5607 "PIM cached nexthop rpf information\n")
5610 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5615 pim_show_nexthop(vrf
->info
, vty
);
5620 DEFUN (show_ip_pim_nexthop_lookup
,
5621 show_ip_pim_nexthop_lookup_cmd
,
5622 "show ip pim [vrf NAME] nexthop-lookup A.B.C.D A.B.C.D",
5627 "PIM cached nexthop rpf lookup\n"
5628 "Source/RP address\n"
5629 "Multicast Group address\n")
5631 struct prefix nht_p
;
5633 struct in_addr src_addr
, grp_addr
;
5634 struct in_addr vif_source
;
5635 const char *addr_str
, *addr_str1
;
5637 struct pim_nexthop nexthop
;
5638 char nexthop_addr_str
[PREFIX_STRLEN
];
5639 char grp_str
[PREFIX_STRLEN
];
5641 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5646 argv_find(argv
, argc
, "A.B.C.D", &idx
);
5647 addr_str
= argv
[idx
]->arg
;
5648 result
= inet_pton(AF_INET
, addr_str
, &src_addr
);
5650 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
5651 errno
, safe_strerror(errno
));
5655 if (pim_is_group_224_4(src_addr
)) {
5657 "Invalid argument. Expected Valid Source Address.\n");
5661 addr_str1
= argv
[idx
+ 1]->arg
;
5662 result
= inet_pton(AF_INET
, addr_str1
, &grp_addr
);
5664 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
5665 errno
, safe_strerror(errno
));
5669 if (!pim_is_group_224_4(grp_addr
)) {
5671 "Invalid argument. Expected Valid Multicast Group Address.\n");
5675 if (!pim_rp_set_upstream_addr(vrf
->info
, &vif_source
, src_addr
,
5679 nht_p
.family
= AF_INET
;
5680 nht_p
.prefixlen
= IPV4_MAX_BITLEN
;
5681 nht_p
.u
.prefix4
= vif_source
;
5682 grp
.family
= AF_INET
;
5683 grp
.prefixlen
= IPV4_MAX_BITLEN
;
5684 grp
.u
.prefix4
= grp_addr
;
5685 memset(&nexthop
, 0, sizeof(nexthop
));
5687 result
= pim_ecmp_nexthop_lookup(vrf
->info
, &nexthop
, &nht_p
, &grp
, 0);
5691 "Nexthop Lookup failed, no usable routes returned.\n");
5695 pim_addr_dump("<grp?>", &grp
, grp_str
, sizeof(grp_str
));
5696 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
5697 nexthop_addr_str
, sizeof(nexthop_addr_str
));
5698 vty_out(vty
, "Group %s --- Nexthop %s Interface %s \n", grp_str
,
5699 nexthop_addr_str
, nexthop
.interface
->name
);
5704 DEFUN (show_ip_pim_interface_traffic
,
5705 show_ip_pim_interface_traffic_cmd
,
5706 "show ip pim [vrf NAME] interface traffic [WORD] [json]",
5711 "PIM interface information\n"
5712 "Protocol Packet counters\n"
5717 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5718 bool uj
= use_json(argc
, argv
);
5723 if (argv_find(argv
, argc
, "WORD", &idx
))
5724 pim_show_interface_traffic_single(vrf
->info
, vty
,
5725 argv
[idx
]->arg
, uj
);
5727 pim_show_interface_traffic(vrf
->info
, vty
, uj
);
5732 DEFUN (show_ip_pim_bsm_db
,
5733 show_ip_pim_bsm_db_cmd
,
5734 "show ip pim bsm-database [vrf NAME] [json]",
5738 "PIM cached bsm packets information\n"
5743 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5744 bool uj
= use_json(argc
, argv
);
5749 pim_show_bsm_db(vrf
->info
, vty
, uj
);
5753 DEFUN (show_ip_pim_bsrp
,
5754 show_ip_pim_bsrp_cmd
,
5755 "show ip pim bsrp-info [vrf NAME] [json]",
5759 "PIM cached group-rp mappings information\n"
5764 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5765 bool uj
= use_json(argc
, argv
);
5770 pim_show_group_rp_mappings_info(vrf
->info
, vty
, uj
);
5775 DEFUN (show_ip_pim_statistics
,
5776 show_ip_pim_statistics_cmd
,
5777 "show ip pim [vrf NAME] statistics [interface WORD] [json]",
5788 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5789 bool uj
= use_json(argc
, argv
);
5794 if (argv_find(argv
, argc
, "WORD", &idx
))
5795 pim_show_statistics(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
5797 pim_show_statistics(vrf
->info
, vty
, NULL
, uj
);
5802 static void show_multicast_interfaces(struct pim_instance
*pim
, struct vty
*vty
,
5805 struct interface
*ifp
;
5806 char buf
[PREFIX_STRLEN
];
5807 json_object
*json
= NULL
;
5808 json_object
*json_row
= NULL
;
5813 json
= json_object_new_object();
5816 "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut\n");
5818 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
5819 struct pim_interface
*pim_ifp
;
5820 struct in_addr ifaddr
;
5821 struct sioc_vif_req vreq
;
5823 pim_ifp
= ifp
->info
;
5828 memset(&vreq
, 0, sizeof(vreq
));
5829 vreq
.vifi
= pim_ifp
->mroute_vif_index
;
5831 if (ioctl(pim
->mroute_socket
, SIOCGETVIFCNT
, &vreq
)) {
5833 "ioctl(SIOCGETVIFCNT=%lu) failure for interface %s vif_index=%d: errno=%d: %s",
5834 (unsigned long)SIOCGETVIFCNT
, ifp
->name
,
5835 pim_ifp
->mroute_vif_index
, errno
,
5836 safe_strerror(errno
));
5839 ifaddr
= pim_ifp
->primary_address
;
5841 json_row
= json_object_new_object();
5842 json_object_string_add(json_row
, "name", ifp
->name
);
5843 json_object_string_add(json_row
, "state",
5844 if_is_up(ifp
) ? "up" : "down");
5845 json_object_string_add(
5846 json_row
, "address",
5847 inet_ntop(AF_INET
, &pim_ifp
->primary_address
,
5849 json_object_int_add(json_row
, "ifIndex", ifp
->ifindex
);
5850 json_object_int_add(json_row
, "vif",
5851 pim_ifp
->mroute_vif_index
);
5852 json_object_int_add(json_row
, "pktsIn",
5853 (unsigned long)vreq
.icount
);
5854 json_object_int_add(json_row
, "pktsOut",
5855 (unsigned long)vreq
.ocount
);
5856 json_object_int_add(json_row
, "bytesIn",
5857 (unsigned long)vreq
.ibytes
);
5858 json_object_int_add(json_row
, "bytesOut",
5859 (unsigned long)vreq
.obytes
);
5860 json_object_object_add(json
, ifp
->name
, json_row
);
5863 "%-16s %-15s %3d %3d %7lu %7lu %10lu %10lu\n",
5865 inet_ntop(AF_INET
, &ifaddr
, buf
, sizeof(buf
)),
5866 ifp
->ifindex
, pim_ifp
->mroute_vif_index
,
5867 (unsigned long)vreq
.icount
,
5868 (unsigned long)vreq
.ocount
,
5869 (unsigned long)vreq
.ibytes
,
5870 (unsigned long)vreq
.obytes
);
5875 vty_out(vty
, "%s\n",
5876 json_object_to_json_string_ext(
5877 json
, JSON_C_TO_STRING_PRETTY
));
5878 json_object_free(json
);
5882 static void pim_cmd_show_ip_multicast_helper(struct pim_instance
*pim
,
5885 struct vrf
*vrf
= pim
->vrf
;
5886 time_t now
= pim_time_monotonic_sec();
5892 vty_out(vty
, "Router MLAG Role: %s\n",
5893 mlag_role2str(router
->mlag_role
, mlag_role
, sizeof(mlag_role
)));
5894 vty_out(vty
, "Mroute socket descriptor:");
5896 vty_out(vty
, " %d(%s)\n", pim
->mroute_socket
, vrf
->name
);
5898 pim_time_uptime(uptime
, sizeof(uptime
),
5899 now
- pim
->mroute_socket_creation
);
5900 vty_out(vty
, "Mroute socket uptime: %s\n", uptime
);
5904 pim_zebra_zclient_update(vty
);
5905 pim_zlookup_show_ip_multicast(vty
);
5908 vty_out(vty
, "Maximum highest VifIndex: %d\n", PIM_MAX_USABLE_VIFS
);
5911 vty_out(vty
, "Upstream Join Timer: %d secs\n", router
->t_periodic
);
5912 vty_out(vty
, "Join/Prune Holdtime: %d secs\n", PIM_JP_HOLDTIME
);
5913 vty_out(vty
, "PIM ECMP: %s\n", pim
->ecmp_enable
? "Enable" : "Disable");
5914 vty_out(vty
, "PIM ECMP Rebalance: %s\n",
5915 pim
->ecmp_rebalance_enable
? "Enable" : "Disable");
5919 show_rpf_refresh_stats(vty
, pim
, now
, NULL
);
5923 show_scan_oil_stats(pim
, vty
, now
);
5925 show_multicast_interfaces(pim
, vty
, false);
5928 DEFUN (show_ip_multicast
,
5929 show_ip_multicast_cmd
,
5930 "show ip multicast [vrf NAME]",
5934 "Multicast global information\n")
5937 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5942 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
5947 DEFUN (show_ip_multicast_vrf_all
,
5948 show_ip_multicast_vrf_all_cmd
,
5949 "show ip multicast vrf all",
5953 "Multicast global information\n")
5955 bool uj
= use_json(argc
, argv
);
5961 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5965 vty_out(vty
, " \"%s\": ", vrf
->name
);
5968 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5969 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
5972 vty_out(vty
, "}\n");
5977 DEFUN(show_ip_multicast_count
,
5978 show_ip_multicast_count_cmd
,
5979 "show ip multicast count [vrf NAME] [json]",
5981 "Multicast global information\n"
5982 "Data packet count\n"
5983 VRF_CMD_HELP_STR JSON_STR
)
5986 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5987 bool uj
= use_json(argc
, argv
);
5992 show_multicast_interfaces(vrf
->info
, vty
, uj
);
5997 DEFUN(show_ip_multicast_count_vrf_all
,
5998 show_ip_multicast_count_vrf_all_cmd
,
5999 "show ip multicast count vrf all [json]",
6001 "Multicast global information\n"
6002 "Data packet count\n"
6003 VRF_CMD_HELP_STR JSON_STR
)
6005 bool uj
= use_json(argc
, argv
);
6012 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
6017 vty_out(vty
, " \"%s\": ", vrf
->name
);
6020 vty_out(vty
, "VRF: %s\n", vrf
->name
);
6022 show_multicast_interfaces(vrf
->info
, vty
, uj
);
6026 vty_out(vty
, "}\n");
6031 static void show_mroute(struct pim_instance
*pim
, struct vty
*vty
,
6032 struct prefix_sg
*sg
, bool fill
, bool uj
)
6034 struct listnode
*node
;
6035 struct channel_oil
*c_oil
;
6036 struct static_route
*s_route
;
6038 json_object
*json
= NULL
;
6039 json_object
*json_group
= NULL
;
6040 json_object
*json_source
= NULL
;
6041 json_object
*json_oil
= NULL
;
6042 json_object
*json_ifp_out
= NULL
;
6045 char grp_str
[INET_ADDRSTRLEN
];
6046 char src_str
[INET_ADDRSTRLEN
];
6047 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
6048 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
6050 struct interface
*ifp_in
;
6052 char state_str
[PIM_REG_STATE_STR_LEN
];
6053 char mroute_uptime
[10];
6056 json
= json_object_new_object();
6058 vty_out(vty
, "IP Multicast Routing Table\n");
6059 vty_out(vty
, "Flags: S - Sparse, C - Connected, P - Pruned\n");
6061 " R - SGRpt Pruned, F - Register flag, T - SPT-bit set\n");
6063 "\nSource Group Flags Proto Input Output TTL Uptime\n");
6066 now
= pim_time_monotonic_sec();
6068 /* print list of PIM and IGMP routes */
6069 frr_each (rb_pim_oil
, &pim
->channel_oil_head
, c_oil
) {
6072 if (!c_oil
->installed
)
6075 if (sg
->grp
.s_addr
!= INADDR_ANY
6076 && sg
->grp
.s_addr
!= c_oil
->oil
.mfcc_mcastgrp
.s_addr
)
6078 if (sg
->src
.s_addr
!= INADDR_ANY
6079 && sg
->src
.s_addr
!= c_oil
->oil
.mfcc_origin
.s_addr
)
6082 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
6084 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
6087 strlcpy(state_str
, "S", sizeof(state_str
));
6088 /* When a non DR receives a igmp join, it creates a (*,G)
6089 * channel_oil without any upstream creation */
6091 if (PIM_UPSTREAM_FLAG_TEST_SRC_IGMP(c_oil
->up
->flags
))
6092 strlcat(state_str
, "C", sizeof(state_str
));
6093 if (pim_upstream_is_sg_rpt(c_oil
->up
))
6094 strlcat(state_str
, "R", sizeof(state_str
));
6095 if (PIM_UPSTREAM_FLAG_TEST_FHR(c_oil
->up
->flags
))
6096 strlcat(state_str
, "F", sizeof(state_str
));
6097 if (c_oil
->up
->sptbit
== PIM_UPSTREAM_SPTBIT_TRUE
)
6098 strlcat(state_str
, "T", sizeof(state_str
));
6100 if (pim_channel_oil_empty(c_oil
))
6101 strlcat(state_str
, "P", sizeof(state_str
));
6103 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
6106 strlcpy(in_ifname
, ifp_in
->name
, sizeof(in_ifname
));
6108 strlcpy(in_ifname
, "<iif?>", sizeof(in_ifname
));
6111 pim_time_uptime(mroute_uptime
, sizeof(mroute_uptime
),
6112 now
- c_oil
->mroute_creation
);
6116 /* Find the group, create it if it doesn't exist */
6117 json_object_object_get_ex(json
, grp_str
, &json_group
);
6120 json_group
= json_object_new_object();
6121 json_object_object_add(json
, grp_str
,
6125 /* Find the source nested under the group, create it if
6128 json_object_object_get_ex(json_group
, src_str
,
6132 json_source
= json_object_new_object();
6133 json_object_object_add(json_group
, src_str
,
6137 /* Find the inbound interface nested under the source,
6138 * create it if it doesn't exist */
6139 json_object_int_add(json_source
, "installed",
6141 json_object_int_add(json_source
, "refCount",
6142 c_oil
->oil_ref_count
);
6143 json_object_int_add(json_source
, "oilSize",
6145 json_object_int_add(json_source
, "OilInheritedRescan",
6146 c_oil
->oil_inherited_rescan
);
6147 json_object_string_add(json_source
, "iif", in_ifname
);
6148 json_object_string_add(json_source
, "upTime",
6153 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
6155 struct interface
*ifp_out
;
6158 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
6162 /* do not display muted OIFs */
6163 if (c_oil
->oif_flags
[oif_vif_index
]
6164 & PIM_OIF_FLAG_MUTE
)
6167 if (c_oil
->oil
.mfcc_parent
== oif_vif_index
&&
6168 !pim_mroute_allow_iif_in_oil(c_oil
,
6172 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
6176 strlcpy(out_ifname
, ifp_out
->name
, sizeof(out_ifname
));
6178 strlcpy(out_ifname
, "<oif?>", sizeof(out_ifname
));
6181 json_ifp_out
= json_object_new_object();
6182 json_object_string_add(json_ifp_out
, "source",
6184 json_object_string_add(json_ifp_out
, "group",
6187 if (c_oil
->oif_flags
[oif_vif_index
]
6188 & PIM_OIF_FLAG_PROTO_PIM
)
6189 json_object_boolean_true_add(
6190 json_ifp_out
, "protocolPim");
6192 if (c_oil
->oif_flags
[oif_vif_index
]
6193 & PIM_OIF_FLAG_PROTO_IGMP
)
6194 json_object_boolean_true_add(
6195 json_ifp_out
, "protocolIgmp");
6197 if (c_oil
->oif_flags
[oif_vif_index
]
6198 & PIM_OIF_FLAG_PROTO_VXLAN
)
6199 json_object_boolean_true_add(
6200 json_ifp_out
, "protocolVxlan");
6202 if (c_oil
->oif_flags
[oif_vif_index
]
6203 & PIM_OIF_FLAG_PROTO_STAR
)
6204 json_object_boolean_true_add(
6206 "protocolInherited");
6208 json_object_string_add(json_ifp_out
,
6211 json_object_int_add(json_ifp_out
, "iVifI",
6212 c_oil
->oil
.mfcc_parent
);
6213 json_object_string_add(json_ifp_out
,
6214 "outboundInterface",
6216 json_object_int_add(json_ifp_out
, "oVifI",
6218 json_object_int_add(json_ifp_out
, "ttl", ttl
);
6219 json_object_string_add(json_ifp_out
, "upTime",
6221 json_object_string_add(json_source
, "flags",
6224 json_oil
= json_object_new_object();
6225 json_object_object_add(json_source
,
6228 json_object_object_add(json_oil
, out_ifname
,
6232 if (c_oil
->oif_flags
[oif_vif_index
]
6233 & PIM_OIF_FLAG_PROTO_PIM
) {
6234 strlcpy(proto
, "PIM", sizeof(proto
));
6237 if (c_oil
->oif_flags
[oif_vif_index
]
6238 & PIM_OIF_FLAG_PROTO_IGMP
) {
6239 strlcpy(proto
, "IGMP", sizeof(proto
));
6242 if (c_oil
->oif_flags
[oif_vif_index
]
6243 & PIM_OIF_FLAG_PROTO_VXLAN
) {
6244 strlcpy(proto
, "VxLAN", sizeof(proto
));
6247 if (c_oil
->oif_flags
[oif_vif_index
]
6248 & PIM_OIF_FLAG_PROTO_STAR
) {
6249 strlcpy(proto
, "STAR", sizeof(proto
));
6253 "%-15s %-15s %-8s %-6s %-16s %-16s %-3d %8s\n",
6254 src_str
, grp_str
, state_str
, proto
,
6255 in_ifname
, out_ifname
, ttl
,
6261 in_ifname
[0] = '\0';
6262 state_str
[0] = '\0';
6263 mroute_uptime
[0] = '\0';
6269 if (!uj
&& !found_oif
) {
6271 "%-15s %-15s %-8s %-6s %-16s %-16s %-3d %8s\n",
6272 src_str
, grp_str
, state_str
, "none", in_ifname
,
6273 "none", 0, "--:--:--");
6277 /* Print list of static routes */
6278 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
6281 if (!s_route
->c_oil
.installed
)
6284 pim_inet4_dump("<group?>", s_route
->group
, grp_str
,
6286 pim_inet4_dump("<source?>", s_route
->source
, src_str
,
6288 ifp_in
= pim_if_find_by_vif_index(pim
, s_route
->iif
);
6292 strlcpy(in_ifname
, ifp_in
->name
, sizeof(in_ifname
));
6294 strlcpy(in_ifname
, "<iif?>", sizeof(in_ifname
));
6298 /* Find the group, create it if it doesn't exist */
6299 json_object_object_get_ex(json
, grp_str
, &json_group
);
6302 json_group
= json_object_new_object();
6303 json_object_object_add(json
, grp_str
,
6307 /* Find the source nested under the group, create it if
6308 * it doesn't exist */
6309 json_object_object_get_ex(json_group
, src_str
,
6313 json_source
= json_object_new_object();
6314 json_object_object_add(json_group
, src_str
,
6318 json_object_string_add(json_source
, "iif", in_ifname
);
6321 strlcpy(proto
, "STATIC", sizeof(proto
));
6324 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
6326 struct interface
*ifp_out
;
6327 char oif_uptime
[10];
6330 ttl
= s_route
->oif_ttls
[oif_vif_index
];
6334 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
6336 oif_uptime
, sizeof(oif_uptime
),
6339 .oif_creation
[oif_vif_index
]);
6343 strlcpy(out_ifname
, ifp_out
->name
, sizeof(out_ifname
));
6345 strlcpy(out_ifname
, "<oif?>", sizeof(out_ifname
));
6348 json_ifp_out
= json_object_new_object();
6349 json_object_string_add(json_ifp_out
, "source",
6351 json_object_string_add(json_ifp_out
, "group",
6353 json_object_boolean_true_add(json_ifp_out
,
6355 json_object_string_add(json_ifp_out
,
6358 json_object_int_add(
6359 json_ifp_out
, "iVifI",
6360 s_route
->c_oil
.oil
.mfcc_parent
);
6361 json_object_string_add(json_ifp_out
,
6362 "outboundInterface",
6364 json_object_int_add(json_ifp_out
, "oVifI",
6366 json_object_int_add(json_ifp_out
, "ttl", ttl
);
6367 json_object_string_add(json_ifp_out
, "upTime",
6370 json_oil
= json_object_new_object();
6371 json_object_object_add(json_source
,
6374 json_object_object_add(json_oil
, out_ifname
,
6378 "%-15s %-15s %-8s %-6s %-16s %-16s %-3d %8s\n",
6379 src_str
, grp_str
, "-", proto
, in_ifname
,
6380 out_ifname
, ttl
, oif_uptime
);
6381 if (first
&& !fill
) {
6384 in_ifname
[0] = '\0';
6390 if (!uj
&& !found_oif
) {
6392 "%-15s %-15s %-8s %-6s %-16s %-16s %-3d %8s\n",
6393 src_str
, grp_str
, "-", proto
, in_ifname
, "none",
6399 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
6400 json
, JSON_C_TO_STRING_PRETTY
));
6401 json_object_free(json
);
6405 DEFPY (show_ip_mroute
,
6407 "show ip mroute [vrf NAME] [A.B.C.D$s_or_g [A.B.C.D$g]] [fill$fill] [json$json]",
6412 "The Source or Group\n"
6414 "Fill in Assumed data\n"
6417 struct prefix_sg sg
= {0};
6418 struct pim_instance
*pim
;
6421 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
6424 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
6427 pim
= pim_get_pim_instance(v
->vrf_id
);
6430 vty_out(vty
, "%% Unable to find pim instance\n");
6434 if (s_or_g
.s_addr
!= INADDR_ANY
) {
6435 if (g
.s_addr
!= INADDR_ANY
) {
6441 show_mroute(pim
, vty
, &sg
, !!fill
, !!json
);
6445 DEFUN (show_ip_mroute_vrf_all
,
6446 show_ip_mroute_vrf_all_cmd
,
6447 "show ip mroute vrf all [fill] [json]",
6452 "Fill in Assumed data\n"
6455 struct prefix_sg sg
= {0};
6456 bool uj
= use_json(argc
, argv
);
6462 if (argv_find(argv
, argc
, "fill", &idx
))
6467 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
6471 vty_out(vty
, " \"%s\": ", vrf
->name
);
6474 vty_out(vty
, "VRF: %s\n", vrf
->name
);
6475 show_mroute(vrf
->info
, vty
, &sg
, fill
, uj
);
6478 vty_out(vty
, "}\n");
6483 DEFUN (clear_ip_mroute_count
,
6484 clear_ip_mroute_count_cmd
,
6485 "clear ip mroute [vrf NAME] count",
6490 "Route and packet count data\n")
6493 struct listnode
*node
;
6494 struct channel_oil
*c_oil
;
6495 struct static_route
*sr
;
6496 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6497 struct pim_instance
*pim
;
6503 frr_each(rb_pim_oil
, &pim
->channel_oil_head
, c_oil
) {
6504 if (!c_oil
->installed
)
6507 pim_mroute_update_counters(c_oil
);
6508 c_oil
->cc
.origpktcnt
= c_oil
->cc
.pktcnt
;
6509 c_oil
->cc
.origbytecnt
= c_oil
->cc
.bytecnt
;
6510 c_oil
->cc
.origwrong_if
= c_oil
->cc
.wrong_if
;
6513 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, sr
)) {
6514 if (!sr
->c_oil
.installed
)
6517 pim_mroute_update_counters(&sr
->c_oil
);
6519 sr
->c_oil
.cc
.origpktcnt
= sr
->c_oil
.cc
.pktcnt
;
6520 sr
->c_oil
.cc
.origbytecnt
= sr
->c_oil
.cc
.bytecnt
;
6521 sr
->c_oil
.cc
.origwrong_if
= sr
->c_oil
.cc
.wrong_if
;
6526 static void show_mroute_count_per_channel_oil(struct channel_oil
*c_oil
,
6530 char group_str
[INET_ADDRSTRLEN
];
6531 char source_str
[INET_ADDRSTRLEN
];
6532 json_object
*json_group
= NULL
;
6533 json_object
*json_source
= NULL
;
6535 if (!c_oil
->installed
)
6538 pim_mroute_update_counters(c_oil
);
6540 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, group_str
,
6542 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, source_str
,
6543 sizeof(source_str
));
6546 json_object_object_get_ex(json
, group_str
, &json_group
);
6549 json_group
= json_object_new_object();
6550 json_object_object_add(json
, group_str
, json_group
);
6553 json_source
= json_object_new_object();
6554 json_object_object_add(json_group
, source_str
, json_source
);
6555 json_object_int_add(json_source
, "lastUsed",
6556 c_oil
->cc
.lastused
/ 100);
6557 json_object_int_add(json_source
, "packets", c_oil
->cc
.pktcnt
);
6558 json_object_int_add(json_source
, "bytes", c_oil
->cc
.bytecnt
);
6559 json_object_int_add(json_source
, "wrongIf", c_oil
->cc
.wrong_if
);
6562 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
6563 source_str
, group_str
, c_oil
->cc
.lastused
/ 100,
6564 c_oil
->cc
.pktcnt
- c_oil
->cc
.origpktcnt
,
6565 c_oil
->cc
.bytecnt
- c_oil
->cc
.origbytecnt
,
6566 c_oil
->cc
.wrong_if
- c_oil
->cc
.origwrong_if
);
6570 static void show_mroute_count(struct pim_instance
*pim
, struct vty
*vty
,
6573 struct listnode
*node
;
6574 struct channel_oil
*c_oil
;
6575 struct static_route
*sr
;
6576 json_object
*json
= NULL
;
6579 json
= json_object_new_object();
6584 "Source Group LastUsed Packets Bytes WrongIf \n");
6587 /* Print PIM and IGMP route counts */
6588 frr_each (rb_pim_oil
, &pim
->channel_oil_head
, c_oil
)
6589 show_mroute_count_per_channel_oil(c_oil
, json
, vty
);
6591 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, sr
))
6592 show_mroute_count_per_channel_oil(&sr
->c_oil
, json
, vty
);
6595 vty_out(vty
, "%s\n",
6596 json_object_to_json_string_ext(
6597 json
, JSON_C_TO_STRING_PRETTY
));
6598 json_object_free(json
);
6602 DEFUN (show_ip_mroute_count
,
6603 show_ip_mroute_count_cmd
,
6604 "show ip mroute [vrf NAME] count [json]",
6609 "Route and packet count data\n"
6613 bool uj
= use_json(argc
, argv
);
6614 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6619 show_mroute_count(vrf
->info
, vty
, uj
);
6623 DEFUN (show_ip_mroute_count_vrf_all
,
6624 show_ip_mroute_count_vrf_all_cmd
,
6625 "show ip mroute vrf all count [json]",
6630 "Route and packet count data\n"
6633 bool uj
= use_json(argc
, argv
);
6639 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
6643 vty_out(vty
, " \"%s\": ", vrf
->name
);
6646 vty_out(vty
, "VRF: %s\n", vrf
->name
);
6647 show_mroute_count(vrf
->info
, vty
, uj
);
6650 vty_out(vty
, "}\n");
6655 static void show_mroute_summary(struct pim_instance
*pim
, struct vty
*vty
,
6658 struct listnode
*node
;
6659 struct channel_oil
*c_oil
;
6660 struct static_route
*s_route
;
6661 uint32_t starg_sw_mroute_cnt
= 0;
6662 uint32_t sg_sw_mroute_cnt
= 0;
6663 uint32_t starg_hw_mroute_cnt
= 0;
6664 uint32_t sg_hw_mroute_cnt
= 0;
6665 json_object
*json_starg
= NULL
;
6666 json_object
*json_sg
= NULL
;
6669 vty_out(vty
, "Mroute Type Installed/Total\n");
6671 frr_each (rb_pim_oil
, &pim
->channel_oil_head
, c_oil
) {
6672 if (!c_oil
->installed
) {
6673 if (c_oil
->oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
6674 starg_sw_mroute_cnt
++;
6678 if (c_oil
->oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
6679 starg_hw_mroute_cnt
++;
6685 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
6686 if (!s_route
->c_oil
.installed
) {
6687 if (s_route
->c_oil
.oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
6688 starg_sw_mroute_cnt
++;
6692 if (s_route
->c_oil
.oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
6693 starg_hw_mroute_cnt
++;
6700 vty_out(vty
, "%-20s %u/%u\n", "(*, G)", starg_hw_mroute_cnt
,
6701 starg_sw_mroute_cnt
+ starg_hw_mroute_cnt
);
6702 vty_out(vty
, "%-20s %u/%u\n", "(S, G)", sg_hw_mroute_cnt
,
6703 sg_sw_mroute_cnt
+ sg_hw_mroute_cnt
);
6704 vty_out(vty
, "------\n");
6705 vty_out(vty
, "%-20s %u/%u\n", "Total",
6706 (starg_hw_mroute_cnt
+ sg_hw_mroute_cnt
),
6707 (starg_sw_mroute_cnt
+ starg_hw_mroute_cnt
6708 + sg_sw_mroute_cnt
+ sg_hw_mroute_cnt
));
6710 /* (*,G) route details */
6711 json_starg
= json_object_new_object();
6712 json_object_object_add(json
, "wildcardGroup", json_starg
);
6714 json_object_int_add(json_starg
, "installed",
6715 starg_hw_mroute_cnt
);
6716 json_object_int_add(json_starg
, "total",
6717 starg_sw_mroute_cnt
+ starg_hw_mroute_cnt
);
6719 /* (S, G) route details */
6720 json_sg
= json_object_new_object();
6721 json_object_object_add(json
, "sourceGroup", json_sg
);
6723 json_object_int_add(json_sg
, "installed", sg_hw_mroute_cnt
);
6724 json_object_int_add(json_sg
, "total",
6725 sg_sw_mroute_cnt
+ sg_hw_mroute_cnt
);
6727 json_object_int_add(json
, "totalNumOfInstalledMroutes",
6728 starg_hw_mroute_cnt
+ sg_hw_mroute_cnt
);
6729 json_object_int_add(json
, "totalNumOfMroutes",
6730 starg_sw_mroute_cnt
+ starg_hw_mroute_cnt
6732 + sg_hw_mroute_cnt
);
6736 DEFUN (show_ip_mroute_summary
,
6737 show_ip_mroute_summary_cmd
,
6738 "show ip mroute [vrf NAME] summary [json]",
6743 "Summary of all mroutes\n"
6747 bool uj
= use_json(argc
, argv
);
6748 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6749 json_object
*json
= NULL
;
6752 json
= json_object_new_object();
6757 show_mroute_summary(vrf
->info
, vty
, json
);
6760 vty_out(vty
, "%s\n",
6761 json_object_to_json_string_ext(
6762 json
, JSON_C_TO_STRING_PRETTY
));
6763 json_object_free(json
);
6768 DEFUN (show_ip_mroute_summary_vrf_all
,
6769 show_ip_mroute_summary_vrf_all_cmd
,
6770 "show ip mroute vrf all summary [json]",
6775 "Summary of all mroutes\n"
6779 bool uj
= use_json(argc
, argv
);
6780 json_object
*json
= NULL
;
6781 json_object
*json_vrf
= NULL
;
6784 json
= json_object_new_object();
6786 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
6788 json_vrf
= json_object_new_object();
6790 vty_out(vty
, "VRF: %s\n", vrf
->name
);
6792 show_mroute_summary(vrf
->info
, vty
, json_vrf
);
6795 json_object_object_add(json
, vrf
->name
, json_vrf
);
6799 vty_out(vty
, "%s\n",
6800 json_object_to_json_string_ext(
6801 json
, JSON_C_TO_STRING_PRETTY
));
6802 json_object_free(json
);
6810 "show ip rib [vrf NAME] A.B.C.D",
6815 "Unicast address\n")
6818 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6819 struct in_addr addr
;
6820 const char *addr_str
;
6821 struct pim_nexthop nexthop
;
6822 char nexthop_addr_str
[PREFIX_STRLEN
];
6828 memset(&nexthop
, 0, sizeof(nexthop
));
6829 argv_find(argv
, argc
, "A.B.C.D", &idx
);
6830 addr_str
= argv
[idx
]->arg
;
6831 result
= inet_pton(AF_INET
, addr_str
, &addr
);
6833 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
6834 errno
, safe_strerror(errno
));
6838 if (!pim_nexthop_lookup(vrf
->info
, &nexthop
, addr
, 0)) {
6840 "Failure querying RIB nexthop for unicast address %s\n",
6846 "Address NextHop Interface Metric Preference\n");
6848 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
6849 nexthop_addr_str
, sizeof(nexthop_addr_str
));
6851 vty_out(vty
, "%-15s %-15s %-9s %6d %10d\n", addr_str
, nexthop_addr_str
,
6852 nexthop
.interface
? nexthop
.interface
->name
: "<ifname?>",
6853 nexthop
.mrib_route_metric
, nexthop
.mrib_metric_preference
);
6858 static void show_ssmpingd(struct pim_instance
*pim
, struct vty
*vty
)
6860 struct listnode
*node
;
6861 struct ssmpingd_sock
*ss
;
6865 "Source Socket Address Port Uptime Requests\n");
6867 if (!pim
->ssmpingd_list
)
6870 now
= pim_time_monotonic_sec();
6872 for (ALL_LIST_ELEMENTS_RO(pim
->ssmpingd_list
, node
, ss
)) {
6873 char source_str
[INET_ADDRSTRLEN
];
6875 struct sockaddr_in bind_addr
;
6876 socklen_t len
= sizeof(bind_addr
);
6877 char bind_addr_str
[INET_ADDRSTRLEN
];
6879 pim_inet4_dump("<src?>", ss
->source_addr
, source_str
,
6880 sizeof(source_str
));
6882 if (pim_socket_getsockname(
6883 ss
->sock_fd
, (struct sockaddr
*)&bind_addr
, &len
)) {
6885 "%% Failure reading socket name for ssmpingd source %s on fd=%d\n",
6886 source_str
, ss
->sock_fd
);
6889 pim_inet4_dump("<addr?>", bind_addr
.sin_addr
, bind_addr_str
,
6890 sizeof(bind_addr_str
));
6891 pim_time_uptime(ss_uptime
, sizeof(ss_uptime
),
6892 now
- ss
->creation
);
6894 vty_out(vty
, "%-15s %6d %-15s %5d %8s %8lld\n", source_str
,
6895 ss
->sock_fd
, bind_addr_str
, ntohs(bind_addr
.sin_port
),
6896 ss_uptime
, (long long)ss
->requests
);
6900 DEFUN (show_ip_ssmpingd
,
6901 show_ip_ssmpingd_cmd
,
6902 "show ip ssmpingd [vrf NAME]",
6909 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6914 show_ssmpingd(vrf
->info
, vty
);
6918 DEFUN (ip_pim_spt_switchover_infinity
,
6919 ip_pim_spt_switchover_infinity_cmd
,
6920 "ip pim spt-switchover infinity-and-beyond",
6924 "Never switch to SPT Tree\n")
6926 const char *vrfname
;
6927 char spt_plist_xpath
[XPATH_MAXLEN
];
6928 char spt_action_xpath
[XPATH_MAXLEN
];
6930 vrfname
= pim_cli_get_vrf_name(vty
);
6931 if (vrfname
== NULL
)
6932 return CMD_WARNING_CONFIG_FAILED
;
6934 snprintf(spt_plist_xpath
, sizeof(spt_plist_xpath
),
6935 FRR_PIM_AF_XPATH
, "frr-pim:pimd", "pim", vrfname
,
6936 "frr-routing:ipv4");
6937 strlcat(spt_plist_xpath
, "/spt-switchover/spt-infinity-prefix-list",
6938 sizeof(spt_plist_xpath
));
6940 snprintf(spt_action_xpath
, sizeof(spt_action_xpath
),
6941 FRR_PIM_AF_XPATH
, "frr-pim:pimd", "pim", vrfname
,
6942 "frr-routing:ipv4");
6943 strlcat(spt_action_xpath
, "/spt-switchover/spt-action",
6944 sizeof(spt_action_xpath
));
6946 if (yang_dnode_exists(vty
->candidate_config
->dnode
, spt_plist_xpath
))
6947 nb_cli_enqueue_change(vty
, spt_plist_xpath
, NB_OP_DESTROY
,
6949 nb_cli_enqueue_change(vty
, spt_action_xpath
, NB_OP_MODIFY
,
6950 "PIM_SPT_INFINITY");
6952 return nb_cli_apply_changes(vty
, NULL
);
6955 DEFUN (ip_pim_spt_switchover_infinity_plist
,
6956 ip_pim_spt_switchover_infinity_plist_cmd
,
6957 "ip pim spt-switchover infinity-and-beyond prefix-list WORD",
6961 "Never switch to SPT Tree\n"
6962 "Prefix-List to control which groups to switch\n"
6963 "Prefix-List name\n")
6965 const char *vrfname
;
6966 char spt_plist_xpath
[XPATH_MAXLEN
];
6967 char spt_action_xpath
[XPATH_MAXLEN
];
6969 vrfname
= pim_cli_get_vrf_name(vty
);
6970 if (vrfname
== NULL
)
6971 return CMD_WARNING_CONFIG_FAILED
;
6973 snprintf(spt_plist_xpath
, sizeof(spt_plist_xpath
),
6974 FRR_PIM_AF_XPATH
, "frr-pim:pimd", "pim", vrfname
,
6975 "frr-routing:ipv4");
6976 strlcat(spt_plist_xpath
, "/spt-switchover/spt-infinity-prefix-list",
6977 sizeof(spt_plist_xpath
));
6979 snprintf(spt_action_xpath
, sizeof(spt_action_xpath
),
6980 FRR_PIM_AF_XPATH
, "frr-pim:pimd", "pim", vrfname
,
6981 "frr-routing:ipv4");
6982 strlcat(spt_action_xpath
, "/spt-switchover/spt-action",
6983 sizeof(spt_action_xpath
));
6985 nb_cli_enqueue_change(vty
, spt_action_xpath
, NB_OP_MODIFY
,
6986 "PIM_SPT_INFINITY");
6987 nb_cli_enqueue_change(vty
, spt_plist_xpath
, NB_OP_MODIFY
,
6990 return nb_cli_apply_changes(vty
, NULL
);
6993 DEFUN (no_ip_pim_spt_switchover_infinity
,
6994 no_ip_pim_spt_switchover_infinity_cmd
,
6995 "no ip pim spt-switchover infinity-and-beyond",
7000 "Never switch to SPT Tree\n")
7002 const char *vrfname
;
7003 char spt_plist_xpath
[XPATH_MAXLEN
];
7004 char spt_action_xpath
[XPATH_MAXLEN
];
7006 vrfname
= pim_cli_get_vrf_name(vty
);
7007 if (vrfname
== NULL
)
7008 return CMD_WARNING_CONFIG_FAILED
;
7010 snprintf(spt_plist_xpath
, sizeof(spt_plist_xpath
),
7011 FRR_PIM_AF_XPATH
, "frr-pim:pimd", "pim", vrfname
,
7012 "frr-routing:ipv4");
7013 strlcat(spt_plist_xpath
, "/spt-switchover/spt-infinity-prefix-list",
7014 sizeof(spt_plist_xpath
));
7016 snprintf(spt_action_xpath
, sizeof(spt_action_xpath
),
7017 FRR_PIM_AF_XPATH
, "frr-pim:pimd", "pim", vrfname
,
7018 "frr-routing:ipv4");
7019 strlcat(spt_action_xpath
, "/spt-switchover/spt-action",
7020 sizeof(spt_action_xpath
));
7022 nb_cli_enqueue_change(vty
, spt_plist_xpath
, NB_OP_DESTROY
, NULL
);
7023 nb_cli_enqueue_change(vty
, spt_action_xpath
, NB_OP_MODIFY
,
7024 "PIM_SPT_IMMEDIATE");
7026 return nb_cli_apply_changes(vty
, NULL
);
7029 DEFUN (no_ip_pim_spt_switchover_infinity_plist
,
7030 no_ip_pim_spt_switchover_infinity_plist_cmd
,
7031 "no ip pim spt-switchover infinity-and-beyond prefix-list WORD",
7036 "Never switch to SPT Tree\n"
7037 "Prefix-List to control which groups to switch\n"
7038 "Prefix-List name\n")
7040 const char *vrfname
;
7041 char spt_plist_xpath
[XPATH_MAXLEN
];
7042 char spt_action_xpath
[XPATH_MAXLEN
];
7044 vrfname
= pim_cli_get_vrf_name(vty
);
7045 if (vrfname
== NULL
)
7046 return CMD_WARNING_CONFIG_FAILED
;
7048 snprintf(spt_plist_xpath
, sizeof(spt_plist_xpath
),
7049 FRR_PIM_AF_XPATH
, "frr-pim:pimd", "pim", vrfname
,
7050 "frr-routing:ipv4");
7051 strlcat(spt_plist_xpath
, "/spt-switchover/spt-infinity-prefix-list",
7052 sizeof(spt_plist_xpath
));
7054 snprintf(spt_action_xpath
, sizeof(spt_action_xpath
),
7055 FRR_PIM_AF_XPATH
, "frr-pim:pimd", "pim", vrfname
,
7056 "frr-routing:ipv4");
7057 strlcat(spt_action_xpath
, "/spt-switchover/spt-action",
7058 sizeof(spt_action_xpath
));
7060 nb_cli_enqueue_change(vty
, spt_plist_xpath
, NB_OP_DESTROY
, NULL
);
7061 nb_cli_enqueue_change(vty
, spt_action_xpath
, NB_OP_MODIFY
,
7062 "PIM_SPT_IMMEDIATE");
7064 return nb_cli_apply_changes(vty
, NULL
);
7067 DEFPY (pim_register_accept_list
,
7068 pim_register_accept_list_cmd
,
7069 "[no] ip pim register-accept-list WORD$word",
7073 "Only accept registers from a specific source prefix list\n"
7074 "Prefix-List name\n")
7076 const char *vrfname
;
7077 char reg_alist_xpath
[XPATH_MAXLEN
];
7079 vrfname
= pim_cli_get_vrf_name(vty
);
7080 if (vrfname
== NULL
)
7081 return CMD_WARNING_CONFIG_FAILED
;
7083 snprintf(reg_alist_xpath
, sizeof(reg_alist_xpath
),
7084 FRR_PIM_AF_XPATH
, "frr-pim:pimd", "pim", vrfname
,
7085 "frr-routing:ipv4");
7086 strlcat(reg_alist_xpath
, "/register-accept-list",
7087 sizeof(reg_alist_xpath
));
7090 nb_cli_enqueue_change(vty
, reg_alist_xpath
,
7091 NB_OP_DESTROY
, NULL
);
7093 nb_cli_enqueue_change(vty
, reg_alist_xpath
,
7094 NB_OP_MODIFY
, word
);
7096 return nb_cli_apply_changes(vty
, NULL
);
7099 DEFUN (ip_pim_joinprune_time
,
7100 ip_pim_joinprune_time_cmd
,
7101 "ip pim join-prune-interval (1-65535)",
7103 "pim multicast routing\n"
7104 "Join Prune Send Interval\n"
7107 nb_cli_enqueue_change(vty
, "/frr-pim:pim/join-prune-interval",
7108 NB_OP_MODIFY
, argv
[3]->arg
);
7110 return nb_cli_apply_changes(vty
, NULL
);
7113 DEFUN (no_ip_pim_joinprune_time
,
7114 no_ip_pim_joinprune_time_cmd
,
7115 "no ip pim join-prune-interval [(1-65535)]",
7118 "pim multicast routing\n"
7119 "Join Prune Send Interval\n"
7122 nb_cli_enqueue_change(vty
, "/frr-pim:pim/join-prune-interval",
7123 NB_OP_DESTROY
, NULL
);
7125 return nb_cli_apply_changes(vty
, NULL
);
7128 DEFUN (ip_pim_register_suppress
,
7129 ip_pim_register_suppress_cmd
,
7130 "ip pim register-suppress-time (1-65535)",
7132 "pim multicast routing\n"
7133 "Register Suppress Timer\n"
7136 nb_cli_enqueue_change(vty
, "/frr-pim:pim/register-suppress-time",
7137 NB_OP_MODIFY
, argv
[3]->arg
);
7139 return nb_cli_apply_changes(vty
, NULL
);
7142 DEFUN (no_ip_pim_register_suppress
,
7143 no_ip_pim_register_suppress_cmd
,
7144 "no ip pim register-suppress-time [(1-65535)]",
7147 "pim multicast routing\n"
7148 "Register Suppress Timer\n"
7151 nb_cli_enqueue_change(vty
, "/frr-pim:pim/register-suppress-time",
7152 NB_OP_DESTROY
, NULL
);
7154 return nb_cli_apply_changes(vty
, NULL
);
7157 DEFUN (ip_pim_rp_keep_alive
,
7158 ip_pim_rp_keep_alive_cmd
,
7159 "ip pim rp keep-alive-timer (1-65535)",
7161 "pim multicast routing\n"
7163 "Keep alive Timer\n"
7166 const char *vrfname
;
7167 char rp_ka_timer_xpath
[XPATH_MAXLEN
];
7169 vrfname
= pim_cli_get_vrf_name(vty
);
7170 if (vrfname
== NULL
)
7171 return CMD_WARNING_CONFIG_FAILED
;
7173 snprintf(rp_ka_timer_xpath
, sizeof(rp_ka_timer_xpath
),
7174 FRR_PIM_XPATH
, "frr-pim:pimd", "pim", vrfname
);
7175 strlcat(rp_ka_timer_xpath
, "/rp-keep-alive-timer",
7176 sizeof(rp_ka_timer_xpath
));
7178 nb_cli_enqueue_change(vty
, rp_ka_timer_xpath
, NB_OP_MODIFY
,
7181 return nb_cli_apply_changes(vty
, NULL
);
7184 DEFUN (no_ip_pim_rp_keep_alive
,
7185 no_ip_pim_rp_keep_alive_cmd
,
7186 "no ip pim rp keep-alive-timer [(1-65535)]",
7189 "pim multicast routing\n"
7191 "Keep alive Timer\n"
7194 const char *vrfname
;
7195 char rp_ka_timer
[6];
7196 char rp_ka_timer_xpath
[XPATH_MAXLEN
];
7200 v
= yang_dnode_get_uint16(vty
->candidate_config
->dnode
,
7201 "/frr-pim:pim/register-suppress-time");
7202 v
= 3 * v
+ PIM_REGISTER_PROBE_TIME_DEFAULT
;
7205 snprintf(rp_ka_timer
, sizeof(rp_ka_timer
), "%u", v
);
7207 vrfname
= pim_cli_get_vrf_name(vty
);
7208 if (vrfname
== NULL
)
7209 return CMD_WARNING_CONFIG_FAILED
;
7211 snprintf(rp_ka_timer_xpath
, sizeof(rp_ka_timer_xpath
),
7212 FRR_PIM_XPATH
, "frr-pim:pimd", "pim", vrfname
);
7213 strlcat(rp_ka_timer_xpath
, "/rp-keep-alive-timer",
7214 sizeof(rp_ka_timer_xpath
));
7216 nb_cli_enqueue_change(vty
, rp_ka_timer_xpath
, NB_OP_MODIFY
,
7219 return nb_cli_apply_changes(vty
, NULL
);
7222 DEFUN (ip_pim_keep_alive
,
7223 ip_pim_keep_alive_cmd
,
7224 "ip pim keep-alive-timer (1-65535)",
7226 "pim multicast routing\n"
7227 "Keep alive Timer\n"
7230 const char *vrfname
;
7231 char ka_timer_xpath
[XPATH_MAXLEN
];
7233 vrfname
= pim_cli_get_vrf_name(vty
);
7234 if (vrfname
== NULL
)
7235 return CMD_WARNING_CONFIG_FAILED
;
7237 snprintf(ka_timer_xpath
, sizeof(ka_timer_xpath
), FRR_PIM_XPATH
,
7238 "frr-pim:pimd", "pim", vrfname
);
7239 strlcat(ka_timer_xpath
, "/keep-alive-timer", sizeof(ka_timer_xpath
));
7241 nb_cli_enqueue_change(vty
, ka_timer_xpath
, NB_OP_MODIFY
,
7244 return nb_cli_apply_changes(vty
, NULL
);
7247 DEFUN (no_ip_pim_keep_alive
,
7248 no_ip_pim_keep_alive_cmd
,
7249 "no ip pim keep-alive-timer [(1-65535)]",
7252 "pim multicast routing\n"
7253 "Keep alive Timer\n"
7256 const char *vrfname
;
7257 char ka_timer_xpath
[XPATH_MAXLEN
];
7259 vrfname
= pim_cli_get_vrf_name(vty
);
7260 if (vrfname
== NULL
)
7261 return CMD_WARNING_CONFIG_FAILED
;
7263 snprintf(ka_timer_xpath
, sizeof(ka_timer_xpath
), FRR_PIM_XPATH
,
7264 "frr-pim:pimd", "pim", vrfname
);
7265 strlcat(ka_timer_xpath
, "/keep-alive-timer", sizeof(ka_timer_xpath
));
7267 nb_cli_enqueue_change(vty
, ka_timer_xpath
, NB_OP_DESTROY
, NULL
);
7269 return nb_cli_apply_changes(vty
, NULL
);
7272 DEFUN (ip_pim_packets
,
7274 "ip pim packets (1-255)",
7276 "pim multicast routing\n"
7277 "packets to process at one time per fd\n"
7278 "Number of packets\n")
7280 nb_cli_enqueue_change(vty
, "/frr-pim:pim/packets", NB_OP_MODIFY
,
7283 return nb_cli_apply_changes(vty
, NULL
);
7286 DEFUN (no_ip_pim_packets
,
7287 no_ip_pim_packets_cmd
,
7288 "no ip pim packets [(1-255)]",
7291 "pim multicast routing\n"
7292 "packets to process at one time per fd\n"
7295 nb_cli_enqueue_change(vty
, "/frr-pim:pim/packets", NB_OP_DESTROY
, NULL
);
7297 return nb_cli_apply_changes(vty
, NULL
);
7300 DEFPY (igmp_group_watermark
,
7301 igmp_group_watermark_cmd
,
7302 "ip igmp watermark-warn (1-65535)$limit",
7305 "Configure group limit for watermark warning\n"
7306 "Group count to generate watermark warning\n")
7308 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7309 pim
->igmp_watermark_limit
= limit
;
7314 DEFPY (no_igmp_group_watermark
,
7315 no_igmp_group_watermark_cmd
,
7316 "no ip igmp watermark-warn [(1-65535)$limit]",
7320 "Unconfigure group limit for watermark warning\n"
7323 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7324 pim
->igmp_watermark_limit
= 0;
7329 DEFUN (ip_pim_v6_secondary
,
7330 ip_pim_v6_secondary_cmd
,
7331 "ip pim send-v6-secondary",
7333 "pim multicast routing\n"
7334 "Send v6 secondary addresses\n")
7336 const char *vrfname
;
7337 char send_v6_secondary_xpath
[XPATH_MAXLEN
];
7339 vrfname
= pim_cli_get_vrf_name(vty
);
7340 if (vrfname
== NULL
)
7341 return CMD_WARNING_CONFIG_FAILED
;
7343 snprintf(send_v6_secondary_xpath
, sizeof(send_v6_secondary_xpath
),
7345 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4");
7346 strlcat(send_v6_secondary_xpath
, "/send-v6-secondary",
7347 sizeof(send_v6_secondary_xpath
));
7349 nb_cli_enqueue_change(vty
, send_v6_secondary_xpath
, NB_OP_MODIFY
,
7352 return nb_cli_apply_changes(vty
, NULL
);
7355 DEFUN (no_ip_pim_v6_secondary
,
7356 no_ip_pim_v6_secondary_cmd
,
7357 "no ip pim send-v6-secondary",
7360 "pim multicast routing\n"
7361 "Send v6 secondary addresses\n")
7363 const char *vrfname
;
7364 char send_v6_secondary_xpath
[XPATH_MAXLEN
];
7366 vrfname
= pim_cli_get_vrf_name(vty
);
7367 if (vrfname
== NULL
)
7368 return CMD_WARNING_CONFIG_FAILED
;
7370 snprintf(send_v6_secondary_xpath
, sizeof(send_v6_secondary_xpath
),
7372 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4");
7373 strlcat(send_v6_secondary_xpath
, "/send-v6-secondary",
7374 sizeof(send_v6_secondary_xpath
));
7376 nb_cli_enqueue_change(vty
, send_v6_secondary_xpath
, NB_OP_MODIFY
,
7379 return nb_cli_apply_changes(vty
, NULL
);
7384 "ip pim rp A.B.C.D [A.B.C.D/M]",
7386 "pim multicast routing\n"
7388 "ip address of RP\n"
7389 "Group Address range to cover\n")
7391 const char *vrfname
;
7392 int idx_rp
= 3, idx_group
= 4;
7393 char rp_group_xpath
[XPATH_MAXLEN
];
7395 struct prefix group
;
7396 struct in_addr rp_addr
;
7397 const char *group_str
=
7398 (argc
== 5) ? argv
[idx_group
]->arg
: "224.0.0.0/4";
7400 result
= str2prefix(group_str
, &group
);
7404 prefix_copy(&temp
, &group
);
7406 if (!prefix_same(&group
, &temp
)) {
7407 vty_out(vty
, "%% Inconsistent address and mask: %s\n",
7409 return CMD_WARNING_CONFIG_FAILED
;
7414 vty_out(vty
, "%% Bad group address specified: %s\n",
7416 return CMD_WARNING_CONFIG_FAILED
;
7419 result
= inet_pton(AF_INET
, argv
[idx_rp
]->arg
, &rp_addr
);
7421 vty_out(vty
, "%% Bad RP address specified: %s\n",
7423 return CMD_WARNING_CONFIG_FAILED
;
7426 vrfname
= pim_cli_get_vrf_name(vty
);
7427 if (vrfname
== NULL
)
7428 return CMD_WARNING_CONFIG_FAILED
;
7430 snprintf(rp_group_xpath
, sizeof(rp_group_xpath
),
7431 FRR_PIM_STATIC_RP_XPATH
,
7432 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4",
7434 strlcat(rp_group_xpath
, "/group-list", sizeof(rp_group_xpath
));
7436 nb_cli_enqueue_change(vty
, rp_group_xpath
, NB_OP_CREATE
, group_str
);
7438 return nb_cli_apply_changes(vty
, NULL
);
7441 DEFUN (ip_pim_rp_prefix_list
,
7442 ip_pim_rp_prefix_list_cmd
,
7443 "ip pim rp A.B.C.D prefix-list WORD",
7445 "pim multicast routing\n"
7447 "ip address of RP\n"
7448 "group prefix-list filter\n"
7449 "Name of a prefix-list\n")
7451 int idx_rp
= 3, idx_plist
= 5;
7452 const char *vrfname
;
7453 char rp_plist_xpath
[XPATH_MAXLEN
];
7455 vrfname
= pim_cli_get_vrf_name(vty
);
7456 if (vrfname
== NULL
)
7457 return CMD_WARNING_CONFIG_FAILED
;
7459 snprintf(rp_plist_xpath
, sizeof(rp_plist_xpath
),
7460 FRR_PIM_STATIC_RP_XPATH
,
7461 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4",
7463 strlcat(rp_plist_xpath
, "/prefix-list", sizeof(rp_plist_xpath
));
7465 nb_cli_enqueue_change(vty
, rp_plist_xpath
, NB_OP_MODIFY
,
7466 argv
[idx_plist
]->arg
);
7468 return nb_cli_apply_changes(vty
, NULL
);
7471 DEFUN (no_ip_pim_rp
,
7473 "no ip pim rp A.B.C.D [A.B.C.D/M]",
7476 "pim multicast routing\n"
7478 "ip address of RP\n"
7479 "Group Address range to cover\n")
7481 int idx_rp
= 4, idx_group
= 5;
7482 const char *group_str
=
7483 (argc
== 6) ? argv
[idx_group
]->arg
: "224.0.0.0/4";
7484 char group_list_xpath
[XPATH_MAXLEN
+ 32];
7485 char group_xpath
[XPATH_MAXLEN
+ 64];
7486 char rp_xpath
[XPATH_MAXLEN
];
7487 const char *vrfname
;
7488 const struct lyd_node
*group_dnode
;
7490 vrfname
= pim_cli_get_vrf_name(vty
);
7491 if (vrfname
== NULL
)
7492 return CMD_WARNING_CONFIG_FAILED
;
7494 snprintf(rp_xpath
, sizeof(rp_xpath
), FRR_PIM_STATIC_RP_XPATH
,
7495 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4",
7498 snprintf(group_list_xpath
, sizeof(group_list_xpath
), "%s/group-list",
7501 snprintf(group_xpath
, sizeof(group_xpath
), "%s[.='%s']",
7502 group_list_xpath
, group_str
);
7504 if (!yang_dnode_exists(vty
->candidate_config
->dnode
, group_xpath
)) {
7505 vty_out(vty
, "%% Unable to find specified RP\n");
7509 group_dnode
= yang_dnode_get(vty
->candidate_config
->dnode
, group_xpath
);
7511 if (yang_is_last_list_dnode(group_dnode
))
7512 nb_cli_enqueue_change(vty
, rp_xpath
, NB_OP_DESTROY
, NULL
);
7514 nb_cli_enqueue_change(vty
, group_list_xpath
, NB_OP_DESTROY
,
7517 return nb_cli_apply_changes(vty
, NULL
);
7520 DEFUN (no_ip_pim_rp_prefix_list
,
7521 no_ip_pim_rp_prefix_list_cmd
,
7522 "no ip pim rp A.B.C.D prefix-list WORD",
7525 "pim multicast routing\n"
7527 "ip address of RP\n"
7528 "group prefix-list filter\n"
7529 "Name of a prefix-list\n")
7533 char rp_xpath
[XPATH_MAXLEN
];
7534 char plist_xpath
[XPATH_MAXLEN
];
7535 const char *vrfname
;
7536 const struct lyd_node
*plist_dnode
;
7539 vrfname
= pim_cli_get_vrf_name(vty
);
7540 if (vrfname
== NULL
)
7541 return CMD_WARNING_CONFIG_FAILED
;
7543 snprintf(rp_xpath
, sizeof(rp_xpath
), FRR_PIM_STATIC_RP_XPATH
,
7544 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4",
7547 snprintf(plist_xpath
, sizeof(plist_xpath
), FRR_PIM_STATIC_RP_XPATH
,
7548 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4",
7550 strlcat(plist_xpath
, "/prefix-list", sizeof(plist_xpath
));
7552 plist_dnode
= yang_dnode_get(vty
->candidate_config
->dnode
, plist_xpath
);
7554 vty_out(vty
, "%% Unable to find specified RP\n");
7558 plist
= yang_dnode_get_string(plist_dnode
, plist_xpath
);
7559 if (strcmp(argv
[idx_plist
]->arg
, plist
)) {
7560 vty_out(vty
, "%% Unable to find specified RP\n");
7564 nb_cli_enqueue_change(vty
, rp_xpath
, NB_OP_DESTROY
, NULL
);
7566 return nb_cli_apply_changes(vty
, NULL
);
7569 DEFUN (ip_pim_ssm_prefix_list
,
7570 ip_pim_ssm_prefix_list_cmd
,
7571 "ip pim ssm prefix-list WORD",
7573 "pim multicast routing\n"
7574 "Source Specific Multicast\n"
7575 "group range prefix-list filter\n"
7576 "Name of a prefix-list\n")
7578 const char *vrfname
;
7579 char ssm_plist_xpath
[XPATH_MAXLEN
];
7581 vrfname
= pim_cli_get_vrf_name(vty
);
7582 if (vrfname
== NULL
)
7583 return CMD_WARNING_CONFIG_FAILED
;
7585 snprintf(ssm_plist_xpath
, sizeof(ssm_plist_xpath
), FRR_PIM_AF_XPATH
,
7586 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4");
7587 strlcat(ssm_plist_xpath
, "/ssm-prefix-list", sizeof(ssm_plist_xpath
));
7589 nb_cli_enqueue_change(vty
, ssm_plist_xpath
, NB_OP_MODIFY
, argv
[4]->arg
);
7591 return nb_cli_apply_changes(vty
, NULL
);
7594 DEFUN (no_ip_pim_ssm_prefix_list
,
7595 no_ip_pim_ssm_prefix_list_cmd
,
7596 "no ip pim ssm prefix-list",
7599 "pim multicast routing\n"
7600 "Source Specific Multicast\n"
7601 "group range prefix-list filter\n")
7603 const char *vrfname
;
7604 char ssm_plist_xpath
[XPATH_MAXLEN
];
7606 vrfname
= pim_cli_get_vrf_name(vty
);
7607 if (vrfname
== NULL
)
7608 return CMD_WARNING_CONFIG_FAILED
;
7610 snprintf(ssm_plist_xpath
, sizeof(ssm_plist_xpath
),
7612 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4");
7613 strlcat(ssm_plist_xpath
, "/ssm-prefix-list", sizeof(ssm_plist_xpath
));
7615 nb_cli_enqueue_change(vty
, ssm_plist_xpath
, NB_OP_DESTROY
, NULL
);
7617 return nb_cli_apply_changes(vty
, NULL
);
7620 DEFUN (no_ip_pim_ssm_prefix_list_name
,
7621 no_ip_pim_ssm_prefix_list_name_cmd
,
7622 "no ip pim ssm prefix-list WORD",
7625 "pim multicast routing\n"
7626 "Source Specific Multicast\n"
7627 "group range prefix-list filter\n"
7628 "Name of a prefix-list\n")
7630 const char *vrfname
;
7631 const struct lyd_node
*ssm_plist_dnode
;
7632 char ssm_plist_xpath
[XPATH_MAXLEN
];
7633 const char *ssm_plist_name
;
7635 vrfname
= pim_cli_get_vrf_name(vty
);
7636 if (vrfname
== NULL
)
7637 return CMD_WARNING_CONFIG_FAILED
;
7639 snprintf(ssm_plist_xpath
, sizeof(ssm_plist_xpath
),
7641 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4");
7642 strlcat(ssm_plist_xpath
, "/ssm-prefix-list", sizeof(ssm_plist_xpath
));
7643 ssm_plist_dnode
= yang_dnode_get(vty
->candidate_config
->dnode
,
7646 if (!ssm_plist_dnode
) {
7648 "%% pim ssm prefix-list %s doesn't exist\n",
7650 return CMD_WARNING_CONFIG_FAILED
;
7653 ssm_plist_name
= yang_dnode_get_string(ssm_plist_dnode
, ".");
7655 if (ssm_plist_name
&& !strcmp(ssm_plist_name
, argv
[5]->arg
)) {
7656 nb_cli_enqueue_change(vty
, ssm_plist_xpath
, NB_OP_DESTROY
,
7659 return nb_cli_apply_changes(vty
, NULL
);
7662 vty_out(vty
, "%% pim ssm prefix-list %s doesn't exist\n", argv
[5]->arg
);
7664 return CMD_WARNING_CONFIG_FAILED
;
7667 static void ip_pim_ssm_show_group_range(struct pim_instance
*pim
,
7668 struct vty
*vty
, bool uj
)
7670 struct pim_ssm
*ssm
= pim
->ssm_info
;
7671 const char *range_str
=
7672 ssm
->plist_name
? ssm
->plist_name
: PIM_SSM_STANDARD_RANGE
;
7676 json
= json_object_new_object();
7677 json_object_string_add(json
, "ssmGroups", range_str
);
7678 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
7679 json
, JSON_C_TO_STRING_PRETTY
));
7680 json_object_free(json
);
7682 vty_out(vty
, "SSM group range : %s\n", range_str
);
7685 DEFUN (show_ip_pim_ssm_range
,
7686 show_ip_pim_ssm_range_cmd
,
7687 "show ip pim [vrf NAME] group-type [json]",
7696 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
7697 bool uj
= use_json(argc
, argv
);
7702 ip_pim_ssm_show_group_range(vrf
->info
, vty
, uj
);
7707 static void ip_pim_ssm_show_group_type(struct pim_instance
*pim
,
7708 struct vty
*vty
, bool uj
,
7711 struct in_addr group_addr
;
7712 const char *type_str
;
7715 result
= inet_pton(AF_INET
, group
, &group_addr
);
7717 type_str
= "invalid";
7719 if (pim_is_group_224_4(group_addr
))
7721 pim_is_grp_ssm(pim
, group_addr
) ? "SSM" : "ASM";
7723 type_str
= "not-multicast";
7728 json
= json_object_new_object();
7729 json_object_string_add(json
, "groupType", type_str
);
7730 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
7731 json
, JSON_C_TO_STRING_PRETTY
));
7732 json_object_free(json
);
7734 vty_out(vty
, "Group type : %s\n", type_str
);
7737 DEFUN (show_ip_pim_group_type
,
7738 show_ip_pim_group_type_cmd
,
7739 "show ip pim [vrf NAME] group-type A.B.C.D [json]",
7744 "multicast group type\n"
7749 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
7750 bool uj
= use_json(argc
, argv
);
7755 argv_find(argv
, argc
, "A.B.C.D", &idx
);
7756 ip_pim_ssm_show_group_type(vrf
->info
, vty
, uj
, argv
[idx
]->arg
);
7761 DEFUN (show_ip_pim_bsr
,
7762 show_ip_pim_bsr_cmd
,
7763 "show ip pim bsr [json]",
7767 "boot-strap router information\n"
7771 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
7772 bool uj
= use_json(argc
, argv
);
7777 pim_show_bsr(vrf
->info
, vty
, uj
);
7784 "ip ssmpingd [A.B.C.D]",
7790 const char *source_str
= (argc
== 3) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
7791 const char *vrfname
;
7792 char ssmpingd_ip_xpath
[XPATH_MAXLEN
];
7794 vrfname
= pim_cli_get_vrf_name(vty
);
7795 if (vrfname
== NULL
)
7796 return CMD_WARNING_CONFIG_FAILED
;
7798 snprintf(ssmpingd_ip_xpath
, sizeof(ssmpingd_ip_xpath
),
7800 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4");
7801 strlcat(ssmpingd_ip_xpath
, "/ssm-pingd-source-ip",
7802 sizeof(ssmpingd_ip_xpath
));
7804 nb_cli_enqueue_change(vty
, ssmpingd_ip_xpath
, NB_OP_CREATE
,
7807 return nb_cli_apply_changes(vty
, NULL
);
7810 DEFUN (no_ip_ssmpingd
,
7812 "no ip ssmpingd [A.B.C.D]",
7818 const char *vrfname
;
7820 const char *source_str
= (argc
== 4) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
7821 char ssmpingd_ip_xpath
[XPATH_MAXLEN
];
7823 vrfname
= pim_cli_get_vrf_name(vty
);
7824 if (vrfname
== NULL
)
7825 return CMD_WARNING_CONFIG_FAILED
;
7827 snprintf(ssmpingd_ip_xpath
, sizeof(ssmpingd_ip_xpath
),
7829 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4");
7830 strlcat(ssmpingd_ip_xpath
, "/ssm-pingd-source-ip",
7831 sizeof(ssmpingd_ip_xpath
));
7833 nb_cli_enqueue_change(vty
, ssmpingd_ip_xpath
, NB_OP_DESTROY
,
7836 return nb_cli_apply_changes(vty
, NULL
);
7843 "pim multicast routing\n"
7844 "Enable PIM ECMP \n")
7846 const char *vrfname
;
7847 char ecmp_xpath
[XPATH_MAXLEN
];
7849 vrfname
= pim_cli_get_vrf_name(vty
);
7850 if (vrfname
== NULL
)
7851 return CMD_WARNING_CONFIG_FAILED
;
7853 snprintf(ecmp_xpath
, sizeof(ecmp_xpath
), FRR_PIM_XPATH
,
7854 "frr-pim:pimd", "pim", vrfname
);
7855 strlcat(ecmp_xpath
, "/ecmp", sizeof(ecmp_xpath
));
7857 nb_cli_enqueue_change(vty
, ecmp_xpath
, NB_OP_MODIFY
, "true");
7858 return nb_cli_apply_changes(vty
, NULL
);
7861 DEFUN (no_ip_pim_ecmp
,
7866 "pim multicast routing\n"
7867 "Disable PIM ECMP \n")
7869 const char *vrfname
;
7870 char ecmp_xpath
[XPATH_MAXLEN
];
7872 vrfname
= pim_cli_get_vrf_name(vty
);
7873 if (vrfname
== NULL
)
7874 return CMD_WARNING_CONFIG_FAILED
;
7876 snprintf(ecmp_xpath
, sizeof(ecmp_xpath
), FRR_PIM_XPATH
,
7877 "frr-pim:pimd", "pim", vrfname
);
7878 strlcat(ecmp_xpath
, "/ecmp", sizeof(ecmp_xpath
));
7880 nb_cli_enqueue_change(vty
, ecmp_xpath
, NB_OP_MODIFY
, "false");
7882 return nb_cli_apply_changes(vty
, NULL
);
7885 DEFUN (ip_pim_ecmp_rebalance
,
7886 ip_pim_ecmp_rebalance_cmd
,
7887 "ip pim ecmp rebalance",
7889 "pim multicast routing\n"
7890 "Enable PIM ECMP \n"
7891 "Enable PIM ECMP Rebalance\n")
7893 const char *vrfname
;
7894 char ecmp_xpath
[XPATH_MAXLEN
];
7895 char ecmp_rebalance_xpath
[XPATH_MAXLEN
];
7897 vrfname
= pim_cli_get_vrf_name(vty
);
7898 if (vrfname
== NULL
)
7899 return CMD_WARNING_CONFIG_FAILED
;
7901 snprintf(ecmp_xpath
, sizeof(ecmp_xpath
), FRR_PIM_XPATH
,
7902 "frr-pim:pimd", "pim", vrfname
);
7903 strlcat(ecmp_xpath
, "/ecmp", sizeof(ecmp_xpath
));
7904 snprintf(ecmp_rebalance_xpath
, sizeof(ecmp_rebalance_xpath
),
7906 "frr-pim:pimd", "pim", vrfname
);
7907 strlcat(ecmp_rebalance_xpath
, "/ecmp-rebalance",
7908 sizeof(ecmp_rebalance_xpath
));
7910 nb_cli_enqueue_change(vty
, ecmp_xpath
, NB_OP_MODIFY
, "true");
7911 nb_cli_enqueue_change(vty
, ecmp_rebalance_xpath
, NB_OP_MODIFY
, "true");
7913 return nb_cli_apply_changes(vty
, NULL
);
7916 DEFUN (no_ip_pim_ecmp_rebalance
,
7917 no_ip_pim_ecmp_rebalance_cmd
,
7918 "no ip pim ecmp rebalance",
7921 "pim multicast routing\n"
7922 "Disable PIM ECMP \n"
7923 "Disable PIM ECMP Rebalance\n")
7925 const char *vrfname
;
7926 char ecmp_rebalance_xpath
[XPATH_MAXLEN
];
7928 vrfname
= pim_cli_get_vrf_name(vty
);
7929 if (vrfname
== NULL
)
7930 return CMD_WARNING_CONFIG_FAILED
;
7932 snprintf(ecmp_rebalance_xpath
, sizeof(ecmp_rebalance_xpath
),
7934 "frr-pim:pimd", "pim", vrfname
);
7935 strlcat(ecmp_rebalance_xpath
, "/ecmp-rebalance",
7936 sizeof(ecmp_rebalance_xpath
));
7938 nb_cli_enqueue_change(vty
, ecmp_rebalance_xpath
, NB_OP_MODIFY
, "false");
7940 return nb_cli_apply_changes(vty
, NULL
);
7943 DEFUN (interface_ip_igmp
,
7944 interface_ip_igmp_cmd
,
7949 nb_cli_enqueue_change(vty
, "./igmp-enable", NB_OP_MODIFY
, "true");
7951 return nb_cli_apply_changes(vty
, "./frr-igmp:igmp");
7954 DEFUN (interface_no_ip_igmp
,
7955 interface_no_ip_igmp_cmd
,
7961 const struct lyd_node
*pim_enable_dnode
;
7962 char pim_if_xpath
[XPATH_MAXLEN
+ 20];
7964 snprintf(pim_if_xpath
, sizeof(pim_if_xpath
),
7965 "%s/frr-pim:pim", VTY_CURR_XPATH
);
7967 pim_enable_dnode
= yang_dnode_getf(vty
->candidate_config
->dnode
,
7968 "%s/pim-enable", pim_if_xpath
);
7969 if (!pim_enable_dnode
) {
7970 nb_cli_enqueue_change(vty
, pim_if_xpath
, NB_OP_DESTROY
, NULL
);
7971 nb_cli_enqueue_change(vty
, ".", NB_OP_DESTROY
, NULL
);
7973 if (!yang_dnode_get_bool(pim_enable_dnode
, ".")) {
7974 nb_cli_enqueue_change(vty
, pim_if_xpath
, NB_OP_DESTROY
,
7976 nb_cli_enqueue_change(vty
, ".", NB_OP_DESTROY
, NULL
);
7978 nb_cli_enqueue_change(vty
, "./igmp-enable",
7979 NB_OP_MODIFY
, "false");
7982 return nb_cli_apply_changes(vty
, "./frr-igmp:igmp");
7985 DEFUN (interface_ip_igmp_join
,
7986 interface_ip_igmp_join_cmd
,
7987 "ip igmp join A.B.C.D [A.B.C.D]",
7990 "IGMP join multicast group\n"
7991 "Multicast group address\n"
7996 const char *source_str
;
7997 char xpath
[XPATH_MAXLEN
];
8000 source_str
= argv
[idx_source
]->arg
;
8002 if (strcmp(source_str
, "0.0.0.0") == 0) {
8003 vty_out(vty
, "Bad source address %s\n",
8004 argv
[idx_source
]->arg
);
8005 return CMD_WARNING_CONFIG_FAILED
;
8008 source_str
= "0.0.0.0";
8010 snprintf(xpath
, sizeof(xpath
), FRR_IGMP_JOIN_XPATH
,
8011 "frr-routing:ipv4", argv
[idx_group
]->arg
, source_str
);
8013 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
8015 return nb_cli_apply_changes(vty
, NULL
);
8018 DEFUN (interface_no_ip_igmp_join
,
8019 interface_no_ip_igmp_join_cmd
,
8020 "no ip igmp join A.B.C.D [A.B.C.D]",
8024 "IGMP join multicast group\n"
8025 "Multicast group address\n"
8030 const char *source_str
;
8031 char xpath
[XPATH_MAXLEN
];
8034 source_str
= argv
[idx_source
]->arg
;
8036 if (strcmp(source_str
, "0.0.0.0") == 0) {
8037 vty_out(vty
, "Bad source address %s\n",
8038 argv
[idx_source
]->arg
);
8039 return CMD_WARNING_CONFIG_FAILED
;
8042 source_str
= "0.0.0.0";
8044 snprintf(xpath
, sizeof(xpath
), FRR_IGMP_JOIN_XPATH
,
8045 "frr-routing:ipv4", argv
[idx_group
]->arg
, source_str
);
8047 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
8049 return nb_cli_apply_changes(vty
, NULL
);
8052 DEFUN (interface_ip_igmp_query_interval
,
8053 interface_ip_igmp_query_interval_cmd
,
8054 "ip igmp query-interval (1-65535)",
8057 IFACE_IGMP_QUERY_INTERVAL_STR
8058 "Query interval in seconds\n")
8060 const struct lyd_node
*pim_enable_dnode
;
8063 yang_dnode_getf(vty
->candidate_config
->dnode
,
8064 "%s/frr-pim:pim/pim-enable", VTY_CURR_XPATH
);
8065 if (!pim_enable_dnode
) {
8066 nb_cli_enqueue_change(vty
, "./igmp-enable", NB_OP_MODIFY
,
8069 if (!yang_dnode_get_bool(pim_enable_dnode
, "."))
8070 nb_cli_enqueue_change(vty
, "./igmp-enable",
8071 NB_OP_MODIFY
, "true");
8074 nb_cli_enqueue_change(vty
, "./query-interval", NB_OP_MODIFY
,
8077 return nb_cli_apply_changes(vty
, "./frr-igmp:igmp");
8080 DEFUN (interface_no_ip_igmp_query_interval
,
8081 interface_no_ip_igmp_query_interval_cmd
,
8082 "no ip igmp query-interval [(1-65535)]",
8086 IFACE_IGMP_QUERY_INTERVAL_STR
8089 nb_cli_enqueue_change(vty
, "./query-interval", NB_OP_DESTROY
, NULL
);
8091 return nb_cli_apply_changes(vty
, "./frr-igmp:igmp");
8094 DEFUN (interface_ip_igmp_version
,
8095 interface_ip_igmp_version_cmd
,
8096 "ip igmp version (2-3)",
8100 "IGMP version number\n")
8102 nb_cli_enqueue_change(vty
, "./igmp-enable", NB_OP_MODIFY
,
8104 nb_cli_enqueue_change(vty
, "./version", NB_OP_MODIFY
, argv
[3]->arg
);
8106 return nb_cli_apply_changes(vty
, "./frr-igmp:igmp");
8109 DEFUN (interface_no_ip_igmp_version
,
8110 interface_no_ip_igmp_version_cmd
,
8111 "no ip igmp version (2-3)",
8116 "IGMP version number\n")
8118 nb_cli_enqueue_change(vty
, "./version", NB_OP_DESTROY
, NULL
);
8120 return nb_cli_apply_changes(vty
, "./frr-igmp:igmp");
8123 DEFUN (interface_ip_igmp_query_max_response_time
,
8124 interface_ip_igmp_query_max_response_time_cmd
,
8125 "ip igmp query-max-response-time (1-65535)",
8128 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
8129 "Query response value in deci-seconds\n")
8131 const struct lyd_node
*pim_enable_dnode
;
8134 yang_dnode_getf(vty
->candidate_config
->dnode
,
8135 "%s/frr-pim:pim/pim-enable", VTY_CURR_XPATH
);
8137 if (!pim_enable_dnode
) {
8138 nb_cli_enqueue_change(vty
, "./igmp-enable", NB_OP_MODIFY
,
8141 if (!yang_dnode_get_bool(pim_enable_dnode
, "."))
8142 nb_cli_enqueue_change(vty
, "./igmp-enable",
8143 NB_OP_MODIFY
, "true");
8146 nb_cli_enqueue_change(vty
, "./query-max-response-time", NB_OP_MODIFY
,
8149 return nb_cli_apply_changes(vty
, "./frr-igmp:igmp");
8152 DEFUN (interface_no_ip_igmp_query_max_response_time
,
8153 interface_no_ip_igmp_query_max_response_time_cmd
,
8154 "no ip igmp query-max-response-time [(1-65535)]",
8158 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
8161 nb_cli_enqueue_change(vty
, "./query-max-response-time", NB_OP_DESTROY
,
8163 return nb_cli_apply_changes(vty
, "./frr-igmp:igmp");
8166 DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec
,
8167 interface_ip_igmp_query_max_response_time_dsec_cmd
,
8168 "ip igmp query-max-response-time-dsec (1-65535)",
8171 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
8172 "Query response value in deciseconds\n")
8174 const struct lyd_node
*pim_enable_dnode
;
8177 yang_dnode_getf(vty
->candidate_config
->dnode
,
8178 "%s/frr-pim:pim/pim-enable", VTY_CURR_XPATH
);
8179 if (!pim_enable_dnode
) {
8180 nb_cli_enqueue_change(vty
, "./igmp-enable", NB_OP_MODIFY
,
8183 if (!yang_dnode_get_bool(pim_enable_dnode
, "."))
8184 nb_cli_enqueue_change(vty
, "./igmp-enable",
8185 NB_OP_MODIFY
, "true");
8188 nb_cli_enqueue_change(vty
, "./query-max-response-time", NB_OP_MODIFY
,
8191 return nb_cli_apply_changes(vty
, "./frr-igmp:igmp");
8194 DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec
,
8195 interface_no_ip_igmp_query_max_response_time_dsec_cmd
,
8196 "no ip igmp query-max-response-time-dsec [(1-65535)]",
8200 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
8203 nb_cli_enqueue_change(vty
, "./query-max-response-time", NB_OP_DESTROY
,
8206 return nb_cli_apply_changes(vty
, "./frr-igmp:igmp");
8209 DEFUN (interface_ip_igmp_last_member_query_count
,
8210 interface_ip_igmp_last_member_query_count_cmd
,
8211 "ip igmp last-member-query-count (1-255)",
8214 IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR
8215 "Last member query count\n")
8217 const struct lyd_node
*pim_enable_dnode
;
8220 yang_dnode_getf(vty
->candidate_config
->dnode
,
8221 "%s/frr-pim:pim/pim-enable", VTY_CURR_XPATH
);
8222 if (!pim_enable_dnode
) {
8223 nb_cli_enqueue_change(vty
, "./igmp-enable", NB_OP_MODIFY
,
8226 if (!yang_dnode_get_bool(pim_enable_dnode
, "."))
8227 nb_cli_enqueue_change(vty
, "./igmp-enable",
8228 NB_OP_MODIFY
, "true");
8231 nb_cli_enqueue_change(vty
, "./robustness-variable", NB_OP_MODIFY
,
8234 return nb_cli_apply_changes(vty
, "./frr-igmp:igmp");
8237 DEFUN (interface_no_ip_igmp_last_member_query_count
,
8238 interface_no_ip_igmp_last_member_query_count_cmd
,
8239 "no ip igmp last-member-query-count [(1-255)]",
8243 IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR
8246 nb_cli_enqueue_change(vty
, "./robustness-variable", NB_OP_DESTROY
,
8249 return nb_cli_apply_changes(vty
, "./frr-igmp:igmp");
8252 DEFUN (interface_ip_igmp_last_member_query_interval
,
8253 interface_ip_igmp_last_member_query_interval_cmd
,
8254 "ip igmp last-member-query-interval (1-65535)",
8257 IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR
8258 "Last member query interval in deciseconds\n")
8260 const struct lyd_node
*pim_enable_dnode
;
8263 yang_dnode_getf(vty
->candidate_config
->dnode
,
8264 "%s/frr-pim:pim/pim-enable", VTY_CURR_XPATH
);
8265 if (!pim_enable_dnode
) {
8266 nb_cli_enqueue_change(vty
, "./igmp-enable", NB_OP_MODIFY
,
8269 if (!yang_dnode_get_bool(pim_enable_dnode
, "."))
8270 nb_cli_enqueue_change(vty
, "./igmp-enable",
8271 NB_OP_MODIFY
, "true");
8274 nb_cli_enqueue_change(vty
, "./last-member-query-interval", NB_OP_MODIFY
,
8277 return nb_cli_apply_changes(vty
, "./frr-igmp:igmp");
8280 DEFUN (interface_no_ip_igmp_last_member_query_interval
,
8281 interface_no_ip_igmp_last_member_query_interval_cmd
,
8282 "no ip igmp last-member-query-interval [(1-65535)]",
8286 IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR
8289 nb_cli_enqueue_change(vty
, "./last-member-query-interval",
8290 NB_OP_DESTROY
, NULL
);
8292 return nb_cli_apply_changes(vty
, "./frr-igmp:igmp");
8295 DEFUN (interface_ip_pim_drprio
,
8296 interface_ip_pim_drprio_cmd
,
8297 "ip pim drpriority (1-4294967295)",
8300 "Set the Designated Router Election Priority\n"
8301 "Value of the new DR Priority\n")
8305 nb_cli_enqueue_change(vty
, "./dr-priority", NB_OP_MODIFY
,
8306 argv
[idx_number
]->arg
);
8308 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
8311 DEFUN (interface_no_ip_pim_drprio
,
8312 interface_no_ip_pim_drprio_cmd
,
8313 "no ip pim drpriority [(1-4294967295)]",
8317 "Revert the Designated Router Priority to default\n"
8318 "Old Value of the Priority\n")
8320 nb_cli_enqueue_change(vty
, "./dr-priority", NB_OP_DESTROY
, NULL
);
8322 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
8325 DEFPY_HIDDEN (interface_ip_igmp_query_generate
,
8326 interface_ip_igmp_query_generate_cmd
,
8327 "ip igmp generate-query-once [version (2-3)]",
8330 "Generate igmp general query once\n"
8332 "IGMP version number\n")
8334 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8335 int igmp_version
= 2;
8338 vty_out(vty
, "IGMP/PIM is not enabled on the interface %s\n",
8340 return CMD_WARNING_CONFIG_FAILED
;
8344 igmp_version
= atoi(argv
[4]->arg
);
8346 igmp_send_query_on_intf(ifp
, igmp_version
);
8351 DEFPY_HIDDEN (pim_test_sg_keepalive
,
8352 pim_test_sg_keepalive_cmd
,
8353 "test pim [vrf NAME$name] keepalive-reset A.B.C.D$source A.B.C.D$group",
8357 "Reset the Keepalive Timer\n"
8358 "The Source we are resetting\n"
8359 "The Group we are resetting\n")
8361 struct pim_upstream
*up
;
8362 struct pim_instance
*pim
;
8363 struct prefix_sg sg
;
8369 pim
= pim_get_pim_instance(VRF_DEFAULT
);
8371 struct vrf
*vrf
= vrf_lookup_by_name(name
);
8374 vty_out(vty
, "%% Vrf specified: %s does not exist\n",
8379 pim
= pim_get_pim_instance(vrf
->vrf_id
);
8383 vty_out(vty
, "%% Unable to find pim instance\n");
8387 up
= pim_upstream_find(pim
, &sg
);
8389 vty_out(vty
, "%% Unable to find %s specified\n",
8390 pim_str_sg_dump(&sg
));
8394 vty_out(vty
, "Setting %s to current keep alive time: %d\n",
8395 pim_str_sg_dump(&sg
), pim
->keep_alive_time
);
8396 pim_upstream_keep_alive_timer_start(up
, pim
->keep_alive_time
);
8401 DEFPY (interface_ip_pim_activeactive
,
8402 interface_ip_pim_activeactive_cmd
,
8403 "[no$no] ip pim active-active",
8407 "Mark interface as Active-Active for MLAG operations, Hidden because not finished yet\n")
8410 nb_cli_enqueue_change(vty
, "./active-active", NB_OP_MODIFY
,
8413 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
,
8416 nb_cli_enqueue_change(vty
, "./active-active", NB_OP_MODIFY
,
8420 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
8423 DEFUN_HIDDEN (interface_ip_pim_ssm
,
8424 interface_ip_pim_ssm_cmd
,
8432 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
, "true");
8434 ret
= nb_cli_apply_changes(vty
, "./frr-pim:pim");
8440 "WARN: Enabled PIM SM on interface; configure PIM SSM range if needed\n");
8445 DEFUN_HIDDEN (interface_ip_pim_sm
,
8446 interface_ip_pim_sm_cmd
,
8452 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
, "true");
8454 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
8457 DEFUN (interface_ip_pim
,
8458 interface_ip_pim_cmd
,
8463 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
, "true");
8465 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
8468 DEFUN_HIDDEN (interface_no_ip_pim_ssm
,
8469 interface_no_ip_pim_ssm_cmd
,
8476 const struct lyd_node
*igmp_enable_dnode
;
8477 char igmp_if_xpath
[XPATH_MAXLEN
+ 20];
8479 snprintf(igmp_if_xpath
, sizeof(igmp_if_xpath
),
8480 "%s/frr-igmp:igmp", VTY_CURR_XPATH
);
8481 igmp_enable_dnode
= yang_dnode_getf(vty
->candidate_config
->dnode
,
8482 "%s/igmp-enable", igmp_if_xpath
);
8484 if (!igmp_enable_dnode
) {
8485 nb_cli_enqueue_change(vty
, igmp_if_xpath
, NB_OP_DESTROY
, NULL
);
8486 nb_cli_enqueue_change(vty
, ".", NB_OP_DESTROY
, NULL
);
8488 if (!yang_dnode_get_bool(igmp_enable_dnode
, ".")) {
8489 nb_cli_enqueue_change(vty
, igmp_if_xpath
, NB_OP_DESTROY
,
8491 nb_cli_enqueue_change(vty
, ".", NB_OP_DESTROY
, NULL
);
8493 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
,
8497 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
8500 DEFUN_HIDDEN (interface_no_ip_pim_sm
,
8501 interface_no_ip_pim_sm_cmd
,
8508 const struct lyd_node
*igmp_enable_dnode
;
8509 char igmp_if_xpath
[XPATH_MAXLEN
+ 20];
8511 snprintf(igmp_if_xpath
, sizeof(igmp_if_xpath
),
8512 "%s/frr-igmp:igmp", VTY_CURR_XPATH
);
8513 igmp_enable_dnode
= yang_dnode_getf(vty
->candidate_config
->dnode
,
8514 "%s/igmp-enable", igmp_if_xpath
);
8516 if (!igmp_enable_dnode
) {
8517 nb_cli_enqueue_change(vty
, igmp_if_xpath
, NB_OP_DESTROY
, NULL
);
8518 nb_cli_enqueue_change(vty
, ".", NB_OP_DESTROY
, NULL
);
8520 if (!yang_dnode_get_bool(igmp_enable_dnode
, ".")) {
8521 nb_cli_enqueue_change(vty
, igmp_if_xpath
, NB_OP_DESTROY
,
8523 nb_cli_enqueue_change(vty
, ".", NB_OP_DESTROY
, NULL
);
8525 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
,
8529 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
8532 DEFUN (interface_no_ip_pim
,
8533 interface_no_ip_pim_cmd
,
8539 const struct lyd_node
*igmp_enable_dnode
;
8540 char igmp_if_xpath
[XPATH_MAXLEN
+ 20];
8542 snprintf(igmp_if_xpath
, sizeof(igmp_if_xpath
),
8543 "%s/frr-igmp:igmp", VTY_CURR_XPATH
);
8544 igmp_enable_dnode
= yang_dnode_getf(vty
->candidate_config
->dnode
,
8545 "%s/igmp-enable", igmp_if_xpath
);
8547 if (!igmp_enable_dnode
) {
8548 nb_cli_enqueue_change(vty
, igmp_if_xpath
, NB_OP_DESTROY
, NULL
);
8549 nb_cli_enqueue_change(vty
, ".", NB_OP_DESTROY
, NULL
);
8551 if (!yang_dnode_get_bool(igmp_enable_dnode
, ".")) {
8552 nb_cli_enqueue_change(vty
, igmp_if_xpath
, NB_OP_DESTROY
,
8554 nb_cli_enqueue_change(vty
, ".", NB_OP_DESTROY
, NULL
);
8556 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
,
8560 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
8564 DEFUN(interface_ip_pim_boundary_oil
,
8565 interface_ip_pim_boundary_oil_cmd
,
8566 "ip multicast boundary oil WORD",
8568 "Generic multicast configuration options\n"
8569 "Define multicast boundary\n"
8570 "Filter OIL by group using prefix list\n"
8571 "Prefix list to filter OIL with\n")
8573 nb_cli_enqueue_change(vty
, "./multicast-boundary-oil", NB_OP_MODIFY
,
8576 return nb_cli_apply_changes(vty
,
8577 "./frr-pim:pim/address-family[address-family='%s']",
8578 "frr-routing:ipv4");
8582 DEFUN(interface_no_ip_pim_boundary_oil
,
8583 interface_no_ip_pim_boundary_oil_cmd
,
8584 "no ip multicast boundary oil [WORD]",
8587 "Generic multicast configuration options\n"
8588 "Define multicast boundary\n"
8589 "Filter OIL by group using prefix list\n"
8590 "Prefix list to filter OIL with\n")
8592 nb_cli_enqueue_change(vty
, "./multicast-boundary-oil", NB_OP_DESTROY
,
8595 return nb_cli_apply_changes(vty
,
8596 "./frr-pim:pim/address-family[address-family='%s']",
8597 "frr-routing:ipv4");
8600 DEFUN (interface_ip_mroute
,
8601 interface_ip_mroute_cmd
,
8602 "ip mroute INTERFACE A.B.C.D [A.B.C.D]",
8604 "Add multicast route\n"
8605 "Outgoing interface name\n"
8609 int idx_interface
= 2;
8611 const char *source_str
;
8613 if (argc
== (idx_ipv4
+ 1))
8614 source_str
= "0.0.0.0";
8616 source_str
= argv
[idx_ipv4
+ 1]->arg
;
8618 nb_cli_enqueue_change(vty
, "./oif", NB_OP_MODIFY
,
8619 argv
[idx_interface
]->arg
);
8621 return nb_cli_apply_changes(vty
,
8622 "./frr-pim:pim/address-family[address-family='%s']/mroute[source-addr='%s'][group-addr='%s']",
8623 "frr-routing:ipv4", source_str
,
8624 argv
[idx_ipv4
]->arg
);
8627 DEFUN (interface_no_ip_mroute
,
8628 interface_no_ip_mroute_cmd
,
8629 "no ip mroute INTERFACE A.B.C.D [A.B.C.D]",
8632 "Add multicast route\n"
8633 "Outgoing interface name\n"
8638 const char *source_str
;
8640 if (argc
== (idx_ipv4
+ 1))
8641 source_str
= "0.0.0.0";
8643 source_str
= argv
[idx_ipv4
+ 1]->arg
;
8645 nb_cli_enqueue_change(vty
, ".", NB_OP_DESTROY
, NULL
);
8647 return nb_cli_apply_changes(vty
,
8648 "./frr-pim:pim/address-family[address-family='%s']/mroute[source-addr='%s'][group-addr='%s']",
8649 "frr-routing:ipv4", source_str
,
8650 argv
[idx_ipv4
]->arg
);
8653 DEFUN (interface_ip_pim_hello
,
8654 interface_ip_pim_hello_cmd
,
8655 "ip pim hello (1-65535) [(1-65535)]",
8659 IFACE_PIM_HELLO_TIME_STR
8660 IFACE_PIM_HELLO_HOLD_STR
)
8664 const struct lyd_node
*igmp_enable_dnode
;
8667 yang_dnode_getf(vty
->candidate_config
->dnode
,
8668 "%s/frr-igmp:igmp/igmp-enable", VTY_CURR_XPATH
);
8669 if (!igmp_enable_dnode
) {
8670 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
,
8673 if (!yang_dnode_get_bool(igmp_enable_dnode
, "."))
8674 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
,
8678 nb_cli_enqueue_change(vty
, "./hello-interval", NB_OP_MODIFY
,
8679 argv
[idx_time
]->arg
);
8681 if (argc
== idx_hold
+ 1)
8682 nb_cli_enqueue_change(vty
, "./hello-holdtime", NB_OP_MODIFY
,
8683 argv
[idx_hold
]->arg
);
8685 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
8688 DEFUN (interface_no_ip_pim_hello
,
8689 interface_no_ip_pim_hello_cmd
,
8690 "no ip pim hello [(1-65535) [(1-65535)]]",
8698 nb_cli_enqueue_change(vty
, "./hello-interval", NB_OP_DESTROY
, NULL
);
8699 nb_cli_enqueue_change(vty
, "./hello-holdtime", NB_OP_DESTROY
, NULL
);
8701 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
8710 PIM_DO_DEBUG_IGMP_EVENTS
;
8711 PIM_DO_DEBUG_IGMP_PACKETS
;
8712 PIM_DO_DEBUG_IGMP_TRACE
;
8716 DEFUN (no_debug_igmp
,
8723 PIM_DONT_DEBUG_IGMP_EVENTS
;
8724 PIM_DONT_DEBUG_IGMP_PACKETS
;
8725 PIM_DONT_DEBUG_IGMP_TRACE
;
8730 DEFUN (debug_igmp_events
,
8731 debug_igmp_events_cmd
,
8732 "debug igmp events",
8735 DEBUG_IGMP_EVENTS_STR
)
8737 PIM_DO_DEBUG_IGMP_EVENTS
;
8741 DEFUN (no_debug_igmp_events
,
8742 no_debug_igmp_events_cmd
,
8743 "no debug igmp events",
8747 DEBUG_IGMP_EVENTS_STR
)
8749 PIM_DONT_DEBUG_IGMP_EVENTS
;
8754 DEFUN (debug_igmp_packets
,
8755 debug_igmp_packets_cmd
,
8756 "debug igmp packets",
8759 DEBUG_IGMP_PACKETS_STR
)
8761 PIM_DO_DEBUG_IGMP_PACKETS
;
8765 DEFUN (no_debug_igmp_packets
,
8766 no_debug_igmp_packets_cmd
,
8767 "no debug igmp packets",
8771 DEBUG_IGMP_PACKETS_STR
)
8773 PIM_DONT_DEBUG_IGMP_PACKETS
;
8778 DEFUN (debug_igmp_trace
,
8779 debug_igmp_trace_cmd
,
8783 DEBUG_IGMP_TRACE_STR
)
8785 PIM_DO_DEBUG_IGMP_TRACE
;
8789 DEFUN (no_debug_igmp_trace
,
8790 no_debug_igmp_trace_cmd
,
8791 "no debug igmp trace",
8795 DEBUG_IGMP_TRACE_STR
)
8797 PIM_DONT_DEBUG_IGMP_TRACE
;
8802 DEFUN (debug_mroute
,
8808 PIM_DO_DEBUG_MROUTE
;
8812 DEFUN (debug_mroute_detail
,
8813 debug_mroute_detail_cmd
,
8814 "debug mroute detail",
8819 PIM_DO_DEBUG_MROUTE_DETAIL
;
8823 DEFUN (no_debug_mroute
,
8824 no_debug_mroute_cmd
,
8830 PIM_DONT_DEBUG_MROUTE
;
8834 DEFUN (no_debug_mroute_detail
,
8835 no_debug_mroute_detail_cmd
,
8836 "no debug mroute detail",
8842 PIM_DONT_DEBUG_MROUTE_DETAIL
;
8846 DEFUN (debug_pim_static
,
8847 debug_pim_static_cmd
,
8853 PIM_DO_DEBUG_STATIC
;
8857 DEFUN (no_debug_pim_static
,
8858 no_debug_pim_static_cmd
,
8859 "no debug pim static",
8865 PIM_DONT_DEBUG_STATIC
;
8876 PIM_DO_DEBUG_PIM_EVENTS
;
8877 PIM_DO_DEBUG_PIM_PACKETS
;
8878 PIM_DO_DEBUG_PIM_TRACE
;
8879 PIM_DO_DEBUG_MSDP_EVENTS
;
8880 PIM_DO_DEBUG_MSDP_PACKETS
;
8885 DEFUN (no_debug_pim
,
8892 PIM_DONT_DEBUG_PIM_EVENTS
;
8893 PIM_DONT_DEBUG_PIM_PACKETS
;
8894 PIM_DONT_DEBUG_PIM_TRACE
;
8895 PIM_DONT_DEBUG_MSDP_EVENTS
;
8896 PIM_DONT_DEBUG_MSDP_PACKETS
;
8898 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
8899 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
8905 DEFUN (debug_pim_nht
,
8910 "Nexthop Tracking\n")
8912 PIM_DO_DEBUG_PIM_NHT
;
8916 DEFUN (no_debug_pim_nht
,
8917 no_debug_pim_nht_cmd
,
8922 "Nexthop Tracking\n")
8924 PIM_DONT_DEBUG_PIM_NHT
;
8928 DEFUN (debug_pim_nht_rp
,
8929 debug_pim_nht_rp_cmd
,
8933 "Nexthop Tracking\n"
8934 "RP Nexthop Tracking\n")
8936 PIM_DO_DEBUG_PIM_NHT_RP
;
8940 DEFUN (no_debug_pim_nht_rp
,
8941 no_debug_pim_nht_rp_cmd
,
8942 "no debug pim nht rp",
8946 "Nexthop Tracking\n"
8947 "RP Nexthop Tracking\n")
8949 PIM_DONT_DEBUG_PIM_NHT_RP
;
8953 DEFUN (debug_pim_events
,
8954 debug_pim_events_cmd
,
8958 DEBUG_PIM_EVENTS_STR
)
8960 PIM_DO_DEBUG_PIM_EVENTS
;
8964 DEFUN (no_debug_pim_events
,
8965 no_debug_pim_events_cmd
,
8966 "no debug pim events",
8970 DEBUG_PIM_EVENTS_STR
)
8972 PIM_DONT_DEBUG_PIM_EVENTS
;
8976 DEFUN (debug_pim_packets
,
8977 debug_pim_packets_cmd
,
8978 "debug pim packets [<hello|joins|register>]",
8981 DEBUG_PIM_PACKETS_STR
8982 DEBUG_PIM_HELLO_PACKETS_STR
8983 DEBUG_PIM_J_P_PACKETS_STR
8984 DEBUG_PIM_PIM_REG_PACKETS_STR
)
8987 if (argv_find(argv
, argc
, "hello", &idx
)) {
8988 PIM_DO_DEBUG_PIM_HELLO
;
8989 vty_out(vty
, "PIM Hello debugging is on\n");
8990 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
8991 PIM_DO_DEBUG_PIM_J_P
;
8992 vty_out(vty
, "PIM Join/Prune debugging is on\n");
8993 } else if (argv_find(argv
, argc
, "register", &idx
)) {
8994 PIM_DO_DEBUG_PIM_REG
;
8995 vty_out(vty
, "PIM Register debugging is on\n");
8997 PIM_DO_DEBUG_PIM_PACKETS
;
8998 vty_out(vty
, "PIM Packet debugging is on \n");
9003 DEFUN (no_debug_pim_packets
,
9004 no_debug_pim_packets_cmd
,
9005 "no debug pim packets [<hello|joins|register>]",
9009 DEBUG_PIM_PACKETS_STR
9010 DEBUG_PIM_HELLO_PACKETS_STR
9011 DEBUG_PIM_J_P_PACKETS_STR
9012 DEBUG_PIM_PIM_REG_PACKETS_STR
)
9015 if (argv_find(argv
, argc
, "hello", &idx
)) {
9016 PIM_DONT_DEBUG_PIM_HELLO
;
9017 vty_out(vty
, "PIM Hello debugging is off \n");
9018 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
9019 PIM_DONT_DEBUG_PIM_J_P
;
9020 vty_out(vty
, "PIM Join/Prune debugging is off \n");
9021 } else if (argv_find(argv
, argc
, "register", &idx
)) {
9022 PIM_DONT_DEBUG_PIM_REG
;
9023 vty_out(vty
, "PIM Register debugging is off\n");
9025 PIM_DONT_DEBUG_PIM_PACKETS
;
9031 DEFUN (debug_pim_packetdump_send
,
9032 debug_pim_packetdump_send_cmd
,
9033 "debug pim packet-dump send",
9036 DEBUG_PIM_PACKETDUMP_STR
9037 DEBUG_PIM_PACKETDUMP_SEND_STR
)
9039 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND
;
9043 DEFUN (no_debug_pim_packetdump_send
,
9044 no_debug_pim_packetdump_send_cmd
,
9045 "no debug pim packet-dump send",
9049 DEBUG_PIM_PACKETDUMP_STR
9050 DEBUG_PIM_PACKETDUMP_SEND_STR
)
9052 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
9056 DEFUN (debug_pim_packetdump_recv
,
9057 debug_pim_packetdump_recv_cmd
,
9058 "debug pim packet-dump receive",
9061 DEBUG_PIM_PACKETDUMP_STR
9062 DEBUG_PIM_PACKETDUMP_RECV_STR
)
9064 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV
;
9068 DEFUN (no_debug_pim_packetdump_recv
,
9069 no_debug_pim_packetdump_recv_cmd
,
9070 "no debug pim packet-dump receive",
9074 DEBUG_PIM_PACKETDUMP_STR
9075 DEBUG_PIM_PACKETDUMP_RECV_STR
)
9077 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
9081 DEFUN (debug_pim_trace
,
9082 debug_pim_trace_cmd
,
9086 DEBUG_PIM_TRACE_STR
)
9088 PIM_DO_DEBUG_PIM_TRACE
;
9092 DEFUN (debug_pim_trace_detail
,
9093 debug_pim_trace_detail_cmd
,
9094 "debug pim trace detail",
9098 "Detailed Information\n")
9100 PIM_DO_DEBUG_PIM_TRACE_DETAIL
;
9104 DEFUN (no_debug_pim_trace
,
9105 no_debug_pim_trace_cmd
,
9106 "no debug pim trace",
9110 DEBUG_PIM_TRACE_STR
)
9112 PIM_DONT_DEBUG_PIM_TRACE
;
9116 DEFUN (no_debug_pim_trace_detail
,
9117 no_debug_pim_trace_detail_cmd
,
9118 "no debug pim trace detail",
9123 "Detailed Information\n")
9125 PIM_DONT_DEBUG_PIM_TRACE_DETAIL
;
9129 DEFUN (debug_ssmpingd
,
9135 PIM_DO_DEBUG_SSMPINGD
;
9139 DEFUN (no_debug_ssmpingd
,
9140 no_debug_ssmpingd_cmd
,
9141 "no debug ssmpingd",
9146 PIM_DONT_DEBUG_SSMPINGD
;
9150 DEFUN (debug_pim_zebra
,
9151 debug_pim_zebra_cmd
,
9155 DEBUG_PIM_ZEBRA_STR
)
9161 DEFUN (no_debug_pim_zebra
,
9162 no_debug_pim_zebra_cmd
,
9163 "no debug pim zebra",
9167 DEBUG_PIM_ZEBRA_STR
)
9169 PIM_DONT_DEBUG_ZEBRA
;
9173 DEFUN(debug_pim_mlag
, debug_pim_mlag_cmd
, "debug pim mlag",
9174 DEBUG_STR DEBUG_PIM_STR DEBUG_PIM_MLAG_STR
)
9180 DEFUN(no_debug_pim_mlag
, no_debug_pim_mlag_cmd
, "no debug pim mlag",
9181 NO_STR DEBUG_STR DEBUG_PIM_STR DEBUG_PIM_MLAG_STR
)
9183 PIM_DONT_DEBUG_MLAG
;
9187 DEFUN (debug_pim_vxlan
,
9188 debug_pim_vxlan_cmd
,
9192 DEBUG_PIM_VXLAN_STR
)
9198 DEFUN (no_debug_pim_vxlan
,
9199 no_debug_pim_vxlan_cmd
,
9200 "no debug pim vxlan",
9204 DEBUG_PIM_VXLAN_STR
)
9206 PIM_DONT_DEBUG_VXLAN
;
9216 PIM_DO_DEBUG_MSDP_EVENTS
;
9217 PIM_DO_DEBUG_MSDP_PACKETS
;
9221 DEFUN (no_debug_msdp
,
9228 PIM_DONT_DEBUG_MSDP_EVENTS
;
9229 PIM_DONT_DEBUG_MSDP_PACKETS
;
9233 DEFUN (debug_msdp_events
,
9234 debug_msdp_events_cmd
,
9235 "debug msdp events",
9238 DEBUG_MSDP_EVENTS_STR
)
9240 PIM_DO_DEBUG_MSDP_EVENTS
;
9244 DEFUN (no_debug_msdp_events
,
9245 no_debug_msdp_events_cmd
,
9246 "no debug msdp events",
9250 DEBUG_MSDP_EVENTS_STR
)
9252 PIM_DONT_DEBUG_MSDP_EVENTS
;
9256 DEFUN (debug_msdp_packets
,
9257 debug_msdp_packets_cmd
,
9258 "debug msdp packets",
9261 DEBUG_MSDP_PACKETS_STR
)
9263 PIM_DO_DEBUG_MSDP_PACKETS
;
9267 DEFUN (no_debug_msdp_packets
,
9268 no_debug_msdp_packets_cmd
,
9269 "no debug msdp packets",
9273 DEBUG_MSDP_PACKETS_STR
)
9275 PIM_DONT_DEBUG_MSDP_PACKETS
;
9279 DEFUN (debug_mtrace
,
9285 PIM_DO_DEBUG_MTRACE
;
9289 DEFUN (no_debug_mtrace
,
9290 no_debug_mtrace_cmd
,
9296 PIM_DONT_DEBUG_MTRACE
;
9311 DEFUN (no_debug_bsm
,
9324 DEFUN_NOSH (show_debugging_pim
,
9325 show_debugging_pim_cmd
,
9326 "show debugging [pim]",
9331 vty_out(vty
, "PIM debugging status\n");
9333 pim_debug_config_write(vty
);
9338 DEFUN (interface_pim_use_source
,
9339 interface_pim_use_source_cmd
,
9340 "ip pim use-source A.B.C.D",
9343 "Configure primary IP address\n"
9344 "source ip address\n")
9346 nb_cli_enqueue_change(vty
, "./use-source", NB_OP_MODIFY
, argv
[3]->arg
);
9348 return nb_cli_apply_changes(vty
,
9349 "./frr-pim:pim/address-family[address-family='%s']",
9350 "frr-routing:ipv4");
9353 DEFUN (interface_no_pim_use_source
,
9354 interface_no_pim_use_source_cmd
,
9355 "no ip pim use-source [A.B.C.D]",
9359 "Delete source IP address\n"
9360 "source ip address\n")
9362 nb_cli_enqueue_change(vty
, "./use-source", NB_OP_MODIFY
, "0.0.0.0");
9364 return nb_cli_apply_changes(vty
,
9365 "./frr-pim:pim/address-family[address-family='%s']",
9366 "frr-routing:ipv4");
9371 "ip pim bfd [profile BFDPROF$prof]",
9374 "Enables BFD support\n"
9376 "Use BFD profile name\n")
9378 const struct lyd_node
*igmp_enable_dnode
;
9381 yang_dnode_getf(vty
->candidate_config
->dnode
,
9382 "%s/frr-igmp:igmp/igmp-enable", VTY_CURR_XPATH
);
9383 if (!igmp_enable_dnode
)
9384 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
,
9387 if (!yang_dnode_get_bool(igmp_enable_dnode
, "."))
9388 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
,
9392 nb_cli_enqueue_change(vty
, "./bfd", NB_OP_CREATE
, NULL
);
9394 nb_cli_enqueue_change(vty
, "./bfd/profile", NB_OP_MODIFY
, prof
);
9396 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
9399 DEFPY(no_ip_pim_bfd_profile
, no_ip_pim_bfd_profile_cmd
,
9400 "no ip pim bfd profile [BFDPROF]",
9404 "Enables BFD support\n"
9405 "Disable BFD profile\n"
9406 "BFD Profile name\n")
9408 nb_cli_enqueue_change(vty
, "./bfd/profile", NB_OP_DESTROY
, NULL
);
9410 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
9413 DEFUN (no_ip_pim_bfd
,
9419 "Disables BFD support\n")
9421 nb_cli_enqueue_change(vty
, "./bfd", NB_OP_DESTROY
, NULL
);
9423 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
9431 "Enables BSM support on the interface\n")
9433 const struct lyd_node
*igmp_enable_dnode
;
9436 yang_dnode_getf(vty
->candidate_config
->dnode
,
9437 "%s/frr-igmp:igmp/igmp-enable", VTY_CURR_XPATH
);
9438 if (!igmp_enable_dnode
)
9439 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
,
9442 if (!yang_dnode_get_bool(igmp_enable_dnode
, "."))
9443 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
,
9447 nb_cli_enqueue_change(vty
, "./bsm", NB_OP_MODIFY
, "true");
9449 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
9452 DEFUN (no_ip_pim_bsm
,
9458 "Disables BSM support\n")
9460 nb_cli_enqueue_change(vty
, "./bsm", NB_OP_MODIFY
, "false");
9462 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
9465 DEFUN (ip_pim_ucast_bsm
,
9466 ip_pim_ucast_bsm_cmd
,
9467 "ip pim unicast-bsm",
9470 "Accept/Send unicast BSM on the interface\n")
9472 const struct lyd_node
*igmp_enable_dnode
;
9475 yang_dnode_getf(vty
->candidate_config
->dnode
,
9476 "%s/frr-igmp:igmp/igmp-enable", VTY_CURR_XPATH
);
9477 if (!igmp_enable_dnode
)
9478 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
,
9481 if (!yang_dnode_get_bool(igmp_enable_dnode
, "."))
9482 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
,
9486 nb_cli_enqueue_change(vty
, "./unicast-bsm", NB_OP_MODIFY
, "true");
9488 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
9491 DEFUN (no_ip_pim_ucast_bsm
,
9492 no_ip_pim_ucast_bsm_cmd
,
9493 "no ip pim unicast-bsm",
9497 "Block send/receive unicast BSM on this interface\n")
9499 nb_cli_enqueue_change(vty
, "./unicast-bsm", NB_OP_MODIFY
, "false");
9501 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
9507 ip_pim_bfd_param_cmd
,
9508 "ip pim bfd (2-255) (1-65535) (1-65535)",
9511 "Enables BFD support\n"
9512 "Detect Multiplier\n"
9513 "Required min receive interval\n"
9514 "Desired min transmit interval\n")
9518 ip_pim_bfd_param_cmd
,
9519 "ip pim bfd (2-255) (1-65535) (1-65535)",
9522 "Enables BFD support\n"
9523 "Detect Multiplier\n"
9524 "Required min receive interval\n"
9525 "Desired min transmit interval\n")
9526 #endif /* HAVE_BFDD */
9529 int idx_number_2
= 4;
9530 int idx_number_3
= 5;
9531 const struct lyd_node
*igmp_enable_dnode
;
9534 yang_dnode_getf(vty
->candidate_config
->dnode
,
9535 "%s/frr-igmp:igmp/igmp-enable", VTY_CURR_XPATH
);
9536 if (!igmp_enable_dnode
)
9537 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
,
9540 if (!yang_dnode_get_bool(igmp_enable_dnode
, "."))
9541 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
,
9545 nb_cli_enqueue_change(vty
, "./bfd", NB_OP_CREATE
, NULL
);
9546 nb_cli_enqueue_change(vty
, "./bfd/min-rx-interval", NB_OP_MODIFY
,
9547 argv
[idx_number_2
]->arg
);
9548 nb_cli_enqueue_change(vty
, "./bfd/min-tx-interval", NB_OP_MODIFY
,
9549 argv
[idx_number_3
]->arg
);
9550 nb_cli_enqueue_change(vty
, "./bfd/detect_mult", NB_OP_MODIFY
,
9551 argv
[idx_number
]->arg
);
9553 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
9557 ALIAS(no_ip_pim_bfd
, no_ip_pim_bfd_param_cmd
,
9558 "no ip pim bfd (2-255) (1-65535) (1-65535)",
9562 "Enables BFD support\n"
9563 "Detect Multiplier\n"
9564 "Required min receive interval\n"
9565 "Desired min transmit interval\n")
9566 #endif /* !HAVE_BFDD */
9568 DEFPY(ip_msdp_peer
, ip_msdp_peer_cmd
,
9569 "ip msdp peer A.B.C.D$peer source A.B.C.D$source",
9572 "Configure MSDP peer\n"
9574 "Source address for TCP connection\n"
9575 "Local IP address\n")
9577 const char *vrfname
;
9578 char temp_xpath
[XPATH_MAXLEN
];
9579 char msdp_peer_source_xpath
[XPATH_MAXLEN
];
9581 vrfname
= pim_cli_get_vrf_name(vty
);
9582 if (vrfname
== NULL
)
9583 return CMD_WARNING_CONFIG_FAILED
;
9585 snprintf(msdp_peer_source_xpath
, sizeof(msdp_peer_source_xpath
),
9586 FRR_PIM_AF_XPATH
, "frr-pim:pimd", "pim", vrfname
,
9587 "frr-routing:ipv4");
9588 snprintf(temp_xpath
, sizeof(temp_xpath
),
9589 "/msdp-peer[peer-ip='%s']/source-ip", peer_str
);
9590 strlcat(msdp_peer_source_xpath
, temp_xpath
,
9591 sizeof(msdp_peer_source_xpath
));
9593 nb_cli_enqueue_change(vty
, msdp_peer_source_xpath
, NB_OP_MODIFY
,
9596 return nb_cli_apply_changes(vty
, NULL
);
9599 DEFPY(ip_msdp_timers
, ip_msdp_timers_cmd
,
9600 "ip msdp timers (1-65535)$keepalive (1-65535)$holdtime [(1-65535)$connretry]",
9603 "MSDP timers configuration\n"
9604 "Keep alive period (in seconds)\n"
9605 "Hold time period (in seconds)\n"
9606 "Connection retry period (in seconds)\n")
9608 const char *vrfname
;
9609 char xpath
[XPATH_MAXLEN
];
9611 vrfname
= pim_cli_get_vrf_name(vty
);
9612 if (vrfname
== NULL
)
9613 return CMD_WARNING_CONFIG_FAILED
;
9615 snprintf(xpath
, sizeof(xpath
), FRR_PIM_MSDP_XPATH
, "frr-pim:pimd",
9616 "pim", vrfname
, "frr-routing:ipv4");
9617 nb_cli_enqueue_change(vty
, "./hold-time", NB_OP_MODIFY
, holdtime_str
);
9618 nb_cli_enqueue_change(vty
, "./keep-alive", NB_OP_MODIFY
, keepalive_str
);
9620 nb_cli_enqueue_change(vty
, "./connection-retry", NB_OP_MODIFY
,
9623 nb_cli_enqueue_change(vty
, "./connection-retry", NB_OP_DESTROY
,
9626 nb_cli_apply_changes(vty
, xpath
);
9631 DEFPY(no_ip_msdp_timers
, no_ip_msdp_timers_cmd
,
9632 "no ip msdp timers [(1-65535) (1-65535) [(1-65535)]]",
9636 "MSDP timers configuration\n"
9641 const char *vrfname
;
9642 char xpath
[XPATH_MAXLEN
];
9644 vrfname
= pim_cli_get_vrf_name(vty
);
9645 if (vrfname
== NULL
)
9646 return CMD_WARNING_CONFIG_FAILED
;
9648 snprintf(xpath
, sizeof(xpath
), FRR_PIM_MSDP_XPATH
, "frr-pim:pimd",
9649 "pim", vrfname
, "frr-routing:ipv4");
9651 nb_cli_enqueue_change(vty
, "./hold-time", NB_OP_DESTROY
, NULL
);
9652 nb_cli_enqueue_change(vty
, "./keep-alive", NB_OP_DESTROY
, NULL
);
9653 nb_cli_enqueue_change(vty
, "./connection-retry", NB_OP_DESTROY
, NULL
);
9655 nb_cli_apply_changes(vty
, xpath
);
9660 DEFUN (no_ip_msdp_peer
,
9661 no_ip_msdp_peer_cmd
,
9662 "no ip msdp peer A.B.C.D",
9666 "Delete MSDP peer\n"
9667 "peer ip address\n")
9669 const char *vrfname
;
9670 char msdp_peer_xpath
[XPATH_MAXLEN
];
9671 char temp_xpath
[XPATH_MAXLEN
];
9673 vrfname
= pim_cli_get_vrf_name(vty
);
9674 if (vrfname
== NULL
)
9675 return CMD_WARNING_CONFIG_FAILED
;
9677 snprintf(msdp_peer_xpath
, sizeof(msdp_peer_xpath
),
9679 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4");
9680 snprintf(temp_xpath
, sizeof(temp_xpath
),
9681 "/msdp-peer[peer-ip='%s']",
9684 strlcat(msdp_peer_xpath
, temp_xpath
, sizeof(msdp_peer_xpath
));
9686 nb_cli_enqueue_change(vty
, msdp_peer_xpath
, NB_OP_DESTROY
, NULL
);
9688 return nb_cli_apply_changes(vty
, NULL
);
9691 DEFPY(ip_msdp_mesh_group_member
,
9692 ip_msdp_mesh_group_member_cmd
,
9693 "ip msdp mesh-group WORD$gname member A.B.C.D$maddr",
9696 "Configure MSDP mesh-group\n"
9698 "Mesh group member\n"
9699 "Peer IP address\n")
9701 const char *vrfname
;
9702 char xpath_value
[XPATH_MAXLEN
];
9704 vrfname
= pim_cli_get_vrf_name(vty
);
9705 if (vrfname
== NULL
)
9706 return CMD_WARNING_CONFIG_FAILED
;
9708 /* Create mesh group. */
9709 snprintf(xpath_value
, sizeof(xpath_value
),
9710 FRR_PIM_AF_XPATH
"/msdp-mesh-groups[name='%s']",
9711 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4", gname
);
9712 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_CREATE
, NULL
);
9714 /* Create mesh group member. */
9715 strlcat(xpath_value
, "/members[address='", sizeof(xpath_value
));
9716 strlcat(xpath_value
, maddr_str
, sizeof(xpath_value
));
9717 strlcat(xpath_value
, "']", sizeof(xpath_value
));
9718 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_CREATE
, NULL
);
9720 return nb_cli_apply_changes(vty
, NULL
);
9723 DEFPY(no_ip_msdp_mesh_group_member
,
9724 no_ip_msdp_mesh_group_member_cmd
,
9725 "no ip msdp mesh-group WORD$gname member A.B.C.D$maddr",
9729 "Delete MSDP mesh-group member\n"
9731 "Mesh group member\n"
9732 "Peer IP address\n")
9734 const char *vrfname
;
9735 char xpath_value
[XPATH_MAXLEN
];
9736 char xpath_member_value
[XPATH_MAXLEN
];
9738 vrfname
= pim_cli_get_vrf_name(vty
);
9739 if (vrfname
== NULL
)
9740 return CMD_WARNING_CONFIG_FAILED
;
9742 /* Get mesh group base XPath. */
9743 snprintf(xpath_value
, sizeof(xpath_value
),
9744 FRR_PIM_AF_XPATH
"/msdp-mesh-groups[name='%s']",
9745 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4", gname
);
9747 if (!yang_dnode_exists(vty
->candidate_config
->dnode
, xpath_value
)) {
9748 vty_out(vty
, "%% mesh-group does not exist\n");
9749 return CMD_WARNING_CONFIG_FAILED
;
9752 /* Remove mesh group member. */
9753 strlcpy(xpath_member_value
, xpath_value
, sizeof(xpath_member_value
));
9754 strlcat(xpath_member_value
, "/members[address='",
9755 sizeof(xpath_member_value
));
9756 strlcat(xpath_member_value
, maddr_str
, sizeof(xpath_member_value
));
9757 strlcat(xpath_member_value
, "']", sizeof(xpath_member_value
));
9758 if (!yang_dnode_exists(vty
->candidate_config
->dnode
,
9759 xpath_member_value
)) {
9760 vty_out(vty
, "%% mesh-group member does not exist\n");
9761 return CMD_WARNING_CONFIG_FAILED
;
9764 nb_cli_enqueue_change(vty
, xpath_member_value
, NB_OP_DESTROY
, NULL
);
9767 * If this is the last member, then we must remove the group altogether
9768 * to not break legacy CLI behaviour.
9770 pim_cli_legacy_mesh_group_behavior(vty
, gname
);
9772 return nb_cli_apply_changes(vty
, NULL
);
9775 DEFPY(ip_msdp_mesh_group_source
,
9776 ip_msdp_mesh_group_source_cmd
,
9777 "ip msdp mesh-group WORD$gname source A.B.C.D$saddr",
9780 "Configure MSDP mesh-group\n"
9782 "Mesh group local address\n"
9783 "Source IP address for the TCP connection\n")
9785 const char *vrfname
;
9786 char xpath_value
[XPATH_MAXLEN
];
9788 vrfname
= pim_cli_get_vrf_name(vty
);
9789 if (vrfname
== NULL
)
9790 return CMD_WARNING_CONFIG_FAILED
;
9792 /* Create mesh group. */
9793 snprintf(xpath_value
, sizeof(xpath_value
),
9794 FRR_PIM_AF_XPATH
"/msdp-mesh-groups[name='%s']",
9795 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4", gname
);
9796 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_CREATE
, NULL
);
9798 /* Create mesh group source. */
9799 strlcat(xpath_value
, "/source", sizeof(xpath_value
));
9800 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_MODIFY
, saddr_str
);
9802 return nb_cli_apply_changes(vty
, NULL
);
9805 DEFPY(no_ip_msdp_mesh_group_source
,
9806 no_ip_msdp_mesh_group_source_cmd
,
9807 "no ip msdp mesh-group WORD$gname source [A.B.C.D]",
9811 "Delete MSDP mesh-group source\n"
9813 "Mesh group source\n"
9814 "Mesh group local address\n")
9816 const char *vrfname
;
9817 char xpath_value
[XPATH_MAXLEN
];
9819 vrfname
= pim_cli_get_vrf_name(vty
);
9820 if (vrfname
== NULL
)
9821 return CMD_WARNING_CONFIG_FAILED
;
9823 /* Get mesh group base XPath. */
9824 snprintf(xpath_value
, sizeof(xpath_value
),
9825 FRR_PIM_AF_XPATH
"/msdp-mesh-groups[name='%s']",
9826 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4", gname
);
9827 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_CREATE
, NULL
);
9829 /* Create mesh group source. */
9830 strlcat(xpath_value
, "/source", sizeof(xpath_value
));
9831 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_DESTROY
, NULL
);
9834 * If this is the last member, then we must remove the group altogether
9835 * to not break legacy CLI behaviour.
9837 pim_cli_legacy_mesh_group_behavior(vty
, gname
);
9839 return nb_cli_apply_changes(vty
, NULL
);
9842 DEFPY(no_ip_msdp_mesh_group
,
9843 no_ip_msdp_mesh_group_cmd
,
9844 "no ip msdp mesh-group WORD$gname",
9848 "Delete MSDP mesh-group\n"
9851 const char *vrfname
;
9852 char xpath_value
[XPATH_MAXLEN
];
9854 vrfname
= pim_cli_get_vrf_name(vty
);
9855 if (vrfname
== NULL
)
9856 return CMD_WARNING_CONFIG_FAILED
;
9858 /* Get mesh group base XPath. */
9859 snprintf(xpath_value
, sizeof(xpath_value
),
9860 FRR_PIM_AF_XPATH
"/msdp-mesh-groups[name='%s']",
9861 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4", gname
);
9862 if (!yang_dnode_exists(vty
->candidate_config
->dnode
, xpath_value
))
9865 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_DESTROY
, NULL
);
9866 return nb_cli_apply_changes(vty
, NULL
);
9869 static void ip_msdp_show_mesh_group(struct vty
*vty
, struct pim_msdp_mg
*mg
,
9870 struct json_object
*json
)
9872 struct listnode
*mbrnode
;
9873 struct pim_msdp_mg_mbr
*mbr
;
9874 char mbr_str
[INET_ADDRSTRLEN
];
9875 char src_str
[INET_ADDRSTRLEN
];
9876 char state_str
[PIM_MSDP_STATE_STRLEN
];
9877 enum pim_msdp_peer_state state
;
9878 json_object
*json_mg_row
= NULL
;
9879 json_object
*json_members
= NULL
;
9880 json_object
*json_row
= NULL
;
9882 pim_inet4_dump("<source?>", mg
->src_ip
, src_str
, sizeof(src_str
));
9884 /* currently there is only one mesh group but we should still
9886 * it a dict with mg-name as key */
9887 json_mg_row
= json_object_new_object();
9888 json_object_string_add(json_mg_row
, "name",
9889 mg
->mesh_group_name
);
9890 json_object_string_add(json_mg_row
, "source", src_str
);
9892 vty_out(vty
, "Mesh group : %s\n", mg
->mesh_group_name
);
9893 vty_out(vty
, " Source : %s\n", src_str
);
9894 vty_out(vty
, " Member State\n");
9897 for (ALL_LIST_ELEMENTS_RO(mg
->mbr_list
, mbrnode
, mbr
)) {
9898 pim_inet4_dump("<mbr?>", mbr
->mbr_ip
, mbr_str
, sizeof(mbr_str
));
9900 state
= mbr
->mp
->state
;
9902 state
= PIM_MSDP_DISABLED
;
9904 pim_msdp_state_dump(state
, state_str
, sizeof(state_str
));
9906 json_row
= json_object_new_object();
9907 json_object_string_add(json_row
, "member", mbr_str
);
9908 json_object_string_add(json_row
, "state", state_str
);
9909 if (!json_members
) {
9910 json_members
= json_object_new_object();
9911 json_object_object_add(json_mg_row
, "members",
9914 json_object_object_add(json_members
, mbr_str
, json_row
);
9916 vty_out(vty
, " %-15s %11s\n", mbr_str
, state_str
);
9921 json_object_object_add(json
, mg
->mesh_group_name
, json_mg_row
);
9924 DEFUN (show_ip_msdp_mesh_group
,
9925 show_ip_msdp_mesh_group_cmd
,
9926 "show ip msdp [vrf NAME] mesh-group [json]",
9931 "MSDP mesh-group information\n"
9934 bool uj
= use_json(argc
, argv
);
9936 struct pim_msdp_mg
*mg
;
9937 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
9938 struct pim_instance
*pim
= vrf
->info
;
9939 struct json_object
*json
= NULL
;
9944 /* Quick case: list is empty. */
9945 if (SLIST_EMPTY(&pim
->msdp
.mglist
)) {
9947 vty_out(vty
, "{}\n");
9953 json
= json_object_new_object();
9955 SLIST_FOREACH (mg
, &pim
->msdp
.mglist
, mg_entry
)
9956 ip_msdp_show_mesh_group(vty
, mg
, json
);
9959 vty_out(vty
, "%s\n",
9960 json_object_to_json_string_ext(
9961 json
, JSON_C_TO_STRING_PRETTY
));
9962 json_object_free(json
);
9968 DEFUN (show_ip_msdp_mesh_group_vrf_all
,
9969 show_ip_msdp_mesh_group_vrf_all_cmd
,
9970 "show ip msdp vrf all mesh-group [json]",
9975 "MSDP mesh-group information\n"
9978 bool uj
= use_json(argc
, argv
);
9979 struct json_object
*json
= NULL
, *vrf_json
= NULL
;
9980 struct pim_instance
*pim
;
9981 struct pim_msdp_mg
*mg
;
9985 json
= json_object_new_object();
9987 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
9989 vrf_json
= json_object_new_object();
9990 json_object_object_add(json
, vrf
->name
, vrf_json
);
9992 vty_out(vty
, "VRF: %s\n", vrf
->name
);
9995 SLIST_FOREACH (mg
, &pim
->msdp
.mglist
, mg_entry
)
9996 ip_msdp_show_mesh_group(vty
, mg
, vrf_json
);
10000 vty_out(vty
, "%s\n",
10001 json_object_to_json_string_ext(
10002 json
, JSON_C_TO_STRING_PRETTY
));
10003 json_object_free(json
);
10006 return CMD_SUCCESS
;
10009 static void ip_msdp_show_peers(struct pim_instance
*pim
, struct vty
*vty
,
10012 struct listnode
*mpnode
;
10013 struct pim_msdp_peer
*mp
;
10014 char peer_str
[INET_ADDRSTRLEN
];
10015 char local_str
[INET_ADDRSTRLEN
];
10016 char state_str
[PIM_MSDP_STATE_STRLEN
];
10017 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
10019 json_object
*json
= NULL
;
10020 json_object
*json_row
= NULL
;
10024 json
= json_object_new_object();
10027 "Peer Local State Uptime SaCnt\n");
10030 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
10031 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
10032 now
= pim_time_monotonic_sec();
10033 pim_time_uptime(timebuf
, sizeof(timebuf
),
10036 strlcpy(timebuf
, "-", sizeof(timebuf
));
10038 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
10039 pim_inet4_dump("<local?>", mp
->local
, local_str
,
10040 sizeof(local_str
));
10041 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
10043 json_row
= json_object_new_object();
10044 json_object_string_add(json_row
, "peer", peer_str
);
10045 json_object_string_add(json_row
, "local", local_str
);
10046 json_object_string_add(json_row
, "state", state_str
);
10047 json_object_string_add(json_row
, "upTime", timebuf
);
10048 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
10049 json_object_object_add(json
, peer_str
, json_row
);
10051 vty_out(vty
, "%-15s %15s %11s %8s %6d\n", peer_str
,
10052 local_str
, state_str
, timebuf
, mp
->sa_cnt
);
10057 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10058 json
, JSON_C_TO_STRING_PRETTY
));
10059 json_object_free(json
);
10063 static void ip_msdp_show_peers_detail(struct pim_instance
*pim
, struct vty
*vty
,
10064 const char *peer
, bool uj
)
10066 struct listnode
*mpnode
;
10067 struct pim_msdp_peer
*mp
;
10068 char peer_str
[INET_ADDRSTRLEN
];
10069 char local_str
[INET_ADDRSTRLEN
];
10070 char state_str
[PIM_MSDP_STATE_STRLEN
];
10071 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
10072 char katimer
[PIM_MSDP_TIMER_STRLEN
];
10073 char crtimer
[PIM_MSDP_TIMER_STRLEN
];
10074 char holdtimer
[PIM_MSDP_TIMER_STRLEN
];
10076 json_object
*json
= NULL
;
10077 json_object
*json_row
= NULL
;
10080 json
= json_object_new_object();
10083 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
10084 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
10085 if (strcmp(peer
, "detail") && strcmp(peer
, peer_str
))
10088 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
10089 now
= pim_time_monotonic_sec();
10090 pim_time_uptime(timebuf
, sizeof(timebuf
),
10093 strlcpy(timebuf
, "-", sizeof(timebuf
));
10095 pim_inet4_dump("<local?>", mp
->local
, local_str
,
10096 sizeof(local_str
));
10097 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
10098 pim_time_timer_to_hhmmss(katimer
, sizeof(katimer
),
10100 pim_time_timer_to_hhmmss(crtimer
, sizeof(crtimer
),
10102 pim_time_timer_to_hhmmss(holdtimer
, sizeof(holdtimer
),
10106 json_row
= json_object_new_object();
10107 json_object_string_add(json_row
, "peer", peer_str
);
10108 json_object_string_add(json_row
, "local", local_str
);
10109 if (mp
->flags
& PIM_MSDP_PEERF_IN_GROUP
)
10110 json_object_string_add(json_row
,
10112 mp
->mesh_group_name
);
10113 json_object_string_add(json_row
, "state", state_str
);
10114 json_object_string_add(json_row
, "upTime", timebuf
);
10115 json_object_string_add(json_row
, "keepAliveTimer",
10117 json_object_string_add(json_row
, "connRetryTimer",
10119 json_object_string_add(json_row
, "holdTimer",
10121 json_object_string_add(json_row
, "lastReset",
10123 json_object_int_add(json_row
, "connAttempts",
10124 mp
->conn_attempts
);
10125 json_object_int_add(json_row
, "establishedChanges",
10127 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
10128 json_object_int_add(json_row
, "kaSent", mp
->ka_tx_cnt
);
10129 json_object_int_add(json_row
, "kaRcvd", mp
->ka_rx_cnt
);
10130 json_object_int_add(json_row
, "saSent", mp
->sa_tx_cnt
);
10131 json_object_int_add(json_row
, "saRcvd", mp
->sa_rx_cnt
);
10132 json_object_object_add(json
, peer_str
, json_row
);
10134 vty_out(vty
, "Peer : %s\n", peer_str
);
10135 vty_out(vty
, " Local : %s\n", local_str
);
10136 if (mp
->flags
& PIM_MSDP_PEERF_IN_GROUP
)
10137 vty_out(vty
, " Mesh Group : %s\n",
10138 mp
->mesh_group_name
);
10139 vty_out(vty
, " State : %s\n", state_str
);
10140 vty_out(vty
, " Uptime : %s\n", timebuf
);
10142 vty_out(vty
, " Keepalive Timer : %s\n", katimer
);
10143 vty_out(vty
, " Conn Retry Timer : %s\n", crtimer
);
10144 vty_out(vty
, " Hold Timer : %s\n", holdtimer
);
10145 vty_out(vty
, " Last Reset : %s\n",
10147 vty_out(vty
, " Conn Attempts : %d\n",
10148 mp
->conn_attempts
);
10149 vty_out(vty
, " Established Changes : %d\n",
10151 vty_out(vty
, " SA Count : %d\n",
10153 vty_out(vty
, " Statistics :\n");
10156 vty_out(vty
, " Keepalives : %10d %10d\n",
10157 mp
->ka_tx_cnt
, mp
->ka_rx_cnt
);
10158 vty_out(vty
, " SAs : %10d %10d\n",
10159 mp
->sa_tx_cnt
, mp
->sa_rx_cnt
);
10160 vty_out(vty
, "\n");
10165 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10166 json
, JSON_C_TO_STRING_PRETTY
));
10167 json_object_free(json
);
10171 DEFUN (show_ip_msdp_peer_detail
,
10172 show_ip_msdp_peer_detail_cmd
,
10173 "show ip msdp [vrf NAME] peer [detail|A.B.C.D] [json]",
10178 "MSDP peer information\n"
10179 "Detailed output\n"
10180 "peer ip address\n"
10183 bool uj
= use_json(argc
, argv
);
10185 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10188 return CMD_WARNING
;
10192 if (argv_find(argv
, argc
, "detail", &idx
))
10193 arg
= argv
[idx
]->text
;
10194 else if (argv_find(argv
, argc
, "A.B.C.D", &idx
))
10195 arg
= argv
[idx
]->arg
;
10198 ip_msdp_show_peers_detail(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
10200 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
10202 return CMD_SUCCESS
;
10205 DEFUN (show_ip_msdp_peer_detail_vrf_all
,
10206 show_ip_msdp_peer_detail_vrf_all_cmd
,
10207 "show ip msdp vrf all peer [detail|A.B.C.D] [json]",
10212 "MSDP peer information\n"
10213 "Detailed output\n"
10214 "peer ip address\n"
10218 bool uj
= use_json(argc
, argv
);
10223 vty_out(vty
, "{ ");
10224 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
10227 vty_out(vty
, ", ");
10228 vty_out(vty
, " \"%s\": ", vrf
->name
);
10231 vty_out(vty
, "VRF: %s\n", vrf
->name
);
10232 if (argv_find(argv
, argc
, "detail", &idx
)
10233 || argv_find(argv
, argc
, "A.B.C.D", &idx
))
10234 ip_msdp_show_peers_detail(vrf
->info
, vty
,
10235 argv
[idx
]->arg
, uj
);
10237 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
10240 vty_out(vty
, "}\n");
10242 return CMD_SUCCESS
;
10245 static void ip_msdp_show_sa(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
10247 struct listnode
*sanode
;
10248 struct pim_msdp_sa
*sa
;
10249 char src_str
[INET_ADDRSTRLEN
];
10250 char grp_str
[INET_ADDRSTRLEN
];
10251 char rp_str
[INET_ADDRSTRLEN
];
10252 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
10256 json_object
*json
= NULL
;
10257 json_object
*json_group
= NULL
;
10258 json_object
*json_row
= NULL
;
10261 json
= json_object_new_object();
10264 "Source Group RP Local SPT Uptime\n");
10267 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
10268 now
= pim_time_monotonic_sec();
10269 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
10270 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
10271 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
10272 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
10273 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
10275 strlcpy(spt_str
, "yes", sizeof(spt_str
));
10277 strlcpy(spt_str
, "no", sizeof(spt_str
));
10280 strlcpy(rp_str
, "-", sizeof(rp_str
));
10281 strlcpy(spt_str
, "-", sizeof(spt_str
));
10283 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
10284 strlcpy(local_str
, "yes", sizeof(local_str
));
10286 strlcpy(local_str
, "no", sizeof(local_str
));
10289 json_object_object_get_ex(json
, grp_str
, &json_group
);
10292 json_group
= json_object_new_object();
10293 json_object_object_add(json
, grp_str
,
10297 json_row
= json_object_new_object();
10298 json_object_string_add(json_row
, "source", src_str
);
10299 json_object_string_add(json_row
, "group", grp_str
);
10300 json_object_string_add(json_row
, "rp", rp_str
);
10301 json_object_string_add(json_row
, "local", local_str
);
10302 json_object_string_add(json_row
, "sptSetup", spt_str
);
10303 json_object_string_add(json_row
, "upTime", timebuf
);
10304 json_object_object_add(json_group
, src_str
, json_row
);
10306 vty_out(vty
, "%-15s %15s %15s %5c %3c %8s\n",
10307 src_str
, grp_str
, rp_str
, local_str
[0],
10308 spt_str
[0], timebuf
);
10313 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10314 json
, JSON_C_TO_STRING_PRETTY
));
10315 json_object_free(json
);
10319 static void ip_msdp_show_sa_entry_detail(struct pim_msdp_sa
*sa
,
10320 const char *src_str
,
10321 const char *grp_str
, struct vty
*vty
,
10322 bool uj
, json_object
*json
)
10324 char rp_str
[INET_ADDRSTRLEN
];
10325 char peer_str
[INET_ADDRSTRLEN
];
10326 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
10329 char statetimer
[PIM_MSDP_TIMER_STRLEN
];
10331 json_object
*json_group
= NULL
;
10332 json_object
*json_row
= NULL
;
10334 now
= pim_time_monotonic_sec();
10335 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
10336 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
10337 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
10338 pim_inet4_dump("<peer?>", sa
->peer
, peer_str
, sizeof(peer_str
));
10340 strlcpy(spt_str
, "yes", sizeof(spt_str
));
10342 strlcpy(spt_str
, "no", sizeof(spt_str
));
10345 strlcpy(rp_str
, "-", sizeof(rp_str
));
10346 strlcpy(peer_str
, "-", sizeof(peer_str
));
10347 strlcpy(spt_str
, "-", sizeof(spt_str
));
10349 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
10350 strlcpy(local_str
, "yes", sizeof(local_str
));
10352 strlcpy(local_str
, "no", sizeof(local_str
));
10354 pim_time_timer_to_hhmmss(statetimer
, sizeof(statetimer
),
10355 sa
->sa_state_timer
);
10357 json_object_object_get_ex(json
, grp_str
, &json_group
);
10360 json_group
= json_object_new_object();
10361 json_object_object_add(json
, grp_str
, json_group
);
10364 json_row
= json_object_new_object();
10365 json_object_string_add(json_row
, "source", src_str
);
10366 json_object_string_add(json_row
, "group", grp_str
);
10367 json_object_string_add(json_row
, "rp", rp_str
);
10368 json_object_string_add(json_row
, "local", local_str
);
10369 json_object_string_add(json_row
, "sptSetup", spt_str
);
10370 json_object_string_add(json_row
, "upTime", timebuf
);
10371 json_object_string_add(json_row
, "stateTimer", statetimer
);
10372 json_object_object_add(json_group
, src_str
, json_row
);
10374 vty_out(vty
, "SA : %s\n", sa
->sg_str
);
10375 vty_out(vty
, " RP : %s\n", rp_str
);
10376 vty_out(vty
, " Peer : %s\n", peer_str
);
10377 vty_out(vty
, " Local : %s\n", local_str
);
10378 vty_out(vty
, " SPT Setup : %s\n", spt_str
);
10379 vty_out(vty
, " Uptime : %s\n", timebuf
);
10380 vty_out(vty
, " State Timer : %s\n", statetimer
);
10381 vty_out(vty
, "\n");
10385 static void ip_msdp_show_sa_detail(struct pim_instance
*pim
, struct vty
*vty
,
10388 struct listnode
*sanode
;
10389 struct pim_msdp_sa
*sa
;
10390 char src_str
[INET_ADDRSTRLEN
];
10391 char grp_str
[INET_ADDRSTRLEN
];
10392 json_object
*json
= NULL
;
10395 json
= json_object_new_object();
10398 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
10399 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
10400 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
10401 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
, uj
,
10406 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10407 json
, JSON_C_TO_STRING_PRETTY
));
10408 json_object_free(json
);
10412 DEFUN (show_ip_msdp_sa_detail
,
10413 show_ip_msdp_sa_detail_cmd
,
10414 "show ip msdp [vrf NAME] sa detail [json]",
10419 "MSDP active-source information\n"
10420 "Detailed output\n"
10423 bool uj
= use_json(argc
, argv
);
10425 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10428 return CMD_WARNING
;
10430 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
10432 return CMD_SUCCESS
;
10435 DEFUN (show_ip_msdp_sa_detail_vrf_all
,
10436 show_ip_msdp_sa_detail_vrf_all_cmd
,
10437 "show ip msdp vrf all sa detail [json]",
10442 "MSDP active-source information\n"
10443 "Detailed output\n"
10446 bool uj
= use_json(argc
, argv
);
10451 vty_out(vty
, "{ ");
10452 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
10455 vty_out(vty
, ", ");
10456 vty_out(vty
, " \"%s\": ", vrf
->name
);
10459 vty_out(vty
, "VRF: %s\n", vrf
->name
);
10460 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
10463 vty_out(vty
, "}\n");
10465 return CMD_SUCCESS
;
10468 static void ip_msdp_show_sa_addr(struct pim_instance
*pim
, struct vty
*vty
,
10469 const char *addr
, bool uj
)
10471 struct listnode
*sanode
;
10472 struct pim_msdp_sa
*sa
;
10473 char src_str
[INET_ADDRSTRLEN
];
10474 char grp_str
[INET_ADDRSTRLEN
];
10475 json_object
*json
= NULL
;
10478 json
= json_object_new_object();
10481 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
10482 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
10483 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
10484 if (!strcmp(addr
, src_str
) || !strcmp(addr
, grp_str
)) {
10485 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
10491 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10492 json
, JSON_C_TO_STRING_PRETTY
));
10493 json_object_free(json
);
10497 static void ip_msdp_show_sa_sg(struct pim_instance
*pim
, struct vty
*vty
,
10498 const char *src
, const char *grp
, bool uj
)
10500 struct listnode
*sanode
;
10501 struct pim_msdp_sa
*sa
;
10502 char src_str
[INET_ADDRSTRLEN
];
10503 char grp_str
[INET_ADDRSTRLEN
];
10504 json_object
*json
= NULL
;
10507 json
= json_object_new_object();
10510 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
10511 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
10512 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
10513 if (!strcmp(src
, src_str
) && !strcmp(grp
, grp_str
)) {
10514 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
10520 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10521 json
, JSON_C_TO_STRING_PRETTY
));
10522 json_object_free(json
);
10526 DEFUN (show_ip_msdp_sa_sg
,
10527 show_ip_msdp_sa_sg_cmd
,
10528 "show ip msdp [vrf NAME] sa [A.B.C.D [A.B.C.D]] [json]",
10533 "MSDP active-source information\n"
10534 "source or group ip\n"
10538 bool uj
= use_json(argc
, argv
);
10542 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10545 return CMD_WARNING
;
10547 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
10549 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
10553 if (src_ip
&& grp_ip
)
10554 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
10556 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
10558 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
10560 return CMD_SUCCESS
;
10563 DEFUN (show_ip_msdp_sa_sg_vrf_all
,
10564 show_ip_msdp_sa_sg_vrf_all_cmd
,
10565 "show ip msdp vrf all sa [A.B.C.D [A.B.C.D]] [json]",
10570 "MSDP active-source information\n"
10571 "source or group ip\n"
10575 bool uj
= use_json(argc
, argv
);
10580 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
10582 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
10587 vty_out(vty
, "{ ");
10588 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
10591 vty_out(vty
, ", ");
10592 vty_out(vty
, " \"%s\": ", vrf
->name
);
10595 vty_out(vty
, "VRF: %s\n", vrf
->name
);
10597 if (src_ip
&& grp_ip
)
10598 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
10600 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
10602 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
10605 vty_out(vty
, "}\n");
10607 return CMD_SUCCESS
;
10610 struct pim_sg_cache_walk_data
{
10613 json_object
*json_group
;
10614 struct in_addr addr
;
10618 static void pim_show_vxlan_sg_entry(struct pim_vxlan_sg
*vxlan_sg
,
10619 struct pim_sg_cache_walk_data
*cwd
)
10621 struct vty
*vty
= cwd
->vty
;
10622 json_object
*json
= cwd
->json
;
10623 char src_str
[INET_ADDRSTRLEN
];
10624 char grp_str
[INET_ADDRSTRLEN
];
10625 json_object
*json_row
;
10626 bool installed
= (vxlan_sg
->up
) ? true : false;
10627 const char *iif_name
= vxlan_sg
->iif
?vxlan_sg
->iif
->name
:"-";
10628 const char *oif_name
;
10630 if (pim_vxlan_is_orig_mroute(vxlan_sg
))
10631 oif_name
= vxlan_sg
->orig_oif
?vxlan_sg
->orig_oif
->name
:"";
10633 oif_name
= vxlan_sg
->term_oif
?vxlan_sg
->term_oif
->name
:"";
10635 if (cwd
->addr_match
&& (vxlan_sg
->sg
.src
.s_addr
!= cwd
->addr
.s_addr
) &&
10636 (vxlan_sg
->sg
.grp
.s_addr
!= cwd
->addr
.s_addr
)) {
10639 pim_inet4_dump("<src?>", vxlan_sg
->sg
.src
, src_str
, sizeof(src_str
));
10640 pim_inet4_dump("<grp?>", vxlan_sg
->sg
.grp
, grp_str
, sizeof(grp_str
));
10642 json_object_object_get_ex(json
, grp_str
, &cwd
->json_group
);
10644 if (!cwd
->json_group
) {
10645 cwd
->json_group
= json_object_new_object();
10646 json_object_object_add(json
, grp_str
,
10650 json_row
= json_object_new_object();
10651 json_object_string_add(json_row
, "source", src_str
);
10652 json_object_string_add(json_row
, "group", grp_str
);
10653 json_object_string_add(json_row
, "input", iif_name
);
10654 json_object_string_add(json_row
, "output", oif_name
);
10656 json_object_boolean_true_add(json_row
, "installed");
10658 json_object_boolean_false_add(json_row
, "installed");
10659 json_object_object_add(cwd
->json_group
, src_str
, json_row
);
10661 vty_out(vty
, "%-15s %-15s %-15s %-15s %-5s\n",
10662 src_str
, grp_str
, iif_name
, oif_name
,
10667 static void pim_show_vxlan_sg_hash_entry(struct hash_bucket
*bucket
, void *arg
)
10669 pim_show_vxlan_sg_entry((struct pim_vxlan_sg
*)bucket
->data
,
10670 (struct pim_sg_cache_walk_data
*)arg
);
10673 static void pim_show_vxlan_sg(struct pim_instance
*pim
,
10674 struct vty
*vty
, bool uj
)
10676 json_object
*json
= NULL
;
10677 struct pim_sg_cache_walk_data cwd
;
10680 json
= json_object_new_object();
10682 vty_out(vty
, "Codes: I -> installed\n");
10684 "Source Group Input Output Flags\n");
10687 memset(&cwd
, 0, sizeof(cwd
));
10690 hash_iterate(pim
->vxlan
.sg_hash
, pim_show_vxlan_sg_hash_entry
, &cwd
);
10693 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10694 json
, JSON_C_TO_STRING_PRETTY
));
10695 json_object_free(json
);
10699 static void pim_show_vxlan_sg_match_addr(struct pim_instance
*pim
,
10700 struct vty
*vty
, char *addr_str
,
10703 json_object
*json
= NULL
;
10704 struct pim_sg_cache_walk_data cwd
;
10707 memset(&cwd
, 0, sizeof(cwd
));
10708 result
= inet_pton(AF_INET
, addr_str
, &cwd
.addr
);
10710 vty_out(vty
, "Bad address %s: errno=%d: %s\n", addr_str
,
10711 errno
, safe_strerror(errno
));
10716 json
= json_object_new_object();
10718 vty_out(vty
, "Codes: I -> installed\n");
10720 "Source Group Input Output Flags\n");
10725 cwd
.addr_match
= true;
10726 hash_iterate(pim
->vxlan
.sg_hash
, pim_show_vxlan_sg_hash_entry
, &cwd
);
10729 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10730 json
, JSON_C_TO_STRING_PRETTY
));
10731 json_object_free(json
);
10735 static void pim_show_vxlan_sg_one(struct pim_instance
*pim
,
10736 struct vty
*vty
, char *src_str
, char *grp_str
,
10739 json_object
*json
= NULL
;
10740 struct prefix_sg sg
;
10742 struct pim_vxlan_sg
*vxlan_sg
;
10743 const char *iif_name
;
10745 const char *oif_name
;
10747 result
= inet_pton(AF_INET
, src_str
, &sg
.src
);
10749 vty_out(vty
, "Bad src address %s: errno=%d: %s\n", src_str
,
10750 errno
, safe_strerror(errno
));
10753 result
= inet_pton(AF_INET
, grp_str
, &sg
.grp
);
10755 vty_out(vty
, "Bad grp address %s: errno=%d: %s\n", grp_str
,
10756 errno
, safe_strerror(errno
));
10760 sg
.family
= AF_INET
;
10761 sg
.prefixlen
= IPV4_MAX_BITLEN
;
10763 json
= json_object_new_object();
10765 vxlan_sg
= pim_vxlan_sg_find(pim
, &sg
);
10767 installed
= (vxlan_sg
->up
) ? true : false;
10768 iif_name
= vxlan_sg
->iif
?vxlan_sg
->iif
->name
:"-";
10770 if (pim_vxlan_is_orig_mroute(vxlan_sg
))
10772 vxlan_sg
->orig_oif
?vxlan_sg
->orig_oif
->name
:"";
10775 vxlan_sg
->term_oif
?vxlan_sg
->term_oif
->name
:"";
10778 json_object_string_add(json
, "source", src_str
);
10779 json_object_string_add(json
, "group", grp_str
);
10780 json_object_string_add(json
, "input", iif_name
);
10781 json_object_string_add(json
, "output", oif_name
);
10783 json_object_boolean_true_add(json
, "installed");
10785 json_object_boolean_false_add(json
,
10788 vty_out(vty
, "SG : %s\n", vxlan_sg
->sg_str
);
10789 vty_out(vty
, " Input : %s\n", iif_name
);
10790 vty_out(vty
, " Output : %s\n", oif_name
);
10791 vty_out(vty
, " installed : %s\n",
10792 installed
?"yes":"no");
10797 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10798 json
, JSON_C_TO_STRING_PRETTY
));
10799 json_object_free(json
);
10803 DEFUN (show_ip_pim_vxlan_sg
,
10804 show_ip_pim_vxlan_sg_cmd
,
10805 "show ip pim [vrf NAME] vxlan-groups [A.B.C.D [A.B.C.D]] [json]",
10810 "VxLAN BUM groups\n"
10811 "source or group ip\n"
10815 bool uj
= use_json(argc
, argv
);
10819 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10822 return CMD_WARNING
;
10824 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ?
10825 argv
[idx
++]->arg
:NULL
;
10826 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
) ?
10827 argv
[idx
]->arg
:NULL
;
10829 if (src_ip
&& grp_ip
)
10830 pim_show_vxlan_sg_one(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
10832 pim_show_vxlan_sg_match_addr(vrf
->info
, vty
, src_ip
, uj
);
10834 pim_show_vxlan_sg(vrf
->info
, vty
, uj
);
10836 return CMD_SUCCESS
;
10839 static void pim_show_vxlan_sg_work(struct pim_instance
*pim
,
10840 struct vty
*vty
, bool uj
)
10842 json_object
*json
= NULL
;
10843 struct pim_sg_cache_walk_data cwd
;
10844 struct listnode
*node
;
10845 struct pim_vxlan_sg
*vxlan_sg
;
10848 json
= json_object_new_object();
10850 vty_out(vty
, "Codes: I -> installed\n");
10852 "Source Group Input Flags\n");
10855 memset(&cwd
, 0, sizeof(cwd
));
10858 for (ALL_LIST_ELEMENTS_RO(pim_vxlan_p
->work_list
, node
, vxlan_sg
))
10859 pim_show_vxlan_sg_entry(vxlan_sg
, &cwd
);
10862 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10863 json
, JSON_C_TO_STRING_PRETTY
));
10864 json_object_free(json
);
10868 DEFUN_HIDDEN (show_ip_pim_vxlan_sg_work
,
10869 show_ip_pim_vxlan_sg_work_cmd
,
10870 "show ip pim [vrf NAME] vxlan-work [json]",
10875 "VxLAN work list\n"
10878 bool uj
= use_json(argc
, argv
);
10882 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10885 return CMD_WARNING
;
10887 pim_show_vxlan_sg_work(vrf
->info
, vty
, uj
);
10889 return CMD_SUCCESS
;
10892 DEFUN_HIDDEN (no_ip_pim_mlag
,
10893 no_ip_pim_mlag_cmd
,
10900 char mlag_xpath
[XPATH_MAXLEN
];
10902 snprintf(mlag_xpath
, sizeof(mlag_xpath
), FRR_PIM_AF_XPATH
,
10903 "frr-pim:pimd", "pim", "default", "frr-routing:ipv4");
10904 strlcat(mlag_xpath
, "/mlag", sizeof(mlag_xpath
));
10906 nb_cli_enqueue_change(vty
, mlag_xpath
, NB_OP_DESTROY
, NULL
);
10909 return nb_cli_apply_changes(vty
, NULL
);
10912 DEFUN_HIDDEN (ip_pim_mlag
,
10914 "ip pim mlag INTERFACE role [primary|secondary] state [up|down] addr A.B.C.D",
10918 "peerlink sub interface\n"
10920 "MLAG role primary\n"
10921 "MLAG role secondary\n"
10922 "peer session state\n"
10923 "peer session state up\n"
10924 "peer session state down\n"
10926 "unique ip address\n")
10929 char mlag_peerlink_rif_xpath
[XPATH_MAXLEN
];
10930 char mlag_my_role_xpath
[XPATH_MAXLEN
];
10931 char mlag_peer_state_xpath
[XPATH_MAXLEN
];
10932 char mlag_reg_address_xpath
[XPATH_MAXLEN
];
10934 snprintf(mlag_peerlink_rif_xpath
, sizeof(mlag_peerlink_rif_xpath
),
10936 "frr-pim:pimd", "pim", "default", "frr-routing:ipv4");
10937 strlcat(mlag_peerlink_rif_xpath
, "/mlag/peerlink-rif",
10938 sizeof(mlag_peerlink_rif_xpath
));
10941 nb_cli_enqueue_change(vty
, mlag_peerlink_rif_xpath
, NB_OP_MODIFY
,
10944 snprintf(mlag_my_role_xpath
, sizeof(mlag_my_role_xpath
),
10946 "frr-pim:pimd", "pim", "default", "frr-routing:ipv4");
10947 strlcat(mlag_my_role_xpath
, "/mlag/my-role",
10948 sizeof(mlag_my_role_xpath
));
10951 if (!strcmp(argv
[idx
]->arg
, "primary")) {
10952 nb_cli_enqueue_change(vty
, mlag_my_role_xpath
, NB_OP_MODIFY
,
10953 "MLAG_ROLE_PRIMARY");
10955 } else if (!strcmp(argv
[idx
]->arg
, "secondary")) {
10956 nb_cli_enqueue_change(vty
, mlag_my_role_xpath
, NB_OP_MODIFY
,
10957 "MLAG_ROLE_SECONDARY");
10960 vty_out(vty
, "unknown MLAG role %s\n", argv
[idx
]->arg
);
10961 return CMD_WARNING
;
10964 snprintf(mlag_peer_state_xpath
, sizeof(mlag_peer_state_xpath
),
10966 "frr-pim:pimd", "pim", "default", "frr-routing:ipv4");
10967 strlcat(mlag_peer_state_xpath
, "/mlag/peer-state",
10968 sizeof(mlag_peer_state_xpath
));
10971 if (!strcmp(argv
[idx
]->arg
, "up")) {
10972 nb_cli_enqueue_change(vty
, mlag_peer_state_xpath
, NB_OP_MODIFY
,
10975 } else if (strcmp(argv
[idx
]->arg
, "down")) {
10976 nb_cli_enqueue_change(vty
, mlag_peer_state_xpath
, NB_OP_MODIFY
,
10980 vty_out(vty
, "unknown MLAG state %s\n", argv
[idx
]->arg
);
10981 return CMD_WARNING
;
10984 snprintf(mlag_reg_address_xpath
, sizeof(mlag_reg_address_xpath
),
10986 "frr-pim:pimd", "pim", "default", "frr-routing:ipv4");
10987 strlcat(mlag_reg_address_xpath
, "/mlag/reg-address",
10988 sizeof(mlag_reg_address_xpath
));
10991 nb_cli_enqueue_change(vty
, mlag_reg_address_xpath
, NB_OP_MODIFY
,
10994 return nb_cli_apply_changes(vty
, NULL
);
10997 void pim_cmd_init(void)
10999 if_cmd_init(pim_interface_config_write
);
11001 install_node(&debug_node
);
11003 install_element(ENABLE_NODE
, &pim_test_sg_keepalive_cmd
);
11005 install_element(CONFIG_NODE
, &ip_pim_rp_cmd
);
11006 install_element(VRF_NODE
, &ip_pim_rp_cmd
);
11007 install_element(CONFIG_NODE
, &no_ip_pim_rp_cmd
);
11008 install_element(VRF_NODE
, &no_ip_pim_rp_cmd
);
11009 install_element(CONFIG_NODE
, &ip_pim_rp_prefix_list_cmd
);
11010 install_element(VRF_NODE
, &ip_pim_rp_prefix_list_cmd
);
11011 install_element(CONFIG_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
11012 install_element(VRF_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
11013 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
11014 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
11015 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
11016 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
11017 install_element(CONFIG_NODE
, &ip_pim_ssm_prefix_list_cmd
);
11018 install_element(VRF_NODE
, &ip_pim_ssm_prefix_list_cmd
);
11019 install_element(CONFIG_NODE
, &ip_pim_register_suppress_cmd
);
11020 install_element(CONFIG_NODE
, &no_ip_pim_register_suppress_cmd
);
11021 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
11022 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
11023 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
11024 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
11025 install_element(CONFIG_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
11026 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
11027 install_element(CONFIG_NODE
,
11028 &no_ip_pim_spt_switchover_infinity_plist_cmd
);
11029 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_plist_cmd
);
11030 install_element(CONFIG_NODE
, &pim_register_accept_list_cmd
);
11031 install_element(VRF_NODE
, &pim_register_accept_list_cmd
);
11032 install_element(CONFIG_NODE
, &ip_pim_joinprune_time_cmd
);
11033 install_element(CONFIG_NODE
, &no_ip_pim_joinprune_time_cmd
);
11034 install_element(CONFIG_NODE
, &ip_pim_keep_alive_cmd
);
11035 install_element(VRF_NODE
, &ip_pim_keep_alive_cmd
);
11036 install_element(CONFIG_NODE
, &ip_pim_rp_keep_alive_cmd
);
11037 install_element(VRF_NODE
, &ip_pim_rp_keep_alive_cmd
);
11038 install_element(CONFIG_NODE
, &no_ip_pim_keep_alive_cmd
);
11039 install_element(VRF_NODE
, &no_ip_pim_keep_alive_cmd
);
11040 install_element(CONFIG_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
11041 install_element(VRF_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
11042 install_element(CONFIG_NODE
, &ip_pim_packets_cmd
);
11043 install_element(CONFIG_NODE
, &no_ip_pim_packets_cmd
);
11044 install_element(CONFIG_NODE
, &ip_pim_v6_secondary_cmd
);
11045 install_element(VRF_NODE
, &ip_pim_v6_secondary_cmd
);
11046 install_element(CONFIG_NODE
, &no_ip_pim_v6_secondary_cmd
);
11047 install_element(VRF_NODE
, &no_ip_pim_v6_secondary_cmd
);
11048 install_element(CONFIG_NODE
, &ip_ssmpingd_cmd
);
11049 install_element(VRF_NODE
, &ip_ssmpingd_cmd
);
11050 install_element(CONFIG_NODE
, &no_ip_ssmpingd_cmd
);
11051 install_element(VRF_NODE
, &no_ip_ssmpingd_cmd
);
11052 install_element(CONFIG_NODE
, &ip_msdp_peer_cmd
);
11053 install_element(VRF_NODE
, &ip_msdp_peer_cmd
);
11054 install_element(CONFIG_NODE
, &no_ip_msdp_peer_cmd
);
11055 install_element(VRF_NODE
, &no_ip_msdp_peer_cmd
);
11056 install_element(CONFIG_NODE
, &ip_pim_ecmp_cmd
);
11057 install_element(VRF_NODE
, &ip_pim_ecmp_cmd
);
11058 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_cmd
);
11059 install_element(VRF_NODE
, &no_ip_pim_ecmp_cmd
);
11060 install_element(CONFIG_NODE
, &ip_pim_ecmp_rebalance_cmd
);
11061 install_element(VRF_NODE
, &ip_pim_ecmp_rebalance_cmd
);
11062 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
11063 install_element(VRF_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
11064 install_element(CONFIG_NODE
, &ip_pim_mlag_cmd
);
11065 install_element(CONFIG_NODE
, &no_ip_pim_mlag_cmd
);
11066 install_element(CONFIG_NODE
, &igmp_group_watermark_cmd
);
11067 install_element(VRF_NODE
, &igmp_group_watermark_cmd
);
11068 install_element(CONFIG_NODE
, &no_igmp_group_watermark_cmd
);
11069 install_element(VRF_NODE
, &no_igmp_group_watermark_cmd
);
11071 install_element(INTERFACE_NODE
, &interface_ip_igmp_cmd
);
11072 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_cmd
);
11073 install_element(INTERFACE_NODE
, &interface_ip_igmp_join_cmd
);
11074 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_join_cmd
);
11075 install_element(INTERFACE_NODE
, &interface_ip_igmp_version_cmd
);
11076 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_version_cmd
);
11077 install_element(INTERFACE_NODE
, &interface_ip_igmp_query_interval_cmd
);
11078 install_element(INTERFACE_NODE
,
11079 &interface_no_ip_igmp_query_interval_cmd
);
11080 install_element(INTERFACE_NODE
,
11081 &interface_ip_igmp_query_max_response_time_cmd
);
11082 install_element(INTERFACE_NODE
,
11083 &interface_no_ip_igmp_query_max_response_time_cmd
);
11084 install_element(INTERFACE_NODE
,
11085 &interface_ip_igmp_query_max_response_time_dsec_cmd
);
11086 install_element(INTERFACE_NODE
,
11087 &interface_no_ip_igmp_query_max_response_time_dsec_cmd
);
11088 install_element(INTERFACE_NODE
,
11089 &interface_ip_igmp_last_member_query_count_cmd
);
11090 install_element(INTERFACE_NODE
,
11091 &interface_no_ip_igmp_last_member_query_count_cmd
);
11092 install_element(INTERFACE_NODE
,
11093 &interface_ip_igmp_last_member_query_interval_cmd
);
11094 install_element(INTERFACE_NODE
,
11095 &interface_no_ip_igmp_last_member_query_interval_cmd
);
11096 install_element(INTERFACE_NODE
, &interface_ip_pim_activeactive_cmd
);
11097 install_element(INTERFACE_NODE
, &interface_ip_pim_ssm_cmd
);
11098 install_element(INTERFACE_NODE
, &interface_no_ip_pim_ssm_cmd
);
11099 install_element(INTERFACE_NODE
, &interface_ip_pim_sm_cmd
);
11100 install_element(INTERFACE_NODE
, &interface_no_ip_pim_sm_cmd
);
11101 install_element(INTERFACE_NODE
, &interface_ip_pim_cmd
);
11102 install_element(INTERFACE_NODE
, &interface_no_ip_pim_cmd
);
11103 install_element(INTERFACE_NODE
, &interface_ip_pim_drprio_cmd
);
11104 install_element(INTERFACE_NODE
, &interface_no_ip_pim_drprio_cmd
);
11105 install_element(INTERFACE_NODE
, &interface_ip_pim_hello_cmd
);
11106 install_element(INTERFACE_NODE
, &interface_no_ip_pim_hello_cmd
);
11107 install_element(INTERFACE_NODE
, &interface_ip_pim_boundary_oil_cmd
);
11108 install_element(INTERFACE_NODE
, &interface_no_ip_pim_boundary_oil_cmd
);
11109 install_element(INTERFACE_NODE
, &interface_ip_igmp_query_generate_cmd
);
11111 // Static mroutes NEB
11112 install_element(INTERFACE_NODE
, &interface_ip_mroute_cmd
);
11113 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_cmd
);
11115 install_element(VIEW_NODE
, &show_ip_igmp_interface_cmd
);
11116 install_element(VIEW_NODE
, &show_ip_igmp_interface_vrf_all_cmd
);
11117 install_element(VIEW_NODE
, &show_ip_igmp_join_cmd
);
11118 install_element(VIEW_NODE
, &show_ip_igmp_join_vrf_all_cmd
);
11119 install_element(VIEW_NODE
, &show_ip_igmp_groups_cmd
);
11120 install_element(VIEW_NODE
, &show_ip_igmp_groups_vrf_all_cmd
);
11121 install_element(VIEW_NODE
, &show_ip_igmp_groups_retransmissions_cmd
);
11122 install_element(VIEW_NODE
, &show_ip_igmp_sources_cmd
);
11123 install_element(VIEW_NODE
, &show_ip_igmp_sources_retransmissions_cmd
);
11124 install_element(VIEW_NODE
, &show_ip_igmp_statistics_cmd
);
11125 install_element(VIEW_NODE
, &show_ip_pim_assert_cmd
);
11126 install_element(VIEW_NODE
, &show_ip_pim_assert_internal_cmd
);
11127 install_element(VIEW_NODE
, &show_ip_pim_assert_metric_cmd
);
11128 install_element(VIEW_NODE
, &show_ip_pim_assert_winner_metric_cmd
);
11129 install_element(VIEW_NODE
, &show_ip_pim_interface_traffic_cmd
);
11130 install_element(VIEW_NODE
, &show_ip_pim_interface_cmd
);
11131 install_element(VIEW_NODE
, &show_ip_pim_interface_vrf_all_cmd
);
11132 install_element(VIEW_NODE
, &show_ip_pim_join_cmd
);
11133 install_element(VIEW_NODE
, &show_ip_pim_join_vrf_all_cmd
);
11134 install_element(VIEW_NODE
, &show_ip_pim_jp_agg_cmd
);
11135 install_element(VIEW_NODE
, &show_ip_pim_local_membership_cmd
);
11136 install_element(VIEW_NODE
, &show_ip_pim_mlag_summary_cmd
);
11137 install_element(VIEW_NODE
, &show_ip_pim_mlag_up_cmd
);
11138 install_element(VIEW_NODE
, &show_ip_pim_mlag_up_vrf_all_cmd
);
11139 install_element(VIEW_NODE
, &show_ip_pim_neighbor_cmd
);
11140 install_element(VIEW_NODE
, &show_ip_pim_neighbor_vrf_all_cmd
);
11141 install_element(VIEW_NODE
, &show_ip_pim_rpf_cmd
);
11142 install_element(VIEW_NODE
, &show_ip_pim_rpf_vrf_all_cmd
);
11143 install_element(VIEW_NODE
, &show_ip_pim_secondary_cmd
);
11144 install_element(VIEW_NODE
, &show_ip_pim_state_cmd
);
11145 install_element(VIEW_NODE
, &show_ip_pim_state_vrf_all_cmd
);
11146 install_element(VIEW_NODE
, &show_ip_pim_upstream_cmd
);
11147 install_element(VIEW_NODE
, &show_ip_pim_upstream_vrf_all_cmd
);
11148 install_element(VIEW_NODE
, &show_ip_pim_channel_cmd
);
11149 install_element(VIEW_NODE
, &show_ip_pim_upstream_join_desired_cmd
);
11150 install_element(VIEW_NODE
, &show_ip_pim_upstream_rpf_cmd
);
11151 install_element(VIEW_NODE
, &show_ip_pim_rp_cmd
);
11152 install_element(VIEW_NODE
, &show_ip_pim_rp_vrf_all_cmd
);
11153 install_element(VIEW_NODE
, &show_ip_pim_bsr_cmd
);
11154 install_element(VIEW_NODE
, &show_ip_multicast_cmd
);
11155 install_element(VIEW_NODE
, &show_ip_multicast_vrf_all_cmd
);
11156 install_element(VIEW_NODE
, &show_ip_multicast_count_cmd
);
11157 install_element(VIEW_NODE
, &show_ip_multicast_count_vrf_all_cmd
);
11158 install_element(VIEW_NODE
, &show_ip_mroute_cmd
);
11159 install_element(VIEW_NODE
, &show_ip_mroute_vrf_all_cmd
);
11160 install_element(VIEW_NODE
, &show_ip_mroute_count_cmd
);
11161 install_element(VIEW_NODE
, &show_ip_mroute_count_vrf_all_cmd
);
11162 install_element(VIEW_NODE
, &show_ip_mroute_summary_cmd
);
11163 install_element(VIEW_NODE
, &show_ip_mroute_summary_vrf_all_cmd
);
11164 install_element(VIEW_NODE
, &show_ip_rib_cmd
);
11165 install_element(VIEW_NODE
, &show_ip_ssmpingd_cmd
);
11166 install_element(VIEW_NODE
, &show_ip_pim_nexthop_cmd
);
11167 install_element(VIEW_NODE
, &show_ip_pim_nexthop_lookup_cmd
);
11168 install_element(VIEW_NODE
, &show_ip_pim_bsrp_cmd
);
11169 install_element(VIEW_NODE
, &show_ip_pim_bsm_db_cmd
);
11170 install_element(VIEW_NODE
, &show_ip_pim_statistics_cmd
);
11172 install_element(ENABLE_NODE
, &clear_ip_mroute_count_cmd
);
11173 install_element(ENABLE_NODE
, &clear_ip_interfaces_cmd
);
11174 install_element(ENABLE_NODE
, &clear_ip_igmp_interfaces_cmd
);
11175 install_element(ENABLE_NODE
, &clear_ip_mroute_cmd
);
11176 install_element(ENABLE_NODE
, &clear_ip_pim_interfaces_cmd
);
11177 install_element(ENABLE_NODE
, &clear_ip_pim_interface_traffic_cmd
);
11178 install_element(ENABLE_NODE
, &clear_ip_pim_oil_cmd
);
11179 install_element(ENABLE_NODE
, &clear_ip_pim_statistics_cmd
);
11180 install_element(ENABLE_NODE
, &clear_ip_pim_bsr_db_cmd
);
11182 install_element(ENABLE_NODE
, &show_debugging_pim_cmd
);
11184 install_element(ENABLE_NODE
, &debug_igmp_cmd
);
11185 install_element(ENABLE_NODE
, &no_debug_igmp_cmd
);
11186 install_element(ENABLE_NODE
, &debug_igmp_events_cmd
);
11187 install_element(ENABLE_NODE
, &no_debug_igmp_events_cmd
);
11188 install_element(ENABLE_NODE
, &debug_igmp_packets_cmd
);
11189 install_element(ENABLE_NODE
, &no_debug_igmp_packets_cmd
);
11190 install_element(ENABLE_NODE
, &debug_igmp_trace_cmd
);
11191 install_element(ENABLE_NODE
, &no_debug_igmp_trace_cmd
);
11192 install_element(ENABLE_NODE
, &debug_mroute_cmd
);
11193 install_element(ENABLE_NODE
, &debug_mroute_detail_cmd
);
11194 install_element(ENABLE_NODE
, &no_debug_mroute_cmd
);
11195 install_element(ENABLE_NODE
, &no_debug_mroute_detail_cmd
);
11196 install_element(ENABLE_NODE
, &debug_pim_static_cmd
);
11197 install_element(ENABLE_NODE
, &no_debug_pim_static_cmd
);
11198 install_element(ENABLE_NODE
, &debug_pim_cmd
);
11199 install_element(ENABLE_NODE
, &no_debug_pim_cmd
);
11200 install_element(ENABLE_NODE
, &debug_pim_nht_cmd
);
11201 install_element(ENABLE_NODE
, &no_debug_pim_nht_cmd
);
11202 install_element(ENABLE_NODE
, &debug_pim_nht_rp_cmd
);
11203 install_element(ENABLE_NODE
, &no_debug_pim_nht_rp_cmd
);
11204 install_element(ENABLE_NODE
, &debug_pim_events_cmd
);
11205 install_element(ENABLE_NODE
, &no_debug_pim_events_cmd
);
11206 install_element(ENABLE_NODE
, &debug_pim_packets_cmd
);
11207 install_element(ENABLE_NODE
, &no_debug_pim_packets_cmd
);
11208 install_element(ENABLE_NODE
, &debug_pim_packetdump_send_cmd
);
11209 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_send_cmd
);
11210 install_element(ENABLE_NODE
, &debug_pim_packetdump_recv_cmd
);
11211 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_recv_cmd
);
11212 install_element(ENABLE_NODE
, &debug_pim_trace_cmd
);
11213 install_element(ENABLE_NODE
, &no_debug_pim_trace_cmd
);
11214 install_element(ENABLE_NODE
, &debug_pim_trace_detail_cmd
);
11215 install_element(ENABLE_NODE
, &no_debug_pim_trace_detail_cmd
);
11216 install_element(ENABLE_NODE
, &debug_ssmpingd_cmd
);
11217 install_element(ENABLE_NODE
, &no_debug_ssmpingd_cmd
);
11218 install_element(ENABLE_NODE
, &debug_pim_zebra_cmd
);
11219 install_element(ENABLE_NODE
, &no_debug_pim_zebra_cmd
);
11220 install_element(ENABLE_NODE
, &debug_pim_mlag_cmd
);
11221 install_element(ENABLE_NODE
, &no_debug_pim_mlag_cmd
);
11222 install_element(ENABLE_NODE
, &debug_pim_vxlan_cmd
);
11223 install_element(ENABLE_NODE
, &no_debug_pim_vxlan_cmd
);
11224 install_element(ENABLE_NODE
, &debug_msdp_cmd
);
11225 install_element(ENABLE_NODE
, &no_debug_msdp_cmd
);
11226 install_element(ENABLE_NODE
, &debug_msdp_events_cmd
);
11227 install_element(ENABLE_NODE
, &no_debug_msdp_events_cmd
);
11228 install_element(ENABLE_NODE
, &debug_msdp_packets_cmd
);
11229 install_element(ENABLE_NODE
, &no_debug_msdp_packets_cmd
);
11230 install_element(ENABLE_NODE
, &debug_mtrace_cmd
);
11231 install_element(ENABLE_NODE
, &no_debug_mtrace_cmd
);
11232 install_element(ENABLE_NODE
, &debug_bsm_cmd
);
11233 install_element(ENABLE_NODE
, &no_debug_bsm_cmd
);
11235 install_element(CONFIG_NODE
, &debug_igmp_cmd
);
11236 install_element(CONFIG_NODE
, &no_debug_igmp_cmd
);
11237 install_element(CONFIG_NODE
, &debug_igmp_events_cmd
);
11238 install_element(CONFIG_NODE
, &no_debug_igmp_events_cmd
);
11239 install_element(CONFIG_NODE
, &debug_igmp_packets_cmd
);
11240 install_element(CONFIG_NODE
, &no_debug_igmp_packets_cmd
);
11241 install_element(CONFIG_NODE
, &debug_igmp_trace_cmd
);
11242 install_element(CONFIG_NODE
, &no_debug_igmp_trace_cmd
);
11243 install_element(CONFIG_NODE
, &debug_mroute_cmd
);
11244 install_element(CONFIG_NODE
, &debug_mroute_detail_cmd
);
11245 install_element(CONFIG_NODE
, &no_debug_mroute_cmd
);
11246 install_element(CONFIG_NODE
, &no_debug_mroute_detail_cmd
);
11247 install_element(CONFIG_NODE
, &debug_pim_static_cmd
);
11248 install_element(CONFIG_NODE
, &no_debug_pim_static_cmd
);
11249 install_element(CONFIG_NODE
, &debug_pim_cmd
);
11250 install_element(CONFIG_NODE
, &no_debug_pim_cmd
);
11251 install_element(CONFIG_NODE
, &debug_pim_nht_cmd
);
11252 install_element(CONFIG_NODE
, &no_debug_pim_nht_cmd
);
11253 install_element(CONFIG_NODE
, &debug_pim_nht_rp_cmd
);
11254 install_element(CONFIG_NODE
, &no_debug_pim_nht_rp_cmd
);
11255 install_element(CONFIG_NODE
, &debug_pim_events_cmd
);
11256 install_element(CONFIG_NODE
, &no_debug_pim_events_cmd
);
11257 install_element(CONFIG_NODE
, &debug_pim_packets_cmd
);
11258 install_element(CONFIG_NODE
, &no_debug_pim_packets_cmd
);
11259 install_element(CONFIG_NODE
, &debug_pim_trace_cmd
);
11260 install_element(CONFIG_NODE
, &no_debug_pim_trace_cmd
);
11261 install_element(CONFIG_NODE
, &debug_pim_trace_detail_cmd
);
11262 install_element(CONFIG_NODE
, &no_debug_pim_trace_detail_cmd
);
11263 install_element(CONFIG_NODE
, &debug_ssmpingd_cmd
);
11264 install_element(CONFIG_NODE
, &no_debug_ssmpingd_cmd
);
11265 install_element(CONFIG_NODE
, &debug_pim_zebra_cmd
);
11266 install_element(CONFIG_NODE
, &no_debug_pim_zebra_cmd
);
11267 install_element(CONFIG_NODE
, &debug_pim_mlag_cmd
);
11268 install_element(CONFIG_NODE
, &no_debug_pim_mlag_cmd
);
11269 install_element(CONFIG_NODE
, &debug_pim_vxlan_cmd
);
11270 install_element(CONFIG_NODE
, &no_debug_pim_vxlan_cmd
);
11271 install_element(CONFIG_NODE
, &debug_msdp_cmd
);
11272 install_element(CONFIG_NODE
, &no_debug_msdp_cmd
);
11273 install_element(CONFIG_NODE
, &debug_msdp_events_cmd
);
11274 install_element(CONFIG_NODE
, &no_debug_msdp_events_cmd
);
11275 install_element(CONFIG_NODE
, &debug_msdp_packets_cmd
);
11276 install_element(CONFIG_NODE
, &no_debug_msdp_packets_cmd
);
11277 install_element(CONFIG_NODE
, &debug_mtrace_cmd
);
11278 install_element(CONFIG_NODE
, &no_debug_mtrace_cmd
);
11279 install_element(CONFIG_NODE
, &debug_bsm_cmd
);
11280 install_element(CONFIG_NODE
, &no_debug_bsm_cmd
);
11282 install_element(CONFIG_NODE
, &ip_msdp_timers_cmd
);
11283 install_element(VRF_NODE
, &ip_msdp_timers_cmd
);
11284 install_element(CONFIG_NODE
, &no_ip_msdp_timers_cmd
);
11285 install_element(VRF_NODE
, &no_ip_msdp_timers_cmd
);
11286 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_member_cmd
);
11287 install_element(VRF_NODE
, &ip_msdp_mesh_group_member_cmd
);
11288 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
11289 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
11290 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_source_cmd
);
11291 install_element(VRF_NODE
, &ip_msdp_mesh_group_source_cmd
);
11292 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
11293 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
11294 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_cmd
);
11295 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_cmd
);
11296 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_cmd
);
11297 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_vrf_all_cmd
);
11298 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_cmd
);
11299 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_vrf_all_cmd
);
11300 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_cmd
);
11301 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_vrf_all_cmd
);
11302 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_cmd
);
11303 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_vrf_all_cmd
);
11304 install_element(VIEW_NODE
, &show_ip_pim_ssm_range_cmd
);
11305 install_element(VIEW_NODE
, &show_ip_pim_group_type_cmd
);
11306 install_element(VIEW_NODE
, &show_ip_pim_vxlan_sg_cmd
);
11307 install_element(VIEW_NODE
, &show_ip_pim_vxlan_sg_work_cmd
);
11308 install_element(INTERFACE_NODE
, &interface_pim_use_source_cmd
);
11309 install_element(INTERFACE_NODE
, &interface_no_pim_use_source_cmd
);
11310 /* Install BSM command */
11311 install_element(INTERFACE_NODE
, &ip_pim_bsm_cmd
);
11312 install_element(INTERFACE_NODE
, &no_ip_pim_bsm_cmd
);
11313 install_element(INTERFACE_NODE
, &ip_pim_ucast_bsm_cmd
);
11314 install_element(INTERFACE_NODE
, &no_ip_pim_ucast_bsm_cmd
);
11315 /* Install BFD command */
11316 install_element(INTERFACE_NODE
, &ip_pim_bfd_cmd
);
11317 install_element(INTERFACE_NODE
, &ip_pim_bfd_param_cmd
);
11318 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_profile_cmd
);
11319 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_cmd
);
11321 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_param_cmd
);
11322 #endif /* !HAVE_BFDD */