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
= {
73 INTERFACE_NODE
, "%s(config-if)# ", 1 /* vtysh ? yes */
76 static struct cmd_node debug_node
= {DEBUG_NODE
, "", 1};
78 static struct vrf
*pim_cmd_lookup_vrf(struct vty
*vty
, struct cmd_token
*argv
[],
79 const int argc
, int *idx
)
83 if (argv_find(argv
, argc
, "NAME", idx
))
84 vrf
= vrf_lookup_by_name(argv
[*idx
]->arg
);
86 vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
89 vty_out(vty
, "Specified VRF: %s does not exist\n",
95 static void pim_if_membership_clear(struct interface
*ifp
)
97 struct pim_interface
*pim_ifp
;
102 if (PIM_IF_TEST_PIM(pim_ifp
->options
)
103 && PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
107 pim_ifchannel_membership_clear(ifp
);
111 When PIM is disabled on interface, IGMPv3 local membership
112 information is not injected into PIM interface state.
114 The function pim_if_membership_refresh() fetches all IGMPv3 local
115 membership information into PIM. It is intented to be called
116 whenever PIM is enabled on the interface in order to collect missed
117 local membership information.
119 static void pim_if_membership_refresh(struct interface
*ifp
)
121 struct pim_interface
*pim_ifp
;
122 struct listnode
*sock_node
;
123 struct igmp_sock
*igmp
;
128 if (!PIM_IF_TEST_PIM(pim_ifp
->options
))
130 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
))
134 First clear off membership from all PIM (S,G) entries on the
138 pim_ifchannel_membership_clear(ifp
);
141 Then restore PIM (S,G) membership from all IGMPv3 (S,G) entries on
145 /* scan igmp sockets */
146 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
147 struct listnode
*grpnode
;
148 struct igmp_group
*grp
;
150 /* scan igmp groups */
151 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grpnode
,
153 struct listnode
*srcnode
;
154 struct igmp_source
*src
;
156 /* scan group sources */
157 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
,
160 if (IGMP_SOURCE_TEST_FORWARDING(
161 src
->source_flags
)) {
165 sizeof(struct prefix_sg
));
166 sg
.src
= src
->source_addr
;
167 sg
.grp
= grp
->group_addr
;
168 pim_ifchannel_local_membership_add(ifp
,
169 &sg
, false /*is_vxlan*/);
172 } /* scan group sources */
173 } /* scan igmp groups */
174 } /* scan igmp sockets */
177 Finally delete every PIM (S,G) entry lacking all state info
180 pim_ifchannel_delete_on_noinfo(ifp
);
183 static void pim_show_assert_helper(struct vty
*vty
,
184 struct pim_interface
*pim_ifp
,
185 struct pim_ifchannel
*ch
, time_t now
)
187 char ch_src_str
[INET_ADDRSTRLEN
];
188 char ch_grp_str
[INET_ADDRSTRLEN
];
189 char winner_str
[INET_ADDRSTRLEN
];
190 struct in_addr ifaddr
;
194 ifaddr
= pim_ifp
->primary_address
;
196 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
197 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
198 pim_inet4_dump("<assrt_win?>", ch
->ifassert_winner
, winner_str
,
201 pim_time_uptime(uptime
, sizeof(uptime
), now
- ch
->ifassert_creation
);
202 pim_time_timer_to_mmss(timer
, sizeof(timer
), ch
->t_ifassert_timer
);
204 vty_out(vty
, "%-16s %-15s %-15s %-15s %-6s %-15s %-8s %-5s\n",
205 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
, ch_grp_str
,
206 pim_ifchannel_ifassert_name(ch
->ifassert_state
), winner_str
,
210 static void pim_show_assert(struct pim_instance
*pim
, struct vty
*vty
)
212 struct pim_interface
*pim_ifp
;
213 struct pim_ifchannel
*ch
;
214 struct interface
*ifp
;
217 now
= pim_time_monotonic_sec();
220 "Interface Address Source Group State Winner Uptime Timer\n");
222 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
227 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
228 pim_show_assert_helper(vty
, pim_ifp
, ch
, now
);
229 } /* scan interface channels */
233 static void pim_show_assert_internal_helper(struct vty
*vty
,
234 struct pim_interface
*pim_ifp
,
235 struct pim_ifchannel
*ch
)
237 char ch_src_str
[INET_ADDRSTRLEN
];
238 char ch_grp_str
[INET_ADDRSTRLEN
];
239 struct in_addr ifaddr
;
241 ifaddr
= pim_ifp
->primary_address
;
243 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
244 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
245 vty_out(vty
, "%-16s %-15s %-15s %-15s %-3s %-3s %-3s %-4s\n",
246 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
, ch_grp_str
,
247 PIM_IF_FLAG_TEST_COULD_ASSERT(ch
->flags
) ? "yes" : "no",
248 pim_macro_ch_could_assert_eval(ch
) ? "yes" : "no",
249 PIM_IF_FLAG_TEST_ASSERT_TRACKING_DESIRED(ch
->flags
) ? "yes"
251 pim_macro_assert_tracking_desired_eval(ch
) ? "yes" : "no");
254 static void pim_show_assert_internal(struct pim_instance
*pim
, struct vty
*vty
)
256 struct pim_interface
*pim_ifp
;
257 struct pim_ifchannel
*ch
;
258 struct interface
*ifp
;
262 "ECA: Evaluate CouldAssert\n"
263 "ATD: AssertTrackingDesired\n"
264 "eATD: Evaluate AssertTrackingDesired\n\n");
267 "Interface Address Source Group CA eCA ATD eATD\n");
268 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
273 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
274 pim_show_assert_internal_helper(vty
, pim_ifp
, ch
);
275 } /* scan interface channels */
279 static void pim_show_assert_metric_helper(struct vty
*vty
,
280 struct pim_interface
*pim_ifp
,
281 struct pim_ifchannel
*ch
)
283 char ch_src_str
[INET_ADDRSTRLEN
];
284 char ch_grp_str
[INET_ADDRSTRLEN
];
285 char addr_str
[INET_ADDRSTRLEN
];
286 struct pim_assert_metric am
;
287 struct in_addr ifaddr
;
289 ifaddr
= pim_ifp
->primary_address
;
291 am
= pim_macro_spt_assert_metric(&ch
->upstream
->rpf
,
292 pim_ifp
->primary_address
);
294 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
295 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
296 pim_inet4_dump("<addr?>", am
.ip_address
, addr_str
, sizeof(addr_str
));
298 vty_out(vty
, "%-16s %-15s %-15s %-15s %-3s %4u %6u %-15s\n",
299 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
, ch_grp_str
,
300 am
.rpt_bit_flag
? "yes" : "no", am
.metric_preference
,
301 am
.route_metric
, addr_str
);
304 static void pim_show_assert_metric(struct pim_instance
*pim
, struct vty
*vty
)
306 struct pim_interface
*pim_ifp
;
307 struct pim_ifchannel
*ch
;
308 struct interface
*ifp
;
311 "Interface Address Source Group RPT Pref Metric Address \n");
313 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
318 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
319 pim_show_assert_metric_helper(vty
, pim_ifp
, ch
);
320 } /* scan interface channels */
324 static void pim_show_assert_winner_metric_helper(struct vty
*vty
,
325 struct pim_interface
*pim_ifp
,
326 struct pim_ifchannel
*ch
)
328 char ch_src_str
[INET_ADDRSTRLEN
];
329 char ch_grp_str
[INET_ADDRSTRLEN
];
330 char addr_str
[INET_ADDRSTRLEN
];
331 struct pim_assert_metric
*am
;
332 struct in_addr ifaddr
;
336 ifaddr
= pim_ifp
->primary_address
;
338 am
= &ch
->ifassert_winner_metric
;
340 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
341 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
342 pim_inet4_dump("<addr?>", am
->ip_address
, addr_str
, sizeof(addr_str
));
344 if (am
->metric_preference
== PIM_ASSERT_METRIC_PREFERENCE_MAX
)
345 snprintf(pref_str
, sizeof(pref_str
), "INFI");
347 snprintf(pref_str
, sizeof(pref_str
), "%4u",
348 am
->metric_preference
);
350 if (am
->route_metric
== PIM_ASSERT_ROUTE_METRIC_MAX
)
351 snprintf(metr_str
, sizeof(metr_str
), "INFI");
353 snprintf(metr_str
, sizeof(metr_str
), "%6u", am
->route_metric
);
355 vty_out(vty
, "%-16s %-15s %-15s %-15s %-3s %-4s %-6s %-15s\n",
356 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
, ch_grp_str
,
357 am
->rpt_bit_flag
? "yes" : "no", pref_str
, metr_str
, addr_str
);
360 static void pim_show_assert_winner_metric(struct pim_instance
*pim
,
363 struct pim_interface
*pim_ifp
;
364 struct pim_ifchannel
*ch
;
365 struct interface
*ifp
;
368 "Interface Address Source Group RPT Pref Metric Address \n");
370 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
375 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
376 pim_show_assert_winner_metric_helper(vty
, pim_ifp
, ch
);
377 } /* scan interface channels */
381 static void json_object_pim_ifp_add(struct json_object
*json
,
382 struct interface
*ifp
)
384 struct pim_interface
*pim_ifp
;
387 json_object_string_add(json
, "name", ifp
->name
);
388 json_object_string_add(json
, "state", if_is_up(ifp
) ? "up" : "down");
389 json_object_string_add(json
, "address",
390 inet_ntoa(pim_ifp
->primary_address
));
391 json_object_int_add(json
, "index", ifp
->ifindex
);
393 if (if_is_multicast(ifp
))
394 json_object_boolean_true_add(json
, "flagMulticast");
396 if (if_is_broadcast(ifp
))
397 json_object_boolean_true_add(json
, "flagBroadcast");
399 if (ifp
->flags
& IFF_ALLMULTI
)
400 json_object_boolean_true_add(json
, "flagAllMulticast");
402 if (ifp
->flags
& IFF_PROMISC
)
403 json_object_boolean_true_add(json
, "flagPromiscuous");
405 if (PIM_IF_IS_DELETED(ifp
))
406 json_object_boolean_true_add(json
, "flagDeleted");
408 if (pim_if_lan_delay_enabled(ifp
))
409 json_object_boolean_true_add(json
, "lanDelayEnabled");
412 static void pim_show_membership_helper(struct vty
*vty
,
413 struct pim_interface
*pim_ifp
,
414 struct pim_ifchannel
*ch
,
415 struct json_object
*json
)
417 char ch_src_str
[INET_ADDRSTRLEN
];
418 char ch_grp_str
[INET_ADDRSTRLEN
];
419 json_object
*json_iface
= NULL
;
420 json_object
*json_row
= NULL
;
422 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
423 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
425 json_object_object_get_ex(json
, ch
->interface
->name
, &json_iface
);
427 json_iface
= json_object_new_object();
428 json_object_pim_ifp_add(json_iface
, ch
->interface
);
429 json_object_object_add(json
, ch
->interface
->name
, json_iface
);
432 json_row
= json_object_new_object();
433 json_object_string_add(json_row
, "source", ch_src_str
);
434 json_object_string_add(json_row
, "group", ch_grp_str
);
435 json_object_string_add(json_row
, "localMembership",
436 ch
->local_ifmembership
== PIM_IFMEMBERSHIP_NOINFO
439 json_object_object_add(json_iface
, ch_grp_str
, json_row
);
441 static void pim_show_membership(struct pim_instance
*pim
, struct vty
*vty
,
444 struct pim_interface
*pim_ifp
;
445 struct pim_ifchannel
*ch
;
446 struct interface
*ifp
;
448 json_object
*json
= NULL
;
449 json_object
*json_tmp
= NULL
;
451 json
= json_object_new_object();
453 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
458 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
459 pim_show_membership_helper(vty
, pim_ifp
, ch
, json
);
460 } /* scan interface channels */
464 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
465 json
, JSON_C_TO_STRING_PRETTY
));
468 "Interface Address Source Group Membership\n");
471 * Example of the json data we are traversing
477 * "address":"10.1.20.1",
479 * "flagMulticast":true,
480 * "flagBroadcast":true,
481 * "lanDelayEnabled":true,
484 * "group":"226.10.10.10",
485 * "localMembership":"INCLUDE"
491 /* foreach interface */
492 json_object_object_foreach(json
, key
, val
)
495 /* Find all of the keys where the val is an object. In
497 * above the only one is 226.10.10.10
499 json_object_object_foreach(val
, if_field_key
,
502 type
= json_object_get_type(if_field_val
);
504 if (type
== json_type_object
) {
505 vty_out(vty
, "%-16s ", key
);
507 json_object_object_get_ex(
508 val
, "address", &json_tmp
);
509 vty_out(vty
, "%-15s ",
510 json_object_get_string(
513 json_object_object_get_ex(if_field_val
,
516 vty_out(vty
, "%-15s ",
517 json_object_get_string(
521 vty_out(vty
, "%-15s ", if_field_key
);
523 json_object_object_get_ex(
524 if_field_val
, "localMembership",
526 vty_out(vty
, "%-10s\n",
527 json_object_get_string(
534 json_object_free(json
);
537 static void pim_print_ifp_flags(struct vty
*vty
, struct interface
*ifp
,
540 vty_out(vty
, "Flags\n");
541 vty_out(vty
, "-----\n");
542 vty_out(vty
, "All Multicast : %s\n",
543 (ifp
->flags
& IFF_ALLMULTI
) ? "yes" : "no");
544 vty_out(vty
, "Broadcast : %s\n",
545 if_is_broadcast(ifp
) ? "yes" : "no");
546 vty_out(vty
, "Deleted : %s\n",
547 PIM_IF_IS_DELETED(ifp
) ? "yes" : "no");
548 vty_out(vty
, "Interface Index : %d\n", ifp
->ifindex
);
549 vty_out(vty
, "Multicast : %s\n",
550 if_is_multicast(ifp
) ? "yes" : "no");
551 vty_out(vty
, "Multicast Loop : %d\n", mloop
);
552 vty_out(vty
, "Promiscuous : %s\n",
553 (ifp
->flags
& IFF_PROMISC
) ? "yes" : "no");
558 static void igmp_show_interfaces(struct pim_instance
*pim
, struct vty
*vty
,
561 struct interface
*ifp
;
563 json_object
*json
= NULL
;
564 json_object
*json_row
= NULL
;
566 now
= pim_time_monotonic_sec();
569 json
= json_object_new_object();
572 "Interface State Address V Querier Query Timer Uptime\n");
574 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
575 struct pim_interface
*pim_ifp
;
576 struct listnode
*sock_node
;
577 struct igmp_sock
*igmp
;
584 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
587 char query_hhmmss
[10];
589 pim_time_uptime(uptime
, sizeof(uptime
),
590 now
- igmp
->sock_creation
);
591 pim_time_timer_to_hhmmss(query_hhmmss
,
592 sizeof(query_hhmmss
),
593 igmp
->t_igmp_query_timer
);
596 json_row
= json_object_new_object();
597 json_object_pim_ifp_add(json_row
, ifp
);
598 json_object_string_add(json_row
, "upTime",
600 json_object_int_add(json_row
, "version",
601 pim_ifp
->igmp_version
);
603 if (igmp
->t_igmp_query_timer
) {
604 json_object_boolean_true_add(json_row
,
606 json_object_string_add(json_row
,
611 json_object_object_add(json
, ifp
->name
,
614 if (igmp
->mtrace_only
) {
615 json_object_boolean_true_add(
616 json_row
, "mtraceOnly");
620 "%-16s %5s %15s %d %7s %11s %8s\n",
623 ? (igmp
->mtrace_only
? "mtrc"
626 inet_ntoa(igmp
->ifaddr
),
627 pim_ifp
->igmp_version
,
628 igmp
->t_igmp_query_timer
? "local"
630 query_hhmmss
, uptime
);
636 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
637 json
, JSON_C_TO_STRING_PRETTY
));
638 json_object_free(json
);
642 static void igmp_show_interfaces_single(struct pim_instance
*pim
,
643 struct vty
*vty
, const char *ifname
,
646 struct igmp_sock
*igmp
;
647 struct interface
*ifp
;
648 struct listnode
*sock_node
;
649 struct pim_interface
*pim_ifp
;
651 char query_hhmmss
[10];
652 char other_hhmmss
[10];
653 int found_ifname
= 0;
656 long gmi_msec
; /* Group Membership Interval */
659 long oqpi_msec
; /* Other Querier Present Interval */
664 json_object
*json
= NULL
;
665 json_object
*json_row
= NULL
;
668 json
= json_object_new_object();
670 now
= pim_time_monotonic_sec();
672 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
678 if (strcmp(ifname
, "detail") && strcmp(ifname
, ifp
->name
))
681 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
684 pim_time_uptime(uptime
, sizeof(uptime
),
685 now
- igmp
->sock_creation
);
686 pim_time_timer_to_hhmmss(query_hhmmss
,
687 sizeof(query_hhmmss
),
688 igmp
->t_igmp_query_timer
);
689 pim_time_timer_to_hhmmss(other_hhmmss
,
690 sizeof(other_hhmmss
),
691 igmp
->t_other_querier_timer
);
693 gmi_msec
= PIM_IGMP_GMI_MSEC(
694 igmp
->querier_robustness_variable
,
695 igmp
->querier_query_interval
,
696 pim_ifp
->igmp_query_max_response_time_dsec
);
699 pim_ifp
->igmp_default_query_interval
);
701 oqpi_msec
= PIM_IGMP_OQPI_MSEC(
702 igmp
->querier_robustness_variable
,
703 igmp
->querier_query_interval
,
704 pim_ifp
->igmp_query_max_response_time_dsec
);
706 lmqt_msec
= PIM_IGMP_LMQT_MSEC(
707 pim_ifp
->igmp_specific_query_max_response_time_dsec
,
708 pim_ifp
->igmp_last_member_query_count
);
712 igmp
->querier_robustness_variable
,
713 igmp
->querier_query_interval
,
714 pim_ifp
->igmp_query_max_response_time_dsec
)
717 qri_msec
= pim_ifp
->igmp_query_max_response_time_dsec
719 if (pim_ifp
->pim_sock_fd
>= 0)
720 mloop
= pim_socket_mcastloop_get(
721 pim_ifp
->pim_sock_fd
);
724 lmqc
= pim_ifp
->igmp_last_member_query_count
;
727 json_row
= json_object_new_object();
728 json_object_pim_ifp_add(json_row
, ifp
);
729 json_object_string_add(json_row
, "upTime",
731 json_object_string_add(json_row
, "querier",
732 igmp
->t_igmp_query_timer
735 json_object_int_add(json_row
, "queryStartCount",
736 igmp
->startup_query_count
);
737 json_object_string_add(json_row
,
740 json_object_string_add(json_row
,
743 json_object_int_add(json_row
, "version",
744 pim_ifp
->igmp_version
);
747 "timerGroupMembershipIntervalMsec",
749 json_object_int_add(json_row
,
750 "lastMemberQueryCount",
752 json_object_int_add(json_row
,
753 "timerLastMemberQueryMsec",
757 "timerOlderHostPresentIntervalMsec",
761 "timerOtherQuerierPresentIntervalMsec",
764 json_row
, "timerQueryInterval",
765 igmp
->querier_query_interval
);
768 "timerQueryResponseIntervalMsec",
771 json_row
, "timerRobustnessVariable",
772 igmp
->querier_robustness_variable
);
773 json_object_int_add(json_row
,
774 "timerStartupQueryInterval",
777 json_object_object_add(json
, ifp
->name
,
780 if (igmp
->mtrace_only
) {
781 json_object_boolean_true_add(
782 json_row
, "mtraceOnly");
785 vty_out(vty
, "Interface : %s\n", ifp
->name
);
786 vty_out(vty
, "State : %s\n",
788 ? (igmp
->mtrace_only
? "mtrace"
791 vty_out(vty
, "Address : %s\n",
792 inet_ntoa(pim_ifp
->primary_address
));
793 vty_out(vty
, "Uptime : %s\n", uptime
);
794 vty_out(vty
, "Version : %d\n",
795 pim_ifp
->igmp_version
);
799 vty_out(vty
, "Querier\n");
800 vty_out(vty
, "-------\n");
801 vty_out(vty
, "Querier : %s\n",
802 igmp
->t_igmp_query_timer
? "local"
804 vty_out(vty
, "Start Count : %d\n",
805 igmp
->startup_query_count
);
806 vty_out(vty
, "Query Timer : %s\n",
808 vty_out(vty
, "Other Timer : %s\n",
813 vty_out(vty
, "Timers\n");
814 vty_out(vty
, "------\n");
816 "Group Membership Interval : %lis\n",
819 "Last Member Query Count : %d\n",
822 "Last Member Query Time : %lis\n",
825 "Older Host Present Interval : %lis\n",
828 "Other Querier Present Interval : %lis\n",
831 "Query Interval : %ds\n",
832 igmp
->querier_query_interval
);
834 "Query Response Interval : %lis\n",
837 "Robustness Variable : %d\n",
838 igmp
->querier_robustness_variable
);
840 "Startup Query Interval : %ds\n",
845 pim_print_ifp_flags(vty
, ifp
, mloop
);
851 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
852 json
, JSON_C_TO_STRING_PRETTY
));
853 json_object_free(json
);
856 vty_out(vty
, "%% No such interface\n");
860 static void igmp_show_interface_join(struct pim_instance
*pim
, struct vty
*vty
)
862 struct interface
*ifp
;
865 now
= pim_time_monotonic_sec();
868 "Interface Address Source Group Socket Uptime \n");
870 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
871 struct pim_interface
*pim_ifp
;
872 struct listnode
*join_node
;
873 struct igmp_join
*ij
;
874 struct in_addr pri_addr
;
875 char pri_addr_str
[INET_ADDRSTRLEN
];
882 if (!pim_ifp
->igmp_join_list
)
885 pri_addr
= pim_find_primary_addr(ifp
);
886 pim_inet4_dump("<pri?>", pri_addr
, pri_addr_str
,
887 sizeof(pri_addr_str
));
889 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_join_list
, join_node
,
891 char group_str
[INET_ADDRSTRLEN
];
892 char source_str
[INET_ADDRSTRLEN
];
895 pim_time_uptime(uptime
, sizeof(uptime
),
896 now
- ij
->sock_creation
);
897 pim_inet4_dump("<grp?>", ij
->group_addr
, group_str
,
899 pim_inet4_dump("<src?>", ij
->source_addr
, source_str
,
902 vty_out(vty
, "%-16s %-15s %-15s %-15s %6d %8s\n",
903 ifp
->name
, pri_addr_str
, source_str
, group_str
,
904 ij
->sock_fd
, uptime
);
905 } /* for (pim_ifp->igmp_join_list) */
910 static void pim_show_interfaces_single(struct pim_instance
*pim
,
911 struct vty
*vty
, const char *ifname
,
914 struct in_addr ifaddr
;
915 struct interface
*ifp
;
916 struct listnode
*neighnode
;
917 struct pim_interface
*pim_ifp
;
918 struct pim_neighbor
*neigh
;
919 struct pim_upstream
*up
;
921 char dr_str
[INET_ADDRSTRLEN
];
924 char grp_str
[INET_ADDRSTRLEN
];
925 char hello_period
[10];
926 char hello_timer
[10];
927 char neigh_src_str
[INET_ADDRSTRLEN
];
928 char src_str
[INET_ADDRSTRLEN
];
929 char stat_uptime
[10];
932 int found_ifname
= 0;
934 json_object
*json
= NULL
;
935 json_object
*json_row
= NULL
;
936 json_object
*json_pim_neighbor
= NULL
;
937 json_object
*json_pim_neighbors
= NULL
;
938 json_object
*json_group
= NULL
;
939 json_object
*json_group_source
= NULL
;
940 json_object
*json_fhr_sources
= NULL
;
941 struct pim_secondary_addr
*sec_addr
;
942 struct listnode
*sec_node
;
944 now
= pim_time_monotonic_sec();
947 json
= json_object_new_object();
949 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
955 if (mlag
== true && pim_ifp
->activeactive
== false)
958 if (strcmp(ifname
, "detail") && strcmp(ifname
, ifp
->name
))
962 ifaddr
= pim_ifp
->primary_address
;
963 pim_inet4_dump("<dr?>", pim_ifp
->pim_dr_addr
, dr_str
,
965 pim_time_uptime_begin(dr_uptime
, sizeof(dr_uptime
), now
,
966 pim_ifp
->pim_dr_election_last
);
967 pim_time_timer_to_hhmmss(hello_timer
, sizeof(hello_timer
),
968 pim_ifp
->t_pim_hello_timer
);
969 pim_time_mmss(hello_period
, sizeof(hello_period
),
970 pim_ifp
->pim_hello_period
);
971 pim_time_uptime(stat_uptime
, sizeof(stat_uptime
),
972 now
- pim_ifp
->pim_ifstat_start
);
973 if (pim_ifp
->pim_sock_fd
>= 0)
974 mloop
= pim_socket_mcastloop_get(pim_ifp
->pim_sock_fd
);
979 char pbuf
[PREFIX2STR_BUFFER
];
980 json_row
= json_object_new_object();
981 json_object_pim_ifp_add(json_row
, ifp
);
983 if (pim_ifp
->update_source
.s_addr
!= INADDR_ANY
) {
984 json_object_string_add(
985 json_row
, "useSource",
986 inet_ntoa(pim_ifp
->update_source
));
988 if (pim_ifp
->sec_addr_list
) {
989 json_object
*sec_list
= NULL
;
991 sec_list
= json_object_new_array();
992 for (ALL_LIST_ELEMENTS_RO(
993 pim_ifp
->sec_addr_list
, sec_node
,
995 json_object_array_add(
997 json_object_new_string(
1003 json_object_object_add(json_row
,
1004 "secondaryAddressList",
1009 if (pim_ifp
->pim_neighbor_list
->count
) {
1010 json_pim_neighbors
= json_object_new_object();
1012 for (ALL_LIST_ELEMENTS_RO(
1013 pim_ifp
->pim_neighbor_list
,
1014 neighnode
, neigh
)) {
1016 json_object_new_object();
1017 pim_inet4_dump("<src?>",
1020 sizeof(neigh_src_str
));
1021 pim_time_uptime(uptime
, sizeof(uptime
),
1022 now
- neigh
->creation
);
1023 pim_time_timer_to_hhmmss(
1024 expire
, sizeof(expire
),
1025 neigh
->t_expire_timer
);
1027 json_object_string_add(
1028 json_pim_neighbor
, "address",
1030 json_object_string_add(
1031 json_pim_neighbor
, "upTime",
1033 json_object_string_add(
1034 json_pim_neighbor
, "holdtime",
1037 json_object_object_add(
1043 json_object_object_add(json_row
, "neighbors",
1044 json_pim_neighbors
);
1047 json_object_string_add(json_row
, "drAddress", dr_str
);
1048 json_object_int_add(json_row
, "drPriority",
1049 pim_ifp
->pim_dr_priority
);
1050 json_object_string_add(json_row
, "drUptime", dr_uptime
);
1051 json_object_int_add(json_row
, "drElections",
1052 pim_ifp
->pim_dr_election_count
);
1053 json_object_int_add(json_row
, "drChanges",
1054 pim_ifp
->pim_dr_election_changes
);
1057 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
1058 if (ifp
!= up
->rpf
.source_nexthop
.interface
)
1061 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
))
1064 if (!json_fhr_sources
)
1066 json_object_new_object();
1068 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
,
1070 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
,
1072 pim_time_uptime(uptime
, sizeof(uptime
),
1073 now
- up
->state_transition
);
1076 * Does this group live in json_fhr_sources?
1079 json_object_object_get_ex(json_fhr_sources
,
1080 grp_str
, &json_group
);
1083 json_group
= json_object_new_object();
1084 json_object_object_add(json_fhr_sources
,
1089 json_group_source
= json_object_new_object();
1090 json_object_string_add(json_group_source
,
1092 json_object_string_add(json_group_source
,
1094 json_object_string_add(json_group_source
,
1096 json_object_object_add(json_group
, src_str
,
1100 if (json_fhr_sources
) {
1101 json_object_object_add(json_row
,
1106 json_object_int_add(json_row
, "helloPeriod",
1107 pim_ifp
->pim_hello_period
);
1108 json_object_string_add(json_row
, "helloTimer",
1110 json_object_string_add(json_row
, "helloStatStart",
1112 json_object_int_add(json_row
, "helloReceived",
1113 pim_ifp
->pim_ifstat_hello_recv
);
1114 json_object_int_add(json_row
, "helloReceivedFailed",
1115 pim_ifp
->pim_ifstat_hello_recvfail
);
1116 json_object_int_add(json_row
, "helloSend",
1117 pim_ifp
->pim_ifstat_hello_sent
);
1118 json_object_int_add(json_row
, "hellosendFailed",
1119 pim_ifp
->pim_ifstat_hello_sendfail
);
1120 json_object_int_add(json_row
, "helloGenerationId",
1121 pim_ifp
->pim_generation_id
);
1122 json_object_int_add(json_row
, "flagMulticastLoop",
1125 json_object_int_add(
1126 json_row
, "effectivePropagationDelay",
1127 pim_if_effective_propagation_delay_msec(ifp
));
1128 json_object_int_add(
1129 json_row
, "effectiveOverrideInterval",
1130 pim_if_effective_override_interval_msec(ifp
));
1131 json_object_int_add(
1132 json_row
, "joinPruneOverrideInterval",
1133 pim_if_jp_override_interval_msec(ifp
));
1135 json_object_int_add(
1136 json_row
, "propagationDelay",
1137 pim_ifp
->pim_propagation_delay_msec
);
1138 json_object_int_add(
1139 json_row
, "propagationDelayHighest",
1140 pim_ifp
->pim_neighbors_highest_propagation_delay_msec
);
1141 json_object_int_add(
1142 json_row
, "overrideInterval",
1143 pim_ifp
->pim_override_interval_msec
);
1144 json_object_int_add(
1145 json_row
, "overrideIntervalHighest",
1146 pim_ifp
->pim_neighbors_highest_override_interval_msec
);
1147 json_object_object_add(json
, ifp
->name
, json_row
);
1150 vty_out(vty
, "Interface : %s\n", ifp
->name
);
1151 vty_out(vty
, "State : %s\n",
1152 if_is_up(ifp
) ? "up" : "down");
1153 if (pim_ifp
->update_source
.s_addr
!= INADDR_ANY
) {
1154 vty_out(vty
, "Use Source : %s\n",
1155 inet_ntoa(pim_ifp
->update_source
));
1157 if (pim_ifp
->sec_addr_list
) {
1158 char pbuf
[PREFIX2STR_BUFFER
];
1159 vty_out(vty
, "Address : %s (primary)\n",
1161 for (ALL_LIST_ELEMENTS_RO(
1162 pim_ifp
->sec_addr_list
, sec_node
,
1164 vty_out(vty
, " %s\n",
1165 prefix2str(&sec_addr
->addr
,
1166 pbuf
, sizeof(pbuf
)));
1169 vty_out(vty
, "Address : %s\n",
1177 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
,
1178 neighnode
, neigh
)) {
1181 vty_out(vty
, "PIM Neighbors\n");
1182 vty_out(vty
, "-------------\n");
1186 pim_inet4_dump("<src?>", neigh
->source_addr
,
1188 sizeof(neigh_src_str
));
1189 pim_time_uptime(uptime
, sizeof(uptime
),
1190 now
- neigh
->creation
);
1191 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
1192 neigh
->t_expire_timer
);
1194 "%-15s : up for %s, holdtime expires in %s\n",
1195 neigh_src_str
, uptime
, expire
);
1198 if (!print_header
) {
1203 vty_out(vty
, "Designated Router\n");
1204 vty_out(vty
, "-----------------\n");
1205 vty_out(vty
, "Address : %s\n", dr_str
);
1206 vty_out(vty
, "Priority : %u(%d)\n",
1207 pim_ifp
->pim_dr_priority
,
1208 pim_ifp
->pim_dr_num_nondrpri_neighbors
);
1209 vty_out(vty
, "Uptime : %s\n", dr_uptime
);
1210 vty_out(vty
, "Elections : %d\n",
1211 pim_ifp
->pim_dr_election_count
);
1212 vty_out(vty
, "Changes : %d\n",
1213 pim_ifp
->pim_dr_election_changes
);
1219 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
1220 if (!up
->rpf
.source_nexthop
.interface
)
1223 if (strcmp(ifp
->name
,
1224 up
->rpf
.source_nexthop
1229 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
))
1234 "FHR - First Hop Router\n");
1236 "----------------------\n");
1240 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
,
1242 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
,
1244 pim_time_uptime(uptime
, sizeof(uptime
),
1245 now
- up
->state_transition
);
1247 "%s : %s is a source, uptime is %s\n",
1248 grp_str
, src_str
, uptime
);
1251 if (!print_header
) {
1256 vty_out(vty
, "Hellos\n");
1257 vty_out(vty
, "------\n");
1258 vty_out(vty
, "Period : %d\n",
1259 pim_ifp
->pim_hello_period
);
1260 vty_out(vty
, "Timer : %s\n", hello_timer
);
1261 vty_out(vty
, "StatStart : %s\n", stat_uptime
);
1262 vty_out(vty
, "Receive : %d\n",
1263 pim_ifp
->pim_ifstat_hello_recv
);
1264 vty_out(vty
, "Receive Failed : %d\n",
1265 pim_ifp
->pim_ifstat_hello_recvfail
);
1266 vty_out(vty
, "Send : %d\n",
1267 pim_ifp
->pim_ifstat_hello_sent
);
1268 vty_out(vty
, "Send Failed : %d\n",
1269 pim_ifp
->pim_ifstat_hello_sendfail
);
1270 vty_out(vty
, "Generation ID : %08x\n",
1271 pim_ifp
->pim_generation_id
);
1275 pim_print_ifp_flags(vty
, ifp
, mloop
);
1277 vty_out(vty
, "Join Prune Interval\n");
1278 vty_out(vty
, "-------------------\n");
1279 vty_out(vty
, "LAN Delay : %s\n",
1280 pim_if_lan_delay_enabled(ifp
) ? "yes" : "no");
1281 vty_out(vty
, "Effective Propagation Delay : %d msec\n",
1282 pim_if_effective_propagation_delay_msec(ifp
));
1283 vty_out(vty
, "Effective Override Interval : %d msec\n",
1284 pim_if_effective_override_interval_msec(ifp
));
1285 vty_out(vty
, "Join Prune Override Interval : %d msec\n",
1286 pim_if_jp_override_interval_msec(ifp
));
1290 vty_out(vty
, "LAN Prune Delay\n");
1291 vty_out(vty
, "---------------\n");
1292 vty_out(vty
, "Propagation Delay : %d msec\n",
1293 pim_ifp
->pim_propagation_delay_msec
);
1294 vty_out(vty
, "Propagation Delay (Highest) : %d msec\n",
1295 pim_ifp
->pim_neighbors_highest_propagation_delay_msec
);
1296 vty_out(vty
, "Override Interval : %d msec\n",
1297 pim_ifp
->pim_override_interval_msec
);
1298 vty_out(vty
, "Override Interval (Highest) : %d msec\n",
1299 pim_ifp
->pim_neighbors_highest_override_interval_msec
);
1306 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1307 json
, JSON_C_TO_STRING_PRETTY
));
1308 json_object_free(json
);
1311 vty_out(vty
, "%% No such interface\n");
1315 static void igmp_show_statistics(struct pim_instance
*pim
, struct vty
*vty
,
1316 const char *ifname
, bool uj
)
1318 struct interface
*ifp
;
1319 struct igmp_stats rx_stats
;
1321 igmp_stats_init(&rx_stats
);
1323 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1324 struct pim_interface
*pim_ifp
;
1325 struct listnode
*sock_node
;
1326 struct igmp_sock
*igmp
;
1328 pim_ifp
= ifp
->info
;
1333 if (ifname
&& strcmp(ifname
, ifp
->name
))
1336 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
1338 igmp_stats_add(&rx_stats
, &igmp
->rx_stats
);
1342 json_object
*json
= NULL
;
1343 json_object
*json_row
= NULL
;
1345 json
= json_object_new_object();
1346 json_row
= json_object_new_object();
1348 json_object_string_add(json_row
, "name", ifname
? ifname
:
1350 json_object_int_add(json_row
, "queryV1", rx_stats
.query_v1
);
1351 json_object_int_add(json_row
, "queryV2", rx_stats
.query_v2
);
1352 json_object_int_add(json_row
, "queryV3", rx_stats
.query_v3
);
1353 json_object_int_add(json_row
, "leaveV3", rx_stats
.leave_v2
);
1354 json_object_int_add(json_row
, "reportV1", rx_stats
.report_v1
);
1355 json_object_int_add(json_row
, "reportV2", rx_stats
.report_v2
);
1356 json_object_int_add(json_row
, "reportV3", rx_stats
.report_v3
);
1357 json_object_int_add(json_row
, "mtraceResponse",
1358 rx_stats
.mtrace_rsp
);
1359 json_object_int_add(json_row
, "mtraceRequest",
1360 rx_stats
.mtrace_req
);
1361 json_object_int_add(json_row
, "unsupported",
1362 rx_stats
.unsupported
);
1363 json_object_object_add(json
, ifname
? ifname
: "global",
1365 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1366 json
, JSON_C_TO_STRING_PRETTY
));
1367 json_object_free(json
);
1369 vty_out(vty
, "IGMP RX statistics\n");
1370 vty_out(vty
, "Interface : %s\n",
1371 ifname
? ifname
: "global");
1372 vty_out(vty
, "V1 query : %u\n", rx_stats
.query_v1
);
1373 vty_out(vty
, "V2 query : %u\n", rx_stats
.query_v2
);
1374 vty_out(vty
, "V3 query : %u\n", rx_stats
.query_v3
);
1375 vty_out(vty
, "V2 leave : %u\n", rx_stats
.leave_v2
);
1376 vty_out(vty
, "V1 report : %u\n", rx_stats
.report_v1
);
1377 vty_out(vty
, "V2 report : %u\n", rx_stats
.report_v2
);
1378 vty_out(vty
, "V3 report : %u\n", rx_stats
.report_v3
);
1379 vty_out(vty
, "mtrace response : %u\n", rx_stats
.mtrace_rsp
);
1380 vty_out(vty
, "mtrace request : %u\n", rx_stats
.mtrace_req
);
1381 vty_out(vty
, "unsupported : %u\n", rx_stats
.unsupported
);
1385 static void pim_show_interfaces(struct pim_instance
*pim
, struct vty
*vty
,
1388 struct interface
*ifp
;
1389 struct pim_interface
*pim_ifp
;
1390 struct pim_upstream
*up
;
1393 int pim_ifchannels
= 0;
1394 json_object
*json
= NULL
;
1395 json_object
*json_row
= NULL
;
1396 json_object
*json_tmp
;
1398 json
= json_object_new_object();
1400 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1401 pim_ifp
= ifp
->info
;
1406 if (mlag
== true && pim_ifp
->activeactive
== false)
1409 pim_nbrs
= pim_ifp
->pim_neighbor_list
->count
;
1410 pim_ifchannels
= pim_if_ifchannel_count(pim_ifp
);
1413 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
)
1414 if (ifp
== up
->rpf
.source_nexthop
.interface
)
1415 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
1418 json_row
= json_object_new_object();
1419 json_object_pim_ifp_add(json_row
, ifp
);
1420 json_object_int_add(json_row
, "pimNeighbors", pim_nbrs
);
1421 json_object_int_add(json_row
, "pimIfChannels", pim_ifchannels
);
1422 json_object_int_add(json_row
, "firstHopRouterCount", fhr
);
1423 json_object_string_add(json_row
, "pimDesignatedRouter",
1424 inet_ntoa(pim_ifp
->pim_dr_addr
));
1426 if (pim_ifp
->pim_dr_addr
.s_addr
1427 == pim_ifp
->primary_address
.s_addr
)
1428 json_object_boolean_true_add(
1429 json_row
, "pimDesignatedRouterLocal");
1431 json_object_object_add(json
, ifp
->name
, json_row
);
1435 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1436 json
, JSON_C_TO_STRING_PRETTY
));
1439 "Interface State Address PIM Nbrs PIM DR FHR IfChannels\n");
1441 json_object_object_foreach(json
, key
, val
)
1443 vty_out(vty
, "%-16s ", key
);
1445 json_object_object_get_ex(val
, "state", &json_tmp
);
1446 vty_out(vty
, "%5s ", json_object_get_string(json_tmp
));
1448 json_object_object_get_ex(val
, "address", &json_tmp
);
1449 vty_out(vty
, "%15s ",
1450 json_object_get_string(json_tmp
));
1452 json_object_object_get_ex(val
, "pimNeighbors",
1454 vty_out(vty
, "%8d ", json_object_get_int(json_tmp
));
1456 if (json_object_object_get_ex(
1457 val
, "pimDesignatedRouterLocal",
1459 vty_out(vty
, "%15s ", "local");
1461 json_object_object_get_ex(
1462 val
, "pimDesignatedRouter", &json_tmp
);
1463 vty_out(vty
, "%15s ",
1464 json_object_get_string(json_tmp
));
1467 json_object_object_get_ex(val
, "firstHopRouter",
1469 vty_out(vty
, "%3d ", json_object_get_int(json_tmp
));
1471 json_object_object_get_ex(val
, "pimIfChannels",
1473 vty_out(vty
, "%9d\n", json_object_get_int(json_tmp
));
1477 json_object_free(json
);
1480 static void pim_show_interface_traffic(struct pim_instance
*pim
,
1481 struct vty
*vty
, bool uj
)
1483 struct interface
*ifp
= NULL
;
1484 struct pim_interface
*pim_ifp
= NULL
;
1485 json_object
*json
= NULL
;
1486 json_object
*json_row
= NULL
;
1489 json
= json_object_new_object();
1492 vty_out(vty
, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s%-17s\n",
1493 "Interface", " HELLO", " JOIN",
1494 " PRUNE", " REGISTER", "REGISTER-STOP",
1496 vty_out(vty
, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s%-17s\n", "",
1497 " Rx/Tx", " Rx/Tx", " Rx/Tx",
1498 " Rx/Tx", " Rx/Tx", " Rx/Tx",
1501 "---------------------------------------------------------------------------------------------------------------\n");
1504 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1505 pim_ifp
= ifp
->info
;
1510 if (pim_ifp
->pim_sock_fd
< 0)
1513 json_row
= json_object_new_object();
1514 json_object_pim_ifp_add(json_row
, ifp
);
1515 json_object_int_add(json_row
, "helloRx",
1516 pim_ifp
->pim_ifstat_hello_recv
);
1517 json_object_int_add(json_row
, "helloTx",
1518 pim_ifp
->pim_ifstat_hello_sent
);
1519 json_object_int_add(json_row
, "joinRx",
1520 pim_ifp
->pim_ifstat_join_recv
);
1521 json_object_int_add(json_row
, "joinTx",
1522 pim_ifp
->pim_ifstat_join_send
);
1523 json_object_int_add(json_row
, "pruneTx",
1524 pim_ifp
->pim_ifstat_prune_send
);
1525 json_object_int_add(json_row
, "pruneRx",
1526 pim_ifp
->pim_ifstat_prune_recv
);
1527 json_object_int_add(json_row
, "registerRx",
1528 pim_ifp
->pim_ifstat_reg_recv
);
1529 json_object_int_add(json_row
, "registerTx",
1530 pim_ifp
->pim_ifstat_reg_recv
);
1531 json_object_int_add(json_row
, "registerStopRx",
1532 pim_ifp
->pim_ifstat_reg_stop_recv
);
1533 json_object_int_add(json_row
, "registerStopTx",
1534 pim_ifp
->pim_ifstat_reg_stop_send
);
1535 json_object_int_add(json_row
, "assertRx",
1536 pim_ifp
->pim_ifstat_assert_recv
);
1537 json_object_int_add(json_row
, "assertTx",
1538 pim_ifp
->pim_ifstat_assert_send
);
1539 json_object_int_add(json_row
, "bsmRx",
1540 pim_ifp
->pim_ifstat_bsm_rx
);
1541 json_object_int_add(json_row
, "bsmTx",
1542 pim_ifp
->pim_ifstat_bsm_tx
);
1543 json_object_object_add(json
, ifp
->name
, json_row
);
1546 "%-16s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7" PRIu64
"/%-7" PRIu64
"\n",
1547 ifp
->name
, pim_ifp
->pim_ifstat_hello_recv
,
1548 pim_ifp
->pim_ifstat_hello_sent
,
1549 pim_ifp
->pim_ifstat_join_recv
,
1550 pim_ifp
->pim_ifstat_join_send
,
1551 pim_ifp
->pim_ifstat_prune_recv
,
1552 pim_ifp
->pim_ifstat_prune_send
,
1553 pim_ifp
->pim_ifstat_reg_recv
,
1554 pim_ifp
->pim_ifstat_reg_send
,
1555 pim_ifp
->pim_ifstat_reg_stop_recv
,
1556 pim_ifp
->pim_ifstat_reg_stop_send
,
1557 pim_ifp
->pim_ifstat_assert_recv
,
1558 pim_ifp
->pim_ifstat_assert_send
,
1559 pim_ifp
->pim_ifstat_bsm_rx
,
1560 pim_ifp
->pim_ifstat_bsm_tx
);
1564 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1565 json
, JSON_C_TO_STRING_PRETTY
));
1566 json_object_free(json
);
1570 static void pim_show_interface_traffic_single(struct pim_instance
*pim
,
1572 const char *ifname
, bool uj
)
1574 struct interface
*ifp
= NULL
;
1575 struct pim_interface
*pim_ifp
= NULL
;
1576 json_object
*json
= NULL
;
1577 json_object
*json_row
= NULL
;
1578 uint8_t found_ifname
= 0;
1581 json
= json_object_new_object();
1584 vty_out(vty
, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s%-17s\n",
1585 "Interface", " HELLO", " JOIN", " PRUNE",
1586 " REGISTER", " REGISTER-STOP", " ASSERT",
1588 vty_out(vty
, "%-14s%-18s%-17s%-17s%-17s%-17s%-17s%-17s\n", "",
1589 " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1590 " Rx/Tx", " Rx/Tx", " Rx/Tx");
1592 "-------------------------------------------------------------------------------------------------------------------------------\n");
1595 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1596 if (strcmp(ifname
, ifp
->name
))
1599 pim_ifp
= ifp
->info
;
1604 if (pim_ifp
->pim_sock_fd
< 0)
1609 json_row
= json_object_new_object();
1610 json_object_pim_ifp_add(json_row
, ifp
);
1611 json_object_int_add(json_row
, "helloRx",
1612 pim_ifp
->pim_ifstat_hello_recv
);
1613 json_object_int_add(json_row
, "helloTx",
1614 pim_ifp
->pim_ifstat_hello_sent
);
1615 json_object_int_add(json_row
, "joinRx",
1616 pim_ifp
->pim_ifstat_join_recv
);
1617 json_object_int_add(json_row
, "joinTx",
1618 pim_ifp
->pim_ifstat_join_send
);
1619 json_object_int_add(json_row
, "registerRx",
1620 pim_ifp
->pim_ifstat_reg_recv
);
1621 json_object_int_add(json_row
, "registerTx",
1622 pim_ifp
->pim_ifstat_reg_recv
);
1623 json_object_int_add(json_row
, "registerStopRx",
1624 pim_ifp
->pim_ifstat_reg_stop_recv
);
1625 json_object_int_add(json_row
, "registerStopTx",
1626 pim_ifp
->pim_ifstat_reg_stop_send
);
1627 json_object_int_add(json_row
, "assertRx",
1628 pim_ifp
->pim_ifstat_assert_recv
);
1629 json_object_int_add(json_row
, "assertTx",
1630 pim_ifp
->pim_ifstat_assert_send
);
1631 json_object_int_add(json_row
, "bsmRx",
1632 pim_ifp
->pim_ifstat_bsm_rx
);
1633 json_object_int_add(json_row
, "bsmTx",
1634 pim_ifp
->pim_ifstat_bsm_tx
);
1636 json_object_object_add(json
, ifp
->name
, json_row
);
1639 "%-16s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7" PRIu64
"/%-7" PRIu64
"\n",
1640 ifp
->name
, pim_ifp
->pim_ifstat_hello_recv
,
1641 pim_ifp
->pim_ifstat_hello_sent
,
1642 pim_ifp
->pim_ifstat_join_recv
,
1643 pim_ifp
->pim_ifstat_join_send
,
1644 pim_ifp
->pim_ifstat_prune_recv
,
1645 pim_ifp
->pim_ifstat_prune_send
,
1646 pim_ifp
->pim_ifstat_reg_recv
,
1647 pim_ifp
->pim_ifstat_reg_send
,
1648 pim_ifp
->pim_ifstat_reg_stop_recv
,
1649 pim_ifp
->pim_ifstat_reg_stop_send
,
1650 pim_ifp
->pim_ifstat_assert_recv
,
1651 pim_ifp
->pim_ifstat_assert_send
,
1652 pim_ifp
->pim_ifstat_bsm_rx
,
1653 pim_ifp
->pim_ifstat_bsm_tx
);
1657 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1658 json
, JSON_C_TO_STRING_PRETTY
));
1659 json_object_free(json
);
1662 vty_out(vty
, "%% No such interface\n");
1666 static void pim_show_join_helper(struct vty
*vty
, struct pim_interface
*pim_ifp
,
1667 struct pim_ifchannel
*ch
, json_object
*json
,
1668 time_t now
, bool uj
)
1670 char ch_src_str
[INET_ADDRSTRLEN
];
1671 char ch_grp_str
[INET_ADDRSTRLEN
];
1672 json_object
*json_iface
= NULL
;
1673 json_object
*json_row
= NULL
;
1674 json_object
*json_grp
= NULL
;
1675 struct in_addr ifaddr
;
1680 ifaddr
= pim_ifp
->primary_address
;
1682 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
1683 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
1685 pim_time_uptime_begin(uptime
, sizeof(uptime
), now
, ch
->ifjoin_creation
);
1686 pim_time_timer_to_mmss(expire
, sizeof(expire
),
1687 ch
->t_ifjoin_expiry_timer
);
1688 pim_time_timer_to_mmss(prune
, sizeof(prune
),
1689 ch
->t_ifjoin_prune_pending_timer
);
1692 json_object_object_get_ex(json
, ch
->interface
->name
,
1696 json_iface
= json_object_new_object();
1697 json_object_pim_ifp_add(json_iface
, ch
->interface
);
1698 json_object_object_add(json
, ch
->interface
->name
,
1702 json_row
= json_object_new_object();
1703 json_object_string_add(json_row
, "source", ch_src_str
);
1704 json_object_string_add(json_row
, "group", ch_grp_str
);
1705 json_object_string_add(json_row
, "upTime", uptime
);
1706 json_object_string_add(json_row
, "expire", expire
);
1707 json_object_string_add(json_row
, "prune", prune
);
1708 json_object_string_add(
1709 json_row
, "channelJoinName",
1710 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
, ch
->flags
));
1711 if (PIM_IF_FLAG_TEST_S_G_RPT(ch
->flags
))
1712 json_object_int_add(json_row
, "SGRpt", 1);
1713 if (PIM_IF_FLAG_TEST_PROTO_PIM(ch
->flags
))
1714 json_object_int_add(json_row
, "protocolPim", 1);
1715 if (PIM_IF_FLAG_TEST_PROTO_IGMP(ch
->flags
))
1716 json_object_int_add(json_row
, "protocolIgmp", 1);
1717 json_object_object_get_ex(json_iface
, ch_grp_str
, &json_grp
);
1719 json_grp
= json_object_new_object();
1720 json_object_object_add(json_grp
, ch_src_str
, json_row
);
1721 json_object_object_add(json_iface
, ch_grp_str
,
1724 json_object_object_add(json_grp
, ch_src_str
, json_row
);
1726 vty_out(vty
, "%-16s %-15s %-15s %-15s %-10s %8s %-6s %5s\n",
1727 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
,
1729 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
, ch
->flags
),
1730 uptime
, expire
, prune
);
1734 static void pim_show_join(struct pim_instance
*pim
, struct vty
*vty
,
1735 struct prefix_sg
*sg
, bool uj
)
1737 struct pim_interface
*pim_ifp
;
1738 struct pim_ifchannel
*ch
;
1739 struct interface
*ifp
;
1741 json_object
*json
= NULL
;
1743 now
= pim_time_monotonic_sec();
1746 json
= json_object_new_object();
1749 "Interface Address Source Group State Uptime Expire Prune\n");
1751 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1752 pim_ifp
= ifp
->info
;
1756 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
1757 if (sg
->grp
.s_addr
!= INADDR_ANY
1758 && sg
->grp
.s_addr
!= ch
->sg
.grp
.s_addr
)
1760 if (sg
->src
.s_addr
!= INADDR_ANY
1761 && sg
->src
.s_addr
!= ch
->sg
.src
.s_addr
)
1763 pim_show_join_helper(vty
, pim_ifp
, ch
, json
, now
, uj
);
1764 } /* scan interface channels */
1768 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1769 json
, JSON_C_TO_STRING_PRETTY
));
1770 json_object_free(json
);
1774 static void pim_show_neighbors_single(struct pim_instance
*pim
, struct vty
*vty
,
1775 const char *neighbor
, bool uj
)
1777 struct listnode
*neighnode
;
1778 struct interface
*ifp
;
1779 struct pim_interface
*pim_ifp
;
1780 struct pim_neighbor
*neigh
;
1782 int found_neighbor
= 0;
1783 int option_address_list
;
1784 int option_dr_priority
;
1785 int option_generation_id
;
1786 int option_holdtime
;
1787 int option_lan_prune_delay
;
1791 char neigh_src_str
[INET_ADDRSTRLEN
];
1793 json_object
*json
= NULL
;
1794 json_object
*json_ifp
= NULL
;
1795 json_object
*json_row
= NULL
;
1797 now
= pim_time_monotonic_sec();
1800 json
= json_object_new_object();
1802 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1803 pim_ifp
= ifp
->info
;
1808 if (pim_ifp
->pim_sock_fd
< 0)
1811 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
1813 pim_inet4_dump("<src?>", neigh
->source_addr
,
1814 neigh_src_str
, sizeof(neigh_src_str
));
1817 * The user can specify either the interface name or the
1819 * If this pim_ifp matches neither then skip.
1821 if (strcmp(neighbor
, "detail")
1822 && strcmp(neighbor
, ifp
->name
)
1823 && strcmp(neighbor
, neigh_src_str
))
1827 pim_time_uptime(uptime
, sizeof(uptime
),
1828 now
- neigh
->creation
);
1829 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
1830 neigh
->t_expire_timer
);
1832 option_address_list
= 0;
1833 option_dr_priority
= 0;
1834 option_generation_id
= 0;
1835 option_holdtime
= 0;
1836 option_lan_prune_delay
= 0;
1839 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1840 PIM_OPTION_MASK_ADDRESS_LIST
))
1841 option_address_list
= 1;
1843 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1844 PIM_OPTION_MASK_DR_PRIORITY
))
1845 option_dr_priority
= 1;
1847 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1848 PIM_OPTION_MASK_GENERATION_ID
))
1849 option_generation_id
= 1;
1851 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1852 PIM_OPTION_MASK_HOLDTIME
))
1853 option_holdtime
= 1;
1855 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1856 PIM_OPTION_MASK_LAN_PRUNE_DELAY
))
1857 option_lan_prune_delay
= 1;
1859 if (PIM_OPTION_IS_SET(
1860 neigh
->hello_options
,
1861 PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION
))
1866 /* Does this ifp live in json? If not create
1868 json_object_object_get_ex(json
, ifp
->name
,
1872 json_ifp
= json_object_new_object();
1873 json_object_pim_ifp_add(json_ifp
, ifp
);
1874 json_object_object_add(json
, ifp
->name
,
1878 json_row
= json_object_new_object();
1879 json_object_string_add(json_row
, "interface",
1881 json_object_string_add(json_row
, "address",
1883 json_object_string_add(json_row
, "upTime",
1885 json_object_string_add(json_row
, "holdtime",
1887 json_object_int_add(json_row
, "drPriority",
1888 neigh
->dr_priority
);
1889 json_object_int_add(json_row
, "generationId",
1890 neigh
->generation_id
);
1892 if (option_address_list
)
1893 json_object_boolean_true_add(
1895 "helloOptionAddressList");
1897 if (option_dr_priority
)
1898 json_object_boolean_true_add(
1900 "helloOptionDrPriority");
1902 if (option_generation_id
)
1903 json_object_boolean_true_add(
1905 "helloOptionGenerationId");
1907 if (option_holdtime
)
1908 json_object_boolean_true_add(
1910 "helloOptionHoldtime");
1912 if (option_lan_prune_delay
)
1913 json_object_boolean_true_add(
1915 "helloOptionLanPruneDelay");
1918 json_object_boolean_true_add(
1919 json_row
, "helloOptionTBit");
1921 json_object_object_add(json_ifp
, neigh_src_str
,
1925 vty_out(vty
, "Interface : %s\n", ifp
->name
);
1926 vty_out(vty
, "Neighbor : %s\n", neigh_src_str
);
1934 " DR Priority : %d\n",
1935 neigh
->dr_priority
);
1937 " Generation ID : %08x\n",
1938 neigh
->generation_id
);
1940 " Override Interval (msec) : %d\n",
1941 neigh
->override_interval_msec
);
1943 " Propagation Delay (msec) : %d\n",
1944 neigh
->propagation_delay_msec
);
1946 " Hello Option - Address List : %s\n",
1947 option_address_list
? "yes" : "no");
1949 " Hello Option - DR Priority : %s\n",
1950 option_dr_priority
? "yes" : "no");
1952 " Hello Option - Generation ID : %s\n",
1953 option_generation_id
? "yes" : "no");
1955 " Hello Option - Holdtime : %s\n",
1956 option_holdtime
? "yes" : "no");
1958 " Hello Option - LAN Prune Delay : %s\n",
1959 option_lan_prune_delay
? "yes" : "no");
1961 " Hello Option - T-bit : %s\n",
1962 option_t_bit
? "yes" : "no");
1963 pim_bfd_show_info(vty
, neigh
->bfd_info
,
1971 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1972 json
, JSON_C_TO_STRING_PRETTY
));
1973 json_object_free(json
);
1976 if (!found_neighbor
)
1978 "%% No such interface or neighbor\n");
1983 static void pim_show_state(struct pim_instance
*pim
, struct vty
*vty
,
1984 const char *src_or_group
, const char *group
, bool uj
)
1986 struct channel_oil
*c_oil
;
1987 json_object
*json
= NULL
;
1988 json_object
*json_group
= NULL
;
1989 json_object
*json_ifp_in
= NULL
;
1990 json_object
*json_ifp_out
= NULL
;
1991 json_object
*json_source
= NULL
;
1994 now
= pim_time_monotonic_sec();
1997 json
= json_object_new_object();
2000 "Codes: J -> Pim Join, I -> IGMP Report, S -> Source, * -> Inherited from (*,G), V -> VxLAN, M -> Muted");
2002 "\nActive Source Group RPT IIF OIL\n");
2005 frr_each (rb_pim_oil
, &pim
->channel_oil_head
, c_oil
) {
2006 char grp_str
[INET_ADDRSTRLEN
];
2007 char src_str
[INET_ADDRSTRLEN
];
2008 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
2009 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
2011 struct interface
*ifp_in
;
2016 PIM_UPSTREAM_FLAG_TEST_USE_RPT(c_oil
->up
->flags
)) ||
2017 c_oil
->oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
2022 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
2024 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
2026 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
2029 strlcpy(in_ifname
, ifp_in
->name
, sizeof(in_ifname
));
2031 strlcpy(in_ifname
, "<iif?>", sizeof(in_ifname
));
2034 if (strcmp(src_or_group
, src_str
)
2035 && strcmp(src_or_group
, grp_str
))
2038 if (group
&& strcmp(group
, grp_str
))
2044 /* Find the group, create it if it doesn't exist */
2045 json_object_object_get_ex(json
, grp_str
, &json_group
);
2048 json_group
= json_object_new_object();
2049 json_object_object_add(json
, grp_str
,
2053 /* Find the source nested under the group, create it if
2054 * it doesn't exist */
2055 json_object_object_get_ex(json_group
, src_str
,
2059 json_source
= json_object_new_object();
2060 json_object_object_add(json_group
, src_str
,
2064 /* Find the inbound interface nested under the source,
2065 * create it if it doesn't exist */
2066 json_object_object_get_ex(json_source
, in_ifname
,
2070 json_ifp_in
= json_object_new_object();
2071 json_object_object_add(json_source
, in_ifname
,
2073 json_object_int_add(json_source
, "Installed",
2076 json_object_boolean_true_add(
2077 json_source
, "isRpt");
2079 json_object_boolean_false_add(
2080 json_source
, "isRpt");
2081 json_object_int_add(json_source
, "RefCount",
2082 c_oil
->oil_ref_count
);
2083 json_object_int_add(json_source
, "OilListSize",
2085 json_object_int_add(
2086 json_source
, "OilRescan",
2087 c_oil
->oil_inherited_rescan
);
2088 json_object_int_add(json_source
, "LastUsed",
2089 c_oil
->cc
.lastused
);
2090 json_object_int_add(json_source
, "PacketCount",
2092 json_object_int_add(json_source
, "ByteCount",
2094 json_object_int_add(json_source
,
2096 c_oil
->cc
.wrong_if
);
2099 vty_out(vty
, "%-6d %-15s %-15s %-3s %-16s ",
2100 c_oil
->installed
, src_str
, grp_str
,
2101 isRpt
? "y" : "n", in_ifname
);
2104 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
2106 struct interface
*ifp_out
;
2107 char oif_uptime
[10];
2110 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
2114 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
2116 oif_uptime
, sizeof(oif_uptime
),
2117 now
- c_oil
->oif_creation
[oif_vif_index
]);
2120 strlcpy(out_ifname
, ifp_out
->name
, sizeof(out_ifname
));
2122 strlcpy(out_ifname
, "<oif?>", sizeof(out_ifname
));
2125 json_ifp_out
= json_object_new_object();
2126 json_object_string_add(json_ifp_out
, "source",
2128 json_object_string_add(json_ifp_out
, "group",
2130 json_object_string_add(json_ifp_out
,
2133 json_object_string_add(json_ifp_out
,
2134 "outboundInterface",
2136 json_object_int_add(json_ifp_out
, "installed",
2139 json_object_object_add(json_ifp_in
, out_ifname
,
2144 vty_out(vty
, "%s(%c%c%c%c%c)",
2146 (c_oil
->oif_flags
[oif_vif_index
]
2147 & PIM_OIF_FLAG_PROTO_IGMP
)
2150 (c_oil
->oif_flags
[oif_vif_index
]
2151 & PIM_OIF_FLAG_PROTO_PIM
)
2154 (c_oil
->oif_flags
[oif_vif_index
]
2155 & PIM_OIF_FLAG_PROTO_VXLAN
)
2158 (c_oil
->oif_flags
[oif_vif_index
]
2159 & PIM_OIF_FLAG_PROTO_STAR
)
2162 (c_oil
->oif_flags
[oif_vif_index
]
2163 & PIM_OIF_FLAG_MUTE
)
2167 vty_out(vty
, ", %s(%c%c%c%c%c)",
2169 (c_oil
->oif_flags
[oif_vif_index
]
2170 & PIM_OIF_FLAG_PROTO_IGMP
)
2173 (c_oil
->oif_flags
[oif_vif_index
]
2174 & PIM_OIF_FLAG_PROTO_PIM
)
2177 (c_oil
->oif_flags
[oif_vif_index
]
2178 & PIM_OIF_FLAG_PROTO_VXLAN
)
2181 (c_oil
->oif_flags
[oif_vif_index
]
2182 & PIM_OIF_FLAG_PROTO_STAR
)
2185 (c_oil
->oif_flags
[oif_vif_index
]
2186 & PIM_OIF_FLAG_MUTE
)
2198 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2199 json
, JSON_C_TO_STRING_PRETTY
));
2200 json_object_free(json
);
2206 static void pim_show_neighbors(struct pim_instance
*pim
, struct vty
*vty
,
2209 struct listnode
*neighnode
;
2210 struct interface
*ifp
;
2211 struct pim_interface
*pim_ifp
;
2212 struct pim_neighbor
*neigh
;
2216 char neigh_src_str
[INET_ADDRSTRLEN
];
2217 json_object
*json
= NULL
;
2218 json_object
*json_ifp_rows
= NULL
;
2219 json_object
*json_row
= NULL
;
2221 now
= pim_time_monotonic_sec();
2224 json
= json_object_new_object();
2227 "Interface Neighbor Uptime Holdtime DR Pri\n");
2230 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2231 pim_ifp
= ifp
->info
;
2236 if (pim_ifp
->pim_sock_fd
< 0)
2240 json_ifp_rows
= json_object_new_object();
2242 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
2244 pim_inet4_dump("<src?>", neigh
->source_addr
,
2245 neigh_src_str
, sizeof(neigh_src_str
));
2246 pim_time_uptime(uptime
, sizeof(uptime
),
2247 now
- neigh
->creation
);
2248 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
2249 neigh
->t_expire_timer
);
2252 json_row
= json_object_new_object();
2253 json_object_string_add(json_row
, "interface",
2255 json_object_string_add(json_row
, "neighbor",
2257 json_object_string_add(json_row
, "upTime",
2259 json_object_string_add(json_row
, "holdTime",
2261 json_object_int_add(json_row
, "holdTimeMax",
2263 json_object_int_add(json_row
, "drPriority",
2264 neigh
->dr_priority
);
2265 json_object_object_add(json_ifp_rows
,
2266 neigh_src_str
, json_row
);
2269 vty_out(vty
, "%-16s %15s %8s %8s %6d\n",
2270 ifp
->name
, neigh_src_str
, uptime
,
2271 expire
, neigh
->dr_priority
);
2276 json_object_object_add(json
, ifp
->name
, json_ifp_rows
);
2277 json_ifp_rows
= NULL
;
2282 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2283 json
, JSON_C_TO_STRING_PRETTY
));
2284 json_object_free(json
);
2288 static void pim_show_neighbors_secondary(struct pim_instance
*pim
,
2291 struct interface
*ifp
;
2294 "Interface Address Neighbor Secondary \n");
2296 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2297 struct pim_interface
*pim_ifp
;
2298 struct in_addr ifaddr
;
2299 struct listnode
*neighnode
;
2300 struct pim_neighbor
*neigh
;
2302 pim_ifp
= ifp
->info
;
2307 if (pim_ifp
->pim_sock_fd
< 0)
2310 ifaddr
= pim_ifp
->primary_address
;
2312 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
2314 char neigh_src_str
[INET_ADDRSTRLEN
];
2315 struct listnode
*prefix_node
;
2318 if (!neigh
->prefix_list
)
2321 pim_inet4_dump("<src?>", neigh
->source_addr
,
2322 neigh_src_str
, sizeof(neigh_src_str
));
2324 for (ALL_LIST_ELEMENTS_RO(neigh
->prefix_list
,
2326 char neigh_sec_str
[PREFIX2STR_BUFFER
];
2328 prefix2str(p
, neigh_sec_str
,
2329 sizeof(neigh_sec_str
));
2331 vty_out(vty
, "%-16s %-15s %-15s %-15s\n",
2332 ifp
->name
, inet_ntoa(ifaddr
),
2333 neigh_src_str
, neigh_sec_str
);
2339 static void json_object_pim_upstream_add(json_object
*json
,
2340 struct pim_upstream
*up
)
2342 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED
)
2343 json_object_boolean_true_add(json
, "drJoinDesired");
2345 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED
)
2346 json_object_boolean_true_add(json
, "drJoinDesiredUpdated");
2348 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
2349 json_object_boolean_true_add(json
, "firstHopRouter");
2351 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_IGMP
)
2352 json_object_boolean_true_add(json
, "sourceIgmp");
2354 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_PIM
)
2355 json_object_boolean_true_add(json
, "sourcePim");
2357 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_STREAM
)
2358 json_object_boolean_true_add(json
, "sourceStream");
2360 /* XXX: need to print ths flag in the plain text display as well */
2361 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_MSDP
)
2362 json_object_boolean_true_add(json
, "sourceMsdp");
2364 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SEND_SG_RPT_PRUNE
)
2365 json_object_boolean_true_add(json
, "sendSGRptPrune");
2367 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_LHR
)
2368 json_object_boolean_true_add(json
, "lastHopRouter");
2370 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DISABLE_KAT_EXPIRY
)
2371 json_object_boolean_true_add(json
, "disableKATExpiry");
2373 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_STATIC_IIF
)
2374 json_object_boolean_true_add(json
, "staticIncomingInterface");
2376 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_ALLOW_IIF_IN_OIL
)
2377 json_object_boolean_true_add(json
,
2378 "allowIncomingInterfaceinOil");
2380 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_NO_PIMREG_DATA
)
2381 json_object_boolean_true_add(json
, "noPimRegistrationData");
2383 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FORCE_PIMREG
)
2384 json_object_boolean_true_add(json
, "forcePimRegistration");
2386 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_ORIG
)
2387 json_object_boolean_true_add(json
, "sourceVxlanOrigination");
2389 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_TERM
)
2390 json_object_boolean_true_add(json
, "sourceVxlanTermination");
2392 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_VXLAN
)
2393 json_object_boolean_true_add(json
, "mlagVxlan");
2395 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_NON_DF
)
2396 json_object_boolean_true_add(json
,
2397 "mlagNonDesignatedForwarder");
2401 pim_upstream_state2brief_str(enum pim_upstream_state join_state
,
2402 char *state_str
, size_t state_str_len
)
2404 switch (join_state
) {
2405 case PIM_UPSTREAM_NOTJOINED
:
2406 strlcpy(state_str
, "NotJ", state_str_len
);
2408 case PIM_UPSTREAM_JOINED
:
2409 strlcpy(state_str
, "J", state_str_len
);
2412 strlcpy(state_str
, "Unk", state_str_len
);
2417 static const char *pim_reg_state2brief_str(enum pim_reg_state reg_state
,
2418 char *state_str
, size_t state_str_len
)
2420 switch (reg_state
) {
2421 case PIM_REG_NOINFO
:
2422 strlcpy(state_str
, "RegNI", state_str_len
);
2425 strlcpy(state_str
, "RegJ", state_str_len
);
2427 case PIM_REG_JOIN_PENDING
:
2429 strlcpy(state_str
, "RegP", state_str_len
);
2432 strlcpy(state_str
, "Unk", state_str_len
);
2437 static void pim_show_upstream(struct pim_instance
*pim
, struct vty
*vty
,
2438 struct prefix_sg
*sg
, bool uj
)
2440 struct pim_upstream
*up
;
2442 json_object
*json
= NULL
;
2443 json_object
*json_group
= NULL
;
2444 json_object
*json_row
= NULL
;
2446 now
= pim_time_monotonic_sec();
2449 json
= json_object_new_object();
2452 "Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt\n");
2454 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
2455 char src_str
[INET_ADDRSTRLEN
];
2456 char grp_str
[INET_ADDRSTRLEN
];
2458 char join_timer
[10];
2461 char msdp_reg_timer
[10];
2462 char state_str
[PIM_REG_STATE_STR_LEN
];
2464 if (sg
->grp
.s_addr
!= INADDR_ANY
2465 && sg
->grp
.s_addr
!= up
->sg
.grp
.s_addr
)
2467 if (sg
->src
.s_addr
!= INADDR_ANY
2468 && sg
->src
.s_addr
!= up
->sg
.src
.s_addr
)
2471 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2472 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2473 pim_time_uptime(uptime
, sizeof(uptime
),
2474 now
- up
->state_transition
);
2475 pim_time_timer_to_hhmmss(join_timer
, sizeof(join_timer
),
2479 * If the upstream is not dummy and it has a J/P timer for the
2480 * neighbor display that
2482 if (!up
->t_join_timer
&& up
->rpf
.source_nexthop
.interface
) {
2483 struct pim_neighbor
*nbr
;
2485 nbr
= pim_neighbor_find(
2486 up
->rpf
.source_nexthop
.interface
,
2487 up
->rpf
.rpf_addr
.u
.prefix4
);
2489 pim_time_timer_to_hhmmss(join_timer
,
2494 pim_time_timer_to_hhmmss(rs_timer
, sizeof(rs_timer
),
2496 pim_time_timer_to_hhmmss(ka_timer
, sizeof(ka_timer
),
2498 pim_time_timer_to_hhmmss(msdp_reg_timer
, sizeof(msdp_reg_timer
),
2499 up
->t_msdp_reg_timer
);
2501 pim_upstream_state2brief_str(up
->join_state
, state_str
, sizeof(state_str
));
2502 if (up
->reg_state
!= PIM_REG_NOINFO
) {
2503 char tmp_str
[PIM_REG_STATE_STR_LEN
];
2505 sprintf(state_str
+ strlen(state_str
), ",%s",
2506 pim_reg_state2brief_str(up
->reg_state
, tmp_str
,
2511 json_object_object_get_ex(json
, grp_str
, &json_group
);
2514 json_group
= json_object_new_object();
2515 json_object_object_add(json
, grp_str
,
2519 json_row
= json_object_new_object();
2520 json_object_pim_upstream_add(json_row
, up
);
2521 json_object_string_add(
2522 json_row
, "inboundInterface",
2523 up
->rpf
.source_nexthop
.interface
2524 ? up
->rpf
.source_nexthop
.interface
->name
2528 * The RPF address we use is slightly different
2529 * based upon what we are looking up.
2530 * If we have a S, list that unless
2531 * we are the FHR, else we just put
2532 * the RP as the rpfAddress
2534 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
2535 || up
->sg
.src
.s_addr
== INADDR_ANY
) {
2536 char rpf
[PREFIX_STRLEN
];
2537 struct pim_rpf
*rpg
;
2539 rpg
= RP(pim
, up
->sg
.grp
);
2540 pim_inet4_dump("<rpf?>",
2541 rpg
->rpf_addr
.u
.prefix4
, rpf
,
2543 json_object_string_add(json_row
, "rpfAddress",
2546 json_object_string_add(json_row
, "rpfAddress",
2550 json_object_string_add(json_row
, "source", src_str
);
2551 json_object_string_add(json_row
, "group", grp_str
);
2552 json_object_string_add(json_row
, "state", state_str
);
2553 json_object_string_add(
2554 json_row
, "joinState",
2555 pim_upstream_state2str(up
->join_state
));
2556 json_object_string_add(
2557 json_row
, "regState",
2558 pim_reg_state2str(up
->reg_state
, state_str
, sizeof(state_str
)));
2559 json_object_string_add(json_row
, "upTime", uptime
);
2560 json_object_string_add(json_row
, "joinTimer",
2562 json_object_string_add(json_row
, "resetTimer",
2564 json_object_string_add(json_row
, "keepaliveTimer",
2566 json_object_string_add(json_row
, "msdpRegTimer",
2568 json_object_int_add(json_row
, "refCount",
2570 json_object_int_add(json_row
, "sptBit", up
->sptbit
);
2571 json_object_object_add(json_group
, src_str
, json_row
);
2574 "%-16s%-15s %-15s %-11s %-8s %-9s %-9s %-9s %6d\n",
2575 up
->rpf
.source_nexthop
.interface
2576 ? up
->rpf
.source_nexthop
.interface
->name
2578 src_str
, grp_str
, state_str
, uptime
, join_timer
,
2579 rs_timer
, ka_timer
, up
->ref_count
);
2584 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2585 json
, JSON_C_TO_STRING_PRETTY
));
2586 json_object_free(json
);
2590 static void pim_show_channel_helper(struct pim_instance
*pim
,
2592 struct pim_interface
*pim_ifp
,
2593 struct pim_ifchannel
*ch
,
2594 json_object
*json
, bool uj
)
2596 struct pim_upstream
*up
= ch
->upstream
;
2597 json_object
*json_group
= NULL
;
2598 char src_str
[INET_ADDRSTRLEN
];
2599 char grp_str
[INET_ADDRSTRLEN
];
2600 json_object
*json_row
= NULL
;
2602 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2603 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2606 json_object_object_get_ex(json
, grp_str
, &json_group
);
2609 json_group
= json_object_new_object();
2610 json_object_object_add(json
, grp_str
, json_group
);
2613 json_row
= json_object_new_object();
2614 json_object_pim_upstream_add(json_row
, up
);
2615 json_object_string_add(json_row
, "interface",
2616 ch
->interface
->name
);
2617 json_object_string_add(json_row
, "source", src_str
);
2618 json_object_string_add(json_row
, "group", grp_str
);
2620 if (pim_macro_ch_lost_assert(ch
))
2621 json_object_boolean_true_add(json_row
, "lostAssert");
2623 if (pim_macro_chisin_joins(ch
))
2624 json_object_boolean_true_add(json_row
, "joins");
2626 if (pim_macro_chisin_pim_include(ch
))
2627 json_object_boolean_true_add(json_row
, "pimInclude");
2629 if (pim_upstream_evaluate_join_desired(pim
, up
))
2630 json_object_boolean_true_add(json_row
,
2631 "evaluateJoinDesired");
2633 json_object_object_add(json_group
, src_str
, json_row
);
2636 vty_out(vty
, "%-16s %-15s %-15s %-10s %-5s %-10s %-11s %-6s\n",
2637 ch
->interface
->name
, src_str
, grp_str
,
2638 pim_macro_ch_lost_assert(ch
) ? "yes" : "no",
2639 pim_macro_chisin_joins(ch
) ? "yes" : "no",
2640 pim_macro_chisin_pim_include(ch
) ? "yes" : "no",
2641 PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(up
->flags
)
2644 pim_upstream_evaluate_join_desired(pim
, up
) ? "yes"
2649 static void pim_show_channel(struct pim_instance
*pim
, struct vty
*vty
,
2652 struct pim_interface
*pim_ifp
;
2653 struct pim_ifchannel
*ch
;
2654 struct interface
*ifp
;
2656 json_object
*json
= NULL
;
2659 json
= json_object_new_object();
2662 "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD\n");
2664 /* scan per-interface (S,G) state */
2665 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2666 pim_ifp
= ifp
->info
;
2671 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
2672 /* scan all interfaces */
2673 pim_show_channel_helper(pim
, vty
, pim_ifp
, ch
,
2679 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2680 json
, JSON_C_TO_STRING_PRETTY
));
2681 json_object_free(json
);
2685 static void pim_show_join_desired_helper(struct pim_instance
*pim
,
2687 struct pim_upstream
*up
,
2688 json_object
*json
, bool uj
)
2690 json_object
*json_group
= NULL
;
2691 char src_str
[INET_ADDRSTRLEN
];
2692 char grp_str
[INET_ADDRSTRLEN
];
2693 json_object
*json_row
= NULL
;
2695 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2696 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2699 json_object_object_get_ex(json
, grp_str
, &json_group
);
2702 json_group
= json_object_new_object();
2703 json_object_object_add(json
, grp_str
, json_group
);
2706 json_row
= json_object_new_object();
2707 json_object_pim_upstream_add(json_row
, up
);
2708 json_object_string_add(json_row
, "source", src_str
);
2709 json_object_string_add(json_row
, "group", grp_str
);
2711 if (pim_upstream_evaluate_join_desired(pim
, up
))
2712 json_object_boolean_true_add(json_row
,
2713 "evaluateJoinDesired");
2715 json_object_object_add(json_group
, src_str
, json_row
);
2718 vty_out(vty
, "%-15s %-15s %-6s\n",
2720 pim_upstream_evaluate_join_desired(pim
, up
) ? "yes"
2725 static void pim_show_join_desired(struct pim_instance
*pim
, struct vty
*vty
,
2728 struct pim_upstream
*up
;
2730 json_object
*json
= NULL
;
2733 json
= json_object_new_object();
2736 "Source Group EvalJD\n");
2738 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
2739 /* scan all interfaces */
2740 pim_show_join_desired_helper(pim
, vty
, up
,
2745 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2746 json
, JSON_C_TO_STRING_PRETTY
));
2747 json_object_free(json
);
2751 static void pim_show_upstream_rpf(struct pim_instance
*pim
, struct vty
*vty
,
2754 struct pim_upstream
*up
;
2755 json_object
*json
= NULL
;
2756 json_object
*json_group
= NULL
;
2757 json_object
*json_row
= NULL
;
2760 json
= json_object_new_object();
2763 "Source Group RpfIface RibNextHop RpfAddress \n");
2765 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
2766 char src_str
[INET_ADDRSTRLEN
];
2767 char grp_str
[INET_ADDRSTRLEN
];
2768 char rpf_nexthop_str
[PREFIX_STRLEN
];
2769 char rpf_addr_str
[PREFIX_STRLEN
];
2770 struct pim_rpf
*rpf
;
2771 const char *rpf_ifname
;
2775 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2776 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2777 pim_addr_dump("<nexthop?>",
2778 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2779 rpf_nexthop_str
, sizeof(rpf_nexthop_str
));
2780 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2781 sizeof(rpf_addr_str
));
2783 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2786 json_object_object_get_ex(json
, grp_str
, &json_group
);
2789 json_group
= json_object_new_object();
2790 json_object_object_add(json
, grp_str
,
2794 json_row
= json_object_new_object();
2795 json_object_pim_upstream_add(json_row
, up
);
2796 json_object_string_add(json_row
, "source", src_str
);
2797 json_object_string_add(json_row
, "group", grp_str
);
2798 json_object_string_add(json_row
, "rpfInterface",
2800 json_object_string_add(json_row
, "ribNexthop",
2802 json_object_string_add(json_row
, "rpfAddress",
2804 json_object_object_add(json_group
, src_str
, json_row
);
2806 vty_out(vty
, "%-15s %-15s %-16s %-15s %-15s\n", src_str
,
2807 grp_str
, rpf_ifname
, rpf_nexthop_str
,
2813 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2814 json
, JSON_C_TO_STRING_PRETTY
));
2815 json_object_free(json
);
2819 static void show_rpf_refresh_stats(struct vty
*vty
, struct pim_instance
*pim
,
2820 time_t now
, json_object
*json
)
2822 char refresh_uptime
[10];
2824 pim_time_uptime_begin(refresh_uptime
, sizeof(refresh_uptime
), now
,
2825 pim
->rpf_cache_refresh_last
);
2828 json_object_int_add(json
, "rpfCacheRefreshDelayMsecs",
2829 router
->rpf_cache_refresh_delay_msec
);
2830 json_object_int_add(
2831 json
, "rpfCacheRefreshTimer",
2832 pim_time_timer_remain_msec(pim
->rpf_cache_refresher
));
2833 json_object_int_add(json
, "rpfCacheRefreshRequests",
2834 pim
->rpf_cache_refresh_requests
);
2835 json_object_int_add(json
, "rpfCacheRefreshEvents",
2836 pim
->rpf_cache_refresh_events
);
2837 json_object_string_add(json
, "rpfCacheRefreshLast",
2839 json_object_int_add(json
, "nexthopLookups",
2840 pim
->nexthop_lookups
);
2841 json_object_int_add(json
, "nexthopLookupsAvoided",
2842 pim
->nexthop_lookups_avoided
);
2845 "RPF Cache Refresh Delay: %ld msecs\n"
2846 "RPF Cache Refresh Timer: %ld msecs\n"
2847 "RPF Cache Refresh Requests: %lld\n"
2848 "RPF Cache Refresh Events: %lld\n"
2849 "RPF Cache Refresh Last: %s\n"
2850 "Nexthop Lookups: %lld\n"
2851 "Nexthop Lookups Avoided: %lld\n",
2852 router
->rpf_cache_refresh_delay_msec
,
2853 pim_time_timer_remain_msec(pim
->rpf_cache_refresher
),
2854 (long long)pim
->rpf_cache_refresh_requests
,
2855 (long long)pim
->rpf_cache_refresh_events
,
2856 refresh_uptime
, (long long)pim
->nexthop_lookups
,
2857 (long long)pim
->nexthop_lookups_avoided
);
2861 static void show_scan_oil_stats(struct pim_instance
*pim
, struct vty
*vty
,
2864 char uptime_scan_oil
[10];
2865 char uptime_mroute_add
[10];
2866 char uptime_mroute_del
[10];
2868 pim_time_uptime_begin(uptime_scan_oil
, sizeof(uptime_scan_oil
), now
,
2869 pim
->scan_oil_last
);
2870 pim_time_uptime_begin(uptime_mroute_add
, sizeof(uptime_mroute_add
), now
,
2871 pim
->mroute_add_last
);
2872 pim_time_uptime_begin(uptime_mroute_del
, sizeof(uptime_mroute_del
), now
,
2873 pim
->mroute_del_last
);
2876 "Scan OIL - Last: %s Events: %lld\n"
2877 "MFC Add - Last: %s Events: %lld\n"
2878 "MFC Del - Last: %s Events: %lld\n",
2879 uptime_scan_oil
, (long long)pim
->scan_oil_events
,
2880 uptime_mroute_add
, (long long)pim
->mroute_add_events
,
2881 uptime_mroute_del
, (long long)pim
->mroute_del_events
);
2884 static void pim_show_rpf(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
2886 struct pim_upstream
*up
;
2887 time_t now
= pim_time_monotonic_sec();
2888 json_object
*json
= NULL
;
2889 json_object
*json_group
= NULL
;
2890 json_object
*json_row
= NULL
;
2893 json
= json_object_new_object();
2894 show_rpf_refresh_stats(vty
, pim
, now
, json
);
2896 show_rpf_refresh_stats(vty
, pim
, now
, json
);
2899 "Source Group RpfIface RpfAddress RibNextHop Metric Pref\n");
2902 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
2903 char src_str
[INET_ADDRSTRLEN
];
2904 char grp_str
[INET_ADDRSTRLEN
];
2905 char rpf_addr_str
[PREFIX_STRLEN
];
2906 char rib_nexthop_str
[PREFIX_STRLEN
];
2907 const char *rpf_ifname
;
2908 struct pim_rpf
*rpf
= &up
->rpf
;
2910 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2911 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2912 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2913 sizeof(rpf_addr_str
));
2914 pim_addr_dump("<nexthop?>",
2915 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2916 rib_nexthop_str
, sizeof(rib_nexthop_str
));
2918 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2921 json_object_object_get_ex(json
, grp_str
, &json_group
);
2924 json_group
= json_object_new_object();
2925 json_object_object_add(json
, grp_str
,
2929 json_row
= json_object_new_object();
2930 json_object_string_add(json_row
, "source", src_str
);
2931 json_object_string_add(json_row
, "group", grp_str
);
2932 json_object_string_add(json_row
, "rpfInterface",
2934 json_object_string_add(json_row
, "rpfAddress",
2936 json_object_string_add(json_row
, "ribNexthop",
2938 json_object_int_add(
2939 json_row
, "routeMetric",
2940 rpf
->source_nexthop
.mrib_route_metric
);
2941 json_object_int_add(
2942 json_row
, "routePreference",
2943 rpf
->source_nexthop
.mrib_metric_preference
);
2944 json_object_object_add(json_group
, src_str
, json_row
);
2947 vty_out(vty
, "%-15s %-15s %-16s %-15s %-15s %6d %4d\n",
2948 src_str
, grp_str
, rpf_ifname
, rpf_addr_str
,
2950 rpf
->source_nexthop
.mrib_route_metric
,
2951 rpf
->source_nexthop
.mrib_metric_preference
);
2956 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2957 json
, JSON_C_TO_STRING_PRETTY
));
2958 json_object_free(json
);
2962 struct pnc_cache_walk_data
{
2964 struct pim_instance
*pim
;
2967 static int pim_print_pnc_cache_walkcb(struct hash_bucket
*bucket
, void *arg
)
2969 struct pim_nexthop_cache
*pnc
= bucket
->data
;
2970 struct pnc_cache_walk_data
*cwd
= arg
;
2971 struct vty
*vty
= cwd
->vty
;
2972 struct pim_instance
*pim
= cwd
->pim
;
2973 struct nexthop
*nh_node
= NULL
;
2974 ifindex_t first_ifindex
;
2975 struct interface
*ifp
= NULL
;
2977 for (nh_node
= pnc
->nexthop
; nh_node
; nh_node
= nh_node
->next
) {
2978 first_ifindex
= nh_node
->ifindex
;
2979 ifp
= if_lookup_by_index(first_ifindex
, pim
->vrf_id
);
2981 vty_out(vty
, "%-15s ", inet_ntoa(pnc
->rpf
.rpf_addr
.u
.prefix4
));
2982 vty_out(vty
, "%-16s ", ifp
? ifp
->name
: "NULL");
2983 vty_out(vty
, "%s ", inet_ntoa(nh_node
->gate
.ipv4
));
2989 static void pim_show_nexthop(struct pim_instance
*pim
, struct vty
*vty
)
2991 struct pnc_cache_walk_data cwd
;
2995 vty_out(vty
, "Number of registered addresses: %lu\n",
2996 pim
->rpf_hash
->count
);
2997 vty_out(vty
, "Address Interface Nexthop\n");
2998 vty_out(vty
, "---------------------------------------------\n");
3000 hash_walk(pim
->rpf_hash
, pim_print_pnc_cache_walkcb
, &cwd
);
3003 /* Display the bsm database details */
3004 static void pim_show_bsm_db(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
3006 struct listnode
*bsmnode
;
3009 struct bsm_info
*bsm
;
3010 json_object
*json
= NULL
;
3011 json_object
*json_group
= NULL
;
3012 json_object
*json_row
= NULL
;
3014 count
= pim
->global_scope
.bsm_list
->count
;
3017 json
= json_object_new_object();
3018 json_object_int_add(json
, "Number of the fragments", count
);
3020 vty_out(vty
, "Scope Zone: Global\n");
3021 vty_out(vty
, "Number of the fragments: %d\n", count
);
3025 for (ALL_LIST_ELEMENTS_RO(pim
->global_scope
.bsm_list
, bsmnode
, bsm
)) {
3026 char grp_str
[PREFIX_STRLEN
];
3027 char rp_str
[INET_ADDRSTRLEN
];
3028 char bsr_str
[INET_ADDRSTRLEN
];
3029 struct bsmmsg_grpinfo
*group
;
3030 struct bsmmsg_rpinfo
*rpaddr
;
3032 struct bsm_hdr
*hdr
;
3033 uint32_t offset
= 0;
3036 uint32_t frag_rp_cnt
= 0;
3041 /* skip pim header */
3042 buf
+= PIM_MSG_HEADER_LEN
;
3043 len
-= PIM_MSG_HEADER_LEN
;
3045 hdr
= (struct bsm_hdr
*)buf
;
3047 /* BSM starts with bsr header */
3048 buf
+= sizeof(struct bsm_hdr
);
3049 len
-= sizeof(struct bsm_hdr
);
3051 pim_inet4_dump("<BSR Address?>", hdr
->bsr_addr
.addr
, bsr_str
,
3056 json_object_string_add(json
, "BSR address", bsr_str
);
3057 json_object_int_add(json
, "BSR priority",
3059 json_object_int_add(json
, "Hashmask Length",
3061 json_object_int_add(json
, "Fragment Tag",
3062 ntohs(hdr
->frag_tag
));
3064 vty_out(vty
, "BSM Fragment : %d\n", fragment
);
3065 vty_out(vty
, "------------------\n");
3066 vty_out(vty
, "%-15s %-15s %-15s %-15s\n", "BSR-Address",
3067 "BSR-Priority", "Hashmask-len", "Fragment-Tag");
3068 vty_out(vty
, "%-15s %-15d %-15d %-15d\n", bsr_str
,
3069 hdr
->bsr_prio
, hdr
->hm_len
,
3070 ntohs(hdr
->frag_tag
));
3075 while (offset
< len
) {
3076 group
= (struct bsmmsg_grpinfo
*)buf
;
3078 if (group
->group
.family
== PIM_MSG_ADDRESS_FAMILY_IPV4
)
3079 grp
.family
= AF_INET
;
3081 grp
.prefixlen
= group
->group
.mask
;
3082 grp
.u
.prefix4
.s_addr
= group
->group
.addr
.s_addr
;
3084 prefix2str(&grp
, grp_str
, sizeof(grp_str
));
3086 buf
+= sizeof(struct bsmmsg_grpinfo
);
3087 offset
+= sizeof(struct bsmmsg_grpinfo
);
3090 json_object_object_get_ex(json
, grp_str
,
3093 json_group
= json_object_new_object();
3094 json_object_int_add(json_group
,
3097 json_object_int_add(
3098 json_group
, "Fragment Rp count",
3099 group
->frag_rp_count
);
3100 json_object_object_add(json
, grp_str
,
3104 vty_out(vty
, "Group : %s\n", grp_str
);
3105 vty_out(vty
, "-------------------\n");
3106 vty_out(vty
, "Rp Count:%d\n", group
->rp_count
);
3107 vty_out(vty
, "Fragment Rp Count : %d\n",
3108 group
->frag_rp_count
);
3111 frag_rp_cnt
= group
->frag_rp_count
;
3118 "RpAddress HoldTime Priority\n");
3120 while (frag_rp_cnt
--) {
3121 rpaddr
= (struct bsmmsg_rpinfo
*)buf
;
3123 buf
+= sizeof(struct bsmmsg_rpinfo
);
3124 offset
+= sizeof(struct bsmmsg_rpinfo
);
3126 pim_inet4_dump("<Rp addr?>",
3127 rpaddr
->rpaddr
.addr
, rp_str
,
3131 json_row
= json_object_new_object();
3132 json_object_string_add(
3133 json_row
, "Rp Address", rp_str
);
3134 json_object_int_add(
3135 json_row
, "Rp HoldTime",
3136 ntohs(rpaddr
->rp_holdtime
));
3137 json_object_int_add(json_row
,
3140 json_object_object_add(
3141 json_group
, rp_str
, json_row
);
3143 vty_out(vty
, "%-15s %-12d %d\n", rp_str
,
3144 ntohs(rpaddr
->rp_holdtime
),
3155 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3156 json
, JSON_C_TO_STRING_PRETTY
));
3157 json_object_free(json
);
3161 /*Display the group-rp mappings */
3162 static void pim_show_group_rp_mappings_info(struct pim_instance
*pim
,
3163 struct vty
*vty
, bool uj
)
3165 struct bsgrp_node
*bsgrp
;
3166 struct listnode
*rpnode
;
3167 struct bsm_rpinfo
*bsm_rp
;
3168 struct route_node
*rn
;
3169 char bsr_str
[INET_ADDRSTRLEN
];
3170 json_object
*json
= NULL
;
3171 json_object
*json_group
= NULL
;
3172 json_object
*json_row
= NULL
;
3174 if (pim
->global_scope
.current_bsr
.s_addr
== INADDR_ANY
)
3175 strlcpy(bsr_str
, "0.0.0.0", sizeof(bsr_str
));
3178 pim_inet4_dump("<bsr?>", pim
->global_scope
.current_bsr
, bsr_str
,
3182 json
= json_object_new_object();
3183 json_object_string_add(json
, "BSR Address", bsr_str
);
3185 vty_out(vty
, "BSR Address %s\n", bsr_str
);
3188 for (rn
= route_top(pim
->global_scope
.bsrp_table
); rn
;
3189 rn
= route_next(rn
)) {
3190 bsgrp
= (struct bsgrp_node
*)rn
->info
;
3195 char grp_str
[PREFIX_STRLEN
];
3197 prefix2str(&bsgrp
->group
, grp_str
, sizeof(grp_str
));
3200 json_object_object_get_ex(json
, grp_str
, &json_group
);
3202 json_group
= json_object_new_object();
3203 json_object_object_add(json
, grp_str
,
3207 vty_out(vty
, "Group Address %s\n", grp_str
);
3208 vty_out(vty
, "--------------------------\n");
3209 vty_out(vty
, "%-15s %-15s %-15s %-15s\n", "Rp Address",
3210 "priority", "Holdtime", "Hash");
3212 vty_out(vty
, "(ACTIVE)\n");
3215 if (bsgrp
->bsrp_list
) {
3216 for (ALL_LIST_ELEMENTS_RO(bsgrp
->bsrp_list
, rpnode
,
3218 char rp_str
[INET_ADDRSTRLEN
];
3220 pim_inet4_dump("<Rp Address?>",
3221 bsm_rp
->rp_address
, rp_str
,
3225 json_row
= json_object_new_object();
3226 json_object_string_add(
3227 json_row
, "Rp Address", rp_str
);
3228 json_object_int_add(
3229 json_row
, "Rp HoldTime",
3230 bsm_rp
->rp_holdtime
);
3231 json_object_int_add(json_row
,
3234 json_object_int_add(json_row
,
3237 json_object_object_add(
3238 json_group
, rp_str
, json_row
);
3242 "%-15s %-15u %-15u %-15u\n",
3243 rp_str
, bsm_rp
->rp_prio
,
3244 bsm_rp
->rp_holdtime
,
3248 if (!bsgrp
->bsrp_list
->count
&& !uj
)
3249 vty_out(vty
, "Active List is empty.\n");
3253 json_object_int_add(json_group
, "Pending RP count",
3254 bsgrp
->pend_rp_cnt
);
3256 vty_out(vty
, "(PENDING)\n");
3257 vty_out(vty
, "Pending RP count :%d\n",
3258 bsgrp
->pend_rp_cnt
);
3259 if (bsgrp
->pend_rp_cnt
)
3260 vty_out(vty
, "%-15s %-15s %-15s %-15s\n",
3261 "Rp Address", "priority", "Holdtime",
3265 if (bsgrp
->partial_bsrp_list
) {
3266 for (ALL_LIST_ELEMENTS_RO(bsgrp
->partial_bsrp_list
,
3268 char rp_str
[INET_ADDRSTRLEN
];
3270 pim_inet4_dump("<Rp Addr?>", bsm_rp
->rp_address
,
3271 rp_str
, sizeof(rp_str
));
3274 json_row
= json_object_new_object();
3275 json_object_string_add(
3276 json_row
, "Rp Address", rp_str
);
3277 json_object_int_add(
3278 json_row
, "Rp HoldTime",
3279 bsm_rp
->rp_holdtime
);
3280 json_object_int_add(json_row
,
3283 json_object_int_add(json_row
,
3286 json_object_object_add(
3287 json_group
, rp_str
, json_row
);
3290 "%-15s %-15u %-15u %-15u\n",
3291 rp_str
, bsm_rp
->rp_prio
,
3292 bsm_rp
->rp_holdtime
,
3296 if (!bsgrp
->partial_bsrp_list
->count
&& !uj
)
3297 vty_out(vty
, "Partial List is empty\n");
3305 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3306 json
, JSON_C_TO_STRING_PRETTY
));
3307 json_object_free(json
);
3311 /* pim statistics - just adding only bsm related now.
3312 * We can continue to add all pim related stats here.
3314 static void pim_show_statistics(struct pim_instance
*pim
, struct vty
*vty
,
3315 const char *ifname
, bool uj
)
3317 json_object
*json
= NULL
;
3318 struct interface
*ifp
;
3321 json
= json_object_new_object();
3322 json_object_int_add(json
, "Number of Received BSMs",
3324 json_object_int_add(json
, "Number of Forwared BSMs",
3326 json_object_int_add(json
, "Number of Dropped BSMs",
3329 vty_out(vty
, "BSM Statistics :\n");
3330 vty_out(vty
, "----------------\n");
3331 vty_out(vty
, "Number of Received BSMs : %" PRIu64
"\n",
3333 vty_out(vty
, "Number of Forwared BSMs : %" PRIu64
"\n",
3335 vty_out(vty
, "Number of Dropped BSMs : %" PRIu64
"\n",
3341 /* scan interfaces */
3342 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3343 struct pim_interface
*pim_ifp
= ifp
->info
;
3345 if (ifname
&& strcmp(ifname
, ifp
->name
))
3352 vty_out(vty
, "Interface : %s\n", ifp
->name
);
3353 vty_out(vty
, "-------------------\n");
3355 "Number of BSMs dropped due to config miss : %u\n",
3356 pim_ifp
->pim_ifstat_bsm_cfg_miss
);
3357 vty_out(vty
, "Number of unicast BSMs dropped : %u\n",
3358 pim_ifp
->pim_ifstat_ucast_bsm_cfg_miss
);
3360 "Number of BSMs dropped due to invalid scope zone : %u\n",
3361 pim_ifp
->pim_ifstat_bsm_invalid_sz
);
3364 json_object
*json_row
= NULL
;
3366 json_row
= json_object_new_object();
3368 json_object_string_add(json_row
, "If Name", ifp
->name
);
3369 json_object_int_add(
3371 "Number of BSMs dropped due to config miss",
3372 pim_ifp
->pim_ifstat_bsm_cfg_miss
);
3373 json_object_int_add(
3374 json_row
, "Number of unicast BSMs dropped",
3375 pim_ifp
->pim_ifstat_ucast_bsm_cfg_miss
);
3376 json_object_int_add(json_row
,
3377 "Number of BSMs dropped due to invalid scope zone",
3378 pim_ifp
->pim_ifstat_bsm_invalid_sz
);
3379 json_object_object_add(json
, ifp
->name
, json_row
);
3385 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3386 json
, JSON_C_TO_STRING_PRETTY
));
3387 json_object_free(json
);
3391 static void clear_pim_statistics(struct pim_instance
*pim
)
3393 struct interface
*ifp
;
3397 pim
->bsm_dropped
= 0;
3399 /* scan interfaces */
3400 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3401 struct pim_interface
*pim_ifp
= ifp
->info
;
3406 pim_ifp
->pim_ifstat_bsm_cfg_miss
= 0;
3407 pim_ifp
->pim_ifstat_ucast_bsm_cfg_miss
= 0;
3408 pim_ifp
->pim_ifstat_bsm_invalid_sz
= 0;
3412 static void igmp_show_groups(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
3414 struct interface
*ifp
;
3416 json_object
*json
= NULL
;
3417 json_object
*json_iface
= NULL
;
3418 json_object
*json_row
= NULL
;
3420 now
= pim_time_monotonic_sec();
3423 json
= json_object_new_object();
3426 "Interface Address Group Mode Timer Srcs V Uptime \n");
3428 /* scan interfaces */
3429 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3430 struct pim_interface
*pim_ifp
= ifp
->info
;
3431 struct listnode
*sock_node
;
3432 struct igmp_sock
*igmp
;
3437 /* scan igmp sockets */
3438 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3440 char ifaddr_str
[INET_ADDRSTRLEN
];
3441 struct listnode
*grpnode
;
3442 struct igmp_group
*grp
;
3444 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3445 sizeof(ifaddr_str
));
3447 /* scan igmp groups */
3448 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3450 char group_str
[INET_ADDRSTRLEN
];
3454 pim_inet4_dump("<group?>", grp
->group_addr
,
3455 group_str
, sizeof(group_str
));
3456 pim_time_timer_to_hhmmss(hhmmss
, sizeof(hhmmss
),
3457 grp
->t_group_timer
);
3458 pim_time_uptime(uptime
, sizeof(uptime
),
3459 now
- grp
->group_creation
);
3462 json_object_object_get_ex(
3463 json
, ifp
->name
, &json_iface
);
3467 json_object_new_object();
3468 json_object_pim_ifp_add(
3470 json_object_object_add(
3475 json_row
= json_object_new_object();
3476 json_object_string_add(
3477 json_row
, "source", ifaddr_str
);
3478 json_object_string_add(
3479 json_row
, "group", group_str
);
3481 if (grp
->igmp_version
== 3)
3482 json_object_string_add(
3484 grp
->group_filtermode_isexcl
3488 json_object_string_add(json_row
,
3490 json_object_int_add(
3491 json_row
, "sourcesCount",
3492 grp
->group_source_list
3494 grp
->group_source_list
)
3496 json_object_int_add(json_row
, "version",
3498 json_object_string_add(
3499 json_row
, "uptime", uptime
);
3500 json_object_object_add(json_iface
,
3506 "%-16s %-15s %-15s %4s %8s %4d %d %8s\n",
3507 ifp
->name
, ifaddr_str
,
3509 grp
->igmp_version
== 3
3510 ? (grp
->group_filtermode_isexcl
3515 grp
->group_source_list
3517 grp
->group_source_list
)
3519 grp
->igmp_version
, uptime
);
3521 } /* scan igmp groups */
3522 } /* scan igmp sockets */
3523 } /* scan interfaces */
3526 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3527 json
, JSON_C_TO_STRING_PRETTY
));
3528 json_object_free(json
);
3532 static void igmp_show_group_retransmission(struct pim_instance
*pim
,
3535 struct interface
*ifp
;
3538 "Interface Address Group RetTimer Counter RetSrcs\n");
3540 /* scan interfaces */
3541 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3542 struct pim_interface
*pim_ifp
= ifp
->info
;
3543 struct listnode
*sock_node
;
3544 struct igmp_sock
*igmp
;
3549 /* scan igmp sockets */
3550 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3552 char ifaddr_str
[INET_ADDRSTRLEN
];
3553 struct listnode
*grpnode
;
3554 struct igmp_group
*grp
;
3556 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3557 sizeof(ifaddr_str
));
3559 /* scan igmp groups */
3560 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3562 char group_str
[INET_ADDRSTRLEN
];
3563 char grp_retr_mmss
[10];
3564 struct listnode
*src_node
;
3565 struct igmp_source
*src
;
3566 int grp_retr_sources
= 0;
3568 pim_inet4_dump("<group?>", grp
->group_addr
,
3569 group_str
, sizeof(group_str
));
3570 pim_time_timer_to_mmss(
3571 grp_retr_mmss
, sizeof(grp_retr_mmss
),
3572 grp
->t_group_query_retransmit_timer
);
3575 /* count group sources with retransmission state
3577 for (ALL_LIST_ELEMENTS_RO(
3578 grp
->group_source_list
, src_node
,
3580 if (src
->source_query_retransmit_count
3586 vty_out(vty
, "%-16s %-15s %-15s %-8s %7d %7d\n",
3587 ifp
->name
, ifaddr_str
, group_str
,
3589 grp
->group_specific_query_retransmit_count
,
3592 } /* scan igmp groups */
3593 } /* scan igmp sockets */
3594 } /* scan interfaces */
3597 static void igmp_show_sources(struct pim_instance
*pim
, struct vty
*vty
)
3599 struct interface
*ifp
;
3602 now
= pim_time_monotonic_sec();
3605 "Interface Address Group Source Timer Fwd Uptime \n");
3607 /* scan interfaces */
3608 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3609 struct pim_interface
*pim_ifp
= ifp
->info
;
3610 struct listnode
*sock_node
;
3611 struct igmp_sock
*igmp
;
3616 /* scan igmp sockets */
3617 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3619 char ifaddr_str
[INET_ADDRSTRLEN
];
3620 struct listnode
*grpnode
;
3621 struct igmp_group
*grp
;
3623 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3624 sizeof(ifaddr_str
));
3626 /* scan igmp groups */
3627 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3629 char group_str
[INET_ADDRSTRLEN
];
3630 struct listnode
*srcnode
;
3631 struct igmp_source
*src
;
3633 pim_inet4_dump("<group?>", grp
->group_addr
,
3634 group_str
, sizeof(group_str
));
3636 /* scan group sources */
3637 for (ALL_LIST_ELEMENTS_RO(
3638 grp
->group_source_list
, srcnode
,
3640 char source_str
[INET_ADDRSTRLEN
];
3645 "<source?>", src
->source_addr
,
3646 source_str
, sizeof(source_str
));
3648 pim_time_timer_to_mmss(
3650 src
->t_source_timer
);
3653 uptime
, sizeof(uptime
),
3654 now
- src
->source_creation
);
3657 "%-16s %-15s %-15s %-15s %5s %3s %8s\n",
3658 ifp
->name
, ifaddr_str
,
3659 group_str
, source_str
, mmss
,
3660 IGMP_SOURCE_TEST_FORWARDING(
3666 } /* scan group sources */
3667 } /* scan igmp groups */
3668 } /* scan igmp sockets */
3669 } /* scan interfaces */
3672 static void igmp_show_source_retransmission(struct pim_instance
*pim
,
3675 struct interface
*ifp
;
3678 "Interface Address Group Source Counter\n");
3680 /* scan interfaces */
3681 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3682 struct pim_interface
*pim_ifp
= ifp
->info
;
3683 struct listnode
*sock_node
;
3684 struct igmp_sock
*igmp
;
3689 /* scan igmp sockets */
3690 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3692 char ifaddr_str
[INET_ADDRSTRLEN
];
3693 struct listnode
*grpnode
;
3694 struct igmp_group
*grp
;
3696 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3697 sizeof(ifaddr_str
));
3699 /* scan igmp groups */
3700 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3702 char group_str
[INET_ADDRSTRLEN
];
3703 struct listnode
*srcnode
;
3704 struct igmp_source
*src
;
3706 pim_inet4_dump("<group?>", grp
->group_addr
,
3707 group_str
, sizeof(group_str
));
3709 /* scan group sources */
3710 for (ALL_LIST_ELEMENTS_RO(
3711 grp
->group_source_list
, srcnode
,
3713 char source_str
[INET_ADDRSTRLEN
];
3716 "<source?>", src
->source_addr
,
3717 source_str
, sizeof(source_str
));
3720 "%-16s %-15s %-15s %-15s %7d\n",
3721 ifp
->name
, ifaddr_str
,
3722 group_str
, source_str
,
3723 src
->source_query_retransmit_count
);
3725 } /* scan group sources */
3726 } /* scan igmp groups */
3727 } /* scan igmp sockets */
3728 } /* scan interfaces */
3731 static void pim_show_bsr(struct pim_instance
*pim
,
3736 char last_bsm_seen
[10];
3739 char bsr_str
[PREFIX_STRLEN
];
3740 json_object
*json
= NULL
;
3742 if (pim
->global_scope
.current_bsr
.s_addr
== INADDR_ANY
) {
3743 strlcpy(bsr_str
, "0.0.0.0", sizeof(bsr_str
));
3744 pim_time_uptime(uptime
, sizeof(uptime
),
3745 pim
->global_scope
.current_bsr_first_ts
);
3746 pim_time_uptime(last_bsm_seen
, sizeof(last_bsm_seen
),
3747 pim
->global_scope
.current_bsr_last_ts
);
3751 pim_inet4_dump("<bsr?>", pim
->global_scope
.current_bsr
,
3752 bsr_str
, sizeof(bsr_str
));
3753 now
= pim_time_monotonic_sec();
3754 pim_time_uptime(uptime
, sizeof(uptime
),
3755 (now
- pim
->global_scope
.current_bsr_first_ts
));
3756 pim_time_uptime(last_bsm_seen
, sizeof(last_bsm_seen
),
3757 now
- pim
->global_scope
.current_bsr_last_ts
);
3760 switch (pim
->global_scope
.state
) {
3762 strlcpy(bsr_state
, "NO_INFO", sizeof(bsr_state
));
3765 strlcpy(bsr_state
, "ACCEPT_ANY", sizeof(bsr_state
));
3767 case ACCEPT_PREFERRED
:
3768 strlcpy(bsr_state
, "ACCEPT_PREFERRED", sizeof(bsr_state
));
3771 strlcpy(bsr_state
, "", sizeof(bsr_state
));
3775 json
= json_object_new_object();
3776 json_object_string_add(json
, "bsr", bsr_str
);
3777 json_object_int_add(json
, "priority",
3778 pim
->global_scope
.current_bsr_prio
);
3779 json_object_int_add(json
, "fragment_tag",
3780 pim
->global_scope
.bsm_frag_tag
);
3781 json_object_string_add(json
, "state", bsr_state
);
3782 json_object_string_add(json
, "upTime", uptime
);
3783 json_object_string_add(json
, "last_bsm_seen", last_bsm_seen
);
3787 vty_out(vty
, "PIMv2 Bootstrap information\n");
3788 vty_out(vty
, "Current preferred BSR address: %s\n", bsr_str
);
3790 "Priority Fragment-Tag State UpTime\n");
3791 vty_out(vty
, " %-12d %-12d %-13s %7s\n",
3792 pim
->global_scope
.current_bsr_prio
,
3793 pim
->global_scope
.bsm_frag_tag
,
3796 vty_out(vty
, "Last BSM seen: %s\n", last_bsm_seen
);
3800 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3801 json
, JSON_C_TO_STRING_PRETTY
));
3802 json_object_free(json
);
3806 static void clear_igmp_interfaces(struct pim_instance
*pim
)
3808 struct interface
*ifp
;
3810 FOR_ALL_INTERFACES (pim
->vrf
, ifp
)
3811 pim_if_addr_del_all_igmp(ifp
);
3813 FOR_ALL_INTERFACES (pim
->vrf
, ifp
)
3814 pim_if_addr_add_all(ifp
);
3817 static void clear_pim_interfaces(struct pim_instance
*pim
)
3819 struct interface
*ifp
;
3821 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3823 pim_neighbor_delete_all(ifp
, "interface cleared");
3828 static void clear_interfaces(struct pim_instance
*pim
)
3830 clear_igmp_interfaces(pim
);
3831 clear_pim_interfaces(pim
);
3834 #define PIM_GET_PIM_INTERFACE(pim_ifp, ifp) \
3835 pim_ifp = ifp->info; \
3838 "%% Enable PIM and/or IGMP on this interface first\n"); \
3839 return CMD_WARNING_CONFIG_FAILED; \
3842 DEFUN (clear_ip_interfaces
,
3843 clear_ip_interfaces_cmd
,
3844 "clear ip interfaces [vrf NAME]",
3847 "Reset interfaces\n"
3851 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3856 clear_interfaces(vrf
->info
);
3861 DEFUN (clear_ip_igmp_interfaces
,
3862 clear_ip_igmp_interfaces_cmd
,
3863 "clear ip igmp [vrf NAME] interfaces",
3868 "Reset IGMP interfaces\n")
3871 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3876 clear_igmp_interfaces(vrf
->info
);
3881 DEFUN (clear_ip_pim_statistics
,
3882 clear_ip_pim_statistics_cmd
,
3883 "clear ip pim statistics [vrf NAME]",
3888 "Reset PIM statistics\n")
3891 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3896 clear_pim_statistics(vrf
->info
);
3900 static void clear_mroute(struct pim_instance
*pim
)
3902 struct pim_upstream
*up
;
3903 struct interface
*ifp
;
3905 /* scan interfaces */
3906 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3907 struct pim_interface
*pim_ifp
= ifp
->info
;
3908 struct listnode
*sock_node
;
3909 struct igmp_sock
*igmp
;
3910 struct pim_ifchannel
*ch
;
3915 /* deleting all ifchannels */
3916 while (!RB_EMPTY(pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
)) {
3917 ch
= RB_ROOT(pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
);
3919 pim_ifchannel_delete(ch
);
3922 /* clean up all igmp groups */
3923 /* scan igmp sockets */
3924 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3927 struct igmp_group
*grp
;
3929 if (igmp
->igmp_group_list
) {
3930 while (igmp
->igmp_group_list
->count
) {
3931 grp
= listnode_head(
3932 igmp
->igmp_group_list
);
3933 igmp_group_delete(grp
);
3940 /* clean up all upstreams*/
3941 while ((up
= rb_pim_upstream_first(&pim
->upstream_head
))) {
3942 pim_upstream_del(pim
, up
, __func__
);
3946 DEFUN (clear_ip_mroute
,
3947 clear_ip_mroute_cmd
,
3948 "clear ip mroute [vrf NAME]",
3951 "Reset multicast routes\n"
3955 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3960 clear_mroute(vrf
->info
);
3965 DEFUN (clear_ip_pim_interfaces
,
3966 clear_ip_pim_interfaces_cmd
,
3967 "clear ip pim [vrf NAME] interfaces",
3972 "Reset PIM interfaces\n")
3975 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3980 clear_pim_interfaces(vrf
->info
);
3985 DEFUN (clear_ip_pim_interface_traffic
,
3986 clear_ip_pim_interface_traffic_cmd
,
3987 "clear ip pim [vrf NAME] interface traffic",
3990 "PIM clear commands\n"
3992 "Reset PIM interfaces\n"
3993 "Reset Protocol Packet counters\n")
3996 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3997 struct interface
*ifp
= NULL
;
3998 struct pim_interface
*pim_ifp
= NULL
;
4003 FOR_ALL_INTERFACES (vrf
, ifp
) {
4004 pim_ifp
= ifp
->info
;
4009 pim_ifp
->pim_ifstat_hello_recv
= 0;
4010 pim_ifp
->pim_ifstat_hello_sent
= 0;
4011 pim_ifp
->pim_ifstat_join_recv
= 0;
4012 pim_ifp
->pim_ifstat_join_send
= 0;
4013 pim_ifp
->pim_ifstat_prune_recv
= 0;
4014 pim_ifp
->pim_ifstat_prune_send
= 0;
4015 pim_ifp
->pim_ifstat_reg_recv
= 0;
4016 pim_ifp
->pim_ifstat_reg_send
= 0;
4017 pim_ifp
->pim_ifstat_reg_stop_recv
= 0;
4018 pim_ifp
->pim_ifstat_reg_stop_send
= 0;
4019 pim_ifp
->pim_ifstat_assert_recv
= 0;
4020 pim_ifp
->pim_ifstat_assert_send
= 0;
4021 pim_ifp
->pim_ifstat_bsm_rx
= 0;
4022 pim_ifp
->pim_ifstat_bsm_tx
= 0;
4028 DEFUN (clear_ip_pim_oil
,
4029 clear_ip_pim_oil_cmd
,
4030 "clear ip pim [vrf NAME] oil",
4035 "Rescan PIM OIL (output interface list)\n")
4038 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4043 pim_scan_oil(vrf
->info
);
4048 DEFUN (show_ip_igmp_interface
,
4049 show_ip_igmp_interface_cmd
,
4050 "show ip igmp [vrf NAME] interface [detail|WORD] [json]",
4055 "IGMP interface information\n"
4061 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4062 bool uj
= use_json(argc
, argv
);
4067 if (argv_find(argv
, argc
, "detail", &idx
)
4068 || argv_find(argv
, argc
, "WORD", &idx
))
4069 igmp_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
4071 igmp_show_interfaces(vrf
->info
, vty
, uj
);
4076 DEFUN (show_ip_igmp_interface_vrf_all
,
4077 show_ip_igmp_interface_vrf_all_cmd
,
4078 "show ip igmp vrf all interface [detail|WORD] [json]",
4083 "IGMP interface information\n"
4089 bool uj
= use_json(argc
, argv
);
4095 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4099 vty_out(vty
, " \"%s\": ", vrf
->name
);
4102 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4103 if (argv_find(argv
, argc
, "detail", &idx
)
4104 || argv_find(argv
, argc
, "WORD", &idx
))
4105 igmp_show_interfaces_single(vrf
->info
, vty
,
4106 argv
[idx
]->arg
, uj
);
4108 igmp_show_interfaces(vrf
->info
, vty
, uj
);
4111 vty_out(vty
, "}\n");
4116 DEFUN (show_ip_igmp_join
,
4117 show_ip_igmp_join_cmd
,
4118 "show ip igmp [vrf NAME] join",
4123 "IGMP static join information\n")
4126 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4131 igmp_show_interface_join(vrf
->info
, vty
);
4136 DEFUN (show_ip_igmp_join_vrf_all
,
4137 show_ip_igmp_join_vrf_all_cmd
,
4138 "show ip igmp vrf all join",
4143 "IGMP static join information\n")
4145 bool uj
= use_json(argc
, argv
);
4151 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4155 vty_out(vty
, " \"%s\": ", vrf
->name
);
4158 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4159 igmp_show_interface_join(vrf
->info
, vty
);
4162 vty_out(vty
, "}\n");
4167 DEFUN (show_ip_igmp_groups
,
4168 show_ip_igmp_groups_cmd
,
4169 "show ip igmp [vrf NAME] groups [json]",
4178 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4179 bool uj
= use_json(argc
, argv
);
4184 igmp_show_groups(vrf
->info
, vty
, uj
);
4189 DEFUN (show_ip_igmp_groups_vrf_all
,
4190 show_ip_igmp_groups_vrf_all_cmd
,
4191 "show ip igmp vrf all groups [json]",
4199 bool uj
= use_json(argc
, argv
);
4205 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4209 vty_out(vty
, " \"%s\": ", vrf
->name
);
4212 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4213 igmp_show_groups(vrf
->info
, vty
, uj
);
4216 vty_out(vty
, "}\n");
4221 DEFUN (show_ip_igmp_groups_retransmissions
,
4222 show_ip_igmp_groups_retransmissions_cmd
,
4223 "show ip igmp [vrf NAME] groups retransmissions",
4229 "IGMP group retransmissions\n")
4232 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4237 igmp_show_group_retransmission(vrf
->info
, vty
);
4242 DEFUN (show_ip_igmp_sources
,
4243 show_ip_igmp_sources_cmd
,
4244 "show ip igmp [vrf NAME] sources",
4252 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4257 igmp_show_sources(vrf
->info
, vty
);
4262 DEFUN (show_ip_igmp_sources_retransmissions
,
4263 show_ip_igmp_sources_retransmissions_cmd
,
4264 "show ip igmp [vrf NAME] sources retransmissions",
4270 "IGMP source retransmissions\n")
4273 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4278 igmp_show_source_retransmission(vrf
->info
, vty
);
4283 DEFUN (show_ip_igmp_statistics
,
4284 show_ip_igmp_statistics_cmd
,
4285 "show ip igmp [vrf NAME] statistics [interface WORD] [json]",
4296 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4297 bool uj
= use_json(argc
, argv
);
4302 if (argv_find(argv
, argc
, "WORD", &idx
))
4303 igmp_show_statistics(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
4305 igmp_show_statistics(vrf
->info
, vty
, NULL
, uj
);
4310 DEFUN (show_ip_pim_mlag_summary
,
4311 show_ip_pim_mlag_summary_cmd
,
4312 "show ip pim mlag summary [json]",
4317 "status and stats\n"
4320 bool uj
= use_json(argc
, argv
);
4321 char role_buf
[MLAG_ROLE_STRSIZE
];
4322 char addr_buf
[INET_ADDRSTRLEN
];
4325 json_object
*json
= NULL
;
4326 json_object
*json_stat
= NULL
;
4328 json
= json_object_new_object();
4329 if (router
->mlag_flags
& PIM_MLAGF_LOCAL_CONN_UP
)
4330 json_object_boolean_true_add(json
, "mlagConnUp");
4331 if (router
->mlag_flags
& PIM_MLAGF_PEER_CONN_UP
)
4332 json_object_boolean_true_add(json
, "mlagPeerConnUp");
4333 if (router
->mlag_flags
& PIM_MLAGF_PEER_ZEBRA_UP
)
4334 json_object_boolean_true_add(json
, "mlagPeerZebraUp");
4335 json_object_string_add(json
, "mlagRole",
4336 mlag_role2str(router
->mlag_role
,
4337 role_buf
, sizeof(role_buf
)));
4338 inet_ntop(AF_INET
, &router
->local_vtep_ip
,
4339 addr_buf
, INET_ADDRSTRLEN
);
4340 json_object_string_add(json
, "localVtepIp", addr_buf
);
4341 inet_ntop(AF_INET
, &router
->anycast_vtep_ip
,
4342 addr_buf
, INET_ADDRSTRLEN
);
4343 json_object_string_add(json
, "anycastVtepIp", addr_buf
);
4344 json_object_string_add(json
, "peerlinkRif",
4345 router
->peerlink_rif
);
4347 json_stat
= json_object_new_object();
4348 json_object_int_add(json_stat
, "mlagConnFlaps",
4349 router
->mlag_stats
.mlagd_session_downs
);
4350 json_object_int_add(json_stat
, "mlagPeerConnFlaps",
4351 router
->mlag_stats
.peer_session_downs
);
4352 json_object_int_add(json_stat
, "mlagPeerZebraFlaps",
4353 router
->mlag_stats
.peer_zebra_downs
);
4354 json_object_int_add(json_stat
, "mrouteAddRx",
4355 router
->mlag_stats
.msg
.mroute_add_rx
);
4356 json_object_int_add(json_stat
, "mrouteAddTx",
4357 router
->mlag_stats
.msg
.mroute_add_tx
);
4358 json_object_int_add(json_stat
, "mrouteDelRx",
4359 router
->mlag_stats
.msg
.mroute_del_rx
);
4360 json_object_int_add(json_stat
, "mrouteDelTx",
4361 router
->mlag_stats
.msg
.mroute_del_tx
);
4362 json_object_int_add(json_stat
, "mlagStatusUpdates",
4363 router
->mlag_stats
.msg
.mlag_status_updates
);
4364 json_object_int_add(json_stat
, "peerZebraStatusUpdates",
4365 router
->mlag_stats
.msg
.peer_zebra_status_updates
);
4366 json_object_int_add(json_stat
, "pimStatusUpdates",
4367 router
->mlag_stats
.msg
.pim_status_updates
);
4368 json_object_int_add(json_stat
, "vxlanUpdates",
4369 router
->mlag_stats
.msg
.vxlan_updates
);
4370 json_object_object_add(json
, "connStats", json_stat
);
4372 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4373 json
, JSON_C_TO_STRING_PRETTY
));
4374 json_object_free(json
);
4378 vty_out(vty
, "MLAG daemon connection: %s\n",
4379 (router
->mlag_flags
& PIM_MLAGF_LOCAL_CONN_UP
)
4381 vty_out(vty
, "MLAG peer state: %s\n",
4382 (router
->mlag_flags
& PIM_MLAGF_PEER_CONN_UP
)
4384 vty_out(vty
, "Zebra peer state: %s\n",
4385 (router
->mlag_flags
& PIM_MLAGF_PEER_ZEBRA_UP
)
4387 vty_out(vty
, "MLAG role: %s\n",
4388 mlag_role2str(router
->mlag_role
, role_buf
, sizeof(role_buf
)));
4389 inet_ntop(AF_INET
, &router
->local_vtep_ip
,
4390 addr_buf
, INET_ADDRSTRLEN
);
4391 vty_out(vty
, "Local VTEP IP: %s\n", addr_buf
);
4392 inet_ntop(AF_INET
, &router
->anycast_vtep_ip
,
4393 addr_buf
, INET_ADDRSTRLEN
);
4394 vty_out(vty
, "Anycast VTEP IP: %s\n", addr_buf
);
4395 vty_out(vty
, "Peerlink: %s\n", router
->peerlink_rif
);
4396 vty_out(vty
, "Session flaps: mlagd: %d mlag-peer: %d zebra-peer: %d\n",
4397 router
->mlag_stats
.mlagd_session_downs
,
4398 router
->mlag_stats
.peer_session_downs
,
4399 router
->mlag_stats
.peer_zebra_downs
);
4400 vty_out(vty
, "Message Statistics:\n");
4401 vty_out(vty
, " mroute adds: rx: %d, tx: %d\n",
4402 router
->mlag_stats
.msg
.mroute_add_rx
,
4403 router
->mlag_stats
.msg
.mroute_add_tx
);
4404 vty_out(vty
, " mroute dels: rx: %d, tx: %d\n",
4405 router
->mlag_stats
.msg
.mroute_del_rx
,
4406 router
->mlag_stats
.msg
.mroute_del_tx
);
4407 vty_out(vty
, " peer zebra status updates: %d\n",
4408 router
->mlag_stats
.msg
.peer_zebra_status_updates
);
4409 vty_out(vty
, " PIM status updates: %d\n",
4410 router
->mlag_stats
.msg
.pim_status_updates
);
4411 vty_out(vty
, " VxLAN updates: %d\n",
4412 router
->mlag_stats
.msg
.vxlan_updates
);
4417 DEFUN (show_ip_pim_assert
,
4418 show_ip_pim_assert_cmd
,
4419 "show ip pim [vrf NAME] assert",
4424 "PIM interface assert\n")
4427 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4432 pim_show_assert(vrf
->info
, vty
);
4437 DEFUN (show_ip_pim_assert_internal
,
4438 show_ip_pim_assert_internal_cmd
,
4439 "show ip pim [vrf NAME] assert-internal",
4444 "PIM interface internal assert state\n")
4447 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4452 pim_show_assert_internal(vrf
->info
, vty
);
4457 DEFUN (show_ip_pim_assert_metric
,
4458 show_ip_pim_assert_metric_cmd
,
4459 "show ip pim [vrf NAME] assert-metric",
4464 "PIM interface assert metric\n")
4467 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4472 pim_show_assert_metric(vrf
->info
, vty
);
4477 DEFUN (show_ip_pim_assert_winner_metric
,
4478 show_ip_pim_assert_winner_metric_cmd
,
4479 "show ip pim [vrf NAME] assert-winner-metric",
4484 "PIM interface assert winner metric\n")
4487 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4492 pim_show_assert_winner_metric(vrf
->info
, vty
);
4497 DEFUN (show_ip_pim_interface
,
4498 show_ip_pim_interface_cmd
,
4499 "show ip pim [mlag] [vrf NAME] interface [detail|WORD] [json]",
4505 "PIM interface information\n"
4511 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4512 bool uj
= use_json(argc
, argv
);
4518 if (argv_find(argv
, argc
, "mlag", &idx
))
4521 if (argv_find(argv
, argc
, "WORD", &idx
)
4522 || argv_find(argv
, argc
, "detail", &idx
))
4523 pim_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, mlag
,
4526 pim_show_interfaces(vrf
->info
, vty
, mlag
, uj
);
4531 DEFUN (show_ip_pim_interface_vrf_all
,
4532 show_ip_pim_interface_vrf_all_cmd
,
4533 "show ip pim [mlag] vrf all interface [detail|WORD] [json]",
4539 "PIM interface information\n"
4545 bool uj
= use_json(argc
, argv
);
4550 if (argv_find(argv
, argc
, "mlag", &idx
))
4556 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4560 vty_out(vty
, " \"%s\": ", vrf
->name
);
4563 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4564 if (argv_find(argv
, argc
, "WORD", &idx
)
4565 || argv_find(argv
, argc
, "detail", &idx
))
4566 pim_show_interfaces_single(vrf
->info
, vty
,
4567 argv
[idx
]->arg
, mlag
, uj
);
4569 pim_show_interfaces(vrf
->info
, vty
, mlag
, uj
);
4572 vty_out(vty
, "}\n");
4577 DEFPY (show_ip_pim_join
,
4578 show_ip_pim_join_cmd
,
4579 "show ip pim [vrf NAME] join [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
4584 "PIM interface join information\n"
4585 "The Source or Group\n"
4589 struct prefix_sg sg
= {0};
4592 struct pim_instance
*pim
;
4594 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
4597 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
4600 pim
= pim_get_pim_instance(v
->vrf_id
);
4603 vty_out(vty
, "%% Unable to find pim instance\n");
4607 if (s_or_g
.s_addr
!= 0) {
4608 if (g
.s_addr
!= 0) {
4615 pim_show_join(pim
, vty
, &sg
, uj
);
4620 DEFUN (show_ip_pim_join_vrf_all
,
4621 show_ip_pim_join_vrf_all_cmd
,
4622 "show ip pim vrf all join [json]",
4627 "PIM interface join information\n"
4630 struct prefix_sg sg
= {0};
4631 bool uj
= use_json(argc
, argv
);
4637 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4641 vty_out(vty
, " \"%s\": ", vrf
->name
);
4644 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4645 pim_show_join(vrf
->info
, vty
, &sg
, uj
);
4648 vty_out(vty
, "}\n");
4653 static void pim_show_jp_agg_helper(struct vty
*vty
,
4654 struct interface
*ifp
,
4655 struct pim_neighbor
*neigh
,
4656 struct pim_upstream
*up
,
4659 char src_str
[INET_ADDRSTRLEN
];
4660 char grp_str
[INET_ADDRSTRLEN
];
4661 char rpf_str
[INET_ADDRSTRLEN
];
4663 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
4664 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
4665 /* pius->address.s_addr */
4666 pim_inet4_dump("<rpf?>", neigh
->source_addr
, rpf_str
, sizeof(rpf_str
));
4668 vty_out(vty
, "%-16s %-15s %-15s %-15s %5s\n",
4669 ifp
->name
, rpf_str
, src_str
,
4670 grp_str
, is_join
?"J":"P");
4673 static void pim_show_jp_agg_list(struct pim_instance
*pim
, struct vty
*vty
)
4675 struct interface
*ifp
;
4676 struct pim_interface
*pim_ifp
;
4677 struct listnode
*n_node
;
4678 struct pim_neighbor
*neigh
;
4679 struct listnode
*jag_node
;
4680 struct pim_jp_agg_group
*jag
;
4681 struct listnode
*js_node
;
4682 struct pim_jp_sources
*js
;
4685 "Interface RPF Nbr Source Group State\n");
4687 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
4688 pim_ifp
= ifp
->info
;
4692 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
,
4694 for (ALL_LIST_ELEMENTS_RO(neigh
->upstream_jp_agg
,
4696 for (ALL_LIST_ELEMENTS_RO(jag
->sources
,
4698 pim_show_jp_agg_helper(vty
,
4707 DEFPY (show_ip_pim_jp_agg
,
4708 show_ip_pim_jp_agg_cmd
,
4709 "show ip pim [vrf NAME] jp-agg",
4714 "join prune aggregation list\n")
4717 struct pim_instance
*pim
;
4719 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
4722 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
4725 pim
= pim_get_pim_instance(v
->vrf_id
);
4728 vty_out(vty
, "%% Unable to find pim instance\n");
4732 pim_show_jp_agg_list(pim
, vty
);
4737 DEFUN (show_ip_pim_local_membership
,
4738 show_ip_pim_local_membership_cmd
,
4739 "show ip pim [vrf NAME] local-membership [json]",
4744 "PIM interface local-membership\n"
4748 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4749 bool uj
= use_json(argc
, argv
);
4754 pim_show_membership(vrf
->info
, vty
, uj
);
4759 static void pim_show_mlag_up_entry_detail(struct vrf
*vrf
,
4760 struct vty
*vty
, struct pim_upstream
*up
,
4761 char *src_str
, char *grp_str
, json_object
*json
)
4764 json_object
*json_row
= NULL
;
4765 json_object
*own_list
= NULL
;
4766 json_object
*json_group
= NULL
;
4769 json_object_object_get_ex(json
, grp_str
, &json_group
);
4771 json_group
= json_object_new_object();
4772 json_object_object_add(json
, grp_str
,
4776 json_row
= json_object_new_object();
4777 json_object_string_add(json_row
, "source", src_str
);
4778 json_object_string_add(json_row
, "group", grp_str
);
4780 own_list
= json_object_new_array();
4781 if (pim_up_mlag_is_local(up
))
4782 json_object_array_add(own_list
,
4783 json_object_new_string("local"));
4784 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
))
4785 json_object_array_add(own_list
,
4786 json_object_new_string("peer"));
4787 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE
))
4788 json_object_array_add(
4789 own_list
, json_object_new_string("Interface"));
4790 json_object_object_add(json_row
, "owners", own_list
);
4792 json_object_int_add(json_row
, "localCost",
4793 pim_up_mlag_local_cost(up
));
4794 json_object_int_add(json_row
, "peerCost",
4795 pim_up_mlag_peer_cost(up
));
4796 if (PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up
->flags
))
4797 json_object_boolean_false_add(json_row
, "df");
4799 json_object_boolean_true_add(json_row
, "df");
4800 json_object_object_add(json_group
, src_str
, json_row
);
4805 if (pim_up_mlag_is_local(up
))
4806 strlcat(own_str
, "L", sizeof(own_str
));
4807 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
))
4808 strlcat(own_str
, "P", sizeof(own_str
));
4809 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE
))
4810 strlcat(own_str
, "I", sizeof(own_str
));
4811 /* XXX - fixup, print paragraph output */
4813 "%-15s %-15s %-6s %-11u %-10d %2s\n",
4814 src_str
, grp_str
, own_str
,
4815 pim_up_mlag_local_cost(up
),
4816 pim_up_mlag_peer_cost(up
),
4817 PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up
->flags
)
4822 static void pim_show_mlag_up_detail(struct vrf
*vrf
,
4823 struct vty
*vty
, const char *src_or_group
,
4824 const char *group
, bool uj
)
4826 char src_str
[INET_ADDRSTRLEN
];
4827 char grp_str
[INET_ADDRSTRLEN
];
4828 struct pim_upstream
*up
;
4829 struct pim_instance
*pim
= vrf
->info
;
4830 json_object
*json
= NULL
;
4833 json
= json_object_new_object();
4836 "Source Group Owner Local-cost Peer-cost DF\n");
4838 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
4839 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
)
4840 && !(up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE
)
4841 && !pim_up_mlag_is_local(up
))
4844 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
4845 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
4846 /* XXX: strcmps are clearly inefficient. we should do uint comps
4850 if (strcmp(src_str
, src_or_group
) ||
4851 strcmp(grp_str
, group
))
4854 if (strcmp(src_str
, src_or_group
) &&
4855 strcmp(grp_str
, src_or_group
))
4858 pim_show_mlag_up_entry_detail(vrf
, vty
, up
,
4859 src_str
, grp_str
, json
);
4863 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4864 json
, JSON_C_TO_STRING_PRETTY
));
4865 json_object_free(json
);
4869 static void pim_show_mlag_up_vrf(struct vrf
*vrf
, struct vty
*vty
, bool uj
)
4871 json_object
*json
= NULL
;
4872 json_object
*json_row
;
4873 struct pim_upstream
*up
;
4874 char src_str
[INET_ADDRSTRLEN
];
4875 char grp_str
[INET_ADDRSTRLEN
];
4876 struct pim_instance
*pim
= vrf
->info
;
4877 json_object
*json_group
= NULL
;
4880 json
= json_object_new_object();
4883 "Source Group Owner Local-cost Peer-cost DF\n");
4886 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
4887 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
)
4888 && !(up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE
)
4889 && !pim_up_mlag_is_local(up
))
4891 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
4892 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
4894 json_object
*own_list
= NULL
;
4896 json_object_object_get_ex(json
, grp_str
, &json_group
);
4898 json_group
= json_object_new_object();
4899 json_object_object_add(json
, grp_str
,
4903 json_row
= json_object_new_object();
4904 json_object_string_add(json_row
, "vrf", vrf
->name
);
4905 json_object_string_add(json_row
, "source", src_str
);
4906 json_object_string_add(json_row
, "group", grp_str
);
4908 own_list
= json_object_new_array();
4909 if (pim_up_mlag_is_local(up
)) {
4911 json_object_array_add(own_list
,
4912 json_object_new_string("local"));
4914 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
)) {
4915 json_object_array_add(own_list
,
4916 json_object_new_string("peer"));
4918 json_object_object_add(json_row
, "owners", own_list
);
4920 json_object_int_add(json_row
, "localCost",
4921 pim_up_mlag_local_cost(up
));
4922 json_object_int_add(json_row
, "peerCost",
4923 pim_up_mlag_peer_cost(up
));
4924 if (PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up
->flags
))
4925 json_object_boolean_false_add(json_row
, "df");
4927 json_object_boolean_true_add(json_row
, "df");
4928 json_object_object_add(json_group
, src_str
, json_row
);
4933 if (pim_up_mlag_is_local(up
))
4934 strlcat(own_str
, "L", sizeof(own_str
));
4935 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
))
4936 strlcat(own_str
, "P", sizeof(own_str
));
4937 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE
))
4938 strlcat(own_str
, "I", sizeof(own_str
));
4940 "%-15s %-15s %-6s %-11u %-10u %2s\n",
4941 src_str
, grp_str
, own_str
,
4942 pim_up_mlag_local_cost(up
),
4943 pim_up_mlag_peer_cost(up
),
4944 PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up
->flags
)
4949 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4950 json
, JSON_C_TO_STRING_PRETTY
));
4951 json_object_free(json
);
4955 static void pim_show_mlag_help_string(struct vty
*vty
, bool uj
)
4958 vty_out(vty
, "Owner codes:\n");
4960 "L: EVPN-MLAG Entry, I:PIM-MLAG Entry, "
4966 DEFUN(show_ip_pim_mlag_up
, show_ip_pim_mlag_up_cmd
,
4967 "show ip pim [vrf NAME] mlag upstream [A.B.C.D [A.B.C.D]] [json]",
4974 "Unicast or Multicast address\n"
4975 "Multicast address\n" JSON_STR
)
4977 const char *src_or_group
= NULL
;
4978 const char *group
= NULL
;
4980 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4981 bool uj
= use_json(argc
, argv
);
4983 if (!vrf
|| !vrf
->info
) {
4984 vty_out(vty
, "%s: VRF or Info missing\n", __func__
);
4991 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
4992 src_or_group
= argv
[idx
]->arg
;
4994 group
= argv
[idx
+ 1]->arg
;
4997 pim_show_mlag_help_string(vty
, uj
);
5000 pim_show_mlag_up_detail(vrf
, vty
, src_or_group
, group
, uj
);
5002 pim_show_mlag_up_vrf(vrf
, vty
, uj
);
5008 DEFUN(show_ip_pim_mlag_up_vrf_all
, show_ip_pim_mlag_up_vrf_all_cmd
,
5009 "show ip pim vrf all mlag upstream [json]",
5010 SHOW_STR IP_STR PIM_STR VRF_CMD_HELP_STR
5012 "upstream\n" JSON_STR
)
5015 bool uj
= use_json(argc
, argv
);
5017 pim_show_mlag_help_string(vty
, uj
);
5018 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5019 pim_show_mlag_up_vrf(vrf
, vty
, uj
);
5025 DEFUN (show_ip_pim_neighbor
,
5026 show_ip_pim_neighbor_cmd
,
5027 "show ip pim [vrf NAME] neighbor [detail|WORD] [json]",
5032 "PIM neighbor information\n"
5034 "Name of interface or neighbor\n"
5038 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5039 bool uj
= use_json(argc
, argv
);
5044 if (argv_find(argv
, argc
, "detail", &idx
)
5045 || argv_find(argv
, argc
, "WORD", &idx
))
5046 pim_show_neighbors_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
5048 pim_show_neighbors(vrf
->info
, vty
, uj
);
5053 DEFUN (show_ip_pim_neighbor_vrf_all
,
5054 show_ip_pim_neighbor_vrf_all_cmd
,
5055 "show ip pim vrf all neighbor [detail|WORD] [json]",
5060 "PIM neighbor information\n"
5062 "Name of interface or neighbor\n"
5066 bool uj
= use_json(argc
, argv
);
5072 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5076 vty_out(vty
, " \"%s\": ", vrf
->name
);
5079 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5080 if (argv_find(argv
, argc
, "detail", &idx
)
5081 || argv_find(argv
, argc
, "WORD", &idx
))
5082 pim_show_neighbors_single(vrf
->info
, vty
,
5083 argv
[idx
]->arg
, uj
);
5085 pim_show_neighbors(vrf
->info
, vty
, uj
);
5088 vty_out(vty
, "}\n");
5093 DEFUN (show_ip_pim_secondary
,
5094 show_ip_pim_secondary_cmd
,
5095 "show ip pim [vrf NAME] secondary",
5100 "PIM neighbor addresses\n")
5103 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5108 pim_show_neighbors_secondary(vrf
->info
, vty
);
5113 DEFUN (show_ip_pim_state
,
5114 show_ip_pim_state_cmd
,
5115 "show ip pim [vrf NAME] state [A.B.C.D [A.B.C.D]] [json]",
5120 "PIM state information\n"
5121 "Unicast or Multicast address\n"
5122 "Multicast address\n"
5125 const char *src_or_group
= NULL
;
5126 const char *group
= NULL
;
5128 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5129 bool uj
= use_json(argc
, argv
);
5137 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
5138 src_or_group
= argv
[idx
]->arg
;
5140 group
= argv
[idx
+ 1]->arg
;
5143 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
5148 DEFUN (show_ip_pim_state_vrf_all
,
5149 show_ip_pim_state_vrf_all_cmd
,
5150 "show ip pim vrf all state [A.B.C.D [A.B.C.D]] [json]",
5155 "PIM state information\n"
5156 "Unicast or Multicast address\n"
5157 "Multicast address\n"
5160 const char *src_or_group
= NULL
;
5161 const char *group
= NULL
;
5163 bool uj
= use_json(argc
, argv
);
5172 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
5173 src_or_group
= argv
[idx
]->arg
;
5175 group
= argv
[idx
+ 1]->arg
;
5178 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5182 vty_out(vty
, " \"%s\": ", vrf
->name
);
5185 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5186 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
5189 vty_out(vty
, "}\n");
5194 DEFPY (show_ip_pim_upstream
,
5195 show_ip_pim_upstream_cmd
,
5196 "show ip pim [vrf NAME] upstream [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
5201 "PIM upstream information\n"
5202 "The Source or Group\n"
5206 struct prefix_sg sg
= {0};
5209 struct pim_instance
*pim
;
5211 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
5214 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
5217 pim
= pim_get_pim_instance(v
->vrf_id
);
5220 vty_out(vty
, "%% Unable to find pim instance\n");
5224 if (s_or_g
.s_addr
!= 0) {
5225 if (g
.s_addr
!= 0) {
5231 pim_show_upstream(pim
, vty
, &sg
, uj
);
5236 DEFUN (show_ip_pim_upstream_vrf_all
,
5237 show_ip_pim_upstream_vrf_all_cmd
,
5238 "show ip pim vrf all upstream [json]",
5243 "PIM upstream information\n"
5246 struct prefix_sg sg
= {0};
5247 bool uj
= use_json(argc
, argv
);
5253 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5257 vty_out(vty
, " \"%s\": ", vrf
->name
);
5260 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5261 pim_show_upstream(vrf
->info
, vty
, &sg
, uj
);
5267 DEFUN (show_ip_pim_channel
,
5268 show_ip_pim_channel_cmd
,
5269 "show ip pim [vrf NAME] channel [json]",
5274 "PIM downstream channel info\n"
5278 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5279 bool uj
= use_json(argc
, argv
);
5284 pim_show_channel(vrf
->info
, vty
, uj
);
5289 DEFUN (show_ip_pim_upstream_join_desired
,
5290 show_ip_pim_upstream_join_desired_cmd
,
5291 "show ip pim [vrf NAME] upstream-join-desired [json]",
5296 "PIM upstream join-desired\n"
5300 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5301 bool uj
= use_json(argc
, argv
);
5306 pim_show_join_desired(vrf
->info
, vty
, uj
);
5311 DEFUN (show_ip_pim_upstream_rpf
,
5312 show_ip_pim_upstream_rpf_cmd
,
5313 "show ip pim [vrf NAME] upstream-rpf [json]",
5318 "PIM upstream source rpf\n"
5322 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5323 bool uj
= use_json(argc
, argv
);
5328 pim_show_upstream_rpf(vrf
->info
, vty
, uj
);
5333 DEFUN (show_ip_pim_rp
,
5335 "show ip pim [vrf NAME] rp-info [json]",
5340 "PIM RP information\n"
5344 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5345 bool uj
= use_json(argc
, argv
);
5350 pim_rp_show_information(vrf
->info
, vty
, uj
);
5355 DEFUN (show_ip_pim_rp_vrf_all
,
5356 show_ip_pim_rp_vrf_all_cmd
,
5357 "show ip pim vrf all rp-info [json]",
5362 "PIM RP information\n"
5365 bool uj
= use_json(argc
, argv
);
5371 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5375 vty_out(vty
, " \"%s\": ", vrf
->name
);
5378 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5379 pim_rp_show_information(vrf
->info
, vty
, uj
);
5382 vty_out(vty
, "}\n");
5387 DEFUN (show_ip_pim_rpf
,
5388 show_ip_pim_rpf_cmd
,
5389 "show ip pim [vrf NAME] rpf [json]",
5394 "PIM cached source rpf information\n"
5398 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5399 bool uj
= use_json(argc
, argv
);
5404 pim_show_rpf(vrf
->info
, vty
, uj
);
5409 DEFUN (show_ip_pim_rpf_vrf_all
,
5410 show_ip_pim_rpf_vrf_all_cmd
,
5411 "show ip pim vrf all rpf [json]",
5416 "PIM cached source rpf information\n"
5419 bool uj
= use_json(argc
, argv
);
5425 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5429 vty_out(vty
, " \"%s\": ", vrf
->name
);
5432 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5433 pim_show_rpf(vrf
->info
, vty
, uj
);
5436 vty_out(vty
, "}\n");
5441 DEFUN (show_ip_pim_nexthop
,
5442 show_ip_pim_nexthop_cmd
,
5443 "show ip pim [vrf NAME] nexthop",
5448 "PIM cached nexthop rpf information\n")
5451 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5456 pim_show_nexthop(vrf
->info
, vty
);
5461 DEFUN (show_ip_pim_nexthop_lookup
,
5462 show_ip_pim_nexthop_lookup_cmd
,
5463 "show ip pim [vrf NAME] nexthop-lookup A.B.C.D A.B.C.D",
5468 "PIM cached nexthop rpf lookup\n"
5469 "Source/RP address\n"
5470 "Multicast Group address\n")
5472 struct prefix nht_p
;
5474 struct in_addr src_addr
, grp_addr
;
5475 struct in_addr vif_source
;
5476 const char *addr_str
, *addr_str1
;
5478 struct pim_nexthop nexthop
;
5479 char nexthop_addr_str
[PREFIX_STRLEN
];
5480 char grp_str
[PREFIX_STRLEN
];
5482 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5487 argv_find(argv
, argc
, "A.B.C.D", &idx
);
5488 addr_str
= argv
[idx
]->arg
;
5489 result
= inet_pton(AF_INET
, addr_str
, &src_addr
);
5491 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
5492 errno
, safe_strerror(errno
));
5496 if (pim_is_group_224_4(src_addr
)) {
5498 "Invalid argument. Expected Valid Source Address.\n");
5502 addr_str1
= argv
[idx
+ 1]->arg
;
5503 result
= inet_pton(AF_INET
, addr_str1
, &grp_addr
);
5505 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
5506 errno
, safe_strerror(errno
));
5510 if (!pim_is_group_224_4(grp_addr
)) {
5512 "Invalid argument. Expected Valid Multicast Group Address.\n");
5516 if (!pim_rp_set_upstream_addr(vrf
->info
, &vif_source
, src_addr
,
5520 nht_p
.family
= AF_INET
;
5521 nht_p
.prefixlen
= IPV4_MAX_BITLEN
;
5522 nht_p
.u
.prefix4
= vif_source
;
5523 grp
.family
= AF_INET
;
5524 grp
.prefixlen
= IPV4_MAX_BITLEN
;
5525 grp
.u
.prefix4
= grp_addr
;
5526 memset(&nexthop
, 0, sizeof(nexthop
));
5528 result
= pim_ecmp_nexthop_lookup(vrf
->info
, &nexthop
, &nht_p
, &grp
, 0);
5532 "Nexthop Lookup failed, no usable routes returned.\n");
5536 pim_addr_dump("<grp?>", &grp
, grp_str
, sizeof(grp_str
));
5537 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
5538 nexthop_addr_str
, sizeof(nexthop_addr_str
));
5539 vty_out(vty
, "Group %s --- Nexthop %s Interface %s \n", grp_str
,
5540 nexthop_addr_str
, nexthop
.interface
->name
);
5545 DEFUN (show_ip_pim_interface_traffic
,
5546 show_ip_pim_interface_traffic_cmd
,
5547 "show ip pim [vrf NAME] interface traffic [WORD] [json]",
5552 "PIM interface information\n"
5553 "Protocol Packet counters\n"
5558 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5559 bool uj
= use_json(argc
, argv
);
5564 if (argv_find(argv
, argc
, "WORD", &idx
))
5565 pim_show_interface_traffic_single(vrf
->info
, vty
,
5566 argv
[idx
]->arg
, uj
);
5568 pim_show_interface_traffic(vrf
->info
, vty
, uj
);
5573 DEFUN (show_ip_pim_bsm_db
,
5574 show_ip_pim_bsm_db_cmd
,
5575 "show ip pim bsm-database [vrf NAME] [json]",
5579 "PIM cached bsm packets information\n"
5584 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5585 bool uj
= use_json(argc
, argv
);
5590 pim_show_bsm_db(vrf
->info
, vty
, uj
);
5594 DEFUN (show_ip_pim_bsrp
,
5595 show_ip_pim_bsrp_cmd
,
5596 "show ip pim bsrp-info [vrf NAME] [json]",
5600 "PIM cached group-rp mappings information\n"
5605 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5606 bool uj
= use_json(argc
, argv
);
5611 pim_show_group_rp_mappings_info(vrf
->info
, vty
, uj
);
5616 DEFUN (show_ip_pim_statistics
,
5617 show_ip_pim_statistics_cmd
,
5618 "show ip pim [vrf NAME] statistics [interface WORD] [json]",
5629 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5630 bool uj
= use_json(argc
, argv
);
5635 if (argv_find(argv
, argc
, "WORD", &idx
))
5636 pim_show_statistics(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
5638 pim_show_statistics(vrf
->info
, vty
, NULL
, uj
);
5643 static void show_multicast_interfaces(struct pim_instance
*pim
, struct vty
*vty
)
5645 struct interface
*ifp
;
5650 "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut\n");
5652 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
5653 struct pim_interface
*pim_ifp
;
5654 struct in_addr ifaddr
;
5655 struct sioc_vif_req vreq
;
5657 pim_ifp
= ifp
->info
;
5662 memset(&vreq
, 0, sizeof(vreq
));
5663 vreq
.vifi
= pim_ifp
->mroute_vif_index
;
5665 if (ioctl(pim
->mroute_socket
, SIOCGETVIFCNT
, &vreq
)) {
5667 "ioctl(SIOCGETVIFCNT=%lu) failure for interface %s vif_index=%d: errno=%d: %s",
5668 (unsigned long)SIOCGETVIFCNT
, ifp
->name
,
5669 pim_ifp
->mroute_vif_index
, errno
,
5670 safe_strerror(errno
));
5673 ifaddr
= pim_ifp
->primary_address
;
5675 vty_out(vty
, "%-16s %-15s %3d %3d %7lu %7lu %10lu %10lu\n",
5676 ifp
->name
, inet_ntoa(ifaddr
), ifp
->ifindex
,
5677 pim_ifp
->mroute_vif_index
, (unsigned long)vreq
.icount
,
5678 (unsigned long)vreq
.ocount
, (unsigned long)vreq
.ibytes
,
5679 (unsigned long)vreq
.obytes
);
5683 static void pim_cmd_show_ip_multicast_helper(struct pim_instance
*pim
,
5686 struct vrf
*vrf
= pim
->vrf
;
5687 time_t now
= pim_time_monotonic_sec();
5693 vty_out(vty
, "Router MLAG Role: %s\n",
5694 mlag_role2str(router
->mlag_role
, mlag_role
, sizeof(mlag_role
)));
5695 vty_out(vty
, "Mroute socket descriptor:");
5697 vty_out(vty
, " %d(%s)\n", pim
->mroute_socket
, vrf
->name
);
5699 pim_time_uptime(uptime
, sizeof(uptime
),
5700 now
- pim
->mroute_socket_creation
);
5701 vty_out(vty
, "Mroute socket uptime: %s\n", uptime
);
5705 pim_zebra_zclient_update(vty
);
5706 pim_zlookup_show_ip_multicast(vty
);
5709 vty_out(vty
, "Maximum highest VifIndex: %d\n", PIM_MAX_USABLE_VIFS
);
5712 vty_out(vty
, "Upstream Join Timer: %d secs\n", router
->t_periodic
);
5713 vty_out(vty
, "Join/Prune Holdtime: %d secs\n", PIM_JP_HOLDTIME
);
5714 vty_out(vty
, "PIM ECMP: %s\n", pim
->ecmp_enable
? "Enable" : "Disable");
5715 vty_out(vty
, "PIM ECMP Rebalance: %s\n",
5716 pim
->ecmp_rebalance_enable
? "Enable" : "Disable");
5720 show_rpf_refresh_stats(vty
, pim
, now
, NULL
);
5724 show_scan_oil_stats(pim
, vty
, now
);
5726 show_multicast_interfaces(pim
, vty
);
5729 DEFUN (show_ip_multicast
,
5730 show_ip_multicast_cmd
,
5731 "show ip multicast [vrf NAME]",
5735 "Multicast global information\n")
5738 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5743 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
5748 DEFUN (show_ip_multicast_vrf_all
,
5749 show_ip_multicast_vrf_all_cmd
,
5750 "show ip multicast vrf all",
5754 "Multicast global information\n")
5756 bool uj
= use_json(argc
, argv
);
5762 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5766 vty_out(vty
, " \"%s\": ", vrf
->name
);
5769 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5770 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
5773 vty_out(vty
, "}\n");
5778 static void show_mroute(struct pim_instance
*pim
, struct vty
*vty
,
5779 struct prefix_sg
*sg
, bool fill
, bool uj
)
5781 struct listnode
*node
;
5782 struct channel_oil
*c_oil
;
5783 struct static_route
*s_route
;
5785 json_object
*json
= NULL
;
5786 json_object
*json_group
= NULL
;
5787 json_object
*json_source
= NULL
;
5788 json_object
*json_oil
= NULL
;
5789 json_object
*json_ifp_out
= NULL
;
5792 char grp_str
[INET_ADDRSTRLEN
];
5793 char src_str
[INET_ADDRSTRLEN
];
5794 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
5795 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
5797 struct interface
*ifp_in
;
5799 char state_str
[PIM_REG_STATE_STR_LEN
];
5800 char mroute_uptime
[10];
5803 json
= json_object_new_object();
5805 vty_out(vty
, "IP Multicast Routing Table\n");
5806 vty_out(vty
, "Flags: S- Sparse, C - Connected, P - Pruned\n");
5808 " R - RP-bit set, F - Register flag, T - SPT-bit set\n");
5810 "\nSource Group Flags Proto Input Output TTL Uptime\n");
5813 now
= pim_time_monotonic_sec();
5815 /* print list of PIM and IGMP routes */
5816 frr_each (rb_pim_oil
, &pim
->channel_oil_head
, c_oil
) {
5819 if (!c_oil
->installed
&& !uj
)
5822 if (sg
->grp
.s_addr
!= 0 &&
5823 sg
->grp
.s_addr
!= c_oil
->oil
.mfcc_mcastgrp
.s_addr
)
5825 if (sg
->src
.s_addr
!= 0 &&
5826 sg
->src
.s_addr
!= c_oil
->oil
.mfcc_origin
.s_addr
)
5829 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
5831 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
5834 strlcpy(state_str
, "S", sizeof(state_str
));
5835 /* When a non DR receives a igmp join, it creates a (*,G)
5836 * channel_oil without any upstream creation */
5838 if (PIM_UPSTREAM_FLAG_TEST_SRC_IGMP(c_oil
->up
->flags
))
5839 strlcat(state_str
, "C", sizeof(state_str
));
5840 if (pim_upstream_is_sg_rpt(c_oil
->up
))
5841 strlcat(state_str
, "R", sizeof(state_str
));
5842 if (PIM_UPSTREAM_FLAG_TEST_FHR(c_oil
->up
->flags
))
5843 strlcat(state_str
, "F", sizeof(state_str
));
5844 if (c_oil
->up
->sptbit
== PIM_UPSTREAM_SPTBIT_TRUE
)
5845 strlcat(state_str
, "T", sizeof(state_str
));
5847 if (pim_channel_oil_empty(c_oil
))
5848 strlcat(state_str
, "P", sizeof(state_str
));
5850 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
5853 strlcpy(in_ifname
, ifp_in
->name
, sizeof(in_ifname
));
5855 strlcpy(in_ifname
, "<iif?>", sizeof(in_ifname
));
5858 pim_time_uptime(mroute_uptime
, sizeof(mroute_uptime
),
5859 now
- c_oil
->mroute_creation
);
5863 /* Find the group, create it if it doesn't exist */
5864 json_object_object_get_ex(json
, grp_str
, &json_group
);
5867 json_group
= json_object_new_object();
5868 json_object_object_add(json
, grp_str
,
5872 /* Find the source nested under the group, create it if
5875 json_object_object_get_ex(json_group
, src_str
,
5879 json_source
= json_object_new_object();
5880 json_object_object_add(json_group
, src_str
,
5884 /* Find the inbound interface nested under the source,
5885 * create it if it doesn't exist */
5886 json_object_int_add(json_source
, "installed",
5888 json_object_int_add(json_source
, "refCount",
5889 c_oil
->oil_ref_count
);
5890 json_object_int_add(json_source
, "oilSize",
5892 json_object_int_add(json_source
, "OilInheritedRescan",
5893 c_oil
->oil_inherited_rescan
);
5894 json_object_string_add(json_source
, "iif", in_ifname
);
5895 json_object_string_add(json_source
, "upTime",
5900 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
5902 struct interface
*ifp_out
;
5905 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
5909 /* do not display muted OIFs */
5910 if (c_oil
->oif_flags
[oif_vif_index
]
5911 & PIM_OIF_FLAG_MUTE
)
5914 if (c_oil
->oil
.mfcc_parent
== oif_vif_index
&&
5915 !pim_mroute_allow_iif_in_oil(c_oil
,
5919 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
5923 strlcpy(out_ifname
, ifp_out
->name
, sizeof(out_ifname
));
5925 strlcpy(out_ifname
, "<oif?>", sizeof(out_ifname
));
5928 json_ifp_out
= json_object_new_object();
5929 json_object_string_add(json_ifp_out
, "source",
5931 json_object_string_add(json_ifp_out
, "group",
5934 if (c_oil
->oif_flags
[oif_vif_index
]
5935 & PIM_OIF_FLAG_PROTO_PIM
)
5936 json_object_boolean_true_add(
5937 json_ifp_out
, "protocolPim");
5939 if (c_oil
->oif_flags
[oif_vif_index
]
5940 & PIM_OIF_FLAG_PROTO_IGMP
)
5941 json_object_boolean_true_add(
5942 json_ifp_out
, "protocolIgmp");
5944 if (c_oil
->oif_flags
[oif_vif_index
]
5945 & PIM_OIF_FLAG_PROTO_VXLAN
)
5946 json_object_boolean_true_add(
5947 json_ifp_out
, "protocolVxlan");
5949 if (c_oil
->oif_flags
[oif_vif_index
]
5950 & PIM_OIF_FLAG_PROTO_STAR
)
5951 json_object_boolean_true_add(
5953 "protocolInherited");
5955 json_object_string_add(json_ifp_out
,
5958 json_object_int_add(json_ifp_out
, "iVifI",
5959 c_oil
->oil
.mfcc_parent
);
5960 json_object_string_add(json_ifp_out
,
5961 "outboundInterface",
5963 json_object_int_add(json_ifp_out
, "oVifI",
5965 json_object_int_add(json_ifp_out
, "ttl", ttl
);
5966 json_object_string_add(json_ifp_out
, "upTime",
5969 json_oil
= json_object_new_object();
5970 json_object_object_add(json_source
,
5973 json_object_object_add(json_oil
, out_ifname
,
5976 if (c_oil
->oif_flags
[oif_vif_index
]
5977 & PIM_OIF_FLAG_PROTO_PIM
) {
5978 strlcpy(proto
, "PIM", sizeof(proto
));
5981 if (c_oil
->oif_flags
[oif_vif_index
]
5982 & PIM_OIF_FLAG_PROTO_IGMP
) {
5983 strlcpy(proto
, "IGMP", sizeof(proto
));
5986 if (c_oil
->oif_flags
[oif_vif_index
]
5987 & PIM_OIF_FLAG_PROTO_VXLAN
) {
5988 strlcpy(proto
, "VxLAN", sizeof(proto
));
5991 if (c_oil
->oif_flags
[oif_vif_index
]
5992 & PIM_OIF_FLAG_PROTO_STAR
) {
5993 strlcpy(proto
, "STAR", sizeof(proto
));
5997 "%-15s %-15s %-15s %-6s %-16s %-16s %-3d %8s\n",
5998 src_str
, grp_str
, state_str
, proto
,
5999 in_ifname
, out_ifname
, ttl
,
6005 in_ifname
[0] = '\0';
6006 state_str
[0] = '\0';
6007 mroute_uptime
[0] = '\0';
6013 if (!uj
&& !found_oif
) {
6015 "%-15s %-15s %-15s %-6s %-16s %-16s %-3d %8s\n",
6016 src_str
, grp_str
, state_str
, "none", in_ifname
,
6017 "none", 0, "--:--:--");
6021 /* Print list of static routes */
6022 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
6025 if (!s_route
->c_oil
.installed
)
6028 pim_inet4_dump("<group?>", s_route
->group
, grp_str
,
6030 pim_inet4_dump("<source?>", s_route
->source
, src_str
,
6032 ifp_in
= pim_if_find_by_vif_index(pim
, s_route
->iif
);
6036 strlcpy(in_ifname
, ifp_in
->name
, sizeof(in_ifname
));
6038 strlcpy(in_ifname
, "<iif?>", sizeof(in_ifname
));
6042 /* Find the group, create it if it doesn't exist */
6043 json_object_object_get_ex(json
, grp_str
, &json_group
);
6046 json_group
= json_object_new_object();
6047 json_object_object_add(json
, grp_str
,
6051 /* Find the source nested under the group, create it if
6052 * it doesn't exist */
6053 json_object_object_get_ex(json_group
, src_str
,
6057 json_source
= json_object_new_object();
6058 json_object_object_add(json_group
, src_str
,
6062 json_object_string_add(json_source
, "iif", in_ifname
);
6065 strlcpy(proto
, "STATIC", sizeof(proto
));
6068 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
6070 struct interface
*ifp_out
;
6071 char oif_uptime
[10];
6074 ttl
= s_route
->oif_ttls
[oif_vif_index
];
6078 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
6080 oif_uptime
, sizeof(oif_uptime
),
6083 .oif_creation
[oif_vif_index
]);
6087 strlcpy(out_ifname
, ifp_out
->name
, sizeof(out_ifname
));
6089 strlcpy(out_ifname
, "<oif?>", sizeof(out_ifname
));
6092 json_ifp_out
= json_object_new_object();
6093 json_object_string_add(json_ifp_out
, "source",
6095 json_object_string_add(json_ifp_out
, "group",
6097 json_object_boolean_true_add(json_ifp_out
,
6099 json_object_string_add(json_ifp_out
,
6102 json_object_int_add(
6103 json_ifp_out
, "iVifI",
6104 s_route
->c_oil
.oil
.mfcc_parent
);
6105 json_object_string_add(json_ifp_out
,
6106 "outboundInterface",
6108 json_object_int_add(json_ifp_out
, "oVifI",
6110 json_object_int_add(json_ifp_out
, "ttl", ttl
);
6111 json_object_string_add(json_ifp_out
, "upTime",
6114 json_oil
= json_object_new_object();
6115 json_object_object_add(json_source
,
6118 json_object_object_add(json_oil
, out_ifname
,
6122 "%-15s %-15s %-6s %-16s %-16s %-3d %8s %s\n",
6123 src_str
, grp_str
, proto
, in_ifname
,
6124 out_ifname
, ttl
, oif_uptime
,
6126 if (first
&& !fill
) {
6129 in_ifname
[0] = '\0';
6135 if (!uj
&& !found_oif
) {
6137 "%-15s %-15s %-6s %-16s %-16s %-3d %8s %s\n",
6138 src_str
, grp_str
, proto
, in_ifname
, "none", 0,
6139 "--:--:--", pim
->vrf
->name
);
6144 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
6145 json
, JSON_C_TO_STRING_PRETTY
));
6146 json_object_free(json
);
6150 DEFPY (show_ip_mroute
,
6152 "show ip mroute [vrf NAME] [A.B.C.D$s_or_g [A.B.C.D$g]] [fill$fill] [json$json]",
6157 "The Source or Group\n"
6159 "Fill in Assumed data\n"
6162 struct prefix_sg sg
= {0};
6163 struct pim_instance
*pim
;
6166 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
6169 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
6172 pim
= pim_get_pim_instance(v
->vrf_id
);
6175 vty_out(vty
, "%% Unable to find pim instance\n");
6179 if (s_or_g
.s_addr
!= 0) {
6180 if (g
.s_addr
!= 0) {
6186 show_mroute(pim
, vty
, &sg
, !!fill
, !!json
);
6190 DEFUN (show_ip_mroute_vrf_all
,
6191 show_ip_mroute_vrf_all_cmd
,
6192 "show ip mroute vrf all [fill] [json]",
6197 "Fill in Assumed data\n"
6200 struct prefix_sg sg
= {0};
6201 bool uj
= use_json(argc
, argv
);
6207 if (argv_find(argv
, argc
, "fill", &idx
))
6212 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
6216 vty_out(vty
, " \"%s\": ", vrf
->name
);
6219 vty_out(vty
, "VRF: %s\n", vrf
->name
);
6220 show_mroute(vrf
->info
, vty
, &sg
, fill
, uj
);
6223 vty_out(vty
, "}\n");
6228 DEFUN (clear_ip_mroute_count
,
6229 clear_ip_mroute_count_cmd
,
6230 "clear ip mroute [vrf NAME] count",
6235 "Route and packet count data\n")
6238 struct listnode
*node
;
6239 struct channel_oil
*c_oil
;
6240 struct static_route
*sr
;
6241 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6242 struct pim_instance
*pim
;
6248 frr_each(rb_pim_oil
, &pim
->channel_oil_head
, c_oil
) {
6249 if (!c_oil
->installed
)
6252 pim_mroute_update_counters(c_oil
);
6253 c_oil
->cc
.origpktcnt
= c_oil
->cc
.pktcnt
;
6254 c_oil
->cc
.origbytecnt
= c_oil
->cc
.bytecnt
;
6255 c_oil
->cc
.origwrong_if
= c_oil
->cc
.wrong_if
;
6258 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, sr
)) {
6259 if (!sr
->c_oil
.installed
)
6262 pim_mroute_update_counters(&sr
->c_oil
);
6264 sr
->c_oil
.cc
.origpktcnt
= sr
->c_oil
.cc
.pktcnt
;
6265 sr
->c_oil
.cc
.origbytecnt
= sr
->c_oil
.cc
.bytecnt
;
6266 sr
->c_oil
.cc
.origwrong_if
= sr
->c_oil
.cc
.wrong_if
;
6271 static void show_mroute_count(struct pim_instance
*pim
, struct vty
*vty
)
6273 struct listnode
*node
;
6274 struct channel_oil
*c_oil
;
6275 struct static_route
*sr
;
6280 "Source Group LastUsed Packets Bytes WrongIf \n");
6282 /* Print PIM and IGMP route counts */
6283 frr_each (rb_pim_oil
, &pim
->channel_oil_head
, c_oil
) {
6284 char group_str
[INET_ADDRSTRLEN
];
6285 char source_str
[INET_ADDRSTRLEN
];
6287 if (!c_oil
->installed
)
6290 pim_mroute_update_counters(c_oil
);
6292 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, group_str
,
6294 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, source_str
,
6295 sizeof(source_str
));
6297 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
6298 source_str
, group_str
, c_oil
->cc
.lastused
/ 100,
6299 c_oil
->cc
.pktcnt
- c_oil
->cc
.origpktcnt
,
6300 c_oil
->cc
.bytecnt
- c_oil
->cc
.origbytecnt
,
6301 c_oil
->cc
.wrong_if
- c_oil
->cc
.origwrong_if
);
6304 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, sr
)) {
6305 char group_str
[INET_ADDRSTRLEN
];
6306 char source_str
[INET_ADDRSTRLEN
];
6308 if (!sr
->c_oil
.installed
)
6311 pim_mroute_update_counters(&sr
->c_oil
);
6313 pim_inet4_dump("<group?>", sr
->c_oil
.oil
.mfcc_mcastgrp
,
6314 group_str
, sizeof(group_str
));
6315 pim_inet4_dump("<source?>", sr
->c_oil
.oil
.mfcc_origin
,
6316 source_str
, sizeof(source_str
));
6318 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
6319 source_str
, group_str
, sr
->c_oil
.cc
.lastused
,
6320 sr
->c_oil
.cc
.pktcnt
- sr
->c_oil
.cc
.origpktcnt
,
6321 sr
->c_oil
.cc
.bytecnt
- sr
->c_oil
.cc
.origbytecnt
,
6322 sr
->c_oil
.cc
.wrong_if
- sr
->c_oil
.cc
.origwrong_if
);
6326 DEFUN (show_ip_mroute_count
,
6327 show_ip_mroute_count_cmd
,
6328 "show ip mroute [vrf NAME] count",
6333 "Route and packet count data\n")
6336 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6341 show_mroute_count(vrf
->info
, vty
);
6345 DEFUN (show_ip_mroute_count_vrf_all
,
6346 show_ip_mroute_count_vrf_all_cmd
,
6347 "show ip mroute vrf all count",
6352 "Route and packet count data\n")
6354 bool uj
= use_json(argc
, argv
);
6360 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
6364 vty_out(vty
, " \"%s\": ", vrf
->name
);
6367 vty_out(vty
, "VRF: %s\n", vrf
->name
);
6368 show_mroute_count(vrf
->info
, vty
);
6371 vty_out(vty
, "}\n");
6376 static void show_mroute_summary(struct pim_instance
*pim
, struct vty
*vty
)
6378 struct listnode
*node
;
6379 struct channel_oil
*c_oil
;
6380 struct static_route
*s_route
;
6381 uint32_t starg_sw_mroute_cnt
= 0;
6382 uint32_t sg_sw_mroute_cnt
= 0;
6383 uint32_t starg_hw_mroute_cnt
= 0;
6384 uint32_t sg_hw_mroute_cnt
= 0;
6386 vty_out(vty
, "Mroute Type Installed/Total\n");
6388 frr_each (rb_pim_oil
, &pim
->channel_oil_head
, c_oil
) {
6389 if (!c_oil
->installed
) {
6390 if (c_oil
->oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
6391 starg_sw_mroute_cnt
++;
6395 if (c_oil
->oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
6396 starg_hw_mroute_cnt
++;
6402 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
6403 if (!s_route
->c_oil
.installed
) {
6404 if (s_route
->c_oil
.oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
6405 starg_sw_mroute_cnt
++;
6409 if (s_route
->c_oil
.oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
6410 starg_hw_mroute_cnt
++;
6416 vty_out(vty
, "%-20s %d/%d\n", "(*, G)", starg_hw_mroute_cnt
,
6417 starg_sw_mroute_cnt
+ starg_hw_mroute_cnt
);
6418 vty_out(vty
, "%-20s %d/%d\n", "(S, G)", sg_hw_mroute_cnt
,
6419 sg_sw_mroute_cnt
+ sg_hw_mroute_cnt
);
6420 vty_out(vty
, "------\n");
6421 vty_out(vty
, "%-20s %d/%d\n", "Total",
6422 (starg_hw_mroute_cnt
+ sg_hw_mroute_cnt
),
6423 (starg_sw_mroute_cnt
+
6424 starg_hw_mroute_cnt
+
6429 DEFUN (show_ip_mroute_summary
,
6430 show_ip_mroute_summary_cmd
,
6431 "show ip mroute [vrf NAME] summary",
6436 "Summary of all mroutes\n")
6439 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6444 show_mroute_summary(vrf
->info
, vty
);
6448 DEFUN (show_ip_mroute_summary_vrf_all
,
6449 show_ip_mroute_summary_vrf_all_cmd
,
6450 "show ip mroute vrf all summary",
6455 "Summary of all mroutes\n")
6459 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
6460 vty_out(vty
, "VRF: %s\n", vrf
->name
);
6461 show_mroute_summary(vrf
->info
, vty
);
6469 "show ip rib [vrf NAME] A.B.C.D",
6474 "Unicast address\n")
6477 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6478 struct in_addr addr
;
6479 const char *addr_str
;
6480 struct pim_nexthop nexthop
;
6481 char nexthop_addr_str
[PREFIX_STRLEN
];
6487 memset(&nexthop
, 0, sizeof(nexthop
));
6488 argv_find(argv
, argc
, "A.B.C.D", &idx
);
6489 addr_str
= argv
[idx
]->arg
;
6490 result
= inet_pton(AF_INET
, addr_str
, &addr
);
6492 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
6493 errno
, safe_strerror(errno
));
6497 if (!pim_nexthop_lookup(vrf
->info
, &nexthop
, addr
, 0)) {
6499 "Failure querying RIB nexthop for unicast address %s\n",
6505 "Address NextHop Interface Metric Preference\n");
6507 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
6508 nexthop_addr_str
, sizeof(nexthop_addr_str
));
6510 vty_out(vty
, "%-15s %-15s %-9s %6d %10d\n", addr_str
, nexthop_addr_str
,
6511 nexthop
.interface
? nexthop
.interface
->name
: "<ifname?>",
6512 nexthop
.mrib_route_metric
, nexthop
.mrib_metric_preference
);
6517 static void show_ssmpingd(struct pim_instance
*pim
, struct vty
*vty
)
6519 struct listnode
*node
;
6520 struct ssmpingd_sock
*ss
;
6524 "Source Socket Address Port Uptime Requests\n");
6526 if (!pim
->ssmpingd_list
)
6529 now
= pim_time_monotonic_sec();
6531 for (ALL_LIST_ELEMENTS_RO(pim
->ssmpingd_list
, node
, ss
)) {
6532 char source_str
[INET_ADDRSTRLEN
];
6534 struct sockaddr_in bind_addr
;
6535 socklen_t len
= sizeof(bind_addr
);
6536 char bind_addr_str
[INET_ADDRSTRLEN
];
6538 pim_inet4_dump("<src?>", ss
->source_addr
, source_str
,
6539 sizeof(source_str
));
6541 if (pim_socket_getsockname(
6542 ss
->sock_fd
, (struct sockaddr
*)&bind_addr
, &len
)) {
6544 "%% Failure reading socket name for ssmpingd source %s on fd=%d\n",
6545 source_str
, ss
->sock_fd
);
6548 pim_inet4_dump("<addr?>", bind_addr
.sin_addr
, bind_addr_str
,
6549 sizeof(bind_addr_str
));
6550 pim_time_uptime(ss_uptime
, sizeof(ss_uptime
),
6551 now
- ss
->creation
);
6553 vty_out(vty
, "%-15s %6d %-15s %5d %8s %8lld\n", source_str
,
6554 ss
->sock_fd
, bind_addr_str
, ntohs(bind_addr
.sin_port
),
6555 ss_uptime
, (long long)ss
->requests
);
6559 DEFUN (show_ip_ssmpingd
,
6560 show_ip_ssmpingd_cmd
,
6561 "show ip ssmpingd [vrf NAME]",
6568 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6573 show_ssmpingd(vrf
->info
, vty
);
6577 static int pim_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
6578 const char *rp
, const char *group
,
6583 result
= pim_rp_new_config(pim
, rp
, group
, plist
);
6585 if (result
== PIM_GROUP_BAD_ADDR_MASK_COMBO
) {
6586 vty_out(vty
, "%% Inconsistent address and mask: %s\n",
6588 return CMD_WARNING_CONFIG_FAILED
;
6591 if (result
== PIM_GROUP_BAD_ADDRESS
) {
6592 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
6593 return CMD_WARNING_CONFIG_FAILED
;
6596 if (result
== PIM_RP_BAD_ADDRESS
) {
6597 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
6598 return CMD_WARNING_CONFIG_FAILED
;
6601 if (result
== PIM_RP_NO_PATH
) {
6602 vty_out(vty
, "%% No Path to RP address specified: %s\n", rp
);
6606 if (result
== PIM_GROUP_OVERLAP
) {
6608 "%% Group range specified cannot exact match another\n");
6609 return CMD_WARNING_CONFIG_FAILED
;
6612 if (result
== PIM_GROUP_PFXLIST_OVERLAP
) {
6614 "%% This group is already covered by a RP prefix-list\n");
6615 return CMD_WARNING_CONFIG_FAILED
;
6618 if (result
== PIM_RP_PFXLIST_IN_USE
) {
6620 "%% The same prefix-list cannot be applied to multiple RPs\n");
6621 return CMD_WARNING_CONFIG_FAILED
;
6627 static int pim_cmd_spt_switchover(struct pim_instance
*pim
,
6628 enum pim_spt_switchover spt
,
6631 pim
->spt
.switchover
= spt
;
6633 switch (pim
->spt
.switchover
) {
6634 case PIM_SPT_IMMEDIATE
:
6635 XFREE(MTYPE_PIM_PLIST_NAME
, pim
->spt
.plist
);
6637 pim_upstream_add_lhr_star_pimreg(pim
);
6639 case PIM_SPT_INFINITY
:
6640 pim_upstream_remove_lhr_star_pimreg(pim
, plist
);
6642 XFREE(MTYPE_PIM_PLIST_NAME
, pim
->spt
.plist
);
6646 XSTRDUP(MTYPE_PIM_PLIST_NAME
, plist
);
6653 DEFUN (ip_pim_spt_switchover_infinity
,
6654 ip_pim_spt_switchover_infinity_cmd
,
6655 "ip pim spt-switchover infinity-and-beyond",
6659 "Never switch to SPT Tree\n")
6661 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6662 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, NULL
);
6665 DEFUN (ip_pim_spt_switchover_infinity_plist
,
6666 ip_pim_spt_switchover_infinity_plist_cmd
,
6667 "ip pim spt-switchover infinity-and-beyond prefix-list WORD",
6671 "Never switch to SPT Tree\n"
6672 "Prefix-List to control which groups to switch\n"
6673 "Prefix-List name\n")
6675 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6676 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, argv
[5]->arg
);
6679 DEFUN (no_ip_pim_spt_switchover_infinity
,
6680 no_ip_pim_spt_switchover_infinity_cmd
,
6681 "no ip pim spt-switchover infinity-and-beyond",
6686 "Never switch to SPT Tree\n")
6688 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6689 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
6692 DEFUN (no_ip_pim_spt_switchover_infinity_plist
,
6693 no_ip_pim_spt_switchover_infinity_plist_cmd
,
6694 "no ip pim spt-switchover infinity-and-beyond prefix-list WORD",
6699 "Never switch to SPT Tree\n"
6700 "Prefix-List to control which groups to switch\n"
6701 "Prefix-List name\n")
6703 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6704 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
6707 DEFPY (pim_register_accept_list
,
6708 pim_register_accept_list_cmd
,
6709 "[no] ip pim register-accept-list WORD$word",
6713 "Only accept registers from a specific source prefix list\n"
6714 "Prefix-List name\n")
6716 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6719 XFREE(MTYPE_PIM_PLIST_NAME
, pim
->register_plist
);
6721 XFREE(MTYPE_PIM_PLIST_NAME
, pim
->register_plist
);
6722 pim
->register_plist
= XSTRDUP(MTYPE_PIM_PLIST_NAME
, word
);
6727 DEFUN (ip_pim_joinprune_time
,
6728 ip_pim_joinprune_time_cmd
,
6729 "ip pim join-prune-interval (60-600)",
6731 "pim multicast routing\n"
6732 "Join Prune Send Interval\n"
6735 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6736 router
->t_periodic
= atoi(argv
[3]->arg
);
6740 DEFUN (no_ip_pim_joinprune_time
,
6741 no_ip_pim_joinprune_time_cmd
,
6742 "no ip pim join-prune-interval (60-600)",
6745 "pim multicast routing\n"
6746 "Join Prune Send Interval\n"
6749 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6750 router
->t_periodic
= PIM_DEFAULT_T_PERIODIC
;
6754 DEFUN (ip_pim_register_suppress
,
6755 ip_pim_register_suppress_cmd
,
6756 "ip pim register-suppress-time (5-60000)",
6758 "pim multicast routing\n"
6759 "Register Suppress Timer\n"
6762 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6763 router
->register_suppress_time
= atoi(argv
[3]->arg
);
6767 DEFUN (no_ip_pim_register_suppress
,
6768 no_ip_pim_register_suppress_cmd
,
6769 "no ip pim register-suppress-time (5-60000)",
6772 "pim multicast routing\n"
6773 "Register Suppress Timer\n"
6776 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6777 router
->register_suppress_time
= PIM_REGISTER_SUPPRESSION_TIME_DEFAULT
;
6781 DEFUN (ip_pim_rp_keep_alive
,
6782 ip_pim_rp_keep_alive_cmd
,
6783 "ip pim rp keep-alive-timer (31-60000)",
6785 "pim multicast routing\n"
6787 "Keep alive Timer\n"
6790 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6791 pim
->rp_keep_alive_time
= atoi(argv
[4]->arg
);
6795 DEFUN (no_ip_pim_rp_keep_alive
,
6796 no_ip_pim_rp_keep_alive_cmd
,
6797 "no ip pim rp keep-alive-timer (31-60000)",
6800 "pim multicast routing\n"
6802 "Keep alive Timer\n"
6805 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6806 pim
->rp_keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
6810 DEFUN (ip_pim_keep_alive
,
6811 ip_pim_keep_alive_cmd
,
6812 "ip pim keep-alive-timer (31-60000)",
6814 "pim multicast routing\n"
6815 "Keep alive Timer\n"
6818 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6819 pim
->keep_alive_time
= atoi(argv
[3]->arg
);
6823 DEFUN (no_ip_pim_keep_alive
,
6824 no_ip_pim_keep_alive_cmd
,
6825 "no ip pim keep-alive-timer (31-60000)",
6828 "pim multicast routing\n"
6829 "Keep alive Timer\n"
6832 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6833 pim
->keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
6837 DEFUN (ip_pim_packets
,
6839 "ip pim packets (1-100)",
6841 "pim multicast routing\n"
6842 "packets to process at one time per fd\n"
6843 "Number of packets\n")
6845 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6846 router
->packet_process
= atoi(argv
[3]->arg
);
6850 DEFUN (no_ip_pim_packets
,
6851 no_ip_pim_packets_cmd
,
6852 "no ip pim packets (1-100)",
6855 "pim multicast routing\n"
6856 "packets to process at one time per fd\n"
6857 "Number of packets\n")
6859 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6860 router
->packet_process
= PIM_DEFAULT_PACKET_PROCESS
;
6864 DEFUN (ip_pim_v6_secondary
,
6865 ip_pim_v6_secondary_cmd
,
6866 "ip pim send-v6-secondary",
6868 "pim multicast routing\n"
6869 "Send v6 secondary addresses\n")
6871 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6872 pim
->send_v6_secondary
= 1;
6877 DEFUN (no_ip_pim_v6_secondary
,
6878 no_ip_pim_v6_secondary_cmd
,
6879 "no ip pim send-v6-secondary",
6882 "pim multicast routing\n"
6883 "Send v6 secondary addresses\n")
6885 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6886 pim
->send_v6_secondary
= 0;
6893 "ip pim rp A.B.C.D [A.B.C.D/M]",
6895 "pim multicast routing\n"
6897 "ip address of RP\n"
6898 "Group Address range to cover\n")
6900 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6903 if (argc
== (idx_ipv4
+ 1))
6904 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
6907 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
6908 argv
[idx_ipv4
+ 1]->arg
, NULL
);
6911 DEFUN (ip_pim_rp_prefix_list
,
6912 ip_pim_rp_prefix_list_cmd
,
6913 "ip pim rp A.B.C.D prefix-list WORD",
6915 "pim multicast routing\n"
6917 "ip address of RP\n"
6918 "group prefix-list filter\n"
6919 "Name of a prefix-list\n")
6921 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6922 return pim_rp_cmd_worker(pim
, vty
, argv
[3]->arg
, NULL
, argv
[5]->arg
);
6925 static int pim_no_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
6926 const char *rp
, const char *group
,
6929 int result
= pim_rp_del_config(pim
, rp
, group
, plist
);
6931 if (result
== PIM_GROUP_BAD_ADDRESS
) {
6932 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
6933 return CMD_WARNING_CONFIG_FAILED
;
6936 if (result
== PIM_RP_BAD_ADDRESS
) {
6937 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
6938 return CMD_WARNING_CONFIG_FAILED
;
6941 if (result
== PIM_RP_NOT_FOUND
) {
6942 vty_out(vty
, "%% Unable to find specified RP\n");
6943 return CMD_WARNING_CONFIG_FAILED
;
6949 DEFUN (no_ip_pim_rp
,
6951 "no ip pim rp A.B.C.D [A.B.C.D/M]",
6954 "pim multicast routing\n"
6956 "ip address of RP\n"
6957 "Group Address range to cover\n")
6959 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6960 int idx_ipv4
= 4, idx_group
= 0;
6962 if (argv_find(argv
, argc
, "A.B.C.D/M", &idx_group
))
6963 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
6964 argv
[idx_group
]->arg
, NULL
);
6966 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
6970 DEFUN (no_ip_pim_rp_prefix_list
,
6971 no_ip_pim_rp_prefix_list_cmd
,
6972 "no ip pim rp A.B.C.D prefix-list WORD",
6975 "pim multicast routing\n"
6977 "ip address of RP\n"
6978 "group prefix-list filter\n"
6979 "Name of a prefix-list\n")
6981 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6982 return pim_no_rp_cmd_worker(pim
, vty
, argv
[4]->arg
, NULL
, argv
[6]->arg
);
6985 static int pim_ssm_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
6988 int result
= pim_ssm_range_set(pim
, pim
->vrf_id
, plist
);
6989 int ret
= CMD_WARNING_CONFIG_FAILED
;
6991 if (result
== PIM_SSM_ERR_NONE
)
6995 case PIM_SSM_ERR_NO_VRF
:
6996 vty_out(vty
, "%% VRF doesn't exist\n");
6998 case PIM_SSM_ERR_DUP
:
6999 vty_out(vty
, "%% duplicate config\n");
7003 vty_out(vty
, "%% ssm range config failed\n");
7009 DEFUN (ip_pim_ssm_prefix_list
,
7010 ip_pim_ssm_prefix_list_cmd
,
7011 "ip pim ssm prefix-list WORD",
7013 "pim multicast routing\n"
7014 "Source Specific Multicast\n"
7015 "group range prefix-list filter\n"
7016 "Name of a prefix-list\n")
7018 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7019 return pim_ssm_cmd_worker(pim
, vty
, argv
[4]->arg
);
7022 DEFUN (no_ip_pim_ssm_prefix_list
,
7023 no_ip_pim_ssm_prefix_list_cmd
,
7024 "no ip pim ssm prefix-list",
7027 "pim multicast routing\n"
7028 "Source Specific Multicast\n"
7029 "group range prefix-list filter\n")
7031 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7032 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
7035 DEFUN (no_ip_pim_ssm_prefix_list_name
,
7036 no_ip_pim_ssm_prefix_list_name_cmd
,
7037 "no ip pim ssm prefix-list WORD",
7040 "pim multicast routing\n"
7041 "Source Specific Multicast\n"
7042 "group range prefix-list filter\n"
7043 "Name of a prefix-list\n")
7045 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7046 struct pim_ssm
*ssm
= pim
->ssm_info
;
7048 if (ssm
->plist_name
&& !strcmp(ssm
->plist_name
, argv
[5]->arg
))
7049 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
7051 vty_out(vty
, "%% pim ssm prefix-list %s doesn't exist\n", argv
[5]->arg
);
7053 return CMD_WARNING_CONFIG_FAILED
;
7056 static void ip_pim_ssm_show_group_range(struct pim_instance
*pim
,
7057 struct vty
*vty
, bool uj
)
7059 struct pim_ssm
*ssm
= pim
->ssm_info
;
7060 const char *range_str
=
7061 ssm
->plist_name
? ssm
->plist_name
: PIM_SSM_STANDARD_RANGE
;
7065 json
= json_object_new_object();
7066 json_object_string_add(json
, "ssmGroups", range_str
);
7067 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
7068 json
, JSON_C_TO_STRING_PRETTY
));
7069 json_object_free(json
);
7071 vty_out(vty
, "SSM group range : %s\n", range_str
);
7074 DEFUN (show_ip_pim_ssm_range
,
7075 show_ip_pim_ssm_range_cmd
,
7076 "show ip pim [vrf NAME] group-type [json]",
7085 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
7086 bool uj
= use_json(argc
, argv
);
7091 ip_pim_ssm_show_group_range(vrf
->info
, vty
, uj
);
7096 static void ip_pim_ssm_show_group_type(struct pim_instance
*pim
,
7097 struct vty
*vty
, bool uj
,
7100 struct in_addr group_addr
;
7101 const char *type_str
;
7104 result
= inet_pton(AF_INET
, group
, &group_addr
);
7106 type_str
= "invalid";
7108 if (pim_is_group_224_4(group_addr
))
7110 pim_is_grp_ssm(pim
, group_addr
) ? "SSM" : "ASM";
7112 type_str
= "not-multicast";
7117 json
= json_object_new_object();
7118 json_object_string_add(json
, "groupType", type_str
);
7119 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
7120 json
, JSON_C_TO_STRING_PRETTY
));
7121 json_object_free(json
);
7123 vty_out(vty
, "Group type : %s\n", type_str
);
7126 DEFUN (show_ip_pim_group_type
,
7127 show_ip_pim_group_type_cmd
,
7128 "show ip pim [vrf NAME] group-type A.B.C.D [json]",
7133 "multicast group type\n"
7138 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
7139 bool uj
= use_json(argc
, argv
);
7144 argv_find(argv
, argc
, "A.B.C.D", &idx
);
7145 ip_pim_ssm_show_group_type(vrf
->info
, vty
, uj
, argv
[idx
]->arg
);
7150 DEFUN (show_ip_pim_bsr
,
7151 show_ip_pim_bsr_cmd
,
7152 "show ip pim bsr [json]",
7156 "boot-strap router information\n"
7160 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
7161 bool uj
= use_json(argc
, argv
);
7166 pim_show_bsr(vrf
->info
, vty
, uj
);
7173 "ip ssmpingd [A.B.C.D]",
7178 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7181 struct in_addr source_addr
;
7182 const char *source_str
= (argc
== 3) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
7184 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
7186 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
7187 source_str
, errno
, safe_strerror(errno
));
7188 return CMD_WARNING_CONFIG_FAILED
;
7191 result
= pim_ssmpingd_start(pim
, source_addr
);
7193 vty_out(vty
, "%% Failure starting ssmpingd for source %s: %d\n",
7194 source_str
, result
);
7195 return CMD_WARNING_CONFIG_FAILED
;
7201 DEFUN (no_ip_ssmpingd
,
7203 "no ip ssmpingd [A.B.C.D]",
7209 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7212 struct in_addr source_addr
;
7213 const char *source_str
= (argc
== 4) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
7215 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
7217 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
7218 source_str
, errno
, safe_strerror(errno
));
7219 return CMD_WARNING_CONFIG_FAILED
;
7222 result
= pim_ssmpingd_stop(pim
, source_addr
);
7224 vty_out(vty
, "%% Failure stopping ssmpingd for source %s: %d\n",
7225 source_str
, result
);
7226 return CMD_WARNING_CONFIG_FAILED
;
7236 "pim multicast routing\n"
7237 "Enable PIM ECMP \n")
7239 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7240 pim
->ecmp_enable
= true;
7245 DEFUN (no_ip_pim_ecmp
,
7250 "pim multicast routing\n"
7251 "Disable PIM ECMP \n")
7253 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7254 pim
->ecmp_enable
= false;
7259 DEFUN (ip_pim_ecmp_rebalance
,
7260 ip_pim_ecmp_rebalance_cmd
,
7261 "ip pim ecmp rebalance",
7263 "pim multicast routing\n"
7264 "Enable PIM ECMP \n"
7265 "Enable PIM ECMP Rebalance\n")
7267 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7268 pim
->ecmp_enable
= true;
7269 pim
->ecmp_rebalance_enable
= true;
7274 DEFUN (no_ip_pim_ecmp_rebalance
,
7275 no_ip_pim_ecmp_rebalance_cmd
,
7276 "no ip pim ecmp rebalance",
7279 "pim multicast routing\n"
7280 "Disable PIM ECMP \n"
7281 "Disable PIM ECMP Rebalance\n")
7283 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7284 pim
->ecmp_rebalance_enable
= false;
7289 static int pim_cmd_igmp_start(struct vty
*vty
, struct interface
*ifp
)
7291 struct pim_interface
*pim_ifp
;
7292 struct pim_instance
*pim
;
7293 uint8_t need_startup
= 0;
7295 pim_ifp
= ifp
->info
;
7298 pim
= pim_get_pim_instance(ifp
->vrf_id
);
7299 /* Limit mcast interfaces to number of vifs available */
7300 if (pim
->mcast_if_count
== MAXVIFS
) {
7302 "Max multicast interfaces(%d) Reached. Could not enable IGMP on interface %s\n",
7303 MAXVIFS
, ifp
->name
);
7304 return CMD_WARNING_CONFIG_FAILED
;
7306 (void)pim_if_new(ifp
, true, false, false, false);
7309 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
7310 PIM_IF_DO_IGMP(pim_ifp
->options
);
7315 /* 'ip igmp' executed multiple times, with need_startup
7316 avoid multiple if add all and membership refresh */
7318 pim_if_addr_add_all(ifp
);
7319 pim_if_membership_refresh(ifp
);
7325 DEFUN (interface_ip_igmp
,
7326 interface_ip_igmp_cmd
,
7331 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7333 return pim_cmd_igmp_start(vty
, ifp
);
7336 DEFUN (interface_no_ip_igmp
,
7337 interface_no_ip_igmp_cmd
,
7343 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7344 struct pim_interface
*pim_ifp
= ifp
->info
;
7349 PIM_IF_DONT_IGMP(pim_ifp
->options
);
7351 pim_if_membership_clear(ifp
);
7353 pim_if_addr_del_all_igmp(ifp
);
7355 if (!PIM_IF_TEST_PIM(pim_ifp
->options
)) {
7362 DEFUN (interface_ip_igmp_join
,
7363 interface_ip_igmp_join_cmd
,
7364 "ip igmp join A.B.C.D [A.B.C.D]",
7367 "IGMP join multicast group\n"
7368 "Multicast group address\n"
7371 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7374 const char *group_str
;
7375 const char *source_str
;
7376 struct in_addr group_addr
;
7377 struct in_addr source_addr
;
7381 group_str
= argv
[idx_ipv4
]->arg
;
7382 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
7384 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
7385 errno
, safe_strerror(errno
));
7386 return CMD_WARNING_CONFIG_FAILED
;
7389 /* Source address */
7390 if (argc
== (idx_ipv4_2
+ 1)) {
7391 source_str
= argv
[idx_ipv4_2
]->arg
;
7392 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
7394 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
7395 source_str
, errno
, safe_strerror(errno
));
7396 return CMD_WARNING_CONFIG_FAILED
;
7398 /* Reject 0.0.0.0. Reserved for any source. */
7399 if (source_addr
.s_addr
== INADDR_ANY
) {
7400 vty_out(vty
, "Bad source address %s\n", source_str
);
7401 return CMD_WARNING_CONFIG_FAILED
;
7404 source_addr
.s_addr
= INADDR_ANY
;
7407 CMD_FERR_RETURN(pim_if_igmp_join_add(ifp
, group_addr
, source_addr
),
7408 "Failure joining IGMP group: $ERR");
7413 DEFUN (interface_no_ip_igmp_join
,
7414 interface_no_ip_igmp_join_cmd
,
7415 "no ip igmp join A.B.C.D [A.B.C.D]",
7419 "IGMP join multicast group\n"
7420 "Multicast group address\n"
7423 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7426 const char *group_str
;
7427 const char *source_str
;
7428 struct in_addr group_addr
;
7429 struct in_addr source_addr
;
7433 group_str
= argv
[idx_ipv4
]->arg
;
7434 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
7436 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
7437 errno
, safe_strerror(errno
));
7438 return CMD_WARNING_CONFIG_FAILED
;
7441 /* Source address */
7442 if (argc
== (idx_ipv4_2
+ 1)) {
7443 source_str
= argv
[idx_ipv4_2
]->arg
;
7444 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
7446 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
7447 source_str
, errno
, safe_strerror(errno
));
7448 return CMD_WARNING_CONFIG_FAILED
;
7450 /* Reject 0.0.0.0. Reserved for any source. */
7451 if (source_addr
.s_addr
== INADDR_ANY
) {
7452 vty_out(vty
, "Bad source address %s\n", source_str
);
7453 return CMD_WARNING_CONFIG_FAILED
;
7457 source_addr
.s_addr
= INADDR_ANY
;
7460 result
= pim_if_igmp_join_del(ifp
, group_addr
, source_addr
);
7463 "%% Failure leaving IGMP group %s source %s on interface %s: %d\n",
7464 group_str
, source_str
, ifp
->name
, result
);
7465 return CMD_WARNING_CONFIG_FAILED
;
7472 CLI reconfiguration affects the interface level (struct pim_interface).
7473 This function propagates the reconfiguration to every active socket
7476 static void igmp_sock_query_interval_reconfig(struct igmp_sock
*igmp
)
7478 struct interface
*ifp
;
7479 struct pim_interface
*pim_ifp
;
7483 /* other querier present? */
7485 if (igmp
->t_other_querier_timer
)
7488 /* this is the querier */
7490 zassert(igmp
->interface
);
7491 zassert(igmp
->interface
->info
);
7493 ifp
= igmp
->interface
;
7494 pim_ifp
= ifp
->info
;
7496 if (PIM_DEBUG_IGMP_TRACE
) {
7497 char ifaddr_str
[INET_ADDRSTRLEN
];
7498 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
7499 sizeof(ifaddr_str
));
7500 zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
7501 __func__
, ifaddr_str
, ifp
->name
,
7502 pim_ifp
->igmp_default_query_interval
);
7506 igmp_startup_mode_on() will reset QQI:
7508 igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
7510 igmp_startup_mode_on(igmp
);
7513 static void igmp_sock_query_reschedule(struct igmp_sock
*igmp
)
7515 if (igmp
->mtrace_only
)
7518 if (igmp
->t_igmp_query_timer
) {
7519 /* other querier present */
7520 zassert(igmp
->t_igmp_query_timer
);
7521 zassert(!igmp
->t_other_querier_timer
);
7523 pim_igmp_general_query_off(igmp
);
7524 pim_igmp_general_query_on(igmp
);
7526 zassert(igmp
->t_igmp_query_timer
);
7527 zassert(!igmp
->t_other_querier_timer
);
7529 /* this is the querier */
7531 zassert(!igmp
->t_igmp_query_timer
);
7532 zassert(igmp
->t_other_querier_timer
);
7534 pim_igmp_other_querier_timer_off(igmp
);
7535 pim_igmp_other_querier_timer_on(igmp
);
7537 zassert(!igmp
->t_igmp_query_timer
);
7538 zassert(igmp
->t_other_querier_timer
);
7542 static void change_query_interval(struct pim_interface
*pim_ifp
,
7545 struct listnode
*sock_node
;
7546 struct igmp_sock
*igmp
;
7548 pim_ifp
->igmp_default_query_interval
= query_interval
;
7550 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
7551 igmp_sock_query_interval_reconfig(igmp
);
7552 igmp_sock_query_reschedule(igmp
);
7556 static void change_query_max_response_time(struct pim_interface
*pim_ifp
,
7557 int query_max_response_time_dsec
)
7559 struct listnode
*sock_node
;
7560 struct igmp_sock
*igmp
;
7562 pim_ifp
->igmp_query_max_response_time_dsec
=
7563 query_max_response_time_dsec
;
7566 Below we modify socket/group/source timers in order to quickly
7567 reflect the change. Otherwise, those timers would eventually catch
7571 /* scan all sockets */
7572 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
7573 struct listnode
*grp_node
;
7574 struct igmp_group
*grp
;
7576 /* reschedule socket general query */
7577 igmp_sock_query_reschedule(igmp
);
7579 /* scan socket groups */
7580 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grp_node
,
7582 struct listnode
*src_node
;
7583 struct igmp_source
*src
;
7585 /* reset group timers for groups in EXCLUDE mode */
7586 if (grp
->group_filtermode_isexcl
) {
7587 igmp_group_reset_gmi(grp
);
7590 /* scan group sources */
7591 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
,
7594 /* reset source timers for sources with running
7596 if (src
->t_source_timer
) {
7597 igmp_source_reset_gmi(igmp
, grp
, src
);
7604 #define IGMP_QUERY_INTERVAL_MIN (1)
7605 #define IGMP_QUERY_INTERVAL_MAX (1800)
7607 DEFUN (interface_ip_igmp_query_interval
,
7608 interface_ip_igmp_query_interval_cmd
,
7609 "ip igmp query-interval (1-1800)",
7612 IFACE_IGMP_QUERY_INTERVAL_STR
7613 "Query interval in seconds\n")
7615 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7616 struct pim_interface
*pim_ifp
= ifp
->info
;
7618 int query_interval_dsec
;
7622 ret
= pim_cmd_igmp_start(vty
, ifp
);
7623 if (ret
!= CMD_SUCCESS
)
7625 pim_ifp
= ifp
->info
;
7628 query_interval
= atoi(argv
[3]->arg
);
7629 query_interval_dsec
= 10 * query_interval
;
7632 It seems we don't need to check bounds since command.c does it
7633 already, but we verify them anyway for extra safety.
7635 if (query_interval
< IGMP_QUERY_INTERVAL_MIN
) {
7637 "General query interval %d lower than minimum %d\n",
7638 query_interval
, IGMP_QUERY_INTERVAL_MIN
);
7639 return CMD_WARNING_CONFIG_FAILED
;
7641 if (query_interval
> IGMP_QUERY_INTERVAL_MAX
) {
7643 "General query interval %d higher than maximum %d\n",
7644 query_interval
, IGMP_QUERY_INTERVAL_MAX
);
7645 return CMD_WARNING_CONFIG_FAILED
;
7648 if (query_interval_dsec
<= pim_ifp
->igmp_query_max_response_time_dsec
) {
7650 "Can't set general query interval %d dsec <= query max response time %d dsec.\n",
7651 query_interval_dsec
,
7652 pim_ifp
->igmp_query_max_response_time_dsec
);
7653 return CMD_WARNING_CONFIG_FAILED
;
7656 change_query_interval(pim_ifp
, query_interval
);
7661 DEFUN (interface_no_ip_igmp_query_interval
,
7662 interface_no_ip_igmp_query_interval_cmd
,
7663 "no ip igmp query-interval",
7667 IFACE_IGMP_QUERY_INTERVAL_STR
)
7669 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7670 struct pim_interface
*pim_ifp
= ifp
->info
;
7671 int default_query_interval_dsec
;
7676 default_query_interval_dsec
= IGMP_GENERAL_QUERY_INTERVAL
* 10;
7678 if (default_query_interval_dsec
7679 <= pim_ifp
->igmp_query_max_response_time_dsec
) {
7681 "Can't set default general query interval %d dsec <= query max response time %d dsec.\n",
7682 default_query_interval_dsec
,
7683 pim_ifp
->igmp_query_max_response_time_dsec
);
7684 return CMD_WARNING_CONFIG_FAILED
;
7687 change_query_interval(pim_ifp
, IGMP_GENERAL_QUERY_INTERVAL
);
7692 DEFUN (interface_ip_igmp_version
,
7693 interface_ip_igmp_version_cmd
,
7694 "ip igmp version (2-3)",
7698 "IGMP version number\n")
7700 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7701 struct pim_interface
*pim_ifp
= ifp
->info
;
7702 int igmp_version
, old_version
= 0;
7706 ret
= pim_cmd_igmp_start(vty
, ifp
);
7707 if (ret
!= CMD_SUCCESS
)
7709 pim_ifp
= ifp
->info
;
7712 igmp_version
= atoi(argv
[3]->arg
);
7713 old_version
= pim_ifp
->igmp_version
;
7714 pim_ifp
->igmp_version
= igmp_version
;
7716 // Check if IGMP is Enabled otherwise, enable on interface
7717 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
7718 PIM_IF_DO_IGMP(pim_ifp
->options
);
7719 pim_if_addr_add_all(ifp
);
7720 pim_if_membership_refresh(ifp
);
7721 old_version
= igmp_version
;
7722 // avoid refreshing membership again.
7724 /* Current and new version is different refresh existing
7725 membership. Going from 3 -> 2 or 2 -> 3. */
7726 if (old_version
!= igmp_version
)
7727 pim_if_membership_refresh(ifp
);
7732 DEFUN (interface_no_ip_igmp_version
,
7733 interface_no_ip_igmp_version_cmd
,
7734 "no ip igmp version (2-3)",
7739 "IGMP version number\n")
7741 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7742 struct pim_interface
*pim_ifp
= ifp
->info
;
7747 pim_ifp
->igmp_version
= IGMP_DEFAULT_VERSION
;
7752 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
7753 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
7755 DEFUN (interface_ip_igmp_query_max_response_time
,
7756 interface_ip_igmp_query_max_response_time_cmd
,
7757 "ip igmp query-max-response-time (10-250)",
7760 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
7761 "Query response value in deci-seconds\n")
7763 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7764 struct pim_interface
*pim_ifp
= ifp
->info
;
7765 int query_max_response_time
;
7769 ret
= pim_cmd_igmp_start(vty
, ifp
);
7770 if (ret
!= CMD_SUCCESS
)
7772 pim_ifp
= ifp
->info
;
7775 query_max_response_time
= atoi(argv
[3]->arg
);
7777 if (query_max_response_time
7778 >= pim_ifp
->igmp_default_query_interval
* 10) {
7780 "Can't set query max response time %d sec >= general query interval %d sec\n",
7781 query_max_response_time
,
7782 pim_ifp
->igmp_default_query_interval
);
7783 return CMD_WARNING_CONFIG_FAILED
;
7786 change_query_max_response_time(pim_ifp
, query_max_response_time
);
7791 DEFUN (interface_no_ip_igmp_query_max_response_time
,
7792 interface_no_ip_igmp_query_max_response_time_cmd
,
7793 "no ip igmp query-max-response-time (10-250)",
7797 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
7798 "Time for response in deci-seconds\n")
7800 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7801 struct pim_interface
*pim_ifp
= ifp
->info
;
7806 change_query_max_response_time(pim_ifp
,
7807 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
7812 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
7813 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
7815 DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec
,
7816 interface_ip_igmp_query_max_response_time_dsec_cmd
,
7817 "ip igmp query-max-response-time-dsec (10-250)",
7820 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
7821 "Query response value in deciseconds\n")
7823 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7824 struct pim_interface
*pim_ifp
= ifp
->info
;
7825 int query_max_response_time_dsec
;
7826 int default_query_interval_dsec
;
7830 ret
= pim_cmd_igmp_start(vty
, ifp
);
7831 if (ret
!= CMD_SUCCESS
)
7833 pim_ifp
= ifp
->info
;
7836 query_max_response_time_dsec
= atoi(argv
[4]->arg
);
7838 default_query_interval_dsec
= 10 * pim_ifp
->igmp_default_query_interval
;
7840 if (query_max_response_time_dsec
>= default_query_interval_dsec
) {
7842 "Can't set query max response time %d dsec >= general query interval %d dsec\n",
7843 query_max_response_time_dsec
,
7844 default_query_interval_dsec
);
7845 return CMD_WARNING_CONFIG_FAILED
;
7848 change_query_max_response_time(pim_ifp
, query_max_response_time_dsec
);
7853 DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec
,
7854 interface_no_ip_igmp_query_max_response_time_dsec_cmd
,
7855 "no ip igmp query-max-response-time-dsec",
7859 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
)
7861 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7862 struct pim_interface
*pim_ifp
= ifp
->info
;
7867 change_query_max_response_time(pim_ifp
,
7868 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
7873 #define IGMP_LAST_MEMBER_QUERY_COUNT_MIN (1)
7874 #define IGMP_LAST_MEMBER_QUERY_COUNT_MAX (7)
7876 DEFUN (interface_ip_igmp_last_member_query_count
,
7877 interface_ip_igmp_last_member_query_count_cmd
,
7878 "ip igmp last-member-query-count (1-7)",
7881 IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR
7882 "Last member query count\n")
7884 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7885 struct pim_interface
*pim_ifp
= ifp
->info
;
7886 int last_member_query_count
;
7890 ret
= pim_cmd_igmp_start(vty
, ifp
);
7891 if (ret
!= CMD_SUCCESS
)
7893 pim_ifp
= ifp
->info
;
7896 last_member_query_count
= atoi(argv
[3]->arg
);
7898 pim_ifp
->igmp_last_member_query_count
= last_member_query_count
;
7903 DEFUN (interface_no_ip_igmp_last_member_query_count
,
7904 interface_no_ip_igmp_last_member_query_count_cmd
,
7905 "no ip igmp last-member-query-count",
7909 IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR
)
7911 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7912 struct pim_interface
*pim_ifp
= ifp
->info
;
7917 pim_ifp
->igmp_last_member_query_count
=
7918 IGMP_DEFAULT_ROBUSTNESS_VARIABLE
;
7923 #define IGMP_LAST_MEMBER_QUERY_INTERVAL_MIN (1)
7924 #define IGMP_LAST_MEMBER_QUERY_INTERVAL_MAX (255)
7926 DEFUN (interface_ip_igmp_last_member_query_interval
,
7927 interface_ip_igmp_last_member_query_interval_cmd
,
7928 "ip igmp last-member-query-interval (1-255)",
7931 IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR
7932 "Last member query interval in deciseconds\n")
7934 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7935 struct pim_interface
*pim_ifp
= ifp
->info
;
7936 int last_member_query_interval
;
7940 ret
= pim_cmd_igmp_start(vty
, ifp
);
7941 if (ret
!= CMD_SUCCESS
)
7943 pim_ifp
= ifp
->info
;
7946 last_member_query_interval
= atoi(argv
[3]->arg
);
7947 pim_ifp
->igmp_specific_query_max_response_time_dsec
7948 = last_member_query_interval
;
7953 DEFUN (interface_no_ip_igmp_last_member_query_interval
,
7954 interface_no_ip_igmp_last_member_query_interval_cmd
,
7955 "no ip igmp last-member-query-interval",
7959 IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR
)
7961 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7962 struct pim_interface
*pim_ifp
= ifp
->info
;
7967 pim_ifp
->igmp_specific_query_max_response_time_dsec
=
7968 IGMP_SPECIFIC_QUERY_MAX_RESPONSE_TIME_DSEC
;
7973 DEFUN (interface_ip_pim_drprio
,
7974 interface_ip_pim_drprio_cmd
,
7975 "ip pim drpriority (1-4294967295)",
7978 "Set the Designated Router Election Priority\n"
7979 "Value of the new DR Priority\n")
7981 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7983 struct pim_interface
*pim_ifp
= ifp
->info
;
7984 uint32_t old_dr_prio
;
7987 vty_out(vty
, "Please enable PIM on interface, first\n");
7988 return CMD_WARNING_CONFIG_FAILED
;
7991 old_dr_prio
= pim_ifp
->pim_dr_priority
;
7993 pim_ifp
->pim_dr_priority
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
7995 if (old_dr_prio
!= pim_ifp
->pim_dr_priority
) {
7996 pim_if_dr_election(ifp
);
7997 pim_hello_restart_now(ifp
);
8003 DEFUN (interface_no_ip_pim_drprio
,
8004 interface_no_ip_pim_drprio_cmd
,
8005 "no ip pim drpriority [(1-4294967295)]",
8009 "Revert the Designated Router Priority to default\n"
8010 "Old Value of the Priority\n")
8012 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8013 struct pim_interface
*pim_ifp
= ifp
->info
;
8016 vty_out(vty
, "Pim not enabled on this interface\n");
8017 return CMD_WARNING_CONFIG_FAILED
;
8020 if (pim_ifp
->pim_dr_priority
!= PIM_DEFAULT_DR_PRIORITY
) {
8021 pim_ifp
->pim_dr_priority
= PIM_DEFAULT_DR_PRIORITY
;
8022 pim_if_dr_election(ifp
);
8023 pim_hello_restart_now(ifp
);
8029 DEFPY_HIDDEN (interface_ip_igmp_query_generate
,
8030 interface_ip_igmp_query_generate_cmd
,
8031 "ip igmp generate-query-once [version (2-3)]",
8034 "Generate igmp general query once\n"
8036 "IGMP version number\n")
8038 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8039 int igmp_version
= 2;
8042 vty_out(vty
, "IGMP/PIM is not enabled on the interface %s\n",
8044 return CMD_WARNING_CONFIG_FAILED
;
8048 igmp_version
= atoi(argv
[4]->arg
);
8050 igmp_send_query_on_intf(ifp
, igmp_version
);
8055 static int pim_cmd_interface_add(struct vty
*vty
, struct interface
*ifp
)
8057 struct pim_interface
*pim_ifp
= ifp
->info
;
8058 struct pim_instance
*pim
;
8061 pim
= pim_get_pim_instance(ifp
->vrf_id
);
8062 /* Limiting mcast interfaces to number of VIFs */
8063 if (pim
->mcast_if_count
== MAXVIFS
) {
8064 vty_out(vty
, "Max multicast interfaces(%d) reached.",
8068 pim_ifp
= pim_if_new(ifp
, false, true, false, false);
8070 PIM_IF_DO_PIM(pim_ifp
->options
);
8072 pim_if_addr_add_all(ifp
);
8073 pim_if_membership_refresh(ifp
);
8075 pim_if_create_pimreg(pim_ifp
->pim
);
8079 DEFPY_HIDDEN (pim_test_sg_keepalive
,
8080 pim_test_sg_keepalive_cmd
,
8081 "test pim [vrf NAME$name] keepalive-reset A.B.C.D$source A.B.C.D$group",
8085 "Reset the Keepalive Timer\n"
8086 "The Source we are resetting\n"
8087 "The Group we are resetting\n")
8089 struct pim_upstream
*up
;
8090 struct pim_instance
*pim
;
8091 struct prefix_sg sg
;
8097 pim
= pim_get_pim_instance(VRF_DEFAULT
);
8099 struct vrf
*vrf
= vrf_lookup_by_name(name
);
8102 vty_out(vty
, "%% Vrf specified: %s does not exist\n",
8107 pim
= pim_get_pim_instance(vrf
->vrf_id
);
8111 vty_out(vty
, "%% Unable to find pim instance\n");
8115 up
= pim_upstream_find(pim
, &sg
);
8117 vty_out(vty
, "%% Unable to find %s specified\n",
8118 pim_str_sg_dump(&sg
));
8122 vty_out(vty
, "Setting %s to current keep alive time: %d\n",
8123 pim_str_sg_dump(&sg
), pim
->keep_alive_time
);
8124 pim_upstream_keep_alive_timer_start(up
, pim
->keep_alive_time
);
8129 DEFPY (interface_ip_pim_activeactive
,
8130 interface_ip_pim_activeactive_cmd
,
8131 "[no$no] ip pim active-active",
8135 "Mark interface as Active-Active for MLAG operations, Hidden because not finished yet\n")
8137 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8138 struct pim_interface
*pim_ifp
;
8140 if (!no
&& !pim_cmd_interface_add(vty
, ifp
)) {
8142 "Could not enable PIM SM active-active on interface %s\n",
8144 return CMD_WARNING_CONFIG_FAILED
;
8149 zlog_debug("%sConfiguring PIM active-active on Interface: %s",
8150 no
? "Un-" : " ", ifp
->name
);
8152 pim_ifp
= ifp
->info
;
8154 pim_if_unconfigure_mlag_dualactive(pim_ifp
);
8156 pim_if_configure_mlag_dualactive(pim_ifp
);
8161 DEFUN_HIDDEN (interface_ip_pim_ssm
,
8162 interface_ip_pim_ssm_cmd
,
8168 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8170 if (!pim_cmd_interface_add(vty
, ifp
)) {
8171 vty_out(vty
, "Could not enable PIM SM on interface %s\n",
8173 return CMD_WARNING_CONFIG_FAILED
;
8177 "WARN: Enabled PIM SM on interface; configure PIM SSM "
8178 "range if needed\n");
8182 static int interface_ip_pim_helper(struct vty
*vty
)
8184 struct pim_interface
*pim_ifp
;
8186 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8188 if (!pim_cmd_interface_add(vty
, ifp
)) {
8189 vty_out(vty
, "Could not enable PIM SM on interface %s\n",
8191 return CMD_WARNING_CONFIG_FAILED
;
8194 pim_ifp
= ifp
->info
;
8196 pim_if_create_pimreg(pim_ifp
->pim
);
8201 DEFUN_HIDDEN (interface_ip_pim_sm
,
8202 interface_ip_pim_sm_cmd
,
8208 return interface_ip_pim_helper(vty
);
8211 DEFUN (interface_ip_pim
,
8212 interface_ip_pim_cmd
,
8217 return interface_ip_pim_helper(vty
);
8220 static int pim_cmd_interface_delete(struct interface
*ifp
)
8222 struct pim_interface
*pim_ifp
= ifp
->info
;
8227 PIM_IF_DONT_PIM(pim_ifp
->options
);
8229 pim_if_membership_clear(ifp
);
8232 pim_sock_delete() removes all neighbors from
8233 pim_ifp->pim_neighbor_list.
8235 pim_sock_delete(ifp
, "pim unconfigured on interface");
8237 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
8238 pim_if_addr_del_all(ifp
);
8245 static int interface_no_ip_pim_helper(struct vty
*vty
)
8247 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8248 if (!pim_cmd_interface_delete(ifp
)) {
8249 vty_out(vty
, "Unable to delete interface information\n");
8250 return CMD_WARNING_CONFIG_FAILED
;
8256 DEFUN_HIDDEN (interface_no_ip_pim_ssm
,
8257 interface_no_ip_pim_ssm_cmd
,
8264 return interface_no_ip_pim_helper(vty
);
8267 DEFUN_HIDDEN (interface_no_ip_pim_sm
,
8268 interface_no_ip_pim_sm_cmd
,
8275 return interface_no_ip_pim_helper(vty
);
8278 DEFUN (interface_no_ip_pim
,
8279 interface_no_ip_pim_cmd
,
8285 return interface_no_ip_pim_helper(vty
);
8289 DEFUN(interface_ip_pim_boundary_oil
,
8290 interface_ip_pim_boundary_oil_cmd
,
8291 "ip multicast boundary oil WORD",
8293 "Generic multicast configuration options\n"
8294 "Define multicast boundary\n"
8295 "Filter OIL by group using prefix list\n"
8296 "Prefix list to filter OIL with\n")
8298 VTY_DECLVAR_CONTEXT(interface
, iif
);
8299 struct pim_interface
*pim_ifp
;
8302 argv_find(argv
, argc
, "WORD", &idx
);
8304 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
8306 if (pim_ifp
->boundary_oil_plist
)
8307 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
8309 pim_ifp
->boundary_oil_plist
=
8310 XSTRDUP(MTYPE_PIM_INTERFACE
, argv
[idx
]->arg
);
8312 /* Interface will be pruned from OIL on next Join */
8316 DEFUN(interface_no_ip_pim_boundary_oil
,
8317 interface_no_ip_pim_boundary_oil_cmd
,
8318 "no ip multicast boundary oil [WORD]",
8321 "Generic multicast configuration options\n"
8322 "Define multicast boundary\n"
8323 "Filter OIL by group using prefix list\n"
8324 "Prefix list to filter OIL with\n")
8326 VTY_DECLVAR_CONTEXT(interface
, iif
);
8327 struct pim_interface
*pim_ifp
;
8330 argv_find(argv
, argc
, "WORD", &idx
);
8332 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
8334 if (pim_ifp
->boundary_oil_plist
)
8335 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
8340 DEFUN (interface_ip_mroute
,
8341 interface_ip_mroute_cmd
,
8342 "ip mroute INTERFACE A.B.C.D [A.B.C.D]",
8344 "Add multicast route\n"
8345 "Outgoing interface name\n"
8349 VTY_DECLVAR_CONTEXT(interface
, iif
);
8350 struct pim_interface
*pim_ifp
;
8351 struct pim_instance
*pim
;
8352 int idx_interface
= 2;
8354 struct interface
*oif
;
8355 const char *oifname
;
8356 const char *grp_str
;
8357 struct in_addr grp_addr
;
8358 const char *src_str
;
8359 struct in_addr src_addr
;
8362 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
8365 oifname
= argv
[idx_interface
]->arg
;
8366 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
8368 vty_out(vty
, "No such interface name %s\n", oifname
);
8372 grp_str
= argv
[idx_ipv4
]->arg
;
8373 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
8375 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
8376 errno
, safe_strerror(errno
));
8380 if (argc
== (idx_ipv4
+ 1)) {
8381 src_addr
.s_addr
= INADDR_ANY
;
8384 src_str
= argv
[idx_ipv4
+ 1]->arg
;
8385 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
8387 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
8388 errno
, safe_strerror(errno
));
8393 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
8394 vty_out(vty
, "Failed to add static mroute\n");
8401 DEFUN (interface_no_ip_mroute
,
8402 interface_no_ip_mroute_cmd
,
8403 "no ip mroute INTERFACE A.B.C.D [A.B.C.D]",
8406 "Add multicast route\n"
8407 "Outgoing interface name\n"
8411 VTY_DECLVAR_CONTEXT(interface
, iif
);
8412 struct pim_interface
*pim_ifp
;
8413 struct pim_instance
*pim
;
8414 int idx_interface
= 3;
8416 struct interface
*oif
;
8417 const char *oifname
;
8418 const char *grp_str
;
8419 struct in_addr grp_addr
;
8420 const char *src_str
;
8421 struct in_addr src_addr
;
8424 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
8427 oifname
= argv
[idx_interface
]->arg
;
8428 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
8430 vty_out(vty
, "No such interface name %s\n", oifname
);
8434 grp_str
= argv
[idx_ipv4
]->arg
;
8435 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
8437 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
8438 errno
, safe_strerror(errno
));
8442 if (argc
== (idx_ipv4
+ 1)) {
8443 src_addr
.s_addr
= INADDR_ANY
;
8446 src_str
= argv
[idx_ipv4
+ 1]->arg
;
8447 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
8449 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
8450 errno
, safe_strerror(errno
));
8455 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
8456 vty_out(vty
, "Failed to remove static mroute\n");
8463 DEFUN (interface_ip_pim_hello
,
8464 interface_ip_pim_hello_cmd
,
8465 "ip pim hello (1-180) [(1-180)]",
8469 IFACE_PIM_HELLO_TIME_STR
8470 IFACE_PIM_HELLO_HOLD_STR
)
8472 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8475 struct pim_interface
*pim_ifp
= ifp
->info
;
8478 if (!pim_cmd_interface_add(vty
, ifp
)) {
8480 "Could not enable PIM SM on interface %s\n",
8482 return CMD_WARNING_CONFIG_FAILED
;
8486 pim_ifp
= ifp
->info
;
8487 pim_ifp
->pim_hello_period
= strtol(argv
[idx_time
]->arg
, NULL
, 10);
8489 if (argc
== idx_hold
+ 1)
8490 pim_ifp
->pim_default_holdtime
=
8491 strtol(argv
[idx_hold
]->arg
, NULL
, 10);
8496 DEFUN (interface_no_ip_pim_hello
,
8497 interface_no_ip_pim_hello_cmd
,
8498 "no ip pim hello [(1-180) (1-180)]",
8503 IFACE_PIM_HELLO_TIME_STR
8504 IFACE_PIM_HELLO_HOLD_STR
)
8506 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8507 struct pim_interface
*pim_ifp
= ifp
->info
;
8510 vty_out(vty
, "Pim not enabled on this interface\n");
8511 return CMD_WARNING_CONFIG_FAILED
;
8514 pim_ifp
->pim_hello_period
= PIM_DEFAULT_HELLO_PERIOD
;
8515 pim_ifp
->pim_default_holdtime
= -1;
8526 PIM_DO_DEBUG_IGMP_EVENTS
;
8527 PIM_DO_DEBUG_IGMP_PACKETS
;
8528 PIM_DO_DEBUG_IGMP_TRACE
;
8532 DEFUN (no_debug_igmp
,
8539 PIM_DONT_DEBUG_IGMP_EVENTS
;
8540 PIM_DONT_DEBUG_IGMP_PACKETS
;
8541 PIM_DONT_DEBUG_IGMP_TRACE
;
8546 DEFUN (debug_igmp_events
,
8547 debug_igmp_events_cmd
,
8548 "debug igmp events",
8551 DEBUG_IGMP_EVENTS_STR
)
8553 PIM_DO_DEBUG_IGMP_EVENTS
;
8557 DEFUN (no_debug_igmp_events
,
8558 no_debug_igmp_events_cmd
,
8559 "no debug igmp events",
8563 DEBUG_IGMP_EVENTS_STR
)
8565 PIM_DONT_DEBUG_IGMP_EVENTS
;
8570 DEFUN (debug_igmp_packets
,
8571 debug_igmp_packets_cmd
,
8572 "debug igmp packets",
8575 DEBUG_IGMP_PACKETS_STR
)
8577 PIM_DO_DEBUG_IGMP_PACKETS
;
8581 DEFUN (no_debug_igmp_packets
,
8582 no_debug_igmp_packets_cmd
,
8583 "no debug igmp packets",
8587 DEBUG_IGMP_PACKETS_STR
)
8589 PIM_DONT_DEBUG_IGMP_PACKETS
;
8594 DEFUN (debug_igmp_trace
,
8595 debug_igmp_trace_cmd
,
8599 DEBUG_IGMP_TRACE_STR
)
8601 PIM_DO_DEBUG_IGMP_TRACE
;
8605 DEFUN (no_debug_igmp_trace
,
8606 no_debug_igmp_trace_cmd
,
8607 "no debug igmp trace",
8611 DEBUG_IGMP_TRACE_STR
)
8613 PIM_DONT_DEBUG_IGMP_TRACE
;
8618 DEFUN (debug_mroute
,
8624 PIM_DO_DEBUG_MROUTE
;
8628 DEFUN (debug_mroute_detail
,
8629 debug_mroute_detail_cmd
,
8630 "debug mroute detail",
8635 PIM_DO_DEBUG_MROUTE_DETAIL
;
8639 DEFUN (no_debug_mroute
,
8640 no_debug_mroute_cmd
,
8646 PIM_DONT_DEBUG_MROUTE
;
8650 DEFUN (no_debug_mroute_detail
,
8651 no_debug_mroute_detail_cmd
,
8652 "no debug mroute detail",
8658 PIM_DONT_DEBUG_MROUTE_DETAIL
;
8662 DEFUN (debug_pim_static
,
8663 debug_pim_static_cmd
,
8669 PIM_DO_DEBUG_STATIC
;
8673 DEFUN (no_debug_pim_static
,
8674 no_debug_pim_static_cmd
,
8675 "no debug pim static",
8681 PIM_DONT_DEBUG_STATIC
;
8692 PIM_DO_DEBUG_PIM_EVENTS
;
8693 PIM_DO_DEBUG_PIM_PACKETS
;
8694 PIM_DO_DEBUG_PIM_TRACE
;
8695 PIM_DO_DEBUG_MSDP_EVENTS
;
8696 PIM_DO_DEBUG_MSDP_PACKETS
;
8701 DEFUN (no_debug_pim
,
8708 PIM_DONT_DEBUG_PIM_EVENTS
;
8709 PIM_DONT_DEBUG_PIM_PACKETS
;
8710 PIM_DONT_DEBUG_PIM_TRACE
;
8711 PIM_DONT_DEBUG_MSDP_EVENTS
;
8712 PIM_DONT_DEBUG_MSDP_PACKETS
;
8714 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
8715 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
8721 DEFUN (debug_pim_nht
,
8726 "Nexthop Tracking\n")
8728 PIM_DO_DEBUG_PIM_NHT
;
8732 DEFUN (no_debug_pim_nht
,
8733 no_debug_pim_nht_cmd
,
8738 "Nexthop Tracking\n")
8740 PIM_DONT_DEBUG_PIM_NHT
;
8744 DEFUN (debug_pim_nht_rp
,
8745 debug_pim_nht_rp_cmd
,
8749 "Nexthop Tracking\n"
8750 "RP Nexthop Tracking\n")
8752 PIM_DO_DEBUG_PIM_NHT_RP
;
8756 DEFUN (no_debug_pim_nht_rp
,
8757 no_debug_pim_nht_rp_cmd
,
8758 "no debug pim nht rp",
8762 "Nexthop Tracking\n"
8763 "RP Nexthop Tracking\n")
8765 PIM_DONT_DEBUG_PIM_NHT_RP
;
8769 DEFUN (debug_pim_events
,
8770 debug_pim_events_cmd
,
8774 DEBUG_PIM_EVENTS_STR
)
8776 PIM_DO_DEBUG_PIM_EVENTS
;
8780 DEFUN (no_debug_pim_events
,
8781 no_debug_pim_events_cmd
,
8782 "no debug pim events",
8786 DEBUG_PIM_EVENTS_STR
)
8788 PIM_DONT_DEBUG_PIM_EVENTS
;
8792 DEFUN (debug_pim_packets
,
8793 debug_pim_packets_cmd
,
8794 "debug pim packets [<hello|joins|register>]",
8797 DEBUG_PIM_PACKETS_STR
8798 DEBUG_PIM_HELLO_PACKETS_STR
8799 DEBUG_PIM_J_P_PACKETS_STR
8800 DEBUG_PIM_PIM_REG_PACKETS_STR
)
8803 if (argv_find(argv
, argc
, "hello", &idx
)) {
8804 PIM_DO_DEBUG_PIM_HELLO
;
8805 vty_out(vty
, "PIM Hello debugging is on\n");
8806 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
8807 PIM_DO_DEBUG_PIM_J_P
;
8808 vty_out(vty
, "PIM Join/Prune debugging is on\n");
8809 } else if (argv_find(argv
, argc
, "register", &idx
)) {
8810 PIM_DO_DEBUG_PIM_REG
;
8811 vty_out(vty
, "PIM Register debugging is on\n");
8813 PIM_DO_DEBUG_PIM_PACKETS
;
8814 vty_out(vty
, "PIM Packet debugging is on \n");
8819 DEFUN (no_debug_pim_packets
,
8820 no_debug_pim_packets_cmd
,
8821 "no debug pim packets [<hello|joins|register>]",
8825 DEBUG_PIM_PACKETS_STR
8826 DEBUG_PIM_HELLO_PACKETS_STR
8827 DEBUG_PIM_J_P_PACKETS_STR
8828 DEBUG_PIM_PIM_REG_PACKETS_STR
)
8831 if (argv_find(argv
, argc
, "hello", &idx
)) {
8832 PIM_DONT_DEBUG_PIM_HELLO
;
8833 vty_out(vty
, "PIM Hello debugging is off \n");
8834 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
8835 PIM_DONT_DEBUG_PIM_J_P
;
8836 vty_out(vty
, "PIM Join/Prune debugging is off \n");
8837 } else if (argv_find(argv
, argc
, "register", &idx
)) {
8838 PIM_DONT_DEBUG_PIM_REG
;
8839 vty_out(vty
, "PIM Register debugging is off\n");
8841 PIM_DONT_DEBUG_PIM_PACKETS
;
8847 DEFUN (debug_pim_packetdump_send
,
8848 debug_pim_packetdump_send_cmd
,
8849 "debug pim packet-dump send",
8852 DEBUG_PIM_PACKETDUMP_STR
8853 DEBUG_PIM_PACKETDUMP_SEND_STR
)
8855 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND
;
8859 DEFUN (no_debug_pim_packetdump_send
,
8860 no_debug_pim_packetdump_send_cmd
,
8861 "no debug pim packet-dump send",
8865 DEBUG_PIM_PACKETDUMP_STR
8866 DEBUG_PIM_PACKETDUMP_SEND_STR
)
8868 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
8872 DEFUN (debug_pim_packetdump_recv
,
8873 debug_pim_packetdump_recv_cmd
,
8874 "debug pim packet-dump receive",
8877 DEBUG_PIM_PACKETDUMP_STR
8878 DEBUG_PIM_PACKETDUMP_RECV_STR
)
8880 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV
;
8884 DEFUN (no_debug_pim_packetdump_recv
,
8885 no_debug_pim_packetdump_recv_cmd
,
8886 "no debug pim packet-dump receive",
8890 DEBUG_PIM_PACKETDUMP_STR
8891 DEBUG_PIM_PACKETDUMP_RECV_STR
)
8893 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
8897 DEFUN (debug_pim_trace
,
8898 debug_pim_trace_cmd
,
8902 DEBUG_PIM_TRACE_STR
)
8904 PIM_DO_DEBUG_PIM_TRACE
;
8908 DEFUN (debug_pim_trace_detail
,
8909 debug_pim_trace_detail_cmd
,
8910 "debug pim trace detail",
8914 "Detailed Information\n")
8916 PIM_DO_DEBUG_PIM_TRACE_DETAIL
;
8920 DEFUN (no_debug_pim_trace
,
8921 no_debug_pim_trace_cmd
,
8922 "no debug pim trace",
8926 DEBUG_PIM_TRACE_STR
)
8928 PIM_DONT_DEBUG_PIM_TRACE
;
8932 DEFUN (no_debug_pim_trace_detail
,
8933 no_debug_pim_trace_detail_cmd
,
8934 "no debug pim trace detail",
8939 "Detailed Information\n")
8941 PIM_DONT_DEBUG_PIM_TRACE_DETAIL
;
8945 DEFUN (debug_ssmpingd
,
8951 PIM_DO_DEBUG_SSMPINGD
;
8955 DEFUN (no_debug_ssmpingd
,
8956 no_debug_ssmpingd_cmd
,
8957 "no debug ssmpingd",
8962 PIM_DONT_DEBUG_SSMPINGD
;
8966 DEFUN (debug_pim_zebra
,
8967 debug_pim_zebra_cmd
,
8971 DEBUG_PIM_ZEBRA_STR
)
8977 DEFUN (no_debug_pim_zebra
,
8978 no_debug_pim_zebra_cmd
,
8979 "no debug pim zebra",
8983 DEBUG_PIM_ZEBRA_STR
)
8985 PIM_DONT_DEBUG_ZEBRA
;
8989 DEFUN(debug_pim_mlag
, debug_pim_mlag_cmd
, "debug pim mlag",
8990 DEBUG_STR DEBUG_PIM_STR DEBUG_PIM_MLAG_STR
)
8996 DEFUN(no_debug_pim_mlag
, no_debug_pim_mlag_cmd
, "no debug pim mlag",
8997 NO_STR DEBUG_STR DEBUG_PIM_STR DEBUG_PIM_MLAG_STR
)
8999 PIM_DONT_DEBUG_MLAG
;
9003 DEFUN (debug_pim_vxlan
,
9004 debug_pim_vxlan_cmd
,
9008 DEBUG_PIM_VXLAN_STR
)
9014 DEFUN (no_debug_pim_vxlan
,
9015 no_debug_pim_vxlan_cmd
,
9016 "no debug pim vxlan",
9020 DEBUG_PIM_VXLAN_STR
)
9022 PIM_DONT_DEBUG_VXLAN
;
9032 PIM_DO_DEBUG_MSDP_EVENTS
;
9033 PIM_DO_DEBUG_MSDP_PACKETS
;
9037 DEFUN (no_debug_msdp
,
9044 PIM_DONT_DEBUG_MSDP_EVENTS
;
9045 PIM_DONT_DEBUG_MSDP_PACKETS
;
9049 DEFUN (debug_msdp_events
,
9050 debug_msdp_events_cmd
,
9051 "debug msdp events",
9054 DEBUG_MSDP_EVENTS_STR
)
9056 PIM_DO_DEBUG_MSDP_EVENTS
;
9060 DEFUN (no_debug_msdp_events
,
9061 no_debug_msdp_events_cmd
,
9062 "no debug msdp events",
9066 DEBUG_MSDP_EVENTS_STR
)
9068 PIM_DONT_DEBUG_MSDP_EVENTS
;
9072 DEFUN (debug_msdp_packets
,
9073 debug_msdp_packets_cmd
,
9074 "debug msdp packets",
9077 DEBUG_MSDP_PACKETS_STR
)
9079 PIM_DO_DEBUG_MSDP_PACKETS
;
9083 DEFUN (no_debug_msdp_packets
,
9084 no_debug_msdp_packets_cmd
,
9085 "no debug msdp packets",
9089 DEBUG_MSDP_PACKETS_STR
)
9091 PIM_DONT_DEBUG_MSDP_PACKETS
;
9095 DEFUN (debug_mtrace
,
9101 PIM_DO_DEBUG_MTRACE
;
9105 DEFUN (no_debug_mtrace
,
9106 no_debug_mtrace_cmd
,
9112 PIM_DONT_DEBUG_MTRACE
;
9127 DEFUN (no_debug_bsm
,
9140 DEFUN_NOSH (show_debugging_pim
,
9141 show_debugging_pim_cmd
,
9142 "show debugging [pim]",
9147 vty_out(vty
, "PIM debugging status\n");
9149 pim_debug_config_write(vty
);
9154 static int interface_pim_use_src_cmd_worker(struct vty
*vty
, const char *source
)
9157 struct in_addr source_addr
;
9158 int ret
= CMD_SUCCESS
;
9159 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9161 result
= inet_pton(AF_INET
, source
, &source_addr
);
9163 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", source
,
9164 errno
, safe_strerror(errno
));
9165 return CMD_WARNING_CONFIG_FAILED
;
9168 result
= pim_update_source_set(ifp
, source_addr
);
9172 case PIM_IFACE_NOT_FOUND
:
9173 ret
= CMD_WARNING_CONFIG_FAILED
;
9174 vty_out(vty
, "Pim not enabled on this interface\n");
9176 case PIM_UPDATE_SOURCE_DUP
:
9178 vty_out(vty
, "%% Source already set to %s\n", source
);
9181 ret
= CMD_WARNING_CONFIG_FAILED
;
9182 vty_out(vty
, "%% Source set failed\n");
9188 DEFUN (interface_pim_use_source
,
9189 interface_pim_use_source_cmd
,
9190 "ip pim use-source A.B.C.D",
9193 "Configure primary IP address\n"
9194 "source ip address\n")
9196 return interface_pim_use_src_cmd_worker(vty
, argv
[3]->arg
);
9199 DEFUN (interface_no_pim_use_source
,
9200 interface_no_pim_use_source_cmd
,
9201 "no ip pim use-source [A.B.C.D]",
9205 "Delete source IP address\n"
9206 "source ip address\n")
9208 return interface_pim_use_src_cmd_worker(vty
, "0.0.0.0");
9216 "Enables BFD support\n")
9218 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9219 struct pim_interface
*pim_ifp
= ifp
->info
;
9220 struct bfd_info
*bfd_info
= NULL
;
9223 if (!pim_cmd_interface_add(vty
, ifp
)) {
9225 "Could not enable PIM SM on interface %s\n",
9230 pim_ifp
= ifp
->info
;
9232 bfd_info
= pim_ifp
->bfd_info
;
9234 if (!bfd_info
|| !CHECK_FLAG(bfd_info
->flags
, BFD_FLAG_PARAM_CFG
))
9235 pim_bfd_if_param_set(ifp
, BFD_DEF_MIN_RX
, BFD_DEF_MIN_TX
,
9236 BFD_DEF_DETECT_MULT
, 1);
9241 DEFUN (no_ip_pim_bfd
,
9247 "Disables BFD support\n")
9249 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9250 struct pim_interface
*pim_ifp
= ifp
->info
;
9253 vty_out(vty
, "Pim not enabled on this interface\n");
9257 if (pim_ifp
->bfd_info
) {
9258 pim_bfd_reg_dereg_all_nbr(ifp
, ZEBRA_BFD_DEST_DEREGISTER
);
9259 bfd_info_free(&(pim_ifp
->bfd_info
));
9270 "Enables BSM support on the interface\n")
9272 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9273 struct pim_interface
*pim_ifp
= ifp
->info
;
9276 if (!pim_cmd_interface_add(vty
, ifp
)) {
9278 "Could not enable PIM SM on interface %s\n",
9284 pim_ifp
= ifp
->info
;
9285 pim_ifp
->bsm_enable
= true;
9290 DEFUN (no_ip_pim_bsm
,
9296 "Disables BSM support\n")
9298 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9299 struct pim_interface
*pim_ifp
= ifp
->info
;
9302 vty_out(vty
, "Pim not enabled on this interface\n");
9306 pim_ifp
->bsm_enable
= false;
9311 DEFUN (ip_pim_ucast_bsm
,
9312 ip_pim_ucast_bsm_cmd
,
9313 "ip pim unicast-bsm",
9316 "Accept/Send unicast BSM on the interface\n")
9318 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9319 struct pim_interface
*pim_ifp
= ifp
->info
;
9322 if (!pim_cmd_interface_add(vty
, ifp
)) {
9324 "Could not enable PIM SM on interface %s\n",
9330 pim_ifp
= ifp
->info
;
9331 pim_ifp
->ucast_bsm_accept
= true;
9336 DEFUN (no_ip_pim_ucast_bsm
,
9337 no_ip_pim_ucast_bsm_cmd
,
9338 "no ip pim unicast-bsm",
9342 "Block send/receive unicast BSM on this interface\n")
9344 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9345 struct pim_interface
*pim_ifp
= ifp
->info
;
9348 vty_out(vty
, "Pim not enabled on this interface\n");
9352 pim_ifp
->ucast_bsm_accept
= false;
9360 ip_pim_bfd_param_cmd
,
9361 "ip pim bfd (2-255) (50-60000) (50-60000)",
9364 "Enables BFD support\n"
9365 "Detect Multiplier\n"
9366 "Required min receive interval\n"
9367 "Desired min transmit interval\n")
9371 ip_pim_bfd_param_cmd
,
9372 "ip pim bfd (2-255) (50-60000) (50-60000)",
9375 "Enables BFD support\n"
9376 "Detect Multiplier\n"
9377 "Required min receive interval\n"
9378 "Desired min transmit interval\n")
9379 #endif /* HAVE_BFDD */
9381 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9383 int idx_number_2
= 4;
9384 int idx_number_3
= 5;
9389 struct pim_interface
*pim_ifp
= ifp
->info
;
9392 if (!pim_cmd_interface_add(vty
, ifp
)) {
9394 "Could not enable PIM SM on interface %s\n",
9400 if ((ret
= bfd_validate_param(
9401 vty
, argv
[idx_number
]->arg
, argv
[idx_number_2
]->arg
,
9402 argv
[idx_number_3
]->arg
, &dm_val
, &rx_val
, &tx_val
))
9406 pim_bfd_if_param_set(ifp
, rx_val
, tx_val
, dm_val
, 0);
9412 ALIAS(no_ip_pim_bfd
, no_ip_pim_bfd_param_cmd
,
9413 "no ip pim bfd (2-255) (50-60000) (50-60000)", NO_STR IP_STR PIM_STR
9414 "Enables BFD support\n"
9415 "Detect Multiplier\n"
9416 "Required min receive interval\n"
9417 "Desired min transmit interval\n")
9418 #endif /* !HAVE_BFDD */
9420 static int ip_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
9421 const char *peer
, const char *local
)
9423 enum pim_msdp_err result
;
9424 struct in_addr peer_addr
;
9425 struct in_addr local_addr
;
9426 int ret
= CMD_SUCCESS
;
9428 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
9430 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
9431 errno
, safe_strerror(errno
));
9432 return CMD_WARNING_CONFIG_FAILED
;
9435 result
= inet_pton(AF_INET
, local
, &local_addr
);
9437 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", local
,
9438 errno
, safe_strerror(errno
));
9439 return CMD_WARNING_CONFIG_FAILED
;
9442 result
= pim_msdp_peer_add(pim
, peer_addr
, local_addr
, "default",
9445 case PIM_MSDP_ERR_NONE
:
9447 case PIM_MSDP_ERR_OOM
:
9448 ret
= CMD_WARNING_CONFIG_FAILED
;
9449 vty_out(vty
, "%% Out of memory\n");
9451 case PIM_MSDP_ERR_PEER_EXISTS
:
9453 vty_out(vty
, "%% Peer exists\n");
9455 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
9456 ret
= CMD_WARNING_CONFIG_FAILED
;
9457 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
9460 ret
= CMD_WARNING_CONFIG_FAILED
;
9461 vty_out(vty
, "%% peer add failed\n");
9467 DEFUN_HIDDEN (ip_msdp_peer
,
9469 "ip msdp peer A.B.C.D source A.B.C.D",
9472 "Configure MSDP peer\n"
9474 "Source address for TCP connection\n"
9475 "local ip address\n")
9477 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9478 return ip_msdp_peer_cmd_worker(pim
, vty
, argv
[3]->arg
, argv
[5]->arg
);
9481 static int ip_no_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
9484 enum pim_msdp_err result
;
9485 struct in_addr peer_addr
;
9487 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
9489 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
9490 errno
, safe_strerror(errno
));
9491 return CMD_WARNING_CONFIG_FAILED
;
9494 result
= pim_msdp_peer_del(pim
, peer_addr
);
9496 case PIM_MSDP_ERR_NONE
:
9498 case PIM_MSDP_ERR_NO_PEER
:
9499 vty_out(vty
, "%% Peer does not exist\n");
9502 vty_out(vty
, "%% peer del failed\n");
9505 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9508 DEFUN_HIDDEN (no_ip_msdp_peer
,
9509 no_ip_msdp_peer_cmd
,
9510 "no ip msdp peer A.B.C.D",
9514 "Delete MSDP peer\n"
9515 "peer ip address\n")
9517 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9518 return ip_no_msdp_peer_cmd_worker(pim
, vty
, argv
[4]->arg
);
9521 static int ip_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
9522 struct vty
*vty
, const char *mg
,
9525 enum pim_msdp_err result
;
9526 struct in_addr mbr_ip
;
9527 int ret
= CMD_SUCCESS
;
9529 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
9531 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
9532 errno
, safe_strerror(errno
));
9533 return CMD_WARNING_CONFIG_FAILED
;
9536 result
= pim_msdp_mg_mbr_add(pim
, mg
, mbr_ip
);
9538 case PIM_MSDP_ERR_NONE
:
9540 case PIM_MSDP_ERR_OOM
:
9541 ret
= CMD_WARNING_CONFIG_FAILED
;
9542 vty_out(vty
, "%% Out of memory\n");
9544 case PIM_MSDP_ERR_MG_MBR_EXISTS
:
9546 vty_out(vty
, "%% mesh-group member exists\n");
9548 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
9549 ret
= CMD_WARNING_CONFIG_FAILED
;
9550 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
9553 ret
= CMD_WARNING_CONFIG_FAILED
;
9554 vty_out(vty
, "%% member add failed\n");
9560 DEFUN (ip_msdp_mesh_group_member
,
9561 ip_msdp_mesh_group_member_cmd
,
9562 "ip msdp mesh-group WORD member A.B.C.D",
9565 "Configure MSDP mesh-group\n"
9567 "mesh group member\n"
9568 "peer ip address\n")
9570 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9571 return ip_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[3]->arg
,
9575 static int ip_no_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
9580 enum pim_msdp_err result
;
9581 struct in_addr mbr_ip
;
9583 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
9585 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
9586 errno
, safe_strerror(errno
));
9587 return CMD_WARNING_CONFIG_FAILED
;
9590 result
= pim_msdp_mg_mbr_del(pim
, mg
, mbr_ip
);
9592 case PIM_MSDP_ERR_NONE
:
9594 case PIM_MSDP_ERR_NO_MG
:
9595 vty_out(vty
, "%% mesh-group does not exist\n");
9597 case PIM_MSDP_ERR_NO_MG_MBR
:
9598 vty_out(vty
, "%% mesh-group member does not exist\n");
9601 vty_out(vty
, "%% mesh-group member del failed\n");
9604 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9606 DEFUN (no_ip_msdp_mesh_group_member
,
9607 no_ip_msdp_mesh_group_member_cmd
,
9608 "no ip msdp mesh-group WORD member A.B.C.D",
9612 "Delete MSDP mesh-group member\n"
9614 "mesh group member\n"
9615 "peer ip address\n")
9617 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9618 return ip_no_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[4]->arg
,
9622 static int ip_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
9623 struct vty
*vty
, const char *mg
,
9626 enum pim_msdp_err result
;
9627 struct in_addr src_ip
;
9629 result
= inet_pton(AF_INET
, src
, &src_ip
);
9631 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", src
,
9632 errno
, safe_strerror(errno
));
9633 return CMD_WARNING_CONFIG_FAILED
;
9636 result
= pim_msdp_mg_src_add(pim
, mg
, src_ip
);
9638 case PIM_MSDP_ERR_NONE
:
9640 case PIM_MSDP_ERR_OOM
:
9641 vty_out(vty
, "%% Out of memory\n");
9643 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
9644 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
9647 vty_out(vty
, "%% source add failed\n");
9650 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9654 DEFUN (ip_msdp_mesh_group_source
,
9655 ip_msdp_mesh_group_source_cmd
,
9656 "ip msdp mesh-group WORD source A.B.C.D",
9659 "Configure MSDP mesh-group\n"
9661 "mesh group local address\n"
9662 "source ip address for the TCP connection\n")
9664 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9665 return ip_msdp_mesh_group_source_cmd_worker(pim
, vty
, argv
[3]->arg
,
9669 static int ip_no_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
9673 enum pim_msdp_err result
;
9675 result
= pim_msdp_mg_src_del(pim
, mg
);
9677 case PIM_MSDP_ERR_NONE
:
9679 case PIM_MSDP_ERR_NO_MG
:
9680 vty_out(vty
, "%% mesh-group does not exist\n");
9683 vty_out(vty
, "%% mesh-group source del failed\n");
9686 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9689 static int ip_no_msdp_mesh_group_cmd_worker(struct pim_instance
*pim
,
9690 struct vty
*vty
, const char *mg
)
9692 enum pim_msdp_err result
;
9694 result
= pim_msdp_mg_del(pim
, mg
);
9696 case PIM_MSDP_ERR_NONE
:
9698 case PIM_MSDP_ERR_NO_MG
:
9699 vty_out(vty
, "%% mesh-group does not exist\n");
9702 vty_out(vty
, "%% mesh-group source del failed\n");
9705 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9708 DEFUN (no_ip_msdp_mesh_group_source
,
9709 no_ip_msdp_mesh_group_source_cmd
,
9710 "no ip msdp mesh-group WORD source [A.B.C.D]",
9714 "Delete MSDP mesh-group source\n"
9716 "mesh group source\n"
9717 "mesh group local address\n")
9719 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9721 return ip_no_msdp_mesh_group_cmd_worker(pim
, vty
, argv
[6]->arg
);
9723 return ip_no_msdp_mesh_group_source_cmd_worker(pim
, vty
,
9727 static void print_empty_json_obj(struct vty
*vty
)
9730 json
= json_object_new_object();
9731 vty_out(vty
, "%s\n",
9732 json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
));
9733 json_object_free(json
);
9736 static void ip_msdp_show_mesh_group(struct pim_instance
*pim
, struct vty
*vty
,
9739 struct listnode
*mbrnode
;
9740 struct pim_msdp_mg_mbr
*mbr
;
9741 struct pim_msdp_mg
*mg
= pim
->msdp
.mg
;
9742 char mbr_str
[INET_ADDRSTRLEN
];
9743 char src_str
[INET_ADDRSTRLEN
];
9744 char state_str
[PIM_MSDP_STATE_STRLEN
];
9745 enum pim_msdp_peer_state state
;
9746 json_object
*json
= NULL
;
9747 json_object
*json_mg_row
= NULL
;
9748 json_object
*json_members
= NULL
;
9749 json_object
*json_row
= NULL
;
9753 print_empty_json_obj(vty
);
9757 pim_inet4_dump("<source?>", mg
->src_ip
, src_str
, sizeof(src_str
));
9759 json
= json_object_new_object();
9760 /* currently there is only one mesh group but we should still
9762 * it a dict with mg-name as key */
9763 json_mg_row
= json_object_new_object();
9764 json_object_string_add(json_mg_row
, "name",
9765 mg
->mesh_group_name
);
9766 json_object_string_add(json_mg_row
, "source", src_str
);
9768 vty_out(vty
, "Mesh group : %s\n", mg
->mesh_group_name
);
9769 vty_out(vty
, " Source : %s\n", src_str
);
9770 vty_out(vty
, " Member State\n");
9773 for (ALL_LIST_ELEMENTS_RO(mg
->mbr_list
, mbrnode
, mbr
)) {
9774 pim_inet4_dump("<mbr?>", mbr
->mbr_ip
, mbr_str
, sizeof(mbr_str
));
9776 state
= mbr
->mp
->state
;
9778 state
= PIM_MSDP_DISABLED
;
9780 pim_msdp_state_dump(state
, state_str
, sizeof(state_str
));
9782 json_row
= json_object_new_object();
9783 json_object_string_add(json_row
, "member", mbr_str
);
9784 json_object_string_add(json_row
, "state", state_str
);
9785 if (!json_members
) {
9786 json_members
= json_object_new_object();
9787 json_object_object_add(json_mg_row
, "members",
9790 json_object_object_add(json_members
, mbr_str
, json_row
);
9792 vty_out(vty
, " %-15s %11s\n", mbr_str
, state_str
);
9797 json_object_object_add(json
, mg
->mesh_group_name
, json_mg_row
);
9798 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9799 json
, JSON_C_TO_STRING_PRETTY
));
9800 json_object_free(json
);
9804 DEFUN (show_ip_msdp_mesh_group
,
9805 show_ip_msdp_mesh_group_cmd
,
9806 "show ip msdp [vrf NAME] mesh-group [json]",
9811 "MSDP mesh-group information\n"
9814 bool uj
= use_json(argc
, argv
);
9816 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
9821 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
9826 DEFUN (show_ip_msdp_mesh_group_vrf_all
,
9827 show_ip_msdp_mesh_group_vrf_all_cmd
,
9828 "show ip msdp vrf all mesh-group [json]",
9833 "MSDP mesh-group information\n"
9836 bool uj
= use_json(argc
, argv
);
9842 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
9846 vty_out(vty
, " \"%s\": ", vrf
->name
);
9849 vty_out(vty
, "VRF: %s\n", vrf
->name
);
9850 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
9853 vty_out(vty
, "}\n");
9858 static void ip_msdp_show_peers(struct pim_instance
*pim
, struct vty
*vty
,
9861 struct listnode
*mpnode
;
9862 struct pim_msdp_peer
*mp
;
9863 char peer_str
[INET_ADDRSTRLEN
];
9864 char local_str
[INET_ADDRSTRLEN
];
9865 char state_str
[PIM_MSDP_STATE_STRLEN
];
9866 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
9868 json_object
*json
= NULL
;
9869 json_object
*json_row
= NULL
;
9873 json
= json_object_new_object();
9876 "Peer Local State Uptime SaCnt\n");
9879 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
9880 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
9881 now
= pim_time_monotonic_sec();
9882 pim_time_uptime(timebuf
, sizeof(timebuf
),
9885 strlcpy(timebuf
, "-", sizeof(timebuf
));
9887 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
9888 pim_inet4_dump("<local?>", mp
->local
, local_str
,
9890 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
9892 json_row
= json_object_new_object();
9893 json_object_string_add(json_row
, "peer", peer_str
);
9894 json_object_string_add(json_row
, "local", local_str
);
9895 json_object_string_add(json_row
, "state", state_str
);
9896 json_object_string_add(json_row
, "upTime", timebuf
);
9897 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
9898 json_object_object_add(json
, peer_str
, json_row
);
9900 vty_out(vty
, "%-15s %15s %11s %8s %6d\n", peer_str
,
9901 local_str
, state_str
, timebuf
, mp
->sa_cnt
);
9906 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9907 json
, JSON_C_TO_STRING_PRETTY
));
9908 json_object_free(json
);
9912 static void ip_msdp_show_peers_detail(struct pim_instance
*pim
, struct vty
*vty
,
9913 const char *peer
, bool uj
)
9915 struct listnode
*mpnode
;
9916 struct pim_msdp_peer
*mp
;
9917 char peer_str
[INET_ADDRSTRLEN
];
9918 char local_str
[INET_ADDRSTRLEN
];
9919 char state_str
[PIM_MSDP_STATE_STRLEN
];
9920 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
9921 char katimer
[PIM_MSDP_TIMER_STRLEN
];
9922 char crtimer
[PIM_MSDP_TIMER_STRLEN
];
9923 char holdtimer
[PIM_MSDP_TIMER_STRLEN
];
9925 json_object
*json
= NULL
;
9926 json_object
*json_row
= NULL
;
9929 json
= json_object_new_object();
9932 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
9933 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
9934 if (strcmp(peer
, "detail") && strcmp(peer
, peer_str
))
9937 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
9938 now
= pim_time_monotonic_sec();
9939 pim_time_uptime(timebuf
, sizeof(timebuf
),
9942 strlcpy(timebuf
, "-", sizeof(timebuf
));
9944 pim_inet4_dump("<local?>", mp
->local
, local_str
,
9946 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
9947 pim_time_timer_to_hhmmss(katimer
, sizeof(katimer
),
9949 pim_time_timer_to_hhmmss(crtimer
, sizeof(crtimer
),
9951 pim_time_timer_to_hhmmss(holdtimer
, sizeof(holdtimer
),
9955 json_row
= json_object_new_object();
9956 json_object_string_add(json_row
, "peer", peer_str
);
9957 json_object_string_add(json_row
, "local", local_str
);
9958 json_object_string_add(json_row
, "meshGroupName",
9959 mp
->mesh_group_name
);
9960 json_object_string_add(json_row
, "state", state_str
);
9961 json_object_string_add(json_row
, "upTime", timebuf
);
9962 json_object_string_add(json_row
, "keepAliveTimer",
9964 json_object_string_add(json_row
, "connRetryTimer",
9966 json_object_string_add(json_row
, "holdTimer",
9968 json_object_string_add(json_row
, "lastReset",
9970 json_object_int_add(json_row
, "connAttempts",
9972 json_object_int_add(json_row
, "establishedChanges",
9974 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
9975 json_object_int_add(json_row
, "kaSent", mp
->ka_tx_cnt
);
9976 json_object_int_add(json_row
, "kaRcvd", mp
->ka_rx_cnt
);
9977 json_object_int_add(json_row
, "saSent", mp
->sa_tx_cnt
);
9978 json_object_int_add(json_row
, "saRcvd", mp
->sa_rx_cnt
);
9979 json_object_object_add(json
, peer_str
, json_row
);
9981 vty_out(vty
, "Peer : %s\n", peer_str
);
9982 vty_out(vty
, " Local : %s\n", local_str
);
9983 vty_out(vty
, " Mesh Group : %s\n",
9984 mp
->mesh_group_name
);
9985 vty_out(vty
, " State : %s\n", state_str
);
9986 vty_out(vty
, " Uptime : %s\n", timebuf
);
9988 vty_out(vty
, " Keepalive Timer : %s\n", katimer
);
9989 vty_out(vty
, " Conn Retry Timer : %s\n", crtimer
);
9990 vty_out(vty
, " Hold Timer : %s\n", holdtimer
);
9991 vty_out(vty
, " Last Reset : %s\n",
9993 vty_out(vty
, " Conn Attempts : %d\n",
9995 vty_out(vty
, " Established Changes : %d\n",
9997 vty_out(vty
, " SA Count : %d\n",
9999 vty_out(vty
, " Statistics :\n");
10002 vty_out(vty
, " Keepalives : %10d %10d\n",
10003 mp
->ka_tx_cnt
, mp
->ka_rx_cnt
);
10004 vty_out(vty
, " SAs : %10d %10d\n",
10005 mp
->sa_tx_cnt
, mp
->sa_rx_cnt
);
10006 vty_out(vty
, "\n");
10011 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10012 json
, JSON_C_TO_STRING_PRETTY
));
10013 json_object_free(json
);
10017 DEFUN (show_ip_msdp_peer_detail
,
10018 show_ip_msdp_peer_detail_cmd
,
10019 "show ip msdp [vrf NAME] peer [detail|A.B.C.D] [json]",
10024 "MSDP peer information\n"
10025 "Detailed output\n"
10026 "peer ip address\n"
10029 bool uj
= use_json(argc
, argv
);
10031 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10034 return CMD_WARNING
;
10038 if (argv_find(argv
, argc
, "detail", &idx
))
10039 arg
= argv
[idx
]->text
;
10040 else if (argv_find(argv
, argc
, "A.B.C.D", &idx
))
10041 arg
= argv
[idx
]->arg
;
10044 ip_msdp_show_peers_detail(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
10046 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
10048 return CMD_SUCCESS
;
10051 DEFUN (show_ip_msdp_peer_detail_vrf_all
,
10052 show_ip_msdp_peer_detail_vrf_all_cmd
,
10053 "show ip msdp vrf all peer [detail|A.B.C.D] [json]",
10058 "MSDP peer information\n"
10059 "Detailed output\n"
10060 "peer ip address\n"
10064 bool uj
= use_json(argc
, argv
);
10069 vty_out(vty
, "{ ");
10070 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
10073 vty_out(vty
, ", ");
10074 vty_out(vty
, " \"%s\": ", vrf
->name
);
10077 vty_out(vty
, "VRF: %s\n", vrf
->name
);
10078 if (argv_find(argv
, argc
, "detail", &idx
)
10079 || argv_find(argv
, argc
, "A.B.C.D", &idx
))
10080 ip_msdp_show_peers_detail(vrf
->info
, vty
,
10081 argv
[idx
]->arg
, uj
);
10083 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
10086 vty_out(vty
, "}\n");
10088 return CMD_SUCCESS
;
10091 static void ip_msdp_show_sa(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
10093 struct listnode
*sanode
;
10094 struct pim_msdp_sa
*sa
;
10095 char src_str
[INET_ADDRSTRLEN
];
10096 char grp_str
[INET_ADDRSTRLEN
];
10097 char rp_str
[INET_ADDRSTRLEN
];
10098 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
10102 json_object
*json
= NULL
;
10103 json_object
*json_group
= NULL
;
10104 json_object
*json_row
= NULL
;
10107 json
= json_object_new_object();
10110 "Source Group RP Local SPT Uptime\n");
10113 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
10114 now
= pim_time_monotonic_sec();
10115 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
10116 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
10117 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
10118 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
10119 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
10121 strlcpy(spt_str
, "yes", sizeof(spt_str
));
10123 strlcpy(spt_str
, "no", sizeof(spt_str
));
10126 strlcpy(rp_str
, "-", sizeof(rp_str
));
10127 strlcpy(spt_str
, "-", sizeof(spt_str
));
10129 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
10130 strlcpy(local_str
, "yes", sizeof(local_str
));
10132 strlcpy(local_str
, "no", sizeof(local_str
));
10135 json_object_object_get_ex(json
, grp_str
, &json_group
);
10138 json_group
= json_object_new_object();
10139 json_object_object_add(json
, grp_str
,
10143 json_row
= json_object_new_object();
10144 json_object_string_add(json_row
, "source", src_str
);
10145 json_object_string_add(json_row
, "group", grp_str
);
10146 json_object_string_add(json_row
, "rp", rp_str
);
10147 json_object_string_add(json_row
, "local", local_str
);
10148 json_object_string_add(json_row
, "sptSetup", spt_str
);
10149 json_object_string_add(json_row
, "upTime", timebuf
);
10150 json_object_object_add(json_group
, src_str
, json_row
);
10152 vty_out(vty
, "%-15s %15s %15s %5c %3c %8s\n",
10153 src_str
, grp_str
, rp_str
, local_str
[0],
10154 spt_str
[0], timebuf
);
10159 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10160 json
, JSON_C_TO_STRING_PRETTY
));
10161 json_object_free(json
);
10165 static void ip_msdp_show_sa_entry_detail(struct pim_msdp_sa
*sa
,
10166 const char *src_str
,
10167 const char *grp_str
, struct vty
*vty
,
10168 bool uj
, json_object
*json
)
10170 char rp_str
[INET_ADDRSTRLEN
];
10171 char peer_str
[INET_ADDRSTRLEN
];
10172 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
10175 char statetimer
[PIM_MSDP_TIMER_STRLEN
];
10177 json_object
*json_group
= NULL
;
10178 json_object
*json_row
= NULL
;
10180 now
= pim_time_monotonic_sec();
10181 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
10182 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
10183 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
10184 pim_inet4_dump("<peer?>", sa
->peer
, peer_str
, sizeof(peer_str
));
10186 strlcpy(spt_str
, "yes", sizeof(spt_str
));
10188 strlcpy(spt_str
, "no", sizeof(spt_str
));
10191 strlcpy(rp_str
, "-", sizeof(rp_str
));
10192 strlcpy(peer_str
, "-", sizeof(peer_str
));
10193 strlcpy(spt_str
, "-", sizeof(spt_str
));
10195 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
10196 strlcpy(local_str
, "yes", sizeof(local_str
));
10198 strlcpy(local_str
, "no", sizeof(local_str
));
10200 pim_time_timer_to_hhmmss(statetimer
, sizeof(statetimer
),
10201 sa
->sa_state_timer
);
10203 json_object_object_get_ex(json
, grp_str
, &json_group
);
10206 json_group
= json_object_new_object();
10207 json_object_object_add(json
, grp_str
, json_group
);
10210 json_row
= json_object_new_object();
10211 json_object_string_add(json_row
, "source", src_str
);
10212 json_object_string_add(json_row
, "group", grp_str
);
10213 json_object_string_add(json_row
, "rp", rp_str
);
10214 json_object_string_add(json_row
, "local", local_str
);
10215 json_object_string_add(json_row
, "sptSetup", spt_str
);
10216 json_object_string_add(json_row
, "upTime", timebuf
);
10217 json_object_string_add(json_row
, "stateTimer", statetimer
);
10218 json_object_object_add(json_group
, src_str
, json_row
);
10220 vty_out(vty
, "SA : %s\n", sa
->sg_str
);
10221 vty_out(vty
, " RP : %s\n", rp_str
);
10222 vty_out(vty
, " Peer : %s\n", peer_str
);
10223 vty_out(vty
, " Local : %s\n", local_str
);
10224 vty_out(vty
, " SPT Setup : %s\n", spt_str
);
10225 vty_out(vty
, " Uptime : %s\n", timebuf
);
10226 vty_out(vty
, " State Timer : %s\n", statetimer
);
10227 vty_out(vty
, "\n");
10231 static void ip_msdp_show_sa_detail(struct pim_instance
*pim
, struct vty
*vty
,
10234 struct listnode
*sanode
;
10235 struct pim_msdp_sa
*sa
;
10236 char src_str
[INET_ADDRSTRLEN
];
10237 char grp_str
[INET_ADDRSTRLEN
];
10238 json_object
*json
= NULL
;
10241 json
= json_object_new_object();
10244 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
10245 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
10246 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
10247 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
, uj
,
10252 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10253 json
, JSON_C_TO_STRING_PRETTY
));
10254 json_object_free(json
);
10258 DEFUN (show_ip_msdp_sa_detail
,
10259 show_ip_msdp_sa_detail_cmd
,
10260 "show ip msdp [vrf NAME] sa detail [json]",
10265 "MSDP active-source information\n"
10266 "Detailed output\n"
10269 bool uj
= use_json(argc
, argv
);
10271 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10274 return CMD_WARNING
;
10276 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
10278 return CMD_SUCCESS
;
10281 DEFUN (show_ip_msdp_sa_detail_vrf_all
,
10282 show_ip_msdp_sa_detail_vrf_all_cmd
,
10283 "show ip msdp vrf all sa detail [json]",
10288 "MSDP active-source information\n"
10289 "Detailed output\n"
10292 bool uj
= use_json(argc
, argv
);
10297 vty_out(vty
, "{ ");
10298 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
10301 vty_out(vty
, ", ");
10302 vty_out(vty
, " \"%s\": ", vrf
->name
);
10305 vty_out(vty
, "VRF: %s\n", vrf
->name
);
10306 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
10309 vty_out(vty
, "}\n");
10311 return CMD_SUCCESS
;
10314 static void ip_msdp_show_sa_addr(struct pim_instance
*pim
, struct vty
*vty
,
10315 const char *addr
, bool uj
)
10317 struct listnode
*sanode
;
10318 struct pim_msdp_sa
*sa
;
10319 char src_str
[INET_ADDRSTRLEN
];
10320 char grp_str
[INET_ADDRSTRLEN
];
10321 json_object
*json
= NULL
;
10324 json
= json_object_new_object();
10327 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
10328 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
10329 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
10330 if (!strcmp(addr
, src_str
) || !strcmp(addr
, grp_str
)) {
10331 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
10337 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10338 json
, JSON_C_TO_STRING_PRETTY
));
10339 json_object_free(json
);
10343 static void ip_msdp_show_sa_sg(struct pim_instance
*pim
, struct vty
*vty
,
10344 const char *src
, const char *grp
, bool uj
)
10346 struct listnode
*sanode
;
10347 struct pim_msdp_sa
*sa
;
10348 char src_str
[INET_ADDRSTRLEN
];
10349 char grp_str
[INET_ADDRSTRLEN
];
10350 json_object
*json
= NULL
;
10353 json
= json_object_new_object();
10356 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
10357 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
10358 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
10359 if (!strcmp(src
, src_str
) && !strcmp(grp
, grp_str
)) {
10360 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
10366 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10367 json
, JSON_C_TO_STRING_PRETTY
));
10368 json_object_free(json
);
10372 DEFUN (show_ip_msdp_sa_sg
,
10373 show_ip_msdp_sa_sg_cmd
,
10374 "show ip msdp [vrf NAME] sa [A.B.C.D [A.B.C.D]] [json]",
10379 "MSDP active-source information\n"
10380 "source or group ip\n"
10384 bool uj
= use_json(argc
, argv
);
10388 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10391 return CMD_WARNING
;
10393 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
10395 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
10399 if (src_ip
&& grp_ip
)
10400 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
10402 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
10404 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
10406 return CMD_SUCCESS
;
10409 DEFUN (show_ip_msdp_sa_sg_vrf_all
,
10410 show_ip_msdp_sa_sg_vrf_all_cmd
,
10411 "show ip msdp vrf all sa [A.B.C.D [A.B.C.D]] [json]",
10416 "MSDP active-source information\n"
10417 "source or group ip\n"
10421 bool uj
= use_json(argc
, argv
);
10426 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
10428 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
10433 vty_out(vty
, "{ ");
10434 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
10437 vty_out(vty
, ", ");
10438 vty_out(vty
, " \"%s\": ", vrf
->name
);
10441 vty_out(vty
, "VRF: %s\n", vrf
->name
);
10443 if (src_ip
&& grp_ip
)
10444 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
10446 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
10448 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
10451 vty_out(vty
, "}\n");
10453 return CMD_SUCCESS
;
10456 struct pim_sg_cache_walk_data
{
10459 json_object
*json_group
;
10460 struct in_addr addr
;
10464 static void pim_show_vxlan_sg_entry(struct pim_vxlan_sg
*vxlan_sg
,
10465 struct pim_sg_cache_walk_data
*cwd
)
10467 struct vty
*vty
= cwd
->vty
;
10468 json_object
*json
= cwd
->json
;
10469 char src_str
[INET_ADDRSTRLEN
];
10470 char grp_str
[INET_ADDRSTRLEN
];
10471 json_object
*json_row
;
10472 bool installed
= (vxlan_sg
->up
) ? true : false;
10473 const char *iif_name
= vxlan_sg
->iif
?vxlan_sg
->iif
->name
:"-";
10474 const char *oif_name
;
10476 if (pim_vxlan_is_orig_mroute(vxlan_sg
))
10477 oif_name
= vxlan_sg
->orig_oif
?vxlan_sg
->orig_oif
->name
:"";
10479 oif_name
= vxlan_sg
->term_oif
?vxlan_sg
->term_oif
->name
:"";
10481 if (cwd
->addr_match
&& (vxlan_sg
->sg
.src
.s_addr
!= cwd
->addr
.s_addr
) &&
10482 (vxlan_sg
->sg
.grp
.s_addr
!= cwd
->addr
.s_addr
)) {
10485 pim_inet4_dump("<src?>", vxlan_sg
->sg
.src
, src_str
, sizeof(src_str
));
10486 pim_inet4_dump("<grp?>", vxlan_sg
->sg
.grp
, grp_str
, sizeof(grp_str
));
10488 json_object_object_get_ex(json
, grp_str
, &cwd
->json_group
);
10490 if (!cwd
->json_group
) {
10491 cwd
->json_group
= json_object_new_object();
10492 json_object_object_add(json
, grp_str
,
10496 json_row
= json_object_new_object();
10497 json_object_string_add(json_row
, "source", src_str
);
10498 json_object_string_add(json_row
, "group", grp_str
);
10499 json_object_string_add(json_row
, "input", iif_name
);
10500 json_object_string_add(json_row
, "output", oif_name
);
10502 json_object_boolean_true_add(json_row
, "installed");
10504 json_object_boolean_false_add(json_row
, "installed");
10505 json_object_object_add(cwd
->json_group
, src_str
, json_row
);
10507 vty_out(vty
, "%-15s %-15s %-15s %-15s %-5s\n",
10508 src_str
, grp_str
, iif_name
, oif_name
,
10513 static void pim_show_vxlan_sg_hash_entry(struct hash_bucket
*backet
, void *arg
)
10515 pim_show_vxlan_sg_entry((struct pim_vxlan_sg
*)backet
->data
,
10516 (struct pim_sg_cache_walk_data
*)arg
);
10519 static void pim_show_vxlan_sg(struct pim_instance
*pim
,
10520 struct vty
*vty
, bool uj
)
10522 json_object
*json
= NULL
;
10523 struct pim_sg_cache_walk_data cwd
;
10526 json
= json_object_new_object();
10528 vty_out(vty
, "Codes: I -> installed\n");
10530 "Source Group Input Output Flags\n");
10533 memset(&cwd
, 0, sizeof(cwd
));
10536 hash_iterate(pim
->vxlan
.sg_hash
, pim_show_vxlan_sg_hash_entry
, &cwd
);
10539 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10540 json
, JSON_C_TO_STRING_PRETTY
));
10541 json_object_free(json
);
10545 static void pim_show_vxlan_sg_match_addr(struct pim_instance
*pim
,
10546 struct vty
*vty
, char *addr_str
, bool uj
)
10548 json_object
*json
= NULL
;
10549 struct pim_sg_cache_walk_data cwd
;
10552 memset(&cwd
, 0, sizeof(cwd
));
10553 result
= inet_pton(AF_INET
, addr_str
, &cwd
.addr
);
10555 vty_out(vty
, "Bad address %s: errno=%d: %s\n", addr_str
,
10556 errno
, safe_strerror(errno
));
10561 json
= json_object_new_object();
10563 vty_out(vty
, "Codes: I -> installed\n");
10565 "Source Group Input Output Flags\n");
10570 cwd
.addr_match
= true;
10571 hash_iterate(pim
->vxlan
.sg_hash
, pim_show_vxlan_sg_hash_entry
, &cwd
);
10574 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10575 json
, JSON_C_TO_STRING_PRETTY
));
10576 json_object_free(json
);
10580 static void pim_show_vxlan_sg_one(struct pim_instance
*pim
,
10581 struct vty
*vty
, char *src_str
, char *grp_str
, bool uj
)
10583 json_object
*json
= NULL
;
10584 struct prefix_sg sg
;
10586 struct pim_vxlan_sg
*vxlan_sg
;
10587 const char *iif_name
;
10589 const char *oif_name
;
10591 result
= inet_pton(AF_INET
, src_str
, &sg
.src
);
10593 vty_out(vty
, "Bad src address %s: errno=%d: %s\n", src_str
,
10594 errno
, safe_strerror(errno
));
10597 result
= inet_pton(AF_INET
, grp_str
, &sg
.grp
);
10599 vty_out(vty
, "Bad grp address %s: errno=%d: %s\n", grp_str
,
10600 errno
, safe_strerror(errno
));
10604 sg
.family
= AF_INET
;
10605 sg
.prefixlen
= IPV4_MAX_BITLEN
;
10607 json
= json_object_new_object();
10609 vxlan_sg
= pim_vxlan_sg_find(pim
, &sg
);
10611 installed
= (vxlan_sg
->up
) ? true : false;
10612 iif_name
= vxlan_sg
->iif
?vxlan_sg
->iif
->name
:"-";
10614 if (pim_vxlan_is_orig_mroute(vxlan_sg
))
10616 vxlan_sg
->orig_oif
?vxlan_sg
->orig_oif
->name
:"";
10619 vxlan_sg
->term_oif
?vxlan_sg
->term_oif
->name
:"";
10622 json_object_string_add(json
, "source", src_str
);
10623 json_object_string_add(json
, "group", grp_str
);
10624 json_object_string_add(json
, "input", iif_name
);
10625 json_object_string_add(json
, "output", oif_name
);
10627 json_object_boolean_true_add(json
, "installed");
10629 json_object_boolean_false_add(json
,
10632 vty_out(vty
, "SG : %s\n", vxlan_sg
->sg_str
);
10633 vty_out(vty
, " Input : %s\n", iif_name
);
10634 vty_out(vty
, " Output : %s\n", oif_name
);
10635 vty_out(vty
, " installed : %s\n",
10636 installed
?"yes":"no");
10641 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10642 json
, JSON_C_TO_STRING_PRETTY
));
10643 json_object_free(json
);
10647 DEFUN (show_ip_pim_vxlan_sg
,
10648 show_ip_pim_vxlan_sg_cmd
,
10649 "show ip pim [vrf NAME] vxlan-groups [A.B.C.D [A.B.C.D]] [json]",
10654 "VxLAN BUM groups\n"
10655 "source or group ip\n"
10659 bool uj
= use_json(argc
, argv
);
10663 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10666 return CMD_WARNING
;
10668 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ?
10669 argv
[idx
++]->arg
:NULL
;
10670 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
) ?
10671 argv
[idx
]->arg
:NULL
;
10673 if (src_ip
&& grp_ip
)
10674 pim_show_vxlan_sg_one(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
10676 pim_show_vxlan_sg_match_addr(vrf
->info
, vty
, src_ip
, uj
);
10678 pim_show_vxlan_sg(vrf
->info
, vty
, uj
);
10680 return CMD_SUCCESS
;
10683 static void pim_show_vxlan_sg_work(struct pim_instance
*pim
,
10684 struct vty
*vty
, bool uj
)
10686 json_object
*json
= NULL
;
10687 struct pim_sg_cache_walk_data cwd
;
10688 struct listnode
*node
;
10689 struct pim_vxlan_sg
*vxlan_sg
;
10692 json
= json_object_new_object();
10694 vty_out(vty
, "Codes: I -> installed\n");
10696 "Source Group Input Flags\n");
10699 memset(&cwd
, 0, sizeof(cwd
));
10702 for (ALL_LIST_ELEMENTS_RO(pim_vxlan_p
->work_list
, node
, vxlan_sg
))
10703 pim_show_vxlan_sg_entry(vxlan_sg
, &cwd
);
10706 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10707 json
, JSON_C_TO_STRING_PRETTY
));
10708 json_object_free(json
);
10712 DEFUN_HIDDEN (show_ip_pim_vxlan_sg_work
,
10713 show_ip_pim_vxlan_sg_work_cmd
,
10714 "show ip pim [vrf NAME] vxlan-work [json]",
10719 "VxLAN work list\n"
10722 bool uj
= use_json(argc
, argv
);
10726 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10729 return CMD_WARNING
;
10731 pim_show_vxlan_sg_work(vrf
->info
, vty
, uj
);
10733 return CMD_SUCCESS
;
10736 DEFUN_HIDDEN (no_ip_pim_mlag
,
10737 no_ip_pim_mlag_cmd
,
10744 struct in_addr addr
;
10747 pim_vxlan_mlag_update(true/*mlag_enable*/,
10748 false/*peer_state*/, MLAG_ROLE_NONE
,
10749 NULL
/*peerlink*/, &addr
);
10751 return CMD_SUCCESS
;
10754 DEFUN_HIDDEN (ip_pim_mlag
,
10756 "ip pim mlag INTERFACE role [primary|secondary] state [up|down] addr A.B.C.D",
10760 "peerlink sub interface\n"
10762 "MLAG role primary\n"
10763 "MLAG role secondary\n"
10764 "peer session state\n"
10765 "peer session state up\n"
10766 "peer session state down\n"
10768 "unique ip address\n")
10770 struct interface
*ifp
;
10771 const char *peerlink
;
10776 struct in_addr reg_addr
;
10779 peerlink
= argv
[idx
]->arg
;
10780 ifp
= if_lookup_by_name(peerlink
, VRF_DEFAULT
);
10782 vty_out(vty
, "No such interface name %s\n", peerlink
);
10783 return CMD_WARNING
;
10787 if (!strcmp(argv
[idx
]->arg
, "primary")) {
10788 role
= MLAG_ROLE_PRIMARY
;
10789 } else if (!strcmp(argv
[idx
]->arg
, "secondary")) {
10790 role
= MLAG_ROLE_SECONDARY
;
10792 vty_out(vty
, "unknown MLAG role %s\n", argv
[idx
]->arg
);
10793 return CMD_WARNING
;
10797 if (!strcmp(argv
[idx
]->arg
, "up")) {
10799 } else if (strcmp(argv
[idx
]->arg
, "down")) {
10800 peer_state
= false;
10802 vty_out(vty
, "unknown MLAG state %s\n", argv
[idx
]->arg
);
10803 return CMD_WARNING
;
10807 result
= inet_pton(AF_INET
, argv
[idx
]->arg
, ®_addr
);
10809 vty_out(vty
, "%% Bad reg address %s: errno=%d: %s\n",
10811 errno
, safe_strerror(errno
));
10812 return CMD_WARNING_CONFIG_FAILED
;
10814 pim_vxlan_mlag_update(true, peer_state
, role
, ifp
, ®_addr
);
10816 return CMD_SUCCESS
;
10819 void pim_cmd_init(void)
10821 install_node(&interface_node
,
10822 pim_interface_config_write
); /* INTERFACE_NODE */
10825 install_node(&debug_node
, pim_debug_config_write
);
10827 install_element(ENABLE_NODE
, &pim_test_sg_keepalive_cmd
);
10829 install_element(CONFIG_NODE
, &ip_pim_rp_cmd
);
10830 install_element(VRF_NODE
, &ip_pim_rp_cmd
);
10831 install_element(CONFIG_NODE
, &no_ip_pim_rp_cmd
);
10832 install_element(VRF_NODE
, &no_ip_pim_rp_cmd
);
10833 install_element(CONFIG_NODE
, &ip_pim_rp_prefix_list_cmd
);
10834 install_element(VRF_NODE
, &ip_pim_rp_prefix_list_cmd
);
10835 install_element(CONFIG_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
10836 install_element(VRF_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
10837 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
10838 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
10839 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
10840 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
10841 install_element(CONFIG_NODE
, &ip_pim_ssm_prefix_list_cmd
);
10842 install_element(VRF_NODE
, &ip_pim_ssm_prefix_list_cmd
);
10843 install_element(CONFIG_NODE
, &ip_pim_register_suppress_cmd
);
10844 install_element(VRF_NODE
, &ip_pim_register_suppress_cmd
);
10845 install_element(CONFIG_NODE
, &no_ip_pim_register_suppress_cmd
);
10846 install_element(VRF_NODE
, &no_ip_pim_register_suppress_cmd
);
10847 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
10848 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
10849 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
10850 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
10851 install_element(CONFIG_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
10852 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
10853 install_element(CONFIG_NODE
,
10854 &no_ip_pim_spt_switchover_infinity_plist_cmd
);
10855 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_plist_cmd
);
10856 install_element(CONFIG_NODE
, &pim_register_accept_list_cmd
);
10857 install_element(VRF_NODE
, &pim_register_accept_list_cmd
);
10858 install_element(CONFIG_NODE
, &ip_pim_joinprune_time_cmd
);
10859 install_element(VRF_NODE
, &ip_pim_joinprune_time_cmd
);
10860 install_element(CONFIG_NODE
, &no_ip_pim_joinprune_time_cmd
);
10861 install_element(VRF_NODE
, &no_ip_pim_joinprune_time_cmd
);
10862 install_element(CONFIG_NODE
, &ip_pim_keep_alive_cmd
);
10863 install_element(VRF_NODE
, &ip_pim_keep_alive_cmd
);
10864 install_element(CONFIG_NODE
, &ip_pim_rp_keep_alive_cmd
);
10865 install_element(VRF_NODE
, &ip_pim_rp_keep_alive_cmd
);
10866 install_element(CONFIG_NODE
, &no_ip_pim_keep_alive_cmd
);
10867 install_element(VRF_NODE
, &no_ip_pim_keep_alive_cmd
);
10868 install_element(CONFIG_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
10869 install_element(VRF_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
10870 install_element(CONFIG_NODE
, &ip_pim_packets_cmd
);
10871 install_element(VRF_NODE
, &ip_pim_packets_cmd
);
10872 install_element(CONFIG_NODE
, &no_ip_pim_packets_cmd
);
10873 install_element(VRF_NODE
, &no_ip_pim_packets_cmd
);
10874 install_element(CONFIG_NODE
, &ip_pim_v6_secondary_cmd
);
10875 install_element(VRF_NODE
, &ip_pim_v6_secondary_cmd
);
10876 install_element(CONFIG_NODE
, &no_ip_pim_v6_secondary_cmd
);
10877 install_element(VRF_NODE
, &no_ip_pim_v6_secondary_cmd
);
10878 install_element(CONFIG_NODE
, &ip_ssmpingd_cmd
);
10879 install_element(VRF_NODE
, &ip_ssmpingd_cmd
);
10880 install_element(CONFIG_NODE
, &no_ip_ssmpingd_cmd
);
10881 install_element(VRF_NODE
, &no_ip_ssmpingd_cmd
);
10882 install_element(CONFIG_NODE
, &ip_msdp_peer_cmd
);
10883 install_element(VRF_NODE
, &ip_msdp_peer_cmd
);
10884 install_element(CONFIG_NODE
, &no_ip_msdp_peer_cmd
);
10885 install_element(VRF_NODE
, &no_ip_msdp_peer_cmd
);
10886 install_element(CONFIG_NODE
, &ip_pim_ecmp_cmd
);
10887 install_element(VRF_NODE
, &ip_pim_ecmp_cmd
);
10888 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_cmd
);
10889 install_element(VRF_NODE
, &no_ip_pim_ecmp_cmd
);
10890 install_element(CONFIG_NODE
, &ip_pim_ecmp_rebalance_cmd
);
10891 install_element(VRF_NODE
, &ip_pim_ecmp_rebalance_cmd
);
10892 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
10893 install_element(VRF_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
10894 install_element(CONFIG_NODE
, &ip_pim_mlag_cmd
);
10895 install_element(CONFIG_NODE
, &no_ip_pim_mlag_cmd
);
10897 install_element(INTERFACE_NODE
, &interface_ip_igmp_cmd
);
10898 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_cmd
);
10899 install_element(INTERFACE_NODE
, &interface_ip_igmp_join_cmd
);
10900 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_join_cmd
);
10901 install_element(INTERFACE_NODE
, &interface_ip_igmp_version_cmd
);
10902 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_version_cmd
);
10903 install_element(INTERFACE_NODE
, &interface_ip_igmp_query_interval_cmd
);
10904 install_element(INTERFACE_NODE
,
10905 &interface_no_ip_igmp_query_interval_cmd
);
10906 install_element(INTERFACE_NODE
,
10907 &interface_ip_igmp_query_max_response_time_cmd
);
10908 install_element(INTERFACE_NODE
,
10909 &interface_no_ip_igmp_query_max_response_time_cmd
);
10910 install_element(INTERFACE_NODE
,
10911 &interface_ip_igmp_query_max_response_time_dsec_cmd
);
10912 install_element(INTERFACE_NODE
,
10913 &interface_no_ip_igmp_query_max_response_time_dsec_cmd
);
10914 install_element(INTERFACE_NODE
,
10915 &interface_ip_igmp_last_member_query_count_cmd
);
10916 install_element(INTERFACE_NODE
,
10917 &interface_no_ip_igmp_last_member_query_count_cmd
);
10918 install_element(INTERFACE_NODE
,
10919 &interface_ip_igmp_last_member_query_interval_cmd
);
10920 install_element(INTERFACE_NODE
,
10921 &interface_no_ip_igmp_last_member_query_interval_cmd
);
10922 install_element(INTERFACE_NODE
, &interface_ip_pim_activeactive_cmd
);
10923 install_element(INTERFACE_NODE
, &interface_ip_pim_ssm_cmd
);
10924 install_element(INTERFACE_NODE
, &interface_no_ip_pim_ssm_cmd
);
10925 install_element(INTERFACE_NODE
, &interface_ip_pim_sm_cmd
);
10926 install_element(INTERFACE_NODE
, &interface_no_ip_pim_sm_cmd
);
10927 install_element(INTERFACE_NODE
, &interface_ip_pim_cmd
);
10928 install_element(INTERFACE_NODE
, &interface_no_ip_pim_cmd
);
10929 install_element(INTERFACE_NODE
, &interface_ip_pim_drprio_cmd
);
10930 install_element(INTERFACE_NODE
, &interface_no_ip_pim_drprio_cmd
);
10931 install_element(INTERFACE_NODE
, &interface_ip_pim_hello_cmd
);
10932 install_element(INTERFACE_NODE
, &interface_no_ip_pim_hello_cmd
);
10933 install_element(INTERFACE_NODE
, &interface_ip_pim_boundary_oil_cmd
);
10934 install_element(INTERFACE_NODE
, &interface_no_ip_pim_boundary_oil_cmd
);
10935 install_element(INTERFACE_NODE
, &interface_ip_igmp_query_generate_cmd
);
10937 // Static mroutes NEB
10938 install_element(INTERFACE_NODE
, &interface_ip_mroute_cmd
);
10939 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_cmd
);
10941 install_element(VIEW_NODE
, &show_ip_igmp_interface_cmd
);
10942 install_element(VIEW_NODE
, &show_ip_igmp_interface_vrf_all_cmd
);
10943 install_element(VIEW_NODE
, &show_ip_igmp_join_cmd
);
10944 install_element(VIEW_NODE
, &show_ip_igmp_join_vrf_all_cmd
);
10945 install_element(VIEW_NODE
, &show_ip_igmp_groups_cmd
);
10946 install_element(VIEW_NODE
, &show_ip_igmp_groups_vrf_all_cmd
);
10947 install_element(VIEW_NODE
, &show_ip_igmp_groups_retransmissions_cmd
);
10948 install_element(VIEW_NODE
, &show_ip_igmp_sources_cmd
);
10949 install_element(VIEW_NODE
, &show_ip_igmp_sources_retransmissions_cmd
);
10950 install_element(VIEW_NODE
, &show_ip_igmp_statistics_cmd
);
10951 install_element(VIEW_NODE
, &show_ip_pim_assert_cmd
);
10952 install_element(VIEW_NODE
, &show_ip_pim_assert_internal_cmd
);
10953 install_element(VIEW_NODE
, &show_ip_pim_assert_metric_cmd
);
10954 install_element(VIEW_NODE
, &show_ip_pim_assert_winner_metric_cmd
);
10955 install_element(VIEW_NODE
, &show_ip_pim_interface_traffic_cmd
);
10956 install_element(VIEW_NODE
, &show_ip_pim_interface_cmd
);
10957 install_element(VIEW_NODE
, &show_ip_pim_interface_vrf_all_cmd
);
10958 install_element(VIEW_NODE
, &show_ip_pim_join_cmd
);
10959 install_element(VIEW_NODE
, &show_ip_pim_join_vrf_all_cmd
);
10960 install_element(VIEW_NODE
, &show_ip_pim_jp_agg_cmd
);
10961 install_element(VIEW_NODE
, &show_ip_pim_local_membership_cmd
);
10962 install_element(VIEW_NODE
, &show_ip_pim_mlag_summary_cmd
);
10963 install_element(VIEW_NODE
, &show_ip_pim_mlag_up_cmd
);
10964 install_element(VIEW_NODE
, &show_ip_pim_mlag_up_vrf_all_cmd
);
10965 install_element(VIEW_NODE
, &show_ip_pim_neighbor_cmd
);
10966 install_element(VIEW_NODE
, &show_ip_pim_neighbor_vrf_all_cmd
);
10967 install_element(VIEW_NODE
, &show_ip_pim_rpf_cmd
);
10968 install_element(VIEW_NODE
, &show_ip_pim_rpf_vrf_all_cmd
);
10969 install_element(VIEW_NODE
, &show_ip_pim_secondary_cmd
);
10970 install_element(VIEW_NODE
, &show_ip_pim_state_cmd
);
10971 install_element(VIEW_NODE
, &show_ip_pim_state_vrf_all_cmd
);
10972 install_element(VIEW_NODE
, &show_ip_pim_upstream_cmd
);
10973 install_element(VIEW_NODE
, &show_ip_pim_upstream_vrf_all_cmd
);
10974 install_element(VIEW_NODE
, &show_ip_pim_channel_cmd
);
10975 install_element(VIEW_NODE
, &show_ip_pim_upstream_join_desired_cmd
);
10976 install_element(VIEW_NODE
, &show_ip_pim_upstream_rpf_cmd
);
10977 install_element(VIEW_NODE
, &show_ip_pim_rp_cmd
);
10978 install_element(VIEW_NODE
, &show_ip_pim_rp_vrf_all_cmd
);
10979 install_element(VIEW_NODE
, &show_ip_pim_bsr_cmd
);
10980 install_element(VIEW_NODE
, &show_ip_multicast_cmd
);
10981 install_element(VIEW_NODE
, &show_ip_multicast_vrf_all_cmd
);
10982 install_element(VIEW_NODE
, &show_ip_mroute_cmd
);
10983 install_element(VIEW_NODE
, &show_ip_mroute_vrf_all_cmd
);
10984 install_element(VIEW_NODE
, &show_ip_mroute_count_cmd
);
10985 install_element(VIEW_NODE
, &show_ip_mroute_count_vrf_all_cmd
);
10986 install_element(VIEW_NODE
, &show_ip_mroute_summary_cmd
);
10987 install_element(VIEW_NODE
, &show_ip_mroute_summary_vrf_all_cmd
);
10988 install_element(VIEW_NODE
, &show_ip_rib_cmd
);
10989 install_element(VIEW_NODE
, &show_ip_ssmpingd_cmd
);
10990 install_element(VIEW_NODE
, &show_debugging_pim_cmd
);
10991 install_element(VIEW_NODE
, &show_ip_pim_nexthop_cmd
);
10992 install_element(VIEW_NODE
, &show_ip_pim_nexthop_lookup_cmd
);
10993 install_element(VIEW_NODE
, &show_ip_pim_bsrp_cmd
);
10994 install_element(VIEW_NODE
, &show_ip_pim_bsm_db_cmd
);
10995 install_element(VIEW_NODE
, &show_ip_pim_statistics_cmd
);
10997 install_element(ENABLE_NODE
, &clear_ip_mroute_count_cmd
);
10998 install_element(ENABLE_NODE
, &clear_ip_interfaces_cmd
);
10999 install_element(ENABLE_NODE
, &clear_ip_igmp_interfaces_cmd
);
11000 install_element(ENABLE_NODE
, &clear_ip_mroute_cmd
);
11001 install_element(ENABLE_NODE
, &clear_ip_pim_interfaces_cmd
);
11002 install_element(ENABLE_NODE
, &clear_ip_pim_interface_traffic_cmd
);
11003 install_element(ENABLE_NODE
, &clear_ip_pim_oil_cmd
);
11004 install_element(ENABLE_NODE
, &clear_ip_pim_statistics_cmd
);
11006 install_element(ENABLE_NODE
, &debug_igmp_cmd
);
11007 install_element(ENABLE_NODE
, &no_debug_igmp_cmd
);
11008 install_element(ENABLE_NODE
, &debug_igmp_events_cmd
);
11009 install_element(ENABLE_NODE
, &no_debug_igmp_events_cmd
);
11010 install_element(ENABLE_NODE
, &debug_igmp_packets_cmd
);
11011 install_element(ENABLE_NODE
, &no_debug_igmp_packets_cmd
);
11012 install_element(ENABLE_NODE
, &debug_igmp_trace_cmd
);
11013 install_element(ENABLE_NODE
, &no_debug_igmp_trace_cmd
);
11014 install_element(ENABLE_NODE
, &debug_mroute_cmd
);
11015 install_element(ENABLE_NODE
, &debug_mroute_detail_cmd
);
11016 install_element(ENABLE_NODE
, &no_debug_mroute_cmd
);
11017 install_element(ENABLE_NODE
, &no_debug_mroute_detail_cmd
);
11018 install_element(ENABLE_NODE
, &debug_pim_static_cmd
);
11019 install_element(ENABLE_NODE
, &no_debug_pim_static_cmd
);
11020 install_element(ENABLE_NODE
, &debug_pim_cmd
);
11021 install_element(ENABLE_NODE
, &no_debug_pim_cmd
);
11022 install_element(ENABLE_NODE
, &debug_pim_nht_cmd
);
11023 install_element(ENABLE_NODE
, &no_debug_pim_nht_cmd
);
11024 install_element(ENABLE_NODE
, &debug_pim_nht_rp_cmd
);
11025 install_element(ENABLE_NODE
, &no_debug_pim_nht_rp_cmd
);
11026 install_element(ENABLE_NODE
, &debug_pim_events_cmd
);
11027 install_element(ENABLE_NODE
, &no_debug_pim_events_cmd
);
11028 install_element(ENABLE_NODE
, &debug_pim_packets_cmd
);
11029 install_element(ENABLE_NODE
, &no_debug_pim_packets_cmd
);
11030 install_element(ENABLE_NODE
, &debug_pim_packetdump_send_cmd
);
11031 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_send_cmd
);
11032 install_element(ENABLE_NODE
, &debug_pim_packetdump_recv_cmd
);
11033 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_recv_cmd
);
11034 install_element(ENABLE_NODE
, &debug_pim_trace_cmd
);
11035 install_element(ENABLE_NODE
, &no_debug_pim_trace_cmd
);
11036 install_element(ENABLE_NODE
, &debug_pim_trace_detail_cmd
);
11037 install_element(ENABLE_NODE
, &no_debug_pim_trace_detail_cmd
);
11038 install_element(ENABLE_NODE
, &debug_ssmpingd_cmd
);
11039 install_element(ENABLE_NODE
, &no_debug_ssmpingd_cmd
);
11040 install_element(ENABLE_NODE
, &debug_pim_zebra_cmd
);
11041 install_element(ENABLE_NODE
, &no_debug_pim_zebra_cmd
);
11042 install_element(ENABLE_NODE
, &debug_pim_mlag_cmd
);
11043 install_element(ENABLE_NODE
, &no_debug_pim_mlag_cmd
);
11044 install_element(ENABLE_NODE
, &debug_pim_vxlan_cmd
);
11045 install_element(ENABLE_NODE
, &no_debug_pim_vxlan_cmd
);
11046 install_element(ENABLE_NODE
, &debug_msdp_cmd
);
11047 install_element(ENABLE_NODE
, &no_debug_msdp_cmd
);
11048 install_element(ENABLE_NODE
, &debug_msdp_events_cmd
);
11049 install_element(ENABLE_NODE
, &no_debug_msdp_events_cmd
);
11050 install_element(ENABLE_NODE
, &debug_msdp_packets_cmd
);
11051 install_element(ENABLE_NODE
, &no_debug_msdp_packets_cmd
);
11052 install_element(ENABLE_NODE
, &debug_mtrace_cmd
);
11053 install_element(ENABLE_NODE
, &no_debug_mtrace_cmd
);
11054 install_element(ENABLE_NODE
, &debug_bsm_cmd
);
11055 install_element(ENABLE_NODE
, &no_debug_bsm_cmd
);
11057 install_element(CONFIG_NODE
, &debug_igmp_cmd
);
11058 install_element(CONFIG_NODE
, &no_debug_igmp_cmd
);
11059 install_element(CONFIG_NODE
, &debug_igmp_events_cmd
);
11060 install_element(CONFIG_NODE
, &no_debug_igmp_events_cmd
);
11061 install_element(CONFIG_NODE
, &debug_igmp_packets_cmd
);
11062 install_element(CONFIG_NODE
, &no_debug_igmp_packets_cmd
);
11063 install_element(CONFIG_NODE
, &debug_igmp_trace_cmd
);
11064 install_element(CONFIG_NODE
, &no_debug_igmp_trace_cmd
);
11065 install_element(CONFIG_NODE
, &debug_mroute_cmd
);
11066 install_element(CONFIG_NODE
, &debug_mroute_detail_cmd
);
11067 install_element(CONFIG_NODE
, &no_debug_mroute_cmd
);
11068 install_element(CONFIG_NODE
, &no_debug_mroute_detail_cmd
);
11069 install_element(CONFIG_NODE
, &debug_pim_static_cmd
);
11070 install_element(CONFIG_NODE
, &no_debug_pim_static_cmd
);
11071 install_element(CONFIG_NODE
, &debug_pim_cmd
);
11072 install_element(CONFIG_NODE
, &no_debug_pim_cmd
);
11073 install_element(CONFIG_NODE
, &debug_pim_nht_cmd
);
11074 install_element(CONFIG_NODE
, &no_debug_pim_nht_cmd
);
11075 install_element(CONFIG_NODE
, &debug_pim_nht_rp_cmd
);
11076 install_element(CONFIG_NODE
, &no_debug_pim_nht_rp_cmd
);
11077 install_element(CONFIG_NODE
, &debug_pim_events_cmd
);
11078 install_element(CONFIG_NODE
, &no_debug_pim_events_cmd
);
11079 install_element(CONFIG_NODE
, &debug_pim_packets_cmd
);
11080 install_element(CONFIG_NODE
, &no_debug_pim_packets_cmd
);
11081 install_element(CONFIG_NODE
, &debug_pim_trace_cmd
);
11082 install_element(CONFIG_NODE
, &no_debug_pim_trace_cmd
);
11083 install_element(CONFIG_NODE
, &debug_pim_trace_detail_cmd
);
11084 install_element(CONFIG_NODE
, &no_debug_pim_trace_detail_cmd
);
11085 install_element(CONFIG_NODE
, &debug_ssmpingd_cmd
);
11086 install_element(CONFIG_NODE
, &no_debug_ssmpingd_cmd
);
11087 install_element(CONFIG_NODE
, &debug_pim_zebra_cmd
);
11088 install_element(CONFIG_NODE
, &no_debug_pim_zebra_cmd
);
11089 install_element(CONFIG_NODE
, &debug_pim_mlag_cmd
);
11090 install_element(CONFIG_NODE
, &no_debug_pim_mlag_cmd
);
11091 install_element(CONFIG_NODE
, &debug_pim_vxlan_cmd
);
11092 install_element(CONFIG_NODE
, &no_debug_pim_vxlan_cmd
);
11093 install_element(CONFIG_NODE
, &debug_msdp_cmd
);
11094 install_element(CONFIG_NODE
, &no_debug_msdp_cmd
);
11095 install_element(CONFIG_NODE
, &debug_msdp_events_cmd
);
11096 install_element(CONFIG_NODE
, &no_debug_msdp_events_cmd
);
11097 install_element(CONFIG_NODE
, &debug_msdp_packets_cmd
);
11098 install_element(CONFIG_NODE
, &no_debug_msdp_packets_cmd
);
11099 install_element(CONFIG_NODE
, &debug_mtrace_cmd
);
11100 install_element(CONFIG_NODE
, &no_debug_mtrace_cmd
);
11101 install_element(CONFIG_NODE
, &debug_bsm_cmd
);
11102 install_element(CONFIG_NODE
, &no_debug_bsm_cmd
);
11104 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_member_cmd
);
11105 install_element(VRF_NODE
, &ip_msdp_mesh_group_member_cmd
);
11106 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
11107 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
11108 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_source_cmd
);
11109 install_element(VRF_NODE
, &ip_msdp_mesh_group_source_cmd
);
11110 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
11111 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
11112 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_cmd
);
11113 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_vrf_all_cmd
);
11114 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_cmd
);
11115 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_vrf_all_cmd
);
11116 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_cmd
);
11117 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_vrf_all_cmd
);
11118 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_cmd
);
11119 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_vrf_all_cmd
);
11120 install_element(VIEW_NODE
, &show_ip_pim_ssm_range_cmd
);
11121 install_element(VIEW_NODE
, &show_ip_pim_group_type_cmd
);
11122 install_element(VIEW_NODE
, &show_ip_pim_vxlan_sg_cmd
);
11123 install_element(VIEW_NODE
, &show_ip_pim_vxlan_sg_work_cmd
);
11124 install_element(INTERFACE_NODE
, &interface_pim_use_source_cmd
);
11125 install_element(INTERFACE_NODE
, &interface_no_pim_use_source_cmd
);
11126 /* Install BSM command */
11127 install_element(INTERFACE_NODE
, &ip_pim_bsm_cmd
);
11128 install_element(INTERFACE_NODE
, &no_ip_pim_bsm_cmd
);
11129 install_element(INTERFACE_NODE
, &ip_pim_ucast_bsm_cmd
);
11130 install_element(INTERFACE_NODE
, &no_ip_pim_ucast_bsm_cmd
);
11131 /* Install BFD command */
11132 install_element(INTERFACE_NODE
, &ip_pim_bfd_cmd
);
11133 install_element(INTERFACE_NODE
, &ip_pim_bfd_param_cmd
);
11134 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_cmd
);
11136 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_param_cmd
);
11137 #endif /* !HAVE_BFDD */