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, P: Peer Entry\n");
4987 DEFUN(show_ip_pim_mlag_up
, show_ip_pim_mlag_up_cmd
,
4988 "show ip pim [vrf NAME] mlag upstream [A.B.C.D [A.B.C.D]] [json]",
4995 "Unicast or Multicast address\n"
4996 "Multicast address\n" JSON_STR
)
4998 const char *src_or_group
= NULL
;
4999 const char *group
= NULL
;
5001 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5002 bool uj
= use_json(argc
, argv
);
5004 if (!vrf
|| !vrf
->info
) {
5005 vty_out(vty
, "%s: VRF or Info missing\n", __func__
);
5012 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
5013 src_or_group
= argv
[idx
]->arg
;
5015 group
= argv
[idx
+ 1]->arg
;
5018 pim_show_mlag_help_string(vty
, uj
);
5021 pim_show_mlag_up_detail(vrf
, vty
, src_or_group
, group
, uj
);
5023 pim_show_mlag_up_vrf(vrf
, vty
, uj
);
5029 DEFUN(show_ip_pim_mlag_up_vrf_all
, show_ip_pim_mlag_up_vrf_all_cmd
,
5030 "show ip pim vrf all mlag upstream [json]",
5031 SHOW_STR IP_STR PIM_STR VRF_CMD_HELP_STR
5033 "upstream\n" JSON_STR
)
5036 bool uj
= use_json(argc
, argv
);
5038 pim_show_mlag_help_string(vty
, uj
);
5039 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5040 pim_show_mlag_up_vrf(vrf
, vty
, uj
);
5046 DEFUN (show_ip_pim_neighbor
,
5047 show_ip_pim_neighbor_cmd
,
5048 "show ip pim [vrf NAME] neighbor [detail|WORD] [json]",
5053 "PIM neighbor information\n"
5055 "Name of interface or neighbor\n"
5059 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5060 bool uj
= use_json(argc
, argv
);
5065 if (argv_find(argv
, argc
, "detail", &idx
)
5066 || argv_find(argv
, argc
, "WORD", &idx
))
5067 pim_show_neighbors_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
5069 pim_show_neighbors(vrf
->info
, vty
, uj
);
5074 DEFUN (show_ip_pim_neighbor_vrf_all
,
5075 show_ip_pim_neighbor_vrf_all_cmd
,
5076 "show ip pim vrf all neighbor [detail|WORD] [json]",
5081 "PIM neighbor information\n"
5083 "Name of interface or neighbor\n"
5087 bool uj
= use_json(argc
, argv
);
5093 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5097 vty_out(vty
, " \"%s\": ", vrf
->name
);
5100 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5101 if (argv_find(argv
, argc
, "detail", &idx
)
5102 || argv_find(argv
, argc
, "WORD", &idx
))
5103 pim_show_neighbors_single(vrf
->info
, vty
,
5104 argv
[idx
]->arg
, uj
);
5106 pim_show_neighbors(vrf
->info
, vty
, uj
);
5109 vty_out(vty
, "}\n");
5114 DEFUN (show_ip_pim_secondary
,
5115 show_ip_pim_secondary_cmd
,
5116 "show ip pim [vrf NAME] secondary",
5121 "PIM neighbor addresses\n")
5124 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5129 pim_show_neighbors_secondary(vrf
->info
, vty
);
5134 DEFUN (show_ip_pim_state
,
5135 show_ip_pim_state_cmd
,
5136 "show ip pim [vrf NAME] state [A.B.C.D [A.B.C.D]] [json]",
5141 "PIM state information\n"
5142 "Unicast or Multicast address\n"
5143 "Multicast address\n"
5146 const char *src_or_group
= NULL
;
5147 const char *group
= NULL
;
5149 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5150 bool uj
= use_json(argc
, argv
);
5158 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
5159 src_or_group
= argv
[idx
]->arg
;
5161 group
= argv
[idx
+ 1]->arg
;
5164 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
5169 DEFUN (show_ip_pim_state_vrf_all
,
5170 show_ip_pim_state_vrf_all_cmd
,
5171 "show ip pim vrf all state [A.B.C.D [A.B.C.D]] [json]",
5176 "PIM state information\n"
5177 "Unicast or Multicast address\n"
5178 "Multicast address\n"
5181 const char *src_or_group
= NULL
;
5182 const char *group
= NULL
;
5184 bool uj
= use_json(argc
, argv
);
5193 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
5194 src_or_group
= argv
[idx
]->arg
;
5196 group
= argv
[idx
+ 1]->arg
;
5199 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5203 vty_out(vty
, " \"%s\": ", vrf
->name
);
5206 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5207 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
5210 vty_out(vty
, "}\n");
5215 DEFPY (show_ip_pim_upstream
,
5216 show_ip_pim_upstream_cmd
,
5217 "show ip pim [vrf NAME] upstream [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
5222 "PIM upstream information\n"
5223 "The Source or Group\n"
5227 struct prefix_sg sg
= {0};
5230 struct pim_instance
*pim
;
5232 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
5235 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
5238 pim
= pim_get_pim_instance(v
->vrf_id
);
5241 vty_out(vty
, "%% Unable to find pim instance\n");
5245 if (s_or_g
.s_addr
!= 0) {
5246 if (g
.s_addr
!= 0) {
5252 pim_show_upstream(pim
, vty
, &sg
, uj
);
5257 DEFUN (show_ip_pim_upstream_vrf_all
,
5258 show_ip_pim_upstream_vrf_all_cmd
,
5259 "show ip pim vrf all upstream [json]",
5264 "PIM upstream information\n"
5267 struct prefix_sg sg
= {0};
5268 bool uj
= use_json(argc
, argv
);
5274 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5278 vty_out(vty
, " \"%s\": ", vrf
->name
);
5281 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5282 pim_show_upstream(vrf
->info
, vty
, &sg
, uj
);
5288 DEFUN (show_ip_pim_channel
,
5289 show_ip_pim_channel_cmd
,
5290 "show ip pim [vrf NAME] channel [json]",
5295 "PIM downstream channel info\n"
5299 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5300 bool uj
= use_json(argc
, argv
);
5305 pim_show_channel(vrf
->info
, vty
, uj
);
5310 DEFUN (show_ip_pim_upstream_join_desired
,
5311 show_ip_pim_upstream_join_desired_cmd
,
5312 "show ip pim [vrf NAME] upstream-join-desired [json]",
5317 "PIM upstream join-desired\n"
5321 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5322 bool uj
= use_json(argc
, argv
);
5327 pim_show_join_desired(vrf
->info
, vty
, uj
);
5332 DEFUN (show_ip_pim_upstream_rpf
,
5333 show_ip_pim_upstream_rpf_cmd
,
5334 "show ip pim [vrf NAME] upstream-rpf [json]",
5339 "PIM upstream source rpf\n"
5343 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5344 bool uj
= use_json(argc
, argv
);
5349 pim_show_upstream_rpf(vrf
->info
, vty
, uj
);
5354 DEFUN (show_ip_pim_rp
,
5356 "show ip pim [vrf NAME] rp-info [json]",
5361 "PIM RP information\n"
5365 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5366 bool uj
= use_json(argc
, argv
);
5371 pim_rp_show_information(vrf
->info
, vty
, uj
);
5376 DEFUN (show_ip_pim_rp_vrf_all
,
5377 show_ip_pim_rp_vrf_all_cmd
,
5378 "show ip pim vrf all rp-info [json]",
5383 "PIM RP information\n"
5386 bool uj
= use_json(argc
, argv
);
5392 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5396 vty_out(vty
, " \"%s\": ", vrf
->name
);
5399 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5400 pim_rp_show_information(vrf
->info
, vty
, uj
);
5403 vty_out(vty
, "}\n");
5408 DEFUN (show_ip_pim_rpf
,
5409 show_ip_pim_rpf_cmd
,
5410 "show ip pim [vrf NAME] rpf [json]",
5415 "PIM cached source rpf information\n"
5419 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5420 bool uj
= use_json(argc
, argv
);
5425 pim_show_rpf(vrf
->info
, vty
, uj
);
5430 DEFUN (show_ip_pim_rpf_vrf_all
,
5431 show_ip_pim_rpf_vrf_all_cmd
,
5432 "show ip pim vrf all rpf [json]",
5437 "PIM cached source rpf information\n"
5440 bool uj
= use_json(argc
, argv
);
5446 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5450 vty_out(vty
, " \"%s\": ", vrf
->name
);
5453 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5454 pim_show_rpf(vrf
->info
, vty
, uj
);
5457 vty_out(vty
, "}\n");
5462 DEFUN (show_ip_pim_nexthop
,
5463 show_ip_pim_nexthop_cmd
,
5464 "show ip pim [vrf NAME] nexthop",
5469 "PIM cached nexthop rpf information\n")
5472 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5477 pim_show_nexthop(vrf
->info
, vty
);
5482 DEFUN (show_ip_pim_nexthop_lookup
,
5483 show_ip_pim_nexthop_lookup_cmd
,
5484 "show ip pim [vrf NAME] nexthop-lookup A.B.C.D A.B.C.D",
5489 "PIM cached nexthop rpf lookup\n"
5490 "Source/RP address\n"
5491 "Multicast Group address\n")
5493 struct prefix nht_p
;
5495 struct in_addr src_addr
, grp_addr
;
5496 struct in_addr vif_source
;
5497 const char *addr_str
, *addr_str1
;
5499 struct pim_nexthop nexthop
;
5500 char nexthop_addr_str
[PREFIX_STRLEN
];
5501 char grp_str
[PREFIX_STRLEN
];
5503 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5508 argv_find(argv
, argc
, "A.B.C.D", &idx
);
5509 addr_str
= argv
[idx
]->arg
;
5510 result
= inet_pton(AF_INET
, addr_str
, &src_addr
);
5512 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
5513 errno
, safe_strerror(errno
));
5517 if (pim_is_group_224_4(src_addr
)) {
5519 "Invalid argument. Expected Valid Source Address.\n");
5523 addr_str1
= argv
[idx
+ 1]->arg
;
5524 result
= inet_pton(AF_INET
, addr_str1
, &grp_addr
);
5526 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
5527 errno
, safe_strerror(errno
));
5531 if (!pim_is_group_224_4(grp_addr
)) {
5533 "Invalid argument. Expected Valid Multicast Group Address.\n");
5537 if (!pim_rp_set_upstream_addr(vrf
->info
, &vif_source
, src_addr
,
5541 nht_p
.family
= AF_INET
;
5542 nht_p
.prefixlen
= IPV4_MAX_BITLEN
;
5543 nht_p
.u
.prefix4
= vif_source
;
5544 grp
.family
= AF_INET
;
5545 grp
.prefixlen
= IPV4_MAX_BITLEN
;
5546 grp
.u
.prefix4
= grp_addr
;
5547 memset(&nexthop
, 0, sizeof(nexthop
));
5549 result
= pim_ecmp_nexthop_lookup(vrf
->info
, &nexthop
, &nht_p
, &grp
, 0);
5553 "Nexthop Lookup failed, no usable routes returned.\n");
5557 pim_addr_dump("<grp?>", &grp
, grp_str
, sizeof(grp_str
));
5558 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
5559 nexthop_addr_str
, sizeof(nexthop_addr_str
));
5560 vty_out(vty
, "Group %s --- Nexthop %s Interface %s \n", grp_str
,
5561 nexthop_addr_str
, nexthop
.interface
->name
);
5566 DEFUN (show_ip_pim_interface_traffic
,
5567 show_ip_pim_interface_traffic_cmd
,
5568 "show ip pim [vrf NAME] interface traffic [WORD] [json]",
5573 "PIM interface information\n"
5574 "Protocol Packet counters\n"
5579 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5580 bool uj
= use_json(argc
, argv
);
5585 if (argv_find(argv
, argc
, "WORD", &idx
))
5586 pim_show_interface_traffic_single(vrf
->info
, vty
,
5587 argv
[idx
]->arg
, uj
);
5589 pim_show_interface_traffic(vrf
->info
, vty
, uj
);
5594 DEFUN (show_ip_pim_bsm_db
,
5595 show_ip_pim_bsm_db_cmd
,
5596 "show ip pim bsm-database [vrf NAME] [json]",
5600 "PIM cached bsm packets information\n"
5605 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5606 bool uj
= use_json(argc
, argv
);
5611 pim_show_bsm_db(vrf
->info
, vty
, uj
);
5615 DEFUN (show_ip_pim_bsrp
,
5616 show_ip_pim_bsrp_cmd
,
5617 "show ip pim bsrp-info [vrf NAME] [json]",
5621 "PIM cached group-rp mappings information\n"
5626 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5627 bool uj
= use_json(argc
, argv
);
5632 pim_show_group_rp_mappings_info(vrf
->info
, vty
, uj
);
5637 DEFUN (show_ip_pim_statistics
,
5638 show_ip_pim_statistics_cmd
,
5639 "show ip pim [vrf NAME] statistics [interface WORD] [json]",
5650 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5651 bool uj
= use_json(argc
, argv
);
5656 if (argv_find(argv
, argc
, "WORD", &idx
))
5657 pim_show_statistics(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
5659 pim_show_statistics(vrf
->info
, vty
, NULL
, uj
);
5664 static void show_multicast_interfaces(struct pim_instance
*pim
, struct vty
*vty
,
5667 struct interface
*ifp
;
5668 json_object
*json
= NULL
;
5669 json_object
*json_row
= NULL
;
5674 json
= json_object_new_object();
5677 "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut\n");
5679 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
5680 struct pim_interface
*pim_ifp
;
5681 struct in_addr ifaddr
;
5682 struct sioc_vif_req vreq
;
5684 pim_ifp
= ifp
->info
;
5689 memset(&vreq
, 0, sizeof(vreq
));
5690 vreq
.vifi
= pim_ifp
->mroute_vif_index
;
5692 if (ioctl(pim
->mroute_socket
, SIOCGETVIFCNT
, &vreq
)) {
5694 "ioctl(SIOCGETVIFCNT=%lu) failure for interface %s vif_index=%d: errno=%d: %s",
5695 (unsigned long)SIOCGETVIFCNT
, ifp
->name
,
5696 pim_ifp
->mroute_vif_index
, errno
,
5697 safe_strerror(errno
));
5700 ifaddr
= pim_ifp
->primary_address
;
5702 json_row
= json_object_new_object();
5703 json_object_string_add(json_row
, "name", ifp
->name
);
5704 json_object_string_add(json_row
, "state",
5705 if_is_up(ifp
) ? "up" : "down");
5706 json_object_string_add(
5707 json_row
, "address",
5708 inet_ntoa(pim_ifp
->primary_address
));
5709 json_object_int_add(json_row
, "ifIndex", ifp
->ifindex
);
5710 json_object_int_add(json_row
, "vif",
5711 pim_ifp
->mroute_vif_index
);
5712 json_object_int_add(json_row
, "pktsIn",
5713 (unsigned long)vreq
.icount
);
5714 json_object_int_add(json_row
, "pktsOut",
5715 (unsigned long)vreq
.ocount
);
5716 json_object_int_add(json_row
, "bytesIn",
5717 (unsigned long)vreq
.ibytes
);
5718 json_object_int_add(json_row
, "bytesOut",
5719 (unsigned long)vreq
.obytes
);
5720 json_object_object_add(json
, ifp
->name
, json_row
);
5723 "%-16s %-15s %3d %3d %7lu %7lu %10lu %10lu\n",
5724 ifp
->name
, inet_ntoa(ifaddr
), ifp
->ifindex
,
5725 pim_ifp
->mroute_vif_index
,
5726 (unsigned long)vreq
.icount
,
5727 (unsigned long)vreq
.ocount
,
5728 (unsigned long)vreq
.ibytes
,
5729 (unsigned long)vreq
.obytes
);
5734 vty_out(vty
, "%s\n",
5735 json_object_to_json_string_ext(
5736 json
, JSON_C_TO_STRING_PRETTY
));
5737 json_object_free(json
);
5741 static void pim_cmd_show_ip_multicast_helper(struct pim_instance
*pim
,
5744 struct vrf
*vrf
= pim
->vrf
;
5745 time_t now
= pim_time_monotonic_sec();
5751 vty_out(vty
, "Router MLAG Role: %s\n",
5752 mlag_role2str(router
->mlag_role
, mlag_role
, sizeof(mlag_role
)));
5753 vty_out(vty
, "Mroute socket descriptor:");
5755 vty_out(vty
, " %d(%s)\n", pim
->mroute_socket
, vrf
->name
);
5757 pim_time_uptime(uptime
, sizeof(uptime
),
5758 now
- pim
->mroute_socket_creation
);
5759 vty_out(vty
, "Mroute socket uptime: %s\n", uptime
);
5763 pim_zebra_zclient_update(vty
);
5764 pim_zlookup_show_ip_multicast(vty
);
5767 vty_out(vty
, "Maximum highest VifIndex: %d\n", PIM_MAX_USABLE_VIFS
);
5770 vty_out(vty
, "Upstream Join Timer: %d secs\n", router
->t_periodic
);
5771 vty_out(vty
, "Join/Prune Holdtime: %d secs\n", PIM_JP_HOLDTIME
);
5772 vty_out(vty
, "PIM ECMP: %s\n", pim
->ecmp_enable
? "Enable" : "Disable");
5773 vty_out(vty
, "PIM ECMP Rebalance: %s\n",
5774 pim
->ecmp_rebalance_enable
? "Enable" : "Disable");
5778 show_rpf_refresh_stats(vty
, pim
, now
, NULL
);
5782 show_scan_oil_stats(pim
, vty
, now
);
5784 show_multicast_interfaces(pim
, vty
, false);
5787 DEFUN (show_ip_multicast
,
5788 show_ip_multicast_cmd
,
5789 "show ip multicast [vrf NAME]",
5793 "Multicast global information\n")
5796 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5801 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
5806 DEFUN (show_ip_multicast_vrf_all
,
5807 show_ip_multicast_vrf_all_cmd
,
5808 "show ip multicast vrf all",
5812 "Multicast global information\n")
5814 bool uj
= use_json(argc
, argv
);
5820 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5824 vty_out(vty
, " \"%s\": ", vrf
->name
);
5827 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5828 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
5831 vty_out(vty
, "}\n");
5836 DEFUN(show_ip_multicast_count
,
5837 show_ip_multicast_count_cmd
,
5838 "show ip multicast count [vrf NAME] [json]",
5840 "Multicast global information\n"
5841 "Data packet count\n"
5842 VRF_CMD_HELP_STR JSON_STR
)
5845 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5846 bool uj
= use_json(argc
, argv
);
5851 show_multicast_interfaces(vrf
->info
, vty
, uj
);
5856 DEFUN(show_ip_multicast_count_vrf_all
,
5857 show_ip_multicast_count_vrf_all_cmd
,
5858 "show ip multicast count vrf all [json]",
5860 "Multicast global information\n"
5861 "Data packet count\n"
5862 VRF_CMD_HELP_STR JSON_STR
)
5864 bool uj
= use_json(argc
, argv
);
5871 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5876 vty_out(vty
, " \"%s\": ", vrf
->name
);
5879 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5881 show_multicast_interfaces(vrf
->info
, vty
, uj
);
5885 vty_out(vty
, "}\n");
5890 static void show_mroute(struct pim_instance
*pim
, struct vty
*vty
,
5891 struct prefix_sg
*sg
, bool fill
, bool uj
)
5893 struct listnode
*node
;
5894 struct channel_oil
*c_oil
;
5895 struct static_route
*s_route
;
5897 json_object
*json
= NULL
;
5898 json_object
*json_group
= NULL
;
5899 json_object
*json_source
= NULL
;
5900 json_object
*json_oil
= NULL
;
5901 json_object
*json_ifp_out
= NULL
;
5904 char grp_str
[INET_ADDRSTRLEN
];
5905 char src_str
[INET_ADDRSTRLEN
];
5906 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
5907 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
5909 struct interface
*ifp_in
;
5911 char state_str
[PIM_REG_STATE_STR_LEN
];
5912 char mroute_uptime
[10];
5915 json
= json_object_new_object();
5917 vty_out(vty
, "IP Multicast Routing Table\n");
5918 vty_out(vty
, "Flags: S - Sparse, C - Connected, P - Pruned\n");
5920 " R - RP-bit set, F - Register flag, T - SPT-bit set\n");
5922 "\nSource Group Flags Proto Input Output TTL Uptime\n");
5925 now
= pim_time_monotonic_sec();
5927 /* print list of PIM and IGMP routes */
5928 frr_each (rb_pim_oil
, &pim
->channel_oil_head
, c_oil
) {
5931 if (!c_oil
->installed
)
5934 if (sg
->grp
.s_addr
!= 0 &&
5935 sg
->grp
.s_addr
!= c_oil
->oil
.mfcc_mcastgrp
.s_addr
)
5937 if (sg
->src
.s_addr
!= 0 &&
5938 sg
->src
.s_addr
!= c_oil
->oil
.mfcc_origin
.s_addr
)
5941 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
5943 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
5946 strlcpy(state_str
, "S", sizeof(state_str
));
5947 /* When a non DR receives a igmp join, it creates a (*,G)
5948 * channel_oil without any upstream creation */
5950 if (PIM_UPSTREAM_FLAG_TEST_SRC_IGMP(c_oil
->up
->flags
))
5951 strlcat(state_str
, "C", sizeof(state_str
));
5952 if (pim_upstream_is_sg_rpt(c_oil
->up
))
5953 strlcat(state_str
, "R", sizeof(state_str
));
5954 if (PIM_UPSTREAM_FLAG_TEST_FHR(c_oil
->up
->flags
))
5955 strlcat(state_str
, "F", sizeof(state_str
));
5956 if (c_oil
->up
->sptbit
== PIM_UPSTREAM_SPTBIT_TRUE
)
5957 strlcat(state_str
, "T", sizeof(state_str
));
5959 if (pim_channel_oil_empty(c_oil
))
5960 strlcat(state_str
, "P", sizeof(state_str
));
5962 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
5965 strlcpy(in_ifname
, ifp_in
->name
, sizeof(in_ifname
));
5967 strlcpy(in_ifname
, "<iif?>", sizeof(in_ifname
));
5970 pim_time_uptime(mroute_uptime
, sizeof(mroute_uptime
),
5971 now
- c_oil
->mroute_creation
);
5975 /* Find the group, create it if it doesn't exist */
5976 json_object_object_get_ex(json
, grp_str
, &json_group
);
5979 json_group
= json_object_new_object();
5980 json_object_object_add(json
, grp_str
,
5984 /* Find the source nested under the group, create it if
5987 json_object_object_get_ex(json_group
, src_str
,
5991 json_source
= json_object_new_object();
5992 json_object_object_add(json_group
, src_str
,
5996 /* Find the inbound interface nested under the source,
5997 * create it if it doesn't exist */
5998 json_object_int_add(json_source
, "installed",
6000 json_object_int_add(json_source
, "refCount",
6001 c_oil
->oil_ref_count
);
6002 json_object_int_add(json_source
, "oilSize",
6004 json_object_int_add(json_source
, "OilInheritedRescan",
6005 c_oil
->oil_inherited_rescan
);
6006 json_object_string_add(json_source
, "iif", in_ifname
);
6007 json_object_string_add(json_source
, "upTime",
6012 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
6014 struct interface
*ifp_out
;
6017 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
6021 /* do not display muted OIFs */
6022 if (c_oil
->oif_flags
[oif_vif_index
]
6023 & PIM_OIF_FLAG_MUTE
)
6026 if (c_oil
->oil
.mfcc_parent
== oif_vif_index
&&
6027 !pim_mroute_allow_iif_in_oil(c_oil
,
6031 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
6035 strlcpy(out_ifname
, ifp_out
->name
, sizeof(out_ifname
));
6037 strlcpy(out_ifname
, "<oif?>", sizeof(out_ifname
));
6040 json_ifp_out
= json_object_new_object();
6041 json_object_string_add(json_ifp_out
, "source",
6043 json_object_string_add(json_ifp_out
, "group",
6046 if (c_oil
->oif_flags
[oif_vif_index
]
6047 & PIM_OIF_FLAG_PROTO_PIM
)
6048 json_object_boolean_true_add(
6049 json_ifp_out
, "protocolPim");
6051 if (c_oil
->oif_flags
[oif_vif_index
]
6052 & PIM_OIF_FLAG_PROTO_IGMP
)
6053 json_object_boolean_true_add(
6054 json_ifp_out
, "protocolIgmp");
6056 if (c_oil
->oif_flags
[oif_vif_index
]
6057 & PIM_OIF_FLAG_PROTO_VXLAN
)
6058 json_object_boolean_true_add(
6059 json_ifp_out
, "protocolVxlan");
6061 if (c_oil
->oif_flags
[oif_vif_index
]
6062 & PIM_OIF_FLAG_PROTO_STAR
)
6063 json_object_boolean_true_add(
6065 "protocolInherited");
6067 json_object_string_add(json_ifp_out
,
6070 json_object_int_add(json_ifp_out
, "iVifI",
6071 c_oil
->oil
.mfcc_parent
);
6072 json_object_string_add(json_ifp_out
,
6073 "outboundInterface",
6075 json_object_int_add(json_ifp_out
, "oVifI",
6077 json_object_int_add(json_ifp_out
, "ttl", ttl
);
6078 json_object_string_add(json_ifp_out
, "upTime",
6080 json_object_string_add(json_source
, "flags",
6083 json_oil
= json_object_new_object();
6084 json_object_object_add(json_source
,
6087 json_object_object_add(json_oil
, out_ifname
,
6090 if (c_oil
->oif_flags
[oif_vif_index
]
6091 & PIM_OIF_FLAG_PROTO_PIM
) {
6092 strlcpy(proto
, "PIM", sizeof(proto
));
6095 if (c_oil
->oif_flags
[oif_vif_index
]
6096 & PIM_OIF_FLAG_PROTO_IGMP
) {
6097 strlcpy(proto
, "IGMP", sizeof(proto
));
6100 if (c_oil
->oif_flags
[oif_vif_index
]
6101 & PIM_OIF_FLAG_PROTO_VXLAN
) {
6102 strlcpy(proto
, "VxLAN", sizeof(proto
));
6105 if (c_oil
->oif_flags
[oif_vif_index
]
6106 & PIM_OIF_FLAG_PROTO_STAR
) {
6107 strlcpy(proto
, "STAR", sizeof(proto
));
6111 "%-15s %-15s %-15s %-6s %-16s %-16s %-3d %8s\n",
6112 src_str
, grp_str
, state_str
, proto
,
6113 in_ifname
, out_ifname
, ttl
,
6119 in_ifname
[0] = '\0';
6120 state_str
[0] = '\0';
6121 mroute_uptime
[0] = '\0';
6127 if (!uj
&& !found_oif
) {
6129 "%-15s %-15s %-15s %-6s %-16s %-16s %-3d %8s\n",
6130 src_str
, grp_str
, state_str
, "none", in_ifname
,
6131 "none", 0, "--:--:--");
6135 /* Print list of static routes */
6136 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
6139 if (!s_route
->c_oil
.installed
)
6142 pim_inet4_dump("<group?>", s_route
->group
, grp_str
,
6144 pim_inet4_dump("<source?>", s_route
->source
, src_str
,
6146 ifp_in
= pim_if_find_by_vif_index(pim
, s_route
->iif
);
6150 strlcpy(in_ifname
, ifp_in
->name
, sizeof(in_ifname
));
6152 strlcpy(in_ifname
, "<iif?>", sizeof(in_ifname
));
6156 /* Find the group, create it if it doesn't exist */
6157 json_object_object_get_ex(json
, grp_str
, &json_group
);
6160 json_group
= json_object_new_object();
6161 json_object_object_add(json
, grp_str
,
6165 /* Find the source nested under the group, create it if
6166 * it doesn't exist */
6167 json_object_object_get_ex(json_group
, src_str
,
6171 json_source
= json_object_new_object();
6172 json_object_object_add(json_group
, src_str
,
6176 json_object_string_add(json_source
, "iif", in_ifname
);
6179 strlcpy(proto
, "STATIC", sizeof(proto
));
6182 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
6184 struct interface
*ifp_out
;
6185 char oif_uptime
[10];
6188 ttl
= s_route
->oif_ttls
[oif_vif_index
];
6192 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
6194 oif_uptime
, sizeof(oif_uptime
),
6197 .oif_creation
[oif_vif_index
]);
6201 strlcpy(out_ifname
, ifp_out
->name
, sizeof(out_ifname
));
6203 strlcpy(out_ifname
, "<oif?>", sizeof(out_ifname
));
6206 json_ifp_out
= json_object_new_object();
6207 json_object_string_add(json_ifp_out
, "source",
6209 json_object_string_add(json_ifp_out
, "group",
6211 json_object_boolean_true_add(json_ifp_out
,
6213 json_object_string_add(json_ifp_out
,
6216 json_object_int_add(
6217 json_ifp_out
, "iVifI",
6218 s_route
->c_oil
.oil
.mfcc_parent
);
6219 json_object_string_add(json_ifp_out
,
6220 "outboundInterface",
6222 json_object_int_add(json_ifp_out
, "oVifI",
6224 json_object_int_add(json_ifp_out
, "ttl", ttl
);
6225 json_object_string_add(json_ifp_out
, "upTime",
6228 json_oil
= json_object_new_object();
6229 json_object_object_add(json_source
,
6232 json_object_object_add(json_oil
, out_ifname
,
6236 "%-15s %-15s %-6s %-16s %-16s %-3d %8s %s\n",
6237 src_str
, grp_str
, proto
, in_ifname
,
6238 out_ifname
, ttl
, oif_uptime
,
6240 if (first
&& !fill
) {
6243 in_ifname
[0] = '\0';
6249 if (!uj
&& !found_oif
) {
6251 "%-15s %-15s %-6s %-16s %-16s %-3d %8s %s\n",
6252 src_str
, grp_str
, proto
, in_ifname
, "none", 0,
6253 "--:--:--", pim
->vrf
->name
);
6258 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
6259 json
, JSON_C_TO_STRING_PRETTY
));
6260 json_object_free(json
);
6264 DEFPY (show_ip_mroute
,
6266 "show ip mroute [vrf NAME] [A.B.C.D$s_or_g [A.B.C.D$g]] [fill$fill] [json$json]",
6271 "The Source or Group\n"
6273 "Fill in Assumed data\n"
6276 struct prefix_sg sg
= {0};
6277 struct pim_instance
*pim
;
6280 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
6283 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
6286 pim
= pim_get_pim_instance(v
->vrf_id
);
6289 vty_out(vty
, "%% Unable to find pim instance\n");
6293 if (s_or_g
.s_addr
!= 0) {
6294 if (g
.s_addr
!= 0) {
6300 show_mroute(pim
, vty
, &sg
, !!fill
, !!json
);
6304 DEFUN (show_ip_mroute_vrf_all
,
6305 show_ip_mroute_vrf_all_cmd
,
6306 "show ip mroute vrf all [fill] [json]",
6311 "Fill in Assumed data\n"
6314 struct prefix_sg sg
= {0};
6315 bool uj
= use_json(argc
, argv
);
6321 if (argv_find(argv
, argc
, "fill", &idx
))
6326 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
6330 vty_out(vty
, " \"%s\": ", vrf
->name
);
6333 vty_out(vty
, "VRF: %s\n", vrf
->name
);
6334 show_mroute(vrf
->info
, vty
, &sg
, fill
, uj
);
6337 vty_out(vty
, "}\n");
6342 DEFUN (clear_ip_mroute_count
,
6343 clear_ip_mroute_count_cmd
,
6344 "clear ip mroute [vrf NAME] count",
6349 "Route and packet count data\n")
6352 struct listnode
*node
;
6353 struct channel_oil
*c_oil
;
6354 struct static_route
*sr
;
6355 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6356 struct pim_instance
*pim
;
6362 frr_each(rb_pim_oil
, &pim
->channel_oil_head
, c_oil
) {
6363 if (!c_oil
->installed
)
6366 pim_mroute_update_counters(c_oil
);
6367 c_oil
->cc
.origpktcnt
= c_oil
->cc
.pktcnt
;
6368 c_oil
->cc
.origbytecnt
= c_oil
->cc
.bytecnt
;
6369 c_oil
->cc
.origwrong_if
= c_oil
->cc
.wrong_if
;
6372 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, sr
)) {
6373 if (!sr
->c_oil
.installed
)
6376 pim_mroute_update_counters(&sr
->c_oil
);
6378 sr
->c_oil
.cc
.origpktcnt
= sr
->c_oil
.cc
.pktcnt
;
6379 sr
->c_oil
.cc
.origbytecnt
= sr
->c_oil
.cc
.bytecnt
;
6380 sr
->c_oil
.cc
.origwrong_if
= sr
->c_oil
.cc
.wrong_if
;
6385 static void show_mroute_count_per_channel_oil(struct channel_oil
*c_oil
,
6389 char group_str
[INET_ADDRSTRLEN
];
6390 char source_str
[INET_ADDRSTRLEN
];
6391 json_object
*json_group
= NULL
;
6392 json_object
*json_source
= NULL
;
6394 if (!c_oil
->installed
)
6397 pim_mroute_update_counters(c_oil
);
6399 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, group_str
,
6401 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, source_str
,
6402 sizeof(source_str
));
6405 json_object_object_get_ex(json
, group_str
, &json_group
);
6408 json_group
= json_object_new_object();
6409 json_object_object_add(json
, group_str
, json_group
);
6412 json_source
= json_object_new_object();
6413 json_object_object_add(json_group
, source_str
, json_source
);
6414 json_object_int_add(json_source
, "lastUsed",
6415 c_oil
->cc
.lastused
/ 100);
6416 json_object_int_add(json_source
, "packets", c_oil
->cc
.pktcnt
);
6417 json_object_int_add(json_source
, "bytes", c_oil
->cc
.bytecnt
);
6418 json_object_int_add(json_source
, "wrongIf", c_oil
->cc
.wrong_if
);
6421 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
6422 source_str
, group_str
, c_oil
->cc
.lastused
/ 100,
6423 c_oil
->cc
.pktcnt
- c_oil
->cc
.origpktcnt
,
6424 c_oil
->cc
.bytecnt
- c_oil
->cc
.origbytecnt
,
6425 c_oil
->cc
.wrong_if
- c_oil
->cc
.origwrong_if
);
6429 static void show_mroute_count(struct pim_instance
*pim
, struct vty
*vty
,
6432 struct listnode
*node
;
6433 struct channel_oil
*c_oil
;
6434 struct static_route
*sr
;
6435 json_object
*json
= NULL
;
6438 json
= json_object_new_object();
6443 "Source Group LastUsed Packets Bytes WrongIf \n");
6446 /* Print PIM and IGMP route counts */
6447 frr_each (rb_pim_oil
, &pim
->channel_oil_head
, c_oil
)
6448 show_mroute_count_per_channel_oil(c_oil
, json
, vty
);
6450 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, sr
))
6451 show_mroute_count_per_channel_oil(&sr
->c_oil
, json
, vty
);
6454 vty_out(vty
, "%s\n",
6455 json_object_to_json_string_ext(
6456 json
, JSON_C_TO_STRING_PRETTY
));
6457 json_object_free(json
);
6461 DEFUN (show_ip_mroute_count
,
6462 show_ip_mroute_count_cmd
,
6463 "show ip mroute [vrf NAME] count [json]",
6468 "Route and packet count data\n"
6472 bool uj
= use_json(argc
, argv
);
6473 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6478 show_mroute_count(vrf
->info
, vty
, uj
);
6482 DEFUN (show_ip_mroute_count_vrf_all
,
6483 show_ip_mroute_count_vrf_all_cmd
,
6484 "show ip mroute vrf all count [json]",
6489 "Route and packet count data\n"
6492 bool uj
= use_json(argc
, argv
);
6498 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
6502 vty_out(vty
, " \"%s\": ", vrf
->name
);
6505 vty_out(vty
, "VRF: %s\n", vrf
->name
);
6506 show_mroute_count(vrf
->info
, vty
, uj
);
6509 vty_out(vty
, "}\n");
6514 static void show_mroute_summary(struct pim_instance
*pim
, struct vty
*vty
,
6517 struct listnode
*node
;
6518 struct channel_oil
*c_oil
;
6519 struct static_route
*s_route
;
6520 uint32_t starg_sw_mroute_cnt
= 0;
6521 uint32_t sg_sw_mroute_cnt
= 0;
6522 uint32_t starg_hw_mroute_cnt
= 0;
6523 uint32_t sg_hw_mroute_cnt
= 0;
6524 json_object
*json_starg
= NULL
;
6525 json_object
*json_sg
= NULL
;
6528 vty_out(vty
, "Mroute Type Installed/Total\n");
6530 frr_each (rb_pim_oil
, &pim
->channel_oil_head
, c_oil
) {
6531 if (!c_oil
->installed
) {
6532 if (c_oil
->oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
6533 starg_sw_mroute_cnt
++;
6537 if (c_oil
->oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
6538 starg_hw_mroute_cnt
++;
6544 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
6545 if (!s_route
->c_oil
.installed
) {
6546 if (s_route
->c_oil
.oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
6547 starg_sw_mroute_cnt
++;
6551 if (s_route
->c_oil
.oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
6552 starg_hw_mroute_cnt
++;
6559 vty_out(vty
, "%-20s %u/%u\n", "(*, G)", starg_hw_mroute_cnt
,
6560 starg_sw_mroute_cnt
+ starg_hw_mroute_cnt
);
6561 vty_out(vty
, "%-20s %u/%u\n", "(S, G)", sg_hw_mroute_cnt
,
6562 sg_sw_mroute_cnt
+ sg_hw_mroute_cnt
);
6563 vty_out(vty
, "------\n");
6564 vty_out(vty
, "%-20s %u/%u\n", "Total",
6565 (starg_hw_mroute_cnt
+ sg_hw_mroute_cnt
),
6566 (starg_sw_mroute_cnt
+ starg_hw_mroute_cnt
6567 + sg_sw_mroute_cnt
+ sg_hw_mroute_cnt
));
6569 /* (*,G) route details */
6570 json_starg
= json_object_new_object();
6571 json_object_object_add(json
, "wildcardGroup", json_starg
);
6573 json_object_int_add(json_starg
, "installed",
6574 starg_hw_mroute_cnt
);
6575 json_object_int_add(json_starg
, "total",
6576 starg_sw_mroute_cnt
+ starg_hw_mroute_cnt
);
6578 /* (S, G) route details */
6579 json_sg
= json_object_new_object();
6580 json_object_object_add(json
, "sourceGroup", json_sg
);
6582 json_object_int_add(json_sg
, "installed", sg_hw_mroute_cnt
);
6583 json_object_int_add(json_sg
, "total",
6584 sg_sw_mroute_cnt
+ sg_hw_mroute_cnt
);
6586 json_object_int_add(json
, "totalNumOfInstalledMroutes",
6587 starg_hw_mroute_cnt
+ sg_hw_mroute_cnt
);
6588 json_object_int_add(json
, "totalNumOfMroutes",
6589 starg_sw_mroute_cnt
+ starg_hw_mroute_cnt
6591 + sg_hw_mroute_cnt
);
6595 DEFUN (show_ip_mroute_summary
,
6596 show_ip_mroute_summary_cmd
,
6597 "show ip mroute [vrf NAME] summary [json]",
6602 "Summary of all mroutes\n"
6606 bool uj
= use_json(argc
, argv
);
6607 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6608 json_object
*json
= NULL
;
6611 json
= json_object_new_object();
6616 show_mroute_summary(vrf
->info
, vty
, json
);
6619 vty_out(vty
, "%s\n",
6620 json_object_to_json_string_ext(
6621 json
, JSON_C_TO_STRING_PRETTY
));
6622 json_object_free(json
);
6627 DEFUN (show_ip_mroute_summary_vrf_all
,
6628 show_ip_mroute_summary_vrf_all_cmd
,
6629 "show ip mroute vrf all summary [json]",
6634 "Summary of all mroutes\n"
6638 bool uj
= use_json(argc
, argv
);
6639 json_object
*json
= NULL
;
6640 json_object
*json_vrf
= NULL
;
6643 json
= json_object_new_object();
6645 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
6647 json_vrf
= json_object_new_object();
6649 vty_out(vty
, "VRF: %s\n", vrf
->name
);
6651 show_mroute_summary(vrf
->info
, vty
, json_vrf
);
6654 json_object_object_add(json
, vrf
->name
, json_vrf
);
6658 vty_out(vty
, "%s\n",
6659 json_object_to_json_string_ext(
6660 json
, JSON_C_TO_STRING_PRETTY
));
6661 json_object_free(json
);
6669 "show ip rib [vrf NAME] A.B.C.D",
6674 "Unicast address\n")
6677 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6678 struct in_addr addr
;
6679 const char *addr_str
;
6680 struct pim_nexthop nexthop
;
6681 char nexthop_addr_str
[PREFIX_STRLEN
];
6687 memset(&nexthop
, 0, sizeof(nexthop
));
6688 argv_find(argv
, argc
, "A.B.C.D", &idx
);
6689 addr_str
= argv
[idx
]->arg
;
6690 result
= inet_pton(AF_INET
, addr_str
, &addr
);
6692 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
6693 errno
, safe_strerror(errno
));
6697 if (!pim_nexthop_lookup(vrf
->info
, &nexthop
, addr
, 0)) {
6699 "Failure querying RIB nexthop for unicast address %s\n",
6705 "Address NextHop Interface Metric Preference\n");
6707 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
6708 nexthop_addr_str
, sizeof(nexthop_addr_str
));
6710 vty_out(vty
, "%-15s %-15s %-9s %6d %10d\n", addr_str
, nexthop_addr_str
,
6711 nexthop
.interface
? nexthop
.interface
->name
: "<ifname?>",
6712 nexthop
.mrib_route_metric
, nexthop
.mrib_metric_preference
);
6717 static void show_ssmpingd(struct pim_instance
*pim
, struct vty
*vty
)
6719 struct listnode
*node
;
6720 struct ssmpingd_sock
*ss
;
6724 "Source Socket Address Port Uptime Requests\n");
6726 if (!pim
->ssmpingd_list
)
6729 now
= pim_time_monotonic_sec();
6731 for (ALL_LIST_ELEMENTS_RO(pim
->ssmpingd_list
, node
, ss
)) {
6732 char source_str
[INET_ADDRSTRLEN
];
6734 struct sockaddr_in bind_addr
;
6735 socklen_t len
= sizeof(bind_addr
);
6736 char bind_addr_str
[INET_ADDRSTRLEN
];
6738 pim_inet4_dump("<src?>", ss
->source_addr
, source_str
,
6739 sizeof(source_str
));
6741 if (pim_socket_getsockname(
6742 ss
->sock_fd
, (struct sockaddr
*)&bind_addr
, &len
)) {
6744 "%% Failure reading socket name for ssmpingd source %s on fd=%d\n",
6745 source_str
, ss
->sock_fd
);
6748 pim_inet4_dump("<addr?>", bind_addr
.sin_addr
, bind_addr_str
,
6749 sizeof(bind_addr_str
));
6750 pim_time_uptime(ss_uptime
, sizeof(ss_uptime
),
6751 now
- ss
->creation
);
6753 vty_out(vty
, "%-15s %6d %-15s %5d %8s %8lld\n", source_str
,
6754 ss
->sock_fd
, bind_addr_str
, ntohs(bind_addr
.sin_port
),
6755 ss_uptime
, (long long)ss
->requests
);
6759 DEFUN (show_ip_ssmpingd
,
6760 show_ip_ssmpingd_cmd
,
6761 "show ip ssmpingd [vrf NAME]",
6768 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6773 show_ssmpingd(vrf
->info
, vty
);
6777 static int pim_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
6778 const char *rp
, const char *group
,
6783 result
= pim_rp_new_config(pim
, rp
, group
, plist
);
6785 if (result
== PIM_GROUP_BAD_ADDR_MASK_COMBO
) {
6786 vty_out(vty
, "%% Inconsistent address and mask: %s\n",
6787 group
? group
: "No Group Address");
6788 return CMD_WARNING_CONFIG_FAILED
;
6791 if (result
== PIM_GROUP_BAD_ADDRESS
) {
6792 vty_out(vty
, "%% Bad group address specified: %s\n",
6793 group
? group
: "No Group Address");
6794 return CMD_WARNING_CONFIG_FAILED
;
6797 if (result
== PIM_RP_BAD_ADDRESS
) {
6798 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
6799 return CMD_WARNING_CONFIG_FAILED
;
6802 if (result
== PIM_RP_NO_PATH
) {
6803 vty_out(vty
, "%% No Path to RP address specified: %s\n", rp
);
6807 if (result
== PIM_GROUP_OVERLAP
) {
6809 "%% Group range specified cannot exact match another\n");
6810 return CMD_WARNING_CONFIG_FAILED
;
6813 if (result
== PIM_GROUP_PFXLIST_OVERLAP
) {
6815 "%% This group is already covered by a RP prefix-list\n");
6816 return CMD_WARNING_CONFIG_FAILED
;
6819 if (result
== PIM_RP_PFXLIST_IN_USE
) {
6821 "%% The same prefix-list cannot be applied to multiple RPs\n");
6822 return CMD_WARNING_CONFIG_FAILED
;
6828 static int pim_cmd_spt_switchover(struct pim_instance
*pim
,
6829 enum pim_spt_switchover spt
,
6832 pim
->spt
.switchover
= spt
;
6834 switch (pim
->spt
.switchover
) {
6835 case PIM_SPT_IMMEDIATE
:
6836 XFREE(MTYPE_PIM_PLIST_NAME
, pim
->spt
.plist
);
6838 pim_upstream_add_lhr_star_pimreg(pim
);
6840 case PIM_SPT_INFINITY
:
6841 pim_upstream_remove_lhr_star_pimreg(pim
, plist
);
6843 XFREE(MTYPE_PIM_PLIST_NAME
, pim
->spt
.plist
);
6847 XSTRDUP(MTYPE_PIM_PLIST_NAME
, plist
);
6854 DEFUN (ip_pim_spt_switchover_infinity
,
6855 ip_pim_spt_switchover_infinity_cmd
,
6856 "ip pim spt-switchover infinity-and-beyond",
6860 "Never switch to SPT Tree\n")
6862 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6863 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, NULL
);
6866 DEFUN (ip_pim_spt_switchover_infinity_plist
,
6867 ip_pim_spt_switchover_infinity_plist_cmd
,
6868 "ip pim spt-switchover infinity-and-beyond prefix-list WORD",
6872 "Never switch to SPT Tree\n"
6873 "Prefix-List to control which groups to switch\n"
6874 "Prefix-List name\n")
6876 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6877 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, argv
[5]->arg
);
6880 DEFUN (no_ip_pim_spt_switchover_infinity
,
6881 no_ip_pim_spt_switchover_infinity_cmd
,
6882 "no ip pim spt-switchover infinity-and-beyond",
6887 "Never switch to SPT Tree\n")
6889 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6890 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
6893 DEFUN (no_ip_pim_spt_switchover_infinity_plist
,
6894 no_ip_pim_spt_switchover_infinity_plist_cmd
,
6895 "no ip pim spt-switchover infinity-and-beyond prefix-list WORD",
6900 "Never switch to SPT Tree\n"
6901 "Prefix-List to control which groups to switch\n"
6902 "Prefix-List name\n")
6904 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6905 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
6908 DEFPY (pim_register_accept_list
,
6909 pim_register_accept_list_cmd
,
6910 "[no] ip pim register-accept-list WORD$word",
6914 "Only accept registers from a specific source prefix list\n"
6915 "Prefix-List name\n")
6917 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6920 XFREE(MTYPE_PIM_PLIST_NAME
, pim
->register_plist
);
6922 XFREE(MTYPE_PIM_PLIST_NAME
, pim
->register_plist
);
6923 pim
->register_plist
= XSTRDUP(MTYPE_PIM_PLIST_NAME
, word
);
6928 DEFUN (ip_pim_joinprune_time
,
6929 ip_pim_joinprune_time_cmd
,
6930 "ip pim join-prune-interval (60-600)",
6932 "pim multicast routing\n"
6933 "Join Prune Send Interval\n"
6936 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6937 router
->t_periodic
= atoi(argv
[3]->arg
);
6941 DEFUN (no_ip_pim_joinprune_time
,
6942 no_ip_pim_joinprune_time_cmd
,
6943 "no ip pim join-prune-interval (60-600)",
6946 "pim multicast routing\n"
6947 "Join Prune Send Interval\n"
6950 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6951 router
->t_periodic
= PIM_DEFAULT_T_PERIODIC
;
6955 DEFUN (ip_pim_register_suppress
,
6956 ip_pim_register_suppress_cmd
,
6957 "ip pim register-suppress-time (5-60000)",
6959 "pim multicast routing\n"
6960 "Register Suppress Timer\n"
6963 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6964 router
->register_suppress_time
= atoi(argv
[3]->arg
);
6968 DEFUN (no_ip_pim_register_suppress
,
6969 no_ip_pim_register_suppress_cmd
,
6970 "no ip pim register-suppress-time (5-60000)",
6973 "pim multicast routing\n"
6974 "Register Suppress Timer\n"
6977 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6978 router
->register_suppress_time
= PIM_REGISTER_SUPPRESSION_TIME_DEFAULT
;
6982 DEFUN (ip_pim_rp_keep_alive
,
6983 ip_pim_rp_keep_alive_cmd
,
6984 "ip pim rp keep-alive-timer (31-60000)",
6986 "pim multicast routing\n"
6988 "Keep alive Timer\n"
6991 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6992 pim
->rp_keep_alive_time
= atoi(argv
[4]->arg
);
6996 DEFUN (no_ip_pim_rp_keep_alive
,
6997 no_ip_pim_rp_keep_alive_cmd
,
6998 "no ip pim rp keep-alive-timer (31-60000)",
7001 "pim multicast routing\n"
7003 "Keep alive Timer\n"
7006 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7007 pim
->rp_keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
7011 DEFUN (ip_pim_keep_alive
,
7012 ip_pim_keep_alive_cmd
,
7013 "ip pim keep-alive-timer (31-60000)",
7015 "pim multicast routing\n"
7016 "Keep alive Timer\n"
7019 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7020 pim
->keep_alive_time
= atoi(argv
[3]->arg
);
7024 DEFUN (no_ip_pim_keep_alive
,
7025 no_ip_pim_keep_alive_cmd
,
7026 "no ip pim keep-alive-timer (31-60000)",
7029 "pim multicast routing\n"
7030 "Keep alive Timer\n"
7033 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7034 pim
->keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
7038 DEFUN (ip_pim_packets
,
7040 "ip pim packets (1-100)",
7042 "pim multicast routing\n"
7043 "packets to process at one time per fd\n"
7044 "Number of packets\n")
7046 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7047 router
->packet_process
= atoi(argv
[3]->arg
);
7051 DEFUN (no_ip_pim_packets
,
7052 no_ip_pim_packets_cmd
,
7053 "no ip pim packets (1-100)",
7056 "pim multicast routing\n"
7057 "packets to process at one time per fd\n"
7058 "Number of packets\n")
7060 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7061 router
->packet_process
= PIM_DEFAULT_PACKET_PROCESS
;
7065 DEFPY (igmp_group_watermark
,
7066 igmp_group_watermark_cmd
,
7067 "ip igmp watermark-warn (10-60000)$limit",
7070 "Configure group limit for watermark warning\n"
7071 "Group count to generate watermark warning\n")
7073 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7074 pim
->igmp_watermark_limit
= limit
;
7079 DEFPY (no_igmp_group_watermark
,
7080 no_igmp_group_watermark_cmd
,
7081 "no ip igmp watermark-warn [(10-60000)$limit]",
7085 "Unconfigure group limit for watermark warning\n"
7086 "Group count to generate watermark warning\n")
7088 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7089 pim
->igmp_watermark_limit
= 0;
7094 DEFUN (ip_pim_v6_secondary
,
7095 ip_pim_v6_secondary_cmd
,
7096 "ip pim send-v6-secondary",
7098 "pim multicast routing\n"
7099 "Send v6 secondary addresses\n")
7101 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7102 pim
->send_v6_secondary
= 1;
7107 DEFUN (no_ip_pim_v6_secondary
,
7108 no_ip_pim_v6_secondary_cmd
,
7109 "no ip pim send-v6-secondary",
7112 "pim multicast routing\n"
7113 "Send v6 secondary addresses\n")
7115 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7116 pim
->send_v6_secondary
= 0;
7123 "ip pim rp A.B.C.D [A.B.C.D/M]",
7125 "pim multicast routing\n"
7127 "ip address of RP\n"
7128 "Group Address range to cover\n")
7130 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7133 if (argc
== (idx_ipv4
+ 1))
7134 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
7137 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
7138 argv
[idx_ipv4
+ 1]->arg
, NULL
);
7141 DEFUN (ip_pim_rp_prefix_list
,
7142 ip_pim_rp_prefix_list_cmd
,
7143 "ip pim rp A.B.C.D prefix-list WORD",
7145 "pim multicast routing\n"
7147 "ip address of RP\n"
7148 "group prefix-list filter\n"
7149 "Name of a prefix-list\n")
7151 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7152 return pim_rp_cmd_worker(pim
, vty
, argv
[3]->arg
, NULL
, argv
[5]->arg
);
7155 static int pim_no_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
7156 const char *rp
, const char *group
,
7159 int result
= pim_rp_del_config(pim
, rp
, group
, plist
);
7161 if (result
== PIM_GROUP_BAD_ADDRESS
) {
7162 vty_out(vty
, "%% Bad group address specified: %s\n",
7163 group
? group
: "No Group Address");
7164 return CMD_WARNING_CONFIG_FAILED
;
7167 if (result
== PIM_RP_BAD_ADDRESS
) {
7168 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
7169 return CMD_WARNING_CONFIG_FAILED
;
7172 if (result
== PIM_RP_NOT_FOUND
) {
7173 vty_out(vty
, "%% Unable to find specified RP\n");
7174 return CMD_WARNING_CONFIG_FAILED
;
7180 DEFUN (no_ip_pim_rp
,
7182 "no ip pim rp A.B.C.D [A.B.C.D/M]",
7185 "pim multicast routing\n"
7187 "ip address of RP\n"
7188 "Group Address range to cover\n")
7190 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7191 int idx_ipv4
= 4, idx_group
= 0;
7193 if (argv_find(argv
, argc
, "A.B.C.D/M", &idx_group
))
7194 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
7195 argv
[idx_group
]->arg
, NULL
);
7197 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
7201 DEFUN (no_ip_pim_rp_prefix_list
,
7202 no_ip_pim_rp_prefix_list_cmd
,
7203 "no ip pim rp A.B.C.D prefix-list WORD",
7206 "pim multicast routing\n"
7208 "ip address of RP\n"
7209 "group prefix-list filter\n"
7210 "Name of a prefix-list\n")
7212 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7213 return pim_no_rp_cmd_worker(pim
, vty
, argv
[4]->arg
, NULL
, argv
[6]->arg
);
7216 static int pim_ssm_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
7219 int result
= pim_ssm_range_set(pim
, pim
->vrf_id
, plist
);
7220 int ret
= CMD_WARNING_CONFIG_FAILED
;
7222 if (result
== PIM_SSM_ERR_NONE
)
7226 case PIM_SSM_ERR_NO_VRF
:
7227 vty_out(vty
, "%% VRF doesn't exist\n");
7229 case PIM_SSM_ERR_DUP
:
7230 vty_out(vty
, "%% duplicate config\n");
7234 vty_out(vty
, "%% ssm range config failed\n");
7240 DEFUN (ip_pim_ssm_prefix_list
,
7241 ip_pim_ssm_prefix_list_cmd
,
7242 "ip pim ssm prefix-list WORD",
7244 "pim multicast routing\n"
7245 "Source Specific Multicast\n"
7246 "group range prefix-list filter\n"
7247 "Name of a prefix-list\n")
7249 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7250 return pim_ssm_cmd_worker(pim
, vty
, argv
[4]->arg
);
7253 DEFUN (no_ip_pim_ssm_prefix_list
,
7254 no_ip_pim_ssm_prefix_list_cmd
,
7255 "no ip pim ssm prefix-list",
7258 "pim multicast routing\n"
7259 "Source Specific Multicast\n"
7260 "group range prefix-list filter\n")
7262 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7263 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
7266 DEFUN (no_ip_pim_ssm_prefix_list_name
,
7267 no_ip_pim_ssm_prefix_list_name_cmd
,
7268 "no ip pim ssm prefix-list WORD",
7271 "pim multicast routing\n"
7272 "Source Specific Multicast\n"
7273 "group range prefix-list filter\n"
7274 "Name of a prefix-list\n")
7276 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7277 struct pim_ssm
*ssm
= pim
->ssm_info
;
7279 if (ssm
->plist_name
&& !strcmp(ssm
->plist_name
, argv
[5]->arg
))
7280 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
7282 vty_out(vty
, "%% pim ssm prefix-list %s doesn't exist\n", argv
[5]->arg
);
7284 return CMD_WARNING_CONFIG_FAILED
;
7287 static void ip_pim_ssm_show_group_range(struct pim_instance
*pim
,
7288 struct vty
*vty
, bool uj
)
7290 struct pim_ssm
*ssm
= pim
->ssm_info
;
7291 const char *range_str
=
7292 ssm
->plist_name
? ssm
->plist_name
: PIM_SSM_STANDARD_RANGE
;
7296 json
= json_object_new_object();
7297 json_object_string_add(json
, "ssmGroups", range_str
);
7298 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
7299 json
, JSON_C_TO_STRING_PRETTY
));
7300 json_object_free(json
);
7302 vty_out(vty
, "SSM group range : %s\n", range_str
);
7305 DEFUN (show_ip_pim_ssm_range
,
7306 show_ip_pim_ssm_range_cmd
,
7307 "show ip pim [vrf NAME] group-type [json]",
7316 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
7317 bool uj
= use_json(argc
, argv
);
7322 ip_pim_ssm_show_group_range(vrf
->info
, vty
, uj
);
7327 static void ip_pim_ssm_show_group_type(struct pim_instance
*pim
,
7328 struct vty
*vty
, bool uj
,
7331 struct in_addr group_addr
;
7332 const char *type_str
;
7335 result
= inet_pton(AF_INET
, group
, &group_addr
);
7337 type_str
= "invalid";
7339 if (pim_is_group_224_4(group_addr
))
7341 pim_is_grp_ssm(pim
, group_addr
) ? "SSM" : "ASM";
7343 type_str
= "not-multicast";
7348 json
= json_object_new_object();
7349 json_object_string_add(json
, "groupType", type_str
);
7350 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
7351 json
, JSON_C_TO_STRING_PRETTY
));
7352 json_object_free(json
);
7354 vty_out(vty
, "Group type : %s\n", type_str
);
7357 DEFUN (show_ip_pim_group_type
,
7358 show_ip_pim_group_type_cmd
,
7359 "show ip pim [vrf NAME] group-type A.B.C.D [json]",
7364 "multicast group type\n"
7369 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
7370 bool uj
= use_json(argc
, argv
);
7375 argv_find(argv
, argc
, "A.B.C.D", &idx
);
7376 ip_pim_ssm_show_group_type(vrf
->info
, vty
, uj
, argv
[idx
]->arg
);
7381 DEFUN (show_ip_pim_bsr
,
7382 show_ip_pim_bsr_cmd
,
7383 "show ip pim bsr [json]",
7387 "boot-strap router information\n"
7391 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
7392 bool uj
= use_json(argc
, argv
);
7397 pim_show_bsr(vrf
->info
, vty
, uj
);
7404 "ip ssmpingd [A.B.C.D]",
7409 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7412 struct in_addr source_addr
;
7413 const char *source_str
= (argc
== 3) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
7415 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
7417 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
7418 source_str
, errno
, safe_strerror(errno
));
7419 return CMD_WARNING_CONFIG_FAILED
;
7422 result
= pim_ssmpingd_start(pim
, source_addr
);
7424 vty_out(vty
, "%% Failure starting ssmpingd for source %s: %d\n",
7425 source_str
, result
);
7426 return CMD_WARNING_CONFIG_FAILED
;
7432 DEFUN (no_ip_ssmpingd
,
7434 "no ip ssmpingd [A.B.C.D]",
7440 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7443 struct in_addr source_addr
;
7444 const char *source_str
= (argc
== 4) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
7446 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
7448 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
7449 source_str
, errno
, safe_strerror(errno
));
7450 return CMD_WARNING_CONFIG_FAILED
;
7453 result
= pim_ssmpingd_stop(pim
, source_addr
);
7455 vty_out(vty
, "%% Failure stopping ssmpingd for source %s: %d\n",
7456 source_str
, result
);
7457 return CMD_WARNING_CONFIG_FAILED
;
7467 "pim multicast routing\n"
7468 "Enable PIM ECMP \n")
7470 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7471 pim
->ecmp_enable
= true;
7476 DEFUN (no_ip_pim_ecmp
,
7481 "pim multicast routing\n"
7482 "Disable PIM ECMP \n")
7484 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7485 pim
->ecmp_enable
= false;
7490 DEFUN (ip_pim_ecmp_rebalance
,
7491 ip_pim_ecmp_rebalance_cmd
,
7492 "ip pim ecmp rebalance",
7494 "pim multicast routing\n"
7495 "Enable PIM ECMP \n"
7496 "Enable PIM ECMP Rebalance\n")
7498 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7499 pim
->ecmp_enable
= true;
7500 pim
->ecmp_rebalance_enable
= true;
7505 DEFUN (no_ip_pim_ecmp_rebalance
,
7506 no_ip_pim_ecmp_rebalance_cmd
,
7507 "no ip pim ecmp rebalance",
7510 "pim multicast routing\n"
7511 "Disable PIM ECMP \n"
7512 "Disable PIM ECMP Rebalance\n")
7514 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7515 pim
->ecmp_rebalance_enable
= false;
7520 static int pim_cmd_igmp_start(struct vty
*vty
, struct interface
*ifp
)
7522 struct pim_interface
*pim_ifp
;
7523 struct pim_instance
*pim
;
7524 uint8_t need_startup
= 0;
7526 pim_ifp
= ifp
->info
;
7529 pim
= pim_get_pim_instance(ifp
->vrf_id
);
7530 /* Limit mcast interfaces to number of vifs available */
7531 if (pim
->mcast_if_count
== MAXVIFS
) {
7533 "Max multicast interfaces(%d) Reached. Could not enable IGMP on interface %s\n",
7534 MAXVIFS
, ifp
->name
);
7535 return CMD_WARNING_CONFIG_FAILED
;
7537 (void)pim_if_new(ifp
, true, false, false, false);
7540 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
7541 PIM_IF_DO_IGMP(pim_ifp
->options
);
7546 /* 'ip igmp' executed multiple times, with need_startup
7547 avoid multiple if add all and membership refresh */
7549 pim_if_addr_add_all(ifp
);
7550 pim_if_membership_refresh(ifp
);
7556 DEFUN (interface_ip_igmp
,
7557 interface_ip_igmp_cmd
,
7562 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7564 return pim_cmd_igmp_start(vty
, ifp
);
7567 DEFUN (interface_no_ip_igmp
,
7568 interface_no_ip_igmp_cmd
,
7574 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7575 struct pim_interface
*pim_ifp
= ifp
->info
;
7580 PIM_IF_DONT_IGMP(pim_ifp
->options
);
7582 pim_if_membership_clear(ifp
);
7584 pim_if_addr_del_all_igmp(ifp
);
7586 if (!PIM_IF_TEST_PIM(pim_ifp
->options
)) {
7593 DEFUN (interface_ip_igmp_join
,
7594 interface_ip_igmp_join_cmd
,
7595 "ip igmp join A.B.C.D [A.B.C.D]",
7598 "IGMP join multicast group\n"
7599 "Multicast group address\n"
7602 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7605 const char *group_str
;
7606 const char *source_str
;
7607 struct in_addr group_addr
;
7608 struct in_addr source_addr
;
7612 group_str
= argv
[idx_ipv4
]->arg
;
7613 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
7615 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
7616 errno
, safe_strerror(errno
));
7617 return CMD_WARNING_CONFIG_FAILED
;
7620 /* Source address */
7621 if (argc
== (idx_ipv4_2
+ 1)) {
7622 source_str
= argv
[idx_ipv4_2
]->arg
;
7623 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
7625 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
7626 source_str
, errno
, safe_strerror(errno
));
7627 return CMD_WARNING_CONFIG_FAILED
;
7629 /* Reject 0.0.0.0. Reserved for any source. */
7630 if (source_addr
.s_addr
== INADDR_ANY
) {
7631 vty_out(vty
, "Bad source address %s\n", source_str
);
7632 return CMD_WARNING_CONFIG_FAILED
;
7635 source_addr
.s_addr
= INADDR_ANY
;
7638 CMD_FERR_RETURN(pim_if_igmp_join_add(ifp
, group_addr
, source_addr
),
7639 "Failure joining IGMP group: $ERR");
7644 DEFUN (interface_no_ip_igmp_join
,
7645 interface_no_ip_igmp_join_cmd
,
7646 "no ip igmp join A.B.C.D [A.B.C.D]",
7650 "IGMP join multicast group\n"
7651 "Multicast group address\n"
7654 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7657 const char *group_str
;
7658 const char *source_str
;
7659 struct in_addr group_addr
;
7660 struct in_addr source_addr
;
7664 group_str
= argv
[idx_ipv4
]->arg
;
7665 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
7667 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
7668 errno
, safe_strerror(errno
));
7669 return CMD_WARNING_CONFIG_FAILED
;
7672 /* Source address */
7673 if (argc
== (idx_ipv4_2
+ 1)) {
7674 source_str
= argv
[idx_ipv4_2
]->arg
;
7675 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
7677 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
7678 source_str
, errno
, safe_strerror(errno
));
7679 return CMD_WARNING_CONFIG_FAILED
;
7681 /* Reject 0.0.0.0. Reserved for any source. */
7682 if (source_addr
.s_addr
== INADDR_ANY
) {
7683 vty_out(vty
, "Bad source address %s\n", source_str
);
7684 return CMD_WARNING_CONFIG_FAILED
;
7688 source_addr
.s_addr
= INADDR_ANY
;
7691 result
= pim_if_igmp_join_del(ifp
, group_addr
, source_addr
);
7694 "%% Failure leaving IGMP group %s source %s on interface %s: %d\n",
7695 group_str
, source_str
, ifp
->name
, result
);
7696 return CMD_WARNING_CONFIG_FAILED
;
7703 CLI reconfiguration affects the interface level (struct pim_interface).
7704 This function propagates the reconfiguration to every active socket
7707 static void igmp_sock_query_interval_reconfig(struct igmp_sock
*igmp
)
7709 struct interface
*ifp
;
7710 struct pim_interface
*pim_ifp
;
7714 /* other querier present? */
7716 if (igmp
->t_other_querier_timer
)
7719 /* this is the querier */
7721 zassert(igmp
->interface
);
7722 zassert(igmp
->interface
->info
);
7724 ifp
= igmp
->interface
;
7725 pim_ifp
= ifp
->info
;
7727 if (PIM_DEBUG_IGMP_TRACE
) {
7728 char ifaddr_str
[INET_ADDRSTRLEN
];
7729 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
7730 sizeof(ifaddr_str
));
7731 zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
7732 __func__
, ifaddr_str
, ifp
->name
,
7733 pim_ifp
->igmp_default_query_interval
);
7737 igmp_startup_mode_on() will reset QQI:
7739 igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
7741 igmp_startup_mode_on(igmp
);
7744 static void igmp_sock_query_reschedule(struct igmp_sock
*igmp
)
7746 if (igmp
->mtrace_only
)
7749 if (igmp
->t_igmp_query_timer
) {
7750 /* other querier present */
7751 zassert(igmp
->t_igmp_query_timer
);
7752 zassert(!igmp
->t_other_querier_timer
);
7754 pim_igmp_general_query_off(igmp
);
7755 pim_igmp_general_query_on(igmp
);
7757 zassert(igmp
->t_igmp_query_timer
);
7758 zassert(!igmp
->t_other_querier_timer
);
7760 /* this is the querier */
7762 zassert(!igmp
->t_igmp_query_timer
);
7763 zassert(igmp
->t_other_querier_timer
);
7765 pim_igmp_other_querier_timer_off(igmp
);
7766 pim_igmp_other_querier_timer_on(igmp
);
7768 zassert(!igmp
->t_igmp_query_timer
);
7769 zassert(igmp
->t_other_querier_timer
);
7773 static void change_query_interval(struct pim_interface
*pim_ifp
,
7776 struct listnode
*sock_node
;
7777 struct igmp_sock
*igmp
;
7779 pim_ifp
->igmp_default_query_interval
= query_interval
;
7781 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
7782 igmp_sock_query_interval_reconfig(igmp
);
7783 igmp_sock_query_reschedule(igmp
);
7787 static void change_query_max_response_time(struct pim_interface
*pim_ifp
,
7788 int query_max_response_time_dsec
)
7790 struct listnode
*sock_node
;
7791 struct igmp_sock
*igmp
;
7793 pim_ifp
->igmp_query_max_response_time_dsec
=
7794 query_max_response_time_dsec
;
7797 Below we modify socket/group/source timers in order to quickly
7798 reflect the change. Otherwise, those timers would eventually catch
7802 /* scan all sockets */
7803 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
7804 struct listnode
*grp_node
;
7805 struct igmp_group
*grp
;
7807 /* reschedule socket general query */
7808 igmp_sock_query_reschedule(igmp
);
7810 /* scan socket groups */
7811 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grp_node
,
7813 struct listnode
*src_node
;
7814 struct igmp_source
*src
;
7816 /* reset group timers for groups in EXCLUDE mode */
7817 if (grp
->group_filtermode_isexcl
) {
7818 igmp_group_reset_gmi(grp
);
7821 /* scan group sources */
7822 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
,
7825 /* reset source timers for sources with running
7827 if (src
->t_source_timer
) {
7828 igmp_source_reset_gmi(igmp
, grp
, src
);
7835 #define IGMP_QUERY_INTERVAL_MIN (1)
7836 #define IGMP_QUERY_INTERVAL_MAX (1800)
7838 DEFUN (interface_ip_igmp_query_interval
,
7839 interface_ip_igmp_query_interval_cmd
,
7840 "ip igmp query-interval (1-1800)",
7843 IFACE_IGMP_QUERY_INTERVAL_STR
7844 "Query interval in seconds\n")
7846 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7847 struct pim_interface
*pim_ifp
= ifp
->info
;
7849 int query_interval_dsec
;
7853 ret
= pim_cmd_igmp_start(vty
, ifp
);
7854 if (ret
!= CMD_SUCCESS
)
7856 pim_ifp
= ifp
->info
;
7859 query_interval
= atoi(argv
[3]->arg
);
7860 query_interval_dsec
= 10 * query_interval
;
7863 It seems we don't need to check bounds since command.c does it
7864 already, but we verify them anyway for extra safety.
7866 if (query_interval
< IGMP_QUERY_INTERVAL_MIN
) {
7868 "General query interval %d lower than minimum %d\n",
7869 query_interval
, IGMP_QUERY_INTERVAL_MIN
);
7870 return CMD_WARNING_CONFIG_FAILED
;
7872 if (query_interval
> IGMP_QUERY_INTERVAL_MAX
) {
7874 "General query interval %d higher than maximum %d\n",
7875 query_interval
, IGMP_QUERY_INTERVAL_MAX
);
7876 return CMD_WARNING_CONFIG_FAILED
;
7879 if (query_interval_dsec
<= pim_ifp
->igmp_query_max_response_time_dsec
) {
7881 "Can't set general query interval %d dsec <= query max response time %d dsec.\n",
7882 query_interval_dsec
,
7883 pim_ifp
->igmp_query_max_response_time_dsec
);
7884 return CMD_WARNING_CONFIG_FAILED
;
7887 change_query_interval(pim_ifp
, query_interval
);
7892 DEFUN (interface_no_ip_igmp_query_interval
,
7893 interface_no_ip_igmp_query_interval_cmd
,
7894 "no ip igmp query-interval",
7898 IFACE_IGMP_QUERY_INTERVAL_STR
)
7900 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7901 struct pim_interface
*pim_ifp
= ifp
->info
;
7902 int default_query_interval_dsec
;
7907 default_query_interval_dsec
= IGMP_GENERAL_QUERY_INTERVAL
* 10;
7909 if (default_query_interval_dsec
7910 <= pim_ifp
->igmp_query_max_response_time_dsec
) {
7912 "Can't set default general query interval %d dsec <= query max response time %d dsec.\n",
7913 default_query_interval_dsec
,
7914 pim_ifp
->igmp_query_max_response_time_dsec
);
7915 return CMD_WARNING_CONFIG_FAILED
;
7918 change_query_interval(pim_ifp
, IGMP_GENERAL_QUERY_INTERVAL
);
7923 DEFUN (interface_ip_igmp_version
,
7924 interface_ip_igmp_version_cmd
,
7925 "ip igmp version (2-3)",
7929 "IGMP version number\n")
7931 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7932 struct pim_interface
*pim_ifp
= ifp
->info
;
7933 int igmp_version
, old_version
= 0;
7937 ret
= pim_cmd_igmp_start(vty
, ifp
);
7938 if (ret
!= CMD_SUCCESS
)
7940 pim_ifp
= ifp
->info
;
7943 igmp_version
= atoi(argv
[3]->arg
);
7944 old_version
= pim_ifp
->igmp_version
;
7945 pim_ifp
->igmp_version
= igmp_version
;
7947 // Check if IGMP is Enabled otherwise, enable on interface
7948 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
7949 PIM_IF_DO_IGMP(pim_ifp
->options
);
7950 pim_if_addr_add_all(ifp
);
7951 pim_if_membership_refresh(ifp
);
7952 old_version
= igmp_version
;
7953 // avoid refreshing membership again.
7955 /* Current and new version is different refresh existing
7956 membership. Going from 3 -> 2 or 2 -> 3. */
7957 if (old_version
!= igmp_version
)
7958 pim_if_membership_refresh(ifp
);
7963 DEFUN (interface_no_ip_igmp_version
,
7964 interface_no_ip_igmp_version_cmd
,
7965 "no ip igmp version (2-3)",
7970 "IGMP version number\n")
7972 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7973 struct pim_interface
*pim_ifp
= ifp
->info
;
7978 pim_ifp
->igmp_version
= IGMP_DEFAULT_VERSION
;
7983 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
7984 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
7986 DEFUN (interface_ip_igmp_query_max_response_time
,
7987 interface_ip_igmp_query_max_response_time_cmd
,
7988 "ip igmp query-max-response-time (10-250)",
7991 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
7992 "Query response value in deci-seconds\n")
7994 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7995 struct pim_interface
*pim_ifp
= ifp
->info
;
7996 int query_max_response_time
;
8000 ret
= pim_cmd_igmp_start(vty
, ifp
);
8001 if (ret
!= CMD_SUCCESS
)
8003 pim_ifp
= ifp
->info
;
8006 query_max_response_time
= atoi(argv
[3]->arg
);
8008 if (query_max_response_time
8009 >= pim_ifp
->igmp_default_query_interval
* 10) {
8011 "Can't set query max response time %d sec >= general query interval %d sec\n",
8012 query_max_response_time
,
8013 pim_ifp
->igmp_default_query_interval
);
8014 return CMD_WARNING_CONFIG_FAILED
;
8017 change_query_max_response_time(pim_ifp
, query_max_response_time
);
8022 DEFUN (interface_no_ip_igmp_query_max_response_time
,
8023 interface_no_ip_igmp_query_max_response_time_cmd
,
8024 "no ip igmp query-max-response-time (10-250)",
8028 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
8029 "Time for response in deci-seconds\n")
8031 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8032 struct pim_interface
*pim_ifp
= ifp
->info
;
8037 change_query_max_response_time(pim_ifp
,
8038 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
8043 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
8044 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
8046 DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec
,
8047 interface_ip_igmp_query_max_response_time_dsec_cmd
,
8048 "ip igmp query-max-response-time-dsec (10-250)",
8051 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
8052 "Query response value in deciseconds\n")
8054 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8055 struct pim_interface
*pim_ifp
= ifp
->info
;
8056 int query_max_response_time_dsec
;
8057 int default_query_interval_dsec
;
8061 ret
= pim_cmd_igmp_start(vty
, ifp
);
8062 if (ret
!= CMD_SUCCESS
)
8064 pim_ifp
= ifp
->info
;
8067 query_max_response_time_dsec
= atoi(argv
[4]->arg
);
8069 default_query_interval_dsec
= 10 * pim_ifp
->igmp_default_query_interval
;
8071 if (query_max_response_time_dsec
>= default_query_interval_dsec
) {
8073 "Can't set query max response time %d dsec >= general query interval %d dsec\n",
8074 query_max_response_time_dsec
,
8075 default_query_interval_dsec
);
8076 return CMD_WARNING_CONFIG_FAILED
;
8079 change_query_max_response_time(pim_ifp
, query_max_response_time_dsec
);
8084 DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec
,
8085 interface_no_ip_igmp_query_max_response_time_dsec_cmd
,
8086 "no ip igmp query-max-response-time-dsec",
8090 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
)
8092 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8093 struct pim_interface
*pim_ifp
= ifp
->info
;
8098 change_query_max_response_time(pim_ifp
,
8099 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
8104 #define IGMP_LAST_MEMBER_QUERY_COUNT_MIN (1)
8105 #define IGMP_LAST_MEMBER_QUERY_COUNT_MAX (7)
8107 DEFUN (interface_ip_igmp_last_member_query_count
,
8108 interface_ip_igmp_last_member_query_count_cmd
,
8109 "ip igmp last-member-query-count (1-7)",
8112 IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR
8113 "Last member query count\n")
8115 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8116 struct pim_interface
*pim_ifp
= ifp
->info
;
8117 int last_member_query_count
;
8121 ret
= pim_cmd_igmp_start(vty
, ifp
);
8122 if (ret
!= CMD_SUCCESS
)
8124 pim_ifp
= ifp
->info
;
8127 last_member_query_count
= atoi(argv
[3]->arg
);
8129 pim_ifp
->igmp_last_member_query_count
= last_member_query_count
;
8134 DEFUN (interface_no_ip_igmp_last_member_query_count
,
8135 interface_no_ip_igmp_last_member_query_count_cmd
,
8136 "no ip igmp last-member-query-count",
8140 IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR
)
8142 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8143 struct pim_interface
*pim_ifp
= ifp
->info
;
8148 pim_ifp
->igmp_last_member_query_count
=
8149 IGMP_DEFAULT_ROBUSTNESS_VARIABLE
;
8154 #define IGMP_LAST_MEMBER_QUERY_INTERVAL_MIN (1)
8155 #define IGMP_LAST_MEMBER_QUERY_INTERVAL_MAX (255)
8157 DEFUN (interface_ip_igmp_last_member_query_interval
,
8158 interface_ip_igmp_last_member_query_interval_cmd
,
8159 "ip igmp last-member-query-interval (1-255)",
8162 IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR
8163 "Last member query interval in deciseconds\n")
8165 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8166 struct pim_interface
*pim_ifp
= ifp
->info
;
8167 int last_member_query_interval
;
8171 ret
= pim_cmd_igmp_start(vty
, ifp
);
8172 if (ret
!= CMD_SUCCESS
)
8174 pim_ifp
= ifp
->info
;
8177 last_member_query_interval
= atoi(argv
[3]->arg
);
8178 pim_ifp
->igmp_specific_query_max_response_time_dsec
8179 = last_member_query_interval
;
8184 DEFUN (interface_no_ip_igmp_last_member_query_interval
,
8185 interface_no_ip_igmp_last_member_query_interval_cmd
,
8186 "no ip igmp last-member-query-interval",
8190 IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR
)
8192 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8193 struct pim_interface
*pim_ifp
= ifp
->info
;
8198 pim_ifp
->igmp_specific_query_max_response_time_dsec
=
8199 IGMP_SPECIFIC_QUERY_MAX_RESPONSE_TIME_DSEC
;
8204 DEFUN (interface_ip_pim_drprio
,
8205 interface_ip_pim_drprio_cmd
,
8206 "ip pim drpriority (1-4294967295)",
8209 "Set the Designated Router Election Priority\n"
8210 "Value of the new DR Priority\n")
8212 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8214 struct pim_interface
*pim_ifp
= ifp
->info
;
8215 uint32_t old_dr_prio
;
8218 vty_out(vty
, "Please enable PIM on interface, first\n");
8219 return CMD_WARNING_CONFIG_FAILED
;
8222 old_dr_prio
= pim_ifp
->pim_dr_priority
;
8224 pim_ifp
->pim_dr_priority
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
8226 if (old_dr_prio
!= pim_ifp
->pim_dr_priority
) {
8227 pim_if_dr_election(ifp
);
8228 pim_hello_restart_now(ifp
);
8234 DEFUN (interface_no_ip_pim_drprio
,
8235 interface_no_ip_pim_drprio_cmd
,
8236 "no ip pim drpriority [(1-4294967295)]",
8240 "Revert the Designated Router Priority to default\n"
8241 "Old Value of the Priority\n")
8243 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8244 struct pim_interface
*pim_ifp
= ifp
->info
;
8247 vty_out(vty
, "Pim not enabled on this interface\n");
8248 return CMD_WARNING_CONFIG_FAILED
;
8251 if (pim_ifp
->pim_dr_priority
!= PIM_DEFAULT_DR_PRIORITY
) {
8252 pim_ifp
->pim_dr_priority
= PIM_DEFAULT_DR_PRIORITY
;
8253 pim_if_dr_election(ifp
);
8254 pim_hello_restart_now(ifp
);
8260 DEFPY_HIDDEN (interface_ip_igmp_query_generate
,
8261 interface_ip_igmp_query_generate_cmd
,
8262 "ip igmp generate-query-once [version (2-3)]",
8265 "Generate igmp general query once\n"
8267 "IGMP version number\n")
8269 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8270 int igmp_version
= 2;
8273 vty_out(vty
, "IGMP/PIM is not enabled on the interface %s\n",
8275 return CMD_WARNING_CONFIG_FAILED
;
8279 igmp_version
= atoi(argv
[4]->arg
);
8281 igmp_send_query_on_intf(ifp
, igmp_version
);
8286 static int pim_cmd_interface_add(struct vty
*vty
, struct interface
*ifp
)
8288 struct pim_interface
*pim_ifp
= ifp
->info
;
8289 struct pim_instance
*pim
;
8292 pim
= pim_get_pim_instance(ifp
->vrf_id
);
8293 /* Limiting mcast interfaces to number of VIFs */
8294 if (pim
->mcast_if_count
== MAXVIFS
) {
8295 vty_out(vty
, "Max multicast interfaces(%d) reached.",
8299 pim_ifp
= pim_if_new(ifp
, false, true, false, false);
8301 PIM_IF_DO_PIM(pim_ifp
->options
);
8303 pim_if_addr_add_all(ifp
);
8304 pim_if_membership_refresh(ifp
);
8306 pim_if_create_pimreg(pim_ifp
->pim
);
8310 DEFPY_HIDDEN (pim_test_sg_keepalive
,
8311 pim_test_sg_keepalive_cmd
,
8312 "test pim [vrf NAME$name] keepalive-reset A.B.C.D$source A.B.C.D$group",
8316 "Reset the Keepalive Timer\n"
8317 "The Source we are resetting\n"
8318 "The Group we are resetting\n")
8320 struct pim_upstream
*up
;
8321 struct pim_instance
*pim
;
8322 struct prefix_sg sg
;
8328 pim
= pim_get_pim_instance(VRF_DEFAULT
);
8330 struct vrf
*vrf
= vrf_lookup_by_name(name
);
8333 vty_out(vty
, "%% Vrf specified: %s does not exist\n",
8338 pim
= pim_get_pim_instance(vrf
->vrf_id
);
8342 vty_out(vty
, "%% Unable to find pim instance\n");
8346 up
= pim_upstream_find(pim
, &sg
);
8348 vty_out(vty
, "%% Unable to find %s specified\n",
8349 pim_str_sg_dump(&sg
));
8353 vty_out(vty
, "Setting %s to current keep alive time: %d\n",
8354 pim_str_sg_dump(&sg
), pim
->keep_alive_time
);
8355 pim_upstream_keep_alive_timer_start(up
, pim
->keep_alive_time
);
8360 DEFPY (interface_ip_pim_activeactive
,
8361 interface_ip_pim_activeactive_cmd
,
8362 "[no$no] ip pim active-active",
8366 "Mark interface as Active-Active for MLAG operations, Hidden because not finished yet\n")
8368 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8369 struct pim_interface
*pim_ifp
;
8371 if (!no
&& !pim_cmd_interface_add(vty
, ifp
)) {
8373 "Could not enable PIM SM active-active on interface %s\n",
8375 return CMD_WARNING_CONFIG_FAILED
;
8380 zlog_debug("%sConfiguring PIM active-active on Interface: %s",
8381 no
? "Un-" : " ", ifp
->name
);
8383 pim_ifp
= ifp
->info
;
8385 pim_if_unconfigure_mlag_dualactive(pim_ifp
);
8387 pim_if_configure_mlag_dualactive(pim_ifp
);
8392 DEFUN_HIDDEN (interface_ip_pim_ssm
,
8393 interface_ip_pim_ssm_cmd
,
8399 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8401 if (!pim_cmd_interface_add(vty
, ifp
)) {
8402 vty_out(vty
, "Could not enable PIM SM on interface %s\n",
8404 return CMD_WARNING_CONFIG_FAILED
;
8408 "WARN: Enabled PIM SM on interface; configure PIM SSM range if needed\n");
8412 static int interface_ip_pim_helper(struct vty
*vty
)
8414 struct pim_interface
*pim_ifp
;
8416 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8418 if (!pim_cmd_interface_add(vty
, ifp
)) {
8419 vty_out(vty
, "Could not enable PIM SM on interface %s\n",
8421 return CMD_WARNING_CONFIG_FAILED
;
8424 pim_ifp
= ifp
->info
;
8426 pim_if_create_pimreg(pim_ifp
->pim
);
8431 DEFUN_HIDDEN (interface_ip_pim_sm
,
8432 interface_ip_pim_sm_cmd
,
8438 return interface_ip_pim_helper(vty
);
8441 DEFUN (interface_ip_pim
,
8442 interface_ip_pim_cmd
,
8447 return interface_ip_pim_helper(vty
);
8450 static int pim_cmd_interface_delete(struct interface
*ifp
)
8452 struct pim_interface
*pim_ifp
= ifp
->info
;
8457 PIM_IF_DONT_PIM(pim_ifp
->options
);
8459 pim_if_membership_clear(ifp
);
8462 pim_sock_delete() removes all neighbors from
8463 pim_ifp->pim_neighbor_list.
8465 pim_sock_delete(ifp
, "pim unconfigured on interface");
8467 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
8468 pim_if_addr_del_all(ifp
);
8475 static int interface_no_ip_pim_helper(struct vty
*vty
)
8477 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8478 if (!pim_cmd_interface_delete(ifp
)) {
8479 vty_out(vty
, "Unable to delete interface information\n");
8480 return CMD_WARNING_CONFIG_FAILED
;
8486 DEFUN_HIDDEN (interface_no_ip_pim_ssm
,
8487 interface_no_ip_pim_ssm_cmd
,
8494 return interface_no_ip_pim_helper(vty
);
8497 DEFUN_HIDDEN (interface_no_ip_pim_sm
,
8498 interface_no_ip_pim_sm_cmd
,
8505 return interface_no_ip_pim_helper(vty
);
8508 DEFUN (interface_no_ip_pim
,
8509 interface_no_ip_pim_cmd
,
8515 return interface_no_ip_pim_helper(vty
);
8519 DEFUN(interface_ip_pim_boundary_oil
,
8520 interface_ip_pim_boundary_oil_cmd
,
8521 "ip multicast boundary oil WORD",
8523 "Generic multicast configuration options\n"
8524 "Define multicast boundary\n"
8525 "Filter OIL by group using prefix list\n"
8526 "Prefix list to filter OIL with\n")
8528 VTY_DECLVAR_CONTEXT(interface
, iif
);
8529 struct pim_interface
*pim_ifp
;
8532 argv_find(argv
, argc
, "WORD", &idx
);
8534 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
8536 if (pim_ifp
->boundary_oil_plist
)
8537 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
8539 pim_ifp
->boundary_oil_plist
=
8540 XSTRDUP(MTYPE_PIM_INTERFACE
, argv
[idx
]->arg
);
8542 /* Interface will be pruned from OIL on next Join */
8546 DEFUN(interface_no_ip_pim_boundary_oil
,
8547 interface_no_ip_pim_boundary_oil_cmd
,
8548 "no ip multicast boundary oil [WORD]",
8551 "Generic multicast configuration options\n"
8552 "Define multicast boundary\n"
8553 "Filter OIL by group using prefix list\n"
8554 "Prefix list to filter OIL with\n")
8556 VTY_DECLVAR_CONTEXT(interface
, iif
);
8557 struct pim_interface
*pim_ifp
;
8560 argv_find(argv
, argc
, "WORD", &idx
);
8562 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
8564 if (pim_ifp
->boundary_oil_plist
)
8565 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
8570 DEFUN (interface_ip_mroute
,
8571 interface_ip_mroute_cmd
,
8572 "ip mroute INTERFACE A.B.C.D [A.B.C.D]",
8574 "Add multicast route\n"
8575 "Outgoing interface name\n"
8579 VTY_DECLVAR_CONTEXT(interface
, iif
);
8580 struct pim_interface
*pim_ifp
;
8581 struct pim_instance
*pim
;
8582 int idx_interface
= 2;
8584 struct interface
*oif
;
8585 const char *oifname
;
8586 const char *grp_str
;
8587 struct in_addr grp_addr
;
8588 const char *src_str
;
8589 struct in_addr src_addr
;
8592 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
8595 oifname
= argv
[idx_interface
]->arg
;
8596 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
8598 vty_out(vty
, "No such interface name %s\n", oifname
);
8602 grp_str
= argv
[idx_ipv4
]->arg
;
8603 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
8605 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
8606 errno
, safe_strerror(errno
));
8610 if (argc
== (idx_ipv4
+ 1)) {
8611 src_addr
.s_addr
= INADDR_ANY
;
8614 src_str
= argv
[idx_ipv4
+ 1]->arg
;
8615 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
8617 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
8618 errno
, safe_strerror(errno
));
8623 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
8624 vty_out(vty
, "Failed to add static mroute\n");
8631 DEFUN (interface_no_ip_mroute
,
8632 interface_no_ip_mroute_cmd
,
8633 "no ip mroute INTERFACE A.B.C.D [A.B.C.D]",
8636 "Add multicast route\n"
8637 "Outgoing interface name\n"
8641 VTY_DECLVAR_CONTEXT(interface
, iif
);
8642 struct pim_interface
*pim_ifp
;
8643 struct pim_instance
*pim
;
8644 int idx_interface
= 3;
8646 struct interface
*oif
;
8647 const char *oifname
;
8648 const char *grp_str
;
8649 struct in_addr grp_addr
;
8650 const char *src_str
;
8651 struct in_addr src_addr
;
8654 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
8657 oifname
= argv
[idx_interface
]->arg
;
8658 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
8660 vty_out(vty
, "No such interface name %s\n", oifname
);
8664 grp_str
= argv
[idx_ipv4
]->arg
;
8665 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
8667 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
8668 errno
, safe_strerror(errno
));
8672 if (argc
== (idx_ipv4
+ 1)) {
8673 src_addr
.s_addr
= INADDR_ANY
;
8676 src_str
= argv
[idx_ipv4
+ 1]->arg
;
8677 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
8679 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
8680 errno
, safe_strerror(errno
));
8685 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
8686 vty_out(vty
, "Failed to remove static mroute\n");
8693 DEFUN (interface_ip_pim_hello
,
8694 interface_ip_pim_hello_cmd
,
8695 "ip pim hello (1-180) [(1-180)]",
8699 IFACE_PIM_HELLO_TIME_STR
8700 IFACE_PIM_HELLO_HOLD_STR
)
8702 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8705 struct pim_interface
*pim_ifp
= ifp
->info
;
8708 if (!pim_cmd_interface_add(vty
, ifp
)) {
8710 "Could not enable PIM SM on interface %s\n",
8712 return CMD_WARNING_CONFIG_FAILED
;
8716 pim_ifp
= ifp
->info
;
8717 pim_ifp
->pim_hello_period
= strtol(argv
[idx_time
]->arg
, NULL
, 10);
8719 if (argc
== idx_hold
+ 1)
8720 pim_ifp
->pim_default_holdtime
=
8721 strtol(argv
[idx_hold
]->arg
, NULL
, 10);
8726 DEFUN (interface_no_ip_pim_hello
,
8727 interface_no_ip_pim_hello_cmd
,
8728 "no ip pim hello [(1-180) (1-180)]",
8733 IFACE_PIM_HELLO_TIME_STR
8734 IFACE_PIM_HELLO_HOLD_STR
)
8736 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8737 struct pim_interface
*pim_ifp
= ifp
->info
;
8740 vty_out(vty
, "Pim not enabled on this interface\n");
8741 return CMD_WARNING_CONFIG_FAILED
;
8744 pim_ifp
->pim_hello_period
= PIM_DEFAULT_HELLO_PERIOD
;
8745 pim_ifp
->pim_default_holdtime
= -1;
8756 PIM_DO_DEBUG_IGMP_EVENTS
;
8757 PIM_DO_DEBUG_IGMP_PACKETS
;
8758 PIM_DO_DEBUG_IGMP_TRACE
;
8762 DEFUN (no_debug_igmp
,
8769 PIM_DONT_DEBUG_IGMP_EVENTS
;
8770 PIM_DONT_DEBUG_IGMP_PACKETS
;
8771 PIM_DONT_DEBUG_IGMP_TRACE
;
8776 DEFUN (debug_igmp_events
,
8777 debug_igmp_events_cmd
,
8778 "debug igmp events",
8781 DEBUG_IGMP_EVENTS_STR
)
8783 PIM_DO_DEBUG_IGMP_EVENTS
;
8787 DEFUN (no_debug_igmp_events
,
8788 no_debug_igmp_events_cmd
,
8789 "no debug igmp events",
8793 DEBUG_IGMP_EVENTS_STR
)
8795 PIM_DONT_DEBUG_IGMP_EVENTS
;
8800 DEFUN (debug_igmp_packets
,
8801 debug_igmp_packets_cmd
,
8802 "debug igmp packets",
8805 DEBUG_IGMP_PACKETS_STR
)
8807 PIM_DO_DEBUG_IGMP_PACKETS
;
8811 DEFUN (no_debug_igmp_packets
,
8812 no_debug_igmp_packets_cmd
,
8813 "no debug igmp packets",
8817 DEBUG_IGMP_PACKETS_STR
)
8819 PIM_DONT_DEBUG_IGMP_PACKETS
;
8824 DEFUN (debug_igmp_trace
,
8825 debug_igmp_trace_cmd
,
8829 DEBUG_IGMP_TRACE_STR
)
8831 PIM_DO_DEBUG_IGMP_TRACE
;
8835 DEFUN (no_debug_igmp_trace
,
8836 no_debug_igmp_trace_cmd
,
8837 "no debug igmp trace",
8841 DEBUG_IGMP_TRACE_STR
)
8843 PIM_DONT_DEBUG_IGMP_TRACE
;
8848 DEFUN (debug_mroute
,
8854 PIM_DO_DEBUG_MROUTE
;
8858 DEFUN (debug_mroute_detail
,
8859 debug_mroute_detail_cmd
,
8860 "debug mroute detail",
8865 PIM_DO_DEBUG_MROUTE_DETAIL
;
8869 DEFUN (no_debug_mroute
,
8870 no_debug_mroute_cmd
,
8876 PIM_DONT_DEBUG_MROUTE
;
8880 DEFUN (no_debug_mroute_detail
,
8881 no_debug_mroute_detail_cmd
,
8882 "no debug mroute detail",
8888 PIM_DONT_DEBUG_MROUTE_DETAIL
;
8892 DEFUN (debug_pim_static
,
8893 debug_pim_static_cmd
,
8899 PIM_DO_DEBUG_STATIC
;
8903 DEFUN (no_debug_pim_static
,
8904 no_debug_pim_static_cmd
,
8905 "no debug pim static",
8911 PIM_DONT_DEBUG_STATIC
;
8922 PIM_DO_DEBUG_PIM_EVENTS
;
8923 PIM_DO_DEBUG_PIM_PACKETS
;
8924 PIM_DO_DEBUG_PIM_TRACE
;
8925 PIM_DO_DEBUG_MSDP_EVENTS
;
8926 PIM_DO_DEBUG_MSDP_PACKETS
;
8931 DEFUN (no_debug_pim
,
8938 PIM_DONT_DEBUG_PIM_EVENTS
;
8939 PIM_DONT_DEBUG_PIM_PACKETS
;
8940 PIM_DONT_DEBUG_PIM_TRACE
;
8941 PIM_DONT_DEBUG_MSDP_EVENTS
;
8942 PIM_DONT_DEBUG_MSDP_PACKETS
;
8944 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
8945 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
8951 DEFUN (debug_pim_nht
,
8956 "Nexthop Tracking\n")
8958 PIM_DO_DEBUG_PIM_NHT
;
8962 DEFUN (no_debug_pim_nht
,
8963 no_debug_pim_nht_cmd
,
8968 "Nexthop Tracking\n")
8970 PIM_DONT_DEBUG_PIM_NHT
;
8974 DEFUN (debug_pim_nht_rp
,
8975 debug_pim_nht_rp_cmd
,
8979 "Nexthop Tracking\n"
8980 "RP Nexthop Tracking\n")
8982 PIM_DO_DEBUG_PIM_NHT_RP
;
8986 DEFUN (no_debug_pim_nht_rp
,
8987 no_debug_pim_nht_rp_cmd
,
8988 "no debug pim nht rp",
8992 "Nexthop Tracking\n"
8993 "RP Nexthop Tracking\n")
8995 PIM_DONT_DEBUG_PIM_NHT_RP
;
8999 DEFUN (debug_pim_events
,
9000 debug_pim_events_cmd
,
9004 DEBUG_PIM_EVENTS_STR
)
9006 PIM_DO_DEBUG_PIM_EVENTS
;
9010 DEFUN (no_debug_pim_events
,
9011 no_debug_pim_events_cmd
,
9012 "no debug pim events",
9016 DEBUG_PIM_EVENTS_STR
)
9018 PIM_DONT_DEBUG_PIM_EVENTS
;
9022 DEFUN (debug_pim_packets
,
9023 debug_pim_packets_cmd
,
9024 "debug pim packets [<hello|joins|register>]",
9027 DEBUG_PIM_PACKETS_STR
9028 DEBUG_PIM_HELLO_PACKETS_STR
9029 DEBUG_PIM_J_P_PACKETS_STR
9030 DEBUG_PIM_PIM_REG_PACKETS_STR
)
9033 if (argv_find(argv
, argc
, "hello", &idx
)) {
9034 PIM_DO_DEBUG_PIM_HELLO
;
9035 vty_out(vty
, "PIM Hello debugging is on\n");
9036 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
9037 PIM_DO_DEBUG_PIM_J_P
;
9038 vty_out(vty
, "PIM Join/Prune debugging is on\n");
9039 } else if (argv_find(argv
, argc
, "register", &idx
)) {
9040 PIM_DO_DEBUG_PIM_REG
;
9041 vty_out(vty
, "PIM Register debugging is on\n");
9043 PIM_DO_DEBUG_PIM_PACKETS
;
9044 vty_out(vty
, "PIM Packet debugging is on \n");
9049 DEFUN (no_debug_pim_packets
,
9050 no_debug_pim_packets_cmd
,
9051 "no debug pim packets [<hello|joins|register>]",
9055 DEBUG_PIM_PACKETS_STR
9056 DEBUG_PIM_HELLO_PACKETS_STR
9057 DEBUG_PIM_J_P_PACKETS_STR
9058 DEBUG_PIM_PIM_REG_PACKETS_STR
)
9061 if (argv_find(argv
, argc
, "hello", &idx
)) {
9062 PIM_DONT_DEBUG_PIM_HELLO
;
9063 vty_out(vty
, "PIM Hello debugging is off \n");
9064 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
9065 PIM_DONT_DEBUG_PIM_J_P
;
9066 vty_out(vty
, "PIM Join/Prune debugging is off \n");
9067 } else if (argv_find(argv
, argc
, "register", &idx
)) {
9068 PIM_DONT_DEBUG_PIM_REG
;
9069 vty_out(vty
, "PIM Register debugging is off\n");
9071 PIM_DONT_DEBUG_PIM_PACKETS
;
9077 DEFUN (debug_pim_packetdump_send
,
9078 debug_pim_packetdump_send_cmd
,
9079 "debug pim packet-dump send",
9082 DEBUG_PIM_PACKETDUMP_STR
9083 DEBUG_PIM_PACKETDUMP_SEND_STR
)
9085 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND
;
9089 DEFUN (no_debug_pim_packetdump_send
,
9090 no_debug_pim_packetdump_send_cmd
,
9091 "no debug pim packet-dump send",
9095 DEBUG_PIM_PACKETDUMP_STR
9096 DEBUG_PIM_PACKETDUMP_SEND_STR
)
9098 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
9102 DEFUN (debug_pim_packetdump_recv
,
9103 debug_pim_packetdump_recv_cmd
,
9104 "debug pim packet-dump receive",
9107 DEBUG_PIM_PACKETDUMP_STR
9108 DEBUG_PIM_PACKETDUMP_RECV_STR
)
9110 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV
;
9114 DEFUN (no_debug_pim_packetdump_recv
,
9115 no_debug_pim_packetdump_recv_cmd
,
9116 "no debug pim packet-dump receive",
9120 DEBUG_PIM_PACKETDUMP_STR
9121 DEBUG_PIM_PACKETDUMP_RECV_STR
)
9123 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
9127 DEFUN (debug_pim_trace
,
9128 debug_pim_trace_cmd
,
9132 DEBUG_PIM_TRACE_STR
)
9134 PIM_DO_DEBUG_PIM_TRACE
;
9138 DEFUN (debug_pim_trace_detail
,
9139 debug_pim_trace_detail_cmd
,
9140 "debug pim trace detail",
9144 "Detailed Information\n")
9146 PIM_DO_DEBUG_PIM_TRACE_DETAIL
;
9150 DEFUN (no_debug_pim_trace
,
9151 no_debug_pim_trace_cmd
,
9152 "no debug pim trace",
9156 DEBUG_PIM_TRACE_STR
)
9158 PIM_DONT_DEBUG_PIM_TRACE
;
9162 DEFUN (no_debug_pim_trace_detail
,
9163 no_debug_pim_trace_detail_cmd
,
9164 "no debug pim trace detail",
9169 "Detailed Information\n")
9171 PIM_DONT_DEBUG_PIM_TRACE_DETAIL
;
9175 DEFUN (debug_ssmpingd
,
9181 PIM_DO_DEBUG_SSMPINGD
;
9185 DEFUN (no_debug_ssmpingd
,
9186 no_debug_ssmpingd_cmd
,
9187 "no debug ssmpingd",
9192 PIM_DONT_DEBUG_SSMPINGD
;
9196 DEFUN (debug_pim_zebra
,
9197 debug_pim_zebra_cmd
,
9201 DEBUG_PIM_ZEBRA_STR
)
9207 DEFUN (no_debug_pim_zebra
,
9208 no_debug_pim_zebra_cmd
,
9209 "no debug pim zebra",
9213 DEBUG_PIM_ZEBRA_STR
)
9215 PIM_DONT_DEBUG_ZEBRA
;
9219 DEFUN(debug_pim_mlag
, debug_pim_mlag_cmd
, "debug pim mlag",
9220 DEBUG_STR DEBUG_PIM_STR DEBUG_PIM_MLAG_STR
)
9226 DEFUN(no_debug_pim_mlag
, no_debug_pim_mlag_cmd
, "no debug pim mlag",
9227 NO_STR DEBUG_STR DEBUG_PIM_STR DEBUG_PIM_MLAG_STR
)
9229 PIM_DONT_DEBUG_MLAG
;
9233 DEFUN (debug_pim_vxlan
,
9234 debug_pim_vxlan_cmd
,
9238 DEBUG_PIM_VXLAN_STR
)
9244 DEFUN (no_debug_pim_vxlan
,
9245 no_debug_pim_vxlan_cmd
,
9246 "no debug pim vxlan",
9250 DEBUG_PIM_VXLAN_STR
)
9252 PIM_DONT_DEBUG_VXLAN
;
9262 PIM_DO_DEBUG_MSDP_EVENTS
;
9263 PIM_DO_DEBUG_MSDP_PACKETS
;
9267 DEFUN (no_debug_msdp
,
9274 PIM_DONT_DEBUG_MSDP_EVENTS
;
9275 PIM_DONT_DEBUG_MSDP_PACKETS
;
9279 DEFUN (debug_msdp_events
,
9280 debug_msdp_events_cmd
,
9281 "debug msdp events",
9284 DEBUG_MSDP_EVENTS_STR
)
9286 PIM_DO_DEBUG_MSDP_EVENTS
;
9290 DEFUN (no_debug_msdp_events
,
9291 no_debug_msdp_events_cmd
,
9292 "no debug msdp events",
9296 DEBUG_MSDP_EVENTS_STR
)
9298 PIM_DONT_DEBUG_MSDP_EVENTS
;
9302 DEFUN (debug_msdp_packets
,
9303 debug_msdp_packets_cmd
,
9304 "debug msdp packets",
9307 DEBUG_MSDP_PACKETS_STR
)
9309 PIM_DO_DEBUG_MSDP_PACKETS
;
9313 DEFUN (no_debug_msdp_packets
,
9314 no_debug_msdp_packets_cmd
,
9315 "no debug msdp packets",
9319 DEBUG_MSDP_PACKETS_STR
)
9321 PIM_DONT_DEBUG_MSDP_PACKETS
;
9325 DEFUN (debug_mtrace
,
9331 PIM_DO_DEBUG_MTRACE
;
9335 DEFUN (no_debug_mtrace
,
9336 no_debug_mtrace_cmd
,
9342 PIM_DONT_DEBUG_MTRACE
;
9357 DEFUN (no_debug_bsm
,
9370 DEFUN_NOSH (show_debugging_pim
,
9371 show_debugging_pim_cmd
,
9372 "show debugging [pim]",
9377 vty_out(vty
, "PIM debugging status\n");
9379 pim_debug_config_write(vty
);
9384 static int interface_pim_use_src_cmd_worker(struct vty
*vty
, const char *source
)
9387 struct in_addr source_addr
;
9388 int ret
= CMD_SUCCESS
;
9389 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9391 result
= inet_pton(AF_INET
, source
, &source_addr
);
9393 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", source
,
9394 errno
, safe_strerror(errno
));
9395 return CMD_WARNING_CONFIG_FAILED
;
9398 result
= pim_update_source_set(ifp
, source_addr
);
9402 case PIM_IFACE_NOT_FOUND
:
9403 ret
= CMD_WARNING_CONFIG_FAILED
;
9404 vty_out(vty
, "Pim not enabled on this interface\n");
9406 case PIM_UPDATE_SOURCE_DUP
:
9408 vty_out(vty
, "%% Source already set to %s\n", source
);
9411 ret
= CMD_WARNING_CONFIG_FAILED
;
9412 vty_out(vty
, "%% Source set failed\n");
9418 DEFUN (interface_pim_use_source
,
9419 interface_pim_use_source_cmd
,
9420 "ip pim use-source A.B.C.D",
9423 "Configure primary IP address\n"
9424 "source ip address\n")
9426 return interface_pim_use_src_cmd_worker(vty
, argv
[3]->arg
);
9429 DEFUN (interface_no_pim_use_source
,
9430 interface_no_pim_use_source_cmd
,
9431 "no ip pim use-source [A.B.C.D]",
9435 "Delete source IP address\n"
9436 "source ip address\n")
9438 return interface_pim_use_src_cmd_worker(vty
, "0.0.0.0");
9446 "Enables BFD support\n")
9448 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9449 struct pim_interface
*pim_ifp
= ifp
->info
;
9450 struct bfd_info
*bfd_info
= NULL
;
9453 if (!pim_cmd_interface_add(vty
, ifp
)) {
9455 "Could not enable PIM SM on interface %s\n",
9460 pim_ifp
= ifp
->info
;
9462 bfd_info
= pim_ifp
->bfd_info
;
9464 if (!bfd_info
|| !CHECK_FLAG(bfd_info
->flags
, BFD_FLAG_PARAM_CFG
))
9465 pim_bfd_if_param_set(ifp
, BFD_DEF_MIN_RX
, BFD_DEF_MIN_TX
,
9466 BFD_DEF_DETECT_MULT
, 1);
9471 DEFUN (no_ip_pim_bfd
,
9477 "Disables BFD support\n")
9479 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9480 struct pim_interface
*pim_ifp
= ifp
->info
;
9483 vty_out(vty
, "Pim not enabled on this interface\n");
9487 if (pim_ifp
->bfd_info
) {
9488 pim_bfd_reg_dereg_all_nbr(ifp
, ZEBRA_BFD_DEST_DEREGISTER
);
9489 bfd_info_free(&(pim_ifp
->bfd_info
));
9500 "Enables BSM support on the interface\n")
9502 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9503 struct pim_interface
*pim_ifp
= ifp
->info
;
9506 if (!pim_cmd_interface_add(vty
, ifp
)) {
9508 "Could not enable PIM SM on interface %s\n",
9514 pim_ifp
= ifp
->info
;
9515 pim_ifp
->bsm_enable
= true;
9520 DEFUN (no_ip_pim_bsm
,
9526 "Disables BSM support\n")
9528 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9529 struct pim_interface
*pim_ifp
= ifp
->info
;
9532 vty_out(vty
, "Pim not enabled on this interface\n");
9536 pim_ifp
->bsm_enable
= false;
9541 DEFUN (ip_pim_ucast_bsm
,
9542 ip_pim_ucast_bsm_cmd
,
9543 "ip pim unicast-bsm",
9546 "Accept/Send unicast BSM on the interface\n")
9548 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9549 struct pim_interface
*pim_ifp
= ifp
->info
;
9552 if (!pim_cmd_interface_add(vty
, ifp
)) {
9554 "Could not enable PIM SM on interface %s\n",
9560 pim_ifp
= ifp
->info
;
9561 pim_ifp
->ucast_bsm_accept
= true;
9566 DEFUN (no_ip_pim_ucast_bsm
,
9567 no_ip_pim_ucast_bsm_cmd
,
9568 "no ip pim unicast-bsm",
9572 "Block send/receive unicast BSM on this interface\n")
9574 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9575 struct pim_interface
*pim_ifp
= ifp
->info
;
9578 vty_out(vty
, "Pim not enabled on this interface\n");
9582 pim_ifp
->ucast_bsm_accept
= false;
9590 ip_pim_bfd_param_cmd
,
9591 "ip pim bfd (2-255) (50-60000) (50-60000)",
9594 "Enables BFD support\n"
9595 "Detect Multiplier\n"
9596 "Required min receive interval\n"
9597 "Desired min transmit interval\n")
9601 ip_pim_bfd_param_cmd
,
9602 "ip pim bfd (2-255) (50-60000) (50-60000)",
9605 "Enables BFD support\n"
9606 "Detect Multiplier\n"
9607 "Required min receive interval\n"
9608 "Desired min transmit interval\n")
9609 #endif /* HAVE_BFDD */
9611 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9613 int idx_number_2
= 4;
9614 int idx_number_3
= 5;
9619 struct pim_interface
*pim_ifp
= ifp
->info
;
9622 if (!pim_cmd_interface_add(vty
, ifp
)) {
9624 "Could not enable PIM SM on interface %s\n",
9630 if ((ret
= bfd_validate_param(
9631 vty
, argv
[idx_number
]->arg
, argv
[idx_number_2
]->arg
,
9632 argv
[idx_number_3
]->arg
, &dm_val
, &rx_val
, &tx_val
))
9636 pim_bfd_if_param_set(ifp
, rx_val
, tx_val
, dm_val
, 0);
9642 ALIAS(no_ip_pim_bfd
, no_ip_pim_bfd_param_cmd
,
9643 "no ip pim bfd (2-255) (50-60000) (50-60000)", NO_STR IP_STR PIM_STR
9644 "Enables BFD support\n"
9645 "Detect Multiplier\n"
9646 "Required min receive interval\n"
9647 "Desired min transmit interval\n")
9648 #endif /* !HAVE_BFDD */
9650 static int ip_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
9651 const char *peer
, const char *local
)
9653 enum pim_msdp_err result
;
9654 struct in_addr peer_addr
;
9655 struct in_addr local_addr
;
9656 int ret
= CMD_SUCCESS
;
9658 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
9660 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
9661 errno
, safe_strerror(errno
));
9662 return CMD_WARNING_CONFIG_FAILED
;
9665 result
= inet_pton(AF_INET
, local
, &local_addr
);
9667 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", local
,
9668 errno
, safe_strerror(errno
));
9669 return CMD_WARNING_CONFIG_FAILED
;
9672 result
= pim_msdp_peer_add(pim
, peer_addr
, local_addr
, "default",
9675 case PIM_MSDP_ERR_NONE
:
9677 case PIM_MSDP_ERR_OOM
:
9678 ret
= CMD_WARNING_CONFIG_FAILED
;
9679 vty_out(vty
, "%% Out of memory\n");
9681 case PIM_MSDP_ERR_PEER_EXISTS
:
9683 vty_out(vty
, "%% Peer exists\n");
9685 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
9686 ret
= CMD_WARNING_CONFIG_FAILED
;
9687 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
9690 ret
= CMD_WARNING_CONFIG_FAILED
;
9691 vty_out(vty
, "%% peer add failed\n");
9697 DEFUN_HIDDEN (ip_msdp_peer
,
9699 "ip msdp peer A.B.C.D source A.B.C.D",
9702 "Configure MSDP peer\n"
9704 "Source address for TCP connection\n"
9705 "local ip address\n")
9707 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9708 return ip_msdp_peer_cmd_worker(pim
, vty
, argv
[3]->arg
, argv
[5]->arg
);
9711 static int ip_no_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
9714 enum pim_msdp_err result
;
9715 struct in_addr peer_addr
;
9717 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
9719 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
9720 errno
, safe_strerror(errno
));
9721 return CMD_WARNING_CONFIG_FAILED
;
9724 result
= pim_msdp_peer_del(pim
, peer_addr
);
9726 case PIM_MSDP_ERR_NONE
:
9728 case PIM_MSDP_ERR_NO_PEER
:
9729 vty_out(vty
, "%% Peer does not exist\n");
9732 vty_out(vty
, "%% peer del failed\n");
9735 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9738 DEFUN_HIDDEN (no_ip_msdp_peer
,
9739 no_ip_msdp_peer_cmd
,
9740 "no ip msdp peer A.B.C.D",
9744 "Delete MSDP peer\n"
9745 "peer ip address\n")
9747 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9748 return ip_no_msdp_peer_cmd_worker(pim
, vty
, argv
[4]->arg
);
9751 static int ip_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
9752 struct vty
*vty
, const char *mg
,
9755 enum pim_msdp_err result
;
9756 struct in_addr mbr_ip
;
9757 int ret
= CMD_SUCCESS
;
9759 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
9761 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
9762 errno
, safe_strerror(errno
));
9763 return CMD_WARNING_CONFIG_FAILED
;
9766 result
= pim_msdp_mg_mbr_add(pim
, mg
, mbr_ip
);
9768 case PIM_MSDP_ERR_NONE
:
9770 case PIM_MSDP_ERR_OOM
:
9771 ret
= CMD_WARNING_CONFIG_FAILED
;
9772 vty_out(vty
, "%% Out of memory\n");
9774 case PIM_MSDP_ERR_MG_MBR_EXISTS
:
9776 vty_out(vty
, "%% mesh-group member exists\n");
9778 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
9779 ret
= CMD_WARNING_CONFIG_FAILED
;
9780 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
9783 ret
= CMD_WARNING_CONFIG_FAILED
;
9784 vty_out(vty
, "%% member add failed\n");
9790 DEFUN (ip_msdp_mesh_group_member
,
9791 ip_msdp_mesh_group_member_cmd
,
9792 "ip msdp mesh-group WORD member A.B.C.D",
9795 "Configure MSDP mesh-group\n"
9797 "mesh group member\n"
9798 "peer ip address\n")
9800 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9801 return ip_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[3]->arg
,
9805 static int ip_no_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
9810 enum pim_msdp_err result
;
9811 struct in_addr mbr_ip
;
9813 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
9815 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
9816 errno
, safe_strerror(errno
));
9817 return CMD_WARNING_CONFIG_FAILED
;
9820 result
= pim_msdp_mg_mbr_del(pim
, mg
, mbr_ip
);
9822 case PIM_MSDP_ERR_NONE
:
9824 case PIM_MSDP_ERR_NO_MG
:
9825 vty_out(vty
, "%% mesh-group does not exist\n");
9827 case PIM_MSDP_ERR_NO_MG_MBR
:
9828 vty_out(vty
, "%% mesh-group member does not exist\n");
9831 vty_out(vty
, "%% mesh-group member del failed\n");
9834 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9836 DEFUN (no_ip_msdp_mesh_group_member
,
9837 no_ip_msdp_mesh_group_member_cmd
,
9838 "no ip msdp mesh-group WORD member A.B.C.D",
9842 "Delete MSDP mesh-group member\n"
9844 "mesh group member\n"
9845 "peer ip address\n")
9847 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9848 return ip_no_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[4]->arg
,
9852 static int ip_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
9853 struct vty
*vty
, const char *mg
,
9856 enum pim_msdp_err result
;
9857 struct in_addr src_ip
;
9859 result
= inet_pton(AF_INET
, src
, &src_ip
);
9861 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", src
,
9862 errno
, safe_strerror(errno
));
9863 return CMD_WARNING_CONFIG_FAILED
;
9866 result
= pim_msdp_mg_src_add(pim
, mg
, src_ip
);
9868 case PIM_MSDP_ERR_NONE
:
9870 case PIM_MSDP_ERR_OOM
:
9871 vty_out(vty
, "%% Out of memory\n");
9873 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
9874 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
9877 vty_out(vty
, "%% source add failed\n");
9880 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9884 DEFUN (ip_msdp_mesh_group_source
,
9885 ip_msdp_mesh_group_source_cmd
,
9886 "ip msdp mesh-group WORD source A.B.C.D",
9889 "Configure MSDP mesh-group\n"
9891 "mesh group local address\n"
9892 "source ip address for the TCP connection\n")
9894 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9895 return ip_msdp_mesh_group_source_cmd_worker(pim
, vty
, argv
[3]->arg
,
9899 static int ip_no_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
9903 enum pim_msdp_err result
;
9905 result
= pim_msdp_mg_src_del(pim
, mg
);
9907 case PIM_MSDP_ERR_NONE
:
9909 case PIM_MSDP_ERR_NO_MG
:
9910 vty_out(vty
, "%% mesh-group does not exist\n");
9913 vty_out(vty
, "%% mesh-group source del failed\n");
9916 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9919 static int ip_no_msdp_mesh_group_cmd_worker(struct pim_instance
*pim
,
9920 struct vty
*vty
, const char *mg
)
9922 enum pim_msdp_err result
;
9924 result
= pim_msdp_mg_del(pim
, mg
);
9926 case PIM_MSDP_ERR_NONE
:
9928 case PIM_MSDP_ERR_NO_MG
:
9929 vty_out(vty
, "%% mesh-group does not exist\n");
9932 vty_out(vty
, "%% mesh-group source del failed\n");
9935 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9938 DEFUN (no_ip_msdp_mesh_group_source
,
9939 no_ip_msdp_mesh_group_source_cmd
,
9940 "no ip msdp mesh-group WORD source [A.B.C.D]",
9944 "Delete MSDP mesh-group source\n"
9946 "mesh group source\n"
9947 "mesh group local address\n")
9949 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9951 return ip_no_msdp_mesh_group_source_cmd_worker(pim
, vty
, argv
[4]->arg
);
9954 DEFUN (no_ip_msdp_mesh_group
,
9955 no_ip_msdp_mesh_group_cmd
,
9956 "no ip msdp mesh-group [WORD]",
9960 "Delete MSDP mesh-group\n"
9963 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9966 return ip_no_msdp_mesh_group_cmd_worker(pim
, vty
, argv
[4]->arg
);
9968 return ip_no_msdp_mesh_group_cmd_worker(pim
, vty
, NULL
);
9971 static void print_empty_json_obj(struct vty
*vty
)
9974 json
= json_object_new_object();
9975 vty_out(vty
, "%s\n",
9976 json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
));
9977 json_object_free(json
);
9980 static void ip_msdp_show_mesh_group(struct pim_instance
*pim
, struct vty
*vty
,
9983 struct listnode
*mbrnode
;
9984 struct pim_msdp_mg_mbr
*mbr
;
9985 struct pim_msdp_mg
*mg
= pim
->msdp
.mg
;
9986 char mbr_str
[INET_ADDRSTRLEN
];
9987 char src_str
[INET_ADDRSTRLEN
];
9988 char state_str
[PIM_MSDP_STATE_STRLEN
];
9989 enum pim_msdp_peer_state state
;
9990 json_object
*json
= NULL
;
9991 json_object
*json_mg_row
= NULL
;
9992 json_object
*json_members
= NULL
;
9993 json_object
*json_row
= NULL
;
9997 print_empty_json_obj(vty
);
10001 pim_inet4_dump("<source?>", mg
->src_ip
, src_str
, sizeof(src_str
));
10003 json
= json_object_new_object();
10004 /* currently there is only one mesh group but we should still
10006 * it a dict with mg-name as key */
10007 json_mg_row
= json_object_new_object();
10008 json_object_string_add(json_mg_row
, "name",
10009 mg
->mesh_group_name
);
10010 json_object_string_add(json_mg_row
, "source", src_str
);
10012 vty_out(vty
, "Mesh group : %s\n", mg
->mesh_group_name
);
10013 vty_out(vty
, " Source : %s\n", src_str
);
10014 vty_out(vty
, " Member State\n");
10017 for (ALL_LIST_ELEMENTS_RO(mg
->mbr_list
, mbrnode
, mbr
)) {
10018 pim_inet4_dump("<mbr?>", mbr
->mbr_ip
, mbr_str
, sizeof(mbr_str
));
10020 state
= mbr
->mp
->state
;
10022 state
= PIM_MSDP_DISABLED
;
10024 pim_msdp_state_dump(state
, state_str
, sizeof(state_str
));
10026 json_row
= json_object_new_object();
10027 json_object_string_add(json_row
, "member", mbr_str
);
10028 json_object_string_add(json_row
, "state", state_str
);
10029 if (!json_members
) {
10030 json_members
= json_object_new_object();
10031 json_object_object_add(json_mg_row
, "members",
10034 json_object_object_add(json_members
, mbr_str
, json_row
);
10036 vty_out(vty
, " %-15s %11s\n", mbr_str
, state_str
);
10041 json_object_object_add(json
, mg
->mesh_group_name
, json_mg_row
);
10042 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10043 json
, JSON_C_TO_STRING_PRETTY
));
10044 json_object_free(json
);
10048 DEFUN (show_ip_msdp_mesh_group
,
10049 show_ip_msdp_mesh_group_cmd
,
10050 "show ip msdp [vrf NAME] mesh-group [json]",
10055 "MSDP mesh-group information\n"
10058 bool uj
= use_json(argc
, argv
);
10060 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10063 return CMD_WARNING
;
10065 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
10067 return CMD_SUCCESS
;
10070 DEFUN (show_ip_msdp_mesh_group_vrf_all
,
10071 show_ip_msdp_mesh_group_vrf_all_cmd
,
10072 "show ip msdp vrf all mesh-group [json]",
10077 "MSDP mesh-group information\n"
10080 bool uj
= use_json(argc
, argv
);
10085 vty_out(vty
, "{ ");
10086 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
10089 vty_out(vty
, ", ");
10090 vty_out(vty
, " \"%s\": ", vrf
->name
);
10093 vty_out(vty
, "VRF: %s\n", vrf
->name
);
10094 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
10097 vty_out(vty
, "}\n");
10099 return CMD_SUCCESS
;
10102 static void ip_msdp_show_peers(struct pim_instance
*pim
, struct vty
*vty
,
10105 struct listnode
*mpnode
;
10106 struct pim_msdp_peer
*mp
;
10107 char peer_str
[INET_ADDRSTRLEN
];
10108 char local_str
[INET_ADDRSTRLEN
];
10109 char state_str
[PIM_MSDP_STATE_STRLEN
];
10110 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
10112 json_object
*json
= NULL
;
10113 json_object
*json_row
= NULL
;
10117 json
= json_object_new_object();
10120 "Peer Local State Uptime SaCnt\n");
10123 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
10124 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
10125 now
= pim_time_monotonic_sec();
10126 pim_time_uptime(timebuf
, sizeof(timebuf
),
10129 strlcpy(timebuf
, "-", sizeof(timebuf
));
10131 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
10132 pim_inet4_dump("<local?>", mp
->local
, local_str
,
10133 sizeof(local_str
));
10134 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
10136 json_row
= json_object_new_object();
10137 json_object_string_add(json_row
, "peer", peer_str
);
10138 json_object_string_add(json_row
, "local", local_str
);
10139 json_object_string_add(json_row
, "state", state_str
);
10140 json_object_string_add(json_row
, "upTime", timebuf
);
10141 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
10142 json_object_object_add(json
, peer_str
, json_row
);
10144 vty_out(vty
, "%-15s %15s %11s %8s %6d\n", peer_str
,
10145 local_str
, state_str
, timebuf
, mp
->sa_cnt
);
10150 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10151 json
, JSON_C_TO_STRING_PRETTY
));
10152 json_object_free(json
);
10156 static void ip_msdp_show_peers_detail(struct pim_instance
*pim
, struct vty
*vty
,
10157 const char *peer
, bool uj
)
10159 struct listnode
*mpnode
;
10160 struct pim_msdp_peer
*mp
;
10161 char peer_str
[INET_ADDRSTRLEN
];
10162 char local_str
[INET_ADDRSTRLEN
];
10163 char state_str
[PIM_MSDP_STATE_STRLEN
];
10164 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
10165 char katimer
[PIM_MSDP_TIMER_STRLEN
];
10166 char crtimer
[PIM_MSDP_TIMER_STRLEN
];
10167 char holdtimer
[PIM_MSDP_TIMER_STRLEN
];
10169 json_object
*json
= NULL
;
10170 json_object
*json_row
= NULL
;
10173 json
= json_object_new_object();
10176 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
10177 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
10178 if (strcmp(peer
, "detail") && strcmp(peer
, peer_str
))
10181 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
10182 now
= pim_time_monotonic_sec();
10183 pim_time_uptime(timebuf
, sizeof(timebuf
),
10186 strlcpy(timebuf
, "-", sizeof(timebuf
));
10188 pim_inet4_dump("<local?>", mp
->local
, local_str
,
10189 sizeof(local_str
));
10190 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
10191 pim_time_timer_to_hhmmss(katimer
, sizeof(katimer
),
10193 pim_time_timer_to_hhmmss(crtimer
, sizeof(crtimer
),
10195 pim_time_timer_to_hhmmss(holdtimer
, sizeof(holdtimer
),
10199 json_row
= json_object_new_object();
10200 json_object_string_add(json_row
, "peer", peer_str
);
10201 json_object_string_add(json_row
, "local", local_str
);
10202 json_object_string_add(json_row
, "meshGroupName",
10203 mp
->mesh_group_name
);
10204 json_object_string_add(json_row
, "state", state_str
);
10205 json_object_string_add(json_row
, "upTime", timebuf
);
10206 json_object_string_add(json_row
, "keepAliveTimer",
10208 json_object_string_add(json_row
, "connRetryTimer",
10210 json_object_string_add(json_row
, "holdTimer",
10212 json_object_string_add(json_row
, "lastReset",
10214 json_object_int_add(json_row
, "connAttempts",
10215 mp
->conn_attempts
);
10216 json_object_int_add(json_row
, "establishedChanges",
10218 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
10219 json_object_int_add(json_row
, "kaSent", mp
->ka_tx_cnt
);
10220 json_object_int_add(json_row
, "kaRcvd", mp
->ka_rx_cnt
);
10221 json_object_int_add(json_row
, "saSent", mp
->sa_tx_cnt
);
10222 json_object_int_add(json_row
, "saRcvd", mp
->sa_rx_cnt
);
10223 json_object_object_add(json
, peer_str
, json_row
);
10225 vty_out(vty
, "Peer : %s\n", peer_str
);
10226 vty_out(vty
, " Local : %s\n", local_str
);
10227 vty_out(vty
, " Mesh Group : %s\n",
10228 mp
->mesh_group_name
);
10229 vty_out(vty
, " State : %s\n", state_str
);
10230 vty_out(vty
, " Uptime : %s\n", timebuf
);
10232 vty_out(vty
, " Keepalive Timer : %s\n", katimer
);
10233 vty_out(vty
, " Conn Retry Timer : %s\n", crtimer
);
10234 vty_out(vty
, " Hold Timer : %s\n", holdtimer
);
10235 vty_out(vty
, " Last Reset : %s\n",
10237 vty_out(vty
, " Conn Attempts : %d\n",
10238 mp
->conn_attempts
);
10239 vty_out(vty
, " Established Changes : %d\n",
10241 vty_out(vty
, " SA Count : %d\n",
10243 vty_out(vty
, " Statistics :\n");
10246 vty_out(vty
, " Keepalives : %10d %10d\n",
10247 mp
->ka_tx_cnt
, mp
->ka_rx_cnt
);
10248 vty_out(vty
, " SAs : %10d %10d\n",
10249 mp
->sa_tx_cnt
, mp
->sa_rx_cnt
);
10250 vty_out(vty
, "\n");
10255 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10256 json
, JSON_C_TO_STRING_PRETTY
));
10257 json_object_free(json
);
10261 DEFUN (show_ip_msdp_peer_detail
,
10262 show_ip_msdp_peer_detail_cmd
,
10263 "show ip msdp [vrf NAME] peer [detail|A.B.C.D] [json]",
10268 "MSDP peer information\n"
10269 "Detailed output\n"
10270 "peer ip address\n"
10273 bool uj
= use_json(argc
, argv
);
10275 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10278 return CMD_WARNING
;
10282 if (argv_find(argv
, argc
, "detail", &idx
))
10283 arg
= argv
[idx
]->text
;
10284 else if (argv_find(argv
, argc
, "A.B.C.D", &idx
))
10285 arg
= argv
[idx
]->arg
;
10288 ip_msdp_show_peers_detail(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
10290 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
10292 return CMD_SUCCESS
;
10295 DEFUN (show_ip_msdp_peer_detail_vrf_all
,
10296 show_ip_msdp_peer_detail_vrf_all_cmd
,
10297 "show ip msdp vrf all peer [detail|A.B.C.D] [json]",
10302 "MSDP peer information\n"
10303 "Detailed output\n"
10304 "peer ip address\n"
10308 bool uj
= use_json(argc
, argv
);
10313 vty_out(vty
, "{ ");
10314 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
10317 vty_out(vty
, ", ");
10318 vty_out(vty
, " \"%s\": ", vrf
->name
);
10321 vty_out(vty
, "VRF: %s\n", vrf
->name
);
10322 if (argv_find(argv
, argc
, "detail", &idx
)
10323 || argv_find(argv
, argc
, "A.B.C.D", &idx
))
10324 ip_msdp_show_peers_detail(vrf
->info
, vty
,
10325 argv
[idx
]->arg
, uj
);
10327 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
10330 vty_out(vty
, "}\n");
10332 return CMD_SUCCESS
;
10335 static void ip_msdp_show_sa(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
10337 struct listnode
*sanode
;
10338 struct pim_msdp_sa
*sa
;
10339 char src_str
[INET_ADDRSTRLEN
];
10340 char grp_str
[INET_ADDRSTRLEN
];
10341 char rp_str
[INET_ADDRSTRLEN
];
10342 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
10346 json_object
*json
= NULL
;
10347 json_object
*json_group
= NULL
;
10348 json_object
*json_row
= NULL
;
10351 json
= json_object_new_object();
10354 "Source Group RP Local SPT Uptime\n");
10357 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
10358 now
= pim_time_monotonic_sec();
10359 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
10360 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
10361 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
10362 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
10363 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
10365 strlcpy(spt_str
, "yes", sizeof(spt_str
));
10367 strlcpy(spt_str
, "no", sizeof(spt_str
));
10370 strlcpy(rp_str
, "-", sizeof(rp_str
));
10371 strlcpy(spt_str
, "-", sizeof(spt_str
));
10373 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
10374 strlcpy(local_str
, "yes", sizeof(local_str
));
10376 strlcpy(local_str
, "no", sizeof(local_str
));
10379 json_object_object_get_ex(json
, grp_str
, &json_group
);
10382 json_group
= json_object_new_object();
10383 json_object_object_add(json
, grp_str
,
10387 json_row
= json_object_new_object();
10388 json_object_string_add(json_row
, "source", src_str
);
10389 json_object_string_add(json_row
, "group", grp_str
);
10390 json_object_string_add(json_row
, "rp", rp_str
);
10391 json_object_string_add(json_row
, "local", local_str
);
10392 json_object_string_add(json_row
, "sptSetup", spt_str
);
10393 json_object_string_add(json_row
, "upTime", timebuf
);
10394 json_object_object_add(json_group
, src_str
, json_row
);
10396 vty_out(vty
, "%-15s %15s %15s %5c %3c %8s\n",
10397 src_str
, grp_str
, rp_str
, local_str
[0],
10398 spt_str
[0], timebuf
);
10403 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10404 json
, JSON_C_TO_STRING_PRETTY
));
10405 json_object_free(json
);
10409 static void ip_msdp_show_sa_entry_detail(struct pim_msdp_sa
*sa
,
10410 const char *src_str
,
10411 const char *grp_str
, struct vty
*vty
,
10412 bool uj
, json_object
*json
)
10414 char rp_str
[INET_ADDRSTRLEN
];
10415 char peer_str
[INET_ADDRSTRLEN
];
10416 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
10419 char statetimer
[PIM_MSDP_TIMER_STRLEN
];
10421 json_object
*json_group
= NULL
;
10422 json_object
*json_row
= NULL
;
10424 now
= pim_time_monotonic_sec();
10425 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
10426 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
10427 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
10428 pim_inet4_dump("<peer?>", sa
->peer
, peer_str
, sizeof(peer_str
));
10430 strlcpy(spt_str
, "yes", sizeof(spt_str
));
10432 strlcpy(spt_str
, "no", sizeof(spt_str
));
10435 strlcpy(rp_str
, "-", sizeof(rp_str
));
10436 strlcpy(peer_str
, "-", sizeof(peer_str
));
10437 strlcpy(spt_str
, "-", sizeof(spt_str
));
10439 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
10440 strlcpy(local_str
, "yes", sizeof(local_str
));
10442 strlcpy(local_str
, "no", sizeof(local_str
));
10444 pim_time_timer_to_hhmmss(statetimer
, sizeof(statetimer
),
10445 sa
->sa_state_timer
);
10447 json_object_object_get_ex(json
, grp_str
, &json_group
);
10450 json_group
= json_object_new_object();
10451 json_object_object_add(json
, grp_str
, json_group
);
10454 json_row
= json_object_new_object();
10455 json_object_string_add(json_row
, "source", src_str
);
10456 json_object_string_add(json_row
, "group", grp_str
);
10457 json_object_string_add(json_row
, "rp", rp_str
);
10458 json_object_string_add(json_row
, "local", local_str
);
10459 json_object_string_add(json_row
, "sptSetup", spt_str
);
10460 json_object_string_add(json_row
, "upTime", timebuf
);
10461 json_object_string_add(json_row
, "stateTimer", statetimer
);
10462 json_object_object_add(json_group
, src_str
, json_row
);
10464 vty_out(vty
, "SA : %s\n", sa
->sg_str
);
10465 vty_out(vty
, " RP : %s\n", rp_str
);
10466 vty_out(vty
, " Peer : %s\n", peer_str
);
10467 vty_out(vty
, " Local : %s\n", local_str
);
10468 vty_out(vty
, " SPT Setup : %s\n", spt_str
);
10469 vty_out(vty
, " Uptime : %s\n", timebuf
);
10470 vty_out(vty
, " State Timer : %s\n", statetimer
);
10471 vty_out(vty
, "\n");
10475 static void ip_msdp_show_sa_detail(struct pim_instance
*pim
, struct vty
*vty
,
10478 struct listnode
*sanode
;
10479 struct pim_msdp_sa
*sa
;
10480 char src_str
[INET_ADDRSTRLEN
];
10481 char grp_str
[INET_ADDRSTRLEN
];
10482 json_object
*json
= NULL
;
10485 json
= json_object_new_object();
10488 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
10489 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
10490 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
10491 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
, uj
,
10496 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10497 json
, JSON_C_TO_STRING_PRETTY
));
10498 json_object_free(json
);
10502 DEFUN (show_ip_msdp_sa_detail
,
10503 show_ip_msdp_sa_detail_cmd
,
10504 "show ip msdp [vrf NAME] sa detail [json]",
10509 "MSDP active-source information\n"
10510 "Detailed output\n"
10513 bool uj
= use_json(argc
, argv
);
10515 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10518 return CMD_WARNING
;
10520 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
10522 return CMD_SUCCESS
;
10525 DEFUN (show_ip_msdp_sa_detail_vrf_all
,
10526 show_ip_msdp_sa_detail_vrf_all_cmd
,
10527 "show ip msdp vrf all sa detail [json]",
10532 "MSDP active-source information\n"
10533 "Detailed output\n"
10536 bool uj
= use_json(argc
, argv
);
10541 vty_out(vty
, "{ ");
10542 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
10545 vty_out(vty
, ", ");
10546 vty_out(vty
, " \"%s\": ", vrf
->name
);
10549 vty_out(vty
, "VRF: %s\n", vrf
->name
);
10550 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
10553 vty_out(vty
, "}\n");
10555 return CMD_SUCCESS
;
10558 static void ip_msdp_show_sa_addr(struct pim_instance
*pim
, struct vty
*vty
,
10559 const char *addr
, bool uj
)
10561 struct listnode
*sanode
;
10562 struct pim_msdp_sa
*sa
;
10563 char src_str
[INET_ADDRSTRLEN
];
10564 char grp_str
[INET_ADDRSTRLEN
];
10565 json_object
*json
= NULL
;
10568 json
= json_object_new_object();
10571 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
10572 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
10573 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
10574 if (!strcmp(addr
, src_str
) || !strcmp(addr
, grp_str
)) {
10575 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
10581 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10582 json
, JSON_C_TO_STRING_PRETTY
));
10583 json_object_free(json
);
10587 static void ip_msdp_show_sa_sg(struct pim_instance
*pim
, struct vty
*vty
,
10588 const char *src
, const char *grp
, bool uj
)
10590 struct listnode
*sanode
;
10591 struct pim_msdp_sa
*sa
;
10592 char src_str
[INET_ADDRSTRLEN
];
10593 char grp_str
[INET_ADDRSTRLEN
];
10594 json_object
*json
= NULL
;
10597 json
= json_object_new_object();
10600 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
10601 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
10602 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
10603 if (!strcmp(src
, src_str
) && !strcmp(grp
, grp_str
)) {
10604 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
10610 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10611 json
, JSON_C_TO_STRING_PRETTY
));
10612 json_object_free(json
);
10616 DEFUN (show_ip_msdp_sa_sg
,
10617 show_ip_msdp_sa_sg_cmd
,
10618 "show ip msdp [vrf NAME] sa [A.B.C.D [A.B.C.D]] [json]",
10623 "MSDP active-source information\n"
10624 "source or group ip\n"
10628 bool uj
= use_json(argc
, argv
);
10632 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10635 return CMD_WARNING
;
10637 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
10639 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
10643 if (src_ip
&& grp_ip
)
10644 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
10646 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
10648 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
10650 return CMD_SUCCESS
;
10653 DEFUN (show_ip_msdp_sa_sg_vrf_all
,
10654 show_ip_msdp_sa_sg_vrf_all_cmd
,
10655 "show ip msdp vrf all sa [A.B.C.D [A.B.C.D]] [json]",
10660 "MSDP active-source information\n"
10661 "source or group ip\n"
10665 bool uj
= use_json(argc
, argv
);
10670 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
10672 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
10677 vty_out(vty
, "{ ");
10678 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
10681 vty_out(vty
, ", ");
10682 vty_out(vty
, " \"%s\": ", vrf
->name
);
10685 vty_out(vty
, "VRF: %s\n", vrf
->name
);
10687 if (src_ip
&& grp_ip
)
10688 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
10690 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
10692 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
10695 vty_out(vty
, "}\n");
10697 return CMD_SUCCESS
;
10700 struct pim_sg_cache_walk_data
{
10703 json_object
*json_group
;
10704 struct in_addr addr
;
10708 static void pim_show_vxlan_sg_entry(struct pim_vxlan_sg
*vxlan_sg
,
10709 struct pim_sg_cache_walk_data
*cwd
)
10711 struct vty
*vty
= cwd
->vty
;
10712 json_object
*json
= cwd
->json
;
10713 char src_str
[INET_ADDRSTRLEN
];
10714 char grp_str
[INET_ADDRSTRLEN
];
10715 json_object
*json_row
;
10716 bool installed
= (vxlan_sg
->up
) ? true : false;
10717 const char *iif_name
= vxlan_sg
->iif
?vxlan_sg
->iif
->name
:"-";
10718 const char *oif_name
;
10720 if (pim_vxlan_is_orig_mroute(vxlan_sg
))
10721 oif_name
= vxlan_sg
->orig_oif
?vxlan_sg
->orig_oif
->name
:"";
10723 oif_name
= vxlan_sg
->term_oif
?vxlan_sg
->term_oif
->name
:"";
10725 if (cwd
->addr_match
&& (vxlan_sg
->sg
.src
.s_addr
!= cwd
->addr
.s_addr
) &&
10726 (vxlan_sg
->sg
.grp
.s_addr
!= cwd
->addr
.s_addr
)) {
10729 pim_inet4_dump("<src?>", vxlan_sg
->sg
.src
, src_str
, sizeof(src_str
));
10730 pim_inet4_dump("<grp?>", vxlan_sg
->sg
.grp
, grp_str
, sizeof(grp_str
));
10732 json_object_object_get_ex(json
, grp_str
, &cwd
->json_group
);
10734 if (!cwd
->json_group
) {
10735 cwd
->json_group
= json_object_new_object();
10736 json_object_object_add(json
, grp_str
,
10740 json_row
= json_object_new_object();
10741 json_object_string_add(json_row
, "source", src_str
);
10742 json_object_string_add(json_row
, "group", grp_str
);
10743 json_object_string_add(json_row
, "input", iif_name
);
10744 json_object_string_add(json_row
, "output", oif_name
);
10746 json_object_boolean_true_add(json_row
, "installed");
10748 json_object_boolean_false_add(json_row
, "installed");
10749 json_object_object_add(cwd
->json_group
, src_str
, json_row
);
10751 vty_out(vty
, "%-15s %-15s %-15s %-15s %-5s\n",
10752 src_str
, grp_str
, iif_name
, oif_name
,
10757 static void pim_show_vxlan_sg_hash_entry(struct hash_bucket
*backet
, void *arg
)
10759 pim_show_vxlan_sg_entry((struct pim_vxlan_sg
*)backet
->data
,
10760 (struct pim_sg_cache_walk_data
*)arg
);
10763 static void pim_show_vxlan_sg(struct pim_instance
*pim
,
10764 struct vty
*vty
, bool uj
)
10766 json_object
*json
= NULL
;
10767 struct pim_sg_cache_walk_data cwd
;
10770 json
= json_object_new_object();
10772 vty_out(vty
, "Codes: I -> installed\n");
10774 "Source Group Input Output Flags\n");
10777 memset(&cwd
, 0, sizeof(cwd
));
10780 hash_iterate(pim
->vxlan
.sg_hash
, pim_show_vxlan_sg_hash_entry
, &cwd
);
10783 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10784 json
, JSON_C_TO_STRING_PRETTY
));
10785 json_object_free(json
);
10789 static void pim_show_vxlan_sg_match_addr(struct pim_instance
*pim
,
10790 struct vty
*vty
, char *addr_str
, bool uj
)
10792 json_object
*json
= NULL
;
10793 struct pim_sg_cache_walk_data cwd
;
10796 memset(&cwd
, 0, sizeof(cwd
));
10797 result
= inet_pton(AF_INET
, addr_str
, &cwd
.addr
);
10799 vty_out(vty
, "Bad address %s: errno=%d: %s\n", addr_str
,
10800 errno
, safe_strerror(errno
));
10805 json
= json_object_new_object();
10807 vty_out(vty
, "Codes: I -> installed\n");
10809 "Source Group Input Output Flags\n");
10814 cwd
.addr_match
= true;
10815 hash_iterate(pim
->vxlan
.sg_hash
, pim_show_vxlan_sg_hash_entry
, &cwd
);
10818 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10819 json
, JSON_C_TO_STRING_PRETTY
));
10820 json_object_free(json
);
10824 static void pim_show_vxlan_sg_one(struct pim_instance
*pim
,
10825 struct vty
*vty
, char *src_str
, char *grp_str
, bool uj
)
10827 json_object
*json
= NULL
;
10828 struct prefix_sg sg
;
10830 struct pim_vxlan_sg
*vxlan_sg
;
10831 const char *iif_name
;
10833 const char *oif_name
;
10835 result
= inet_pton(AF_INET
, src_str
, &sg
.src
);
10837 vty_out(vty
, "Bad src address %s: errno=%d: %s\n", src_str
,
10838 errno
, safe_strerror(errno
));
10841 result
= inet_pton(AF_INET
, grp_str
, &sg
.grp
);
10843 vty_out(vty
, "Bad grp address %s: errno=%d: %s\n", grp_str
,
10844 errno
, safe_strerror(errno
));
10848 sg
.family
= AF_INET
;
10849 sg
.prefixlen
= IPV4_MAX_BITLEN
;
10851 json
= json_object_new_object();
10853 vxlan_sg
= pim_vxlan_sg_find(pim
, &sg
);
10855 installed
= (vxlan_sg
->up
) ? true : false;
10856 iif_name
= vxlan_sg
->iif
?vxlan_sg
->iif
->name
:"-";
10858 if (pim_vxlan_is_orig_mroute(vxlan_sg
))
10860 vxlan_sg
->orig_oif
?vxlan_sg
->orig_oif
->name
:"";
10863 vxlan_sg
->term_oif
?vxlan_sg
->term_oif
->name
:"";
10866 json_object_string_add(json
, "source", src_str
);
10867 json_object_string_add(json
, "group", grp_str
);
10868 json_object_string_add(json
, "input", iif_name
);
10869 json_object_string_add(json
, "output", oif_name
);
10871 json_object_boolean_true_add(json
, "installed");
10873 json_object_boolean_false_add(json
,
10876 vty_out(vty
, "SG : %s\n", vxlan_sg
->sg_str
);
10877 vty_out(vty
, " Input : %s\n", iif_name
);
10878 vty_out(vty
, " Output : %s\n", oif_name
);
10879 vty_out(vty
, " installed : %s\n",
10880 installed
?"yes":"no");
10885 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10886 json
, JSON_C_TO_STRING_PRETTY
));
10887 json_object_free(json
);
10891 DEFUN (show_ip_pim_vxlan_sg
,
10892 show_ip_pim_vxlan_sg_cmd
,
10893 "show ip pim [vrf NAME] vxlan-groups [A.B.C.D [A.B.C.D]] [json]",
10898 "VxLAN BUM groups\n"
10899 "source or group ip\n"
10903 bool uj
= use_json(argc
, argv
);
10907 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10910 return CMD_WARNING
;
10912 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ?
10913 argv
[idx
++]->arg
:NULL
;
10914 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
) ?
10915 argv
[idx
]->arg
:NULL
;
10917 if (src_ip
&& grp_ip
)
10918 pim_show_vxlan_sg_one(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
10920 pim_show_vxlan_sg_match_addr(vrf
->info
, vty
, src_ip
, uj
);
10922 pim_show_vxlan_sg(vrf
->info
, vty
, uj
);
10924 return CMD_SUCCESS
;
10927 static void pim_show_vxlan_sg_work(struct pim_instance
*pim
,
10928 struct vty
*vty
, bool uj
)
10930 json_object
*json
= NULL
;
10931 struct pim_sg_cache_walk_data cwd
;
10932 struct listnode
*node
;
10933 struct pim_vxlan_sg
*vxlan_sg
;
10936 json
= json_object_new_object();
10938 vty_out(vty
, "Codes: I -> installed\n");
10940 "Source Group Input Flags\n");
10943 memset(&cwd
, 0, sizeof(cwd
));
10946 for (ALL_LIST_ELEMENTS_RO(pim_vxlan_p
->work_list
, node
, vxlan_sg
))
10947 pim_show_vxlan_sg_entry(vxlan_sg
, &cwd
);
10950 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10951 json
, JSON_C_TO_STRING_PRETTY
));
10952 json_object_free(json
);
10956 DEFUN_HIDDEN (show_ip_pim_vxlan_sg_work
,
10957 show_ip_pim_vxlan_sg_work_cmd
,
10958 "show ip pim [vrf NAME] vxlan-work [json]",
10963 "VxLAN work list\n"
10966 bool uj
= use_json(argc
, argv
);
10970 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10973 return CMD_WARNING
;
10975 pim_show_vxlan_sg_work(vrf
->info
, vty
, uj
);
10977 return CMD_SUCCESS
;
10980 DEFUN_HIDDEN (no_ip_pim_mlag
,
10981 no_ip_pim_mlag_cmd
,
10988 struct in_addr addr
;
10991 pim_vxlan_mlag_update(true/*mlag_enable*/,
10992 false/*peer_state*/, MLAG_ROLE_NONE
,
10993 NULL
/*peerlink*/, &addr
);
10995 return CMD_SUCCESS
;
10998 DEFUN_HIDDEN (ip_pim_mlag
,
11000 "ip pim mlag INTERFACE role [primary|secondary] state [up|down] addr A.B.C.D",
11004 "peerlink sub interface\n"
11006 "MLAG role primary\n"
11007 "MLAG role secondary\n"
11008 "peer session state\n"
11009 "peer session state up\n"
11010 "peer session state down\n"
11012 "unique ip address\n")
11014 struct interface
*ifp
;
11015 const char *peerlink
;
11020 struct in_addr reg_addr
;
11023 peerlink
= argv
[idx
]->arg
;
11024 ifp
= if_lookup_by_name(peerlink
, VRF_DEFAULT
);
11026 vty_out(vty
, "No such interface name %s\n", peerlink
);
11027 return CMD_WARNING
;
11031 if (!strcmp(argv
[idx
]->arg
, "primary")) {
11032 role
= MLAG_ROLE_PRIMARY
;
11033 } else if (!strcmp(argv
[idx
]->arg
, "secondary")) {
11034 role
= MLAG_ROLE_SECONDARY
;
11036 vty_out(vty
, "unknown MLAG role %s\n", argv
[idx
]->arg
);
11037 return CMD_WARNING
;
11041 if (!strcmp(argv
[idx
]->arg
, "up")) {
11043 } else if (strcmp(argv
[idx
]->arg
, "down")) {
11044 peer_state
= false;
11046 vty_out(vty
, "unknown MLAG state %s\n", argv
[idx
]->arg
);
11047 return CMD_WARNING
;
11051 result
= inet_pton(AF_INET
, argv
[idx
]->arg
, ®_addr
);
11053 vty_out(vty
, "%% Bad reg address %s: errno=%d: %s\n",
11055 errno
, safe_strerror(errno
));
11056 return CMD_WARNING_CONFIG_FAILED
;
11058 pim_vxlan_mlag_update(true, peer_state
, role
, ifp
, ®_addr
);
11060 return CMD_SUCCESS
;
11063 void pim_cmd_init(void)
11065 install_node(&interface_node
); /* INTERFACE_NODE */
11068 install_node(&debug_node
);
11070 install_element(ENABLE_NODE
, &pim_test_sg_keepalive_cmd
);
11072 install_element(CONFIG_NODE
, &ip_pim_rp_cmd
);
11073 install_element(VRF_NODE
, &ip_pim_rp_cmd
);
11074 install_element(CONFIG_NODE
, &no_ip_pim_rp_cmd
);
11075 install_element(VRF_NODE
, &no_ip_pim_rp_cmd
);
11076 install_element(CONFIG_NODE
, &ip_pim_rp_prefix_list_cmd
);
11077 install_element(VRF_NODE
, &ip_pim_rp_prefix_list_cmd
);
11078 install_element(CONFIG_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
11079 install_element(VRF_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
11080 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
11081 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
11082 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
11083 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
11084 install_element(CONFIG_NODE
, &ip_pim_ssm_prefix_list_cmd
);
11085 install_element(VRF_NODE
, &ip_pim_ssm_prefix_list_cmd
);
11086 install_element(CONFIG_NODE
, &ip_pim_register_suppress_cmd
);
11087 install_element(VRF_NODE
, &ip_pim_register_suppress_cmd
);
11088 install_element(CONFIG_NODE
, &no_ip_pim_register_suppress_cmd
);
11089 install_element(VRF_NODE
, &no_ip_pim_register_suppress_cmd
);
11090 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
11091 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
11092 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
11093 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
11094 install_element(CONFIG_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
11095 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
11096 install_element(CONFIG_NODE
,
11097 &no_ip_pim_spt_switchover_infinity_plist_cmd
);
11098 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_plist_cmd
);
11099 install_element(CONFIG_NODE
, &pim_register_accept_list_cmd
);
11100 install_element(VRF_NODE
, &pim_register_accept_list_cmd
);
11101 install_element(CONFIG_NODE
, &ip_pim_joinprune_time_cmd
);
11102 install_element(VRF_NODE
, &ip_pim_joinprune_time_cmd
);
11103 install_element(CONFIG_NODE
, &no_ip_pim_joinprune_time_cmd
);
11104 install_element(VRF_NODE
, &no_ip_pim_joinprune_time_cmd
);
11105 install_element(CONFIG_NODE
, &ip_pim_keep_alive_cmd
);
11106 install_element(VRF_NODE
, &ip_pim_keep_alive_cmd
);
11107 install_element(CONFIG_NODE
, &ip_pim_rp_keep_alive_cmd
);
11108 install_element(VRF_NODE
, &ip_pim_rp_keep_alive_cmd
);
11109 install_element(CONFIG_NODE
, &no_ip_pim_keep_alive_cmd
);
11110 install_element(VRF_NODE
, &no_ip_pim_keep_alive_cmd
);
11111 install_element(CONFIG_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
11112 install_element(VRF_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
11113 install_element(CONFIG_NODE
, &ip_pim_packets_cmd
);
11114 install_element(VRF_NODE
, &ip_pim_packets_cmd
);
11115 install_element(CONFIG_NODE
, &no_ip_pim_packets_cmd
);
11116 install_element(VRF_NODE
, &no_ip_pim_packets_cmd
);
11117 install_element(CONFIG_NODE
, &ip_pim_v6_secondary_cmd
);
11118 install_element(VRF_NODE
, &ip_pim_v6_secondary_cmd
);
11119 install_element(CONFIG_NODE
, &no_ip_pim_v6_secondary_cmd
);
11120 install_element(VRF_NODE
, &no_ip_pim_v6_secondary_cmd
);
11121 install_element(CONFIG_NODE
, &ip_ssmpingd_cmd
);
11122 install_element(VRF_NODE
, &ip_ssmpingd_cmd
);
11123 install_element(CONFIG_NODE
, &no_ip_ssmpingd_cmd
);
11124 install_element(VRF_NODE
, &no_ip_ssmpingd_cmd
);
11125 install_element(CONFIG_NODE
, &ip_msdp_peer_cmd
);
11126 install_element(VRF_NODE
, &ip_msdp_peer_cmd
);
11127 install_element(CONFIG_NODE
, &no_ip_msdp_peer_cmd
);
11128 install_element(VRF_NODE
, &no_ip_msdp_peer_cmd
);
11129 install_element(CONFIG_NODE
, &ip_pim_ecmp_cmd
);
11130 install_element(VRF_NODE
, &ip_pim_ecmp_cmd
);
11131 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_cmd
);
11132 install_element(VRF_NODE
, &no_ip_pim_ecmp_cmd
);
11133 install_element(CONFIG_NODE
, &ip_pim_ecmp_rebalance_cmd
);
11134 install_element(VRF_NODE
, &ip_pim_ecmp_rebalance_cmd
);
11135 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
11136 install_element(VRF_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
11137 install_element(CONFIG_NODE
, &ip_pim_mlag_cmd
);
11138 install_element(CONFIG_NODE
, &no_ip_pim_mlag_cmd
);
11139 install_element(CONFIG_NODE
, &igmp_group_watermark_cmd
);
11140 install_element(VRF_NODE
, &igmp_group_watermark_cmd
);
11141 install_element(CONFIG_NODE
, &no_igmp_group_watermark_cmd
);
11142 install_element(VRF_NODE
, &no_igmp_group_watermark_cmd
);
11144 install_element(INTERFACE_NODE
, &interface_ip_igmp_cmd
);
11145 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_cmd
);
11146 install_element(INTERFACE_NODE
, &interface_ip_igmp_join_cmd
);
11147 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_join_cmd
);
11148 install_element(INTERFACE_NODE
, &interface_ip_igmp_version_cmd
);
11149 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_version_cmd
);
11150 install_element(INTERFACE_NODE
, &interface_ip_igmp_query_interval_cmd
);
11151 install_element(INTERFACE_NODE
,
11152 &interface_no_ip_igmp_query_interval_cmd
);
11153 install_element(INTERFACE_NODE
,
11154 &interface_ip_igmp_query_max_response_time_cmd
);
11155 install_element(INTERFACE_NODE
,
11156 &interface_no_ip_igmp_query_max_response_time_cmd
);
11157 install_element(INTERFACE_NODE
,
11158 &interface_ip_igmp_query_max_response_time_dsec_cmd
);
11159 install_element(INTERFACE_NODE
,
11160 &interface_no_ip_igmp_query_max_response_time_dsec_cmd
);
11161 install_element(INTERFACE_NODE
,
11162 &interface_ip_igmp_last_member_query_count_cmd
);
11163 install_element(INTERFACE_NODE
,
11164 &interface_no_ip_igmp_last_member_query_count_cmd
);
11165 install_element(INTERFACE_NODE
,
11166 &interface_ip_igmp_last_member_query_interval_cmd
);
11167 install_element(INTERFACE_NODE
,
11168 &interface_no_ip_igmp_last_member_query_interval_cmd
);
11169 install_element(INTERFACE_NODE
, &interface_ip_pim_activeactive_cmd
);
11170 install_element(INTERFACE_NODE
, &interface_ip_pim_ssm_cmd
);
11171 install_element(INTERFACE_NODE
, &interface_no_ip_pim_ssm_cmd
);
11172 install_element(INTERFACE_NODE
, &interface_ip_pim_sm_cmd
);
11173 install_element(INTERFACE_NODE
, &interface_no_ip_pim_sm_cmd
);
11174 install_element(INTERFACE_NODE
, &interface_ip_pim_cmd
);
11175 install_element(INTERFACE_NODE
, &interface_no_ip_pim_cmd
);
11176 install_element(INTERFACE_NODE
, &interface_ip_pim_drprio_cmd
);
11177 install_element(INTERFACE_NODE
, &interface_no_ip_pim_drprio_cmd
);
11178 install_element(INTERFACE_NODE
, &interface_ip_pim_hello_cmd
);
11179 install_element(INTERFACE_NODE
, &interface_no_ip_pim_hello_cmd
);
11180 install_element(INTERFACE_NODE
, &interface_ip_pim_boundary_oil_cmd
);
11181 install_element(INTERFACE_NODE
, &interface_no_ip_pim_boundary_oil_cmd
);
11182 install_element(INTERFACE_NODE
, &interface_ip_igmp_query_generate_cmd
);
11184 // Static mroutes NEB
11185 install_element(INTERFACE_NODE
, &interface_ip_mroute_cmd
);
11186 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_cmd
);
11188 install_element(VIEW_NODE
, &show_ip_igmp_interface_cmd
);
11189 install_element(VIEW_NODE
, &show_ip_igmp_interface_vrf_all_cmd
);
11190 install_element(VIEW_NODE
, &show_ip_igmp_join_cmd
);
11191 install_element(VIEW_NODE
, &show_ip_igmp_join_vrf_all_cmd
);
11192 install_element(VIEW_NODE
, &show_ip_igmp_groups_cmd
);
11193 install_element(VIEW_NODE
, &show_ip_igmp_groups_vrf_all_cmd
);
11194 install_element(VIEW_NODE
, &show_ip_igmp_groups_retransmissions_cmd
);
11195 install_element(VIEW_NODE
, &show_ip_igmp_sources_cmd
);
11196 install_element(VIEW_NODE
, &show_ip_igmp_sources_retransmissions_cmd
);
11197 install_element(VIEW_NODE
, &show_ip_igmp_statistics_cmd
);
11198 install_element(VIEW_NODE
, &show_ip_pim_assert_cmd
);
11199 install_element(VIEW_NODE
, &show_ip_pim_assert_internal_cmd
);
11200 install_element(VIEW_NODE
, &show_ip_pim_assert_metric_cmd
);
11201 install_element(VIEW_NODE
, &show_ip_pim_assert_winner_metric_cmd
);
11202 install_element(VIEW_NODE
, &show_ip_pim_interface_traffic_cmd
);
11203 install_element(VIEW_NODE
, &show_ip_pim_interface_cmd
);
11204 install_element(VIEW_NODE
, &show_ip_pim_interface_vrf_all_cmd
);
11205 install_element(VIEW_NODE
, &show_ip_pim_join_cmd
);
11206 install_element(VIEW_NODE
, &show_ip_pim_join_vrf_all_cmd
);
11207 install_element(VIEW_NODE
, &show_ip_pim_jp_agg_cmd
);
11208 install_element(VIEW_NODE
, &show_ip_pim_local_membership_cmd
);
11209 install_element(VIEW_NODE
, &show_ip_pim_mlag_summary_cmd
);
11210 install_element(VIEW_NODE
, &show_ip_pim_mlag_up_cmd
);
11211 install_element(VIEW_NODE
, &show_ip_pim_mlag_up_vrf_all_cmd
);
11212 install_element(VIEW_NODE
, &show_ip_pim_neighbor_cmd
);
11213 install_element(VIEW_NODE
, &show_ip_pim_neighbor_vrf_all_cmd
);
11214 install_element(VIEW_NODE
, &show_ip_pim_rpf_cmd
);
11215 install_element(VIEW_NODE
, &show_ip_pim_rpf_vrf_all_cmd
);
11216 install_element(VIEW_NODE
, &show_ip_pim_secondary_cmd
);
11217 install_element(VIEW_NODE
, &show_ip_pim_state_cmd
);
11218 install_element(VIEW_NODE
, &show_ip_pim_state_vrf_all_cmd
);
11219 install_element(VIEW_NODE
, &show_ip_pim_upstream_cmd
);
11220 install_element(VIEW_NODE
, &show_ip_pim_upstream_vrf_all_cmd
);
11221 install_element(VIEW_NODE
, &show_ip_pim_channel_cmd
);
11222 install_element(VIEW_NODE
, &show_ip_pim_upstream_join_desired_cmd
);
11223 install_element(VIEW_NODE
, &show_ip_pim_upstream_rpf_cmd
);
11224 install_element(VIEW_NODE
, &show_ip_pim_rp_cmd
);
11225 install_element(VIEW_NODE
, &show_ip_pim_rp_vrf_all_cmd
);
11226 install_element(VIEW_NODE
, &show_ip_pim_bsr_cmd
);
11227 install_element(VIEW_NODE
, &show_ip_multicast_cmd
);
11228 install_element(VIEW_NODE
, &show_ip_multicast_vrf_all_cmd
);
11229 install_element(VIEW_NODE
, &show_ip_multicast_count_cmd
);
11230 install_element(VIEW_NODE
, &show_ip_multicast_count_vrf_all_cmd
);
11231 install_element(VIEW_NODE
, &show_ip_mroute_cmd
);
11232 install_element(VIEW_NODE
, &show_ip_mroute_vrf_all_cmd
);
11233 install_element(VIEW_NODE
, &show_ip_mroute_count_cmd
);
11234 install_element(VIEW_NODE
, &show_ip_mroute_count_vrf_all_cmd
);
11235 install_element(VIEW_NODE
, &show_ip_mroute_summary_cmd
);
11236 install_element(VIEW_NODE
, &show_ip_mroute_summary_vrf_all_cmd
);
11237 install_element(VIEW_NODE
, &show_ip_rib_cmd
);
11238 install_element(VIEW_NODE
, &show_ip_ssmpingd_cmd
);
11239 install_element(VIEW_NODE
, &show_ip_pim_nexthop_cmd
);
11240 install_element(VIEW_NODE
, &show_ip_pim_nexthop_lookup_cmd
);
11241 install_element(VIEW_NODE
, &show_ip_pim_bsrp_cmd
);
11242 install_element(VIEW_NODE
, &show_ip_pim_bsm_db_cmd
);
11243 install_element(VIEW_NODE
, &show_ip_pim_statistics_cmd
);
11245 install_element(ENABLE_NODE
, &clear_ip_mroute_count_cmd
);
11246 install_element(ENABLE_NODE
, &clear_ip_interfaces_cmd
);
11247 install_element(ENABLE_NODE
, &clear_ip_igmp_interfaces_cmd
);
11248 install_element(ENABLE_NODE
, &clear_ip_mroute_cmd
);
11249 install_element(ENABLE_NODE
, &clear_ip_pim_interfaces_cmd
);
11250 install_element(ENABLE_NODE
, &clear_ip_pim_interface_traffic_cmd
);
11251 install_element(ENABLE_NODE
, &clear_ip_pim_oil_cmd
);
11252 install_element(ENABLE_NODE
, &clear_ip_pim_statistics_cmd
);
11254 install_element(ENABLE_NODE
, &show_debugging_pim_cmd
);
11256 install_element(ENABLE_NODE
, &debug_igmp_cmd
);
11257 install_element(ENABLE_NODE
, &no_debug_igmp_cmd
);
11258 install_element(ENABLE_NODE
, &debug_igmp_events_cmd
);
11259 install_element(ENABLE_NODE
, &no_debug_igmp_events_cmd
);
11260 install_element(ENABLE_NODE
, &debug_igmp_packets_cmd
);
11261 install_element(ENABLE_NODE
, &no_debug_igmp_packets_cmd
);
11262 install_element(ENABLE_NODE
, &debug_igmp_trace_cmd
);
11263 install_element(ENABLE_NODE
, &no_debug_igmp_trace_cmd
);
11264 install_element(ENABLE_NODE
, &debug_mroute_cmd
);
11265 install_element(ENABLE_NODE
, &debug_mroute_detail_cmd
);
11266 install_element(ENABLE_NODE
, &no_debug_mroute_cmd
);
11267 install_element(ENABLE_NODE
, &no_debug_mroute_detail_cmd
);
11268 install_element(ENABLE_NODE
, &debug_pim_static_cmd
);
11269 install_element(ENABLE_NODE
, &no_debug_pim_static_cmd
);
11270 install_element(ENABLE_NODE
, &debug_pim_cmd
);
11271 install_element(ENABLE_NODE
, &no_debug_pim_cmd
);
11272 install_element(ENABLE_NODE
, &debug_pim_nht_cmd
);
11273 install_element(ENABLE_NODE
, &no_debug_pim_nht_cmd
);
11274 install_element(ENABLE_NODE
, &debug_pim_nht_rp_cmd
);
11275 install_element(ENABLE_NODE
, &no_debug_pim_nht_rp_cmd
);
11276 install_element(ENABLE_NODE
, &debug_pim_events_cmd
);
11277 install_element(ENABLE_NODE
, &no_debug_pim_events_cmd
);
11278 install_element(ENABLE_NODE
, &debug_pim_packets_cmd
);
11279 install_element(ENABLE_NODE
, &no_debug_pim_packets_cmd
);
11280 install_element(ENABLE_NODE
, &debug_pim_packetdump_send_cmd
);
11281 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_send_cmd
);
11282 install_element(ENABLE_NODE
, &debug_pim_packetdump_recv_cmd
);
11283 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_recv_cmd
);
11284 install_element(ENABLE_NODE
, &debug_pim_trace_cmd
);
11285 install_element(ENABLE_NODE
, &no_debug_pim_trace_cmd
);
11286 install_element(ENABLE_NODE
, &debug_pim_trace_detail_cmd
);
11287 install_element(ENABLE_NODE
, &no_debug_pim_trace_detail_cmd
);
11288 install_element(ENABLE_NODE
, &debug_ssmpingd_cmd
);
11289 install_element(ENABLE_NODE
, &no_debug_ssmpingd_cmd
);
11290 install_element(ENABLE_NODE
, &debug_pim_zebra_cmd
);
11291 install_element(ENABLE_NODE
, &no_debug_pim_zebra_cmd
);
11292 install_element(ENABLE_NODE
, &debug_pim_mlag_cmd
);
11293 install_element(ENABLE_NODE
, &no_debug_pim_mlag_cmd
);
11294 install_element(ENABLE_NODE
, &debug_pim_vxlan_cmd
);
11295 install_element(ENABLE_NODE
, &no_debug_pim_vxlan_cmd
);
11296 install_element(ENABLE_NODE
, &debug_msdp_cmd
);
11297 install_element(ENABLE_NODE
, &no_debug_msdp_cmd
);
11298 install_element(ENABLE_NODE
, &debug_msdp_events_cmd
);
11299 install_element(ENABLE_NODE
, &no_debug_msdp_events_cmd
);
11300 install_element(ENABLE_NODE
, &debug_msdp_packets_cmd
);
11301 install_element(ENABLE_NODE
, &no_debug_msdp_packets_cmd
);
11302 install_element(ENABLE_NODE
, &debug_mtrace_cmd
);
11303 install_element(ENABLE_NODE
, &no_debug_mtrace_cmd
);
11304 install_element(ENABLE_NODE
, &debug_bsm_cmd
);
11305 install_element(ENABLE_NODE
, &no_debug_bsm_cmd
);
11307 install_element(CONFIG_NODE
, &debug_igmp_cmd
);
11308 install_element(CONFIG_NODE
, &no_debug_igmp_cmd
);
11309 install_element(CONFIG_NODE
, &debug_igmp_events_cmd
);
11310 install_element(CONFIG_NODE
, &no_debug_igmp_events_cmd
);
11311 install_element(CONFIG_NODE
, &debug_igmp_packets_cmd
);
11312 install_element(CONFIG_NODE
, &no_debug_igmp_packets_cmd
);
11313 install_element(CONFIG_NODE
, &debug_igmp_trace_cmd
);
11314 install_element(CONFIG_NODE
, &no_debug_igmp_trace_cmd
);
11315 install_element(CONFIG_NODE
, &debug_mroute_cmd
);
11316 install_element(CONFIG_NODE
, &debug_mroute_detail_cmd
);
11317 install_element(CONFIG_NODE
, &no_debug_mroute_cmd
);
11318 install_element(CONFIG_NODE
, &no_debug_mroute_detail_cmd
);
11319 install_element(CONFIG_NODE
, &debug_pim_static_cmd
);
11320 install_element(CONFIG_NODE
, &no_debug_pim_static_cmd
);
11321 install_element(CONFIG_NODE
, &debug_pim_cmd
);
11322 install_element(CONFIG_NODE
, &no_debug_pim_cmd
);
11323 install_element(CONFIG_NODE
, &debug_pim_nht_cmd
);
11324 install_element(CONFIG_NODE
, &no_debug_pim_nht_cmd
);
11325 install_element(CONFIG_NODE
, &debug_pim_nht_rp_cmd
);
11326 install_element(CONFIG_NODE
, &no_debug_pim_nht_rp_cmd
);
11327 install_element(CONFIG_NODE
, &debug_pim_events_cmd
);
11328 install_element(CONFIG_NODE
, &no_debug_pim_events_cmd
);
11329 install_element(CONFIG_NODE
, &debug_pim_packets_cmd
);
11330 install_element(CONFIG_NODE
, &no_debug_pim_packets_cmd
);
11331 install_element(CONFIG_NODE
, &debug_pim_trace_cmd
);
11332 install_element(CONFIG_NODE
, &no_debug_pim_trace_cmd
);
11333 install_element(CONFIG_NODE
, &debug_pim_trace_detail_cmd
);
11334 install_element(CONFIG_NODE
, &no_debug_pim_trace_detail_cmd
);
11335 install_element(CONFIG_NODE
, &debug_ssmpingd_cmd
);
11336 install_element(CONFIG_NODE
, &no_debug_ssmpingd_cmd
);
11337 install_element(CONFIG_NODE
, &debug_pim_zebra_cmd
);
11338 install_element(CONFIG_NODE
, &no_debug_pim_zebra_cmd
);
11339 install_element(CONFIG_NODE
, &debug_pim_mlag_cmd
);
11340 install_element(CONFIG_NODE
, &no_debug_pim_mlag_cmd
);
11341 install_element(CONFIG_NODE
, &debug_pim_vxlan_cmd
);
11342 install_element(CONFIG_NODE
, &no_debug_pim_vxlan_cmd
);
11343 install_element(CONFIG_NODE
, &debug_msdp_cmd
);
11344 install_element(CONFIG_NODE
, &no_debug_msdp_cmd
);
11345 install_element(CONFIG_NODE
, &debug_msdp_events_cmd
);
11346 install_element(CONFIG_NODE
, &no_debug_msdp_events_cmd
);
11347 install_element(CONFIG_NODE
, &debug_msdp_packets_cmd
);
11348 install_element(CONFIG_NODE
, &no_debug_msdp_packets_cmd
);
11349 install_element(CONFIG_NODE
, &debug_mtrace_cmd
);
11350 install_element(CONFIG_NODE
, &no_debug_mtrace_cmd
);
11351 install_element(CONFIG_NODE
, &debug_bsm_cmd
);
11352 install_element(CONFIG_NODE
, &no_debug_bsm_cmd
);
11354 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_member_cmd
);
11355 install_element(VRF_NODE
, &ip_msdp_mesh_group_member_cmd
);
11356 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
11357 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
11358 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_source_cmd
);
11359 install_element(VRF_NODE
, &ip_msdp_mesh_group_source_cmd
);
11360 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
11361 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
11362 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_cmd
);
11363 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_cmd
);
11364 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_cmd
);
11365 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_vrf_all_cmd
);
11366 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_cmd
);
11367 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_vrf_all_cmd
);
11368 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_cmd
);
11369 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_vrf_all_cmd
);
11370 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_cmd
);
11371 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_vrf_all_cmd
);
11372 install_element(VIEW_NODE
, &show_ip_pim_ssm_range_cmd
);
11373 install_element(VIEW_NODE
, &show_ip_pim_group_type_cmd
);
11374 install_element(VIEW_NODE
, &show_ip_pim_vxlan_sg_cmd
);
11375 install_element(VIEW_NODE
, &show_ip_pim_vxlan_sg_work_cmd
);
11376 install_element(INTERFACE_NODE
, &interface_pim_use_source_cmd
);
11377 install_element(INTERFACE_NODE
, &interface_no_pim_use_source_cmd
);
11378 /* Install BSM command */
11379 install_element(INTERFACE_NODE
, &ip_pim_bsm_cmd
);
11380 install_element(INTERFACE_NODE
, &no_ip_pim_bsm_cmd
);
11381 install_element(INTERFACE_NODE
, &ip_pim_ucast_bsm_cmd
);
11382 install_element(INTERFACE_NODE
, &no_ip_pim_ucast_bsm_cmd
);
11383 /* Install BFD command */
11384 install_element(INTERFACE_NODE
, &ip_pim_bfd_cmd
);
11385 install_element(INTERFACE_NODE
, &ip_pim_bfd_param_cmd
);
11386 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_cmd
);
11388 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_param_cmd
);
11389 #endif /* !HAVE_BFDD */