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
;
202 char buf
[PREFIX_STRLEN
];
204 ifaddr
= pim_ifp
->primary_address
;
206 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
207 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
208 pim_inet4_dump("<assrt_win?>", ch
->ifassert_winner
, winner_str
,
211 pim_time_uptime(uptime
, sizeof(uptime
), now
- ch
->ifassert_creation
);
212 pim_time_timer_to_mmss(timer
, sizeof(timer
), ch
->t_ifassert_timer
);
214 vty_out(vty
, "%-16s %-15s %-15s %-15s %-6s %-15s %-8s %-5s\n",
216 inet_ntop(AF_INET
, &ifaddr
, buf
, sizeof(buf
)), ch_src_str
,
217 ch_grp_str
, pim_ifchannel_ifassert_name(ch
->ifassert_state
),
218 winner_str
, uptime
, timer
);
221 static void pim_show_assert(struct pim_instance
*pim
, struct vty
*vty
)
223 struct pim_interface
*pim_ifp
;
224 struct pim_ifchannel
*ch
;
225 struct interface
*ifp
;
228 now
= pim_time_monotonic_sec();
231 "Interface Address Source Group State Winner Uptime Timer\n");
233 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
238 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
239 pim_show_assert_helper(vty
, pim_ifp
, ch
, now
);
240 } /* scan interface channels */
244 static void pim_show_assert_internal_helper(struct vty
*vty
,
245 struct pim_interface
*pim_ifp
,
246 struct pim_ifchannel
*ch
)
248 char ch_src_str
[INET_ADDRSTRLEN
];
249 char ch_grp_str
[INET_ADDRSTRLEN
];
250 struct in_addr ifaddr
;
251 char buf
[PREFIX_STRLEN
];
253 ifaddr
= pim_ifp
->primary_address
;
255 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
256 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
257 vty_out(vty
, "%-16s %-15s %-15s %-15s %-3s %-3s %-3s %-4s\n",
259 inet_ntop(AF_INET
, &ifaddr
, buf
, sizeof(buf
)),
260 ch_src_str
, ch_grp_str
,
261 PIM_IF_FLAG_TEST_COULD_ASSERT(ch
->flags
) ? "yes" : "no",
262 pim_macro_ch_could_assert_eval(ch
) ? "yes" : "no",
263 PIM_IF_FLAG_TEST_ASSERT_TRACKING_DESIRED(ch
->flags
) ? "yes"
265 pim_macro_assert_tracking_desired_eval(ch
) ? "yes" : "no");
268 static void pim_show_assert_internal(struct pim_instance
*pim
, struct vty
*vty
)
270 struct pim_interface
*pim_ifp
;
271 struct pim_ifchannel
*ch
;
272 struct interface
*ifp
;
276 "ECA: Evaluate CouldAssert\n"
277 "ATD: AssertTrackingDesired\n"
278 "eATD: Evaluate AssertTrackingDesired\n\n");
281 "Interface Address Source Group CA eCA ATD eATD\n");
282 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
287 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
288 pim_show_assert_internal_helper(vty
, pim_ifp
, ch
);
289 } /* scan interface channels */
293 static void pim_show_assert_metric_helper(struct vty
*vty
,
294 struct pim_interface
*pim_ifp
,
295 struct pim_ifchannel
*ch
)
297 char ch_src_str
[INET_ADDRSTRLEN
];
298 char ch_grp_str
[INET_ADDRSTRLEN
];
299 char addr_str
[INET_ADDRSTRLEN
];
300 struct pim_assert_metric am
;
301 struct in_addr ifaddr
;
302 char buf
[PREFIX_STRLEN
];
304 ifaddr
= pim_ifp
->primary_address
;
306 am
= pim_macro_spt_assert_metric(&ch
->upstream
->rpf
,
307 pim_ifp
->primary_address
);
309 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
310 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
311 pim_inet4_dump("<addr?>", am
.ip_address
, addr_str
, sizeof(addr_str
));
313 vty_out(vty
, "%-16s %-15s %-15s %-15s %-3s %4u %6u %-15s\n",
315 inet_ntop(AF_INET
, &ifaddr
, buf
, sizeof(buf
)),
316 ch_src_str
, ch_grp_str
, am
.rpt_bit_flag
? "yes" : "no",
317 am
.metric_preference
, am
.route_metric
, addr_str
);
320 static void pim_show_assert_metric(struct pim_instance
*pim
, struct vty
*vty
)
322 struct pim_interface
*pim_ifp
;
323 struct pim_ifchannel
*ch
;
324 struct interface
*ifp
;
327 "Interface Address Source Group RPT Pref Metric Address \n");
329 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
334 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
335 pim_show_assert_metric_helper(vty
, pim_ifp
, ch
);
336 } /* scan interface channels */
340 static void pim_show_assert_winner_metric_helper(struct vty
*vty
,
341 struct pim_interface
*pim_ifp
,
342 struct pim_ifchannel
*ch
)
344 char ch_src_str
[INET_ADDRSTRLEN
];
345 char ch_grp_str
[INET_ADDRSTRLEN
];
346 char addr_str
[INET_ADDRSTRLEN
];
347 struct pim_assert_metric
*am
;
348 struct in_addr ifaddr
;
351 char buf
[PREFIX_STRLEN
];
353 ifaddr
= pim_ifp
->primary_address
;
355 am
= &ch
->ifassert_winner_metric
;
357 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
358 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
359 pim_inet4_dump("<addr?>", am
->ip_address
, addr_str
, sizeof(addr_str
));
361 if (am
->metric_preference
== PIM_ASSERT_METRIC_PREFERENCE_MAX
)
362 snprintf(pref_str
, sizeof(pref_str
), "INFI");
364 snprintf(pref_str
, sizeof(pref_str
), "%4u",
365 am
->metric_preference
);
367 if (am
->route_metric
== PIM_ASSERT_ROUTE_METRIC_MAX
)
368 snprintf(metr_str
, sizeof(metr_str
), "INFI");
370 snprintf(metr_str
, sizeof(metr_str
), "%6u", am
->route_metric
);
372 vty_out(vty
, "%-16s %-15s %-15s %-15s %-3s %-4s %-6s %-15s\n",
374 inet_ntop(AF_INET
, &ifaddr
, buf
, sizeof(buf
)), ch_src_str
,
375 ch_grp_str
, am
->rpt_bit_flag
? "yes" : "no", pref_str
, metr_str
,
379 static void pim_show_assert_winner_metric(struct pim_instance
*pim
,
382 struct pim_interface
*pim_ifp
;
383 struct pim_ifchannel
*ch
;
384 struct interface
*ifp
;
387 "Interface Address Source Group RPT Pref Metric Address \n");
389 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
394 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
395 pim_show_assert_winner_metric_helper(vty
, pim_ifp
, ch
);
396 } /* scan interface channels */
400 static void json_object_pim_ifp_add(struct json_object
*json
,
401 struct interface
*ifp
)
403 struct pim_interface
*pim_ifp
;
404 char buf
[PREFIX_STRLEN
];
407 json_object_string_add(json
, "name", ifp
->name
);
408 json_object_string_add(json
, "state", if_is_up(ifp
) ? "up" : "down");
409 json_object_string_add(json
, "address",
410 inet_ntop(AF_INET
, &pim_ifp
->primary_address
,
412 json_object_int_add(json
, "index", ifp
->ifindex
);
414 if (if_is_multicast(ifp
))
415 json_object_boolean_true_add(json
, "flagMulticast");
417 if (if_is_broadcast(ifp
))
418 json_object_boolean_true_add(json
, "flagBroadcast");
420 if (ifp
->flags
& IFF_ALLMULTI
)
421 json_object_boolean_true_add(json
, "flagAllMulticast");
423 if (ifp
->flags
& IFF_PROMISC
)
424 json_object_boolean_true_add(json
, "flagPromiscuous");
426 if (PIM_IF_IS_DELETED(ifp
))
427 json_object_boolean_true_add(json
, "flagDeleted");
429 if (pim_if_lan_delay_enabled(ifp
))
430 json_object_boolean_true_add(json
, "lanDelayEnabled");
433 static void pim_show_membership_helper(struct vty
*vty
,
434 struct pim_interface
*pim_ifp
,
435 struct pim_ifchannel
*ch
,
436 struct json_object
*json
)
438 char ch_src_str
[INET_ADDRSTRLEN
];
439 char ch_grp_str
[INET_ADDRSTRLEN
];
440 json_object
*json_iface
= NULL
;
441 json_object
*json_row
= NULL
;
443 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
444 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
446 json_object_object_get_ex(json
, ch
->interface
->name
, &json_iface
);
448 json_iface
= json_object_new_object();
449 json_object_pim_ifp_add(json_iface
, ch
->interface
);
450 json_object_object_add(json
, ch
->interface
->name
, json_iface
);
453 json_row
= json_object_new_object();
454 json_object_string_add(json_row
, "source", ch_src_str
);
455 json_object_string_add(json_row
, "group", ch_grp_str
);
456 json_object_string_add(json_row
, "localMembership",
457 ch
->local_ifmembership
== PIM_IFMEMBERSHIP_NOINFO
460 json_object_object_add(json_iface
, ch_grp_str
, json_row
);
462 static void pim_show_membership(struct pim_instance
*pim
, struct vty
*vty
,
465 struct pim_interface
*pim_ifp
;
466 struct pim_ifchannel
*ch
;
467 struct interface
*ifp
;
469 json_object
*json
= NULL
;
470 json_object
*json_tmp
= NULL
;
472 json
= json_object_new_object();
474 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
479 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
480 pim_show_membership_helper(vty
, pim_ifp
, ch
, json
);
481 } /* scan interface channels */
485 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
486 json
, JSON_C_TO_STRING_PRETTY
));
489 "Interface Address Source Group Membership\n");
492 * Example of the json data we are traversing
498 * "address":"10.1.20.1",
500 * "flagMulticast":true,
501 * "flagBroadcast":true,
502 * "lanDelayEnabled":true,
505 * "group":"226.10.10.10",
506 * "localMembership":"INCLUDE"
512 /* foreach interface */
513 json_object_object_foreach(json
, key
, val
)
516 /* Find all of the keys where the val is an object. In
518 * above the only one is 226.10.10.10
520 json_object_object_foreach(val
, if_field_key
,
523 type
= json_object_get_type(if_field_val
);
525 if (type
== json_type_object
) {
526 vty_out(vty
, "%-16s ", key
);
528 json_object_object_get_ex(
529 val
, "address", &json_tmp
);
530 vty_out(vty
, "%-15s ",
531 json_object_get_string(
534 json_object_object_get_ex(if_field_val
,
537 vty_out(vty
, "%-15s ",
538 json_object_get_string(
542 vty_out(vty
, "%-15s ", if_field_key
);
544 json_object_object_get_ex(
545 if_field_val
, "localMembership",
547 vty_out(vty
, "%-10s\n",
548 json_object_get_string(
555 json_object_free(json
);
558 static void pim_print_ifp_flags(struct vty
*vty
, struct interface
*ifp
,
561 vty_out(vty
, "Flags\n");
562 vty_out(vty
, "-----\n");
563 vty_out(vty
, "All Multicast : %s\n",
564 (ifp
->flags
& IFF_ALLMULTI
) ? "yes" : "no");
565 vty_out(vty
, "Broadcast : %s\n",
566 if_is_broadcast(ifp
) ? "yes" : "no");
567 vty_out(vty
, "Deleted : %s\n",
568 PIM_IF_IS_DELETED(ifp
) ? "yes" : "no");
569 vty_out(vty
, "Interface Index : %d\n", ifp
->ifindex
);
570 vty_out(vty
, "Multicast : %s\n",
571 if_is_multicast(ifp
) ? "yes" : "no");
572 vty_out(vty
, "Multicast Loop : %d\n", mloop
);
573 vty_out(vty
, "Promiscuous : %s\n",
574 (ifp
->flags
& IFF_PROMISC
) ? "yes" : "no");
579 static void igmp_show_interfaces(struct pim_instance
*pim
, struct vty
*vty
,
582 struct interface
*ifp
;
584 char buf
[PREFIX_STRLEN
];
585 json_object
*json
= NULL
;
586 json_object
*json_row
= NULL
;
588 now
= pim_time_monotonic_sec();
591 json
= json_object_new_object();
594 "Interface State Address V Querier Query Timer Uptime\n");
596 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
597 struct pim_interface
*pim_ifp
;
598 struct listnode
*sock_node
;
599 struct igmp_sock
*igmp
;
606 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
609 char query_hhmmss
[10];
611 pim_time_uptime(uptime
, sizeof(uptime
),
612 now
- igmp
->sock_creation
);
613 pim_time_timer_to_hhmmss(query_hhmmss
,
614 sizeof(query_hhmmss
),
615 igmp
->t_igmp_query_timer
);
618 json_row
= json_object_new_object();
619 json_object_pim_ifp_add(json_row
, ifp
);
620 json_object_string_add(json_row
, "upTime",
622 json_object_int_add(json_row
, "version",
623 pim_ifp
->igmp_version
);
625 if (igmp
->t_igmp_query_timer
) {
626 json_object_boolean_true_add(json_row
,
628 json_object_string_add(json_row
,
633 json_object_object_add(json
, ifp
->name
,
636 if (igmp
->mtrace_only
) {
637 json_object_boolean_true_add(
638 json_row
, "mtraceOnly");
642 "%-16s %5s %15s %d %7s %11s %8s\n",
645 ? (igmp
->mtrace_only
? "mtrc"
648 inet_ntop(AF_INET
, &igmp
->ifaddr
,
650 pim_ifp
->igmp_version
,
651 igmp
->t_igmp_query_timer
? "local"
653 query_hhmmss
, uptime
);
659 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
660 json
, JSON_C_TO_STRING_PRETTY
));
661 json_object_free(json
);
665 static void igmp_show_interfaces_single(struct pim_instance
*pim
,
666 struct vty
*vty
, const char *ifname
,
669 struct igmp_sock
*igmp
;
670 struct interface
*ifp
;
671 struct listnode
*sock_node
;
672 struct pim_interface
*pim_ifp
;
674 char query_hhmmss
[10];
675 char other_hhmmss
[10];
676 int found_ifname
= 0;
679 long gmi_msec
; /* Group Membership Interval */
682 long oqpi_msec
; /* Other Querier Present Interval */
687 json_object
*json
= NULL
;
688 json_object
*json_row
= NULL
;
691 json
= json_object_new_object();
693 now
= pim_time_monotonic_sec();
695 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
701 if (strcmp(ifname
, "detail") && strcmp(ifname
, ifp
->name
))
704 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
707 pim_time_uptime(uptime
, sizeof(uptime
),
708 now
- igmp
->sock_creation
);
709 pim_time_timer_to_hhmmss(query_hhmmss
,
710 sizeof(query_hhmmss
),
711 igmp
->t_igmp_query_timer
);
712 pim_time_timer_to_hhmmss(other_hhmmss
,
713 sizeof(other_hhmmss
),
714 igmp
->t_other_querier_timer
);
716 gmi_msec
= PIM_IGMP_GMI_MSEC(
717 igmp
->querier_robustness_variable
,
718 igmp
->querier_query_interval
,
719 pim_ifp
->igmp_query_max_response_time_dsec
);
722 pim_ifp
->igmp_default_query_interval
);
724 oqpi_msec
= PIM_IGMP_OQPI_MSEC(
725 igmp
->querier_robustness_variable
,
726 igmp
->querier_query_interval
,
727 pim_ifp
->igmp_query_max_response_time_dsec
);
729 lmqt_msec
= PIM_IGMP_LMQT_MSEC(
730 pim_ifp
->igmp_specific_query_max_response_time_dsec
,
731 pim_ifp
->igmp_last_member_query_count
);
735 igmp
->querier_robustness_variable
,
736 igmp
->querier_query_interval
,
737 pim_ifp
->igmp_query_max_response_time_dsec
)
740 qri_msec
= pim_ifp
->igmp_query_max_response_time_dsec
742 if (pim_ifp
->pim_sock_fd
>= 0)
743 mloop
= pim_socket_mcastloop_get(
744 pim_ifp
->pim_sock_fd
);
747 lmqc
= pim_ifp
->igmp_last_member_query_count
;
750 json_row
= json_object_new_object();
751 json_object_pim_ifp_add(json_row
, ifp
);
752 json_object_string_add(json_row
, "upTime",
754 json_object_string_add(json_row
, "querier",
755 igmp
->t_igmp_query_timer
758 json_object_int_add(json_row
, "queryStartCount",
759 igmp
->startup_query_count
);
760 json_object_string_add(json_row
,
763 json_object_string_add(json_row
,
766 json_object_int_add(json_row
, "version",
767 pim_ifp
->igmp_version
);
770 "timerGroupMembershipIntervalMsec",
772 json_object_int_add(json_row
,
773 "lastMemberQueryCount",
775 json_object_int_add(json_row
,
776 "timerLastMemberQueryMsec",
780 "timerOlderHostPresentIntervalMsec",
784 "timerOtherQuerierPresentIntervalMsec",
787 json_row
, "timerQueryInterval",
788 igmp
->querier_query_interval
);
791 "timerQueryResponseIntervalMsec",
794 json_row
, "timerRobustnessVariable",
795 igmp
->querier_robustness_variable
);
796 json_object_int_add(json_row
,
797 "timerStartupQueryInterval",
800 json_object_object_add(json
, ifp
->name
,
803 if (igmp
->mtrace_only
) {
804 json_object_boolean_true_add(
805 json_row
, "mtraceOnly");
808 vty_out(vty
, "Interface : %s\n", ifp
->name
);
809 vty_out(vty
, "State : %s\n",
811 ? (igmp
->mtrace_only
? "mtrace"
814 vty_out(vty
, "Address : %pI4\n",
815 &pim_ifp
->primary_address
);
816 vty_out(vty
, "Uptime : %s\n", uptime
);
817 vty_out(vty
, "Version : %d\n",
818 pim_ifp
->igmp_version
);
822 vty_out(vty
, "Querier\n");
823 vty_out(vty
, "-------\n");
824 vty_out(vty
, "Querier : %s\n",
825 igmp
->t_igmp_query_timer
? "local"
827 vty_out(vty
, "Start Count : %d\n",
828 igmp
->startup_query_count
);
829 vty_out(vty
, "Query Timer : %s\n",
831 vty_out(vty
, "Other Timer : %s\n",
836 vty_out(vty
, "Timers\n");
837 vty_out(vty
, "------\n");
839 "Group Membership Interval : %lis\n",
842 "Last Member Query Count : %d\n",
845 "Last Member Query Time : %lis\n",
848 "Older Host Present Interval : %lis\n",
851 "Other Querier Present Interval : %lis\n",
854 "Query Interval : %ds\n",
855 igmp
->querier_query_interval
);
857 "Query Response Interval : %lis\n",
860 "Robustness Variable : %d\n",
861 igmp
->querier_robustness_variable
);
863 "Startup Query Interval : %ds\n",
868 pim_print_ifp_flags(vty
, ifp
, mloop
);
874 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
875 json
, JSON_C_TO_STRING_PRETTY
));
876 json_object_free(json
);
879 vty_out(vty
, "%% No such interface\n");
883 static void igmp_show_interface_join(struct pim_instance
*pim
, struct vty
*vty
)
885 struct interface
*ifp
;
888 now
= pim_time_monotonic_sec();
891 "Interface Address Source Group Socket Uptime \n");
893 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
894 struct pim_interface
*pim_ifp
;
895 struct listnode
*join_node
;
896 struct igmp_join
*ij
;
897 struct in_addr pri_addr
;
898 char pri_addr_str
[INET_ADDRSTRLEN
];
905 if (!pim_ifp
->igmp_join_list
)
908 pri_addr
= pim_find_primary_addr(ifp
);
909 pim_inet4_dump("<pri?>", pri_addr
, pri_addr_str
,
910 sizeof(pri_addr_str
));
912 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_join_list
, join_node
,
914 char group_str
[INET_ADDRSTRLEN
];
915 char source_str
[INET_ADDRSTRLEN
];
918 pim_time_uptime(uptime
, sizeof(uptime
),
919 now
- ij
->sock_creation
);
920 pim_inet4_dump("<grp?>", ij
->group_addr
, group_str
,
922 pim_inet4_dump("<src?>", ij
->source_addr
, source_str
,
925 vty_out(vty
, "%-16s %-15s %-15s %-15s %6d %8s\n",
926 ifp
->name
, pri_addr_str
, source_str
, group_str
,
927 ij
->sock_fd
, uptime
);
928 } /* for (pim_ifp->igmp_join_list) */
933 static void pim_show_interfaces_single(struct pim_instance
*pim
,
934 struct vty
*vty
, const char *ifname
,
937 struct in_addr ifaddr
;
938 struct interface
*ifp
;
939 struct listnode
*neighnode
;
940 struct pim_interface
*pim_ifp
;
941 struct pim_neighbor
*neigh
;
942 struct pim_upstream
*up
;
944 char dr_str
[INET_ADDRSTRLEN
];
947 char grp_str
[INET_ADDRSTRLEN
];
948 char hello_period
[10];
949 char hello_timer
[10];
950 char neigh_src_str
[INET_ADDRSTRLEN
];
951 char src_str
[INET_ADDRSTRLEN
];
952 char stat_uptime
[10];
955 int found_ifname
= 0;
957 char buf
[PREFIX_STRLEN
];
958 json_object
*json
= NULL
;
959 json_object
*json_row
= NULL
;
960 json_object
*json_pim_neighbor
= NULL
;
961 json_object
*json_pim_neighbors
= NULL
;
962 json_object
*json_group
= NULL
;
963 json_object
*json_group_source
= NULL
;
964 json_object
*json_fhr_sources
= NULL
;
965 struct pim_secondary_addr
*sec_addr
;
966 struct listnode
*sec_node
;
968 now
= pim_time_monotonic_sec();
971 json
= json_object_new_object();
973 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
979 if (mlag
== true && pim_ifp
->activeactive
== false)
982 if (strcmp(ifname
, "detail") && strcmp(ifname
, ifp
->name
))
986 ifaddr
= pim_ifp
->primary_address
;
987 pim_inet4_dump("<dr?>", pim_ifp
->pim_dr_addr
, dr_str
,
989 pim_time_uptime_begin(dr_uptime
, sizeof(dr_uptime
), now
,
990 pim_ifp
->pim_dr_election_last
);
991 pim_time_timer_to_hhmmss(hello_timer
, sizeof(hello_timer
),
992 pim_ifp
->t_pim_hello_timer
);
993 pim_time_mmss(hello_period
, sizeof(hello_period
),
994 pim_ifp
->pim_hello_period
);
995 pim_time_uptime(stat_uptime
, sizeof(stat_uptime
),
996 now
- pim_ifp
->pim_ifstat_start
);
997 if (pim_ifp
->pim_sock_fd
>= 0)
998 mloop
= pim_socket_mcastloop_get(pim_ifp
->pim_sock_fd
);
1003 char pbuf
[PREFIX2STR_BUFFER
];
1004 json_row
= json_object_new_object();
1005 json_object_pim_ifp_add(json_row
, ifp
);
1007 if (pim_ifp
->update_source
.s_addr
!= INADDR_ANY
) {
1008 json_object_string_add(
1009 json_row
, "useSource",
1011 &pim_ifp
->update_source
,
1014 if (pim_ifp
->sec_addr_list
) {
1015 json_object
*sec_list
= NULL
;
1017 sec_list
= json_object_new_array();
1018 for (ALL_LIST_ELEMENTS_RO(
1019 pim_ifp
->sec_addr_list
, sec_node
,
1021 json_object_array_add(
1023 json_object_new_string(
1029 json_object_object_add(json_row
,
1030 "secondaryAddressList",
1035 if (pim_ifp
->pim_neighbor_list
->count
) {
1036 json_pim_neighbors
= json_object_new_object();
1038 for (ALL_LIST_ELEMENTS_RO(
1039 pim_ifp
->pim_neighbor_list
,
1040 neighnode
, neigh
)) {
1042 json_object_new_object();
1043 pim_inet4_dump("<src?>",
1046 sizeof(neigh_src_str
));
1047 pim_time_uptime(uptime
, sizeof(uptime
),
1048 now
- neigh
->creation
);
1049 pim_time_timer_to_hhmmss(
1050 expire
, sizeof(expire
),
1051 neigh
->t_expire_timer
);
1053 json_object_string_add(
1054 json_pim_neighbor
, "address",
1056 json_object_string_add(
1057 json_pim_neighbor
, "upTime",
1059 json_object_string_add(
1060 json_pim_neighbor
, "holdtime",
1063 json_object_object_add(
1069 json_object_object_add(json_row
, "neighbors",
1070 json_pim_neighbors
);
1073 json_object_string_add(json_row
, "drAddress", dr_str
);
1074 json_object_int_add(json_row
, "drPriority",
1075 pim_ifp
->pim_dr_priority
);
1076 json_object_string_add(json_row
, "drUptime", dr_uptime
);
1077 json_object_int_add(json_row
, "drElections",
1078 pim_ifp
->pim_dr_election_count
);
1079 json_object_int_add(json_row
, "drChanges",
1080 pim_ifp
->pim_dr_election_changes
);
1083 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
1084 if (ifp
!= up
->rpf
.source_nexthop
.interface
)
1087 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
))
1090 if (!json_fhr_sources
)
1092 json_object_new_object();
1094 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
,
1096 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
,
1098 pim_time_uptime(uptime
, sizeof(uptime
),
1099 now
- up
->state_transition
);
1102 * Does this group live in json_fhr_sources?
1105 json_object_object_get_ex(json_fhr_sources
,
1106 grp_str
, &json_group
);
1109 json_group
= json_object_new_object();
1110 json_object_object_add(json_fhr_sources
,
1115 json_group_source
= json_object_new_object();
1116 json_object_string_add(json_group_source
,
1118 json_object_string_add(json_group_source
,
1120 json_object_string_add(json_group_source
,
1122 json_object_object_add(json_group
, src_str
,
1126 if (json_fhr_sources
) {
1127 json_object_object_add(json_row
,
1132 json_object_int_add(json_row
, "helloPeriod",
1133 pim_ifp
->pim_hello_period
);
1134 json_object_string_add(json_row
, "helloTimer",
1136 json_object_string_add(json_row
, "helloStatStart",
1138 json_object_int_add(json_row
, "helloReceived",
1139 pim_ifp
->pim_ifstat_hello_recv
);
1140 json_object_int_add(json_row
, "helloReceivedFailed",
1141 pim_ifp
->pim_ifstat_hello_recvfail
);
1142 json_object_int_add(json_row
, "helloSend",
1143 pim_ifp
->pim_ifstat_hello_sent
);
1144 json_object_int_add(json_row
, "hellosendFailed",
1145 pim_ifp
->pim_ifstat_hello_sendfail
);
1146 json_object_int_add(json_row
, "helloGenerationId",
1147 pim_ifp
->pim_generation_id
);
1148 json_object_int_add(json_row
, "flagMulticastLoop",
1151 json_object_int_add(
1152 json_row
, "effectivePropagationDelay",
1153 pim_if_effective_propagation_delay_msec(ifp
));
1154 json_object_int_add(
1155 json_row
, "effectiveOverrideInterval",
1156 pim_if_effective_override_interval_msec(ifp
));
1157 json_object_int_add(
1158 json_row
, "joinPruneOverrideInterval",
1159 pim_if_jp_override_interval_msec(ifp
));
1161 json_object_int_add(
1162 json_row
, "propagationDelay",
1163 pim_ifp
->pim_propagation_delay_msec
);
1164 json_object_int_add(
1165 json_row
, "propagationDelayHighest",
1166 pim_ifp
->pim_neighbors_highest_propagation_delay_msec
);
1167 json_object_int_add(
1168 json_row
, "overrideInterval",
1169 pim_ifp
->pim_override_interval_msec
);
1170 json_object_int_add(
1171 json_row
, "overrideIntervalHighest",
1172 pim_ifp
->pim_neighbors_highest_override_interval_msec
);
1173 json_object_object_add(json
, ifp
->name
, json_row
);
1176 vty_out(vty
, "Interface : %s\n", ifp
->name
);
1177 vty_out(vty
, "State : %s\n",
1178 if_is_up(ifp
) ? "up" : "down");
1179 if (pim_ifp
->update_source
.s_addr
!= INADDR_ANY
) {
1180 vty_out(vty
, "Use Source : %pI4\n",
1181 &pim_ifp
->update_source
);
1183 if (pim_ifp
->sec_addr_list
) {
1184 vty_out(vty
, "Address : %pI4 (primary)\n",
1186 for (ALL_LIST_ELEMENTS_RO(
1187 pim_ifp
->sec_addr_list
, sec_node
,
1189 vty_out(vty
, " %pFX\n",
1192 vty_out(vty
, "Address : %pI4\n",
1200 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
,
1201 neighnode
, neigh
)) {
1204 vty_out(vty
, "PIM Neighbors\n");
1205 vty_out(vty
, "-------------\n");
1209 pim_inet4_dump("<src?>", neigh
->source_addr
,
1211 sizeof(neigh_src_str
));
1212 pim_time_uptime(uptime
, sizeof(uptime
),
1213 now
- neigh
->creation
);
1214 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
1215 neigh
->t_expire_timer
);
1217 "%-15s : up for %s, holdtime expires in %s\n",
1218 neigh_src_str
, uptime
, expire
);
1221 if (!print_header
) {
1226 vty_out(vty
, "Designated Router\n");
1227 vty_out(vty
, "-----------------\n");
1228 vty_out(vty
, "Address : %s\n", dr_str
);
1229 vty_out(vty
, "Priority : %u(%d)\n",
1230 pim_ifp
->pim_dr_priority
,
1231 pim_ifp
->pim_dr_num_nondrpri_neighbors
);
1232 vty_out(vty
, "Uptime : %s\n", dr_uptime
);
1233 vty_out(vty
, "Elections : %d\n",
1234 pim_ifp
->pim_dr_election_count
);
1235 vty_out(vty
, "Changes : %d\n",
1236 pim_ifp
->pim_dr_election_changes
);
1242 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
1243 if (!up
->rpf
.source_nexthop
.interface
)
1246 if (strcmp(ifp
->name
,
1247 up
->rpf
.source_nexthop
1252 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
))
1257 "FHR - First Hop Router\n");
1259 "----------------------\n");
1263 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
,
1265 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
,
1267 pim_time_uptime(uptime
, sizeof(uptime
),
1268 now
- up
->state_transition
);
1270 "%s : %s is a source, uptime is %s\n",
1271 grp_str
, src_str
, uptime
);
1274 if (!print_header
) {
1279 vty_out(vty
, "Hellos\n");
1280 vty_out(vty
, "------\n");
1281 vty_out(vty
, "Period : %d\n",
1282 pim_ifp
->pim_hello_period
);
1283 vty_out(vty
, "Timer : %s\n", hello_timer
);
1284 vty_out(vty
, "StatStart : %s\n", stat_uptime
);
1285 vty_out(vty
, "Receive : %d\n",
1286 pim_ifp
->pim_ifstat_hello_recv
);
1287 vty_out(vty
, "Receive Failed : %d\n",
1288 pim_ifp
->pim_ifstat_hello_recvfail
);
1289 vty_out(vty
, "Send : %d\n",
1290 pim_ifp
->pim_ifstat_hello_sent
);
1291 vty_out(vty
, "Send Failed : %d\n",
1292 pim_ifp
->pim_ifstat_hello_sendfail
);
1293 vty_out(vty
, "Generation ID : %08x\n",
1294 pim_ifp
->pim_generation_id
);
1298 pim_print_ifp_flags(vty
, ifp
, mloop
);
1300 vty_out(vty
, "Join Prune Interval\n");
1301 vty_out(vty
, "-------------------\n");
1302 vty_out(vty
, "LAN Delay : %s\n",
1303 pim_if_lan_delay_enabled(ifp
) ? "yes" : "no");
1304 vty_out(vty
, "Effective Propagation Delay : %d msec\n",
1305 pim_if_effective_propagation_delay_msec(ifp
));
1306 vty_out(vty
, "Effective Override Interval : %d msec\n",
1307 pim_if_effective_override_interval_msec(ifp
));
1308 vty_out(vty
, "Join Prune Override Interval : %d msec\n",
1309 pim_if_jp_override_interval_msec(ifp
));
1313 vty_out(vty
, "LAN Prune Delay\n");
1314 vty_out(vty
, "---------------\n");
1315 vty_out(vty
, "Propagation Delay : %d msec\n",
1316 pim_ifp
->pim_propagation_delay_msec
);
1317 vty_out(vty
, "Propagation Delay (Highest) : %d msec\n",
1318 pim_ifp
->pim_neighbors_highest_propagation_delay_msec
);
1319 vty_out(vty
, "Override Interval : %d msec\n",
1320 pim_ifp
->pim_override_interval_msec
);
1321 vty_out(vty
, "Override Interval (Highest) : %d msec\n",
1322 pim_ifp
->pim_neighbors_highest_override_interval_msec
);
1329 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1330 json
, JSON_C_TO_STRING_PRETTY
));
1331 json_object_free(json
);
1334 vty_out(vty
, "%% No such interface\n");
1338 static void igmp_show_statistics(struct pim_instance
*pim
, struct vty
*vty
,
1339 const char *ifname
, bool uj
)
1341 struct interface
*ifp
;
1342 struct igmp_stats rx_stats
;
1344 igmp_stats_init(&rx_stats
);
1346 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1347 struct pim_interface
*pim_ifp
;
1348 struct listnode
*sock_node
;
1349 struct igmp_sock
*igmp
;
1351 pim_ifp
= ifp
->info
;
1356 if (ifname
&& strcmp(ifname
, ifp
->name
))
1359 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
1361 igmp_stats_add(&rx_stats
, &igmp
->rx_stats
);
1365 json_object
*json
= NULL
;
1366 json_object
*json_row
= NULL
;
1368 json
= json_object_new_object();
1369 json_row
= json_object_new_object();
1371 json_object_string_add(json_row
, "name", ifname
? ifname
:
1373 json_object_int_add(json_row
, "queryV1", rx_stats
.query_v1
);
1374 json_object_int_add(json_row
, "queryV2", rx_stats
.query_v2
);
1375 json_object_int_add(json_row
, "queryV3", rx_stats
.query_v3
);
1376 json_object_int_add(json_row
, "leaveV3", rx_stats
.leave_v2
);
1377 json_object_int_add(json_row
, "reportV1", rx_stats
.report_v1
);
1378 json_object_int_add(json_row
, "reportV2", rx_stats
.report_v2
);
1379 json_object_int_add(json_row
, "reportV3", rx_stats
.report_v3
);
1380 json_object_int_add(json_row
, "mtraceResponse",
1381 rx_stats
.mtrace_rsp
);
1382 json_object_int_add(json_row
, "mtraceRequest",
1383 rx_stats
.mtrace_req
);
1384 json_object_int_add(json_row
, "unsupported",
1385 rx_stats
.unsupported
);
1386 json_object_object_add(json
, ifname
? ifname
: "global",
1388 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1389 json
, JSON_C_TO_STRING_PRETTY
));
1390 json_object_free(json
);
1392 vty_out(vty
, "IGMP RX statistics\n");
1393 vty_out(vty
, "Interface : %s\n",
1394 ifname
? ifname
: "global");
1395 vty_out(vty
, "V1 query : %u\n", rx_stats
.query_v1
);
1396 vty_out(vty
, "V2 query : %u\n", rx_stats
.query_v2
);
1397 vty_out(vty
, "V3 query : %u\n", rx_stats
.query_v3
);
1398 vty_out(vty
, "V2 leave : %u\n", rx_stats
.leave_v2
);
1399 vty_out(vty
, "V1 report : %u\n", rx_stats
.report_v1
);
1400 vty_out(vty
, "V2 report : %u\n", rx_stats
.report_v2
);
1401 vty_out(vty
, "V3 report : %u\n", rx_stats
.report_v3
);
1402 vty_out(vty
, "mtrace response : %u\n", rx_stats
.mtrace_rsp
);
1403 vty_out(vty
, "mtrace request : %u\n", rx_stats
.mtrace_req
);
1404 vty_out(vty
, "unsupported : %u\n", rx_stats
.unsupported
);
1408 static void pim_show_interfaces(struct pim_instance
*pim
, struct vty
*vty
,
1411 struct interface
*ifp
;
1412 struct pim_interface
*pim_ifp
;
1413 struct pim_upstream
*up
;
1416 int pim_ifchannels
= 0;
1417 char buf
[PREFIX_STRLEN
];
1418 json_object
*json
= NULL
;
1419 json_object
*json_row
= NULL
;
1420 json_object
*json_tmp
;
1422 json
= json_object_new_object();
1424 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1425 pim_ifp
= ifp
->info
;
1430 if (mlag
== true && pim_ifp
->activeactive
== false)
1433 pim_nbrs
= pim_ifp
->pim_neighbor_list
->count
;
1434 pim_ifchannels
= pim_if_ifchannel_count(pim_ifp
);
1437 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
)
1438 if (ifp
== up
->rpf
.source_nexthop
.interface
)
1439 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
1442 json_row
= json_object_new_object();
1443 json_object_pim_ifp_add(json_row
, ifp
);
1444 json_object_int_add(json_row
, "pimNeighbors", pim_nbrs
);
1445 json_object_int_add(json_row
, "pimIfChannels", pim_ifchannels
);
1446 json_object_int_add(json_row
, "firstHopRouterCount", fhr
);
1447 json_object_string_add(json_row
, "pimDesignatedRouter",
1449 &pim_ifp
->pim_dr_addr
, buf
,
1452 if (pim_ifp
->pim_dr_addr
.s_addr
1453 == pim_ifp
->primary_address
.s_addr
)
1454 json_object_boolean_true_add(
1455 json_row
, "pimDesignatedRouterLocal");
1457 json_object_object_add(json
, ifp
->name
, json_row
);
1461 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1462 json
, JSON_C_TO_STRING_PRETTY
));
1465 "Interface State Address PIM Nbrs PIM DR FHR IfChannels\n");
1467 json_object_object_foreach(json
, key
, val
)
1469 vty_out(vty
, "%-16s ", key
);
1471 json_object_object_get_ex(val
, "state", &json_tmp
);
1472 vty_out(vty
, "%5s ", json_object_get_string(json_tmp
));
1474 json_object_object_get_ex(val
, "address", &json_tmp
);
1475 vty_out(vty
, "%15s ",
1476 json_object_get_string(json_tmp
));
1478 json_object_object_get_ex(val
, "pimNeighbors",
1480 vty_out(vty
, "%8d ", json_object_get_int(json_tmp
));
1482 if (json_object_object_get_ex(
1483 val
, "pimDesignatedRouterLocal",
1485 vty_out(vty
, "%15s ", "local");
1487 json_object_object_get_ex(
1488 val
, "pimDesignatedRouter", &json_tmp
);
1489 vty_out(vty
, "%15s ",
1490 json_object_get_string(json_tmp
));
1493 json_object_object_get_ex(val
, "firstHopRouter",
1495 vty_out(vty
, "%3d ", json_object_get_int(json_tmp
));
1497 json_object_object_get_ex(val
, "pimIfChannels",
1499 vty_out(vty
, "%9d\n", json_object_get_int(json_tmp
));
1503 json_object_free(json
);
1506 static void pim_show_interface_traffic(struct pim_instance
*pim
,
1507 struct vty
*vty
, bool uj
)
1509 struct interface
*ifp
= NULL
;
1510 struct pim_interface
*pim_ifp
= NULL
;
1511 json_object
*json
= NULL
;
1512 json_object
*json_row
= NULL
;
1515 json
= json_object_new_object();
1518 vty_out(vty
, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s%-17s\n",
1519 "Interface", " HELLO", " JOIN",
1520 " PRUNE", " REGISTER", "REGISTER-STOP",
1522 vty_out(vty
, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s%-17s\n", "",
1523 " Rx/Tx", " Rx/Tx", " Rx/Tx",
1524 " Rx/Tx", " Rx/Tx", " Rx/Tx",
1527 "---------------------------------------------------------------------------------------------------------------\n");
1530 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1531 pim_ifp
= ifp
->info
;
1536 if (pim_ifp
->pim_sock_fd
< 0)
1539 json_row
= json_object_new_object();
1540 json_object_pim_ifp_add(json_row
, ifp
);
1541 json_object_int_add(json_row
, "helloRx",
1542 pim_ifp
->pim_ifstat_hello_recv
);
1543 json_object_int_add(json_row
, "helloTx",
1544 pim_ifp
->pim_ifstat_hello_sent
);
1545 json_object_int_add(json_row
, "joinRx",
1546 pim_ifp
->pim_ifstat_join_recv
);
1547 json_object_int_add(json_row
, "joinTx",
1548 pim_ifp
->pim_ifstat_join_send
);
1549 json_object_int_add(json_row
, "pruneTx",
1550 pim_ifp
->pim_ifstat_prune_send
);
1551 json_object_int_add(json_row
, "pruneRx",
1552 pim_ifp
->pim_ifstat_prune_recv
);
1553 json_object_int_add(json_row
, "registerRx",
1554 pim_ifp
->pim_ifstat_reg_recv
);
1555 json_object_int_add(json_row
, "registerTx",
1556 pim_ifp
->pim_ifstat_reg_recv
);
1557 json_object_int_add(json_row
, "registerStopRx",
1558 pim_ifp
->pim_ifstat_reg_stop_recv
);
1559 json_object_int_add(json_row
, "registerStopTx",
1560 pim_ifp
->pim_ifstat_reg_stop_send
);
1561 json_object_int_add(json_row
, "assertRx",
1562 pim_ifp
->pim_ifstat_assert_recv
);
1563 json_object_int_add(json_row
, "assertTx",
1564 pim_ifp
->pim_ifstat_assert_send
);
1565 json_object_int_add(json_row
, "bsmRx",
1566 pim_ifp
->pim_ifstat_bsm_rx
);
1567 json_object_int_add(json_row
, "bsmTx",
1568 pim_ifp
->pim_ifstat_bsm_tx
);
1569 json_object_object_add(json
, ifp
->name
, json_row
);
1572 "%-16s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7" PRIu64
"/%-7" PRIu64
"\n",
1573 ifp
->name
, pim_ifp
->pim_ifstat_hello_recv
,
1574 pim_ifp
->pim_ifstat_hello_sent
,
1575 pim_ifp
->pim_ifstat_join_recv
,
1576 pim_ifp
->pim_ifstat_join_send
,
1577 pim_ifp
->pim_ifstat_prune_recv
,
1578 pim_ifp
->pim_ifstat_prune_send
,
1579 pim_ifp
->pim_ifstat_reg_recv
,
1580 pim_ifp
->pim_ifstat_reg_send
,
1581 pim_ifp
->pim_ifstat_reg_stop_recv
,
1582 pim_ifp
->pim_ifstat_reg_stop_send
,
1583 pim_ifp
->pim_ifstat_assert_recv
,
1584 pim_ifp
->pim_ifstat_assert_send
,
1585 pim_ifp
->pim_ifstat_bsm_rx
,
1586 pim_ifp
->pim_ifstat_bsm_tx
);
1590 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1591 json
, JSON_C_TO_STRING_PRETTY
));
1592 json_object_free(json
);
1596 static void pim_show_interface_traffic_single(struct pim_instance
*pim
,
1598 const char *ifname
, bool uj
)
1600 struct interface
*ifp
= NULL
;
1601 struct pim_interface
*pim_ifp
= NULL
;
1602 json_object
*json
= NULL
;
1603 json_object
*json_row
= NULL
;
1604 uint8_t found_ifname
= 0;
1607 json
= json_object_new_object();
1610 vty_out(vty
, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s%-17s\n",
1611 "Interface", " HELLO", " JOIN", " PRUNE",
1612 " REGISTER", " REGISTER-STOP", " ASSERT",
1614 vty_out(vty
, "%-14s%-18s%-17s%-17s%-17s%-17s%-17s%-17s\n", "",
1615 " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1616 " Rx/Tx", " Rx/Tx", " Rx/Tx");
1618 "-------------------------------------------------------------------------------------------------------------------------------\n");
1621 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1622 if (strcmp(ifname
, ifp
->name
))
1625 pim_ifp
= ifp
->info
;
1630 if (pim_ifp
->pim_sock_fd
< 0)
1635 json_row
= json_object_new_object();
1636 json_object_pim_ifp_add(json_row
, ifp
);
1637 json_object_int_add(json_row
, "helloRx",
1638 pim_ifp
->pim_ifstat_hello_recv
);
1639 json_object_int_add(json_row
, "helloTx",
1640 pim_ifp
->pim_ifstat_hello_sent
);
1641 json_object_int_add(json_row
, "joinRx",
1642 pim_ifp
->pim_ifstat_join_recv
);
1643 json_object_int_add(json_row
, "joinTx",
1644 pim_ifp
->pim_ifstat_join_send
);
1645 json_object_int_add(json_row
, "registerRx",
1646 pim_ifp
->pim_ifstat_reg_recv
);
1647 json_object_int_add(json_row
, "registerTx",
1648 pim_ifp
->pim_ifstat_reg_recv
);
1649 json_object_int_add(json_row
, "registerStopRx",
1650 pim_ifp
->pim_ifstat_reg_stop_recv
);
1651 json_object_int_add(json_row
, "registerStopTx",
1652 pim_ifp
->pim_ifstat_reg_stop_send
);
1653 json_object_int_add(json_row
, "assertRx",
1654 pim_ifp
->pim_ifstat_assert_recv
);
1655 json_object_int_add(json_row
, "assertTx",
1656 pim_ifp
->pim_ifstat_assert_send
);
1657 json_object_int_add(json_row
, "bsmRx",
1658 pim_ifp
->pim_ifstat_bsm_rx
);
1659 json_object_int_add(json_row
, "bsmTx",
1660 pim_ifp
->pim_ifstat_bsm_tx
);
1662 json_object_object_add(json
, ifp
->name
, json_row
);
1665 "%-16s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7" PRIu64
"/%-7" PRIu64
"\n",
1666 ifp
->name
, pim_ifp
->pim_ifstat_hello_recv
,
1667 pim_ifp
->pim_ifstat_hello_sent
,
1668 pim_ifp
->pim_ifstat_join_recv
,
1669 pim_ifp
->pim_ifstat_join_send
,
1670 pim_ifp
->pim_ifstat_prune_recv
,
1671 pim_ifp
->pim_ifstat_prune_send
,
1672 pim_ifp
->pim_ifstat_reg_recv
,
1673 pim_ifp
->pim_ifstat_reg_send
,
1674 pim_ifp
->pim_ifstat_reg_stop_recv
,
1675 pim_ifp
->pim_ifstat_reg_stop_send
,
1676 pim_ifp
->pim_ifstat_assert_recv
,
1677 pim_ifp
->pim_ifstat_assert_send
,
1678 pim_ifp
->pim_ifstat_bsm_rx
,
1679 pim_ifp
->pim_ifstat_bsm_tx
);
1683 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1684 json
, JSON_C_TO_STRING_PRETTY
));
1685 json_object_free(json
);
1688 vty_out(vty
, "%% No such interface\n");
1692 static void pim_show_join_helper(struct vty
*vty
, struct pim_interface
*pim_ifp
,
1693 struct pim_ifchannel
*ch
, json_object
*json
,
1694 time_t now
, bool uj
)
1696 char ch_src_str
[INET_ADDRSTRLEN
];
1697 char ch_grp_str
[INET_ADDRSTRLEN
];
1698 json_object
*json_iface
= NULL
;
1699 json_object
*json_row
= NULL
;
1700 json_object
*json_grp
= NULL
;
1701 struct in_addr ifaddr
;
1705 char buf
[PREFIX_STRLEN
];
1707 ifaddr
= pim_ifp
->primary_address
;
1709 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
1710 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
1712 pim_time_uptime_begin(uptime
, sizeof(uptime
), now
, ch
->ifjoin_creation
);
1713 pim_time_timer_to_mmss(expire
, sizeof(expire
),
1714 ch
->t_ifjoin_expiry_timer
);
1715 pim_time_timer_to_mmss(prune
, sizeof(prune
),
1716 ch
->t_ifjoin_prune_pending_timer
);
1719 json_object_object_get_ex(json
, ch
->interface
->name
,
1723 json_iface
= json_object_new_object();
1724 json_object_pim_ifp_add(json_iface
, ch
->interface
);
1725 json_object_object_add(json
, ch
->interface
->name
,
1729 json_row
= json_object_new_object();
1730 json_object_string_add(json_row
, "source", ch_src_str
);
1731 json_object_string_add(json_row
, "group", ch_grp_str
);
1732 json_object_string_add(json_row
, "upTime", uptime
);
1733 json_object_string_add(json_row
, "expire", expire
);
1734 json_object_string_add(json_row
, "prune", prune
);
1735 json_object_string_add(
1736 json_row
, "channelJoinName",
1737 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
, ch
->flags
));
1738 if (PIM_IF_FLAG_TEST_S_G_RPT(ch
->flags
))
1739 json_object_int_add(json_row
, "SGRpt", 1);
1740 if (PIM_IF_FLAG_TEST_PROTO_PIM(ch
->flags
))
1741 json_object_int_add(json_row
, "protocolPim", 1);
1742 if (PIM_IF_FLAG_TEST_PROTO_IGMP(ch
->flags
))
1743 json_object_int_add(json_row
, "protocolIgmp", 1);
1744 json_object_object_get_ex(json_iface
, ch_grp_str
, &json_grp
);
1746 json_grp
= json_object_new_object();
1747 json_object_object_add(json_grp
, ch_src_str
, json_row
);
1748 json_object_object_add(json_iface
, ch_grp_str
,
1751 json_object_object_add(json_grp
, ch_src_str
, json_row
);
1753 vty_out(vty
, "%-16s %-15s %-15s %-15s %-10s %8s %-6s %5s\n",
1754 ch
->interface
->name
,
1755 inet_ntop(AF_INET
, &ifaddr
, buf
, sizeof(buf
)),
1756 ch_src_str
, ch_grp_str
,
1757 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
, ch
->flags
),
1758 uptime
, expire
, prune
);
1762 static void pim_show_join(struct pim_instance
*pim
, struct vty
*vty
,
1763 struct prefix_sg
*sg
, bool uj
)
1765 struct pim_interface
*pim_ifp
;
1766 struct pim_ifchannel
*ch
;
1767 struct interface
*ifp
;
1769 json_object
*json
= NULL
;
1771 now
= pim_time_monotonic_sec();
1774 json
= json_object_new_object();
1777 "Interface Address Source Group State Uptime Expire Prune\n");
1779 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1780 pim_ifp
= ifp
->info
;
1784 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
1785 if (sg
->grp
.s_addr
!= INADDR_ANY
1786 && sg
->grp
.s_addr
!= ch
->sg
.grp
.s_addr
)
1788 if (sg
->src
.s_addr
!= INADDR_ANY
1789 && sg
->src
.s_addr
!= ch
->sg
.src
.s_addr
)
1791 pim_show_join_helper(vty
, pim_ifp
, ch
, json
, now
, uj
);
1792 } /* scan interface channels */
1796 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1797 json
, JSON_C_TO_STRING_PRETTY
));
1798 json_object_free(json
);
1802 static void pim_show_neighbors_single(struct pim_instance
*pim
, struct vty
*vty
,
1803 const char *neighbor
, bool uj
)
1805 struct listnode
*neighnode
;
1806 struct interface
*ifp
;
1807 struct pim_interface
*pim_ifp
;
1808 struct pim_neighbor
*neigh
;
1810 int found_neighbor
= 0;
1811 int option_address_list
;
1812 int option_dr_priority
;
1813 int option_generation_id
;
1814 int option_holdtime
;
1815 int option_lan_prune_delay
;
1819 char neigh_src_str
[INET_ADDRSTRLEN
];
1821 json_object
*json
= NULL
;
1822 json_object
*json_ifp
= NULL
;
1823 json_object
*json_row
= NULL
;
1825 now
= pim_time_monotonic_sec();
1828 json
= json_object_new_object();
1830 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1831 pim_ifp
= ifp
->info
;
1836 if (pim_ifp
->pim_sock_fd
< 0)
1839 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
1841 pim_inet4_dump("<src?>", neigh
->source_addr
,
1842 neigh_src_str
, sizeof(neigh_src_str
));
1845 * The user can specify either the interface name or the
1847 * If this pim_ifp matches neither then skip.
1849 if (strcmp(neighbor
, "detail")
1850 && strcmp(neighbor
, ifp
->name
)
1851 && strcmp(neighbor
, neigh_src_str
))
1855 pim_time_uptime(uptime
, sizeof(uptime
),
1856 now
- neigh
->creation
);
1857 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
1858 neigh
->t_expire_timer
);
1860 option_address_list
= 0;
1861 option_dr_priority
= 0;
1862 option_generation_id
= 0;
1863 option_holdtime
= 0;
1864 option_lan_prune_delay
= 0;
1867 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1868 PIM_OPTION_MASK_ADDRESS_LIST
))
1869 option_address_list
= 1;
1871 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1872 PIM_OPTION_MASK_DR_PRIORITY
))
1873 option_dr_priority
= 1;
1875 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1876 PIM_OPTION_MASK_GENERATION_ID
))
1877 option_generation_id
= 1;
1879 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1880 PIM_OPTION_MASK_HOLDTIME
))
1881 option_holdtime
= 1;
1883 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1884 PIM_OPTION_MASK_LAN_PRUNE_DELAY
))
1885 option_lan_prune_delay
= 1;
1887 if (PIM_OPTION_IS_SET(
1888 neigh
->hello_options
,
1889 PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION
))
1894 /* Does this ifp live in json? If not create
1896 json_object_object_get_ex(json
, ifp
->name
,
1900 json_ifp
= json_object_new_object();
1901 json_object_pim_ifp_add(json_ifp
, ifp
);
1902 json_object_object_add(json
, ifp
->name
,
1906 json_row
= json_object_new_object();
1907 json_object_string_add(json_row
, "interface",
1909 json_object_string_add(json_row
, "address",
1911 json_object_string_add(json_row
, "upTime",
1913 json_object_string_add(json_row
, "holdtime",
1915 json_object_int_add(json_row
, "drPriority",
1916 neigh
->dr_priority
);
1917 json_object_int_add(json_row
, "generationId",
1918 neigh
->generation_id
);
1920 if (option_address_list
)
1921 json_object_boolean_true_add(
1923 "helloOptionAddressList");
1925 if (option_dr_priority
)
1926 json_object_boolean_true_add(
1928 "helloOptionDrPriority");
1930 if (option_generation_id
)
1931 json_object_boolean_true_add(
1933 "helloOptionGenerationId");
1935 if (option_holdtime
)
1936 json_object_boolean_true_add(
1938 "helloOptionHoldtime");
1940 if (option_lan_prune_delay
)
1941 json_object_boolean_true_add(
1943 "helloOptionLanPruneDelay");
1946 json_object_boolean_true_add(
1947 json_row
, "helloOptionTBit");
1949 json_object_object_add(json_ifp
, neigh_src_str
,
1953 vty_out(vty
, "Interface : %s\n", ifp
->name
);
1954 vty_out(vty
, "Neighbor : %s\n", neigh_src_str
);
1962 " DR Priority : %d\n",
1963 neigh
->dr_priority
);
1965 " Generation ID : %08x\n",
1966 neigh
->generation_id
);
1968 " Override Interval (msec) : %d\n",
1969 neigh
->override_interval_msec
);
1971 " Propagation Delay (msec) : %d\n",
1972 neigh
->propagation_delay_msec
);
1974 " Hello Option - Address List : %s\n",
1975 option_address_list
? "yes" : "no");
1977 " Hello Option - DR Priority : %s\n",
1978 option_dr_priority
? "yes" : "no");
1980 " Hello Option - Generation ID : %s\n",
1981 option_generation_id
? "yes" : "no");
1983 " Hello Option - Holdtime : %s\n",
1984 option_holdtime
? "yes" : "no");
1986 " Hello Option - LAN Prune Delay : %s\n",
1987 option_lan_prune_delay
? "yes" : "no");
1989 " Hello Option - T-bit : %s\n",
1990 option_t_bit
? "yes" : "no");
1991 pim_bfd_show_info(vty
, neigh
->bfd_info
,
1999 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2000 json
, JSON_C_TO_STRING_PRETTY
));
2001 json_object_free(json
);
2004 if (!found_neighbor
)
2006 "%% No such interface or neighbor\n");
2011 static void pim_show_state(struct pim_instance
*pim
, struct vty
*vty
,
2012 const char *src_or_group
, const char *group
, bool uj
)
2014 struct channel_oil
*c_oil
;
2015 json_object
*json
= NULL
;
2016 json_object
*json_group
= NULL
;
2017 json_object
*json_ifp_in
= NULL
;
2018 json_object
*json_ifp_out
= NULL
;
2019 json_object
*json_source
= NULL
;
2022 now
= pim_time_monotonic_sec();
2025 json
= json_object_new_object();
2028 "Codes: J -> Pim Join, I -> IGMP Report, S -> Source, * -> Inherited from (*,G), V -> VxLAN, M -> Muted");
2030 "\nActive Source Group RPT IIF OIL\n");
2033 frr_each (rb_pim_oil
, &pim
->channel_oil_head
, c_oil
) {
2034 char grp_str
[INET_ADDRSTRLEN
];
2035 char src_str
[INET_ADDRSTRLEN
];
2036 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
2037 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
2039 struct interface
*ifp_in
;
2044 PIM_UPSTREAM_FLAG_TEST_USE_RPT(c_oil
->up
->flags
)) ||
2045 c_oil
->oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
2050 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
2052 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
2054 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
2057 strlcpy(in_ifname
, ifp_in
->name
, sizeof(in_ifname
));
2059 strlcpy(in_ifname
, "<iif?>", sizeof(in_ifname
));
2062 if (strcmp(src_or_group
, src_str
)
2063 && strcmp(src_or_group
, grp_str
))
2066 if (group
&& strcmp(group
, grp_str
))
2072 /* Find the group, create it if it doesn't exist */
2073 json_object_object_get_ex(json
, grp_str
, &json_group
);
2076 json_group
= json_object_new_object();
2077 json_object_object_add(json
, grp_str
,
2081 /* Find the source nested under the group, create it if
2082 * it doesn't exist */
2083 json_object_object_get_ex(json_group
, src_str
,
2087 json_source
= json_object_new_object();
2088 json_object_object_add(json_group
, src_str
,
2092 /* Find the inbound interface nested under the source,
2093 * create it if it doesn't exist */
2094 json_object_object_get_ex(json_source
, in_ifname
,
2098 json_ifp_in
= json_object_new_object();
2099 json_object_object_add(json_source
, in_ifname
,
2101 json_object_int_add(json_source
, "Installed",
2104 json_object_boolean_true_add(
2105 json_source
, "isRpt");
2107 json_object_boolean_false_add(
2108 json_source
, "isRpt");
2109 json_object_int_add(json_source
, "RefCount",
2110 c_oil
->oil_ref_count
);
2111 json_object_int_add(json_source
, "OilListSize",
2113 json_object_int_add(
2114 json_source
, "OilRescan",
2115 c_oil
->oil_inherited_rescan
);
2116 json_object_int_add(json_source
, "LastUsed",
2117 c_oil
->cc
.lastused
);
2118 json_object_int_add(json_source
, "PacketCount",
2120 json_object_int_add(json_source
, "ByteCount",
2122 json_object_int_add(json_source
,
2124 c_oil
->cc
.wrong_if
);
2127 vty_out(vty
, "%-6d %-15s %-15s %-3s %-16s ",
2128 c_oil
->installed
, src_str
, grp_str
,
2129 isRpt
? "y" : "n", in_ifname
);
2132 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
2134 struct interface
*ifp_out
;
2135 char oif_uptime
[10];
2138 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
2142 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
2144 oif_uptime
, sizeof(oif_uptime
),
2145 now
- c_oil
->oif_creation
[oif_vif_index
]);
2148 strlcpy(out_ifname
, ifp_out
->name
, sizeof(out_ifname
));
2150 strlcpy(out_ifname
, "<oif?>", sizeof(out_ifname
));
2153 json_ifp_out
= json_object_new_object();
2154 json_object_string_add(json_ifp_out
, "source",
2156 json_object_string_add(json_ifp_out
, "group",
2158 json_object_string_add(json_ifp_out
,
2161 json_object_string_add(json_ifp_out
,
2162 "outboundInterface",
2164 json_object_int_add(json_ifp_out
, "installed",
2167 json_object_object_add(json_ifp_in
, out_ifname
,
2172 vty_out(vty
, "%s(%c%c%c%c%c)",
2174 (c_oil
->oif_flags
[oif_vif_index
]
2175 & PIM_OIF_FLAG_PROTO_IGMP
)
2178 (c_oil
->oif_flags
[oif_vif_index
]
2179 & PIM_OIF_FLAG_PROTO_PIM
)
2182 (c_oil
->oif_flags
[oif_vif_index
]
2183 & PIM_OIF_FLAG_PROTO_VXLAN
)
2186 (c_oil
->oif_flags
[oif_vif_index
]
2187 & PIM_OIF_FLAG_PROTO_STAR
)
2190 (c_oil
->oif_flags
[oif_vif_index
]
2191 & PIM_OIF_FLAG_MUTE
)
2195 vty_out(vty
, ", %s(%c%c%c%c%c)",
2197 (c_oil
->oif_flags
[oif_vif_index
]
2198 & PIM_OIF_FLAG_PROTO_IGMP
)
2201 (c_oil
->oif_flags
[oif_vif_index
]
2202 & PIM_OIF_FLAG_PROTO_PIM
)
2205 (c_oil
->oif_flags
[oif_vif_index
]
2206 & PIM_OIF_FLAG_PROTO_VXLAN
)
2209 (c_oil
->oif_flags
[oif_vif_index
]
2210 & PIM_OIF_FLAG_PROTO_STAR
)
2213 (c_oil
->oif_flags
[oif_vif_index
]
2214 & PIM_OIF_FLAG_MUTE
)
2226 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2227 json
, JSON_C_TO_STRING_PRETTY
));
2228 json_object_free(json
);
2234 static void pim_show_neighbors(struct pim_instance
*pim
, struct vty
*vty
,
2237 struct listnode
*neighnode
;
2238 struct interface
*ifp
;
2239 struct pim_interface
*pim_ifp
;
2240 struct pim_neighbor
*neigh
;
2244 char neigh_src_str
[INET_ADDRSTRLEN
];
2245 json_object
*json
= NULL
;
2246 json_object
*json_ifp_rows
= NULL
;
2247 json_object
*json_row
= NULL
;
2249 now
= pim_time_monotonic_sec();
2252 json
= json_object_new_object();
2255 "Interface Neighbor Uptime Holdtime DR Pri\n");
2258 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2259 pim_ifp
= ifp
->info
;
2264 if (pim_ifp
->pim_sock_fd
< 0)
2268 json_ifp_rows
= json_object_new_object();
2270 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
2272 pim_inet4_dump("<src?>", neigh
->source_addr
,
2273 neigh_src_str
, sizeof(neigh_src_str
));
2274 pim_time_uptime(uptime
, sizeof(uptime
),
2275 now
- neigh
->creation
);
2276 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
2277 neigh
->t_expire_timer
);
2280 json_row
= json_object_new_object();
2281 json_object_string_add(json_row
, "interface",
2283 json_object_string_add(json_row
, "neighbor",
2285 json_object_string_add(json_row
, "upTime",
2287 json_object_string_add(json_row
, "holdTime",
2289 json_object_int_add(json_row
, "holdTimeMax",
2291 json_object_int_add(json_row
, "drPriority",
2292 neigh
->dr_priority
);
2293 json_object_object_add(json_ifp_rows
,
2294 neigh_src_str
, json_row
);
2297 vty_out(vty
, "%-16s %15s %8s %8s %6d\n",
2298 ifp
->name
, neigh_src_str
, uptime
,
2299 expire
, neigh
->dr_priority
);
2304 json_object_object_add(json
, ifp
->name
, json_ifp_rows
);
2305 json_ifp_rows
= NULL
;
2310 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2311 json
, JSON_C_TO_STRING_PRETTY
));
2312 json_object_free(json
);
2316 static void pim_show_neighbors_secondary(struct pim_instance
*pim
,
2319 struct interface
*ifp
;
2322 "Interface Address Neighbor Secondary \n");
2324 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2325 struct pim_interface
*pim_ifp
;
2326 struct in_addr ifaddr
;
2327 struct listnode
*neighnode
;
2328 struct pim_neighbor
*neigh
;
2329 char buf
[PREFIX_STRLEN
];
2331 pim_ifp
= ifp
->info
;
2336 if (pim_ifp
->pim_sock_fd
< 0)
2339 ifaddr
= pim_ifp
->primary_address
;
2341 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
2343 char neigh_src_str
[INET_ADDRSTRLEN
];
2344 struct listnode
*prefix_node
;
2347 if (!neigh
->prefix_list
)
2350 pim_inet4_dump("<src?>", neigh
->source_addr
,
2351 neigh_src_str
, sizeof(neigh_src_str
));
2353 for (ALL_LIST_ELEMENTS_RO(neigh
->prefix_list
,
2355 vty_out(vty
, "%-16s %-15s %-15s %-15pFX\n",
2357 inet_ntop(AF_INET
, &ifaddr
,
2364 static void json_object_pim_upstream_add(json_object
*json
,
2365 struct pim_upstream
*up
)
2367 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED
)
2368 json_object_boolean_true_add(json
, "drJoinDesired");
2370 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED
)
2371 json_object_boolean_true_add(json
, "drJoinDesiredUpdated");
2373 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
2374 json_object_boolean_true_add(json
, "firstHopRouter");
2376 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_IGMP
)
2377 json_object_boolean_true_add(json
, "sourceIgmp");
2379 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_PIM
)
2380 json_object_boolean_true_add(json
, "sourcePim");
2382 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_STREAM
)
2383 json_object_boolean_true_add(json
, "sourceStream");
2385 /* XXX: need to print ths flag in the plain text display as well */
2386 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_MSDP
)
2387 json_object_boolean_true_add(json
, "sourceMsdp");
2389 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SEND_SG_RPT_PRUNE
)
2390 json_object_boolean_true_add(json
, "sendSGRptPrune");
2392 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_LHR
)
2393 json_object_boolean_true_add(json
, "lastHopRouter");
2395 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DISABLE_KAT_EXPIRY
)
2396 json_object_boolean_true_add(json
, "disableKATExpiry");
2398 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_STATIC_IIF
)
2399 json_object_boolean_true_add(json
, "staticIncomingInterface");
2401 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_ALLOW_IIF_IN_OIL
)
2402 json_object_boolean_true_add(json
,
2403 "allowIncomingInterfaceinOil");
2405 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_NO_PIMREG_DATA
)
2406 json_object_boolean_true_add(json
, "noPimRegistrationData");
2408 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FORCE_PIMREG
)
2409 json_object_boolean_true_add(json
, "forcePimRegistration");
2411 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_ORIG
)
2412 json_object_boolean_true_add(json
, "sourceVxlanOrigination");
2414 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_TERM
)
2415 json_object_boolean_true_add(json
, "sourceVxlanTermination");
2417 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_VXLAN
)
2418 json_object_boolean_true_add(json
, "mlagVxlan");
2420 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_NON_DF
)
2421 json_object_boolean_true_add(json
,
2422 "mlagNonDesignatedForwarder");
2426 pim_upstream_state2brief_str(enum pim_upstream_state join_state
,
2427 char *state_str
, size_t state_str_len
)
2429 switch (join_state
) {
2430 case PIM_UPSTREAM_NOTJOINED
:
2431 strlcpy(state_str
, "NotJ", state_str_len
);
2433 case PIM_UPSTREAM_JOINED
:
2434 strlcpy(state_str
, "J", state_str_len
);
2437 strlcpy(state_str
, "Unk", state_str_len
);
2442 static const char *pim_reg_state2brief_str(enum pim_reg_state reg_state
,
2443 char *state_str
, size_t state_str_len
)
2445 switch (reg_state
) {
2446 case PIM_REG_NOINFO
:
2447 strlcpy(state_str
, "RegNI", state_str_len
);
2450 strlcpy(state_str
, "RegJ", state_str_len
);
2452 case PIM_REG_JOIN_PENDING
:
2454 strlcpy(state_str
, "RegP", state_str_len
);
2457 strlcpy(state_str
, "Unk", state_str_len
);
2462 static void pim_show_upstream(struct pim_instance
*pim
, struct vty
*vty
,
2463 struct prefix_sg
*sg
, bool uj
)
2465 struct pim_upstream
*up
;
2467 json_object
*json
= NULL
;
2468 json_object
*json_group
= NULL
;
2469 json_object
*json_row
= NULL
;
2471 now
= pim_time_monotonic_sec();
2474 json
= json_object_new_object();
2477 "Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt\n");
2479 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
2480 char src_str
[INET_ADDRSTRLEN
];
2481 char grp_str
[INET_ADDRSTRLEN
];
2483 char join_timer
[10];
2486 char msdp_reg_timer
[10];
2487 char state_str
[PIM_REG_STATE_STR_LEN
];
2489 if (sg
->grp
.s_addr
!= INADDR_ANY
2490 && sg
->grp
.s_addr
!= up
->sg
.grp
.s_addr
)
2492 if (sg
->src
.s_addr
!= INADDR_ANY
2493 && sg
->src
.s_addr
!= up
->sg
.src
.s_addr
)
2496 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2497 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2498 pim_time_uptime(uptime
, sizeof(uptime
),
2499 now
- up
->state_transition
);
2500 pim_time_timer_to_hhmmss(join_timer
, sizeof(join_timer
),
2504 * If the upstream is not dummy and it has a J/P timer for the
2505 * neighbor display that
2507 if (!up
->t_join_timer
&& up
->rpf
.source_nexthop
.interface
) {
2508 struct pim_neighbor
*nbr
;
2510 nbr
= pim_neighbor_find(
2511 up
->rpf
.source_nexthop
.interface
,
2512 up
->rpf
.rpf_addr
.u
.prefix4
);
2514 pim_time_timer_to_hhmmss(join_timer
,
2519 pim_time_timer_to_hhmmss(rs_timer
, sizeof(rs_timer
),
2521 pim_time_timer_to_hhmmss(ka_timer
, sizeof(ka_timer
),
2523 pim_time_timer_to_hhmmss(msdp_reg_timer
, sizeof(msdp_reg_timer
),
2524 up
->t_msdp_reg_timer
);
2526 pim_upstream_state2brief_str(up
->join_state
, state_str
, sizeof(state_str
));
2527 if (up
->reg_state
!= PIM_REG_NOINFO
) {
2528 char tmp_str
[PIM_REG_STATE_STR_LEN
];
2529 char tmp
[sizeof(state_str
) + 1];
2531 snprintf(tmp
, sizeof(tmp
), ",%s",
2532 pim_reg_state2brief_str(up
->reg_state
, tmp_str
,
2534 strlcat(state_str
, tmp
, sizeof(state_str
));
2538 json_object_object_get_ex(json
, grp_str
, &json_group
);
2541 json_group
= json_object_new_object();
2542 json_object_object_add(json
, grp_str
,
2546 json_row
= json_object_new_object();
2547 json_object_pim_upstream_add(json_row
, up
);
2548 json_object_string_add(
2549 json_row
, "inboundInterface",
2550 up
->rpf
.source_nexthop
.interface
2551 ? up
->rpf
.source_nexthop
.interface
->name
2555 * The RPF address we use is slightly different
2556 * based upon what we are looking up.
2557 * If we have a S, list that unless
2558 * we are the FHR, else we just put
2559 * the RP as the rpfAddress
2561 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
2562 || up
->sg
.src
.s_addr
== INADDR_ANY
) {
2563 char rpf
[PREFIX_STRLEN
];
2564 struct pim_rpf
*rpg
;
2566 rpg
= RP(pim
, up
->sg
.grp
);
2567 pim_inet4_dump("<rpf?>",
2568 rpg
->rpf_addr
.u
.prefix4
, rpf
,
2570 json_object_string_add(json_row
, "rpfAddress",
2573 json_object_string_add(json_row
, "rpfAddress",
2577 json_object_string_add(json_row
, "source", src_str
);
2578 json_object_string_add(json_row
, "group", grp_str
);
2579 json_object_string_add(json_row
, "state", state_str
);
2580 json_object_string_add(
2581 json_row
, "joinState",
2582 pim_upstream_state2str(up
->join_state
));
2583 json_object_string_add(
2584 json_row
, "regState",
2585 pim_reg_state2str(up
->reg_state
, state_str
, sizeof(state_str
)));
2586 json_object_string_add(json_row
, "upTime", uptime
);
2587 json_object_string_add(json_row
, "joinTimer",
2589 json_object_string_add(json_row
, "resetTimer",
2591 json_object_string_add(json_row
, "keepaliveTimer",
2593 json_object_string_add(json_row
, "msdpRegTimer",
2595 json_object_int_add(json_row
, "refCount",
2597 json_object_int_add(json_row
, "sptBit", up
->sptbit
);
2598 json_object_object_add(json_group
, src_str
, json_row
);
2601 "%-16s%-15s %-15s %-11s %-8s %-9s %-9s %-9s %6d\n",
2602 up
->rpf
.source_nexthop
.interface
2603 ? up
->rpf
.source_nexthop
.interface
->name
2605 src_str
, grp_str
, state_str
, uptime
, join_timer
,
2606 rs_timer
, ka_timer
, up
->ref_count
);
2611 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2612 json
, JSON_C_TO_STRING_PRETTY
));
2613 json_object_free(json
);
2617 static void pim_show_channel_helper(struct pim_instance
*pim
,
2619 struct pim_interface
*pim_ifp
,
2620 struct pim_ifchannel
*ch
,
2621 json_object
*json
, bool uj
)
2623 struct pim_upstream
*up
= ch
->upstream
;
2624 json_object
*json_group
= NULL
;
2625 char src_str
[INET_ADDRSTRLEN
];
2626 char grp_str
[INET_ADDRSTRLEN
];
2627 json_object
*json_row
= NULL
;
2629 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2630 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2633 json_object_object_get_ex(json
, grp_str
, &json_group
);
2636 json_group
= json_object_new_object();
2637 json_object_object_add(json
, grp_str
, json_group
);
2640 json_row
= json_object_new_object();
2641 json_object_pim_upstream_add(json_row
, up
);
2642 json_object_string_add(json_row
, "interface",
2643 ch
->interface
->name
);
2644 json_object_string_add(json_row
, "source", src_str
);
2645 json_object_string_add(json_row
, "group", grp_str
);
2647 if (pim_macro_ch_lost_assert(ch
))
2648 json_object_boolean_true_add(json_row
, "lostAssert");
2650 if (pim_macro_chisin_joins(ch
))
2651 json_object_boolean_true_add(json_row
, "joins");
2653 if (pim_macro_chisin_pim_include(ch
))
2654 json_object_boolean_true_add(json_row
, "pimInclude");
2656 if (pim_upstream_evaluate_join_desired(pim
, up
))
2657 json_object_boolean_true_add(json_row
,
2658 "evaluateJoinDesired");
2660 json_object_object_add(json_group
, src_str
, json_row
);
2663 vty_out(vty
, "%-16s %-15s %-15s %-10s %-5s %-10s %-11s %-6s\n",
2664 ch
->interface
->name
, src_str
, grp_str
,
2665 pim_macro_ch_lost_assert(ch
) ? "yes" : "no",
2666 pim_macro_chisin_joins(ch
) ? "yes" : "no",
2667 pim_macro_chisin_pim_include(ch
) ? "yes" : "no",
2668 PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(up
->flags
)
2671 pim_upstream_evaluate_join_desired(pim
, up
) ? "yes"
2676 static void pim_show_channel(struct pim_instance
*pim
, struct vty
*vty
,
2679 struct pim_interface
*pim_ifp
;
2680 struct pim_ifchannel
*ch
;
2681 struct interface
*ifp
;
2683 json_object
*json
= NULL
;
2686 json
= json_object_new_object();
2689 "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD\n");
2691 /* scan per-interface (S,G) state */
2692 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2693 pim_ifp
= ifp
->info
;
2698 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
2699 /* scan all interfaces */
2700 pim_show_channel_helper(pim
, vty
, pim_ifp
, ch
,
2706 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2707 json
, JSON_C_TO_STRING_PRETTY
));
2708 json_object_free(json
);
2712 static void pim_show_join_desired_helper(struct pim_instance
*pim
,
2714 struct pim_upstream
*up
,
2715 json_object
*json
, bool uj
)
2717 json_object
*json_group
= NULL
;
2718 char src_str
[INET_ADDRSTRLEN
];
2719 char grp_str
[INET_ADDRSTRLEN
];
2720 json_object
*json_row
= NULL
;
2722 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2723 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2726 json_object_object_get_ex(json
, grp_str
, &json_group
);
2729 json_group
= json_object_new_object();
2730 json_object_object_add(json
, grp_str
, json_group
);
2733 json_row
= json_object_new_object();
2734 json_object_pim_upstream_add(json_row
, up
);
2735 json_object_string_add(json_row
, "source", src_str
);
2736 json_object_string_add(json_row
, "group", grp_str
);
2738 if (pim_upstream_evaluate_join_desired(pim
, up
))
2739 json_object_boolean_true_add(json_row
,
2740 "evaluateJoinDesired");
2742 json_object_object_add(json_group
, src_str
, json_row
);
2745 vty_out(vty
, "%-15s %-15s %-6s\n",
2747 pim_upstream_evaluate_join_desired(pim
, up
) ? "yes"
2752 static void pim_show_join_desired(struct pim_instance
*pim
, struct vty
*vty
,
2755 struct pim_upstream
*up
;
2757 json_object
*json
= NULL
;
2760 json
= json_object_new_object();
2763 "Source Group EvalJD\n");
2765 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
2766 /* scan all interfaces */
2767 pim_show_join_desired_helper(pim
, vty
, up
,
2772 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2773 json
, JSON_C_TO_STRING_PRETTY
));
2774 json_object_free(json
);
2778 static void pim_show_upstream_rpf(struct pim_instance
*pim
, struct vty
*vty
,
2781 struct pim_upstream
*up
;
2782 json_object
*json
= NULL
;
2783 json_object
*json_group
= NULL
;
2784 json_object
*json_row
= NULL
;
2787 json
= json_object_new_object();
2790 "Source Group RpfIface RibNextHop RpfAddress \n");
2792 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
2793 char src_str
[INET_ADDRSTRLEN
];
2794 char grp_str
[INET_ADDRSTRLEN
];
2795 char rpf_nexthop_str
[PREFIX_STRLEN
];
2796 char rpf_addr_str
[PREFIX_STRLEN
];
2797 struct pim_rpf
*rpf
;
2798 const char *rpf_ifname
;
2802 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2803 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2804 pim_addr_dump("<nexthop?>",
2805 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2806 rpf_nexthop_str
, sizeof(rpf_nexthop_str
));
2807 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2808 sizeof(rpf_addr_str
));
2810 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2813 json_object_object_get_ex(json
, grp_str
, &json_group
);
2816 json_group
= json_object_new_object();
2817 json_object_object_add(json
, grp_str
,
2821 json_row
= json_object_new_object();
2822 json_object_pim_upstream_add(json_row
, up
);
2823 json_object_string_add(json_row
, "source", src_str
);
2824 json_object_string_add(json_row
, "group", grp_str
);
2825 json_object_string_add(json_row
, "rpfInterface",
2827 json_object_string_add(json_row
, "ribNexthop",
2829 json_object_string_add(json_row
, "rpfAddress",
2831 json_object_object_add(json_group
, src_str
, json_row
);
2833 vty_out(vty
, "%-15s %-15s %-16s %-15s %-15s\n", src_str
,
2834 grp_str
, rpf_ifname
, rpf_nexthop_str
,
2840 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2841 json
, JSON_C_TO_STRING_PRETTY
));
2842 json_object_free(json
);
2846 static void show_rpf_refresh_stats(struct vty
*vty
, struct pim_instance
*pim
,
2847 time_t now
, json_object
*json
)
2849 char refresh_uptime
[10];
2851 pim_time_uptime_begin(refresh_uptime
, sizeof(refresh_uptime
), now
,
2852 pim
->rpf_cache_refresh_last
);
2855 json_object_int_add(json
, "rpfCacheRefreshDelayMsecs",
2856 router
->rpf_cache_refresh_delay_msec
);
2857 json_object_int_add(
2858 json
, "rpfCacheRefreshTimer",
2859 pim_time_timer_remain_msec(pim
->rpf_cache_refresher
));
2860 json_object_int_add(json
, "rpfCacheRefreshRequests",
2861 pim
->rpf_cache_refresh_requests
);
2862 json_object_int_add(json
, "rpfCacheRefreshEvents",
2863 pim
->rpf_cache_refresh_events
);
2864 json_object_string_add(json
, "rpfCacheRefreshLast",
2866 json_object_int_add(json
, "nexthopLookups",
2867 pim
->nexthop_lookups
);
2868 json_object_int_add(json
, "nexthopLookupsAvoided",
2869 pim
->nexthop_lookups_avoided
);
2872 "RPF Cache Refresh Delay: %ld msecs\n"
2873 "RPF Cache Refresh Timer: %ld msecs\n"
2874 "RPF Cache Refresh Requests: %lld\n"
2875 "RPF Cache Refresh Events: %lld\n"
2876 "RPF Cache Refresh Last: %s\n"
2877 "Nexthop Lookups: %lld\n"
2878 "Nexthop Lookups Avoided: %lld\n",
2879 router
->rpf_cache_refresh_delay_msec
,
2880 pim_time_timer_remain_msec(pim
->rpf_cache_refresher
),
2881 (long long)pim
->rpf_cache_refresh_requests
,
2882 (long long)pim
->rpf_cache_refresh_events
,
2883 refresh_uptime
, (long long)pim
->nexthop_lookups
,
2884 (long long)pim
->nexthop_lookups_avoided
);
2888 static void show_scan_oil_stats(struct pim_instance
*pim
, struct vty
*vty
,
2891 char uptime_scan_oil
[10];
2892 char uptime_mroute_add
[10];
2893 char uptime_mroute_del
[10];
2895 pim_time_uptime_begin(uptime_scan_oil
, sizeof(uptime_scan_oil
), now
,
2896 pim
->scan_oil_last
);
2897 pim_time_uptime_begin(uptime_mroute_add
, sizeof(uptime_mroute_add
), now
,
2898 pim
->mroute_add_last
);
2899 pim_time_uptime_begin(uptime_mroute_del
, sizeof(uptime_mroute_del
), now
,
2900 pim
->mroute_del_last
);
2903 "Scan OIL - Last: %s Events: %lld\n"
2904 "MFC Add - Last: %s Events: %lld\n"
2905 "MFC Del - Last: %s Events: %lld\n",
2906 uptime_scan_oil
, (long long)pim
->scan_oil_events
,
2907 uptime_mroute_add
, (long long)pim
->mroute_add_events
,
2908 uptime_mroute_del
, (long long)pim
->mroute_del_events
);
2911 static void pim_show_rpf(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
2913 struct pim_upstream
*up
;
2914 time_t now
= pim_time_monotonic_sec();
2915 json_object
*json
= NULL
;
2916 json_object
*json_group
= NULL
;
2917 json_object
*json_row
= NULL
;
2920 json
= json_object_new_object();
2921 show_rpf_refresh_stats(vty
, pim
, now
, json
);
2923 show_rpf_refresh_stats(vty
, pim
, now
, json
);
2926 "Source Group RpfIface RpfAddress RibNextHop Metric Pref\n");
2929 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
2930 char src_str
[INET_ADDRSTRLEN
];
2931 char grp_str
[INET_ADDRSTRLEN
];
2932 char rpf_addr_str
[PREFIX_STRLEN
];
2933 char rib_nexthop_str
[PREFIX_STRLEN
];
2934 const char *rpf_ifname
;
2935 struct pim_rpf
*rpf
= &up
->rpf
;
2937 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2938 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2939 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2940 sizeof(rpf_addr_str
));
2941 pim_addr_dump("<nexthop?>",
2942 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2943 rib_nexthop_str
, sizeof(rib_nexthop_str
));
2945 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2948 json_object_object_get_ex(json
, grp_str
, &json_group
);
2951 json_group
= json_object_new_object();
2952 json_object_object_add(json
, grp_str
,
2956 json_row
= json_object_new_object();
2957 json_object_string_add(json_row
, "source", src_str
);
2958 json_object_string_add(json_row
, "group", grp_str
);
2959 json_object_string_add(json_row
, "rpfInterface",
2961 json_object_string_add(json_row
, "rpfAddress",
2963 json_object_string_add(json_row
, "ribNexthop",
2965 json_object_int_add(
2966 json_row
, "routeMetric",
2967 rpf
->source_nexthop
.mrib_route_metric
);
2968 json_object_int_add(
2969 json_row
, "routePreference",
2970 rpf
->source_nexthop
.mrib_metric_preference
);
2971 json_object_object_add(json_group
, src_str
, json_row
);
2974 vty_out(vty
, "%-15s %-15s %-16s %-15s %-15s %6d %4d\n",
2975 src_str
, grp_str
, rpf_ifname
, rpf_addr_str
,
2977 rpf
->source_nexthop
.mrib_route_metric
,
2978 rpf
->source_nexthop
.mrib_metric_preference
);
2983 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2984 json
, JSON_C_TO_STRING_PRETTY
));
2985 json_object_free(json
);
2989 struct pnc_cache_walk_data
{
2991 struct pim_instance
*pim
;
2994 static int pim_print_pnc_cache_walkcb(struct hash_bucket
*bucket
, void *arg
)
2996 struct pim_nexthop_cache
*pnc
= bucket
->data
;
2997 struct pnc_cache_walk_data
*cwd
= arg
;
2998 struct vty
*vty
= cwd
->vty
;
2999 struct pim_instance
*pim
= cwd
->pim
;
3000 struct nexthop
*nh_node
= NULL
;
3001 ifindex_t first_ifindex
;
3002 struct interface
*ifp
= NULL
;
3003 char buf
[PREFIX_STRLEN
];
3005 for (nh_node
= pnc
->nexthop
; nh_node
; nh_node
= nh_node
->next
) {
3006 first_ifindex
= nh_node
->ifindex
;
3007 ifp
= if_lookup_by_index(first_ifindex
, pim
->vrf_id
);
3009 vty_out(vty
, "%-15s ", inet_ntop(AF_INET
,
3010 &pnc
->rpf
.rpf_addr
.u
.prefix4
,
3012 vty_out(vty
, "%-16s ", ifp
? ifp
->name
: "NULL");
3013 vty_out(vty
, "%pI4 ", &nh_node
->gate
.ipv4
);
3019 static void pim_show_nexthop(struct pim_instance
*pim
, struct vty
*vty
)
3021 struct pnc_cache_walk_data cwd
;
3025 vty_out(vty
, "Number of registered addresses: %lu\n",
3026 pim
->rpf_hash
->count
);
3027 vty_out(vty
, "Address Interface Nexthop\n");
3028 vty_out(vty
, "---------------------------------------------\n");
3030 hash_walk(pim
->rpf_hash
, pim_print_pnc_cache_walkcb
, &cwd
);
3033 /* Display the bsm database details */
3034 static void pim_show_bsm_db(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
3036 struct listnode
*bsmnode
;
3039 struct bsm_info
*bsm
;
3040 json_object
*json
= NULL
;
3041 json_object
*json_group
= NULL
;
3042 json_object
*json_row
= NULL
;
3044 count
= pim
->global_scope
.bsm_list
->count
;
3047 json
= json_object_new_object();
3048 json_object_int_add(json
, "Number of the fragments", count
);
3050 vty_out(vty
, "Scope Zone: Global\n");
3051 vty_out(vty
, "Number of the fragments: %d\n", count
);
3055 for (ALL_LIST_ELEMENTS_RO(pim
->global_scope
.bsm_list
, bsmnode
, bsm
)) {
3056 char grp_str
[PREFIX_STRLEN
];
3057 char rp_str
[INET_ADDRSTRLEN
];
3058 char bsr_str
[INET_ADDRSTRLEN
];
3059 struct bsmmsg_grpinfo
*group
;
3060 struct bsmmsg_rpinfo
*rpaddr
;
3062 struct bsm_hdr
*hdr
;
3063 uint32_t offset
= 0;
3066 uint32_t frag_rp_cnt
= 0;
3071 /* skip pim header */
3072 buf
+= PIM_MSG_HEADER_LEN
;
3073 len
-= PIM_MSG_HEADER_LEN
;
3075 hdr
= (struct bsm_hdr
*)buf
;
3077 /* BSM starts with bsr header */
3078 buf
+= sizeof(struct bsm_hdr
);
3079 len
-= sizeof(struct bsm_hdr
);
3081 pim_inet4_dump("<BSR Address?>", hdr
->bsr_addr
.addr
, bsr_str
,
3086 json_object_string_add(json
, "BSR address", bsr_str
);
3087 json_object_int_add(json
, "BSR priority",
3089 json_object_int_add(json
, "Hashmask Length",
3091 json_object_int_add(json
, "Fragment Tag",
3092 ntohs(hdr
->frag_tag
));
3094 vty_out(vty
, "BSM Fragment : %d\n", fragment
);
3095 vty_out(vty
, "------------------\n");
3096 vty_out(vty
, "%-15s %-15s %-15s %-15s\n", "BSR-Address",
3097 "BSR-Priority", "Hashmask-len", "Fragment-Tag");
3098 vty_out(vty
, "%-15s %-15d %-15d %-15d\n", bsr_str
,
3099 hdr
->bsr_prio
, hdr
->hm_len
,
3100 ntohs(hdr
->frag_tag
));
3105 while (offset
< len
) {
3106 group
= (struct bsmmsg_grpinfo
*)buf
;
3108 if (group
->group
.family
== PIM_MSG_ADDRESS_FAMILY_IPV4
)
3109 grp
.family
= AF_INET
;
3111 grp
.prefixlen
= group
->group
.mask
;
3112 grp
.u
.prefix4
.s_addr
= group
->group
.addr
.s_addr
;
3114 prefix2str(&grp
, grp_str
, sizeof(grp_str
));
3116 buf
+= sizeof(struct bsmmsg_grpinfo
);
3117 offset
+= sizeof(struct bsmmsg_grpinfo
);
3120 json_object_object_get_ex(json
, grp_str
,
3123 json_group
= json_object_new_object();
3124 json_object_int_add(json_group
,
3127 json_object_int_add(
3128 json_group
, "Fragment Rp count",
3129 group
->frag_rp_count
);
3130 json_object_object_add(json
, grp_str
,
3134 vty_out(vty
, "Group : %s\n", grp_str
);
3135 vty_out(vty
, "-------------------\n");
3136 vty_out(vty
, "Rp Count:%d\n", group
->rp_count
);
3137 vty_out(vty
, "Fragment Rp Count : %d\n",
3138 group
->frag_rp_count
);
3141 frag_rp_cnt
= group
->frag_rp_count
;
3148 "RpAddress HoldTime Priority\n");
3150 while (frag_rp_cnt
--) {
3151 rpaddr
= (struct bsmmsg_rpinfo
*)buf
;
3153 buf
+= sizeof(struct bsmmsg_rpinfo
);
3154 offset
+= sizeof(struct bsmmsg_rpinfo
);
3156 pim_inet4_dump("<Rp addr?>",
3157 rpaddr
->rpaddr
.addr
, rp_str
,
3161 json_row
= json_object_new_object();
3162 json_object_string_add(
3163 json_row
, "Rp Address", rp_str
);
3164 json_object_int_add(
3165 json_row
, "Rp HoldTime",
3166 ntohs(rpaddr
->rp_holdtime
));
3167 json_object_int_add(json_row
,
3170 json_object_object_add(
3171 json_group
, rp_str
, json_row
);
3173 vty_out(vty
, "%-15s %-12d %d\n", rp_str
,
3174 ntohs(rpaddr
->rp_holdtime
),
3185 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3186 json
, JSON_C_TO_STRING_PRETTY
));
3187 json_object_free(json
);
3191 /*Display the group-rp mappings */
3192 static void pim_show_group_rp_mappings_info(struct pim_instance
*pim
,
3193 struct vty
*vty
, bool uj
)
3195 struct bsgrp_node
*bsgrp
;
3196 struct listnode
*rpnode
;
3197 struct bsm_rpinfo
*bsm_rp
;
3198 struct route_node
*rn
;
3199 char bsr_str
[INET_ADDRSTRLEN
];
3200 json_object
*json
= NULL
;
3201 json_object
*json_group
= NULL
;
3202 json_object
*json_row
= NULL
;
3204 if (pim
->global_scope
.current_bsr
.s_addr
== INADDR_ANY
)
3205 strlcpy(bsr_str
, "0.0.0.0", sizeof(bsr_str
));
3208 pim_inet4_dump("<bsr?>", pim
->global_scope
.current_bsr
, bsr_str
,
3212 json
= json_object_new_object();
3213 json_object_string_add(json
, "BSR Address", bsr_str
);
3215 vty_out(vty
, "BSR Address %s\n", bsr_str
);
3218 for (rn
= route_top(pim
->global_scope
.bsrp_table
); rn
;
3219 rn
= route_next(rn
)) {
3220 bsgrp
= (struct bsgrp_node
*)rn
->info
;
3225 char grp_str
[PREFIX_STRLEN
];
3227 prefix2str(&bsgrp
->group
, grp_str
, sizeof(grp_str
));
3230 json_object_object_get_ex(json
, grp_str
, &json_group
);
3232 json_group
= json_object_new_object();
3233 json_object_object_add(json
, grp_str
,
3237 vty_out(vty
, "Group Address %pFX\n", &bsgrp
->group
);
3238 vty_out(vty
, "--------------------------\n");
3239 vty_out(vty
, "%-15s %-15s %-15s %-15s\n", "Rp Address",
3240 "priority", "Holdtime", "Hash");
3242 vty_out(vty
, "(ACTIVE)\n");
3245 if (bsgrp
->bsrp_list
) {
3246 for (ALL_LIST_ELEMENTS_RO(bsgrp
->bsrp_list
, rpnode
,
3248 char rp_str
[INET_ADDRSTRLEN
];
3250 pim_inet4_dump("<Rp Address?>",
3251 bsm_rp
->rp_address
, rp_str
,
3255 json_row
= json_object_new_object();
3256 json_object_string_add(
3257 json_row
, "Rp Address", rp_str
);
3258 json_object_int_add(
3259 json_row
, "Rp HoldTime",
3260 bsm_rp
->rp_holdtime
);
3261 json_object_int_add(json_row
,
3264 json_object_int_add(json_row
,
3267 json_object_object_add(
3268 json_group
, rp_str
, json_row
);
3272 "%-15s %-15u %-15u %-15u\n",
3273 rp_str
, bsm_rp
->rp_prio
,
3274 bsm_rp
->rp_holdtime
,
3278 if (!bsgrp
->bsrp_list
->count
&& !uj
)
3279 vty_out(vty
, "Active List is empty.\n");
3283 json_object_int_add(json_group
, "Pending RP count",
3284 bsgrp
->pend_rp_cnt
);
3286 vty_out(vty
, "(PENDING)\n");
3287 vty_out(vty
, "Pending RP count :%d\n",
3288 bsgrp
->pend_rp_cnt
);
3289 if (bsgrp
->pend_rp_cnt
)
3290 vty_out(vty
, "%-15s %-15s %-15s %-15s\n",
3291 "Rp Address", "priority", "Holdtime",
3295 if (bsgrp
->partial_bsrp_list
) {
3296 for (ALL_LIST_ELEMENTS_RO(bsgrp
->partial_bsrp_list
,
3298 char rp_str
[INET_ADDRSTRLEN
];
3300 pim_inet4_dump("<Rp Addr?>", bsm_rp
->rp_address
,
3301 rp_str
, sizeof(rp_str
));
3304 json_row
= json_object_new_object();
3305 json_object_string_add(
3306 json_row
, "Rp Address", rp_str
);
3307 json_object_int_add(
3308 json_row
, "Rp HoldTime",
3309 bsm_rp
->rp_holdtime
);
3310 json_object_int_add(json_row
,
3313 json_object_int_add(json_row
,
3316 json_object_object_add(
3317 json_group
, rp_str
, json_row
);
3320 "%-15s %-15u %-15u %-15u\n",
3321 rp_str
, bsm_rp
->rp_prio
,
3322 bsm_rp
->rp_holdtime
,
3326 if (!bsgrp
->partial_bsrp_list
->count
&& !uj
)
3327 vty_out(vty
, "Partial List is empty\n");
3335 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3336 json
, JSON_C_TO_STRING_PRETTY
));
3337 json_object_free(json
);
3341 /* pim statistics - just adding only bsm related now.
3342 * We can continue to add all pim related stats here.
3344 static void pim_show_statistics(struct pim_instance
*pim
, struct vty
*vty
,
3345 const char *ifname
, bool uj
)
3347 json_object
*json
= NULL
;
3348 struct interface
*ifp
;
3351 json
= json_object_new_object();
3352 json_object_int_add(json
, "bsmRx", pim
->bsm_rcvd
);
3353 json_object_int_add(json
, "bsmTx", pim
->bsm_sent
);
3354 json_object_int_add(json
, "bsmDropped", pim
->bsm_dropped
);
3356 vty_out(vty
, "BSM Statistics :\n");
3357 vty_out(vty
, "----------------\n");
3358 vty_out(vty
, "Number of Received BSMs : %" PRIu64
"\n",
3360 vty_out(vty
, "Number of Forwared BSMs : %" PRIu64
"\n",
3362 vty_out(vty
, "Number of Dropped BSMs : %" PRIu64
"\n",
3368 /* scan interfaces */
3369 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3370 struct pim_interface
*pim_ifp
= ifp
->info
;
3372 if (ifname
&& strcmp(ifname
, ifp
->name
))
3379 vty_out(vty
, "Interface : %s\n", ifp
->name
);
3380 vty_out(vty
, "-------------------\n");
3382 "Number of BSMs dropped due to config miss : %u\n",
3383 pim_ifp
->pim_ifstat_bsm_cfg_miss
);
3384 vty_out(vty
, "Number of unicast BSMs dropped : %u\n",
3385 pim_ifp
->pim_ifstat_ucast_bsm_cfg_miss
);
3387 "Number of BSMs dropped due to invalid scope zone : %u\n",
3388 pim_ifp
->pim_ifstat_bsm_invalid_sz
);
3391 json_object
*json_row
= NULL
;
3393 json_row
= json_object_new_object();
3395 json_object_string_add(json_row
, "If Name", ifp
->name
);
3396 json_object_int_add(json_row
, "bsmDroppedConfig",
3397 pim_ifp
->pim_ifstat_bsm_cfg_miss
);
3398 json_object_int_add(
3399 json_row
, "bsmDroppedUnicast",
3400 pim_ifp
->pim_ifstat_ucast_bsm_cfg_miss
);
3401 json_object_int_add(json_row
,
3402 "bsmDroppedInvalidScopeZone",
3403 pim_ifp
->pim_ifstat_bsm_invalid_sz
);
3404 json_object_object_add(json
, ifp
->name
, json_row
);
3410 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3411 json
, JSON_C_TO_STRING_PRETTY
));
3412 json_object_free(json
);
3416 static void clear_pim_statistics(struct pim_instance
*pim
)
3418 struct interface
*ifp
;
3422 pim
->bsm_dropped
= 0;
3424 /* scan interfaces */
3425 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3426 struct pim_interface
*pim_ifp
= ifp
->info
;
3431 pim_ifp
->pim_ifstat_bsm_cfg_miss
= 0;
3432 pim_ifp
->pim_ifstat_ucast_bsm_cfg_miss
= 0;
3433 pim_ifp
->pim_ifstat_bsm_invalid_sz
= 0;
3437 static void igmp_show_groups(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
3439 struct interface
*ifp
;
3441 json_object
*json
= NULL
;
3442 json_object
*json_iface
= NULL
;
3443 json_object
*json_group
= NULL
;
3444 json_object
*json_groups
= NULL
;
3446 now
= pim_time_monotonic_sec();
3449 json
= json_object_new_object();
3450 json_object_int_add(json
, "totalGroups", pim
->igmp_group_count
);
3451 json_object_int_add(json
, "watermarkLimit",
3452 pim
->igmp_watermark_limit
);
3454 vty_out(vty
, "Total IGMP groups: %u\n", pim
->igmp_group_count
);
3455 vty_out(vty
, "Watermark warn limit(%s): %u\n",
3456 pim
->igmp_watermark_limit
? "Set" : "Not Set",
3457 pim
->igmp_watermark_limit
);
3459 "Interface Address Group Mode Timer Srcs V Uptime \n");
3462 /* scan interfaces */
3463 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3464 struct pim_interface
*pim_ifp
= ifp
->info
;
3465 struct listnode
*sock_node
;
3466 struct igmp_sock
*igmp
;
3471 /* scan igmp sockets */
3472 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3474 char ifaddr_str
[INET_ADDRSTRLEN
];
3475 struct listnode
*grpnode
;
3476 struct igmp_group
*grp
;
3478 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3479 sizeof(ifaddr_str
));
3481 /* scan igmp groups */
3482 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3484 char group_str
[INET_ADDRSTRLEN
];
3488 pim_inet4_dump("<group?>", grp
->group_addr
,
3489 group_str
, sizeof(group_str
));
3490 pim_time_timer_to_hhmmss(hhmmss
, sizeof(hhmmss
),
3491 grp
->t_group_timer
);
3492 pim_time_uptime(uptime
, sizeof(uptime
),
3493 now
- grp
->group_creation
);
3496 json_object_object_get_ex(
3497 json
, ifp
->name
, &json_iface
);
3501 json_object_new_object();
3502 json_object_pim_ifp_add(
3504 json_object_object_add(
3508 json_object_new_array();
3509 json_object_object_add(
3515 json_group
= json_object_new_object();
3516 json_object_string_add(json_group
,
3519 json_object_string_add(json_group
,
3523 if (grp
->igmp_version
== 3)
3524 json_object_string_add(
3526 grp
->group_filtermode_isexcl
3530 json_object_string_add(json_group
,
3532 json_object_int_add(
3533 json_group
, "sourcesCount",
3534 grp
->group_source_list
3536 grp
->group_source_list
)
3538 json_object_int_add(
3539 json_group
, "version",
3541 json_object_string_add(
3542 json_group
, "uptime", uptime
);
3543 json_object_array_add(json_groups
,
3547 "%-16s %-15s %-15s %4s %8s %4d %d %8s\n",
3548 ifp
->name
, ifaddr_str
,
3550 grp
->igmp_version
== 3
3551 ? (grp
->group_filtermode_isexcl
3556 grp
->group_source_list
3558 grp
->group_source_list
)
3560 grp
->igmp_version
, uptime
);
3562 } /* scan igmp groups */
3563 } /* scan igmp sockets */
3564 } /* scan interfaces */
3567 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3568 json
, JSON_C_TO_STRING_PRETTY
));
3569 json_object_free(json
);
3573 static void igmp_show_group_retransmission(struct pim_instance
*pim
,
3576 struct interface
*ifp
;
3579 "Interface Address Group RetTimer Counter RetSrcs\n");
3581 /* scan interfaces */
3582 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3583 struct pim_interface
*pim_ifp
= ifp
->info
;
3584 struct listnode
*sock_node
;
3585 struct igmp_sock
*igmp
;
3590 /* scan igmp sockets */
3591 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3593 char ifaddr_str
[INET_ADDRSTRLEN
];
3594 struct listnode
*grpnode
;
3595 struct igmp_group
*grp
;
3597 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3598 sizeof(ifaddr_str
));
3600 /* scan igmp groups */
3601 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3603 char group_str
[INET_ADDRSTRLEN
];
3604 char grp_retr_mmss
[10];
3605 struct listnode
*src_node
;
3606 struct igmp_source
*src
;
3607 int grp_retr_sources
= 0;
3609 pim_inet4_dump("<group?>", grp
->group_addr
,
3610 group_str
, sizeof(group_str
));
3611 pim_time_timer_to_mmss(
3612 grp_retr_mmss
, sizeof(grp_retr_mmss
),
3613 grp
->t_group_query_retransmit_timer
);
3616 /* count group sources with retransmission state
3618 for (ALL_LIST_ELEMENTS_RO(
3619 grp
->group_source_list
, src_node
,
3621 if (src
->source_query_retransmit_count
3627 vty_out(vty
, "%-16s %-15s %-15s %-8s %7d %7d\n",
3628 ifp
->name
, ifaddr_str
, group_str
,
3630 grp
->group_specific_query_retransmit_count
,
3633 } /* scan igmp groups */
3634 } /* scan igmp sockets */
3635 } /* scan interfaces */
3638 static void igmp_show_sources(struct pim_instance
*pim
, struct vty
*vty
)
3640 struct interface
*ifp
;
3643 now
= pim_time_monotonic_sec();
3646 "Interface Address Group Source Timer Fwd Uptime \n");
3648 /* scan interfaces */
3649 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3650 struct pim_interface
*pim_ifp
= ifp
->info
;
3651 struct listnode
*sock_node
;
3652 struct igmp_sock
*igmp
;
3657 /* scan igmp sockets */
3658 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3660 char ifaddr_str
[INET_ADDRSTRLEN
];
3661 struct listnode
*grpnode
;
3662 struct igmp_group
*grp
;
3664 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3665 sizeof(ifaddr_str
));
3667 /* scan igmp groups */
3668 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3670 char group_str
[INET_ADDRSTRLEN
];
3671 struct listnode
*srcnode
;
3672 struct igmp_source
*src
;
3674 pim_inet4_dump("<group?>", grp
->group_addr
,
3675 group_str
, sizeof(group_str
));
3677 /* scan group sources */
3678 for (ALL_LIST_ELEMENTS_RO(
3679 grp
->group_source_list
, srcnode
,
3681 char source_str
[INET_ADDRSTRLEN
];
3686 "<source?>", src
->source_addr
,
3687 source_str
, sizeof(source_str
));
3689 pim_time_timer_to_mmss(
3691 src
->t_source_timer
);
3694 uptime
, sizeof(uptime
),
3695 now
- src
->source_creation
);
3698 "%-16s %-15s %-15s %-15s %5s %3s %8s\n",
3699 ifp
->name
, ifaddr_str
,
3700 group_str
, source_str
, mmss
,
3701 IGMP_SOURCE_TEST_FORWARDING(
3707 } /* scan group sources */
3708 } /* scan igmp groups */
3709 } /* scan igmp sockets */
3710 } /* scan interfaces */
3713 static void igmp_show_source_retransmission(struct pim_instance
*pim
,
3716 struct interface
*ifp
;
3719 "Interface Address Group Source Counter\n");
3721 /* scan interfaces */
3722 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3723 struct pim_interface
*pim_ifp
= ifp
->info
;
3724 struct listnode
*sock_node
;
3725 struct igmp_sock
*igmp
;
3730 /* scan igmp sockets */
3731 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3733 char ifaddr_str
[INET_ADDRSTRLEN
];
3734 struct listnode
*grpnode
;
3735 struct igmp_group
*grp
;
3737 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3738 sizeof(ifaddr_str
));
3740 /* scan igmp groups */
3741 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3743 char group_str
[INET_ADDRSTRLEN
];
3744 struct listnode
*srcnode
;
3745 struct igmp_source
*src
;
3747 pim_inet4_dump("<group?>", grp
->group_addr
,
3748 group_str
, sizeof(group_str
));
3750 /* scan group sources */
3751 for (ALL_LIST_ELEMENTS_RO(
3752 grp
->group_source_list
, srcnode
,
3754 char source_str
[INET_ADDRSTRLEN
];
3757 "<source?>", src
->source_addr
,
3758 source_str
, sizeof(source_str
));
3761 "%-16s %-15s %-15s %-15s %7d\n",
3762 ifp
->name
, ifaddr_str
,
3763 group_str
, source_str
,
3764 src
->source_query_retransmit_count
);
3766 } /* scan group sources */
3767 } /* scan igmp groups */
3768 } /* scan igmp sockets */
3769 } /* scan interfaces */
3772 static void pim_show_bsr(struct pim_instance
*pim
,
3777 char last_bsm_seen
[10];
3780 char bsr_str
[PREFIX_STRLEN
];
3781 json_object
*json
= NULL
;
3783 if (pim
->global_scope
.current_bsr
.s_addr
== INADDR_ANY
) {
3784 strlcpy(bsr_str
, "0.0.0.0", sizeof(bsr_str
));
3785 pim_time_uptime(uptime
, sizeof(uptime
),
3786 pim
->global_scope
.current_bsr_first_ts
);
3787 pim_time_uptime(last_bsm_seen
, sizeof(last_bsm_seen
),
3788 pim
->global_scope
.current_bsr_last_ts
);
3792 pim_inet4_dump("<bsr?>", pim
->global_scope
.current_bsr
,
3793 bsr_str
, sizeof(bsr_str
));
3794 now
= pim_time_monotonic_sec();
3795 pim_time_uptime(uptime
, sizeof(uptime
),
3796 (now
- pim
->global_scope
.current_bsr_first_ts
));
3797 pim_time_uptime(last_bsm_seen
, sizeof(last_bsm_seen
),
3798 now
- pim
->global_scope
.current_bsr_last_ts
);
3801 switch (pim
->global_scope
.state
) {
3803 strlcpy(bsr_state
, "NO_INFO", sizeof(bsr_state
));
3806 strlcpy(bsr_state
, "ACCEPT_ANY", sizeof(bsr_state
));
3808 case ACCEPT_PREFERRED
:
3809 strlcpy(bsr_state
, "ACCEPT_PREFERRED", sizeof(bsr_state
));
3812 strlcpy(bsr_state
, "", sizeof(bsr_state
));
3816 json
= json_object_new_object();
3817 json_object_string_add(json
, "bsr", bsr_str
);
3818 json_object_int_add(json
, "priority",
3819 pim
->global_scope
.current_bsr_prio
);
3820 json_object_int_add(json
, "fragmentTag",
3821 pim
->global_scope
.bsm_frag_tag
);
3822 json_object_string_add(json
, "state", bsr_state
);
3823 json_object_string_add(json
, "upTime", uptime
);
3824 json_object_string_add(json
, "lastBsmSeen", last_bsm_seen
);
3828 vty_out(vty
, "PIMv2 Bootstrap information\n");
3829 vty_out(vty
, "Current preferred BSR address: %s\n", bsr_str
);
3831 "Priority Fragment-Tag State UpTime\n");
3832 vty_out(vty
, " %-12d %-12d %-13s %7s\n",
3833 pim
->global_scope
.current_bsr_prio
,
3834 pim
->global_scope
.bsm_frag_tag
,
3837 vty_out(vty
, "Last BSM seen: %s\n", last_bsm_seen
);
3841 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3842 json
, JSON_C_TO_STRING_PRETTY
));
3843 json_object_free(json
);
3847 static void clear_igmp_interfaces(struct pim_instance
*pim
)
3849 struct interface
*ifp
;
3851 FOR_ALL_INTERFACES (pim
->vrf
, ifp
)
3852 pim_if_addr_del_all_igmp(ifp
);
3854 FOR_ALL_INTERFACES (pim
->vrf
, ifp
)
3855 pim_if_addr_add_all(ifp
);
3858 static void clear_pim_interfaces(struct pim_instance
*pim
)
3860 struct interface
*ifp
;
3862 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3864 pim_neighbor_delete_all(ifp
, "interface cleared");
3869 static void clear_interfaces(struct pim_instance
*pim
)
3871 clear_igmp_interfaces(pim
);
3872 clear_pim_interfaces(pim
);
3875 #define PIM_GET_PIM_INTERFACE(pim_ifp, ifp) \
3876 pim_ifp = ifp->info; \
3879 "%% Enable PIM and/or IGMP on this interface first\n"); \
3880 return CMD_WARNING_CONFIG_FAILED; \
3883 DEFUN (clear_ip_interfaces
,
3884 clear_ip_interfaces_cmd
,
3885 "clear ip interfaces [vrf NAME]",
3888 "Reset interfaces\n"
3892 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3897 clear_interfaces(vrf
->info
);
3902 DEFUN (clear_ip_igmp_interfaces
,
3903 clear_ip_igmp_interfaces_cmd
,
3904 "clear ip igmp [vrf NAME] interfaces",
3909 "Reset IGMP interfaces\n")
3912 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3917 clear_igmp_interfaces(vrf
->info
);
3922 DEFUN (clear_ip_pim_statistics
,
3923 clear_ip_pim_statistics_cmd
,
3924 "clear ip pim statistics [vrf NAME]",
3929 "Reset PIM statistics\n")
3932 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3937 clear_pim_statistics(vrf
->info
);
3941 static void clear_mroute(struct pim_instance
*pim
)
3943 struct pim_upstream
*up
;
3944 struct interface
*ifp
;
3946 /* scan interfaces */
3947 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3948 struct pim_interface
*pim_ifp
= ifp
->info
;
3949 struct listnode
*sock_node
;
3950 struct igmp_sock
*igmp
;
3951 struct pim_ifchannel
*ch
;
3956 /* deleting all ifchannels */
3957 while (!RB_EMPTY(pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
)) {
3958 ch
= RB_ROOT(pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
);
3960 pim_ifchannel_delete(ch
);
3963 /* clean up all igmp groups */
3964 /* scan igmp sockets */
3965 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3968 struct igmp_group
*grp
;
3970 if (igmp
->igmp_group_list
) {
3971 while (igmp
->igmp_group_list
->count
) {
3972 grp
= listnode_head(
3973 igmp
->igmp_group_list
);
3974 igmp_group_delete(grp
);
3981 /* clean up all upstreams*/
3982 while ((up
= rb_pim_upstream_first(&pim
->upstream_head
))) {
3983 pim_upstream_del(pim
, up
, __func__
);
3987 DEFUN (clear_ip_mroute
,
3988 clear_ip_mroute_cmd
,
3989 "clear ip mroute [vrf NAME]",
3992 "Reset multicast routes\n"
3996 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4001 clear_mroute(vrf
->info
);
4006 DEFUN (clear_ip_pim_interfaces
,
4007 clear_ip_pim_interfaces_cmd
,
4008 "clear ip pim [vrf NAME] interfaces",
4013 "Reset PIM interfaces\n")
4016 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4021 clear_pim_interfaces(vrf
->info
);
4026 DEFUN (clear_ip_pim_interface_traffic
,
4027 clear_ip_pim_interface_traffic_cmd
,
4028 "clear ip pim [vrf NAME] interface traffic",
4031 "PIM clear commands\n"
4033 "Reset PIM interfaces\n"
4034 "Reset Protocol Packet counters\n")
4037 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4038 struct interface
*ifp
= NULL
;
4039 struct pim_interface
*pim_ifp
= NULL
;
4044 FOR_ALL_INTERFACES (vrf
, ifp
) {
4045 pim_ifp
= ifp
->info
;
4050 pim_ifp
->pim_ifstat_hello_recv
= 0;
4051 pim_ifp
->pim_ifstat_hello_sent
= 0;
4052 pim_ifp
->pim_ifstat_join_recv
= 0;
4053 pim_ifp
->pim_ifstat_join_send
= 0;
4054 pim_ifp
->pim_ifstat_prune_recv
= 0;
4055 pim_ifp
->pim_ifstat_prune_send
= 0;
4056 pim_ifp
->pim_ifstat_reg_recv
= 0;
4057 pim_ifp
->pim_ifstat_reg_send
= 0;
4058 pim_ifp
->pim_ifstat_reg_stop_recv
= 0;
4059 pim_ifp
->pim_ifstat_reg_stop_send
= 0;
4060 pim_ifp
->pim_ifstat_assert_recv
= 0;
4061 pim_ifp
->pim_ifstat_assert_send
= 0;
4062 pim_ifp
->pim_ifstat_bsm_rx
= 0;
4063 pim_ifp
->pim_ifstat_bsm_tx
= 0;
4069 DEFUN (clear_ip_pim_oil
,
4070 clear_ip_pim_oil_cmd
,
4071 "clear ip pim [vrf NAME] oil",
4076 "Rescan PIM OIL (output interface list)\n")
4079 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4084 pim_scan_oil(vrf
->info
);
4089 DEFUN (show_ip_igmp_interface
,
4090 show_ip_igmp_interface_cmd
,
4091 "show ip igmp [vrf NAME] interface [detail|WORD] [json]",
4096 "IGMP interface information\n"
4102 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4103 bool uj
= use_json(argc
, argv
);
4108 if (argv_find(argv
, argc
, "detail", &idx
)
4109 || argv_find(argv
, argc
, "WORD", &idx
))
4110 igmp_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
4112 igmp_show_interfaces(vrf
->info
, vty
, uj
);
4117 DEFUN (show_ip_igmp_interface_vrf_all
,
4118 show_ip_igmp_interface_vrf_all_cmd
,
4119 "show ip igmp vrf all interface [detail|WORD] [json]",
4124 "IGMP interface information\n"
4130 bool uj
= use_json(argc
, argv
);
4136 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4140 vty_out(vty
, " \"%s\": ", vrf
->name
);
4143 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4144 if (argv_find(argv
, argc
, "detail", &idx
)
4145 || argv_find(argv
, argc
, "WORD", &idx
))
4146 igmp_show_interfaces_single(vrf
->info
, vty
,
4147 argv
[idx
]->arg
, uj
);
4149 igmp_show_interfaces(vrf
->info
, vty
, uj
);
4152 vty_out(vty
, "}\n");
4157 DEFUN (show_ip_igmp_join
,
4158 show_ip_igmp_join_cmd
,
4159 "show ip igmp [vrf NAME] join",
4164 "IGMP static join information\n")
4167 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4172 igmp_show_interface_join(vrf
->info
, vty
);
4177 DEFUN (show_ip_igmp_join_vrf_all
,
4178 show_ip_igmp_join_vrf_all_cmd
,
4179 "show ip igmp vrf all join",
4184 "IGMP static join information\n")
4186 bool uj
= use_json(argc
, argv
);
4192 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4196 vty_out(vty
, " \"%s\": ", vrf
->name
);
4199 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4200 igmp_show_interface_join(vrf
->info
, vty
);
4203 vty_out(vty
, "}\n");
4208 DEFUN (show_ip_igmp_groups
,
4209 show_ip_igmp_groups_cmd
,
4210 "show ip igmp [vrf NAME] groups [json]",
4219 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4220 bool uj
= use_json(argc
, argv
);
4225 igmp_show_groups(vrf
->info
, vty
, uj
);
4230 DEFUN (show_ip_igmp_groups_vrf_all
,
4231 show_ip_igmp_groups_vrf_all_cmd
,
4232 "show ip igmp vrf all groups [json]",
4240 bool uj
= use_json(argc
, argv
);
4246 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4250 vty_out(vty
, " \"%s\": ", vrf
->name
);
4253 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4254 igmp_show_groups(vrf
->info
, vty
, uj
);
4257 vty_out(vty
, "}\n");
4262 DEFUN (show_ip_igmp_groups_retransmissions
,
4263 show_ip_igmp_groups_retransmissions_cmd
,
4264 "show ip igmp [vrf NAME] groups retransmissions",
4270 "IGMP group retransmissions\n")
4273 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4278 igmp_show_group_retransmission(vrf
->info
, vty
);
4283 DEFUN (show_ip_igmp_sources
,
4284 show_ip_igmp_sources_cmd
,
4285 "show ip igmp [vrf NAME] sources",
4293 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4298 igmp_show_sources(vrf
->info
, vty
);
4303 DEFUN (show_ip_igmp_sources_retransmissions
,
4304 show_ip_igmp_sources_retransmissions_cmd
,
4305 "show ip igmp [vrf NAME] sources retransmissions",
4311 "IGMP source retransmissions\n")
4314 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4319 igmp_show_source_retransmission(vrf
->info
, vty
);
4324 DEFUN (show_ip_igmp_statistics
,
4325 show_ip_igmp_statistics_cmd
,
4326 "show ip igmp [vrf NAME] statistics [interface WORD] [json]",
4337 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4338 bool uj
= use_json(argc
, argv
);
4343 if (argv_find(argv
, argc
, "WORD", &idx
))
4344 igmp_show_statistics(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
4346 igmp_show_statistics(vrf
->info
, vty
, NULL
, uj
);
4351 DEFUN (show_ip_pim_mlag_summary
,
4352 show_ip_pim_mlag_summary_cmd
,
4353 "show ip pim mlag summary [json]",
4358 "status and stats\n"
4361 bool uj
= use_json(argc
, argv
);
4362 char role_buf
[MLAG_ROLE_STRSIZE
];
4363 char addr_buf
[INET_ADDRSTRLEN
];
4366 json_object
*json
= NULL
;
4367 json_object
*json_stat
= NULL
;
4369 json
= json_object_new_object();
4370 if (router
->mlag_flags
& PIM_MLAGF_LOCAL_CONN_UP
)
4371 json_object_boolean_true_add(json
, "mlagConnUp");
4372 if (router
->mlag_flags
& PIM_MLAGF_PEER_CONN_UP
)
4373 json_object_boolean_true_add(json
, "mlagPeerConnUp");
4374 if (router
->mlag_flags
& PIM_MLAGF_PEER_ZEBRA_UP
)
4375 json_object_boolean_true_add(json
, "mlagPeerZebraUp");
4376 json_object_string_add(json
, "mlagRole",
4377 mlag_role2str(router
->mlag_role
,
4378 role_buf
, sizeof(role_buf
)));
4379 inet_ntop(AF_INET
, &router
->local_vtep_ip
,
4380 addr_buf
, INET_ADDRSTRLEN
);
4381 json_object_string_add(json
, "localVtepIp", addr_buf
);
4382 inet_ntop(AF_INET
, &router
->anycast_vtep_ip
,
4383 addr_buf
, INET_ADDRSTRLEN
);
4384 json_object_string_add(json
, "anycastVtepIp", addr_buf
);
4385 json_object_string_add(json
, "peerlinkRif",
4386 router
->peerlink_rif
);
4388 json_stat
= json_object_new_object();
4389 json_object_int_add(json_stat
, "mlagConnFlaps",
4390 router
->mlag_stats
.mlagd_session_downs
);
4391 json_object_int_add(json_stat
, "mlagPeerConnFlaps",
4392 router
->mlag_stats
.peer_session_downs
);
4393 json_object_int_add(json_stat
, "mlagPeerZebraFlaps",
4394 router
->mlag_stats
.peer_zebra_downs
);
4395 json_object_int_add(json_stat
, "mrouteAddRx",
4396 router
->mlag_stats
.msg
.mroute_add_rx
);
4397 json_object_int_add(json_stat
, "mrouteAddTx",
4398 router
->mlag_stats
.msg
.mroute_add_tx
);
4399 json_object_int_add(json_stat
, "mrouteDelRx",
4400 router
->mlag_stats
.msg
.mroute_del_rx
);
4401 json_object_int_add(json_stat
, "mrouteDelTx",
4402 router
->mlag_stats
.msg
.mroute_del_tx
);
4403 json_object_int_add(json_stat
, "mlagStatusUpdates",
4404 router
->mlag_stats
.msg
.mlag_status_updates
);
4405 json_object_int_add(json_stat
, "peerZebraStatusUpdates",
4406 router
->mlag_stats
.msg
.peer_zebra_status_updates
);
4407 json_object_int_add(json_stat
, "pimStatusUpdates",
4408 router
->mlag_stats
.msg
.pim_status_updates
);
4409 json_object_int_add(json_stat
, "vxlanUpdates",
4410 router
->mlag_stats
.msg
.vxlan_updates
);
4411 json_object_object_add(json
, "connStats", json_stat
);
4413 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4414 json
, JSON_C_TO_STRING_PRETTY
));
4415 json_object_free(json
);
4419 vty_out(vty
, "MLAG daemon connection: %s\n",
4420 (router
->mlag_flags
& PIM_MLAGF_LOCAL_CONN_UP
)
4422 vty_out(vty
, "MLAG peer state: %s\n",
4423 (router
->mlag_flags
& PIM_MLAGF_PEER_CONN_UP
)
4425 vty_out(vty
, "Zebra peer state: %s\n",
4426 (router
->mlag_flags
& PIM_MLAGF_PEER_ZEBRA_UP
)
4428 vty_out(vty
, "MLAG role: %s\n",
4429 mlag_role2str(router
->mlag_role
, role_buf
, sizeof(role_buf
)));
4430 inet_ntop(AF_INET
, &router
->local_vtep_ip
,
4431 addr_buf
, INET_ADDRSTRLEN
);
4432 vty_out(vty
, "Local VTEP IP: %s\n", addr_buf
);
4433 inet_ntop(AF_INET
, &router
->anycast_vtep_ip
,
4434 addr_buf
, INET_ADDRSTRLEN
);
4435 vty_out(vty
, "Anycast VTEP IP: %s\n", addr_buf
);
4436 vty_out(vty
, "Peerlink: %s\n", router
->peerlink_rif
);
4437 vty_out(vty
, "Session flaps: mlagd: %d mlag-peer: %d zebra-peer: %d\n",
4438 router
->mlag_stats
.mlagd_session_downs
,
4439 router
->mlag_stats
.peer_session_downs
,
4440 router
->mlag_stats
.peer_zebra_downs
);
4441 vty_out(vty
, "Message Statistics:\n");
4442 vty_out(vty
, " mroute adds: rx: %d, tx: %d\n",
4443 router
->mlag_stats
.msg
.mroute_add_rx
,
4444 router
->mlag_stats
.msg
.mroute_add_tx
);
4445 vty_out(vty
, " mroute dels: rx: %d, tx: %d\n",
4446 router
->mlag_stats
.msg
.mroute_del_rx
,
4447 router
->mlag_stats
.msg
.mroute_del_tx
);
4448 vty_out(vty
, " peer zebra status updates: %d\n",
4449 router
->mlag_stats
.msg
.peer_zebra_status_updates
);
4450 vty_out(vty
, " PIM status updates: %d\n",
4451 router
->mlag_stats
.msg
.pim_status_updates
);
4452 vty_out(vty
, " VxLAN updates: %d\n",
4453 router
->mlag_stats
.msg
.vxlan_updates
);
4458 DEFUN (show_ip_pim_assert
,
4459 show_ip_pim_assert_cmd
,
4460 "show ip pim [vrf NAME] assert",
4465 "PIM interface assert\n")
4468 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4473 pim_show_assert(vrf
->info
, vty
);
4478 DEFUN (show_ip_pim_assert_internal
,
4479 show_ip_pim_assert_internal_cmd
,
4480 "show ip pim [vrf NAME] assert-internal",
4485 "PIM interface internal assert state\n")
4488 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4493 pim_show_assert_internal(vrf
->info
, vty
);
4498 DEFUN (show_ip_pim_assert_metric
,
4499 show_ip_pim_assert_metric_cmd
,
4500 "show ip pim [vrf NAME] assert-metric",
4505 "PIM interface assert metric\n")
4508 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4513 pim_show_assert_metric(vrf
->info
, vty
);
4518 DEFUN (show_ip_pim_assert_winner_metric
,
4519 show_ip_pim_assert_winner_metric_cmd
,
4520 "show ip pim [vrf NAME] assert-winner-metric",
4525 "PIM interface assert winner metric\n")
4528 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4533 pim_show_assert_winner_metric(vrf
->info
, vty
);
4538 DEFUN (show_ip_pim_interface
,
4539 show_ip_pim_interface_cmd
,
4540 "show ip pim [mlag] [vrf NAME] interface [detail|WORD] [json]",
4546 "PIM interface information\n"
4552 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4553 bool uj
= use_json(argc
, argv
);
4559 if (argv_find(argv
, argc
, "mlag", &idx
))
4562 if (argv_find(argv
, argc
, "WORD", &idx
)
4563 || argv_find(argv
, argc
, "detail", &idx
))
4564 pim_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, mlag
,
4567 pim_show_interfaces(vrf
->info
, vty
, mlag
, uj
);
4572 DEFUN (show_ip_pim_interface_vrf_all
,
4573 show_ip_pim_interface_vrf_all_cmd
,
4574 "show ip pim [mlag] vrf all interface [detail|WORD] [json]",
4580 "PIM interface information\n"
4586 bool uj
= use_json(argc
, argv
);
4591 if (argv_find(argv
, argc
, "mlag", &idx
))
4597 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4601 vty_out(vty
, " \"%s\": ", vrf
->name
);
4604 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4605 if (argv_find(argv
, argc
, "WORD", &idx
)
4606 || argv_find(argv
, argc
, "detail", &idx
))
4607 pim_show_interfaces_single(vrf
->info
, vty
,
4608 argv
[idx
]->arg
, mlag
, uj
);
4610 pim_show_interfaces(vrf
->info
, vty
, mlag
, uj
);
4613 vty_out(vty
, "}\n");
4618 DEFPY (show_ip_pim_join
,
4619 show_ip_pim_join_cmd
,
4620 "show ip pim [vrf NAME] join [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
4625 "PIM interface join information\n"
4626 "The Source or Group\n"
4630 struct prefix_sg sg
= {0};
4633 struct pim_instance
*pim
;
4635 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
4638 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
4641 pim
= pim_get_pim_instance(v
->vrf_id
);
4644 vty_out(vty
, "%% Unable to find pim instance\n");
4648 if (s_or_g
.s_addr
!= 0) {
4649 if (g
.s_addr
!= 0) {
4656 pim_show_join(pim
, vty
, &sg
, uj
);
4661 DEFUN (show_ip_pim_join_vrf_all
,
4662 show_ip_pim_join_vrf_all_cmd
,
4663 "show ip pim vrf all join [json]",
4668 "PIM interface join information\n"
4671 struct prefix_sg sg
= {0};
4672 bool uj
= use_json(argc
, argv
);
4678 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4682 vty_out(vty
, " \"%s\": ", vrf
->name
);
4685 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4686 pim_show_join(vrf
->info
, vty
, &sg
, uj
);
4689 vty_out(vty
, "}\n");
4694 static void pim_show_jp_agg_helper(struct vty
*vty
,
4695 struct interface
*ifp
,
4696 struct pim_neighbor
*neigh
,
4697 struct pim_upstream
*up
,
4700 char src_str
[INET_ADDRSTRLEN
];
4701 char grp_str
[INET_ADDRSTRLEN
];
4702 char rpf_str
[INET_ADDRSTRLEN
];
4704 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
4705 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
4706 /* pius->address.s_addr */
4707 pim_inet4_dump("<rpf?>", neigh
->source_addr
, rpf_str
, sizeof(rpf_str
));
4709 vty_out(vty
, "%-16s %-15s %-15s %-15s %5s\n",
4710 ifp
->name
, rpf_str
, src_str
,
4711 grp_str
, is_join
?"J":"P");
4714 static void pim_show_jp_agg_list(struct pim_instance
*pim
, struct vty
*vty
)
4716 struct interface
*ifp
;
4717 struct pim_interface
*pim_ifp
;
4718 struct listnode
*n_node
;
4719 struct pim_neighbor
*neigh
;
4720 struct listnode
*jag_node
;
4721 struct pim_jp_agg_group
*jag
;
4722 struct listnode
*js_node
;
4723 struct pim_jp_sources
*js
;
4726 "Interface RPF Nbr Source Group State\n");
4728 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
4729 pim_ifp
= ifp
->info
;
4733 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
,
4735 for (ALL_LIST_ELEMENTS_RO(neigh
->upstream_jp_agg
,
4737 for (ALL_LIST_ELEMENTS_RO(jag
->sources
,
4739 pim_show_jp_agg_helper(vty
,
4748 DEFPY (show_ip_pim_jp_agg
,
4749 show_ip_pim_jp_agg_cmd
,
4750 "show ip pim [vrf NAME] jp-agg",
4755 "join prune aggregation list\n")
4758 struct pim_instance
*pim
;
4760 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
4763 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
4766 pim
= pim_get_pim_instance(v
->vrf_id
);
4769 vty_out(vty
, "%% Unable to find pim instance\n");
4773 pim_show_jp_agg_list(pim
, vty
);
4778 DEFUN (show_ip_pim_local_membership
,
4779 show_ip_pim_local_membership_cmd
,
4780 "show ip pim [vrf NAME] local-membership [json]",
4785 "PIM interface local-membership\n"
4789 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4790 bool uj
= use_json(argc
, argv
);
4795 pim_show_membership(vrf
->info
, vty
, uj
);
4800 static void pim_show_mlag_up_entry_detail(struct vrf
*vrf
,
4801 struct vty
*vty
, struct pim_upstream
*up
,
4802 char *src_str
, char *grp_str
, json_object
*json
)
4805 json_object
*json_row
= NULL
;
4806 json_object
*own_list
= NULL
;
4807 json_object
*json_group
= NULL
;
4810 json_object_object_get_ex(json
, grp_str
, &json_group
);
4812 json_group
= json_object_new_object();
4813 json_object_object_add(json
, grp_str
,
4817 json_row
= json_object_new_object();
4818 json_object_string_add(json_row
, "source", src_str
);
4819 json_object_string_add(json_row
, "group", grp_str
);
4821 own_list
= json_object_new_array();
4822 if (pim_up_mlag_is_local(up
))
4823 json_object_array_add(own_list
,
4824 json_object_new_string("local"));
4825 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
))
4826 json_object_array_add(own_list
,
4827 json_object_new_string("peer"));
4828 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE
))
4829 json_object_array_add(
4830 own_list
, json_object_new_string("Interface"));
4831 json_object_object_add(json_row
, "owners", own_list
);
4833 json_object_int_add(json_row
, "localCost",
4834 pim_up_mlag_local_cost(up
));
4835 json_object_int_add(json_row
, "peerCost",
4836 pim_up_mlag_peer_cost(up
));
4837 if (PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up
->flags
))
4838 json_object_boolean_false_add(json_row
, "df");
4840 json_object_boolean_true_add(json_row
, "df");
4841 json_object_object_add(json_group
, src_str
, json_row
);
4846 if (pim_up_mlag_is_local(up
))
4847 strlcat(own_str
, "L", sizeof(own_str
));
4848 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
))
4849 strlcat(own_str
, "P", sizeof(own_str
));
4850 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE
))
4851 strlcat(own_str
, "I", sizeof(own_str
));
4852 /* XXX - fixup, print paragraph output */
4854 "%-15s %-15s %-6s %-11u %-10d %2s\n",
4855 src_str
, grp_str
, own_str
,
4856 pim_up_mlag_local_cost(up
),
4857 pim_up_mlag_peer_cost(up
),
4858 PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up
->flags
)
4863 static void pim_show_mlag_up_detail(struct vrf
*vrf
,
4864 struct vty
*vty
, const char *src_or_group
,
4865 const char *group
, bool uj
)
4867 char src_str
[INET_ADDRSTRLEN
];
4868 char grp_str
[INET_ADDRSTRLEN
];
4869 struct pim_upstream
*up
;
4870 struct pim_instance
*pim
= vrf
->info
;
4871 json_object
*json
= NULL
;
4874 json
= json_object_new_object();
4877 "Source Group Owner Local-cost Peer-cost DF\n");
4879 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
4880 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
)
4881 && !(up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE
)
4882 && !pim_up_mlag_is_local(up
))
4885 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
4886 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
4887 /* XXX: strcmps are clearly inefficient. we should do uint comps
4891 if (strcmp(src_str
, src_or_group
) ||
4892 strcmp(grp_str
, group
))
4895 if (strcmp(src_str
, src_or_group
) &&
4896 strcmp(grp_str
, src_or_group
))
4899 pim_show_mlag_up_entry_detail(vrf
, vty
, up
,
4900 src_str
, grp_str
, json
);
4904 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4905 json
, JSON_C_TO_STRING_PRETTY
));
4906 json_object_free(json
);
4910 static void pim_show_mlag_up_vrf(struct vrf
*vrf
, struct vty
*vty
, bool uj
)
4912 json_object
*json
= NULL
;
4913 json_object
*json_row
;
4914 struct pim_upstream
*up
;
4915 char src_str
[INET_ADDRSTRLEN
];
4916 char grp_str
[INET_ADDRSTRLEN
];
4917 struct pim_instance
*pim
= vrf
->info
;
4918 json_object
*json_group
= NULL
;
4921 json
= json_object_new_object();
4924 "Source Group Owner Local-cost Peer-cost DF\n");
4927 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
4928 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
)
4929 && !(up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE
)
4930 && !pim_up_mlag_is_local(up
))
4932 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
4933 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
4935 json_object
*own_list
= NULL
;
4937 json_object_object_get_ex(json
, grp_str
, &json_group
);
4939 json_group
= json_object_new_object();
4940 json_object_object_add(json
, grp_str
,
4944 json_row
= json_object_new_object();
4945 json_object_string_add(json_row
, "vrf", vrf
->name
);
4946 json_object_string_add(json_row
, "source", src_str
);
4947 json_object_string_add(json_row
, "group", grp_str
);
4949 own_list
= json_object_new_array();
4950 if (pim_up_mlag_is_local(up
)) {
4952 json_object_array_add(own_list
,
4953 json_object_new_string("local"));
4955 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
)) {
4956 json_object_array_add(own_list
,
4957 json_object_new_string("peer"));
4959 json_object_object_add(json_row
, "owners", own_list
);
4961 json_object_int_add(json_row
, "localCost",
4962 pim_up_mlag_local_cost(up
));
4963 json_object_int_add(json_row
, "peerCost",
4964 pim_up_mlag_peer_cost(up
));
4965 if (PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up
->flags
))
4966 json_object_boolean_false_add(json_row
, "df");
4968 json_object_boolean_true_add(json_row
, "df");
4969 json_object_object_add(json_group
, src_str
, json_row
);
4974 if (pim_up_mlag_is_local(up
))
4975 strlcat(own_str
, "L", sizeof(own_str
));
4976 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
))
4977 strlcat(own_str
, "P", sizeof(own_str
));
4978 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE
))
4979 strlcat(own_str
, "I", sizeof(own_str
));
4981 "%-15s %-15s %-6s %-11u %-10u %2s\n",
4982 src_str
, grp_str
, own_str
,
4983 pim_up_mlag_local_cost(up
),
4984 pim_up_mlag_peer_cost(up
),
4985 PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up
->flags
)
4990 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4991 json
, JSON_C_TO_STRING_PRETTY
));
4992 json_object_free(json
);
4996 static void pim_show_mlag_help_string(struct vty
*vty
, bool uj
)
4999 vty_out(vty
, "Owner codes:\n");
5001 "L: EVPN-MLAG Entry, I:PIM-MLAG Entry, P: Peer Entry\n");
5006 DEFUN(show_ip_pim_mlag_up
, show_ip_pim_mlag_up_cmd
,
5007 "show ip pim [vrf NAME] mlag upstream [A.B.C.D [A.B.C.D]] [json]",
5014 "Unicast or Multicast address\n"
5015 "Multicast address\n" JSON_STR
)
5017 const char *src_or_group
= NULL
;
5018 const char *group
= NULL
;
5020 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5021 bool uj
= use_json(argc
, argv
);
5023 if (!vrf
|| !vrf
->info
) {
5024 vty_out(vty
, "%s: VRF or Info missing\n", __func__
);
5031 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
5032 src_or_group
= argv
[idx
]->arg
;
5034 group
= argv
[idx
+ 1]->arg
;
5037 pim_show_mlag_help_string(vty
, uj
);
5040 pim_show_mlag_up_detail(vrf
, vty
, src_or_group
, group
, uj
);
5042 pim_show_mlag_up_vrf(vrf
, vty
, uj
);
5048 DEFUN(show_ip_pim_mlag_up_vrf_all
, show_ip_pim_mlag_up_vrf_all_cmd
,
5049 "show ip pim vrf all mlag upstream [json]",
5050 SHOW_STR IP_STR PIM_STR VRF_CMD_HELP_STR
5052 "upstream\n" JSON_STR
)
5055 bool uj
= use_json(argc
, argv
);
5057 pim_show_mlag_help_string(vty
, uj
);
5058 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5059 pim_show_mlag_up_vrf(vrf
, vty
, uj
);
5065 DEFUN (show_ip_pim_neighbor
,
5066 show_ip_pim_neighbor_cmd
,
5067 "show ip pim [vrf NAME] neighbor [detail|WORD] [json]",
5072 "PIM neighbor information\n"
5074 "Name of interface or neighbor\n"
5078 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5079 bool uj
= use_json(argc
, argv
);
5084 if (argv_find(argv
, argc
, "detail", &idx
)
5085 || argv_find(argv
, argc
, "WORD", &idx
))
5086 pim_show_neighbors_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
5088 pim_show_neighbors(vrf
->info
, vty
, uj
);
5093 DEFUN (show_ip_pim_neighbor_vrf_all
,
5094 show_ip_pim_neighbor_vrf_all_cmd
,
5095 "show ip pim vrf all neighbor [detail|WORD] [json]",
5100 "PIM neighbor information\n"
5102 "Name of interface or neighbor\n"
5106 bool uj
= use_json(argc
, argv
);
5112 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5116 vty_out(vty
, " \"%s\": ", vrf
->name
);
5119 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5120 if (argv_find(argv
, argc
, "detail", &idx
)
5121 || argv_find(argv
, argc
, "WORD", &idx
))
5122 pim_show_neighbors_single(vrf
->info
, vty
,
5123 argv
[idx
]->arg
, uj
);
5125 pim_show_neighbors(vrf
->info
, vty
, uj
);
5128 vty_out(vty
, "}\n");
5133 DEFUN (show_ip_pim_secondary
,
5134 show_ip_pim_secondary_cmd
,
5135 "show ip pim [vrf NAME] secondary",
5140 "PIM neighbor addresses\n")
5143 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5148 pim_show_neighbors_secondary(vrf
->info
, vty
);
5153 DEFUN (show_ip_pim_state
,
5154 show_ip_pim_state_cmd
,
5155 "show ip pim [vrf NAME] state [A.B.C.D [A.B.C.D]] [json]",
5160 "PIM state information\n"
5161 "Unicast or Multicast address\n"
5162 "Multicast address\n"
5165 const char *src_or_group
= NULL
;
5166 const char *group
= NULL
;
5168 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5169 bool uj
= use_json(argc
, argv
);
5177 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
5178 src_or_group
= argv
[idx
]->arg
;
5180 group
= argv
[idx
+ 1]->arg
;
5183 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
5188 DEFUN (show_ip_pim_state_vrf_all
,
5189 show_ip_pim_state_vrf_all_cmd
,
5190 "show ip pim vrf all state [A.B.C.D [A.B.C.D]] [json]",
5195 "PIM state information\n"
5196 "Unicast or Multicast address\n"
5197 "Multicast address\n"
5200 const char *src_or_group
= NULL
;
5201 const char *group
= NULL
;
5203 bool uj
= use_json(argc
, argv
);
5212 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
5213 src_or_group
= argv
[idx
]->arg
;
5215 group
= argv
[idx
+ 1]->arg
;
5218 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5222 vty_out(vty
, " \"%s\": ", vrf
->name
);
5225 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5226 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
5229 vty_out(vty
, "}\n");
5234 DEFPY (show_ip_pim_upstream
,
5235 show_ip_pim_upstream_cmd
,
5236 "show ip pim [vrf NAME] upstream [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
5241 "PIM upstream information\n"
5242 "The Source or Group\n"
5246 struct prefix_sg sg
= {0};
5249 struct pim_instance
*pim
;
5251 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
5254 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
5257 pim
= pim_get_pim_instance(v
->vrf_id
);
5260 vty_out(vty
, "%% Unable to find pim instance\n");
5264 if (s_or_g
.s_addr
!= 0) {
5265 if (g
.s_addr
!= 0) {
5271 pim_show_upstream(pim
, vty
, &sg
, uj
);
5276 DEFUN (show_ip_pim_upstream_vrf_all
,
5277 show_ip_pim_upstream_vrf_all_cmd
,
5278 "show ip pim vrf all upstream [json]",
5283 "PIM upstream information\n"
5286 struct prefix_sg sg
= {0};
5287 bool uj
= use_json(argc
, argv
);
5293 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5297 vty_out(vty
, " \"%s\": ", vrf
->name
);
5300 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5301 pim_show_upstream(vrf
->info
, vty
, &sg
, uj
);
5307 DEFUN (show_ip_pim_channel
,
5308 show_ip_pim_channel_cmd
,
5309 "show ip pim [vrf NAME] channel [json]",
5314 "PIM downstream channel info\n"
5318 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5319 bool uj
= use_json(argc
, argv
);
5324 pim_show_channel(vrf
->info
, vty
, uj
);
5329 DEFUN (show_ip_pim_upstream_join_desired
,
5330 show_ip_pim_upstream_join_desired_cmd
,
5331 "show ip pim [vrf NAME] upstream-join-desired [json]",
5336 "PIM upstream join-desired\n"
5340 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5341 bool uj
= use_json(argc
, argv
);
5346 pim_show_join_desired(vrf
->info
, vty
, uj
);
5351 DEFUN (show_ip_pim_upstream_rpf
,
5352 show_ip_pim_upstream_rpf_cmd
,
5353 "show ip pim [vrf NAME] upstream-rpf [json]",
5358 "PIM upstream source rpf\n"
5362 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5363 bool uj
= use_json(argc
, argv
);
5368 pim_show_upstream_rpf(vrf
->info
, vty
, uj
);
5373 DEFUN (show_ip_pim_rp
,
5375 "show ip pim [vrf NAME] rp-info [json]",
5380 "PIM RP information\n"
5384 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5385 bool uj
= use_json(argc
, argv
);
5390 pim_rp_show_information(vrf
->info
, vty
, uj
);
5395 DEFUN (show_ip_pim_rp_vrf_all
,
5396 show_ip_pim_rp_vrf_all_cmd
,
5397 "show ip pim vrf all rp-info [json]",
5402 "PIM RP information\n"
5405 bool uj
= use_json(argc
, argv
);
5411 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5415 vty_out(vty
, " \"%s\": ", vrf
->name
);
5418 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5419 pim_rp_show_information(vrf
->info
, vty
, uj
);
5422 vty_out(vty
, "}\n");
5427 DEFUN (show_ip_pim_rpf
,
5428 show_ip_pim_rpf_cmd
,
5429 "show ip pim [vrf NAME] rpf [json]",
5434 "PIM cached source rpf information\n"
5438 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5439 bool uj
= use_json(argc
, argv
);
5444 pim_show_rpf(vrf
->info
, vty
, uj
);
5449 DEFUN (show_ip_pim_rpf_vrf_all
,
5450 show_ip_pim_rpf_vrf_all_cmd
,
5451 "show ip pim vrf all rpf [json]",
5456 "PIM cached source rpf information\n"
5459 bool uj
= use_json(argc
, argv
);
5465 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5469 vty_out(vty
, " \"%s\": ", vrf
->name
);
5472 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5473 pim_show_rpf(vrf
->info
, vty
, uj
);
5476 vty_out(vty
, "}\n");
5481 DEFUN (show_ip_pim_nexthop
,
5482 show_ip_pim_nexthop_cmd
,
5483 "show ip pim [vrf NAME] nexthop",
5488 "PIM cached nexthop rpf information\n")
5491 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5496 pim_show_nexthop(vrf
->info
, vty
);
5501 DEFUN (show_ip_pim_nexthop_lookup
,
5502 show_ip_pim_nexthop_lookup_cmd
,
5503 "show ip pim [vrf NAME] nexthop-lookup A.B.C.D A.B.C.D",
5508 "PIM cached nexthop rpf lookup\n"
5509 "Source/RP address\n"
5510 "Multicast Group address\n")
5512 struct prefix nht_p
;
5514 struct in_addr src_addr
, grp_addr
;
5515 struct in_addr vif_source
;
5516 const char *addr_str
, *addr_str1
;
5518 struct pim_nexthop nexthop
;
5519 char nexthop_addr_str
[PREFIX_STRLEN
];
5520 char grp_str
[PREFIX_STRLEN
];
5522 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5527 argv_find(argv
, argc
, "A.B.C.D", &idx
);
5528 addr_str
= argv
[idx
]->arg
;
5529 result
= inet_pton(AF_INET
, addr_str
, &src_addr
);
5531 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
5532 errno
, safe_strerror(errno
));
5536 if (pim_is_group_224_4(src_addr
)) {
5538 "Invalid argument. Expected Valid Source Address.\n");
5542 addr_str1
= argv
[idx
+ 1]->arg
;
5543 result
= inet_pton(AF_INET
, addr_str1
, &grp_addr
);
5545 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
5546 errno
, safe_strerror(errno
));
5550 if (!pim_is_group_224_4(grp_addr
)) {
5552 "Invalid argument. Expected Valid Multicast Group Address.\n");
5556 if (!pim_rp_set_upstream_addr(vrf
->info
, &vif_source
, src_addr
,
5560 nht_p
.family
= AF_INET
;
5561 nht_p
.prefixlen
= IPV4_MAX_BITLEN
;
5562 nht_p
.u
.prefix4
= vif_source
;
5563 grp
.family
= AF_INET
;
5564 grp
.prefixlen
= IPV4_MAX_BITLEN
;
5565 grp
.u
.prefix4
= grp_addr
;
5566 memset(&nexthop
, 0, sizeof(nexthop
));
5568 result
= pim_ecmp_nexthop_lookup(vrf
->info
, &nexthop
, &nht_p
, &grp
, 0);
5572 "Nexthop Lookup failed, no usable routes returned.\n");
5576 pim_addr_dump("<grp?>", &grp
, grp_str
, sizeof(grp_str
));
5577 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
5578 nexthop_addr_str
, sizeof(nexthop_addr_str
));
5579 vty_out(vty
, "Group %s --- Nexthop %s Interface %s \n", grp_str
,
5580 nexthop_addr_str
, nexthop
.interface
->name
);
5585 DEFUN (show_ip_pim_interface_traffic
,
5586 show_ip_pim_interface_traffic_cmd
,
5587 "show ip pim [vrf NAME] interface traffic [WORD] [json]",
5592 "PIM interface information\n"
5593 "Protocol Packet counters\n"
5598 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5599 bool uj
= use_json(argc
, argv
);
5604 if (argv_find(argv
, argc
, "WORD", &idx
))
5605 pim_show_interface_traffic_single(vrf
->info
, vty
,
5606 argv
[idx
]->arg
, uj
);
5608 pim_show_interface_traffic(vrf
->info
, vty
, uj
);
5613 DEFUN (show_ip_pim_bsm_db
,
5614 show_ip_pim_bsm_db_cmd
,
5615 "show ip pim bsm-database [vrf NAME] [json]",
5619 "PIM cached bsm packets information\n"
5624 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5625 bool uj
= use_json(argc
, argv
);
5630 pim_show_bsm_db(vrf
->info
, vty
, uj
);
5634 DEFUN (show_ip_pim_bsrp
,
5635 show_ip_pim_bsrp_cmd
,
5636 "show ip pim bsrp-info [vrf NAME] [json]",
5640 "PIM cached group-rp mappings information\n"
5645 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5646 bool uj
= use_json(argc
, argv
);
5651 pim_show_group_rp_mappings_info(vrf
->info
, vty
, uj
);
5656 DEFUN (show_ip_pim_statistics
,
5657 show_ip_pim_statistics_cmd
,
5658 "show ip pim [vrf NAME] statistics [interface WORD] [json]",
5669 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5670 bool uj
= use_json(argc
, argv
);
5675 if (argv_find(argv
, argc
, "WORD", &idx
))
5676 pim_show_statistics(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
5678 pim_show_statistics(vrf
->info
, vty
, NULL
, uj
);
5683 static void show_multicast_interfaces(struct pim_instance
*pim
, struct vty
*vty
,
5686 struct interface
*ifp
;
5687 char buf
[PREFIX_STRLEN
];
5688 json_object
*json
= NULL
;
5689 json_object
*json_row
= NULL
;
5694 json
= json_object_new_object();
5697 "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut\n");
5699 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
5700 struct pim_interface
*pim_ifp
;
5701 struct in_addr ifaddr
;
5702 struct sioc_vif_req vreq
;
5704 pim_ifp
= ifp
->info
;
5709 memset(&vreq
, 0, sizeof(vreq
));
5710 vreq
.vifi
= pim_ifp
->mroute_vif_index
;
5712 if (ioctl(pim
->mroute_socket
, SIOCGETVIFCNT
, &vreq
)) {
5714 "ioctl(SIOCGETVIFCNT=%lu) failure for interface %s vif_index=%d: errno=%d: %s",
5715 (unsigned long)SIOCGETVIFCNT
, ifp
->name
,
5716 pim_ifp
->mroute_vif_index
, errno
,
5717 safe_strerror(errno
));
5720 ifaddr
= pim_ifp
->primary_address
;
5722 json_row
= json_object_new_object();
5723 json_object_string_add(json_row
, "name", ifp
->name
);
5724 json_object_string_add(json_row
, "state",
5725 if_is_up(ifp
) ? "up" : "down");
5726 json_object_string_add(
5727 json_row
, "address",
5728 inet_ntop(AF_INET
, &pim_ifp
->primary_address
,
5730 json_object_int_add(json_row
, "ifIndex", ifp
->ifindex
);
5731 json_object_int_add(json_row
, "vif",
5732 pim_ifp
->mroute_vif_index
);
5733 json_object_int_add(json_row
, "pktsIn",
5734 (unsigned long)vreq
.icount
);
5735 json_object_int_add(json_row
, "pktsOut",
5736 (unsigned long)vreq
.ocount
);
5737 json_object_int_add(json_row
, "bytesIn",
5738 (unsigned long)vreq
.ibytes
);
5739 json_object_int_add(json_row
, "bytesOut",
5740 (unsigned long)vreq
.obytes
);
5741 json_object_object_add(json
, ifp
->name
, json_row
);
5744 "%-16s %-15s %3d %3d %7lu %7lu %10lu %10lu\n",
5746 inet_ntop(AF_INET
, &ifaddr
, buf
, sizeof(buf
)),
5747 ifp
->ifindex
, pim_ifp
->mroute_vif_index
,
5748 (unsigned long)vreq
.icount
,
5749 (unsigned long)vreq
.ocount
,
5750 (unsigned long)vreq
.ibytes
,
5751 (unsigned long)vreq
.obytes
);
5756 vty_out(vty
, "%s\n",
5757 json_object_to_json_string_ext(
5758 json
, JSON_C_TO_STRING_PRETTY
));
5759 json_object_free(json
);
5763 static void pim_cmd_show_ip_multicast_helper(struct pim_instance
*pim
,
5766 struct vrf
*vrf
= pim
->vrf
;
5767 time_t now
= pim_time_monotonic_sec();
5773 vty_out(vty
, "Router MLAG Role: %s\n",
5774 mlag_role2str(router
->mlag_role
, mlag_role
, sizeof(mlag_role
)));
5775 vty_out(vty
, "Mroute socket descriptor:");
5777 vty_out(vty
, " %d(%s)\n", pim
->mroute_socket
, vrf
->name
);
5779 pim_time_uptime(uptime
, sizeof(uptime
),
5780 now
- pim
->mroute_socket_creation
);
5781 vty_out(vty
, "Mroute socket uptime: %s\n", uptime
);
5785 pim_zebra_zclient_update(vty
);
5786 pim_zlookup_show_ip_multicast(vty
);
5789 vty_out(vty
, "Maximum highest VifIndex: %d\n", PIM_MAX_USABLE_VIFS
);
5792 vty_out(vty
, "Upstream Join Timer: %d secs\n", router
->t_periodic
);
5793 vty_out(vty
, "Join/Prune Holdtime: %d secs\n", PIM_JP_HOLDTIME
);
5794 vty_out(vty
, "PIM ECMP: %s\n", pim
->ecmp_enable
? "Enable" : "Disable");
5795 vty_out(vty
, "PIM ECMP Rebalance: %s\n",
5796 pim
->ecmp_rebalance_enable
? "Enable" : "Disable");
5800 show_rpf_refresh_stats(vty
, pim
, now
, NULL
);
5804 show_scan_oil_stats(pim
, vty
, now
);
5806 show_multicast_interfaces(pim
, vty
, false);
5809 DEFUN (show_ip_multicast
,
5810 show_ip_multicast_cmd
,
5811 "show ip multicast [vrf NAME]",
5815 "Multicast global information\n")
5818 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5823 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
5828 DEFUN (show_ip_multicast_vrf_all
,
5829 show_ip_multicast_vrf_all_cmd
,
5830 "show ip multicast vrf all",
5834 "Multicast global information\n")
5836 bool uj
= use_json(argc
, argv
);
5842 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5846 vty_out(vty
, " \"%s\": ", vrf
->name
);
5849 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5850 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
5853 vty_out(vty
, "}\n");
5858 DEFUN(show_ip_multicast_count
,
5859 show_ip_multicast_count_cmd
,
5860 "show ip multicast count [vrf NAME] [json]",
5862 "Multicast global information\n"
5863 "Data packet count\n"
5864 VRF_CMD_HELP_STR JSON_STR
)
5867 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5868 bool uj
= use_json(argc
, argv
);
5873 show_multicast_interfaces(vrf
->info
, vty
, uj
);
5878 DEFUN(show_ip_multicast_count_vrf_all
,
5879 show_ip_multicast_count_vrf_all_cmd
,
5880 "show ip multicast count vrf all [json]",
5882 "Multicast global information\n"
5883 "Data packet count\n"
5884 VRF_CMD_HELP_STR JSON_STR
)
5886 bool uj
= use_json(argc
, argv
);
5893 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5898 vty_out(vty
, " \"%s\": ", vrf
->name
);
5901 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5903 show_multicast_interfaces(vrf
->info
, vty
, uj
);
5907 vty_out(vty
, "}\n");
5912 static void show_mroute(struct pim_instance
*pim
, struct vty
*vty
,
5913 struct prefix_sg
*sg
, bool fill
, bool uj
)
5915 struct listnode
*node
;
5916 struct channel_oil
*c_oil
;
5917 struct static_route
*s_route
;
5919 json_object
*json
= NULL
;
5920 json_object
*json_group
= NULL
;
5921 json_object
*json_source
= NULL
;
5922 json_object
*json_oil
= NULL
;
5923 json_object
*json_ifp_out
= NULL
;
5926 char grp_str
[INET_ADDRSTRLEN
];
5927 char src_str
[INET_ADDRSTRLEN
];
5928 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
5929 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
5931 struct interface
*ifp_in
;
5933 char state_str
[PIM_REG_STATE_STR_LEN
];
5934 char mroute_uptime
[10];
5937 json
= json_object_new_object();
5939 vty_out(vty
, "IP Multicast Routing Table\n");
5940 vty_out(vty
, "Flags: S - Sparse, C - Connected, P - Pruned\n");
5942 " R - RP-bit set, F - Register flag, T - SPT-bit set\n");
5944 "\nSource Group Flags Proto Input Output TTL Uptime\n");
5947 now
= pim_time_monotonic_sec();
5949 /* print list of PIM and IGMP routes */
5950 frr_each (rb_pim_oil
, &pim
->channel_oil_head
, c_oil
) {
5953 if (!c_oil
->installed
)
5956 if (sg
->grp
.s_addr
!= 0 &&
5957 sg
->grp
.s_addr
!= c_oil
->oil
.mfcc_mcastgrp
.s_addr
)
5959 if (sg
->src
.s_addr
!= 0 &&
5960 sg
->src
.s_addr
!= c_oil
->oil
.mfcc_origin
.s_addr
)
5963 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
5965 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
5968 strlcpy(state_str
, "S", sizeof(state_str
));
5969 /* When a non DR receives a igmp join, it creates a (*,G)
5970 * channel_oil without any upstream creation */
5972 if (PIM_UPSTREAM_FLAG_TEST_SRC_IGMP(c_oil
->up
->flags
))
5973 strlcat(state_str
, "C", sizeof(state_str
));
5974 if (pim_upstream_is_sg_rpt(c_oil
->up
))
5975 strlcat(state_str
, "R", sizeof(state_str
));
5976 if (PIM_UPSTREAM_FLAG_TEST_FHR(c_oil
->up
->flags
))
5977 strlcat(state_str
, "F", sizeof(state_str
));
5978 if (c_oil
->up
->sptbit
== PIM_UPSTREAM_SPTBIT_TRUE
)
5979 strlcat(state_str
, "T", sizeof(state_str
));
5981 if (pim_channel_oil_empty(c_oil
))
5982 strlcat(state_str
, "P", sizeof(state_str
));
5984 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
5987 strlcpy(in_ifname
, ifp_in
->name
, sizeof(in_ifname
));
5989 strlcpy(in_ifname
, "<iif?>", sizeof(in_ifname
));
5992 pim_time_uptime(mroute_uptime
, sizeof(mroute_uptime
),
5993 now
- c_oil
->mroute_creation
);
5997 /* Find the group, create it if it doesn't exist */
5998 json_object_object_get_ex(json
, grp_str
, &json_group
);
6001 json_group
= json_object_new_object();
6002 json_object_object_add(json
, grp_str
,
6006 /* Find the source nested under the group, create it if
6009 json_object_object_get_ex(json_group
, src_str
,
6013 json_source
= json_object_new_object();
6014 json_object_object_add(json_group
, src_str
,
6018 /* Find the inbound interface nested under the source,
6019 * create it if it doesn't exist */
6020 json_object_int_add(json_source
, "installed",
6022 json_object_int_add(json_source
, "refCount",
6023 c_oil
->oil_ref_count
);
6024 json_object_int_add(json_source
, "oilSize",
6026 json_object_int_add(json_source
, "OilInheritedRescan",
6027 c_oil
->oil_inherited_rescan
);
6028 json_object_string_add(json_source
, "iif", in_ifname
);
6029 json_object_string_add(json_source
, "upTime",
6034 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
6036 struct interface
*ifp_out
;
6039 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
6043 /* do not display muted OIFs */
6044 if (c_oil
->oif_flags
[oif_vif_index
]
6045 & PIM_OIF_FLAG_MUTE
)
6048 if (c_oil
->oil
.mfcc_parent
== oif_vif_index
&&
6049 !pim_mroute_allow_iif_in_oil(c_oil
,
6053 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
6057 strlcpy(out_ifname
, ifp_out
->name
, sizeof(out_ifname
));
6059 strlcpy(out_ifname
, "<oif?>", sizeof(out_ifname
));
6062 json_ifp_out
= json_object_new_object();
6063 json_object_string_add(json_ifp_out
, "source",
6065 json_object_string_add(json_ifp_out
, "group",
6068 if (c_oil
->oif_flags
[oif_vif_index
]
6069 & PIM_OIF_FLAG_PROTO_PIM
)
6070 json_object_boolean_true_add(
6071 json_ifp_out
, "protocolPim");
6073 if (c_oil
->oif_flags
[oif_vif_index
]
6074 & PIM_OIF_FLAG_PROTO_IGMP
)
6075 json_object_boolean_true_add(
6076 json_ifp_out
, "protocolIgmp");
6078 if (c_oil
->oif_flags
[oif_vif_index
]
6079 & PIM_OIF_FLAG_PROTO_VXLAN
)
6080 json_object_boolean_true_add(
6081 json_ifp_out
, "protocolVxlan");
6083 if (c_oil
->oif_flags
[oif_vif_index
]
6084 & PIM_OIF_FLAG_PROTO_STAR
)
6085 json_object_boolean_true_add(
6087 "protocolInherited");
6089 json_object_string_add(json_ifp_out
,
6092 json_object_int_add(json_ifp_out
, "iVifI",
6093 c_oil
->oil
.mfcc_parent
);
6094 json_object_string_add(json_ifp_out
,
6095 "outboundInterface",
6097 json_object_int_add(json_ifp_out
, "oVifI",
6099 json_object_int_add(json_ifp_out
, "ttl", ttl
);
6100 json_object_string_add(json_ifp_out
, "upTime",
6102 json_object_string_add(json_source
, "flags",
6105 json_oil
= json_object_new_object();
6106 json_object_object_add(json_source
,
6109 json_object_object_add(json_oil
, out_ifname
,
6112 if (c_oil
->oif_flags
[oif_vif_index
]
6113 & PIM_OIF_FLAG_PROTO_PIM
) {
6114 strlcpy(proto
, "PIM", sizeof(proto
));
6117 if (c_oil
->oif_flags
[oif_vif_index
]
6118 & PIM_OIF_FLAG_PROTO_IGMP
) {
6119 strlcpy(proto
, "IGMP", sizeof(proto
));
6122 if (c_oil
->oif_flags
[oif_vif_index
]
6123 & PIM_OIF_FLAG_PROTO_VXLAN
) {
6124 strlcpy(proto
, "VxLAN", sizeof(proto
));
6127 if (c_oil
->oif_flags
[oif_vif_index
]
6128 & PIM_OIF_FLAG_PROTO_STAR
) {
6129 strlcpy(proto
, "STAR", sizeof(proto
));
6133 "%-15s %-15s %-15s %-6s %-16s %-16s %-3d %8s\n",
6134 src_str
, grp_str
, state_str
, proto
,
6135 in_ifname
, out_ifname
, ttl
,
6141 in_ifname
[0] = '\0';
6142 state_str
[0] = '\0';
6143 mroute_uptime
[0] = '\0';
6149 if (!uj
&& !found_oif
) {
6151 "%-15s %-15s %-15s %-6s %-16s %-16s %-3d %8s\n",
6152 src_str
, grp_str
, state_str
, "none", in_ifname
,
6153 "none", 0, "--:--:--");
6157 /* Print list of static routes */
6158 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
6161 if (!s_route
->c_oil
.installed
)
6164 pim_inet4_dump("<group?>", s_route
->group
, grp_str
,
6166 pim_inet4_dump("<source?>", s_route
->source
, src_str
,
6168 ifp_in
= pim_if_find_by_vif_index(pim
, s_route
->iif
);
6172 strlcpy(in_ifname
, ifp_in
->name
, sizeof(in_ifname
));
6174 strlcpy(in_ifname
, "<iif?>", sizeof(in_ifname
));
6178 /* Find the group, create it if it doesn't exist */
6179 json_object_object_get_ex(json
, grp_str
, &json_group
);
6182 json_group
= json_object_new_object();
6183 json_object_object_add(json
, grp_str
,
6187 /* Find the source nested under the group, create it if
6188 * it doesn't exist */
6189 json_object_object_get_ex(json_group
, src_str
,
6193 json_source
= json_object_new_object();
6194 json_object_object_add(json_group
, src_str
,
6198 json_object_string_add(json_source
, "iif", in_ifname
);
6201 strlcpy(proto
, "STATIC", sizeof(proto
));
6204 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
6206 struct interface
*ifp_out
;
6207 char oif_uptime
[10];
6210 ttl
= s_route
->oif_ttls
[oif_vif_index
];
6214 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
6216 oif_uptime
, sizeof(oif_uptime
),
6219 .oif_creation
[oif_vif_index
]);
6223 strlcpy(out_ifname
, ifp_out
->name
, sizeof(out_ifname
));
6225 strlcpy(out_ifname
, "<oif?>", sizeof(out_ifname
));
6228 json_ifp_out
= json_object_new_object();
6229 json_object_string_add(json_ifp_out
, "source",
6231 json_object_string_add(json_ifp_out
, "group",
6233 json_object_boolean_true_add(json_ifp_out
,
6235 json_object_string_add(json_ifp_out
,
6238 json_object_int_add(
6239 json_ifp_out
, "iVifI",
6240 s_route
->c_oil
.oil
.mfcc_parent
);
6241 json_object_string_add(json_ifp_out
,
6242 "outboundInterface",
6244 json_object_int_add(json_ifp_out
, "oVifI",
6246 json_object_int_add(json_ifp_out
, "ttl", ttl
);
6247 json_object_string_add(json_ifp_out
, "upTime",
6250 json_oil
= json_object_new_object();
6251 json_object_object_add(json_source
,
6254 json_object_object_add(json_oil
, out_ifname
,
6258 "%-15s %-15s %-6s %-16s %-16s %-3d %8s %s\n",
6259 src_str
, grp_str
, proto
, in_ifname
,
6260 out_ifname
, ttl
, oif_uptime
,
6262 if (first
&& !fill
) {
6265 in_ifname
[0] = '\0';
6271 if (!uj
&& !found_oif
) {
6273 "%-15s %-15s %-6s %-16s %-16s %-3d %8s %s\n",
6274 src_str
, grp_str
, proto
, in_ifname
, "none", 0,
6275 "--:--:--", pim
->vrf
->name
);
6280 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
6281 json
, JSON_C_TO_STRING_PRETTY
));
6282 json_object_free(json
);
6286 DEFPY (show_ip_mroute
,
6288 "show ip mroute [vrf NAME] [A.B.C.D$s_or_g [A.B.C.D$g]] [fill$fill] [json$json]",
6293 "The Source or Group\n"
6295 "Fill in Assumed data\n"
6298 struct prefix_sg sg
= {0};
6299 struct pim_instance
*pim
;
6302 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
6305 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
6308 pim
= pim_get_pim_instance(v
->vrf_id
);
6311 vty_out(vty
, "%% Unable to find pim instance\n");
6315 if (s_or_g
.s_addr
!= 0) {
6316 if (g
.s_addr
!= 0) {
6322 show_mroute(pim
, vty
, &sg
, !!fill
, !!json
);
6326 DEFUN (show_ip_mroute_vrf_all
,
6327 show_ip_mroute_vrf_all_cmd
,
6328 "show ip mroute vrf all [fill] [json]",
6333 "Fill in Assumed data\n"
6336 struct prefix_sg sg
= {0};
6337 bool uj
= use_json(argc
, argv
);
6343 if (argv_find(argv
, argc
, "fill", &idx
))
6348 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
6352 vty_out(vty
, " \"%s\": ", vrf
->name
);
6355 vty_out(vty
, "VRF: %s\n", vrf
->name
);
6356 show_mroute(vrf
->info
, vty
, &sg
, fill
, uj
);
6359 vty_out(vty
, "}\n");
6364 DEFUN (clear_ip_mroute_count
,
6365 clear_ip_mroute_count_cmd
,
6366 "clear ip mroute [vrf NAME] count",
6371 "Route and packet count data\n")
6374 struct listnode
*node
;
6375 struct channel_oil
*c_oil
;
6376 struct static_route
*sr
;
6377 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6378 struct pim_instance
*pim
;
6384 frr_each(rb_pim_oil
, &pim
->channel_oil_head
, c_oil
) {
6385 if (!c_oil
->installed
)
6388 pim_mroute_update_counters(c_oil
);
6389 c_oil
->cc
.origpktcnt
= c_oil
->cc
.pktcnt
;
6390 c_oil
->cc
.origbytecnt
= c_oil
->cc
.bytecnt
;
6391 c_oil
->cc
.origwrong_if
= c_oil
->cc
.wrong_if
;
6394 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, sr
)) {
6395 if (!sr
->c_oil
.installed
)
6398 pim_mroute_update_counters(&sr
->c_oil
);
6400 sr
->c_oil
.cc
.origpktcnt
= sr
->c_oil
.cc
.pktcnt
;
6401 sr
->c_oil
.cc
.origbytecnt
= sr
->c_oil
.cc
.bytecnt
;
6402 sr
->c_oil
.cc
.origwrong_if
= sr
->c_oil
.cc
.wrong_if
;
6407 static void show_mroute_count_per_channel_oil(struct channel_oil
*c_oil
,
6411 char group_str
[INET_ADDRSTRLEN
];
6412 char source_str
[INET_ADDRSTRLEN
];
6413 json_object
*json_group
= NULL
;
6414 json_object
*json_source
= NULL
;
6416 if (!c_oil
->installed
)
6419 pim_mroute_update_counters(c_oil
);
6421 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, group_str
,
6423 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, source_str
,
6424 sizeof(source_str
));
6427 json_object_object_get_ex(json
, group_str
, &json_group
);
6430 json_group
= json_object_new_object();
6431 json_object_object_add(json
, group_str
, json_group
);
6434 json_source
= json_object_new_object();
6435 json_object_object_add(json_group
, source_str
, json_source
);
6436 json_object_int_add(json_source
, "lastUsed",
6437 c_oil
->cc
.lastused
/ 100);
6438 json_object_int_add(json_source
, "packets", c_oil
->cc
.pktcnt
);
6439 json_object_int_add(json_source
, "bytes", c_oil
->cc
.bytecnt
);
6440 json_object_int_add(json_source
, "wrongIf", c_oil
->cc
.wrong_if
);
6443 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
6444 source_str
, group_str
, c_oil
->cc
.lastused
/ 100,
6445 c_oil
->cc
.pktcnt
- c_oil
->cc
.origpktcnt
,
6446 c_oil
->cc
.bytecnt
- c_oil
->cc
.origbytecnt
,
6447 c_oil
->cc
.wrong_if
- c_oil
->cc
.origwrong_if
);
6451 static void show_mroute_count(struct pim_instance
*pim
, struct vty
*vty
,
6454 struct listnode
*node
;
6455 struct channel_oil
*c_oil
;
6456 struct static_route
*sr
;
6457 json_object
*json
= NULL
;
6460 json
= json_object_new_object();
6465 "Source Group LastUsed Packets Bytes WrongIf \n");
6468 /* Print PIM and IGMP route counts */
6469 frr_each (rb_pim_oil
, &pim
->channel_oil_head
, c_oil
)
6470 show_mroute_count_per_channel_oil(c_oil
, json
, vty
);
6472 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, sr
))
6473 show_mroute_count_per_channel_oil(&sr
->c_oil
, json
, vty
);
6476 vty_out(vty
, "%s\n",
6477 json_object_to_json_string_ext(
6478 json
, JSON_C_TO_STRING_PRETTY
));
6479 json_object_free(json
);
6483 DEFUN (show_ip_mroute_count
,
6484 show_ip_mroute_count_cmd
,
6485 "show ip mroute [vrf NAME] count [json]",
6490 "Route and packet count data\n"
6494 bool uj
= use_json(argc
, argv
);
6495 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6500 show_mroute_count(vrf
->info
, vty
, uj
);
6504 DEFUN (show_ip_mroute_count_vrf_all
,
6505 show_ip_mroute_count_vrf_all_cmd
,
6506 "show ip mroute vrf all count [json]",
6511 "Route and packet count data\n"
6514 bool uj
= use_json(argc
, argv
);
6520 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
6524 vty_out(vty
, " \"%s\": ", vrf
->name
);
6527 vty_out(vty
, "VRF: %s\n", vrf
->name
);
6528 show_mroute_count(vrf
->info
, vty
, uj
);
6531 vty_out(vty
, "}\n");
6536 static void show_mroute_summary(struct pim_instance
*pim
, struct vty
*vty
,
6539 struct listnode
*node
;
6540 struct channel_oil
*c_oil
;
6541 struct static_route
*s_route
;
6542 uint32_t starg_sw_mroute_cnt
= 0;
6543 uint32_t sg_sw_mroute_cnt
= 0;
6544 uint32_t starg_hw_mroute_cnt
= 0;
6545 uint32_t sg_hw_mroute_cnt
= 0;
6546 json_object
*json_starg
= NULL
;
6547 json_object
*json_sg
= NULL
;
6550 vty_out(vty
, "Mroute Type Installed/Total\n");
6552 frr_each (rb_pim_oil
, &pim
->channel_oil_head
, c_oil
) {
6553 if (!c_oil
->installed
) {
6554 if (c_oil
->oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
6555 starg_sw_mroute_cnt
++;
6559 if (c_oil
->oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
6560 starg_hw_mroute_cnt
++;
6566 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
6567 if (!s_route
->c_oil
.installed
) {
6568 if (s_route
->c_oil
.oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
6569 starg_sw_mroute_cnt
++;
6573 if (s_route
->c_oil
.oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
6574 starg_hw_mroute_cnt
++;
6581 vty_out(vty
, "%-20s %u/%u\n", "(*, G)", starg_hw_mroute_cnt
,
6582 starg_sw_mroute_cnt
+ starg_hw_mroute_cnt
);
6583 vty_out(vty
, "%-20s %u/%u\n", "(S, G)", sg_hw_mroute_cnt
,
6584 sg_sw_mroute_cnt
+ sg_hw_mroute_cnt
);
6585 vty_out(vty
, "------\n");
6586 vty_out(vty
, "%-20s %u/%u\n", "Total",
6587 (starg_hw_mroute_cnt
+ sg_hw_mroute_cnt
),
6588 (starg_sw_mroute_cnt
+ starg_hw_mroute_cnt
6589 + sg_sw_mroute_cnt
+ sg_hw_mroute_cnt
));
6591 /* (*,G) route details */
6592 json_starg
= json_object_new_object();
6593 json_object_object_add(json
, "wildcardGroup", json_starg
);
6595 json_object_int_add(json_starg
, "installed",
6596 starg_hw_mroute_cnt
);
6597 json_object_int_add(json_starg
, "total",
6598 starg_sw_mroute_cnt
+ starg_hw_mroute_cnt
);
6600 /* (S, G) route details */
6601 json_sg
= json_object_new_object();
6602 json_object_object_add(json
, "sourceGroup", json_sg
);
6604 json_object_int_add(json_sg
, "installed", sg_hw_mroute_cnt
);
6605 json_object_int_add(json_sg
, "total",
6606 sg_sw_mroute_cnt
+ sg_hw_mroute_cnt
);
6608 json_object_int_add(json
, "totalNumOfInstalledMroutes",
6609 starg_hw_mroute_cnt
+ sg_hw_mroute_cnt
);
6610 json_object_int_add(json
, "totalNumOfMroutes",
6611 starg_sw_mroute_cnt
+ starg_hw_mroute_cnt
6613 + sg_hw_mroute_cnt
);
6617 DEFUN (show_ip_mroute_summary
,
6618 show_ip_mroute_summary_cmd
,
6619 "show ip mroute [vrf NAME] summary [json]",
6624 "Summary of all mroutes\n"
6628 bool uj
= use_json(argc
, argv
);
6629 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6630 json_object
*json
= NULL
;
6633 json
= json_object_new_object();
6638 show_mroute_summary(vrf
->info
, vty
, json
);
6641 vty_out(vty
, "%s\n",
6642 json_object_to_json_string_ext(
6643 json
, JSON_C_TO_STRING_PRETTY
));
6644 json_object_free(json
);
6649 DEFUN (show_ip_mroute_summary_vrf_all
,
6650 show_ip_mroute_summary_vrf_all_cmd
,
6651 "show ip mroute vrf all summary [json]",
6656 "Summary of all mroutes\n"
6660 bool uj
= use_json(argc
, argv
);
6661 json_object
*json
= NULL
;
6662 json_object
*json_vrf
= NULL
;
6665 json
= json_object_new_object();
6667 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
6669 json_vrf
= json_object_new_object();
6671 vty_out(vty
, "VRF: %s\n", vrf
->name
);
6673 show_mroute_summary(vrf
->info
, vty
, json_vrf
);
6676 json_object_object_add(json
, vrf
->name
, json_vrf
);
6680 vty_out(vty
, "%s\n",
6681 json_object_to_json_string_ext(
6682 json
, JSON_C_TO_STRING_PRETTY
));
6683 json_object_free(json
);
6691 "show ip rib [vrf NAME] A.B.C.D",
6696 "Unicast address\n")
6699 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6700 struct in_addr addr
;
6701 const char *addr_str
;
6702 struct pim_nexthop nexthop
;
6703 char nexthop_addr_str
[PREFIX_STRLEN
];
6709 memset(&nexthop
, 0, sizeof(nexthop
));
6710 argv_find(argv
, argc
, "A.B.C.D", &idx
);
6711 addr_str
= argv
[idx
]->arg
;
6712 result
= inet_pton(AF_INET
, addr_str
, &addr
);
6714 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
6715 errno
, safe_strerror(errno
));
6719 if (!pim_nexthop_lookup(vrf
->info
, &nexthop
, addr
, 0)) {
6721 "Failure querying RIB nexthop for unicast address %s\n",
6727 "Address NextHop Interface Metric Preference\n");
6729 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
6730 nexthop_addr_str
, sizeof(nexthop_addr_str
));
6732 vty_out(vty
, "%-15s %-15s %-9s %6d %10d\n", addr_str
, nexthop_addr_str
,
6733 nexthop
.interface
? nexthop
.interface
->name
: "<ifname?>",
6734 nexthop
.mrib_route_metric
, nexthop
.mrib_metric_preference
);
6739 static void show_ssmpingd(struct pim_instance
*pim
, struct vty
*vty
)
6741 struct listnode
*node
;
6742 struct ssmpingd_sock
*ss
;
6746 "Source Socket Address Port Uptime Requests\n");
6748 if (!pim
->ssmpingd_list
)
6751 now
= pim_time_monotonic_sec();
6753 for (ALL_LIST_ELEMENTS_RO(pim
->ssmpingd_list
, node
, ss
)) {
6754 char source_str
[INET_ADDRSTRLEN
];
6756 struct sockaddr_in bind_addr
;
6757 socklen_t len
= sizeof(bind_addr
);
6758 char bind_addr_str
[INET_ADDRSTRLEN
];
6760 pim_inet4_dump("<src?>", ss
->source_addr
, source_str
,
6761 sizeof(source_str
));
6763 if (pim_socket_getsockname(
6764 ss
->sock_fd
, (struct sockaddr
*)&bind_addr
, &len
)) {
6766 "%% Failure reading socket name for ssmpingd source %s on fd=%d\n",
6767 source_str
, ss
->sock_fd
);
6770 pim_inet4_dump("<addr?>", bind_addr
.sin_addr
, bind_addr_str
,
6771 sizeof(bind_addr_str
));
6772 pim_time_uptime(ss_uptime
, sizeof(ss_uptime
),
6773 now
- ss
->creation
);
6775 vty_out(vty
, "%-15s %6d %-15s %5d %8s %8lld\n", source_str
,
6776 ss
->sock_fd
, bind_addr_str
, ntohs(bind_addr
.sin_port
),
6777 ss_uptime
, (long long)ss
->requests
);
6781 DEFUN (show_ip_ssmpingd
,
6782 show_ip_ssmpingd_cmd
,
6783 "show ip ssmpingd [vrf NAME]",
6790 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6795 show_ssmpingd(vrf
->info
, vty
);
6799 static int pim_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
6800 const char *rp
, const char *group
,
6805 result
= pim_rp_new_config(pim
, rp
, group
, plist
);
6807 if (result
== PIM_GROUP_BAD_ADDR_MASK_COMBO
) {
6808 vty_out(vty
, "%% Inconsistent address and mask: %s\n",
6809 group
? group
: "No Group Address");
6810 return CMD_WARNING_CONFIG_FAILED
;
6813 if (result
== PIM_GROUP_BAD_ADDRESS
) {
6814 vty_out(vty
, "%% Bad group address specified: %s\n",
6815 group
? group
: "No Group Address");
6816 return CMD_WARNING_CONFIG_FAILED
;
6819 if (result
== PIM_RP_BAD_ADDRESS
) {
6820 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
6821 return CMD_WARNING_CONFIG_FAILED
;
6824 if (result
== PIM_RP_NO_PATH
) {
6825 vty_out(vty
, "%% No Path to RP address specified: %s\n", rp
);
6829 if (result
== PIM_GROUP_OVERLAP
) {
6831 "%% Group range specified cannot exact match another\n");
6832 return CMD_WARNING_CONFIG_FAILED
;
6835 if (result
== PIM_GROUP_PFXLIST_OVERLAP
) {
6837 "%% This group is already covered by a RP prefix-list\n");
6838 return CMD_WARNING_CONFIG_FAILED
;
6841 if (result
== PIM_RP_PFXLIST_IN_USE
) {
6843 "%% The same prefix-list cannot be applied to multiple RPs\n");
6844 return CMD_WARNING_CONFIG_FAILED
;
6850 static int pim_cmd_spt_switchover(struct pim_instance
*pim
,
6851 enum pim_spt_switchover spt
,
6854 pim
->spt
.switchover
= spt
;
6856 switch (pim
->spt
.switchover
) {
6857 case PIM_SPT_IMMEDIATE
:
6858 XFREE(MTYPE_PIM_PLIST_NAME
, pim
->spt
.plist
);
6860 pim_upstream_add_lhr_star_pimreg(pim
);
6862 case PIM_SPT_INFINITY
:
6863 pim_upstream_remove_lhr_star_pimreg(pim
, plist
);
6865 XFREE(MTYPE_PIM_PLIST_NAME
, pim
->spt
.plist
);
6869 XSTRDUP(MTYPE_PIM_PLIST_NAME
, plist
);
6876 DEFUN (ip_pim_spt_switchover_infinity
,
6877 ip_pim_spt_switchover_infinity_cmd
,
6878 "ip pim spt-switchover infinity-and-beyond",
6882 "Never switch to SPT Tree\n")
6884 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6885 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, NULL
);
6888 DEFUN (ip_pim_spt_switchover_infinity_plist
,
6889 ip_pim_spt_switchover_infinity_plist_cmd
,
6890 "ip pim spt-switchover infinity-and-beyond prefix-list WORD",
6894 "Never switch to SPT Tree\n"
6895 "Prefix-List to control which groups to switch\n"
6896 "Prefix-List name\n")
6898 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6899 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, argv
[5]->arg
);
6902 DEFUN (no_ip_pim_spt_switchover_infinity
,
6903 no_ip_pim_spt_switchover_infinity_cmd
,
6904 "no ip pim spt-switchover infinity-and-beyond",
6909 "Never switch to SPT Tree\n")
6911 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6912 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
6915 DEFUN (no_ip_pim_spt_switchover_infinity_plist
,
6916 no_ip_pim_spt_switchover_infinity_plist_cmd
,
6917 "no ip pim spt-switchover infinity-and-beyond prefix-list WORD",
6922 "Never switch to SPT Tree\n"
6923 "Prefix-List to control which groups to switch\n"
6924 "Prefix-List name\n")
6926 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6927 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
6930 DEFPY (pim_register_accept_list
,
6931 pim_register_accept_list_cmd
,
6932 "[no] ip pim register-accept-list WORD$word",
6936 "Only accept registers from a specific source prefix list\n"
6937 "Prefix-List name\n")
6939 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6942 XFREE(MTYPE_PIM_PLIST_NAME
, pim
->register_plist
);
6944 XFREE(MTYPE_PIM_PLIST_NAME
, pim
->register_plist
);
6945 pim
->register_plist
= XSTRDUP(MTYPE_PIM_PLIST_NAME
, word
);
6950 DEFUN (ip_pim_joinprune_time
,
6951 ip_pim_joinprune_time_cmd
,
6952 "ip pim join-prune-interval (60-600)",
6954 "pim multicast routing\n"
6955 "Join Prune Send Interval\n"
6958 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6959 router
->t_periodic
= atoi(argv
[3]->arg
);
6963 DEFUN (no_ip_pim_joinprune_time
,
6964 no_ip_pim_joinprune_time_cmd
,
6965 "no ip pim join-prune-interval (60-600)",
6968 "pim multicast routing\n"
6969 "Join Prune Send Interval\n"
6972 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6973 router
->t_periodic
= PIM_DEFAULT_T_PERIODIC
;
6977 DEFUN (ip_pim_register_suppress
,
6978 ip_pim_register_suppress_cmd
,
6979 "ip pim register-suppress-time (5-60000)",
6981 "pim multicast routing\n"
6982 "Register Suppress Timer\n"
6985 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6986 router
->register_suppress_time
= atoi(argv
[3]->arg
);
6990 DEFUN (no_ip_pim_register_suppress
,
6991 no_ip_pim_register_suppress_cmd
,
6992 "no ip pim register-suppress-time (5-60000)",
6995 "pim multicast routing\n"
6996 "Register Suppress Timer\n"
6999 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7000 router
->register_suppress_time
= PIM_REGISTER_SUPPRESSION_TIME_DEFAULT
;
7004 DEFUN (ip_pim_rp_keep_alive
,
7005 ip_pim_rp_keep_alive_cmd
,
7006 "ip pim rp keep-alive-timer (31-60000)",
7008 "pim multicast routing\n"
7010 "Keep alive Timer\n"
7013 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7014 pim
->rp_keep_alive_time
= atoi(argv
[4]->arg
);
7018 DEFUN (no_ip_pim_rp_keep_alive
,
7019 no_ip_pim_rp_keep_alive_cmd
,
7020 "no ip pim rp keep-alive-timer (31-60000)",
7023 "pim multicast routing\n"
7025 "Keep alive Timer\n"
7028 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7029 pim
->rp_keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
7033 DEFUN (ip_pim_keep_alive
,
7034 ip_pim_keep_alive_cmd
,
7035 "ip pim keep-alive-timer (31-60000)",
7037 "pim multicast routing\n"
7038 "Keep alive Timer\n"
7041 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7042 pim
->keep_alive_time
= atoi(argv
[3]->arg
);
7046 DEFUN (no_ip_pim_keep_alive
,
7047 no_ip_pim_keep_alive_cmd
,
7048 "no ip pim keep-alive-timer (31-60000)",
7051 "pim multicast routing\n"
7052 "Keep alive Timer\n"
7055 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7056 pim
->keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
7060 DEFUN (ip_pim_packets
,
7062 "ip pim packets (1-100)",
7064 "pim multicast routing\n"
7065 "packets to process at one time per fd\n"
7066 "Number of packets\n")
7068 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7069 router
->packet_process
= atoi(argv
[3]->arg
);
7073 DEFUN (no_ip_pim_packets
,
7074 no_ip_pim_packets_cmd
,
7075 "no ip pim packets (1-100)",
7078 "pim multicast routing\n"
7079 "packets to process at one time per fd\n"
7080 "Number of packets\n")
7082 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7083 router
->packet_process
= PIM_DEFAULT_PACKET_PROCESS
;
7087 DEFPY (igmp_group_watermark
,
7088 igmp_group_watermark_cmd
,
7089 "ip igmp watermark-warn (10-60000)$limit",
7092 "Configure group limit for watermark warning\n"
7093 "Group count to generate watermark warning\n")
7095 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7096 pim
->igmp_watermark_limit
= limit
;
7101 DEFPY (no_igmp_group_watermark
,
7102 no_igmp_group_watermark_cmd
,
7103 "no ip igmp watermark-warn [(10-60000)$limit]",
7107 "Unconfigure group limit for watermark warning\n"
7108 "Group count to generate watermark warning\n")
7110 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7111 pim
->igmp_watermark_limit
= 0;
7116 DEFUN (ip_pim_v6_secondary
,
7117 ip_pim_v6_secondary_cmd
,
7118 "ip pim send-v6-secondary",
7120 "pim multicast routing\n"
7121 "Send v6 secondary addresses\n")
7123 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7124 pim
->send_v6_secondary
= 1;
7129 DEFUN (no_ip_pim_v6_secondary
,
7130 no_ip_pim_v6_secondary_cmd
,
7131 "no ip pim send-v6-secondary",
7134 "pim multicast routing\n"
7135 "Send v6 secondary addresses\n")
7137 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7138 pim
->send_v6_secondary
= 0;
7145 "ip pim rp A.B.C.D [A.B.C.D/M]",
7147 "pim multicast routing\n"
7149 "ip address of RP\n"
7150 "Group Address range to cover\n")
7152 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7155 if (argc
== (idx_ipv4
+ 1))
7156 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
7159 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
7160 argv
[idx_ipv4
+ 1]->arg
, NULL
);
7163 DEFUN (ip_pim_rp_prefix_list
,
7164 ip_pim_rp_prefix_list_cmd
,
7165 "ip pim rp A.B.C.D prefix-list WORD",
7167 "pim multicast routing\n"
7169 "ip address of RP\n"
7170 "group prefix-list filter\n"
7171 "Name of a prefix-list\n")
7173 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7174 return pim_rp_cmd_worker(pim
, vty
, argv
[3]->arg
, NULL
, argv
[5]->arg
);
7177 static int pim_no_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
7178 const char *rp
, const char *group
,
7181 int result
= pim_rp_del_config(pim
, rp
, group
, plist
);
7183 if (result
== PIM_GROUP_BAD_ADDRESS
) {
7184 vty_out(vty
, "%% Bad group address specified: %s\n",
7185 group
? group
: "No Group Address");
7186 return CMD_WARNING_CONFIG_FAILED
;
7189 if (result
== PIM_RP_BAD_ADDRESS
) {
7190 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
7191 return CMD_WARNING_CONFIG_FAILED
;
7194 if (result
== PIM_RP_NOT_FOUND
) {
7195 vty_out(vty
, "%% Unable to find specified RP\n");
7196 return CMD_WARNING_CONFIG_FAILED
;
7202 DEFUN (no_ip_pim_rp
,
7204 "no ip pim rp A.B.C.D [A.B.C.D/M]",
7207 "pim multicast routing\n"
7209 "ip address of RP\n"
7210 "Group Address range to cover\n")
7212 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7213 int idx_ipv4
= 4, idx_group
= 0;
7215 if (argv_find(argv
, argc
, "A.B.C.D/M", &idx_group
))
7216 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
7217 argv
[idx_group
]->arg
, NULL
);
7219 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
7223 DEFUN (no_ip_pim_rp_prefix_list
,
7224 no_ip_pim_rp_prefix_list_cmd
,
7225 "no ip pim rp A.B.C.D prefix-list WORD",
7228 "pim multicast routing\n"
7230 "ip address of RP\n"
7231 "group prefix-list filter\n"
7232 "Name of a prefix-list\n")
7234 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7235 return pim_no_rp_cmd_worker(pim
, vty
, argv
[4]->arg
, NULL
, argv
[6]->arg
);
7238 static int pim_ssm_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
7241 int result
= pim_ssm_range_set(pim
, pim
->vrf_id
, plist
);
7242 int ret
= CMD_WARNING_CONFIG_FAILED
;
7244 if (result
== PIM_SSM_ERR_NONE
)
7248 case PIM_SSM_ERR_NO_VRF
:
7249 vty_out(vty
, "%% VRF doesn't exist\n");
7251 case PIM_SSM_ERR_DUP
:
7252 vty_out(vty
, "%% duplicate config\n");
7256 vty_out(vty
, "%% ssm range config failed\n");
7262 DEFUN (ip_pim_ssm_prefix_list
,
7263 ip_pim_ssm_prefix_list_cmd
,
7264 "ip pim ssm prefix-list WORD",
7266 "pim multicast routing\n"
7267 "Source Specific Multicast\n"
7268 "group range prefix-list filter\n"
7269 "Name of a prefix-list\n")
7271 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7272 return pim_ssm_cmd_worker(pim
, vty
, argv
[4]->arg
);
7275 DEFUN (no_ip_pim_ssm_prefix_list
,
7276 no_ip_pim_ssm_prefix_list_cmd
,
7277 "no ip pim ssm prefix-list",
7280 "pim multicast routing\n"
7281 "Source Specific Multicast\n"
7282 "group range prefix-list filter\n")
7284 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7285 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
7288 DEFUN (no_ip_pim_ssm_prefix_list_name
,
7289 no_ip_pim_ssm_prefix_list_name_cmd
,
7290 "no ip pim ssm prefix-list WORD",
7293 "pim multicast routing\n"
7294 "Source Specific Multicast\n"
7295 "group range prefix-list filter\n"
7296 "Name of a prefix-list\n")
7298 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7299 struct pim_ssm
*ssm
= pim
->ssm_info
;
7301 if (ssm
->plist_name
&& !strcmp(ssm
->plist_name
, argv
[5]->arg
))
7302 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
7304 vty_out(vty
, "%% pim ssm prefix-list %s doesn't exist\n", argv
[5]->arg
);
7306 return CMD_WARNING_CONFIG_FAILED
;
7309 static void ip_pim_ssm_show_group_range(struct pim_instance
*pim
,
7310 struct vty
*vty
, bool uj
)
7312 struct pim_ssm
*ssm
= pim
->ssm_info
;
7313 const char *range_str
=
7314 ssm
->plist_name
? ssm
->plist_name
: PIM_SSM_STANDARD_RANGE
;
7318 json
= json_object_new_object();
7319 json_object_string_add(json
, "ssmGroups", range_str
);
7320 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
7321 json
, JSON_C_TO_STRING_PRETTY
));
7322 json_object_free(json
);
7324 vty_out(vty
, "SSM group range : %s\n", range_str
);
7327 DEFUN (show_ip_pim_ssm_range
,
7328 show_ip_pim_ssm_range_cmd
,
7329 "show ip pim [vrf NAME] group-type [json]",
7338 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
7339 bool uj
= use_json(argc
, argv
);
7344 ip_pim_ssm_show_group_range(vrf
->info
, vty
, uj
);
7349 static void ip_pim_ssm_show_group_type(struct pim_instance
*pim
,
7350 struct vty
*vty
, bool uj
,
7353 struct in_addr group_addr
;
7354 const char *type_str
;
7357 result
= inet_pton(AF_INET
, group
, &group_addr
);
7359 type_str
= "invalid";
7361 if (pim_is_group_224_4(group_addr
))
7363 pim_is_grp_ssm(pim
, group_addr
) ? "SSM" : "ASM";
7365 type_str
= "not-multicast";
7370 json
= json_object_new_object();
7371 json_object_string_add(json
, "groupType", type_str
);
7372 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
7373 json
, JSON_C_TO_STRING_PRETTY
));
7374 json_object_free(json
);
7376 vty_out(vty
, "Group type : %s\n", type_str
);
7379 DEFUN (show_ip_pim_group_type
,
7380 show_ip_pim_group_type_cmd
,
7381 "show ip pim [vrf NAME] group-type A.B.C.D [json]",
7386 "multicast group type\n"
7391 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
7392 bool uj
= use_json(argc
, argv
);
7397 argv_find(argv
, argc
, "A.B.C.D", &idx
);
7398 ip_pim_ssm_show_group_type(vrf
->info
, vty
, uj
, argv
[idx
]->arg
);
7403 DEFUN (show_ip_pim_bsr
,
7404 show_ip_pim_bsr_cmd
,
7405 "show ip pim bsr [json]",
7409 "boot-strap router information\n"
7413 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
7414 bool uj
= use_json(argc
, argv
);
7419 pim_show_bsr(vrf
->info
, vty
, uj
);
7426 "ip ssmpingd [A.B.C.D]",
7431 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7434 struct in_addr source_addr
;
7435 const char *source_str
= (argc
== 3) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
7437 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
7439 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
7440 source_str
, errno
, safe_strerror(errno
));
7441 return CMD_WARNING_CONFIG_FAILED
;
7444 result
= pim_ssmpingd_start(pim
, source_addr
);
7446 vty_out(vty
, "%% Failure starting ssmpingd for source %s: %d\n",
7447 source_str
, result
);
7448 return CMD_WARNING_CONFIG_FAILED
;
7454 DEFUN (no_ip_ssmpingd
,
7456 "no ip ssmpingd [A.B.C.D]",
7462 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7465 struct in_addr source_addr
;
7466 const char *source_str
= (argc
== 4) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
7468 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
7470 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
7471 source_str
, errno
, safe_strerror(errno
));
7472 return CMD_WARNING_CONFIG_FAILED
;
7475 result
= pim_ssmpingd_stop(pim
, source_addr
);
7477 vty_out(vty
, "%% Failure stopping ssmpingd for source %s: %d\n",
7478 source_str
, result
);
7479 return CMD_WARNING_CONFIG_FAILED
;
7489 "pim multicast routing\n"
7490 "Enable PIM ECMP \n")
7492 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7493 pim
->ecmp_enable
= true;
7498 DEFUN (no_ip_pim_ecmp
,
7503 "pim multicast routing\n"
7504 "Disable PIM ECMP \n")
7506 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7507 pim
->ecmp_enable
= false;
7512 DEFUN (ip_pim_ecmp_rebalance
,
7513 ip_pim_ecmp_rebalance_cmd
,
7514 "ip pim ecmp rebalance",
7516 "pim multicast routing\n"
7517 "Enable PIM ECMP \n"
7518 "Enable PIM ECMP Rebalance\n")
7520 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7521 pim
->ecmp_enable
= true;
7522 pim
->ecmp_rebalance_enable
= true;
7527 DEFUN (no_ip_pim_ecmp_rebalance
,
7528 no_ip_pim_ecmp_rebalance_cmd
,
7529 "no ip pim ecmp rebalance",
7532 "pim multicast routing\n"
7533 "Disable PIM ECMP \n"
7534 "Disable PIM ECMP Rebalance\n")
7536 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7537 pim
->ecmp_rebalance_enable
= false;
7542 static int pim_cmd_igmp_start(struct vty
*vty
, struct interface
*ifp
)
7544 struct pim_interface
*pim_ifp
;
7545 struct pim_instance
*pim
;
7546 uint8_t need_startup
= 0;
7548 pim_ifp
= ifp
->info
;
7551 pim
= pim_get_pim_instance(ifp
->vrf_id
);
7552 /* Limit mcast interfaces to number of vifs available */
7553 if (pim
->mcast_if_count
== MAXVIFS
) {
7555 "Max multicast interfaces(%d) Reached. Could not enable IGMP on interface %s\n",
7556 MAXVIFS
, ifp
->name
);
7557 return CMD_WARNING_CONFIG_FAILED
;
7559 (void)pim_if_new(ifp
, true, false, false, false);
7562 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
7563 PIM_IF_DO_IGMP(pim_ifp
->options
);
7568 /* 'ip igmp' executed multiple times, with need_startup
7569 avoid multiple if add all and membership refresh */
7571 pim_if_addr_add_all(ifp
);
7572 pim_if_membership_refresh(ifp
);
7578 DEFUN (interface_ip_igmp
,
7579 interface_ip_igmp_cmd
,
7584 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7586 return pim_cmd_igmp_start(vty
, ifp
);
7589 DEFUN (interface_no_ip_igmp
,
7590 interface_no_ip_igmp_cmd
,
7596 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7597 struct pim_interface
*pim_ifp
= ifp
->info
;
7602 PIM_IF_DONT_IGMP(pim_ifp
->options
);
7604 pim_if_membership_clear(ifp
);
7606 pim_if_addr_del_all_igmp(ifp
);
7608 if (!PIM_IF_TEST_PIM(pim_ifp
->options
)) {
7615 DEFUN (interface_ip_igmp_join
,
7616 interface_ip_igmp_join_cmd
,
7617 "ip igmp join A.B.C.D [A.B.C.D]",
7620 "IGMP join multicast group\n"
7621 "Multicast group address\n"
7624 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7627 const char *group_str
;
7628 const char *source_str
;
7629 struct in_addr group_addr
;
7630 struct in_addr source_addr
;
7634 group_str
= argv
[idx_ipv4
]->arg
;
7635 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
7637 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
7638 errno
, safe_strerror(errno
));
7639 return CMD_WARNING_CONFIG_FAILED
;
7642 /* Source address */
7643 if (argc
== (idx_ipv4_2
+ 1)) {
7644 source_str
= argv
[idx_ipv4_2
]->arg
;
7645 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
7647 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
7648 source_str
, errno
, safe_strerror(errno
));
7649 return CMD_WARNING_CONFIG_FAILED
;
7651 /* Reject 0.0.0.0. Reserved for any source. */
7652 if (source_addr
.s_addr
== INADDR_ANY
) {
7653 vty_out(vty
, "Bad source address %s\n", source_str
);
7654 return CMD_WARNING_CONFIG_FAILED
;
7657 source_addr
.s_addr
= INADDR_ANY
;
7660 CMD_FERR_RETURN(pim_if_igmp_join_add(ifp
, group_addr
, source_addr
),
7661 "Failure joining IGMP group: $ERR");
7666 DEFUN (interface_no_ip_igmp_join
,
7667 interface_no_ip_igmp_join_cmd
,
7668 "no ip igmp join A.B.C.D [A.B.C.D]",
7672 "IGMP join multicast group\n"
7673 "Multicast group address\n"
7676 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7679 const char *group_str
;
7680 const char *source_str
;
7681 struct in_addr group_addr
;
7682 struct in_addr source_addr
;
7686 group_str
= argv
[idx_ipv4
]->arg
;
7687 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
7689 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
7690 errno
, safe_strerror(errno
));
7691 return CMD_WARNING_CONFIG_FAILED
;
7694 /* Source address */
7695 if (argc
== (idx_ipv4_2
+ 1)) {
7696 source_str
= argv
[idx_ipv4_2
]->arg
;
7697 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
7699 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
7700 source_str
, errno
, safe_strerror(errno
));
7701 return CMD_WARNING_CONFIG_FAILED
;
7703 /* Reject 0.0.0.0. Reserved for any source. */
7704 if (source_addr
.s_addr
== INADDR_ANY
) {
7705 vty_out(vty
, "Bad source address %s\n", source_str
);
7706 return CMD_WARNING_CONFIG_FAILED
;
7710 source_addr
.s_addr
= INADDR_ANY
;
7713 result
= pim_if_igmp_join_del(ifp
, group_addr
, source_addr
);
7716 "%% Failure leaving IGMP group %s source %s on interface %s: %d\n",
7717 group_str
, source_str
, ifp
->name
, result
);
7718 return CMD_WARNING_CONFIG_FAILED
;
7725 CLI reconfiguration affects the interface level (struct pim_interface).
7726 This function propagates the reconfiguration to every active socket
7729 static void igmp_sock_query_interval_reconfig(struct igmp_sock
*igmp
)
7731 struct interface
*ifp
;
7732 struct pim_interface
*pim_ifp
;
7736 /* other querier present? */
7738 if (igmp
->t_other_querier_timer
)
7741 /* this is the querier */
7743 zassert(igmp
->interface
);
7744 zassert(igmp
->interface
->info
);
7746 ifp
= igmp
->interface
;
7747 pim_ifp
= ifp
->info
;
7749 if (PIM_DEBUG_IGMP_TRACE
) {
7750 char ifaddr_str
[INET_ADDRSTRLEN
];
7751 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
7752 sizeof(ifaddr_str
));
7753 zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
7754 __func__
, ifaddr_str
, ifp
->name
,
7755 pim_ifp
->igmp_default_query_interval
);
7759 igmp_startup_mode_on() will reset QQI:
7761 igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
7763 igmp_startup_mode_on(igmp
);
7766 static void igmp_sock_query_reschedule(struct igmp_sock
*igmp
)
7768 if (igmp
->mtrace_only
)
7771 if (igmp
->t_igmp_query_timer
) {
7772 /* other querier present */
7773 zassert(igmp
->t_igmp_query_timer
);
7774 zassert(!igmp
->t_other_querier_timer
);
7776 pim_igmp_general_query_off(igmp
);
7777 pim_igmp_general_query_on(igmp
);
7779 zassert(igmp
->t_igmp_query_timer
);
7780 zassert(!igmp
->t_other_querier_timer
);
7782 /* this is the querier */
7784 zassert(!igmp
->t_igmp_query_timer
);
7785 zassert(igmp
->t_other_querier_timer
);
7787 pim_igmp_other_querier_timer_off(igmp
);
7788 pim_igmp_other_querier_timer_on(igmp
);
7790 zassert(!igmp
->t_igmp_query_timer
);
7791 zassert(igmp
->t_other_querier_timer
);
7795 static void change_query_interval(struct pim_interface
*pim_ifp
,
7798 struct listnode
*sock_node
;
7799 struct igmp_sock
*igmp
;
7801 pim_ifp
->igmp_default_query_interval
= query_interval
;
7803 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
7804 igmp_sock_query_interval_reconfig(igmp
);
7805 igmp_sock_query_reschedule(igmp
);
7809 static void change_query_max_response_time(struct pim_interface
*pim_ifp
,
7810 int query_max_response_time_dsec
)
7812 struct listnode
*sock_node
;
7813 struct igmp_sock
*igmp
;
7815 pim_ifp
->igmp_query_max_response_time_dsec
=
7816 query_max_response_time_dsec
;
7819 Below we modify socket/group/source timers in order to quickly
7820 reflect the change. Otherwise, those timers would eventually catch
7824 /* scan all sockets */
7825 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
7826 struct listnode
*grp_node
;
7827 struct igmp_group
*grp
;
7829 /* reschedule socket general query */
7830 igmp_sock_query_reschedule(igmp
);
7832 /* scan socket groups */
7833 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grp_node
,
7835 struct listnode
*src_node
;
7836 struct igmp_source
*src
;
7838 /* reset group timers for groups in EXCLUDE mode */
7839 if (grp
->group_filtermode_isexcl
) {
7840 igmp_group_reset_gmi(grp
);
7843 /* scan group sources */
7844 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
,
7847 /* reset source timers for sources with running
7849 if (src
->t_source_timer
) {
7850 igmp_source_reset_gmi(igmp
, grp
, src
);
7857 #define IGMP_QUERY_INTERVAL_MIN (1)
7858 #define IGMP_QUERY_INTERVAL_MAX (1800)
7860 DEFUN (interface_ip_igmp_query_interval
,
7861 interface_ip_igmp_query_interval_cmd
,
7862 "ip igmp query-interval (1-1800)",
7865 IFACE_IGMP_QUERY_INTERVAL_STR
7866 "Query interval in seconds\n")
7868 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7869 struct pim_interface
*pim_ifp
= ifp
->info
;
7871 int query_interval_dsec
;
7875 ret
= pim_cmd_igmp_start(vty
, ifp
);
7876 if (ret
!= CMD_SUCCESS
)
7878 pim_ifp
= ifp
->info
;
7881 query_interval
= atoi(argv
[3]->arg
);
7882 query_interval_dsec
= 10 * query_interval
;
7885 It seems we don't need to check bounds since command.c does it
7886 already, but we verify them anyway for extra safety.
7888 if (query_interval
< IGMP_QUERY_INTERVAL_MIN
) {
7890 "General query interval %d lower than minimum %d\n",
7891 query_interval
, IGMP_QUERY_INTERVAL_MIN
);
7892 return CMD_WARNING_CONFIG_FAILED
;
7894 if (query_interval
> IGMP_QUERY_INTERVAL_MAX
) {
7896 "General query interval %d higher than maximum %d\n",
7897 query_interval
, IGMP_QUERY_INTERVAL_MAX
);
7898 return CMD_WARNING_CONFIG_FAILED
;
7901 if (query_interval_dsec
<= pim_ifp
->igmp_query_max_response_time_dsec
) {
7903 "Can't set general query interval %d dsec <= query max response time %d dsec.\n",
7904 query_interval_dsec
,
7905 pim_ifp
->igmp_query_max_response_time_dsec
);
7906 return CMD_WARNING_CONFIG_FAILED
;
7909 change_query_interval(pim_ifp
, query_interval
);
7914 DEFUN (interface_no_ip_igmp_query_interval
,
7915 interface_no_ip_igmp_query_interval_cmd
,
7916 "no ip igmp query-interval",
7920 IFACE_IGMP_QUERY_INTERVAL_STR
)
7922 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7923 struct pim_interface
*pim_ifp
= ifp
->info
;
7924 int default_query_interval_dsec
;
7929 default_query_interval_dsec
= IGMP_GENERAL_QUERY_INTERVAL
* 10;
7931 if (default_query_interval_dsec
7932 <= pim_ifp
->igmp_query_max_response_time_dsec
) {
7934 "Can't set default general query interval %d dsec <= query max response time %d dsec.\n",
7935 default_query_interval_dsec
,
7936 pim_ifp
->igmp_query_max_response_time_dsec
);
7937 return CMD_WARNING_CONFIG_FAILED
;
7940 change_query_interval(pim_ifp
, IGMP_GENERAL_QUERY_INTERVAL
);
7945 DEFUN (interface_ip_igmp_version
,
7946 interface_ip_igmp_version_cmd
,
7947 "ip igmp version (2-3)",
7951 "IGMP version number\n")
7953 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7954 struct pim_interface
*pim_ifp
= ifp
->info
;
7955 int igmp_version
, old_version
= 0;
7959 ret
= pim_cmd_igmp_start(vty
, ifp
);
7960 if (ret
!= CMD_SUCCESS
)
7962 pim_ifp
= ifp
->info
;
7965 igmp_version
= atoi(argv
[3]->arg
);
7966 old_version
= pim_ifp
->igmp_version
;
7967 pim_ifp
->igmp_version
= igmp_version
;
7969 // Check if IGMP is Enabled otherwise, enable on interface
7970 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
7971 PIM_IF_DO_IGMP(pim_ifp
->options
);
7972 pim_if_addr_add_all(ifp
);
7973 pim_if_membership_refresh(ifp
);
7974 old_version
= igmp_version
;
7975 // avoid refreshing membership again.
7977 /* Current and new version is different refresh existing
7978 membership. Going from 3 -> 2 or 2 -> 3. */
7979 if (old_version
!= igmp_version
)
7980 pim_if_membership_refresh(ifp
);
7985 DEFUN (interface_no_ip_igmp_version
,
7986 interface_no_ip_igmp_version_cmd
,
7987 "no ip igmp version (2-3)",
7992 "IGMP version number\n")
7994 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7995 struct pim_interface
*pim_ifp
= ifp
->info
;
8000 pim_ifp
->igmp_version
= IGMP_DEFAULT_VERSION
;
8005 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
8006 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
8008 DEFUN (interface_ip_igmp_query_max_response_time
,
8009 interface_ip_igmp_query_max_response_time_cmd
,
8010 "ip igmp query-max-response-time (10-250)",
8013 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
8014 "Query response value in deci-seconds\n")
8016 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8017 struct pim_interface
*pim_ifp
= ifp
->info
;
8018 int query_max_response_time
;
8022 ret
= pim_cmd_igmp_start(vty
, ifp
);
8023 if (ret
!= CMD_SUCCESS
)
8025 pim_ifp
= ifp
->info
;
8028 query_max_response_time
= atoi(argv
[3]->arg
);
8030 if (query_max_response_time
8031 >= pim_ifp
->igmp_default_query_interval
* 10) {
8033 "Can't set query max response time %d sec >= general query interval %d sec\n",
8034 query_max_response_time
,
8035 pim_ifp
->igmp_default_query_interval
);
8036 return CMD_WARNING_CONFIG_FAILED
;
8039 change_query_max_response_time(pim_ifp
, query_max_response_time
);
8044 DEFUN (interface_no_ip_igmp_query_max_response_time
,
8045 interface_no_ip_igmp_query_max_response_time_cmd
,
8046 "no ip igmp query-max-response-time (10-250)",
8050 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
8051 "Time for response in deci-seconds\n")
8053 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8054 struct pim_interface
*pim_ifp
= ifp
->info
;
8059 change_query_max_response_time(pim_ifp
,
8060 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
8065 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
8066 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
8068 DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec
,
8069 interface_ip_igmp_query_max_response_time_dsec_cmd
,
8070 "ip igmp query-max-response-time-dsec (10-250)",
8073 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
8074 "Query response value in deciseconds\n")
8076 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8077 struct pim_interface
*pim_ifp
= ifp
->info
;
8078 int query_max_response_time_dsec
;
8079 int default_query_interval_dsec
;
8083 ret
= pim_cmd_igmp_start(vty
, ifp
);
8084 if (ret
!= CMD_SUCCESS
)
8086 pim_ifp
= ifp
->info
;
8089 query_max_response_time_dsec
= atoi(argv
[4]->arg
);
8091 default_query_interval_dsec
= 10 * pim_ifp
->igmp_default_query_interval
;
8093 if (query_max_response_time_dsec
>= default_query_interval_dsec
) {
8095 "Can't set query max response time %d dsec >= general query interval %d dsec\n",
8096 query_max_response_time_dsec
,
8097 default_query_interval_dsec
);
8098 return CMD_WARNING_CONFIG_FAILED
;
8101 change_query_max_response_time(pim_ifp
, query_max_response_time_dsec
);
8106 DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec
,
8107 interface_no_ip_igmp_query_max_response_time_dsec_cmd
,
8108 "no ip igmp query-max-response-time-dsec",
8112 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
)
8114 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8115 struct pim_interface
*pim_ifp
= ifp
->info
;
8120 change_query_max_response_time(pim_ifp
,
8121 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
8126 #define IGMP_LAST_MEMBER_QUERY_COUNT_MIN (1)
8127 #define IGMP_LAST_MEMBER_QUERY_COUNT_MAX (7)
8129 DEFUN (interface_ip_igmp_last_member_query_count
,
8130 interface_ip_igmp_last_member_query_count_cmd
,
8131 "ip igmp last-member-query-count (1-7)",
8134 IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR
8135 "Last member query count\n")
8137 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8138 struct pim_interface
*pim_ifp
= ifp
->info
;
8139 int last_member_query_count
;
8143 ret
= pim_cmd_igmp_start(vty
, ifp
);
8144 if (ret
!= CMD_SUCCESS
)
8146 pim_ifp
= ifp
->info
;
8149 last_member_query_count
= atoi(argv
[3]->arg
);
8151 pim_ifp
->igmp_last_member_query_count
= last_member_query_count
;
8156 DEFUN (interface_no_ip_igmp_last_member_query_count
,
8157 interface_no_ip_igmp_last_member_query_count_cmd
,
8158 "no ip igmp last-member-query-count",
8162 IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR
)
8164 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8165 struct pim_interface
*pim_ifp
= ifp
->info
;
8170 pim_ifp
->igmp_last_member_query_count
=
8171 IGMP_DEFAULT_ROBUSTNESS_VARIABLE
;
8176 #define IGMP_LAST_MEMBER_QUERY_INTERVAL_MIN (1)
8177 #define IGMP_LAST_MEMBER_QUERY_INTERVAL_MAX (255)
8179 DEFUN (interface_ip_igmp_last_member_query_interval
,
8180 interface_ip_igmp_last_member_query_interval_cmd
,
8181 "ip igmp last-member-query-interval (1-255)",
8184 IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR
8185 "Last member query interval in deciseconds\n")
8187 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8188 struct pim_interface
*pim_ifp
= ifp
->info
;
8189 int last_member_query_interval
;
8193 ret
= pim_cmd_igmp_start(vty
, ifp
);
8194 if (ret
!= CMD_SUCCESS
)
8196 pim_ifp
= ifp
->info
;
8199 last_member_query_interval
= atoi(argv
[3]->arg
);
8200 pim_ifp
->igmp_specific_query_max_response_time_dsec
8201 = last_member_query_interval
;
8206 DEFUN (interface_no_ip_igmp_last_member_query_interval
,
8207 interface_no_ip_igmp_last_member_query_interval_cmd
,
8208 "no ip igmp last-member-query-interval",
8212 IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR
)
8214 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8215 struct pim_interface
*pim_ifp
= ifp
->info
;
8220 pim_ifp
->igmp_specific_query_max_response_time_dsec
=
8221 IGMP_SPECIFIC_QUERY_MAX_RESPONSE_TIME_DSEC
;
8226 DEFUN (interface_ip_pim_drprio
,
8227 interface_ip_pim_drprio_cmd
,
8228 "ip pim drpriority (1-4294967295)",
8231 "Set the Designated Router Election Priority\n"
8232 "Value of the new DR Priority\n")
8234 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8236 struct pim_interface
*pim_ifp
= ifp
->info
;
8237 uint32_t old_dr_prio
;
8240 vty_out(vty
, "Please enable PIM on interface, first\n");
8241 return CMD_WARNING_CONFIG_FAILED
;
8244 old_dr_prio
= pim_ifp
->pim_dr_priority
;
8246 pim_ifp
->pim_dr_priority
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
8248 if (old_dr_prio
!= pim_ifp
->pim_dr_priority
) {
8249 pim_if_dr_election(ifp
);
8250 pim_hello_restart_now(ifp
);
8256 DEFUN (interface_no_ip_pim_drprio
,
8257 interface_no_ip_pim_drprio_cmd
,
8258 "no ip pim drpriority [(1-4294967295)]",
8262 "Revert the Designated Router Priority to default\n"
8263 "Old Value of the Priority\n")
8265 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8266 struct pim_interface
*pim_ifp
= ifp
->info
;
8269 vty_out(vty
, "Pim not enabled on this interface\n");
8270 return CMD_WARNING_CONFIG_FAILED
;
8273 if (pim_ifp
->pim_dr_priority
!= PIM_DEFAULT_DR_PRIORITY
) {
8274 pim_ifp
->pim_dr_priority
= PIM_DEFAULT_DR_PRIORITY
;
8275 pim_if_dr_election(ifp
);
8276 pim_hello_restart_now(ifp
);
8282 DEFPY_HIDDEN (interface_ip_igmp_query_generate
,
8283 interface_ip_igmp_query_generate_cmd
,
8284 "ip igmp generate-query-once [version (2-3)]",
8287 "Generate igmp general query once\n"
8289 "IGMP version number\n")
8291 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8292 int igmp_version
= 2;
8295 vty_out(vty
, "IGMP/PIM is not enabled on the interface %s\n",
8297 return CMD_WARNING_CONFIG_FAILED
;
8301 igmp_version
= atoi(argv
[4]->arg
);
8303 igmp_send_query_on_intf(ifp
, igmp_version
);
8308 static int pim_cmd_interface_add(struct vty
*vty
, struct interface
*ifp
)
8310 struct pim_interface
*pim_ifp
= ifp
->info
;
8311 struct pim_instance
*pim
;
8314 pim
= pim_get_pim_instance(ifp
->vrf_id
);
8315 /* Limiting mcast interfaces to number of VIFs */
8316 if (pim
->mcast_if_count
== MAXVIFS
) {
8317 vty_out(vty
, "Max multicast interfaces(%d) reached.",
8321 pim_ifp
= pim_if_new(ifp
, false, true, false, false);
8323 PIM_IF_DO_PIM(pim_ifp
->options
);
8325 pim_if_addr_add_all(ifp
);
8326 pim_if_membership_refresh(ifp
);
8328 pim_if_create_pimreg(pim_ifp
->pim
);
8332 DEFPY_HIDDEN (pim_test_sg_keepalive
,
8333 pim_test_sg_keepalive_cmd
,
8334 "test pim [vrf NAME$name] keepalive-reset A.B.C.D$source A.B.C.D$group",
8338 "Reset the Keepalive Timer\n"
8339 "The Source we are resetting\n"
8340 "The Group we are resetting\n")
8342 struct pim_upstream
*up
;
8343 struct pim_instance
*pim
;
8344 struct prefix_sg sg
;
8350 pim
= pim_get_pim_instance(VRF_DEFAULT
);
8352 struct vrf
*vrf
= vrf_lookup_by_name(name
);
8355 vty_out(vty
, "%% Vrf specified: %s does not exist\n",
8360 pim
= pim_get_pim_instance(vrf
->vrf_id
);
8364 vty_out(vty
, "%% Unable to find pim instance\n");
8368 up
= pim_upstream_find(pim
, &sg
);
8370 vty_out(vty
, "%% Unable to find %s specified\n",
8371 pim_str_sg_dump(&sg
));
8375 vty_out(vty
, "Setting %s to current keep alive time: %d\n",
8376 pim_str_sg_dump(&sg
), pim
->keep_alive_time
);
8377 pim_upstream_keep_alive_timer_start(up
, pim
->keep_alive_time
);
8382 DEFPY (interface_ip_pim_activeactive
,
8383 interface_ip_pim_activeactive_cmd
,
8384 "[no$no] ip pim active-active",
8388 "Mark interface as Active-Active for MLAG operations, Hidden because not finished yet\n")
8390 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8391 struct pim_interface
*pim_ifp
;
8393 if (!no
&& !pim_cmd_interface_add(vty
, ifp
)) {
8395 "Could not enable PIM SM active-active on interface %s\n",
8397 return CMD_WARNING_CONFIG_FAILED
;
8402 zlog_debug("%sConfiguring PIM active-active on Interface: %s",
8403 no
? "Un-" : " ", ifp
->name
);
8405 pim_ifp
= ifp
->info
;
8407 pim_if_unconfigure_mlag_dualactive(pim_ifp
);
8409 pim_if_configure_mlag_dualactive(pim_ifp
);
8414 DEFUN_HIDDEN (interface_ip_pim_ssm
,
8415 interface_ip_pim_ssm_cmd
,
8421 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8423 if (!pim_cmd_interface_add(vty
, ifp
)) {
8424 vty_out(vty
, "Could not enable PIM SM on interface %s\n",
8426 return CMD_WARNING_CONFIG_FAILED
;
8430 "WARN: Enabled PIM SM on interface; configure PIM SSM range if needed\n");
8434 static int interface_ip_pim_helper(struct vty
*vty
)
8436 struct pim_interface
*pim_ifp
;
8438 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8440 if (!pim_cmd_interface_add(vty
, ifp
)) {
8441 vty_out(vty
, "Could not enable PIM SM on interface %s\n",
8443 return CMD_WARNING_CONFIG_FAILED
;
8446 pim_ifp
= ifp
->info
;
8448 pim_if_create_pimreg(pim_ifp
->pim
);
8453 DEFUN_HIDDEN (interface_ip_pim_sm
,
8454 interface_ip_pim_sm_cmd
,
8460 return interface_ip_pim_helper(vty
);
8463 DEFUN (interface_ip_pim
,
8464 interface_ip_pim_cmd
,
8469 return interface_ip_pim_helper(vty
);
8472 static int pim_cmd_interface_delete(struct interface
*ifp
)
8474 struct pim_interface
*pim_ifp
= ifp
->info
;
8479 PIM_IF_DONT_PIM(pim_ifp
->options
);
8481 pim_if_membership_clear(ifp
);
8484 pim_sock_delete() removes all neighbors from
8485 pim_ifp->pim_neighbor_list.
8487 pim_sock_delete(ifp
, "pim unconfigured on interface");
8489 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
8490 pim_if_addr_del_all(ifp
);
8497 static int interface_no_ip_pim_helper(struct vty
*vty
)
8499 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8500 if (!pim_cmd_interface_delete(ifp
)) {
8501 vty_out(vty
, "Unable to delete interface information\n");
8502 return CMD_WARNING_CONFIG_FAILED
;
8508 DEFUN_HIDDEN (interface_no_ip_pim_ssm
,
8509 interface_no_ip_pim_ssm_cmd
,
8516 return interface_no_ip_pim_helper(vty
);
8519 DEFUN_HIDDEN (interface_no_ip_pim_sm
,
8520 interface_no_ip_pim_sm_cmd
,
8527 return interface_no_ip_pim_helper(vty
);
8530 DEFUN (interface_no_ip_pim
,
8531 interface_no_ip_pim_cmd
,
8537 return interface_no_ip_pim_helper(vty
);
8541 DEFUN(interface_ip_pim_boundary_oil
,
8542 interface_ip_pim_boundary_oil_cmd
,
8543 "ip multicast boundary oil WORD",
8545 "Generic multicast configuration options\n"
8546 "Define multicast boundary\n"
8547 "Filter OIL by group using prefix list\n"
8548 "Prefix list to filter OIL with\n")
8550 VTY_DECLVAR_CONTEXT(interface
, iif
);
8551 struct pim_interface
*pim_ifp
;
8554 argv_find(argv
, argc
, "WORD", &idx
);
8556 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
8558 if (pim_ifp
->boundary_oil_plist
)
8559 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
8561 pim_ifp
->boundary_oil_plist
=
8562 XSTRDUP(MTYPE_PIM_INTERFACE
, argv
[idx
]->arg
);
8564 /* Interface will be pruned from OIL on next Join */
8568 DEFUN(interface_no_ip_pim_boundary_oil
,
8569 interface_no_ip_pim_boundary_oil_cmd
,
8570 "no ip multicast boundary oil [WORD]",
8573 "Generic multicast configuration options\n"
8574 "Define multicast boundary\n"
8575 "Filter OIL by group using prefix list\n"
8576 "Prefix list to filter OIL with\n")
8578 VTY_DECLVAR_CONTEXT(interface
, iif
);
8579 struct pim_interface
*pim_ifp
;
8582 argv_find(argv
, argc
, "WORD", &idx
);
8584 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
8586 if (pim_ifp
->boundary_oil_plist
)
8587 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
8592 DEFUN (interface_ip_mroute
,
8593 interface_ip_mroute_cmd
,
8594 "ip mroute INTERFACE A.B.C.D [A.B.C.D]",
8596 "Add multicast route\n"
8597 "Outgoing interface name\n"
8601 VTY_DECLVAR_CONTEXT(interface
, iif
);
8602 struct pim_interface
*pim_ifp
;
8603 struct pim_instance
*pim
;
8604 int idx_interface
= 2;
8606 struct interface
*oif
;
8607 const char *oifname
;
8608 const char *grp_str
;
8609 struct in_addr grp_addr
;
8610 const char *src_str
;
8611 struct in_addr src_addr
;
8614 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
8617 oifname
= argv
[idx_interface
]->arg
;
8618 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
8620 vty_out(vty
, "No such interface name %s\n", oifname
);
8624 grp_str
= argv
[idx_ipv4
]->arg
;
8625 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
8627 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
8628 errno
, safe_strerror(errno
));
8632 if (argc
== (idx_ipv4
+ 1)) {
8633 src_addr
.s_addr
= INADDR_ANY
;
8636 src_str
= argv
[idx_ipv4
+ 1]->arg
;
8637 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
8639 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
8640 errno
, safe_strerror(errno
));
8645 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
8646 vty_out(vty
, "Failed to add static mroute\n");
8653 DEFUN (interface_no_ip_mroute
,
8654 interface_no_ip_mroute_cmd
,
8655 "no ip mroute INTERFACE A.B.C.D [A.B.C.D]",
8658 "Add multicast route\n"
8659 "Outgoing interface name\n"
8663 VTY_DECLVAR_CONTEXT(interface
, iif
);
8664 struct pim_interface
*pim_ifp
;
8665 struct pim_instance
*pim
;
8666 int idx_interface
= 3;
8668 struct interface
*oif
;
8669 const char *oifname
;
8670 const char *grp_str
;
8671 struct in_addr grp_addr
;
8672 const char *src_str
;
8673 struct in_addr src_addr
;
8676 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
8679 oifname
= argv
[idx_interface
]->arg
;
8680 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
8682 vty_out(vty
, "No such interface name %s\n", oifname
);
8686 grp_str
= argv
[idx_ipv4
]->arg
;
8687 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
8689 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
8690 errno
, safe_strerror(errno
));
8694 if (argc
== (idx_ipv4
+ 1)) {
8695 src_addr
.s_addr
= INADDR_ANY
;
8698 src_str
= argv
[idx_ipv4
+ 1]->arg
;
8699 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
8701 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
8702 errno
, safe_strerror(errno
));
8707 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
8708 vty_out(vty
, "Failed to remove static mroute\n");
8715 DEFUN (interface_ip_pim_hello
,
8716 interface_ip_pim_hello_cmd
,
8717 "ip pim hello (1-180) [(1-180)]",
8721 IFACE_PIM_HELLO_TIME_STR
8722 IFACE_PIM_HELLO_HOLD_STR
)
8724 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8727 struct pim_interface
*pim_ifp
= ifp
->info
;
8730 if (!pim_cmd_interface_add(vty
, ifp
)) {
8732 "Could not enable PIM SM on interface %s\n",
8734 return CMD_WARNING_CONFIG_FAILED
;
8738 pim_ifp
= ifp
->info
;
8739 pim_ifp
->pim_hello_period
= strtol(argv
[idx_time
]->arg
, NULL
, 10);
8741 if (argc
== idx_hold
+ 1)
8742 pim_ifp
->pim_default_holdtime
=
8743 strtol(argv
[idx_hold
]->arg
, NULL
, 10);
8748 DEFUN (interface_no_ip_pim_hello
,
8749 interface_no_ip_pim_hello_cmd
,
8750 "no ip pim hello [(1-180) (1-180)]",
8755 IFACE_PIM_HELLO_TIME_STR
8756 IFACE_PIM_HELLO_HOLD_STR
)
8758 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8759 struct pim_interface
*pim_ifp
= ifp
->info
;
8762 vty_out(vty
, "Pim not enabled on this interface\n");
8763 return CMD_WARNING_CONFIG_FAILED
;
8766 pim_ifp
->pim_hello_period
= PIM_DEFAULT_HELLO_PERIOD
;
8767 pim_ifp
->pim_default_holdtime
= -1;
8778 PIM_DO_DEBUG_IGMP_EVENTS
;
8779 PIM_DO_DEBUG_IGMP_PACKETS
;
8780 PIM_DO_DEBUG_IGMP_TRACE
;
8784 DEFUN (no_debug_igmp
,
8791 PIM_DONT_DEBUG_IGMP_EVENTS
;
8792 PIM_DONT_DEBUG_IGMP_PACKETS
;
8793 PIM_DONT_DEBUG_IGMP_TRACE
;
8798 DEFUN (debug_igmp_events
,
8799 debug_igmp_events_cmd
,
8800 "debug igmp events",
8803 DEBUG_IGMP_EVENTS_STR
)
8805 PIM_DO_DEBUG_IGMP_EVENTS
;
8809 DEFUN (no_debug_igmp_events
,
8810 no_debug_igmp_events_cmd
,
8811 "no debug igmp events",
8815 DEBUG_IGMP_EVENTS_STR
)
8817 PIM_DONT_DEBUG_IGMP_EVENTS
;
8822 DEFUN (debug_igmp_packets
,
8823 debug_igmp_packets_cmd
,
8824 "debug igmp packets",
8827 DEBUG_IGMP_PACKETS_STR
)
8829 PIM_DO_DEBUG_IGMP_PACKETS
;
8833 DEFUN (no_debug_igmp_packets
,
8834 no_debug_igmp_packets_cmd
,
8835 "no debug igmp packets",
8839 DEBUG_IGMP_PACKETS_STR
)
8841 PIM_DONT_DEBUG_IGMP_PACKETS
;
8846 DEFUN (debug_igmp_trace
,
8847 debug_igmp_trace_cmd
,
8851 DEBUG_IGMP_TRACE_STR
)
8853 PIM_DO_DEBUG_IGMP_TRACE
;
8857 DEFUN (no_debug_igmp_trace
,
8858 no_debug_igmp_trace_cmd
,
8859 "no debug igmp trace",
8863 DEBUG_IGMP_TRACE_STR
)
8865 PIM_DONT_DEBUG_IGMP_TRACE
;
8870 DEFUN (debug_mroute
,
8876 PIM_DO_DEBUG_MROUTE
;
8880 DEFUN (debug_mroute_detail
,
8881 debug_mroute_detail_cmd
,
8882 "debug mroute detail",
8887 PIM_DO_DEBUG_MROUTE_DETAIL
;
8891 DEFUN (no_debug_mroute
,
8892 no_debug_mroute_cmd
,
8898 PIM_DONT_DEBUG_MROUTE
;
8902 DEFUN (no_debug_mroute_detail
,
8903 no_debug_mroute_detail_cmd
,
8904 "no debug mroute detail",
8910 PIM_DONT_DEBUG_MROUTE_DETAIL
;
8914 DEFUN (debug_pim_static
,
8915 debug_pim_static_cmd
,
8921 PIM_DO_DEBUG_STATIC
;
8925 DEFUN (no_debug_pim_static
,
8926 no_debug_pim_static_cmd
,
8927 "no debug pim static",
8933 PIM_DONT_DEBUG_STATIC
;
8944 PIM_DO_DEBUG_PIM_EVENTS
;
8945 PIM_DO_DEBUG_PIM_PACKETS
;
8946 PIM_DO_DEBUG_PIM_TRACE
;
8947 PIM_DO_DEBUG_MSDP_EVENTS
;
8948 PIM_DO_DEBUG_MSDP_PACKETS
;
8953 DEFUN (no_debug_pim
,
8960 PIM_DONT_DEBUG_PIM_EVENTS
;
8961 PIM_DONT_DEBUG_PIM_PACKETS
;
8962 PIM_DONT_DEBUG_PIM_TRACE
;
8963 PIM_DONT_DEBUG_MSDP_EVENTS
;
8964 PIM_DONT_DEBUG_MSDP_PACKETS
;
8966 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
8967 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
8973 DEFUN (debug_pim_nht
,
8978 "Nexthop Tracking\n")
8980 PIM_DO_DEBUG_PIM_NHT
;
8984 DEFUN (no_debug_pim_nht
,
8985 no_debug_pim_nht_cmd
,
8990 "Nexthop Tracking\n")
8992 PIM_DONT_DEBUG_PIM_NHT
;
8996 DEFUN (debug_pim_nht_rp
,
8997 debug_pim_nht_rp_cmd
,
9001 "Nexthop Tracking\n"
9002 "RP Nexthop Tracking\n")
9004 PIM_DO_DEBUG_PIM_NHT_RP
;
9008 DEFUN (no_debug_pim_nht_rp
,
9009 no_debug_pim_nht_rp_cmd
,
9010 "no debug pim nht rp",
9014 "Nexthop Tracking\n"
9015 "RP Nexthop Tracking\n")
9017 PIM_DONT_DEBUG_PIM_NHT_RP
;
9021 DEFUN (debug_pim_events
,
9022 debug_pim_events_cmd
,
9026 DEBUG_PIM_EVENTS_STR
)
9028 PIM_DO_DEBUG_PIM_EVENTS
;
9032 DEFUN (no_debug_pim_events
,
9033 no_debug_pim_events_cmd
,
9034 "no debug pim events",
9038 DEBUG_PIM_EVENTS_STR
)
9040 PIM_DONT_DEBUG_PIM_EVENTS
;
9044 DEFUN (debug_pim_packets
,
9045 debug_pim_packets_cmd
,
9046 "debug pim packets [<hello|joins|register>]",
9049 DEBUG_PIM_PACKETS_STR
9050 DEBUG_PIM_HELLO_PACKETS_STR
9051 DEBUG_PIM_J_P_PACKETS_STR
9052 DEBUG_PIM_PIM_REG_PACKETS_STR
)
9055 if (argv_find(argv
, argc
, "hello", &idx
)) {
9056 PIM_DO_DEBUG_PIM_HELLO
;
9057 vty_out(vty
, "PIM Hello debugging is on\n");
9058 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
9059 PIM_DO_DEBUG_PIM_J_P
;
9060 vty_out(vty
, "PIM Join/Prune debugging is on\n");
9061 } else if (argv_find(argv
, argc
, "register", &idx
)) {
9062 PIM_DO_DEBUG_PIM_REG
;
9063 vty_out(vty
, "PIM Register debugging is on\n");
9065 PIM_DO_DEBUG_PIM_PACKETS
;
9066 vty_out(vty
, "PIM Packet debugging is on \n");
9071 DEFUN (no_debug_pim_packets
,
9072 no_debug_pim_packets_cmd
,
9073 "no debug pim packets [<hello|joins|register>]",
9077 DEBUG_PIM_PACKETS_STR
9078 DEBUG_PIM_HELLO_PACKETS_STR
9079 DEBUG_PIM_J_P_PACKETS_STR
9080 DEBUG_PIM_PIM_REG_PACKETS_STR
)
9083 if (argv_find(argv
, argc
, "hello", &idx
)) {
9084 PIM_DONT_DEBUG_PIM_HELLO
;
9085 vty_out(vty
, "PIM Hello debugging is off \n");
9086 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
9087 PIM_DONT_DEBUG_PIM_J_P
;
9088 vty_out(vty
, "PIM Join/Prune debugging is off \n");
9089 } else if (argv_find(argv
, argc
, "register", &idx
)) {
9090 PIM_DONT_DEBUG_PIM_REG
;
9091 vty_out(vty
, "PIM Register debugging is off\n");
9093 PIM_DONT_DEBUG_PIM_PACKETS
;
9099 DEFUN (debug_pim_packetdump_send
,
9100 debug_pim_packetdump_send_cmd
,
9101 "debug pim packet-dump send",
9104 DEBUG_PIM_PACKETDUMP_STR
9105 DEBUG_PIM_PACKETDUMP_SEND_STR
)
9107 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND
;
9111 DEFUN (no_debug_pim_packetdump_send
,
9112 no_debug_pim_packetdump_send_cmd
,
9113 "no debug pim packet-dump send",
9117 DEBUG_PIM_PACKETDUMP_STR
9118 DEBUG_PIM_PACKETDUMP_SEND_STR
)
9120 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
9124 DEFUN (debug_pim_packetdump_recv
,
9125 debug_pim_packetdump_recv_cmd
,
9126 "debug pim packet-dump receive",
9129 DEBUG_PIM_PACKETDUMP_STR
9130 DEBUG_PIM_PACKETDUMP_RECV_STR
)
9132 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV
;
9136 DEFUN (no_debug_pim_packetdump_recv
,
9137 no_debug_pim_packetdump_recv_cmd
,
9138 "no debug pim packet-dump receive",
9142 DEBUG_PIM_PACKETDUMP_STR
9143 DEBUG_PIM_PACKETDUMP_RECV_STR
)
9145 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
9149 DEFUN (debug_pim_trace
,
9150 debug_pim_trace_cmd
,
9154 DEBUG_PIM_TRACE_STR
)
9156 PIM_DO_DEBUG_PIM_TRACE
;
9160 DEFUN (debug_pim_trace_detail
,
9161 debug_pim_trace_detail_cmd
,
9162 "debug pim trace detail",
9166 "Detailed Information\n")
9168 PIM_DO_DEBUG_PIM_TRACE_DETAIL
;
9172 DEFUN (no_debug_pim_trace
,
9173 no_debug_pim_trace_cmd
,
9174 "no debug pim trace",
9178 DEBUG_PIM_TRACE_STR
)
9180 PIM_DONT_DEBUG_PIM_TRACE
;
9184 DEFUN (no_debug_pim_trace_detail
,
9185 no_debug_pim_trace_detail_cmd
,
9186 "no debug pim trace detail",
9191 "Detailed Information\n")
9193 PIM_DONT_DEBUG_PIM_TRACE_DETAIL
;
9197 DEFUN (debug_ssmpingd
,
9203 PIM_DO_DEBUG_SSMPINGD
;
9207 DEFUN (no_debug_ssmpingd
,
9208 no_debug_ssmpingd_cmd
,
9209 "no debug ssmpingd",
9214 PIM_DONT_DEBUG_SSMPINGD
;
9218 DEFUN (debug_pim_zebra
,
9219 debug_pim_zebra_cmd
,
9223 DEBUG_PIM_ZEBRA_STR
)
9229 DEFUN (no_debug_pim_zebra
,
9230 no_debug_pim_zebra_cmd
,
9231 "no debug pim zebra",
9235 DEBUG_PIM_ZEBRA_STR
)
9237 PIM_DONT_DEBUG_ZEBRA
;
9241 DEFUN(debug_pim_mlag
, debug_pim_mlag_cmd
, "debug pim mlag",
9242 DEBUG_STR DEBUG_PIM_STR DEBUG_PIM_MLAG_STR
)
9248 DEFUN(no_debug_pim_mlag
, no_debug_pim_mlag_cmd
, "no debug pim mlag",
9249 NO_STR DEBUG_STR DEBUG_PIM_STR DEBUG_PIM_MLAG_STR
)
9251 PIM_DONT_DEBUG_MLAG
;
9255 DEFUN (debug_pim_vxlan
,
9256 debug_pim_vxlan_cmd
,
9260 DEBUG_PIM_VXLAN_STR
)
9266 DEFUN (no_debug_pim_vxlan
,
9267 no_debug_pim_vxlan_cmd
,
9268 "no debug pim vxlan",
9272 DEBUG_PIM_VXLAN_STR
)
9274 PIM_DONT_DEBUG_VXLAN
;
9284 PIM_DO_DEBUG_MSDP_EVENTS
;
9285 PIM_DO_DEBUG_MSDP_PACKETS
;
9289 DEFUN (no_debug_msdp
,
9296 PIM_DONT_DEBUG_MSDP_EVENTS
;
9297 PIM_DONT_DEBUG_MSDP_PACKETS
;
9301 DEFUN (debug_msdp_events
,
9302 debug_msdp_events_cmd
,
9303 "debug msdp events",
9306 DEBUG_MSDP_EVENTS_STR
)
9308 PIM_DO_DEBUG_MSDP_EVENTS
;
9312 DEFUN (no_debug_msdp_events
,
9313 no_debug_msdp_events_cmd
,
9314 "no debug msdp events",
9318 DEBUG_MSDP_EVENTS_STR
)
9320 PIM_DONT_DEBUG_MSDP_EVENTS
;
9324 DEFUN (debug_msdp_packets
,
9325 debug_msdp_packets_cmd
,
9326 "debug msdp packets",
9329 DEBUG_MSDP_PACKETS_STR
)
9331 PIM_DO_DEBUG_MSDP_PACKETS
;
9335 DEFUN (no_debug_msdp_packets
,
9336 no_debug_msdp_packets_cmd
,
9337 "no debug msdp packets",
9341 DEBUG_MSDP_PACKETS_STR
)
9343 PIM_DONT_DEBUG_MSDP_PACKETS
;
9347 DEFUN (debug_mtrace
,
9353 PIM_DO_DEBUG_MTRACE
;
9357 DEFUN (no_debug_mtrace
,
9358 no_debug_mtrace_cmd
,
9364 PIM_DONT_DEBUG_MTRACE
;
9379 DEFUN (no_debug_bsm
,
9392 DEFUN_NOSH (show_debugging_pim
,
9393 show_debugging_pim_cmd
,
9394 "show debugging [pim]",
9399 vty_out(vty
, "PIM debugging status\n");
9401 pim_debug_config_write(vty
);
9406 static int interface_pim_use_src_cmd_worker(struct vty
*vty
, const char *source
)
9409 struct in_addr source_addr
;
9410 int ret
= CMD_SUCCESS
;
9411 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9413 result
= inet_pton(AF_INET
, source
, &source_addr
);
9415 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", source
,
9416 errno
, safe_strerror(errno
));
9417 return CMD_WARNING_CONFIG_FAILED
;
9420 result
= pim_update_source_set(ifp
, source_addr
);
9424 case PIM_IFACE_NOT_FOUND
:
9425 ret
= CMD_WARNING_CONFIG_FAILED
;
9426 vty_out(vty
, "Pim not enabled on this interface\n");
9428 case PIM_UPDATE_SOURCE_DUP
:
9430 vty_out(vty
, "%% Source already set to %s\n", source
);
9433 ret
= CMD_WARNING_CONFIG_FAILED
;
9434 vty_out(vty
, "%% Source set failed\n");
9440 DEFUN (interface_pim_use_source
,
9441 interface_pim_use_source_cmd
,
9442 "ip pim use-source A.B.C.D",
9445 "Configure primary IP address\n"
9446 "source ip address\n")
9448 return interface_pim_use_src_cmd_worker(vty
, argv
[3]->arg
);
9451 DEFUN (interface_no_pim_use_source
,
9452 interface_no_pim_use_source_cmd
,
9453 "no ip pim use-source [A.B.C.D]",
9457 "Delete source IP address\n"
9458 "source ip address\n")
9460 return interface_pim_use_src_cmd_worker(vty
, "0.0.0.0");
9468 "Enables BFD support\n")
9470 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9471 struct pim_interface
*pim_ifp
= ifp
->info
;
9472 struct bfd_info
*bfd_info
= NULL
;
9475 if (!pim_cmd_interface_add(vty
, ifp
)) {
9477 "Could not enable PIM SM on interface %s\n",
9482 pim_ifp
= ifp
->info
;
9484 bfd_info
= pim_ifp
->bfd_info
;
9486 if (!bfd_info
|| !CHECK_FLAG(bfd_info
->flags
, BFD_FLAG_PARAM_CFG
))
9487 pim_bfd_if_param_set(ifp
, BFD_DEF_MIN_RX
, BFD_DEF_MIN_TX
,
9488 BFD_DEF_DETECT_MULT
, 1);
9493 DEFUN (no_ip_pim_bfd
,
9499 "Disables BFD support\n")
9501 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9502 struct pim_interface
*pim_ifp
= ifp
->info
;
9505 vty_out(vty
, "Pim not enabled on this interface\n");
9509 if (pim_ifp
->bfd_info
) {
9510 pim_bfd_reg_dereg_all_nbr(ifp
, ZEBRA_BFD_DEST_DEREGISTER
);
9511 bfd_info_free(&(pim_ifp
->bfd_info
));
9522 "Enables BSM support on the interface\n")
9524 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9525 struct pim_interface
*pim_ifp
= ifp
->info
;
9528 if (!pim_cmd_interface_add(vty
, ifp
)) {
9530 "Could not enable PIM SM on interface %s\n",
9536 pim_ifp
= ifp
->info
;
9537 pim_ifp
->bsm_enable
= true;
9542 DEFUN (no_ip_pim_bsm
,
9548 "Disables BSM support\n")
9550 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9551 struct pim_interface
*pim_ifp
= ifp
->info
;
9554 vty_out(vty
, "Pim not enabled on this interface\n");
9558 pim_ifp
->bsm_enable
= false;
9563 DEFUN (ip_pim_ucast_bsm
,
9564 ip_pim_ucast_bsm_cmd
,
9565 "ip pim unicast-bsm",
9568 "Accept/Send unicast BSM on the interface\n")
9570 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9571 struct pim_interface
*pim_ifp
= ifp
->info
;
9574 if (!pim_cmd_interface_add(vty
, ifp
)) {
9576 "Could not enable PIM SM on interface %s\n",
9582 pim_ifp
= ifp
->info
;
9583 pim_ifp
->ucast_bsm_accept
= true;
9588 DEFUN (no_ip_pim_ucast_bsm
,
9589 no_ip_pim_ucast_bsm_cmd
,
9590 "no ip pim unicast-bsm",
9594 "Block send/receive unicast BSM on this interface\n")
9596 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9597 struct pim_interface
*pim_ifp
= ifp
->info
;
9600 vty_out(vty
, "Pim not enabled on this interface\n");
9604 pim_ifp
->ucast_bsm_accept
= false;
9612 ip_pim_bfd_param_cmd
,
9613 "ip pim bfd (2-255) (50-60000) (50-60000)",
9616 "Enables BFD support\n"
9617 "Detect Multiplier\n"
9618 "Required min receive interval\n"
9619 "Desired min transmit interval\n")
9623 ip_pim_bfd_param_cmd
,
9624 "ip pim bfd (2-255) (50-60000) (50-60000)",
9627 "Enables BFD support\n"
9628 "Detect Multiplier\n"
9629 "Required min receive interval\n"
9630 "Desired min transmit interval\n")
9631 #endif /* HAVE_BFDD */
9633 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9635 int idx_number_2
= 4;
9636 int idx_number_3
= 5;
9641 struct pim_interface
*pim_ifp
= ifp
->info
;
9644 if (!pim_cmd_interface_add(vty
, ifp
)) {
9646 "Could not enable PIM SM on interface %s\n",
9652 if ((ret
= bfd_validate_param(
9653 vty
, argv
[idx_number
]->arg
, argv
[idx_number_2
]->arg
,
9654 argv
[idx_number_3
]->arg
, &dm_val
, &rx_val
, &tx_val
))
9658 pim_bfd_if_param_set(ifp
, rx_val
, tx_val
, dm_val
, 0);
9664 ALIAS(no_ip_pim_bfd
, no_ip_pim_bfd_param_cmd
,
9665 "no ip pim bfd (2-255) (50-60000) (50-60000)", NO_STR IP_STR PIM_STR
9666 "Enables BFD support\n"
9667 "Detect Multiplier\n"
9668 "Required min receive interval\n"
9669 "Desired min transmit interval\n")
9670 #endif /* !HAVE_BFDD */
9672 static int ip_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
9673 const char *peer
, const char *local
)
9675 enum pim_msdp_err result
;
9676 struct in_addr peer_addr
;
9677 struct in_addr local_addr
;
9678 int ret
= CMD_SUCCESS
;
9680 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
9682 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
9683 errno
, safe_strerror(errno
));
9684 return CMD_WARNING_CONFIG_FAILED
;
9687 result
= inet_pton(AF_INET
, local
, &local_addr
);
9689 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", local
,
9690 errno
, safe_strerror(errno
));
9691 return CMD_WARNING_CONFIG_FAILED
;
9694 result
= pim_msdp_peer_add(pim
, peer_addr
, local_addr
, "default",
9697 case PIM_MSDP_ERR_NONE
:
9699 case PIM_MSDP_ERR_OOM
:
9700 ret
= CMD_WARNING_CONFIG_FAILED
;
9701 vty_out(vty
, "%% Out of memory\n");
9703 case PIM_MSDP_ERR_PEER_EXISTS
:
9705 vty_out(vty
, "%% Peer exists\n");
9707 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
9708 ret
= CMD_WARNING_CONFIG_FAILED
;
9709 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
9712 ret
= CMD_WARNING_CONFIG_FAILED
;
9713 vty_out(vty
, "%% peer add failed\n");
9719 DEFUN (ip_msdp_peer
,
9721 "ip msdp peer A.B.C.D source A.B.C.D",
9724 "Configure MSDP peer\n"
9726 "Source address for TCP connection\n"
9727 "local ip address\n")
9729 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9730 return ip_msdp_peer_cmd_worker(pim
, vty
, argv
[3]->arg
, argv
[5]->arg
);
9733 static int ip_no_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
9736 enum pim_msdp_err result
;
9737 struct in_addr peer_addr
;
9739 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
9741 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
9742 errno
, safe_strerror(errno
));
9743 return CMD_WARNING_CONFIG_FAILED
;
9746 result
= pim_msdp_peer_del(pim
, peer_addr
);
9748 case PIM_MSDP_ERR_NONE
:
9750 case PIM_MSDP_ERR_NO_PEER
:
9751 vty_out(vty
, "%% Peer does not exist\n");
9754 vty_out(vty
, "%% peer del failed\n");
9757 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9760 DEFUN (no_ip_msdp_peer
,
9761 no_ip_msdp_peer_cmd
,
9762 "no ip msdp peer A.B.C.D",
9766 "Delete MSDP peer\n"
9767 "peer ip address\n")
9769 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9770 return ip_no_msdp_peer_cmd_worker(pim
, vty
, argv
[4]->arg
);
9773 static int ip_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
9774 struct vty
*vty
, const char *mg
,
9777 enum pim_msdp_err result
;
9778 struct in_addr mbr_ip
;
9779 int ret
= CMD_SUCCESS
;
9781 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
9783 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
9784 errno
, safe_strerror(errno
));
9785 return CMD_WARNING_CONFIG_FAILED
;
9788 result
= pim_msdp_mg_mbr_add(pim
, mg
, mbr_ip
);
9790 case PIM_MSDP_ERR_NONE
:
9792 case PIM_MSDP_ERR_OOM
:
9793 ret
= CMD_WARNING_CONFIG_FAILED
;
9794 vty_out(vty
, "%% Out of memory\n");
9796 case PIM_MSDP_ERR_MG_MBR_EXISTS
:
9798 vty_out(vty
, "%% mesh-group member exists\n");
9800 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
9801 ret
= CMD_WARNING_CONFIG_FAILED
;
9802 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
9805 ret
= CMD_WARNING_CONFIG_FAILED
;
9806 vty_out(vty
, "%% member add failed\n");
9812 DEFUN (ip_msdp_mesh_group_member
,
9813 ip_msdp_mesh_group_member_cmd
,
9814 "ip msdp mesh-group WORD member A.B.C.D",
9817 "Configure MSDP mesh-group\n"
9819 "mesh group member\n"
9820 "peer ip address\n")
9822 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9823 return ip_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[3]->arg
,
9827 static int ip_no_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
9832 enum pim_msdp_err result
;
9833 struct in_addr mbr_ip
;
9835 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
9837 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
9838 errno
, safe_strerror(errno
));
9839 return CMD_WARNING_CONFIG_FAILED
;
9842 result
= pim_msdp_mg_mbr_del(pim
, mg
, mbr_ip
);
9844 case PIM_MSDP_ERR_NONE
:
9846 case PIM_MSDP_ERR_NO_MG
:
9847 vty_out(vty
, "%% mesh-group does not exist\n");
9849 case PIM_MSDP_ERR_NO_MG_MBR
:
9850 vty_out(vty
, "%% mesh-group member does not exist\n");
9853 vty_out(vty
, "%% mesh-group member del failed\n");
9856 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9858 DEFUN (no_ip_msdp_mesh_group_member
,
9859 no_ip_msdp_mesh_group_member_cmd
,
9860 "no ip msdp mesh-group WORD member A.B.C.D",
9864 "Delete MSDP mesh-group member\n"
9866 "mesh group member\n"
9867 "peer ip address\n")
9869 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9870 return ip_no_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[4]->arg
,
9874 static int ip_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
9875 struct vty
*vty
, const char *mg
,
9878 enum pim_msdp_err result
;
9879 struct in_addr src_ip
;
9881 result
= inet_pton(AF_INET
, src
, &src_ip
);
9883 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", src
,
9884 errno
, safe_strerror(errno
));
9885 return CMD_WARNING_CONFIG_FAILED
;
9888 result
= pim_msdp_mg_src_add(pim
, mg
, src_ip
);
9890 case PIM_MSDP_ERR_NONE
:
9892 case PIM_MSDP_ERR_OOM
:
9893 vty_out(vty
, "%% Out of memory\n");
9895 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
9896 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
9899 vty_out(vty
, "%% source add failed\n");
9902 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9906 DEFUN (ip_msdp_mesh_group_source
,
9907 ip_msdp_mesh_group_source_cmd
,
9908 "ip msdp mesh-group WORD source A.B.C.D",
9911 "Configure MSDP mesh-group\n"
9913 "mesh group local address\n"
9914 "source ip address for the TCP connection\n")
9916 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9917 return ip_msdp_mesh_group_source_cmd_worker(pim
, vty
, argv
[3]->arg
,
9921 static int ip_no_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
9925 enum pim_msdp_err result
;
9927 result
= pim_msdp_mg_src_del(pim
, mg
);
9929 case PIM_MSDP_ERR_NONE
:
9931 case PIM_MSDP_ERR_NO_MG
:
9932 vty_out(vty
, "%% mesh-group does not exist\n");
9935 vty_out(vty
, "%% mesh-group source del failed\n");
9938 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9941 static int ip_no_msdp_mesh_group_cmd_worker(struct pim_instance
*pim
,
9942 struct vty
*vty
, const char *mg
)
9944 enum pim_msdp_err result
;
9946 result
= pim_msdp_mg_del(pim
, mg
);
9948 case PIM_MSDP_ERR_NONE
:
9950 case PIM_MSDP_ERR_NO_MG
:
9951 vty_out(vty
, "%% mesh-group does not exist\n");
9954 vty_out(vty
, "%% mesh-group source del failed\n");
9957 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9960 DEFUN (no_ip_msdp_mesh_group_source
,
9961 no_ip_msdp_mesh_group_source_cmd
,
9962 "no ip msdp mesh-group WORD source [A.B.C.D]",
9966 "Delete MSDP mesh-group source\n"
9968 "mesh group source\n"
9969 "mesh group local address\n")
9971 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9973 return ip_no_msdp_mesh_group_source_cmd_worker(pim
, vty
, argv
[4]->arg
);
9976 DEFUN (no_ip_msdp_mesh_group
,
9977 no_ip_msdp_mesh_group_cmd
,
9978 "no ip msdp mesh-group [WORD]",
9982 "Delete MSDP mesh-group\n"
9985 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9988 return ip_no_msdp_mesh_group_cmd_worker(pim
, vty
, argv
[4]->arg
);
9990 return ip_no_msdp_mesh_group_cmd_worker(pim
, vty
, NULL
);
9993 static void print_empty_json_obj(struct vty
*vty
)
9996 json
= json_object_new_object();
9997 vty_out(vty
, "%s\n",
9998 json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
));
9999 json_object_free(json
);
10002 static void ip_msdp_show_mesh_group(struct pim_instance
*pim
, struct vty
*vty
,
10005 struct listnode
*mbrnode
;
10006 struct pim_msdp_mg_mbr
*mbr
;
10007 struct pim_msdp_mg
*mg
= pim
->msdp
.mg
;
10008 char mbr_str
[INET_ADDRSTRLEN
];
10009 char src_str
[INET_ADDRSTRLEN
];
10010 char state_str
[PIM_MSDP_STATE_STRLEN
];
10011 enum pim_msdp_peer_state state
;
10012 json_object
*json
= NULL
;
10013 json_object
*json_mg_row
= NULL
;
10014 json_object
*json_members
= NULL
;
10015 json_object
*json_row
= NULL
;
10019 print_empty_json_obj(vty
);
10023 pim_inet4_dump("<source?>", mg
->src_ip
, src_str
, sizeof(src_str
));
10025 json
= json_object_new_object();
10026 /* currently there is only one mesh group but we should still
10028 * it a dict with mg-name as key */
10029 json_mg_row
= json_object_new_object();
10030 json_object_string_add(json_mg_row
, "name",
10031 mg
->mesh_group_name
);
10032 json_object_string_add(json_mg_row
, "source", src_str
);
10034 vty_out(vty
, "Mesh group : %s\n", mg
->mesh_group_name
);
10035 vty_out(vty
, " Source : %s\n", src_str
);
10036 vty_out(vty
, " Member State\n");
10039 for (ALL_LIST_ELEMENTS_RO(mg
->mbr_list
, mbrnode
, mbr
)) {
10040 pim_inet4_dump("<mbr?>", mbr
->mbr_ip
, mbr_str
, sizeof(mbr_str
));
10042 state
= mbr
->mp
->state
;
10044 state
= PIM_MSDP_DISABLED
;
10046 pim_msdp_state_dump(state
, state_str
, sizeof(state_str
));
10048 json_row
= json_object_new_object();
10049 json_object_string_add(json_row
, "member", mbr_str
);
10050 json_object_string_add(json_row
, "state", state_str
);
10051 if (!json_members
) {
10052 json_members
= json_object_new_object();
10053 json_object_object_add(json_mg_row
, "members",
10056 json_object_object_add(json_members
, mbr_str
, json_row
);
10058 vty_out(vty
, " %-15s %11s\n", mbr_str
, state_str
);
10063 json_object_object_add(json
, mg
->mesh_group_name
, json_mg_row
);
10064 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10065 json
, JSON_C_TO_STRING_PRETTY
));
10066 json_object_free(json
);
10070 DEFUN (show_ip_msdp_mesh_group
,
10071 show_ip_msdp_mesh_group_cmd
,
10072 "show ip msdp [vrf NAME] mesh-group [json]",
10077 "MSDP mesh-group information\n"
10080 bool uj
= use_json(argc
, argv
);
10082 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10085 return CMD_WARNING
;
10087 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
10089 return CMD_SUCCESS
;
10092 DEFUN (show_ip_msdp_mesh_group_vrf_all
,
10093 show_ip_msdp_mesh_group_vrf_all_cmd
,
10094 "show ip msdp vrf all mesh-group [json]",
10099 "MSDP mesh-group information\n"
10102 bool uj
= use_json(argc
, argv
);
10107 vty_out(vty
, "{ ");
10108 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
10111 vty_out(vty
, ", ");
10112 vty_out(vty
, " \"%s\": ", vrf
->name
);
10115 vty_out(vty
, "VRF: %s\n", vrf
->name
);
10116 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
10119 vty_out(vty
, "}\n");
10121 return CMD_SUCCESS
;
10124 static void ip_msdp_show_peers(struct pim_instance
*pim
, struct vty
*vty
,
10127 struct listnode
*mpnode
;
10128 struct pim_msdp_peer
*mp
;
10129 char peer_str
[INET_ADDRSTRLEN
];
10130 char local_str
[INET_ADDRSTRLEN
];
10131 char state_str
[PIM_MSDP_STATE_STRLEN
];
10132 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
10134 json_object
*json
= NULL
;
10135 json_object
*json_row
= NULL
;
10139 json
= json_object_new_object();
10142 "Peer Local State Uptime SaCnt\n");
10145 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
10146 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
10147 now
= pim_time_monotonic_sec();
10148 pim_time_uptime(timebuf
, sizeof(timebuf
),
10151 strlcpy(timebuf
, "-", sizeof(timebuf
));
10153 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
10154 pim_inet4_dump("<local?>", mp
->local
, local_str
,
10155 sizeof(local_str
));
10156 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
10158 json_row
= json_object_new_object();
10159 json_object_string_add(json_row
, "peer", peer_str
);
10160 json_object_string_add(json_row
, "local", local_str
);
10161 json_object_string_add(json_row
, "state", state_str
);
10162 json_object_string_add(json_row
, "upTime", timebuf
);
10163 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
10164 json_object_object_add(json
, peer_str
, json_row
);
10166 vty_out(vty
, "%-15s %15s %11s %8s %6d\n", peer_str
,
10167 local_str
, state_str
, timebuf
, mp
->sa_cnt
);
10172 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10173 json
, JSON_C_TO_STRING_PRETTY
));
10174 json_object_free(json
);
10178 static void ip_msdp_show_peers_detail(struct pim_instance
*pim
, struct vty
*vty
,
10179 const char *peer
, bool uj
)
10181 struct listnode
*mpnode
;
10182 struct pim_msdp_peer
*mp
;
10183 char peer_str
[INET_ADDRSTRLEN
];
10184 char local_str
[INET_ADDRSTRLEN
];
10185 char state_str
[PIM_MSDP_STATE_STRLEN
];
10186 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
10187 char katimer
[PIM_MSDP_TIMER_STRLEN
];
10188 char crtimer
[PIM_MSDP_TIMER_STRLEN
];
10189 char holdtimer
[PIM_MSDP_TIMER_STRLEN
];
10191 json_object
*json
= NULL
;
10192 json_object
*json_row
= NULL
;
10195 json
= json_object_new_object();
10198 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
10199 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
10200 if (strcmp(peer
, "detail") && strcmp(peer
, peer_str
))
10203 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
10204 now
= pim_time_monotonic_sec();
10205 pim_time_uptime(timebuf
, sizeof(timebuf
),
10208 strlcpy(timebuf
, "-", sizeof(timebuf
));
10210 pim_inet4_dump("<local?>", mp
->local
, local_str
,
10211 sizeof(local_str
));
10212 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
10213 pim_time_timer_to_hhmmss(katimer
, sizeof(katimer
),
10215 pim_time_timer_to_hhmmss(crtimer
, sizeof(crtimer
),
10217 pim_time_timer_to_hhmmss(holdtimer
, sizeof(holdtimer
),
10221 json_row
= json_object_new_object();
10222 json_object_string_add(json_row
, "peer", peer_str
);
10223 json_object_string_add(json_row
, "local", local_str
);
10224 json_object_string_add(json_row
, "meshGroupName",
10225 mp
->mesh_group_name
);
10226 json_object_string_add(json_row
, "state", state_str
);
10227 json_object_string_add(json_row
, "upTime", timebuf
);
10228 json_object_string_add(json_row
, "keepAliveTimer",
10230 json_object_string_add(json_row
, "connRetryTimer",
10232 json_object_string_add(json_row
, "holdTimer",
10234 json_object_string_add(json_row
, "lastReset",
10236 json_object_int_add(json_row
, "connAttempts",
10237 mp
->conn_attempts
);
10238 json_object_int_add(json_row
, "establishedChanges",
10240 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
10241 json_object_int_add(json_row
, "kaSent", mp
->ka_tx_cnt
);
10242 json_object_int_add(json_row
, "kaRcvd", mp
->ka_rx_cnt
);
10243 json_object_int_add(json_row
, "saSent", mp
->sa_tx_cnt
);
10244 json_object_int_add(json_row
, "saRcvd", mp
->sa_rx_cnt
);
10245 json_object_object_add(json
, peer_str
, json_row
);
10247 vty_out(vty
, "Peer : %s\n", peer_str
);
10248 vty_out(vty
, " Local : %s\n", local_str
);
10249 vty_out(vty
, " Mesh Group : %s\n",
10250 mp
->mesh_group_name
);
10251 vty_out(vty
, " State : %s\n", state_str
);
10252 vty_out(vty
, " Uptime : %s\n", timebuf
);
10254 vty_out(vty
, " Keepalive Timer : %s\n", katimer
);
10255 vty_out(vty
, " Conn Retry Timer : %s\n", crtimer
);
10256 vty_out(vty
, " Hold Timer : %s\n", holdtimer
);
10257 vty_out(vty
, " Last Reset : %s\n",
10259 vty_out(vty
, " Conn Attempts : %d\n",
10260 mp
->conn_attempts
);
10261 vty_out(vty
, " Established Changes : %d\n",
10263 vty_out(vty
, " SA Count : %d\n",
10265 vty_out(vty
, " Statistics :\n");
10268 vty_out(vty
, " Keepalives : %10d %10d\n",
10269 mp
->ka_tx_cnt
, mp
->ka_rx_cnt
);
10270 vty_out(vty
, " SAs : %10d %10d\n",
10271 mp
->sa_tx_cnt
, mp
->sa_rx_cnt
);
10272 vty_out(vty
, "\n");
10277 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10278 json
, JSON_C_TO_STRING_PRETTY
));
10279 json_object_free(json
);
10283 DEFUN (show_ip_msdp_peer_detail
,
10284 show_ip_msdp_peer_detail_cmd
,
10285 "show ip msdp [vrf NAME] peer [detail|A.B.C.D] [json]",
10290 "MSDP peer information\n"
10291 "Detailed output\n"
10292 "peer ip address\n"
10295 bool uj
= use_json(argc
, argv
);
10297 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10300 return CMD_WARNING
;
10304 if (argv_find(argv
, argc
, "detail", &idx
))
10305 arg
= argv
[idx
]->text
;
10306 else if (argv_find(argv
, argc
, "A.B.C.D", &idx
))
10307 arg
= argv
[idx
]->arg
;
10310 ip_msdp_show_peers_detail(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
10312 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
10314 return CMD_SUCCESS
;
10317 DEFUN (show_ip_msdp_peer_detail_vrf_all
,
10318 show_ip_msdp_peer_detail_vrf_all_cmd
,
10319 "show ip msdp vrf all peer [detail|A.B.C.D] [json]",
10324 "MSDP peer information\n"
10325 "Detailed output\n"
10326 "peer ip address\n"
10330 bool uj
= use_json(argc
, argv
);
10335 vty_out(vty
, "{ ");
10336 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
10339 vty_out(vty
, ", ");
10340 vty_out(vty
, " \"%s\": ", vrf
->name
);
10343 vty_out(vty
, "VRF: %s\n", vrf
->name
);
10344 if (argv_find(argv
, argc
, "detail", &idx
)
10345 || argv_find(argv
, argc
, "A.B.C.D", &idx
))
10346 ip_msdp_show_peers_detail(vrf
->info
, vty
,
10347 argv
[idx
]->arg
, uj
);
10349 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
10352 vty_out(vty
, "}\n");
10354 return CMD_SUCCESS
;
10357 static void ip_msdp_show_sa(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
10359 struct listnode
*sanode
;
10360 struct pim_msdp_sa
*sa
;
10361 char src_str
[INET_ADDRSTRLEN
];
10362 char grp_str
[INET_ADDRSTRLEN
];
10363 char rp_str
[INET_ADDRSTRLEN
];
10364 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
10368 json_object
*json
= NULL
;
10369 json_object
*json_group
= NULL
;
10370 json_object
*json_row
= NULL
;
10373 json
= json_object_new_object();
10376 "Source Group RP Local SPT Uptime\n");
10379 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
10380 now
= pim_time_monotonic_sec();
10381 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
10382 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
10383 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
10384 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
10385 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
10387 strlcpy(spt_str
, "yes", sizeof(spt_str
));
10389 strlcpy(spt_str
, "no", sizeof(spt_str
));
10392 strlcpy(rp_str
, "-", sizeof(rp_str
));
10393 strlcpy(spt_str
, "-", sizeof(spt_str
));
10395 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
10396 strlcpy(local_str
, "yes", sizeof(local_str
));
10398 strlcpy(local_str
, "no", sizeof(local_str
));
10401 json_object_object_get_ex(json
, grp_str
, &json_group
);
10404 json_group
= json_object_new_object();
10405 json_object_object_add(json
, grp_str
,
10409 json_row
= json_object_new_object();
10410 json_object_string_add(json_row
, "source", src_str
);
10411 json_object_string_add(json_row
, "group", grp_str
);
10412 json_object_string_add(json_row
, "rp", rp_str
);
10413 json_object_string_add(json_row
, "local", local_str
);
10414 json_object_string_add(json_row
, "sptSetup", spt_str
);
10415 json_object_string_add(json_row
, "upTime", timebuf
);
10416 json_object_object_add(json_group
, src_str
, json_row
);
10418 vty_out(vty
, "%-15s %15s %15s %5c %3c %8s\n",
10419 src_str
, grp_str
, rp_str
, local_str
[0],
10420 spt_str
[0], timebuf
);
10425 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10426 json
, JSON_C_TO_STRING_PRETTY
));
10427 json_object_free(json
);
10431 static void ip_msdp_show_sa_entry_detail(struct pim_msdp_sa
*sa
,
10432 const char *src_str
,
10433 const char *grp_str
, struct vty
*vty
,
10434 bool uj
, json_object
*json
)
10436 char rp_str
[INET_ADDRSTRLEN
];
10437 char peer_str
[INET_ADDRSTRLEN
];
10438 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
10441 char statetimer
[PIM_MSDP_TIMER_STRLEN
];
10443 json_object
*json_group
= NULL
;
10444 json_object
*json_row
= NULL
;
10446 now
= pim_time_monotonic_sec();
10447 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
10448 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
10449 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
10450 pim_inet4_dump("<peer?>", sa
->peer
, peer_str
, sizeof(peer_str
));
10452 strlcpy(spt_str
, "yes", sizeof(spt_str
));
10454 strlcpy(spt_str
, "no", sizeof(spt_str
));
10457 strlcpy(rp_str
, "-", sizeof(rp_str
));
10458 strlcpy(peer_str
, "-", sizeof(peer_str
));
10459 strlcpy(spt_str
, "-", sizeof(spt_str
));
10461 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
10462 strlcpy(local_str
, "yes", sizeof(local_str
));
10464 strlcpy(local_str
, "no", sizeof(local_str
));
10466 pim_time_timer_to_hhmmss(statetimer
, sizeof(statetimer
),
10467 sa
->sa_state_timer
);
10469 json_object_object_get_ex(json
, grp_str
, &json_group
);
10472 json_group
= json_object_new_object();
10473 json_object_object_add(json
, grp_str
, json_group
);
10476 json_row
= json_object_new_object();
10477 json_object_string_add(json_row
, "source", src_str
);
10478 json_object_string_add(json_row
, "group", grp_str
);
10479 json_object_string_add(json_row
, "rp", rp_str
);
10480 json_object_string_add(json_row
, "local", local_str
);
10481 json_object_string_add(json_row
, "sptSetup", spt_str
);
10482 json_object_string_add(json_row
, "upTime", timebuf
);
10483 json_object_string_add(json_row
, "stateTimer", statetimer
);
10484 json_object_object_add(json_group
, src_str
, json_row
);
10486 vty_out(vty
, "SA : %s\n", sa
->sg_str
);
10487 vty_out(vty
, " RP : %s\n", rp_str
);
10488 vty_out(vty
, " Peer : %s\n", peer_str
);
10489 vty_out(vty
, " Local : %s\n", local_str
);
10490 vty_out(vty
, " SPT Setup : %s\n", spt_str
);
10491 vty_out(vty
, " Uptime : %s\n", timebuf
);
10492 vty_out(vty
, " State Timer : %s\n", statetimer
);
10493 vty_out(vty
, "\n");
10497 static void ip_msdp_show_sa_detail(struct pim_instance
*pim
, struct vty
*vty
,
10500 struct listnode
*sanode
;
10501 struct pim_msdp_sa
*sa
;
10502 char src_str
[INET_ADDRSTRLEN
];
10503 char grp_str
[INET_ADDRSTRLEN
];
10504 json_object
*json
= NULL
;
10507 json
= json_object_new_object();
10510 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
10511 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
10512 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
10513 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
, uj
,
10518 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10519 json
, JSON_C_TO_STRING_PRETTY
));
10520 json_object_free(json
);
10524 DEFUN (show_ip_msdp_sa_detail
,
10525 show_ip_msdp_sa_detail_cmd
,
10526 "show ip msdp [vrf NAME] sa detail [json]",
10531 "MSDP active-source information\n"
10532 "Detailed output\n"
10535 bool uj
= use_json(argc
, argv
);
10537 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10540 return CMD_WARNING
;
10542 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
10544 return CMD_SUCCESS
;
10547 DEFUN (show_ip_msdp_sa_detail_vrf_all
,
10548 show_ip_msdp_sa_detail_vrf_all_cmd
,
10549 "show ip msdp vrf all sa detail [json]",
10554 "MSDP active-source information\n"
10555 "Detailed output\n"
10558 bool uj
= use_json(argc
, argv
);
10563 vty_out(vty
, "{ ");
10564 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
10567 vty_out(vty
, ", ");
10568 vty_out(vty
, " \"%s\": ", vrf
->name
);
10571 vty_out(vty
, "VRF: %s\n", vrf
->name
);
10572 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
10575 vty_out(vty
, "}\n");
10577 return CMD_SUCCESS
;
10580 static void ip_msdp_show_sa_addr(struct pim_instance
*pim
, struct vty
*vty
,
10581 const char *addr
, bool uj
)
10583 struct listnode
*sanode
;
10584 struct pim_msdp_sa
*sa
;
10585 char src_str
[INET_ADDRSTRLEN
];
10586 char grp_str
[INET_ADDRSTRLEN
];
10587 json_object
*json
= NULL
;
10590 json
= json_object_new_object();
10593 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
10594 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
10595 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
10596 if (!strcmp(addr
, src_str
) || !strcmp(addr
, grp_str
)) {
10597 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
10603 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10604 json
, JSON_C_TO_STRING_PRETTY
));
10605 json_object_free(json
);
10609 static void ip_msdp_show_sa_sg(struct pim_instance
*pim
, struct vty
*vty
,
10610 const char *src
, const char *grp
, bool uj
)
10612 struct listnode
*sanode
;
10613 struct pim_msdp_sa
*sa
;
10614 char src_str
[INET_ADDRSTRLEN
];
10615 char grp_str
[INET_ADDRSTRLEN
];
10616 json_object
*json
= NULL
;
10619 json
= json_object_new_object();
10622 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
10623 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
10624 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
10625 if (!strcmp(src
, src_str
) && !strcmp(grp
, grp_str
)) {
10626 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
10632 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10633 json
, JSON_C_TO_STRING_PRETTY
));
10634 json_object_free(json
);
10638 DEFUN (show_ip_msdp_sa_sg
,
10639 show_ip_msdp_sa_sg_cmd
,
10640 "show ip msdp [vrf NAME] sa [A.B.C.D [A.B.C.D]] [json]",
10645 "MSDP active-source information\n"
10646 "source or group ip\n"
10650 bool uj
= use_json(argc
, argv
);
10654 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10657 return CMD_WARNING
;
10659 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
10661 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
10665 if (src_ip
&& grp_ip
)
10666 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
10668 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
10670 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
10672 return CMD_SUCCESS
;
10675 DEFUN (show_ip_msdp_sa_sg_vrf_all
,
10676 show_ip_msdp_sa_sg_vrf_all_cmd
,
10677 "show ip msdp vrf all sa [A.B.C.D [A.B.C.D]] [json]",
10682 "MSDP active-source information\n"
10683 "source or group ip\n"
10687 bool uj
= use_json(argc
, argv
);
10692 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
10694 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
10699 vty_out(vty
, "{ ");
10700 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
10703 vty_out(vty
, ", ");
10704 vty_out(vty
, " \"%s\": ", vrf
->name
);
10707 vty_out(vty
, "VRF: %s\n", vrf
->name
);
10709 if (src_ip
&& grp_ip
)
10710 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
10712 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
10714 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
10717 vty_out(vty
, "}\n");
10719 return CMD_SUCCESS
;
10722 struct pim_sg_cache_walk_data
{
10725 json_object
*json_group
;
10726 struct in_addr addr
;
10730 static void pim_show_vxlan_sg_entry(struct pim_vxlan_sg
*vxlan_sg
,
10731 struct pim_sg_cache_walk_data
*cwd
)
10733 struct vty
*vty
= cwd
->vty
;
10734 json_object
*json
= cwd
->json
;
10735 char src_str
[INET_ADDRSTRLEN
];
10736 char grp_str
[INET_ADDRSTRLEN
];
10737 json_object
*json_row
;
10738 bool installed
= (vxlan_sg
->up
) ? true : false;
10739 const char *iif_name
= vxlan_sg
->iif
?vxlan_sg
->iif
->name
:"-";
10740 const char *oif_name
;
10742 if (pim_vxlan_is_orig_mroute(vxlan_sg
))
10743 oif_name
= vxlan_sg
->orig_oif
?vxlan_sg
->orig_oif
->name
:"";
10745 oif_name
= vxlan_sg
->term_oif
?vxlan_sg
->term_oif
->name
:"";
10747 if (cwd
->addr_match
&& (vxlan_sg
->sg
.src
.s_addr
!= cwd
->addr
.s_addr
) &&
10748 (vxlan_sg
->sg
.grp
.s_addr
!= cwd
->addr
.s_addr
)) {
10751 pim_inet4_dump("<src?>", vxlan_sg
->sg
.src
, src_str
, sizeof(src_str
));
10752 pim_inet4_dump("<grp?>", vxlan_sg
->sg
.grp
, grp_str
, sizeof(grp_str
));
10754 json_object_object_get_ex(json
, grp_str
, &cwd
->json_group
);
10756 if (!cwd
->json_group
) {
10757 cwd
->json_group
= json_object_new_object();
10758 json_object_object_add(json
, grp_str
,
10762 json_row
= json_object_new_object();
10763 json_object_string_add(json_row
, "source", src_str
);
10764 json_object_string_add(json_row
, "group", grp_str
);
10765 json_object_string_add(json_row
, "input", iif_name
);
10766 json_object_string_add(json_row
, "output", oif_name
);
10768 json_object_boolean_true_add(json_row
, "installed");
10770 json_object_boolean_false_add(json_row
, "installed");
10771 json_object_object_add(cwd
->json_group
, src_str
, json_row
);
10773 vty_out(vty
, "%-15s %-15s %-15s %-15s %-5s\n",
10774 src_str
, grp_str
, iif_name
, oif_name
,
10779 static void pim_show_vxlan_sg_hash_entry(struct hash_bucket
*backet
, void *arg
)
10781 pim_show_vxlan_sg_entry((struct pim_vxlan_sg
*)backet
->data
,
10782 (struct pim_sg_cache_walk_data
*)arg
);
10785 static void pim_show_vxlan_sg(struct pim_instance
*pim
,
10786 struct vty
*vty
, bool uj
)
10788 json_object
*json
= NULL
;
10789 struct pim_sg_cache_walk_data cwd
;
10792 json
= json_object_new_object();
10794 vty_out(vty
, "Codes: I -> installed\n");
10796 "Source Group Input Output Flags\n");
10799 memset(&cwd
, 0, sizeof(cwd
));
10802 hash_iterate(pim
->vxlan
.sg_hash
, pim_show_vxlan_sg_hash_entry
, &cwd
);
10805 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10806 json
, JSON_C_TO_STRING_PRETTY
));
10807 json_object_free(json
);
10811 static void pim_show_vxlan_sg_match_addr(struct pim_instance
*pim
,
10812 struct vty
*vty
, char *addr_str
, bool uj
)
10814 json_object
*json
= NULL
;
10815 struct pim_sg_cache_walk_data cwd
;
10818 memset(&cwd
, 0, sizeof(cwd
));
10819 result
= inet_pton(AF_INET
, addr_str
, &cwd
.addr
);
10821 vty_out(vty
, "Bad address %s: errno=%d: %s\n", addr_str
,
10822 errno
, safe_strerror(errno
));
10827 json
= json_object_new_object();
10829 vty_out(vty
, "Codes: I -> installed\n");
10831 "Source Group Input Output Flags\n");
10836 cwd
.addr_match
= true;
10837 hash_iterate(pim
->vxlan
.sg_hash
, pim_show_vxlan_sg_hash_entry
, &cwd
);
10840 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10841 json
, JSON_C_TO_STRING_PRETTY
));
10842 json_object_free(json
);
10846 static void pim_show_vxlan_sg_one(struct pim_instance
*pim
,
10847 struct vty
*vty
, char *src_str
, char *grp_str
, bool uj
)
10849 json_object
*json
= NULL
;
10850 struct prefix_sg sg
;
10852 struct pim_vxlan_sg
*vxlan_sg
;
10853 const char *iif_name
;
10855 const char *oif_name
;
10857 result
= inet_pton(AF_INET
, src_str
, &sg
.src
);
10859 vty_out(vty
, "Bad src address %s: errno=%d: %s\n", src_str
,
10860 errno
, safe_strerror(errno
));
10863 result
= inet_pton(AF_INET
, grp_str
, &sg
.grp
);
10865 vty_out(vty
, "Bad grp address %s: errno=%d: %s\n", grp_str
,
10866 errno
, safe_strerror(errno
));
10870 sg
.family
= AF_INET
;
10871 sg
.prefixlen
= IPV4_MAX_BITLEN
;
10873 json
= json_object_new_object();
10875 vxlan_sg
= pim_vxlan_sg_find(pim
, &sg
);
10877 installed
= (vxlan_sg
->up
) ? true : false;
10878 iif_name
= vxlan_sg
->iif
?vxlan_sg
->iif
->name
:"-";
10880 if (pim_vxlan_is_orig_mroute(vxlan_sg
))
10882 vxlan_sg
->orig_oif
?vxlan_sg
->orig_oif
->name
:"";
10885 vxlan_sg
->term_oif
?vxlan_sg
->term_oif
->name
:"";
10888 json_object_string_add(json
, "source", src_str
);
10889 json_object_string_add(json
, "group", grp_str
);
10890 json_object_string_add(json
, "input", iif_name
);
10891 json_object_string_add(json
, "output", oif_name
);
10893 json_object_boolean_true_add(json
, "installed");
10895 json_object_boolean_false_add(json
,
10898 vty_out(vty
, "SG : %s\n", vxlan_sg
->sg_str
);
10899 vty_out(vty
, " Input : %s\n", iif_name
);
10900 vty_out(vty
, " Output : %s\n", oif_name
);
10901 vty_out(vty
, " installed : %s\n",
10902 installed
?"yes":"no");
10907 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10908 json
, JSON_C_TO_STRING_PRETTY
));
10909 json_object_free(json
);
10913 DEFUN (show_ip_pim_vxlan_sg
,
10914 show_ip_pim_vxlan_sg_cmd
,
10915 "show ip pim [vrf NAME] vxlan-groups [A.B.C.D [A.B.C.D]] [json]",
10920 "VxLAN BUM groups\n"
10921 "source or group ip\n"
10925 bool uj
= use_json(argc
, argv
);
10929 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10932 return CMD_WARNING
;
10934 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ?
10935 argv
[idx
++]->arg
:NULL
;
10936 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
) ?
10937 argv
[idx
]->arg
:NULL
;
10939 if (src_ip
&& grp_ip
)
10940 pim_show_vxlan_sg_one(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
10942 pim_show_vxlan_sg_match_addr(vrf
->info
, vty
, src_ip
, uj
);
10944 pim_show_vxlan_sg(vrf
->info
, vty
, uj
);
10946 return CMD_SUCCESS
;
10949 static void pim_show_vxlan_sg_work(struct pim_instance
*pim
,
10950 struct vty
*vty
, bool uj
)
10952 json_object
*json
= NULL
;
10953 struct pim_sg_cache_walk_data cwd
;
10954 struct listnode
*node
;
10955 struct pim_vxlan_sg
*vxlan_sg
;
10958 json
= json_object_new_object();
10960 vty_out(vty
, "Codes: I -> installed\n");
10962 "Source Group Input Flags\n");
10965 memset(&cwd
, 0, sizeof(cwd
));
10968 for (ALL_LIST_ELEMENTS_RO(pim_vxlan_p
->work_list
, node
, vxlan_sg
))
10969 pim_show_vxlan_sg_entry(vxlan_sg
, &cwd
);
10972 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10973 json
, JSON_C_TO_STRING_PRETTY
));
10974 json_object_free(json
);
10978 DEFUN_HIDDEN (show_ip_pim_vxlan_sg_work
,
10979 show_ip_pim_vxlan_sg_work_cmd
,
10980 "show ip pim [vrf NAME] vxlan-work [json]",
10985 "VxLAN work list\n"
10988 bool uj
= use_json(argc
, argv
);
10992 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10995 return CMD_WARNING
;
10997 pim_show_vxlan_sg_work(vrf
->info
, vty
, uj
);
10999 return CMD_SUCCESS
;
11002 DEFUN_HIDDEN (no_ip_pim_mlag
,
11003 no_ip_pim_mlag_cmd
,
11010 struct in_addr addr
;
11013 pim_vxlan_mlag_update(true/*mlag_enable*/,
11014 false/*peer_state*/, MLAG_ROLE_NONE
,
11015 NULL
/*peerlink*/, &addr
);
11017 return CMD_SUCCESS
;
11020 DEFUN_HIDDEN (ip_pim_mlag
,
11022 "ip pim mlag INTERFACE role [primary|secondary] state [up|down] addr A.B.C.D",
11026 "peerlink sub interface\n"
11028 "MLAG role primary\n"
11029 "MLAG role secondary\n"
11030 "peer session state\n"
11031 "peer session state up\n"
11032 "peer session state down\n"
11034 "unique ip address\n")
11036 struct interface
*ifp
;
11037 const char *peerlink
;
11042 struct in_addr reg_addr
;
11045 peerlink
= argv
[idx
]->arg
;
11046 ifp
= if_lookup_by_name(peerlink
, VRF_DEFAULT
);
11048 vty_out(vty
, "No such interface name %s\n", peerlink
);
11049 return CMD_WARNING
;
11053 if (!strcmp(argv
[idx
]->arg
, "primary")) {
11054 role
= MLAG_ROLE_PRIMARY
;
11055 } else if (!strcmp(argv
[idx
]->arg
, "secondary")) {
11056 role
= MLAG_ROLE_SECONDARY
;
11058 vty_out(vty
, "unknown MLAG role %s\n", argv
[idx
]->arg
);
11059 return CMD_WARNING
;
11063 if (!strcmp(argv
[idx
]->arg
, "up")) {
11065 } else if (strcmp(argv
[idx
]->arg
, "down")) {
11066 peer_state
= false;
11068 vty_out(vty
, "unknown MLAG state %s\n", argv
[idx
]->arg
);
11069 return CMD_WARNING
;
11073 result
= inet_pton(AF_INET
, argv
[idx
]->arg
, ®_addr
);
11075 vty_out(vty
, "%% Bad reg address %s: errno=%d: %s\n",
11077 errno
, safe_strerror(errno
));
11078 return CMD_WARNING_CONFIG_FAILED
;
11080 pim_vxlan_mlag_update(true, peer_state
, role
, ifp
, ®_addr
);
11082 return CMD_SUCCESS
;
11085 void pim_cmd_init(void)
11087 install_node(&interface_node
); /* INTERFACE_NODE */
11090 install_node(&debug_node
);
11092 install_element(ENABLE_NODE
, &pim_test_sg_keepalive_cmd
);
11094 install_element(CONFIG_NODE
, &ip_pim_rp_cmd
);
11095 install_element(VRF_NODE
, &ip_pim_rp_cmd
);
11096 install_element(CONFIG_NODE
, &no_ip_pim_rp_cmd
);
11097 install_element(VRF_NODE
, &no_ip_pim_rp_cmd
);
11098 install_element(CONFIG_NODE
, &ip_pim_rp_prefix_list_cmd
);
11099 install_element(VRF_NODE
, &ip_pim_rp_prefix_list_cmd
);
11100 install_element(CONFIG_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
11101 install_element(VRF_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
11102 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
11103 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
11104 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
11105 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
11106 install_element(CONFIG_NODE
, &ip_pim_ssm_prefix_list_cmd
);
11107 install_element(VRF_NODE
, &ip_pim_ssm_prefix_list_cmd
);
11108 install_element(CONFIG_NODE
, &ip_pim_register_suppress_cmd
);
11109 install_element(VRF_NODE
, &ip_pim_register_suppress_cmd
);
11110 install_element(CONFIG_NODE
, &no_ip_pim_register_suppress_cmd
);
11111 install_element(VRF_NODE
, &no_ip_pim_register_suppress_cmd
);
11112 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
11113 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
11114 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
11115 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
11116 install_element(CONFIG_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
11117 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
11118 install_element(CONFIG_NODE
,
11119 &no_ip_pim_spt_switchover_infinity_plist_cmd
);
11120 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_plist_cmd
);
11121 install_element(CONFIG_NODE
, &pim_register_accept_list_cmd
);
11122 install_element(VRF_NODE
, &pim_register_accept_list_cmd
);
11123 install_element(CONFIG_NODE
, &ip_pim_joinprune_time_cmd
);
11124 install_element(VRF_NODE
, &ip_pim_joinprune_time_cmd
);
11125 install_element(CONFIG_NODE
, &no_ip_pim_joinprune_time_cmd
);
11126 install_element(VRF_NODE
, &no_ip_pim_joinprune_time_cmd
);
11127 install_element(CONFIG_NODE
, &ip_pim_keep_alive_cmd
);
11128 install_element(VRF_NODE
, &ip_pim_keep_alive_cmd
);
11129 install_element(CONFIG_NODE
, &ip_pim_rp_keep_alive_cmd
);
11130 install_element(VRF_NODE
, &ip_pim_rp_keep_alive_cmd
);
11131 install_element(CONFIG_NODE
, &no_ip_pim_keep_alive_cmd
);
11132 install_element(VRF_NODE
, &no_ip_pim_keep_alive_cmd
);
11133 install_element(CONFIG_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
11134 install_element(VRF_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
11135 install_element(CONFIG_NODE
, &ip_pim_packets_cmd
);
11136 install_element(VRF_NODE
, &ip_pim_packets_cmd
);
11137 install_element(CONFIG_NODE
, &no_ip_pim_packets_cmd
);
11138 install_element(VRF_NODE
, &no_ip_pim_packets_cmd
);
11139 install_element(CONFIG_NODE
, &ip_pim_v6_secondary_cmd
);
11140 install_element(VRF_NODE
, &ip_pim_v6_secondary_cmd
);
11141 install_element(CONFIG_NODE
, &no_ip_pim_v6_secondary_cmd
);
11142 install_element(VRF_NODE
, &no_ip_pim_v6_secondary_cmd
);
11143 install_element(CONFIG_NODE
, &ip_ssmpingd_cmd
);
11144 install_element(VRF_NODE
, &ip_ssmpingd_cmd
);
11145 install_element(CONFIG_NODE
, &no_ip_ssmpingd_cmd
);
11146 install_element(VRF_NODE
, &no_ip_ssmpingd_cmd
);
11147 install_element(CONFIG_NODE
, &ip_msdp_peer_cmd
);
11148 install_element(VRF_NODE
, &ip_msdp_peer_cmd
);
11149 install_element(CONFIG_NODE
, &no_ip_msdp_peer_cmd
);
11150 install_element(VRF_NODE
, &no_ip_msdp_peer_cmd
);
11151 install_element(CONFIG_NODE
, &ip_pim_ecmp_cmd
);
11152 install_element(VRF_NODE
, &ip_pim_ecmp_cmd
);
11153 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_cmd
);
11154 install_element(VRF_NODE
, &no_ip_pim_ecmp_cmd
);
11155 install_element(CONFIG_NODE
, &ip_pim_ecmp_rebalance_cmd
);
11156 install_element(VRF_NODE
, &ip_pim_ecmp_rebalance_cmd
);
11157 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
11158 install_element(VRF_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
11159 install_element(CONFIG_NODE
, &ip_pim_mlag_cmd
);
11160 install_element(CONFIG_NODE
, &no_ip_pim_mlag_cmd
);
11161 install_element(CONFIG_NODE
, &igmp_group_watermark_cmd
);
11162 install_element(VRF_NODE
, &igmp_group_watermark_cmd
);
11163 install_element(CONFIG_NODE
, &no_igmp_group_watermark_cmd
);
11164 install_element(VRF_NODE
, &no_igmp_group_watermark_cmd
);
11166 install_element(INTERFACE_NODE
, &interface_ip_igmp_cmd
);
11167 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_cmd
);
11168 install_element(INTERFACE_NODE
, &interface_ip_igmp_join_cmd
);
11169 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_join_cmd
);
11170 install_element(INTERFACE_NODE
, &interface_ip_igmp_version_cmd
);
11171 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_version_cmd
);
11172 install_element(INTERFACE_NODE
, &interface_ip_igmp_query_interval_cmd
);
11173 install_element(INTERFACE_NODE
,
11174 &interface_no_ip_igmp_query_interval_cmd
);
11175 install_element(INTERFACE_NODE
,
11176 &interface_ip_igmp_query_max_response_time_cmd
);
11177 install_element(INTERFACE_NODE
,
11178 &interface_no_ip_igmp_query_max_response_time_cmd
);
11179 install_element(INTERFACE_NODE
,
11180 &interface_ip_igmp_query_max_response_time_dsec_cmd
);
11181 install_element(INTERFACE_NODE
,
11182 &interface_no_ip_igmp_query_max_response_time_dsec_cmd
);
11183 install_element(INTERFACE_NODE
,
11184 &interface_ip_igmp_last_member_query_count_cmd
);
11185 install_element(INTERFACE_NODE
,
11186 &interface_no_ip_igmp_last_member_query_count_cmd
);
11187 install_element(INTERFACE_NODE
,
11188 &interface_ip_igmp_last_member_query_interval_cmd
);
11189 install_element(INTERFACE_NODE
,
11190 &interface_no_ip_igmp_last_member_query_interval_cmd
);
11191 install_element(INTERFACE_NODE
, &interface_ip_pim_activeactive_cmd
);
11192 install_element(INTERFACE_NODE
, &interface_ip_pim_ssm_cmd
);
11193 install_element(INTERFACE_NODE
, &interface_no_ip_pim_ssm_cmd
);
11194 install_element(INTERFACE_NODE
, &interface_ip_pim_sm_cmd
);
11195 install_element(INTERFACE_NODE
, &interface_no_ip_pim_sm_cmd
);
11196 install_element(INTERFACE_NODE
, &interface_ip_pim_cmd
);
11197 install_element(INTERFACE_NODE
, &interface_no_ip_pim_cmd
);
11198 install_element(INTERFACE_NODE
, &interface_ip_pim_drprio_cmd
);
11199 install_element(INTERFACE_NODE
, &interface_no_ip_pim_drprio_cmd
);
11200 install_element(INTERFACE_NODE
, &interface_ip_pim_hello_cmd
);
11201 install_element(INTERFACE_NODE
, &interface_no_ip_pim_hello_cmd
);
11202 install_element(INTERFACE_NODE
, &interface_ip_pim_boundary_oil_cmd
);
11203 install_element(INTERFACE_NODE
, &interface_no_ip_pim_boundary_oil_cmd
);
11204 install_element(INTERFACE_NODE
, &interface_ip_igmp_query_generate_cmd
);
11206 // Static mroutes NEB
11207 install_element(INTERFACE_NODE
, &interface_ip_mroute_cmd
);
11208 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_cmd
);
11210 install_element(VIEW_NODE
, &show_ip_igmp_interface_cmd
);
11211 install_element(VIEW_NODE
, &show_ip_igmp_interface_vrf_all_cmd
);
11212 install_element(VIEW_NODE
, &show_ip_igmp_join_cmd
);
11213 install_element(VIEW_NODE
, &show_ip_igmp_join_vrf_all_cmd
);
11214 install_element(VIEW_NODE
, &show_ip_igmp_groups_cmd
);
11215 install_element(VIEW_NODE
, &show_ip_igmp_groups_vrf_all_cmd
);
11216 install_element(VIEW_NODE
, &show_ip_igmp_groups_retransmissions_cmd
);
11217 install_element(VIEW_NODE
, &show_ip_igmp_sources_cmd
);
11218 install_element(VIEW_NODE
, &show_ip_igmp_sources_retransmissions_cmd
);
11219 install_element(VIEW_NODE
, &show_ip_igmp_statistics_cmd
);
11220 install_element(VIEW_NODE
, &show_ip_pim_assert_cmd
);
11221 install_element(VIEW_NODE
, &show_ip_pim_assert_internal_cmd
);
11222 install_element(VIEW_NODE
, &show_ip_pim_assert_metric_cmd
);
11223 install_element(VIEW_NODE
, &show_ip_pim_assert_winner_metric_cmd
);
11224 install_element(VIEW_NODE
, &show_ip_pim_interface_traffic_cmd
);
11225 install_element(VIEW_NODE
, &show_ip_pim_interface_cmd
);
11226 install_element(VIEW_NODE
, &show_ip_pim_interface_vrf_all_cmd
);
11227 install_element(VIEW_NODE
, &show_ip_pim_join_cmd
);
11228 install_element(VIEW_NODE
, &show_ip_pim_join_vrf_all_cmd
);
11229 install_element(VIEW_NODE
, &show_ip_pim_jp_agg_cmd
);
11230 install_element(VIEW_NODE
, &show_ip_pim_local_membership_cmd
);
11231 install_element(VIEW_NODE
, &show_ip_pim_mlag_summary_cmd
);
11232 install_element(VIEW_NODE
, &show_ip_pim_mlag_up_cmd
);
11233 install_element(VIEW_NODE
, &show_ip_pim_mlag_up_vrf_all_cmd
);
11234 install_element(VIEW_NODE
, &show_ip_pim_neighbor_cmd
);
11235 install_element(VIEW_NODE
, &show_ip_pim_neighbor_vrf_all_cmd
);
11236 install_element(VIEW_NODE
, &show_ip_pim_rpf_cmd
);
11237 install_element(VIEW_NODE
, &show_ip_pim_rpf_vrf_all_cmd
);
11238 install_element(VIEW_NODE
, &show_ip_pim_secondary_cmd
);
11239 install_element(VIEW_NODE
, &show_ip_pim_state_cmd
);
11240 install_element(VIEW_NODE
, &show_ip_pim_state_vrf_all_cmd
);
11241 install_element(VIEW_NODE
, &show_ip_pim_upstream_cmd
);
11242 install_element(VIEW_NODE
, &show_ip_pim_upstream_vrf_all_cmd
);
11243 install_element(VIEW_NODE
, &show_ip_pim_channel_cmd
);
11244 install_element(VIEW_NODE
, &show_ip_pim_upstream_join_desired_cmd
);
11245 install_element(VIEW_NODE
, &show_ip_pim_upstream_rpf_cmd
);
11246 install_element(VIEW_NODE
, &show_ip_pim_rp_cmd
);
11247 install_element(VIEW_NODE
, &show_ip_pim_rp_vrf_all_cmd
);
11248 install_element(VIEW_NODE
, &show_ip_pim_bsr_cmd
);
11249 install_element(VIEW_NODE
, &show_ip_multicast_cmd
);
11250 install_element(VIEW_NODE
, &show_ip_multicast_vrf_all_cmd
);
11251 install_element(VIEW_NODE
, &show_ip_multicast_count_cmd
);
11252 install_element(VIEW_NODE
, &show_ip_multicast_count_vrf_all_cmd
);
11253 install_element(VIEW_NODE
, &show_ip_mroute_cmd
);
11254 install_element(VIEW_NODE
, &show_ip_mroute_vrf_all_cmd
);
11255 install_element(VIEW_NODE
, &show_ip_mroute_count_cmd
);
11256 install_element(VIEW_NODE
, &show_ip_mroute_count_vrf_all_cmd
);
11257 install_element(VIEW_NODE
, &show_ip_mroute_summary_cmd
);
11258 install_element(VIEW_NODE
, &show_ip_mroute_summary_vrf_all_cmd
);
11259 install_element(VIEW_NODE
, &show_ip_rib_cmd
);
11260 install_element(VIEW_NODE
, &show_ip_ssmpingd_cmd
);
11261 install_element(VIEW_NODE
, &show_ip_pim_nexthop_cmd
);
11262 install_element(VIEW_NODE
, &show_ip_pim_nexthop_lookup_cmd
);
11263 install_element(VIEW_NODE
, &show_ip_pim_bsrp_cmd
);
11264 install_element(VIEW_NODE
, &show_ip_pim_bsm_db_cmd
);
11265 install_element(VIEW_NODE
, &show_ip_pim_statistics_cmd
);
11267 install_element(ENABLE_NODE
, &clear_ip_mroute_count_cmd
);
11268 install_element(ENABLE_NODE
, &clear_ip_interfaces_cmd
);
11269 install_element(ENABLE_NODE
, &clear_ip_igmp_interfaces_cmd
);
11270 install_element(ENABLE_NODE
, &clear_ip_mroute_cmd
);
11271 install_element(ENABLE_NODE
, &clear_ip_pim_interfaces_cmd
);
11272 install_element(ENABLE_NODE
, &clear_ip_pim_interface_traffic_cmd
);
11273 install_element(ENABLE_NODE
, &clear_ip_pim_oil_cmd
);
11274 install_element(ENABLE_NODE
, &clear_ip_pim_statistics_cmd
);
11276 install_element(ENABLE_NODE
, &show_debugging_pim_cmd
);
11278 install_element(ENABLE_NODE
, &debug_igmp_cmd
);
11279 install_element(ENABLE_NODE
, &no_debug_igmp_cmd
);
11280 install_element(ENABLE_NODE
, &debug_igmp_events_cmd
);
11281 install_element(ENABLE_NODE
, &no_debug_igmp_events_cmd
);
11282 install_element(ENABLE_NODE
, &debug_igmp_packets_cmd
);
11283 install_element(ENABLE_NODE
, &no_debug_igmp_packets_cmd
);
11284 install_element(ENABLE_NODE
, &debug_igmp_trace_cmd
);
11285 install_element(ENABLE_NODE
, &no_debug_igmp_trace_cmd
);
11286 install_element(ENABLE_NODE
, &debug_mroute_cmd
);
11287 install_element(ENABLE_NODE
, &debug_mroute_detail_cmd
);
11288 install_element(ENABLE_NODE
, &no_debug_mroute_cmd
);
11289 install_element(ENABLE_NODE
, &no_debug_mroute_detail_cmd
);
11290 install_element(ENABLE_NODE
, &debug_pim_static_cmd
);
11291 install_element(ENABLE_NODE
, &no_debug_pim_static_cmd
);
11292 install_element(ENABLE_NODE
, &debug_pim_cmd
);
11293 install_element(ENABLE_NODE
, &no_debug_pim_cmd
);
11294 install_element(ENABLE_NODE
, &debug_pim_nht_cmd
);
11295 install_element(ENABLE_NODE
, &no_debug_pim_nht_cmd
);
11296 install_element(ENABLE_NODE
, &debug_pim_nht_rp_cmd
);
11297 install_element(ENABLE_NODE
, &no_debug_pim_nht_rp_cmd
);
11298 install_element(ENABLE_NODE
, &debug_pim_events_cmd
);
11299 install_element(ENABLE_NODE
, &no_debug_pim_events_cmd
);
11300 install_element(ENABLE_NODE
, &debug_pim_packets_cmd
);
11301 install_element(ENABLE_NODE
, &no_debug_pim_packets_cmd
);
11302 install_element(ENABLE_NODE
, &debug_pim_packetdump_send_cmd
);
11303 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_send_cmd
);
11304 install_element(ENABLE_NODE
, &debug_pim_packetdump_recv_cmd
);
11305 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_recv_cmd
);
11306 install_element(ENABLE_NODE
, &debug_pim_trace_cmd
);
11307 install_element(ENABLE_NODE
, &no_debug_pim_trace_cmd
);
11308 install_element(ENABLE_NODE
, &debug_pim_trace_detail_cmd
);
11309 install_element(ENABLE_NODE
, &no_debug_pim_trace_detail_cmd
);
11310 install_element(ENABLE_NODE
, &debug_ssmpingd_cmd
);
11311 install_element(ENABLE_NODE
, &no_debug_ssmpingd_cmd
);
11312 install_element(ENABLE_NODE
, &debug_pim_zebra_cmd
);
11313 install_element(ENABLE_NODE
, &no_debug_pim_zebra_cmd
);
11314 install_element(ENABLE_NODE
, &debug_pim_mlag_cmd
);
11315 install_element(ENABLE_NODE
, &no_debug_pim_mlag_cmd
);
11316 install_element(ENABLE_NODE
, &debug_pim_vxlan_cmd
);
11317 install_element(ENABLE_NODE
, &no_debug_pim_vxlan_cmd
);
11318 install_element(ENABLE_NODE
, &debug_msdp_cmd
);
11319 install_element(ENABLE_NODE
, &no_debug_msdp_cmd
);
11320 install_element(ENABLE_NODE
, &debug_msdp_events_cmd
);
11321 install_element(ENABLE_NODE
, &no_debug_msdp_events_cmd
);
11322 install_element(ENABLE_NODE
, &debug_msdp_packets_cmd
);
11323 install_element(ENABLE_NODE
, &no_debug_msdp_packets_cmd
);
11324 install_element(ENABLE_NODE
, &debug_mtrace_cmd
);
11325 install_element(ENABLE_NODE
, &no_debug_mtrace_cmd
);
11326 install_element(ENABLE_NODE
, &debug_bsm_cmd
);
11327 install_element(ENABLE_NODE
, &no_debug_bsm_cmd
);
11329 install_element(CONFIG_NODE
, &debug_igmp_cmd
);
11330 install_element(CONFIG_NODE
, &no_debug_igmp_cmd
);
11331 install_element(CONFIG_NODE
, &debug_igmp_events_cmd
);
11332 install_element(CONFIG_NODE
, &no_debug_igmp_events_cmd
);
11333 install_element(CONFIG_NODE
, &debug_igmp_packets_cmd
);
11334 install_element(CONFIG_NODE
, &no_debug_igmp_packets_cmd
);
11335 install_element(CONFIG_NODE
, &debug_igmp_trace_cmd
);
11336 install_element(CONFIG_NODE
, &no_debug_igmp_trace_cmd
);
11337 install_element(CONFIG_NODE
, &debug_mroute_cmd
);
11338 install_element(CONFIG_NODE
, &debug_mroute_detail_cmd
);
11339 install_element(CONFIG_NODE
, &no_debug_mroute_cmd
);
11340 install_element(CONFIG_NODE
, &no_debug_mroute_detail_cmd
);
11341 install_element(CONFIG_NODE
, &debug_pim_static_cmd
);
11342 install_element(CONFIG_NODE
, &no_debug_pim_static_cmd
);
11343 install_element(CONFIG_NODE
, &debug_pim_cmd
);
11344 install_element(CONFIG_NODE
, &no_debug_pim_cmd
);
11345 install_element(CONFIG_NODE
, &debug_pim_nht_cmd
);
11346 install_element(CONFIG_NODE
, &no_debug_pim_nht_cmd
);
11347 install_element(CONFIG_NODE
, &debug_pim_nht_rp_cmd
);
11348 install_element(CONFIG_NODE
, &no_debug_pim_nht_rp_cmd
);
11349 install_element(CONFIG_NODE
, &debug_pim_events_cmd
);
11350 install_element(CONFIG_NODE
, &no_debug_pim_events_cmd
);
11351 install_element(CONFIG_NODE
, &debug_pim_packets_cmd
);
11352 install_element(CONFIG_NODE
, &no_debug_pim_packets_cmd
);
11353 install_element(CONFIG_NODE
, &debug_pim_trace_cmd
);
11354 install_element(CONFIG_NODE
, &no_debug_pim_trace_cmd
);
11355 install_element(CONFIG_NODE
, &debug_pim_trace_detail_cmd
);
11356 install_element(CONFIG_NODE
, &no_debug_pim_trace_detail_cmd
);
11357 install_element(CONFIG_NODE
, &debug_ssmpingd_cmd
);
11358 install_element(CONFIG_NODE
, &no_debug_ssmpingd_cmd
);
11359 install_element(CONFIG_NODE
, &debug_pim_zebra_cmd
);
11360 install_element(CONFIG_NODE
, &no_debug_pim_zebra_cmd
);
11361 install_element(CONFIG_NODE
, &debug_pim_mlag_cmd
);
11362 install_element(CONFIG_NODE
, &no_debug_pim_mlag_cmd
);
11363 install_element(CONFIG_NODE
, &debug_pim_vxlan_cmd
);
11364 install_element(CONFIG_NODE
, &no_debug_pim_vxlan_cmd
);
11365 install_element(CONFIG_NODE
, &debug_msdp_cmd
);
11366 install_element(CONFIG_NODE
, &no_debug_msdp_cmd
);
11367 install_element(CONFIG_NODE
, &debug_msdp_events_cmd
);
11368 install_element(CONFIG_NODE
, &no_debug_msdp_events_cmd
);
11369 install_element(CONFIG_NODE
, &debug_msdp_packets_cmd
);
11370 install_element(CONFIG_NODE
, &no_debug_msdp_packets_cmd
);
11371 install_element(CONFIG_NODE
, &debug_mtrace_cmd
);
11372 install_element(CONFIG_NODE
, &no_debug_mtrace_cmd
);
11373 install_element(CONFIG_NODE
, &debug_bsm_cmd
);
11374 install_element(CONFIG_NODE
, &no_debug_bsm_cmd
);
11376 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_member_cmd
);
11377 install_element(VRF_NODE
, &ip_msdp_mesh_group_member_cmd
);
11378 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
11379 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
11380 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_source_cmd
);
11381 install_element(VRF_NODE
, &ip_msdp_mesh_group_source_cmd
);
11382 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
11383 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
11384 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_cmd
);
11385 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_cmd
);
11386 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_cmd
);
11387 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_vrf_all_cmd
);
11388 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_cmd
);
11389 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_vrf_all_cmd
);
11390 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_cmd
);
11391 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_vrf_all_cmd
);
11392 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_cmd
);
11393 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_vrf_all_cmd
);
11394 install_element(VIEW_NODE
, &show_ip_pim_ssm_range_cmd
);
11395 install_element(VIEW_NODE
, &show_ip_pim_group_type_cmd
);
11396 install_element(VIEW_NODE
, &show_ip_pim_vxlan_sg_cmd
);
11397 install_element(VIEW_NODE
, &show_ip_pim_vxlan_sg_work_cmd
);
11398 install_element(INTERFACE_NODE
, &interface_pim_use_source_cmd
);
11399 install_element(INTERFACE_NODE
, &interface_no_pim_use_source_cmd
);
11400 /* Install BSM command */
11401 install_element(INTERFACE_NODE
, &ip_pim_bsm_cmd
);
11402 install_element(INTERFACE_NODE
, &no_ip_pim_bsm_cmd
);
11403 install_element(INTERFACE_NODE
, &ip_pim_ucast_bsm_cmd
);
11404 install_element(INTERFACE_NODE
, &no_ip_pim_ucast_bsm_cmd
);
11405 /* Install BFD command */
11406 install_element(INTERFACE_NODE
, &ip_pim_bfd_cmd
);
11407 install_element(INTERFACE_NODE
, &ip_pim_bfd_param_cmd
);
11408 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_cmd
);
11410 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_param_cmd
);
11411 #endif /* !HAVE_BFDD */