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
, "registerRx",
1524 pim_ifp
->pim_ifstat_reg_recv
);
1525 json_object_int_add(json_row
, "registerTx",
1526 pim_ifp
->pim_ifstat_reg_recv
);
1527 json_object_int_add(json_row
, "registerStopRx",
1528 pim_ifp
->pim_ifstat_reg_stop_recv
);
1529 json_object_int_add(json_row
, "registerStopTx",
1530 pim_ifp
->pim_ifstat_reg_stop_send
);
1531 json_object_int_add(json_row
, "assertRx",
1532 pim_ifp
->pim_ifstat_assert_recv
);
1533 json_object_int_add(json_row
, "assertTx",
1534 pim_ifp
->pim_ifstat_assert_send
);
1535 json_object_int_add(json_row
, "bsmRx",
1536 pim_ifp
->pim_ifstat_bsm_rx
);
1537 json_object_int_add(json_row
, "bsmTx",
1538 pim_ifp
->pim_ifstat_bsm_tx
);
1539 json_object_object_add(json
, ifp
->name
, json_row
);
1542 "%-16s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7" PRIu64
"/%-7" PRIu64
"\n",
1543 ifp
->name
, pim_ifp
->pim_ifstat_hello_recv
,
1544 pim_ifp
->pim_ifstat_hello_sent
,
1545 pim_ifp
->pim_ifstat_join_recv
,
1546 pim_ifp
->pim_ifstat_join_send
,
1547 pim_ifp
->pim_ifstat_prune_recv
,
1548 pim_ifp
->pim_ifstat_prune_send
,
1549 pim_ifp
->pim_ifstat_reg_recv
,
1550 pim_ifp
->pim_ifstat_reg_send
,
1551 pim_ifp
->pim_ifstat_reg_stop_recv
,
1552 pim_ifp
->pim_ifstat_reg_stop_send
,
1553 pim_ifp
->pim_ifstat_assert_recv
,
1554 pim_ifp
->pim_ifstat_assert_send
,
1555 pim_ifp
->pim_ifstat_bsm_rx
,
1556 pim_ifp
->pim_ifstat_bsm_tx
);
1560 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1561 json
, JSON_C_TO_STRING_PRETTY
));
1562 json_object_free(json
);
1566 static void pim_show_interface_traffic_single(struct pim_instance
*pim
,
1568 const char *ifname
, bool uj
)
1570 struct interface
*ifp
= NULL
;
1571 struct pim_interface
*pim_ifp
= NULL
;
1572 json_object
*json
= NULL
;
1573 json_object
*json_row
= NULL
;
1574 uint8_t found_ifname
= 0;
1577 json
= json_object_new_object();
1580 vty_out(vty
, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s%-17s\n",
1581 "Interface", " HELLO", " JOIN", " PRUNE",
1582 " REGISTER", " REGISTER-STOP", " ASSERT",
1584 vty_out(vty
, "%-14s%-18s%-17s%-17s%-17s%-17s%-17s%-17s\n", "",
1585 " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1586 " Rx/Tx", " Rx/Tx", " Rx/Tx");
1588 "-------------------------------------------------------------------------------------------------------------------------------\n");
1591 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1592 if (strcmp(ifname
, ifp
->name
))
1595 pim_ifp
= ifp
->info
;
1600 if (pim_ifp
->pim_sock_fd
< 0)
1605 json_row
= json_object_new_object();
1606 json_object_pim_ifp_add(json_row
, ifp
);
1607 json_object_int_add(json_row
, "helloRx",
1608 pim_ifp
->pim_ifstat_hello_recv
);
1609 json_object_int_add(json_row
, "helloTx",
1610 pim_ifp
->pim_ifstat_hello_sent
);
1611 json_object_int_add(json_row
, "joinRx",
1612 pim_ifp
->pim_ifstat_join_recv
);
1613 json_object_int_add(json_row
, "joinTx",
1614 pim_ifp
->pim_ifstat_join_send
);
1615 json_object_int_add(json_row
, "registerRx",
1616 pim_ifp
->pim_ifstat_reg_recv
);
1617 json_object_int_add(json_row
, "registerTx",
1618 pim_ifp
->pim_ifstat_reg_recv
);
1619 json_object_int_add(json_row
, "registerStopRx",
1620 pim_ifp
->pim_ifstat_reg_stop_recv
);
1621 json_object_int_add(json_row
, "registerStopTx",
1622 pim_ifp
->pim_ifstat_reg_stop_send
);
1623 json_object_int_add(json_row
, "assertRx",
1624 pim_ifp
->pim_ifstat_assert_recv
);
1625 json_object_int_add(json_row
, "assertTx",
1626 pim_ifp
->pim_ifstat_assert_send
);
1627 json_object_int_add(json_row
, "bsmRx",
1628 pim_ifp
->pim_ifstat_bsm_rx
);
1629 json_object_int_add(json_row
, "bsmTx",
1630 pim_ifp
->pim_ifstat_bsm_tx
);
1632 json_object_object_add(json
, ifp
->name
, json_row
);
1635 "%-16s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7" PRIu64
"/%-7" PRIu64
"\n",
1636 ifp
->name
, pim_ifp
->pim_ifstat_hello_recv
,
1637 pim_ifp
->pim_ifstat_hello_sent
,
1638 pim_ifp
->pim_ifstat_join_recv
,
1639 pim_ifp
->pim_ifstat_join_send
,
1640 pim_ifp
->pim_ifstat_prune_recv
,
1641 pim_ifp
->pim_ifstat_prune_send
,
1642 pim_ifp
->pim_ifstat_reg_recv
,
1643 pim_ifp
->pim_ifstat_reg_send
,
1644 pim_ifp
->pim_ifstat_reg_stop_recv
,
1645 pim_ifp
->pim_ifstat_reg_stop_send
,
1646 pim_ifp
->pim_ifstat_assert_recv
,
1647 pim_ifp
->pim_ifstat_assert_send
,
1648 pim_ifp
->pim_ifstat_bsm_rx
,
1649 pim_ifp
->pim_ifstat_bsm_tx
);
1653 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1654 json
, JSON_C_TO_STRING_PRETTY
));
1655 json_object_free(json
);
1658 vty_out(vty
, "%% No such interface\n");
1662 static void pim_show_join_helper(struct vty
*vty
, struct pim_interface
*pim_ifp
,
1663 struct pim_ifchannel
*ch
, json_object
*json
,
1664 time_t now
, bool uj
)
1666 char ch_src_str
[INET_ADDRSTRLEN
];
1667 char ch_grp_str
[INET_ADDRSTRLEN
];
1668 json_object
*json_iface
= NULL
;
1669 json_object
*json_row
= NULL
;
1670 json_object
*json_grp
= NULL
;
1671 struct in_addr ifaddr
;
1676 ifaddr
= pim_ifp
->primary_address
;
1678 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
1679 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
1681 pim_time_uptime_begin(uptime
, sizeof(uptime
), now
, ch
->ifjoin_creation
);
1682 pim_time_timer_to_mmss(expire
, sizeof(expire
),
1683 ch
->t_ifjoin_expiry_timer
);
1684 pim_time_timer_to_mmss(prune
, sizeof(prune
),
1685 ch
->t_ifjoin_prune_pending_timer
);
1688 json_object_object_get_ex(json
, ch
->interface
->name
,
1692 json_iface
= json_object_new_object();
1693 json_object_pim_ifp_add(json_iface
, ch
->interface
);
1694 json_object_object_add(json
, ch
->interface
->name
,
1698 json_row
= json_object_new_object();
1699 json_object_string_add(json_row
, "source", ch_src_str
);
1700 json_object_string_add(json_row
, "group", ch_grp_str
);
1701 json_object_string_add(json_row
, "upTime", uptime
);
1702 json_object_string_add(json_row
, "expire", expire
);
1703 json_object_string_add(json_row
, "prune", prune
);
1704 json_object_string_add(
1705 json_row
, "channelJoinName",
1706 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
, ch
->flags
));
1707 if (PIM_IF_FLAG_TEST_S_G_RPT(ch
->flags
))
1708 json_object_int_add(json_row
, "SGRpt", 1);
1710 json_object_object_get_ex(json_iface
, ch_grp_str
, &json_grp
);
1712 json_grp
= json_object_new_object();
1713 json_object_object_add(json_grp
, ch_src_str
, json_row
);
1714 json_object_object_add(json_iface
, ch_grp_str
,
1717 json_object_object_add(json_grp
, ch_src_str
, json_row
);
1719 vty_out(vty
, "%-16s %-15s %-15s %-15s %-10s %8s %-6s %5s\n",
1720 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
,
1722 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
, ch
->flags
),
1723 uptime
, expire
, prune
);
1727 static void pim_show_join(struct pim_instance
*pim
, struct vty
*vty
,
1728 struct prefix_sg
*sg
, bool uj
)
1730 struct pim_interface
*pim_ifp
;
1731 struct pim_ifchannel
*ch
;
1732 struct interface
*ifp
;
1734 json_object
*json
= NULL
;
1736 now
= pim_time_monotonic_sec();
1739 json
= json_object_new_object();
1742 "Interface Address Source Group State Uptime Expire Prune\n");
1744 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1745 pim_ifp
= ifp
->info
;
1749 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
1750 if (sg
->grp
.s_addr
!= INADDR_ANY
1751 && sg
->grp
.s_addr
!= ch
->sg
.grp
.s_addr
)
1753 if (sg
->src
.s_addr
!= INADDR_ANY
1754 && sg
->src
.s_addr
!= ch
->sg
.src
.s_addr
)
1756 pim_show_join_helper(vty
, pim_ifp
, ch
, json
, now
, uj
);
1757 } /* scan interface channels */
1761 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1762 json
, JSON_C_TO_STRING_PRETTY
));
1763 json_object_free(json
);
1767 static void pim_show_neighbors_single(struct pim_instance
*pim
, struct vty
*vty
,
1768 const char *neighbor
, bool uj
)
1770 struct listnode
*neighnode
;
1771 struct interface
*ifp
;
1772 struct pim_interface
*pim_ifp
;
1773 struct pim_neighbor
*neigh
;
1775 int found_neighbor
= 0;
1776 int option_address_list
;
1777 int option_dr_priority
;
1778 int option_generation_id
;
1779 int option_holdtime
;
1780 int option_lan_prune_delay
;
1784 char neigh_src_str
[INET_ADDRSTRLEN
];
1786 json_object
*json
= NULL
;
1787 json_object
*json_ifp
= NULL
;
1788 json_object
*json_row
= NULL
;
1790 now
= pim_time_monotonic_sec();
1793 json
= json_object_new_object();
1795 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1796 pim_ifp
= ifp
->info
;
1801 if (pim_ifp
->pim_sock_fd
< 0)
1804 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
1806 pim_inet4_dump("<src?>", neigh
->source_addr
,
1807 neigh_src_str
, sizeof(neigh_src_str
));
1810 * The user can specify either the interface name or the
1812 * If this pim_ifp matches neither then skip.
1814 if (strcmp(neighbor
, "detail")
1815 && strcmp(neighbor
, ifp
->name
)
1816 && strcmp(neighbor
, neigh_src_str
))
1820 pim_time_uptime(uptime
, sizeof(uptime
),
1821 now
- neigh
->creation
);
1822 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
1823 neigh
->t_expire_timer
);
1825 option_address_list
= 0;
1826 option_dr_priority
= 0;
1827 option_generation_id
= 0;
1828 option_holdtime
= 0;
1829 option_lan_prune_delay
= 0;
1832 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1833 PIM_OPTION_MASK_ADDRESS_LIST
))
1834 option_address_list
= 1;
1836 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1837 PIM_OPTION_MASK_DR_PRIORITY
))
1838 option_dr_priority
= 1;
1840 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1841 PIM_OPTION_MASK_GENERATION_ID
))
1842 option_generation_id
= 1;
1844 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1845 PIM_OPTION_MASK_HOLDTIME
))
1846 option_holdtime
= 1;
1848 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1849 PIM_OPTION_MASK_LAN_PRUNE_DELAY
))
1850 option_lan_prune_delay
= 1;
1852 if (PIM_OPTION_IS_SET(
1853 neigh
->hello_options
,
1854 PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION
))
1859 /* Does this ifp live in json? If not create
1861 json_object_object_get_ex(json
, ifp
->name
,
1865 json_ifp
= json_object_new_object();
1866 json_object_pim_ifp_add(json_ifp
, ifp
);
1867 json_object_object_add(json
, ifp
->name
,
1871 json_row
= json_object_new_object();
1872 json_object_string_add(json_row
, "interface",
1874 json_object_string_add(json_row
, "address",
1876 json_object_string_add(json_row
, "upTime",
1878 json_object_string_add(json_row
, "holdtime",
1880 json_object_int_add(json_row
, "drPriority",
1881 neigh
->dr_priority
);
1882 json_object_int_add(json_row
, "generationId",
1883 neigh
->generation_id
);
1885 if (option_address_list
)
1886 json_object_boolean_true_add(
1888 "helloOptionAddressList");
1890 if (option_dr_priority
)
1891 json_object_boolean_true_add(
1893 "helloOptionDrPriority");
1895 if (option_generation_id
)
1896 json_object_boolean_true_add(
1898 "helloOptionGenerationId");
1900 if (option_holdtime
)
1901 json_object_boolean_true_add(
1903 "helloOptionHoldtime");
1905 if (option_lan_prune_delay
)
1906 json_object_boolean_true_add(
1908 "helloOptionLanPruneDelay");
1911 json_object_boolean_true_add(
1912 json_row
, "helloOptionTBit");
1914 json_object_object_add(json_ifp
, neigh_src_str
,
1918 vty_out(vty
, "Interface : %s\n", ifp
->name
);
1919 vty_out(vty
, "Neighbor : %s\n", neigh_src_str
);
1927 " DR Priority : %d\n",
1928 neigh
->dr_priority
);
1930 " Generation ID : %08x\n",
1931 neigh
->generation_id
);
1933 " Override Interval (msec) : %d\n",
1934 neigh
->override_interval_msec
);
1936 " Propagation Delay (msec) : %d\n",
1937 neigh
->propagation_delay_msec
);
1939 " Hello Option - Address List : %s\n",
1940 option_address_list
? "yes" : "no");
1942 " Hello Option - DR Priority : %s\n",
1943 option_dr_priority
? "yes" : "no");
1945 " Hello Option - Generation ID : %s\n",
1946 option_generation_id
? "yes" : "no");
1948 " Hello Option - Holdtime : %s\n",
1949 option_holdtime
? "yes" : "no");
1951 " Hello Option - LAN Prune Delay : %s\n",
1952 option_lan_prune_delay
? "yes" : "no");
1954 " Hello Option - T-bit : %s\n",
1955 option_t_bit
? "yes" : "no");
1956 pim_bfd_show_info(vty
, neigh
->bfd_info
,
1964 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1965 json
, JSON_C_TO_STRING_PRETTY
));
1966 json_object_free(json
);
1969 if (!found_neighbor
)
1971 "%% No such interface or neighbor\n");
1976 static void pim_show_state(struct pim_instance
*pim
, struct vty
*vty
,
1977 const char *src_or_group
, const char *group
, bool uj
)
1979 struct channel_oil
*c_oil
;
1980 json_object
*json
= NULL
;
1981 json_object
*json_group
= NULL
;
1982 json_object
*json_ifp_in
= NULL
;
1983 json_object
*json_ifp_out
= NULL
;
1984 json_object
*json_source
= NULL
;
1987 now
= pim_time_monotonic_sec();
1990 json
= json_object_new_object();
1993 "Codes: J -> Pim Join, I -> IGMP Report, S -> Source, * -> Inherited from (*,G), V -> VxLAN, M -> Muted");
1995 "\nActive Source Group RPT IIF OIL\n");
1998 frr_each (rb_pim_oil
, &pim
->channel_oil_head
, c_oil
) {
1999 char grp_str
[INET_ADDRSTRLEN
];
2000 char src_str
[INET_ADDRSTRLEN
];
2001 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
2002 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
2004 struct interface
*ifp_in
;
2009 PIM_UPSTREAM_FLAG_TEST_USE_RPT(c_oil
->up
->flags
)) ||
2010 c_oil
->oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
2015 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
2017 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
2019 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
2022 strlcpy(in_ifname
, ifp_in
->name
, sizeof(in_ifname
));
2024 strlcpy(in_ifname
, "<iif?>", sizeof(in_ifname
));
2027 if (strcmp(src_or_group
, src_str
)
2028 && strcmp(src_or_group
, grp_str
))
2031 if (group
&& strcmp(group
, grp_str
))
2037 /* Find the group, create it if it doesn't exist */
2038 json_object_object_get_ex(json
, grp_str
, &json_group
);
2041 json_group
= json_object_new_object();
2042 json_object_object_add(json
, grp_str
,
2046 /* Find the source nested under the group, create it if
2047 * it doesn't exist */
2048 json_object_object_get_ex(json_group
, src_str
,
2052 json_source
= json_object_new_object();
2053 json_object_object_add(json_group
, src_str
,
2057 /* Find the inbound interface nested under the source,
2058 * create it if it doesn't exist */
2059 json_object_object_get_ex(json_source
, in_ifname
,
2063 json_ifp_in
= json_object_new_object();
2064 json_object_object_add(json_source
, in_ifname
,
2066 json_object_int_add(json_source
, "Installed",
2069 json_object_boolean_true_add(
2070 json_source
, "isRpt");
2072 json_object_boolean_false_add(
2073 json_source
, "isRpt");
2074 json_object_int_add(json_source
, "RefCount",
2075 c_oil
->oil_ref_count
);
2076 json_object_int_add(json_source
, "OilListSize",
2078 json_object_int_add(
2079 json_source
, "OilRescan",
2080 c_oil
->oil_inherited_rescan
);
2081 json_object_int_add(json_source
, "LastUsed",
2082 c_oil
->cc
.lastused
);
2083 json_object_int_add(json_source
, "PacketCount",
2085 json_object_int_add(json_source
, "ByteCount",
2087 json_object_int_add(json_source
,
2089 c_oil
->cc
.wrong_if
);
2092 vty_out(vty
, "%-6d %-15s %-15s %-3s %-16s ",
2093 c_oil
->installed
, src_str
, grp_str
,
2094 isRpt
? "y" : "n", in_ifname
);
2097 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
2099 struct interface
*ifp_out
;
2100 char oif_uptime
[10];
2103 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
2107 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
2109 oif_uptime
, sizeof(oif_uptime
),
2110 now
- c_oil
->oif_creation
[oif_vif_index
]);
2113 strlcpy(out_ifname
, ifp_out
->name
, sizeof(out_ifname
));
2115 strlcpy(out_ifname
, "<oif?>", sizeof(out_ifname
));
2118 json_ifp_out
= json_object_new_object();
2119 json_object_string_add(json_ifp_out
, "source",
2121 json_object_string_add(json_ifp_out
, "group",
2123 json_object_string_add(json_ifp_out
,
2126 json_object_string_add(json_ifp_out
,
2127 "outboundInterface",
2129 json_object_int_add(json_ifp_out
, "installed",
2132 json_object_object_add(json_ifp_in
, out_ifname
,
2137 vty_out(vty
, "%s(%c%c%c%c%c)",
2139 (c_oil
->oif_flags
[oif_vif_index
]
2140 & PIM_OIF_FLAG_PROTO_IGMP
)
2143 (c_oil
->oif_flags
[oif_vif_index
]
2144 & PIM_OIF_FLAG_PROTO_PIM
)
2147 (c_oil
->oif_flags
[oif_vif_index
]
2148 & PIM_OIF_FLAG_PROTO_VXLAN
)
2151 (c_oil
->oif_flags
[oif_vif_index
]
2152 & PIM_OIF_FLAG_PROTO_STAR
)
2155 (c_oil
->oif_flags
[oif_vif_index
]
2156 & PIM_OIF_FLAG_MUTE
)
2160 vty_out(vty
, ", %s(%c%c%c%c%c)",
2162 (c_oil
->oif_flags
[oif_vif_index
]
2163 & PIM_OIF_FLAG_PROTO_IGMP
)
2166 (c_oil
->oif_flags
[oif_vif_index
]
2167 & PIM_OIF_FLAG_PROTO_PIM
)
2170 (c_oil
->oif_flags
[oif_vif_index
]
2171 & PIM_OIF_FLAG_PROTO_VXLAN
)
2174 (c_oil
->oif_flags
[oif_vif_index
]
2175 & PIM_OIF_FLAG_PROTO_STAR
)
2178 (c_oil
->oif_flags
[oif_vif_index
]
2179 & PIM_OIF_FLAG_MUTE
)
2191 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2192 json
, JSON_C_TO_STRING_PRETTY
));
2193 json_object_free(json
);
2199 static void pim_show_neighbors(struct pim_instance
*pim
, struct vty
*vty
,
2202 struct listnode
*neighnode
;
2203 struct interface
*ifp
;
2204 struct pim_interface
*pim_ifp
;
2205 struct pim_neighbor
*neigh
;
2209 char neigh_src_str
[INET_ADDRSTRLEN
];
2210 json_object
*json
= NULL
;
2211 json_object
*json_ifp_rows
= NULL
;
2212 json_object
*json_row
= NULL
;
2214 now
= pim_time_monotonic_sec();
2217 json
= json_object_new_object();
2220 "Interface Neighbor Uptime Holdtime DR Pri\n");
2223 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2224 pim_ifp
= ifp
->info
;
2229 if (pim_ifp
->pim_sock_fd
< 0)
2233 json_ifp_rows
= json_object_new_object();
2235 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
2237 pim_inet4_dump("<src?>", neigh
->source_addr
,
2238 neigh_src_str
, sizeof(neigh_src_str
));
2239 pim_time_uptime(uptime
, sizeof(uptime
),
2240 now
- neigh
->creation
);
2241 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
2242 neigh
->t_expire_timer
);
2245 json_row
= json_object_new_object();
2246 json_object_string_add(json_row
, "interface",
2248 json_object_string_add(json_row
, "neighbor",
2250 json_object_string_add(json_row
, "upTime",
2252 json_object_string_add(json_row
, "holdTime",
2254 json_object_int_add(json_row
, "holdTimeMax",
2256 json_object_int_add(json_row
, "drPriority",
2257 neigh
->dr_priority
);
2258 json_object_object_add(json_ifp_rows
,
2259 neigh_src_str
, json_row
);
2262 vty_out(vty
, "%-16s %15s %8s %8s %6d\n",
2263 ifp
->name
, neigh_src_str
, uptime
,
2264 expire
, neigh
->dr_priority
);
2269 json_object_object_add(json
, ifp
->name
, json_ifp_rows
);
2270 json_ifp_rows
= NULL
;
2275 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2276 json
, JSON_C_TO_STRING_PRETTY
));
2277 json_object_free(json
);
2281 static void pim_show_neighbors_secondary(struct pim_instance
*pim
,
2284 struct interface
*ifp
;
2287 "Interface Address Neighbor Secondary \n");
2289 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2290 struct pim_interface
*pim_ifp
;
2291 struct in_addr ifaddr
;
2292 struct listnode
*neighnode
;
2293 struct pim_neighbor
*neigh
;
2295 pim_ifp
= ifp
->info
;
2300 if (pim_ifp
->pim_sock_fd
< 0)
2303 ifaddr
= pim_ifp
->primary_address
;
2305 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
2307 char neigh_src_str
[INET_ADDRSTRLEN
];
2308 struct listnode
*prefix_node
;
2311 if (!neigh
->prefix_list
)
2314 pim_inet4_dump("<src?>", neigh
->source_addr
,
2315 neigh_src_str
, sizeof(neigh_src_str
));
2317 for (ALL_LIST_ELEMENTS_RO(neigh
->prefix_list
,
2319 char neigh_sec_str
[PREFIX2STR_BUFFER
];
2321 prefix2str(p
, neigh_sec_str
,
2322 sizeof(neigh_sec_str
));
2324 vty_out(vty
, "%-16s %-15s %-15s %-15s\n",
2325 ifp
->name
, inet_ntoa(ifaddr
),
2326 neigh_src_str
, neigh_sec_str
);
2332 static void json_object_pim_upstream_add(json_object
*json
,
2333 struct pim_upstream
*up
)
2335 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED
)
2336 json_object_boolean_true_add(json
, "drJoinDesired");
2338 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED
)
2339 json_object_boolean_true_add(json
, "drJoinDesiredUpdated");
2341 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
2342 json_object_boolean_true_add(json
, "firstHopRouter");
2344 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_IGMP
)
2345 json_object_boolean_true_add(json
, "sourceIgmp");
2347 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_PIM
)
2348 json_object_boolean_true_add(json
, "sourcePim");
2350 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_STREAM
)
2351 json_object_boolean_true_add(json
, "sourceStream");
2353 /* XXX: need to print ths flag in the plain text display as well */
2354 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_MSDP
)
2355 json_object_boolean_true_add(json
, "sourceMsdp");
2357 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SEND_SG_RPT_PRUNE
)
2358 json_object_boolean_true_add(json
, "sendSGRptPrune");
2360 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_LHR
)
2361 json_object_boolean_true_add(json
, "lastHopRouter");
2363 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DISABLE_KAT_EXPIRY
)
2364 json_object_boolean_true_add(json
, "disableKATExpiry");
2366 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_STATIC_IIF
)
2367 json_object_boolean_true_add(json
, "staticIncomingInterface");
2369 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_ALLOW_IIF_IN_OIL
)
2370 json_object_boolean_true_add(json
,
2371 "allowIncomingInterfaceinOil");
2373 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_NO_PIMREG_DATA
)
2374 json_object_boolean_true_add(json
, "noPimRegistrationData");
2376 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FORCE_PIMREG
)
2377 json_object_boolean_true_add(json
, "forcePimRegistration");
2379 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_ORIG
)
2380 json_object_boolean_true_add(json
, "sourceVxlanOrigination");
2382 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_TERM
)
2383 json_object_boolean_true_add(json
, "sourceVxlanTermination");
2385 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_VXLAN
)
2386 json_object_boolean_true_add(json
, "mlagVxlan");
2388 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_NON_DF
)
2389 json_object_boolean_true_add(json
,
2390 "mlagNonDesignatedForwarder");
2394 pim_upstream_state2brief_str(enum pim_upstream_state join_state
,
2395 char *state_str
, size_t state_str_len
)
2397 switch (join_state
) {
2398 case PIM_UPSTREAM_NOTJOINED
:
2399 strlcpy(state_str
, "NotJ", state_str_len
);
2401 case PIM_UPSTREAM_JOINED
:
2402 strlcpy(state_str
, "J", state_str_len
);
2405 strlcpy(state_str
, "Unk", state_str_len
);
2410 static const char *pim_reg_state2brief_str(enum pim_reg_state reg_state
,
2411 char *state_str
, size_t state_str_len
)
2413 switch (reg_state
) {
2414 case PIM_REG_NOINFO
:
2415 strlcpy(state_str
, "RegNI", state_str_len
);
2418 strlcpy(state_str
, "RegJ", state_str_len
);
2420 case PIM_REG_JOIN_PENDING
:
2422 strlcpy(state_str
, "RegP", state_str_len
);
2425 strlcpy(state_str
, "Unk", state_str_len
);
2430 static void pim_show_upstream(struct pim_instance
*pim
, struct vty
*vty
,
2431 struct prefix_sg
*sg
, bool uj
)
2433 struct pim_upstream
*up
;
2435 json_object
*json
= NULL
;
2436 json_object
*json_group
= NULL
;
2437 json_object
*json_row
= NULL
;
2439 now
= pim_time_monotonic_sec();
2442 json
= json_object_new_object();
2445 "Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt\n");
2447 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
2448 char src_str
[INET_ADDRSTRLEN
];
2449 char grp_str
[INET_ADDRSTRLEN
];
2451 char join_timer
[10];
2454 char msdp_reg_timer
[10];
2455 char state_str
[PIM_REG_STATE_STR_LEN
];
2457 if (sg
->grp
.s_addr
!= INADDR_ANY
2458 && sg
->grp
.s_addr
!= up
->sg
.grp
.s_addr
)
2460 if (sg
->src
.s_addr
!= INADDR_ANY
2461 && sg
->src
.s_addr
!= up
->sg
.src
.s_addr
)
2464 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2465 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2466 pim_time_uptime(uptime
, sizeof(uptime
),
2467 now
- up
->state_transition
);
2468 pim_time_timer_to_hhmmss(join_timer
, sizeof(join_timer
),
2472 * If the upstream is not dummy and it has a J/P timer for the
2473 * neighbor display that
2475 if (!up
->t_join_timer
&& up
->rpf
.source_nexthop
.interface
) {
2476 struct pim_neighbor
*nbr
;
2478 nbr
= pim_neighbor_find(
2479 up
->rpf
.source_nexthop
.interface
,
2480 up
->rpf
.rpf_addr
.u
.prefix4
);
2482 pim_time_timer_to_hhmmss(join_timer
,
2487 pim_time_timer_to_hhmmss(rs_timer
, sizeof(rs_timer
),
2489 pim_time_timer_to_hhmmss(ka_timer
, sizeof(ka_timer
),
2491 pim_time_timer_to_hhmmss(msdp_reg_timer
, sizeof(msdp_reg_timer
),
2492 up
->t_msdp_reg_timer
);
2494 pim_upstream_state2brief_str(up
->join_state
, state_str
, sizeof(state_str
));
2495 if (up
->reg_state
!= PIM_REG_NOINFO
) {
2496 char tmp_str
[PIM_REG_STATE_STR_LEN
];
2498 sprintf(state_str
+ strlen(state_str
), ",%s",
2499 pim_reg_state2brief_str(up
->reg_state
, tmp_str
,
2504 json_object_object_get_ex(json
, grp_str
, &json_group
);
2507 json_group
= json_object_new_object();
2508 json_object_object_add(json
, grp_str
,
2512 json_row
= json_object_new_object();
2513 json_object_pim_upstream_add(json_row
, up
);
2514 json_object_string_add(
2515 json_row
, "inboundInterface",
2516 up
->rpf
.source_nexthop
.interface
2517 ? up
->rpf
.source_nexthop
.interface
->name
2521 * The RPF address we use is slightly different
2522 * based upon what we are looking up.
2523 * If we have a S, list that unless
2524 * we are the FHR, else we just put
2525 * the RP as the rpfAddress
2527 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
2528 || up
->sg
.src
.s_addr
== INADDR_ANY
) {
2529 char rpf
[PREFIX_STRLEN
];
2530 struct pim_rpf
*rpg
;
2532 rpg
= RP(pim
, up
->sg
.grp
);
2533 pim_inet4_dump("<rpf?>",
2534 rpg
->rpf_addr
.u
.prefix4
, rpf
,
2536 json_object_string_add(json_row
, "rpfAddress",
2539 json_object_string_add(json_row
, "rpfAddress",
2543 json_object_string_add(json_row
, "source", src_str
);
2544 json_object_string_add(json_row
, "group", grp_str
);
2545 json_object_string_add(json_row
, "state", state_str
);
2546 json_object_string_add(
2547 json_row
, "joinState",
2548 pim_upstream_state2str(up
->join_state
));
2549 json_object_string_add(
2550 json_row
, "regState",
2551 pim_reg_state2str(up
->reg_state
, state_str
, sizeof(state_str
)));
2552 json_object_string_add(json_row
, "upTime", uptime
);
2553 json_object_string_add(json_row
, "joinTimer",
2555 json_object_string_add(json_row
, "resetTimer",
2557 json_object_string_add(json_row
, "keepaliveTimer",
2559 json_object_string_add(json_row
, "msdpRegTimer",
2561 json_object_int_add(json_row
, "refCount",
2563 json_object_int_add(json_row
, "sptBit", up
->sptbit
);
2564 json_object_object_add(json_group
, src_str
, json_row
);
2567 "%-16s%-15s %-15s %-11s %-8s %-9s %-9s %-9s %6d\n",
2568 up
->rpf
.source_nexthop
.interface
2569 ? up
->rpf
.source_nexthop
.interface
->name
2571 src_str
, grp_str
, state_str
, uptime
, join_timer
,
2572 rs_timer
, ka_timer
, up
->ref_count
);
2577 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2578 json
, JSON_C_TO_STRING_PRETTY
));
2579 json_object_free(json
);
2583 static void pim_show_channel_helper(struct pim_instance
*pim
,
2585 struct pim_interface
*pim_ifp
,
2586 struct pim_ifchannel
*ch
,
2587 json_object
*json
, bool uj
)
2589 struct pim_upstream
*up
= ch
->upstream
;
2590 json_object
*json_group
= NULL
;
2591 char src_str
[INET_ADDRSTRLEN
];
2592 char grp_str
[INET_ADDRSTRLEN
];
2593 json_object
*json_row
= NULL
;
2595 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2596 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2599 json_object_object_get_ex(json
, grp_str
, &json_group
);
2602 json_group
= json_object_new_object();
2603 json_object_object_add(json
, grp_str
, json_group
);
2606 json_row
= json_object_new_object();
2607 json_object_pim_upstream_add(json_row
, up
);
2608 json_object_string_add(json_row
, "interface",
2609 ch
->interface
->name
);
2610 json_object_string_add(json_row
, "source", src_str
);
2611 json_object_string_add(json_row
, "group", grp_str
);
2613 if (pim_macro_ch_lost_assert(ch
))
2614 json_object_boolean_true_add(json_row
, "lostAssert");
2616 if (pim_macro_chisin_joins(ch
))
2617 json_object_boolean_true_add(json_row
, "joins");
2619 if (pim_macro_chisin_pim_include(ch
))
2620 json_object_boolean_true_add(json_row
, "pimInclude");
2622 if (pim_upstream_evaluate_join_desired(pim
, up
))
2623 json_object_boolean_true_add(json_row
,
2624 "evaluateJoinDesired");
2626 json_object_object_add(json_group
, src_str
, json_row
);
2629 vty_out(vty
, "%-16s %-15s %-15s %-10s %-5s %-10s %-11s %-6s\n",
2630 ch
->interface
->name
, src_str
, grp_str
,
2631 pim_macro_ch_lost_assert(ch
) ? "yes" : "no",
2632 pim_macro_chisin_joins(ch
) ? "yes" : "no",
2633 pim_macro_chisin_pim_include(ch
) ? "yes" : "no",
2634 PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(up
->flags
)
2637 pim_upstream_evaluate_join_desired(pim
, up
) ? "yes"
2642 static void pim_show_channel(struct pim_instance
*pim
, struct vty
*vty
,
2645 struct pim_interface
*pim_ifp
;
2646 struct pim_ifchannel
*ch
;
2647 struct interface
*ifp
;
2649 json_object
*json
= NULL
;
2652 json
= json_object_new_object();
2655 "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD\n");
2657 /* scan per-interface (S,G) state */
2658 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2659 pim_ifp
= ifp
->info
;
2664 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
2665 /* scan all interfaces */
2666 pim_show_channel_helper(pim
, vty
, pim_ifp
, ch
,
2672 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2673 json
, JSON_C_TO_STRING_PRETTY
));
2674 json_object_free(json
);
2678 static void pim_show_join_desired_helper(struct pim_instance
*pim
,
2680 struct pim_upstream
*up
,
2681 json_object
*json
, bool uj
)
2683 json_object
*json_group
= NULL
;
2684 char src_str
[INET_ADDRSTRLEN
];
2685 char grp_str
[INET_ADDRSTRLEN
];
2686 json_object
*json_row
= NULL
;
2688 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2689 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2692 json_object_object_get_ex(json
, grp_str
, &json_group
);
2695 json_group
= json_object_new_object();
2696 json_object_object_add(json
, grp_str
, json_group
);
2699 json_row
= json_object_new_object();
2700 json_object_pim_upstream_add(json_row
, up
);
2701 json_object_string_add(json_row
, "source", src_str
);
2702 json_object_string_add(json_row
, "group", grp_str
);
2704 if (pim_upstream_evaluate_join_desired(pim
, up
))
2705 json_object_boolean_true_add(json_row
,
2706 "evaluateJoinDesired");
2708 json_object_object_add(json_group
, src_str
, json_row
);
2711 vty_out(vty
, "%-15s %-15s %-6s\n",
2713 pim_upstream_evaluate_join_desired(pim
, up
) ? "yes"
2718 static void pim_show_join_desired(struct pim_instance
*pim
, struct vty
*vty
,
2721 struct pim_upstream
*up
;
2723 json_object
*json
= NULL
;
2726 json
= json_object_new_object();
2729 "Source Group EvalJD\n");
2731 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
2732 /* scan all interfaces */
2733 pim_show_join_desired_helper(pim
, vty
, up
,
2738 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2739 json
, JSON_C_TO_STRING_PRETTY
));
2740 json_object_free(json
);
2744 static void pim_show_upstream_rpf(struct pim_instance
*pim
, struct vty
*vty
,
2747 struct pim_upstream
*up
;
2748 json_object
*json
= NULL
;
2749 json_object
*json_group
= NULL
;
2750 json_object
*json_row
= NULL
;
2753 json
= json_object_new_object();
2756 "Source Group RpfIface RibNextHop RpfAddress \n");
2758 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
2759 char src_str
[INET_ADDRSTRLEN
];
2760 char grp_str
[INET_ADDRSTRLEN
];
2761 char rpf_nexthop_str
[PREFIX_STRLEN
];
2762 char rpf_addr_str
[PREFIX_STRLEN
];
2763 struct pim_rpf
*rpf
;
2764 const char *rpf_ifname
;
2768 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2769 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2770 pim_addr_dump("<nexthop?>",
2771 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2772 rpf_nexthop_str
, sizeof(rpf_nexthop_str
));
2773 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2774 sizeof(rpf_addr_str
));
2776 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2779 json_object_object_get_ex(json
, grp_str
, &json_group
);
2782 json_group
= json_object_new_object();
2783 json_object_object_add(json
, grp_str
,
2787 json_row
= json_object_new_object();
2788 json_object_pim_upstream_add(json_row
, up
);
2789 json_object_string_add(json_row
, "source", src_str
);
2790 json_object_string_add(json_row
, "group", grp_str
);
2791 json_object_string_add(json_row
, "rpfInterface",
2793 json_object_string_add(json_row
, "ribNexthop",
2795 json_object_string_add(json_row
, "rpfAddress",
2797 json_object_object_add(json_group
, src_str
, json_row
);
2799 vty_out(vty
, "%-15s %-15s %-16s %-15s %-15s\n", src_str
,
2800 grp_str
, rpf_ifname
, rpf_nexthop_str
,
2806 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2807 json
, JSON_C_TO_STRING_PRETTY
));
2808 json_object_free(json
);
2812 static void show_rpf_refresh_stats(struct vty
*vty
, struct pim_instance
*pim
,
2813 time_t now
, json_object
*json
)
2815 char refresh_uptime
[10];
2817 pim_time_uptime_begin(refresh_uptime
, sizeof(refresh_uptime
), now
,
2818 pim
->rpf_cache_refresh_last
);
2821 json_object_int_add(json
, "rpfCacheRefreshDelayMsecs",
2822 router
->rpf_cache_refresh_delay_msec
);
2823 json_object_int_add(
2824 json
, "rpfCacheRefreshTimer",
2825 pim_time_timer_remain_msec(pim
->rpf_cache_refresher
));
2826 json_object_int_add(json
, "rpfCacheRefreshRequests",
2827 pim
->rpf_cache_refresh_requests
);
2828 json_object_int_add(json
, "rpfCacheRefreshEvents",
2829 pim
->rpf_cache_refresh_events
);
2830 json_object_string_add(json
, "rpfCacheRefreshLast",
2832 json_object_int_add(json
, "nexthopLookups",
2833 pim
->nexthop_lookups
);
2834 json_object_int_add(json
, "nexthopLookupsAvoided",
2835 pim
->nexthop_lookups_avoided
);
2838 "RPF Cache Refresh Delay: %ld msecs\n"
2839 "RPF Cache Refresh Timer: %ld msecs\n"
2840 "RPF Cache Refresh Requests: %lld\n"
2841 "RPF Cache Refresh Events: %lld\n"
2842 "RPF Cache Refresh Last: %s\n"
2843 "Nexthop Lookups: %lld\n"
2844 "Nexthop Lookups Avoided: %lld\n",
2845 router
->rpf_cache_refresh_delay_msec
,
2846 pim_time_timer_remain_msec(pim
->rpf_cache_refresher
),
2847 (long long)pim
->rpf_cache_refresh_requests
,
2848 (long long)pim
->rpf_cache_refresh_events
,
2849 refresh_uptime
, (long long)pim
->nexthop_lookups
,
2850 (long long)pim
->nexthop_lookups_avoided
);
2854 static void show_scan_oil_stats(struct pim_instance
*pim
, struct vty
*vty
,
2857 char uptime_scan_oil
[10];
2858 char uptime_mroute_add
[10];
2859 char uptime_mroute_del
[10];
2861 pim_time_uptime_begin(uptime_scan_oil
, sizeof(uptime_scan_oil
), now
,
2862 pim
->scan_oil_last
);
2863 pim_time_uptime_begin(uptime_mroute_add
, sizeof(uptime_mroute_add
), now
,
2864 pim
->mroute_add_last
);
2865 pim_time_uptime_begin(uptime_mroute_del
, sizeof(uptime_mroute_del
), now
,
2866 pim
->mroute_del_last
);
2869 "Scan OIL - Last: %s Events: %lld\n"
2870 "MFC Add - Last: %s Events: %lld\n"
2871 "MFC Del - Last: %s Events: %lld\n",
2872 uptime_scan_oil
, (long long)pim
->scan_oil_events
,
2873 uptime_mroute_add
, (long long)pim
->mroute_add_events
,
2874 uptime_mroute_del
, (long long)pim
->mroute_del_events
);
2877 static void pim_show_rpf(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
2879 struct pim_upstream
*up
;
2880 time_t now
= pim_time_monotonic_sec();
2881 json_object
*json
= NULL
;
2882 json_object
*json_group
= NULL
;
2883 json_object
*json_row
= NULL
;
2886 json
= json_object_new_object();
2887 show_rpf_refresh_stats(vty
, pim
, now
, json
);
2889 show_rpf_refresh_stats(vty
, pim
, now
, json
);
2892 "Source Group RpfIface RpfAddress RibNextHop Metric Pref\n");
2895 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
2896 char src_str
[INET_ADDRSTRLEN
];
2897 char grp_str
[INET_ADDRSTRLEN
];
2898 char rpf_addr_str
[PREFIX_STRLEN
];
2899 char rib_nexthop_str
[PREFIX_STRLEN
];
2900 const char *rpf_ifname
;
2901 struct pim_rpf
*rpf
= &up
->rpf
;
2903 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2904 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2905 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2906 sizeof(rpf_addr_str
));
2907 pim_addr_dump("<nexthop?>",
2908 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2909 rib_nexthop_str
, sizeof(rib_nexthop_str
));
2911 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2914 json_object_object_get_ex(json
, grp_str
, &json_group
);
2917 json_group
= json_object_new_object();
2918 json_object_object_add(json
, grp_str
,
2922 json_row
= json_object_new_object();
2923 json_object_string_add(json_row
, "source", src_str
);
2924 json_object_string_add(json_row
, "group", grp_str
);
2925 json_object_string_add(json_row
, "rpfInterface",
2927 json_object_string_add(json_row
, "rpfAddress",
2929 json_object_string_add(json_row
, "ribNexthop",
2931 json_object_int_add(
2932 json_row
, "routeMetric",
2933 rpf
->source_nexthop
.mrib_route_metric
);
2934 json_object_int_add(
2935 json_row
, "routePreference",
2936 rpf
->source_nexthop
.mrib_metric_preference
);
2937 json_object_object_add(json_group
, src_str
, json_row
);
2940 vty_out(vty
, "%-15s %-15s %-16s %-15s %-15s %6d %4d\n",
2941 src_str
, grp_str
, rpf_ifname
, rpf_addr_str
,
2943 rpf
->source_nexthop
.mrib_route_metric
,
2944 rpf
->source_nexthop
.mrib_metric_preference
);
2949 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2950 json
, JSON_C_TO_STRING_PRETTY
));
2951 json_object_free(json
);
2955 struct pnc_cache_walk_data
{
2957 struct pim_instance
*pim
;
2960 static int pim_print_pnc_cache_walkcb(struct hash_bucket
*bucket
, void *arg
)
2962 struct pim_nexthop_cache
*pnc
= bucket
->data
;
2963 struct pnc_cache_walk_data
*cwd
= arg
;
2964 struct vty
*vty
= cwd
->vty
;
2965 struct pim_instance
*pim
= cwd
->pim
;
2966 struct nexthop
*nh_node
= NULL
;
2967 ifindex_t first_ifindex
;
2968 struct interface
*ifp
= NULL
;
2970 for (nh_node
= pnc
->nexthop
; nh_node
; nh_node
= nh_node
->next
) {
2971 first_ifindex
= nh_node
->ifindex
;
2972 ifp
= if_lookup_by_index(first_ifindex
, pim
->vrf_id
);
2974 vty_out(vty
, "%-15s ", inet_ntoa(pnc
->rpf
.rpf_addr
.u
.prefix4
));
2975 vty_out(vty
, "%-16s ", ifp
? ifp
->name
: "NULL");
2976 vty_out(vty
, "%s ", inet_ntoa(nh_node
->gate
.ipv4
));
2982 static void pim_show_nexthop(struct pim_instance
*pim
, struct vty
*vty
)
2984 struct pnc_cache_walk_data cwd
;
2988 vty_out(vty
, "Number of registered addresses: %lu\n",
2989 pim
->rpf_hash
->count
);
2990 vty_out(vty
, "Address Interface Nexthop\n");
2991 vty_out(vty
, "---------------------------------------------\n");
2993 hash_walk(pim
->rpf_hash
, pim_print_pnc_cache_walkcb
, &cwd
);
2996 /* Display the bsm database details */
2997 static void pim_show_bsm_db(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
2999 struct listnode
*bsmnode
;
3002 struct bsm_info
*bsm
;
3003 json_object
*json
= NULL
;
3004 json_object
*json_group
= NULL
;
3005 json_object
*json_row
= NULL
;
3007 count
= pim
->global_scope
.bsm_list
->count
;
3010 json
= json_object_new_object();
3011 json_object_int_add(json
, "Number of the fragments", count
);
3013 vty_out(vty
, "Scope Zone: Global\n");
3014 vty_out(vty
, "Number of the fragments: %d\n", count
);
3018 for (ALL_LIST_ELEMENTS_RO(pim
->global_scope
.bsm_list
, bsmnode
, bsm
)) {
3019 char grp_str
[INET_ADDRSTRLEN
];
3020 char rp_str
[INET_ADDRSTRLEN
];
3021 char bsr_str
[INET_ADDRSTRLEN
];
3022 struct bsmmsg_grpinfo
*group
;
3023 struct bsmmsg_rpinfo
*rpaddr
;
3025 struct bsm_hdr
*hdr
;
3026 uint32_t offset
= 0;
3029 uint32_t frag_rp_cnt
= 0;
3034 /* skip pim header */
3035 buf
+= PIM_MSG_HEADER_LEN
;
3036 len
-= PIM_MSG_HEADER_LEN
;
3038 hdr
= (struct bsm_hdr
*)buf
;
3040 /* BSM starts with bsr header */
3041 buf
+= sizeof(struct bsm_hdr
);
3042 len
-= sizeof(struct bsm_hdr
);
3044 pim_inet4_dump("<BSR Address?>", hdr
->bsr_addr
.addr
, bsr_str
,
3049 json_object_string_add(json
, "BSR address", bsr_str
);
3050 json_object_int_add(json
, "BSR priority",
3052 json_object_int_add(json
, "Hashmask Length",
3054 json_object_int_add(json
, "Fragment Tag",
3055 ntohs(hdr
->frag_tag
));
3057 vty_out(vty
, "BSM Fragment : %d\n", fragment
);
3058 vty_out(vty
, "------------------\n");
3059 vty_out(vty
, "%-15s %-15s %-15s %-15s\n", "BSR-Address",
3060 "BSR-Priority", "Hashmask-len", "Fragment-Tag");
3061 vty_out(vty
, "%-15s %-15d %-15d %-15d\n", bsr_str
,
3062 hdr
->bsr_prio
, hdr
->hm_len
,
3063 ntohs(hdr
->frag_tag
));
3068 while (offset
< len
) {
3069 group
= (struct bsmmsg_grpinfo
*)buf
;
3071 if (group
->group
.family
== PIM_MSG_ADDRESS_FAMILY_IPV4
)
3072 grp
.family
= AF_INET
;
3074 grp
.prefixlen
= group
->group
.mask
;
3075 grp
.u
.prefix4
.s_addr
= group
->group
.addr
.s_addr
;
3077 prefix2str(&grp
, grp_str
, sizeof(grp_str
));
3079 buf
+= sizeof(struct bsmmsg_grpinfo
);
3080 offset
+= sizeof(struct bsmmsg_grpinfo
);
3083 json_object_object_get_ex(json
, grp_str
,
3086 json_group
= json_object_new_object();
3087 json_object_int_add(json_group
,
3090 json_object_int_add(
3091 json_group
, "Fragment Rp count",
3092 group
->frag_rp_count
);
3093 json_object_object_add(json
, grp_str
,
3097 vty_out(vty
, "Group : %s\n", grp_str
);
3098 vty_out(vty
, "-------------------\n");
3099 vty_out(vty
, "Rp Count:%d\n", group
->rp_count
);
3100 vty_out(vty
, "Fragment Rp Count : %d\n",
3101 group
->frag_rp_count
);
3104 frag_rp_cnt
= group
->frag_rp_count
;
3111 "RpAddress HoldTime Priority\n");
3113 while (frag_rp_cnt
--) {
3114 rpaddr
= (struct bsmmsg_rpinfo
*)buf
;
3116 buf
+= sizeof(struct bsmmsg_rpinfo
);
3117 offset
+= sizeof(struct bsmmsg_rpinfo
);
3119 pim_inet4_dump("<Rp addr?>",
3120 rpaddr
->rpaddr
.addr
, rp_str
,
3124 json_row
= json_object_new_object();
3125 json_object_string_add(
3126 json_row
, "Rp Address", rp_str
);
3127 json_object_int_add(
3128 json_row
, "Rp HoldTime",
3129 ntohs(rpaddr
->rp_holdtime
));
3130 json_object_int_add(json_row
,
3133 json_object_object_add(
3134 json_group
, rp_str
, json_row
);
3136 vty_out(vty
, "%-15s %-12d %d\n", rp_str
,
3137 ntohs(rpaddr
->rp_holdtime
),
3148 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3149 json
, JSON_C_TO_STRING_PRETTY
));
3150 json_object_free(json
);
3154 /*Display the group-rp mappings */
3155 static void pim_show_group_rp_mappings_info(struct pim_instance
*pim
,
3156 struct vty
*vty
, bool uj
)
3158 struct bsgrp_node
*bsgrp
;
3159 struct listnode
*rpnode
;
3160 struct bsm_rpinfo
*bsm_rp
;
3161 struct route_node
*rn
;
3162 char bsr_str
[INET_ADDRSTRLEN
];
3163 json_object
*json
= NULL
;
3164 json_object
*json_group
= NULL
;
3165 json_object
*json_row
= NULL
;
3167 if (pim
->global_scope
.current_bsr
.s_addr
== INADDR_ANY
)
3168 strlcpy(bsr_str
, "0.0.0.0", sizeof(bsr_str
));
3171 pim_inet4_dump("<bsr?>", pim
->global_scope
.current_bsr
, bsr_str
,
3175 json
= json_object_new_object();
3176 json_object_string_add(json
, "BSR Address", bsr_str
);
3178 vty_out(vty
, "BSR Address %s\n", bsr_str
);
3181 for (rn
= route_top(pim
->global_scope
.bsrp_table
); rn
;
3182 rn
= route_next(rn
)) {
3183 bsgrp
= (struct bsgrp_node
*)rn
->info
;
3188 char grp_str
[INET_ADDRSTRLEN
];
3190 prefix2str(&bsgrp
->group
, grp_str
, sizeof(grp_str
));
3193 json_object_object_get_ex(json
, grp_str
, &json_group
);
3195 json_group
= json_object_new_object();
3196 json_object_object_add(json
, grp_str
,
3200 vty_out(vty
, "Group Address %s\n", grp_str
);
3201 vty_out(vty
, "--------------------------\n");
3202 vty_out(vty
, "%-15s %-15s %-15s %-15s\n", "Rp Address",
3203 "priority", "Holdtime", "Hash");
3205 vty_out(vty
, "(ACTIVE)\n");
3208 if (bsgrp
->bsrp_list
) {
3209 for (ALL_LIST_ELEMENTS_RO(bsgrp
->bsrp_list
, rpnode
,
3211 char rp_str
[INET_ADDRSTRLEN
];
3213 pim_inet4_dump("<Rp Address?>",
3214 bsm_rp
->rp_address
, rp_str
,
3218 json_row
= json_object_new_object();
3219 json_object_string_add(
3220 json_row
, "Rp Address", rp_str
);
3221 json_object_int_add(
3222 json_row
, "Rp HoldTime",
3223 bsm_rp
->rp_holdtime
);
3224 json_object_int_add(json_row
,
3227 json_object_int_add(json_row
,
3230 json_object_object_add(
3231 json_group
, rp_str
, json_row
);
3235 "%-15s %-15u %-15u %-15u\n",
3236 rp_str
, bsm_rp
->rp_prio
,
3237 bsm_rp
->rp_holdtime
,
3241 if (!bsgrp
->bsrp_list
->count
&& !uj
)
3242 vty_out(vty
, "Active List is empty.\n");
3246 json_object_int_add(json_group
, "Pending RP count",
3247 bsgrp
->pend_rp_cnt
);
3249 vty_out(vty
, "(PENDING)\n");
3250 vty_out(vty
, "Pending RP count :%d\n",
3251 bsgrp
->pend_rp_cnt
);
3252 if (bsgrp
->pend_rp_cnt
)
3253 vty_out(vty
, "%-15s %-15s %-15s %-15s\n",
3254 "Rp Address", "priority", "Holdtime",
3258 if (bsgrp
->partial_bsrp_list
) {
3259 for (ALL_LIST_ELEMENTS_RO(bsgrp
->partial_bsrp_list
,
3261 char rp_str
[INET_ADDRSTRLEN
];
3263 pim_inet4_dump("<Rp Addr?>", bsm_rp
->rp_address
,
3264 rp_str
, sizeof(rp_str
));
3267 json_row
= json_object_new_object();
3268 json_object_string_add(
3269 json_row
, "Rp Address", rp_str
);
3270 json_object_int_add(
3271 json_row
, "Rp HoldTime",
3272 bsm_rp
->rp_holdtime
);
3273 json_object_int_add(json_row
,
3276 json_object_int_add(json_row
,
3279 json_object_object_add(
3280 json_group
, rp_str
, json_row
);
3283 "%-15s %-15u %-15u %-15u\n",
3284 rp_str
, bsm_rp
->rp_prio
,
3285 bsm_rp
->rp_holdtime
,
3289 if (!bsgrp
->partial_bsrp_list
->count
&& !uj
)
3290 vty_out(vty
, "Partial List is empty\n");
3298 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3299 json
, JSON_C_TO_STRING_PRETTY
));
3300 json_object_free(json
);
3304 /* pim statistics - just adding only bsm related now.
3305 * We can continue to add all pim related stats here.
3307 static void pim_show_statistics(struct pim_instance
*pim
, struct vty
*vty
,
3308 const char *ifname
, bool uj
)
3310 json_object
*json
= NULL
;
3311 struct interface
*ifp
;
3314 json
= json_object_new_object();
3315 json_object_int_add(json
, "Number of Received BSMs",
3317 json_object_int_add(json
, "Number of Forwared BSMs",
3319 json_object_int_add(json
, "Number of Dropped BSMs",
3322 vty_out(vty
, "BSM Statistics :\n");
3323 vty_out(vty
, "----------------\n");
3324 vty_out(vty
, "Number of Received BSMs : %" PRIu64
"\n",
3326 vty_out(vty
, "Number of Forwared BSMs : %" PRIu64
"\n",
3328 vty_out(vty
, "Number of Dropped BSMs : %" PRIu64
"\n",
3334 /* scan interfaces */
3335 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3336 struct pim_interface
*pim_ifp
= ifp
->info
;
3338 if (ifname
&& strcmp(ifname
, ifp
->name
))
3345 vty_out(vty
, "Interface : %s\n", ifp
->name
);
3346 vty_out(vty
, "-------------------\n");
3348 "Number of BSMs dropped due to config miss : %u\n",
3349 pim_ifp
->pim_ifstat_bsm_cfg_miss
);
3350 vty_out(vty
, "Number of unicast BSMs dropped : %u\n",
3351 pim_ifp
->pim_ifstat_ucast_bsm_cfg_miss
);
3353 "Number of BSMs dropped due to invalid scope zone : %u\n",
3354 pim_ifp
->pim_ifstat_bsm_invalid_sz
);
3357 json_object
*json_row
= NULL
;
3359 json_row
= json_object_new_object();
3361 json_object_string_add(json_row
, "If Name", ifp
->name
);
3362 json_object_int_add(
3364 "Number of BSMs dropped due to config miss",
3365 pim_ifp
->pim_ifstat_bsm_cfg_miss
);
3366 json_object_int_add(
3367 json_row
, "Number of unicast BSMs dropped",
3368 pim_ifp
->pim_ifstat_ucast_bsm_cfg_miss
);
3369 json_object_int_add(json_row
,
3370 "Number of BSMs dropped due to invalid scope zone",
3371 pim_ifp
->pim_ifstat_bsm_invalid_sz
);
3372 json_object_object_add(json
, ifp
->name
, json_row
);
3378 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3379 json
, JSON_C_TO_STRING_PRETTY
));
3380 json_object_free(json
);
3384 static void clear_pim_statistics(struct pim_instance
*pim
)
3386 struct interface
*ifp
;
3390 pim
->bsm_dropped
= 0;
3392 /* scan interfaces */
3393 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3394 struct pim_interface
*pim_ifp
= ifp
->info
;
3399 pim_ifp
->pim_ifstat_bsm_cfg_miss
= 0;
3400 pim_ifp
->pim_ifstat_ucast_bsm_cfg_miss
= 0;
3401 pim_ifp
->pim_ifstat_bsm_invalid_sz
= 0;
3405 static void igmp_show_groups(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
3407 struct interface
*ifp
;
3409 json_object
*json
= NULL
;
3410 json_object
*json_iface
= NULL
;
3411 json_object
*json_row
= NULL
;
3413 now
= pim_time_monotonic_sec();
3416 json
= json_object_new_object();
3419 "Interface Address Group Mode Timer Srcs V Uptime \n");
3421 /* scan interfaces */
3422 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3423 struct pim_interface
*pim_ifp
= ifp
->info
;
3424 struct listnode
*sock_node
;
3425 struct igmp_sock
*igmp
;
3430 /* scan igmp sockets */
3431 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3433 char ifaddr_str
[INET_ADDRSTRLEN
];
3434 struct listnode
*grpnode
;
3435 struct igmp_group
*grp
;
3437 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3438 sizeof(ifaddr_str
));
3440 /* scan igmp groups */
3441 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3443 char group_str
[INET_ADDRSTRLEN
];
3447 pim_inet4_dump("<group?>", grp
->group_addr
,
3448 group_str
, sizeof(group_str
));
3449 pim_time_timer_to_hhmmss(hhmmss
, sizeof(hhmmss
),
3450 grp
->t_group_timer
);
3451 pim_time_uptime(uptime
, sizeof(uptime
),
3452 now
- grp
->group_creation
);
3455 json_object_object_get_ex(
3456 json
, ifp
->name
, &json_iface
);
3460 json_object_new_object();
3461 json_object_pim_ifp_add(
3463 json_object_object_add(
3468 json_row
= json_object_new_object();
3469 json_object_string_add(
3470 json_row
, "source", ifaddr_str
);
3471 json_object_string_add(
3472 json_row
, "group", group_str
);
3474 if (grp
->igmp_version
== 3)
3475 json_object_string_add(
3477 grp
->group_filtermode_isexcl
3481 json_object_string_add(json_row
,
3483 json_object_int_add(
3484 json_row
, "sourcesCount",
3485 grp
->group_source_list
3487 grp
->group_source_list
)
3489 json_object_int_add(json_row
, "version",
3491 json_object_string_add(
3492 json_row
, "uptime", uptime
);
3493 json_object_object_add(json_iface
,
3499 "%-16s %-15s %-15s %4s %8s %4d %d %8s\n",
3500 ifp
->name
, ifaddr_str
,
3502 grp
->igmp_version
== 3
3503 ? (grp
->group_filtermode_isexcl
3508 grp
->group_source_list
3510 grp
->group_source_list
)
3512 grp
->igmp_version
, uptime
);
3514 } /* scan igmp groups */
3515 } /* scan igmp sockets */
3516 } /* scan interfaces */
3519 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3520 json
, JSON_C_TO_STRING_PRETTY
));
3521 json_object_free(json
);
3525 static void igmp_show_group_retransmission(struct pim_instance
*pim
,
3528 struct interface
*ifp
;
3531 "Interface Address Group RetTimer Counter RetSrcs\n");
3533 /* scan interfaces */
3534 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3535 struct pim_interface
*pim_ifp
= ifp
->info
;
3536 struct listnode
*sock_node
;
3537 struct igmp_sock
*igmp
;
3542 /* scan igmp sockets */
3543 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3545 char ifaddr_str
[INET_ADDRSTRLEN
];
3546 struct listnode
*grpnode
;
3547 struct igmp_group
*grp
;
3549 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3550 sizeof(ifaddr_str
));
3552 /* scan igmp groups */
3553 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3555 char group_str
[INET_ADDRSTRLEN
];
3556 char grp_retr_mmss
[10];
3557 struct listnode
*src_node
;
3558 struct igmp_source
*src
;
3559 int grp_retr_sources
= 0;
3561 pim_inet4_dump("<group?>", grp
->group_addr
,
3562 group_str
, sizeof(group_str
));
3563 pim_time_timer_to_mmss(
3564 grp_retr_mmss
, sizeof(grp_retr_mmss
),
3565 grp
->t_group_query_retransmit_timer
);
3568 /* count group sources with retransmission state
3570 for (ALL_LIST_ELEMENTS_RO(
3571 grp
->group_source_list
, src_node
,
3573 if (src
->source_query_retransmit_count
3579 vty_out(vty
, "%-16s %-15s %-15s %-8s %7d %7d\n",
3580 ifp
->name
, ifaddr_str
, group_str
,
3582 grp
->group_specific_query_retransmit_count
,
3585 } /* scan igmp groups */
3586 } /* scan igmp sockets */
3587 } /* scan interfaces */
3590 static void igmp_show_sources(struct pim_instance
*pim
, struct vty
*vty
)
3592 struct interface
*ifp
;
3595 now
= pim_time_monotonic_sec();
3598 "Interface Address Group Source Timer Fwd Uptime \n");
3600 /* scan interfaces */
3601 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3602 struct pim_interface
*pim_ifp
= ifp
->info
;
3603 struct listnode
*sock_node
;
3604 struct igmp_sock
*igmp
;
3609 /* scan igmp sockets */
3610 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3612 char ifaddr_str
[INET_ADDRSTRLEN
];
3613 struct listnode
*grpnode
;
3614 struct igmp_group
*grp
;
3616 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3617 sizeof(ifaddr_str
));
3619 /* scan igmp groups */
3620 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3622 char group_str
[INET_ADDRSTRLEN
];
3623 struct listnode
*srcnode
;
3624 struct igmp_source
*src
;
3626 pim_inet4_dump("<group?>", grp
->group_addr
,
3627 group_str
, sizeof(group_str
));
3629 /* scan group sources */
3630 for (ALL_LIST_ELEMENTS_RO(
3631 grp
->group_source_list
, srcnode
,
3633 char source_str
[INET_ADDRSTRLEN
];
3638 "<source?>", src
->source_addr
,
3639 source_str
, sizeof(source_str
));
3641 pim_time_timer_to_mmss(
3643 src
->t_source_timer
);
3646 uptime
, sizeof(uptime
),
3647 now
- src
->source_creation
);
3650 "%-16s %-15s %-15s %-15s %5s %3s %8s\n",
3651 ifp
->name
, ifaddr_str
,
3652 group_str
, source_str
, mmss
,
3653 IGMP_SOURCE_TEST_FORWARDING(
3659 } /* scan group sources */
3660 } /* scan igmp groups */
3661 } /* scan igmp sockets */
3662 } /* scan interfaces */
3665 static void igmp_show_source_retransmission(struct pim_instance
*pim
,
3668 struct interface
*ifp
;
3671 "Interface Address Group Source Counter\n");
3673 /* scan interfaces */
3674 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3675 struct pim_interface
*pim_ifp
= ifp
->info
;
3676 struct listnode
*sock_node
;
3677 struct igmp_sock
*igmp
;
3682 /* scan igmp sockets */
3683 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3685 char ifaddr_str
[INET_ADDRSTRLEN
];
3686 struct listnode
*grpnode
;
3687 struct igmp_group
*grp
;
3689 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3690 sizeof(ifaddr_str
));
3692 /* scan igmp groups */
3693 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3695 char group_str
[INET_ADDRSTRLEN
];
3696 struct listnode
*srcnode
;
3697 struct igmp_source
*src
;
3699 pim_inet4_dump("<group?>", grp
->group_addr
,
3700 group_str
, sizeof(group_str
));
3702 /* scan group sources */
3703 for (ALL_LIST_ELEMENTS_RO(
3704 grp
->group_source_list
, srcnode
,
3706 char source_str
[INET_ADDRSTRLEN
];
3709 "<source?>", src
->source_addr
,
3710 source_str
, sizeof(source_str
));
3713 "%-16s %-15s %-15s %-15s %7d\n",
3714 ifp
->name
, ifaddr_str
,
3715 group_str
, source_str
,
3716 src
->source_query_retransmit_count
);
3718 } /* scan group sources */
3719 } /* scan igmp groups */
3720 } /* scan igmp sockets */
3721 } /* scan interfaces */
3724 static void pim_show_bsr(struct pim_instance
*pim
,
3729 char last_bsm_seen
[10];
3732 char bsr_str
[PREFIX_STRLEN
];
3733 json_object
*json
= NULL
;
3735 vty_out(vty
, "PIMv2 Bootstrap information\n");
3737 if (pim
->global_scope
.current_bsr
.s_addr
== INADDR_ANY
) {
3738 strlcpy(bsr_str
, "0.0.0.0", sizeof(bsr_str
));
3739 pim_time_uptime(uptime
, sizeof(uptime
),
3740 pim
->global_scope
.current_bsr_first_ts
);
3741 pim_time_uptime(last_bsm_seen
, sizeof(last_bsm_seen
),
3742 pim
->global_scope
.current_bsr_last_ts
);
3746 pim_inet4_dump("<bsr?>", pim
->global_scope
.current_bsr
,
3747 bsr_str
, sizeof(bsr_str
));
3748 now
= pim_time_monotonic_sec();
3749 pim_time_uptime(uptime
, sizeof(uptime
),
3750 (now
- pim
->global_scope
.current_bsr_first_ts
));
3751 pim_time_uptime(last_bsm_seen
, sizeof(last_bsm_seen
),
3752 now
- pim
->global_scope
.current_bsr_last_ts
);
3755 switch (pim
->global_scope
.state
) {
3757 strlcpy(bsr_state
, "NO_INFO", sizeof(bsr_state
));
3760 strlcpy(bsr_state
, "ACCEPT_ANY", sizeof(bsr_state
));
3762 case ACCEPT_PREFERRED
:
3763 strlcpy(bsr_state
, "ACCEPT_PREFERRED", sizeof(bsr_state
));
3766 strlcpy(bsr_state
, "", sizeof(bsr_state
));
3770 json
= json_object_new_object();
3771 json_object_string_add(json
, "bsr", bsr_str
);
3772 json_object_int_add(json
, "priority",
3773 pim
->global_scope
.current_bsr_prio
);
3774 json_object_int_add(json
, "fragment_tag",
3775 pim
->global_scope
.bsm_frag_tag
);
3776 json_object_string_add(json
, "state", bsr_state
);
3777 json_object_string_add(json
, "upTime", uptime
);
3778 json_object_string_add(json
, "last_bsm_seen", last_bsm_seen
);
3782 vty_out(vty
, "Current preferred BSR address: %s\n", bsr_str
);
3784 "Priority Fragment-Tag State UpTime\n");
3785 vty_out(vty
, " %-12d %-12d %-13s %7s\n",
3786 pim
->global_scope
.current_bsr_prio
,
3787 pim
->global_scope
.bsm_frag_tag
,
3790 vty_out(vty
, "Last BSM seen: %s\n", last_bsm_seen
);
3794 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3795 json
, JSON_C_TO_STRING_PRETTY
));
3796 json_object_free(json
);
3800 static void clear_igmp_interfaces(struct pim_instance
*pim
)
3802 struct interface
*ifp
;
3804 FOR_ALL_INTERFACES (pim
->vrf
, ifp
)
3805 pim_if_addr_del_all_igmp(ifp
);
3807 FOR_ALL_INTERFACES (pim
->vrf
, ifp
)
3808 pim_if_addr_add_all(ifp
);
3811 static void clear_pim_interfaces(struct pim_instance
*pim
)
3813 struct interface
*ifp
;
3815 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3817 pim_neighbor_delete_all(ifp
, "interface cleared");
3822 static void clear_interfaces(struct pim_instance
*pim
)
3824 clear_igmp_interfaces(pim
);
3825 clear_pim_interfaces(pim
);
3828 #define PIM_GET_PIM_INTERFACE(pim_ifp, ifp) \
3829 pim_ifp = ifp->info; \
3832 "%% Enable PIM and/or IGMP on this interface first\n"); \
3833 return CMD_WARNING_CONFIG_FAILED; \
3836 DEFUN (clear_ip_interfaces
,
3837 clear_ip_interfaces_cmd
,
3838 "clear ip interfaces [vrf NAME]",
3841 "Reset interfaces\n"
3845 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3850 clear_interfaces(vrf
->info
);
3855 DEFUN (clear_ip_igmp_interfaces
,
3856 clear_ip_igmp_interfaces_cmd
,
3857 "clear ip igmp [vrf NAME] interfaces",
3862 "Reset IGMP interfaces\n")
3865 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3870 clear_igmp_interfaces(vrf
->info
);
3875 DEFUN (clear_ip_pim_statistics
,
3876 clear_ip_pim_statistics_cmd
,
3877 "clear ip pim statistics [vrf NAME]",
3882 "Reset PIM statistics\n")
3885 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3890 clear_pim_statistics(vrf
->info
);
3894 static void clear_mroute(struct pim_instance
*pim
)
3896 struct pim_upstream
*up
;
3897 struct interface
*ifp
;
3899 /* scan interfaces */
3900 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3901 struct pim_interface
*pim_ifp
= ifp
->info
;
3902 struct listnode
*sock_node
;
3903 struct igmp_sock
*igmp
;
3904 struct pim_ifchannel
*ch
;
3909 /* deleting all ifchannels */
3910 while (!RB_EMPTY(pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
)) {
3911 ch
= RB_ROOT(pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
);
3913 pim_ifchannel_delete(ch
);
3916 /* clean up all igmp groups */
3917 /* scan igmp sockets */
3918 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3921 struct igmp_group
*grp
;
3923 if (igmp
->igmp_group_list
) {
3924 while (igmp
->igmp_group_list
->count
) {
3925 grp
= listnode_head(
3926 igmp
->igmp_group_list
);
3927 igmp_group_delete(grp
);
3934 /* clean up all upstreams*/
3935 while ((up
= rb_pim_upstream_first(&pim
->upstream_head
))) {
3936 pim_upstream_del(pim
, up
, __func__
);
3940 DEFUN (clear_ip_mroute
,
3941 clear_ip_mroute_cmd
,
3942 "clear ip mroute [vrf NAME]",
3945 "Reset multicast routes\n"
3949 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3954 clear_mroute(vrf
->info
);
3959 DEFUN (clear_ip_pim_interfaces
,
3960 clear_ip_pim_interfaces_cmd
,
3961 "clear ip pim [vrf NAME] interfaces",
3966 "Reset PIM interfaces\n")
3969 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3974 clear_pim_interfaces(vrf
->info
);
3979 DEFUN (clear_ip_pim_interface_traffic
,
3980 clear_ip_pim_interface_traffic_cmd
,
3981 "clear ip pim [vrf NAME] interface traffic",
3984 "PIM clear commands\n"
3986 "Reset PIM interfaces\n"
3987 "Reset Protocol Packet counters\n")
3990 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3991 struct interface
*ifp
= NULL
;
3992 struct pim_interface
*pim_ifp
= NULL
;
3997 FOR_ALL_INTERFACES (vrf
, ifp
) {
3998 pim_ifp
= ifp
->info
;
4003 pim_ifp
->pim_ifstat_hello_recv
= 0;
4004 pim_ifp
->pim_ifstat_hello_sent
= 0;
4005 pim_ifp
->pim_ifstat_join_recv
= 0;
4006 pim_ifp
->pim_ifstat_join_send
= 0;
4007 pim_ifp
->pim_ifstat_prune_recv
= 0;
4008 pim_ifp
->pim_ifstat_prune_send
= 0;
4009 pim_ifp
->pim_ifstat_reg_recv
= 0;
4010 pim_ifp
->pim_ifstat_reg_send
= 0;
4011 pim_ifp
->pim_ifstat_reg_stop_recv
= 0;
4012 pim_ifp
->pim_ifstat_reg_stop_send
= 0;
4013 pim_ifp
->pim_ifstat_assert_recv
= 0;
4014 pim_ifp
->pim_ifstat_assert_send
= 0;
4015 pim_ifp
->pim_ifstat_bsm_rx
= 0;
4016 pim_ifp
->pim_ifstat_bsm_tx
= 0;
4022 DEFUN (clear_ip_pim_oil
,
4023 clear_ip_pim_oil_cmd
,
4024 "clear ip pim [vrf NAME] oil",
4029 "Rescan PIM OIL (output interface list)\n")
4032 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4037 pim_scan_oil(vrf
->info
);
4042 DEFUN (show_ip_igmp_interface
,
4043 show_ip_igmp_interface_cmd
,
4044 "show ip igmp [vrf NAME] interface [detail|WORD] [json]",
4049 "IGMP interface information\n"
4055 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4056 bool uj
= use_json(argc
, argv
);
4061 if (argv_find(argv
, argc
, "detail", &idx
)
4062 || argv_find(argv
, argc
, "WORD", &idx
))
4063 igmp_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
4065 igmp_show_interfaces(vrf
->info
, vty
, uj
);
4070 DEFUN (show_ip_igmp_interface_vrf_all
,
4071 show_ip_igmp_interface_vrf_all_cmd
,
4072 "show ip igmp vrf all interface [detail|WORD] [json]",
4077 "IGMP interface information\n"
4083 bool uj
= use_json(argc
, argv
);
4089 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4093 vty_out(vty
, " \"%s\": ", vrf
->name
);
4096 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4097 if (argv_find(argv
, argc
, "detail", &idx
)
4098 || argv_find(argv
, argc
, "WORD", &idx
))
4099 igmp_show_interfaces_single(vrf
->info
, vty
,
4100 argv
[idx
]->arg
, uj
);
4102 igmp_show_interfaces(vrf
->info
, vty
, uj
);
4105 vty_out(vty
, "}\n");
4110 DEFUN (show_ip_igmp_join
,
4111 show_ip_igmp_join_cmd
,
4112 "show ip igmp [vrf NAME] join",
4117 "IGMP static join information\n")
4120 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4125 igmp_show_interface_join(vrf
->info
, vty
);
4130 DEFUN (show_ip_igmp_join_vrf_all
,
4131 show_ip_igmp_join_vrf_all_cmd
,
4132 "show ip igmp vrf all join",
4137 "IGMP static join information\n")
4139 bool uj
= use_json(argc
, argv
);
4145 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4149 vty_out(vty
, " \"%s\": ", vrf
->name
);
4152 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4153 igmp_show_interface_join(vrf
->info
, vty
);
4156 vty_out(vty
, "}\n");
4161 DEFUN (show_ip_igmp_groups
,
4162 show_ip_igmp_groups_cmd
,
4163 "show ip igmp [vrf NAME] groups [json]",
4172 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4173 bool uj
= use_json(argc
, argv
);
4178 igmp_show_groups(vrf
->info
, vty
, uj
);
4183 DEFUN (show_ip_igmp_groups_vrf_all
,
4184 show_ip_igmp_groups_vrf_all_cmd
,
4185 "show ip igmp vrf all groups [json]",
4193 bool uj
= use_json(argc
, argv
);
4199 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4203 vty_out(vty
, " \"%s\": ", vrf
->name
);
4206 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4207 igmp_show_groups(vrf
->info
, vty
, uj
);
4210 vty_out(vty
, "}\n");
4215 DEFUN (show_ip_igmp_groups_retransmissions
,
4216 show_ip_igmp_groups_retransmissions_cmd
,
4217 "show ip igmp [vrf NAME] groups retransmissions",
4223 "IGMP group retransmissions\n")
4226 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4231 igmp_show_group_retransmission(vrf
->info
, vty
);
4236 DEFUN (show_ip_igmp_sources
,
4237 show_ip_igmp_sources_cmd
,
4238 "show ip igmp [vrf NAME] sources",
4246 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4251 igmp_show_sources(vrf
->info
, vty
);
4256 DEFUN (show_ip_igmp_sources_retransmissions
,
4257 show_ip_igmp_sources_retransmissions_cmd
,
4258 "show ip igmp [vrf NAME] sources retransmissions",
4264 "IGMP source retransmissions\n")
4267 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4272 igmp_show_source_retransmission(vrf
->info
, vty
);
4277 DEFUN (show_ip_igmp_statistics
,
4278 show_ip_igmp_statistics_cmd
,
4279 "show ip igmp [vrf NAME] statistics [interface WORD] [json]",
4290 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4291 bool uj
= use_json(argc
, argv
);
4296 if (argv_find(argv
, argc
, "WORD", &idx
))
4297 igmp_show_statistics(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
4299 igmp_show_statistics(vrf
->info
, vty
, NULL
, uj
);
4304 DEFUN (show_ip_pim_mlag_summary
,
4305 show_ip_pim_mlag_summary_cmd
,
4306 "show ip pim mlag summary [json]",
4311 "status and stats\n"
4314 bool uj
= use_json(argc
, argv
);
4315 char role_buf
[MLAG_ROLE_STRSIZE
];
4316 char addr_buf
[INET_ADDRSTRLEN
];
4319 json_object
*json
= NULL
;
4320 json_object
*json_stat
= NULL
;
4322 json
= json_object_new_object();
4323 if (router
->mlag_flags
& PIM_MLAGF_LOCAL_CONN_UP
)
4324 json_object_boolean_true_add(json
, "mlagConnUp");
4325 if (router
->mlag_flags
& PIM_MLAGF_PEER_CONN_UP
)
4326 json_object_boolean_true_add(json
, "mlagPeerConnUp");
4327 if (router
->mlag_flags
& PIM_MLAGF_PEER_ZEBRA_UP
)
4328 json_object_boolean_true_add(json
, "mlagPeerZebraUp");
4329 json_object_string_add(json
, "mlagRole",
4330 mlag_role2str(router
->mlag_role
,
4331 role_buf
, sizeof(role_buf
)));
4332 inet_ntop(AF_INET
, &router
->local_vtep_ip
,
4333 addr_buf
, INET_ADDRSTRLEN
);
4334 json_object_string_add(json
, "localVtepIp", addr_buf
);
4335 inet_ntop(AF_INET
, &router
->anycast_vtep_ip
,
4336 addr_buf
, INET_ADDRSTRLEN
);
4337 json_object_string_add(json
, "anycastVtepIp", addr_buf
);
4338 json_object_string_add(json
, "peerlinkRif",
4339 router
->peerlink_rif
);
4341 json_stat
= json_object_new_object();
4342 json_object_int_add(json_stat
, "mlagConnFlaps",
4343 router
->mlag_stats
.mlagd_session_downs
);
4344 json_object_int_add(json_stat
, "mlagPeerConnFlaps",
4345 router
->mlag_stats
.peer_session_downs
);
4346 json_object_int_add(json_stat
, "mlagPeerZebraFlaps",
4347 router
->mlag_stats
.peer_zebra_downs
);
4348 json_object_int_add(json_stat
, "mrouteAddRx",
4349 router
->mlag_stats
.msg
.mroute_add_rx
);
4350 json_object_int_add(json_stat
, "mrouteAddTx",
4351 router
->mlag_stats
.msg
.mroute_add_tx
);
4352 json_object_int_add(json_stat
, "mrouteDelRx",
4353 router
->mlag_stats
.msg
.mroute_del_rx
);
4354 json_object_int_add(json_stat
, "mrouteDelTx",
4355 router
->mlag_stats
.msg
.mroute_del_tx
);
4356 json_object_int_add(json_stat
, "mlagStatusUpdates",
4357 router
->mlag_stats
.msg
.mlag_status_updates
);
4358 json_object_int_add(json_stat
, "peerZebraStatusUpdates",
4359 router
->mlag_stats
.msg
.peer_zebra_status_updates
);
4360 json_object_int_add(json_stat
, "pimStatusUpdates",
4361 router
->mlag_stats
.msg
.pim_status_updates
);
4362 json_object_int_add(json_stat
, "vxlanUpdates",
4363 router
->mlag_stats
.msg
.vxlan_updates
);
4364 json_object_object_add(json
, "connStats", json_stat
);
4366 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4367 json
, JSON_C_TO_STRING_PRETTY
));
4368 json_object_free(json
);
4372 vty_out(vty
, "MLAG daemon connection: %s\n",
4373 (router
->mlag_flags
& PIM_MLAGF_LOCAL_CONN_UP
)
4375 vty_out(vty
, "MLAG peer state: %s\n",
4376 (router
->mlag_flags
& PIM_MLAGF_PEER_CONN_UP
)
4378 vty_out(vty
, "Zebra peer state: %s\n",
4379 (router
->mlag_flags
& PIM_MLAGF_PEER_ZEBRA_UP
)
4381 vty_out(vty
, "MLAG role: %s\n",
4382 mlag_role2str(router
->mlag_role
, role_buf
, sizeof(role_buf
)));
4383 inet_ntop(AF_INET
, &router
->local_vtep_ip
,
4384 addr_buf
, INET_ADDRSTRLEN
);
4385 vty_out(vty
, "Local VTEP IP: %s\n", addr_buf
);
4386 inet_ntop(AF_INET
, &router
->anycast_vtep_ip
,
4387 addr_buf
, INET_ADDRSTRLEN
);
4388 vty_out(vty
, "Anycast VTEP IP: %s\n", addr_buf
);
4389 vty_out(vty
, "Peerlink: %s\n", router
->peerlink_rif
);
4390 vty_out(vty
, "Session flaps: mlagd: %d mlag-peer: %d zebra-peer: %d\n",
4391 router
->mlag_stats
.mlagd_session_downs
,
4392 router
->mlag_stats
.peer_session_downs
,
4393 router
->mlag_stats
.peer_zebra_downs
);
4394 vty_out(vty
, "Message Statistics:\n");
4395 vty_out(vty
, " mroute adds: rx: %d, tx: %d\n",
4396 router
->mlag_stats
.msg
.mroute_add_rx
,
4397 router
->mlag_stats
.msg
.mroute_add_tx
);
4398 vty_out(vty
, " mroute dels: rx: %d, tx: %d\n",
4399 router
->mlag_stats
.msg
.mroute_del_rx
,
4400 router
->mlag_stats
.msg
.mroute_del_tx
);
4401 vty_out(vty
, " peer zebra status updates: %d\n",
4402 router
->mlag_stats
.msg
.peer_zebra_status_updates
);
4403 vty_out(vty
, " PIM status updates: %d\n",
4404 router
->mlag_stats
.msg
.pim_status_updates
);
4405 vty_out(vty
, " VxLAN updates: %d\n",
4406 router
->mlag_stats
.msg
.vxlan_updates
);
4411 DEFUN (show_ip_pim_assert
,
4412 show_ip_pim_assert_cmd
,
4413 "show ip pim [vrf NAME] assert",
4418 "PIM interface assert\n")
4421 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4426 pim_show_assert(vrf
->info
, vty
);
4431 DEFUN (show_ip_pim_assert_internal
,
4432 show_ip_pim_assert_internal_cmd
,
4433 "show ip pim [vrf NAME] assert-internal",
4438 "PIM interface internal assert state\n")
4441 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4446 pim_show_assert_internal(vrf
->info
, vty
);
4451 DEFUN (show_ip_pim_assert_metric
,
4452 show_ip_pim_assert_metric_cmd
,
4453 "show ip pim [vrf NAME] assert-metric",
4458 "PIM interface assert metric\n")
4461 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4466 pim_show_assert_metric(vrf
->info
, vty
);
4471 DEFUN (show_ip_pim_assert_winner_metric
,
4472 show_ip_pim_assert_winner_metric_cmd
,
4473 "show ip pim [vrf NAME] assert-winner-metric",
4478 "PIM interface assert winner metric\n")
4481 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4486 pim_show_assert_winner_metric(vrf
->info
, vty
);
4491 DEFUN (show_ip_pim_interface
,
4492 show_ip_pim_interface_cmd
,
4493 "show ip pim [mlag] [vrf NAME] interface [detail|WORD] [json]",
4499 "PIM interface information\n"
4505 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4506 bool uj
= use_json(argc
, argv
);
4512 if (argv_find(argv
, argc
, "mlag", &idx
))
4515 if (argv_find(argv
, argc
, "WORD", &idx
)
4516 || argv_find(argv
, argc
, "detail", &idx
))
4517 pim_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, mlag
,
4520 pim_show_interfaces(vrf
->info
, vty
, mlag
, uj
);
4525 DEFUN (show_ip_pim_interface_vrf_all
,
4526 show_ip_pim_interface_vrf_all_cmd
,
4527 "show ip pim [mlag] vrf all interface [detail|WORD] [json]",
4533 "PIM interface information\n"
4539 bool uj
= use_json(argc
, argv
);
4544 if (argv_find(argv
, argc
, "mlag", &idx
))
4550 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4554 vty_out(vty
, " \"%s\": ", vrf
->name
);
4557 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4558 if (argv_find(argv
, argc
, "WORD", &idx
)
4559 || argv_find(argv
, argc
, "detail", &idx
))
4560 pim_show_interfaces_single(vrf
->info
, vty
,
4561 argv
[idx
]->arg
, mlag
, uj
);
4563 pim_show_interfaces(vrf
->info
, vty
, mlag
, uj
);
4566 vty_out(vty
, "}\n");
4571 DEFPY (show_ip_pim_join
,
4572 show_ip_pim_join_cmd
,
4573 "show ip pim [vrf NAME] join [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
4578 "PIM interface join information\n"
4579 "The Source or Group\n"
4583 struct prefix_sg sg
= {0};
4586 struct pim_instance
*pim
;
4588 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
4591 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
4594 pim
= pim_get_pim_instance(v
->vrf_id
);
4597 vty_out(vty
, "%% Unable to find pim instance\n");
4601 if (s_or_g
.s_addr
!= 0) {
4602 if (g
.s_addr
!= 0) {
4609 pim_show_join(pim
, vty
, &sg
, uj
);
4614 DEFUN (show_ip_pim_join_vrf_all
,
4615 show_ip_pim_join_vrf_all_cmd
,
4616 "show ip pim vrf all join [json]",
4621 "PIM interface join information\n"
4624 struct prefix_sg sg
= {0};
4625 bool uj
= use_json(argc
, argv
);
4631 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4635 vty_out(vty
, " \"%s\": ", vrf
->name
);
4638 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4639 pim_show_join(vrf
->info
, vty
, &sg
, uj
);
4642 vty_out(vty
, "}\n");
4647 static void pim_show_jp_agg_helper(struct vty
*vty
,
4648 struct interface
*ifp
,
4649 struct pim_neighbor
*neigh
,
4650 struct pim_upstream
*up
,
4653 char src_str
[INET_ADDRSTRLEN
];
4654 char grp_str
[INET_ADDRSTRLEN
];
4655 char rpf_str
[INET_ADDRSTRLEN
];
4657 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
4658 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
4659 /* pius->address.s_addr */
4660 pim_inet4_dump("<rpf?>", neigh
->source_addr
, rpf_str
, sizeof(rpf_str
));
4662 vty_out(vty
, "%-16s %-15s %-15s %-15s %5s\n",
4663 ifp
->name
, rpf_str
, src_str
,
4664 grp_str
, is_join
?"J":"P");
4667 static void pim_show_jp_agg_list(struct pim_instance
*pim
, struct vty
*vty
)
4669 struct interface
*ifp
;
4670 struct pim_interface
*pim_ifp
;
4671 struct listnode
*n_node
;
4672 struct pim_neighbor
*neigh
;
4673 struct listnode
*jag_node
;
4674 struct pim_jp_agg_group
*jag
;
4675 struct listnode
*js_node
;
4676 struct pim_jp_sources
*js
;
4679 "Interface RPF Nbr Source Group State\n");
4681 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
4682 pim_ifp
= ifp
->info
;
4686 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
,
4688 for (ALL_LIST_ELEMENTS_RO(neigh
->upstream_jp_agg
,
4690 for (ALL_LIST_ELEMENTS_RO(jag
->sources
,
4692 pim_show_jp_agg_helper(vty
,
4701 DEFPY (show_ip_pim_jp_agg
,
4702 show_ip_pim_jp_agg_cmd
,
4703 "show ip pim [vrf NAME] jp-agg",
4708 "join prune aggregation list\n")
4711 struct pim_instance
*pim
;
4713 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
4716 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
4719 pim
= pim_get_pim_instance(v
->vrf_id
);
4722 vty_out(vty
, "%% Unable to find pim instance\n");
4726 pim_show_jp_agg_list(pim
, vty
);
4731 DEFUN (show_ip_pim_local_membership
,
4732 show_ip_pim_local_membership_cmd
,
4733 "show ip pim [vrf NAME] local-membership [json]",
4738 "PIM interface local-membership\n"
4742 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4743 bool uj
= use_json(argc
, argv
);
4748 pim_show_membership(vrf
->info
, vty
, uj
);
4753 static void pim_show_mlag_up_entry_detail(struct vrf
*vrf
,
4754 struct vty
*vty
, struct pim_upstream
*up
,
4755 char *src_str
, char *grp_str
, json_object
*json
)
4758 json_object
*json_row
= NULL
;
4759 json_object
*own_list
= NULL
;
4760 json_object
*json_group
= NULL
;
4763 json_object_object_get_ex(json
, grp_str
, &json_group
);
4765 json_group
= json_object_new_object();
4766 json_object_object_add(json
, grp_str
,
4770 json_row
= json_object_new_object();
4771 json_object_string_add(json_row
, "source", src_str
);
4772 json_object_string_add(json_row
, "group", grp_str
);
4774 own_list
= json_object_new_array();
4775 if (pim_up_mlag_is_local(up
))
4776 json_object_array_add(own_list
,
4777 json_object_new_string("local"));
4778 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
))
4779 json_object_array_add(own_list
,
4780 json_object_new_string("peer"));
4781 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE
))
4782 json_object_array_add(
4783 own_list
, json_object_new_string("Interface"));
4784 json_object_object_add(json_row
, "owners", own_list
);
4786 json_object_int_add(json_row
, "localCost",
4787 pim_up_mlag_local_cost(up
));
4788 json_object_int_add(json_row
, "peerCost",
4789 pim_up_mlag_peer_cost(up
));
4790 if (PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up
->flags
))
4791 json_object_boolean_false_add(json_row
, "df");
4793 json_object_boolean_true_add(json_row
, "df");
4794 json_object_object_add(json_group
, src_str
, json_row
);
4799 if (pim_up_mlag_is_local(up
))
4800 strlcat(own_str
, "L", sizeof(own_str
));
4801 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
))
4802 strlcat(own_str
, "P", sizeof(own_str
));
4803 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE
))
4804 strlcat(own_str
, "I", sizeof(own_str
));
4805 /* XXX - fixup, print paragraph output */
4807 "%-15s %-15s %-6s %-11u %-10d %2s\n",
4808 src_str
, grp_str
, own_str
,
4809 pim_up_mlag_local_cost(up
),
4810 pim_up_mlag_peer_cost(up
),
4811 PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up
->flags
)
4816 static void pim_show_mlag_up_detail(struct vrf
*vrf
,
4817 struct vty
*vty
, const char *src_or_group
,
4818 const char *group
, bool uj
)
4820 char src_str
[INET_ADDRSTRLEN
];
4821 char grp_str
[INET_ADDRSTRLEN
];
4822 struct pim_upstream
*up
;
4823 struct pim_instance
*pim
= vrf
->info
;
4824 json_object
*json
= NULL
;
4827 json
= json_object_new_object();
4830 "Source Group Owner Local-cost Peer-cost DF\n");
4832 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
4833 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
)
4834 && !(up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE
)
4835 && !pim_up_mlag_is_local(up
))
4838 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
4839 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
4840 /* XXX: strcmps are clearly inefficient. we should do uint comps
4844 if (strcmp(src_str
, src_or_group
) ||
4845 strcmp(grp_str
, group
))
4848 if (strcmp(src_str
, src_or_group
) &&
4849 strcmp(grp_str
, src_or_group
))
4852 pim_show_mlag_up_entry_detail(vrf
, vty
, up
,
4853 src_str
, grp_str
, json
);
4857 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4858 json
, JSON_C_TO_STRING_PRETTY
));
4859 json_object_free(json
);
4863 static void pim_show_mlag_up_vrf(struct vrf
*vrf
, struct vty
*vty
, bool uj
)
4865 json_object
*json
= NULL
;
4866 json_object
*json_row
;
4867 struct pim_upstream
*up
;
4868 char src_str
[INET_ADDRSTRLEN
];
4869 char grp_str
[INET_ADDRSTRLEN
];
4870 struct pim_instance
*pim
= vrf
->info
;
4871 json_object
*json_group
= NULL
;
4874 json
= json_object_new_object();
4877 "Source Group Owner Local-cost Peer-cost DF\n");
4880 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
4881 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
)
4882 && !(up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE
)
4883 && !pim_up_mlag_is_local(up
))
4885 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
4886 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
4888 json_object
*own_list
= NULL
;
4890 json_object_object_get_ex(json
, grp_str
, &json_group
);
4892 json_group
= json_object_new_object();
4893 json_object_object_add(json
, grp_str
,
4897 json_row
= json_object_new_object();
4898 json_object_string_add(json_row
, "vrf", vrf
->name
);
4899 json_object_string_add(json_row
, "source", src_str
);
4900 json_object_string_add(json_row
, "group", grp_str
);
4902 own_list
= json_object_new_array();
4903 if (pim_up_mlag_is_local(up
)) {
4905 json_object_array_add(own_list
,
4906 json_object_new_string("local"));
4908 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
)) {
4909 json_object_array_add(own_list
,
4910 json_object_new_string("peer"));
4912 json_object_object_add(json_row
, "owners", own_list
);
4914 json_object_int_add(json_row
, "localCost",
4915 pim_up_mlag_local_cost(up
));
4916 json_object_int_add(json_row
, "peerCost",
4917 pim_up_mlag_peer_cost(up
));
4918 if (PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up
->flags
))
4919 json_object_boolean_false_add(json_row
, "df");
4921 json_object_boolean_true_add(json_row
, "df");
4922 json_object_object_add(json_group
, src_str
, json_row
);
4927 if (pim_up_mlag_is_local(up
))
4928 strlcat(own_str
, "L", sizeof(own_str
));
4929 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
))
4930 strlcat(own_str
, "P", sizeof(own_str
));
4931 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE
))
4932 strlcat(own_str
, "I", sizeof(own_str
));
4934 "%-15s %-15s %-6s %-11u %-10u %2s\n",
4935 src_str
, grp_str
, own_str
,
4936 pim_up_mlag_local_cost(up
),
4937 pim_up_mlag_peer_cost(up
),
4938 PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up
->flags
)
4943 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4944 json
, JSON_C_TO_STRING_PRETTY
));
4945 json_object_free(json
);
4949 static void pim_show_mlag_help_string(struct vty
*vty
, bool uj
)
4952 vty_out(vty
, "Owner codes:\n");
4954 "L: EVPN-MLAG Entry, I:PIM-MLAG Entry, "
4960 DEFUN(show_ip_pim_mlag_up
, show_ip_pim_mlag_up_cmd
,
4961 "show ip pim [vrf NAME] mlag upstream [A.B.C.D [A.B.C.D]] [json]",
4968 "Unicast or Multicast address\n"
4969 "Multicast address\n" JSON_STR
)
4971 const char *src_or_group
= NULL
;
4972 const char *group
= NULL
;
4974 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4975 bool uj
= use_json(argc
, argv
);
4977 if (!vrf
|| !vrf
->info
) {
4978 vty_out(vty
, "%s: VRF or Info missing\n", __func__
);
4985 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
4986 src_or_group
= argv
[idx
]->arg
;
4988 group
= argv
[idx
+ 1]->arg
;
4991 pim_show_mlag_help_string(vty
, uj
);
4994 pim_show_mlag_up_detail(vrf
, vty
, src_or_group
, group
, uj
);
4996 pim_show_mlag_up_vrf(vrf
, vty
, uj
);
5002 DEFUN(show_ip_pim_mlag_up_vrf_all
, show_ip_pim_mlag_up_vrf_all_cmd
,
5003 "show ip pim vrf all mlag upstream [json]",
5004 SHOW_STR IP_STR PIM_STR VRF_CMD_HELP_STR
5006 "upstream\n" JSON_STR
)
5009 bool uj
= use_json(argc
, argv
);
5011 pim_show_mlag_help_string(vty
, uj
);
5012 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5013 pim_show_mlag_up_vrf(vrf
, vty
, uj
);
5019 DEFUN (show_ip_pim_neighbor
,
5020 show_ip_pim_neighbor_cmd
,
5021 "show ip pim [vrf NAME] neighbor [detail|WORD] [json]",
5026 "PIM neighbor information\n"
5028 "Name of interface or neighbor\n"
5032 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5033 bool uj
= use_json(argc
, argv
);
5038 if (argv_find(argv
, argc
, "detail", &idx
)
5039 || argv_find(argv
, argc
, "WORD", &idx
))
5040 pim_show_neighbors_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
5042 pim_show_neighbors(vrf
->info
, vty
, uj
);
5047 DEFUN (show_ip_pim_neighbor_vrf_all
,
5048 show_ip_pim_neighbor_vrf_all_cmd
,
5049 "show ip pim vrf all neighbor [detail|WORD] [json]",
5054 "PIM neighbor information\n"
5056 "Name of interface or neighbor\n"
5060 bool uj
= use_json(argc
, argv
);
5066 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5070 vty_out(vty
, " \"%s\": ", vrf
->name
);
5073 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5074 if (argv_find(argv
, argc
, "detail", &idx
)
5075 || argv_find(argv
, argc
, "WORD", &idx
))
5076 pim_show_neighbors_single(vrf
->info
, vty
,
5077 argv
[idx
]->arg
, uj
);
5079 pim_show_neighbors(vrf
->info
, vty
, uj
);
5082 vty_out(vty
, "}\n");
5087 DEFUN (show_ip_pim_secondary
,
5088 show_ip_pim_secondary_cmd
,
5089 "show ip pim [vrf NAME] secondary",
5094 "PIM neighbor addresses\n")
5097 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5102 pim_show_neighbors_secondary(vrf
->info
, vty
);
5107 DEFUN (show_ip_pim_state
,
5108 show_ip_pim_state_cmd
,
5109 "show ip pim [vrf NAME] state [A.B.C.D [A.B.C.D]] [json]",
5114 "PIM state information\n"
5115 "Unicast or Multicast address\n"
5116 "Multicast address\n"
5119 const char *src_or_group
= NULL
;
5120 const char *group
= NULL
;
5122 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5123 bool uj
= use_json(argc
, argv
);
5131 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
5132 src_or_group
= argv
[idx
]->arg
;
5134 group
= argv
[idx
+ 1]->arg
;
5137 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
5142 DEFUN (show_ip_pim_state_vrf_all
,
5143 show_ip_pim_state_vrf_all_cmd
,
5144 "show ip pim vrf all state [A.B.C.D [A.B.C.D]] [json]",
5149 "PIM state information\n"
5150 "Unicast or Multicast address\n"
5151 "Multicast address\n"
5154 const char *src_or_group
= NULL
;
5155 const char *group
= NULL
;
5157 bool uj
= use_json(argc
, argv
);
5166 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
5167 src_or_group
= argv
[idx
]->arg
;
5169 group
= argv
[idx
+ 1]->arg
;
5172 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5176 vty_out(vty
, " \"%s\": ", vrf
->name
);
5179 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5180 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
5183 vty_out(vty
, "}\n");
5188 DEFPY (show_ip_pim_upstream
,
5189 show_ip_pim_upstream_cmd
,
5190 "show ip pim [vrf NAME] upstream [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
5195 "PIM upstream information\n"
5196 "The Source or Group\n"
5200 struct prefix_sg sg
= {0};
5203 struct pim_instance
*pim
;
5205 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
5208 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
5211 pim
= pim_get_pim_instance(v
->vrf_id
);
5214 vty_out(vty
, "%% Unable to find pim instance\n");
5218 if (s_or_g
.s_addr
!= 0) {
5219 if (g
.s_addr
!= 0) {
5225 pim_show_upstream(pim
, vty
, &sg
, uj
);
5230 DEFUN (show_ip_pim_upstream_vrf_all
,
5231 show_ip_pim_upstream_vrf_all_cmd
,
5232 "show ip pim vrf all upstream [json]",
5237 "PIM upstream information\n"
5240 struct prefix_sg sg
= {0};
5241 bool uj
= use_json(argc
, argv
);
5247 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5251 vty_out(vty
, " \"%s\": ", vrf
->name
);
5254 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5255 pim_show_upstream(vrf
->info
, vty
, &sg
, uj
);
5261 DEFUN (show_ip_pim_channel
,
5262 show_ip_pim_channel_cmd
,
5263 "show ip pim [vrf NAME] channel [json]",
5268 "PIM downstream channel info\n"
5272 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5273 bool uj
= use_json(argc
, argv
);
5278 pim_show_channel(vrf
->info
, vty
, uj
);
5283 DEFUN (show_ip_pim_upstream_join_desired
,
5284 show_ip_pim_upstream_join_desired_cmd
,
5285 "show ip pim [vrf NAME] upstream-join-desired [json]",
5290 "PIM upstream join-desired\n"
5294 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5295 bool uj
= use_json(argc
, argv
);
5300 pim_show_join_desired(vrf
->info
, vty
, uj
);
5305 DEFUN (show_ip_pim_upstream_rpf
,
5306 show_ip_pim_upstream_rpf_cmd
,
5307 "show ip pim [vrf NAME] upstream-rpf [json]",
5312 "PIM upstream source rpf\n"
5316 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5317 bool uj
= use_json(argc
, argv
);
5322 pim_show_upstream_rpf(vrf
->info
, vty
, uj
);
5327 DEFUN (show_ip_pim_rp
,
5329 "show ip pim [vrf NAME] rp-info [json]",
5334 "PIM RP information\n"
5338 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5339 bool uj
= use_json(argc
, argv
);
5344 pim_rp_show_information(vrf
->info
, vty
, uj
);
5349 DEFUN (show_ip_pim_rp_vrf_all
,
5350 show_ip_pim_rp_vrf_all_cmd
,
5351 "show ip pim vrf all rp-info [json]",
5356 "PIM RP information\n"
5359 bool uj
= use_json(argc
, argv
);
5365 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5369 vty_out(vty
, " \"%s\": ", vrf
->name
);
5372 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5373 pim_rp_show_information(vrf
->info
, vty
, uj
);
5376 vty_out(vty
, "}\n");
5381 DEFUN (show_ip_pim_rpf
,
5382 show_ip_pim_rpf_cmd
,
5383 "show ip pim [vrf NAME] rpf [json]",
5388 "PIM cached source rpf information\n"
5392 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5393 bool uj
= use_json(argc
, argv
);
5398 pim_show_rpf(vrf
->info
, vty
, uj
);
5403 DEFUN (show_ip_pim_rpf_vrf_all
,
5404 show_ip_pim_rpf_vrf_all_cmd
,
5405 "show ip pim vrf all rpf [json]",
5410 "PIM cached source rpf information\n"
5413 bool uj
= use_json(argc
, argv
);
5419 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5423 vty_out(vty
, " \"%s\": ", vrf
->name
);
5426 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5427 pim_show_rpf(vrf
->info
, vty
, uj
);
5430 vty_out(vty
, "}\n");
5435 DEFUN (show_ip_pim_nexthop
,
5436 show_ip_pim_nexthop_cmd
,
5437 "show ip pim [vrf NAME] nexthop",
5442 "PIM cached nexthop rpf information\n")
5445 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5450 pim_show_nexthop(vrf
->info
, vty
);
5455 DEFUN (show_ip_pim_nexthop_lookup
,
5456 show_ip_pim_nexthop_lookup_cmd
,
5457 "show ip pim [vrf NAME] nexthop-lookup A.B.C.D A.B.C.D",
5462 "PIM cached nexthop rpf lookup\n"
5463 "Source/RP address\n"
5464 "Multicast Group address\n")
5466 struct prefix nht_p
;
5468 struct in_addr src_addr
, grp_addr
;
5469 struct in_addr vif_source
;
5470 const char *addr_str
, *addr_str1
;
5472 struct pim_nexthop nexthop
;
5473 char nexthop_addr_str
[PREFIX_STRLEN
];
5474 char grp_str
[PREFIX_STRLEN
];
5476 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5481 argv_find(argv
, argc
, "A.B.C.D", &idx
);
5482 addr_str
= argv
[idx
]->arg
;
5483 result
= inet_pton(AF_INET
, addr_str
, &src_addr
);
5485 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
5486 errno
, safe_strerror(errno
));
5490 if (pim_is_group_224_4(src_addr
)) {
5492 "Invalid argument. Expected Valid Source Address.\n");
5496 addr_str1
= argv
[idx
+ 1]->arg
;
5497 result
= inet_pton(AF_INET
, addr_str1
, &grp_addr
);
5499 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
5500 errno
, safe_strerror(errno
));
5504 if (!pim_is_group_224_4(grp_addr
)) {
5506 "Invalid argument. Expected Valid Multicast Group Address.\n");
5510 if (!pim_rp_set_upstream_addr(vrf
->info
, &vif_source
, src_addr
,
5514 nht_p
.family
= AF_INET
;
5515 nht_p
.prefixlen
= IPV4_MAX_BITLEN
;
5516 nht_p
.u
.prefix4
= vif_source
;
5517 grp
.family
= AF_INET
;
5518 grp
.prefixlen
= IPV4_MAX_BITLEN
;
5519 grp
.u
.prefix4
= grp_addr
;
5520 memset(&nexthop
, 0, sizeof(nexthop
));
5522 result
= pim_ecmp_nexthop_lookup(vrf
->info
, &nexthop
, &nht_p
, &grp
, 0);
5526 "Nexthop Lookup failed, no usable routes returned.\n");
5530 pim_addr_dump("<grp?>", &grp
, grp_str
, sizeof(grp_str
));
5531 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
5532 nexthop_addr_str
, sizeof(nexthop_addr_str
));
5533 vty_out(vty
, "Group %s --- Nexthop %s Interface %s \n", grp_str
,
5534 nexthop_addr_str
, nexthop
.interface
->name
);
5539 DEFUN (show_ip_pim_interface_traffic
,
5540 show_ip_pim_interface_traffic_cmd
,
5541 "show ip pim [vrf NAME] interface traffic [WORD] [json]",
5546 "PIM interface information\n"
5547 "Protocol Packet counters\n"
5552 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5553 bool uj
= use_json(argc
, argv
);
5558 if (argv_find(argv
, argc
, "WORD", &idx
))
5559 pim_show_interface_traffic_single(vrf
->info
, vty
,
5560 argv
[idx
]->arg
, uj
);
5562 pim_show_interface_traffic(vrf
->info
, vty
, uj
);
5567 DEFUN (show_ip_pim_bsm_db
,
5568 show_ip_pim_bsm_db_cmd
,
5569 "show ip pim bsm-database [vrf NAME] [json]",
5573 "PIM cached bsm packets information\n"
5578 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5579 bool uj
= use_json(argc
, argv
);
5584 pim_show_bsm_db(vrf
->info
, vty
, uj
);
5588 DEFUN (show_ip_pim_bsrp
,
5589 show_ip_pim_bsrp_cmd
,
5590 "show ip pim bsrp-info [vrf NAME] [json]",
5594 "PIM cached group-rp mappings information\n"
5599 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5600 bool uj
= use_json(argc
, argv
);
5605 pim_show_group_rp_mappings_info(vrf
->info
, vty
, uj
);
5610 DEFUN (show_ip_pim_statistics
,
5611 show_ip_pim_statistics_cmd
,
5612 "show ip pim [vrf NAME] statistics [interface WORD] [json]",
5623 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5624 bool uj
= use_json(argc
, argv
);
5629 if (argv_find(argv
, argc
, "WORD", &idx
))
5630 pim_show_statistics(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
5632 pim_show_statistics(vrf
->info
, vty
, NULL
, uj
);
5637 static void show_multicast_interfaces(struct pim_instance
*pim
, struct vty
*vty
)
5639 struct interface
*ifp
;
5644 "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut\n");
5646 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
5647 struct pim_interface
*pim_ifp
;
5648 struct in_addr ifaddr
;
5649 struct sioc_vif_req vreq
;
5651 pim_ifp
= ifp
->info
;
5656 memset(&vreq
, 0, sizeof(vreq
));
5657 vreq
.vifi
= pim_ifp
->mroute_vif_index
;
5659 if (ioctl(pim
->mroute_socket
, SIOCGETVIFCNT
, &vreq
)) {
5661 "ioctl(SIOCGETVIFCNT=%lu) failure for interface %s vif_index=%d: errno=%d: %s",
5662 (unsigned long)SIOCGETVIFCNT
, ifp
->name
,
5663 pim_ifp
->mroute_vif_index
, errno
,
5664 safe_strerror(errno
));
5667 ifaddr
= pim_ifp
->primary_address
;
5669 vty_out(vty
, "%-16s %-15s %3d %3d %7lu %7lu %10lu %10lu\n",
5670 ifp
->name
, inet_ntoa(ifaddr
), ifp
->ifindex
,
5671 pim_ifp
->mroute_vif_index
, (unsigned long)vreq
.icount
,
5672 (unsigned long)vreq
.ocount
, (unsigned long)vreq
.ibytes
,
5673 (unsigned long)vreq
.obytes
);
5677 static void pim_cmd_show_ip_multicast_helper(struct pim_instance
*pim
,
5680 struct vrf
*vrf
= pim
->vrf
;
5681 time_t now
= pim_time_monotonic_sec();
5687 vty_out(vty
, "Router MLAG Role: %s\n",
5688 mlag_role2str(router
->mlag_role
, mlag_role
, sizeof(mlag_role
)));
5689 vty_out(vty
, "Mroute socket descriptor:");
5691 vty_out(vty
, " %d(%s)\n", pim
->mroute_socket
, vrf
->name
);
5693 pim_time_uptime(uptime
, sizeof(uptime
),
5694 now
- pim
->mroute_socket_creation
);
5695 vty_out(vty
, "Mroute socket uptime: %s\n", uptime
);
5699 pim_zebra_zclient_update(vty
);
5700 pim_zlookup_show_ip_multicast(vty
);
5703 vty_out(vty
, "Maximum highest VifIndex: %d\n", PIM_MAX_USABLE_VIFS
);
5706 vty_out(vty
, "Upstream Join Timer: %d secs\n", router
->t_periodic
);
5707 vty_out(vty
, "Join/Prune Holdtime: %d secs\n", PIM_JP_HOLDTIME
);
5708 vty_out(vty
, "PIM ECMP: %s\n", pim
->ecmp_enable
? "Enable" : "Disable");
5709 vty_out(vty
, "PIM ECMP Rebalance: %s\n",
5710 pim
->ecmp_rebalance_enable
? "Enable" : "Disable");
5714 show_rpf_refresh_stats(vty
, pim
, now
, NULL
);
5718 show_scan_oil_stats(pim
, vty
, now
);
5720 show_multicast_interfaces(pim
, vty
);
5723 DEFUN (show_ip_multicast
,
5724 show_ip_multicast_cmd
,
5725 "show ip multicast [vrf NAME]",
5729 "Multicast global information\n")
5732 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5737 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
5742 DEFUN (show_ip_multicast_vrf_all
,
5743 show_ip_multicast_vrf_all_cmd
,
5744 "show ip multicast vrf all",
5748 "Multicast global information\n")
5750 bool uj
= use_json(argc
, argv
);
5756 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5760 vty_out(vty
, " \"%s\": ", vrf
->name
);
5763 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5764 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
5767 vty_out(vty
, "}\n");
5772 static void show_mroute(struct pim_instance
*pim
, struct vty
*vty
,
5773 struct prefix_sg
*sg
, bool fill
, bool uj
)
5775 struct listnode
*node
;
5776 struct channel_oil
*c_oil
;
5777 struct static_route
*s_route
;
5779 json_object
*json
= NULL
;
5780 json_object
*json_group
= NULL
;
5781 json_object
*json_source
= NULL
;
5782 json_object
*json_oil
= NULL
;
5783 json_object
*json_ifp_out
= NULL
;
5786 char grp_str
[INET_ADDRSTRLEN
];
5787 char src_str
[INET_ADDRSTRLEN
];
5788 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
5789 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
5791 struct interface
*ifp_in
;
5795 json
= json_object_new_object();
5798 "Source Group Proto Input Output TTL Uptime\n");
5801 now
= pim_time_monotonic_sec();
5803 /* print list of PIM and IGMP routes */
5804 frr_each (rb_pim_oil
, &pim
->channel_oil_head
, c_oil
) {
5807 if (!c_oil
->installed
&& !uj
)
5810 if (sg
->grp
.s_addr
!= 0 &&
5811 sg
->grp
.s_addr
!= c_oil
->oil
.mfcc_mcastgrp
.s_addr
)
5813 if (sg
->src
.s_addr
!= 0 &&
5814 sg
->src
.s_addr
!= c_oil
->oil
.mfcc_origin
.s_addr
)
5817 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
5819 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
5821 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
5824 strlcpy(in_ifname
, ifp_in
->name
, sizeof(in_ifname
));
5826 strlcpy(in_ifname
, "<iif?>", sizeof(in_ifname
));
5830 /* Find the group, create it if it doesn't exist */
5831 json_object_object_get_ex(json
, grp_str
, &json_group
);
5834 json_group
= json_object_new_object();
5835 json_object_object_add(json
, grp_str
,
5839 /* Find the source nested under the group, create it if
5840 * it doesn't exist */
5841 json_object_object_get_ex(json_group
, src_str
,
5845 json_source
= json_object_new_object();
5846 json_object_object_add(json_group
, src_str
,
5850 /* Find the inbound interface nested under the source,
5851 * create it if it doesn't exist */
5852 json_object_int_add(json_source
, "installed",
5854 json_object_int_add(json_source
, "refCount",
5855 c_oil
->oil_ref_count
);
5856 json_object_int_add(json_source
, "oilSize",
5858 json_object_int_add(json_source
, "OilInheritedRescan",
5859 c_oil
->oil_inherited_rescan
);
5860 json_object_string_add(json_source
, "iif", in_ifname
);
5864 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
5866 struct interface
*ifp_out
;
5867 char mroute_uptime
[10];
5870 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
5874 /* do not display muted OIFs */
5875 if (c_oil
->oif_flags
[oif_vif_index
]
5876 & PIM_OIF_FLAG_MUTE
)
5879 if (c_oil
->oil
.mfcc_parent
== oif_vif_index
&&
5880 !pim_mroute_allow_iif_in_oil(c_oil
,
5884 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
5886 mroute_uptime
, sizeof(mroute_uptime
),
5887 now
- c_oil
->mroute_creation
);
5891 strlcpy(out_ifname
, ifp_out
->name
, sizeof(out_ifname
));
5893 strlcpy(out_ifname
, "<oif?>", sizeof(out_ifname
));
5896 json_ifp_out
= json_object_new_object();
5897 json_object_string_add(json_ifp_out
, "source",
5899 json_object_string_add(json_ifp_out
, "group",
5902 if (c_oil
->oif_flags
[oif_vif_index
]
5903 & PIM_OIF_FLAG_PROTO_PIM
)
5904 json_object_boolean_true_add(
5905 json_ifp_out
, "protocolPim");
5907 if (c_oil
->oif_flags
[oif_vif_index
]
5908 & PIM_OIF_FLAG_PROTO_IGMP
)
5909 json_object_boolean_true_add(
5910 json_ifp_out
, "protocolIgmp");
5912 if (c_oil
->oif_flags
[oif_vif_index
]
5913 & PIM_OIF_FLAG_PROTO_VXLAN
)
5914 json_object_boolean_true_add(
5915 json_ifp_out
, "protocolVxlan");
5917 if (c_oil
->oif_flags
[oif_vif_index
]
5918 & PIM_OIF_FLAG_PROTO_STAR
)
5919 json_object_boolean_true_add(
5921 "protocolInherited");
5923 json_object_string_add(json_ifp_out
,
5926 json_object_int_add(json_ifp_out
, "iVifI",
5927 c_oil
->oil
.mfcc_parent
);
5928 json_object_string_add(json_ifp_out
,
5929 "outboundInterface",
5931 json_object_int_add(json_ifp_out
, "oVifI",
5933 json_object_int_add(json_ifp_out
, "ttl", ttl
);
5934 json_object_string_add(json_ifp_out
, "upTime",
5937 json_oil
= json_object_new_object();
5938 json_object_object_add(json_source
,
5941 json_object_object_add(json_oil
, out_ifname
,
5944 if (c_oil
->oif_flags
[oif_vif_index
]
5945 & PIM_OIF_FLAG_PROTO_PIM
) {
5946 strlcpy(proto
, "PIM", sizeof(proto
));
5949 if (c_oil
->oif_flags
[oif_vif_index
]
5950 & PIM_OIF_FLAG_PROTO_IGMP
) {
5951 strlcpy(proto
, "IGMP", sizeof(proto
));
5954 if (c_oil
->oif_flags
[oif_vif_index
]
5955 & PIM_OIF_FLAG_PROTO_VXLAN
) {
5956 strlcpy(proto
, "VxLAN", sizeof(proto
));
5959 if (c_oil
->oif_flags
[oif_vif_index
]
5960 & PIM_OIF_FLAG_PROTO_STAR
) {
5961 strlcpy(proto
, "STAR", sizeof(proto
));
5965 "%-15s %-15s %-6s %-16s %-16s %-3d %8s\n",
5966 src_str
, grp_str
, proto
, in_ifname
,
5967 out_ifname
, ttl
, mroute_uptime
);
5972 in_ifname
[0] = '\0';
5978 if (!uj
&& !found_oif
) {
5979 vty_out(vty
, "%-15s %-15s %-6s %-16s %-16s %-3d %8s\n",
5980 src_str
, grp_str
, "none", in_ifname
, "none", 0,
5985 /* Print list of static routes */
5986 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
5989 if (!s_route
->c_oil
.installed
)
5992 pim_inet4_dump("<group?>", s_route
->group
, grp_str
,
5994 pim_inet4_dump("<source?>", s_route
->source
, src_str
,
5996 ifp_in
= pim_if_find_by_vif_index(pim
, s_route
->iif
);
6000 strlcpy(in_ifname
, ifp_in
->name
, sizeof(in_ifname
));
6002 strlcpy(in_ifname
, "<iif?>", sizeof(in_ifname
));
6006 /* Find the group, create it if it doesn't exist */
6007 json_object_object_get_ex(json
, grp_str
, &json_group
);
6010 json_group
= json_object_new_object();
6011 json_object_object_add(json
, grp_str
,
6015 /* Find the source nested under the group, create it if
6016 * it doesn't exist */
6017 json_object_object_get_ex(json_group
, src_str
,
6021 json_source
= json_object_new_object();
6022 json_object_object_add(json_group
, src_str
,
6026 json_object_string_add(json_source
, "iif", in_ifname
);
6029 strlcpy(proto
, "STATIC", sizeof(proto
));
6032 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
6034 struct interface
*ifp_out
;
6035 char oif_uptime
[10];
6038 ttl
= s_route
->oif_ttls
[oif_vif_index
];
6042 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
6044 oif_uptime
, sizeof(oif_uptime
),
6047 .oif_creation
[oif_vif_index
]);
6051 strlcpy(out_ifname
, ifp_out
->name
, sizeof(out_ifname
));
6053 strlcpy(out_ifname
, "<oif?>", sizeof(out_ifname
));
6056 json_ifp_out
= json_object_new_object();
6057 json_object_string_add(json_ifp_out
, "source",
6059 json_object_string_add(json_ifp_out
, "group",
6061 json_object_boolean_true_add(json_ifp_out
,
6063 json_object_string_add(json_ifp_out
,
6066 json_object_int_add(
6067 json_ifp_out
, "iVifI",
6068 s_route
->c_oil
.oil
.mfcc_parent
);
6069 json_object_string_add(json_ifp_out
,
6070 "outboundInterface",
6072 json_object_int_add(json_ifp_out
, "oVifI",
6074 json_object_int_add(json_ifp_out
, "ttl", ttl
);
6075 json_object_string_add(json_ifp_out
, "upTime",
6078 json_oil
= json_object_new_object();
6079 json_object_object_add(json_source
,
6082 json_object_object_add(json_oil
, out_ifname
,
6086 "%-15s %-15s %-6s %-16s %-16s %-3d %8s %s\n",
6087 src_str
, grp_str
, proto
, in_ifname
,
6088 out_ifname
, ttl
, oif_uptime
,
6090 if (first
&& !fill
) {
6093 in_ifname
[0] = '\0';
6099 if (!uj
&& !found_oif
) {
6101 "%-15s %-15s %-6s %-16s %-16s %-3d %8s %s\n",
6102 src_str
, grp_str
, proto
, in_ifname
, "none", 0,
6103 "--:--:--", pim
->vrf
->name
);
6108 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
6109 json
, JSON_C_TO_STRING_PRETTY
));
6110 json_object_free(json
);
6114 DEFPY (show_ip_mroute
,
6116 "show ip mroute [vrf NAME] [A.B.C.D$s_or_g [A.B.C.D$g]] [fill$fill] [json$json]",
6121 "The Source or Group\n"
6123 "Fill in Assumed data\n"
6126 struct prefix_sg sg
= {0};
6127 struct pim_instance
*pim
;
6130 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
6133 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
6136 pim
= pim_get_pim_instance(v
->vrf_id
);
6139 vty_out(vty
, "%% Unable to find pim instance\n");
6143 if (s_or_g
.s_addr
!= 0) {
6144 if (g
.s_addr
!= 0) {
6150 show_mroute(pim
, vty
, &sg
, !!fill
, !!json
);
6154 DEFUN (show_ip_mroute_vrf_all
,
6155 show_ip_mroute_vrf_all_cmd
,
6156 "show ip mroute vrf all [fill] [json]",
6161 "Fill in Assumed data\n"
6164 struct prefix_sg sg
= {0};
6165 bool uj
= use_json(argc
, argv
);
6171 if (argv_find(argv
, argc
, "fill", &idx
))
6176 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
6180 vty_out(vty
, " \"%s\": ", vrf
->name
);
6183 vty_out(vty
, "VRF: %s\n", vrf
->name
);
6184 show_mroute(vrf
->info
, vty
, &sg
, fill
, uj
);
6187 vty_out(vty
, "}\n");
6192 DEFUN (clear_ip_mroute_count
,
6193 clear_ip_mroute_count_cmd
,
6194 "clear ip mroute [vrf NAME] count",
6199 "Route and packet count data\n")
6202 struct listnode
*node
;
6203 struct channel_oil
*c_oil
;
6204 struct static_route
*sr
;
6205 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6206 struct pim_instance
*pim
;
6212 frr_each(rb_pim_oil
, &pim
->channel_oil_head
, c_oil
) {
6213 if (!c_oil
->installed
)
6216 pim_mroute_update_counters(c_oil
);
6217 c_oil
->cc
.origpktcnt
= c_oil
->cc
.pktcnt
;
6218 c_oil
->cc
.origbytecnt
= c_oil
->cc
.bytecnt
;
6219 c_oil
->cc
.origwrong_if
= c_oil
->cc
.wrong_if
;
6222 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, sr
)) {
6223 if (!sr
->c_oil
.installed
)
6226 pim_mroute_update_counters(&sr
->c_oil
);
6228 sr
->c_oil
.cc
.origpktcnt
= sr
->c_oil
.cc
.pktcnt
;
6229 sr
->c_oil
.cc
.origbytecnt
= sr
->c_oil
.cc
.bytecnt
;
6230 sr
->c_oil
.cc
.origwrong_if
= sr
->c_oil
.cc
.wrong_if
;
6235 static void show_mroute_count(struct pim_instance
*pim
, struct vty
*vty
)
6237 struct listnode
*node
;
6238 struct channel_oil
*c_oil
;
6239 struct static_route
*sr
;
6244 "Source Group LastUsed Packets Bytes WrongIf \n");
6246 /* Print PIM and IGMP route counts */
6247 frr_each (rb_pim_oil
, &pim
->channel_oil_head
, c_oil
) {
6248 char group_str
[INET_ADDRSTRLEN
];
6249 char source_str
[INET_ADDRSTRLEN
];
6251 if (!c_oil
->installed
)
6254 pim_mroute_update_counters(c_oil
);
6256 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, group_str
,
6258 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, source_str
,
6259 sizeof(source_str
));
6261 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
6262 source_str
, group_str
, c_oil
->cc
.lastused
/ 100,
6263 c_oil
->cc
.pktcnt
- c_oil
->cc
.origpktcnt
,
6264 c_oil
->cc
.bytecnt
- c_oil
->cc
.origbytecnt
,
6265 c_oil
->cc
.wrong_if
- c_oil
->cc
.origwrong_if
);
6268 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, sr
)) {
6269 char group_str
[INET_ADDRSTRLEN
];
6270 char source_str
[INET_ADDRSTRLEN
];
6272 if (!sr
->c_oil
.installed
)
6275 pim_mroute_update_counters(&sr
->c_oil
);
6277 pim_inet4_dump("<group?>", sr
->c_oil
.oil
.mfcc_mcastgrp
,
6278 group_str
, sizeof(group_str
));
6279 pim_inet4_dump("<source?>", sr
->c_oil
.oil
.mfcc_origin
,
6280 source_str
, sizeof(source_str
));
6282 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
6283 source_str
, group_str
, sr
->c_oil
.cc
.lastused
,
6284 sr
->c_oil
.cc
.pktcnt
- sr
->c_oil
.cc
.origpktcnt
,
6285 sr
->c_oil
.cc
.bytecnt
- sr
->c_oil
.cc
.origbytecnt
,
6286 sr
->c_oil
.cc
.wrong_if
- sr
->c_oil
.cc
.origwrong_if
);
6290 DEFUN (show_ip_mroute_count
,
6291 show_ip_mroute_count_cmd
,
6292 "show ip mroute [vrf NAME] count",
6297 "Route and packet count data\n")
6300 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6305 show_mroute_count(vrf
->info
, vty
);
6309 DEFUN (show_ip_mroute_count_vrf_all
,
6310 show_ip_mroute_count_vrf_all_cmd
,
6311 "show ip mroute vrf all count",
6316 "Route and packet count data\n")
6318 bool uj
= use_json(argc
, argv
);
6324 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
6328 vty_out(vty
, " \"%s\": ", vrf
->name
);
6331 vty_out(vty
, "VRF: %s\n", vrf
->name
);
6332 show_mroute_count(vrf
->info
, vty
);
6335 vty_out(vty
, "}\n");
6340 static void show_mroute_summary(struct pim_instance
*pim
, struct vty
*vty
)
6342 struct listnode
*node
;
6343 struct channel_oil
*c_oil
;
6344 struct static_route
*s_route
;
6345 uint32_t starg_sw_mroute_cnt
= 0;
6346 uint32_t sg_sw_mroute_cnt
= 0;
6347 uint32_t starg_hw_mroute_cnt
= 0;
6348 uint32_t sg_hw_mroute_cnt
= 0;
6350 vty_out(vty
, "Mroute Type Installed/Total\n");
6352 frr_each (rb_pim_oil
, &pim
->channel_oil_head
, c_oil
) {
6353 if (!c_oil
->installed
) {
6354 if (c_oil
->oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
6355 starg_sw_mroute_cnt
++;
6359 if (c_oil
->oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
6360 starg_hw_mroute_cnt
++;
6366 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
6367 if (!s_route
->c_oil
.installed
) {
6368 if (s_route
->c_oil
.oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
6369 starg_sw_mroute_cnt
++;
6373 if (s_route
->c_oil
.oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
6374 starg_hw_mroute_cnt
++;
6380 vty_out(vty
, "%-20s %d/%d\n", "(*, G)", starg_hw_mroute_cnt
,
6381 starg_sw_mroute_cnt
+ starg_hw_mroute_cnt
);
6382 vty_out(vty
, "%-20s %d/%d\n", "(S, G)", sg_hw_mroute_cnt
,
6383 sg_sw_mroute_cnt
+ sg_hw_mroute_cnt
);
6384 vty_out(vty
, "------\n");
6385 vty_out(vty
, "%-20s %d/%d\n", "Total",
6386 (starg_hw_mroute_cnt
+ sg_hw_mroute_cnt
),
6387 (starg_sw_mroute_cnt
+
6388 starg_hw_mroute_cnt
+
6393 DEFUN (show_ip_mroute_summary
,
6394 show_ip_mroute_summary_cmd
,
6395 "show ip mroute [vrf NAME] summary",
6400 "Summary of all mroutes\n")
6403 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6408 show_mroute_summary(vrf
->info
, vty
);
6412 DEFUN (show_ip_mroute_summary_vrf_all
,
6413 show_ip_mroute_summary_vrf_all_cmd
,
6414 "show ip mroute vrf all summary",
6419 "Summary of all mroutes\n")
6423 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
6424 vty_out(vty
, "VRF: %s\n", vrf
->name
);
6425 show_mroute_summary(vrf
->info
, vty
);
6433 "show ip rib [vrf NAME] A.B.C.D",
6438 "Unicast address\n")
6441 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6442 struct in_addr addr
;
6443 const char *addr_str
;
6444 struct pim_nexthop nexthop
;
6445 char nexthop_addr_str
[PREFIX_STRLEN
];
6451 memset(&nexthop
, 0, sizeof(nexthop
));
6452 argv_find(argv
, argc
, "A.B.C.D", &idx
);
6453 addr_str
= argv
[idx
]->arg
;
6454 result
= inet_pton(AF_INET
, addr_str
, &addr
);
6456 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
6457 errno
, safe_strerror(errno
));
6461 if (!pim_nexthop_lookup(vrf
->info
, &nexthop
, addr
, 0)) {
6463 "Failure querying RIB nexthop for unicast address %s\n",
6469 "Address NextHop Interface Metric Preference\n");
6471 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
6472 nexthop_addr_str
, sizeof(nexthop_addr_str
));
6474 vty_out(vty
, "%-15s %-15s %-9s %6d %10d\n", addr_str
, nexthop_addr_str
,
6475 nexthop
.interface
? nexthop
.interface
->name
: "<ifname?>",
6476 nexthop
.mrib_route_metric
, nexthop
.mrib_metric_preference
);
6481 static void show_ssmpingd(struct pim_instance
*pim
, struct vty
*vty
)
6483 struct listnode
*node
;
6484 struct ssmpingd_sock
*ss
;
6488 "Source Socket Address Port Uptime Requests\n");
6490 if (!pim
->ssmpingd_list
)
6493 now
= pim_time_monotonic_sec();
6495 for (ALL_LIST_ELEMENTS_RO(pim
->ssmpingd_list
, node
, ss
)) {
6496 char source_str
[INET_ADDRSTRLEN
];
6498 struct sockaddr_in bind_addr
;
6499 socklen_t len
= sizeof(bind_addr
);
6500 char bind_addr_str
[INET_ADDRSTRLEN
];
6502 pim_inet4_dump("<src?>", ss
->source_addr
, source_str
,
6503 sizeof(source_str
));
6505 if (pim_socket_getsockname(
6506 ss
->sock_fd
, (struct sockaddr
*)&bind_addr
, &len
)) {
6508 "%% Failure reading socket name for ssmpingd source %s on fd=%d\n",
6509 source_str
, ss
->sock_fd
);
6512 pim_inet4_dump("<addr?>", bind_addr
.sin_addr
, bind_addr_str
,
6513 sizeof(bind_addr_str
));
6514 pim_time_uptime(ss_uptime
, sizeof(ss_uptime
),
6515 now
- ss
->creation
);
6517 vty_out(vty
, "%-15s %6d %-15s %5d %8s %8lld\n", source_str
,
6518 ss
->sock_fd
, bind_addr_str
, ntohs(bind_addr
.sin_port
),
6519 ss_uptime
, (long long)ss
->requests
);
6523 DEFUN (show_ip_ssmpingd
,
6524 show_ip_ssmpingd_cmd
,
6525 "show ip ssmpingd [vrf NAME]",
6532 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6537 show_ssmpingd(vrf
->info
, vty
);
6541 static int pim_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
6542 const char *rp
, const char *group
,
6547 result
= pim_rp_new_config(pim
, rp
, group
, plist
);
6549 if (result
== PIM_GROUP_BAD_ADDR_MASK_COMBO
) {
6550 vty_out(vty
, "%% Inconsistent address and mask: %s\n",
6552 return CMD_WARNING_CONFIG_FAILED
;
6555 if (result
== PIM_GROUP_BAD_ADDRESS
) {
6556 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
6557 return CMD_WARNING_CONFIG_FAILED
;
6560 if (result
== PIM_RP_BAD_ADDRESS
) {
6561 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
6562 return CMD_WARNING_CONFIG_FAILED
;
6565 if (result
== PIM_RP_NO_PATH
) {
6566 vty_out(vty
, "%% No Path to RP address specified: %s\n", rp
);
6570 if (result
== PIM_GROUP_OVERLAP
) {
6572 "%% Group range specified cannot exact match another\n");
6573 return CMD_WARNING_CONFIG_FAILED
;
6576 if (result
== PIM_GROUP_PFXLIST_OVERLAP
) {
6578 "%% This group is already covered by a RP prefix-list\n");
6579 return CMD_WARNING_CONFIG_FAILED
;
6582 if (result
== PIM_RP_PFXLIST_IN_USE
) {
6584 "%% The same prefix-list cannot be applied to multiple RPs\n");
6585 return CMD_WARNING_CONFIG_FAILED
;
6591 static int pim_cmd_spt_switchover(struct pim_instance
*pim
,
6592 enum pim_spt_switchover spt
,
6595 pim
->spt
.switchover
= spt
;
6597 switch (pim
->spt
.switchover
) {
6598 case PIM_SPT_IMMEDIATE
:
6599 XFREE(MTYPE_PIM_SPT_PLIST_NAME
, pim
->spt
.plist
);
6601 pim_upstream_add_lhr_star_pimreg(pim
);
6603 case PIM_SPT_INFINITY
:
6604 pim_upstream_remove_lhr_star_pimreg(pim
, plist
);
6606 XFREE(MTYPE_PIM_SPT_PLIST_NAME
, pim
->spt
.plist
);
6610 XSTRDUP(MTYPE_PIM_SPT_PLIST_NAME
, plist
);
6617 DEFUN (ip_pim_spt_switchover_infinity
,
6618 ip_pim_spt_switchover_infinity_cmd
,
6619 "ip pim spt-switchover infinity-and-beyond",
6623 "Never switch to SPT Tree\n")
6625 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6626 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, NULL
);
6629 DEFUN (ip_pim_spt_switchover_infinity_plist
,
6630 ip_pim_spt_switchover_infinity_plist_cmd
,
6631 "ip pim spt-switchover infinity-and-beyond prefix-list WORD",
6635 "Never switch to SPT Tree\n"
6636 "Prefix-List to control which groups to switch\n"
6637 "Prefix-List name\n")
6639 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6640 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, argv
[5]->arg
);
6643 DEFUN (no_ip_pim_spt_switchover_infinity
,
6644 no_ip_pim_spt_switchover_infinity_cmd
,
6645 "no ip pim spt-switchover infinity-and-beyond",
6650 "Never switch to SPT Tree\n")
6652 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6653 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
6656 DEFUN (no_ip_pim_spt_switchover_infinity_plist
,
6657 no_ip_pim_spt_switchover_infinity_plist_cmd
,
6658 "no ip pim spt-switchover infinity-and-beyond prefix-list WORD",
6663 "Never switch to SPT Tree\n"
6664 "Prefix-List to control which groups to switch\n"
6665 "Prefix-List name\n")
6667 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6668 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
6671 DEFUN (ip_pim_joinprune_time
,
6672 ip_pim_joinprune_time_cmd
,
6673 "ip pim join-prune-interval (60-600)",
6675 "pim multicast routing\n"
6676 "Join Prune Send Interval\n"
6679 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6680 router
->t_periodic
= atoi(argv
[3]->arg
);
6684 DEFUN (no_ip_pim_joinprune_time
,
6685 no_ip_pim_joinprune_time_cmd
,
6686 "no ip pim join-prune-interval (60-600)",
6689 "pim multicast routing\n"
6690 "Join Prune Send Interval\n"
6693 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6694 router
->t_periodic
= PIM_DEFAULT_T_PERIODIC
;
6698 DEFUN (ip_pim_register_suppress
,
6699 ip_pim_register_suppress_cmd
,
6700 "ip pim register-suppress-time (5-60000)",
6702 "pim multicast routing\n"
6703 "Register Suppress Timer\n"
6706 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6707 router
->register_suppress_time
= atoi(argv
[3]->arg
);
6711 DEFUN (no_ip_pim_register_suppress
,
6712 no_ip_pim_register_suppress_cmd
,
6713 "no ip pim register-suppress-time (5-60000)",
6716 "pim multicast routing\n"
6717 "Register Suppress Timer\n"
6720 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6721 router
->register_suppress_time
= PIM_REGISTER_SUPPRESSION_TIME_DEFAULT
;
6725 DEFUN (ip_pim_rp_keep_alive
,
6726 ip_pim_rp_keep_alive_cmd
,
6727 "ip pim rp keep-alive-timer (31-60000)",
6729 "pim multicast routing\n"
6731 "Keep alive Timer\n"
6734 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6735 pim
->rp_keep_alive_time
= atoi(argv
[4]->arg
);
6739 DEFUN (no_ip_pim_rp_keep_alive
,
6740 no_ip_pim_rp_keep_alive_cmd
,
6741 "no ip pim rp keep-alive-timer (31-60000)",
6744 "pim multicast routing\n"
6746 "Keep alive Timer\n"
6749 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6750 pim
->rp_keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
6754 DEFUN (ip_pim_keep_alive
,
6755 ip_pim_keep_alive_cmd
,
6756 "ip pim keep-alive-timer (31-60000)",
6758 "pim multicast routing\n"
6759 "Keep alive Timer\n"
6762 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6763 pim
->keep_alive_time
= atoi(argv
[3]->arg
);
6767 DEFUN (no_ip_pim_keep_alive
,
6768 no_ip_pim_keep_alive_cmd
,
6769 "no ip pim keep-alive-timer (31-60000)",
6772 "pim multicast routing\n"
6773 "Keep alive Timer\n"
6776 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6777 pim
->keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
6781 DEFUN (ip_pim_packets
,
6783 "ip pim packets (1-100)",
6785 "pim multicast routing\n"
6786 "packets to process at one time per fd\n"
6787 "Number of packets\n")
6789 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6790 router
->packet_process
= atoi(argv
[3]->arg
);
6794 DEFUN (no_ip_pim_packets
,
6795 no_ip_pim_packets_cmd
,
6796 "no ip pim packets (1-100)",
6799 "pim multicast routing\n"
6800 "packets to process at one time per fd\n"
6801 "Number of packets\n")
6803 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6804 router
->packet_process
= PIM_DEFAULT_PACKET_PROCESS
;
6808 DEFUN (ip_pim_v6_secondary
,
6809 ip_pim_v6_secondary_cmd
,
6810 "ip pim send-v6-secondary",
6812 "pim multicast routing\n"
6813 "Send v6 secondary addresses\n")
6815 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6816 pim
->send_v6_secondary
= 1;
6821 DEFUN (no_ip_pim_v6_secondary
,
6822 no_ip_pim_v6_secondary_cmd
,
6823 "no ip pim send-v6-secondary",
6826 "pim multicast routing\n"
6827 "Send v6 secondary addresses\n")
6829 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6830 pim
->send_v6_secondary
= 0;
6837 "ip pim rp A.B.C.D [A.B.C.D/M]",
6839 "pim multicast routing\n"
6841 "ip address of RP\n"
6842 "Group Address range to cover\n")
6844 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6847 if (argc
== (idx_ipv4
+ 1))
6848 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
6851 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
6852 argv
[idx_ipv4
+ 1]->arg
, NULL
);
6855 DEFUN (ip_pim_rp_prefix_list
,
6856 ip_pim_rp_prefix_list_cmd
,
6857 "ip pim rp A.B.C.D prefix-list WORD",
6859 "pim multicast routing\n"
6861 "ip address of RP\n"
6862 "group prefix-list filter\n"
6863 "Name of a prefix-list\n")
6865 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6866 return pim_rp_cmd_worker(pim
, vty
, argv
[3]->arg
, NULL
, argv
[5]->arg
);
6869 static int pim_no_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
6870 const char *rp
, const char *group
,
6873 int result
= pim_rp_del_config(pim
, rp
, group
, plist
);
6875 if (result
== PIM_GROUP_BAD_ADDRESS
) {
6876 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
6877 return CMD_WARNING_CONFIG_FAILED
;
6880 if (result
== PIM_RP_BAD_ADDRESS
) {
6881 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
6882 return CMD_WARNING_CONFIG_FAILED
;
6885 if (result
== PIM_RP_NOT_FOUND
) {
6886 vty_out(vty
, "%% Unable to find specified RP\n");
6887 return CMD_WARNING_CONFIG_FAILED
;
6893 DEFUN (no_ip_pim_rp
,
6895 "no ip pim rp A.B.C.D [A.B.C.D/M]",
6898 "pim multicast routing\n"
6900 "ip address of RP\n"
6901 "Group Address range to cover\n")
6903 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6904 int idx_ipv4
= 4, idx_group
= 0;
6906 if (argv_find(argv
, argc
, "A.B.C.D/M", &idx_group
))
6907 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
6908 argv
[idx_group
]->arg
, NULL
);
6910 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
6914 DEFUN (no_ip_pim_rp_prefix_list
,
6915 no_ip_pim_rp_prefix_list_cmd
,
6916 "no ip pim rp A.B.C.D prefix-list WORD",
6919 "pim multicast routing\n"
6921 "ip address of RP\n"
6922 "group prefix-list filter\n"
6923 "Name of a prefix-list\n")
6925 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6926 return pim_no_rp_cmd_worker(pim
, vty
, argv
[4]->arg
, NULL
, argv
[6]->arg
);
6929 static int pim_ssm_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
6932 int result
= pim_ssm_range_set(pim
, pim
->vrf_id
, plist
);
6933 int ret
= CMD_WARNING_CONFIG_FAILED
;
6935 if (result
== PIM_SSM_ERR_NONE
)
6939 case PIM_SSM_ERR_NO_VRF
:
6940 vty_out(vty
, "%% VRF doesn't exist\n");
6942 case PIM_SSM_ERR_DUP
:
6943 vty_out(vty
, "%% duplicate config\n");
6947 vty_out(vty
, "%% ssm range config failed\n");
6953 DEFUN (ip_pim_ssm_prefix_list
,
6954 ip_pim_ssm_prefix_list_cmd
,
6955 "ip pim ssm prefix-list WORD",
6957 "pim multicast routing\n"
6958 "Source Specific Multicast\n"
6959 "group range prefix-list filter\n"
6960 "Name of a prefix-list\n")
6962 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6963 return pim_ssm_cmd_worker(pim
, vty
, argv
[4]->arg
);
6966 DEFUN (no_ip_pim_ssm_prefix_list
,
6967 no_ip_pim_ssm_prefix_list_cmd
,
6968 "no ip pim ssm prefix-list",
6971 "pim multicast routing\n"
6972 "Source Specific Multicast\n"
6973 "group range prefix-list filter\n")
6975 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6976 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
6979 DEFUN (no_ip_pim_ssm_prefix_list_name
,
6980 no_ip_pim_ssm_prefix_list_name_cmd
,
6981 "no ip pim ssm prefix-list WORD",
6984 "pim multicast routing\n"
6985 "Source Specific Multicast\n"
6986 "group range prefix-list filter\n"
6987 "Name of a prefix-list\n")
6989 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6990 struct pim_ssm
*ssm
= pim
->ssm_info
;
6992 if (ssm
->plist_name
&& !strcmp(ssm
->plist_name
, argv
[5]->arg
))
6993 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
6995 vty_out(vty
, "%% pim ssm prefix-list %s doesn't exist\n", argv
[5]->arg
);
6997 return CMD_WARNING_CONFIG_FAILED
;
7000 static void ip_pim_ssm_show_group_range(struct pim_instance
*pim
,
7001 struct vty
*vty
, bool uj
)
7003 struct pim_ssm
*ssm
= pim
->ssm_info
;
7004 const char *range_str
=
7005 ssm
->plist_name
? ssm
->plist_name
: PIM_SSM_STANDARD_RANGE
;
7009 json
= json_object_new_object();
7010 json_object_string_add(json
, "ssmGroups", range_str
);
7011 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
7012 json
, JSON_C_TO_STRING_PRETTY
));
7013 json_object_free(json
);
7015 vty_out(vty
, "SSM group range : %s\n", range_str
);
7018 DEFUN (show_ip_pim_ssm_range
,
7019 show_ip_pim_ssm_range_cmd
,
7020 "show ip pim [vrf NAME] group-type [json]",
7029 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
7030 bool uj
= use_json(argc
, argv
);
7035 ip_pim_ssm_show_group_range(vrf
->info
, vty
, uj
);
7040 static void ip_pim_ssm_show_group_type(struct pim_instance
*pim
,
7041 struct vty
*vty
, bool uj
,
7044 struct in_addr group_addr
;
7045 const char *type_str
;
7048 result
= inet_pton(AF_INET
, group
, &group_addr
);
7050 type_str
= "invalid";
7052 if (pim_is_group_224_4(group_addr
))
7054 pim_is_grp_ssm(pim
, group_addr
) ? "SSM" : "ASM";
7056 type_str
= "not-multicast";
7061 json
= json_object_new_object();
7062 json_object_string_add(json
, "groupType", type_str
);
7063 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
7064 json
, JSON_C_TO_STRING_PRETTY
));
7065 json_object_free(json
);
7067 vty_out(vty
, "Group type : %s\n", type_str
);
7070 DEFUN (show_ip_pim_group_type
,
7071 show_ip_pim_group_type_cmd
,
7072 "show ip pim [vrf NAME] group-type A.B.C.D [json]",
7077 "multicast group type\n"
7082 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
7083 bool uj
= use_json(argc
, argv
);
7088 argv_find(argv
, argc
, "A.B.C.D", &idx
);
7089 ip_pim_ssm_show_group_type(vrf
->info
, vty
, uj
, argv
[idx
]->arg
);
7094 DEFUN (show_ip_pim_bsr
,
7095 show_ip_pim_bsr_cmd
,
7096 "show ip pim bsr [json]",
7100 "boot-strap router information\n"
7104 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
7105 bool uj
= use_json(argc
, argv
);
7110 pim_show_bsr(vrf
->info
, vty
, uj
);
7117 "ip ssmpingd [A.B.C.D]",
7122 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7125 struct in_addr source_addr
;
7126 const char *source_str
= (argc
== 3) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
7128 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
7130 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
7131 source_str
, errno
, safe_strerror(errno
));
7132 return CMD_WARNING_CONFIG_FAILED
;
7135 result
= pim_ssmpingd_start(pim
, source_addr
);
7137 vty_out(vty
, "%% Failure starting ssmpingd for source %s: %d\n",
7138 source_str
, result
);
7139 return CMD_WARNING_CONFIG_FAILED
;
7145 DEFUN (no_ip_ssmpingd
,
7147 "no ip ssmpingd [A.B.C.D]",
7153 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7156 struct in_addr source_addr
;
7157 const char *source_str
= (argc
== 4) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
7159 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
7161 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
7162 source_str
, errno
, safe_strerror(errno
));
7163 return CMD_WARNING_CONFIG_FAILED
;
7166 result
= pim_ssmpingd_stop(pim
, source_addr
);
7168 vty_out(vty
, "%% Failure stopping ssmpingd for source %s: %d\n",
7169 source_str
, result
);
7170 return CMD_WARNING_CONFIG_FAILED
;
7180 "pim multicast routing\n"
7181 "Enable PIM ECMP \n")
7183 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7184 pim
->ecmp_enable
= true;
7189 DEFUN (no_ip_pim_ecmp
,
7194 "pim multicast routing\n"
7195 "Disable PIM ECMP \n")
7197 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7198 pim
->ecmp_enable
= false;
7203 DEFUN (ip_pim_ecmp_rebalance
,
7204 ip_pim_ecmp_rebalance_cmd
,
7205 "ip pim ecmp rebalance",
7207 "pim multicast routing\n"
7208 "Enable PIM ECMP \n"
7209 "Enable PIM ECMP Rebalance\n")
7211 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7212 pim
->ecmp_enable
= true;
7213 pim
->ecmp_rebalance_enable
= true;
7218 DEFUN (no_ip_pim_ecmp_rebalance
,
7219 no_ip_pim_ecmp_rebalance_cmd
,
7220 "no ip pim ecmp rebalance",
7223 "pim multicast routing\n"
7224 "Disable PIM ECMP \n"
7225 "Disable PIM ECMP Rebalance\n")
7227 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7228 pim
->ecmp_rebalance_enable
= false;
7233 static int pim_cmd_igmp_start(struct vty
*vty
, struct interface
*ifp
)
7235 struct pim_interface
*pim_ifp
;
7236 uint8_t need_startup
= 0;
7238 pim_ifp
= ifp
->info
;
7241 (void)pim_if_new(ifp
, true, false, false, false);
7244 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
7245 PIM_IF_DO_IGMP(pim_ifp
->options
);
7250 /* 'ip igmp' executed multiple times, with need_startup
7251 avoid multiple if add all and membership refresh */
7253 pim_if_addr_add_all(ifp
);
7254 pim_if_membership_refresh(ifp
);
7260 DEFUN (interface_ip_igmp
,
7261 interface_ip_igmp_cmd
,
7266 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7268 return pim_cmd_igmp_start(vty
, ifp
);
7271 DEFUN (interface_no_ip_igmp
,
7272 interface_no_ip_igmp_cmd
,
7278 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7279 struct pim_interface
*pim_ifp
= ifp
->info
;
7284 PIM_IF_DONT_IGMP(pim_ifp
->options
);
7286 pim_if_membership_clear(ifp
);
7288 pim_if_addr_del_all_igmp(ifp
);
7290 if (!PIM_IF_TEST_PIM(pim_ifp
->options
)) {
7297 DEFUN (interface_ip_igmp_join
,
7298 interface_ip_igmp_join_cmd
,
7299 "ip igmp join A.B.C.D [A.B.C.D]",
7302 "IGMP join multicast group\n"
7303 "Multicast group address\n"
7306 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7309 const char *group_str
;
7310 const char *source_str
;
7311 struct in_addr group_addr
;
7312 struct in_addr source_addr
;
7316 group_str
= argv
[idx_ipv4
]->arg
;
7317 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
7319 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
7320 errno
, safe_strerror(errno
));
7321 return CMD_WARNING_CONFIG_FAILED
;
7324 /* Source address */
7325 if (argc
== (idx_ipv4_2
+ 1)) {
7326 source_str
= argv
[idx_ipv4_2
]->arg
;
7327 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
7329 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
7330 source_str
, errno
, safe_strerror(errno
));
7331 return CMD_WARNING_CONFIG_FAILED
;
7333 /* Reject 0.0.0.0. Reserved for any source. */
7334 if (source_addr
.s_addr
== INADDR_ANY
) {
7335 vty_out(vty
, "Bad source address %s\n", source_str
);
7336 return CMD_WARNING_CONFIG_FAILED
;
7339 source_addr
.s_addr
= INADDR_ANY
;
7342 CMD_FERR_RETURN(pim_if_igmp_join_add(ifp
, group_addr
, source_addr
),
7343 "Failure joining IGMP group: $ERR");
7348 DEFUN (interface_no_ip_igmp_join
,
7349 interface_no_ip_igmp_join_cmd
,
7350 "no ip igmp join A.B.C.D [A.B.C.D]",
7354 "IGMP join multicast group\n"
7355 "Multicast group address\n"
7358 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7361 const char *group_str
;
7362 const char *source_str
;
7363 struct in_addr group_addr
;
7364 struct in_addr source_addr
;
7368 group_str
= argv
[idx_ipv4
]->arg
;
7369 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
7371 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
7372 errno
, safe_strerror(errno
));
7373 return CMD_WARNING_CONFIG_FAILED
;
7376 /* Source address */
7377 if (argc
== (idx_ipv4_2
+ 1)) {
7378 source_str
= argv
[idx_ipv4_2
]->arg
;
7379 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
7381 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
7382 source_str
, errno
, safe_strerror(errno
));
7383 return CMD_WARNING_CONFIG_FAILED
;
7385 /* Reject 0.0.0.0. Reserved for any source. */
7386 if (source_addr
.s_addr
== INADDR_ANY
) {
7387 vty_out(vty
, "Bad source address %s\n", source_str
);
7388 return CMD_WARNING_CONFIG_FAILED
;
7392 source_addr
.s_addr
= INADDR_ANY
;
7395 result
= pim_if_igmp_join_del(ifp
, group_addr
, source_addr
);
7398 "%% Failure leaving IGMP group %s source %s on interface %s: %d\n",
7399 group_str
, source_str
, ifp
->name
, result
);
7400 return CMD_WARNING_CONFIG_FAILED
;
7407 CLI reconfiguration affects the interface level (struct pim_interface).
7408 This function propagates the reconfiguration to every active socket
7411 static void igmp_sock_query_interval_reconfig(struct igmp_sock
*igmp
)
7413 struct interface
*ifp
;
7414 struct pim_interface
*pim_ifp
;
7418 /* other querier present? */
7420 if (igmp
->t_other_querier_timer
)
7423 /* this is the querier */
7425 zassert(igmp
->interface
);
7426 zassert(igmp
->interface
->info
);
7428 ifp
= igmp
->interface
;
7429 pim_ifp
= ifp
->info
;
7431 if (PIM_DEBUG_IGMP_TRACE
) {
7432 char ifaddr_str
[INET_ADDRSTRLEN
];
7433 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
7434 sizeof(ifaddr_str
));
7435 zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
7436 __func__
, ifaddr_str
, ifp
->name
,
7437 pim_ifp
->igmp_default_query_interval
);
7441 igmp_startup_mode_on() will reset QQI:
7443 igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
7445 igmp_startup_mode_on(igmp
);
7448 static void igmp_sock_query_reschedule(struct igmp_sock
*igmp
)
7450 if (igmp
->mtrace_only
)
7453 if (igmp
->t_igmp_query_timer
) {
7454 /* other querier present */
7455 zassert(igmp
->t_igmp_query_timer
);
7456 zassert(!igmp
->t_other_querier_timer
);
7458 pim_igmp_general_query_off(igmp
);
7459 pim_igmp_general_query_on(igmp
);
7461 zassert(igmp
->t_igmp_query_timer
);
7462 zassert(!igmp
->t_other_querier_timer
);
7464 /* this is the querier */
7466 zassert(!igmp
->t_igmp_query_timer
);
7467 zassert(igmp
->t_other_querier_timer
);
7469 pim_igmp_other_querier_timer_off(igmp
);
7470 pim_igmp_other_querier_timer_on(igmp
);
7472 zassert(!igmp
->t_igmp_query_timer
);
7473 zassert(igmp
->t_other_querier_timer
);
7477 static void change_query_interval(struct pim_interface
*pim_ifp
,
7480 struct listnode
*sock_node
;
7481 struct igmp_sock
*igmp
;
7483 pim_ifp
->igmp_default_query_interval
= query_interval
;
7485 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
7486 igmp_sock_query_interval_reconfig(igmp
);
7487 igmp_sock_query_reschedule(igmp
);
7491 static void change_query_max_response_time(struct pim_interface
*pim_ifp
,
7492 int query_max_response_time_dsec
)
7494 struct listnode
*sock_node
;
7495 struct igmp_sock
*igmp
;
7497 pim_ifp
->igmp_query_max_response_time_dsec
=
7498 query_max_response_time_dsec
;
7501 Below we modify socket/group/source timers in order to quickly
7502 reflect the change. Otherwise, those timers would eventually catch
7506 /* scan all sockets */
7507 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
7508 struct listnode
*grp_node
;
7509 struct igmp_group
*grp
;
7511 /* reschedule socket general query */
7512 igmp_sock_query_reschedule(igmp
);
7514 /* scan socket groups */
7515 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grp_node
,
7517 struct listnode
*src_node
;
7518 struct igmp_source
*src
;
7520 /* reset group timers for groups in EXCLUDE mode */
7521 if (grp
->group_filtermode_isexcl
) {
7522 igmp_group_reset_gmi(grp
);
7525 /* scan group sources */
7526 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
,
7529 /* reset source timers for sources with running
7531 if (src
->t_source_timer
) {
7532 igmp_source_reset_gmi(igmp
, grp
, src
);
7539 #define IGMP_QUERY_INTERVAL_MIN (1)
7540 #define IGMP_QUERY_INTERVAL_MAX (1800)
7542 DEFUN (interface_ip_igmp_query_interval
,
7543 interface_ip_igmp_query_interval_cmd
,
7544 "ip igmp query-interval (1-1800)",
7547 IFACE_IGMP_QUERY_INTERVAL_STR
7548 "Query interval in seconds\n")
7550 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7551 struct pim_interface
*pim_ifp
= ifp
->info
;
7553 int query_interval_dsec
;
7557 ret
= pim_cmd_igmp_start(vty
, ifp
);
7558 if (ret
!= CMD_SUCCESS
)
7560 pim_ifp
= ifp
->info
;
7563 query_interval
= atoi(argv
[3]->arg
);
7564 query_interval_dsec
= 10 * query_interval
;
7567 It seems we don't need to check bounds since command.c does it
7568 already, but we verify them anyway for extra safety.
7570 if (query_interval
< IGMP_QUERY_INTERVAL_MIN
) {
7572 "General query interval %d lower than minimum %d\n",
7573 query_interval
, IGMP_QUERY_INTERVAL_MIN
);
7574 return CMD_WARNING_CONFIG_FAILED
;
7576 if (query_interval
> IGMP_QUERY_INTERVAL_MAX
) {
7578 "General query interval %d higher than maximum %d\n",
7579 query_interval
, IGMP_QUERY_INTERVAL_MAX
);
7580 return CMD_WARNING_CONFIG_FAILED
;
7583 if (query_interval_dsec
<= pim_ifp
->igmp_query_max_response_time_dsec
) {
7585 "Can't set general query interval %d dsec <= query max response time %d dsec.\n",
7586 query_interval_dsec
,
7587 pim_ifp
->igmp_query_max_response_time_dsec
);
7588 return CMD_WARNING_CONFIG_FAILED
;
7591 change_query_interval(pim_ifp
, query_interval
);
7596 DEFUN (interface_no_ip_igmp_query_interval
,
7597 interface_no_ip_igmp_query_interval_cmd
,
7598 "no ip igmp query-interval",
7602 IFACE_IGMP_QUERY_INTERVAL_STR
)
7604 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7605 struct pim_interface
*pim_ifp
= ifp
->info
;
7606 int default_query_interval_dsec
;
7611 default_query_interval_dsec
= IGMP_GENERAL_QUERY_INTERVAL
* 10;
7613 if (default_query_interval_dsec
7614 <= pim_ifp
->igmp_query_max_response_time_dsec
) {
7616 "Can't set default general query interval %d dsec <= query max response time %d dsec.\n",
7617 default_query_interval_dsec
,
7618 pim_ifp
->igmp_query_max_response_time_dsec
);
7619 return CMD_WARNING_CONFIG_FAILED
;
7622 change_query_interval(pim_ifp
, IGMP_GENERAL_QUERY_INTERVAL
);
7627 DEFUN (interface_ip_igmp_version
,
7628 interface_ip_igmp_version_cmd
,
7629 "ip igmp version (2-3)",
7633 "IGMP version number\n")
7635 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7636 struct pim_interface
*pim_ifp
= ifp
->info
;
7637 int igmp_version
, old_version
= 0;
7641 ret
= pim_cmd_igmp_start(vty
, ifp
);
7642 if (ret
!= CMD_SUCCESS
)
7644 pim_ifp
= ifp
->info
;
7647 igmp_version
= atoi(argv
[3]->arg
);
7648 old_version
= pim_ifp
->igmp_version
;
7649 pim_ifp
->igmp_version
= igmp_version
;
7651 // Check if IGMP is Enabled otherwise, enable on interface
7652 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
7653 PIM_IF_DO_IGMP(pim_ifp
->options
);
7654 pim_if_addr_add_all(ifp
);
7655 pim_if_membership_refresh(ifp
);
7656 old_version
= igmp_version
;
7657 // avoid refreshing membership again.
7659 /* Current and new version is different refresh existing
7660 membership. Going from 3 -> 2 or 2 -> 3. */
7661 if (old_version
!= igmp_version
)
7662 pim_if_membership_refresh(ifp
);
7667 DEFUN (interface_no_ip_igmp_version
,
7668 interface_no_ip_igmp_version_cmd
,
7669 "no ip igmp version (2-3)",
7674 "IGMP version number\n")
7676 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7677 struct pim_interface
*pim_ifp
= ifp
->info
;
7682 pim_ifp
->igmp_version
= IGMP_DEFAULT_VERSION
;
7687 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
7688 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
7690 DEFUN (interface_ip_igmp_query_max_response_time
,
7691 interface_ip_igmp_query_max_response_time_cmd
,
7692 "ip igmp query-max-response-time (10-250)",
7695 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
7696 "Query response value in deci-seconds\n")
7698 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7699 struct pim_interface
*pim_ifp
= ifp
->info
;
7700 int query_max_response_time
;
7704 ret
= pim_cmd_igmp_start(vty
, ifp
);
7705 if (ret
!= CMD_SUCCESS
)
7707 pim_ifp
= ifp
->info
;
7710 query_max_response_time
= atoi(argv
[3]->arg
);
7712 if (query_max_response_time
7713 >= pim_ifp
->igmp_default_query_interval
* 10) {
7715 "Can't set query max response time %d sec >= general query interval %d sec\n",
7716 query_max_response_time
,
7717 pim_ifp
->igmp_default_query_interval
);
7718 return CMD_WARNING_CONFIG_FAILED
;
7721 change_query_max_response_time(pim_ifp
, query_max_response_time
);
7726 DEFUN (interface_no_ip_igmp_query_max_response_time
,
7727 interface_no_ip_igmp_query_max_response_time_cmd
,
7728 "no ip igmp query-max-response-time (10-250)",
7732 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
7733 "Time for response in deci-seconds\n")
7735 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7736 struct pim_interface
*pim_ifp
= ifp
->info
;
7741 change_query_max_response_time(pim_ifp
,
7742 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
7747 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
7748 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
7750 DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec
,
7751 interface_ip_igmp_query_max_response_time_dsec_cmd
,
7752 "ip igmp query-max-response-time-dsec (10-250)",
7755 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
7756 "Query response value in deciseconds\n")
7758 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7759 struct pim_interface
*pim_ifp
= ifp
->info
;
7760 int query_max_response_time_dsec
;
7761 int default_query_interval_dsec
;
7765 ret
= pim_cmd_igmp_start(vty
, ifp
);
7766 if (ret
!= CMD_SUCCESS
)
7768 pim_ifp
= ifp
->info
;
7771 query_max_response_time_dsec
= atoi(argv
[4]->arg
);
7773 default_query_interval_dsec
= 10 * pim_ifp
->igmp_default_query_interval
;
7775 if (query_max_response_time_dsec
>= default_query_interval_dsec
) {
7777 "Can't set query max response time %d dsec >= general query interval %d dsec\n",
7778 query_max_response_time_dsec
,
7779 default_query_interval_dsec
);
7780 return CMD_WARNING_CONFIG_FAILED
;
7783 change_query_max_response_time(pim_ifp
, query_max_response_time_dsec
);
7788 DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec
,
7789 interface_no_ip_igmp_query_max_response_time_dsec_cmd
,
7790 "no ip igmp query-max-response-time-dsec",
7794 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
)
7796 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7797 struct pim_interface
*pim_ifp
= ifp
->info
;
7802 change_query_max_response_time(pim_ifp
,
7803 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
7808 #define IGMP_LAST_MEMBER_QUERY_COUNT_MIN (1)
7809 #define IGMP_LAST_MEMBER_QUERY_COUNT_MAX (7)
7811 DEFUN (interface_ip_igmp_last_member_query_count
,
7812 interface_ip_igmp_last_member_query_count_cmd
,
7813 "ip igmp last-member-query-count (1-7)",
7816 IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR
7817 "Last member query count\n")
7819 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7820 struct pim_interface
*pim_ifp
= ifp
->info
;
7821 int last_member_query_count
;
7825 ret
= pim_cmd_igmp_start(vty
, ifp
);
7826 if (ret
!= CMD_SUCCESS
)
7828 pim_ifp
= ifp
->info
;
7831 last_member_query_count
= atoi(argv
[3]->arg
);
7833 pim_ifp
->igmp_last_member_query_count
= last_member_query_count
;
7838 DEFUN (interface_no_ip_igmp_last_member_query_count
,
7839 interface_no_ip_igmp_last_member_query_count_cmd
,
7840 "no ip igmp last-member-query-count",
7844 IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR
)
7846 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7847 struct pim_interface
*pim_ifp
= ifp
->info
;
7852 pim_ifp
->igmp_last_member_query_count
=
7853 IGMP_DEFAULT_ROBUSTNESS_VARIABLE
;
7858 #define IGMP_LAST_MEMBER_QUERY_INTERVAL_MIN (1)
7859 #define IGMP_LAST_MEMBER_QUERY_INTERVAL_MAX (255)
7861 DEFUN (interface_ip_igmp_last_member_query_interval
,
7862 interface_ip_igmp_last_member_query_interval_cmd
,
7863 "ip igmp last-member-query-interval (1-255)",
7866 IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR
7867 "Last member query interval in deciseconds\n")
7869 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7870 struct pim_interface
*pim_ifp
= ifp
->info
;
7871 int last_member_query_interval
;
7875 ret
= pim_cmd_igmp_start(vty
, ifp
);
7876 if (ret
!= CMD_SUCCESS
)
7878 pim_ifp
= ifp
->info
;
7881 last_member_query_interval
= atoi(argv
[3]->arg
);
7882 pim_ifp
->igmp_specific_query_max_response_time_dsec
7883 = last_member_query_interval
;
7888 DEFUN (interface_no_ip_igmp_last_member_query_interval
,
7889 interface_no_ip_igmp_last_member_query_interval_cmd
,
7890 "no ip igmp last-member-query-interval",
7894 IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR
)
7896 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7897 struct pim_interface
*pim_ifp
= ifp
->info
;
7902 pim_ifp
->igmp_specific_query_max_response_time_dsec
=
7903 IGMP_SPECIFIC_QUERY_MAX_RESPONSE_TIME_DSEC
;
7908 DEFUN (interface_ip_pim_drprio
,
7909 interface_ip_pim_drprio_cmd
,
7910 "ip pim drpriority (1-4294967295)",
7913 "Set the Designated Router Election Priority\n"
7914 "Value of the new DR Priority\n")
7916 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7918 struct pim_interface
*pim_ifp
= ifp
->info
;
7919 uint32_t old_dr_prio
;
7922 vty_out(vty
, "Please enable PIM on interface, first\n");
7923 return CMD_WARNING_CONFIG_FAILED
;
7926 old_dr_prio
= pim_ifp
->pim_dr_priority
;
7928 pim_ifp
->pim_dr_priority
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
7930 if (old_dr_prio
!= pim_ifp
->pim_dr_priority
) {
7931 pim_if_dr_election(ifp
);
7932 pim_hello_restart_now(ifp
);
7938 DEFUN (interface_no_ip_pim_drprio
,
7939 interface_no_ip_pim_drprio_cmd
,
7940 "no ip pim drpriority [(1-4294967295)]",
7944 "Revert the Designated Router Priority to default\n"
7945 "Old Value of the Priority\n")
7947 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7948 struct pim_interface
*pim_ifp
= ifp
->info
;
7951 vty_out(vty
, "Pim not enabled on this interface\n");
7952 return CMD_WARNING_CONFIG_FAILED
;
7955 if (pim_ifp
->pim_dr_priority
!= PIM_DEFAULT_DR_PRIORITY
) {
7956 pim_ifp
->pim_dr_priority
= PIM_DEFAULT_DR_PRIORITY
;
7957 pim_if_dr_election(ifp
);
7958 pim_hello_restart_now(ifp
);
7964 DEFPY_HIDDEN (interface_ip_igmp_query_generate
,
7965 interface_ip_igmp_query_generate_cmd
,
7966 "ip igmp generate-query-once [version (2-3)]",
7969 "Generate igmp general query once\n"
7971 "IGMP version number\n")
7973 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7974 int igmp_version
= 2;
7977 vty_out(vty
, "IGMP/PIM is not enabled on the interface %s\n",
7979 return CMD_WARNING_CONFIG_FAILED
;
7983 igmp_version
= atoi(argv
[4]->arg
);
7985 igmp_send_query_on_intf(ifp
, igmp_version
);
7990 static int pim_cmd_interface_add(struct interface
*ifp
)
7992 struct pim_interface
*pim_ifp
= ifp
->info
;
7995 pim_ifp
= pim_if_new(ifp
, false, true, false, false);
7997 PIM_IF_DO_PIM(pim_ifp
->options
);
7999 pim_if_addr_add_all(ifp
);
8000 pim_if_membership_refresh(ifp
);
8002 pim_if_create_pimreg(pim_ifp
->pim
);
8006 DEFPY_HIDDEN (pim_test_sg_keepalive
,
8007 pim_test_sg_keepalive_cmd
,
8008 "test pim [vrf NAME$name] keepalive-reset A.B.C.D$source A.B.C.D$group",
8012 "Reset the Keepalive Timer\n"
8013 "The Source we are resetting\n"
8014 "The Group we are resetting\n")
8016 struct pim_upstream
*up
;
8017 struct pim_instance
*pim
;
8018 struct prefix_sg sg
;
8024 pim
= pim_get_pim_instance(VRF_DEFAULT
);
8026 struct vrf
*vrf
= vrf_lookup_by_name(name
);
8029 vty_out(vty
, "%% Vrf specified: %s does not exist\n",
8034 pim
= pim_get_pim_instance(vrf
->vrf_id
);
8038 vty_out(vty
, "%% Unable to find pim instance\n");
8042 up
= pim_upstream_find(pim
, &sg
);
8044 vty_out(vty
, "%% Unable to find %s specified\n",
8045 pim_str_sg_dump(&sg
));
8049 vty_out(vty
, "Setting %s to current keep alive time: %d\n",
8050 pim_str_sg_dump(&sg
), pim
->keep_alive_time
);
8051 pim_upstream_keep_alive_timer_start(up
, pim
->keep_alive_time
);
8056 DEFPY (interface_ip_pim_activeactive
,
8057 interface_ip_pim_activeactive_cmd
,
8058 "[no$no] ip pim active-active",
8062 "Mark interface as Active-Active for MLAG operations, Hidden because not finished yet\n")
8064 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8065 struct pim_interface
*pim_ifp
;
8067 if (!no
&& !pim_cmd_interface_add(ifp
)) {
8068 vty_out(vty
, "Could not enable PIM SM active-active on interface\n");
8069 return CMD_WARNING_CONFIG_FAILED
;
8074 zlog_debug("%sConfiguring PIM active-active on Interface: %s",
8075 no
? "Un-":" ", ifp
->name
);
8077 pim_ifp
= ifp
->info
;
8079 pim_if_unconfigure_mlag_dualactive(pim_ifp
);
8081 pim_if_configure_mlag_dualactive(pim_ifp
);
8086 DEFUN_HIDDEN (interface_ip_pim_ssm
,
8087 interface_ip_pim_ssm_cmd
,
8093 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8095 if (!pim_cmd_interface_add(ifp
)) {
8096 vty_out(vty
, "Could not enable PIM SM on interface\n");
8097 return CMD_WARNING_CONFIG_FAILED
;
8101 "WARN: Enabled PIM SM on interface; configure PIM SSM "
8102 "range if needed\n");
8106 static int interface_ip_pim_helper(struct vty
*vty
)
8108 struct pim_interface
*pim_ifp
;
8110 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8112 if (!pim_cmd_interface_add(ifp
)) {
8113 vty_out(vty
, "Could not enable PIM SM on interface\n");
8114 return CMD_WARNING_CONFIG_FAILED
;
8117 pim_ifp
= ifp
->info
;
8119 pim_if_create_pimreg(pim_ifp
->pim
);
8124 DEFUN_HIDDEN (interface_ip_pim_sm
,
8125 interface_ip_pim_sm_cmd
,
8131 return interface_ip_pim_helper(vty
);
8134 DEFUN (interface_ip_pim
,
8135 interface_ip_pim_cmd
,
8140 return interface_ip_pim_helper(vty
);
8143 static int pim_cmd_interface_delete(struct interface
*ifp
)
8145 struct pim_interface
*pim_ifp
= ifp
->info
;
8150 PIM_IF_DONT_PIM(pim_ifp
->options
);
8152 pim_if_membership_clear(ifp
);
8155 pim_sock_delete() removes all neighbors from
8156 pim_ifp->pim_neighbor_list.
8158 pim_sock_delete(ifp
, "pim unconfigured on interface");
8160 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
8161 pim_if_addr_del_all(ifp
);
8168 static int interface_no_ip_pim_helper(struct vty
*vty
)
8170 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8171 if (!pim_cmd_interface_delete(ifp
)) {
8172 vty_out(vty
, "Unable to delete interface information\n");
8173 return CMD_WARNING_CONFIG_FAILED
;
8179 DEFUN_HIDDEN (interface_no_ip_pim_ssm
,
8180 interface_no_ip_pim_ssm_cmd
,
8187 return interface_no_ip_pim_helper(vty
);
8190 DEFUN_HIDDEN (interface_no_ip_pim_sm
,
8191 interface_no_ip_pim_sm_cmd
,
8198 return interface_no_ip_pim_helper(vty
);
8201 DEFUN (interface_no_ip_pim
,
8202 interface_no_ip_pim_cmd
,
8208 return interface_no_ip_pim_helper(vty
);
8212 DEFUN(interface_ip_pim_boundary_oil
,
8213 interface_ip_pim_boundary_oil_cmd
,
8214 "ip multicast boundary oil WORD",
8216 "Generic multicast configuration options\n"
8217 "Define multicast boundary\n"
8218 "Filter OIL by group using prefix list\n"
8219 "Prefix list to filter OIL with\n")
8221 VTY_DECLVAR_CONTEXT(interface
, iif
);
8222 struct pim_interface
*pim_ifp
;
8225 argv_find(argv
, argc
, "WORD", &idx
);
8227 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
8229 if (pim_ifp
->boundary_oil_plist
)
8230 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
8232 pim_ifp
->boundary_oil_plist
=
8233 XSTRDUP(MTYPE_PIM_INTERFACE
, argv
[idx
]->arg
);
8235 /* Interface will be pruned from OIL on next Join */
8239 DEFUN(interface_no_ip_pim_boundary_oil
,
8240 interface_no_ip_pim_boundary_oil_cmd
,
8241 "no ip multicast boundary oil [WORD]",
8244 "Generic multicast configuration options\n"
8245 "Define multicast boundary\n"
8246 "Filter OIL by group using prefix list\n"
8247 "Prefix list to filter OIL with\n")
8249 VTY_DECLVAR_CONTEXT(interface
, iif
);
8250 struct pim_interface
*pim_ifp
;
8253 argv_find(argv
, argc
, "WORD", &idx
);
8255 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
8257 if (pim_ifp
->boundary_oil_plist
)
8258 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
8263 DEFUN (interface_ip_mroute
,
8264 interface_ip_mroute_cmd
,
8265 "ip mroute INTERFACE A.B.C.D [A.B.C.D]",
8267 "Add multicast route\n"
8268 "Outgoing interface name\n"
8272 VTY_DECLVAR_CONTEXT(interface
, iif
);
8273 struct pim_interface
*pim_ifp
;
8274 struct pim_instance
*pim
;
8275 int idx_interface
= 2;
8277 struct interface
*oif
;
8278 const char *oifname
;
8279 const char *grp_str
;
8280 struct in_addr grp_addr
;
8281 const char *src_str
;
8282 struct in_addr src_addr
;
8285 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
8288 oifname
= argv
[idx_interface
]->arg
;
8289 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
8291 vty_out(vty
, "No such interface name %s\n", oifname
);
8295 grp_str
= argv
[idx_ipv4
]->arg
;
8296 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
8298 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
8299 errno
, safe_strerror(errno
));
8303 if (argc
== (idx_ipv4
+ 1)) {
8304 src_addr
.s_addr
= INADDR_ANY
;
8307 src_str
= argv
[idx_ipv4
+ 1]->arg
;
8308 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
8310 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
8311 errno
, safe_strerror(errno
));
8316 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
8317 vty_out(vty
, "Failed to add static mroute\n");
8324 DEFUN (interface_no_ip_mroute
,
8325 interface_no_ip_mroute_cmd
,
8326 "no ip mroute INTERFACE A.B.C.D [A.B.C.D]",
8329 "Add multicast route\n"
8330 "Outgoing interface name\n"
8334 VTY_DECLVAR_CONTEXT(interface
, iif
);
8335 struct pim_interface
*pim_ifp
;
8336 struct pim_instance
*pim
;
8337 int idx_interface
= 3;
8339 struct interface
*oif
;
8340 const char *oifname
;
8341 const char *grp_str
;
8342 struct in_addr grp_addr
;
8343 const char *src_str
;
8344 struct in_addr src_addr
;
8347 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
8350 oifname
= argv
[idx_interface
]->arg
;
8351 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
8353 vty_out(vty
, "No such interface name %s\n", oifname
);
8357 grp_str
= argv
[idx_ipv4
]->arg
;
8358 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
8360 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
8361 errno
, safe_strerror(errno
));
8365 if (argc
== (idx_ipv4
+ 1)) {
8366 src_addr
.s_addr
= INADDR_ANY
;
8369 src_str
= argv
[idx_ipv4
+ 1]->arg
;
8370 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
8372 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
8373 errno
, safe_strerror(errno
));
8378 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
8379 vty_out(vty
, "Failed to remove static mroute\n");
8386 DEFUN (interface_ip_pim_hello
,
8387 interface_ip_pim_hello_cmd
,
8388 "ip pim hello (1-180) [(1-180)]",
8392 IFACE_PIM_HELLO_TIME_STR
8393 IFACE_PIM_HELLO_HOLD_STR
)
8395 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8398 struct pim_interface
*pim_ifp
= ifp
->info
;
8401 if (!pim_cmd_interface_add(ifp
)) {
8402 vty_out(vty
, "Could not enable PIM SM on interface\n");
8403 return CMD_WARNING_CONFIG_FAILED
;
8407 pim_ifp
= ifp
->info
;
8408 pim_ifp
->pim_hello_period
= strtol(argv
[idx_time
]->arg
, NULL
, 10);
8410 if (argc
== idx_hold
+ 1)
8411 pim_ifp
->pim_default_holdtime
=
8412 strtol(argv
[idx_hold
]->arg
, NULL
, 10);
8417 DEFUN (interface_no_ip_pim_hello
,
8418 interface_no_ip_pim_hello_cmd
,
8419 "no ip pim hello [(1-180) (1-180)]",
8424 IFACE_PIM_HELLO_TIME_STR
8425 IFACE_PIM_HELLO_HOLD_STR
)
8427 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8428 struct pim_interface
*pim_ifp
= ifp
->info
;
8431 vty_out(vty
, "Pim not enabled on this interface\n");
8432 return CMD_WARNING_CONFIG_FAILED
;
8435 pim_ifp
->pim_hello_period
= PIM_DEFAULT_HELLO_PERIOD
;
8436 pim_ifp
->pim_default_holdtime
= -1;
8447 PIM_DO_DEBUG_IGMP_EVENTS
;
8448 PIM_DO_DEBUG_IGMP_PACKETS
;
8449 PIM_DO_DEBUG_IGMP_TRACE
;
8453 DEFUN (no_debug_igmp
,
8460 PIM_DONT_DEBUG_IGMP_EVENTS
;
8461 PIM_DONT_DEBUG_IGMP_PACKETS
;
8462 PIM_DONT_DEBUG_IGMP_TRACE
;
8467 DEFUN (debug_igmp_events
,
8468 debug_igmp_events_cmd
,
8469 "debug igmp events",
8472 DEBUG_IGMP_EVENTS_STR
)
8474 PIM_DO_DEBUG_IGMP_EVENTS
;
8478 DEFUN (no_debug_igmp_events
,
8479 no_debug_igmp_events_cmd
,
8480 "no debug igmp events",
8484 DEBUG_IGMP_EVENTS_STR
)
8486 PIM_DONT_DEBUG_IGMP_EVENTS
;
8491 DEFUN (debug_igmp_packets
,
8492 debug_igmp_packets_cmd
,
8493 "debug igmp packets",
8496 DEBUG_IGMP_PACKETS_STR
)
8498 PIM_DO_DEBUG_IGMP_PACKETS
;
8502 DEFUN (no_debug_igmp_packets
,
8503 no_debug_igmp_packets_cmd
,
8504 "no debug igmp packets",
8508 DEBUG_IGMP_PACKETS_STR
)
8510 PIM_DONT_DEBUG_IGMP_PACKETS
;
8515 DEFUN (debug_igmp_trace
,
8516 debug_igmp_trace_cmd
,
8520 DEBUG_IGMP_TRACE_STR
)
8522 PIM_DO_DEBUG_IGMP_TRACE
;
8526 DEFUN (no_debug_igmp_trace
,
8527 no_debug_igmp_trace_cmd
,
8528 "no debug igmp trace",
8532 DEBUG_IGMP_TRACE_STR
)
8534 PIM_DONT_DEBUG_IGMP_TRACE
;
8539 DEFUN (debug_mroute
,
8545 PIM_DO_DEBUG_MROUTE
;
8549 DEFUN (debug_mroute_detail
,
8550 debug_mroute_detail_cmd
,
8551 "debug mroute detail",
8556 PIM_DO_DEBUG_MROUTE_DETAIL
;
8560 DEFUN (no_debug_mroute
,
8561 no_debug_mroute_cmd
,
8567 PIM_DONT_DEBUG_MROUTE
;
8571 DEFUN (no_debug_mroute_detail
,
8572 no_debug_mroute_detail_cmd
,
8573 "no debug mroute detail",
8579 PIM_DONT_DEBUG_MROUTE_DETAIL
;
8583 DEFUN (debug_pim_static
,
8584 debug_pim_static_cmd
,
8590 PIM_DO_DEBUG_STATIC
;
8594 DEFUN (no_debug_pim_static
,
8595 no_debug_pim_static_cmd
,
8596 "no debug pim static",
8602 PIM_DONT_DEBUG_STATIC
;
8613 PIM_DO_DEBUG_PIM_EVENTS
;
8614 PIM_DO_DEBUG_PIM_PACKETS
;
8615 PIM_DO_DEBUG_PIM_TRACE
;
8616 PIM_DO_DEBUG_MSDP_EVENTS
;
8617 PIM_DO_DEBUG_MSDP_PACKETS
;
8622 DEFUN (no_debug_pim
,
8629 PIM_DONT_DEBUG_PIM_EVENTS
;
8630 PIM_DONT_DEBUG_PIM_PACKETS
;
8631 PIM_DONT_DEBUG_PIM_TRACE
;
8632 PIM_DONT_DEBUG_MSDP_EVENTS
;
8633 PIM_DONT_DEBUG_MSDP_PACKETS
;
8635 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
8636 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
8642 DEFUN (debug_pim_nht
,
8647 "Nexthop Tracking\n")
8649 PIM_DO_DEBUG_PIM_NHT
;
8653 DEFUN (no_debug_pim_nht
,
8654 no_debug_pim_nht_cmd
,
8659 "Nexthop Tracking\n")
8661 PIM_DONT_DEBUG_PIM_NHT
;
8665 DEFUN (debug_pim_nht_rp
,
8666 debug_pim_nht_rp_cmd
,
8670 "Nexthop Tracking\n"
8671 "RP Nexthop Tracking\n")
8673 PIM_DO_DEBUG_PIM_NHT_RP
;
8677 DEFUN (no_debug_pim_nht_rp
,
8678 no_debug_pim_nht_rp_cmd
,
8679 "no debug pim nht rp",
8683 "Nexthop Tracking\n"
8684 "RP Nexthop Tracking\n")
8686 PIM_DONT_DEBUG_PIM_NHT_RP
;
8690 DEFUN (debug_pim_events
,
8691 debug_pim_events_cmd
,
8695 DEBUG_PIM_EVENTS_STR
)
8697 PIM_DO_DEBUG_PIM_EVENTS
;
8701 DEFUN (no_debug_pim_events
,
8702 no_debug_pim_events_cmd
,
8703 "no debug pim events",
8707 DEBUG_PIM_EVENTS_STR
)
8709 PIM_DONT_DEBUG_PIM_EVENTS
;
8713 DEFUN (debug_pim_packets
,
8714 debug_pim_packets_cmd
,
8715 "debug pim packets [<hello|joins|register>]",
8718 DEBUG_PIM_PACKETS_STR
8719 DEBUG_PIM_HELLO_PACKETS_STR
8720 DEBUG_PIM_J_P_PACKETS_STR
8721 DEBUG_PIM_PIM_REG_PACKETS_STR
)
8724 if (argv_find(argv
, argc
, "hello", &idx
)) {
8725 PIM_DO_DEBUG_PIM_HELLO
;
8726 vty_out(vty
, "PIM Hello debugging is on\n");
8727 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
8728 PIM_DO_DEBUG_PIM_J_P
;
8729 vty_out(vty
, "PIM Join/Prune debugging is on\n");
8730 } else if (argv_find(argv
, argc
, "register", &idx
)) {
8731 PIM_DO_DEBUG_PIM_REG
;
8732 vty_out(vty
, "PIM Register debugging is on\n");
8734 PIM_DO_DEBUG_PIM_PACKETS
;
8735 vty_out(vty
, "PIM Packet debugging is on \n");
8740 DEFUN (no_debug_pim_packets
,
8741 no_debug_pim_packets_cmd
,
8742 "no debug pim packets [<hello|joins|register>]",
8746 DEBUG_PIM_PACKETS_STR
8747 DEBUG_PIM_HELLO_PACKETS_STR
8748 DEBUG_PIM_J_P_PACKETS_STR
8749 DEBUG_PIM_PIM_REG_PACKETS_STR
)
8752 if (argv_find(argv
, argc
, "hello", &idx
)) {
8753 PIM_DONT_DEBUG_PIM_HELLO
;
8754 vty_out(vty
, "PIM Hello debugging is off \n");
8755 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
8756 PIM_DONT_DEBUG_PIM_J_P
;
8757 vty_out(vty
, "PIM Join/Prune debugging is off \n");
8758 } else if (argv_find(argv
, argc
, "register", &idx
)) {
8759 PIM_DONT_DEBUG_PIM_REG
;
8760 vty_out(vty
, "PIM Register debugging is off\n");
8762 PIM_DONT_DEBUG_PIM_PACKETS
;
8768 DEFUN (debug_pim_packetdump_send
,
8769 debug_pim_packetdump_send_cmd
,
8770 "debug pim packet-dump send",
8773 DEBUG_PIM_PACKETDUMP_STR
8774 DEBUG_PIM_PACKETDUMP_SEND_STR
)
8776 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND
;
8780 DEFUN (no_debug_pim_packetdump_send
,
8781 no_debug_pim_packetdump_send_cmd
,
8782 "no debug pim packet-dump send",
8786 DEBUG_PIM_PACKETDUMP_STR
8787 DEBUG_PIM_PACKETDUMP_SEND_STR
)
8789 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
8793 DEFUN (debug_pim_packetdump_recv
,
8794 debug_pim_packetdump_recv_cmd
,
8795 "debug pim packet-dump receive",
8798 DEBUG_PIM_PACKETDUMP_STR
8799 DEBUG_PIM_PACKETDUMP_RECV_STR
)
8801 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV
;
8805 DEFUN (no_debug_pim_packetdump_recv
,
8806 no_debug_pim_packetdump_recv_cmd
,
8807 "no debug pim packet-dump receive",
8811 DEBUG_PIM_PACKETDUMP_STR
8812 DEBUG_PIM_PACKETDUMP_RECV_STR
)
8814 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
8818 DEFUN (debug_pim_trace
,
8819 debug_pim_trace_cmd
,
8823 DEBUG_PIM_TRACE_STR
)
8825 PIM_DO_DEBUG_PIM_TRACE
;
8829 DEFUN (debug_pim_trace_detail
,
8830 debug_pim_trace_detail_cmd
,
8831 "debug pim trace detail",
8835 "Detailed Information\n")
8837 PIM_DO_DEBUG_PIM_TRACE_DETAIL
;
8841 DEFUN (no_debug_pim_trace
,
8842 no_debug_pim_trace_cmd
,
8843 "no debug pim trace",
8847 DEBUG_PIM_TRACE_STR
)
8849 PIM_DONT_DEBUG_PIM_TRACE
;
8853 DEFUN (no_debug_pim_trace_detail
,
8854 no_debug_pim_trace_detail_cmd
,
8855 "no debug pim trace detail",
8860 "Detailed Information\n")
8862 PIM_DONT_DEBUG_PIM_TRACE_DETAIL
;
8866 DEFUN (debug_ssmpingd
,
8872 PIM_DO_DEBUG_SSMPINGD
;
8876 DEFUN (no_debug_ssmpingd
,
8877 no_debug_ssmpingd_cmd
,
8878 "no debug ssmpingd",
8883 PIM_DONT_DEBUG_SSMPINGD
;
8887 DEFUN (debug_pim_zebra
,
8888 debug_pim_zebra_cmd
,
8892 DEBUG_PIM_ZEBRA_STR
)
8898 DEFUN (no_debug_pim_zebra
,
8899 no_debug_pim_zebra_cmd
,
8900 "no debug pim zebra",
8904 DEBUG_PIM_ZEBRA_STR
)
8906 PIM_DONT_DEBUG_ZEBRA
;
8910 DEFUN(debug_pim_mlag
, debug_pim_mlag_cmd
, "debug pim mlag",
8911 DEBUG_STR DEBUG_PIM_STR DEBUG_PIM_MLAG_STR
)
8917 DEFUN(no_debug_pim_mlag
, no_debug_pim_mlag_cmd
, "no debug pim mlag",
8918 NO_STR DEBUG_STR DEBUG_PIM_STR DEBUG_PIM_MLAG_STR
)
8920 PIM_DONT_DEBUG_MLAG
;
8924 DEFUN (debug_pim_vxlan
,
8925 debug_pim_vxlan_cmd
,
8929 DEBUG_PIM_VXLAN_STR
)
8935 DEFUN (no_debug_pim_vxlan
,
8936 no_debug_pim_vxlan_cmd
,
8937 "no debug pim vxlan",
8941 DEBUG_PIM_VXLAN_STR
)
8943 PIM_DONT_DEBUG_VXLAN
;
8953 PIM_DO_DEBUG_MSDP_EVENTS
;
8954 PIM_DO_DEBUG_MSDP_PACKETS
;
8958 DEFUN (no_debug_msdp
,
8965 PIM_DONT_DEBUG_MSDP_EVENTS
;
8966 PIM_DONT_DEBUG_MSDP_PACKETS
;
8970 DEFUN (debug_msdp_events
,
8971 debug_msdp_events_cmd
,
8972 "debug msdp events",
8975 DEBUG_MSDP_EVENTS_STR
)
8977 PIM_DO_DEBUG_MSDP_EVENTS
;
8981 DEFUN (no_debug_msdp_events
,
8982 no_debug_msdp_events_cmd
,
8983 "no debug msdp events",
8987 DEBUG_MSDP_EVENTS_STR
)
8989 PIM_DONT_DEBUG_MSDP_EVENTS
;
8993 DEFUN (debug_msdp_packets
,
8994 debug_msdp_packets_cmd
,
8995 "debug msdp packets",
8998 DEBUG_MSDP_PACKETS_STR
)
9000 PIM_DO_DEBUG_MSDP_PACKETS
;
9004 DEFUN (no_debug_msdp_packets
,
9005 no_debug_msdp_packets_cmd
,
9006 "no debug msdp packets",
9010 DEBUG_MSDP_PACKETS_STR
)
9012 PIM_DONT_DEBUG_MSDP_PACKETS
;
9016 DEFUN (debug_mtrace
,
9022 PIM_DO_DEBUG_MTRACE
;
9026 DEFUN (no_debug_mtrace
,
9027 no_debug_mtrace_cmd
,
9033 PIM_DONT_DEBUG_MTRACE
;
9048 DEFUN (no_debug_bsm
,
9061 DEFUN_NOSH (show_debugging_pim
,
9062 show_debugging_pim_cmd
,
9063 "show debugging [pim]",
9068 vty_out(vty
, "PIM debugging status\n");
9070 pim_debug_config_write(vty
);
9075 static int interface_pim_use_src_cmd_worker(struct vty
*vty
, const char *source
)
9078 struct in_addr source_addr
;
9079 int ret
= CMD_SUCCESS
;
9080 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9082 result
= inet_pton(AF_INET
, source
, &source_addr
);
9084 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", source
,
9085 errno
, safe_strerror(errno
));
9086 return CMD_WARNING_CONFIG_FAILED
;
9089 result
= pim_update_source_set(ifp
, source_addr
);
9093 case PIM_IFACE_NOT_FOUND
:
9094 ret
= CMD_WARNING_CONFIG_FAILED
;
9095 vty_out(vty
, "Pim not enabled on this interface\n");
9097 case PIM_UPDATE_SOURCE_DUP
:
9099 vty_out(vty
, "%% Source already set to %s\n", source
);
9102 ret
= CMD_WARNING_CONFIG_FAILED
;
9103 vty_out(vty
, "%% Source set failed\n");
9109 DEFUN (interface_pim_use_source
,
9110 interface_pim_use_source_cmd
,
9111 "ip pim use-source A.B.C.D",
9114 "Configure primary IP address\n"
9115 "source ip address\n")
9117 return interface_pim_use_src_cmd_worker(vty
, argv
[3]->arg
);
9120 DEFUN (interface_no_pim_use_source
,
9121 interface_no_pim_use_source_cmd
,
9122 "no ip pim use-source [A.B.C.D]",
9126 "Delete source IP address\n"
9127 "source ip address\n")
9129 return interface_pim_use_src_cmd_worker(vty
, "0.0.0.0");
9137 "Enables BFD support\n")
9139 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9140 struct pim_interface
*pim_ifp
= ifp
->info
;
9141 struct bfd_info
*bfd_info
= NULL
;
9144 if (!pim_cmd_interface_add(ifp
)) {
9145 vty_out(vty
, "Could not enable PIM SM on interface\n");
9149 pim_ifp
= ifp
->info
;
9151 bfd_info
= pim_ifp
->bfd_info
;
9153 if (!bfd_info
|| !CHECK_FLAG(bfd_info
->flags
, BFD_FLAG_PARAM_CFG
))
9154 pim_bfd_if_param_set(ifp
, BFD_DEF_MIN_RX
, BFD_DEF_MIN_TX
,
9155 BFD_DEF_DETECT_MULT
, 1);
9160 DEFUN (no_ip_pim_bfd
,
9166 "Disables BFD support\n")
9168 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9169 struct pim_interface
*pim_ifp
= ifp
->info
;
9172 vty_out(vty
, "Pim not enabled on this interface\n");
9176 if (pim_ifp
->bfd_info
) {
9177 pim_bfd_reg_dereg_all_nbr(ifp
, ZEBRA_BFD_DEST_DEREGISTER
);
9178 bfd_info_free(&(pim_ifp
->bfd_info
));
9189 "Enables BSM support on the interface\n")
9191 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9192 struct pim_interface
*pim_ifp
= ifp
->info
;
9195 if (!pim_cmd_interface_add(ifp
)) {
9196 vty_out(vty
, "Could not enable PIM SM on interface\n");
9201 pim_ifp
= ifp
->info
;
9202 pim_ifp
->bsm_enable
= true;
9207 DEFUN (no_ip_pim_bsm
,
9213 "Disables BSM support\n")
9215 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9216 struct pim_interface
*pim_ifp
= ifp
->info
;
9219 vty_out(vty
, "Pim not enabled on this interface\n");
9223 pim_ifp
->bsm_enable
= false;
9228 DEFUN (ip_pim_ucast_bsm
,
9229 ip_pim_ucast_bsm_cmd
,
9230 "ip pim unicast-bsm",
9233 "Accept/Send unicast BSM on the interface\n")
9235 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9236 struct pim_interface
*pim_ifp
= ifp
->info
;
9239 if (!pim_cmd_interface_add(ifp
)) {
9240 vty_out(vty
, "Could not enable PIM SM on interface\n");
9245 pim_ifp
= ifp
->info
;
9246 pim_ifp
->ucast_bsm_accept
= true;
9251 DEFUN (no_ip_pim_ucast_bsm
,
9252 no_ip_pim_ucast_bsm_cmd
,
9253 "no ip pim unicast-bsm",
9257 "Block send/receive unicast BSM on this interface\n")
9259 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9260 struct pim_interface
*pim_ifp
= ifp
->info
;
9263 vty_out(vty
, "Pim not enabled on this interface\n");
9267 pim_ifp
->ucast_bsm_accept
= false;
9275 ip_pim_bfd_param_cmd
,
9276 "ip pim bfd (2-255) (50-60000) (50-60000)",
9279 "Enables BFD support\n"
9280 "Detect Multiplier\n"
9281 "Required min receive interval\n"
9282 "Desired min transmit interval\n")
9286 ip_pim_bfd_param_cmd
,
9287 "ip pim bfd (2-255) (50-60000) (50-60000)",
9290 "Enables BFD support\n"
9291 "Detect Multiplier\n"
9292 "Required min receive interval\n"
9293 "Desired min transmit interval\n")
9294 #endif /* HAVE_BFDD */
9296 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9298 int idx_number_2
= 4;
9299 int idx_number_3
= 5;
9304 struct pim_interface
*pim_ifp
= ifp
->info
;
9307 if (!pim_cmd_interface_add(ifp
)) {
9308 vty_out(vty
, "Could not enable PIM SM on interface\n");
9313 if ((ret
= bfd_validate_param(
9314 vty
, argv
[idx_number
]->arg
, argv
[idx_number_2
]->arg
,
9315 argv
[idx_number_3
]->arg
, &dm_val
, &rx_val
, &tx_val
))
9319 pim_bfd_if_param_set(ifp
, rx_val
, tx_val
, dm_val
, 0);
9325 ALIAS(no_ip_pim_bfd
, no_ip_pim_bfd_param_cmd
,
9326 "no ip pim bfd (2-255) (50-60000) (50-60000)", NO_STR IP_STR PIM_STR
9327 "Enables BFD support\n"
9328 "Detect Multiplier\n"
9329 "Required min receive interval\n"
9330 "Desired min transmit interval\n")
9331 #endif /* !HAVE_BFDD */
9333 static int ip_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
9334 const char *peer
, const char *local
)
9336 enum pim_msdp_err result
;
9337 struct in_addr peer_addr
;
9338 struct in_addr local_addr
;
9339 int ret
= CMD_SUCCESS
;
9341 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
9343 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
9344 errno
, safe_strerror(errno
));
9345 return CMD_WARNING_CONFIG_FAILED
;
9348 result
= inet_pton(AF_INET
, local
, &local_addr
);
9350 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", local
,
9351 errno
, safe_strerror(errno
));
9352 return CMD_WARNING_CONFIG_FAILED
;
9355 result
= pim_msdp_peer_add(pim
, peer_addr
, local_addr
, "default",
9358 case PIM_MSDP_ERR_NONE
:
9360 case PIM_MSDP_ERR_OOM
:
9361 ret
= CMD_WARNING_CONFIG_FAILED
;
9362 vty_out(vty
, "%% Out of memory\n");
9364 case PIM_MSDP_ERR_PEER_EXISTS
:
9366 vty_out(vty
, "%% Peer exists\n");
9368 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
9369 ret
= CMD_WARNING_CONFIG_FAILED
;
9370 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
9373 ret
= CMD_WARNING_CONFIG_FAILED
;
9374 vty_out(vty
, "%% peer add failed\n");
9380 DEFUN_HIDDEN (ip_msdp_peer
,
9382 "ip msdp peer A.B.C.D source A.B.C.D",
9385 "Configure MSDP peer\n"
9387 "Source address for TCP connection\n"
9388 "local ip address\n")
9390 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9391 return ip_msdp_peer_cmd_worker(pim
, vty
, argv
[3]->arg
, argv
[5]->arg
);
9394 static int ip_no_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
9397 enum pim_msdp_err result
;
9398 struct in_addr peer_addr
;
9400 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
9402 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
9403 errno
, safe_strerror(errno
));
9404 return CMD_WARNING_CONFIG_FAILED
;
9407 result
= pim_msdp_peer_del(pim
, peer_addr
);
9409 case PIM_MSDP_ERR_NONE
:
9411 case PIM_MSDP_ERR_NO_PEER
:
9412 vty_out(vty
, "%% Peer does not exist\n");
9415 vty_out(vty
, "%% peer del failed\n");
9418 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9421 DEFUN_HIDDEN (no_ip_msdp_peer
,
9422 no_ip_msdp_peer_cmd
,
9423 "no ip msdp peer A.B.C.D",
9427 "Delete MSDP peer\n"
9428 "peer ip address\n")
9430 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9431 return ip_no_msdp_peer_cmd_worker(pim
, vty
, argv
[4]->arg
);
9434 static int ip_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
9435 struct vty
*vty
, const char *mg
,
9438 enum pim_msdp_err result
;
9439 struct in_addr mbr_ip
;
9440 int ret
= CMD_SUCCESS
;
9442 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
9444 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
9445 errno
, safe_strerror(errno
));
9446 return CMD_WARNING_CONFIG_FAILED
;
9449 result
= pim_msdp_mg_mbr_add(pim
, mg
, mbr_ip
);
9451 case PIM_MSDP_ERR_NONE
:
9453 case PIM_MSDP_ERR_OOM
:
9454 ret
= CMD_WARNING_CONFIG_FAILED
;
9455 vty_out(vty
, "%% Out of memory\n");
9457 case PIM_MSDP_ERR_MG_MBR_EXISTS
:
9459 vty_out(vty
, "%% mesh-group member exists\n");
9461 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
9462 ret
= CMD_WARNING_CONFIG_FAILED
;
9463 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
9466 ret
= CMD_WARNING_CONFIG_FAILED
;
9467 vty_out(vty
, "%% member add failed\n");
9473 DEFUN (ip_msdp_mesh_group_member
,
9474 ip_msdp_mesh_group_member_cmd
,
9475 "ip msdp mesh-group WORD member A.B.C.D",
9478 "Configure MSDP mesh-group\n"
9480 "mesh group member\n"
9481 "peer ip address\n")
9483 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9484 return ip_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[3]->arg
,
9488 static int ip_no_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
9493 enum pim_msdp_err result
;
9494 struct in_addr mbr_ip
;
9496 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
9498 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
9499 errno
, safe_strerror(errno
));
9500 return CMD_WARNING_CONFIG_FAILED
;
9503 result
= pim_msdp_mg_mbr_del(pim
, mg
, mbr_ip
);
9505 case PIM_MSDP_ERR_NONE
:
9507 case PIM_MSDP_ERR_NO_MG
:
9508 vty_out(vty
, "%% mesh-group does not exist\n");
9510 case PIM_MSDP_ERR_NO_MG_MBR
:
9511 vty_out(vty
, "%% mesh-group member does not exist\n");
9514 vty_out(vty
, "%% mesh-group member del failed\n");
9517 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9519 DEFUN (no_ip_msdp_mesh_group_member
,
9520 no_ip_msdp_mesh_group_member_cmd
,
9521 "no ip msdp mesh-group WORD member A.B.C.D",
9525 "Delete MSDP mesh-group member\n"
9527 "mesh group member\n"
9528 "peer ip address\n")
9530 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9531 return ip_no_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[4]->arg
,
9535 static int ip_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
9536 struct vty
*vty
, const char *mg
,
9539 enum pim_msdp_err result
;
9540 struct in_addr src_ip
;
9542 result
= inet_pton(AF_INET
, src
, &src_ip
);
9544 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", src
,
9545 errno
, safe_strerror(errno
));
9546 return CMD_WARNING_CONFIG_FAILED
;
9549 result
= pim_msdp_mg_src_add(pim
, mg
, src_ip
);
9551 case PIM_MSDP_ERR_NONE
:
9553 case PIM_MSDP_ERR_OOM
:
9554 vty_out(vty
, "%% Out of memory\n");
9556 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
9557 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
9560 vty_out(vty
, "%% source add failed\n");
9563 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9567 DEFUN (ip_msdp_mesh_group_source
,
9568 ip_msdp_mesh_group_source_cmd
,
9569 "ip msdp mesh-group WORD source A.B.C.D",
9572 "Configure MSDP mesh-group\n"
9574 "mesh group local address\n"
9575 "source ip address for the TCP connection\n")
9577 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9578 return ip_msdp_mesh_group_source_cmd_worker(pim
, vty
, argv
[3]->arg
,
9582 static int ip_no_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
9586 enum pim_msdp_err result
;
9588 result
= pim_msdp_mg_src_del(pim
, mg
);
9590 case PIM_MSDP_ERR_NONE
:
9592 case PIM_MSDP_ERR_NO_MG
:
9593 vty_out(vty
, "%% mesh-group does not exist\n");
9596 vty_out(vty
, "%% mesh-group source del failed\n");
9599 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9602 static int ip_no_msdp_mesh_group_cmd_worker(struct pim_instance
*pim
,
9603 struct vty
*vty
, const char *mg
)
9605 enum pim_msdp_err result
;
9607 result
= pim_msdp_mg_del(pim
, mg
);
9609 case PIM_MSDP_ERR_NONE
:
9611 case PIM_MSDP_ERR_NO_MG
:
9612 vty_out(vty
, "%% mesh-group does not exist\n");
9615 vty_out(vty
, "%% mesh-group source del failed\n");
9618 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9621 DEFUN (no_ip_msdp_mesh_group_source
,
9622 no_ip_msdp_mesh_group_source_cmd
,
9623 "no ip msdp mesh-group WORD source [A.B.C.D]",
9627 "Delete MSDP mesh-group source\n"
9629 "mesh group source\n"
9630 "mesh group local address\n")
9632 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9634 return ip_no_msdp_mesh_group_cmd_worker(pim
, vty
, argv
[6]->arg
);
9636 return ip_no_msdp_mesh_group_source_cmd_worker(pim
, vty
,
9640 static void print_empty_json_obj(struct vty
*vty
)
9643 json
= json_object_new_object();
9644 vty_out(vty
, "%s\n",
9645 json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
));
9646 json_object_free(json
);
9649 static void ip_msdp_show_mesh_group(struct pim_instance
*pim
, struct vty
*vty
,
9652 struct listnode
*mbrnode
;
9653 struct pim_msdp_mg_mbr
*mbr
;
9654 struct pim_msdp_mg
*mg
= pim
->msdp
.mg
;
9655 char mbr_str
[INET_ADDRSTRLEN
];
9656 char src_str
[INET_ADDRSTRLEN
];
9657 char state_str
[PIM_MSDP_STATE_STRLEN
];
9658 enum pim_msdp_peer_state state
;
9659 json_object
*json
= NULL
;
9660 json_object
*json_mg_row
= NULL
;
9661 json_object
*json_members
= NULL
;
9662 json_object
*json_row
= NULL
;
9666 print_empty_json_obj(vty
);
9670 pim_inet4_dump("<source?>", mg
->src_ip
, src_str
, sizeof(src_str
));
9672 json
= json_object_new_object();
9673 /* currently there is only one mesh group but we should still
9675 * it a dict with mg-name as key */
9676 json_mg_row
= json_object_new_object();
9677 json_object_string_add(json_mg_row
, "name",
9678 mg
->mesh_group_name
);
9679 json_object_string_add(json_mg_row
, "source", src_str
);
9681 vty_out(vty
, "Mesh group : %s\n", mg
->mesh_group_name
);
9682 vty_out(vty
, " Source : %s\n", src_str
);
9683 vty_out(vty
, " Member State\n");
9686 for (ALL_LIST_ELEMENTS_RO(mg
->mbr_list
, mbrnode
, mbr
)) {
9687 pim_inet4_dump("<mbr?>", mbr
->mbr_ip
, mbr_str
, sizeof(mbr_str
));
9689 state
= mbr
->mp
->state
;
9691 state
= PIM_MSDP_DISABLED
;
9693 pim_msdp_state_dump(state
, state_str
, sizeof(state_str
));
9695 json_row
= json_object_new_object();
9696 json_object_string_add(json_row
, "member", mbr_str
);
9697 json_object_string_add(json_row
, "state", state_str
);
9698 if (!json_members
) {
9699 json_members
= json_object_new_object();
9700 json_object_object_add(json_mg_row
, "members",
9703 json_object_object_add(json_members
, mbr_str
, json_row
);
9705 vty_out(vty
, " %-15s %11s\n", mbr_str
, state_str
);
9710 json_object_object_add(json
, mg
->mesh_group_name
, json_mg_row
);
9711 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9712 json
, JSON_C_TO_STRING_PRETTY
));
9713 json_object_free(json
);
9717 DEFUN (show_ip_msdp_mesh_group
,
9718 show_ip_msdp_mesh_group_cmd
,
9719 "show ip msdp [vrf NAME] mesh-group [json]",
9724 "MSDP mesh-group information\n"
9727 bool uj
= use_json(argc
, argv
);
9729 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
9734 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
9739 DEFUN (show_ip_msdp_mesh_group_vrf_all
,
9740 show_ip_msdp_mesh_group_vrf_all_cmd
,
9741 "show ip msdp vrf all mesh-group [json]",
9746 "MSDP mesh-group information\n"
9749 bool uj
= use_json(argc
, argv
);
9755 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
9759 vty_out(vty
, " \"%s\": ", vrf
->name
);
9762 vty_out(vty
, "VRF: %s\n", vrf
->name
);
9763 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
9766 vty_out(vty
, "}\n");
9771 static void ip_msdp_show_peers(struct pim_instance
*pim
, struct vty
*vty
,
9774 struct listnode
*mpnode
;
9775 struct pim_msdp_peer
*mp
;
9776 char peer_str
[INET_ADDRSTRLEN
];
9777 char local_str
[INET_ADDRSTRLEN
];
9778 char state_str
[PIM_MSDP_STATE_STRLEN
];
9779 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
9781 json_object
*json
= NULL
;
9782 json_object
*json_row
= NULL
;
9786 json
= json_object_new_object();
9789 "Peer Local State Uptime SaCnt\n");
9792 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
9793 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
9794 now
= pim_time_monotonic_sec();
9795 pim_time_uptime(timebuf
, sizeof(timebuf
),
9798 strlcpy(timebuf
, "-", sizeof(timebuf
));
9800 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
9801 pim_inet4_dump("<local?>", mp
->local
, local_str
,
9803 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
9805 json_row
= json_object_new_object();
9806 json_object_string_add(json_row
, "peer", peer_str
);
9807 json_object_string_add(json_row
, "local", local_str
);
9808 json_object_string_add(json_row
, "state", state_str
);
9809 json_object_string_add(json_row
, "upTime", timebuf
);
9810 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
9811 json_object_object_add(json
, peer_str
, json_row
);
9813 vty_out(vty
, "%-15s %15s %11s %8s %6d\n", peer_str
,
9814 local_str
, state_str
, timebuf
, mp
->sa_cnt
);
9819 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9820 json
, JSON_C_TO_STRING_PRETTY
));
9821 json_object_free(json
);
9825 static void ip_msdp_show_peers_detail(struct pim_instance
*pim
, struct vty
*vty
,
9826 const char *peer
, bool uj
)
9828 struct listnode
*mpnode
;
9829 struct pim_msdp_peer
*mp
;
9830 char peer_str
[INET_ADDRSTRLEN
];
9831 char local_str
[INET_ADDRSTRLEN
];
9832 char state_str
[PIM_MSDP_STATE_STRLEN
];
9833 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
9834 char katimer
[PIM_MSDP_TIMER_STRLEN
];
9835 char crtimer
[PIM_MSDP_TIMER_STRLEN
];
9836 char holdtimer
[PIM_MSDP_TIMER_STRLEN
];
9838 json_object
*json
= NULL
;
9839 json_object
*json_row
= NULL
;
9842 json
= json_object_new_object();
9845 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
9846 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
9847 if (strcmp(peer
, "detail") && strcmp(peer
, peer_str
))
9850 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
9851 now
= pim_time_monotonic_sec();
9852 pim_time_uptime(timebuf
, sizeof(timebuf
),
9855 strlcpy(timebuf
, "-", sizeof(timebuf
));
9857 pim_inet4_dump("<local?>", mp
->local
, local_str
,
9859 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
9860 pim_time_timer_to_hhmmss(katimer
, sizeof(katimer
),
9862 pim_time_timer_to_hhmmss(crtimer
, sizeof(crtimer
),
9864 pim_time_timer_to_hhmmss(holdtimer
, sizeof(holdtimer
),
9868 json_row
= json_object_new_object();
9869 json_object_string_add(json_row
, "peer", peer_str
);
9870 json_object_string_add(json_row
, "local", local_str
);
9871 json_object_string_add(json_row
, "meshGroupName",
9872 mp
->mesh_group_name
);
9873 json_object_string_add(json_row
, "state", state_str
);
9874 json_object_string_add(json_row
, "upTime", timebuf
);
9875 json_object_string_add(json_row
, "keepAliveTimer",
9877 json_object_string_add(json_row
, "connRetryTimer",
9879 json_object_string_add(json_row
, "holdTimer",
9881 json_object_string_add(json_row
, "lastReset",
9883 json_object_int_add(json_row
, "connAttempts",
9885 json_object_int_add(json_row
, "establishedChanges",
9887 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
9888 json_object_int_add(json_row
, "kaSent", mp
->ka_tx_cnt
);
9889 json_object_int_add(json_row
, "kaRcvd", mp
->ka_rx_cnt
);
9890 json_object_int_add(json_row
, "saSent", mp
->sa_tx_cnt
);
9891 json_object_int_add(json_row
, "saRcvd", mp
->sa_rx_cnt
);
9892 json_object_object_add(json
, peer_str
, json_row
);
9894 vty_out(vty
, "Peer : %s\n", peer_str
);
9895 vty_out(vty
, " Local : %s\n", local_str
);
9896 vty_out(vty
, " Mesh Group : %s\n",
9897 mp
->mesh_group_name
);
9898 vty_out(vty
, " State : %s\n", state_str
);
9899 vty_out(vty
, " Uptime : %s\n", timebuf
);
9901 vty_out(vty
, " Keepalive Timer : %s\n", katimer
);
9902 vty_out(vty
, " Conn Retry Timer : %s\n", crtimer
);
9903 vty_out(vty
, " Hold Timer : %s\n", holdtimer
);
9904 vty_out(vty
, " Last Reset : %s\n",
9906 vty_out(vty
, " Conn Attempts : %d\n",
9908 vty_out(vty
, " Established Changes : %d\n",
9910 vty_out(vty
, " SA Count : %d\n",
9912 vty_out(vty
, " Statistics :\n");
9915 vty_out(vty
, " Keepalives : %10d %10d\n",
9916 mp
->ka_tx_cnt
, mp
->ka_rx_cnt
);
9917 vty_out(vty
, " SAs : %10d %10d\n",
9918 mp
->sa_tx_cnt
, mp
->sa_rx_cnt
);
9924 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9925 json
, JSON_C_TO_STRING_PRETTY
));
9926 json_object_free(json
);
9930 DEFUN (show_ip_msdp_peer_detail
,
9931 show_ip_msdp_peer_detail_cmd
,
9932 "show ip msdp [vrf NAME] peer [detail|A.B.C.D] [json]",
9937 "MSDP peer information\n"
9942 bool uj
= use_json(argc
, argv
);
9944 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
9951 if (argv_find(argv
, argc
, "detail", &idx
))
9952 arg
= argv
[idx
]->text
;
9953 else if (argv_find(argv
, argc
, "A.B.C.D", &idx
))
9954 arg
= argv
[idx
]->arg
;
9957 ip_msdp_show_peers_detail(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
9959 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
9964 DEFUN (show_ip_msdp_peer_detail_vrf_all
,
9965 show_ip_msdp_peer_detail_vrf_all_cmd
,
9966 "show ip msdp vrf all peer [detail|A.B.C.D] [json]",
9971 "MSDP peer information\n"
9977 bool uj
= use_json(argc
, argv
);
9983 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
9987 vty_out(vty
, " \"%s\": ", vrf
->name
);
9990 vty_out(vty
, "VRF: %s\n", vrf
->name
);
9991 if (argv_find(argv
, argc
, "detail", &idx
)
9992 || argv_find(argv
, argc
, "A.B.C.D", &idx
))
9993 ip_msdp_show_peers_detail(vrf
->info
, vty
,
9994 argv
[idx
]->arg
, uj
);
9996 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
9999 vty_out(vty
, "}\n");
10001 return CMD_SUCCESS
;
10004 static void ip_msdp_show_sa(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
10006 struct listnode
*sanode
;
10007 struct pim_msdp_sa
*sa
;
10008 char src_str
[INET_ADDRSTRLEN
];
10009 char grp_str
[INET_ADDRSTRLEN
];
10010 char rp_str
[INET_ADDRSTRLEN
];
10011 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
10015 json_object
*json
= NULL
;
10016 json_object
*json_group
= NULL
;
10017 json_object
*json_row
= NULL
;
10020 json
= json_object_new_object();
10023 "Source Group RP Local SPT Uptime\n");
10026 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
10027 now
= pim_time_monotonic_sec();
10028 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
10029 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
10030 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
10031 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
10032 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
10034 strlcpy(spt_str
, "yes", sizeof(spt_str
));
10036 strlcpy(spt_str
, "no", sizeof(spt_str
));
10039 strlcpy(rp_str
, "-", sizeof(rp_str
));
10040 strlcpy(spt_str
, "-", sizeof(spt_str
));
10042 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
10043 strlcpy(local_str
, "yes", sizeof(local_str
));
10045 strlcpy(local_str
, "no", sizeof(local_str
));
10048 json_object_object_get_ex(json
, grp_str
, &json_group
);
10051 json_group
= json_object_new_object();
10052 json_object_object_add(json
, grp_str
,
10056 json_row
= json_object_new_object();
10057 json_object_string_add(json_row
, "source", src_str
);
10058 json_object_string_add(json_row
, "group", grp_str
);
10059 json_object_string_add(json_row
, "rp", rp_str
);
10060 json_object_string_add(json_row
, "local", local_str
);
10061 json_object_string_add(json_row
, "sptSetup", spt_str
);
10062 json_object_string_add(json_row
, "upTime", timebuf
);
10063 json_object_object_add(json_group
, src_str
, json_row
);
10065 vty_out(vty
, "%-15s %15s %15s %5c %3c %8s\n",
10066 src_str
, grp_str
, rp_str
, local_str
[0],
10067 spt_str
[0], timebuf
);
10072 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10073 json
, JSON_C_TO_STRING_PRETTY
));
10074 json_object_free(json
);
10078 static void ip_msdp_show_sa_entry_detail(struct pim_msdp_sa
*sa
,
10079 const char *src_str
,
10080 const char *grp_str
, struct vty
*vty
,
10081 bool uj
, json_object
*json
)
10083 char rp_str
[INET_ADDRSTRLEN
];
10084 char peer_str
[INET_ADDRSTRLEN
];
10085 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
10088 char statetimer
[PIM_MSDP_TIMER_STRLEN
];
10090 json_object
*json_group
= NULL
;
10091 json_object
*json_row
= NULL
;
10093 now
= pim_time_monotonic_sec();
10094 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
10095 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
10096 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
10097 pim_inet4_dump("<peer?>", sa
->peer
, peer_str
, sizeof(peer_str
));
10099 strlcpy(spt_str
, "yes", sizeof(spt_str
));
10101 strlcpy(spt_str
, "no", sizeof(spt_str
));
10104 strlcpy(rp_str
, "-", sizeof(rp_str
));
10105 strlcpy(peer_str
, "-", sizeof(peer_str
));
10106 strlcpy(spt_str
, "-", sizeof(spt_str
));
10108 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
10109 strlcpy(local_str
, "yes", sizeof(local_str
));
10111 strlcpy(local_str
, "no", sizeof(local_str
));
10113 pim_time_timer_to_hhmmss(statetimer
, sizeof(statetimer
),
10114 sa
->sa_state_timer
);
10116 json_object_object_get_ex(json
, grp_str
, &json_group
);
10119 json_group
= json_object_new_object();
10120 json_object_object_add(json
, grp_str
, json_group
);
10123 json_row
= json_object_new_object();
10124 json_object_string_add(json_row
, "source", src_str
);
10125 json_object_string_add(json_row
, "group", grp_str
);
10126 json_object_string_add(json_row
, "rp", rp_str
);
10127 json_object_string_add(json_row
, "local", local_str
);
10128 json_object_string_add(json_row
, "sptSetup", spt_str
);
10129 json_object_string_add(json_row
, "upTime", timebuf
);
10130 json_object_string_add(json_row
, "stateTimer", statetimer
);
10131 json_object_object_add(json_group
, src_str
, json_row
);
10133 vty_out(vty
, "SA : %s\n", sa
->sg_str
);
10134 vty_out(vty
, " RP : %s\n", rp_str
);
10135 vty_out(vty
, " Peer : %s\n", peer_str
);
10136 vty_out(vty
, " Local : %s\n", local_str
);
10137 vty_out(vty
, " SPT Setup : %s\n", spt_str
);
10138 vty_out(vty
, " Uptime : %s\n", timebuf
);
10139 vty_out(vty
, " State Timer : %s\n", statetimer
);
10140 vty_out(vty
, "\n");
10144 static void ip_msdp_show_sa_detail(struct pim_instance
*pim
, struct vty
*vty
,
10147 struct listnode
*sanode
;
10148 struct pim_msdp_sa
*sa
;
10149 char src_str
[INET_ADDRSTRLEN
];
10150 char grp_str
[INET_ADDRSTRLEN
];
10151 json_object
*json
= NULL
;
10154 json
= json_object_new_object();
10157 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
10158 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
10159 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
10160 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
, uj
,
10165 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10166 json
, JSON_C_TO_STRING_PRETTY
));
10167 json_object_free(json
);
10171 DEFUN (show_ip_msdp_sa_detail
,
10172 show_ip_msdp_sa_detail_cmd
,
10173 "show ip msdp [vrf NAME] sa detail [json]",
10178 "MSDP active-source information\n"
10179 "Detailed output\n"
10182 bool uj
= use_json(argc
, argv
);
10184 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10187 return CMD_WARNING
;
10189 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
10191 return CMD_SUCCESS
;
10194 DEFUN (show_ip_msdp_sa_detail_vrf_all
,
10195 show_ip_msdp_sa_detail_vrf_all_cmd
,
10196 "show ip msdp vrf all sa detail [json]",
10201 "MSDP active-source information\n"
10202 "Detailed output\n"
10205 bool uj
= use_json(argc
, argv
);
10210 vty_out(vty
, "{ ");
10211 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
10214 vty_out(vty
, ", ");
10215 vty_out(vty
, " \"%s\": ", vrf
->name
);
10218 vty_out(vty
, "VRF: %s\n", vrf
->name
);
10219 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
10222 vty_out(vty
, "}\n");
10224 return CMD_SUCCESS
;
10227 static void ip_msdp_show_sa_addr(struct pim_instance
*pim
, struct vty
*vty
,
10228 const char *addr
, bool uj
)
10230 struct listnode
*sanode
;
10231 struct pim_msdp_sa
*sa
;
10232 char src_str
[INET_ADDRSTRLEN
];
10233 char grp_str
[INET_ADDRSTRLEN
];
10234 json_object
*json
= NULL
;
10237 json
= json_object_new_object();
10240 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
10241 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
10242 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
10243 if (!strcmp(addr
, src_str
) || !strcmp(addr
, grp_str
)) {
10244 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
10250 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10251 json
, JSON_C_TO_STRING_PRETTY
));
10252 json_object_free(json
);
10256 static void ip_msdp_show_sa_sg(struct pim_instance
*pim
, struct vty
*vty
,
10257 const char *src
, const char *grp
, bool uj
)
10259 struct listnode
*sanode
;
10260 struct pim_msdp_sa
*sa
;
10261 char src_str
[INET_ADDRSTRLEN
];
10262 char grp_str
[INET_ADDRSTRLEN
];
10263 json_object
*json
= NULL
;
10266 json
= json_object_new_object();
10269 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
10270 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
10271 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
10272 if (!strcmp(src
, src_str
) && !strcmp(grp
, grp_str
)) {
10273 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
10279 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10280 json
, JSON_C_TO_STRING_PRETTY
));
10281 json_object_free(json
);
10285 DEFUN (show_ip_msdp_sa_sg
,
10286 show_ip_msdp_sa_sg_cmd
,
10287 "show ip msdp [vrf NAME] sa [A.B.C.D [A.B.C.D]] [json]",
10292 "MSDP active-source information\n"
10293 "source or group ip\n"
10297 bool uj
= use_json(argc
, argv
);
10301 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10304 return CMD_WARNING
;
10306 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
10308 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
10312 if (src_ip
&& grp_ip
)
10313 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
10315 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
10317 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
10319 return CMD_SUCCESS
;
10322 DEFUN (show_ip_msdp_sa_sg_vrf_all
,
10323 show_ip_msdp_sa_sg_vrf_all_cmd
,
10324 "show ip msdp vrf all sa [A.B.C.D [A.B.C.D]] [json]",
10329 "MSDP active-source information\n"
10330 "source or group ip\n"
10334 bool uj
= use_json(argc
, argv
);
10339 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
10341 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
10346 vty_out(vty
, "{ ");
10347 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
10350 vty_out(vty
, ", ");
10351 vty_out(vty
, " \"%s\": ", vrf
->name
);
10354 vty_out(vty
, "VRF: %s\n", vrf
->name
);
10356 if (src_ip
&& grp_ip
)
10357 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
10359 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
10361 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
10364 vty_out(vty
, "}\n");
10366 return CMD_SUCCESS
;
10369 struct pim_sg_cache_walk_data
{
10372 json_object
*json_group
;
10373 struct in_addr addr
;
10377 static void pim_show_vxlan_sg_entry(struct pim_vxlan_sg
*vxlan_sg
,
10378 struct pim_sg_cache_walk_data
*cwd
)
10380 struct vty
*vty
= cwd
->vty
;
10381 json_object
*json
= cwd
->json
;
10382 char src_str
[INET_ADDRSTRLEN
];
10383 char grp_str
[INET_ADDRSTRLEN
];
10384 json_object
*json_row
;
10385 bool installed
= (vxlan_sg
->up
) ? true : false;
10386 const char *iif_name
= vxlan_sg
->iif
?vxlan_sg
->iif
->name
:"-";
10387 const char *oif_name
;
10389 if (pim_vxlan_is_orig_mroute(vxlan_sg
))
10390 oif_name
= vxlan_sg
->orig_oif
?vxlan_sg
->orig_oif
->name
:"";
10392 oif_name
= vxlan_sg
->term_oif
?vxlan_sg
->term_oif
->name
:"";
10394 if (cwd
->addr_match
&& (vxlan_sg
->sg
.src
.s_addr
!= cwd
->addr
.s_addr
) &&
10395 (vxlan_sg
->sg
.grp
.s_addr
!= cwd
->addr
.s_addr
)) {
10398 pim_inet4_dump("<src?>", vxlan_sg
->sg
.src
, src_str
, sizeof(src_str
));
10399 pim_inet4_dump("<grp?>", vxlan_sg
->sg
.grp
, grp_str
, sizeof(grp_str
));
10401 json_object_object_get_ex(json
, grp_str
, &cwd
->json_group
);
10403 if (!cwd
->json_group
) {
10404 cwd
->json_group
= json_object_new_object();
10405 json_object_object_add(json
, grp_str
,
10409 json_row
= json_object_new_object();
10410 json_object_string_add(json_row
, "source", src_str
);
10411 json_object_string_add(json_row
, "group", grp_str
);
10412 json_object_string_add(json_row
, "input", iif_name
);
10413 json_object_string_add(json_row
, "output", oif_name
);
10415 json_object_boolean_true_add(json_row
, "installed");
10417 json_object_boolean_false_add(json_row
, "installed");
10418 json_object_object_add(cwd
->json_group
, src_str
, json_row
);
10420 vty_out(vty
, "%-15s %-15s %-15s %-15s %-5s\n",
10421 src_str
, grp_str
, iif_name
, oif_name
,
10426 static void pim_show_vxlan_sg_hash_entry(struct hash_bucket
*backet
, void *arg
)
10428 pim_show_vxlan_sg_entry((struct pim_vxlan_sg
*)backet
->data
,
10429 (struct pim_sg_cache_walk_data
*)arg
);
10432 static void pim_show_vxlan_sg(struct pim_instance
*pim
,
10433 struct vty
*vty
, bool uj
)
10435 json_object
*json
= NULL
;
10436 struct pim_sg_cache_walk_data cwd
;
10439 json
= json_object_new_object();
10441 vty_out(vty
, "Codes: I -> installed\n");
10443 "Source Group Input Output Flags\n");
10446 memset(&cwd
, 0, sizeof(cwd
));
10449 hash_iterate(pim
->vxlan
.sg_hash
, pim_show_vxlan_sg_hash_entry
, &cwd
);
10452 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10453 json
, JSON_C_TO_STRING_PRETTY
));
10454 json_object_free(json
);
10458 static void pim_show_vxlan_sg_match_addr(struct pim_instance
*pim
,
10459 struct vty
*vty
, char *addr_str
, bool uj
)
10461 json_object
*json
= NULL
;
10462 struct pim_sg_cache_walk_data cwd
;
10465 memset(&cwd
, 0, sizeof(cwd
));
10466 result
= inet_pton(AF_INET
, addr_str
, &cwd
.addr
);
10468 vty_out(vty
, "Bad address %s: errno=%d: %s\n", addr_str
,
10469 errno
, safe_strerror(errno
));
10474 json
= json_object_new_object();
10476 vty_out(vty
, "Codes: I -> installed\n");
10478 "Source Group Input Output Flags\n");
10483 cwd
.addr_match
= true;
10484 hash_iterate(pim
->vxlan
.sg_hash
, pim_show_vxlan_sg_hash_entry
, &cwd
);
10487 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10488 json
, JSON_C_TO_STRING_PRETTY
));
10489 json_object_free(json
);
10493 static void pim_show_vxlan_sg_one(struct pim_instance
*pim
,
10494 struct vty
*vty
, char *src_str
, char *grp_str
, bool uj
)
10496 json_object
*json
= NULL
;
10497 struct prefix_sg sg
;
10499 struct pim_vxlan_sg
*vxlan_sg
;
10500 const char *iif_name
;
10502 const char *oif_name
;
10504 result
= inet_pton(AF_INET
, src_str
, &sg
.src
);
10506 vty_out(vty
, "Bad src address %s: errno=%d: %s\n", src_str
,
10507 errno
, safe_strerror(errno
));
10510 result
= inet_pton(AF_INET
, grp_str
, &sg
.grp
);
10512 vty_out(vty
, "Bad grp address %s: errno=%d: %s\n", grp_str
,
10513 errno
, safe_strerror(errno
));
10517 sg
.family
= AF_INET
;
10518 sg
.prefixlen
= IPV4_MAX_BITLEN
;
10520 json
= json_object_new_object();
10522 vxlan_sg
= pim_vxlan_sg_find(pim
, &sg
);
10524 installed
= (vxlan_sg
->up
) ? true : false;
10525 iif_name
= vxlan_sg
->iif
?vxlan_sg
->iif
->name
:"-";
10527 if (pim_vxlan_is_orig_mroute(vxlan_sg
))
10529 vxlan_sg
->orig_oif
?vxlan_sg
->orig_oif
->name
:"";
10532 vxlan_sg
->term_oif
?vxlan_sg
->term_oif
->name
:"";
10535 json_object_string_add(json
, "source", src_str
);
10536 json_object_string_add(json
, "group", grp_str
);
10537 json_object_string_add(json
, "input", iif_name
);
10538 json_object_string_add(json
, "output", oif_name
);
10540 json_object_boolean_true_add(json
, "installed");
10542 json_object_boolean_false_add(json
,
10545 vty_out(vty
, "SG : %s\n", vxlan_sg
->sg_str
);
10546 vty_out(vty
, " Input : %s\n", iif_name
);
10547 vty_out(vty
, " Output : %s\n", oif_name
);
10548 vty_out(vty
, " installed : %s\n",
10549 installed
?"yes":"no");
10554 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10555 json
, JSON_C_TO_STRING_PRETTY
));
10556 json_object_free(json
);
10560 DEFUN (show_ip_pim_vxlan_sg
,
10561 show_ip_pim_vxlan_sg_cmd
,
10562 "show ip pim [vrf NAME] vxlan-groups [A.B.C.D [A.B.C.D]] [json]",
10567 "VxLAN BUM groups\n"
10568 "source or group ip\n"
10572 bool uj
= use_json(argc
, argv
);
10576 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10579 return CMD_WARNING
;
10581 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ?
10582 argv
[idx
++]->arg
:NULL
;
10583 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
) ?
10584 argv
[idx
]->arg
:NULL
;
10586 if (src_ip
&& grp_ip
)
10587 pim_show_vxlan_sg_one(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
10589 pim_show_vxlan_sg_match_addr(vrf
->info
, vty
, src_ip
, uj
);
10591 pim_show_vxlan_sg(vrf
->info
, vty
, uj
);
10593 return CMD_SUCCESS
;
10596 static void pim_show_vxlan_sg_work(struct pim_instance
*pim
,
10597 struct vty
*vty
, bool uj
)
10599 json_object
*json
= NULL
;
10600 struct pim_sg_cache_walk_data cwd
;
10601 struct listnode
*node
;
10602 struct pim_vxlan_sg
*vxlan_sg
;
10605 json
= json_object_new_object();
10607 vty_out(vty
, "Codes: I -> installed\n");
10609 "Source Group Input Flags\n");
10612 memset(&cwd
, 0, sizeof(cwd
));
10615 for (ALL_LIST_ELEMENTS_RO(pim_vxlan_p
->work_list
, node
, vxlan_sg
))
10616 pim_show_vxlan_sg_entry(vxlan_sg
, &cwd
);
10619 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10620 json
, JSON_C_TO_STRING_PRETTY
));
10621 json_object_free(json
);
10625 DEFUN_HIDDEN (show_ip_pim_vxlan_sg_work
,
10626 show_ip_pim_vxlan_sg_work_cmd
,
10627 "show ip pim [vrf NAME] vxlan-work [json]",
10632 "VxLAN work list\n"
10635 bool uj
= use_json(argc
, argv
);
10639 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10642 return CMD_WARNING
;
10644 pim_show_vxlan_sg_work(vrf
->info
, vty
, uj
);
10646 return CMD_SUCCESS
;
10649 DEFUN_HIDDEN (no_ip_pim_mlag
,
10650 no_ip_pim_mlag_cmd
,
10657 struct in_addr addr
;
10660 pim_vxlan_mlag_update(true/*mlag_enable*/,
10661 false/*peer_state*/, MLAG_ROLE_NONE
,
10662 NULL
/*peerlink*/, &addr
);
10664 return CMD_SUCCESS
;
10667 DEFUN_HIDDEN (ip_pim_mlag
,
10669 "ip pim mlag INTERFACE role [primary|secondary] state [up|down] addr A.B.C.D",
10673 "peerlink sub interface\n"
10675 "MLAG role primary\n"
10676 "MLAG role secondary\n"
10677 "peer session state\n"
10678 "peer session state up\n"
10679 "peer session state down\n"
10681 "unique ip address\n")
10683 struct interface
*ifp
;
10684 const char *peerlink
;
10689 struct in_addr reg_addr
;
10692 peerlink
= argv
[idx
]->arg
;
10693 ifp
= if_lookup_by_name(peerlink
, VRF_DEFAULT
);
10695 vty_out(vty
, "No such interface name %s\n", peerlink
);
10696 return CMD_WARNING
;
10700 if (!strcmp(argv
[idx
]->arg
, "primary")) {
10701 role
= MLAG_ROLE_PRIMARY
;
10702 } else if (!strcmp(argv
[idx
]->arg
, "secondary")) {
10703 role
= MLAG_ROLE_SECONDARY
;
10705 vty_out(vty
, "unknown MLAG role %s\n", argv
[idx
]->arg
);
10706 return CMD_WARNING
;
10710 if (!strcmp(argv
[idx
]->arg
, "up")) {
10712 } else if (strcmp(argv
[idx
]->arg
, "down")) {
10713 peer_state
= false;
10715 vty_out(vty
, "unknown MLAG state %s\n", argv
[idx
]->arg
);
10716 return CMD_WARNING
;
10720 result
= inet_pton(AF_INET
, argv
[idx
]->arg
, ®_addr
);
10722 vty_out(vty
, "%% Bad reg address %s: errno=%d: %s\n",
10724 errno
, safe_strerror(errno
));
10725 return CMD_WARNING_CONFIG_FAILED
;
10727 pim_vxlan_mlag_update(true, peer_state
, role
, ifp
, ®_addr
);
10729 return CMD_SUCCESS
;
10732 void pim_cmd_init(void)
10734 install_node(&interface_node
,
10735 pim_interface_config_write
); /* INTERFACE_NODE */
10738 install_node(&debug_node
, pim_debug_config_write
);
10740 install_element(ENABLE_NODE
, &pim_test_sg_keepalive_cmd
);
10742 install_element(CONFIG_NODE
, &ip_pim_rp_cmd
);
10743 install_element(VRF_NODE
, &ip_pim_rp_cmd
);
10744 install_element(CONFIG_NODE
, &no_ip_pim_rp_cmd
);
10745 install_element(VRF_NODE
, &no_ip_pim_rp_cmd
);
10746 install_element(CONFIG_NODE
, &ip_pim_rp_prefix_list_cmd
);
10747 install_element(VRF_NODE
, &ip_pim_rp_prefix_list_cmd
);
10748 install_element(CONFIG_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
10749 install_element(VRF_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
10750 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
10751 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
10752 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
10753 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
10754 install_element(CONFIG_NODE
, &ip_pim_ssm_prefix_list_cmd
);
10755 install_element(VRF_NODE
, &ip_pim_ssm_prefix_list_cmd
);
10756 install_element(CONFIG_NODE
, &ip_pim_register_suppress_cmd
);
10757 install_element(VRF_NODE
, &ip_pim_register_suppress_cmd
);
10758 install_element(CONFIG_NODE
, &no_ip_pim_register_suppress_cmd
);
10759 install_element(VRF_NODE
, &no_ip_pim_register_suppress_cmd
);
10760 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
10761 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
10762 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
10763 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
10764 install_element(CONFIG_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
10765 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
10766 install_element(CONFIG_NODE
,
10767 &no_ip_pim_spt_switchover_infinity_plist_cmd
);
10768 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_plist_cmd
);
10769 install_element(CONFIG_NODE
, &ip_pim_joinprune_time_cmd
);
10770 install_element(VRF_NODE
, &ip_pim_joinprune_time_cmd
);
10771 install_element(CONFIG_NODE
, &no_ip_pim_joinprune_time_cmd
);
10772 install_element(VRF_NODE
, &no_ip_pim_joinprune_time_cmd
);
10773 install_element(CONFIG_NODE
, &ip_pim_keep_alive_cmd
);
10774 install_element(VRF_NODE
, &ip_pim_keep_alive_cmd
);
10775 install_element(CONFIG_NODE
, &ip_pim_rp_keep_alive_cmd
);
10776 install_element(VRF_NODE
, &ip_pim_rp_keep_alive_cmd
);
10777 install_element(CONFIG_NODE
, &no_ip_pim_keep_alive_cmd
);
10778 install_element(VRF_NODE
, &no_ip_pim_keep_alive_cmd
);
10779 install_element(CONFIG_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
10780 install_element(VRF_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
10781 install_element(CONFIG_NODE
, &ip_pim_packets_cmd
);
10782 install_element(VRF_NODE
, &ip_pim_packets_cmd
);
10783 install_element(CONFIG_NODE
, &no_ip_pim_packets_cmd
);
10784 install_element(VRF_NODE
, &no_ip_pim_packets_cmd
);
10785 install_element(CONFIG_NODE
, &ip_pim_v6_secondary_cmd
);
10786 install_element(VRF_NODE
, &ip_pim_v6_secondary_cmd
);
10787 install_element(CONFIG_NODE
, &no_ip_pim_v6_secondary_cmd
);
10788 install_element(VRF_NODE
, &no_ip_pim_v6_secondary_cmd
);
10789 install_element(CONFIG_NODE
, &ip_ssmpingd_cmd
);
10790 install_element(VRF_NODE
, &ip_ssmpingd_cmd
);
10791 install_element(CONFIG_NODE
, &no_ip_ssmpingd_cmd
);
10792 install_element(VRF_NODE
, &no_ip_ssmpingd_cmd
);
10793 install_element(CONFIG_NODE
, &ip_msdp_peer_cmd
);
10794 install_element(VRF_NODE
, &ip_msdp_peer_cmd
);
10795 install_element(CONFIG_NODE
, &no_ip_msdp_peer_cmd
);
10796 install_element(VRF_NODE
, &no_ip_msdp_peer_cmd
);
10797 install_element(CONFIG_NODE
, &ip_pim_ecmp_cmd
);
10798 install_element(VRF_NODE
, &ip_pim_ecmp_cmd
);
10799 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_cmd
);
10800 install_element(VRF_NODE
, &no_ip_pim_ecmp_cmd
);
10801 install_element(CONFIG_NODE
, &ip_pim_ecmp_rebalance_cmd
);
10802 install_element(VRF_NODE
, &ip_pim_ecmp_rebalance_cmd
);
10803 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
10804 install_element(VRF_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
10805 install_element(CONFIG_NODE
, &ip_pim_mlag_cmd
);
10806 install_element(CONFIG_NODE
, &no_ip_pim_mlag_cmd
);
10808 install_element(INTERFACE_NODE
, &interface_ip_igmp_cmd
);
10809 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_cmd
);
10810 install_element(INTERFACE_NODE
, &interface_ip_igmp_join_cmd
);
10811 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_join_cmd
);
10812 install_element(INTERFACE_NODE
, &interface_ip_igmp_version_cmd
);
10813 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_version_cmd
);
10814 install_element(INTERFACE_NODE
, &interface_ip_igmp_query_interval_cmd
);
10815 install_element(INTERFACE_NODE
,
10816 &interface_no_ip_igmp_query_interval_cmd
);
10817 install_element(INTERFACE_NODE
,
10818 &interface_ip_igmp_query_max_response_time_cmd
);
10819 install_element(INTERFACE_NODE
,
10820 &interface_no_ip_igmp_query_max_response_time_cmd
);
10821 install_element(INTERFACE_NODE
,
10822 &interface_ip_igmp_query_max_response_time_dsec_cmd
);
10823 install_element(INTERFACE_NODE
,
10824 &interface_no_ip_igmp_query_max_response_time_dsec_cmd
);
10825 install_element(INTERFACE_NODE
,
10826 &interface_ip_igmp_last_member_query_count_cmd
);
10827 install_element(INTERFACE_NODE
,
10828 &interface_no_ip_igmp_last_member_query_count_cmd
);
10829 install_element(INTERFACE_NODE
,
10830 &interface_ip_igmp_last_member_query_interval_cmd
);
10831 install_element(INTERFACE_NODE
,
10832 &interface_no_ip_igmp_last_member_query_interval_cmd
);
10833 install_element(INTERFACE_NODE
, &interface_ip_pim_activeactive_cmd
);
10834 install_element(INTERFACE_NODE
, &interface_ip_pim_ssm_cmd
);
10835 install_element(INTERFACE_NODE
, &interface_no_ip_pim_ssm_cmd
);
10836 install_element(INTERFACE_NODE
, &interface_ip_pim_sm_cmd
);
10837 install_element(INTERFACE_NODE
, &interface_no_ip_pim_sm_cmd
);
10838 install_element(INTERFACE_NODE
, &interface_ip_pim_cmd
);
10839 install_element(INTERFACE_NODE
, &interface_no_ip_pim_cmd
);
10840 install_element(INTERFACE_NODE
, &interface_ip_pim_drprio_cmd
);
10841 install_element(INTERFACE_NODE
, &interface_no_ip_pim_drprio_cmd
);
10842 install_element(INTERFACE_NODE
, &interface_ip_pim_hello_cmd
);
10843 install_element(INTERFACE_NODE
, &interface_no_ip_pim_hello_cmd
);
10844 install_element(INTERFACE_NODE
, &interface_ip_pim_boundary_oil_cmd
);
10845 install_element(INTERFACE_NODE
, &interface_no_ip_pim_boundary_oil_cmd
);
10846 install_element(INTERFACE_NODE
, &interface_ip_igmp_query_generate_cmd
);
10848 // Static mroutes NEB
10849 install_element(INTERFACE_NODE
, &interface_ip_mroute_cmd
);
10850 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_cmd
);
10852 install_element(VIEW_NODE
, &show_ip_igmp_interface_cmd
);
10853 install_element(VIEW_NODE
, &show_ip_igmp_interface_vrf_all_cmd
);
10854 install_element(VIEW_NODE
, &show_ip_igmp_join_cmd
);
10855 install_element(VIEW_NODE
, &show_ip_igmp_join_vrf_all_cmd
);
10856 install_element(VIEW_NODE
, &show_ip_igmp_groups_cmd
);
10857 install_element(VIEW_NODE
, &show_ip_igmp_groups_vrf_all_cmd
);
10858 install_element(VIEW_NODE
, &show_ip_igmp_groups_retransmissions_cmd
);
10859 install_element(VIEW_NODE
, &show_ip_igmp_sources_cmd
);
10860 install_element(VIEW_NODE
, &show_ip_igmp_sources_retransmissions_cmd
);
10861 install_element(VIEW_NODE
, &show_ip_igmp_statistics_cmd
);
10862 install_element(VIEW_NODE
, &show_ip_pim_assert_cmd
);
10863 install_element(VIEW_NODE
, &show_ip_pim_assert_internal_cmd
);
10864 install_element(VIEW_NODE
, &show_ip_pim_assert_metric_cmd
);
10865 install_element(VIEW_NODE
, &show_ip_pim_assert_winner_metric_cmd
);
10866 install_element(VIEW_NODE
, &show_ip_pim_interface_traffic_cmd
);
10867 install_element(VIEW_NODE
, &show_ip_pim_interface_cmd
);
10868 install_element(VIEW_NODE
, &show_ip_pim_interface_vrf_all_cmd
);
10869 install_element(VIEW_NODE
, &show_ip_pim_join_cmd
);
10870 install_element(VIEW_NODE
, &show_ip_pim_join_vrf_all_cmd
);
10871 install_element(VIEW_NODE
, &show_ip_pim_jp_agg_cmd
);
10872 install_element(VIEW_NODE
, &show_ip_pim_local_membership_cmd
);
10873 install_element(VIEW_NODE
, &show_ip_pim_mlag_summary_cmd
);
10874 install_element(VIEW_NODE
, &show_ip_pim_mlag_up_cmd
);
10875 install_element(VIEW_NODE
, &show_ip_pim_mlag_up_vrf_all_cmd
);
10876 install_element(VIEW_NODE
, &show_ip_pim_neighbor_cmd
);
10877 install_element(VIEW_NODE
, &show_ip_pim_neighbor_vrf_all_cmd
);
10878 install_element(VIEW_NODE
, &show_ip_pim_rpf_cmd
);
10879 install_element(VIEW_NODE
, &show_ip_pim_rpf_vrf_all_cmd
);
10880 install_element(VIEW_NODE
, &show_ip_pim_secondary_cmd
);
10881 install_element(VIEW_NODE
, &show_ip_pim_state_cmd
);
10882 install_element(VIEW_NODE
, &show_ip_pim_state_vrf_all_cmd
);
10883 install_element(VIEW_NODE
, &show_ip_pim_upstream_cmd
);
10884 install_element(VIEW_NODE
, &show_ip_pim_upstream_vrf_all_cmd
);
10885 install_element(VIEW_NODE
, &show_ip_pim_channel_cmd
);
10886 install_element(VIEW_NODE
, &show_ip_pim_upstream_join_desired_cmd
);
10887 install_element(VIEW_NODE
, &show_ip_pim_upstream_rpf_cmd
);
10888 install_element(VIEW_NODE
, &show_ip_pim_rp_cmd
);
10889 install_element(VIEW_NODE
, &show_ip_pim_rp_vrf_all_cmd
);
10890 install_element(VIEW_NODE
, &show_ip_pim_bsr_cmd
);
10891 install_element(VIEW_NODE
, &show_ip_multicast_cmd
);
10892 install_element(VIEW_NODE
, &show_ip_multicast_vrf_all_cmd
);
10893 install_element(VIEW_NODE
, &show_ip_mroute_cmd
);
10894 install_element(VIEW_NODE
, &show_ip_mroute_vrf_all_cmd
);
10895 install_element(VIEW_NODE
, &show_ip_mroute_count_cmd
);
10896 install_element(VIEW_NODE
, &show_ip_mroute_count_vrf_all_cmd
);
10897 install_element(VIEW_NODE
, &show_ip_mroute_summary_cmd
);
10898 install_element(VIEW_NODE
, &show_ip_mroute_summary_vrf_all_cmd
);
10899 install_element(VIEW_NODE
, &show_ip_rib_cmd
);
10900 install_element(VIEW_NODE
, &show_ip_ssmpingd_cmd
);
10901 install_element(VIEW_NODE
, &show_debugging_pim_cmd
);
10902 install_element(VIEW_NODE
, &show_ip_pim_nexthop_cmd
);
10903 install_element(VIEW_NODE
, &show_ip_pim_nexthop_lookup_cmd
);
10904 install_element(VIEW_NODE
, &show_ip_pim_bsrp_cmd
);
10905 install_element(VIEW_NODE
, &show_ip_pim_bsm_db_cmd
);
10906 install_element(VIEW_NODE
, &show_ip_pim_statistics_cmd
);
10908 install_element(ENABLE_NODE
, &clear_ip_mroute_count_cmd
);
10909 install_element(ENABLE_NODE
, &clear_ip_interfaces_cmd
);
10910 install_element(ENABLE_NODE
, &clear_ip_igmp_interfaces_cmd
);
10911 install_element(ENABLE_NODE
, &clear_ip_mroute_cmd
);
10912 install_element(ENABLE_NODE
, &clear_ip_pim_interfaces_cmd
);
10913 install_element(ENABLE_NODE
, &clear_ip_pim_interface_traffic_cmd
);
10914 install_element(ENABLE_NODE
, &clear_ip_pim_oil_cmd
);
10915 install_element(ENABLE_NODE
, &clear_ip_pim_statistics_cmd
);
10917 install_element(ENABLE_NODE
, &debug_igmp_cmd
);
10918 install_element(ENABLE_NODE
, &no_debug_igmp_cmd
);
10919 install_element(ENABLE_NODE
, &debug_igmp_events_cmd
);
10920 install_element(ENABLE_NODE
, &no_debug_igmp_events_cmd
);
10921 install_element(ENABLE_NODE
, &debug_igmp_packets_cmd
);
10922 install_element(ENABLE_NODE
, &no_debug_igmp_packets_cmd
);
10923 install_element(ENABLE_NODE
, &debug_igmp_trace_cmd
);
10924 install_element(ENABLE_NODE
, &no_debug_igmp_trace_cmd
);
10925 install_element(ENABLE_NODE
, &debug_mroute_cmd
);
10926 install_element(ENABLE_NODE
, &debug_mroute_detail_cmd
);
10927 install_element(ENABLE_NODE
, &no_debug_mroute_cmd
);
10928 install_element(ENABLE_NODE
, &no_debug_mroute_detail_cmd
);
10929 install_element(ENABLE_NODE
, &debug_pim_static_cmd
);
10930 install_element(ENABLE_NODE
, &no_debug_pim_static_cmd
);
10931 install_element(ENABLE_NODE
, &debug_pim_cmd
);
10932 install_element(ENABLE_NODE
, &no_debug_pim_cmd
);
10933 install_element(ENABLE_NODE
, &debug_pim_nht_cmd
);
10934 install_element(ENABLE_NODE
, &no_debug_pim_nht_cmd
);
10935 install_element(ENABLE_NODE
, &debug_pim_nht_rp_cmd
);
10936 install_element(ENABLE_NODE
, &no_debug_pim_nht_rp_cmd
);
10937 install_element(ENABLE_NODE
, &debug_pim_events_cmd
);
10938 install_element(ENABLE_NODE
, &no_debug_pim_events_cmd
);
10939 install_element(ENABLE_NODE
, &debug_pim_packets_cmd
);
10940 install_element(ENABLE_NODE
, &no_debug_pim_packets_cmd
);
10941 install_element(ENABLE_NODE
, &debug_pim_packetdump_send_cmd
);
10942 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_send_cmd
);
10943 install_element(ENABLE_NODE
, &debug_pim_packetdump_recv_cmd
);
10944 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_recv_cmd
);
10945 install_element(ENABLE_NODE
, &debug_pim_trace_cmd
);
10946 install_element(ENABLE_NODE
, &no_debug_pim_trace_cmd
);
10947 install_element(ENABLE_NODE
, &debug_pim_trace_detail_cmd
);
10948 install_element(ENABLE_NODE
, &no_debug_pim_trace_detail_cmd
);
10949 install_element(ENABLE_NODE
, &debug_ssmpingd_cmd
);
10950 install_element(ENABLE_NODE
, &no_debug_ssmpingd_cmd
);
10951 install_element(ENABLE_NODE
, &debug_pim_zebra_cmd
);
10952 install_element(ENABLE_NODE
, &no_debug_pim_zebra_cmd
);
10953 install_element(ENABLE_NODE
, &debug_pim_mlag_cmd
);
10954 install_element(ENABLE_NODE
, &no_debug_pim_mlag_cmd
);
10955 install_element(ENABLE_NODE
, &debug_pim_vxlan_cmd
);
10956 install_element(ENABLE_NODE
, &no_debug_pim_vxlan_cmd
);
10957 install_element(ENABLE_NODE
, &debug_msdp_cmd
);
10958 install_element(ENABLE_NODE
, &no_debug_msdp_cmd
);
10959 install_element(ENABLE_NODE
, &debug_msdp_events_cmd
);
10960 install_element(ENABLE_NODE
, &no_debug_msdp_events_cmd
);
10961 install_element(ENABLE_NODE
, &debug_msdp_packets_cmd
);
10962 install_element(ENABLE_NODE
, &no_debug_msdp_packets_cmd
);
10963 install_element(ENABLE_NODE
, &debug_mtrace_cmd
);
10964 install_element(ENABLE_NODE
, &no_debug_mtrace_cmd
);
10965 install_element(ENABLE_NODE
, &debug_bsm_cmd
);
10966 install_element(ENABLE_NODE
, &no_debug_bsm_cmd
);
10968 install_element(CONFIG_NODE
, &debug_igmp_cmd
);
10969 install_element(CONFIG_NODE
, &no_debug_igmp_cmd
);
10970 install_element(CONFIG_NODE
, &debug_igmp_events_cmd
);
10971 install_element(CONFIG_NODE
, &no_debug_igmp_events_cmd
);
10972 install_element(CONFIG_NODE
, &debug_igmp_packets_cmd
);
10973 install_element(CONFIG_NODE
, &no_debug_igmp_packets_cmd
);
10974 install_element(CONFIG_NODE
, &debug_igmp_trace_cmd
);
10975 install_element(CONFIG_NODE
, &no_debug_igmp_trace_cmd
);
10976 install_element(CONFIG_NODE
, &debug_mroute_cmd
);
10977 install_element(CONFIG_NODE
, &debug_mroute_detail_cmd
);
10978 install_element(CONFIG_NODE
, &no_debug_mroute_cmd
);
10979 install_element(CONFIG_NODE
, &no_debug_mroute_detail_cmd
);
10980 install_element(CONFIG_NODE
, &debug_pim_static_cmd
);
10981 install_element(CONFIG_NODE
, &no_debug_pim_static_cmd
);
10982 install_element(CONFIG_NODE
, &debug_pim_cmd
);
10983 install_element(CONFIG_NODE
, &no_debug_pim_cmd
);
10984 install_element(CONFIG_NODE
, &debug_pim_nht_cmd
);
10985 install_element(CONFIG_NODE
, &no_debug_pim_nht_cmd
);
10986 install_element(CONFIG_NODE
, &debug_pim_nht_rp_cmd
);
10987 install_element(CONFIG_NODE
, &no_debug_pim_nht_rp_cmd
);
10988 install_element(CONFIG_NODE
, &debug_pim_events_cmd
);
10989 install_element(CONFIG_NODE
, &no_debug_pim_events_cmd
);
10990 install_element(CONFIG_NODE
, &debug_pim_packets_cmd
);
10991 install_element(CONFIG_NODE
, &no_debug_pim_packets_cmd
);
10992 install_element(CONFIG_NODE
, &debug_pim_trace_cmd
);
10993 install_element(CONFIG_NODE
, &no_debug_pim_trace_cmd
);
10994 install_element(CONFIG_NODE
, &debug_pim_trace_detail_cmd
);
10995 install_element(CONFIG_NODE
, &no_debug_pim_trace_detail_cmd
);
10996 install_element(CONFIG_NODE
, &debug_ssmpingd_cmd
);
10997 install_element(CONFIG_NODE
, &no_debug_ssmpingd_cmd
);
10998 install_element(CONFIG_NODE
, &debug_pim_zebra_cmd
);
10999 install_element(CONFIG_NODE
, &no_debug_pim_zebra_cmd
);
11000 install_element(CONFIG_NODE
, &debug_pim_mlag_cmd
);
11001 install_element(CONFIG_NODE
, &no_debug_pim_mlag_cmd
);
11002 install_element(CONFIG_NODE
, &debug_pim_vxlan_cmd
);
11003 install_element(CONFIG_NODE
, &no_debug_pim_vxlan_cmd
);
11004 install_element(CONFIG_NODE
, &debug_msdp_cmd
);
11005 install_element(CONFIG_NODE
, &no_debug_msdp_cmd
);
11006 install_element(CONFIG_NODE
, &debug_msdp_events_cmd
);
11007 install_element(CONFIG_NODE
, &no_debug_msdp_events_cmd
);
11008 install_element(CONFIG_NODE
, &debug_msdp_packets_cmd
);
11009 install_element(CONFIG_NODE
, &no_debug_msdp_packets_cmd
);
11010 install_element(CONFIG_NODE
, &debug_mtrace_cmd
);
11011 install_element(CONFIG_NODE
, &no_debug_mtrace_cmd
);
11012 install_element(CONFIG_NODE
, &debug_bsm_cmd
);
11013 install_element(CONFIG_NODE
, &no_debug_bsm_cmd
);
11015 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_member_cmd
);
11016 install_element(VRF_NODE
, &ip_msdp_mesh_group_member_cmd
);
11017 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
11018 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
11019 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_source_cmd
);
11020 install_element(VRF_NODE
, &ip_msdp_mesh_group_source_cmd
);
11021 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
11022 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
11023 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_cmd
);
11024 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_vrf_all_cmd
);
11025 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_cmd
);
11026 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_vrf_all_cmd
);
11027 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_cmd
);
11028 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_vrf_all_cmd
);
11029 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_cmd
);
11030 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_vrf_all_cmd
);
11031 install_element(VIEW_NODE
, &show_ip_pim_ssm_range_cmd
);
11032 install_element(VIEW_NODE
, &show_ip_pim_group_type_cmd
);
11033 install_element(VIEW_NODE
, &show_ip_pim_vxlan_sg_cmd
);
11034 install_element(VIEW_NODE
, &show_ip_pim_vxlan_sg_work_cmd
);
11035 install_element(INTERFACE_NODE
, &interface_pim_use_source_cmd
);
11036 install_element(INTERFACE_NODE
, &interface_no_pim_use_source_cmd
);
11037 /* Install BSM command */
11038 install_element(INTERFACE_NODE
, &ip_pim_bsm_cmd
);
11039 install_element(INTERFACE_NODE
, &no_ip_pim_bsm_cmd
);
11040 install_element(INTERFACE_NODE
, &ip_pim_ucast_bsm_cmd
);
11041 install_element(INTERFACE_NODE
, &no_ip_pim_ucast_bsm_cmd
);
11042 /* Install BFD command */
11043 install_element(INTERFACE_NODE
, &ip_pim_bfd_cmd
);
11044 install_element(INTERFACE_NODE
, &ip_pim_bfd_param_cmd
);
11045 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_cmd
);
11047 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_param_cmd
);
11048 #endif /* !HAVE_BFDD */