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
];
2513 char tmp
[sizeof(state_str
) + 1];
2515 snprintf(tmp
, sizeof(tmp
), ",%s",
2516 pim_reg_state2brief_str(up
->reg_state
, tmp_str
,
2518 strlcat(state_str
, tmp
, sizeof(state_str
));
2522 json_object_object_get_ex(json
, grp_str
, &json_group
);
2525 json_group
= json_object_new_object();
2526 json_object_object_add(json
, grp_str
,
2530 json_row
= json_object_new_object();
2531 json_object_pim_upstream_add(json_row
, up
);
2532 json_object_string_add(
2533 json_row
, "inboundInterface",
2534 up
->rpf
.source_nexthop
.interface
2535 ? up
->rpf
.source_nexthop
.interface
->name
2539 * The RPF address we use is slightly different
2540 * based upon what we are looking up.
2541 * If we have a S, list that unless
2542 * we are the FHR, else we just put
2543 * the RP as the rpfAddress
2545 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
2546 || up
->sg
.src
.s_addr
== INADDR_ANY
) {
2547 char rpf
[PREFIX_STRLEN
];
2548 struct pim_rpf
*rpg
;
2550 rpg
= RP(pim
, up
->sg
.grp
);
2551 pim_inet4_dump("<rpf?>",
2552 rpg
->rpf_addr
.u
.prefix4
, rpf
,
2554 json_object_string_add(json_row
, "rpfAddress",
2557 json_object_string_add(json_row
, "rpfAddress",
2561 json_object_string_add(json_row
, "source", src_str
);
2562 json_object_string_add(json_row
, "group", grp_str
);
2563 json_object_string_add(json_row
, "state", state_str
);
2564 json_object_string_add(
2565 json_row
, "joinState",
2566 pim_upstream_state2str(up
->join_state
));
2567 json_object_string_add(
2568 json_row
, "regState",
2569 pim_reg_state2str(up
->reg_state
, state_str
, sizeof(state_str
)));
2570 json_object_string_add(json_row
, "upTime", uptime
);
2571 json_object_string_add(json_row
, "joinTimer",
2573 json_object_string_add(json_row
, "resetTimer",
2575 json_object_string_add(json_row
, "keepaliveTimer",
2577 json_object_string_add(json_row
, "msdpRegTimer",
2579 json_object_int_add(json_row
, "refCount",
2581 json_object_int_add(json_row
, "sptBit", up
->sptbit
);
2582 json_object_object_add(json_group
, src_str
, json_row
);
2585 "%-16s%-15s %-15s %-11s %-8s %-9s %-9s %-9s %6d\n",
2586 up
->rpf
.source_nexthop
.interface
2587 ? up
->rpf
.source_nexthop
.interface
->name
2589 src_str
, grp_str
, state_str
, uptime
, join_timer
,
2590 rs_timer
, ka_timer
, up
->ref_count
);
2595 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2596 json
, JSON_C_TO_STRING_PRETTY
));
2597 json_object_free(json
);
2601 static void pim_show_channel_helper(struct pim_instance
*pim
,
2603 struct pim_interface
*pim_ifp
,
2604 struct pim_ifchannel
*ch
,
2605 json_object
*json
, bool uj
)
2607 struct pim_upstream
*up
= ch
->upstream
;
2608 json_object
*json_group
= NULL
;
2609 char src_str
[INET_ADDRSTRLEN
];
2610 char grp_str
[INET_ADDRSTRLEN
];
2611 json_object
*json_row
= NULL
;
2613 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2614 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2617 json_object_object_get_ex(json
, grp_str
, &json_group
);
2620 json_group
= json_object_new_object();
2621 json_object_object_add(json
, grp_str
, json_group
);
2624 json_row
= json_object_new_object();
2625 json_object_pim_upstream_add(json_row
, up
);
2626 json_object_string_add(json_row
, "interface",
2627 ch
->interface
->name
);
2628 json_object_string_add(json_row
, "source", src_str
);
2629 json_object_string_add(json_row
, "group", grp_str
);
2631 if (pim_macro_ch_lost_assert(ch
))
2632 json_object_boolean_true_add(json_row
, "lostAssert");
2634 if (pim_macro_chisin_joins(ch
))
2635 json_object_boolean_true_add(json_row
, "joins");
2637 if (pim_macro_chisin_pim_include(ch
))
2638 json_object_boolean_true_add(json_row
, "pimInclude");
2640 if (pim_upstream_evaluate_join_desired(pim
, up
))
2641 json_object_boolean_true_add(json_row
,
2642 "evaluateJoinDesired");
2644 json_object_object_add(json_group
, src_str
, json_row
);
2647 vty_out(vty
, "%-16s %-15s %-15s %-10s %-5s %-10s %-11s %-6s\n",
2648 ch
->interface
->name
, src_str
, grp_str
,
2649 pim_macro_ch_lost_assert(ch
) ? "yes" : "no",
2650 pim_macro_chisin_joins(ch
) ? "yes" : "no",
2651 pim_macro_chisin_pim_include(ch
) ? "yes" : "no",
2652 PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(up
->flags
)
2655 pim_upstream_evaluate_join_desired(pim
, up
) ? "yes"
2660 static void pim_show_channel(struct pim_instance
*pim
, struct vty
*vty
,
2663 struct pim_interface
*pim_ifp
;
2664 struct pim_ifchannel
*ch
;
2665 struct interface
*ifp
;
2667 json_object
*json
= NULL
;
2670 json
= json_object_new_object();
2673 "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD\n");
2675 /* scan per-interface (S,G) state */
2676 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2677 pim_ifp
= ifp
->info
;
2682 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
2683 /* scan all interfaces */
2684 pim_show_channel_helper(pim
, vty
, pim_ifp
, ch
,
2690 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2691 json
, JSON_C_TO_STRING_PRETTY
));
2692 json_object_free(json
);
2696 static void pim_show_join_desired_helper(struct pim_instance
*pim
,
2698 struct pim_upstream
*up
,
2699 json_object
*json
, bool uj
)
2701 json_object
*json_group
= NULL
;
2702 char src_str
[INET_ADDRSTRLEN
];
2703 char grp_str
[INET_ADDRSTRLEN
];
2704 json_object
*json_row
= NULL
;
2706 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2707 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2710 json_object_object_get_ex(json
, grp_str
, &json_group
);
2713 json_group
= json_object_new_object();
2714 json_object_object_add(json
, grp_str
, json_group
);
2717 json_row
= json_object_new_object();
2718 json_object_pim_upstream_add(json_row
, up
);
2719 json_object_string_add(json_row
, "source", src_str
);
2720 json_object_string_add(json_row
, "group", grp_str
);
2722 if (pim_upstream_evaluate_join_desired(pim
, up
))
2723 json_object_boolean_true_add(json_row
,
2724 "evaluateJoinDesired");
2726 json_object_object_add(json_group
, src_str
, json_row
);
2729 vty_out(vty
, "%-15s %-15s %-6s\n",
2731 pim_upstream_evaluate_join_desired(pim
, up
) ? "yes"
2736 static void pim_show_join_desired(struct pim_instance
*pim
, struct vty
*vty
,
2739 struct pim_upstream
*up
;
2741 json_object
*json
= NULL
;
2744 json
= json_object_new_object();
2747 "Source Group EvalJD\n");
2749 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
2750 /* scan all interfaces */
2751 pim_show_join_desired_helper(pim
, vty
, up
,
2756 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2757 json
, JSON_C_TO_STRING_PRETTY
));
2758 json_object_free(json
);
2762 static void pim_show_upstream_rpf(struct pim_instance
*pim
, struct vty
*vty
,
2765 struct pim_upstream
*up
;
2766 json_object
*json
= NULL
;
2767 json_object
*json_group
= NULL
;
2768 json_object
*json_row
= NULL
;
2771 json
= json_object_new_object();
2774 "Source Group RpfIface RibNextHop RpfAddress \n");
2776 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
2777 char src_str
[INET_ADDRSTRLEN
];
2778 char grp_str
[INET_ADDRSTRLEN
];
2779 char rpf_nexthop_str
[PREFIX_STRLEN
];
2780 char rpf_addr_str
[PREFIX_STRLEN
];
2781 struct pim_rpf
*rpf
;
2782 const char *rpf_ifname
;
2786 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2787 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2788 pim_addr_dump("<nexthop?>",
2789 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2790 rpf_nexthop_str
, sizeof(rpf_nexthop_str
));
2791 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2792 sizeof(rpf_addr_str
));
2794 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2797 json_object_object_get_ex(json
, grp_str
, &json_group
);
2800 json_group
= json_object_new_object();
2801 json_object_object_add(json
, grp_str
,
2805 json_row
= json_object_new_object();
2806 json_object_pim_upstream_add(json_row
, up
);
2807 json_object_string_add(json_row
, "source", src_str
);
2808 json_object_string_add(json_row
, "group", grp_str
);
2809 json_object_string_add(json_row
, "rpfInterface",
2811 json_object_string_add(json_row
, "ribNexthop",
2813 json_object_string_add(json_row
, "rpfAddress",
2815 json_object_object_add(json_group
, src_str
, json_row
);
2817 vty_out(vty
, "%-15s %-15s %-16s %-15s %-15s\n", src_str
,
2818 grp_str
, rpf_ifname
, rpf_nexthop_str
,
2824 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2825 json
, JSON_C_TO_STRING_PRETTY
));
2826 json_object_free(json
);
2830 static void show_rpf_refresh_stats(struct vty
*vty
, struct pim_instance
*pim
,
2831 time_t now
, json_object
*json
)
2833 char refresh_uptime
[10];
2835 pim_time_uptime_begin(refresh_uptime
, sizeof(refresh_uptime
), now
,
2836 pim
->rpf_cache_refresh_last
);
2839 json_object_int_add(json
, "rpfCacheRefreshDelayMsecs",
2840 router
->rpf_cache_refresh_delay_msec
);
2841 json_object_int_add(
2842 json
, "rpfCacheRefreshTimer",
2843 pim_time_timer_remain_msec(pim
->rpf_cache_refresher
));
2844 json_object_int_add(json
, "rpfCacheRefreshRequests",
2845 pim
->rpf_cache_refresh_requests
);
2846 json_object_int_add(json
, "rpfCacheRefreshEvents",
2847 pim
->rpf_cache_refresh_events
);
2848 json_object_string_add(json
, "rpfCacheRefreshLast",
2850 json_object_int_add(json
, "nexthopLookups",
2851 pim
->nexthop_lookups
);
2852 json_object_int_add(json
, "nexthopLookupsAvoided",
2853 pim
->nexthop_lookups_avoided
);
2856 "RPF Cache Refresh Delay: %ld msecs\n"
2857 "RPF Cache Refresh Timer: %ld msecs\n"
2858 "RPF Cache Refresh Requests: %lld\n"
2859 "RPF Cache Refresh Events: %lld\n"
2860 "RPF Cache Refresh Last: %s\n"
2861 "Nexthop Lookups: %lld\n"
2862 "Nexthop Lookups Avoided: %lld\n",
2863 router
->rpf_cache_refresh_delay_msec
,
2864 pim_time_timer_remain_msec(pim
->rpf_cache_refresher
),
2865 (long long)pim
->rpf_cache_refresh_requests
,
2866 (long long)pim
->rpf_cache_refresh_events
,
2867 refresh_uptime
, (long long)pim
->nexthop_lookups
,
2868 (long long)pim
->nexthop_lookups_avoided
);
2872 static void show_scan_oil_stats(struct pim_instance
*pim
, struct vty
*vty
,
2875 char uptime_scan_oil
[10];
2876 char uptime_mroute_add
[10];
2877 char uptime_mroute_del
[10];
2879 pim_time_uptime_begin(uptime_scan_oil
, sizeof(uptime_scan_oil
), now
,
2880 pim
->scan_oil_last
);
2881 pim_time_uptime_begin(uptime_mroute_add
, sizeof(uptime_mroute_add
), now
,
2882 pim
->mroute_add_last
);
2883 pim_time_uptime_begin(uptime_mroute_del
, sizeof(uptime_mroute_del
), now
,
2884 pim
->mroute_del_last
);
2887 "Scan OIL - Last: %s Events: %lld\n"
2888 "MFC Add - Last: %s Events: %lld\n"
2889 "MFC Del - Last: %s Events: %lld\n",
2890 uptime_scan_oil
, (long long)pim
->scan_oil_events
,
2891 uptime_mroute_add
, (long long)pim
->mroute_add_events
,
2892 uptime_mroute_del
, (long long)pim
->mroute_del_events
);
2895 static void pim_show_rpf(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
2897 struct pim_upstream
*up
;
2898 time_t now
= pim_time_monotonic_sec();
2899 json_object
*json
= NULL
;
2900 json_object
*json_group
= NULL
;
2901 json_object
*json_row
= NULL
;
2904 json
= json_object_new_object();
2905 show_rpf_refresh_stats(vty
, pim
, now
, json
);
2907 show_rpf_refresh_stats(vty
, pim
, now
, json
);
2910 "Source Group RpfIface RpfAddress RibNextHop Metric Pref\n");
2913 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
2914 char src_str
[INET_ADDRSTRLEN
];
2915 char grp_str
[INET_ADDRSTRLEN
];
2916 char rpf_addr_str
[PREFIX_STRLEN
];
2917 char rib_nexthop_str
[PREFIX_STRLEN
];
2918 const char *rpf_ifname
;
2919 struct pim_rpf
*rpf
= &up
->rpf
;
2921 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2922 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2923 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2924 sizeof(rpf_addr_str
));
2925 pim_addr_dump("<nexthop?>",
2926 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2927 rib_nexthop_str
, sizeof(rib_nexthop_str
));
2929 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2932 json_object_object_get_ex(json
, grp_str
, &json_group
);
2935 json_group
= json_object_new_object();
2936 json_object_object_add(json
, grp_str
,
2940 json_row
= json_object_new_object();
2941 json_object_string_add(json_row
, "source", src_str
);
2942 json_object_string_add(json_row
, "group", grp_str
);
2943 json_object_string_add(json_row
, "rpfInterface",
2945 json_object_string_add(json_row
, "rpfAddress",
2947 json_object_string_add(json_row
, "ribNexthop",
2949 json_object_int_add(
2950 json_row
, "routeMetric",
2951 rpf
->source_nexthop
.mrib_route_metric
);
2952 json_object_int_add(
2953 json_row
, "routePreference",
2954 rpf
->source_nexthop
.mrib_metric_preference
);
2955 json_object_object_add(json_group
, src_str
, json_row
);
2958 vty_out(vty
, "%-15s %-15s %-16s %-15s %-15s %6d %4d\n",
2959 src_str
, grp_str
, rpf_ifname
, rpf_addr_str
,
2961 rpf
->source_nexthop
.mrib_route_metric
,
2962 rpf
->source_nexthop
.mrib_metric_preference
);
2967 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2968 json
, JSON_C_TO_STRING_PRETTY
));
2969 json_object_free(json
);
2973 struct pnc_cache_walk_data
{
2975 struct pim_instance
*pim
;
2978 static int pim_print_pnc_cache_walkcb(struct hash_bucket
*bucket
, void *arg
)
2980 struct pim_nexthop_cache
*pnc
= bucket
->data
;
2981 struct pnc_cache_walk_data
*cwd
= arg
;
2982 struct vty
*vty
= cwd
->vty
;
2983 struct pim_instance
*pim
= cwd
->pim
;
2984 struct nexthop
*nh_node
= NULL
;
2985 ifindex_t first_ifindex
;
2986 struct interface
*ifp
= NULL
;
2988 for (nh_node
= pnc
->nexthop
; nh_node
; nh_node
= nh_node
->next
) {
2989 first_ifindex
= nh_node
->ifindex
;
2990 ifp
= if_lookup_by_index(first_ifindex
, pim
->vrf_id
);
2992 vty_out(vty
, "%-15s ", inet_ntoa(pnc
->rpf
.rpf_addr
.u
.prefix4
));
2993 vty_out(vty
, "%-16s ", ifp
? ifp
->name
: "NULL");
2994 vty_out(vty
, "%s ", inet_ntoa(nh_node
->gate
.ipv4
));
3000 static void pim_show_nexthop(struct pim_instance
*pim
, struct vty
*vty
)
3002 struct pnc_cache_walk_data cwd
;
3006 vty_out(vty
, "Number of registered addresses: %lu\n",
3007 pim
->rpf_hash
->count
);
3008 vty_out(vty
, "Address Interface Nexthop\n");
3009 vty_out(vty
, "---------------------------------------------\n");
3011 hash_walk(pim
->rpf_hash
, pim_print_pnc_cache_walkcb
, &cwd
);
3014 /* Display the bsm database details */
3015 static void pim_show_bsm_db(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
3017 struct listnode
*bsmnode
;
3020 struct bsm_info
*bsm
;
3021 json_object
*json
= NULL
;
3022 json_object
*json_group
= NULL
;
3023 json_object
*json_row
= NULL
;
3025 count
= pim
->global_scope
.bsm_list
->count
;
3028 json
= json_object_new_object();
3029 json_object_int_add(json
, "Number of the fragments", count
);
3031 vty_out(vty
, "Scope Zone: Global\n");
3032 vty_out(vty
, "Number of the fragments: %d\n", count
);
3036 for (ALL_LIST_ELEMENTS_RO(pim
->global_scope
.bsm_list
, bsmnode
, bsm
)) {
3037 char grp_str
[PREFIX_STRLEN
];
3038 char rp_str
[INET_ADDRSTRLEN
];
3039 char bsr_str
[INET_ADDRSTRLEN
];
3040 struct bsmmsg_grpinfo
*group
;
3041 struct bsmmsg_rpinfo
*rpaddr
;
3043 struct bsm_hdr
*hdr
;
3044 uint32_t offset
= 0;
3047 uint32_t frag_rp_cnt
= 0;
3052 /* skip pim header */
3053 buf
+= PIM_MSG_HEADER_LEN
;
3054 len
-= PIM_MSG_HEADER_LEN
;
3056 hdr
= (struct bsm_hdr
*)buf
;
3058 /* BSM starts with bsr header */
3059 buf
+= sizeof(struct bsm_hdr
);
3060 len
-= sizeof(struct bsm_hdr
);
3062 pim_inet4_dump("<BSR Address?>", hdr
->bsr_addr
.addr
, bsr_str
,
3067 json_object_string_add(json
, "BSR address", bsr_str
);
3068 json_object_int_add(json
, "BSR priority",
3070 json_object_int_add(json
, "Hashmask Length",
3072 json_object_int_add(json
, "Fragment Tag",
3073 ntohs(hdr
->frag_tag
));
3075 vty_out(vty
, "BSM Fragment : %d\n", fragment
);
3076 vty_out(vty
, "------------------\n");
3077 vty_out(vty
, "%-15s %-15s %-15s %-15s\n", "BSR-Address",
3078 "BSR-Priority", "Hashmask-len", "Fragment-Tag");
3079 vty_out(vty
, "%-15s %-15d %-15d %-15d\n", bsr_str
,
3080 hdr
->bsr_prio
, hdr
->hm_len
,
3081 ntohs(hdr
->frag_tag
));
3086 while (offset
< len
) {
3087 group
= (struct bsmmsg_grpinfo
*)buf
;
3089 if (group
->group
.family
== PIM_MSG_ADDRESS_FAMILY_IPV4
)
3090 grp
.family
= AF_INET
;
3092 grp
.prefixlen
= group
->group
.mask
;
3093 grp
.u
.prefix4
.s_addr
= group
->group
.addr
.s_addr
;
3095 prefix2str(&grp
, grp_str
, sizeof(grp_str
));
3097 buf
+= sizeof(struct bsmmsg_grpinfo
);
3098 offset
+= sizeof(struct bsmmsg_grpinfo
);
3101 json_object_object_get_ex(json
, grp_str
,
3104 json_group
= json_object_new_object();
3105 json_object_int_add(json_group
,
3108 json_object_int_add(
3109 json_group
, "Fragment Rp count",
3110 group
->frag_rp_count
);
3111 json_object_object_add(json
, grp_str
,
3115 vty_out(vty
, "Group : %s\n", grp_str
);
3116 vty_out(vty
, "-------------------\n");
3117 vty_out(vty
, "Rp Count:%d\n", group
->rp_count
);
3118 vty_out(vty
, "Fragment Rp Count : %d\n",
3119 group
->frag_rp_count
);
3122 frag_rp_cnt
= group
->frag_rp_count
;
3129 "RpAddress HoldTime Priority\n");
3131 while (frag_rp_cnt
--) {
3132 rpaddr
= (struct bsmmsg_rpinfo
*)buf
;
3134 buf
+= sizeof(struct bsmmsg_rpinfo
);
3135 offset
+= sizeof(struct bsmmsg_rpinfo
);
3137 pim_inet4_dump("<Rp addr?>",
3138 rpaddr
->rpaddr
.addr
, rp_str
,
3142 json_row
= json_object_new_object();
3143 json_object_string_add(
3144 json_row
, "Rp Address", rp_str
);
3145 json_object_int_add(
3146 json_row
, "Rp HoldTime",
3147 ntohs(rpaddr
->rp_holdtime
));
3148 json_object_int_add(json_row
,
3151 json_object_object_add(
3152 json_group
, rp_str
, json_row
);
3154 vty_out(vty
, "%-15s %-12d %d\n", rp_str
,
3155 ntohs(rpaddr
->rp_holdtime
),
3166 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3167 json
, JSON_C_TO_STRING_PRETTY
));
3168 json_object_free(json
);
3172 /*Display the group-rp mappings */
3173 static void pim_show_group_rp_mappings_info(struct pim_instance
*pim
,
3174 struct vty
*vty
, bool uj
)
3176 struct bsgrp_node
*bsgrp
;
3177 struct listnode
*rpnode
;
3178 struct bsm_rpinfo
*bsm_rp
;
3179 struct route_node
*rn
;
3180 char bsr_str
[INET_ADDRSTRLEN
];
3181 json_object
*json
= NULL
;
3182 json_object
*json_group
= NULL
;
3183 json_object
*json_row
= NULL
;
3185 if (pim
->global_scope
.current_bsr
.s_addr
== INADDR_ANY
)
3186 strlcpy(bsr_str
, "0.0.0.0", sizeof(bsr_str
));
3189 pim_inet4_dump("<bsr?>", pim
->global_scope
.current_bsr
, bsr_str
,
3193 json
= json_object_new_object();
3194 json_object_string_add(json
, "BSR Address", bsr_str
);
3196 vty_out(vty
, "BSR Address %s\n", bsr_str
);
3199 for (rn
= route_top(pim
->global_scope
.bsrp_table
); rn
;
3200 rn
= route_next(rn
)) {
3201 bsgrp
= (struct bsgrp_node
*)rn
->info
;
3206 char grp_str
[PREFIX_STRLEN
];
3208 prefix2str(&bsgrp
->group
, grp_str
, sizeof(grp_str
));
3211 json_object_object_get_ex(json
, grp_str
, &json_group
);
3213 json_group
= json_object_new_object();
3214 json_object_object_add(json
, grp_str
,
3218 vty_out(vty
, "Group Address %s\n", grp_str
);
3219 vty_out(vty
, "--------------------------\n");
3220 vty_out(vty
, "%-15s %-15s %-15s %-15s\n", "Rp Address",
3221 "priority", "Holdtime", "Hash");
3223 vty_out(vty
, "(ACTIVE)\n");
3226 if (bsgrp
->bsrp_list
) {
3227 for (ALL_LIST_ELEMENTS_RO(bsgrp
->bsrp_list
, rpnode
,
3229 char rp_str
[INET_ADDRSTRLEN
];
3231 pim_inet4_dump("<Rp Address?>",
3232 bsm_rp
->rp_address
, rp_str
,
3236 json_row
= json_object_new_object();
3237 json_object_string_add(
3238 json_row
, "Rp Address", rp_str
);
3239 json_object_int_add(
3240 json_row
, "Rp HoldTime",
3241 bsm_rp
->rp_holdtime
);
3242 json_object_int_add(json_row
,
3245 json_object_int_add(json_row
,
3248 json_object_object_add(
3249 json_group
, rp_str
, json_row
);
3253 "%-15s %-15u %-15u %-15u\n",
3254 rp_str
, bsm_rp
->rp_prio
,
3255 bsm_rp
->rp_holdtime
,
3259 if (!bsgrp
->bsrp_list
->count
&& !uj
)
3260 vty_out(vty
, "Active List is empty.\n");
3264 json_object_int_add(json_group
, "Pending RP count",
3265 bsgrp
->pend_rp_cnt
);
3267 vty_out(vty
, "(PENDING)\n");
3268 vty_out(vty
, "Pending RP count :%d\n",
3269 bsgrp
->pend_rp_cnt
);
3270 if (bsgrp
->pend_rp_cnt
)
3271 vty_out(vty
, "%-15s %-15s %-15s %-15s\n",
3272 "Rp Address", "priority", "Holdtime",
3276 if (bsgrp
->partial_bsrp_list
) {
3277 for (ALL_LIST_ELEMENTS_RO(bsgrp
->partial_bsrp_list
,
3279 char rp_str
[INET_ADDRSTRLEN
];
3281 pim_inet4_dump("<Rp Addr?>", bsm_rp
->rp_address
,
3282 rp_str
, sizeof(rp_str
));
3285 json_row
= json_object_new_object();
3286 json_object_string_add(
3287 json_row
, "Rp Address", rp_str
);
3288 json_object_int_add(
3289 json_row
, "Rp HoldTime",
3290 bsm_rp
->rp_holdtime
);
3291 json_object_int_add(json_row
,
3294 json_object_int_add(json_row
,
3297 json_object_object_add(
3298 json_group
, rp_str
, json_row
);
3301 "%-15s %-15u %-15u %-15u\n",
3302 rp_str
, bsm_rp
->rp_prio
,
3303 bsm_rp
->rp_holdtime
,
3307 if (!bsgrp
->partial_bsrp_list
->count
&& !uj
)
3308 vty_out(vty
, "Partial List is empty\n");
3316 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3317 json
, JSON_C_TO_STRING_PRETTY
));
3318 json_object_free(json
);
3322 /* pim statistics - just adding only bsm related now.
3323 * We can continue to add all pim related stats here.
3325 static void pim_show_statistics(struct pim_instance
*pim
, struct vty
*vty
,
3326 const char *ifname
, bool uj
)
3328 json_object
*json
= NULL
;
3329 struct interface
*ifp
;
3332 json
= json_object_new_object();
3333 json_object_int_add(json
, "bsmRx", pim
->bsm_rcvd
);
3334 json_object_int_add(json
, "bsmTx", pim
->bsm_sent
);
3335 json_object_int_add(json
, "bsmDropped", pim
->bsm_dropped
);
3337 vty_out(vty
, "BSM Statistics :\n");
3338 vty_out(vty
, "----------------\n");
3339 vty_out(vty
, "Number of Received BSMs : %" PRIu64
"\n",
3341 vty_out(vty
, "Number of Forwared BSMs : %" PRIu64
"\n",
3343 vty_out(vty
, "Number of Dropped BSMs : %" PRIu64
"\n",
3349 /* scan interfaces */
3350 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3351 struct pim_interface
*pim_ifp
= ifp
->info
;
3353 if (ifname
&& strcmp(ifname
, ifp
->name
))
3360 vty_out(vty
, "Interface : %s\n", ifp
->name
);
3361 vty_out(vty
, "-------------------\n");
3363 "Number of BSMs dropped due to config miss : %u\n",
3364 pim_ifp
->pim_ifstat_bsm_cfg_miss
);
3365 vty_out(vty
, "Number of unicast BSMs dropped : %u\n",
3366 pim_ifp
->pim_ifstat_ucast_bsm_cfg_miss
);
3368 "Number of BSMs dropped due to invalid scope zone : %u\n",
3369 pim_ifp
->pim_ifstat_bsm_invalid_sz
);
3372 json_object
*json_row
= NULL
;
3374 json_row
= json_object_new_object();
3376 json_object_string_add(json_row
, "If Name", ifp
->name
);
3377 json_object_int_add(json_row
, "bsmDroppedConfig",
3378 pim_ifp
->pim_ifstat_bsm_cfg_miss
);
3379 json_object_int_add(
3380 json_row
, "bsmDroppedUnicast",
3381 pim_ifp
->pim_ifstat_ucast_bsm_cfg_miss
);
3382 json_object_int_add(json_row
,
3383 "bsmDroppedInvalidScopeZone",
3384 pim_ifp
->pim_ifstat_bsm_invalid_sz
);
3385 json_object_object_add(json
, ifp
->name
, json_row
);
3391 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3392 json
, JSON_C_TO_STRING_PRETTY
));
3393 json_object_free(json
);
3397 static void clear_pim_statistics(struct pim_instance
*pim
)
3399 struct interface
*ifp
;
3403 pim
->bsm_dropped
= 0;
3405 /* scan interfaces */
3406 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3407 struct pim_interface
*pim_ifp
= ifp
->info
;
3412 pim_ifp
->pim_ifstat_bsm_cfg_miss
= 0;
3413 pim_ifp
->pim_ifstat_ucast_bsm_cfg_miss
= 0;
3414 pim_ifp
->pim_ifstat_bsm_invalid_sz
= 0;
3418 static void igmp_show_groups(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
3420 struct interface
*ifp
;
3422 json_object
*json
= NULL
;
3423 json_object
*json_iface
= NULL
;
3424 json_object
*json_group
= NULL
;
3425 json_object
*json_groups
= NULL
;
3427 now
= pim_time_monotonic_sec();
3430 json
= json_object_new_object();
3431 json_object_int_add(json
, "totalGroups", pim
->igmp_group_count
);
3432 json_object_int_add(json
, "watermarkLimit",
3433 pim
->igmp_watermark_limit
);
3435 vty_out(vty
, "Total IGMP groups: %u\n", pim
->igmp_group_count
);
3436 vty_out(vty
, "Watermark warn limit(%s): %u\n",
3437 pim
->igmp_watermark_limit
? "Set" : "Not Set",
3438 pim
->igmp_watermark_limit
);
3440 "Interface Address Group Mode Timer Srcs V Uptime \n");
3443 /* scan interfaces */
3444 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3445 struct pim_interface
*pim_ifp
= ifp
->info
;
3446 struct listnode
*sock_node
;
3447 struct igmp_sock
*igmp
;
3452 /* scan igmp sockets */
3453 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3455 char ifaddr_str
[INET_ADDRSTRLEN
];
3456 struct listnode
*grpnode
;
3457 struct igmp_group
*grp
;
3459 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3460 sizeof(ifaddr_str
));
3462 /* scan igmp groups */
3463 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3465 char group_str
[INET_ADDRSTRLEN
];
3469 pim_inet4_dump("<group?>", grp
->group_addr
,
3470 group_str
, sizeof(group_str
));
3471 pim_time_timer_to_hhmmss(hhmmss
, sizeof(hhmmss
),
3472 grp
->t_group_timer
);
3473 pim_time_uptime(uptime
, sizeof(uptime
),
3474 now
- grp
->group_creation
);
3477 json_object_object_get_ex(
3478 json
, ifp
->name
, &json_iface
);
3482 json_object_new_object();
3483 json_object_pim_ifp_add(
3485 json_object_object_add(
3489 json_object_new_array();
3490 json_object_object_add(
3496 json_group
= json_object_new_object();
3497 json_object_string_add(json_group
,
3500 json_object_string_add(json_group
,
3504 if (grp
->igmp_version
== 3)
3505 json_object_string_add(
3507 grp
->group_filtermode_isexcl
3511 json_object_string_add(json_group
,
3513 json_object_int_add(
3514 json_group
, "sourcesCount",
3515 grp
->group_source_list
3517 grp
->group_source_list
)
3519 json_object_int_add(
3520 json_group
, "version",
3522 json_object_string_add(
3523 json_group
, "uptime", uptime
);
3524 json_object_array_add(json_groups
,
3528 "%-16s %-15s %-15s %4s %8s %4d %d %8s\n",
3529 ifp
->name
, ifaddr_str
,
3531 grp
->igmp_version
== 3
3532 ? (grp
->group_filtermode_isexcl
3537 grp
->group_source_list
3539 grp
->group_source_list
)
3541 grp
->igmp_version
, uptime
);
3543 } /* scan igmp groups */
3544 } /* scan igmp sockets */
3545 } /* scan interfaces */
3548 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3549 json
, JSON_C_TO_STRING_PRETTY
));
3550 json_object_free(json
);
3554 static void igmp_show_group_retransmission(struct pim_instance
*pim
,
3557 struct interface
*ifp
;
3560 "Interface Address Group RetTimer Counter RetSrcs\n");
3562 /* scan interfaces */
3563 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3564 struct pim_interface
*pim_ifp
= ifp
->info
;
3565 struct listnode
*sock_node
;
3566 struct igmp_sock
*igmp
;
3571 /* scan igmp sockets */
3572 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3574 char ifaddr_str
[INET_ADDRSTRLEN
];
3575 struct listnode
*grpnode
;
3576 struct igmp_group
*grp
;
3578 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3579 sizeof(ifaddr_str
));
3581 /* scan igmp groups */
3582 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3584 char group_str
[INET_ADDRSTRLEN
];
3585 char grp_retr_mmss
[10];
3586 struct listnode
*src_node
;
3587 struct igmp_source
*src
;
3588 int grp_retr_sources
= 0;
3590 pim_inet4_dump("<group?>", grp
->group_addr
,
3591 group_str
, sizeof(group_str
));
3592 pim_time_timer_to_mmss(
3593 grp_retr_mmss
, sizeof(grp_retr_mmss
),
3594 grp
->t_group_query_retransmit_timer
);
3597 /* count group sources with retransmission state
3599 for (ALL_LIST_ELEMENTS_RO(
3600 grp
->group_source_list
, src_node
,
3602 if (src
->source_query_retransmit_count
3608 vty_out(vty
, "%-16s %-15s %-15s %-8s %7d %7d\n",
3609 ifp
->name
, ifaddr_str
, group_str
,
3611 grp
->group_specific_query_retransmit_count
,
3614 } /* scan igmp groups */
3615 } /* scan igmp sockets */
3616 } /* scan interfaces */
3619 static void igmp_show_sources(struct pim_instance
*pim
, struct vty
*vty
)
3621 struct interface
*ifp
;
3624 now
= pim_time_monotonic_sec();
3627 "Interface Address Group Source Timer Fwd Uptime \n");
3629 /* scan interfaces */
3630 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3631 struct pim_interface
*pim_ifp
= ifp
->info
;
3632 struct listnode
*sock_node
;
3633 struct igmp_sock
*igmp
;
3638 /* scan igmp sockets */
3639 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3641 char ifaddr_str
[INET_ADDRSTRLEN
];
3642 struct listnode
*grpnode
;
3643 struct igmp_group
*grp
;
3645 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3646 sizeof(ifaddr_str
));
3648 /* scan igmp groups */
3649 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3651 char group_str
[INET_ADDRSTRLEN
];
3652 struct listnode
*srcnode
;
3653 struct igmp_source
*src
;
3655 pim_inet4_dump("<group?>", grp
->group_addr
,
3656 group_str
, sizeof(group_str
));
3658 /* scan group sources */
3659 for (ALL_LIST_ELEMENTS_RO(
3660 grp
->group_source_list
, srcnode
,
3662 char source_str
[INET_ADDRSTRLEN
];
3667 "<source?>", src
->source_addr
,
3668 source_str
, sizeof(source_str
));
3670 pim_time_timer_to_mmss(
3672 src
->t_source_timer
);
3675 uptime
, sizeof(uptime
),
3676 now
- src
->source_creation
);
3679 "%-16s %-15s %-15s %-15s %5s %3s %8s\n",
3680 ifp
->name
, ifaddr_str
,
3681 group_str
, source_str
, mmss
,
3682 IGMP_SOURCE_TEST_FORWARDING(
3688 } /* scan group sources */
3689 } /* scan igmp groups */
3690 } /* scan igmp sockets */
3691 } /* scan interfaces */
3694 static void igmp_show_source_retransmission(struct pim_instance
*pim
,
3697 struct interface
*ifp
;
3700 "Interface Address Group Source Counter\n");
3702 /* scan interfaces */
3703 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3704 struct pim_interface
*pim_ifp
= ifp
->info
;
3705 struct listnode
*sock_node
;
3706 struct igmp_sock
*igmp
;
3711 /* scan igmp sockets */
3712 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3714 char ifaddr_str
[INET_ADDRSTRLEN
];
3715 struct listnode
*grpnode
;
3716 struct igmp_group
*grp
;
3718 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3719 sizeof(ifaddr_str
));
3721 /* scan igmp groups */
3722 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3724 char group_str
[INET_ADDRSTRLEN
];
3725 struct listnode
*srcnode
;
3726 struct igmp_source
*src
;
3728 pim_inet4_dump("<group?>", grp
->group_addr
,
3729 group_str
, sizeof(group_str
));
3731 /* scan group sources */
3732 for (ALL_LIST_ELEMENTS_RO(
3733 grp
->group_source_list
, srcnode
,
3735 char source_str
[INET_ADDRSTRLEN
];
3738 "<source?>", src
->source_addr
,
3739 source_str
, sizeof(source_str
));
3742 "%-16s %-15s %-15s %-15s %7d\n",
3743 ifp
->name
, ifaddr_str
,
3744 group_str
, source_str
,
3745 src
->source_query_retransmit_count
);
3747 } /* scan group sources */
3748 } /* scan igmp groups */
3749 } /* scan igmp sockets */
3750 } /* scan interfaces */
3753 static void pim_show_bsr(struct pim_instance
*pim
,
3758 char last_bsm_seen
[10];
3761 char bsr_str
[PREFIX_STRLEN
];
3762 json_object
*json
= NULL
;
3764 if (pim
->global_scope
.current_bsr
.s_addr
== INADDR_ANY
) {
3765 strlcpy(bsr_str
, "0.0.0.0", sizeof(bsr_str
));
3766 pim_time_uptime(uptime
, sizeof(uptime
),
3767 pim
->global_scope
.current_bsr_first_ts
);
3768 pim_time_uptime(last_bsm_seen
, sizeof(last_bsm_seen
),
3769 pim
->global_scope
.current_bsr_last_ts
);
3773 pim_inet4_dump("<bsr?>", pim
->global_scope
.current_bsr
,
3774 bsr_str
, sizeof(bsr_str
));
3775 now
= pim_time_monotonic_sec();
3776 pim_time_uptime(uptime
, sizeof(uptime
),
3777 (now
- pim
->global_scope
.current_bsr_first_ts
));
3778 pim_time_uptime(last_bsm_seen
, sizeof(last_bsm_seen
),
3779 now
- pim
->global_scope
.current_bsr_last_ts
);
3782 switch (pim
->global_scope
.state
) {
3784 strlcpy(bsr_state
, "NO_INFO", sizeof(bsr_state
));
3787 strlcpy(bsr_state
, "ACCEPT_ANY", sizeof(bsr_state
));
3789 case ACCEPT_PREFERRED
:
3790 strlcpy(bsr_state
, "ACCEPT_PREFERRED", sizeof(bsr_state
));
3793 strlcpy(bsr_state
, "", sizeof(bsr_state
));
3797 json
= json_object_new_object();
3798 json_object_string_add(json
, "bsr", bsr_str
);
3799 json_object_int_add(json
, "priority",
3800 pim
->global_scope
.current_bsr_prio
);
3801 json_object_int_add(json
, "fragmentTag",
3802 pim
->global_scope
.bsm_frag_tag
);
3803 json_object_string_add(json
, "state", bsr_state
);
3804 json_object_string_add(json
, "upTime", uptime
);
3805 json_object_string_add(json
, "lastBsmSeen", last_bsm_seen
);
3809 vty_out(vty
, "PIMv2 Bootstrap information\n");
3810 vty_out(vty
, "Current preferred BSR address: %s\n", bsr_str
);
3812 "Priority Fragment-Tag State UpTime\n");
3813 vty_out(vty
, " %-12d %-12d %-13s %7s\n",
3814 pim
->global_scope
.current_bsr_prio
,
3815 pim
->global_scope
.bsm_frag_tag
,
3818 vty_out(vty
, "Last BSM seen: %s\n", last_bsm_seen
);
3822 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3823 json
, JSON_C_TO_STRING_PRETTY
));
3824 json_object_free(json
);
3828 static void clear_igmp_interfaces(struct pim_instance
*pim
)
3830 struct interface
*ifp
;
3832 FOR_ALL_INTERFACES (pim
->vrf
, ifp
)
3833 pim_if_addr_del_all_igmp(ifp
);
3835 FOR_ALL_INTERFACES (pim
->vrf
, ifp
)
3836 pim_if_addr_add_all(ifp
);
3839 static void clear_pim_interfaces(struct pim_instance
*pim
)
3841 struct interface
*ifp
;
3843 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3845 pim_neighbor_delete_all(ifp
, "interface cleared");
3850 static void clear_interfaces(struct pim_instance
*pim
)
3852 clear_igmp_interfaces(pim
);
3853 clear_pim_interfaces(pim
);
3856 #define PIM_GET_PIM_INTERFACE(pim_ifp, ifp) \
3857 pim_ifp = ifp->info; \
3860 "%% Enable PIM and/or IGMP on this interface first\n"); \
3861 return CMD_WARNING_CONFIG_FAILED; \
3864 DEFUN (clear_ip_interfaces
,
3865 clear_ip_interfaces_cmd
,
3866 "clear ip interfaces [vrf NAME]",
3869 "Reset interfaces\n"
3873 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3878 clear_interfaces(vrf
->info
);
3883 DEFUN (clear_ip_igmp_interfaces
,
3884 clear_ip_igmp_interfaces_cmd
,
3885 "clear ip igmp [vrf NAME] interfaces",
3890 "Reset IGMP interfaces\n")
3893 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3898 clear_igmp_interfaces(vrf
->info
);
3903 DEFUN (clear_ip_pim_statistics
,
3904 clear_ip_pim_statistics_cmd
,
3905 "clear ip pim statistics [vrf NAME]",
3910 "Reset PIM statistics\n")
3913 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3918 clear_pim_statistics(vrf
->info
);
3922 static void clear_mroute(struct pim_instance
*pim
)
3924 struct pim_upstream
*up
;
3925 struct interface
*ifp
;
3927 /* scan interfaces */
3928 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3929 struct pim_interface
*pim_ifp
= ifp
->info
;
3930 struct listnode
*sock_node
;
3931 struct igmp_sock
*igmp
;
3932 struct pim_ifchannel
*ch
;
3937 /* deleting all ifchannels */
3938 while (!RB_EMPTY(pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
)) {
3939 ch
= RB_ROOT(pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
);
3941 pim_ifchannel_delete(ch
);
3944 /* clean up all igmp groups */
3945 /* scan igmp sockets */
3946 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3949 struct igmp_group
*grp
;
3951 if (igmp
->igmp_group_list
) {
3952 while (igmp
->igmp_group_list
->count
) {
3953 grp
= listnode_head(
3954 igmp
->igmp_group_list
);
3955 igmp_group_delete(grp
);
3962 /* clean up all upstreams*/
3963 while ((up
= rb_pim_upstream_first(&pim
->upstream_head
))) {
3964 pim_upstream_del(pim
, up
, __func__
);
3968 DEFUN (clear_ip_mroute
,
3969 clear_ip_mroute_cmd
,
3970 "clear ip mroute [vrf NAME]",
3973 "Reset multicast routes\n"
3977 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3982 clear_mroute(vrf
->info
);
3987 DEFUN (clear_ip_pim_interfaces
,
3988 clear_ip_pim_interfaces_cmd
,
3989 "clear ip pim [vrf NAME] interfaces",
3994 "Reset PIM interfaces\n")
3997 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4002 clear_pim_interfaces(vrf
->info
);
4007 DEFUN (clear_ip_pim_interface_traffic
,
4008 clear_ip_pim_interface_traffic_cmd
,
4009 "clear ip pim [vrf NAME] interface traffic",
4012 "PIM clear commands\n"
4014 "Reset PIM interfaces\n"
4015 "Reset Protocol Packet counters\n")
4018 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4019 struct interface
*ifp
= NULL
;
4020 struct pim_interface
*pim_ifp
= NULL
;
4025 FOR_ALL_INTERFACES (vrf
, ifp
) {
4026 pim_ifp
= ifp
->info
;
4031 pim_ifp
->pim_ifstat_hello_recv
= 0;
4032 pim_ifp
->pim_ifstat_hello_sent
= 0;
4033 pim_ifp
->pim_ifstat_join_recv
= 0;
4034 pim_ifp
->pim_ifstat_join_send
= 0;
4035 pim_ifp
->pim_ifstat_prune_recv
= 0;
4036 pim_ifp
->pim_ifstat_prune_send
= 0;
4037 pim_ifp
->pim_ifstat_reg_recv
= 0;
4038 pim_ifp
->pim_ifstat_reg_send
= 0;
4039 pim_ifp
->pim_ifstat_reg_stop_recv
= 0;
4040 pim_ifp
->pim_ifstat_reg_stop_send
= 0;
4041 pim_ifp
->pim_ifstat_assert_recv
= 0;
4042 pim_ifp
->pim_ifstat_assert_send
= 0;
4043 pim_ifp
->pim_ifstat_bsm_rx
= 0;
4044 pim_ifp
->pim_ifstat_bsm_tx
= 0;
4050 DEFUN (clear_ip_pim_oil
,
4051 clear_ip_pim_oil_cmd
,
4052 "clear ip pim [vrf NAME] oil",
4057 "Rescan PIM OIL (output interface list)\n")
4060 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4065 pim_scan_oil(vrf
->info
);
4070 DEFUN (show_ip_igmp_interface
,
4071 show_ip_igmp_interface_cmd
,
4072 "show ip igmp [vrf NAME] interface [detail|WORD] [json]",
4077 "IGMP interface information\n"
4083 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4084 bool uj
= use_json(argc
, argv
);
4089 if (argv_find(argv
, argc
, "detail", &idx
)
4090 || argv_find(argv
, argc
, "WORD", &idx
))
4091 igmp_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
4093 igmp_show_interfaces(vrf
->info
, vty
, uj
);
4098 DEFUN (show_ip_igmp_interface_vrf_all
,
4099 show_ip_igmp_interface_vrf_all_cmd
,
4100 "show ip igmp vrf all interface [detail|WORD] [json]",
4105 "IGMP interface information\n"
4111 bool uj
= use_json(argc
, argv
);
4117 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4121 vty_out(vty
, " \"%s\": ", vrf
->name
);
4124 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4125 if (argv_find(argv
, argc
, "detail", &idx
)
4126 || argv_find(argv
, argc
, "WORD", &idx
))
4127 igmp_show_interfaces_single(vrf
->info
, vty
,
4128 argv
[idx
]->arg
, uj
);
4130 igmp_show_interfaces(vrf
->info
, vty
, uj
);
4133 vty_out(vty
, "}\n");
4138 DEFUN (show_ip_igmp_join
,
4139 show_ip_igmp_join_cmd
,
4140 "show ip igmp [vrf NAME] join",
4145 "IGMP static join information\n")
4148 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4153 igmp_show_interface_join(vrf
->info
, vty
);
4158 DEFUN (show_ip_igmp_join_vrf_all
,
4159 show_ip_igmp_join_vrf_all_cmd
,
4160 "show ip igmp vrf all join",
4165 "IGMP static join information\n")
4167 bool uj
= use_json(argc
, argv
);
4173 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4177 vty_out(vty
, " \"%s\": ", vrf
->name
);
4180 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4181 igmp_show_interface_join(vrf
->info
, vty
);
4184 vty_out(vty
, "}\n");
4189 DEFUN (show_ip_igmp_groups
,
4190 show_ip_igmp_groups_cmd
,
4191 "show ip igmp [vrf NAME] groups [json]",
4200 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4201 bool uj
= use_json(argc
, argv
);
4206 igmp_show_groups(vrf
->info
, vty
, uj
);
4211 DEFUN (show_ip_igmp_groups_vrf_all
,
4212 show_ip_igmp_groups_vrf_all_cmd
,
4213 "show ip igmp vrf all groups [json]",
4221 bool uj
= use_json(argc
, argv
);
4227 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4231 vty_out(vty
, " \"%s\": ", vrf
->name
);
4234 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4235 igmp_show_groups(vrf
->info
, vty
, uj
);
4238 vty_out(vty
, "}\n");
4243 DEFUN (show_ip_igmp_groups_retransmissions
,
4244 show_ip_igmp_groups_retransmissions_cmd
,
4245 "show ip igmp [vrf NAME] groups retransmissions",
4251 "IGMP group retransmissions\n")
4254 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4259 igmp_show_group_retransmission(vrf
->info
, vty
);
4264 DEFUN (show_ip_igmp_sources
,
4265 show_ip_igmp_sources_cmd
,
4266 "show ip igmp [vrf NAME] sources",
4274 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4279 igmp_show_sources(vrf
->info
, vty
);
4284 DEFUN (show_ip_igmp_sources_retransmissions
,
4285 show_ip_igmp_sources_retransmissions_cmd
,
4286 "show ip igmp [vrf NAME] sources retransmissions",
4292 "IGMP source retransmissions\n")
4295 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4300 igmp_show_source_retransmission(vrf
->info
, vty
);
4305 DEFUN (show_ip_igmp_statistics
,
4306 show_ip_igmp_statistics_cmd
,
4307 "show ip igmp [vrf NAME] statistics [interface WORD] [json]",
4318 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4319 bool uj
= use_json(argc
, argv
);
4324 if (argv_find(argv
, argc
, "WORD", &idx
))
4325 igmp_show_statistics(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
4327 igmp_show_statistics(vrf
->info
, vty
, NULL
, uj
);
4332 DEFUN (show_ip_pim_mlag_summary
,
4333 show_ip_pim_mlag_summary_cmd
,
4334 "show ip pim mlag summary [json]",
4339 "status and stats\n"
4342 bool uj
= use_json(argc
, argv
);
4343 char role_buf
[MLAG_ROLE_STRSIZE
];
4344 char addr_buf
[INET_ADDRSTRLEN
];
4347 json_object
*json
= NULL
;
4348 json_object
*json_stat
= NULL
;
4350 json
= json_object_new_object();
4351 if (router
->mlag_flags
& PIM_MLAGF_LOCAL_CONN_UP
)
4352 json_object_boolean_true_add(json
, "mlagConnUp");
4353 if (router
->mlag_flags
& PIM_MLAGF_PEER_CONN_UP
)
4354 json_object_boolean_true_add(json
, "mlagPeerConnUp");
4355 if (router
->mlag_flags
& PIM_MLAGF_PEER_ZEBRA_UP
)
4356 json_object_boolean_true_add(json
, "mlagPeerZebraUp");
4357 json_object_string_add(json
, "mlagRole",
4358 mlag_role2str(router
->mlag_role
,
4359 role_buf
, sizeof(role_buf
)));
4360 inet_ntop(AF_INET
, &router
->local_vtep_ip
,
4361 addr_buf
, INET_ADDRSTRLEN
);
4362 json_object_string_add(json
, "localVtepIp", addr_buf
);
4363 inet_ntop(AF_INET
, &router
->anycast_vtep_ip
,
4364 addr_buf
, INET_ADDRSTRLEN
);
4365 json_object_string_add(json
, "anycastVtepIp", addr_buf
);
4366 json_object_string_add(json
, "peerlinkRif",
4367 router
->peerlink_rif
);
4369 json_stat
= json_object_new_object();
4370 json_object_int_add(json_stat
, "mlagConnFlaps",
4371 router
->mlag_stats
.mlagd_session_downs
);
4372 json_object_int_add(json_stat
, "mlagPeerConnFlaps",
4373 router
->mlag_stats
.peer_session_downs
);
4374 json_object_int_add(json_stat
, "mlagPeerZebraFlaps",
4375 router
->mlag_stats
.peer_zebra_downs
);
4376 json_object_int_add(json_stat
, "mrouteAddRx",
4377 router
->mlag_stats
.msg
.mroute_add_rx
);
4378 json_object_int_add(json_stat
, "mrouteAddTx",
4379 router
->mlag_stats
.msg
.mroute_add_tx
);
4380 json_object_int_add(json_stat
, "mrouteDelRx",
4381 router
->mlag_stats
.msg
.mroute_del_rx
);
4382 json_object_int_add(json_stat
, "mrouteDelTx",
4383 router
->mlag_stats
.msg
.mroute_del_tx
);
4384 json_object_int_add(json_stat
, "mlagStatusUpdates",
4385 router
->mlag_stats
.msg
.mlag_status_updates
);
4386 json_object_int_add(json_stat
, "peerZebraStatusUpdates",
4387 router
->mlag_stats
.msg
.peer_zebra_status_updates
);
4388 json_object_int_add(json_stat
, "pimStatusUpdates",
4389 router
->mlag_stats
.msg
.pim_status_updates
);
4390 json_object_int_add(json_stat
, "vxlanUpdates",
4391 router
->mlag_stats
.msg
.vxlan_updates
);
4392 json_object_object_add(json
, "connStats", json_stat
);
4394 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4395 json
, JSON_C_TO_STRING_PRETTY
));
4396 json_object_free(json
);
4400 vty_out(vty
, "MLAG daemon connection: %s\n",
4401 (router
->mlag_flags
& PIM_MLAGF_LOCAL_CONN_UP
)
4403 vty_out(vty
, "MLAG peer state: %s\n",
4404 (router
->mlag_flags
& PIM_MLAGF_PEER_CONN_UP
)
4406 vty_out(vty
, "Zebra peer state: %s\n",
4407 (router
->mlag_flags
& PIM_MLAGF_PEER_ZEBRA_UP
)
4409 vty_out(vty
, "MLAG role: %s\n",
4410 mlag_role2str(router
->mlag_role
, role_buf
, sizeof(role_buf
)));
4411 inet_ntop(AF_INET
, &router
->local_vtep_ip
,
4412 addr_buf
, INET_ADDRSTRLEN
);
4413 vty_out(vty
, "Local VTEP IP: %s\n", addr_buf
);
4414 inet_ntop(AF_INET
, &router
->anycast_vtep_ip
,
4415 addr_buf
, INET_ADDRSTRLEN
);
4416 vty_out(vty
, "Anycast VTEP IP: %s\n", addr_buf
);
4417 vty_out(vty
, "Peerlink: %s\n", router
->peerlink_rif
);
4418 vty_out(vty
, "Session flaps: mlagd: %d mlag-peer: %d zebra-peer: %d\n",
4419 router
->mlag_stats
.mlagd_session_downs
,
4420 router
->mlag_stats
.peer_session_downs
,
4421 router
->mlag_stats
.peer_zebra_downs
);
4422 vty_out(vty
, "Message Statistics:\n");
4423 vty_out(vty
, " mroute adds: rx: %d, tx: %d\n",
4424 router
->mlag_stats
.msg
.mroute_add_rx
,
4425 router
->mlag_stats
.msg
.mroute_add_tx
);
4426 vty_out(vty
, " mroute dels: rx: %d, tx: %d\n",
4427 router
->mlag_stats
.msg
.mroute_del_rx
,
4428 router
->mlag_stats
.msg
.mroute_del_tx
);
4429 vty_out(vty
, " peer zebra status updates: %d\n",
4430 router
->mlag_stats
.msg
.peer_zebra_status_updates
);
4431 vty_out(vty
, " PIM status updates: %d\n",
4432 router
->mlag_stats
.msg
.pim_status_updates
);
4433 vty_out(vty
, " VxLAN updates: %d\n",
4434 router
->mlag_stats
.msg
.vxlan_updates
);
4439 DEFUN (show_ip_pim_assert
,
4440 show_ip_pim_assert_cmd
,
4441 "show ip pim [vrf NAME] assert",
4446 "PIM interface assert\n")
4449 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4454 pim_show_assert(vrf
->info
, vty
);
4459 DEFUN (show_ip_pim_assert_internal
,
4460 show_ip_pim_assert_internal_cmd
,
4461 "show ip pim [vrf NAME] assert-internal",
4466 "PIM interface internal assert state\n")
4469 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4474 pim_show_assert_internal(vrf
->info
, vty
);
4479 DEFUN (show_ip_pim_assert_metric
,
4480 show_ip_pim_assert_metric_cmd
,
4481 "show ip pim [vrf NAME] assert-metric",
4486 "PIM interface assert metric\n")
4489 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4494 pim_show_assert_metric(vrf
->info
, vty
);
4499 DEFUN (show_ip_pim_assert_winner_metric
,
4500 show_ip_pim_assert_winner_metric_cmd
,
4501 "show ip pim [vrf NAME] assert-winner-metric",
4506 "PIM interface assert winner metric\n")
4509 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4514 pim_show_assert_winner_metric(vrf
->info
, vty
);
4519 DEFUN (show_ip_pim_interface
,
4520 show_ip_pim_interface_cmd
,
4521 "show ip pim [mlag] [vrf NAME] interface [detail|WORD] [json]",
4527 "PIM interface information\n"
4533 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4534 bool uj
= use_json(argc
, argv
);
4540 if (argv_find(argv
, argc
, "mlag", &idx
))
4543 if (argv_find(argv
, argc
, "WORD", &idx
)
4544 || argv_find(argv
, argc
, "detail", &idx
))
4545 pim_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, mlag
,
4548 pim_show_interfaces(vrf
->info
, vty
, mlag
, uj
);
4553 DEFUN (show_ip_pim_interface_vrf_all
,
4554 show_ip_pim_interface_vrf_all_cmd
,
4555 "show ip pim [mlag] vrf all interface [detail|WORD] [json]",
4561 "PIM interface information\n"
4567 bool uj
= use_json(argc
, argv
);
4572 if (argv_find(argv
, argc
, "mlag", &idx
))
4578 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4582 vty_out(vty
, " \"%s\": ", vrf
->name
);
4585 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4586 if (argv_find(argv
, argc
, "WORD", &idx
)
4587 || argv_find(argv
, argc
, "detail", &idx
))
4588 pim_show_interfaces_single(vrf
->info
, vty
,
4589 argv
[idx
]->arg
, mlag
, uj
);
4591 pim_show_interfaces(vrf
->info
, vty
, mlag
, uj
);
4594 vty_out(vty
, "}\n");
4599 DEFPY (show_ip_pim_join
,
4600 show_ip_pim_join_cmd
,
4601 "show ip pim [vrf NAME] join [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
4606 "PIM interface join information\n"
4607 "The Source or Group\n"
4611 struct prefix_sg sg
= {0};
4614 struct pim_instance
*pim
;
4616 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
4619 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
4622 pim
= pim_get_pim_instance(v
->vrf_id
);
4625 vty_out(vty
, "%% Unable to find pim instance\n");
4629 if (s_or_g
.s_addr
!= 0) {
4630 if (g
.s_addr
!= 0) {
4637 pim_show_join(pim
, vty
, &sg
, uj
);
4642 DEFUN (show_ip_pim_join_vrf_all
,
4643 show_ip_pim_join_vrf_all_cmd
,
4644 "show ip pim vrf all join [json]",
4649 "PIM interface join information\n"
4652 struct prefix_sg sg
= {0};
4653 bool uj
= use_json(argc
, argv
);
4659 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4663 vty_out(vty
, " \"%s\": ", vrf
->name
);
4666 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4667 pim_show_join(vrf
->info
, vty
, &sg
, uj
);
4670 vty_out(vty
, "}\n");
4675 static void pim_show_jp_agg_helper(struct vty
*vty
,
4676 struct interface
*ifp
,
4677 struct pim_neighbor
*neigh
,
4678 struct pim_upstream
*up
,
4681 char src_str
[INET_ADDRSTRLEN
];
4682 char grp_str
[INET_ADDRSTRLEN
];
4683 char rpf_str
[INET_ADDRSTRLEN
];
4685 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
4686 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
4687 /* pius->address.s_addr */
4688 pim_inet4_dump("<rpf?>", neigh
->source_addr
, rpf_str
, sizeof(rpf_str
));
4690 vty_out(vty
, "%-16s %-15s %-15s %-15s %5s\n",
4691 ifp
->name
, rpf_str
, src_str
,
4692 grp_str
, is_join
?"J":"P");
4695 static void pim_show_jp_agg_list(struct pim_instance
*pim
, struct vty
*vty
)
4697 struct interface
*ifp
;
4698 struct pim_interface
*pim_ifp
;
4699 struct listnode
*n_node
;
4700 struct pim_neighbor
*neigh
;
4701 struct listnode
*jag_node
;
4702 struct pim_jp_agg_group
*jag
;
4703 struct listnode
*js_node
;
4704 struct pim_jp_sources
*js
;
4707 "Interface RPF Nbr Source Group State\n");
4709 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
4710 pim_ifp
= ifp
->info
;
4714 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
,
4716 for (ALL_LIST_ELEMENTS_RO(neigh
->upstream_jp_agg
,
4718 for (ALL_LIST_ELEMENTS_RO(jag
->sources
,
4720 pim_show_jp_agg_helper(vty
,
4729 DEFPY (show_ip_pim_jp_agg
,
4730 show_ip_pim_jp_agg_cmd
,
4731 "show ip pim [vrf NAME] jp-agg",
4736 "join prune aggregation list\n")
4739 struct pim_instance
*pim
;
4741 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
4744 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
4747 pim
= pim_get_pim_instance(v
->vrf_id
);
4750 vty_out(vty
, "%% Unable to find pim instance\n");
4754 pim_show_jp_agg_list(pim
, vty
);
4759 DEFUN (show_ip_pim_local_membership
,
4760 show_ip_pim_local_membership_cmd
,
4761 "show ip pim [vrf NAME] local-membership [json]",
4766 "PIM interface local-membership\n"
4770 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4771 bool uj
= use_json(argc
, argv
);
4776 pim_show_membership(vrf
->info
, vty
, uj
);
4781 static void pim_show_mlag_up_entry_detail(struct vrf
*vrf
,
4782 struct vty
*vty
, struct pim_upstream
*up
,
4783 char *src_str
, char *grp_str
, json_object
*json
)
4786 json_object
*json_row
= NULL
;
4787 json_object
*own_list
= NULL
;
4788 json_object
*json_group
= NULL
;
4791 json_object_object_get_ex(json
, grp_str
, &json_group
);
4793 json_group
= json_object_new_object();
4794 json_object_object_add(json
, grp_str
,
4798 json_row
= json_object_new_object();
4799 json_object_string_add(json_row
, "source", src_str
);
4800 json_object_string_add(json_row
, "group", grp_str
);
4802 own_list
= json_object_new_array();
4803 if (pim_up_mlag_is_local(up
))
4804 json_object_array_add(own_list
,
4805 json_object_new_string("local"));
4806 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
))
4807 json_object_array_add(own_list
,
4808 json_object_new_string("peer"));
4809 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE
))
4810 json_object_array_add(
4811 own_list
, json_object_new_string("Interface"));
4812 json_object_object_add(json_row
, "owners", own_list
);
4814 json_object_int_add(json_row
, "localCost",
4815 pim_up_mlag_local_cost(up
));
4816 json_object_int_add(json_row
, "peerCost",
4817 pim_up_mlag_peer_cost(up
));
4818 if (PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up
->flags
))
4819 json_object_boolean_false_add(json_row
, "df");
4821 json_object_boolean_true_add(json_row
, "df");
4822 json_object_object_add(json_group
, src_str
, json_row
);
4827 if (pim_up_mlag_is_local(up
))
4828 strlcat(own_str
, "L", sizeof(own_str
));
4829 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
))
4830 strlcat(own_str
, "P", sizeof(own_str
));
4831 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE
))
4832 strlcat(own_str
, "I", sizeof(own_str
));
4833 /* XXX - fixup, print paragraph output */
4835 "%-15s %-15s %-6s %-11u %-10d %2s\n",
4836 src_str
, grp_str
, own_str
,
4837 pim_up_mlag_local_cost(up
),
4838 pim_up_mlag_peer_cost(up
),
4839 PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up
->flags
)
4844 static void pim_show_mlag_up_detail(struct vrf
*vrf
,
4845 struct vty
*vty
, const char *src_or_group
,
4846 const char *group
, bool uj
)
4848 char src_str
[INET_ADDRSTRLEN
];
4849 char grp_str
[INET_ADDRSTRLEN
];
4850 struct pim_upstream
*up
;
4851 struct pim_instance
*pim
= vrf
->info
;
4852 json_object
*json
= NULL
;
4855 json
= json_object_new_object();
4858 "Source Group Owner Local-cost Peer-cost DF\n");
4860 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
4861 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
)
4862 && !(up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE
)
4863 && !pim_up_mlag_is_local(up
))
4866 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
4867 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
4868 /* XXX: strcmps are clearly inefficient. we should do uint comps
4872 if (strcmp(src_str
, src_or_group
) ||
4873 strcmp(grp_str
, group
))
4876 if (strcmp(src_str
, src_or_group
) &&
4877 strcmp(grp_str
, src_or_group
))
4880 pim_show_mlag_up_entry_detail(vrf
, vty
, up
,
4881 src_str
, grp_str
, json
);
4885 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4886 json
, JSON_C_TO_STRING_PRETTY
));
4887 json_object_free(json
);
4891 static void pim_show_mlag_up_vrf(struct vrf
*vrf
, struct vty
*vty
, bool uj
)
4893 json_object
*json
= NULL
;
4894 json_object
*json_row
;
4895 struct pim_upstream
*up
;
4896 char src_str
[INET_ADDRSTRLEN
];
4897 char grp_str
[INET_ADDRSTRLEN
];
4898 struct pim_instance
*pim
= vrf
->info
;
4899 json_object
*json_group
= NULL
;
4902 json
= json_object_new_object();
4905 "Source Group Owner Local-cost Peer-cost DF\n");
4908 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
4909 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
)
4910 && !(up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE
)
4911 && !pim_up_mlag_is_local(up
))
4913 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
4914 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
4916 json_object
*own_list
= NULL
;
4918 json_object_object_get_ex(json
, grp_str
, &json_group
);
4920 json_group
= json_object_new_object();
4921 json_object_object_add(json
, grp_str
,
4925 json_row
= json_object_new_object();
4926 json_object_string_add(json_row
, "vrf", vrf
->name
);
4927 json_object_string_add(json_row
, "source", src_str
);
4928 json_object_string_add(json_row
, "group", grp_str
);
4930 own_list
= json_object_new_array();
4931 if (pim_up_mlag_is_local(up
)) {
4933 json_object_array_add(own_list
,
4934 json_object_new_string("local"));
4936 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
)) {
4937 json_object_array_add(own_list
,
4938 json_object_new_string("peer"));
4940 json_object_object_add(json_row
, "owners", own_list
);
4942 json_object_int_add(json_row
, "localCost",
4943 pim_up_mlag_local_cost(up
));
4944 json_object_int_add(json_row
, "peerCost",
4945 pim_up_mlag_peer_cost(up
));
4946 if (PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up
->flags
))
4947 json_object_boolean_false_add(json_row
, "df");
4949 json_object_boolean_true_add(json_row
, "df");
4950 json_object_object_add(json_group
, src_str
, json_row
);
4955 if (pim_up_mlag_is_local(up
))
4956 strlcat(own_str
, "L", sizeof(own_str
));
4957 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
))
4958 strlcat(own_str
, "P", sizeof(own_str
));
4959 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE
))
4960 strlcat(own_str
, "I", sizeof(own_str
));
4962 "%-15s %-15s %-6s %-11u %-10u %2s\n",
4963 src_str
, grp_str
, own_str
,
4964 pim_up_mlag_local_cost(up
),
4965 pim_up_mlag_peer_cost(up
),
4966 PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up
->flags
)
4971 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4972 json
, JSON_C_TO_STRING_PRETTY
));
4973 json_object_free(json
);
4977 static void pim_show_mlag_help_string(struct vty
*vty
, bool uj
)
4980 vty_out(vty
, "Owner codes:\n");
4982 "L: EVPN-MLAG Entry, I:PIM-MLAG Entry, "
4988 DEFUN(show_ip_pim_mlag_up
, show_ip_pim_mlag_up_cmd
,
4989 "show ip pim [vrf NAME] mlag upstream [A.B.C.D [A.B.C.D]] [json]",
4996 "Unicast or Multicast address\n"
4997 "Multicast address\n" JSON_STR
)
4999 const char *src_or_group
= NULL
;
5000 const char *group
= NULL
;
5002 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5003 bool uj
= use_json(argc
, argv
);
5005 if (!vrf
|| !vrf
->info
) {
5006 vty_out(vty
, "%s: VRF or Info missing\n", __func__
);
5013 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
5014 src_or_group
= argv
[idx
]->arg
;
5016 group
= argv
[idx
+ 1]->arg
;
5019 pim_show_mlag_help_string(vty
, uj
);
5022 pim_show_mlag_up_detail(vrf
, vty
, src_or_group
, group
, uj
);
5024 pim_show_mlag_up_vrf(vrf
, vty
, uj
);
5030 DEFUN(show_ip_pim_mlag_up_vrf_all
, show_ip_pim_mlag_up_vrf_all_cmd
,
5031 "show ip pim vrf all mlag upstream [json]",
5032 SHOW_STR IP_STR PIM_STR VRF_CMD_HELP_STR
5034 "upstream\n" JSON_STR
)
5037 bool uj
= use_json(argc
, argv
);
5039 pim_show_mlag_help_string(vty
, uj
);
5040 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5041 pim_show_mlag_up_vrf(vrf
, vty
, uj
);
5047 DEFUN (show_ip_pim_neighbor
,
5048 show_ip_pim_neighbor_cmd
,
5049 "show ip pim [vrf NAME] neighbor [detail|WORD] [json]",
5054 "PIM neighbor information\n"
5056 "Name of interface or neighbor\n"
5060 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5061 bool uj
= use_json(argc
, argv
);
5066 if (argv_find(argv
, argc
, "detail", &idx
)
5067 || argv_find(argv
, argc
, "WORD", &idx
))
5068 pim_show_neighbors_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
5070 pim_show_neighbors(vrf
->info
, vty
, uj
);
5075 DEFUN (show_ip_pim_neighbor_vrf_all
,
5076 show_ip_pim_neighbor_vrf_all_cmd
,
5077 "show ip pim vrf all neighbor [detail|WORD] [json]",
5082 "PIM neighbor information\n"
5084 "Name of interface or neighbor\n"
5088 bool uj
= use_json(argc
, argv
);
5094 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5098 vty_out(vty
, " \"%s\": ", vrf
->name
);
5101 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5102 if (argv_find(argv
, argc
, "detail", &idx
)
5103 || argv_find(argv
, argc
, "WORD", &idx
))
5104 pim_show_neighbors_single(vrf
->info
, vty
,
5105 argv
[idx
]->arg
, uj
);
5107 pim_show_neighbors(vrf
->info
, vty
, uj
);
5110 vty_out(vty
, "}\n");
5115 DEFUN (show_ip_pim_secondary
,
5116 show_ip_pim_secondary_cmd
,
5117 "show ip pim [vrf NAME] secondary",
5122 "PIM neighbor addresses\n")
5125 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5130 pim_show_neighbors_secondary(vrf
->info
, vty
);
5135 DEFUN (show_ip_pim_state
,
5136 show_ip_pim_state_cmd
,
5137 "show ip pim [vrf NAME] state [A.B.C.D [A.B.C.D]] [json]",
5142 "PIM state information\n"
5143 "Unicast or Multicast address\n"
5144 "Multicast address\n"
5147 const char *src_or_group
= NULL
;
5148 const char *group
= NULL
;
5150 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5151 bool uj
= use_json(argc
, argv
);
5159 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
5160 src_or_group
= argv
[idx
]->arg
;
5162 group
= argv
[idx
+ 1]->arg
;
5165 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
5170 DEFUN (show_ip_pim_state_vrf_all
,
5171 show_ip_pim_state_vrf_all_cmd
,
5172 "show ip pim vrf all state [A.B.C.D [A.B.C.D]] [json]",
5177 "PIM state information\n"
5178 "Unicast or Multicast address\n"
5179 "Multicast address\n"
5182 const char *src_or_group
= NULL
;
5183 const char *group
= NULL
;
5185 bool uj
= use_json(argc
, argv
);
5194 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
5195 src_or_group
= argv
[idx
]->arg
;
5197 group
= argv
[idx
+ 1]->arg
;
5200 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5204 vty_out(vty
, " \"%s\": ", vrf
->name
);
5207 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5208 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
5211 vty_out(vty
, "}\n");
5216 DEFPY (show_ip_pim_upstream
,
5217 show_ip_pim_upstream_cmd
,
5218 "show ip pim [vrf NAME] upstream [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
5223 "PIM upstream information\n"
5224 "The Source or Group\n"
5228 struct prefix_sg sg
= {0};
5231 struct pim_instance
*pim
;
5233 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
5236 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
5239 pim
= pim_get_pim_instance(v
->vrf_id
);
5242 vty_out(vty
, "%% Unable to find pim instance\n");
5246 if (s_or_g
.s_addr
!= 0) {
5247 if (g
.s_addr
!= 0) {
5253 pim_show_upstream(pim
, vty
, &sg
, uj
);
5258 DEFUN (show_ip_pim_upstream_vrf_all
,
5259 show_ip_pim_upstream_vrf_all_cmd
,
5260 "show ip pim vrf all upstream [json]",
5265 "PIM upstream information\n"
5268 struct prefix_sg sg
= {0};
5269 bool uj
= use_json(argc
, argv
);
5275 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5279 vty_out(vty
, " \"%s\": ", vrf
->name
);
5282 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5283 pim_show_upstream(vrf
->info
, vty
, &sg
, uj
);
5289 DEFUN (show_ip_pim_channel
,
5290 show_ip_pim_channel_cmd
,
5291 "show ip pim [vrf NAME] channel [json]",
5296 "PIM downstream channel info\n"
5300 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5301 bool uj
= use_json(argc
, argv
);
5306 pim_show_channel(vrf
->info
, vty
, uj
);
5311 DEFUN (show_ip_pim_upstream_join_desired
,
5312 show_ip_pim_upstream_join_desired_cmd
,
5313 "show ip pim [vrf NAME] upstream-join-desired [json]",
5318 "PIM upstream join-desired\n"
5322 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5323 bool uj
= use_json(argc
, argv
);
5328 pim_show_join_desired(vrf
->info
, vty
, uj
);
5333 DEFUN (show_ip_pim_upstream_rpf
,
5334 show_ip_pim_upstream_rpf_cmd
,
5335 "show ip pim [vrf NAME] upstream-rpf [json]",
5340 "PIM upstream source rpf\n"
5344 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5345 bool uj
= use_json(argc
, argv
);
5350 pim_show_upstream_rpf(vrf
->info
, vty
, uj
);
5355 DEFUN (show_ip_pim_rp
,
5357 "show ip pim [vrf NAME] rp-info [json]",
5362 "PIM RP information\n"
5366 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5367 bool uj
= use_json(argc
, argv
);
5372 pim_rp_show_information(vrf
->info
, vty
, uj
);
5377 DEFUN (show_ip_pim_rp_vrf_all
,
5378 show_ip_pim_rp_vrf_all_cmd
,
5379 "show ip pim vrf all rp-info [json]",
5384 "PIM RP information\n"
5387 bool uj
= use_json(argc
, argv
);
5393 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5397 vty_out(vty
, " \"%s\": ", vrf
->name
);
5400 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5401 pim_rp_show_information(vrf
->info
, vty
, uj
);
5404 vty_out(vty
, "}\n");
5409 DEFUN (show_ip_pim_rpf
,
5410 show_ip_pim_rpf_cmd
,
5411 "show ip pim [vrf NAME] rpf [json]",
5416 "PIM cached source rpf information\n"
5420 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5421 bool uj
= use_json(argc
, argv
);
5426 pim_show_rpf(vrf
->info
, vty
, uj
);
5431 DEFUN (show_ip_pim_rpf_vrf_all
,
5432 show_ip_pim_rpf_vrf_all_cmd
,
5433 "show ip pim vrf all rpf [json]",
5438 "PIM cached source rpf information\n"
5441 bool uj
= use_json(argc
, argv
);
5447 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5451 vty_out(vty
, " \"%s\": ", vrf
->name
);
5454 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5455 pim_show_rpf(vrf
->info
, vty
, uj
);
5458 vty_out(vty
, "}\n");
5463 DEFUN (show_ip_pim_nexthop
,
5464 show_ip_pim_nexthop_cmd
,
5465 "show ip pim [vrf NAME] nexthop",
5470 "PIM cached nexthop rpf information\n")
5473 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5478 pim_show_nexthop(vrf
->info
, vty
);
5483 DEFUN (show_ip_pim_nexthop_lookup
,
5484 show_ip_pim_nexthop_lookup_cmd
,
5485 "show ip pim [vrf NAME] nexthop-lookup A.B.C.D A.B.C.D",
5490 "PIM cached nexthop rpf lookup\n"
5491 "Source/RP address\n"
5492 "Multicast Group address\n")
5494 struct prefix nht_p
;
5496 struct in_addr src_addr
, grp_addr
;
5497 struct in_addr vif_source
;
5498 const char *addr_str
, *addr_str1
;
5500 struct pim_nexthop nexthop
;
5501 char nexthop_addr_str
[PREFIX_STRLEN
];
5502 char grp_str
[PREFIX_STRLEN
];
5504 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5509 argv_find(argv
, argc
, "A.B.C.D", &idx
);
5510 addr_str
= argv
[idx
]->arg
;
5511 result
= inet_pton(AF_INET
, addr_str
, &src_addr
);
5513 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
5514 errno
, safe_strerror(errno
));
5518 if (pim_is_group_224_4(src_addr
)) {
5520 "Invalid argument. Expected Valid Source Address.\n");
5524 addr_str1
= argv
[idx
+ 1]->arg
;
5525 result
= inet_pton(AF_INET
, addr_str1
, &grp_addr
);
5527 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
5528 errno
, safe_strerror(errno
));
5532 if (!pim_is_group_224_4(grp_addr
)) {
5534 "Invalid argument. Expected Valid Multicast Group Address.\n");
5538 if (!pim_rp_set_upstream_addr(vrf
->info
, &vif_source
, src_addr
,
5542 nht_p
.family
= AF_INET
;
5543 nht_p
.prefixlen
= IPV4_MAX_BITLEN
;
5544 nht_p
.u
.prefix4
= vif_source
;
5545 grp
.family
= AF_INET
;
5546 grp
.prefixlen
= IPV4_MAX_BITLEN
;
5547 grp
.u
.prefix4
= grp_addr
;
5548 memset(&nexthop
, 0, sizeof(nexthop
));
5550 result
= pim_ecmp_nexthop_lookup(vrf
->info
, &nexthop
, &nht_p
, &grp
, 0);
5554 "Nexthop Lookup failed, no usable routes returned.\n");
5558 pim_addr_dump("<grp?>", &grp
, grp_str
, sizeof(grp_str
));
5559 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
5560 nexthop_addr_str
, sizeof(nexthop_addr_str
));
5561 vty_out(vty
, "Group %s --- Nexthop %s Interface %s \n", grp_str
,
5562 nexthop_addr_str
, nexthop
.interface
->name
);
5567 DEFUN (show_ip_pim_interface_traffic
,
5568 show_ip_pim_interface_traffic_cmd
,
5569 "show ip pim [vrf NAME] interface traffic [WORD] [json]",
5574 "PIM interface information\n"
5575 "Protocol Packet counters\n"
5580 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5581 bool uj
= use_json(argc
, argv
);
5586 if (argv_find(argv
, argc
, "WORD", &idx
))
5587 pim_show_interface_traffic_single(vrf
->info
, vty
,
5588 argv
[idx
]->arg
, uj
);
5590 pim_show_interface_traffic(vrf
->info
, vty
, uj
);
5595 DEFUN (show_ip_pim_bsm_db
,
5596 show_ip_pim_bsm_db_cmd
,
5597 "show ip pim bsm-database [vrf NAME] [json]",
5601 "PIM cached bsm packets information\n"
5606 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5607 bool uj
= use_json(argc
, argv
);
5612 pim_show_bsm_db(vrf
->info
, vty
, uj
);
5616 DEFUN (show_ip_pim_bsrp
,
5617 show_ip_pim_bsrp_cmd
,
5618 "show ip pim bsrp-info [vrf NAME] [json]",
5622 "PIM cached group-rp mappings information\n"
5627 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5628 bool uj
= use_json(argc
, argv
);
5633 pim_show_group_rp_mappings_info(vrf
->info
, vty
, uj
);
5638 DEFUN (show_ip_pim_statistics
,
5639 show_ip_pim_statistics_cmd
,
5640 "show ip pim [vrf NAME] statistics [interface WORD] [json]",
5651 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5652 bool uj
= use_json(argc
, argv
);
5657 if (argv_find(argv
, argc
, "WORD", &idx
))
5658 pim_show_statistics(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
5660 pim_show_statistics(vrf
->info
, vty
, NULL
, uj
);
5665 static void show_multicast_interfaces(struct pim_instance
*pim
, struct vty
*vty
)
5667 struct interface
*ifp
;
5672 "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut\n");
5674 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
5675 struct pim_interface
*pim_ifp
;
5676 struct in_addr ifaddr
;
5677 struct sioc_vif_req vreq
;
5679 pim_ifp
= ifp
->info
;
5684 memset(&vreq
, 0, sizeof(vreq
));
5685 vreq
.vifi
= pim_ifp
->mroute_vif_index
;
5687 if (ioctl(pim
->mroute_socket
, SIOCGETVIFCNT
, &vreq
)) {
5689 "ioctl(SIOCGETVIFCNT=%lu) failure for interface %s vif_index=%d: errno=%d: %s",
5690 (unsigned long)SIOCGETVIFCNT
, ifp
->name
,
5691 pim_ifp
->mroute_vif_index
, errno
,
5692 safe_strerror(errno
));
5695 ifaddr
= pim_ifp
->primary_address
;
5697 vty_out(vty
, "%-16s %-15s %3d %3d %7lu %7lu %10lu %10lu\n",
5698 ifp
->name
, inet_ntoa(ifaddr
), ifp
->ifindex
,
5699 pim_ifp
->mroute_vif_index
, (unsigned long)vreq
.icount
,
5700 (unsigned long)vreq
.ocount
, (unsigned long)vreq
.ibytes
,
5701 (unsigned long)vreq
.obytes
);
5705 static void pim_cmd_show_ip_multicast_helper(struct pim_instance
*pim
,
5708 struct vrf
*vrf
= pim
->vrf
;
5709 time_t now
= pim_time_monotonic_sec();
5715 vty_out(vty
, "Router MLAG Role: %s\n",
5716 mlag_role2str(router
->mlag_role
, mlag_role
, sizeof(mlag_role
)));
5717 vty_out(vty
, "Mroute socket descriptor:");
5719 vty_out(vty
, " %d(%s)\n", pim
->mroute_socket
, vrf
->name
);
5721 pim_time_uptime(uptime
, sizeof(uptime
),
5722 now
- pim
->mroute_socket_creation
);
5723 vty_out(vty
, "Mroute socket uptime: %s\n", uptime
);
5727 pim_zebra_zclient_update(vty
);
5728 pim_zlookup_show_ip_multicast(vty
);
5731 vty_out(vty
, "Maximum highest VifIndex: %d\n", PIM_MAX_USABLE_VIFS
);
5734 vty_out(vty
, "Upstream Join Timer: %d secs\n", router
->t_periodic
);
5735 vty_out(vty
, "Join/Prune Holdtime: %d secs\n", PIM_JP_HOLDTIME
);
5736 vty_out(vty
, "PIM ECMP: %s\n", pim
->ecmp_enable
? "Enable" : "Disable");
5737 vty_out(vty
, "PIM ECMP Rebalance: %s\n",
5738 pim
->ecmp_rebalance_enable
? "Enable" : "Disable");
5742 show_rpf_refresh_stats(vty
, pim
, now
, NULL
);
5746 show_scan_oil_stats(pim
, vty
, now
);
5748 show_multicast_interfaces(pim
, vty
);
5751 DEFUN (show_ip_multicast
,
5752 show_ip_multicast_cmd
,
5753 "show ip multicast [vrf NAME]",
5757 "Multicast global information\n")
5760 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5765 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
5770 DEFUN (show_ip_multicast_vrf_all
,
5771 show_ip_multicast_vrf_all_cmd
,
5772 "show ip multicast vrf all",
5776 "Multicast global information\n")
5778 bool uj
= use_json(argc
, argv
);
5784 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5788 vty_out(vty
, " \"%s\": ", vrf
->name
);
5791 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5792 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
5795 vty_out(vty
, "}\n");
5800 static void show_mroute(struct pim_instance
*pim
, struct vty
*vty
,
5801 struct prefix_sg
*sg
, bool fill
, bool uj
)
5803 struct listnode
*node
;
5804 struct channel_oil
*c_oil
;
5805 struct static_route
*s_route
;
5807 json_object
*json
= NULL
;
5808 json_object
*json_group
= NULL
;
5809 json_object
*json_source
= NULL
;
5810 json_object
*json_oil
= NULL
;
5811 json_object
*json_ifp_out
= NULL
;
5814 char grp_str
[INET_ADDRSTRLEN
];
5815 char src_str
[INET_ADDRSTRLEN
];
5816 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
5817 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
5819 struct interface
*ifp_in
;
5821 char state_str
[PIM_REG_STATE_STR_LEN
];
5822 char mroute_uptime
[10];
5825 json
= json_object_new_object();
5827 vty_out(vty
, "IP Multicast Routing Table\n");
5828 vty_out(vty
, "Flags: S - Sparse, C - Connected, P - Pruned\n");
5830 " R - RP-bit set, F - Register flag, T - SPT-bit set\n");
5832 "\nSource Group Flags Proto Input Output TTL Uptime\n");
5835 now
= pim_time_monotonic_sec();
5837 /* print list of PIM and IGMP routes */
5838 frr_each (rb_pim_oil
, &pim
->channel_oil_head
, c_oil
) {
5841 if (!c_oil
->installed
&& !uj
)
5844 if (sg
->grp
.s_addr
!= 0 &&
5845 sg
->grp
.s_addr
!= c_oil
->oil
.mfcc_mcastgrp
.s_addr
)
5847 if (sg
->src
.s_addr
!= 0 &&
5848 sg
->src
.s_addr
!= c_oil
->oil
.mfcc_origin
.s_addr
)
5851 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
5853 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
5856 strlcpy(state_str
, "S", sizeof(state_str
));
5857 /* When a non DR receives a igmp join, it creates a (*,G)
5858 * channel_oil without any upstream creation */
5860 if (PIM_UPSTREAM_FLAG_TEST_SRC_IGMP(c_oil
->up
->flags
))
5861 strlcat(state_str
, "C", sizeof(state_str
));
5862 if (pim_upstream_is_sg_rpt(c_oil
->up
))
5863 strlcat(state_str
, "R", sizeof(state_str
));
5864 if (PIM_UPSTREAM_FLAG_TEST_FHR(c_oil
->up
->flags
))
5865 strlcat(state_str
, "F", sizeof(state_str
));
5866 if (c_oil
->up
->sptbit
== PIM_UPSTREAM_SPTBIT_TRUE
)
5867 strlcat(state_str
, "T", sizeof(state_str
));
5869 if (pim_channel_oil_empty(c_oil
))
5870 strlcat(state_str
, "P", sizeof(state_str
));
5872 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
5875 strlcpy(in_ifname
, ifp_in
->name
, sizeof(in_ifname
));
5877 strlcpy(in_ifname
, "<iif?>", sizeof(in_ifname
));
5880 pim_time_uptime(mroute_uptime
, sizeof(mroute_uptime
),
5881 now
- c_oil
->mroute_creation
);
5885 /* Find the group, create it if it doesn't exist */
5886 json_object_object_get_ex(json
, grp_str
, &json_group
);
5889 json_group
= json_object_new_object();
5890 json_object_object_add(json
, grp_str
,
5894 /* Find the source nested under the group, create it if
5897 json_object_object_get_ex(json_group
, src_str
,
5901 json_source
= json_object_new_object();
5902 json_object_object_add(json_group
, src_str
,
5906 /* Find the inbound interface nested under the source,
5907 * create it if it doesn't exist */
5908 json_object_int_add(json_source
, "installed",
5910 json_object_int_add(json_source
, "refCount",
5911 c_oil
->oil_ref_count
);
5912 json_object_int_add(json_source
, "oilSize",
5914 json_object_int_add(json_source
, "OilInheritedRescan",
5915 c_oil
->oil_inherited_rescan
);
5916 json_object_string_add(json_source
, "iif", in_ifname
);
5917 json_object_string_add(json_source
, "upTime",
5922 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
5924 struct interface
*ifp_out
;
5927 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
5931 /* do not display muted OIFs */
5932 if (c_oil
->oif_flags
[oif_vif_index
]
5933 & PIM_OIF_FLAG_MUTE
)
5936 if (c_oil
->oil
.mfcc_parent
== oif_vif_index
&&
5937 !pim_mroute_allow_iif_in_oil(c_oil
,
5941 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
5945 strlcpy(out_ifname
, ifp_out
->name
, sizeof(out_ifname
));
5947 strlcpy(out_ifname
, "<oif?>", sizeof(out_ifname
));
5950 json_ifp_out
= json_object_new_object();
5951 json_object_string_add(json_ifp_out
, "source",
5953 json_object_string_add(json_ifp_out
, "group",
5956 if (c_oil
->oif_flags
[oif_vif_index
]
5957 & PIM_OIF_FLAG_PROTO_PIM
)
5958 json_object_boolean_true_add(
5959 json_ifp_out
, "protocolPim");
5961 if (c_oil
->oif_flags
[oif_vif_index
]
5962 & PIM_OIF_FLAG_PROTO_IGMP
)
5963 json_object_boolean_true_add(
5964 json_ifp_out
, "protocolIgmp");
5966 if (c_oil
->oif_flags
[oif_vif_index
]
5967 & PIM_OIF_FLAG_PROTO_VXLAN
)
5968 json_object_boolean_true_add(
5969 json_ifp_out
, "protocolVxlan");
5971 if (c_oil
->oif_flags
[oif_vif_index
]
5972 & PIM_OIF_FLAG_PROTO_STAR
)
5973 json_object_boolean_true_add(
5975 "protocolInherited");
5977 json_object_string_add(json_ifp_out
,
5980 json_object_int_add(json_ifp_out
, "iVifI",
5981 c_oil
->oil
.mfcc_parent
);
5982 json_object_string_add(json_ifp_out
,
5983 "outboundInterface",
5985 json_object_int_add(json_ifp_out
, "oVifI",
5987 json_object_int_add(json_ifp_out
, "ttl", ttl
);
5988 json_object_string_add(json_ifp_out
, "upTime",
5991 json_oil
= json_object_new_object();
5992 json_object_object_add(json_source
,
5995 json_object_object_add(json_oil
, out_ifname
,
5998 if (c_oil
->oif_flags
[oif_vif_index
]
5999 & PIM_OIF_FLAG_PROTO_PIM
) {
6000 strlcpy(proto
, "PIM", sizeof(proto
));
6003 if (c_oil
->oif_flags
[oif_vif_index
]
6004 & PIM_OIF_FLAG_PROTO_IGMP
) {
6005 strlcpy(proto
, "IGMP", sizeof(proto
));
6008 if (c_oil
->oif_flags
[oif_vif_index
]
6009 & PIM_OIF_FLAG_PROTO_VXLAN
) {
6010 strlcpy(proto
, "VxLAN", sizeof(proto
));
6013 if (c_oil
->oif_flags
[oif_vif_index
]
6014 & PIM_OIF_FLAG_PROTO_STAR
) {
6015 strlcpy(proto
, "STAR", sizeof(proto
));
6019 "%-15s %-15s %-15s %-6s %-16s %-16s %-3d %8s\n",
6020 src_str
, grp_str
, state_str
, proto
,
6021 in_ifname
, out_ifname
, ttl
,
6027 in_ifname
[0] = '\0';
6028 state_str
[0] = '\0';
6029 mroute_uptime
[0] = '\0';
6035 if (!uj
&& !found_oif
) {
6037 "%-15s %-15s %-15s %-6s %-16s %-16s %-3d %8s\n",
6038 src_str
, grp_str
, state_str
, "none", in_ifname
,
6039 "none", 0, "--:--:--");
6043 /* Print list of static routes */
6044 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
6047 if (!s_route
->c_oil
.installed
)
6050 pim_inet4_dump("<group?>", s_route
->group
, grp_str
,
6052 pim_inet4_dump("<source?>", s_route
->source
, src_str
,
6054 ifp_in
= pim_if_find_by_vif_index(pim
, s_route
->iif
);
6058 strlcpy(in_ifname
, ifp_in
->name
, sizeof(in_ifname
));
6060 strlcpy(in_ifname
, "<iif?>", sizeof(in_ifname
));
6064 /* Find the group, create it if it doesn't exist */
6065 json_object_object_get_ex(json
, grp_str
, &json_group
);
6068 json_group
= json_object_new_object();
6069 json_object_object_add(json
, grp_str
,
6073 /* Find the source nested under the group, create it if
6074 * it doesn't exist */
6075 json_object_object_get_ex(json_group
, src_str
,
6079 json_source
= json_object_new_object();
6080 json_object_object_add(json_group
, src_str
,
6084 json_object_string_add(json_source
, "iif", in_ifname
);
6087 strlcpy(proto
, "STATIC", sizeof(proto
));
6090 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
6092 struct interface
*ifp_out
;
6093 char oif_uptime
[10];
6096 ttl
= s_route
->oif_ttls
[oif_vif_index
];
6100 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
6102 oif_uptime
, sizeof(oif_uptime
),
6105 .oif_creation
[oif_vif_index
]);
6109 strlcpy(out_ifname
, ifp_out
->name
, sizeof(out_ifname
));
6111 strlcpy(out_ifname
, "<oif?>", sizeof(out_ifname
));
6114 json_ifp_out
= json_object_new_object();
6115 json_object_string_add(json_ifp_out
, "source",
6117 json_object_string_add(json_ifp_out
, "group",
6119 json_object_boolean_true_add(json_ifp_out
,
6121 json_object_string_add(json_ifp_out
,
6124 json_object_int_add(
6125 json_ifp_out
, "iVifI",
6126 s_route
->c_oil
.oil
.mfcc_parent
);
6127 json_object_string_add(json_ifp_out
,
6128 "outboundInterface",
6130 json_object_int_add(json_ifp_out
, "oVifI",
6132 json_object_int_add(json_ifp_out
, "ttl", ttl
);
6133 json_object_string_add(json_ifp_out
, "upTime",
6136 json_oil
= json_object_new_object();
6137 json_object_object_add(json_source
,
6140 json_object_object_add(json_oil
, out_ifname
,
6144 "%-15s %-15s %-6s %-16s %-16s %-3d %8s %s\n",
6145 src_str
, grp_str
, proto
, in_ifname
,
6146 out_ifname
, ttl
, oif_uptime
,
6148 if (first
&& !fill
) {
6151 in_ifname
[0] = '\0';
6157 if (!uj
&& !found_oif
) {
6159 "%-15s %-15s %-6s %-16s %-16s %-3d %8s %s\n",
6160 src_str
, grp_str
, proto
, in_ifname
, "none", 0,
6161 "--:--:--", pim
->vrf
->name
);
6166 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
6167 json
, JSON_C_TO_STRING_PRETTY
));
6168 json_object_free(json
);
6172 DEFPY (show_ip_mroute
,
6174 "show ip mroute [vrf NAME] [A.B.C.D$s_or_g [A.B.C.D$g]] [fill$fill] [json$json]",
6179 "The Source or Group\n"
6181 "Fill in Assumed data\n"
6184 struct prefix_sg sg
= {0};
6185 struct pim_instance
*pim
;
6188 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
6191 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
6194 pim
= pim_get_pim_instance(v
->vrf_id
);
6197 vty_out(vty
, "%% Unable to find pim instance\n");
6201 if (s_or_g
.s_addr
!= 0) {
6202 if (g
.s_addr
!= 0) {
6208 show_mroute(pim
, vty
, &sg
, !!fill
, !!json
);
6212 DEFUN (show_ip_mroute_vrf_all
,
6213 show_ip_mroute_vrf_all_cmd
,
6214 "show ip mroute vrf all [fill] [json]",
6219 "Fill in Assumed data\n"
6222 struct prefix_sg sg
= {0};
6223 bool uj
= use_json(argc
, argv
);
6229 if (argv_find(argv
, argc
, "fill", &idx
))
6234 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
6238 vty_out(vty
, " \"%s\": ", vrf
->name
);
6241 vty_out(vty
, "VRF: %s\n", vrf
->name
);
6242 show_mroute(vrf
->info
, vty
, &sg
, fill
, uj
);
6245 vty_out(vty
, "}\n");
6250 DEFUN (clear_ip_mroute_count
,
6251 clear_ip_mroute_count_cmd
,
6252 "clear ip mroute [vrf NAME] count",
6257 "Route and packet count data\n")
6260 struct listnode
*node
;
6261 struct channel_oil
*c_oil
;
6262 struct static_route
*sr
;
6263 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6264 struct pim_instance
*pim
;
6270 frr_each(rb_pim_oil
, &pim
->channel_oil_head
, c_oil
) {
6271 if (!c_oil
->installed
)
6274 pim_mroute_update_counters(c_oil
);
6275 c_oil
->cc
.origpktcnt
= c_oil
->cc
.pktcnt
;
6276 c_oil
->cc
.origbytecnt
= c_oil
->cc
.bytecnt
;
6277 c_oil
->cc
.origwrong_if
= c_oil
->cc
.wrong_if
;
6280 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, sr
)) {
6281 if (!sr
->c_oil
.installed
)
6284 pim_mroute_update_counters(&sr
->c_oil
);
6286 sr
->c_oil
.cc
.origpktcnt
= sr
->c_oil
.cc
.pktcnt
;
6287 sr
->c_oil
.cc
.origbytecnt
= sr
->c_oil
.cc
.bytecnt
;
6288 sr
->c_oil
.cc
.origwrong_if
= sr
->c_oil
.cc
.wrong_if
;
6293 static void show_mroute_count(struct pim_instance
*pim
, struct vty
*vty
)
6295 struct listnode
*node
;
6296 struct channel_oil
*c_oil
;
6297 struct static_route
*sr
;
6302 "Source Group LastUsed Packets Bytes WrongIf \n");
6304 /* Print PIM and IGMP route counts */
6305 frr_each (rb_pim_oil
, &pim
->channel_oil_head
, c_oil
) {
6306 char group_str
[INET_ADDRSTRLEN
];
6307 char source_str
[INET_ADDRSTRLEN
];
6309 if (!c_oil
->installed
)
6312 pim_mroute_update_counters(c_oil
);
6314 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, group_str
,
6316 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, source_str
,
6317 sizeof(source_str
));
6319 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
6320 source_str
, group_str
, c_oil
->cc
.lastused
/ 100,
6321 c_oil
->cc
.pktcnt
- c_oil
->cc
.origpktcnt
,
6322 c_oil
->cc
.bytecnt
- c_oil
->cc
.origbytecnt
,
6323 c_oil
->cc
.wrong_if
- c_oil
->cc
.origwrong_if
);
6326 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, sr
)) {
6327 char group_str
[INET_ADDRSTRLEN
];
6328 char source_str
[INET_ADDRSTRLEN
];
6330 if (!sr
->c_oil
.installed
)
6333 pim_mroute_update_counters(&sr
->c_oil
);
6335 pim_inet4_dump("<group?>", sr
->c_oil
.oil
.mfcc_mcastgrp
,
6336 group_str
, sizeof(group_str
));
6337 pim_inet4_dump("<source?>", sr
->c_oil
.oil
.mfcc_origin
,
6338 source_str
, sizeof(source_str
));
6340 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
6341 source_str
, group_str
, sr
->c_oil
.cc
.lastused
,
6342 sr
->c_oil
.cc
.pktcnt
- sr
->c_oil
.cc
.origpktcnt
,
6343 sr
->c_oil
.cc
.bytecnt
- sr
->c_oil
.cc
.origbytecnt
,
6344 sr
->c_oil
.cc
.wrong_if
- sr
->c_oil
.cc
.origwrong_if
);
6348 DEFUN (show_ip_mroute_count
,
6349 show_ip_mroute_count_cmd
,
6350 "show ip mroute [vrf NAME] count",
6355 "Route and packet count data\n")
6358 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6363 show_mroute_count(vrf
->info
, vty
);
6367 DEFUN (show_ip_mroute_count_vrf_all
,
6368 show_ip_mroute_count_vrf_all_cmd
,
6369 "show ip mroute vrf all count",
6374 "Route and packet count data\n")
6376 bool uj
= use_json(argc
, argv
);
6382 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
6386 vty_out(vty
, " \"%s\": ", vrf
->name
);
6389 vty_out(vty
, "VRF: %s\n", vrf
->name
);
6390 show_mroute_count(vrf
->info
, vty
);
6393 vty_out(vty
, "}\n");
6398 static void show_mroute_summary(struct pim_instance
*pim
, struct vty
*vty
)
6400 struct listnode
*node
;
6401 struct channel_oil
*c_oil
;
6402 struct static_route
*s_route
;
6403 uint32_t starg_sw_mroute_cnt
= 0;
6404 uint32_t sg_sw_mroute_cnt
= 0;
6405 uint32_t starg_hw_mroute_cnt
= 0;
6406 uint32_t sg_hw_mroute_cnt
= 0;
6408 vty_out(vty
, "Mroute Type Installed/Total\n");
6410 frr_each (rb_pim_oil
, &pim
->channel_oil_head
, c_oil
) {
6411 if (!c_oil
->installed
) {
6412 if (c_oil
->oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
6413 starg_sw_mroute_cnt
++;
6417 if (c_oil
->oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
6418 starg_hw_mroute_cnt
++;
6424 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
6425 if (!s_route
->c_oil
.installed
) {
6426 if (s_route
->c_oil
.oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
6427 starg_sw_mroute_cnt
++;
6431 if (s_route
->c_oil
.oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
6432 starg_hw_mroute_cnt
++;
6438 vty_out(vty
, "%-20s %d/%d\n", "(*, G)", starg_hw_mroute_cnt
,
6439 starg_sw_mroute_cnt
+ starg_hw_mroute_cnt
);
6440 vty_out(vty
, "%-20s %d/%d\n", "(S, G)", sg_hw_mroute_cnt
,
6441 sg_sw_mroute_cnt
+ sg_hw_mroute_cnt
);
6442 vty_out(vty
, "------\n");
6443 vty_out(vty
, "%-20s %d/%d\n", "Total",
6444 (starg_hw_mroute_cnt
+ sg_hw_mroute_cnt
),
6445 (starg_sw_mroute_cnt
+
6446 starg_hw_mroute_cnt
+
6451 DEFUN (show_ip_mroute_summary
,
6452 show_ip_mroute_summary_cmd
,
6453 "show ip mroute [vrf NAME] summary",
6458 "Summary of all mroutes\n")
6461 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6466 show_mroute_summary(vrf
->info
, vty
);
6470 DEFUN (show_ip_mroute_summary_vrf_all
,
6471 show_ip_mroute_summary_vrf_all_cmd
,
6472 "show ip mroute vrf all summary",
6477 "Summary of all mroutes\n")
6481 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
6482 vty_out(vty
, "VRF: %s\n", vrf
->name
);
6483 show_mroute_summary(vrf
->info
, vty
);
6491 "show ip rib [vrf NAME] A.B.C.D",
6496 "Unicast address\n")
6499 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6500 struct in_addr addr
;
6501 const char *addr_str
;
6502 struct pim_nexthop nexthop
;
6503 char nexthop_addr_str
[PREFIX_STRLEN
];
6509 memset(&nexthop
, 0, sizeof(nexthop
));
6510 argv_find(argv
, argc
, "A.B.C.D", &idx
);
6511 addr_str
= argv
[idx
]->arg
;
6512 result
= inet_pton(AF_INET
, addr_str
, &addr
);
6514 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
6515 errno
, safe_strerror(errno
));
6519 if (!pim_nexthop_lookup(vrf
->info
, &nexthop
, addr
, 0)) {
6521 "Failure querying RIB nexthop for unicast address %s\n",
6527 "Address NextHop Interface Metric Preference\n");
6529 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
6530 nexthop_addr_str
, sizeof(nexthop_addr_str
));
6532 vty_out(vty
, "%-15s %-15s %-9s %6d %10d\n", addr_str
, nexthop_addr_str
,
6533 nexthop
.interface
? nexthop
.interface
->name
: "<ifname?>",
6534 nexthop
.mrib_route_metric
, nexthop
.mrib_metric_preference
);
6539 static void show_ssmpingd(struct pim_instance
*pim
, struct vty
*vty
)
6541 struct listnode
*node
;
6542 struct ssmpingd_sock
*ss
;
6546 "Source Socket Address Port Uptime Requests\n");
6548 if (!pim
->ssmpingd_list
)
6551 now
= pim_time_monotonic_sec();
6553 for (ALL_LIST_ELEMENTS_RO(pim
->ssmpingd_list
, node
, ss
)) {
6554 char source_str
[INET_ADDRSTRLEN
];
6556 struct sockaddr_in bind_addr
;
6557 socklen_t len
= sizeof(bind_addr
);
6558 char bind_addr_str
[INET_ADDRSTRLEN
];
6560 pim_inet4_dump("<src?>", ss
->source_addr
, source_str
,
6561 sizeof(source_str
));
6563 if (pim_socket_getsockname(
6564 ss
->sock_fd
, (struct sockaddr
*)&bind_addr
, &len
)) {
6566 "%% Failure reading socket name for ssmpingd source %s on fd=%d\n",
6567 source_str
, ss
->sock_fd
);
6570 pim_inet4_dump("<addr?>", bind_addr
.sin_addr
, bind_addr_str
,
6571 sizeof(bind_addr_str
));
6572 pim_time_uptime(ss_uptime
, sizeof(ss_uptime
),
6573 now
- ss
->creation
);
6575 vty_out(vty
, "%-15s %6d %-15s %5d %8s %8lld\n", source_str
,
6576 ss
->sock_fd
, bind_addr_str
, ntohs(bind_addr
.sin_port
),
6577 ss_uptime
, (long long)ss
->requests
);
6581 DEFUN (show_ip_ssmpingd
,
6582 show_ip_ssmpingd_cmd
,
6583 "show ip ssmpingd [vrf NAME]",
6590 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6595 show_ssmpingd(vrf
->info
, vty
);
6599 static int pim_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
6600 const char *rp
, const char *group
,
6605 result
= pim_rp_new_config(pim
, rp
, group
, plist
);
6607 if (result
== PIM_GROUP_BAD_ADDR_MASK_COMBO
) {
6608 vty_out(vty
, "%% Inconsistent address and mask: %s\n",
6610 return CMD_WARNING_CONFIG_FAILED
;
6613 if (result
== PIM_GROUP_BAD_ADDRESS
) {
6614 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
6615 return CMD_WARNING_CONFIG_FAILED
;
6618 if (result
== PIM_RP_BAD_ADDRESS
) {
6619 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
6620 return CMD_WARNING_CONFIG_FAILED
;
6623 if (result
== PIM_RP_NO_PATH
) {
6624 vty_out(vty
, "%% No Path to RP address specified: %s\n", rp
);
6628 if (result
== PIM_GROUP_OVERLAP
) {
6630 "%% Group range specified cannot exact match another\n");
6631 return CMD_WARNING_CONFIG_FAILED
;
6634 if (result
== PIM_GROUP_PFXLIST_OVERLAP
) {
6636 "%% This group is already covered by a RP prefix-list\n");
6637 return CMD_WARNING_CONFIG_FAILED
;
6640 if (result
== PIM_RP_PFXLIST_IN_USE
) {
6642 "%% The same prefix-list cannot be applied to multiple RPs\n");
6643 return CMD_WARNING_CONFIG_FAILED
;
6649 static int pim_cmd_spt_switchover(struct pim_instance
*pim
,
6650 enum pim_spt_switchover spt
,
6653 pim
->spt
.switchover
= spt
;
6655 switch (pim
->spt
.switchover
) {
6656 case PIM_SPT_IMMEDIATE
:
6657 XFREE(MTYPE_PIM_PLIST_NAME
, pim
->spt
.plist
);
6659 pim_upstream_add_lhr_star_pimreg(pim
);
6661 case PIM_SPT_INFINITY
:
6662 pim_upstream_remove_lhr_star_pimreg(pim
, plist
);
6664 XFREE(MTYPE_PIM_PLIST_NAME
, pim
->spt
.plist
);
6668 XSTRDUP(MTYPE_PIM_PLIST_NAME
, plist
);
6675 DEFUN (ip_pim_spt_switchover_infinity
,
6676 ip_pim_spt_switchover_infinity_cmd
,
6677 "ip pim spt-switchover infinity-and-beyond",
6681 "Never switch to SPT Tree\n")
6683 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6684 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, NULL
);
6687 DEFUN (ip_pim_spt_switchover_infinity_plist
,
6688 ip_pim_spt_switchover_infinity_plist_cmd
,
6689 "ip pim spt-switchover infinity-and-beyond prefix-list WORD",
6693 "Never switch to SPT Tree\n"
6694 "Prefix-List to control which groups to switch\n"
6695 "Prefix-List name\n")
6697 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6698 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, argv
[5]->arg
);
6701 DEFUN (no_ip_pim_spt_switchover_infinity
,
6702 no_ip_pim_spt_switchover_infinity_cmd
,
6703 "no ip pim spt-switchover infinity-and-beyond",
6708 "Never switch to SPT Tree\n")
6710 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6711 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
6714 DEFUN (no_ip_pim_spt_switchover_infinity_plist
,
6715 no_ip_pim_spt_switchover_infinity_plist_cmd
,
6716 "no ip pim spt-switchover infinity-and-beyond prefix-list WORD",
6721 "Never switch to SPT Tree\n"
6722 "Prefix-List to control which groups to switch\n"
6723 "Prefix-List name\n")
6725 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6726 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
6729 DEFPY (pim_register_accept_list
,
6730 pim_register_accept_list_cmd
,
6731 "[no] ip pim register-accept-list WORD$word",
6735 "Only accept registers from a specific source prefix list\n"
6736 "Prefix-List name\n")
6738 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6741 XFREE(MTYPE_PIM_PLIST_NAME
, pim
->register_plist
);
6743 XFREE(MTYPE_PIM_PLIST_NAME
, pim
->register_plist
);
6744 pim
->register_plist
= XSTRDUP(MTYPE_PIM_PLIST_NAME
, word
);
6749 DEFUN (ip_pim_joinprune_time
,
6750 ip_pim_joinprune_time_cmd
,
6751 "ip pim join-prune-interval (60-600)",
6753 "pim multicast routing\n"
6754 "Join Prune Send Interval\n"
6757 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6758 router
->t_periodic
= atoi(argv
[3]->arg
);
6762 DEFUN (no_ip_pim_joinprune_time
,
6763 no_ip_pim_joinprune_time_cmd
,
6764 "no ip pim join-prune-interval (60-600)",
6767 "pim multicast routing\n"
6768 "Join Prune Send Interval\n"
6771 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6772 router
->t_periodic
= PIM_DEFAULT_T_PERIODIC
;
6776 DEFUN (ip_pim_register_suppress
,
6777 ip_pim_register_suppress_cmd
,
6778 "ip pim register-suppress-time (5-60000)",
6780 "pim multicast routing\n"
6781 "Register Suppress Timer\n"
6784 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6785 router
->register_suppress_time
= atoi(argv
[3]->arg
);
6789 DEFUN (no_ip_pim_register_suppress
,
6790 no_ip_pim_register_suppress_cmd
,
6791 "no ip pim register-suppress-time (5-60000)",
6794 "pim multicast routing\n"
6795 "Register Suppress Timer\n"
6798 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6799 router
->register_suppress_time
= PIM_REGISTER_SUPPRESSION_TIME_DEFAULT
;
6803 DEFUN (ip_pim_rp_keep_alive
,
6804 ip_pim_rp_keep_alive_cmd
,
6805 "ip pim rp keep-alive-timer (31-60000)",
6807 "pim multicast routing\n"
6809 "Keep alive Timer\n"
6812 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6813 pim
->rp_keep_alive_time
= atoi(argv
[4]->arg
);
6817 DEFUN (no_ip_pim_rp_keep_alive
,
6818 no_ip_pim_rp_keep_alive_cmd
,
6819 "no ip pim rp keep-alive-timer (31-60000)",
6822 "pim multicast routing\n"
6824 "Keep alive Timer\n"
6827 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6828 pim
->rp_keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
6832 DEFUN (ip_pim_keep_alive
,
6833 ip_pim_keep_alive_cmd
,
6834 "ip pim keep-alive-timer (31-60000)",
6836 "pim multicast routing\n"
6837 "Keep alive Timer\n"
6840 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6841 pim
->keep_alive_time
= atoi(argv
[3]->arg
);
6845 DEFUN (no_ip_pim_keep_alive
,
6846 no_ip_pim_keep_alive_cmd
,
6847 "no ip pim keep-alive-timer (31-60000)",
6850 "pim multicast routing\n"
6851 "Keep alive Timer\n"
6854 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6855 pim
->keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
6859 DEFUN (ip_pim_packets
,
6861 "ip pim packets (1-100)",
6863 "pim multicast routing\n"
6864 "packets to process at one time per fd\n"
6865 "Number of packets\n")
6867 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6868 router
->packet_process
= atoi(argv
[3]->arg
);
6872 DEFUN (no_ip_pim_packets
,
6873 no_ip_pim_packets_cmd
,
6874 "no ip pim packets (1-100)",
6877 "pim multicast routing\n"
6878 "packets to process at one time per fd\n"
6879 "Number of packets\n")
6881 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6882 router
->packet_process
= PIM_DEFAULT_PACKET_PROCESS
;
6886 DEFPY (igmp_group_watermark
,
6887 igmp_group_watermark_cmd
,
6888 "ip igmp watermark-warn (10-60000)$limit",
6891 "Configure group limit for watermark warning\n"
6892 "Group count to generate watermark warning\n")
6894 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6895 pim
->igmp_watermark_limit
= limit
;
6900 DEFPY (no_igmp_group_watermark
,
6901 no_igmp_group_watermark_cmd
,
6902 "no ip igmp watermark-warn [(10-60000)$limit]",
6906 "Unconfigure group limit for watermark warning\n"
6907 "Group count to generate watermark warning\n")
6909 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6910 pim
->igmp_watermark_limit
= 0;
6915 DEFUN (ip_pim_v6_secondary
,
6916 ip_pim_v6_secondary_cmd
,
6917 "ip pim send-v6-secondary",
6919 "pim multicast routing\n"
6920 "Send v6 secondary addresses\n")
6922 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6923 pim
->send_v6_secondary
= 1;
6928 DEFUN (no_ip_pim_v6_secondary
,
6929 no_ip_pim_v6_secondary_cmd
,
6930 "no ip pim send-v6-secondary",
6933 "pim multicast routing\n"
6934 "Send v6 secondary addresses\n")
6936 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6937 pim
->send_v6_secondary
= 0;
6944 "ip pim rp A.B.C.D [A.B.C.D/M]",
6946 "pim multicast routing\n"
6948 "ip address of RP\n"
6949 "Group Address range to cover\n")
6951 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6954 if (argc
== (idx_ipv4
+ 1))
6955 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
6958 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
6959 argv
[idx_ipv4
+ 1]->arg
, NULL
);
6962 DEFUN (ip_pim_rp_prefix_list
,
6963 ip_pim_rp_prefix_list_cmd
,
6964 "ip pim rp A.B.C.D prefix-list WORD",
6966 "pim multicast routing\n"
6968 "ip address of RP\n"
6969 "group prefix-list filter\n"
6970 "Name of a prefix-list\n")
6972 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6973 return pim_rp_cmd_worker(pim
, vty
, argv
[3]->arg
, NULL
, argv
[5]->arg
);
6976 static int pim_no_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
6977 const char *rp
, const char *group
,
6980 int result
= pim_rp_del_config(pim
, rp
, group
, plist
);
6982 if (result
== PIM_GROUP_BAD_ADDRESS
) {
6983 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
6984 return CMD_WARNING_CONFIG_FAILED
;
6987 if (result
== PIM_RP_BAD_ADDRESS
) {
6988 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
6989 return CMD_WARNING_CONFIG_FAILED
;
6992 if (result
== PIM_RP_NOT_FOUND
) {
6993 vty_out(vty
, "%% Unable to find specified RP\n");
6994 return CMD_WARNING_CONFIG_FAILED
;
7000 DEFUN (no_ip_pim_rp
,
7002 "no ip pim rp A.B.C.D [A.B.C.D/M]",
7005 "pim multicast routing\n"
7007 "ip address of RP\n"
7008 "Group Address range to cover\n")
7010 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7011 int idx_ipv4
= 4, idx_group
= 0;
7013 if (argv_find(argv
, argc
, "A.B.C.D/M", &idx_group
))
7014 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
7015 argv
[idx_group
]->arg
, NULL
);
7017 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
7021 DEFUN (no_ip_pim_rp_prefix_list
,
7022 no_ip_pim_rp_prefix_list_cmd
,
7023 "no ip pim rp A.B.C.D prefix-list WORD",
7026 "pim multicast routing\n"
7028 "ip address of RP\n"
7029 "group prefix-list filter\n"
7030 "Name of a prefix-list\n")
7032 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7033 return pim_no_rp_cmd_worker(pim
, vty
, argv
[4]->arg
, NULL
, argv
[6]->arg
);
7036 static int pim_ssm_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
7039 int result
= pim_ssm_range_set(pim
, pim
->vrf_id
, plist
);
7040 int ret
= CMD_WARNING_CONFIG_FAILED
;
7042 if (result
== PIM_SSM_ERR_NONE
)
7046 case PIM_SSM_ERR_NO_VRF
:
7047 vty_out(vty
, "%% VRF doesn't exist\n");
7049 case PIM_SSM_ERR_DUP
:
7050 vty_out(vty
, "%% duplicate config\n");
7054 vty_out(vty
, "%% ssm range config failed\n");
7060 DEFUN (ip_pim_ssm_prefix_list
,
7061 ip_pim_ssm_prefix_list_cmd
,
7062 "ip pim ssm prefix-list WORD",
7064 "pim multicast routing\n"
7065 "Source Specific Multicast\n"
7066 "group range prefix-list filter\n"
7067 "Name of a prefix-list\n")
7069 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7070 return pim_ssm_cmd_worker(pim
, vty
, argv
[4]->arg
);
7073 DEFUN (no_ip_pim_ssm_prefix_list
,
7074 no_ip_pim_ssm_prefix_list_cmd
,
7075 "no ip pim ssm prefix-list",
7078 "pim multicast routing\n"
7079 "Source Specific Multicast\n"
7080 "group range prefix-list filter\n")
7082 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7083 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
7086 DEFUN (no_ip_pim_ssm_prefix_list_name
,
7087 no_ip_pim_ssm_prefix_list_name_cmd
,
7088 "no ip pim ssm prefix-list WORD",
7091 "pim multicast routing\n"
7092 "Source Specific Multicast\n"
7093 "group range prefix-list filter\n"
7094 "Name of a prefix-list\n")
7096 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7097 struct pim_ssm
*ssm
= pim
->ssm_info
;
7099 if (ssm
->plist_name
&& !strcmp(ssm
->plist_name
, argv
[5]->arg
))
7100 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
7102 vty_out(vty
, "%% pim ssm prefix-list %s doesn't exist\n", argv
[5]->arg
);
7104 return CMD_WARNING_CONFIG_FAILED
;
7107 static void ip_pim_ssm_show_group_range(struct pim_instance
*pim
,
7108 struct vty
*vty
, bool uj
)
7110 struct pim_ssm
*ssm
= pim
->ssm_info
;
7111 const char *range_str
=
7112 ssm
->plist_name
? ssm
->plist_name
: PIM_SSM_STANDARD_RANGE
;
7116 json
= json_object_new_object();
7117 json_object_string_add(json
, "ssmGroups", range_str
);
7118 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
7119 json
, JSON_C_TO_STRING_PRETTY
));
7120 json_object_free(json
);
7122 vty_out(vty
, "SSM group range : %s\n", range_str
);
7125 DEFUN (show_ip_pim_ssm_range
,
7126 show_ip_pim_ssm_range_cmd
,
7127 "show ip pim [vrf NAME] group-type [json]",
7136 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
7137 bool uj
= use_json(argc
, argv
);
7142 ip_pim_ssm_show_group_range(vrf
->info
, vty
, uj
);
7147 static void ip_pim_ssm_show_group_type(struct pim_instance
*pim
,
7148 struct vty
*vty
, bool uj
,
7151 struct in_addr group_addr
;
7152 const char *type_str
;
7155 result
= inet_pton(AF_INET
, group
, &group_addr
);
7157 type_str
= "invalid";
7159 if (pim_is_group_224_4(group_addr
))
7161 pim_is_grp_ssm(pim
, group_addr
) ? "SSM" : "ASM";
7163 type_str
= "not-multicast";
7168 json
= json_object_new_object();
7169 json_object_string_add(json
, "groupType", type_str
);
7170 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
7171 json
, JSON_C_TO_STRING_PRETTY
));
7172 json_object_free(json
);
7174 vty_out(vty
, "Group type : %s\n", type_str
);
7177 DEFUN (show_ip_pim_group_type
,
7178 show_ip_pim_group_type_cmd
,
7179 "show ip pim [vrf NAME] group-type A.B.C.D [json]",
7184 "multicast group type\n"
7189 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
7190 bool uj
= use_json(argc
, argv
);
7195 argv_find(argv
, argc
, "A.B.C.D", &idx
);
7196 ip_pim_ssm_show_group_type(vrf
->info
, vty
, uj
, argv
[idx
]->arg
);
7201 DEFUN (show_ip_pim_bsr
,
7202 show_ip_pim_bsr_cmd
,
7203 "show ip pim bsr [json]",
7207 "boot-strap router information\n"
7211 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
7212 bool uj
= use_json(argc
, argv
);
7217 pim_show_bsr(vrf
->info
, vty
, uj
);
7224 "ip ssmpingd [A.B.C.D]",
7229 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7232 struct in_addr source_addr
;
7233 const char *source_str
= (argc
== 3) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
7235 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
7237 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
7238 source_str
, errno
, safe_strerror(errno
));
7239 return CMD_WARNING_CONFIG_FAILED
;
7242 result
= pim_ssmpingd_start(pim
, source_addr
);
7244 vty_out(vty
, "%% Failure starting ssmpingd for source %s: %d\n",
7245 source_str
, result
);
7246 return CMD_WARNING_CONFIG_FAILED
;
7252 DEFUN (no_ip_ssmpingd
,
7254 "no ip ssmpingd [A.B.C.D]",
7260 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7263 struct in_addr source_addr
;
7264 const char *source_str
= (argc
== 4) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
7266 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
7268 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
7269 source_str
, errno
, safe_strerror(errno
));
7270 return CMD_WARNING_CONFIG_FAILED
;
7273 result
= pim_ssmpingd_stop(pim
, source_addr
);
7275 vty_out(vty
, "%% Failure stopping ssmpingd for source %s: %d\n",
7276 source_str
, result
);
7277 return CMD_WARNING_CONFIG_FAILED
;
7287 "pim multicast routing\n"
7288 "Enable PIM ECMP \n")
7290 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7291 pim
->ecmp_enable
= true;
7296 DEFUN (no_ip_pim_ecmp
,
7301 "pim multicast routing\n"
7302 "Disable PIM ECMP \n")
7304 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7305 pim
->ecmp_enable
= false;
7310 DEFUN (ip_pim_ecmp_rebalance
,
7311 ip_pim_ecmp_rebalance_cmd
,
7312 "ip pim ecmp rebalance",
7314 "pim multicast routing\n"
7315 "Enable PIM ECMP \n"
7316 "Enable PIM ECMP Rebalance\n")
7318 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7319 pim
->ecmp_enable
= true;
7320 pim
->ecmp_rebalance_enable
= true;
7325 DEFUN (no_ip_pim_ecmp_rebalance
,
7326 no_ip_pim_ecmp_rebalance_cmd
,
7327 "no ip pim ecmp rebalance",
7330 "pim multicast routing\n"
7331 "Disable PIM ECMP \n"
7332 "Disable PIM ECMP Rebalance\n")
7334 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7335 pim
->ecmp_rebalance_enable
= false;
7340 static int pim_cmd_igmp_start(struct vty
*vty
, struct interface
*ifp
)
7342 struct pim_interface
*pim_ifp
;
7343 struct pim_instance
*pim
;
7344 uint8_t need_startup
= 0;
7346 pim_ifp
= ifp
->info
;
7349 pim
= pim_get_pim_instance(ifp
->vrf_id
);
7350 /* Limit mcast interfaces to number of vifs available */
7351 if (pim
->mcast_if_count
== MAXVIFS
) {
7353 "Max multicast interfaces(%d) Reached. Could not enable IGMP on interface %s\n",
7354 MAXVIFS
, ifp
->name
);
7355 return CMD_WARNING_CONFIG_FAILED
;
7357 (void)pim_if_new(ifp
, true, false, false, false);
7360 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
7361 PIM_IF_DO_IGMP(pim_ifp
->options
);
7366 /* 'ip igmp' executed multiple times, with need_startup
7367 avoid multiple if add all and membership refresh */
7369 pim_if_addr_add_all(ifp
);
7370 pim_if_membership_refresh(ifp
);
7376 DEFUN (interface_ip_igmp
,
7377 interface_ip_igmp_cmd
,
7382 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7384 return pim_cmd_igmp_start(vty
, ifp
);
7387 DEFUN (interface_no_ip_igmp
,
7388 interface_no_ip_igmp_cmd
,
7394 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7395 struct pim_interface
*pim_ifp
= ifp
->info
;
7400 PIM_IF_DONT_IGMP(pim_ifp
->options
);
7402 pim_if_membership_clear(ifp
);
7404 pim_if_addr_del_all_igmp(ifp
);
7406 if (!PIM_IF_TEST_PIM(pim_ifp
->options
)) {
7413 DEFUN (interface_ip_igmp_join
,
7414 interface_ip_igmp_join_cmd
,
7415 "ip igmp join A.B.C.D [A.B.C.D]",
7418 "IGMP join multicast group\n"
7419 "Multicast group address\n"
7422 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7425 const char *group_str
;
7426 const char *source_str
;
7427 struct in_addr group_addr
;
7428 struct in_addr source_addr
;
7432 group_str
= argv
[idx_ipv4
]->arg
;
7433 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
7435 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
7436 errno
, safe_strerror(errno
));
7437 return CMD_WARNING_CONFIG_FAILED
;
7440 /* Source address */
7441 if (argc
== (idx_ipv4_2
+ 1)) {
7442 source_str
= argv
[idx_ipv4_2
]->arg
;
7443 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
7445 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
7446 source_str
, errno
, safe_strerror(errno
));
7447 return CMD_WARNING_CONFIG_FAILED
;
7449 /* Reject 0.0.0.0. Reserved for any source. */
7450 if (source_addr
.s_addr
== INADDR_ANY
) {
7451 vty_out(vty
, "Bad source address %s\n", source_str
);
7452 return CMD_WARNING_CONFIG_FAILED
;
7455 source_addr
.s_addr
= INADDR_ANY
;
7458 CMD_FERR_RETURN(pim_if_igmp_join_add(ifp
, group_addr
, source_addr
),
7459 "Failure joining IGMP group: $ERR");
7464 DEFUN (interface_no_ip_igmp_join
,
7465 interface_no_ip_igmp_join_cmd
,
7466 "no ip igmp join A.B.C.D [A.B.C.D]",
7470 "IGMP join multicast group\n"
7471 "Multicast group address\n"
7474 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7477 const char *group_str
;
7478 const char *source_str
;
7479 struct in_addr group_addr
;
7480 struct in_addr source_addr
;
7484 group_str
= argv
[idx_ipv4
]->arg
;
7485 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
7487 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
7488 errno
, safe_strerror(errno
));
7489 return CMD_WARNING_CONFIG_FAILED
;
7492 /* Source address */
7493 if (argc
== (idx_ipv4_2
+ 1)) {
7494 source_str
= argv
[idx_ipv4_2
]->arg
;
7495 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
7497 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
7498 source_str
, errno
, safe_strerror(errno
));
7499 return CMD_WARNING_CONFIG_FAILED
;
7501 /* Reject 0.0.0.0. Reserved for any source. */
7502 if (source_addr
.s_addr
== INADDR_ANY
) {
7503 vty_out(vty
, "Bad source address %s\n", source_str
);
7504 return CMD_WARNING_CONFIG_FAILED
;
7508 source_addr
.s_addr
= INADDR_ANY
;
7511 result
= pim_if_igmp_join_del(ifp
, group_addr
, source_addr
);
7514 "%% Failure leaving IGMP group %s source %s on interface %s: %d\n",
7515 group_str
, source_str
, ifp
->name
, result
);
7516 return CMD_WARNING_CONFIG_FAILED
;
7523 CLI reconfiguration affects the interface level (struct pim_interface).
7524 This function propagates the reconfiguration to every active socket
7527 static void igmp_sock_query_interval_reconfig(struct igmp_sock
*igmp
)
7529 struct interface
*ifp
;
7530 struct pim_interface
*pim_ifp
;
7534 /* other querier present? */
7536 if (igmp
->t_other_querier_timer
)
7539 /* this is the querier */
7541 zassert(igmp
->interface
);
7542 zassert(igmp
->interface
->info
);
7544 ifp
= igmp
->interface
;
7545 pim_ifp
= ifp
->info
;
7547 if (PIM_DEBUG_IGMP_TRACE
) {
7548 char ifaddr_str
[INET_ADDRSTRLEN
];
7549 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
7550 sizeof(ifaddr_str
));
7551 zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
7552 __func__
, ifaddr_str
, ifp
->name
,
7553 pim_ifp
->igmp_default_query_interval
);
7557 igmp_startup_mode_on() will reset QQI:
7559 igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
7561 igmp_startup_mode_on(igmp
);
7564 static void igmp_sock_query_reschedule(struct igmp_sock
*igmp
)
7566 if (igmp
->mtrace_only
)
7569 if (igmp
->t_igmp_query_timer
) {
7570 /* other querier present */
7571 zassert(igmp
->t_igmp_query_timer
);
7572 zassert(!igmp
->t_other_querier_timer
);
7574 pim_igmp_general_query_off(igmp
);
7575 pim_igmp_general_query_on(igmp
);
7577 zassert(igmp
->t_igmp_query_timer
);
7578 zassert(!igmp
->t_other_querier_timer
);
7580 /* this is the querier */
7582 zassert(!igmp
->t_igmp_query_timer
);
7583 zassert(igmp
->t_other_querier_timer
);
7585 pim_igmp_other_querier_timer_off(igmp
);
7586 pim_igmp_other_querier_timer_on(igmp
);
7588 zassert(!igmp
->t_igmp_query_timer
);
7589 zassert(igmp
->t_other_querier_timer
);
7593 static void change_query_interval(struct pim_interface
*pim_ifp
,
7596 struct listnode
*sock_node
;
7597 struct igmp_sock
*igmp
;
7599 pim_ifp
->igmp_default_query_interval
= query_interval
;
7601 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
7602 igmp_sock_query_interval_reconfig(igmp
);
7603 igmp_sock_query_reschedule(igmp
);
7607 static void change_query_max_response_time(struct pim_interface
*pim_ifp
,
7608 int query_max_response_time_dsec
)
7610 struct listnode
*sock_node
;
7611 struct igmp_sock
*igmp
;
7613 pim_ifp
->igmp_query_max_response_time_dsec
=
7614 query_max_response_time_dsec
;
7617 Below we modify socket/group/source timers in order to quickly
7618 reflect the change. Otherwise, those timers would eventually catch
7622 /* scan all sockets */
7623 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
7624 struct listnode
*grp_node
;
7625 struct igmp_group
*grp
;
7627 /* reschedule socket general query */
7628 igmp_sock_query_reschedule(igmp
);
7630 /* scan socket groups */
7631 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grp_node
,
7633 struct listnode
*src_node
;
7634 struct igmp_source
*src
;
7636 /* reset group timers for groups in EXCLUDE mode */
7637 if (grp
->group_filtermode_isexcl
) {
7638 igmp_group_reset_gmi(grp
);
7641 /* scan group sources */
7642 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
,
7645 /* reset source timers for sources with running
7647 if (src
->t_source_timer
) {
7648 igmp_source_reset_gmi(igmp
, grp
, src
);
7655 #define IGMP_QUERY_INTERVAL_MIN (1)
7656 #define IGMP_QUERY_INTERVAL_MAX (1800)
7658 DEFUN (interface_ip_igmp_query_interval
,
7659 interface_ip_igmp_query_interval_cmd
,
7660 "ip igmp query-interval (1-1800)",
7663 IFACE_IGMP_QUERY_INTERVAL_STR
7664 "Query interval in seconds\n")
7666 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7667 struct pim_interface
*pim_ifp
= ifp
->info
;
7669 int query_interval_dsec
;
7673 ret
= pim_cmd_igmp_start(vty
, ifp
);
7674 if (ret
!= CMD_SUCCESS
)
7676 pim_ifp
= ifp
->info
;
7679 query_interval
= atoi(argv
[3]->arg
);
7680 query_interval_dsec
= 10 * query_interval
;
7683 It seems we don't need to check bounds since command.c does it
7684 already, but we verify them anyway for extra safety.
7686 if (query_interval
< IGMP_QUERY_INTERVAL_MIN
) {
7688 "General query interval %d lower than minimum %d\n",
7689 query_interval
, IGMP_QUERY_INTERVAL_MIN
);
7690 return CMD_WARNING_CONFIG_FAILED
;
7692 if (query_interval
> IGMP_QUERY_INTERVAL_MAX
) {
7694 "General query interval %d higher than maximum %d\n",
7695 query_interval
, IGMP_QUERY_INTERVAL_MAX
);
7696 return CMD_WARNING_CONFIG_FAILED
;
7699 if (query_interval_dsec
<= pim_ifp
->igmp_query_max_response_time_dsec
) {
7701 "Can't set general query interval %d dsec <= query max response time %d dsec.\n",
7702 query_interval_dsec
,
7703 pim_ifp
->igmp_query_max_response_time_dsec
);
7704 return CMD_WARNING_CONFIG_FAILED
;
7707 change_query_interval(pim_ifp
, query_interval
);
7712 DEFUN (interface_no_ip_igmp_query_interval
,
7713 interface_no_ip_igmp_query_interval_cmd
,
7714 "no ip igmp query-interval",
7718 IFACE_IGMP_QUERY_INTERVAL_STR
)
7720 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7721 struct pim_interface
*pim_ifp
= ifp
->info
;
7722 int default_query_interval_dsec
;
7727 default_query_interval_dsec
= IGMP_GENERAL_QUERY_INTERVAL
* 10;
7729 if (default_query_interval_dsec
7730 <= pim_ifp
->igmp_query_max_response_time_dsec
) {
7732 "Can't set default general query interval %d dsec <= query max response time %d dsec.\n",
7733 default_query_interval_dsec
,
7734 pim_ifp
->igmp_query_max_response_time_dsec
);
7735 return CMD_WARNING_CONFIG_FAILED
;
7738 change_query_interval(pim_ifp
, IGMP_GENERAL_QUERY_INTERVAL
);
7743 DEFUN (interface_ip_igmp_version
,
7744 interface_ip_igmp_version_cmd
,
7745 "ip igmp version (2-3)",
7749 "IGMP version number\n")
7751 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7752 struct pim_interface
*pim_ifp
= ifp
->info
;
7753 int igmp_version
, old_version
= 0;
7757 ret
= pim_cmd_igmp_start(vty
, ifp
);
7758 if (ret
!= CMD_SUCCESS
)
7760 pim_ifp
= ifp
->info
;
7763 igmp_version
= atoi(argv
[3]->arg
);
7764 old_version
= pim_ifp
->igmp_version
;
7765 pim_ifp
->igmp_version
= igmp_version
;
7767 // Check if IGMP is Enabled otherwise, enable on interface
7768 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
7769 PIM_IF_DO_IGMP(pim_ifp
->options
);
7770 pim_if_addr_add_all(ifp
);
7771 pim_if_membership_refresh(ifp
);
7772 old_version
= igmp_version
;
7773 // avoid refreshing membership again.
7775 /* Current and new version is different refresh existing
7776 membership. Going from 3 -> 2 or 2 -> 3. */
7777 if (old_version
!= igmp_version
)
7778 pim_if_membership_refresh(ifp
);
7783 DEFUN (interface_no_ip_igmp_version
,
7784 interface_no_ip_igmp_version_cmd
,
7785 "no ip igmp version (2-3)",
7790 "IGMP version number\n")
7792 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7793 struct pim_interface
*pim_ifp
= ifp
->info
;
7798 pim_ifp
->igmp_version
= IGMP_DEFAULT_VERSION
;
7803 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
7804 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
7806 DEFUN (interface_ip_igmp_query_max_response_time
,
7807 interface_ip_igmp_query_max_response_time_cmd
,
7808 "ip igmp query-max-response-time (10-250)",
7811 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
7812 "Query response value in deci-seconds\n")
7814 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7815 struct pim_interface
*pim_ifp
= ifp
->info
;
7816 int query_max_response_time
;
7820 ret
= pim_cmd_igmp_start(vty
, ifp
);
7821 if (ret
!= CMD_SUCCESS
)
7823 pim_ifp
= ifp
->info
;
7826 query_max_response_time
= atoi(argv
[3]->arg
);
7828 if (query_max_response_time
7829 >= pim_ifp
->igmp_default_query_interval
* 10) {
7831 "Can't set query max response time %d sec >= general query interval %d sec\n",
7832 query_max_response_time
,
7833 pim_ifp
->igmp_default_query_interval
);
7834 return CMD_WARNING_CONFIG_FAILED
;
7837 change_query_max_response_time(pim_ifp
, query_max_response_time
);
7842 DEFUN (interface_no_ip_igmp_query_max_response_time
,
7843 interface_no_ip_igmp_query_max_response_time_cmd
,
7844 "no ip igmp query-max-response-time (10-250)",
7848 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
7849 "Time for response in deci-seconds\n")
7851 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7852 struct pim_interface
*pim_ifp
= ifp
->info
;
7857 change_query_max_response_time(pim_ifp
,
7858 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
7863 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
7864 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
7866 DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec
,
7867 interface_ip_igmp_query_max_response_time_dsec_cmd
,
7868 "ip igmp query-max-response-time-dsec (10-250)",
7871 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
7872 "Query response value in deciseconds\n")
7874 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7875 struct pim_interface
*pim_ifp
= ifp
->info
;
7876 int query_max_response_time_dsec
;
7877 int default_query_interval_dsec
;
7881 ret
= pim_cmd_igmp_start(vty
, ifp
);
7882 if (ret
!= CMD_SUCCESS
)
7884 pim_ifp
= ifp
->info
;
7887 query_max_response_time_dsec
= atoi(argv
[4]->arg
);
7889 default_query_interval_dsec
= 10 * pim_ifp
->igmp_default_query_interval
;
7891 if (query_max_response_time_dsec
>= default_query_interval_dsec
) {
7893 "Can't set query max response time %d dsec >= general query interval %d dsec\n",
7894 query_max_response_time_dsec
,
7895 default_query_interval_dsec
);
7896 return CMD_WARNING_CONFIG_FAILED
;
7899 change_query_max_response_time(pim_ifp
, query_max_response_time_dsec
);
7904 DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec
,
7905 interface_no_ip_igmp_query_max_response_time_dsec_cmd
,
7906 "no ip igmp query-max-response-time-dsec",
7910 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
)
7912 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7913 struct pim_interface
*pim_ifp
= ifp
->info
;
7918 change_query_max_response_time(pim_ifp
,
7919 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
7924 #define IGMP_LAST_MEMBER_QUERY_COUNT_MIN (1)
7925 #define IGMP_LAST_MEMBER_QUERY_COUNT_MAX (7)
7927 DEFUN (interface_ip_igmp_last_member_query_count
,
7928 interface_ip_igmp_last_member_query_count_cmd
,
7929 "ip igmp last-member-query-count (1-7)",
7932 IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR
7933 "Last member query count\n")
7935 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7936 struct pim_interface
*pim_ifp
= ifp
->info
;
7937 int last_member_query_count
;
7941 ret
= pim_cmd_igmp_start(vty
, ifp
);
7942 if (ret
!= CMD_SUCCESS
)
7944 pim_ifp
= ifp
->info
;
7947 last_member_query_count
= atoi(argv
[3]->arg
);
7949 pim_ifp
->igmp_last_member_query_count
= last_member_query_count
;
7954 DEFUN (interface_no_ip_igmp_last_member_query_count
,
7955 interface_no_ip_igmp_last_member_query_count_cmd
,
7956 "no ip igmp last-member-query-count",
7960 IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR
)
7962 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7963 struct pim_interface
*pim_ifp
= ifp
->info
;
7968 pim_ifp
->igmp_last_member_query_count
=
7969 IGMP_DEFAULT_ROBUSTNESS_VARIABLE
;
7974 #define IGMP_LAST_MEMBER_QUERY_INTERVAL_MIN (1)
7975 #define IGMP_LAST_MEMBER_QUERY_INTERVAL_MAX (255)
7977 DEFUN (interface_ip_igmp_last_member_query_interval
,
7978 interface_ip_igmp_last_member_query_interval_cmd
,
7979 "ip igmp last-member-query-interval (1-255)",
7982 IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR
7983 "Last member query interval in deciseconds\n")
7985 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7986 struct pim_interface
*pim_ifp
= ifp
->info
;
7987 int last_member_query_interval
;
7991 ret
= pim_cmd_igmp_start(vty
, ifp
);
7992 if (ret
!= CMD_SUCCESS
)
7994 pim_ifp
= ifp
->info
;
7997 last_member_query_interval
= atoi(argv
[3]->arg
);
7998 pim_ifp
->igmp_specific_query_max_response_time_dsec
7999 = last_member_query_interval
;
8004 DEFUN (interface_no_ip_igmp_last_member_query_interval
,
8005 interface_no_ip_igmp_last_member_query_interval_cmd
,
8006 "no ip igmp last-member-query-interval",
8010 IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR
)
8012 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8013 struct pim_interface
*pim_ifp
= ifp
->info
;
8018 pim_ifp
->igmp_specific_query_max_response_time_dsec
=
8019 IGMP_SPECIFIC_QUERY_MAX_RESPONSE_TIME_DSEC
;
8024 DEFUN (interface_ip_pim_drprio
,
8025 interface_ip_pim_drprio_cmd
,
8026 "ip pim drpriority (1-4294967295)",
8029 "Set the Designated Router Election Priority\n"
8030 "Value of the new DR Priority\n")
8032 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8034 struct pim_interface
*pim_ifp
= ifp
->info
;
8035 uint32_t old_dr_prio
;
8038 vty_out(vty
, "Please enable PIM on interface, first\n");
8039 return CMD_WARNING_CONFIG_FAILED
;
8042 old_dr_prio
= pim_ifp
->pim_dr_priority
;
8044 pim_ifp
->pim_dr_priority
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
8046 if (old_dr_prio
!= pim_ifp
->pim_dr_priority
) {
8047 pim_if_dr_election(ifp
);
8048 pim_hello_restart_now(ifp
);
8054 DEFUN (interface_no_ip_pim_drprio
,
8055 interface_no_ip_pim_drprio_cmd
,
8056 "no ip pim drpriority [(1-4294967295)]",
8060 "Revert the Designated Router Priority to default\n"
8061 "Old Value of the Priority\n")
8063 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8064 struct pim_interface
*pim_ifp
= ifp
->info
;
8067 vty_out(vty
, "Pim not enabled on this interface\n");
8068 return CMD_WARNING_CONFIG_FAILED
;
8071 if (pim_ifp
->pim_dr_priority
!= PIM_DEFAULT_DR_PRIORITY
) {
8072 pim_ifp
->pim_dr_priority
= PIM_DEFAULT_DR_PRIORITY
;
8073 pim_if_dr_election(ifp
);
8074 pim_hello_restart_now(ifp
);
8080 DEFPY_HIDDEN (interface_ip_igmp_query_generate
,
8081 interface_ip_igmp_query_generate_cmd
,
8082 "ip igmp generate-query-once [version (2-3)]",
8085 "Generate igmp general query once\n"
8087 "IGMP version number\n")
8089 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8090 int igmp_version
= 2;
8093 vty_out(vty
, "IGMP/PIM is not enabled on the interface %s\n",
8095 return CMD_WARNING_CONFIG_FAILED
;
8099 igmp_version
= atoi(argv
[4]->arg
);
8101 igmp_send_query_on_intf(ifp
, igmp_version
);
8106 static int pim_cmd_interface_add(struct vty
*vty
, struct interface
*ifp
)
8108 struct pim_interface
*pim_ifp
= ifp
->info
;
8109 struct pim_instance
*pim
;
8112 pim
= pim_get_pim_instance(ifp
->vrf_id
);
8113 /* Limiting mcast interfaces to number of VIFs */
8114 if (pim
->mcast_if_count
== MAXVIFS
) {
8115 vty_out(vty
, "Max multicast interfaces(%d) reached.",
8119 pim_ifp
= pim_if_new(ifp
, false, true, false, false);
8121 PIM_IF_DO_PIM(pim_ifp
->options
);
8123 pim_if_addr_add_all(ifp
);
8124 pim_if_membership_refresh(ifp
);
8126 pim_if_create_pimreg(pim_ifp
->pim
);
8130 DEFPY_HIDDEN (pim_test_sg_keepalive
,
8131 pim_test_sg_keepalive_cmd
,
8132 "test pim [vrf NAME$name] keepalive-reset A.B.C.D$source A.B.C.D$group",
8136 "Reset the Keepalive Timer\n"
8137 "The Source we are resetting\n"
8138 "The Group we are resetting\n")
8140 struct pim_upstream
*up
;
8141 struct pim_instance
*pim
;
8142 struct prefix_sg sg
;
8148 pim
= pim_get_pim_instance(VRF_DEFAULT
);
8150 struct vrf
*vrf
= vrf_lookup_by_name(name
);
8153 vty_out(vty
, "%% Vrf specified: %s does not exist\n",
8158 pim
= pim_get_pim_instance(vrf
->vrf_id
);
8162 vty_out(vty
, "%% Unable to find pim instance\n");
8166 up
= pim_upstream_find(pim
, &sg
);
8168 vty_out(vty
, "%% Unable to find %s specified\n",
8169 pim_str_sg_dump(&sg
));
8173 vty_out(vty
, "Setting %s to current keep alive time: %d\n",
8174 pim_str_sg_dump(&sg
), pim
->keep_alive_time
);
8175 pim_upstream_keep_alive_timer_start(up
, pim
->keep_alive_time
);
8180 DEFPY (interface_ip_pim_activeactive
,
8181 interface_ip_pim_activeactive_cmd
,
8182 "[no$no] ip pim active-active",
8186 "Mark interface as Active-Active for MLAG operations, Hidden because not finished yet\n")
8188 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8189 struct pim_interface
*pim_ifp
;
8191 if (!no
&& !pim_cmd_interface_add(vty
, ifp
)) {
8193 "Could not enable PIM SM active-active on interface %s\n",
8195 return CMD_WARNING_CONFIG_FAILED
;
8200 zlog_debug("%sConfiguring PIM active-active on Interface: %s",
8201 no
? "Un-" : " ", ifp
->name
);
8203 pim_ifp
= ifp
->info
;
8205 pim_if_unconfigure_mlag_dualactive(pim_ifp
);
8207 pim_if_configure_mlag_dualactive(pim_ifp
);
8212 DEFUN_HIDDEN (interface_ip_pim_ssm
,
8213 interface_ip_pim_ssm_cmd
,
8219 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8221 if (!pim_cmd_interface_add(vty
, ifp
)) {
8222 vty_out(vty
, "Could not enable PIM SM on interface %s\n",
8224 return CMD_WARNING_CONFIG_FAILED
;
8228 "WARN: Enabled PIM SM on interface; configure PIM SSM "
8229 "range if needed\n");
8233 static int interface_ip_pim_helper(struct vty
*vty
)
8235 struct pim_interface
*pim_ifp
;
8237 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8239 if (!pim_cmd_interface_add(vty
, ifp
)) {
8240 vty_out(vty
, "Could not enable PIM SM on interface %s\n",
8242 return CMD_WARNING_CONFIG_FAILED
;
8245 pim_ifp
= ifp
->info
;
8247 pim_if_create_pimreg(pim_ifp
->pim
);
8252 DEFUN_HIDDEN (interface_ip_pim_sm
,
8253 interface_ip_pim_sm_cmd
,
8259 return interface_ip_pim_helper(vty
);
8262 DEFUN (interface_ip_pim
,
8263 interface_ip_pim_cmd
,
8268 return interface_ip_pim_helper(vty
);
8271 static int pim_cmd_interface_delete(struct interface
*ifp
)
8273 struct pim_interface
*pim_ifp
= ifp
->info
;
8278 PIM_IF_DONT_PIM(pim_ifp
->options
);
8280 pim_if_membership_clear(ifp
);
8283 pim_sock_delete() removes all neighbors from
8284 pim_ifp->pim_neighbor_list.
8286 pim_sock_delete(ifp
, "pim unconfigured on interface");
8288 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
8289 pim_if_addr_del_all(ifp
);
8296 static int interface_no_ip_pim_helper(struct vty
*vty
)
8298 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8299 if (!pim_cmd_interface_delete(ifp
)) {
8300 vty_out(vty
, "Unable to delete interface information\n");
8301 return CMD_WARNING_CONFIG_FAILED
;
8307 DEFUN_HIDDEN (interface_no_ip_pim_ssm
,
8308 interface_no_ip_pim_ssm_cmd
,
8315 return interface_no_ip_pim_helper(vty
);
8318 DEFUN_HIDDEN (interface_no_ip_pim_sm
,
8319 interface_no_ip_pim_sm_cmd
,
8326 return interface_no_ip_pim_helper(vty
);
8329 DEFUN (interface_no_ip_pim
,
8330 interface_no_ip_pim_cmd
,
8336 return interface_no_ip_pim_helper(vty
);
8340 DEFUN(interface_ip_pim_boundary_oil
,
8341 interface_ip_pim_boundary_oil_cmd
,
8342 "ip multicast boundary oil WORD",
8344 "Generic multicast configuration options\n"
8345 "Define multicast boundary\n"
8346 "Filter OIL by group using prefix list\n"
8347 "Prefix list to filter OIL with\n")
8349 VTY_DECLVAR_CONTEXT(interface
, iif
);
8350 struct pim_interface
*pim_ifp
;
8353 argv_find(argv
, argc
, "WORD", &idx
);
8355 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
8357 if (pim_ifp
->boundary_oil_plist
)
8358 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
8360 pim_ifp
->boundary_oil_plist
=
8361 XSTRDUP(MTYPE_PIM_INTERFACE
, argv
[idx
]->arg
);
8363 /* Interface will be pruned from OIL on next Join */
8367 DEFUN(interface_no_ip_pim_boundary_oil
,
8368 interface_no_ip_pim_boundary_oil_cmd
,
8369 "no ip multicast boundary oil [WORD]",
8372 "Generic multicast configuration options\n"
8373 "Define multicast boundary\n"
8374 "Filter OIL by group using prefix list\n"
8375 "Prefix list to filter OIL with\n")
8377 VTY_DECLVAR_CONTEXT(interface
, iif
);
8378 struct pim_interface
*pim_ifp
;
8381 argv_find(argv
, argc
, "WORD", &idx
);
8383 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
8385 if (pim_ifp
->boundary_oil_plist
)
8386 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
8391 DEFUN (interface_ip_mroute
,
8392 interface_ip_mroute_cmd
,
8393 "ip mroute INTERFACE A.B.C.D [A.B.C.D]",
8395 "Add multicast route\n"
8396 "Outgoing interface name\n"
8400 VTY_DECLVAR_CONTEXT(interface
, iif
);
8401 struct pim_interface
*pim_ifp
;
8402 struct pim_instance
*pim
;
8403 int idx_interface
= 2;
8405 struct interface
*oif
;
8406 const char *oifname
;
8407 const char *grp_str
;
8408 struct in_addr grp_addr
;
8409 const char *src_str
;
8410 struct in_addr src_addr
;
8413 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
8416 oifname
= argv
[idx_interface
]->arg
;
8417 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
8419 vty_out(vty
, "No such interface name %s\n", oifname
);
8423 grp_str
= argv
[idx_ipv4
]->arg
;
8424 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
8426 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
8427 errno
, safe_strerror(errno
));
8431 if (argc
== (idx_ipv4
+ 1)) {
8432 src_addr
.s_addr
= INADDR_ANY
;
8435 src_str
= argv
[idx_ipv4
+ 1]->arg
;
8436 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
8438 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
8439 errno
, safe_strerror(errno
));
8444 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
8445 vty_out(vty
, "Failed to add static mroute\n");
8452 DEFUN (interface_no_ip_mroute
,
8453 interface_no_ip_mroute_cmd
,
8454 "no ip mroute INTERFACE A.B.C.D [A.B.C.D]",
8457 "Add multicast route\n"
8458 "Outgoing interface name\n"
8462 VTY_DECLVAR_CONTEXT(interface
, iif
);
8463 struct pim_interface
*pim_ifp
;
8464 struct pim_instance
*pim
;
8465 int idx_interface
= 3;
8467 struct interface
*oif
;
8468 const char *oifname
;
8469 const char *grp_str
;
8470 struct in_addr grp_addr
;
8471 const char *src_str
;
8472 struct in_addr src_addr
;
8475 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
8478 oifname
= argv
[idx_interface
]->arg
;
8479 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
8481 vty_out(vty
, "No such interface name %s\n", oifname
);
8485 grp_str
= argv
[idx_ipv4
]->arg
;
8486 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
8488 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
8489 errno
, safe_strerror(errno
));
8493 if (argc
== (idx_ipv4
+ 1)) {
8494 src_addr
.s_addr
= INADDR_ANY
;
8497 src_str
= argv
[idx_ipv4
+ 1]->arg
;
8498 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
8500 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
8501 errno
, safe_strerror(errno
));
8506 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
8507 vty_out(vty
, "Failed to remove static mroute\n");
8514 DEFUN (interface_ip_pim_hello
,
8515 interface_ip_pim_hello_cmd
,
8516 "ip pim hello (1-180) [(1-180)]",
8520 IFACE_PIM_HELLO_TIME_STR
8521 IFACE_PIM_HELLO_HOLD_STR
)
8523 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8526 struct pim_interface
*pim_ifp
= ifp
->info
;
8529 if (!pim_cmd_interface_add(vty
, ifp
)) {
8531 "Could not enable PIM SM on interface %s\n",
8533 return CMD_WARNING_CONFIG_FAILED
;
8537 pim_ifp
= ifp
->info
;
8538 pim_ifp
->pim_hello_period
= strtol(argv
[idx_time
]->arg
, NULL
, 10);
8540 if (argc
== idx_hold
+ 1)
8541 pim_ifp
->pim_default_holdtime
=
8542 strtol(argv
[idx_hold
]->arg
, NULL
, 10);
8547 DEFUN (interface_no_ip_pim_hello
,
8548 interface_no_ip_pim_hello_cmd
,
8549 "no ip pim hello [(1-180) (1-180)]",
8554 IFACE_PIM_HELLO_TIME_STR
8555 IFACE_PIM_HELLO_HOLD_STR
)
8557 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8558 struct pim_interface
*pim_ifp
= ifp
->info
;
8561 vty_out(vty
, "Pim not enabled on this interface\n");
8562 return CMD_WARNING_CONFIG_FAILED
;
8565 pim_ifp
->pim_hello_period
= PIM_DEFAULT_HELLO_PERIOD
;
8566 pim_ifp
->pim_default_holdtime
= -1;
8577 PIM_DO_DEBUG_IGMP_EVENTS
;
8578 PIM_DO_DEBUG_IGMP_PACKETS
;
8579 PIM_DO_DEBUG_IGMP_TRACE
;
8583 DEFUN (no_debug_igmp
,
8590 PIM_DONT_DEBUG_IGMP_EVENTS
;
8591 PIM_DONT_DEBUG_IGMP_PACKETS
;
8592 PIM_DONT_DEBUG_IGMP_TRACE
;
8597 DEFUN (debug_igmp_events
,
8598 debug_igmp_events_cmd
,
8599 "debug igmp events",
8602 DEBUG_IGMP_EVENTS_STR
)
8604 PIM_DO_DEBUG_IGMP_EVENTS
;
8608 DEFUN (no_debug_igmp_events
,
8609 no_debug_igmp_events_cmd
,
8610 "no debug igmp events",
8614 DEBUG_IGMP_EVENTS_STR
)
8616 PIM_DONT_DEBUG_IGMP_EVENTS
;
8621 DEFUN (debug_igmp_packets
,
8622 debug_igmp_packets_cmd
,
8623 "debug igmp packets",
8626 DEBUG_IGMP_PACKETS_STR
)
8628 PIM_DO_DEBUG_IGMP_PACKETS
;
8632 DEFUN (no_debug_igmp_packets
,
8633 no_debug_igmp_packets_cmd
,
8634 "no debug igmp packets",
8638 DEBUG_IGMP_PACKETS_STR
)
8640 PIM_DONT_DEBUG_IGMP_PACKETS
;
8645 DEFUN (debug_igmp_trace
,
8646 debug_igmp_trace_cmd
,
8650 DEBUG_IGMP_TRACE_STR
)
8652 PIM_DO_DEBUG_IGMP_TRACE
;
8656 DEFUN (no_debug_igmp_trace
,
8657 no_debug_igmp_trace_cmd
,
8658 "no debug igmp trace",
8662 DEBUG_IGMP_TRACE_STR
)
8664 PIM_DONT_DEBUG_IGMP_TRACE
;
8669 DEFUN (debug_mroute
,
8675 PIM_DO_DEBUG_MROUTE
;
8679 DEFUN (debug_mroute_detail
,
8680 debug_mroute_detail_cmd
,
8681 "debug mroute detail",
8686 PIM_DO_DEBUG_MROUTE_DETAIL
;
8690 DEFUN (no_debug_mroute
,
8691 no_debug_mroute_cmd
,
8697 PIM_DONT_DEBUG_MROUTE
;
8701 DEFUN (no_debug_mroute_detail
,
8702 no_debug_mroute_detail_cmd
,
8703 "no debug mroute detail",
8709 PIM_DONT_DEBUG_MROUTE_DETAIL
;
8713 DEFUN (debug_pim_static
,
8714 debug_pim_static_cmd
,
8720 PIM_DO_DEBUG_STATIC
;
8724 DEFUN (no_debug_pim_static
,
8725 no_debug_pim_static_cmd
,
8726 "no debug pim static",
8732 PIM_DONT_DEBUG_STATIC
;
8743 PIM_DO_DEBUG_PIM_EVENTS
;
8744 PIM_DO_DEBUG_PIM_PACKETS
;
8745 PIM_DO_DEBUG_PIM_TRACE
;
8746 PIM_DO_DEBUG_MSDP_EVENTS
;
8747 PIM_DO_DEBUG_MSDP_PACKETS
;
8752 DEFUN (no_debug_pim
,
8759 PIM_DONT_DEBUG_PIM_EVENTS
;
8760 PIM_DONT_DEBUG_PIM_PACKETS
;
8761 PIM_DONT_DEBUG_PIM_TRACE
;
8762 PIM_DONT_DEBUG_MSDP_EVENTS
;
8763 PIM_DONT_DEBUG_MSDP_PACKETS
;
8765 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
8766 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
8772 DEFUN (debug_pim_nht
,
8777 "Nexthop Tracking\n")
8779 PIM_DO_DEBUG_PIM_NHT
;
8783 DEFUN (no_debug_pim_nht
,
8784 no_debug_pim_nht_cmd
,
8789 "Nexthop Tracking\n")
8791 PIM_DONT_DEBUG_PIM_NHT
;
8795 DEFUN (debug_pim_nht_rp
,
8796 debug_pim_nht_rp_cmd
,
8800 "Nexthop Tracking\n"
8801 "RP Nexthop Tracking\n")
8803 PIM_DO_DEBUG_PIM_NHT_RP
;
8807 DEFUN (no_debug_pim_nht_rp
,
8808 no_debug_pim_nht_rp_cmd
,
8809 "no debug pim nht rp",
8813 "Nexthop Tracking\n"
8814 "RP Nexthop Tracking\n")
8816 PIM_DONT_DEBUG_PIM_NHT_RP
;
8820 DEFUN (debug_pim_events
,
8821 debug_pim_events_cmd
,
8825 DEBUG_PIM_EVENTS_STR
)
8827 PIM_DO_DEBUG_PIM_EVENTS
;
8831 DEFUN (no_debug_pim_events
,
8832 no_debug_pim_events_cmd
,
8833 "no debug pim events",
8837 DEBUG_PIM_EVENTS_STR
)
8839 PIM_DONT_DEBUG_PIM_EVENTS
;
8843 DEFUN (debug_pim_packets
,
8844 debug_pim_packets_cmd
,
8845 "debug pim packets [<hello|joins|register>]",
8848 DEBUG_PIM_PACKETS_STR
8849 DEBUG_PIM_HELLO_PACKETS_STR
8850 DEBUG_PIM_J_P_PACKETS_STR
8851 DEBUG_PIM_PIM_REG_PACKETS_STR
)
8854 if (argv_find(argv
, argc
, "hello", &idx
)) {
8855 PIM_DO_DEBUG_PIM_HELLO
;
8856 vty_out(vty
, "PIM Hello debugging is on\n");
8857 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
8858 PIM_DO_DEBUG_PIM_J_P
;
8859 vty_out(vty
, "PIM Join/Prune debugging is on\n");
8860 } else if (argv_find(argv
, argc
, "register", &idx
)) {
8861 PIM_DO_DEBUG_PIM_REG
;
8862 vty_out(vty
, "PIM Register debugging is on\n");
8864 PIM_DO_DEBUG_PIM_PACKETS
;
8865 vty_out(vty
, "PIM Packet debugging is on \n");
8870 DEFUN (no_debug_pim_packets
,
8871 no_debug_pim_packets_cmd
,
8872 "no debug pim packets [<hello|joins|register>]",
8876 DEBUG_PIM_PACKETS_STR
8877 DEBUG_PIM_HELLO_PACKETS_STR
8878 DEBUG_PIM_J_P_PACKETS_STR
8879 DEBUG_PIM_PIM_REG_PACKETS_STR
)
8882 if (argv_find(argv
, argc
, "hello", &idx
)) {
8883 PIM_DONT_DEBUG_PIM_HELLO
;
8884 vty_out(vty
, "PIM Hello debugging is off \n");
8885 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
8886 PIM_DONT_DEBUG_PIM_J_P
;
8887 vty_out(vty
, "PIM Join/Prune debugging is off \n");
8888 } else if (argv_find(argv
, argc
, "register", &idx
)) {
8889 PIM_DONT_DEBUG_PIM_REG
;
8890 vty_out(vty
, "PIM Register debugging is off\n");
8892 PIM_DONT_DEBUG_PIM_PACKETS
;
8898 DEFUN (debug_pim_packetdump_send
,
8899 debug_pim_packetdump_send_cmd
,
8900 "debug pim packet-dump send",
8903 DEBUG_PIM_PACKETDUMP_STR
8904 DEBUG_PIM_PACKETDUMP_SEND_STR
)
8906 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND
;
8910 DEFUN (no_debug_pim_packetdump_send
,
8911 no_debug_pim_packetdump_send_cmd
,
8912 "no debug pim packet-dump send",
8916 DEBUG_PIM_PACKETDUMP_STR
8917 DEBUG_PIM_PACKETDUMP_SEND_STR
)
8919 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
8923 DEFUN (debug_pim_packetdump_recv
,
8924 debug_pim_packetdump_recv_cmd
,
8925 "debug pim packet-dump receive",
8928 DEBUG_PIM_PACKETDUMP_STR
8929 DEBUG_PIM_PACKETDUMP_RECV_STR
)
8931 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV
;
8935 DEFUN (no_debug_pim_packetdump_recv
,
8936 no_debug_pim_packetdump_recv_cmd
,
8937 "no debug pim packet-dump receive",
8941 DEBUG_PIM_PACKETDUMP_STR
8942 DEBUG_PIM_PACKETDUMP_RECV_STR
)
8944 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
8948 DEFUN (debug_pim_trace
,
8949 debug_pim_trace_cmd
,
8953 DEBUG_PIM_TRACE_STR
)
8955 PIM_DO_DEBUG_PIM_TRACE
;
8959 DEFUN (debug_pim_trace_detail
,
8960 debug_pim_trace_detail_cmd
,
8961 "debug pim trace detail",
8965 "Detailed Information\n")
8967 PIM_DO_DEBUG_PIM_TRACE_DETAIL
;
8971 DEFUN (no_debug_pim_trace
,
8972 no_debug_pim_trace_cmd
,
8973 "no debug pim trace",
8977 DEBUG_PIM_TRACE_STR
)
8979 PIM_DONT_DEBUG_PIM_TRACE
;
8983 DEFUN (no_debug_pim_trace_detail
,
8984 no_debug_pim_trace_detail_cmd
,
8985 "no debug pim trace detail",
8990 "Detailed Information\n")
8992 PIM_DONT_DEBUG_PIM_TRACE_DETAIL
;
8996 DEFUN (debug_ssmpingd
,
9002 PIM_DO_DEBUG_SSMPINGD
;
9006 DEFUN (no_debug_ssmpingd
,
9007 no_debug_ssmpingd_cmd
,
9008 "no debug ssmpingd",
9013 PIM_DONT_DEBUG_SSMPINGD
;
9017 DEFUN (debug_pim_zebra
,
9018 debug_pim_zebra_cmd
,
9022 DEBUG_PIM_ZEBRA_STR
)
9028 DEFUN (no_debug_pim_zebra
,
9029 no_debug_pim_zebra_cmd
,
9030 "no debug pim zebra",
9034 DEBUG_PIM_ZEBRA_STR
)
9036 PIM_DONT_DEBUG_ZEBRA
;
9040 DEFUN(debug_pim_mlag
, debug_pim_mlag_cmd
, "debug pim mlag",
9041 DEBUG_STR DEBUG_PIM_STR DEBUG_PIM_MLAG_STR
)
9047 DEFUN(no_debug_pim_mlag
, no_debug_pim_mlag_cmd
, "no debug pim mlag",
9048 NO_STR DEBUG_STR DEBUG_PIM_STR DEBUG_PIM_MLAG_STR
)
9050 PIM_DONT_DEBUG_MLAG
;
9054 DEFUN (debug_pim_vxlan
,
9055 debug_pim_vxlan_cmd
,
9059 DEBUG_PIM_VXLAN_STR
)
9065 DEFUN (no_debug_pim_vxlan
,
9066 no_debug_pim_vxlan_cmd
,
9067 "no debug pim vxlan",
9071 DEBUG_PIM_VXLAN_STR
)
9073 PIM_DONT_DEBUG_VXLAN
;
9083 PIM_DO_DEBUG_MSDP_EVENTS
;
9084 PIM_DO_DEBUG_MSDP_PACKETS
;
9088 DEFUN (no_debug_msdp
,
9095 PIM_DONT_DEBUG_MSDP_EVENTS
;
9096 PIM_DONT_DEBUG_MSDP_PACKETS
;
9100 DEFUN (debug_msdp_events
,
9101 debug_msdp_events_cmd
,
9102 "debug msdp events",
9105 DEBUG_MSDP_EVENTS_STR
)
9107 PIM_DO_DEBUG_MSDP_EVENTS
;
9111 DEFUN (no_debug_msdp_events
,
9112 no_debug_msdp_events_cmd
,
9113 "no debug msdp events",
9117 DEBUG_MSDP_EVENTS_STR
)
9119 PIM_DONT_DEBUG_MSDP_EVENTS
;
9123 DEFUN (debug_msdp_packets
,
9124 debug_msdp_packets_cmd
,
9125 "debug msdp packets",
9128 DEBUG_MSDP_PACKETS_STR
)
9130 PIM_DO_DEBUG_MSDP_PACKETS
;
9134 DEFUN (no_debug_msdp_packets
,
9135 no_debug_msdp_packets_cmd
,
9136 "no debug msdp packets",
9140 DEBUG_MSDP_PACKETS_STR
)
9142 PIM_DONT_DEBUG_MSDP_PACKETS
;
9146 DEFUN (debug_mtrace
,
9152 PIM_DO_DEBUG_MTRACE
;
9156 DEFUN (no_debug_mtrace
,
9157 no_debug_mtrace_cmd
,
9163 PIM_DONT_DEBUG_MTRACE
;
9178 DEFUN (no_debug_bsm
,
9191 DEFUN_NOSH (show_debugging_pim
,
9192 show_debugging_pim_cmd
,
9193 "show debugging [pim]",
9198 vty_out(vty
, "PIM debugging status\n");
9200 pim_debug_config_write(vty
);
9205 static int interface_pim_use_src_cmd_worker(struct vty
*vty
, const char *source
)
9208 struct in_addr source_addr
;
9209 int ret
= CMD_SUCCESS
;
9210 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9212 result
= inet_pton(AF_INET
, source
, &source_addr
);
9214 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", source
,
9215 errno
, safe_strerror(errno
));
9216 return CMD_WARNING_CONFIG_FAILED
;
9219 result
= pim_update_source_set(ifp
, source_addr
);
9223 case PIM_IFACE_NOT_FOUND
:
9224 ret
= CMD_WARNING_CONFIG_FAILED
;
9225 vty_out(vty
, "Pim not enabled on this interface\n");
9227 case PIM_UPDATE_SOURCE_DUP
:
9229 vty_out(vty
, "%% Source already set to %s\n", source
);
9232 ret
= CMD_WARNING_CONFIG_FAILED
;
9233 vty_out(vty
, "%% Source set failed\n");
9239 DEFUN (interface_pim_use_source
,
9240 interface_pim_use_source_cmd
,
9241 "ip pim use-source A.B.C.D",
9244 "Configure primary IP address\n"
9245 "source ip address\n")
9247 return interface_pim_use_src_cmd_worker(vty
, argv
[3]->arg
);
9250 DEFUN (interface_no_pim_use_source
,
9251 interface_no_pim_use_source_cmd
,
9252 "no ip pim use-source [A.B.C.D]",
9256 "Delete source IP address\n"
9257 "source ip address\n")
9259 return interface_pim_use_src_cmd_worker(vty
, "0.0.0.0");
9267 "Enables BFD support\n")
9269 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9270 struct pim_interface
*pim_ifp
= ifp
->info
;
9271 struct bfd_info
*bfd_info
= NULL
;
9274 if (!pim_cmd_interface_add(vty
, ifp
)) {
9276 "Could not enable PIM SM on interface %s\n",
9281 pim_ifp
= ifp
->info
;
9283 bfd_info
= pim_ifp
->bfd_info
;
9285 if (!bfd_info
|| !CHECK_FLAG(bfd_info
->flags
, BFD_FLAG_PARAM_CFG
))
9286 pim_bfd_if_param_set(ifp
, BFD_DEF_MIN_RX
, BFD_DEF_MIN_TX
,
9287 BFD_DEF_DETECT_MULT
, 1);
9292 DEFUN (no_ip_pim_bfd
,
9298 "Disables BFD support\n")
9300 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9301 struct pim_interface
*pim_ifp
= ifp
->info
;
9304 vty_out(vty
, "Pim not enabled on this interface\n");
9308 if (pim_ifp
->bfd_info
) {
9309 pim_bfd_reg_dereg_all_nbr(ifp
, ZEBRA_BFD_DEST_DEREGISTER
);
9310 bfd_info_free(&(pim_ifp
->bfd_info
));
9321 "Enables BSM support on the interface\n")
9323 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9324 struct pim_interface
*pim_ifp
= ifp
->info
;
9327 if (!pim_cmd_interface_add(vty
, ifp
)) {
9329 "Could not enable PIM SM on interface %s\n",
9335 pim_ifp
= ifp
->info
;
9336 pim_ifp
->bsm_enable
= true;
9341 DEFUN (no_ip_pim_bsm
,
9347 "Disables BSM support\n")
9349 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9350 struct pim_interface
*pim_ifp
= ifp
->info
;
9353 vty_out(vty
, "Pim not enabled on this interface\n");
9357 pim_ifp
->bsm_enable
= false;
9362 DEFUN (ip_pim_ucast_bsm
,
9363 ip_pim_ucast_bsm_cmd
,
9364 "ip pim unicast-bsm",
9367 "Accept/Send unicast BSM on the interface\n")
9369 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9370 struct pim_interface
*pim_ifp
= ifp
->info
;
9373 if (!pim_cmd_interface_add(vty
, ifp
)) {
9375 "Could not enable PIM SM on interface %s\n",
9381 pim_ifp
= ifp
->info
;
9382 pim_ifp
->ucast_bsm_accept
= true;
9387 DEFUN (no_ip_pim_ucast_bsm
,
9388 no_ip_pim_ucast_bsm_cmd
,
9389 "no ip pim unicast-bsm",
9393 "Block send/receive unicast BSM on this interface\n")
9395 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9396 struct pim_interface
*pim_ifp
= ifp
->info
;
9399 vty_out(vty
, "Pim not enabled on this interface\n");
9403 pim_ifp
->ucast_bsm_accept
= false;
9411 ip_pim_bfd_param_cmd
,
9412 "ip pim bfd (2-255) (50-60000) (50-60000)",
9415 "Enables BFD support\n"
9416 "Detect Multiplier\n"
9417 "Required min receive interval\n"
9418 "Desired min transmit interval\n")
9422 ip_pim_bfd_param_cmd
,
9423 "ip pim bfd (2-255) (50-60000) (50-60000)",
9426 "Enables BFD support\n"
9427 "Detect Multiplier\n"
9428 "Required min receive interval\n"
9429 "Desired min transmit interval\n")
9430 #endif /* HAVE_BFDD */
9432 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9434 int idx_number_2
= 4;
9435 int idx_number_3
= 5;
9440 struct pim_interface
*pim_ifp
= ifp
->info
;
9443 if (!pim_cmd_interface_add(vty
, ifp
)) {
9445 "Could not enable PIM SM on interface %s\n",
9451 if ((ret
= bfd_validate_param(
9452 vty
, argv
[idx_number
]->arg
, argv
[idx_number_2
]->arg
,
9453 argv
[idx_number_3
]->arg
, &dm_val
, &rx_val
, &tx_val
))
9457 pim_bfd_if_param_set(ifp
, rx_val
, tx_val
, dm_val
, 0);
9463 ALIAS(no_ip_pim_bfd
, no_ip_pim_bfd_param_cmd
,
9464 "no ip pim bfd (2-255) (50-60000) (50-60000)", NO_STR IP_STR PIM_STR
9465 "Enables BFD support\n"
9466 "Detect Multiplier\n"
9467 "Required min receive interval\n"
9468 "Desired min transmit interval\n")
9469 #endif /* !HAVE_BFDD */
9471 static int ip_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
9472 const char *peer
, const char *local
)
9474 enum pim_msdp_err result
;
9475 struct in_addr peer_addr
;
9476 struct in_addr local_addr
;
9477 int ret
= CMD_SUCCESS
;
9479 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
9481 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
9482 errno
, safe_strerror(errno
));
9483 return CMD_WARNING_CONFIG_FAILED
;
9486 result
= inet_pton(AF_INET
, local
, &local_addr
);
9488 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", local
,
9489 errno
, safe_strerror(errno
));
9490 return CMD_WARNING_CONFIG_FAILED
;
9493 result
= pim_msdp_peer_add(pim
, peer_addr
, local_addr
, "default",
9496 case PIM_MSDP_ERR_NONE
:
9498 case PIM_MSDP_ERR_OOM
:
9499 ret
= CMD_WARNING_CONFIG_FAILED
;
9500 vty_out(vty
, "%% Out of memory\n");
9502 case PIM_MSDP_ERR_PEER_EXISTS
:
9504 vty_out(vty
, "%% Peer exists\n");
9506 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
9507 ret
= CMD_WARNING_CONFIG_FAILED
;
9508 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
9511 ret
= CMD_WARNING_CONFIG_FAILED
;
9512 vty_out(vty
, "%% peer add failed\n");
9518 DEFUN_HIDDEN (ip_msdp_peer
,
9520 "ip msdp peer A.B.C.D source A.B.C.D",
9523 "Configure MSDP peer\n"
9525 "Source address for TCP connection\n"
9526 "local ip address\n")
9528 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9529 return ip_msdp_peer_cmd_worker(pim
, vty
, argv
[3]->arg
, argv
[5]->arg
);
9532 static int ip_no_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
9535 enum pim_msdp_err result
;
9536 struct in_addr peer_addr
;
9538 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
9540 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
9541 errno
, safe_strerror(errno
));
9542 return CMD_WARNING_CONFIG_FAILED
;
9545 result
= pim_msdp_peer_del(pim
, peer_addr
);
9547 case PIM_MSDP_ERR_NONE
:
9549 case PIM_MSDP_ERR_NO_PEER
:
9550 vty_out(vty
, "%% Peer does not exist\n");
9553 vty_out(vty
, "%% peer del failed\n");
9556 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9559 DEFUN_HIDDEN (no_ip_msdp_peer
,
9560 no_ip_msdp_peer_cmd
,
9561 "no ip msdp peer A.B.C.D",
9565 "Delete MSDP peer\n"
9566 "peer ip address\n")
9568 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9569 return ip_no_msdp_peer_cmd_worker(pim
, vty
, argv
[4]->arg
);
9572 static int ip_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
9573 struct vty
*vty
, const char *mg
,
9576 enum pim_msdp_err result
;
9577 struct in_addr mbr_ip
;
9578 int ret
= CMD_SUCCESS
;
9580 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
9582 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
9583 errno
, safe_strerror(errno
));
9584 return CMD_WARNING_CONFIG_FAILED
;
9587 result
= pim_msdp_mg_mbr_add(pim
, mg
, mbr_ip
);
9589 case PIM_MSDP_ERR_NONE
:
9591 case PIM_MSDP_ERR_OOM
:
9592 ret
= CMD_WARNING_CONFIG_FAILED
;
9593 vty_out(vty
, "%% Out of memory\n");
9595 case PIM_MSDP_ERR_MG_MBR_EXISTS
:
9597 vty_out(vty
, "%% mesh-group member exists\n");
9599 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
9600 ret
= CMD_WARNING_CONFIG_FAILED
;
9601 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
9604 ret
= CMD_WARNING_CONFIG_FAILED
;
9605 vty_out(vty
, "%% member add failed\n");
9611 DEFUN (ip_msdp_mesh_group_member
,
9612 ip_msdp_mesh_group_member_cmd
,
9613 "ip msdp mesh-group WORD member A.B.C.D",
9616 "Configure MSDP mesh-group\n"
9618 "mesh group member\n"
9619 "peer ip address\n")
9621 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9622 return ip_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[3]->arg
,
9626 static int ip_no_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
9631 enum pim_msdp_err result
;
9632 struct in_addr mbr_ip
;
9634 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
9636 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
9637 errno
, safe_strerror(errno
));
9638 return CMD_WARNING_CONFIG_FAILED
;
9641 result
= pim_msdp_mg_mbr_del(pim
, mg
, mbr_ip
);
9643 case PIM_MSDP_ERR_NONE
:
9645 case PIM_MSDP_ERR_NO_MG
:
9646 vty_out(vty
, "%% mesh-group does not exist\n");
9648 case PIM_MSDP_ERR_NO_MG_MBR
:
9649 vty_out(vty
, "%% mesh-group member does not exist\n");
9652 vty_out(vty
, "%% mesh-group member del failed\n");
9655 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9657 DEFUN (no_ip_msdp_mesh_group_member
,
9658 no_ip_msdp_mesh_group_member_cmd
,
9659 "no ip msdp mesh-group WORD member A.B.C.D",
9663 "Delete MSDP mesh-group member\n"
9665 "mesh group member\n"
9666 "peer ip address\n")
9668 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9669 return ip_no_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[4]->arg
,
9673 static int ip_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
9674 struct vty
*vty
, const char *mg
,
9677 enum pim_msdp_err result
;
9678 struct in_addr src_ip
;
9680 result
= inet_pton(AF_INET
, src
, &src_ip
);
9682 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", src
,
9683 errno
, safe_strerror(errno
));
9684 return CMD_WARNING_CONFIG_FAILED
;
9687 result
= pim_msdp_mg_src_add(pim
, mg
, src_ip
);
9689 case PIM_MSDP_ERR_NONE
:
9691 case PIM_MSDP_ERR_OOM
:
9692 vty_out(vty
, "%% Out of memory\n");
9694 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
9695 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
9698 vty_out(vty
, "%% source add failed\n");
9701 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9705 DEFUN (ip_msdp_mesh_group_source
,
9706 ip_msdp_mesh_group_source_cmd
,
9707 "ip msdp mesh-group WORD source A.B.C.D",
9710 "Configure MSDP mesh-group\n"
9712 "mesh group local address\n"
9713 "source ip address for the TCP connection\n")
9715 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9716 return ip_msdp_mesh_group_source_cmd_worker(pim
, vty
, argv
[3]->arg
,
9720 static int ip_no_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
9724 enum pim_msdp_err result
;
9726 result
= pim_msdp_mg_src_del(pim
, mg
);
9728 case PIM_MSDP_ERR_NONE
:
9730 case PIM_MSDP_ERR_NO_MG
:
9731 vty_out(vty
, "%% mesh-group does not exist\n");
9734 vty_out(vty
, "%% mesh-group source del failed\n");
9737 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9740 static int ip_no_msdp_mesh_group_cmd_worker(struct pim_instance
*pim
,
9741 struct vty
*vty
, const char *mg
)
9743 enum pim_msdp_err result
;
9745 result
= pim_msdp_mg_del(pim
, mg
);
9747 case PIM_MSDP_ERR_NONE
:
9749 case PIM_MSDP_ERR_NO_MG
:
9750 vty_out(vty
, "%% mesh-group does not exist\n");
9753 vty_out(vty
, "%% mesh-group source del failed\n");
9756 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9759 DEFUN (no_ip_msdp_mesh_group_source
,
9760 no_ip_msdp_mesh_group_source_cmd
,
9761 "no ip msdp mesh-group WORD source [A.B.C.D]",
9765 "Delete MSDP mesh-group source\n"
9767 "mesh group source\n"
9768 "mesh group local address\n")
9770 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9772 return ip_no_msdp_mesh_group_source_cmd_worker(pim
, vty
, argv
[4]->arg
);
9775 DEFUN (no_ip_msdp_mesh_group
,
9776 no_ip_msdp_mesh_group_cmd
,
9777 "no ip msdp mesh-group [WORD]",
9781 "Delete MSDP mesh-group\n"
9784 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9787 return ip_no_msdp_mesh_group_cmd_worker(pim
, vty
, argv
[4]->arg
);
9789 return ip_no_msdp_mesh_group_cmd_worker(pim
, vty
, NULL
);
9792 static void print_empty_json_obj(struct vty
*vty
)
9795 json
= json_object_new_object();
9796 vty_out(vty
, "%s\n",
9797 json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
));
9798 json_object_free(json
);
9801 static void ip_msdp_show_mesh_group(struct pim_instance
*pim
, struct vty
*vty
,
9804 struct listnode
*mbrnode
;
9805 struct pim_msdp_mg_mbr
*mbr
;
9806 struct pim_msdp_mg
*mg
= pim
->msdp
.mg
;
9807 char mbr_str
[INET_ADDRSTRLEN
];
9808 char src_str
[INET_ADDRSTRLEN
];
9809 char state_str
[PIM_MSDP_STATE_STRLEN
];
9810 enum pim_msdp_peer_state state
;
9811 json_object
*json
= NULL
;
9812 json_object
*json_mg_row
= NULL
;
9813 json_object
*json_members
= NULL
;
9814 json_object
*json_row
= NULL
;
9818 print_empty_json_obj(vty
);
9822 pim_inet4_dump("<source?>", mg
->src_ip
, src_str
, sizeof(src_str
));
9824 json
= json_object_new_object();
9825 /* currently there is only one mesh group but we should still
9827 * it a dict with mg-name as key */
9828 json_mg_row
= json_object_new_object();
9829 json_object_string_add(json_mg_row
, "name",
9830 mg
->mesh_group_name
);
9831 json_object_string_add(json_mg_row
, "source", src_str
);
9833 vty_out(vty
, "Mesh group : %s\n", mg
->mesh_group_name
);
9834 vty_out(vty
, " Source : %s\n", src_str
);
9835 vty_out(vty
, " Member State\n");
9838 for (ALL_LIST_ELEMENTS_RO(mg
->mbr_list
, mbrnode
, mbr
)) {
9839 pim_inet4_dump("<mbr?>", mbr
->mbr_ip
, mbr_str
, sizeof(mbr_str
));
9841 state
= mbr
->mp
->state
;
9843 state
= PIM_MSDP_DISABLED
;
9845 pim_msdp_state_dump(state
, state_str
, sizeof(state_str
));
9847 json_row
= json_object_new_object();
9848 json_object_string_add(json_row
, "member", mbr_str
);
9849 json_object_string_add(json_row
, "state", state_str
);
9850 if (!json_members
) {
9851 json_members
= json_object_new_object();
9852 json_object_object_add(json_mg_row
, "members",
9855 json_object_object_add(json_members
, mbr_str
, json_row
);
9857 vty_out(vty
, " %-15s %11s\n", mbr_str
, state_str
);
9862 json_object_object_add(json
, mg
->mesh_group_name
, json_mg_row
);
9863 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9864 json
, JSON_C_TO_STRING_PRETTY
));
9865 json_object_free(json
);
9869 DEFUN (show_ip_msdp_mesh_group
,
9870 show_ip_msdp_mesh_group_cmd
,
9871 "show ip msdp [vrf NAME] mesh-group [json]",
9876 "MSDP mesh-group information\n"
9879 bool uj
= use_json(argc
, argv
);
9881 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
9886 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
9891 DEFUN (show_ip_msdp_mesh_group_vrf_all
,
9892 show_ip_msdp_mesh_group_vrf_all_cmd
,
9893 "show ip msdp vrf all mesh-group [json]",
9898 "MSDP mesh-group information\n"
9901 bool uj
= use_json(argc
, argv
);
9907 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
9911 vty_out(vty
, " \"%s\": ", vrf
->name
);
9914 vty_out(vty
, "VRF: %s\n", vrf
->name
);
9915 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
9918 vty_out(vty
, "}\n");
9923 static void ip_msdp_show_peers(struct pim_instance
*pim
, struct vty
*vty
,
9926 struct listnode
*mpnode
;
9927 struct pim_msdp_peer
*mp
;
9928 char peer_str
[INET_ADDRSTRLEN
];
9929 char local_str
[INET_ADDRSTRLEN
];
9930 char state_str
[PIM_MSDP_STATE_STRLEN
];
9931 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
9933 json_object
*json
= NULL
;
9934 json_object
*json_row
= NULL
;
9938 json
= json_object_new_object();
9941 "Peer Local State Uptime SaCnt\n");
9944 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
9945 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
9946 now
= pim_time_monotonic_sec();
9947 pim_time_uptime(timebuf
, sizeof(timebuf
),
9950 strlcpy(timebuf
, "-", sizeof(timebuf
));
9952 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
9953 pim_inet4_dump("<local?>", mp
->local
, local_str
,
9955 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
9957 json_row
= json_object_new_object();
9958 json_object_string_add(json_row
, "peer", peer_str
);
9959 json_object_string_add(json_row
, "local", local_str
);
9960 json_object_string_add(json_row
, "state", state_str
);
9961 json_object_string_add(json_row
, "upTime", timebuf
);
9962 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
9963 json_object_object_add(json
, peer_str
, json_row
);
9965 vty_out(vty
, "%-15s %15s %11s %8s %6d\n", peer_str
,
9966 local_str
, state_str
, timebuf
, mp
->sa_cnt
);
9971 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9972 json
, JSON_C_TO_STRING_PRETTY
));
9973 json_object_free(json
);
9977 static void ip_msdp_show_peers_detail(struct pim_instance
*pim
, struct vty
*vty
,
9978 const char *peer
, bool uj
)
9980 struct listnode
*mpnode
;
9981 struct pim_msdp_peer
*mp
;
9982 char peer_str
[INET_ADDRSTRLEN
];
9983 char local_str
[INET_ADDRSTRLEN
];
9984 char state_str
[PIM_MSDP_STATE_STRLEN
];
9985 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
9986 char katimer
[PIM_MSDP_TIMER_STRLEN
];
9987 char crtimer
[PIM_MSDP_TIMER_STRLEN
];
9988 char holdtimer
[PIM_MSDP_TIMER_STRLEN
];
9990 json_object
*json
= NULL
;
9991 json_object
*json_row
= NULL
;
9994 json
= json_object_new_object();
9997 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
9998 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
9999 if (strcmp(peer
, "detail") && strcmp(peer
, peer_str
))
10002 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
10003 now
= pim_time_monotonic_sec();
10004 pim_time_uptime(timebuf
, sizeof(timebuf
),
10007 strlcpy(timebuf
, "-", sizeof(timebuf
));
10009 pim_inet4_dump("<local?>", mp
->local
, local_str
,
10010 sizeof(local_str
));
10011 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
10012 pim_time_timer_to_hhmmss(katimer
, sizeof(katimer
),
10014 pim_time_timer_to_hhmmss(crtimer
, sizeof(crtimer
),
10016 pim_time_timer_to_hhmmss(holdtimer
, sizeof(holdtimer
),
10020 json_row
= json_object_new_object();
10021 json_object_string_add(json_row
, "peer", peer_str
);
10022 json_object_string_add(json_row
, "local", local_str
);
10023 json_object_string_add(json_row
, "meshGroupName",
10024 mp
->mesh_group_name
);
10025 json_object_string_add(json_row
, "state", state_str
);
10026 json_object_string_add(json_row
, "upTime", timebuf
);
10027 json_object_string_add(json_row
, "keepAliveTimer",
10029 json_object_string_add(json_row
, "connRetryTimer",
10031 json_object_string_add(json_row
, "holdTimer",
10033 json_object_string_add(json_row
, "lastReset",
10035 json_object_int_add(json_row
, "connAttempts",
10036 mp
->conn_attempts
);
10037 json_object_int_add(json_row
, "establishedChanges",
10039 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
10040 json_object_int_add(json_row
, "kaSent", mp
->ka_tx_cnt
);
10041 json_object_int_add(json_row
, "kaRcvd", mp
->ka_rx_cnt
);
10042 json_object_int_add(json_row
, "saSent", mp
->sa_tx_cnt
);
10043 json_object_int_add(json_row
, "saRcvd", mp
->sa_rx_cnt
);
10044 json_object_object_add(json
, peer_str
, json_row
);
10046 vty_out(vty
, "Peer : %s\n", peer_str
);
10047 vty_out(vty
, " Local : %s\n", local_str
);
10048 vty_out(vty
, " Mesh Group : %s\n",
10049 mp
->mesh_group_name
);
10050 vty_out(vty
, " State : %s\n", state_str
);
10051 vty_out(vty
, " Uptime : %s\n", timebuf
);
10053 vty_out(vty
, " Keepalive Timer : %s\n", katimer
);
10054 vty_out(vty
, " Conn Retry Timer : %s\n", crtimer
);
10055 vty_out(vty
, " Hold Timer : %s\n", holdtimer
);
10056 vty_out(vty
, " Last Reset : %s\n",
10058 vty_out(vty
, " Conn Attempts : %d\n",
10059 mp
->conn_attempts
);
10060 vty_out(vty
, " Established Changes : %d\n",
10062 vty_out(vty
, " SA Count : %d\n",
10064 vty_out(vty
, " Statistics :\n");
10067 vty_out(vty
, " Keepalives : %10d %10d\n",
10068 mp
->ka_tx_cnt
, mp
->ka_rx_cnt
);
10069 vty_out(vty
, " SAs : %10d %10d\n",
10070 mp
->sa_tx_cnt
, mp
->sa_rx_cnt
);
10071 vty_out(vty
, "\n");
10076 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10077 json
, JSON_C_TO_STRING_PRETTY
));
10078 json_object_free(json
);
10082 DEFUN (show_ip_msdp_peer_detail
,
10083 show_ip_msdp_peer_detail_cmd
,
10084 "show ip msdp [vrf NAME] peer [detail|A.B.C.D] [json]",
10089 "MSDP peer information\n"
10090 "Detailed output\n"
10091 "peer ip address\n"
10094 bool uj
= use_json(argc
, argv
);
10096 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10099 return CMD_WARNING
;
10103 if (argv_find(argv
, argc
, "detail", &idx
))
10104 arg
= argv
[idx
]->text
;
10105 else if (argv_find(argv
, argc
, "A.B.C.D", &idx
))
10106 arg
= argv
[idx
]->arg
;
10109 ip_msdp_show_peers_detail(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
10111 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
10113 return CMD_SUCCESS
;
10116 DEFUN (show_ip_msdp_peer_detail_vrf_all
,
10117 show_ip_msdp_peer_detail_vrf_all_cmd
,
10118 "show ip msdp vrf all peer [detail|A.B.C.D] [json]",
10123 "MSDP peer information\n"
10124 "Detailed output\n"
10125 "peer ip address\n"
10129 bool uj
= use_json(argc
, argv
);
10134 vty_out(vty
, "{ ");
10135 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
10138 vty_out(vty
, ", ");
10139 vty_out(vty
, " \"%s\": ", vrf
->name
);
10142 vty_out(vty
, "VRF: %s\n", vrf
->name
);
10143 if (argv_find(argv
, argc
, "detail", &idx
)
10144 || argv_find(argv
, argc
, "A.B.C.D", &idx
))
10145 ip_msdp_show_peers_detail(vrf
->info
, vty
,
10146 argv
[idx
]->arg
, uj
);
10148 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
10151 vty_out(vty
, "}\n");
10153 return CMD_SUCCESS
;
10156 static void ip_msdp_show_sa(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
10158 struct listnode
*sanode
;
10159 struct pim_msdp_sa
*sa
;
10160 char src_str
[INET_ADDRSTRLEN
];
10161 char grp_str
[INET_ADDRSTRLEN
];
10162 char rp_str
[INET_ADDRSTRLEN
];
10163 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
10167 json_object
*json
= NULL
;
10168 json_object
*json_group
= NULL
;
10169 json_object
*json_row
= NULL
;
10172 json
= json_object_new_object();
10175 "Source Group RP Local SPT Uptime\n");
10178 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
10179 now
= pim_time_monotonic_sec();
10180 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
10181 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
10182 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
10183 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
10184 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
10186 strlcpy(spt_str
, "yes", sizeof(spt_str
));
10188 strlcpy(spt_str
, "no", sizeof(spt_str
));
10191 strlcpy(rp_str
, "-", sizeof(rp_str
));
10192 strlcpy(spt_str
, "-", sizeof(spt_str
));
10194 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
10195 strlcpy(local_str
, "yes", sizeof(local_str
));
10197 strlcpy(local_str
, "no", sizeof(local_str
));
10200 json_object_object_get_ex(json
, grp_str
, &json_group
);
10203 json_group
= json_object_new_object();
10204 json_object_object_add(json
, grp_str
,
10208 json_row
= json_object_new_object();
10209 json_object_string_add(json_row
, "source", src_str
);
10210 json_object_string_add(json_row
, "group", grp_str
);
10211 json_object_string_add(json_row
, "rp", rp_str
);
10212 json_object_string_add(json_row
, "local", local_str
);
10213 json_object_string_add(json_row
, "sptSetup", spt_str
);
10214 json_object_string_add(json_row
, "upTime", timebuf
);
10215 json_object_object_add(json_group
, src_str
, json_row
);
10217 vty_out(vty
, "%-15s %15s %15s %5c %3c %8s\n",
10218 src_str
, grp_str
, rp_str
, local_str
[0],
10219 spt_str
[0], timebuf
);
10224 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10225 json
, JSON_C_TO_STRING_PRETTY
));
10226 json_object_free(json
);
10230 static void ip_msdp_show_sa_entry_detail(struct pim_msdp_sa
*sa
,
10231 const char *src_str
,
10232 const char *grp_str
, struct vty
*vty
,
10233 bool uj
, json_object
*json
)
10235 char rp_str
[INET_ADDRSTRLEN
];
10236 char peer_str
[INET_ADDRSTRLEN
];
10237 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
10240 char statetimer
[PIM_MSDP_TIMER_STRLEN
];
10242 json_object
*json_group
= NULL
;
10243 json_object
*json_row
= NULL
;
10245 now
= pim_time_monotonic_sec();
10246 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
10247 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
10248 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
10249 pim_inet4_dump("<peer?>", sa
->peer
, peer_str
, sizeof(peer_str
));
10251 strlcpy(spt_str
, "yes", sizeof(spt_str
));
10253 strlcpy(spt_str
, "no", sizeof(spt_str
));
10256 strlcpy(rp_str
, "-", sizeof(rp_str
));
10257 strlcpy(peer_str
, "-", sizeof(peer_str
));
10258 strlcpy(spt_str
, "-", sizeof(spt_str
));
10260 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
10261 strlcpy(local_str
, "yes", sizeof(local_str
));
10263 strlcpy(local_str
, "no", sizeof(local_str
));
10265 pim_time_timer_to_hhmmss(statetimer
, sizeof(statetimer
),
10266 sa
->sa_state_timer
);
10268 json_object_object_get_ex(json
, grp_str
, &json_group
);
10271 json_group
= json_object_new_object();
10272 json_object_object_add(json
, grp_str
, json_group
);
10275 json_row
= json_object_new_object();
10276 json_object_string_add(json_row
, "source", src_str
);
10277 json_object_string_add(json_row
, "group", grp_str
);
10278 json_object_string_add(json_row
, "rp", rp_str
);
10279 json_object_string_add(json_row
, "local", local_str
);
10280 json_object_string_add(json_row
, "sptSetup", spt_str
);
10281 json_object_string_add(json_row
, "upTime", timebuf
);
10282 json_object_string_add(json_row
, "stateTimer", statetimer
);
10283 json_object_object_add(json_group
, src_str
, json_row
);
10285 vty_out(vty
, "SA : %s\n", sa
->sg_str
);
10286 vty_out(vty
, " RP : %s\n", rp_str
);
10287 vty_out(vty
, " Peer : %s\n", peer_str
);
10288 vty_out(vty
, " Local : %s\n", local_str
);
10289 vty_out(vty
, " SPT Setup : %s\n", spt_str
);
10290 vty_out(vty
, " Uptime : %s\n", timebuf
);
10291 vty_out(vty
, " State Timer : %s\n", statetimer
);
10292 vty_out(vty
, "\n");
10296 static void ip_msdp_show_sa_detail(struct pim_instance
*pim
, struct vty
*vty
,
10299 struct listnode
*sanode
;
10300 struct pim_msdp_sa
*sa
;
10301 char src_str
[INET_ADDRSTRLEN
];
10302 char grp_str
[INET_ADDRSTRLEN
];
10303 json_object
*json
= NULL
;
10306 json
= json_object_new_object();
10309 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
10310 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
10311 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
10312 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
, uj
,
10317 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10318 json
, JSON_C_TO_STRING_PRETTY
));
10319 json_object_free(json
);
10323 DEFUN (show_ip_msdp_sa_detail
,
10324 show_ip_msdp_sa_detail_cmd
,
10325 "show ip msdp [vrf NAME] sa detail [json]",
10330 "MSDP active-source information\n"
10331 "Detailed output\n"
10334 bool uj
= use_json(argc
, argv
);
10336 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10339 return CMD_WARNING
;
10341 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
10343 return CMD_SUCCESS
;
10346 DEFUN (show_ip_msdp_sa_detail_vrf_all
,
10347 show_ip_msdp_sa_detail_vrf_all_cmd
,
10348 "show ip msdp vrf all sa detail [json]",
10353 "MSDP active-source information\n"
10354 "Detailed output\n"
10357 bool uj
= use_json(argc
, argv
);
10362 vty_out(vty
, "{ ");
10363 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
10366 vty_out(vty
, ", ");
10367 vty_out(vty
, " \"%s\": ", vrf
->name
);
10370 vty_out(vty
, "VRF: %s\n", vrf
->name
);
10371 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
10374 vty_out(vty
, "}\n");
10376 return CMD_SUCCESS
;
10379 static void ip_msdp_show_sa_addr(struct pim_instance
*pim
, struct vty
*vty
,
10380 const char *addr
, bool uj
)
10382 struct listnode
*sanode
;
10383 struct pim_msdp_sa
*sa
;
10384 char src_str
[INET_ADDRSTRLEN
];
10385 char grp_str
[INET_ADDRSTRLEN
];
10386 json_object
*json
= NULL
;
10389 json
= json_object_new_object();
10392 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
10393 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
10394 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
10395 if (!strcmp(addr
, src_str
) || !strcmp(addr
, grp_str
)) {
10396 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
10402 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10403 json
, JSON_C_TO_STRING_PRETTY
));
10404 json_object_free(json
);
10408 static void ip_msdp_show_sa_sg(struct pim_instance
*pim
, struct vty
*vty
,
10409 const char *src
, const char *grp
, bool uj
)
10411 struct listnode
*sanode
;
10412 struct pim_msdp_sa
*sa
;
10413 char src_str
[INET_ADDRSTRLEN
];
10414 char grp_str
[INET_ADDRSTRLEN
];
10415 json_object
*json
= NULL
;
10418 json
= json_object_new_object();
10421 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
10422 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
10423 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
10424 if (!strcmp(src
, src_str
) && !strcmp(grp
, grp_str
)) {
10425 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
10431 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10432 json
, JSON_C_TO_STRING_PRETTY
));
10433 json_object_free(json
);
10437 DEFUN (show_ip_msdp_sa_sg
,
10438 show_ip_msdp_sa_sg_cmd
,
10439 "show ip msdp [vrf NAME] sa [A.B.C.D [A.B.C.D]] [json]",
10444 "MSDP active-source information\n"
10445 "source or group ip\n"
10449 bool uj
= use_json(argc
, argv
);
10453 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10456 return CMD_WARNING
;
10458 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
10460 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
10464 if (src_ip
&& grp_ip
)
10465 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
10467 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
10469 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
10471 return CMD_SUCCESS
;
10474 DEFUN (show_ip_msdp_sa_sg_vrf_all
,
10475 show_ip_msdp_sa_sg_vrf_all_cmd
,
10476 "show ip msdp vrf all sa [A.B.C.D [A.B.C.D]] [json]",
10481 "MSDP active-source information\n"
10482 "source or group ip\n"
10486 bool uj
= use_json(argc
, argv
);
10491 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
10493 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
10498 vty_out(vty
, "{ ");
10499 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
10502 vty_out(vty
, ", ");
10503 vty_out(vty
, " \"%s\": ", vrf
->name
);
10506 vty_out(vty
, "VRF: %s\n", vrf
->name
);
10508 if (src_ip
&& grp_ip
)
10509 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
10511 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
10513 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
10516 vty_out(vty
, "}\n");
10518 return CMD_SUCCESS
;
10521 struct pim_sg_cache_walk_data
{
10524 json_object
*json_group
;
10525 struct in_addr addr
;
10529 static void pim_show_vxlan_sg_entry(struct pim_vxlan_sg
*vxlan_sg
,
10530 struct pim_sg_cache_walk_data
*cwd
)
10532 struct vty
*vty
= cwd
->vty
;
10533 json_object
*json
= cwd
->json
;
10534 char src_str
[INET_ADDRSTRLEN
];
10535 char grp_str
[INET_ADDRSTRLEN
];
10536 json_object
*json_row
;
10537 bool installed
= (vxlan_sg
->up
) ? true : false;
10538 const char *iif_name
= vxlan_sg
->iif
?vxlan_sg
->iif
->name
:"-";
10539 const char *oif_name
;
10541 if (pim_vxlan_is_orig_mroute(vxlan_sg
))
10542 oif_name
= vxlan_sg
->orig_oif
?vxlan_sg
->orig_oif
->name
:"";
10544 oif_name
= vxlan_sg
->term_oif
?vxlan_sg
->term_oif
->name
:"";
10546 if (cwd
->addr_match
&& (vxlan_sg
->sg
.src
.s_addr
!= cwd
->addr
.s_addr
) &&
10547 (vxlan_sg
->sg
.grp
.s_addr
!= cwd
->addr
.s_addr
)) {
10550 pim_inet4_dump("<src?>", vxlan_sg
->sg
.src
, src_str
, sizeof(src_str
));
10551 pim_inet4_dump("<grp?>", vxlan_sg
->sg
.grp
, grp_str
, sizeof(grp_str
));
10553 json_object_object_get_ex(json
, grp_str
, &cwd
->json_group
);
10555 if (!cwd
->json_group
) {
10556 cwd
->json_group
= json_object_new_object();
10557 json_object_object_add(json
, grp_str
,
10561 json_row
= json_object_new_object();
10562 json_object_string_add(json_row
, "source", src_str
);
10563 json_object_string_add(json_row
, "group", grp_str
);
10564 json_object_string_add(json_row
, "input", iif_name
);
10565 json_object_string_add(json_row
, "output", oif_name
);
10567 json_object_boolean_true_add(json_row
, "installed");
10569 json_object_boolean_false_add(json_row
, "installed");
10570 json_object_object_add(cwd
->json_group
, src_str
, json_row
);
10572 vty_out(vty
, "%-15s %-15s %-15s %-15s %-5s\n",
10573 src_str
, grp_str
, iif_name
, oif_name
,
10578 static void pim_show_vxlan_sg_hash_entry(struct hash_bucket
*backet
, void *arg
)
10580 pim_show_vxlan_sg_entry((struct pim_vxlan_sg
*)backet
->data
,
10581 (struct pim_sg_cache_walk_data
*)arg
);
10584 static void pim_show_vxlan_sg(struct pim_instance
*pim
,
10585 struct vty
*vty
, bool uj
)
10587 json_object
*json
= NULL
;
10588 struct pim_sg_cache_walk_data cwd
;
10591 json
= json_object_new_object();
10593 vty_out(vty
, "Codes: I -> installed\n");
10595 "Source Group Input Output Flags\n");
10598 memset(&cwd
, 0, sizeof(cwd
));
10601 hash_iterate(pim
->vxlan
.sg_hash
, pim_show_vxlan_sg_hash_entry
, &cwd
);
10604 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10605 json
, JSON_C_TO_STRING_PRETTY
));
10606 json_object_free(json
);
10610 static void pim_show_vxlan_sg_match_addr(struct pim_instance
*pim
,
10611 struct vty
*vty
, char *addr_str
, bool uj
)
10613 json_object
*json
= NULL
;
10614 struct pim_sg_cache_walk_data cwd
;
10617 memset(&cwd
, 0, sizeof(cwd
));
10618 result
= inet_pton(AF_INET
, addr_str
, &cwd
.addr
);
10620 vty_out(vty
, "Bad address %s: errno=%d: %s\n", addr_str
,
10621 errno
, safe_strerror(errno
));
10626 json
= json_object_new_object();
10628 vty_out(vty
, "Codes: I -> installed\n");
10630 "Source Group Input Output Flags\n");
10635 cwd
.addr_match
= true;
10636 hash_iterate(pim
->vxlan
.sg_hash
, pim_show_vxlan_sg_hash_entry
, &cwd
);
10639 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10640 json
, JSON_C_TO_STRING_PRETTY
));
10641 json_object_free(json
);
10645 static void pim_show_vxlan_sg_one(struct pim_instance
*pim
,
10646 struct vty
*vty
, char *src_str
, char *grp_str
, bool uj
)
10648 json_object
*json
= NULL
;
10649 struct prefix_sg sg
;
10651 struct pim_vxlan_sg
*vxlan_sg
;
10652 const char *iif_name
;
10654 const char *oif_name
;
10656 result
= inet_pton(AF_INET
, src_str
, &sg
.src
);
10658 vty_out(vty
, "Bad src address %s: errno=%d: %s\n", src_str
,
10659 errno
, safe_strerror(errno
));
10662 result
= inet_pton(AF_INET
, grp_str
, &sg
.grp
);
10664 vty_out(vty
, "Bad grp address %s: errno=%d: %s\n", grp_str
,
10665 errno
, safe_strerror(errno
));
10669 sg
.family
= AF_INET
;
10670 sg
.prefixlen
= IPV4_MAX_BITLEN
;
10672 json
= json_object_new_object();
10674 vxlan_sg
= pim_vxlan_sg_find(pim
, &sg
);
10676 installed
= (vxlan_sg
->up
) ? true : false;
10677 iif_name
= vxlan_sg
->iif
?vxlan_sg
->iif
->name
:"-";
10679 if (pim_vxlan_is_orig_mroute(vxlan_sg
))
10681 vxlan_sg
->orig_oif
?vxlan_sg
->orig_oif
->name
:"";
10684 vxlan_sg
->term_oif
?vxlan_sg
->term_oif
->name
:"";
10687 json_object_string_add(json
, "source", src_str
);
10688 json_object_string_add(json
, "group", grp_str
);
10689 json_object_string_add(json
, "input", iif_name
);
10690 json_object_string_add(json
, "output", oif_name
);
10692 json_object_boolean_true_add(json
, "installed");
10694 json_object_boolean_false_add(json
,
10697 vty_out(vty
, "SG : %s\n", vxlan_sg
->sg_str
);
10698 vty_out(vty
, " Input : %s\n", iif_name
);
10699 vty_out(vty
, " Output : %s\n", oif_name
);
10700 vty_out(vty
, " installed : %s\n",
10701 installed
?"yes":"no");
10706 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10707 json
, JSON_C_TO_STRING_PRETTY
));
10708 json_object_free(json
);
10712 DEFUN (show_ip_pim_vxlan_sg
,
10713 show_ip_pim_vxlan_sg_cmd
,
10714 "show ip pim [vrf NAME] vxlan-groups [A.B.C.D [A.B.C.D]] [json]",
10719 "VxLAN BUM groups\n"
10720 "source or group ip\n"
10724 bool uj
= use_json(argc
, argv
);
10728 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10731 return CMD_WARNING
;
10733 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ?
10734 argv
[idx
++]->arg
:NULL
;
10735 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
) ?
10736 argv
[idx
]->arg
:NULL
;
10738 if (src_ip
&& grp_ip
)
10739 pim_show_vxlan_sg_one(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
10741 pim_show_vxlan_sg_match_addr(vrf
->info
, vty
, src_ip
, uj
);
10743 pim_show_vxlan_sg(vrf
->info
, vty
, uj
);
10745 return CMD_SUCCESS
;
10748 static void pim_show_vxlan_sg_work(struct pim_instance
*pim
,
10749 struct vty
*vty
, bool uj
)
10751 json_object
*json
= NULL
;
10752 struct pim_sg_cache_walk_data cwd
;
10753 struct listnode
*node
;
10754 struct pim_vxlan_sg
*vxlan_sg
;
10757 json
= json_object_new_object();
10759 vty_out(vty
, "Codes: I -> installed\n");
10761 "Source Group Input Flags\n");
10764 memset(&cwd
, 0, sizeof(cwd
));
10767 for (ALL_LIST_ELEMENTS_RO(pim_vxlan_p
->work_list
, node
, vxlan_sg
))
10768 pim_show_vxlan_sg_entry(vxlan_sg
, &cwd
);
10771 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10772 json
, JSON_C_TO_STRING_PRETTY
));
10773 json_object_free(json
);
10777 DEFUN_HIDDEN (show_ip_pim_vxlan_sg_work
,
10778 show_ip_pim_vxlan_sg_work_cmd
,
10779 "show ip pim [vrf NAME] vxlan-work [json]",
10784 "VxLAN work list\n"
10787 bool uj
= use_json(argc
, argv
);
10791 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10794 return CMD_WARNING
;
10796 pim_show_vxlan_sg_work(vrf
->info
, vty
, uj
);
10798 return CMD_SUCCESS
;
10801 DEFUN_HIDDEN (no_ip_pim_mlag
,
10802 no_ip_pim_mlag_cmd
,
10809 struct in_addr addr
;
10812 pim_vxlan_mlag_update(true/*mlag_enable*/,
10813 false/*peer_state*/, MLAG_ROLE_NONE
,
10814 NULL
/*peerlink*/, &addr
);
10816 return CMD_SUCCESS
;
10819 DEFUN_HIDDEN (ip_pim_mlag
,
10821 "ip pim mlag INTERFACE role [primary|secondary] state [up|down] addr A.B.C.D",
10825 "peerlink sub interface\n"
10827 "MLAG role primary\n"
10828 "MLAG role secondary\n"
10829 "peer session state\n"
10830 "peer session state up\n"
10831 "peer session state down\n"
10833 "unique ip address\n")
10835 struct interface
*ifp
;
10836 const char *peerlink
;
10841 struct in_addr reg_addr
;
10844 peerlink
= argv
[idx
]->arg
;
10845 ifp
= if_lookup_by_name(peerlink
, VRF_DEFAULT
);
10847 vty_out(vty
, "No such interface name %s\n", peerlink
);
10848 return CMD_WARNING
;
10852 if (!strcmp(argv
[idx
]->arg
, "primary")) {
10853 role
= MLAG_ROLE_PRIMARY
;
10854 } else if (!strcmp(argv
[idx
]->arg
, "secondary")) {
10855 role
= MLAG_ROLE_SECONDARY
;
10857 vty_out(vty
, "unknown MLAG role %s\n", argv
[idx
]->arg
);
10858 return CMD_WARNING
;
10862 if (!strcmp(argv
[idx
]->arg
, "up")) {
10864 } else if (strcmp(argv
[idx
]->arg
, "down")) {
10865 peer_state
= false;
10867 vty_out(vty
, "unknown MLAG state %s\n", argv
[idx
]->arg
);
10868 return CMD_WARNING
;
10872 result
= inet_pton(AF_INET
, argv
[idx
]->arg
, ®_addr
);
10874 vty_out(vty
, "%% Bad reg address %s: errno=%d: %s\n",
10876 errno
, safe_strerror(errno
));
10877 return CMD_WARNING_CONFIG_FAILED
;
10879 pim_vxlan_mlag_update(true, peer_state
, role
, ifp
, ®_addr
);
10881 return CMD_SUCCESS
;
10884 void pim_cmd_init(void)
10886 install_node(&interface_node
); /* INTERFACE_NODE */
10889 install_node(&debug_node
);
10891 install_element(ENABLE_NODE
, &pim_test_sg_keepalive_cmd
);
10893 install_element(CONFIG_NODE
, &ip_pim_rp_cmd
);
10894 install_element(VRF_NODE
, &ip_pim_rp_cmd
);
10895 install_element(CONFIG_NODE
, &no_ip_pim_rp_cmd
);
10896 install_element(VRF_NODE
, &no_ip_pim_rp_cmd
);
10897 install_element(CONFIG_NODE
, &ip_pim_rp_prefix_list_cmd
);
10898 install_element(VRF_NODE
, &ip_pim_rp_prefix_list_cmd
);
10899 install_element(CONFIG_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
10900 install_element(VRF_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
10901 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
10902 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
10903 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
10904 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
10905 install_element(CONFIG_NODE
, &ip_pim_ssm_prefix_list_cmd
);
10906 install_element(VRF_NODE
, &ip_pim_ssm_prefix_list_cmd
);
10907 install_element(CONFIG_NODE
, &ip_pim_register_suppress_cmd
);
10908 install_element(VRF_NODE
, &ip_pim_register_suppress_cmd
);
10909 install_element(CONFIG_NODE
, &no_ip_pim_register_suppress_cmd
);
10910 install_element(VRF_NODE
, &no_ip_pim_register_suppress_cmd
);
10911 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
10912 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
10913 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
10914 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
10915 install_element(CONFIG_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
10916 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
10917 install_element(CONFIG_NODE
,
10918 &no_ip_pim_spt_switchover_infinity_plist_cmd
);
10919 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_plist_cmd
);
10920 install_element(CONFIG_NODE
, &pim_register_accept_list_cmd
);
10921 install_element(VRF_NODE
, &pim_register_accept_list_cmd
);
10922 install_element(CONFIG_NODE
, &ip_pim_joinprune_time_cmd
);
10923 install_element(VRF_NODE
, &ip_pim_joinprune_time_cmd
);
10924 install_element(CONFIG_NODE
, &no_ip_pim_joinprune_time_cmd
);
10925 install_element(VRF_NODE
, &no_ip_pim_joinprune_time_cmd
);
10926 install_element(CONFIG_NODE
, &ip_pim_keep_alive_cmd
);
10927 install_element(VRF_NODE
, &ip_pim_keep_alive_cmd
);
10928 install_element(CONFIG_NODE
, &ip_pim_rp_keep_alive_cmd
);
10929 install_element(VRF_NODE
, &ip_pim_rp_keep_alive_cmd
);
10930 install_element(CONFIG_NODE
, &no_ip_pim_keep_alive_cmd
);
10931 install_element(VRF_NODE
, &no_ip_pim_keep_alive_cmd
);
10932 install_element(CONFIG_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
10933 install_element(VRF_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
10934 install_element(CONFIG_NODE
, &ip_pim_packets_cmd
);
10935 install_element(VRF_NODE
, &ip_pim_packets_cmd
);
10936 install_element(CONFIG_NODE
, &no_ip_pim_packets_cmd
);
10937 install_element(VRF_NODE
, &no_ip_pim_packets_cmd
);
10938 install_element(CONFIG_NODE
, &ip_pim_v6_secondary_cmd
);
10939 install_element(VRF_NODE
, &ip_pim_v6_secondary_cmd
);
10940 install_element(CONFIG_NODE
, &no_ip_pim_v6_secondary_cmd
);
10941 install_element(VRF_NODE
, &no_ip_pim_v6_secondary_cmd
);
10942 install_element(CONFIG_NODE
, &ip_ssmpingd_cmd
);
10943 install_element(VRF_NODE
, &ip_ssmpingd_cmd
);
10944 install_element(CONFIG_NODE
, &no_ip_ssmpingd_cmd
);
10945 install_element(VRF_NODE
, &no_ip_ssmpingd_cmd
);
10946 install_element(CONFIG_NODE
, &ip_msdp_peer_cmd
);
10947 install_element(VRF_NODE
, &ip_msdp_peer_cmd
);
10948 install_element(CONFIG_NODE
, &no_ip_msdp_peer_cmd
);
10949 install_element(VRF_NODE
, &no_ip_msdp_peer_cmd
);
10950 install_element(CONFIG_NODE
, &ip_pim_ecmp_cmd
);
10951 install_element(VRF_NODE
, &ip_pim_ecmp_cmd
);
10952 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_cmd
);
10953 install_element(VRF_NODE
, &no_ip_pim_ecmp_cmd
);
10954 install_element(CONFIG_NODE
, &ip_pim_ecmp_rebalance_cmd
);
10955 install_element(VRF_NODE
, &ip_pim_ecmp_rebalance_cmd
);
10956 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
10957 install_element(VRF_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
10958 install_element(CONFIG_NODE
, &ip_pim_mlag_cmd
);
10959 install_element(CONFIG_NODE
, &no_ip_pim_mlag_cmd
);
10960 install_element(CONFIG_NODE
, &igmp_group_watermark_cmd
);
10961 install_element(VRF_NODE
, &igmp_group_watermark_cmd
);
10962 install_element(CONFIG_NODE
, &no_igmp_group_watermark_cmd
);
10963 install_element(VRF_NODE
, &no_igmp_group_watermark_cmd
);
10965 install_element(INTERFACE_NODE
, &interface_ip_igmp_cmd
);
10966 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_cmd
);
10967 install_element(INTERFACE_NODE
, &interface_ip_igmp_join_cmd
);
10968 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_join_cmd
);
10969 install_element(INTERFACE_NODE
, &interface_ip_igmp_version_cmd
);
10970 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_version_cmd
);
10971 install_element(INTERFACE_NODE
, &interface_ip_igmp_query_interval_cmd
);
10972 install_element(INTERFACE_NODE
,
10973 &interface_no_ip_igmp_query_interval_cmd
);
10974 install_element(INTERFACE_NODE
,
10975 &interface_ip_igmp_query_max_response_time_cmd
);
10976 install_element(INTERFACE_NODE
,
10977 &interface_no_ip_igmp_query_max_response_time_cmd
);
10978 install_element(INTERFACE_NODE
,
10979 &interface_ip_igmp_query_max_response_time_dsec_cmd
);
10980 install_element(INTERFACE_NODE
,
10981 &interface_no_ip_igmp_query_max_response_time_dsec_cmd
);
10982 install_element(INTERFACE_NODE
,
10983 &interface_ip_igmp_last_member_query_count_cmd
);
10984 install_element(INTERFACE_NODE
,
10985 &interface_no_ip_igmp_last_member_query_count_cmd
);
10986 install_element(INTERFACE_NODE
,
10987 &interface_ip_igmp_last_member_query_interval_cmd
);
10988 install_element(INTERFACE_NODE
,
10989 &interface_no_ip_igmp_last_member_query_interval_cmd
);
10990 install_element(INTERFACE_NODE
, &interface_ip_pim_activeactive_cmd
);
10991 install_element(INTERFACE_NODE
, &interface_ip_pim_ssm_cmd
);
10992 install_element(INTERFACE_NODE
, &interface_no_ip_pim_ssm_cmd
);
10993 install_element(INTERFACE_NODE
, &interface_ip_pim_sm_cmd
);
10994 install_element(INTERFACE_NODE
, &interface_no_ip_pim_sm_cmd
);
10995 install_element(INTERFACE_NODE
, &interface_ip_pim_cmd
);
10996 install_element(INTERFACE_NODE
, &interface_no_ip_pim_cmd
);
10997 install_element(INTERFACE_NODE
, &interface_ip_pim_drprio_cmd
);
10998 install_element(INTERFACE_NODE
, &interface_no_ip_pim_drprio_cmd
);
10999 install_element(INTERFACE_NODE
, &interface_ip_pim_hello_cmd
);
11000 install_element(INTERFACE_NODE
, &interface_no_ip_pim_hello_cmd
);
11001 install_element(INTERFACE_NODE
, &interface_ip_pim_boundary_oil_cmd
);
11002 install_element(INTERFACE_NODE
, &interface_no_ip_pim_boundary_oil_cmd
);
11003 install_element(INTERFACE_NODE
, &interface_ip_igmp_query_generate_cmd
);
11005 // Static mroutes NEB
11006 install_element(INTERFACE_NODE
, &interface_ip_mroute_cmd
);
11007 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_cmd
);
11009 install_element(VIEW_NODE
, &show_ip_igmp_interface_cmd
);
11010 install_element(VIEW_NODE
, &show_ip_igmp_interface_vrf_all_cmd
);
11011 install_element(VIEW_NODE
, &show_ip_igmp_join_cmd
);
11012 install_element(VIEW_NODE
, &show_ip_igmp_join_vrf_all_cmd
);
11013 install_element(VIEW_NODE
, &show_ip_igmp_groups_cmd
);
11014 install_element(VIEW_NODE
, &show_ip_igmp_groups_vrf_all_cmd
);
11015 install_element(VIEW_NODE
, &show_ip_igmp_groups_retransmissions_cmd
);
11016 install_element(VIEW_NODE
, &show_ip_igmp_sources_cmd
);
11017 install_element(VIEW_NODE
, &show_ip_igmp_sources_retransmissions_cmd
);
11018 install_element(VIEW_NODE
, &show_ip_igmp_statistics_cmd
);
11019 install_element(VIEW_NODE
, &show_ip_pim_assert_cmd
);
11020 install_element(VIEW_NODE
, &show_ip_pim_assert_internal_cmd
);
11021 install_element(VIEW_NODE
, &show_ip_pim_assert_metric_cmd
);
11022 install_element(VIEW_NODE
, &show_ip_pim_assert_winner_metric_cmd
);
11023 install_element(VIEW_NODE
, &show_ip_pim_interface_traffic_cmd
);
11024 install_element(VIEW_NODE
, &show_ip_pim_interface_cmd
);
11025 install_element(VIEW_NODE
, &show_ip_pim_interface_vrf_all_cmd
);
11026 install_element(VIEW_NODE
, &show_ip_pim_join_cmd
);
11027 install_element(VIEW_NODE
, &show_ip_pim_join_vrf_all_cmd
);
11028 install_element(VIEW_NODE
, &show_ip_pim_jp_agg_cmd
);
11029 install_element(VIEW_NODE
, &show_ip_pim_local_membership_cmd
);
11030 install_element(VIEW_NODE
, &show_ip_pim_mlag_summary_cmd
);
11031 install_element(VIEW_NODE
, &show_ip_pim_mlag_up_cmd
);
11032 install_element(VIEW_NODE
, &show_ip_pim_mlag_up_vrf_all_cmd
);
11033 install_element(VIEW_NODE
, &show_ip_pim_neighbor_cmd
);
11034 install_element(VIEW_NODE
, &show_ip_pim_neighbor_vrf_all_cmd
);
11035 install_element(VIEW_NODE
, &show_ip_pim_rpf_cmd
);
11036 install_element(VIEW_NODE
, &show_ip_pim_rpf_vrf_all_cmd
);
11037 install_element(VIEW_NODE
, &show_ip_pim_secondary_cmd
);
11038 install_element(VIEW_NODE
, &show_ip_pim_state_cmd
);
11039 install_element(VIEW_NODE
, &show_ip_pim_state_vrf_all_cmd
);
11040 install_element(VIEW_NODE
, &show_ip_pim_upstream_cmd
);
11041 install_element(VIEW_NODE
, &show_ip_pim_upstream_vrf_all_cmd
);
11042 install_element(VIEW_NODE
, &show_ip_pim_channel_cmd
);
11043 install_element(VIEW_NODE
, &show_ip_pim_upstream_join_desired_cmd
);
11044 install_element(VIEW_NODE
, &show_ip_pim_upstream_rpf_cmd
);
11045 install_element(VIEW_NODE
, &show_ip_pim_rp_cmd
);
11046 install_element(VIEW_NODE
, &show_ip_pim_rp_vrf_all_cmd
);
11047 install_element(VIEW_NODE
, &show_ip_pim_bsr_cmd
);
11048 install_element(VIEW_NODE
, &show_ip_multicast_cmd
);
11049 install_element(VIEW_NODE
, &show_ip_multicast_vrf_all_cmd
);
11050 install_element(VIEW_NODE
, &show_ip_mroute_cmd
);
11051 install_element(VIEW_NODE
, &show_ip_mroute_vrf_all_cmd
);
11052 install_element(VIEW_NODE
, &show_ip_mroute_count_cmd
);
11053 install_element(VIEW_NODE
, &show_ip_mroute_count_vrf_all_cmd
);
11054 install_element(VIEW_NODE
, &show_ip_mroute_summary_cmd
);
11055 install_element(VIEW_NODE
, &show_ip_mroute_summary_vrf_all_cmd
);
11056 install_element(VIEW_NODE
, &show_ip_rib_cmd
);
11057 install_element(VIEW_NODE
, &show_ip_ssmpingd_cmd
);
11058 install_element(VIEW_NODE
, &show_debugging_pim_cmd
);
11059 install_element(VIEW_NODE
, &show_ip_pim_nexthop_cmd
);
11060 install_element(VIEW_NODE
, &show_ip_pim_nexthop_lookup_cmd
);
11061 install_element(VIEW_NODE
, &show_ip_pim_bsrp_cmd
);
11062 install_element(VIEW_NODE
, &show_ip_pim_bsm_db_cmd
);
11063 install_element(VIEW_NODE
, &show_ip_pim_statistics_cmd
);
11065 install_element(ENABLE_NODE
, &clear_ip_mroute_count_cmd
);
11066 install_element(ENABLE_NODE
, &clear_ip_interfaces_cmd
);
11067 install_element(ENABLE_NODE
, &clear_ip_igmp_interfaces_cmd
);
11068 install_element(ENABLE_NODE
, &clear_ip_mroute_cmd
);
11069 install_element(ENABLE_NODE
, &clear_ip_pim_interfaces_cmd
);
11070 install_element(ENABLE_NODE
, &clear_ip_pim_interface_traffic_cmd
);
11071 install_element(ENABLE_NODE
, &clear_ip_pim_oil_cmd
);
11072 install_element(ENABLE_NODE
, &clear_ip_pim_statistics_cmd
);
11074 install_element(ENABLE_NODE
, &debug_igmp_cmd
);
11075 install_element(ENABLE_NODE
, &no_debug_igmp_cmd
);
11076 install_element(ENABLE_NODE
, &debug_igmp_events_cmd
);
11077 install_element(ENABLE_NODE
, &no_debug_igmp_events_cmd
);
11078 install_element(ENABLE_NODE
, &debug_igmp_packets_cmd
);
11079 install_element(ENABLE_NODE
, &no_debug_igmp_packets_cmd
);
11080 install_element(ENABLE_NODE
, &debug_igmp_trace_cmd
);
11081 install_element(ENABLE_NODE
, &no_debug_igmp_trace_cmd
);
11082 install_element(ENABLE_NODE
, &debug_mroute_cmd
);
11083 install_element(ENABLE_NODE
, &debug_mroute_detail_cmd
);
11084 install_element(ENABLE_NODE
, &no_debug_mroute_cmd
);
11085 install_element(ENABLE_NODE
, &no_debug_mroute_detail_cmd
);
11086 install_element(ENABLE_NODE
, &debug_pim_static_cmd
);
11087 install_element(ENABLE_NODE
, &no_debug_pim_static_cmd
);
11088 install_element(ENABLE_NODE
, &debug_pim_cmd
);
11089 install_element(ENABLE_NODE
, &no_debug_pim_cmd
);
11090 install_element(ENABLE_NODE
, &debug_pim_nht_cmd
);
11091 install_element(ENABLE_NODE
, &no_debug_pim_nht_cmd
);
11092 install_element(ENABLE_NODE
, &debug_pim_nht_rp_cmd
);
11093 install_element(ENABLE_NODE
, &no_debug_pim_nht_rp_cmd
);
11094 install_element(ENABLE_NODE
, &debug_pim_events_cmd
);
11095 install_element(ENABLE_NODE
, &no_debug_pim_events_cmd
);
11096 install_element(ENABLE_NODE
, &debug_pim_packets_cmd
);
11097 install_element(ENABLE_NODE
, &no_debug_pim_packets_cmd
);
11098 install_element(ENABLE_NODE
, &debug_pim_packetdump_send_cmd
);
11099 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_send_cmd
);
11100 install_element(ENABLE_NODE
, &debug_pim_packetdump_recv_cmd
);
11101 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_recv_cmd
);
11102 install_element(ENABLE_NODE
, &debug_pim_trace_cmd
);
11103 install_element(ENABLE_NODE
, &no_debug_pim_trace_cmd
);
11104 install_element(ENABLE_NODE
, &debug_pim_trace_detail_cmd
);
11105 install_element(ENABLE_NODE
, &no_debug_pim_trace_detail_cmd
);
11106 install_element(ENABLE_NODE
, &debug_ssmpingd_cmd
);
11107 install_element(ENABLE_NODE
, &no_debug_ssmpingd_cmd
);
11108 install_element(ENABLE_NODE
, &debug_pim_zebra_cmd
);
11109 install_element(ENABLE_NODE
, &no_debug_pim_zebra_cmd
);
11110 install_element(ENABLE_NODE
, &debug_pim_mlag_cmd
);
11111 install_element(ENABLE_NODE
, &no_debug_pim_mlag_cmd
);
11112 install_element(ENABLE_NODE
, &debug_pim_vxlan_cmd
);
11113 install_element(ENABLE_NODE
, &no_debug_pim_vxlan_cmd
);
11114 install_element(ENABLE_NODE
, &debug_msdp_cmd
);
11115 install_element(ENABLE_NODE
, &no_debug_msdp_cmd
);
11116 install_element(ENABLE_NODE
, &debug_msdp_events_cmd
);
11117 install_element(ENABLE_NODE
, &no_debug_msdp_events_cmd
);
11118 install_element(ENABLE_NODE
, &debug_msdp_packets_cmd
);
11119 install_element(ENABLE_NODE
, &no_debug_msdp_packets_cmd
);
11120 install_element(ENABLE_NODE
, &debug_mtrace_cmd
);
11121 install_element(ENABLE_NODE
, &no_debug_mtrace_cmd
);
11122 install_element(ENABLE_NODE
, &debug_bsm_cmd
);
11123 install_element(ENABLE_NODE
, &no_debug_bsm_cmd
);
11125 install_element(CONFIG_NODE
, &debug_igmp_cmd
);
11126 install_element(CONFIG_NODE
, &no_debug_igmp_cmd
);
11127 install_element(CONFIG_NODE
, &debug_igmp_events_cmd
);
11128 install_element(CONFIG_NODE
, &no_debug_igmp_events_cmd
);
11129 install_element(CONFIG_NODE
, &debug_igmp_packets_cmd
);
11130 install_element(CONFIG_NODE
, &no_debug_igmp_packets_cmd
);
11131 install_element(CONFIG_NODE
, &debug_igmp_trace_cmd
);
11132 install_element(CONFIG_NODE
, &no_debug_igmp_trace_cmd
);
11133 install_element(CONFIG_NODE
, &debug_mroute_cmd
);
11134 install_element(CONFIG_NODE
, &debug_mroute_detail_cmd
);
11135 install_element(CONFIG_NODE
, &no_debug_mroute_cmd
);
11136 install_element(CONFIG_NODE
, &no_debug_mroute_detail_cmd
);
11137 install_element(CONFIG_NODE
, &debug_pim_static_cmd
);
11138 install_element(CONFIG_NODE
, &no_debug_pim_static_cmd
);
11139 install_element(CONFIG_NODE
, &debug_pim_cmd
);
11140 install_element(CONFIG_NODE
, &no_debug_pim_cmd
);
11141 install_element(CONFIG_NODE
, &debug_pim_nht_cmd
);
11142 install_element(CONFIG_NODE
, &no_debug_pim_nht_cmd
);
11143 install_element(CONFIG_NODE
, &debug_pim_nht_rp_cmd
);
11144 install_element(CONFIG_NODE
, &no_debug_pim_nht_rp_cmd
);
11145 install_element(CONFIG_NODE
, &debug_pim_events_cmd
);
11146 install_element(CONFIG_NODE
, &no_debug_pim_events_cmd
);
11147 install_element(CONFIG_NODE
, &debug_pim_packets_cmd
);
11148 install_element(CONFIG_NODE
, &no_debug_pim_packets_cmd
);
11149 install_element(CONFIG_NODE
, &debug_pim_trace_cmd
);
11150 install_element(CONFIG_NODE
, &no_debug_pim_trace_cmd
);
11151 install_element(CONFIG_NODE
, &debug_pim_trace_detail_cmd
);
11152 install_element(CONFIG_NODE
, &no_debug_pim_trace_detail_cmd
);
11153 install_element(CONFIG_NODE
, &debug_ssmpingd_cmd
);
11154 install_element(CONFIG_NODE
, &no_debug_ssmpingd_cmd
);
11155 install_element(CONFIG_NODE
, &debug_pim_zebra_cmd
);
11156 install_element(CONFIG_NODE
, &no_debug_pim_zebra_cmd
);
11157 install_element(CONFIG_NODE
, &debug_pim_mlag_cmd
);
11158 install_element(CONFIG_NODE
, &no_debug_pim_mlag_cmd
);
11159 install_element(CONFIG_NODE
, &debug_pim_vxlan_cmd
);
11160 install_element(CONFIG_NODE
, &no_debug_pim_vxlan_cmd
);
11161 install_element(CONFIG_NODE
, &debug_msdp_cmd
);
11162 install_element(CONFIG_NODE
, &no_debug_msdp_cmd
);
11163 install_element(CONFIG_NODE
, &debug_msdp_events_cmd
);
11164 install_element(CONFIG_NODE
, &no_debug_msdp_events_cmd
);
11165 install_element(CONFIG_NODE
, &debug_msdp_packets_cmd
);
11166 install_element(CONFIG_NODE
, &no_debug_msdp_packets_cmd
);
11167 install_element(CONFIG_NODE
, &debug_mtrace_cmd
);
11168 install_element(CONFIG_NODE
, &no_debug_mtrace_cmd
);
11169 install_element(CONFIG_NODE
, &debug_bsm_cmd
);
11170 install_element(CONFIG_NODE
, &no_debug_bsm_cmd
);
11172 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_member_cmd
);
11173 install_element(VRF_NODE
, &ip_msdp_mesh_group_member_cmd
);
11174 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
11175 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
11176 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_source_cmd
);
11177 install_element(VRF_NODE
, &ip_msdp_mesh_group_source_cmd
);
11178 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
11179 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
11180 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_cmd
);
11181 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_cmd
);
11182 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_cmd
);
11183 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_vrf_all_cmd
);
11184 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_cmd
);
11185 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_vrf_all_cmd
);
11186 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_cmd
);
11187 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_vrf_all_cmd
);
11188 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_cmd
);
11189 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_vrf_all_cmd
);
11190 install_element(VIEW_NODE
, &show_ip_pim_ssm_range_cmd
);
11191 install_element(VIEW_NODE
, &show_ip_pim_group_type_cmd
);
11192 install_element(VIEW_NODE
, &show_ip_pim_vxlan_sg_cmd
);
11193 install_element(VIEW_NODE
, &show_ip_pim_vxlan_sg_work_cmd
);
11194 install_element(INTERFACE_NODE
, &interface_pim_use_source_cmd
);
11195 install_element(INTERFACE_NODE
, &interface_no_pim_use_source_cmd
);
11196 /* Install BSM command */
11197 install_element(INTERFACE_NODE
, &ip_pim_bsm_cmd
);
11198 install_element(INTERFACE_NODE
, &no_ip_pim_bsm_cmd
);
11199 install_element(INTERFACE_NODE
, &ip_pim_ucast_bsm_cmd
);
11200 install_element(INTERFACE_NODE
, &no_ip_pim_ucast_bsm_cmd
);
11201 /* Install BFD command */
11202 install_element(INTERFACE_NODE
, &ip_pim_bfd_cmd
);
11203 install_element(INTERFACE_NODE
, &ip_pim_bfd_param_cmd
);
11204 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_cmd
);
11206 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_param_cmd
);
11207 #endif /* !HAVE_BFDD */