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
[INET_ADDRSTRLEN
];
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
[INET_ADDRSTRLEN
];
3197 prefix2str(&bsgrp
->group
, grp_str
, sizeof(grp_str
));
3200 json_object_object_get_ex(json
, grp_str
, &json_group
);
3202 json_group
= json_object_new_object();
3203 json_object_object_add(json
, grp_str
,
3207 vty_out(vty
, "Group Address %s\n", grp_str
);
3208 vty_out(vty
, "--------------------------\n");
3209 vty_out(vty
, "%-15s %-15s %-15s %-15s\n", "Rp Address",
3210 "priority", "Holdtime", "Hash");
3212 vty_out(vty
, "(ACTIVE)\n");
3215 if (bsgrp
->bsrp_list
) {
3216 for (ALL_LIST_ELEMENTS_RO(bsgrp
->bsrp_list
, rpnode
,
3218 char rp_str
[INET_ADDRSTRLEN
];
3220 pim_inet4_dump("<Rp Address?>",
3221 bsm_rp
->rp_address
, rp_str
,
3225 json_row
= json_object_new_object();
3226 json_object_string_add(
3227 json_row
, "Rp Address", rp_str
);
3228 json_object_int_add(
3229 json_row
, "Rp HoldTime",
3230 bsm_rp
->rp_holdtime
);
3231 json_object_int_add(json_row
,
3234 json_object_int_add(json_row
,
3237 json_object_object_add(
3238 json_group
, rp_str
, json_row
);
3242 "%-15s %-15u %-15u %-15u\n",
3243 rp_str
, bsm_rp
->rp_prio
,
3244 bsm_rp
->rp_holdtime
,
3248 if (!bsgrp
->bsrp_list
->count
&& !uj
)
3249 vty_out(vty
, "Active List is empty.\n");
3253 json_object_int_add(json_group
, "Pending RP count",
3254 bsgrp
->pend_rp_cnt
);
3256 vty_out(vty
, "(PENDING)\n");
3257 vty_out(vty
, "Pending RP count :%d\n",
3258 bsgrp
->pend_rp_cnt
);
3259 if (bsgrp
->pend_rp_cnt
)
3260 vty_out(vty
, "%-15s %-15s %-15s %-15s\n",
3261 "Rp Address", "priority", "Holdtime",
3265 if (bsgrp
->partial_bsrp_list
) {
3266 for (ALL_LIST_ELEMENTS_RO(bsgrp
->partial_bsrp_list
,
3268 char rp_str
[INET_ADDRSTRLEN
];
3270 pim_inet4_dump("<Rp Addr?>", bsm_rp
->rp_address
,
3271 rp_str
, sizeof(rp_str
));
3274 json_row
= json_object_new_object();
3275 json_object_string_add(
3276 json_row
, "Rp Address", rp_str
);
3277 json_object_int_add(
3278 json_row
, "Rp HoldTime",
3279 bsm_rp
->rp_holdtime
);
3280 json_object_int_add(json_row
,
3283 json_object_int_add(json_row
,
3286 json_object_object_add(
3287 json_group
, rp_str
, json_row
);
3290 "%-15s %-15u %-15u %-15u\n",
3291 rp_str
, bsm_rp
->rp_prio
,
3292 bsm_rp
->rp_holdtime
,
3296 if (!bsgrp
->partial_bsrp_list
->count
&& !uj
)
3297 vty_out(vty
, "Partial List is empty\n");
3305 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3306 json
, JSON_C_TO_STRING_PRETTY
));
3307 json_object_free(json
);
3311 /* pim statistics - just adding only bsm related now.
3312 * We can continue to add all pim related stats here.
3314 static void pim_show_statistics(struct pim_instance
*pim
, struct vty
*vty
,
3315 const char *ifname
, bool uj
)
3317 json_object
*json
= NULL
;
3318 struct interface
*ifp
;
3321 json
= json_object_new_object();
3322 json_object_int_add(json
, "Number of Received BSMs",
3324 json_object_int_add(json
, "Number of Forwared BSMs",
3326 json_object_int_add(json
, "Number of Dropped BSMs",
3329 vty_out(vty
, "BSM Statistics :\n");
3330 vty_out(vty
, "----------------\n");
3331 vty_out(vty
, "Number of Received BSMs : %" PRIu64
"\n",
3333 vty_out(vty
, "Number of Forwared BSMs : %" PRIu64
"\n",
3335 vty_out(vty
, "Number of Dropped BSMs : %" PRIu64
"\n",
3341 /* scan interfaces */
3342 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3343 struct pim_interface
*pim_ifp
= ifp
->info
;
3345 if (ifname
&& strcmp(ifname
, ifp
->name
))
3352 vty_out(vty
, "Interface : %s\n", ifp
->name
);
3353 vty_out(vty
, "-------------------\n");
3355 "Number of BSMs dropped due to config miss : %u\n",
3356 pim_ifp
->pim_ifstat_bsm_cfg_miss
);
3357 vty_out(vty
, "Number of unicast BSMs dropped : %u\n",
3358 pim_ifp
->pim_ifstat_ucast_bsm_cfg_miss
);
3360 "Number of BSMs dropped due to invalid scope zone : %u\n",
3361 pim_ifp
->pim_ifstat_bsm_invalid_sz
);
3364 json_object
*json_row
= NULL
;
3366 json_row
= json_object_new_object();
3368 json_object_string_add(json_row
, "If Name", ifp
->name
);
3369 json_object_int_add(
3371 "Number of BSMs dropped due to config miss",
3372 pim_ifp
->pim_ifstat_bsm_cfg_miss
);
3373 json_object_int_add(
3374 json_row
, "Number of unicast BSMs dropped",
3375 pim_ifp
->pim_ifstat_ucast_bsm_cfg_miss
);
3376 json_object_int_add(json_row
,
3377 "Number of BSMs dropped due to invalid scope zone",
3378 pim_ifp
->pim_ifstat_bsm_invalid_sz
);
3379 json_object_object_add(json
, ifp
->name
, json_row
);
3385 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3386 json
, JSON_C_TO_STRING_PRETTY
));
3387 json_object_free(json
);
3391 static void clear_pim_statistics(struct pim_instance
*pim
)
3393 struct interface
*ifp
;
3397 pim
->bsm_dropped
= 0;
3399 /* scan interfaces */
3400 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3401 struct pim_interface
*pim_ifp
= ifp
->info
;
3406 pim_ifp
->pim_ifstat_bsm_cfg_miss
= 0;
3407 pim_ifp
->pim_ifstat_ucast_bsm_cfg_miss
= 0;
3408 pim_ifp
->pim_ifstat_bsm_invalid_sz
= 0;
3412 static void igmp_show_groups(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
3414 struct interface
*ifp
;
3416 json_object
*json
= NULL
;
3417 json_object
*json_iface
= NULL
;
3418 json_object
*json_row
= NULL
;
3420 now
= pim_time_monotonic_sec();
3423 json
= json_object_new_object();
3426 "Interface Address Group Mode Timer Srcs V Uptime \n");
3428 /* scan interfaces */
3429 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3430 struct pim_interface
*pim_ifp
= ifp
->info
;
3431 struct listnode
*sock_node
;
3432 struct igmp_sock
*igmp
;
3437 /* scan igmp sockets */
3438 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3440 char ifaddr_str
[INET_ADDRSTRLEN
];
3441 struct listnode
*grpnode
;
3442 struct igmp_group
*grp
;
3444 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3445 sizeof(ifaddr_str
));
3447 /* scan igmp groups */
3448 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3450 char group_str
[INET_ADDRSTRLEN
];
3454 pim_inet4_dump("<group?>", grp
->group_addr
,
3455 group_str
, sizeof(group_str
));
3456 pim_time_timer_to_hhmmss(hhmmss
, sizeof(hhmmss
),
3457 grp
->t_group_timer
);
3458 pim_time_uptime(uptime
, sizeof(uptime
),
3459 now
- grp
->group_creation
);
3462 json_object_object_get_ex(
3463 json
, ifp
->name
, &json_iface
);
3467 json_object_new_object();
3468 json_object_pim_ifp_add(
3470 json_object_object_add(
3475 json_row
= json_object_new_object();
3476 json_object_string_add(
3477 json_row
, "source", ifaddr_str
);
3478 json_object_string_add(
3479 json_row
, "group", group_str
);
3481 if (grp
->igmp_version
== 3)
3482 json_object_string_add(
3484 grp
->group_filtermode_isexcl
3488 json_object_string_add(json_row
,
3490 json_object_int_add(
3491 json_row
, "sourcesCount",
3492 grp
->group_source_list
3494 grp
->group_source_list
)
3496 json_object_int_add(json_row
, "version",
3498 json_object_string_add(
3499 json_row
, "uptime", uptime
);
3500 json_object_object_add(json_iface
,
3506 "%-16s %-15s %-15s %4s %8s %4d %d %8s\n",
3507 ifp
->name
, ifaddr_str
,
3509 grp
->igmp_version
== 3
3510 ? (grp
->group_filtermode_isexcl
3515 grp
->group_source_list
3517 grp
->group_source_list
)
3519 grp
->igmp_version
, uptime
);
3521 } /* scan igmp groups */
3522 } /* scan igmp sockets */
3523 } /* scan interfaces */
3526 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3527 json
, JSON_C_TO_STRING_PRETTY
));
3528 json_object_free(json
);
3532 static void igmp_show_group_retransmission(struct pim_instance
*pim
,
3535 struct interface
*ifp
;
3538 "Interface Address Group RetTimer Counter RetSrcs\n");
3540 /* scan interfaces */
3541 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3542 struct pim_interface
*pim_ifp
= ifp
->info
;
3543 struct listnode
*sock_node
;
3544 struct igmp_sock
*igmp
;
3549 /* scan igmp sockets */
3550 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3552 char ifaddr_str
[INET_ADDRSTRLEN
];
3553 struct listnode
*grpnode
;
3554 struct igmp_group
*grp
;
3556 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3557 sizeof(ifaddr_str
));
3559 /* scan igmp groups */
3560 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3562 char group_str
[INET_ADDRSTRLEN
];
3563 char grp_retr_mmss
[10];
3564 struct listnode
*src_node
;
3565 struct igmp_source
*src
;
3566 int grp_retr_sources
= 0;
3568 pim_inet4_dump("<group?>", grp
->group_addr
,
3569 group_str
, sizeof(group_str
));
3570 pim_time_timer_to_mmss(
3571 grp_retr_mmss
, sizeof(grp_retr_mmss
),
3572 grp
->t_group_query_retransmit_timer
);
3575 /* count group sources with retransmission state
3577 for (ALL_LIST_ELEMENTS_RO(
3578 grp
->group_source_list
, src_node
,
3580 if (src
->source_query_retransmit_count
3586 vty_out(vty
, "%-16s %-15s %-15s %-8s %7d %7d\n",
3587 ifp
->name
, ifaddr_str
, group_str
,
3589 grp
->group_specific_query_retransmit_count
,
3592 } /* scan igmp groups */
3593 } /* scan igmp sockets */
3594 } /* scan interfaces */
3597 static void igmp_show_sources(struct pim_instance
*pim
, struct vty
*vty
)
3599 struct interface
*ifp
;
3602 now
= pim_time_monotonic_sec();
3605 "Interface Address Group Source Timer Fwd Uptime \n");
3607 /* scan interfaces */
3608 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3609 struct pim_interface
*pim_ifp
= ifp
->info
;
3610 struct listnode
*sock_node
;
3611 struct igmp_sock
*igmp
;
3616 /* scan igmp sockets */
3617 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3619 char ifaddr_str
[INET_ADDRSTRLEN
];
3620 struct listnode
*grpnode
;
3621 struct igmp_group
*grp
;
3623 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3624 sizeof(ifaddr_str
));
3626 /* scan igmp groups */
3627 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3629 char group_str
[INET_ADDRSTRLEN
];
3630 struct listnode
*srcnode
;
3631 struct igmp_source
*src
;
3633 pim_inet4_dump("<group?>", grp
->group_addr
,
3634 group_str
, sizeof(group_str
));
3636 /* scan group sources */
3637 for (ALL_LIST_ELEMENTS_RO(
3638 grp
->group_source_list
, srcnode
,
3640 char source_str
[INET_ADDRSTRLEN
];
3645 "<source?>", src
->source_addr
,
3646 source_str
, sizeof(source_str
));
3648 pim_time_timer_to_mmss(
3650 src
->t_source_timer
);
3653 uptime
, sizeof(uptime
),
3654 now
- src
->source_creation
);
3657 "%-16s %-15s %-15s %-15s %5s %3s %8s\n",
3658 ifp
->name
, ifaddr_str
,
3659 group_str
, source_str
, mmss
,
3660 IGMP_SOURCE_TEST_FORWARDING(
3666 } /* scan group sources */
3667 } /* scan igmp groups */
3668 } /* scan igmp sockets */
3669 } /* scan interfaces */
3672 static void igmp_show_source_retransmission(struct pim_instance
*pim
,
3675 struct interface
*ifp
;
3678 "Interface Address Group Source Counter\n");
3680 /* scan interfaces */
3681 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3682 struct pim_interface
*pim_ifp
= ifp
->info
;
3683 struct listnode
*sock_node
;
3684 struct igmp_sock
*igmp
;
3689 /* scan igmp sockets */
3690 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3692 char ifaddr_str
[INET_ADDRSTRLEN
];
3693 struct listnode
*grpnode
;
3694 struct igmp_group
*grp
;
3696 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3697 sizeof(ifaddr_str
));
3699 /* scan igmp groups */
3700 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3702 char group_str
[INET_ADDRSTRLEN
];
3703 struct listnode
*srcnode
;
3704 struct igmp_source
*src
;
3706 pim_inet4_dump("<group?>", grp
->group_addr
,
3707 group_str
, sizeof(group_str
));
3709 /* scan group sources */
3710 for (ALL_LIST_ELEMENTS_RO(
3711 grp
->group_source_list
, srcnode
,
3713 char source_str
[INET_ADDRSTRLEN
];
3716 "<source?>", src
->source_addr
,
3717 source_str
, sizeof(source_str
));
3720 "%-16s %-15s %-15s %-15s %7d\n",
3721 ifp
->name
, ifaddr_str
,
3722 group_str
, source_str
,
3723 src
->source_query_retransmit_count
);
3725 } /* scan group sources */
3726 } /* scan igmp groups */
3727 } /* scan igmp sockets */
3728 } /* scan interfaces */
3731 static void pim_show_bsr(struct pim_instance
*pim
,
3736 char last_bsm_seen
[10];
3739 char bsr_str
[PREFIX_STRLEN
];
3740 json_object
*json
= NULL
;
3742 if (pim
->global_scope
.current_bsr
.s_addr
== INADDR_ANY
) {
3743 strlcpy(bsr_str
, "0.0.0.0", sizeof(bsr_str
));
3744 pim_time_uptime(uptime
, sizeof(uptime
),
3745 pim
->global_scope
.current_bsr_first_ts
);
3746 pim_time_uptime(last_bsm_seen
, sizeof(last_bsm_seen
),
3747 pim
->global_scope
.current_bsr_last_ts
);
3751 pim_inet4_dump("<bsr?>", pim
->global_scope
.current_bsr
,
3752 bsr_str
, sizeof(bsr_str
));
3753 now
= pim_time_monotonic_sec();
3754 pim_time_uptime(uptime
, sizeof(uptime
),
3755 (now
- pim
->global_scope
.current_bsr_first_ts
));
3756 pim_time_uptime(last_bsm_seen
, sizeof(last_bsm_seen
),
3757 now
- pim
->global_scope
.current_bsr_last_ts
);
3760 switch (pim
->global_scope
.state
) {
3762 strlcpy(bsr_state
, "NO_INFO", sizeof(bsr_state
));
3765 strlcpy(bsr_state
, "ACCEPT_ANY", sizeof(bsr_state
));
3767 case ACCEPT_PREFERRED
:
3768 strlcpy(bsr_state
, "ACCEPT_PREFERRED", sizeof(bsr_state
));
3771 strlcpy(bsr_state
, "", sizeof(bsr_state
));
3775 json
= json_object_new_object();
3776 json_object_string_add(json
, "bsr", bsr_str
);
3777 json_object_int_add(json
, "priority",
3778 pim
->global_scope
.current_bsr_prio
);
3779 json_object_int_add(json
, "fragment_tag",
3780 pim
->global_scope
.bsm_frag_tag
);
3781 json_object_string_add(json
, "state", bsr_state
);
3782 json_object_string_add(json
, "upTime", uptime
);
3783 json_object_string_add(json
, "last_bsm_seen", last_bsm_seen
);
3787 vty_out(vty
, "PIMv2 Bootstrap information\n");
3788 vty_out(vty
, "Current preferred BSR address: %s\n", bsr_str
);
3790 "Priority Fragment-Tag State UpTime\n");
3791 vty_out(vty
, " %-12d %-12d %-13s %7s\n",
3792 pim
->global_scope
.current_bsr_prio
,
3793 pim
->global_scope
.bsm_frag_tag
,
3796 vty_out(vty
, "Last BSM seen: %s\n", last_bsm_seen
);
3800 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3801 json
, JSON_C_TO_STRING_PRETTY
));
3802 json_object_free(json
);
3806 static void clear_igmp_interfaces(struct pim_instance
*pim
)
3808 struct interface
*ifp
;
3810 FOR_ALL_INTERFACES (pim
->vrf
, ifp
)
3811 pim_if_addr_del_all_igmp(ifp
);
3813 FOR_ALL_INTERFACES (pim
->vrf
, ifp
)
3814 pim_if_addr_add_all(ifp
);
3817 static void clear_pim_interfaces(struct pim_instance
*pim
)
3819 struct interface
*ifp
;
3821 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3823 pim_neighbor_delete_all(ifp
, "interface cleared");
3828 static void clear_interfaces(struct pim_instance
*pim
)
3830 clear_igmp_interfaces(pim
);
3831 clear_pim_interfaces(pim
);
3834 #define PIM_GET_PIM_INTERFACE(pim_ifp, ifp) \
3835 pim_ifp = ifp->info; \
3838 "%% Enable PIM and/or IGMP on this interface first\n"); \
3839 return CMD_WARNING_CONFIG_FAILED; \
3842 DEFUN (clear_ip_interfaces
,
3843 clear_ip_interfaces_cmd
,
3844 "clear ip interfaces [vrf NAME]",
3847 "Reset interfaces\n"
3851 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3856 clear_interfaces(vrf
->info
);
3861 DEFUN (clear_ip_igmp_interfaces
,
3862 clear_ip_igmp_interfaces_cmd
,
3863 "clear ip igmp [vrf NAME] interfaces",
3868 "Reset IGMP interfaces\n")
3871 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3876 clear_igmp_interfaces(vrf
->info
);
3881 DEFUN (clear_ip_pim_statistics
,
3882 clear_ip_pim_statistics_cmd
,
3883 "clear ip pim statistics [vrf NAME]",
3888 "Reset PIM statistics\n")
3891 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3896 clear_pim_statistics(vrf
->info
);
3900 static void clear_mroute(struct pim_instance
*pim
)
3902 struct pim_upstream
*up
;
3903 struct interface
*ifp
;
3905 /* scan interfaces */
3906 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3907 struct pim_interface
*pim_ifp
= ifp
->info
;
3908 struct listnode
*sock_node
;
3909 struct igmp_sock
*igmp
;
3910 struct pim_ifchannel
*ch
;
3915 /* deleting all ifchannels */
3916 while (!RB_EMPTY(pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
)) {
3917 ch
= RB_ROOT(pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
);
3919 pim_ifchannel_delete(ch
);
3922 /* clean up all igmp groups */
3923 /* scan igmp sockets */
3924 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3927 struct igmp_group
*grp
;
3929 if (igmp
->igmp_group_list
) {
3930 while (igmp
->igmp_group_list
->count
) {
3931 grp
= listnode_head(
3932 igmp
->igmp_group_list
);
3933 igmp_group_delete(grp
);
3940 /* clean up all upstreams*/
3941 while ((up
= rb_pim_upstream_first(&pim
->upstream_head
))) {
3942 pim_upstream_del(pim
, up
, __func__
);
3946 DEFUN (clear_ip_mroute
,
3947 clear_ip_mroute_cmd
,
3948 "clear ip mroute [vrf NAME]",
3951 "Reset multicast routes\n"
3955 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3960 clear_mroute(vrf
->info
);
3965 DEFUN (clear_ip_pim_interfaces
,
3966 clear_ip_pim_interfaces_cmd
,
3967 "clear ip pim [vrf NAME] interfaces",
3972 "Reset PIM interfaces\n")
3975 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3980 clear_pim_interfaces(vrf
->info
);
3985 DEFUN (clear_ip_pim_interface_traffic
,
3986 clear_ip_pim_interface_traffic_cmd
,
3987 "clear ip pim [vrf NAME] interface traffic",
3990 "PIM clear commands\n"
3992 "Reset PIM interfaces\n"
3993 "Reset Protocol Packet counters\n")
3996 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3997 struct interface
*ifp
= NULL
;
3998 struct pim_interface
*pim_ifp
= NULL
;
4003 FOR_ALL_INTERFACES (vrf
, ifp
) {
4004 pim_ifp
= ifp
->info
;
4009 pim_ifp
->pim_ifstat_hello_recv
= 0;
4010 pim_ifp
->pim_ifstat_hello_sent
= 0;
4011 pim_ifp
->pim_ifstat_join_recv
= 0;
4012 pim_ifp
->pim_ifstat_join_send
= 0;
4013 pim_ifp
->pim_ifstat_prune_recv
= 0;
4014 pim_ifp
->pim_ifstat_prune_send
= 0;
4015 pim_ifp
->pim_ifstat_reg_recv
= 0;
4016 pim_ifp
->pim_ifstat_reg_send
= 0;
4017 pim_ifp
->pim_ifstat_reg_stop_recv
= 0;
4018 pim_ifp
->pim_ifstat_reg_stop_send
= 0;
4019 pim_ifp
->pim_ifstat_assert_recv
= 0;
4020 pim_ifp
->pim_ifstat_assert_send
= 0;
4021 pim_ifp
->pim_ifstat_bsm_rx
= 0;
4022 pim_ifp
->pim_ifstat_bsm_tx
= 0;
4028 DEFUN (clear_ip_pim_oil
,
4029 clear_ip_pim_oil_cmd
,
4030 "clear ip pim [vrf NAME] oil",
4035 "Rescan PIM OIL (output interface list)\n")
4038 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4043 pim_scan_oil(vrf
->info
);
4048 DEFUN (show_ip_igmp_interface
,
4049 show_ip_igmp_interface_cmd
,
4050 "show ip igmp [vrf NAME] interface [detail|WORD] [json]",
4055 "IGMP interface information\n"
4061 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4062 bool uj
= use_json(argc
, argv
);
4067 if (argv_find(argv
, argc
, "detail", &idx
)
4068 || argv_find(argv
, argc
, "WORD", &idx
))
4069 igmp_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
4071 igmp_show_interfaces(vrf
->info
, vty
, uj
);
4076 DEFUN (show_ip_igmp_interface_vrf_all
,
4077 show_ip_igmp_interface_vrf_all_cmd
,
4078 "show ip igmp vrf all interface [detail|WORD] [json]",
4083 "IGMP interface information\n"
4089 bool uj
= use_json(argc
, argv
);
4095 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4099 vty_out(vty
, " \"%s\": ", vrf
->name
);
4102 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4103 if (argv_find(argv
, argc
, "detail", &idx
)
4104 || argv_find(argv
, argc
, "WORD", &idx
))
4105 igmp_show_interfaces_single(vrf
->info
, vty
,
4106 argv
[idx
]->arg
, uj
);
4108 igmp_show_interfaces(vrf
->info
, vty
, uj
);
4111 vty_out(vty
, "}\n");
4116 DEFUN (show_ip_igmp_join
,
4117 show_ip_igmp_join_cmd
,
4118 "show ip igmp [vrf NAME] join",
4123 "IGMP static join information\n")
4126 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4131 igmp_show_interface_join(vrf
->info
, vty
);
4136 DEFUN (show_ip_igmp_join_vrf_all
,
4137 show_ip_igmp_join_vrf_all_cmd
,
4138 "show ip igmp vrf all join",
4143 "IGMP static join information\n")
4145 bool uj
= use_json(argc
, argv
);
4151 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4155 vty_out(vty
, " \"%s\": ", vrf
->name
);
4158 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4159 igmp_show_interface_join(vrf
->info
, vty
);
4162 vty_out(vty
, "}\n");
4167 DEFUN (show_ip_igmp_groups
,
4168 show_ip_igmp_groups_cmd
,
4169 "show ip igmp [vrf NAME] groups [json]",
4178 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4179 bool uj
= use_json(argc
, argv
);
4184 igmp_show_groups(vrf
->info
, vty
, uj
);
4189 DEFUN (show_ip_igmp_groups_vrf_all
,
4190 show_ip_igmp_groups_vrf_all_cmd
,
4191 "show ip igmp vrf all groups [json]",
4199 bool uj
= use_json(argc
, argv
);
4205 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4209 vty_out(vty
, " \"%s\": ", vrf
->name
);
4212 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4213 igmp_show_groups(vrf
->info
, vty
, uj
);
4216 vty_out(vty
, "}\n");
4221 DEFUN (show_ip_igmp_groups_retransmissions
,
4222 show_ip_igmp_groups_retransmissions_cmd
,
4223 "show ip igmp [vrf NAME] groups retransmissions",
4229 "IGMP group retransmissions\n")
4232 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4237 igmp_show_group_retransmission(vrf
->info
, vty
);
4242 DEFUN (show_ip_igmp_sources
,
4243 show_ip_igmp_sources_cmd
,
4244 "show ip igmp [vrf NAME] sources",
4252 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4257 igmp_show_sources(vrf
->info
, vty
);
4262 DEFUN (show_ip_igmp_sources_retransmissions
,
4263 show_ip_igmp_sources_retransmissions_cmd
,
4264 "show ip igmp [vrf NAME] sources retransmissions",
4270 "IGMP source retransmissions\n")
4273 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4278 igmp_show_source_retransmission(vrf
->info
, vty
);
4283 DEFUN (show_ip_igmp_statistics
,
4284 show_ip_igmp_statistics_cmd
,
4285 "show ip igmp [vrf NAME] statistics [interface WORD] [json]",
4296 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4297 bool uj
= use_json(argc
, argv
);
4302 if (argv_find(argv
, argc
, "WORD", &idx
))
4303 igmp_show_statistics(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
4305 igmp_show_statistics(vrf
->info
, vty
, NULL
, uj
);
4310 DEFUN (show_ip_pim_mlag_summary
,
4311 show_ip_pim_mlag_summary_cmd
,
4312 "show ip pim mlag summary [json]",
4317 "status and stats\n"
4320 bool uj
= use_json(argc
, argv
);
4321 char role_buf
[MLAG_ROLE_STRSIZE
];
4322 char addr_buf
[INET_ADDRSTRLEN
];
4325 json_object
*json
= NULL
;
4326 json_object
*json_stat
= NULL
;
4328 json
= json_object_new_object();
4329 if (router
->mlag_flags
& PIM_MLAGF_LOCAL_CONN_UP
)
4330 json_object_boolean_true_add(json
, "mlagConnUp");
4331 if (router
->mlag_flags
& PIM_MLAGF_PEER_CONN_UP
)
4332 json_object_boolean_true_add(json
, "mlagPeerConnUp");
4333 if (router
->mlag_flags
& PIM_MLAGF_PEER_ZEBRA_UP
)
4334 json_object_boolean_true_add(json
, "mlagPeerZebraUp");
4335 json_object_string_add(json
, "mlagRole",
4336 mlag_role2str(router
->mlag_role
,
4337 role_buf
, sizeof(role_buf
)));
4338 inet_ntop(AF_INET
, &router
->local_vtep_ip
,
4339 addr_buf
, INET_ADDRSTRLEN
);
4340 json_object_string_add(json
, "localVtepIp", addr_buf
);
4341 inet_ntop(AF_INET
, &router
->anycast_vtep_ip
,
4342 addr_buf
, INET_ADDRSTRLEN
);
4343 json_object_string_add(json
, "anycastVtepIp", addr_buf
);
4344 json_object_string_add(json
, "peerlinkRif",
4345 router
->peerlink_rif
);
4347 json_stat
= json_object_new_object();
4348 json_object_int_add(json_stat
, "mlagConnFlaps",
4349 router
->mlag_stats
.mlagd_session_downs
);
4350 json_object_int_add(json_stat
, "mlagPeerConnFlaps",
4351 router
->mlag_stats
.peer_session_downs
);
4352 json_object_int_add(json_stat
, "mlagPeerZebraFlaps",
4353 router
->mlag_stats
.peer_zebra_downs
);
4354 json_object_int_add(json_stat
, "mrouteAddRx",
4355 router
->mlag_stats
.msg
.mroute_add_rx
);
4356 json_object_int_add(json_stat
, "mrouteAddTx",
4357 router
->mlag_stats
.msg
.mroute_add_tx
);
4358 json_object_int_add(json_stat
, "mrouteDelRx",
4359 router
->mlag_stats
.msg
.mroute_del_rx
);
4360 json_object_int_add(json_stat
, "mrouteDelTx",
4361 router
->mlag_stats
.msg
.mroute_del_tx
);
4362 json_object_int_add(json_stat
, "mlagStatusUpdates",
4363 router
->mlag_stats
.msg
.mlag_status_updates
);
4364 json_object_int_add(json_stat
, "peerZebraStatusUpdates",
4365 router
->mlag_stats
.msg
.peer_zebra_status_updates
);
4366 json_object_int_add(json_stat
, "pimStatusUpdates",
4367 router
->mlag_stats
.msg
.pim_status_updates
);
4368 json_object_int_add(json_stat
, "vxlanUpdates",
4369 router
->mlag_stats
.msg
.vxlan_updates
);
4370 json_object_object_add(json
, "connStats", json_stat
);
4372 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4373 json
, JSON_C_TO_STRING_PRETTY
));
4374 json_object_free(json
);
4378 vty_out(vty
, "MLAG daemon connection: %s\n",
4379 (router
->mlag_flags
& PIM_MLAGF_LOCAL_CONN_UP
)
4381 vty_out(vty
, "MLAG peer state: %s\n",
4382 (router
->mlag_flags
& PIM_MLAGF_PEER_CONN_UP
)
4384 vty_out(vty
, "Zebra peer state: %s\n",
4385 (router
->mlag_flags
& PIM_MLAGF_PEER_ZEBRA_UP
)
4387 vty_out(vty
, "MLAG role: %s\n",
4388 mlag_role2str(router
->mlag_role
, role_buf
, sizeof(role_buf
)));
4389 inet_ntop(AF_INET
, &router
->local_vtep_ip
,
4390 addr_buf
, INET_ADDRSTRLEN
);
4391 vty_out(vty
, "Local VTEP IP: %s\n", addr_buf
);
4392 inet_ntop(AF_INET
, &router
->anycast_vtep_ip
,
4393 addr_buf
, INET_ADDRSTRLEN
);
4394 vty_out(vty
, "Anycast VTEP IP: %s\n", addr_buf
);
4395 vty_out(vty
, "Peerlink: %s\n", router
->peerlink_rif
);
4396 vty_out(vty
, "Session flaps: mlagd: %d mlag-peer: %d zebra-peer: %d\n",
4397 router
->mlag_stats
.mlagd_session_downs
,
4398 router
->mlag_stats
.peer_session_downs
,
4399 router
->mlag_stats
.peer_zebra_downs
);
4400 vty_out(vty
, "Message Statistics:\n");
4401 vty_out(vty
, " mroute adds: rx: %d, tx: %d\n",
4402 router
->mlag_stats
.msg
.mroute_add_rx
,
4403 router
->mlag_stats
.msg
.mroute_add_tx
);
4404 vty_out(vty
, " mroute dels: rx: %d, tx: %d\n",
4405 router
->mlag_stats
.msg
.mroute_del_rx
,
4406 router
->mlag_stats
.msg
.mroute_del_tx
);
4407 vty_out(vty
, " peer zebra status updates: %d\n",
4408 router
->mlag_stats
.msg
.peer_zebra_status_updates
);
4409 vty_out(vty
, " PIM status updates: %d\n",
4410 router
->mlag_stats
.msg
.pim_status_updates
);
4411 vty_out(vty
, " VxLAN updates: %d\n",
4412 router
->mlag_stats
.msg
.vxlan_updates
);
4417 DEFUN (show_ip_pim_assert
,
4418 show_ip_pim_assert_cmd
,
4419 "show ip pim [vrf NAME] assert",
4424 "PIM interface assert\n")
4427 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4432 pim_show_assert(vrf
->info
, vty
);
4437 DEFUN (show_ip_pim_assert_internal
,
4438 show_ip_pim_assert_internal_cmd
,
4439 "show ip pim [vrf NAME] assert-internal",
4444 "PIM interface internal assert state\n")
4447 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4452 pim_show_assert_internal(vrf
->info
, vty
);
4457 DEFUN (show_ip_pim_assert_metric
,
4458 show_ip_pim_assert_metric_cmd
,
4459 "show ip pim [vrf NAME] assert-metric",
4464 "PIM interface assert metric\n")
4467 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4472 pim_show_assert_metric(vrf
->info
, vty
);
4477 DEFUN (show_ip_pim_assert_winner_metric
,
4478 show_ip_pim_assert_winner_metric_cmd
,
4479 "show ip pim [vrf NAME] assert-winner-metric",
4484 "PIM interface assert winner metric\n")
4487 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4492 pim_show_assert_winner_metric(vrf
->info
, vty
);
4497 DEFUN (show_ip_pim_interface
,
4498 show_ip_pim_interface_cmd
,
4499 "show ip pim [mlag] [vrf NAME] interface [detail|WORD] [json]",
4505 "PIM interface information\n"
4511 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4512 bool uj
= use_json(argc
, argv
);
4518 if (argv_find(argv
, argc
, "mlag", &idx
))
4521 if (argv_find(argv
, argc
, "WORD", &idx
)
4522 || argv_find(argv
, argc
, "detail", &idx
))
4523 pim_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, mlag
,
4526 pim_show_interfaces(vrf
->info
, vty
, mlag
, uj
);
4531 DEFUN (show_ip_pim_interface_vrf_all
,
4532 show_ip_pim_interface_vrf_all_cmd
,
4533 "show ip pim [mlag] vrf all interface [detail|WORD] [json]",
4539 "PIM interface information\n"
4545 bool uj
= use_json(argc
, argv
);
4550 if (argv_find(argv
, argc
, "mlag", &idx
))
4556 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4560 vty_out(vty
, " \"%s\": ", vrf
->name
);
4563 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4564 if (argv_find(argv
, argc
, "WORD", &idx
)
4565 || argv_find(argv
, argc
, "detail", &idx
))
4566 pim_show_interfaces_single(vrf
->info
, vty
,
4567 argv
[idx
]->arg
, mlag
, uj
);
4569 pim_show_interfaces(vrf
->info
, vty
, mlag
, uj
);
4572 vty_out(vty
, "}\n");
4577 DEFPY (show_ip_pim_join
,
4578 show_ip_pim_join_cmd
,
4579 "show ip pim [vrf NAME] join [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
4584 "PIM interface join information\n"
4585 "The Source or Group\n"
4589 struct prefix_sg sg
= {0};
4592 struct pim_instance
*pim
;
4594 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
4597 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
4600 pim
= pim_get_pim_instance(v
->vrf_id
);
4603 vty_out(vty
, "%% Unable to find pim instance\n");
4607 if (s_or_g
.s_addr
!= 0) {
4608 if (g
.s_addr
!= 0) {
4615 pim_show_join(pim
, vty
, &sg
, uj
);
4620 DEFUN (show_ip_pim_join_vrf_all
,
4621 show_ip_pim_join_vrf_all_cmd
,
4622 "show ip pim vrf all join [json]",
4627 "PIM interface join information\n"
4630 struct prefix_sg sg
= {0};
4631 bool uj
= use_json(argc
, argv
);
4637 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4641 vty_out(vty
, " \"%s\": ", vrf
->name
);
4644 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4645 pim_show_join(vrf
->info
, vty
, &sg
, uj
);
4648 vty_out(vty
, "}\n");
4653 static void pim_show_jp_agg_helper(struct vty
*vty
,
4654 struct interface
*ifp
,
4655 struct pim_neighbor
*neigh
,
4656 struct pim_upstream
*up
,
4659 char src_str
[INET_ADDRSTRLEN
];
4660 char grp_str
[INET_ADDRSTRLEN
];
4661 char rpf_str
[INET_ADDRSTRLEN
];
4663 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
4664 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
4665 /* pius->address.s_addr */
4666 pim_inet4_dump("<rpf?>", neigh
->source_addr
, rpf_str
, sizeof(rpf_str
));
4668 vty_out(vty
, "%-16s %-15s %-15s %-15s %5s\n",
4669 ifp
->name
, rpf_str
, src_str
,
4670 grp_str
, is_join
?"J":"P");
4673 static void pim_show_jp_agg_list(struct pim_instance
*pim
, struct vty
*vty
)
4675 struct interface
*ifp
;
4676 struct pim_interface
*pim_ifp
;
4677 struct listnode
*n_node
;
4678 struct pim_neighbor
*neigh
;
4679 struct listnode
*jag_node
;
4680 struct pim_jp_agg_group
*jag
;
4681 struct listnode
*js_node
;
4682 struct pim_jp_sources
*js
;
4685 "Interface RPF Nbr Source Group State\n");
4687 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
4688 pim_ifp
= ifp
->info
;
4692 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
,
4694 for (ALL_LIST_ELEMENTS_RO(neigh
->upstream_jp_agg
,
4696 for (ALL_LIST_ELEMENTS_RO(jag
->sources
,
4698 pim_show_jp_agg_helper(vty
,
4707 DEFPY (show_ip_pim_jp_agg
,
4708 show_ip_pim_jp_agg_cmd
,
4709 "show ip pim [vrf NAME] jp-agg",
4714 "join prune aggregation list\n")
4717 struct pim_instance
*pim
;
4719 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
4722 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
4725 pim
= pim_get_pim_instance(v
->vrf_id
);
4728 vty_out(vty
, "%% Unable to find pim instance\n");
4732 pim_show_jp_agg_list(pim
, vty
);
4737 DEFUN (show_ip_pim_local_membership
,
4738 show_ip_pim_local_membership_cmd
,
4739 "show ip pim [vrf NAME] local-membership [json]",
4744 "PIM interface local-membership\n"
4748 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4749 bool uj
= use_json(argc
, argv
);
4754 pim_show_membership(vrf
->info
, vty
, uj
);
4759 static void pim_show_mlag_up_entry_detail(struct vrf
*vrf
,
4760 struct vty
*vty
, struct pim_upstream
*up
,
4761 char *src_str
, char *grp_str
, json_object
*json
)
4764 json_object
*json_row
= NULL
;
4765 json_object
*own_list
= NULL
;
4766 json_object
*json_group
= NULL
;
4769 json_object_object_get_ex(json
, grp_str
, &json_group
);
4771 json_group
= json_object_new_object();
4772 json_object_object_add(json
, grp_str
,
4776 json_row
= json_object_new_object();
4777 json_object_string_add(json_row
, "source", src_str
);
4778 json_object_string_add(json_row
, "group", grp_str
);
4780 own_list
= json_object_new_array();
4781 if (pim_up_mlag_is_local(up
))
4782 json_object_array_add(own_list
,
4783 json_object_new_string("local"));
4784 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
))
4785 json_object_array_add(own_list
,
4786 json_object_new_string("peer"));
4787 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE
))
4788 json_object_array_add(
4789 own_list
, json_object_new_string("Interface"));
4790 json_object_object_add(json_row
, "owners", own_list
);
4792 json_object_int_add(json_row
, "localCost",
4793 pim_up_mlag_local_cost(up
));
4794 json_object_int_add(json_row
, "peerCost",
4795 pim_up_mlag_peer_cost(up
));
4796 if (PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up
->flags
))
4797 json_object_boolean_false_add(json_row
, "df");
4799 json_object_boolean_true_add(json_row
, "df");
4800 json_object_object_add(json_group
, src_str
, json_row
);
4805 if (pim_up_mlag_is_local(up
))
4806 strlcat(own_str
, "L", sizeof(own_str
));
4807 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
))
4808 strlcat(own_str
, "P", sizeof(own_str
));
4809 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE
))
4810 strlcat(own_str
, "I", sizeof(own_str
));
4811 /* XXX - fixup, print paragraph output */
4813 "%-15s %-15s %-6s %-11u %-10d %2s\n",
4814 src_str
, grp_str
, own_str
,
4815 pim_up_mlag_local_cost(up
),
4816 pim_up_mlag_peer_cost(up
),
4817 PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up
->flags
)
4822 static void pim_show_mlag_up_detail(struct vrf
*vrf
,
4823 struct vty
*vty
, const char *src_or_group
,
4824 const char *group
, bool uj
)
4826 char src_str
[INET_ADDRSTRLEN
];
4827 char grp_str
[INET_ADDRSTRLEN
];
4828 struct pim_upstream
*up
;
4829 struct pim_instance
*pim
= vrf
->info
;
4830 json_object
*json
= NULL
;
4833 json
= json_object_new_object();
4836 "Source Group Owner Local-cost Peer-cost DF\n");
4838 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
4839 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
)
4840 && !(up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE
)
4841 && !pim_up_mlag_is_local(up
))
4844 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
4845 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
4846 /* XXX: strcmps are clearly inefficient. we should do uint comps
4850 if (strcmp(src_str
, src_or_group
) ||
4851 strcmp(grp_str
, group
))
4854 if (strcmp(src_str
, src_or_group
) &&
4855 strcmp(grp_str
, src_or_group
))
4858 pim_show_mlag_up_entry_detail(vrf
, vty
, up
,
4859 src_str
, grp_str
, json
);
4863 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4864 json
, JSON_C_TO_STRING_PRETTY
));
4865 json_object_free(json
);
4869 static void pim_show_mlag_up_vrf(struct vrf
*vrf
, struct vty
*vty
, bool uj
)
4871 json_object
*json
= NULL
;
4872 json_object
*json_row
;
4873 struct pim_upstream
*up
;
4874 char src_str
[INET_ADDRSTRLEN
];
4875 char grp_str
[INET_ADDRSTRLEN
];
4876 struct pim_instance
*pim
= vrf
->info
;
4877 json_object
*json_group
= NULL
;
4880 json
= json_object_new_object();
4883 "Source Group Owner Local-cost Peer-cost DF\n");
4886 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
4887 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
)
4888 && !(up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE
)
4889 && !pim_up_mlag_is_local(up
))
4891 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
4892 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
4894 json_object
*own_list
= NULL
;
4896 json_object_object_get_ex(json
, grp_str
, &json_group
);
4898 json_group
= json_object_new_object();
4899 json_object_object_add(json
, grp_str
,
4903 json_row
= json_object_new_object();
4904 json_object_string_add(json_row
, "vrf", vrf
->name
);
4905 json_object_string_add(json_row
, "source", src_str
);
4906 json_object_string_add(json_row
, "group", grp_str
);
4908 own_list
= json_object_new_array();
4909 if (pim_up_mlag_is_local(up
)) {
4911 json_object_array_add(own_list
,
4912 json_object_new_string("local"));
4914 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
)) {
4915 json_object_array_add(own_list
,
4916 json_object_new_string("peer"));
4918 json_object_object_add(json_row
, "owners", own_list
);
4920 json_object_int_add(json_row
, "localCost",
4921 pim_up_mlag_local_cost(up
));
4922 json_object_int_add(json_row
, "peerCost",
4923 pim_up_mlag_peer_cost(up
));
4924 if (PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up
->flags
))
4925 json_object_boolean_false_add(json_row
, "df");
4927 json_object_boolean_true_add(json_row
, "df");
4928 json_object_object_add(json_group
, src_str
, json_row
);
4933 if (pim_up_mlag_is_local(up
))
4934 strlcat(own_str
, "L", sizeof(own_str
));
4935 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
))
4936 strlcat(own_str
, "P", sizeof(own_str
));
4937 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE
))
4938 strlcat(own_str
, "I", sizeof(own_str
));
4940 "%-15s %-15s %-6s %-11u %-10u %2s\n",
4941 src_str
, grp_str
, own_str
,
4942 pim_up_mlag_local_cost(up
),
4943 pim_up_mlag_peer_cost(up
),
4944 PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up
->flags
)
4949 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4950 json
, JSON_C_TO_STRING_PRETTY
));
4951 json_object_free(json
);
4955 static void pim_show_mlag_help_string(struct vty
*vty
, bool uj
)
4958 vty_out(vty
, "Owner codes:\n");
4960 "L: EVPN-MLAG Entry, I:PIM-MLAG Entry, "
4966 DEFUN(show_ip_pim_mlag_up
, show_ip_pim_mlag_up_cmd
,
4967 "show ip pim [vrf NAME] mlag upstream [A.B.C.D [A.B.C.D]] [json]",
4974 "Unicast or Multicast address\n"
4975 "Multicast address\n" JSON_STR
)
4977 const char *src_or_group
= NULL
;
4978 const char *group
= NULL
;
4980 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4981 bool uj
= use_json(argc
, argv
);
4983 if (!vrf
|| !vrf
->info
) {
4984 vty_out(vty
, "%s: VRF or Info missing\n", __func__
);
4991 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
4992 src_or_group
= argv
[idx
]->arg
;
4994 group
= argv
[idx
+ 1]->arg
;
4997 pim_show_mlag_help_string(vty
, uj
);
5000 pim_show_mlag_up_detail(vrf
, vty
, src_or_group
, group
, uj
);
5002 pim_show_mlag_up_vrf(vrf
, vty
, uj
);
5008 DEFUN(show_ip_pim_mlag_up_vrf_all
, show_ip_pim_mlag_up_vrf_all_cmd
,
5009 "show ip pim vrf all mlag upstream [json]",
5010 SHOW_STR IP_STR PIM_STR VRF_CMD_HELP_STR
5012 "upstream\n" JSON_STR
)
5015 bool uj
= use_json(argc
, argv
);
5017 pim_show_mlag_help_string(vty
, uj
);
5018 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5019 pim_show_mlag_up_vrf(vrf
, vty
, uj
);
5025 DEFUN (show_ip_pim_neighbor
,
5026 show_ip_pim_neighbor_cmd
,
5027 "show ip pim [vrf NAME] neighbor [detail|WORD] [json]",
5032 "PIM neighbor information\n"
5034 "Name of interface or neighbor\n"
5038 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5039 bool uj
= use_json(argc
, argv
);
5044 if (argv_find(argv
, argc
, "detail", &idx
)
5045 || argv_find(argv
, argc
, "WORD", &idx
))
5046 pim_show_neighbors_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
5048 pim_show_neighbors(vrf
->info
, vty
, uj
);
5053 DEFUN (show_ip_pim_neighbor_vrf_all
,
5054 show_ip_pim_neighbor_vrf_all_cmd
,
5055 "show ip pim vrf all neighbor [detail|WORD] [json]",
5060 "PIM neighbor information\n"
5062 "Name of interface or neighbor\n"
5066 bool uj
= use_json(argc
, argv
);
5072 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5076 vty_out(vty
, " \"%s\": ", vrf
->name
);
5079 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5080 if (argv_find(argv
, argc
, "detail", &idx
)
5081 || argv_find(argv
, argc
, "WORD", &idx
))
5082 pim_show_neighbors_single(vrf
->info
, vty
,
5083 argv
[idx
]->arg
, uj
);
5085 pim_show_neighbors(vrf
->info
, vty
, uj
);
5088 vty_out(vty
, "}\n");
5093 DEFUN (show_ip_pim_secondary
,
5094 show_ip_pim_secondary_cmd
,
5095 "show ip pim [vrf NAME] secondary",
5100 "PIM neighbor addresses\n")
5103 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5108 pim_show_neighbors_secondary(vrf
->info
, vty
);
5113 DEFUN (show_ip_pim_state
,
5114 show_ip_pim_state_cmd
,
5115 "show ip pim [vrf NAME] state [A.B.C.D [A.B.C.D]] [json]",
5120 "PIM state information\n"
5121 "Unicast or Multicast address\n"
5122 "Multicast address\n"
5125 const char *src_or_group
= NULL
;
5126 const char *group
= NULL
;
5128 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5129 bool uj
= use_json(argc
, argv
);
5137 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
5138 src_or_group
= argv
[idx
]->arg
;
5140 group
= argv
[idx
+ 1]->arg
;
5143 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
5148 DEFUN (show_ip_pim_state_vrf_all
,
5149 show_ip_pim_state_vrf_all_cmd
,
5150 "show ip pim vrf all state [A.B.C.D [A.B.C.D]] [json]",
5155 "PIM state information\n"
5156 "Unicast or Multicast address\n"
5157 "Multicast address\n"
5160 const char *src_or_group
= NULL
;
5161 const char *group
= NULL
;
5163 bool uj
= use_json(argc
, argv
);
5172 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
5173 src_or_group
= argv
[idx
]->arg
;
5175 group
= argv
[idx
+ 1]->arg
;
5178 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5182 vty_out(vty
, " \"%s\": ", vrf
->name
);
5185 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5186 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
5189 vty_out(vty
, "}\n");
5194 DEFPY (show_ip_pim_upstream
,
5195 show_ip_pim_upstream_cmd
,
5196 "show ip pim [vrf NAME] upstream [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
5201 "PIM upstream information\n"
5202 "The Source or Group\n"
5206 struct prefix_sg sg
= {0};
5209 struct pim_instance
*pim
;
5211 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
5214 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
5217 pim
= pim_get_pim_instance(v
->vrf_id
);
5220 vty_out(vty
, "%% Unable to find pim instance\n");
5224 if (s_or_g
.s_addr
!= 0) {
5225 if (g
.s_addr
!= 0) {
5231 pim_show_upstream(pim
, vty
, &sg
, uj
);
5236 DEFUN (show_ip_pim_upstream_vrf_all
,
5237 show_ip_pim_upstream_vrf_all_cmd
,
5238 "show ip pim vrf all upstream [json]",
5243 "PIM upstream information\n"
5246 struct prefix_sg sg
= {0};
5247 bool uj
= use_json(argc
, argv
);
5253 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5257 vty_out(vty
, " \"%s\": ", vrf
->name
);
5260 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5261 pim_show_upstream(vrf
->info
, vty
, &sg
, uj
);
5267 DEFUN (show_ip_pim_channel
,
5268 show_ip_pim_channel_cmd
,
5269 "show ip pim [vrf NAME] channel [json]",
5274 "PIM downstream channel info\n"
5278 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5279 bool uj
= use_json(argc
, argv
);
5284 pim_show_channel(vrf
->info
, vty
, uj
);
5289 DEFUN (show_ip_pim_upstream_join_desired
,
5290 show_ip_pim_upstream_join_desired_cmd
,
5291 "show ip pim [vrf NAME] upstream-join-desired [json]",
5296 "PIM upstream join-desired\n"
5300 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5301 bool uj
= use_json(argc
, argv
);
5306 pim_show_join_desired(vrf
->info
, vty
, uj
);
5311 DEFUN (show_ip_pim_upstream_rpf
,
5312 show_ip_pim_upstream_rpf_cmd
,
5313 "show ip pim [vrf NAME] upstream-rpf [json]",
5318 "PIM upstream source rpf\n"
5322 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5323 bool uj
= use_json(argc
, argv
);
5328 pim_show_upstream_rpf(vrf
->info
, vty
, uj
);
5333 DEFUN (show_ip_pim_rp
,
5335 "show ip pim [vrf NAME] rp-info [json]",
5340 "PIM RP information\n"
5344 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5345 bool uj
= use_json(argc
, argv
);
5350 pim_rp_show_information(vrf
->info
, vty
, uj
);
5355 DEFUN (show_ip_pim_rp_vrf_all
,
5356 show_ip_pim_rp_vrf_all_cmd
,
5357 "show ip pim vrf all rp-info [json]",
5362 "PIM RP information\n"
5365 bool uj
= use_json(argc
, argv
);
5371 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5375 vty_out(vty
, " \"%s\": ", vrf
->name
);
5378 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5379 pim_rp_show_information(vrf
->info
, vty
, uj
);
5382 vty_out(vty
, "}\n");
5387 DEFUN (show_ip_pim_rpf
,
5388 show_ip_pim_rpf_cmd
,
5389 "show ip pim [vrf NAME] rpf [json]",
5394 "PIM cached source rpf information\n"
5398 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5399 bool uj
= use_json(argc
, argv
);
5404 pim_show_rpf(vrf
->info
, vty
, uj
);
5409 DEFUN (show_ip_pim_rpf_vrf_all
,
5410 show_ip_pim_rpf_vrf_all_cmd
,
5411 "show ip pim vrf all rpf [json]",
5416 "PIM cached source rpf information\n"
5419 bool uj
= use_json(argc
, argv
);
5425 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5429 vty_out(vty
, " \"%s\": ", vrf
->name
);
5432 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5433 pim_show_rpf(vrf
->info
, vty
, uj
);
5436 vty_out(vty
, "}\n");
5441 DEFUN (show_ip_pim_nexthop
,
5442 show_ip_pim_nexthop_cmd
,
5443 "show ip pim [vrf NAME] nexthop",
5448 "PIM cached nexthop rpf information\n")
5451 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5456 pim_show_nexthop(vrf
->info
, vty
);
5461 DEFUN (show_ip_pim_nexthop_lookup
,
5462 show_ip_pim_nexthop_lookup_cmd
,
5463 "show ip pim [vrf NAME] nexthop-lookup A.B.C.D A.B.C.D",
5468 "PIM cached nexthop rpf lookup\n"
5469 "Source/RP address\n"
5470 "Multicast Group address\n")
5472 struct prefix nht_p
;
5474 struct in_addr src_addr
, grp_addr
;
5475 struct in_addr vif_source
;
5476 const char *addr_str
, *addr_str1
;
5478 struct pim_nexthop nexthop
;
5479 char nexthop_addr_str
[PREFIX_STRLEN
];
5480 char grp_str
[PREFIX_STRLEN
];
5482 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5487 argv_find(argv
, argc
, "A.B.C.D", &idx
);
5488 addr_str
= argv
[idx
]->arg
;
5489 result
= inet_pton(AF_INET
, addr_str
, &src_addr
);
5491 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
5492 errno
, safe_strerror(errno
));
5496 if (pim_is_group_224_4(src_addr
)) {
5498 "Invalid argument. Expected Valid Source Address.\n");
5502 addr_str1
= argv
[idx
+ 1]->arg
;
5503 result
= inet_pton(AF_INET
, addr_str1
, &grp_addr
);
5505 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
5506 errno
, safe_strerror(errno
));
5510 if (!pim_is_group_224_4(grp_addr
)) {
5512 "Invalid argument. Expected Valid Multicast Group Address.\n");
5516 if (!pim_rp_set_upstream_addr(vrf
->info
, &vif_source
, src_addr
,
5520 nht_p
.family
= AF_INET
;
5521 nht_p
.prefixlen
= IPV4_MAX_BITLEN
;
5522 nht_p
.u
.prefix4
= vif_source
;
5523 grp
.family
= AF_INET
;
5524 grp
.prefixlen
= IPV4_MAX_BITLEN
;
5525 grp
.u
.prefix4
= grp_addr
;
5526 memset(&nexthop
, 0, sizeof(nexthop
));
5528 result
= pim_ecmp_nexthop_lookup(vrf
->info
, &nexthop
, &nht_p
, &grp
, 0);
5532 "Nexthop Lookup failed, no usable routes returned.\n");
5536 pim_addr_dump("<grp?>", &grp
, grp_str
, sizeof(grp_str
));
5537 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
5538 nexthop_addr_str
, sizeof(nexthop_addr_str
));
5539 vty_out(vty
, "Group %s --- Nexthop %s Interface %s \n", grp_str
,
5540 nexthop_addr_str
, nexthop
.interface
->name
);
5545 DEFUN (show_ip_pim_interface_traffic
,
5546 show_ip_pim_interface_traffic_cmd
,
5547 "show ip pim [vrf NAME] interface traffic [WORD] [json]",
5552 "PIM interface information\n"
5553 "Protocol Packet counters\n"
5558 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5559 bool uj
= use_json(argc
, argv
);
5564 if (argv_find(argv
, argc
, "WORD", &idx
))
5565 pim_show_interface_traffic_single(vrf
->info
, vty
,
5566 argv
[idx
]->arg
, uj
);
5568 pim_show_interface_traffic(vrf
->info
, vty
, uj
);
5573 DEFUN (show_ip_pim_bsm_db
,
5574 show_ip_pim_bsm_db_cmd
,
5575 "show ip pim bsm-database [vrf NAME] [json]",
5579 "PIM cached bsm packets information\n"
5584 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5585 bool uj
= use_json(argc
, argv
);
5590 pim_show_bsm_db(vrf
->info
, vty
, uj
);
5594 DEFUN (show_ip_pim_bsrp
,
5595 show_ip_pim_bsrp_cmd
,
5596 "show ip pim bsrp-info [vrf NAME] [json]",
5600 "PIM cached group-rp mappings information\n"
5605 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5606 bool uj
= use_json(argc
, argv
);
5611 pim_show_group_rp_mappings_info(vrf
->info
, vty
, uj
);
5616 DEFUN (show_ip_pim_statistics
,
5617 show_ip_pim_statistics_cmd
,
5618 "show ip pim [vrf NAME] statistics [interface WORD] [json]",
5629 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5630 bool uj
= use_json(argc
, argv
);
5635 if (argv_find(argv
, argc
, "WORD", &idx
))
5636 pim_show_statistics(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
5638 pim_show_statistics(vrf
->info
, vty
, NULL
, uj
);
5643 static void show_multicast_interfaces(struct pim_instance
*pim
, struct vty
*vty
)
5645 struct interface
*ifp
;
5650 "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut\n");
5652 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
5653 struct pim_interface
*pim_ifp
;
5654 struct in_addr ifaddr
;
5655 struct sioc_vif_req vreq
;
5657 pim_ifp
= ifp
->info
;
5662 memset(&vreq
, 0, sizeof(vreq
));
5663 vreq
.vifi
= pim_ifp
->mroute_vif_index
;
5665 if (ioctl(pim
->mroute_socket
, SIOCGETVIFCNT
, &vreq
)) {
5667 "ioctl(SIOCGETVIFCNT=%lu) failure for interface %s vif_index=%d: errno=%d: %s",
5668 (unsigned long)SIOCGETVIFCNT
, ifp
->name
,
5669 pim_ifp
->mroute_vif_index
, errno
,
5670 safe_strerror(errno
));
5673 ifaddr
= pim_ifp
->primary_address
;
5675 vty_out(vty
, "%-16s %-15s %3d %3d %7lu %7lu %10lu %10lu\n",
5676 ifp
->name
, inet_ntoa(ifaddr
), ifp
->ifindex
,
5677 pim_ifp
->mroute_vif_index
, (unsigned long)vreq
.icount
,
5678 (unsigned long)vreq
.ocount
, (unsigned long)vreq
.ibytes
,
5679 (unsigned long)vreq
.obytes
);
5683 static void pim_cmd_show_ip_multicast_helper(struct pim_instance
*pim
,
5686 struct vrf
*vrf
= pim
->vrf
;
5687 time_t now
= pim_time_monotonic_sec();
5693 vty_out(vty
, "Router MLAG Role: %s\n",
5694 mlag_role2str(router
->mlag_role
, mlag_role
, sizeof(mlag_role
)));
5695 vty_out(vty
, "Mroute socket descriptor:");
5697 vty_out(vty
, " %d(%s)\n", pim
->mroute_socket
, vrf
->name
);
5699 pim_time_uptime(uptime
, sizeof(uptime
),
5700 now
- pim
->mroute_socket_creation
);
5701 vty_out(vty
, "Mroute socket uptime: %s\n", uptime
);
5705 pim_zebra_zclient_update(vty
);
5706 pim_zlookup_show_ip_multicast(vty
);
5709 vty_out(vty
, "Maximum highest VifIndex: %d\n", PIM_MAX_USABLE_VIFS
);
5712 vty_out(vty
, "Upstream Join Timer: %d secs\n", router
->t_periodic
);
5713 vty_out(vty
, "Join/Prune Holdtime: %d secs\n", PIM_JP_HOLDTIME
);
5714 vty_out(vty
, "PIM ECMP: %s\n", pim
->ecmp_enable
? "Enable" : "Disable");
5715 vty_out(vty
, "PIM ECMP Rebalance: %s\n",
5716 pim
->ecmp_rebalance_enable
? "Enable" : "Disable");
5720 show_rpf_refresh_stats(vty
, pim
, now
, NULL
);
5724 show_scan_oil_stats(pim
, vty
, now
);
5726 show_multicast_interfaces(pim
, vty
);
5729 DEFUN (show_ip_multicast
,
5730 show_ip_multicast_cmd
,
5731 "show ip multicast [vrf NAME]",
5735 "Multicast global information\n")
5738 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5743 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
5748 DEFUN (show_ip_multicast_vrf_all
,
5749 show_ip_multicast_vrf_all_cmd
,
5750 "show ip multicast vrf all",
5754 "Multicast global information\n")
5756 bool uj
= use_json(argc
, argv
);
5762 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5766 vty_out(vty
, " \"%s\": ", vrf
->name
);
5769 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5770 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
5773 vty_out(vty
, "}\n");
5778 static void show_mroute(struct pim_instance
*pim
, struct vty
*vty
,
5779 struct prefix_sg
*sg
, bool fill
, bool uj
)
5781 struct listnode
*node
;
5782 struct channel_oil
*c_oil
;
5783 struct static_route
*s_route
;
5785 json_object
*json
= NULL
;
5786 json_object
*json_group
= NULL
;
5787 json_object
*json_source
= NULL
;
5788 json_object
*json_oil
= NULL
;
5789 json_object
*json_ifp_out
= NULL
;
5792 char grp_str
[INET_ADDRSTRLEN
];
5793 char src_str
[INET_ADDRSTRLEN
];
5794 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
5795 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
5797 struct interface
*ifp_in
;
5799 char state_str
[PIM_REG_STATE_STR_LEN
];
5800 char mroute_uptime
[10];
5803 json
= json_object_new_object();
5805 vty_out(vty
, "IP Multicast Routing Table\n");
5806 vty_out(vty
, "Flags: S- Sparse, C - Connected, P - Pruned\n");
5808 " R - RP-bit set, F - Register flag, T - SPT-bit set\n");
5810 "\nSource Group Flags Proto Input Output TTL Uptime\n");
5813 now
= pim_time_monotonic_sec();
5815 /* print list of PIM and IGMP routes */
5816 frr_each (rb_pim_oil
, &pim
->channel_oil_head
, c_oil
) {
5819 if (!c_oil
->installed
&& !uj
)
5822 if (sg
->grp
.s_addr
!= 0 &&
5823 sg
->grp
.s_addr
!= c_oil
->oil
.mfcc_mcastgrp
.s_addr
)
5825 if (sg
->src
.s_addr
!= 0 &&
5826 sg
->src
.s_addr
!= c_oil
->oil
.mfcc_origin
.s_addr
)
5829 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
5831 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
5834 strlcpy(state_str
, "S", sizeof(state_str
));
5835 /* When a non DR receives a igmp join, it creates a (*,G)
5836 * channel_oil without any upstream creation */
5838 if (PIM_UPSTREAM_FLAG_TEST_SRC_IGMP(c_oil
->up
->flags
))
5839 strlcat(state_str
, "C", sizeof(state_str
));
5840 if (pim_upstream_is_sg_rpt(c_oil
->up
))
5841 strlcat(state_str
, "R", sizeof(state_str
));
5842 if (PIM_UPSTREAM_FLAG_TEST_FHR(c_oil
->up
->flags
))
5843 strlcat(state_str
, "F", sizeof(state_str
));
5844 if (c_oil
->up
->sptbit
== PIM_UPSTREAM_SPTBIT_TRUE
)
5845 strlcat(state_str
, "T", sizeof(state_str
));
5847 if (pim_channel_oil_empty(c_oil
))
5848 strlcat(state_str
, "P", sizeof(state_str
));
5850 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
5853 strlcpy(in_ifname
, ifp_in
->name
, sizeof(in_ifname
));
5855 strlcpy(in_ifname
, "<iif?>", sizeof(in_ifname
));
5858 pim_time_uptime(mroute_uptime
, sizeof(mroute_uptime
),
5859 now
- c_oil
->mroute_creation
);
5863 /* Find the group, create it if it doesn't exist */
5864 json_object_object_get_ex(json
, grp_str
, &json_group
);
5867 json_group
= json_object_new_object();
5868 json_object_object_add(json
, grp_str
,
5872 /* Find the source nested under the group, create it if
5875 json_object_object_get_ex(json_group
, src_str
,
5879 json_source
= json_object_new_object();
5880 json_object_object_add(json_group
, src_str
,
5884 /* Find the inbound interface nested under the source,
5885 * create it if it doesn't exist */
5886 json_object_int_add(json_source
, "installed",
5888 json_object_int_add(json_source
, "refCount",
5889 c_oil
->oil_ref_count
);
5890 json_object_int_add(json_source
, "oilSize",
5892 json_object_int_add(json_source
, "OilInheritedRescan",
5893 c_oil
->oil_inherited_rescan
);
5894 json_object_string_add(json_source
, "iif", in_ifname
);
5895 json_object_string_add(json_source
, "upTime",
5900 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
5902 struct interface
*ifp_out
;
5905 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
5909 /* do not display muted OIFs */
5910 if (c_oil
->oif_flags
[oif_vif_index
]
5911 & PIM_OIF_FLAG_MUTE
)
5914 if (c_oil
->oil
.mfcc_parent
== oif_vif_index
&&
5915 !pim_mroute_allow_iif_in_oil(c_oil
,
5919 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
5923 strlcpy(out_ifname
, ifp_out
->name
, sizeof(out_ifname
));
5925 strlcpy(out_ifname
, "<oif?>", sizeof(out_ifname
));
5928 json_ifp_out
= json_object_new_object();
5929 json_object_string_add(json_ifp_out
, "source",
5931 json_object_string_add(json_ifp_out
, "group",
5934 if (c_oil
->oif_flags
[oif_vif_index
]
5935 & PIM_OIF_FLAG_PROTO_PIM
)
5936 json_object_boolean_true_add(
5937 json_ifp_out
, "protocolPim");
5939 if (c_oil
->oif_flags
[oif_vif_index
]
5940 & PIM_OIF_FLAG_PROTO_IGMP
)
5941 json_object_boolean_true_add(
5942 json_ifp_out
, "protocolIgmp");
5944 if (c_oil
->oif_flags
[oif_vif_index
]
5945 & PIM_OIF_FLAG_PROTO_VXLAN
)
5946 json_object_boolean_true_add(
5947 json_ifp_out
, "protocolVxlan");
5949 if (c_oil
->oif_flags
[oif_vif_index
]
5950 & PIM_OIF_FLAG_PROTO_STAR
)
5951 json_object_boolean_true_add(
5953 "protocolInherited");
5955 json_object_string_add(json_ifp_out
,
5958 json_object_int_add(json_ifp_out
, "iVifI",
5959 c_oil
->oil
.mfcc_parent
);
5960 json_object_string_add(json_ifp_out
,
5961 "outboundInterface",
5963 json_object_int_add(json_ifp_out
, "oVifI",
5965 json_object_int_add(json_ifp_out
, "ttl", ttl
);
5966 json_object_string_add(json_ifp_out
, "upTime",
5969 json_oil
= json_object_new_object();
5970 json_object_object_add(json_source
,
5973 json_object_object_add(json_oil
, out_ifname
,
5976 if (c_oil
->oif_flags
[oif_vif_index
]
5977 & PIM_OIF_FLAG_PROTO_PIM
) {
5978 strlcpy(proto
, "PIM", sizeof(proto
));
5981 if (c_oil
->oif_flags
[oif_vif_index
]
5982 & PIM_OIF_FLAG_PROTO_IGMP
) {
5983 strlcpy(proto
, "IGMP", sizeof(proto
));
5986 if (c_oil
->oif_flags
[oif_vif_index
]
5987 & PIM_OIF_FLAG_PROTO_VXLAN
) {
5988 strlcpy(proto
, "VxLAN", sizeof(proto
));
5991 if (c_oil
->oif_flags
[oif_vif_index
]
5992 & PIM_OIF_FLAG_PROTO_STAR
) {
5993 strlcpy(proto
, "STAR", sizeof(proto
));
5997 "%-15s %-15s %-15s %-6s %-16s %-16s %-3d %8s\n",
5998 src_str
, grp_str
, state_str
, proto
,
5999 in_ifname
, out_ifname
, ttl
,
6005 in_ifname
[0] = '\0';
6006 state_str
[0] = '\0';
6007 mroute_uptime
[0] = '\0';
6013 if (!uj
&& !found_oif
) {
6015 "%-15s %-15s %-15s %-6s %-16s %-16s %-3d %8s\n",
6016 src_str
, grp_str
, state_str
, "none", in_ifname
,
6017 "none", 0, "--:--:--");
6021 /* Print list of static routes */
6022 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
6025 if (!s_route
->c_oil
.installed
)
6028 pim_inet4_dump("<group?>", s_route
->group
, grp_str
,
6030 pim_inet4_dump("<source?>", s_route
->source
, src_str
,
6032 ifp_in
= pim_if_find_by_vif_index(pim
, s_route
->iif
);
6036 strlcpy(in_ifname
, ifp_in
->name
, sizeof(in_ifname
));
6038 strlcpy(in_ifname
, "<iif?>", sizeof(in_ifname
));
6042 /* Find the group, create it if it doesn't exist */
6043 json_object_object_get_ex(json
, grp_str
, &json_group
);
6046 json_group
= json_object_new_object();
6047 json_object_object_add(json
, grp_str
,
6051 /* Find the source nested under the group, create it if
6052 * it doesn't exist */
6053 json_object_object_get_ex(json_group
, src_str
,
6057 json_source
= json_object_new_object();
6058 json_object_object_add(json_group
, src_str
,
6062 json_object_string_add(json_source
, "iif", in_ifname
);
6065 strlcpy(proto
, "STATIC", sizeof(proto
));
6068 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
6070 struct interface
*ifp_out
;
6071 char oif_uptime
[10];
6074 ttl
= s_route
->oif_ttls
[oif_vif_index
];
6078 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
6080 oif_uptime
, sizeof(oif_uptime
),
6083 .oif_creation
[oif_vif_index
]);
6087 strlcpy(out_ifname
, ifp_out
->name
, sizeof(out_ifname
));
6089 strlcpy(out_ifname
, "<oif?>", sizeof(out_ifname
));
6092 json_ifp_out
= json_object_new_object();
6093 json_object_string_add(json_ifp_out
, "source",
6095 json_object_string_add(json_ifp_out
, "group",
6097 json_object_boolean_true_add(json_ifp_out
,
6099 json_object_string_add(json_ifp_out
,
6102 json_object_int_add(
6103 json_ifp_out
, "iVifI",
6104 s_route
->c_oil
.oil
.mfcc_parent
);
6105 json_object_string_add(json_ifp_out
,
6106 "outboundInterface",
6108 json_object_int_add(json_ifp_out
, "oVifI",
6110 json_object_int_add(json_ifp_out
, "ttl", ttl
);
6111 json_object_string_add(json_ifp_out
, "upTime",
6114 json_oil
= json_object_new_object();
6115 json_object_object_add(json_source
,
6118 json_object_object_add(json_oil
, out_ifname
,
6122 "%-15s %-15s %-6s %-16s %-16s %-3d %8s %s\n",
6123 src_str
, grp_str
, proto
, in_ifname
,
6124 out_ifname
, ttl
, oif_uptime
,
6126 if (first
&& !fill
) {
6129 in_ifname
[0] = '\0';
6135 if (!uj
&& !found_oif
) {
6137 "%-15s %-15s %-6s %-16s %-16s %-3d %8s %s\n",
6138 src_str
, grp_str
, proto
, in_ifname
, "none", 0,
6139 "--:--:--", pim
->vrf
->name
);
6144 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
6145 json
, JSON_C_TO_STRING_PRETTY
));
6146 json_object_free(json
);
6150 DEFPY (show_ip_mroute
,
6152 "show ip mroute [vrf NAME] [A.B.C.D$s_or_g [A.B.C.D$g]] [fill$fill] [json$json]",
6157 "The Source or Group\n"
6159 "Fill in Assumed data\n"
6162 struct prefix_sg sg
= {0};
6163 struct pim_instance
*pim
;
6166 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
6169 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
6172 pim
= pim_get_pim_instance(v
->vrf_id
);
6175 vty_out(vty
, "%% Unable to find pim instance\n");
6179 if (s_or_g
.s_addr
!= 0) {
6180 if (g
.s_addr
!= 0) {
6186 show_mroute(pim
, vty
, &sg
, !!fill
, !!json
);
6190 DEFUN (show_ip_mroute_vrf_all
,
6191 show_ip_mroute_vrf_all_cmd
,
6192 "show ip mroute vrf all [fill] [json]",
6197 "Fill in Assumed data\n"
6200 struct prefix_sg sg
= {0};
6201 bool uj
= use_json(argc
, argv
);
6207 if (argv_find(argv
, argc
, "fill", &idx
))
6212 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
6216 vty_out(vty
, " \"%s\": ", vrf
->name
);
6219 vty_out(vty
, "VRF: %s\n", vrf
->name
);
6220 show_mroute(vrf
->info
, vty
, &sg
, fill
, uj
);
6223 vty_out(vty
, "}\n");
6228 DEFUN (clear_ip_mroute_count
,
6229 clear_ip_mroute_count_cmd
,
6230 "clear ip mroute [vrf NAME] count",
6235 "Route and packet count data\n")
6238 struct listnode
*node
;
6239 struct channel_oil
*c_oil
;
6240 struct static_route
*sr
;
6241 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6242 struct pim_instance
*pim
;
6248 frr_each(rb_pim_oil
, &pim
->channel_oil_head
, c_oil
) {
6249 if (!c_oil
->installed
)
6252 pim_mroute_update_counters(c_oil
);
6253 c_oil
->cc
.origpktcnt
= c_oil
->cc
.pktcnt
;
6254 c_oil
->cc
.origbytecnt
= c_oil
->cc
.bytecnt
;
6255 c_oil
->cc
.origwrong_if
= c_oil
->cc
.wrong_if
;
6258 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, sr
)) {
6259 if (!sr
->c_oil
.installed
)
6262 pim_mroute_update_counters(&sr
->c_oil
);
6264 sr
->c_oil
.cc
.origpktcnt
= sr
->c_oil
.cc
.pktcnt
;
6265 sr
->c_oil
.cc
.origbytecnt
= sr
->c_oil
.cc
.bytecnt
;
6266 sr
->c_oil
.cc
.origwrong_if
= sr
->c_oil
.cc
.wrong_if
;
6271 static void show_mroute_count(struct pim_instance
*pim
, struct vty
*vty
)
6273 struct listnode
*node
;
6274 struct channel_oil
*c_oil
;
6275 struct static_route
*sr
;
6280 "Source Group LastUsed Packets Bytes WrongIf \n");
6282 /* Print PIM and IGMP route counts */
6283 frr_each (rb_pim_oil
, &pim
->channel_oil_head
, c_oil
) {
6284 char group_str
[INET_ADDRSTRLEN
];
6285 char source_str
[INET_ADDRSTRLEN
];
6287 if (!c_oil
->installed
)
6290 pim_mroute_update_counters(c_oil
);
6292 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, group_str
,
6294 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, source_str
,
6295 sizeof(source_str
));
6297 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
6298 source_str
, group_str
, c_oil
->cc
.lastused
/ 100,
6299 c_oil
->cc
.pktcnt
- c_oil
->cc
.origpktcnt
,
6300 c_oil
->cc
.bytecnt
- c_oil
->cc
.origbytecnt
,
6301 c_oil
->cc
.wrong_if
- c_oil
->cc
.origwrong_if
);
6304 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, sr
)) {
6305 char group_str
[INET_ADDRSTRLEN
];
6306 char source_str
[INET_ADDRSTRLEN
];
6308 if (!sr
->c_oil
.installed
)
6311 pim_mroute_update_counters(&sr
->c_oil
);
6313 pim_inet4_dump("<group?>", sr
->c_oil
.oil
.mfcc_mcastgrp
,
6314 group_str
, sizeof(group_str
));
6315 pim_inet4_dump("<source?>", sr
->c_oil
.oil
.mfcc_origin
,
6316 source_str
, sizeof(source_str
));
6318 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
6319 source_str
, group_str
, sr
->c_oil
.cc
.lastused
,
6320 sr
->c_oil
.cc
.pktcnt
- sr
->c_oil
.cc
.origpktcnt
,
6321 sr
->c_oil
.cc
.bytecnt
- sr
->c_oil
.cc
.origbytecnt
,
6322 sr
->c_oil
.cc
.wrong_if
- sr
->c_oil
.cc
.origwrong_if
);
6326 DEFUN (show_ip_mroute_count
,
6327 show_ip_mroute_count_cmd
,
6328 "show ip mroute [vrf NAME] count",
6333 "Route and packet count data\n")
6336 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6341 show_mroute_count(vrf
->info
, vty
);
6345 DEFUN (show_ip_mroute_count_vrf_all
,
6346 show_ip_mroute_count_vrf_all_cmd
,
6347 "show ip mroute vrf all count",
6352 "Route and packet count data\n")
6354 bool uj
= use_json(argc
, argv
);
6360 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
6364 vty_out(vty
, " \"%s\": ", vrf
->name
);
6367 vty_out(vty
, "VRF: %s\n", vrf
->name
);
6368 show_mroute_count(vrf
->info
, vty
);
6371 vty_out(vty
, "}\n");
6376 static void show_mroute_summary(struct pim_instance
*pim
, struct vty
*vty
)
6378 struct listnode
*node
;
6379 struct channel_oil
*c_oil
;
6380 struct static_route
*s_route
;
6381 uint32_t starg_sw_mroute_cnt
= 0;
6382 uint32_t sg_sw_mroute_cnt
= 0;
6383 uint32_t starg_hw_mroute_cnt
= 0;
6384 uint32_t sg_hw_mroute_cnt
= 0;
6386 vty_out(vty
, "Mroute Type Installed/Total\n");
6388 frr_each (rb_pim_oil
, &pim
->channel_oil_head
, c_oil
) {
6389 if (!c_oil
->installed
) {
6390 if (c_oil
->oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
6391 starg_sw_mroute_cnt
++;
6395 if (c_oil
->oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
6396 starg_hw_mroute_cnt
++;
6402 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
6403 if (!s_route
->c_oil
.installed
) {
6404 if (s_route
->c_oil
.oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
6405 starg_sw_mroute_cnt
++;
6409 if (s_route
->c_oil
.oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
6410 starg_hw_mroute_cnt
++;
6416 vty_out(vty
, "%-20s %d/%d\n", "(*, G)", starg_hw_mroute_cnt
,
6417 starg_sw_mroute_cnt
+ starg_hw_mroute_cnt
);
6418 vty_out(vty
, "%-20s %d/%d\n", "(S, G)", sg_hw_mroute_cnt
,
6419 sg_sw_mroute_cnt
+ sg_hw_mroute_cnt
);
6420 vty_out(vty
, "------\n");
6421 vty_out(vty
, "%-20s %d/%d\n", "Total",
6422 (starg_hw_mroute_cnt
+ sg_hw_mroute_cnt
),
6423 (starg_sw_mroute_cnt
+
6424 starg_hw_mroute_cnt
+
6429 DEFUN (show_ip_mroute_summary
,
6430 show_ip_mroute_summary_cmd
,
6431 "show ip mroute [vrf NAME] summary",
6436 "Summary of all mroutes\n")
6439 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6444 show_mroute_summary(vrf
->info
, vty
);
6448 DEFUN (show_ip_mroute_summary_vrf_all
,
6449 show_ip_mroute_summary_vrf_all_cmd
,
6450 "show ip mroute vrf all summary",
6455 "Summary of all mroutes\n")
6459 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
6460 vty_out(vty
, "VRF: %s\n", vrf
->name
);
6461 show_mroute_summary(vrf
->info
, vty
);
6469 "show ip rib [vrf NAME] A.B.C.D",
6474 "Unicast address\n")
6477 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6478 struct in_addr addr
;
6479 const char *addr_str
;
6480 struct pim_nexthop nexthop
;
6481 char nexthop_addr_str
[PREFIX_STRLEN
];
6487 memset(&nexthop
, 0, sizeof(nexthop
));
6488 argv_find(argv
, argc
, "A.B.C.D", &idx
);
6489 addr_str
= argv
[idx
]->arg
;
6490 result
= inet_pton(AF_INET
, addr_str
, &addr
);
6492 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
6493 errno
, safe_strerror(errno
));
6497 if (!pim_nexthop_lookup(vrf
->info
, &nexthop
, addr
, 0)) {
6499 "Failure querying RIB nexthop for unicast address %s\n",
6505 "Address NextHop Interface Metric Preference\n");
6507 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
6508 nexthop_addr_str
, sizeof(nexthop_addr_str
));
6510 vty_out(vty
, "%-15s %-15s %-9s %6d %10d\n", addr_str
, nexthop_addr_str
,
6511 nexthop
.interface
? nexthop
.interface
->name
: "<ifname?>",
6512 nexthop
.mrib_route_metric
, nexthop
.mrib_metric_preference
);
6517 static void show_ssmpingd(struct pim_instance
*pim
, struct vty
*vty
)
6519 struct listnode
*node
;
6520 struct ssmpingd_sock
*ss
;
6524 "Source Socket Address Port Uptime Requests\n");
6526 if (!pim
->ssmpingd_list
)
6529 now
= pim_time_monotonic_sec();
6531 for (ALL_LIST_ELEMENTS_RO(pim
->ssmpingd_list
, node
, ss
)) {
6532 char source_str
[INET_ADDRSTRLEN
];
6534 struct sockaddr_in bind_addr
;
6535 socklen_t len
= sizeof(bind_addr
);
6536 char bind_addr_str
[INET_ADDRSTRLEN
];
6538 pim_inet4_dump("<src?>", ss
->source_addr
, source_str
,
6539 sizeof(source_str
));
6541 if (pim_socket_getsockname(
6542 ss
->sock_fd
, (struct sockaddr
*)&bind_addr
, &len
)) {
6544 "%% Failure reading socket name for ssmpingd source %s on fd=%d\n",
6545 source_str
, ss
->sock_fd
);
6548 pim_inet4_dump("<addr?>", bind_addr
.sin_addr
, bind_addr_str
,
6549 sizeof(bind_addr_str
));
6550 pim_time_uptime(ss_uptime
, sizeof(ss_uptime
),
6551 now
- ss
->creation
);
6553 vty_out(vty
, "%-15s %6d %-15s %5d %8s %8lld\n", source_str
,
6554 ss
->sock_fd
, bind_addr_str
, ntohs(bind_addr
.sin_port
),
6555 ss_uptime
, (long long)ss
->requests
);
6559 DEFUN (show_ip_ssmpingd
,
6560 show_ip_ssmpingd_cmd
,
6561 "show ip ssmpingd [vrf NAME]",
6568 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6573 show_ssmpingd(vrf
->info
, vty
);
6577 static int pim_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
6578 const char *rp
, const char *group
,
6583 result
= pim_rp_new_config(pim
, rp
, group
, plist
);
6585 if (result
== PIM_GROUP_BAD_ADDR_MASK_COMBO
) {
6586 vty_out(vty
, "%% Inconsistent address and mask: %s\n",
6588 return CMD_WARNING_CONFIG_FAILED
;
6591 if (result
== PIM_GROUP_BAD_ADDRESS
) {
6592 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
6593 return CMD_WARNING_CONFIG_FAILED
;
6596 if (result
== PIM_RP_BAD_ADDRESS
) {
6597 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
6598 return CMD_WARNING_CONFIG_FAILED
;
6601 if (result
== PIM_RP_NO_PATH
) {
6602 vty_out(vty
, "%% No Path to RP address specified: %s\n", rp
);
6606 if (result
== PIM_GROUP_OVERLAP
) {
6608 "%% Group range specified cannot exact match another\n");
6609 return CMD_WARNING_CONFIG_FAILED
;
6612 if (result
== PIM_GROUP_PFXLIST_OVERLAP
) {
6614 "%% This group is already covered by a RP prefix-list\n");
6615 return CMD_WARNING_CONFIG_FAILED
;
6618 if (result
== PIM_RP_PFXLIST_IN_USE
) {
6620 "%% The same prefix-list cannot be applied to multiple RPs\n");
6621 return CMD_WARNING_CONFIG_FAILED
;
6627 static int pim_cmd_spt_switchover(struct pim_instance
*pim
,
6628 enum pim_spt_switchover spt
,
6631 pim
->spt
.switchover
= spt
;
6633 switch (pim
->spt
.switchover
) {
6634 case PIM_SPT_IMMEDIATE
:
6635 XFREE(MTYPE_PIM_PLIST_NAME
, pim
->spt
.plist
);
6637 pim_upstream_add_lhr_star_pimreg(pim
);
6639 case PIM_SPT_INFINITY
:
6640 pim_upstream_remove_lhr_star_pimreg(pim
, plist
);
6642 XFREE(MTYPE_PIM_PLIST_NAME
, pim
->spt
.plist
);
6646 XSTRDUP(MTYPE_PIM_PLIST_NAME
, plist
);
6653 DEFUN (ip_pim_spt_switchover_infinity
,
6654 ip_pim_spt_switchover_infinity_cmd
,
6655 "ip pim spt-switchover infinity-and-beyond",
6659 "Never switch to SPT Tree\n")
6661 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6662 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, NULL
);
6665 DEFUN (ip_pim_spt_switchover_infinity_plist
,
6666 ip_pim_spt_switchover_infinity_plist_cmd
,
6667 "ip pim spt-switchover infinity-and-beyond prefix-list WORD",
6671 "Never switch to SPT Tree\n"
6672 "Prefix-List to control which groups to switch\n"
6673 "Prefix-List name\n")
6675 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6676 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, argv
[5]->arg
);
6679 DEFUN (no_ip_pim_spt_switchover_infinity
,
6680 no_ip_pim_spt_switchover_infinity_cmd
,
6681 "no ip pim spt-switchover infinity-and-beyond",
6686 "Never switch to SPT Tree\n")
6688 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6689 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
6692 DEFUN (no_ip_pim_spt_switchover_infinity_plist
,
6693 no_ip_pim_spt_switchover_infinity_plist_cmd
,
6694 "no ip pim spt-switchover infinity-and-beyond prefix-list WORD",
6699 "Never switch to SPT Tree\n"
6700 "Prefix-List to control which groups to switch\n"
6701 "Prefix-List name\n")
6703 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6704 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
6707 DEFPY (pim_register_accept_list
,
6708 pim_register_accept_list_cmd
,
6709 "[no] ip pim register-accept-list WORD$word",
6713 "Only accept registers from a specific source prefix list\n"
6714 "Prefix-List name\n")
6716 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6719 XFREE(MTYPE_PIM_PLIST_NAME
, pim
->register_plist
);
6721 XFREE(MTYPE_PIM_PLIST_NAME
, pim
->register_plist
);
6722 pim
->register_plist
= XSTRDUP(MTYPE_PIM_PLIST_NAME
, word
);
6727 DEFUN (ip_pim_joinprune_time
,
6728 ip_pim_joinprune_time_cmd
,
6729 "ip pim join-prune-interval (60-600)",
6731 "pim multicast routing\n"
6732 "Join Prune Send Interval\n"
6735 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6736 router
->t_periodic
= atoi(argv
[3]->arg
);
6740 DEFUN (no_ip_pim_joinprune_time
,
6741 no_ip_pim_joinprune_time_cmd
,
6742 "no ip pim join-prune-interval (60-600)",
6745 "pim multicast routing\n"
6746 "Join Prune Send Interval\n"
6749 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6750 router
->t_periodic
= PIM_DEFAULT_T_PERIODIC
;
6754 DEFUN (ip_pim_register_suppress
,
6755 ip_pim_register_suppress_cmd
,
6756 "ip pim register-suppress-time (5-60000)",
6758 "pim multicast routing\n"
6759 "Register Suppress Timer\n"
6762 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6763 router
->register_suppress_time
= atoi(argv
[3]->arg
);
6767 DEFUN (no_ip_pim_register_suppress
,
6768 no_ip_pim_register_suppress_cmd
,
6769 "no ip pim register-suppress-time (5-60000)",
6772 "pim multicast routing\n"
6773 "Register Suppress Timer\n"
6776 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6777 router
->register_suppress_time
= PIM_REGISTER_SUPPRESSION_TIME_DEFAULT
;
6781 DEFUN (ip_pim_rp_keep_alive
,
6782 ip_pim_rp_keep_alive_cmd
,
6783 "ip pim rp keep-alive-timer (31-60000)",
6785 "pim multicast routing\n"
6787 "Keep alive Timer\n"
6790 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6791 pim
->rp_keep_alive_time
= atoi(argv
[4]->arg
);
6795 DEFUN (no_ip_pim_rp_keep_alive
,
6796 no_ip_pim_rp_keep_alive_cmd
,
6797 "no ip pim rp keep-alive-timer (31-60000)",
6800 "pim multicast routing\n"
6802 "Keep alive Timer\n"
6805 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6806 pim
->rp_keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
6810 DEFUN (ip_pim_keep_alive
,
6811 ip_pim_keep_alive_cmd
,
6812 "ip pim keep-alive-timer (31-60000)",
6814 "pim multicast routing\n"
6815 "Keep alive Timer\n"
6818 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6819 pim
->keep_alive_time
= atoi(argv
[3]->arg
);
6823 DEFUN (no_ip_pim_keep_alive
,
6824 no_ip_pim_keep_alive_cmd
,
6825 "no ip pim keep-alive-timer (31-60000)",
6828 "pim multicast routing\n"
6829 "Keep alive Timer\n"
6832 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6833 pim
->keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
6837 DEFUN (ip_pim_packets
,
6839 "ip pim packets (1-100)",
6841 "pim multicast routing\n"
6842 "packets to process at one time per fd\n"
6843 "Number of packets\n")
6845 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6846 router
->packet_process
= atoi(argv
[3]->arg
);
6850 DEFUN (no_ip_pim_packets
,
6851 no_ip_pim_packets_cmd
,
6852 "no ip pim packets (1-100)",
6855 "pim multicast routing\n"
6856 "packets to process at one time per fd\n"
6857 "Number of packets\n")
6859 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6860 router
->packet_process
= PIM_DEFAULT_PACKET_PROCESS
;
6864 DEFUN (ip_pim_v6_secondary
,
6865 ip_pim_v6_secondary_cmd
,
6866 "ip pim send-v6-secondary",
6868 "pim multicast routing\n"
6869 "Send v6 secondary addresses\n")
6871 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6872 pim
->send_v6_secondary
= 1;
6877 DEFUN (no_ip_pim_v6_secondary
,
6878 no_ip_pim_v6_secondary_cmd
,
6879 "no ip pim send-v6-secondary",
6882 "pim multicast routing\n"
6883 "Send v6 secondary addresses\n")
6885 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6886 pim
->send_v6_secondary
= 0;
6893 "ip pim rp A.B.C.D [A.B.C.D/M]",
6895 "pim multicast routing\n"
6897 "ip address of RP\n"
6898 "Group Address range to cover\n")
6900 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6903 if (argc
== (idx_ipv4
+ 1))
6904 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
6907 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
6908 argv
[idx_ipv4
+ 1]->arg
, NULL
);
6911 DEFUN (ip_pim_rp_prefix_list
,
6912 ip_pim_rp_prefix_list_cmd
,
6913 "ip pim rp A.B.C.D prefix-list WORD",
6915 "pim multicast routing\n"
6917 "ip address of RP\n"
6918 "group prefix-list filter\n"
6919 "Name of a prefix-list\n")
6921 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6922 return pim_rp_cmd_worker(pim
, vty
, argv
[3]->arg
, NULL
, argv
[5]->arg
);
6925 static int pim_no_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
6926 const char *rp
, const char *group
,
6929 int result
= pim_rp_del_config(pim
, rp
, group
, plist
);
6931 if (result
== PIM_GROUP_BAD_ADDRESS
) {
6932 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
6933 return CMD_WARNING_CONFIG_FAILED
;
6936 if (result
== PIM_RP_BAD_ADDRESS
) {
6937 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
6938 return CMD_WARNING_CONFIG_FAILED
;
6941 if (result
== PIM_RP_NOT_FOUND
) {
6942 vty_out(vty
, "%% Unable to find specified RP\n");
6943 return CMD_WARNING_CONFIG_FAILED
;
6949 DEFUN (no_ip_pim_rp
,
6951 "no ip pim rp A.B.C.D [A.B.C.D/M]",
6954 "pim multicast routing\n"
6956 "ip address of RP\n"
6957 "Group Address range to cover\n")
6959 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6960 int idx_ipv4
= 4, idx_group
= 0;
6962 if (argv_find(argv
, argc
, "A.B.C.D/M", &idx_group
))
6963 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
6964 argv
[idx_group
]->arg
, NULL
);
6966 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
6970 DEFUN (no_ip_pim_rp_prefix_list
,
6971 no_ip_pim_rp_prefix_list_cmd
,
6972 "no ip pim rp A.B.C.D prefix-list WORD",
6975 "pim multicast routing\n"
6977 "ip address of RP\n"
6978 "group prefix-list filter\n"
6979 "Name of a prefix-list\n")
6981 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6982 return pim_no_rp_cmd_worker(pim
, vty
, argv
[4]->arg
, NULL
, argv
[6]->arg
);
6985 static int pim_ssm_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
6988 int result
= pim_ssm_range_set(pim
, pim
->vrf_id
, plist
);
6989 int ret
= CMD_WARNING_CONFIG_FAILED
;
6991 if (result
== PIM_SSM_ERR_NONE
)
6995 case PIM_SSM_ERR_NO_VRF
:
6996 vty_out(vty
, "%% VRF doesn't exist\n");
6998 case PIM_SSM_ERR_DUP
:
6999 vty_out(vty
, "%% duplicate config\n");
7003 vty_out(vty
, "%% ssm range config failed\n");
7009 DEFUN (ip_pim_ssm_prefix_list
,
7010 ip_pim_ssm_prefix_list_cmd
,
7011 "ip pim ssm prefix-list WORD",
7013 "pim multicast routing\n"
7014 "Source Specific Multicast\n"
7015 "group range prefix-list filter\n"
7016 "Name of a prefix-list\n")
7018 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7019 return pim_ssm_cmd_worker(pim
, vty
, argv
[4]->arg
);
7022 DEFUN (no_ip_pim_ssm_prefix_list
,
7023 no_ip_pim_ssm_prefix_list_cmd
,
7024 "no ip pim ssm prefix-list",
7027 "pim multicast routing\n"
7028 "Source Specific Multicast\n"
7029 "group range prefix-list filter\n")
7031 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7032 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
7035 DEFUN (no_ip_pim_ssm_prefix_list_name
,
7036 no_ip_pim_ssm_prefix_list_name_cmd
,
7037 "no ip pim ssm prefix-list WORD",
7040 "pim multicast routing\n"
7041 "Source Specific Multicast\n"
7042 "group range prefix-list filter\n"
7043 "Name of a prefix-list\n")
7045 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7046 struct pim_ssm
*ssm
= pim
->ssm_info
;
7048 if (ssm
->plist_name
&& !strcmp(ssm
->plist_name
, argv
[5]->arg
))
7049 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
7051 vty_out(vty
, "%% pim ssm prefix-list %s doesn't exist\n", argv
[5]->arg
);
7053 return CMD_WARNING_CONFIG_FAILED
;
7056 static void ip_pim_ssm_show_group_range(struct pim_instance
*pim
,
7057 struct vty
*vty
, bool uj
)
7059 struct pim_ssm
*ssm
= pim
->ssm_info
;
7060 const char *range_str
=
7061 ssm
->plist_name
? ssm
->plist_name
: PIM_SSM_STANDARD_RANGE
;
7065 json
= json_object_new_object();
7066 json_object_string_add(json
, "ssmGroups", range_str
);
7067 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
7068 json
, JSON_C_TO_STRING_PRETTY
));
7069 json_object_free(json
);
7071 vty_out(vty
, "SSM group range : %s\n", range_str
);
7074 DEFUN (show_ip_pim_ssm_range
,
7075 show_ip_pim_ssm_range_cmd
,
7076 "show ip pim [vrf NAME] group-type [json]",
7085 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
7086 bool uj
= use_json(argc
, argv
);
7091 ip_pim_ssm_show_group_range(vrf
->info
, vty
, uj
);
7096 static void ip_pim_ssm_show_group_type(struct pim_instance
*pim
,
7097 struct vty
*vty
, bool uj
,
7100 struct in_addr group_addr
;
7101 const char *type_str
;
7104 result
= inet_pton(AF_INET
, group
, &group_addr
);
7106 type_str
= "invalid";
7108 if (pim_is_group_224_4(group_addr
))
7110 pim_is_grp_ssm(pim
, group_addr
) ? "SSM" : "ASM";
7112 type_str
= "not-multicast";
7117 json
= json_object_new_object();
7118 json_object_string_add(json
, "groupType", type_str
);
7119 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
7120 json
, JSON_C_TO_STRING_PRETTY
));
7121 json_object_free(json
);
7123 vty_out(vty
, "Group type : %s\n", type_str
);
7126 DEFUN (show_ip_pim_group_type
,
7127 show_ip_pim_group_type_cmd
,
7128 "show ip pim [vrf NAME] group-type A.B.C.D [json]",
7133 "multicast group type\n"
7138 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
7139 bool uj
= use_json(argc
, argv
);
7144 argv_find(argv
, argc
, "A.B.C.D", &idx
);
7145 ip_pim_ssm_show_group_type(vrf
->info
, vty
, uj
, argv
[idx
]->arg
);
7150 DEFUN (show_ip_pim_bsr
,
7151 show_ip_pim_bsr_cmd
,
7152 "show ip pim bsr [json]",
7156 "boot-strap router information\n"
7160 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
7161 bool uj
= use_json(argc
, argv
);
7166 pim_show_bsr(vrf
->info
, vty
, uj
);
7173 "ip ssmpingd [A.B.C.D]",
7178 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7181 struct in_addr source_addr
;
7182 const char *source_str
= (argc
== 3) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
7184 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
7186 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
7187 source_str
, errno
, safe_strerror(errno
));
7188 return CMD_WARNING_CONFIG_FAILED
;
7191 result
= pim_ssmpingd_start(pim
, source_addr
);
7193 vty_out(vty
, "%% Failure starting ssmpingd for source %s: %d\n",
7194 source_str
, result
);
7195 return CMD_WARNING_CONFIG_FAILED
;
7201 DEFUN (no_ip_ssmpingd
,
7203 "no ip ssmpingd [A.B.C.D]",
7209 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7212 struct in_addr source_addr
;
7213 const char *source_str
= (argc
== 4) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
7215 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
7217 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
7218 source_str
, errno
, safe_strerror(errno
));
7219 return CMD_WARNING_CONFIG_FAILED
;
7222 result
= pim_ssmpingd_stop(pim
, source_addr
);
7224 vty_out(vty
, "%% Failure stopping ssmpingd for source %s: %d\n",
7225 source_str
, result
);
7226 return CMD_WARNING_CONFIG_FAILED
;
7236 "pim multicast routing\n"
7237 "Enable PIM ECMP \n")
7239 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7240 pim
->ecmp_enable
= true;
7245 DEFUN (no_ip_pim_ecmp
,
7250 "pim multicast routing\n"
7251 "Disable PIM ECMP \n")
7253 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7254 pim
->ecmp_enable
= false;
7259 DEFUN (ip_pim_ecmp_rebalance
,
7260 ip_pim_ecmp_rebalance_cmd
,
7261 "ip pim ecmp rebalance",
7263 "pim multicast routing\n"
7264 "Enable PIM ECMP \n"
7265 "Enable PIM ECMP Rebalance\n")
7267 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7268 pim
->ecmp_enable
= true;
7269 pim
->ecmp_rebalance_enable
= true;
7274 DEFUN (no_ip_pim_ecmp_rebalance
,
7275 no_ip_pim_ecmp_rebalance_cmd
,
7276 "no ip pim ecmp rebalance",
7279 "pim multicast routing\n"
7280 "Disable PIM ECMP \n"
7281 "Disable PIM ECMP Rebalance\n")
7283 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7284 pim
->ecmp_rebalance_enable
= false;
7289 static int pim_cmd_igmp_start(struct vty
*vty
, struct interface
*ifp
)
7291 struct pim_interface
*pim_ifp
;
7292 uint8_t need_startup
= 0;
7294 pim_ifp
= ifp
->info
;
7297 (void)pim_if_new(ifp
, true, false, false, false);
7300 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
7301 PIM_IF_DO_IGMP(pim_ifp
->options
);
7306 /* 'ip igmp' executed multiple times, with need_startup
7307 avoid multiple if add all and membership refresh */
7309 pim_if_addr_add_all(ifp
);
7310 pim_if_membership_refresh(ifp
);
7316 DEFUN (interface_ip_igmp
,
7317 interface_ip_igmp_cmd
,
7322 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7324 return pim_cmd_igmp_start(vty
, ifp
);
7327 DEFUN (interface_no_ip_igmp
,
7328 interface_no_ip_igmp_cmd
,
7334 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7335 struct pim_interface
*pim_ifp
= ifp
->info
;
7340 PIM_IF_DONT_IGMP(pim_ifp
->options
);
7342 pim_if_membership_clear(ifp
);
7344 pim_if_addr_del_all_igmp(ifp
);
7346 if (!PIM_IF_TEST_PIM(pim_ifp
->options
)) {
7353 DEFUN (interface_ip_igmp_join
,
7354 interface_ip_igmp_join_cmd
,
7355 "ip igmp join A.B.C.D [A.B.C.D]",
7358 "IGMP join multicast group\n"
7359 "Multicast group address\n"
7362 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7365 const char *group_str
;
7366 const char *source_str
;
7367 struct in_addr group_addr
;
7368 struct in_addr source_addr
;
7372 group_str
= argv
[idx_ipv4
]->arg
;
7373 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
7375 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
7376 errno
, safe_strerror(errno
));
7377 return CMD_WARNING_CONFIG_FAILED
;
7380 /* Source address */
7381 if (argc
== (idx_ipv4_2
+ 1)) {
7382 source_str
= argv
[idx_ipv4_2
]->arg
;
7383 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
7385 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
7386 source_str
, errno
, safe_strerror(errno
));
7387 return CMD_WARNING_CONFIG_FAILED
;
7389 /* Reject 0.0.0.0. Reserved for any source. */
7390 if (source_addr
.s_addr
== INADDR_ANY
) {
7391 vty_out(vty
, "Bad source address %s\n", source_str
);
7392 return CMD_WARNING_CONFIG_FAILED
;
7395 source_addr
.s_addr
= INADDR_ANY
;
7398 CMD_FERR_RETURN(pim_if_igmp_join_add(ifp
, group_addr
, source_addr
),
7399 "Failure joining IGMP group: $ERR");
7404 DEFUN (interface_no_ip_igmp_join
,
7405 interface_no_ip_igmp_join_cmd
,
7406 "no ip igmp join A.B.C.D [A.B.C.D]",
7410 "IGMP join multicast group\n"
7411 "Multicast group address\n"
7414 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7417 const char *group_str
;
7418 const char *source_str
;
7419 struct in_addr group_addr
;
7420 struct in_addr source_addr
;
7424 group_str
= argv
[idx_ipv4
]->arg
;
7425 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
7427 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
7428 errno
, safe_strerror(errno
));
7429 return CMD_WARNING_CONFIG_FAILED
;
7432 /* Source address */
7433 if (argc
== (idx_ipv4_2
+ 1)) {
7434 source_str
= argv
[idx_ipv4_2
]->arg
;
7435 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
7437 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
7438 source_str
, errno
, safe_strerror(errno
));
7439 return CMD_WARNING_CONFIG_FAILED
;
7441 /* Reject 0.0.0.0. Reserved for any source. */
7442 if (source_addr
.s_addr
== INADDR_ANY
) {
7443 vty_out(vty
, "Bad source address %s\n", source_str
);
7444 return CMD_WARNING_CONFIG_FAILED
;
7448 source_addr
.s_addr
= INADDR_ANY
;
7451 result
= pim_if_igmp_join_del(ifp
, group_addr
, source_addr
);
7454 "%% Failure leaving IGMP group %s source %s on interface %s: %d\n",
7455 group_str
, source_str
, ifp
->name
, result
);
7456 return CMD_WARNING_CONFIG_FAILED
;
7463 CLI reconfiguration affects the interface level (struct pim_interface).
7464 This function propagates the reconfiguration to every active socket
7467 static void igmp_sock_query_interval_reconfig(struct igmp_sock
*igmp
)
7469 struct interface
*ifp
;
7470 struct pim_interface
*pim_ifp
;
7474 /* other querier present? */
7476 if (igmp
->t_other_querier_timer
)
7479 /* this is the querier */
7481 zassert(igmp
->interface
);
7482 zassert(igmp
->interface
->info
);
7484 ifp
= igmp
->interface
;
7485 pim_ifp
= ifp
->info
;
7487 if (PIM_DEBUG_IGMP_TRACE
) {
7488 char ifaddr_str
[INET_ADDRSTRLEN
];
7489 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
7490 sizeof(ifaddr_str
));
7491 zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
7492 __func__
, ifaddr_str
, ifp
->name
,
7493 pim_ifp
->igmp_default_query_interval
);
7497 igmp_startup_mode_on() will reset QQI:
7499 igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
7501 igmp_startup_mode_on(igmp
);
7504 static void igmp_sock_query_reschedule(struct igmp_sock
*igmp
)
7506 if (igmp
->mtrace_only
)
7509 if (igmp
->t_igmp_query_timer
) {
7510 /* other querier present */
7511 zassert(igmp
->t_igmp_query_timer
);
7512 zassert(!igmp
->t_other_querier_timer
);
7514 pim_igmp_general_query_off(igmp
);
7515 pim_igmp_general_query_on(igmp
);
7517 zassert(igmp
->t_igmp_query_timer
);
7518 zassert(!igmp
->t_other_querier_timer
);
7520 /* this is the querier */
7522 zassert(!igmp
->t_igmp_query_timer
);
7523 zassert(igmp
->t_other_querier_timer
);
7525 pim_igmp_other_querier_timer_off(igmp
);
7526 pim_igmp_other_querier_timer_on(igmp
);
7528 zassert(!igmp
->t_igmp_query_timer
);
7529 zassert(igmp
->t_other_querier_timer
);
7533 static void change_query_interval(struct pim_interface
*pim_ifp
,
7536 struct listnode
*sock_node
;
7537 struct igmp_sock
*igmp
;
7539 pim_ifp
->igmp_default_query_interval
= query_interval
;
7541 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
7542 igmp_sock_query_interval_reconfig(igmp
);
7543 igmp_sock_query_reschedule(igmp
);
7547 static void change_query_max_response_time(struct pim_interface
*pim_ifp
,
7548 int query_max_response_time_dsec
)
7550 struct listnode
*sock_node
;
7551 struct igmp_sock
*igmp
;
7553 pim_ifp
->igmp_query_max_response_time_dsec
=
7554 query_max_response_time_dsec
;
7557 Below we modify socket/group/source timers in order to quickly
7558 reflect the change. Otherwise, those timers would eventually catch
7562 /* scan all sockets */
7563 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
7564 struct listnode
*grp_node
;
7565 struct igmp_group
*grp
;
7567 /* reschedule socket general query */
7568 igmp_sock_query_reschedule(igmp
);
7570 /* scan socket groups */
7571 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grp_node
,
7573 struct listnode
*src_node
;
7574 struct igmp_source
*src
;
7576 /* reset group timers for groups in EXCLUDE mode */
7577 if (grp
->group_filtermode_isexcl
) {
7578 igmp_group_reset_gmi(grp
);
7581 /* scan group sources */
7582 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
,
7585 /* reset source timers for sources with running
7587 if (src
->t_source_timer
) {
7588 igmp_source_reset_gmi(igmp
, grp
, src
);
7595 #define IGMP_QUERY_INTERVAL_MIN (1)
7596 #define IGMP_QUERY_INTERVAL_MAX (1800)
7598 DEFUN (interface_ip_igmp_query_interval
,
7599 interface_ip_igmp_query_interval_cmd
,
7600 "ip igmp query-interval (1-1800)",
7603 IFACE_IGMP_QUERY_INTERVAL_STR
7604 "Query interval in seconds\n")
7606 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7607 struct pim_interface
*pim_ifp
= ifp
->info
;
7609 int query_interval_dsec
;
7613 ret
= pim_cmd_igmp_start(vty
, ifp
);
7614 if (ret
!= CMD_SUCCESS
)
7616 pim_ifp
= ifp
->info
;
7619 query_interval
= atoi(argv
[3]->arg
);
7620 query_interval_dsec
= 10 * query_interval
;
7623 It seems we don't need to check bounds since command.c does it
7624 already, but we verify them anyway for extra safety.
7626 if (query_interval
< IGMP_QUERY_INTERVAL_MIN
) {
7628 "General query interval %d lower than minimum %d\n",
7629 query_interval
, IGMP_QUERY_INTERVAL_MIN
);
7630 return CMD_WARNING_CONFIG_FAILED
;
7632 if (query_interval
> IGMP_QUERY_INTERVAL_MAX
) {
7634 "General query interval %d higher than maximum %d\n",
7635 query_interval
, IGMP_QUERY_INTERVAL_MAX
);
7636 return CMD_WARNING_CONFIG_FAILED
;
7639 if (query_interval_dsec
<= pim_ifp
->igmp_query_max_response_time_dsec
) {
7641 "Can't set general query interval %d dsec <= query max response time %d dsec.\n",
7642 query_interval_dsec
,
7643 pim_ifp
->igmp_query_max_response_time_dsec
);
7644 return CMD_WARNING_CONFIG_FAILED
;
7647 change_query_interval(pim_ifp
, query_interval
);
7652 DEFUN (interface_no_ip_igmp_query_interval
,
7653 interface_no_ip_igmp_query_interval_cmd
,
7654 "no ip igmp query-interval",
7658 IFACE_IGMP_QUERY_INTERVAL_STR
)
7660 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7661 struct pim_interface
*pim_ifp
= ifp
->info
;
7662 int default_query_interval_dsec
;
7667 default_query_interval_dsec
= IGMP_GENERAL_QUERY_INTERVAL
* 10;
7669 if (default_query_interval_dsec
7670 <= pim_ifp
->igmp_query_max_response_time_dsec
) {
7672 "Can't set default general query interval %d dsec <= query max response time %d dsec.\n",
7673 default_query_interval_dsec
,
7674 pim_ifp
->igmp_query_max_response_time_dsec
);
7675 return CMD_WARNING_CONFIG_FAILED
;
7678 change_query_interval(pim_ifp
, IGMP_GENERAL_QUERY_INTERVAL
);
7683 DEFUN (interface_ip_igmp_version
,
7684 interface_ip_igmp_version_cmd
,
7685 "ip igmp version (2-3)",
7689 "IGMP version number\n")
7691 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7692 struct pim_interface
*pim_ifp
= ifp
->info
;
7693 int igmp_version
, old_version
= 0;
7697 ret
= pim_cmd_igmp_start(vty
, ifp
);
7698 if (ret
!= CMD_SUCCESS
)
7700 pim_ifp
= ifp
->info
;
7703 igmp_version
= atoi(argv
[3]->arg
);
7704 old_version
= pim_ifp
->igmp_version
;
7705 pim_ifp
->igmp_version
= igmp_version
;
7707 // Check if IGMP is Enabled otherwise, enable on interface
7708 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
7709 PIM_IF_DO_IGMP(pim_ifp
->options
);
7710 pim_if_addr_add_all(ifp
);
7711 pim_if_membership_refresh(ifp
);
7712 old_version
= igmp_version
;
7713 // avoid refreshing membership again.
7715 /* Current and new version is different refresh existing
7716 membership. Going from 3 -> 2 or 2 -> 3. */
7717 if (old_version
!= igmp_version
)
7718 pim_if_membership_refresh(ifp
);
7723 DEFUN (interface_no_ip_igmp_version
,
7724 interface_no_ip_igmp_version_cmd
,
7725 "no ip igmp version (2-3)",
7730 "IGMP version number\n")
7732 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7733 struct pim_interface
*pim_ifp
= ifp
->info
;
7738 pim_ifp
->igmp_version
= IGMP_DEFAULT_VERSION
;
7743 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
7744 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
7746 DEFUN (interface_ip_igmp_query_max_response_time
,
7747 interface_ip_igmp_query_max_response_time_cmd
,
7748 "ip igmp query-max-response-time (10-250)",
7751 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
7752 "Query response value in deci-seconds\n")
7754 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7755 struct pim_interface
*pim_ifp
= ifp
->info
;
7756 int query_max_response_time
;
7760 ret
= pim_cmd_igmp_start(vty
, ifp
);
7761 if (ret
!= CMD_SUCCESS
)
7763 pim_ifp
= ifp
->info
;
7766 query_max_response_time
= atoi(argv
[3]->arg
);
7768 if (query_max_response_time
7769 >= pim_ifp
->igmp_default_query_interval
* 10) {
7771 "Can't set query max response time %d sec >= general query interval %d sec\n",
7772 query_max_response_time
,
7773 pim_ifp
->igmp_default_query_interval
);
7774 return CMD_WARNING_CONFIG_FAILED
;
7777 change_query_max_response_time(pim_ifp
, query_max_response_time
);
7782 DEFUN (interface_no_ip_igmp_query_max_response_time
,
7783 interface_no_ip_igmp_query_max_response_time_cmd
,
7784 "no ip igmp query-max-response-time (10-250)",
7788 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
7789 "Time for response in deci-seconds\n")
7791 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7792 struct pim_interface
*pim_ifp
= ifp
->info
;
7797 change_query_max_response_time(pim_ifp
,
7798 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
7803 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
7804 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
7806 DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec
,
7807 interface_ip_igmp_query_max_response_time_dsec_cmd
,
7808 "ip igmp query-max-response-time-dsec (10-250)",
7811 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
7812 "Query response value in deciseconds\n")
7814 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7815 struct pim_interface
*pim_ifp
= ifp
->info
;
7816 int query_max_response_time_dsec
;
7817 int default_query_interval_dsec
;
7821 ret
= pim_cmd_igmp_start(vty
, ifp
);
7822 if (ret
!= CMD_SUCCESS
)
7824 pim_ifp
= ifp
->info
;
7827 query_max_response_time_dsec
= atoi(argv
[4]->arg
);
7829 default_query_interval_dsec
= 10 * pim_ifp
->igmp_default_query_interval
;
7831 if (query_max_response_time_dsec
>= default_query_interval_dsec
) {
7833 "Can't set query max response time %d dsec >= general query interval %d dsec\n",
7834 query_max_response_time_dsec
,
7835 default_query_interval_dsec
);
7836 return CMD_WARNING_CONFIG_FAILED
;
7839 change_query_max_response_time(pim_ifp
, query_max_response_time_dsec
);
7844 DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec
,
7845 interface_no_ip_igmp_query_max_response_time_dsec_cmd
,
7846 "no ip igmp query-max-response-time-dsec",
7850 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
)
7852 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7853 struct pim_interface
*pim_ifp
= ifp
->info
;
7858 change_query_max_response_time(pim_ifp
,
7859 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
7864 #define IGMP_LAST_MEMBER_QUERY_COUNT_MIN (1)
7865 #define IGMP_LAST_MEMBER_QUERY_COUNT_MAX (7)
7867 DEFUN (interface_ip_igmp_last_member_query_count
,
7868 interface_ip_igmp_last_member_query_count_cmd
,
7869 "ip igmp last-member-query-count (1-7)",
7872 IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR
7873 "Last member query count\n")
7875 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7876 struct pim_interface
*pim_ifp
= ifp
->info
;
7877 int last_member_query_count
;
7881 ret
= pim_cmd_igmp_start(vty
, ifp
);
7882 if (ret
!= CMD_SUCCESS
)
7884 pim_ifp
= ifp
->info
;
7887 last_member_query_count
= atoi(argv
[3]->arg
);
7889 pim_ifp
->igmp_last_member_query_count
= last_member_query_count
;
7894 DEFUN (interface_no_ip_igmp_last_member_query_count
,
7895 interface_no_ip_igmp_last_member_query_count_cmd
,
7896 "no ip igmp last-member-query-count",
7900 IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR
)
7902 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7903 struct pim_interface
*pim_ifp
= ifp
->info
;
7908 pim_ifp
->igmp_last_member_query_count
=
7909 IGMP_DEFAULT_ROBUSTNESS_VARIABLE
;
7914 #define IGMP_LAST_MEMBER_QUERY_INTERVAL_MIN (1)
7915 #define IGMP_LAST_MEMBER_QUERY_INTERVAL_MAX (255)
7917 DEFUN (interface_ip_igmp_last_member_query_interval
,
7918 interface_ip_igmp_last_member_query_interval_cmd
,
7919 "ip igmp last-member-query-interval (1-255)",
7922 IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR
7923 "Last member query interval in deciseconds\n")
7925 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7926 struct pim_interface
*pim_ifp
= ifp
->info
;
7927 int last_member_query_interval
;
7931 ret
= pim_cmd_igmp_start(vty
, ifp
);
7932 if (ret
!= CMD_SUCCESS
)
7934 pim_ifp
= ifp
->info
;
7937 last_member_query_interval
= atoi(argv
[3]->arg
);
7938 pim_ifp
->igmp_specific_query_max_response_time_dsec
7939 = last_member_query_interval
;
7944 DEFUN (interface_no_ip_igmp_last_member_query_interval
,
7945 interface_no_ip_igmp_last_member_query_interval_cmd
,
7946 "no ip igmp last-member-query-interval",
7950 IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR
)
7952 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7953 struct pim_interface
*pim_ifp
= ifp
->info
;
7958 pim_ifp
->igmp_specific_query_max_response_time_dsec
=
7959 IGMP_SPECIFIC_QUERY_MAX_RESPONSE_TIME_DSEC
;
7964 DEFUN (interface_ip_pim_drprio
,
7965 interface_ip_pim_drprio_cmd
,
7966 "ip pim drpriority (1-4294967295)",
7969 "Set the Designated Router Election Priority\n"
7970 "Value of the new DR Priority\n")
7972 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7974 struct pim_interface
*pim_ifp
= ifp
->info
;
7975 uint32_t old_dr_prio
;
7978 vty_out(vty
, "Please enable PIM on interface, first\n");
7979 return CMD_WARNING_CONFIG_FAILED
;
7982 old_dr_prio
= pim_ifp
->pim_dr_priority
;
7984 pim_ifp
->pim_dr_priority
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
7986 if (old_dr_prio
!= pim_ifp
->pim_dr_priority
) {
7987 pim_if_dr_election(ifp
);
7988 pim_hello_restart_now(ifp
);
7994 DEFUN (interface_no_ip_pim_drprio
,
7995 interface_no_ip_pim_drprio_cmd
,
7996 "no ip pim drpriority [(1-4294967295)]",
8000 "Revert the Designated Router Priority to default\n"
8001 "Old Value of the Priority\n")
8003 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8004 struct pim_interface
*pim_ifp
= ifp
->info
;
8007 vty_out(vty
, "Pim not enabled on this interface\n");
8008 return CMD_WARNING_CONFIG_FAILED
;
8011 if (pim_ifp
->pim_dr_priority
!= PIM_DEFAULT_DR_PRIORITY
) {
8012 pim_ifp
->pim_dr_priority
= PIM_DEFAULT_DR_PRIORITY
;
8013 pim_if_dr_election(ifp
);
8014 pim_hello_restart_now(ifp
);
8020 DEFPY_HIDDEN (interface_ip_igmp_query_generate
,
8021 interface_ip_igmp_query_generate_cmd
,
8022 "ip igmp generate-query-once [version (2-3)]",
8025 "Generate igmp general query once\n"
8027 "IGMP version number\n")
8029 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8030 int igmp_version
= 2;
8033 vty_out(vty
, "IGMP/PIM is not enabled on the interface %s\n",
8035 return CMD_WARNING_CONFIG_FAILED
;
8039 igmp_version
= atoi(argv
[4]->arg
);
8041 igmp_send_query_on_intf(ifp
, igmp_version
);
8046 static int pim_cmd_interface_add(struct interface
*ifp
)
8048 struct pim_interface
*pim_ifp
= ifp
->info
;
8051 pim_ifp
= pim_if_new(ifp
, false, true, false, false);
8053 PIM_IF_DO_PIM(pim_ifp
->options
);
8055 pim_if_addr_add_all(ifp
);
8056 pim_if_membership_refresh(ifp
);
8058 pim_if_create_pimreg(pim_ifp
->pim
);
8062 DEFPY_HIDDEN (pim_test_sg_keepalive
,
8063 pim_test_sg_keepalive_cmd
,
8064 "test pim [vrf NAME$name] keepalive-reset A.B.C.D$source A.B.C.D$group",
8068 "Reset the Keepalive Timer\n"
8069 "The Source we are resetting\n"
8070 "The Group we are resetting\n")
8072 struct pim_upstream
*up
;
8073 struct pim_instance
*pim
;
8074 struct prefix_sg sg
;
8080 pim
= pim_get_pim_instance(VRF_DEFAULT
);
8082 struct vrf
*vrf
= vrf_lookup_by_name(name
);
8085 vty_out(vty
, "%% Vrf specified: %s does not exist\n",
8090 pim
= pim_get_pim_instance(vrf
->vrf_id
);
8094 vty_out(vty
, "%% Unable to find pim instance\n");
8098 up
= pim_upstream_find(pim
, &sg
);
8100 vty_out(vty
, "%% Unable to find %s specified\n",
8101 pim_str_sg_dump(&sg
));
8105 vty_out(vty
, "Setting %s to current keep alive time: %d\n",
8106 pim_str_sg_dump(&sg
), pim
->keep_alive_time
);
8107 pim_upstream_keep_alive_timer_start(up
, pim
->keep_alive_time
);
8112 DEFPY (interface_ip_pim_activeactive
,
8113 interface_ip_pim_activeactive_cmd
,
8114 "[no$no] ip pim active-active",
8118 "Mark interface as Active-Active for MLAG operations, Hidden because not finished yet\n")
8120 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8121 struct pim_interface
*pim_ifp
;
8123 if (!no
&& !pim_cmd_interface_add(ifp
)) {
8124 vty_out(vty
, "Could not enable PIM SM active-active on interface\n");
8125 return CMD_WARNING_CONFIG_FAILED
;
8130 zlog_debug("%sConfiguring PIM active-active on Interface: %s",
8131 no
? "Un-":" ", ifp
->name
);
8133 pim_ifp
= ifp
->info
;
8135 pim_if_unconfigure_mlag_dualactive(pim_ifp
);
8137 pim_if_configure_mlag_dualactive(pim_ifp
);
8142 DEFUN_HIDDEN (interface_ip_pim_ssm
,
8143 interface_ip_pim_ssm_cmd
,
8149 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8151 if (!pim_cmd_interface_add(ifp
)) {
8152 vty_out(vty
, "Could not enable PIM SM on interface\n");
8153 return CMD_WARNING_CONFIG_FAILED
;
8157 "WARN: Enabled PIM SM on interface; configure PIM SSM "
8158 "range if needed\n");
8162 static int interface_ip_pim_helper(struct vty
*vty
)
8164 struct pim_interface
*pim_ifp
;
8166 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8168 if (!pim_cmd_interface_add(ifp
)) {
8169 vty_out(vty
, "Could not enable PIM SM on interface\n");
8170 return CMD_WARNING_CONFIG_FAILED
;
8173 pim_ifp
= ifp
->info
;
8175 pim_if_create_pimreg(pim_ifp
->pim
);
8180 DEFUN_HIDDEN (interface_ip_pim_sm
,
8181 interface_ip_pim_sm_cmd
,
8187 return interface_ip_pim_helper(vty
);
8190 DEFUN (interface_ip_pim
,
8191 interface_ip_pim_cmd
,
8196 return interface_ip_pim_helper(vty
);
8199 static int pim_cmd_interface_delete(struct interface
*ifp
)
8201 struct pim_interface
*pim_ifp
= ifp
->info
;
8206 PIM_IF_DONT_PIM(pim_ifp
->options
);
8208 pim_if_membership_clear(ifp
);
8211 pim_sock_delete() removes all neighbors from
8212 pim_ifp->pim_neighbor_list.
8214 pim_sock_delete(ifp
, "pim unconfigured on interface");
8216 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
8217 pim_if_addr_del_all(ifp
);
8224 static int interface_no_ip_pim_helper(struct vty
*vty
)
8226 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8227 if (!pim_cmd_interface_delete(ifp
)) {
8228 vty_out(vty
, "Unable to delete interface information\n");
8229 return CMD_WARNING_CONFIG_FAILED
;
8235 DEFUN_HIDDEN (interface_no_ip_pim_ssm
,
8236 interface_no_ip_pim_ssm_cmd
,
8243 return interface_no_ip_pim_helper(vty
);
8246 DEFUN_HIDDEN (interface_no_ip_pim_sm
,
8247 interface_no_ip_pim_sm_cmd
,
8254 return interface_no_ip_pim_helper(vty
);
8257 DEFUN (interface_no_ip_pim
,
8258 interface_no_ip_pim_cmd
,
8264 return interface_no_ip_pim_helper(vty
);
8268 DEFUN(interface_ip_pim_boundary_oil
,
8269 interface_ip_pim_boundary_oil_cmd
,
8270 "ip multicast boundary oil WORD",
8272 "Generic multicast configuration options\n"
8273 "Define multicast boundary\n"
8274 "Filter OIL by group using prefix list\n"
8275 "Prefix list to filter OIL with\n")
8277 VTY_DECLVAR_CONTEXT(interface
, iif
);
8278 struct pim_interface
*pim_ifp
;
8281 argv_find(argv
, argc
, "WORD", &idx
);
8283 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
8285 if (pim_ifp
->boundary_oil_plist
)
8286 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
8288 pim_ifp
->boundary_oil_plist
=
8289 XSTRDUP(MTYPE_PIM_INTERFACE
, argv
[idx
]->arg
);
8291 /* Interface will be pruned from OIL on next Join */
8295 DEFUN(interface_no_ip_pim_boundary_oil
,
8296 interface_no_ip_pim_boundary_oil_cmd
,
8297 "no ip multicast boundary oil [WORD]",
8300 "Generic multicast configuration options\n"
8301 "Define multicast boundary\n"
8302 "Filter OIL by group using prefix list\n"
8303 "Prefix list to filter OIL with\n")
8305 VTY_DECLVAR_CONTEXT(interface
, iif
);
8306 struct pim_interface
*pim_ifp
;
8309 argv_find(argv
, argc
, "WORD", &idx
);
8311 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
8313 if (pim_ifp
->boundary_oil_plist
)
8314 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
8319 DEFUN (interface_ip_mroute
,
8320 interface_ip_mroute_cmd
,
8321 "ip mroute INTERFACE A.B.C.D [A.B.C.D]",
8323 "Add multicast route\n"
8324 "Outgoing interface name\n"
8328 VTY_DECLVAR_CONTEXT(interface
, iif
);
8329 struct pim_interface
*pim_ifp
;
8330 struct pim_instance
*pim
;
8331 int idx_interface
= 2;
8333 struct interface
*oif
;
8334 const char *oifname
;
8335 const char *grp_str
;
8336 struct in_addr grp_addr
;
8337 const char *src_str
;
8338 struct in_addr src_addr
;
8341 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
8344 oifname
= argv
[idx_interface
]->arg
;
8345 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
8347 vty_out(vty
, "No such interface name %s\n", oifname
);
8351 grp_str
= argv
[idx_ipv4
]->arg
;
8352 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
8354 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
8355 errno
, safe_strerror(errno
));
8359 if (argc
== (idx_ipv4
+ 1)) {
8360 src_addr
.s_addr
= INADDR_ANY
;
8363 src_str
= argv
[idx_ipv4
+ 1]->arg
;
8364 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
8366 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
8367 errno
, safe_strerror(errno
));
8372 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
8373 vty_out(vty
, "Failed to add static mroute\n");
8380 DEFUN (interface_no_ip_mroute
,
8381 interface_no_ip_mroute_cmd
,
8382 "no ip mroute INTERFACE A.B.C.D [A.B.C.D]",
8385 "Add multicast route\n"
8386 "Outgoing interface name\n"
8390 VTY_DECLVAR_CONTEXT(interface
, iif
);
8391 struct pim_interface
*pim_ifp
;
8392 struct pim_instance
*pim
;
8393 int idx_interface
= 3;
8395 struct interface
*oif
;
8396 const char *oifname
;
8397 const char *grp_str
;
8398 struct in_addr grp_addr
;
8399 const char *src_str
;
8400 struct in_addr src_addr
;
8403 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
8406 oifname
= argv
[idx_interface
]->arg
;
8407 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
8409 vty_out(vty
, "No such interface name %s\n", oifname
);
8413 grp_str
= argv
[idx_ipv4
]->arg
;
8414 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
8416 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
8417 errno
, safe_strerror(errno
));
8421 if (argc
== (idx_ipv4
+ 1)) {
8422 src_addr
.s_addr
= INADDR_ANY
;
8425 src_str
= argv
[idx_ipv4
+ 1]->arg
;
8426 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
8428 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
8429 errno
, safe_strerror(errno
));
8434 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
8435 vty_out(vty
, "Failed to remove static mroute\n");
8442 DEFUN (interface_ip_pim_hello
,
8443 interface_ip_pim_hello_cmd
,
8444 "ip pim hello (1-180) [(1-180)]",
8448 IFACE_PIM_HELLO_TIME_STR
8449 IFACE_PIM_HELLO_HOLD_STR
)
8451 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8454 struct pim_interface
*pim_ifp
= ifp
->info
;
8457 if (!pim_cmd_interface_add(ifp
)) {
8458 vty_out(vty
, "Could not enable PIM SM on interface\n");
8459 return CMD_WARNING_CONFIG_FAILED
;
8463 pim_ifp
= ifp
->info
;
8464 pim_ifp
->pim_hello_period
= strtol(argv
[idx_time
]->arg
, NULL
, 10);
8466 if (argc
== idx_hold
+ 1)
8467 pim_ifp
->pim_default_holdtime
=
8468 strtol(argv
[idx_hold
]->arg
, NULL
, 10);
8473 DEFUN (interface_no_ip_pim_hello
,
8474 interface_no_ip_pim_hello_cmd
,
8475 "no ip pim hello [(1-180) (1-180)]",
8480 IFACE_PIM_HELLO_TIME_STR
8481 IFACE_PIM_HELLO_HOLD_STR
)
8483 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8484 struct pim_interface
*pim_ifp
= ifp
->info
;
8487 vty_out(vty
, "Pim not enabled on this interface\n");
8488 return CMD_WARNING_CONFIG_FAILED
;
8491 pim_ifp
->pim_hello_period
= PIM_DEFAULT_HELLO_PERIOD
;
8492 pim_ifp
->pim_default_holdtime
= -1;
8503 PIM_DO_DEBUG_IGMP_EVENTS
;
8504 PIM_DO_DEBUG_IGMP_PACKETS
;
8505 PIM_DO_DEBUG_IGMP_TRACE
;
8509 DEFUN (no_debug_igmp
,
8516 PIM_DONT_DEBUG_IGMP_EVENTS
;
8517 PIM_DONT_DEBUG_IGMP_PACKETS
;
8518 PIM_DONT_DEBUG_IGMP_TRACE
;
8523 DEFUN (debug_igmp_events
,
8524 debug_igmp_events_cmd
,
8525 "debug igmp events",
8528 DEBUG_IGMP_EVENTS_STR
)
8530 PIM_DO_DEBUG_IGMP_EVENTS
;
8534 DEFUN (no_debug_igmp_events
,
8535 no_debug_igmp_events_cmd
,
8536 "no debug igmp events",
8540 DEBUG_IGMP_EVENTS_STR
)
8542 PIM_DONT_DEBUG_IGMP_EVENTS
;
8547 DEFUN (debug_igmp_packets
,
8548 debug_igmp_packets_cmd
,
8549 "debug igmp packets",
8552 DEBUG_IGMP_PACKETS_STR
)
8554 PIM_DO_DEBUG_IGMP_PACKETS
;
8558 DEFUN (no_debug_igmp_packets
,
8559 no_debug_igmp_packets_cmd
,
8560 "no debug igmp packets",
8564 DEBUG_IGMP_PACKETS_STR
)
8566 PIM_DONT_DEBUG_IGMP_PACKETS
;
8571 DEFUN (debug_igmp_trace
,
8572 debug_igmp_trace_cmd
,
8576 DEBUG_IGMP_TRACE_STR
)
8578 PIM_DO_DEBUG_IGMP_TRACE
;
8582 DEFUN (no_debug_igmp_trace
,
8583 no_debug_igmp_trace_cmd
,
8584 "no debug igmp trace",
8588 DEBUG_IGMP_TRACE_STR
)
8590 PIM_DONT_DEBUG_IGMP_TRACE
;
8595 DEFUN (debug_mroute
,
8601 PIM_DO_DEBUG_MROUTE
;
8605 DEFUN (debug_mroute_detail
,
8606 debug_mroute_detail_cmd
,
8607 "debug mroute detail",
8612 PIM_DO_DEBUG_MROUTE_DETAIL
;
8616 DEFUN (no_debug_mroute
,
8617 no_debug_mroute_cmd
,
8623 PIM_DONT_DEBUG_MROUTE
;
8627 DEFUN (no_debug_mroute_detail
,
8628 no_debug_mroute_detail_cmd
,
8629 "no debug mroute detail",
8635 PIM_DONT_DEBUG_MROUTE_DETAIL
;
8639 DEFUN (debug_pim_static
,
8640 debug_pim_static_cmd
,
8646 PIM_DO_DEBUG_STATIC
;
8650 DEFUN (no_debug_pim_static
,
8651 no_debug_pim_static_cmd
,
8652 "no debug pim static",
8658 PIM_DONT_DEBUG_STATIC
;
8669 PIM_DO_DEBUG_PIM_EVENTS
;
8670 PIM_DO_DEBUG_PIM_PACKETS
;
8671 PIM_DO_DEBUG_PIM_TRACE
;
8672 PIM_DO_DEBUG_MSDP_EVENTS
;
8673 PIM_DO_DEBUG_MSDP_PACKETS
;
8678 DEFUN (no_debug_pim
,
8685 PIM_DONT_DEBUG_PIM_EVENTS
;
8686 PIM_DONT_DEBUG_PIM_PACKETS
;
8687 PIM_DONT_DEBUG_PIM_TRACE
;
8688 PIM_DONT_DEBUG_MSDP_EVENTS
;
8689 PIM_DONT_DEBUG_MSDP_PACKETS
;
8691 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
8692 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
8698 DEFUN (debug_pim_nht
,
8703 "Nexthop Tracking\n")
8705 PIM_DO_DEBUG_PIM_NHT
;
8709 DEFUN (no_debug_pim_nht
,
8710 no_debug_pim_nht_cmd
,
8715 "Nexthop Tracking\n")
8717 PIM_DONT_DEBUG_PIM_NHT
;
8721 DEFUN (debug_pim_nht_rp
,
8722 debug_pim_nht_rp_cmd
,
8726 "Nexthop Tracking\n"
8727 "RP Nexthop Tracking\n")
8729 PIM_DO_DEBUG_PIM_NHT_RP
;
8733 DEFUN (no_debug_pim_nht_rp
,
8734 no_debug_pim_nht_rp_cmd
,
8735 "no debug pim nht rp",
8739 "Nexthop Tracking\n"
8740 "RP Nexthop Tracking\n")
8742 PIM_DONT_DEBUG_PIM_NHT_RP
;
8746 DEFUN (debug_pim_events
,
8747 debug_pim_events_cmd
,
8751 DEBUG_PIM_EVENTS_STR
)
8753 PIM_DO_DEBUG_PIM_EVENTS
;
8757 DEFUN (no_debug_pim_events
,
8758 no_debug_pim_events_cmd
,
8759 "no debug pim events",
8763 DEBUG_PIM_EVENTS_STR
)
8765 PIM_DONT_DEBUG_PIM_EVENTS
;
8769 DEFUN (debug_pim_packets
,
8770 debug_pim_packets_cmd
,
8771 "debug pim packets [<hello|joins|register>]",
8774 DEBUG_PIM_PACKETS_STR
8775 DEBUG_PIM_HELLO_PACKETS_STR
8776 DEBUG_PIM_J_P_PACKETS_STR
8777 DEBUG_PIM_PIM_REG_PACKETS_STR
)
8780 if (argv_find(argv
, argc
, "hello", &idx
)) {
8781 PIM_DO_DEBUG_PIM_HELLO
;
8782 vty_out(vty
, "PIM Hello debugging is on\n");
8783 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
8784 PIM_DO_DEBUG_PIM_J_P
;
8785 vty_out(vty
, "PIM Join/Prune debugging is on\n");
8786 } else if (argv_find(argv
, argc
, "register", &idx
)) {
8787 PIM_DO_DEBUG_PIM_REG
;
8788 vty_out(vty
, "PIM Register debugging is on\n");
8790 PIM_DO_DEBUG_PIM_PACKETS
;
8791 vty_out(vty
, "PIM Packet debugging is on \n");
8796 DEFUN (no_debug_pim_packets
,
8797 no_debug_pim_packets_cmd
,
8798 "no debug pim packets [<hello|joins|register>]",
8802 DEBUG_PIM_PACKETS_STR
8803 DEBUG_PIM_HELLO_PACKETS_STR
8804 DEBUG_PIM_J_P_PACKETS_STR
8805 DEBUG_PIM_PIM_REG_PACKETS_STR
)
8808 if (argv_find(argv
, argc
, "hello", &idx
)) {
8809 PIM_DONT_DEBUG_PIM_HELLO
;
8810 vty_out(vty
, "PIM Hello debugging is off \n");
8811 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
8812 PIM_DONT_DEBUG_PIM_J_P
;
8813 vty_out(vty
, "PIM Join/Prune debugging is off \n");
8814 } else if (argv_find(argv
, argc
, "register", &idx
)) {
8815 PIM_DONT_DEBUG_PIM_REG
;
8816 vty_out(vty
, "PIM Register debugging is off\n");
8818 PIM_DONT_DEBUG_PIM_PACKETS
;
8824 DEFUN (debug_pim_packetdump_send
,
8825 debug_pim_packetdump_send_cmd
,
8826 "debug pim packet-dump send",
8829 DEBUG_PIM_PACKETDUMP_STR
8830 DEBUG_PIM_PACKETDUMP_SEND_STR
)
8832 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND
;
8836 DEFUN (no_debug_pim_packetdump_send
,
8837 no_debug_pim_packetdump_send_cmd
,
8838 "no debug pim packet-dump send",
8842 DEBUG_PIM_PACKETDUMP_STR
8843 DEBUG_PIM_PACKETDUMP_SEND_STR
)
8845 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
8849 DEFUN (debug_pim_packetdump_recv
,
8850 debug_pim_packetdump_recv_cmd
,
8851 "debug pim packet-dump receive",
8854 DEBUG_PIM_PACKETDUMP_STR
8855 DEBUG_PIM_PACKETDUMP_RECV_STR
)
8857 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV
;
8861 DEFUN (no_debug_pim_packetdump_recv
,
8862 no_debug_pim_packetdump_recv_cmd
,
8863 "no debug pim packet-dump receive",
8867 DEBUG_PIM_PACKETDUMP_STR
8868 DEBUG_PIM_PACKETDUMP_RECV_STR
)
8870 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
8874 DEFUN (debug_pim_trace
,
8875 debug_pim_trace_cmd
,
8879 DEBUG_PIM_TRACE_STR
)
8881 PIM_DO_DEBUG_PIM_TRACE
;
8885 DEFUN (debug_pim_trace_detail
,
8886 debug_pim_trace_detail_cmd
,
8887 "debug pim trace detail",
8891 "Detailed Information\n")
8893 PIM_DO_DEBUG_PIM_TRACE_DETAIL
;
8897 DEFUN (no_debug_pim_trace
,
8898 no_debug_pim_trace_cmd
,
8899 "no debug pim trace",
8903 DEBUG_PIM_TRACE_STR
)
8905 PIM_DONT_DEBUG_PIM_TRACE
;
8909 DEFUN (no_debug_pim_trace_detail
,
8910 no_debug_pim_trace_detail_cmd
,
8911 "no debug pim trace detail",
8916 "Detailed Information\n")
8918 PIM_DONT_DEBUG_PIM_TRACE_DETAIL
;
8922 DEFUN (debug_ssmpingd
,
8928 PIM_DO_DEBUG_SSMPINGD
;
8932 DEFUN (no_debug_ssmpingd
,
8933 no_debug_ssmpingd_cmd
,
8934 "no debug ssmpingd",
8939 PIM_DONT_DEBUG_SSMPINGD
;
8943 DEFUN (debug_pim_zebra
,
8944 debug_pim_zebra_cmd
,
8948 DEBUG_PIM_ZEBRA_STR
)
8954 DEFUN (no_debug_pim_zebra
,
8955 no_debug_pim_zebra_cmd
,
8956 "no debug pim zebra",
8960 DEBUG_PIM_ZEBRA_STR
)
8962 PIM_DONT_DEBUG_ZEBRA
;
8966 DEFUN(debug_pim_mlag
, debug_pim_mlag_cmd
, "debug pim mlag",
8967 DEBUG_STR DEBUG_PIM_STR DEBUG_PIM_MLAG_STR
)
8973 DEFUN(no_debug_pim_mlag
, no_debug_pim_mlag_cmd
, "no debug pim mlag",
8974 NO_STR DEBUG_STR DEBUG_PIM_STR DEBUG_PIM_MLAG_STR
)
8976 PIM_DONT_DEBUG_MLAG
;
8980 DEFUN (debug_pim_vxlan
,
8981 debug_pim_vxlan_cmd
,
8985 DEBUG_PIM_VXLAN_STR
)
8991 DEFUN (no_debug_pim_vxlan
,
8992 no_debug_pim_vxlan_cmd
,
8993 "no debug pim vxlan",
8997 DEBUG_PIM_VXLAN_STR
)
8999 PIM_DONT_DEBUG_VXLAN
;
9009 PIM_DO_DEBUG_MSDP_EVENTS
;
9010 PIM_DO_DEBUG_MSDP_PACKETS
;
9014 DEFUN (no_debug_msdp
,
9021 PIM_DONT_DEBUG_MSDP_EVENTS
;
9022 PIM_DONT_DEBUG_MSDP_PACKETS
;
9026 DEFUN (debug_msdp_events
,
9027 debug_msdp_events_cmd
,
9028 "debug msdp events",
9031 DEBUG_MSDP_EVENTS_STR
)
9033 PIM_DO_DEBUG_MSDP_EVENTS
;
9037 DEFUN (no_debug_msdp_events
,
9038 no_debug_msdp_events_cmd
,
9039 "no debug msdp events",
9043 DEBUG_MSDP_EVENTS_STR
)
9045 PIM_DONT_DEBUG_MSDP_EVENTS
;
9049 DEFUN (debug_msdp_packets
,
9050 debug_msdp_packets_cmd
,
9051 "debug msdp packets",
9054 DEBUG_MSDP_PACKETS_STR
)
9056 PIM_DO_DEBUG_MSDP_PACKETS
;
9060 DEFUN (no_debug_msdp_packets
,
9061 no_debug_msdp_packets_cmd
,
9062 "no debug msdp packets",
9066 DEBUG_MSDP_PACKETS_STR
)
9068 PIM_DONT_DEBUG_MSDP_PACKETS
;
9072 DEFUN (debug_mtrace
,
9078 PIM_DO_DEBUG_MTRACE
;
9082 DEFUN (no_debug_mtrace
,
9083 no_debug_mtrace_cmd
,
9089 PIM_DONT_DEBUG_MTRACE
;
9104 DEFUN (no_debug_bsm
,
9117 DEFUN_NOSH (show_debugging_pim
,
9118 show_debugging_pim_cmd
,
9119 "show debugging [pim]",
9124 vty_out(vty
, "PIM debugging status\n");
9126 pim_debug_config_write(vty
);
9131 static int interface_pim_use_src_cmd_worker(struct vty
*vty
, const char *source
)
9134 struct in_addr source_addr
;
9135 int ret
= CMD_SUCCESS
;
9136 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9138 result
= inet_pton(AF_INET
, source
, &source_addr
);
9140 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", source
,
9141 errno
, safe_strerror(errno
));
9142 return CMD_WARNING_CONFIG_FAILED
;
9145 result
= pim_update_source_set(ifp
, source_addr
);
9149 case PIM_IFACE_NOT_FOUND
:
9150 ret
= CMD_WARNING_CONFIG_FAILED
;
9151 vty_out(vty
, "Pim not enabled on this interface\n");
9153 case PIM_UPDATE_SOURCE_DUP
:
9155 vty_out(vty
, "%% Source already set to %s\n", source
);
9158 ret
= CMD_WARNING_CONFIG_FAILED
;
9159 vty_out(vty
, "%% Source set failed\n");
9165 DEFUN (interface_pim_use_source
,
9166 interface_pim_use_source_cmd
,
9167 "ip pim use-source A.B.C.D",
9170 "Configure primary IP address\n"
9171 "source ip address\n")
9173 return interface_pim_use_src_cmd_worker(vty
, argv
[3]->arg
);
9176 DEFUN (interface_no_pim_use_source
,
9177 interface_no_pim_use_source_cmd
,
9178 "no ip pim use-source [A.B.C.D]",
9182 "Delete source IP address\n"
9183 "source ip address\n")
9185 return interface_pim_use_src_cmd_worker(vty
, "0.0.0.0");
9193 "Enables BFD support\n")
9195 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9196 struct pim_interface
*pim_ifp
= ifp
->info
;
9197 struct bfd_info
*bfd_info
= NULL
;
9200 if (!pim_cmd_interface_add(ifp
)) {
9201 vty_out(vty
, "Could not enable PIM SM on interface\n");
9205 pim_ifp
= ifp
->info
;
9207 bfd_info
= pim_ifp
->bfd_info
;
9209 if (!bfd_info
|| !CHECK_FLAG(bfd_info
->flags
, BFD_FLAG_PARAM_CFG
))
9210 pim_bfd_if_param_set(ifp
, BFD_DEF_MIN_RX
, BFD_DEF_MIN_TX
,
9211 BFD_DEF_DETECT_MULT
, 1);
9216 DEFUN (no_ip_pim_bfd
,
9222 "Disables BFD support\n")
9224 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9225 struct pim_interface
*pim_ifp
= ifp
->info
;
9228 vty_out(vty
, "Pim not enabled on this interface\n");
9232 if (pim_ifp
->bfd_info
) {
9233 pim_bfd_reg_dereg_all_nbr(ifp
, ZEBRA_BFD_DEST_DEREGISTER
);
9234 bfd_info_free(&(pim_ifp
->bfd_info
));
9245 "Enables BSM support on the interface\n")
9247 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9248 struct pim_interface
*pim_ifp
= ifp
->info
;
9251 if (!pim_cmd_interface_add(ifp
)) {
9252 vty_out(vty
, "Could not enable PIM SM on interface\n");
9257 pim_ifp
= ifp
->info
;
9258 pim_ifp
->bsm_enable
= true;
9263 DEFUN (no_ip_pim_bsm
,
9269 "Disables BSM support\n")
9271 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9272 struct pim_interface
*pim_ifp
= ifp
->info
;
9275 vty_out(vty
, "Pim not enabled on this interface\n");
9279 pim_ifp
->bsm_enable
= false;
9284 DEFUN (ip_pim_ucast_bsm
,
9285 ip_pim_ucast_bsm_cmd
,
9286 "ip pim unicast-bsm",
9289 "Accept/Send unicast BSM on the interface\n")
9291 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9292 struct pim_interface
*pim_ifp
= ifp
->info
;
9295 if (!pim_cmd_interface_add(ifp
)) {
9296 vty_out(vty
, "Could not enable PIM SM on interface\n");
9301 pim_ifp
= ifp
->info
;
9302 pim_ifp
->ucast_bsm_accept
= true;
9307 DEFUN (no_ip_pim_ucast_bsm
,
9308 no_ip_pim_ucast_bsm_cmd
,
9309 "no ip pim unicast-bsm",
9313 "Block send/receive unicast BSM on this interface\n")
9315 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9316 struct pim_interface
*pim_ifp
= ifp
->info
;
9319 vty_out(vty
, "Pim not enabled on this interface\n");
9323 pim_ifp
->ucast_bsm_accept
= false;
9331 ip_pim_bfd_param_cmd
,
9332 "ip pim bfd (2-255) (50-60000) (50-60000)",
9335 "Enables BFD support\n"
9336 "Detect Multiplier\n"
9337 "Required min receive interval\n"
9338 "Desired min transmit interval\n")
9342 ip_pim_bfd_param_cmd
,
9343 "ip pim bfd (2-255) (50-60000) (50-60000)",
9346 "Enables BFD support\n"
9347 "Detect Multiplier\n"
9348 "Required min receive interval\n"
9349 "Desired min transmit interval\n")
9350 #endif /* HAVE_BFDD */
9352 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9354 int idx_number_2
= 4;
9355 int idx_number_3
= 5;
9360 struct pim_interface
*pim_ifp
= ifp
->info
;
9363 if (!pim_cmd_interface_add(ifp
)) {
9364 vty_out(vty
, "Could not enable PIM SM on interface\n");
9369 if ((ret
= bfd_validate_param(
9370 vty
, argv
[idx_number
]->arg
, argv
[idx_number_2
]->arg
,
9371 argv
[idx_number_3
]->arg
, &dm_val
, &rx_val
, &tx_val
))
9375 pim_bfd_if_param_set(ifp
, rx_val
, tx_val
, dm_val
, 0);
9381 ALIAS(no_ip_pim_bfd
, no_ip_pim_bfd_param_cmd
,
9382 "no ip pim bfd (2-255) (50-60000) (50-60000)", NO_STR IP_STR PIM_STR
9383 "Enables BFD support\n"
9384 "Detect Multiplier\n"
9385 "Required min receive interval\n"
9386 "Desired min transmit interval\n")
9387 #endif /* !HAVE_BFDD */
9389 static int ip_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
9390 const char *peer
, const char *local
)
9392 enum pim_msdp_err result
;
9393 struct in_addr peer_addr
;
9394 struct in_addr local_addr
;
9395 int ret
= CMD_SUCCESS
;
9397 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
9399 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
9400 errno
, safe_strerror(errno
));
9401 return CMD_WARNING_CONFIG_FAILED
;
9404 result
= inet_pton(AF_INET
, local
, &local_addr
);
9406 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", local
,
9407 errno
, safe_strerror(errno
));
9408 return CMD_WARNING_CONFIG_FAILED
;
9411 result
= pim_msdp_peer_add(pim
, peer_addr
, local_addr
, "default",
9414 case PIM_MSDP_ERR_NONE
:
9416 case PIM_MSDP_ERR_OOM
:
9417 ret
= CMD_WARNING_CONFIG_FAILED
;
9418 vty_out(vty
, "%% Out of memory\n");
9420 case PIM_MSDP_ERR_PEER_EXISTS
:
9422 vty_out(vty
, "%% Peer exists\n");
9424 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
9425 ret
= CMD_WARNING_CONFIG_FAILED
;
9426 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
9429 ret
= CMD_WARNING_CONFIG_FAILED
;
9430 vty_out(vty
, "%% peer add failed\n");
9436 DEFUN_HIDDEN (ip_msdp_peer
,
9438 "ip msdp peer A.B.C.D source A.B.C.D",
9441 "Configure MSDP peer\n"
9443 "Source address for TCP connection\n"
9444 "local ip address\n")
9446 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9447 return ip_msdp_peer_cmd_worker(pim
, vty
, argv
[3]->arg
, argv
[5]->arg
);
9450 static int ip_no_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
9453 enum pim_msdp_err result
;
9454 struct in_addr peer_addr
;
9456 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
9458 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
9459 errno
, safe_strerror(errno
));
9460 return CMD_WARNING_CONFIG_FAILED
;
9463 result
= pim_msdp_peer_del(pim
, peer_addr
);
9465 case PIM_MSDP_ERR_NONE
:
9467 case PIM_MSDP_ERR_NO_PEER
:
9468 vty_out(vty
, "%% Peer does not exist\n");
9471 vty_out(vty
, "%% peer del failed\n");
9474 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9477 DEFUN_HIDDEN (no_ip_msdp_peer
,
9478 no_ip_msdp_peer_cmd
,
9479 "no ip msdp peer A.B.C.D",
9483 "Delete MSDP peer\n"
9484 "peer ip address\n")
9486 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9487 return ip_no_msdp_peer_cmd_worker(pim
, vty
, argv
[4]->arg
);
9490 static int ip_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
9491 struct vty
*vty
, const char *mg
,
9494 enum pim_msdp_err result
;
9495 struct in_addr mbr_ip
;
9496 int ret
= CMD_SUCCESS
;
9498 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
9500 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
9501 errno
, safe_strerror(errno
));
9502 return CMD_WARNING_CONFIG_FAILED
;
9505 result
= pim_msdp_mg_mbr_add(pim
, mg
, mbr_ip
);
9507 case PIM_MSDP_ERR_NONE
:
9509 case PIM_MSDP_ERR_OOM
:
9510 ret
= CMD_WARNING_CONFIG_FAILED
;
9511 vty_out(vty
, "%% Out of memory\n");
9513 case PIM_MSDP_ERR_MG_MBR_EXISTS
:
9515 vty_out(vty
, "%% mesh-group member exists\n");
9517 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
9518 ret
= CMD_WARNING_CONFIG_FAILED
;
9519 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
9522 ret
= CMD_WARNING_CONFIG_FAILED
;
9523 vty_out(vty
, "%% member add failed\n");
9529 DEFUN (ip_msdp_mesh_group_member
,
9530 ip_msdp_mesh_group_member_cmd
,
9531 "ip msdp mesh-group WORD member A.B.C.D",
9534 "Configure MSDP mesh-group\n"
9536 "mesh group member\n"
9537 "peer ip address\n")
9539 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9540 return ip_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[3]->arg
,
9544 static int ip_no_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
9549 enum pim_msdp_err result
;
9550 struct in_addr mbr_ip
;
9552 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
9554 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
9555 errno
, safe_strerror(errno
));
9556 return CMD_WARNING_CONFIG_FAILED
;
9559 result
= pim_msdp_mg_mbr_del(pim
, mg
, mbr_ip
);
9561 case PIM_MSDP_ERR_NONE
:
9563 case PIM_MSDP_ERR_NO_MG
:
9564 vty_out(vty
, "%% mesh-group does not exist\n");
9566 case PIM_MSDP_ERR_NO_MG_MBR
:
9567 vty_out(vty
, "%% mesh-group member does not exist\n");
9570 vty_out(vty
, "%% mesh-group member del failed\n");
9573 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9575 DEFUN (no_ip_msdp_mesh_group_member
,
9576 no_ip_msdp_mesh_group_member_cmd
,
9577 "no ip msdp mesh-group WORD member A.B.C.D",
9581 "Delete MSDP mesh-group member\n"
9583 "mesh group member\n"
9584 "peer ip address\n")
9586 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9587 return ip_no_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[4]->arg
,
9591 static int ip_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
9592 struct vty
*vty
, const char *mg
,
9595 enum pim_msdp_err result
;
9596 struct in_addr src_ip
;
9598 result
= inet_pton(AF_INET
, src
, &src_ip
);
9600 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", src
,
9601 errno
, safe_strerror(errno
));
9602 return CMD_WARNING_CONFIG_FAILED
;
9605 result
= pim_msdp_mg_src_add(pim
, mg
, src_ip
);
9607 case PIM_MSDP_ERR_NONE
:
9609 case PIM_MSDP_ERR_OOM
:
9610 vty_out(vty
, "%% Out of memory\n");
9612 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
9613 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
9616 vty_out(vty
, "%% source add failed\n");
9619 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9623 DEFUN (ip_msdp_mesh_group_source
,
9624 ip_msdp_mesh_group_source_cmd
,
9625 "ip msdp mesh-group WORD source A.B.C.D",
9628 "Configure MSDP mesh-group\n"
9630 "mesh group local address\n"
9631 "source ip address for the TCP connection\n")
9633 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9634 return ip_msdp_mesh_group_source_cmd_worker(pim
, vty
, argv
[3]->arg
,
9638 static int ip_no_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
9642 enum pim_msdp_err result
;
9644 result
= pim_msdp_mg_src_del(pim
, mg
);
9646 case PIM_MSDP_ERR_NONE
:
9648 case PIM_MSDP_ERR_NO_MG
:
9649 vty_out(vty
, "%% mesh-group does not exist\n");
9652 vty_out(vty
, "%% mesh-group source del failed\n");
9655 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9658 static int ip_no_msdp_mesh_group_cmd_worker(struct pim_instance
*pim
,
9659 struct vty
*vty
, const char *mg
)
9661 enum pim_msdp_err result
;
9663 result
= pim_msdp_mg_del(pim
, mg
);
9665 case PIM_MSDP_ERR_NONE
:
9667 case PIM_MSDP_ERR_NO_MG
:
9668 vty_out(vty
, "%% mesh-group does not exist\n");
9671 vty_out(vty
, "%% mesh-group source del failed\n");
9674 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9677 DEFUN (no_ip_msdp_mesh_group_source
,
9678 no_ip_msdp_mesh_group_source_cmd
,
9679 "no ip msdp mesh-group WORD source [A.B.C.D]",
9683 "Delete MSDP mesh-group source\n"
9685 "mesh group source\n"
9686 "mesh group local address\n")
9688 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9690 return ip_no_msdp_mesh_group_cmd_worker(pim
, vty
, argv
[6]->arg
);
9692 return ip_no_msdp_mesh_group_source_cmd_worker(pim
, vty
,
9696 static void print_empty_json_obj(struct vty
*vty
)
9699 json
= json_object_new_object();
9700 vty_out(vty
, "%s\n",
9701 json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
));
9702 json_object_free(json
);
9705 static void ip_msdp_show_mesh_group(struct pim_instance
*pim
, struct vty
*vty
,
9708 struct listnode
*mbrnode
;
9709 struct pim_msdp_mg_mbr
*mbr
;
9710 struct pim_msdp_mg
*mg
= pim
->msdp
.mg
;
9711 char mbr_str
[INET_ADDRSTRLEN
];
9712 char src_str
[INET_ADDRSTRLEN
];
9713 char state_str
[PIM_MSDP_STATE_STRLEN
];
9714 enum pim_msdp_peer_state state
;
9715 json_object
*json
= NULL
;
9716 json_object
*json_mg_row
= NULL
;
9717 json_object
*json_members
= NULL
;
9718 json_object
*json_row
= NULL
;
9722 print_empty_json_obj(vty
);
9726 pim_inet4_dump("<source?>", mg
->src_ip
, src_str
, sizeof(src_str
));
9728 json
= json_object_new_object();
9729 /* currently there is only one mesh group but we should still
9731 * it a dict with mg-name as key */
9732 json_mg_row
= json_object_new_object();
9733 json_object_string_add(json_mg_row
, "name",
9734 mg
->mesh_group_name
);
9735 json_object_string_add(json_mg_row
, "source", src_str
);
9737 vty_out(vty
, "Mesh group : %s\n", mg
->mesh_group_name
);
9738 vty_out(vty
, " Source : %s\n", src_str
);
9739 vty_out(vty
, " Member State\n");
9742 for (ALL_LIST_ELEMENTS_RO(mg
->mbr_list
, mbrnode
, mbr
)) {
9743 pim_inet4_dump("<mbr?>", mbr
->mbr_ip
, mbr_str
, sizeof(mbr_str
));
9745 state
= mbr
->mp
->state
;
9747 state
= PIM_MSDP_DISABLED
;
9749 pim_msdp_state_dump(state
, state_str
, sizeof(state_str
));
9751 json_row
= json_object_new_object();
9752 json_object_string_add(json_row
, "member", mbr_str
);
9753 json_object_string_add(json_row
, "state", state_str
);
9754 if (!json_members
) {
9755 json_members
= json_object_new_object();
9756 json_object_object_add(json_mg_row
, "members",
9759 json_object_object_add(json_members
, mbr_str
, json_row
);
9761 vty_out(vty
, " %-15s %11s\n", mbr_str
, state_str
);
9766 json_object_object_add(json
, mg
->mesh_group_name
, json_mg_row
);
9767 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9768 json
, JSON_C_TO_STRING_PRETTY
));
9769 json_object_free(json
);
9773 DEFUN (show_ip_msdp_mesh_group
,
9774 show_ip_msdp_mesh_group_cmd
,
9775 "show ip msdp [vrf NAME] mesh-group [json]",
9780 "MSDP mesh-group information\n"
9783 bool uj
= use_json(argc
, argv
);
9785 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
9790 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
9795 DEFUN (show_ip_msdp_mesh_group_vrf_all
,
9796 show_ip_msdp_mesh_group_vrf_all_cmd
,
9797 "show ip msdp vrf all mesh-group [json]",
9802 "MSDP mesh-group information\n"
9805 bool uj
= use_json(argc
, argv
);
9811 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
9815 vty_out(vty
, " \"%s\": ", vrf
->name
);
9818 vty_out(vty
, "VRF: %s\n", vrf
->name
);
9819 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
9822 vty_out(vty
, "}\n");
9827 static void ip_msdp_show_peers(struct pim_instance
*pim
, struct vty
*vty
,
9830 struct listnode
*mpnode
;
9831 struct pim_msdp_peer
*mp
;
9832 char peer_str
[INET_ADDRSTRLEN
];
9833 char local_str
[INET_ADDRSTRLEN
];
9834 char state_str
[PIM_MSDP_STATE_STRLEN
];
9835 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
9837 json_object
*json
= NULL
;
9838 json_object
*json_row
= NULL
;
9842 json
= json_object_new_object();
9845 "Peer Local State Uptime SaCnt\n");
9848 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
9849 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
9850 now
= pim_time_monotonic_sec();
9851 pim_time_uptime(timebuf
, sizeof(timebuf
),
9854 strlcpy(timebuf
, "-", sizeof(timebuf
));
9856 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
9857 pim_inet4_dump("<local?>", mp
->local
, local_str
,
9859 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
9861 json_row
= json_object_new_object();
9862 json_object_string_add(json_row
, "peer", peer_str
);
9863 json_object_string_add(json_row
, "local", local_str
);
9864 json_object_string_add(json_row
, "state", state_str
);
9865 json_object_string_add(json_row
, "upTime", timebuf
);
9866 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
9867 json_object_object_add(json
, peer_str
, json_row
);
9869 vty_out(vty
, "%-15s %15s %11s %8s %6d\n", peer_str
,
9870 local_str
, state_str
, timebuf
, mp
->sa_cnt
);
9875 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9876 json
, JSON_C_TO_STRING_PRETTY
));
9877 json_object_free(json
);
9881 static void ip_msdp_show_peers_detail(struct pim_instance
*pim
, struct vty
*vty
,
9882 const char *peer
, bool uj
)
9884 struct listnode
*mpnode
;
9885 struct pim_msdp_peer
*mp
;
9886 char peer_str
[INET_ADDRSTRLEN
];
9887 char local_str
[INET_ADDRSTRLEN
];
9888 char state_str
[PIM_MSDP_STATE_STRLEN
];
9889 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
9890 char katimer
[PIM_MSDP_TIMER_STRLEN
];
9891 char crtimer
[PIM_MSDP_TIMER_STRLEN
];
9892 char holdtimer
[PIM_MSDP_TIMER_STRLEN
];
9894 json_object
*json
= NULL
;
9895 json_object
*json_row
= NULL
;
9898 json
= json_object_new_object();
9901 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
9902 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
9903 if (strcmp(peer
, "detail") && strcmp(peer
, peer_str
))
9906 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
9907 now
= pim_time_monotonic_sec();
9908 pim_time_uptime(timebuf
, sizeof(timebuf
),
9911 strlcpy(timebuf
, "-", sizeof(timebuf
));
9913 pim_inet4_dump("<local?>", mp
->local
, local_str
,
9915 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
9916 pim_time_timer_to_hhmmss(katimer
, sizeof(katimer
),
9918 pim_time_timer_to_hhmmss(crtimer
, sizeof(crtimer
),
9920 pim_time_timer_to_hhmmss(holdtimer
, sizeof(holdtimer
),
9924 json_row
= json_object_new_object();
9925 json_object_string_add(json_row
, "peer", peer_str
);
9926 json_object_string_add(json_row
, "local", local_str
);
9927 json_object_string_add(json_row
, "meshGroupName",
9928 mp
->mesh_group_name
);
9929 json_object_string_add(json_row
, "state", state_str
);
9930 json_object_string_add(json_row
, "upTime", timebuf
);
9931 json_object_string_add(json_row
, "keepAliveTimer",
9933 json_object_string_add(json_row
, "connRetryTimer",
9935 json_object_string_add(json_row
, "holdTimer",
9937 json_object_string_add(json_row
, "lastReset",
9939 json_object_int_add(json_row
, "connAttempts",
9941 json_object_int_add(json_row
, "establishedChanges",
9943 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
9944 json_object_int_add(json_row
, "kaSent", mp
->ka_tx_cnt
);
9945 json_object_int_add(json_row
, "kaRcvd", mp
->ka_rx_cnt
);
9946 json_object_int_add(json_row
, "saSent", mp
->sa_tx_cnt
);
9947 json_object_int_add(json_row
, "saRcvd", mp
->sa_rx_cnt
);
9948 json_object_object_add(json
, peer_str
, json_row
);
9950 vty_out(vty
, "Peer : %s\n", peer_str
);
9951 vty_out(vty
, " Local : %s\n", local_str
);
9952 vty_out(vty
, " Mesh Group : %s\n",
9953 mp
->mesh_group_name
);
9954 vty_out(vty
, " State : %s\n", state_str
);
9955 vty_out(vty
, " Uptime : %s\n", timebuf
);
9957 vty_out(vty
, " Keepalive Timer : %s\n", katimer
);
9958 vty_out(vty
, " Conn Retry Timer : %s\n", crtimer
);
9959 vty_out(vty
, " Hold Timer : %s\n", holdtimer
);
9960 vty_out(vty
, " Last Reset : %s\n",
9962 vty_out(vty
, " Conn Attempts : %d\n",
9964 vty_out(vty
, " Established Changes : %d\n",
9966 vty_out(vty
, " SA Count : %d\n",
9968 vty_out(vty
, " Statistics :\n");
9971 vty_out(vty
, " Keepalives : %10d %10d\n",
9972 mp
->ka_tx_cnt
, mp
->ka_rx_cnt
);
9973 vty_out(vty
, " SAs : %10d %10d\n",
9974 mp
->sa_tx_cnt
, mp
->sa_rx_cnt
);
9980 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9981 json
, JSON_C_TO_STRING_PRETTY
));
9982 json_object_free(json
);
9986 DEFUN (show_ip_msdp_peer_detail
,
9987 show_ip_msdp_peer_detail_cmd
,
9988 "show ip msdp [vrf NAME] peer [detail|A.B.C.D] [json]",
9993 "MSDP peer information\n"
9998 bool uj
= use_json(argc
, argv
);
10000 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10003 return CMD_WARNING
;
10007 if (argv_find(argv
, argc
, "detail", &idx
))
10008 arg
= argv
[idx
]->text
;
10009 else if (argv_find(argv
, argc
, "A.B.C.D", &idx
))
10010 arg
= argv
[idx
]->arg
;
10013 ip_msdp_show_peers_detail(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
10015 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
10017 return CMD_SUCCESS
;
10020 DEFUN (show_ip_msdp_peer_detail_vrf_all
,
10021 show_ip_msdp_peer_detail_vrf_all_cmd
,
10022 "show ip msdp vrf all peer [detail|A.B.C.D] [json]",
10027 "MSDP peer information\n"
10028 "Detailed output\n"
10029 "peer ip address\n"
10033 bool uj
= use_json(argc
, argv
);
10038 vty_out(vty
, "{ ");
10039 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
10042 vty_out(vty
, ", ");
10043 vty_out(vty
, " \"%s\": ", vrf
->name
);
10046 vty_out(vty
, "VRF: %s\n", vrf
->name
);
10047 if (argv_find(argv
, argc
, "detail", &idx
)
10048 || argv_find(argv
, argc
, "A.B.C.D", &idx
))
10049 ip_msdp_show_peers_detail(vrf
->info
, vty
,
10050 argv
[idx
]->arg
, uj
);
10052 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
10055 vty_out(vty
, "}\n");
10057 return CMD_SUCCESS
;
10060 static void ip_msdp_show_sa(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
10062 struct listnode
*sanode
;
10063 struct pim_msdp_sa
*sa
;
10064 char src_str
[INET_ADDRSTRLEN
];
10065 char grp_str
[INET_ADDRSTRLEN
];
10066 char rp_str
[INET_ADDRSTRLEN
];
10067 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
10071 json_object
*json
= NULL
;
10072 json_object
*json_group
= NULL
;
10073 json_object
*json_row
= NULL
;
10076 json
= json_object_new_object();
10079 "Source Group RP Local SPT Uptime\n");
10082 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
10083 now
= pim_time_monotonic_sec();
10084 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
10085 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
10086 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
10087 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
10088 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
10090 strlcpy(spt_str
, "yes", sizeof(spt_str
));
10092 strlcpy(spt_str
, "no", sizeof(spt_str
));
10095 strlcpy(rp_str
, "-", sizeof(rp_str
));
10096 strlcpy(spt_str
, "-", sizeof(spt_str
));
10098 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
10099 strlcpy(local_str
, "yes", sizeof(local_str
));
10101 strlcpy(local_str
, "no", sizeof(local_str
));
10104 json_object_object_get_ex(json
, grp_str
, &json_group
);
10107 json_group
= json_object_new_object();
10108 json_object_object_add(json
, grp_str
,
10112 json_row
= json_object_new_object();
10113 json_object_string_add(json_row
, "source", src_str
);
10114 json_object_string_add(json_row
, "group", grp_str
);
10115 json_object_string_add(json_row
, "rp", rp_str
);
10116 json_object_string_add(json_row
, "local", local_str
);
10117 json_object_string_add(json_row
, "sptSetup", spt_str
);
10118 json_object_string_add(json_row
, "upTime", timebuf
);
10119 json_object_object_add(json_group
, src_str
, json_row
);
10121 vty_out(vty
, "%-15s %15s %15s %5c %3c %8s\n",
10122 src_str
, grp_str
, rp_str
, local_str
[0],
10123 spt_str
[0], timebuf
);
10128 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10129 json
, JSON_C_TO_STRING_PRETTY
));
10130 json_object_free(json
);
10134 static void ip_msdp_show_sa_entry_detail(struct pim_msdp_sa
*sa
,
10135 const char *src_str
,
10136 const char *grp_str
, struct vty
*vty
,
10137 bool uj
, json_object
*json
)
10139 char rp_str
[INET_ADDRSTRLEN
];
10140 char peer_str
[INET_ADDRSTRLEN
];
10141 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
10144 char statetimer
[PIM_MSDP_TIMER_STRLEN
];
10146 json_object
*json_group
= NULL
;
10147 json_object
*json_row
= NULL
;
10149 now
= pim_time_monotonic_sec();
10150 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
10151 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
10152 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
10153 pim_inet4_dump("<peer?>", sa
->peer
, peer_str
, sizeof(peer_str
));
10155 strlcpy(spt_str
, "yes", sizeof(spt_str
));
10157 strlcpy(spt_str
, "no", sizeof(spt_str
));
10160 strlcpy(rp_str
, "-", sizeof(rp_str
));
10161 strlcpy(peer_str
, "-", sizeof(peer_str
));
10162 strlcpy(spt_str
, "-", sizeof(spt_str
));
10164 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
10165 strlcpy(local_str
, "yes", sizeof(local_str
));
10167 strlcpy(local_str
, "no", sizeof(local_str
));
10169 pim_time_timer_to_hhmmss(statetimer
, sizeof(statetimer
),
10170 sa
->sa_state_timer
);
10172 json_object_object_get_ex(json
, grp_str
, &json_group
);
10175 json_group
= json_object_new_object();
10176 json_object_object_add(json
, grp_str
, json_group
);
10179 json_row
= json_object_new_object();
10180 json_object_string_add(json_row
, "source", src_str
);
10181 json_object_string_add(json_row
, "group", grp_str
);
10182 json_object_string_add(json_row
, "rp", rp_str
);
10183 json_object_string_add(json_row
, "local", local_str
);
10184 json_object_string_add(json_row
, "sptSetup", spt_str
);
10185 json_object_string_add(json_row
, "upTime", timebuf
);
10186 json_object_string_add(json_row
, "stateTimer", statetimer
);
10187 json_object_object_add(json_group
, src_str
, json_row
);
10189 vty_out(vty
, "SA : %s\n", sa
->sg_str
);
10190 vty_out(vty
, " RP : %s\n", rp_str
);
10191 vty_out(vty
, " Peer : %s\n", peer_str
);
10192 vty_out(vty
, " Local : %s\n", local_str
);
10193 vty_out(vty
, " SPT Setup : %s\n", spt_str
);
10194 vty_out(vty
, " Uptime : %s\n", timebuf
);
10195 vty_out(vty
, " State Timer : %s\n", statetimer
);
10196 vty_out(vty
, "\n");
10200 static void ip_msdp_show_sa_detail(struct pim_instance
*pim
, struct vty
*vty
,
10203 struct listnode
*sanode
;
10204 struct pim_msdp_sa
*sa
;
10205 char src_str
[INET_ADDRSTRLEN
];
10206 char grp_str
[INET_ADDRSTRLEN
];
10207 json_object
*json
= NULL
;
10210 json
= json_object_new_object();
10213 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
10214 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
10215 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
10216 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
, uj
,
10221 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10222 json
, JSON_C_TO_STRING_PRETTY
));
10223 json_object_free(json
);
10227 DEFUN (show_ip_msdp_sa_detail
,
10228 show_ip_msdp_sa_detail_cmd
,
10229 "show ip msdp [vrf NAME] sa detail [json]",
10234 "MSDP active-source information\n"
10235 "Detailed output\n"
10238 bool uj
= use_json(argc
, argv
);
10240 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10243 return CMD_WARNING
;
10245 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
10247 return CMD_SUCCESS
;
10250 DEFUN (show_ip_msdp_sa_detail_vrf_all
,
10251 show_ip_msdp_sa_detail_vrf_all_cmd
,
10252 "show ip msdp vrf all sa detail [json]",
10257 "MSDP active-source information\n"
10258 "Detailed output\n"
10261 bool uj
= use_json(argc
, argv
);
10266 vty_out(vty
, "{ ");
10267 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
10270 vty_out(vty
, ", ");
10271 vty_out(vty
, " \"%s\": ", vrf
->name
);
10274 vty_out(vty
, "VRF: %s\n", vrf
->name
);
10275 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
10278 vty_out(vty
, "}\n");
10280 return CMD_SUCCESS
;
10283 static void ip_msdp_show_sa_addr(struct pim_instance
*pim
, struct vty
*vty
,
10284 const char *addr
, bool uj
)
10286 struct listnode
*sanode
;
10287 struct pim_msdp_sa
*sa
;
10288 char src_str
[INET_ADDRSTRLEN
];
10289 char grp_str
[INET_ADDRSTRLEN
];
10290 json_object
*json
= NULL
;
10293 json
= json_object_new_object();
10296 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
10297 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
10298 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
10299 if (!strcmp(addr
, src_str
) || !strcmp(addr
, grp_str
)) {
10300 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
10306 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10307 json
, JSON_C_TO_STRING_PRETTY
));
10308 json_object_free(json
);
10312 static void ip_msdp_show_sa_sg(struct pim_instance
*pim
, struct vty
*vty
,
10313 const char *src
, const char *grp
, bool uj
)
10315 struct listnode
*sanode
;
10316 struct pim_msdp_sa
*sa
;
10317 char src_str
[INET_ADDRSTRLEN
];
10318 char grp_str
[INET_ADDRSTRLEN
];
10319 json_object
*json
= NULL
;
10322 json
= json_object_new_object();
10325 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
10326 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
10327 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
10328 if (!strcmp(src
, src_str
) && !strcmp(grp
, grp_str
)) {
10329 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
10335 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10336 json
, JSON_C_TO_STRING_PRETTY
));
10337 json_object_free(json
);
10341 DEFUN (show_ip_msdp_sa_sg
,
10342 show_ip_msdp_sa_sg_cmd
,
10343 "show ip msdp [vrf NAME] sa [A.B.C.D [A.B.C.D]] [json]",
10348 "MSDP active-source information\n"
10349 "source or group ip\n"
10353 bool uj
= use_json(argc
, argv
);
10357 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10360 return CMD_WARNING
;
10362 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
10364 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
10368 if (src_ip
&& grp_ip
)
10369 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
10371 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
10373 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
10375 return CMD_SUCCESS
;
10378 DEFUN (show_ip_msdp_sa_sg_vrf_all
,
10379 show_ip_msdp_sa_sg_vrf_all_cmd
,
10380 "show ip msdp vrf all sa [A.B.C.D [A.B.C.D]] [json]",
10385 "MSDP active-source information\n"
10386 "source or group ip\n"
10390 bool uj
= use_json(argc
, argv
);
10395 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
10397 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
10402 vty_out(vty
, "{ ");
10403 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
10406 vty_out(vty
, ", ");
10407 vty_out(vty
, " \"%s\": ", vrf
->name
);
10410 vty_out(vty
, "VRF: %s\n", vrf
->name
);
10412 if (src_ip
&& grp_ip
)
10413 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
10415 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
10417 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
10420 vty_out(vty
, "}\n");
10422 return CMD_SUCCESS
;
10425 struct pim_sg_cache_walk_data
{
10428 json_object
*json_group
;
10429 struct in_addr addr
;
10433 static void pim_show_vxlan_sg_entry(struct pim_vxlan_sg
*vxlan_sg
,
10434 struct pim_sg_cache_walk_data
*cwd
)
10436 struct vty
*vty
= cwd
->vty
;
10437 json_object
*json
= cwd
->json
;
10438 char src_str
[INET_ADDRSTRLEN
];
10439 char grp_str
[INET_ADDRSTRLEN
];
10440 json_object
*json_row
;
10441 bool installed
= (vxlan_sg
->up
) ? true : false;
10442 const char *iif_name
= vxlan_sg
->iif
?vxlan_sg
->iif
->name
:"-";
10443 const char *oif_name
;
10445 if (pim_vxlan_is_orig_mroute(vxlan_sg
))
10446 oif_name
= vxlan_sg
->orig_oif
?vxlan_sg
->orig_oif
->name
:"";
10448 oif_name
= vxlan_sg
->term_oif
?vxlan_sg
->term_oif
->name
:"";
10450 if (cwd
->addr_match
&& (vxlan_sg
->sg
.src
.s_addr
!= cwd
->addr
.s_addr
) &&
10451 (vxlan_sg
->sg
.grp
.s_addr
!= cwd
->addr
.s_addr
)) {
10454 pim_inet4_dump("<src?>", vxlan_sg
->sg
.src
, src_str
, sizeof(src_str
));
10455 pim_inet4_dump("<grp?>", vxlan_sg
->sg
.grp
, grp_str
, sizeof(grp_str
));
10457 json_object_object_get_ex(json
, grp_str
, &cwd
->json_group
);
10459 if (!cwd
->json_group
) {
10460 cwd
->json_group
= json_object_new_object();
10461 json_object_object_add(json
, grp_str
,
10465 json_row
= json_object_new_object();
10466 json_object_string_add(json_row
, "source", src_str
);
10467 json_object_string_add(json_row
, "group", grp_str
);
10468 json_object_string_add(json_row
, "input", iif_name
);
10469 json_object_string_add(json_row
, "output", oif_name
);
10471 json_object_boolean_true_add(json_row
, "installed");
10473 json_object_boolean_false_add(json_row
, "installed");
10474 json_object_object_add(cwd
->json_group
, src_str
, json_row
);
10476 vty_out(vty
, "%-15s %-15s %-15s %-15s %-5s\n",
10477 src_str
, grp_str
, iif_name
, oif_name
,
10482 static void pim_show_vxlan_sg_hash_entry(struct hash_bucket
*backet
, void *arg
)
10484 pim_show_vxlan_sg_entry((struct pim_vxlan_sg
*)backet
->data
,
10485 (struct pim_sg_cache_walk_data
*)arg
);
10488 static void pim_show_vxlan_sg(struct pim_instance
*pim
,
10489 struct vty
*vty
, bool uj
)
10491 json_object
*json
= NULL
;
10492 struct pim_sg_cache_walk_data cwd
;
10495 json
= json_object_new_object();
10497 vty_out(vty
, "Codes: I -> installed\n");
10499 "Source Group Input Output Flags\n");
10502 memset(&cwd
, 0, sizeof(cwd
));
10505 hash_iterate(pim
->vxlan
.sg_hash
, pim_show_vxlan_sg_hash_entry
, &cwd
);
10508 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10509 json
, JSON_C_TO_STRING_PRETTY
));
10510 json_object_free(json
);
10514 static void pim_show_vxlan_sg_match_addr(struct pim_instance
*pim
,
10515 struct vty
*vty
, char *addr_str
, bool uj
)
10517 json_object
*json
= NULL
;
10518 struct pim_sg_cache_walk_data cwd
;
10521 memset(&cwd
, 0, sizeof(cwd
));
10522 result
= inet_pton(AF_INET
, addr_str
, &cwd
.addr
);
10524 vty_out(vty
, "Bad address %s: errno=%d: %s\n", addr_str
,
10525 errno
, safe_strerror(errno
));
10530 json
= json_object_new_object();
10532 vty_out(vty
, "Codes: I -> installed\n");
10534 "Source Group Input Output Flags\n");
10539 cwd
.addr_match
= true;
10540 hash_iterate(pim
->vxlan
.sg_hash
, pim_show_vxlan_sg_hash_entry
, &cwd
);
10543 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10544 json
, JSON_C_TO_STRING_PRETTY
));
10545 json_object_free(json
);
10549 static void pim_show_vxlan_sg_one(struct pim_instance
*pim
,
10550 struct vty
*vty
, char *src_str
, char *grp_str
, bool uj
)
10552 json_object
*json
= NULL
;
10553 struct prefix_sg sg
;
10555 struct pim_vxlan_sg
*vxlan_sg
;
10556 const char *iif_name
;
10558 const char *oif_name
;
10560 result
= inet_pton(AF_INET
, src_str
, &sg
.src
);
10562 vty_out(vty
, "Bad src address %s: errno=%d: %s\n", src_str
,
10563 errno
, safe_strerror(errno
));
10566 result
= inet_pton(AF_INET
, grp_str
, &sg
.grp
);
10568 vty_out(vty
, "Bad grp address %s: errno=%d: %s\n", grp_str
,
10569 errno
, safe_strerror(errno
));
10573 sg
.family
= AF_INET
;
10574 sg
.prefixlen
= IPV4_MAX_BITLEN
;
10576 json
= json_object_new_object();
10578 vxlan_sg
= pim_vxlan_sg_find(pim
, &sg
);
10580 installed
= (vxlan_sg
->up
) ? true : false;
10581 iif_name
= vxlan_sg
->iif
?vxlan_sg
->iif
->name
:"-";
10583 if (pim_vxlan_is_orig_mroute(vxlan_sg
))
10585 vxlan_sg
->orig_oif
?vxlan_sg
->orig_oif
->name
:"";
10588 vxlan_sg
->term_oif
?vxlan_sg
->term_oif
->name
:"";
10591 json_object_string_add(json
, "source", src_str
);
10592 json_object_string_add(json
, "group", grp_str
);
10593 json_object_string_add(json
, "input", iif_name
);
10594 json_object_string_add(json
, "output", oif_name
);
10596 json_object_boolean_true_add(json
, "installed");
10598 json_object_boolean_false_add(json
,
10601 vty_out(vty
, "SG : %s\n", vxlan_sg
->sg_str
);
10602 vty_out(vty
, " Input : %s\n", iif_name
);
10603 vty_out(vty
, " Output : %s\n", oif_name
);
10604 vty_out(vty
, " installed : %s\n",
10605 installed
?"yes":"no");
10610 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10611 json
, JSON_C_TO_STRING_PRETTY
));
10612 json_object_free(json
);
10616 DEFUN (show_ip_pim_vxlan_sg
,
10617 show_ip_pim_vxlan_sg_cmd
,
10618 "show ip pim [vrf NAME] vxlan-groups [A.B.C.D [A.B.C.D]] [json]",
10623 "VxLAN BUM groups\n"
10624 "source or group ip\n"
10628 bool uj
= use_json(argc
, argv
);
10632 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10635 return CMD_WARNING
;
10637 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ?
10638 argv
[idx
++]->arg
:NULL
;
10639 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
) ?
10640 argv
[idx
]->arg
:NULL
;
10642 if (src_ip
&& grp_ip
)
10643 pim_show_vxlan_sg_one(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
10645 pim_show_vxlan_sg_match_addr(vrf
->info
, vty
, src_ip
, uj
);
10647 pim_show_vxlan_sg(vrf
->info
, vty
, uj
);
10649 return CMD_SUCCESS
;
10652 static void pim_show_vxlan_sg_work(struct pim_instance
*pim
,
10653 struct vty
*vty
, bool uj
)
10655 json_object
*json
= NULL
;
10656 struct pim_sg_cache_walk_data cwd
;
10657 struct listnode
*node
;
10658 struct pim_vxlan_sg
*vxlan_sg
;
10661 json
= json_object_new_object();
10663 vty_out(vty
, "Codes: I -> installed\n");
10665 "Source Group Input Flags\n");
10668 memset(&cwd
, 0, sizeof(cwd
));
10671 for (ALL_LIST_ELEMENTS_RO(pim_vxlan_p
->work_list
, node
, vxlan_sg
))
10672 pim_show_vxlan_sg_entry(vxlan_sg
, &cwd
);
10675 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10676 json
, JSON_C_TO_STRING_PRETTY
));
10677 json_object_free(json
);
10681 DEFUN_HIDDEN (show_ip_pim_vxlan_sg_work
,
10682 show_ip_pim_vxlan_sg_work_cmd
,
10683 "show ip pim [vrf NAME] vxlan-work [json]",
10688 "VxLAN work list\n"
10691 bool uj
= use_json(argc
, argv
);
10695 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10698 return CMD_WARNING
;
10700 pim_show_vxlan_sg_work(vrf
->info
, vty
, uj
);
10702 return CMD_SUCCESS
;
10705 DEFUN_HIDDEN (no_ip_pim_mlag
,
10706 no_ip_pim_mlag_cmd
,
10713 struct in_addr addr
;
10716 pim_vxlan_mlag_update(true/*mlag_enable*/,
10717 false/*peer_state*/, MLAG_ROLE_NONE
,
10718 NULL
/*peerlink*/, &addr
);
10720 return CMD_SUCCESS
;
10723 DEFUN_HIDDEN (ip_pim_mlag
,
10725 "ip pim mlag INTERFACE role [primary|secondary] state [up|down] addr A.B.C.D",
10729 "peerlink sub interface\n"
10731 "MLAG role primary\n"
10732 "MLAG role secondary\n"
10733 "peer session state\n"
10734 "peer session state up\n"
10735 "peer session state down\n"
10737 "unique ip address\n")
10739 struct interface
*ifp
;
10740 const char *peerlink
;
10745 struct in_addr reg_addr
;
10748 peerlink
= argv
[idx
]->arg
;
10749 ifp
= if_lookup_by_name(peerlink
, VRF_DEFAULT
);
10751 vty_out(vty
, "No such interface name %s\n", peerlink
);
10752 return CMD_WARNING
;
10756 if (!strcmp(argv
[idx
]->arg
, "primary")) {
10757 role
= MLAG_ROLE_PRIMARY
;
10758 } else if (!strcmp(argv
[idx
]->arg
, "secondary")) {
10759 role
= MLAG_ROLE_SECONDARY
;
10761 vty_out(vty
, "unknown MLAG role %s\n", argv
[idx
]->arg
);
10762 return CMD_WARNING
;
10766 if (!strcmp(argv
[idx
]->arg
, "up")) {
10768 } else if (strcmp(argv
[idx
]->arg
, "down")) {
10769 peer_state
= false;
10771 vty_out(vty
, "unknown MLAG state %s\n", argv
[idx
]->arg
);
10772 return CMD_WARNING
;
10776 result
= inet_pton(AF_INET
, argv
[idx
]->arg
, ®_addr
);
10778 vty_out(vty
, "%% Bad reg address %s: errno=%d: %s\n",
10780 errno
, safe_strerror(errno
));
10781 return CMD_WARNING_CONFIG_FAILED
;
10783 pim_vxlan_mlag_update(true, peer_state
, role
, ifp
, ®_addr
);
10785 return CMD_SUCCESS
;
10788 void pim_cmd_init(void)
10790 install_node(&interface_node
,
10791 pim_interface_config_write
); /* INTERFACE_NODE */
10794 install_node(&debug_node
, pim_debug_config_write
);
10796 install_element(ENABLE_NODE
, &pim_test_sg_keepalive_cmd
);
10798 install_element(CONFIG_NODE
, &ip_pim_rp_cmd
);
10799 install_element(VRF_NODE
, &ip_pim_rp_cmd
);
10800 install_element(CONFIG_NODE
, &no_ip_pim_rp_cmd
);
10801 install_element(VRF_NODE
, &no_ip_pim_rp_cmd
);
10802 install_element(CONFIG_NODE
, &ip_pim_rp_prefix_list_cmd
);
10803 install_element(VRF_NODE
, &ip_pim_rp_prefix_list_cmd
);
10804 install_element(CONFIG_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
10805 install_element(VRF_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
10806 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
10807 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
10808 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
10809 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
10810 install_element(CONFIG_NODE
, &ip_pim_ssm_prefix_list_cmd
);
10811 install_element(VRF_NODE
, &ip_pim_ssm_prefix_list_cmd
);
10812 install_element(CONFIG_NODE
, &ip_pim_register_suppress_cmd
);
10813 install_element(VRF_NODE
, &ip_pim_register_suppress_cmd
);
10814 install_element(CONFIG_NODE
, &no_ip_pim_register_suppress_cmd
);
10815 install_element(VRF_NODE
, &no_ip_pim_register_suppress_cmd
);
10816 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
10817 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
10818 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
10819 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
10820 install_element(CONFIG_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
10821 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
10822 install_element(CONFIG_NODE
,
10823 &no_ip_pim_spt_switchover_infinity_plist_cmd
);
10824 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_plist_cmd
);
10825 install_element(CONFIG_NODE
, &pim_register_accept_list_cmd
);
10826 install_element(VRF_NODE
, &pim_register_accept_list_cmd
);
10827 install_element(CONFIG_NODE
, &ip_pim_joinprune_time_cmd
);
10828 install_element(VRF_NODE
, &ip_pim_joinprune_time_cmd
);
10829 install_element(CONFIG_NODE
, &no_ip_pim_joinprune_time_cmd
);
10830 install_element(VRF_NODE
, &no_ip_pim_joinprune_time_cmd
);
10831 install_element(CONFIG_NODE
, &ip_pim_keep_alive_cmd
);
10832 install_element(VRF_NODE
, &ip_pim_keep_alive_cmd
);
10833 install_element(CONFIG_NODE
, &ip_pim_rp_keep_alive_cmd
);
10834 install_element(VRF_NODE
, &ip_pim_rp_keep_alive_cmd
);
10835 install_element(CONFIG_NODE
, &no_ip_pim_keep_alive_cmd
);
10836 install_element(VRF_NODE
, &no_ip_pim_keep_alive_cmd
);
10837 install_element(CONFIG_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
10838 install_element(VRF_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
10839 install_element(CONFIG_NODE
, &ip_pim_packets_cmd
);
10840 install_element(VRF_NODE
, &ip_pim_packets_cmd
);
10841 install_element(CONFIG_NODE
, &no_ip_pim_packets_cmd
);
10842 install_element(VRF_NODE
, &no_ip_pim_packets_cmd
);
10843 install_element(CONFIG_NODE
, &ip_pim_v6_secondary_cmd
);
10844 install_element(VRF_NODE
, &ip_pim_v6_secondary_cmd
);
10845 install_element(CONFIG_NODE
, &no_ip_pim_v6_secondary_cmd
);
10846 install_element(VRF_NODE
, &no_ip_pim_v6_secondary_cmd
);
10847 install_element(CONFIG_NODE
, &ip_ssmpingd_cmd
);
10848 install_element(VRF_NODE
, &ip_ssmpingd_cmd
);
10849 install_element(CONFIG_NODE
, &no_ip_ssmpingd_cmd
);
10850 install_element(VRF_NODE
, &no_ip_ssmpingd_cmd
);
10851 install_element(CONFIG_NODE
, &ip_msdp_peer_cmd
);
10852 install_element(VRF_NODE
, &ip_msdp_peer_cmd
);
10853 install_element(CONFIG_NODE
, &no_ip_msdp_peer_cmd
);
10854 install_element(VRF_NODE
, &no_ip_msdp_peer_cmd
);
10855 install_element(CONFIG_NODE
, &ip_pim_ecmp_cmd
);
10856 install_element(VRF_NODE
, &ip_pim_ecmp_cmd
);
10857 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_cmd
);
10858 install_element(VRF_NODE
, &no_ip_pim_ecmp_cmd
);
10859 install_element(CONFIG_NODE
, &ip_pim_ecmp_rebalance_cmd
);
10860 install_element(VRF_NODE
, &ip_pim_ecmp_rebalance_cmd
);
10861 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
10862 install_element(VRF_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
10863 install_element(CONFIG_NODE
, &ip_pim_mlag_cmd
);
10864 install_element(CONFIG_NODE
, &no_ip_pim_mlag_cmd
);
10866 install_element(INTERFACE_NODE
, &interface_ip_igmp_cmd
);
10867 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_cmd
);
10868 install_element(INTERFACE_NODE
, &interface_ip_igmp_join_cmd
);
10869 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_join_cmd
);
10870 install_element(INTERFACE_NODE
, &interface_ip_igmp_version_cmd
);
10871 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_version_cmd
);
10872 install_element(INTERFACE_NODE
, &interface_ip_igmp_query_interval_cmd
);
10873 install_element(INTERFACE_NODE
,
10874 &interface_no_ip_igmp_query_interval_cmd
);
10875 install_element(INTERFACE_NODE
,
10876 &interface_ip_igmp_query_max_response_time_cmd
);
10877 install_element(INTERFACE_NODE
,
10878 &interface_no_ip_igmp_query_max_response_time_cmd
);
10879 install_element(INTERFACE_NODE
,
10880 &interface_ip_igmp_query_max_response_time_dsec_cmd
);
10881 install_element(INTERFACE_NODE
,
10882 &interface_no_ip_igmp_query_max_response_time_dsec_cmd
);
10883 install_element(INTERFACE_NODE
,
10884 &interface_ip_igmp_last_member_query_count_cmd
);
10885 install_element(INTERFACE_NODE
,
10886 &interface_no_ip_igmp_last_member_query_count_cmd
);
10887 install_element(INTERFACE_NODE
,
10888 &interface_ip_igmp_last_member_query_interval_cmd
);
10889 install_element(INTERFACE_NODE
,
10890 &interface_no_ip_igmp_last_member_query_interval_cmd
);
10891 install_element(INTERFACE_NODE
, &interface_ip_pim_activeactive_cmd
);
10892 install_element(INTERFACE_NODE
, &interface_ip_pim_ssm_cmd
);
10893 install_element(INTERFACE_NODE
, &interface_no_ip_pim_ssm_cmd
);
10894 install_element(INTERFACE_NODE
, &interface_ip_pim_sm_cmd
);
10895 install_element(INTERFACE_NODE
, &interface_no_ip_pim_sm_cmd
);
10896 install_element(INTERFACE_NODE
, &interface_ip_pim_cmd
);
10897 install_element(INTERFACE_NODE
, &interface_no_ip_pim_cmd
);
10898 install_element(INTERFACE_NODE
, &interface_ip_pim_drprio_cmd
);
10899 install_element(INTERFACE_NODE
, &interface_no_ip_pim_drprio_cmd
);
10900 install_element(INTERFACE_NODE
, &interface_ip_pim_hello_cmd
);
10901 install_element(INTERFACE_NODE
, &interface_no_ip_pim_hello_cmd
);
10902 install_element(INTERFACE_NODE
, &interface_ip_pim_boundary_oil_cmd
);
10903 install_element(INTERFACE_NODE
, &interface_no_ip_pim_boundary_oil_cmd
);
10904 install_element(INTERFACE_NODE
, &interface_ip_igmp_query_generate_cmd
);
10906 // Static mroutes NEB
10907 install_element(INTERFACE_NODE
, &interface_ip_mroute_cmd
);
10908 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_cmd
);
10910 install_element(VIEW_NODE
, &show_ip_igmp_interface_cmd
);
10911 install_element(VIEW_NODE
, &show_ip_igmp_interface_vrf_all_cmd
);
10912 install_element(VIEW_NODE
, &show_ip_igmp_join_cmd
);
10913 install_element(VIEW_NODE
, &show_ip_igmp_join_vrf_all_cmd
);
10914 install_element(VIEW_NODE
, &show_ip_igmp_groups_cmd
);
10915 install_element(VIEW_NODE
, &show_ip_igmp_groups_vrf_all_cmd
);
10916 install_element(VIEW_NODE
, &show_ip_igmp_groups_retransmissions_cmd
);
10917 install_element(VIEW_NODE
, &show_ip_igmp_sources_cmd
);
10918 install_element(VIEW_NODE
, &show_ip_igmp_sources_retransmissions_cmd
);
10919 install_element(VIEW_NODE
, &show_ip_igmp_statistics_cmd
);
10920 install_element(VIEW_NODE
, &show_ip_pim_assert_cmd
);
10921 install_element(VIEW_NODE
, &show_ip_pim_assert_internal_cmd
);
10922 install_element(VIEW_NODE
, &show_ip_pim_assert_metric_cmd
);
10923 install_element(VIEW_NODE
, &show_ip_pim_assert_winner_metric_cmd
);
10924 install_element(VIEW_NODE
, &show_ip_pim_interface_traffic_cmd
);
10925 install_element(VIEW_NODE
, &show_ip_pim_interface_cmd
);
10926 install_element(VIEW_NODE
, &show_ip_pim_interface_vrf_all_cmd
);
10927 install_element(VIEW_NODE
, &show_ip_pim_join_cmd
);
10928 install_element(VIEW_NODE
, &show_ip_pim_join_vrf_all_cmd
);
10929 install_element(VIEW_NODE
, &show_ip_pim_jp_agg_cmd
);
10930 install_element(VIEW_NODE
, &show_ip_pim_local_membership_cmd
);
10931 install_element(VIEW_NODE
, &show_ip_pim_mlag_summary_cmd
);
10932 install_element(VIEW_NODE
, &show_ip_pim_mlag_up_cmd
);
10933 install_element(VIEW_NODE
, &show_ip_pim_mlag_up_vrf_all_cmd
);
10934 install_element(VIEW_NODE
, &show_ip_pim_neighbor_cmd
);
10935 install_element(VIEW_NODE
, &show_ip_pim_neighbor_vrf_all_cmd
);
10936 install_element(VIEW_NODE
, &show_ip_pim_rpf_cmd
);
10937 install_element(VIEW_NODE
, &show_ip_pim_rpf_vrf_all_cmd
);
10938 install_element(VIEW_NODE
, &show_ip_pim_secondary_cmd
);
10939 install_element(VIEW_NODE
, &show_ip_pim_state_cmd
);
10940 install_element(VIEW_NODE
, &show_ip_pim_state_vrf_all_cmd
);
10941 install_element(VIEW_NODE
, &show_ip_pim_upstream_cmd
);
10942 install_element(VIEW_NODE
, &show_ip_pim_upstream_vrf_all_cmd
);
10943 install_element(VIEW_NODE
, &show_ip_pim_channel_cmd
);
10944 install_element(VIEW_NODE
, &show_ip_pim_upstream_join_desired_cmd
);
10945 install_element(VIEW_NODE
, &show_ip_pim_upstream_rpf_cmd
);
10946 install_element(VIEW_NODE
, &show_ip_pim_rp_cmd
);
10947 install_element(VIEW_NODE
, &show_ip_pim_rp_vrf_all_cmd
);
10948 install_element(VIEW_NODE
, &show_ip_pim_bsr_cmd
);
10949 install_element(VIEW_NODE
, &show_ip_multicast_cmd
);
10950 install_element(VIEW_NODE
, &show_ip_multicast_vrf_all_cmd
);
10951 install_element(VIEW_NODE
, &show_ip_mroute_cmd
);
10952 install_element(VIEW_NODE
, &show_ip_mroute_vrf_all_cmd
);
10953 install_element(VIEW_NODE
, &show_ip_mroute_count_cmd
);
10954 install_element(VIEW_NODE
, &show_ip_mroute_count_vrf_all_cmd
);
10955 install_element(VIEW_NODE
, &show_ip_mroute_summary_cmd
);
10956 install_element(VIEW_NODE
, &show_ip_mroute_summary_vrf_all_cmd
);
10957 install_element(VIEW_NODE
, &show_ip_rib_cmd
);
10958 install_element(VIEW_NODE
, &show_ip_ssmpingd_cmd
);
10959 install_element(VIEW_NODE
, &show_debugging_pim_cmd
);
10960 install_element(VIEW_NODE
, &show_ip_pim_nexthop_cmd
);
10961 install_element(VIEW_NODE
, &show_ip_pim_nexthop_lookup_cmd
);
10962 install_element(VIEW_NODE
, &show_ip_pim_bsrp_cmd
);
10963 install_element(VIEW_NODE
, &show_ip_pim_bsm_db_cmd
);
10964 install_element(VIEW_NODE
, &show_ip_pim_statistics_cmd
);
10966 install_element(ENABLE_NODE
, &clear_ip_mroute_count_cmd
);
10967 install_element(ENABLE_NODE
, &clear_ip_interfaces_cmd
);
10968 install_element(ENABLE_NODE
, &clear_ip_igmp_interfaces_cmd
);
10969 install_element(ENABLE_NODE
, &clear_ip_mroute_cmd
);
10970 install_element(ENABLE_NODE
, &clear_ip_pim_interfaces_cmd
);
10971 install_element(ENABLE_NODE
, &clear_ip_pim_interface_traffic_cmd
);
10972 install_element(ENABLE_NODE
, &clear_ip_pim_oil_cmd
);
10973 install_element(ENABLE_NODE
, &clear_ip_pim_statistics_cmd
);
10975 install_element(ENABLE_NODE
, &debug_igmp_cmd
);
10976 install_element(ENABLE_NODE
, &no_debug_igmp_cmd
);
10977 install_element(ENABLE_NODE
, &debug_igmp_events_cmd
);
10978 install_element(ENABLE_NODE
, &no_debug_igmp_events_cmd
);
10979 install_element(ENABLE_NODE
, &debug_igmp_packets_cmd
);
10980 install_element(ENABLE_NODE
, &no_debug_igmp_packets_cmd
);
10981 install_element(ENABLE_NODE
, &debug_igmp_trace_cmd
);
10982 install_element(ENABLE_NODE
, &no_debug_igmp_trace_cmd
);
10983 install_element(ENABLE_NODE
, &debug_mroute_cmd
);
10984 install_element(ENABLE_NODE
, &debug_mroute_detail_cmd
);
10985 install_element(ENABLE_NODE
, &no_debug_mroute_cmd
);
10986 install_element(ENABLE_NODE
, &no_debug_mroute_detail_cmd
);
10987 install_element(ENABLE_NODE
, &debug_pim_static_cmd
);
10988 install_element(ENABLE_NODE
, &no_debug_pim_static_cmd
);
10989 install_element(ENABLE_NODE
, &debug_pim_cmd
);
10990 install_element(ENABLE_NODE
, &no_debug_pim_cmd
);
10991 install_element(ENABLE_NODE
, &debug_pim_nht_cmd
);
10992 install_element(ENABLE_NODE
, &no_debug_pim_nht_cmd
);
10993 install_element(ENABLE_NODE
, &debug_pim_nht_rp_cmd
);
10994 install_element(ENABLE_NODE
, &no_debug_pim_nht_rp_cmd
);
10995 install_element(ENABLE_NODE
, &debug_pim_events_cmd
);
10996 install_element(ENABLE_NODE
, &no_debug_pim_events_cmd
);
10997 install_element(ENABLE_NODE
, &debug_pim_packets_cmd
);
10998 install_element(ENABLE_NODE
, &no_debug_pim_packets_cmd
);
10999 install_element(ENABLE_NODE
, &debug_pim_packetdump_send_cmd
);
11000 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_send_cmd
);
11001 install_element(ENABLE_NODE
, &debug_pim_packetdump_recv_cmd
);
11002 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_recv_cmd
);
11003 install_element(ENABLE_NODE
, &debug_pim_trace_cmd
);
11004 install_element(ENABLE_NODE
, &no_debug_pim_trace_cmd
);
11005 install_element(ENABLE_NODE
, &debug_pim_trace_detail_cmd
);
11006 install_element(ENABLE_NODE
, &no_debug_pim_trace_detail_cmd
);
11007 install_element(ENABLE_NODE
, &debug_ssmpingd_cmd
);
11008 install_element(ENABLE_NODE
, &no_debug_ssmpingd_cmd
);
11009 install_element(ENABLE_NODE
, &debug_pim_zebra_cmd
);
11010 install_element(ENABLE_NODE
, &no_debug_pim_zebra_cmd
);
11011 install_element(ENABLE_NODE
, &debug_pim_mlag_cmd
);
11012 install_element(ENABLE_NODE
, &no_debug_pim_mlag_cmd
);
11013 install_element(ENABLE_NODE
, &debug_pim_vxlan_cmd
);
11014 install_element(ENABLE_NODE
, &no_debug_pim_vxlan_cmd
);
11015 install_element(ENABLE_NODE
, &debug_msdp_cmd
);
11016 install_element(ENABLE_NODE
, &no_debug_msdp_cmd
);
11017 install_element(ENABLE_NODE
, &debug_msdp_events_cmd
);
11018 install_element(ENABLE_NODE
, &no_debug_msdp_events_cmd
);
11019 install_element(ENABLE_NODE
, &debug_msdp_packets_cmd
);
11020 install_element(ENABLE_NODE
, &no_debug_msdp_packets_cmd
);
11021 install_element(ENABLE_NODE
, &debug_mtrace_cmd
);
11022 install_element(ENABLE_NODE
, &no_debug_mtrace_cmd
);
11023 install_element(ENABLE_NODE
, &debug_bsm_cmd
);
11024 install_element(ENABLE_NODE
, &no_debug_bsm_cmd
);
11026 install_element(CONFIG_NODE
, &debug_igmp_cmd
);
11027 install_element(CONFIG_NODE
, &no_debug_igmp_cmd
);
11028 install_element(CONFIG_NODE
, &debug_igmp_events_cmd
);
11029 install_element(CONFIG_NODE
, &no_debug_igmp_events_cmd
);
11030 install_element(CONFIG_NODE
, &debug_igmp_packets_cmd
);
11031 install_element(CONFIG_NODE
, &no_debug_igmp_packets_cmd
);
11032 install_element(CONFIG_NODE
, &debug_igmp_trace_cmd
);
11033 install_element(CONFIG_NODE
, &no_debug_igmp_trace_cmd
);
11034 install_element(CONFIG_NODE
, &debug_mroute_cmd
);
11035 install_element(CONFIG_NODE
, &debug_mroute_detail_cmd
);
11036 install_element(CONFIG_NODE
, &no_debug_mroute_cmd
);
11037 install_element(CONFIG_NODE
, &no_debug_mroute_detail_cmd
);
11038 install_element(CONFIG_NODE
, &debug_pim_static_cmd
);
11039 install_element(CONFIG_NODE
, &no_debug_pim_static_cmd
);
11040 install_element(CONFIG_NODE
, &debug_pim_cmd
);
11041 install_element(CONFIG_NODE
, &no_debug_pim_cmd
);
11042 install_element(CONFIG_NODE
, &debug_pim_nht_cmd
);
11043 install_element(CONFIG_NODE
, &no_debug_pim_nht_cmd
);
11044 install_element(CONFIG_NODE
, &debug_pim_nht_rp_cmd
);
11045 install_element(CONFIG_NODE
, &no_debug_pim_nht_rp_cmd
);
11046 install_element(CONFIG_NODE
, &debug_pim_events_cmd
);
11047 install_element(CONFIG_NODE
, &no_debug_pim_events_cmd
);
11048 install_element(CONFIG_NODE
, &debug_pim_packets_cmd
);
11049 install_element(CONFIG_NODE
, &no_debug_pim_packets_cmd
);
11050 install_element(CONFIG_NODE
, &debug_pim_trace_cmd
);
11051 install_element(CONFIG_NODE
, &no_debug_pim_trace_cmd
);
11052 install_element(CONFIG_NODE
, &debug_pim_trace_detail_cmd
);
11053 install_element(CONFIG_NODE
, &no_debug_pim_trace_detail_cmd
);
11054 install_element(CONFIG_NODE
, &debug_ssmpingd_cmd
);
11055 install_element(CONFIG_NODE
, &no_debug_ssmpingd_cmd
);
11056 install_element(CONFIG_NODE
, &debug_pim_zebra_cmd
);
11057 install_element(CONFIG_NODE
, &no_debug_pim_zebra_cmd
);
11058 install_element(CONFIG_NODE
, &debug_pim_mlag_cmd
);
11059 install_element(CONFIG_NODE
, &no_debug_pim_mlag_cmd
);
11060 install_element(CONFIG_NODE
, &debug_pim_vxlan_cmd
);
11061 install_element(CONFIG_NODE
, &no_debug_pim_vxlan_cmd
);
11062 install_element(CONFIG_NODE
, &debug_msdp_cmd
);
11063 install_element(CONFIG_NODE
, &no_debug_msdp_cmd
);
11064 install_element(CONFIG_NODE
, &debug_msdp_events_cmd
);
11065 install_element(CONFIG_NODE
, &no_debug_msdp_events_cmd
);
11066 install_element(CONFIG_NODE
, &debug_msdp_packets_cmd
);
11067 install_element(CONFIG_NODE
, &no_debug_msdp_packets_cmd
);
11068 install_element(CONFIG_NODE
, &debug_mtrace_cmd
);
11069 install_element(CONFIG_NODE
, &no_debug_mtrace_cmd
);
11070 install_element(CONFIG_NODE
, &debug_bsm_cmd
);
11071 install_element(CONFIG_NODE
, &no_debug_bsm_cmd
);
11073 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_member_cmd
);
11074 install_element(VRF_NODE
, &ip_msdp_mesh_group_member_cmd
);
11075 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
11076 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
11077 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_source_cmd
);
11078 install_element(VRF_NODE
, &ip_msdp_mesh_group_source_cmd
);
11079 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
11080 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
11081 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_cmd
);
11082 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_vrf_all_cmd
);
11083 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_cmd
);
11084 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_vrf_all_cmd
);
11085 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_cmd
);
11086 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_vrf_all_cmd
);
11087 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_cmd
);
11088 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_vrf_all_cmd
);
11089 install_element(VIEW_NODE
, &show_ip_pim_ssm_range_cmd
);
11090 install_element(VIEW_NODE
, &show_ip_pim_group_type_cmd
);
11091 install_element(VIEW_NODE
, &show_ip_pim_vxlan_sg_cmd
);
11092 install_element(VIEW_NODE
, &show_ip_pim_vxlan_sg_work_cmd
);
11093 install_element(INTERFACE_NODE
, &interface_pim_use_source_cmd
);
11094 install_element(INTERFACE_NODE
, &interface_no_pim_use_source_cmd
);
11095 /* Install BSM command */
11096 install_element(INTERFACE_NODE
, &ip_pim_bsm_cmd
);
11097 install_element(INTERFACE_NODE
, &no_ip_pim_bsm_cmd
);
11098 install_element(INTERFACE_NODE
, &ip_pim_ucast_bsm_cmd
);
11099 install_element(INTERFACE_NODE
, &no_ip_pim_ucast_bsm_cmd
);
11100 /* Install BFD command */
11101 install_element(INTERFACE_NODE
, &ip_pim_bfd_cmd
);
11102 install_element(INTERFACE_NODE
, &ip_pim_bfd_param_cmd
);
11103 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_cmd
);
11105 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_param_cmd
);
11106 #endif /* !HAVE_BFDD */