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
,
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 listnode
*upnode
;
918 struct pim_interface
*pim_ifp
;
919 struct pim_neighbor
*neigh
;
920 struct pim_upstream
*up
;
922 char dr_str
[INET_ADDRSTRLEN
];
925 char grp_str
[INET_ADDRSTRLEN
];
926 char hello_period
[10];
927 char hello_timer
[10];
928 char neigh_src_str
[INET_ADDRSTRLEN
];
929 char src_str
[INET_ADDRSTRLEN
];
930 char stat_uptime
[10];
933 int found_ifname
= 0;
935 json_object
*json
= NULL
;
936 json_object
*json_row
= NULL
;
937 json_object
*json_pim_neighbor
= NULL
;
938 json_object
*json_pim_neighbors
= NULL
;
939 json_object
*json_group
= NULL
;
940 json_object
*json_group_source
= NULL
;
941 json_object
*json_fhr_sources
= NULL
;
942 struct pim_secondary_addr
*sec_addr
;
943 struct listnode
*sec_node
;
945 now
= pim_time_monotonic_sec();
948 json
= json_object_new_object();
950 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
956 if (strcmp(ifname
, "detail") && strcmp(ifname
, ifp
->name
))
960 ifaddr
= pim_ifp
->primary_address
;
961 pim_inet4_dump("<dr?>", pim_ifp
->pim_dr_addr
, dr_str
,
963 pim_time_uptime_begin(dr_uptime
, sizeof(dr_uptime
), now
,
964 pim_ifp
->pim_dr_election_last
);
965 pim_time_timer_to_hhmmss(hello_timer
, sizeof(hello_timer
),
966 pim_ifp
->t_pim_hello_timer
);
967 pim_time_mmss(hello_period
, sizeof(hello_period
),
968 pim_ifp
->pim_hello_period
);
969 pim_time_uptime(stat_uptime
, sizeof(stat_uptime
),
970 now
- pim_ifp
->pim_ifstat_start
);
971 if (pim_ifp
->pim_sock_fd
>= 0)
972 mloop
= pim_socket_mcastloop_get(pim_ifp
->pim_sock_fd
);
977 char pbuf
[PREFIX2STR_BUFFER
];
978 json_row
= json_object_new_object();
979 json_object_pim_ifp_add(json_row
, ifp
);
981 if (pim_ifp
->update_source
.s_addr
!= INADDR_ANY
) {
982 json_object_string_add(
983 json_row
, "useSource",
984 inet_ntoa(pim_ifp
->update_source
));
986 if (pim_ifp
->sec_addr_list
) {
987 json_object
*sec_list
= NULL
;
989 sec_list
= json_object_new_array();
990 for (ALL_LIST_ELEMENTS_RO(
991 pim_ifp
->sec_addr_list
, sec_node
,
993 json_object_array_add(
995 json_object_new_string(
1001 json_object_object_add(json_row
,
1002 "secondaryAddressList",
1007 if (pim_ifp
->pim_neighbor_list
->count
) {
1008 json_pim_neighbors
= json_object_new_object();
1010 for (ALL_LIST_ELEMENTS_RO(
1011 pim_ifp
->pim_neighbor_list
,
1012 neighnode
, neigh
)) {
1014 json_object_new_object();
1015 pim_inet4_dump("<src?>",
1018 sizeof(neigh_src_str
));
1019 pim_time_uptime(uptime
, sizeof(uptime
),
1020 now
- neigh
->creation
);
1021 pim_time_timer_to_hhmmss(
1022 expire
, sizeof(expire
),
1023 neigh
->t_expire_timer
);
1025 json_object_string_add(
1026 json_pim_neighbor
, "address",
1028 json_object_string_add(
1029 json_pim_neighbor
, "upTime",
1031 json_object_string_add(
1032 json_pim_neighbor
, "holdtime",
1035 json_object_object_add(
1041 json_object_object_add(json_row
, "neighbors",
1042 json_pim_neighbors
);
1045 json_object_string_add(json_row
, "drAddress", dr_str
);
1046 json_object_int_add(json_row
, "drPriority",
1047 pim_ifp
->pim_dr_priority
);
1048 json_object_string_add(json_row
, "drUptime", dr_uptime
);
1049 json_object_int_add(json_row
, "drElections",
1050 pim_ifp
->pim_dr_election_count
);
1051 json_object_int_add(json_row
, "drChanges",
1052 pim_ifp
->pim_dr_election_changes
);
1055 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
,
1057 if (ifp
!= up
->rpf
.source_nexthop
.interface
)
1060 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
))
1063 if (!json_fhr_sources
)
1065 json_object_new_object();
1067 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
,
1069 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
,
1071 pim_time_uptime(uptime
, sizeof(uptime
),
1072 now
- up
->state_transition
);
1075 * Does this group live in json_fhr_sources?
1078 json_object_object_get_ex(json_fhr_sources
,
1079 grp_str
, &json_group
);
1082 json_group
= json_object_new_object();
1083 json_object_object_add(json_fhr_sources
,
1088 json_group_source
= json_object_new_object();
1089 json_object_string_add(json_group_source
,
1091 json_object_string_add(json_group_source
,
1093 json_object_string_add(json_group_source
,
1095 json_object_object_add(json_group
, src_str
,
1099 if (json_fhr_sources
) {
1100 json_object_object_add(json_row
,
1105 json_object_int_add(json_row
, "helloPeriod",
1106 pim_ifp
->pim_hello_period
);
1107 json_object_string_add(json_row
, "helloTimer",
1109 json_object_string_add(json_row
, "helloStatStart",
1111 json_object_int_add(json_row
, "helloReceived",
1112 pim_ifp
->pim_ifstat_hello_recv
);
1113 json_object_int_add(json_row
, "helloReceivedFailed",
1114 pim_ifp
->pim_ifstat_hello_recvfail
);
1115 json_object_int_add(json_row
, "helloSend",
1116 pim_ifp
->pim_ifstat_hello_sent
);
1117 json_object_int_add(json_row
, "hellosendFailed",
1118 pim_ifp
->pim_ifstat_hello_sendfail
);
1119 json_object_int_add(json_row
, "helloGenerationId",
1120 pim_ifp
->pim_generation_id
);
1121 json_object_int_add(json_row
, "flagMulticastLoop",
1124 json_object_int_add(
1125 json_row
, "effectivePropagationDelay",
1126 pim_if_effective_propagation_delay_msec(ifp
));
1127 json_object_int_add(
1128 json_row
, "effectiveOverrideInterval",
1129 pim_if_effective_override_interval_msec(ifp
));
1130 json_object_int_add(
1131 json_row
, "joinPruneOverrideInterval",
1132 pim_if_jp_override_interval_msec(ifp
));
1134 json_object_int_add(
1135 json_row
, "propagationDelay",
1136 pim_ifp
->pim_propagation_delay_msec
);
1137 json_object_int_add(
1138 json_row
, "propagationDelayHighest",
1139 pim_ifp
->pim_neighbors_highest_propagation_delay_msec
);
1140 json_object_int_add(
1141 json_row
, "overrideInterval",
1142 pim_ifp
->pim_override_interval_msec
);
1143 json_object_int_add(
1144 json_row
, "overrideIntervalHighest",
1145 pim_ifp
->pim_neighbors_highest_override_interval_msec
);
1146 json_object_object_add(json
, ifp
->name
, json_row
);
1149 vty_out(vty
, "Interface : %s\n", ifp
->name
);
1150 vty_out(vty
, "State : %s\n",
1151 if_is_up(ifp
) ? "up" : "down");
1152 if (pim_ifp
->update_source
.s_addr
!= INADDR_ANY
) {
1153 vty_out(vty
, "Use Source : %s\n",
1154 inet_ntoa(pim_ifp
->update_source
));
1156 if (pim_ifp
->sec_addr_list
) {
1157 char pbuf
[PREFIX2STR_BUFFER
];
1158 vty_out(vty
, "Address : %s (primary)\n",
1160 for (ALL_LIST_ELEMENTS_RO(
1161 pim_ifp
->sec_addr_list
, sec_node
,
1163 vty_out(vty
, " %s\n",
1164 prefix2str(&sec_addr
->addr
,
1165 pbuf
, sizeof(pbuf
)));
1168 vty_out(vty
, "Address : %s\n",
1176 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
,
1177 neighnode
, neigh
)) {
1180 vty_out(vty
, "PIM Neighbors\n");
1181 vty_out(vty
, "-------------\n");
1185 pim_inet4_dump("<src?>", neigh
->source_addr
,
1187 sizeof(neigh_src_str
));
1188 pim_time_uptime(uptime
, sizeof(uptime
),
1189 now
- neigh
->creation
);
1190 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
1191 neigh
->t_expire_timer
);
1193 "%-15s : up for %s, holdtime expires in %s\n",
1194 neigh_src_str
, uptime
, expire
);
1197 if (!print_header
) {
1202 vty_out(vty
, "Designated Router\n");
1203 vty_out(vty
, "-----------------\n");
1204 vty_out(vty
, "Address : %s\n", dr_str
);
1205 vty_out(vty
, "Priority : %u(%d)\n",
1206 pim_ifp
->pim_dr_priority
,
1207 pim_ifp
->pim_dr_num_nondrpri_neighbors
);
1208 vty_out(vty
, "Uptime : %s\n", dr_uptime
);
1209 vty_out(vty
, "Elections : %d\n",
1210 pim_ifp
->pim_dr_election_count
);
1211 vty_out(vty
, "Changes : %d\n",
1212 pim_ifp
->pim_dr_election_changes
);
1218 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
,
1220 if (!up
->rpf
.source_nexthop
.interface
)
1223 if (strcmp(ifp
->name
,
1224 up
->rpf
.source_nexthop
1229 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
))
1234 "FHR - First Hop Router\n");
1236 "----------------------\n");
1240 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
,
1242 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
,
1244 pim_time_uptime(uptime
, sizeof(uptime
),
1245 now
- up
->state_transition
);
1247 "%s : %s is a source, uptime is %s\n",
1248 grp_str
, src_str
, uptime
);
1251 if (!print_header
) {
1256 vty_out(vty
, "Hellos\n");
1257 vty_out(vty
, "------\n");
1258 vty_out(vty
, "Period : %d\n",
1259 pim_ifp
->pim_hello_period
);
1260 vty_out(vty
, "Timer : %s\n", hello_timer
);
1261 vty_out(vty
, "StatStart : %s\n", stat_uptime
);
1262 vty_out(vty
, "Receive : %d\n",
1263 pim_ifp
->pim_ifstat_hello_recv
);
1264 vty_out(vty
, "Receive Failed : %d\n",
1265 pim_ifp
->pim_ifstat_hello_recvfail
);
1266 vty_out(vty
, "Send : %d\n",
1267 pim_ifp
->pim_ifstat_hello_sent
);
1268 vty_out(vty
, "Send Failed : %d\n",
1269 pim_ifp
->pim_ifstat_hello_sendfail
);
1270 vty_out(vty
, "Generation ID : %08x\n",
1271 pim_ifp
->pim_generation_id
);
1275 pim_print_ifp_flags(vty
, ifp
, mloop
);
1277 vty_out(vty
, "Join Prune Interval\n");
1278 vty_out(vty
, "-------------------\n");
1279 vty_out(vty
, "LAN Delay : %s\n",
1280 pim_if_lan_delay_enabled(ifp
) ? "yes" : "no");
1281 vty_out(vty
, "Effective Propagation Delay : %d msec\n",
1282 pim_if_effective_propagation_delay_msec(ifp
));
1283 vty_out(vty
, "Effective Override Interval : %d msec\n",
1284 pim_if_effective_override_interval_msec(ifp
));
1285 vty_out(vty
, "Join Prune Override Interval : %d msec\n",
1286 pim_if_jp_override_interval_msec(ifp
));
1290 vty_out(vty
, "LAN Prune Delay\n");
1291 vty_out(vty
, "---------------\n");
1292 vty_out(vty
, "Propagation Delay : %d msec\n",
1293 pim_ifp
->pim_propagation_delay_msec
);
1294 vty_out(vty
, "Propagation Delay (Highest) : %d msec\n",
1295 pim_ifp
->pim_neighbors_highest_propagation_delay_msec
);
1296 vty_out(vty
, "Override Interval : %d msec\n",
1297 pim_ifp
->pim_override_interval_msec
);
1298 vty_out(vty
, "Override Interval (Highest) : %d msec\n",
1299 pim_ifp
->pim_neighbors_highest_override_interval_msec
);
1306 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1307 json
, JSON_C_TO_STRING_PRETTY
));
1308 json_object_free(json
);
1311 vty_out(vty
, "%% No such interface\n");
1315 static void igmp_show_statistics(struct pim_instance
*pim
, struct vty
*vty
,
1316 const char *ifname
, bool uj
)
1318 struct interface
*ifp
;
1319 struct igmp_stats rx_stats
;
1321 igmp_stats_init(&rx_stats
);
1323 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1324 struct pim_interface
*pim_ifp
;
1325 struct listnode
*sock_node
;
1326 struct igmp_sock
*igmp
;
1328 pim_ifp
= ifp
->info
;
1333 if (ifname
&& strcmp(ifname
, ifp
->name
))
1336 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
1338 igmp_stats_add(&rx_stats
, &igmp
->rx_stats
);
1342 json_object
*json
= NULL
;
1343 json_object
*json_row
= NULL
;
1345 json
= json_object_new_object();
1346 json_row
= json_object_new_object();
1348 json_object_string_add(json_row
, "name", ifname
? ifname
:
1350 json_object_int_add(json_row
, "queryV1", rx_stats
.query_v1
);
1351 json_object_int_add(json_row
, "queryV2", rx_stats
.query_v2
);
1352 json_object_int_add(json_row
, "queryV3", rx_stats
.query_v3
);
1353 json_object_int_add(json_row
, "leaveV3", rx_stats
.leave_v2
);
1354 json_object_int_add(json_row
, "reportV1", rx_stats
.report_v1
);
1355 json_object_int_add(json_row
, "reportV2", rx_stats
.report_v2
);
1356 json_object_int_add(json_row
, "reportV3", rx_stats
.report_v3
);
1357 json_object_int_add(json_row
, "mtraceResponse",
1358 rx_stats
.mtrace_rsp
);
1359 json_object_int_add(json_row
, "mtraceRequest",
1360 rx_stats
.mtrace_req
);
1361 json_object_int_add(json_row
, "unsupported",
1362 rx_stats
.unsupported
);
1363 json_object_object_add(json
, ifname
? ifname
: "global",
1365 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1366 json
, JSON_C_TO_STRING_PRETTY
));
1367 json_object_free(json
);
1369 vty_out(vty
, "IGMP RX statistics\n");
1370 vty_out(vty
, "Interface : %s\n",
1371 ifname
? ifname
: "global");
1372 vty_out(vty
, "V1 query : %u\n", rx_stats
.query_v1
);
1373 vty_out(vty
, "V2 query : %u\n", rx_stats
.query_v2
);
1374 vty_out(vty
, "V3 query : %u\n", rx_stats
.query_v3
);
1375 vty_out(vty
, "V2 leave : %u\n", rx_stats
.leave_v2
);
1376 vty_out(vty
, "V1 report : %u\n", rx_stats
.report_v1
);
1377 vty_out(vty
, "V2 report : %u\n", rx_stats
.report_v2
);
1378 vty_out(vty
, "V3 report : %u\n", rx_stats
.report_v3
);
1379 vty_out(vty
, "mtrace response : %u\n", rx_stats
.mtrace_rsp
);
1380 vty_out(vty
, "mtrace request : %u\n", rx_stats
.mtrace_req
);
1381 vty_out(vty
, "unsupported : %u\n", rx_stats
.unsupported
);
1385 static void pim_show_interfaces(struct pim_instance
*pim
, struct vty
*vty
,
1388 struct interface
*ifp
;
1389 struct listnode
*upnode
;
1390 struct pim_interface
*pim_ifp
;
1391 struct pim_upstream
*up
;
1394 int pim_ifchannels
= 0;
1395 json_object
*json
= NULL
;
1396 json_object
*json_row
= NULL
;
1397 json_object
*json_tmp
;
1399 json
= json_object_new_object();
1401 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1402 pim_ifp
= ifp
->info
;
1407 pim_nbrs
= pim_ifp
->pim_neighbor_list
->count
;
1408 pim_ifchannels
= pim_if_ifchannel_count(pim_ifp
);
1411 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
, up
))
1412 if (ifp
== up
->rpf
.source_nexthop
.interface
)
1413 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
1416 json_row
= json_object_new_object();
1417 json_object_pim_ifp_add(json_row
, ifp
);
1418 json_object_int_add(json_row
, "pimNeighbors", pim_nbrs
);
1419 json_object_int_add(json_row
, "pimIfChannels", pim_ifchannels
);
1420 json_object_int_add(json_row
, "firstHopRouterCount", fhr
);
1421 json_object_string_add(json_row
, "pimDesignatedRouter",
1422 inet_ntoa(pim_ifp
->pim_dr_addr
));
1424 if (pim_ifp
->pim_dr_addr
.s_addr
1425 == pim_ifp
->primary_address
.s_addr
)
1426 json_object_boolean_true_add(
1427 json_row
, "pimDesignatedRouterLocal");
1429 json_object_object_add(json
, ifp
->name
, json_row
);
1433 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1434 json
, JSON_C_TO_STRING_PRETTY
));
1437 "Interface State Address PIM Nbrs PIM DR FHR IfChannels\n");
1439 json_object_object_foreach(json
, key
, val
)
1441 vty_out(vty
, "%-16s ", key
);
1443 json_object_object_get_ex(val
, "state", &json_tmp
);
1444 vty_out(vty
, "%5s ", json_object_get_string(json_tmp
));
1446 json_object_object_get_ex(val
, "address", &json_tmp
);
1447 vty_out(vty
, "%15s ",
1448 json_object_get_string(json_tmp
));
1450 json_object_object_get_ex(val
, "pimNeighbors",
1452 vty_out(vty
, "%8d ", json_object_get_int(json_tmp
));
1454 if (json_object_object_get_ex(
1455 val
, "pimDesignatedRouterLocal",
1457 vty_out(vty
, "%15s ", "local");
1459 json_object_object_get_ex(
1460 val
, "pimDesignatedRouter", &json_tmp
);
1461 vty_out(vty
, "%15s ",
1462 json_object_get_string(json_tmp
));
1465 json_object_object_get_ex(val
, "firstHopRouter",
1467 vty_out(vty
, "%3d ", json_object_get_int(json_tmp
));
1469 json_object_object_get_ex(val
, "pimIfChannels",
1471 vty_out(vty
, "%9d\n", json_object_get_int(json_tmp
));
1475 json_object_free(json
);
1478 static void pim_show_interface_traffic(struct pim_instance
*pim
,
1479 struct vty
*vty
, bool uj
)
1481 struct interface
*ifp
= NULL
;
1482 struct pim_interface
*pim_ifp
= NULL
;
1483 json_object
*json
= NULL
;
1484 json_object
*json_row
= NULL
;
1487 json
= json_object_new_object();
1490 vty_out(vty
, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s%-17s\n",
1491 "Interface", " HELLO", " JOIN",
1492 " PRUNE", " REGISTER", "REGISTER-STOP",
1494 vty_out(vty
, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s%-17s\n", "",
1495 " Rx/Tx", " Rx/Tx", " Rx/Tx",
1496 " Rx/Tx", " Rx/Tx", " Rx/Tx",
1499 "---------------------------------------------------------------------------------------------------------------\n");
1502 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1503 pim_ifp
= ifp
->info
;
1508 if (pim_ifp
->pim_sock_fd
< 0)
1511 json_row
= json_object_new_object();
1512 json_object_pim_ifp_add(json_row
, ifp
);
1513 json_object_int_add(json_row
, "helloRx",
1514 pim_ifp
->pim_ifstat_hello_recv
);
1515 json_object_int_add(json_row
, "helloTx",
1516 pim_ifp
->pim_ifstat_hello_sent
);
1517 json_object_int_add(json_row
, "joinRx",
1518 pim_ifp
->pim_ifstat_join_recv
);
1519 json_object_int_add(json_row
, "joinTx",
1520 pim_ifp
->pim_ifstat_join_send
);
1521 json_object_int_add(json_row
, "registerRx",
1522 pim_ifp
->pim_ifstat_reg_recv
);
1523 json_object_int_add(json_row
, "registerTx",
1524 pim_ifp
->pim_ifstat_reg_recv
);
1525 json_object_int_add(json_row
, "registerStopRx",
1526 pim_ifp
->pim_ifstat_reg_stop_recv
);
1527 json_object_int_add(json_row
, "registerStopTx",
1528 pim_ifp
->pim_ifstat_reg_stop_send
);
1529 json_object_int_add(json_row
, "assertRx",
1530 pim_ifp
->pim_ifstat_assert_recv
);
1531 json_object_int_add(json_row
, "assertTx",
1532 pim_ifp
->pim_ifstat_assert_send
);
1533 json_object_int_add(json_row
, "bsmRx",
1534 pim_ifp
->pim_ifstat_bsm_rx
);
1535 json_object_int_add(json_row
, "bsmTx",
1536 pim_ifp
->pim_ifstat_bsm_tx
);
1537 json_object_object_add(json
, ifp
->name
, json_row
);
1540 "%-16s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7" PRIu64
"/%-7" PRIu64
"\n",
1541 ifp
->name
, pim_ifp
->pim_ifstat_hello_recv
,
1542 pim_ifp
->pim_ifstat_hello_sent
,
1543 pim_ifp
->pim_ifstat_join_recv
,
1544 pim_ifp
->pim_ifstat_join_send
,
1545 pim_ifp
->pim_ifstat_prune_recv
,
1546 pim_ifp
->pim_ifstat_prune_send
,
1547 pim_ifp
->pim_ifstat_reg_recv
,
1548 pim_ifp
->pim_ifstat_reg_send
,
1549 pim_ifp
->pim_ifstat_reg_stop_recv
,
1550 pim_ifp
->pim_ifstat_reg_stop_send
,
1551 pim_ifp
->pim_ifstat_assert_recv
,
1552 pim_ifp
->pim_ifstat_assert_send
,
1553 pim_ifp
->pim_ifstat_bsm_rx
,
1554 pim_ifp
->pim_ifstat_bsm_tx
);
1558 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1559 json
, JSON_C_TO_STRING_PRETTY
));
1560 json_object_free(json
);
1564 static void pim_show_interface_traffic_single(struct pim_instance
*pim
,
1566 const char *ifname
, bool uj
)
1568 struct interface
*ifp
= NULL
;
1569 struct pim_interface
*pim_ifp
= NULL
;
1570 json_object
*json
= NULL
;
1571 json_object
*json_row
= NULL
;
1572 uint8_t found_ifname
= 0;
1575 json
= json_object_new_object();
1578 vty_out(vty
, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s%-17s\n",
1579 "Interface", " HELLO", " JOIN", " PRUNE",
1580 " REGISTER", " REGISTER-STOP", " ASSERT",
1582 vty_out(vty
, "%-14s%-18s%-17s%-17s%-17s%-17s%-17s%-17s\n", "",
1583 " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1584 " Rx/Tx", " Rx/Tx", " Rx/Tx");
1586 "-------------------------------------------------------------------------------------------------------------------------------\n");
1589 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1590 if (strcmp(ifname
, ifp
->name
))
1593 pim_ifp
= ifp
->info
;
1598 if (pim_ifp
->pim_sock_fd
< 0)
1603 json_row
= json_object_new_object();
1604 json_object_pim_ifp_add(json_row
, ifp
);
1605 json_object_int_add(json_row
, "helloRx",
1606 pim_ifp
->pim_ifstat_hello_recv
);
1607 json_object_int_add(json_row
, "helloTx",
1608 pim_ifp
->pim_ifstat_hello_sent
);
1609 json_object_int_add(json_row
, "joinRx",
1610 pim_ifp
->pim_ifstat_join_recv
);
1611 json_object_int_add(json_row
, "joinTx",
1612 pim_ifp
->pim_ifstat_join_send
);
1613 json_object_int_add(json_row
, "registerRx",
1614 pim_ifp
->pim_ifstat_reg_recv
);
1615 json_object_int_add(json_row
, "registerTx",
1616 pim_ifp
->pim_ifstat_reg_recv
);
1617 json_object_int_add(json_row
, "registerStopRx",
1618 pim_ifp
->pim_ifstat_reg_stop_recv
);
1619 json_object_int_add(json_row
, "registerStopTx",
1620 pim_ifp
->pim_ifstat_reg_stop_send
);
1621 json_object_int_add(json_row
, "assertRx",
1622 pim_ifp
->pim_ifstat_assert_recv
);
1623 json_object_int_add(json_row
, "assertTx",
1624 pim_ifp
->pim_ifstat_assert_send
);
1625 json_object_int_add(json_row
, "bsmRx",
1626 pim_ifp
->pim_ifstat_bsm_rx
);
1627 json_object_int_add(json_row
, "bsmTx",
1628 pim_ifp
->pim_ifstat_bsm_tx
);
1630 json_object_object_add(json
, ifp
->name
, json_row
);
1633 "%-16s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7" PRIu64
"/%-7" PRIu64
"\n",
1634 ifp
->name
, pim_ifp
->pim_ifstat_hello_recv
,
1635 pim_ifp
->pim_ifstat_hello_sent
,
1636 pim_ifp
->pim_ifstat_join_recv
,
1637 pim_ifp
->pim_ifstat_join_send
,
1638 pim_ifp
->pim_ifstat_prune_recv
,
1639 pim_ifp
->pim_ifstat_prune_send
,
1640 pim_ifp
->pim_ifstat_reg_recv
,
1641 pim_ifp
->pim_ifstat_reg_send
,
1642 pim_ifp
->pim_ifstat_reg_stop_recv
,
1643 pim_ifp
->pim_ifstat_reg_stop_send
,
1644 pim_ifp
->pim_ifstat_assert_recv
,
1645 pim_ifp
->pim_ifstat_assert_send
,
1646 pim_ifp
->pim_ifstat_bsm_rx
,
1647 pim_ifp
->pim_ifstat_bsm_tx
);
1651 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1652 json
, JSON_C_TO_STRING_PRETTY
));
1653 json_object_free(json
);
1656 vty_out(vty
, "%% No such interface\n");
1660 static void pim_show_join_helper(struct vty
*vty
, struct pim_interface
*pim_ifp
,
1661 struct pim_ifchannel
*ch
, json_object
*json
,
1662 time_t now
, bool uj
)
1664 char ch_src_str
[INET_ADDRSTRLEN
];
1665 char ch_grp_str
[INET_ADDRSTRLEN
];
1666 json_object
*json_iface
= NULL
;
1667 json_object
*json_row
= NULL
;
1668 json_object
*json_grp
= NULL
;
1669 struct in_addr ifaddr
;
1674 ifaddr
= pim_ifp
->primary_address
;
1676 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
1677 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
1679 pim_time_uptime_begin(uptime
, sizeof(uptime
), now
, ch
->ifjoin_creation
);
1680 pim_time_timer_to_mmss(expire
, sizeof(expire
),
1681 ch
->t_ifjoin_expiry_timer
);
1682 pim_time_timer_to_mmss(prune
, sizeof(prune
),
1683 ch
->t_ifjoin_prune_pending_timer
);
1686 json_object_object_get_ex(json
, ch
->interface
->name
,
1690 json_iface
= json_object_new_object();
1691 json_object_pim_ifp_add(json_iface
, ch
->interface
);
1692 json_object_object_add(json
, ch
->interface
->name
,
1696 json_row
= json_object_new_object();
1697 json_object_string_add(json_row
, "source", ch_src_str
);
1698 json_object_string_add(json_row
, "group", ch_grp_str
);
1699 json_object_string_add(json_row
, "upTime", uptime
);
1700 json_object_string_add(json_row
, "expire", expire
);
1701 json_object_string_add(json_row
, "prune", prune
);
1702 json_object_string_add(
1703 json_row
, "channelJoinName",
1704 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
, ch
->flags
));
1705 if (PIM_IF_FLAG_TEST_S_G_RPT(ch
->flags
))
1706 json_object_int_add(json_row
, "SGRpt", 1);
1708 json_object_object_get_ex(json_iface
, ch_grp_str
, &json_grp
);
1710 json_grp
= json_object_new_object();
1711 json_object_object_add(json_grp
, ch_src_str
, json_row
);
1712 json_object_object_add(json_iface
, ch_grp_str
,
1715 json_object_object_add(json_grp
, ch_src_str
, json_row
);
1717 vty_out(vty
, "%-16s %-15s %-15s %-15s %-10s %8s %-6s %5s\n",
1718 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
,
1720 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
, ch
->flags
),
1721 uptime
, expire
, prune
);
1725 static void pim_show_join(struct pim_instance
*pim
, struct vty
*vty
,
1726 struct prefix_sg
*sg
, bool uj
)
1728 struct pim_interface
*pim_ifp
;
1729 struct pim_ifchannel
*ch
;
1730 struct interface
*ifp
;
1732 json_object
*json
= NULL
;
1734 now
= pim_time_monotonic_sec();
1737 json
= json_object_new_object();
1740 "Interface Address Source Group State Uptime Expire Prune\n");
1742 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1743 pim_ifp
= ifp
->info
;
1747 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
1748 if (sg
->grp
.s_addr
!= 0
1749 && sg
->grp
.s_addr
!= ch
->sg
.grp
.s_addr
)
1751 if (sg
->src
.s_addr
!= 0
1752 && sg
->src
.s_addr
!= ch
->sg
.src
.s_addr
)
1754 pim_show_join_helper(vty
, pim_ifp
, ch
, json
, now
, uj
);
1755 } /* scan interface channels */
1759 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1760 json
, JSON_C_TO_STRING_PRETTY
));
1761 json_object_free(json
);
1765 static void pim_show_neighbors_single(struct pim_instance
*pim
, struct vty
*vty
,
1766 const char *neighbor
, bool uj
)
1768 struct listnode
*neighnode
;
1769 struct interface
*ifp
;
1770 struct pim_interface
*pim_ifp
;
1771 struct pim_neighbor
*neigh
;
1773 int found_neighbor
= 0;
1774 int option_address_list
;
1775 int option_dr_priority
;
1776 int option_generation_id
;
1777 int option_holdtime
;
1778 int option_lan_prune_delay
;
1782 char neigh_src_str
[INET_ADDRSTRLEN
];
1784 json_object
*json
= NULL
;
1785 json_object
*json_ifp
= NULL
;
1786 json_object
*json_row
= NULL
;
1788 now
= pim_time_monotonic_sec();
1791 json
= json_object_new_object();
1793 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1794 pim_ifp
= ifp
->info
;
1799 if (pim_ifp
->pim_sock_fd
< 0)
1802 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
1804 pim_inet4_dump("<src?>", neigh
->source_addr
,
1805 neigh_src_str
, sizeof(neigh_src_str
));
1808 * The user can specify either the interface name or the
1810 * If this pim_ifp matches neither then skip.
1812 if (strcmp(neighbor
, "detail")
1813 && strcmp(neighbor
, ifp
->name
)
1814 && strcmp(neighbor
, neigh_src_str
))
1818 pim_time_uptime(uptime
, sizeof(uptime
),
1819 now
- neigh
->creation
);
1820 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
1821 neigh
->t_expire_timer
);
1823 option_address_list
= 0;
1824 option_dr_priority
= 0;
1825 option_generation_id
= 0;
1826 option_holdtime
= 0;
1827 option_lan_prune_delay
= 0;
1830 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1831 PIM_OPTION_MASK_ADDRESS_LIST
))
1832 option_address_list
= 1;
1834 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1835 PIM_OPTION_MASK_DR_PRIORITY
))
1836 option_dr_priority
= 1;
1838 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1839 PIM_OPTION_MASK_GENERATION_ID
))
1840 option_generation_id
= 1;
1842 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1843 PIM_OPTION_MASK_HOLDTIME
))
1844 option_holdtime
= 1;
1846 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1847 PIM_OPTION_MASK_LAN_PRUNE_DELAY
))
1848 option_lan_prune_delay
= 1;
1850 if (PIM_OPTION_IS_SET(
1851 neigh
->hello_options
,
1852 PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION
))
1857 /* Does this ifp live in json? If not create
1859 json_object_object_get_ex(json
, ifp
->name
,
1863 json_ifp
= json_object_new_object();
1864 json_object_pim_ifp_add(json_ifp
, ifp
);
1865 json_object_object_add(json
, ifp
->name
,
1869 json_row
= json_object_new_object();
1870 json_object_string_add(json_row
, "interface",
1872 json_object_string_add(json_row
, "address",
1874 json_object_string_add(json_row
, "upTime",
1876 json_object_string_add(json_row
, "holdtime",
1878 json_object_int_add(json_row
, "drPriority",
1879 neigh
->dr_priority
);
1880 json_object_int_add(json_row
, "generationId",
1881 neigh
->generation_id
);
1883 if (option_address_list
)
1884 json_object_boolean_true_add(
1886 "helloOptionAddressList");
1888 if (option_dr_priority
)
1889 json_object_boolean_true_add(
1891 "helloOptionDrPriority");
1893 if (option_generation_id
)
1894 json_object_boolean_true_add(
1896 "helloOptionGenerationId");
1898 if (option_holdtime
)
1899 json_object_boolean_true_add(
1901 "helloOptionHoldtime");
1903 if (option_lan_prune_delay
)
1904 json_object_boolean_true_add(
1906 "helloOptionLanPruneDelay");
1909 json_object_boolean_true_add(
1910 json_row
, "helloOptionTBit");
1912 json_object_object_add(json_ifp
, neigh_src_str
,
1916 vty_out(vty
, "Interface : %s\n", ifp
->name
);
1917 vty_out(vty
, "Neighbor : %s\n", neigh_src_str
);
1925 " DR Priority : %d\n",
1926 neigh
->dr_priority
);
1928 " Generation ID : %08x\n",
1929 neigh
->generation_id
);
1931 " Override Interval (msec) : %d\n",
1932 neigh
->override_interval_msec
);
1934 " Propagation Delay (msec) : %d\n",
1935 neigh
->propagation_delay_msec
);
1937 " Hello Option - Address List : %s\n",
1938 option_address_list
? "yes" : "no");
1940 " Hello Option - DR Priority : %s\n",
1941 option_dr_priority
? "yes" : "no");
1943 " Hello Option - Generation ID : %s\n",
1944 option_generation_id
? "yes" : "no");
1946 " Hello Option - Holdtime : %s\n",
1947 option_holdtime
? "yes" : "no");
1949 " Hello Option - LAN Prune Delay : %s\n",
1950 option_lan_prune_delay
? "yes" : "no");
1952 " Hello Option - T-bit : %s\n",
1953 option_t_bit
? "yes" : "no");
1954 pim_bfd_show_info(vty
, neigh
->bfd_info
,
1962 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1963 json
, JSON_C_TO_STRING_PRETTY
));
1964 json_object_free(json
);
1967 if (!found_neighbor
)
1969 "%% No such interface or neighbor\n");
1974 static void pim_show_state(struct pim_instance
*pim
, struct vty
*vty
,
1975 const char *src_or_group
, const char *group
, bool uj
)
1977 struct channel_oil
*c_oil
;
1978 struct listnode
*node
;
1979 json_object
*json
= NULL
;
1980 json_object
*json_group
= NULL
;
1981 json_object
*json_ifp_in
= NULL
;
1982 json_object
*json_ifp_out
= NULL
;
1983 json_object
*json_source
= NULL
;
1986 now
= pim_time_monotonic_sec();
1989 json
= json_object_new_object();
1992 "Codes: J -> Pim Join, I -> IGMP Report, S -> Source, * -> Inherited from (*,G), V -> VxLAN");
1994 "\nInstalled Source Group IIF OIL\n");
1997 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
1998 char grp_str
[INET_ADDRSTRLEN
];
1999 char src_str
[INET_ADDRSTRLEN
];
2000 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
2001 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
2003 struct interface
*ifp_in
;
2006 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
2008 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
2010 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
2013 strlcpy(in_ifname
, ifp_in
->name
, sizeof(in_ifname
));
2015 strlcpy(in_ifname
, "<iif?>", sizeof(in_ifname
));
2018 if (strcmp(src_or_group
, src_str
)
2019 && strcmp(src_or_group
, grp_str
))
2022 if (group
&& strcmp(group
, grp_str
))
2028 /* Find the group, create it if it doesn't exist */
2029 json_object_object_get_ex(json
, grp_str
, &json_group
);
2032 json_group
= json_object_new_object();
2033 json_object_object_add(json
, grp_str
,
2037 /* Find the source nested under the group, create it if
2038 * it doesn't exist */
2039 json_object_object_get_ex(json_group
, src_str
,
2043 json_source
= json_object_new_object();
2044 json_object_object_add(json_group
, src_str
,
2048 /* Find the inbound interface nested under the source,
2049 * create it if it doesn't exist */
2050 json_object_object_get_ex(json_source
, in_ifname
,
2054 json_ifp_in
= json_object_new_object();
2055 json_object_object_add(json_source
, in_ifname
,
2057 json_object_int_add(json_source
, "Installed",
2059 json_object_int_add(json_source
, "RefCount",
2060 c_oil
->oil_ref_count
);
2061 json_object_int_add(json_source
, "OilListSize",
2063 json_object_int_add(
2064 json_source
, "OilRescan",
2065 c_oil
->oil_inherited_rescan
);
2066 json_object_int_add(json_source
, "LastUsed",
2067 c_oil
->cc
.lastused
);
2068 json_object_int_add(json_source
, "PacketCount",
2070 json_object_int_add(json_source
, "ByteCount",
2072 json_object_int_add(json_source
,
2074 c_oil
->cc
.wrong_if
);
2077 vty_out(vty
, "%-9d %-15s %-15s %-16s ",
2078 c_oil
->installed
, src_str
, grp_str
, in_ifname
);
2081 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
2083 struct interface
*ifp_out
;
2084 char oif_uptime
[10];
2087 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
2091 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
2093 oif_uptime
, sizeof(oif_uptime
),
2094 now
- c_oil
->oif_creation
[oif_vif_index
]);
2097 strlcpy(out_ifname
, ifp_out
->name
, sizeof(out_ifname
));
2099 strlcpy(out_ifname
, "<oif?>", sizeof(out_ifname
));
2102 json_ifp_out
= json_object_new_object();
2103 json_object_string_add(json_ifp_out
, "source",
2105 json_object_string_add(json_ifp_out
, "group",
2107 json_object_string_add(json_ifp_out
,
2110 json_object_string_add(json_ifp_out
,
2111 "outboundInterface",
2113 json_object_int_add(json_ifp_out
, "installed",
2116 json_object_object_add(json_ifp_in
, out_ifname
,
2121 vty_out(vty
, "%s(%c%c%c%c)", out_ifname
,
2122 (c_oil
->oif_flags
[oif_vif_index
]
2123 & PIM_OIF_FLAG_PROTO_IGMP
)
2126 (c_oil
->oif_flags
[oif_vif_index
]
2127 & PIM_OIF_FLAG_PROTO_PIM
)
2130 (c_oil
->oif_flags
[oif_vif_index
]
2131 & PIM_OIF_FLAG_PROTO_VXLAN
)
2134 (c_oil
->oif_flags
[oif_vif_index
]
2135 & PIM_OIF_FLAG_PROTO_STAR
)
2139 vty_out(vty
, ", %s(%c%c%c%c)",
2141 (c_oil
->oif_flags
[oif_vif_index
]
2142 & PIM_OIF_FLAG_PROTO_IGMP
)
2145 (c_oil
->oif_flags
[oif_vif_index
]
2146 & PIM_OIF_FLAG_PROTO_PIM
)
2149 (c_oil
->oif_flags
[oif_vif_index
]
2150 & PIM_OIF_FLAG_PROTO_VXLAN
)
2153 (c_oil
->oif_flags
[oif_vif_index
]
2154 & PIM_OIF_FLAG_PROTO_STAR
)
2166 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2167 json
, JSON_C_TO_STRING_PRETTY
));
2168 json_object_free(json
);
2174 static void pim_show_neighbors(struct pim_instance
*pim
, struct vty
*vty
,
2177 struct listnode
*neighnode
;
2178 struct interface
*ifp
;
2179 struct pim_interface
*pim_ifp
;
2180 struct pim_neighbor
*neigh
;
2184 char neigh_src_str
[INET_ADDRSTRLEN
];
2185 json_object
*json
= NULL
;
2186 json_object
*json_ifp_rows
= NULL
;
2187 json_object
*json_row
= NULL
;
2189 now
= pim_time_monotonic_sec();
2192 json
= json_object_new_object();
2195 "Interface Neighbor Uptime Holdtime DR Pri\n");
2198 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2199 pim_ifp
= ifp
->info
;
2204 if (pim_ifp
->pim_sock_fd
< 0)
2208 json_ifp_rows
= json_object_new_object();
2210 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
2212 pim_inet4_dump("<src?>", neigh
->source_addr
,
2213 neigh_src_str
, sizeof(neigh_src_str
));
2214 pim_time_uptime(uptime
, sizeof(uptime
),
2215 now
- neigh
->creation
);
2216 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
2217 neigh
->t_expire_timer
);
2220 json_row
= json_object_new_object();
2221 json_object_string_add(json_row
, "interface",
2223 json_object_string_add(json_row
, "neighbor",
2225 json_object_string_add(json_row
, "upTime",
2227 json_object_string_add(json_row
, "holdTime",
2229 json_object_int_add(json_row
, "holdTimeMax",
2231 json_object_int_add(json_row
, "drPriority",
2232 neigh
->dr_priority
);
2233 json_object_object_add(json_ifp_rows
,
2234 neigh_src_str
, json_row
);
2237 vty_out(vty
, "%-16s %15s %8s %8s %6d\n",
2238 ifp
->name
, neigh_src_str
, uptime
,
2239 expire
, neigh
->dr_priority
);
2244 json_object_object_add(json
, ifp
->name
, json_ifp_rows
);
2245 json_ifp_rows
= NULL
;
2250 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2251 json
, JSON_C_TO_STRING_PRETTY
));
2252 json_object_free(json
);
2256 static void pim_show_neighbors_secondary(struct pim_instance
*pim
,
2259 struct interface
*ifp
;
2262 "Interface Address Neighbor Secondary \n");
2264 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2265 struct pim_interface
*pim_ifp
;
2266 struct in_addr ifaddr
;
2267 struct listnode
*neighnode
;
2268 struct pim_neighbor
*neigh
;
2270 pim_ifp
= ifp
->info
;
2275 if (pim_ifp
->pim_sock_fd
< 0)
2278 ifaddr
= pim_ifp
->primary_address
;
2280 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
2282 char neigh_src_str
[INET_ADDRSTRLEN
];
2283 struct listnode
*prefix_node
;
2286 if (!neigh
->prefix_list
)
2289 pim_inet4_dump("<src?>", neigh
->source_addr
,
2290 neigh_src_str
, sizeof(neigh_src_str
));
2292 for (ALL_LIST_ELEMENTS_RO(neigh
->prefix_list
,
2294 char neigh_sec_str
[PREFIX2STR_BUFFER
];
2296 prefix2str(p
, neigh_sec_str
,
2297 sizeof(neigh_sec_str
));
2299 vty_out(vty
, "%-16s %-15s %-15s %-15s\n",
2300 ifp
->name
, inet_ntoa(ifaddr
),
2301 neigh_src_str
, neigh_sec_str
);
2307 static void json_object_pim_upstream_add(json_object
*json
,
2308 struct pim_upstream
*up
)
2310 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED
)
2311 json_object_boolean_true_add(json
, "drJoinDesired");
2313 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED
)
2314 json_object_boolean_true_add(json
, "drJoinDesiredUpdated");
2316 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
2317 json_object_boolean_true_add(json
, "firstHopRouter");
2319 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_IGMP
)
2320 json_object_boolean_true_add(json
, "sourceIgmp");
2322 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_PIM
)
2323 json_object_boolean_true_add(json
, "sourcePim");
2325 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_STREAM
)
2326 json_object_boolean_true_add(json
, "sourceStream");
2328 /* XXX: need to print ths flag in the plain text display as well */
2329 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_MSDP
)
2330 json_object_boolean_true_add(json
, "sourceMsdp");
2332 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SEND_SG_RPT_PRUNE
)
2333 json_object_boolean_true_add(json
, "sendSGRptPrune");
2335 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_LHR
)
2336 json_object_boolean_true_add(json
, "lastHopRouter");
2338 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DISABLE_KAT_EXPIRY
)
2339 json_object_boolean_true_add(json
, "disableKATExpiry");
2341 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_STATIC_IIF
)
2342 json_object_boolean_true_add(json
, "staticIncomingInterface");
2344 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_ALLOW_IIF_IN_OIL
)
2345 json_object_boolean_true_add(json
,
2346 "allowIncomingInterfaceinOil");
2348 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_NO_PIMREG_DATA
)
2349 json_object_boolean_true_add(json
, "noPimRegistrationData");
2351 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FORCE_PIMREG
)
2352 json_object_boolean_true_add(json
, "forcePimRegistration");
2354 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_ORIG
)
2355 json_object_boolean_true_add(json
, "sourceVxlanOrigination");
2357 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_TERM
)
2358 json_object_boolean_true_add(json
, "sourceVxlanTermination");
2360 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_VXLAN
)
2361 json_object_boolean_true_add(json
, "mlagVxlan");
2363 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_NON_DF
)
2364 json_object_boolean_true_add(json
,
2365 "mlagNonDesignatedForwarder");
2369 pim_upstream_state2brief_str(enum pim_upstream_state join_state
,
2370 char *state_str
, size_t state_str_len
)
2372 switch (join_state
) {
2373 case PIM_UPSTREAM_NOTJOINED
:
2374 strlcpy(state_str
, "NotJ", state_str_len
);
2376 case PIM_UPSTREAM_JOINED
:
2377 strlcpy(state_str
, "J", state_str_len
);
2380 strlcpy(state_str
, "Unk", state_str_len
);
2385 static const char *pim_reg_state2brief_str(enum pim_reg_state reg_state
,
2386 char *state_str
, size_t state_str_len
)
2388 switch (reg_state
) {
2389 case PIM_REG_NOINFO
:
2390 strlcpy(state_str
, "RegNI", state_str_len
);
2393 strlcpy(state_str
, "RegJ", state_str_len
);
2395 case PIM_REG_JOIN_PENDING
:
2397 strlcpy(state_str
, "RegP", state_str_len
);
2400 strlcpy(state_str
, "Unk", state_str_len
);
2405 static void pim_show_upstream(struct pim_instance
*pim
, struct vty
*vty
,
2406 struct prefix_sg
*sg
, bool uj
)
2408 struct listnode
*upnode
;
2409 struct pim_upstream
*up
;
2411 json_object
*json
= NULL
;
2412 json_object
*json_group
= NULL
;
2413 json_object
*json_row
= NULL
;
2415 now
= pim_time_monotonic_sec();
2418 json
= json_object_new_object();
2421 "Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt\n");
2423 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
, up
)) {
2424 char src_str
[INET_ADDRSTRLEN
];
2425 char grp_str
[INET_ADDRSTRLEN
];
2427 char join_timer
[10];
2430 char msdp_reg_timer
[10];
2431 char state_str
[PIM_REG_STATE_STR_LEN
];
2433 if (sg
->grp
.s_addr
!= 0 && sg
->grp
.s_addr
!= up
->sg
.grp
.s_addr
)
2435 if (sg
->src
.s_addr
!= 0 && sg
->src
.s_addr
!= up
->sg
.src
.s_addr
)
2438 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2439 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2440 pim_time_uptime(uptime
, sizeof(uptime
),
2441 now
- up
->state_transition
);
2442 pim_time_timer_to_hhmmss(join_timer
, sizeof(join_timer
),
2446 * If the upstream is not dummy and it has a J/P timer for the
2447 * neighbor display that
2449 if (!up
->t_join_timer
&& up
->rpf
.source_nexthop
.interface
) {
2450 struct pim_neighbor
*nbr
;
2452 nbr
= pim_neighbor_find(
2453 up
->rpf
.source_nexthop
.interface
,
2454 up
->rpf
.rpf_addr
.u
.prefix4
);
2456 pim_time_timer_to_hhmmss(join_timer
,
2461 pim_time_timer_to_hhmmss(rs_timer
, sizeof(rs_timer
),
2463 pim_time_timer_to_hhmmss(ka_timer
, sizeof(ka_timer
),
2465 pim_time_timer_to_hhmmss(msdp_reg_timer
, sizeof(msdp_reg_timer
),
2466 up
->t_msdp_reg_timer
);
2468 pim_upstream_state2brief_str(up
->join_state
, state_str
, sizeof(state_str
));
2469 if (up
->reg_state
!= PIM_REG_NOINFO
) {
2470 char tmp_str
[PIM_REG_STATE_STR_LEN
];
2472 sprintf(state_str
+ strlen(state_str
), ",%s",
2473 pim_reg_state2brief_str(up
->reg_state
, tmp_str
,
2478 json_object_object_get_ex(json
, grp_str
, &json_group
);
2481 json_group
= json_object_new_object();
2482 json_object_object_add(json
, grp_str
,
2486 json_row
= json_object_new_object();
2487 json_object_pim_upstream_add(json_row
, up
);
2488 json_object_string_add(
2489 json_row
, "inboundInterface",
2490 up
->rpf
.source_nexthop
.interface
2491 ? up
->rpf
.source_nexthop
.interface
->name
2495 * The RPF address we use is slightly different
2496 * based upon what we are looking up.
2497 * If we have a S, list that unless
2498 * we are the FHR, else we just put
2499 * the RP as the rpfAddress
2501 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
2502 || up
->sg
.src
.s_addr
== INADDR_ANY
) {
2503 char rpf
[PREFIX_STRLEN
];
2504 struct pim_rpf
*rpg
;
2506 rpg
= RP(pim
, up
->sg
.grp
);
2507 pim_inet4_dump("<rpf?>",
2508 rpg
->rpf_addr
.u
.prefix4
, rpf
,
2510 json_object_string_add(json_row
, "rpfAddress",
2513 json_object_string_add(json_row
, "rpfAddress",
2517 json_object_string_add(json_row
, "source", src_str
);
2518 json_object_string_add(json_row
, "group", grp_str
);
2519 json_object_string_add(json_row
, "state", state_str
);
2520 json_object_string_add(
2521 json_row
, "joinState",
2522 pim_upstream_state2str(up
->join_state
));
2523 json_object_string_add(
2524 json_row
, "regState",
2525 pim_reg_state2str(up
->reg_state
, state_str
, sizeof(state_str
)));
2526 json_object_string_add(json_row
, "upTime", uptime
);
2527 json_object_string_add(json_row
, "joinTimer",
2529 json_object_string_add(json_row
, "resetTimer",
2531 json_object_string_add(json_row
, "keepaliveTimer",
2533 json_object_string_add(json_row
, "msdpRegTimer",
2535 json_object_int_add(json_row
, "refCount",
2537 json_object_int_add(json_row
, "sptBit", up
->sptbit
);
2538 json_object_object_add(json_group
, src_str
, json_row
);
2541 "%-16s%-15s %-15s %-11s %-8s %-9s %-9s %-9s %6d\n",
2542 up
->rpf
.source_nexthop
.interface
2543 ? up
->rpf
.source_nexthop
.interface
->name
2545 src_str
, grp_str
, state_str
, uptime
, join_timer
,
2546 rs_timer
, ka_timer
, up
->ref_count
);
2551 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2552 json
, JSON_C_TO_STRING_PRETTY
));
2553 json_object_free(json
);
2557 static void pim_show_join_desired_helper(struct pim_instance
*pim
,
2559 struct pim_interface
*pim_ifp
,
2560 struct pim_ifchannel
*ch
,
2561 json_object
*json
, bool uj
)
2563 struct pim_upstream
*up
= ch
->upstream
;
2564 json_object
*json_group
= NULL
;
2565 char src_str
[INET_ADDRSTRLEN
];
2566 char grp_str
[INET_ADDRSTRLEN
];
2567 json_object
*json_row
= NULL
;
2569 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2570 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2573 json_object_object_get_ex(json
, grp_str
, &json_group
);
2576 json_group
= json_object_new_object();
2577 json_object_object_add(json
, grp_str
, json_group
);
2580 json_row
= json_object_new_object();
2581 json_object_pim_upstream_add(json_row
, up
);
2582 json_object_string_add(json_row
, "interface",
2583 ch
->interface
->name
);
2584 json_object_string_add(json_row
, "source", src_str
);
2585 json_object_string_add(json_row
, "group", grp_str
);
2587 if (pim_macro_ch_lost_assert(ch
))
2588 json_object_boolean_true_add(json_row
, "lostAssert");
2590 if (pim_macro_chisin_joins(ch
))
2591 json_object_boolean_true_add(json_row
, "joins");
2593 if (pim_macro_chisin_pim_include(ch
))
2594 json_object_boolean_true_add(json_row
, "pimInclude");
2596 if (pim_upstream_evaluate_join_desired(pim
, up
))
2597 json_object_boolean_true_add(json_row
,
2598 "evaluateJoinDesired");
2600 json_object_object_add(json_group
, src_str
, json_row
);
2603 vty_out(vty
, "%-16s %-15s %-15s %-10s %-5s %-10s %-11s %-6s\n",
2604 ch
->interface
->name
, src_str
, grp_str
,
2605 pim_macro_ch_lost_assert(ch
) ? "yes" : "no",
2606 pim_macro_chisin_joins(ch
) ? "yes" : "no",
2607 pim_macro_chisin_pim_include(ch
) ? "yes" : "no",
2608 PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(up
->flags
)
2611 pim_upstream_evaluate_join_desired(pim
, up
) ? "yes"
2616 static void pim_show_join_desired(struct pim_instance
*pim
, struct vty
*vty
,
2619 struct pim_interface
*pim_ifp
;
2620 struct pim_ifchannel
*ch
;
2621 struct interface
*ifp
;
2623 json_object
*json
= NULL
;
2626 json
= json_object_new_object();
2629 "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD\n");
2631 /* scan per-interface (S,G) state */
2632 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2633 pim_ifp
= ifp
->info
;
2638 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
2639 /* scan all interfaces */
2640 pim_show_join_desired_helper(pim
, vty
, pim_ifp
, ch
,
2646 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2647 json
, JSON_C_TO_STRING_PRETTY
));
2648 json_object_free(json
);
2652 static void pim_show_upstream_rpf(struct pim_instance
*pim
, struct vty
*vty
,
2655 struct listnode
*upnode
;
2656 struct pim_upstream
*up
;
2657 json_object
*json
= NULL
;
2658 json_object
*json_group
= NULL
;
2659 json_object
*json_row
= NULL
;
2662 json
= json_object_new_object();
2665 "Source Group RpfIface RibNextHop RpfAddress \n");
2667 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
, up
)) {
2668 char src_str
[INET_ADDRSTRLEN
];
2669 char grp_str
[INET_ADDRSTRLEN
];
2670 char rpf_nexthop_str
[PREFIX_STRLEN
];
2671 char rpf_addr_str
[PREFIX_STRLEN
];
2672 struct pim_rpf
*rpf
;
2673 const char *rpf_ifname
;
2677 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2678 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2679 pim_addr_dump("<nexthop?>",
2680 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2681 rpf_nexthop_str
, sizeof(rpf_nexthop_str
));
2682 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2683 sizeof(rpf_addr_str
));
2685 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2688 json_object_object_get_ex(json
, grp_str
, &json_group
);
2691 json_group
= json_object_new_object();
2692 json_object_object_add(json
, grp_str
,
2696 json_row
= json_object_new_object();
2697 json_object_pim_upstream_add(json_row
, up
);
2698 json_object_string_add(json_row
, "source", src_str
);
2699 json_object_string_add(json_row
, "group", grp_str
);
2700 json_object_string_add(json_row
, "rpfInterface",
2702 json_object_string_add(json_row
, "ribNexthop",
2704 json_object_string_add(json_row
, "rpfAddress",
2706 json_object_object_add(json_group
, src_str
, json_row
);
2708 vty_out(vty
, "%-15s %-15s %-16s %-15s %-15s\n", src_str
,
2709 grp_str
, rpf_ifname
, rpf_nexthop_str
,
2715 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2716 json
, JSON_C_TO_STRING_PRETTY
));
2717 json_object_free(json
);
2721 static void show_rpf_refresh_stats(struct vty
*vty
, struct pim_instance
*pim
,
2722 time_t now
, json_object
*json
)
2724 char refresh_uptime
[10];
2726 pim_time_uptime_begin(refresh_uptime
, sizeof(refresh_uptime
), now
,
2727 pim
->rpf_cache_refresh_last
);
2730 json_object_int_add(json
, "rpfCacheRefreshDelayMsecs",
2731 router
->rpf_cache_refresh_delay_msec
);
2732 json_object_int_add(
2733 json
, "rpfCacheRefreshTimer",
2734 pim_time_timer_remain_msec(pim
->rpf_cache_refresher
));
2735 json_object_int_add(json
, "rpfCacheRefreshRequests",
2736 pim
->rpf_cache_refresh_requests
);
2737 json_object_int_add(json
, "rpfCacheRefreshEvents",
2738 pim
->rpf_cache_refresh_events
);
2739 json_object_string_add(json
, "rpfCacheRefreshLast",
2741 json_object_int_add(json
, "nexthopLookups",
2742 pim
->nexthop_lookups
);
2743 json_object_int_add(json
, "nexthopLookupsAvoided",
2744 pim
->nexthop_lookups_avoided
);
2747 "RPF Cache Refresh Delay: %ld msecs\n"
2748 "RPF Cache Refresh Timer: %ld msecs\n"
2749 "RPF Cache Refresh Requests: %lld\n"
2750 "RPF Cache Refresh Events: %lld\n"
2751 "RPF Cache Refresh Last: %s\n"
2752 "Nexthop Lookups: %lld\n"
2753 "Nexthop Lookups Avoided: %lld\n",
2754 router
->rpf_cache_refresh_delay_msec
,
2755 pim_time_timer_remain_msec(pim
->rpf_cache_refresher
),
2756 (long long)pim
->rpf_cache_refresh_requests
,
2757 (long long)pim
->rpf_cache_refresh_events
,
2758 refresh_uptime
, (long long)pim
->nexthop_lookups
,
2759 (long long)pim
->nexthop_lookups_avoided
);
2763 static void show_scan_oil_stats(struct pim_instance
*pim
, struct vty
*vty
,
2766 char uptime_scan_oil
[10];
2767 char uptime_mroute_add
[10];
2768 char uptime_mroute_del
[10];
2770 pim_time_uptime_begin(uptime_scan_oil
, sizeof(uptime_scan_oil
), now
,
2771 pim
->scan_oil_last
);
2772 pim_time_uptime_begin(uptime_mroute_add
, sizeof(uptime_mroute_add
), now
,
2773 pim
->mroute_add_last
);
2774 pim_time_uptime_begin(uptime_mroute_del
, sizeof(uptime_mroute_del
), now
,
2775 pim
->mroute_del_last
);
2778 "Scan OIL - Last: %s Events: %lld\n"
2779 "MFC Add - Last: %s Events: %lld\n"
2780 "MFC Del - Last: %s Events: %lld\n",
2781 uptime_scan_oil
, (long long)pim
->scan_oil_events
,
2782 uptime_mroute_add
, (long long)pim
->mroute_add_events
,
2783 uptime_mroute_del
, (long long)pim
->mroute_del_events
);
2786 static void pim_show_rpf(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
2788 struct listnode
*up_node
;
2789 struct pim_upstream
*up
;
2790 time_t now
= pim_time_monotonic_sec();
2791 json_object
*json
= NULL
;
2792 json_object
*json_group
= NULL
;
2793 json_object
*json_row
= NULL
;
2796 json
= json_object_new_object();
2797 show_rpf_refresh_stats(vty
, pim
, now
, json
);
2799 show_rpf_refresh_stats(vty
, pim
, now
, json
);
2802 "Source Group RpfIface RpfAddress RibNextHop Metric Pref\n");
2805 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, up_node
, up
)) {
2806 char src_str
[INET_ADDRSTRLEN
];
2807 char grp_str
[INET_ADDRSTRLEN
];
2808 char rpf_addr_str
[PREFIX_STRLEN
];
2809 char rib_nexthop_str
[PREFIX_STRLEN
];
2810 const char *rpf_ifname
;
2811 struct pim_rpf
*rpf
= &up
->rpf
;
2813 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2814 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2815 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2816 sizeof(rpf_addr_str
));
2817 pim_addr_dump("<nexthop?>",
2818 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2819 rib_nexthop_str
, sizeof(rib_nexthop_str
));
2821 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2824 json_object_object_get_ex(json
, grp_str
, &json_group
);
2827 json_group
= json_object_new_object();
2828 json_object_object_add(json
, grp_str
,
2832 json_row
= json_object_new_object();
2833 json_object_string_add(json_row
, "source", src_str
);
2834 json_object_string_add(json_row
, "group", grp_str
);
2835 json_object_string_add(json_row
, "rpfInterface",
2837 json_object_string_add(json_row
, "rpfAddress",
2839 json_object_string_add(json_row
, "ribNexthop",
2841 json_object_int_add(
2842 json_row
, "routeMetric",
2843 rpf
->source_nexthop
.mrib_route_metric
);
2844 json_object_int_add(
2845 json_row
, "routePreference",
2846 rpf
->source_nexthop
.mrib_metric_preference
);
2847 json_object_object_add(json_group
, src_str
, json_row
);
2850 vty_out(vty
, "%-15s %-15s %-16s %-15s %-15s %6d %4d\n",
2851 src_str
, grp_str
, rpf_ifname
, rpf_addr_str
,
2853 rpf
->source_nexthop
.mrib_route_metric
,
2854 rpf
->source_nexthop
.mrib_metric_preference
);
2859 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2860 json
, JSON_C_TO_STRING_PRETTY
));
2861 json_object_free(json
);
2865 struct pnc_cache_walk_data
{
2867 struct pim_instance
*pim
;
2870 static int pim_print_pnc_cache_walkcb(struct hash_bucket
*bucket
, void *arg
)
2872 struct pim_nexthop_cache
*pnc
= bucket
->data
;
2873 struct pnc_cache_walk_data
*cwd
= arg
;
2874 struct vty
*vty
= cwd
->vty
;
2875 struct pim_instance
*pim
= cwd
->pim
;
2876 struct nexthop
*nh_node
= NULL
;
2877 ifindex_t first_ifindex
;
2878 struct interface
*ifp
= NULL
;
2880 for (nh_node
= pnc
->nexthop
; nh_node
; nh_node
= nh_node
->next
) {
2881 first_ifindex
= nh_node
->ifindex
;
2882 ifp
= if_lookup_by_index(first_ifindex
, pim
->vrf_id
);
2884 vty_out(vty
, "%-15s ", inet_ntoa(pnc
->rpf
.rpf_addr
.u
.prefix4
));
2885 vty_out(vty
, "%-16s ", ifp
? ifp
->name
: "NULL");
2886 vty_out(vty
, "%s ", inet_ntoa(nh_node
->gate
.ipv4
));
2892 static void pim_show_nexthop(struct pim_instance
*pim
, struct vty
*vty
)
2894 struct pnc_cache_walk_data cwd
;
2898 vty_out(vty
, "Number of registered addresses: %lu\n",
2899 pim
->rpf_hash
->count
);
2900 vty_out(vty
, "Address Interface Nexthop\n");
2901 vty_out(vty
, "---------------------------------------------\n");
2903 hash_walk(pim
->rpf_hash
, pim_print_pnc_cache_walkcb
, &cwd
);
2906 /* Display the bsm database details */
2907 static void pim_show_bsm_db(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
2909 struct listnode
*bsmnode
;
2912 struct bsm_info
*bsm
;
2913 json_object
*json
= NULL
;
2914 json_object
*json_group
= NULL
;
2915 json_object
*json_row
= NULL
;
2917 count
= pim
->global_scope
.bsm_list
->count
;
2920 json
= json_object_new_object();
2921 json_object_int_add(json
, "Number of the fragments", count
);
2923 vty_out(vty
, "Scope Zone: Global\n");
2924 vty_out(vty
, "Number of the fragments: %d\n", count
);
2928 for (ALL_LIST_ELEMENTS_RO(pim
->global_scope
.bsm_list
, bsmnode
, bsm
)) {
2929 char grp_str
[INET_ADDRSTRLEN
];
2930 char rp_str
[INET_ADDRSTRLEN
];
2931 char bsr_str
[INET_ADDRSTRLEN
];
2932 struct bsmmsg_grpinfo
*group
;
2933 struct bsmmsg_rpinfo
*rpaddr
;
2935 struct bsm_hdr
*hdr
;
2936 uint32_t offset
= 0;
2939 uint32_t frag_rp_cnt
= 0;
2944 /* skip pim header */
2945 buf
+= PIM_MSG_HEADER_LEN
;
2946 len
-= PIM_MSG_HEADER_LEN
;
2948 hdr
= (struct bsm_hdr
*)buf
;
2950 /* BSM starts with bsr header */
2951 buf
+= sizeof(struct bsm_hdr
);
2952 len
-= sizeof(struct bsm_hdr
);
2954 pim_inet4_dump("<BSR Address?>", hdr
->bsr_addr
.addr
, bsr_str
,
2959 json_object_string_add(json
, "BSR address", bsr_str
);
2960 json_object_int_add(json
, "BSR priority",
2962 json_object_int_add(json
, "Hashmask Length",
2964 json_object_int_add(json
, "Fragment Tag",
2965 ntohs(hdr
->frag_tag
));
2967 vty_out(vty
, "BSM Fragment : %d\n", fragment
);
2968 vty_out(vty
, "------------------\n");
2969 vty_out(vty
, "%-15s %-15s %-15s %-15s\n", "BSR-Address",
2970 "BSR-Priority", "Hashmask-len", "Fragment-Tag");
2971 vty_out(vty
, "%-15s %-15d %-15d %-15d\n", bsr_str
,
2972 hdr
->bsr_prio
, hdr
->hm_len
,
2973 ntohs(hdr
->frag_tag
));
2978 while (offset
< len
) {
2979 group
= (struct bsmmsg_grpinfo
*)buf
;
2981 if (group
->group
.family
== PIM_MSG_ADDRESS_FAMILY_IPV4
)
2982 grp
.family
= AF_INET
;
2984 grp
.prefixlen
= group
->group
.mask
;
2985 grp
.u
.prefix4
.s_addr
= group
->group
.addr
.s_addr
;
2987 prefix2str(&grp
, grp_str
, sizeof(grp_str
));
2989 buf
+= sizeof(struct bsmmsg_grpinfo
);
2990 offset
+= sizeof(struct bsmmsg_grpinfo
);
2993 json_object_object_get_ex(json
, grp_str
,
2996 json_group
= json_object_new_object();
2997 json_object_int_add(json_group
,
3000 json_object_int_add(
3001 json_group
, "Fragment Rp count",
3002 group
->frag_rp_count
);
3003 json_object_object_add(json
, grp_str
,
3007 vty_out(vty
, "Group : %s\n", grp_str
);
3008 vty_out(vty
, "-------------------\n");
3009 vty_out(vty
, "Rp Count:%d\n", group
->rp_count
);
3010 vty_out(vty
, "Fragment Rp Count : %d\n",
3011 group
->frag_rp_count
);
3014 frag_rp_cnt
= group
->frag_rp_count
;
3021 "RpAddress HoldTime Priority\n");
3023 while (frag_rp_cnt
--) {
3024 rpaddr
= (struct bsmmsg_rpinfo
*)buf
;
3026 buf
+= sizeof(struct bsmmsg_rpinfo
);
3027 offset
+= sizeof(struct bsmmsg_rpinfo
);
3029 pim_inet4_dump("<Rp addr?>",
3030 rpaddr
->rpaddr
.addr
, rp_str
,
3034 json_row
= json_object_new_object();
3035 json_object_string_add(
3036 json_row
, "Rp Address", rp_str
);
3037 json_object_int_add(
3038 json_row
, "Rp HoldTime",
3039 ntohs(rpaddr
->rp_holdtime
));
3040 json_object_int_add(json_row
,
3043 json_object_object_add(
3044 json_group
, rp_str
, json_row
);
3046 vty_out(vty
, "%-15s %-12d %d\n", rp_str
,
3047 ntohs(rpaddr
->rp_holdtime
),
3058 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3059 json
, JSON_C_TO_STRING_PRETTY
));
3060 json_object_free(json
);
3064 /*Display the group-rp mappings */
3065 static void pim_show_group_rp_mappings_info(struct pim_instance
*pim
,
3066 struct vty
*vty
, bool uj
)
3068 struct bsgrp_node
*bsgrp
;
3069 struct listnode
*rpnode
;
3070 struct bsm_rpinfo
*bsm_rp
;
3071 struct route_node
*rn
;
3072 char bsr_str
[INET_ADDRSTRLEN
];
3073 json_object
*json
= NULL
;
3074 json_object
*json_group
= NULL
;
3075 json_object
*json_row
= NULL
;
3077 if (pim
->global_scope
.current_bsr
.s_addr
== INADDR_ANY
)
3078 strlcpy(bsr_str
, "0.0.0.0", sizeof(bsr_str
));
3081 pim_inet4_dump("<bsr?>", pim
->global_scope
.current_bsr
, bsr_str
,
3085 json
= json_object_new_object();
3086 json_object_string_add(json
, "BSR Address", bsr_str
);
3088 vty_out(vty
, "BSR Address %s\n", bsr_str
);
3091 for (rn
= route_top(pim
->global_scope
.bsrp_table
); rn
;
3092 rn
= route_next(rn
)) {
3093 bsgrp
= (struct bsgrp_node
*)rn
->info
;
3098 char grp_str
[INET_ADDRSTRLEN
];
3100 prefix2str(&bsgrp
->group
, grp_str
, sizeof(grp_str
));
3103 json_object_object_get_ex(json
, grp_str
, &json_group
);
3105 json_group
= json_object_new_object();
3106 json_object_object_add(json
, grp_str
,
3110 vty_out(vty
, "Group Address %s\n", grp_str
);
3111 vty_out(vty
, "--------------------------\n");
3112 vty_out(vty
, "%-15s %-15s %-15s %-15s\n", "Rp Address",
3113 "priority", "Holdtime", "Hash");
3115 vty_out(vty
, "(ACTIVE)\n");
3118 if (bsgrp
->bsrp_list
) {
3119 for (ALL_LIST_ELEMENTS_RO(bsgrp
->bsrp_list
, rpnode
,
3121 char rp_str
[INET_ADDRSTRLEN
];
3123 pim_inet4_dump("<Rp Address?>",
3124 bsm_rp
->rp_address
, rp_str
,
3128 json_row
= json_object_new_object();
3129 json_object_string_add(
3130 json_row
, "Rp Address", rp_str
);
3131 json_object_int_add(
3132 json_row
, "Rp HoldTime",
3133 bsm_rp
->rp_holdtime
);
3134 json_object_int_add(json_row
,
3137 json_object_int_add(json_row
,
3140 json_object_object_add(
3141 json_group
, rp_str
, json_row
);
3145 "%-15s %-15u %-15u %-15u\n",
3146 rp_str
, bsm_rp
->rp_prio
,
3147 bsm_rp
->rp_holdtime
,
3151 if (!bsgrp
->bsrp_list
->count
&& !uj
)
3152 vty_out(vty
, "Active List is empty.\n");
3156 json_object_int_add(json_group
, "Pending RP count",
3157 bsgrp
->pend_rp_cnt
);
3159 vty_out(vty
, "(PENDING)\n");
3160 vty_out(vty
, "Pending RP count :%d\n",
3161 bsgrp
->pend_rp_cnt
);
3162 if (bsgrp
->pend_rp_cnt
)
3163 vty_out(vty
, "%-15s %-15s %-15s %-15s\n",
3164 "Rp Address", "priority", "Holdtime",
3168 if (bsgrp
->partial_bsrp_list
) {
3169 for (ALL_LIST_ELEMENTS_RO(bsgrp
->partial_bsrp_list
,
3171 char rp_str
[INET_ADDRSTRLEN
];
3173 pim_inet4_dump("<Rp Addr?>", bsm_rp
->rp_address
,
3174 rp_str
, sizeof(rp_str
));
3177 json_row
= json_object_new_object();
3178 json_object_string_add(
3179 json_row
, "Rp Address", rp_str
);
3180 json_object_int_add(
3181 json_row
, "Rp HoldTime",
3182 bsm_rp
->rp_holdtime
);
3183 json_object_int_add(json_row
,
3186 json_object_int_add(json_row
,
3189 json_object_object_add(
3190 json_group
, rp_str
, json_row
);
3193 "%-15s %-15u %-15u %-15u\n",
3194 rp_str
, bsm_rp
->rp_prio
,
3195 bsm_rp
->rp_holdtime
,
3199 if (!bsgrp
->partial_bsrp_list
->count
&& !uj
)
3200 vty_out(vty
, "Partial List is empty\n");
3208 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3209 json
, JSON_C_TO_STRING_PRETTY
));
3210 json_object_free(json
);
3214 /* pim statistics - just adding only bsm related now.
3215 * We can continue to add all pim related stats here.
3217 static void pim_show_statistics(struct pim_instance
*pim
, struct vty
*vty
,
3218 const char *ifname
, bool uj
)
3220 json_object
*json
= NULL
;
3221 struct interface
*ifp
;
3224 json
= json_object_new_object();
3225 json_object_int_add(json
, "Number of Received BSMs",
3227 json_object_int_add(json
, "Number of Forwared BSMs",
3229 json_object_int_add(json
, "Number of Dropped BSMs",
3232 vty_out(vty
, "BSM Statistics :\n");
3233 vty_out(vty
, "----------------\n");
3234 vty_out(vty
, "Number of Received BSMs : %" PRIu64
"\n",
3236 vty_out(vty
, "Number of Forwared BSMs : %" PRIu64
"\n",
3238 vty_out(vty
, "Number of Dropped BSMs : %" PRIu64
"\n",
3244 /* scan interfaces */
3245 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3246 struct pim_interface
*pim_ifp
= ifp
->info
;
3248 if (ifname
&& strcmp(ifname
, ifp
->name
))
3255 vty_out(vty
, "Interface : %s\n", ifp
->name
);
3256 vty_out(vty
, "-------------------\n");
3258 "Number of BSMs dropped due to config miss : %u\n",
3259 pim_ifp
->pim_ifstat_bsm_cfg_miss
);
3260 vty_out(vty
, "Number of unicast BSMs dropped : %u\n",
3261 pim_ifp
->pim_ifstat_ucast_bsm_cfg_miss
);
3263 "Number of BSMs dropped due to invalid scope zone : %u\n",
3264 pim_ifp
->pim_ifstat_bsm_invalid_sz
);
3267 json_object
*json_row
= NULL
;
3269 json_row
= json_object_new_object();
3271 json_object_string_add(json_row
, "If Name", ifp
->name
);
3272 json_object_int_add(
3274 "Number of BSMs dropped due to config miss",
3275 pim_ifp
->pim_ifstat_bsm_cfg_miss
);
3276 json_object_int_add(
3277 json_row
, "Number of unicast BSMs dropped",
3278 pim_ifp
->pim_ifstat_ucast_bsm_cfg_miss
);
3279 json_object_int_add(json_row
,
3280 "Number of BSMs dropped due to invalid scope zone",
3281 pim_ifp
->pim_ifstat_bsm_invalid_sz
);
3282 json_object_object_add(json
, ifp
->name
, json_row
);
3288 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3289 json
, JSON_C_TO_STRING_PRETTY
));
3290 json_object_free(json
);
3294 static void clear_pim_statistics(struct pim_instance
*pim
)
3296 struct interface
*ifp
;
3300 pim
->bsm_dropped
= 0;
3302 /* scan interfaces */
3303 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3304 struct pim_interface
*pim_ifp
= ifp
->info
;
3309 pim_ifp
->pim_ifstat_bsm_cfg_miss
= 0;
3310 pim_ifp
->pim_ifstat_ucast_bsm_cfg_miss
= 0;
3311 pim_ifp
->pim_ifstat_bsm_invalid_sz
= 0;
3315 static void igmp_show_groups(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
3317 struct interface
*ifp
;
3319 json_object
*json
= NULL
;
3320 json_object
*json_iface
= NULL
;
3321 json_object
*json_row
= NULL
;
3323 now
= pim_time_monotonic_sec();
3326 json
= json_object_new_object();
3329 "Interface Address Group Mode Timer Srcs V Uptime \n");
3331 /* scan interfaces */
3332 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3333 struct pim_interface
*pim_ifp
= ifp
->info
;
3334 struct listnode
*sock_node
;
3335 struct igmp_sock
*igmp
;
3340 /* scan igmp sockets */
3341 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3343 char ifaddr_str
[INET_ADDRSTRLEN
];
3344 struct listnode
*grpnode
;
3345 struct igmp_group
*grp
;
3347 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3348 sizeof(ifaddr_str
));
3350 /* scan igmp groups */
3351 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3353 char group_str
[INET_ADDRSTRLEN
];
3357 pim_inet4_dump("<group?>", grp
->group_addr
,
3358 group_str
, sizeof(group_str
));
3359 pim_time_timer_to_hhmmss(hhmmss
, sizeof(hhmmss
),
3360 grp
->t_group_timer
);
3361 pim_time_uptime(uptime
, sizeof(uptime
),
3362 now
- grp
->group_creation
);
3365 json_object_object_get_ex(
3366 json
, ifp
->name
, &json_iface
);
3370 json_object_new_object();
3371 json_object_pim_ifp_add(
3373 json_object_object_add(
3378 json_row
= json_object_new_object();
3379 json_object_string_add(
3380 json_row
, "source", ifaddr_str
);
3381 json_object_string_add(
3382 json_row
, "group", group_str
);
3384 if (grp
->igmp_version
== 3)
3385 json_object_string_add(
3387 grp
->group_filtermode_isexcl
3391 json_object_string_add(json_row
,
3393 json_object_int_add(
3394 json_row
, "sourcesCount",
3395 grp
->group_source_list
3397 grp
->group_source_list
)
3399 json_object_int_add(json_row
, "version",
3401 json_object_string_add(
3402 json_row
, "uptime", uptime
);
3403 json_object_object_add(json_iface
,
3409 "%-16s %-15s %-15s %4s %8s %4d %d %8s\n",
3410 ifp
->name
, ifaddr_str
,
3412 grp
->igmp_version
== 3
3413 ? (grp
->group_filtermode_isexcl
3418 grp
->group_source_list
3420 grp
->group_source_list
)
3422 grp
->igmp_version
, uptime
);
3424 } /* scan igmp groups */
3425 } /* scan igmp sockets */
3426 } /* scan interfaces */
3429 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3430 json
, JSON_C_TO_STRING_PRETTY
));
3431 json_object_free(json
);
3435 static void igmp_show_group_retransmission(struct pim_instance
*pim
,
3438 struct interface
*ifp
;
3441 "Interface Address Group RetTimer Counter RetSrcs\n");
3443 /* scan interfaces */
3444 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3445 struct pim_interface
*pim_ifp
= ifp
->info
;
3446 struct listnode
*sock_node
;
3447 struct igmp_sock
*igmp
;
3452 /* scan igmp sockets */
3453 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3455 char ifaddr_str
[INET_ADDRSTRLEN
];
3456 struct listnode
*grpnode
;
3457 struct igmp_group
*grp
;
3459 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3460 sizeof(ifaddr_str
));
3462 /* scan igmp groups */
3463 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3465 char group_str
[INET_ADDRSTRLEN
];
3466 char grp_retr_mmss
[10];
3467 struct listnode
*src_node
;
3468 struct igmp_source
*src
;
3469 int grp_retr_sources
= 0;
3471 pim_inet4_dump("<group?>", grp
->group_addr
,
3472 group_str
, sizeof(group_str
));
3473 pim_time_timer_to_mmss(
3474 grp_retr_mmss
, sizeof(grp_retr_mmss
),
3475 grp
->t_group_query_retransmit_timer
);
3478 /* count group sources with retransmission state
3480 for (ALL_LIST_ELEMENTS_RO(
3481 grp
->group_source_list
, src_node
,
3483 if (src
->source_query_retransmit_count
3489 vty_out(vty
, "%-16s %-15s %-15s %-8s %7d %7d\n",
3490 ifp
->name
, ifaddr_str
, group_str
,
3492 grp
->group_specific_query_retransmit_count
,
3495 } /* scan igmp groups */
3496 } /* scan igmp sockets */
3497 } /* scan interfaces */
3500 static void igmp_show_sources(struct pim_instance
*pim
, struct vty
*vty
)
3502 struct interface
*ifp
;
3505 now
= pim_time_monotonic_sec();
3508 "Interface Address Group Source Timer Fwd Uptime \n");
3510 /* scan interfaces */
3511 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3512 struct pim_interface
*pim_ifp
= ifp
->info
;
3513 struct listnode
*sock_node
;
3514 struct igmp_sock
*igmp
;
3519 /* scan igmp sockets */
3520 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3522 char ifaddr_str
[INET_ADDRSTRLEN
];
3523 struct listnode
*grpnode
;
3524 struct igmp_group
*grp
;
3526 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3527 sizeof(ifaddr_str
));
3529 /* scan igmp groups */
3530 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3532 char group_str
[INET_ADDRSTRLEN
];
3533 struct listnode
*srcnode
;
3534 struct igmp_source
*src
;
3536 pim_inet4_dump("<group?>", grp
->group_addr
,
3537 group_str
, sizeof(group_str
));
3539 /* scan group sources */
3540 for (ALL_LIST_ELEMENTS_RO(
3541 grp
->group_source_list
, srcnode
,
3543 char source_str
[INET_ADDRSTRLEN
];
3548 "<source?>", src
->source_addr
,
3549 source_str
, sizeof(source_str
));
3551 pim_time_timer_to_mmss(
3553 src
->t_source_timer
);
3556 uptime
, sizeof(uptime
),
3557 now
- src
->source_creation
);
3560 "%-16s %-15s %-15s %-15s %5s %3s %8s\n",
3561 ifp
->name
, ifaddr_str
,
3562 group_str
, source_str
, mmss
,
3563 IGMP_SOURCE_TEST_FORWARDING(
3569 } /* scan group sources */
3570 } /* scan igmp groups */
3571 } /* scan igmp sockets */
3572 } /* scan interfaces */
3575 static void igmp_show_source_retransmission(struct pim_instance
*pim
,
3578 struct interface
*ifp
;
3581 "Interface Address Group Source Counter\n");
3583 /* scan interfaces */
3584 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3585 struct pim_interface
*pim_ifp
= ifp
->info
;
3586 struct listnode
*sock_node
;
3587 struct igmp_sock
*igmp
;
3592 /* scan igmp sockets */
3593 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3595 char ifaddr_str
[INET_ADDRSTRLEN
];
3596 struct listnode
*grpnode
;
3597 struct igmp_group
*grp
;
3599 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3600 sizeof(ifaddr_str
));
3602 /* scan igmp groups */
3603 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3605 char group_str
[INET_ADDRSTRLEN
];
3606 struct listnode
*srcnode
;
3607 struct igmp_source
*src
;
3609 pim_inet4_dump("<group?>", grp
->group_addr
,
3610 group_str
, sizeof(group_str
));
3612 /* scan group sources */
3613 for (ALL_LIST_ELEMENTS_RO(
3614 grp
->group_source_list
, srcnode
,
3616 char source_str
[INET_ADDRSTRLEN
];
3619 "<source?>", src
->source_addr
,
3620 source_str
, sizeof(source_str
));
3623 "%-16s %-15s %-15s %-15s %7d\n",
3624 ifp
->name
, ifaddr_str
,
3625 group_str
, source_str
,
3626 src
->source_query_retransmit_count
);
3628 } /* scan group sources */
3629 } /* scan igmp groups */
3630 } /* scan igmp sockets */
3631 } /* scan interfaces */
3634 static void pim_show_bsr(struct pim_instance
*pim
,
3639 char last_bsm_seen
[10];
3642 char bsr_str
[PREFIX_STRLEN
];
3643 json_object
*json
= NULL
;
3645 vty_out(vty
, "PIMv2 Bootstrap information\n");
3647 if (pim
->global_scope
.current_bsr
.s_addr
== INADDR_ANY
) {
3648 strlcpy(bsr_str
, "0.0.0.0", sizeof(bsr_str
));
3649 pim_time_uptime(uptime
, sizeof(uptime
),
3650 pim
->global_scope
.current_bsr_first_ts
);
3651 pim_time_uptime(last_bsm_seen
, sizeof(last_bsm_seen
),
3652 pim
->global_scope
.current_bsr_last_ts
);
3656 pim_inet4_dump("<bsr?>", pim
->global_scope
.current_bsr
,
3657 bsr_str
, sizeof(bsr_str
));
3658 now
= pim_time_monotonic_sec();
3659 pim_time_uptime(uptime
, sizeof(uptime
),
3660 (now
- pim
->global_scope
.current_bsr_first_ts
));
3661 pim_time_uptime(last_bsm_seen
, sizeof(last_bsm_seen
),
3662 now
- pim
->global_scope
.current_bsr_last_ts
);
3665 switch (pim
->global_scope
.state
) {
3667 strlcpy(bsr_state
, "NO_INFO", sizeof(bsr_state
));
3670 strlcpy(bsr_state
, "ACCEPT_ANY", sizeof(bsr_state
));
3672 case ACCEPT_PREFERRED
:
3673 strlcpy(bsr_state
, "ACCEPT_PREFERRED", sizeof(bsr_state
));
3676 strlcpy(bsr_state
, "", sizeof(bsr_state
));
3680 json
= json_object_new_object();
3681 json_object_string_add(json
, "bsr", bsr_str
);
3682 json_object_int_add(json
, "priority",
3683 pim
->global_scope
.current_bsr_prio
);
3684 json_object_int_add(json
, "fragment_tag",
3685 pim
->global_scope
.bsm_frag_tag
);
3686 json_object_string_add(json
, "state", bsr_state
);
3687 json_object_string_add(json
, "upTime", uptime
);
3688 json_object_string_add(json
, "last_bsm_seen", last_bsm_seen
);
3692 vty_out(vty
, "Current preferred BSR address: %s\n", bsr_str
);
3694 "Priority Fragment-Tag State UpTime\n");
3695 vty_out(vty
, " %-12d %-12d %-13s %7s\n",
3696 pim
->global_scope
.current_bsr_prio
,
3697 pim
->global_scope
.bsm_frag_tag
,
3700 vty_out(vty
, "Last BSM seen: %s\n", last_bsm_seen
);
3704 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3705 json
, JSON_C_TO_STRING_PRETTY
));
3706 json_object_free(json
);
3710 static void clear_igmp_interfaces(struct pim_instance
*pim
)
3712 struct interface
*ifp
;
3714 FOR_ALL_INTERFACES (pim
->vrf
, ifp
)
3715 pim_if_addr_del_all_igmp(ifp
);
3717 FOR_ALL_INTERFACES (pim
->vrf
, ifp
)
3718 pim_if_addr_add_all(ifp
);
3721 static void clear_pim_interfaces(struct pim_instance
*pim
)
3723 struct interface
*ifp
;
3725 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3727 pim_neighbor_delete_all(ifp
, "interface cleared");
3732 static void clear_interfaces(struct pim_instance
*pim
)
3734 clear_igmp_interfaces(pim
);
3735 clear_pim_interfaces(pim
);
3738 #define PIM_GET_PIM_INTERFACE(pim_ifp, ifp) \
3739 pim_ifp = ifp->info; \
3742 "%% Enable PIM and/or IGMP on this interface first\n"); \
3743 return CMD_WARNING_CONFIG_FAILED; \
3746 DEFUN (clear_ip_interfaces
,
3747 clear_ip_interfaces_cmd
,
3748 "clear ip interfaces [vrf NAME]",
3751 "Reset interfaces\n"
3755 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3760 clear_interfaces(vrf
->info
);
3765 DEFUN (clear_ip_igmp_interfaces
,
3766 clear_ip_igmp_interfaces_cmd
,
3767 "clear ip igmp [vrf NAME] interfaces",
3772 "Reset IGMP interfaces\n")
3775 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3780 clear_igmp_interfaces(vrf
->info
);
3785 DEFUN (clear_ip_pim_statistics
,
3786 clear_ip_pim_statistics_cmd
,
3787 "clear ip pim statistics [vrf NAME]",
3792 "Reset PIM statistics\n")
3795 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3800 clear_pim_statistics(vrf
->info
);
3804 static void clear_mroute(struct pim_instance
*pim
)
3806 struct pim_upstream
*up
;
3807 struct interface
*ifp
;
3809 /* scan interfaces */
3810 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3811 struct pim_interface
*pim_ifp
= ifp
->info
;
3812 struct listnode
*sock_node
;
3813 struct igmp_sock
*igmp
;
3814 struct pim_ifchannel
*ch
;
3819 /* deleting all ifchannels */
3820 while (!RB_EMPTY(pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
)) {
3821 ch
= RB_ROOT(pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
);
3823 pim_ifchannel_delete(ch
);
3826 /* clean up all igmp groups */
3827 /* scan igmp sockets */
3828 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3831 struct igmp_group
*grp
;
3833 if (igmp
->igmp_group_list
) {
3834 while (igmp
->igmp_group_list
->count
) {
3835 grp
= listnode_head(
3836 igmp
->igmp_group_list
);
3837 igmp_group_delete(grp
);
3844 /* clean up all upstreams*/
3845 if (pim
->upstream_list
) {
3846 while (pim
->upstream_list
->count
) {
3847 up
= listnode_head(pim
->upstream_list
);
3848 pim_upstream_del(pim
, up
, __PRETTY_FUNCTION__
);
3853 DEFUN (clear_ip_mroute
,
3854 clear_ip_mroute_cmd
,
3855 "clear ip mroute [vrf NAME]",
3858 "Reset multicast routes\n"
3862 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3867 clear_mroute(vrf
->info
);
3872 DEFUN (clear_ip_pim_interfaces
,
3873 clear_ip_pim_interfaces_cmd
,
3874 "clear ip pim [vrf NAME] interfaces",
3879 "Reset PIM interfaces\n")
3882 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3887 clear_pim_interfaces(vrf
->info
);
3892 DEFUN (clear_ip_pim_interface_traffic
,
3893 clear_ip_pim_interface_traffic_cmd
,
3894 "clear ip pim [vrf NAME] interface traffic",
3897 "PIM clear commands\n"
3899 "Reset PIM interfaces\n"
3900 "Reset Protocol Packet counters\n")
3903 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3904 struct interface
*ifp
= NULL
;
3905 struct pim_interface
*pim_ifp
= NULL
;
3910 FOR_ALL_INTERFACES (vrf
, ifp
) {
3911 pim_ifp
= ifp
->info
;
3916 pim_ifp
->pim_ifstat_hello_recv
= 0;
3917 pim_ifp
->pim_ifstat_hello_sent
= 0;
3918 pim_ifp
->pim_ifstat_join_recv
= 0;
3919 pim_ifp
->pim_ifstat_join_send
= 0;
3920 pim_ifp
->pim_ifstat_prune_recv
= 0;
3921 pim_ifp
->pim_ifstat_prune_send
= 0;
3922 pim_ifp
->pim_ifstat_reg_recv
= 0;
3923 pim_ifp
->pim_ifstat_reg_send
= 0;
3924 pim_ifp
->pim_ifstat_reg_stop_recv
= 0;
3925 pim_ifp
->pim_ifstat_reg_stop_send
= 0;
3926 pim_ifp
->pim_ifstat_assert_recv
= 0;
3927 pim_ifp
->pim_ifstat_assert_send
= 0;
3928 pim_ifp
->pim_ifstat_bsm_rx
= 0;
3929 pim_ifp
->pim_ifstat_bsm_tx
= 0;
3935 DEFUN (clear_ip_pim_oil
,
3936 clear_ip_pim_oil_cmd
,
3937 "clear ip pim [vrf NAME] oil",
3942 "Rescan PIM OIL (output interface list)\n")
3945 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3950 pim_scan_oil(vrf
->info
);
3955 DEFUN (show_ip_igmp_interface
,
3956 show_ip_igmp_interface_cmd
,
3957 "show ip igmp [vrf NAME] interface [detail|WORD] [json]",
3962 "IGMP interface information\n"
3968 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3969 bool uj
= use_json(argc
, argv
);
3974 if (argv_find(argv
, argc
, "detail", &idx
)
3975 || argv_find(argv
, argc
, "WORD", &idx
))
3976 igmp_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
3978 igmp_show_interfaces(vrf
->info
, vty
, uj
);
3983 DEFUN (show_ip_igmp_interface_vrf_all
,
3984 show_ip_igmp_interface_vrf_all_cmd
,
3985 "show ip igmp vrf all interface [detail|WORD] [json]",
3990 "IGMP interface information\n"
3996 bool uj
= use_json(argc
, argv
);
4002 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4006 vty_out(vty
, " \"%s\": ", vrf
->name
);
4009 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4010 if (argv_find(argv
, argc
, "detail", &idx
)
4011 || argv_find(argv
, argc
, "WORD", &idx
))
4012 igmp_show_interfaces_single(vrf
->info
, vty
,
4013 argv
[idx
]->arg
, uj
);
4015 igmp_show_interfaces(vrf
->info
, vty
, uj
);
4018 vty_out(vty
, "}\n");
4023 DEFUN (show_ip_igmp_join
,
4024 show_ip_igmp_join_cmd
,
4025 "show ip igmp [vrf NAME] join",
4030 "IGMP static join information\n")
4033 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4038 igmp_show_interface_join(vrf
->info
, vty
);
4043 DEFUN (show_ip_igmp_join_vrf_all
,
4044 show_ip_igmp_join_vrf_all_cmd
,
4045 "show ip igmp vrf all join",
4050 "IGMP static join information\n")
4052 bool uj
= use_json(argc
, argv
);
4058 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4062 vty_out(vty
, " \"%s\": ", vrf
->name
);
4065 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4066 igmp_show_interface_join(vrf
->info
, vty
);
4069 vty_out(vty
, "}\n");
4074 DEFUN (show_ip_igmp_groups
,
4075 show_ip_igmp_groups_cmd
,
4076 "show ip igmp [vrf NAME] groups [json]",
4085 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4086 bool uj
= use_json(argc
, argv
);
4091 igmp_show_groups(vrf
->info
, vty
, uj
);
4096 DEFUN (show_ip_igmp_groups_vrf_all
,
4097 show_ip_igmp_groups_vrf_all_cmd
,
4098 "show ip igmp vrf all groups [json]",
4106 bool uj
= use_json(argc
, argv
);
4112 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4116 vty_out(vty
, " \"%s\": ", vrf
->name
);
4119 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4120 igmp_show_groups(vrf
->info
, vty
, uj
);
4123 vty_out(vty
, "}\n");
4128 DEFUN (show_ip_igmp_groups_retransmissions
,
4129 show_ip_igmp_groups_retransmissions_cmd
,
4130 "show ip igmp [vrf NAME] groups retransmissions",
4136 "IGMP group retransmissions\n")
4139 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4144 igmp_show_group_retransmission(vrf
->info
, vty
);
4149 DEFUN (show_ip_igmp_sources
,
4150 show_ip_igmp_sources_cmd
,
4151 "show ip igmp [vrf NAME] sources",
4159 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4164 igmp_show_sources(vrf
->info
, vty
);
4169 DEFUN (show_ip_igmp_sources_retransmissions
,
4170 show_ip_igmp_sources_retransmissions_cmd
,
4171 "show ip igmp [vrf NAME] sources retransmissions",
4177 "IGMP source retransmissions\n")
4180 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4185 igmp_show_source_retransmission(vrf
->info
, vty
);
4190 DEFUN (show_ip_igmp_statistics
,
4191 show_ip_igmp_statistics_cmd
,
4192 "show ip igmp [vrf NAME] statistics [interface WORD] [json]",
4203 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4204 bool uj
= use_json(argc
, argv
);
4209 if (argv_find(argv
, argc
, "WORD", &idx
))
4210 igmp_show_statistics(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
4212 igmp_show_statistics(vrf
->info
, vty
, NULL
, uj
);
4217 DEFUN (show_ip_pim_assert
,
4218 show_ip_pim_assert_cmd
,
4219 "show ip pim [vrf NAME] assert",
4224 "PIM interface assert\n")
4227 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4232 pim_show_assert(vrf
->info
, vty
);
4237 DEFUN (show_ip_pim_assert_internal
,
4238 show_ip_pim_assert_internal_cmd
,
4239 "show ip pim [vrf NAME] assert-internal",
4244 "PIM interface internal assert state\n")
4247 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4252 pim_show_assert_internal(vrf
->info
, vty
);
4257 DEFUN (show_ip_pim_assert_metric
,
4258 show_ip_pim_assert_metric_cmd
,
4259 "show ip pim [vrf NAME] assert-metric",
4264 "PIM interface assert metric\n")
4267 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4272 pim_show_assert_metric(vrf
->info
, vty
);
4277 DEFUN (show_ip_pim_assert_winner_metric
,
4278 show_ip_pim_assert_winner_metric_cmd
,
4279 "show ip pim [vrf NAME] assert-winner-metric",
4284 "PIM interface assert winner metric\n")
4287 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4292 pim_show_assert_winner_metric(vrf
->info
, vty
);
4297 DEFUN (show_ip_pim_interface
,
4298 show_ip_pim_interface_cmd
,
4299 "show ip pim [vrf NAME] interface [detail|WORD] [json]",
4304 "PIM interface information\n"
4310 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4311 bool uj
= use_json(argc
, argv
);
4316 if (argv_find(argv
, argc
, "WORD", &idx
)
4317 || argv_find(argv
, argc
, "detail", &idx
))
4318 pim_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
4320 pim_show_interfaces(vrf
->info
, vty
, uj
);
4325 DEFUN (show_ip_pim_interface_vrf_all
,
4326 show_ip_pim_interface_vrf_all_cmd
,
4327 "show ip pim vrf all interface [detail|WORD] [json]",
4332 "PIM interface information\n"
4338 bool uj
= use_json(argc
, argv
);
4344 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4348 vty_out(vty
, " \"%s\": ", vrf
->name
);
4351 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4352 if (argv_find(argv
, argc
, "WORD", &idx
)
4353 || argv_find(argv
, argc
, "detail", &idx
))
4354 pim_show_interfaces_single(vrf
->info
, vty
,
4355 argv
[idx
]->arg
, uj
);
4357 pim_show_interfaces(vrf
->info
, vty
, uj
);
4360 vty_out(vty
, "}\n");
4365 DEFPY (show_ip_pim_join
,
4366 show_ip_pim_join_cmd
,
4367 "show ip pim [vrf NAME] join [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
4372 "PIM interface join information\n"
4373 "The Source or Group\n"
4377 struct prefix_sg sg
= {0};
4380 struct pim_instance
*pim
;
4382 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
4385 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
4388 pim
= pim_get_pim_instance(v
->vrf_id
);
4391 vty_out(vty
, "%% Unable to find pim instance\n");
4395 if (s_or_g
.s_addr
!= 0) {
4396 if (g
.s_addr
!= 0) {
4403 pim_show_join(pim
, vty
, &sg
, uj
);
4408 DEFUN (show_ip_pim_join_vrf_all
,
4409 show_ip_pim_join_vrf_all_cmd
,
4410 "show ip pim vrf all join [json]",
4415 "PIM interface join information\n"
4418 struct prefix_sg sg
= {0};
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 pim_show_join(vrf
->info
, vty
, &sg
, uj
);
4436 vty_out(vty
, "}\n");
4441 DEFUN (show_ip_pim_local_membership
,
4442 show_ip_pim_local_membership_cmd
,
4443 "show ip pim [vrf NAME] local-membership [json]",
4448 "PIM interface local-membership\n"
4452 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4453 bool uj
= use_json(argc
, argv
);
4458 pim_show_membership(vrf
->info
, vty
, uj
);
4463 DEFUN (show_ip_pim_neighbor
,
4464 show_ip_pim_neighbor_cmd
,
4465 "show ip pim [vrf NAME] neighbor [detail|WORD] [json]",
4470 "PIM neighbor information\n"
4472 "Name of interface or neighbor\n"
4476 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4477 bool uj
= use_json(argc
, argv
);
4482 if (argv_find(argv
, argc
, "detail", &idx
)
4483 || argv_find(argv
, argc
, "WORD", &idx
))
4484 pim_show_neighbors_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
4486 pim_show_neighbors(vrf
->info
, vty
, uj
);
4491 DEFUN (show_ip_pim_neighbor_vrf_all
,
4492 show_ip_pim_neighbor_vrf_all_cmd
,
4493 "show ip pim vrf all neighbor [detail|WORD] [json]",
4498 "PIM neighbor information\n"
4500 "Name of interface or neighbor\n"
4504 bool uj
= use_json(argc
, argv
);
4510 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4514 vty_out(vty
, " \"%s\": ", vrf
->name
);
4517 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4518 if (argv_find(argv
, argc
, "detail", &idx
)
4519 || argv_find(argv
, argc
, "WORD", &idx
))
4520 pim_show_neighbors_single(vrf
->info
, vty
,
4521 argv
[idx
]->arg
, uj
);
4523 pim_show_neighbors(vrf
->info
, vty
, uj
);
4526 vty_out(vty
, "}\n");
4531 DEFUN (show_ip_pim_secondary
,
4532 show_ip_pim_secondary_cmd
,
4533 "show ip pim [vrf NAME] secondary",
4538 "PIM neighbor addresses\n")
4541 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4546 pim_show_neighbors_secondary(vrf
->info
, vty
);
4551 DEFUN (show_ip_pim_state
,
4552 show_ip_pim_state_cmd
,
4553 "show ip pim [vrf NAME] state [A.B.C.D [A.B.C.D]] [json]",
4558 "PIM state information\n"
4559 "Unicast or Multicast address\n"
4560 "Multicast address\n"
4563 const char *src_or_group
= NULL
;
4564 const char *group
= NULL
;
4566 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4567 bool uj
= use_json(argc
, argv
);
4575 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
4576 src_or_group
= argv
[idx
]->arg
;
4578 group
= argv
[idx
+ 1]->arg
;
4581 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
4586 DEFUN (show_ip_pim_state_vrf_all
,
4587 show_ip_pim_state_vrf_all_cmd
,
4588 "show ip pim vrf all state [A.B.C.D [A.B.C.D]] [json]",
4593 "PIM state information\n"
4594 "Unicast or Multicast address\n"
4595 "Multicast address\n"
4598 const char *src_or_group
= NULL
;
4599 const char *group
= NULL
;
4601 bool uj
= use_json(argc
, argv
);
4610 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
4611 src_or_group
= argv
[idx
]->arg
;
4613 group
= argv
[idx
+ 1]->arg
;
4616 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4620 vty_out(vty
, " \"%s\": ", vrf
->name
);
4623 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4624 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
4627 vty_out(vty
, "}\n");
4632 DEFPY (show_ip_pim_upstream
,
4633 show_ip_pim_upstream_cmd
,
4634 "show ip pim [vrf NAME] upstream [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
4639 "PIM upstream information\n"
4640 "The Source or Group\n"
4644 struct prefix_sg sg
= {0};
4647 struct pim_instance
*pim
;
4649 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
4652 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
4655 pim
= pim_get_pim_instance(v
->vrf_id
);
4658 vty_out(vty
, "%% Unable to find pim instance\n");
4662 if (s_or_g
.s_addr
!= 0) {
4663 if (g
.s_addr
!= 0) {
4669 pim_show_upstream(pim
, vty
, &sg
, uj
);
4674 DEFUN (show_ip_pim_upstream_vrf_all
,
4675 show_ip_pim_upstream_vrf_all_cmd
,
4676 "show ip pim vrf all upstream [json]",
4681 "PIM upstream information\n"
4684 struct prefix_sg sg
= {0};
4685 bool uj
= use_json(argc
, argv
);
4691 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4695 vty_out(vty
, " \"%s\": ", vrf
->name
);
4698 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4699 pim_show_upstream(vrf
->info
, vty
, &sg
, uj
);
4705 DEFUN (show_ip_pim_upstream_join_desired
,
4706 show_ip_pim_upstream_join_desired_cmd
,
4707 "show ip pim [vrf NAME] upstream-join-desired [json]",
4712 "PIM upstream join-desired\n"
4716 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4717 bool uj
= use_json(argc
, argv
);
4722 pim_show_join_desired(vrf
->info
, vty
, uj
);
4727 DEFUN (show_ip_pim_upstream_rpf
,
4728 show_ip_pim_upstream_rpf_cmd
,
4729 "show ip pim [vrf NAME] upstream-rpf [json]",
4734 "PIM upstream source rpf\n"
4738 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4739 bool uj
= use_json(argc
, argv
);
4744 pim_show_upstream_rpf(vrf
->info
, vty
, uj
);
4749 DEFUN (show_ip_pim_rp
,
4751 "show ip pim [vrf NAME] rp-info [json]",
4756 "PIM RP information\n"
4760 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4761 bool uj
= use_json(argc
, argv
);
4766 pim_rp_show_information(vrf
->info
, vty
, uj
);
4771 DEFUN (show_ip_pim_rp_vrf_all
,
4772 show_ip_pim_rp_vrf_all_cmd
,
4773 "show ip pim vrf all rp-info [json]",
4778 "PIM RP information\n"
4781 bool uj
= use_json(argc
, argv
);
4787 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4791 vty_out(vty
, " \"%s\": ", vrf
->name
);
4794 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4795 pim_rp_show_information(vrf
->info
, vty
, uj
);
4798 vty_out(vty
, "}\n");
4803 DEFUN (show_ip_pim_rpf
,
4804 show_ip_pim_rpf_cmd
,
4805 "show ip pim [vrf NAME] rpf [json]",
4810 "PIM cached source rpf information\n"
4814 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4815 bool uj
= use_json(argc
, argv
);
4820 pim_show_rpf(vrf
->info
, vty
, uj
);
4825 DEFUN (show_ip_pim_rpf_vrf_all
,
4826 show_ip_pim_rpf_vrf_all_cmd
,
4827 "show ip pim vrf all rpf [json]",
4832 "PIM cached source rpf information\n"
4835 bool uj
= use_json(argc
, argv
);
4841 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4845 vty_out(vty
, " \"%s\": ", vrf
->name
);
4848 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4849 pim_show_rpf(vrf
->info
, vty
, uj
);
4852 vty_out(vty
, "}\n");
4857 DEFUN (show_ip_pim_nexthop
,
4858 show_ip_pim_nexthop_cmd
,
4859 "show ip pim [vrf NAME] nexthop",
4864 "PIM cached nexthop rpf information\n")
4867 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4872 pim_show_nexthop(vrf
->info
, vty
);
4877 DEFUN (show_ip_pim_nexthop_lookup
,
4878 show_ip_pim_nexthop_lookup_cmd
,
4879 "show ip pim [vrf NAME] nexthop-lookup A.B.C.D A.B.C.D",
4884 "PIM cached nexthop rpf lookup\n"
4885 "Source/RP address\n"
4886 "Multicast Group address\n")
4888 struct prefix nht_p
;
4890 struct in_addr src_addr
, grp_addr
;
4891 struct in_addr vif_source
;
4892 const char *addr_str
, *addr_str1
;
4894 struct pim_nexthop nexthop
;
4895 char nexthop_addr_str
[PREFIX_STRLEN
];
4896 char grp_str
[PREFIX_STRLEN
];
4898 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4903 argv_find(argv
, argc
, "A.B.C.D", &idx
);
4904 addr_str
= argv
[idx
]->arg
;
4905 result
= inet_pton(AF_INET
, addr_str
, &src_addr
);
4907 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
4908 errno
, safe_strerror(errno
));
4912 if (pim_is_group_224_4(src_addr
)) {
4914 "Invalid argument. Expected Valid Source Address.\n");
4918 addr_str1
= argv
[idx
+ 1]->arg
;
4919 result
= inet_pton(AF_INET
, addr_str1
, &grp_addr
);
4921 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
4922 errno
, safe_strerror(errno
));
4926 if (!pim_is_group_224_4(grp_addr
)) {
4928 "Invalid argument. Expected Valid Multicast Group Address.\n");
4932 if (!pim_rp_set_upstream_addr(vrf
->info
, &vif_source
, src_addr
,
4936 nht_p
.family
= AF_INET
;
4937 nht_p
.prefixlen
= IPV4_MAX_BITLEN
;
4938 nht_p
.u
.prefix4
= vif_source
;
4939 grp
.family
= AF_INET
;
4940 grp
.prefixlen
= IPV4_MAX_BITLEN
;
4941 grp
.u
.prefix4
= grp_addr
;
4942 memset(&nexthop
, 0, sizeof(nexthop
));
4944 result
= pim_ecmp_nexthop_lookup(vrf
->info
, &nexthop
, &nht_p
, &grp
, 0);
4948 "Nexthop Lookup failed, no usable routes returned.\n");
4952 pim_addr_dump("<grp?>", &grp
, grp_str
, sizeof(grp_str
));
4953 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
4954 nexthop_addr_str
, sizeof(nexthop_addr_str
));
4955 vty_out(vty
, "Group %s --- Nexthop %s Interface %s \n", grp_str
,
4956 nexthop_addr_str
, nexthop
.interface
->name
);
4961 DEFUN (show_ip_pim_interface_traffic
,
4962 show_ip_pim_interface_traffic_cmd
,
4963 "show ip pim [vrf NAME] interface traffic [WORD] [json]",
4968 "PIM interface information\n"
4969 "Protocol Packet counters\n"
4974 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4975 bool uj
= use_json(argc
, argv
);
4980 if (argv_find(argv
, argc
, "WORD", &idx
))
4981 pim_show_interface_traffic_single(vrf
->info
, vty
,
4982 argv
[idx
]->arg
, uj
);
4984 pim_show_interface_traffic(vrf
->info
, vty
, uj
);
4989 DEFUN (show_ip_pim_bsm_db
,
4990 show_ip_pim_bsm_db_cmd
,
4991 "show ip pim bsm-database [vrf NAME] [json]",
4995 "PIM cached bsm packets information\n"
5000 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5001 bool uj
= use_json(argc
, argv
);
5006 pim_show_bsm_db(vrf
->info
, vty
, uj
);
5010 DEFUN (show_ip_pim_bsrp
,
5011 show_ip_pim_bsrp_cmd
,
5012 "show ip pim bsrp-info [vrf NAME] [json]",
5016 "PIM cached group-rp mappings information\n"
5021 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5022 bool uj
= use_json(argc
, argv
);
5027 pim_show_group_rp_mappings_info(vrf
->info
, vty
, uj
);
5032 DEFUN (show_ip_pim_statistics
,
5033 show_ip_pim_statistics_cmd
,
5034 "show ip pim [vrf NAME] statistics [interface WORD] [json]",
5045 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5046 bool uj
= use_json(argc
, argv
);
5051 if (argv_find(argv
, argc
, "WORD", &idx
))
5052 pim_show_statistics(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
5054 pim_show_statistics(vrf
->info
, vty
, NULL
, uj
);
5059 static void show_multicast_interfaces(struct pim_instance
*pim
, struct vty
*vty
)
5061 struct interface
*ifp
;
5066 "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut\n");
5068 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
5069 struct pim_interface
*pim_ifp
;
5070 struct in_addr ifaddr
;
5071 struct sioc_vif_req vreq
;
5073 pim_ifp
= ifp
->info
;
5078 memset(&vreq
, 0, sizeof(vreq
));
5079 vreq
.vifi
= pim_ifp
->mroute_vif_index
;
5081 if (ioctl(pim
->mroute_socket
, SIOCGETVIFCNT
, &vreq
)) {
5083 "ioctl(SIOCGETVIFCNT=%lu) failure for interface %s vif_index=%d: errno=%d: %s",
5084 (unsigned long)SIOCGETVIFCNT
, ifp
->name
,
5085 pim_ifp
->mroute_vif_index
, errno
,
5086 safe_strerror(errno
));
5089 ifaddr
= pim_ifp
->primary_address
;
5091 vty_out(vty
, "%-16s %-15s %3d %3d %7lu %7lu %10lu %10lu\n",
5092 ifp
->name
, inet_ntoa(ifaddr
), ifp
->ifindex
,
5093 pim_ifp
->mroute_vif_index
, (unsigned long)vreq
.icount
,
5094 (unsigned long)vreq
.ocount
, (unsigned long)vreq
.ibytes
,
5095 (unsigned long)vreq
.obytes
);
5099 static void pim_cmd_show_ip_multicast_helper(struct pim_instance
*pim
,
5102 struct vrf
*vrf
= pim
->vrf
;
5103 time_t now
= pim_time_monotonic_sec();
5109 vty_out(vty
, "Router MLAG Role: %s\n",
5110 mlag_role2str(router
->role
, mlag_role
, sizeof(mlag_role
)));
5111 vty_out(vty
, "Mroute socket descriptor:");
5113 vty_out(vty
, " %d(%s)\n", pim
->mroute_socket
, vrf
->name
);
5115 pim_time_uptime(uptime
, sizeof(uptime
),
5116 now
- pim
->mroute_socket_creation
);
5117 vty_out(vty
, "Mroute socket uptime: %s\n", uptime
);
5121 pim_zebra_zclient_update(vty
);
5122 pim_zlookup_show_ip_multicast(vty
);
5125 vty_out(vty
, "Maximum highest VifIndex: %d\n", PIM_MAX_USABLE_VIFS
);
5128 vty_out(vty
, "Upstream Join Timer: %d secs\n", router
->t_periodic
);
5129 vty_out(vty
, "Join/Prune Holdtime: %d secs\n", PIM_JP_HOLDTIME
);
5130 vty_out(vty
, "PIM ECMP: %s\n", pim
->ecmp_enable
? "Enable" : "Disable");
5131 vty_out(vty
, "PIM ECMP Rebalance: %s\n",
5132 pim
->ecmp_rebalance_enable
? "Enable" : "Disable");
5136 show_rpf_refresh_stats(vty
, pim
, now
, NULL
);
5140 show_scan_oil_stats(pim
, vty
, now
);
5142 show_multicast_interfaces(pim
, vty
);
5145 DEFUN (show_ip_multicast
,
5146 show_ip_multicast_cmd
,
5147 "show ip multicast [vrf NAME]",
5151 "Multicast global information\n")
5154 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5159 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
5164 DEFUN (show_ip_multicast_vrf_all
,
5165 show_ip_multicast_vrf_all_cmd
,
5166 "show ip multicast vrf all",
5170 "Multicast global information\n")
5172 bool uj
= use_json(argc
, argv
);
5178 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5182 vty_out(vty
, " \"%s\": ", vrf
->name
);
5185 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5186 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
5189 vty_out(vty
, "}\n");
5194 static void show_mroute(struct pim_instance
*pim
, struct vty
*vty
,
5195 struct prefix_sg
*sg
, bool fill
, bool uj
)
5197 struct listnode
*node
;
5198 struct channel_oil
*c_oil
;
5199 struct static_route
*s_route
;
5201 json_object
*json
= NULL
;
5202 json_object
*json_group
= NULL
;
5203 json_object
*json_source
= NULL
;
5204 json_object
*json_oil
= NULL
;
5205 json_object
*json_ifp_out
= NULL
;
5208 char grp_str
[INET_ADDRSTRLEN
];
5209 char src_str
[INET_ADDRSTRLEN
];
5210 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
5211 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
5213 struct interface
*ifp_in
;
5217 json
= json_object_new_object();
5220 "Source Group Proto Input Output TTL Uptime\n");
5223 now
= pim_time_monotonic_sec();
5225 /* print list of PIM and IGMP routes */
5226 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
5229 if (!c_oil
->installed
&& !uj
)
5232 if (sg
->grp
.s_addr
!= 0 &&
5233 sg
->grp
.s_addr
!= c_oil
->oil
.mfcc_mcastgrp
.s_addr
)
5235 if (sg
->src
.s_addr
!= 0 &&
5236 sg
->src
.s_addr
!= c_oil
->oil
.mfcc_origin
.s_addr
)
5239 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
5241 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
5243 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
5246 strlcpy(in_ifname
, ifp_in
->name
, sizeof(in_ifname
));
5248 strlcpy(in_ifname
, "<iif?>", sizeof(in_ifname
));
5252 /* Find the group, create it if it doesn't exist */
5253 json_object_object_get_ex(json
, grp_str
, &json_group
);
5256 json_group
= json_object_new_object();
5257 json_object_object_add(json
, grp_str
,
5261 /* Find the source nested under the group, create it if
5262 * it doesn't exist */
5263 json_object_object_get_ex(json_group
, src_str
,
5267 json_source
= json_object_new_object();
5268 json_object_object_add(json_group
, src_str
,
5272 /* Find the inbound interface nested under the source,
5273 * create it if it doesn't exist */
5274 json_object_int_add(json_source
, "installed",
5276 json_object_int_add(json_source
, "refCount",
5277 c_oil
->oil_ref_count
);
5278 json_object_int_add(json_source
, "oilSize",
5280 json_object_int_add(json_source
, "OilInheritedRescan",
5281 c_oil
->oil_inherited_rescan
);
5282 json_object_string_add(json_source
, "iif", in_ifname
);
5286 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
5288 struct interface
*ifp_out
;
5289 char mroute_uptime
[10];
5292 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
5296 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
5298 mroute_uptime
, sizeof(mroute_uptime
),
5299 now
- c_oil
->mroute_creation
);
5303 strlcpy(out_ifname
, ifp_out
->name
, sizeof(out_ifname
));
5305 strlcpy(out_ifname
, "<oif?>", sizeof(out_ifname
));
5308 json_ifp_out
= json_object_new_object();
5309 json_object_string_add(json_ifp_out
, "source",
5311 json_object_string_add(json_ifp_out
, "group",
5314 if (c_oil
->oif_flags
[oif_vif_index
]
5315 & PIM_OIF_FLAG_PROTO_PIM
)
5316 json_object_boolean_true_add(
5317 json_ifp_out
, "protocolPim");
5319 if (c_oil
->oif_flags
[oif_vif_index
]
5320 & PIM_OIF_FLAG_PROTO_IGMP
)
5321 json_object_boolean_true_add(
5322 json_ifp_out
, "protocolIgmp");
5324 if (c_oil
->oif_flags
[oif_vif_index
]
5325 & PIM_OIF_FLAG_PROTO_VXLAN
)
5326 json_object_boolean_true_add(
5327 json_ifp_out
, "protocolVxlan");
5329 if (c_oil
->oif_flags
[oif_vif_index
]
5330 & PIM_OIF_FLAG_PROTO_STAR
)
5331 json_object_boolean_true_add(
5333 "protocolInherited");
5335 json_object_string_add(json_ifp_out
,
5338 json_object_int_add(json_ifp_out
, "iVifI",
5339 c_oil
->oil
.mfcc_parent
);
5340 json_object_string_add(json_ifp_out
,
5341 "outboundInterface",
5343 json_object_int_add(json_ifp_out
, "oVifI",
5345 json_object_int_add(json_ifp_out
, "ttl", ttl
);
5346 json_object_string_add(json_ifp_out
, "upTime",
5349 json_oil
= json_object_new_object();
5350 json_object_object_add(json_source
,
5353 json_object_object_add(json_oil
, out_ifname
,
5356 if (c_oil
->oif_flags
[oif_vif_index
]
5357 & PIM_OIF_FLAG_PROTO_PIM
) {
5358 strlcpy(proto
, "PIM", sizeof(proto
));
5361 if (c_oil
->oif_flags
[oif_vif_index
]
5362 & PIM_OIF_FLAG_PROTO_IGMP
) {
5363 strlcpy(proto
, "IGMP", sizeof(proto
));
5366 if (c_oil
->oif_flags
[oif_vif_index
]
5367 & PIM_OIF_FLAG_PROTO_VXLAN
) {
5368 strlcpy(proto
, "VxLAN", sizeof(proto
));
5371 if (c_oil
->oif_flags
[oif_vif_index
]
5372 & PIM_OIF_FLAG_PROTO_STAR
) {
5373 strlcpy(proto
, "STAR", sizeof(proto
));
5377 "%-15s %-15s %-6s %-16s %-16s %-3d %8s\n",
5378 src_str
, grp_str
, proto
, in_ifname
,
5379 out_ifname
, ttl
, mroute_uptime
);
5384 in_ifname
[0] = '\0';
5390 if (!uj
&& !found_oif
) {
5391 vty_out(vty
, "%-15s %-15s %-6s %-16s %-16s %-3d %8s\n",
5392 src_str
, grp_str
, "none", in_ifname
, "none", 0,
5397 /* Print list of static routes */
5398 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
5401 if (!s_route
->c_oil
.installed
)
5404 pim_inet4_dump("<group?>", s_route
->group
, grp_str
,
5406 pim_inet4_dump("<source?>", s_route
->source
, src_str
,
5408 ifp_in
= pim_if_find_by_vif_index(pim
, s_route
->iif
);
5412 strlcpy(in_ifname
, ifp_in
->name
, sizeof(in_ifname
));
5414 strlcpy(in_ifname
, "<iif?>", sizeof(in_ifname
));
5418 /* Find the group, create it if it doesn't exist */
5419 json_object_object_get_ex(json
, grp_str
, &json_group
);
5422 json_group
= json_object_new_object();
5423 json_object_object_add(json
, grp_str
,
5427 /* Find the source nested under the group, create it if
5428 * it doesn't exist */
5429 json_object_object_get_ex(json_group
, src_str
,
5433 json_source
= json_object_new_object();
5434 json_object_object_add(json_group
, src_str
,
5438 json_object_string_add(json_source
, "iif", in_ifname
);
5441 strlcpy(proto
, "STATIC", sizeof(proto
));
5444 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
5446 struct interface
*ifp_out
;
5447 char oif_uptime
[10];
5450 ttl
= s_route
->oif_ttls
[oif_vif_index
];
5454 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
5456 oif_uptime
, sizeof(oif_uptime
),
5459 .oif_creation
[oif_vif_index
]);
5463 strlcpy(out_ifname
, ifp_out
->name
, sizeof(out_ifname
));
5465 strlcpy(out_ifname
, "<oif?>", sizeof(out_ifname
));
5468 json_ifp_out
= json_object_new_object();
5469 json_object_string_add(json_ifp_out
, "source",
5471 json_object_string_add(json_ifp_out
, "group",
5473 json_object_boolean_true_add(json_ifp_out
,
5475 json_object_string_add(json_ifp_out
,
5478 json_object_int_add(
5479 json_ifp_out
, "iVifI",
5480 s_route
->c_oil
.oil
.mfcc_parent
);
5481 json_object_string_add(json_ifp_out
,
5482 "outboundInterface",
5484 json_object_int_add(json_ifp_out
, "oVifI",
5486 json_object_int_add(json_ifp_out
, "ttl", ttl
);
5487 json_object_string_add(json_ifp_out
, "upTime",
5490 json_oil
= json_object_new_object();
5491 json_object_object_add(json_source
,
5494 json_object_object_add(json_oil
, out_ifname
,
5498 "%-15s %-15s %-6s %-16s %-16s %-3d %8s %s\n",
5499 src_str
, grp_str
, proto
, in_ifname
,
5500 out_ifname
, ttl
, oif_uptime
,
5502 if (first
&& !fill
) {
5505 in_ifname
[0] = '\0';
5511 if (!uj
&& !found_oif
) {
5513 "%-15s %-15s %-6s %-16s %-16s %-3d %8s %s\n",
5514 src_str
, grp_str
, proto
, in_ifname
, "none", 0,
5515 "--:--:--", pim
->vrf
->name
);
5520 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5521 json
, JSON_C_TO_STRING_PRETTY
));
5522 json_object_free(json
);
5526 DEFPY (show_ip_mroute
,
5528 "show ip mroute [vrf NAME] [A.B.C.D$s_or_g [A.B.C.D$g]] [fill$fill] [json$json]",
5533 "The Source or Group\n"
5535 "Fill in Assumed data\n"
5538 struct prefix_sg sg
= {0};
5539 struct pim_instance
*pim
;
5542 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
5545 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
5548 pim
= pim_get_pim_instance(v
->vrf_id
);
5551 vty_out(vty
, "%% Unable to find pim instance\n");
5555 if (s_or_g
.s_addr
!= 0) {
5556 if (g
.s_addr
!= 0) {
5562 show_mroute(pim
, vty
, &sg
, !!fill
, !!json
);
5566 DEFUN (show_ip_mroute_vrf_all
,
5567 show_ip_mroute_vrf_all_cmd
,
5568 "show ip mroute vrf all [fill] [json]",
5573 "Fill in Assumed data\n"
5576 struct prefix_sg sg
= {0};
5577 bool uj
= use_json(argc
, argv
);
5583 if (argv_find(argv
, argc
, "fill", &idx
))
5588 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5592 vty_out(vty
, " \"%s\": ", vrf
->name
);
5595 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5596 show_mroute(vrf
->info
, vty
, &sg
, fill
, uj
);
5599 vty_out(vty
, "}\n");
5604 DEFUN (clear_ip_mroute_count
,
5605 clear_ip_mroute_count_cmd
,
5606 "clear ip mroute [vrf NAME] count",
5611 "Route and packet count data\n")
5614 struct listnode
*node
;
5615 struct channel_oil
*c_oil
;
5616 struct static_route
*sr
;
5617 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5618 struct pim_instance
*pim
;
5624 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
5625 if (!c_oil
->installed
)
5628 pim_mroute_update_counters(c_oil
);
5629 c_oil
->cc
.origpktcnt
= c_oil
->cc
.pktcnt
;
5630 c_oil
->cc
.origbytecnt
= c_oil
->cc
.bytecnt
;
5631 c_oil
->cc
.origwrong_if
= c_oil
->cc
.wrong_if
;
5634 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, sr
)) {
5635 if (!sr
->c_oil
.installed
)
5638 pim_mroute_update_counters(&sr
->c_oil
);
5640 sr
->c_oil
.cc
.origpktcnt
= sr
->c_oil
.cc
.pktcnt
;
5641 sr
->c_oil
.cc
.origbytecnt
= sr
->c_oil
.cc
.bytecnt
;
5642 sr
->c_oil
.cc
.origwrong_if
= sr
->c_oil
.cc
.wrong_if
;
5647 static void show_mroute_count(struct pim_instance
*pim
, struct vty
*vty
)
5649 struct listnode
*node
;
5650 struct channel_oil
*c_oil
;
5651 struct static_route
*sr
;
5656 "Source Group LastUsed Packets Bytes WrongIf \n");
5658 /* Print PIM and IGMP route counts */
5659 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
5660 char group_str
[INET_ADDRSTRLEN
];
5661 char source_str
[INET_ADDRSTRLEN
];
5663 if (!c_oil
->installed
)
5666 pim_mroute_update_counters(c_oil
);
5668 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, group_str
,
5670 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, source_str
,
5671 sizeof(source_str
));
5673 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
5674 source_str
, group_str
, c_oil
->cc
.lastused
/ 100,
5675 c_oil
->cc
.pktcnt
- c_oil
->cc
.origpktcnt
,
5676 c_oil
->cc
.bytecnt
- c_oil
->cc
.origbytecnt
,
5677 c_oil
->cc
.wrong_if
- c_oil
->cc
.origwrong_if
);
5680 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, sr
)) {
5681 char group_str
[INET_ADDRSTRLEN
];
5682 char source_str
[INET_ADDRSTRLEN
];
5684 if (!sr
->c_oil
.installed
)
5687 pim_mroute_update_counters(&sr
->c_oil
);
5689 pim_inet4_dump("<group?>", sr
->c_oil
.oil
.mfcc_mcastgrp
,
5690 group_str
, sizeof(group_str
));
5691 pim_inet4_dump("<source?>", sr
->c_oil
.oil
.mfcc_origin
,
5692 source_str
, sizeof(source_str
));
5694 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
5695 source_str
, group_str
, sr
->c_oil
.cc
.lastused
,
5696 sr
->c_oil
.cc
.pktcnt
- sr
->c_oil
.cc
.origpktcnt
,
5697 sr
->c_oil
.cc
.bytecnt
- sr
->c_oil
.cc
.origbytecnt
,
5698 sr
->c_oil
.cc
.wrong_if
- sr
->c_oil
.cc
.origwrong_if
);
5702 DEFUN (show_ip_mroute_count
,
5703 show_ip_mroute_count_cmd
,
5704 "show ip mroute [vrf NAME] count",
5709 "Route and packet count data\n")
5712 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5717 show_mroute_count(vrf
->info
, vty
);
5721 DEFUN (show_ip_mroute_count_vrf_all
,
5722 show_ip_mroute_count_vrf_all_cmd
,
5723 "show ip mroute vrf all count",
5728 "Route and packet count data\n")
5730 bool uj
= use_json(argc
, argv
);
5736 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5740 vty_out(vty
, " \"%s\": ", vrf
->name
);
5743 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5744 show_mroute_count(vrf
->info
, vty
);
5747 vty_out(vty
, "}\n");
5752 static void show_mroute_summary(struct pim_instance
*pim
, struct vty
*vty
)
5754 struct listnode
*node
;
5755 struct channel_oil
*c_oil
;
5756 struct static_route
*s_route
;
5757 uint32_t starg_sw_mroute_cnt
= 0;
5758 uint32_t sg_sw_mroute_cnt
= 0;
5759 uint32_t starg_hw_mroute_cnt
= 0;
5760 uint32_t sg_hw_mroute_cnt
= 0;
5762 vty_out(vty
, "Mroute Type Installed/Total\n");
5764 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
5765 if (!c_oil
->installed
) {
5766 if (c_oil
->oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
5767 starg_sw_mroute_cnt
++;
5771 if (c_oil
->oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
5772 starg_hw_mroute_cnt
++;
5778 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
5779 if (!s_route
->c_oil
.installed
) {
5780 if (s_route
->c_oil
.oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
5781 starg_sw_mroute_cnt
++;
5785 if (s_route
->c_oil
.oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
5786 starg_hw_mroute_cnt
++;
5792 vty_out(vty
, "%-20s %d/%d\n", "(*, G)", starg_hw_mroute_cnt
,
5793 starg_sw_mroute_cnt
+ starg_hw_mroute_cnt
);
5794 vty_out(vty
, "%-20s %d/%d\n", "(S, G)", sg_hw_mroute_cnt
,
5795 sg_sw_mroute_cnt
+ sg_hw_mroute_cnt
);
5796 vty_out(vty
, "------\n");
5797 vty_out(vty
, "%-20s %d/%d\n", "Total",
5798 (starg_hw_mroute_cnt
+ sg_hw_mroute_cnt
),
5799 (starg_sw_mroute_cnt
+
5800 starg_hw_mroute_cnt
+
5805 DEFUN (show_ip_mroute_summary
,
5806 show_ip_mroute_summary_cmd
,
5807 "show ip mroute [vrf NAME] summary",
5812 "Summary of all mroutes\n")
5815 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5820 show_mroute_summary(vrf
->info
, vty
);
5824 DEFUN (show_ip_mroute_summary_vrf_all
,
5825 show_ip_mroute_summary_vrf_all_cmd
,
5826 "show ip mroute vrf all summary",
5831 "Summary of all mroutes\n")
5835 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5836 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5837 show_mroute_summary(vrf
->info
, vty
);
5845 "show ip rib [vrf NAME] A.B.C.D",
5850 "Unicast address\n")
5853 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5854 struct in_addr addr
;
5855 const char *addr_str
;
5856 struct pim_nexthop nexthop
;
5857 char nexthop_addr_str
[PREFIX_STRLEN
];
5863 memset(&nexthop
, 0, sizeof(nexthop
));
5864 argv_find(argv
, argc
, "A.B.C.D", &idx
);
5865 addr_str
= argv
[idx
]->arg
;
5866 result
= inet_pton(AF_INET
, addr_str
, &addr
);
5868 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
5869 errno
, safe_strerror(errno
));
5873 if (!pim_nexthop_lookup(vrf
->info
, &nexthop
, addr
, 0)) {
5875 "Failure querying RIB nexthop for unicast address %s\n",
5881 "Address NextHop Interface Metric Preference\n");
5883 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
5884 nexthop_addr_str
, sizeof(nexthop_addr_str
));
5886 vty_out(vty
, "%-15s %-15s %-9s %6d %10d\n", addr_str
, nexthop_addr_str
,
5887 nexthop
.interface
? nexthop
.interface
->name
: "<ifname?>",
5888 nexthop
.mrib_route_metric
, nexthop
.mrib_metric_preference
);
5893 static void show_ssmpingd(struct pim_instance
*pim
, struct vty
*vty
)
5895 struct listnode
*node
;
5896 struct ssmpingd_sock
*ss
;
5900 "Source Socket Address Port Uptime Requests\n");
5902 if (!pim
->ssmpingd_list
)
5905 now
= pim_time_monotonic_sec();
5907 for (ALL_LIST_ELEMENTS_RO(pim
->ssmpingd_list
, node
, ss
)) {
5908 char source_str
[INET_ADDRSTRLEN
];
5910 struct sockaddr_in bind_addr
;
5911 socklen_t len
= sizeof(bind_addr
);
5912 char bind_addr_str
[INET_ADDRSTRLEN
];
5914 pim_inet4_dump("<src?>", ss
->source_addr
, source_str
,
5915 sizeof(source_str
));
5917 if (pim_socket_getsockname(
5918 ss
->sock_fd
, (struct sockaddr
*)&bind_addr
, &len
)) {
5920 "%% Failure reading socket name for ssmpingd source %s on fd=%d\n",
5921 source_str
, ss
->sock_fd
);
5924 pim_inet4_dump("<addr?>", bind_addr
.sin_addr
, bind_addr_str
,
5925 sizeof(bind_addr_str
));
5926 pim_time_uptime(ss_uptime
, sizeof(ss_uptime
),
5927 now
- ss
->creation
);
5929 vty_out(vty
, "%-15s %6d %-15s %5d %8s %8lld\n", source_str
,
5930 ss
->sock_fd
, bind_addr_str
, ntohs(bind_addr
.sin_port
),
5931 ss_uptime
, (long long)ss
->requests
);
5935 DEFUN (show_ip_ssmpingd
,
5936 show_ip_ssmpingd_cmd
,
5937 "show ip ssmpingd [vrf NAME]",
5944 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5949 show_ssmpingd(vrf
->info
, vty
);
5953 static int pim_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
5954 const char *rp
, const char *group
,
5959 result
= pim_rp_new_config(pim
, rp
, group
, plist
);
5961 if (result
== PIM_GROUP_BAD_ADDR_MASK_COMBO
) {
5962 vty_out(vty
, "%% Inconsistent address and mask: %s\n",
5964 return CMD_WARNING_CONFIG_FAILED
;
5967 if (result
== PIM_GROUP_BAD_ADDRESS
) {
5968 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
5969 return CMD_WARNING_CONFIG_FAILED
;
5972 if (result
== PIM_RP_BAD_ADDRESS
) {
5973 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
5974 return CMD_WARNING_CONFIG_FAILED
;
5977 if (result
== PIM_RP_NO_PATH
) {
5978 vty_out(vty
, "%% No Path to RP address specified: %s\n", rp
);
5982 if (result
== PIM_GROUP_OVERLAP
) {
5984 "%% Group range specified cannot exact match another\n");
5985 return CMD_WARNING_CONFIG_FAILED
;
5988 if (result
== PIM_GROUP_PFXLIST_OVERLAP
) {
5990 "%% This group is already covered by a RP prefix-list\n");
5991 return CMD_WARNING_CONFIG_FAILED
;
5994 if (result
== PIM_RP_PFXLIST_IN_USE
) {
5996 "%% The same prefix-list cannot be applied to multiple RPs\n");
5997 return CMD_WARNING_CONFIG_FAILED
;
6003 static int pim_cmd_spt_switchover(struct pim_instance
*pim
,
6004 enum pim_spt_switchover spt
,
6007 pim
->spt
.switchover
= spt
;
6009 switch (pim
->spt
.switchover
) {
6010 case PIM_SPT_IMMEDIATE
:
6011 XFREE(MTYPE_PIM_SPT_PLIST_NAME
, pim
->spt
.plist
);
6013 pim_upstream_add_lhr_star_pimreg(pim
);
6015 case PIM_SPT_INFINITY
:
6016 pim_upstream_remove_lhr_star_pimreg(pim
, plist
);
6018 XFREE(MTYPE_PIM_SPT_PLIST_NAME
, pim
->spt
.plist
);
6022 XSTRDUP(MTYPE_PIM_SPT_PLIST_NAME
, plist
);
6029 DEFUN (ip_pim_spt_switchover_infinity
,
6030 ip_pim_spt_switchover_infinity_cmd
,
6031 "ip pim spt-switchover infinity-and-beyond",
6035 "Never switch to SPT Tree\n")
6037 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6038 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, NULL
);
6041 DEFUN (ip_pim_spt_switchover_infinity_plist
,
6042 ip_pim_spt_switchover_infinity_plist_cmd
,
6043 "ip pim spt-switchover infinity-and-beyond prefix-list WORD",
6047 "Never switch to SPT Tree\n"
6048 "Prefix-List to control which groups to switch\n"
6049 "Prefix-List name\n")
6051 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6052 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, argv
[5]->arg
);
6055 DEFUN (no_ip_pim_spt_switchover_infinity
,
6056 no_ip_pim_spt_switchover_infinity_cmd
,
6057 "no ip pim spt-switchover infinity-and-beyond",
6062 "Never switch to SPT Tree\n")
6064 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6065 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
6068 DEFUN (no_ip_pim_spt_switchover_infinity_plist
,
6069 no_ip_pim_spt_switchover_infinity_plist_cmd
,
6070 "no ip pim spt-switchover infinity-and-beyond prefix-list WORD",
6075 "Never switch to SPT Tree\n"
6076 "Prefix-List to control which groups to switch\n"
6077 "Prefix-List name\n")
6079 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6080 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
6083 DEFUN (ip_pim_joinprune_time
,
6084 ip_pim_joinprune_time_cmd
,
6085 "ip pim join-prune-interval (60-600)",
6087 "pim multicast routing\n"
6088 "Join Prune Send Interval\n"
6091 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6092 router
->t_periodic
= atoi(argv
[3]->arg
);
6096 DEFUN (no_ip_pim_joinprune_time
,
6097 no_ip_pim_joinprune_time_cmd
,
6098 "no ip pim join-prune-interval (60-600)",
6101 "pim multicast routing\n"
6102 "Join Prune Send Interval\n"
6105 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6106 router
->t_periodic
= PIM_DEFAULT_T_PERIODIC
;
6110 DEFUN (ip_pim_register_suppress
,
6111 ip_pim_register_suppress_cmd
,
6112 "ip pim register-suppress-time (5-60000)",
6114 "pim multicast routing\n"
6115 "Register Suppress Timer\n"
6118 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6119 router
->register_suppress_time
= atoi(argv
[3]->arg
);
6123 DEFUN (no_ip_pim_register_suppress
,
6124 no_ip_pim_register_suppress_cmd
,
6125 "no ip pim register-suppress-time (5-60000)",
6128 "pim multicast routing\n"
6129 "Register Suppress Timer\n"
6132 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6133 router
->register_suppress_time
= PIM_REGISTER_SUPPRESSION_TIME_DEFAULT
;
6137 DEFUN (ip_pim_rp_keep_alive
,
6138 ip_pim_rp_keep_alive_cmd
,
6139 "ip pim rp keep-alive-timer (31-60000)",
6141 "pim multicast routing\n"
6143 "Keep alive Timer\n"
6146 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6147 pim
->rp_keep_alive_time
= atoi(argv
[4]->arg
);
6151 DEFUN (no_ip_pim_rp_keep_alive
,
6152 no_ip_pim_rp_keep_alive_cmd
,
6153 "no ip pim rp keep-alive-timer (31-60000)",
6156 "pim multicast routing\n"
6158 "Keep alive Timer\n"
6161 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6162 pim
->rp_keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
6166 DEFUN (ip_pim_keep_alive
,
6167 ip_pim_keep_alive_cmd
,
6168 "ip pim keep-alive-timer (31-60000)",
6170 "pim multicast routing\n"
6171 "Keep alive Timer\n"
6174 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6175 pim
->keep_alive_time
= atoi(argv
[3]->arg
);
6179 DEFUN (no_ip_pim_keep_alive
,
6180 no_ip_pim_keep_alive_cmd
,
6181 "no ip pim keep-alive-timer (31-60000)",
6184 "pim multicast routing\n"
6185 "Keep alive Timer\n"
6188 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6189 pim
->keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
6193 DEFUN (ip_pim_packets
,
6195 "ip pim packets (1-100)",
6197 "pim multicast routing\n"
6198 "packets to process at one time per fd\n"
6199 "Number of packets\n")
6201 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6202 router
->packet_process
= atoi(argv
[3]->arg
);
6206 DEFUN (no_ip_pim_packets
,
6207 no_ip_pim_packets_cmd
,
6208 "no ip pim packets (1-100)",
6211 "pim multicast routing\n"
6212 "packets to process at one time per fd\n"
6213 "Number of packets\n")
6215 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6216 router
->packet_process
= PIM_DEFAULT_PACKET_PROCESS
;
6220 DEFUN (ip_pim_v6_secondary
,
6221 ip_pim_v6_secondary_cmd
,
6222 "ip pim send-v6-secondary",
6224 "pim multicast routing\n"
6225 "Send v6 secondary addresses\n")
6227 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6228 pim
->send_v6_secondary
= 1;
6233 DEFUN (no_ip_pim_v6_secondary
,
6234 no_ip_pim_v6_secondary_cmd
,
6235 "no ip pim send-v6-secondary",
6238 "pim multicast routing\n"
6239 "Send v6 secondary addresses\n")
6241 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6242 pim
->send_v6_secondary
= 0;
6249 "ip pim rp A.B.C.D [A.B.C.D/M]",
6251 "pim multicast routing\n"
6253 "ip address of RP\n"
6254 "Group Address range to cover\n")
6256 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6259 if (argc
== (idx_ipv4
+ 1))
6260 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
6263 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
6264 argv
[idx_ipv4
+ 1]->arg
, NULL
);
6267 DEFUN (ip_pim_rp_prefix_list
,
6268 ip_pim_rp_prefix_list_cmd
,
6269 "ip pim rp A.B.C.D prefix-list WORD",
6271 "pim multicast routing\n"
6273 "ip address of RP\n"
6274 "group prefix-list filter\n"
6275 "Name of a prefix-list\n")
6277 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6278 return pim_rp_cmd_worker(pim
, vty
, argv
[3]->arg
, NULL
, argv
[5]->arg
);
6281 static int pim_no_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
6282 const char *rp
, const char *group
,
6285 int result
= pim_rp_del_config(pim
, rp
, group
, plist
);
6287 if (result
== PIM_GROUP_BAD_ADDRESS
) {
6288 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
6289 return CMD_WARNING_CONFIG_FAILED
;
6292 if (result
== PIM_RP_BAD_ADDRESS
) {
6293 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
6294 return CMD_WARNING_CONFIG_FAILED
;
6297 if (result
== PIM_RP_NOT_FOUND
) {
6298 vty_out(vty
, "%% Unable to find specified RP\n");
6299 return CMD_WARNING_CONFIG_FAILED
;
6305 DEFUN (no_ip_pim_rp
,
6307 "no ip pim rp A.B.C.D [A.B.C.D/M]",
6310 "pim multicast routing\n"
6312 "ip address of RP\n"
6313 "Group Address range to cover\n")
6315 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6316 int idx_ipv4
= 4, idx_group
= 0;
6318 if (argv_find(argv
, argc
, "A.B.C.D/M", &idx_group
))
6319 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
6320 argv
[idx_group
]->arg
, NULL
);
6322 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
6326 DEFUN (no_ip_pim_rp_prefix_list
,
6327 no_ip_pim_rp_prefix_list_cmd
,
6328 "no ip pim rp A.B.C.D prefix-list WORD",
6331 "pim multicast routing\n"
6333 "ip address of RP\n"
6334 "group prefix-list filter\n"
6335 "Name of a prefix-list\n")
6337 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6338 return pim_no_rp_cmd_worker(pim
, vty
, argv
[4]->arg
, NULL
, argv
[6]->arg
);
6341 static int pim_ssm_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
6344 int result
= pim_ssm_range_set(pim
, pim
->vrf_id
, plist
);
6345 int ret
= CMD_WARNING_CONFIG_FAILED
;
6347 if (result
== PIM_SSM_ERR_NONE
)
6351 case PIM_SSM_ERR_NO_VRF
:
6352 vty_out(vty
, "%% VRF doesn't exist\n");
6354 case PIM_SSM_ERR_DUP
:
6355 vty_out(vty
, "%% duplicate config\n");
6359 vty_out(vty
, "%% ssm range config failed\n");
6365 DEFUN (ip_pim_ssm_prefix_list
,
6366 ip_pim_ssm_prefix_list_cmd
,
6367 "ip pim ssm prefix-list WORD",
6369 "pim multicast routing\n"
6370 "Source Specific Multicast\n"
6371 "group range prefix-list filter\n"
6372 "Name of a prefix-list\n")
6374 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6375 return pim_ssm_cmd_worker(pim
, vty
, argv
[4]->arg
);
6378 DEFUN (no_ip_pim_ssm_prefix_list
,
6379 no_ip_pim_ssm_prefix_list_cmd
,
6380 "no ip pim ssm prefix-list",
6383 "pim multicast routing\n"
6384 "Source Specific Multicast\n"
6385 "group range prefix-list filter\n")
6387 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6388 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
6391 DEFUN (no_ip_pim_ssm_prefix_list_name
,
6392 no_ip_pim_ssm_prefix_list_name_cmd
,
6393 "no ip pim ssm prefix-list WORD",
6396 "pim multicast routing\n"
6397 "Source Specific Multicast\n"
6398 "group range prefix-list filter\n"
6399 "Name of a prefix-list\n")
6401 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6402 struct pim_ssm
*ssm
= pim
->ssm_info
;
6404 if (ssm
->plist_name
&& !strcmp(ssm
->plist_name
, argv
[5]->arg
))
6405 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
6407 vty_out(vty
, "%% pim ssm prefix-list %s doesn't exist\n", argv
[5]->arg
);
6409 return CMD_WARNING_CONFIG_FAILED
;
6412 static void ip_pim_ssm_show_group_range(struct pim_instance
*pim
,
6413 struct vty
*vty
, bool uj
)
6415 struct pim_ssm
*ssm
= pim
->ssm_info
;
6416 const char *range_str
=
6417 ssm
->plist_name
? ssm
->plist_name
: PIM_SSM_STANDARD_RANGE
;
6421 json
= json_object_new_object();
6422 json_object_string_add(json
, "ssmGroups", range_str
);
6423 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
6424 json
, JSON_C_TO_STRING_PRETTY
));
6425 json_object_free(json
);
6427 vty_out(vty
, "SSM group range : %s\n", range_str
);
6430 DEFUN (show_ip_pim_ssm_range
,
6431 show_ip_pim_ssm_range_cmd
,
6432 "show ip pim [vrf NAME] group-type [json]",
6441 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6442 bool uj
= use_json(argc
, argv
);
6447 ip_pim_ssm_show_group_range(vrf
->info
, vty
, uj
);
6452 static void ip_pim_ssm_show_group_type(struct pim_instance
*pim
,
6453 struct vty
*vty
, bool uj
,
6456 struct in_addr group_addr
;
6457 const char *type_str
;
6460 result
= inet_pton(AF_INET
, group
, &group_addr
);
6462 type_str
= "invalid";
6464 if (pim_is_group_224_4(group_addr
))
6466 pim_is_grp_ssm(pim
, group_addr
) ? "SSM" : "ASM";
6468 type_str
= "not-multicast";
6473 json
= json_object_new_object();
6474 json_object_string_add(json
, "groupType", type_str
);
6475 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
6476 json
, JSON_C_TO_STRING_PRETTY
));
6477 json_object_free(json
);
6479 vty_out(vty
, "Group type : %s\n", type_str
);
6482 DEFUN (show_ip_pim_group_type
,
6483 show_ip_pim_group_type_cmd
,
6484 "show ip pim [vrf NAME] group-type A.B.C.D [json]",
6489 "multicast group type\n"
6494 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6495 bool uj
= use_json(argc
, argv
);
6500 argv_find(argv
, argc
, "A.B.C.D", &idx
);
6501 ip_pim_ssm_show_group_type(vrf
->info
, vty
, uj
, argv
[idx
]->arg
);
6506 DEFUN (show_ip_pim_bsr
,
6507 show_ip_pim_bsr_cmd
,
6508 "show ip pim bsr [json]",
6512 "boot-strap router information\n"
6516 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6517 bool uj
= use_json(argc
, argv
);
6522 pim_show_bsr(vrf
->info
, vty
, uj
);
6529 "ip ssmpingd [A.B.C.D]",
6534 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6537 struct in_addr source_addr
;
6538 const char *source_str
= (argc
== 3) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
6540 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
6542 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
6543 source_str
, errno
, safe_strerror(errno
));
6544 return CMD_WARNING_CONFIG_FAILED
;
6547 result
= pim_ssmpingd_start(pim
, source_addr
);
6549 vty_out(vty
, "%% Failure starting ssmpingd for source %s: %d\n",
6550 source_str
, result
);
6551 return CMD_WARNING_CONFIG_FAILED
;
6557 DEFUN (no_ip_ssmpingd
,
6559 "no ip ssmpingd [A.B.C.D]",
6565 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6568 struct in_addr source_addr
;
6569 const char *source_str
= (argc
== 4) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
6571 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
6573 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
6574 source_str
, errno
, safe_strerror(errno
));
6575 return CMD_WARNING_CONFIG_FAILED
;
6578 result
= pim_ssmpingd_stop(pim
, source_addr
);
6580 vty_out(vty
, "%% Failure stopping ssmpingd for source %s: %d\n",
6581 source_str
, result
);
6582 return CMD_WARNING_CONFIG_FAILED
;
6592 "pim multicast routing\n"
6593 "Enable PIM ECMP \n")
6595 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6596 pim
->ecmp_enable
= true;
6601 DEFUN (no_ip_pim_ecmp
,
6606 "pim multicast routing\n"
6607 "Disable PIM ECMP \n")
6609 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6610 pim
->ecmp_enable
= false;
6615 DEFUN (ip_pim_ecmp_rebalance
,
6616 ip_pim_ecmp_rebalance_cmd
,
6617 "ip pim ecmp rebalance",
6619 "pim multicast routing\n"
6620 "Enable PIM ECMP \n"
6621 "Enable PIM ECMP Rebalance\n")
6623 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6624 pim
->ecmp_enable
= true;
6625 pim
->ecmp_rebalance_enable
= true;
6630 DEFUN (no_ip_pim_ecmp_rebalance
,
6631 no_ip_pim_ecmp_rebalance_cmd
,
6632 "no ip pim ecmp rebalance",
6635 "pim multicast routing\n"
6636 "Disable PIM ECMP \n"
6637 "Disable PIM ECMP Rebalance\n")
6639 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6640 pim
->ecmp_rebalance_enable
= false;
6645 static int pim_cmd_igmp_start(struct vty
*vty
, struct interface
*ifp
)
6647 struct pim_interface
*pim_ifp
;
6648 uint8_t need_startup
= 0;
6650 pim_ifp
= ifp
->info
;
6653 (void)pim_if_new(ifp
, true, false, false, false);
6656 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
6657 PIM_IF_DO_IGMP(pim_ifp
->options
);
6662 /* 'ip igmp' executed multiple times, with need_startup
6663 avoid multiple if add all and membership refresh */
6665 pim_if_addr_add_all(ifp
);
6666 pim_if_membership_refresh(ifp
);
6672 DEFUN (interface_ip_igmp
,
6673 interface_ip_igmp_cmd
,
6678 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6680 return pim_cmd_igmp_start(vty
, ifp
);
6683 DEFUN (interface_no_ip_igmp
,
6684 interface_no_ip_igmp_cmd
,
6690 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6691 struct pim_interface
*pim_ifp
= ifp
->info
;
6696 PIM_IF_DONT_IGMP(pim_ifp
->options
);
6698 pim_if_membership_clear(ifp
);
6700 pim_if_addr_del_all_igmp(ifp
);
6702 if (!PIM_IF_TEST_PIM(pim_ifp
->options
)) {
6709 DEFUN (interface_ip_igmp_join
,
6710 interface_ip_igmp_join_cmd
,
6711 "ip igmp join A.B.C.D A.B.C.D",
6714 "IGMP join multicast group\n"
6715 "Multicast group address\n"
6718 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6721 const char *group_str
;
6722 const char *source_str
;
6723 struct in_addr group_addr
;
6724 struct in_addr source_addr
;
6728 group_str
= argv
[idx_ipv4
]->arg
;
6729 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
6731 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
6732 errno
, safe_strerror(errno
));
6733 return CMD_WARNING_CONFIG_FAILED
;
6736 /* Source address */
6737 source_str
= argv
[idx_ipv4_2
]->arg
;
6738 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
6740 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
6741 source_str
, errno
, safe_strerror(errno
));
6742 return CMD_WARNING_CONFIG_FAILED
;
6745 CMD_FERR_RETURN(pim_if_igmp_join_add(ifp
, group_addr
, source_addr
),
6746 "Failure joining IGMP group: $ERR");
6751 DEFUN (interface_no_ip_igmp_join
,
6752 interface_no_ip_igmp_join_cmd
,
6753 "no ip igmp join A.B.C.D A.B.C.D",
6757 "IGMP join multicast group\n"
6758 "Multicast group address\n"
6761 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6764 const char *group_str
;
6765 const char *source_str
;
6766 struct in_addr group_addr
;
6767 struct in_addr source_addr
;
6771 group_str
= argv
[idx_ipv4
]->arg
;
6772 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
6774 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
6775 errno
, safe_strerror(errno
));
6776 return CMD_WARNING_CONFIG_FAILED
;
6779 /* Source address */
6780 source_str
= argv
[idx_ipv4_2
]->arg
;
6781 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
6783 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
6784 source_str
, errno
, safe_strerror(errno
));
6785 return CMD_WARNING_CONFIG_FAILED
;
6788 result
= pim_if_igmp_join_del(ifp
, group_addr
, source_addr
);
6791 "%% Failure leaving IGMP group %s source %s on interface %s: %d\n",
6792 group_str
, source_str
, ifp
->name
, result
);
6793 return CMD_WARNING_CONFIG_FAILED
;
6800 CLI reconfiguration affects the interface level (struct pim_interface).
6801 This function propagates the reconfiguration to every active socket
6804 static void igmp_sock_query_interval_reconfig(struct igmp_sock
*igmp
)
6806 struct interface
*ifp
;
6807 struct pim_interface
*pim_ifp
;
6811 /* other querier present? */
6813 if (igmp
->t_other_querier_timer
)
6816 /* this is the querier */
6818 zassert(igmp
->interface
);
6819 zassert(igmp
->interface
->info
);
6821 ifp
= igmp
->interface
;
6822 pim_ifp
= ifp
->info
;
6824 if (PIM_DEBUG_IGMP_TRACE
) {
6825 char ifaddr_str
[INET_ADDRSTRLEN
];
6826 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
6827 sizeof(ifaddr_str
));
6828 zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
6829 __PRETTY_FUNCTION__
, ifaddr_str
, ifp
->name
,
6830 pim_ifp
->igmp_default_query_interval
);
6834 igmp_startup_mode_on() will reset QQI:
6836 igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
6838 igmp_startup_mode_on(igmp
);
6841 static void igmp_sock_query_reschedule(struct igmp_sock
*igmp
)
6843 if (igmp
->t_igmp_query_timer
) {
6844 /* other querier present */
6845 zassert(igmp
->t_igmp_query_timer
);
6846 zassert(!igmp
->t_other_querier_timer
);
6848 pim_igmp_general_query_off(igmp
);
6849 pim_igmp_general_query_on(igmp
);
6851 zassert(igmp
->t_igmp_query_timer
);
6852 zassert(!igmp
->t_other_querier_timer
);
6854 /* this is the querier */
6856 zassert(!igmp
->t_igmp_query_timer
);
6857 zassert(igmp
->t_other_querier_timer
);
6859 pim_igmp_other_querier_timer_off(igmp
);
6860 pim_igmp_other_querier_timer_on(igmp
);
6862 zassert(!igmp
->t_igmp_query_timer
);
6863 zassert(igmp
->t_other_querier_timer
);
6867 static void change_query_interval(struct pim_interface
*pim_ifp
,
6870 struct listnode
*sock_node
;
6871 struct igmp_sock
*igmp
;
6873 pim_ifp
->igmp_default_query_interval
= query_interval
;
6875 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
6876 igmp_sock_query_interval_reconfig(igmp
);
6877 igmp_sock_query_reschedule(igmp
);
6881 static void change_query_max_response_time(struct pim_interface
*pim_ifp
,
6882 int query_max_response_time_dsec
)
6884 struct listnode
*sock_node
;
6885 struct igmp_sock
*igmp
;
6887 pim_ifp
->igmp_query_max_response_time_dsec
=
6888 query_max_response_time_dsec
;
6891 Below we modify socket/group/source timers in order to quickly
6892 reflect the change. Otherwise, those timers would eventually catch
6896 /* scan all sockets */
6897 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
6898 struct listnode
*grp_node
;
6899 struct igmp_group
*grp
;
6901 /* reschedule socket general query */
6902 igmp_sock_query_reschedule(igmp
);
6904 /* scan socket groups */
6905 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grp_node
,
6907 struct listnode
*src_node
;
6908 struct igmp_source
*src
;
6910 /* reset group timers for groups in EXCLUDE mode */
6911 if (grp
->group_filtermode_isexcl
) {
6912 igmp_group_reset_gmi(grp
);
6915 /* scan group sources */
6916 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
,
6919 /* reset source timers for sources with running
6921 if (src
->t_source_timer
) {
6922 igmp_source_reset_gmi(igmp
, grp
, src
);
6929 #define IGMP_QUERY_INTERVAL_MIN (1)
6930 #define IGMP_QUERY_INTERVAL_MAX (1800)
6932 DEFUN (interface_ip_igmp_query_interval
,
6933 interface_ip_igmp_query_interval_cmd
,
6934 "ip igmp query-interval (1-1800)",
6937 IFACE_IGMP_QUERY_INTERVAL_STR
6938 "Query interval in seconds\n")
6940 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6941 struct pim_interface
*pim_ifp
= ifp
->info
;
6943 int query_interval_dsec
;
6947 ret
= pim_cmd_igmp_start(vty
, ifp
);
6948 if (ret
!= CMD_SUCCESS
)
6950 pim_ifp
= ifp
->info
;
6953 query_interval
= atoi(argv
[3]->arg
);
6954 query_interval_dsec
= 10 * query_interval
;
6957 It seems we don't need to check bounds since command.c does it
6958 already, but we verify them anyway for extra safety.
6960 if (query_interval
< IGMP_QUERY_INTERVAL_MIN
) {
6962 "General query interval %d lower than minimum %d\n",
6963 query_interval
, IGMP_QUERY_INTERVAL_MIN
);
6964 return CMD_WARNING_CONFIG_FAILED
;
6966 if (query_interval
> IGMP_QUERY_INTERVAL_MAX
) {
6968 "General query interval %d higher than maximum %d\n",
6969 query_interval
, IGMP_QUERY_INTERVAL_MAX
);
6970 return CMD_WARNING_CONFIG_FAILED
;
6973 if (query_interval_dsec
<= pim_ifp
->igmp_query_max_response_time_dsec
) {
6975 "Can't set general query interval %d dsec <= query max response time %d dsec.\n",
6976 query_interval_dsec
,
6977 pim_ifp
->igmp_query_max_response_time_dsec
);
6978 return CMD_WARNING_CONFIG_FAILED
;
6981 change_query_interval(pim_ifp
, query_interval
);
6986 DEFUN (interface_no_ip_igmp_query_interval
,
6987 interface_no_ip_igmp_query_interval_cmd
,
6988 "no ip igmp query-interval",
6992 IFACE_IGMP_QUERY_INTERVAL_STR
)
6994 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6995 struct pim_interface
*pim_ifp
= ifp
->info
;
6996 int default_query_interval_dsec
;
7001 default_query_interval_dsec
= IGMP_GENERAL_QUERY_INTERVAL
* 10;
7003 if (default_query_interval_dsec
7004 <= pim_ifp
->igmp_query_max_response_time_dsec
) {
7006 "Can't set default general query interval %d dsec <= query max response time %d dsec.\n",
7007 default_query_interval_dsec
,
7008 pim_ifp
->igmp_query_max_response_time_dsec
);
7009 return CMD_WARNING_CONFIG_FAILED
;
7012 change_query_interval(pim_ifp
, IGMP_GENERAL_QUERY_INTERVAL
);
7017 DEFUN (interface_ip_igmp_version
,
7018 interface_ip_igmp_version_cmd
,
7019 "ip igmp version (2-3)",
7023 "IGMP version number\n")
7025 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7026 struct pim_interface
*pim_ifp
= ifp
->info
;
7027 int igmp_version
, old_version
= 0;
7031 ret
= pim_cmd_igmp_start(vty
, ifp
);
7032 if (ret
!= CMD_SUCCESS
)
7034 pim_ifp
= ifp
->info
;
7037 igmp_version
= atoi(argv
[3]->arg
);
7038 old_version
= pim_ifp
->igmp_version
;
7039 pim_ifp
->igmp_version
= igmp_version
;
7041 // Check if IGMP is Enabled otherwise, enable on interface
7042 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
7043 PIM_IF_DO_IGMP(pim_ifp
->options
);
7044 pim_if_addr_add_all(ifp
);
7045 pim_if_membership_refresh(ifp
);
7046 old_version
= igmp_version
;
7047 // avoid refreshing membership again.
7049 /* Current and new version is different refresh existing
7050 membership. Going from 3 -> 2 or 2 -> 3. */
7051 if (old_version
!= igmp_version
)
7052 pim_if_membership_refresh(ifp
);
7057 DEFUN (interface_no_ip_igmp_version
,
7058 interface_no_ip_igmp_version_cmd
,
7059 "no ip igmp version (2-3)",
7064 "IGMP version number\n")
7066 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7067 struct pim_interface
*pim_ifp
= ifp
->info
;
7072 pim_ifp
->igmp_version
= IGMP_DEFAULT_VERSION
;
7077 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
7078 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
7080 DEFUN (interface_ip_igmp_query_max_response_time
,
7081 interface_ip_igmp_query_max_response_time_cmd
,
7082 "ip igmp query-max-response-time (10-250)",
7085 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
7086 "Query response value in deci-seconds\n")
7088 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7089 struct pim_interface
*pim_ifp
= ifp
->info
;
7090 int query_max_response_time
;
7094 ret
= pim_cmd_igmp_start(vty
, ifp
);
7095 if (ret
!= CMD_SUCCESS
)
7097 pim_ifp
= ifp
->info
;
7100 query_max_response_time
= atoi(argv
[3]->arg
);
7102 if (query_max_response_time
7103 >= pim_ifp
->igmp_default_query_interval
* 10) {
7105 "Can't set query max response time %d sec >= general query interval %d sec\n",
7106 query_max_response_time
,
7107 pim_ifp
->igmp_default_query_interval
);
7108 return CMD_WARNING_CONFIG_FAILED
;
7111 change_query_max_response_time(pim_ifp
, query_max_response_time
);
7116 DEFUN (interface_no_ip_igmp_query_max_response_time
,
7117 interface_no_ip_igmp_query_max_response_time_cmd
,
7118 "no ip igmp query-max-response-time (10-250)",
7122 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
7123 "Time for response in deci-seconds\n")
7125 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7126 struct pim_interface
*pim_ifp
= ifp
->info
;
7131 change_query_max_response_time(pim_ifp
,
7132 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
7137 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
7138 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
7140 DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec
,
7141 interface_ip_igmp_query_max_response_time_dsec_cmd
,
7142 "ip igmp query-max-response-time-dsec (10-250)",
7145 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
7146 "Query response value in deciseconds\n")
7148 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7149 struct pim_interface
*pim_ifp
= ifp
->info
;
7150 int query_max_response_time_dsec
;
7151 int default_query_interval_dsec
;
7155 ret
= pim_cmd_igmp_start(vty
, ifp
);
7156 if (ret
!= CMD_SUCCESS
)
7158 pim_ifp
= ifp
->info
;
7161 query_max_response_time_dsec
= atoi(argv
[4]->arg
);
7163 default_query_interval_dsec
= 10 * pim_ifp
->igmp_default_query_interval
;
7165 if (query_max_response_time_dsec
>= default_query_interval_dsec
) {
7167 "Can't set query max response time %d dsec >= general query interval %d dsec\n",
7168 query_max_response_time_dsec
,
7169 default_query_interval_dsec
);
7170 return CMD_WARNING_CONFIG_FAILED
;
7173 change_query_max_response_time(pim_ifp
, query_max_response_time_dsec
);
7178 DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec
,
7179 interface_no_ip_igmp_query_max_response_time_dsec_cmd
,
7180 "no ip igmp query-max-response-time-dsec",
7184 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
)
7186 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7187 struct pim_interface
*pim_ifp
= ifp
->info
;
7192 change_query_max_response_time(pim_ifp
,
7193 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
7198 #define IGMP_LAST_MEMBER_QUERY_COUNT_MIN (1)
7199 #define IGMP_LAST_MEMBER_QUERY_COUNT_MAX (7)
7201 DEFUN (interface_ip_igmp_last_member_query_count
,
7202 interface_ip_igmp_last_member_query_count_cmd
,
7203 "ip igmp last-member-query-count (1-7)",
7206 IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR
7207 "Last member query count\n")
7209 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7210 struct pim_interface
*pim_ifp
= ifp
->info
;
7211 int last_member_query_count
;
7215 ret
= pim_cmd_igmp_start(vty
, ifp
);
7216 if (ret
!= CMD_SUCCESS
)
7218 pim_ifp
= ifp
->info
;
7221 last_member_query_count
= atoi(argv
[3]->arg
);
7223 pim_ifp
->igmp_last_member_query_count
= last_member_query_count
;
7228 DEFUN (interface_no_ip_igmp_last_member_query_count
,
7229 interface_no_ip_igmp_last_member_query_count_cmd
,
7230 "no ip igmp last-member-query-count",
7234 IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR
)
7236 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7237 struct pim_interface
*pim_ifp
= ifp
->info
;
7242 pim_ifp
->igmp_last_member_query_count
=
7243 IGMP_DEFAULT_ROBUSTNESS_VARIABLE
;
7248 #define IGMP_LAST_MEMBER_QUERY_INTERVAL_MIN (1)
7249 #define IGMP_LAST_MEMBER_QUERY_INTERVAL_MAX (255)
7251 DEFUN (interface_ip_igmp_last_member_query_interval
,
7252 interface_ip_igmp_last_member_query_interval_cmd
,
7253 "ip igmp last-member-query-interval (1-255)",
7256 IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR
7257 "Last member query interval in deciseconds\n")
7259 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7260 struct pim_interface
*pim_ifp
= ifp
->info
;
7261 int last_member_query_interval
;
7265 ret
= pim_cmd_igmp_start(vty
, ifp
);
7266 if (ret
!= CMD_SUCCESS
)
7268 pim_ifp
= ifp
->info
;
7271 last_member_query_interval
= atoi(argv
[3]->arg
);
7272 pim_ifp
->igmp_specific_query_max_response_time_dsec
7273 = last_member_query_interval
;
7278 DEFUN (interface_no_ip_igmp_last_member_query_interval
,
7279 interface_no_ip_igmp_last_member_query_interval_cmd
,
7280 "no ip igmp last-member-query-interval",
7284 IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR
)
7286 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7287 struct pim_interface
*pim_ifp
= ifp
->info
;
7292 pim_ifp
->igmp_specific_query_max_response_time_dsec
=
7293 IGMP_SPECIFIC_QUERY_MAX_RESPONSE_TIME_DSEC
;
7298 DEFUN (interface_ip_pim_drprio
,
7299 interface_ip_pim_drprio_cmd
,
7300 "ip pim drpriority (1-4294967295)",
7303 "Set the Designated Router Election Priority\n"
7304 "Value of the new DR Priority\n")
7306 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7308 struct pim_interface
*pim_ifp
= ifp
->info
;
7309 uint32_t old_dr_prio
;
7312 vty_out(vty
, "Please enable PIM on interface, first\n");
7313 return CMD_WARNING_CONFIG_FAILED
;
7316 old_dr_prio
= pim_ifp
->pim_dr_priority
;
7318 pim_ifp
->pim_dr_priority
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
7320 if (old_dr_prio
!= pim_ifp
->pim_dr_priority
) {
7321 pim_if_dr_election(ifp
);
7322 pim_hello_restart_now(ifp
);
7328 DEFUN (interface_no_ip_pim_drprio
,
7329 interface_no_ip_pim_drprio_cmd
,
7330 "no ip pim drpriority [(1-4294967295)]",
7334 "Revert the Designated Router Priority to default\n"
7335 "Old Value of the Priority\n")
7337 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7338 struct pim_interface
*pim_ifp
= ifp
->info
;
7341 vty_out(vty
, "Pim not enabled on this interface\n");
7342 return CMD_WARNING_CONFIG_FAILED
;
7345 if (pim_ifp
->pim_dr_priority
!= PIM_DEFAULT_DR_PRIORITY
) {
7346 pim_ifp
->pim_dr_priority
= PIM_DEFAULT_DR_PRIORITY
;
7347 pim_if_dr_election(ifp
);
7348 pim_hello_restart_now(ifp
);
7354 DEFPY_HIDDEN (interface_ip_igmp_query_generate
,
7355 interface_ip_igmp_query_generate_cmd
,
7356 "ip igmp generate-query-once [version (2-3)]",
7359 "Generate igmp general query once\n"
7361 "IGMP version number\n")
7363 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7364 int igmp_version
= 2;
7367 vty_out(vty
, "IGMP/PIM is not enabled on the interface %s\n",
7369 return CMD_WARNING_CONFIG_FAILED
;
7373 igmp_version
= atoi(argv
[4]->arg
);
7375 igmp_send_query_on_intf(ifp
, igmp_version
);
7380 static int pim_cmd_interface_add(struct interface
*ifp
)
7382 struct pim_interface
*pim_ifp
= ifp
->info
;
7385 pim_ifp
= pim_if_new(ifp
, false, true, false, false);
7387 PIM_IF_DO_PIM(pim_ifp
->options
);
7389 pim_if_addr_add_all(ifp
);
7390 pim_if_membership_refresh(ifp
);
7392 pim_if_create_pimreg(pim_ifp
->pim
);
7396 DEFPY_HIDDEN (pim_test_sg_keepalive
,
7397 pim_test_sg_keepalive_cmd
,
7398 "test pim [vrf NAME$name] keepalive-reset A.B.C.D$source A.B.C.D$group",
7402 "Reset the Keepalive Timer\n"
7403 "The Source we are resetting\n"
7404 "The Group we are resetting\n")
7406 struct pim_upstream
*up
;
7407 struct pim_instance
*pim
;
7408 struct prefix_sg sg
;
7414 pim
= pim_get_pim_instance(VRF_DEFAULT
);
7416 struct vrf
*vrf
= vrf_lookup_by_name(name
);
7419 vty_out(vty
, "%% Vrf specified: %s does not exist\n",
7424 pim
= pim_get_pim_instance(vrf
->vrf_id
);
7428 vty_out(vty
, "%% Unable to find pim instance\n");
7432 up
= pim_upstream_find(pim
, &sg
);
7434 vty_out(vty
, "%% Unable to find %s specified\n",
7435 pim_str_sg_dump(&sg
));
7439 vty_out(vty
, "Setting %s to current keep alive time: %d\n",
7440 pim_str_sg_dump(&sg
), pim
->keep_alive_time
);
7441 pim_upstream_keep_alive_timer_start(up
, pim
->keep_alive_time
);
7446 DEFPY_HIDDEN (interface_ip_pim_activeactive
,
7447 interface_ip_pim_activeactive_cmd
,
7448 "[no$no] ip pim active-active",
7452 "Mark interface as Active-Active for MLAG operations, Hidden because not finished yet\n")
7454 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7455 struct pim_interface
*pim_ifp
;
7457 if (!no
&& !pim_cmd_interface_add(ifp
)) {
7458 vty_out(vty
, "Could not enable PIM SM active-active on interface\n");
7459 return CMD_WARNING_CONFIG_FAILED
;
7462 pim_ifp
= ifp
->info
;
7464 pim_if_unconfigure_mlag_dualactive(pim_ifp
);
7466 pim_if_configure_mlag_dualactive(pim_ifp
);
7471 DEFUN_HIDDEN (interface_ip_pim_ssm
,
7472 interface_ip_pim_ssm_cmd
,
7478 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7480 if (!pim_cmd_interface_add(ifp
)) {
7481 vty_out(vty
, "Could not enable PIM SM on interface\n");
7482 return CMD_WARNING_CONFIG_FAILED
;
7486 "WARN: Enabled PIM SM on interface; configure PIM SSM "
7487 "range if needed\n");
7491 static int interface_ip_pim_helper(struct vty
*vty
)
7493 struct pim_interface
*pim_ifp
;
7495 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7497 if (!pim_cmd_interface_add(ifp
)) {
7498 vty_out(vty
, "Could not enable PIM SM on interface\n");
7499 return CMD_WARNING_CONFIG_FAILED
;
7502 pim_ifp
= ifp
->info
;
7504 pim_if_create_pimreg(pim_ifp
->pim
);
7509 DEFUN_HIDDEN (interface_ip_pim_sm
,
7510 interface_ip_pim_sm_cmd
,
7516 return interface_ip_pim_helper(vty
);
7519 DEFUN (interface_ip_pim
,
7520 interface_ip_pim_cmd
,
7525 return interface_ip_pim_helper(vty
);
7528 static int pim_cmd_interface_delete(struct interface
*ifp
)
7530 struct pim_interface
*pim_ifp
= ifp
->info
;
7535 PIM_IF_DONT_PIM(pim_ifp
->options
);
7537 pim_if_membership_clear(ifp
);
7540 pim_sock_delete() removes all neighbors from
7541 pim_ifp->pim_neighbor_list.
7543 pim_sock_delete(ifp
, "pim unconfigured on interface");
7545 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
7546 pim_if_addr_del_all(ifp
);
7553 static int interface_no_ip_pim_helper(struct vty
*vty
)
7555 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7556 if (!pim_cmd_interface_delete(ifp
)) {
7557 vty_out(vty
, "Unable to delete interface information\n");
7558 return CMD_WARNING_CONFIG_FAILED
;
7564 DEFUN_HIDDEN (interface_no_ip_pim_ssm
,
7565 interface_no_ip_pim_ssm_cmd
,
7572 return interface_no_ip_pim_helper(vty
);
7575 DEFUN_HIDDEN (interface_no_ip_pim_sm
,
7576 interface_no_ip_pim_sm_cmd
,
7583 return interface_no_ip_pim_helper(vty
);
7586 DEFUN (interface_no_ip_pim
,
7587 interface_no_ip_pim_cmd
,
7593 return interface_no_ip_pim_helper(vty
);
7597 DEFUN(interface_ip_pim_boundary_oil
,
7598 interface_ip_pim_boundary_oil_cmd
,
7599 "ip multicast boundary oil WORD",
7601 "Generic multicast configuration options\n"
7602 "Define multicast boundary\n"
7603 "Filter OIL by group using prefix list\n"
7604 "Prefix list to filter OIL with\n")
7606 VTY_DECLVAR_CONTEXT(interface
, iif
);
7607 struct pim_interface
*pim_ifp
;
7610 argv_find(argv
, argc
, "WORD", &idx
);
7612 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
7614 if (pim_ifp
->boundary_oil_plist
)
7615 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
7617 pim_ifp
->boundary_oil_plist
=
7618 XSTRDUP(MTYPE_PIM_INTERFACE
, argv
[idx
]->arg
);
7620 /* Interface will be pruned from OIL on next Join */
7624 DEFUN(interface_no_ip_pim_boundary_oil
,
7625 interface_no_ip_pim_boundary_oil_cmd
,
7626 "no ip multicast boundary oil [WORD]",
7629 "Generic multicast configuration options\n"
7630 "Define multicast boundary\n"
7631 "Filter OIL by group using prefix list\n"
7632 "Prefix list to filter OIL with\n")
7634 VTY_DECLVAR_CONTEXT(interface
, iif
);
7635 struct pim_interface
*pim_ifp
;
7638 argv_find(argv
, argc
, "WORD", &idx
);
7640 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
7642 if (pim_ifp
->boundary_oil_plist
)
7643 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
7648 DEFUN (interface_ip_mroute
,
7649 interface_ip_mroute_cmd
,
7650 "ip mroute INTERFACE A.B.C.D",
7652 "Add multicast route\n"
7653 "Outgoing interface name\n"
7656 VTY_DECLVAR_CONTEXT(interface
, iif
);
7657 struct pim_interface
*pim_ifp
;
7658 struct pim_instance
*pim
;
7659 int idx_interface
= 2;
7661 struct interface
*oif
;
7662 const char *oifname
;
7663 const char *grp_str
;
7664 struct in_addr grp_addr
;
7665 struct in_addr src_addr
;
7668 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
7671 oifname
= argv
[idx_interface
]->arg
;
7672 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
7674 vty_out(vty
, "No such interface name %s\n", oifname
);
7678 grp_str
= argv
[idx_ipv4
]->arg
;
7679 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
7681 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
7682 errno
, safe_strerror(errno
));
7686 src_addr
.s_addr
= INADDR_ANY
;
7688 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
7689 vty_out(vty
, "Failed to add route\n");
7696 DEFUN (interface_ip_mroute_source
,
7697 interface_ip_mroute_source_cmd
,
7698 "ip mroute INTERFACE A.B.C.D A.B.C.D",
7700 "Add multicast route\n"
7701 "Outgoing interface name\n"
7705 VTY_DECLVAR_CONTEXT(interface
, iif
);
7706 struct pim_interface
*pim_ifp
;
7707 struct pim_instance
*pim
;
7708 int idx_interface
= 2;
7711 struct interface
*oif
;
7712 const char *oifname
;
7713 const char *grp_str
;
7714 struct in_addr grp_addr
;
7715 const char *src_str
;
7716 struct in_addr src_addr
;
7719 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
7722 oifname
= argv
[idx_interface
]->arg
;
7723 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
7725 vty_out(vty
, "No such interface name %s\n", oifname
);
7729 grp_str
= argv
[idx_ipv4
]->arg
;
7730 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
7732 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
7733 errno
, safe_strerror(errno
));
7737 src_str
= argv
[idx_ipv4_2
]->arg
;
7738 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
7740 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
7741 errno
, safe_strerror(errno
));
7745 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
7746 vty_out(vty
, "Failed to add route\n");
7753 DEFUN (interface_no_ip_mroute
,
7754 interface_no_ip_mroute_cmd
,
7755 "no ip mroute INTERFACE A.B.C.D",
7758 "Add multicast route\n"
7759 "Outgoing interface name\n"
7762 VTY_DECLVAR_CONTEXT(interface
, iif
);
7763 struct pim_interface
*pim_ifp
;
7764 struct pim_instance
*pim
;
7765 int idx_interface
= 3;
7767 struct interface
*oif
;
7768 const char *oifname
;
7769 const char *grp_str
;
7770 struct in_addr grp_addr
;
7771 struct in_addr src_addr
;
7774 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
7777 oifname
= argv
[idx_interface
]->arg
;
7778 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
7780 vty_out(vty
, "No such interface name %s\n", oifname
);
7784 grp_str
= argv
[idx_ipv4
]->arg
;
7785 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
7787 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
7788 errno
, safe_strerror(errno
));
7792 src_addr
.s_addr
= INADDR_ANY
;
7794 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
7795 vty_out(vty
, "Failed to remove route\n");
7802 DEFUN (interface_no_ip_mroute_source
,
7803 interface_no_ip_mroute_source_cmd
,
7804 "no ip mroute INTERFACE A.B.C.D A.B.C.D",
7807 "Add multicast route\n"
7808 "Outgoing interface name\n"
7812 VTY_DECLVAR_CONTEXT(interface
, iif
);
7813 struct pim_interface
*pim_ifp
;
7814 struct pim_instance
*pim
;
7815 int idx_interface
= 3;
7818 struct interface
*oif
;
7819 const char *oifname
;
7820 const char *grp_str
;
7821 struct in_addr grp_addr
;
7822 const char *src_str
;
7823 struct in_addr src_addr
;
7826 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
7829 oifname
= argv
[idx_interface
]->arg
;
7830 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
7832 vty_out(vty
, "No such interface name %s\n", oifname
);
7836 grp_str
= argv
[idx_ipv4
]->arg
;
7837 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
7839 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
7840 errno
, safe_strerror(errno
));
7844 src_str
= argv
[idx_ipv4_2
]->arg
;
7845 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
7847 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
7848 errno
, safe_strerror(errno
));
7852 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
7853 vty_out(vty
, "Failed to remove route\n");
7860 DEFUN (interface_ip_pim_hello
,
7861 interface_ip_pim_hello_cmd
,
7862 "ip pim hello (1-180) [(1-180)]",
7866 IFACE_PIM_HELLO_TIME_STR
7867 IFACE_PIM_HELLO_HOLD_STR
)
7869 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7872 struct pim_interface
*pim_ifp
= ifp
->info
;
7875 if (!pim_cmd_interface_add(ifp
)) {
7876 vty_out(vty
, "Could not enable PIM SM on interface\n");
7877 return CMD_WARNING_CONFIG_FAILED
;
7881 pim_ifp
= ifp
->info
;
7882 pim_ifp
->pim_hello_period
= strtol(argv
[idx_time
]->arg
, NULL
, 10);
7884 if (argc
== idx_hold
+ 1)
7885 pim_ifp
->pim_default_holdtime
=
7886 strtol(argv
[idx_hold
]->arg
, NULL
, 10);
7891 DEFUN (interface_no_ip_pim_hello
,
7892 interface_no_ip_pim_hello_cmd
,
7893 "no ip pim hello [(1-180) (1-180)]",
7898 IFACE_PIM_HELLO_TIME_STR
7899 IFACE_PIM_HELLO_HOLD_STR
)
7901 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7902 struct pim_interface
*pim_ifp
= ifp
->info
;
7905 vty_out(vty
, "Pim not enabled on this interface\n");
7906 return CMD_WARNING_CONFIG_FAILED
;
7909 pim_ifp
->pim_hello_period
= PIM_DEFAULT_HELLO_PERIOD
;
7910 pim_ifp
->pim_default_holdtime
= -1;
7921 PIM_DO_DEBUG_IGMP_EVENTS
;
7922 PIM_DO_DEBUG_IGMP_PACKETS
;
7923 PIM_DO_DEBUG_IGMP_TRACE
;
7927 DEFUN (no_debug_igmp
,
7934 PIM_DONT_DEBUG_IGMP_EVENTS
;
7935 PIM_DONT_DEBUG_IGMP_PACKETS
;
7936 PIM_DONT_DEBUG_IGMP_TRACE
;
7941 DEFUN (debug_igmp_events
,
7942 debug_igmp_events_cmd
,
7943 "debug igmp events",
7946 DEBUG_IGMP_EVENTS_STR
)
7948 PIM_DO_DEBUG_IGMP_EVENTS
;
7952 DEFUN (no_debug_igmp_events
,
7953 no_debug_igmp_events_cmd
,
7954 "no debug igmp events",
7958 DEBUG_IGMP_EVENTS_STR
)
7960 PIM_DONT_DEBUG_IGMP_EVENTS
;
7965 DEFUN (debug_igmp_packets
,
7966 debug_igmp_packets_cmd
,
7967 "debug igmp packets",
7970 DEBUG_IGMP_PACKETS_STR
)
7972 PIM_DO_DEBUG_IGMP_PACKETS
;
7976 DEFUN (no_debug_igmp_packets
,
7977 no_debug_igmp_packets_cmd
,
7978 "no debug igmp packets",
7982 DEBUG_IGMP_PACKETS_STR
)
7984 PIM_DONT_DEBUG_IGMP_PACKETS
;
7989 DEFUN (debug_igmp_trace
,
7990 debug_igmp_trace_cmd
,
7994 DEBUG_IGMP_TRACE_STR
)
7996 PIM_DO_DEBUG_IGMP_TRACE
;
8000 DEFUN (no_debug_igmp_trace
,
8001 no_debug_igmp_trace_cmd
,
8002 "no debug igmp trace",
8006 DEBUG_IGMP_TRACE_STR
)
8008 PIM_DONT_DEBUG_IGMP_TRACE
;
8013 DEFUN (debug_mroute
,
8019 PIM_DO_DEBUG_MROUTE
;
8023 DEFUN (debug_mroute_detail
,
8024 debug_mroute_detail_cmd
,
8025 "debug mroute detail",
8030 PIM_DO_DEBUG_MROUTE_DETAIL
;
8034 DEFUN (no_debug_mroute
,
8035 no_debug_mroute_cmd
,
8041 PIM_DONT_DEBUG_MROUTE
;
8045 DEFUN (no_debug_mroute_detail
,
8046 no_debug_mroute_detail_cmd
,
8047 "no debug mroute detail",
8053 PIM_DONT_DEBUG_MROUTE_DETAIL
;
8057 DEFUN (debug_pim_static
,
8058 debug_pim_static_cmd
,
8064 PIM_DO_DEBUG_STATIC
;
8068 DEFUN (no_debug_pim_static
,
8069 no_debug_pim_static_cmd
,
8070 "no debug pim static",
8076 PIM_DONT_DEBUG_STATIC
;
8087 PIM_DO_DEBUG_PIM_EVENTS
;
8088 PIM_DO_DEBUG_PIM_PACKETS
;
8089 PIM_DO_DEBUG_PIM_TRACE
;
8090 PIM_DO_DEBUG_MSDP_EVENTS
;
8091 PIM_DO_DEBUG_MSDP_PACKETS
;
8096 DEFUN (no_debug_pim
,
8103 PIM_DONT_DEBUG_PIM_EVENTS
;
8104 PIM_DONT_DEBUG_PIM_PACKETS
;
8105 PIM_DONT_DEBUG_PIM_TRACE
;
8106 PIM_DONT_DEBUG_MSDP_EVENTS
;
8107 PIM_DONT_DEBUG_MSDP_PACKETS
;
8109 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
8110 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
8116 DEFUN (debug_pim_nht
,
8121 "Nexthop Tracking\n")
8123 PIM_DO_DEBUG_PIM_NHT
;
8127 DEFUN (no_debug_pim_nht
,
8128 no_debug_pim_nht_cmd
,
8133 "Nexthop Tracking\n")
8135 PIM_DONT_DEBUG_PIM_NHT
;
8139 DEFUN (debug_pim_nht_rp
,
8140 debug_pim_nht_rp_cmd
,
8144 "Nexthop Tracking\n"
8145 "RP Nexthop Tracking\n")
8147 PIM_DO_DEBUG_PIM_NHT_RP
;
8151 DEFUN (no_debug_pim_nht_rp
,
8152 no_debug_pim_nht_rp_cmd
,
8153 "no debug pim nht rp",
8157 "Nexthop Tracking\n"
8158 "RP Nexthop Tracking\n")
8160 PIM_DONT_DEBUG_PIM_NHT_RP
;
8164 DEFUN (debug_pim_events
,
8165 debug_pim_events_cmd
,
8169 DEBUG_PIM_EVENTS_STR
)
8171 PIM_DO_DEBUG_PIM_EVENTS
;
8175 DEFUN (no_debug_pim_events
,
8176 no_debug_pim_events_cmd
,
8177 "no debug pim events",
8181 DEBUG_PIM_EVENTS_STR
)
8183 PIM_DONT_DEBUG_PIM_EVENTS
;
8187 DEFUN (debug_pim_packets
,
8188 debug_pim_packets_cmd
,
8189 "debug pim packets [<hello|joins|register>]",
8192 DEBUG_PIM_PACKETS_STR
8193 DEBUG_PIM_HELLO_PACKETS_STR
8194 DEBUG_PIM_J_P_PACKETS_STR
8195 DEBUG_PIM_PIM_REG_PACKETS_STR
)
8198 if (argv_find(argv
, argc
, "hello", &idx
)) {
8199 PIM_DO_DEBUG_PIM_HELLO
;
8200 vty_out(vty
, "PIM Hello debugging is on\n");
8201 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
8202 PIM_DO_DEBUG_PIM_J_P
;
8203 vty_out(vty
, "PIM Join/Prune debugging is on\n");
8204 } else if (argv_find(argv
, argc
, "register", &idx
)) {
8205 PIM_DO_DEBUG_PIM_REG
;
8206 vty_out(vty
, "PIM Register debugging is on\n");
8208 PIM_DO_DEBUG_PIM_PACKETS
;
8209 vty_out(vty
, "PIM Packet debugging is on \n");
8214 DEFUN (no_debug_pim_packets
,
8215 no_debug_pim_packets_cmd
,
8216 "no debug pim packets [<hello|joins|register>]",
8220 DEBUG_PIM_PACKETS_STR
8221 DEBUG_PIM_HELLO_PACKETS_STR
8222 DEBUG_PIM_J_P_PACKETS_STR
8223 DEBUG_PIM_PIM_REG_PACKETS_STR
)
8226 if (argv_find(argv
, argc
, "hello", &idx
)) {
8227 PIM_DONT_DEBUG_PIM_HELLO
;
8228 vty_out(vty
, "PIM Hello debugging is off \n");
8229 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
8230 PIM_DONT_DEBUG_PIM_J_P
;
8231 vty_out(vty
, "PIM Join/Prune debugging is off \n");
8232 } else if (argv_find(argv
, argc
, "register", &idx
)) {
8233 PIM_DONT_DEBUG_PIM_REG
;
8234 vty_out(vty
, "PIM Register debugging is off\n");
8236 PIM_DONT_DEBUG_PIM_PACKETS
;
8242 DEFUN (debug_pim_packetdump_send
,
8243 debug_pim_packetdump_send_cmd
,
8244 "debug pim packet-dump send",
8247 DEBUG_PIM_PACKETDUMP_STR
8248 DEBUG_PIM_PACKETDUMP_SEND_STR
)
8250 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND
;
8254 DEFUN (no_debug_pim_packetdump_send
,
8255 no_debug_pim_packetdump_send_cmd
,
8256 "no debug pim packet-dump send",
8260 DEBUG_PIM_PACKETDUMP_STR
8261 DEBUG_PIM_PACKETDUMP_SEND_STR
)
8263 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
8267 DEFUN (debug_pim_packetdump_recv
,
8268 debug_pim_packetdump_recv_cmd
,
8269 "debug pim packet-dump receive",
8272 DEBUG_PIM_PACKETDUMP_STR
8273 DEBUG_PIM_PACKETDUMP_RECV_STR
)
8275 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV
;
8279 DEFUN (no_debug_pim_packetdump_recv
,
8280 no_debug_pim_packetdump_recv_cmd
,
8281 "no debug pim packet-dump receive",
8285 DEBUG_PIM_PACKETDUMP_STR
8286 DEBUG_PIM_PACKETDUMP_RECV_STR
)
8288 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
8292 DEFUN (debug_pim_trace
,
8293 debug_pim_trace_cmd
,
8297 DEBUG_PIM_TRACE_STR
)
8299 PIM_DO_DEBUG_PIM_TRACE
;
8303 DEFUN (debug_pim_trace_detail
,
8304 debug_pim_trace_detail_cmd
,
8305 "debug pim trace detail",
8309 "Detailed Information\n")
8311 PIM_DO_DEBUG_PIM_TRACE_DETAIL
;
8315 DEFUN (no_debug_pim_trace
,
8316 no_debug_pim_trace_cmd
,
8317 "no debug pim trace",
8321 DEBUG_PIM_TRACE_STR
)
8323 PIM_DONT_DEBUG_PIM_TRACE
;
8327 DEFUN (no_debug_pim_trace_detail
,
8328 no_debug_pim_trace_detail_cmd
,
8329 "no debug pim trace detail",
8334 "Detailed Information\n")
8336 PIM_DONT_DEBUG_PIM_TRACE_DETAIL
;
8340 DEFUN (debug_ssmpingd
,
8346 PIM_DO_DEBUG_SSMPINGD
;
8350 DEFUN (no_debug_ssmpingd
,
8351 no_debug_ssmpingd_cmd
,
8352 "no debug ssmpingd",
8357 PIM_DONT_DEBUG_SSMPINGD
;
8361 DEFUN (debug_pim_zebra
,
8362 debug_pim_zebra_cmd
,
8366 DEBUG_PIM_ZEBRA_STR
)
8372 DEFUN (no_debug_pim_zebra
,
8373 no_debug_pim_zebra_cmd
,
8374 "no debug pim zebra",
8378 DEBUG_PIM_ZEBRA_STR
)
8380 PIM_DONT_DEBUG_ZEBRA
;
8384 DEFUN(debug_pim_mlag
, debug_pim_mlag_cmd
, "debug pim mlag",
8385 DEBUG_STR DEBUG_PIM_STR DEBUG_PIM_MLAG_STR
)
8391 DEFUN(no_debug_pim_mlag
, no_debug_pim_mlag_cmd
, "no debug pim mlag",
8392 NO_STR DEBUG_STR DEBUG_PIM_STR DEBUG_PIM_MLAG_STR
)
8394 PIM_DONT_DEBUG_MLAG
;
8398 DEFUN (debug_pim_vxlan
,
8399 debug_pim_vxlan_cmd
,
8403 DEBUG_PIM_VXLAN_STR
)
8409 DEFUN (no_debug_pim_vxlan
,
8410 no_debug_pim_vxlan_cmd
,
8411 "no debug pim vxlan",
8415 DEBUG_PIM_VXLAN_STR
)
8417 PIM_DONT_DEBUG_VXLAN
;
8427 PIM_DO_DEBUG_MSDP_EVENTS
;
8428 PIM_DO_DEBUG_MSDP_PACKETS
;
8432 DEFUN (no_debug_msdp
,
8439 PIM_DONT_DEBUG_MSDP_EVENTS
;
8440 PIM_DONT_DEBUG_MSDP_PACKETS
;
8444 DEFUN (debug_msdp_events
,
8445 debug_msdp_events_cmd
,
8446 "debug msdp events",
8449 DEBUG_MSDP_EVENTS_STR
)
8451 PIM_DO_DEBUG_MSDP_EVENTS
;
8455 DEFUN (no_debug_msdp_events
,
8456 no_debug_msdp_events_cmd
,
8457 "no debug msdp events",
8461 DEBUG_MSDP_EVENTS_STR
)
8463 PIM_DONT_DEBUG_MSDP_EVENTS
;
8467 DEFUN (debug_msdp_packets
,
8468 debug_msdp_packets_cmd
,
8469 "debug msdp packets",
8472 DEBUG_MSDP_PACKETS_STR
)
8474 PIM_DO_DEBUG_MSDP_PACKETS
;
8478 DEFUN (no_debug_msdp_packets
,
8479 no_debug_msdp_packets_cmd
,
8480 "no debug msdp packets",
8484 DEBUG_MSDP_PACKETS_STR
)
8486 PIM_DONT_DEBUG_MSDP_PACKETS
;
8490 DEFUN (debug_mtrace
,
8496 PIM_DO_DEBUG_MTRACE
;
8500 DEFUN (no_debug_mtrace
,
8501 no_debug_mtrace_cmd
,
8507 PIM_DONT_DEBUG_MTRACE
;
8522 DEFUN (no_debug_bsm
,
8535 DEFUN_NOSH (show_debugging_pim
,
8536 show_debugging_pim_cmd
,
8537 "show debugging [pim]",
8542 vty_out(vty
, "PIM debugging status\n");
8544 pim_debug_config_write(vty
);
8549 static int interface_pim_use_src_cmd_worker(struct vty
*vty
, const char *source
)
8552 struct in_addr source_addr
;
8553 int ret
= CMD_SUCCESS
;
8554 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8556 result
= inet_pton(AF_INET
, source
, &source_addr
);
8558 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", source
,
8559 errno
, safe_strerror(errno
));
8560 return CMD_WARNING_CONFIG_FAILED
;
8563 result
= pim_update_source_set(ifp
, source_addr
);
8567 case PIM_IFACE_NOT_FOUND
:
8568 ret
= CMD_WARNING_CONFIG_FAILED
;
8569 vty_out(vty
, "Pim not enabled on this interface\n");
8571 case PIM_UPDATE_SOURCE_DUP
:
8573 vty_out(vty
, "%% Source already set to %s\n", source
);
8576 ret
= CMD_WARNING_CONFIG_FAILED
;
8577 vty_out(vty
, "%% Source set failed\n");
8583 DEFUN (interface_pim_use_source
,
8584 interface_pim_use_source_cmd
,
8585 "ip pim use-source A.B.C.D",
8588 "Configure primary IP address\n"
8589 "source ip address\n")
8591 return interface_pim_use_src_cmd_worker(vty
, argv
[3]->arg
);
8594 DEFUN (interface_no_pim_use_source
,
8595 interface_no_pim_use_source_cmd
,
8596 "no ip pim use-source [A.B.C.D]",
8600 "Delete source IP address\n"
8601 "source ip address\n")
8603 return interface_pim_use_src_cmd_worker(vty
, "0.0.0.0");
8611 "Enables BFD support\n")
8613 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8614 struct pim_interface
*pim_ifp
= ifp
->info
;
8615 struct bfd_info
*bfd_info
= NULL
;
8618 if (!pim_cmd_interface_add(ifp
)) {
8619 vty_out(vty
, "Could not enable PIM SM on interface\n");
8623 pim_ifp
= ifp
->info
;
8625 bfd_info
= pim_ifp
->bfd_info
;
8627 if (!bfd_info
|| !CHECK_FLAG(bfd_info
->flags
, BFD_FLAG_PARAM_CFG
))
8628 pim_bfd_if_param_set(ifp
, BFD_DEF_MIN_RX
, BFD_DEF_MIN_TX
,
8629 BFD_DEF_DETECT_MULT
, 1);
8634 DEFUN (no_ip_pim_bfd
,
8640 "Disables BFD support\n")
8642 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8643 struct pim_interface
*pim_ifp
= ifp
->info
;
8646 vty_out(vty
, "Pim not enabled on this interface\n");
8650 if (pim_ifp
->bfd_info
) {
8651 pim_bfd_reg_dereg_all_nbr(ifp
, ZEBRA_BFD_DEST_DEREGISTER
);
8652 bfd_info_free(&(pim_ifp
->bfd_info
));
8663 "Enables BSM support on the interface\n")
8665 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8666 struct pim_interface
*pim_ifp
= ifp
->info
;
8669 if (!pim_cmd_interface_add(ifp
)) {
8670 vty_out(vty
, "Could not enable PIM SM on interface\n");
8675 pim_ifp
= ifp
->info
;
8676 pim_ifp
->bsm_enable
= true;
8681 DEFUN (no_ip_pim_bsm
,
8687 "Disables BSM support\n")
8689 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8690 struct pim_interface
*pim_ifp
= ifp
->info
;
8693 vty_out(vty
, "Pim not enabled on this interface\n");
8697 pim_ifp
->bsm_enable
= false;
8702 DEFUN (ip_pim_ucast_bsm
,
8703 ip_pim_ucast_bsm_cmd
,
8704 "ip pim unicast-bsm",
8707 "Accept/Send unicast BSM on the interface\n")
8709 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8710 struct pim_interface
*pim_ifp
= ifp
->info
;
8713 if (!pim_cmd_interface_add(ifp
)) {
8714 vty_out(vty
, "Could not enable PIM SM on interface\n");
8719 pim_ifp
= ifp
->info
;
8720 pim_ifp
->ucast_bsm_accept
= true;
8725 DEFUN (no_ip_pim_ucast_bsm
,
8726 no_ip_pim_ucast_bsm_cmd
,
8727 "no ip pim unicast-bsm",
8731 "Block send/receive unicast BSM on this interface\n")
8733 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8734 struct pim_interface
*pim_ifp
= ifp
->info
;
8737 vty_out(vty
, "Pim not enabled on this interface\n");
8741 pim_ifp
->ucast_bsm_accept
= false;
8749 ip_pim_bfd_param_cmd
,
8750 "ip pim bfd (2-255) (50-60000) (50-60000)",
8753 "Enables BFD support\n"
8754 "Detect Multiplier\n"
8755 "Required min receive interval\n"
8756 "Desired min transmit interval\n")
8760 ip_pim_bfd_param_cmd
,
8761 "ip pim bfd (2-255) (50-60000) (50-60000)",
8764 "Enables BFD support\n"
8765 "Detect Multiplier\n"
8766 "Required min receive interval\n"
8767 "Desired min transmit interval\n")
8768 #endif /* HAVE_BFDD */
8770 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8772 int idx_number_2
= 4;
8773 int idx_number_3
= 5;
8778 struct pim_interface
*pim_ifp
= ifp
->info
;
8781 if (!pim_cmd_interface_add(ifp
)) {
8782 vty_out(vty
, "Could not enable PIM SM on interface\n");
8787 if ((ret
= bfd_validate_param(
8788 vty
, argv
[idx_number
]->arg
, argv
[idx_number_2
]->arg
,
8789 argv
[idx_number_3
]->arg
, &dm_val
, &rx_val
, &tx_val
))
8793 pim_bfd_if_param_set(ifp
, rx_val
, tx_val
, dm_val
, 0);
8799 ALIAS(no_ip_pim_bfd
, no_ip_pim_bfd_param_cmd
,
8800 "no ip pim bfd (2-255) (50-60000) (50-60000)", NO_STR IP_STR PIM_STR
8801 "Enables BFD support\n"
8802 "Detect Multiplier\n"
8803 "Required min receive interval\n"
8804 "Desired min transmit interval\n")
8805 #endif /* !HAVE_BFDD */
8807 static int ip_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
8808 const char *peer
, const char *local
)
8810 enum pim_msdp_err result
;
8811 struct in_addr peer_addr
;
8812 struct in_addr local_addr
;
8813 int ret
= CMD_SUCCESS
;
8815 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
8817 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
8818 errno
, safe_strerror(errno
));
8819 return CMD_WARNING_CONFIG_FAILED
;
8822 result
= inet_pton(AF_INET
, local
, &local_addr
);
8824 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", local
,
8825 errno
, safe_strerror(errno
));
8826 return CMD_WARNING_CONFIG_FAILED
;
8829 result
= pim_msdp_peer_add(pim
, peer_addr
, local_addr
, "default",
8832 case PIM_MSDP_ERR_NONE
:
8834 case PIM_MSDP_ERR_OOM
:
8835 ret
= CMD_WARNING_CONFIG_FAILED
;
8836 vty_out(vty
, "%% Out of memory\n");
8838 case PIM_MSDP_ERR_PEER_EXISTS
:
8840 vty_out(vty
, "%% Peer exists\n");
8842 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
8843 ret
= CMD_WARNING_CONFIG_FAILED
;
8844 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
8847 ret
= CMD_WARNING_CONFIG_FAILED
;
8848 vty_out(vty
, "%% peer add failed\n");
8854 DEFUN_HIDDEN (ip_msdp_peer
,
8856 "ip msdp peer A.B.C.D source A.B.C.D",
8859 "Configure MSDP peer\n"
8861 "Source address for TCP connection\n"
8862 "local ip address\n")
8864 PIM_DECLVAR_CONTEXT(vrf
, pim
);
8865 return ip_msdp_peer_cmd_worker(pim
, vty
, argv
[3]->arg
, argv
[5]->arg
);
8868 static int ip_no_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
8871 enum pim_msdp_err result
;
8872 struct in_addr peer_addr
;
8874 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
8876 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
8877 errno
, safe_strerror(errno
));
8878 return CMD_WARNING_CONFIG_FAILED
;
8881 result
= pim_msdp_peer_del(pim
, peer_addr
);
8883 case PIM_MSDP_ERR_NONE
:
8885 case PIM_MSDP_ERR_NO_PEER
:
8886 vty_out(vty
, "%% Peer does not exist\n");
8889 vty_out(vty
, "%% peer del failed\n");
8892 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
8895 DEFUN_HIDDEN (no_ip_msdp_peer
,
8896 no_ip_msdp_peer_cmd
,
8897 "no ip msdp peer A.B.C.D",
8901 "Delete MSDP peer\n"
8902 "peer ip address\n")
8904 PIM_DECLVAR_CONTEXT(vrf
, pim
);
8905 return ip_no_msdp_peer_cmd_worker(pim
, vty
, argv
[4]->arg
);
8908 static int ip_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
8909 struct vty
*vty
, const char *mg
,
8912 enum pim_msdp_err result
;
8913 struct in_addr mbr_ip
;
8914 int ret
= CMD_SUCCESS
;
8916 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
8918 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
8919 errno
, safe_strerror(errno
));
8920 return CMD_WARNING_CONFIG_FAILED
;
8923 result
= pim_msdp_mg_mbr_add(pim
, mg
, mbr_ip
);
8925 case PIM_MSDP_ERR_NONE
:
8927 case PIM_MSDP_ERR_OOM
:
8928 ret
= CMD_WARNING_CONFIG_FAILED
;
8929 vty_out(vty
, "%% Out of memory\n");
8931 case PIM_MSDP_ERR_MG_MBR_EXISTS
:
8933 vty_out(vty
, "%% mesh-group member exists\n");
8935 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
8936 ret
= CMD_WARNING_CONFIG_FAILED
;
8937 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
8940 ret
= CMD_WARNING_CONFIG_FAILED
;
8941 vty_out(vty
, "%% member add failed\n");
8947 DEFUN (ip_msdp_mesh_group_member
,
8948 ip_msdp_mesh_group_member_cmd
,
8949 "ip msdp mesh-group WORD member A.B.C.D",
8952 "Configure MSDP mesh-group\n"
8954 "mesh group member\n"
8955 "peer ip address\n")
8957 PIM_DECLVAR_CONTEXT(vrf
, pim
);
8958 return ip_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[3]->arg
,
8962 static int ip_no_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
8967 enum pim_msdp_err result
;
8968 struct in_addr mbr_ip
;
8970 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
8972 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
8973 errno
, safe_strerror(errno
));
8974 return CMD_WARNING_CONFIG_FAILED
;
8977 result
= pim_msdp_mg_mbr_del(pim
, mg
, mbr_ip
);
8979 case PIM_MSDP_ERR_NONE
:
8981 case PIM_MSDP_ERR_NO_MG
:
8982 vty_out(vty
, "%% mesh-group does not exist\n");
8984 case PIM_MSDP_ERR_NO_MG_MBR
:
8985 vty_out(vty
, "%% mesh-group member does not exist\n");
8988 vty_out(vty
, "%% mesh-group member del failed\n");
8991 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
8993 DEFUN (no_ip_msdp_mesh_group_member
,
8994 no_ip_msdp_mesh_group_member_cmd
,
8995 "no ip msdp mesh-group WORD member A.B.C.D",
8999 "Delete MSDP mesh-group member\n"
9001 "mesh group member\n"
9002 "peer ip address\n")
9004 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9005 return ip_no_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[4]->arg
,
9009 static int ip_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
9010 struct vty
*vty
, const char *mg
,
9013 enum pim_msdp_err result
;
9014 struct in_addr src_ip
;
9016 result
= inet_pton(AF_INET
, src
, &src_ip
);
9018 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", src
,
9019 errno
, safe_strerror(errno
));
9020 return CMD_WARNING_CONFIG_FAILED
;
9023 result
= pim_msdp_mg_src_add(pim
, mg
, src_ip
);
9025 case PIM_MSDP_ERR_NONE
:
9027 case PIM_MSDP_ERR_OOM
:
9028 vty_out(vty
, "%% Out of memory\n");
9030 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
9031 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
9034 vty_out(vty
, "%% source add failed\n");
9037 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9041 DEFUN (ip_msdp_mesh_group_source
,
9042 ip_msdp_mesh_group_source_cmd
,
9043 "ip msdp mesh-group WORD source A.B.C.D",
9046 "Configure MSDP mesh-group\n"
9048 "mesh group local address\n"
9049 "source ip address for the TCP connection\n")
9051 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9052 return ip_msdp_mesh_group_source_cmd_worker(pim
, vty
, argv
[3]->arg
,
9056 static int ip_no_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
9060 enum pim_msdp_err result
;
9062 result
= pim_msdp_mg_src_del(pim
, mg
);
9064 case PIM_MSDP_ERR_NONE
:
9066 case PIM_MSDP_ERR_NO_MG
:
9067 vty_out(vty
, "%% mesh-group does not exist\n");
9070 vty_out(vty
, "%% mesh-group source del failed\n");
9073 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9076 static int ip_no_msdp_mesh_group_cmd_worker(struct pim_instance
*pim
,
9077 struct vty
*vty
, const char *mg
)
9079 enum pim_msdp_err result
;
9081 result
= pim_msdp_mg_del(pim
, mg
);
9083 case PIM_MSDP_ERR_NONE
:
9085 case PIM_MSDP_ERR_NO_MG
:
9086 vty_out(vty
, "%% mesh-group does not exist\n");
9089 vty_out(vty
, "%% mesh-group source del failed\n");
9092 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9095 DEFUN (no_ip_msdp_mesh_group_source
,
9096 no_ip_msdp_mesh_group_source_cmd
,
9097 "no ip msdp mesh-group WORD source [A.B.C.D]",
9101 "Delete MSDP mesh-group source\n"
9103 "mesh group source\n"
9104 "mesh group local address\n")
9106 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9108 return ip_no_msdp_mesh_group_cmd_worker(pim
, vty
, argv
[6]->arg
);
9110 return ip_no_msdp_mesh_group_source_cmd_worker(pim
, vty
,
9114 static void print_empty_json_obj(struct vty
*vty
)
9117 json
= json_object_new_object();
9118 vty_out(vty
, "%s\n",
9119 json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
));
9120 json_object_free(json
);
9123 static void ip_msdp_show_mesh_group(struct pim_instance
*pim
, struct vty
*vty
,
9126 struct listnode
*mbrnode
;
9127 struct pim_msdp_mg_mbr
*mbr
;
9128 struct pim_msdp_mg
*mg
= pim
->msdp
.mg
;
9129 char mbr_str
[INET_ADDRSTRLEN
];
9130 char src_str
[INET_ADDRSTRLEN
];
9131 char state_str
[PIM_MSDP_STATE_STRLEN
];
9132 enum pim_msdp_peer_state state
;
9133 json_object
*json
= NULL
;
9134 json_object
*json_mg_row
= NULL
;
9135 json_object
*json_members
= NULL
;
9136 json_object
*json_row
= NULL
;
9140 print_empty_json_obj(vty
);
9144 pim_inet4_dump("<source?>", mg
->src_ip
, src_str
, sizeof(src_str
));
9146 json
= json_object_new_object();
9147 /* currently there is only one mesh group but we should still
9149 * it a dict with mg-name as key */
9150 json_mg_row
= json_object_new_object();
9151 json_object_string_add(json_mg_row
, "name",
9152 mg
->mesh_group_name
);
9153 json_object_string_add(json_mg_row
, "source", src_str
);
9155 vty_out(vty
, "Mesh group : %s\n", mg
->mesh_group_name
);
9156 vty_out(vty
, " Source : %s\n", src_str
);
9157 vty_out(vty
, " Member State\n");
9160 for (ALL_LIST_ELEMENTS_RO(mg
->mbr_list
, mbrnode
, mbr
)) {
9161 pim_inet4_dump("<mbr?>", mbr
->mbr_ip
, mbr_str
, sizeof(mbr_str
));
9163 state
= mbr
->mp
->state
;
9165 state
= PIM_MSDP_DISABLED
;
9167 pim_msdp_state_dump(state
, state_str
, sizeof(state_str
));
9169 json_row
= json_object_new_object();
9170 json_object_string_add(json_row
, "member", mbr_str
);
9171 json_object_string_add(json_row
, "state", state_str
);
9172 if (!json_members
) {
9173 json_members
= json_object_new_object();
9174 json_object_object_add(json_mg_row
, "members",
9177 json_object_object_add(json_members
, mbr_str
, json_row
);
9179 vty_out(vty
, " %-15s %11s\n", mbr_str
, state_str
);
9184 json_object_object_add(json
, mg
->mesh_group_name
, json_mg_row
);
9185 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9186 json
, JSON_C_TO_STRING_PRETTY
));
9187 json_object_free(json
);
9191 DEFUN (show_ip_msdp_mesh_group
,
9192 show_ip_msdp_mesh_group_cmd
,
9193 "show ip msdp [vrf NAME] mesh-group [json]",
9198 "MSDP mesh-group information\n"
9201 bool uj
= use_json(argc
, argv
);
9203 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
9208 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
9213 DEFUN (show_ip_msdp_mesh_group_vrf_all
,
9214 show_ip_msdp_mesh_group_vrf_all_cmd
,
9215 "show ip msdp vrf all mesh-group [json]",
9220 "MSDP mesh-group information\n"
9223 bool uj
= use_json(argc
, argv
);
9229 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
9233 vty_out(vty
, " \"%s\": ", vrf
->name
);
9236 vty_out(vty
, "VRF: %s\n", vrf
->name
);
9237 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
9240 vty_out(vty
, "}\n");
9245 static void ip_msdp_show_peers(struct pim_instance
*pim
, struct vty
*vty
,
9248 struct listnode
*mpnode
;
9249 struct pim_msdp_peer
*mp
;
9250 char peer_str
[INET_ADDRSTRLEN
];
9251 char local_str
[INET_ADDRSTRLEN
];
9252 char state_str
[PIM_MSDP_STATE_STRLEN
];
9253 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
9255 json_object
*json
= NULL
;
9256 json_object
*json_row
= NULL
;
9260 json
= json_object_new_object();
9263 "Peer Local State Uptime SaCnt\n");
9266 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
9267 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
9268 now
= pim_time_monotonic_sec();
9269 pim_time_uptime(timebuf
, sizeof(timebuf
),
9272 strlcpy(timebuf
, "-", sizeof(timebuf
));
9274 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
9275 pim_inet4_dump("<local?>", mp
->local
, local_str
,
9277 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
9279 json_row
= json_object_new_object();
9280 json_object_string_add(json_row
, "peer", peer_str
);
9281 json_object_string_add(json_row
, "local", local_str
);
9282 json_object_string_add(json_row
, "state", state_str
);
9283 json_object_string_add(json_row
, "upTime", timebuf
);
9284 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
9285 json_object_object_add(json
, peer_str
, json_row
);
9287 vty_out(vty
, "%-15s %15s %11s %8s %6d\n", peer_str
,
9288 local_str
, state_str
, timebuf
, mp
->sa_cnt
);
9293 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9294 json
, JSON_C_TO_STRING_PRETTY
));
9295 json_object_free(json
);
9299 static void ip_msdp_show_peers_detail(struct pim_instance
*pim
, struct vty
*vty
,
9300 const char *peer
, bool uj
)
9302 struct listnode
*mpnode
;
9303 struct pim_msdp_peer
*mp
;
9304 char peer_str
[INET_ADDRSTRLEN
];
9305 char local_str
[INET_ADDRSTRLEN
];
9306 char state_str
[PIM_MSDP_STATE_STRLEN
];
9307 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
9308 char katimer
[PIM_MSDP_TIMER_STRLEN
];
9309 char crtimer
[PIM_MSDP_TIMER_STRLEN
];
9310 char holdtimer
[PIM_MSDP_TIMER_STRLEN
];
9312 json_object
*json
= NULL
;
9313 json_object
*json_row
= NULL
;
9316 json
= json_object_new_object();
9319 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
9320 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
9321 if (strcmp(peer
, "detail") && strcmp(peer
, peer_str
))
9324 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
9325 now
= pim_time_monotonic_sec();
9326 pim_time_uptime(timebuf
, sizeof(timebuf
),
9329 strlcpy(timebuf
, "-", sizeof(timebuf
));
9331 pim_inet4_dump("<local?>", mp
->local
, local_str
,
9333 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
9334 pim_time_timer_to_hhmmss(katimer
, sizeof(katimer
),
9336 pim_time_timer_to_hhmmss(crtimer
, sizeof(crtimer
),
9338 pim_time_timer_to_hhmmss(holdtimer
, sizeof(holdtimer
),
9342 json_row
= json_object_new_object();
9343 json_object_string_add(json_row
, "peer", peer_str
);
9344 json_object_string_add(json_row
, "local", local_str
);
9345 json_object_string_add(json_row
, "meshGroupName",
9346 mp
->mesh_group_name
);
9347 json_object_string_add(json_row
, "state", state_str
);
9348 json_object_string_add(json_row
, "upTime", timebuf
);
9349 json_object_string_add(json_row
, "keepAliveTimer",
9351 json_object_string_add(json_row
, "connRetryTimer",
9353 json_object_string_add(json_row
, "holdTimer",
9355 json_object_string_add(json_row
, "lastReset",
9357 json_object_int_add(json_row
, "connAttempts",
9359 json_object_int_add(json_row
, "establishedChanges",
9361 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
9362 json_object_int_add(json_row
, "kaSent", mp
->ka_tx_cnt
);
9363 json_object_int_add(json_row
, "kaRcvd", mp
->ka_rx_cnt
);
9364 json_object_int_add(json_row
, "saSent", mp
->sa_tx_cnt
);
9365 json_object_int_add(json_row
, "saRcvd", mp
->sa_rx_cnt
);
9366 json_object_object_add(json
, peer_str
, json_row
);
9368 vty_out(vty
, "Peer : %s\n", peer_str
);
9369 vty_out(vty
, " Local : %s\n", local_str
);
9370 vty_out(vty
, " Mesh Group : %s\n",
9371 mp
->mesh_group_name
);
9372 vty_out(vty
, " State : %s\n", state_str
);
9373 vty_out(vty
, " Uptime : %s\n", timebuf
);
9375 vty_out(vty
, " Keepalive Timer : %s\n", katimer
);
9376 vty_out(vty
, " Conn Retry Timer : %s\n", crtimer
);
9377 vty_out(vty
, " Hold Timer : %s\n", holdtimer
);
9378 vty_out(vty
, " Last Reset : %s\n",
9380 vty_out(vty
, " Conn Attempts : %d\n",
9382 vty_out(vty
, " Established Changes : %d\n",
9384 vty_out(vty
, " SA Count : %d\n",
9386 vty_out(vty
, " Statistics :\n");
9389 vty_out(vty
, " Keepalives : %10d %10d\n",
9390 mp
->ka_tx_cnt
, mp
->ka_rx_cnt
);
9391 vty_out(vty
, " SAs : %10d %10d\n",
9392 mp
->sa_tx_cnt
, mp
->sa_rx_cnt
);
9398 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9399 json
, JSON_C_TO_STRING_PRETTY
));
9400 json_object_free(json
);
9404 DEFUN (show_ip_msdp_peer_detail
,
9405 show_ip_msdp_peer_detail_cmd
,
9406 "show ip msdp [vrf NAME] peer [detail|A.B.C.D] [json]",
9411 "MSDP peer information\n"
9416 bool uj
= use_json(argc
, argv
);
9418 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
9425 if (argv_find(argv
, argc
, "detail", &idx
))
9426 arg
= argv
[idx
]->text
;
9427 else if (argv_find(argv
, argc
, "A.B.C.D", &idx
))
9428 arg
= argv
[idx
]->arg
;
9431 ip_msdp_show_peers_detail(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
9433 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
9438 DEFUN (show_ip_msdp_peer_detail_vrf_all
,
9439 show_ip_msdp_peer_detail_vrf_all_cmd
,
9440 "show ip msdp vrf all peer [detail|A.B.C.D] [json]",
9445 "MSDP peer information\n"
9451 bool uj
= use_json(argc
, argv
);
9457 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
9461 vty_out(vty
, " \"%s\": ", vrf
->name
);
9464 vty_out(vty
, "VRF: %s\n", vrf
->name
);
9465 if (argv_find(argv
, argc
, "detail", &idx
)
9466 || argv_find(argv
, argc
, "A.B.C.D", &idx
))
9467 ip_msdp_show_peers_detail(vrf
->info
, vty
,
9468 argv
[idx
]->arg
, uj
);
9470 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
9473 vty_out(vty
, "}\n");
9478 static void ip_msdp_show_sa(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
9480 struct listnode
*sanode
;
9481 struct pim_msdp_sa
*sa
;
9482 char src_str
[INET_ADDRSTRLEN
];
9483 char grp_str
[INET_ADDRSTRLEN
];
9484 char rp_str
[INET_ADDRSTRLEN
];
9485 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
9489 json_object
*json
= NULL
;
9490 json_object
*json_group
= NULL
;
9491 json_object
*json_row
= NULL
;
9494 json
= json_object_new_object();
9497 "Source Group RP Local SPT Uptime\n");
9500 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
9501 now
= pim_time_monotonic_sec();
9502 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
9503 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
9504 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
9505 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
9506 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
9508 strlcpy(spt_str
, "yes", sizeof(spt_str
));
9510 strlcpy(spt_str
, "no", sizeof(spt_str
));
9513 strlcpy(rp_str
, "-", sizeof(rp_str
));
9514 strlcpy(spt_str
, "-", sizeof(spt_str
));
9516 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
9517 strlcpy(local_str
, "yes", sizeof(local_str
));
9519 strlcpy(local_str
, "no", sizeof(local_str
));
9522 json_object_object_get_ex(json
, grp_str
, &json_group
);
9525 json_group
= json_object_new_object();
9526 json_object_object_add(json
, grp_str
,
9530 json_row
= json_object_new_object();
9531 json_object_string_add(json_row
, "source", src_str
);
9532 json_object_string_add(json_row
, "group", grp_str
);
9533 json_object_string_add(json_row
, "rp", rp_str
);
9534 json_object_string_add(json_row
, "local", local_str
);
9535 json_object_string_add(json_row
, "sptSetup", spt_str
);
9536 json_object_string_add(json_row
, "upTime", timebuf
);
9537 json_object_object_add(json_group
, src_str
, json_row
);
9539 vty_out(vty
, "%-15s %15s %15s %5c %3c %8s\n",
9540 src_str
, grp_str
, rp_str
, local_str
[0],
9541 spt_str
[0], timebuf
);
9546 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9547 json
, JSON_C_TO_STRING_PRETTY
));
9548 json_object_free(json
);
9552 static void ip_msdp_show_sa_entry_detail(struct pim_msdp_sa
*sa
,
9553 const char *src_str
,
9554 const char *grp_str
, struct vty
*vty
,
9555 bool uj
, json_object
*json
)
9557 char rp_str
[INET_ADDRSTRLEN
];
9558 char peer_str
[INET_ADDRSTRLEN
];
9559 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
9562 char statetimer
[PIM_MSDP_TIMER_STRLEN
];
9564 json_object
*json_group
= NULL
;
9565 json_object
*json_row
= NULL
;
9567 now
= pim_time_monotonic_sec();
9568 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
9569 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
9570 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
9571 pim_inet4_dump("<peer?>", sa
->peer
, peer_str
, sizeof(peer_str
));
9573 strlcpy(spt_str
, "yes", sizeof(spt_str
));
9575 strlcpy(spt_str
, "no", sizeof(spt_str
));
9578 strlcpy(rp_str
, "-", sizeof(rp_str
));
9579 strlcpy(peer_str
, "-", sizeof(peer_str
));
9580 strlcpy(spt_str
, "-", sizeof(spt_str
));
9582 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
9583 strlcpy(local_str
, "yes", sizeof(local_str
));
9585 strlcpy(local_str
, "no", sizeof(local_str
));
9587 pim_time_timer_to_hhmmss(statetimer
, sizeof(statetimer
),
9588 sa
->sa_state_timer
);
9590 json_object_object_get_ex(json
, grp_str
, &json_group
);
9593 json_group
= json_object_new_object();
9594 json_object_object_add(json
, grp_str
, json_group
);
9597 json_row
= json_object_new_object();
9598 json_object_string_add(json_row
, "source", src_str
);
9599 json_object_string_add(json_row
, "group", grp_str
);
9600 json_object_string_add(json_row
, "rp", rp_str
);
9601 json_object_string_add(json_row
, "local", local_str
);
9602 json_object_string_add(json_row
, "sptSetup", spt_str
);
9603 json_object_string_add(json_row
, "upTime", timebuf
);
9604 json_object_string_add(json_row
, "stateTimer", statetimer
);
9605 json_object_object_add(json_group
, src_str
, json_row
);
9607 vty_out(vty
, "SA : %s\n", sa
->sg_str
);
9608 vty_out(vty
, " RP : %s\n", rp_str
);
9609 vty_out(vty
, " Peer : %s\n", peer_str
);
9610 vty_out(vty
, " Local : %s\n", local_str
);
9611 vty_out(vty
, " SPT Setup : %s\n", spt_str
);
9612 vty_out(vty
, " Uptime : %s\n", timebuf
);
9613 vty_out(vty
, " State Timer : %s\n", statetimer
);
9618 static void ip_msdp_show_sa_detail(struct pim_instance
*pim
, struct vty
*vty
,
9621 struct listnode
*sanode
;
9622 struct pim_msdp_sa
*sa
;
9623 char src_str
[INET_ADDRSTRLEN
];
9624 char grp_str
[INET_ADDRSTRLEN
];
9625 json_object
*json
= NULL
;
9628 json
= json_object_new_object();
9631 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
9632 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
9633 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
9634 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
, uj
,
9639 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9640 json
, JSON_C_TO_STRING_PRETTY
));
9641 json_object_free(json
);
9645 DEFUN (show_ip_msdp_sa_detail
,
9646 show_ip_msdp_sa_detail_cmd
,
9647 "show ip msdp [vrf NAME] sa detail [json]",
9652 "MSDP active-source information\n"
9656 bool uj
= use_json(argc
, argv
);
9658 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
9663 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
9668 DEFUN (show_ip_msdp_sa_detail_vrf_all
,
9669 show_ip_msdp_sa_detail_vrf_all_cmd
,
9670 "show ip msdp vrf all sa detail [json]",
9675 "MSDP active-source information\n"
9679 bool uj
= use_json(argc
, argv
);
9685 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
9689 vty_out(vty
, " \"%s\": ", vrf
->name
);
9692 vty_out(vty
, "VRF: %s\n", vrf
->name
);
9693 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
9696 vty_out(vty
, "}\n");
9701 static void ip_msdp_show_sa_addr(struct pim_instance
*pim
, struct vty
*vty
,
9702 const char *addr
, bool uj
)
9704 struct listnode
*sanode
;
9705 struct pim_msdp_sa
*sa
;
9706 char src_str
[INET_ADDRSTRLEN
];
9707 char grp_str
[INET_ADDRSTRLEN
];
9708 json_object
*json
= NULL
;
9711 json
= json_object_new_object();
9714 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
9715 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
9716 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
9717 if (!strcmp(addr
, src_str
) || !strcmp(addr
, grp_str
)) {
9718 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
9724 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9725 json
, JSON_C_TO_STRING_PRETTY
));
9726 json_object_free(json
);
9730 static void ip_msdp_show_sa_sg(struct pim_instance
*pim
, struct vty
*vty
,
9731 const char *src
, const char *grp
, bool uj
)
9733 struct listnode
*sanode
;
9734 struct pim_msdp_sa
*sa
;
9735 char src_str
[INET_ADDRSTRLEN
];
9736 char grp_str
[INET_ADDRSTRLEN
];
9737 json_object
*json
= NULL
;
9740 json
= json_object_new_object();
9743 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
9744 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
9745 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
9746 if (!strcmp(src
, src_str
) && !strcmp(grp
, grp_str
)) {
9747 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
9753 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9754 json
, JSON_C_TO_STRING_PRETTY
));
9755 json_object_free(json
);
9759 DEFUN (show_ip_msdp_sa_sg
,
9760 show_ip_msdp_sa_sg_cmd
,
9761 "show ip msdp [vrf NAME] sa [A.B.C.D [A.B.C.D]] [json]",
9766 "MSDP active-source information\n"
9767 "source or group ip\n"
9771 bool uj
= use_json(argc
, argv
);
9775 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
9780 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
9782 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
9786 if (src_ip
&& grp_ip
)
9787 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
9789 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
9791 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
9796 DEFUN (show_ip_msdp_sa_sg_vrf_all
,
9797 show_ip_msdp_sa_sg_vrf_all_cmd
,
9798 "show ip msdp vrf all sa [A.B.C.D [A.B.C.D]] [json]",
9803 "MSDP active-source information\n"
9804 "source or group ip\n"
9808 bool uj
= use_json(argc
, argv
);
9813 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
9815 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
9821 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
9825 vty_out(vty
, " \"%s\": ", vrf
->name
);
9828 vty_out(vty
, "VRF: %s\n", vrf
->name
);
9830 if (src_ip
&& grp_ip
)
9831 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
9833 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
9835 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
9838 vty_out(vty
, "}\n");
9843 struct pim_sg_cache_walk_data
{
9846 json_object
*json_group
;
9847 struct in_addr addr
;
9851 static void pim_show_vxlan_sg_entry(struct pim_vxlan_sg
*vxlan_sg
,
9852 struct pim_sg_cache_walk_data
*cwd
)
9854 struct vty
*vty
= cwd
->vty
;
9855 json_object
*json
= cwd
->json
;
9856 char src_str
[INET_ADDRSTRLEN
];
9857 char grp_str
[INET_ADDRSTRLEN
];
9858 json_object
*json_row
;
9859 bool installed
= (vxlan_sg
->up
) ? true : false;
9860 const char *iif_name
= vxlan_sg
->iif
?vxlan_sg
->iif
->name
:"-";
9861 const char *oif_name
;
9863 if (pim_vxlan_is_orig_mroute(vxlan_sg
))
9864 oif_name
= vxlan_sg
->orig_oif
?vxlan_sg
->orig_oif
->name
:"";
9866 oif_name
= vxlan_sg
->term_oif
?vxlan_sg
->term_oif
->name
:"";
9868 if (cwd
->addr_match
&& (vxlan_sg
->sg
.src
.s_addr
!= cwd
->addr
.s_addr
) &&
9869 (vxlan_sg
->sg
.grp
.s_addr
!= cwd
->addr
.s_addr
)) {
9872 pim_inet4_dump("<src?>", vxlan_sg
->sg
.src
, src_str
, sizeof(src_str
));
9873 pim_inet4_dump("<grp?>", vxlan_sg
->sg
.grp
, grp_str
, sizeof(grp_str
));
9875 json_object_object_get_ex(json
, grp_str
, &cwd
->json_group
);
9877 if (!cwd
->json_group
) {
9878 cwd
->json_group
= json_object_new_object();
9879 json_object_object_add(json
, grp_str
,
9883 json_row
= json_object_new_object();
9884 json_object_string_add(json_row
, "source", src_str
);
9885 json_object_string_add(json_row
, "group", grp_str
);
9886 json_object_string_add(json_row
, "input", iif_name
);
9887 json_object_string_add(json_row
, "output", oif_name
);
9889 json_object_boolean_true_add(json_row
, "installed");
9891 json_object_boolean_false_add(json_row
, "installed");
9892 json_object_object_add(cwd
->json_group
, src_str
, json_row
);
9894 vty_out(vty
, "%-15s %-15s %-15s %-15s %-5s\n",
9895 src_str
, grp_str
, iif_name
, oif_name
,
9900 static void pim_show_vxlan_sg_hash_entry(struct hash_backet
*backet
, void *arg
)
9902 pim_show_vxlan_sg_entry((struct pim_vxlan_sg
*)backet
->data
,
9903 (struct pim_sg_cache_walk_data
*)arg
);
9906 static void pim_show_vxlan_sg(struct pim_instance
*pim
,
9907 struct vty
*vty
, bool uj
)
9909 json_object
*json
= NULL
;
9910 struct pim_sg_cache_walk_data cwd
;
9913 json
= json_object_new_object();
9915 vty_out(vty
, "Codes: I -> installed\n");
9917 "Source Group Input Output Flags\n");
9920 memset(&cwd
, 0, sizeof(cwd
));
9923 hash_iterate(pim
->vxlan
.sg_hash
, pim_show_vxlan_sg_hash_entry
, &cwd
);
9926 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9927 json
, JSON_C_TO_STRING_PRETTY
));
9928 json_object_free(json
);
9932 static void pim_show_vxlan_sg_match_addr(struct pim_instance
*pim
,
9933 struct vty
*vty
, char *addr_str
, bool uj
)
9935 json_object
*json
= NULL
;
9936 struct pim_sg_cache_walk_data cwd
;
9939 memset(&cwd
, 0, sizeof(cwd
));
9940 result
= inet_pton(AF_INET
, addr_str
, &cwd
.addr
);
9942 vty_out(vty
, "Bad address %s: errno=%d: %s\n", addr_str
,
9943 errno
, safe_strerror(errno
));
9948 json
= json_object_new_object();
9950 vty_out(vty
, "Codes: I -> installed\n");
9952 "Source Group Input Output Flags\n");
9957 cwd
.addr_match
= true;
9958 hash_iterate(pim
->vxlan
.sg_hash
, pim_show_vxlan_sg_hash_entry
, &cwd
);
9961 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9962 json
, JSON_C_TO_STRING_PRETTY
));
9963 json_object_free(json
);
9967 static void pim_show_vxlan_sg_one(struct pim_instance
*pim
,
9968 struct vty
*vty
, char *src_str
, char *grp_str
, bool uj
)
9970 json_object
*json
= NULL
;
9971 struct prefix_sg sg
;
9973 struct pim_vxlan_sg
*vxlan_sg
;
9974 const char *iif_name
;
9976 const char *oif_name
;
9978 result
= inet_pton(AF_INET
, src_str
, &sg
.src
);
9980 vty_out(vty
, "Bad src address %s: errno=%d: %s\n", src_str
,
9981 errno
, safe_strerror(errno
));
9984 result
= inet_pton(AF_INET
, grp_str
, &sg
.grp
);
9986 vty_out(vty
, "Bad grp address %s: errno=%d: %s\n", grp_str
,
9987 errno
, safe_strerror(errno
));
9991 sg
.family
= AF_INET
;
9992 sg
.prefixlen
= IPV4_MAX_BITLEN
;
9994 json
= json_object_new_object();
9996 vxlan_sg
= pim_vxlan_sg_find(pim
, &sg
);
9998 installed
= (vxlan_sg
->up
) ? true : false;
9999 iif_name
= vxlan_sg
->iif
?vxlan_sg
->iif
->name
:"-";
10001 if (pim_vxlan_is_orig_mroute(vxlan_sg
))
10003 vxlan_sg
->orig_oif
?vxlan_sg
->orig_oif
->name
:"";
10006 vxlan_sg
->term_oif
?vxlan_sg
->term_oif
->name
:"";
10009 json_object_string_add(json
, "source", src_str
);
10010 json_object_string_add(json
, "group", grp_str
);
10011 json_object_string_add(json
, "input", iif_name
);
10012 json_object_string_add(json
, "output", oif_name
);
10014 json_object_boolean_true_add(json
, "installed");
10016 json_object_boolean_false_add(json
,
10019 vty_out(vty
, "SG : %s\n", vxlan_sg
->sg_str
);
10020 vty_out(vty
, " Input : %s\n", iif_name
);
10021 vty_out(vty
, " Output : %s\n", oif_name
);
10022 vty_out(vty
, " installed : %s\n",
10023 installed
?"yes":"no");
10028 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10029 json
, JSON_C_TO_STRING_PRETTY
));
10030 json_object_free(json
);
10034 DEFUN (show_ip_pim_vxlan_sg
,
10035 show_ip_pim_vxlan_sg_cmd
,
10036 "show ip pim [vrf NAME] vxlan-groups [A.B.C.D [A.B.C.D]] [json]",
10041 "VxLAN BUM groups\n"
10042 "source or group ip\n"
10046 bool uj
= use_json(argc
, argv
);
10050 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10053 return CMD_WARNING
;
10055 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ?
10056 argv
[idx
++]->arg
:NULL
;
10057 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
) ?
10058 argv
[idx
]->arg
:NULL
;
10060 if (src_ip
&& grp_ip
)
10061 pim_show_vxlan_sg_one(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
10063 pim_show_vxlan_sg_match_addr(vrf
->info
, vty
, src_ip
, uj
);
10065 pim_show_vxlan_sg(vrf
->info
, vty
, uj
);
10067 return CMD_SUCCESS
;
10070 static void pim_show_vxlan_sg_work(struct pim_instance
*pim
,
10071 struct vty
*vty
, bool uj
)
10073 json_object
*json
= NULL
;
10074 struct pim_sg_cache_walk_data cwd
;
10075 struct listnode
*node
;
10076 struct pim_vxlan_sg
*vxlan_sg
;
10079 json
= json_object_new_object();
10081 vty_out(vty
, "Codes: I -> installed\n");
10083 "Source Group Input Flags\n");
10086 memset(&cwd
, 0, sizeof(cwd
));
10089 for (ALL_LIST_ELEMENTS_RO(pim_vxlan_p
->work_list
, node
, vxlan_sg
))
10090 pim_show_vxlan_sg_entry(vxlan_sg
, &cwd
);
10093 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10094 json
, JSON_C_TO_STRING_PRETTY
));
10095 json_object_free(json
);
10099 DEFUN_HIDDEN (show_ip_pim_vxlan_sg_work
,
10100 show_ip_pim_vxlan_sg_work_cmd
,
10101 "show ip pim [vrf NAME] vxlan-work [json]",
10106 "VxLAN work list\n"
10109 bool uj
= use_json(argc
, argv
);
10113 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10116 return CMD_WARNING
;
10118 pim_show_vxlan_sg_work(vrf
->info
, vty
, uj
);
10120 return CMD_SUCCESS
;
10123 DEFUN_HIDDEN (no_ip_pim_mlag
,
10124 no_ip_pim_mlag_cmd
,
10131 struct in_addr addr
;
10134 pim_vxlan_mlag_update(true/*mlag_enable*/,
10135 false/*peer_state*/, PIM_VXLAN_MLAG_ROLE_SECONDARY
,
10136 NULL
/*peerlink*/, &addr
);
10138 return CMD_SUCCESS
;
10141 DEFUN_HIDDEN (ip_pim_mlag
,
10143 "ip pim mlag INTERFACE role [primary|secondary] state [up|down] addr A.B.C.D",
10147 "peerlink sub interface\n"
10149 "MLAG role primary\n"
10150 "MLAG role secondary\n"
10151 "peer session state\n"
10152 "peer session state up\n"
10153 "peer session state down\n"
10155 "unique ip address\n")
10157 struct interface
*ifp
;
10158 const char *peerlink
;
10163 struct in_addr reg_addr
;
10166 peerlink
= argv
[idx
]->arg
;
10167 ifp
= if_lookup_by_name(peerlink
, VRF_DEFAULT
);
10169 vty_out(vty
, "No such interface name %s\n", peerlink
);
10170 return CMD_WARNING
;
10174 if (!strcmp(argv
[idx
]->arg
, "primary")) {
10175 role
= PIM_VXLAN_MLAG_ROLE_PRIMARY
;
10176 } else if (!strcmp(argv
[idx
]->arg
, "secondary")) {
10177 role
= PIM_VXLAN_MLAG_ROLE_SECONDARY
;
10179 vty_out(vty
, "unknown MLAG role %s\n", argv
[idx
]->arg
);
10180 return CMD_WARNING
;
10184 if (!strcmp(argv
[idx
]->arg
, "up")) {
10186 } else if (strcmp(argv
[idx
]->arg
, "down")) {
10187 peer_state
= false;
10189 vty_out(vty
, "unknown MLAG state %s\n", argv
[idx
]->arg
);
10190 return CMD_WARNING
;
10194 result
= inet_pton(AF_INET
, argv
[idx
]->arg
, ®_addr
);
10196 vty_out(vty
, "%% Bad reg address %s: errno=%d: %s\n",
10198 errno
, safe_strerror(errno
));
10199 return CMD_WARNING_CONFIG_FAILED
;
10201 pim_vxlan_mlag_update(true, peer_state
, role
, ifp
, ®_addr
);
10203 return CMD_SUCCESS
;
10206 void pim_cmd_init(void)
10208 install_node(&interface_node
,
10209 pim_interface_config_write
); /* INTERFACE_NODE */
10212 install_node(&debug_node
, pim_debug_config_write
);
10214 install_element(ENABLE_NODE
, &pim_test_sg_keepalive_cmd
);
10216 install_element(CONFIG_NODE
, &ip_pim_rp_cmd
);
10217 install_element(VRF_NODE
, &ip_pim_rp_cmd
);
10218 install_element(CONFIG_NODE
, &no_ip_pim_rp_cmd
);
10219 install_element(VRF_NODE
, &no_ip_pim_rp_cmd
);
10220 install_element(CONFIG_NODE
, &ip_pim_rp_prefix_list_cmd
);
10221 install_element(VRF_NODE
, &ip_pim_rp_prefix_list_cmd
);
10222 install_element(CONFIG_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
10223 install_element(VRF_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
10224 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
10225 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
10226 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
10227 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
10228 install_element(CONFIG_NODE
, &ip_pim_ssm_prefix_list_cmd
);
10229 install_element(VRF_NODE
, &ip_pim_ssm_prefix_list_cmd
);
10230 install_element(CONFIG_NODE
, &ip_pim_register_suppress_cmd
);
10231 install_element(VRF_NODE
, &ip_pim_register_suppress_cmd
);
10232 install_element(CONFIG_NODE
, &no_ip_pim_register_suppress_cmd
);
10233 install_element(VRF_NODE
, &no_ip_pim_register_suppress_cmd
);
10234 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
10235 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
10236 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
10237 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
10238 install_element(CONFIG_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
10239 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
10240 install_element(CONFIG_NODE
,
10241 &no_ip_pim_spt_switchover_infinity_plist_cmd
);
10242 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_plist_cmd
);
10243 install_element(CONFIG_NODE
, &ip_pim_joinprune_time_cmd
);
10244 install_element(VRF_NODE
, &ip_pim_joinprune_time_cmd
);
10245 install_element(CONFIG_NODE
, &no_ip_pim_joinprune_time_cmd
);
10246 install_element(VRF_NODE
, &no_ip_pim_joinprune_time_cmd
);
10247 install_element(CONFIG_NODE
, &ip_pim_keep_alive_cmd
);
10248 install_element(VRF_NODE
, &ip_pim_keep_alive_cmd
);
10249 install_element(CONFIG_NODE
, &ip_pim_rp_keep_alive_cmd
);
10250 install_element(VRF_NODE
, &ip_pim_rp_keep_alive_cmd
);
10251 install_element(CONFIG_NODE
, &no_ip_pim_keep_alive_cmd
);
10252 install_element(VRF_NODE
, &no_ip_pim_keep_alive_cmd
);
10253 install_element(CONFIG_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
10254 install_element(VRF_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
10255 install_element(CONFIG_NODE
, &ip_pim_packets_cmd
);
10256 install_element(VRF_NODE
, &ip_pim_packets_cmd
);
10257 install_element(CONFIG_NODE
, &no_ip_pim_packets_cmd
);
10258 install_element(VRF_NODE
, &no_ip_pim_packets_cmd
);
10259 install_element(CONFIG_NODE
, &ip_pim_v6_secondary_cmd
);
10260 install_element(VRF_NODE
, &ip_pim_v6_secondary_cmd
);
10261 install_element(CONFIG_NODE
, &no_ip_pim_v6_secondary_cmd
);
10262 install_element(VRF_NODE
, &no_ip_pim_v6_secondary_cmd
);
10263 install_element(CONFIG_NODE
, &ip_ssmpingd_cmd
);
10264 install_element(VRF_NODE
, &ip_ssmpingd_cmd
);
10265 install_element(CONFIG_NODE
, &no_ip_ssmpingd_cmd
);
10266 install_element(VRF_NODE
, &no_ip_ssmpingd_cmd
);
10267 install_element(CONFIG_NODE
, &ip_msdp_peer_cmd
);
10268 install_element(VRF_NODE
, &ip_msdp_peer_cmd
);
10269 install_element(CONFIG_NODE
, &no_ip_msdp_peer_cmd
);
10270 install_element(VRF_NODE
, &no_ip_msdp_peer_cmd
);
10271 install_element(CONFIG_NODE
, &ip_pim_ecmp_cmd
);
10272 install_element(VRF_NODE
, &ip_pim_ecmp_cmd
);
10273 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_cmd
);
10274 install_element(VRF_NODE
, &no_ip_pim_ecmp_cmd
);
10275 install_element(CONFIG_NODE
, &ip_pim_ecmp_rebalance_cmd
);
10276 install_element(VRF_NODE
, &ip_pim_ecmp_rebalance_cmd
);
10277 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
10278 install_element(VRF_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
10279 install_element(CONFIG_NODE
, &ip_pim_mlag_cmd
);
10280 install_element(CONFIG_NODE
, &no_ip_pim_mlag_cmd
);
10282 install_element(INTERFACE_NODE
, &interface_ip_igmp_cmd
);
10283 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_cmd
);
10284 install_element(INTERFACE_NODE
, &interface_ip_igmp_join_cmd
);
10285 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_join_cmd
);
10286 install_element(INTERFACE_NODE
, &interface_ip_igmp_version_cmd
);
10287 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_version_cmd
);
10288 install_element(INTERFACE_NODE
, &interface_ip_igmp_query_interval_cmd
);
10289 install_element(INTERFACE_NODE
,
10290 &interface_no_ip_igmp_query_interval_cmd
);
10291 install_element(INTERFACE_NODE
,
10292 &interface_ip_igmp_query_max_response_time_cmd
);
10293 install_element(INTERFACE_NODE
,
10294 &interface_no_ip_igmp_query_max_response_time_cmd
);
10295 install_element(INTERFACE_NODE
,
10296 &interface_ip_igmp_query_max_response_time_dsec_cmd
);
10297 install_element(INTERFACE_NODE
,
10298 &interface_no_ip_igmp_query_max_response_time_dsec_cmd
);
10299 install_element(INTERFACE_NODE
,
10300 &interface_ip_igmp_last_member_query_count_cmd
);
10301 install_element(INTERFACE_NODE
,
10302 &interface_no_ip_igmp_last_member_query_count_cmd
);
10303 install_element(INTERFACE_NODE
,
10304 &interface_ip_igmp_last_member_query_interval_cmd
);
10305 install_element(INTERFACE_NODE
,
10306 &interface_no_ip_igmp_last_member_query_interval_cmd
);
10307 install_element(INTERFACE_NODE
, &interface_ip_pim_activeactive_cmd
);
10308 install_element(INTERFACE_NODE
, &interface_ip_pim_ssm_cmd
);
10309 install_element(INTERFACE_NODE
, &interface_no_ip_pim_ssm_cmd
);
10310 install_element(INTERFACE_NODE
, &interface_ip_pim_sm_cmd
);
10311 install_element(INTERFACE_NODE
, &interface_no_ip_pim_sm_cmd
);
10312 install_element(INTERFACE_NODE
, &interface_ip_pim_cmd
);
10313 install_element(INTERFACE_NODE
, &interface_no_ip_pim_cmd
);
10314 install_element(INTERFACE_NODE
, &interface_ip_pim_drprio_cmd
);
10315 install_element(INTERFACE_NODE
, &interface_no_ip_pim_drprio_cmd
);
10316 install_element(INTERFACE_NODE
, &interface_ip_pim_hello_cmd
);
10317 install_element(INTERFACE_NODE
, &interface_no_ip_pim_hello_cmd
);
10318 install_element(INTERFACE_NODE
, &interface_ip_pim_boundary_oil_cmd
);
10319 install_element(INTERFACE_NODE
, &interface_no_ip_pim_boundary_oil_cmd
);
10320 install_element(INTERFACE_NODE
, &interface_ip_igmp_query_generate_cmd
);
10322 // Static mroutes NEB
10323 install_element(INTERFACE_NODE
, &interface_ip_mroute_cmd
);
10324 install_element(INTERFACE_NODE
, &interface_ip_mroute_source_cmd
);
10325 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_cmd
);
10326 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_source_cmd
);
10328 install_element(VIEW_NODE
, &show_ip_igmp_interface_cmd
);
10329 install_element(VIEW_NODE
, &show_ip_igmp_interface_vrf_all_cmd
);
10330 install_element(VIEW_NODE
, &show_ip_igmp_join_cmd
);
10331 install_element(VIEW_NODE
, &show_ip_igmp_join_vrf_all_cmd
);
10332 install_element(VIEW_NODE
, &show_ip_igmp_groups_cmd
);
10333 install_element(VIEW_NODE
, &show_ip_igmp_groups_vrf_all_cmd
);
10334 install_element(VIEW_NODE
, &show_ip_igmp_groups_retransmissions_cmd
);
10335 install_element(VIEW_NODE
, &show_ip_igmp_sources_cmd
);
10336 install_element(VIEW_NODE
, &show_ip_igmp_sources_retransmissions_cmd
);
10337 install_element(VIEW_NODE
, &show_ip_igmp_statistics_cmd
);
10338 install_element(VIEW_NODE
, &show_ip_pim_assert_cmd
);
10339 install_element(VIEW_NODE
, &show_ip_pim_assert_internal_cmd
);
10340 install_element(VIEW_NODE
, &show_ip_pim_assert_metric_cmd
);
10341 install_element(VIEW_NODE
, &show_ip_pim_assert_winner_metric_cmd
);
10342 install_element(VIEW_NODE
, &show_ip_pim_interface_traffic_cmd
);
10343 install_element(VIEW_NODE
, &show_ip_pim_interface_cmd
);
10344 install_element(VIEW_NODE
, &show_ip_pim_interface_vrf_all_cmd
);
10345 install_element(VIEW_NODE
, &show_ip_pim_join_cmd
);
10346 install_element(VIEW_NODE
, &show_ip_pim_join_vrf_all_cmd
);
10347 install_element(VIEW_NODE
, &show_ip_pim_local_membership_cmd
);
10348 install_element(VIEW_NODE
, &show_ip_pim_neighbor_cmd
);
10349 install_element(VIEW_NODE
, &show_ip_pim_neighbor_vrf_all_cmd
);
10350 install_element(VIEW_NODE
, &show_ip_pim_rpf_cmd
);
10351 install_element(VIEW_NODE
, &show_ip_pim_rpf_vrf_all_cmd
);
10352 install_element(VIEW_NODE
, &show_ip_pim_secondary_cmd
);
10353 install_element(VIEW_NODE
, &show_ip_pim_state_cmd
);
10354 install_element(VIEW_NODE
, &show_ip_pim_state_vrf_all_cmd
);
10355 install_element(VIEW_NODE
, &show_ip_pim_upstream_cmd
);
10356 install_element(VIEW_NODE
, &show_ip_pim_upstream_vrf_all_cmd
);
10357 install_element(VIEW_NODE
, &show_ip_pim_upstream_join_desired_cmd
);
10358 install_element(VIEW_NODE
, &show_ip_pim_upstream_rpf_cmd
);
10359 install_element(VIEW_NODE
, &show_ip_pim_rp_cmd
);
10360 install_element(VIEW_NODE
, &show_ip_pim_rp_vrf_all_cmd
);
10361 install_element(VIEW_NODE
, &show_ip_pim_bsr_cmd
);
10362 install_element(VIEW_NODE
, &show_ip_multicast_cmd
);
10363 install_element(VIEW_NODE
, &show_ip_multicast_vrf_all_cmd
);
10364 install_element(VIEW_NODE
, &show_ip_mroute_cmd
);
10365 install_element(VIEW_NODE
, &show_ip_mroute_vrf_all_cmd
);
10366 install_element(VIEW_NODE
, &show_ip_mroute_count_cmd
);
10367 install_element(VIEW_NODE
, &show_ip_mroute_count_vrf_all_cmd
);
10368 install_element(VIEW_NODE
, &show_ip_mroute_summary_cmd
);
10369 install_element(VIEW_NODE
, &show_ip_mroute_summary_vrf_all_cmd
);
10370 install_element(VIEW_NODE
, &show_ip_rib_cmd
);
10371 install_element(VIEW_NODE
, &show_ip_ssmpingd_cmd
);
10372 install_element(VIEW_NODE
, &show_debugging_pim_cmd
);
10373 install_element(VIEW_NODE
, &show_ip_pim_nexthop_cmd
);
10374 install_element(VIEW_NODE
, &show_ip_pim_nexthop_lookup_cmd
);
10375 install_element(VIEW_NODE
, &show_ip_pim_bsrp_cmd
);
10376 install_element(VIEW_NODE
, &show_ip_pim_bsm_db_cmd
);
10377 install_element(VIEW_NODE
, &show_ip_pim_statistics_cmd
);
10379 install_element(ENABLE_NODE
, &clear_ip_mroute_count_cmd
);
10380 install_element(ENABLE_NODE
, &clear_ip_interfaces_cmd
);
10381 install_element(ENABLE_NODE
, &clear_ip_igmp_interfaces_cmd
);
10382 install_element(ENABLE_NODE
, &clear_ip_mroute_cmd
);
10383 install_element(ENABLE_NODE
, &clear_ip_pim_interfaces_cmd
);
10384 install_element(ENABLE_NODE
, &clear_ip_pim_interface_traffic_cmd
);
10385 install_element(ENABLE_NODE
, &clear_ip_pim_oil_cmd
);
10386 install_element(ENABLE_NODE
, &clear_ip_pim_statistics_cmd
);
10388 install_element(ENABLE_NODE
, &debug_igmp_cmd
);
10389 install_element(ENABLE_NODE
, &no_debug_igmp_cmd
);
10390 install_element(ENABLE_NODE
, &debug_igmp_events_cmd
);
10391 install_element(ENABLE_NODE
, &no_debug_igmp_events_cmd
);
10392 install_element(ENABLE_NODE
, &debug_igmp_packets_cmd
);
10393 install_element(ENABLE_NODE
, &no_debug_igmp_packets_cmd
);
10394 install_element(ENABLE_NODE
, &debug_igmp_trace_cmd
);
10395 install_element(ENABLE_NODE
, &no_debug_igmp_trace_cmd
);
10396 install_element(ENABLE_NODE
, &debug_mroute_cmd
);
10397 install_element(ENABLE_NODE
, &debug_mroute_detail_cmd
);
10398 install_element(ENABLE_NODE
, &no_debug_mroute_cmd
);
10399 install_element(ENABLE_NODE
, &no_debug_mroute_detail_cmd
);
10400 install_element(ENABLE_NODE
, &debug_pim_static_cmd
);
10401 install_element(ENABLE_NODE
, &no_debug_pim_static_cmd
);
10402 install_element(ENABLE_NODE
, &debug_pim_cmd
);
10403 install_element(ENABLE_NODE
, &no_debug_pim_cmd
);
10404 install_element(ENABLE_NODE
, &debug_pim_nht_cmd
);
10405 install_element(ENABLE_NODE
, &no_debug_pim_nht_cmd
);
10406 install_element(ENABLE_NODE
, &debug_pim_nht_rp_cmd
);
10407 install_element(ENABLE_NODE
, &no_debug_pim_nht_rp_cmd
);
10408 install_element(ENABLE_NODE
, &debug_pim_events_cmd
);
10409 install_element(ENABLE_NODE
, &no_debug_pim_events_cmd
);
10410 install_element(ENABLE_NODE
, &debug_pim_packets_cmd
);
10411 install_element(ENABLE_NODE
, &no_debug_pim_packets_cmd
);
10412 install_element(ENABLE_NODE
, &debug_pim_packetdump_send_cmd
);
10413 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_send_cmd
);
10414 install_element(ENABLE_NODE
, &debug_pim_packetdump_recv_cmd
);
10415 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_recv_cmd
);
10416 install_element(ENABLE_NODE
, &debug_pim_trace_cmd
);
10417 install_element(ENABLE_NODE
, &no_debug_pim_trace_cmd
);
10418 install_element(ENABLE_NODE
, &debug_pim_trace_detail_cmd
);
10419 install_element(ENABLE_NODE
, &no_debug_pim_trace_detail_cmd
);
10420 install_element(ENABLE_NODE
, &debug_ssmpingd_cmd
);
10421 install_element(ENABLE_NODE
, &no_debug_ssmpingd_cmd
);
10422 install_element(ENABLE_NODE
, &debug_pim_zebra_cmd
);
10423 install_element(ENABLE_NODE
, &no_debug_pim_zebra_cmd
);
10424 install_element(ENABLE_NODE
, &debug_pim_mlag_cmd
);
10425 install_element(ENABLE_NODE
, &no_debug_pim_mlag_cmd
);
10426 install_element(ENABLE_NODE
, &debug_pim_vxlan_cmd
);
10427 install_element(ENABLE_NODE
, &no_debug_pim_vxlan_cmd
);
10428 install_element(ENABLE_NODE
, &debug_msdp_cmd
);
10429 install_element(ENABLE_NODE
, &no_debug_msdp_cmd
);
10430 install_element(ENABLE_NODE
, &debug_msdp_events_cmd
);
10431 install_element(ENABLE_NODE
, &no_debug_msdp_events_cmd
);
10432 install_element(ENABLE_NODE
, &debug_msdp_packets_cmd
);
10433 install_element(ENABLE_NODE
, &no_debug_msdp_packets_cmd
);
10434 install_element(ENABLE_NODE
, &debug_mtrace_cmd
);
10435 install_element(ENABLE_NODE
, &no_debug_mtrace_cmd
);
10436 install_element(ENABLE_NODE
, &debug_bsm_cmd
);
10437 install_element(ENABLE_NODE
, &no_debug_bsm_cmd
);
10439 install_element(CONFIG_NODE
, &debug_igmp_cmd
);
10440 install_element(CONFIG_NODE
, &no_debug_igmp_cmd
);
10441 install_element(CONFIG_NODE
, &debug_igmp_events_cmd
);
10442 install_element(CONFIG_NODE
, &no_debug_igmp_events_cmd
);
10443 install_element(CONFIG_NODE
, &debug_igmp_packets_cmd
);
10444 install_element(CONFIG_NODE
, &no_debug_igmp_packets_cmd
);
10445 install_element(CONFIG_NODE
, &debug_igmp_trace_cmd
);
10446 install_element(CONFIG_NODE
, &no_debug_igmp_trace_cmd
);
10447 install_element(CONFIG_NODE
, &debug_mroute_cmd
);
10448 install_element(CONFIG_NODE
, &debug_mroute_detail_cmd
);
10449 install_element(CONFIG_NODE
, &no_debug_mroute_cmd
);
10450 install_element(CONFIG_NODE
, &no_debug_mroute_detail_cmd
);
10451 install_element(CONFIG_NODE
, &debug_pim_static_cmd
);
10452 install_element(CONFIG_NODE
, &no_debug_pim_static_cmd
);
10453 install_element(CONFIG_NODE
, &debug_pim_cmd
);
10454 install_element(CONFIG_NODE
, &no_debug_pim_cmd
);
10455 install_element(CONFIG_NODE
, &debug_pim_nht_cmd
);
10456 install_element(CONFIG_NODE
, &no_debug_pim_nht_cmd
);
10457 install_element(CONFIG_NODE
, &debug_pim_nht_rp_cmd
);
10458 install_element(CONFIG_NODE
, &no_debug_pim_nht_rp_cmd
);
10459 install_element(CONFIG_NODE
, &debug_pim_events_cmd
);
10460 install_element(CONFIG_NODE
, &no_debug_pim_events_cmd
);
10461 install_element(CONFIG_NODE
, &debug_pim_packets_cmd
);
10462 install_element(CONFIG_NODE
, &no_debug_pim_packets_cmd
);
10463 install_element(CONFIG_NODE
, &debug_pim_trace_cmd
);
10464 install_element(CONFIG_NODE
, &no_debug_pim_trace_cmd
);
10465 install_element(CONFIG_NODE
, &debug_pim_trace_detail_cmd
);
10466 install_element(CONFIG_NODE
, &no_debug_pim_trace_detail_cmd
);
10467 install_element(CONFIG_NODE
, &debug_ssmpingd_cmd
);
10468 install_element(CONFIG_NODE
, &no_debug_ssmpingd_cmd
);
10469 install_element(CONFIG_NODE
, &debug_pim_zebra_cmd
);
10470 install_element(CONFIG_NODE
, &no_debug_pim_zebra_cmd
);
10471 install_element(CONFIG_NODE
, &debug_pim_vxlan_cmd
);
10472 install_element(CONFIG_NODE
, &no_debug_pim_vxlan_cmd
);
10473 install_element(CONFIG_NODE
, &debug_msdp_cmd
);
10474 install_element(CONFIG_NODE
, &no_debug_msdp_cmd
);
10475 install_element(CONFIG_NODE
, &debug_msdp_events_cmd
);
10476 install_element(CONFIG_NODE
, &no_debug_msdp_events_cmd
);
10477 install_element(CONFIG_NODE
, &debug_msdp_packets_cmd
);
10478 install_element(CONFIG_NODE
, &no_debug_msdp_packets_cmd
);
10479 install_element(CONFIG_NODE
, &debug_mtrace_cmd
);
10480 install_element(CONFIG_NODE
, &no_debug_mtrace_cmd
);
10481 install_element(CONFIG_NODE
, &debug_bsm_cmd
);
10482 install_element(CONFIG_NODE
, &no_debug_bsm_cmd
);
10484 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_member_cmd
);
10485 install_element(VRF_NODE
, &ip_msdp_mesh_group_member_cmd
);
10486 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
10487 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
10488 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_source_cmd
);
10489 install_element(VRF_NODE
, &ip_msdp_mesh_group_source_cmd
);
10490 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
10491 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
10492 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_cmd
);
10493 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_vrf_all_cmd
);
10494 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_cmd
);
10495 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_vrf_all_cmd
);
10496 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_cmd
);
10497 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_vrf_all_cmd
);
10498 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_cmd
);
10499 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_vrf_all_cmd
);
10500 install_element(VIEW_NODE
, &show_ip_pim_ssm_range_cmd
);
10501 install_element(VIEW_NODE
, &show_ip_pim_group_type_cmd
);
10502 install_element(VIEW_NODE
, &show_ip_pim_vxlan_sg_cmd
);
10503 install_element(VIEW_NODE
, &show_ip_pim_vxlan_sg_work_cmd
);
10504 install_element(INTERFACE_NODE
, &interface_pim_use_source_cmd
);
10505 install_element(INTERFACE_NODE
, &interface_no_pim_use_source_cmd
);
10506 /* Install BSM command */
10507 install_element(INTERFACE_NODE
, &ip_pim_bsm_cmd
);
10508 install_element(INTERFACE_NODE
, &no_ip_pim_bsm_cmd
);
10509 install_element(INTERFACE_NODE
, &ip_pim_ucast_bsm_cmd
);
10510 install_element(INTERFACE_NODE
, &no_ip_pim_ucast_bsm_cmd
);
10511 /* Install BFD command */
10512 install_element(INTERFACE_NODE
, &ip_pim_bfd_cmd
);
10513 install_element(INTERFACE_NODE
, &ip_pim_bfd_param_cmd
);
10514 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_cmd
);
10516 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_param_cmd
);
10517 #endif /* !HAVE_BFDD */