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"
68 #ifndef VTYSH_EXTRACT_PL
69 #include "pimd/pim_cmd_clippy.c"
72 static struct cmd_node interface_node
= {
74 .node
= INTERFACE_NODE
,
75 .parent_node
= CONFIG_NODE
,
76 .prompt
= "%s(config-if)# ",
77 .config_write
= pim_interface_config_write
,
80 static struct cmd_node debug_node
= {
84 .config_write
= pim_debug_config_write
,
87 static struct vrf
*pim_cmd_lookup_vrf(struct vty
*vty
, struct cmd_token
*argv
[],
88 const int argc
, int *idx
)
92 if (argv_find(argv
, argc
, "NAME", idx
))
93 vrf
= vrf_lookup_by_name(argv
[*idx
]->arg
);
95 vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
98 vty_out(vty
, "Specified VRF: %s does not exist\n",
104 static void pim_if_membership_clear(struct interface
*ifp
)
106 struct pim_interface
*pim_ifp
;
111 if (PIM_IF_TEST_PIM(pim_ifp
->options
)
112 && PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
116 pim_ifchannel_membership_clear(ifp
);
120 When PIM is disabled on interface, IGMPv3 local membership
121 information is not injected into PIM interface state.
123 The function pim_if_membership_refresh() fetches all IGMPv3 local
124 membership information into PIM. It is intented to be called
125 whenever PIM is enabled on the interface in order to collect missed
126 local membership information.
128 static void pim_if_membership_refresh(struct interface
*ifp
)
130 struct pim_interface
*pim_ifp
;
131 struct listnode
*sock_node
;
132 struct igmp_sock
*igmp
;
137 if (!PIM_IF_TEST_PIM(pim_ifp
->options
))
139 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
))
143 First clear off membership from all PIM (S,G) entries on the
147 pim_ifchannel_membership_clear(ifp
);
150 Then restore PIM (S,G) membership from all IGMPv3 (S,G) entries on
154 /* scan igmp sockets */
155 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
156 struct listnode
*grpnode
;
157 struct igmp_group
*grp
;
159 /* scan igmp groups */
160 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grpnode
,
162 struct listnode
*srcnode
;
163 struct igmp_source
*src
;
165 /* scan group sources */
166 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
,
169 if (IGMP_SOURCE_TEST_FORWARDING(
170 src
->source_flags
)) {
174 sizeof(struct prefix_sg
));
175 sg
.src
= src
->source_addr
;
176 sg
.grp
= grp
->group_addr
;
177 pim_ifchannel_local_membership_add(ifp
,
178 &sg
, false /*is_vxlan*/);
181 } /* scan group sources */
182 } /* scan igmp groups */
183 } /* scan igmp sockets */
186 Finally delete every PIM (S,G) entry lacking all state info
189 pim_ifchannel_delete_on_noinfo(ifp
);
192 static void pim_show_assert_helper(struct vty
*vty
,
193 struct pim_interface
*pim_ifp
,
194 struct pim_ifchannel
*ch
, time_t now
)
196 char ch_src_str
[INET_ADDRSTRLEN
];
197 char ch_grp_str
[INET_ADDRSTRLEN
];
198 char winner_str
[INET_ADDRSTRLEN
];
199 struct in_addr ifaddr
;
203 ifaddr
= pim_ifp
->primary_address
;
205 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
206 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
207 pim_inet4_dump("<assrt_win?>", ch
->ifassert_winner
, winner_str
,
210 pim_time_uptime(uptime
, sizeof(uptime
), now
- ch
->ifassert_creation
);
211 pim_time_timer_to_mmss(timer
, sizeof(timer
), ch
->t_ifassert_timer
);
213 vty_out(vty
, "%-16s %-15s %-15s %-15s %-6s %-15s %-8s %-5s\n",
214 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
, ch_grp_str
,
215 pim_ifchannel_ifassert_name(ch
->ifassert_state
), winner_str
,
219 static void pim_show_assert(struct pim_instance
*pim
, struct vty
*vty
)
221 struct pim_interface
*pim_ifp
;
222 struct pim_ifchannel
*ch
;
223 struct interface
*ifp
;
226 now
= pim_time_monotonic_sec();
229 "Interface Address Source Group State Winner Uptime Timer\n");
231 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
236 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
237 pim_show_assert_helper(vty
, pim_ifp
, ch
, now
);
238 } /* scan interface channels */
242 static void pim_show_assert_internal_helper(struct vty
*vty
,
243 struct pim_interface
*pim_ifp
,
244 struct pim_ifchannel
*ch
)
246 char ch_src_str
[INET_ADDRSTRLEN
];
247 char ch_grp_str
[INET_ADDRSTRLEN
];
248 struct in_addr ifaddr
;
250 ifaddr
= pim_ifp
->primary_address
;
252 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
253 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
254 vty_out(vty
, "%-16s %-15s %-15s %-15s %-3s %-3s %-3s %-4s\n",
255 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
, ch_grp_str
,
256 PIM_IF_FLAG_TEST_COULD_ASSERT(ch
->flags
) ? "yes" : "no",
257 pim_macro_ch_could_assert_eval(ch
) ? "yes" : "no",
258 PIM_IF_FLAG_TEST_ASSERT_TRACKING_DESIRED(ch
->flags
) ? "yes"
260 pim_macro_assert_tracking_desired_eval(ch
) ? "yes" : "no");
263 static void pim_show_assert_internal(struct pim_instance
*pim
, struct vty
*vty
)
265 struct pim_interface
*pim_ifp
;
266 struct pim_ifchannel
*ch
;
267 struct interface
*ifp
;
271 "ECA: Evaluate CouldAssert\n"
272 "ATD: AssertTrackingDesired\n"
273 "eATD: Evaluate AssertTrackingDesired\n\n");
276 "Interface Address Source Group CA eCA ATD eATD\n");
277 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
282 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
283 pim_show_assert_internal_helper(vty
, pim_ifp
, ch
);
284 } /* scan interface channels */
288 static void pim_show_assert_metric_helper(struct vty
*vty
,
289 struct pim_interface
*pim_ifp
,
290 struct pim_ifchannel
*ch
)
292 char ch_src_str
[INET_ADDRSTRLEN
];
293 char ch_grp_str
[INET_ADDRSTRLEN
];
294 char addr_str
[INET_ADDRSTRLEN
];
295 struct pim_assert_metric am
;
296 struct in_addr ifaddr
;
298 ifaddr
= pim_ifp
->primary_address
;
300 am
= pim_macro_spt_assert_metric(&ch
->upstream
->rpf
,
301 pim_ifp
->primary_address
);
303 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
304 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
305 pim_inet4_dump("<addr?>", am
.ip_address
, addr_str
, sizeof(addr_str
));
307 vty_out(vty
, "%-16s %-15s %-15s %-15s %-3s %4u %6u %-15s\n",
308 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
, ch_grp_str
,
309 am
.rpt_bit_flag
? "yes" : "no", am
.metric_preference
,
310 am
.route_metric
, addr_str
);
313 static void pim_show_assert_metric(struct pim_instance
*pim
, struct vty
*vty
)
315 struct pim_interface
*pim_ifp
;
316 struct pim_ifchannel
*ch
;
317 struct interface
*ifp
;
320 "Interface Address Source Group RPT Pref Metric Address \n");
322 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
327 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
328 pim_show_assert_metric_helper(vty
, pim_ifp
, ch
);
329 } /* scan interface channels */
333 static void pim_show_assert_winner_metric_helper(struct vty
*vty
,
334 struct pim_interface
*pim_ifp
,
335 struct pim_ifchannel
*ch
)
337 char ch_src_str
[INET_ADDRSTRLEN
];
338 char ch_grp_str
[INET_ADDRSTRLEN
];
339 char addr_str
[INET_ADDRSTRLEN
];
340 struct pim_assert_metric
*am
;
341 struct in_addr ifaddr
;
345 ifaddr
= pim_ifp
->primary_address
;
347 am
= &ch
->ifassert_winner_metric
;
349 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
350 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
351 pim_inet4_dump("<addr?>", am
->ip_address
, addr_str
, sizeof(addr_str
));
353 if (am
->metric_preference
== PIM_ASSERT_METRIC_PREFERENCE_MAX
)
354 snprintf(pref_str
, sizeof(pref_str
), "INFI");
356 snprintf(pref_str
, sizeof(pref_str
), "%4u",
357 am
->metric_preference
);
359 if (am
->route_metric
== PIM_ASSERT_ROUTE_METRIC_MAX
)
360 snprintf(metr_str
, sizeof(metr_str
), "INFI");
362 snprintf(metr_str
, sizeof(metr_str
), "%6u", am
->route_metric
);
364 vty_out(vty
, "%-16s %-15s %-15s %-15s %-3s %-4s %-6s %-15s\n",
365 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
, ch_grp_str
,
366 am
->rpt_bit_flag
? "yes" : "no", pref_str
, metr_str
, addr_str
);
369 static void pim_show_assert_winner_metric(struct pim_instance
*pim
,
372 struct pim_interface
*pim_ifp
;
373 struct pim_ifchannel
*ch
;
374 struct interface
*ifp
;
377 "Interface Address Source Group RPT Pref Metric Address \n");
379 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
384 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
385 pim_show_assert_winner_metric_helper(vty
, pim_ifp
, ch
);
386 } /* scan interface channels */
390 static void json_object_pim_ifp_add(struct json_object
*json
,
391 struct interface
*ifp
)
393 struct pim_interface
*pim_ifp
;
396 json_object_string_add(json
, "name", ifp
->name
);
397 json_object_string_add(json
, "state", if_is_up(ifp
) ? "up" : "down");
398 json_object_string_add(json
, "address",
399 inet_ntoa(pim_ifp
->primary_address
));
400 json_object_int_add(json
, "index", ifp
->ifindex
);
402 if (if_is_multicast(ifp
))
403 json_object_boolean_true_add(json
, "flagMulticast");
405 if (if_is_broadcast(ifp
))
406 json_object_boolean_true_add(json
, "flagBroadcast");
408 if (ifp
->flags
& IFF_ALLMULTI
)
409 json_object_boolean_true_add(json
, "flagAllMulticast");
411 if (ifp
->flags
& IFF_PROMISC
)
412 json_object_boolean_true_add(json
, "flagPromiscuous");
414 if (PIM_IF_IS_DELETED(ifp
))
415 json_object_boolean_true_add(json
, "flagDeleted");
417 if (pim_if_lan_delay_enabled(ifp
))
418 json_object_boolean_true_add(json
, "lanDelayEnabled");
421 static void pim_show_membership_helper(struct vty
*vty
,
422 struct pim_interface
*pim_ifp
,
423 struct pim_ifchannel
*ch
,
424 struct json_object
*json
)
426 char ch_src_str
[INET_ADDRSTRLEN
];
427 char ch_grp_str
[INET_ADDRSTRLEN
];
428 json_object
*json_iface
= NULL
;
429 json_object
*json_row
= NULL
;
431 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
432 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
434 json_object_object_get_ex(json
, ch
->interface
->name
, &json_iface
);
436 json_iface
= json_object_new_object();
437 json_object_pim_ifp_add(json_iface
, ch
->interface
);
438 json_object_object_add(json
, ch
->interface
->name
, json_iface
);
441 json_row
= json_object_new_object();
442 json_object_string_add(json_row
, "source", ch_src_str
);
443 json_object_string_add(json_row
, "group", ch_grp_str
);
444 json_object_string_add(json_row
, "localMembership",
445 ch
->local_ifmembership
== PIM_IFMEMBERSHIP_NOINFO
448 json_object_object_add(json_iface
, ch_grp_str
, json_row
);
450 static void pim_show_membership(struct pim_instance
*pim
, struct vty
*vty
,
453 struct pim_interface
*pim_ifp
;
454 struct pim_ifchannel
*ch
;
455 struct interface
*ifp
;
457 json_object
*json
= NULL
;
458 json_object
*json_tmp
= NULL
;
460 json
= json_object_new_object();
462 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
467 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
468 pim_show_membership_helper(vty
, pim_ifp
, ch
, json
);
469 } /* scan interface channels */
473 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
474 json
, JSON_C_TO_STRING_PRETTY
));
477 "Interface Address Source Group Membership\n");
480 * Example of the json data we are traversing
486 * "address":"10.1.20.1",
488 * "flagMulticast":true,
489 * "flagBroadcast":true,
490 * "lanDelayEnabled":true,
493 * "group":"226.10.10.10",
494 * "localMembership":"INCLUDE"
500 /* foreach interface */
501 json_object_object_foreach(json
, key
, val
)
504 /* Find all of the keys where the val is an object. In
506 * above the only one is 226.10.10.10
508 json_object_object_foreach(val
, if_field_key
,
511 type
= json_object_get_type(if_field_val
);
513 if (type
== json_type_object
) {
514 vty_out(vty
, "%-16s ", key
);
516 json_object_object_get_ex(
517 val
, "address", &json_tmp
);
518 vty_out(vty
, "%-15s ",
519 json_object_get_string(
522 json_object_object_get_ex(if_field_val
,
525 vty_out(vty
, "%-15s ",
526 json_object_get_string(
530 vty_out(vty
, "%-15s ", if_field_key
);
532 json_object_object_get_ex(
533 if_field_val
, "localMembership",
535 vty_out(vty
, "%-10s\n",
536 json_object_get_string(
543 json_object_free(json
);
546 static void pim_print_ifp_flags(struct vty
*vty
, struct interface
*ifp
,
549 vty_out(vty
, "Flags\n");
550 vty_out(vty
, "-----\n");
551 vty_out(vty
, "All Multicast : %s\n",
552 (ifp
->flags
& IFF_ALLMULTI
) ? "yes" : "no");
553 vty_out(vty
, "Broadcast : %s\n",
554 if_is_broadcast(ifp
) ? "yes" : "no");
555 vty_out(vty
, "Deleted : %s\n",
556 PIM_IF_IS_DELETED(ifp
) ? "yes" : "no");
557 vty_out(vty
, "Interface Index : %d\n", ifp
->ifindex
);
558 vty_out(vty
, "Multicast : %s\n",
559 if_is_multicast(ifp
) ? "yes" : "no");
560 vty_out(vty
, "Multicast Loop : %d\n", mloop
);
561 vty_out(vty
, "Promiscuous : %s\n",
562 (ifp
->flags
& IFF_PROMISC
) ? "yes" : "no");
567 static void igmp_show_interfaces(struct pim_instance
*pim
, struct vty
*vty
,
570 struct interface
*ifp
;
572 json_object
*json
= NULL
;
573 json_object
*json_row
= NULL
;
575 now
= pim_time_monotonic_sec();
578 json
= json_object_new_object();
581 "Interface State Address V Querier Query Timer Uptime\n");
583 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
584 struct pim_interface
*pim_ifp
;
585 struct listnode
*sock_node
;
586 struct igmp_sock
*igmp
;
593 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
596 char query_hhmmss
[10];
598 pim_time_uptime(uptime
, sizeof(uptime
),
599 now
- igmp
->sock_creation
);
600 pim_time_timer_to_hhmmss(query_hhmmss
,
601 sizeof(query_hhmmss
),
602 igmp
->t_igmp_query_timer
);
605 json_row
= json_object_new_object();
606 json_object_pim_ifp_add(json_row
, ifp
);
607 json_object_string_add(json_row
, "upTime",
609 json_object_int_add(json_row
, "version",
610 pim_ifp
->igmp_version
);
612 if (igmp
->t_igmp_query_timer
) {
613 json_object_boolean_true_add(json_row
,
615 json_object_string_add(json_row
,
620 json_object_object_add(json
, ifp
->name
,
623 if (igmp
->mtrace_only
) {
624 json_object_boolean_true_add(
625 json_row
, "mtraceOnly");
629 "%-16s %5s %15s %d %7s %11s %8s\n",
632 ? (igmp
->mtrace_only
? "mtrc"
635 inet_ntoa(igmp
->ifaddr
),
636 pim_ifp
->igmp_version
,
637 igmp
->t_igmp_query_timer
? "local"
639 query_hhmmss
, uptime
);
645 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
646 json
, JSON_C_TO_STRING_PRETTY
));
647 json_object_free(json
);
651 static void igmp_show_interfaces_single(struct pim_instance
*pim
,
652 struct vty
*vty
, const char *ifname
,
655 struct igmp_sock
*igmp
;
656 struct interface
*ifp
;
657 struct listnode
*sock_node
;
658 struct pim_interface
*pim_ifp
;
660 char query_hhmmss
[10];
661 char other_hhmmss
[10];
662 int found_ifname
= 0;
665 long gmi_msec
; /* Group Membership Interval */
668 long oqpi_msec
; /* Other Querier Present Interval */
673 json_object
*json
= NULL
;
674 json_object
*json_row
= NULL
;
677 json
= json_object_new_object();
679 now
= pim_time_monotonic_sec();
681 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
687 if (strcmp(ifname
, "detail") && strcmp(ifname
, ifp
->name
))
690 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
693 pim_time_uptime(uptime
, sizeof(uptime
),
694 now
- igmp
->sock_creation
);
695 pim_time_timer_to_hhmmss(query_hhmmss
,
696 sizeof(query_hhmmss
),
697 igmp
->t_igmp_query_timer
);
698 pim_time_timer_to_hhmmss(other_hhmmss
,
699 sizeof(other_hhmmss
),
700 igmp
->t_other_querier_timer
);
702 gmi_msec
= PIM_IGMP_GMI_MSEC(
703 igmp
->querier_robustness_variable
,
704 igmp
->querier_query_interval
,
705 pim_ifp
->igmp_query_max_response_time_dsec
);
708 pim_ifp
->igmp_default_query_interval
);
710 oqpi_msec
= PIM_IGMP_OQPI_MSEC(
711 igmp
->querier_robustness_variable
,
712 igmp
->querier_query_interval
,
713 pim_ifp
->igmp_query_max_response_time_dsec
);
715 lmqt_msec
= PIM_IGMP_LMQT_MSEC(
716 pim_ifp
->igmp_specific_query_max_response_time_dsec
,
717 pim_ifp
->igmp_last_member_query_count
);
721 igmp
->querier_robustness_variable
,
722 igmp
->querier_query_interval
,
723 pim_ifp
->igmp_query_max_response_time_dsec
)
726 qri_msec
= pim_ifp
->igmp_query_max_response_time_dsec
728 if (pim_ifp
->pim_sock_fd
>= 0)
729 mloop
= pim_socket_mcastloop_get(
730 pim_ifp
->pim_sock_fd
);
733 lmqc
= pim_ifp
->igmp_last_member_query_count
;
736 json_row
= json_object_new_object();
737 json_object_pim_ifp_add(json_row
, ifp
);
738 json_object_string_add(json_row
, "upTime",
740 json_object_string_add(json_row
, "querier",
741 igmp
->t_igmp_query_timer
744 json_object_int_add(json_row
, "queryStartCount",
745 igmp
->startup_query_count
);
746 json_object_string_add(json_row
,
749 json_object_string_add(json_row
,
752 json_object_int_add(json_row
, "version",
753 pim_ifp
->igmp_version
);
756 "timerGroupMembershipIntervalMsec",
758 json_object_int_add(json_row
,
759 "lastMemberQueryCount",
761 json_object_int_add(json_row
,
762 "timerLastMemberQueryMsec",
766 "timerOlderHostPresentIntervalMsec",
770 "timerOtherQuerierPresentIntervalMsec",
773 json_row
, "timerQueryInterval",
774 igmp
->querier_query_interval
);
777 "timerQueryResponseIntervalMsec",
780 json_row
, "timerRobustnessVariable",
781 igmp
->querier_robustness_variable
);
782 json_object_int_add(json_row
,
783 "timerStartupQueryInterval",
786 json_object_object_add(json
, ifp
->name
,
789 if (igmp
->mtrace_only
) {
790 json_object_boolean_true_add(
791 json_row
, "mtraceOnly");
794 vty_out(vty
, "Interface : %s\n", ifp
->name
);
795 vty_out(vty
, "State : %s\n",
797 ? (igmp
->mtrace_only
? "mtrace"
800 vty_out(vty
, "Address : %s\n",
801 inet_ntoa(pim_ifp
->primary_address
));
802 vty_out(vty
, "Uptime : %s\n", uptime
);
803 vty_out(vty
, "Version : %d\n",
804 pim_ifp
->igmp_version
);
808 vty_out(vty
, "Querier\n");
809 vty_out(vty
, "-------\n");
810 vty_out(vty
, "Querier : %s\n",
811 igmp
->t_igmp_query_timer
? "local"
813 vty_out(vty
, "Start Count : %d\n",
814 igmp
->startup_query_count
);
815 vty_out(vty
, "Query Timer : %s\n",
817 vty_out(vty
, "Other Timer : %s\n",
822 vty_out(vty
, "Timers\n");
823 vty_out(vty
, "------\n");
825 "Group Membership Interval : %lis\n",
828 "Last Member Query Count : %d\n",
831 "Last Member Query Time : %lis\n",
834 "Older Host Present Interval : %lis\n",
837 "Other Querier Present Interval : %lis\n",
840 "Query Interval : %ds\n",
841 igmp
->querier_query_interval
);
843 "Query Response Interval : %lis\n",
846 "Robustness Variable : %d\n",
847 igmp
->querier_robustness_variable
);
849 "Startup Query Interval : %ds\n",
854 pim_print_ifp_flags(vty
, ifp
, mloop
);
860 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
861 json
, JSON_C_TO_STRING_PRETTY
));
862 json_object_free(json
);
865 vty_out(vty
, "%% No such interface\n");
869 static void igmp_show_interface_join(struct pim_instance
*pim
, struct vty
*vty
)
871 struct interface
*ifp
;
874 now
= pim_time_monotonic_sec();
877 "Interface Address Source Group Socket Uptime \n");
879 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
880 struct pim_interface
*pim_ifp
;
881 struct listnode
*join_node
;
882 struct igmp_join
*ij
;
883 struct in_addr pri_addr
;
884 char pri_addr_str
[INET_ADDRSTRLEN
];
891 if (!pim_ifp
->igmp_join_list
)
894 pri_addr
= pim_find_primary_addr(ifp
);
895 pim_inet4_dump("<pri?>", pri_addr
, pri_addr_str
,
896 sizeof(pri_addr_str
));
898 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_join_list
, join_node
,
900 char group_str
[INET_ADDRSTRLEN
];
901 char source_str
[INET_ADDRSTRLEN
];
904 pim_time_uptime(uptime
, sizeof(uptime
),
905 now
- ij
->sock_creation
);
906 pim_inet4_dump("<grp?>", ij
->group_addr
, group_str
,
908 pim_inet4_dump("<src?>", ij
->source_addr
, source_str
,
911 vty_out(vty
, "%-16s %-15s %-15s %-15s %6d %8s\n",
912 ifp
->name
, pri_addr_str
, source_str
, group_str
,
913 ij
->sock_fd
, uptime
);
914 } /* for (pim_ifp->igmp_join_list) */
919 static void pim_show_interfaces_single(struct pim_instance
*pim
,
920 struct vty
*vty
, const char *ifname
,
923 struct in_addr ifaddr
;
924 struct interface
*ifp
;
925 struct listnode
*neighnode
;
926 struct pim_interface
*pim_ifp
;
927 struct pim_neighbor
*neigh
;
928 struct pim_upstream
*up
;
930 char dr_str
[INET_ADDRSTRLEN
];
933 char grp_str
[INET_ADDRSTRLEN
];
934 char hello_period
[10];
935 char hello_timer
[10];
936 char neigh_src_str
[INET_ADDRSTRLEN
];
937 char src_str
[INET_ADDRSTRLEN
];
938 char stat_uptime
[10];
941 int found_ifname
= 0;
943 json_object
*json
= NULL
;
944 json_object
*json_row
= NULL
;
945 json_object
*json_pim_neighbor
= NULL
;
946 json_object
*json_pim_neighbors
= NULL
;
947 json_object
*json_group
= NULL
;
948 json_object
*json_group_source
= NULL
;
949 json_object
*json_fhr_sources
= NULL
;
950 struct pim_secondary_addr
*sec_addr
;
951 struct listnode
*sec_node
;
953 now
= pim_time_monotonic_sec();
956 json
= json_object_new_object();
958 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
964 if (mlag
== true && pim_ifp
->activeactive
== false)
967 if (strcmp(ifname
, "detail") && strcmp(ifname
, ifp
->name
))
971 ifaddr
= pim_ifp
->primary_address
;
972 pim_inet4_dump("<dr?>", pim_ifp
->pim_dr_addr
, dr_str
,
974 pim_time_uptime_begin(dr_uptime
, sizeof(dr_uptime
), now
,
975 pim_ifp
->pim_dr_election_last
);
976 pim_time_timer_to_hhmmss(hello_timer
, sizeof(hello_timer
),
977 pim_ifp
->t_pim_hello_timer
);
978 pim_time_mmss(hello_period
, sizeof(hello_period
),
979 pim_ifp
->pim_hello_period
);
980 pim_time_uptime(stat_uptime
, sizeof(stat_uptime
),
981 now
- pim_ifp
->pim_ifstat_start
);
982 if (pim_ifp
->pim_sock_fd
>= 0)
983 mloop
= pim_socket_mcastloop_get(pim_ifp
->pim_sock_fd
);
988 char pbuf
[PREFIX2STR_BUFFER
];
989 json_row
= json_object_new_object();
990 json_object_pim_ifp_add(json_row
, ifp
);
992 if (pim_ifp
->update_source
.s_addr
!= INADDR_ANY
) {
993 json_object_string_add(
994 json_row
, "useSource",
995 inet_ntoa(pim_ifp
->update_source
));
997 if (pim_ifp
->sec_addr_list
) {
998 json_object
*sec_list
= NULL
;
1000 sec_list
= json_object_new_array();
1001 for (ALL_LIST_ELEMENTS_RO(
1002 pim_ifp
->sec_addr_list
, sec_node
,
1004 json_object_array_add(
1006 json_object_new_string(
1012 json_object_object_add(json_row
,
1013 "secondaryAddressList",
1018 if (pim_ifp
->pim_neighbor_list
->count
) {
1019 json_pim_neighbors
= json_object_new_object();
1021 for (ALL_LIST_ELEMENTS_RO(
1022 pim_ifp
->pim_neighbor_list
,
1023 neighnode
, neigh
)) {
1025 json_object_new_object();
1026 pim_inet4_dump("<src?>",
1029 sizeof(neigh_src_str
));
1030 pim_time_uptime(uptime
, sizeof(uptime
),
1031 now
- neigh
->creation
);
1032 pim_time_timer_to_hhmmss(
1033 expire
, sizeof(expire
),
1034 neigh
->t_expire_timer
);
1036 json_object_string_add(
1037 json_pim_neighbor
, "address",
1039 json_object_string_add(
1040 json_pim_neighbor
, "upTime",
1042 json_object_string_add(
1043 json_pim_neighbor
, "holdtime",
1046 json_object_object_add(
1052 json_object_object_add(json_row
, "neighbors",
1053 json_pim_neighbors
);
1056 json_object_string_add(json_row
, "drAddress", dr_str
);
1057 json_object_int_add(json_row
, "drPriority",
1058 pim_ifp
->pim_dr_priority
);
1059 json_object_string_add(json_row
, "drUptime", dr_uptime
);
1060 json_object_int_add(json_row
, "drElections",
1061 pim_ifp
->pim_dr_election_count
);
1062 json_object_int_add(json_row
, "drChanges",
1063 pim_ifp
->pim_dr_election_changes
);
1066 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
1067 if (ifp
!= up
->rpf
.source_nexthop
.interface
)
1070 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
))
1073 if (!json_fhr_sources
)
1075 json_object_new_object();
1077 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
,
1079 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
,
1081 pim_time_uptime(uptime
, sizeof(uptime
),
1082 now
- up
->state_transition
);
1085 * Does this group live in json_fhr_sources?
1088 json_object_object_get_ex(json_fhr_sources
,
1089 grp_str
, &json_group
);
1092 json_group
= json_object_new_object();
1093 json_object_object_add(json_fhr_sources
,
1098 json_group_source
= json_object_new_object();
1099 json_object_string_add(json_group_source
,
1101 json_object_string_add(json_group_source
,
1103 json_object_string_add(json_group_source
,
1105 json_object_object_add(json_group
, src_str
,
1109 if (json_fhr_sources
) {
1110 json_object_object_add(json_row
,
1115 json_object_int_add(json_row
, "helloPeriod",
1116 pim_ifp
->pim_hello_period
);
1117 json_object_string_add(json_row
, "helloTimer",
1119 json_object_string_add(json_row
, "helloStatStart",
1121 json_object_int_add(json_row
, "helloReceived",
1122 pim_ifp
->pim_ifstat_hello_recv
);
1123 json_object_int_add(json_row
, "helloReceivedFailed",
1124 pim_ifp
->pim_ifstat_hello_recvfail
);
1125 json_object_int_add(json_row
, "helloSend",
1126 pim_ifp
->pim_ifstat_hello_sent
);
1127 json_object_int_add(json_row
, "hellosendFailed",
1128 pim_ifp
->pim_ifstat_hello_sendfail
);
1129 json_object_int_add(json_row
, "helloGenerationId",
1130 pim_ifp
->pim_generation_id
);
1131 json_object_int_add(json_row
, "flagMulticastLoop",
1134 json_object_int_add(
1135 json_row
, "effectivePropagationDelay",
1136 pim_if_effective_propagation_delay_msec(ifp
));
1137 json_object_int_add(
1138 json_row
, "effectiveOverrideInterval",
1139 pim_if_effective_override_interval_msec(ifp
));
1140 json_object_int_add(
1141 json_row
, "joinPruneOverrideInterval",
1142 pim_if_jp_override_interval_msec(ifp
));
1144 json_object_int_add(
1145 json_row
, "propagationDelay",
1146 pim_ifp
->pim_propagation_delay_msec
);
1147 json_object_int_add(
1148 json_row
, "propagationDelayHighest",
1149 pim_ifp
->pim_neighbors_highest_propagation_delay_msec
);
1150 json_object_int_add(
1151 json_row
, "overrideInterval",
1152 pim_ifp
->pim_override_interval_msec
);
1153 json_object_int_add(
1154 json_row
, "overrideIntervalHighest",
1155 pim_ifp
->pim_neighbors_highest_override_interval_msec
);
1156 json_object_object_add(json
, ifp
->name
, json_row
);
1159 vty_out(vty
, "Interface : %s\n", ifp
->name
);
1160 vty_out(vty
, "State : %s\n",
1161 if_is_up(ifp
) ? "up" : "down");
1162 if (pim_ifp
->update_source
.s_addr
!= INADDR_ANY
) {
1163 vty_out(vty
, "Use Source : %s\n",
1164 inet_ntoa(pim_ifp
->update_source
));
1166 if (pim_ifp
->sec_addr_list
) {
1167 char pbuf
[PREFIX2STR_BUFFER
];
1168 vty_out(vty
, "Address : %s (primary)\n",
1170 for (ALL_LIST_ELEMENTS_RO(
1171 pim_ifp
->sec_addr_list
, sec_node
,
1173 vty_out(vty
, " %s\n",
1174 prefix2str(&sec_addr
->addr
,
1175 pbuf
, sizeof(pbuf
)));
1178 vty_out(vty
, "Address : %s\n",
1186 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
,
1187 neighnode
, neigh
)) {
1190 vty_out(vty
, "PIM Neighbors\n");
1191 vty_out(vty
, "-------------\n");
1195 pim_inet4_dump("<src?>", neigh
->source_addr
,
1197 sizeof(neigh_src_str
));
1198 pim_time_uptime(uptime
, sizeof(uptime
),
1199 now
- neigh
->creation
);
1200 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
1201 neigh
->t_expire_timer
);
1203 "%-15s : up for %s, holdtime expires in %s\n",
1204 neigh_src_str
, uptime
, expire
);
1207 if (!print_header
) {
1212 vty_out(vty
, "Designated Router\n");
1213 vty_out(vty
, "-----------------\n");
1214 vty_out(vty
, "Address : %s\n", dr_str
);
1215 vty_out(vty
, "Priority : %u(%d)\n",
1216 pim_ifp
->pim_dr_priority
,
1217 pim_ifp
->pim_dr_num_nondrpri_neighbors
);
1218 vty_out(vty
, "Uptime : %s\n", dr_uptime
);
1219 vty_out(vty
, "Elections : %d\n",
1220 pim_ifp
->pim_dr_election_count
);
1221 vty_out(vty
, "Changes : %d\n",
1222 pim_ifp
->pim_dr_election_changes
);
1228 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
1229 if (!up
->rpf
.source_nexthop
.interface
)
1232 if (strcmp(ifp
->name
,
1233 up
->rpf
.source_nexthop
1238 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
))
1243 "FHR - First Hop Router\n");
1245 "----------------------\n");
1249 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
,
1251 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
,
1253 pim_time_uptime(uptime
, sizeof(uptime
),
1254 now
- up
->state_transition
);
1256 "%s : %s is a source, uptime is %s\n",
1257 grp_str
, src_str
, uptime
);
1260 if (!print_header
) {
1265 vty_out(vty
, "Hellos\n");
1266 vty_out(vty
, "------\n");
1267 vty_out(vty
, "Period : %d\n",
1268 pim_ifp
->pim_hello_period
);
1269 vty_out(vty
, "Timer : %s\n", hello_timer
);
1270 vty_out(vty
, "StatStart : %s\n", stat_uptime
);
1271 vty_out(vty
, "Receive : %d\n",
1272 pim_ifp
->pim_ifstat_hello_recv
);
1273 vty_out(vty
, "Receive Failed : %d\n",
1274 pim_ifp
->pim_ifstat_hello_recvfail
);
1275 vty_out(vty
, "Send : %d\n",
1276 pim_ifp
->pim_ifstat_hello_sent
);
1277 vty_out(vty
, "Send Failed : %d\n",
1278 pim_ifp
->pim_ifstat_hello_sendfail
);
1279 vty_out(vty
, "Generation ID : %08x\n",
1280 pim_ifp
->pim_generation_id
);
1284 pim_print_ifp_flags(vty
, ifp
, mloop
);
1286 vty_out(vty
, "Join Prune Interval\n");
1287 vty_out(vty
, "-------------------\n");
1288 vty_out(vty
, "LAN Delay : %s\n",
1289 pim_if_lan_delay_enabled(ifp
) ? "yes" : "no");
1290 vty_out(vty
, "Effective Propagation Delay : %d msec\n",
1291 pim_if_effective_propagation_delay_msec(ifp
));
1292 vty_out(vty
, "Effective Override Interval : %d msec\n",
1293 pim_if_effective_override_interval_msec(ifp
));
1294 vty_out(vty
, "Join Prune Override Interval : %d msec\n",
1295 pim_if_jp_override_interval_msec(ifp
));
1299 vty_out(vty
, "LAN Prune Delay\n");
1300 vty_out(vty
, "---------------\n");
1301 vty_out(vty
, "Propagation Delay : %d msec\n",
1302 pim_ifp
->pim_propagation_delay_msec
);
1303 vty_out(vty
, "Propagation Delay (Highest) : %d msec\n",
1304 pim_ifp
->pim_neighbors_highest_propagation_delay_msec
);
1305 vty_out(vty
, "Override Interval : %d msec\n",
1306 pim_ifp
->pim_override_interval_msec
);
1307 vty_out(vty
, "Override Interval (Highest) : %d msec\n",
1308 pim_ifp
->pim_neighbors_highest_override_interval_msec
);
1315 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1316 json
, JSON_C_TO_STRING_PRETTY
));
1317 json_object_free(json
);
1320 vty_out(vty
, "%% No such interface\n");
1324 static void igmp_show_statistics(struct pim_instance
*pim
, struct vty
*vty
,
1325 const char *ifname
, bool uj
)
1327 struct interface
*ifp
;
1328 struct igmp_stats rx_stats
;
1330 igmp_stats_init(&rx_stats
);
1332 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1333 struct pim_interface
*pim_ifp
;
1334 struct listnode
*sock_node
;
1335 struct igmp_sock
*igmp
;
1337 pim_ifp
= ifp
->info
;
1342 if (ifname
&& strcmp(ifname
, ifp
->name
))
1345 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
1347 igmp_stats_add(&rx_stats
, &igmp
->rx_stats
);
1351 json_object
*json
= NULL
;
1352 json_object
*json_row
= NULL
;
1354 json
= json_object_new_object();
1355 json_row
= json_object_new_object();
1357 json_object_string_add(json_row
, "name", ifname
? ifname
:
1359 json_object_int_add(json_row
, "queryV1", rx_stats
.query_v1
);
1360 json_object_int_add(json_row
, "queryV2", rx_stats
.query_v2
);
1361 json_object_int_add(json_row
, "queryV3", rx_stats
.query_v3
);
1362 json_object_int_add(json_row
, "leaveV3", rx_stats
.leave_v2
);
1363 json_object_int_add(json_row
, "reportV1", rx_stats
.report_v1
);
1364 json_object_int_add(json_row
, "reportV2", rx_stats
.report_v2
);
1365 json_object_int_add(json_row
, "reportV3", rx_stats
.report_v3
);
1366 json_object_int_add(json_row
, "mtraceResponse",
1367 rx_stats
.mtrace_rsp
);
1368 json_object_int_add(json_row
, "mtraceRequest",
1369 rx_stats
.mtrace_req
);
1370 json_object_int_add(json_row
, "unsupported",
1371 rx_stats
.unsupported
);
1372 json_object_object_add(json
, ifname
? ifname
: "global",
1374 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1375 json
, JSON_C_TO_STRING_PRETTY
));
1376 json_object_free(json
);
1378 vty_out(vty
, "IGMP RX statistics\n");
1379 vty_out(vty
, "Interface : %s\n",
1380 ifname
? ifname
: "global");
1381 vty_out(vty
, "V1 query : %u\n", rx_stats
.query_v1
);
1382 vty_out(vty
, "V2 query : %u\n", rx_stats
.query_v2
);
1383 vty_out(vty
, "V3 query : %u\n", rx_stats
.query_v3
);
1384 vty_out(vty
, "V2 leave : %u\n", rx_stats
.leave_v2
);
1385 vty_out(vty
, "V1 report : %u\n", rx_stats
.report_v1
);
1386 vty_out(vty
, "V2 report : %u\n", rx_stats
.report_v2
);
1387 vty_out(vty
, "V3 report : %u\n", rx_stats
.report_v3
);
1388 vty_out(vty
, "mtrace response : %u\n", rx_stats
.mtrace_rsp
);
1389 vty_out(vty
, "mtrace request : %u\n", rx_stats
.mtrace_req
);
1390 vty_out(vty
, "unsupported : %u\n", rx_stats
.unsupported
);
1394 static void pim_show_interfaces(struct pim_instance
*pim
, struct vty
*vty
,
1397 struct interface
*ifp
;
1398 struct pim_interface
*pim_ifp
;
1399 struct pim_upstream
*up
;
1402 int pim_ifchannels
= 0;
1403 json_object
*json
= NULL
;
1404 json_object
*json_row
= NULL
;
1405 json_object
*json_tmp
;
1407 json
= json_object_new_object();
1409 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1410 pim_ifp
= ifp
->info
;
1415 if (mlag
== true && pim_ifp
->activeactive
== false)
1418 pim_nbrs
= pim_ifp
->pim_neighbor_list
->count
;
1419 pim_ifchannels
= pim_if_ifchannel_count(pim_ifp
);
1422 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
)
1423 if (ifp
== up
->rpf
.source_nexthop
.interface
)
1424 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
1427 json_row
= json_object_new_object();
1428 json_object_pim_ifp_add(json_row
, ifp
);
1429 json_object_int_add(json_row
, "pimNeighbors", pim_nbrs
);
1430 json_object_int_add(json_row
, "pimIfChannels", pim_ifchannels
);
1431 json_object_int_add(json_row
, "firstHopRouterCount", fhr
);
1432 json_object_string_add(json_row
, "pimDesignatedRouter",
1433 inet_ntoa(pim_ifp
->pim_dr_addr
));
1435 if (pim_ifp
->pim_dr_addr
.s_addr
1436 == pim_ifp
->primary_address
.s_addr
)
1437 json_object_boolean_true_add(
1438 json_row
, "pimDesignatedRouterLocal");
1440 json_object_object_add(json
, ifp
->name
, json_row
);
1444 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1445 json
, JSON_C_TO_STRING_PRETTY
));
1448 "Interface State Address PIM Nbrs PIM DR FHR IfChannels\n");
1450 json_object_object_foreach(json
, key
, val
)
1452 vty_out(vty
, "%-16s ", key
);
1454 json_object_object_get_ex(val
, "state", &json_tmp
);
1455 vty_out(vty
, "%5s ", json_object_get_string(json_tmp
));
1457 json_object_object_get_ex(val
, "address", &json_tmp
);
1458 vty_out(vty
, "%15s ",
1459 json_object_get_string(json_tmp
));
1461 json_object_object_get_ex(val
, "pimNeighbors",
1463 vty_out(vty
, "%8d ", json_object_get_int(json_tmp
));
1465 if (json_object_object_get_ex(
1466 val
, "pimDesignatedRouterLocal",
1468 vty_out(vty
, "%15s ", "local");
1470 json_object_object_get_ex(
1471 val
, "pimDesignatedRouter", &json_tmp
);
1472 vty_out(vty
, "%15s ",
1473 json_object_get_string(json_tmp
));
1476 json_object_object_get_ex(val
, "firstHopRouter",
1478 vty_out(vty
, "%3d ", json_object_get_int(json_tmp
));
1480 json_object_object_get_ex(val
, "pimIfChannels",
1482 vty_out(vty
, "%9d\n", json_object_get_int(json_tmp
));
1486 json_object_free(json
);
1489 static void pim_show_interface_traffic(struct pim_instance
*pim
,
1490 struct vty
*vty
, bool uj
)
1492 struct interface
*ifp
= NULL
;
1493 struct pim_interface
*pim_ifp
= NULL
;
1494 json_object
*json
= NULL
;
1495 json_object
*json_row
= NULL
;
1498 json
= json_object_new_object();
1501 vty_out(vty
, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s%-17s\n",
1502 "Interface", " HELLO", " JOIN",
1503 " PRUNE", " REGISTER", "REGISTER-STOP",
1505 vty_out(vty
, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s%-17s\n", "",
1506 " Rx/Tx", " Rx/Tx", " Rx/Tx",
1507 " Rx/Tx", " Rx/Tx", " Rx/Tx",
1510 "---------------------------------------------------------------------------------------------------------------\n");
1513 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1514 pim_ifp
= ifp
->info
;
1519 if (pim_ifp
->pim_sock_fd
< 0)
1522 json_row
= json_object_new_object();
1523 json_object_pim_ifp_add(json_row
, ifp
);
1524 json_object_int_add(json_row
, "helloRx",
1525 pim_ifp
->pim_ifstat_hello_recv
);
1526 json_object_int_add(json_row
, "helloTx",
1527 pim_ifp
->pim_ifstat_hello_sent
);
1528 json_object_int_add(json_row
, "joinRx",
1529 pim_ifp
->pim_ifstat_join_recv
);
1530 json_object_int_add(json_row
, "joinTx",
1531 pim_ifp
->pim_ifstat_join_send
);
1532 json_object_int_add(json_row
, "pruneTx",
1533 pim_ifp
->pim_ifstat_prune_send
);
1534 json_object_int_add(json_row
, "pruneRx",
1535 pim_ifp
->pim_ifstat_prune_recv
);
1536 json_object_int_add(json_row
, "registerRx",
1537 pim_ifp
->pim_ifstat_reg_recv
);
1538 json_object_int_add(json_row
, "registerTx",
1539 pim_ifp
->pim_ifstat_reg_recv
);
1540 json_object_int_add(json_row
, "registerStopRx",
1541 pim_ifp
->pim_ifstat_reg_stop_recv
);
1542 json_object_int_add(json_row
, "registerStopTx",
1543 pim_ifp
->pim_ifstat_reg_stop_send
);
1544 json_object_int_add(json_row
, "assertRx",
1545 pim_ifp
->pim_ifstat_assert_recv
);
1546 json_object_int_add(json_row
, "assertTx",
1547 pim_ifp
->pim_ifstat_assert_send
);
1548 json_object_int_add(json_row
, "bsmRx",
1549 pim_ifp
->pim_ifstat_bsm_rx
);
1550 json_object_int_add(json_row
, "bsmTx",
1551 pim_ifp
->pim_ifstat_bsm_tx
);
1552 json_object_object_add(json
, ifp
->name
, json_row
);
1555 "%-16s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7" PRIu64
"/%-7" PRIu64
"\n",
1556 ifp
->name
, pim_ifp
->pim_ifstat_hello_recv
,
1557 pim_ifp
->pim_ifstat_hello_sent
,
1558 pim_ifp
->pim_ifstat_join_recv
,
1559 pim_ifp
->pim_ifstat_join_send
,
1560 pim_ifp
->pim_ifstat_prune_recv
,
1561 pim_ifp
->pim_ifstat_prune_send
,
1562 pim_ifp
->pim_ifstat_reg_recv
,
1563 pim_ifp
->pim_ifstat_reg_send
,
1564 pim_ifp
->pim_ifstat_reg_stop_recv
,
1565 pim_ifp
->pim_ifstat_reg_stop_send
,
1566 pim_ifp
->pim_ifstat_assert_recv
,
1567 pim_ifp
->pim_ifstat_assert_send
,
1568 pim_ifp
->pim_ifstat_bsm_rx
,
1569 pim_ifp
->pim_ifstat_bsm_tx
);
1573 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1574 json
, JSON_C_TO_STRING_PRETTY
));
1575 json_object_free(json
);
1579 static void pim_show_interface_traffic_single(struct pim_instance
*pim
,
1581 const char *ifname
, bool uj
)
1583 struct interface
*ifp
= NULL
;
1584 struct pim_interface
*pim_ifp
= NULL
;
1585 json_object
*json
= NULL
;
1586 json_object
*json_row
= NULL
;
1587 uint8_t found_ifname
= 0;
1590 json
= json_object_new_object();
1593 vty_out(vty
, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s%-17s\n",
1594 "Interface", " HELLO", " JOIN", " PRUNE",
1595 " REGISTER", " REGISTER-STOP", " ASSERT",
1597 vty_out(vty
, "%-14s%-18s%-17s%-17s%-17s%-17s%-17s%-17s\n", "",
1598 " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1599 " Rx/Tx", " Rx/Tx", " Rx/Tx");
1601 "-------------------------------------------------------------------------------------------------------------------------------\n");
1604 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1605 if (strcmp(ifname
, ifp
->name
))
1608 pim_ifp
= ifp
->info
;
1613 if (pim_ifp
->pim_sock_fd
< 0)
1618 json_row
= json_object_new_object();
1619 json_object_pim_ifp_add(json_row
, ifp
);
1620 json_object_int_add(json_row
, "helloRx",
1621 pim_ifp
->pim_ifstat_hello_recv
);
1622 json_object_int_add(json_row
, "helloTx",
1623 pim_ifp
->pim_ifstat_hello_sent
);
1624 json_object_int_add(json_row
, "joinRx",
1625 pim_ifp
->pim_ifstat_join_recv
);
1626 json_object_int_add(json_row
, "joinTx",
1627 pim_ifp
->pim_ifstat_join_send
);
1628 json_object_int_add(json_row
, "registerRx",
1629 pim_ifp
->pim_ifstat_reg_recv
);
1630 json_object_int_add(json_row
, "registerTx",
1631 pim_ifp
->pim_ifstat_reg_recv
);
1632 json_object_int_add(json_row
, "registerStopRx",
1633 pim_ifp
->pim_ifstat_reg_stop_recv
);
1634 json_object_int_add(json_row
, "registerStopTx",
1635 pim_ifp
->pim_ifstat_reg_stop_send
);
1636 json_object_int_add(json_row
, "assertRx",
1637 pim_ifp
->pim_ifstat_assert_recv
);
1638 json_object_int_add(json_row
, "assertTx",
1639 pim_ifp
->pim_ifstat_assert_send
);
1640 json_object_int_add(json_row
, "bsmRx",
1641 pim_ifp
->pim_ifstat_bsm_rx
);
1642 json_object_int_add(json_row
, "bsmTx",
1643 pim_ifp
->pim_ifstat_bsm_tx
);
1645 json_object_object_add(json
, ifp
->name
, json_row
);
1648 "%-16s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7" PRIu64
"/%-7" PRIu64
"\n",
1649 ifp
->name
, pim_ifp
->pim_ifstat_hello_recv
,
1650 pim_ifp
->pim_ifstat_hello_sent
,
1651 pim_ifp
->pim_ifstat_join_recv
,
1652 pim_ifp
->pim_ifstat_join_send
,
1653 pim_ifp
->pim_ifstat_prune_recv
,
1654 pim_ifp
->pim_ifstat_prune_send
,
1655 pim_ifp
->pim_ifstat_reg_recv
,
1656 pim_ifp
->pim_ifstat_reg_send
,
1657 pim_ifp
->pim_ifstat_reg_stop_recv
,
1658 pim_ifp
->pim_ifstat_reg_stop_send
,
1659 pim_ifp
->pim_ifstat_assert_recv
,
1660 pim_ifp
->pim_ifstat_assert_send
,
1661 pim_ifp
->pim_ifstat_bsm_rx
,
1662 pim_ifp
->pim_ifstat_bsm_tx
);
1666 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1667 json
, JSON_C_TO_STRING_PRETTY
));
1668 json_object_free(json
);
1671 vty_out(vty
, "%% No such interface\n");
1675 static void pim_show_join_helper(struct vty
*vty
, struct pim_interface
*pim_ifp
,
1676 struct pim_ifchannel
*ch
, json_object
*json
,
1677 time_t now
, bool uj
)
1679 char ch_src_str
[INET_ADDRSTRLEN
];
1680 char ch_grp_str
[INET_ADDRSTRLEN
];
1681 json_object
*json_iface
= NULL
;
1682 json_object
*json_row
= NULL
;
1683 json_object
*json_grp
= NULL
;
1684 struct in_addr ifaddr
;
1689 ifaddr
= pim_ifp
->primary_address
;
1691 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
1692 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
1694 pim_time_uptime_begin(uptime
, sizeof(uptime
), now
, ch
->ifjoin_creation
);
1695 pim_time_timer_to_mmss(expire
, sizeof(expire
),
1696 ch
->t_ifjoin_expiry_timer
);
1697 pim_time_timer_to_mmss(prune
, sizeof(prune
),
1698 ch
->t_ifjoin_prune_pending_timer
);
1701 json_object_object_get_ex(json
, ch
->interface
->name
,
1705 json_iface
= json_object_new_object();
1706 json_object_pim_ifp_add(json_iface
, ch
->interface
);
1707 json_object_object_add(json
, ch
->interface
->name
,
1711 json_row
= json_object_new_object();
1712 json_object_string_add(json_row
, "source", ch_src_str
);
1713 json_object_string_add(json_row
, "group", ch_grp_str
);
1714 json_object_string_add(json_row
, "upTime", uptime
);
1715 json_object_string_add(json_row
, "expire", expire
);
1716 json_object_string_add(json_row
, "prune", prune
);
1717 json_object_string_add(
1718 json_row
, "channelJoinName",
1719 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
, ch
->flags
));
1720 if (PIM_IF_FLAG_TEST_S_G_RPT(ch
->flags
))
1721 json_object_int_add(json_row
, "SGRpt", 1);
1722 if (PIM_IF_FLAG_TEST_PROTO_PIM(ch
->flags
))
1723 json_object_int_add(json_row
, "protocolPim", 1);
1724 if (PIM_IF_FLAG_TEST_PROTO_IGMP(ch
->flags
))
1725 json_object_int_add(json_row
, "protocolIgmp", 1);
1726 json_object_object_get_ex(json_iface
, ch_grp_str
, &json_grp
);
1728 json_grp
= json_object_new_object();
1729 json_object_object_add(json_grp
, ch_src_str
, json_row
);
1730 json_object_object_add(json_iface
, ch_grp_str
,
1733 json_object_object_add(json_grp
, ch_src_str
, json_row
);
1735 vty_out(vty
, "%-16s %-15s %-15s %-15s %-10s %8s %-6s %5s\n",
1736 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
,
1738 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
, ch
->flags
),
1739 uptime
, expire
, prune
);
1743 static void pim_show_join(struct pim_instance
*pim
, struct vty
*vty
,
1744 struct prefix_sg
*sg
, bool uj
)
1746 struct pim_interface
*pim_ifp
;
1747 struct pim_ifchannel
*ch
;
1748 struct interface
*ifp
;
1750 json_object
*json
= NULL
;
1752 now
= pim_time_monotonic_sec();
1755 json
= json_object_new_object();
1758 "Interface Address Source Group State Uptime Expire Prune\n");
1760 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1761 pim_ifp
= ifp
->info
;
1765 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
1766 if (sg
->grp
.s_addr
!= INADDR_ANY
1767 && sg
->grp
.s_addr
!= ch
->sg
.grp
.s_addr
)
1769 if (sg
->src
.s_addr
!= INADDR_ANY
1770 && sg
->src
.s_addr
!= ch
->sg
.src
.s_addr
)
1772 pim_show_join_helper(vty
, pim_ifp
, ch
, json
, now
, uj
);
1773 } /* scan interface channels */
1777 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1778 json
, JSON_C_TO_STRING_PRETTY
));
1779 json_object_free(json
);
1783 static void pim_show_neighbors_single(struct pim_instance
*pim
, struct vty
*vty
,
1784 const char *neighbor
, bool uj
)
1786 struct listnode
*neighnode
;
1787 struct interface
*ifp
;
1788 struct pim_interface
*pim_ifp
;
1789 struct pim_neighbor
*neigh
;
1791 int found_neighbor
= 0;
1792 int option_address_list
;
1793 int option_dr_priority
;
1794 int option_generation_id
;
1795 int option_holdtime
;
1796 int option_lan_prune_delay
;
1800 char neigh_src_str
[INET_ADDRSTRLEN
];
1802 json_object
*json
= NULL
;
1803 json_object
*json_ifp
= NULL
;
1804 json_object
*json_row
= NULL
;
1806 now
= pim_time_monotonic_sec();
1809 json
= json_object_new_object();
1811 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1812 pim_ifp
= ifp
->info
;
1817 if (pim_ifp
->pim_sock_fd
< 0)
1820 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
1822 pim_inet4_dump("<src?>", neigh
->source_addr
,
1823 neigh_src_str
, sizeof(neigh_src_str
));
1826 * The user can specify either the interface name or the
1828 * If this pim_ifp matches neither then skip.
1830 if (strcmp(neighbor
, "detail")
1831 && strcmp(neighbor
, ifp
->name
)
1832 && strcmp(neighbor
, neigh_src_str
))
1836 pim_time_uptime(uptime
, sizeof(uptime
),
1837 now
- neigh
->creation
);
1838 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
1839 neigh
->t_expire_timer
);
1841 option_address_list
= 0;
1842 option_dr_priority
= 0;
1843 option_generation_id
= 0;
1844 option_holdtime
= 0;
1845 option_lan_prune_delay
= 0;
1848 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1849 PIM_OPTION_MASK_ADDRESS_LIST
))
1850 option_address_list
= 1;
1852 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1853 PIM_OPTION_MASK_DR_PRIORITY
))
1854 option_dr_priority
= 1;
1856 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1857 PIM_OPTION_MASK_GENERATION_ID
))
1858 option_generation_id
= 1;
1860 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1861 PIM_OPTION_MASK_HOLDTIME
))
1862 option_holdtime
= 1;
1864 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1865 PIM_OPTION_MASK_LAN_PRUNE_DELAY
))
1866 option_lan_prune_delay
= 1;
1868 if (PIM_OPTION_IS_SET(
1869 neigh
->hello_options
,
1870 PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION
))
1875 /* Does this ifp live in json? If not create
1877 json_object_object_get_ex(json
, ifp
->name
,
1881 json_ifp
= json_object_new_object();
1882 json_object_pim_ifp_add(json_ifp
, ifp
);
1883 json_object_object_add(json
, ifp
->name
,
1887 json_row
= json_object_new_object();
1888 json_object_string_add(json_row
, "interface",
1890 json_object_string_add(json_row
, "address",
1892 json_object_string_add(json_row
, "upTime",
1894 json_object_string_add(json_row
, "holdtime",
1896 json_object_int_add(json_row
, "drPriority",
1897 neigh
->dr_priority
);
1898 json_object_int_add(json_row
, "generationId",
1899 neigh
->generation_id
);
1901 if (option_address_list
)
1902 json_object_boolean_true_add(
1904 "helloOptionAddressList");
1906 if (option_dr_priority
)
1907 json_object_boolean_true_add(
1909 "helloOptionDrPriority");
1911 if (option_generation_id
)
1912 json_object_boolean_true_add(
1914 "helloOptionGenerationId");
1916 if (option_holdtime
)
1917 json_object_boolean_true_add(
1919 "helloOptionHoldtime");
1921 if (option_lan_prune_delay
)
1922 json_object_boolean_true_add(
1924 "helloOptionLanPruneDelay");
1927 json_object_boolean_true_add(
1928 json_row
, "helloOptionTBit");
1930 json_object_object_add(json_ifp
, neigh_src_str
,
1934 vty_out(vty
, "Interface : %s\n", ifp
->name
);
1935 vty_out(vty
, "Neighbor : %s\n", neigh_src_str
);
1943 " DR Priority : %d\n",
1944 neigh
->dr_priority
);
1946 " Generation ID : %08x\n",
1947 neigh
->generation_id
);
1949 " Override Interval (msec) : %d\n",
1950 neigh
->override_interval_msec
);
1952 " Propagation Delay (msec) : %d\n",
1953 neigh
->propagation_delay_msec
);
1955 " Hello Option - Address List : %s\n",
1956 option_address_list
? "yes" : "no");
1958 " Hello Option - DR Priority : %s\n",
1959 option_dr_priority
? "yes" : "no");
1961 " Hello Option - Generation ID : %s\n",
1962 option_generation_id
? "yes" : "no");
1964 " Hello Option - Holdtime : %s\n",
1965 option_holdtime
? "yes" : "no");
1967 " Hello Option - LAN Prune Delay : %s\n",
1968 option_lan_prune_delay
? "yes" : "no");
1970 " Hello Option - T-bit : %s\n",
1971 option_t_bit
? "yes" : "no");
1972 pim_bfd_show_info(vty
, neigh
->bfd_info
,
1980 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1981 json
, JSON_C_TO_STRING_PRETTY
));
1982 json_object_free(json
);
1985 if (!found_neighbor
)
1987 "%% No such interface or neighbor\n");
1992 static void pim_show_state(struct pim_instance
*pim
, struct vty
*vty
,
1993 const char *src_or_group
, const char *group
, bool uj
)
1995 struct channel_oil
*c_oil
;
1996 json_object
*json
= NULL
;
1997 json_object
*json_group
= NULL
;
1998 json_object
*json_ifp_in
= NULL
;
1999 json_object
*json_ifp_out
= NULL
;
2000 json_object
*json_source
= NULL
;
2003 now
= pim_time_monotonic_sec();
2006 json
= json_object_new_object();
2009 "Codes: J -> Pim Join, I -> IGMP Report, S -> Source, * -> Inherited from (*,G), V -> VxLAN, M -> Muted");
2011 "\nActive Source Group RPT IIF OIL\n");
2014 frr_each (rb_pim_oil
, &pim
->channel_oil_head
, c_oil
) {
2015 char grp_str
[INET_ADDRSTRLEN
];
2016 char src_str
[INET_ADDRSTRLEN
];
2017 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
2018 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
2020 struct interface
*ifp_in
;
2025 PIM_UPSTREAM_FLAG_TEST_USE_RPT(c_oil
->up
->flags
)) ||
2026 c_oil
->oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
2031 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
2033 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
2035 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
2038 strlcpy(in_ifname
, ifp_in
->name
, sizeof(in_ifname
));
2040 strlcpy(in_ifname
, "<iif?>", sizeof(in_ifname
));
2043 if (strcmp(src_or_group
, src_str
)
2044 && strcmp(src_or_group
, grp_str
))
2047 if (group
&& strcmp(group
, grp_str
))
2053 /* Find the group, create it if it doesn't exist */
2054 json_object_object_get_ex(json
, grp_str
, &json_group
);
2057 json_group
= json_object_new_object();
2058 json_object_object_add(json
, grp_str
,
2062 /* Find the source nested under the group, create it if
2063 * it doesn't exist */
2064 json_object_object_get_ex(json_group
, src_str
,
2068 json_source
= json_object_new_object();
2069 json_object_object_add(json_group
, src_str
,
2073 /* Find the inbound interface nested under the source,
2074 * create it if it doesn't exist */
2075 json_object_object_get_ex(json_source
, in_ifname
,
2079 json_ifp_in
= json_object_new_object();
2080 json_object_object_add(json_source
, in_ifname
,
2082 json_object_int_add(json_source
, "Installed",
2085 json_object_boolean_true_add(
2086 json_source
, "isRpt");
2088 json_object_boolean_false_add(
2089 json_source
, "isRpt");
2090 json_object_int_add(json_source
, "RefCount",
2091 c_oil
->oil_ref_count
);
2092 json_object_int_add(json_source
, "OilListSize",
2094 json_object_int_add(
2095 json_source
, "OilRescan",
2096 c_oil
->oil_inherited_rescan
);
2097 json_object_int_add(json_source
, "LastUsed",
2098 c_oil
->cc
.lastused
);
2099 json_object_int_add(json_source
, "PacketCount",
2101 json_object_int_add(json_source
, "ByteCount",
2103 json_object_int_add(json_source
,
2105 c_oil
->cc
.wrong_if
);
2108 vty_out(vty
, "%-6d %-15s %-15s %-3s %-16s ",
2109 c_oil
->installed
, src_str
, grp_str
,
2110 isRpt
? "y" : "n", in_ifname
);
2113 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
2115 struct interface
*ifp_out
;
2116 char oif_uptime
[10];
2119 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
2123 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
2125 oif_uptime
, sizeof(oif_uptime
),
2126 now
- c_oil
->oif_creation
[oif_vif_index
]);
2129 strlcpy(out_ifname
, ifp_out
->name
, sizeof(out_ifname
));
2131 strlcpy(out_ifname
, "<oif?>", sizeof(out_ifname
));
2134 json_ifp_out
= json_object_new_object();
2135 json_object_string_add(json_ifp_out
, "source",
2137 json_object_string_add(json_ifp_out
, "group",
2139 json_object_string_add(json_ifp_out
,
2142 json_object_string_add(json_ifp_out
,
2143 "outboundInterface",
2145 json_object_int_add(json_ifp_out
, "installed",
2148 json_object_object_add(json_ifp_in
, out_ifname
,
2153 vty_out(vty
, "%s(%c%c%c%c%c)",
2155 (c_oil
->oif_flags
[oif_vif_index
]
2156 & PIM_OIF_FLAG_PROTO_IGMP
)
2159 (c_oil
->oif_flags
[oif_vif_index
]
2160 & PIM_OIF_FLAG_PROTO_PIM
)
2163 (c_oil
->oif_flags
[oif_vif_index
]
2164 & PIM_OIF_FLAG_PROTO_VXLAN
)
2167 (c_oil
->oif_flags
[oif_vif_index
]
2168 & PIM_OIF_FLAG_PROTO_STAR
)
2171 (c_oil
->oif_flags
[oif_vif_index
]
2172 & PIM_OIF_FLAG_MUTE
)
2176 vty_out(vty
, ", %s(%c%c%c%c%c)",
2178 (c_oil
->oif_flags
[oif_vif_index
]
2179 & PIM_OIF_FLAG_PROTO_IGMP
)
2182 (c_oil
->oif_flags
[oif_vif_index
]
2183 & PIM_OIF_FLAG_PROTO_PIM
)
2186 (c_oil
->oif_flags
[oif_vif_index
]
2187 & PIM_OIF_FLAG_PROTO_VXLAN
)
2190 (c_oil
->oif_flags
[oif_vif_index
]
2191 & PIM_OIF_FLAG_PROTO_STAR
)
2194 (c_oil
->oif_flags
[oif_vif_index
]
2195 & PIM_OIF_FLAG_MUTE
)
2207 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2208 json
, JSON_C_TO_STRING_PRETTY
));
2209 json_object_free(json
);
2215 static void pim_show_neighbors(struct pim_instance
*pim
, struct vty
*vty
,
2218 struct listnode
*neighnode
;
2219 struct interface
*ifp
;
2220 struct pim_interface
*pim_ifp
;
2221 struct pim_neighbor
*neigh
;
2225 char neigh_src_str
[INET_ADDRSTRLEN
];
2226 json_object
*json
= NULL
;
2227 json_object
*json_ifp_rows
= NULL
;
2228 json_object
*json_row
= NULL
;
2230 now
= pim_time_monotonic_sec();
2233 json
= json_object_new_object();
2236 "Interface Neighbor Uptime Holdtime DR Pri\n");
2239 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2240 pim_ifp
= ifp
->info
;
2245 if (pim_ifp
->pim_sock_fd
< 0)
2249 json_ifp_rows
= json_object_new_object();
2251 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
2253 pim_inet4_dump("<src?>", neigh
->source_addr
,
2254 neigh_src_str
, sizeof(neigh_src_str
));
2255 pim_time_uptime(uptime
, sizeof(uptime
),
2256 now
- neigh
->creation
);
2257 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
2258 neigh
->t_expire_timer
);
2261 json_row
= json_object_new_object();
2262 json_object_string_add(json_row
, "interface",
2264 json_object_string_add(json_row
, "neighbor",
2266 json_object_string_add(json_row
, "upTime",
2268 json_object_string_add(json_row
, "holdTime",
2270 json_object_int_add(json_row
, "holdTimeMax",
2272 json_object_int_add(json_row
, "drPriority",
2273 neigh
->dr_priority
);
2274 json_object_object_add(json_ifp_rows
,
2275 neigh_src_str
, json_row
);
2278 vty_out(vty
, "%-16s %15s %8s %8s %6d\n",
2279 ifp
->name
, neigh_src_str
, uptime
,
2280 expire
, neigh
->dr_priority
);
2285 json_object_object_add(json
, ifp
->name
, json_ifp_rows
);
2286 json_ifp_rows
= NULL
;
2291 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2292 json
, JSON_C_TO_STRING_PRETTY
));
2293 json_object_free(json
);
2297 static void pim_show_neighbors_secondary(struct pim_instance
*pim
,
2300 struct interface
*ifp
;
2303 "Interface Address Neighbor Secondary \n");
2305 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2306 struct pim_interface
*pim_ifp
;
2307 struct in_addr ifaddr
;
2308 struct listnode
*neighnode
;
2309 struct pim_neighbor
*neigh
;
2311 pim_ifp
= ifp
->info
;
2316 if (pim_ifp
->pim_sock_fd
< 0)
2319 ifaddr
= pim_ifp
->primary_address
;
2321 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
2323 char neigh_src_str
[INET_ADDRSTRLEN
];
2324 struct listnode
*prefix_node
;
2327 if (!neigh
->prefix_list
)
2330 pim_inet4_dump("<src?>", neigh
->source_addr
,
2331 neigh_src_str
, sizeof(neigh_src_str
));
2333 for (ALL_LIST_ELEMENTS_RO(neigh
->prefix_list
,
2335 char neigh_sec_str
[PREFIX2STR_BUFFER
];
2337 prefix2str(p
, neigh_sec_str
,
2338 sizeof(neigh_sec_str
));
2340 vty_out(vty
, "%-16s %-15s %-15s %-15s\n",
2341 ifp
->name
, inet_ntoa(ifaddr
),
2342 neigh_src_str
, neigh_sec_str
);
2348 static void json_object_pim_upstream_add(json_object
*json
,
2349 struct pim_upstream
*up
)
2351 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED
)
2352 json_object_boolean_true_add(json
, "drJoinDesired");
2354 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED
)
2355 json_object_boolean_true_add(json
, "drJoinDesiredUpdated");
2357 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
2358 json_object_boolean_true_add(json
, "firstHopRouter");
2360 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_IGMP
)
2361 json_object_boolean_true_add(json
, "sourceIgmp");
2363 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_PIM
)
2364 json_object_boolean_true_add(json
, "sourcePim");
2366 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_STREAM
)
2367 json_object_boolean_true_add(json
, "sourceStream");
2369 /* XXX: need to print ths flag in the plain text display as well */
2370 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_MSDP
)
2371 json_object_boolean_true_add(json
, "sourceMsdp");
2373 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SEND_SG_RPT_PRUNE
)
2374 json_object_boolean_true_add(json
, "sendSGRptPrune");
2376 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_LHR
)
2377 json_object_boolean_true_add(json
, "lastHopRouter");
2379 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DISABLE_KAT_EXPIRY
)
2380 json_object_boolean_true_add(json
, "disableKATExpiry");
2382 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_STATIC_IIF
)
2383 json_object_boolean_true_add(json
, "staticIncomingInterface");
2385 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_ALLOW_IIF_IN_OIL
)
2386 json_object_boolean_true_add(json
,
2387 "allowIncomingInterfaceinOil");
2389 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_NO_PIMREG_DATA
)
2390 json_object_boolean_true_add(json
, "noPimRegistrationData");
2392 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FORCE_PIMREG
)
2393 json_object_boolean_true_add(json
, "forcePimRegistration");
2395 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_ORIG
)
2396 json_object_boolean_true_add(json
, "sourceVxlanOrigination");
2398 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_TERM
)
2399 json_object_boolean_true_add(json
, "sourceVxlanTermination");
2401 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_VXLAN
)
2402 json_object_boolean_true_add(json
, "mlagVxlan");
2404 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_NON_DF
)
2405 json_object_boolean_true_add(json
,
2406 "mlagNonDesignatedForwarder");
2410 pim_upstream_state2brief_str(enum pim_upstream_state join_state
,
2411 char *state_str
, size_t state_str_len
)
2413 switch (join_state
) {
2414 case PIM_UPSTREAM_NOTJOINED
:
2415 strlcpy(state_str
, "NotJ", state_str_len
);
2417 case PIM_UPSTREAM_JOINED
:
2418 strlcpy(state_str
, "J", state_str_len
);
2421 strlcpy(state_str
, "Unk", state_str_len
);
2426 static const char *pim_reg_state2brief_str(enum pim_reg_state reg_state
,
2427 char *state_str
, size_t state_str_len
)
2429 switch (reg_state
) {
2430 case PIM_REG_NOINFO
:
2431 strlcpy(state_str
, "RegNI", state_str_len
);
2434 strlcpy(state_str
, "RegJ", state_str_len
);
2436 case PIM_REG_JOIN_PENDING
:
2438 strlcpy(state_str
, "RegP", state_str_len
);
2441 strlcpy(state_str
, "Unk", state_str_len
);
2446 static void pim_show_upstream(struct pim_instance
*pim
, struct vty
*vty
,
2447 struct prefix_sg
*sg
, bool uj
)
2449 struct pim_upstream
*up
;
2451 json_object
*json
= NULL
;
2452 json_object
*json_group
= NULL
;
2453 json_object
*json_row
= NULL
;
2455 now
= pim_time_monotonic_sec();
2458 json
= json_object_new_object();
2461 "Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt\n");
2463 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
2464 char src_str
[INET_ADDRSTRLEN
];
2465 char grp_str
[INET_ADDRSTRLEN
];
2467 char join_timer
[10];
2470 char msdp_reg_timer
[10];
2471 char state_str
[PIM_REG_STATE_STR_LEN
];
2473 if (sg
->grp
.s_addr
!= INADDR_ANY
2474 && sg
->grp
.s_addr
!= up
->sg
.grp
.s_addr
)
2476 if (sg
->src
.s_addr
!= INADDR_ANY
2477 && sg
->src
.s_addr
!= up
->sg
.src
.s_addr
)
2480 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2481 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2482 pim_time_uptime(uptime
, sizeof(uptime
),
2483 now
- up
->state_transition
);
2484 pim_time_timer_to_hhmmss(join_timer
, sizeof(join_timer
),
2488 * If the upstream is not dummy and it has a J/P timer for the
2489 * neighbor display that
2491 if (!up
->t_join_timer
&& up
->rpf
.source_nexthop
.interface
) {
2492 struct pim_neighbor
*nbr
;
2494 nbr
= pim_neighbor_find(
2495 up
->rpf
.source_nexthop
.interface
,
2496 up
->rpf
.rpf_addr
.u
.prefix4
);
2498 pim_time_timer_to_hhmmss(join_timer
,
2503 pim_time_timer_to_hhmmss(rs_timer
, sizeof(rs_timer
),
2505 pim_time_timer_to_hhmmss(ka_timer
, sizeof(ka_timer
),
2507 pim_time_timer_to_hhmmss(msdp_reg_timer
, sizeof(msdp_reg_timer
),
2508 up
->t_msdp_reg_timer
);
2510 pim_upstream_state2brief_str(up
->join_state
, state_str
, sizeof(state_str
));
2511 if (up
->reg_state
!= PIM_REG_NOINFO
) {
2512 char tmp_str
[PIM_REG_STATE_STR_LEN
];
2514 sprintf(state_str
+ strlen(state_str
), ",%s",
2515 pim_reg_state2brief_str(up
->reg_state
, tmp_str
,
2520 json_object_object_get_ex(json
, grp_str
, &json_group
);
2523 json_group
= json_object_new_object();
2524 json_object_object_add(json
, grp_str
,
2528 json_row
= json_object_new_object();
2529 json_object_pim_upstream_add(json_row
, up
);
2530 json_object_string_add(
2531 json_row
, "inboundInterface",
2532 up
->rpf
.source_nexthop
.interface
2533 ? up
->rpf
.source_nexthop
.interface
->name
2537 * The RPF address we use is slightly different
2538 * based upon what we are looking up.
2539 * If we have a S, list that unless
2540 * we are the FHR, else we just put
2541 * the RP as the rpfAddress
2543 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
2544 || up
->sg
.src
.s_addr
== INADDR_ANY
) {
2545 char rpf
[PREFIX_STRLEN
];
2546 struct pim_rpf
*rpg
;
2548 rpg
= RP(pim
, up
->sg
.grp
);
2549 pim_inet4_dump("<rpf?>",
2550 rpg
->rpf_addr
.u
.prefix4
, rpf
,
2552 json_object_string_add(json_row
, "rpfAddress",
2555 json_object_string_add(json_row
, "rpfAddress",
2559 json_object_string_add(json_row
, "source", src_str
);
2560 json_object_string_add(json_row
, "group", grp_str
);
2561 json_object_string_add(json_row
, "state", state_str
);
2562 json_object_string_add(
2563 json_row
, "joinState",
2564 pim_upstream_state2str(up
->join_state
));
2565 json_object_string_add(
2566 json_row
, "regState",
2567 pim_reg_state2str(up
->reg_state
, state_str
, sizeof(state_str
)));
2568 json_object_string_add(json_row
, "upTime", uptime
);
2569 json_object_string_add(json_row
, "joinTimer",
2571 json_object_string_add(json_row
, "resetTimer",
2573 json_object_string_add(json_row
, "keepaliveTimer",
2575 json_object_string_add(json_row
, "msdpRegTimer",
2577 json_object_int_add(json_row
, "refCount",
2579 json_object_int_add(json_row
, "sptBit", up
->sptbit
);
2580 json_object_object_add(json_group
, src_str
, json_row
);
2583 "%-16s%-15s %-15s %-11s %-8s %-9s %-9s %-9s %6d\n",
2584 up
->rpf
.source_nexthop
.interface
2585 ? up
->rpf
.source_nexthop
.interface
->name
2587 src_str
, grp_str
, state_str
, uptime
, join_timer
,
2588 rs_timer
, ka_timer
, up
->ref_count
);
2593 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2594 json
, JSON_C_TO_STRING_PRETTY
));
2595 json_object_free(json
);
2599 static void pim_show_channel_helper(struct pim_instance
*pim
,
2601 struct pim_interface
*pim_ifp
,
2602 struct pim_ifchannel
*ch
,
2603 json_object
*json
, bool uj
)
2605 struct pim_upstream
*up
= ch
->upstream
;
2606 json_object
*json_group
= NULL
;
2607 char src_str
[INET_ADDRSTRLEN
];
2608 char grp_str
[INET_ADDRSTRLEN
];
2609 json_object
*json_row
= NULL
;
2611 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2612 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2615 json_object_object_get_ex(json
, grp_str
, &json_group
);
2618 json_group
= json_object_new_object();
2619 json_object_object_add(json
, grp_str
, json_group
);
2622 json_row
= json_object_new_object();
2623 json_object_pim_upstream_add(json_row
, up
);
2624 json_object_string_add(json_row
, "interface",
2625 ch
->interface
->name
);
2626 json_object_string_add(json_row
, "source", src_str
);
2627 json_object_string_add(json_row
, "group", grp_str
);
2629 if (pim_macro_ch_lost_assert(ch
))
2630 json_object_boolean_true_add(json_row
, "lostAssert");
2632 if (pim_macro_chisin_joins(ch
))
2633 json_object_boolean_true_add(json_row
, "joins");
2635 if (pim_macro_chisin_pim_include(ch
))
2636 json_object_boolean_true_add(json_row
, "pimInclude");
2638 if (pim_upstream_evaluate_join_desired(pim
, up
))
2639 json_object_boolean_true_add(json_row
,
2640 "evaluateJoinDesired");
2642 json_object_object_add(json_group
, src_str
, json_row
);
2645 vty_out(vty
, "%-16s %-15s %-15s %-10s %-5s %-10s %-11s %-6s\n",
2646 ch
->interface
->name
, src_str
, grp_str
,
2647 pim_macro_ch_lost_assert(ch
) ? "yes" : "no",
2648 pim_macro_chisin_joins(ch
) ? "yes" : "no",
2649 pim_macro_chisin_pim_include(ch
) ? "yes" : "no",
2650 PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(up
->flags
)
2653 pim_upstream_evaluate_join_desired(pim
, up
) ? "yes"
2658 static void pim_show_channel(struct pim_instance
*pim
, struct vty
*vty
,
2661 struct pim_interface
*pim_ifp
;
2662 struct pim_ifchannel
*ch
;
2663 struct interface
*ifp
;
2665 json_object
*json
= NULL
;
2668 json
= json_object_new_object();
2671 "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD\n");
2673 /* scan per-interface (S,G) state */
2674 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2675 pim_ifp
= ifp
->info
;
2680 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
2681 /* scan all interfaces */
2682 pim_show_channel_helper(pim
, vty
, pim_ifp
, ch
,
2688 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2689 json
, JSON_C_TO_STRING_PRETTY
));
2690 json_object_free(json
);
2694 static void pim_show_join_desired_helper(struct pim_instance
*pim
,
2696 struct pim_upstream
*up
,
2697 json_object
*json
, bool uj
)
2699 json_object
*json_group
= NULL
;
2700 char src_str
[INET_ADDRSTRLEN
];
2701 char grp_str
[INET_ADDRSTRLEN
];
2702 json_object
*json_row
= NULL
;
2704 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2705 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2708 json_object_object_get_ex(json
, grp_str
, &json_group
);
2711 json_group
= json_object_new_object();
2712 json_object_object_add(json
, grp_str
, json_group
);
2715 json_row
= json_object_new_object();
2716 json_object_pim_upstream_add(json_row
, up
);
2717 json_object_string_add(json_row
, "source", src_str
);
2718 json_object_string_add(json_row
, "group", grp_str
);
2720 if (pim_upstream_evaluate_join_desired(pim
, up
))
2721 json_object_boolean_true_add(json_row
,
2722 "evaluateJoinDesired");
2724 json_object_object_add(json_group
, src_str
, json_row
);
2727 vty_out(vty
, "%-15s %-15s %-6s\n",
2729 pim_upstream_evaluate_join_desired(pim
, up
) ? "yes"
2734 static void pim_show_join_desired(struct pim_instance
*pim
, struct vty
*vty
,
2737 struct pim_upstream
*up
;
2739 json_object
*json
= NULL
;
2742 json
= json_object_new_object();
2745 "Source Group EvalJD\n");
2747 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
2748 /* scan all interfaces */
2749 pim_show_join_desired_helper(pim
, vty
, up
,
2754 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2755 json
, JSON_C_TO_STRING_PRETTY
));
2756 json_object_free(json
);
2760 static void pim_show_upstream_rpf(struct pim_instance
*pim
, struct vty
*vty
,
2763 struct pim_upstream
*up
;
2764 json_object
*json
= NULL
;
2765 json_object
*json_group
= NULL
;
2766 json_object
*json_row
= NULL
;
2769 json
= json_object_new_object();
2772 "Source Group RpfIface RibNextHop RpfAddress \n");
2774 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
2775 char src_str
[INET_ADDRSTRLEN
];
2776 char grp_str
[INET_ADDRSTRLEN
];
2777 char rpf_nexthop_str
[PREFIX_STRLEN
];
2778 char rpf_addr_str
[PREFIX_STRLEN
];
2779 struct pim_rpf
*rpf
;
2780 const char *rpf_ifname
;
2784 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2785 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2786 pim_addr_dump("<nexthop?>",
2787 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2788 rpf_nexthop_str
, sizeof(rpf_nexthop_str
));
2789 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2790 sizeof(rpf_addr_str
));
2792 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2795 json_object_object_get_ex(json
, grp_str
, &json_group
);
2798 json_group
= json_object_new_object();
2799 json_object_object_add(json
, grp_str
,
2803 json_row
= json_object_new_object();
2804 json_object_pim_upstream_add(json_row
, up
);
2805 json_object_string_add(json_row
, "source", src_str
);
2806 json_object_string_add(json_row
, "group", grp_str
);
2807 json_object_string_add(json_row
, "rpfInterface",
2809 json_object_string_add(json_row
, "ribNexthop",
2811 json_object_string_add(json_row
, "rpfAddress",
2813 json_object_object_add(json_group
, src_str
, json_row
);
2815 vty_out(vty
, "%-15s %-15s %-16s %-15s %-15s\n", src_str
,
2816 grp_str
, rpf_ifname
, rpf_nexthop_str
,
2822 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2823 json
, JSON_C_TO_STRING_PRETTY
));
2824 json_object_free(json
);
2828 static void show_rpf_refresh_stats(struct vty
*vty
, struct pim_instance
*pim
,
2829 time_t now
, json_object
*json
)
2831 char refresh_uptime
[10];
2833 pim_time_uptime_begin(refresh_uptime
, sizeof(refresh_uptime
), now
,
2834 pim
->rpf_cache_refresh_last
);
2837 json_object_int_add(json
, "rpfCacheRefreshDelayMsecs",
2838 router
->rpf_cache_refresh_delay_msec
);
2839 json_object_int_add(
2840 json
, "rpfCacheRefreshTimer",
2841 pim_time_timer_remain_msec(pim
->rpf_cache_refresher
));
2842 json_object_int_add(json
, "rpfCacheRefreshRequests",
2843 pim
->rpf_cache_refresh_requests
);
2844 json_object_int_add(json
, "rpfCacheRefreshEvents",
2845 pim
->rpf_cache_refresh_events
);
2846 json_object_string_add(json
, "rpfCacheRefreshLast",
2848 json_object_int_add(json
, "nexthopLookups",
2849 pim
->nexthop_lookups
);
2850 json_object_int_add(json
, "nexthopLookupsAvoided",
2851 pim
->nexthop_lookups_avoided
);
2854 "RPF Cache Refresh Delay: %ld msecs\n"
2855 "RPF Cache Refresh Timer: %ld msecs\n"
2856 "RPF Cache Refresh Requests: %lld\n"
2857 "RPF Cache Refresh Events: %lld\n"
2858 "RPF Cache Refresh Last: %s\n"
2859 "Nexthop Lookups: %lld\n"
2860 "Nexthop Lookups Avoided: %lld\n",
2861 router
->rpf_cache_refresh_delay_msec
,
2862 pim_time_timer_remain_msec(pim
->rpf_cache_refresher
),
2863 (long long)pim
->rpf_cache_refresh_requests
,
2864 (long long)pim
->rpf_cache_refresh_events
,
2865 refresh_uptime
, (long long)pim
->nexthop_lookups
,
2866 (long long)pim
->nexthop_lookups_avoided
);
2870 static void show_scan_oil_stats(struct pim_instance
*pim
, struct vty
*vty
,
2873 char uptime_scan_oil
[10];
2874 char uptime_mroute_add
[10];
2875 char uptime_mroute_del
[10];
2877 pim_time_uptime_begin(uptime_scan_oil
, sizeof(uptime_scan_oil
), now
,
2878 pim
->scan_oil_last
);
2879 pim_time_uptime_begin(uptime_mroute_add
, sizeof(uptime_mroute_add
), now
,
2880 pim
->mroute_add_last
);
2881 pim_time_uptime_begin(uptime_mroute_del
, sizeof(uptime_mroute_del
), now
,
2882 pim
->mroute_del_last
);
2885 "Scan OIL - Last: %s Events: %lld\n"
2886 "MFC Add - Last: %s Events: %lld\n"
2887 "MFC Del - Last: %s Events: %lld\n",
2888 uptime_scan_oil
, (long long)pim
->scan_oil_events
,
2889 uptime_mroute_add
, (long long)pim
->mroute_add_events
,
2890 uptime_mroute_del
, (long long)pim
->mroute_del_events
);
2893 static void pim_show_rpf(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
2895 struct pim_upstream
*up
;
2896 time_t now
= pim_time_monotonic_sec();
2897 json_object
*json
= NULL
;
2898 json_object
*json_group
= NULL
;
2899 json_object
*json_row
= NULL
;
2902 json
= json_object_new_object();
2903 show_rpf_refresh_stats(vty
, pim
, now
, json
);
2905 show_rpf_refresh_stats(vty
, pim
, now
, json
);
2908 "Source Group RpfIface RpfAddress RibNextHop Metric Pref\n");
2911 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
2912 char src_str
[INET_ADDRSTRLEN
];
2913 char grp_str
[INET_ADDRSTRLEN
];
2914 char rpf_addr_str
[PREFIX_STRLEN
];
2915 char rib_nexthop_str
[PREFIX_STRLEN
];
2916 const char *rpf_ifname
;
2917 struct pim_rpf
*rpf
= &up
->rpf
;
2919 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2920 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2921 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2922 sizeof(rpf_addr_str
));
2923 pim_addr_dump("<nexthop?>",
2924 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2925 rib_nexthop_str
, sizeof(rib_nexthop_str
));
2927 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2930 json_object_object_get_ex(json
, grp_str
, &json_group
);
2933 json_group
= json_object_new_object();
2934 json_object_object_add(json
, grp_str
,
2938 json_row
= json_object_new_object();
2939 json_object_string_add(json_row
, "source", src_str
);
2940 json_object_string_add(json_row
, "group", grp_str
);
2941 json_object_string_add(json_row
, "rpfInterface",
2943 json_object_string_add(json_row
, "rpfAddress",
2945 json_object_string_add(json_row
, "ribNexthop",
2947 json_object_int_add(
2948 json_row
, "routeMetric",
2949 rpf
->source_nexthop
.mrib_route_metric
);
2950 json_object_int_add(
2951 json_row
, "routePreference",
2952 rpf
->source_nexthop
.mrib_metric_preference
);
2953 json_object_object_add(json_group
, src_str
, json_row
);
2956 vty_out(vty
, "%-15s %-15s %-16s %-15s %-15s %6d %4d\n",
2957 src_str
, grp_str
, rpf_ifname
, rpf_addr_str
,
2959 rpf
->source_nexthop
.mrib_route_metric
,
2960 rpf
->source_nexthop
.mrib_metric_preference
);
2965 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2966 json
, JSON_C_TO_STRING_PRETTY
));
2967 json_object_free(json
);
2971 struct pnc_cache_walk_data
{
2973 struct pim_instance
*pim
;
2976 static int pim_print_pnc_cache_walkcb(struct hash_bucket
*bucket
, void *arg
)
2978 struct pim_nexthop_cache
*pnc
= bucket
->data
;
2979 struct pnc_cache_walk_data
*cwd
= arg
;
2980 struct vty
*vty
= cwd
->vty
;
2981 struct pim_instance
*pim
= cwd
->pim
;
2982 struct nexthop
*nh_node
= NULL
;
2983 ifindex_t first_ifindex
;
2984 struct interface
*ifp
= NULL
;
2986 for (nh_node
= pnc
->nexthop
; nh_node
; nh_node
= nh_node
->next
) {
2987 first_ifindex
= nh_node
->ifindex
;
2988 ifp
= if_lookup_by_index(first_ifindex
, pim
->vrf_id
);
2990 vty_out(vty
, "%-15s ", inet_ntoa(pnc
->rpf
.rpf_addr
.u
.prefix4
));
2991 vty_out(vty
, "%-16s ", ifp
? ifp
->name
: "NULL");
2992 vty_out(vty
, "%s ", inet_ntoa(nh_node
->gate
.ipv4
));
2998 static void pim_show_nexthop(struct pim_instance
*pim
, struct vty
*vty
)
3000 struct pnc_cache_walk_data cwd
;
3004 vty_out(vty
, "Number of registered addresses: %lu\n",
3005 pim
->rpf_hash
->count
);
3006 vty_out(vty
, "Address Interface Nexthop\n");
3007 vty_out(vty
, "---------------------------------------------\n");
3009 hash_walk(pim
->rpf_hash
, pim_print_pnc_cache_walkcb
, &cwd
);
3012 /* Display the bsm database details */
3013 static void pim_show_bsm_db(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
3015 struct listnode
*bsmnode
;
3018 struct bsm_info
*bsm
;
3019 json_object
*json
= NULL
;
3020 json_object
*json_group
= NULL
;
3021 json_object
*json_row
= NULL
;
3023 count
= pim
->global_scope
.bsm_list
->count
;
3026 json
= json_object_new_object();
3027 json_object_int_add(json
, "Number of the fragments", count
);
3029 vty_out(vty
, "Scope Zone: Global\n");
3030 vty_out(vty
, "Number of the fragments: %d\n", count
);
3034 for (ALL_LIST_ELEMENTS_RO(pim
->global_scope
.bsm_list
, bsmnode
, bsm
)) {
3035 char grp_str
[PREFIX_STRLEN
];
3036 char rp_str
[INET_ADDRSTRLEN
];
3037 char bsr_str
[INET_ADDRSTRLEN
];
3038 struct bsmmsg_grpinfo
*group
;
3039 struct bsmmsg_rpinfo
*rpaddr
;
3041 struct bsm_hdr
*hdr
;
3042 uint32_t offset
= 0;
3045 uint32_t frag_rp_cnt
= 0;
3050 /* skip pim header */
3051 buf
+= PIM_MSG_HEADER_LEN
;
3052 len
-= PIM_MSG_HEADER_LEN
;
3054 hdr
= (struct bsm_hdr
*)buf
;
3056 /* BSM starts with bsr header */
3057 buf
+= sizeof(struct bsm_hdr
);
3058 len
-= sizeof(struct bsm_hdr
);
3060 pim_inet4_dump("<BSR Address?>", hdr
->bsr_addr
.addr
, bsr_str
,
3065 json_object_string_add(json
, "BSR address", bsr_str
);
3066 json_object_int_add(json
, "BSR priority",
3068 json_object_int_add(json
, "Hashmask Length",
3070 json_object_int_add(json
, "Fragment Tag",
3071 ntohs(hdr
->frag_tag
));
3073 vty_out(vty
, "BSM Fragment : %d\n", fragment
);
3074 vty_out(vty
, "------------------\n");
3075 vty_out(vty
, "%-15s %-15s %-15s %-15s\n", "BSR-Address",
3076 "BSR-Priority", "Hashmask-len", "Fragment-Tag");
3077 vty_out(vty
, "%-15s %-15d %-15d %-15d\n", bsr_str
,
3078 hdr
->bsr_prio
, hdr
->hm_len
,
3079 ntohs(hdr
->frag_tag
));
3084 while (offset
< len
) {
3085 group
= (struct bsmmsg_grpinfo
*)buf
;
3087 if (group
->group
.family
== PIM_MSG_ADDRESS_FAMILY_IPV4
)
3088 grp
.family
= AF_INET
;
3090 grp
.prefixlen
= group
->group
.mask
;
3091 grp
.u
.prefix4
.s_addr
= group
->group
.addr
.s_addr
;
3093 prefix2str(&grp
, grp_str
, sizeof(grp_str
));
3095 buf
+= sizeof(struct bsmmsg_grpinfo
);
3096 offset
+= sizeof(struct bsmmsg_grpinfo
);
3099 json_object_object_get_ex(json
, grp_str
,
3102 json_group
= json_object_new_object();
3103 json_object_int_add(json_group
,
3106 json_object_int_add(
3107 json_group
, "Fragment Rp count",
3108 group
->frag_rp_count
);
3109 json_object_object_add(json
, grp_str
,
3113 vty_out(vty
, "Group : %s\n", grp_str
);
3114 vty_out(vty
, "-------------------\n");
3115 vty_out(vty
, "Rp Count:%d\n", group
->rp_count
);
3116 vty_out(vty
, "Fragment Rp Count : %d\n",
3117 group
->frag_rp_count
);
3120 frag_rp_cnt
= group
->frag_rp_count
;
3127 "RpAddress HoldTime Priority\n");
3129 while (frag_rp_cnt
--) {
3130 rpaddr
= (struct bsmmsg_rpinfo
*)buf
;
3132 buf
+= sizeof(struct bsmmsg_rpinfo
);
3133 offset
+= sizeof(struct bsmmsg_rpinfo
);
3135 pim_inet4_dump("<Rp addr?>",
3136 rpaddr
->rpaddr
.addr
, rp_str
,
3140 json_row
= json_object_new_object();
3141 json_object_string_add(
3142 json_row
, "Rp Address", rp_str
);
3143 json_object_int_add(
3144 json_row
, "Rp HoldTime",
3145 ntohs(rpaddr
->rp_holdtime
));
3146 json_object_int_add(json_row
,
3149 json_object_object_add(
3150 json_group
, rp_str
, json_row
);
3152 vty_out(vty
, "%-15s %-12d %d\n", rp_str
,
3153 ntohs(rpaddr
->rp_holdtime
),
3164 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3165 json
, JSON_C_TO_STRING_PRETTY
));
3166 json_object_free(json
);
3170 /*Display the group-rp mappings */
3171 static void pim_show_group_rp_mappings_info(struct pim_instance
*pim
,
3172 struct vty
*vty
, bool uj
)
3174 struct bsgrp_node
*bsgrp
;
3175 struct listnode
*rpnode
;
3176 struct bsm_rpinfo
*bsm_rp
;
3177 struct route_node
*rn
;
3178 char bsr_str
[INET_ADDRSTRLEN
];
3179 json_object
*json
= NULL
;
3180 json_object
*json_group
= NULL
;
3181 json_object
*json_row
= NULL
;
3183 if (pim
->global_scope
.current_bsr
.s_addr
== INADDR_ANY
)
3184 strlcpy(bsr_str
, "0.0.0.0", sizeof(bsr_str
));
3187 pim_inet4_dump("<bsr?>", pim
->global_scope
.current_bsr
, bsr_str
,
3191 json
= json_object_new_object();
3192 json_object_string_add(json
, "BSR Address", bsr_str
);
3194 vty_out(vty
, "BSR Address %s\n", bsr_str
);
3197 for (rn
= route_top(pim
->global_scope
.bsrp_table
); rn
;
3198 rn
= route_next(rn
)) {
3199 bsgrp
= (struct bsgrp_node
*)rn
->info
;
3204 char grp_str
[PREFIX_STRLEN
];
3206 prefix2str(&bsgrp
->group
, grp_str
, sizeof(grp_str
));
3209 json_object_object_get_ex(json
, grp_str
, &json_group
);
3211 json_group
= json_object_new_object();
3212 json_object_object_add(json
, grp_str
,
3216 vty_out(vty
, "Group Address %s\n", grp_str
);
3217 vty_out(vty
, "--------------------------\n");
3218 vty_out(vty
, "%-15s %-15s %-15s %-15s\n", "Rp Address",
3219 "priority", "Holdtime", "Hash");
3221 vty_out(vty
, "(ACTIVE)\n");
3224 if (bsgrp
->bsrp_list
) {
3225 for (ALL_LIST_ELEMENTS_RO(bsgrp
->bsrp_list
, rpnode
,
3227 char rp_str
[INET_ADDRSTRLEN
];
3229 pim_inet4_dump("<Rp Address?>",
3230 bsm_rp
->rp_address
, rp_str
,
3234 json_row
= json_object_new_object();
3235 json_object_string_add(
3236 json_row
, "Rp Address", rp_str
);
3237 json_object_int_add(
3238 json_row
, "Rp HoldTime",
3239 bsm_rp
->rp_holdtime
);
3240 json_object_int_add(json_row
,
3243 json_object_int_add(json_row
,
3246 json_object_object_add(
3247 json_group
, rp_str
, json_row
);
3251 "%-15s %-15u %-15u %-15u\n",
3252 rp_str
, bsm_rp
->rp_prio
,
3253 bsm_rp
->rp_holdtime
,
3257 if (!bsgrp
->bsrp_list
->count
&& !uj
)
3258 vty_out(vty
, "Active List is empty.\n");
3262 json_object_int_add(json_group
, "Pending RP count",
3263 bsgrp
->pend_rp_cnt
);
3265 vty_out(vty
, "(PENDING)\n");
3266 vty_out(vty
, "Pending RP count :%d\n",
3267 bsgrp
->pend_rp_cnt
);
3268 if (bsgrp
->pend_rp_cnt
)
3269 vty_out(vty
, "%-15s %-15s %-15s %-15s\n",
3270 "Rp Address", "priority", "Holdtime",
3274 if (bsgrp
->partial_bsrp_list
) {
3275 for (ALL_LIST_ELEMENTS_RO(bsgrp
->partial_bsrp_list
,
3277 char rp_str
[INET_ADDRSTRLEN
];
3279 pim_inet4_dump("<Rp Addr?>", bsm_rp
->rp_address
,
3280 rp_str
, sizeof(rp_str
));
3283 json_row
= json_object_new_object();
3284 json_object_string_add(
3285 json_row
, "Rp Address", rp_str
);
3286 json_object_int_add(
3287 json_row
, "Rp HoldTime",
3288 bsm_rp
->rp_holdtime
);
3289 json_object_int_add(json_row
,
3292 json_object_int_add(json_row
,
3295 json_object_object_add(
3296 json_group
, rp_str
, json_row
);
3299 "%-15s %-15u %-15u %-15u\n",
3300 rp_str
, bsm_rp
->rp_prio
,
3301 bsm_rp
->rp_holdtime
,
3305 if (!bsgrp
->partial_bsrp_list
->count
&& !uj
)
3306 vty_out(vty
, "Partial List is empty\n");
3314 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3315 json
, JSON_C_TO_STRING_PRETTY
));
3316 json_object_free(json
);
3320 /* pim statistics - just adding only bsm related now.
3321 * We can continue to add all pim related stats here.
3323 static void pim_show_statistics(struct pim_instance
*pim
, struct vty
*vty
,
3324 const char *ifname
, bool uj
)
3326 json_object
*json
= NULL
;
3327 struct interface
*ifp
;
3330 json
= json_object_new_object();
3331 json_object_int_add(json
, "bsmRx", pim
->bsm_rcvd
);
3332 json_object_int_add(json
, "bsmTx", pim
->bsm_sent
);
3333 json_object_int_add(json
, "bsmDropped", pim
->bsm_dropped
);
3335 vty_out(vty
, "BSM Statistics :\n");
3336 vty_out(vty
, "----------------\n");
3337 vty_out(vty
, "Number of Received BSMs : %" PRIu64
"\n",
3339 vty_out(vty
, "Number of Forwared BSMs : %" PRIu64
"\n",
3341 vty_out(vty
, "Number of Dropped BSMs : %" PRIu64
"\n",
3347 /* scan interfaces */
3348 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3349 struct pim_interface
*pim_ifp
= ifp
->info
;
3351 if (ifname
&& strcmp(ifname
, ifp
->name
))
3358 vty_out(vty
, "Interface : %s\n", ifp
->name
);
3359 vty_out(vty
, "-------------------\n");
3361 "Number of BSMs dropped due to config miss : %u\n",
3362 pim_ifp
->pim_ifstat_bsm_cfg_miss
);
3363 vty_out(vty
, "Number of unicast BSMs dropped : %u\n",
3364 pim_ifp
->pim_ifstat_ucast_bsm_cfg_miss
);
3366 "Number of BSMs dropped due to invalid scope zone : %u\n",
3367 pim_ifp
->pim_ifstat_bsm_invalid_sz
);
3370 json_object
*json_row
= NULL
;
3372 json_row
= json_object_new_object();
3374 json_object_string_add(json_row
, "If Name", ifp
->name
);
3375 json_object_int_add(json_row
, "bsmDroppedConfig",
3376 pim_ifp
->pim_ifstat_bsm_cfg_miss
);
3377 json_object_int_add(
3378 json_row
, "bsmDroppedUnicast",
3379 pim_ifp
->pim_ifstat_ucast_bsm_cfg_miss
);
3380 json_object_int_add(json_row
,
3381 "bsmDroppedInvalidScopeZone",
3382 pim_ifp
->pim_ifstat_bsm_invalid_sz
);
3383 json_object_object_add(json
, ifp
->name
, json_row
);
3389 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3390 json
, JSON_C_TO_STRING_PRETTY
));
3391 json_object_free(json
);
3395 static void clear_pim_statistics(struct pim_instance
*pim
)
3397 struct interface
*ifp
;
3401 pim
->bsm_dropped
= 0;
3403 /* scan interfaces */
3404 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3405 struct pim_interface
*pim_ifp
= ifp
->info
;
3410 pim_ifp
->pim_ifstat_bsm_cfg_miss
= 0;
3411 pim_ifp
->pim_ifstat_ucast_bsm_cfg_miss
= 0;
3412 pim_ifp
->pim_ifstat_bsm_invalid_sz
= 0;
3416 static void igmp_show_groups(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
3418 struct interface
*ifp
;
3420 json_object
*json
= NULL
;
3421 json_object
*json_iface
= NULL
;
3422 json_object
*json_row
= NULL
;
3424 now
= pim_time_monotonic_sec();
3427 json
= json_object_new_object();
3430 "Interface Address Group Mode Timer Srcs V Uptime \n");
3432 /* scan interfaces */
3433 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3434 struct pim_interface
*pim_ifp
= ifp
->info
;
3435 struct listnode
*sock_node
;
3436 struct igmp_sock
*igmp
;
3441 /* scan igmp sockets */
3442 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3444 char ifaddr_str
[INET_ADDRSTRLEN
];
3445 struct listnode
*grpnode
;
3446 struct igmp_group
*grp
;
3448 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3449 sizeof(ifaddr_str
));
3451 /* scan igmp groups */
3452 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3454 char group_str
[INET_ADDRSTRLEN
];
3458 pim_inet4_dump("<group?>", grp
->group_addr
,
3459 group_str
, sizeof(group_str
));
3460 pim_time_timer_to_hhmmss(hhmmss
, sizeof(hhmmss
),
3461 grp
->t_group_timer
);
3462 pim_time_uptime(uptime
, sizeof(uptime
),
3463 now
- grp
->group_creation
);
3466 json_object_object_get_ex(
3467 json
, ifp
->name
, &json_iface
);
3471 json_object_new_object();
3472 json_object_pim_ifp_add(
3474 json_object_object_add(
3479 json_row
= json_object_new_object();
3480 json_object_string_add(
3481 json_row
, "source", ifaddr_str
);
3482 json_object_string_add(
3483 json_row
, "group", group_str
);
3485 if (grp
->igmp_version
== 3)
3486 json_object_string_add(
3488 grp
->group_filtermode_isexcl
3492 json_object_string_add(json_row
,
3494 json_object_int_add(
3495 json_row
, "sourcesCount",
3496 grp
->group_source_list
3498 grp
->group_source_list
)
3500 json_object_int_add(json_row
, "version",
3502 json_object_string_add(
3503 json_row
, "uptime", uptime
);
3504 json_object_object_add(json_iface
,
3510 "%-16s %-15s %-15s %4s %8s %4d %d %8s\n",
3511 ifp
->name
, ifaddr_str
,
3513 grp
->igmp_version
== 3
3514 ? (grp
->group_filtermode_isexcl
3519 grp
->group_source_list
3521 grp
->group_source_list
)
3523 grp
->igmp_version
, uptime
);
3525 } /* scan igmp groups */
3526 } /* scan igmp sockets */
3527 } /* scan interfaces */
3530 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3531 json
, JSON_C_TO_STRING_PRETTY
));
3532 json_object_free(json
);
3536 static void igmp_show_group_retransmission(struct pim_instance
*pim
,
3539 struct interface
*ifp
;
3542 "Interface Address Group RetTimer Counter RetSrcs\n");
3544 /* scan interfaces */
3545 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3546 struct pim_interface
*pim_ifp
= ifp
->info
;
3547 struct listnode
*sock_node
;
3548 struct igmp_sock
*igmp
;
3553 /* scan igmp sockets */
3554 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3556 char ifaddr_str
[INET_ADDRSTRLEN
];
3557 struct listnode
*grpnode
;
3558 struct igmp_group
*grp
;
3560 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3561 sizeof(ifaddr_str
));
3563 /* scan igmp groups */
3564 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3566 char group_str
[INET_ADDRSTRLEN
];
3567 char grp_retr_mmss
[10];
3568 struct listnode
*src_node
;
3569 struct igmp_source
*src
;
3570 int grp_retr_sources
= 0;
3572 pim_inet4_dump("<group?>", grp
->group_addr
,
3573 group_str
, sizeof(group_str
));
3574 pim_time_timer_to_mmss(
3575 grp_retr_mmss
, sizeof(grp_retr_mmss
),
3576 grp
->t_group_query_retransmit_timer
);
3579 /* count group sources with retransmission state
3581 for (ALL_LIST_ELEMENTS_RO(
3582 grp
->group_source_list
, src_node
,
3584 if (src
->source_query_retransmit_count
3590 vty_out(vty
, "%-16s %-15s %-15s %-8s %7d %7d\n",
3591 ifp
->name
, ifaddr_str
, group_str
,
3593 grp
->group_specific_query_retransmit_count
,
3596 } /* scan igmp groups */
3597 } /* scan igmp sockets */
3598 } /* scan interfaces */
3601 static void igmp_show_sources(struct pim_instance
*pim
, struct vty
*vty
)
3603 struct interface
*ifp
;
3606 now
= pim_time_monotonic_sec();
3609 "Interface Address Group Source Timer Fwd Uptime \n");
3611 /* scan interfaces */
3612 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3613 struct pim_interface
*pim_ifp
= ifp
->info
;
3614 struct listnode
*sock_node
;
3615 struct igmp_sock
*igmp
;
3620 /* scan igmp sockets */
3621 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3623 char ifaddr_str
[INET_ADDRSTRLEN
];
3624 struct listnode
*grpnode
;
3625 struct igmp_group
*grp
;
3627 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3628 sizeof(ifaddr_str
));
3630 /* scan igmp groups */
3631 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3633 char group_str
[INET_ADDRSTRLEN
];
3634 struct listnode
*srcnode
;
3635 struct igmp_source
*src
;
3637 pim_inet4_dump("<group?>", grp
->group_addr
,
3638 group_str
, sizeof(group_str
));
3640 /* scan group sources */
3641 for (ALL_LIST_ELEMENTS_RO(
3642 grp
->group_source_list
, srcnode
,
3644 char source_str
[INET_ADDRSTRLEN
];
3649 "<source?>", src
->source_addr
,
3650 source_str
, sizeof(source_str
));
3652 pim_time_timer_to_mmss(
3654 src
->t_source_timer
);
3657 uptime
, sizeof(uptime
),
3658 now
- src
->source_creation
);
3661 "%-16s %-15s %-15s %-15s %5s %3s %8s\n",
3662 ifp
->name
, ifaddr_str
,
3663 group_str
, source_str
, mmss
,
3664 IGMP_SOURCE_TEST_FORWARDING(
3670 } /* scan group sources */
3671 } /* scan igmp groups */
3672 } /* scan igmp sockets */
3673 } /* scan interfaces */
3676 static void igmp_show_source_retransmission(struct pim_instance
*pim
,
3679 struct interface
*ifp
;
3682 "Interface Address Group Source Counter\n");
3684 /* scan interfaces */
3685 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3686 struct pim_interface
*pim_ifp
= ifp
->info
;
3687 struct listnode
*sock_node
;
3688 struct igmp_sock
*igmp
;
3693 /* scan igmp sockets */
3694 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3696 char ifaddr_str
[INET_ADDRSTRLEN
];
3697 struct listnode
*grpnode
;
3698 struct igmp_group
*grp
;
3700 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3701 sizeof(ifaddr_str
));
3703 /* scan igmp groups */
3704 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3706 char group_str
[INET_ADDRSTRLEN
];
3707 struct listnode
*srcnode
;
3708 struct igmp_source
*src
;
3710 pim_inet4_dump("<group?>", grp
->group_addr
,
3711 group_str
, sizeof(group_str
));
3713 /* scan group sources */
3714 for (ALL_LIST_ELEMENTS_RO(
3715 grp
->group_source_list
, srcnode
,
3717 char source_str
[INET_ADDRSTRLEN
];
3720 "<source?>", src
->source_addr
,
3721 source_str
, sizeof(source_str
));
3724 "%-16s %-15s %-15s %-15s %7d\n",
3725 ifp
->name
, ifaddr_str
,
3726 group_str
, source_str
,
3727 src
->source_query_retransmit_count
);
3729 } /* scan group sources */
3730 } /* scan igmp groups */
3731 } /* scan igmp sockets */
3732 } /* scan interfaces */
3735 static void pim_show_bsr(struct pim_instance
*pim
,
3740 char last_bsm_seen
[10];
3743 char bsr_str
[PREFIX_STRLEN
];
3744 json_object
*json
= NULL
;
3746 if (pim
->global_scope
.current_bsr
.s_addr
== INADDR_ANY
) {
3747 strlcpy(bsr_str
, "0.0.0.0", sizeof(bsr_str
));
3748 pim_time_uptime(uptime
, sizeof(uptime
),
3749 pim
->global_scope
.current_bsr_first_ts
);
3750 pim_time_uptime(last_bsm_seen
, sizeof(last_bsm_seen
),
3751 pim
->global_scope
.current_bsr_last_ts
);
3755 pim_inet4_dump("<bsr?>", pim
->global_scope
.current_bsr
,
3756 bsr_str
, sizeof(bsr_str
));
3757 now
= pim_time_monotonic_sec();
3758 pim_time_uptime(uptime
, sizeof(uptime
),
3759 (now
- pim
->global_scope
.current_bsr_first_ts
));
3760 pim_time_uptime(last_bsm_seen
, sizeof(last_bsm_seen
),
3761 now
- pim
->global_scope
.current_bsr_last_ts
);
3764 switch (pim
->global_scope
.state
) {
3766 strlcpy(bsr_state
, "NO_INFO", sizeof(bsr_state
));
3769 strlcpy(bsr_state
, "ACCEPT_ANY", sizeof(bsr_state
));
3771 case ACCEPT_PREFERRED
:
3772 strlcpy(bsr_state
, "ACCEPT_PREFERRED", sizeof(bsr_state
));
3775 strlcpy(bsr_state
, "", sizeof(bsr_state
));
3779 json
= json_object_new_object();
3780 json_object_string_add(json
, "bsr", bsr_str
);
3781 json_object_int_add(json
, "priority",
3782 pim
->global_scope
.current_bsr_prio
);
3783 json_object_int_add(json
, "fragmentTag",
3784 pim
->global_scope
.bsm_frag_tag
);
3785 json_object_string_add(json
, "state", bsr_state
);
3786 json_object_string_add(json
, "upTime", uptime
);
3787 json_object_string_add(json
, "lastBsmSeen", last_bsm_seen
);
3791 vty_out(vty
, "PIMv2 Bootstrap information\n");
3792 vty_out(vty
, "Current preferred BSR address: %s\n", bsr_str
);
3794 "Priority Fragment-Tag State UpTime\n");
3795 vty_out(vty
, " %-12d %-12d %-13s %7s\n",
3796 pim
->global_scope
.current_bsr_prio
,
3797 pim
->global_scope
.bsm_frag_tag
,
3800 vty_out(vty
, "Last BSM seen: %s\n", last_bsm_seen
);
3804 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3805 json
, JSON_C_TO_STRING_PRETTY
));
3806 json_object_free(json
);
3810 static void clear_igmp_interfaces(struct pim_instance
*pim
)
3812 struct interface
*ifp
;
3814 FOR_ALL_INTERFACES (pim
->vrf
, ifp
)
3815 pim_if_addr_del_all_igmp(ifp
);
3817 FOR_ALL_INTERFACES (pim
->vrf
, ifp
)
3818 pim_if_addr_add_all(ifp
);
3821 static void clear_pim_interfaces(struct pim_instance
*pim
)
3823 struct interface
*ifp
;
3825 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3827 pim_neighbor_delete_all(ifp
, "interface cleared");
3832 static void clear_interfaces(struct pim_instance
*pim
)
3834 clear_igmp_interfaces(pim
);
3835 clear_pim_interfaces(pim
);
3838 #define PIM_GET_PIM_INTERFACE(pim_ifp, ifp) \
3839 pim_ifp = ifp->info; \
3842 "%% Enable PIM and/or IGMP on this interface first\n"); \
3843 return CMD_WARNING_CONFIG_FAILED; \
3846 DEFUN (clear_ip_interfaces
,
3847 clear_ip_interfaces_cmd
,
3848 "clear ip interfaces [vrf NAME]",
3851 "Reset interfaces\n"
3855 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3860 clear_interfaces(vrf
->info
);
3865 DEFUN (clear_ip_igmp_interfaces
,
3866 clear_ip_igmp_interfaces_cmd
,
3867 "clear ip igmp [vrf NAME] interfaces",
3872 "Reset IGMP interfaces\n")
3875 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3880 clear_igmp_interfaces(vrf
->info
);
3885 DEFUN (clear_ip_pim_statistics
,
3886 clear_ip_pim_statistics_cmd
,
3887 "clear ip pim statistics [vrf NAME]",
3892 "Reset PIM statistics\n")
3895 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3900 clear_pim_statistics(vrf
->info
);
3904 static void clear_mroute(struct pim_instance
*pim
)
3906 struct pim_upstream
*up
;
3907 struct interface
*ifp
;
3909 /* scan interfaces */
3910 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3911 struct pim_interface
*pim_ifp
= ifp
->info
;
3912 struct listnode
*sock_node
;
3913 struct igmp_sock
*igmp
;
3914 struct pim_ifchannel
*ch
;
3919 /* deleting all ifchannels */
3920 while (!RB_EMPTY(pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
)) {
3921 ch
= RB_ROOT(pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
);
3923 pim_ifchannel_delete(ch
);
3926 /* clean up all igmp groups */
3927 /* scan igmp sockets */
3928 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3931 struct igmp_group
*grp
;
3933 if (igmp
->igmp_group_list
) {
3934 while (igmp
->igmp_group_list
->count
) {
3935 grp
= listnode_head(
3936 igmp
->igmp_group_list
);
3937 igmp_group_delete(grp
);
3944 /* clean up all upstreams*/
3945 while ((up
= rb_pim_upstream_first(&pim
->upstream_head
))) {
3946 pim_upstream_del(pim
, up
, __func__
);
3950 DEFUN (clear_ip_mroute
,
3951 clear_ip_mroute_cmd
,
3952 "clear ip mroute [vrf NAME]",
3955 "Reset multicast routes\n"
3959 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3964 clear_mroute(vrf
->info
);
3969 DEFUN (clear_ip_pim_interfaces
,
3970 clear_ip_pim_interfaces_cmd
,
3971 "clear ip pim [vrf NAME] interfaces",
3976 "Reset PIM interfaces\n")
3979 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3984 clear_pim_interfaces(vrf
->info
);
3989 DEFUN (clear_ip_pim_interface_traffic
,
3990 clear_ip_pim_interface_traffic_cmd
,
3991 "clear ip pim [vrf NAME] interface traffic",
3994 "PIM clear commands\n"
3996 "Reset PIM interfaces\n"
3997 "Reset Protocol Packet counters\n")
4000 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4001 struct interface
*ifp
= NULL
;
4002 struct pim_interface
*pim_ifp
= NULL
;
4007 FOR_ALL_INTERFACES (vrf
, ifp
) {
4008 pim_ifp
= ifp
->info
;
4013 pim_ifp
->pim_ifstat_hello_recv
= 0;
4014 pim_ifp
->pim_ifstat_hello_sent
= 0;
4015 pim_ifp
->pim_ifstat_join_recv
= 0;
4016 pim_ifp
->pim_ifstat_join_send
= 0;
4017 pim_ifp
->pim_ifstat_prune_recv
= 0;
4018 pim_ifp
->pim_ifstat_prune_send
= 0;
4019 pim_ifp
->pim_ifstat_reg_recv
= 0;
4020 pim_ifp
->pim_ifstat_reg_send
= 0;
4021 pim_ifp
->pim_ifstat_reg_stop_recv
= 0;
4022 pim_ifp
->pim_ifstat_reg_stop_send
= 0;
4023 pim_ifp
->pim_ifstat_assert_recv
= 0;
4024 pim_ifp
->pim_ifstat_assert_send
= 0;
4025 pim_ifp
->pim_ifstat_bsm_rx
= 0;
4026 pim_ifp
->pim_ifstat_bsm_tx
= 0;
4032 DEFUN (clear_ip_pim_oil
,
4033 clear_ip_pim_oil_cmd
,
4034 "clear ip pim [vrf NAME] oil",
4039 "Rescan PIM OIL (output interface list)\n")
4042 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4047 pim_scan_oil(vrf
->info
);
4052 DEFUN (show_ip_igmp_interface
,
4053 show_ip_igmp_interface_cmd
,
4054 "show ip igmp [vrf NAME] interface [detail|WORD] [json]",
4059 "IGMP interface information\n"
4065 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4066 bool uj
= use_json(argc
, argv
);
4071 if (argv_find(argv
, argc
, "detail", &idx
)
4072 || argv_find(argv
, argc
, "WORD", &idx
))
4073 igmp_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
4075 igmp_show_interfaces(vrf
->info
, vty
, uj
);
4080 DEFUN (show_ip_igmp_interface_vrf_all
,
4081 show_ip_igmp_interface_vrf_all_cmd
,
4082 "show ip igmp vrf all interface [detail|WORD] [json]",
4087 "IGMP interface information\n"
4093 bool uj
= use_json(argc
, argv
);
4099 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4103 vty_out(vty
, " \"%s\": ", vrf
->name
);
4106 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4107 if (argv_find(argv
, argc
, "detail", &idx
)
4108 || argv_find(argv
, argc
, "WORD", &idx
))
4109 igmp_show_interfaces_single(vrf
->info
, vty
,
4110 argv
[idx
]->arg
, uj
);
4112 igmp_show_interfaces(vrf
->info
, vty
, uj
);
4115 vty_out(vty
, "}\n");
4120 DEFUN (show_ip_igmp_join
,
4121 show_ip_igmp_join_cmd
,
4122 "show ip igmp [vrf NAME] join",
4127 "IGMP static join information\n")
4130 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4135 igmp_show_interface_join(vrf
->info
, vty
);
4140 DEFUN (show_ip_igmp_join_vrf_all
,
4141 show_ip_igmp_join_vrf_all_cmd
,
4142 "show ip igmp vrf all join",
4147 "IGMP static join information\n")
4149 bool uj
= use_json(argc
, argv
);
4155 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4159 vty_out(vty
, " \"%s\": ", vrf
->name
);
4162 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4163 igmp_show_interface_join(vrf
->info
, vty
);
4166 vty_out(vty
, "}\n");
4171 DEFUN (show_ip_igmp_groups
,
4172 show_ip_igmp_groups_cmd
,
4173 "show ip igmp [vrf NAME] groups [json]",
4182 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4183 bool uj
= use_json(argc
, argv
);
4188 igmp_show_groups(vrf
->info
, vty
, uj
);
4193 DEFUN (show_ip_igmp_groups_vrf_all
,
4194 show_ip_igmp_groups_vrf_all_cmd
,
4195 "show ip igmp vrf all groups [json]",
4203 bool uj
= use_json(argc
, argv
);
4209 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4213 vty_out(vty
, " \"%s\": ", vrf
->name
);
4216 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4217 igmp_show_groups(vrf
->info
, vty
, uj
);
4220 vty_out(vty
, "}\n");
4225 DEFUN (show_ip_igmp_groups_retransmissions
,
4226 show_ip_igmp_groups_retransmissions_cmd
,
4227 "show ip igmp [vrf NAME] groups retransmissions",
4233 "IGMP group retransmissions\n")
4236 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4241 igmp_show_group_retransmission(vrf
->info
, vty
);
4246 DEFUN (show_ip_igmp_sources
,
4247 show_ip_igmp_sources_cmd
,
4248 "show ip igmp [vrf NAME] sources",
4256 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4261 igmp_show_sources(vrf
->info
, vty
);
4266 DEFUN (show_ip_igmp_sources_retransmissions
,
4267 show_ip_igmp_sources_retransmissions_cmd
,
4268 "show ip igmp [vrf NAME] sources retransmissions",
4274 "IGMP source retransmissions\n")
4277 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4282 igmp_show_source_retransmission(vrf
->info
, vty
);
4287 DEFUN (show_ip_igmp_statistics
,
4288 show_ip_igmp_statistics_cmd
,
4289 "show ip igmp [vrf NAME] statistics [interface WORD] [json]",
4300 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4301 bool uj
= use_json(argc
, argv
);
4306 if (argv_find(argv
, argc
, "WORD", &idx
))
4307 igmp_show_statistics(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
4309 igmp_show_statistics(vrf
->info
, vty
, NULL
, uj
);
4314 DEFUN (show_ip_pim_mlag_summary
,
4315 show_ip_pim_mlag_summary_cmd
,
4316 "show ip pim mlag summary [json]",
4321 "status and stats\n"
4324 bool uj
= use_json(argc
, argv
);
4325 char role_buf
[MLAG_ROLE_STRSIZE
];
4326 char addr_buf
[INET_ADDRSTRLEN
];
4329 json_object
*json
= NULL
;
4330 json_object
*json_stat
= NULL
;
4332 json
= json_object_new_object();
4333 if (router
->mlag_flags
& PIM_MLAGF_LOCAL_CONN_UP
)
4334 json_object_boolean_true_add(json
, "mlagConnUp");
4335 if (router
->mlag_flags
& PIM_MLAGF_PEER_CONN_UP
)
4336 json_object_boolean_true_add(json
, "mlagPeerConnUp");
4337 if (router
->mlag_flags
& PIM_MLAGF_PEER_ZEBRA_UP
)
4338 json_object_boolean_true_add(json
, "mlagPeerZebraUp");
4339 json_object_string_add(json
, "mlagRole",
4340 mlag_role2str(router
->mlag_role
,
4341 role_buf
, sizeof(role_buf
)));
4342 inet_ntop(AF_INET
, &router
->local_vtep_ip
,
4343 addr_buf
, INET_ADDRSTRLEN
);
4344 json_object_string_add(json
, "localVtepIp", addr_buf
);
4345 inet_ntop(AF_INET
, &router
->anycast_vtep_ip
,
4346 addr_buf
, INET_ADDRSTRLEN
);
4347 json_object_string_add(json
, "anycastVtepIp", addr_buf
);
4348 json_object_string_add(json
, "peerlinkRif",
4349 router
->peerlink_rif
);
4351 json_stat
= json_object_new_object();
4352 json_object_int_add(json_stat
, "mlagConnFlaps",
4353 router
->mlag_stats
.mlagd_session_downs
);
4354 json_object_int_add(json_stat
, "mlagPeerConnFlaps",
4355 router
->mlag_stats
.peer_session_downs
);
4356 json_object_int_add(json_stat
, "mlagPeerZebraFlaps",
4357 router
->mlag_stats
.peer_zebra_downs
);
4358 json_object_int_add(json_stat
, "mrouteAddRx",
4359 router
->mlag_stats
.msg
.mroute_add_rx
);
4360 json_object_int_add(json_stat
, "mrouteAddTx",
4361 router
->mlag_stats
.msg
.mroute_add_tx
);
4362 json_object_int_add(json_stat
, "mrouteDelRx",
4363 router
->mlag_stats
.msg
.mroute_del_rx
);
4364 json_object_int_add(json_stat
, "mrouteDelTx",
4365 router
->mlag_stats
.msg
.mroute_del_tx
);
4366 json_object_int_add(json_stat
, "mlagStatusUpdates",
4367 router
->mlag_stats
.msg
.mlag_status_updates
);
4368 json_object_int_add(json_stat
, "peerZebraStatusUpdates",
4369 router
->mlag_stats
.msg
.peer_zebra_status_updates
);
4370 json_object_int_add(json_stat
, "pimStatusUpdates",
4371 router
->mlag_stats
.msg
.pim_status_updates
);
4372 json_object_int_add(json_stat
, "vxlanUpdates",
4373 router
->mlag_stats
.msg
.vxlan_updates
);
4374 json_object_object_add(json
, "connStats", json_stat
);
4376 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4377 json
, JSON_C_TO_STRING_PRETTY
));
4378 json_object_free(json
);
4382 vty_out(vty
, "MLAG daemon connection: %s\n",
4383 (router
->mlag_flags
& PIM_MLAGF_LOCAL_CONN_UP
)
4385 vty_out(vty
, "MLAG peer state: %s\n",
4386 (router
->mlag_flags
& PIM_MLAGF_PEER_CONN_UP
)
4388 vty_out(vty
, "Zebra peer state: %s\n",
4389 (router
->mlag_flags
& PIM_MLAGF_PEER_ZEBRA_UP
)
4391 vty_out(vty
, "MLAG role: %s\n",
4392 mlag_role2str(router
->mlag_role
, role_buf
, sizeof(role_buf
)));
4393 inet_ntop(AF_INET
, &router
->local_vtep_ip
,
4394 addr_buf
, INET_ADDRSTRLEN
);
4395 vty_out(vty
, "Local VTEP IP: %s\n", addr_buf
);
4396 inet_ntop(AF_INET
, &router
->anycast_vtep_ip
,
4397 addr_buf
, INET_ADDRSTRLEN
);
4398 vty_out(vty
, "Anycast VTEP IP: %s\n", addr_buf
);
4399 vty_out(vty
, "Peerlink: %s\n", router
->peerlink_rif
);
4400 vty_out(vty
, "Session flaps: mlagd: %d mlag-peer: %d zebra-peer: %d\n",
4401 router
->mlag_stats
.mlagd_session_downs
,
4402 router
->mlag_stats
.peer_session_downs
,
4403 router
->mlag_stats
.peer_zebra_downs
);
4404 vty_out(vty
, "Message Statistics:\n");
4405 vty_out(vty
, " mroute adds: rx: %d, tx: %d\n",
4406 router
->mlag_stats
.msg
.mroute_add_rx
,
4407 router
->mlag_stats
.msg
.mroute_add_tx
);
4408 vty_out(vty
, " mroute dels: rx: %d, tx: %d\n",
4409 router
->mlag_stats
.msg
.mroute_del_rx
,
4410 router
->mlag_stats
.msg
.mroute_del_tx
);
4411 vty_out(vty
, " peer zebra status updates: %d\n",
4412 router
->mlag_stats
.msg
.peer_zebra_status_updates
);
4413 vty_out(vty
, " PIM status updates: %d\n",
4414 router
->mlag_stats
.msg
.pim_status_updates
);
4415 vty_out(vty
, " VxLAN updates: %d\n",
4416 router
->mlag_stats
.msg
.vxlan_updates
);
4421 DEFUN (show_ip_pim_assert
,
4422 show_ip_pim_assert_cmd
,
4423 "show ip pim [vrf NAME] assert",
4428 "PIM interface assert\n")
4431 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4436 pim_show_assert(vrf
->info
, vty
);
4441 DEFUN (show_ip_pim_assert_internal
,
4442 show_ip_pim_assert_internal_cmd
,
4443 "show ip pim [vrf NAME] assert-internal",
4448 "PIM interface internal assert state\n")
4451 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4456 pim_show_assert_internal(vrf
->info
, vty
);
4461 DEFUN (show_ip_pim_assert_metric
,
4462 show_ip_pim_assert_metric_cmd
,
4463 "show ip pim [vrf NAME] assert-metric",
4468 "PIM interface assert metric\n")
4471 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4476 pim_show_assert_metric(vrf
->info
, vty
);
4481 DEFUN (show_ip_pim_assert_winner_metric
,
4482 show_ip_pim_assert_winner_metric_cmd
,
4483 "show ip pim [vrf NAME] assert-winner-metric",
4488 "PIM interface assert winner metric\n")
4491 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4496 pim_show_assert_winner_metric(vrf
->info
, vty
);
4501 DEFUN (show_ip_pim_interface
,
4502 show_ip_pim_interface_cmd
,
4503 "show ip pim [mlag] [vrf NAME] interface [detail|WORD] [json]",
4509 "PIM interface information\n"
4515 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4516 bool uj
= use_json(argc
, argv
);
4522 if (argv_find(argv
, argc
, "mlag", &idx
))
4525 if (argv_find(argv
, argc
, "WORD", &idx
)
4526 || argv_find(argv
, argc
, "detail", &idx
))
4527 pim_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, mlag
,
4530 pim_show_interfaces(vrf
->info
, vty
, mlag
, uj
);
4535 DEFUN (show_ip_pim_interface_vrf_all
,
4536 show_ip_pim_interface_vrf_all_cmd
,
4537 "show ip pim [mlag] vrf all interface [detail|WORD] [json]",
4543 "PIM interface information\n"
4549 bool uj
= use_json(argc
, argv
);
4554 if (argv_find(argv
, argc
, "mlag", &idx
))
4560 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4564 vty_out(vty
, " \"%s\": ", vrf
->name
);
4567 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4568 if (argv_find(argv
, argc
, "WORD", &idx
)
4569 || argv_find(argv
, argc
, "detail", &idx
))
4570 pim_show_interfaces_single(vrf
->info
, vty
,
4571 argv
[idx
]->arg
, mlag
, uj
);
4573 pim_show_interfaces(vrf
->info
, vty
, mlag
, uj
);
4576 vty_out(vty
, "}\n");
4581 DEFPY (show_ip_pim_join
,
4582 show_ip_pim_join_cmd
,
4583 "show ip pim [vrf NAME] join [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
4588 "PIM interface join information\n"
4589 "The Source or Group\n"
4593 struct prefix_sg sg
= {0};
4596 struct pim_instance
*pim
;
4598 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
4601 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
4604 pim
= pim_get_pim_instance(v
->vrf_id
);
4607 vty_out(vty
, "%% Unable to find pim instance\n");
4611 if (s_or_g
.s_addr
!= 0) {
4612 if (g
.s_addr
!= 0) {
4619 pim_show_join(pim
, vty
, &sg
, uj
);
4624 DEFUN (show_ip_pim_join_vrf_all
,
4625 show_ip_pim_join_vrf_all_cmd
,
4626 "show ip pim vrf all join [json]",
4631 "PIM interface join information\n"
4634 struct prefix_sg sg
= {0};
4635 bool uj
= use_json(argc
, argv
);
4641 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4645 vty_out(vty
, " \"%s\": ", vrf
->name
);
4648 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4649 pim_show_join(vrf
->info
, vty
, &sg
, uj
);
4652 vty_out(vty
, "}\n");
4657 static void pim_show_jp_agg_helper(struct vty
*vty
,
4658 struct interface
*ifp
,
4659 struct pim_neighbor
*neigh
,
4660 struct pim_upstream
*up
,
4663 char src_str
[INET_ADDRSTRLEN
];
4664 char grp_str
[INET_ADDRSTRLEN
];
4665 char rpf_str
[INET_ADDRSTRLEN
];
4667 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
4668 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
4669 /* pius->address.s_addr */
4670 pim_inet4_dump("<rpf?>", neigh
->source_addr
, rpf_str
, sizeof(rpf_str
));
4672 vty_out(vty
, "%-16s %-15s %-15s %-15s %5s\n",
4673 ifp
->name
, rpf_str
, src_str
,
4674 grp_str
, is_join
?"J":"P");
4677 static void pim_show_jp_agg_list(struct pim_instance
*pim
, struct vty
*vty
)
4679 struct interface
*ifp
;
4680 struct pim_interface
*pim_ifp
;
4681 struct listnode
*n_node
;
4682 struct pim_neighbor
*neigh
;
4683 struct listnode
*jag_node
;
4684 struct pim_jp_agg_group
*jag
;
4685 struct listnode
*js_node
;
4686 struct pim_jp_sources
*js
;
4689 "Interface RPF Nbr Source Group State\n");
4691 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
4692 pim_ifp
= ifp
->info
;
4696 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
,
4698 for (ALL_LIST_ELEMENTS_RO(neigh
->upstream_jp_agg
,
4700 for (ALL_LIST_ELEMENTS_RO(jag
->sources
,
4702 pim_show_jp_agg_helper(vty
,
4711 DEFPY (show_ip_pim_jp_agg
,
4712 show_ip_pim_jp_agg_cmd
,
4713 "show ip pim [vrf NAME] jp-agg",
4718 "join prune aggregation list\n")
4721 struct pim_instance
*pim
;
4723 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
4726 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
4729 pim
= pim_get_pim_instance(v
->vrf_id
);
4732 vty_out(vty
, "%% Unable to find pim instance\n");
4736 pim_show_jp_agg_list(pim
, vty
);
4741 DEFUN (show_ip_pim_local_membership
,
4742 show_ip_pim_local_membership_cmd
,
4743 "show ip pim [vrf NAME] local-membership [json]",
4748 "PIM interface local-membership\n"
4752 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4753 bool uj
= use_json(argc
, argv
);
4758 pim_show_membership(vrf
->info
, vty
, uj
);
4763 static void pim_show_mlag_up_entry_detail(struct vrf
*vrf
,
4764 struct vty
*vty
, struct pim_upstream
*up
,
4765 char *src_str
, char *grp_str
, json_object
*json
)
4768 json_object
*json_row
= NULL
;
4769 json_object
*own_list
= NULL
;
4770 json_object
*json_group
= NULL
;
4773 json_object_object_get_ex(json
, grp_str
, &json_group
);
4775 json_group
= json_object_new_object();
4776 json_object_object_add(json
, grp_str
,
4780 json_row
= json_object_new_object();
4781 json_object_string_add(json_row
, "source", src_str
);
4782 json_object_string_add(json_row
, "group", grp_str
);
4784 own_list
= json_object_new_array();
4785 if (pim_up_mlag_is_local(up
))
4786 json_object_array_add(own_list
,
4787 json_object_new_string("local"));
4788 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
))
4789 json_object_array_add(own_list
,
4790 json_object_new_string("peer"));
4791 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE
))
4792 json_object_array_add(
4793 own_list
, json_object_new_string("Interface"));
4794 json_object_object_add(json_row
, "owners", own_list
);
4796 json_object_int_add(json_row
, "localCost",
4797 pim_up_mlag_local_cost(up
));
4798 json_object_int_add(json_row
, "peerCost",
4799 pim_up_mlag_peer_cost(up
));
4800 if (PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up
->flags
))
4801 json_object_boolean_false_add(json_row
, "df");
4803 json_object_boolean_true_add(json_row
, "df");
4804 json_object_object_add(json_group
, src_str
, json_row
);
4809 if (pim_up_mlag_is_local(up
))
4810 strlcat(own_str
, "L", sizeof(own_str
));
4811 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
))
4812 strlcat(own_str
, "P", sizeof(own_str
));
4813 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE
))
4814 strlcat(own_str
, "I", sizeof(own_str
));
4815 /* XXX - fixup, print paragraph output */
4817 "%-15s %-15s %-6s %-11u %-10d %2s\n",
4818 src_str
, grp_str
, own_str
,
4819 pim_up_mlag_local_cost(up
),
4820 pim_up_mlag_peer_cost(up
),
4821 PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up
->flags
)
4826 static void pim_show_mlag_up_detail(struct vrf
*vrf
,
4827 struct vty
*vty
, const char *src_or_group
,
4828 const char *group
, bool uj
)
4830 char src_str
[INET_ADDRSTRLEN
];
4831 char grp_str
[INET_ADDRSTRLEN
];
4832 struct pim_upstream
*up
;
4833 struct pim_instance
*pim
= vrf
->info
;
4834 json_object
*json
= NULL
;
4837 json
= json_object_new_object();
4840 "Source Group Owner Local-cost Peer-cost DF\n");
4842 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
4843 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
)
4844 && !(up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE
)
4845 && !pim_up_mlag_is_local(up
))
4848 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
4849 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
4850 /* XXX: strcmps are clearly inefficient. we should do uint comps
4854 if (strcmp(src_str
, src_or_group
) ||
4855 strcmp(grp_str
, group
))
4858 if (strcmp(src_str
, src_or_group
) &&
4859 strcmp(grp_str
, src_or_group
))
4862 pim_show_mlag_up_entry_detail(vrf
, vty
, up
,
4863 src_str
, grp_str
, json
);
4867 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4868 json
, JSON_C_TO_STRING_PRETTY
));
4869 json_object_free(json
);
4873 static void pim_show_mlag_up_vrf(struct vrf
*vrf
, struct vty
*vty
, bool uj
)
4875 json_object
*json
= NULL
;
4876 json_object
*json_row
;
4877 struct pim_upstream
*up
;
4878 char src_str
[INET_ADDRSTRLEN
];
4879 char grp_str
[INET_ADDRSTRLEN
];
4880 struct pim_instance
*pim
= vrf
->info
;
4881 json_object
*json_group
= NULL
;
4884 json
= json_object_new_object();
4887 "Source Group Owner Local-cost Peer-cost DF\n");
4890 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
4891 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
)
4892 && !(up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE
)
4893 && !pim_up_mlag_is_local(up
))
4895 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
4896 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
4898 json_object
*own_list
= NULL
;
4900 json_object_object_get_ex(json
, grp_str
, &json_group
);
4902 json_group
= json_object_new_object();
4903 json_object_object_add(json
, grp_str
,
4907 json_row
= json_object_new_object();
4908 json_object_string_add(json_row
, "vrf", vrf
->name
);
4909 json_object_string_add(json_row
, "source", src_str
);
4910 json_object_string_add(json_row
, "group", grp_str
);
4912 own_list
= json_object_new_array();
4913 if (pim_up_mlag_is_local(up
)) {
4915 json_object_array_add(own_list
,
4916 json_object_new_string("local"));
4918 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
)) {
4919 json_object_array_add(own_list
,
4920 json_object_new_string("peer"));
4922 json_object_object_add(json_row
, "owners", own_list
);
4924 json_object_int_add(json_row
, "localCost",
4925 pim_up_mlag_local_cost(up
));
4926 json_object_int_add(json_row
, "peerCost",
4927 pim_up_mlag_peer_cost(up
));
4928 if (PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up
->flags
))
4929 json_object_boolean_false_add(json_row
, "df");
4931 json_object_boolean_true_add(json_row
, "df");
4932 json_object_object_add(json_group
, src_str
, json_row
);
4937 if (pim_up_mlag_is_local(up
))
4938 strlcat(own_str
, "L", sizeof(own_str
));
4939 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
))
4940 strlcat(own_str
, "P", sizeof(own_str
));
4941 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE
))
4942 strlcat(own_str
, "I", sizeof(own_str
));
4944 "%-15s %-15s %-6s %-11u %-10u %2s\n",
4945 src_str
, grp_str
, own_str
,
4946 pim_up_mlag_local_cost(up
),
4947 pim_up_mlag_peer_cost(up
),
4948 PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up
->flags
)
4953 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4954 json
, JSON_C_TO_STRING_PRETTY
));
4955 json_object_free(json
);
4959 static void pim_show_mlag_help_string(struct vty
*vty
, bool uj
)
4962 vty_out(vty
, "Owner codes:\n");
4964 "L: EVPN-MLAG Entry, I:PIM-MLAG Entry, "
4970 DEFUN(show_ip_pim_mlag_up
, show_ip_pim_mlag_up_cmd
,
4971 "show ip pim [vrf NAME] mlag upstream [A.B.C.D [A.B.C.D]] [json]",
4978 "Unicast or Multicast address\n"
4979 "Multicast address\n" JSON_STR
)
4981 const char *src_or_group
= NULL
;
4982 const char *group
= NULL
;
4984 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4985 bool uj
= use_json(argc
, argv
);
4987 if (!vrf
|| !vrf
->info
) {
4988 vty_out(vty
, "%s: VRF or Info missing\n", __func__
);
4995 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
4996 src_or_group
= argv
[idx
]->arg
;
4998 group
= argv
[idx
+ 1]->arg
;
5001 pim_show_mlag_help_string(vty
, uj
);
5004 pim_show_mlag_up_detail(vrf
, vty
, src_or_group
, group
, uj
);
5006 pim_show_mlag_up_vrf(vrf
, vty
, uj
);
5012 DEFUN(show_ip_pim_mlag_up_vrf_all
, show_ip_pim_mlag_up_vrf_all_cmd
,
5013 "show ip pim vrf all mlag upstream [json]",
5014 SHOW_STR IP_STR PIM_STR VRF_CMD_HELP_STR
5016 "upstream\n" JSON_STR
)
5019 bool uj
= use_json(argc
, argv
);
5021 pim_show_mlag_help_string(vty
, uj
);
5022 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5023 pim_show_mlag_up_vrf(vrf
, vty
, uj
);
5029 DEFUN (show_ip_pim_neighbor
,
5030 show_ip_pim_neighbor_cmd
,
5031 "show ip pim [vrf NAME] neighbor [detail|WORD] [json]",
5036 "PIM neighbor information\n"
5038 "Name of interface or neighbor\n"
5042 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5043 bool uj
= use_json(argc
, argv
);
5048 if (argv_find(argv
, argc
, "detail", &idx
)
5049 || argv_find(argv
, argc
, "WORD", &idx
))
5050 pim_show_neighbors_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
5052 pim_show_neighbors(vrf
->info
, vty
, uj
);
5057 DEFUN (show_ip_pim_neighbor_vrf_all
,
5058 show_ip_pim_neighbor_vrf_all_cmd
,
5059 "show ip pim vrf all neighbor [detail|WORD] [json]",
5064 "PIM neighbor information\n"
5066 "Name of interface or neighbor\n"
5070 bool uj
= use_json(argc
, argv
);
5076 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5080 vty_out(vty
, " \"%s\": ", vrf
->name
);
5083 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5084 if (argv_find(argv
, argc
, "detail", &idx
)
5085 || argv_find(argv
, argc
, "WORD", &idx
))
5086 pim_show_neighbors_single(vrf
->info
, vty
,
5087 argv
[idx
]->arg
, uj
);
5089 pim_show_neighbors(vrf
->info
, vty
, uj
);
5092 vty_out(vty
, "}\n");
5097 DEFUN (show_ip_pim_secondary
,
5098 show_ip_pim_secondary_cmd
,
5099 "show ip pim [vrf NAME] secondary",
5104 "PIM neighbor addresses\n")
5107 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5112 pim_show_neighbors_secondary(vrf
->info
, vty
);
5117 DEFUN (show_ip_pim_state
,
5118 show_ip_pim_state_cmd
,
5119 "show ip pim [vrf NAME] state [A.B.C.D [A.B.C.D]] [json]",
5124 "PIM state information\n"
5125 "Unicast or Multicast address\n"
5126 "Multicast address\n"
5129 const char *src_or_group
= NULL
;
5130 const char *group
= NULL
;
5132 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5133 bool uj
= use_json(argc
, argv
);
5141 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
5142 src_or_group
= argv
[idx
]->arg
;
5144 group
= argv
[idx
+ 1]->arg
;
5147 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
5152 DEFUN (show_ip_pim_state_vrf_all
,
5153 show_ip_pim_state_vrf_all_cmd
,
5154 "show ip pim vrf all state [A.B.C.D [A.B.C.D]] [json]",
5159 "PIM state information\n"
5160 "Unicast or Multicast address\n"
5161 "Multicast address\n"
5164 const char *src_or_group
= NULL
;
5165 const char *group
= NULL
;
5167 bool uj
= use_json(argc
, argv
);
5176 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
5177 src_or_group
= argv
[idx
]->arg
;
5179 group
= argv
[idx
+ 1]->arg
;
5182 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5186 vty_out(vty
, " \"%s\": ", vrf
->name
);
5189 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5190 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
5193 vty_out(vty
, "}\n");
5198 DEFPY (show_ip_pim_upstream
,
5199 show_ip_pim_upstream_cmd
,
5200 "show ip pim [vrf NAME] upstream [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
5205 "PIM upstream information\n"
5206 "The Source or Group\n"
5210 struct prefix_sg sg
= {0};
5213 struct pim_instance
*pim
;
5215 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
5218 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
5221 pim
= pim_get_pim_instance(v
->vrf_id
);
5224 vty_out(vty
, "%% Unable to find pim instance\n");
5228 if (s_or_g
.s_addr
!= 0) {
5229 if (g
.s_addr
!= 0) {
5235 pim_show_upstream(pim
, vty
, &sg
, uj
);
5240 DEFUN (show_ip_pim_upstream_vrf_all
,
5241 show_ip_pim_upstream_vrf_all_cmd
,
5242 "show ip pim vrf all upstream [json]",
5247 "PIM upstream information\n"
5250 struct prefix_sg sg
= {0};
5251 bool uj
= use_json(argc
, argv
);
5257 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5261 vty_out(vty
, " \"%s\": ", vrf
->name
);
5264 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5265 pim_show_upstream(vrf
->info
, vty
, &sg
, uj
);
5271 DEFUN (show_ip_pim_channel
,
5272 show_ip_pim_channel_cmd
,
5273 "show ip pim [vrf NAME] channel [json]",
5278 "PIM downstream channel info\n"
5282 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5283 bool uj
= use_json(argc
, argv
);
5288 pim_show_channel(vrf
->info
, vty
, uj
);
5293 DEFUN (show_ip_pim_upstream_join_desired
,
5294 show_ip_pim_upstream_join_desired_cmd
,
5295 "show ip pim [vrf NAME] upstream-join-desired [json]",
5300 "PIM upstream join-desired\n"
5304 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5305 bool uj
= use_json(argc
, argv
);
5310 pim_show_join_desired(vrf
->info
, vty
, uj
);
5315 DEFUN (show_ip_pim_upstream_rpf
,
5316 show_ip_pim_upstream_rpf_cmd
,
5317 "show ip pim [vrf NAME] upstream-rpf [json]",
5322 "PIM upstream source rpf\n"
5326 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5327 bool uj
= use_json(argc
, argv
);
5332 pim_show_upstream_rpf(vrf
->info
, vty
, uj
);
5337 DEFUN (show_ip_pim_rp
,
5339 "show ip pim [vrf NAME] rp-info [json]",
5344 "PIM RP information\n"
5348 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5349 bool uj
= use_json(argc
, argv
);
5354 pim_rp_show_information(vrf
->info
, vty
, uj
);
5359 DEFUN (show_ip_pim_rp_vrf_all
,
5360 show_ip_pim_rp_vrf_all_cmd
,
5361 "show ip pim vrf all rp-info [json]",
5366 "PIM RP information\n"
5369 bool uj
= use_json(argc
, argv
);
5375 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5379 vty_out(vty
, " \"%s\": ", vrf
->name
);
5382 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5383 pim_rp_show_information(vrf
->info
, vty
, uj
);
5386 vty_out(vty
, "}\n");
5391 DEFUN (show_ip_pim_rpf
,
5392 show_ip_pim_rpf_cmd
,
5393 "show ip pim [vrf NAME] rpf [json]",
5398 "PIM cached source rpf information\n"
5402 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5403 bool uj
= use_json(argc
, argv
);
5408 pim_show_rpf(vrf
->info
, vty
, uj
);
5413 DEFUN (show_ip_pim_rpf_vrf_all
,
5414 show_ip_pim_rpf_vrf_all_cmd
,
5415 "show ip pim vrf all rpf [json]",
5420 "PIM cached source rpf information\n"
5423 bool uj
= use_json(argc
, argv
);
5429 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5433 vty_out(vty
, " \"%s\": ", vrf
->name
);
5436 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5437 pim_show_rpf(vrf
->info
, vty
, uj
);
5440 vty_out(vty
, "}\n");
5445 DEFUN (show_ip_pim_nexthop
,
5446 show_ip_pim_nexthop_cmd
,
5447 "show ip pim [vrf NAME] nexthop",
5452 "PIM cached nexthop rpf information\n")
5455 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5460 pim_show_nexthop(vrf
->info
, vty
);
5465 DEFUN (show_ip_pim_nexthop_lookup
,
5466 show_ip_pim_nexthop_lookup_cmd
,
5467 "show ip pim [vrf NAME] nexthop-lookup A.B.C.D A.B.C.D",
5472 "PIM cached nexthop rpf lookup\n"
5473 "Source/RP address\n"
5474 "Multicast Group address\n")
5476 struct prefix nht_p
;
5478 struct in_addr src_addr
, grp_addr
;
5479 struct in_addr vif_source
;
5480 const char *addr_str
, *addr_str1
;
5482 struct pim_nexthop nexthop
;
5483 char nexthop_addr_str
[PREFIX_STRLEN
];
5484 char grp_str
[PREFIX_STRLEN
];
5486 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5491 argv_find(argv
, argc
, "A.B.C.D", &idx
);
5492 addr_str
= argv
[idx
]->arg
;
5493 result
= inet_pton(AF_INET
, addr_str
, &src_addr
);
5495 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
5496 errno
, safe_strerror(errno
));
5500 if (pim_is_group_224_4(src_addr
)) {
5502 "Invalid argument. Expected Valid Source Address.\n");
5506 addr_str1
= argv
[idx
+ 1]->arg
;
5507 result
= inet_pton(AF_INET
, addr_str1
, &grp_addr
);
5509 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
5510 errno
, safe_strerror(errno
));
5514 if (!pim_is_group_224_4(grp_addr
)) {
5516 "Invalid argument. Expected Valid Multicast Group Address.\n");
5520 if (!pim_rp_set_upstream_addr(vrf
->info
, &vif_source
, src_addr
,
5524 nht_p
.family
= AF_INET
;
5525 nht_p
.prefixlen
= IPV4_MAX_BITLEN
;
5526 nht_p
.u
.prefix4
= vif_source
;
5527 grp
.family
= AF_INET
;
5528 grp
.prefixlen
= IPV4_MAX_BITLEN
;
5529 grp
.u
.prefix4
= grp_addr
;
5530 memset(&nexthop
, 0, sizeof(nexthop
));
5532 result
= pim_ecmp_nexthop_lookup(vrf
->info
, &nexthop
, &nht_p
, &grp
, 0);
5536 "Nexthop Lookup failed, no usable routes returned.\n");
5540 pim_addr_dump("<grp?>", &grp
, grp_str
, sizeof(grp_str
));
5541 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
5542 nexthop_addr_str
, sizeof(nexthop_addr_str
));
5543 vty_out(vty
, "Group %s --- Nexthop %s Interface %s \n", grp_str
,
5544 nexthop_addr_str
, nexthop
.interface
->name
);
5549 DEFUN (show_ip_pim_interface_traffic
,
5550 show_ip_pim_interface_traffic_cmd
,
5551 "show ip pim [vrf NAME] interface traffic [WORD] [json]",
5556 "PIM interface information\n"
5557 "Protocol Packet counters\n"
5562 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5563 bool uj
= use_json(argc
, argv
);
5568 if (argv_find(argv
, argc
, "WORD", &idx
))
5569 pim_show_interface_traffic_single(vrf
->info
, vty
,
5570 argv
[idx
]->arg
, uj
);
5572 pim_show_interface_traffic(vrf
->info
, vty
, uj
);
5577 DEFUN (show_ip_pim_bsm_db
,
5578 show_ip_pim_bsm_db_cmd
,
5579 "show ip pim bsm-database [vrf NAME] [json]",
5583 "PIM cached bsm packets information\n"
5588 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5589 bool uj
= use_json(argc
, argv
);
5594 pim_show_bsm_db(vrf
->info
, vty
, uj
);
5598 DEFUN (show_ip_pim_bsrp
,
5599 show_ip_pim_bsrp_cmd
,
5600 "show ip pim bsrp-info [vrf NAME] [json]",
5604 "PIM cached group-rp mappings information\n"
5609 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5610 bool uj
= use_json(argc
, argv
);
5615 pim_show_group_rp_mappings_info(vrf
->info
, vty
, uj
);
5620 DEFUN (show_ip_pim_statistics
,
5621 show_ip_pim_statistics_cmd
,
5622 "show ip pim [vrf NAME] statistics [interface WORD] [json]",
5633 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5634 bool uj
= use_json(argc
, argv
);
5639 if (argv_find(argv
, argc
, "WORD", &idx
))
5640 pim_show_statistics(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
5642 pim_show_statistics(vrf
->info
, vty
, NULL
, uj
);
5647 static void show_multicast_interfaces(struct pim_instance
*pim
, struct vty
*vty
)
5649 struct interface
*ifp
;
5654 "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut\n");
5656 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
5657 struct pim_interface
*pim_ifp
;
5658 struct in_addr ifaddr
;
5659 struct sioc_vif_req vreq
;
5661 pim_ifp
= ifp
->info
;
5666 memset(&vreq
, 0, sizeof(vreq
));
5667 vreq
.vifi
= pim_ifp
->mroute_vif_index
;
5669 if (ioctl(pim
->mroute_socket
, SIOCGETVIFCNT
, &vreq
)) {
5671 "ioctl(SIOCGETVIFCNT=%lu) failure for interface %s vif_index=%d: errno=%d: %s",
5672 (unsigned long)SIOCGETVIFCNT
, ifp
->name
,
5673 pim_ifp
->mroute_vif_index
, errno
,
5674 safe_strerror(errno
));
5677 ifaddr
= pim_ifp
->primary_address
;
5679 vty_out(vty
, "%-16s %-15s %3d %3d %7lu %7lu %10lu %10lu\n",
5680 ifp
->name
, inet_ntoa(ifaddr
), ifp
->ifindex
,
5681 pim_ifp
->mroute_vif_index
, (unsigned long)vreq
.icount
,
5682 (unsigned long)vreq
.ocount
, (unsigned long)vreq
.ibytes
,
5683 (unsigned long)vreq
.obytes
);
5687 static void pim_cmd_show_ip_multicast_helper(struct pim_instance
*pim
,
5690 struct vrf
*vrf
= pim
->vrf
;
5691 time_t now
= pim_time_monotonic_sec();
5697 vty_out(vty
, "Router MLAG Role: %s\n",
5698 mlag_role2str(router
->mlag_role
, mlag_role
, sizeof(mlag_role
)));
5699 vty_out(vty
, "Mroute socket descriptor:");
5701 vty_out(vty
, " %d(%s)\n", pim
->mroute_socket
, vrf
->name
);
5703 pim_time_uptime(uptime
, sizeof(uptime
),
5704 now
- pim
->mroute_socket_creation
);
5705 vty_out(vty
, "Mroute socket uptime: %s\n", uptime
);
5709 pim_zebra_zclient_update(vty
);
5710 pim_zlookup_show_ip_multicast(vty
);
5713 vty_out(vty
, "Maximum highest VifIndex: %d\n", PIM_MAX_USABLE_VIFS
);
5716 vty_out(vty
, "Upstream Join Timer: %d secs\n", router
->t_periodic
);
5717 vty_out(vty
, "Join/Prune Holdtime: %d secs\n", PIM_JP_HOLDTIME
);
5718 vty_out(vty
, "PIM ECMP: %s\n", pim
->ecmp_enable
? "Enable" : "Disable");
5719 vty_out(vty
, "PIM ECMP Rebalance: %s\n",
5720 pim
->ecmp_rebalance_enable
? "Enable" : "Disable");
5724 show_rpf_refresh_stats(vty
, pim
, now
, NULL
);
5728 show_scan_oil_stats(pim
, vty
, now
);
5730 show_multicast_interfaces(pim
, vty
);
5733 DEFUN (show_ip_multicast
,
5734 show_ip_multicast_cmd
,
5735 "show ip multicast [vrf NAME]",
5739 "Multicast global information\n")
5742 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5747 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
5752 DEFUN (show_ip_multicast_vrf_all
,
5753 show_ip_multicast_vrf_all_cmd
,
5754 "show ip multicast vrf all",
5758 "Multicast global information\n")
5760 bool uj
= use_json(argc
, argv
);
5766 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5770 vty_out(vty
, " \"%s\": ", vrf
->name
);
5773 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5774 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
5777 vty_out(vty
, "}\n");
5782 static void show_mroute(struct pim_instance
*pim
, struct vty
*vty
,
5783 struct prefix_sg
*sg
, bool fill
, bool uj
)
5785 struct listnode
*node
;
5786 struct channel_oil
*c_oil
;
5787 struct static_route
*s_route
;
5789 json_object
*json
= NULL
;
5790 json_object
*json_group
= NULL
;
5791 json_object
*json_source
= NULL
;
5792 json_object
*json_oil
= NULL
;
5793 json_object
*json_ifp_out
= NULL
;
5796 char grp_str
[INET_ADDRSTRLEN
];
5797 char src_str
[INET_ADDRSTRLEN
];
5798 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
5799 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
5801 struct interface
*ifp_in
;
5803 char state_str
[PIM_REG_STATE_STR_LEN
];
5804 char mroute_uptime
[10];
5807 json
= json_object_new_object();
5809 vty_out(vty
, "IP Multicast Routing Table\n");
5810 vty_out(vty
, "Flags: S- Sparse, C - Connected, P - Pruned\n");
5812 " R - RP-bit set, F - Register flag, T - SPT-bit set\n");
5814 "\nSource Group Flags Proto Input Output TTL Uptime\n");
5817 now
= pim_time_monotonic_sec();
5819 /* print list of PIM and IGMP routes */
5820 frr_each (rb_pim_oil
, &pim
->channel_oil_head
, c_oil
) {
5823 if (!c_oil
->installed
&& !uj
)
5826 if (sg
->grp
.s_addr
!= 0 &&
5827 sg
->grp
.s_addr
!= c_oil
->oil
.mfcc_mcastgrp
.s_addr
)
5829 if (sg
->src
.s_addr
!= 0 &&
5830 sg
->src
.s_addr
!= c_oil
->oil
.mfcc_origin
.s_addr
)
5833 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
5835 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
5838 strlcpy(state_str
, "S", sizeof(state_str
));
5839 /* When a non DR receives a igmp join, it creates a (*,G)
5840 * channel_oil without any upstream creation */
5842 if (PIM_UPSTREAM_FLAG_TEST_SRC_IGMP(c_oil
->up
->flags
))
5843 strlcat(state_str
, "C", sizeof(state_str
));
5844 if (pim_upstream_is_sg_rpt(c_oil
->up
))
5845 strlcat(state_str
, "R", sizeof(state_str
));
5846 if (PIM_UPSTREAM_FLAG_TEST_FHR(c_oil
->up
->flags
))
5847 strlcat(state_str
, "F", sizeof(state_str
));
5848 if (c_oil
->up
->sptbit
== PIM_UPSTREAM_SPTBIT_TRUE
)
5849 strlcat(state_str
, "T", sizeof(state_str
));
5851 if (pim_channel_oil_empty(c_oil
))
5852 strlcat(state_str
, "P", sizeof(state_str
));
5854 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
5857 strlcpy(in_ifname
, ifp_in
->name
, sizeof(in_ifname
));
5859 strlcpy(in_ifname
, "<iif?>", sizeof(in_ifname
));
5862 pim_time_uptime(mroute_uptime
, sizeof(mroute_uptime
),
5863 now
- c_oil
->mroute_creation
);
5867 /* Find the group, create it if it doesn't exist */
5868 json_object_object_get_ex(json
, grp_str
, &json_group
);
5871 json_group
= json_object_new_object();
5872 json_object_object_add(json
, grp_str
,
5876 /* Find the source nested under the group, create it if
5879 json_object_object_get_ex(json_group
, src_str
,
5883 json_source
= json_object_new_object();
5884 json_object_object_add(json_group
, src_str
,
5888 /* Find the inbound interface nested under the source,
5889 * create it if it doesn't exist */
5890 json_object_int_add(json_source
, "installed",
5892 json_object_int_add(json_source
, "refCount",
5893 c_oil
->oil_ref_count
);
5894 json_object_int_add(json_source
, "oilSize",
5896 json_object_int_add(json_source
, "OilInheritedRescan",
5897 c_oil
->oil_inherited_rescan
);
5898 json_object_string_add(json_source
, "iif", in_ifname
);
5899 json_object_string_add(json_source
, "upTime",
5904 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
5906 struct interface
*ifp_out
;
5909 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
5913 /* do not display muted OIFs */
5914 if (c_oil
->oif_flags
[oif_vif_index
]
5915 & PIM_OIF_FLAG_MUTE
)
5918 if (c_oil
->oil
.mfcc_parent
== oif_vif_index
&&
5919 !pim_mroute_allow_iif_in_oil(c_oil
,
5923 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
5927 strlcpy(out_ifname
, ifp_out
->name
, sizeof(out_ifname
));
5929 strlcpy(out_ifname
, "<oif?>", sizeof(out_ifname
));
5932 json_ifp_out
= json_object_new_object();
5933 json_object_string_add(json_ifp_out
, "source",
5935 json_object_string_add(json_ifp_out
, "group",
5938 if (c_oil
->oif_flags
[oif_vif_index
]
5939 & PIM_OIF_FLAG_PROTO_PIM
)
5940 json_object_boolean_true_add(
5941 json_ifp_out
, "protocolPim");
5943 if (c_oil
->oif_flags
[oif_vif_index
]
5944 & PIM_OIF_FLAG_PROTO_IGMP
)
5945 json_object_boolean_true_add(
5946 json_ifp_out
, "protocolIgmp");
5948 if (c_oil
->oif_flags
[oif_vif_index
]
5949 & PIM_OIF_FLAG_PROTO_VXLAN
)
5950 json_object_boolean_true_add(
5951 json_ifp_out
, "protocolVxlan");
5953 if (c_oil
->oif_flags
[oif_vif_index
]
5954 & PIM_OIF_FLAG_PROTO_STAR
)
5955 json_object_boolean_true_add(
5957 "protocolInherited");
5959 json_object_string_add(json_ifp_out
,
5962 json_object_int_add(json_ifp_out
, "iVifI",
5963 c_oil
->oil
.mfcc_parent
);
5964 json_object_string_add(json_ifp_out
,
5965 "outboundInterface",
5967 json_object_int_add(json_ifp_out
, "oVifI",
5969 json_object_int_add(json_ifp_out
, "ttl", ttl
);
5970 json_object_string_add(json_ifp_out
, "upTime",
5973 json_oil
= json_object_new_object();
5974 json_object_object_add(json_source
,
5977 json_object_object_add(json_oil
, out_ifname
,
5980 if (c_oil
->oif_flags
[oif_vif_index
]
5981 & PIM_OIF_FLAG_PROTO_PIM
) {
5982 strlcpy(proto
, "PIM", sizeof(proto
));
5985 if (c_oil
->oif_flags
[oif_vif_index
]
5986 & PIM_OIF_FLAG_PROTO_IGMP
) {
5987 strlcpy(proto
, "IGMP", sizeof(proto
));
5990 if (c_oil
->oif_flags
[oif_vif_index
]
5991 & PIM_OIF_FLAG_PROTO_VXLAN
) {
5992 strlcpy(proto
, "VxLAN", sizeof(proto
));
5995 if (c_oil
->oif_flags
[oif_vif_index
]
5996 & PIM_OIF_FLAG_PROTO_STAR
) {
5997 strlcpy(proto
, "STAR", sizeof(proto
));
6001 "%-15s %-15s %-15s %-6s %-16s %-16s %-3d %8s\n",
6002 src_str
, grp_str
, state_str
, proto
,
6003 in_ifname
, out_ifname
, ttl
,
6009 in_ifname
[0] = '\0';
6010 state_str
[0] = '\0';
6011 mroute_uptime
[0] = '\0';
6017 if (!uj
&& !found_oif
) {
6019 "%-15s %-15s %-15s %-6s %-16s %-16s %-3d %8s\n",
6020 src_str
, grp_str
, state_str
, "none", in_ifname
,
6021 "none", 0, "--:--:--");
6025 /* Print list of static routes */
6026 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
6029 if (!s_route
->c_oil
.installed
)
6032 pim_inet4_dump("<group?>", s_route
->group
, grp_str
,
6034 pim_inet4_dump("<source?>", s_route
->source
, src_str
,
6036 ifp_in
= pim_if_find_by_vif_index(pim
, s_route
->iif
);
6040 strlcpy(in_ifname
, ifp_in
->name
, sizeof(in_ifname
));
6042 strlcpy(in_ifname
, "<iif?>", sizeof(in_ifname
));
6046 /* Find the group, create it if it doesn't exist */
6047 json_object_object_get_ex(json
, grp_str
, &json_group
);
6050 json_group
= json_object_new_object();
6051 json_object_object_add(json
, grp_str
,
6055 /* Find the source nested under the group, create it if
6056 * it doesn't exist */
6057 json_object_object_get_ex(json_group
, src_str
,
6061 json_source
= json_object_new_object();
6062 json_object_object_add(json_group
, src_str
,
6066 json_object_string_add(json_source
, "iif", in_ifname
);
6069 strlcpy(proto
, "STATIC", sizeof(proto
));
6072 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
6074 struct interface
*ifp_out
;
6075 char oif_uptime
[10];
6078 ttl
= s_route
->oif_ttls
[oif_vif_index
];
6082 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
6084 oif_uptime
, sizeof(oif_uptime
),
6087 .oif_creation
[oif_vif_index
]);
6091 strlcpy(out_ifname
, ifp_out
->name
, sizeof(out_ifname
));
6093 strlcpy(out_ifname
, "<oif?>", sizeof(out_ifname
));
6096 json_ifp_out
= json_object_new_object();
6097 json_object_string_add(json_ifp_out
, "source",
6099 json_object_string_add(json_ifp_out
, "group",
6101 json_object_boolean_true_add(json_ifp_out
,
6103 json_object_string_add(json_ifp_out
,
6106 json_object_int_add(
6107 json_ifp_out
, "iVifI",
6108 s_route
->c_oil
.oil
.mfcc_parent
);
6109 json_object_string_add(json_ifp_out
,
6110 "outboundInterface",
6112 json_object_int_add(json_ifp_out
, "oVifI",
6114 json_object_int_add(json_ifp_out
, "ttl", ttl
);
6115 json_object_string_add(json_ifp_out
, "upTime",
6118 json_oil
= json_object_new_object();
6119 json_object_object_add(json_source
,
6122 json_object_object_add(json_oil
, out_ifname
,
6126 "%-15s %-15s %-6s %-16s %-16s %-3d %8s %s\n",
6127 src_str
, grp_str
, proto
, in_ifname
,
6128 out_ifname
, ttl
, oif_uptime
,
6130 if (first
&& !fill
) {
6133 in_ifname
[0] = '\0';
6139 if (!uj
&& !found_oif
) {
6141 "%-15s %-15s %-6s %-16s %-16s %-3d %8s %s\n",
6142 src_str
, grp_str
, proto
, in_ifname
, "none", 0,
6143 "--:--:--", pim
->vrf
->name
);
6148 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
6149 json
, JSON_C_TO_STRING_PRETTY
));
6150 json_object_free(json
);
6154 DEFPY (show_ip_mroute
,
6156 "show ip mroute [vrf NAME] [A.B.C.D$s_or_g [A.B.C.D$g]] [fill$fill] [json$json]",
6161 "The Source or Group\n"
6163 "Fill in Assumed data\n"
6166 struct prefix_sg sg
= {0};
6167 struct pim_instance
*pim
;
6170 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
6173 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
6176 pim
= pim_get_pim_instance(v
->vrf_id
);
6179 vty_out(vty
, "%% Unable to find pim instance\n");
6183 if (s_or_g
.s_addr
!= 0) {
6184 if (g
.s_addr
!= 0) {
6190 show_mroute(pim
, vty
, &sg
, !!fill
, !!json
);
6194 DEFUN (show_ip_mroute_vrf_all
,
6195 show_ip_mroute_vrf_all_cmd
,
6196 "show ip mroute vrf all [fill] [json]",
6201 "Fill in Assumed data\n"
6204 struct prefix_sg sg
= {0};
6205 bool uj
= use_json(argc
, argv
);
6211 if (argv_find(argv
, argc
, "fill", &idx
))
6216 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
6220 vty_out(vty
, " \"%s\": ", vrf
->name
);
6223 vty_out(vty
, "VRF: %s\n", vrf
->name
);
6224 show_mroute(vrf
->info
, vty
, &sg
, fill
, uj
);
6227 vty_out(vty
, "}\n");
6232 DEFUN (clear_ip_mroute_count
,
6233 clear_ip_mroute_count_cmd
,
6234 "clear ip mroute [vrf NAME] count",
6239 "Route and packet count data\n")
6242 struct listnode
*node
;
6243 struct channel_oil
*c_oil
;
6244 struct static_route
*sr
;
6245 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6246 struct pim_instance
*pim
;
6252 frr_each(rb_pim_oil
, &pim
->channel_oil_head
, c_oil
) {
6253 if (!c_oil
->installed
)
6256 pim_mroute_update_counters(c_oil
);
6257 c_oil
->cc
.origpktcnt
= c_oil
->cc
.pktcnt
;
6258 c_oil
->cc
.origbytecnt
= c_oil
->cc
.bytecnt
;
6259 c_oil
->cc
.origwrong_if
= c_oil
->cc
.wrong_if
;
6262 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, sr
)) {
6263 if (!sr
->c_oil
.installed
)
6266 pim_mroute_update_counters(&sr
->c_oil
);
6268 sr
->c_oil
.cc
.origpktcnt
= sr
->c_oil
.cc
.pktcnt
;
6269 sr
->c_oil
.cc
.origbytecnt
= sr
->c_oil
.cc
.bytecnt
;
6270 sr
->c_oil
.cc
.origwrong_if
= sr
->c_oil
.cc
.wrong_if
;
6275 static void show_mroute_count(struct pim_instance
*pim
, struct vty
*vty
)
6277 struct listnode
*node
;
6278 struct channel_oil
*c_oil
;
6279 struct static_route
*sr
;
6284 "Source Group LastUsed Packets Bytes WrongIf \n");
6286 /* Print PIM and IGMP route counts */
6287 frr_each (rb_pim_oil
, &pim
->channel_oil_head
, c_oil
) {
6288 char group_str
[INET_ADDRSTRLEN
];
6289 char source_str
[INET_ADDRSTRLEN
];
6291 if (!c_oil
->installed
)
6294 pim_mroute_update_counters(c_oil
);
6296 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, group_str
,
6298 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, source_str
,
6299 sizeof(source_str
));
6301 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
6302 source_str
, group_str
, c_oil
->cc
.lastused
/ 100,
6303 c_oil
->cc
.pktcnt
- c_oil
->cc
.origpktcnt
,
6304 c_oil
->cc
.bytecnt
- c_oil
->cc
.origbytecnt
,
6305 c_oil
->cc
.wrong_if
- c_oil
->cc
.origwrong_if
);
6308 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, sr
)) {
6309 char group_str
[INET_ADDRSTRLEN
];
6310 char source_str
[INET_ADDRSTRLEN
];
6312 if (!sr
->c_oil
.installed
)
6315 pim_mroute_update_counters(&sr
->c_oil
);
6317 pim_inet4_dump("<group?>", sr
->c_oil
.oil
.mfcc_mcastgrp
,
6318 group_str
, sizeof(group_str
));
6319 pim_inet4_dump("<source?>", sr
->c_oil
.oil
.mfcc_origin
,
6320 source_str
, sizeof(source_str
));
6322 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
6323 source_str
, group_str
, sr
->c_oil
.cc
.lastused
,
6324 sr
->c_oil
.cc
.pktcnt
- sr
->c_oil
.cc
.origpktcnt
,
6325 sr
->c_oil
.cc
.bytecnt
- sr
->c_oil
.cc
.origbytecnt
,
6326 sr
->c_oil
.cc
.wrong_if
- sr
->c_oil
.cc
.origwrong_if
);
6330 DEFUN (show_ip_mroute_count
,
6331 show_ip_mroute_count_cmd
,
6332 "show ip mroute [vrf NAME] count",
6337 "Route and packet count data\n")
6340 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6345 show_mroute_count(vrf
->info
, vty
);
6349 DEFUN (show_ip_mroute_count_vrf_all
,
6350 show_ip_mroute_count_vrf_all_cmd
,
6351 "show ip mroute vrf all count",
6356 "Route and packet count data\n")
6358 bool uj
= use_json(argc
, argv
);
6364 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
6368 vty_out(vty
, " \"%s\": ", vrf
->name
);
6371 vty_out(vty
, "VRF: %s\n", vrf
->name
);
6372 show_mroute_count(vrf
->info
, vty
);
6375 vty_out(vty
, "}\n");
6380 static void show_mroute_summary(struct pim_instance
*pim
, struct vty
*vty
)
6382 struct listnode
*node
;
6383 struct channel_oil
*c_oil
;
6384 struct static_route
*s_route
;
6385 uint32_t starg_sw_mroute_cnt
= 0;
6386 uint32_t sg_sw_mroute_cnt
= 0;
6387 uint32_t starg_hw_mroute_cnt
= 0;
6388 uint32_t sg_hw_mroute_cnt
= 0;
6390 vty_out(vty
, "Mroute Type Installed/Total\n");
6392 frr_each (rb_pim_oil
, &pim
->channel_oil_head
, c_oil
) {
6393 if (!c_oil
->installed
) {
6394 if (c_oil
->oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
6395 starg_sw_mroute_cnt
++;
6399 if (c_oil
->oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
6400 starg_hw_mroute_cnt
++;
6406 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
6407 if (!s_route
->c_oil
.installed
) {
6408 if (s_route
->c_oil
.oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
6409 starg_sw_mroute_cnt
++;
6413 if (s_route
->c_oil
.oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
6414 starg_hw_mroute_cnt
++;
6420 vty_out(vty
, "%-20s %d/%d\n", "(*, G)", starg_hw_mroute_cnt
,
6421 starg_sw_mroute_cnt
+ starg_hw_mroute_cnt
);
6422 vty_out(vty
, "%-20s %d/%d\n", "(S, G)", sg_hw_mroute_cnt
,
6423 sg_sw_mroute_cnt
+ sg_hw_mroute_cnt
);
6424 vty_out(vty
, "------\n");
6425 vty_out(vty
, "%-20s %d/%d\n", "Total",
6426 (starg_hw_mroute_cnt
+ sg_hw_mroute_cnt
),
6427 (starg_sw_mroute_cnt
+
6428 starg_hw_mroute_cnt
+
6433 DEFUN (show_ip_mroute_summary
,
6434 show_ip_mroute_summary_cmd
,
6435 "show ip mroute [vrf NAME] summary",
6440 "Summary of all mroutes\n")
6443 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6448 show_mroute_summary(vrf
->info
, vty
);
6452 DEFUN (show_ip_mroute_summary_vrf_all
,
6453 show_ip_mroute_summary_vrf_all_cmd
,
6454 "show ip mroute vrf all summary",
6459 "Summary of all mroutes\n")
6463 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
6464 vty_out(vty
, "VRF: %s\n", vrf
->name
);
6465 show_mroute_summary(vrf
->info
, vty
);
6473 "show ip rib [vrf NAME] A.B.C.D",
6478 "Unicast address\n")
6481 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6482 struct in_addr addr
;
6483 const char *addr_str
;
6484 struct pim_nexthop nexthop
;
6485 char nexthop_addr_str
[PREFIX_STRLEN
];
6491 memset(&nexthop
, 0, sizeof(nexthop
));
6492 argv_find(argv
, argc
, "A.B.C.D", &idx
);
6493 addr_str
= argv
[idx
]->arg
;
6494 result
= inet_pton(AF_INET
, addr_str
, &addr
);
6496 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
6497 errno
, safe_strerror(errno
));
6501 if (!pim_nexthop_lookup(vrf
->info
, &nexthop
, addr
, 0)) {
6503 "Failure querying RIB nexthop for unicast address %s\n",
6509 "Address NextHop Interface Metric Preference\n");
6511 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
6512 nexthop_addr_str
, sizeof(nexthop_addr_str
));
6514 vty_out(vty
, "%-15s %-15s %-9s %6d %10d\n", addr_str
, nexthop_addr_str
,
6515 nexthop
.interface
? nexthop
.interface
->name
: "<ifname?>",
6516 nexthop
.mrib_route_metric
, nexthop
.mrib_metric_preference
);
6521 static void show_ssmpingd(struct pim_instance
*pim
, struct vty
*vty
)
6523 struct listnode
*node
;
6524 struct ssmpingd_sock
*ss
;
6528 "Source Socket Address Port Uptime Requests\n");
6530 if (!pim
->ssmpingd_list
)
6533 now
= pim_time_monotonic_sec();
6535 for (ALL_LIST_ELEMENTS_RO(pim
->ssmpingd_list
, node
, ss
)) {
6536 char source_str
[INET_ADDRSTRLEN
];
6538 struct sockaddr_in bind_addr
;
6539 socklen_t len
= sizeof(bind_addr
);
6540 char bind_addr_str
[INET_ADDRSTRLEN
];
6542 pim_inet4_dump("<src?>", ss
->source_addr
, source_str
,
6543 sizeof(source_str
));
6545 if (pim_socket_getsockname(
6546 ss
->sock_fd
, (struct sockaddr
*)&bind_addr
, &len
)) {
6548 "%% Failure reading socket name for ssmpingd source %s on fd=%d\n",
6549 source_str
, ss
->sock_fd
);
6552 pim_inet4_dump("<addr?>", bind_addr
.sin_addr
, bind_addr_str
,
6553 sizeof(bind_addr_str
));
6554 pim_time_uptime(ss_uptime
, sizeof(ss_uptime
),
6555 now
- ss
->creation
);
6557 vty_out(vty
, "%-15s %6d %-15s %5d %8s %8lld\n", source_str
,
6558 ss
->sock_fd
, bind_addr_str
, ntohs(bind_addr
.sin_port
),
6559 ss_uptime
, (long long)ss
->requests
);
6563 DEFUN (show_ip_ssmpingd
,
6564 show_ip_ssmpingd_cmd
,
6565 "show ip ssmpingd [vrf NAME]",
6572 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6577 show_ssmpingd(vrf
->info
, vty
);
6581 static int pim_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
6582 const char *rp
, const char *group
,
6587 result
= pim_rp_new_config(pim
, rp
, group
, plist
);
6589 if (result
== PIM_GROUP_BAD_ADDR_MASK_COMBO
) {
6590 vty_out(vty
, "%% Inconsistent address and mask: %s\n",
6592 return CMD_WARNING_CONFIG_FAILED
;
6595 if (result
== PIM_GROUP_BAD_ADDRESS
) {
6596 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
6597 return CMD_WARNING_CONFIG_FAILED
;
6600 if (result
== PIM_RP_BAD_ADDRESS
) {
6601 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
6602 return CMD_WARNING_CONFIG_FAILED
;
6605 if (result
== PIM_RP_NO_PATH
) {
6606 vty_out(vty
, "%% No Path to RP address specified: %s\n", rp
);
6610 if (result
== PIM_GROUP_OVERLAP
) {
6612 "%% Group range specified cannot exact match another\n");
6613 return CMD_WARNING_CONFIG_FAILED
;
6616 if (result
== PIM_GROUP_PFXLIST_OVERLAP
) {
6618 "%% This group is already covered by a RP prefix-list\n");
6619 return CMD_WARNING_CONFIG_FAILED
;
6622 if (result
== PIM_RP_PFXLIST_IN_USE
) {
6624 "%% The same prefix-list cannot be applied to multiple RPs\n");
6625 return CMD_WARNING_CONFIG_FAILED
;
6631 static int pim_cmd_spt_switchover(struct pim_instance
*pim
,
6632 enum pim_spt_switchover spt
,
6635 pim
->spt
.switchover
= spt
;
6637 switch (pim
->spt
.switchover
) {
6638 case PIM_SPT_IMMEDIATE
:
6639 XFREE(MTYPE_PIM_PLIST_NAME
, pim
->spt
.plist
);
6641 pim_upstream_add_lhr_star_pimreg(pim
);
6643 case PIM_SPT_INFINITY
:
6644 pim_upstream_remove_lhr_star_pimreg(pim
, plist
);
6646 XFREE(MTYPE_PIM_PLIST_NAME
, pim
->spt
.plist
);
6650 XSTRDUP(MTYPE_PIM_PLIST_NAME
, plist
);
6657 DEFUN (ip_pim_spt_switchover_infinity
,
6658 ip_pim_spt_switchover_infinity_cmd
,
6659 "ip pim spt-switchover infinity-and-beyond",
6663 "Never switch to SPT Tree\n")
6665 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6666 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, NULL
);
6669 DEFUN (ip_pim_spt_switchover_infinity_plist
,
6670 ip_pim_spt_switchover_infinity_plist_cmd
,
6671 "ip pim spt-switchover infinity-and-beyond prefix-list WORD",
6675 "Never switch to SPT Tree\n"
6676 "Prefix-List to control which groups to switch\n"
6677 "Prefix-List name\n")
6679 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6680 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, argv
[5]->arg
);
6683 DEFUN (no_ip_pim_spt_switchover_infinity
,
6684 no_ip_pim_spt_switchover_infinity_cmd
,
6685 "no ip pim spt-switchover infinity-and-beyond",
6690 "Never switch to SPT Tree\n")
6692 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6693 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
6696 DEFUN (no_ip_pim_spt_switchover_infinity_plist
,
6697 no_ip_pim_spt_switchover_infinity_plist_cmd
,
6698 "no ip pim spt-switchover infinity-and-beyond prefix-list WORD",
6703 "Never switch to SPT Tree\n"
6704 "Prefix-List to control which groups to switch\n"
6705 "Prefix-List name\n")
6707 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6708 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
6711 DEFPY (pim_register_accept_list
,
6712 pim_register_accept_list_cmd
,
6713 "[no] ip pim register-accept-list WORD$word",
6717 "Only accept registers from a specific source prefix list\n"
6718 "Prefix-List name\n")
6720 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6723 XFREE(MTYPE_PIM_PLIST_NAME
, pim
->register_plist
);
6725 XFREE(MTYPE_PIM_PLIST_NAME
, pim
->register_plist
);
6726 pim
->register_plist
= XSTRDUP(MTYPE_PIM_PLIST_NAME
, word
);
6731 DEFUN (ip_pim_joinprune_time
,
6732 ip_pim_joinprune_time_cmd
,
6733 "ip pim join-prune-interval (60-600)",
6735 "pim multicast routing\n"
6736 "Join Prune Send Interval\n"
6739 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6740 router
->t_periodic
= atoi(argv
[3]->arg
);
6744 DEFUN (no_ip_pim_joinprune_time
,
6745 no_ip_pim_joinprune_time_cmd
,
6746 "no ip pim join-prune-interval (60-600)",
6749 "pim multicast routing\n"
6750 "Join Prune Send Interval\n"
6753 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6754 router
->t_periodic
= PIM_DEFAULT_T_PERIODIC
;
6758 DEFUN (ip_pim_register_suppress
,
6759 ip_pim_register_suppress_cmd
,
6760 "ip pim register-suppress-time (5-60000)",
6762 "pim multicast routing\n"
6763 "Register Suppress Timer\n"
6766 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6767 router
->register_suppress_time
= atoi(argv
[3]->arg
);
6771 DEFUN (no_ip_pim_register_suppress
,
6772 no_ip_pim_register_suppress_cmd
,
6773 "no ip pim register-suppress-time (5-60000)",
6776 "pim multicast routing\n"
6777 "Register Suppress Timer\n"
6780 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6781 router
->register_suppress_time
= PIM_REGISTER_SUPPRESSION_TIME_DEFAULT
;
6785 DEFUN (ip_pim_rp_keep_alive
,
6786 ip_pim_rp_keep_alive_cmd
,
6787 "ip pim rp keep-alive-timer (31-60000)",
6789 "pim multicast routing\n"
6791 "Keep alive Timer\n"
6794 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6795 pim
->rp_keep_alive_time
= atoi(argv
[4]->arg
);
6799 DEFUN (no_ip_pim_rp_keep_alive
,
6800 no_ip_pim_rp_keep_alive_cmd
,
6801 "no ip pim rp keep-alive-timer (31-60000)",
6804 "pim multicast routing\n"
6806 "Keep alive Timer\n"
6809 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6810 pim
->rp_keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
6814 DEFUN (ip_pim_keep_alive
,
6815 ip_pim_keep_alive_cmd
,
6816 "ip pim keep-alive-timer (31-60000)",
6818 "pim multicast routing\n"
6819 "Keep alive Timer\n"
6822 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6823 pim
->keep_alive_time
= atoi(argv
[3]->arg
);
6827 DEFUN (no_ip_pim_keep_alive
,
6828 no_ip_pim_keep_alive_cmd
,
6829 "no ip pim keep-alive-timer (31-60000)",
6832 "pim multicast routing\n"
6833 "Keep alive Timer\n"
6836 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6837 pim
->keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
6841 DEFUN (ip_pim_packets
,
6843 "ip pim packets (1-100)",
6845 "pim multicast routing\n"
6846 "packets to process at one time per fd\n"
6847 "Number of packets\n")
6849 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6850 router
->packet_process
= atoi(argv
[3]->arg
);
6854 DEFUN (no_ip_pim_packets
,
6855 no_ip_pim_packets_cmd
,
6856 "no ip pim packets (1-100)",
6859 "pim multicast routing\n"
6860 "packets to process at one time per fd\n"
6861 "Number of packets\n")
6863 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6864 router
->packet_process
= PIM_DEFAULT_PACKET_PROCESS
;
6868 DEFUN (ip_pim_v6_secondary
,
6869 ip_pim_v6_secondary_cmd
,
6870 "ip pim send-v6-secondary",
6872 "pim multicast routing\n"
6873 "Send v6 secondary addresses\n")
6875 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6876 pim
->send_v6_secondary
= 1;
6881 DEFUN (no_ip_pim_v6_secondary
,
6882 no_ip_pim_v6_secondary_cmd
,
6883 "no ip pim send-v6-secondary",
6886 "pim multicast routing\n"
6887 "Send v6 secondary addresses\n")
6889 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6890 pim
->send_v6_secondary
= 0;
6897 "ip pim rp A.B.C.D [A.B.C.D/M]",
6899 "pim multicast routing\n"
6901 "ip address of RP\n"
6902 "Group Address range to cover\n")
6904 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6907 if (argc
== (idx_ipv4
+ 1))
6908 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
6911 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
6912 argv
[idx_ipv4
+ 1]->arg
, NULL
);
6915 DEFUN (ip_pim_rp_prefix_list
,
6916 ip_pim_rp_prefix_list_cmd
,
6917 "ip pim rp A.B.C.D prefix-list WORD",
6919 "pim multicast routing\n"
6921 "ip address of RP\n"
6922 "group prefix-list filter\n"
6923 "Name of a prefix-list\n")
6925 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6926 return pim_rp_cmd_worker(pim
, vty
, argv
[3]->arg
, NULL
, argv
[5]->arg
);
6929 static int pim_no_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
6930 const char *rp
, const char *group
,
6933 int result
= pim_rp_del_config(pim
, rp
, group
, plist
);
6935 if (result
== PIM_GROUP_BAD_ADDRESS
) {
6936 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
6937 return CMD_WARNING_CONFIG_FAILED
;
6940 if (result
== PIM_RP_BAD_ADDRESS
) {
6941 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
6942 return CMD_WARNING_CONFIG_FAILED
;
6945 if (result
== PIM_RP_NOT_FOUND
) {
6946 vty_out(vty
, "%% Unable to find specified RP\n");
6947 return CMD_WARNING_CONFIG_FAILED
;
6953 DEFUN (no_ip_pim_rp
,
6955 "no ip pim rp A.B.C.D [A.B.C.D/M]",
6958 "pim multicast routing\n"
6960 "ip address of RP\n"
6961 "Group Address range to cover\n")
6963 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6964 int idx_ipv4
= 4, idx_group
= 0;
6966 if (argv_find(argv
, argc
, "A.B.C.D/M", &idx_group
))
6967 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
6968 argv
[idx_group
]->arg
, NULL
);
6970 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
6974 DEFUN (no_ip_pim_rp_prefix_list
,
6975 no_ip_pim_rp_prefix_list_cmd
,
6976 "no ip pim rp A.B.C.D prefix-list WORD",
6979 "pim multicast routing\n"
6981 "ip address of RP\n"
6982 "group prefix-list filter\n"
6983 "Name of a prefix-list\n")
6985 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6986 return pim_no_rp_cmd_worker(pim
, vty
, argv
[4]->arg
, NULL
, argv
[6]->arg
);
6989 static int pim_ssm_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
6992 int result
= pim_ssm_range_set(pim
, pim
->vrf_id
, plist
);
6993 int ret
= CMD_WARNING_CONFIG_FAILED
;
6995 if (result
== PIM_SSM_ERR_NONE
)
6999 case PIM_SSM_ERR_NO_VRF
:
7000 vty_out(vty
, "%% VRF doesn't exist\n");
7002 case PIM_SSM_ERR_DUP
:
7003 vty_out(vty
, "%% duplicate config\n");
7007 vty_out(vty
, "%% ssm range config failed\n");
7013 DEFUN (ip_pim_ssm_prefix_list
,
7014 ip_pim_ssm_prefix_list_cmd
,
7015 "ip pim ssm prefix-list WORD",
7017 "pim multicast routing\n"
7018 "Source Specific Multicast\n"
7019 "group range prefix-list filter\n"
7020 "Name of a prefix-list\n")
7022 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7023 return pim_ssm_cmd_worker(pim
, vty
, argv
[4]->arg
);
7026 DEFUN (no_ip_pim_ssm_prefix_list
,
7027 no_ip_pim_ssm_prefix_list_cmd
,
7028 "no ip pim ssm prefix-list",
7031 "pim multicast routing\n"
7032 "Source Specific Multicast\n"
7033 "group range prefix-list filter\n")
7035 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7036 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
7039 DEFUN (no_ip_pim_ssm_prefix_list_name
,
7040 no_ip_pim_ssm_prefix_list_name_cmd
,
7041 "no ip pim ssm prefix-list WORD",
7044 "pim multicast routing\n"
7045 "Source Specific Multicast\n"
7046 "group range prefix-list filter\n"
7047 "Name of a prefix-list\n")
7049 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7050 struct pim_ssm
*ssm
= pim
->ssm_info
;
7052 if (ssm
->plist_name
&& !strcmp(ssm
->plist_name
, argv
[5]->arg
))
7053 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
7055 vty_out(vty
, "%% pim ssm prefix-list %s doesn't exist\n", argv
[5]->arg
);
7057 return CMD_WARNING_CONFIG_FAILED
;
7060 static void ip_pim_ssm_show_group_range(struct pim_instance
*pim
,
7061 struct vty
*vty
, bool uj
)
7063 struct pim_ssm
*ssm
= pim
->ssm_info
;
7064 const char *range_str
=
7065 ssm
->plist_name
? ssm
->plist_name
: PIM_SSM_STANDARD_RANGE
;
7069 json
= json_object_new_object();
7070 json_object_string_add(json
, "ssmGroups", range_str
);
7071 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
7072 json
, JSON_C_TO_STRING_PRETTY
));
7073 json_object_free(json
);
7075 vty_out(vty
, "SSM group range : %s\n", range_str
);
7078 DEFUN (show_ip_pim_ssm_range
,
7079 show_ip_pim_ssm_range_cmd
,
7080 "show ip pim [vrf NAME] group-type [json]",
7089 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
7090 bool uj
= use_json(argc
, argv
);
7095 ip_pim_ssm_show_group_range(vrf
->info
, vty
, uj
);
7100 static void ip_pim_ssm_show_group_type(struct pim_instance
*pim
,
7101 struct vty
*vty
, bool uj
,
7104 struct in_addr group_addr
;
7105 const char *type_str
;
7108 result
= inet_pton(AF_INET
, group
, &group_addr
);
7110 type_str
= "invalid";
7112 if (pim_is_group_224_4(group_addr
))
7114 pim_is_grp_ssm(pim
, group_addr
) ? "SSM" : "ASM";
7116 type_str
= "not-multicast";
7121 json
= json_object_new_object();
7122 json_object_string_add(json
, "groupType", type_str
);
7123 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
7124 json
, JSON_C_TO_STRING_PRETTY
));
7125 json_object_free(json
);
7127 vty_out(vty
, "Group type : %s\n", type_str
);
7130 DEFUN (show_ip_pim_group_type
,
7131 show_ip_pim_group_type_cmd
,
7132 "show ip pim [vrf NAME] group-type A.B.C.D [json]",
7137 "multicast group type\n"
7142 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
7143 bool uj
= use_json(argc
, argv
);
7148 argv_find(argv
, argc
, "A.B.C.D", &idx
);
7149 ip_pim_ssm_show_group_type(vrf
->info
, vty
, uj
, argv
[idx
]->arg
);
7154 DEFUN (show_ip_pim_bsr
,
7155 show_ip_pim_bsr_cmd
,
7156 "show ip pim bsr [json]",
7160 "boot-strap router information\n"
7164 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
7165 bool uj
= use_json(argc
, argv
);
7170 pim_show_bsr(vrf
->info
, vty
, uj
);
7177 "ip ssmpingd [A.B.C.D]",
7182 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7185 struct in_addr source_addr
;
7186 const char *source_str
= (argc
== 3) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
7188 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
7190 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
7191 source_str
, errno
, safe_strerror(errno
));
7192 return CMD_WARNING_CONFIG_FAILED
;
7195 result
= pim_ssmpingd_start(pim
, source_addr
);
7197 vty_out(vty
, "%% Failure starting ssmpingd for source %s: %d\n",
7198 source_str
, result
);
7199 return CMD_WARNING_CONFIG_FAILED
;
7205 DEFUN (no_ip_ssmpingd
,
7207 "no ip ssmpingd [A.B.C.D]",
7213 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7216 struct in_addr source_addr
;
7217 const char *source_str
= (argc
== 4) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
7219 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
7221 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
7222 source_str
, errno
, safe_strerror(errno
));
7223 return CMD_WARNING_CONFIG_FAILED
;
7226 result
= pim_ssmpingd_stop(pim
, source_addr
);
7228 vty_out(vty
, "%% Failure stopping ssmpingd for source %s: %d\n",
7229 source_str
, result
);
7230 return CMD_WARNING_CONFIG_FAILED
;
7240 "pim multicast routing\n"
7241 "Enable PIM ECMP \n")
7243 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7244 pim
->ecmp_enable
= true;
7249 DEFUN (no_ip_pim_ecmp
,
7254 "pim multicast routing\n"
7255 "Disable PIM ECMP \n")
7257 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7258 pim
->ecmp_enable
= false;
7263 DEFUN (ip_pim_ecmp_rebalance
,
7264 ip_pim_ecmp_rebalance_cmd
,
7265 "ip pim ecmp rebalance",
7267 "pim multicast routing\n"
7268 "Enable PIM ECMP \n"
7269 "Enable PIM ECMP Rebalance\n")
7271 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7272 pim
->ecmp_enable
= true;
7273 pim
->ecmp_rebalance_enable
= true;
7278 DEFUN (no_ip_pim_ecmp_rebalance
,
7279 no_ip_pim_ecmp_rebalance_cmd
,
7280 "no ip pim ecmp rebalance",
7283 "pim multicast routing\n"
7284 "Disable PIM ECMP \n"
7285 "Disable PIM ECMP Rebalance\n")
7287 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7288 pim
->ecmp_rebalance_enable
= false;
7293 static int pim_cmd_igmp_start(struct vty
*vty
, struct interface
*ifp
)
7295 struct pim_interface
*pim_ifp
;
7296 struct pim_instance
*pim
;
7297 uint8_t need_startup
= 0;
7299 pim_ifp
= ifp
->info
;
7302 pim
= pim_get_pim_instance(ifp
->vrf_id
);
7303 /* Limit mcast interfaces to number of vifs available */
7304 if (pim
->mcast_if_count
== MAXVIFS
) {
7306 "Max multicast interfaces(%d) Reached. Could not enable IGMP on interface %s\n",
7307 MAXVIFS
, ifp
->name
);
7308 return CMD_WARNING_CONFIG_FAILED
;
7310 (void)pim_if_new(ifp
, true, false, false, false);
7313 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
7314 PIM_IF_DO_IGMP(pim_ifp
->options
);
7319 /* 'ip igmp' executed multiple times, with need_startup
7320 avoid multiple if add all and membership refresh */
7322 pim_if_addr_add_all(ifp
);
7323 pim_if_membership_refresh(ifp
);
7329 DEFUN (interface_ip_igmp
,
7330 interface_ip_igmp_cmd
,
7335 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7337 return pim_cmd_igmp_start(vty
, ifp
);
7340 DEFUN (interface_no_ip_igmp
,
7341 interface_no_ip_igmp_cmd
,
7347 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7348 struct pim_interface
*pim_ifp
= ifp
->info
;
7353 PIM_IF_DONT_IGMP(pim_ifp
->options
);
7355 pim_if_membership_clear(ifp
);
7357 pim_if_addr_del_all_igmp(ifp
);
7359 if (!PIM_IF_TEST_PIM(pim_ifp
->options
)) {
7366 DEFUN (interface_ip_igmp_join
,
7367 interface_ip_igmp_join_cmd
,
7368 "ip igmp join A.B.C.D [A.B.C.D]",
7371 "IGMP join multicast group\n"
7372 "Multicast group address\n"
7375 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7378 const char *group_str
;
7379 const char *source_str
;
7380 struct in_addr group_addr
;
7381 struct in_addr source_addr
;
7385 group_str
= argv
[idx_ipv4
]->arg
;
7386 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
7388 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
7389 errno
, safe_strerror(errno
));
7390 return CMD_WARNING_CONFIG_FAILED
;
7393 /* Source address */
7394 if (argc
== (idx_ipv4_2
+ 1)) {
7395 source_str
= argv
[idx_ipv4_2
]->arg
;
7396 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
7398 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
7399 source_str
, errno
, safe_strerror(errno
));
7400 return CMD_WARNING_CONFIG_FAILED
;
7402 /* Reject 0.0.0.0. Reserved for any source. */
7403 if (source_addr
.s_addr
== INADDR_ANY
) {
7404 vty_out(vty
, "Bad source address %s\n", source_str
);
7405 return CMD_WARNING_CONFIG_FAILED
;
7408 source_addr
.s_addr
= INADDR_ANY
;
7411 CMD_FERR_RETURN(pim_if_igmp_join_add(ifp
, group_addr
, source_addr
),
7412 "Failure joining IGMP group: $ERR");
7417 DEFUN (interface_no_ip_igmp_join
,
7418 interface_no_ip_igmp_join_cmd
,
7419 "no ip igmp join A.B.C.D [A.B.C.D]",
7423 "IGMP join multicast group\n"
7424 "Multicast group address\n"
7427 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7430 const char *group_str
;
7431 const char *source_str
;
7432 struct in_addr group_addr
;
7433 struct in_addr source_addr
;
7437 group_str
= argv
[idx_ipv4
]->arg
;
7438 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
7440 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
7441 errno
, safe_strerror(errno
));
7442 return CMD_WARNING_CONFIG_FAILED
;
7445 /* Source address */
7446 if (argc
== (idx_ipv4_2
+ 1)) {
7447 source_str
= argv
[idx_ipv4_2
]->arg
;
7448 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
7450 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
7451 source_str
, errno
, safe_strerror(errno
));
7452 return CMD_WARNING_CONFIG_FAILED
;
7454 /* Reject 0.0.0.0. Reserved for any source. */
7455 if (source_addr
.s_addr
== INADDR_ANY
) {
7456 vty_out(vty
, "Bad source address %s\n", source_str
);
7457 return CMD_WARNING_CONFIG_FAILED
;
7461 source_addr
.s_addr
= INADDR_ANY
;
7464 result
= pim_if_igmp_join_del(ifp
, group_addr
, source_addr
);
7467 "%% Failure leaving IGMP group %s source %s on interface %s: %d\n",
7468 group_str
, source_str
, ifp
->name
, result
);
7469 return CMD_WARNING_CONFIG_FAILED
;
7476 CLI reconfiguration affects the interface level (struct pim_interface).
7477 This function propagates the reconfiguration to every active socket
7480 static void igmp_sock_query_interval_reconfig(struct igmp_sock
*igmp
)
7482 struct interface
*ifp
;
7483 struct pim_interface
*pim_ifp
;
7487 /* other querier present? */
7489 if (igmp
->t_other_querier_timer
)
7492 /* this is the querier */
7494 zassert(igmp
->interface
);
7495 zassert(igmp
->interface
->info
);
7497 ifp
= igmp
->interface
;
7498 pim_ifp
= ifp
->info
;
7500 if (PIM_DEBUG_IGMP_TRACE
) {
7501 char ifaddr_str
[INET_ADDRSTRLEN
];
7502 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
7503 sizeof(ifaddr_str
));
7504 zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
7505 __func__
, ifaddr_str
, ifp
->name
,
7506 pim_ifp
->igmp_default_query_interval
);
7510 igmp_startup_mode_on() will reset QQI:
7512 igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
7514 igmp_startup_mode_on(igmp
);
7517 static void igmp_sock_query_reschedule(struct igmp_sock
*igmp
)
7519 if (igmp
->mtrace_only
)
7522 if (igmp
->t_igmp_query_timer
) {
7523 /* other querier present */
7524 zassert(igmp
->t_igmp_query_timer
);
7525 zassert(!igmp
->t_other_querier_timer
);
7527 pim_igmp_general_query_off(igmp
);
7528 pim_igmp_general_query_on(igmp
);
7530 zassert(igmp
->t_igmp_query_timer
);
7531 zassert(!igmp
->t_other_querier_timer
);
7533 /* this is the querier */
7535 zassert(!igmp
->t_igmp_query_timer
);
7536 zassert(igmp
->t_other_querier_timer
);
7538 pim_igmp_other_querier_timer_off(igmp
);
7539 pim_igmp_other_querier_timer_on(igmp
);
7541 zassert(!igmp
->t_igmp_query_timer
);
7542 zassert(igmp
->t_other_querier_timer
);
7546 static void change_query_interval(struct pim_interface
*pim_ifp
,
7549 struct listnode
*sock_node
;
7550 struct igmp_sock
*igmp
;
7552 pim_ifp
->igmp_default_query_interval
= query_interval
;
7554 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
7555 igmp_sock_query_interval_reconfig(igmp
);
7556 igmp_sock_query_reschedule(igmp
);
7560 static void change_query_max_response_time(struct pim_interface
*pim_ifp
,
7561 int query_max_response_time_dsec
)
7563 struct listnode
*sock_node
;
7564 struct igmp_sock
*igmp
;
7566 pim_ifp
->igmp_query_max_response_time_dsec
=
7567 query_max_response_time_dsec
;
7570 Below we modify socket/group/source timers in order to quickly
7571 reflect the change. Otherwise, those timers would eventually catch
7575 /* scan all sockets */
7576 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
7577 struct listnode
*grp_node
;
7578 struct igmp_group
*grp
;
7580 /* reschedule socket general query */
7581 igmp_sock_query_reschedule(igmp
);
7583 /* scan socket groups */
7584 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grp_node
,
7586 struct listnode
*src_node
;
7587 struct igmp_source
*src
;
7589 /* reset group timers for groups in EXCLUDE mode */
7590 if (grp
->group_filtermode_isexcl
) {
7591 igmp_group_reset_gmi(grp
);
7594 /* scan group sources */
7595 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
,
7598 /* reset source timers for sources with running
7600 if (src
->t_source_timer
) {
7601 igmp_source_reset_gmi(igmp
, grp
, src
);
7608 #define IGMP_QUERY_INTERVAL_MIN (1)
7609 #define IGMP_QUERY_INTERVAL_MAX (1800)
7611 DEFUN (interface_ip_igmp_query_interval
,
7612 interface_ip_igmp_query_interval_cmd
,
7613 "ip igmp query-interval (1-1800)",
7616 IFACE_IGMP_QUERY_INTERVAL_STR
7617 "Query interval in seconds\n")
7619 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7620 struct pim_interface
*pim_ifp
= ifp
->info
;
7622 int query_interval_dsec
;
7626 ret
= pim_cmd_igmp_start(vty
, ifp
);
7627 if (ret
!= CMD_SUCCESS
)
7629 pim_ifp
= ifp
->info
;
7632 query_interval
= atoi(argv
[3]->arg
);
7633 query_interval_dsec
= 10 * query_interval
;
7636 It seems we don't need to check bounds since command.c does it
7637 already, but we verify them anyway for extra safety.
7639 if (query_interval
< IGMP_QUERY_INTERVAL_MIN
) {
7641 "General query interval %d lower than minimum %d\n",
7642 query_interval
, IGMP_QUERY_INTERVAL_MIN
);
7643 return CMD_WARNING_CONFIG_FAILED
;
7645 if (query_interval
> IGMP_QUERY_INTERVAL_MAX
) {
7647 "General query interval %d higher than maximum %d\n",
7648 query_interval
, IGMP_QUERY_INTERVAL_MAX
);
7649 return CMD_WARNING_CONFIG_FAILED
;
7652 if (query_interval_dsec
<= pim_ifp
->igmp_query_max_response_time_dsec
) {
7654 "Can't set general query interval %d dsec <= query max response time %d dsec.\n",
7655 query_interval_dsec
,
7656 pim_ifp
->igmp_query_max_response_time_dsec
);
7657 return CMD_WARNING_CONFIG_FAILED
;
7660 change_query_interval(pim_ifp
, query_interval
);
7665 DEFUN (interface_no_ip_igmp_query_interval
,
7666 interface_no_ip_igmp_query_interval_cmd
,
7667 "no ip igmp query-interval",
7671 IFACE_IGMP_QUERY_INTERVAL_STR
)
7673 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7674 struct pim_interface
*pim_ifp
= ifp
->info
;
7675 int default_query_interval_dsec
;
7680 default_query_interval_dsec
= IGMP_GENERAL_QUERY_INTERVAL
* 10;
7682 if (default_query_interval_dsec
7683 <= pim_ifp
->igmp_query_max_response_time_dsec
) {
7685 "Can't set default general query interval %d dsec <= query max response time %d dsec.\n",
7686 default_query_interval_dsec
,
7687 pim_ifp
->igmp_query_max_response_time_dsec
);
7688 return CMD_WARNING_CONFIG_FAILED
;
7691 change_query_interval(pim_ifp
, IGMP_GENERAL_QUERY_INTERVAL
);
7696 DEFUN (interface_ip_igmp_version
,
7697 interface_ip_igmp_version_cmd
,
7698 "ip igmp version (2-3)",
7702 "IGMP version number\n")
7704 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7705 struct pim_interface
*pim_ifp
= ifp
->info
;
7706 int igmp_version
, old_version
= 0;
7710 ret
= pim_cmd_igmp_start(vty
, ifp
);
7711 if (ret
!= CMD_SUCCESS
)
7713 pim_ifp
= ifp
->info
;
7716 igmp_version
= atoi(argv
[3]->arg
);
7717 old_version
= pim_ifp
->igmp_version
;
7718 pim_ifp
->igmp_version
= igmp_version
;
7720 // Check if IGMP is Enabled otherwise, enable on interface
7721 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
7722 PIM_IF_DO_IGMP(pim_ifp
->options
);
7723 pim_if_addr_add_all(ifp
);
7724 pim_if_membership_refresh(ifp
);
7725 old_version
= igmp_version
;
7726 // avoid refreshing membership again.
7728 /* Current and new version is different refresh existing
7729 membership. Going from 3 -> 2 or 2 -> 3. */
7730 if (old_version
!= igmp_version
)
7731 pim_if_membership_refresh(ifp
);
7736 DEFUN (interface_no_ip_igmp_version
,
7737 interface_no_ip_igmp_version_cmd
,
7738 "no ip igmp version (2-3)",
7743 "IGMP version number\n")
7745 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7746 struct pim_interface
*pim_ifp
= ifp
->info
;
7751 pim_ifp
->igmp_version
= IGMP_DEFAULT_VERSION
;
7756 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
7757 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
7759 DEFUN (interface_ip_igmp_query_max_response_time
,
7760 interface_ip_igmp_query_max_response_time_cmd
,
7761 "ip igmp query-max-response-time (10-250)",
7764 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
7765 "Query response value in deci-seconds\n")
7767 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7768 struct pim_interface
*pim_ifp
= ifp
->info
;
7769 int query_max_response_time
;
7773 ret
= pim_cmd_igmp_start(vty
, ifp
);
7774 if (ret
!= CMD_SUCCESS
)
7776 pim_ifp
= ifp
->info
;
7779 query_max_response_time
= atoi(argv
[3]->arg
);
7781 if (query_max_response_time
7782 >= pim_ifp
->igmp_default_query_interval
* 10) {
7784 "Can't set query max response time %d sec >= general query interval %d sec\n",
7785 query_max_response_time
,
7786 pim_ifp
->igmp_default_query_interval
);
7787 return CMD_WARNING_CONFIG_FAILED
;
7790 change_query_max_response_time(pim_ifp
, query_max_response_time
);
7795 DEFUN (interface_no_ip_igmp_query_max_response_time
,
7796 interface_no_ip_igmp_query_max_response_time_cmd
,
7797 "no ip igmp query-max-response-time (10-250)",
7801 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
7802 "Time for response in deci-seconds\n")
7804 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7805 struct pim_interface
*pim_ifp
= ifp
->info
;
7810 change_query_max_response_time(pim_ifp
,
7811 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
7816 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
7817 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
7819 DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec
,
7820 interface_ip_igmp_query_max_response_time_dsec_cmd
,
7821 "ip igmp query-max-response-time-dsec (10-250)",
7824 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
7825 "Query response value in deciseconds\n")
7827 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7828 struct pim_interface
*pim_ifp
= ifp
->info
;
7829 int query_max_response_time_dsec
;
7830 int default_query_interval_dsec
;
7834 ret
= pim_cmd_igmp_start(vty
, ifp
);
7835 if (ret
!= CMD_SUCCESS
)
7837 pim_ifp
= ifp
->info
;
7840 query_max_response_time_dsec
= atoi(argv
[4]->arg
);
7842 default_query_interval_dsec
= 10 * pim_ifp
->igmp_default_query_interval
;
7844 if (query_max_response_time_dsec
>= default_query_interval_dsec
) {
7846 "Can't set query max response time %d dsec >= general query interval %d dsec\n",
7847 query_max_response_time_dsec
,
7848 default_query_interval_dsec
);
7849 return CMD_WARNING_CONFIG_FAILED
;
7852 change_query_max_response_time(pim_ifp
, query_max_response_time_dsec
);
7857 DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec
,
7858 interface_no_ip_igmp_query_max_response_time_dsec_cmd
,
7859 "no ip igmp query-max-response-time-dsec",
7863 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
)
7865 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7866 struct pim_interface
*pim_ifp
= ifp
->info
;
7871 change_query_max_response_time(pim_ifp
,
7872 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
7877 #define IGMP_LAST_MEMBER_QUERY_COUNT_MIN (1)
7878 #define IGMP_LAST_MEMBER_QUERY_COUNT_MAX (7)
7880 DEFUN (interface_ip_igmp_last_member_query_count
,
7881 interface_ip_igmp_last_member_query_count_cmd
,
7882 "ip igmp last-member-query-count (1-7)",
7885 IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR
7886 "Last member query count\n")
7888 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7889 struct pim_interface
*pim_ifp
= ifp
->info
;
7890 int last_member_query_count
;
7894 ret
= pim_cmd_igmp_start(vty
, ifp
);
7895 if (ret
!= CMD_SUCCESS
)
7897 pim_ifp
= ifp
->info
;
7900 last_member_query_count
= atoi(argv
[3]->arg
);
7902 pim_ifp
->igmp_last_member_query_count
= last_member_query_count
;
7907 DEFUN (interface_no_ip_igmp_last_member_query_count
,
7908 interface_no_ip_igmp_last_member_query_count_cmd
,
7909 "no ip igmp last-member-query-count",
7913 IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR
)
7915 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7916 struct pim_interface
*pim_ifp
= ifp
->info
;
7921 pim_ifp
->igmp_last_member_query_count
=
7922 IGMP_DEFAULT_ROBUSTNESS_VARIABLE
;
7927 #define IGMP_LAST_MEMBER_QUERY_INTERVAL_MIN (1)
7928 #define IGMP_LAST_MEMBER_QUERY_INTERVAL_MAX (255)
7930 DEFUN (interface_ip_igmp_last_member_query_interval
,
7931 interface_ip_igmp_last_member_query_interval_cmd
,
7932 "ip igmp last-member-query-interval (1-255)",
7935 IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR
7936 "Last member query interval in deciseconds\n")
7938 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7939 struct pim_interface
*pim_ifp
= ifp
->info
;
7940 int last_member_query_interval
;
7944 ret
= pim_cmd_igmp_start(vty
, ifp
);
7945 if (ret
!= CMD_SUCCESS
)
7947 pim_ifp
= ifp
->info
;
7950 last_member_query_interval
= atoi(argv
[3]->arg
);
7951 pim_ifp
->igmp_specific_query_max_response_time_dsec
7952 = last_member_query_interval
;
7957 DEFUN (interface_no_ip_igmp_last_member_query_interval
,
7958 interface_no_ip_igmp_last_member_query_interval_cmd
,
7959 "no ip igmp last-member-query-interval",
7963 IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR
)
7965 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7966 struct pim_interface
*pim_ifp
= ifp
->info
;
7971 pim_ifp
->igmp_specific_query_max_response_time_dsec
=
7972 IGMP_SPECIFIC_QUERY_MAX_RESPONSE_TIME_DSEC
;
7977 DEFUN (interface_ip_pim_drprio
,
7978 interface_ip_pim_drprio_cmd
,
7979 "ip pim drpriority (1-4294967295)",
7982 "Set the Designated Router Election Priority\n"
7983 "Value of the new DR Priority\n")
7985 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7987 struct pim_interface
*pim_ifp
= ifp
->info
;
7988 uint32_t old_dr_prio
;
7991 vty_out(vty
, "Please enable PIM on interface, first\n");
7992 return CMD_WARNING_CONFIG_FAILED
;
7995 old_dr_prio
= pim_ifp
->pim_dr_priority
;
7997 pim_ifp
->pim_dr_priority
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
7999 if (old_dr_prio
!= pim_ifp
->pim_dr_priority
) {
8000 pim_if_dr_election(ifp
);
8001 pim_hello_restart_now(ifp
);
8007 DEFUN (interface_no_ip_pim_drprio
,
8008 interface_no_ip_pim_drprio_cmd
,
8009 "no ip pim drpriority [(1-4294967295)]",
8013 "Revert the Designated Router Priority to default\n"
8014 "Old Value of the Priority\n")
8016 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8017 struct pim_interface
*pim_ifp
= ifp
->info
;
8020 vty_out(vty
, "Pim not enabled on this interface\n");
8021 return CMD_WARNING_CONFIG_FAILED
;
8024 if (pim_ifp
->pim_dr_priority
!= PIM_DEFAULT_DR_PRIORITY
) {
8025 pim_ifp
->pim_dr_priority
= PIM_DEFAULT_DR_PRIORITY
;
8026 pim_if_dr_election(ifp
);
8027 pim_hello_restart_now(ifp
);
8033 DEFPY_HIDDEN (interface_ip_igmp_query_generate
,
8034 interface_ip_igmp_query_generate_cmd
,
8035 "ip igmp generate-query-once [version (2-3)]",
8038 "Generate igmp general query once\n"
8040 "IGMP version number\n")
8042 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8043 int igmp_version
= 2;
8046 vty_out(vty
, "IGMP/PIM is not enabled on the interface %s\n",
8048 return CMD_WARNING_CONFIG_FAILED
;
8052 igmp_version
= atoi(argv
[4]->arg
);
8054 igmp_send_query_on_intf(ifp
, igmp_version
);
8059 static int pim_cmd_interface_add(struct vty
*vty
, struct interface
*ifp
)
8061 struct pim_interface
*pim_ifp
= ifp
->info
;
8062 struct pim_instance
*pim
;
8065 pim
= pim_get_pim_instance(ifp
->vrf_id
);
8066 /* Limiting mcast interfaces to number of VIFs */
8067 if (pim
->mcast_if_count
== MAXVIFS
) {
8068 vty_out(vty
, "Max multicast interfaces(%d) reached.",
8072 pim_ifp
= pim_if_new(ifp
, false, true, false, false);
8074 PIM_IF_DO_PIM(pim_ifp
->options
);
8076 pim_if_addr_add_all(ifp
);
8077 pim_if_membership_refresh(ifp
);
8079 pim_if_create_pimreg(pim_ifp
->pim
);
8083 DEFPY_HIDDEN (pim_test_sg_keepalive
,
8084 pim_test_sg_keepalive_cmd
,
8085 "test pim [vrf NAME$name] keepalive-reset A.B.C.D$source A.B.C.D$group",
8089 "Reset the Keepalive Timer\n"
8090 "The Source we are resetting\n"
8091 "The Group we are resetting\n")
8093 struct pim_upstream
*up
;
8094 struct pim_instance
*pim
;
8095 struct prefix_sg sg
;
8101 pim
= pim_get_pim_instance(VRF_DEFAULT
);
8103 struct vrf
*vrf
= vrf_lookup_by_name(name
);
8106 vty_out(vty
, "%% Vrf specified: %s does not exist\n",
8111 pim
= pim_get_pim_instance(vrf
->vrf_id
);
8115 vty_out(vty
, "%% Unable to find pim instance\n");
8119 up
= pim_upstream_find(pim
, &sg
);
8121 vty_out(vty
, "%% Unable to find %s specified\n",
8122 pim_str_sg_dump(&sg
));
8126 vty_out(vty
, "Setting %s to current keep alive time: %d\n",
8127 pim_str_sg_dump(&sg
), pim
->keep_alive_time
);
8128 pim_upstream_keep_alive_timer_start(up
, pim
->keep_alive_time
);
8133 DEFPY (interface_ip_pim_activeactive
,
8134 interface_ip_pim_activeactive_cmd
,
8135 "[no$no] ip pim active-active",
8139 "Mark interface as Active-Active for MLAG operations, Hidden because not finished yet\n")
8141 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8142 struct pim_interface
*pim_ifp
;
8144 if (!no
&& !pim_cmd_interface_add(vty
, ifp
)) {
8146 "Could not enable PIM SM active-active on interface %s\n",
8148 return CMD_WARNING_CONFIG_FAILED
;
8153 zlog_debug("%sConfiguring PIM active-active on Interface: %s",
8154 no
? "Un-" : " ", ifp
->name
);
8156 pim_ifp
= ifp
->info
;
8158 pim_if_unconfigure_mlag_dualactive(pim_ifp
);
8160 pim_if_configure_mlag_dualactive(pim_ifp
);
8165 DEFUN_HIDDEN (interface_ip_pim_ssm
,
8166 interface_ip_pim_ssm_cmd
,
8172 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8174 if (!pim_cmd_interface_add(vty
, ifp
)) {
8175 vty_out(vty
, "Could not enable PIM SM on interface %s\n",
8177 return CMD_WARNING_CONFIG_FAILED
;
8181 "WARN: Enabled PIM SM on interface; configure PIM SSM "
8182 "range if needed\n");
8186 static int interface_ip_pim_helper(struct vty
*vty
)
8188 struct pim_interface
*pim_ifp
;
8190 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8192 if (!pim_cmd_interface_add(vty
, ifp
)) {
8193 vty_out(vty
, "Could not enable PIM SM on interface %s\n",
8195 return CMD_WARNING_CONFIG_FAILED
;
8198 pim_ifp
= ifp
->info
;
8200 pim_if_create_pimreg(pim_ifp
->pim
);
8205 DEFUN_HIDDEN (interface_ip_pim_sm
,
8206 interface_ip_pim_sm_cmd
,
8212 return interface_ip_pim_helper(vty
);
8215 DEFUN (interface_ip_pim
,
8216 interface_ip_pim_cmd
,
8221 return interface_ip_pim_helper(vty
);
8224 static int pim_cmd_interface_delete(struct interface
*ifp
)
8226 struct pim_interface
*pim_ifp
= ifp
->info
;
8231 PIM_IF_DONT_PIM(pim_ifp
->options
);
8233 pim_if_membership_clear(ifp
);
8236 pim_sock_delete() removes all neighbors from
8237 pim_ifp->pim_neighbor_list.
8239 pim_sock_delete(ifp
, "pim unconfigured on interface");
8241 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
8242 pim_if_addr_del_all(ifp
);
8249 static int interface_no_ip_pim_helper(struct vty
*vty
)
8251 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8252 if (!pim_cmd_interface_delete(ifp
)) {
8253 vty_out(vty
, "Unable to delete interface information\n");
8254 return CMD_WARNING_CONFIG_FAILED
;
8260 DEFUN_HIDDEN (interface_no_ip_pim_ssm
,
8261 interface_no_ip_pim_ssm_cmd
,
8268 return interface_no_ip_pim_helper(vty
);
8271 DEFUN_HIDDEN (interface_no_ip_pim_sm
,
8272 interface_no_ip_pim_sm_cmd
,
8279 return interface_no_ip_pim_helper(vty
);
8282 DEFUN (interface_no_ip_pim
,
8283 interface_no_ip_pim_cmd
,
8289 return interface_no_ip_pim_helper(vty
);
8293 DEFUN(interface_ip_pim_boundary_oil
,
8294 interface_ip_pim_boundary_oil_cmd
,
8295 "ip multicast boundary oil WORD",
8297 "Generic multicast configuration options\n"
8298 "Define multicast boundary\n"
8299 "Filter OIL by group using prefix list\n"
8300 "Prefix list to filter OIL with\n")
8302 VTY_DECLVAR_CONTEXT(interface
, iif
);
8303 struct pim_interface
*pim_ifp
;
8306 argv_find(argv
, argc
, "WORD", &idx
);
8308 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
8310 if (pim_ifp
->boundary_oil_plist
)
8311 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
8313 pim_ifp
->boundary_oil_plist
=
8314 XSTRDUP(MTYPE_PIM_INTERFACE
, argv
[idx
]->arg
);
8316 /* Interface will be pruned from OIL on next Join */
8320 DEFUN(interface_no_ip_pim_boundary_oil
,
8321 interface_no_ip_pim_boundary_oil_cmd
,
8322 "no ip multicast boundary oil [WORD]",
8325 "Generic multicast configuration options\n"
8326 "Define multicast boundary\n"
8327 "Filter OIL by group using prefix list\n"
8328 "Prefix list to filter OIL with\n")
8330 VTY_DECLVAR_CONTEXT(interface
, iif
);
8331 struct pim_interface
*pim_ifp
;
8334 argv_find(argv
, argc
, "WORD", &idx
);
8336 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
8338 if (pim_ifp
->boundary_oil_plist
)
8339 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
8344 DEFUN (interface_ip_mroute
,
8345 interface_ip_mroute_cmd
,
8346 "ip mroute INTERFACE A.B.C.D [A.B.C.D]",
8348 "Add multicast route\n"
8349 "Outgoing interface name\n"
8353 VTY_DECLVAR_CONTEXT(interface
, iif
);
8354 struct pim_interface
*pim_ifp
;
8355 struct pim_instance
*pim
;
8356 int idx_interface
= 2;
8358 struct interface
*oif
;
8359 const char *oifname
;
8360 const char *grp_str
;
8361 struct in_addr grp_addr
;
8362 const char *src_str
;
8363 struct in_addr src_addr
;
8366 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
8369 oifname
= argv
[idx_interface
]->arg
;
8370 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
8372 vty_out(vty
, "No such interface name %s\n", oifname
);
8376 grp_str
= argv
[idx_ipv4
]->arg
;
8377 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
8379 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
8380 errno
, safe_strerror(errno
));
8384 if (argc
== (idx_ipv4
+ 1)) {
8385 src_addr
.s_addr
= INADDR_ANY
;
8388 src_str
= argv
[idx_ipv4
+ 1]->arg
;
8389 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
8391 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
8392 errno
, safe_strerror(errno
));
8397 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
8398 vty_out(vty
, "Failed to add static mroute\n");
8405 DEFUN (interface_no_ip_mroute
,
8406 interface_no_ip_mroute_cmd
,
8407 "no ip mroute INTERFACE A.B.C.D [A.B.C.D]",
8410 "Add multicast route\n"
8411 "Outgoing interface name\n"
8415 VTY_DECLVAR_CONTEXT(interface
, iif
);
8416 struct pim_interface
*pim_ifp
;
8417 struct pim_instance
*pim
;
8418 int idx_interface
= 3;
8420 struct interface
*oif
;
8421 const char *oifname
;
8422 const char *grp_str
;
8423 struct in_addr grp_addr
;
8424 const char *src_str
;
8425 struct in_addr src_addr
;
8428 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
8431 oifname
= argv
[idx_interface
]->arg
;
8432 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
8434 vty_out(vty
, "No such interface name %s\n", oifname
);
8438 grp_str
= argv
[idx_ipv4
]->arg
;
8439 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
8441 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
8442 errno
, safe_strerror(errno
));
8446 if (argc
== (idx_ipv4
+ 1)) {
8447 src_addr
.s_addr
= INADDR_ANY
;
8450 src_str
= argv
[idx_ipv4
+ 1]->arg
;
8451 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
8453 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
8454 errno
, safe_strerror(errno
));
8459 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
8460 vty_out(vty
, "Failed to remove static mroute\n");
8467 DEFUN (interface_ip_pim_hello
,
8468 interface_ip_pim_hello_cmd
,
8469 "ip pim hello (1-180) [(1-180)]",
8473 IFACE_PIM_HELLO_TIME_STR
8474 IFACE_PIM_HELLO_HOLD_STR
)
8476 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8479 struct pim_interface
*pim_ifp
= ifp
->info
;
8482 if (!pim_cmd_interface_add(vty
, ifp
)) {
8484 "Could not enable PIM SM on interface %s\n",
8486 return CMD_WARNING_CONFIG_FAILED
;
8490 pim_ifp
= ifp
->info
;
8491 pim_ifp
->pim_hello_period
= strtol(argv
[idx_time
]->arg
, NULL
, 10);
8493 if (argc
== idx_hold
+ 1)
8494 pim_ifp
->pim_default_holdtime
=
8495 strtol(argv
[idx_hold
]->arg
, NULL
, 10);
8500 DEFUN (interface_no_ip_pim_hello
,
8501 interface_no_ip_pim_hello_cmd
,
8502 "no ip pim hello [(1-180) (1-180)]",
8507 IFACE_PIM_HELLO_TIME_STR
8508 IFACE_PIM_HELLO_HOLD_STR
)
8510 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8511 struct pim_interface
*pim_ifp
= ifp
->info
;
8514 vty_out(vty
, "Pim not enabled on this interface\n");
8515 return CMD_WARNING_CONFIG_FAILED
;
8518 pim_ifp
->pim_hello_period
= PIM_DEFAULT_HELLO_PERIOD
;
8519 pim_ifp
->pim_default_holdtime
= -1;
8530 PIM_DO_DEBUG_IGMP_EVENTS
;
8531 PIM_DO_DEBUG_IGMP_PACKETS
;
8532 PIM_DO_DEBUG_IGMP_TRACE
;
8536 DEFUN (no_debug_igmp
,
8543 PIM_DONT_DEBUG_IGMP_EVENTS
;
8544 PIM_DONT_DEBUG_IGMP_PACKETS
;
8545 PIM_DONT_DEBUG_IGMP_TRACE
;
8550 DEFUN (debug_igmp_events
,
8551 debug_igmp_events_cmd
,
8552 "debug igmp events",
8555 DEBUG_IGMP_EVENTS_STR
)
8557 PIM_DO_DEBUG_IGMP_EVENTS
;
8561 DEFUN (no_debug_igmp_events
,
8562 no_debug_igmp_events_cmd
,
8563 "no debug igmp events",
8567 DEBUG_IGMP_EVENTS_STR
)
8569 PIM_DONT_DEBUG_IGMP_EVENTS
;
8574 DEFUN (debug_igmp_packets
,
8575 debug_igmp_packets_cmd
,
8576 "debug igmp packets",
8579 DEBUG_IGMP_PACKETS_STR
)
8581 PIM_DO_DEBUG_IGMP_PACKETS
;
8585 DEFUN (no_debug_igmp_packets
,
8586 no_debug_igmp_packets_cmd
,
8587 "no debug igmp packets",
8591 DEBUG_IGMP_PACKETS_STR
)
8593 PIM_DONT_DEBUG_IGMP_PACKETS
;
8598 DEFUN (debug_igmp_trace
,
8599 debug_igmp_trace_cmd
,
8603 DEBUG_IGMP_TRACE_STR
)
8605 PIM_DO_DEBUG_IGMP_TRACE
;
8609 DEFUN (no_debug_igmp_trace
,
8610 no_debug_igmp_trace_cmd
,
8611 "no debug igmp trace",
8615 DEBUG_IGMP_TRACE_STR
)
8617 PIM_DONT_DEBUG_IGMP_TRACE
;
8622 DEFUN (debug_mroute
,
8628 PIM_DO_DEBUG_MROUTE
;
8632 DEFUN (debug_mroute_detail
,
8633 debug_mroute_detail_cmd
,
8634 "debug mroute detail",
8639 PIM_DO_DEBUG_MROUTE_DETAIL
;
8643 DEFUN (no_debug_mroute
,
8644 no_debug_mroute_cmd
,
8650 PIM_DONT_DEBUG_MROUTE
;
8654 DEFUN (no_debug_mroute_detail
,
8655 no_debug_mroute_detail_cmd
,
8656 "no debug mroute detail",
8662 PIM_DONT_DEBUG_MROUTE_DETAIL
;
8666 DEFUN (debug_pim_static
,
8667 debug_pim_static_cmd
,
8673 PIM_DO_DEBUG_STATIC
;
8677 DEFUN (no_debug_pim_static
,
8678 no_debug_pim_static_cmd
,
8679 "no debug pim static",
8685 PIM_DONT_DEBUG_STATIC
;
8696 PIM_DO_DEBUG_PIM_EVENTS
;
8697 PIM_DO_DEBUG_PIM_PACKETS
;
8698 PIM_DO_DEBUG_PIM_TRACE
;
8699 PIM_DO_DEBUG_MSDP_EVENTS
;
8700 PIM_DO_DEBUG_MSDP_PACKETS
;
8705 DEFUN (no_debug_pim
,
8712 PIM_DONT_DEBUG_PIM_EVENTS
;
8713 PIM_DONT_DEBUG_PIM_PACKETS
;
8714 PIM_DONT_DEBUG_PIM_TRACE
;
8715 PIM_DONT_DEBUG_MSDP_EVENTS
;
8716 PIM_DONT_DEBUG_MSDP_PACKETS
;
8718 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
8719 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
8725 DEFUN (debug_pim_nht
,
8730 "Nexthop Tracking\n")
8732 PIM_DO_DEBUG_PIM_NHT
;
8736 DEFUN (no_debug_pim_nht
,
8737 no_debug_pim_nht_cmd
,
8742 "Nexthop Tracking\n")
8744 PIM_DONT_DEBUG_PIM_NHT
;
8748 DEFUN (debug_pim_nht_rp
,
8749 debug_pim_nht_rp_cmd
,
8753 "Nexthop Tracking\n"
8754 "RP Nexthop Tracking\n")
8756 PIM_DO_DEBUG_PIM_NHT_RP
;
8760 DEFUN (no_debug_pim_nht_rp
,
8761 no_debug_pim_nht_rp_cmd
,
8762 "no debug pim nht rp",
8766 "Nexthop Tracking\n"
8767 "RP Nexthop Tracking\n")
8769 PIM_DONT_DEBUG_PIM_NHT_RP
;
8773 DEFUN (debug_pim_events
,
8774 debug_pim_events_cmd
,
8778 DEBUG_PIM_EVENTS_STR
)
8780 PIM_DO_DEBUG_PIM_EVENTS
;
8784 DEFUN (no_debug_pim_events
,
8785 no_debug_pim_events_cmd
,
8786 "no debug pim events",
8790 DEBUG_PIM_EVENTS_STR
)
8792 PIM_DONT_DEBUG_PIM_EVENTS
;
8796 DEFUN (debug_pim_packets
,
8797 debug_pim_packets_cmd
,
8798 "debug pim packets [<hello|joins|register>]",
8801 DEBUG_PIM_PACKETS_STR
8802 DEBUG_PIM_HELLO_PACKETS_STR
8803 DEBUG_PIM_J_P_PACKETS_STR
8804 DEBUG_PIM_PIM_REG_PACKETS_STR
)
8807 if (argv_find(argv
, argc
, "hello", &idx
)) {
8808 PIM_DO_DEBUG_PIM_HELLO
;
8809 vty_out(vty
, "PIM Hello debugging is on\n");
8810 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
8811 PIM_DO_DEBUG_PIM_J_P
;
8812 vty_out(vty
, "PIM Join/Prune debugging is on\n");
8813 } else if (argv_find(argv
, argc
, "register", &idx
)) {
8814 PIM_DO_DEBUG_PIM_REG
;
8815 vty_out(vty
, "PIM Register debugging is on\n");
8817 PIM_DO_DEBUG_PIM_PACKETS
;
8818 vty_out(vty
, "PIM Packet debugging is on \n");
8823 DEFUN (no_debug_pim_packets
,
8824 no_debug_pim_packets_cmd
,
8825 "no debug pim packets [<hello|joins|register>]",
8829 DEBUG_PIM_PACKETS_STR
8830 DEBUG_PIM_HELLO_PACKETS_STR
8831 DEBUG_PIM_J_P_PACKETS_STR
8832 DEBUG_PIM_PIM_REG_PACKETS_STR
)
8835 if (argv_find(argv
, argc
, "hello", &idx
)) {
8836 PIM_DONT_DEBUG_PIM_HELLO
;
8837 vty_out(vty
, "PIM Hello debugging is off \n");
8838 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
8839 PIM_DONT_DEBUG_PIM_J_P
;
8840 vty_out(vty
, "PIM Join/Prune debugging is off \n");
8841 } else if (argv_find(argv
, argc
, "register", &idx
)) {
8842 PIM_DONT_DEBUG_PIM_REG
;
8843 vty_out(vty
, "PIM Register debugging is off\n");
8845 PIM_DONT_DEBUG_PIM_PACKETS
;
8851 DEFUN (debug_pim_packetdump_send
,
8852 debug_pim_packetdump_send_cmd
,
8853 "debug pim packet-dump send",
8856 DEBUG_PIM_PACKETDUMP_STR
8857 DEBUG_PIM_PACKETDUMP_SEND_STR
)
8859 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND
;
8863 DEFUN (no_debug_pim_packetdump_send
,
8864 no_debug_pim_packetdump_send_cmd
,
8865 "no debug pim packet-dump send",
8869 DEBUG_PIM_PACKETDUMP_STR
8870 DEBUG_PIM_PACKETDUMP_SEND_STR
)
8872 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
8876 DEFUN (debug_pim_packetdump_recv
,
8877 debug_pim_packetdump_recv_cmd
,
8878 "debug pim packet-dump receive",
8881 DEBUG_PIM_PACKETDUMP_STR
8882 DEBUG_PIM_PACKETDUMP_RECV_STR
)
8884 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV
;
8888 DEFUN (no_debug_pim_packetdump_recv
,
8889 no_debug_pim_packetdump_recv_cmd
,
8890 "no debug pim packet-dump receive",
8894 DEBUG_PIM_PACKETDUMP_STR
8895 DEBUG_PIM_PACKETDUMP_RECV_STR
)
8897 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
8901 DEFUN (debug_pim_trace
,
8902 debug_pim_trace_cmd
,
8906 DEBUG_PIM_TRACE_STR
)
8908 PIM_DO_DEBUG_PIM_TRACE
;
8912 DEFUN (debug_pim_trace_detail
,
8913 debug_pim_trace_detail_cmd
,
8914 "debug pim trace detail",
8918 "Detailed Information\n")
8920 PIM_DO_DEBUG_PIM_TRACE_DETAIL
;
8924 DEFUN (no_debug_pim_trace
,
8925 no_debug_pim_trace_cmd
,
8926 "no debug pim trace",
8930 DEBUG_PIM_TRACE_STR
)
8932 PIM_DONT_DEBUG_PIM_TRACE
;
8936 DEFUN (no_debug_pim_trace_detail
,
8937 no_debug_pim_trace_detail_cmd
,
8938 "no debug pim trace detail",
8943 "Detailed Information\n")
8945 PIM_DONT_DEBUG_PIM_TRACE_DETAIL
;
8949 DEFUN (debug_ssmpingd
,
8955 PIM_DO_DEBUG_SSMPINGD
;
8959 DEFUN (no_debug_ssmpingd
,
8960 no_debug_ssmpingd_cmd
,
8961 "no debug ssmpingd",
8966 PIM_DONT_DEBUG_SSMPINGD
;
8970 DEFUN (debug_pim_zebra
,
8971 debug_pim_zebra_cmd
,
8975 DEBUG_PIM_ZEBRA_STR
)
8981 DEFUN (no_debug_pim_zebra
,
8982 no_debug_pim_zebra_cmd
,
8983 "no debug pim zebra",
8987 DEBUG_PIM_ZEBRA_STR
)
8989 PIM_DONT_DEBUG_ZEBRA
;
8993 DEFUN(debug_pim_mlag
, debug_pim_mlag_cmd
, "debug pim mlag",
8994 DEBUG_STR DEBUG_PIM_STR DEBUG_PIM_MLAG_STR
)
9000 DEFUN(no_debug_pim_mlag
, no_debug_pim_mlag_cmd
, "no debug pim mlag",
9001 NO_STR DEBUG_STR DEBUG_PIM_STR DEBUG_PIM_MLAG_STR
)
9003 PIM_DONT_DEBUG_MLAG
;
9007 DEFUN (debug_pim_vxlan
,
9008 debug_pim_vxlan_cmd
,
9012 DEBUG_PIM_VXLAN_STR
)
9018 DEFUN (no_debug_pim_vxlan
,
9019 no_debug_pim_vxlan_cmd
,
9020 "no debug pim vxlan",
9024 DEBUG_PIM_VXLAN_STR
)
9026 PIM_DONT_DEBUG_VXLAN
;
9036 PIM_DO_DEBUG_MSDP_EVENTS
;
9037 PIM_DO_DEBUG_MSDP_PACKETS
;
9041 DEFUN (no_debug_msdp
,
9048 PIM_DONT_DEBUG_MSDP_EVENTS
;
9049 PIM_DONT_DEBUG_MSDP_PACKETS
;
9053 DEFUN (debug_msdp_events
,
9054 debug_msdp_events_cmd
,
9055 "debug msdp events",
9058 DEBUG_MSDP_EVENTS_STR
)
9060 PIM_DO_DEBUG_MSDP_EVENTS
;
9064 DEFUN (no_debug_msdp_events
,
9065 no_debug_msdp_events_cmd
,
9066 "no debug msdp events",
9070 DEBUG_MSDP_EVENTS_STR
)
9072 PIM_DONT_DEBUG_MSDP_EVENTS
;
9076 DEFUN (debug_msdp_packets
,
9077 debug_msdp_packets_cmd
,
9078 "debug msdp packets",
9081 DEBUG_MSDP_PACKETS_STR
)
9083 PIM_DO_DEBUG_MSDP_PACKETS
;
9087 DEFUN (no_debug_msdp_packets
,
9088 no_debug_msdp_packets_cmd
,
9089 "no debug msdp packets",
9093 DEBUG_MSDP_PACKETS_STR
)
9095 PIM_DONT_DEBUG_MSDP_PACKETS
;
9099 DEFUN (debug_mtrace
,
9105 PIM_DO_DEBUG_MTRACE
;
9109 DEFUN (no_debug_mtrace
,
9110 no_debug_mtrace_cmd
,
9116 PIM_DONT_DEBUG_MTRACE
;
9131 DEFUN (no_debug_bsm
,
9144 DEFUN_NOSH (show_debugging_pim
,
9145 show_debugging_pim_cmd
,
9146 "show debugging [pim]",
9151 vty_out(vty
, "PIM debugging status\n");
9153 pim_debug_config_write(vty
);
9158 static int interface_pim_use_src_cmd_worker(struct vty
*vty
, const char *source
)
9161 struct in_addr source_addr
;
9162 int ret
= CMD_SUCCESS
;
9163 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9165 result
= inet_pton(AF_INET
, source
, &source_addr
);
9167 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", source
,
9168 errno
, safe_strerror(errno
));
9169 return CMD_WARNING_CONFIG_FAILED
;
9172 result
= pim_update_source_set(ifp
, source_addr
);
9176 case PIM_IFACE_NOT_FOUND
:
9177 ret
= CMD_WARNING_CONFIG_FAILED
;
9178 vty_out(vty
, "Pim not enabled on this interface\n");
9180 case PIM_UPDATE_SOURCE_DUP
:
9182 vty_out(vty
, "%% Source already set to %s\n", source
);
9185 ret
= CMD_WARNING_CONFIG_FAILED
;
9186 vty_out(vty
, "%% Source set failed\n");
9192 DEFUN (interface_pim_use_source
,
9193 interface_pim_use_source_cmd
,
9194 "ip pim use-source A.B.C.D",
9197 "Configure primary IP address\n"
9198 "source ip address\n")
9200 return interface_pim_use_src_cmd_worker(vty
, argv
[3]->arg
);
9203 DEFUN (interface_no_pim_use_source
,
9204 interface_no_pim_use_source_cmd
,
9205 "no ip pim use-source [A.B.C.D]",
9209 "Delete source IP address\n"
9210 "source ip address\n")
9212 return interface_pim_use_src_cmd_worker(vty
, "0.0.0.0");
9220 "Enables BFD support\n")
9222 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9223 struct pim_interface
*pim_ifp
= ifp
->info
;
9224 struct bfd_info
*bfd_info
= NULL
;
9227 if (!pim_cmd_interface_add(vty
, ifp
)) {
9229 "Could not enable PIM SM on interface %s\n",
9234 pim_ifp
= ifp
->info
;
9236 bfd_info
= pim_ifp
->bfd_info
;
9238 if (!bfd_info
|| !CHECK_FLAG(bfd_info
->flags
, BFD_FLAG_PARAM_CFG
))
9239 pim_bfd_if_param_set(ifp
, BFD_DEF_MIN_RX
, BFD_DEF_MIN_TX
,
9240 BFD_DEF_DETECT_MULT
, 1);
9245 DEFUN (no_ip_pim_bfd
,
9251 "Disables BFD support\n")
9253 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9254 struct pim_interface
*pim_ifp
= ifp
->info
;
9257 vty_out(vty
, "Pim not enabled on this interface\n");
9261 if (pim_ifp
->bfd_info
) {
9262 pim_bfd_reg_dereg_all_nbr(ifp
, ZEBRA_BFD_DEST_DEREGISTER
);
9263 bfd_info_free(&(pim_ifp
->bfd_info
));
9274 "Enables BSM support on the interface\n")
9276 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9277 struct pim_interface
*pim_ifp
= ifp
->info
;
9280 if (!pim_cmd_interface_add(vty
, ifp
)) {
9282 "Could not enable PIM SM on interface %s\n",
9288 pim_ifp
= ifp
->info
;
9289 pim_ifp
->bsm_enable
= true;
9294 DEFUN (no_ip_pim_bsm
,
9300 "Disables BSM support\n")
9302 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9303 struct pim_interface
*pim_ifp
= ifp
->info
;
9306 vty_out(vty
, "Pim not enabled on this interface\n");
9310 pim_ifp
->bsm_enable
= false;
9315 DEFUN (ip_pim_ucast_bsm
,
9316 ip_pim_ucast_bsm_cmd
,
9317 "ip pim unicast-bsm",
9320 "Accept/Send unicast BSM on the interface\n")
9322 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9323 struct pim_interface
*pim_ifp
= ifp
->info
;
9326 if (!pim_cmd_interface_add(vty
, ifp
)) {
9328 "Could not enable PIM SM on interface %s\n",
9334 pim_ifp
= ifp
->info
;
9335 pim_ifp
->ucast_bsm_accept
= true;
9340 DEFUN (no_ip_pim_ucast_bsm
,
9341 no_ip_pim_ucast_bsm_cmd
,
9342 "no ip pim unicast-bsm",
9346 "Block send/receive unicast BSM on this interface\n")
9348 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9349 struct pim_interface
*pim_ifp
= ifp
->info
;
9352 vty_out(vty
, "Pim not enabled on this interface\n");
9356 pim_ifp
->ucast_bsm_accept
= false;
9364 ip_pim_bfd_param_cmd
,
9365 "ip pim bfd (2-255) (50-60000) (50-60000)",
9368 "Enables BFD support\n"
9369 "Detect Multiplier\n"
9370 "Required min receive interval\n"
9371 "Desired min transmit interval\n")
9375 ip_pim_bfd_param_cmd
,
9376 "ip pim bfd (2-255) (50-60000) (50-60000)",
9379 "Enables BFD support\n"
9380 "Detect Multiplier\n"
9381 "Required min receive interval\n"
9382 "Desired min transmit interval\n")
9383 #endif /* HAVE_BFDD */
9385 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9387 int idx_number_2
= 4;
9388 int idx_number_3
= 5;
9393 struct pim_interface
*pim_ifp
= ifp
->info
;
9396 if (!pim_cmd_interface_add(vty
, ifp
)) {
9398 "Could not enable PIM SM on interface %s\n",
9404 if ((ret
= bfd_validate_param(
9405 vty
, argv
[idx_number
]->arg
, argv
[idx_number_2
]->arg
,
9406 argv
[idx_number_3
]->arg
, &dm_val
, &rx_val
, &tx_val
))
9410 pim_bfd_if_param_set(ifp
, rx_val
, tx_val
, dm_val
, 0);
9416 ALIAS(no_ip_pim_bfd
, no_ip_pim_bfd_param_cmd
,
9417 "no ip pim bfd (2-255) (50-60000) (50-60000)", NO_STR IP_STR PIM_STR
9418 "Enables BFD support\n"
9419 "Detect Multiplier\n"
9420 "Required min receive interval\n"
9421 "Desired min transmit interval\n")
9422 #endif /* !HAVE_BFDD */
9424 static int ip_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
9425 const char *peer
, const char *local
)
9427 enum pim_msdp_err result
;
9428 struct in_addr peer_addr
;
9429 struct in_addr local_addr
;
9430 int ret
= CMD_SUCCESS
;
9432 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
9434 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
9435 errno
, safe_strerror(errno
));
9436 return CMD_WARNING_CONFIG_FAILED
;
9439 result
= inet_pton(AF_INET
, local
, &local_addr
);
9441 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", local
,
9442 errno
, safe_strerror(errno
));
9443 return CMD_WARNING_CONFIG_FAILED
;
9446 result
= pim_msdp_peer_add(pim
, peer_addr
, local_addr
, "default",
9449 case PIM_MSDP_ERR_NONE
:
9451 case PIM_MSDP_ERR_OOM
:
9452 ret
= CMD_WARNING_CONFIG_FAILED
;
9453 vty_out(vty
, "%% Out of memory\n");
9455 case PIM_MSDP_ERR_PEER_EXISTS
:
9457 vty_out(vty
, "%% Peer exists\n");
9459 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
9460 ret
= CMD_WARNING_CONFIG_FAILED
;
9461 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
9464 ret
= CMD_WARNING_CONFIG_FAILED
;
9465 vty_out(vty
, "%% peer add failed\n");
9471 DEFUN_HIDDEN (ip_msdp_peer
,
9473 "ip msdp peer A.B.C.D source A.B.C.D",
9476 "Configure MSDP peer\n"
9478 "Source address for TCP connection\n"
9479 "local ip address\n")
9481 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9482 return ip_msdp_peer_cmd_worker(pim
, vty
, argv
[3]->arg
, argv
[5]->arg
);
9485 static int ip_no_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
9488 enum pim_msdp_err result
;
9489 struct in_addr peer_addr
;
9491 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
9493 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
9494 errno
, safe_strerror(errno
));
9495 return CMD_WARNING_CONFIG_FAILED
;
9498 result
= pim_msdp_peer_del(pim
, peer_addr
);
9500 case PIM_MSDP_ERR_NONE
:
9502 case PIM_MSDP_ERR_NO_PEER
:
9503 vty_out(vty
, "%% Peer does not exist\n");
9506 vty_out(vty
, "%% peer del failed\n");
9509 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9512 DEFUN_HIDDEN (no_ip_msdp_peer
,
9513 no_ip_msdp_peer_cmd
,
9514 "no ip msdp peer A.B.C.D",
9518 "Delete MSDP peer\n"
9519 "peer ip address\n")
9521 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9522 return ip_no_msdp_peer_cmd_worker(pim
, vty
, argv
[4]->arg
);
9525 static int ip_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
9526 struct vty
*vty
, const char *mg
,
9529 enum pim_msdp_err result
;
9530 struct in_addr mbr_ip
;
9531 int ret
= CMD_SUCCESS
;
9533 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
9535 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
9536 errno
, safe_strerror(errno
));
9537 return CMD_WARNING_CONFIG_FAILED
;
9540 result
= pim_msdp_mg_mbr_add(pim
, mg
, mbr_ip
);
9542 case PIM_MSDP_ERR_NONE
:
9544 case PIM_MSDP_ERR_OOM
:
9545 ret
= CMD_WARNING_CONFIG_FAILED
;
9546 vty_out(vty
, "%% Out of memory\n");
9548 case PIM_MSDP_ERR_MG_MBR_EXISTS
:
9550 vty_out(vty
, "%% mesh-group member exists\n");
9552 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
9553 ret
= CMD_WARNING_CONFIG_FAILED
;
9554 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
9557 ret
= CMD_WARNING_CONFIG_FAILED
;
9558 vty_out(vty
, "%% member add failed\n");
9564 DEFUN (ip_msdp_mesh_group_member
,
9565 ip_msdp_mesh_group_member_cmd
,
9566 "ip msdp mesh-group WORD member A.B.C.D",
9569 "Configure MSDP mesh-group\n"
9571 "mesh group member\n"
9572 "peer ip address\n")
9574 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9575 return ip_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[3]->arg
,
9579 static int ip_no_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
9584 enum pim_msdp_err result
;
9585 struct in_addr mbr_ip
;
9587 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
9589 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
9590 errno
, safe_strerror(errno
));
9591 return CMD_WARNING_CONFIG_FAILED
;
9594 result
= pim_msdp_mg_mbr_del(pim
, mg
, mbr_ip
);
9596 case PIM_MSDP_ERR_NONE
:
9598 case PIM_MSDP_ERR_NO_MG
:
9599 vty_out(vty
, "%% mesh-group does not exist\n");
9601 case PIM_MSDP_ERR_NO_MG_MBR
:
9602 vty_out(vty
, "%% mesh-group member does not exist\n");
9605 vty_out(vty
, "%% mesh-group member del failed\n");
9608 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9610 DEFUN (no_ip_msdp_mesh_group_member
,
9611 no_ip_msdp_mesh_group_member_cmd
,
9612 "no ip msdp mesh-group WORD member A.B.C.D",
9616 "Delete MSDP mesh-group member\n"
9618 "mesh group member\n"
9619 "peer ip address\n")
9621 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9622 return ip_no_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[4]->arg
,
9626 static int ip_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
9627 struct vty
*vty
, const char *mg
,
9630 enum pim_msdp_err result
;
9631 struct in_addr src_ip
;
9633 result
= inet_pton(AF_INET
, src
, &src_ip
);
9635 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", src
,
9636 errno
, safe_strerror(errno
));
9637 return CMD_WARNING_CONFIG_FAILED
;
9640 result
= pim_msdp_mg_src_add(pim
, mg
, src_ip
);
9642 case PIM_MSDP_ERR_NONE
:
9644 case PIM_MSDP_ERR_OOM
:
9645 vty_out(vty
, "%% Out of memory\n");
9647 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
9648 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
9651 vty_out(vty
, "%% source add failed\n");
9654 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9658 DEFUN (ip_msdp_mesh_group_source
,
9659 ip_msdp_mesh_group_source_cmd
,
9660 "ip msdp mesh-group WORD source A.B.C.D",
9663 "Configure MSDP mesh-group\n"
9665 "mesh group local address\n"
9666 "source ip address for the TCP connection\n")
9668 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9669 return ip_msdp_mesh_group_source_cmd_worker(pim
, vty
, argv
[3]->arg
,
9673 static int ip_no_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
9677 enum pim_msdp_err result
;
9679 result
= pim_msdp_mg_src_del(pim
, mg
);
9681 case PIM_MSDP_ERR_NONE
:
9683 case PIM_MSDP_ERR_NO_MG
:
9684 vty_out(vty
, "%% mesh-group does not exist\n");
9687 vty_out(vty
, "%% mesh-group source del failed\n");
9690 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9693 static int ip_no_msdp_mesh_group_cmd_worker(struct pim_instance
*pim
,
9694 struct vty
*vty
, const char *mg
)
9696 enum pim_msdp_err result
;
9698 result
= pim_msdp_mg_del(pim
, mg
);
9700 case PIM_MSDP_ERR_NONE
:
9702 case PIM_MSDP_ERR_NO_MG
:
9703 vty_out(vty
, "%% mesh-group does not exist\n");
9706 vty_out(vty
, "%% mesh-group source del failed\n");
9709 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9712 DEFUN (no_ip_msdp_mesh_group_source
,
9713 no_ip_msdp_mesh_group_source_cmd
,
9714 "no ip msdp mesh-group WORD source [A.B.C.D]",
9718 "Delete MSDP mesh-group source\n"
9720 "mesh group source\n"
9721 "mesh group local address\n")
9723 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9725 return ip_no_msdp_mesh_group_source_cmd_worker(pim
, vty
, argv
[4]->arg
);
9728 DEFUN (no_ip_msdp_mesh_group
,
9729 no_ip_msdp_mesh_group_cmd
,
9730 "no ip msdp mesh-group [WORD]",
9734 "Delete MSDP mesh-group\n"
9737 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9740 return ip_no_msdp_mesh_group_cmd_worker(pim
, vty
, argv
[4]->arg
);
9742 return ip_no_msdp_mesh_group_cmd_worker(pim
, vty
, NULL
);
9745 static void print_empty_json_obj(struct vty
*vty
)
9748 json
= json_object_new_object();
9749 vty_out(vty
, "%s\n",
9750 json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
));
9751 json_object_free(json
);
9754 static void ip_msdp_show_mesh_group(struct pim_instance
*pim
, struct vty
*vty
,
9757 struct listnode
*mbrnode
;
9758 struct pim_msdp_mg_mbr
*mbr
;
9759 struct pim_msdp_mg
*mg
= pim
->msdp
.mg
;
9760 char mbr_str
[INET_ADDRSTRLEN
];
9761 char src_str
[INET_ADDRSTRLEN
];
9762 char state_str
[PIM_MSDP_STATE_STRLEN
];
9763 enum pim_msdp_peer_state state
;
9764 json_object
*json
= NULL
;
9765 json_object
*json_mg_row
= NULL
;
9766 json_object
*json_members
= NULL
;
9767 json_object
*json_row
= NULL
;
9771 print_empty_json_obj(vty
);
9775 pim_inet4_dump("<source?>", mg
->src_ip
, src_str
, sizeof(src_str
));
9777 json
= json_object_new_object();
9778 /* currently there is only one mesh group but we should still
9780 * it a dict with mg-name as key */
9781 json_mg_row
= json_object_new_object();
9782 json_object_string_add(json_mg_row
, "name",
9783 mg
->mesh_group_name
);
9784 json_object_string_add(json_mg_row
, "source", src_str
);
9786 vty_out(vty
, "Mesh group : %s\n", mg
->mesh_group_name
);
9787 vty_out(vty
, " Source : %s\n", src_str
);
9788 vty_out(vty
, " Member State\n");
9791 for (ALL_LIST_ELEMENTS_RO(mg
->mbr_list
, mbrnode
, mbr
)) {
9792 pim_inet4_dump("<mbr?>", mbr
->mbr_ip
, mbr_str
, sizeof(mbr_str
));
9794 state
= mbr
->mp
->state
;
9796 state
= PIM_MSDP_DISABLED
;
9798 pim_msdp_state_dump(state
, state_str
, sizeof(state_str
));
9800 json_row
= json_object_new_object();
9801 json_object_string_add(json_row
, "member", mbr_str
);
9802 json_object_string_add(json_row
, "state", state_str
);
9803 if (!json_members
) {
9804 json_members
= json_object_new_object();
9805 json_object_object_add(json_mg_row
, "members",
9808 json_object_object_add(json_members
, mbr_str
, json_row
);
9810 vty_out(vty
, " %-15s %11s\n", mbr_str
, state_str
);
9815 json_object_object_add(json
, mg
->mesh_group_name
, json_mg_row
);
9816 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9817 json
, JSON_C_TO_STRING_PRETTY
));
9818 json_object_free(json
);
9822 DEFUN (show_ip_msdp_mesh_group
,
9823 show_ip_msdp_mesh_group_cmd
,
9824 "show ip msdp [vrf NAME] mesh-group [json]",
9829 "MSDP mesh-group information\n"
9832 bool uj
= use_json(argc
, argv
);
9834 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
9839 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
9844 DEFUN (show_ip_msdp_mesh_group_vrf_all
,
9845 show_ip_msdp_mesh_group_vrf_all_cmd
,
9846 "show ip msdp vrf all mesh-group [json]",
9851 "MSDP mesh-group information\n"
9854 bool uj
= use_json(argc
, argv
);
9860 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
9864 vty_out(vty
, " \"%s\": ", vrf
->name
);
9867 vty_out(vty
, "VRF: %s\n", vrf
->name
);
9868 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
9871 vty_out(vty
, "}\n");
9876 static void ip_msdp_show_peers(struct pim_instance
*pim
, struct vty
*vty
,
9879 struct listnode
*mpnode
;
9880 struct pim_msdp_peer
*mp
;
9881 char peer_str
[INET_ADDRSTRLEN
];
9882 char local_str
[INET_ADDRSTRLEN
];
9883 char state_str
[PIM_MSDP_STATE_STRLEN
];
9884 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
9886 json_object
*json
= NULL
;
9887 json_object
*json_row
= NULL
;
9891 json
= json_object_new_object();
9894 "Peer Local State Uptime SaCnt\n");
9897 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
9898 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
9899 now
= pim_time_monotonic_sec();
9900 pim_time_uptime(timebuf
, sizeof(timebuf
),
9903 strlcpy(timebuf
, "-", sizeof(timebuf
));
9905 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
9906 pim_inet4_dump("<local?>", mp
->local
, local_str
,
9908 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
9910 json_row
= json_object_new_object();
9911 json_object_string_add(json_row
, "peer", peer_str
);
9912 json_object_string_add(json_row
, "local", local_str
);
9913 json_object_string_add(json_row
, "state", state_str
);
9914 json_object_string_add(json_row
, "upTime", timebuf
);
9915 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
9916 json_object_object_add(json
, peer_str
, json_row
);
9918 vty_out(vty
, "%-15s %15s %11s %8s %6d\n", peer_str
,
9919 local_str
, state_str
, timebuf
, mp
->sa_cnt
);
9924 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9925 json
, JSON_C_TO_STRING_PRETTY
));
9926 json_object_free(json
);
9930 static void ip_msdp_show_peers_detail(struct pim_instance
*pim
, struct vty
*vty
,
9931 const char *peer
, bool uj
)
9933 struct listnode
*mpnode
;
9934 struct pim_msdp_peer
*mp
;
9935 char peer_str
[INET_ADDRSTRLEN
];
9936 char local_str
[INET_ADDRSTRLEN
];
9937 char state_str
[PIM_MSDP_STATE_STRLEN
];
9938 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
9939 char katimer
[PIM_MSDP_TIMER_STRLEN
];
9940 char crtimer
[PIM_MSDP_TIMER_STRLEN
];
9941 char holdtimer
[PIM_MSDP_TIMER_STRLEN
];
9943 json_object
*json
= NULL
;
9944 json_object
*json_row
= NULL
;
9947 json
= json_object_new_object();
9950 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
9951 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
9952 if (strcmp(peer
, "detail") && strcmp(peer
, peer_str
))
9955 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
9956 now
= pim_time_monotonic_sec();
9957 pim_time_uptime(timebuf
, sizeof(timebuf
),
9960 strlcpy(timebuf
, "-", sizeof(timebuf
));
9962 pim_inet4_dump("<local?>", mp
->local
, local_str
,
9964 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
9965 pim_time_timer_to_hhmmss(katimer
, sizeof(katimer
),
9967 pim_time_timer_to_hhmmss(crtimer
, sizeof(crtimer
),
9969 pim_time_timer_to_hhmmss(holdtimer
, sizeof(holdtimer
),
9973 json_row
= json_object_new_object();
9974 json_object_string_add(json_row
, "peer", peer_str
);
9975 json_object_string_add(json_row
, "local", local_str
);
9976 json_object_string_add(json_row
, "meshGroupName",
9977 mp
->mesh_group_name
);
9978 json_object_string_add(json_row
, "state", state_str
);
9979 json_object_string_add(json_row
, "upTime", timebuf
);
9980 json_object_string_add(json_row
, "keepAliveTimer",
9982 json_object_string_add(json_row
, "connRetryTimer",
9984 json_object_string_add(json_row
, "holdTimer",
9986 json_object_string_add(json_row
, "lastReset",
9988 json_object_int_add(json_row
, "connAttempts",
9990 json_object_int_add(json_row
, "establishedChanges",
9992 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
9993 json_object_int_add(json_row
, "kaSent", mp
->ka_tx_cnt
);
9994 json_object_int_add(json_row
, "kaRcvd", mp
->ka_rx_cnt
);
9995 json_object_int_add(json_row
, "saSent", mp
->sa_tx_cnt
);
9996 json_object_int_add(json_row
, "saRcvd", mp
->sa_rx_cnt
);
9997 json_object_object_add(json
, peer_str
, json_row
);
9999 vty_out(vty
, "Peer : %s\n", peer_str
);
10000 vty_out(vty
, " Local : %s\n", local_str
);
10001 vty_out(vty
, " Mesh Group : %s\n",
10002 mp
->mesh_group_name
);
10003 vty_out(vty
, " State : %s\n", state_str
);
10004 vty_out(vty
, " Uptime : %s\n", timebuf
);
10006 vty_out(vty
, " Keepalive Timer : %s\n", katimer
);
10007 vty_out(vty
, " Conn Retry Timer : %s\n", crtimer
);
10008 vty_out(vty
, " Hold Timer : %s\n", holdtimer
);
10009 vty_out(vty
, " Last Reset : %s\n",
10011 vty_out(vty
, " Conn Attempts : %d\n",
10012 mp
->conn_attempts
);
10013 vty_out(vty
, " Established Changes : %d\n",
10015 vty_out(vty
, " SA Count : %d\n",
10017 vty_out(vty
, " Statistics :\n");
10020 vty_out(vty
, " Keepalives : %10d %10d\n",
10021 mp
->ka_tx_cnt
, mp
->ka_rx_cnt
);
10022 vty_out(vty
, " SAs : %10d %10d\n",
10023 mp
->sa_tx_cnt
, mp
->sa_rx_cnt
);
10024 vty_out(vty
, "\n");
10029 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10030 json
, JSON_C_TO_STRING_PRETTY
));
10031 json_object_free(json
);
10035 DEFUN (show_ip_msdp_peer_detail
,
10036 show_ip_msdp_peer_detail_cmd
,
10037 "show ip msdp [vrf NAME] peer [detail|A.B.C.D] [json]",
10042 "MSDP peer information\n"
10043 "Detailed output\n"
10044 "peer ip address\n"
10047 bool uj
= use_json(argc
, argv
);
10049 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10052 return CMD_WARNING
;
10056 if (argv_find(argv
, argc
, "detail", &idx
))
10057 arg
= argv
[idx
]->text
;
10058 else if (argv_find(argv
, argc
, "A.B.C.D", &idx
))
10059 arg
= argv
[idx
]->arg
;
10062 ip_msdp_show_peers_detail(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
10064 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
10066 return CMD_SUCCESS
;
10069 DEFUN (show_ip_msdp_peer_detail_vrf_all
,
10070 show_ip_msdp_peer_detail_vrf_all_cmd
,
10071 "show ip msdp vrf all peer [detail|A.B.C.D] [json]",
10076 "MSDP peer information\n"
10077 "Detailed output\n"
10078 "peer ip address\n"
10082 bool uj
= use_json(argc
, argv
);
10087 vty_out(vty
, "{ ");
10088 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
10091 vty_out(vty
, ", ");
10092 vty_out(vty
, " \"%s\": ", vrf
->name
);
10095 vty_out(vty
, "VRF: %s\n", vrf
->name
);
10096 if (argv_find(argv
, argc
, "detail", &idx
)
10097 || argv_find(argv
, argc
, "A.B.C.D", &idx
))
10098 ip_msdp_show_peers_detail(vrf
->info
, vty
,
10099 argv
[idx
]->arg
, uj
);
10101 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
10104 vty_out(vty
, "}\n");
10106 return CMD_SUCCESS
;
10109 static void ip_msdp_show_sa(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
10111 struct listnode
*sanode
;
10112 struct pim_msdp_sa
*sa
;
10113 char src_str
[INET_ADDRSTRLEN
];
10114 char grp_str
[INET_ADDRSTRLEN
];
10115 char rp_str
[INET_ADDRSTRLEN
];
10116 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
10120 json_object
*json
= NULL
;
10121 json_object
*json_group
= NULL
;
10122 json_object
*json_row
= NULL
;
10125 json
= json_object_new_object();
10128 "Source Group RP Local SPT Uptime\n");
10131 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
10132 now
= pim_time_monotonic_sec();
10133 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
10134 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
10135 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
10136 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
10137 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
10139 strlcpy(spt_str
, "yes", sizeof(spt_str
));
10141 strlcpy(spt_str
, "no", sizeof(spt_str
));
10144 strlcpy(rp_str
, "-", sizeof(rp_str
));
10145 strlcpy(spt_str
, "-", sizeof(spt_str
));
10147 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
10148 strlcpy(local_str
, "yes", sizeof(local_str
));
10150 strlcpy(local_str
, "no", sizeof(local_str
));
10153 json_object_object_get_ex(json
, grp_str
, &json_group
);
10156 json_group
= json_object_new_object();
10157 json_object_object_add(json
, grp_str
,
10161 json_row
= json_object_new_object();
10162 json_object_string_add(json_row
, "source", src_str
);
10163 json_object_string_add(json_row
, "group", grp_str
);
10164 json_object_string_add(json_row
, "rp", rp_str
);
10165 json_object_string_add(json_row
, "local", local_str
);
10166 json_object_string_add(json_row
, "sptSetup", spt_str
);
10167 json_object_string_add(json_row
, "upTime", timebuf
);
10168 json_object_object_add(json_group
, src_str
, json_row
);
10170 vty_out(vty
, "%-15s %15s %15s %5c %3c %8s\n",
10171 src_str
, grp_str
, rp_str
, local_str
[0],
10172 spt_str
[0], timebuf
);
10177 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10178 json
, JSON_C_TO_STRING_PRETTY
));
10179 json_object_free(json
);
10183 static void ip_msdp_show_sa_entry_detail(struct pim_msdp_sa
*sa
,
10184 const char *src_str
,
10185 const char *grp_str
, struct vty
*vty
,
10186 bool uj
, json_object
*json
)
10188 char rp_str
[INET_ADDRSTRLEN
];
10189 char peer_str
[INET_ADDRSTRLEN
];
10190 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
10193 char statetimer
[PIM_MSDP_TIMER_STRLEN
];
10195 json_object
*json_group
= NULL
;
10196 json_object
*json_row
= NULL
;
10198 now
= pim_time_monotonic_sec();
10199 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
10200 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
10201 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
10202 pim_inet4_dump("<peer?>", sa
->peer
, peer_str
, sizeof(peer_str
));
10204 strlcpy(spt_str
, "yes", sizeof(spt_str
));
10206 strlcpy(spt_str
, "no", sizeof(spt_str
));
10209 strlcpy(rp_str
, "-", sizeof(rp_str
));
10210 strlcpy(peer_str
, "-", sizeof(peer_str
));
10211 strlcpy(spt_str
, "-", sizeof(spt_str
));
10213 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
10214 strlcpy(local_str
, "yes", sizeof(local_str
));
10216 strlcpy(local_str
, "no", sizeof(local_str
));
10218 pim_time_timer_to_hhmmss(statetimer
, sizeof(statetimer
),
10219 sa
->sa_state_timer
);
10221 json_object_object_get_ex(json
, grp_str
, &json_group
);
10224 json_group
= json_object_new_object();
10225 json_object_object_add(json
, grp_str
, json_group
);
10228 json_row
= json_object_new_object();
10229 json_object_string_add(json_row
, "source", src_str
);
10230 json_object_string_add(json_row
, "group", grp_str
);
10231 json_object_string_add(json_row
, "rp", rp_str
);
10232 json_object_string_add(json_row
, "local", local_str
);
10233 json_object_string_add(json_row
, "sptSetup", spt_str
);
10234 json_object_string_add(json_row
, "upTime", timebuf
);
10235 json_object_string_add(json_row
, "stateTimer", statetimer
);
10236 json_object_object_add(json_group
, src_str
, json_row
);
10238 vty_out(vty
, "SA : %s\n", sa
->sg_str
);
10239 vty_out(vty
, " RP : %s\n", rp_str
);
10240 vty_out(vty
, " Peer : %s\n", peer_str
);
10241 vty_out(vty
, " Local : %s\n", local_str
);
10242 vty_out(vty
, " SPT Setup : %s\n", spt_str
);
10243 vty_out(vty
, " Uptime : %s\n", timebuf
);
10244 vty_out(vty
, " State Timer : %s\n", statetimer
);
10245 vty_out(vty
, "\n");
10249 static void ip_msdp_show_sa_detail(struct pim_instance
*pim
, struct vty
*vty
,
10252 struct listnode
*sanode
;
10253 struct pim_msdp_sa
*sa
;
10254 char src_str
[INET_ADDRSTRLEN
];
10255 char grp_str
[INET_ADDRSTRLEN
];
10256 json_object
*json
= NULL
;
10259 json
= json_object_new_object();
10262 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
10263 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
10264 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
10265 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
, uj
,
10270 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10271 json
, JSON_C_TO_STRING_PRETTY
));
10272 json_object_free(json
);
10276 DEFUN (show_ip_msdp_sa_detail
,
10277 show_ip_msdp_sa_detail_cmd
,
10278 "show ip msdp [vrf NAME] sa detail [json]",
10283 "MSDP active-source information\n"
10284 "Detailed output\n"
10287 bool uj
= use_json(argc
, argv
);
10289 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10292 return CMD_WARNING
;
10294 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
10296 return CMD_SUCCESS
;
10299 DEFUN (show_ip_msdp_sa_detail_vrf_all
,
10300 show_ip_msdp_sa_detail_vrf_all_cmd
,
10301 "show ip msdp vrf all sa detail [json]",
10306 "MSDP active-source information\n"
10307 "Detailed output\n"
10310 bool uj
= use_json(argc
, argv
);
10315 vty_out(vty
, "{ ");
10316 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
10319 vty_out(vty
, ", ");
10320 vty_out(vty
, " \"%s\": ", vrf
->name
);
10323 vty_out(vty
, "VRF: %s\n", vrf
->name
);
10324 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
10327 vty_out(vty
, "}\n");
10329 return CMD_SUCCESS
;
10332 static void ip_msdp_show_sa_addr(struct pim_instance
*pim
, struct vty
*vty
,
10333 const char *addr
, bool uj
)
10335 struct listnode
*sanode
;
10336 struct pim_msdp_sa
*sa
;
10337 char src_str
[INET_ADDRSTRLEN
];
10338 char grp_str
[INET_ADDRSTRLEN
];
10339 json_object
*json
= NULL
;
10342 json
= json_object_new_object();
10345 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
10346 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
10347 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
10348 if (!strcmp(addr
, src_str
) || !strcmp(addr
, grp_str
)) {
10349 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
10355 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10356 json
, JSON_C_TO_STRING_PRETTY
));
10357 json_object_free(json
);
10361 static void ip_msdp_show_sa_sg(struct pim_instance
*pim
, struct vty
*vty
,
10362 const char *src
, const char *grp
, bool uj
)
10364 struct listnode
*sanode
;
10365 struct pim_msdp_sa
*sa
;
10366 char src_str
[INET_ADDRSTRLEN
];
10367 char grp_str
[INET_ADDRSTRLEN
];
10368 json_object
*json
= NULL
;
10371 json
= json_object_new_object();
10374 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
10375 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
10376 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
10377 if (!strcmp(src
, src_str
) && !strcmp(grp
, grp_str
)) {
10378 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
10384 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10385 json
, JSON_C_TO_STRING_PRETTY
));
10386 json_object_free(json
);
10390 DEFUN (show_ip_msdp_sa_sg
,
10391 show_ip_msdp_sa_sg_cmd
,
10392 "show ip msdp [vrf NAME] sa [A.B.C.D [A.B.C.D]] [json]",
10397 "MSDP active-source information\n"
10398 "source or group ip\n"
10402 bool uj
= use_json(argc
, argv
);
10406 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10409 return CMD_WARNING
;
10411 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
10413 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
10417 if (src_ip
&& grp_ip
)
10418 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
10420 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
10422 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
10424 return CMD_SUCCESS
;
10427 DEFUN (show_ip_msdp_sa_sg_vrf_all
,
10428 show_ip_msdp_sa_sg_vrf_all_cmd
,
10429 "show ip msdp vrf all sa [A.B.C.D [A.B.C.D]] [json]",
10434 "MSDP active-source information\n"
10435 "source or group ip\n"
10439 bool uj
= use_json(argc
, argv
);
10444 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
10446 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
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
);
10461 if (src_ip
&& grp_ip
)
10462 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
10464 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
10466 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
10469 vty_out(vty
, "}\n");
10471 return CMD_SUCCESS
;
10474 struct pim_sg_cache_walk_data
{
10477 json_object
*json_group
;
10478 struct in_addr addr
;
10482 static void pim_show_vxlan_sg_entry(struct pim_vxlan_sg
*vxlan_sg
,
10483 struct pim_sg_cache_walk_data
*cwd
)
10485 struct vty
*vty
= cwd
->vty
;
10486 json_object
*json
= cwd
->json
;
10487 char src_str
[INET_ADDRSTRLEN
];
10488 char grp_str
[INET_ADDRSTRLEN
];
10489 json_object
*json_row
;
10490 bool installed
= (vxlan_sg
->up
) ? true : false;
10491 const char *iif_name
= vxlan_sg
->iif
?vxlan_sg
->iif
->name
:"-";
10492 const char *oif_name
;
10494 if (pim_vxlan_is_orig_mroute(vxlan_sg
))
10495 oif_name
= vxlan_sg
->orig_oif
?vxlan_sg
->orig_oif
->name
:"";
10497 oif_name
= vxlan_sg
->term_oif
?vxlan_sg
->term_oif
->name
:"";
10499 if (cwd
->addr_match
&& (vxlan_sg
->sg
.src
.s_addr
!= cwd
->addr
.s_addr
) &&
10500 (vxlan_sg
->sg
.grp
.s_addr
!= cwd
->addr
.s_addr
)) {
10503 pim_inet4_dump("<src?>", vxlan_sg
->sg
.src
, src_str
, sizeof(src_str
));
10504 pim_inet4_dump("<grp?>", vxlan_sg
->sg
.grp
, grp_str
, sizeof(grp_str
));
10506 json_object_object_get_ex(json
, grp_str
, &cwd
->json_group
);
10508 if (!cwd
->json_group
) {
10509 cwd
->json_group
= json_object_new_object();
10510 json_object_object_add(json
, grp_str
,
10514 json_row
= json_object_new_object();
10515 json_object_string_add(json_row
, "source", src_str
);
10516 json_object_string_add(json_row
, "group", grp_str
);
10517 json_object_string_add(json_row
, "input", iif_name
);
10518 json_object_string_add(json_row
, "output", oif_name
);
10520 json_object_boolean_true_add(json_row
, "installed");
10522 json_object_boolean_false_add(json_row
, "installed");
10523 json_object_object_add(cwd
->json_group
, src_str
, json_row
);
10525 vty_out(vty
, "%-15s %-15s %-15s %-15s %-5s\n",
10526 src_str
, grp_str
, iif_name
, oif_name
,
10531 static void pim_show_vxlan_sg_hash_entry(struct hash_bucket
*backet
, void *arg
)
10533 pim_show_vxlan_sg_entry((struct pim_vxlan_sg
*)backet
->data
,
10534 (struct pim_sg_cache_walk_data
*)arg
);
10537 static void pim_show_vxlan_sg(struct pim_instance
*pim
,
10538 struct vty
*vty
, bool uj
)
10540 json_object
*json
= NULL
;
10541 struct pim_sg_cache_walk_data cwd
;
10544 json
= json_object_new_object();
10546 vty_out(vty
, "Codes: I -> installed\n");
10548 "Source Group Input Output Flags\n");
10551 memset(&cwd
, 0, sizeof(cwd
));
10554 hash_iterate(pim
->vxlan
.sg_hash
, pim_show_vxlan_sg_hash_entry
, &cwd
);
10557 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10558 json
, JSON_C_TO_STRING_PRETTY
));
10559 json_object_free(json
);
10563 static void pim_show_vxlan_sg_match_addr(struct pim_instance
*pim
,
10564 struct vty
*vty
, char *addr_str
, bool uj
)
10566 json_object
*json
= NULL
;
10567 struct pim_sg_cache_walk_data cwd
;
10570 memset(&cwd
, 0, sizeof(cwd
));
10571 result
= inet_pton(AF_INET
, addr_str
, &cwd
.addr
);
10573 vty_out(vty
, "Bad address %s: errno=%d: %s\n", addr_str
,
10574 errno
, safe_strerror(errno
));
10579 json
= json_object_new_object();
10581 vty_out(vty
, "Codes: I -> installed\n");
10583 "Source Group Input Output Flags\n");
10588 cwd
.addr_match
= true;
10589 hash_iterate(pim
->vxlan
.sg_hash
, pim_show_vxlan_sg_hash_entry
, &cwd
);
10592 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10593 json
, JSON_C_TO_STRING_PRETTY
));
10594 json_object_free(json
);
10598 static void pim_show_vxlan_sg_one(struct pim_instance
*pim
,
10599 struct vty
*vty
, char *src_str
, char *grp_str
, bool uj
)
10601 json_object
*json
= NULL
;
10602 struct prefix_sg sg
;
10604 struct pim_vxlan_sg
*vxlan_sg
;
10605 const char *iif_name
;
10607 const char *oif_name
;
10609 result
= inet_pton(AF_INET
, src_str
, &sg
.src
);
10611 vty_out(vty
, "Bad src address %s: errno=%d: %s\n", src_str
,
10612 errno
, safe_strerror(errno
));
10615 result
= inet_pton(AF_INET
, grp_str
, &sg
.grp
);
10617 vty_out(vty
, "Bad grp address %s: errno=%d: %s\n", grp_str
,
10618 errno
, safe_strerror(errno
));
10622 sg
.family
= AF_INET
;
10623 sg
.prefixlen
= IPV4_MAX_BITLEN
;
10625 json
= json_object_new_object();
10627 vxlan_sg
= pim_vxlan_sg_find(pim
, &sg
);
10629 installed
= (vxlan_sg
->up
) ? true : false;
10630 iif_name
= vxlan_sg
->iif
?vxlan_sg
->iif
->name
:"-";
10632 if (pim_vxlan_is_orig_mroute(vxlan_sg
))
10634 vxlan_sg
->orig_oif
?vxlan_sg
->orig_oif
->name
:"";
10637 vxlan_sg
->term_oif
?vxlan_sg
->term_oif
->name
:"";
10640 json_object_string_add(json
, "source", src_str
);
10641 json_object_string_add(json
, "group", grp_str
);
10642 json_object_string_add(json
, "input", iif_name
);
10643 json_object_string_add(json
, "output", oif_name
);
10645 json_object_boolean_true_add(json
, "installed");
10647 json_object_boolean_false_add(json
,
10650 vty_out(vty
, "SG : %s\n", vxlan_sg
->sg_str
);
10651 vty_out(vty
, " Input : %s\n", iif_name
);
10652 vty_out(vty
, " Output : %s\n", oif_name
);
10653 vty_out(vty
, " installed : %s\n",
10654 installed
?"yes":"no");
10659 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10660 json
, JSON_C_TO_STRING_PRETTY
));
10661 json_object_free(json
);
10665 DEFUN (show_ip_pim_vxlan_sg
,
10666 show_ip_pim_vxlan_sg_cmd
,
10667 "show ip pim [vrf NAME] vxlan-groups [A.B.C.D [A.B.C.D]] [json]",
10672 "VxLAN BUM groups\n"
10673 "source or group ip\n"
10677 bool uj
= use_json(argc
, argv
);
10681 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10684 return CMD_WARNING
;
10686 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ?
10687 argv
[idx
++]->arg
:NULL
;
10688 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
) ?
10689 argv
[idx
]->arg
:NULL
;
10691 if (src_ip
&& grp_ip
)
10692 pim_show_vxlan_sg_one(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
10694 pim_show_vxlan_sg_match_addr(vrf
->info
, vty
, src_ip
, uj
);
10696 pim_show_vxlan_sg(vrf
->info
, vty
, uj
);
10698 return CMD_SUCCESS
;
10701 static void pim_show_vxlan_sg_work(struct pim_instance
*pim
,
10702 struct vty
*vty
, bool uj
)
10704 json_object
*json
= NULL
;
10705 struct pim_sg_cache_walk_data cwd
;
10706 struct listnode
*node
;
10707 struct pim_vxlan_sg
*vxlan_sg
;
10710 json
= json_object_new_object();
10712 vty_out(vty
, "Codes: I -> installed\n");
10714 "Source Group Input Flags\n");
10717 memset(&cwd
, 0, sizeof(cwd
));
10720 for (ALL_LIST_ELEMENTS_RO(pim_vxlan_p
->work_list
, node
, vxlan_sg
))
10721 pim_show_vxlan_sg_entry(vxlan_sg
, &cwd
);
10724 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10725 json
, JSON_C_TO_STRING_PRETTY
));
10726 json_object_free(json
);
10730 DEFUN_HIDDEN (show_ip_pim_vxlan_sg_work
,
10731 show_ip_pim_vxlan_sg_work_cmd
,
10732 "show ip pim [vrf NAME] vxlan-work [json]",
10737 "VxLAN work list\n"
10740 bool uj
= use_json(argc
, argv
);
10744 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10747 return CMD_WARNING
;
10749 pim_show_vxlan_sg_work(vrf
->info
, vty
, uj
);
10751 return CMD_SUCCESS
;
10754 DEFUN_HIDDEN (no_ip_pim_mlag
,
10755 no_ip_pim_mlag_cmd
,
10762 struct in_addr addr
;
10765 pim_vxlan_mlag_update(true/*mlag_enable*/,
10766 false/*peer_state*/, MLAG_ROLE_NONE
,
10767 NULL
/*peerlink*/, &addr
);
10769 return CMD_SUCCESS
;
10772 DEFUN_HIDDEN (ip_pim_mlag
,
10774 "ip pim mlag INTERFACE role [primary|secondary] state [up|down] addr A.B.C.D",
10778 "peerlink sub interface\n"
10780 "MLAG role primary\n"
10781 "MLAG role secondary\n"
10782 "peer session state\n"
10783 "peer session state up\n"
10784 "peer session state down\n"
10786 "unique ip address\n")
10788 struct interface
*ifp
;
10789 const char *peerlink
;
10794 struct in_addr reg_addr
;
10797 peerlink
= argv
[idx
]->arg
;
10798 ifp
= if_lookup_by_name(peerlink
, VRF_DEFAULT
);
10800 vty_out(vty
, "No such interface name %s\n", peerlink
);
10801 return CMD_WARNING
;
10805 if (!strcmp(argv
[idx
]->arg
, "primary")) {
10806 role
= MLAG_ROLE_PRIMARY
;
10807 } else if (!strcmp(argv
[idx
]->arg
, "secondary")) {
10808 role
= MLAG_ROLE_SECONDARY
;
10810 vty_out(vty
, "unknown MLAG role %s\n", argv
[idx
]->arg
);
10811 return CMD_WARNING
;
10815 if (!strcmp(argv
[idx
]->arg
, "up")) {
10817 } else if (strcmp(argv
[idx
]->arg
, "down")) {
10818 peer_state
= false;
10820 vty_out(vty
, "unknown MLAG state %s\n", argv
[idx
]->arg
);
10821 return CMD_WARNING
;
10825 result
= inet_pton(AF_INET
, argv
[idx
]->arg
, ®_addr
);
10827 vty_out(vty
, "%% Bad reg address %s: errno=%d: %s\n",
10829 errno
, safe_strerror(errno
));
10830 return CMD_WARNING_CONFIG_FAILED
;
10832 pim_vxlan_mlag_update(true, peer_state
, role
, ifp
, ®_addr
);
10834 return CMD_SUCCESS
;
10837 void pim_cmd_init(void)
10839 install_node(&interface_node
); /* INTERFACE_NODE */
10842 install_node(&debug_node
);
10844 install_element(ENABLE_NODE
, &pim_test_sg_keepalive_cmd
);
10846 install_element(CONFIG_NODE
, &ip_pim_rp_cmd
);
10847 install_element(VRF_NODE
, &ip_pim_rp_cmd
);
10848 install_element(CONFIG_NODE
, &no_ip_pim_rp_cmd
);
10849 install_element(VRF_NODE
, &no_ip_pim_rp_cmd
);
10850 install_element(CONFIG_NODE
, &ip_pim_rp_prefix_list_cmd
);
10851 install_element(VRF_NODE
, &ip_pim_rp_prefix_list_cmd
);
10852 install_element(CONFIG_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
10853 install_element(VRF_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
10854 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
10855 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
10856 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
10857 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
10858 install_element(CONFIG_NODE
, &ip_pim_ssm_prefix_list_cmd
);
10859 install_element(VRF_NODE
, &ip_pim_ssm_prefix_list_cmd
);
10860 install_element(CONFIG_NODE
, &ip_pim_register_suppress_cmd
);
10861 install_element(VRF_NODE
, &ip_pim_register_suppress_cmd
);
10862 install_element(CONFIG_NODE
, &no_ip_pim_register_suppress_cmd
);
10863 install_element(VRF_NODE
, &no_ip_pim_register_suppress_cmd
);
10864 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
10865 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
10866 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
10867 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
10868 install_element(CONFIG_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
10869 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
10870 install_element(CONFIG_NODE
,
10871 &no_ip_pim_spt_switchover_infinity_plist_cmd
);
10872 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_plist_cmd
);
10873 install_element(CONFIG_NODE
, &pim_register_accept_list_cmd
);
10874 install_element(VRF_NODE
, &pim_register_accept_list_cmd
);
10875 install_element(CONFIG_NODE
, &ip_pim_joinprune_time_cmd
);
10876 install_element(VRF_NODE
, &ip_pim_joinprune_time_cmd
);
10877 install_element(CONFIG_NODE
, &no_ip_pim_joinprune_time_cmd
);
10878 install_element(VRF_NODE
, &no_ip_pim_joinprune_time_cmd
);
10879 install_element(CONFIG_NODE
, &ip_pim_keep_alive_cmd
);
10880 install_element(VRF_NODE
, &ip_pim_keep_alive_cmd
);
10881 install_element(CONFIG_NODE
, &ip_pim_rp_keep_alive_cmd
);
10882 install_element(VRF_NODE
, &ip_pim_rp_keep_alive_cmd
);
10883 install_element(CONFIG_NODE
, &no_ip_pim_keep_alive_cmd
);
10884 install_element(VRF_NODE
, &no_ip_pim_keep_alive_cmd
);
10885 install_element(CONFIG_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
10886 install_element(VRF_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
10887 install_element(CONFIG_NODE
, &ip_pim_packets_cmd
);
10888 install_element(VRF_NODE
, &ip_pim_packets_cmd
);
10889 install_element(CONFIG_NODE
, &no_ip_pim_packets_cmd
);
10890 install_element(VRF_NODE
, &no_ip_pim_packets_cmd
);
10891 install_element(CONFIG_NODE
, &ip_pim_v6_secondary_cmd
);
10892 install_element(VRF_NODE
, &ip_pim_v6_secondary_cmd
);
10893 install_element(CONFIG_NODE
, &no_ip_pim_v6_secondary_cmd
);
10894 install_element(VRF_NODE
, &no_ip_pim_v6_secondary_cmd
);
10895 install_element(CONFIG_NODE
, &ip_ssmpingd_cmd
);
10896 install_element(VRF_NODE
, &ip_ssmpingd_cmd
);
10897 install_element(CONFIG_NODE
, &no_ip_ssmpingd_cmd
);
10898 install_element(VRF_NODE
, &no_ip_ssmpingd_cmd
);
10899 install_element(CONFIG_NODE
, &ip_msdp_peer_cmd
);
10900 install_element(VRF_NODE
, &ip_msdp_peer_cmd
);
10901 install_element(CONFIG_NODE
, &no_ip_msdp_peer_cmd
);
10902 install_element(VRF_NODE
, &no_ip_msdp_peer_cmd
);
10903 install_element(CONFIG_NODE
, &ip_pim_ecmp_cmd
);
10904 install_element(VRF_NODE
, &ip_pim_ecmp_cmd
);
10905 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_cmd
);
10906 install_element(VRF_NODE
, &no_ip_pim_ecmp_cmd
);
10907 install_element(CONFIG_NODE
, &ip_pim_ecmp_rebalance_cmd
);
10908 install_element(VRF_NODE
, &ip_pim_ecmp_rebalance_cmd
);
10909 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
10910 install_element(VRF_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
10911 install_element(CONFIG_NODE
, &ip_pim_mlag_cmd
);
10912 install_element(CONFIG_NODE
, &no_ip_pim_mlag_cmd
);
10914 install_element(INTERFACE_NODE
, &interface_ip_igmp_cmd
);
10915 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_cmd
);
10916 install_element(INTERFACE_NODE
, &interface_ip_igmp_join_cmd
);
10917 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_join_cmd
);
10918 install_element(INTERFACE_NODE
, &interface_ip_igmp_version_cmd
);
10919 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_version_cmd
);
10920 install_element(INTERFACE_NODE
, &interface_ip_igmp_query_interval_cmd
);
10921 install_element(INTERFACE_NODE
,
10922 &interface_no_ip_igmp_query_interval_cmd
);
10923 install_element(INTERFACE_NODE
,
10924 &interface_ip_igmp_query_max_response_time_cmd
);
10925 install_element(INTERFACE_NODE
,
10926 &interface_no_ip_igmp_query_max_response_time_cmd
);
10927 install_element(INTERFACE_NODE
,
10928 &interface_ip_igmp_query_max_response_time_dsec_cmd
);
10929 install_element(INTERFACE_NODE
,
10930 &interface_no_ip_igmp_query_max_response_time_dsec_cmd
);
10931 install_element(INTERFACE_NODE
,
10932 &interface_ip_igmp_last_member_query_count_cmd
);
10933 install_element(INTERFACE_NODE
,
10934 &interface_no_ip_igmp_last_member_query_count_cmd
);
10935 install_element(INTERFACE_NODE
,
10936 &interface_ip_igmp_last_member_query_interval_cmd
);
10937 install_element(INTERFACE_NODE
,
10938 &interface_no_ip_igmp_last_member_query_interval_cmd
);
10939 install_element(INTERFACE_NODE
, &interface_ip_pim_activeactive_cmd
);
10940 install_element(INTERFACE_NODE
, &interface_ip_pim_ssm_cmd
);
10941 install_element(INTERFACE_NODE
, &interface_no_ip_pim_ssm_cmd
);
10942 install_element(INTERFACE_NODE
, &interface_ip_pim_sm_cmd
);
10943 install_element(INTERFACE_NODE
, &interface_no_ip_pim_sm_cmd
);
10944 install_element(INTERFACE_NODE
, &interface_ip_pim_cmd
);
10945 install_element(INTERFACE_NODE
, &interface_no_ip_pim_cmd
);
10946 install_element(INTERFACE_NODE
, &interface_ip_pim_drprio_cmd
);
10947 install_element(INTERFACE_NODE
, &interface_no_ip_pim_drprio_cmd
);
10948 install_element(INTERFACE_NODE
, &interface_ip_pim_hello_cmd
);
10949 install_element(INTERFACE_NODE
, &interface_no_ip_pim_hello_cmd
);
10950 install_element(INTERFACE_NODE
, &interface_ip_pim_boundary_oil_cmd
);
10951 install_element(INTERFACE_NODE
, &interface_no_ip_pim_boundary_oil_cmd
);
10952 install_element(INTERFACE_NODE
, &interface_ip_igmp_query_generate_cmd
);
10954 // Static mroutes NEB
10955 install_element(INTERFACE_NODE
, &interface_ip_mroute_cmd
);
10956 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_cmd
);
10958 install_element(VIEW_NODE
, &show_ip_igmp_interface_cmd
);
10959 install_element(VIEW_NODE
, &show_ip_igmp_interface_vrf_all_cmd
);
10960 install_element(VIEW_NODE
, &show_ip_igmp_join_cmd
);
10961 install_element(VIEW_NODE
, &show_ip_igmp_join_vrf_all_cmd
);
10962 install_element(VIEW_NODE
, &show_ip_igmp_groups_cmd
);
10963 install_element(VIEW_NODE
, &show_ip_igmp_groups_vrf_all_cmd
);
10964 install_element(VIEW_NODE
, &show_ip_igmp_groups_retransmissions_cmd
);
10965 install_element(VIEW_NODE
, &show_ip_igmp_sources_cmd
);
10966 install_element(VIEW_NODE
, &show_ip_igmp_sources_retransmissions_cmd
);
10967 install_element(VIEW_NODE
, &show_ip_igmp_statistics_cmd
);
10968 install_element(VIEW_NODE
, &show_ip_pim_assert_cmd
);
10969 install_element(VIEW_NODE
, &show_ip_pim_assert_internal_cmd
);
10970 install_element(VIEW_NODE
, &show_ip_pim_assert_metric_cmd
);
10971 install_element(VIEW_NODE
, &show_ip_pim_assert_winner_metric_cmd
);
10972 install_element(VIEW_NODE
, &show_ip_pim_interface_traffic_cmd
);
10973 install_element(VIEW_NODE
, &show_ip_pim_interface_cmd
);
10974 install_element(VIEW_NODE
, &show_ip_pim_interface_vrf_all_cmd
);
10975 install_element(VIEW_NODE
, &show_ip_pim_join_cmd
);
10976 install_element(VIEW_NODE
, &show_ip_pim_join_vrf_all_cmd
);
10977 install_element(VIEW_NODE
, &show_ip_pim_jp_agg_cmd
);
10978 install_element(VIEW_NODE
, &show_ip_pim_local_membership_cmd
);
10979 install_element(VIEW_NODE
, &show_ip_pim_mlag_summary_cmd
);
10980 install_element(VIEW_NODE
, &show_ip_pim_mlag_up_cmd
);
10981 install_element(VIEW_NODE
, &show_ip_pim_mlag_up_vrf_all_cmd
);
10982 install_element(VIEW_NODE
, &show_ip_pim_neighbor_cmd
);
10983 install_element(VIEW_NODE
, &show_ip_pim_neighbor_vrf_all_cmd
);
10984 install_element(VIEW_NODE
, &show_ip_pim_rpf_cmd
);
10985 install_element(VIEW_NODE
, &show_ip_pim_rpf_vrf_all_cmd
);
10986 install_element(VIEW_NODE
, &show_ip_pim_secondary_cmd
);
10987 install_element(VIEW_NODE
, &show_ip_pim_state_cmd
);
10988 install_element(VIEW_NODE
, &show_ip_pim_state_vrf_all_cmd
);
10989 install_element(VIEW_NODE
, &show_ip_pim_upstream_cmd
);
10990 install_element(VIEW_NODE
, &show_ip_pim_upstream_vrf_all_cmd
);
10991 install_element(VIEW_NODE
, &show_ip_pim_channel_cmd
);
10992 install_element(VIEW_NODE
, &show_ip_pim_upstream_join_desired_cmd
);
10993 install_element(VIEW_NODE
, &show_ip_pim_upstream_rpf_cmd
);
10994 install_element(VIEW_NODE
, &show_ip_pim_rp_cmd
);
10995 install_element(VIEW_NODE
, &show_ip_pim_rp_vrf_all_cmd
);
10996 install_element(VIEW_NODE
, &show_ip_pim_bsr_cmd
);
10997 install_element(VIEW_NODE
, &show_ip_multicast_cmd
);
10998 install_element(VIEW_NODE
, &show_ip_multicast_vrf_all_cmd
);
10999 install_element(VIEW_NODE
, &show_ip_mroute_cmd
);
11000 install_element(VIEW_NODE
, &show_ip_mroute_vrf_all_cmd
);
11001 install_element(VIEW_NODE
, &show_ip_mroute_count_cmd
);
11002 install_element(VIEW_NODE
, &show_ip_mroute_count_vrf_all_cmd
);
11003 install_element(VIEW_NODE
, &show_ip_mroute_summary_cmd
);
11004 install_element(VIEW_NODE
, &show_ip_mroute_summary_vrf_all_cmd
);
11005 install_element(VIEW_NODE
, &show_ip_rib_cmd
);
11006 install_element(VIEW_NODE
, &show_ip_ssmpingd_cmd
);
11007 install_element(VIEW_NODE
, &show_debugging_pim_cmd
);
11008 install_element(VIEW_NODE
, &show_ip_pim_nexthop_cmd
);
11009 install_element(VIEW_NODE
, &show_ip_pim_nexthop_lookup_cmd
);
11010 install_element(VIEW_NODE
, &show_ip_pim_bsrp_cmd
);
11011 install_element(VIEW_NODE
, &show_ip_pim_bsm_db_cmd
);
11012 install_element(VIEW_NODE
, &show_ip_pim_statistics_cmd
);
11014 install_element(ENABLE_NODE
, &clear_ip_mroute_count_cmd
);
11015 install_element(ENABLE_NODE
, &clear_ip_interfaces_cmd
);
11016 install_element(ENABLE_NODE
, &clear_ip_igmp_interfaces_cmd
);
11017 install_element(ENABLE_NODE
, &clear_ip_mroute_cmd
);
11018 install_element(ENABLE_NODE
, &clear_ip_pim_interfaces_cmd
);
11019 install_element(ENABLE_NODE
, &clear_ip_pim_interface_traffic_cmd
);
11020 install_element(ENABLE_NODE
, &clear_ip_pim_oil_cmd
);
11021 install_element(ENABLE_NODE
, &clear_ip_pim_statistics_cmd
);
11023 install_element(ENABLE_NODE
, &debug_igmp_cmd
);
11024 install_element(ENABLE_NODE
, &no_debug_igmp_cmd
);
11025 install_element(ENABLE_NODE
, &debug_igmp_events_cmd
);
11026 install_element(ENABLE_NODE
, &no_debug_igmp_events_cmd
);
11027 install_element(ENABLE_NODE
, &debug_igmp_packets_cmd
);
11028 install_element(ENABLE_NODE
, &no_debug_igmp_packets_cmd
);
11029 install_element(ENABLE_NODE
, &debug_igmp_trace_cmd
);
11030 install_element(ENABLE_NODE
, &no_debug_igmp_trace_cmd
);
11031 install_element(ENABLE_NODE
, &debug_mroute_cmd
);
11032 install_element(ENABLE_NODE
, &debug_mroute_detail_cmd
);
11033 install_element(ENABLE_NODE
, &no_debug_mroute_cmd
);
11034 install_element(ENABLE_NODE
, &no_debug_mroute_detail_cmd
);
11035 install_element(ENABLE_NODE
, &debug_pim_static_cmd
);
11036 install_element(ENABLE_NODE
, &no_debug_pim_static_cmd
);
11037 install_element(ENABLE_NODE
, &debug_pim_cmd
);
11038 install_element(ENABLE_NODE
, &no_debug_pim_cmd
);
11039 install_element(ENABLE_NODE
, &debug_pim_nht_cmd
);
11040 install_element(ENABLE_NODE
, &no_debug_pim_nht_cmd
);
11041 install_element(ENABLE_NODE
, &debug_pim_nht_rp_cmd
);
11042 install_element(ENABLE_NODE
, &no_debug_pim_nht_rp_cmd
);
11043 install_element(ENABLE_NODE
, &debug_pim_events_cmd
);
11044 install_element(ENABLE_NODE
, &no_debug_pim_events_cmd
);
11045 install_element(ENABLE_NODE
, &debug_pim_packets_cmd
);
11046 install_element(ENABLE_NODE
, &no_debug_pim_packets_cmd
);
11047 install_element(ENABLE_NODE
, &debug_pim_packetdump_send_cmd
);
11048 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_send_cmd
);
11049 install_element(ENABLE_NODE
, &debug_pim_packetdump_recv_cmd
);
11050 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_recv_cmd
);
11051 install_element(ENABLE_NODE
, &debug_pim_trace_cmd
);
11052 install_element(ENABLE_NODE
, &no_debug_pim_trace_cmd
);
11053 install_element(ENABLE_NODE
, &debug_pim_trace_detail_cmd
);
11054 install_element(ENABLE_NODE
, &no_debug_pim_trace_detail_cmd
);
11055 install_element(ENABLE_NODE
, &debug_ssmpingd_cmd
);
11056 install_element(ENABLE_NODE
, &no_debug_ssmpingd_cmd
);
11057 install_element(ENABLE_NODE
, &debug_pim_zebra_cmd
);
11058 install_element(ENABLE_NODE
, &no_debug_pim_zebra_cmd
);
11059 install_element(ENABLE_NODE
, &debug_pim_mlag_cmd
);
11060 install_element(ENABLE_NODE
, &no_debug_pim_mlag_cmd
);
11061 install_element(ENABLE_NODE
, &debug_pim_vxlan_cmd
);
11062 install_element(ENABLE_NODE
, &no_debug_pim_vxlan_cmd
);
11063 install_element(ENABLE_NODE
, &debug_msdp_cmd
);
11064 install_element(ENABLE_NODE
, &no_debug_msdp_cmd
);
11065 install_element(ENABLE_NODE
, &debug_msdp_events_cmd
);
11066 install_element(ENABLE_NODE
, &no_debug_msdp_events_cmd
);
11067 install_element(ENABLE_NODE
, &debug_msdp_packets_cmd
);
11068 install_element(ENABLE_NODE
, &no_debug_msdp_packets_cmd
);
11069 install_element(ENABLE_NODE
, &debug_mtrace_cmd
);
11070 install_element(ENABLE_NODE
, &no_debug_mtrace_cmd
);
11071 install_element(ENABLE_NODE
, &debug_bsm_cmd
);
11072 install_element(ENABLE_NODE
, &no_debug_bsm_cmd
);
11074 install_element(CONFIG_NODE
, &debug_igmp_cmd
);
11075 install_element(CONFIG_NODE
, &no_debug_igmp_cmd
);
11076 install_element(CONFIG_NODE
, &debug_igmp_events_cmd
);
11077 install_element(CONFIG_NODE
, &no_debug_igmp_events_cmd
);
11078 install_element(CONFIG_NODE
, &debug_igmp_packets_cmd
);
11079 install_element(CONFIG_NODE
, &no_debug_igmp_packets_cmd
);
11080 install_element(CONFIG_NODE
, &debug_igmp_trace_cmd
);
11081 install_element(CONFIG_NODE
, &no_debug_igmp_trace_cmd
);
11082 install_element(CONFIG_NODE
, &debug_mroute_cmd
);
11083 install_element(CONFIG_NODE
, &debug_mroute_detail_cmd
);
11084 install_element(CONFIG_NODE
, &no_debug_mroute_cmd
);
11085 install_element(CONFIG_NODE
, &no_debug_mroute_detail_cmd
);
11086 install_element(CONFIG_NODE
, &debug_pim_static_cmd
);
11087 install_element(CONFIG_NODE
, &no_debug_pim_static_cmd
);
11088 install_element(CONFIG_NODE
, &debug_pim_cmd
);
11089 install_element(CONFIG_NODE
, &no_debug_pim_cmd
);
11090 install_element(CONFIG_NODE
, &debug_pim_nht_cmd
);
11091 install_element(CONFIG_NODE
, &no_debug_pim_nht_cmd
);
11092 install_element(CONFIG_NODE
, &debug_pim_nht_rp_cmd
);
11093 install_element(CONFIG_NODE
, &no_debug_pim_nht_rp_cmd
);
11094 install_element(CONFIG_NODE
, &debug_pim_events_cmd
);
11095 install_element(CONFIG_NODE
, &no_debug_pim_events_cmd
);
11096 install_element(CONFIG_NODE
, &debug_pim_packets_cmd
);
11097 install_element(CONFIG_NODE
, &no_debug_pim_packets_cmd
);
11098 install_element(CONFIG_NODE
, &debug_pim_trace_cmd
);
11099 install_element(CONFIG_NODE
, &no_debug_pim_trace_cmd
);
11100 install_element(CONFIG_NODE
, &debug_pim_trace_detail_cmd
);
11101 install_element(CONFIG_NODE
, &no_debug_pim_trace_detail_cmd
);
11102 install_element(CONFIG_NODE
, &debug_ssmpingd_cmd
);
11103 install_element(CONFIG_NODE
, &no_debug_ssmpingd_cmd
);
11104 install_element(CONFIG_NODE
, &debug_pim_zebra_cmd
);
11105 install_element(CONFIG_NODE
, &no_debug_pim_zebra_cmd
);
11106 install_element(CONFIG_NODE
, &debug_pim_mlag_cmd
);
11107 install_element(CONFIG_NODE
, &no_debug_pim_mlag_cmd
);
11108 install_element(CONFIG_NODE
, &debug_pim_vxlan_cmd
);
11109 install_element(CONFIG_NODE
, &no_debug_pim_vxlan_cmd
);
11110 install_element(CONFIG_NODE
, &debug_msdp_cmd
);
11111 install_element(CONFIG_NODE
, &no_debug_msdp_cmd
);
11112 install_element(CONFIG_NODE
, &debug_msdp_events_cmd
);
11113 install_element(CONFIG_NODE
, &no_debug_msdp_events_cmd
);
11114 install_element(CONFIG_NODE
, &debug_msdp_packets_cmd
);
11115 install_element(CONFIG_NODE
, &no_debug_msdp_packets_cmd
);
11116 install_element(CONFIG_NODE
, &debug_mtrace_cmd
);
11117 install_element(CONFIG_NODE
, &no_debug_mtrace_cmd
);
11118 install_element(CONFIG_NODE
, &debug_bsm_cmd
);
11119 install_element(CONFIG_NODE
, &no_debug_bsm_cmd
);
11121 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_member_cmd
);
11122 install_element(VRF_NODE
, &ip_msdp_mesh_group_member_cmd
);
11123 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
11124 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
11125 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_source_cmd
);
11126 install_element(VRF_NODE
, &ip_msdp_mesh_group_source_cmd
);
11127 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
11128 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
11129 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_cmd
);
11130 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_cmd
);
11131 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_cmd
);
11132 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_vrf_all_cmd
);
11133 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_cmd
);
11134 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_vrf_all_cmd
);
11135 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_cmd
);
11136 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_vrf_all_cmd
);
11137 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_cmd
);
11138 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_vrf_all_cmd
);
11139 install_element(VIEW_NODE
, &show_ip_pim_ssm_range_cmd
);
11140 install_element(VIEW_NODE
, &show_ip_pim_group_type_cmd
);
11141 install_element(VIEW_NODE
, &show_ip_pim_vxlan_sg_cmd
);
11142 install_element(VIEW_NODE
, &show_ip_pim_vxlan_sg_work_cmd
);
11143 install_element(INTERFACE_NODE
, &interface_pim_use_source_cmd
);
11144 install_element(INTERFACE_NODE
, &interface_no_pim_use_source_cmd
);
11145 /* Install BSM command */
11146 install_element(INTERFACE_NODE
, &ip_pim_bsm_cmd
);
11147 install_element(INTERFACE_NODE
, &no_ip_pim_bsm_cmd
);
11148 install_element(INTERFACE_NODE
, &ip_pim_ucast_bsm_cmd
);
11149 install_element(INTERFACE_NODE
, &no_ip_pim_ucast_bsm_cmd
);
11150 /* Install BFD command */
11151 install_element(INTERFACE_NODE
, &ip_pim_bfd_cmd
);
11152 install_element(INTERFACE_NODE
, &ip_pim_bfd_param_cmd
);
11153 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_cmd
);
11155 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_param_cmd
);
11156 #endif /* !HAVE_BFDD */