3 * Copyright (C) 2008 Everton da Silva Marques
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; see the file COPYING; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
34 #include "pim_mroute.h"
36 #include "pim_iface.h"
38 #include "pim_mroute.h"
41 #include "pim_igmpv3.h"
46 #include "pim_neighbor.h"
48 #include "pim_ifchannel.h"
49 #include "pim_hello.h"
51 #include "pim_upstream.h"
53 #include "pim_macro.h"
54 #include "pim_ssmpingd.h"
55 #include "pim_zebra.h"
56 #include "pim_static.h"
58 #include "pim_zlookup.h"
63 #include "pim_vxlan.h"
68 #ifndef VTYSH_EXTRACT_PL
69 #include "pimd/pim_cmd_clippy.c"
72 static struct cmd_node interface_node
= {
73 INTERFACE_NODE
, "%s(config-if)# ", 1 /* vtysh ? yes */
76 static struct cmd_node debug_node
= {DEBUG_NODE
, "", 1};
78 static struct vrf
*pim_cmd_lookup_vrf(struct vty
*vty
, struct cmd_token
*argv
[],
79 const int argc
, int *idx
)
83 if (argv_find(argv
, argc
, "NAME", idx
))
84 vrf
= vrf_lookup_by_name(argv
[*idx
]->arg
);
86 vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
89 vty_out(vty
, "Specified VRF: %s does not exist\n",
95 static void pim_if_membership_clear(struct interface
*ifp
)
97 struct pim_interface
*pim_ifp
;
102 if (PIM_IF_TEST_PIM(pim_ifp
->options
)
103 && PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
107 pim_ifchannel_membership_clear(ifp
);
111 When PIM is disabled on interface, IGMPv3 local membership
112 information is not injected into PIM interface state.
114 The function pim_if_membership_refresh() fetches all IGMPv3 local
115 membership information into PIM. It is intented to be called
116 whenever PIM is enabled on the interface in order to collect missed
117 local membership information.
119 static void pim_if_membership_refresh(struct interface
*ifp
)
121 struct pim_interface
*pim_ifp
;
122 struct listnode
*sock_node
;
123 struct igmp_sock
*igmp
;
128 if (!PIM_IF_TEST_PIM(pim_ifp
->options
))
130 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
))
134 First clear off membership from all PIM (S,G) entries on the
138 pim_ifchannel_membership_clear(ifp
);
141 Then restore PIM (S,G) membership from all IGMPv3 (S,G) entries on
145 /* scan igmp sockets */
146 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
147 struct listnode
*grpnode
;
148 struct igmp_group
*grp
;
150 /* scan igmp groups */
151 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grpnode
,
153 struct listnode
*srcnode
;
154 struct igmp_source
*src
;
156 /* scan group sources */
157 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
,
160 if (IGMP_SOURCE_TEST_FORWARDING(
161 src
->source_flags
)) {
165 sizeof(struct prefix_sg
));
166 sg
.src
= src
->source_addr
;
167 sg
.grp
= grp
->group_addr
;
168 pim_ifchannel_local_membership_add(ifp
,
169 &sg
, false /*is_vxlan*/);
172 } /* scan group sources */
173 } /* scan igmp groups */
174 } /* scan igmp sockets */
177 Finally delete every PIM (S,G) entry lacking all state info
180 pim_ifchannel_delete_on_noinfo(ifp
);
183 static void pim_show_assert_helper(struct vty
*vty
,
184 struct pim_interface
*pim_ifp
,
185 struct pim_ifchannel
*ch
, time_t now
)
187 char ch_src_str
[INET_ADDRSTRLEN
];
188 char ch_grp_str
[INET_ADDRSTRLEN
];
189 char winner_str
[INET_ADDRSTRLEN
];
190 struct in_addr ifaddr
;
194 ifaddr
= pim_ifp
->primary_address
;
196 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
197 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
198 pim_inet4_dump("<assrt_win?>", ch
->ifassert_winner
, winner_str
,
201 pim_time_uptime(uptime
, sizeof(uptime
), now
- ch
->ifassert_creation
);
202 pim_time_timer_to_mmss(timer
, sizeof(timer
), ch
->t_ifassert_timer
);
204 vty_out(vty
, "%-16s %-15s %-15s %-15s %-6s %-15s %-8s %-5s\n",
205 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
, ch_grp_str
,
206 pim_ifchannel_ifassert_name(ch
->ifassert_state
), winner_str
,
210 static void pim_show_assert(struct pim_instance
*pim
, struct vty
*vty
)
212 struct pim_interface
*pim_ifp
;
213 struct pim_ifchannel
*ch
;
214 struct interface
*ifp
;
217 now
= pim_time_monotonic_sec();
220 "Interface Address Source Group State Winner Uptime Timer\n");
222 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
227 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
228 pim_show_assert_helper(vty
, pim_ifp
, ch
, now
);
229 } /* scan interface channels */
233 static void pim_show_assert_internal_helper(struct vty
*vty
,
234 struct pim_interface
*pim_ifp
,
235 struct pim_ifchannel
*ch
)
237 char ch_src_str
[INET_ADDRSTRLEN
];
238 char ch_grp_str
[INET_ADDRSTRLEN
];
239 struct in_addr ifaddr
;
241 ifaddr
= pim_ifp
->primary_address
;
243 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
244 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
245 vty_out(vty
, "%-16s %-15s %-15s %-15s %-3s %-3s %-3s %-4s\n",
246 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
, ch_grp_str
,
247 PIM_IF_FLAG_TEST_COULD_ASSERT(ch
->flags
) ? "yes" : "no",
248 pim_macro_ch_could_assert_eval(ch
) ? "yes" : "no",
249 PIM_IF_FLAG_TEST_ASSERT_TRACKING_DESIRED(ch
->flags
) ? "yes"
251 pim_macro_assert_tracking_desired_eval(ch
) ? "yes" : "no");
254 static void pim_show_assert_internal(struct pim_instance
*pim
, struct vty
*vty
)
256 struct pim_interface
*pim_ifp
;
257 struct pim_ifchannel
*ch
;
258 struct interface
*ifp
;
262 "ECA: Evaluate CouldAssert\n"
263 "ATD: AssertTrackingDesired\n"
264 "eATD: Evaluate AssertTrackingDesired\n\n");
267 "Interface Address Source Group CA eCA ATD eATD\n");
268 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
273 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
274 pim_show_assert_internal_helper(vty
, pim_ifp
, ch
);
275 } /* scan interface channels */
279 static void pim_show_assert_metric_helper(struct vty
*vty
,
280 struct pim_interface
*pim_ifp
,
281 struct pim_ifchannel
*ch
)
283 char ch_src_str
[INET_ADDRSTRLEN
];
284 char ch_grp_str
[INET_ADDRSTRLEN
];
285 char addr_str
[INET_ADDRSTRLEN
];
286 struct pim_assert_metric am
;
287 struct in_addr ifaddr
;
289 ifaddr
= pim_ifp
->primary_address
;
291 am
= pim_macro_spt_assert_metric(&ch
->upstream
->rpf
,
292 pim_ifp
->primary_address
);
294 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
295 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
296 pim_inet4_dump("<addr?>", am
.ip_address
, addr_str
, sizeof(addr_str
));
298 vty_out(vty
, "%-16s %-15s %-15s %-15s %-3s %4u %6u %-15s\n",
299 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
, ch_grp_str
,
300 am
.rpt_bit_flag
? "yes" : "no", am
.metric_preference
,
301 am
.route_metric
, addr_str
);
304 static void pim_show_assert_metric(struct pim_instance
*pim
, struct vty
*vty
)
306 struct pim_interface
*pim_ifp
;
307 struct pim_ifchannel
*ch
;
308 struct interface
*ifp
;
311 "Interface Address Source Group RPT Pref Metric Address \n");
313 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
318 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
319 pim_show_assert_metric_helper(vty
, pim_ifp
, ch
);
320 } /* scan interface channels */
324 static void pim_show_assert_winner_metric_helper(struct vty
*vty
,
325 struct pim_interface
*pim_ifp
,
326 struct pim_ifchannel
*ch
)
328 char ch_src_str
[INET_ADDRSTRLEN
];
329 char ch_grp_str
[INET_ADDRSTRLEN
];
330 char addr_str
[INET_ADDRSTRLEN
];
331 struct pim_assert_metric
*am
;
332 struct in_addr ifaddr
;
336 ifaddr
= pim_ifp
->primary_address
;
338 am
= &ch
->ifassert_winner_metric
;
340 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
341 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
342 pim_inet4_dump("<addr?>", am
->ip_address
, addr_str
, sizeof(addr_str
));
344 if (am
->metric_preference
== PIM_ASSERT_METRIC_PREFERENCE_MAX
)
345 snprintf(pref_str
, sizeof(pref_str
), "INFI");
347 snprintf(pref_str
, sizeof(pref_str
), "%4u",
348 am
->metric_preference
);
350 if (am
->route_metric
== PIM_ASSERT_ROUTE_METRIC_MAX
)
351 snprintf(metr_str
, sizeof(metr_str
), "INFI");
353 snprintf(metr_str
, sizeof(metr_str
), "%6u", am
->route_metric
);
355 vty_out(vty
, "%-16s %-15s %-15s %-15s %-3s %-4s %-6s %-15s\n",
356 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
, ch_grp_str
,
357 am
->rpt_bit_flag
? "yes" : "no", pref_str
, metr_str
, addr_str
);
360 static void pim_show_assert_winner_metric(struct pim_instance
*pim
,
363 struct pim_interface
*pim_ifp
;
364 struct pim_ifchannel
*ch
;
365 struct interface
*ifp
;
368 "Interface Address Source Group RPT Pref Metric Address \n");
370 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
375 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
376 pim_show_assert_winner_metric_helper(vty
, pim_ifp
, ch
);
377 } /* scan interface channels */
381 static void json_object_pim_ifp_add(struct json_object
*json
,
382 struct interface
*ifp
)
384 struct pim_interface
*pim_ifp
;
387 json_object_string_add(json
, "name", ifp
->name
);
388 json_object_string_add(json
, "state", if_is_up(ifp
) ? "up" : "down");
389 json_object_string_add(json
, "address",
390 inet_ntoa(pim_ifp
->primary_address
));
391 json_object_int_add(json
, "index", ifp
->ifindex
);
393 if (if_is_multicast(ifp
))
394 json_object_boolean_true_add(json
, "flagMulticast");
396 if (if_is_broadcast(ifp
))
397 json_object_boolean_true_add(json
, "flagBroadcast");
399 if (ifp
->flags
& IFF_ALLMULTI
)
400 json_object_boolean_true_add(json
, "flagAllMulticast");
402 if (ifp
->flags
& IFF_PROMISC
)
403 json_object_boolean_true_add(json
, "flagPromiscuous");
405 if (PIM_IF_IS_DELETED(ifp
))
406 json_object_boolean_true_add(json
, "flagDeleted");
408 if (pim_if_lan_delay_enabled(ifp
))
409 json_object_boolean_true_add(json
, "lanDelayEnabled");
412 static void pim_show_membership_helper(struct vty
*vty
,
413 struct pim_interface
*pim_ifp
,
414 struct pim_ifchannel
*ch
,
415 struct json_object
*json
)
417 char ch_src_str
[INET_ADDRSTRLEN
];
418 char ch_grp_str
[INET_ADDRSTRLEN
];
419 json_object
*json_iface
= NULL
;
420 json_object
*json_row
= NULL
;
422 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
423 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
425 json_object_object_get_ex(json
, ch
->interface
->name
, &json_iface
);
427 json_iface
= json_object_new_object();
428 json_object_pim_ifp_add(json_iface
, ch
->interface
);
429 json_object_object_add(json
, ch
->interface
->name
, json_iface
);
432 json_row
= json_object_new_object();
433 json_object_string_add(json_row
, "source", ch_src_str
);
434 json_object_string_add(json_row
, "group", ch_grp_str
);
435 json_object_string_add(json_row
, "localMembership",
436 ch
->local_ifmembership
== PIM_IFMEMBERSHIP_NOINFO
439 json_object_object_add(json_iface
, ch_grp_str
, json_row
);
441 static void pim_show_membership(struct pim_instance
*pim
, struct vty
*vty
,
444 struct pim_interface
*pim_ifp
;
445 struct pim_ifchannel
*ch
;
446 struct interface
*ifp
;
448 json_object
*json
= NULL
;
449 json_object
*json_tmp
= NULL
;
451 json
= json_object_new_object();
453 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
458 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
459 pim_show_membership_helper(vty
, pim_ifp
, ch
, json
);
460 } /* scan interface channels */
464 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
465 json
, JSON_C_TO_STRING_PRETTY
));
468 "Interface Address Source Group Membership\n");
471 * Example of the json data we are traversing
477 * "address":"10.1.20.1",
479 * "flagMulticast":true,
480 * "flagBroadcast":true,
481 * "lanDelayEnabled":true,
484 * "group":"226.10.10.10",
485 * "localMembership":"INCLUDE"
491 /* foreach interface */
492 json_object_object_foreach(json
, key
, val
)
495 /* Find all of the keys where the val is an object. In
497 * above the only one is 226.10.10.10
499 json_object_object_foreach(val
, if_field_key
,
502 type
= json_object_get_type(if_field_val
);
504 if (type
== json_type_object
) {
505 vty_out(vty
, "%-16s ", key
);
507 json_object_object_get_ex(
508 val
, "address", &json_tmp
);
509 vty_out(vty
, "%-15s ",
510 json_object_get_string(
513 json_object_object_get_ex(if_field_val
,
516 vty_out(vty
, "%-15s ",
517 json_object_get_string(
521 vty_out(vty
, "%-15s ", if_field_key
);
523 json_object_object_get_ex(
524 if_field_val
, "localMembership",
526 vty_out(vty
, "%-10s\n",
527 json_object_get_string(
534 json_object_free(json
);
537 static void pim_print_ifp_flags(struct vty
*vty
, struct interface
*ifp
,
540 vty_out(vty
, "Flags\n");
541 vty_out(vty
, "-----\n");
542 vty_out(vty
, "All Multicast : %s\n",
543 (ifp
->flags
& IFF_ALLMULTI
) ? "yes" : "no");
544 vty_out(vty
, "Broadcast : %s\n",
545 if_is_broadcast(ifp
) ? "yes" : "no");
546 vty_out(vty
, "Deleted : %s\n",
547 PIM_IF_IS_DELETED(ifp
) ? "yes" : "no");
548 vty_out(vty
, "Interface Index : %d\n", ifp
->ifindex
);
549 vty_out(vty
, "Multicast : %s\n",
550 if_is_multicast(ifp
) ? "yes" : "no");
551 vty_out(vty
, "Multicast Loop : %d\n", mloop
);
552 vty_out(vty
, "Promiscuous : %s\n",
553 (ifp
->flags
& IFF_PROMISC
) ? "yes" : "no");
558 static void igmp_show_interfaces(struct pim_instance
*pim
, struct vty
*vty
,
561 struct interface
*ifp
;
563 json_object
*json
= NULL
;
564 json_object
*json_row
= NULL
;
566 now
= pim_time_monotonic_sec();
569 json
= json_object_new_object();
572 "Interface State Address V Querier Query Timer Uptime\n");
574 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
575 struct pim_interface
*pim_ifp
;
576 struct listnode
*sock_node
;
577 struct igmp_sock
*igmp
;
584 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
587 char query_hhmmss
[10];
589 pim_time_uptime(uptime
, sizeof(uptime
),
590 now
- igmp
->sock_creation
);
591 pim_time_timer_to_hhmmss(query_hhmmss
,
592 sizeof(query_hhmmss
),
593 igmp
->t_igmp_query_timer
);
596 json_row
= json_object_new_object();
597 json_object_pim_ifp_add(json_row
, ifp
);
598 json_object_string_add(json_row
, "upTime",
600 json_object_int_add(json_row
, "version",
601 pim_ifp
->igmp_version
);
603 if (igmp
->t_igmp_query_timer
) {
604 json_object_boolean_true_add(json_row
,
606 json_object_string_add(json_row
,
611 json_object_object_add(json
, ifp
->name
,
614 if (igmp
->mtrace_only
) {
615 json_object_boolean_true_add(
616 json_row
, "mtraceOnly");
620 "%-16s %5s %15s %d %7s %11s %8s\n",
623 ? (igmp
->mtrace_only
? "mtrc"
626 inet_ntoa(igmp
->ifaddr
),
627 pim_ifp
->igmp_version
,
628 igmp
->t_igmp_query_timer
? "local"
630 query_hhmmss
, uptime
);
636 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
637 json
, JSON_C_TO_STRING_PRETTY
));
638 json_object_free(json
);
642 static void igmp_show_interfaces_single(struct pim_instance
*pim
,
643 struct vty
*vty
, const char *ifname
,
646 struct igmp_sock
*igmp
;
647 struct interface
*ifp
;
648 struct listnode
*sock_node
;
649 struct pim_interface
*pim_ifp
;
651 char query_hhmmss
[10];
652 char other_hhmmss
[10];
653 int found_ifname
= 0;
656 long gmi_msec
; /* Group Membership Interval */
659 long oqpi_msec
; /* Other Querier Present Interval */
664 json_object
*json
= NULL
;
665 json_object
*json_row
= NULL
;
668 json
= json_object_new_object();
670 now
= pim_time_monotonic_sec();
672 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
678 if (strcmp(ifname
, "detail") && strcmp(ifname
, ifp
->name
))
681 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
684 pim_time_uptime(uptime
, sizeof(uptime
),
685 now
- igmp
->sock_creation
);
686 pim_time_timer_to_hhmmss(query_hhmmss
,
687 sizeof(query_hhmmss
),
688 igmp
->t_igmp_query_timer
);
689 pim_time_timer_to_hhmmss(other_hhmmss
,
690 sizeof(other_hhmmss
),
691 igmp
->t_other_querier_timer
);
693 gmi_msec
= PIM_IGMP_GMI_MSEC(
694 igmp
->querier_robustness_variable
,
695 igmp
->querier_query_interval
,
696 pim_ifp
->igmp_query_max_response_time_dsec
);
699 pim_ifp
->igmp_default_query_interval
);
701 oqpi_msec
= PIM_IGMP_OQPI_MSEC(
702 igmp
->querier_robustness_variable
,
703 igmp
->querier_query_interval
,
704 pim_ifp
->igmp_query_max_response_time_dsec
);
706 lmqt_msec
= PIM_IGMP_LMQT_MSEC(
707 pim_ifp
->igmp_specific_query_max_response_time_dsec
,
708 pim_ifp
->igmp_last_member_query_count
);
712 igmp
->querier_robustness_variable
,
713 igmp
->querier_query_interval
,
714 pim_ifp
->igmp_query_max_response_time_dsec
)
717 qri_msec
= pim_ifp
->igmp_query_max_response_time_dsec
719 if (pim_ifp
->pim_sock_fd
>= 0)
720 mloop
= pim_socket_mcastloop_get(
721 pim_ifp
->pim_sock_fd
);
724 lmqc
= pim_ifp
->igmp_last_member_query_count
;
727 json_row
= json_object_new_object();
728 json_object_pim_ifp_add(json_row
, ifp
);
729 json_object_string_add(json_row
, "upTime",
731 json_object_string_add(json_row
, "querier",
732 igmp
->t_igmp_query_timer
735 json_object_int_add(json_row
, "queryStartCount",
736 igmp
->startup_query_count
);
737 json_object_string_add(json_row
,
740 json_object_string_add(json_row
,
743 json_object_int_add(json_row
, "version",
744 pim_ifp
->igmp_version
);
747 "timerGroupMembershipIntervalMsec",
749 json_object_int_add(json_row
,
750 "lastMemberQueryCount",
752 json_object_int_add(json_row
,
753 "timerLastMemberQueryMsec",
757 "timerOlderHostPresentIntervalMsec",
761 "timerOtherQuerierPresentIntervalMsec",
764 json_row
, "timerQueryInterval",
765 igmp
->querier_query_interval
);
768 "timerQueryResponseIntervalMsec",
771 json_row
, "timerRobustnessVariable",
772 igmp
->querier_robustness_variable
);
773 json_object_int_add(json_row
,
774 "timerStartupQueryInterval",
777 json_object_object_add(json
, ifp
->name
,
780 if (igmp
->mtrace_only
) {
781 json_object_boolean_true_add(
782 json_row
, "mtraceOnly");
785 vty_out(vty
, "Interface : %s\n", ifp
->name
);
786 vty_out(vty
, "State : %s\n",
788 ? (igmp
->mtrace_only
? "mtrace"
791 vty_out(vty
, "Address : %s\n",
792 inet_ntoa(pim_ifp
->primary_address
));
793 vty_out(vty
, "Uptime : %s\n", uptime
);
794 vty_out(vty
, "Version : %d\n",
795 pim_ifp
->igmp_version
);
799 vty_out(vty
, "Querier\n");
800 vty_out(vty
, "-------\n");
801 vty_out(vty
, "Querier : %s\n",
802 igmp
->t_igmp_query_timer
? "local"
804 vty_out(vty
, "Start Count : %d\n",
805 igmp
->startup_query_count
);
806 vty_out(vty
, "Query Timer : %s\n",
808 vty_out(vty
, "Other Timer : %s\n",
813 vty_out(vty
, "Timers\n");
814 vty_out(vty
, "------\n");
816 "Group Membership Interval : %lis\n",
819 "Last Member Query Count : %d\n",
822 "Last Member Query Time : %lis\n",
825 "Older Host Present Interval : %lis\n",
828 "Other Querier Present Interval : %lis\n",
831 "Query Interval : %ds\n",
832 igmp
->querier_query_interval
);
834 "Query Response Interval : %lis\n",
837 "Robustness Variable : %d\n",
838 igmp
->querier_robustness_variable
);
840 "Startup Query Interval : %ds\n",
845 pim_print_ifp_flags(vty
, ifp
, mloop
);
851 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
852 json
, JSON_C_TO_STRING_PRETTY
));
853 json_object_free(json
);
856 vty_out(vty
, "%% No such interface\n");
860 static void igmp_show_interface_join(struct pim_instance
*pim
, struct vty
*vty
)
862 struct interface
*ifp
;
865 now
= pim_time_monotonic_sec();
868 "Interface Address Source Group Socket Uptime \n");
870 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
871 struct pim_interface
*pim_ifp
;
872 struct listnode
*join_node
;
873 struct igmp_join
*ij
;
874 struct in_addr pri_addr
;
875 char pri_addr_str
[INET_ADDRSTRLEN
];
882 if (!pim_ifp
->igmp_join_list
)
885 pri_addr
= pim_find_primary_addr(ifp
);
886 pim_inet4_dump("<pri?>", pri_addr
, pri_addr_str
,
887 sizeof(pri_addr_str
));
889 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_join_list
, join_node
,
891 char group_str
[INET_ADDRSTRLEN
];
892 char source_str
[INET_ADDRSTRLEN
];
895 pim_time_uptime(uptime
, sizeof(uptime
),
896 now
- ij
->sock_creation
);
897 pim_inet4_dump("<grp?>", ij
->group_addr
, group_str
,
899 pim_inet4_dump("<src?>", ij
->source_addr
, source_str
,
902 vty_out(vty
, "%-16s %-15s %-15s %-15s %6d %8s\n",
903 ifp
->name
, pri_addr_str
, source_str
, group_str
,
904 ij
->sock_fd
, uptime
);
905 } /* for (pim_ifp->igmp_join_list) */
910 static void pim_show_interfaces_single(struct pim_instance
*pim
,
911 struct vty
*vty
, const char *ifname
,
914 struct in_addr ifaddr
;
915 struct interface
*ifp
;
916 struct listnode
*neighnode
;
917 struct pim_interface
*pim_ifp
;
918 struct pim_neighbor
*neigh
;
919 struct pim_upstream
*up
;
921 char dr_str
[INET_ADDRSTRLEN
];
924 char grp_str
[INET_ADDRSTRLEN
];
925 char hello_period
[10];
926 char hello_timer
[10];
927 char neigh_src_str
[INET_ADDRSTRLEN
];
928 char src_str
[INET_ADDRSTRLEN
];
929 char stat_uptime
[10];
932 int found_ifname
= 0;
934 json_object
*json
= NULL
;
935 json_object
*json_row
= NULL
;
936 json_object
*json_pim_neighbor
= NULL
;
937 json_object
*json_pim_neighbors
= NULL
;
938 json_object
*json_group
= NULL
;
939 json_object
*json_group_source
= NULL
;
940 json_object
*json_fhr_sources
= NULL
;
941 struct pim_secondary_addr
*sec_addr
;
942 struct listnode
*sec_node
;
944 now
= pim_time_monotonic_sec();
947 json
= json_object_new_object();
949 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
955 if (mlag
== true && pim_ifp
->activeactive
== false)
958 if (strcmp(ifname
, "detail") && strcmp(ifname
, ifp
->name
))
962 ifaddr
= pim_ifp
->primary_address
;
963 pim_inet4_dump("<dr?>", pim_ifp
->pim_dr_addr
, dr_str
,
965 pim_time_uptime_begin(dr_uptime
, sizeof(dr_uptime
), now
,
966 pim_ifp
->pim_dr_election_last
);
967 pim_time_timer_to_hhmmss(hello_timer
, sizeof(hello_timer
),
968 pim_ifp
->t_pim_hello_timer
);
969 pim_time_mmss(hello_period
, sizeof(hello_period
),
970 pim_ifp
->pim_hello_period
);
971 pim_time_uptime(stat_uptime
, sizeof(stat_uptime
),
972 now
- pim_ifp
->pim_ifstat_start
);
973 if (pim_ifp
->pim_sock_fd
>= 0)
974 mloop
= pim_socket_mcastloop_get(pim_ifp
->pim_sock_fd
);
979 char pbuf
[PREFIX2STR_BUFFER
];
980 json_row
= json_object_new_object();
981 json_object_pim_ifp_add(json_row
, ifp
);
983 if (pim_ifp
->update_source
.s_addr
!= INADDR_ANY
) {
984 json_object_string_add(
985 json_row
, "useSource",
986 inet_ntoa(pim_ifp
->update_source
));
988 if (pim_ifp
->sec_addr_list
) {
989 json_object
*sec_list
= NULL
;
991 sec_list
= json_object_new_array();
992 for (ALL_LIST_ELEMENTS_RO(
993 pim_ifp
->sec_addr_list
, sec_node
,
995 json_object_array_add(
997 json_object_new_string(
1003 json_object_object_add(json_row
,
1004 "secondaryAddressList",
1009 if (pim_ifp
->pim_neighbor_list
->count
) {
1010 json_pim_neighbors
= json_object_new_object();
1012 for (ALL_LIST_ELEMENTS_RO(
1013 pim_ifp
->pim_neighbor_list
,
1014 neighnode
, neigh
)) {
1016 json_object_new_object();
1017 pim_inet4_dump("<src?>",
1020 sizeof(neigh_src_str
));
1021 pim_time_uptime(uptime
, sizeof(uptime
),
1022 now
- neigh
->creation
);
1023 pim_time_timer_to_hhmmss(
1024 expire
, sizeof(expire
),
1025 neigh
->t_expire_timer
);
1027 json_object_string_add(
1028 json_pim_neighbor
, "address",
1030 json_object_string_add(
1031 json_pim_neighbor
, "upTime",
1033 json_object_string_add(
1034 json_pim_neighbor
, "holdtime",
1037 json_object_object_add(
1043 json_object_object_add(json_row
, "neighbors",
1044 json_pim_neighbors
);
1047 json_object_string_add(json_row
, "drAddress", dr_str
);
1048 json_object_int_add(json_row
, "drPriority",
1049 pim_ifp
->pim_dr_priority
);
1050 json_object_string_add(json_row
, "drUptime", dr_uptime
);
1051 json_object_int_add(json_row
, "drElections",
1052 pim_ifp
->pim_dr_election_count
);
1053 json_object_int_add(json_row
, "drChanges",
1054 pim_ifp
->pim_dr_election_changes
);
1057 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
1058 if (ifp
!= up
->rpf
.source_nexthop
.interface
)
1061 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
))
1064 if (!json_fhr_sources
)
1066 json_object_new_object();
1068 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
,
1070 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
,
1072 pim_time_uptime(uptime
, sizeof(uptime
),
1073 now
- up
->state_transition
);
1076 * Does this group live in json_fhr_sources?
1079 json_object_object_get_ex(json_fhr_sources
,
1080 grp_str
, &json_group
);
1083 json_group
= json_object_new_object();
1084 json_object_object_add(json_fhr_sources
,
1089 json_group_source
= json_object_new_object();
1090 json_object_string_add(json_group_source
,
1092 json_object_string_add(json_group_source
,
1094 json_object_string_add(json_group_source
,
1096 json_object_object_add(json_group
, src_str
,
1100 if (json_fhr_sources
) {
1101 json_object_object_add(json_row
,
1106 json_object_int_add(json_row
, "helloPeriod",
1107 pim_ifp
->pim_hello_period
);
1108 json_object_string_add(json_row
, "helloTimer",
1110 json_object_string_add(json_row
, "helloStatStart",
1112 json_object_int_add(json_row
, "helloReceived",
1113 pim_ifp
->pim_ifstat_hello_recv
);
1114 json_object_int_add(json_row
, "helloReceivedFailed",
1115 pim_ifp
->pim_ifstat_hello_recvfail
);
1116 json_object_int_add(json_row
, "helloSend",
1117 pim_ifp
->pim_ifstat_hello_sent
);
1118 json_object_int_add(json_row
, "hellosendFailed",
1119 pim_ifp
->pim_ifstat_hello_sendfail
);
1120 json_object_int_add(json_row
, "helloGenerationId",
1121 pim_ifp
->pim_generation_id
);
1122 json_object_int_add(json_row
, "flagMulticastLoop",
1125 json_object_int_add(
1126 json_row
, "effectivePropagationDelay",
1127 pim_if_effective_propagation_delay_msec(ifp
));
1128 json_object_int_add(
1129 json_row
, "effectiveOverrideInterval",
1130 pim_if_effective_override_interval_msec(ifp
));
1131 json_object_int_add(
1132 json_row
, "joinPruneOverrideInterval",
1133 pim_if_jp_override_interval_msec(ifp
));
1135 json_object_int_add(
1136 json_row
, "propagationDelay",
1137 pim_ifp
->pim_propagation_delay_msec
);
1138 json_object_int_add(
1139 json_row
, "propagationDelayHighest",
1140 pim_ifp
->pim_neighbors_highest_propagation_delay_msec
);
1141 json_object_int_add(
1142 json_row
, "overrideInterval",
1143 pim_ifp
->pim_override_interval_msec
);
1144 json_object_int_add(
1145 json_row
, "overrideIntervalHighest",
1146 pim_ifp
->pim_neighbors_highest_override_interval_msec
);
1147 json_object_object_add(json
, ifp
->name
, json_row
);
1150 vty_out(vty
, "Interface : %s\n", ifp
->name
);
1151 vty_out(vty
, "State : %s\n",
1152 if_is_up(ifp
) ? "up" : "down");
1153 if (pim_ifp
->update_source
.s_addr
!= INADDR_ANY
) {
1154 vty_out(vty
, "Use Source : %s\n",
1155 inet_ntoa(pim_ifp
->update_source
));
1157 if (pim_ifp
->sec_addr_list
) {
1158 char pbuf
[PREFIX2STR_BUFFER
];
1159 vty_out(vty
, "Address : %s (primary)\n",
1161 for (ALL_LIST_ELEMENTS_RO(
1162 pim_ifp
->sec_addr_list
, sec_node
,
1164 vty_out(vty
, " %s\n",
1165 prefix2str(&sec_addr
->addr
,
1166 pbuf
, sizeof(pbuf
)));
1169 vty_out(vty
, "Address : %s\n",
1177 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
,
1178 neighnode
, neigh
)) {
1181 vty_out(vty
, "PIM Neighbors\n");
1182 vty_out(vty
, "-------------\n");
1186 pim_inet4_dump("<src?>", neigh
->source_addr
,
1188 sizeof(neigh_src_str
));
1189 pim_time_uptime(uptime
, sizeof(uptime
),
1190 now
- neigh
->creation
);
1191 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
1192 neigh
->t_expire_timer
);
1194 "%-15s : up for %s, holdtime expires in %s\n",
1195 neigh_src_str
, uptime
, expire
);
1198 if (!print_header
) {
1203 vty_out(vty
, "Designated Router\n");
1204 vty_out(vty
, "-----------------\n");
1205 vty_out(vty
, "Address : %s\n", dr_str
);
1206 vty_out(vty
, "Priority : %u(%d)\n",
1207 pim_ifp
->pim_dr_priority
,
1208 pim_ifp
->pim_dr_num_nondrpri_neighbors
);
1209 vty_out(vty
, "Uptime : %s\n", dr_uptime
);
1210 vty_out(vty
, "Elections : %d\n",
1211 pim_ifp
->pim_dr_election_count
);
1212 vty_out(vty
, "Changes : %d\n",
1213 pim_ifp
->pim_dr_election_changes
);
1219 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
1220 if (!up
->rpf
.source_nexthop
.interface
)
1223 if (strcmp(ifp
->name
,
1224 up
->rpf
.source_nexthop
1229 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
))
1234 "FHR - First Hop Router\n");
1236 "----------------------\n");
1240 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
,
1242 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
,
1244 pim_time_uptime(uptime
, sizeof(uptime
),
1245 now
- up
->state_transition
);
1247 "%s : %s is a source, uptime is %s\n",
1248 grp_str
, src_str
, uptime
);
1251 if (!print_header
) {
1256 vty_out(vty
, "Hellos\n");
1257 vty_out(vty
, "------\n");
1258 vty_out(vty
, "Period : %d\n",
1259 pim_ifp
->pim_hello_period
);
1260 vty_out(vty
, "Timer : %s\n", hello_timer
);
1261 vty_out(vty
, "StatStart : %s\n", stat_uptime
);
1262 vty_out(vty
, "Receive : %d\n",
1263 pim_ifp
->pim_ifstat_hello_recv
);
1264 vty_out(vty
, "Receive Failed : %d\n",
1265 pim_ifp
->pim_ifstat_hello_recvfail
);
1266 vty_out(vty
, "Send : %d\n",
1267 pim_ifp
->pim_ifstat_hello_sent
);
1268 vty_out(vty
, "Send Failed : %d\n",
1269 pim_ifp
->pim_ifstat_hello_sendfail
);
1270 vty_out(vty
, "Generation ID : %08x\n",
1271 pim_ifp
->pim_generation_id
);
1275 pim_print_ifp_flags(vty
, ifp
, mloop
);
1277 vty_out(vty
, "Join Prune Interval\n");
1278 vty_out(vty
, "-------------------\n");
1279 vty_out(vty
, "LAN Delay : %s\n",
1280 pim_if_lan_delay_enabled(ifp
) ? "yes" : "no");
1281 vty_out(vty
, "Effective Propagation Delay : %d msec\n",
1282 pim_if_effective_propagation_delay_msec(ifp
));
1283 vty_out(vty
, "Effective Override Interval : %d msec\n",
1284 pim_if_effective_override_interval_msec(ifp
));
1285 vty_out(vty
, "Join Prune Override Interval : %d msec\n",
1286 pim_if_jp_override_interval_msec(ifp
));
1290 vty_out(vty
, "LAN Prune Delay\n");
1291 vty_out(vty
, "---------------\n");
1292 vty_out(vty
, "Propagation Delay : %d msec\n",
1293 pim_ifp
->pim_propagation_delay_msec
);
1294 vty_out(vty
, "Propagation Delay (Highest) : %d msec\n",
1295 pim_ifp
->pim_neighbors_highest_propagation_delay_msec
);
1296 vty_out(vty
, "Override Interval : %d msec\n",
1297 pim_ifp
->pim_override_interval_msec
);
1298 vty_out(vty
, "Override Interval (Highest) : %d msec\n",
1299 pim_ifp
->pim_neighbors_highest_override_interval_msec
);
1306 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1307 json
, JSON_C_TO_STRING_PRETTY
));
1308 json_object_free(json
);
1311 vty_out(vty
, "%% No such interface\n");
1315 static void igmp_show_statistics(struct pim_instance
*pim
, struct vty
*vty
,
1316 const char *ifname
, bool uj
)
1318 struct interface
*ifp
;
1319 struct igmp_stats rx_stats
;
1321 igmp_stats_init(&rx_stats
);
1323 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1324 struct pim_interface
*pim_ifp
;
1325 struct listnode
*sock_node
;
1326 struct igmp_sock
*igmp
;
1328 pim_ifp
= ifp
->info
;
1333 if (ifname
&& strcmp(ifname
, ifp
->name
))
1336 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
1338 igmp_stats_add(&rx_stats
, &igmp
->rx_stats
);
1342 json_object
*json
= NULL
;
1343 json_object
*json_row
= NULL
;
1345 json
= json_object_new_object();
1346 json_row
= json_object_new_object();
1348 json_object_string_add(json_row
, "name", ifname
? ifname
:
1350 json_object_int_add(json_row
, "queryV1", rx_stats
.query_v1
);
1351 json_object_int_add(json_row
, "queryV2", rx_stats
.query_v2
);
1352 json_object_int_add(json_row
, "queryV3", rx_stats
.query_v3
);
1353 json_object_int_add(json_row
, "leaveV3", rx_stats
.leave_v2
);
1354 json_object_int_add(json_row
, "reportV1", rx_stats
.report_v1
);
1355 json_object_int_add(json_row
, "reportV2", rx_stats
.report_v2
);
1356 json_object_int_add(json_row
, "reportV3", rx_stats
.report_v3
);
1357 json_object_int_add(json_row
, "mtraceResponse",
1358 rx_stats
.mtrace_rsp
);
1359 json_object_int_add(json_row
, "mtraceRequest",
1360 rx_stats
.mtrace_req
);
1361 json_object_int_add(json_row
, "unsupported",
1362 rx_stats
.unsupported
);
1363 json_object_object_add(json
, ifname
? ifname
: "global",
1365 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1366 json
, JSON_C_TO_STRING_PRETTY
));
1367 json_object_free(json
);
1369 vty_out(vty
, "IGMP RX statistics\n");
1370 vty_out(vty
, "Interface : %s\n",
1371 ifname
? ifname
: "global");
1372 vty_out(vty
, "V1 query : %u\n", rx_stats
.query_v1
);
1373 vty_out(vty
, "V2 query : %u\n", rx_stats
.query_v2
);
1374 vty_out(vty
, "V3 query : %u\n", rx_stats
.query_v3
);
1375 vty_out(vty
, "V2 leave : %u\n", rx_stats
.leave_v2
);
1376 vty_out(vty
, "V1 report : %u\n", rx_stats
.report_v1
);
1377 vty_out(vty
, "V2 report : %u\n", rx_stats
.report_v2
);
1378 vty_out(vty
, "V3 report : %u\n", rx_stats
.report_v3
);
1379 vty_out(vty
, "mtrace response : %u\n", rx_stats
.mtrace_rsp
);
1380 vty_out(vty
, "mtrace request : %u\n", rx_stats
.mtrace_req
);
1381 vty_out(vty
, "unsupported : %u\n", rx_stats
.unsupported
);
1385 static void pim_show_interfaces(struct pim_instance
*pim
, struct vty
*vty
,
1388 struct interface
*ifp
;
1389 struct pim_interface
*pim_ifp
;
1390 struct pim_upstream
*up
;
1393 int pim_ifchannels
= 0;
1394 json_object
*json
= NULL
;
1395 json_object
*json_row
= NULL
;
1396 json_object
*json_tmp
;
1398 json
= json_object_new_object();
1400 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1401 pim_ifp
= ifp
->info
;
1406 if (mlag
== true && pim_ifp
->activeactive
== false)
1409 pim_nbrs
= pim_ifp
->pim_neighbor_list
->count
;
1410 pim_ifchannels
= pim_if_ifchannel_count(pim_ifp
);
1413 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
)
1414 if (ifp
== up
->rpf
.source_nexthop
.interface
)
1415 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
1418 json_row
= json_object_new_object();
1419 json_object_pim_ifp_add(json_row
, ifp
);
1420 json_object_int_add(json_row
, "pimNeighbors", pim_nbrs
);
1421 json_object_int_add(json_row
, "pimIfChannels", pim_ifchannels
);
1422 json_object_int_add(json_row
, "firstHopRouterCount", fhr
);
1423 json_object_string_add(json_row
, "pimDesignatedRouter",
1424 inet_ntoa(pim_ifp
->pim_dr_addr
));
1426 if (pim_ifp
->pim_dr_addr
.s_addr
1427 == pim_ifp
->primary_address
.s_addr
)
1428 json_object_boolean_true_add(
1429 json_row
, "pimDesignatedRouterLocal");
1431 json_object_object_add(json
, ifp
->name
, json_row
);
1435 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1436 json
, JSON_C_TO_STRING_PRETTY
));
1439 "Interface State Address PIM Nbrs PIM DR FHR IfChannels\n");
1441 json_object_object_foreach(json
, key
, val
)
1443 vty_out(vty
, "%-16s ", key
);
1445 json_object_object_get_ex(val
, "state", &json_tmp
);
1446 vty_out(vty
, "%5s ", json_object_get_string(json_tmp
));
1448 json_object_object_get_ex(val
, "address", &json_tmp
);
1449 vty_out(vty
, "%15s ",
1450 json_object_get_string(json_tmp
));
1452 json_object_object_get_ex(val
, "pimNeighbors",
1454 vty_out(vty
, "%8d ", json_object_get_int(json_tmp
));
1456 if (json_object_object_get_ex(
1457 val
, "pimDesignatedRouterLocal",
1459 vty_out(vty
, "%15s ", "local");
1461 json_object_object_get_ex(
1462 val
, "pimDesignatedRouter", &json_tmp
);
1463 vty_out(vty
, "%15s ",
1464 json_object_get_string(json_tmp
));
1467 json_object_object_get_ex(val
, "firstHopRouter",
1469 vty_out(vty
, "%3d ", json_object_get_int(json_tmp
));
1471 json_object_object_get_ex(val
, "pimIfChannels",
1473 vty_out(vty
, "%9d\n", json_object_get_int(json_tmp
));
1477 json_object_free(json
);
1480 static void pim_show_interface_traffic(struct pim_instance
*pim
,
1481 struct vty
*vty
, bool uj
)
1483 struct interface
*ifp
= NULL
;
1484 struct pim_interface
*pim_ifp
= NULL
;
1485 json_object
*json
= NULL
;
1486 json_object
*json_row
= NULL
;
1489 json
= json_object_new_object();
1492 vty_out(vty
, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s%-17s\n",
1493 "Interface", " HELLO", " JOIN",
1494 " PRUNE", " REGISTER", "REGISTER-STOP",
1496 vty_out(vty
, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s%-17s\n", "",
1497 " Rx/Tx", " Rx/Tx", " Rx/Tx",
1498 " Rx/Tx", " Rx/Tx", " Rx/Tx",
1501 "---------------------------------------------------------------------------------------------------------------\n");
1504 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1505 pim_ifp
= ifp
->info
;
1510 if (pim_ifp
->pim_sock_fd
< 0)
1513 json_row
= json_object_new_object();
1514 json_object_pim_ifp_add(json_row
, ifp
);
1515 json_object_int_add(json_row
, "helloRx",
1516 pim_ifp
->pim_ifstat_hello_recv
);
1517 json_object_int_add(json_row
, "helloTx",
1518 pim_ifp
->pim_ifstat_hello_sent
);
1519 json_object_int_add(json_row
, "joinRx",
1520 pim_ifp
->pim_ifstat_join_recv
);
1521 json_object_int_add(json_row
, "joinTx",
1522 pim_ifp
->pim_ifstat_join_send
);
1523 json_object_int_add(json_row
, "pruneTx",
1524 pim_ifp
->pim_ifstat_prune_send
);
1525 json_object_int_add(json_row
, "pruneRx",
1526 pim_ifp
->pim_ifstat_prune_recv
);
1527 json_object_int_add(json_row
, "registerRx",
1528 pim_ifp
->pim_ifstat_reg_recv
);
1529 json_object_int_add(json_row
, "registerTx",
1530 pim_ifp
->pim_ifstat_reg_recv
);
1531 json_object_int_add(json_row
, "registerStopRx",
1532 pim_ifp
->pim_ifstat_reg_stop_recv
);
1533 json_object_int_add(json_row
, "registerStopTx",
1534 pim_ifp
->pim_ifstat_reg_stop_send
);
1535 json_object_int_add(json_row
, "assertRx",
1536 pim_ifp
->pim_ifstat_assert_recv
);
1537 json_object_int_add(json_row
, "assertTx",
1538 pim_ifp
->pim_ifstat_assert_send
);
1539 json_object_int_add(json_row
, "bsmRx",
1540 pim_ifp
->pim_ifstat_bsm_rx
);
1541 json_object_int_add(json_row
, "bsmTx",
1542 pim_ifp
->pim_ifstat_bsm_tx
);
1543 json_object_object_add(json
, ifp
->name
, json_row
);
1546 "%-16s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7" PRIu64
"/%-7" PRIu64
"\n",
1547 ifp
->name
, pim_ifp
->pim_ifstat_hello_recv
,
1548 pim_ifp
->pim_ifstat_hello_sent
,
1549 pim_ifp
->pim_ifstat_join_recv
,
1550 pim_ifp
->pim_ifstat_join_send
,
1551 pim_ifp
->pim_ifstat_prune_recv
,
1552 pim_ifp
->pim_ifstat_prune_send
,
1553 pim_ifp
->pim_ifstat_reg_recv
,
1554 pim_ifp
->pim_ifstat_reg_send
,
1555 pim_ifp
->pim_ifstat_reg_stop_recv
,
1556 pim_ifp
->pim_ifstat_reg_stop_send
,
1557 pim_ifp
->pim_ifstat_assert_recv
,
1558 pim_ifp
->pim_ifstat_assert_send
,
1559 pim_ifp
->pim_ifstat_bsm_rx
,
1560 pim_ifp
->pim_ifstat_bsm_tx
);
1564 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1565 json
, JSON_C_TO_STRING_PRETTY
));
1566 json_object_free(json
);
1570 static void pim_show_interface_traffic_single(struct pim_instance
*pim
,
1572 const char *ifname
, bool uj
)
1574 struct interface
*ifp
= NULL
;
1575 struct pim_interface
*pim_ifp
= NULL
;
1576 json_object
*json
= NULL
;
1577 json_object
*json_row
= NULL
;
1578 uint8_t found_ifname
= 0;
1581 json
= json_object_new_object();
1584 vty_out(vty
, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s%-17s\n",
1585 "Interface", " HELLO", " JOIN", " PRUNE",
1586 " REGISTER", " REGISTER-STOP", " ASSERT",
1588 vty_out(vty
, "%-14s%-18s%-17s%-17s%-17s%-17s%-17s%-17s\n", "",
1589 " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1590 " Rx/Tx", " Rx/Tx", " Rx/Tx");
1592 "-------------------------------------------------------------------------------------------------------------------------------\n");
1595 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1596 if (strcmp(ifname
, ifp
->name
))
1599 pim_ifp
= ifp
->info
;
1604 if (pim_ifp
->pim_sock_fd
< 0)
1609 json_row
= json_object_new_object();
1610 json_object_pim_ifp_add(json_row
, ifp
);
1611 json_object_int_add(json_row
, "helloRx",
1612 pim_ifp
->pim_ifstat_hello_recv
);
1613 json_object_int_add(json_row
, "helloTx",
1614 pim_ifp
->pim_ifstat_hello_sent
);
1615 json_object_int_add(json_row
, "joinRx",
1616 pim_ifp
->pim_ifstat_join_recv
);
1617 json_object_int_add(json_row
, "joinTx",
1618 pim_ifp
->pim_ifstat_join_send
);
1619 json_object_int_add(json_row
, "registerRx",
1620 pim_ifp
->pim_ifstat_reg_recv
);
1621 json_object_int_add(json_row
, "registerTx",
1622 pim_ifp
->pim_ifstat_reg_recv
);
1623 json_object_int_add(json_row
, "registerStopRx",
1624 pim_ifp
->pim_ifstat_reg_stop_recv
);
1625 json_object_int_add(json_row
, "registerStopTx",
1626 pim_ifp
->pim_ifstat_reg_stop_send
);
1627 json_object_int_add(json_row
, "assertRx",
1628 pim_ifp
->pim_ifstat_assert_recv
);
1629 json_object_int_add(json_row
, "assertTx",
1630 pim_ifp
->pim_ifstat_assert_send
);
1631 json_object_int_add(json_row
, "bsmRx",
1632 pim_ifp
->pim_ifstat_bsm_rx
);
1633 json_object_int_add(json_row
, "bsmTx",
1634 pim_ifp
->pim_ifstat_bsm_tx
);
1636 json_object_object_add(json
, ifp
->name
, json_row
);
1639 "%-16s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7" PRIu64
"/%-7" PRIu64
"\n",
1640 ifp
->name
, pim_ifp
->pim_ifstat_hello_recv
,
1641 pim_ifp
->pim_ifstat_hello_sent
,
1642 pim_ifp
->pim_ifstat_join_recv
,
1643 pim_ifp
->pim_ifstat_join_send
,
1644 pim_ifp
->pim_ifstat_prune_recv
,
1645 pim_ifp
->pim_ifstat_prune_send
,
1646 pim_ifp
->pim_ifstat_reg_recv
,
1647 pim_ifp
->pim_ifstat_reg_send
,
1648 pim_ifp
->pim_ifstat_reg_stop_recv
,
1649 pim_ifp
->pim_ifstat_reg_stop_send
,
1650 pim_ifp
->pim_ifstat_assert_recv
,
1651 pim_ifp
->pim_ifstat_assert_send
,
1652 pim_ifp
->pim_ifstat_bsm_rx
,
1653 pim_ifp
->pim_ifstat_bsm_tx
);
1657 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1658 json
, JSON_C_TO_STRING_PRETTY
));
1659 json_object_free(json
);
1662 vty_out(vty
, "%% No such interface\n");
1666 static void pim_show_join_helper(struct vty
*vty
, struct pim_interface
*pim_ifp
,
1667 struct pim_ifchannel
*ch
, json_object
*json
,
1668 time_t now
, bool uj
)
1670 char ch_src_str
[INET_ADDRSTRLEN
];
1671 char ch_grp_str
[INET_ADDRSTRLEN
];
1672 json_object
*json_iface
= NULL
;
1673 json_object
*json_row
= NULL
;
1674 json_object
*json_grp
= NULL
;
1675 struct in_addr ifaddr
;
1680 ifaddr
= pim_ifp
->primary_address
;
1682 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
1683 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
1685 pim_time_uptime_begin(uptime
, sizeof(uptime
), now
, ch
->ifjoin_creation
);
1686 pim_time_timer_to_mmss(expire
, sizeof(expire
),
1687 ch
->t_ifjoin_expiry_timer
);
1688 pim_time_timer_to_mmss(prune
, sizeof(prune
),
1689 ch
->t_ifjoin_prune_pending_timer
);
1692 json_object_object_get_ex(json
, ch
->interface
->name
,
1696 json_iface
= json_object_new_object();
1697 json_object_pim_ifp_add(json_iface
, ch
->interface
);
1698 json_object_object_add(json
, ch
->interface
->name
,
1702 json_row
= json_object_new_object();
1703 json_object_string_add(json_row
, "source", ch_src_str
);
1704 json_object_string_add(json_row
, "group", ch_grp_str
);
1705 json_object_string_add(json_row
, "upTime", uptime
);
1706 json_object_string_add(json_row
, "expire", expire
);
1707 json_object_string_add(json_row
, "prune", prune
);
1708 json_object_string_add(
1709 json_row
, "channelJoinName",
1710 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
, ch
->flags
));
1711 if (PIM_IF_FLAG_TEST_S_G_RPT(ch
->flags
))
1712 json_object_int_add(json_row
, "SGRpt", 1);
1713 if (PIM_IF_FLAG_TEST_PROTO_PIM(ch
->flags
))
1714 json_object_int_add(json_row
, "protocolPim", 1);
1715 if (PIM_IF_FLAG_TEST_PROTO_IGMP(ch
->flags
))
1716 json_object_int_add(json_row
, "protocolIgmp", 1);
1717 json_object_object_get_ex(json_iface
, ch_grp_str
, &json_grp
);
1719 json_grp
= json_object_new_object();
1720 json_object_object_add(json_grp
, ch_src_str
, json_row
);
1721 json_object_object_add(json_iface
, ch_grp_str
,
1724 json_object_object_add(json_grp
, ch_src_str
, json_row
);
1726 vty_out(vty
, "%-16s %-15s %-15s %-15s %-10s %8s %-6s %5s\n",
1727 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
,
1729 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
, ch
->flags
),
1730 uptime
, expire
, prune
);
1734 static void pim_show_join(struct pim_instance
*pim
, struct vty
*vty
,
1735 struct prefix_sg
*sg
, bool uj
)
1737 struct pim_interface
*pim_ifp
;
1738 struct pim_ifchannel
*ch
;
1739 struct interface
*ifp
;
1741 json_object
*json
= NULL
;
1743 now
= pim_time_monotonic_sec();
1746 json
= json_object_new_object();
1749 "Interface Address Source Group State Uptime Expire Prune\n");
1751 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1752 pim_ifp
= ifp
->info
;
1756 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
1757 if (sg
->grp
.s_addr
!= INADDR_ANY
1758 && sg
->grp
.s_addr
!= ch
->sg
.grp
.s_addr
)
1760 if (sg
->src
.s_addr
!= INADDR_ANY
1761 && sg
->src
.s_addr
!= ch
->sg
.src
.s_addr
)
1763 pim_show_join_helper(vty
, pim_ifp
, ch
, json
, now
, uj
);
1764 } /* scan interface channels */
1768 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1769 json
, JSON_C_TO_STRING_PRETTY
));
1770 json_object_free(json
);
1774 static void pim_show_neighbors_single(struct pim_instance
*pim
, struct vty
*vty
,
1775 const char *neighbor
, bool uj
)
1777 struct listnode
*neighnode
;
1778 struct interface
*ifp
;
1779 struct pim_interface
*pim_ifp
;
1780 struct pim_neighbor
*neigh
;
1782 int found_neighbor
= 0;
1783 int option_address_list
;
1784 int option_dr_priority
;
1785 int option_generation_id
;
1786 int option_holdtime
;
1787 int option_lan_prune_delay
;
1791 char neigh_src_str
[INET_ADDRSTRLEN
];
1793 json_object
*json
= NULL
;
1794 json_object
*json_ifp
= NULL
;
1795 json_object
*json_row
= NULL
;
1797 now
= pim_time_monotonic_sec();
1800 json
= json_object_new_object();
1802 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1803 pim_ifp
= ifp
->info
;
1808 if (pim_ifp
->pim_sock_fd
< 0)
1811 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
1813 pim_inet4_dump("<src?>", neigh
->source_addr
,
1814 neigh_src_str
, sizeof(neigh_src_str
));
1817 * The user can specify either the interface name or the
1819 * If this pim_ifp matches neither then skip.
1821 if (strcmp(neighbor
, "detail")
1822 && strcmp(neighbor
, ifp
->name
)
1823 && strcmp(neighbor
, neigh_src_str
))
1827 pim_time_uptime(uptime
, sizeof(uptime
),
1828 now
- neigh
->creation
);
1829 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
1830 neigh
->t_expire_timer
);
1832 option_address_list
= 0;
1833 option_dr_priority
= 0;
1834 option_generation_id
= 0;
1835 option_holdtime
= 0;
1836 option_lan_prune_delay
= 0;
1839 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1840 PIM_OPTION_MASK_ADDRESS_LIST
))
1841 option_address_list
= 1;
1843 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1844 PIM_OPTION_MASK_DR_PRIORITY
))
1845 option_dr_priority
= 1;
1847 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1848 PIM_OPTION_MASK_GENERATION_ID
))
1849 option_generation_id
= 1;
1851 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1852 PIM_OPTION_MASK_HOLDTIME
))
1853 option_holdtime
= 1;
1855 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1856 PIM_OPTION_MASK_LAN_PRUNE_DELAY
))
1857 option_lan_prune_delay
= 1;
1859 if (PIM_OPTION_IS_SET(
1860 neigh
->hello_options
,
1861 PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION
))
1866 /* Does this ifp live in json? If not create
1868 json_object_object_get_ex(json
, ifp
->name
,
1872 json_ifp
= json_object_new_object();
1873 json_object_pim_ifp_add(json_ifp
, ifp
);
1874 json_object_object_add(json
, ifp
->name
,
1878 json_row
= json_object_new_object();
1879 json_object_string_add(json_row
, "interface",
1881 json_object_string_add(json_row
, "address",
1883 json_object_string_add(json_row
, "upTime",
1885 json_object_string_add(json_row
, "holdtime",
1887 json_object_int_add(json_row
, "drPriority",
1888 neigh
->dr_priority
);
1889 json_object_int_add(json_row
, "generationId",
1890 neigh
->generation_id
);
1892 if (option_address_list
)
1893 json_object_boolean_true_add(
1895 "helloOptionAddressList");
1897 if (option_dr_priority
)
1898 json_object_boolean_true_add(
1900 "helloOptionDrPriority");
1902 if (option_generation_id
)
1903 json_object_boolean_true_add(
1905 "helloOptionGenerationId");
1907 if (option_holdtime
)
1908 json_object_boolean_true_add(
1910 "helloOptionHoldtime");
1912 if (option_lan_prune_delay
)
1913 json_object_boolean_true_add(
1915 "helloOptionLanPruneDelay");
1918 json_object_boolean_true_add(
1919 json_row
, "helloOptionTBit");
1921 json_object_object_add(json_ifp
, neigh_src_str
,
1925 vty_out(vty
, "Interface : %s\n", ifp
->name
);
1926 vty_out(vty
, "Neighbor : %s\n", neigh_src_str
);
1934 " DR Priority : %d\n",
1935 neigh
->dr_priority
);
1937 " Generation ID : %08x\n",
1938 neigh
->generation_id
);
1940 " Override Interval (msec) : %d\n",
1941 neigh
->override_interval_msec
);
1943 " Propagation Delay (msec) : %d\n",
1944 neigh
->propagation_delay_msec
);
1946 " Hello Option - Address List : %s\n",
1947 option_address_list
? "yes" : "no");
1949 " Hello Option - DR Priority : %s\n",
1950 option_dr_priority
? "yes" : "no");
1952 " Hello Option - Generation ID : %s\n",
1953 option_generation_id
? "yes" : "no");
1955 " Hello Option - Holdtime : %s\n",
1956 option_holdtime
? "yes" : "no");
1958 " Hello Option - LAN Prune Delay : %s\n",
1959 option_lan_prune_delay
? "yes" : "no");
1961 " Hello Option - T-bit : %s\n",
1962 option_t_bit
? "yes" : "no");
1963 pim_bfd_show_info(vty
, neigh
->bfd_info
,
1971 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1972 json
, JSON_C_TO_STRING_PRETTY
));
1973 json_object_free(json
);
1976 if (!found_neighbor
)
1978 "%% No such interface or neighbor\n");
1983 static void pim_show_state(struct pim_instance
*pim
, struct vty
*vty
,
1984 const char *src_or_group
, const char *group
, bool uj
)
1986 struct channel_oil
*c_oil
;
1987 json_object
*json
= NULL
;
1988 json_object
*json_group
= NULL
;
1989 json_object
*json_ifp_in
= NULL
;
1990 json_object
*json_ifp_out
= NULL
;
1991 json_object
*json_source
= NULL
;
1994 now
= pim_time_monotonic_sec();
1997 json
= json_object_new_object();
2000 "Codes: J -> Pim Join, I -> IGMP Report, S -> Source, * -> Inherited from (*,G), V -> VxLAN, M -> Muted");
2002 "\nActive Source Group RPT IIF OIL\n");
2005 frr_each (rb_pim_oil
, &pim
->channel_oil_head
, c_oil
) {
2006 char grp_str
[INET_ADDRSTRLEN
];
2007 char src_str
[INET_ADDRSTRLEN
];
2008 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
2009 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
2011 struct interface
*ifp_in
;
2016 PIM_UPSTREAM_FLAG_TEST_USE_RPT(c_oil
->up
->flags
)) ||
2017 c_oil
->oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
2022 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
2024 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
2026 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
2029 strlcpy(in_ifname
, ifp_in
->name
, sizeof(in_ifname
));
2031 strlcpy(in_ifname
, "<iif?>", sizeof(in_ifname
));
2034 if (strcmp(src_or_group
, src_str
)
2035 && strcmp(src_or_group
, grp_str
))
2038 if (group
&& strcmp(group
, grp_str
))
2044 /* Find the group, create it if it doesn't exist */
2045 json_object_object_get_ex(json
, grp_str
, &json_group
);
2048 json_group
= json_object_new_object();
2049 json_object_object_add(json
, grp_str
,
2053 /* Find the source nested under the group, create it if
2054 * it doesn't exist */
2055 json_object_object_get_ex(json_group
, src_str
,
2059 json_source
= json_object_new_object();
2060 json_object_object_add(json_group
, src_str
,
2064 /* Find the inbound interface nested under the source,
2065 * create it if it doesn't exist */
2066 json_object_object_get_ex(json_source
, in_ifname
,
2070 json_ifp_in
= json_object_new_object();
2071 json_object_object_add(json_source
, in_ifname
,
2073 json_object_int_add(json_source
, "Installed",
2076 json_object_boolean_true_add(
2077 json_source
, "isRpt");
2079 json_object_boolean_false_add(
2080 json_source
, "isRpt");
2081 json_object_int_add(json_source
, "RefCount",
2082 c_oil
->oil_ref_count
);
2083 json_object_int_add(json_source
, "OilListSize",
2085 json_object_int_add(
2086 json_source
, "OilRescan",
2087 c_oil
->oil_inherited_rescan
);
2088 json_object_int_add(json_source
, "LastUsed",
2089 c_oil
->cc
.lastused
);
2090 json_object_int_add(json_source
, "PacketCount",
2092 json_object_int_add(json_source
, "ByteCount",
2094 json_object_int_add(json_source
,
2096 c_oil
->cc
.wrong_if
);
2099 vty_out(vty
, "%-6d %-15s %-15s %-3s %-16s ",
2100 c_oil
->installed
, src_str
, grp_str
,
2101 isRpt
? "y" : "n", in_ifname
);
2104 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
2106 struct interface
*ifp_out
;
2107 char oif_uptime
[10];
2110 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
2114 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
2116 oif_uptime
, sizeof(oif_uptime
),
2117 now
- c_oil
->oif_creation
[oif_vif_index
]);
2120 strlcpy(out_ifname
, ifp_out
->name
, sizeof(out_ifname
));
2122 strlcpy(out_ifname
, "<oif?>", sizeof(out_ifname
));
2125 json_ifp_out
= json_object_new_object();
2126 json_object_string_add(json_ifp_out
, "source",
2128 json_object_string_add(json_ifp_out
, "group",
2130 json_object_string_add(json_ifp_out
,
2133 json_object_string_add(json_ifp_out
,
2134 "outboundInterface",
2136 json_object_int_add(json_ifp_out
, "installed",
2139 json_object_object_add(json_ifp_in
, out_ifname
,
2144 vty_out(vty
, "%s(%c%c%c%c%c)",
2146 (c_oil
->oif_flags
[oif_vif_index
]
2147 & PIM_OIF_FLAG_PROTO_IGMP
)
2150 (c_oil
->oif_flags
[oif_vif_index
]
2151 & PIM_OIF_FLAG_PROTO_PIM
)
2154 (c_oil
->oif_flags
[oif_vif_index
]
2155 & PIM_OIF_FLAG_PROTO_VXLAN
)
2158 (c_oil
->oif_flags
[oif_vif_index
]
2159 & PIM_OIF_FLAG_PROTO_STAR
)
2162 (c_oil
->oif_flags
[oif_vif_index
]
2163 & PIM_OIF_FLAG_MUTE
)
2167 vty_out(vty
, ", %s(%c%c%c%c%c)",
2169 (c_oil
->oif_flags
[oif_vif_index
]
2170 & PIM_OIF_FLAG_PROTO_IGMP
)
2173 (c_oil
->oif_flags
[oif_vif_index
]
2174 & PIM_OIF_FLAG_PROTO_PIM
)
2177 (c_oil
->oif_flags
[oif_vif_index
]
2178 & PIM_OIF_FLAG_PROTO_VXLAN
)
2181 (c_oil
->oif_flags
[oif_vif_index
]
2182 & PIM_OIF_FLAG_PROTO_STAR
)
2185 (c_oil
->oif_flags
[oif_vif_index
]
2186 & PIM_OIF_FLAG_MUTE
)
2198 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2199 json
, JSON_C_TO_STRING_PRETTY
));
2200 json_object_free(json
);
2206 static void pim_show_neighbors(struct pim_instance
*pim
, struct vty
*vty
,
2209 struct listnode
*neighnode
;
2210 struct interface
*ifp
;
2211 struct pim_interface
*pim_ifp
;
2212 struct pim_neighbor
*neigh
;
2216 char neigh_src_str
[INET_ADDRSTRLEN
];
2217 json_object
*json
= NULL
;
2218 json_object
*json_ifp_rows
= NULL
;
2219 json_object
*json_row
= NULL
;
2221 now
= pim_time_monotonic_sec();
2224 json
= json_object_new_object();
2227 "Interface Neighbor Uptime Holdtime DR Pri\n");
2230 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2231 pim_ifp
= ifp
->info
;
2236 if (pim_ifp
->pim_sock_fd
< 0)
2240 json_ifp_rows
= json_object_new_object();
2242 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
2244 pim_inet4_dump("<src?>", neigh
->source_addr
,
2245 neigh_src_str
, sizeof(neigh_src_str
));
2246 pim_time_uptime(uptime
, sizeof(uptime
),
2247 now
- neigh
->creation
);
2248 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
2249 neigh
->t_expire_timer
);
2252 json_row
= json_object_new_object();
2253 json_object_string_add(json_row
, "interface",
2255 json_object_string_add(json_row
, "neighbor",
2257 json_object_string_add(json_row
, "upTime",
2259 json_object_string_add(json_row
, "holdTime",
2261 json_object_int_add(json_row
, "holdTimeMax",
2263 json_object_int_add(json_row
, "drPriority",
2264 neigh
->dr_priority
);
2265 json_object_object_add(json_ifp_rows
,
2266 neigh_src_str
, json_row
);
2269 vty_out(vty
, "%-16s %15s %8s %8s %6d\n",
2270 ifp
->name
, neigh_src_str
, uptime
,
2271 expire
, neigh
->dr_priority
);
2276 json_object_object_add(json
, ifp
->name
, json_ifp_rows
);
2277 json_ifp_rows
= NULL
;
2282 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2283 json
, JSON_C_TO_STRING_PRETTY
));
2284 json_object_free(json
);
2288 static void pim_show_neighbors_secondary(struct pim_instance
*pim
,
2291 struct interface
*ifp
;
2294 "Interface Address Neighbor Secondary \n");
2296 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2297 struct pim_interface
*pim_ifp
;
2298 struct in_addr ifaddr
;
2299 struct listnode
*neighnode
;
2300 struct pim_neighbor
*neigh
;
2302 pim_ifp
= ifp
->info
;
2307 if (pim_ifp
->pim_sock_fd
< 0)
2310 ifaddr
= pim_ifp
->primary_address
;
2312 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
2314 char neigh_src_str
[INET_ADDRSTRLEN
];
2315 struct listnode
*prefix_node
;
2318 if (!neigh
->prefix_list
)
2321 pim_inet4_dump("<src?>", neigh
->source_addr
,
2322 neigh_src_str
, sizeof(neigh_src_str
));
2324 for (ALL_LIST_ELEMENTS_RO(neigh
->prefix_list
,
2326 char neigh_sec_str
[PREFIX2STR_BUFFER
];
2328 prefix2str(p
, neigh_sec_str
,
2329 sizeof(neigh_sec_str
));
2331 vty_out(vty
, "%-16s %-15s %-15s %-15s\n",
2332 ifp
->name
, inet_ntoa(ifaddr
),
2333 neigh_src_str
, neigh_sec_str
);
2339 static void json_object_pim_upstream_add(json_object
*json
,
2340 struct pim_upstream
*up
)
2342 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED
)
2343 json_object_boolean_true_add(json
, "drJoinDesired");
2345 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED
)
2346 json_object_boolean_true_add(json
, "drJoinDesiredUpdated");
2348 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
2349 json_object_boolean_true_add(json
, "firstHopRouter");
2351 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_IGMP
)
2352 json_object_boolean_true_add(json
, "sourceIgmp");
2354 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_PIM
)
2355 json_object_boolean_true_add(json
, "sourcePim");
2357 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_STREAM
)
2358 json_object_boolean_true_add(json
, "sourceStream");
2360 /* XXX: need to print ths flag in the plain text display as well */
2361 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_MSDP
)
2362 json_object_boolean_true_add(json
, "sourceMsdp");
2364 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SEND_SG_RPT_PRUNE
)
2365 json_object_boolean_true_add(json
, "sendSGRptPrune");
2367 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_LHR
)
2368 json_object_boolean_true_add(json
, "lastHopRouter");
2370 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DISABLE_KAT_EXPIRY
)
2371 json_object_boolean_true_add(json
, "disableKATExpiry");
2373 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_STATIC_IIF
)
2374 json_object_boolean_true_add(json
, "staticIncomingInterface");
2376 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_ALLOW_IIF_IN_OIL
)
2377 json_object_boolean_true_add(json
,
2378 "allowIncomingInterfaceinOil");
2380 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_NO_PIMREG_DATA
)
2381 json_object_boolean_true_add(json
, "noPimRegistrationData");
2383 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FORCE_PIMREG
)
2384 json_object_boolean_true_add(json
, "forcePimRegistration");
2386 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_ORIG
)
2387 json_object_boolean_true_add(json
, "sourceVxlanOrigination");
2389 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_TERM
)
2390 json_object_boolean_true_add(json
, "sourceVxlanTermination");
2392 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_VXLAN
)
2393 json_object_boolean_true_add(json
, "mlagVxlan");
2395 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_NON_DF
)
2396 json_object_boolean_true_add(json
,
2397 "mlagNonDesignatedForwarder");
2401 pim_upstream_state2brief_str(enum pim_upstream_state join_state
,
2402 char *state_str
, size_t state_str_len
)
2404 switch (join_state
) {
2405 case PIM_UPSTREAM_NOTJOINED
:
2406 strlcpy(state_str
, "NotJ", state_str_len
);
2408 case PIM_UPSTREAM_JOINED
:
2409 strlcpy(state_str
, "J", state_str_len
);
2412 strlcpy(state_str
, "Unk", state_str_len
);
2417 static const char *pim_reg_state2brief_str(enum pim_reg_state reg_state
,
2418 char *state_str
, size_t state_str_len
)
2420 switch (reg_state
) {
2421 case PIM_REG_NOINFO
:
2422 strlcpy(state_str
, "RegNI", state_str_len
);
2425 strlcpy(state_str
, "RegJ", state_str_len
);
2427 case PIM_REG_JOIN_PENDING
:
2429 strlcpy(state_str
, "RegP", state_str_len
);
2432 strlcpy(state_str
, "Unk", state_str_len
);
2437 static void pim_show_upstream(struct pim_instance
*pim
, struct vty
*vty
,
2438 struct prefix_sg
*sg
, bool uj
)
2440 struct pim_upstream
*up
;
2442 json_object
*json
= NULL
;
2443 json_object
*json_group
= NULL
;
2444 json_object
*json_row
= NULL
;
2446 now
= pim_time_monotonic_sec();
2449 json
= json_object_new_object();
2452 "Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt\n");
2454 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
2455 char src_str
[INET_ADDRSTRLEN
];
2456 char grp_str
[INET_ADDRSTRLEN
];
2458 char join_timer
[10];
2461 char msdp_reg_timer
[10];
2462 char state_str
[PIM_REG_STATE_STR_LEN
];
2464 if (sg
->grp
.s_addr
!= INADDR_ANY
2465 && sg
->grp
.s_addr
!= up
->sg
.grp
.s_addr
)
2467 if (sg
->src
.s_addr
!= INADDR_ANY
2468 && sg
->src
.s_addr
!= up
->sg
.src
.s_addr
)
2471 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2472 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2473 pim_time_uptime(uptime
, sizeof(uptime
),
2474 now
- up
->state_transition
);
2475 pim_time_timer_to_hhmmss(join_timer
, sizeof(join_timer
),
2479 * If the upstream is not dummy and it has a J/P timer for the
2480 * neighbor display that
2482 if (!up
->t_join_timer
&& up
->rpf
.source_nexthop
.interface
) {
2483 struct pim_neighbor
*nbr
;
2485 nbr
= pim_neighbor_find(
2486 up
->rpf
.source_nexthop
.interface
,
2487 up
->rpf
.rpf_addr
.u
.prefix4
);
2489 pim_time_timer_to_hhmmss(join_timer
,
2494 pim_time_timer_to_hhmmss(rs_timer
, sizeof(rs_timer
),
2496 pim_time_timer_to_hhmmss(ka_timer
, sizeof(ka_timer
),
2498 pim_time_timer_to_hhmmss(msdp_reg_timer
, sizeof(msdp_reg_timer
),
2499 up
->t_msdp_reg_timer
);
2501 pim_upstream_state2brief_str(up
->join_state
, state_str
, sizeof(state_str
));
2502 if (up
->reg_state
!= PIM_REG_NOINFO
) {
2503 char tmp_str
[PIM_REG_STATE_STR_LEN
];
2505 sprintf(state_str
+ strlen(state_str
), ",%s",
2506 pim_reg_state2brief_str(up
->reg_state
, tmp_str
,
2511 json_object_object_get_ex(json
, grp_str
, &json_group
);
2514 json_group
= json_object_new_object();
2515 json_object_object_add(json
, grp_str
,
2519 json_row
= json_object_new_object();
2520 json_object_pim_upstream_add(json_row
, up
);
2521 json_object_string_add(
2522 json_row
, "inboundInterface",
2523 up
->rpf
.source_nexthop
.interface
2524 ? up
->rpf
.source_nexthop
.interface
->name
2528 * The RPF address we use is slightly different
2529 * based upon what we are looking up.
2530 * If we have a S, list that unless
2531 * we are the FHR, else we just put
2532 * the RP as the rpfAddress
2534 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
2535 || up
->sg
.src
.s_addr
== INADDR_ANY
) {
2536 char rpf
[PREFIX_STRLEN
];
2537 struct pim_rpf
*rpg
;
2539 rpg
= RP(pim
, up
->sg
.grp
);
2540 pim_inet4_dump("<rpf?>",
2541 rpg
->rpf_addr
.u
.prefix4
, rpf
,
2543 json_object_string_add(json_row
, "rpfAddress",
2546 json_object_string_add(json_row
, "rpfAddress",
2550 json_object_string_add(json_row
, "source", src_str
);
2551 json_object_string_add(json_row
, "group", grp_str
);
2552 json_object_string_add(json_row
, "state", state_str
);
2553 json_object_string_add(
2554 json_row
, "joinState",
2555 pim_upstream_state2str(up
->join_state
));
2556 json_object_string_add(
2557 json_row
, "regState",
2558 pim_reg_state2str(up
->reg_state
, state_str
, sizeof(state_str
)));
2559 json_object_string_add(json_row
, "upTime", uptime
);
2560 json_object_string_add(json_row
, "joinTimer",
2562 json_object_string_add(json_row
, "resetTimer",
2564 json_object_string_add(json_row
, "keepaliveTimer",
2566 json_object_string_add(json_row
, "msdpRegTimer",
2568 json_object_int_add(json_row
, "refCount",
2570 json_object_int_add(json_row
, "sptBit", up
->sptbit
);
2571 json_object_object_add(json_group
, src_str
, json_row
);
2574 "%-16s%-15s %-15s %-11s %-8s %-9s %-9s %-9s %6d\n",
2575 up
->rpf
.source_nexthop
.interface
2576 ? up
->rpf
.source_nexthop
.interface
->name
2578 src_str
, grp_str
, state_str
, uptime
, join_timer
,
2579 rs_timer
, ka_timer
, up
->ref_count
);
2584 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2585 json
, JSON_C_TO_STRING_PRETTY
));
2586 json_object_free(json
);
2590 static void pim_show_channel_helper(struct pim_instance
*pim
,
2592 struct pim_interface
*pim_ifp
,
2593 struct pim_ifchannel
*ch
,
2594 json_object
*json
, bool uj
)
2596 struct pim_upstream
*up
= ch
->upstream
;
2597 json_object
*json_group
= NULL
;
2598 char src_str
[INET_ADDRSTRLEN
];
2599 char grp_str
[INET_ADDRSTRLEN
];
2600 json_object
*json_row
= NULL
;
2602 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2603 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2606 json_object_object_get_ex(json
, grp_str
, &json_group
);
2609 json_group
= json_object_new_object();
2610 json_object_object_add(json
, grp_str
, json_group
);
2613 json_row
= json_object_new_object();
2614 json_object_pim_upstream_add(json_row
, up
);
2615 json_object_string_add(json_row
, "interface",
2616 ch
->interface
->name
);
2617 json_object_string_add(json_row
, "source", src_str
);
2618 json_object_string_add(json_row
, "group", grp_str
);
2620 if (pim_macro_ch_lost_assert(ch
))
2621 json_object_boolean_true_add(json_row
, "lostAssert");
2623 if (pim_macro_chisin_joins(ch
))
2624 json_object_boolean_true_add(json_row
, "joins");
2626 if (pim_macro_chisin_pim_include(ch
))
2627 json_object_boolean_true_add(json_row
, "pimInclude");
2629 if (pim_upstream_evaluate_join_desired(pim
, up
))
2630 json_object_boolean_true_add(json_row
,
2631 "evaluateJoinDesired");
2633 json_object_object_add(json_group
, src_str
, json_row
);
2636 vty_out(vty
, "%-16s %-15s %-15s %-10s %-5s %-10s %-11s %-6s\n",
2637 ch
->interface
->name
, src_str
, grp_str
,
2638 pim_macro_ch_lost_assert(ch
) ? "yes" : "no",
2639 pim_macro_chisin_joins(ch
) ? "yes" : "no",
2640 pim_macro_chisin_pim_include(ch
) ? "yes" : "no",
2641 PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(up
->flags
)
2644 pim_upstream_evaluate_join_desired(pim
, up
) ? "yes"
2649 static void pim_show_channel(struct pim_instance
*pim
, struct vty
*vty
,
2652 struct pim_interface
*pim_ifp
;
2653 struct pim_ifchannel
*ch
;
2654 struct interface
*ifp
;
2656 json_object
*json
= NULL
;
2659 json
= json_object_new_object();
2662 "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD\n");
2664 /* scan per-interface (S,G) state */
2665 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2666 pim_ifp
= ifp
->info
;
2671 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
2672 /* scan all interfaces */
2673 pim_show_channel_helper(pim
, vty
, pim_ifp
, ch
,
2679 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2680 json
, JSON_C_TO_STRING_PRETTY
));
2681 json_object_free(json
);
2685 static void pim_show_join_desired_helper(struct pim_instance
*pim
,
2687 struct pim_upstream
*up
,
2688 json_object
*json
, bool uj
)
2690 json_object
*json_group
= NULL
;
2691 char src_str
[INET_ADDRSTRLEN
];
2692 char grp_str
[INET_ADDRSTRLEN
];
2693 json_object
*json_row
= NULL
;
2695 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2696 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2699 json_object_object_get_ex(json
, grp_str
, &json_group
);
2702 json_group
= json_object_new_object();
2703 json_object_object_add(json
, grp_str
, json_group
);
2706 json_row
= json_object_new_object();
2707 json_object_pim_upstream_add(json_row
, up
);
2708 json_object_string_add(json_row
, "source", src_str
);
2709 json_object_string_add(json_row
, "group", grp_str
);
2711 if (pim_upstream_evaluate_join_desired(pim
, up
))
2712 json_object_boolean_true_add(json_row
,
2713 "evaluateJoinDesired");
2715 json_object_object_add(json_group
, src_str
, json_row
);
2718 vty_out(vty
, "%-15s %-15s %-6s\n",
2720 pim_upstream_evaluate_join_desired(pim
, up
) ? "yes"
2725 static void pim_show_join_desired(struct pim_instance
*pim
, struct vty
*vty
,
2728 struct pim_upstream
*up
;
2730 json_object
*json
= NULL
;
2733 json
= json_object_new_object();
2736 "Source Group EvalJD\n");
2738 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
2739 /* scan all interfaces */
2740 pim_show_join_desired_helper(pim
, vty
, up
,
2745 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2746 json
, JSON_C_TO_STRING_PRETTY
));
2747 json_object_free(json
);
2751 static void pim_show_upstream_rpf(struct pim_instance
*pim
, struct vty
*vty
,
2754 struct pim_upstream
*up
;
2755 json_object
*json
= NULL
;
2756 json_object
*json_group
= NULL
;
2757 json_object
*json_row
= NULL
;
2760 json
= json_object_new_object();
2763 "Source Group RpfIface RibNextHop RpfAddress \n");
2765 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
2766 char src_str
[INET_ADDRSTRLEN
];
2767 char grp_str
[INET_ADDRSTRLEN
];
2768 char rpf_nexthop_str
[PREFIX_STRLEN
];
2769 char rpf_addr_str
[PREFIX_STRLEN
];
2770 struct pim_rpf
*rpf
;
2771 const char *rpf_ifname
;
2775 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2776 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2777 pim_addr_dump("<nexthop?>",
2778 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2779 rpf_nexthop_str
, sizeof(rpf_nexthop_str
));
2780 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2781 sizeof(rpf_addr_str
));
2783 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2786 json_object_object_get_ex(json
, grp_str
, &json_group
);
2789 json_group
= json_object_new_object();
2790 json_object_object_add(json
, grp_str
,
2794 json_row
= json_object_new_object();
2795 json_object_pim_upstream_add(json_row
, up
);
2796 json_object_string_add(json_row
, "source", src_str
);
2797 json_object_string_add(json_row
, "group", grp_str
);
2798 json_object_string_add(json_row
, "rpfInterface",
2800 json_object_string_add(json_row
, "ribNexthop",
2802 json_object_string_add(json_row
, "rpfAddress",
2804 json_object_object_add(json_group
, src_str
, json_row
);
2806 vty_out(vty
, "%-15s %-15s %-16s %-15s %-15s\n", src_str
,
2807 grp_str
, rpf_ifname
, rpf_nexthop_str
,
2813 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2814 json
, JSON_C_TO_STRING_PRETTY
));
2815 json_object_free(json
);
2819 static void show_rpf_refresh_stats(struct vty
*vty
, struct pim_instance
*pim
,
2820 time_t now
, json_object
*json
)
2822 char refresh_uptime
[10];
2824 pim_time_uptime_begin(refresh_uptime
, sizeof(refresh_uptime
), now
,
2825 pim
->rpf_cache_refresh_last
);
2828 json_object_int_add(json
, "rpfCacheRefreshDelayMsecs",
2829 router
->rpf_cache_refresh_delay_msec
);
2830 json_object_int_add(
2831 json
, "rpfCacheRefreshTimer",
2832 pim_time_timer_remain_msec(pim
->rpf_cache_refresher
));
2833 json_object_int_add(json
, "rpfCacheRefreshRequests",
2834 pim
->rpf_cache_refresh_requests
);
2835 json_object_int_add(json
, "rpfCacheRefreshEvents",
2836 pim
->rpf_cache_refresh_events
);
2837 json_object_string_add(json
, "rpfCacheRefreshLast",
2839 json_object_int_add(json
, "nexthopLookups",
2840 pim
->nexthop_lookups
);
2841 json_object_int_add(json
, "nexthopLookupsAvoided",
2842 pim
->nexthop_lookups_avoided
);
2845 "RPF Cache Refresh Delay: %ld msecs\n"
2846 "RPF Cache Refresh Timer: %ld msecs\n"
2847 "RPF Cache Refresh Requests: %lld\n"
2848 "RPF Cache Refresh Events: %lld\n"
2849 "RPF Cache Refresh Last: %s\n"
2850 "Nexthop Lookups: %lld\n"
2851 "Nexthop Lookups Avoided: %lld\n",
2852 router
->rpf_cache_refresh_delay_msec
,
2853 pim_time_timer_remain_msec(pim
->rpf_cache_refresher
),
2854 (long long)pim
->rpf_cache_refresh_requests
,
2855 (long long)pim
->rpf_cache_refresh_events
,
2856 refresh_uptime
, (long long)pim
->nexthop_lookups
,
2857 (long long)pim
->nexthop_lookups_avoided
);
2861 static void show_scan_oil_stats(struct pim_instance
*pim
, struct vty
*vty
,
2864 char uptime_scan_oil
[10];
2865 char uptime_mroute_add
[10];
2866 char uptime_mroute_del
[10];
2868 pim_time_uptime_begin(uptime_scan_oil
, sizeof(uptime_scan_oil
), now
,
2869 pim
->scan_oil_last
);
2870 pim_time_uptime_begin(uptime_mroute_add
, sizeof(uptime_mroute_add
), now
,
2871 pim
->mroute_add_last
);
2872 pim_time_uptime_begin(uptime_mroute_del
, sizeof(uptime_mroute_del
), now
,
2873 pim
->mroute_del_last
);
2876 "Scan OIL - Last: %s Events: %lld\n"
2877 "MFC Add - Last: %s Events: %lld\n"
2878 "MFC Del - Last: %s Events: %lld\n",
2879 uptime_scan_oil
, (long long)pim
->scan_oil_events
,
2880 uptime_mroute_add
, (long long)pim
->mroute_add_events
,
2881 uptime_mroute_del
, (long long)pim
->mroute_del_events
);
2884 static void pim_show_rpf(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
2886 struct pim_upstream
*up
;
2887 time_t now
= pim_time_monotonic_sec();
2888 json_object
*json
= NULL
;
2889 json_object
*json_group
= NULL
;
2890 json_object
*json_row
= NULL
;
2893 json
= json_object_new_object();
2894 show_rpf_refresh_stats(vty
, pim
, now
, json
);
2896 show_rpf_refresh_stats(vty
, pim
, now
, json
);
2899 "Source Group RpfIface RpfAddress RibNextHop Metric Pref\n");
2902 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
2903 char src_str
[INET_ADDRSTRLEN
];
2904 char grp_str
[INET_ADDRSTRLEN
];
2905 char rpf_addr_str
[PREFIX_STRLEN
];
2906 char rib_nexthop_str
[PREFIX_STRLEN
];
2907 const char *rpf_ifname
;
2908 struct pim_rpf
*rpf
= &up
->rpf
;
2910 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2911 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2912 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2913 sizeof(rpf_addr_str
));
2914 pim_addr_dump("<nexthop?>",
2915 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2916 rib_nexthop_str
, sizeof(rib_nexthop_str
));
2918 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2921 json_object_object_get_ex(json
, grp_str
, &json_group
);
2924 json_group
= json_object_new_object();
2925 json_object_object_add(json
, grp_str
,
2929 json_row
= json_object_new_object();
2930 json_object_string_add(json_row
, "source", src_str
);
2931 json_object_string_add(json_row
, "group", grp_str
);
2932 json_object_string_add(json_row
, "rpfInterface",
2934 json_object_string_add(json_row
, "rpfAddress",
2936 json_object_string_add(json_row
, "ribNexthop",
2938 json_object_int_add(
2939 json_row
, "routeMetric",
2940 rpf
->source_nexthop
.mrib_route_metric
);
2941 json_object_int_add(
2942 json_row
, "routePreference",
2943 rpf
->source_nexthop
.mrib_metric_preference
);
2944 json_object_object_add(json_group
, src_str
, json_row
);
2947 vty_out(vty
, "%-15s %-15s %-16s %-15s %-15s %6d %4d\n",
2948 src_str
, grp_str
, rpf_ifname
, rpf_addr_str
,
2950 rpf
->source_nexthop
.mrib_route_metric
,
2951 rpf
->source_nexthop
.mrib_metric_preference
);
2956 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2957 json
, JSON_C_TO_STRING_PRETTY
));
2958 json_object_free(json
);
2962 struct pnc_cache_walk_data
{
2964 struct pim_instance
*pim
;
2967 static int pim_print_pnc_cache_walkcb(struct hash_bucket
*bucket
, void *arg
)
2969 struct pim_nexthop_cache
*pnc
= bucket
->data
;
2970 struct pnc_cache_walk_data
*cwd
= arg
;
2971 struct vty
*vty
= cwd
->vty
;
2972 struct pim_instance
*pim
= cwd
->pim
;
2973 struct nexthop
*nh_node
= NULL
;
2974 ifindex_t first_ifindex
;
2975 struct interface
*ifp
= NULL
;
2977 for (nh_node
= pnc
->nexthop
; nh_node
; nh_node
= nh_node
->next
) {
2978 first_ifindex
= nh_node
->ifindex
;
2979 ifp
= if_lookup_by_index(first_ifindex
, pim
->vrf_id
);
2981 vty_out(vty
, "%-15s ", inet_ntoa(pnc
->rpf
.rpf_addr
.u
.prefix4
));
2982 vty_out(vty
, "%-16s ", ifp
? ifp
->name
: "NULL");
2983 vty_out(vty
, "%s ", inet_ntoa(nh_node
->gate
.ipv4
));
2989 static void pim_show_nexthop(struct pim_instance
*pim
, struct vty
*vty
)
2991 struct pnc_cache_walk_data cwd
;
2995 vty_out(vty
, "Number of registered addresses: %lu\n",
2996 pim
->rpf_hash
->count
);
2997 vty_out(vty
, "Address Interface Nexthop\n");
2998 vty_out(vty
, "---------------------------------------------\n");
3000 hash_walk(pim
->rpf_hash
, pim_print_pnc_cache_walkcb
, &cwd
);
3003 /* Display the bsm database details */
3004 static void pim_show_bsm_db(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
3006 struct listnode
*bsmnode
;
3009 struct bsm_info
*bsm
;
3010 json_object
*json
= NULL
;
3011 json_object
*json_group
= NULL
;
3012 json_object
*json_row
= NULL
;
3014 count
= pim
->global_scope
.bsm_list
->count
;
3017 json
= json_object_new_object();
3018 json_object_int_add(json
, "Number of the fragments", count
);
3020 vty_out(vty
, "Scope Zone: Global\n");
3021 vty_out(vty
, "Number of the fragments: %d\n", count
);
3025 for (ALL_LIST_ELEMENTS_RO(pim
->global_scope
.bsm_list
, bsmnode
, bsm
)) {
3026 char grp_str
[PREFIX_STRLEN
];
3027 char rp_str
[INET_ADDRSTRLEN
];
3028 char bsr_str
[INET_ADDRSTRLEN
];
3029 struct bsmmsg_grpinfo
*group
;
3030 struct bsmmsg_rpinfo
*rpaddr
;
3032 struct bsm_hdr
*hdr
;
3033 uint32_t offset
= 0;
3036 uint32_t frag_rp_cnt
= 0;
3041 /* skip pim header */
3042 buf
+= PIM_MSG_HEADER_LEN
;
3043 len
-= PIM_MSG_HEADER_LEN
;
3045 hdr
= (struct bsm_hdr
*)buf
;
3047 /* BSM starts with bsr header */
3048 buf
+= sizeof(struct bsm_hdr
);
3049 len
-= sizeof(struct bsm_hdr
);
3051 pim_inet4_dump("<BSR Address?>", hdr
->bsr_addr
.addr
, bsr_str
,
3056 json_object_string_add(json
, "BSR address", bsr_str
);
3057 json_object_int_add(json
, "BSR priority",
3059 json_object_int_add(json
, "Hashmask Length",
3061 json_object_int_add(json
, "Fragment Tag",
3062 ntohs(hdr
->frag_tag
));
3064 vty_out(vty
, "BSM Fragment : %d\n", fragment
);
3065 vty_out(vty
, "------------------\n");
3066 vty_out(vty
, "%-15s %-15s %-15s %-15s\n", "BSR-Address",
3067 "BSR-Priority", "Hashmask-len", "Fragment-Tag");
3068 vty_out(vty
, "%-15s %-15d %-15d %-15d\n", bsr_str
,
3069 hdr
->bsr_prio
, hdr
->hm_len
,
3070 ntohs(hdr
->frag_tag
));
3075 while (offset
< len
) {
3076 group
= (struct bsmmsg_grpinfo
*)buf
;
3078 if (group
->group
.family
== PIM_MSG_ADDRESS_FAMILY_IPV4
)
3079 grp
.family
= AF_INET
;
3081 grp
.prefixlen
= group
->group
.mask
;
3082 grp
.u
.prefix4
.s_addr
= group
->group
.addr
.s_addr
;
3084 prefix2str(&grp
, grp_str
, sizeof(grp_str
));
3086 buf
+= sizeof(struct bsmmsg_grpinfo
);
3087 offset
+= sizeof(struct bsmmsg_grpinfo
);
3090 json_object_object_get_ex(json
, grp_str
,
3093 json_group
= json_object_new_object();
3094 json_object_int_add(json_group
,
3097 json_object_int_add(
3098 json_group
, "Fragment Rp count",
3099 group
->frag_rp_count
);
3100 json_object_object_add(json
, grp_str
,
3104 vty_out(vty
, "Group : %s\n", grp_str
);
3105 vty_out(vty
, "-------------------\n");
3106 vty_out(vty
, "Rp Count:%d\n", group
->rp_count
);
3107 vty_out(vty
, "Fragment Rp Count : %d\n",
3108 group
->frag_rp_count
);
3111 frag_rp_cnt
= group
->frag_rp_count
;
3118 "RpAddress HoldTime Priority\n");
3120 while (frag_rp_cnt
--) {
3121 rpaddr
= (struct bsmmsg_rpinfo
*)buf
;
3123 buf
+= sizeof(struct bsmmsg_rpinfo
);
3124 offset
+= sizeof(struct bsmmsg_rpinfo
);
3126 pim_inet4_dump("<Rp addr?>",
3127 rpaddr
->rpaddr
.addr
, rp_str
,
3131 json_row
= json_object_new_object();
3132 json_object_string_add(
3133 json_row
, "Rp Address", rp_str
);
3134 json_object_int_add(
3135 json_row
, "Rp HoldTime",
3136 ntohs(rpaddr
->rp_holdtime
));
3137 json_object_int_add(json_row
,
3140 json_object_object_add(
3141 json_group
, rp_str
, json_row
);
3143 vty_out(vty
, "%-15s %-12d %d\n", rp_str
,
3144 ntohs(rpaddr
->rp_holdtime
),
3155 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3156 json
, JSON_C_TO_STRING_PRETTY
));
3157 json_object_free(json
);
3161 /*Display the group-rp mappings */
3162 static void pim_show_group_rp_mappings_info(struct pim_instance
*pim
,
3163 struct vty
*vty
, bool uj
)
3165 struct bsgrp_node
*bsgrp
;
3166 struct listnode
*rpnode
;
3167 struct bsm_rpinfo
*bsm_rp
;
3168 struct route_node
*rn
;
3169 char bsr_str
[INET_ADDRSTRLEN
];
3170 json_object
*json
= NULL
;
3171 json_object
*json_group
= NULL
;
3172 json_object
*json_row
= NULL
;
3174 if (pim
->global_scope
.current_bsr
.s_addr
== INADDR_ANY
)
3175 strlcpy(bsr_str
, "0.0.0.0", sizeof(bsr_str
));
3178 pim_inet4_dump("<bsr?>", pim
->global_scope
.current_bsr
, bsr_str
,
3182 json
= json_object_new_object();
3183 json_object_string_add(json
, "BSR Address", bsr_str
);
3185 vty_out(vty
, "BSR Address %s\n", bsr_str
);
3188 for (rn
= route_top(pim
->global_scope
.bsrp_table
); rn
;
3189 rn
= route_next(rn
)) {
3190 bsgrp
= (struct bsgrp_node
*)rn
->info
;
3195 char grp_str
[PREFIX_STRLEN
];
3197 prefix2str(&bsgrp
->group
, grp_str
, sizeof(grp_str
));
3200 json_object_object_get_ex(json
, grp_str
, &json_group
);
3202 json_group
= json_object_new_object();
3203 json_object_object_add(json
, grp_str
,
3207 vty_out(vty
, "Group Address %s\n", grp_str
);
3208 vty_out(vty
, "--------------------------\n");
3209 vty_out(vty
, "%-15s %-15s %-15s %-15s\n", "Rp Address",
3210 "priority", "Holdtime", "Hash");
3212 vty_out(vty
, "(ACTIVE)\n");
3215 if (bsgrp
->bsrp_list
) {
3216 for (ALL_LIST_ELEMENTS_RO(bsgrp
->bsrp_list
, rpnode
,
3218 char rp_str
[INET_ADDRSTRLEN
];
3220 pim_inet4_dump("<Rp Address?>",
3221 bsm_rp
->rp_address
, rp_str
,
3225 json_row
= json_object_new_object();
3226 json_object_string_add(
3227 json_row
, "Rp Address", rp_str
);
3228 json_object_int_add(
3229 json_row
, "Rp HoldTime",
3230 bsm_rp
->rp_holdtime
);
3231 json_object_int_add(json_row
,
3234 json_object_int_add(json_row
,
3237 json_object_object_add(
3238 json_group
, rp_str
, json_row
);
3242 "%-15s %-15u %-15u %-15u\n",
3243 rp_str
, bsm_rp
->rp_prio
,
3244 bsm_rp
->rp_holdtime
,
3248 if (!bsgrp
->bsrp_list
->count
&& !uj
)
3249 vty_out(vty
, "Active List is empty.\n");
3253 json_object_int_add(json_group
, "Pending RP count",
3254 bsgrp
->pend_rp_cnt
);
3256 vty_out(vty
, "(PENDING)\n");
3257 vty_out(vty
, "Pending RP count :%d\n",
3258 bsgrp
->pend_rp_cnt
);
3259 if (bsgrp
->pend_rp_cnt
)
3260 vty_out(vty
, "%-15s %-15s %-15s %-15s\n",
3261 "Rp Address", "priority", "Holdtime",
3265 if (bsgrp
->partial_bsrp_list
) {
3266 for (ALL_LIST_ELEMENTS_RO(bsgrp
->partial_bsrp_list
,
3268 char rp_str
[INET_ADDRSTRLEN
];
3270 pim_inet4_dump("<Rp Addr?>", bsm_rp
->rp_address
,
3271 rp_str
, sizeof(rp_str
));
3274 json_row
= json_object_new_object();
3275 json_object_string_add(
3276 json_row
, "Rp Address", rp_str
);
3277 json_object_int_add(
3278 json_row
, "Rp HoldTime",
3279 bsm_rp
->rp_holdtime
);
3280 json_object_int_add(json_row
,
3283 json_object_int_add(json_row
,
3286 json_object_object_add(
3287 json_group
, rp_str
, json_row
);
3290 "%-15s %-15u %-15u %-15u\n",
3291 rp_str
, bsm_rp
->rp_prio
,
3292 bsm_rp
->rp_holdtime
,
3296 if (!bsgrp
->partial_bsrp_list
->count
&& !uj
)
3297 vty_out(vty
, "Partial List is empty\n");
3305 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3306 json
, JSON_C_TO_STRING_PRETTY
));
3307 json_object_free(json
);
3311 /* pim statistics - just adding only bsm related now.
3312 * We can continue to add all pim related stats here.
3314 static void pim_show_statistics(struct pim_instance
*pim
, struct vty
*vty
,
3315 const char *ifname
, bool uj
)
3317 json_object
*json
= NULL
;
3318 struct interface
*ifp
;
3321 json
= json_object_new_object();
3322 json_object_int_add(json
, "bsmRx", pim
->bsm_rcvd
);
3323 json_object_int_add(json
, "bsmTx", pim
->bsm_sent
);
3324 json_object_int_add(json
, "bsmDropped", pim
->bsm_dropped
);
3326 vty_out(vty
, "BSM Statistics :\n");
3327 vty_out(vty
, "----------------\n");
3328 vty_out(vty
, "Number of Received BSMs : %" PRIu64
"\n",
3330 vty_out(vty
, "Number of Forwared BSMs : %" PRIu64
"\n",
3332 vty_out(vty
, "Number of Dropped BSMs : %" PRIu64
"\n",
3338 /* scan interfaces */
3339 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3340 struct pim_interface
*pim_ifp
= ifp
->info
;
3342 if (ifname
&& strcmp(ifname
, ifp
->name
))
3349 vty_out(vty
, "Interface : %s\n", ifp
->name
);
3350 vty_out(vty
, "-------------------\n");
3352 "Number of BSMs dropped due to config miss : %u\n",
3353 pim_ifp
->pim_ifstat_bsm_cfg_miss
);
3354 vty_out(vty
, "Number of unicast BSMs dropped : %u\n",
3355 pim_ifp
->pim_ifstat_ucast_bsm_cfg_miss
);
3357 "Number of BSMs dropped due to invalid scope zone : %u\n",
3358 pim_ifp
->pim_ifstat_bsm_invalid_sz
);
3361 json_object
*json_row
= NULL
;
3363 json_row
= json_object_new_object();
3365 json_object_string_add(json_row
, "If Name", ifp
->name
);
3366 json_object_int_add(json_row
, "bsmDroppedConfig",
3367 pim_ifp
->pim_ifstat_bsm_cfg_miss
);
3368 json_object_int_add(
3369 json_row
, "bsmDroppedUnicast",
3370 pim_ifp
->pim_ifstat_ucast_bsm_cfg_miss
);
3371 json_object_int_add(json_row
,
3372 "bsmDroppedInvalidScopeZone",
3373 pim_ifp
->pim_ifstat_bsm_invalid_sz
);
3374 json_object_object_add(json
, ifp
->name
, json_row
);
3380 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3381 json
, JSON_C_TO_STRING_PRETTY
));
3382 json_object_free(json
);
3386 static void clear_pim_statistics(struct pim_instance
*pim
)
3388 struct interface
*ifp
;
3392 pim
->bsm_dropped
= 0;
3394 /* scan interfaces */
3395 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3396 struct pim_interface
*pim_ifp
= ifp
->info
;
3401 pim_ifp
->pim_ifstat_bsm_cfg_miss
= 0;
3402 pim_ifp
->pim_ifstat_ucast_bsm_cfg_miss
= 0;
3403 pim_ifp
->pim_ifstat_bsm_invalid_sz
= 0;
3407 static void igmp_show_groups(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
3409 struct interface
*ifp
;
3411 json_object
*json
= NULL
;
3412 json_object
*json_iface
= NULL
;
3413 json_object
*json_row
= NULL
;
3415 now
= pim_time_monotonic_sec();
3418 json
= json_object_new_object();
3421 "Interface Address Group Mode Timer Srcs V Uptime \n");
3423 /* scan interfaces */
3424 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3425 struct pim_interface
*pim_ifp
= ifp
->info
;
3426 struct listnode
*sock_node
;
3427 struct igmp_sock
*igmp
;
3432 /* scan igmp sockets */
3433 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3435 char ifaddr_str
[INET_ADDRSTRLEN
];
3436 struct listnode
*grpnode
;
3437 struct igmp_group
*grp
;
3439 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3440 sizeof(ifaddr_str
));
3442 /* scan igmp groups */
3443 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3445 char group_str
[INET_ADDRSTRLEN
];
3449 pim_inet4_dump("<group?>", grp
->group_addr
,
3450 group_str
, sizeof(group_str
));
3451 pim_time_timer_to_hhmmss(hhmmss
, sizeof(hhmmss
),
3452 grp
->t_group_timer
);
3453 pim_time_uptime(uptime
, sizeof(uptime
),
3454 now
- grp
->group_creation
);
3457 json_object_object_get_ex(
3458 json
, ifp
->name
, &json_iface
);
3462 json_object_new_object();
3463 json_object_pim_ifp_add(
3465 json_object_object_add(
3470 json_row
= json_object_new_object();
3471 json_object_string_add(
3472 json_row
, "source", ifaddr_str
);
3473 json_object_string_add(
3474 json_row
, "group", group_str
);
3476 if (grp
->igmp_version
== 3)
3477 json_object_string_add(
3479 grp
->group_filtermode_isexcl
3483 json_object_string_add(json_row
,
3485 json_object_int_add(
3486 json_row
, "sourcesCount",
3487 grp
->group_source_list
3489 grp
->group_source_list
)
3491 json_object_int_add(json_row
, "version",
3493 json_object_string_add(
3494 json_row
, "uptime", uptime
);
3495 json_object_object_add(json_iface
,
3501 "%-16s %-15s %-15s %4s %8s %4d %d %8s\n",
3502 ifp
->name
, ifaddr_str
,
3504 grp
->igmp_version
== 3
3505 ? (grp
->group_filtermode_isexcl
3510 grp
->group_source_list
3512 grp
->group_source_list
)
3514 grp
->igmp_version
, uptime
);
3516 } /* scan igmp groups */
3517 } /* scan igmp sockets */
3518 } /* scan interfaces */
3521 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3522 json
, JSON_C_TO_STRING_PRETTY
));
3523 json_object_free(json
);
3527 static void igmp_show_group_retransmission(struct pim_instance
*pim
,
3530 struct interface
*ifp
;
3533 "Interface Address Group RetTimer Counter RetSrcs\n");
3535 /* scan interfaces */
3536 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3537 struct pim_interface
*pim_ifp
= ifp
->info
;
3538 struct listnode
*sock_node
;
3539 struct igmp_sock
*igmp
;
3544 /* scan igmp sockets */
3545 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3547 char ifaddr_str
[INET_ADDRSTRLEN
];
3548 struct listnode
*grpnode
;
3549 struct igmp_group
*grp
;
3551 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3552 sizeof(ifaddr_str
));
3554 /* scan igmp groups */
3555 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3557 char group_str
[INET_ADDRSTRLEN
];
3558 char grp_retr_mmss
[10];
3559 struct listnode
*src_node
;
3560 struct igmp_source
*src
;
3561 int grp_retr_sources
= 0;
3563 pim_inet4_dump("<group?>", grp
->group_addr
,
3564 group_str
, sizeof(group_str
));
3565 pim_time_timer_to_mmss(
3566 grp_retr_mmss
, sizeof(grp_retr_mmss
),
3567 grp
->t_group_query_retransmit_timer
);
3570 /* count group sources with retransmission state
3572 for (ALL_LIST_ELEMENTS_RO(
3573 grp
->group_source_list
, src_node
,
3575 if (src
->source_query_retransmit_count
3581 vty_out(vty
, "%-16s %-15s %-15s %-8s %7d %7d\n",
3582 ifp
->name
, ifaddr_str
, group_str
,
3584 grp
->group_specific_query_retransmit_count
,
3587 } /* scan igmp groups */
3588 } /* scan igmp sockets */
3589 } /* scan interfaces */
3592 static void igmp_show_sources(struct pim_instance
*pim
, struct vty
*vty
)
3594 struct interface
*ifp
;
3597 now
= pim_time_monotonic_sec();
3600 "Interface Address Group Source Timer Fwd Uptime \n");
3602 /* scan interfaces */
3603 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3604 struct pim_interface
*pim_ifp
= ifp
->info
;
3605 struct listnode
*sock_node
;
3606 struct igmp_sock
*igmp
;
3611 /* scan igmp sockets */
3612 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3614 char ifaddr_str
[INET_ADDRSTRLEN
];
3615 struct listnode
*grpnode
;
3616 struct igmp_group
*grp
;
3618 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3619 sizeof(ifaddr_str
));
3621 /* scan igmp groups */
3622 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3624 char group_str
[INET_ADDRSTRLEN
];
3625 struct listnode
*srcnode
;
3626 struct igmp_source
*src
;
3628 pim_inet4_dump("<group?>", grp
->group_addr
,
3629 group_str
, sizeof(group_str
));
3631 /* scan group sources */
3632 for (ALL_LIST_ELEMENTS_RO(
3633 grp
->group_source_list
, srcnode
,
3635 char source_str
[INET_ADDRSTRLEN
];
3640 "<source?>", src
->source_addr
,
3641 source_str
, sizeof(source_str
));
3643 pim_time_timer_to_mmss(
3645 src
->t_source_timer
);
3648 uptime
, sizeof(uptime
),
3649 now
- src
->source_creation
);
3652 "%-16s %-15s %-15s %-15s %5s %3s %8s\n",
3653 ifp
->name
, ifaddr_str
,
3654 group_str
, source_str
, mmss
,
3655 IGMP_SOURCE_TEST_FORWARDING(
3661 } /* scan group sources */
3662 } /* scan igmp groups */
3663 } /* scan igmp sockets */
3664 } /* scan interfaces */
3667 static void igmp_show_source_retransmission(struct pim_instance
*pim
,
3670 struct interface
*ifp
;
3673 "Interface Address Group Source Counter\n");
3675 /* scan interfaces */
3676 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3677 struct pim_interface
*pim_ifp
= ifp
->info
;
3678 struct listnode
*sock_node
;
3679 struct igmp_sock
*igmp
;
3684 /* scan igmp sockets */
3685 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3687 char ifaddr_str
[INET_ADDRSTRLEN
];
3688 struct listnode
*grpnode
;
3689 struct igmp_group
*grp
;
3691 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3692 sizeof(ifaddr_str
));
3694 /* scan igmp groups */
3695 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3697 char group_str
[INET_ADDRSTRLEN
];
3698 struct listnode
*srcnode
;
3699 struct igmp_source
*src
;
3701 pim_inet4_dump("<group?>", grp
->group_addr
,
3702 group_str
, sizeof(group_str
));
3704 /* scan group sources */
3705 for (ALL_LIST_ELEMENTS_RO(
3706 grp
->group_source_list
, srcnode
,
3708 char source_str
[INET_ADDRSTRLEN
];
3711 "<source?>", src
->source_addr
,
3712 source_str
, sizeof(source_str
));
3715 "%-16s %-15s %-15s %-15s %7d\n",
3716 ifp
->name
, ifaddr_str
,
3717 group_str
, source_str
,
3718 src
->source_query_retransmit_count
);
3720 } /* scan group sources */
3721 } /* scan igmp groups */
3722 } /* scan igmp sockets */
3723 } /* scan interfaces */
3726 static void pim_show_bsr(struct pim_instance
*pim
,
3731 char last_bsm_seen
[10];
3734 char bsr_str
[PREFIX_STRLEN
];
3735 json_object
*json
= NULL
;
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
, "fragmentTag",
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
, "lastBsmSeen", last_bsm_seen
);
3782 vty_out(vty
, "PIMv2 Bootstrap information\n");
3783 vty_out(vty
, "Current preferred BSR address: %s\n", bsr_str
);
3785 "Priority Fragment-Tag State UpTime\n");
3786 vty_out(vty
, " %-12d %-12d %-13s %7s\n",
3787 pim
->global_scope
.current_bsr_prio
,
3788 pim
->global_scope
.bsm_frag_tag
,
3791 vty_out(vty
, "Last BSM seen: %s\n", last_bsm_seen
);
3795 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3796 json
, JSON_C_TO_STRING_PRETTY
));
3797 json_object_free(json
);
3801 static void clear_igmp_interfaces(struct pim_instance
*pim
)
3803 struct interface
*ifp
;
3805 FOR_ALL_INTERFACES (pim
->vrf
, ifp
)
3806 pim_if_addr_del_all_igmp(ifp
);
3808 FOR_ALL_INTERFACES (pim
->vrf
, ifp
)
3809 pim_if_addr_add_all(ifp
);
3812 static void clear_pim_interfaces(struct pim_instance
*pim
)
3814 struct interface
*ifp
;
3816 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3818 pim_neighbor_delete_all(ifp
, "interface cleared");
3823 static void clear_interfaces(struct pim_instance
*pim
)
3825 clear_igmp_interfaces(pim
);
3826 clear_pim_interfaces(pim
);
3829 #define PIM_GET_PIM_INTERFACE(pim_ifp, ifp) \
3830 pim_ifp = ifp->info; \
3833 "%% Enable PIM and/or IGMP on this interface first\n"); \
3834 return CMD_WARNING_CONFIG_FAILED; \
3837 DEFUN (clear_ip_interfaces
,
3838 clear_ip_interfaces_cmd
,
3839 "clear ip interfaces [vrf NAME]",
3842 "Reset interfaces\n"
3846 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3851 clear_interfaces(vrf
->info
);
3856 DEFUN (clear_ip_igmp_interfaces
,
3857 clear_ip_igmp_interfaces_cmd
,
3858 "clear ip igmp [vrf NAME] interfaces",
3863 "Reset IGMP interfaces\n")
3866 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3871 clear_igmp_interfaces(vrf
->info
);
3876 DEFUN (clear_ip_pim_statistics
,
3877 clear_ip_pim_statistics_cmd
,
3878 "clear ip pim statistics [vrf NAME]",
3883 "Reset PIM statistics\n")
3886 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3891 clear_pim_statistics(vrf
->info
);
3895 static void clear_mroute(struct pim_instance
*pim
)
3897 struct pim_upstream
*up
;
3898 struct interface
*ifp
;
3900 /* scan interfaces */
3901 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3902 struct pim_interface
*pim_ifp
= ifp
->info
;
3903 struct listnode
*sock_node
;
3904 struct igmp_sock
*igmp
;
3905 struct pim_ifchannel
*ch
;
3910 /* deleting all ifchannels */
3911 while (!RB_EMPTY(pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
)) {
3912 ch
= RB_ROOT(pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
);
3914 pim_ifchannel_delete(ch
);
3917 /* clean up all igmp groups */
3918 /* scan igmp sockets */
3919 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3922 struct igmp_group
*grp
;
3924 if (igmp
->igmp_group_list
) {
3925 while (igmp
->igmp_group_list
->count
) {
3926 grp
= listnode_head(
3927 igmp
->igmp_group_list
);
3928 igmp_group_delete(grp
);
3935 /* clean up all upstreams*/
3936 while ((up
= rb_pim_upstream_first(&pim
->upstream_head
))) {
3937 pim_upstream_del(pim
, up
, __func__
);
3941 DEFUN (clear_ip_mroute
,
3942 clear_ip_mroute_cmd
,
3943 "clear ip mroute [vrf NAME]",
3946 "Reset multicast routes\n"
3950 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3955 clear_mroute(vrf
->info
);
3960 DEFUN (clear_ip_pim_interfaces
,
3961 clear_ip_pim_interfaces_cmd
,
3962 "clear ip pim [vrf NAME] interfaces",
3967 "Reset PIM interfaces\n")
3970 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3975 clear_pim_interfaces(vrf
->info
);
3980 DEFUN (clear_ip_pim_interface_traffic
,
3981 clear_ip_pim_interface_traffic_cmd
,
3982 "clear ip pim [vrf NAME] interface traffic",
3985 "PIM clear commands\n"
3987 "Reset PIM interfaces\n"
3988 "Reset Protocol Packet counters\n")
3991 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3992 struct interface
*ifp
= NULL
;
3993 struct pim_interface
*pim_ifp
= NULL
;
3998 FOR_ALL_INTERFACES (vrf
, ifp
) {
3999 pim_ifp
= ifp
->info
;
4004 pim_ifp
->pim_ifstat_hello_recv
= 0;
4005 pim_ifp
->pim_ifstat_hello_sent
= 0;
4006 pim_ifp
->pim_ifstat_join_recv
= 0;
4007 pim_ifp
->pim_ifstat_join_send
= 0;
4008 pim_ifp
->pim_ifstat_prune_recv
= 0;
4009 pim_ifp
->pim_ifstat_prune_send
= 0;
4010 pim_ifp
->pim_ifstat_reg_recv
= 0;
4011 pim_ifp
->pim_ifstat_reg_send
= 0;
4012 pim_ifp
->pim_ifstat_reg_stop_recv
= 0;
4013 pim_ifp
->pim_ifstat_reg_stop_send
= 0;
4014 pim_ifp
->pim_ifstat_assert_recv
= 0;
4015 pim_ifp
->pim_ifstat_assert_send
= 0;
4016 pim_ifp
->pim_ifstat_bsm_rx
= 0;
4017 pim_ifp
->pim_ifstat_bsm_tx
= 0;
4023 DEFUN (clear_ip_pim_oil
,
4024 clear_ip_pim_oil_cmd
,
4025 "clear ip pim [vrf NAME] oil",
4030 "Rescan PIM OIL (output interface list)\n")
4033 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4038 pim_scan_oil(vrf
->info
);
4043 DEFUN (show_ip_igmp_interface
,
4044 show_ip_igmp_interface_cmd
,
4045 "show ip igmp [vrf NAME] interface [detail|WORD] [json]",
4050 "IGMP interface information\n"
4056 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4057 bool uj
= use_json(argc
, argv
);
4062 if (argv_find(argv
, argc
, "detail", &idx
)
4063 || argv_find(argv
, argc
, "WORD", &idx
))
4064 igmp_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
4066 igmp_show_interfaces(vrf
->info
, vty
, uj
);
4071 DEFUN (show_ip_igmp_interface_vrf_all
,
4072 show_ip_igmp_interface_vrf_all_cmd
,
4073 "show ip igmp vrf all interface [detail|WORD] [json]",
4078 "IGMP interface information\n"
4084 bool uj
= use_json(argc
, argv
);
4090 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4094 vty_out(vty
, " \"%s\": ", vrf
->name
);
4097 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4098 if (argv_find(argv
, argc
, "detail", &idx
)
4099 || argv_find(argv
, argc
, "WORD", &idx
))
4100 igmp_show_interfaces_single(vrf
->info
, vty
,
4101 argv
[idx
]->arg
, uj
);
4103 igmp_show_interfaces(vrf
->info
, vty
, uj
);
4106 vty_out(vty
, "}\n");
4111 DEFUN (show_ip_igmp_join
,
4112 show_ip_igmp_join_cmd
,
4113 "show ip igmp [vrf NAME] join",
4118 "IGMP static join information\n")
4121 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4126 igmp_show_interface_join(vrf
->info
, vty
);
4131 DEFUN (show_ip_igmp_join_vrf_all
,
4132 show_ip_igmp_join_vrf_all_cmd
,
4133 "show ip igmp vrf all join",
4138 "IGMP static join information\n")
4140 bool uj
= use_json(argc
, argv
);
4146 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4150 vty_out(vty
, " \"%s\": ", vrf
->name
);
4153 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4154 igmp_show_interface_join(vrf
->info
, vty
);
4157 vty_out(vty
, "}\n");
4162 DEFUN (show_ip_igmp_groups
,
4163 show_ip_igmp_groups_cmd
,
4164 "show ip igmp [vrf NAME] groups [json]",
4173 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4174 bool uj
= use_json(argc
, argv
);
4179 igmp_show_groups(vrf
->info
, vty
, uj
);
4184 DEFUN (show_ip_igmp_groups_vrf_all
,
4185 show_ip_igmp_groups_vrf_all_cmd
,
4186 "show ip igmp vrf all groups [json]",
4194 bool uj
= use_json(argc
, argv
);
4200 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4204 vty_out(vty
, " \"%s\": ", vrf
->name
);
4207 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4208 igmp_show_groups(vrf
->info
, vty
, uj
);
4211 vty_out(vty
, "}\n");
4216 DEFUN (show_ip_igmp_groups_retransmissions
,
4217 show_ip_igmp_groups_retransmissions_cmd
,
4218 "show ip igmp [vrf NAME] groups retransmissions",
4224 "IGMP group retransmissions\n")
4227 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4232 igmp_show_group_retransmission(vrf
->info
, vty
);
4237 DEFUN (show_ip_igmp_sources
,
4238 show_ip_igmp_sources_cmd
,
4239 "show ip igmp [vrf NAME] sources",
4247 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4252 igmp_show_sources(vrf
->info
, vty
);
4257 DEFUN (show_ip_igmp_sources_retransmissions
,
4258 show_ip_igmp_sources_retransmissions_cmd
,
4259 "show ip igmp [vrf NAME] sources retransmissions",
4265 "IGMP source retransmissions\n")
4268 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4273 igmp_show_source_retransmission(vrf
->info
, vty
);
4278 DEFUN (show_ip_igmp_statistics
,
4279 show_ip_igmp_statistics_cmd
,
4280 "show ip igmp [vrf NAME] statistics [interface WORD] [json]",
4291 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4292 bool uj
= use_json(argc
, argv
);
4297 if (argv_find(argv
, argc
, "WORD", &idx
))
4298 igmp_show_statistics(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
4300 igmp_show_statistics(vrf
->info
, vty
, NULL
, uj
);
4305 DEFUN (show_ip_pim_mlag_summary
,
4306 show_ip_pim_mlag_summary_cmd
,
4307 "show ip pim mlag summary [json]",
4312 "status and stats\n"
4315 bool uj
= use_json(argc
, argv
);
4316 char role_buf
[MLAG_ROLE_STRSIZE
];
4317 char addr_buf
[INET_ADDRSTRLEN
];
4320 json_object
*json
= NULL
;
4321 json_object
*json_stat
= NULL
;
4323 json
= json_object_new_object();
4324 if (router
->mlag_flags
& PIM_MLAGF_LOCAL_CONN_UP
)
4325 json_object_boolean_true_add(json
, "mlagConnUp");
4326 if (router
->mlag_flags
& PIM_MLAGF_PEER_CONN_UP
)
4327 json_object_boolean_true_add(json
, "mlagPeerConnUp");
4328 if (router
->mlag_flags
& PIM_MLAGF_PEER_ZEBRA_UP
)
4329 json_object_boolean_true_add(json
, "mlagPeerZebraUp");
4330 json_object_string_add(json
, "mlagRole",
4331 mlag_role2str(router
->mlag_role
,
4332 role_buf
, sizeof(role_buf
)));
4333 inet_ntop(AF_INET
, &router
->local_vtep_ip
,
4334 addr_buf
, INET_ADDRSTRLEN
);
4335 json_object_string_add(json
, "localVtepIp", addr_buf
);
4336 inet_ntop(AF_INET
, &router
->anycast_vtep_ip
,
4337 addr_buf
, INET_ADDRSTRLEN
);
4338 json_object_string_add(json
, "anycastVtepIp", addr_buf
);
4339 json_object_string_add(json
, "peerlinkRif",
4340 router
->peerlink_rif
);
4342 json_stat
= json_object_new_object();
4343 json_object_int_add(json_stat
, "mlagConnFlaps",
4344 router
->mlag_stats
.mlagd_session_downs
);
4345 json_object_int_add(json_stat
, "mlagPeerConnFlaps",
4346 router
->mlag_stats
.peer_session_downs
);
4347 json_object_int_add(json_stat
, "mlagPeerZebraFlaps",
4348 router
->mlag_stats
.peer_zebra_downs
);
4349 json_object_int_add(json_stat
, "mrouteAddRx",
4350 router
->mlag_stats
.msg
.mroute_add_rx
);
4351 json_object_int_add(json_stat
, "mrouteAddTx",
4352 router
->mlag_stats
.msg
.mroute_add_tx
);
4353 json_object_int_add(json_stat
, "mrouteDelRx",
4354 router
->mlag_stats
.msg
.mroute_del_rx
);
4355 json_object_int_add(json_stat
, "mrouteDelTx",
4356 router
->mlag_stats
.msg
.mroute_del_tx
);
4357 json_object_int_add(json_stat
, "mlagStatusUpdates",
4358 router
->mlag_stats
.msg
.mlag_status_updates
);
4359 json_object_int_add(json_stat
, "peerZebraStatusUpdates",
4360 router
->mlag_stats
.msg
.peer_zebra_status_updates
);
4361 json_object_int_add(json_stat
, "pimStatusUpdates",
4362 router
->mlag_stats
.msg
.pim_status_updates
);
4363 json_object_int_add(json_stat
, "vxlanUpdates",
4364 router
->mlag_stats
.msg
.vxlan_updates
);
4365 json_object_object_add(json
, "connStats", json_stat
);
4367 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4368 json
, JSON_C_TO_STRING_PRETTY
));
4369 json_object_free(json
);
4373 vty_out(vty
, "MLAG daemon connection: %s\n",
4374 (router
->mlag_flags
& PIM_MLAGF_LOCAL_CONN_UP
)
4376 vty_out(vty
, "MLAG peer state: %s\n",
4377 (router
->mlag_flags
& PIM_MLAGF_PEER_CONN_UP
)
4379 vty_out(vty
, "Zebra peer state: %s\n",
4380 (router
->mlag_flags
& PIM_MLAGF_PEER_ZEBRA_UP
)
4382 vty_out(vty
, "MLAG role: %s\n",
4383 mlag_role2str(router
->mlag_role
, role_buf
, sizeof(role_buf
)));
4384 inet_ntop(AF_INET
, &router
->local_vtep_ip
,
4385 addr_buf
, INET_ADDRSTRLEN
);
4386 vty_out(vty
, "Local VTEP IP: %s\n", addr_buf
);
4387 inet_ntop(AF_INET
, &router
->anycast_vtep_ip
,
4388 addr_buf
, INET_ADDRSTRLEN
);
4389 vty_out(vty
, "Anycast VTEP IP: %s\n", addr_buf
);
4390 vty_out(vty
, "Peerlink: %s\n", router
->peerlink_rif
);
4391 vty_out(vty
, "Session flaps: mlagd: %d mlag-peer: %d zebra-peer: %d\n",
4392 router
->mlag_stats
.mlagd_session_downs
,
4393 router
->mlag_stats
.peer_session_downs
,
4394 router
->mlag_stats
.peer_zebra_downs
);
4395 vty_out(vty
, "Message Statistics:\n");
4396 vty_out(vty
, " mroute adds: rx: %d, tx: %d\n",
4397 router
->mlag_stats
.msg
.mroute_add_rx
,
4398 router
->mlag_stats
.msg
.mroute_add_tx
);
4399 vty_out(vty
, " mroute dels: rx: %d, tx: %d\n",
4400 router
->mlag_stats
.msg
.mroute_del_rx
,
4401 router
->mlag_stats
.msg
.mroute_del_tx
);
4402 vty_out(vty
, " peer zebra status updates: %d\n",
4403 router
->mlag_stats
.msg
.peer_zebra_status_updates
);
4404 vty_out(vty
, " PIM status updates: %d\n",
4405 router
->mlag_stats
.msg
.pim_status_updates
);
4406 vty_out(vty
, " VxLAN updates: %d\n",
4407 router
->mlag_stats
.msg
.vxlan_updates
);
4412 DEFUN (show_ip_pim_assert
,
4413 show_ip_pim_assert_cmd
,
4414 "show ip pim [vrf NAME] assert",
4419 "PIM interface assert\n")
4422 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4427 pim_show_assert(vrf
->info
, vty
);
4432 DEFUN (show_ip_pim_assert_internal
,
4433 show_ip_pim_assert_internal_cmd
,
4434 "show ip pim [vrf NAME] assert-internal",
4439 "PIM interface internal assert state\n")
4442 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4447 pim_show_assert_internal(vrf
->info
, vty
);
4452 DEFUN (show_ip_pim_assert_metric
,
4453 show_ip_pim_assert_metric_cmd
,
4454 "show ip pim [vrf NAME] assert-metric",
4459 "PIM interface assert metric\n")
4462 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4467 pim_show_assert_metric(vrf
->info
, vty
);
4472 DEFUN (show_ip_pim_assert_winner_metric
,
4473 show_ip_pim_assert_winner_metric_cmd
,
4474 "show ip pim [vrf NAME] assert-winner-metric",
4479 "PIM interface assert winner metric\n")
4482 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4487 pim_show_assert_winner_metric(vrf
->info
, vty
);
4492 DEFUN (show_ip_pim_interface
,
4493 show_ip_pim_interface_cmd
,
4494 "show ip pim [mlag] [vrf NAME] interface [detail|WORD] [json]",
4500 "PIM interface information\n"
4506 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4507 bool uj
= use_json(argc
, argv
);
4513 if (argv_find(argv
, argc
, "mlag", &idx
))
4516 if (argv_find(argv
, argc
, "WORD", &idx
)
4517 || argv_find(argv
, argc
, "detail", &idx
))
4518 pim_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, mlag
,
4521 pim_show_interfaces(vrf
->info
, vty
, mlag
, uj
);
4526 DEFUN (show_ip_pim_interface_vrf_all
,
4527 show_ip_pim_interface_vrf_all_cmd
,
4528 "show ip pim [mlag] vrf all interface [detail|WORD] [json]",
4534 "PIM interface information\n"
4540 bool uj
= use_json(argc
, argv
);
4545 if (argv_find(argv
, argc
, "mlag", &idx
))
4551 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4555 vty_out(vty
, " \"%s\": ", vrf
->name
);
4558 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4559 if (argv_find(argv
, argc
, "WORD", &idx
)
4560 || argv_find(argv
, argc
, "detail", &idx
))
4561 pim_show_interfaces_single(vrf
->info
, vty
,
4562 argv
[idx
]->arg
, mlag
, uj
);
4564 pim_show_interfaces(vrf
->info
, vty
, mlag
, uj
);
4567 vty_out(vty
, "}\n");
4572 DEFPY (show_ip_pim_join
,
4573 show_ip_pim_join_cmd
,
4574 "show ip pim [vrf NAME] join [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
4579 "PIM interface join information\n"
4580 "The Source or Group\n"
4584 struct prefix_sg sg
= {0};
4587 struct pim_instance
*pim
;
4589 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
4592 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
4595 pim
= pim_get_pim_instance(v
->vrf_id
);
4598 vty_out(vty
, "%% Unable to find pim instance\n");
4602 if (s_or_g
.s_addr
!= 0) {
4603 if (g
.s_addr
!= 0) {
4610 pim_show_join(pim
, vty
, &sg
, uj
);
4615 DEFUN (show_ip_pim_join_vrf_all
,
4616 show_ip_pim_join_vrf_all_cmd
,
4617 "show ip pim vrf all join [json]",
4622 "PIM interface join information\n"
4625 struct prefix_sg sg
= {0};
4626 bool uj
= use_json(argc
, argv
);
4632 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4636 vty_out(vty
, " \"%s\": ", vrf
->name
);
4639 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4640 pim_show_join(vrf
->info
, vty
, &sg
, uj
);
4643 vty_out(vty
, "}\n");
4648 static void pim_show_jp_agg_helper(struct vty
*vty
,
4649 struct interface
*ifp
,
4650 struct pim_neighbor
*neigh
,
4651 struct pim_upstream
*up
,
4654 char src_str
[INET_ADDRSTRLEN
];
4655 char grp_str
[INET_ADDRSTRLEN
];
4656 char rpf_str
[INET_ADDRSTRLEN
];
4658 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
4659 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
4660 /* pius->address.s_addr */
4661 pim_inet4_dump("<rpf?>", neigh
->source_addr
, rpf_str
, sizeof(rpf_str
));
4663 vty_out(vty
, "%-16s %-15s %-15s %-15s %5s\n",
4664 ifp
->name
, rpf_str
, src_str
,
4665 grp_str
, is_join
?"J":"P");
4668 static void pim_show_jp_agg_list(struct pim_instance
*pim
, struct vty
*vty
)
4670 struct interface
*ifp
;
4671 struct pim_interface
*pim_ifp
;
4672 struct listnode
*n_node
;
4673 struct pim_neighbor
*neigh
;
4674 struct listnode
*jag_node
;
4675 struct pim_jp_agg_group
*jag
;
4676 struct listnode
*js_node
;
4677 struct pim_jp_sources
*js
;
4680 "Interface RPF Nbr Source Group State\n");
4682 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
4683 pim_ifp
= ifp
->info
;
4687 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
,
4689 for (ALL_LIST_ELEMENTS_RO(neigh
->upstream_jp_agg
,
4691 for (ALL_LIST_ELEMENTS_RO(jag
->sources
,
4693 pim_show_jp_agg_helper(vty
,
4702 DEFPY (show_ip_pim_jp_agg
,
4703 show_ip_pim_jp_agg_cmd
,
4704 "show ip pim [vrf NAME] jp-agg",
4709 "join prune aggregation list\n")
4712 struct pim_instance
*pim
;
4714 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
4717 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
4720 pim
= pim_get_pim_instance(v
->vrf_id
);
4723 vty_out(vty
, "%% Unable to find pim instance\n");
4727 pim_show_jp_agg_list(pim
, vty
);
4732 DEFUN (show_ip_pim_local_membership
,
4733 show_ip_pim_local_membership_cmd
,
4734 "show ip pim [vrf NAME] local-membership [json]",
4739 "PIM interface local-membership\n"
4743 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4744 bool uj
= use_json(argc
, argv
);
4749 pim_show_membership(vrf
->info
, vty
, uj
);
4754 static void pim_show_mlag_up_entry_detail(struct vrf
*vrf
,
4755 struct vty
*vty
, struct pim_upstream
*up
,
4756 char *src_str
, char *grp_str
, json_object
*json
)
4759 json_object
*json_row
= NULL
;
4760 json_object
*own_list
= NULL
;
4761 json_object
*json_group
= NULL
;
4764 json_object_object_get_ex(json
, grp_str
, &json_group
);
4766 json_group
= json_object_new_object();
4767 json_object_object_add(json
, grp_str
,
4771 json_row
= json_object_new_object();
4772 json_object_string_add(json_row
, "source", src_str
);
4773 json_object_string_add(json_row
, "group", grp_str
);
4775 own_list
= json_object_new_array();
4776 if (pim_up_mlag_is_local(up
))
4777 json_object_array_add(own_list
,
4778 json_object_new_string("local"));
4779 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
))
4780 json_object_array_add(own_list
,
4781 json_object_new_string("peer"));
4782 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE
))
4783 json_object_array_add(
4784 own_list
, json_object_new_string("Interface"));
4785 json_object_object_add(json_row
, "owners", own_list
);
4787 json_object_int_add(json_row
, "localCost",
4788 pim_up_mlag_local_cost(up
));
4789 json_object_int_add(json_row
, "peerCost",
4790 pim_up_mlag_peer_cost(up
));
4791 if (PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up
->flags
))
4792 json_object_boolean_false_add(json_row
, "df");
4794 json_object_boolean_true_add(json_row
, "df");
4795 json_object_object_add(json_group
, src_str
, json_row
);
4800 if (pim_up_mlag_is_local(up
))
4801 strlcat(own_str
, "L", sizeof(own_str
));
4802 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
))
4803 strlcat(own_str
, "P", sizeof(own_str
));
4804 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE
))
4805 strlcat(own_str
, "I", sizeof(own_str
));
4806 /* XXX - fixup, print paragraph output */
4808 "%-15s %-15s %-6s %-11u %-10d %2s\n",
4809 src_str
, grp_str
, own_str
,
4810 pim_up_mlag_local_cost(up
),
4811 pim_up_mlag_peer_cost(up
),
4812 PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up
->flags
)
4817 static void pim_show_mlag_up_detail(struct vrf
*vrf
,
4818 struct vty
*vty
, const char *src_or_group
,
4819 const char *group
, bool uj
)
4821 char src_str
[INET_ADDRSTRLEN
];
4822 char grp_str
[INET_ADDRSTRLEN
];
4823 struct pim_upstream
*up
;
4824 struct pim_instance
*pim
= vrf
->info
;
4825 json_object
*json
= NULL
;
4828 json
= json_object_new_object();
4831 "Source Group Owner Local-cost Peer-cost DF\n");
4833 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
4834 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
)
4835 && !(up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE
)
4836 && !pim_up_mlag_is_local(up
))
4839 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
4840 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
4841 /* XXX: strcmps are clearly inefficient. we should do uint comps
4845 if (strcmp(src_str
, src_or_group
) ||
4846 strcmp(grp_str
, group
))
4849 if (strcmp(src_str
, src_or_group
) &&
4850 strcmp(grp_str
, src_or_group
))
4853 pim_show_mlag_up_entry_detail(vrf
, vty
, up
,
4854 src_str
, grp_str
, json
);
4858 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4859 json
, JSON_C_TO_STRING_PRETTY
));
4860 json_object_free(json
);
4864 static void pim_show_mlag_up_vrf(struct vrf
*vrf
, struct vty
*vty
, bool uj
)
4866 json_object
*json
= NULL
;
4867 json_object
*json_row
;
4868 struct pim_upstream
*up
;
4869 char src_str
[INET_ADDRSTRLEN
];
4870 char grp_str
[INET_ADDRSTRLEN
];
4871 struct pim_instance
*pim
= vrf
->info
;
4872 json_object
*json_group
= NULL
;
4875 json
= json_object_new_object();
4878 "Source Group Owner Local-cost Peer-cost DF\n");
4881 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
4882 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
)
4883 && !(up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE
)
4884 && !pim_up_mlag_is_local(up
))
4886 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
4887 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
4889 json_object
*own_list
= NULL
;
4891 json_object_object_get_ex(json
, grp_str
, &json_group
);
4893 json_group
= json_object_new_object();
4894 json_object_object_add(json
, grp_str
,
4898 json_row
= json_object_new_object();
4899 json_object_string_add(json_row
, "vrf", vrf
->name
);
4900 json_object_string_add(json_row
, "source", src_str
);
4901 json_object_string_add(json_row
, "group", grp_str
);
4903 own_list
= json_object_new_array();
4904 if (pim_up_mlag_is_local(up
)) {
4906 json_object_array_add(own_list
,
4907 json_object_new_string("local"));
4909 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
)) {
4910 json_object_array_add(own_list
,
4911 json_object_new_string("peer"));
4913 json_object_object_add(json_row
, "owners", own_list
);
4915 json_object_int_add(json_row
, "localCost",
4916 pim_up_mlag_local_cost(up
));
4917 json_object_int_add(json_row
, "peerCost",
4918 pim_up_mlag_peer_cost(up
));
4919 if (PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up
->flags
))
4920 json_object_boolean_false_add(json_row
, "df");
4922 json_object_boolean_true_add(json_row
, "df");
4923 json_object_object_add(json_group
, src_str
, json_row
);
4928 if (pim_up_mlag_is_local(up
))
4929 strlcat(own_str
, "L", sizeof(own_str
));
4930 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
))
4931 strlcat(own_str
, "P", sizeof(own_str
));
4932 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE
))
4933 strlcat(own_str
, "I", sizeof(own_str
));
4935 "%-15s %-15s %-6s %-11u %-10u %2s\n",
4936 src_str
, grp_str
, own_str
,
4937 pim_up_mlag_local_cost(up
),
4938 pim_up_mlag_peer_cost(up
),
4939 PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up
->flags
)
4944 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4945 json
, JSON_C_TO_STRING_PRETTY
));
4946 json_object_free(json
);
4950 static void pim_show_mlag_help_string(struct vty
*vty
, bool uj
)
4953 vty_out(vty
, "Owner codes:\n");
4955 "L: EVPN-MLAG Entry, I:PIM-MLAG Entry, "
4961 DEFUN(show_ip_pim_mlag_up
, show_ip_pim_mlag_up_cmd
,
4962 "show ip pim [vrf NAME] mlag upstream [A.B.C.D [A.B.C.D]] [json]",
4969 "Unicast or Multicast address\n"
4970 "Multicast address\n" JSON_STR
)
4972 const char *src_or_group
= NULL
;
4973 const char *group
= NULL
;
4975 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4976 bool uj
= use_json(argc
, argv
);
4978 if (!vrf
|| !vrf
->info
) {
4979 vty_out(vty
, "%s: VRF or Info missing\n", __func__
);
4986 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
4987 src_or_group
= argv
[idx
]->arg
;
4989 group
= argv
[idx
+ 1]->arg
;
4992 pim_show_mlag_help_string(vty
, uj
);
4995 pim_show_mlag_up_detail(vrf
, vty
, src_or_group
, group
, uj
);
4997 pim_show_mlag_up_vrf(vrf
, vty
, uj
);
5003 DEFUN(show_ip_pim_mlag_up_vrf_all
, show_ip_pim_mlag_up_vrf_all_cmd
,
5004 "show ip pim vrf all mlag upstream [json]",
5005 SHOW_STR IP_STR PIM_STR VRF_CMD_HELP_STR
5007 "upstream\n" JSON_STR
)
5010 bool uj
= use_json(argc
, argv
);
5012 pim_show_mlag_help_string(vty
, uj
);
5013 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5014 pim_show_mlag_up_vrf(vrf
, vty
, uj
);
5020 DEFUN (show_ip_pim_neighbor
,
5021 show_ip_pim_neighbor_cmd
,
5022 "show ip pim [vrf NAME] neighbor [detail|WORD] [json]",
5027 "PIM neighbor information\n"
5029 "Name of interface or neighbor\n"
5033 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5034 bool uj
= use_json(argc
, argv
);
5039 if (argv_find(argv
, argc
, "detail", &idx
)
5040 || argv_find(argv
, argc
, "WORD", &idx
))
5041 pim_show_neighbors_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
5043 pim_show_neighbors(vrf
->info
, vty
, uj
);
5048 DEFUN (show_ip_pim_neighbor_vrf_all
,
5049 show_ip_pim_neighbor_vrf_all_cmd
,
5050 "show ip pim vrf all neighbor [detail|WORD] [json]",
5055 "PIM neighbor information\n"
5057 "Name of interface or neighbor\n"
5061 bool uj
= use_json(argc
, argv
);
5067 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5071 vty_out(vty
, " \"%s\": ", vrf
->name
);
5074 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5075 if (argv_find(argv
, argc
, "detail", &idx
)
5076 || argv_find(argv
, argc
, "WORD", &idx
))
5077 pim_show_neighbors_single(vrf
->info
, vty
,
5078 argv
[idx
]->arg
, uj
);
5080 pim_show_neighbors(vrf
->info
, vty
, uj
);
5083 vty_out(vty
, "}\n");
5088 DEFUN (show_ip_pim_secondary
,
5089 show_ip_pim_secondary_cmd
,
5090 "show ip pim [vrf NAME] secondary",
5095 "PIM neighbor addresses\n")
5098 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5103 pim_show_neighbors_secondary(vrf
->info
, vty
);
5108 DEFUN (show_ip_pim_state
,
5109 show_ip_pim_state_cmd
,
5110 "show ip pim [vrf NAME] state [A.B.C.D [A.B.C.D]] [json]",
5115 "PIM state information\n"
5116 "Unicast or Multicast address\n"
5117 "Multicast address\n"
5120 const char *src_or_group
= NULL
;
5121 const char *group
= NULL
;
5123 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5124 bool uj
= use_json(argc
, argv
);
5132 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
5133 src_or_group
= argv
[idx
]->arg
;
5135 group
= argv
[idx
+ 1]->arg
;
5138 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
5143 DEFUN (show_ip_pim_state_vrf_all
,
5144 show_ip_pim_state_vrf_all_cmd
,
5145 "show ip pim vrf all state [A.B.C.D [A.B.C.D]] [json]",
5150 "PIM state information\n"
5151 "Unicast or Multicast address\n"
5152 "Multicast address\n"
5155 const char *src_or_group
= NULL
;
5156 const char *group
= NULL
;
5158 bool uj
= use_json(argc
, argv
);
5167 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
5168 src_or_group
= argv
[idx
]->arg
;
5170 group
= argv
[idx
+ 1]->arg
;
5173 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5177 vty_out(vty
, " \"%s\": ", vrf
->name
);
5180 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5181 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
5184 vty_out(vty
, "}\n");
5189 DEFPY (show_ip_pim_upstream
,
5190 show_ip_pim_upstream_cmd
,
5191 "show ip pim [vrf NAME] upstream [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
5196 "PIM upstream information\n"
5197 "The Source or Group\n"
5201 struct prefix_sg sg
= {0};
5204 struct pim_instance
*pim
;
5206 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
5209 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
5212 pim
= pim_get_pim_instance(v
->vrf_id
);
5215 vty_out(vty
, "%% Unable to find pim instance\n");
5219 if (s_or_g
.s_addr
!= 0) {
5220 if (g
.s_addr
!= 0) {
5226 pim_show_upstream(pim
, vty
, &sg
, uj
);
5231 DEFUN (show_ip_pim_upstream_vrf_all
,
5232 show_ip_pim_upstream_vrf_all_cmd
,
5233 "show ip pim vrf all upstream [json]",
5238 "PIM upstream information\n"
5241 struct prefix_sg sg
= {0};
5242 bool uj
= use_json(argc
, argv
);
5248 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5252 vty_out(vty
, " \"%s\": ", vrf
->name
);
5255 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5256 pim_show_upstream(vrf
->info
, vty
, &sg
, uj
);
5262 DEFUN (show_ip_pim_channel
,
5263 show_ip_pim_channel_cmd
,
5264 "show ip pim [vrf NAME] channel [json]",
5269 "PIM downstream channel info\n"
5273 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5274 bool uj
= use_json(argc
, argv
);
5279 pim_show_channel(vrf
->info
, vty
, uj
);
5284 DEFUN (show_ip_pim_upstream_join_desired
,
5285 show_ip_pim_upstream_join_desired_cmd
,
5286 "show ip pim [vrf NAME] upstream-join-desired [json]",
5291 "PIM upstream join-desired\n"
5295 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5296 bool uj
= use_json(argc
, argv
);
5301 pim_show_join_desired(vrf
->info
, vty
, uj
);
5306 DEFUN (show_ip_pim_upstream_rpf
,
5307 show_ip_pim_upstream_rpf_cmd
,
5308 "show ip pim [vrf NAME] upstream-rpf [json]",
5313 "PIM upstream source rpf\n"
5317 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5318 bool uj
= use_json(argc
, argv
);
5323 pim_show_upstream_rpf(vrf
->info
, vty
, uj
);
5328 DEFUN (show_ip_pim_rp
,
5330 "show ip pim [vrf NAME] rp-info [json]",
5335 "PIM RP information\n"
5339 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5340 bool uj
= use_json(argc
, argv
);
5345 pim_rp_show_information(vrf
->info
, vty
, uj
);
5350 DEFUN (show_ip_pim_rp_vrf_all
,
5351 show_ip_pim_rp_vrf_all_cmd
,
5352 "show ip pim vrf all rp-info [json]",
5357 "PIM RP information\n"
5360 bool uj
= use_json(argc
, argv
);
5366 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5370 vty_out(vty
, " \"%s\": ", vrf
->name
);
5373 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5374 pim_rp_show_information(vrf
->info
, vty
, uj
);
5377 vty_out(vty
, "}\n");
5382 DEFUN (show_ip_pim_rpf
,
5383 show_ip_pim_rpf_cmd
,
5384 "show ip pim [vrf NAME] rpf [json]",
5389 "PIM cached source rpf information\n"
5393 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5394 bool uj
= use_json(argc
, argv
);
5399 pim_show_rpf(vrf
->info
, vty
, uj
);
5404 DEFUN (show_ip_pim_rpf_vrf_all
,
5405 show_ip_pim_rpf_vrf_all_cmd
,
5406 "show ip pim vrf all rpf [json]",
5411 "PIM cached source rpf information\n"
5414 bool uj
= use_json(argc
, argv
);
5420 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5424 vty_out(vty
, " \"%s\": ", vrf
->name
);
5427 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5428 pim_show_rpf(vrf
->info
, vty
, uj
);
5431 vty_out(vty
, "}\n");
5436 DEFUN (show_ip_pim_nexthop
,
5437 show_ip_pim_nexthop_cmd
,
5438 "show ip pim [vrf NAME] nexthop",
5443 "PIM cached nexthop rpf information\n")
5446 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5451 pim_show_nexthop(vrf
->info
, vty
);
5456 DEFUN (show_ip_pim_nexthop_lookup
,
5457 show_ip_pim_nexthop_lookup_cmd
,
5458 "show ip pim [vrf NAME] nexthop-lookup A.B.C.D A.B.C.D",
5463 "PIM cached nexthop rpf lookup\n"
5464 "Source/RP address\n"
5465 "Multicast Group address\n")
5467 struct prefix nht_p
;
5469 struct in_addr src_addr
, grp_addr
;
5470 struct in_addr vif_source
;
5471 const char *addr_str
, *addr_str1
;
5473 struct pim_nexthop nexthop
;
5474 char nexthop_addr_str
[PREFIX_STRLEN
];
5475 char grp_str
[PREFIX_STRLEN
];
5477 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5482 argv_find(argv
, argc
, "A.B.C.D", &idx
);
5483 addr_str
= argv
[idx
]->arg
;
5484 result
= inet_pton(AF_INET
, addr_str
, &src_addr
);
5486 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
5487 errno
, safe_strerror(errno
));
5491 if (pim_is_group_224_4(src_addr
)) {
5493 "Invalid argument. Expected Valid Source Address.\n");
5497 addr_str1
= argv
[idx
+ 1]->arg
;
5498 result
= inet_pton(AF_INET
, addr_str1
, &grp_addr
);
5500 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
5501 errno
, safe_strerror(errno
));
5505 if (!pim_is_group_224_4(grp_addr
)) {
5507 "Invalid argument. Expected Valid Multicast Group Address.\n");
5511 if (!pim_rp_set_upstream_addr(vrf
->info
, &vif_source
, src_addr
,
5515 nht_p
.family
= AF_INET
;
5516 nht_p
.prefixlen
= IPV4_MAX_BITLEN
;
5517 nht_p
.u
.prefix4
= vif_source
;
5518 grp
.family
= AF_INET
;
5519 grp
.prefixlen
= IPV4_MAX_BITLEN
;
5520 grp
.u
.prefix4
= grp_addr
;
5521 memset(&nexthop
, 0, sizeof(nexthop
));
5523 result
= pim_ecmp_nexthop_lookup(vrf
->info
, &nexthop
, &nht_p
, &grp
, 0);
5527 "Nexthop Lookup failed, no usable routes returned.\n");
5531 pim_addr_dump("<grp?>", &grp
, grp_str
, sizeof(grp_str
));
5532 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
5533 nexthop_addr_str
, sizeof(nexthop_addr_str
));
5534 vty_out(vty
, "Group %s --- Nexthop %s Interface %s \n", grp_str
,
5535 nexthop_addr_str
, nexthop
.interface
->name
);
5540 DEFUN (show_ip_pim_interface_traffic
,
5541 show_ip_pim_interface_traffic_cmd
,
5542 "show ip pim [vrf NAME] interface traffic [WORD] [json]",
5547 "PIM interface information\n"
5548 "Protocol Packet counters\n"
5553 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5554 bool uj
= use_json(argc
, argv
);
5559 if (argv_find(argv
, argc
, "WORD", &idx
))
5560 pim_show_interface_traffic_single(vrf
->info
, vty
,
5561 argv
[idx
]->arg
, uj
);
5563 pim_show_interface_traffic(vrf
->info
, vty
, uj
);
5568 DEFUN (show_ip_pim_bsm_db
,
5569 show_ip_pim_bsm_db_cmd
,
5570 "show ip pim bsm-database [vrf NAME] [json]",
5574 "PIM cached bsm packets information\n"
5579 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5580 bool uj
= use_json(argc
, argv
);
5585 pim_show_bsm_db(vrf
->info
, vty
, uj
);
5589 DEFUN (show_ip_pim_bsrp
,
5590 show_ip_pim_bsrp_cmd
,
5591 "show ip pim bsrp-info [vrf NAME] [json]",
5595 "PIM cached group-rp mappings information\n"
5600 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5601 bool uj
= use_json(argc
, argv
);
5606 pim_show_group_rp_mappings_info(vrf
->info
, vty
, uj
);
5611 DEFUN (show_ip_pim_statistics
,
5612 show_ip_pim_statistics_cmd
,
5613 "show ip pim [vrf NAME] statistics [interface WORD] [json]",
5624 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5625 bool uj
= use_json(argc
, argv
);
5630 if (argv_find(argv
, argc
, "WORD", &idx
))
5631 pim_show_statistics(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
5633 pim_show_statistics(vrf
->info
, vty
, NULL
, uj
);
5638 static void show_multicast_interfaces(struct pim_instance
*pim
, struct vty
*vty
)
5640 struct interface
*ifp
;
5645 "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut\n");
5647 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
5648 struct pim_interface
*pim_ifp
;
5649 struct in_addr ifaddr
;
5650 struct sioc_vif_req vreq
;
5652 pim_ifp
= ifp
->info
;
5657 memset(&vreq
, 0, sizeof(vreq
));
5658 vreq
.vifi
= pim_ifp
->mroute_vif_index
;
5660 if (ioctl(pim
->mroute_socket
, SIOCGETVIFCNT
, &vreq
)) {
5662 "ioctl(SIOCGETVIFCNT=%lu) failure for interface %s vif_index=%d: errno=%d: %s",
5663 (unsigned long)SIOCGETVIFCNT
, ifp
->name
,
5664 pim_ifp
->mroute_vif_index
, errno
,
5665 safe_strerror(errno
));
5668 ifaddr
= pim_ifp
->primary_address
;
5670 vty_out(vty
, "%-16s %-15s %3d %3d %7lu %7lu %10lu %10lu\n",
5671 ifp
->name
, inet_ntoa(ifaddr
), ifp
->ifindex
,
5672 pim_ifp
->mroute_vif_index
, (unsigned long)vreq
.icount
,
5673 (unsigned long)vreq
.ocount
, (unsigned long)vreq
.ibytes
,
5674 (unsigned long)vreq
.obytes
);
5678 static void pim_cmd_show_ip_multicast_helper(struct pim_instance
*pim
,
5681 struct vrf
*vrf
= pim
->vrf
;
5682 time_t now
= pim_time_monotonic_sec();
5688 vty_out(vty
, "Router MLAG Role: %s\n",
5689 mlag_role2str(router
->mlag_role
, mlag_role
, sizeof(mlag_role
)));
5690 vty_out(vty
, "Mroute socket descriptor:");
5692 vty_out(vty
, " %d(%s)\n", pim
->mroute_socket
, vrf
->name
);
5694 pim_time_uptime(uptime
, sizeof(uptime
),
5695 now
- pim
->mroute_socket_creation
);
5696 vty_out(vty
, "Mroute socket uptime: %s\n", uptime
);
5700 pim_zebra_zclient_update(vty
);
5701 pim_zlookup_show_ip_multicast(vty
);
5704 vty_out(vty
, "Maximum highest VifIndex: %d\n", PIM_MAX_USABLE_VIFS
);
5707 vty_out(vty
, "Upstream Join Timer: %d secs\n", router
->t_periodic
);
5708 vty_out(vty
, "Join/Prune Holdtime: %d secs\n", PIM_JP_HOLDTIME
);
5709 vty_out(vty
, "PIM ECMP: %s\n", pim
->ecmp_enable
? "Enable" : "Disable");
5710 vty_out(vty
, "PIM ECMP Rebalance: %s\n",
5711 pim
->ecmp_rebalance_enable
? "Enable" : "Disable");
5715 show_rpf_refresh_stats(vty
, pim
, now
, NULL
);
5719 show_scan_oil_stats(pim
, vty
, now
);
5721 show_multicast_interfaces(pim
, vty
);
5724 DEFUN (show_ip_multicast
,
5725 show_ip_multicast_cmd
,
5726 "show ip multicast [vrf NAME]",
5730 "Multicast global information\n")
5733 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5738 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
5743 DEFUN (show_ip_multicast_vrf_all
,
5744 show_ip_multicast_vrf_all_cmd
,
5745 "show ip multicast vrf all",
5749 "Multicast global information\n")
5751 bool uj
= use_json(argc
, argv
);
5757 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5761 vty_out(vty
, " \"%s\": ", vrf
->name
);
5764 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5765 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
5768 vty_out(vty
, "}\n");
5773 static void show_mroute(struct pim_instance
*pim
, struct vty
*vty
,
5774 struct prefix_sg
*sg
, bool fill
, bool uj
)
5776 struct listnode
*node
;
5777 struct channel_oil
*c_oil
;
5778 struct static_route
*s_route
;
5780 json_object
*json
= NULL
;
5781 json_object
*json_group
= NULL
;
5782 json_object
*json_source
= NULL
;
5783 json_object
*json_oil
= NULL
;
5784 json_object
*json_ifp_out
= NULL
;
5787 char grp_str
[INET_ADDRSTRLEN
];
5788 char src_str
[INET_ADDRSTRLEN
];
5789 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
5790 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
5792 struct interface
*ifp_in
;
5794 char state_str
[PIM_REG_STATE_STR_LEN
];
5795 char mroute_uptime
[10];
5798 json
= json_object_new_object();
5800 vty_out(vty
, "IP Multicast Routing Table\n");
5801 vty_out(vty
, "Flags: S- Sparse, C - Connected, P - Pruned\n");
5803 " R - RP-bit set, F - Register flag, T - SPT-bit set\n");
5805 "\nSource Group Flags Proto Input Output TTL Uptime\n");
5808 now
= pim_time_monotonic_sec();
5810 /* print list of PIM and IGMP routes */
5811 frr_each (rb_pim_oil
, &pim
->channel_oil_head
, c_oil
) {
5814 if (!c_oil
->installed
&& !uj
)
5817 if (sg
->grp
.s_addr
!= 0 &&
5818 sg
->grp
.s_addr
!= c_oil
->oil
.mfcc_mcastgrp
.s_addr
)
5820 if (sg
->src
.s_addr
!= 0 &&
5821 sg
->src
.s_addr
!= c_oil
->oil
.mfcc_origin
.s_addr
)
5824 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
5826 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
5829 strlcpy(state_str
, "S", sizeof(state_str
));
5830 /* When a non DR receives a igmp join, it creates a (*,G)
5831 * channel_oil without any upstream creation */
5833 if (PIM_UPSTREAM_FLAG_TEST_SRC_IGMP(c_oil
->up
->flags
))
5834 strlcat(state_str
, "C", sizeof(state_str
));
5835 if (pim_upstream_is_sg_rpt(c_oil
->up
))
5836 strlcat(state_str
, "R", sizeof(state_str
));
5837 if (PIM_UPSTREAM_FLAG_TEST_FHR(c_oil
->up
->flags
))
5838 strlcat(state_str
, "F", sizeof(state_str
));
5839 if (c_oil
->up
->sptbit
== PIM_UPSTREAM_SPTBIT_TRUE
)
5840 strlcat(state_str
, "T", sizeof(state_str
));
5842 if (pim_channel_oil_empty(c_oil
))
5843 strlcat(state_str
, "P", sizeof(state_str
));
5845 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
5848 strlcpy(in_ifname
, ifp_in
->name
, sizeof(in_ifname
));
5850 strlcpy(in_ifname
, "<iif?>", sizeof(in_ifname
));
5853 pim_time_uptime(mroute_uptime
, sizeof(mroute_uptime
),
5854 now
- c_oil
->mroute_creation
);
5858 /* Find the group, create it if it doesn't exist */
5859 json_object_object_get_ex(json
, grp_str
, &json_group
);
5862 json_group
= json_object_new_object();
5863 json_object_object_add(json
, grp_str
,
5867 /* Find the source nested under the group, create it if
5870 json_object_object_get_ex(json_group
, src_str
,
5874 json_source
= json_object_new_object();
5875 json_object_object_add(json_group
, src_str
,
5879 /* Find the inbound interface nested under the source,
5880 * create it if it doesn't exist */
5881 json_object_int_add(json_source
, "installed",
5883 json_object_int_add(json_source
, "refCount",
5884 c_oil
->oil_ref_count
);
5885 json_object_int_add(json_source
, "oilSize",
5887 json_object_int_add(json_source
, "OilInheritedRescan",
5888 c_oil
->oil_inherited_rescan
);
5889 json_object_string_add(json_source
, "iif", in_ifname
);
5890 json_object_string_add(json_source
, "upTime",
5895 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
5897 struct interface
*ifp_out
;
5900 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
5904 /* do not display muted OIFs */
5905 if (c_oil
->oif_flags
[oif_vif_index
]
5906 & PIM_OIF_FLAG_MUTE
)
5909 if (c_oil
->oil
.mfcc_parent
== oif_vif_index
&&
5910 !pim_mroute_allow_iif_in_oil(c_oil
,
5914 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
5918 strlcpy(out_ifname
, ifp_out
->name
, sizeof(out_ifname
));
5920 strlcpy(out_ifname
, "<oif?>", sizeof(out_ifname
));
5923 json_ifp_out
= json_object_new_object();
5924 json_object_string_add(json_ifp_out
, "source",
5926 json_object_string_add(json_ifp_out
, "group",
5929 if (c_oil
->oif_flags
[oif_vif_index
]
5930 & PIM_OIF_FLAG_PROTO_PIM
)
5931 json_object_boolean_true_add(
5932 json_ifp_out
, "protocolPim");
5934 if (c_oil
->oif_flags
[oif_vif_index
]
5935 & PIM_OIF_FLAG_PROTO_IGMP
)
5936 json_object_boolean_true_add(
5937 json_ifp_out
, "protocolIgmp");
5939 if (c_oil
->oif_flags
[oif_vif_index
]
5940 & PIM_OIF_FLAG_PROTO_VXLAN
)
5941 json_object_boolean_true_add(
5942 json_ifp_out
, "protocolVxlan");
5944 if (c_oil
->oif_flags
[oif_vif_index
]
5945 & PIM_OIF_FLAG_PROTO_STAR
)
5946 json_object_boolean_true_add(
5948 "protocolInherited");
5950 json_object_string_add(json_ifp_out
,
5953 json_object_int_add(json_ifp_out
, "iVifI",
5954 c_oil
->oil
.mfcc_parent
);
5955 json_object_string_add(json_ifp_out
,
5956 "outboundInterface",
5958 json_object_int_add(json_ifp_out
, "oVifI",
5960 json_object_int_add(json_ifp_out
, "ttl", ttl
);
5961 json_object_string_add(json_ifp_out
, "upTime",
5964 json_oil
= json_object_new_object();
5965 json_object_object_add(json_source
,
5968 json_object_object_add(json_oil
, out_ifname
,
5971 if (c_oil
->oif_flags
[oif_vif_index
]
5972 & PIM_OIF_FLAG_PROTO_PIM
) {
5973 strlcpy(proto
, "PIM", sizeof(proto
));
5976 if (c_oil
->oif_flags
[oif_vif_index
]
5977 & PIM_OIF_FLAG_PROTO_IGMP
) {
5978 strlcpy(proto
, "IGMP", sizeof(proto
));
5981 if (c_oil
->oif_flags
[oif_vif_index
]
5982 & PIM_OIF_FLAG_PROTO_VXLAN
) {
5983 strlcpy(proto
, "VxLAN", sizeof(proto
));
5986 if (c_oil
->oif_flags
[oif_vif_index
]
5987 & PIM_OIF_FLAG_PROTO_STAR
) {
5988 strlcpy(proto
, "STAR", sizeof(proto
));
5992 "%-15s %-15s %-15s %-6s %-16s %-16s %-3d %8s\n",
5993 src_str
, grp_str
, state_str
, proto
,
5994 in_ifname
, out_ifname
, ttl
,
6000 in_ifname
[0] = '\0';
6001 state_str
[0] = '\0';
6002 mroute_uptime
[0] = '\0';
6008 if (!uj
&& !found_oif
) {
6010 "%-15s %-15s %-15s %-6s %-16s %-16s %-3d %8s\n",
6011 src_str
, grp_str
, state_str
, "none", in_ifname
,
6012 "none", 0, "--:--:--");
6016 /* Print list of static routes */
6017 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
6020 if (!s_route
->c_oil
.installed
)
6023 pim_inet4_dump("<group?>", s_route
->group
, grp_str
,
6025 pim_inet4_dump("<source?>", s_route
->source
, src_str
,
6027 ifp_in
= pim_if_find_by_vif_index(pim
, s_route
->iif
);
6031 strlcpy(in_ifname
, ifp_in
->name
, sizeof(in_ifname
));
6033 strlcpy(in_ifname
, "<iif?>", sizeof(in_ifname
));
6037 /* Find the group, create it if it doesn't exist */
6038 json_object_object_get_ex(json
, grp_str
, &json_group
);
6041 json_group
= json_object_new_object();
6042 json_object_object_add(json
, grp_str
,
6046 /* Find the source nested under the group, create it if
6047 * it doesn't exist */
6048 json_object_object_get_ex(json_group
, src_str
,
6052 json_source
= json_object_new_object();
6053 json_object_object_add(json_group
, src_str
,
6057 json_object_string_add(json_source
, "iif", in_ifname
);
6060 strlcpy(proto
, "STATIC", sizeof(proto
));
6063 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
6065 struct interface
*ifp_out
;
6066 char oif_uptime
[10];
6069 ttl
= s_route
->oif_ttls
[oif_vif_index
];
6073 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
6075 oif_uptime
, sizeof(oif_uptime
),
6078 .oif_creation
[oif_vif_index
]);
6082 strlcpy(out_ifname
, ifp_out
->name
, sizeof(out_ifname
));
6084 strlcpy(out_ifname
, "<oif?>", sizeof(out_ifname
));
6087 json_ifp_out
= json_object_new_object();
6088 json_object_string_add(json_ifp_out
, "source",
6090 json_object_string_add(json_ifp_out
, "group",
6092 json_object_boolean_true_add(json_ifp_out
,
6094 json_object_string_add(json_ifp_out
,
6097 json_object_int_add(
6098 json_ifp_out
, "iVifI",
6099 s_route
->c_oil
.oil
.mfcc_parent
);
6100 json_object_string_add(json_ifp_out
,
6101 "outboundInterface",
6103 json_object_int_add(json_ifp_out
, "oVifI",
6105 json_object_int_add(json_ifp_out
, "ttl", ttl
);
6106 json_object_string_add(json_ifp_out
, "upTime",
6109 json_oil
= json_object_new_object();
6110 json_object_object_add(json_source
,
6113 json_object_object_add(json_oil
, out_ifname
,
6117 "%-15s %-15s %-6s %-16s %-16s %-3d %8s %s\n",
6118 src_str
, grp_str
, proto
, in_ifname
,
6119 out_ifname
, ttl
, oif_uptime
,
6121 if (first
&& !fill
) {
6124 in_ifname
[0] = '\0';
6130 if (!uj
&& !found_oif
) {
6132 "%-15s %-15s %-6s %-16s %-16s %-3d %8s %s\n",
6133 src_str
, grp_str
, proto
, in_ifname
, "none", 0,
6134 "--:--:--", pim
->vrf
->name
);
6139 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
6140 json
, JSON_C_TO_STRING_PRETTY
));
6141 json_object_free(json
);
6145 DEFPY (show_ip_mroute
,
6147 "show ip mroute [vrf NAME] [A.B.C.D$s_or_g [A.B.C.D$g]] [fill$fill] [json$json]",
6152 "The Source or Group\n"
6154 "Fill in Assumed data\n"
6157 struct prefix_sg sg
= {0};
6158 struct pim_instance
*pim
;
6161 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
6164 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
6167 pim
= pim_get_pim_instance(v
->vrf_id
);
6170 vty_out(vty
, "%% Unable to find pim instance\n");
6174 if (s_or_g
.s_addr
!= 0) {
6175 if (g
.s_addr
!= 0) {
6181 show_mroute(pim
, vty
, &sg
, !!fill
, !!json
);
6185 DEFUN (show_ip_mroute_vrf_all
,
6186 show_ip_mroute_vrf_all_cmd
,
6187 "show ip mroute vrf all [fill] [json]",
6192 "Fill in Assumed data\n"
6195 struct prefix_sg sg
= {0};
6196 bool uj
= use_json(argc
, argv
);
6202 if (argv_find(argv
, argc
, "fill", &idx
))
6207 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
6211 vty_out(vty
, " \"%s\": ", vrf
->name
);
6214 vty_out(vty
, "VRF: %s\n", vrf
->name
);
6215 show_mroute(vrf
->info
, vty
, &sg
, fill
, uj
);
6218 vty_out(vty
, "}\n");
6223 DEFUN (clear_ip_mroute_count
,
6224 clear_ip_mroute_count_cmd
,
6225 "clear ip mroute [vrf NAME] count",
6230 "Route and packet count data\n")
6233 struct listnode
*node
;
6234 struct channel_oil
*c_oil
;
6235 struct static_route
*sr
;
6236 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6237 struct pim_instance
*pim
;
6243 frr_each(rb_pim_oil
, &pim
->channel_oil_head
, c_oil
) {
6244 if (!c_oil
->installed
)
6247 pim_mroute_update_counters(c_oil
);
6248 c_oil
->cc
.origpktcnt
= c_oil
->cc
.pktcnt
;
6249 c_oil
->cc
.origbytecnt
= c_oil
->cc
.bytecnt
;
6250 c_oil
->cc
.origwrong_if
= c_oil
->cc
.wrong_if
;
6253 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, sr
)) {
6254 if (!sr
->c_oil
.installed
)
6257 pim_mroute_update_counters(&sr
->c_oil
);
6259 sr
->c_oil
.cc
.origpktcnt
= sr
->c_oil
.cc
.pktcnt
;
6260 sr
->c_oil
.cc
.origbytecnt
= sr
->c_oil
.cc
.bytecnt
;
6261 sr
->c_oil
.cc
.origwrong_if
= sr
->c_oil
.cc
.wrong_if
;
6266 static void show_mroute_count(struct pim_instance
*pim
, struct vty
*vty
)
6268 struct listnode
*node
;
6269 struct channel_oil
*c_oil
;
6270 struct static_route
*sr
;
6275 "Source Group LastUsed Packets Bytes WrongIf \n");
6277 /* Print PIM and IGMP route counts */
6278 frr_each (rb_pim_oil
, &pim
->channel_oil_head
, c_oil
) {
6279 char group_str
[INET_ADDRSTRLEN
];
6280 char source_str
[INET_ADDRSTRLEN
];
6282 if (!c_oil
->installed
)
6285 pim_mroute_update_counters(c_oil
);
6287 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, group_str
,
6289 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, source_str
,
6290 sizeof(source_str
));
6292 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
6293 source_str
, group_str
, c_oil
->cc
.lastused
/ 100,
6294 c_oil
->cc
.pktcnt
- c_oil
->cc
.origpktcnt
,
6295 c_oil
->cc
.bytecnt
- c_oil
->cc
.origbytecnt
,
6296 c_oil
->cc
.wrong_if
- c_oil
->cc
.origwrong_if
);
6299 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, sr
)) {
6300 char group_str
[INET_ADDRSTRLEN
];
6301 char source_str
[INET_ADDRSTRLEN
];
6303 if (!sr
->c_oil
.installed
)
6306 pim_mroute_update_counters(&sr
->c_oil
);
6308 pim_inet4_dump("<group?>", sr
->c_oil
.oil
.mfcc_mcastgrp
,
6309 group_str
, sizeof(group_str
));
6310 pim_inet4_dump("<source?>", sr
->c_oil
.oil
.mfcc_origin
,
6311 source_str
, sizeof(source_str
));
6313 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
6314 source_str
, group_str
, sr
->c_oil
.cc
.lastused
,
6315 sr
->c_oil
.cc
.pktcnt
- sr
->c_oil
.cc
.origpktcnt
,
6316 sr
->c_oil
.cc
.bytecnt
- sr
->c_oil
.cc
.origbytecnt
,
6317 sr
->c_oil
.cc
.wrong_if
- sr
->c_oil
.cc
.origwrong_if
);
6321 DEFUN (show_ip_mroute_count
,
6322 show_ip_mroute_count_cmd
,
6323 "show ip mroute [vrf NAME] count",
6328 "Route and packet count data\n")
6331 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6336 show_mroute_count(vrf
->info
, vty
);
6340 DEFUN (show_ip_mroute_count_vrf_all
,
6341 show_ip_mroute_count_vrf_all_cmd
,
6342 "show ip mroute vrf all count",
6347 "Route and packet count data\n")
6349 bool uj
= use_json(argc
, argv
);
6355 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
6359 vty_out(vty
, " \"%s\": ", vrf
->name
);
6362 vty_out(vty
, "VRF: %s\n", vrf
->name
);
6363 show_mroute_count(vrf
->info
, vty
);
6366 vty_out(vty
, "}\n");
6371 static void show_mroute_summary(struct pim_instance
*pim
, struct vty
*vty
)
6373 struct listnode
*node
;
6374 struct channel_oil
*c_oil
;
6375 struct static_route
*s_route
;
6376 uint32_t starg_sw_mroute_cnt
= 0;
6377 uint32_t sg_sw_mroute_cnt
= 0;
6378 uint32_t starg_hw_mroute_cnt
= 0;
6379 uint32_t sg_hw_mroute_cnt
= 0;
6381 vty_out(vty
, "Mroute Type Installed/Total\n");
6383 frr_each (rb_pim_oil
, &pim
->channel_oil_head
, c_oil
) {
6384 if (!c_oil
->installed
) {
6385 if (c_oil
->oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
6386 starg_sw_mroute_cnt
++;
6390 if (c_oil
->oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
6391 starg_hw_mroute_cnt
++;
6397 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
6398 if (!s_route
->c_oil
.installed
) {
6399 if (s_route
->c_oil
.oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
6400 starg_sw_mroute_cnt
++;
6404 if (s_route
->c_oil
.oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
6405 starg_hw_mroute_cnt
++;
6411 vty_out(vty
, "%-20s %d/%d\n", "(*, G)", starg_hw_mroute_cnt
,
6412 starg_sw_mroute_cnt
+ starg_hw_mroute_cnt
);
6413 vty_out(vty
, "%-20s %d/%d\n", "(S, G)", sg_hw_mroute_cnt
,
6414 sg_sw_mroute_cnt
+ sg_hw_mroute_cnt
);
6415 vty_out(vty
, "------\n");
6416 vty_out(vty
, "%-20s %d/%d\n", "Total",
6417 (starg_hw_mroute_cnt
+ sg_hw_mroute_cnt
),
6418 (starg_sw_mroute_cnt
+
6419 starg_hw_mroute_cnt
+
6424 DEFUN (show_ip_mroute_summary
,
6425 show_ip_mroute_summary_cmd
,
6426 "show ip mroute [vrf NAME] summary",
6431 "Summary of all mroutes\n")
6434 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6439 show_mroute_summary(vrf
->info
, vty
);
6443 DEFUN (show_ip_mroute_summary_vrf_all
,
6444 show_ip_mroute_summary_vrf_all_cmd
,
6445 "show ip mroute vrf all summary",
6450 "Summary of all mroutes\n")
6454 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
6455 vty_out(vty
, "VRF: %s\n", vrf
->name
);
6456 show_mroute_summary(vrf
->info
, vty
);
6464 "show ip rib [vrf NAME] A.B.C.D",
6469 "Unicast address\n")
6472 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6473 struct in_addr addr
;
6474 const char *addr_str
;
6475 struct pim_nexthop nexthop
;
6476 char nexthop_addr_str
[PREFIX_STRLEN
];
6482 memset(&nexthop
, 0, sizeof(nexthop
));
6483 argv_find(argv
, argc
, "A.B.C.D", &idx
);
6484 addr_str
= argv
[idx
]->arg
;
6485 result
= inet_pton(AF_INET
, addr_str
, &addr
);
6487 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
6488 errno
, safe_strerror(errno
));
6492 if (!pim_nexthop_lookup(vrf
->info
, &nexthop
, addr
, 0)) {
6494 "Failure querying RIB nexthop for unicast address %s\n",
6500 "Address NextHop Interface Metric Preference\n");
6502 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
6503 nexthop_addr_str
, sizeof(nexthop_addr_str
));
6505 vty_out(vty
, "%-15s %-15s %-9s %6d %10d\n", addr_str
, nexthop_addr_str
,
6506 nexthop
.interface
? nexthop
.interface
->name
: "<ifname?>",
6507 nexthop
.mrib_route_metric
, nexthop
.mrib_metric_preference
);
6512 static void show_ssmpingd(struct pim_instance
*pim
, struct vty
*vty
)
6514 struct listnode
*node
;
6515 struct ssmpingd_sock
*ss
;
6519 "Source Socket Address Port Uptime Requests\n");
6521 if (!pim
->ssmpingd_list
)
6524 now
= pim_time_monotonic_sec();
6526 for (ALL_LIST_ELEMENTS_RO(pim
->ssmpingd_list
, node
, ss
)) {
6527 char source_str
[INET_ADDRSTRLEN
];
6529 struct sockaddr_in bind_addr
;
6530 socklen_t len
= sizeof(bind_addr
);
6531 char bind_addr_str
[INET_ADDRSTRLEN
];
6533 pim_inet4_dump("<src?>", ss
->source_addr
, source_str
,
6534 sizeof(source_str
));
6536 if (pim_socket_getsockname(
6537 ss
->sock_fd
, (struct sockaddr
*)&bind_addr
, &len
)) {
6539 "%% Failure reading socket name for ssmpingd source %s on fd=%d\n",
6540 source_str
, ss
->sock_fd
);
6543 pim_inet4_dump("<addr?>", bind_addr
.sin_addr
, bind_addr_str
,
6544 sizeof(bind_addr_str
));
6545 pim_time_uptime(ss_uptime
, sizeof(ss_uptime
),
6546 now
- ss
->creation
);
6548 vty_out(vty
, "%-15s %6d %-15s %5d %8s %8lld\n", source_str
,
6549 ss
->sock_fd
, bind_addr_str
, ntohs(bind_addr
.sin_port
),
6550 ss_uptime
, (long long)ss
->requests
);
6554 DEFUN (show_ip_ssmpingd
,
6555 show_ip_ssmpingd_cmd
,
6556 "show ip ssmpingd [vrf NAME]",
6563 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6568 show_ssmpingd(vrf
->info
, vty
);
6572 static int pim_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
6573 const char *rp
, const char *group
,
6578 result
= pim_rp_new_config(pim
, rp
, group
, plist
);
6580 if (result
== PIM_GROUP_BAD_ADDR_MASK_COMBO
) {
6581 vty_out(vty
, "%% Inconsistent address and mask: %s\n",
6583 return CMD_WARNING_CONFIG_FAILED
;
6586 if (result
== PIM_GROUP_BAD_ADDRESS
) {
6587 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
6588 return CMD_WARNING_CONFIG_FAILED
;
6591 if (result
== PIM_RP_BAD_ADDRESS
) {
6592 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
6593 return CMD_WARNING_CONFIG_FAILED
;
6596 if (result
== PIM_RP_NO_PATH
) {
6597 vty_out(vty
, "%% No Path to RP address specified: %s\n", rp
);
6601 if (result
== PIM_GROUP_OVERLAP
) {
6603 "%% Group range specified cannot exact match another\n");
6604 return CMD_WARNING_CONFIG_FAILED
;
6607 if (result
== PIM_GROUP_PFXLIST_OVERLAP
) {
6609 "%% This group is already covered by a RP prefix-list\n");
6610 return CMD_WARNING_CONFIG_FAILED
;
6613 if (result
== PIM_RP_PFXLIST_IN_USE
) {
6615 "%% The same prefix-list cannot be applied to multiple RPs\n");
6616 return CMD_WARNING_CONFIG_FAILED
;
6622 static int pim_cmd_spt_switchover(struct pim_instance
*pim
,
6623 enum pim_spt_switchover spt
,
6626 pim
->spt
.switchover
= spt
;
6628 switch (pim
->spt
.switchover
) {
6629 case PIM_SPT_IMMEDIATE
:
6630 XFREE(MTYPE_PIM_PLIST_NAME
, pim
->spt
.plist
);
6632 pim_upstream_add_lhr_star_pimreg(pim
);
6634 case PIM_SPT_INFINITY
:
6635 pim_upstream_remove_lhr_star_pimreg(pim
, plist
);
6637 XFREE(MTYPE_PIM_PLIST_NAME
, pim
->spt
.plist
);
6641 XSTRDUP(MTYPE_PIM_PLIST_NAME
, plist
);
6648 DEFUN (ip_pim_spt_switchover_infinity
,
6649 ip_pim_spt_switchover_infinity_cmd
,
6650 "ip pim spt-switchover infinity-and-beyond",
6654 "Never switch to SPT Tree\n")
6656 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6657 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, NULL
);
6660 DEFUN (ip_pim_spt_switchover_infinity_plist
,
6661 ip_pim_spt_switchover_infinity_plist_cmd
,
6662 "ip pim spt-switchover infinity-and-beyond prefix-list WORD",
6666 "Never switch to SPT Tree\n"
6667 "Prefix-List to control which groups to switch\n"
6668 "Prefix-List name\n")
6670 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6671 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, argv
[5]->arg
);
6674 DEFUN (no_ip_pim_spt_switchover_infinity
,
6675 no_ip_pim_spt_switchover_infinity_cmd
,
6676 "no ip pim spt-switchover infinity-and-beyond",
6681 "Never switch to SPT Tree\n")
6683 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6684 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
6687 DEFUN (no_ip_pim_spt_switchover_infinity_plist
,
6688 no_ip_pim_spt_switchover_infinity_plist_cmd
,
6689 "no ip pim spt-switchover infinity-and-beyond prefix-list WORD",
6694 "Never switch to SPT Tree\n"
6695 "Prefix-List to control which groups to switch\n"
6696 "Prefix-List name\n")
6698 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6699 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
6702 DEFPY (pim_register_accept_list
,
6703 pim_register_accept_list_cmd
,
6704 "[no] ip pim register-accept-list WORD$word",
6708 "Only accept registers from a specific source prefix list\n"
6709 "Prefix-List name\n")
6711 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6714 XFREE(MTYPE_PIM_PLIST_NAME
, pim
->register_plist
);
6716 XFREE(MTYPE_PIM_PLIST_NAME
, pim
->register_plist
);
6717 pim
->register_plist
= XSTRDUP(MTYPE_PIM_PLIST_NAME
, word
);
6722 DEFUN (ip_pim_joinprune_time
,
6723 ip_pim_joinprune_time_cmd
,
6724 "ip pim join-prune-interval (60-600)",
6726 "pim multicast routing\n"
6727 "Join Prune Send Interval\n"
6730 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6731 router
->t_periodic
= atoi(argv
[3]->arg
);
6735 DEFUN (no_ip_pim_joinprune_time
,
6736 no_ip_pim_joinprune_time_cmd
,
6737 "no ip pim join-prune-interval (60-600)",
6740 "pim multicast routing\n"
6741 "Join Prune Send Interval\n"
6744 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6745 router
->t_periodic
= PIM_DEFAULT_T_PERIODIC
;
6749 DEFUN (ip_pim_register_suppress
,
6750 ip_pim_register_suppress_cmd
,
6751 "ip pim register-suppress-time (5-60000)",
6753 "pim multicast routing\n"
6754 "Register Suppress Timer\n"
6757 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6758 router
->register_suppress_time
= atoi(argv
[3]->arg
);
6762 DEFUN (no_ip_pim_register_suppress
,
6763 no_ip_pim_register_suppress_cmd
,
6764 "no ip pim register-suppress-time (5-60000)",
6767 "pim multicast routing\n"
6768 "Register Suppress Timer\n"
6771 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6772 router
->register_suppress_time
= PIM_REGISTER_SUPPRESSION_TIME_DEFAULT
;
6776 DEFUN (ip_pim_rp_keep_alive
,
6777 ip_pim_rp_keep_alive_cmd
,
6778 "ip pim rp keep-alive-timer (31-60000)",
6780 "pim multicast routing\n"
6782 "Keep alive Timer\n"
6785 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6786 pim
->rp_keep_alive_time
= atoi(argv
[4]->arg
);
6790 DEFUN (no_ip_pim_rp_keep_alive
,
6791 no_ip_pim_rp_keep_alive_cmd
,
6792 "no ip pim rp keep-alive-timer (31-60000)",
6795 "pim multicast routing\n"
6797 "Keep alive Timer\n"
6800 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6801 pim
->rp_keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
6805 DEFUN (ip_pim_keep_alive
,
6806 ip_pim_keep_alive_cmd
,
6807 "ip pim keep-alive-timer (31-60000)",
6809 "pim multicast routing\n"
6810 "Keep alive Timer\n"
6813 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6814 pim
->keep_alive_time
= atoi(argv
[3]->arg
);
6818 DEFUN (no_ip_pim_keep_alive
,
6819 no_ip_pim_keep_alive_cmd
,
6820 "no ip pim keep-alive-timer (31-60000)",
6823 "pim multicast routing\n"
6824 "Keep alive Timer\n"
6827 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6828 pim
->keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
6832 DEFUN (ip_pim_packets
,
6834 "ip pim packets (1-100)",
6836 "pim multicast routing\n"
6837 "packets to process at one time per fd\n"
6838 "Number of packets\n")
6840 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6841 router
->packet_process
= atoi(argv
[3]->arg
);
6845 DEFUN (no_ip_pim_packets
,
6846 no_ip_pim_packets_cmd
,
6847 "no ip pim packets (1-100)",
6850 "pim multicast routing\n"
6851 "packets to process at one time per fd\n"
6852 "Number of packets\n")
6854 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6855 router
->packet_process
= PIM_DEFAULT_PACKET_PROCESS
;
6859 DEFUN (ip_pim_v6_secondary
,
6860 ip_pim_v6_secondary_cmd
,
6861 "ip pim send-v6-secondary",
6863 "pim multicast routing\n"
6864 "Send v6 secondary addresses\n")
6866 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6867 pim
->send_v6_secondary
= 1;
6872 DEFUN (no_ip_pim_v6_secondary
,
6873 no_ip_pim_v6_secondary_cmd
,
6874 "no ip pim send-v6-secondary",
6877 "pim multicast routing\n"
6878 "Send v6 secondary addresses\n")
6880 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6881 pim
->send_v6_secondary
= 0;
6888 "ip pim rp A.B.C.D [A.B.C.D/M]",
6890 "pim multicast routing\n"
6892 "ip address of RP\n"
6893 "Group Address range to cover\n")
6895 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6898 if (argc
== (idx_ipv4
+ 1))
6899 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
6902 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
6903 argv
[idx_ipv4
+ 1]->arg
, NULL
);
6906 DEFUN (ip_pim_rp_prefix_list
,
6907 ip_pim_rp_prefix_list_cmd
,
6908 "ip pim rp A.B.C.D prefix-list WORD",
6910 "pim multicast routing\n"
6912 "ip address of RP\n"
6913 "group prefix-list filter\n"
6914 "Name of a prefix-list\n")
6916 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6917 return pim_rp_cmd_worker(pim
, vty
, argv
[3]->arg
, NULL
, argv
[5]->arg
);
6920 static int pim_no_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
6921 const char *rp
, const char *group
,
6924 int result
= pim_rp_del_config(pim
, rp
, group
, plist
);
6926 if (result
== PIM_GROUP_BAD_ADDRESS
) {
6927 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
6928 return CMD_WARNING_CONFIG_FAILED
;
6931 if (result
== PIM_RP_BAD_ADDRESS
) {
6932 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
6933 return CMD_WARNING_CONFIG_FAILED
;
6936 if (result
== PIM_RP_NOT_FOUND
) {
6937 vty_out(vty
, "%% Unable to find specified RP\n");
6938 return CMD_WARNING_CONFIG_FAILED
;
6944 DEFUN (no_ip_pim_rp
,
6946 "no ip pim rp A.B.C.D [A.B.C.D/M]",
6949 "pim multicast routing\n"
6951 "ip address of RP\n"
6952 "Group Address range to cover\n")
6954 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6955 int idx_ipv4
= 4, idx_group
= 0;
6957 if (argv_find(argv
, argc
, "A.B.C.D/M", &idx_group
))
6958 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
6959 argv
[idx_group
]->arg
, NULL
);
6961 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
6965 DEFUN (no_ip_pim_rp_prefix_list
,
6966 no_ip_pim_rp_prefix_list_cmd
,
6967 "no ip pim rp A.B.C.D prefix-list WORD",
6970 "pim multicast routing\n"
6972 "ip address of RP\n"
6973 "group prefix-list filter\n"
6974 "Name of a prefix-list\n")
6976 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6977 return pim_no_rp_cmd_worker(pim
, vty
, argv
[4]->arg
, NULL
, argv
[6]->arg
);
6980 static int pim_ssm_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
6983 int result
= pim_ssm_range_set(pim
, pim
->vrf_id
, plist
);
6984 int ret
= CMD_WARNING_CONFIG_FAILED
;
6986 if (result
== PIM_SSM_ERR_NONE
)
6990 case PIM_SSM_ERR_NO_VRF
:
6991 vty_out(vty
, "%% VRF doesn't exist\n");
6993 case PIM_SSM_ERR_DUP
:
6994 vty_out(vty
, "%% duplicate config\n");
6998 vty_out(vty
, "%% ssm range config failed\n");
7004 DEFUN (ip_pim_ssm_prefix_list
,
7005 ip_pim_ssm_prefix_list_cmd
,
7006 "ip pim ssm prefix-list WORD",
7008 "pim multicast routing\n"
7009 "Source Specific Multicast\n"
7010 "group range prefix-list filter\n"
7011 "Name of a prefix-list\n")
7013 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7014 return pim_ssm_cmd_worker(pim
, vty
, argv
[4]->arg
);
7017 DEFUN (no_ip_pim_ssm_prefix_list
,
7018 no_ip_pim_ssm_prefix_list_cmd
,
7019 "no ip pim ssm prefix-list",
7022 "pim multicast routing\n"
7023 "Source Specific Multicast\n"
7024 "group range prefix-list filter\n")
7026 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7027 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
7030 DEFUN (no_ip_pim_ssm_prefix_list_name
,
7031 no_ip_pim_ssm_prefix_list_name_cmd
,
7032 "no ip pim ssm prefix-list WORD",
7035 "pim multicast routing\n"
7036 "Source Specific Multicast\n"
7037 "group range prefix-list filter\n"
7038 "Name of a prefix-list\n")
7040 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7041 struct pim_ssm
*ssm
= pim
->ssm_info
;
7043 if (ssm
->plist_name
&& !strcmp(ssm
->plist_name
, argv
[5]->arg
))
7044 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
7046 vty_out(vty
, "%% pim ssm prefix-list %s doesn't exist\n", argv
[5]->arg
);
7048 return CMD_WARNING_CONFIG_FAILED
;
7051 static void ip_pim_ssm_show_group_range(struct pim_instance
*pim
,
7052 struct vty
*vty
, bool uj
)
7054 struct pim_ssm
*ssm
= pim
->ssm_info
;
7055 const char *range_str
=
7056 ssm
->plist_name
? ssm
->plist_name
: PIM_SSM_STANDARD_RANGE
;
7060 json
= json_object_new_object();
7061 json_object_string_add(json
, "ssmGroups", range_str
);
7062 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
7063 json
, JSON_C_TO_STRING_PRETTY
));
7064 json_object_free(json
);
7066 vty_out(vty
, "SSM group range : %s\n", range_str
);
7069 DEFUN (show_ip_pim_ssm_range
,
7070 show_ip_pim_ssm_range_cmd
,
7071 "show ip pim [vrf NAME] group-type [json]",
7080 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
7081 bool uj
= use_json(argc
, argv
);
7086 ip_pim_ssm_show_group_range(vrf
->info
, vty
, uj
);
7091 static void ip_pim_ssm_show_group_type(struct pim_instance
*pim
,
7092 struct vty
*vty
, bool uj
,
7095 struct in_addr group_addr
;
7096 const char *type_str
;
7099 result
= inet_pton(AF_INET
, group
, &group_addr
);
7101 type_str
= "invalid";
7103 if (pim_is_group_224_4(group_addr
))
7105 pim_is_grp_ssm(pim
, group_addr
) ? "SSM" : "ASM";
7107 type_str
= "not-multicast";
7112 json
= json_object_new_object();
7113 json_object_string_add(json
, "groupType", type_str
);
7114 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
7115 json
, JSON_C_TO_STRING_PRETTY
));
7116 json_object_free(json
);
7118 vty_out(vty
, "Group type : %s\n", type_str
);
7121 DEFUN (show_ip_pim_group_type
,
7122 show_ip_pim_group_type_cmd
,
7123 "show ip pim [vrf NAME] group-type A.B.C.D [json]",
7128 "multicast group type\n"
7133 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
7134 bool uj
= use_json(argc
, argv
);
7139 argv_find(argv
, argc
, "A.B.C.D", &idx
);
7140 ip_pim_ssm_show_group_type(vrf
->info
, vty
, uj
, argv
[idx
]->arg
);
7145 DEFUN (show_ip_pim_bsr
,
7146 show_ip_pim_bsr_cmd
,
7147 "show ip pim bsr [json]",
7151 "boot-strap router information\n"
7155 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
7156 bool uj
= use_json(argc
, argv
);
7161 pim_show_bsr(vrf
->info
, vty
, uj
);
7168 "ip ssmpingd [A.B.C.D]",
7173 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7176 struct in_addr source_addr
;
7177 const char *source_str
= (argc
== 3) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
7179 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
7181 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
7182 source_str
, errno
, safe_strerror(errno
));
7183 return CMD_WARNING_CONFIG_FAILED
;
7186 result
= pim_ssmpingd_start(pim
, source_addr
);
7188 vty_out(vty
, "%% Failure starting ssmpingd for source %s: %d\n",
7189 source_str
, result
);
7190 return CMD_WARNING_CONFIG_FAILED
;
7196 DEFUN (no_ip_ssmpingd
,
7198 "no ip ssmpingd [A.B.C.D]",
7204 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7207 struct in_addr source_addr
;
7208 const char *source_str
= (argc
== 4) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
7210 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
7212 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
7213 source_str
, errno
, safe_strerror(errno
));
7214 return CMD_WARNING_CONFIG_FAILED
;
7217 result
= pim_ssmpingd_stop(pim
, source_addr
);
7219 vty_out(vty
, "%% Failure stopping ssmpingd for source %s: %d\n",
7220 source_str
, result
);
7221 return CMD_WARNING_CONFIG_FAILED
;
7231 "pim multicast routing\n"
7232 "Enable PIM ECMP \n")
7234 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7235 pim
->ecmp_enable
= true;
7240 DEFUN (no_ip_pim_ecmp
,
7245 "pim multicast routing\n"
7246 "Disable PIM ECMP \n")
7248 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7249 pim
->ecmp_enable
= false;
7254 DEFUN (ip_pim_ecmp_rebalance
,
7255 ip_pim_ecmp_rebalance_cmd
,
7256 "ip pim ecmp rebalance",
7258 "pim multicast routing\n"
7259 "Enable PIM ECMP \n"
7260 "Enable PIM ECMP Rebalance\n")
7262 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7263 pim
->ecmp_enable
= true;
7264 pim
->ecmp_rebalance_enable
= true;
7269 DEFUN (no_ip_pim_ecmp_rebalance
,
7270 no_ip_pim_ecmp_rebalance_cmd
,
7271 "no ip pim ecmp rebalance",
7274 "pim multicast routing\n"
7275 "Disable PIM ECMP \n"
7276 "Disable PIM ECMP Rebalance\n")
7278 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7279 pim
->ecmp_rebalance_enable
= false;
7284 static int pim_cmd_igmp_start(struct vty
*vty
, struct interface
*ifp
)
7286 struct pim_interface
*pim_ifp
;
7287 struct pim_instance
*pim
;
7288 uint8_t need_startup
= 0;
7290 pim_ifp
= ifp
->info
;
7293 pim
= pim_get_pim_instance(ifp
->vrf_id
);
7294 /* Limit mcast interfaces to number of vifs available */
7295 if (pim
->mcast_if_count
== MAXVIFS
) {
7297 "Max multicast interfaces(%d) Reached. Could not enable IGMP on interface %s\n",
7298 MAXVIFS
, ifp
->name
);
7299 return CMD_WARNING_CONFIG_FAILED
;
7301 (void)pim_if_new(ifp
, true, false, false, false);
7304 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
7305 PIM_IF_DO_IGMP(pim_ifp
->options
);
7310 /* 'ip igmp' executed multiple times, with need_startup
7311 avoid multiple if add all and membership refresh */
7313 pim_if_addr_add_all(ifp
);
7314 pim_if_membership_refresh(ifp
);
7320 DEFUN (interface_ip_igmp
,
7321 interface_ip_igmp_cmd
,
7326 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7328 return pim_cmd_igmp_start(vty
, ifp
);
7331 DEFUN (interface_no_ip_igmp
,
7332 interface_no_ip_igmp_cmd
,
7338 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7339 struct pim_interface
*pim_ifp
= ifp
->info
;
7344 PIM_IF_DONT_IGMP(pim_ifp
->options
);
7346 pim_if_membership_clear(ifp
);
7348 pim_if_addr_del_all_igmp(ifp
);
7350 if (!PIM_IF_TEST_PIM(pim_ifp
->options
)) {
7357 DEFUN (interface_ip_igmp_join
,
7358 interface_ip_igmp_join_cmd
,
7359 "ip igmp join A.B.C.D [A.B.C.D]",
7362 "IGMP join multicast group\n"
7363 "Multicast group address\n"
7366 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7369 const char *group_str
;
7370 const char *source_str
;
7371 struct in_addr group_addr
;
7372 struct in_addr source_addr
;
7376 group_str
= argv
[idx_ipv4
]->arg
;
7377 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
7379 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
7380 errno
, safe_strerror(errno
));
7381 return CMD_WARNING_CONFIG_FAILED
;
7384 /* Source address */
7385 if (argc
== (idx_ipv4_2
+ 1)) {
7386 source_str
= argv
[idx_ipv4_2
]->arg
;
7387 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
7389 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
7390 source_str
, errno
, safe_strerror(errno
));
7391 return CMD_WARNING_CONFIG_FAILED
;
7393 /* Reject 0.0.0.0. Reserved for any source. */
7394 if (source_addr
.s_addr
== INADDR_ANY
) {
7395 vty_out(vty
, "Bad source address %s\n", source_str
);
7396 return CMD_WARNING_CONFIG_FAILED
;
7399 source_addr
.s_addr
= INADDR_ANY
;
7402 CMD_FERR_RETURN(pim_if_igmp_join_add(ifp
, group_addr
, source_addr
),
7403 "Failure joining IGMP group: $ERR");
7408 DEFUN (interface_no_ip_igmp_join
,
7409 interface_no_ip_igmp_join_cmd
,
7410 "no ip igmp join A.B.C.D [A.B.C.D]",
7414 "IGMP join multicast group\n"
7415 "Multicast group address\n"
7418 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7421 const char *group_str
;
7422 const char *source_str
;
7423 struct in_addr group_addr
;
7424 struct in_addr source_addr
;
7428 group_str
= argv
[idx_ipv4
]->arg
;
7429 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
7431 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
7432 errno
, safe_strerror(errno
));
7433 return CMD_WARNING_CONFIG_FAILED
;
7436 /* Source address */
7437 if (argc
== (idx_ipv4_2
+ 1)) {
7438 source_str
= argv
[idx_ipv4_2
]->arg
;
7439 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
7441 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
7442 source_str
, errno
, safe_strerror(errno
));
7443 return CMD_WARNING_CONFIG_FAILED
;
7445 /* Reject 0.0.0.0. Reserved for any source. */
7446 if (source_addr
.s_addr
== INADDR_ANY
) {
7447 vty_out(vty
, "Bad source address %s\n", source_str
);
7448 return CMD_WARNING_CONFIG_FAILED
;
7452 source_addr
.s_addr
= INADDR_ANY
;
7455 result
= pim_if_igmp_join_del(ifp
, group_addr
, source_addr
);
7458 "%% Failure leaving IGMP group %s source %s on interface %s: %d\n",
7459 group_str
, source_str
, ifp
->name
, result
);
7460 return CMD_WARNING_CONFIG_FAILED
;
7467 CLI reconfiguration affects the interface level (struct pim_interface).
7468 This function propagates the reconfiguration to every active socket
7471 static void igmp_sock_query_interval_reconfig(struct igmp_sock
*igmp
)
7473 struct interface
*ifp
;
7474 struct pim_interface
*pim_ifp
;
7478 /* other querier present? */
7480 if (igmp
->t_other_querier_timer
)
7483 /* this is the querier */
7485 zassert(igmp
->interface
);
7486 zassert(igmp
->interface
->info
);
7488 ifp
= igmp
->interface
;
7489 pim_ifp
= ifp
->info
;
7491 if (PIM_DEBUG_IGMP_TRACE
) {
7492 char ifaddr_str
[INET_ADDRSTRLEN
];
7493 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
7494 sizeof(ifaddr_str
));
7495 zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
7496 __func__
, ifaddr_str
, ifp
->name
,
7497 pim_ifp
->igmp_default_query_interval
);
7501 igmp_startup_mode_on() will reset QQI:
7503 igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
7505 igmp_startup_mode_on(igmp
);
7508 static void igmp_sock_query_reschedule(struct igmp_sock
*igmp
)
7510 if (igmp
->mtrace_only
)
7513 if (igmp
->t_igmp_query_timer
) {
7514 /* other querier present */
7515 zassert(igmp
->t_igmp_query_timer
);
7516 zassert(!igmp
->t_other_querier_timer
);
7518 pim_igmp_general_query_off(igmp
);
7519 pim_igmp_general_query_on(igmp
);
7521 zassert(igmp
->t_igmp_query_timer
);
7522 zassert(!igmp
->t_other_querier_timer
);
7524 /* this is the querier */
7526 zassert(!igmp
->t_igmp_query_timer
);
7527 zassert(igmp
->t_other_querier_timer
);
7529 pim_igmp_other_querier_timer_off(igmp
);
7530 pim_igmp_other_querier_timer_on(igmp
);
7532 zassert(!igmp
->t_igmp_query_timer
);
7533 zassert(igmp
->t_other_querier_timer
);
7537 static void change_query_interval(struct pim_interface
*pim_ifp
,
7540 struct listnode
*sock_node
;
7541 struct igmp_sock
*igmp
;
7543 pim_ifp
->igmp_default_query_interval
= query_interval
;
7545 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
7546 igmp_sock_query_interval_reconfig(igmp
);
7547 igmp_sock_query_reschedule(igmp
);
7551 static void change_query_max_response_time(struct pim_interface
*pim_ifp
,
7552 int query_max_response_time_dsec
)
7554 struct listnode
*sock_node
;
7555 struct igmp_sock
*igmp
;
7557 pim_ifp
->igmp_query_max_response_time_dsec
=
7558 query_max_response_time_dsec
;
7561 Below we modify socket/group/source timers in order to quickly
7562 reflect the change. Otherwise, those timers would eventually catch
7566 /* scan all sockets */
7567 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
7568 struct listnode
*grp_node
;
7569 struct igmp_group
*grp
;
7571 /* reschedule socket general query */
7572 igmp_sock_query_reschedule(igmp
);
7574 /* scan socket groups */
7575 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grp_node
,
7577 struct listnode
*src_node
;
7578 struct igmp_source
*src
;
7580 /* reset group timers for groups in EXCLUDE mode */
7581 if (grp
->group_filtermode_isexcl
) {
7582 igmp_group_reset_gmi(grp
);
7585 /* scan group sources */
7586 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
,
7589 /* reset source timers for sources with running
7591 if (src
->t_source_timer
) {
7592 igmp_source_reset_gmi(igmp
, grp
, src
);
7599 #define IGMP_QUERY_INTERVAL_MIN (1)
7600 #define IGMP_QUERY_INTERVAL_MAX (1800)
7602 DEFUN (interface_ip_igmp_query_interval
,
7603 interface_ip_igmp_query_interval_cmd
,
7604 "ip igmp query-interval (1-1800)",
7607 IFACE_IGMP_QUERY_INTERVAL_STR
7608 "Query interval in seconds\n")
7610 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7611 struct pim_interface
*pim_ifp
= ifp
->info
;
7613 int query_interval_dsec
;
7617 ret
= pim_cmd_igmp_start(vty
, ifp
);
7618 if (ret
!= CMD_SUCCESS
)
7620 pim_ifp
= ifp
->info
;
7623 query_interval
= atoi(argv
[3]->arg
);
7624 query_interval_dsec
= 10 * query_interval
;
7627 It seems we don't need to check bounds since command.c does it
7628 already, but we verify them anyway for extra safety.
7630 if (query_interval
< IGMP_QUERY_INTERVAL_MIN
) {
7632 "General query interval %d lower than minimum %d\n",
7633 query_interval
, IGMP_QUERY_INTERVAL_MIN
);
7634 return CMD_WARNING_CONFIG_FAILED
;
7636 if (query_interval
> IGMP_QUERY_INTERVAL_MAX
) {
7638 "General query interval %d higher than maximum %d\n",
7639 query_interval
, IGMP_QUERY_INTERVAL_MAX
);
7640 return CMD_WARNING_CONFIG_FAILED
;
7643 if (query_interval_dsec
<= pim_ifp
->igmp_query_max_response_time_dsec
) {
7645 "Can't set general query interval %d dsec <= query max response time %d dsec.\n",
7646 query_interval_dsec
,
7647 pim_ifp
->igmp_query_max_response_time_dsec
);
7648 return CMD_WARNING_CONFIG_FAILED
;
7651 change_query_interval(pim_ifp
, query_interval
);
7656 DEFUN (interface_no_ip_igmp_query_interval
,
7657 interface_no_ip_igmp_query_interval_cmd
,
7658 "no ip igmp query-interval",
7662 IFACE_IGMP_QUERY_INTERVAL_STR
)
7664 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7665 struct pim_interface
*pim_ifp
= ifp
->info
;
7666 int default_query_interval_dsec
;
7671 default_query_interval_dsec
= IGMP_GENERAL_QUERY_INTERVAL
* 10;
7673 if (default_query_interval_dsec
7674 <= pim_ifp
->igmp_query_max_response_time_dsec
) {
7676 "Can't set default general query interval %d dsec <= query max response time %d dsec.\n",
7677 default_query_interval_dsec
,
7678 pim_ifp
->igmp_query_max_response_time_dsec
);
7679 return CMD_WARNING_CONFIG_FAILED
;
7682 change_query_interval(pim_ifp
, IGMP_GENERAL_QUERY_INTERVAL
);
7687 DEFUN (interface_ip_igmp_version
,
7688 interface_ip_igmp_version_cmd
,
7689 "ip igmp version (2-3)",
7693 "IGMP version number\n")
7695 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7696 struct pim_interface
*pim_ifp
= ifp
->info
;
7697 int igmp_version
, old_version
= 0;
7701 ret
= pim_cmd_igmp_start(vty
, ifp
);
7702 if (ret
!= CMD_SUCCESS
)
7704 pim_ifp
= ifp
->info
;
7707 igmp_version
= atoi(argv
[3]->arg
);
7708 old_version
= pim_ifp
->igmp_version
;
7709 pim_ifp
->igmp_version
= igmp_version
;
7711 // Check if IGMP is Enabled otherwise, enable on interface
7712 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
7713 PIM_IF_DO_IGMP(pim_ifp
->options
);
7714 pim_if_addr_add_all(ifp
);
7715 pim_if_membership_refresh(ifp
);
7716 old_version
= igmp_version
;
7717 // avoid refreshing membership again.
7719 /* Current and new version is different refresh existing
7720 membership. Going from 3 -> 2 or 2 -> 3. */
7721 if (old_version
!= igmp_version
)
7722 pim_if_membership_refresh(ifp
);
7727 DEFUN (interface_no_ip_igmp_version
,
7728 interface_no_ip_igmp_version_cmd
,
7729 "no ip igmp version (2-3)",
7734 "IGMP version number\n")
7736 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7737 struct pim_interface
*pim_ifp
= ifp
->info
;
7742 pim_ifp
->igmp_version
= IGMP_DEFAULT_VERSION
;
7747 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
7748 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
7750 DEFUN (interface_ip_igmp_query_max_response_time
,
7751 interface_ip_igmp_query_max_response_time_cmd
,
7752 "ip igmp query-max-response-time (10-250)",
7755 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
7756 "Query response value in deci-seconds\n")
7758 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7759 struct pim_interface
*pim_ifp
= ifp
->info
;
7760 int query_max_response_time
;
7764 ret
= pim_cmd_igmp_start(vty
, ifp
);
7765 if (ret
!= CMD_SUCCESS
)
7767 pim_ifp
= ifp
->info
;
7770 query_max_response_time
= atoi(argv
[3]->arg
);
7772 if (query_max_response_time
7773 >= pim_ifp
->igmp_default_query_interval
* 10) {
7775 "Can't set query max response time %d sec >= general query interval %d sec\n",
7776 query_max_response_time
,
7777 pim_ifp
->igmp_default_query_interval
);
7778 return CMD_WARNING_CONFIG_FAILED
;
7781 change_query_max_response_time(pim_ifp
, query_max_response_time
);
7786 DEFUN (interface_no_ip_igmp_query_max_response_time
,
7787 interface_no_ip_igmp_query_max_response_time_cmd
,
7788 "no ip igmp query-max-response-time (10-250)",
7792 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
7793 "Time for response in deci-seconds\n")
7795 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7796 struct pim_interface
*pim_ifp
= ifp
->info
;
7801 change_query_max_response_time(pim_ifp
,
7802 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
7807 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
7808 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
7810 DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec
,
7811 interface_ip_igmp_query_max_response_time_dsec_cmd
,
7812 "ip igmp query-max-response-time-dsec (10-250)",
7815 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
7816 "Query response value in deciseconds\n")
7818 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7819 struct pim_interface
*pim_ifp
= ifp
->info
;
7820 int query_max_response_time_dsec
;
7821 int default_query_interval_dsec
;
7825 ret
= pim_cmd_igmp_start(vty
, ifp
);
7826 if (ret
!= CMD_SUCCESS
)
7828 pim_ifp
= ifp
->info
;
7831 query_max_response_time_dsec
= atoi(argv
[4]->arg
);
7833 default_query_interval_dsec
= 10 * pim_ifp
->igmp_default_query_interval
;
7835 if (query_max_response_time_dsec
>= default_query_interval_dsec
) {
7837 "Can't set query max response time %d dsec >= general query interval %d dsec\n",
7838 query_max_response_time_dsec
,
7839 default_query_interval_dsec
);
7840 return CMD_WARNING_CONFIG_FAILED
;
7843 change_query_max_response_time(pim_ifp
, query_max_response_time_dsec
);
7848 DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec
,
7849 interface_no_ip_igmp_query_max_response_time_dsec_cmd
,
7850 "no ip igmp query-max-response-time-dsec",
7854 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
)
7856 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7857 struct pim_interface
*pim_ifp
= ifp
->info
;
7862 change_query_max_response_time(pim_ifp
,
7863 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
7868 #define IGMP_LAST_MEMBER_QUERY_COUNT_MIN (1)
7869 #define IGMP_LAST_MEMBER_QUERY_COUNT_MAX (7)
7871 DEFUN (interface_ip_igmp_last_member_query_count
,
7872 interface_ip_igmp_last_member_query_count_cmd
,
7873 "ip igmp last-member-query-count (1-7)",
7876 IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR
7877 "Last member query count\n")
7879 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7880 struct pim_interface
*pim_ifp
= ifp
->info
;
7881 int last_member_query_count
;
7885 ret
= pim_cmd_igmp_start(vty
, ifp
);
7886 if (ret
!= CMD_SUCCESS
)
7888 pim_ifp
= ifp
->info
;
7891 last_member_query_count
= atoi(argv
[3]->arg
);
7893 pim_ifp
->igmp_last_member_query_count
= last_member_query_count
;
7898 DEFUN (interface_no_ip_igmp_last_member_query_count
,
7899 interface_no_ip_igmp_last_member_query_count_cmd
,
7900 "no ip igmp last-member-query-count",
7904 IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR
)
7906 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7907 struct pim_interface
*pim_ifp
= ifp
->info
;
7912 pim_ifp
->igmp_last_member_query_count
=
7913 IGMP_DEFAULT_ROBUSTNESS_VARIABLE
;
7918 #define IGMP_LAST_MEMBER_QUERY_INTERVAL_MIN (1)
7919 #define IGMP_LAST_MEMBER_QUERY_INTERVAL_MAX (255)
7921 DEFUN (interface_ip_igmp_last_member_query_interval
,
7922 interface_ip_igmp_last_member_query_interval_cmd
,
7923 "ip igmp last-member-query-interval (1-255)",
7926 IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR
7927 "Last member query interval in deciseconds\n")
7929 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7930 struct pim_interface
*pim_ifp
= ifp
->info
;
7931 int last_member_query_interval
;
7935 ret
= pim_cmd_igmp_start(vty
, ifp
);
7936 if (ret
!= CMD_SUCCESS
)
7938 pim_ifp
= ifp
->info
;
7941 last_member_query_interval
= atoi(argv
[3]->arg
);
7942 pim_ifp
->igmp_specific_query_max_response_time_dsec
7943 = last_member_query_interval
;
7948 DEFUN (interface_no_ip_igmp_last_member_query_interval
,
7949 interface_no_ip_igmp_last_member_query_interval_cmd
,
7950 "no ip igmp last-member-query-interval",
7954 IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR
)
7956 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7957 struct pim_interface
*pim_ifp
= ifp
->info
;
7962 pim_ifp
->igmp_specific_query_max_response_time_dsec
=
7963 IGMP_SPECIFIC_QUERY_MAX_RESPONSE_TIME_DSEC
;
7968 DEFUN (interface_ip_pim_drprio
,
7969 interface_ip_pim_drprio_cmd
,
7970 "ip pim drpriority (1-4294967295)",
7973 "Set the Designated Router Election Priority\n"
7974 "Value of the new DR Priority\n")
7976 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7978 struct pim_interface
*pim_ifp
= ifp
->info
;
7979 uint32_t old_dr_prio
;
7982 vty_out(vty
, "Please enable PIM on interface, first\n");
7983 return CMD_WARNING_CONFIG_FAILED
;
7986 old_dr_prio
= pim_ifp
->pim_dr_priority
;
7988 pim_ifp
->pim_dr_priority
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
7990 if (old_dr_prio
!= pim_ifp
->pim_dr_priority
) {
7991 pim_if_dr_election(ifp
);
7992 pim_hello_restart_now(ifp
);
7998 DEFUN (interface_no_ip_pim_drprio
,
7999 interface_no_ip_pim_drprio_cmd
,
8000 "no ip pim drpriority [(1-4294967295)]",
8004 "Revert the Designated Router Priority to default\n"
8005 "Old Value of the Priority\n")
8007 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8008 struct pim_interface
*pim_ifp
= ifp
->info
;
8011 vty_out(vty
, "Pim not enabled on this interface\n");
8012 return CMD_WARNING_CONFIG_FAILED
;
8015 if (pim_ifp
->pim_dr_priority
!= PIM_DEFAULT_DR_PRIORITY
) {
8016 pim_ifp
->pim_dr_priority
= PIM_DEFAULT_DR_PRIORITY
;
8017 pim_if_dr_election(ifp
);
8018 pim_hello_restart_now(ifp
);
8024 DEFPY_HIDDEN (interface_ip_igmp_query_generate
,
8025 interface_ip_igmp_query_generate_cmd
,
8026 "ip igmp generate-query-once [version (2-3)]",
8029 "Generate igmp general query once\n"
8031 "IGMP version number\n")
8033 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8034 int igmp_version
= 2;
8037 vty_out(vty
, "IGMP/PIM is not enabled on the interface %s\n",
8039 return CMD_WARNING_CONFIG_FAILED
;
8043 igmp_version
= atoi(argv
[4]->arg
);
8045 igmp_send_query_on_intf(ifp
, igmp_version
);
8050 static int pim_cmd_interface_add(struct vty
*vty
, struct interface
*ifp
)
8052 struct pim_interface
*pim_ifp
= ifp
->info
;
8053 struct pim_instance
*pim
;
8056 pim
= pim_get_pim_instance(ifp
->vrf_id
);
8057 /* Limiting mcast interfaces to number of VIFs */
8058 if (pim
->mcast_if_count
== MAXVIFS
) {
8059 vty_out(vty
, "Max multicast interfaces(%d) reached.",
8063 pim_ifp
= pim_if_new(ifp
, false, true, false, false);
8065 PIM_IF_DO_PIM(pim_ifp
->options
);
8067 pim_if_addr_add_all(ifp
);
8068 pim_if_membership_refresh(ifp
);
8070 pim_if_create_pimreg(pim_ifp
->pim
);
8074 DEFPY_HIDDEN (pim_test_sg_keepalive
,
8075 pim_test_sg_keepalive_cmd
,
8076 "test pim [vrf NAME$name] keepalive-reset A.B.C.D$source A.B.C.D$group",
8080 "Reset the Keepalive Timer\n"
8081 "The Source we are resetting\n"
8082 "The Group we are resetting\n")
8084 struct pim_upstream
*up
;
8085 struct pim_instance
*pim
;
8086 struct prefix_sg sg
;
8092 pim
= pim_get_pim_instance(VRF_DEFAULT
);
8094 struct vrf
*vrf
= vrf_lookup_by_name(name
);
8097 vty_out(vty
, "%% Vrf specified: %s does not exist\n",
8102 pim
= pim_get_pim_instance(vrf
->vrf_id
);
8106 vty_out(vty
, "%% Unable to find pim instance\n");
8110 up
= pim_upstream_find(pim
, &sg
);
8112 vty_out(vty
, "%% Unable to find %s specified\n",
8113 pim_str_sg_dump(&sg
));
8117 vty_out(vty
, "Setting %s to current keep alive time: %d\n",
8118 pim_str_sg_dump(&sg
), pim
->keep_alive_time
);
8119 pim_upstream_keep_alive_timer_start(up
, pim
->keep_alive_time
);
8124 DEFPY (interface_ip_pim_activeactive
,
8125 interface_ip_pim_activeactive_cmd
,
8126 "[no$no] ip pim active-active",
8130 "Mark interface as Active-Active for MLAG operations, Hidden because not finished yet\n")
8132 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8133 struct pim_interface
*pim_ifp
;
8135 if (!no
&& !pim_cmd_interface_add(vty
, ifp
)) {
8137 "Could not enable PIM SM active-active on interface %s\n",
8139 return CMD_WARNING_CONFIG_FAILED
;
8144 zlog_debug("%sConfiguring PIM active-active on Interface: %s",
8145 no
? "Un-" : " ", ifp
->name
);
8147 pim_ifp
= ifp
->info
;
8149 pim_if_unconfigure_mlag_dualactive(pim_ifp
);
8151 pim_if_configure_mlag_dualactive(pim_ifp
);
8156 DEFUN_HIDDEN (interface_ip_pim_ssm
,
8157 interface_ip_pim_ssm_cmd
,
8163 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8165 if (!pim_cmd_interface_add(vty
, ifp
)) {
8166 vty_out(vty
, "Could not enable PIM SM on interface %s\n",
8168 return CMD_WARNING_CONFIG_FAILED
;
8172 "WARN: Enabled PIM SM on interface; configure PIM SSM "
8173 "range if needed\n");
8177 static int interface_ip_pim_helper(struct vty
*vty
)
8179 struct pim_interface
*pim_ifp
;
8181 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8183 if (!pim_cmd_interface_add(vty
, ifp
)) {
8184 vty_out(vty
, "Could not enable PIM SM on interface %s\n",
8186 return CMD_WARNING_CONFIG_FAILED
;
8189 pim_ifp
= ifp
->info
;
8191 pim_if_create_pimreg(pim_ifp
->pim
);
8196 DEFUN_HIDDEN (interface_ip_pim_sm
,
8197 interface_ip_pim_sm_cmd
,
8203 return interface_ip_pim_helper(vty
);
8206 DEFUN (interface_ip_pim
,
8207 interface_ip_pim_cmd
,
8212 return interface_ip_pim_helper(vty
);
8215 static int pim_cmd_interface_delete(struct interface
*ifp
)
8217 struct pim_interface
*pim_ifp
= ifp
->info
;
8222 PIM_IF_DONT_PIM(pim_ifp
->options
);
8224 pim_if_membership_clear(ifp
);
8227 pim_sock_delete() removes all neighbors from
8228 pim_ifp->pim_neighbor_list.
8230 pim_sock_delete(ifp
, "pim unconfigured on interface");
8232 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
8233 pim_if_addr_del_all(ifp
);
8240 static int interface_no_ip_pim_helper(struct vty
*vty
)
8242 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8243 if (!pim_cmd_interface_delete(ifp
)) {
8244 vty_out(vty
, "Unable to delete interface information\n");
8245 return CMD_WARNING_CONFIG_FAILED
;
8251 DEFUN_HIDDEN (interface_no_ip_pim_ssm
,
8252 interface_no_ip_pim_ssm_cmd
,
8259 return interface_no_ip_pim_helper(vty
);
8262 DEFUN_HIDDEN (interface_no_ip_pim_sm
,
8263 interface_no_ip_pim_sm_cmd
,
8270 return interface_no_ip_pim_helper(vty
);
8273 DEFUN (interface_no_ip_pim
,
8274 interface_no_ip_pim_cmd
,
8280 return interface_no_ip_pim_helper(vty
);
8284 DEFUN(interface_ip_pim_boundary_oil
,
8285 interface_ip_pim_boundary_oil_cmd
,
8286 "ip multicast boundary oil WORD",
8288 "Generic multicast configuration options\n"
8289 "Define multicast boundary\n"
8290 "Filter OIL by group using prefix list\n"
8291 "Prefix list to filter OIL with\n")
8293 VTY_DECLVAR_CONTEXT(interface
, iif
);
8294 struct pim_interface
*pim_ifp
;
8297 argv_find(argv
, argc
, "WORD", &idx
);
8299 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
8301 if (pim_ifp
->boundary_oil_plist
)
8302 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
8304 pim_ifp
->boundary_oil_plist
=
8305 XSTRDUP(MTYPE_PIM_INTERFACE
, argv
[idx
]->arg
);
8307 /* Interface will be pruned from OIL on next Join */
8311 DEFUN(interface_no_ip_pim_boundary_oil
,
8312 interface_no_ip_pim_boundary_oil_cmd
,
8313 "no ip multicast boundary oil [WORD]",
8316 "Generic multicast configuration options\n"
8317 "Define multicast boundary\n"
8318 "Filter OIL by group using prefix list\n"
8319 "Prefix list to filter OIL with\n")
8321 VTY_DECLVAR_CONTEXT(interface
, iif
);
8322 struct pim_interface
*pim_ifp
;
8325 argv_find(argv
, argc
, "WORD", &idx
);
8327 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
8329 if (pim_ifp
->boundary_oil_plist
)
8330 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
8335 DEFUN (interface_ip_mroute
,
8336 interface_ip_mroute_cmd
,
8337 "ip mroute INTERFACE A.B.C.D [A.B.C.D]",
8339 "Add multicast route\n"
8340 "Outgoing interface name\n"
8344 VTY_DECLVAR_CONTEXT(interface
, iif
);
8345 struct pim_interface
*pim_ifp
;
8346 struct pim_instance
*pim
;
8347 int idx_interface
= 2;
8349 struct interface
*oif
;
8350 const char *oifname
;
8351 const char *grp_str
;
8352 struct in_addr grp_addr
;
8353 const char *src_str
;
8354 struct in_addr src_addr
;
8357 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
8360 oifname
= argv
[idx_interface
]->arg
;
8361 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
8363 vty_out(vty
, "No such interface name %s\n", oifname
);
8367 grp_str
= argv
[idx_ipv4
]->arg
;
8368 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
8370 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
8371 errno
, safe_strerror(errno
));
8375 if (argc
== (idx_ipv4
+ 1)) {
8376 src_addr
.s_addr
= INADDR_ANY
;
8379 src_str
= argv
[idx_ipv4
+ 1]->arg
;
8380 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
8382 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
8383 errno
, safe_strerror(errno
));
8388 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
8389 vty_out(vty
, "Failed to add static mroute\n");
8396 DEFUN (interface_no_ip_mroute
,
8397 interface_no_ip_mroute_cmd
,
8398 "no ip mroute INTERFACE A.B.C.D [A.B.C.D]",
8401 "Add multicast route\n"
8402 "Outgoing interface name\n"
8406 VTY_DECLVAR_CONTEXT(interface
, iif
);
8407 struct pim_interface
*pim_ifp
;
8408 struct pim_instance
*pim
;
8409 int idx_interface
= 3;
8411 struct interface
*oif
;
8412 const char *oifname
;
8413 const char *grp_str
;
8414 struct in_addr grp_addr
;
8415 const char *src_str
;
8416 struct in_addr src_addr
;
8419 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
8422 oifname
= argv
[idx_interface
]->arg
;
8423 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
8425 vty_out(vty
, "No such interface name %s\n", oifname
);
8429 grp_str
= argv
[idx_ipv4
]->arg
;
8430 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
8432 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
8433 errno
, safe_strerror(errno
));
8437 if (argc
== (idx_ipv4
+ 1)) {
8438 src_addr
.s_addr
= INADDR_ANY
;
8441 src_str
= argv
[idx_ipv4
+ 1]->arg
;
8442 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
8444 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
8445 errno
, safe_strerror(errno
));
8450 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
8451 vty_out(vty
, "Failed to remove static mroute\n");
8458 DEFUN (interface_ip_pim_hello
,
8459 interface_ip_pim_hello_cmd
,
8460 "ip pim hello (1-180) [(1-180)]",
8464 IFACE_PIM_HELLO_TIME_STR
8465 IFACE_PIM_HELLO_HOLD_STR
)
8467 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8470 struct pim_interface
*pim_ifp
= ifp
->info
;
8473 if (!pim_cmd_interface_add(vty
, ifp
)) {
8475 "Could not enable PIM SM on interface %s\n",
8477 return CMD_WARNING_CONFIG_FAILED
;
8481 pim_ifp
= ifp
->info
;
8482 pim_ifp
->pim_hello_period
= strtol(argv
[idx_time
]->arg
, NULL
, 10);
8484 if (argc
== idx_hold
+ 1)
8485 pim_ifp
->pim_default_holdtime
=
8486 strtol(argv
[idx_hold
]->arg
, NULL
, 10);
8491 DEFUN (interface_no_ip_pim_hello
,
8492 interface_no_ip_pim_hello_cmd
,
8493 "no ip pim hello [(1-180) (1-180)]",
8498 IFACE_PIM_HELLO_TIME_STR
8499 IFACE_PIM_HELLO_HOLD_STR
)
8501 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8502 struct pim_interface
*pim_ifp
= ifp
->info
;
8505 vty_out(vty
, "Pim not enabled on this interface\n");
8506 return CMD_WARNING_CONFIG_FAILED
;
8509 pim_ifp
->pim_hello_period
= PIM_DEFAULT_HELLO_PERIOD
;
8510 pim_ifp
->pim_default_holdtime
= -1;
8521 PIM_DO_DEBUG_IGMP_EVENTS
;
8522 PIM_DO_DEBUG_IGMP_PACKETS
;
8523 PIM_DO_DEBUG_IGMP_TRACE
;
8527 DEFUN (no_debug_igmp
,
8534 PIM_DONT_DEBUG_IGMP_EVENTS
;
8535 PIM_DONT_DEBUG_IGMP_PACKETS
;
8536 PIM_DONT_DEBUG_IGMP_TRACE
;
8541 DEFUN (debug_igmp_events
,
8542 debug_igmp_events_cmd
,
8543 "debug igmp events",
8546 DEBUG_IGMP_EVENTS_STR
)
8548 PIM_DO_DEBUG_IGMP_EVENTS
;
8552 DEFUN (no_debug_igmp_events
,
8553 no_debug_igmp_events_cmd
,
8554 "no debug igmp events",
8558 DEBUG_IGMP_EVENTS_STR
)
8560 PIM_DONT_DEBUG_IGMP_EVENTS
;
8565 DEFUN (debug_igmp_packets
,
8566 debug_igmp_packets_cmd
,
8567 "debug igmp packets",
8570 DEBUG_IGMP_PACKETS_STR
)
8572 PIM_DO_DEBUG_IGMP_PACKETS
;
8576 DEFUN (no_debug_igmp_packets
,
8577 no_debug_igmp_packets_cmd
,
8578 "no debug igmp packets",
8582 DEBUG_IGMP_PACKETS_STR
)
8584 PIM_DONT_DEBUG_IGMP_PACKETS
;
8589 DEFUN (debug_igmp_trace
,
8590 debug_igmp_trace_cmd
,
8594 DEBUG_IGMP_TRACE_STR
)
8596 PIM_DO_DEBUG_IGMP_TRACE
;
8600 DEFUN (no_debug_igmp_trace
,
8601 no_debug_igmp_trace_cmd
,
8602 "no debug igmp trace",
8606 DEBUG_IGMP_TRACE_STR
)
8608 PIM_DONT_DEBUG_IGMP_TRACE
;
8613 DEFUN (debug_mroute
,
8619 PIM_DO_DEBUG_MROUTE
;
8623 DEFUN (debug_mroute_detail
,
8624 debug_mroute_detail_cmd
,
8625 "debug mroute detail",
8630 PIM_DO_DEBUG_MROUTE_DETAIL
;
8634 DEFUN (no_debug_mroute
,
8635 no_debug_mroute_cmd
,
8641 PIM_DONT_DEBUG_MROUTE
;
8645 DEFUN (no_debug_mroute_detail
,
8646 no_debug_mroute_detail_cmd
,
8647 "no debug mroute detail",
8653 PIM_DONT_DEBUG_MROUTE_DETAIL
;
8657 DEFUN (debug_pim_static
,
8658 debug_pim_static_cmd
,
8664 PIM_DO_DEBUG_STATIC
;
8668 DEFUN (no_debug_pim_static
,
8669 no_debug_pim_static_cmd
,
8670 "no debug pim static",
8676 PIM_DONT_DEBUG_STATIC
;
8687 PIM_DO_DEBUG_PIM_EVENTS
;
8688 PIM_DO_DEBUG_PIM_PACKETS
;
8689 PIM_DO_DEBUG_PIM_TRACE
;
8690 PIM_DO_DEBUG_MSDP_EVENTS
;
8691 PIM_DO_DEBUG_MSDP_PACKETS
;
8696 DEFUN (no_debug_pim
,
8703 PIM_DONT_DEBUG_PIM_EVENTS
;
8704 PIM_DONT_DEBUG_PIM_PACKETS
;
8705 PIM_DONT_DEBUG_PIM_TRACE
;
8706 PIM_DONT_DEBUG_MSDP_EVENTS
;
8707 PIM_DONT_DEBUG_MSDP_PACKETS
;
8709 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
8710 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
8716 DEFUN (debug_pim_nht
,
8721 "Nexthop Tracking\n")
8723 PIM_DO_DEBUG_PIM_NHT
;
8727 DEFUN (no_debug_pim_nht
,
8728 no_debug_pim_nht_cmd
,
8733 "Nexthop Tracking\n")
8735 PIM_DONT_DEBUG_PIM_NHT
;
8739 DEFUN (debug_pim_nht_rp
,
8740 debug_pim_nht_rp_cmd
,
8744 "Nexthop Tracking\n"
8745 "RP Nexthop Tracking\n")
8747 PIM_DO_DEBUG_PIM_NHT_RP
;
8751 DEFUN (no_debug_pim_nht_rp
,
8752 no_debug_pim_nht_rp_cmd
,
8753 "no debug pim nht rp",
8757 "Nexthop Tracking\n"
8758 "RP Nexthop Tracking\n")
8760 PIM_DONT_DEBUG_PIM_NHT_RP
;
8764 DEFUN (debug_pim_events
,
8765 debug_pim_events_cmd
,
8769 DEBUG_PIM_EVENTS_STR
)
8771 PIM_DO_DEBUG_PIM_EVENTS
;
8775 DEFUN (no_debug_pim_events
,
8776 no_debug_pim_events_cmd
,
8777 "no debug pim events",
8781 DEBUG_PIM_EVENTS_STR
)
8783 PIM_DONT_DEBUG_PIM_EVENTS
;
8787 DEFUN (debug_pim_packets
,
8788 debug_pim_packets_cmd
,
8789 "debug pim packets [<hello|joins|register>]",
8792 DEBUG_PIM_PACKETS_STR
8793 DEBUG_PIM_HELLO_PACKETS_STR
8794 DEBUG_PIM_J_P_PACKETS_STR
8795 DEBUG_PIM_PIM_REG_PACKETS_STR
)
8798 if (argv_find(argv
, argc
, "hello", &idx
)) {
8799 PIM_DO_DEBUG_PIM_HELLO
;
8800 vty_out(vty
, "PIM Hello debugging is on\n");
8801 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
8802 PIM_DO_DEBUG_PIM_J_P
;
8803 vty_out(vty
, "PIM Join/Prune debugging is on\n");
8804 } else if (argv_find(argv
, argc
, "register", &idx
)) {
8805 PIM_DO_DEBUG_PIM_REG
;
8806 vty_out(vty
, "PIM Register debugging is on\n");
8808 PIM_DO_DEBUG_PIM_PACKETS
;
8809 vty_out(vty
, "PIM Packet debugging is on \n");
8814 DEFUN (no_debug_pim_packets
,
8815 no_debug_pim_packets_cmd
,
8816 "no debug pim packets [<hello|joins|register>]",
8820 DEBUG_PIM_PACKETS_STR
8821 DEBUG_PIM_HELLO_PACKETS_STR
8822 DEBUG_PIM_J_P_PACKETS_STR
8823 DEBUG_PIM_PIM_REG_PACKETS_STR
)
8826 if (argv_find(argv
, argc
, "hello", &idx
)) {
8827 PIM_DONT_DEBUG_PIM_HELLO
;
8828 vty_out(vty
, "PIM Hello debugging is off \n");
8829 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
8830 PIM_DONT_DEBUG_PIM_J_P
;
8831 vty_out(vty
, "PIM Join/Prune debugging is off \n");
8832 } else if (argv_find(argv
, argc
, "register", &idx
)) {
8833 PIM_DONT_DEBUG_PIM_REG
;
8834 vty_out(vty
, "PIM Register debugging is off\n");
8836 PIM_DONT_DEBUG_PIM_PACKETS
;
8842 DEFUN (debug_pim_packetdump_send
,
8843 debug_pim_packetdump_send_cmd
,
8844 "debug pim packet-dump send",
8847 DEBUG_PIM_PACKETDUMP_STR
8848 DEBUG_PIM_PACKETDUMP_SEND_STR
)
8850 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND
;
8854 DEFUN (no_debug_pim_packetdump_send
,
8855 no_debug_pim_packetdump_send_cmd
,
8856 "no debug pim packet-dump send",
8860 DEBUG_PIM_PACKETDUMP_STR
8861 DEBUG_PIM_PACKETDUMP_SEND_STR
)
8863 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
8867 DEFUN (debug_pim_packetdump_recv
,
8868 debug_pim_packetdump_recv_cmd
,
8869 "debug pim packet-dump receive",
8872 DEBUG_PIM_PACKETDUMP_STR
8873 DEBUG_PIM_PACKETDUMP_RECV_STR
)
8875 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV
;
8879 DEFUN (no_debug_pim_packetdump_recv
,
8880 no_debug_pim_packetdump_recv_cmd
,
8881 "no debug pim packet-dump receive",
8885 DEBUG_PIM_PACKETDUMP_STR
8886 DEBUG_PIM_PACKETDUMP_RECV_STR
)
8888 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
8892 DEFUN (debug_pim_trace
,
8893 debug_pim_trace_cmd
,
8897 DEBUG_PIM_TRACE_STR
)
8899 PIM_DO_DEBUG_PIM_TRACE
;
8903 DEFUN (debug_pim_trace_detail
,
8904 debug_pim_trace_detail_cmd
,
8905 "debug pim trace detail",
8909 "Detailed Information\n")
8911 PIM_DO_DEBUG_PIM_TRACE_DETAIL
;
8915 DEFUN (no_debug_pim_trace
,
8916 no_debug_pim_trace_cmd
,
8917 "no debug pim trace",
8921 DEBUG_PIM_TRACE_STR
)
8923 PIM_DONT_DEBUG_PIM_TRACE
;
8927 DEFUN (no_debug_pim_trace_detail
,
8928 no_debug_pim_trace_detail_cmd
,
8929 "no debug pim trace detail",
8934 "Detailed Information\n")
8936 PIM_DONT_DEBUG_PIM_TRACE_DETAIL
;
8940 DEFUN (debug_ssmpingd
,
8946 PIM_DO_DEBUG_SSMPINGD
;
8950 DEFUN (no_debug_ssmpingd
,
8951 no_debug_ssmpingd_cmd
,
8952 "no debug ssmpingd",
8957 PIM_DONT_DEBUG_SSMPINGD
;
8961 DEFUN (debug_pim_zebra
,
8962 debug_pim_zebra_cmd
,
8966 DEBUG_PIM_ZEBRA_STR
)
8972 DEFUN (no_debug_pim_zebra
,
8973 no_debug_pim_zebra_cmd
,
8974 "no debug pim zebra",
8978 DEBUG_PIM_ZEBRA_STR
)
8980 PIM_DONT_DEBUG_ZEBRA
;
8984 DEFUN(debug_pim_mlag
, debug_pim_mlag_cmd
, "debug pim mlag",
8985 DEBUG_STR DEBUG_PIM_STR DEBUG_PIM_MLAG_STR
)
8991 DEFUN(no_debug_pim_mlag
, no_debug_pim_mlag_cmd
, "no debug pim mlag",
8992 NO_STR DEBUG_STR DEBUG_PIM_STR DEBUG_PIM_MLAG_STR
)
8994 PIM_DONT_DEBUG_MLAG
;
8998 DEFUN (debug_pim_vxlan
,
8999 debug_pim_vxlan_cmd
,
9003 DEBUG_PIM_VXLAN_STR
)
9009 DEFUN (no_debug_pim_vxlan
,
9010 no_debug_pim_vxlan_cmd
,
9011 "no debug pim vxlan",
9015 DEBUG_PIM_VXLAN_STR
)
9017 PIM_DONT_DEBUG_VXLAN
;
9027 PIM_DO_DEBUG_MSDP_EVENTS
;
9028 PIM_DO_DEBUG_MSDP_PACKETS
;
9032 DEFUN (no_debug_msdp
,
9039 PIM_DONT_DEBUG_MSDP_EVENTS
;
9040 PIM_DONT_DEBUG_MSDP_PACKETS
;
9044 DEFUN (debug_msdp_events
,
9045 debug_msdp_events_cmd
,
9046 "debug msdp events",
9049 DEBUG_MSDP_EVENTS_STR
)
9051 PIM_DO_DEBUG_MSDP_EVENTS
;
9055 DEFUN (no_debug_msdp_events
,
9056 no_debug_msdp_events_cmd
,
9057 "no debug msdp events",
9061 DEBUG_MSDP_EVENTS_STR
)
9063 PIM_DONT_DEBUG_MSDP_EVENTS
;
9067 DEFUN (debug_msdp_packets
,
9068 debug_msdp_packets_cmd
,
9069 "debug msdp packets",
9072 DEBUG_MSDP_PACKETS_STR
)
9074 PIM_DO_DEBUG_MSDP_PACKETS
;
9078 DEFUN (no_debug_msdp_packets
,
9079 no_debug_msdp_packets_cmd
,
9080 "no debug msdp packets",
9084 DEBUG_MSDP_PACKETS_STR
)
9086 PIM_DONT_DEBUG_MSDP_PACKETS
;
9090 DEFUN (debug_mtrace
,
9096 PIM_DO_DEBUG_MTRACE
;
9100 DEFUN (no_debug_mtrace
,
9101 no_debug_mtrace_cmd
,
9107 PIM_DONT_DEBUG_MTRACE
;
9122 DEFUN (no_debug_bsm
,
9135 DEFUN_NOSH (show_debugging_pim
,
9136 show_debugging_pim_cmd
,
9137 "show debugging [pim]",
9142 vty_out(vty
, "PIM debugging status\n");
9144 pim_debug_config_write(vty
);
9149 static int interface_pim_use_src_cmd_worker(struct vty
*vty
, const char *source
)
9152 struct in_addr source_addr
;
9153 int ret
= CMD_SUCCESS
;
9154 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9156 result
= inet_pton(AF_INET
, source
, &source_addr
);
9158 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", source
,
9159 errno
, safe_strerror(errno
));
9160 return CMD_WARNING_CONFIG_FAILED
;
9163 result
= pim_update_source_set(ifp
, source_addr
);
9167 case PIM_IFACE_NOT_FOUND
:
9168 ret
= CMD_WARNING_CONFIG_FAILED
;
9169 vty_out(vty
, "Pim not enabled on this interface\n");
9171 case PIM_UPDATE_SOURCE_DUP
:
9173 vty_out(vty
, "%% Source already set to %s\n", source
);
9176 ret
= CMD_WARNING_CONFIG_FAILED
;
9177 vty_out(vty
, "%% Source set failed\n");
9183 DEFUN (interface_pim_use_source
,
9184 interface_pim_use_source_cmd
,
9185 "ip pim use-source A.B.C.D",
9188 "Configure primary IP address\n"
9189 "source ip address\n")
9191 return interface_pim_use_src_cmd_worker(vty
, argv
[3]->arg
);
9194 DEFUN (interface_no_pim_use_source
,
9195 interface_no_pim_use_source_cmd
,
9196 "no ip pim use-source [A.B.C.D]",
9200 "Delete source IP address\n"
9201 "source ip address\n")
9203 return interface_pim_use_src_cmd_worker(vty
, "0.0.0.0");
9211 "Enables BFD support\n")
9213 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9214 struct pim_interface
*pim_ifp
= ifp
->info
;
9215 struct bfd_info
*bfd_info
= NULL
;
9218 if (!pim_cmd_interface_add(vty
, ifp
)) {
9220 "Could not enable PIM SM on interface %s\n",
9225 pim_ifp
= ifp
->info
;
9227 bfd_info
= pim_ifp
->bfd_info
;
9229 if (!bfd_info
|| !CHECK_FLAG(bfd_info
->flags
, BFD_FLAG_PARAM_CFG
))
9230 pim_bfd_if_param_set(ifp
, BFD_DEF_MIN_RX
, BFD_DEF_MIN_TX
,
9231 BFD_DEF_DETECT_MULT
, 1);
9236 DEFUN (no_ip_pim_bfd
,
9242 "Disables BFD support\n")
9244 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9245 struct pim_interface
*pim_ifp
= ifp
->info
;
9248 vty_out(vty
, "Pim not enabled on this interface\n");
9252 if (pim_ifp
->bfd_info
) {
9253 pim_bfd_reg_dereg_all_nbr(ifp
, ZEBRA_BFD_DEST_DEREGISTER
);
9254 bfd_info_free(&(pim_ifp
->bfd_info
));
9265 "Enables BSM support on the interface\n")
9267 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9268 struct pim_interface
*pim_ifp
= ifp
->info
;
9271 if (!pim_cmd_interface_add(vty
, ifp
)) {
9273 "Could not enable PIM SM on interface %s\n",
9279 pim_ifp
= ifp
->info
;
9280 pim_ifp
->bsm_enable
= true;
9285 DEFUN (no_ip_pim_bsm
,
9291 "Disables BSM support\n")
9293 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9294 struct pim_interface
*pim_ifp
= ifp
->info
;
9297 vty_out(vty
, "Pim not enabled on this interface\n");
9301 pim_ifp
->bsm_enable
= false;
9306 DEFUN (ip_pim_ucast_bsm
,
9307 ip_pim_ucast_bsm_cmd
,
9308 "ip pim unicast-bsm",
9311 "Accept/Send unicast BSM on the interface\n")
9313 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9314 struct pim_interface
*pim_ifp
= ifp
->info
;
9317 if (!pim_cmd_interface_add(vty
, ifp
)) {
9319 "Could not enable PIM SM on interface %s\n",
9325 pim_ifp
= ifp
->info
;
9326 pim_ifp
->ucast_bsm_accept
= true;
9331 DEFUN (no_ip_pim_ucast_bsm
,
9332 no_ip_pim_ucast_bsm_cmd
,
9333 "no ip pim unicast-bsm",
9337 "Block send/receive unicast BSM on this interface\n")
9339 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9340 struct pim_interface
*pim_ifp
= ifp
->info
;
9343 vty_out(vty
, "Pim not enabled on this interface\n");
9347 pim_ifp
->ucast_bsm_accept
= false;
9355 ip_pim_bfd_param_cmd
,
9356 "ip pim bfd (2-255) (50-60000) (50-60000)",
9359 "Enables BFD support\n"
9360 "Detect Multiplier\n"
9361 "Required min receive interval\n"
9362 "Desired min transmit interval\n")
9366 ip_pim_bfd_param_cmd
,
9367 "ip pim bfd (2-255) (50-60000) (50-60000)",
9370 "Enables BFD support\n"
9371 "Detect Multiplier\n"
9372 "Required min receive interval\n"
9373 "Desired min transmit interval\n")
9374 #endif /* HAVE_BFDD */
9376 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9378 int idx_number_2
= 4;
9379 int idx_number_3
= 5;
9384 struct pim_interface
*pim_ifp
= ifp
->info
;
9387 if (!pim_cmd_interface_add(vty
, ifp
)) {
9389 "Could not enable PIM SM on interface %s\n",
9395 if ((ret
= bfd_validate_param(
9396 vty
, argv
[idx_number
]->arg
, argv
[idx_number_2
]->arg
,
9397 argv
[idx_number_3
]->arg
, &dm_val
, &rx_val
, &tx_val
))
9401 pim_bfd_if_param_set(ifp
, rx_val
, tx_val
, dm_val
, 0);
9407 ALIAS(no_ip_pim_bfd
, no_ip_pim_bfd_param_cmd
,
9408 "no ip pim bfd (2-255) (50-60000) (50-60000)", NO_STR IP_STR PIM_STR
9409 "Enables BFD support\n"
9410 "Detect Multiplier\n"
9411 "Required min receive interval\n"
9412 "Desired min transmit interval\n")
9413 #endif /* !HAVE_BFDD */
9415 static int ip_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
9416 const char *peer
, const char *local
)
9418 enum pim_msdp_err result
;
9419 struct in_addr peer_addr
;
9420 struct in_addr local_addr
;
9421 int ret
= CMD_SUCCESS
;
9423 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
9425 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
9426 errno
, safe_strerror(errno
));
9427 return CMD_WARNING_CONFIG_FAILED
;
9430 result
= inet_pton(AF_INET
, local
, &local_addr
);
9432 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", local
,
9433 errno
, safe_strerror(errno
));
9434 return CMD_WARNING_CONFIG_FAILED
;
9437 result
= pim_msdp_peer_add(pim
, peer_addr
, local_addr
, "default",
9440 case PIM_MSDP_ERR_NONE
:
9442 case PIM_MSDP_ERR_OOM
:
9443 ret
= CMD_WARNING_CONFIG_FAILED
;
9444 vty_out(vty
, "%% Out of memory\n");
9446 case PIM_MSDP_ERR_PEER_EXISTS
:
9448 vty_out(vty
, "%% Peer exists\n");
9450 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
9451 ret
= CMD_WARNING_CONFIG_FAILED
;
9452 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
9455 ret
= CMD_WARNING_CONFIG_FAILED
;
9456 vty_out(vty
, "%% peer add failed\n");
9462 DEFUN_HIDDEN (ip_msdp_peer
,
9464 "ip msdp peer A.B.C.D source A.B.C.D",
9467 "Configure MSDP peer\n"
9469 "Source address for TCP connection\n"
9470 "local ip address\n")
9472 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9473 return ip_msdp_peer_cmd_worker(pim
, vty
, argv
[3]->arg
, argv
[5]->arg
);
9476 static int ip_no_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
9479 enum pim_msdp_err result
;
9480 struct in_addr peer_addr
;
9482 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
9484 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
9485 errno
, safe_strerror(errno
));
9486 return CMD_WARNING_CONFIG_FAILED
;
9489 result
= pim_msdp_peer_del(pim
, peer_addr
);
9491 case PIM_MSDP_ERR_NONE
:
9493 case PIM_MSDP_ERR_NO_PEER
:
9494 vty_out(vty
, "%% Peer does not exist\n");
9497 vty_out(vty
, "%% peer del failed\n");
9500 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9503 DEFUN_HIDDEN (no_ip_msdp_peer
,
9504 no_ip_msdp_peer_cmd
,
9505 "no ip msdp peer A.B.C.D",
9509 "Delete MSDP peer\n"
9510 "peer ip address\n")
9512 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9513 return ip_no_msdp_peer_cmd_worker(pim
, vty
, argv
[4]->arg
);
9516 static int ip_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
9517 struct vty
*vty
, const char *mg
,
9520 enum pim_msdp_err result
;
9521 struct in_addr mbr_ip
;
9522 int ret
= CMD_SUCCESS
;
9524 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
9526 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
9527 errno
, safe_strerror(errno
));
9528 return CMD_WARNING_CONFIG_FAILED
;
9531 result
= pim_msdp_mg_mbr_add(pim
, mg
, mbr_ip
);
9533 case PIM_MSDP_ERR_NONE
:
9535 case PIM_MSDP_ERR_OOM
:
9536 ret
= CMD_WARNING_CONFIG_FAILED
;
9537 vty_out(vty
, "%% Out of memory\n");
9539 case PIM_MSDP_ERR_MG_MBR_EXISTS
:
9541 vty_out(vty
, "%% mesh-group member exists\n");
9543 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
9544 ret
= CMD_WARNING_CONFIG_FAILED
;
9545 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
9548 ret
= CMD_WARNING_CONFIG_FAILED
;
9549 vty_out(vty
, "%% member add failed\n");
9555 DEFUN (ip_msdp_mesh_group_member
,
9556 ip_msdp_mesh_group_member_cmd
,
9557 "ip msdp mesh-group WORD member A.B.C.D",
9560 "Configure MSDP mesh-group\n"
9562 "mesh group member\n"
9563 "peer ip address\n")
9565 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9566 return ip_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[3]->arg
,
9570 static int ip_no_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
9575 enum pim_msdp_err result
;
9576 struct in_addr mbr_ip
;
9578 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
9580 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
9581 errno
, safe_strerror(errno
));
9582 return CMD_WARNING_CONFIG_FAILED
;
9585 result
= pim_msdp_mg_mbr_del(pim
, mg
, mbr_ip
);
9587 case PIM_MSDP_ERR_NONE
:
9589 case PIM_MSDP_ERR_NO_MG
:
9590 vty_out(vty
, "%% mesh-group does not exist\n");
9592 case PIM_MSDP_ERR_NO_MG_MBR
:
9593 vty_out(vty
, "%% mesh-group member does not exist\n");
9596 vty_out(vty
, "%% mesh-group member del failed\n");
9599 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9601 DEFUN (no_ip_msdp_mesh_group_member
,
9602 no_ip_msdp_mesh_group_member_cmd
,
9603 "no ip msdp mesh-group WORD member A.B.C.D",
9607 "Delete MSDP mesh-group member\n"
9609 "mesh group member\n"
9610 "peer ip address\n")
9612 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9613 return ip_no_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[4]->arg
,
9617 static int ip_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
9618 struct vty
*vty
, const char *mg
,
9621 enum pim_msdp_err result
;
9622 struct in_addr src_ip
;
9624 result
= inet_pton(AF_INET
, src
, &src_ip
);
9626 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", src
,
9627 errno
, safe_strerror(errno
));
9628 return CMD_WARNING_CONFIG_FAILED
;
9631 result
= pim_msdp_mg_src_add(pim
, mg
, src_ip
);
9633 case PIM_MSDP_ERR_NONE
:
9635 case PIM_MSDP_ERR_OOM
:
9636 vty_out(vty
, "%% Out of memory\n");
9638 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
9639 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
9642 vty_out(vty
, "%% source add failed\n");
9645 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9649 DEFUN (ip_msdp_mesh_group_source
,
9650 ip_msdp_mesh_group_source_cmd
,
9651 "ip msdp mesh-group WORD source A.B.C.D",
9654 "Configure MSDP mesh-group\n"
9656 "mesh group local address\n"
9657 "source ip address for the TCP connection\n")
9659 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9660 return ip_msdp_mesh_group_source_cmd_worker(pim
, vty
, argv
[3]->arg
,
9664 static int ip_no_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
9668 enum pim_msdp_err result
;
9670 result
= pim_msdp_mg_src_del(pim
, mg
);
9672 case PIM_MSDP_ERR_NONE
:
9674 case PIM_MSDP_ERR_NO_MG
:
9675 vty_out(vty
, "%% mesh-group does not exist\n");
9678 vty_out(vty
, "%% mesh-group source del failed\n");
9681 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9684 static int ip_no_msdp_mesh_group_cmd_worker(struct pim_instance
*pim
,
9685 struct vty
*vty
, const char *mg
)
9687 enum pim_msdp_err result
;
9689 result
= pim_msdp_mg_del(pim
, mg
);
9691 case PIM_MSDP_ERR_NONE
:
9693 case PIM_MSDP_ERR_NO_MG
:
9694 vty_out(vty
, "%% mesh-group does not exist\n");
9697 vty_out(vty
, "%% mesh-group source del failed\n");
9700 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9703 DEFUN (no_ip_msdp_mesh_group_source
,
9704 no_ip_msdp_mesh_group_source_cmd
,
9705 "no ip msdp mesh-group WORD source [A.B.C.D]",
9709 "Delete MSDP mesh-group source\n"
9711 "mesh group source\n"
9712 "mesh group local address\n")
9714 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9716 return ip_no_msdp_mesh_group_cmd_worker(pim
, vty
, argv
[6]->arg
);
9718 return ip_no_msdp_mesh_group_source_cmd_worker(pim
, vty
,
9722 static void print_empty_json_obj(struct vty
*vty
)
9725 json
= json_object_new_object();
9726 vty_out(vty
, "%s\n",
9727 json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
));
9728 json_object_free(json
);
9731 static void ip_msdp_show_mesh_group(struct pim_instance
*pim
, struct vty
*vty
,
9734 struct listnode
*mbrnode
;
9735 struct pim_msdp_mg_mbr
*mbr
;
9736 struct pim_msdp_mg
*mg
= pim
->msdp
.mg
;
9737 char mbr_str
[INET_ADDRSTRLEN
];
9738 char src_str
[INET_ADDRSTRLEN
];
9739 char state_str
[PIM_MSDP_STATE_STRLEN
];
9740 enum pim_msdp_peer_state state
;
9741 json_object
*json
= NULL
;
9742 json_object
*json_mg_row
= NULL
;
9743 json_object
*json_members
= NULL
;
9744 json_object
*json_row
= NULL
;
9748 print_empty_json_obj(vty
);
9752 pim_inet4_dump("<source?>", mg
->src_ip
, src_str
, sizeof(src_str
));
9754 json
= json_object_new_object();
9755 /* currently there is only one mesh group but we should still
9757 * it a dict with mg-name as key */
9758 json_mg_row
= json_object_new_object();
9759 json_object_string_add(json_mg_row
, "name",
9760 mg
->mesh_group_name
);
9761 json_object_string_add(json_mg_row
, "source", src_str
);
9763 vty_out(vty
, "Mesh group : %s\n", mg
->mesh_group_name
);
9764 vty_out(vty
, " Source : %s\n", src_str
);
9765 vty_out(vty
, " Member State\n");
9768 for (ALL_LIST_ELEMENTS_RO(mg
->mbr_list
, mbrnode
, mbr
)) {
9769 pim_inet4_dump("<mbr?>", mbr
->mbr_ip
, mbr_str
, sizeof(mbr_str
));
9771 state
= mbr
->mp
->state
;
9773 state
= PIM_MSDP_DISABLED
;
9775 pim_msdp_state_dump(state
, state_str
, sizeof(state_str
));
9777 json_row
= json_object_new_object();
9778 json_object_string_add(json_row
, "member", mbr_str
);
9779 json_object_string_add(json_row
, "state", state_str
);
9780 if (!json_members
) {
9781 json_members
= json_object_new_object();
9782 json_object_object_add(json_mg_row
, "members",
9785 json_object_object_add(json_members
, mbr_str
, json_row
);
9787 vty_out(vty
, " %-15s %11s\n", mbr_str
, state_str
);
9792 json_object_object_add(json
, mg
->mesh_group_name
, json_mg_row
);
9793 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9794 json
, JSON_C_TO_STRING_PRETTY
));
9795 json_object_free(json
);
9799 DEFUN (show_ip_msdp_mesh_group
,
9800 show_ip_msdp_mesh_group_cmd
,
9801 "show ip msdp [vrf NAME] mesh-group [json]",
9806 "MSDP mesh-group information\n"
9809 bool uj
= use_json(argc
, argv
);
9811 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
9816 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
9821 DEFUN (show_ip_msdp_mesh_group_vrf_all
,
9822 show_ip_msdp_mesh_group_vrf_all_cmd
,
9823 "show ip msdp vrf all mesh-group [json]",
9828 "MSDP mesh-group information\n"
9831 bool uj
= use_json(argc
, argv
);
9837 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
9841 vty_out(vty
, " \"%s\": ", vrf
->name
);
9844 vty_out(vty
, "VRF: %s\n", vrf
->name
);
9845 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
9848 vty_out(vty
, "}\n");
9853 static void ip_msdp_show_peers(struct pim_instance
*pim
, struct vty
*vty
,
9856 struct listnode
*mpnode
;
9857 struct pim_msdp_peer
*mp
;
9858 char peer_str
[INET_ADDRSTRLEN
];
9859 char local_str
[INET_ADDRSTRLEN
];
9860 char state_str
[PIM_MSDP_STATE_STRLEN
];
9861 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
9863 json_object
*json
= NULL
;
9864 json_object
*json_row
= NULL
;
9868 json
= json_object_new_object();
9871 "Peer Local State Uptime SaCnt\n");
9874 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
9875 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
9876 now
= pim_time_monotonic_sec();
9877 pim_time_uptime(timebuf
, sizeof(timebuf
),
9880 strlcpy(timebuf
, "-", sizeof(timebuf
));
9882 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
9883 pim_inet4_dump("<local?>", mp
->local
, local_str
,
9885 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
9887 json_row
= json_object_new_object();
9888 json_object_string_add(json_row
, "peer", peer_str
);
9889 json_object_string_add(json_row
, "local", local_str
);
9890 json_object_string_add(json_row
, "state", state_str
);
9891 json_object_string_add(json_row
, "upTime", timebuf
);
9892 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
9893 json_object_object_add(json
, peer_str
, json_row
);
9895 vty_out(vty
, "%-15s %15s %11s %8s %6d\n", peer_str
,
9896 local_str
, state_str
, timebuf
, mp
->sa_cnt
);
9901 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9902 json
, JSON_C_TO_STRING_PRETTY
));
9903 json_object_free(json
);
9907 static void ip_msdp_show_peers_detail(struct pim_instance
*pim
, struct vty
*vty
,
9908 const char *peer
, bool uj
)
9910 struct listnode
*mpnode
;
9911 struct pim_msdp_peer
*mp
;
9912 char peer_str
[INET_ADDRSTRLEN
];
9913 char local_str
[INET_ADDRSTRLEN
];
9914 char state_str
[PIM_MSDP_STATE_STRLEN
];
9915 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
9916 char katimer
[PIM_MSDP_TIMER_STRLEN
];
9917 char crtimer
[PIM_MSDP_TIMER_STRLEN
];
9918 char holdtimer
[PIM_MSDP_TIMER_STRLEN
];
9920 json_object
*json
= NULL
;
9921 json_object
*json_row
= NULL
;
9924 json
= json_object_new_object();
9927 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
9928 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
9929 if (strcmp(peer
, "detail") && strcmp(peer
, peer_str
))
9932 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
9933 now
= pim_time_monotonic_sec();
9934 pim_time_uptime(timebuf
, sizeof(timebuf
),
9937 strlcpy(timebuf
, "-", sizeof(timebuf
));
9939 pim_inet4_dump("<local?>", mp
->local
, local_str
,
9941 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
9942 pim_time_timer_to_hhmmss(katimer
, sizeof(katimer
),
9944 pim_time_timer_to_hhmmss(crtimer
, sizeof(crtimer
),
9946 pim_time_timer_to_hhmmss(holdtimer
, sizeof(holdtimer
),
9950 json_row
= json_object_new_object();
9951 json_object_string_add(json_row
, "peer", peer_str
);
9952 json_object_string_add(json_row
, "local", local_str
);
9953 json_object_string_add(json_row
, "meshGroupName",
9954 mp
->mesh_group_name
);
9955 json_object_string_add(json_row
, "state", state_str
);
9956 json_object_string_add(json_row
, "upTime", timebuf
);
9957 json_object_string_add(json_row
, "keepAliveTimer",
9959 json_object_string_add(json_row
, "connRetryTimer",
9961 json_object_string_add(json_row
, "holdTimer",
9963 json_object_string_add(json_row
, "lastReset",
9965 json_object_int_add(json_row
, "connAttempts",
9967 json_object_int_add(json_row
, "establishedChanges",
9969 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
9970 json_object_int_add(json_row
, "kaSent", mp
->ka_tx_cnt
);
9971 json_object_int_add(json_row
, "kaRcvd", mp
->ka_rx_cnt
);
9972 json_object_int_add(json_row
, "saSent", mp
->sa_tx_cnt
);
9973 json_object_int_add(json_row
, "saRcvd", mp
->sa_rx_cnt
);
9974 json_object_object_add(json
, peer_str
, json_row
);
9976 vty_out(vty
, "Peer : %s\n", peer_str
);
9977 vty_out(vty
, " Local : %s\n", local_str
);
9978 vty_out(vty
, " Mesh Group : %s\n",
9979 mp
->mesh_group_name
);
9980 vty_out(vty
, " State : %s\n", state_str
);
9981 vty_out(vty
, " Uptime : %s\n", timebuf
);
9983 vty_out(vty
, " Keepalive Timer : %s\n", katimer
);
9984 vty_out(vty
, " Conn Retry Timer : %s\n", crtimer
);
9985 vty_out(vty
, " Hold Timer : %s\n", holdtimer
);
9986 vty_out(vty
, " Last Reset : %s\n",
9988 vty_out(vty
, " Conn Attempts : %d\n",
9990 vty_out(vty
, " Established Changes : %d\n",
9992 vty_out(vty
, " SA Count : %d\n",
9994 vty_out(vty
, " Statistics :\n");
9997 vty_out(vty
, " Keepalives : %10d %10d\n",
9998 mp
->ka_tx_cnt
, mp
->ka_rx_cnt
);
9999 vty_out(vty
, " SAs : %10d %10d\n",
10000 mp
->sa_tx_cnt
, mp
->sa_rx_cnt
);
10001 vty_out(vty
, "\n");
10006 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10007 json
, JSON_C_TO_STRING_PRETTY
));
10008 json_object_free(json
);
10012 DEFUN (show_ip_msdp_peer_detail
,
10013 show_ip_msdp_peer_detail_cmd
,
10014 "show ip msdp [vrf NAME] peer [detail|A.B.C.D] [json]",
10019 "MSDP peer information\n"
10020 "Detailed output\n"
10021 "peer ip address\n"
10024 bool uj
= use_json(argc
, argv
);
10026 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10029 return CMD_WARNING
;
10033 if (argv_find(argv
, argc
, "detail", &idx
))
10034 arg
= argv
[idx
]->text
;
10035 else if (argv_find(argv
, argc
, "A.B.C.D", &idx
))
10036 arg
= argv
[idx
]->arg
;
10039 ip_msdp_show_peers_detail(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
10041 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
10043 return CMD_SUCCESS
;
10046 DEFUN (show_ip_msdp_peer_detail_vrf_all
,
10047 show_ip_msdp_peer_detail_vrf_all_cmd
,
10048 "show ip msdp vrf all peer [detail|A.B.C.D] [json]",
10053 "MSDP peer information\n"
10054 "Detailed output\n"
10055 "peer ip address\n"
10059 bool uj
= use_json(argc
, argv
);
10064 vty_out(vty
, "{ ");
10065 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
10068 vty_out(vty
, ", ");
10069 vty_out(vty
, " \"%s\": ", vrf
->name
);
10072 vty_out(vty
, "VRF: %s\n", vrf
->name
);
10073 if (argv_find(argv
, argc
, "detail", &idx
)
10074 || argv_find(argv
, argc
, "A.B.C.D", &idx
))
10075 ip_msdp_show_peers_detail(vrf
->info
, vty
,
10076 argv
[idx
]->arg
, uj
);
10078 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
10081 vty_out(vty
, "}\n");
10083 return CMD_SUCCESS
;
10086 static void ip_msdp_show_sa(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
10088 struct listnode
*sanode
;
10089 struct pim_msdp_sa
*sa
;
10090 char src_str
[INET_ADDRSTRLEN
];
10091 char grp_str
[INET_ADDRSTRLEN
];
10092 char rp_str
[INET_ADDRSTRLEN
];
10093 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
10097 json_object
*json
= NULL
;
10098 json_object
*json_group
= NULL
;
10099 json_object
*json_row
= NULL
;
10102 json
= json_object_new_object();
10105 "Source Group RP Local SPT Uptime\n");
10108 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
10109 now
= pim_time_monotonic_sec();
10110 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
10111 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
10112 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
10113 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
10114 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
10116 strlcpy(spt_str
, "yes", sizeof(spt_str
));
10118 strlcpy(spt_str
, "no", sizeof(spt_str
));
10121 strlcpy(rp_str
, "-", sizeof(rp_str
));
10122 strlcpy(spt_str
, "-", sizeof(spt_str
));
10124 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
10125 strlcpy(local_str
, "yes", sizeof(local_str
));
10127 strlcpy(local_str
, "no", sizeof(local_str
));
10130 json_object_object_get_ex(json
, grp_str
, &json_group
);
10133 json_group
= json_object_new_object();
10134 json_object_object_add(json
, grp_str
,
10138 json_row
= json_object_new_object();
10139 json_object_string_add(json_row
, "source", src_str
);
10140 json_object_string_add(json_row
, "group", grp_str
);
10141 json_object_string_add(json_row
, "rp", rp_str
);
10142 json_object_string_add(json_row
, "local", local_str
);
10143 json_object_string_add(json_row
, "sptSetup", spt_str
);
10144 json_object_string_add(json_row
, "upTime", timebuf
);
10145 json_object_object_add(json_group
, src_str
, json_row
);
10147 vty_out(vty
, "%-15s %15s %15s %5c %3c %8s\n",
10148 src_str
, grp_str
, rp_str
, local_str
[0],
10149 spt_str
[0], timebuf
);
10154 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10155 json
, JSON_C_TO_STRING_PRETTY
));
10156 json_object_free(json
);
10160 static void ip_msdp_show_sa_entry_detail(struct pim_msdp_sa
*sa
,
10161 const char *src_str
,
10162 const char *grp_str
, struct vty
*vty
,
10163 bool uj
, json_object
*json
)
10165 char rp_str
[INET_ADDRSTRLEN
];
10166 char peer_str
[INET_ADDRSTRLEN
];
10167 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
10170 char statetimer
[PIM_MSDP_TIMER_STRLEN
];
10172 json_object
*json_group
= NULL
;
10173 json_object
*json_row
= NULL
;
10175 now
= pim_time_monotonic_sec();
10176 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
10177 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
10178 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
10179 pim_inet4_dump("<peer?>", sa
->peer
, peer_str
, sizeof(peer_str
));
10181 strlcpy(spt_str
, "yes", sizeof(spt_str
));
10183 strlcpy(spt_str
, "no", sizeof(spt_str
));
10186 strlcpy(rp_str
, "-", sizeof(rp_str
));
10187 strlcpy(peer_str
, "-", sizeof(peer_str
));
10188 strlcpy(spt_str
, "-", sizeof(spt_str
));
10190 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
10191 strlcpy(local_str
, "yes", sizeof(local_str
));
10193 strlcpy(local_str
, "no", sizeof(local_str
));
10195 pim_time_timer_to_hhmmss(statetimer
, sizeof(statetimer
),
10196 sa
->sa_state_timer
);
10198 json_object_object_get_ex(json
, grp_str
, &json_group
);
10201 json_group
= json_object_new_object();
10202 json_object_object_add(json
, grp_str
, json_group
);
10205 json_row
= json_object_new_object();
10206 json_object_string_add(json_row
, "source", src_str
);
10207 json_object_string_add(json_row
, "group", grp_str
);
10208 json_object_string_add(json_row
, "rp", rp_str
);
10209 json_object_string_add(json_row
, "local", local_str
);
10210 json_object_string_add(json_row
, "sptSetup", spt_str
);
10211 json_object_string_add(json_row
, "upTime", timebuf
);
10212 json_object_string_add(json_row
, "stateTimer", statetimer
);
10213 json_object_object_add(json_group
, src_str
, json_row
);
10215 vty_out(vty
, "SA : %s\n", sa
->sg_str
);
10216 vty_out(vty
, " RP : %s\n", rp_str
);
10217 vty_out(vty
, " Peer : %s\n", peer_str
);
10218 vty_out(vty
, " Local : %s\n", local_str
);
10219 vty_out(vty
, " SPT Setup : %s\n", spt_str
);
10220 vty_out(vty
, " Uptime : %s\n", timebuf
);
10221 vty_out(vty
, " State Timer : %s\n", statetimer
);
10222 vty_out(vty
, "\n");
10226 static void ip_msdp_show_sa_detail(struct pim_instance
*pim
, struct vty
*vty
,
10229 struct listnode
*sanode
;
10230 struct pim_msdp_sa
*sa
;
10231 char src_str
[INET_ADDRSTRLEN
];
10232 char grp_str
[INET_ADDRSTRLEN
];
10233 json_object
*json
= NULL
;
10236 json
= json_object_new_object();
10239 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
10240 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
10241 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
10242 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
, uj
,
10247 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10248 json
, JSON_C_TO_STRING_PRETTY
));
10249 json_object_free(json
);
10253 DEFUN (show_ip_msdp_sa_detail
,
10254 show_ip_msdp_sa_detail_cmd
,
10255 "show ip msdp [vrf NAME] sa detail [json]",
10260 "MSDP active-source information\n"
10261 "Detailed output\n"
10264 bool uj
= use_json(argc
, argv
);
10266 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10269 return CMD_WARNING
;
10271 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
10273 return CMD_SUCCESS
;
10276 DEFUN (show_ip_msdp_sa_detail_vrf_all
,
10277 show_ip_msdp_sa_detail_vrf_all_cmd
,
10278 "show ip msdp vrf all sa detail [json]",
10283 "MSDP active-source information\n"
10284 "Detailed output\n"
10287 bool uj
= use_json(argc
, argv
);
10292 vty_out(vty
, "{ ");
10293 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
10296 vty_out(vty
, ", ");
10297 vty_out(vty
, " \"%s\": ", vrf
->name
);
10300 vty_out(vty
, "VRF: %s\n", vrf
->name
);
10301 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
10304 vty_out(vty
, "}\n");
10306 return CMD_SUCCESS
;
10309 static void ip_msdp_show_sa_addr(struct pim_instance
*pim
, struct vty
*vty
,
10310 const char *addr
, bool uj
)
10312 struct listnode
*sanode
;
10313 struct pim_msdp_sa
*sa
;
10314 char src_str
[INET_ADDRSTRLEN
];
10315 char grp_str
[INET_ADDRSTRLEN
];
10316 json_object
*json
= NULL
;
10319 json
= json_object_new_object();
10322 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
10323 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
10324 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
10325 if (!strcmp(addr
, src_str
) || !strcmp(addr
, grp_str
)) {
10326 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
10332 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10333 json
, JSON_C_TO_STRING_PRETTY
));
10334 json_object_free(json
);
10338 static void ip_msdp_show_sa_sg(struct pim_instance
*pim
, struct vty
*vty
,
10339 const char *src
, const char *grp
, bool uj
)
10341 struct listnode
*sanode
;
10342 struct pim_msdp_sa
*sa
;
10343 char src_str
[INET_ADDRSTRLEN
];
10344 char grp_str
[INET_ADDRSTRLEN
];
10345 json_object
*json
= NULL
;
10348 json
= json_object_new_object();
10351 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
10352 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
10353 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
10354 if (!strcmp(src
, src_str
) && !strcmp(grp
, grp_str
)) {
10355 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
10361 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10362 json
, JSON_C_TO_STRING_PRETTY
));
10363 json_object_free(json
);
10367 DEFUN (show_ip_msdp_sa_sg
,
10368 show_ip_msdp_sa_sg_cmd
,
10369 "show ip msdp [vrf NAME] sa [A.B.C.D [A.B.C.D]] [json]",
10374 "MSDP active-source information\n"
10375 "source or group ip\n"
10379 bool uj
= use_json(argc
, argv
);
10383 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10386 return CMD_WARNING
;
10388 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
10390 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
10394 if (src_ip
&& grp_ip
)
10395 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
10397 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
10399 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
10401 return CMD_SUCCESS
;
10404 DEFUN (show_ip_msdp_sa_sg_vrf_all
,
10405 show_ip_msdp_sa_sg_vrf_all_cmd
,
10406 "show ip msdp vrf all sa [A.B.C.D [A.B.C.D]] [json]",
10411 "MSDP active-source information\n"
10412 "source or group ip\n"
10416 bool uj
= use_json(argc
, argv
);
10421 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
10423 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
10428 vty_out(vty
, "{ ");
10429 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
10432 vty_out(vty
, ", ");
10433 vty_out(vty
, " \"%s\": ", vrf
->name
);
10436 vty_out(vty
, "VRF: %s\n", vrf
->name
);
10438 if (src_ip
&& grp_ip
)
10439 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
10441 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
10443 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
10446 vty_out(vty
, "}\n");
10448 return CMD_SUCCESS
;
10451 struct pim_sg_cache_walk_data
{
10454 json_object
*json_group
;
10455 struct in_addr addr
;
10459 static void pim_show_vxlan_sg_entry(struct pim_vxlan_sg
*vxlan_sg
,
10460 struct pim_sg_cache_walk_data
*cwd
)
10462 struct vty
*vty
= cwd
->vty
;
10463 json_object
*json
= cwd
->json
;
10464 char src_str
[INET_ADDRSTRLEN
];
10465 char grp_str
[INET_ADDRSTRLEN
];
10466 json_object
*json_row
;
10467 bool installed
= (vxlan_sg
->up
) ? true : false;
10468 const char *iif_name
= vxlan_sg
->iif
?vxlan_sg
->iif
->name
:"-";
10469 const char *oif_name
;
10471 if (pim_vxlan_is_orig_mroute(vxlan_sg
))
10472 oif_name
= vxlan_sg
->orig_oif
?vxlan_sg
->orig_oif
->name
:"";
10474 oif_name
= vxlan_sg
->term_oif
?vxlan_sg
->term_oif
->name
:"";
10476 if (cwd
->addr_match
&& (vxlan_sg
->sg
.src
.s_addr
!= cwd
->addr
.s_addr
) &&
10477 (vxlan_sg
->sg
.grp
.s_addr
!= cwd
->addr
.s_addr
)) {
10480 pim_inet4_dump("<src?>", vxlan_sg
->sg
.src
, src_str
, sizeof(src_str
));
10481 pim_inet4_dump("<grp?>", vxlan_sg
->sg
.grp
, grp_str
, sizeof(grp_str
));
10483 json_object_object_get_ex(json
, grp_str
, &cwd
->json_group
);
10485 if (!cwd
->json_group
) {
10486 cwd
->json_group
= json_object_new_object();
10487 json_object_object_add(json
, grp_str
,
10491 json_row
= json_object_new_object();
10492 json_object_string_add(json_row
, "source", src_str
);
10493 json_object_string_add(json_row
, "group", grp_str
);
10494 json_object_string_add(json_row
, "input", iif_name
);
10495 json_object_string_add(json_row
, "output", oif_name
);
10497 json_object_boolean_true_add(json_row
, "installed");
10499 json_object_boolean_false_add(json_row
, "installed");
10500 json_object_object_add(cwd
->json_group
, src_str
, json_row
);
10502 vty_out(vty
, "%-15s %-15s %-15s %-15s %-5s\n",
10503 src_str
, grp_str
, iif_name
, oif_name
,
10508 static void pim_show_vxlan_sg_hash_entry(struct hash_bucket
*backet
, void *arg
)
10510 pim_show_vxlan_sg_entry((struct pim_vxlan_sg
*)backet
->data
,
10511 (struct pim_sg_cache_walk_data
*)arg
);
10514 static void pim_show_vxlan_sg(struct pim_instance
*pim
,
10515 struct vty
*vty
, bool uj
)
10517 json_object
*json
= NULL
;
10518 struct pim_sg_cache_walk_data cwd
;
10521 json
= json_object_new_object();
10523 vty_out(vty
, "Codes: I -> installed\n");
10525 "Source Group Input Output Flags\n");
10528 memset(&cwd
, 0, sizeof(cwd
));
10531 hash_iterate(pim
->vxlan
.sg_hash
, pim_show_vxlan_sg_hash_entry
, &cwd
);
10534 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10535 json
, JSON_C_TO_STRING_PRETTY
));
10536 json_object_free(json
);
10540 static void pim_show_vxlan_sg_match_addr(struct pim_instance
*pim
,
10541 struct vty
*vty
, char *addr_str
, bool uj
)
10543 json_object
*json
= NULL
;
10544 struct pim_sg_cache_walk_data cwd
;
10547 memset(&cwd
, 0, sizeof(cwd
));
10548 result
= inet_pton(AF_INET
, addr_str
, &cwd
.addr
);
10550 vty_out(vty
, "Bad address %s: errno=%d: %s\n", addr_str
,
10551 errno
, safe_strerror(errno
));
10556 json
= json_object_new_object();
10558 vty_out(vty
, "Codes: I -> installed\n");
10560 "Source Group Input Output Flags\n");
10565 cwd
.addr_match
= true;
10566 hash_iterate(pim
->vxlan
.sg_hash
, pim_show_vxlan_sg_hash_entry
, &cwd
);
10569 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10570 json
, JSON_C_TO_STRING_PRETTY
));
10571 json_object_free(json
);
10575 static void pim_show_vxlan_sg_one(struct pim_instance
*pim
,
10576 struct vty
*vty
, char *src_str
, char *grp_str
, bool uj
)
10578 json_object
*json
= NULL
;
10579 struct prefix_sg sg
;
10581 struct pim_vxlan_sg
*vxlan_sg
;
10582 const char *iif_name
;
10584 const char *oif_name
;
10586 result
= inet_pton(AF_INET
, src_str
, &sg
.src
);
10588 vty_out(vty
, "Bad src address %s: errno=%d: %s\n", src_str
,
10589 errno
, safe_strerror(errno
));
10592 result
= inet_pton(AF_INET
, grp_str
, &sg
.grp
);
10594 vty_out(vty
, "Bad grp address %s: errno=%d: %s\n", grp_str
,
10595 errno
, safe_strerror(errno
));
10599 sg
.family
= AF_INET
;
10600 sg
.prefixlen
= IPV4_MAX_BITLEN
;
10602 json
= json_object_new_object();
10604 vxlan_sg
= pim_vxlan_sg_find(pim
, &sg
);
10606 installed
= (vxlan_sg
->up
) ? true : false;
10607 iif_name
= vxlan_sg
->iif
?vxlan_sg
->iif
->name
:"-";
10609 if (pim_vxlan_is_orig_mroute(vxlan_sg
))
10611 vxlan_sg
->orig_oif
?vxlan_sg
->orig_oif
->name
:"";
10614 vxlan_sg
->term_oif
?vxlan_sg
->term_oif
->name
:"";
10617 json_object_string_add(json
, "source", src_str
);
10618 json_object_string_add(json
, "group", grp_str
);
10619 json_object_string_add(json
, "input", iif_name
);
10620 json_object_string_add(json
, "output", oif_name
);
10622 json_object_boolean_true_add(json
, "installed");
10624 json_object_boolean_false_add(json
,
10627 vty_out(vty
, "SG : %s\n", vxlan_sg
->sg_str
);
10628 vty_out(vty
, " Input : %s\n", iif_name
);
10629 vty_out(vty
, " Output : %s\n", oif_name
);
10630 vty_out(vty
, " installed : %s\n",
10631 installed
?"yes":"no");
10636 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10637 json
, JSON_C_TO_STRING_PRETTY
));
10638 json_object_free(json
);
10642 DEFUN (show_ip_pim_vxlan_sg
,
10643 show_ip_pim_vxlan_sg_cmd
,
10644 "show ip pim [vrf NAME] vxlan-groups [A.B.C.D [A.B.C.D]] [json]",
10649 "VxLAN BUM groups\n"
10650 "source or group ip\n"
10654 bool uj
= use_json(argc
, argv
);
10658 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10661 return CMD_WARNING
;
10663 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ?
10664 argv
[idx
++]->arg
:NULL
;
10665 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
) ?
10666 argv
[idx
]->arg
:NULL
;
10668 if (src_ip
&& grp_ip
)
10669 pim_show_vxlan_sg_one(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
10671 pim_show_vxlan_sg_match_addr(vrf
->info
, vty
, src_ip
, uj
);
10673 pim_show_vxlan_sg(vrf
->info
, vty
, uj
);
10675 return CMD_SUCCESS
;
10678 static void pim_show_vxlan_sg_work(struct pim_instance
*pim
,
10679 struct vty
*vty
, bool uj
)
10681 json_object
*json
= NULL
;
10682 struct pim_sg_cache_walk_data cwd
;
10683 struct listnode
*node
;
10684 struct pim_vxlan_sg
*vxlan_sg
;
10687 json
= json_object_new_object();
10689 vty_out(vty
, "Codes: I -> installed\n");
10691 "Source Group Input Flags\n");
10694 memset(&cwd
, 0, sizeof(cwd
));
10697 for (ALL_LIST_ELEMENTS_RO(pim_vxlan_p
->work_list
, node
, vxlan_sg
))
10698 pim_show_vxlan_sg_entry(vxlan_sg
, &cwd
);
10701 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10702 json
, JSON_C_TO_STRING_PRETTY
));
10703 json_object_free(json
);
10707 DEFUN_HIDDEN (show_ip_pim_vxlan_sg_work
,
10708 show_ip_pim_vxlan_sg_work_cmd
,
10709 "show ip pim [vrf NAME] vxlan-work [json]",
10714 "VxLAN work list\n"
10717 bool uj
= use_json(argc
, argv
);
10721 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10724 return CMD_WARNING
;
10726 pim_show_vxlan_sg_work(vrf
->info
, vty
, uj
);
10728 return CMD_SUCCESS
;
10731 DEFUN_HIDDEN (no_ip_pim_mlag
,
10732 no_ip_pim_mlag_cmd
,
10739 struct in_addr addr
;
10742 pim_vxlan_mlag_update(true/*mlag_enable*/,
10743 false/*peer_state*/, MLAG_ROLE_NONE
,
10744 NULL
/*peerlink*/, &addr
);
10746 return CMD_SUCCESS
;
10749 DEFUN_HIDDEN (ip_pim_mlag
,
10751 "ip pim mlag INTERFACE role [primary|secondary] state [up|down] addr A.B.C.D",
10755 "peerlink sub interface\n"
10757 "MLAG role primary\n"
10758 "MLAG role secondary\n"
10759 "peer session state\n"
10760 "peer session state up\n"
10761 "peer session state down\n"
10763 "unique ip address\n")
10765 struct interface
*ifp
;
10766 const char *peerlink
;
10771 struct in_addr reg_addr
;
10774 peerlink
= argv
[idx
]->arg
;
10775 ifp
= if_lookup_by_name(peerlink
, VRF_DEFAULT
);
10777 vty_out(vty
, "No such interface name %s\n", peerlink
);
10778 return CMD_WARNING
;
10782 if (!strcmp(argv
[idx
]->arg
, "primary")) {
10783 role
= MLAG_ROLE_PRIMARY
;
10784 } else if (!strcmp(argv
[idx
]->arg
, "secondary")) {
10785 role
= MLAG_ROLE_SECONDARY
;
10787 vty_out(vty
, "unknown MLAG role %s\n", argv
[idx
]->arg
);
10788 return CMD_WARNING
;
10792 if (!strcmp(argv
[idx
]->arg
, "up")) {
10794 } else if (strcmp(argv
[idx
]->arg
, "down")) {
10795 peer_state
= false;
10797 vty_out(vty
, "unknown MLAG state %s\n", argv
[idx
]->arg
);
10798 return CMD_WARNING
;
10802 result
= inet_pton(AF_INET
, argv
[idx
]->arg
, ®_addr
);
10804 vty_out(vty
, "%% Bad reg address %s: errno=%d: %s\n",
10806 errno
, safe_strerror(errno
));
10807 return CMD_WARNING_CONFIG_FAILED
;
10809 pim_vxlan_mlag_update(true, peer_state
, role
, ifp
, ®_addr
);
10811 return CMD_SUCCESS
;
10814 void pim_cmd_init(void)
10816 install_node(&interface_node
,
10817 pim_interface_config_write
); /* INTERFACE_NODE */
10820 install_node(&debug_node
, pim_debug_config_write
);
10822 install_element(ENABLE_NODE
, &pim_test_sg_keepalive_cmd
);
10824 install_element(CONFIG_NODE
, &ip_pim_rp_cmd
);
10825 install_element(VRF_NODE
, &ip_pim_rp_cmd
);
10826 install_element(CONFIG_NODE
, &no_ip_pim_rp_cmd
);
10827 install_element(VRF_NODE
, &no_ip_pim_rp_cmd
);
10828 install_element(CONFIG_NODE
, &ip_pim_rp_prefix_list_cmd
);
10829 install_element(VRF_NODE
, &ip_pim_rp_prefix_list_cmd
);
10830 install_element(CONFIG_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
10831 install_element(VRF_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
10832 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
10833 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
10834 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
10835 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
10836 install_element(CONFIG_NODE
, &ip_pim_ssm_prefix_list_cmd
);
10837 install_element(VRF_NODE
, &ip_pim_ssm_prefix_list_cmd
);
10838 install_element(CONFIG_NODE
, &ip_pim_register_suppress_cmd
);
10839 install_element(VRF_NODE
, &ip_pim_register_suppress_cmd
);
10840 install_element(CONFIG_NODE
, &no_ip_pim_register_suppress_cmd
);
10841 install_element(VRF_NODE
, &no_ip_pim_register_suppress_cmd
);
10842 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
10843 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
10844 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
10845 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
10846 install_element(CONFIG_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
10847 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
10848 install_element(CONFIG_NODE
,
10849 &no_ip_pim_spt_switchover_infinity_plist_cmd
);
10850 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_plist_cmd
);
10851 install_element(CONFIG_NODE
, &pim_register_accept_list_cmd
);
10852 install_element(VRF_NODE
, &pim_register_accept_list_cmd
);
10853 install_element(CONFIG_NODE
, &ip_pim_joinprune_time_cmd
);
10854 install_element(VRF_NODE
, &ip_pim_joinprune_time_cmd
);
10855 install_element(CONFIG_NODE
, &no_ip_pim_joinprune_time_cmd
);
10856 install_element(VRF_NODE
, &no_ip_pim_joinprune_time_cmd
);
10857 install_element(CONFIG_NODE
, &ip_pim_keep_alive_cmd
);
10858 install_element(VRF_NODE
, &ip_pim_keep_alive_cmd
);
10859 install_element(CONFIG_NODE
, &ip_pim_rp_keep_alive_cmd
);
10860 install_element(VRF_NODE
, &ip_pim_rp_keep_alive_cmd
);
10861 install_element(CONFIG_NODE
, &no_ip_pim_keep_alive_cmd
);
10862 install_element(VRF_NODE
, &no_ip_pim_keep_alive_cmd
);
10863 install_element(CONFIG_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
10864 install_element(VRF_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
10865 install_element(CONFIG_NODE
, &ip_pim_packets_cmd
);
10866 install_element(VRF_NODE
, &ip_pim_packets_cmd
);
10867 install_element(CONFIG_NODE
, &no_ip_pim_packets_cmd
);
10868 install_element(VRF_NODE
, &no_ip_pim_packets_cmd
);
10869 install_element(CONFIG_NODE
, &ip_pim_v6_secondary_cmd
);
10870 install_element(VRF_NODE
, &ip_pim_v6_secondary_cmd
);
10871 install_element(CONFIG_NODE
, &no_ip_pim_v6_secondary_cmd
);
10872 install_element(VRF_NODE
, &no_ip_pim_v6_secondary_cmd
);
10873 install_element(CONFIG_NODE
, &ip_ssmpingd_cmd
);
10874 install_element(VRF_NODE
, &ip_ssmpingd_cmd
);
10875 install_element(CONFIG_NODE
, &no_ip_ssmpingd_cmd
);
10876 install_element(VRF_NODE
, &no_ip_ssmpingd_cmd
);
10877 install_element(CONFIG_NODE
, &ip_msdp_peer_cmd
);
10878 install_element(VRF_NODE
, &ip_msdp_peer_cmd
);
10879 install_element(CONFIG_NODE
, &no_ip_msdp_peer_cmd
);
10880 install_element(VRF_NODE
, &no_ip_msdp_peer_cmd
);
10881 install_element(CONFIG_NODE
, &ip_pim_ecmp_cmd
);
10882 install_element(VRF_NODE
, &ip_pim_ecmp_cmd
);
10883 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_cmd
);
10884 install_element(VRF_NODE
, &no_ip_pim_ecmp_cmd
);
10885 install_element(CONFIG_NODE
, &ip_pim_ecmp_rebalance_cmd
);
10886 install_element(VRF_NODE
, &ip_pim_ecmp_rebalance_cmd
);
10887 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
10888 install_element(VRF_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
10889 install_element(CONFIG_NODE
, &ip_pim_mlag_cmd
);
10890 install_element(CONFIG_NODE
, &no_ip_pim_mlag_cmd
);
10892 install_element(INTERFACE_NODE
, &interface_ip_igmp_cmd
);
10893 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_cmd
);
10894 install_element(INTERFACE_NODE
, &interface_ip_igmp_join_cmd
);
10895 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_join_cmd
);
10896 install_element(INTERFACE_NODE
, &interface_ip_igmp_version_cmd
);
10897 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_version_cmd
);
10898 install_element(INTERFACE_NODE
, &interface_ip_igmp_query_interval_cmd
);
10899 install_element(INTERFACE_NODE
,
10900 &interface_no_ip_igmp_query_interval_cmd
);
10901 install_element(INTERFACE_NODE
,
10902 &interface_ip_igmp_query_max_response_time_cmd
);
10903 install_element(INTERFACE_NODE
,
10904 &interface_no_ip_igmp_query_max_response_time_cmd
);
10905 install_element(INTERFACE_NODE
,
10906 &interface_ip_igmp_query_max_response_time_dsec_cmd
);
10907 install_element(INTERFACE_NODE
,
10908 &interface_no_ip_igmp_query_max_response_time_dsec_cmd
);
10909 install_element(INTERFACE_NODE
,
10910 &interface_ip_igmp_last_member_query_count_cmd
);
10911 install_element(INTERFACE_NODE
,
10912 &interface_no_ip_igmp_last_member_query_count_cmd
);
10913 install_element(INTERFACE_NODE
,
10914 &interface_ip_igmp_last_member_query_interval_cmd
);
10915 install_element(INTERFACE_NODE
,
10916 &interface_no_ip_igmp_last_member_query_interval_cmd
);
10917 install_element(INTERFACE_NODE
, &interface_ip_pim_activeactive_cmd
);
10918 install_element(INTERFACE_NODE
, &interface_ip_pim_ssm_cmd
);
10919 install_element(INTERFACE_NODE
, &interface_no_ip_pim_ssm_cmd
);
10920 install_element(INTERFACE_NODE
, &interface_ip_pim_sm_cmd
);
10921 install_element(INTERFACE_NODE
, &interface_no_ip_pim_sm_cmd
);
10922 install_element(INTERFACE_NODE
, &interface_ip_pim_cmd
);
10923 install_element(INTERFACE_NODE
, &interface_no_ip_pim_cmd
);
10924 install_element(INTERFACE_NODE
, &interface_ip_pim_drprio_cmd
);
10925 install_element(INTERFACE_NODE
, &interface_no_ip_pim_drprio_cmd
);
10926 install_element(INTERFACE_NODE
, &interface_ip_pim_hello_cmd
);
10927 install_element(INTERFACE_NODE
, &interface_no_ip_pim_hello_cmd
);
10928 install_element(INTERFACE_NODE
, &interface_ip_pim_boundary_oil_cmd
);
10929 install_element(INTERFACE_NODE
, &interface_no_ip_pim_boundary_oil_cmd
);
10930 install_element(INTERFACE_NODE
, &interface_ip_igmp_query_generate_cmd
);
10932 // Static mroutes NEB
10933 install_element(INTERFACE_NODE
, &interface_ip_mroute_cmd
);
10934 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_cmd
);
10936 install_element(VIEW_NODE
, &show_ip_igmp_interface_cmd
);
10937 install_element(VIEW_NODE
, &show_ip_igmp_interface_vrf_all_cmd
);
10938 install_element(VIEW_NODE
, &show_ip_igmp_join_cmd
);
10939 install_element(VIEW_NODE
, &show_ip_igmp_join_vrf_all_cmd
);
10940 install_element(VIEW_NODE
, &show_ip_igmp_groups_cmd
);
10941 install_element(VIEW_NODE
, &show_ip_igmp_groups_vrf_all_cmd
);
10942 install_element(VIEW_NODE
, &show_ip_igmp_groups_retransmissions_cmd
);
10943 install_element(VIEW_NODE
, &show_ip_igmp_sources_cmd
);
10944 install_element(VIEW_NODE
, &show_ip_igmp_sources_retransmissions_cmd
);
10945 install_element(VIEW_NODE
, &show_ip_igmp_statistics_cmd
);
10946 install_element(VIEW_NODE
, &show_ip_pim_assert_cmd
);
10947 install_element(VIEW_NODE
, &show_ip_pim_assert_internal_cmd
);
10948 install_element(VIEW_NODE
, &show_ip_pim_assert_metric_cmd
);
10949 install_element(VIEW_NODE
, &show_ip_pim_assert_winner_metric_cmd
);
10950 install_element(VIEW_NODE
, &show_ip_pim_interface_traffic_cmd
);
10951 install_element(VIEW_NODE
, &show_ip_pim_interface_cmd
);
10952 install_element(VIEW_NODE
, &show_ip_pim_interface_vrf_all_cmd
);
10953 install_element(VIEW_NODE
, &show_ip_pim_join_cmd
);
10954 install_element(VIEW_NODE
, &show_ip_pim_join_vrf_all_cmd
);
10955 install_element(VIEW_NODE
, &show_ip_pim_jp_agg_cmd
);
10956 install_element(VIEW_NODE
, &show_ip_pim_local_membership_cmd
);
10957 install_element(VIEW_NODE
, &show_ip_pim_mlag_summary_cmd
);
10958 install_element(VIEW_NODE
, &show_ip_pim_mlag_up_cmd
);
10959 install_element(VIEW_NODE
, &show_ip_pim_mlag_up_vrf_all_cmd
);
10960 install_element(VIEW_NODE
, &show_ip_pim_neighbor_cmd
);
10961 install_element(VIEW_NODE
, &show_ip_pim_neighbor_vrf_all_cmd
);
10962 install_element(VIEW_NODE
, &show_ip_pim_rpf_cmd
);
10963 install_element(VIEW_NODE
, &show_ip_pim_rpf_vrf_all_cmd
);
10964 install_element(VIEW_NODE
, &show_ip_pim_secondary_cmd
);
10965 install_element(VIEW_NODE
, &show_ip_pim_state_cmd
);
10966 install_element(VIEW_NODE
, &show_ip_pim_state_vrf_all_cmd
);
10967 install_element(VIEW_NODE
, &show_ip_pim_upstream_cmd
);
10968 install_element(VIEW_NODE
, &show_ip_pim_upstream_vrf_all_cmd
);
10969 install_element(VIEW_NODE
, &show_ip_pim_channel_cmd
);
10970 install_element(VIEW_NODE
, &show_ip_pim_upstream_join_desired_cmd
);
10971 install_element(VIEW_NODE
, &show_ip_pim_upstream_rpf_cmd
);
10972 install_element(VIEW_NODE
, &show_ip_pim_rp_cmd
);
10973 install_element(VIEW_NODE
, &show_ip_pim_rp_vrf_all_cmd
);
10974 install_element(VIEW_NODE
, &show_ip_pim_bsr_cmd
);
10975 install_element(VIEW_NODE
, &show_ip_multicast_cmd
);
10976 install_element(VIEW_NODE
, &show_ip_multicast_vrf_all_cmd
);
10977 install_element(VIEW_NODE
, &show_ip_mroute_cmd
);
10978 install_element(VIEW_NODE
, &show_ip_mroute_vrf_all_cmd
);
10979 install_element(VIEW_NODE
, &show_ip_mroute_count_cmd
);
10980 install_element(VIEW_NODE
, &show_ip_mroute_count_vrf_all_cmd
);
10981 install_element(VIEW_NODE
, &show_ip_mroute_summary_cmd
);
10982 install_element(VIEW_NODE
, &show_ip_mroute_summary_vrf_all_cmd
);
10983 install_element(VIEW_NODE
, &show_ip_rib_cmd
);
10984 install_element(VIEW_NODE
, &show_ip_ssmpingd_cmd
);
10985 install_element(VIEW_NODE
, &show_debugging_pim_cmd
);
10986 install_element(VIEW_NODE
, &show_ip_pim_nexthop_cmd
);
10987 install_element(VIEW_NODE
, &show_ip_pim_nexthop_lookup_cmd
);
10988 install_element(VIEW_NODE
, &show_ip_pim_bsrp_cmd
);
10989 install_element(VIEW_NODE
, &show_ip_pim_bsm_db_cmd
);
10990 install_element(VIEW_NODE
, &show_ip_pim_statistics_cmd
);
10992 install_element(ENABLE_NODE
, &clear_ip_mroute_count_cmd
);
10993 install_element(ENABLE_NODE
, &clear_ip_interfaces_cmd
);
10994 install_element(ENABLE_NODE
, &clear_ip_igmp_interfaces_cmd
);
10995 install_element(ENABLE_NODE
, &clear_ip_mroute_cmd
);
10996 install_element(ENABLE_NODE
, &clear_ip_pim_interfaces_cmd
);
10997 install_element(ENABLE_NODE
, &clear_ip_pim_interface_traffic_cmd
);
10998 install_element(ENABLE_NODE
, &clear_ip_pim_oil_cmd
);
10999 install_element(ENABLE_NODE
, &clear_ip_pim_statistics_cmd
);
11001 install_element(ENABLE_NODE
, &debug_igmp_cmd
);
11002 install_element(ENABLE_NODE
, &no_debug_igmp_cmd
);
11003 install_element(ENABLE_NODE
, &debug_igmp_events_cmd
);
11004 install_element(ENABLE_NODE
, &no_debug_igmp_events_cmd
);
11005 install_element(ENABLE_NODE
, &debug_igmp_packets_cmd
);
11006 install_element(ENABLE_NODE
, &no_debug_igmp_packets_cmd
);
11007 install_element(ENABLE_NODE
, &debug_igmp_trace_cmd
);
11008 install_element(ENABLE_NODE
, &no_debug_igmp_trace_cmd
);
11009 install_element(ENABLE_NODE
, &debug_mroute_cmd
);
11010 install_element(ENABLE_NODE
, &debug_mroute_detail_cmd
);
11011 install_element(ENABLE_NODE
, &no_debug_mroute_cmd
);
11012 install_element(ENABLE_NODE
, &no_debug_mroute_detail_cmd
);
11013 install_element(ENABLE_NODE
, &debug_pim_static_cmd
);
11014 install_element(ENABLE_NODE
, &no_debug_pim_static_cmd
);
11015 install_element(ENABLE_NODE
, &debug_pim_cmd
);
11016 install_element(ENABLE_NODE
, &no_debug_pim_cmd
);
11017 install_element(ENABLE_NODE
, &debug_pim_nht_cmd
);
11018 install_element(ENABLE_NODE
, &no_debug_pim_nht_cmd
);
11019 install_element(ENABLE_NODE
, &debug_pim_nht_rp_cmd
);
11020 install_element(ENABLE_NODE
, &no_debug_pim_nht_rp_cmd
);
11021 install_element(ENABLE_NODE
, &debug_pim_events_cmd
);
11022 install_element(ENABLE_NODE
, &no_debug_pim_events_cmd
);
11023 install_element(ENABLE_NODE
, &debug_pim_packets_cmd
);
11024 install_element(ENABLE_NODE
, &no_debug_pim_packets_cmd
);
11025 install_element(ENABLE_NODE
, &debug_pim_packetdump_send_cmd
);
11026 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_send_cmd
);
11027 install_element(ENABLE_NODE
, &debug_pim_packetdump_recv_cmd
);
11028 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_recv_cmd
);
11029 install_element(ENABLE_NODE
, &debug_pim_trace_cmd
);
11030 install_element(ENABLE_NODE
, &no_debug_pim_trace_cmd
);
11031 install_element(ENABLE_NODE
, &debug_pim_trace_detail_cmd
);
11032 install_element(ENABLE_NODE
, &no_debug_pim_trace_detail_cmd
);
11033 install_element(ENABLE_NODE
, &debug_ssmpingd_cmd
);
11034 install_element(ENABLE_NODE
, &no_debug_ssmpingd_cmd
);
11035 install_element(ENABLE_NODE
, &debug_pim_zebra_cmd
);
11036 install_element(ENABLE_NODE
, &no_debug_pim_zebra_cmd
);
11037 install_element(ENABLE_NODE
, &debug_pim_mlag_cmd
);
11038 install_element(ENABLE_NODE
, &no_debug_pim_mlag_cmd
);
11039 install_element(ENABLE_NODE
, &debug_pim_vxlan_cmd
);
11040 install_element(ENABLE_NODE
, &no_debug_pim_vxlan_cmd
);
11041 install_element(ENABLE_NODE
, &debug_msdp_cmd
);
11042 install_element(ENABLE_NODE
, &no_debug_msdp_cmd
);
11043 install_element(ENABLE_NODE
, &debug_msdp_events_cmd
);
11044 install_element(ENABLE_NODE
, &no_debug_msdp_events_cmd
);
11045 install_element(ENABLE_NODE
, &debug_msdp_packets_cmd
);
11046 install_element(ENABLE_NODE
, &no_debug_msdp_packets_cmd
);
11047 install_element(ENABLE_NODE
, &debug_mtrace_cmd
);
11048 install_element(ENABLE_NODE
, &no_debug_mtrace_cmd
);
11049 install_element(ENABLE_NODE
, &debug_bsm_cmd
);
11050 install_element(ENABLE_NODE
, &no_debug_bsm_cmd
);
11052 install_element(CONFIG_NODE
, &debug_igmp_cmd
);
11053 install_element(CONFIG_NODE
, &no_debug_igmp_cmd
);
11054 install_element(CONFIG_NODE
, &debug_igmp_events_cmd
);
11055 install_element(CONFIG_NODE
, &no_debug_igmp_events_cmd
);
11056 install_element(CONFIG_NODE
, &debug_igmp_packets_cmd
);
11057 install_element(CONFIG_NODE
, &no_debug_igmp_packets_cmd
);
11058 install_element(CONFIG_NODE
, &debug_igmp_trace_cmd
);
11059 install_element(CONFIG_NODE
, &no_debug_igmp_trace_cmd
);
11060 install_element(CONFIG_NODE
, &debug_mroute_cmd
);
11061 install_element(CONFIG_NODE
, &debug_mroute_detail_cmd
);
11062 install_element(CONFIG_NODE
, &no_debug_mroute_cmd
);
11063 install_element(CONFIG_NODE
, &no_debug_mroute_detail_cmd
);
11064 install_element(CONFIG_NODE
, &debug_pim_static_cmd
);
11065 install_element(CONFIG_NODE
, &no_debug_pim_static_cmd
);
11066 install_element(CONFIG_NODE
, &debug_pim_cmd
);
11067 install_element(CONFIG_NODE
, &no_debug_pim_cmd
);
11068 install_element(CONFIG_NODE
, &debug_pim_nht_cmd
);
11069 install_element(CONFIG_NODE
, &no_debug_pim_nht_cmd
);
11070 install_element(CONFIG_NODE
, &debug_pim_nht_rp_cmd
);
11071 install_element(CONFIG_NODE
, &no_debug_pim_nht_rp_cmd
);
11072 install_element(CONFIG_NODE
, &debug_pim_events_cmd
);
11073 install_element(CONFIG_NODE
, &no_debug_pim_events_cmd
);
11074 install_element(CONFIG_NODE
, &debug_pim_packets_cmd
);
11075 install_element(CONFIG_NODE
, &no_debug_pim_packets_cmd
);
11076 install_element(CONFIG_NODE
, &debug_pim_trace_cmd
);
11077 install_element(CONFIG_NODE
, &no_debug_pim_trace_cmd
);
11078 install_element(CONFIG_NODE
, &debug_pim_trace_detail_cmd
);
11079 install_element(CONFIG_NODE
, &no_debug_pim_trace_detail_cmd
);
11080 install_element(CONFIG_NODE
, &debug_ssmpingd_cmd
);
11081 install_element(CONFIG_NODE
, &no_debug_ssmpingd_cmd
);
11082 install_element(CONFIG_NODE
, &debug_pim_zebra_cmd
);
11083 install_element(CONFIG_NODE
, &no_debug_pim_zebra_cmd
);
11084 install_element(CONFIG_NODE
, &debug_pim_mlag_cmd
);
11085 install_element(CONFIG_NODE
, &no_debug_pim_mlag_cmd
);
11086 install_element(CONFIG_NODE
, &debug_pim_vxlan_cmd
);
11087 install_element(CONFIG_NODE
, &no_debug_pim_vxlan_cmd
);
11088 install_element(CONFIG_NODE
, &debug_msdp_cmd
);
11089 install_element(CONFIG_NODE
, &no_debug_msdp_cmd
);
11090 install_element(CONFIG_NODE
, &debug_msdp_events_cmd
);
11091 install_element(CONFIG_NODE
, &no_debug_msdp_events_cmd
);
11092 install_element(CONFIG_NODE
, &debug_msdp_packets_cmd
);
11093 install_element(CONFIG_NODE
, &no_debug_msdp_packets_cmd
);
11094 install_element(CONFIG_NODE
, &debug_mtrace_cmd
);
11095 install_element(CONFIG_NODE
, &no_debug_mtrace_cmd
);
11096 install_element(CONFIG_NODE
, &debug_bsm_cmd
);
11097 install_element(CONFIG_NODE
, &no_debug_bsm_cmd
);
11099 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_member_cmd
);
11100 install_element(VRF_NODE
, &ip_msdp_mesh_group_member_cmd
);
11101 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
11102 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
11103 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_source_cmd
);
11104 install_element(VRF_NODE
, &ip_msdp_mesh_group_source_cmd
);
11105 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
11106 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
11107 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_cmd
);
11108 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_vrf_all_cmd
);
11109 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_cmd
);
11110 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_vrf_all_cmd
);
11111 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_cmd
);
11112 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_vrf_all_cmd
);
11113 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_cmd
);
11114 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_vrf_all_cmd
);
11115 install_element(VIEW_NODE
, &show_ip_pim_ssm_range_cmd
);
11116 install_element(VIEW_NODE
, &show_ip_pim_group_type_cmd
);
11117 install_element(VIEW_NODE
, &show_ip_pim_vxlan_sg_cmd
);
11118 install_element(VIEW_NODE
, &show_ip_pim_vxlan_sg_work_cmd
);
11119 install_element(INTERFACE_NODE
, &interface_pim_use_source_cmd
);
11120 install_element(INTERFACE_NODE
, &interface_no_pim_use_source_cmd
);
11121 /* Install BSM command */
11122 install_element(INTERFACE_NODE
, &ip_pim_bsm_cmd
);
11123 install_element(INTERFACE_NODE
, &no_ip_pim_bsm_cmd
);
11124 install_element(INTERFACE_NODE
, &ip_pim_ucast_bsm_cmd
);
11125 install_element(INTERFACE_NODE
, &no_ip_pim_ucast_bsm_cmd
);
11126 /* Install BFD command */
11127 install_element(INTERFACE_NODE
, &ip_pim_bfd_cmd
);
11128 install_element(INTERFACE_NODE
, &ip_pim_bfd_param_cmd
);
11129 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_cmd
);
11131 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_param_cmd
);
11132 #endif /* !HAVE_BFDD */