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 (strcmp(ifname
, "detail") && strcmp(ifname
, ifp
->name
))
959 ifaddr
= pim_ifp
->primary_address
;
960 pim_inet4_dump("<dr?>", pim_ifp
->pim_dr_addr
, dr_str
,
962 pim_time_uptime_begin(dr_uptime
, sizeof(dr_uptime
), now
,
963 pim_ifp
->pim_dr_election_last
);
964 pim_time_timer_to_hhmmss(hello_timer
, sizeof(hello_timer
),
965 pim_ifp
->t_pim_hello_timer
);
966 pim_time_mmss(hello_period
, sizeof(hello_period
),
967 pim_ifp
->pim_hello_period
);
968 pim_time_uptime(stat_uptime
, sizeof(stat_uptime
),
969 now
- pim_ifp
->pim_ifstat_start
);
970 if (pim_ifp
->pim_sock_fd
>= 0)
971 mloop
= pim_socket_mcastloop_get(pim_ifp
->pim_sock_fd
);
976 char pbuf
[PREFIX2STR_BUFFER
];
977 json_row
= json_object_new_object();
978 json_object_pim_ifp_add(json_row
, ifp
);
980 if (pim_ifp
->update_source
.s_addr
!= INADDR_ANY
) {
981 json_object_string_add(
982 json_row
, "useSource",
983 inet_ntoa(pim_ifp
->update_source
));
985 if (pim_ifp
->sec_addr_list
) {
986 json_object
*sec_list
= NULL
;
988 sec_list
= json_object_new_array();
989 for (ALL_LIST_ELEMENTS_RO(
990 pim_ifp
->sec_addr_list
, sec_node
,
992 json_object_array_add(
994 json_object_new_string(
1000 json_object_object_add(json_row
,
1001 "secondaryAddressList",
1006 if (pim_ifp
->pim_neighbor_list
->count
) {
1007 json_pim_neighbors
= json_object_new_object();
1009 for (ALL_LIST_ELEMENTS_RO(
1010 pim_ifp
->pim_neighbor_list
,
1011 neighnode
, neigh
)) {
1013 json_object_new_object();
1014 pim_inet4_dump("<src?>",
1017 sizeof(neigh_src_str
));
1018 pim_time_uptime(uptime
, sizeof(uptime
),
1019 now
- neigh
->creation
);
1020 pim_time_timer_to_hhmmss(
1021 expire
, sizeof(expire
),
1022 neigh
->t_expire_timer
);
1024 json_object_string_add(
1025 json_pim_neighbor
, "address",
1027 json_object_string_add(
1028 json_pim_neighbor
, "upTime",
1030 json_object_string_add(
1031 json_pim_neighbor
, "holdtime",
1034 json_object_object_add(
1040 json_object_object_add(json_row
, "neighbors",
1041 json_pim_neighbors
);
1044 json_object_string_add(json_row
, "drAddress", dr_str
);
1045 json_object_int_add(json_row
, "drPriority",
1046 pim_ifp
->pim_dr_priority
);
1047 json_object_string_add(json_row
, "drUptime", dr_uptime
);
1048 json_object_int_add(json_row
, "drElections",
1049 pim_ifp
->pim_dr_election_count
);
1050 json_object_int_add(json_row
, "drChanges",
1051 pim_ifp
->pim_dr_election_changes
);
1054 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
1055 if (ifp
!= up
->rpf
.source_nexthop
.interface
)
1058 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
))
1061 if (!json_fhr_sources
)
1063 json_object_new_object();
1065 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
,
1067 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
,
1069 pim_time_uptime(uptime
, sizeof(uptime
),
1070 now
- up
->state_transition
);
1073 * Does this group live in json_fhr_sources?
1076 json_object_object_get_ex(json_fhr_sources
,
1077 grp_str
, &json_group
);
1080 json_group
= json_object_new_object();
1081 json_object_object_add(json_fhr_sources
,
1086 json_group_source
= json_object_new_object();
1087 json_object_string_add(json_group_source
,
1089 json_object_string_add(json_group_source
,
1091 json_object_string_add(json_group_source
,
1093 json_object_object_add(json_group
, src_str
,
1097 if (json_fhr_sources
) {
1098 json_object_object_add(json_row
,
1103 json_object_int_add(json_row
, "helloPeriod",
1104 pim_ifp
->pim_hello_period
);
1105 json_object_string_add(json_row
, "helloTimer",
1107 json_object_string_add(json_row
, "helloStatStart",
1109 json_object_int_add(json_row
, "helloReceived",
1110 pim_ifp
->pim_ifstat_hello_recv
);
1111 json_object_int_add(json_row
, "helloReceivedFailed",
1112 pim_ifp
->pim_ifstat_hello_recvfail
);
1113 json_object_int_add(json_row
, "helloSend",
1114 pim_ifp
->pim_ifstat_hello_sent
);
1115 json_object_int_add(json_row
, "hellosendFailed",
1116 pim_ifp
->pim_ifstat_hello_sendfail
);
1117 json_object_int_add(json_row
, "helloGenerationId",
1118 pim_ifp
->pim_generation_id
);
1119 json_object_int_add(json_row
, "flagMulticastLoop",
1122 json_object_int_add(
1123 json_row
, "effectivePropagationDelay",
1124 pim_if_effective_propagation_delay_msec(ifp
));
1125 json_object_int_add(
1126 json_row
, "effectiveOverrideInterval",
1127 pim_if_effective_override_interval_msec(ifp
));
1128 json_object_int_add(
1129 json_row
, "joinPruneOverrideInterval",
1130 pim_if_jp_override_interval_msec(ifp
));
1132 json_object_int_add(
1133 json_row
, "propagationDelay",
1134 pim_ifp
->pim_propagation_delay_msec
);
1135 json_object_int_add(
1136 json_row
, "propagationDelayHighest",
1137 pim_ifp
->pim_neighbors_highest_propagation_delay_msec
);
1138 json_object_int_add(
1139 json_row
, "overrideInterval",
1140 pim_ifp
->pim_override_interval_msec
);
1141 json_object_int_add(
1142 json_row
, "overrideIntervalHighest",
1143 pim_ifp
->pim_neighbors_highest_override_interval_msec
);
1144 json_object_object_add(json
, ifp
->name
, json_row
);
1147 vty_out(vty
, "Interface : %s\n", ifp
->name
);
1148 vty_out(vty
, "State : %s\n",
1149 if_is_up(ifp
) ? "up" : "down");
1150 if (pim_ifp
->update_source
.s_addr
!= INADDR_ANY
) {
1151 vty_out(vty
, "Use Source : %s\n",
1152 inet_ntoa(pim_ifp
->update_source
));
1154 if (pim_ifp
->sec_addr_list
) {
1155 char pbuf
[PREFIX2STR_BUFFER
];
1156 vty_out(vty
, "Address : %s (primary)\n",
1158 for (ALL_LIST_ELEMENTS_RO(
1159 pim_ifp
->sec_addr_list
, sec_node
,
1161 vty_out(vty
, " %s\n",
1162 prefix2str(&sec_addr
->addr
,
1163 pbuf
, sizeof(pbuf
)));
1166 vty_out(vty
, "Address : %s\n",
1174 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
,
1175 neighnode
, neigh
)) {
1178 vty_out(vty
, "PIM Neighbors\n");
1179 vty_out(vty
, "-------------\n");
1183 pim_inet4_dump("<src?>", neigh
->source_addr
,
1185 sizeof(neigh_src_str
));
1186 pim_time_uptime(uptime
, sizeof(uptime
),
1187 now
- neigh
->creation
);
1188 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
1189 neigh
->t_expire_timer
);
1191 "%-15s : up for %s, holdtime expires in %s\n",
1192 neigh_src_str
, uptime
, expire
);
1195 if (!print_header
) {
1200 vty_out(vty
, "Designated Router\n");
1201 vty_out(vty
, "-----------------\n");
1202 vty_out(vty
, "Address : %s\n", dr_str
);
1203 vty_out(vty
, "Priority : %u(%d)\n",
1204 pim_ifp
->pim_dr_priority
,
1205 pim_ifp
->pim_dr_num_nondrpri_neighbors
);
1206 vty_out(vty
, "Uptime : %s\n", dr_uptime
);
1207 vty_out(vty
, "Elections : %d\n",
1208 pim_ifp
->pim_dr_election_count
);
1209 vty_out(vty
, "Changes : %d\n",
1210 pim_ifp
->pim_dr_election_changes
);
1216 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
1217 if (!up
->rpf
.source_nexthop
.interface
)
1220 if (strcmp(ifp
->name
,
1221 up
->rpf
.source_nexthop
1226 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
))
1231 "FHR - First Hop Router\n");
1233 "----------------------\n");
1237 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
,
1239 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
,
1241 pim_time_uptime(uptime
, sizeof(uptime
),
1242 now
- up
->state_transition
);
1244 "%s : %s is a source, uptime is %s\n",
1245 grp_str
, src_str
, uptime
);
1248 if (!print_header
) {
1253 vty_out(vty
, "Hellos\n");
1254 vty_out(vty
, "------\n");
1255 vty_out(vty
, "Period : %d\n",
1256 pim_ifp
->pim_hello_period
);
1257 vty_out(vty
, "Timer : %s\n", hello_timer
);
1258 vty_out(vty
, "StatStart : %s\n", stat_uptime
);
1259 vty_out(vty
, "Receive : %d\n",
1260 pim_ifp
->pim_ifstat_hello_recv
);
1261 vty_out(vty
, "Receive Failed : %d\n",
1262 pim_ifp
->pim_ifstat_hello_recvfail
);
1263 vty_out(vty
, "Send : %d\n",
1264 pim_ifp
->pim_ifstat_hello_sent
);
1265 vty_out(vty
, "Send Failed : %d\n",
1266 pim_ifp
->pim_ifstat_hello_sendfail
);
1267 vty_out(vty
, "Generation ID : %08x\n",
1268 pim_ifp
->pim_generation_id
);
1272 pim_print_ifp_flags(vty
, ifp
, mloop
);
1274 vty_out(vty
, "Join Prune Interval\n");
1275 vty_out(vty
, "-------------------\n");
1276 vty_out(vty
, "LAN Delay : %s\n",
1277 pim_if_lan_delay_enabled(ifp
) ? "yes" : "no");
1278 vty_out(vty
, "Effective Propagation Delay : %d msec\n",
1279 pim_if_effective_propagation_delay_msec(ifp
));
1280 vty_out(vty
, "Effective Override Interval : %d msec\n",
1281 pim_if_effective_override_interval_msec(ifp
));
1282 vty_out(vty
, "Join Prune Override Interval : %d msec\n",
1283 pim_if_jp_override_interval_msec(ifp
));
1287 vty_out(vty
, "LAN Prune Delay\n");
1288 vty_out(vty
, "---------------\n");
1289 vty_out(vty
, "Propagation Delay : %d msec\n",
1290 pim_ifp
->pim_propagation_delay_msec
);
1291 vty_out(vty
, "Propagation Delay (Highest) : %d msec\n",
1292 pim_ifp
->pim_neighbors_highest_propagation_delay_msec
);
1293 vty_out(vty
, "Override Interval : %d msec\n",
1294 pim_ifp
->pim_override_interval_msec
);
1295 vty_out(vty
, "Override Interval (Highest) : %d msec\n",
1296 pim_ifp
->pim_neighbors_highest_override_interval_msec
);
1303 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1304 json
, JSON_C_TO_STRING_PRETTY
));
1305 json_object_free(json
);
1308 vty_out(vty
, "%% No such interface\n");
1312 static void igmp_show_statistics(struct pim_instance
*pim
, struct vty
*vty
,
1313 const char *ifname
, bool uj
)
1315 struct interface
*ifp
;
1316 struct igmp_stats rx_stats
;
1318 igmp_stats_init(&rx_stats
);
1320 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1321 struct pim_interface
*pim_ifp
;
1322 struct listnode
*sock_node
;
1323 struct igmp_sock
*igmp
;
1325 pim_ifp
= ifp
->info
;
1330 if (ifname
&& strcmp(ifname
, ifp
->name
))
1333 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
1335 igmp_stats_add(&rx_stats
, &igmp
->rx_stats
);
1339 json_object
*json
= NULL
;
1340 json_object
*json_row
= NULL
;
1342 json
= json_object_new_object();
1343 json_row
= json_object_new_object();
1345 json_object_string_add(json_row
, "name", ifname
? ifname
:
1347 json_object_int_add(json_row
, "queryV1", rx_stats
.query_v1
);
1348 json_object_int_add(json_row
, "queryV2", rx_stats
.query_v2
);
1349 json_object_int_add(json_row
, "queryV3", rx_stats
.query_v3
);
1350 json_object_int_add(json_row
, "leaveV3", rx_stats
.leave_v2
);
1351 json_object_int_add(json_row
, "reportV1", rx_stats
.report_v1
);
1352 json_object_int_add(json_row
, "reportV2", rx_stats
.report_v2
);
1353 json_object_int_add(json_row
, "reportV3", rx_stats
.report_v3
);
1354 json_object_int_add(json_row
, "mtraceResponse",
1355 rx_stats
.mtrace_rsp
);
1356 json_object_int_add(json_row
, "mtraceRequest",
1357 rx_stats
.mtrace_req
);
1358 json_object_int_add(json_row
, "unsupported",
1359 rx_stats
.unsupported
);
1360 json_object_object_add(json
, ifname
? ifname
: "global",
1362 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1363 json
, JSON_C_TO_STRING_PRETTY
));
1364 json_object_free(json
);
1366 vty_out(vty
, "IGMP RX statistics\n");
1367 vty_out(vty
, "Interface : %s\n",
1368 ifname
? ifname
: "global");
1369 vty_out(vty
, "V1 query : %u\n", rx_stats
.query_v1
);
1370 vty_out(vty
, "V2 query : %u\n", rx_stats
.query_v2
);
1371 vty_out(vty
, "V3 query : %u\n", rx_stats
.query_v3
);
1372 vty_out(vty
, "V2 leave : %u\n", rx_stats
.leave_v2
);
1373 vty_out(vty
, "V1 report : %u\n", rx_stats
.report_v1
);
1374 vty_out(vty
, "V2 report : %u\n", rx_stats
.report_v2
);
1375 vty_out(vty
, "V3 report : %u\n", rx_stats
.report_v3
);
1376 vty_out(vty
, "mtrace response : %u\n", rx_stats
.mtrace_rsp
);
1377 vty_out(vty
, "mtrace request : %u\n", rx_stats
.mtrace_req
);
1378 vty_out(vty
, "unsupported : %u\n", rx_stats
.unsupported
);
1382 static void pim_show_interfaces(struct pim_instance
*pim
, struct vty
*vty
,
1385 struct interface
*ifp
;
1386 struct pim_interface
*pim_ifp
;
1387 struct pim_upstream
*up
;
1390 int pim_ifchannels
= 0;
1391 json_object
*json
= NULL
;
1392 json_object
*json_row
= NULL
;
1393 json_object
*json_tmp
;
1395 json
= json_object_new_object();
1397 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1398 pim_ifp
= ifp
->info
;
1403 pim_nbrs
= pim_ifp
->pim_neighbor_list
->count
;
1404 pim_ifchannels
= pim_if_ifchannel_count(pim_ifp
);
1407 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
)
1408 if (ifp
== up
->rpf
.source_nexthop
.interface
)
1409 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
1412 json_row
= json_object_new_object();
1413 json_object_pim_ifp_add(json_row
, ifp
);
1414 json_object_int_add(json_row
, "pimNeighbors", pim_nbrs
);
1415 json_object_int_add(json_row
, "pimIfChannels", pim_ifchannels
);
1416 json_object_int_add(json_row
, "firstHopRouterCount", fhr
);
1417 json_object_string_add(json_row
, "pimDesignatedRouter",
1418 inet_ntoa(pim_ifp
->pim_dr_addr
));
1420 if (pim_ifp
->pim_dr_addr
.s_addr
1421 == pim_ifp
->primary_address
.s_addr
)
1422 json_object_boolean_true_add(
1423 json_row
, "pimDesignatedRouterLocal");
1425 json_object_object_add(json
, ifp
->name
, json_row
);
1429 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1430 json
, JSON_C_TO_STRING_PRETTY
));
1433 "Interface State Address PIM Nbrs PIM DR FHR IfChannels\n");
1435 json_object_object_foreach(json
, key
, val
)
1437 vty_out(vty
, "%-16s ", key
);
1439 json_object_object_get_ex(val
, "state", &json_tmp
);
1440 vty_out(vty
, "%5s ", json_object_get_string(json_tmp
));
1442 json_object_object_get_ex(val
, "address", &json_tmp
);
1443 vty_out(vty
, "%15s ",
1444 json_object_get_string(json_tmp
));
1446 json_object_object_get_ex(val
, "pimNeighbors",
1448 vty_out(vty
, "%8d ", json_object_get_int(json_tmp
));
1450 if (json_object_object_get_ex(
1451 val
, "pimDesignatedRouterLocal",
1453 vty_out(vty
, "%15s ", "local");
1455 json_object_object_get_ex(
1456 val
, "pimDesignatedRouter", &json_tmp
);
1457 vty_out(vty
, "%15s ",
1458 json_object_get_string(json_tmp
));
1461 json_object_object_get_ex(val
, "firstHopRouter",
1463 vty_out(vty
, "%3d ", json_object_get_int(json_tmp
));
1465 json_object_object_get_ex(val
, "pimIfChannels",
1467 vty_out(vty
, "%9d\n", json_object_get_int(json_tmp
));
1471 json_object_free(json
);
1474 static void pim_show_interface_traffic(struct pim_instance
*pim
,
1475 struct vty
*vty
, bool uj
)
1477 struct interface
*ifp
= NULL
;
1478 struct pim_interface
*pim_ifp
= NULL
;
1479 json_object
*json
= NULL
;
1480 json_object
*json_row
= NULL
;
1483 json
= json_object_new_object();
1486 vty_out(vty
, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s%-17s\n",
1487 "Interface", " HELLO", " JOIN",
1488 " PRUNE", " REGISTER", "REGISTER-STOP",
1490 vty_out(vty
, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s%-17s\n", "",
1491 " Rx/Tx", " Rx/Tx", " Rx/Tx",
1492 " Rx/Tx", " Rx/Tx", " Rx/Tx",
1495 "---------------------------------------------------------------------------------------------------------------\n");
1498 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1499 pim_ifp
= ifp
->info
;
1504 if (pim_ifp
->pim_sock_fd
< 0)
1507 json_row
= json_object_new_object();
1508 json_object_pim_ifp_add(json_row
, ifp
);
1509 json_object_int_add(json_row
, "helloRx",
1510 pim_ifp
->pim_ifstat_hello_recv
);
1511 json_object_int_add(json_row
, "helloTx",
1512 pim_ifp
->pim_ifstat_hello_sent
);
1513 json_object_int_add(json_row
, "joinRx",
1514 pim_ifp
->pim_ifstat_join_recv
);
1515 json_object_int_add(json_row
, "joinTx",
1516 pim_ifp
->pim_ifstat_join_send
);
1517 json_object_int_add(json_row
, "registerRx",
1518 pim_ifp
->pim_ifstat_reg_recv
);
1519 json_object_int_add(json_row
, "registerTx",
1520 pim_ifp
->pim_ifstat_reg_recv
);
1521 json_object_int_add(json_row
, "registerStopRx",
1522 pim_ifp
->pim_ifstat_reg_stop_recv
);
1523 json_object_int_add(json_row
, "registerStopTx",
1524 pim_ifp
->pim_ifstat_reg_stop_send
);
1525 json_object_int_add(json_row
, "assertRx",
1526 pim_ifp
->pim_ifstat_assert_recv
);
1527 json_object_int_add(json_row
, "assertTx",
1528 pim_ifp
->pim_ifstat_assert_send
);
1529 json_object_int_add(json_row
, "bsmRx",
1530 pim_ifp
->pim_ifstat_bsm_rx
);
1531 json_object_int_add(json_row
, "bsmTx",
1532 pim_ifp
->pim_ifstat_bsm_tx
);
1533 json_object_object_add(json
, ifp
->name
, json_row
);
1536 "%-16s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7" PRIu64
"/%-7" PRIu64
"\n",
1537 ifp
->name
, pim_ifp
->pim_ifstat_hello_recv
,
1538 pim_ifp
->pim_ifstat_hello_sent
,
1539 pim_ifp
->pim_ifstat_join_recv
,
1540 pim_ifp
->pim_ifstat_join_send
,
1541 pim_ifp
->pim_ifstat_prune_recv
,
1542 pim_ifp
->pim_ifstat_prune_send
,
1543 pim_ifp
->pim_ifstat_reg_recv
,
1544 pim_ifp
->pim_ifstat_reg_send
,
1545 pim_ifp
->pim_ifstat_reg_stop_recv
,
1546 pim_ifp
->pim_ifstat_reg_stop_send
,
1547 pim_ifp
->pim_ifstat_assert_recv
,
1548 pim_ifp
->pim_ifstat_assert_send
,
1549 pim_ifp
->pim_ifstat_bsm_rx
,
1550 pim_ifp
->pim_ifstat_bsm_tx
);
1554 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1555 json
, JSON_C_TO_STRING_PRETTY
));
1556 json_object_free(json
);
1560 static void pim_show_interface_traffic_single(struct pim_instance
*pim
,
1562 const char *ifname
, bool uj
)
1564 struct interface
*ifp
= NULL
;
1565 struct pim_interface
*pim_ifp
= NULL
;
1566 json_object
*json
= NULL
;
1567 json_object
*json_row
= NULL
;
1568 uint8_t found_ifname
= 0;
1571 json
= json_object_new_object();
1574 vty_out(vty
, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s%-17s\n",
1575 "Interface", " HELLO", " JOIN", " PRUNE",
1576 " REGISTER", " REGISTER-STOP", " ASSERT",
1578 vty_out(vty
, "%-14s%-18s%-17s%-17s%-17s%-17s%-17s%-17s\n", "",
1579 " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1580 " Rx/Tx", " Rx/Tx", " Rx/Tx");
1582 "-------------------------------------------------------------------------------------------------------------------------------\n");
1585 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1586 if (strcmp(ifname
, ifp
->name
))
1589 pim_ifp
= ifp
->info
;
1594 if (pim_ifp
->pim_sock_fd
< 0)
1599 json_row
= json_object_new_object();
1600 json_object_pim_ifp_add(json_row
, ifp
);
1601 json_object_int_add(json_row
, "helloRx",
1602 pim_ifp
->pim_ifstat_hello_recv
);
1603 json_object_int_add(json_row
, "helloTx",
1604 pim_ifp
->pim_ifstat_hello_sent
);
1605 json_object_int_add(json_row
, "joinRx",
1606 pim_ifp
->pim_ifstat_join_recv
);
1607 json_object_int_add(json_row
, "joinTx",
1608 pim_ifp
->pim_ifstat_join_send
);
1609 json_object_int_add(json_row
, "registerRx",
1610 pim_ifp
->pim_ifstat_reg_recv
);
1611 json_object_int_add(json_row
, "registerTx",
1612 pim_ifp
->pim_ifstat_reg_recv
);
1613 json_object_int_add(json_row
, "registerStopRx",
1614 pim_ifp
->pim_ifstat_reg_stop_recv
);
1615 json_object_int_add(json_row
, "registerStopTx",
1616 pim_ifp
->pim_ifstat_reg_stop_send
);
1617 json_object_int_add(json_row
, "assertRx",
1618 pim_ifp
->pim_ifstat_assert_recv
);
1619 json_object_int_add(json_row
, "assertTx",
1620 pim_ifp
->pim_ifstat_assert_send
);
1621 json_object_int_add(json_row
, "bsmRx",
1622 pim_ifp
->pim_ifstat_bsm_rx
);
1623 json_object_int_add(json_row
, "bsmTx",
1624 pim_ifp
->pim_ifstat_bsm_tx
);
1626 json_object_object_add(json
, ifp
->name
, json_row
);
1629 "%-16s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7" PRIu64
"/%-7" PRIu64
"\n",
1630 ifp
->name
, pim_ifp
->pim_ifstat_hello_recv
,
1631 pim_ifp
->pim_ifstat_hello_sent
,
1632 pim_ifp
->pim_ifstat_join_recv
,
1633 pim_ifp
->pim_ifstat_join_send
,
1634 pim_ifp
->pim_ifstat_prune_recv
,
1635 pim_ifp
->pim_ifstat_prune_send
,
1636 pim_ifp
->pim_ifstat_reg_recv
,
1637 pim_ifp
->pim_ifstat_reg_send
,
1638 pim_ifp
->pim_ifstat_reg_stop_recv
,
1639 pim_ifp
->pim_ifstat_reg_stop_send
,
1640 pim_ifp
->pim_ifstat_assert_recv
,
1641 pim_ifp
->pim_ifstat_assert_send
,
1642 pim_ifp
->pim_ifstat_bsm_rx
,
1643 pim_ifp
->pim_ifstat_bsm_tx
);
1647 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1648 json
, JSON_C_TO_STRING_PRETTY
));
1649 json_object_free(json
);
1652 vty_out(vty
, "%% No such interface\n");
1656 static void pim_show_join_helper(struct vty
*vty
, struct pim_interface
*pim_ifp
,
1657 struct pim_ifchannel
*ch
, json_object
*json
,
1658 time_t now
, bool uj
)
1660 char ch_src_str
[INET_ADDRSTRLEN
];
1661 char ch_grp_str
[INET_ADDRSTRLEN
];
1662 json_object
*json_iface
= NULL
;
1663 json_object
*json_row
= NULL
;
1664 json_object
*json_grp
= NULL
;
1665 struct in_addr ifaddr
;
1670 ifaddr
= pim_ifp
->primary_address
;
1672 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
1673 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
1675 pim_time_uptime_begin(uptime
, sizeof(uptime
), now
, ch
->ifjoin_creation
);
1676 pim_time_timer_to_mmss(expire
, sizeof(expire
),
1677 ch
->t_ifjoin_expiry_timer
);
1678 pim_time_timer_to_mmss(prune
, sizeof(prune
),
1679 ch
->t_ifjoin_prune_pending_timer
);
1682 json_object_object_get_ex(json
, ch
->interface
->name
,
1686 json_iface
= json_object_new_object();
1687 json_object_pim_ifp_add(json_iface
, ch
->interface
);
1688 json_object_object_add(json
, ch
->interface
->name
,
1692 json_row
= json_object_new_object();
1693 json_object_string_add(json_row
, "source", ch_src_str
);
1694 json_object_string_add(json_row
, "group", ch_grp_str
);
1695 json_object_string_add(json_row
, "upTime", uptime
);
1696 json_object_string_add(json_row
, "expire", expire
);
1697 json_object_string_add(json_row
, "prune", prune
);
1698 json_object_string_add(
1699 json_row
, "channelJoinName",
1700 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
, ch
->flags
));
1701 if (PIM_IF_FLAG_TEST_S_G_RPT(ch
->flags
))
1702 json_object_int_add(json_row
, "SGRpt", 1);
1704 json_object_object_get_ex(json_iface
, ch_grp_str
, &json_grp
);
1706 json_grp
= json_object_new_object();
1707 json_object_object_add(json_grp
, ch_src_str
, json_row
);
1708 json_object_object_add(json_iface
, ch_grp_str
,
1711 json_object_object_add(json_grp
, ch_src_str
, json_row
);
1713 vty_out(vty
, "%-16s %-15s %-15s %-15s %-10s %8s %-6s %5s\n",
1714 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
,
1716 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
, ch
->flags
),
1717 uptime
, expire
, prune
);
1721 static void pim_show_join(struct pim_instance
*pim
, struct vty
*vty
,
1722 struct prefix_sg
*sg
, bool uj
)
1724 struct pim_interface
*pim_ifp
;
1725 struct pim_ifchannel
*ch
;
1726 struct interface
*ifp
;
1728 json_object
*json
= NULL
;
1730 now
= pim_time_monotonic_sec();
1733 json
= json_object_new_object();
1736 "Interface Address Source Group State Uptime Expire Prune\n");
1738 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1739 pim_ifp
= ifp
->info
;
1743 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
1744 if (sg
->grp
.s_addr
!= INADDR_ANY
1745 && sg
->grp
.s_addr
!= ch
->sg
.grp
.s_addr
)
1747 if (sg
->src
.s_addr
!= INADDR_ANY
1748 && sg
->src
.s_addr
!= ch
->sg
.src
.s_addr
)
1750 pim_show_join_helper(vty
, pim_ifp
, ch
, json
, now
, uj
);
1751 } /* scan interface channels */
1755 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1756 json
, JSON_C_TO_STRING_PRETTY
));
1757 json_object_free(json
);
1761 static void pim_show_neighbors_single(struct pim_instance
*pim
, struct vty
*vty
,
1762 const char *neighbor
, bool uj
)
1764 struct listnode
*neighnode
;
1765 struct interface
*ifp
;
1766 struct pim_interface
*pim_ifp
;
1767 struct pim_neighbor
*neigh
;
1769 int found_neighbor
= 0;
1770 int option_address_list
;
1771 int option_dr_priority
;
1772 int option_generation_id
;
1773 int option_holdtime
;
1774 int option_lan_prune_delay
;
1778 char neigh_src_str
[INET_ADDRSTRLEN
];
1780 json_object
*json
= NULL
;
1781 json_object
*json_ifp
= NULL
;
1782 json_object
*json_row
= NULL
;
1784 now
= pim_time_monotonic_sec();
1787 json
= json_object_new_object();
1789 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1790 pim_ifp
= ifp
->info
;
1795 if (pim_ifp
->pim_sock_fd
< 0)
1798 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
1800 pim_inet4_dump("<src?>", neigh
->source_addr
,
1801 neigh_src_str
, sizeof(neigh_src_str
));
1804 * The user can specify either the interface name or the
1806 * If this pim_ifp matches neither then skip.
1808 if (strcmp(neighbor
, "detail")
1809 && strcmp(neighbor
, ifp
->name
)
1810 && strcmp(neighbor
, neigh_src_str
))
1814 pim_time_uptime(uptime
, sizeof(uptime
),
1815 now
- neigh
->creation
);
1816 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
1817 neigh
->t_expire_timer
);
1819 option_address_list
= 0;
1820 option_dr_priority
= 0;
1821 option_generation_id
= 0;
1822 option_holdtime
= 0;
1823 option_lan_prune_delay
= 0;
1826 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1827 PIM_OPTION_MASK_ADDRESS_LIST
))
1828 option_address_list
= 1;
1830 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1831 PIM_OPTION_MASK_DR_PRIORITY
))
1832 option_dr_priority
= 1;
1834 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1835 PIM_OPTION_MASK_GENERATION_ID
))
1836 option_generation_id
= 1;
1838 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1839 PIM_OPTION_MASK_HOLDTIME
))
1840 option_holdtime
= 1;
1842 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1843 PIM_OPTION_MASK_LAN_PRUNE_DELAY
))
1844 option_lan_prune_delay
= 1;
1846 if (PIM_OPTION_IS_SET(
1847 neigh
->hello_options
,
1848 PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION
))
1853 /* Does this ifp live in json? If not create
1855 json_object_object_get_ex(json
, ifp
->name
,
1859 json_ifp
= json_object_new_object();
1860 json_object_pim_ifp_add(json_ifp
, ifp
);
1861 json_object_object_add(json
, ifp
->name
,
1865 json_row
= json_object_new_object();
1866 json_object_string_add(json_row
, "interface",
1868 json_object_string_add(json_row
, "address",
1870 json_object_string_add(json_row
, "upTime",
1872 json_object_string_add(json_row
, "holdtime",
1874 json_object_int_add(json_row
, "drPriority",
1875 neigh
->dr_priority
);
1876 json_object_int_add(json_row
, "generationId",
1877 neigh
->generation_id
);
1879 if (option_address_list
)
1880 json_object_boolean_true_add(
1882 "helloOptionAddressList");
1884 if (option_dr_priority
)
1885 json_object_boolean_true_add(
1887 "helloOptionDrPriority");
1889 if (option_generation_id
)
1890 json_object_boolean_true_add(
1892 "helloOptionGenerationId");
1894 if (option_holdtime
)
1895 json_object_boolean_true_add(
1897 "helloOptionHoldtime");
1899 if (option_lan_prune_delay
)
1900 json_object_boolean_true_add(
1902 "helloOptionLanPruneDelay");
1905 json_object_boolean_true_add(
1906 json_row
, "helloOptionTBit");
1908 json_object_object_add(json_ifp
, neigh_src_str
,
1912 vty_out(vty
, "Interface : %s\n", ifp
->name
);
1913 vty_out(vty
, "Neighbor : %s\n", neigh_src_str
);
1921 " DR Priority : %d\n",
1922 neigh
->dr_priority
);
1924 " Generation ID : %08x\n",
1925 neigh
->generation_id
);
1927 " Override Interval (msec) : %d\n",
1928 neigh
->override_interval_msec
);
1930 " Propagation Delay (msec) : %d\n",
1931 neigh
->propagation_delay_msec
);
1933 " Hello Option - Address List : %s\n",
1934 option_address_list
? "yes" : "no");
1936 " Hello Option - DR Priority : %s\n",
1937 option_dr_priority
? "yes" : "no");
1939 " Hello Option - Generation ID : %s\n",
1940 option_generation_id
? "yes" : "no");
1942 " Hello Option - Holdtime : %s\n",
1943 option_holdtime
? "yes" : "no");
1945 " Hello Option - LAN Prune Delay : %s\n",
1946 option_lan_prune_delay
? "yes" : "no");
1948 " Hello Option - T-bit : %s\n",
1949 option_t_bit
? "yes" : "no");
1950 pim_bfd_show_info(vty
, neigh
->bfd_info
,
1958 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1959 json
, JSON_C_TO_STRING_PRETTY
));
1960 json_object_free(json
);
1963 if (!found_neighbor
)
1965 "%% No such interface or neighbor\n");
1970 static void pim_show_state(struct pim_instance
*pim
, struct vty
*vty
,
1971 const char *src_or_group
, const char *group
, bool uj
)
1973 struct channel_oil
*c_oil
;
1974 json_object
*json
= NULL
;
1975 json_object
*json_group
= NULL
;
1976 json_object
*json_ifp_in
= NULL
;
1977 json_object
*json_ifp_out
= NULL
;
1978 json_object
*json_source
= NULL
;
1981 now
= pim_time_monotonic_sec();
1984 json
= json_object_new_object();
1987 "Codes: J -> Pim Join, I -> IGMP Report, S -> Source, * -> Inherited from (*,G), V -> VxLAN, M -> Muted");
1989 "\nActive Source Group RPT IIF OIL\n");
1992 frr_each (rb_pim_oil
, &pim
->channel_oil_head
, c_oil
) {
1993 char grp_str
[INET_ADDRSTRLEN
];
1994 char src_str
[INET_ADDRSTRLEN
];
1995 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
1996 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
1998 struct interface
*ifp_in
;
2003 PIM_UPSTREAM_FLAG_TEST_USE_RPT(c_oil
->up
->flags
)) ||
2004 c_oil
->oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
2009 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
2011 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
2013 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
2016 strlcpy(in_ifname
, ifp_in
->name
, sizeof(in_ifname
));
2018 strlcpy(in_ifname
, "<iif?>", sizeof(in_ifname
));
2021 if (strcmp(src_or_group
, src_str
)
2022 && strcmp(src_or_group
, grp_str
))
2025 if (group
&& strcmp(group
, grp_str
))
2031 /* Find the group, create it if it doesn't exist */
2032 json_object_object_get_ex(json
, grp_str
, &json_group
);
2035 json_group
= json_object_new_object();
2036 json_object_object_add(json
, grp_str
,
2040 /* Find the source nested under the group, create it if
2041 * it doesn't exist */
2042 json_object_object_get_ex(json_group
, src_str
,
2046 json_source
= json_object_new_object();
2047 json_object_object_add(json_group
, src_str
,
2051 /* Find the inbound interface nested under the source,
2052 * create it if it doesn't exist */
2053 json_object_object_get_ex(json_source
, in_ifname
,
2057 json_ifp_in
= json_object_new_object();
2058 json_object_object_add(json_source
, in_ifname
,
2060 json_object_int_add(json_source
, "Installed",
2063 json_object_boolean_true_add(
2064 json_source
, "isRpt");
2066 json_object_boolean_false_add(
2067 json_source
, "isRpt");
2068 json_object_int_add(json_source
, "RefCount",
2069 c_oil
->oil_ref_count
);
2070 json_object_int_add(json_source
, "OilListSize",
2072 json_object_int_add(
2073 json_source
, "OilRescan",
2074 c_oil
->oil_inherited_rescan
);
2075 json_object_int_add(json_source
, "LastUsed",
2076 c_oil
->cc
.lastused
);
2077 json_object_int_add(json_source
, "PacketCount",
2079 json_object_int_add(json_source
, "ByteCount",
2081 json_object_int_add(json_source
,
2083 c_oil
->cc
.wrong_if
);
2086 vty_out(vty
, "%-6d %-15s %-15s %-3s %-16s ",
2087 c_oil
->installed
, src_str
, grp_str
,
2088 isRpt
? "y" : "n", in_ifname
);
2091 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
2093 struct interface
*ifp_out
;
2094 char oif_uptime
[10];
2097 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
2101 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
2103 oif_uptime
, sizeof(oif_uptime
),
2104 now
- c_oil
->oif_creation
[oif_vif_index
]);
2107 strlcpy(out_ifname
, ifp_out
->name
, sizeof(out_ifname
));
2109 strlcpy(out_ifname
, "<oif?>", sizeof(out_ifname
));
2112 json_ifp_out
= json_object_new_object();
2113 json_object_string_add(json_ifp_out
, "source",
2115 json_object_string_add(json_ifp_out
, "group",
2117 json_object_string_add(json_ifp_out
,
2120 json_object_string_add(json_ifp_out
,
2121 "outboundInterface",
2123 json_object_int_add(json_ifp_out
, "installed",
2126 json_object_object_add(json_ifp_in
, out_ifname
,
2131 vty_out(vty
, "%s(%c%c%c%c%c)",
2133 (c_oil
->oif_flags
[oif_vif_index
]
2134 & PIM_OIF_FLAG_PROTO_IGMP
)
2137 (c_oil
->oif_flags
[oif_vif_index
]
2138 & PIM_OIF_FLAG_PROTO_PIM
)
2141 (c_oil
->oif_flags
[oif_vif_index
]
2142 & PIM_OIF_FLAG_PROTO_VXLAN
)
2145 (c_oil
->oif_flags
[oif_vif_index
]
2146 & PIM_OIF_FLAG_PROTO_STAR
)
2149 (c_oil
->oif_flags
[oif_vif_index
]
2150 & PIM_OIF_FLAG_MUTE
)
2154 vty_out(vty
, ", %s(%c%c%c%c%c)",
2156 (c_oil
->oif_flags
[oif_vif_index
]
2157 & PIM_OIF_FLAG_PROTO_IGMP
)
2160 (c_oil
->oif_flags
[oif_vif_index
]
2161 & PIM_OIF_FLAG_PROTO_PIM
)
2164 (c_oil
->oif_flags
[oif_vif_index
]
2165 & PIM_OIF_FLAG_PROTO_VXLAN
)
2168 (c_oil
->oif_flags
[oif_vif_index
]
2169 & PIM_OIF_FLAG_PROTO_STAR
)
2172 (c_oil
->oif_flags
[oif_vif_index
]
2173 & PIM_OIF_FLAG_MUTE
)
2185 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2186 json
, JSON_C_TO_STRING_PRETTY
));
2187 json_object_free(json
);
2193 static void pim_show_neighbors(struct pim_instance
*pim
, struct vty
*vty
,
2196 struct listnode
*neighnode
;
2197 struct interface
*ifp
;
2198 struct pim_interface
*pim_ifp
;
2199 struct pim_neighbor
*neigh
;
2203 char neigh_src_str
[INET_ADDRSTRLEN
];
2204 json_object
*json
= NULL
;
2205 json_object
*json_ifp_rows
= NULL
;
2206 json_object
*json_row
= NULL
;
2208 now
= pim_time_monotonic_sec();
2211 json
= json_object_new_object();
2214 "Interface Neighbor Uptime Holdtime DR Pri\n");
2217 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2218 pim_ifp
= ifp
->info
;
2223 if (pim_ifp
->pim_sock_fd
< 0)
2227 json_ifp_rows
= json_object_new_object();
2229 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
2231 pim_inet4_dump("<src?>", neigh
->source_addr
,
2232 neigh_src_str
, sizeof(neigh_src_str
));
2233 pim_time_uptime(uptime
, sizeof(uptime
),
2234 now
- neigh
->creation
);
2235 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
2236 neigh
->t_expire_timer
);
2239 json_row
= json_object_new_object();
2240 json_object_string_add(json_row
, "interface",
2242 json_object_string_add(json_row
, "neighbor",
2244 json_object_string_add(json_row
, "upTime",
2246 json_object_string_add(json_row
, "holdTime",
2248 json_object_int_add(json_row
, "holdTimeMax",
2250 json_object_int_add(json_row
, "drPriority",
2251 neigh
->dr_priority
);
2252 json_object_object_add(json_ifp_rows
,
2253 neigh_src_str
, json_row
);
2256 vty_out(vty
, "%-16s %15s %8s %8s %6d\n",
2257 ifp
->name
, neigh_src_str
, uptime
,
2258 expire
, neigh
->dr_priority
);
2263 json_object_object_add(json
, ifp
->name
, json_ifp_rows
);
2264 json_ifp_rows
= NULL
;
2269 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2270 json
, JSON_C_TO_STRING_PRETTY
));
2271 json_object_free(json
);
2275 static void pim_show_neighbors_secondary(struct pim_instance
*pim
,
2278 struct interface
*ifp
;
2281 "Interface Address Neighbor Secondary \n");
2283 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2284 struct pim_interface
*pim_ifp
;
2285 struct in_addr ifaddr
;
2286 struct listnode
*neighnode
;
2287 struct pim_neighbor
*neigh
;
2289 pim_ifp
= ifp
->info
;
2294 if (pim_ifp
->pim_sock_fd
< 0)
2297 ifaddr
= pim_ifp
->primary_address
;
2299 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
2301 char neigh_src_str
[INET_ADDRSTRLEN
];
2302 struct listnode
*prefix_node
;
2305 if (!neigh
->prefix_list
)
2308 pim_inet4_dump("<src?>", neigh
->source_addr
,
2309 neigh_src_str
, sizeof(neigh_src_str
));
2311 for (ALL_LIST_ELEMENTS_RO(neigh
->prefix_list
,
2313 char neigh_sec_str
[PREFIX2STR_BUFFER
];
2315 prefix2str(p
, neigh_sec_str
,
2316 sizeof(neigh_sec_str
));
2318 vty_out(vty
, "%-16s %-15s %-15s %-15s\n",
2319 ifp
->name
, inet_ntoa(ifaddr
),
2320 neigh_src_str
, neigh_sec_str
);
2326 static void json_object_pim_upstream_add(json_object
*json
,
2327 struct pim_upstream
*up
)
2329 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED
)
2330 json_object_boolean_true_add(json
, "drJoinDesired");
2332 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED
)
2333 json_object_boolean_true_add(json
, "drJoinDesiredUpdated");
2335 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
2336 json_object_boolean_true_add(json
, "firstHopRouter");
2338 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_IGMP
)
2339 json_object_boolean_true_add(json
, "sourceIgmp");
2341 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_PIM
)
2342 json_object_boolean_true_add(json
, "sourcePim");
2344 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_STREAM
)
2345 json_object_boolean_true_add(json
, "sourceStream");
2347 /* XXX: need to print ths flag in the plain text display as well */
2348 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_MSDP
)
2349 json_object_boolean_true_add(json
, "sourceMsdp");
2351 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SEND_SG_RPT_PRUNE
)
2352 json_object_boolean_true_add(json
, "sendSGRptPrune");
2354 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_LHR
)
2355 json_object_boolean_true_add(json
, "lastHopRouter");
2357 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DISABLE_KAT_EXPIRY
)
2358 json_object_boolean_true_add(json
, "disableKATExpiry");
2360 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_STATIC_IIF
)
2361 json_object_boolean_true_add(json
, "staticIncomingInterface");
2363 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_ALLOW_IIF_IN_OIL
)
2364 json_object_boolean_true_add(json
,
2365 "allowIncomingInterfaceinOil");
2367 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_NO_PIMREG_DATA
)
2368 json_object_boolean_true_add(json
, "noPimRegistrationData");
2370 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FORCE_PIMREG
)
2371 json_object_boolean_true_add(json
, "forcePimRegistration");
2373 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_ORIG
)
2374 json_object_boolean_true_add(json
, "sourceVxlanOrigination");
2376 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_TERM
)
2377 json_object_boolean_true_add(json
, "sourceVxlanTermination");
2379 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_VXLAN
)
2380 json_object_boolean_true_add(json
, "mlagVxlan");
2382 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_NON_DF
)
2383 json_object_boolean_true_add(json
,
2384 "mlagNonDesignatedForwarder");
2388 pim_upstream_state2brief_str(enum pim_upstream_state join_state
,
2389 char *state_str
, size_t state_str_len
)
2391 switch (join_state
) {
2392 case PIM_UPSTREAM_NOTJOINED
:
2393 strlcpy(state_str
, "NotJ", state_str_len
);
2395 case PIM_UPSTREAM_JOINED
:
2396 strlcpy(state_str
, "J", state_str_len
);
2399 strlcpy(state_str
, "Unk", state_str_len
);
2404 static const char *pim_reg_state2brief_str(enum pim_reg_state reg_state
,
2405 char *state_str
, size_t state_str_len
)
2407 switch (reg_state
) {
2408 case PIM_REG_NOINFO
:
2409 strlcpy(state_str
, "RegNI", state_str_len
);
2412 strlcpy(state_str
, "RegJ", state_str_len
);
2414 case PIM_REG_JOIN_PENDING
:
2416 strlcpy(state_str
, "RegP", state_str_len
);
2419 strlcpy(state_str
, "Unk", state_str_len
);
2424 static void pim_show_upstream(struct pim_instance
*pim
, struct vty
*vty
,
2425 struct prefix_sg
*sg
, bool uj
)
2427 struct pim_upstream
*up
;
2429 json_object
*json
= NULL
;
2430 json_object
*json_group
= NULL
;
2431 json_object
*json_row
= NULL
;
2433 now
= pim_time_monotonic_sec();
2436 json
= json_object_new_object();
2439 "Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt\n");
2441 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
2442 char src_str
[INET_ADDRSTRLEN
];
2443 char grp_str
[INET_ADDRSTRLEN
];
2445 char join_timer
[10];
2448 char msdp_reg_timer
[10];
2449 char state_str
[PIM_REG_STATE_STR_LEN
];
2451 if (sg
->grp
.s_addr
!= INADDR_ANY
2452 && sg
->grp
.s_addr
!= up
->sg
.grp
.s_addr
)
2454 if (sg
->src
.s_addr
!= INADDR_ANY
2455 && sg
->src
.s_addr
!= up
->sg
.src
.s_addr
)
2458 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2459 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2460 pim_time_uptime(uptime
, sizeof(uptime
),
2461 now
- up
->state_transition
);
2462 pim_time_timer_to_hhmmss(join_timer
, sizeof(join_timer
),
2466 * If the upstream is not dummy and it has a J/P timer for the
2467 * neighbor display that
2469 if (!up
->t_join_timer
&& up
->rpf
.source_nexthop
.interface
) {
2470 struct pim_neighbor
*nbr
;
2472 nbr
= pim_neighbor_find(
2473 up
->rpf
.source_nexthop
.interface
,
2474 up
->rpf
.rpf_addr
.u
.prefix4
);
2476 pim_time_timer_to_hhmmss(join_timer
,
2481 pim_time_timer_to_hhmmss(rs_timer
, sizeof(rs_timer
),
2483 pim_time_timer_to_hhmmss(ka_timer
, sizeof(ka_timer
),
2485 pim_time_timer_to_hhmmss(msdp_reg_timer
, sizeof(msdp_reg_timer
),
2486 up
->t_msdp_reg_timer
);
2488 pim_upstream_state2brief_str(up
->join_state
, state_str
, sizeof(state_str
));
2489 if (up
->reg_state
!= PIM_REG_NOINFO
) {
2490 char tmp_str
[PIM_REG_STATE_STR_LEN
];
2492 sprintf(state_str
+ strlen(state_str
), ",%s",
2493 pim_reg_state2brief_str(up
->reg_state
, tmp_str
,
2498 json_object_object_get_ex(json
, grp_str
, &json_group
);
2501 json_group
= json_object_new_object();
2502 json_object_object_add(json
, grp_str
,
2506 json_row
= json_object_new_object();
2507 json_object_pim_upstream_add(json_row
, up
);
2508 json_object_string_add(
2509 json_row
, "inboundInterface",
2510 up
->rpf
.source_nexthop
.interface
2511 ? up
->rpf
.source_nexthop
.interface
->name
2515 * The RPF address we use is slightly different
2516 * based upon what we are looking up.
2517 * If we have a S, list that unless
2518 * we are the FHR, else we just put
2519 * the RP as the rpfAddress
2521 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
2522 || up
->sg
.src
.s_addr
== INADDR_ANY
) {
2523 char rpf
[PREFIX_STRLEN
];
2524 struct pim_rpf
*rpg
;
2526 rpg
= RP(pim
, up
->sg
.grp
);
2527 pim_inet4_dump("<rpf?>",
2528 rpg
->rpf_addr
.u
.prefix4
, rpf
,
2530 json_object_string_add(json_row
, "rpfAddress",
2533 json_object_string_add(json_row
, "rpfAddress",
2537 json_object_string_add(json_row
, "source", src_str
);
2538 json_object_string_add(json_row
, "group", grp_str
);
2539 json_object_string_add(json_row
, "state", state_str
);
2540 json_object_string_add(
2541 json_row
, "joinState",
2542 pim_upstream_state2str(up
->join_state
));
2543 json_object_string_add(
2544 json_row
, "regState",
2545 pim_reg_state2str(up
->reg_state
, state_str
, sizeof(state_str
)));
2546 json_object_string_add(json_row
, "upTime", uptime
);
2547 json_object_string_add(json_row
, "joinTimer",
2549 json_object_string_add(json_row
, "resetTimer",
2551 json_object_string_add(json_row
, "keepaliveTimer",
2553 json_object_string_add(json_row
, "msdpRegTimer",
2555 json_object_int_add(json_row
, "refCount",
2557 json_object_int_add(json_row
, "sptBit", up
->sptbit
);
2558 json_object_object_add(json_group
, src_str
, json_row
);
2561 "%-16s%-15s %-15s %-11s %-8s %-9s %-9s %-9s %6d\n",
2562 up
->rpf
.source_nexthop
.interface
2563 ? up
->rpf
.source_nexthop
.interface
->name
2565 src_str
, grp_str
, state_str
, uptime
, join_timer
,
2566 rs_timer
, ka_timer
, up
->ref_count
);
2571 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2572 json
, JSON_C_TO_STRING_PRETTY
));
2573 json_object_free(json
);
2577 static void pim_show_channel_helper(struct pim_instance
*pim
,
2579 struct pim_interface
*pim_ifp
,
2580 struct pim_ifchannel
*ch
,
2581 json_object
*json
, bool uj
)
2583 struct pim_upstream
*up
= ch
->upstream
;
2584 json_object
*json_group
= NULL
;
2585 char src_str
[INET_ADDRSTRLEN
];
2586 char grp_str
[INET_ADDRSTRLEN
];
2587 json_object
*json_row
= NULL
;
2589 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2590 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2593 json_object_object_get_ex(json
, grp_str
, &json_group
);
2596 json_group
= json_object_new_object();
2597 json_object_object_add(json
, grp_str
, json_group
);
2600 json_row
= json_object_new_object();
2601 json_object_pim_upstream_add(json_row
, up
);
2602 json_object_string_add(json_row
, "interface",
2603 ch
->interface
->name
);
2604 json_object_string_add(json_row
, "source", src_str
);
2605 json_object_string_add(json_row
, "group", grp_str
);
2607 if (pim_macro_ch_lost_assert(ch
))
2608 json_object_boolean_true_add(json_row
, "lostAssert");
2610 if (pim_macro_chisin_joins(ch
))
2611 json_object_boolean_true_add(json_row
, "joins");
2613 if (pim_macro_chisin_pim_include(ch
))
2614 json_object_boolean_true_add(json_row
, "pimInclude");
2616 if (pim_upstream_evaluate_join_desired(pim
, up
))
2617 json_object_boolean_true_add(json_row
,
2618 "evaluateJoinDesired");
2620 json_object_object_add(json_group
, src_str
, json_row
);
2623 vty_out(vty
, "%-16s %-15s %-15s %-10s %-5s %-10s %-11s %-6s\n",
2624 ch
->interface
->name
, src_str
, grp_str
,
2625 pim_macro_ch_lost_assert(ch
) ? "yes" : "no",
2626 pim_macro_chisin_joins(ch
) ? "yes" : "no",
2627 pim_macro_chisin_pim_include(ch
) ? "yes" : "no",
2628 PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(up
->flags
)
2631 pim_upstream_evaluate_join_desired(pim
, up
) ? "yes"
2636 static void pim_show_channel(struct pim_instance
*pim
, struct vty
*vty
,
2639 struct pim_interface
*pim_ifp
;
2640 struct pim_ifchannel
*ch
;
2641 struct interface
*ifp
;
2643 json_object
*json
= NULL
;
2646 json
= json_object_new_object();
2649 "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD\n");
2651 /* scan per-interface (S,G) state */
2652 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2653 pim_ifp
= ifp
->info
;
2658 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
2659 /* scan all interfaces */
2660 pim_show_channel_helper(pim
, vty
, pim_ifp
, ch
,
2666 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2667 json
, JSON_C_TO_STRING_PRETTY
));
2668 json_object_free(json
);
2672 static void pim_show_join_desired_helper(struct pim_instance
*pim
,
2674 struct pim_upstream
*up
,
2675 json_object
*json
, bool uj
)
2677 json_object
*json_group
= NULL
;
2678 char src_str
[INET_ADDRSTRLEN
];
2679 char grp_str
[INET_ADDRSTRLEN
];
2680 json_object
*json_row
= NULL
;
2682 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2683 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2686 json_object_object_get_ex(json
, grp_str
, &json_group
);
2689 json_group
= json_object_new_object();
2690 json_object_object_add(json
, grp_str
, json_group
);
2693 json_row
= json_object_new_object();
2694 json_object_pim_upstream_add(json_row
, up
);
2695 json_object_string_add(json_row
, "source", src_str
);
2696 json_object_string_add(json_row
, "group", grp_str
);
2698 if (pim_upstream_evaluate_join_desired(pim
, up
))
2699 json_object_boolean_true_add(json_row
,
2700 "evaluateJoinDesired");
2702 json_object_object_add(json_group
, src_str
, json_row
);
2705 vty_out(vty
, "%-15s %-15s %-6s\n",
2707 pim_upstream_evaluate_join_desired(pim
, up
) ? "yes"
2712 static void pim_show_join_desired(struct pim_instance
*pim
, struct vty
*vty
,
2715 struct pim_upstream
*up
;
2717 json_object
*json
= NULL
;
2720 json
= json_object_new_object();
2723 "Source Group EvalJD\n");
2725 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
2726 /* scan all interfaces */
2727 pim_show_join_desired_helper(pim
, vty
, up
,
2732 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2733 json
, JSON_C_TO_STRING_PRETTY
));
2734 json_object_free(json
);
2738 static void pim_show_upstream_rpf(struct pim_instance
*pim
, struct vty
*vty
,
2741 struct pim_upstream
*up
;
2742 json_object
*json
= NULL
;
2743 json_object
*json_group
= NULL
;
2744 json_object
*json_row
= NULL
;
2747 json
= json_object_new_object();
2750 "Source Group RpfIface RibNextHop RpfAddress \n");
2752 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
2753 char src_str
[INET_ADDRSTRLEN
];
2754 char grp_str
[INET_ADDRSTRLEN
];
2755 char rpf_nexthop_str
[PREFIX_STRLEN
];
2756 char rpf_addr_str
[PREFIX_STRLEN
];
2757 struct pim_rpf
*rpf
;
2758 const char *rpf_ifname
;
2762 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2763 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2764 pim_addr_dump("<nexthop?>",
2765 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2766 rpf_nexthop_str
, sizeof(rpf_nexthop_str
));
2767 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2768 sizeof(rpf_addr_str
));
2770 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2773 json_object_object_get_ex(json
, grp_str
, &json_group
);
2776 json_group
= json_object_new_object();
2777 json_object_object_add(json
, grp_str
,
2781 json_row
= json_object_new_object();
2782 json_object_pim_upstream_add(json_row
, up
);
2783 json_object_string_add(json_row
, "source", src_str
);
2784 json_object_string_add(json_row
, "group", grp_str
);
2785 json_object_string_add(json_row
, "rpfInterface",
2787 json_object_string_add(json_row
, "ribNexthop",
2789 json_object_string_add(json_row
, "rpfAddress",
2791 json_object_object_add(json_group
, src_str
, json_row
);
2793 vty_out(vty
, "%-15s %-15s %-16s %-15s %-15s\n", src_str
,
2794 grp_str
, rpf_ifname
, rpf_nexthop_str
,
2800 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2801 json
, JSON_C_TO_STRING_PRETTY
));
2802 json_object_free(json
);
2806 static void show_rpf_refresh_stats(struct vty
*vty
, struct pim_instance
*pim
,
2807 time_t now
, json_object
*json
)
2809 char refresh_uptime
[10];
2811 pim_time_uptime_begin(refresh_uptime
, sizeof(refresh_uptime
), now
,
2812 pim
->rpf_cache_refresh_last
);
2815 json_object_int_add(json
, "rpfCacheRefreshDelayMsecs",
2816 router
->rpf_cache_refresh_delay_msec
);
2817 json_object_int_add(
2818 json
, "rpfCacheRefreshTimer",
2819 pim_time_timer_remain_msec(pim
->rpf_cache_refresher
));
2820 json_object_int_add(json
, "rpfCacheRefreshRequests",
2821 pim
->rpf_cache_refresh_requests
);
2822 json_object_int_add(json
, "rpfCacheRefreshEvents",
2823 pim
->rpf_cache_refresh_events
);
2824 json_object_string_add(json
, "rpfCacheRefreshLast",
2826 json_object_int_add(json
, "nexthopLookups",
2827 pim
->nexthop_lookups
);
2828 json_object_int_add(json
, "nexthopLookupsAvoided",
2829 pim
->nexthop_lookups_avoided
);
2832 "RPF Cache Refresh Delay: %ld msecs\n"
2833 "RPF Cache Refresh Timer: %ld msecs\n"
2834 "RPF Cache Refresh Requests: %lld\n"
2835 "RPF Cache Refresh Events: %lld\n"
2836 "RPF Cache Refresh Last: %s\n"
2837 "Nexthop Lookups: %lld\n"
2838 "Nexthop Lookups Avoided: %lld\n",
2839 router
->rpf_cache_refresh_delay_msec
,
2840 pim_time_timer_remain_msec(pim
->rpf_cache_refresher
),
2841 (long long)pim
->rpf_cache_refresh_requests
,
2842 (long long)pim
->rpf_cache_refresh_events
,
2843 refresh_uptime
, (long long)pim
->nexthop_lookups
,
2844 (long long)pim
->nexthop_lookups_avoided
);
2848 static void show_scan_oil_stats(struct pim_instance
*pim
, struct vty
*vty
,
2851 char uptime_scan_oil
[10];
2852 char uptime_mroute_add
[10];
2853 char uptime_mroute_del
[10];
2855 pim_time_uptime_begin(uptime_scan_oil
, sizeof(uptime_scan_oil
), now
,
2856 pim
->scan_oil_last
);
2857 pim_time_uptime_begin(uptime_mroute_add
, sizeof(uptime_mroute_add
), now
,
2858 pim
->mroute_add_last
);
2859 pim_time_uptime_begin(uptime_mroute_del
, sizeof(uptime_mroute_del
), now
,
2860 pim
->mroute_del_last
);
2863 "Scan OIL - Last: %s Events: %lld\n"
2864 "MFC Add - Last: %s Events: %lld\n"
2865 "MFC Del - Last: %s Events: %lld\n",
2866 uptime_scan_oil
, (long long)pim
->scan_oil_events
,
2867 uptime_mroute_add
, (long long)pim
->mroute_add_events
,
2868 uptime_mroute_del
, (long long)pim
->mroute_del_events
);
2871 static void pim_show_rpf(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
2873 struct pim_upstream
*up
;
2874 time_t now
= pim_time_monotonic_sec();
2875 json_object
*json
= NULL
;
2876 json_object
*json_group
= NULL
;
2877 json_object
*json_row
= NULL
;
2880 json
= json_object_new_object();
2881 show_rpf_refresh_stats(vty
, pim
, now
, json
);
2883 show_rpf_refresh_stats(vty
, pim
, now
, json
);
2886 "Source Group RpfIface RpfAddress RibNextHop Metric Pref\n");
2889 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
2890 char src_str
[INET_ADDRSTRLEN
];
2891 char grp_str
[INET_ADDRSTRLEN
];
2892 char rpf_addr_str
[PREFIX_STRLEN
];
2893 char rib_nexthop_str
[PREFIX_STRLEN
];
2894 const char *rpf_ifname
;
2895 struct pim_rpf
*rpf
= &up
->rpf
;
2897 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2898 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2899 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2900 sizeof(rpf_addr_str
));
2901 pim_addr_dump("<nexthop?>",
2902 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2903 rib_nexthop_str
, sizeof(rib_nexthop_str
));
2905 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2908 json_object_object_get_ex(json
, grp_str
, &json_group
);
2911 json_group
= json_object_new_object();
2912 json_object_object_add(json
, grp_str
,
2916 json_row
= json_object_new_object();
2917 json_object_string_add(json_row
, "source", src_str
);
2918 json_object_string_add(json_row
, "group", grp_str
);
2919 json_object_string_add(json_row
, "rpfInterface",
2921 json_object_string_add(json_row
, "rpfAddress",
2923 json_object_string_add(json_row
, "ribNexthop",
2925 json_object_int_add(
2926 json_row
, "routeMetric",
2927 rpf
->source_nexthop
.mrib_route_metric
);
2928 json_object_int_add(
2929 json_row
, "routePreference",
2930 rpf
->source_nexthop
.mrib_metric_preference
);
2931 json_object_object_add(json_group
, src_str
, json_row
);
2934 vty_out(vty
, "%-15s %-15s %-16s %-15s %-15s %6d %4d\n",
2935 src_str
, grp_str
, rpf_ifname
, rpf_addr_str
,
2937 rpf
->source_nexthop
.mrib_route_metric
,
2938 rpf
->source_nexthop
.mrib_metric_preference
);
2943 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2944 json
, JSON_C_TO_STRING_PRETTY
));
2945 json_object_free(json
);
2949 struct pnc_cache_walk_data
{
2951 struct pim_instance
*pim
;
2954 static int pim_print_pnc_cache_walkcb(struct hash_bucket
*bucket
, void *arg
)
2956 struct pim_nexthop_cache
*pnc
= bucket
->data
;
2957 struct pnc_cache_walk_data
*cwd
= arg
;
2958 struct vty
*vty
= cwd
->vty
;
2959 struct pim_instance
*pim
= cwd
->pim
;
2960 struct nexthop
*nh_node
= NULL
;
2961 ifindex_t first_ifindex
;
2962 struct interface
*ifp
= NULL
;
2964 for (nh_node
= pnc
->nexthop
; nh_node
; nh_node
= nh_node
->next
) {
2965 first_ifindex
= nh_node
->ifindex
;
2966 ifp
= if_lookup_by_index(first_ifindex
, pim
->vrf_id
);
2968 vty_out(vty
, "%-15s ", inet_ntoa(pnc
->rpf
.rpf_addr
.u
.prefix4
));
2969 vty_out(vty
, "%-16s ", ifp
? ifp
->name
: "NULL");
2970 vty_out(vty
, "%s ", inet_ntoa(nh_node
->gate
.ipv4
));
2976 static void pim_show_nexthop(struct pim_instance
*pim
, struct vty
*vty
)
2978 struct pnc_cache_walk_data cwd
;
2982 vty_out(vty
, "Number of registered addresses: %lu\n",
2983 pim
->rpf_hash
->count
);
2984 vty_out(vty
, "Address Interface Nexthop\n");
2985 vty_out(vty
, "---------------------------------------------\n");
2987 hash_walk(pim
->rpf_hash
, pim_print_pnc_cache_walkcb
, &cwd
);
2990 /* Display the bsm database details */
2991 static void pim_show_bsm_db(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
2993 struct listnode
*bsmnode
;
2996 struct bsm_info
*bsm
;
2997 json_object
*json
= NULL
;
2998 json_object
*json_group
= NULL
;
2999 json_object
*json_row
= NULL
;
3001 count
= pim
->global_scope
.bsm_list
->count
;
3004 json
= json_object_new_object();
3005 json_object_int_add(json
, "Number of the fragments", count
);
3007 vty_out(vty
, "Scope Zone: Global\n");
3008 vty_out(vty
, "Number of the fragments: %d\n", count
);
3012 for (ALL_LIST_ELEMENTS_RO(pim
->global_scope
.bsm_list
, bsmnode
, bsm
)) {
3013 char grp_str
[INET_ADDRSTRLEN
];
3014 char rp_str
[INET_ADDRSTRLEN
];
3015 char bsr_str
[INET_ADDRSTRLEN
];
3016 struct bsmmsg_grpinfo
*group
;
3017 struct bsmmsg_rpinfo
*rpaddr
;
3019 struct bsm_hdr
*hdr
;
3020 uint32_t offset
= 0;
3023 uint32_t frag_rp_cnt
= 0;
3028 /* skip pim header */
3029 buf
+= PIM_MSG_HEADER_LEN
;
3030 len
-= PIM_MSG_HEADER_LEN
;
3032 hdr
= (struct bsm_hdr
*)buf
;
3034 /* BSM starts with bsr header */
3035 buf
+= sizeof(struct bsm_hdr
);
3036 len
-= sizeof(struct bsm_hdr
);
3038 pim_inet4_dump("<BSR Address?>", hdr
->bsr_addr
.addr
, bsr_str
,
3043 json_object_string_add(json
, "BSR address", bsr_str
);
3044 json_object_int_add(json
, "BSR priority",
3046 json_object_int_add(json
, "Hashmask Length",
3048 json_object_int_add(json
, "Fragment Tag",
3049 ntohs(hdr
->frag_tag
));
3051 vty_out(vty
, "BSM Fragment : %d\n", fragment
);
3052 vty_out(vty
, "------------------\n");
3053 vty_out(vty
, "%-15s %-15s %-15s %-15s\n", "BSR-Address",
3054 "BSR-Priority", "Hashmask-len", "Fragment-Tag");
3055 vty_out(vty
, "%-15s %-15d %-15d %-15d\n", bsr_str
,
3056 hdr
->bsr_prio
, hdr
->hm_len
,
3057 ntohs(hdr
->frag_tag
));
3062 while (offset
< len
) {
3063 group
= (struct bsmmsg_grpinfo
*)buf
;
3065 if (group
->group
.family
== PIM_MSG_ADDRESS_FAMILY_IPV4
)
3066 grp
.family
= AF_INET
;
3068 grp
.prefixlen
= group
->group
.mask
;
3069 grp
.u
.prefix4
.s_addr
= group
->group
.addr
.s_addr
;
3071 prefix2str(&grp
, grp_str
, sizeof(grp_str
));
3073 buf
+= sizeof(struct bsmmsg_grpinfo
);
3074 offset
+= sizeof(struct bsmmsg_grpinfo
);
3077 json_object_object_get_ex(json
, grp_str
,
3080 json_group
= json_object_new_object();
3081 json_object_int_add(json_group
,
3084 json_object_int_add(
3085 json_group
, "Fragment Rp count",
3086 group
->frag_rp_count
);
3087 json_object_object_add(json
, grp_str
,
3091 vty_out(vty
, "Group : %s\n", grp_str
);
3092 vty_out(vty
, "-------------------\n");
3093 vty_out(vty
, "Rp Count:%d\n", group
->rp_count
);
3094 vty_out(vty
, "Fragment Rp Count : %d\n",
3095 group
->frag_rp_count
);
3098 frag_rp_cnt
= group
->frag_rp_count
;
3105 "RpAddress HoldTime Priority\n");
3107 while (frag_rp_cnt
--) {
3108 rpaddr
= (struct bsmmsg_rpinfo
*)buf
;
3110 buf
+= sizeof(struct bsmmsg_rpinfo
);
3111 offset
+= sizeof(struct bsmmsg_rpinfo
);
3113 pim_inet4_dump("<Rp addr?>",
3114 rpaddr
->rpaddr
.addr
, rp_str
,
3118 json_row
= json_object_new_object();
3119 json_object_string_add(
3120 json_row
, "Rp Address", rp_str
);
3121 json_object_int_add(
3122 json_row
, "Rp HoldTime",
3123 ntohs(rpaddr
->rp_holdtime
));
3124 json_object_int_add(json_row
,
3127 json_object_object_add(
3128 json_group
, rp_str
, json_row
);
3130 vty_out(vty
, "%-15s %-12d %d\n", rp_str
,
3131 ntohs(rpaddr
->rp_holdtime
),
3142 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3143 json
, JSON_C_TO_STRING_PRETTY
));
3144 json_object_free(json
);
3148 /*Display the group-rp mappings */
3149 static void pim_show_group_rp_mappings_info(struct pim_instance
*pim
,
3150 struct vty
*vty
, bool uj
)
3152 struct bsgrp_node
*bsgrp
;
3153 struct listnode
*rpnode
;
3154 struct bsm_rpinfo
*bsm_rp
;
3155 struct route_node
*rn
;
3156 char bsr_str
[INET_ADDRSTRLEN
];
3157 json_object
*json
= NULL
;
3158 json_object
*json_group
= NULL
;
3159 json_object
*json_row
= NULL
;
3161 if (pim
->global_scope
.current_bsr
.s_addr
== INADDR_ANY
)
3162 strlcpy(bsr_str
, "0.0.0.0", sizeof(bsr_str
));
3165 pim_inet4_dump("<bsr?>", pim
->global_scope
.current_bsr
, bsr_str
,
3169 json
= json_object_new_object();
3170 json_object_string_add(json
, "BSR Address", bsr_str
);
3172 vty_out(vty
, "BSR Address %s\n", bsr_str
);
3175 for (rn
= route_top(pim
->global_scope
.bsrp_table
); rn
;
3176 rn
= route_next(rn
)) {
3177 bsgrp
= (struct bsgrp_node
*)rn
->info
;
3182 char grp_str
[INET_ADDRSTRLEN
];
3184 prefix2str(&bsgrp
->group
, grp_str
, sizeof(grp_str
));
3187 json_object_object_get_ex(json
, grp_str
, &json_group
);
3189 json_group
= json_object_new_object();
3190 json_object_object_add(json
, grp_str
,
3194 vty_out(vty
, "Group Address %s\n", grp_str
);
3195 vty_out(vty
, "--------------------------\n");
3196 vty_out(vty
, "%-15s %-15s %-15s %-15s\n", "Rp Address",
3197 "priority", "Holdtime", "Hash");
3199 vty_out(vty
, "(ACTIVE)\n");
3202 if (bsgrp
->bsrp_list
) {
3203 for (ALL_LIST_ELEMENTS_RO(bsgrp
->bsrp_list
, rpnode
,
3205 char rp_str
[INET_ADDRSTRLEN
];
3207 pim_inet4_dump("<Rp Address?>",
3208 bsm_rp
->rp_address
, rp_str
,
3212 json_row
= json_object_new_object();
3213 json_object_string_add(
3214 json_row
, "Rp Address", rp_str
);
3215 json_object_int_add(
3216 json_row
, "Rp HoldTime",
3217 bsm_rp
->rp_holdtime
);
3218 json_object_int_add(json_row
,
3221 json_object_int_add(json_row
,
3224 json_object_object_add(
3225 json_group
, rp_str
, json_row
);
3229 "%-15s %-15u %-15u %-15u\n",
3230 rp_str
, bsm_rp
->rp_prio
,
3231 bsm_rp
->rp_holdtime
,
3235 if (!bsgrp
->bsrp_list
->count
&& !uj
)
3236 vty_out(vty
, "Active List is empty.\n");
3240 json_object_int_add(json_group
, "Pending RP count",
3241 bsgrp
->pend_rp_cnt
);
3243 vty_out(vty
, "(PENDING)\n");
3244 vty_out(vty
, "Pending RP count :%d\n",
3245 bsgrp
->pend_rp_cnt
);
3246 if (bsgrp
->pend_rp_cnt
)
3247 vty_out(vty
, "%-15s %-15s %-15s %-15s\n",
3248 "Rp Address", "priority", "Holdtime",
3252 if (bsgrp
->partial_bsrp_list
) {
3253 for (ALL_LIST_ELEMENTS_RO(bsgrp
->partial_bsrp_list
,
3255 char rp_str
[INET_ADDRSTRLEN
];
3257 pim_inet4_dump("<Rp Addr?>", bsm_rp
->rp_address
,
3258 rp_str
, sizeof(rp_str
));
3261 json_row
= json_object_new_object();
3262 json_object_string_add(
3263 json_row
, "Rp Address", rp_str
);
3264 json_object_int_add(
3265 json_row
, "Rp HoldTime",
3266 bsm_rp
->rp_holdtime
);
3267 json_object_int_add(json_row
,
3270 json_object_int_add(json_row
,
3273 json_object_object_add(
3274 json_group
, rp_str
, json_row
);
3277 "%-15s %-15u %-15u %-15u\n",
3278 rp_str
, bsm_rp
->rp_prio
,
3279 bsm_rp
->rp_holdtime
,
3283 if (!bsgrp
->partial_bsrp_list
->count
&& !uj
)
3284 vty_out(vty
, "Partial List is empty\n");
3292 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3293 json
, JSON_C_TO_STRING_PRETTY
));
3294 json_object_free(json
);
3298 /* pim statistics - just adding only bsm related now.
3299 * We can continue to add all pim related stats here.
3301 static void pim_show_statistics(struct pim_instance
*pim
, struct vty
*vty
,
3302 const char *ifname
, bool uj
)
3304 json_object
*json
= NULL
;
3305 struct interface
*ifp
;
3308 json
= json_object_new_object();
3309 json_object_int_add(json
, "Number of Received BSMs",
3311 json_object_int_add(json
, "Number of Forwared BSMs",
3313 json_object_int_add(json
, "Number of Dropped BSMs",
3316 vty_out(vty
, "BSM Statistics :\n");
3317 vty_out(vty
, "----------------\n");
3318 vty_out(vty
, "Number of Received BSMs : %" PRIu64
"\n",
3320 vty_out(vty
, "Number of Forwared BSMs : %" PRIu64
"\n",
3322 vty_out(vty
, "Number of Dropped BSMs : %" PRIu64
"\n",
3328 /* scan interfaces */
3329 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3330 struct pim_interface
*pim_ifp
= ifp
->info
;
3332 if (ifname
&& strcmp(ifname
, ifp
->name
))
3339 vty_out(vty
, "Interface : %s\n", ifp
->name
);
3340 vty_out(vty
, "-------------------\n");
3342 "Number of BSMs dropped due to config miss : %u\n",
3343 pim_ifp
->pim_ifstat_bsm_cfg_miss
);
3344 vty_out(vty
, "Number of unicast BSMs dropped : %u\n",
3345 pim_ifp
->pim_ifstat_ucast_bsm_cfg_miss
);
3347 "Number of BSMs dropped due to invalid scope zone : %u\n",
3348 pim_ifp
->pim_ifstat_bsm_invalid_sz
);
3351 json_object
*json_row
= NULL
;
3353 json_row
= json_object_new_object();
3355 json_object_string_add(json_row
, "If Name", ifp
->name
);
3356 json_object_int_add(
3358 "Number of BSMs dropped due to config miss",
3359 pim_ifp
->pim_ifstat_bsm_cfg_miss
);
3360 json_object_int_add(
3361 json_row
, "Number of unicast BSMs dropped",
3362 pim_ifp
->pim_ifstat_ucast_bsm_cfg_miss
);
3363 json_object_int_add(json_row
,
3364 "Number of BSMs dropped due to invalid scope zone",
3365 pim_ifp
->pim_ifstat_bsm_invalid_sz
);
3366 json_object_object_add(json
, ifp
->name
, json_row
);
3372 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3373 json
, JSON_C_TO_STRING_PRETTY
));
3374 json_object_free(json
);
3378 static void clear_pim_statistics(struct pim_instance
*pim
)
3380 struct interface
*ifp
;
3384 pim
->bsm_dropped
= 0;
3386 /* scan interfaces */
3387 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3388 struct pim_interface
*pim_ifp
= ifp
->info
;
3393 pim_ifp
->pim_ifstat_bsm_cfg_miss
= 0;
3394 pim_ifp
->pim_ifstat_ucast_bsm_cfg_miss
= 0;
3395 pim_ifp
->pim_ifstat_bsm_invalid_sz
= 0;
3399 static void igmp_show_groups(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
3401 struct interface
*ifp
;
3403 json_object
*json
= NULL
;
3404 json_object
*json_iface
= NULL
;
3405 json_object
*json_row
= NULL
;
3407 now
= pim_time_monotonic_sec();
3410 json
= json_object_new_object();
3413 "Interface Address Group Mode Timer Srcs V Uptime \n");
3415 /* scan interfaces */
3416 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3417 struct pim_interface
*pim_ifp
= ifp
->info
;
3418 struct listnode
*sock_node
;
3419 struct igmp_sock
*igmp
;
3424 /* scan igmp sockets */
3425 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3427 char ifaddr_str
[INET_ADDRSTRLEN
];
3428 struct listnode
*grpnode
;
3429 struct igmp_group
*grp
;
3431 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3432 sizeof(ifaddr_str
));
3434 /* scan igmp groups */
3435 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3437 char group_str
[INET_ADDRSTRLEN
];
3441 pim_inet4_dump("<group?>", grp
->group_addr
,
3442 group_str
, sizeof(group_str
));
3443 pim_time_timer_to_hhmmss(hhmmss
, sizeof(hhmmss
),
3444 grp
->t_group_timer
);
3445 pim_time_uptime(uptime
, sizeof(uptime
),
3446 now
- grp
->group_creation
);
3449 json_object_object_get_ex(
3450 json
, ifp
->name
, &json_iface
);
3454 json_object_new_object();
3455 json_object_pim_ifp_add(
3457 json_object_object_add(
3462 json_row
= json_object_new_object();
3463 json_object_string_add(
3464 json_row
, "source", ifaddr_str
);
3465 json_object_string_add(
3466 json_row
, "group", group_str
);
3468 if (grp
->igmp_version
== 3)
3469 json_object_string_add(
3471 grp
->group_filtermode_isexcl
3475 json_object_string_add(json_row
,
3477 json_object_int_add(
3478 json_row
, "sourcesCount",
3479 grp
->group_source_list
3481 grp
->group_source_list
)
3483 json_object_int_add(json_row
, "version",
3485 json_object_string_add(
3486 json_row
, "uptime", uptime
);
3487 json_object_object_add(json_iface
,
3493 "%-16s %-15s %-15s %4s %8s %4d %d %8s\n",
3494 ifp
->name
, ifaddr_str
,
3496 grp
->igmp_version
== 3
3497 ? (grp
->group_filtermode_isexcl
3502 grp
->group_source_list
3504 grp
->group_source_list
)
3506 grp
->igmp_version
, uptime
);
3508 } /* scan igmp groups */
3509 } /* scan igmp sockets */
3510 } /* scan interfaces */
3513 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3514 json
, JSON_C_TO_STRING_PRETTY
));
3515 json_object_free(json
);
3519 static void igmp_show_group_retransmission(struct pim_instance
*pim
,
3522 struct interface
*ifp
;
3525 "Interface Address Group RetTimer Counter RetSrcs\n");
3527 /* scan interfaces */
3528 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3529 struct pim_interface
*pim_ifp
= ifp
->info
;
3530 struct listnode
*sock_node
;
3531 struct igmp_sock
*igmp
;
3536 /* scan igmp sockets */
3537 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3539 char ifaddr_str
[INET_ADDRSTRLEN
];
3540 struct listnode
*grpnode
;
3541 struct igmp_group
*grp
;
3543 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3544 sizeof(ifaddr_str
));
3546 /* scan igmp groups */
3547 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3549 char group_str
[INET_ADDRSTRLEN
];
3550 char grp_retr_mmss
[10];
3551 struct listnode
*src_node
;
3552 struct igmp_source
*src
;
3553 int grp_retr_sources
= 0;
3555 pim_inet4_dump("<group?>", grp
->group_addr
,
3556 group_str
, sizeof(group_str
));
3557 pim_time_timer_to_mmss(
3558 grp_retr_mmss
, sizeof(grp_retr_mmss
),
3559 grp
->t_group_query_retransmit_timer
);
3562 /* count group sources with retransmission state
3564 for (ALL_LIST_ELEMENTS_RO(
3565 grp
->group_source_list
, src_node
,
3567 if (src
->source_query_retransmit_count
3573 vty_out(vty
, "%-16s %-15s %-15s %-8s %7d %7d\n",
3574 ifp
->name
, ifaddr_str
, group_str
,
3576 grp
->group_specific_query_retransmit_count
,
3579 } /* scan igmp groups */
3580 } /* scan igmp sockets */
3581 } /* scan interfaces */
3584 static void igmp_show_sources(struct pim_instance
*pim
, struct vty
*vty
)
3586 struct interface
*ifp
;
3589 now
= pim_time_monotonic_sec();
3592 "Interface Address Group Source Timer Fwd Uptime \n");
3594 /* scan interfaces */
3595 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3596 struct pim_interface
*pim_ifp
= ifp
->info
;
3597 struct listnode
*sock_node
;
3598 struct igmp_sock
*igmp
;
3603 /* scan igmp sockets */
3604 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3606 char ifaddr_str
[INET_ADDRSTRLEN
];
3607 struct listnode
*grpnode
;
3608 struct igmp_group
*grp
;
3610 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3611 sizeof(ifaddr_str
));
3613 /* scan igmp groups */
3614 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3616 char group_str
[INET_ADDRSTRLEN
];
3617 struct listnode
*srcnode
;
3618 struct igmp_source
*src
;
3620 pim_inet4_dump("<group?>", grp
->group_addr
,
3621 group_str
, sizeof(group_str
));
3623 /* scan group sources */
3624 for (ALL_LIST_ELEMENTS_RO(
3625 grp
->group_source_list
, srcnode
,
3627 char source_str
[INET_ADDRSTRLEN
];
3632 "<source?>", src
->source_addr
,
3633 source_str
, sizeof(source_str
));
3635 pim_time_timer_to_mmss(
3637 src
->t_source_timer
);
3640 uptime
, sizeof(uptime
),
3641 now
- src
->source_creation
);
3644 "%-16s %-15s %-15s %-15s %5s %3s %8s\n",
3645 ifp
->name
, ifaddr_str
,
3646 group_str
, source_str
, mmss
,
3647 IGMP_SOURCE_TEST_FORWARDING(
3653 } /* scan group sources */
3654 } /* scan igmp groups */
3655 } /* scan igmp sockets */
3656 } /* scan interfaces */
3659 static void igmp_show_source_retransmission(struct pim_instance
*pim
,
3662 struct interface
*ifp
;
3665 "Interface Address Group Source Counter\n");
3667 /* scan interfaces */
3668 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3669 struct pim_interface
*pim_ifp
= ifp
->info
;
3670 struct listnode
*sock_node
;
3671 struct igmp_sock
*igmp
;
3676 /* scan igmp sockets */
3677 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3679 char ifaddr_str
[INET_ADDRSTRLEN
];
3680 struct listnode
*grpnode
;
3681 struct igmp_group
*grp
;
3683 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3684 sizeof(ifaddr_str
));
3686 /* scan igmp groups */
3687 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3689 char group_str
[INET_ADDRSTRLEN
];
3690 struct listnode
*srcnode
;
3691 struct igmp_source
*src
;
3693 pim_inet4_dump("<group?>", grp
->group_addr
,
3694 group_str
, sizeof(group_str
));
3696 /* scan group sources */
3697 for (ALL_LIST_ELEMENTS_RO(
3698 grp
->group_source_list
, srcnode
,
3700 char source_str
[INET_ADDRSTRLEN
];
3703 "<source?>", src
->source_addr
,
3704 source_str
, sizeof(source_str
));
3707 "%-16s %-15s %-15s %-15s %7d\n",
3708 ifp
->name
, ifaddr_str
,
3709 group_str
, source_str
,
3710 src
->source_query_retransmit_count
);
3712 } /* scan group sources */
3713 } /* scan igmp groups */
3714 } /* scan igmp sockets */
3715 } /* scan interfaces */
3718 static void pim_show_bsr(struct pim_instance
*pim
,
3723 char last_bsm_seen
[10];
3726 char bsr_str
[PREFIX_STRLEN
];
3727 json_object
*json
= NULL
;
3729 vty_out(vty
, "PIMv2 Bootstrap information\n");
3731 if (pim
->global_scope
.current_bsr
.s_addr
== INADDR_ANY
) {
3732 strlcpy(bsr_str
, "0.0.0.0", sizeof(bsr_str
));
3733 pim_time_uptime(uptime
, sizeof(uptime
),
3734 pim
->global_scope
.current_bsr_first_ts
);
3735 pim_time_uptime(last_bsm_seen
, sizeof(last_bsm_seen
),
3736 pim
->global_scope
.current_bsr_last_ts
);
3740 pim_inet4_dump("<bsr?>", pim
->global_scope
.current_bsr
,
3741 bsr_str
, sizeof(bsr_str
));
3742 now
= pim_time_monotonic_sec();
3743 pim_time_uptime(uptime
, sizeof(uptime
),
3744 (now
- pim
->global_scope
.current_bsr_first_ts
));
3745 pim_time_uptime(last_bsm_seen
, sizeof(last_bsm_seen
),
3746 now
- pim
->global_scope
.current_bsr_last_ts
);
3749 switch (pim
->global_scope
.state
) {
3751 strlcpy(bsr_state
, "NO_INFO", sizeof(bsr_state
));
3754 strlcpy(bsr_state
, "ACCEPT_ANY", sizeof(bsr_state
));
3756 case ACCEPT_PREFERRED
:
3757 strlcpy(bsr_state
, "ACCEPT_PREFERRED", sizeof(bsr_state
));
3760 strlcpy(bsr_state
, "", sizeof(bsr_state
));
3764 json
= json_object_new_object();
3765 json_object_string_add(json
, "bsr", bsr_str
);
3766 json_object_int_add(json
, "priority",
3767 pim
->global_scope
.current_bsr_prio
);
3768 json_object_int_add(json
, "fragment_tag",
3769 pim
->global_scope
.bsm_frag_tag
);
3770 json_object_string_add(json
, "state", bsr_state
);
3771 json_object_string_add(json
, "upTime", uptime
);
3772 json_object_string_add(json
, "last_bsm_seen", last_bsm_seen
);
3776 vty_out(vty
, "Current preferred BSR address: %s\n", bsr_str
);
3778 "Priority Fragment-Tag State UpTime\n");
3779 vty_out(vty
, " %-12d %-12d %-13s %7s\n",
3780 pim
->global_scope
.current_bsr_prio
,
3781 pim
->global_scope
.bsm_frag_tag
,
3784 vty_out(vty
, "Last BSM seen: %s\n", last_bsm_seen
);
3788 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3789 json
, JSON_C_TO_STRING_PRETTY
));
3790 json_object_free(json
);
3794 static void clear_igmp_interfaces(struct pim_instance
*pim
)
3796 struct interface
*ifp
;
3798 FOR_ALL_INTERFACES (pim
->vrf
, ifp
)
3799 pim_if_addr_del_all_igmp(ifp
);
3801 FOR_ALL_INTERFACES (pim
->vrf
, ifp
)
3802 pim_if_addr_add_all(ifp
);
3805 static void clear_pim_interfaces(struct pim_instance
*pim
)
3807 struct interface
*ifp
;
3809 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3811 pim_neighbor_delete_all(ifp
, "interface cleared");
3816 static void clear_interfaces(struct pim_instance
*pim
)
3818 clear_igmp_interfaces(pim
);
3819 clear_pim_interfaces(pim
);
3822 #define PIM_GET_PIM_INTERFACE(pim_ifp, ifp) \
3823 pim_ifp = ifp->info; \
3826 "%% Enable PIM and/or IGMP on this interface first\n"); \
3827 return CMD_WARNING_CONFIG_FAILED; \
3830 DEFUN (clear_ip_interfaces
,
3831 clear_ip_interfaces_cmd
,
3832 "clear ip interfaces [vrf NAME]",
3835 "Reset interfaces\n"
3839 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3844 clear_interfaces(vrf
->info
);
3849 DEFUN (clear_ip_igmp_interfaces
,
3850 clear_ip_igmp_interfaces_cmd
,
3851 "clear ip igmp [vrf NAME] interfaces",
3856 "Reset IGMP interfaces\n")
3859 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3864 clear_igmp_interfaces(vrf
->info
);
3869 DEFUN (clear_ip_pim_statistics
,
3870 clear_ip_pim_statistics_cmd
,
3871 "clear ip pim statistics [vrf NAME]",
3876 "Reset PIM statistics\n")
3879 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3884 clear_pim_statistics(vrf
->info
);
3888 static void clear_mroute(struct pim_instance
*pim
)
3890 struct pim_upstream
*up
;
3891 struct interface
*ifp
;
3893 /* scan interfaces */
3894 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3895 struct pim_interface
*pim_ifp
= ifp
->info
;
3896 struct listnode
*sock_node
;
3897 struct igmp_sock
*igmp
;
3898 struct pim_ifchannel
*ch
;
3903 /* deleting all ifchannels */
3904 while (!RB_EMPTY(pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
)) {
3905 ch
= RB_ROOT(pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
);
3907 pim_ifchannel_delete(ch
);
3910 /* clean up all igmp groups */
3911 /* scan igmp sockets */
3912 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3915 struct igmp_group
*grp
;
3917 if (igmp
->igmp_group_list
) {
3918 while (igmp
->igmp_group_list
->count
) {
3919 grp
= listnode_head(
3920 igmp
->igmp_group_list
);
3921 igmp_group_delete(grp
);
3928 /* clean up all upstreams*/
3929 while ((up
= rb_pim_upstream_first(&pim
->upstream_head
))) {
3930 pim_upstream_del(pim
, up
, __PRETTY_FUNCTION__
);
3934 DEFUN (clear_ip_mroute
,
3935 clear_ip_mroute_cmd
,
3936 "clear ip mroute [vrf NAME]",
3939 "Reset multicast routes\n"
3943 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3948 clear_mroute(vrf
->info
);
3953 DEFUN (clear_ip_pim_interfaces
,
3954 clear_ip_pim_interfaces_cmd
,
3955 "clear ip pim [vrf NAME] interfaces",
3960 "Reset PIM interfaces\n")
3963 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3968 clear_pim_interfaces(vrf
->info
);
3973 DEFUN (clear_ip_pim_interface_traffic
,
3974 clear_ip_pim_interface_traffic_cmd
,
3975 "clear ip pim [vrf NAME] interface traffic",
3978 "PIM clear commands\n"
3980 "Reset PIM interfaces\n"
3981 "Reset Protocol Packet counters\n")
3984 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3985 struct interface
*ifp
= NULL
;
3986 struct pim_interface
*pim_ifp
= NULL
;
3991 FOR_ALL_INTERFACES (vrf
, ifp
) {
3992 pim_ifp
= ifp
->info
;
3997 pim_ifp
->pim_ifstat_hello_recv
= 0;
3998 pim_ifp
->pim_ifstat_hello_sent
= 0;
3999 pim_ifp
->pim_ifstat_join_recv
= 0;
4000 pim_ifp
->pim_ifstat_join_send
= 0;
4001 pim_ifp
->pim_ifstat_prune_recv
= 0;
4002 pim_ifp
->pim_ifstat_prune_send
= 0;
4003 pim_ifp
->pim_ifstat_reg_recv
= 0;
4004 pim_ifp
->pim_ifstat_reg_send
= 0;
4005 pim_ifp
->pim_ifstat_reg_stop_recv
= 0;
4006 pim_ifp
->pim_ifstat_reg_stop_send
= 0;
4007 pim_ifp
->pim_ifstat_assert_recv
= 0;
4008 pim_ifp
->pim_ifstat_assert_send
= 0;
4009 pim_ifp
->pim_ifstat_bsm_rx
= 0;
4010 pim_ifp
->pim_ifstat_bsm_tx
= 0;
4016 DEFUN (clear_ip_pim_oil
,
4017 clear_ip_pim_oil_cmd
,
4018 "clear ip pim [vrf NAME] oil",
4023 "Rescan PIM OIL (output interface list)\n")
4026 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4031 pim_scan_oil(vrf
->info
);
4036 DEFUN (show_ip_igmp_interface
,
4037 show_ip_igmp_interface_cmd
,
4038 "show ip igmp [vrf NAME] interface [detail|WORD] [json]",
4043 "IGMP interface information\n"
4049 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4050 bool uj
= use_json(argc
, argv
);
4055 if (argv_find(argv
, argc
, "detail", &idx
)
4056 || argv_find(argv
, argc
, "WORD", &idx
))
4057 igmp_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
4059 igmp_show_interfaces(vrf
->info
, vty
, uj
);
4064 DEFUN (show_ip_igmp_interface_vrf_all
,
4065 show_ip_igmp_interface_vrf_all_cmd
,
4066 "show ip igmp vrf all interface [detail|WORD] [json]",
4071 "IGMP interface information\n"
4077 bool uj
= use_json(argc
, argv
);
4083 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4087 vty_out(vty
, " \"%s\": ", vrf
->name
);
4090 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4091 if (argv_find(argv
, argc
, "detail", &idx
)
4092 || argv_find(argv
, argc
, "WORD", &idx
))
4093 igmp_show_interfaces_single(vrf
->info
, vty
,
4094 argv
[idx
]->arg
, uj
);
4096 igmp_show_interfaces(vrf
->info
, vty
, uj
);
4099 vty_out(vty
, "}\n");
4104 DEFUN (show_ip_igmp_join
,
4105 show_ip_igmp_join_cmd
,
4106 "show ip igmp [vrf NAME] join",
4111 "IGMP static join information\n")
4114 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4119 igmp_show_interface_join(vrf
->info
, vty
);
4124 DEFUN (show_ip_igmp_join_vrf_all
,
4125 show_ip_igmp_join_vrf_all_cmd
,
4126 "show ip igmp vrf all join",
4131 "IGMP static join information\n")
4133 bool uj
= use_json(argc
, argv
);
4139 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4143 vty_out(vty
, " \"%s\": ", vrf
->name
);
4146 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4147 igmp_show_interface_join(vrf
->info
, vty
);
4150 vty_out(vty
, "}\n");
4155 DEFUN (show_ip_igmp_groups
,
4156 show_ip_igmp_groups_cmd
,
4157 "show ip igmp [vrf NAME] groups [json]",
4166 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4167 bool uj
= use_json(argc
, argv
);
4172 igmp_show_groups(vrf
->info
, vty
, uj
);
4177 DEFUN (show_ip_igmp_groups_vrf_all
,
4178 show_ip_igmp_groups_vrf_all_cmd
,
4179 "show ip igmp vrf all groups [json]",
4187 bool uj
= use_json(argc
, argv
);
4193 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4197 vty_out(vty
, " \"%s\": ", vrf
->name
);
4200 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4201 igmp_show_groups(vrf
->info
, vty
, uj
);
4204 vty_out(vty
, "}\n");
4209 DEFUN (show_ip_igmp_groups_retransmissions
,
4210 show_ip_igmp_groups_retransmissions_cmd
,
4211 "show ip igmp [vrf NAME] groups retransmissions",
4217 "IGMP group retransmissions\n")
4220 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4225 igmp_show_group_retransmission(vrf
->info
, vty
);
4230 DEFUN (show_ip_igmp_sources
,
4231 show_ip_igmp_sources_cmd
,
4232 "show ip igmp [vrf NAME] sources",
4240 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4245 igmp_show_sources(vrf
->info
, vty
);
4250 DEFUN (show_ip_igmp_sources_retransmissions
,
4251 show_ip_igmp_sources_retransmissions_cmd
,
4252 "show ip igmp [vrf NAME] sources retransmissions",
4258 "IGMP source retransmissions\n")
4261 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4266 igmp_show_source_retransmission(vrf
->info
, vty
);
4271 DEFUN (show_ip_igmp_statistics
,
4272 show_ip_igmp_statistics_cmd
,
4273 "show ip igmp [vrf NAME] statistics [interface WORD] [json]",
4284 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4285 bool uj
= use_json(argc
, argv
);
4290 if (argv_find(argv
, argc
, "WORD", &idx
))
4291 igmp_show_statistics(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
4293 igmp_show_statistics(vrf
->info
, vty
, NULL
, uj
);
4298 DEFUN (show_ip_pim_assert
,
4299 show_ip_pim_assert_cmd
,
4300 "show ip pim [vrf NAME] assert",
4305 "PIM interface assert\n")
4308 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4313 pim_show_assert(vrf
->info
, vty
);
4318 DEFUN (show_ip_pim_assert_internal
,
4319 show_ip_pim_assert_internal_cmd
,
4320 "show ip pim [vrf NAME] assert-internal",
4325 "PIM interface internal assert state\n")
4328 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4333 pim_show_assert_internal(vrf
->info
, vty
);
4338 DEFUN (show_ip_pim_assert_metric
,
4339 show_ip_pim_assert_metric_cmd
,
4340 "show ip pim [vrf NAME] assert-metric",
4345 "PIM interface assert metric\n")
4348 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4353 pim_show_assert_metric(vrf
->info
, vty
);
4358 DEFUN (show_ip_pim_assert_winner_metric
,
4359 show_ip_pim_assert_winner_metric_cmd
,
4360 "show ip pim [vrf NAME] assert-winner-metric",
4365 "PIM interface assert winner metric\n")
4368 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4373 pim_show_assert_winner_metric(vrf
->info
, vty
);
4378 DEFUN (show_ip_pim_interface
,
4379 show_ip_pim_interface_cmd
,
4380 "show ip pim [vrf NAME] interface [detail|WORD] [json]",
4385 "PIM interface information\n"
4391 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4392 bool uj
= use_json(argc
, argv
);
4397 if (argv_find(argv
, argc
, "WORD", &idx
)
4398 || argv_find(argv
, argc
, "detail", &idx
))
4399 pim_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
4401 pim_show_interfaces(vrf
->info
, vty
, uj
);
4406 DEFUN (show_ip_pim_interface_vrf_all
,
4407 show_ip_pim_interface_vrf_all_cmd
,
4408 "show ip pim vrf all interface [detail|WORD] [json]",
4413 "PIM interface information\n"
4419 bool uj
= use_json(argc
, argv
);
4425 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4429 vty_out(vty
, " \"%s\": ", vrf
->name
);
4432 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4433 if (argv_find(argv
, argc
, "WORD", &idx
)
4434 || argv_find(argv
, argc
, "detail", &idx
))
4435 pim_show_interfaces_single(vrf
->info
, vty
,
4436 argv
[idx
]->arg
, uj
);
4438 pim_show_interfaces(vrf
->info
, vty
, uj
);
4441 vty_out(vty
, "}\n");
4446 DEFPY (show_ip_pim_join
,
4447 show_ip_pim_join_cmd
,
4448 "show ip pim [vrf NAME] join [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
4453 "PIM interface join information\n"
4454 "The Source or Group\n"
4458 struct prefix_sg sg
= {0};
4461 struct pim_instance
*pim
;
4463 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
4466 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
4469 pim
= pim_get_pim_instance(v
->vrf_id
);
4472 vty_out(vty
, "%% Unable to find pim instance\n");
4476 if (s_or_g
.s_addr
!= 0) {
4477 if (g
.s_addr
!= 0) {
4484 pim_show_join(pim
, vty
, &sg
, uj
);
4489 DEFUN (show_ip_pim_join_vrf_all
,
4490 show_ip_pim_join_vrf_all_cmd
,
4491 "show ip pim vrf all join [json]",
4496 "PIM interface join information\n"
4499 struct prefix_sg sg
= {0};
4500 bool uj
= use_json(argc
, argv
);
4506 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4510 vty_out(vty
, " \"%s\": ", vrf
->name
);
4513 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4514 pim_show_join(vrf
->info
, vty
, &sg
, uj
);
4517 vty_out(vty
, "}\n");
4522 static void pim_show_jp_agg_helper(struct vty
*vty
,
4523 struct interface
*ifp
,
4524 struct pim_neighbor
*neigh
,
4525 struct pim_upstream
*up
,
4528 char src_str
[INET_ADDRSTRLEN
];
4529 char grp_str
[INET_ADDRSTRLEN
];
4530 char rpf_str
[INET_ADDRSTRLEN
];
4532 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
4533 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
4534 /* pius->address.s_addr */
4535 pim_inet4_dump("<rpf?>", neigh
->source_addr
, rpf_str
, sizeof(rpf_str
));
4537 vty_out(vty
, "%-16s %-15s %-15s %-15s %5s\n",
4538 ifp
->name
, rpf_str
, src_str
,
4539 grp_str
, is_join
?"J":"P");
4542 static void pim_show_jp_agg_list(struct pim_instance
*pim
, struct vty
*vty
)
4544 struct interface
*ifp
;
4545 struct pim_interface
*pim_ifp
;
4546 struct listnode
*n_node
;
4547 struct pim_neighbor
*neigh
;
4548 struct listnode
*jag_node
;
4549 struct pim_jp_agg_group
*jag
;
4550 struct listnode
*js_node
;
4551 struct pim_jp_sources
*js
;
4554 "Interface RPF Nbr Source Group State\n");
4556 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
4557 pim_ifp
= ifp
->info
;
4561 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
,
4563 for (ALL_LIST_ELEMENTS_RO(neigh
->upstream_jp_agg
,
4565 for (ALL_LIST_ELEMENTS_RO(jag
->sources
,
4567 pim_show_jp_agg_helper(vty
,
4576 DEFPY (show_ip_pim_jp_agg
,
4577 show_ip_pim_jp_agg_cmd
,
4578 "show ip pim [vrf NAME] jp-agg",
4583 "join prune aggregation list\n")
4586 struct pim_instance
*pim
;
4588 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
4591 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
4594 pim
= pim_get_pim_instance(v
->vrf_id
);
4597 vty_out(vty
, "%% Unable to find pim instance\n");
4601 pim_show_jp_agg_list(pim
, vty
);
4606 DEFUN (show_ip_pim_local_membership
,
4607 show_ip_pim_local_membership_cmd
,
4608 "show ip pim [vrf NAME] local-membership [json]",
4613 "PIM interface local-membership\n"
4617 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4618 bool uj
= use_json(argc
, argv
);
4623 pim_show_membership(vrf
->info
, vty
, uj
);
4628 DEFUN (show_ip_pim_mlag_summary
,
4629 show_ip_pim_mlag_summary_cmd
,
4630 "show ip pim mlag summary [json]",
4635 "status and stats\n"
4638 bool uj
= use_json(argc
, argv
);
4639 char role_buf
[MLAG_ROLE_STRSIZE
];
4640 char addr_buf
[INET_ADDRSTRLEN
];
4643 json_object
*json
= NULL
;
4644 json_object
*json_stat
= NULL
;
4646 json
= json_object_new_object();
4647 if (router
->mlag_flags
& PIM_MLAGF_LOCAL_CONN_UP
)
4648 json_object_boolean_true_add(json
, "mlagConnUp");
4649 if (router
->mlag_flags
& PIM_MLAGF_PEER_CONN_UP
)
4650 json_object_boolean_true_add(json
, "mlagPeerConnUp");
4651 if (router
->mlag_flags
& PIM_MLAGF_PEER_ZEBRA_UP
)
4652 json_object_boolean_true_add(json
, "mlagPeerZebraUp");
4653 json_object_string_add(json
, "mlagRole",
4654 mlag_role2str(router
->mlag_role
,
4655 role_buf
, sizeof(role_buf
)));
4656 inet_ntop(AF_INET
, &router
->local_vtep_ip
,
4657 addr_buf
, INET_ADDRSTRLEN
);
4658 json_object_string_add(json
, "localVtepIp", addr_buf
);
4659 inet_ntop(AF_INET
, &router
->anycast_vtep_ip
,
4660 addr_buf
, INET_ADDRSTRLEN
);
4661 json_object_string_add(json
, "anycastVtepIp", addr_buf
);
4662 json_object_string_add(json
, "peerlinkRif",
4663 router
->peerlink_rif
);
4665 json_stat
= json_object_new_object();
4666 json_object_int_add(json_stat
, "mlagConnFlaps",
4667 router
->mlag_stats
.mlagd_session_downs
);
4668 json_object_int_add(json_stat
, "mlagPeerConnFlaps",
4669 router
->mlag_stats
.peer_session_downs
);
4670 json_object_int_add(json_stat
, "mlagPeerZebraFlaps",
4671 router
->mlag_stats
.peer_zebra_downs
);
4672 json_object_int_add(json_stat
, "mrouteAddRx",
4673 router
->mlag_stats
.msg
.mroute_add_rx
);
4674 json_object_int_add(json_stat
, "mrouteAddTx",
4675 router
->mlag_stats
.msg
.mroute_add_tx
);
4676 json_object_int_add(json_stat
, "mrouteDelRx",
4677 router
->mlag_stats
.msg
.mroute_del_rx
);
4678 json_object_int_add(json_stat
, "mrouteDelTx",
4679 router
->mlag_stats
.msg
.mroute_del_tx
);
4680 json_object_int_add(json_stat
, "mlagStatusUpdates",
4681 router
->mlag_stats
.msg
.mlag_status_updates
);
4682 json_object_int_add(json_stat
, "peerZebraStatusUpdates",
4683 router
->mlag_stats
.msg
.peer_zebra_status_updates
);
4684 json_object_int_add(json_stat
, "pimStatusUpdates",
4685 router
->mlag_stats
.msg
.pim_status_updates
);
4686 json_object_int_add(json_stat
, "vxlanUpdates",
4687 router
->mlag_stats
.msg
.vxlan_updates
);
4688 json_object_object_add(json
, "connStats", json_stat
);
4690 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4691 json
, JSON_C_TO_STRING_PRETTY
));
4692 json_object_free(json
);
4696 vty_out(vty
, "MLAG daemon connection: %s\n",
4697 (router
->mlag_flags
& PIM_MLAGF_LOCAL_CONN_UP
)
4699 vty_out(vty
, "MLAG peer state: %s\n",
4700 (router
->mlag_flags
& PIM_MLAGF_PEER_CONN_UP
)
4702 vty_out(vty
, "Zebra peer state: %s\n",
4703 (router
->mlag_flags
& PIM_MLAGF_PEER_ZEBRA_UP
)
4705 vty_out(vty
, "MLAG role: %s\n",
4706 mlag_role2str(router
->mlag_role
, role_buf
, sizeof(role_buf
)));
4707 inet_ntop(AF_INET
, &router
->local_vtep_ip
,
4708 addr_buf
, INET_ADDRSTRLEN
);
4709 vty_out(vty
, "Local VTEP IP: %s\n", addr_buf
);
4710 inet_ntop(AF_INET
, &router
->anycast_vtep_ip
,
4711 addr_buf
, INET_ADDRSTRLEN
);
4712 vty_out(vty
, "Anycast VTEP IP: %s\n", addr_buf
);
4713 vty_out(vty
, "Peerlink: %s\n", router
->peerlink_rif
);
4714 vty_out(vty
, "Session flaps: mlagd: %d mlag-peer: %d zebra-peer: %d\n",
4715 router
->mlag_stats
.mlagd_session_downs
,
4716 router
->mlag_stats
.peer_session_downs
,
4717 router
->mlag_stats
.peer_zebra_downs
);
4718 vty_out(vty
, "Message Statistics:\n");
4719 vty_out(vty
, " mroute adds: rx: %d, tx: %d\n",
4720 router
->mlag_stats
.msg
.mroute_add_rx
,
4721 router
->mlag_stats
.msg
.mroute_add_tx
);
4722 vty_out(vty
, " mroute dels: rx: %d, tx: %d\n",
4723 router
->mlag_stats
.msg
.mroute_del_rx
,
4724 router
->mlag_stats
.msg
.mroute_del_tx
);
4725 vty_out(vty
, " peer zebra status updates: %d\n",
4726 router
->mlag_stats
.msg
.peer_zebra_status_updates
);
4727 vty_out(vty
, " PIM status updates: %d\n",
4728 router
->mlag_stats
.msg
.pim_status_updates
);
4729 vty_out(vty
, " VxLAN updates: %d\n",
4730 router
->mlag_stats
.msg
.vxlan_updates
);
4735 static void pim_show_mlag_up_entry_detail(struct vrf
*vrf
,
4736 struct vty
*vty
, struct pim_upstream
*up
,
4737 char *src_str
, char *grp_str
, json_object
*json
)
4740 json_object
*json_row
= NULL
;
4741 json_object
*own_list
= NULL
;
4742 json_object
*json_group
= NULL
;
4745 json_object_object_get_ex(json
, grp_str
, &json_group
);
4747 json_group
= json_object_new_object();
4748 json_object_object_add(json
, grp_str
,
4752 json_row
= json_object_new_object();
4753 json_object_string_add(json_row
, "source", src_str
);
4754 json_object_string_add(json_row
, "group", grp_str
);
4756 own_list
= json_object_new_array();
4757 if (pim_up_mlag_is_local(up
))
4758 json_object_array_add(own_list
,
4759 json_object_new_string("local"));
4760 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
))
4761 json_object_array_add(own_list
,
4762 json_object_new_string("peer"));
4763 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE
))
4764 json_object_array_add(
4765 own_list
, json_object_new_string("Interface"));
4766 json_object_object_add(json_row
, "owners", own_list
);
4768 json_object_int_add(json_row
, "localCost",
4769 pim_up_mlag_local_cost(up
));
4770 json_object_int_add(json_row
, "peerCost",
4771 pim_up_mlag_peer_cost(up
));
4772 if (PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up
->flags
))
4773 json_object_boolean_false_add(json_row
, "df");
4775 json_object_boolean_true_add(json_row
, "df");
4776 json_object_object_add(json_group
, src_str
, json_row
);
4781 if (pim_up_mlag_is_local(up
))
4782 strlcat(own_str
, "L", sizeof(own_str
));
4783 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
))
4784 strlcat(own_str
, "P", sizeof(own_str
));
4785 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE
))
4786 strlcat(own_str
, "I", sizeof(own_str
));
4787 /* XXX - fixup, print paragraph output */
4789 "%-15s %-15s %-6s %-11u %-10d %2s\n",
4790 src_str
, grp_str
, own_str
,
4791 pim_up_mlag_local_cost(up
),
4792 pim_up_mlag_peer_cost(up
),
4793 PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up
->flags
)
4798 static void pim_show_mlag_up_detail(struct vrf
*vrf
,
4799 struct vty
*vty
, const char *src_or_group
,
4800 const char *group
, bool uj
)
4802 char src_str
[INET_ADDRSTRLEN
];
4803 char grp_str
[INET_ADDRSTRLEN
];
4804 struct pim_upstream
*up
;
4805 struct pim_instance
*pim
= vrf
->info
;
4806 json_object
*json
= NULL
;
4809 json
= json_object_new_object();
4812 "Source Group Owner Local-cost Peer-cost DF\n");
4814 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
4815 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
)
4816 && !(up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE
)
4817 && !pim_up_mlag_is_local(up
))
4820 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
4821 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
4822 /* XXX: strcmps are clearly inefficient. we should do uint comps
4826 if (strcmp(src_str
, src_or_group
) ||
4827 strcmp(grp_str
, group
))
4830 if (strcmp(src_str
, src_or_group
) &&
4831 strcmp(grp_str
, src_or_group
))
4834 pim_show_mlag_up_entry_detail(vrf
, vty
, up
,
4835 src_str
, grp_str
, json
);
4839 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4840 json
, JSON_C_TO_STRING_PRETTY
));
4841 json_object_free(json
);
4845 static void pim_show_mlag_up_vrf(struct vrf
*vrf
, struct vty
*vty
, bool uj
)
4847 json_object
*json
= NULL
;
4848 json_object
*json_row
;
4849 struct pim_upstream
*up
;
4850 char src_str
[INET_ADDRSTRLEN
];
4851 char grp_str
[INET_ADDRSTRLEN
];
4852 struct pim_instance
*pim
= vrf
->info
;
4853 json_object
*json_group
= NULL
;
4856 json
= json_object_new_object();
4859 "Source Group Owner Local-cost Peer-cost DF\n");
4862 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
4863 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
)
4864 && !(up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE
)
4865 && !pim_up_mlag_is_local(up
))
4867 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
4868 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
4870 json_object
*own_list
= NULL
;
4872 json_object_object_get_ex(json
, grp_str
, &json_group
);
4874 json_group
= json_object_new_object();
4875 json_object_object_add(json
, grp_str
,
4879 json_row
= json_object_new_object();
4880 json_object_string_add(json_row
, "vrf", vrf
->name
);
4881 json_object_string_add(json_row
, "source", src_str
);
4882 json_object_string_add(json_row
, "group", grp_str
);
4884 own_list
= json_object_new_array();
4885 if (pim_up_mlag_is_local(up
)) {
4887 json_object_array_add(own_list
,
4888 json_object_new_string("local"));
4890 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
)) {
4891 json_object_array_add(own_list
,
4892 json_object_new_string("peer"));
4894 json_object_object_add(json_row
, "owners", own_list
);
4896 json_object_int_add(json_row
, "localCost",
4897 pim_up_mlag_local_cost(up
));
4898 json_object_int_add(json_row
, "peerCost",
4899 pim_up_mlag_peer_cost(up
));
4900 if (PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up
->flags
))
4901 json_object_boolean_false_add(json_row
, "df");
4903 json_object_boolean_true_add(json_row
, "df");
4904 json_object_object_add(json_group
, src_str
, json_row
);
4909 if (pim_up_mlag_is_local(up
))
4910 strlcat(own_str
, "L", sizeof(own_str
));
4911 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
))
4912 strlcat(own_str
, "P", sizeof(own_str
));
4913 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE
))
4914 strlcat(own_str
, "I", sizeof(own_str
));
4916 "%-15s %-15s %-6s %-11u %-10u %2s\n",
4917 src_str
, grp_str
, own_str
,
4918 pim_up_mlag_local_cost(up
),
4919 pim_up_mlag_peer_cost(up
),
4920 PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up
->flags
)
4925 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4926 json
, JSON_C_TO_STRING_PRETTY
));
4927 json_object_free(json
);
4931 static void pim_show_mlag_help_string(struct vty
*vty
, bool uj
)
4934 vty_out(vty
, "Owner codes:\n");
4936 "L: EVPN-MLAG Entry, I:PIM-MLAG Entry, "
4942 DEFUN(show_ip_pim_mlag_up
, show_ip_pim_mlag_up_cmd
,
4943 "show ip pim [vrf NAME] mlag upstream [A.B.C.D [A.B.C.D]] [json]",
4950 "Unicast or Multicast address\n"
4951 "Multicast address\n" JSON_STR
)
4953 const char *src_or_group
= NULL
;
4954 const char *group
= NULL
;
4956 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4957 bool uj
= use_json(argc
, argv
);
4959 if (!vrf
|| !vrf
->info
) {
4960 vty_out(vty
, "%s: VRF or Info missing\n", __func__
);
4967 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
4968 src_or_group
= argv
[idx
]->arg
;
4970 group
= argv
[idx
+ 1]->arg
;
4973 pim_show_mlag_help_string(vty
, uj
);
4976 pim_show_mlag_up_detail(vrf
, vty
, src_or_group
, group
, uj
);
4978 pim_show_mlag_up_vrf(vrf
, vty
, uj
);
4984 DEFUN(show_ip_pim_mlag_up_vrf_all
, show_ip_pim_mlag_up_vrf_all_cmd
,
4985 "show ip pim vrf all mlag upstream [json]",
4986 SHOW_STR IP_STR PIM_STR VRF_CMD_HELP_STR
4988 "upstream\n" JSON_STR
)
4991 bool uj
= use_json(argc
, argv
);
4993 pim_show_mlag_help_string(vty
, uj
);
4994 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4995 pim_show_mlag_up_vrf(vrf
, vty
, uj
);
5001 DEFUN (show_ip_pim_neighbor
,
5002 show_ip_pim_neighbor_cmd
,
5003 "show ip pim [vrf NAME] neighbor [detail|WORD] [json]",
5008 "PIM neighbor information\n"
5010 "Name of interface or neighbor\n"
5014 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5015 bool uj
= use_json(argc
, argv
);
5020 if (argv_find(argv
, argc
, "detail", &idx
)
5021 || argv_find(argv
, argc
, "WORD", &idx
))
5022 pim_show_neighbors_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
5024 pim_show_neighbors(vrf
->info
, vty
, uj
);
5029 DEFUN (show_ip_pim_neighbor_vrf_all
,
5030 show_ip_pim_neighbor_vrf_all_cmd
,
5031 "show ip pim vrf all neighbor [detail|WORD] [json]",
5036 "PIM neighbor information\n"
5038 "Name of interface or neighbor\n"
5042 bool uj
= use_json(argc
, argv
);
5048 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5052 vty_out(vty
, " \"%s\": ", vrf
->name
);
5055 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5056 if (argv_find(argv
, argc
, "detail", &idx
)
5057 || argv_find(argv
, argc
, "WORD", &idx
))
5058 pim_show_neighbors_single(vrf
->info
, vty
,
5059 argv
[idx
]->arg
, uj
);
5061 pim_show_neighbors(vrf
->info
, vty
, uj
);
5064 vty_out(vty
, "}\n");
5069 DEFUN (show_ip_pim_secondary
,
5070 show_ip_pim_secondary_cmd
,
5071 "show ip pim [vrf NAME] secondary",
5076 "PIM neighbor addresses\n")
5079 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5084 pim_show_neighbors_secondary(vrf
->info
, vty
);
5089 DEFUN (show_ip_pim_state
,
5090 show_ip_pim_state_cmd
,
5091 "show ip pim [vrf NAME] state [A.B.C.D [A.B.C.D]] [json]",
5096 "PIM state information\n"
5097 "Unicast or Multicast address\n"
5098 "Multicast address\n"
5101 const char *src_or_group
= NULL
;
5102 const char *group
= NULL
;
5104 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5105 bool uj
= use_json(argc
, argv
);
5113 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
5114 src_or_group
= argv
[idx
]->arg
;
5116 group
= argv
[idx
+ 1]->arg
;
5119 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
5124 DEFUN (show_ip_pim_state_vrf_all
,
5125 show_ip_pim_state_vrf_all_cmd
,
5126 "show ip pim vrf all state [A.B.C.D [A.B.C.D]] [json]",
5131 "PIM state information\n"
5132 "Unicast or Multicast address\n"
5133 "Multicast address\n"
5136 const char *src_or_group
= NULL
;
5137 const char *group
= NULL
;
5139 bool uj
= use_json(argc
, argv
);
5148 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
5149 src_or_group
= argv
[idx
]->arg
;
5151 group
= argv
[idx
+ 1]->arg
;
5154 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5158 vty_out(vty
, " \"%s\": ", vrf
->name
);
5161 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5162 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
5165 vty_out(vty
, "}\n");
5170 DEFPY (show_ip_pim_upstream
,
5171 show_ip_pim_upstream_cmd
,
5172 "show ip pim [vrf NAME] upstream [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
5177 "PIM upstream information\n"
5178 "The Source or Group\n"
5182 struct prefix_sg sg
= {0};
5185 struct pim_instance
*pim
;
5187 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
5190 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
5193 pim
= pim_get_pim_instance(v
->vrf_id
);
5196 vty_out(vty
, "%% Unable to find pim instance\n");
5200 if (s_or_g
.s_addr
!= 0) {
5201 if (g
.s_addr
!= 0) {
5207 pim_show_upstream(pim
, vty
, &sg
, uj
);
5212 DEFUN (show_ip_pim_upstream_vrf_all
,
5213 show_ip_pim_upstream_vrf_all_cmd
,
5214 "show ip pim vrf all upstream [json]",
5219 "PIM upstream information\n"
5222 struct prefix_sg sg
= {0};
5223 bool uj
= use_json(argc
, argv
);
5229 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5233 vty_out(vty
, " \"%s\": ", vrf
->name
);
5236 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5237 pim_show_upstream(vrf
->info
, vty
, &sg
, uj
);
5243 DEFUN (show_ip_pim_channel
,
5244 show_ip_pim_channel_cmd
,
5245 "show ip pim [vrf NAME] channel [json]",
5250 "PIM downstream channel info\n"
5254 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5255 bool uj
= use_json(argc
, argv
);
5260 pim_show_channel(vrf
->info
, vty
, uj
);
5265 DEFUN (show_ip_pim_upstream_join_desired
,
5266 show_ip_pim_upstream_join_desired_cmd
,
5267 "show ip pim [vrf NAME] upstream-join-desired [json]",
5272 "PIM upstream join-desired\n"
5276 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5277 bool uj
= use_json(argc
, argv
);
5282 pim_show_join_desired(vrf
->info
, vty
, uj
);
5287 DEFUN (show_ip_pim_upstream_rpf
,
5288 show_ip_pim_upstream_rpf_cmd
,
5289 "show ip pim [vrf NAME] upstream-rpf [json]",
5294 "PIM upstream source rpf\n"
5298 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5299 bool uj
= use_json(argc
, argv
);
5304 pim_show_upstream_rpf(vrf
->info
, vty
, uj
);
5309 DEFUN (show_ip_pim_rp
,
5311 "show ip pim [vrf NAME] rp-info [json]",
5316 "PIM RP information\n"
5320 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5321 bool uj
= use_json(argc
, argv
);
5326 pim_rp_show_information(vrf
->info
, vty
, uj
);
5331 DEFUN (show_ip_pim_rp_vrf_all
,
5332 show_ip_pim_rp_vrf_all_cmd
,
5333 "show ip pim vrf all rp-info [json]",
5338 "PIM RP information\n"
5341 bool uj
= use_json(argc
, argv
);
5347 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5351 vty_out(vty
, " \"%s\": ", vrf
->name
);
5354 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5355 pim_rp_show_information(vrf
->info
, vty
, uj
);
5358 vty_out(vty
, "}\n");
5363 DEFUN (show_ip_pim_rpf
,
5364 show_ip_pim_rpf_cmd
,
5365 "show ip pim [vrf NAME] rpf [json]",
5370 "PIM cached source rpf information\n"
5374 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5375 bool uj
= use_json(argc
, argv
);
5380 pim_show_rpf(vrf
->info
, vty
, uj
);
5385 DEFUN (show_ip_pim_rpf_vrf_all
,
5386 show_ip_pim_rpf_vrf_all_cmd
,
5387 "show ip pim vrf all rpf [json]",
5392 "PIM cached source rpf information\n"
5395 bool uj
= use_json(argc
, argv
);
5401 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5405 vty_out(vty
, " \"%s\": ", vrf
->name
);
5408 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5409 pim_show_rpf(vrf
->info
, vty
, uj
);
5412 vty_out(vty
, "}\n");
5417 DEFUN (show_ip_pim_nexthop
,
5418 show_ip_pim_nexthop_cmd
,
5419 "show ip pim [vrf NAME] nexthop",
5424 "PIM cached nexthop rpf information\n")
5427 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5432 pim_show_nexthop(vrf
->info
, vty
);
5437 DEFUN (show_ip_pim_nexthop_lookup
,
5438 show_ip_pim_nexthop_lookup_cmd
,
5439 "show ip pim [vrf NAME] nexthop-lookup A.B.C.D A.B.C.D",
5444 "PIM cached nexthop rpf lookup\n"
5445 "Source/RP address\n"
5446 "Multicast Group address\n")
5448 struct prefix nht_p
;
5450 struct in_addr src_addr
, grp_addr
;
5451 struct in_addr vif_source
;
5452 const char *addr_str
, *addr_str1
;
5454 struct pim_nexthop nexthop
;
5455 char nexthop_addr_str
[PREFIX_STRLEN
];
5456 char grp_str
[PREFIX_STRLEN
];
5458 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5463 argv_find(argv
, argc
, "A.B.C.D", &idx
);
5464 addr_str
= argv
[idx
]->arg
;
5465 result
= inet_pton(AF_INET
, addr_str
, &src_addr
);
5467 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
5468 errno
, safe_strerror(errno
));
5472 if (pim_is_group_224_4(src_addr
)) {
5474 "Invalid argument. Expected Valid Source Address.\n");
5478 addr_str1
= argv
[idx
+ 1]->arg
;
5479 result
= inet_pton(AF_INET
, addr_str1
, &grp_addr
);
5481 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
5482 errno
, safe_strerror(errno
));
5486 if (!pim_is_group_224_4(grp_addr
)) {
5488 "Invalid argument. Expected Valid Multicast Group Address.\n");
5492 if (!pim_rp_set_upstream_addr(vrf
->info
, &vif_source
, src_addr
,
5496 nht_p
.family
= AF_INET
;
5497 nht_p
.prefixlen
= IPV4_MAX_BITLEN
;
5498 nht_p
.u
.prefix4
= vif_source
;
5499 grp
.family
= AF_INET
;
5500 grp
.prefixlen
= IPV4_MAX_BITLEN
;
5501 grp
.u
.prefix4
= grp_addr
;
5502 memset(&nexthop
, 0, sizeof(nexthop
));
5504 result
= pim_ecmp_nexthop_lookup(vrf
->info
, &nexthop
, &nht_p
, &grp
, 0);
5508 "Nexthop Lookup failed, no usable routes returned.\n");
5512 pim_addr_dump("<grp?>", &grp
, grp_str
, sizeof(grp_str
));
5513 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
5514 nexthop_addr_str
, sizeof(nexthop_addr_str
));
5515 vty_out(vty
, "Group %s --- Nexthop %s Interface %s \n", grp_str
,
5516 nexthop_addr_str
, nexthop
.interface
->name
);
5521 DEFUN (show_ip_pim_interface_traffic
,
5522 show_ip_pim_interface_traffic_cmd
,
5523 "show ip pim [vrf NAME] interface traffic [WORD] [json]",
5528 "PIM interface information\n"
5529 "Protocol Packet counters\n"
5534 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5535 bool uj
= use_json(argc
, argv
);
5540 if (argv_find(argv
, argc
, "WORD", &idx
))
5541 pim_show_interface_traffic_single(vrf
->info
, vty
,
5542 argv
[idx
]->arg
, uj
);
5544 pim_show_interface_traffic(vrf
->info
, vty
, uj
);
5549 DEFUN (show_ip_pim_bsm_db
,
5550 show_ip_pim_bsm_db_cmd
,
5551 "show ip pim bsm-database [vrf NAME] [json]",
5555 "PIM cached bsm packets information\n"
5560 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5561 bool uj
= use_json(argc
, argv
);
5566 pim_show_bsm_db(vrf
->info
, vty
, uj
);
5570 DEFUN (show_ip_pim_bsrp
,
5571 show_ip_pim_bsrp_cmd
,
5572 "show ip pim bsrp-info [vrf NAME] [json]",
5576 "PIM cached group-rp mappings information\n"
5581 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5582 bool uj
= use_json(argc
, argv
);
5587 pim_show_group_rp_mappings_info(vrf
->info
, vty
, uj
);
5592 DEFUN (show_ip_pim_statistics
,
5593 show_ip_pim_statistics_cmd
,
5594 "show ip pim [vrf NAME] statistics [interface WORD] [json]",
5605 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5606 bool uj
= use_json(argc
, argv
);
5611 if (argv_find(argv
, argc
, "WORD", &idx
))
5612 pim_show_statistics(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
5614 pim_show_statistics(vrf
->info
, vty
, NULL
, uj
);
5619 static void show_multicast_interfaces(struct pim_instance
*pim
, struct vty
*vty
)
5621 struct interface
*ifp
;
5626 "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut\n");
5628 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
5629 struct pim_interface
*pim_ifp
;
5630 struct in_addr ifaddr
;
5631 struct sioc_vif_req vreq
;
5633 pim_ifp
= ifp
->info
;
5638 memset(&vreq
, 0, sizeof(vreq
));
5639 vreq
.vifi
= pim_ifp
->mroute_vif_index
;
5641 if (ioctl(pim
->mroute_socket
, SIOCGETVIFCNT
, &vreq
)) {
5643 "ioctl(SIOCGETVIFCNT=%lu) failure for interface %s vif_index=%d: errno=%d: %s",
5644 (unsigned long)SIOCGETVIFCNT
, ifp
->name
,
5645 pim_ifp
->mroute_vif_index
, errno
,
5646 safe_strerror(errno
));
5649 ifaddr
= pim_ifp
->primary_address
;
5651 vty_out(vty
, "%-16s %-15s %3d %3d %7lu %7lu %10lu %10lu\n",
5652 ifp
->name
, inet_ntoa(ifaddr
), ifp
->ifindex
,
5653 pim_ifp
->mroute_vif_index
, (unsigned long)vreq
.icount
,
5654 (unsigned long)vreq
.ocount
, (unsigned long)vreq
.ibytes
,
5655 (unsigned long)vreq
.obytes
);
5659 static void pim_cmd_show_ip_multicast_helper(struct pim_instance
*pim
,
5662 struct vrf
*vrf
= pim
->vrf
;
5663 time_t now
= pim_time_monotonic_sec();
5669 vty_out(vty
, "Router MLAG Role: %s\n",
5670 mlag_role2str(router
->mlag_role
, mlag_role
, sizeof(mlag_role
)));
5671 vty_out(vty
, "Mroute socket descriptor:");
5673 vty_out(vty
, " %d(%s)\n", pim
->mroute_socket
, vrf
->name
);
5675 pim_time_uptime(uptime
, sizeof(uptime
),
5676 now
- pim
->mroute_socket_creation
);
5677 vty_out(vty
, "Mroute socket uptime: %s\n", uptime
);
5681 pim_zebra_zclient_update(vty
);
5682 pim_zlookup_show_ip_multicast(vty
);
5685 vty_out(vty
, "Maximum highest VifIndex: %d\n", PIM_MAX_USABLE_VIFS
);
5688 vty_out(vty
, "Upstream Join Timer: %d secs\n", router
->t_periodic
);
5689 vty_out(vty
, "Join/Prune Holdtime: %d secs\n", PIM_JP_HOLDTIME
);
5690 vty_out(vty
, "PIM ECMP: %s\n", pim
->ecmp_enable
? "Enable" : "Disable");
5691 vty_out(vty
, "PIM ECMP Rebalance: %s\n",
5692 pim
->ecmp_rebalance_enable
? "Enable" : "Disable");
5696 show_rpf_refresh_stats(vty
, pim
, now
, NULL
);
5700 show_scan_oil_stats(pim
, vty
, now
);
5702 show_multicast_interfaces(pim
, vty
);
5705 DEFUN (show_ip_multicast
,
5706 show_ip_multicast_cmd
,
5707 "show ip multicast [vrf NAME]",
5711 "Multicast global information\n")
5714 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5719 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
5724 DEFUN (show_ip_multicast_vrf_all
,
5725 show_ip_multicast_vrf_all_cmd
,
5726 "show ip multicast vrf all",
5730 "Multicast global information\n")
5732 bool uj
= use_json(argc
, argv
);
5738 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5742 vty_out(vty
, " \"%s\": ", vrf
->name
);
5745 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5746 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
5749 vty_out(vty
, "}\n");
5754 static void show_mroute(struct pim_instance
*pim
, struct vty
*vty
,
5755 struct prefix_sg
*sg
, bool fill
, bool uj
)
5757 struct listnode
*node
;
5758 struct channel_oil
*c_oil
;
5759 struct static_route
*s_route
;
5761 json_object
*json
= NULL
;
5762 json_object
*json_group
= NULL
;
5763 json_object
*json_source
= NULL
;
5764 json_object
*json_oil
= NULL
;
5765 json_object
*json_ifp_out
= NULL
;
5768 char grp_str
[INET_ADDRSTRLEN
];
5769 char src_str
[INET_ADDRSTRLEN
];
5770 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
5771 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
5773 struct interface
*ifp_in
;
5777 json
= json_object_new_object();
5780 "Source Group Proto Input Output TTL Uptime\n");
5783 now
= pim_time_monotonic_sec();
5785 /* print list of PIM and IGMP routes */
5786 frr_each (rb_pim_oil
, &pim
->channel_oil_head
, c_oil
) {
5789 if (!c_oil
->installed
&& !uj
)
5792 if (sg
->grp
.s_addr
!= 0 &&
5793 sg
->grp
.s_addr
!= c_oil
->oil
.mfcc_mcastgrp
.s_addr
)
5795 if (sg
->src
.s_addr
!= 0 &&
5796 sg
->src
.s_addr
!= c_oil
->oil
.mfcc_origin
.s_addr
)
5799 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
5801 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
5803 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
5806 strlcpy(in_ifname
, ifp_in
->name
, sizeof(in_ifname
));
5808 strlcpy(in_ifname
, "<iif?>", sizeof(in_ifname
));
5812 /* Find the group, create it if it doesn't exist */
5813 json_object_object_get_ex(json
, grp_str
, &json_group
);
5816 json_group
= json_object_new_object();
5817 json_object_object_add(json
, grp_str
,
5821 /* Find the source nested under the group, create it if
5822 * it doesn't exist */
5823 json_object_object_get_ex(json_group
, src_str
,
5827 json_source
= json_object_new_object();
5828 json_object_object_add(json_group
, src_str
,
5832 /* Find the inbound interface nested under the source,
5833 * create it if it doesn't exist */
5834 json_object_int_add(json_source
, "installed",
5836 json_object_int_add(json_source
, "refCount",
5837 c_oil
->oil_ref_count
);
5838 json_object_int_add(json_source
, "oilSize",
5840 json_object_int_add(json_source
, "OilInheritedRescan",
5841 c_oil
->oil_inherited_rescan
);
5842 json_object_string_add(json_source
, "iif", in_ifname
);
5846 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
5848 struct interface
*ifp_out
;
5849 char mroute_uptime
[10];
5852 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
5856 /* do not display muted OIFs */
5857 if (c_oil
->oif_flags
[oif_vif_index
]
5858 & PIM_OIF_FLAG_MUTE
)
5861 if (c_oil
->oil
.mfcc_parent
== oif_vif_index
&&
5862 !pim_mroute_allow_iif_in_oil(c_oil
,
5866 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
5868 mroute_uptime
, sizeof(mroute_uptime
),
5869 now
- c_oil
->mroute_creation
);
5873 strlcpy(out_ifname
, ifp_out
->name
, sizeof(out_ifname
));
5875 strlcpy(out_ifname
, "<oif?>", sizeof(out_ifname
));
5878 json_ifp_out
= json_object_new_object();
5879 json_object_string_add(json_ifp_out
, "source",
5881 json_object_string_add(json_ifp_out
, "group",
5884 if (c_oil
->oif_flags
[oif_vif_index
]
5885 & PIM_OIF_FLAG_PROTO_PIM
)
5886 json_object_boolean_true_add(
5887 json_ifp_out
, "protocolPim");
5889 if (c_oil
->oif_flags
[oif_vif_index
]
5890 & PIM_OIF_FLAG_PROTO_IGMP
)
5891 json_object_boolean_true_add(
5892 json_ifp_out
, "protocolIgmp");
5894 if (c_oil
->oif_flags
[oif_vif_index
]
5895 & PIM_OIF_FLAG_PROTO_VXLAN
)
5896 json_object_boolean_true_add(
5897 json_ifp_out
, "protocolVxlan");
5899 if (c_oil
->oif_flags
[oif_vif_index
]
5900 & PIM_OIF_FLAG_PROTO_STAR
)
5901 json_object_boolean_true_add(
5903 "protocolInherited");
5905 json_object_string_add(json_ifp_out
,
5908 json_object_int_add(json_ifp_out
, "iVifI",
5909 c_oil
->oil
.mfcc_parent
);
5910 json_object_string_add(json_ifp_out
,
5911 "outboundInterface",
5913 json_object_int_add(json_ifp_out
, "oVifI",
5915 json_object_int_add(json_ifp_out
, "ttl", ttl
);
5916 json_object_string_add(json_ifp_out
, "upTime",
5919 json_oil
= json_object_new_object();
5920 json_object_object_add(json_source
,
5923 json_object_object_add(json_oil
, out_ifname
,
5926 if (c_oil
->oif_flags
[oif_vif_index
]
5927 & PIM_OIF_FLAG_PROTO_PIM
) {
5928 strlcpy(proto
, "PIM", sizeof(proto
));
5931 if (c_oil
->oif_flags
[oif_vif_index
]
5932 & PIM_OIF_FLAG_PROTO_IGMP
) {
5933 strlcpy(proto
, "IGMP", sizeof(proto
));
5936 if (c_oil
->oif_flags
[oif_vif_index
]
5937 & PIM_OIF_FLAG_PROTO_VXLAN
) {
5938 strlcpy(proto
, "VxLAN", sizeof(proto
));
5941 if (c_oil
->oif_flags
[oif_vif_index
]
5942 & PIM_OIF_FLAG_PROTO_STAR
) {
5943 strlcpy(proto
, "STAR", sizeof(proto
));
5947 "%-15s %-15s %-6s %-16s %-16s %-3d %8s\n",
5948 src_str
, grp_str
, proto
, in_ifname
,
5949 out_ifname
, ttl
, mroute_uptime
);
5954 in_ifname
[0] = '\0';
5960 if (!uj
&& !found_oif
) {
5961 vty_out(vty
, "%-15s %-15s %-6s %-16s %-16s %-3d %8s\n",
5962 src_str
, grp_str
, "none", in_ifname
, "none", 0,
5967 /* Print list of static routes */
5968 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
5971 if (!s_route
->c_oil
.installed
)
5974 pim_inet4_dump("<group?>", s_route
->group
, grp_str
,
5976 pim_inet4_dump("<source?>", s_route
->source
, src_str
,
5978 ifp_in
= pim_if_find_by_vif_index(pim
, s_route
->iif
);
5982 strlcpy(in_ifname
, ifp_in
->name
, sizeof(in_ifname
));
5984 strlcpy(in_ifname
, "<iif?>", sizeof(in_ifname
));
5988 /* Find the group, create it if it doesn't exist */
5989 json_object_object_get_ex(json
, grp_str
, &json_group
);
5992 json_group
= json_object_new_object();
5993 json_object_object_add(json
, grp_str
,
5997 /* Find the source nested under the group, create it if
5998 * it doesn't exist */
5999 json_object_object_get_ex(json_group
, src_str
,
6003 json_source
= json_object_new_object();
6004 json_object_object_add(json_group
, src_str
,
6008 json_object_string_add(json_source
, "iif", in_ifname
);
6011 strlcpy(proto
, "STATIC", sizeof(proto
));
6014 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
6016 struct interface
*ifp_out
;
6017 char oif_uptime
[10];
6020 ttl
= s_route
->oif_ttls
[oif_vif_index
];
6024 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
6026 oif_uptime
, sizeof(oif_uptime
),
6029 .oif_creation
[oif_vif_index
]);
6033 strlcpy(out_ifname
, ifp_out
->name
, sizeof(out_ifname
));
6035 strlcpy(out_ifname
, "<oif?>", sizeof(out_ifname
));
6038 json_ifp_out
= json_object_new_object();
6039 json_object_string_add(json_ifp_out
, "source",
6041 json_object_string_add(json_ifp_out
, "group",
6043 json_object_boolean_true_add(json_ifp_out
,
6045 json_object_string_add(json_ifp_out
,
6048 json_object_int_add(
6049 json_ifp_out
, "iVifI",
6050 s_route
->c_oil
.oil
.mfcc_parent
);
6051 json_object_string_add(json_ifp_out
,
6052 "outboundInterface",
6054 json_object_int_add(json_ifp_out
, "oVifI",
6056 json_object_int_add(json_ifp_out
, "ttl", ttl
);
6057 json_object_string_add(json_ifp_out
, "upTime",
6060 json_oil
= json_object_new_object();
6061 json_object_object_add(json_source
,
6064 json_object_object_add(json_oil
, out_ifname
,
6068 "%-15s %-15s %-6s %-16s %-16s %-3d %8s %s\n",
6069 src_str
, grp_str
, proto
, in_ifname
,
6070 out_ifname
, ttl
, oif_uptime
,
6072 if (first
&& !fill
) {
6075 in_ifname
[0] = '\0';
6081 if (!uj
&& !found_oif
) {
6083 "%-15s %-15s %-6s %-16s %-16s %-3d %8s %s\n",
6084 src_str
, grp_str
, proto
, in_ifname
, "none", 0,
6085 "--:--:--", pim
->vrf
->name
);
6090 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
6091 json
, JSON_C_TO_STRING_PRETTY
));
6092 json_object_free(json
);
6096 DEFPY (show_ip_mroute
,
6098 "show ip mroute [vrf NAME] [A.B.C.D$s_or_g [A.B.C.D$g]] [fill$fill] [json$json]",
6103 "The Source or Group\n"
6105 "Fill in Assumed data\n"
6108 struct prefix_sg sg
= {0};
6109 struct pim_instance
*pim
;
6112 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
6115 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
6118 pim
= pim_get_pim_instance(v
->vrf_id
);
6121 vty_out(vty
, "%% Unable to find pim instance\n");
6125 if (s_or_g
.s_addr
!= 0) {
6126 if (g
.s_addr
!= 0) {
6132 show_mroute(pim
, vty
, &sg
, !!fill
, !!json
);
6136 DEFUN (show_ip_mroute_vrf_all
,
6137 show_ip_mroute_vrf_all_cmd
,
6138 "show ip mroute vrf all [fill] [json]",
6143 "Fill in Assumed data\n"
6146 struct prefix_sg sg
= {0};
6147 bool uj
= use_json(argc
, argv
);
6153 if (argv_find(argv
, argc
, "fill", &idx
))
6158 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
6162 vty_out(vty
, " \"%s\": ", vrf
->name
);
6165 vty_out(vty
, "VRF: %s\n", vrf
->name
);
6166 show_mroute(vrf
->info
, vty
, &sg
, fill
, uj
);
6169 vty_out(vty
, "}\n");
6174 DEFUN (clear_ip_mroute_count
,
6175 clear_ip_mroute_count_cmd
,
6176 "clear ip mroute [vrf NAME] count",
6181 "Route and packet count data\n")
6184 struct listnode
*node
;
6185 struct channel_oil
*c_oil
;
6186 struct static_route
*sr
;
6187 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6188 struct pim_instance
*pim
;
6194 frr_each(rb_pim_oil
, &pim
->channel_oil_head
, c_oil
) {
6195 if (!c_oil
->installed
)
6198 pim_mroute_update_counters(c_oil
);
6199 c_oil
->cc
.origpktcnt
= c_oil
->cc
.pktcnt
;
6200 c_oil
->cc
.origbytecnt
= c_oil
->cc
.bytecnt
;
6201 c_oil
->cc
.origwrong_if
= c_oil
->cc
.wrong_if
;
6204 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, sr
)) {
6205 if (!sr
->c_oil
.installed
)
6208 pim_mroute_update_counters(&sr
->c_oil
);
6210 sr
->c_oil
.cc
.origpktcnt
= sr
->c_oil
.cc
.pktcnt
;
6211 sr
->c_oil
.cc
.origbytecnt
= sr
->c_oil
.cc
.bytecnt
;
6212 sr
->c_oil
.cc
.origwrong_if
= sr
->c_oil
.cc
.wrong_if
;
6217 static void show_mroute_count(struct pim_instance
*pim
, struct vty
*vty
)
6219 struct listnode
*node
;
6220 struct channel_oil
*c_oil
;
6221 struct static_route
*sr
;
6226 "Source Group LastUsed Packets Bytes WrongIf \n");
6228 /* Print PIM and IGMP route counts */
6229 frr_each (rb_pim_oil
, &pim
->channel_oil_head
, c_oil
) {
6230 char group_str
[INET_ADDRSTRLEN
];
6231 char source_str
[INET_ADDRSTRLEN
];
6233 if (!c_oil
->installed
)
6236 pim_mroute_update_counters(c_oil
);
6238 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, group_str
,
6240 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, source_str
,
6241 sizeof(source_str
));
6243 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
6244 source_str
, group_str
, c_oil
->cc
.lastused
/ 100,
6245 c_oil
->cc
.pktcnt
- c_oil
->cc
.origpktcnt
,
6246 c_oil
->cc
.bytecnt
- c_oil
->cc
.origbytecnt
,
6247 c_oil
->cc
.wrong_if
- c_oil
->cc
.origwrong_if
);
6250 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, sr
)) {
6251 char group_str
[INET_ADDRSTRLEN
];
6252 char source_str
[INET_ADDRSTRLEN
];
6254 if (!sr
->c_oil
.installed
)
6257 pim_mroute_update_counters(&sr
->c_oil
);
6259 pim_inet4_dump("<group?>", sr
->c_oil
.oil
.mfcc_mcastgrp
,
6260 group_str
, sizeof(group_str
));
6261 pim_inet4_dump("<source?>", sr
->c_oil
.oil
.mfcc_origin
,
6262 source_str
, sizeof(source_str
));
6264 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
6265 source_str
, group_str
, sr
->c_oil
.cc
.lastused
,
6266 sr
->c_oil
.cc
.pktcnt
- sr
->c_oil
.cc
.origpktcnt
,
6267 sr
->c_oil
.cc
.bytecnt
- sr
->c_oil
.cc
.origbytecnt
,
6268 sr
->c_oil
.cc
.wrong_if
- sr
->c_oil
.cc
.origwrong_if
);
6272 DEFUN (show_ip_mroute_count
,
6273 show_ip_mroute_count_cmd
,
6274 "show ip mroute [vrf NAME] count",
6279 "Route and packet count data\n")
6282 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6287 show_mroute_count(vrf
->info
, vty
);
6291 DEFUN (show_ip_mroute_count_vrf_all
,
6292 show_ip_mroute_count_vrf_all_cmd
,
6293 "show ip mroute vrf all count",
6298 "Route and packet count data\n")
6300 bool uj
= use_json(argc
, argv
);
6306 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
6310 vty_out(vty
, " \"%s\": ", vrf
->name
);
6313 vty_out(vty
, "VRF: %s\n", vrf
->name
);
6314 show_mroute_count(vrf
->info
, vty
);
6317 vty_out(vty
, "}\n");
6322 static void show_mroute_summary(struct pim_instance
*pim
, struct vty
*vty
)
6324 struct listnode
*node
;
6325 struct channel_oil
*c_oil
;
6326 struct static_route
*s_route
;
6327 uint32_t starg_sw_mroute_cnt
= 0;
6328 uint32_t sg_sw_mroute_cnt
= 0;
6329 uint32_t starg_hw_mroute_cnt
= 0;
6330 uint32_t sg_hw_mroute_cnt
= 0;
6332 vty_out(vty
, "Mroute Type Installed/Total\n");
6334 frr_each (rb_pim_oil
, &pim
->channel_oil_head
, c_oil
) {
6335 if (!c_oil
->installed
) {
6336 if (c_oil
->oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
6337 starg_sw_mroute_cnt
++;
6341 if (c_oil
->oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
6342 starg_hw_mroute_cnt
++;
6348 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
6349 if (!s_route
->c_oil
.installed
) {
6350 if (s_route
->c_oil
.oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
6351 starg_sw_mroute_cnt
++;
6355 if (s_route
->c_oil
.oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
6356 starg_hw_mroute_cnt
++;
6362 vty_out(vty
, "%-20s %d/%d\n", "(*, G)", starg_hw_mroute_cnt
,
6363 starg_sw_mroute_cnt
+ starg_hw_mroute_cnt
);
6364 vty_out(vty
, "%-20s %d/%d\n", "(S, G)", sg_hw_mroute_cnt
,
6365 sg_sw_mroute_cnt
+ sg_hw_mroute_cnt
);
6366 vty_out(vty
, "------\n");
6367 vty_out(vty
, "%-20s %d/%d\n", "Total",
6368 (starg_hw_mroute_cnt
+ sg_hw_mroute_cnt
),
6369 (starg_sw_mroute_cnt
+
6370 starg_hw_mroute_cnt
+
6375 DEFUN (show_ip_mroute_summary
,
6376 show_ip_mroute_summary_cmd
,
6377 "show ip mroute [vrf NAME] summary",
6382 "Summary of all mroutes\n")
6385 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6390 show_mroute_summary(vrf
->info
, vty
);
6394 DEFUN (show_ip_mroute_summary_vrf_all
,
6395 show_ip_mroute_summary_vrf_all_cmd
,
6396 "show ip mroute vrf all summary",
6401 "Summary of all mroutes\n")
6405 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
6406 vty_out(vty
, "VRF: %s\n", vrf
->name
);
6407 show_mroute_summary(vrf
->info
, vty
);
6415 "show ip rib [vrf NAME] A.B.C.D",
6420 "Unicast address\n")
6423 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6424 struct in_addr addr
;
6425 const char *addr_str
;
6426 struct pim_nexthop nexthop
;
6427 char nexthop_addr_str
[PREFIX_STRLEN
];
6433 memset(&nexthop
, 0, sizeof(nexthop
));
6434 argv_find(argv
, argc
, "A.B.C.D", &idx
);
6435 addr_str
= argv
[idx
]->arg
;
6436 result
= inet_pton(AF_INET
, addr_str
, &addr
);
6438 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
6439 errno
, safe_strerror(errno
));
6443 if (!pim_nexthop_lookup(vrf
->info
, &nexthop
, addr
, 0)) {
6445 "Failure querying RIB nexthop for unicast address %s\n",
6451 "Address NextHop Interface Metric Preference\n");
6453 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
6454 nexthop_addr_str
, sizeof(nexthop_addr_str
));
6456 vty_out(vty
, "%-15s %-15s %-9s %6d %10d\n", addr_str
, nexthop_addr_str
,
6457 nexthop
.interface
? nexthop
.interface
->name
: "<ifname?>",
6458 nexthop
.mrib_route_metric
, nexthop
.mrib_metric_preference
);
6463 static void show_ssmpingd(struct pim_instance
*pim
, struct vty
*vty
)
6465 struct listnode
*node
;
6466 struct ssmpingd_sock
*ss
;
6470 "Source Socket Address Port Uptime Requests\n");
6472 if (!pim
->ssmpingd_list
)
6475 now
= pim_time_monotonic_sec();
6477 for (ALL_LIST_ELEMENTS_RO(pim
->ssmpingd_list
, node
, ss
)) {
6478 char source_str
[INET_ADDRSTRLEN
];
6480 struct sockaddr_in bind_addr
;
6481 socklen_t len
= sizeof(bind_addr
);
6482 char bind_addr_str
[INET_ADDRSTRLEN
];
6484 pim_inet4_dump("<src?>", ss
->source_addr
, source_str
,
6485 sizeof(source_str
));
6487 if (pim_socket_getsockname(
6488 ss
->sock_fd
, (struct sockaddr
*)&bind_addr
, &len
)) {
6490 "%% Failure reading socket name for ssmpingd source %s on fd=%d\n",
6491 source_str
, ss
->sock_fd
);
6494 pim_inet4_dump("<addr?>", bind_addr
.sin_addr
, bind_addr_str
,
6495 sizeof(bind_addr_str
));
6496 pim_time_uptime(ss_uptime
, sizeof(ss_uptime
),
6497 now
- ss
->creation
);
6499 vty_out(vty
, "%-15s %6d %-15s %5d %8s %8lld\n", source_str
,
6500 ss
->sock_fd
, bind_addr_str
, ntohs(bind_addr
.sin_port
),
6501 ss_uptime
, (long long)ss
->requests
);
6505 DEFUN (show_ip_ssmpingd
,
6506 show_ip_ssmpingd_cmd
,
6507 "show ip ssmpingd [vrf NAME]",
6514 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6519 show_ssmpingd(vrf
->info
, vty
);
6523 static int pim_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
6524 const char *rp
, const char *group
,
6529 result
= pim_rp_new_config(pim
, rp
, group
, plist
);
6531 if (result
== PIM_GROUP_BAD_ADDR_MASK_COMBO
) {
6532 vty_out(vty
, "%% Inconsistent address and mask: %s\n",
6534 return CMD_WARNING_CONFIG_FAILED
;
6537 if (result
== PIM_GROUP_BAD_ADDRESS
) {
6538 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
6539 return CMD_WARNING_CONFIG_FAILED
;
6542 if (result
== PIM_RP_BAD_ADDRESS
) {
6543 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
6544 return CMD_WARNING_CONFIG_FAILED
;
6547 if (result
== PIM_RP_NO_PATH
) {
6548 vty_out(vty
, "%% No Path to RP address specified: %s\n", rp
);
6552 if (result
== PIM_GROUP_OVERLAP
) {
6554 "%% Group range specified cannot exact match another\n");
6555 return CMD_WARNING_CONFIG_FAILED
;
6558 if (result
== PIM_GROUP_PFXLIST_OVERLAP
) {
6560 "%% This group is already covered by a RP prefix-list\n");
6561 return CMD_WARNING_CONFIG_FAILED
;
6564 if (result
== PIM_RP_PFXLIST_IN_USE
) {
6566 "%% The same prefix-list cannot be applied to multiple RPs\n");
6567 return CMD_WARNING_CONFIG_FAILED
;
6573 static int pim_cmd_spt_switchover(struct pim_instance
*pim
,
6574 enum pim_spt_switchover spt
,
6577 pim
->spt
.switchover
= spt
;
6579 switch (pim
->spt
.switchover
) {
6580 case PIM_SPT_IMMEDIATE
:
6581 XFREE(MTYPE_PIM_SPT_PLIST_NAME
, pim
->spt
.plist
);
6583 pim_upstream_add_lhr_star_pimreg(pim
);
6585 case PIM_SPT_INFINITY
:
6586 pim_upstream_remove_lhr_star_pimreg(pim
, plist
);
6588 XFREE(MTYPE_PIM_SPT_PLIST_NAME
, pim
->spt
.plist
);
6592 XSTRDUP(MTYPE_PIM_SPT_PLIST_NAME
, plist
);
6599 DEFUN (ip_pim_spt_switchover_infinity
,
6600 ip_pim_spt_switchover_infinity_cmd
,
6601 "ip pim spt-switchover infinity-and-beyond",
6605 "Never switch to SPT Tree\n")
6607 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6608 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, NULL
);
6611 DEFUN (ip_pim_spt_switchover_infinity_plist
,
6612 ip_pim_spt_switchover_infinity_plist_cmd
,
6613 "ip pim spt-switchover infinity-and-beyond prefix-list WORD",
6617 "Never switch to SPT Tree\n"
6618 "Prefix-List to control which groups to switch\n"
6619 "Prefix-List name\n")
6621 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6622 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, argv
[5]->arg
);
6625 DEFUN (no_ip_pim_spt_switchover_infinity
,
6626 no_ip_pim_spt_switchover_infinity_cmd
,
6627 "no ip pim spt-switchover infinity-and-beyond",
6632 "Never switch to SPT Tree\n")
6634 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6635 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
6638 DEFUN (no_ip_pim_spt_switchover_infinity_plist
,
6639 no_ip_pim_spt_switchover_infinity_plist_cmd
,
6640 "no ip pim spt-switchover infinity-and-beyond prefix-list WORD",
6645 "Never switch to SPT Tree\n"
6646 "Prefix-List to control which groups to switch\n"
6647 "Prefix-List name\n")
6649 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6650 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
6653 DEFUN (ip_pim_joinprune_time
,
6654 ip_pim_joinprune_time_cmd
,
6655 "ip pim join-prune-interval (60-600)",
6657 "pim multicast routing\n"
6658 "Join Prune Send Interval\n"
6661 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6662 router
->t_periodic
= atoi(argv
[3]->arg
);
6666 DEFUN (no_ip_pim_joinprune_time
,
6667 no_ip_pim_joinprune_time_cmd
,
6668 "no ip pim join-prune-interval (60-600)",
6671 "pim multicast routing\n"
6672 "Join Prune Send Interval\n"
6675 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6676 router
->t_periodic
= PIM_DEFAULT_T_PERIODIC
;
6680 DEFUN (ip_pim_register_suppress
,
6681 ip_pim_register_suppress_cmd
,
6682 "ip pim register-suppress-time (5-60000)",
6684 "pim multicast routing\n"
6685 "Register Suppress Timer\n"
6688 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6689 router
->register_suppress_time
= atoi(argv
[3]->arg
);
6693 DEFUN (no_ip_pim_register_suppress
,
6694 no_ip_pim_register_suppress_cmd
,
6695 "no ip pim register-suppress-time (5-60000)",
6698 "pim multicast routing\n"
6699 "Register Suppress Timer\n"
6702 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6703 router
->register_suppress_time
= PIM_REGISTER_SUPPRESSION_TIME_DEFAULT
;
6707 DEFUN (ip_pim_rp_keep_alive
,
6708 ip_pim_rp_keep_alive_cmd
,
6709 "ip pim rp keep-alive-timer (31-60000)",
6711 "pim multicast routing\n"
6713 "Keep alive Timer\n"
6716 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6717 pim
->rp_keep_alive_time
= atoi(argv
[4]->arg
);
6721 DEFUN (no_ip_pim_rp_keep_alive
,
6722 no_ip_pim_rp_keep_alive_cmd
,
6723 "no ip pim rp keep-alive-timer (31-60000)",
6726 "pim multicast routing\n"
6728 "Keep alive Timer\n"
6731 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6732 pim
->rp_keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
6736 DEFUN (ip_pim_keep_alive
,
6737 ip_pim_keep_alive_cmd
,
6738 "ip pim keep-alive-timer (31-60000)",
6740 "pim multicast routing\n"
6741 "Keep alive Timer\n"
6744 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6745 pim
->keep_alive_time
= atoi(argv
[3]->arg
);
6749 DEFUN (no_ip_pim_keep_alive
,
6750 no_ip_pim_keep_alive_cmd
,
6751 "no ip pim keep-alive-timer (31-60000)",
6754 "pim multicast routing\n"
6755 "Keep alive Timer\n"
6758 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6759 pim
->keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
6763 DEFUN (ip_pim_packets
,
6765 "ip pim packets (1-100)",
6767 "pim multicast routing\n"
6768 "packets to process at one time per fd\n"
6769 "Number of packets\n")
6771 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6772 router
->packet_process
= atoi(argv
[3]->arg
);
6776 DEFUN (no_ip_pim_packets
,
6777 no_ip_pim_packets_cmd
,
6778 "no ip pim packets (1-100)",
6781 "pim multicast routing\n"
6782 "packets to process at one time per fd\n"
6783 "Number of packets\n")
6785 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6786 router
->packet_process
= PIM_DEFAULT_PACKET_PROCESS
;
6790 DEFUN (ip_pim_v6_secondary
,
6791 ip_pim_v6_secondary_cmd
,
6792 "ip pim send-v6-secondary",
6794 "pim multicast routing\n"
6795 "Send v6 secondary addresses\n")
6797 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6798 pim
->send_v6_secondary
= 1;
6803 DEFUN (no_ip_pim_v6_secondary
,
6804 no_ip_pim_v6_secondary_cmd
,
6805 "no ip pim send-v6-secondary",
6808 "pim multicast routing\n"
6809 "Send v6 secondary addresses\n")
6811 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6812 pim
->send_v6_secondary
= 0;
6819 "ip pim rp A.B.C.D [A.B.C.D/M]",
6821 "pim multicast routing\n"
6823 "ip address of RP\n"
6824 "Group Address range to cover\n")
6826 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6829 if (argc
== (idx_ipv4
+ 1))
6830 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
6833 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
6834 argv
[idx_ipv4
+ 1]->arg
, NULL
);
6837 DEFUN (ip_pim_rp_prefix_list
,
6838 ip_pim_rp_prefix_list_cmd
,
6839 "ip pim rp A.B.C.D prefix-list WORD",
6841 "pim multicast routing\n"
6843 "ip address of RP\n"
6844 "group prefix-list filter\n"
6845 "Name of a prefix-list\n")
6847 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6848 return pim_rp_cmd_worker(pim
, vty
, argv
[3]->arg
, NULL
, argv
[5]->arg
);
6851 static int pim_no_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
6852 const char *rp
, const char *group
,
6855 int result
= pim_rp_del_config(pim
, rp
, group
, plist
);
6857 if (result
== PIM_GROUP_BAD_ADDRESS
) {
6858 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
6859 return CMD_WARNING_CONFIG_FAILED
;
6862 if (result
== PIM_RP_BAD_ADDRESS
) {
6863 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
6864 return CMD_WARNING_CONFIG_FAILED
;
6867 if (result
== PIM_RP_NOT_FOUND
) {
6868 vty_out(vty
, "%% Unable to find specified RP\n");
6869 return CMD_WARNING_CONFIG_FAILED
;
6875 DEFUN (no_ip_pim_rp
,
6877 "no ip pim rp A.B.C.D [A.B.C.D/M]",
6880 "pim multicast routing\n"
6882 "ip address of RP\n"
6883 "Group Address range to cover\n")
6885 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6886 int idx_ipv4
= 4, idx_group
= 0;
6888 if (argv_find(argv
, argc
, "A.B.C.D/M", &idx_group
))
6889 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
6890 argv
[idx_group
]->arg
, NULL
);
6892 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
6896 DEFUN (no_ip_pim_rp_prefix_list
,
6897 no_ip_pim_rp_prefix_list_cmd
,
6898 "no ip pim rp A.B.C.D prefix-list WORD",
6901 "pim multicast routing\n"
6903 "ip address of RP\n"
6904 "group prefix-list filter\n"
6905 "Name of a prefix-list\n")
6907 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6908 return pim_no_rp_cmd_worker(pim
, vty
, argv
[4]->arg
, NULL
, argv
[6]->arg
);
6911 static int pim_ssm_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
6914 int result
= pim_ssm_range_set(pim
, pim
->vrf_id
, plist
);
6915 int ret
= CMD_WARNING_CONFIG_FAILED
;
6917 if (result
== PIM_SSM_ERR_NONE
)
6921 case PIM_SSM_ERR_NO_VRF
:
6922 vty_out(vty
, "%% VRF doesn't exist\n");
6924 case PIM_SSM_ERR_DUP
:
6925 vty_out(vty
, "%% duplicate config\n");
6929 vty_out(vty
, "%% ssm range config failed\n");
6935 DEFUN (ip_pim_ssm_prefix_list
,
6936 ip_pim_ssm_prefix_list_cmd
,
6937 "ip pim ssm prefix-list WORD",
6939 "pim multicast routing\n"
6940 "Source Specific Multicast\n"
6941 "group range prefix-list filter\n"
6942 "Name of a prefix-list\n")
6944 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6945 return pim_ssm_cmd_worker(pim
, vty
, argv
[4]->arg
);
6948 DEFUN (no_ip_pim_ssm_prefix_list
,
6949 no_ip_pim_ssm_prefix_list_cmd
,
6950 "no ip pim ssm prefix-list",
6953 "pim multicast routing\n"
6954 "Source Specific Multicast\n"
6955 "group range prefix-list filter\n")
6957 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6958 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
6961 DEFUN (no_ip_pim_ssm_prefix_list_name
,
6962 no_ip_pim_ssm_prefix_list_name_cmd
,
6963 "no ip pim ssm prefix-list WORD",
6966 "pim multicast routing\n"
6967 "Source Specific Multicast\n"
6968 "group range prefix-list filter\n"
6969 "Name of a prefix-list\n")
6971 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6972 struct pim_ssm
*ssm
= pim
->ssm_info
;
6974 if (ssm
->plist_name
&& !strcmp(ssm
->plist_name
, argv
[5]->arg
))
6975 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
6977 vty_out(vty
, "%% pim ssm prefix-list %s doesn't exist\n", argv
[5]->arg
);
6979 return CMD_WARNING_CONFIG_FAILED
;
6982 static void ip_pim_ssm_show_group_range(struct pim_instance
*pim
,
6983 struct vty
*vty
, bool uj
)
6985 struct pim_ssm
*ssm
= pim
->ssm_info
;
6986 const char *range_str
=
6987 ssm
->plist_name
? ssm
->plist_name
: PIM_SSM_STANDARD_RANGE
;
6991 json
= json_object_new_object();
6992 json_object_string_add(json
, "ssmGroups", range_str
);
6993 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
6994 json
, JSON_C_TO_STRING_PRETTY
));
6995 json_object_free(json
);
6997 vty_out(vty
, "SSM group range : %s\n", range_str
);
7000 DEFUN (show_ip_pim_ssm_range
,
7001 show_ip_pim_ssm_range_cmd
,
7002 "show ip pim [vrf NAME] group-type [json]",
7011 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
7012 bool uj
= use_json(argc
, argv
);
7017 ip_pim_ssm_show_group_range(vrf
->info
, vty
, uj
);
7022 static void ip_pim_ssm_show_group_type(struct pim_instance
*pim
,
7023 struct vty
*vty
, bool uj
,
7026 struct in_addr group_addr
;
7027 const char *type_str
;
7030 result
= inet_pton(AF_INET
, group
, &group_addr
);
7032 type_str
= "invalid";
7034 if (pim_is_group_224_4(group_addr
))
7036 pim_is_grp_ssm(pim
, group_addr
) ? "SSM" : "ASM";
7038 type_str
= "not-multicast";
7043 json
= json_object_new_object();
7044 json_object_string_add(json
, "groupType", type_str
);
7045 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
7046 json
, JSON_C_TO_STRING_PRETTY
));
7047 json_object_free(json
);
7049 vty_out(vty
, "Group type : %s\n", type_str
);
7052 DEFUN (show_ip_pim_group_type
,
7053 show_ip_pim_group_type_cmd
,
7054 "show ip pim [vrf NAME] group-type A.B.C.D [json]",
7059 "multicast group type\n"
7064 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
7065 bool uj
= use_json(argc
, argv
);
7070 argv_find(argv
, argc
, "A.B.C.D", &idx
);
7071 ip_pim_ssm_show_group_type(vrf
->info
, vty
, uj
, argv
[idx
]->arg
);
7076 DEFUN (show_ip_pim_bsr
,
7077 show_ip_pim_bsr_cmd
,
7078 "show ip pim bsr [json]",
7082 "boot-strap router information\n"
7086 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
7087 bool uj
= use_json(argc
, argv
);
7092 pim_show_bsr(vrf
->info
, vty
, uj
);
7099 "ip ssmpingd [A.B.C.D]",
7104 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7107 struct in_addr source_addr
;
7108 const char *source_str
= (argc
== 3) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
7110 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
7112 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
7113 source_str
, errno
, safe_strerror(errno
));
7114 return CMD_WARNING_CONFIG_FAILED
;
7117 result
= pim_ssmpingd_start(pim
, source_addr
);
7119 vty_out(vty
, "%% Failure starting ssmpingd for source %s: %d\n",
7120 source_str
, result
);
7121 return CMD_WARNING_CONFIG_FAILED
;
7127 DEFUN (no_ip_ssmpingd
,
7129 "no ip ssmpingd [A.B.C.D]",
7135 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7138 struct in_addr source_addr
;
7139 const char *source_str
= (argc
== 4) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
7141 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
7143 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
7144 source_str
, errno
, safe_strerror(errno
));
7145 return CMD_WARNING_CONFIG_FAILED
;
7148 result
= pim_ssmpingd_stop(pim
, source_addr
);
7150 vty_out(vty
, "%% Failure stopping ssmpingd for source %s: %d\n",
7151 source_str
, result
);
7152 return CMD_WARNING_CONFIG_FAILED
;
7162 "pim multicast routing\n"
7163 "Enable PIM ECMP \n")
7165 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7166 pim
->ecmp_enable
= true;
7171 DEFUN (no_ip_pim_ecmp
,
7176 "pim multicast routing\n"
7177 "Disable PIM ECMP \n")
7179 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7180 pim
->ecmp_enable
= false;
7185 DEFUN (ip_pim_ecmp_rebalance
,
7186 ip_pim_ecmp_rebalance_cmd
,
7187 "ip pim ecmp rebalance",
7189 "pim multicast routing\n"
7190 "Enable PIM ECMP \n"
7191 "Enable PIM ECMP Rebalance\n")
7193 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7194 pim
->ecmp_enable
= true;
7195 pim
->ecmp_rebalance_enable
= true;
7200 DEFUN (no_ip_pim_ecmp_rebalance
,
7201 no_ip_pim_ecmp_rebalance_cmd
,
7202 "no ip pim ecmp rebalance",
7205 "pim multicast routing\n"
7206 "Disable PIM ECMP \n"
7207 "Disable PIM ECMP Rebalance\n")
7209 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7210 pim
->ecmp_rebalance_enable
= false;
7215 static int pim_cmd_igmp_start(struct vty
*vty
, struct interface
*ifp
)
7217 struct pim_interface
*pim_ifp
;
7218 uint8_t need_startup
= 0;
7220 pim_ifp
= ifp
->info
;
7223 (void)pim_if_new(ifp
, true, false, false, false);
7226 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
7227 PIM_IF_DO_IGMP(pim_ifp
->options
);
7232 /* 'ip igmp' executed multiple times, with need_startup
7233 avoid multiple if add all and membership refresh */
7235 pim_if_addr_add_all(ifp
);
7236 pim_if_membership_refresh(ifp
);
7242 DEFUN (interface_ip_igmp
,
7243 interface_ip_igmp_cmd
,
7248 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7250 return pim_cmd_igmp_start(vty
, ifp
);
7253 DEFUN (interface_no_ip_igmp
,
7254 interface_no_ip_igmp_cmd
,
7260 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7261 struct pim_interface
*pim_ifp
= ifp
->info
;
7266 PIM_IF_DONT_IGMP(pim_ifp
->options
);
7268 pim_if_membership_clear(ifp
);
7270 pim_if_addr_del_all_igmp(ifp
);
7272 if (!PIM_IF_TEST_PIM(pim_ifp
->options
)) {
7279 DEFUN (interface_ip_igmp_join
,
7280 interface_ip_igmp_join_cmd
,
7281 "ip igmp join A.B.C.D [A.B.C.D]",
7284 "IGMP join multicast group\n"
7285 "Multicast group address\n"
7288 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7291 const char *group_str
;
7292 const char *source_str
;
7293 struct in_addr group_addr
;
7294 struct in_addr source_addr
;
7298 group_str
= argv
[idx_ipv4
]->arg
;
7299 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
7301 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
7302 errno
, safe_strerror(errno
));
7303 return CMD_WARNING_CONFIG_FAILED
;
7306 /* Source address */
7307 if (argc
== (idx_ipv4_2
+ 1)) {
7308 source_str
= argv
[idx_ipv4_2
]->arg
;
7309 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
7311 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
7312 source_str
, errno
, safe_strerror(errno
));
7313 return CMD_WARNING_CONFIG_FAILED
;
7315 /* Reject 0.0.0.0. Reserved for any source. */
7316 if (source_addr
.s_addr
== INADDR_ANY
) {
7317 vty_out(vty
, "Bad source address %s\n", source_str
);
7318 return CMD_WARNING_CONFIG_FAILED
;
7321 source_addr
.s_addr
= INADDR_ANY
;
7324 CMD_FERR_RETURN(pim_if_igmp_join_add(ifp
, group_addr
, source_addr
),
7325 "Failure joining IGMP group: $ERR");
7330 DEFUN (interface_no_ip_igmp_join
,
7331 interface_no_ip_igmp_join_cmd
,
7332 "no ip igmp join A.B.C.D [A.B.C.D]",
7336 "IGMP join multicast group\n"
7337 "Multicast group address\n"
7340 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7343 const char *group_str
;
7344 const char *source_str
;
7345 struct in_addr group_addr
;
7346 struct in_addr source_addr
;
7350 group_str
= argv
[idx_ipv4
]->arg
;
7351 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
7353 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
7354 errno
, safe_strerror(errno
));
7355 return CMD_WARNING_CONFIG_FAILED
;
7358 /* Source address */
7359 if (argc
== (idx_ipv4_2
+ 1)) {
7360 source_str
= argv
[idx_ipv4_2
]->arg
;
7361 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
7363 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
7364 source_str
, errno
, safe_strerror(errno
));
7365 return CMD_WARNING_CONFIG_FAILED
;
7367 /* Reject 0.0.0.0. Reserved for any source. */
7368 if (source_addr
.s_addr
== INADDR_ANY
) {
7369 vty_out(vty
, "Bad source address %s\n", source_str
);
7370 return CMD_WARNING_CONFIG_FAILED
;
7374 source_addr
.s_addr
= INADDR_ANY
;
7377 result
= pim_if_igmp_join_del(ifp
, group_addr
, source_addr
);
7380 "%% Failure leaving IGMP group %s source %s on interface %s: %d\n",
7381 group_str
, source_str
, ifp
->name
, result
);
7382 return CMD_WARNING_CONFIG_FAILED
;
7389 CLI reconfiguration affects the interface level (struct pim_interface).
7390 This function propagates the reconfiguration to every active socket
7393 static void igmp_sock_query_interval_reconfig(struct igmp_sock
*igmp
)
7395 struct interface
*ifp
;
7396 struct pim_interface
*pim_ifp
;
7400 /* other querier present? */
7402 if (igmp
->t_other_querier_timer
)
7405 /* this is the querier */
7407 zassert(igmp
->interface
);
7408 zassert(igmp
->interface
->info
);
7410 ifp
= igmp
->interface
;
7411 pim_ifp
= ifp
->info
;
7413 if (PIM_DEBUG_IGMP_TRACE
) {
7414 char ifaddr_str
[INET_ADDRSTRLEN
];
7415 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
7416 sizeof(ifaddr_str
));
7417 zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
7418 __PRETTY_FUNCTION__
, ifaddr_str
, ifp
->name
,
7419 pim_ifp
->igmp_default_query_interval
);
7423 igmp_startup_mode_on() will reset QQI:
7425 igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
7427 igmp_startup_mode_on(igmp
);
7430 static void igmp_sock_query_reschedule(struct igmp_sock
*igmp
)
7432 if (igmp
->mtrace_only
)
7435 if (igmp
->t_igmp_query_timer
) {
7436 /* other querier present */
7437 zassert(igmp
->t_igmp_query_timer
);
7438 zassert(!igmp
->t_other_querier_timer
);
7440 pim_igmp_general_query_off(igmp
);
7441 pim_igmp_general_query_on(igmp
);
7443 zassert(igmp
->t_igmp_query_timer
);
7444 zassert(!igmp
->t_other_querier_timer
);
7446 /* this is the querier */
7448 zassert(!igmp
->t_igmp_query_timer
);
7449 zassert(igmp
->t_other_querier_timer
);
7451 pim_igmp_other_querier_timer_off(igmp
);
7452 pim_igmp_other_querier_timer_on(igmp
);
7454 zassert(!igmp
->t_igmp_query_timer
);
7455 zassert(igmp
->t_other_querier_timer
);
7459 static void change_query_interval(struct pim_interface
*pim_ifp
,
7462 struct listnode
*sock_node
;
7463 struct igmp_sock
*igmp
;
7465 pim_ifp
->igmp_default_query_interval
= query_interval
;
7467 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
7468 igmp_sock_query_interval_reconfig(igmp
);
7469 igmp_sock_query_reschedule(igmp
);
7473 static void change_query_max_response_time(struct pim_interface
*pim_ifp
,
7474 int query_max_response_time_dsec
)
7476 struct listnode
*sock_node
;
7477 struct igmp_sock
*igmp
;
7479 pim_ifp
->igmp_query_max_response_time_dsec
=
7480 query_max_response_time_dsec
;
7483 Below we modify socket/group/source timers in order to quickly
7484 reflect the change. Otherwise, those timers would eventually catch
7488 /* scan all sockets */
7489 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
7490 struct listnode
*grp_node
;
7491 struct igmp_group
*grp
;
7493 /* reschedule socket general query */
7494 igmp_sock_query_reschedule(igmp
);
7496 /* scan socket groups */
7497 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grp_node
,
7499 struct listnode
*src_node
;
7500 struct igmp_source
*src
;
7502 /* reset group timers for groups in EXCLUDE mode */
7503 if (grp
->group_filtermode_isexcl
) {
7504 igmp_group_reset_gmi(grp
);
7507 /* scan group sources */
7508 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
,
7511 /* reset source timers for sources with running
7513 if (src
->t_source_timer
) {
7514 igmp_source_reset_gmi(igmp
, grp
, src
);
7521 #define IGMP_QUERY_INTERVAL_MIN (1)
7522 #define IGMP_QUERY_INTERVAL_MAX (1800)
7524 DEFUN (interface_ip_igmp_query_interval
,
7525 interface_ip_igmp_query_interval_cmd
,
7526 "ip igmp query-interval (1-1800)",
7529 IFACE_IGMP_QUERY_INTERVAL_STR
7530 "Query interval in seconds\n")
7532 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7533 struct pim_interface
*pim_ifp
= ifp
->info
;
7535 int query_interval_dsec
;
7539 ret
= pim_cmd_igmp_start(vty
, ifp
);
7540 if (ret
!= CMD_SUCCESS
)
7542 pim_ifp
= ifp
->info
;
7545 query_interval
= atoi(argv
[3]->arg
);
7546 query_interval_dsec
= 10 * query_interval
;
7549 It seems we don't need to check bounds since command.c does it
7550 already, but we verify them anyway for extra safety.
7552 if (query_interval
< IGMP_QUERY_INTERVAL_MIN
) {
7554 "General query interval %d lower than minimum %d\n",
7555 query_interval
, IGMP_QUERY_INTERVAL_MIN
);
7556 return CMD_WARNING_CONFIG_FAILED
;
7558 if (query_interval
> IGMP_QUERY_INTERVAL_MAX
) {
7560 "General query interval %d higher than maximum %d\n",
7561 query_interval
, IGMP_QUERY_INTERVAL_MAX
);
7562 return CMD_WARNING_CONFIG_FAILED
;
7565 if (query_interval_dsec
<= pim_ifp
->igmp_query_max_response_time_dsec
) {
7567 "Can't set general query interval %d dsec <= query max response time %d dsec.\n",
7568 query_interval_dsec
,
7569 pim_ifp
->igmp_query_max_response_time_dsec
);
7570 return CMD_WARNING_CONFIG_FAILED
;
7573 change_query_interval(pim_ifp
, query_interval
);
7578 DEFUN (interface_no_ip_igmp_query_interval
,
7579 interface_no_ip_igmp_query_interval_cmd
,
7580 "no ip igmp query-interval",
7584 IFACE_IGMP_QUERY_INTERVAL_STR
)
7586 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7587 struct pim_interface
*pim_ifp
= ifp
->info
;
7588 int default_query_interval_dsec
;
7593 default_query_interval_dsec
= IGMP_GENERAL_QUERY_INTERVAL
* 10;
7595 if (default_query_interval_dsec
7596 <= pim_ifp
->igmp_query_max_response_time_dsec
) {
7598 "Can't set default general query interval %d dsec <= query max response time %d dsec.\n",
7599 default_query_interval_dsec
,
7600 pim_ifp
->igmp_query_max_response_time_dsec
);
7601 return CMD_WARNING_CONFIG_FAILED
;
7604 change_query_interval(pim_ifp
, IGMP_GENERAL_QUERY_INTERVAL
);
7609 DEFUN (interface_ip_igmp_version
,
7610 interface_ip_igmp_version_cmd
,
7611 "ip igmp version (2-3)",
7615 "IGMP version number\n")
7617 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7618 struct pim_interface
*pim_ifp
= ifp
->info
;
7619 int igmp_version
, old_version
= 0;
7623 ret
= pim_cmd_igmp_start(vty
, ifp
);
7624 if (ret
!= CMD_SUCCESS
)
7626 pim_ifp
= ifp
->info
;
7629 igmp_version
= atoi(argv
[3]->arg
);
7630 old_version
= pim_ifp
->igmp_version
;
7631 pim_ifp
->igmp_version
= igmp_version
;
7633 // Check if IGMP is Enabled otherwise, enable on interface
7634 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
7635 PIM_IF_DO_IGMP(pim_ifp
->options
);
7636 pim_if_addr_add_all(ifp
);
7637 pim_if_membership_refresh(ifp
);
7638 old_version
= igmp_version
;
7639 // avoid refreshing membership again.
7641 /* Current and new version is different refresh existing
7642 membership. Going from 3 -> 2 or 2 -> 3. */
7643 if (old_version
!= igmp_version
)
7644 pim_if_membership_refresh(ifp
);
7649 DEFUN (interface_no_ip_igmp_version
,
7650 interface_no_ip_igmp_version_cmd
,
7651 "no ip igmp version (2-3)",
7656 "IGMP version number\n")
7658 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7659 struct pim_interface
*pim_ifp
= ifp
->info
;
7664 pim_ifp
->igmp_version
= IGMP_DEFAULT_VERSION
;
7669 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
7670 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
7672 DEFUN (interface_ip_igmp_query_max_response_time
,
7673 interface_ip_igmp_query_max_response_time_cmd
,
7674 "ip igmp query-max-response-time (10-250)",
7677 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
7678 "Query response value in deci-seconds\n")
7680 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7681 struct pim_interface
*pim_ifp
= ifp
->info
;
7682 int query_max_response_time
;
7686 ret
= pim_cmd_igmp_start(vty
, ifp
);
7687 if (ret
!= CMD_SUCCESS
)
7689 pim_ifp
= ifp
->info
;
7692 query_max_response_time
= atoi(argv
[3]->arg
);
7694 if (query_max_response_time
7695 >= pim_ifp
->igmp_default_query_interval
* 10) {
7697 "Can't set query max response time %d sec >= general query interval %d sec\n",
7698 query_max_response_time
,
7699 pim_ifp
->igmp_default_query_interval
);
7700 return CMD_WARNING_CONFIG_FAILED
;
7703 change_query_max_response_time(pim_ifp
, query_max_response_time
);
7708 DEFUN (interface_no_ip_igmp_query_max_response_time
,
7709 interface_no_ip_igmp_query_max_response_time_cmd
,
7710 "no ip igmp query-max-response-time (10-250)",
7714 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
7715 "Time for response in deci-seconds\n")
7717 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7718 struct pim_interface
*pim_ifp
= ifp
->info
;
7723 change_query_max_response_time(pim_ifp
,
7724 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
7729 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
7730 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
7732 DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec
,
7733 interface_ip_igmp_query_max_response_time_dsec_cmd
,
7734 "ip igmp query-max-response-time-dsec (10-250)",
7737 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
7738 "Query response value in deciseconds\n")
7740 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7741 struct pim_interface
*pim_ifp
= ifp
->info
;
7742 int query_max_response_time_dsec
;
7743 int default_query_interval_dsec
;
7747 ret
= pim_cmd_igmp_start(vty
, ifp
);
7748 if (ret
!= CMD_SUCCESS
)
7750 pim_ifp
= ifp
->info
;
7753 query_max_response_time_dsec
= atoi(argv
[4]->arg
);
7755 default_query_interval_dsec
= 10 * pim_ifp
->igmp_default_query_interval
;
7757 if (query_max_response_time_dsec
>= default_query_interval_dsec
) {
7759 "Can't set query max response time %d dsec >= general query interval %d dsec\n",
7760 query_max_response_time_dsec
,
7761 default_query_interval_dsec
);
7762 return CMD_WARNING_CONFIG_FAILED
;
7765 change_query_max_response_time(pim_ifp
, query_max_response_time_dsec
);
7770 DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec
,
7771 interface_no_ip_igmp_query_max_response_time_dsec_cmd
,
7772 "no ip igmp query-max-response-time-dsec",
7776 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
)
7778 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7779 struct pim_interface
*pim_ifp
= ifp
->info
;
7784 change_query_max_response_time(pim_ifp
,
7785 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
7790 #define IGMP_LAST_MEMBER_QUERY_COUNT_MIN (1)
7791 #define IGMP_LAST_MEMBER_QUERY_COUNT_MAX (7)
7793 DEFUN (interface_ip_igmp_last_member_query_count
,
7794 interface_ip_igmp_last_member_query_count_cmd
,
7795 "ip igmp last-member-query-count (1-7)",
7798 IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR
7799 "Last member query count\n")
7801 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7802 struct pim_interface
*pim_ifp
= ifp
->info
;
7803 int last_member_query_count
;
7807 ret
= pim_cmd_igmp_start(vty
, ifp
);
7808 if (ret
!= CMD_SUCCESS
)
7810 pim_ifp
= ifp
->info
;
7813 last_member_query_count
= atoi(argv
[3]->arg
);
7815 pim_ifp
->igmp_last_member_query_count
= last_member_query_count
;
7820 DEFUN (interface_no_ip_igmp_last_member_query_count
,
7821 interface_no_ip_igmp_last_member_query_count_cmd
,
7822 "no ip igmp last-member-query-count",
7826 IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR
)
7828 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7829 struct pim_interface
*pim_ifp
= ifp
->info
;
7834 pim_ifp
->igmp_last_member_query_count
=
7835 IGMP_DEFAULT_ROBUSTNESS_VARIABLE
;
7840 #define IGMP_LAST_MEMBER_QUERY_INTERVAL_MIN (1)
7841 #define IGMP_LAST_MEMBER_QUERY_INTERVAL_MAX (255)
7843 DEFUN (interface_ip_igmp_last_member_query_interval
,
7844 interface_ip_igmp_last_member_query_interval_cmd
,
7845 "ip igmp last-member-query-interval (1-255)",
7848 IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR
7849 "Last member query interval in deciseconds\n")
7851 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7852 struct pim_interface
*pim_ifp
= ifp
->info
;
7853 int last_member_query_interval
;
7857 ret
= pim_cmd_igmp_start(vty
, ifp
);
7858 if (ret
!= CMD_SUCCESS
)
7860 pim_ifp
= ifp
->info
;
7863 last_member_query_interval
= atoi(argv
[3]->arg
);
7864 pim_ifp
->igmp_specific_query_max_response_time_dsec
7865 = last_member_query_interval
;
7870 DEFUN (interface_no_ip_igmp_last_member_query_interval
,
7871 interface_no_ip_igmp_last_member_query_interval_cmd
,
7872 "no ip igmp last-member-query-interval",
7876 IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR
)
7878 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7879 struct pim_interface
*pim_ifp
= ifp
->info
;
7884 pim_ifp
->igmp_specific_query_max_response_time_dsec
=
7885 IGMP_SPECIFIC_QUERY_MAX_RESPONSE_TIME_DSEC
;
7890 DEFUN (interface_ip_pim_drprio
,
7891 interface_ip_pim_drprio_cmd
,
7892 "ip pim drpriority (1-4294967295)",
7895 "Set the Designated Router Election Priority\n"
7896 "Value of the new DR Priority\n")
7898 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7900 struct pim_interface
*pim_ifp
= ifp
->info
;
7901 uint32_t old_dr_prio
;
7904 vty_out(vty
, "Please enable PIM on interface, first\n");
7905 return CMD_WARNING_CONFIG_FAILED
;
7908 old_dr_prio
= pim_ifp
->pim_dr_priority
;
7910 pim_ifp
->pim_dr_priority
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
7912 if (old_dr_prio
!= pim_ifp
->pim_dr_priority
) {
7913 pim_if_dr_election(ifp
);
7914 pim_hello_restart_now(ifp
);
7920 DEFUN (interface_no_ip_pim_drprio
,
7921 interface_no_ip_pim_drprio_cmd
,
7922 "no ip pim drpriority [(1-4294967295)]",
7926 "Revert the Designated Router Priority to default\n"
7927 "Old Value of the Priority\n")
7929 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7930 struct pim_interface
*pim_ifp
= ifp
->info
;
7933 vty_out(vty
, "Pim not enabled on this interface\n");
7934 return CMD_WARNING_CONFIG_FAILED
;
7937 if (pim_ifp
->pim_dr_priority
!= PIM_DEFAULT_DR_PRIORITY
) {
7938 pim_ifp
->pim_dr_priority
= PIM_DEFAULT_DR_PRIORITY
;
7939 pim_if_dr_election(ifp
);
7940 pim_hello_restart_now(ifp
);
7946 DEFPY_HIDDEN (interface_ip_igmp_query_generate
,
7947 interface_ip_igmp_query_generate_cmd
,
7948 "ip igmp generate-query-once [version (2-3)]",
7951 "Generate igmp general query once\n"
7953 "IGMP version number\n")
7955 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7956 int igmp_version
= 2;
7959 vty_out(vty
, "IGMP/PIM is not enabled on the interface %s\n",
7961 return CMD_WARNING_CONFIG_FAILED
;
7965 igmp_version
= atoi(argv
[4]->arg
);
7967 igmp_send_query_on_intf(ifp
, igmp_version
);
7972 static int pim_cmd_interface_add(struct interface
*ifp
)
7974 struct pim_interface
*pim_ifp
= ifp
->info
;
7977 pim_ifp
= pim_if_new(ifp
, false, true, false, false);
7979 PIM_IF_DO_PIM(pim_ifp
->options
);
7981 pim_if_addr_add_all(ifp
);
7982 pim_if_membership_refresh(ifp
);
7984 pim_if_create_pimreg(pim_ifp
->pim
);
7988 DEFPY_HIDDEN (pim_test_sg_keepalive
,
7989 pim_test_sg_keepalive_cmd
,
7990 "test pim [vrf NAME$name] keepalive-reset A.B.C.D$source A.B.C.D$group",
7994 "Reset the Keepalive Timer\n"
7995 "The Source we are resetting\n"
7996 "The Group we are resetting\n")
7998 struct pim_upstream
*up
;
7999 struct pim_instance
*pim
;
8000 struct prefix_sg sg
;
8006 pim
= pim_get_pim_instance(VRF_DEFAULT
);
8008 struct vrf
*vrf
= vrf_lookup_by_name(name
);
8011 vty_out(vty
, "%% Vrf specified: %s does not exist\n",
8016 pim
= pim_get_pim_instance(vrf
->vrf_id
);
8020 vty_out(vty
, "%% Unable to find pim instance\n");
8024 up
= pim_upstream_find(pim
, &sg
);
8026 vty_out(vty
, "%% Unable to find %s specified\n",
8027 pim_str_sg_dump(&sg
));
8031 vty_out(vty
, "Setting %s to current keep alive time: %d\n",
8032 pim_str_sg_dump(&sg
), pim
->keep_alive_time
);
8033 pim_upstream_keep_alive_timer_start(up
, pim
->keep_alive_time
);
8038 DEFPY_HIDDEN (interface_ip_pim_activeactive
,
8039 interface_ip_pim_activeactive_cmd
,
8040 "[no$no] ip pim active-active",
8044 "Mark interface as Active-Active for MLAG operations, Hidden because not finished yet\n")
8046 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8047 struct pim_interface
*pim_ifp
;
8049 if (!no
&& !pim_cmd_interface_add(ifp
)) {
8050 vty_out(vty
, "Could not enable PIM SM active-active on interface\n");
8051 return CMD_WARNING_CONFIG_FAILED
;
8054 pim_ifp
= ifp
->info
;
8056 pim_if_unconfigure_mlag_dualactive(pim_ifp
);
8058 pim_if_configure_mlag_dualactive(pim_ifp
);
8063 DEFUN_HIDDEN (interface_ip_pim_ssm
,
8064 interface_ip_pim_ssm_cmd
,
8070 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8072 if (!pim_cmd_interface_add(ifp
)) {
8073 vty_out(vty
, "Could not enable PIM SM on interface\n");
8074 return CMD_WARNING_CONFIG_FAILED
;
8078 "WARN: Enabled PIM SM on interface; configure PIM SSM "
8079 "range if needed\n");
8083 static int interface_ip_pim_helper(struct vty
*vty
)
8085 struct pim_interface
*pim_ifp
;
8087 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8089 if (!pim_cmd_interface_add(ifp
)) {
8090 vty_out(vty
, "Could not enable PIM SM on interface\n");
8091 return CMD_WARNING_CONFIG_FAILED
;
8094 pim_ifp
= ifp
->info
;
8096 pim_if_create_pimreg(pim_ifp
->pim
);
8101 DEFUN_HIDDEN (interface_ip_pim_sm
,
8102 interface_ip_pim_sm_cmd
,
8108 return interface_ip_pim_helper(vty
);
8111 DEFUN (interface_ip_pim
,
8112 interface_ip_pim_cmd
,
8117 return interface_ip_pim_helper(vty
);
8120 static int pim_cmd_interface_delete(struct interface
*ifp
)
8122 struct pim_interface
*pim_ifp
= ifp
->info
;
8127 PIM_IF_DONT_PIM(pim_ifp
->options
);
8129 pim_if_membership_clear(ifp
);
8132 pim_sock_delete() removes all neighbors from
8133 pim_ifp->pim_neighbor_list.
8135 pim_sock_delete(ifp
, "pim unconfigured on interface");
8137 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
8138 pim_if_addr_del_all(ifp
);
8145 static int interface_no_ip_pim_helper(struct vty
*vty
)
8147 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8148 if (!pim_cmd_interface_delete(ifp
)) {
8149 vty_out(vty
, "Unable to delete interface information\n");
8150 return CMD_WARNING_CONFIG_FAILED
;
8156 DEFUN_HIDDEN (interface_no_ip_pim_ssm
,
8157 interface_no_ip_pim_ssm_cmd
,
8164 return interface_no_ip_pim_helper(vty
);
8167 DEFUN_HIDDEN (interface_no_ip_pim_sm
,
8168 interface_no_ip_pim_sm_cmd
,
8175 return interface_no_ip_pim_helper(vty
);
8178 DEFUN (interface_no_ip_pim
,
8179 interface_no_ip_pim_cmd
,
8185 return interface_no_ip_pim_helper(vty
);
8189 DEFUN(interface_ip_pim_boundary_oil
,
8190 interface_ip_pim_boundary_oil_cmd
,
8191 "ip multicast boundary oil WORD",
8193 "Generic multicast configuration options\n"
8194 "Define multicast boundary\n"
8195 "Filter OIL by group using prefix list\n"
8196 "Prefix list to filter OIL with\n")
8198 VTY_DECLVAR_CONTEXT(interface
, iif
);
8199 struct pim_interface
*pim_ifp
;
8202 argv_find(argv
, argc
, "WORD", &idx
);
8204 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
8206 if (pim_ifp
->boundary_oil_plist
)
8207 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
8209 pim_ifp
->boundary_oil_plist
=
8210 XSTRDUP(MTYPE_PIM_INTERFACE
, argv
[idx
]->arg
);
8212 /* Interface will be pruned from OIL on next Join */
8216 DEFUN(interface_no_ip_pim_boundary_oil
,
8217 interface_no_ip_pim_boundary_oil_cmd
,
8218 "no ip multicast boundary oil [WORD]",
8221 "Generic multicast configuration options\n"
8222 "Define multicast boundary\n"
8223 "Filter OIL by group using prefix list\n"
8224 "Prefix list to filter OIL with\n")
8226 VTY_DECLVAR_CONTEXT(interface
, iif
);
8227 struct pim_interface
*pim_ifp
;
8230 argv_find(argv
, argc
, "WORD", &idx
);
8232 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
8234 if (pim_ifp
->boundary_oil_plist
)
8235 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
8240 DEFUN (interface_ip_mroute
,
8241 interface_ip_mroute_cmd
,
8242 "ip mroute INTERFACE A.B.C.D [A.B.C.D]",
8244 "Add multicast route\n"
8245 "Outgoing interface name\n"
8249 VTY_DECLVAR_CONTEXT(interface
, iif
);
8250 struct pim_interface
*pim_ifp
;
8251 struct pim_instance
*pim
;
8252 int idx_interface
= 2;
8254 struct interface
*oif
;
8255 const char *oifname
;
8256 const char *grp_str
;
8257 struct in_addr grp_addr
;
8258 const char *src_str
;
8259 struct in_addr src_addr
;
8262 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
8265 oifname
= argv
[idx_interface
]->arg
;
8266 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
8268 vty_out(vty
, "No such interface name %s\n", oifname
);
8272 grp_str
= argv
[idx_ipv4
]->arg
;
8273 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
8275 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
8276 errno
, safe_strerror(errno
));
8280 if (argc
== (idx_ipv4
+ 1)) {
8281 src_addr
.s_addr
= INADDR_ANY
;
8284 src_str
= argv
[idx_ipv4
+ 1]->arg
;
8285 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
8287 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
8288 errno
, safe_strerror(errno
));
8293 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
8294 vty_out(vty
, "Failed to add static mroute\n");
8301 DEFUN (interface_no_ip_mroute
,
8302 interface_no_ip_mroute_cmd
,
8303 "no ip mroute INTERFACE A.B.C.D [A.B.C.D]",
8306 "Add multicast route\n"
8307 "Outgoing interface name\n"
8311 VTY_DECLVAR_CONTEXT(interface
, iif
);
8312 struct pim_interface
*pim_ifp
;
8313 struct pim_instance
*pim
;
8314 int idx_interface
= 3;
8316 struct interface
*oif
;
8317 const char *oifname
;
8318 const char *grp_str
;
8319 struct in_addr grp_addr
;
8320 const char *src_str
;
8321 struct in_addr src_addr
;
8324 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
8327 oifname
= argv
[idx_interface
]->arg
;
8328 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
8330 vty_out(vty
, "No such interface name %s\n", oifname
);
8334 grp_str
= argv
[idx_ipv4
]->arg
;
8335 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
8337 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
8338 errno
, safe_strerror(errno
));
8342 if (argc
== (idx_ipv4
+ 1)) {
8343 src_addr
.s_addr
= INADDR_ANY
;
8346 src_str
= argv
[idx_ipv4
+ 1]->arg
;
8347 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
8349 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
8350 errno
, safe_strerror(errno
));
8355 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
8356 vty_out(vty
, "Failed to remove static mroute\n");
8363 DEFUN (interface_ip_pim_hello
,
8364 interface_ip_pim_hello_cmd
,
8365 "ip pim hello (1-180) [(1-180)]",
8369 IFACE_PIM_HELLO_TIME_STR
8370 IFACE_PIM_HELLO_HOLD_STR
)
8372 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8375 struct pim_interface
*pim_ifp
= ifp
->info
;
8378 if (!pim_cmd_interface_add(ifp
)) {
8379 vty_out(vty
, "Could not enable PIM SM on interface\n");
8380 return CMD_WARNING_CONFIG_FAILED
;
8384 pim_ifp
= ifp
->info
;
8385 pim_ifp
->pim_hello_period
= strtol(argv
[idx_time
]->arg
, NULL
, 10);
8387 if (argc
== idx_hold
+ 1)
8388 pim_ifp
->pim_default_holdtime
=
8389 strtol(argv
[idx_hold
]->arg
, NULL
, 10);
8394 DEFUN (interface_no_ip_pim_hello
,
8395 interface_no_ip_pim_hello_cmd
,
8396 "no ip pim hello [(1-180) (1-180)]",
8401 IFACE_PIM_HELLO_TIME_STR
8402 IFACE_PIM_HELLO_HOLD_STR
)
8404 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8405 struct pim_interface
*pim_ifp
= ifp
->info
;
8408 vty_out(vty
, "Pim not enabled on this interface\n");
8409 return CMD_WARNING_CONFIG_FAILED
;
8412 pim_ifp
->pim_hello_period
= PIM_DEFAULT_HELLO_PERIOD
;
8413 pim_ifp
->pim_default_holdtime
= -1;
8424 PIM_DO_DEBUG_IGMP_EVENTS
;
8425 PIM_DO_DEBUG_IGMP_PACKETS
;
8426 PIM_DO_DEBUG_IGMP_TRACE
;
8430 DEFUN (no_debug_igmp
,
8437 PIM_DONT_DEBUG_IGMP_EVENTS
;
8438 PIM_DONT_DEBUG_IGMP_PACKETS
;
8439 PIM_DONT_DEBUG_IGMP_TRACE
;
8444 DEFUN (debug_igmp_events
,
8445 debug_igmp_events_cmd
,
8446 "debug igmp events",
8449 DEBUG_IGMP_EVENTS_STR
)
8451 PIM_DO_DEBUG_IGMP_EVENTS
;
8455 DEFUN (no_debug_igmp_events
,
8456 no_debug_igmp_events_cmd
,
8457 "no debug igmp events",
8461 DEBUG_IGMP_EVENTS_STR
)
8463 PIM_DONT_DEBUG_IGMP_EVENTS
;
8468 DEFUN (debug_igmp_packets
,
8469 debug_igmp_packets_cmd
,
8470 "debug igmp packets",
8473 DEBUG_IGMP_PACKETS_STR
)
8475 PIM_DO_DEBUG_IGMP_PACKETS
;
8479 DEFUN (no_debug_igmp_packets
,
8480 no_debug_igmp_packets_cmd
,
8481 "no debug igmp packets",
8485 DEBUG_IGMP_PACKETS_STR
)
8487 PIM_DONT_DEBUG_IGMP_PACKETS
;
8492 DEFUN (debug_igmp_trace
,
8493 debug_igmp_trace_cmd
,
8497 DEBUG_IGMP_TRACE_STR
)
8499 PIM_DO_DEBUG_IGMP_TRACE
;
8503 DEFUN (no_debug_igmp_trace
,
8504 no_debug_igmp_trace_cmd
,
8505 "no debug igmp trace",
8509 DEBUG_IGMP_TRACE_STR
)
8511 PIM_DONT_DEBUG_IGMP_TRACE
;
8516 DEFUN (debug_mroute
,
8522 PIM_DO_DEBUG_MROUTE
;
8526 DEFUN (debug_mroute_detail
,
8527 debug_mroute_detail_cmd
,
8528 "debug mroute detail",
8533 PIM_DO_DEBUG_MROUTE_DETAIL
;
8537 DEFUN (no_debug_mroute
,
8538 no_debug_mroute_cmd
,
8544 PIM_DONT_DEBUG_MROUTE
;
8548 DEFUN (no_debug_mroute_detail
,
8549 no_debug_mroute_detail_cmd
,
8550 "no debug mroute detail",
8556 PIM_DONT_DEBUG_MROUTE_DETAIL
;
8560 DEFUN (debug_pim_static
,
8561 debug_pim_static_cmd
,
8567 PIM_DO_DEBUG_STATIC
;
8571 DEFUN (no_debug_pim_static
,
8572 no_debug_pim_static_cmd
,
8573 "no debug pim static",
8579 PIM_DONT_DEBUG_STATIC
;
8590 PIM_DO_DEBUG_PIM_EVENTS
;
8591 PIM_DO_DEBUG_PIM_PACKETS
;
8592 PIM_DO_DEBUG_PIM_TRACE
;
8593 PIM_DO_DEBUG_MSDP_EVENTS
;
8594 PIM_DO_DEBUG_MSDP_PACKETS
;
8599 DEFUN (no_debug_pim
,
8606 PIM_DONT_DEBUG_PIM_EVENTS
;
8607 PIM_DONT_DEBUG_PIM_PACKETS
;
8608 PIM_DONT_DEBUG_PIM_TRACE
;
8609 PIM_DONT_DEBUG_MSDP_EVENTS
;
8610 PIM_DONT_DEBUG_MSDP_PACKETS
;
8612 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
8613 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
8619 DEFUN (debug_pim_nht
,
8624 "Nexthop Tracking\n")
8626 PIM_DO_DEBUG_PIM_NHT
;
8630 DEFUN (no_debug_pim_nht
,
8631 no_debug_pim_nht_cmd
,
8636 "Nexthop Tracking\n")
8638 PIM_DONT_DEBUG_PIM_NHT
;
8642 DEFUN (debug_pim_nht_rp
,
8643 debug_pim_nht_rp_cmd
,
8647 "Nexthop Tracking\n"
8648 "RP Nexthop Tracking\n")
8650 PIM_DO_DEBUG_PIM_NHT_RP
;
8654 DEFUN (no_debug_pim_nht_rp
,
8655 no_debug_pim_nht_rp_cmd
,
8656 "no debug pim nht rp",
8660 "Nexthop Tracking\n"
8661 "RP Nexthop Tracking\n")
8663 PIM_DONT_DEBUG_PIM_NHT_RP
;
8667 DEFUN (debug_pim_events
,
8668 debug_pim_events_cmd
,
8672 DEBUG_PIM_EVENTS_STR
)
8674 PIM_DO_DEBUG_PIM_EVENTS
;
8678 DEFUN (no_debug_pim_events
,
8679 no_debug_pim_events_cmd
,
8680 "no debug pim events",
8684 DEBUG_PIM_EVENTS_STR
)
8686 PIM_DONT_DEBUG_PIM_EVENTS
;
8690 DEFUN (debug_pim_packets
,
8691 debug_pim_packets_cmd
,
8692 "debug pim packets [<hello|joins|register>]",
8695 DEBUG_PIM_PACKETS_STR
8696 DEBUG_PIM_HELLO_PACKETS_STR
8697 DEBUG_PIM_J_P_PACKETS_STR
8698 DEBUG_PIM_PIM_REG_PACKETS_STR
)
8701 if (argv_find(argv
, argc
, "hello", &idx
)) {
8702 PIM_DO_DEBUG_PIM_HELLO
;
8703 vty_out(vty
, "PIM Hello debugging is on\n");
8704 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
8705 PIM_DO_DEBUG_PIM_J_P
;
8706 vty_out(vty
, "PIM Join/Prune debugging is on\n");
8707 } else if (argv_find(argv
, argc
, "register", &idx
)) {
8708 PIM_DO_DEBUG_PIM_REG
;
8709 vty_out(vty
, "PIM Register debugging is on\n");
8711 PIM_DO_DEBUG_PIM_PACKETS
;
8712 vty_out(vty
, "PIM Packet debugging is on \n");
8717 DEFUN (no_debug_pim_packets
,
8718 no_debug_pim_packets_cmd
,
8719 "no debug pim packets [<hello|joins|register>]",
8723 DEBUG_PIM_PACKETS_STR
8724 DEBUG_PIM_HELLO_PACKETS_STR
8725 DEBUG_PIM_J_P_PACKETS_STR
8726 DEBUG_PIM_PIM_REG_PACKETS_STR
)
8729 if (argv_find(argv
, argc
, "hello", &idx
)) {
8730 PIM_DONT_DEBUG_PIM_HELLO
;
8731 vty_out(vty
, "PIM Hello debugging is off \n");
8732 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
8733 PIM_DONT_DEBUG_PIM_J_P
;
8734 vty_out(vty
, "PIM Join/Prune debugging is off \n");
8735 } else if (argv_find(argv
, argc
, "register", &idx
)) {
8736 PIM_DONT_DEBUG_PIM_REG
;
8737 vty_out(vty
, "PIM Register debugging is off\n");
8739 PIM_DONT_DEBUG_PIM_PACKETS
;
8745 DEFUN (debug_pim_packetdump_send
,
8746 debug_pim_packetdump_send_cmd
,
8747 "debug pim packet-dump send",
8750 DEBUG_PIM_PACKETDUMP_STR
8751 DEBUG_PIM_PACKETDUMP_SEND_STR
)
8753 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND
;
8757 DEFUN (no_debug_pim_packetdump_send
,
8758 no_debug_pim_packetdump_send_cmd
,
8759 "no debug pim packet-dump send",
8763 DEBUG_PIM_PACKETDUMP_STR
8764 DEBUG_PIM_PACKETDUMP_SEND_STR
)
8766 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
8770 DEFUN (debug_pim_packetdump_recv
,
8771 debug_pim_packetdump_recv_cmd
,
8772 "debug pim packet-dump receive",
8775 DEBUG_PIM_PACKETDUMP_STR
8776 DEBUG_PIM_PACKETDUMP_RECV_STR
)
8778 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV
;
8782 DEFUN (no_debug_pim_packetdump_recv
,
8783 no_debug_pim_packetdump_recv_cmd
,
8784 "no debug pim packet-dump receive",
8788 DEBUG_PIM_PACKETDUMP_STR
8789 DEBUG_PIM_PACKETDUMP_RECV_STR
)
8791 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
8795 DEFUN (debug_pim_trace
,
8796 debug_pim_trace_cmd
,
8800 DEBUG_PIM_TRACE_STR
)
8802 PIM_DO_DEBUG_PIM_TRACE
;
8806 DEFUN (debug_pim_trace_detail
,
8807 debug_pim_trace_detail_cmd
,
8808 "debug pim trace detail",
8812 "Detailed Information\n")
8814 PIM_DO_DEBUG_PIM_TRACE_DETAIL
;
8818 DEFUN (no_debug_pim_trace
,
8819 no_debug_pim_trace_cmd
,
8820 "no debug pim trace",
8824 DEBUG_PIM_TRACE_STR
)
8826 PIM_DONT_DEBUG_PIM_TRACE
;
8830 DEFUN (no_debug_pim_trace_detail
,
8831 no_debug_pim_trace_detail_cmd
,
8832 "no debug pim trace detail",
8837 "Detailed Information\n")
8839 PIM_DONT_DEBUG_PIM_TRACE_DETAIL
;
8843 DEFUN (debug_ssmpingd
,
8849 PIM_DO_DEBUG_SSMPINGD
;
8853 DEFUN (no_debug_ssmpingd
,
8854 no_debug_ssmpingd_cmd
,
8855 "no debug ssmpingd",
8860 PIM_DONT_DEBUG_SSMPINGD
;
8864 DEFUN (debug_pim_zebra
,
8865 debug_pim_zebra_cmd
,
8869 DEBUG_PIM_ZEBRA_STR
)
8875 DEFUN (no_debug_pim_zebra
,
8876 no_debug_pim_zebra_cmd
,
8877 "no debug pim zebra",
8881 DEBUG_PIM_ZEBRA_STR
)
8883 PIM_DONT_DEBUG_ZEBRA
;
8887 DEFUN(debug_pim_mlag
, debug_pim_mlag_cmd
, "debug pim mlag",
8888 DEBUG_STR DEBUG_PIM_STR DEBUG_PIM_MLAG_STR
)
8894 DEFUN(no_debug_pim_mlag
, no_debug_pim_mlag_cmd
, "no debug pim mlag",
8895 NO_STR DEBUG_STR DEBUG_PIM_STR DEBUG_PIM_MLAG_STR
)
8897 PIM_DONT_DEBUG_MLAG
;
8901 DEFUN (debug_pim_vxlan
,
8902 debug_pim_vxlan_cmd
,
8906 DEBUG_PIM_VXLAN_STR
)
8912 DEFUN (no_debug_pim_vxlan
,
8913 no_debug_pim_vxlan_cmd
,
8914 "no debug pim vxlan",
8918 DEBUG_PIM_VXLAN_STR
)
8920 PIM_DONT_DEBUG_VXLAN
;
8930 PIM_DO_DEBUG_MSDP_EVENTS
;
8931 PIM_DO_DEBUG_MSDP_PACKETS
;
8935 DEFUN (no_debug_msdp
,
8942 PIM_DONT_DEBUG_MSDP_EVENTS
;
8943 PIM_DONT_DEBUG_MSDP_PACKETS
;
8947 DEFUN (debug_msdp_events
,
8948 debug_msdp_events_cmd
,
8949 "debug msdp events",
8952 DEBUG_MSDP_EVENTS_STR
)
8954 PIM_DO_DEBUG_MSDP_EVENTS
;
8958 DEFUN (no_debug_msdp_events
,
8959 no_debug_msdp_events_cmd
,
8960 "no debug msdp events",
8964 DEBUG_MSDP_EVENTS_STR
)
8966 PIM_DONT_DEBUG_MSDP_EVENTS
;
8970 DEFUN (debug_msdp_packets
,
8971 debug_msdp_packets_cmd
,
8972 "debug msdp packets",
8975 DEBUG_MSDP_PACKETS_STR
)
8977 PIM_DO_DEBUG_MSDP_PACKETS
;
8981 DEFUN (no_debug_msdp_packets
,
8982 no_debug_msdp_packets_cmd
,
8983 "no debug msdp packets",
8987 DEBUG_MSDP_PACKETS_STR
)
8989 PIM_DONT_DEBUG_MSDP_PACKETS
;
8993 DEFUN (debug_mtrace
,
8999 PIM_DO_DEBUG_MTRACE
;
9003 DEFUN (no_debug_mtrace
,
9004 no_debug_mtrace_cmd
,
9010 PIM_DONT_DEBUG_MTRACE
;
9025 DEFUN (no_debug_bsm
,
9038 DEFUN_NOSH (show_debugging_pim
,
9039 show_debugging_pim_cmd
,
9040 "show debugging [pim]",
9045 vty_out(vty
, "PIM debugging status\n");
9047 pim_debug_config_write(vty
);
9052 static int interface_pim_use_src_cmd_worker(struct vty
*vty
, const char *source
)
9055 struct in_addr source_addr
;
9056 int ret
= CMD_SUCCESS
;
9057 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9059 result
= inet_pton(AF_INET
, source
, &source_addr
);
9061 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", source
,
9062 errno
, safe_strerror(errno
));
9063 return CMD_WARNING_CONFIG_FAILED
;
9066 result
= pim_update_source_set(ifp
, source_addr
);
9070 case PIM_IFACE_NOT_FOUND
:
9071 ret
= CMD_WARNING_CONFIG_FAILED
;
9072 vty_out(vty
, "Pim not enabled on this interface\n");
9074 case PIM_UPDATE_SOURCE_DUP
:
9076 vty_out(vty
, "%% Source already set to %s\n", source
);
9079 ret
= CMD_WARNING_CONFIG_FAILED
;
9080 vty_out(vty
, "%% Source set failed\n");
9086 DEFUN (interface_pim_use_source
,
9087 interface_pim_use_source_cmd
,
9088 "ip pim use-source A.B.C.D",
9091 "Configure primary IP address\n"
9092 "source ip address\n")
9094 return interface_pim_use_src_cmd_worker(vty
, argv
[3]->arg
);
9097 DEFUN (interface_no_pim_use_source
,
9098 interface_no_pim_use_source_cmd
,
9099 "no ip pim use-source [A.B.C.D]",
9103 "Delete source IP address\n"
9104 "source ip address\n")
9106 return interface_pim_use_src_cmd_worker(vty
, "0.0.0.0");
9114 "Enables BFD support\n")
9116 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9117 struct pim_interface
*pim_ifp
= ifp
->info
;
9118 struct bfd_info
*bfd_info
= NULL
;
9121 if (!pim_cmd_interface_add(ifp
)) {
9122 vty_out(vty
, "Could not enable PIM SM on interface\n");
9126 pim_ifp
= ifp
->info
;
9128 bfd_info
= pim_ifp
->bfd_info
;
9130 if (!bfd_info
|| !CHECK_FLAG(bfd_info
->flags
, BFD_FLAG_PARAM_CFG
))
9131 pim_bfd_if_param_set(ifp
, BFD_DEF_MIN_RX
, BFD_DEF_MIN_TX
,
9132 BFD_DEF_DETECT_MULT
, 1);
9137 DEFUN (no_ip_pim_bfd
,
9143 "Disables BFD support\n")
9145 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9146 struct pim_interface
*pim_ifp
= ifp
->info
;
9149 vty_out(vty
, "Pim not enabled on this interface\n");
9153 if (pim_ifp
->bfd_info
) {
9154 pim_bfd_reg_dereg_all_nbr(ifp
, ZEBRA_BFD_DEST_DEREGISTER
);
9155 bfd_info_free(&(pim_ifp
->bfd_info
));
9166 "Enables BSM support on the interface\n")
9168 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9169 struct pim_interface
*pim_ifp
= ifp
->info
;
9172 if (!pim_cmd_interface_add(ifp
)) {
9173 vty_out(vty
, "Could not enable PIM SM on interface\n");
9178 pim_ifp
= ifp
->info
;
9179 pim_ifp
->bsm_enable
= true;
9184 DEFUN (no_ip_pim_bsm
,
9190 "Disables BSM support\n")
9192 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9193 struct pim_interface
*pim_ifp
= ifp
->info
;
9196 vty_out(vty
, "Pim not enabled on this interface\n");
9200 pim_ifp
->bsm_enable
= false;
9205 DEFUN (ip_pim_ucast_bsm
,
9206 ip_pim_ucast_bsm_cmd
,
9207 "ip pim unicast-bsm",
9210 "Accept/Send unicast BSM on the interface\n")
9212 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9213 struct pim_interface
*pim_ifp
= ifp
->info
;
9216 if (!pim_cmd_interface_add(ifp
)) {
9217 vty_out(vty
, "Could not enable PIM SM on interface\n");
9222 pim_ifp
= ifp
->info
;
9223 pim_ifp
->ucast_bsm_accept
= true;
9228 DEFUN (no_ip_pim_ucast_bsm
,
9229 no_ip_pim_ucast_bsm_cmd
,
9230 "no ip pim unicast-bsm",
9234 "Block send/receive unicast BSM on this interface\n")
9236 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9237 struct pim_interface
*pim_ifp
= ifp
->info
;
9240 vty_out(vty
, "Pim not enabled on this interface\n");
9244 pim_ifp
->ucast_bsm_accept
= false;
9252 ip_pim_bfd_param_cmd
,
9253 "ip pim bfd (2-255) (50-60000) (50-60000)",
9256 "Enables BFD support\n"
9257 "Detect Multiplier\n"
9258 "Required min receive interval\n"
9259 "Desired min transmit interval\n")
9263 ip_pim_bfd_param_cmd
,
9264 "ip pim bfd (2-255) (50-60000) (50-60000)",
9267 "Enables BFD support\n"
9268 "Detect Multiplier\n"
9269 "Required min receive interval\n"
9270 "Desired min transmit interval\n")
9271 #endif /* HAVE_BFDD */
9273 VTY_DECLVAR_CONTEXT(interface
, ifp
);
9275 int idx_number_2
= 4;
9276 int idx_number_3
= 5;
9281 struct pim_interface
*pim_ifp
= ifp
->info
;
9284 if (!pim_cmd_interface_add(ifp
)) {
9285 vty_out(vty
, "Could not enable PIM SM on interface\n");
9290 if ((ret
= bfd_validate_param(
9291 vty
, argv
[idx_number
]->arg
, argv
[idx_number_2
]->arg
,
9292 argv
[idx_number_3
]->arg
, &dm_val
, &rx_val
, &tx_val
))
9296 pim_bfd_if_param_set(ifp
, rx_val
, tx_val
, dm_val
, 0);
9302 ALIAS(no_ip_pim_bfd
, no_ip_pim_bfd_param_cmd
,
9303 "no ip pim bfd (2-255) (50-60000) (50-60000)", NO_STR IP_STR PIM_STR
9304 "Enables BFD support\n"
9305 "Detect Multiplier\n"
9306 "Required min receive interval\n"
9307 "Desired min transmit interval\n")
9308 #endif /* !HAVE_BFDD */
9310 static int ip_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
9311 const char *peer
, const char *local
)
9313 enum pim_msdp_err result
;
9314 struct in_addr peer_addr
;
9315 struct in_addr local_addr
;
9316 int ret
= CMD_SUCCESS
;
9318 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
9320 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
9321 errno
, safe_strerror(errno
));
9322 return CMD_WARNING_CONFIG_FAILED
;
9325 result
= inet_pton(AF_INET
, local
, &local_addr
);
9327 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", local
,
9328 errno
, safe_strerror(errno
));
9329 return CMD_WARNING_CONFIG_FAILED
;
9332 result
= pim_msdp_peer_add(pim
, peer_addr
, local_addr
, "default",
9335 case PIM_MSDP_ERR_NONE
:
9337 case PIM_MSDP_ERR_OOM
:
9338 ret
= CMD_WARNING_CONFIG_FAILED
;
9339 vty_out(vty
, "%% Out of memory\n");
9341 case PIM_MSDP_ERR_PEER_EXISTS
:
9343 vty_out(vty
, "%% Peer exists\n");
9345 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
9346 ret
= CMD_WARNING_CONFIG_FAILED
;
9347 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
9350 ret
= CMD_WARNING_CONFIG_FAILED
;
9351 vty_out(vty
, "%% peer add failed\n");
9357 DEFUN_HIDDEN (ip_msdp_peer
,
9359 "ip msdp peer A.B.C.D source A.B.C.D",
9362 "Configure MSDP peer\n"
9364 "Source address for TCP connection\n"
9365 "local ip address\n")
9367 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9368 return ip_msdp_peer_cmd_worker(pim
, vty
, argv
[3]->arg
, argv
[5]->arg
);
9371 static int ip_no_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
9374 enum pim_msdp_err result
;
9375 struct in_addr peer_addr
;
9377 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
9379 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
9380 errno
, safe_strerror(errno
));
9381 return CMD_WARNING_CONFIG_FAILED
;
9384 result
= pim_msdp_peer_del(pim
, peer_addr
);
9386 case PIM_MSDP_ERR_NONE
:
9388 case PIM_MSDP_ERR_NO_PEER
:
9389 vty_out(vty
, "%% Peer does not exist\n");
9392 vty_out(vty
, "%% peer del failed\n");
9395 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9398 DEFUN_HIDDEN (no_ip_msdp_peer
,
9399 no_ip_msdp_peer_cmd
,
9400 "no ip msdp peer A.B.C.D",
9404 "Delete MSDP peer\n"
9405 "peer ip address\n")
9407 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9408 return ip_no_msdp_peer_cmd_worker(pim
, vty
, argv
[4]->arg
);
9411 static int ip_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
9412 struct vty
*vty
, const char *mg
,
9415 enum pim_msdp_err result
;
9416 struct in_addr mbr_ip
;
9417 int ret
= CMD_SUCCESS
;
9419 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
9421 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
9422 errno
, safe_strerror(errno
));
9423 return CMD_WARNING_CONFIG_FAILED
;
9426 result
= pim_msdp_mg_mbr_add(pim
, mg
, mbr_ip
);
9428 case PIM_MSDP_ERR_NONE
:
9430 case PIM_MSDP_ERR_OOM
:
9431 ret
= CMD_WARNING_CONFIG_FAILED
;
9432 vty_out(vty
, "%% Out of memory\n");
9434 case PIM_MSDP_ERR_MG_MBR_EXISTS
:
9436 vty_out(vty
, "%% mesh-group member exists\n");
9438 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
9439 ret
= CMD_WARNING_CONFIG_FAILED
;
9440 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
9443 ret
= CMD_WARNING_CONFIG_FAILED
;
9444 vty_out(vty
, "%% member add failed\n");
9450 DEFUN (ip_msdp_mesh_group_member
,
9451 ip_msdp_mesh_group_member_cmd
,
9452 "ip msdp mesh-group WORD member A.B.C.D",
9455 "Configure MSDP mesh-group\n"
9457 "mesh group member\n"
9458 "peer ip address\n")
9460 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9461 return ip_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[3]->arg
,
9465 static int ip_no_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
9470 enum pim_msdp_err result
;
9471 struct in_addr mbr_ip
;
9473 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
9475 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
9476 errno
, safe_strerror(errno
));
9477 return CMD_WARNING_CONFIG_FAILED
;
9480 result
= pim_msdp_mg_mbr_del(pim
, mg
, mbr_ip
);
9482 case PIM_MSDP_ERR_NONE
:
9484 case PIM_MSDP_ERR_NO_MG
:
9485 vty_out(vty
, "%% mesh-group does not exist\n");
9487 case PIM_MSDP_ERR_NO_MG_MBR
:
9488 vty_out(vty
, "%% mesh-group member does not exist\n");
9491 vty_out(vty
, "%% mesh-group member del failed\n");
9494 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9496 DEFUN (no_ip_msdp_mesh_group_member
,
9497 no_ip_msdp_mesh_group_member_cmd
,
9498 "no ip msdp mesh-group WORD member A.B.C.D",
9502 "Delete MSDP mesh-group member\n"
9504 "mesh group member\n"
9505 "peer ip address\n")
9507 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9508 return ip_no_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[4]->arg
,
9512 static int ip_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
9513 struct vty
*vty
, const char *mg
,
9516 enum pim_msdp_err result
;
9517 struct in_addr src_ip
;
9519 result
= inet_pton(AF_INET
, src
, &src_ip
);
9521 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", src
,
9522 errno
, safe_strerror(errno
));
9523 return CMD_WARNING_CONFIG_FAILED
;
9526 result
= pim_msdp_mg_src_add(pim
, mg
, src_ip
);
9528 case PIM_MSDP_ERR_NONE
:
9530 case PIM_MSDP_ERR_OOM
:
9531 vty_out(vty
, "%% Out of memory\n");
9533 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
9534 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
9537 vty_out(vty
, "%% source add failed\n");
9540 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9544 DEFUN (ip_msdp_mesh_group_source
,
9545 ip_msdp_mesh_group_source_cmd
,
9546 "ip msdp mesh-group WORD source A.B.C.D",
9549 "Configure MSDP mesh-group\n"
9551 "mesh group local address\n"
9552 "source ip address for the TCP connection\n")
9554 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9555 return ip_msdp_mesh_group_source_cmd_worker(pim
, vty
, argv
[3]->arg
,
9559 static int ip_no_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
9563 enum pim_msdp_err result
;
9565 result
= pim_msdp_mg_src_del(pim
, mg
);
9567 case PIM_MSDP_ERR_NONE
:
9569 case PIM_MSDP_ERR_NO_MG
:
9570 vty_out(vty
, "%% mesh-group does not exist\n");
9573 vty_out(vty
, "%% mesh-group source del failed\n");
9576 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9579 static int ip_no_msdp_mesh_group_cmd_worker(struct pim_instance
*pim
,
9580 struct vty
*vty
, const char *mg
)
9582 enum pim_msdp_err result
;
9584 result
= pim_msdp_mg_del(pim
, mg
);
9586 case PIM_MSDP_ERR_NONE
:
9588 case PIM_MSDP_ERR_NO_MG
:
9589 vty_out(vty
, "%% mesh-group does not exist\n");
9592 vty_out(vty
, "%% mesh-group source del failed\n");
9595 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9598 DEFUN (no_ip_msdp_mesh_group_source
,
9599 no_ip_msdp_mesh_group_source_cmd
,
9600 "no ip msdp mesh-group WORD source [A.B.C.D]",
9604 "Delete MSDP mesh-group source\n"
9606 "mesh group source\n"
9607 "mesh group local address\n")
9609 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9611 return ip_no_msdp_mesh_group_cmd_worker(pim
, vty
, argv
[6]->arg
);
9613 return ip_no_msdp_mesh_group_source_cmd_worker(pim
, vty
,
9617 static void print_empty_json_obj(struct vty
*vty
)
9620 json
= json_object_new_object();
9621 vty_out(vty
, "%s\n",
9622 json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
));
9623 json_object_free(json
);
9626 static void ip_msdp_show_mesh_group(struct pim_instance
*pim
, struct vty
*vty
,
9629 struct listnode
*mbrnode
;
9630 struct pim_msdp_mg_mbr
*mbr
;
9631 struct pim_msdp_mg
*mg
= pim
->msdp
.mg
;
9632 char mbr_str
[INET_ADDRSTRLEN
];
9633 char src_str
[INET_ADDRSTRLEN
];
9634 char state_str
[PIM_MSDP_STATE_STRLEN
];
9635 enum pim_msdp_peer_state state
;
9636 json_object
*json
= NULL
;
9637 json_object
*json_mg_row
= NULL
;
9638 json_object
*json_members
= NULL
;
9639 json_object
*json_row
= NULL
;
9643 print_empty_json_obj(vty
);
9647 pim_inet4_dump("<source?>", mg
->src_ip
, src_str
, sizeof(src_str
));
9649 json
= json_object_new_object();
9650 /* currently there is only one mesh group but we should still
9652 * it a dict with mg-name as key */
9653 json_mg_row
= json_object_new_object();
9654 json_object_string_add(json_mg_row
, "name",
9655 mg
->mesh_group_name
);
9656 json_object_string_add(json_mg_row
, "source", src_str
);
9658 vty_out(vty
, "Mesh group : %s\n", mg
->mesh_group_name
);
9659 vty_out(vty
, " Source : %s\n", src_str
);
9660 vty_out(vty
, " Member State\n");
9663 for (ALL_LIST_ELEMENTS_RO(mg
->mbr_list
, mbrnode
, mbr
)) {
9664 pim_inet4_dump("<mbr?>", mbr
->mbr_ip
, mbr_str
, sizeof(mbr_str
));
9666 state
= mbr
->mp
->state
;
9668 state
= PIM_MSDP_DISABLED
;
9670 pim_msdp_state_dump(state
, state_str
, sizeof(state_str
));
9672 json_row
= json_object_new_object();
9673 json_object_string_add(json_row
, "member", mbr_str
);
9674 json_object_string_add(json_row
, "state", state_str
);
9675 if (!json_members
) {
9676 json_members
= json_object_new_object();
9677 json_object_object_add(json_mg_row
, "members",
9680 json_object_object_add(json_members
, mbr_str
, json_row
);
9682 vty_out(vty
, " %-15s %11s\n", mbr_str
, state_str
);
9687 json_object_object_add(json
, mg
->mesh_group_name
, json_mg_row
);
9688 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9689 json
, JSON_C_TO_STRING_PRETTY
));
9690 json_object_free(json
);
9694 DEFUN (show_ip_msdp_mesh_group
,
9695 show_ip_msdp_mesh_group_cmd
,
9696 "show ip msdp [vrf NAME] mesh-group [json]",
9701 "MSDP mesh-group information\n"
9704 bool uj
= use_json(argc
, argv
);
9706 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
9711 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
9716 DEFUN (show_ip_msdp_mesh_group_vrf_all
,
9717 show_ip_msdp_mesh_group_vrf_all_cmd
,
9718 "show ip msdp vrf all mesh-group [json]",
9723 "MSDP mesh-group information\n"
9726 bool uj
= use_json(argc
, argv
);
9732 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
9736 vty_out(vty
, " \"%s\": ", vrf
->name
);
9739 vty_out(vty
, "VRF: %s\n", vrf
->name
);
9740 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
9743 vty_out(vty
, "}\n");
9748 static void ip_msdp_show_peers(struct pim_instance
*pim
, struct vty
*vty
,
9751 struct listnode
*mpnode
;
9752 struct pim_msdp_peer
*mp
;
9753 char peer_str
[INET_ADDRSTRLEN
];
9754 char local_str
[INET_ADDRSTRLEN
];
9755 char state_str
[PIM_MSDP_STATE_STRLEN
];
9756 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
9758 json_object
*json
= NULL
;
9759 json_object
*json_row
= NULL
;
9763 json
= json_object_new_object();
9766 "Peer Local State Uptime SaCnt\n");
9769 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
9770 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
9771 now
= pim_time_monotonic_sec();
9772 pim_time_uptime(timebuf
, sizeof(timebuf
),
9775 strlcpy(timebuf
, "-", sizeof(timebuf
));
9777 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
9778 pim_inet4_dump("<local?>", mp
->local
, local_str
,
9780 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
9782 json_row
= json_object_new_object();
9783 json_object_string_add(json_row
, "peer", peer_str
);
9784 json_object_string_add(json_row
, "local", local_str
);
9785 json_object_string_add(json_row
, "state", state_str
);
9786 json_object_string_add(json_row
, "upTime", timebuf
);
9787 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
9788 json_object_object_add(json
, peer_str
, json_row
);
9790 vty_out(vty
, "%-15s %15s %11s %8s %6d\n", peer_str
,
9791 local_str
, state_str
, timebuf
, mp
->sa_cnt
);
9796 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9797 json
, JSON_C_TO_STRING_PRETTY
));
9798 json_object_free(json
);
9802 static void ip_msdp_show_peers_detail(struct pim_instance
*pim
, struct vty
*vty
,
9803 const char *peer
, bool uj
)
9805 struct listnode
*mpnode
;
9806 struct pim_msdp_peer
*mp
;
9807 char peer_str
[INET_ADDRSTRLEN
];
9808 char local_str
[INET_ADDRSTRLEN
];
9809 char state_str
[PIM_MSDP_STATE_STRLEN
];
9810 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
9811 char katimer
[PIM_MSDP_TIMER_STRLEN
];
9812 char crtimer
[PIM_MSDP_TIMER_STRLEN
];
9813 char holdtimer
[PIM_MSDP_TIMER_STRLEN
];
9815 json_object
*json
= NULL
;
9816 json_object
*json_row
= NULL
;
9819 json
= json_object_new_object();
9822 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
9823 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
9824 if (strcmp(peer
, "detail") && strcmp(peer
, peer_str
))
9827 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
9828 now
= pim_time_monotonic_sec();
9829 pim_time_uptime(timebuf
, sizeof(timebuf
),
9832 strlcpy(timebuf
, "-", sizeof(timebuf
));
9834 pim_inet4_dump("<local?>", mp
->local
, local_str
,
9836 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
9837 pim_time_timer_to_hhmmss(katimer
, sizeof(katimer
),
9839 pim_time_timer_to_hhmmss(crtimer
, sizeof(crtimer
),
9841 pim_time_timer_to_hhmmss(holdtimer
, sizeof(holdtimer
),
9845 json_row
= json_object_new_object();
9846 json_object_string_add(json_row
, "peer", peer_str
);
9847 json_object_string_add(json_row
, "local", local_str
);
9848 json_object_string_add(json_row
, "meshGroupName",
9849 mp
->mesh_group_name
);
9850 json_object_string_add(json_row
, "state", state_str
);
9851 json_object_string_add(json_row
, "upTime", timebuf
);
9852 json_object_string_add(json_row
, "keepAliveTimer",
9854 json_object_string_add(json_row
, "connRetryTimer",
9856 json_object_string_add(json_row
, "holdTimer",
9858 json_object_string_add(json_row
, "lastReset",
9860 json_object_int_add(json_row
, "connAttempts",
9862 json_object_int_add(json_row
, "establishedChanges",
9864 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
9865 json_object_int_add(json_row
, "kaSent", mp
->ka_tx_cnt
);
9866 json_object_int_add(json_row
, "kaRcvd", mp
->ka_rx_cnt
);
9867 json_object_int_add(json_row
, "saSent", mp
->sa_tx_cnt
);
9868 json_object_int_add(json_row
, "saRcvd", mp
->sa_rx_cnt
);
9869 json_object_object_add(json
, peer_str
, json_row
);
9871 vty_out(vty
, "Peer : %s\n", peer_str
);
9872 vty_out(vty
, " Local : %s\n", local_str
);
9873 vty_out(vty
, " Mesh Group : %s\n",
9874 mp
->mesh_group_name
);
9875 vty_out(vty
, " State : %s\n", state_str
);
9876 vty_out(vty
, " Uptime : %s\n", timebuf
);
9878 vty_out(vty
, " Keepalive Timer : %s\n", katimer
);
9879 vty_out(vty
, " Conn Retry Timer : %s\n", crtimer
);
9880 vty_out(vty
, " Hold Timer : %s\n", holdtimer
);
9881 vty_out(vty
, " Last Reset : %s\n",
9883 vty_out(vty
, " Conn Attempts : %d\n",
9885 vty_out(vty
, " Established Changes : %d\n",
9887 vty_out(vty
, " SA Count : %d\n",
9889 vty_out(vty
, " Statistics :\n");
9892 vty_out(vty
, " Keepalives : %10d %10d\n",
9893 mp
->ka_tx_cnt
, mp
->ka_rx_cnt
);
9894 vty_out(vty
, " SAs : %10d %10d\n",
9895 mp
->sa_tx_cnt
, mp
->sa_rx_cnt
);
9901 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9902 json
, JSON_C_TO_STRING_PRETTY
));
9903 json_object_free(json
);
9907 DEFUN (show_ip_msdp_peer_detail
,
9908 show_ip_msdp_peer_detail_cmd
,
9909 "show ip msdp [vrf NAME] peer [detail|A.B.C.D] [json]",
9914 "MSDP peer information\n"
9919 bool uj
= use_json(argc
, argv
);
9921 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
9928 if (argv_find(argv
, argc
, "detail", &idx
))
9929 arg
= argv
[idx
]->text
;
9930 else if (argv_find(argv
, argc
, "A.B.C.D", &idx
))
9931 arg
= argv
[idx
]->arg
;
9934 ip_msdp_show_peers_detail(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
9936 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
9941 DEFUN (show_ip_msdp_peer_detail_vrf_all
,
9942 show_ip_msdp_peer_detail_vrf_all_cmd
,
9943 "show ip msdp vrf all peer [detail|A.B.C.D] [json]",
9948 "MSDP peer information\n"
9954 bool uj
= use_json(argc
, argv
);
9960 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
9964 vty_out(vty
, " \"%s\": ", vrf
->name
);
9967 vty_out(vty
, "VRF: %s\n", vrf
->name
);
9968 if (argv_find(argv
, argc
, "detail", &idx
)
9969 || argv_find(argv
, argc
, "A.B.C.D", &idx
))
9970 ip_msdp_show_peers_detail(vrf
->info
, vty
,
9971 argv
[idx
]->arg
, uj
);
9973 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
9976 vty_out(vty
, "}\n");
9981 static void ip_msdp_show_sa(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
9983 struct listnode
*sanode
;
9984 struct pim_msdp_sa
*sa
;
9985 char src_str
[INET_ADDRSTRLEN
];
9986 char grp_str
[INET_ADDRSTRLEN
];
9987 char rp_str
[INET_ADDRSTRLEN
];
9988 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
9992 json_object
*json
= NULL
;
9993 json_object
*json_group
= NULL
;
9994 json_object
*json_row
= NULL
;
9997 json
= json_object_new_object();
10000 "Source Group RP Local SPT Uptime\n");
10003 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
10004 now
= pim_time_monotonic_sec();
10005 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
10006 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
10007 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
10008 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
10009 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
10011 strlcpy(spt_str
, "yes", sizeof(spt_str
));
10013 strlcpy(spt_str
, "no", sizeof(spt_str
));
10016 strlcpy(rp_str
, "-", sizeof(rp_str
));
10017 strlcpy(spt_str
, "-", sizeof(spt_str
));
10019 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
10020 strlcpy(local_str
, "yes", sizeof(local_str
));
10022 strlcpy(local_str
, "no", sizeof(local_str
));
10025 json_object_object_get_ex(json
, grp_str
, &json_group
);
10028 json_group
= json_object_new_object();
10029 json_object_object_add(json
, grp_str
,
10033 json_row
= json_object_new_object();
10034 json_object_string_add(json_row
, "source", src_str
);
10035 json_object_string_add(json_row
, "group", grp_str
);
10036 json_object_string_add(json_row
, "rp", rp_str
);
10037 json_object_string_add(json_row
, "local", local_str
);
10038 json_object_string_add(json_row
, "sptSetup", spt_str
);
10039 json_object_string_add(json_row
, "upTime", timebuf
);
10040 json_object_object_add(json_group
, src_str
, json_row
);
10042 vty_out(vty
, "%-15s %15s %15s %5c %3c %8s\n",
10043 src_str
, grp_str
, rp_str
, local_str
[0],
10044 spt_str
[0], timebuf
);
10049 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10050 json
, JSON_C_TO_STRING_PRETTY
));
10051 json_object_free(json
);
10055 static void ip_msdp_show_sa_entry_detail(struct pim_msdp_sa
*sa
,
10056 const char *src_str
,
10057 const char *grp_str
, struct vty
*vty
,
10058 bool uj
, json_object
*json
)
10060 char rp_str
[INET_ADDRSTRLEN
];
10061 char peer_str
[INET_ADDRSTRLEN
];
10062 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
10065 char statetimer
[PIM_MSDP_TIMER_STRLEN
];
10067 json_object
*json_group
= NULL
;
10068 json_object
*json_row
= NULL
;
10070 now
= pim_time_monotonic_sec();
10071 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
10072 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
10073 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
10074 pim_inet4_dump("<peer?>", sa
->peer
, peer_str
, sizeof(peer_str
));
10076 strlcpy(spt_str
, "yes", sizeof(spt_str
));
10078 strlcpy(spt_str
, "no", sizeof(spt_str
));
10081 strlcpy(rp_str
, "-", sizeof(rp_str
));
10082 strlcpy(peer_str
, "-", sizeof(peer_str
));
10083 strlcpy(spt_str
, "-", sizeof(spt_str
));
10085 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
10086 strlcpy(local_str
, "yes", sizeof(local_str
));
10088 strlcpy(local_str
, "no", sizeof(local_str
));
10090 pim_time_timer_to_hhmmss(statetimer
, sizeof(statetimer
),
10091 sa
->sa_state_timer
);
10093 json_object_object_get_ex(json
, grp_str
, &json_group
);
10096 json_group
= json_object_new_object();
10097 json_object_object_add(json
, grp_str
, json_group
);
10100 json_row
= json_object_new_object();
10101 json_object_string_add(json_row
, "source", src_str
);
10102 json_object_string_add(json_row
, "group", grp_str
);
10103 json_object_string_add(json_row
, "rp", rp_str
);
10104 json_object_string_add(json_row
, "local", local_str
);
10105 json_object_string_add(json_row
, "sptSetup", spt_str
);
10106 json_object_string_add(json_row
, "upTime", timebuf
);
10107 json_object_string_add(json_row
, "stateTimer", statetimer
);
10108 json_object_object_add(json_group
, src_str
, json_row
);
10110 vty_out(vty
, "SA : %s\n", sa
->sg_str
);
10111 vty_out(vty
, " RP : %s\n", rp_str
);
10112 vty_out(vty
, " Peer : %s\n", peer_str
);
10113 vty_out(vty
, " Local : %s\n", local_str
);
10114 vty_out(vty
, " SPT Setup : %s\n", spt_str
);
10115 vty_out(vty
, " Uptime : %s\n", timebuf
);
10116 vty_out(vty
, " State Timer : %s\n", statetimer
);
10117 vty_out(vty
, "\n");
10121 static void ip_msdp_show_sa_detail(struct pim_instance
*pim
, struct vty
*vty
,
10124 struct listnode
*sanode
;
10125 struct pim_msdp_sa
*sa
;
10126 char src_str
[INET_ADDRSTRLEN
];
10127 char grp_str
[INET_ADDRSTRLEN
];
10128 json_object
*json
= NULL
;
10131 json
= json_object_new_object();
10134 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
10135 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
10136 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
10137 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
, uj
,
10142 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10143 json
, JSON_C_TO_STRING_PRETTY
));
10144 json_object_free(json
);
10148 DEFUN (show_ip_msdp_sa_detail
,
10149 show_ip_msdp_sa_detail_cmd
,
10150 "show ip msdp [vrf NAME] sa detail [json]",
10155 "MSDP active-source information\n"
10156 "Detailed output\n"
10159 bool uj
= use_json(argc
, argv
);
10161 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10164 return CMD_WARNING
;
10166 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
10168 return CMD_SUCCESS
;
10171 DEFUN (show_ip_msdp_sa_detail_vrf_all
,
10172 show_ip_msdp_sa_detail_vrf_all_cmd
,
10173 "show ip msdp vrf all sa detail [json]",
10178 "MSDP active-source information\n"
10179 "Detailed output\n"
10182 bool uj
= use_json(argc
, argv
);
10187 vty_out(vty
, "{ ");
10188 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
10191 vty_out(vty
, ", ");
10192 vty_out(vty
, " \"%s\": ", vrf
->name
);
10195 vty_out(vty
, "VRF: %s\n", vrf
->name
);
10196 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
10199 vty_out(vty
, "}\n");
10201 return CMD_SUCCESS
;
10204 static void ip_msdp_show_sa_addr(struct pim_instance
*pim
, struct vty
*vty
,
10205 const char *addr
, bool uj
)
10207 struct listnode
*sanode
;
10208 struct pim_msdp_sa
*sa
;
10209 char src_str
[INET_ADDRSTRLEN
];
10210 char grp_str
[INET_ADDRSTRLEN
];
10211 json_object
*json
= NULL
;
10214 json
= json_object_new_object();
10217 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
10218 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
10219 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
10220 if (!strcmp(addr
, src_str
) || !strcmp(addr
, grp_str
)) {
10221 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
10227 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10228 json
, JSON_C_TO_STRING_PRETTY
));
10229 json_object_free(json
);
10233 static void ip_msdp_show_sa_sg(struct pim_instance
*pim
, struct vty
*vty
,
10234 const char *src
, const char *grp
, bool uj
)
10236 struct listnode
*sanode
;
10237 struct pim_msdp_sa
*sa
;
10238 char src_str
[INET_ADDRSTRLEN
];
10239 char grp_str
[INET_ADDRSTRLEN
];
10240 json_object
*json
= NULL
;
10243 json
= json_object_new_object();
10246 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
10247 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
10248 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
10249 if (!strcmp(src
, src_str
) && !strcmp(grp
, grp_str
)) {
10250 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
10256 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10257 json
, JSON_C_TO_STRING_PRETTY
));
10258 json_object_free(json
);
10262 DEFUN (show_ip_msdp_sa_sg
,
10263 show_ip_msdp_sa_sg_cmd
,
10264 "show ip msdp [vrf NAME] sa [A.B.C.D [A.B.C.D]] [json]",
10269 "MSDP active-source information\n"
10270 "source or group ip\n"
10274 bool uj
= use_json(argc
, argv
);
10278 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10281 return CMD_WARNING
;
10283 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
10285 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
10289 if (src_ip
&& grp_ip
)
10290 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
10292 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
10294 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
10296 return CMD_SUCCESS
;
10299 DEFUN (show_ip_msdp_sa_sg_vrf_all
,
10300 show_ip_msdp_sa_sg_vrf_all_cmd
,
10301 "show ip msdp vrf all sa [A.B.C.D [A.B.C.D]] [json]",
10306 "MSDP active-source information\n"
10307 "source or group ip\n"
10311 bool uj
= use_json(argc
, argv
);
10316 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
10318 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
10323 vty_out(vty
, "{ ");
10324 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
10327 vty_out(vty
, ", ");
10328 vty_out(vty
, " \"%s\": ", vrf
->name
);
10331 vty_out(vty
, "VRF: %s\n", vrf
->name
);
10333 if (src_ip
&& grp_ip
)
10334 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
10336 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
10338 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
10341 vty_out(vty
, "}\n");
10343 return CMD_SUCCESS
;
10346 struct pim_sg_cache_walk_data
{
10349 json_object
*json_group
;
10350 struct in_addr addr
;
10354 static void pim_show_vxlan_sg_entry(struct pim_vxlan_sg
*vxlan_sg
,
10355 struct pim_sg_cache_walk_data
*cwd
)
10357 struct vty
*vty
= cwd
->vty
;
10358 json_object
*json
= cwd
->json
;
10359 char src_str
[INET_ADDRSTRLEN
];
10360 char grp_str
[INET_ADDRSTRLEN
];
10361 json_object
*json_row
;
10362 bool installed
= (vxlan_sg
->up
) ? true : false;
10363 const char *iif_name
= vxlan_sg
->iif
?vxlan_sg
->iif
->name
:"-";
10364 const char *oif_name
;
10366 if (pim_vxlan_is_orig_mroute(vxlan_sg
))
10367 oif_name
= vxlan_sg
->orig_oif
?vxlan_sg
->orig_oif
->name
:"";
10369 oif_name
= vxlan_sg
->term_oif
?vxlan_sg
->term_oif
->name
:"";
10371 if (cwd
->addr_match
&& (vxlan_sg
->sg
.src
.s_addr
!= cwd
->addr
.s_addr
) &&
10372 (vxlan_sg
->sg
.grp
.s_addr
!= cwd
->addr
.s_addr
)) {
10375 pim_inet4_dump("<src?>", vxlan_sg
->sg
.src
, src_str
, sizeof(src_str
));
10376 pim_inet4_dump("<grp?>", vxlan_sg
->sg
.grp
, grp_str
, sizeof(grp_str
));
10378 json_object_object_get_ex(json
, grp_str
, &cwd
->json_group
);
10380 if (!cwd
->json_group
) {
10381 cwd
->json_group
= json_object_new_object();
10382 json_object_object_add(json
, grp_str
,
10386 json_row
= json_object_new_object();
10387 json_object_string_add(json_row
, "source", src_str
);
10388 json_object_string_add(json_row
, "group", grp_str
);
10389 json_object_string_add(json_row
, "input", iif_name
);
10390 json_object_string_add(json_row
, "output", oif_name
);
10392 json_object_boolean_true_add(json_row
, "installed");
10394 json_object_boolean_false_add(json_row
, "installed");
10395 json_object_object_add(cwd
->json_group
, src_str
, json_row
);
10397 vty_out(vty
, "%-15s %-15s %-15s %-15s %-5s\n",
10398 src_str
, grp_str
, iif_name
, oif_name
,
10403 static void pim_show_vxlan_sg_hash_entry(struct hash_bucket
*backet
, void *arg
)
10405 pim_show_vxlan_sg_entry((struct pim_vxlan_sg
*)backet
->data
,
10406 (struct pim_sg_cache_walk_data
*)arg
);
10409 static void pim_show_vxlan_sg(struct pim_instance
*pim
,
10410 struct vty
*vty
, bool uj
)
10412 json_object
*json
= NULL
;
10413 struct pim_sg_cache_walk_data cwd
;
10416 json
= json_object_new_object();
10418 vty_out(vty
, "Codes: I -> installed\n");
10420 "Source Group Input Output Flags\n");
10423 memset(&cwd
, 0, sizeof(cwd
));
10426 hash_iterate(pim
->vxlan
.sg_hash
, pim_show_vxlan_sg_hash_entry
, &cwd
);
10429 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10430 json
, JSON_C_TO_STRING_PRETTY
));
10431 json_object_free(json
);
10435 static void pim_show_vxlan_sg_match_addr(struct pim_instance
*pim
,
10436 struct vty
*vty
, char *addr_str
, bool uj
)
10438 json_object
*json
= NULL
;
10439 struct pim_sg_cache_walk_data cwd
;
10442 memset(&cwd
, 0, sizeof(cwd
));
10443 result
= inet_pton(AF_INET
, addr_str
, &cwd
.addr
);
10445 vty_out(vty
, "Bad address %s: errno=%d: %s\n", addr_str
,
10446 errno
, safe_strerror(errno
));
10451 json
= json_object_new_object();
10453 vty_out(vty
, "Codes: I -> installed\n");
10455 "Source Group Input Output Flags\n");
10460 cwd
.addr_match
= true;
10461 hash_iterate(pim
->vxlan
.sg_hash
, pim_show_vxlan_sg_hash_entry
, &cwd
);
10464 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10465 json
, JSON_C_TO_STRING_PRETTY
));
10466 json_object_free(json
);
10470 static void pim_show_vxlan_sg_one(struct pim_instance
*pim
,
10471 struct vty
*vty
, char *src_str
, char *grp_str
, bool uj
)
10473 json_object
*json
= NULL
;
10474 struct prefix_sg sg
;
10476 struct pim_vxlan_sg
*vxlan_sg
;
10477 const char *iif_name
;
10479 const char *oif_name
;
10481 result
= inet_pton(AF_INET
, src_str
, &sg
.src
);
10483 vty_out(vty
, "Bad src address %s: errno=%d: %s\n", src_str
,
10484 errno
, safe_strerror(errno
));
10487 result
= inet_pton(AF_INET
, grp_str
, &sg
.grp
);
10489 vty_out(vty
, "Bad grp address %s: errno=%d: %s\n", grp_str
,
10490 errno
, safe_strerror(errno
));
10494 sg
.family
= AF_INET
;
10495 sg
.prefixlen
= IPV4_MAX_BITLEN
;
10497 json
= json_object_new_object();
10499 vxlan_sg
= pim_vxlan_sg_find(pim
, &sg
);
10501 installed
= (vxlan_sg
->up
) ? true : false;
10502 iif_name
= vxlan_sg
->iif
?vxlan_sg
->iif
->name
:"-";
10504 if (pim_vxlan_is_orig_mroute(vxlan_sg
))
10506 vxlan_sg
->orig_oif
?vxlan_sg
->orig_oif
->name
:"";
10509 vxlan_sg
->term_oif
?vxlan_sg
->term_oif
->name
:"";
10512 json_object_string_add(json
, "source", src_str
);
10513 json_object_string_add(json
, "group", grp_str
);
10514 json_object_string_add(json
, "input", iif_name
);
10515 json_object_string_add(json
, "output", oif_name
);
10517 json_object_boolean_true_add(json
, "installed");
10519 json_object_boolean_false_add(json
,
10522 vty_out(vty
, "SG : %s\n", vxlan_sg
->sg_str
);
10523 vty_out(vty
, " Input : %s\n", iif_name
);
10524 vty_out(vty
, " Output : %s\n", oif_name
);
10525 vty_out(vty
, " installed : %s\n",
10526 installed
?"yes":"no");
10531 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10532 json
, JSON_C_TO_STRING_PRETTY
));
10533 json_object_free(json
);
10537 DEFUN (show_ip_pim_vxlan_sg
,
10538 show_ip_pim_vxlan_sg_cmd
,
10539 "show ip pim [vrf NAME] vxlan-groups [A.B.C.D [A.B.C.D]] [json]",
10544 "VxLAN BUM groups\n"
10545 "source or group ip\n"
10549 bool uj
= use_json(argc
, argv
);
10553 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10556 return CMD_WARNING
;
10558 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ?
10559 argv
[idx
++]->arg
:NULL
;
10560 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
) ?
10561 argv
[idx
]->arg
:NULL
;
10563 if (src_ip
&& grp_ip
)
10564 pim_show_vxlan_sg_one(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
10566 pim_show_vxlan_sg_match_addr(vrf
->info
, vty
, src_ip
, uj
);
10568 pim_show_vxlan_sg(vrf
->info
, vty
, uj
);
10570 return CMD_SUCCESS
;
10573 static void pim_show_vxlan_sg_work(struct pim_instance
*pim
,
10574 struct vty
*vty
, bool uj
)
10576 json_object
*json
= NULL
;
10577 struct pim_sg_cache_walk_data cwd
;
10578 struct listnode
*node
;
10579 struct pim_vxlan_sg
*vxlan_sg
;
10582 json
= json_object_new_object();
10584 vty_out(vty
, "Codes: I -> installed\n");
10586 "Source Group Input Flags\n");
10589 memset(&cwd
, 0, sizeof(cwd
));
10592 for (ALL_LIST_ELEMENTS_RO(pim_vxlan_p
->work_list
, node
, vxlan_sg
))
10593 pim_show_vxlan_sg_entry(vxlan_sg
, &cwd
);
10596 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10597 json
, JSON_C_TO_STRING_PRETTY
));
10598 json_object_free(json
);
10602 DEFUN_HIDDEN (show_ip_pim_vxlan_sg_work
,
10603 show_ip_pim_vxlan_sg_work_cmd
,
10604 "show ip pim [vrf NAME] vxlan-work [json]",
10609 "VxLAN work list\n"
10612 bool uj
= use_json(argc
, argv
);
10616 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10619 return CMD_WARNING
;
10621 pim_show_vxlan_sg_work(vrf
->info
, vty
, uj
);
10623 return CMD_SUCCESS
;
10626 DEFUN_HIDDEN (no_ip_pim_mlag
,
10627 no_ip_pim_mlag_cmd
,
10634 struct in_addr addr
;
10637 pim_vxlan_mlag_update(true/*mlag_enable*/,
10638 false/*peer_state*/, MLAG_ROLE_NONE
,
10639 NULL
/*peerlink*/, &addr
);
10641 return CMD_SUCCESS
;
10644 DEFUN_HIDDEN (ip_pim_mlag
,
10646 "ip pim mlag INTERFACE role [primary|secondary] state [up|down] addr A.B.C.D",
10650 "peerlink sub interface\n"
10652 "MLAG role primary\n"
10653 "MLAG role secondary\n"
10654 "peer session state\n"
10655 "peer session state up\n"
10656 "peer session state down\n"
10658 "unique ip address\n")
10660 struct interface
*ifp
;
10661 const char *peerlink
;
10666 struct in_addr reg_addr
;
10669 peerlink
= argv
[idx
]->arg
;
10670 ifp
= if_lookup_by_name(peerlink
, VRF_DEFAULT
);
10672 vty_out(vty
, "No such interface name %s\n", peerlink
);
10673 return CMD_WARNING
;
10677 if (!strcmp(argv
[idx
]->arg
, "primary")) {
10678 role
= MLAG_ROLE_PRIMARY
;
10679 } else if (!strcmp(argv
[idx
]->arg
, "secondary")) {
10680 role
= MLAG_ROLE_SECONDARY
;
10682 vty_out(vty
, "unknown MLAG role %s\n", argv
[idx
]->arg
);
10683 return CMD_WARNING
;
10687 if (!strcmp(argv
[idx
]->arg
, "up")) {
10689 } else if (strcmp(argv
[idx
]->arg
, "down")) {
10690 peer_state
= false;
10692 vty_out(vty
, "unknown MLAG state %s\n", argv
[idx
]->arg
);
10693 return CMD_WARNING
;
10697 result
= inet_pton(AF_INET
, argv
[idx
]->arg
, ®_addr
);
10699 vty_out(vty
, "%% Bad reg address %s: errno=%d: %s\n",
10701 errno
, safe_strerror(errno
));
10702 return CMD_WARNING_CONFIG_FAILED
;
10704 pim_vxlan_mlag_update(true, peer_state
, role
, ifp
, ®_addr
);
10706 return CMD_SUCCESS
;
10709 void pim_cmd_init(void)
10711 install_node(&interface_node
,
10712 pim_interface_config_write
); /* INTERFACE_NODE */
10715 install_node(&debug_node
, pim_debug_config_write
);
10717 install_element(ENABLE_NODE
, &pim_test_sg_keepalive_cmd
);
10719 install_element(CONFIG_NODE
, &ip_pim_rp_cmd
);
10720 install_element(VRF_NODE
, &ip_pim_rp_cmd
);
10721 install_element(CONFIG_NODE
, &no_ip_pim_rp_cmd
);
10722 install_element(VRF_NODE
, &no_ip_pim_rp_cmd
);
10723 install_element(CONFIG_NODE
, &ip_pim_rp_prefix_list_cmd
);
10724 install_element(VRF_NODE
, &ip_pim_rp_prefix_list_cmd
);
10725 install_element(CONFIG_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
10726 install_element(VRF_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
10727 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
10728 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
10729 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
10730 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
10731 install_element(CONFIG_NODE
, &ip_pim_ssm_prefix_list_cmd
);
10732 install_element(VRF_NODE
, &ip_pim_ssm_prefix_list_cmd
);
10733 install_element(CONFIG_NODE
, &ip_pim_register_suppress_cmd
);
10734 install_element(VRF_NODE
, &ip_pim_register_suppress_cmd
);
10735 install_element(CONFIG_NODE
, &no_ip_pim_register_suppress_cmd
);
10736 install_element(VRF_NODE
, &no_ip_pim_register_suppress_cmd
);
10737 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
10738 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
10739 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
10740 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
10741 install_element(CONFIG_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
10742 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
10743 install_element(CONFIG_NODE
,
10744 &no_ip_pim_spt_switchover_infinity_plist_cmd
);
10745 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_plist_cmd
);
10746 install_element(CONFIG_NODE
, &ip_pim_joinprune_time_cmd
);
10747 install_element(VRF_NODE
, &ip_pim_joinprune_time_cmd
);
10748 install_element(CONFIG_NODE
, &no_ip_pim_joinprune_time_cmd
);
10749 install_element(VRF_NODE
, &no_ip_pim_joinprune_time_cmd
);
10750 install_element(CONFIG_NODE
, &ip_pim_keep_alive_cmd
);
10751 install_element(VRF_NODE
, &ip_pim_keep_alive_cmd
);
10752 install_element(CONFIG_NODE
, &ip_pim_rp_keep_alive_cmd
);
10753 install_element(VRF_NODE
, &ip_pim_rp_keep_alive_cmd
);
10754 install_element(CONFIG_NODE
, &no_ip_pim_keep_alive_cmd
);
10755 install_element(VRF_NODE
, &no_ip_pim_keep_alive_cmd
);
10756 install_element(CONFIG_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
10757 install_element(VRF_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
10758 install_element(CONFIG_NODE
, &ip_pim_packets_cmd
);
10759 install_element(VRF_NODE
, &ip_pim_packets_cmd
);
10760 install_element(CONFIG_NODE
, &no_ip_pim_packets_cmd
);
10761 install_element(VRF_NODE
, &no_ip_pim_packets_cmd
);
10762 install_element(CONFIG_NODE
, &ip_pim_v6_secondary_cmd
);
10763 install_element(VRF_NODE
, &ip_pim_v6_secondary_cmd
);
10764 install_element(CONFIG_NODE
, &no_ip_pim_v6_secondary_cmd
);
10765 install_element(VRF_NODE
, &no_ip_pim_v6_secondary_cmd
);
10766 install_element(CONFIG_NODE
, &ip_ssmpingd_cmd
);
10767 install_element(VRF_NODE
, &ip_ssmpingd_cmd
);
10768 install_element(CONFIG_NODE
, &no_ip_ssmpingd_cmd
);
10769 install_element(VRF_NODE
, &no_ip_ssmpingd_cmd
);
10770 install_element(CONFIG_NODE
, &ip_msdp_peer_cmd
);
10771 install_element(VRF_NODE
, &ip_msdp_peer_cmd
);
10772 install_element(CONFIG_NODE
, &no_ip_msdp_peer_cmd
);
10773 install_element(VRF_NODE
, &no_ip_msdp_peer_cmd
);
10774 install_element(CONFIG_NODE
, &ip_pim_ecmp_cmd
);
10775 install_element(VRF_NODE
, &ip_pim_ecmp_cmd
);
10776 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_cmd
);
10777 install_element(VRF_NODE
, &no_ip_pim_ecmp_cmd
);
10778 install_element(CONFIG_NODE
, &ip_pim_ecmp_rebalance_cmd
);
10779 install_element(VRF_NODE
, &ip_pim_ecmp_rebalance_cmd
);
10780 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
10781 install_element(VRF_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
10782 install_element(CONFIG_NODE
, &ip_pim_mlag_cmd
);
10783 install_element(CONFIG_NODE
, &no_ip_pim_mlag_cmd
);
10785 install_element(INTERFACE_NODE
, &interface_ip_igmp_cmd
);
10786 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_cmd
);
10787 install_element(INTERFACE_NODE
, &interface_ip_igmp_join_cmd
);
10788 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_join_cmd
);
10789 install_element(INTERFACE_NODE
, &interface_ip_igmp_version_cmd
);
10790 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_version_cmd
);
10791 install_element(INTERFACE_NODE
, &interface_ip_igmp_query_interval_cmd
);
10792 install_element(INTERFACE_NODE
,
10793 &interface_no_ip_igmp_query_interval_cmd
);
10794 install_element(INTERFACE_NODE
,
10795 &interface_ip_igmp_query_max_response_time_cmd
);
10796 install_element(INTERFACE_NODE
,
10797 &interface_no_ip_igmp_query_max_response_time_cmd
);
10798 install_element(INTERFACE_NODE
,
10799 &interface_ip_igmp_query_max_response_time_dsec_cmd
);
10800 install_element(INTERFACE_NODE
,
10801 &interface_no_ip_igmp_query_max_response_time_dsec_cmd
);
10802 install_element(INTERFACE_NODE
,
10803 &interface_ip_igmp_last_member_query_count_cmd
);
10804 install_element(INTERFACE_NODE
,
10805 &interface_no_ip_igmp_last_member_query_count_cmd
);
10806 install_element(INTERFACE_NODE
,
10807 &interface_ip_igmp_last_member_query_interval_cmd
);
10808 install_element(INTERFACE_NODE
,
10809 &interface_no_ip_igmp_last_member_query_interval_cmd
);
10810 install_element(INTERFACE_NODE
, &interface_ip_pim_activeactive_cmd
);
10811 install_element(INTERFACE_NODE
, &interface_ip_pim_ssm_cmd
);
10812 install_element(INTERFACE_NODE
, &interface_no_ip_pim_ssm_cmd
);
10813 install_element(INTERFACE_NODE
, &interface_ip_pim_sm_cmd
);
10814 install_element(INTERFACE_NODE
, &interface_no_ip_pim_sm_cmd
);
10815 install_element(INTERFACE_NODE
, &interface_ip_pim_cmd
);
10816 install_element(INTERFACE_NODE
, &interface_no_ip_pim_cmd
);
10817 install_element(INTERFACE_NODE
, &interface_ip_pim_drprio_cmd
);
10818 install_element(INTERFACE_NODE
, &interface_no_ip_pim_drprio_cmd
);
10819 install_element(INTERFACE_NODE
, &interface_ip_pim_hello_cmd
);
10820 install_element(INTERFACE_NODE
, &interface_no_ip_pim_hello_cmd
);
10821 install_element(INTERFACE_NODE
, &interface_ip_pim_boundary_oil_cmd
);
10822 install_element(INTERFACE_NODE
, &interface_no_ip_pim_boundary_oil_cmd
);
10823 install_element(INTERFACE_NODE
, &interface_ip_igmp_query_generate_cmd
);
10825 // Static mroutes NEB
10826 install_element(INTERFACE_NODE
, &interface_ip_mroute_cmd
);
10827 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_cmd
);
10829 install_element(VIEW_NODE
, &show_ip_igmp_interface_cmd
);
10830 install_element(VIEW_NODE
, &show_ip_igmp_interface_vrf_all_cmd
);
10831 install_element(VIEW_NODE
, &show_ip_igmp_join_cmd
);
10832 install_element(VIEW_NODE
, &show_ip_igmp_join_vrf_all_cmd
);
10833 install_element(VIEW_NODE
, &show_ip_igmp_groups_cmd
);
10834 install_element(VIEW_NODE
, &show_ip_igmp_groups_vrf_all_cmd
);
10835 install_element(VIEW_NODE
, &show_ip_igmp_groups_retransmissions_cmd
);
10836 install_element(VIEW_NODE
, &show_ip_igmp_sources_cmd
);
10837 install_element(VIEW_NODE
, &show_ip_igmp_sources_retransmissions_cmd
);
10838 install_element(VIEW_NODE
, &show_ip_igmp_statistics_cmd
);
10839 install_element(VIEW_NODE
, &show_ip_pim_assert_cmd
);
10840 install_element(VIEW_NODE
, &show_ip_pim_assert_internal_cmd
);
10841 install_element(VIEW_NODE
, &show_ip_pim_assert_metric_cmd
);
10842 install_element(VIEW_NODE
, &show_ip_pim_assert_winner_metric_cmd
);
10843 install_element(VIEW_NODE
, &show_ip_pim_interface_traffic_cmd
);
10844 install_element(VIEW_NODE
, &show_ip_pim_interface_cmd
);
10845 install_element(VIEW_NODE
, &show_ip_pim_interface_vrf_all_cmd
);
10846 install_element(VIEW_NODE
, &show_ip_pim_join_cmd
);
10847 install_element(VIEW_NODE
, &show_ip_pim_join_vrf_all_cmd
);
10848 install_element(VIEW_NODE
, &show_ip_pim_jp_agg_cmd
);
10849 install_element(VIEW_NODE
, &show_ip_pim_local_membership_cmd
);
10850 install_element(VIEW_NODE
, &show_ip_pim_mlag_summary_cmd
);
10851 install_element(VIEW_NODE
, &show_ip_pim_mlag_up_cmd
);
10852 install_element(VIEW_NODE
, &show_ip_pim_mlag_up_vrf_all_cmd
);
10853 install_element(VIEW_NODE
, &show_ip_pim_neighbor_cmd
);
10854 install_element(VIEW_NODE
, &show_ip_pim_neighbor_vrf_all_cmd
);
10855 install_element(VIEW_NODE
, &show_ip_pim_rpf_cmd
);
10856 install_element(VIEW_NODE
, &show_ip_pim_rpf_vrf_all_cmd
);
10857 install_element(VIEW_NODE
, &show_ip_pim_secondary_cmd
);
10858 install_element(VIEW_NODE
, &show_ip_pim_state_cmd
);
10859 install_element(VIEW_NODE
, &show_ip_pim_state_vrf_all_cmd
);
10860 install_element(VIEW_NODE
, &show_ip_pim_upstream_cmd
);
10861 install_element(VIEW_NODE
, &show_ip_pim_upstream_vrf_all_cmd
);
10862 install_element(VIEW_NODE
, &show_ip_pim_channel_cmd
);
10863 install_element(VIEW_NODE
, &show_ip_pim_upstream_join_desired_cmd
);
10864 install_element(VIEW_NODE
, &show_ip_pim_upstream_rpf_cmd
);
10865 install_element(VIEW_NODE
, &show_ip_pim_rp_cmd
);
10866 install_element(VIEW_NODE
, &show_ip_pim_rp_vrf_all_cmd
);
10867 install_element(VIEW_NODE
, &show_ip_pim_bsr_cmd
);
10868 install_element(VIEW_NODE
, &show_ip_multicast_cmd
);
10869 install_element(VIEW_NODE
, &show_ip_multicast_vrf_all_cmd
);
10870 install_element(VIEW_NODE
, &show_ip_mroute_cmd
);
10871 install_element(VIEW_NODE
, &show_ip_mroute_vrf_all_cmd
);
10872 install_element(VIEW_NODE
, &show_ip_mroute_count_cmd
);
10873 install_element(VIEW_NODE
, &show_ip_mroute_count_vrf_all_cmd
);
10874 install_element(VIEW_NODE
, &show_ip_mroute_summary_cmd
);
10875 install_element(VIEW_NODE
, &show_ip_mroute_summary_vrf_all_cmd
);
10876 install_element(VIEW_NODE
, &show_ip_rib_cmd
);
10877 install_element(VIEW_NODE
, &show_ip_ssmpingd_cmd
);
10878 install_element(VIEW_NODE
, &show_debugging_pim_cmd
);
10879 install_element(VIEW_NODE
, &show_ip_pim_nexthop_cmd
);
10880 install_element(VIEW_NODE
, &show_ip_pim_nexthop_lookup_cmd
);
10881 install_element(VIEW_NODE
, &show_ip_pim_bsrp_cmd
);
10882 install_element(VIEW_NODE
, &show_ip_pim_bsm_db_cmd
);
10883 install_element(VIEW_NODE
, &show_ip_pim_statistics_cmd
);
10885 install_element(ENABLE_NODE
, &clear_ip_mroute_count_cmd
);
10886 install_element(ENABLE_NODE
, &clear_ip_interfaces_cmd
);
10887 install_element(ENABLE_NODE
, &clear_ip_igmp_interfaces_cmd
);
10888 install_element(ENABLE_NODE
, &clear_ip_mroute_cmd
);
10889 install_element(ENABLE_NODE
, &clear_ip_pim_interfaces_cmd
);
10890 install_element(ENABLE_NODE
, &clear_ip_pim_interface_traffic_cmd
);
10891 install_element(ENABLE_NODE
, &clear_ip_pim_oil_cmd
);
10892 install_element(ENABLE_NODE
, &clear_ip_pim_statistics_cmd
);
10894 install_element(ENABLE_NODE
, &debug_igmp_cmd
);
10895 install_element(ENABLE_NODE
, &no_debug_igmp_cmd
);
10896 install_element(ENABLE_NODE
, &debug_igmp_events_cmd
);
10897 install_element(ENABLE_NODE
, &no_debug_igmp_events_cmd
);
10898 install_element(ENABLE_NODE
, &debug_igmp_packets_cmd
);
10899 install_element(ENABLE_NODE
, &no_debug_igmp_packets_cmd
);
10900 install_element(ENABLE_NODE
, &debug_igmp_trace_cmd
);
10901 install_element(ENABLE_NODE
, &no_debug_igmp_trace_cmd
);
10902 install_element(ENABLE_NODE
, &debug_mroute_cmd
);
10903 install_element(ENABLE_NODE
, &debug_mroute_detail_cmd
);
10904 install_element(ENABLE_NODE
, &no_debug_mroute_cmd
);
10905 install_element(ENABLE_NODE
, &no_debug_mroute_detail_cmd
);
10906 install_element(ENABLE_NODE
, &debug_pim_static_cmd
);
10907 install_element(ENABLE_NODE
, &no_debug_pim_static_cmd
);
10908 install_element(ENABLE_NODE
, &debug_pim_cmd
);
10909 install_element(ENABLE_NODE
, &no_debug_pim_cmd
);
10910 install_element(ENABLE_NODE
, &debug_pim_nht_cmd
);
10911 install_element(ENABLE_NODE
, &no_debug_pim_nht_cmd
);
10912 install_element(ENABLE_NODE
, &debug_pim_nht_rp_cmd
);
10913 install_element(ENABLE_NODE
, &no_debug_pim_nht_rp_cmd
);
10914 install_element(ENABLE_NODE
, &debug_pim_events_cmd
);
10915 install_element(ENABLE_NODE
, &no_debug_pim_events_cmd
);
10916 install_element(ENABLE_NODE
, &debug_pim_packets_cmd
);
10917 install_element(ENABLE_NODE
, &no_debug_pim_packets_cmd
);
10918 install_element(ENABLE_NODE
, &debug_pim_packetdump_send_cmd
);
10919 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_send_cmd
);
10920 install_element(ENABLE_NODE
, &debug_pim_packetdump_recv_cmd
);
10921 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_recv_cmd
);
10922 install_element(ENABLE_NODE
, &debug_pim_trace_cmd
);
10923 install_element(ENABLE_NODE
, &no_debug_pim_trace_cmd
);
10924 install_element(ENABLE_NODE
, &debug_pim_trace_detail_cmd
);
10925 install_element(ENABLE_NODE
, &no_debug_pim_trace_detail_cmd
);
10926 install_element(ENABLE_NODE
, &debug_ssmpingd_cmd
);
10927 install_element(ENABLE_NODE
, &no_debug_ssmpingd_cmd
);
10928 install_element(ENABLE_NODE
, &debug_pim_zebra_cmd
);
10929 install_element(ENABLE_NODE
, &no_debug_pim_zebra_cmd
);
10930 install_element(ENABLE_NODE
, &debug_pim_mlag_cmd
);
10931 install_element(ENABLE_NODE
, &no_debug_pim_mlag_cmd
);
10932 install_element(ENABLE_NODE
, &debug_pim_vxlan_cmd
);
10933 install_element(ENABLE_NODE
, &no_debug_pim_vxlan_cmd
);
10934 install_element(ENABLE_NODE
, &debug_msdp_cmd
);
10935 install_element(ENABLE_NODE
, &no_debug_msdp_cmd
);
10936 install_element(ENABLE_NODE
, &debug_msdp_events_cmd
);
10937 install_element(ENABLE_NODE
, &no_debug_msdp_events_cmd
);
10938 install_element(ENABLE_NODE
, &debug_msdp_packets_cmd
);
10939 install_element(ENABLE_NODE
, &no_debug_msdp_packets_cmd
);
10940 install_element(ENABLE_NODE
, &debug_mtrace_cmd
);
10941 install_element(ENABLE_NODE
, &no_debug_mtrace_cmd
);
10942 install_element(ENABLE_NODE
, &debug_bsm_cmd
);
10943 install_element(ENABLE_NODE
, &no_debug_bsm_cmd
);
10945 install_element(CONFIG_NODE
, &debug_igmp_cmd
);
10946 install_element(CONFIG_NODE
, &no_debug_igmp_cmd
);
10947 install_element(CONFIG_NODE
, &debug_igmp_events_cmd
);
10948 install_element(CONFIG_NODE
, &no_debug_igmp_events_cmd
);
10949 install_element(CONFIG_NODE
, &debug_igmp_packets_cmd
);
10950 install_element(CONFIG_NODE
, &no_debug_igmp_packets_cmd
);
10951 install_element(CONFIG_NODE
, &debug_igmp_trace_cmd
);
10952 install_element(CONFIG_NODE
, &no_debug_igmp_trace_cmd
);
10953 install_element(CONFIG_NODE
, &debug_mroute_cmd
);
10954 install_element(CONFIG_NODE
, &debug_mroute_detail_cmd
);
10955 install_element(CONFIG_NODE
, &no_debug_mroute_cmd
);
10956 install_element(CONFIG_NODE
, &no_debug_mroute_detail_cmd
);
10957 install_element(CONFIG_NODE
, &debug_pim_static_cmd
);
10958 install_element(CONFIG_NODE
, &no_debug_pim_static_cmd
);
10959 install_element(CONFIG_NODE
, &debug_pim_cmd
);
10960 install_element(CONFIG_NODE
, &no_debug_pim_cmd
);
10961 install_element(CONFIG_NODE
, &debug_pim_nht_cmd
);
10962 install_element(CONFIG_NODE
, &no_debug_pim_nht_cmd
);
10963 install_element(CONFIG_NODE
, &debug_pim_nht_rp_cmd
);
10964 install_element(CONFIG_NODE
, &no_debug_pim_nht_rp_cmd
);
10965 install_element(CONFIG_NODE
, &debug_pim_events_cmd
);
10966 install_element(CONFIG_NODE
, &no_debug_pim_events_cmd
);
10967 install_element(CONFIG_NODE
, &debug_pim_packets_cmd
);
10968 install_element(CONFIG_NODE
, &no_debug_pim_packets_cmd
);
10969 install_element(CONFIG_NODE
, &debug_pim_trace_cmd
);
10970 install_element(CONFIG_NODE
, &no_debug_pim_trace_cmd
);
10971 install_element(CONFIG_NODE
, &debug_pim_trace_detail_cmd
);
10972 install_element(CONFIG_NODE
, &no_debug_pim_trace_detail_cmd
);
10973 install_element(CONFIG_NODE
, &debug_ssmpingd_cmd
);
10974 install_element(CONFIG_NODE
, &no_debug_ssmpingd_cmd
);
10975 install_element(CONFIG_NODE
, &debug_pim_zebra_cmd
);
10976 install_element(CONFIG_NODE
, &no_debug_pim_zebra_cmd
);
10977 install_element(CONFIG_NODE
, &debug_pim_mlag_cmd
);
10978 install_element(CONFIG_NODE
, &no_debug_pim_mlag_cmd
);
10979 install_element(CONFIG_NODE
, &debug_pim_vxlan_cmd
);
10980 install_element(CONFIG_NODE
, &no_debug_pim_vxlan_cmd
);
10981 install_element(CONFIG_NODE
, &debug_msdp_cmd
);
10982 install_element(CONFIG_NODE
, &no_debug_msdp_cmd
);
10983 install_element(CONFIG_NODE
, &debug_msdp_events_cmd
);
10984 install_element(CONFIG_NODE
, &no_debug_msdp_events_cmd
);
10985 install_element(CONFIG_NODE
, &debug_msdp_packets_cmd
);
10986 install_element(CONFIG_NODE
, &no_debug_msdp_packets_cmd
);
10987 install_element(CONFIG_NODE
, &debug_mtrace_cmd
);
10988 install_element(CONFIG_NODE
, &no_debug_mtrace_cmd
);
10989 install_element(CONFIG_NODE
, &debug_bsm_cmd
);
10990 install_element(CONFIG_NODE
, &no_debug_bsm_cmd
);
10992 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_member_cmd
);
10993 install_element(VRF_NODE
, &ip_msdp_mesh_group_member_cmd
);
10994 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
10995 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
10996 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_source_cmd
);
10997 install_element(VRF_NODE
, &ip_msdp_mesh_group_source_cmd
);
10998 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
10999 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
11000 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_cmd
);
11001 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_vrf_all_cmd
);
11002 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_cmd
);
11003 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_vrf_all_cmd
);
11004 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_cmd
);
11005 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_vrf_all_cmd
);
11006 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_cmd
);
11007 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_vrf_all_cmd
);
11008 install_element(VIEW_NODE
, &show_ip_pim_ssm_range_cmd
);
11009 install_element(VIEW_NODE
, &show_ip_pim_group_type_cmd
);
11010 install_element(VIEW_NODE
, &show_ip_pim_vxlan_sg_cmd
);
11011 install_element(VIEW_NODE
, &show_ip_pim_vxlan_sg_work_cmd
);
11012 install_element(INTERFACE_NODE
, &interface_pim_use_source_cmd
);
11013 install_element(INTERFACE_NODE
, &interface_no_pim_use_source_cmd
);
11014 /* Install BSM command */
11015 install_element(INTERFACE_NODE
, &ip_pim_bsm_cmd
);
11016 install_element(INTERFACE_NODE
, &no_ip_pim_bsm_cmd
);
11017 install_element(INTERFACE_NODE
, &ip_pim_ucast_bsm_cmd
);
11018 install_element(INTERFACE_NODE
, &no_ip_pim_ucast_bsm_cmd
);
11019 /* Install BFD command */
11020 install_element(INTERFACE_NODE
, &ip_pim_bfd_cmd
);
11021 install_element(INTERFACE_NODE
, &ip_pim_bfd_param_cmd
);
11022 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_cmd
);
11024 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_param_cmd
);
11025 #endif /* !HAVE_BFDD */