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"
65 #ifndef VTYSH_EXTRACT_PL
66 #include "pimd/pim_cmd_clippy.c"
69 static struct cmd_node interface_node
= {
70 INTERFACE_NODE
, "%s(config-if)# ", 1 /* vtysh ? yes */
73 static struct cmd_node debug_node
= {DEBUG_NODE
, "", 1};
75 static struct vrf
*pim_cmd_lookup_vrf(struct vty
*vty
, struct cmd_token
*argv
[],
76 const int argc
, int *idx
)
80 if (argv_find(argv
, argc
, "NAME", idx
))
81 vrf
= vrf_lookup_by_name(argv
[*idx
]->arg
);
83 vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
86 vty_out(vty
, "Specified VRF: %s does not exist\n",
92 static void pim_if_membership_clear(struct interface
*ifp
)
94 struct pim_interface
*pim_ifp
;
99 if (PIM_IF_TEST_PIM(pim_ifp
->options
)
100 && PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
104 pim_ifchannel_membership_clear(ifp
);
108 When PIM is disabled on interface, IGMPv3 local membership
109 information is not injected into PIM interface state.
111 The function pim_if_membership_refresh() fetches all IGMPv3 local
112 membership information into PIM. It is intented to be called
113 whenever PIM is enabled on the interface in order to collect missed
114 local membership information.
116 static void pim_if_membership_refresh(struct interface
*ifp
)
118 struct pim_interface
*pim_ifp
;
119 struct listnode
*sock_node
;
120 struct igmp_sock
*igmp
;
125 if (!PIM_IF_TEST_PIM(pim_ifp
->options
))
127 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
))
131 First clear off membership from all PIM (S,G) entries on the
135 pim_ifchannel_membership_clear(ifp
);
138 Then restore PIM (S,G) membership from all IGMPv3 (S,G) entries on
142 /* scan igmp sockets */
143 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
144 struct listnode
*grpnode
;
145 struct igmp_group
*grp
;
147 /* scan igmp groups */
148 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grpnode
,
150 struct listnode
*srcnode
;
151 struct igmp_source
*src
;
153 /* scan group sources */
154 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
,
157 if (IGMP_SOURCE_TEST_FORWARDING(
158 src
->source_flags
)) {
162 sizeof(struct prefix_sg
));
163 sg
.src
= src
->source_addr
;
164 sg
.grp
= grp
->group_addr
;
165 pim_ifchannel_local_membership_add(ifp
,
169 } /* scan group sources */
170 } /* scan igmp groups */
171 } /* scan igmp sockets */
174 Finally delete every PIM (S,G) entry lacking all state info
177 pim_ifchannel_delete_on_noinfo(ifp
);
180 static void pim_show_assert_helper(struct vty
*vty
,
181 struct pim_interface
*pim_ifp
,
182 struct pim_ifchannel
*ch
, time_t now
)
184 char ch_src_str
[INET_ADDRSTRLEN
];
185 char ch_grp_str
[INET_ADDRSTRLEN
];
186 char winner_str
[INET_ADDRSTRLEN
];
187 struct in_addr ifaddr
;
191 ifaddr
= pim_ifp
->primary_address
;
193 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
194 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
195 pim_inet4_dump("<assrt_win?>", ch
->ifassert_winner
, winner_str
,
198 pim_time_uptime(uptime
, sizeof(uptime
), now
- ch
->ifassert_creation
);
199 pim_time_timer_to_mmss(timer
, sizeof(timer
), ch
->t_ifassert_timer
);
201 vty_out(vty
, "%-16s %-15s %-15s %-15s %-6s %-15s %-8s %-5s\n",
202 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
, ch_grp_str
,
203 pim_ifchannel_ifassert_name(ch
->ifassert_state
), winner_str
,
207 static void pim_show_assert(struct pim_instance
*pim
, struct vty
*vty
)
209 struct pim_interface
*pim_ifp
;
210 struct pim_ifchannel
*ch
;
211 struct interface
*ifp
;
214 now
= pim_time_monotonic_sec();
217 "Interface Address Source Group State Winner Uptime Timer\n");
219 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
224 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
225 pim_show_assert_helper(vty
, pim_ifp
, ch
, now
);
226 } /* scan interface channels */
230 static void pim_show_assert_internal_helper(struct vty
*vty
,
231 struct pim_interface
*pim_ifp
,
232 struct pim_ifchannel
*ch
)
234 char ch_src_str
[INET_ADDRSTRLEN
];
235 char ch_grp_str
[INET_ADDRSTRLEN
];
236 struct in_addr ifaddr
;
238 ifaddr
= pim_ifp
->primary_address
;
240 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
241 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
242 vty_out(vty
, "%-16s %-15s %-15s %-15s %-3s %-3s %-3s %-4s\n",
243 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
, ch_grp_str
,
244 PIM_IF_FLAG_TEST_COULD_ASSERT(ch
->flags
) ? "yes" : "no",
245 pim_macro_ch_could_assert_eval(ch
) ? "yes" : "no",
246 PIM_IF_FLAG_TEST_ASSERT_TRACKING_DESIRED(ch
->flags
) ? "yes"
248 pim_macro_assert_tracking_desired_eval(ch
) ? "yes" : "no");
251 static void pim_show_assert_internal(struct pim_instance
*pim
, struct vty
*vty
)
253 struct pim_interface
*pim_ifp
;
254 struct pim_ifchannel
*ch
;
255 struct interface
*ifp
;
259 "ECA: Evaluate CouldAssert\n"
260 "ATD: AssertTrackingDesired\n"
261 "eATD: Evaluate AssertTrackingDesired\n\n");
264 "Interface Address Source Group CA eCA ATD eATD\n");
265 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
270 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
271 pim_show_assert_internal_helper(vty
, pim_ifp
, ch
);
272 } /* scan interface channels */
276 static void pim_show_assert_metric_helper(struct vty
*vty
,
277 struct pim_interface
*pim_ifp
,
278 struct pim_ifchannel
*ch
)
280 char ch_src_str
[INET_ADDRSTRLEN
];
281 char ch_grp_str
[INET_ADDRSTRLEN
];
282 char addr_str
[INET_ADDRSTRLEN
];
283 struct pim_assert_metric am
;
284 struct in_addr ifaddr
;
286 ifaddr
= pim_ifp
->primary_address
;
288 am
= pim_macro_spt_assert_metric(&ch
->upstream
->rpf
,
289 pim_ifp
->primary_address
);
291 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
292 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
293 pim_inet4_dump("<addr?>", am
.ip_address
, addr_str
, sizeof(addr_str
));
295 vty_out(vty
, "%-16s %-15s %-15s %-15s %-3s %4u %6u %-15s\n",
296 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
, ch_grp_str
,
297 am
.rpt_bit_flag
? "yes" : "no", am
.metric_preference
,
298 am
.route_metric
, addr_str
);
301 static void pim_show_assert_metric(struct pim_instance
*pim
, struct vty
*vty
)
303 struct pim_interface
*pim_ifp
;
304 struct pim_ifchannel
*ch
;
305 struct interface
*ifp
;
308 "Interface Address Source Group RPT Pref Metric Address \n");
310 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
315 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
316 pim_show_assert_metric_helper(vty
, pim_ifp
, ch
);
317 } /* scan interface channels */
321 static void pim_show_assert_winner_metric_helper(struct vty
*vty
,
322 struct pim_interface
*pim_ifp
,
323 struct pim_ifchannel
*ch
)
325 char ch_src_str
[INET_ADDRSTRLEN
];
326 char ch_grp_str
[INET_ADDRSTRLEN
];
327 char addr_str
[INET_ADDRSTRLEN
];
328 struct pim_assert_metric
*am
;
329 struct in_addr ifaddr
;
333 ifaddr
= pim_ifp
->primary_address
;
335 am
= &ch
->ifassert_winner_metric
;
337 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
338 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
339 pim_inet4_dump("<addr?>", am
->ip_address
, addr_str
, sizeof(addr_str
));
341 if (am
->metric_preference
== PIM_ASSERT_METRIC_PREFERENCE_MAX
)
342 snprintf(pref_str
, sizeof(pref_str
), "INFI");
344 snprintf(pref_str
, sizeof(pref_str
), "%4u",
345 am
->metric_preference
);
347 if (am
->route_metric
== PIM_ASSERT_ROUTE_METRIC_MAX
)
348 snprintf(metr_str
, sizeof(metr_str
), "INFI");
350 snprintf(metr_str
, sizeof(metr_str
), "%6u", am
->route_metric
);
352 vty_out(vty
, "%-16s %-15s %-15s %-15s %-3s %-4s %-6s %-15s\n",
353 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
, ch_grp_str
,
354 am
->rpt_bit_flag
? "yes" : "no", pref_str
, metr_str
, addr_str
);
357 static void pim_show_assert_winner_metric(struct pim_instance
*pim
,
360 struct pim_interface
*pim_ifp
;
361 struct pim_ifchannel
*ch
;
362 struct interface
*ifp
;
365 "Interface Address Source Group RPT Pref Metric Address \n");
367 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
372 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
373 pim_show_assert_winner_metric_helper(vty
, pim_ifp
, ch
);
374 } /* scan interface channels */
378 static void json_object_pim_ifp_add(struct json_object
*json
,
379 struct interface
*ifp
)
381 struct pim_interface
*pim_ifp
;
384 json_object_string_add(json
, "name", ifp
->name
);
385 json_object_string_add(json
, "state", if_is_up(ifp
) ? "up" : "down");
386 json_object_string_add(json
, "address",
387 inet_ntoa(pim_ifp
->primary_address
));
388 json_object_int_add(json
, "index", ifp
->ifindex
);
390 if (if_is_multicast(ifp
))
391 json_object_boolean_true_add(json
, "flagMulticast");
393 if (if_is_broadcast(ifp
))
394 json_object_boolean_true_add(json
, "flagBroadcast");
396 if (ifp
->flags
& IFF_ALLMULTI
)
397 json_object_boolean_true_add(json
, "flagAllMulticast");
399 if (ifp
->flags
& IFF_PROMISC
)
400 json_object_boolean_true_add(json
, "flagPromiscuous");
402 if (PIM_IF_IS_DELETED(ifp
))
403 json_object_boolean_true_add(json
, "flagDeleted");
405 if (pim_if_lan_delay_enabled(ifp
))
406 json_object_boolean_true_add(json
, "lanDelayEnabled");
409 static void pim_show_membership_helper(struct vty
*vty
,
410 struct pim_interface
*pim_ifp
,
411 struct pim_ifchannel
*ch
,
412 struct json_object
*json
)
414 char ch_src_str
[INET_ADDRSTRLEN
];
415 char ch_grp_str
[INET_ADDRSTRLEN
];
416 json_object
*json_iface
= NULL
;
417 json_object
*json_row
= NULL
;
419 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
420 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
422 json_object_object_get_ex(json
, ch
->interface
->name
, &json_iface
);
424 json_iface
= json_object_new_object();
425 json_object_pim_ifp_add(json_iface
, ch
->interface
);
426 json_object_object_add(json
, ch
->interface
->name
, json_iface
);
429 json_row
= json_object_new_object();
430 json_object_string_add(json_row
, "source", ch_src_str
);
431 json_object_string_add(json_row
, "group", ch_grp_str
);
432 json_object_string_add(json_row
, "localMembership",
433 ch
->local_ifmembership
== PIM_IFMEMBERSHIP_NOINFO
436 json_object_object_add(json_iface
, ch_grp_str
, json_row
);
438 static void pim_show_membership(struct pim_instance
*pim
, struct vty
*vty
,
441 struct pim_interface
*pim_ifp
;
442 struct pim_ifchannel
*ch
;
443 struct interface
*ifp
;
445 json_object
*json
= NULL
;
446 json_object
*json_tmp
= NULL
;
448 json
= json_object_new_object();
450 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
455 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
456 pim_show_membership_helper(vty
, pim_ifp
, ch
, json
);
457 } /* scan interface channels */
461 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
462 json
, JSON_C_TO_STRING_PRETTY
));
465 "Interface Address Source Group Membership\n");
468 * Example of the json data we are traversing
474 * "address":"10.1.20.1",
476 * "flagMulticast":true,
477 * "flagBroadcast":true,
478 * "lanDelayEnabled":true,
481 * "group":"226.10.10.10",
482 * "localMembership":"INCLUDE"
488 /* foreach interface */
489 json_object_object_foreach(json
, key
, val
)
492 /* Find all of the keys where the val is an object. In
494 * above the only one is 226.10.10.10
496 json_object_object_foreach(val
, if_field_key
,
499 type
= json_object_get_type(if_field_val
);
501 if (type
== json_type_object
) {
502 vty_out(vty
, "%-16s ", key
);
504 json_object_object_get_ex(
505 val
, "address", &json_tmp
);
506 vty_out(vty
, "%-15s ",
507 json_object_get_string(
510 json_object_object_get_ex(if_field_val
,
513 vty_out(vty
, "%-15s ",
514 json_object_get_string(
518 vty_out(vty
, "%-15s ", if_field_key
);
520 json_object_object_get_ex(
521 if_field_val
, "localMembership",
523 vty_out(vty
, "%-10s\n",
524 json_object_get_string(
531 json_object_free(json
);
534 static void pim_print_ifp_flags(struct vty
*vty
, struct interface
*ifp
,
537 vty_out(vty
, "Flags\n");
538 vty_out(vty
, "-----\n");
539 vty_out(vty
, "All Multicast : %s\n",
540 (ifp
->flags
& IFF_ALLMULTI
) ? "yes" : "no");
541 vty_out(vty
, "Broadcast : %s\n",
542 if_is_broadcast(ifp
) ? "yes" : "no");
543 vty_out(vty
, "Deleted : %s\n",
544 PIM_IF_IS_DELETED(ifp
) ? "yes" : "no");
545 vty_out(vty
, "Interface Index : %d\n", ifp
->ifindex
);
546 vty_out(vty
, "Multicast : %s\n",
547 if_is_multicast(ifp
) ? "yes" : "no");
548 vty_out(vty
, "Multicast Loop : %d\n", mloop
);
549 vty_out(vty
, "Promiscuous : %s\n",
550 (ifp
->flags
& IFF_PROMISC
) ? "yes" : "no");
555 static void igmp_show_interfaces(struct pim_instance
*pim
, struct vty
*vty
,
558 struct interface
*ifp
;
560 json_object
*json
= NULL
;
561 json_object
*json_row
= NULL
;
563 now
= pim_time_monotonic_sec();
566 json
= json_object_new_object();
569 "Interface State Address V Querier Query Timer Uptime\n");
571 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
572 struct pim_interface
*pim_ifp
;
573 struct listnode
*sock_node
;
574 struct igmp_sock
*igmp
;
581 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
584 char query_hhmmss
[10];
586 pim_time_uptime(uptime
, sizeof(uptime
),
587 now
- igmp
->sock_creation
);
588 pim_time_timer_to_hhmmss(query_hhmmss
,
589 sizeof(query_hhmmss
),
590 igmp
->t_igmp_query_timer
);
593 json_row
= json_object_new_object();
594 json_object_pim_ifp_add(json_row
, ifp
);
595 json_object_string_add(json_row
, "upTime",
597 json_object_int_add(json_row
, "version",
598 pim_ifp
->igmp_version
);
600 if (igmp
->t_igmp_query_timer
) {
601 json_object_boolean_true_add(json_row
,
603 json_object_string_add(json_row
,
608 json_object_object_add(json
, ifp
->name
,
611 if (igmp
->mtrace_only
) {
612 json_object_boolean_true_add(
613 json_row
, "mtraceOnly");
617 "%-16s %5s %15s %d %7s %11s %8s\n",
620 ? (igmp
->mtrace_only
? "mtrc"
623 inet_ntoa(igmp
->ifaddr
),
624 pim_ifp
->igmp_version
,
625 igmp
->t_igmp_query_timer
? "local"
627 query_hhmmss
, uptime
);
633 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
634 json
, JSON_C_TO_STRING_PRETTY
));
635 json_object_free(json
);
639 static void igmp_show_interfaces_single(struct pim_instance
*pim
,
640 struct vty
*vty
, const char *ifname
,
643 struct igmp_sock
*igmp
;
644 struct interface
*ifp
;
645 struct listnode
*sock_node
;
646 struct pim_interface
*pim_ifp
;
648 char query_hhmmss
[10];
649 char other_hhmmss
[10];
650 int found_ifname
= 0;
653 long gmi_msec
; /* Group Membership Interval */
656 long oqpi_msec
; /* Other Querier Present Interval */
660 json_object
*json
= NULL
;
661 json_object
*json_row
= NULL
;
664 json
= json_object_new_object();
666 now
= pim_time_monotonic_sec();
668 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
674 if (strcmp(ifname
, "detail") && strcmp(ifname
, ifp
->name
))
677 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
680 pim_time_uptime(uptime
, sizeof(uptime
),
681 now
- igmp
->sock_creation
);
682 pim_time_timer_to_hhmmss(query_hhmmss
,
683 sizeof(query_hhmmss
),
684 igmp
->t_igmp_query_timer
);
685 pim_time_timer_to_hhmmss(other_hhmmss
,
686 sizeof(other_hhmmss
),
687 igmp
->t_other_querier_timer
);
689 gmi_msec
= PIM_IGMP_GMI_MSEC(
690 igmp
->querier_robustness_variable
,
691 igmp
->querier_query_interval
,
692 pim_ifp
->igmp_query_max_response_time_dsec
);
695 pim_ifp
->igmp_default_query_interval
);
697 oqpi_msec
= PIM_IGMP_OQPI_MSEC(
698 igmp
->querier_robustness_variable
,
699 igmp
->querier_query_interval
,
700 pim_ifp
->igmp_query_max_response_time_dsec
);
702 lmqt_msec
= PIM_IGMP_LMQT_MSEC(
703 pim_ifp
->igmp_query_max_response_time_dsec
,
704 igmp
->querier_robustness_variable
);
708 igmp
->querier_robustness_variable
,
709 igmp
->querier_query_interval
,
710 pim_ifp
->igmp_query_max_response_time_dsec
)
713 qri_msec
= pim_ifp
->igmp_query_max_response_time_dsec
715 if (pim_ifp
->pim_sock_fd
>= 0)
716 mloop
= pim_socket_mcastloop_get(
717 pim_ifp
->pim_sock_fd
);
722 json_row
= json_object_new_object();
723 json_object_pim_ifp_add(json_row
, ifp
);
724 json_object_string_add(json_row
, "upTime",
726 json_object_string_add(json_row
, "querier",
727 igmp
->t_igmp_query_timer
730 json_object_int_add(json_row
, "queryStartCount",
731 igmp
->startup_query_count
);
732 json_object_string_add(json_row
,
735 json_object_string_add(json_row
,
738 json_object_int_add(json_row
, "version",
739 pim_ifp
->igmp_version
);
742 "timerGroupMembershipIntervalMsec",
744 json_object_int_add(json_row
,
745 "timerLastMemberQueryMsec",
749 "timerOlderHostPresentIntervalMsec",
753 "timerOtherQuerierPresentIntervalMsec",
756 json_row
, "timerQueryInterval",
757 igmp
->querier_query_interval
);
760 "timerQueryResponseIntervalMsec",
763 json_row
, "timerRobustnessVariable",
764 igmp
->querier_robustness_variable
);
765 json_object_int_add(json_row
,
766 "timerStartupQueryInterval",
769 json_object_object_add(json
, ifp
->name
,
772 if (igmp
->mtrace_only
) {
773 json_object_boolean_true_add(
774 json_row
, "mtraceOnly");
777 vty_out(vty
, "Interface : %s\n", ifp
->name
);
778 vty_out(vty
, "State : %s\n",
780 ? (igmp
->mtrace_only
? "mtrace"
783 vty_out(vty
, "Address : %s\n",
784 inet_ntoa(pim_ifp
->primary_address
));
785 vty_out(vty
, "Uptime : %s\n", uptime
);
786 vty_out(vty
, "Version : %d\n",
787 pim_ifp
->igmp_version
);
791 vty_out(vty
, "Querier\n");
792 vty_out(vty
, "-------\n");
793 vty_out(vty
, "Querier : %s\n",
794 igmp
->t_igmp_query_timer
? "local"
796 vty_out(vty
, "Start Count : %d\n",
797 igmp
->startup_query_count
);
798 vty_out(vty
, "Query Timer : %s\n",
800 vty_out(vty
, "Other Timer : %s\n",
805 vty_out(vty
, "Timers\n");
806 vty_out(vty
, "------\n");
808 "Group Membership Interval : %lis\n",
811 "Last Member Query Time : %lis\n",
814 "Older Host Present Interval : %lis\n",
817 "Other Querier Present Interval : %lis\n",
820 "Query Interval : %ds\n",
821 igmp
->querier_query_interval
);
823 "Query Response Interval : %lis\n",
826 "Robustness Variable : %d\n",
827 igmp
->querier_robustness_variable
);
829 "Startup Query Interval : %ds\n",
834 pim_print_ifp_flags(vty
, ifp
, mloop
);
840 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
841 json
, JSON_C_TO_STRING_PRETTY
));
842 json_object_free(json
);
845 vty_out(vty
, "%% No such interface\n");
849 static void igmp_show_interface_join(struct pim_instance
*pim
, struct vty
*vty
)
851 struct interface
*ifp
;
854 now
= pim_time_monotonic_sec();
857 "Interface Address Source Group Socket Uptime \n");
859 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
860 struct pim_interface
*pim_ifp
;
861 struct listnode
*join_node
;
862 struct igmp_join
*ij
;
863 struct in_addr pri_addr
;
864 char pri_addr_str
[INET_ADDRSTRLEN
];
871 if (!pim_ifp
->igmp_join_list
)
874 pri_addr
= pim_find_primary_addr(ifp
);
875 pim_inet4_dump("<pri?>", pri_addr
, pri_addr_str
,
876 sizeof(pri_addr_str
));
878 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_join_list
, join_node
,
880 char group_str
[INET_ADDRSTRLEN
];
881 char source_str
[INET_ADDRSTRLEN
];
884 pim_time_uptime(uptime
, sizeof(uptime
),
885 now
- ij
->sock_creation
);
886 pim_inet4_dump("<grp?>", ij
->group_addr
, group_str
,
888 pim_inet4_dump("<src?>", ij
->source_addr
, source_str
,
891 vty_out(vty
, "%-16s %-15s %-15s %-15s %6d %8s\n",
892 ifp
->name
, pri_addr_str
, source_str
, group_str
,
893 ij
->sock_fd
, uptime
);
894 } /* for (pim_ifp->igmp_join_list) */
899 static void pim_show_interfaces_single(struct pim_instance
*pim
,
900 struct vty
*vty
, const char *ifname
,
903 struct in_addr ifaddr
;
904 struct interface
*ifp
;
905 struct listnode
*neighnode
;
906 struct listnode
*upnode
;
907 struct pim_interface
*pim_ifp
;
908 struct pim_neighbor
*neigh
;
909 struct pim_upstream
*up
;
911 char dr_str
[INET_ADDRSTRLEN
];
914 char grp_str
[INET_ADDRSTRLEN
];
915 char hello_period
[10];
916 char hello_timer
[10];
917 char neigh_src_str
[INET_ADDRSTRLEN
];
918 char src_str
[INET_ADDRSTRLEN
];
919 char stat_uptime
[10];
922 int found_ifname
= 0;
924 json_object
*json
= NULL
;
925 json_object
*json_row
= NULL
;
926 json_object
*json_pim_neighbor
= NULL
;
927 json_object
*json_pim_neighbors
= NULL
;
928 json_object
*json_group
= NULL
;
929 json_object
*json_group_source
= NULL
;
930 json_object
*json_fhr_sources
= NULL
;
931 struct pim_secondary_addr
*sec_addr
;
932 struct listnode
*sec_node
;
934 now
= pim_time_monotonic_sec();
937 json
= json_object_new_object();
939 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
945 if (strcmp(ifname
, "detail") && strcmp(ifname
, ifp
->name
))
949 ifaddr
= pim_ifp
->primary_address
;
950 pim_inet4_dump("<dr?>", pim_ifp
->pim_dr_addr
, dr_str
,
952 pim_time_uptime_begin(dr_uptime
, sizeof(dr_uptime
), now
,
953 pim_ifp
->pim_dr_election_last
);
954 pim_time_timer_to_hhmmss(hello_timer
, sizeof(hello_timer
),
955 pim_ifp
->t_pim_hello_timer
);
956 pim_time_mmss(hello_period
, sizeof(hello_period
),
957 pim_ifp
->pim_hello_period
);
958 pim_time_uptime(stat_uptime
, sizeof(stat_uptime
),
959 now
- pim_ifp
->pim_ifstat_start
);
960 if (pim_ifp
->pim_sock_fd
>= 0)
961 mloop
= pim_socket_mcastloop_get(pim_ifp
->pim_sock_fd
);
966 char pbuf
[PREFIX2STR_BUFFER
];
967 json_row
= json_object_new_object();
968 json_object_pim_ifp_add(json_row
, ifp
);
970 if (pim_ifp
->update_source
.s_addr
!= INADDR_ANY
) {
971 json_object_string_add(
972 json_row
, "useSource",
973 inet_ntoa(pim_ifp
->update_source
));
975 if (pim_ifp
->sec_addr_list
) {
976 json_object
*sec_list
= NULL
;
978 sec_list
= json_object_new_array();
979 for (ALL_LIST_ELEMENTS_RO(
980 pim_ifp
->sec_addr_list
, sec_node
,
982 json_object_array_add(
984 json_object_new_string(
990 json_object_object_add(json_row
,
991 "secondaryAddressList",
996 if (pim_ifp
->pim_neighbor_list
->count
) {
997 json_pim_neighbors
= json_object_new_object();
999 for (ALL_LIST_ELEMENTS_RO(
1000 pim_ifp
->pim_neighbor_list
,
1001 neighnode
, neigh
)) {
1003 json_object_new_object();
1004 pim_inet4_dump("<src?>",
1007 sizeof(neigh_src_str
));
1008 pim_time_uptime(uptime
, sizeof(uptime
),
1009 now
- neigh
->creation
);
1010 pim_time_timer_to_hhmmss(
1011 expire
, sizeof(expire
),
1012 neigh
->t_expire_timer
);
1014 json_object_string_add(
1015 json_pim_neighbor
, "address",
1017 json_object_string_add(
1018 json_pim_neighbor
, "upTime",
1020 json_object_string_add(
1021 json_pim_neighbor
, "holdtime",
1024 json_object_object_add(
1030 json_object_object_add(json_row
, "neighbors",
1031 json_pim_neighbors
);
1034 json_object_string_add(json_row
, "drAddress", dr_str
);
1035 json_object_int_add(json_row
, "drPriority",
1036 pim_ifp
->pim_dr_priority
);
1037 json_object_string_add(json_row
, "drUptime", dr_uptime
);
1038 json_object_int_add(json_row
, "drElections",
1039 pim_ifp
->pim_dr_election_count
);
1040 json_object_int_add(json_row
, "drChanges",
1041 pim_ifp
->pim_dr_election_changes
);
1044 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
,
1046 if (ifp
!= up
->rpf
.source_nexthop
.interface
)
1049 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
))
1052 if (!json_fhr_sources
)
1054 json_object_new_object();
1056 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
,
1058 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
,
1060 pim_time_uptime(uptime
, sizeof(uptime
),
1061 now
- up
->state_transition
);
1064 * Does this group live in json_fhr_sources?
1067 json_object_object_get_ex(json_fhr_sources
,
1068 grp_str
, &json_group
);
1071 json_group
= json_object_new_object();
1072 json_object_object_add(json_fhr_sources
,
1077 json_group_source
= json_object_new_object();
1078 json_object_string_add(json_group_source
,
1080 json_object_string_add(json_group_source
,
1082 json_object_string_add(json_group_source
,
1084 json_object_object_add(json_group
, src_str
,
1088 if (json_fhr_sources
) {
1089 json_object_object_add(json_row
,
1094 json_object_int_add(json_row
, "helloPeriod",
1095 pim_ifp
->pim_hello_period
);
1096 json_object_string_add(json_row
, "helloTimer",
1098 json_object_string_add(json_row
, "helloStatStart",
1100 json_object_int_add(json_row
, "helloReceived",
1101 pim_ifp
->pim_ifstat_hello_recv
);
1102 json_object_int_add(json_row
, "helloReceivedFailed",
1103 pim_ifp
->pim_ifstat_hello_recvfail
);
1104 json_object_int_add(json_row
, "helloSend",
1105 pim_ifp
->pim_ifstat_hello_sent
);
1106 json_object_int_add(json_row
, "hellosendFailed",
1107 pim_ifp
->pim_ifstat_hello_sendfail
);
1108 json_object_int_add(json_row
, "helloGenerationId",
1109 pim_ifp
->pim_generation_id
);
1110 json_object_int_add(json_row
, "flagMulticastLoop",
1113 json_object_int_add(
1114 json_row
, "effectivePropagationDelay",
1115 pim_if_effective_propagation_delay_msec(ifp
));
1116 json_object_int_add(
1117 json_row
, "effectiveOverrideInterval",
1118 pim_if_effective_override_interval_msec(ifp
));
1119 json_object_int_add(
1120 json_row
, "joinPruneOverrideInterval",
1121 pim_if_jp_override_interval_msec(ifp
));
1123 json_object_int_add(
1124 json_row
, "propagationDelay",
1125 pim_ifp
->pim_propagation_delay_msec
);
1126 json_object_int_add(
1127 json_row
, "propagationDelayHighest",
1128 pim_ifp
->pim_neighbors_highest_propagation_delay_msec
);
1129 json_object_int_add(
1130 json_row
, "overrideInterval",
1131 pim_ifp
->pim_override_interval_msec
);
1132 json_object_int_add(
1133 json_row
, "overrideIntervalHighest",
1134 pim_ifp
->pim_neighbors_highest_override_interval_msec
);
1135 json_object_object_add(json
, ifp
->name
, json_row
);
1138 vty_out(vty
, "Interface : %s\n", ifp
->name
);
1139 vty_out(vty
, "State : %s\n",
1140 if_is_up(ifp
) ? "up" : "down");
1141 if (pim_ifp
->update_source
.s_addr
!= INADDR_ANY
) {
1142 vty_out(vty
, "Use Source : %s\n",
1143 inet_ntoa(pim_ifp
->update_source
));
1145 if (pim_ifp
->sec_addr_list
) {
1146 char pbuf
[PREFIX2STR_BUFFER
];
1147 vty_out(vty
, "Address : %s (primary)\n",
1149 for (ALL_LIST_ELEMENTS_RO(
1150 pim_ifp
->sec_addr_list
, sec_node
,
1152 vty_out(vty
, " %s\n",
1153 prefix2str(&sec_addr
->addr
,
1154 pbuf
, sizeof(pbuf
)));
1157 vty_out(vty
, "Address : %s\n",
1165 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
,
1166 neighnode
, neigh
)) {
1169 vty_out(vty
, "PIM Neighbors\n");
1170 vty_out(vty
, "-------------\n");
1174 pim_inet4_dump("<src?>", neigh
->source_addr
,
1176 sizeof(neigh_src_str
));
1177 pim_time_uptime(uptime
, sizeof(uptime
),
1178 now
- neigh
->creation
);
1179 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
1180 neigh
->t_expire_timer
);
1182 "%-15s : up for %s, holdtime expires in %s\n",
1183 neigh_src_str
, uptime
, expire
);
1186 if (!print_header
) {
1191 vty_out(vty
, "Designated Router\n");
1192 vty_out(vty
, "-----------------\n");
1193 vty_out(vty
, "Address : %s\n", dr_str
);
1194 vty_out(vty
, "Priority : %u(%d)\n",
1195 pim_ifp
->pim_dr_priority
,
1196 pim_ifp
->pim_dr_num_nondrpri_neighbors
);
1197 vty_out(vty
, "Uptime : %s\n", dr_uptime
);
1198 vty_out(vty
, "Elections : %d\n",
1199 pim_ifp
->pim_dr_election_count
);
1200 vty_out(vty
, "Changes : %d\n",
1201 pim_ifp
->pim_dr_election_changes
);
1207 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
,
1210 if (strcmp(ifp
->name
,
1211 up
->rpf
.source_nexthop
1216 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
))
1221 "FHR - First Hop Router\n");
1223 "----------------------\n");
1227 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
,
1229 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
,
1231 pim_time_uptime(uptime
, sizeof(uptime
),
1232 now
- up
->state_transition
);
1234 "%s : %s is a source, uptime is %s\n",
1235 grp_str
, src_str
, uptime
);
1238 if (!print_header
) {
1243 vty_out(vty
, "Hellos\n");
1244 vty_out(vty
, "------\n");
1245 vty_out(vty
, "Period : %d\n",
1246 pim_ifp
->pim_hello_period
);
1247 vty_out(vty
, "Timer : %s\n", hello_timer
);
1248 vty_out(vty
, "StatStart : %s\n", stat_uptime
);
1249 vty_out(vty
, "Receive : %d\n",
1250 pim_ifp
->pim_ifstat_hello_recv
);
1251 vty_out(vty
, "Receive Failed : %d\n",
1252 pim_ifp
->pim_ifstat_hello_recvfail
);
1253 vty_out(vty
, "Send : %d\n",
1254 pim_ifp
->pim_ifstat_hello_sent
);
1255 vty_out(vty
, "Send Failed : %d\n",
1256 pim_ifp
->pim_ifstat_hello_sendfail
);
1257 vty_out(vty
, "Generation ID : %08x\n",
1258 pim_ifp
->pim_generation_id
);
1262 pim_print_ifp_flags(vty
, ifp
, mloop
);
1264 vty_out(vty
, "Join Prune Interval\n");
1265 vty_out(vty
, "-------------------\n");
1266 vty_out(vty
, "LAN Delay : %s\n",
1267 pim_if_lan_delay_enabled(ifp
) ? "yes" : "no");
1268 vty_out(vty
, "Effective Propagation Delay : %d msec\n",
1269 pim_if_effective_propagation_delay_msec(ifp
));
1270 vty_out(vty
, "Effective Override Interval : %d msec\n",
1271 pim_if_effective_override_interval_msec(ifp
));
1272 vty_out(vty
, "Join Prune Override Interval : %d msec\n",
1273 pim_if_jp_override_interval_msec(ifp
));
1277 vty_out(vty
, "LAN Prune Delay\n");
1278 vty_out(vty
, "---------------\n");
1279 vty_out(vty
, "Propagation Delay : %d msec\n",
1280 pim_ifp
->pim_propagation_delay_msec
);
1281 vty_out(vty
, "Propagation Delay (Highest) : %d msec\n",
1282 pim_ifp
->pim_neighbors_highest_propagation_delay_msec
);
1283 vty_out(vty
, "Override Interval : %d msec\n",
1284 pim_ifp
->pim_override_interval_msec
);
1285 vty_out(vty
, "Override Interval (Highest) : %d msec\n",
1286 pim_ifp
->pim_neighbors_highest_override_interval_msec
);
1293 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1294 json
, JSON_C_TO_STRING_PRETTY
));
1295 json_object_free(json
);
1298 vty_out(vty
, "%% No such interface\n");
1302 static void igmp_show_statistics(struct pim_instance
*pim
, struct vty
*vty
,
1303 const char *ifname
, bool uj
)
1305 struct interface
*ifp
;
1306 struct igmp_stats rx_stats
;
1308 igmp_stats_init(&rx_stats
);
1310 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1311 struct pim_interface
*pim_ifp
;
1312 struct listnode
*sock_node
;
1313 struct igmp_sock
*igmp
;
1315 pim_ifp
= ifp
->info
;
1320 if (ifname
&& strcmp(ifname
, ifp
->name
))
1323 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
1325 igmp_stats_add(&rx_stats
, &igmp
->rx_stats
);
1329 json_object
*json
= NULL
;
1330 json_object
*json_row
= NULL
;
1332 json
= json_object_new_object();
1333 json_row
= json_object_new_object();
1335 json_object_string_add(json_row
, "name", ifname
? ifname
:
1337 json_object_int_add(json_row
, "queryV1", rx_stats
.query_v1
);
1338 json_object_int_add(json_row
, "queryV2", rx_stats
.query_v2
);
1339 json_object_int_add(json_row
, "queryV3", rx_stats
.query_v3
);
1340 json_object_int_add(json_row
, "leaveV3", rx_stats
.leave_v2
);
1341 json_object_int_add(json_row
, "reportV1", rx_stats
.report_v1
);
1342 json_object_int_add(json_row
, "reportV2", rx_stats
.report_v2
);
1343 json_object_int_add(json_row
, "reportV3", rx_stats
.report_v3
);
1344 json_object_int_add(json_row
, "mtraceResponse",
1345 rx_stats
.mtrace_rsp
);
1346 json_object_int_add(json_row
, "mtraceRequest",
1347 rx_stats
.mtrace_req
);
1348 json_object_int_add(json_row
, "unsupported",
1349 rx_stats
.unsupported
);
1350 json_object_object_add(json
, ifname
? ifname
: "global",
1352 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1353 json
, JSON_C_TO_STRING_PRETTY
));
1354 json_object_free(json
);
1356 vty_out(vty
, "IGMP RX statistics\n");
1357 vty_out(vty
, "Interface : %s\n",
1358 ifname
? ifname
: "global");
1359 vty_out(vty
, "V1 query : %u\n", rx_stats
.query_v1
);
1360 vty_out(vty
, "V2 query : %u\n", rx_stats
.query_v2
);
1361 vty_out(vty
, "V3 query : %u\n", rx_stats
.query_v3
);
1362 vty_out(vty
, "V2 leave : %u\n", rx_stats
.leave_v2
);
1363 vty_out(vty
, "V1 report : %u\n", rx_stats
.report_v1
);
1364 vty_out(vty
, "V2 report : %u\n", rx_stats
.report_v2
);
1365 vty_out(vty
, "V3 report : %u\n", rx_stats
.report_v3
);
1366 vty_out(vty
, "mtrace response : %u\n", rx_stats
.mtrace_rsp
);
1367 vty_out(vty
, "mtrace request : %u\n", rx_stats
.mtrace_req
);
1368 vty_out(vty
, "unsupported : %u\n", rx_stats
.unsupported
);
1372 static void pim_show_interfaces(struct pim_instance
*pim
, struct vty
*vty
,
1375 struct interface
*ifp
;
1376 struct listnode
*upnode
;
1377 struct pim_interface
*pim_ifp
;
1378 struct pim_upstream
*up
;
1381 int pim_ifchannels
= 0;
1382 json_object
*json
= NULL
;
1383 json_object
*json_row
= NULL
;
1384 json_object
*json_tmp
;
1386 json
= json_object_new_object();
1388 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1389 pim_ifp
= ifp
->info
;
1394 pim_nbrs
= pim_ifp
->pim_neighbor_list
->count
;
1395 pim_ifchannels
= pim_if_ifchannel_count(pim_ifp
);
1398 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
, up
))
1399 if (ifp
== up
->rpf
.source_nexthop
.interface
)
1400 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
1403 json_row
= json_object_new_object();
1404 json_object_pim_ifp_add(json_row
, ifp
);
1405 json_object_int_add(json_row
, "pimNeighbors", pim_nbrs
);
1406 json_object_int_add(json_row
, "pimIfChannels", pim_ifchannels
);
1407 json_object_int_add(json_row
, "firstHopRouterCount", fhr
);
1408 json_object_string_add(json_row
, "pimDesignatedRouter",
1409 inet_ntoa(pim_ifp
->pim_dr_addr
));
1411 if (pim_ifp
->pim_dr_addr
.s_addr
1412 == pim_ifp
->primary_address
.s_addr
)
1413 json_object_boolean_true_add(
1414 json_row
, "pimDesignatedRouterLocal");
1416 json_object_object_add(json
, ifp
->name
, json_row
);
1420 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1421 json
, JSON_C_TO_STRING_PRETTY
));
1424 "Interface State Address PIM Nbrs PIM DR FHR IfChannels\n");
1426 json_object_object_foreach(json
, key
, val
)
1428 vty_out(vty
, "%-16s ", key
);
1430 json_object_object_get_ex(val
, "state", &json_tmp
);
1431 vty_out(vty
, "%5s ", json_object_get_string(json_tmp
));
1433 json_object_object_get_ex(val
, "address", &json_tmp
);
1434 vty_out(vty
, "%15s ",
1435 json_object_get_string(json_tmp
));
1437 json_object_object_get_ex(val
, "pimNeighbors",
1439 vty_out(vty
, "%8d ", json_object_get_int(json_tmp
));
1441 if (json_object_object_get_ex(
1442 val
, "pimDesignatedRouterLocal",
1444 vty_out(vty
, "%15s ", "local");
1446 json_object_object_get_ex(
1447 val
, "pimDesignatedRouter", &json_tmp
);
1448 vty_out(vty
, "%15s ",
1449 json_object_get_string(json_tmp
));
1452 json_object_object_get_ex(val
, "firstHopRouter",
1454 vty_out(vty
, "%3d ", json_object_get_int(json_tmp
));
1456 json_object_object_get_ex(val
, "pimIfChannels",
1458 vty_out(vty
, "%9d\n", json_object_get_int(json_tmp
));
1462 json_object_free(json
);
1465 static void pim_show_interface_traffic(struct pim_instance
*pim
,
1466 struct vty
*vty
, bool uj
)
1468 struct interface
*ifp
= NULL
;
1469 struct pim_interface
*pim_ifp
= NULL
;
1470 json_object
*json
= NULL
;
1471 json_object
*json_row
= NULL
;
1474 json
= json_object_new_object();
1477 vty_out(vty
, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s\n",
1478 "Interface", " HELLO", " JOIN",
1479 " PRUNE", " REGISTER", "REGISTER-STOP",
1481 vty_out(vty
, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s\n", "",
1482 " Rx/Tx", " Rx/Tx", " Rx/Tx",
1483 " Rx/Tx", " Rx/Tx", " Rx/Tx");
1485 "---------------------------------------------------------------------------------------------------------------\n");
1488 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1489 pim_ifp
= ifp
->info
;
1494 if (pim_ifp
->pim_sock_fd
< 0)
1497 json_row
= json_object_new_object();
1498 json_object_pim_ifp_add(json_row
, ifp
);
1499 json_object_int_add(json_row
, "helloRx",
1500 pim_ifp
->pim_ifstat_hello_recv
);
1501 json_object_int_add(json_row
, "helloTx",
1502 pim_ifp
->pim_ifstat_hello_sent
);
1503 json_object_int_add(json_row
, "joinRx",
1504 pim_ifp
->pim_ifstat_join_recv
);
1505 json_object_int_add(json_row
, "joinTx",
1506 pim_ifp
->pim_ifstat_join_send
);
1507 json_object_int_add(json_row
, "registerRx",
1508 pim_ifp
->pim_ifstat_reg_recv
);
1509 json_object_int_add(json_row
, "registerTx",
1510 pim_ifp
->pim_ifstat_reg_recv
);
1511 json_object_int_add(json_row
, "registerStopRx",
1512 pim_ifp
->pim_ifstat_reg_stop_recv
);
1513 json_object_int_add(json_row
, "registerStopTx",
1514 pim_ifp
->pim_ifstat_reg_stop_send
);
1515 json_object_int_add(json_row
, "assertRx",
1516 pim_ifp
->pim_ifstat_assert_recv
);
1517 json_object_int_add(json_row
, "assertTx",
1518 pim_ifp
->pim_ifstat_assert_send
);
1520 json_object_object_add(json
, ifp
->name
, json_row
);
1523 "%-16s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u \n",
1524 ifp
->name
, pim_ifp
->pim_ifstat_hello_recv
,
1525 pim_ifp
->pim_ifstat_hello_sent
,
1526 pim_ifp
->pim_ifstat_join_recv
,
1527 pim_ifp
->pim_ifstat_join_send
,
1528 pim_ifp
->pim_ifstat_prune_recv
,
1529 pim_ifp
->pim_ifstat_prune_send
,
1530 pim_ifp
->pim_ifstat_reg_recv
,
1531 pim_ifp
->pim_ifstat_reg_send
,
1532 pim_ifp
->pim_ifstat_reg_stop_recv
,
1533 pim_ifp
->pim_ifstat_reg_stop_send
,
1534 pim_ifp
->pim_ifstat_assert_recv
,
1535 pim_ifp
->pim_ifstat_assert_send
);
1539 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1540 json
, JSON_C_TO_STRING_PRETTY
));
1541 json_object_free(json
);
1545 static void pim_show_interface_traffic_single(struct pim_instance
*pim
,
1547 const char *ifname
, bool uj
)
1549 struct interface
*ifp
= NULL
;
1550 struct pim_interface
*pim_ifp
= NULL
;
1551 json_object
*json
= NULL
;
1552 json_object
*json_row
= NULL
;
1553 uint8_t found_ifname
= 0;
1556 json
= json_object_new_object();
1559 vty_out(vty
, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s\n",
1560 "Interface", " HELLO", " JOIN", " PRUNE",
1561 " REGISTER", " REGISTER-STOP", " ASSERT");
1562 vty_out(vty
, "%-14s%-18s%-17s%-17s%-17s%-17s%-17s\n", "",
1563 " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1564 " Rx/Tx", " Rx/Tx");
1566 "---------------------------------------------------------------------------------------------------------------------\n");
1569 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1570 if (strcmp(ifname
, ifp
->name
))
1573 pim_ifp
= ifp
->info
;
1578 if (pim_ifp
->pim_sock_fd
< 0)
1583 json_row
= json_object_new_object();
1584 json_object_pim_ifp_add(json_row
, ifp
);
1585 json_object_int_add(json_row
, "helloRx",
1586 pim_ifp
->pim_ifstat_hello_recv
);
1587 json_object_int_add(json_row
, "helloTx",
1588 pim_ifp
->pim_ifstat_hello_sent
);
1589 json_object_int_add(json_row
, "joinRx",
1590 pim_ifp
->pim_ifstat_join_recv
);
1591 json_object_int_add(json_row
, "joinTx",
1592 pim_ifp
->pim_ifstat_join_send
);
1593 json_object_int_add(json_row
, "registerRx",
1594 pim_ifp
->pim_ifstat_reg_recv
);
1595 json_object_int_add(json_row
, "registerTx",
1596 pim_ifp
->pim_ifstat_reg_recv
);
1597 json_object_int_add(json_row
, "registerStopRx",
1598 pim_ifp
->pim_ifstat_reg_stop_recv
);
1599 json_object_int_add(json_row
, "registerStopTx",
1600 pim_ifp
->pim_ifstat_reg_stop_send
);
1601 json_object_int_add(json_row
, "assertRx",
1602 pim_ifp
->pim_ifstat_assert_recv
);
1603 json_object_int_add(json_row
, "assertTx",
1604 pim_ifp
->pim_ifstat_assert_send
);
1606 json_object_object_add(json
, ifp
->name
, json_row
);
1609 "%-16s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u \n",
1610 ifp
->name
, pim_ifp
->pim_ifstat_hello_recv
,
1611 pim_ifp
->pim_ifstat_hello_sent
,
1612 pim_ifp
->pim_ifstat_join_recv
,
1613 pim_ifp
->pim_ifstat_join_send
,
1614 pim_ifp
->pim_ifstat_prune_recv
,
1615 pim_ifp
->pim_ifstat_prune_send
,
1616 pim_ifp
->pim_ifstat_reg_recv
,
1617 pim_ifp
->pim_ifstat_reg_send
,
1618 pim_ifp
->pim_ifstat_reg_stop_recv
,
1619 pim_ifp
->pim_ifstat_reg_stop_send
,
1620 pim_ifp
->pim_ifstat_assert_recv
,
1621 pim_ifp
->pim_ifstat_assert_send
);
1625 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1626 json
, JSON_C_TO_STRING_PRETTY
));
1627 json_object_free(json
);
1630 vty_out(vty
, "%% No such interface\n");
1634 static void pim_show_join_helper(struct vty
*vty
, struct pim_interface
*pim_ifp
,
1635 struct pim_ifchannel
*ch
, json_object
*json
,
1636 time_t now
, bool uj
)
1638 char ch_src_str
[INET_ADDRSTRLEN
];
1639 char ch_grp_str
[INET_ADDRSTRLEN
];
1640 json_object
*json_iface
= NULL
;
1641 json_object
*json_row
= NULL
;
1642 json_object
*json_grp
= NULL
;
1643 struct in_addr ifaddr
;
1648 ifaddr
= pim_ifp
->primary_address
;
1650 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
1651 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
1653 pim_time_uptime_begin(uptime
, sizeof(uptime
), now
, ch
->ifjoin_creation
);
1654 pim_time_timer_to_mmss(expire
, sizeof(expire
),
1655 ch
->t_ifjoin_expiry_timer
);
1656 pim_time_timer_to_mmss(prune
, sizeof(prune
),
1657 ch
->t_ifjoin_prune_pending_timer
);
1660 json_object_object_get_ex(json
, ch
->interface
->name
,
1664 json_iface
= json_object_new_object();
1665 json_object_pim_ifp_add(json_iface
, ch
->interface
);
1666 json_object_object_add(json
, ch
->interface
->name
,
1670 json_row
= json_object_new_object();
1671 json_object_string_add(json_row
, "source", ch_src_str
);
1672 json_object_string_add(json_row
, "group", ch_grp_str
);
1673 json_object_string_add(json_row
, "upTime", uptime
);
1674 json_object_string_add(json_row
, "expire", expire
);
1675 json_object_string_add(json_row
, "prune", prune
);
1676 json_object_string_add(
1677 json_row
, "channelJoinName",
1678 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
, ch
->flags
));
1679 if (PIM_IF_FLAG_TEST_S_G_RPT(ch
->flags
))
1680 json_object_int_add(json_row
, "SGRpt", 1);
1682 json_object_object_get_ex(json_iface
, ch_grp_str
, &json_grp
);
1684 json_grp
= json_object_new_object();
1685 json_object_object_add(json_grp
, ch_src_str
, json_row
);
1686 json_object_object_add(json_iface
, ch_grp_str
,
1689 json_object_object_add(json_grp
, ch_src_str
, json_row
);
1691 vty_out(vty
, "%-16s %-15s %-15s %-15s %-10s %8s %-6s %5s\n",
1692 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
,
1694 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
, ch
->flags
),
1695 uptime
, expire
, prune
);
1699 static void pim_show_join(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
1701 struct pim_interface
*pim_ifp
;
1702 struct pim_ifchannel
*ch
;
1703 struct interface
*ifp
;
1705 json_object
*json
= NULL
;
1707 now
= pim_time_monotonic_sec();
1710 json
= json_object_new_object();
1713 "Interface Address Source Group State Uptime Expire Prune\n");
1715 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1716 pim_ifp
= ifp
->info
;
1720 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
1721 pim_show_join_helper(vty
, pim_ifp
, ch
, json
, now
, uj
);
1722 } /* scan interface channels */
1726 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1727 json
, JSON_C_TO_STRING_PRETTY
));
1728 json_object_free(json
);
1732 static void pim_show_neighbors_single(struct pim_instance
*pim
, struct vty
*vty
,
1733 const char *neighbor
, bool uj
)
1735 struct listnode
*neighnode
;
1736 struct interface
*ifp
;
1737 struct pim_interface
*pim_ifp
;
1738 struct pim_neighbor
*neigh
;
1740 int found_neighbor
= 0;
1741 int option_address_list
;
1742 int option_dr_priority
;
1743 int option_generation_id
;
1744 int option_holdtime
;
1745 int option_lan_prune_delay
;
1749 char neigh_src_str
[INET_ADDRSTRLEN
];
1751 json_object
*json
= NULL
;
1752 json_object
*json_ifp
= NULL
;
1753 json_object
*json_row
= NULL
;
1755 now
= pim_time_monotonic_sec();
1758 json
= json_object_new_object();
1760 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1761 pim_ifp
= ifp
->info
;
1766 if (pim_ifp
->pim_sock_fd
< 0)
1769 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
1771 pim_inet4_dump("<src?>", neigh
->source_addr
,
1772 neigh_src_str
, sizeof(neigh_src_str
));
1775 * The user can specify either the interface name or the
1777 * If this pim_ifp matches neither then skip.
1779 if (strcmp(neighbor
, "detail")
1780 && strcmp(neighbor
, ifp
->name
)
1781 && strcmp(neighbor
, neigh_src_str
))
1785 pim_time_uptime(uptime
, sizeof(uptime
),
1786 now
- neigh
->creation
);
1787 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
1788 neigh
->t_expire_timer
);
1790 option_address_list
= 0;
1791 option_dr_priority
= 0;
1792 option_generation_id
= 0;
1793 option_holdtime
= 0;
1794 option_lan_prune_delay
= 0;
1797 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1798 PIM_OPTION_MASK_ADDRESS_LIST
))
1799 option_address_list
= 1;
1801 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1802 PIM_OPTION_MASK_DR_PRIORITY
))
1803 option_dr_priority
= 1;
1805 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1806 PIM_OPTION_MASK_GENERATION_ID
))
1807 option_generation_id
= 1;
1809 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1810 PIM_OPTION_MASK_HOLDTIME
))
1811 option_holdtime
= 1;
1813 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1814 PIM_OPTION_MASK_LAN_PRUNE_DELAY
))
1815 option_lan_prune_delay
= 1;
1817 if (PIM_OPTION_IS_SET(
1818 neigh
->hello_options
,
1819 PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION
))
1824 /* Does this ifp live in json? If not create
1826 json_object_object_get_ex(json
, ifp
->name
,
1830 json_ifp
= json_object_new_object();
1831 json_object_pim_ifp_add(json_ifp
, ifp
);
1832 json_object_object_add(json
, ifp
->name
,
1836 json_row
= json_object_new_object();
1837 json_object_string_add(json_row
, "interface",
1839 json_object_string_add(json_row
, "address",
1841 json_object_string_add(json_row
, "upTime",
1843 json_object_string_add(json_row
, "holdtime",
1845 json_object_int_add(json_row
, "drPriority",
1846 neigh
->dr_priority
);
1847 json_object_int_add(json_row
, "generationId",
1848 neigh
->generation_id
);
1850 if (option_address_list
)
1851 json_object_boolean_true_add(
1853 "helloOptionAddressList");
1855 if (option_dr_priority
)
1856 json_object_boolean_true_add(
1858 "helloOptionDrPriority");
1860 if (option_generation_id
)
1861 json_object_boolean_true_add(
1863 "helloOptionGenerationId");
1865 if (option_holdtime
)
1866 json_object_boolean_true_add(
1868 "helloOptionHoldtime");
1870 if (option_lan_prune_delay
)
1871 json_object_boolean_true_add(
1873 "helloOptionLanPruneDelay");
1876 json_object_boolean_true_add(
1877 json_row
, "helloOptionTBit");
1879 json_object_object_add(json_ifp
, neigh_src_str
,
1883 vty_out(vty
, "Interface : %s\n", ifp
->name
);
1884 vty_out(vty
, "Neighbor : %s\n", neigh_src_str
);
1892 " DR Priority : %d\n",
1893 neigh
->dr_priority
);
1895 " Generation ID : %08x\n",
1896 neigh
->generation_id
);
1898 " Override Interval (msec) : %d\n",
1899 neigh
->override_interval_msec
);
1901 " Propagation Delay (msec) : %d\n",
1902 neigh
->propagation_delay_msec
);
1904 " Hello Option - Address List : %s\n",
1905 option_address_list
? "yes" : "no");
1907 " Hello Option - DR Priority : %s\n",
1908 option_dr_priority
? "yes" : "no");
1910 " Hello Option - Generation ID : %s\n",
1911 option_generation_id
? "yes" : "no");
1913 " Hello Option - Holdtime : %s\n",
1914 option_holdtime
? "yes" : "no");
1916 " Hello Option - LAN Prune Delay : %s\n",
1917 option_lan_prune_delay
? "yes" : "no");
1919 " Hello Option - T-bit : %s\n",
1920 option_t_bit
? "yes" : "no");
1921 pim_bfd_show_info(vty
, neigh
->bfd_info
,
1929 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1930 json
, JSON_C_TO_STRING_PRETTY
));
1931 json_object_free(json
);
1934 if (!found_neighbor
)
1936 "%% No such interface or neighbor\n");
1941 static void pim_show_state(struct pim_instance
*pim
, struct vty
*vty
,
1942 const char *src_or_group
, const char *group
, bool uj
)
1944 struct channel_oil
*c_oil
;
1945 struct listnode
*node
;
1946 json_object
*json
= NULL
;
1947 json_object
*json_group
= NULL
;
1948 json_object
*json_ifp_in
= NULL
;
1949 json_object
*json_ifp_out
= NULL
;
1950 json_object
*json_source
= NULL
;
1953 now
= pim_time_monotonic_sec();
1956 json
= json_object_new_object();
1959 "Codes: J -> Pim Join, I -> IGMP Report, S -> Source, * -> Inherited from (*,G)");
1961 "\nInstalled Source Group IIF OIL\n");
1964 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
1965 char grp_str
[INET_ADDRSTRLEN
];
1966 char src_str
[INET_ADDRSTRLEN
];
1967 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
1968 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
1970 struct interface
*ifp_in
;
1973 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
1975 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
1977 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
1980 strcpy(in_ifname
, ifp_in
->name
);
1982 strcpy(in_ifname
, "<iif?>");
1985 if (strcmp(src_or_group
, src_str
)
1986 && strcmp(src_or_group
, grp_str
))
1989 if (group
&& strcmp(group
, grp_str
))
1995 /* Find the group, create it if it doesn't exist */
1996 json_object_object_get_ex(json
, grp_str
, &json_group
);
1999 json_group
= json_object_new_object();
2000 json_object_object_add(json
, grp_str
,
2004 /* Find the source nested under the group, create it if
2005 * it doesn't exist */
2006 json_object_object_get_ex(json_group
, src_str
,
2010 json_source
= json_object_new_object();
2011 json_object_object_add(json_group
, src_str
,
2015 /* Find the inbound interface nested under the source,
2016 * create it if it doesn't exist */
2017 json_object_object_get_ex(json_source
, in_ifname
,
2021 json_ifp_in
= json_object_new_object();
2022 json_object_object_add(json_source
, in_ifname
,
2024 json_object_int_add(json_source
, "Installed",
2026 json_object_int_add(json_source
, "RefCount",
2027 c_oil
->oil_ref_count
);
2028 json_object_int_add(json_source
, "OilListSize",
2030 json_object_int_add(
2031 json_source
, "OilRescan",
2032 c_oil
->oil_inherited_rescan
);
2033 json_object_int_add(json_source
, "LastUsed",
2034 c_oil
->cc
.lastused
);
2035 json_object_int_add(json_source
, "PacketCount",
2037 json_object_int_add(json_source
, "ByteCount",
2039 json_object_int_add(json_source
,
2041 c_oil
->cc
.wrong_if
);
2044 vty_out(vty
, "%-9d %-15s %-15s %-16s ",
2045 c_oil
->installed
, src_str
, grp_str
, in_ifname
);
2048 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
2050 struct interface
*ifp_out
;
2051 char oif_uptime
[10];
2054 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
2058 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
2060 oif_uptime
, sizeof(oif_uptime
),
2061 now
- c_oil
->oif_creation
[oif_vif_index
]);
2064 strcpy(out_ifname
, ifp_out
->name
);
2066 strcpy(out_ifname
, "<oif?>");
2069 json_ifp_out
= json_object_new_object();
2070 json_object_string_add(json_ifp_out
, "source",
2072 json_object_string_add(json_ifp_out
, "group",
2074 json_object_string_add(json_ifp_out
,
2077 json_object_string_add(json_ifp_out
,
2078 "outboundInterface",
2080 json_object_int_add(json_ifp_out
, "installed",
2083 json_object_object_add(json_ifp_in
, out_ifname
,
2088 vty_out(vty
, "%s(%c%c%c%c)", out_ifname
,
2089 (c_oil
->oif_flags
[oif_vif_index
]
2090 & PIM_OIF_FLAG_PROTO_IGMP
)
2093 (c_oil
->oif_flags
[oif_vif_index
]
2094 & PIM_OIF_FLAG_PROTO_PIM
)
2097 (c_oil
->oif_flags
[oif_vif_index
]
2098 & PIM_OIF_FLAG_PROTO_SOURCE
)
2101 (c_oil
->oif_flags
[oif_vif_index
]
2102 & PIM_OIF_FLAG_PROTO_STAR
)
2106 vty_out(vty
, ", %s(%c%c%c%c)",
2108 (c_oil
->oif_flags
[oif_vif_index
]
2109 & PIM_OIF_FLAG_PROTO_IGMP
)
2112 (c_oil
->oif_flags
[oif_vif_index
]
2113 & PIM_OIF_FLAG_PROTO_PIM
)
2116 (c_oil
->oif_flags
[oif_vif_index
]
2117 & PIM_OIF_FLAG_PROTO_SOURCE
)
2120 (c_oil
->oif_flags
[oif_vif_index
]
2121 & PIM_OIF_FLAG_PROTO_STAR
)
2133 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2134 json
, JSON_C_TO_STRING_PRETTY
));
2135 json_object_free(json
);
2141 static void pim_show_neighbors(struct pim_instance
*pim
, struct vty
*vty
,
2144 struct listnode
*neighnode
;
2145 struct interface
*ifp
;
2146 struct pim_interface
*pim_ifp
;
2147 struct pim_neighbor
*neigh
;
2151 char neigh_src_str
[INET_ADDRSTRLEN
];
2152 json_object
*json
= NULL
;
2153 json_object
*json_ifp_rows
= NULL
;
2154 json_object
*json_row
= NULL
;
2156 now
= pim_time_monotonic_sec();
2159 json
= json_object_new_object();
2162 "Interface Neighbor Uptime Holdtime DR Pri\n");
2165 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2166 pim_ifp
= ifp
->info
;
2171 if (pim_ifp
->pim_sock_fd
< 0)
2175 json_ifp_rows
= json_object_new_object();
2177 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
2179 pim_inet4_dump("<src?>", neigh
->source_addr
,
2180 neigh_src_str
, sizeof(neigh_src_str
));
2181 pim_time_uptime(uptime
, sizeof(uptime
),
2182 now
- neigh
->creation
);
2183 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
2184 neigh
->t_expire_timer
);
2187 json_row
= json_object_new_object();
2188 json_object_string_add(json_row
, "interface",
2190 json_object_string_add(json_row
, "neighbor",
2192 json_object_string_add(json_row
, "upTime",
2194 json_object_string_add(json_row
, "holdTime",
2196 json_object_int_add(json_row
, "holdTimeMax",
2198 json_object_int_add(json_row
, "drPriority",
2199 neigh
->dr_priority
);
2200 json_object_object_add(json_ifp_rows
,
2201 neigh_src_str
, json_row
);
2204 vty_out(vty
, "%-16s %15s %8s %8s %6d\n",
2205 ifp
->name
, neigh_src_str
, uptime
,
2206 expire
, neigh
->dr_priority
);
2211 json_object_object_add(json
, ifp
->name
, json_ifp_rows
);
2212 json_ifp_rows
= NULL
;
2217 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2218 json
, JSON_C_TO_STRING_PRETTY
));
2219 json_object_free(json
);
2223 static void pim_show_neighbors_secondary(struct pim_instance
*pim
,
2226 struct interface
*ifp
;
2229 "Interface Address Neighbor Secondary \n");
2231 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2232 struct pim_interface
*pim_ifp
;
2233 struct in_addr ifaddr
;
2234 struct listnode
*neighnode
;
2235 struct pim_neighbor
*neigh
;
2237 pim_ifp
= ifp
->info
;
2242 if (pim_ifp
->pim_sock_fd
< 0)
2245 ifaddr
= pim_ifp
->primary_address
;
2247 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
2249 char neigh_src_str
[INET_ADDRSTRLEN
];
2250 struct listnode
*prefix_node
;
2253 if (!neigh
->prefix_list
)
2256 pim_inet4_dump("<src?>", neigh
->source_addr
,
2257 neigh_src_str
, sizeof(neigh_src_str
));
2259 for (ALL_LIST_ELEMENTS_RO(neigh
->prefix_list
,
2261 char neigh_sec_str
[PREFIX2STR_BUFFER
];
2263 prefix2str(p
, neigh_sec_str
,
2264 sizeof(neigh_sec_str
));
2266 vty_out(vty
, "%-16s %-15s %-15s %-15s\n",
2267 ifp
->name
, inet_ntoa(ifaddr
),
2268 neigh_src_str
, neigh_sec_str
);
2274 static void json_object_pim_upstream_add(json_object
*json
,
2275 struct pim_upstream
*up
)
2277 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED
)
2278 json_object_boolean_true_add(json
, "drJoinDesired");
2280 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED
)
2281 json_object_boolean_true_add(json
, "drJoinDesiredUpdated");
2283 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
2284 json_object_boolean_true_add(json
, "firstHopRouter");
2286 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_IGMP
)
2287 json_object_boolean_true_add(json
, "sourceIgmp");
2289 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_PIM
)
2290 json_object_boolean_true_add(json
, "sourcePim");
2292 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_STREAM
)
2293 json_object_boolean_true_add(json
, "sourceStream");
2295 /* XXX: need to print ths flag in the plain text display as well */
2296 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_MSDP
)
2297 json_object_boolean_true_add(json
, "sourceMsdp");
2301 pim_upstream_state2brief_str(enum pim_upstream_state join_state
,
2304 switch (join_state
) {
2305 case PIM_UPSTREAM_NOTJOINED
:
2306 strcpy(state_str
, "NotJ");
2308 case PIM_UPSTREAM_JOINED
:
2309 strcpy(state_str
, "J");
2312 strcpy(state_str
, "Unk");
2317 static const char *pim_reg_state2brief_str(enum pim_reg_state reg_state
,
2320 switch (reg_state
) {
2321 case PIM_REG_NOINFO
:
2322 strcpy(state_str
, "RegNI");
2325 strcpy(state_str
, "RegJ");
2327 case PIM_REG_JOIN_PENDING
:
2329 strcpy(state_str
, "RegP");
2332 strcpy(state_str
, "Unk");
2337 static void pim_show_upstream(struct pim_instance
*pim
, struct vty
*vty
,
2338 struct prefix_sg
*sg
, bool uj
)
2340 struct listnode
*upnode
;
2341 struct pim_upstream
*up
;
2343 json_object
*json
= NULL
;
2344 json_object
*json_group
= NULL
;
2345 json_object
*json_row
= NULL
;
2347 now
= pim_time_monotonic_sec();
2350 json
= json_object_new_object();
2353 "Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt\n");
2355 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
, up
)) {
2356 char src_str
[INET_ADDRSTRLEN
];
2357 char grp_str
[INET_ADDRSTRLEN
];
2359 char join_timer
[10];
2362 char msdp_reg_timer
[10];
2363 char state_str
[PIM_REG_STATE_STR_LEN
];
2365 if (sg
->grp
.s_addr
!= 0 && sg
->grp
.s_addr
!= up
->sg
.grp
.s_addr
)
2367 if (sg
->src
.s_addr
!= 0 && sg
->src
.s_addr
!= up
->sg
.src
.s_addr
)
2370 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2371 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2372 pim_time_uptime(uptime
, sizeof(uptime
),
2373 now
- up
->state_transition
);
2374 pim_time_timer_to_hhmmss(join_timer
, sizeof(join_timer
),
2378 * If the upstream is not dummy and it has a J/P timer for the
2379 * neighbor display that
2381 if (!up
->t_join_timer
&& up
->rpf
.source_nexthop
.interface
) {
2382 struct pim_neighbor
*nbr
;
2384 nbr
= pim_neighbor_find(
2385 up
->rpf
.source_nexthop
.interface
,
2386 up
->rpf
.rpf_addr
.u
.prefix4
);
2388 pim_time_timer_to_hhmmss(join_timer
,
2393 pim_time_timer_to_hhmmss(rs_timer
, sizeof(rs_timer
),
2395 pim_time_timer_to_hhmmss(ka_timer
, sizeof(ka_timer
),
2397 pim_time_timer_to_hhmmss(msdp_reg_timer
, sizeof(msdp_reg_timer
),
2398 up
->t_msdp_reg_timer
);
2400 pim_upstream_state2brief_str(up
->join_state
, state_str
);
2401 if (up
->reg_state
!= PIM_REG_NOINFO
) {
2402 char tmp_str
[PIM_REG_STATE_STR_LEN
];
2404 sprintf(state_str
+ strlen(state_str
), ",%s",
2405 pim_reg_state2brief_str(up
->reg_state
,
2410 json_object_object_get_ex(json
, grp_str
, &json_group
);
2413 json_group
= json_object_new_object();
2414 json_object_object_add(json
, grp_str
,
2418 json_row
= json_object_new_object();
2419 json_object_pim_upstream_add(json_row
, up
);
2420 json_object_string_add(
2421 json_row
, "inboundInterface",
2422 up
->rpf
.source_nexthop
.interface
2423 ? up
->rpf
.source_nexthop
.interface
->name
2427 * The RPF address we use is slightly different
2428 * based upon what we are looking up.
2429 * If we have a S, list that unless
2430 * we are the FHR, else we just put
2431 * the RP as the rpfAddress
2433 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
2434 || up
->sg
.src
.s_addr
== INADDR_ANY
) {
2435 char rpf
[PREFIX_STRLEN
];
2436 struct pim_rpf
*rpg
;
2438 rpg
= RP(pim
, up
->sg
.grp
);
2439 pim_inet4_dump("<rpf?>",
2440 rpg
->rpf_addr
.u
.prefix4
, rpf
,
2442 json_object_string_add(json_row
, "rpfAddress",
2445 json_object_string_add(json_row
, "rpfAddress",
2449 json_object_string_add(json_row
, "source", src_str
);
2450 json_object_string_add(json_row
, "group", grp_str
);
2451 json_object_string_add(json_row
, "state", state_str
);
2452 json_object_string_add(
2453 json_row
, "joinState",
2454 pim_upstream_state2str(up
->join_state
));
2455 json_object_string_add(
2456 json_row
, "regState",
2457 pim_reg_state2str(up
->reg_state
, state_str
));
2458 json_object_string_add(json_row
, "upTime", uptime
);
2459 json_object_string_add(json_row
, "joinTimer",
2461 json_object_string_add(json_row
, "resetTimer",
2463 json_object_string_add(json_row
, "keepaliveTimer",
2465 json_object_string_add(json_row
, "msdpRegTimer",
2467 json_object_int_add(json_row
, "refCount",
2469 json_object_int_add(json_row
, "sptBit", up
->sptbit
);
2470 json_object_object_add(json_group
, src_str
, json_row
);
2473 "%-16s%-15s %-15s %-11s %-8s %-9s %-9s %-9s %6d\n",
2474 up
->rpf
.source_nexthop
.interface
2475 ? up
->rpf
.source_nexthop
.interface
->name
2477 src_str
, grp_str
, state_str
, uptime
, join_timer
,
2478 rs_timer
, ka_timer
, up
->ref_count
);
2483 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2484 json
, JSON_C_TO_STRING_PRETTY
));
2485 json_object_free(json
);
2489 static void pim_show_join_desired_helper(struct pim_instance
*pim
,
2491 struct pim_interface
*pim_ifp
,
2492 struct pim_ifchannel
*ch
,
2493 json_object
*json
, bool uj
)
2495 struct pim_upstream
*up
= ch
->upstream
;
2496 json_object
*json_group
= NULL
;
2497 char src_str
[INET_ADDRSTRLEN
];
2498 char grp_str
[INET_ADDRSTRLEN
];
2499 json_object
*json_row
= NULL
;
2501 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2502 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2505 json_object_object_get_ex(json
, grp_str
, &json_group
);
2508 json_group
= json_object_new_object();
2509 json_object_object_add(json
, grp_str
, json_group
);
2512 json_row
= json_object_new_object();
2513 json_object_pim_upstream_add(json_row
, up
);
2514 json_object_string_add(json_row
, "interface",
2515 ch
->interface
->name
);
2516 json_object_string_add(json_row
, "source", src_str
);
2517 json_object_string_add(json_row
, "group", grp_str
);
2519 if (pim_macro_ch_lost_assert(ch
))
2520 json_object_boolean_true_add(json_row
, "lostAssert");
2522 if (pim_macro_chisin_joins(ch
))
2523 json_object_boolean_true_add(json_row
, "joins");
2525 if (pim_macro_chisin_pim_include(ch
))
2526 json_object_boolean_true_add(json_row
, "pimInclude");
2528 if (pim_upstream_evaluate_join_desired(pim
, up
))
2529 json_object_boolean_true_add(json_row
,
2530 "evaluateJoinDesired");
2532 json_object_object_add(json_group
, src_str
, json_row
);
2535 vty_out(vty
, "%-16s %-15s %-15s %-10s %-5s %-10s %-11s %-6s\n",
2536 ch
->interface
->name
, src_str
, grp_str
,
2537 pim_macro_ch_lost_assert(ch
) ? "yes" : "no",
2538 pim_macro_chisin_joins(ch
) ? "yes" : "no",
2539 pim_macro_chisin_pim_include(ch
) ? "yes" : "no",
2540 PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(up
->flags
)
2543 pim_upstream_evaluate_join_desired(pim
, up
) ? "yes"
2548 static void pim_show_join_desired(struct pim_instance
*pim
, struct vty
*vty
,
2551 struct pim_interface
*pim_ifp
;
2552 struct pim_ifchannel
*ch
;
2553 struct interface
*ifp
;
2555 json_object
*json
= NULL
;
2558 json
= json_object_new_object();
2561 "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD\n");
2563 /* scan per-interface (S,G) state */
2564 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2565 pim_ifp
= ifp
->info
;
2570 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
2571 /* scan all interfaces */
2572 pim_show_join_desired_helper(pim
, vty
, pim_ifp
, ch
,
2578 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2579 json
, JSON_C_TO_STRING_PRETTY
));
2580 json_object_free(json
);
2584 static void pim_show_upstream_rpf(struct pim_instance
*pim
, struct vty
*vty
,
2587 struct listnode
*upnode
;
2588 struct pim_upstream
*up
;
2589 json_object
*json
= NULL
;
2590 json_object
*json_group
= NULL
;
2591 json_object
*json_row
= NULL
;
2594 json
= json_object_new_object();
2597 "Source Group RpfIface RibNextHop RpfAddress \n");
2599 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
, up
)) {
2600 char src_str
[INET_ADDRSTRLEN
];
2601 char grp_str
[INET_ADDRSTRLEN
];
2602 char rpf_nexthop_str
[PREFIX_STRLEN
];
2603 char rpf_addr_str
[PREFIX_STRLEN
];
2604 struct pim_rpf
*rpf
;
2605 const char *rpf_ifname
;
2609 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2610 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2611 pim_addr_dump("<nexthop?>",
2612 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2613 rpf_nexthop_str
, sizeof(rpf_nexthop_str
));
2614 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2615 sizeof(rpf_addr_str
));
2617 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2620 json_object_object_get_ex(json
, grp_str
, &json_group
);
2623 json_group
= json_object_new_object();
2624 json_object_object_add(json
, grp_str
,
2628 json_row
= json_object_new_object();
2629 json_object_pim_upstream_add(json_row
, up
);
2630 json_object_string_add(json_row
, "source", src_str
);
2631 json_object_string_add(json_row
, "group", grp_str
);
2632 json_object_string_add(json_row
, "rpfInterface",
2634 json_object_string_add(json_row
, "ribNexthop",
2636 json_object_string_add(json_row
, "rpfAddress",
2638 json_object_object_add(json_group
, src_str
, json_row
);
2640 vty_out(vty
, "%-15s %-15s %-16s %-15s %-15s\n", src_str
,
2641 grp_str
, rpf_ifname
, rpf_nexthop_str
,
2647 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2648 json
, JSON_C_TO_STRING_PRETTY
));
2649 json_object_free(json
);
2653 static void show_rpf_refresh_stats(struct vty
*vty
, struct pim_instance
*pim
,
2654 time_t now
, json_object
*json
)
2656 char refresh_uptime
[10];
2658 pim_time_uptime_begin(refresh_uptime
, sizeof(refresh_uptime
), now
,
2659 pim
->rpf_cache_refresh_last
);
2662 json_object_int_add(json
, "rpfCacheRefreshDelayMsecs",
2663 router
->rpf_cache_refresh_delay_msec
);
2664 json_object_int_add(
2665 json
, "rpfCacheRefreshTimer",
2666 pim_time_timer_remain_msec(pim
->rpf_cache_refresher
));
2667 json_object_int_add(json
, "rpfCacheRefreshRequests",
2668 pim
->rpf_cache_refresh_requests
);
2669 json_object_int_add(json
, "rpfCacheRefreshEvents",
2670 pim
->rpf_cache_refresh_events
);
2671 json_object_string_add(json
, "rpfCacheRefreshLast",
2673 json_object_int_add(json
, "nexthopLookups",
2674 pim
->nexthop_lookups
);
2675 json_object_int_add(json
, "nexthopLookupsAvoided",
2676 pim
->nexthop_lookups_avoided
);
2679 "RPF Cache Refresh Delay: %ld msecs\n"
2680 "RPF Cache Refresh Timer: %ld msecs\n"
2681 "RPF Cache Refresh Requests: %lld\n"
2682 "RPF Cache Refresh Events: %lld\n"
2683 "RPF Cache Refresh Last: %s\n"
2684 "Nexthop Lookups: %lld\n"
2685 "Nexthop Lookups Avoided: %lld\n",
2686 router
->rpf_cache_refresh_delay_msec
,
2687 pim_time_timer_remain_msec(pim
->rpf_cache_refresher
),
2688 (long long)pim
->rpf_cache_refresh_requests
,
2689 (long long)pim
->rpf_cache_refresh_events
,
2690 refresh_uptime
, (long long)pim
->nexthop_lookups
,
2691 (long long)pim
->nexthop_lookups_avoided
);
2695 static void show_scan_oil_stats(struct pim_instance
*pim
, struct vty
*vty
,
2698 char uptime_scan_oil
[10];
2699 char uptime_mroute_add
[10];
2700 char uptime_mroute_del
[10];
2702 pim_time_uptime_begin(uptime_scan_oil
, sizeof(uptime_scan_oil
), now
,
2703 pim
->scan_oil_last
);
2704 pim_time_uptime_begin(uptime_mroute_add
, sizeof(uptime_mroute_add
), now
,
2705 pim
->mroute_add_last
);
2706 pim_time_uptime_begin(uptime_mroute_del
, sizeof(uptime_mroute_del
), now
,
2707 pim
->mroute_del_last
);
2710 "Scan OIL - Last: %s Events: %lld\n"
2711 "MFC Add - Last: %s Events: %lld\n"
2712 "MFC Del - Last: %s Events: %lld\n",
2713 uptime_scan_oil
, (long long)pim
->scan_oil_events
,
2714 uptime_mroute_add
, (long long)pim
->mroute_add_events
,
2715 uptime_mroute_del
, (long long)pim
->mroute_del_events
);
2718 static void pim_show_rpf(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
2720 struct listnode
*up_node
;
2721 struct pim_upstream
*up
;
2722 time_t now
= pim_time_monotonic_sec();
2723 json_object
*json
= NULL
;
2724 json_object
*json_group
= NULL
;
2725 json_object
*json_row
= NULL
;
2728 json
= json_object_new_object();
2729 show_rpf_refresh_stats(vty
, pim
, now
, json
);
2731 show_rpf_refresh_stats(vty
, pim
, now
, json
);
2734 "Source Group RpfIface RpfAddress RibNextHop Metric Pref\n");
2737 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, up_node
, up
)) {
2738 char src_str
[INET_ADDRSTRLEN
];
2739 char grp_str
[INET_ADDRSTRLEN
];
2740 char rpf_addr_str
[PREFIX_STRLEN
];
2741 char rib_nexthop_str
[PREFIX_STRLEN
];
2742 const char *rpf_ifname
;
2743 struct pim_rpf
*rpf
= &up
->rpf
;
2745 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2746 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2747 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2748 sizeof(rpf_addr_str
));
2749 pim_addr_dump("<nexthop?>",
2750 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2751 rib_nexthop_str
, sizeof(rib_nexthop_str
));
2753 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2756 json_object_object_get_ex(json
, grp_str
, &json_group
);
2759 json_group
= json_object_new_object();
2760 json_object_object_add(json
, grp_str
,
2764 json_row
= json_object_new_object();
2765 json_object_string_add(json_row
, "source", src_str
);
2766 json_object_string_add(json_row
, "group", grp_str
);
2767 json_object_string_add(json_row
, "rpfInterface",
2769 json_object_string_add(json_row
, "rpfAddress",
2771 json_object_string_add(json_row
, "ribNexthop",
2773 json_object_int_add(
2774 json_row
, "routeMetric",
2775 rpf
->source_nexthop
.mrib_route_metric
);
2776 json_object_int_add(
2777 json_row
, "routePreference",
2778 rpf
->source_nexthop
.mrib_metric_preference
);
2779 json_object_object_add(json_group
, src_str
, json_row
);
2782 vty_out(vty
, "%-15s %-15s %-16s %-15s %-15s %6d %4d\n",
2783 src_str
, grp_str
, rpf_ifname
, rpf_addr_str
,
2785 rpf
->source_nexthop
.mrib_route_metric
,
2786 rpf
->source_nexthop
.mrib_metric_preference
);
2791 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2792 json
, JSON_C_TO_STRING_PRETTY
));
2793 json_object_free(json
);
2797 struct pnc_cache_walk_data
{
2799 struct pim_instance
*pim
;
2802 static int pim_print_pnc_cache_walkcb(struct hash_bucket
*bucket
, void *arg
)
2804 struct pim_nexthop_cache
*pnc
= bucket
->data
;
2805 struct pnc_cache_walk_data
*cwd
= arg
;
2806 struct vty
*vty
= cwd
->vty
;
2807 struct pim_instance
*pim
= cwd
->pim
;
2808 struct nexthop
*nh_node
= NULL
;
2809 ifindex_t first_ifindex
;
2810 struct interface
*ifp
= NULL
;
2812 for (nh_node
= pnc
->nexthop
; nh_node
; nh_node
= nh_node
->next
) {
2813 first_ifindex
= nh_node
->ifindex
;
2814 ifp
= if_lookup_by_index(first_ifindex
, pim
->vrf_id
);
2816 vty_out(vty
, "%-15s ", inet_ntoa(pnc
->rpf
.rpf_addr
.u
.prefix4
));
2817 vty_out(vty
, "%-16s ", ifp
? ifp
->name
: "NULL");
2818 vty_out(vty
, "%s ", inet_ntoa(nh_node
->gate
.ipv4
));
2824 static void pim_show_nexthop(struct pim_instance
*pim
, struct vty
*vty
)
2826 struct pnc_cache_walk_data cwd
;
2830 vty_out(vty
, "Number of registered addresses: %lu\n",
2831 pim
->rpf_hash
->count
);
2832 vty_out(vty
, "Address Interface Nexthop\n");
2833 vty_out(vty
, "---------------------------------------------\n");
2835 hash_walk(pim
->rpf_hash
, pim_print_pnc_cache_walkcb
, &cwd
);
2838 static void igmp_show_groups(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
2840 struct interface
*ifp
;
2842 json_object
*json
= NULL
;
2843 json_object
*json_iface
= NULL
;
2844 json_object
*json_row
= NULL
;
2846 now
= pim_time_monotonic_sec();
2849 json
= json_object_new_object();
2852 "Interface Address Group Mode Timer Srcs V Uptime \n");
2854 /* scan interfaces */
2855 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2856 struct pim_interface
*pim_ifp
= ifp
->info
;
2857 struct listnode
*sock_node
;
2858 struct igmp_sock
*igmp
;
2863 /* scan igmp sockets */
2864 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
2866 char ifaddr_str
[INET_ADDRSTRLEN
];
2867 struct listnode
*grpnode
;
2868 struct igmp_group
*grp
;
2870 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
2871 sizeof(ifaddr_str
));
2873 /* scan igmp groups */
2874 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
2876 char group_str
[INET_ADDRSTRLEN
];
2880 pim_inet4_dump("<group?>", grp
->group_addr
,
2881 group_str
, sizeof(group_str
));
2882 pim_time_timer_to_hhmmss(hhmmss
, sizeof(hhmmss
),
2883 grp
->t_group_timer
);
2884 pim_time_uptime(uptime
, sizeof(uptime
),
2885 now
- grp
->group_creation
);
2888 json_object_object_get_ex(
2889 json
, ifp
->name
, &json_iface
);
2893 json_object_new_object();
2894 json_object_pim_ifp_add(
2896 json_object_object_add(
2901 json_row
= json_object_new_object();
2902 json_object_string_add(
2903 json_row
, "source", ifaddr_str
);
2904 json_object_string_add(
2905 json_row
, "group", group_str
);
2907 if (grp
->igmp_version
== 3)
2908 json_object_string_add(
2910 grp
->group_filtermode_isexcl
2914 json_object_string_add(json_row
,
2916 json_object_int_add(
2917 json_row
, "sourcesCount",
2918 grp
->group_source_list
2920 grp
->group_source_list
)
2922 json_object_int_add(json_row
, "version",
2924 json_object_string_add(
2925 json_row
, "uptime", uptime
);
2926 json_object_object_add(json_iface
,
2932 "%-16s %-15s %-15s %4s %8s %4d %d %8s\n",
2933 ifp
->name
, ifaddr_str
,
2935 grp
->igmp_version
== 3
2936 ? (grp
->group_filtermode_isexcl
2941 grp
->group_source_list
2943 grp
->group_source_list
)
2945 grp
->igmp_version
, uptime
);
2947 } /* scan igmp groups */
2948 } /* scan igmp sockets */
2949 } /* scan interfaces */
2952 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2953 json
, JSON_C_TO_STRING_PRETTY
));
2954 json_object_free(json
);
2958 static void igmp_show_group_retransmission(struct pim_instance
*pim
,
2961 struct interface
*ifp
;
2964 "Interface Address Group RetTimer Counter RetSrcs\n");
2966 /* scan interfaces */
2967 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2968 struct pim_interface
*pim_ifp
= ifp
->info
;
2969 struct listnode
*sock_node
;
2970 struct igmp_sock
*igmp
;
2975 /* scan igmp sockets */
2976 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
2978 char ifaddr_str
[INET_ADDRSTRLEN
];
2979 struct listnode
*grpnode
;
2980 struct igmp_group
*grp
;
2982 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
2983 sizeof(ifaddr_str
));
2985 /* scan igmp groups */
2986 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
2988 char group_str
[INET_ADDRSTRLEN
];
2989 char grp_retr_mmss
[10];
2990 struct listnode
*src_node
;
2991 struct igmp_source
*src
;
2992 int grp_retr_sources
= 0;
2994 pim_inet4_dump("<group?>", grp
->group_addr
,
2995 group_str
, sizeof(group_str
));
2996 pim_time_timer_to_mmss(
2997 grp_retr_mmss
, sizeof(grp_retr_mmss
),
2998 grp
->t_group_query_retransmit_timer
);
3001 /* count group sources with retransmission state
3003 for (ALL_LIST_ELEMENTS_RO(
3004 grp
->group_source_list
, src_node
,
3006 if (src
->source_query_retransmit_count
3012 vty_out(vty
, "%-16s %-15s %-15s %-8s %7d %7d\n",
3013 ifp
->name
, ifaddr_str
, group_str
,
3015 grp
->group_specific_query_retransmit_count
,
3018 } /* scan igmp groups */
3019 } /* scan igmp sockets */
3020 } /* scan interfaces */
3023 static void igmp_show_sources(struct pim_instance
*pim
, struct vty
*vty
)
3025 struct interface
*ifp
;
3028 now
= pim_time_monotonic_sec();
3031 "Interface Address Group Source Timer Fwd Uptime \n");
3033 /* scan interfaces */
3034 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3035 struct pim_interface
*pim_ifp
= ifp
->info
;
3036 struct listnode
*sock_node
;
3037 struct igmp_sock
*igmp
;
3042 /* scan igmp sockets */
3043 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3045 char ifaddr_str
[INET_ADDRSTRLEN
];
3046 struct listnode
*grpnode
;
3047 struct igmp_group
*grp
;
3049 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3050 sizeof(ifaddr_str
));
3052 /* scan igmp groups */
3053 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3055 char group_str
[INET_ADDRSTRLEN
];
3056 struct listnode
*srcnode
;
3057 struct igmp_source
*src
;
3059 pim_inet4_dump("<group?>", grp
->group_addr
,
3060 group_str
, sizeof(group_str
));
3062 /* scan group sources */
3063 for (ALL_LIST_ELEMENTS_RO(
3064 grp
->group_source_list
, srcnode
,
3066 char source_str
[INET_ADDRSTRLEN
];
3071 "<source?>", src
->source_addr
,
3072 source_str
, sizeof(source_str
));
3074 pim_time_timer_to_mmss(
3076 src
->t_source_timer
);
3079 uptime
, sizeof(uptime
),
3080 now
- src
->source_creation
);
3083 "%-16s %-15s %-15s %-15s %5s %3s %8s\n",
3084 ifp
->name
, ifaddr_str
,
3085 group_str
, source_str
, mmss
,
3086 IGMP_SOURCE_TEST_FORWARDING(
3092 } /* scan group sources */
3093 } /* scan igmp groups */
3094 } /* scan igmp sockets */
3095 } /* scan interfaces */
3098 static void igmp_show_source_retransmission(struct pim_instance
*pim
,
3101 struct interface
*ifp
;
3104 "Interface Address Group Source Counter\n");
3106 /* scan interfaces */
3107 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3108 struct pim_interface
*pim_ifp
= ifp
->info
;
3109 struct listnode
*sock_node
;
3110 struct igmp_sock
*igmp
;
3115 /* scan igmp sockets */
3116 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3118 char ifaddr_str
[INET_ADDRSTRLEN
];
3119 struct listnode
*grpnode
;
3120 struct igmp_group
*grp
;
3122 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3123 sizeof(ifaddr_str
));
3125 /* scan igmp groups */
3126 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3128 char group_str
[INET_ADDRSTRLEN
];
3129 struct listnode
*srcnode
;
3130 struct igmp_source
*src
;
3132 pim_inet4_dump("<group?>", grp
->group_addr
,
3133 group_str
, sizeof(group_str
));
3135 /* scan group sources */
3136 for (ALL_LIST_ELEMENTS_RO(
3137 grp
->group_source_list
, srcnode
,
3139 char source_str
[INET_ADDRSTRLEN
];
3142 "<source?>", src
->source_addr
,
3143 source_str
, sizeof(source_str
));
3146 "%-16s %-15s %-15s %-15s %7d\n",
3147 ifp
->name
, ifaddr_str
,
3148 group_str
, source_str
,
3149 src
->source_query_retransmit_count
);
3151 } /* scan group sources */
3152 } /* scan igmp groups */
3153 } /* scan igmp sockets */
3154 } /* scan interfaces */
3157 static void clear_igmp_interfaces(struct pim_instance
*pim
)
3159 struct interface
*ifp
;
3161 FOR_ALL_INTERFACES (pim
->vrf
, ifp
)
3162 pim_if_addr_del_all_igmp(ifp
);
3164 FOR_ALL_INTERFACES (pim
->vrf
, ifp
)
3165 pim_if_addr_add_all(ifp
);
3168 static void clear_pim_interfaces(struct pim_instance
*pim
)
3170 struct interface
*ifp
;
3172 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3174 pim_neighbor_delete_all(ifp
, "interface cleared");
3179 static void clear_interfaces(struct pim_instance
*pim
)
3181 clear_igmp_interfaces(pim
);
3182 clear_pim_interfaces(pim
);
3185 #define PIM_GET_PIM_INTERFACE(pim_ifp, ifp) \
3186 pim_ifp = ifp->info; \
3189 "%% Enable PIM and/or IGMP on this interface first\n"); \
3190 return CMD_WARNING_CONFIG_FAILED; \
3193 DEFUN (clear_ip_interfaces
,
3194 clear_ip_interfaces_cmd
,
3195 "clear ip interfaces [vrf NAME]",
3198 "Reset interfaces\n"
3202 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3207 clear_interfaces(vrf
->info
);
3212 DEFUN (clear_ip_igmp_interfaces
,
3213 clear_ip_igmp_interfaces_cmd
,
3214 "clear ip igmp [vrf NAME] interfaces",
3219 "Reset IGMP interfaces\n")
3222 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3227 clear_igmp_interfaces(vrf
->info
);
3232 static void mroute_add_all(struct pim_instance
*pim
)
3234 struct listnode
*node
;
3235 struct channel_oil
*c_oil
;
3237 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
3238 if (pim_mroute_add(c_oil
, __PRETTY_FUNCTION__
)) {
3239 /* just log warning */
3240 char source_str
[INET_ADDRSTRLEN
];
3241 char group_str
[INET_ADDRSTRLEN
];
3242 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
,
3243 source_str
, sizeof(source_str
));
3244 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
,
3245 group_str
, sizeof(group_str
));
3246 zlog_warn("%s %s: (S,G)=(%s,%s) failure writing MFC",
3247 __FILE__
, __PRETTY_FUNCTION__
, source_str
,
3253 static void mroute_del_all(struct pim_instance
*pim
)
3255 struct listnode
*node
;
3256 struct channel_oil
*c_oil
;
3258 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
3259 if (pim_mroute_del(c_oil
, __PRETTY_FUNCTION__
)) {
3260 /* just log warning */
3261 char source_str
[INET_ADDRSTRLEN
];
3262 char group_str
[INET_ADDRSTRLEN
];
3263 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
,
3264 source_str
, sizeof(source_str
));
3265 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
,
3266 group_str
, sizeof(group_str
));
3267 zlog_warn("%s %s: (S,G)=(%s,%s) failure clearing MFC",
3268 __FILE__
, __PRETTY_FUNCTION__
, source_str
,
3274 DEFUN (clear_ip_mroute
,
3275 clear_ip_mroute_cmd
,
3276 "clear ip mroute [vrf NAME]",
3279 "Reset multicast routes\n"
3283 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3288 mroute_del_all(vrf
->info
);
3289 mroute_add_all(vrf
->info
);
3294 DEFUN (clear_ip_pim_interfaces
,
3295 clear_ip_pim_interfaces_cmd
,
3296 "clear ip pim [vrf NAME] interfaces",
3301 "Reset PIM interfaces\n")
3304 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3309 clear_pim_interfaces(vrf
->info
);
3314 DEFUN (clear_ip_pim_interface_traffic
,
3315 clear_ip_pim_interface_traffic_cmd
,
3316 "clear ip pim [vrf NAME] interface traffic",
3319 "PIM clear commands\n"
3321 "Reset PIM interfaces\n"
3322 "Reset Protocol Packet counters\n")
3325 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3326 struct interface
*ifp
= NULL
;
3327 struct pim_interface
*pim_ifp
= NULL
;
3332 FOR_ALL_INTERFACES (vrf
, ifp
) {
3333 pim_ifp
= ifp
->info
;
3338 pim_ifp
->pim_ifstat_hello_recv
= 0;
3339 pim_ifp
->pim_ifstat_hello_sent
= 0;
3340 pim_ifp
->pim_ifstat_join_recv
= 0;
3341 pim_ifp
->pim_ifstat_join_send
= 0;
3342 pim_ifp
->pim_ifstat_prune_recv
= 0;
3343 pim_ifp
->pim_ifstat_prune_send
= 0;
3344 pim_ifp
->pim_ifstat_reg_recv
= 0;
3345 pim_ifp
->pim_ifstat_reg_send
= 0;
3346 pim_ifp
->pim_ifstat_reg_stop_recv
= 0;
3347 pim_ifp
->pim_ifstat_reg_stop_send
= 0;
3348 pim_ifp
->pim_ifstat_assert_recv
= 0;
3349 pim_ifp
->pim_ifstat_assert_send
= 0;
3355 DEFUN (clear_ip_pim_oil
,
3356 clear_ip_pim_oil_cmd
,
3357 "clear ip pim [vrf NAME] oil",
3362 "Rescan PIM OIL (output interface list)\n")
3365 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3370 pim_scan_oil(vrf
->info
);
3375 DEFUN (show_ip_igmp_interface
,
3376 show_ip_igmp_interface_cmd
,
3377 "show ip igmp [vrf NAME] interface [detail|WORD] [json]",
3382 "IGMP interface information\n"
3388 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3389 bool uj
= use_json(argc
, argv
);
3394 if (argv_find(argv
, argc
, "detail", &idx
)
3395 || argv_find(argv
, argc
, "WORD", &idx
))
3396 igmp_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
3398 igmp_show_interfaces(vrf
->info
, vty
, uj
);
3403 DEFUN (show_ip_igmp_interface_vrf_all
,
3404 show_ip_igmp_interface_vrf_all_cmd
,
3405 "show ip igmp vrf all interface [detail|WORD] [json]",
3410 "IGMP interface information\n"
3416 bool uj
= use_json(argc
, argv
);
3422 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3426 vty_out(vty
, " \"%s\": ", vrf
->name
);
3429 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3430 if (argv_find(argv
, argc
, "detail", &idx
)
3431 || argv_find(argv
, argc
, "WORD", &idx
))
3432 igmp_show_interfaces_single(vrf
->info
, vty
,
3433 argv
[idx
]->arg
, uj
);
3435 igmp_show_interfaces(vrf
->info
, vty
, uj
);
3438 vty_out(vty
, "}\n");
3443 DEFUN (show_ip_igmp_join
,
3444 show_ip_igmp_join_cmd
,
3445 "show ip igmp [vrf NAME] join",
3450 "IGMP static join information\n")
3453 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3458 igmp_show_interface_join(vrf
->info
, vty
);
3463 DEFUN (show_ip_igmp_join_vrf_all
,
3464 show_ip_igmp_join_vrf_all_cmd
,
3465 "show ip igmp vrf all join",
3470 "IGMP static join information\n")
3472 bool uj
= use_json(argc
, argv
);
3478 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3482 vty_out(vty
, " \"%s\": ", vrf
->name
);
3485 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3486 igmp_show_interface_join(vrf
->info
, vty
);
3489 vty_out(vty
, "}\n");
3494 DEFUN (show_ip_igmp_groups
,
3495 show_ip_igmp_groups_cmd
,
3496 "show ip igmp [vrf NAME] groups [json]",
3505 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3506 bool uj
= use_json(argc
, argv
);
3511 igmp_show_groups(vrf
->info
, vty
, uj
);
3516 DEFUN (show_ip_igmp_groups_vrf_all
,
3517 show_ip_igmp_groups_vrf_all_cmd
,
3518 "show ip igmp vrf all groups [json]",
3526 bool uj
= use_json(argc
, argv
);
3532 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3536 vty_out(vty
, " \"%s\": ", vrf
->name
);
3539 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3540 igmp_show_groups(vrf
->info
, vty
, uj
);
3543 vty_out(vty
, "}\n");
3548 DEFUN (show_ip_igmp_groups_retransmissions
,
3549 show_ip_igmp_groups_retransmissions_cmd
,
3550 "show ip igmp [vrf NAME] groups retransmissions",
3556 "IGMP group retransmissions\n")
3559 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3564 igmp_show_group_retransmission(vrf
->info
, vty
);
3569 DEFUN (show_ip_igmp_sources
,
3570 show_ip_igmp_sources_cmd
,
3571 "show ip igmp [vrf NAME] sources",
3579 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3584 igmp_show_sources(vrf
->info
, vty
);
3589 DEFUN (show_ip_igmp_sources_retransmissions
,
3590 show_ip_igmp_sources_retransmissions_cmd
,
3591 "show ip igmp [vrf NAME] sources retransmissions",
3597 "IGMP source retransmissions\n")
3600 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3605 igmp_show_source_retransmission(vrf
->info
, vty
);
3610 DEFUN (show_ip_igmp_statistics
,
3611 show_ip_igmp_statistics_cmd
,
3612 "show ip igmp [vrf NAME] statistics [interface WORD] [json]",
3623 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3624 bool uj
= use_json(argc
, argv
);
3629 if (argv_find(argv
, argc
, "WORD", &idx
))
3630 igmp_show_statistics(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
3632 igmp_show_statistics(vrf
->info
, vty
, NULL
, uj
);
3637 DEFUN (show_ip_pim_assert
,
3638 show_ip_pim_assert_cmd
,
3639 "show ip pim [vrf NAME] assert",
3644 "PIM interface assert\n")
3647 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3652 pim_show_assert(vrf
->info
, vty
);
3657 DEFUN (show_ip_pim_assert_internal
,
3658 show_ip_pim_assert_internal_cmd
,
3659 "show ip pim [vrf NAME] assert-internal",
3664 "PIM interface internal assert state\n")
3667 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3672 pim_show_assert_internal(vrf
->info
, vty
);
3677 DEFUN (show_ip_pim_assert_metric
,
3678 show_ip_pim_assert_metric_cmd
,
3679 "show ip pim [vrf NAME] assert-metric",
3684 "PIM interface assert metric\n")
3687 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3692 pim_show_assert_metric(vrf
->info
, vty
);
3697 DEFUN (show_ip_pim_assert_winner_metric
,
3698 show_ip_pim_assert_winner_metric_cmd
,
3699 "show ip pim [vrf NAME] assert-winner-metric",
3704 "PIM interface assert winner metric\n")
3707 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3712 pim_show_assert_winner_metric(vrf
->info
, vty
);
3717 DEFUN (show_ip_pim_interface
,
3718 show_ip_pim_interface_cmd
,
3719 "show ip pim [vrf NAME] interface [detail|WORD] [json]",
3724 "PIM interface information\n"
3730 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3731 bool uj
= use_json(argc
, argv
);
3736 if (argv_find(argv
, argc
, "WORD", &idx
)
3737 || argv_find(argv
, argc
, "detail", &idx
))
3738 pim_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
3740 pim_show_interfaces(vrf
->info
, vty
, uj
);
3745 DEFUN (show_ip_pim_interface_vrf_all
,
3746 show_ip_pim_interface_vrf_all_cmd
,
3747 "show ip pim vrf all interface [detail|WORD] [json]",
3752 "PIM interface information\n"
3758 bool uj
= use_json(argc
, argv
);
3764 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3768 vty_out(vty
, " \"%s\": ", vrf
->name
);
3771 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3772 if (argv_find(argv
, argc
, "WORD", &idx
)
3773 || argv_find(argv
, argc
, "detail", &idx
))
3774 pim_show_interfaces_single(vrf
->info
, vty
,
3775 argv
[idx
]->arg
, uj
);
3777 pim_show_interfaces(vrf
->info
, vty
, uj
);
3780 vty_out(vty
, "}\n");
3785 DEFUN (show_ip_pim_join
,
3786 show_ip_pim_join_cmd
,
3787 "show ip pim [vrf NAME] join [json]",
3792 "PIM interface join information\n"
3796 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3797 bool uj
= use_json(argc
, argv
);
3802 pim_show_join(vrf
->info
, vty
, uj
);
3807 DEFUN (show_ip_pim_join_vrf_all
,
3808 show_ip_pim_join_vrf_all_cmd
,
3809 "show ip pim vrf all join [json]",
3814 "PIM interface join information\n"
3817 bool uj
= use_json(argc
, argv
);
3823 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3827 vty_out(vty
, " \"%s\": ", vrf
->name
);
3830 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3831 pim_show_join(vrf
->info
, vty
, uj
);
3834 vty_out(vty
, "}\n");
3839 DEFUN (show_ip_pim_local_membership
,
3840 show_ip_pim_local_membership_cmd
,
3841 "show ip pim [vrf NAME] local-membership [json]",
3846 "PIM interface local-membership\n"
3850 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3851 bool uj
= use_json(argc
, argv
);
3856 pim_show_membership(vrf
->info
, vty
, uj
);
3861 DEFUN (show_ip_pim_neighbor
,
3862 show_ip_pim_neighbor_cmd
,
3863 "show ip pim [vrf NAME] neighbor [detail|WORD] [json]",
3868 "PIM neighbor information\n"
3870 "Name of interface or neighbor\n"
3874 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3875 bool uj
= use_json(argc
, argv
);
3880 if (argv_find(argv
, argc
, "detail", &idx
)
3881 || argv_find(argv
, argc
, "WORD", &idx
))
3882 pim_show_neighbors_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
3884 pim_show_neighbors(vrf
->info
, vty
, uj
);
3889 DEFUN (show_ip_pim_neighbor_vrf_all
,
3890 show_ip_pim_neighbor_vrf_all_cmd
,
3891 "show ip pim vrf all neighbor [detail|WORD] [json]",
3896 "PIM neighbor information\n"
3898 "Name of interface or neighbor\n"
3902 bool uj
= use_json(argc
, argv
);
3908 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3912 vty_out(vty
, " \"%s\": ", vrf
->name
);
3915 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3916 if (argv_find(argv
, argc
, "detail", &idx
)
3917 || argv_find(argv
, argc
, "WORD", &idx
))
3918 pim_show_neighbors_single(vrf
->info
, vty
,
3919 argv
[idx
]->arg
, uj
);
3921 pim_show_neighbors(vrf
->info
, vty
, uj
);
3924 vty_out(vty
, "}\n");
3929 DEFUN (show_ip_pim_secondary
,
3930 show_ip_pim_secondary_cmd
,
3931 "show ip pim [vrf NAME] secondary",
3936 "PIM neighbor addresses\n")
3939 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3944 pim_show_neighbors_secondary(vrf
->info
, vty
);
3949 DEFUN (show_ip_pim_state
,
3950 show_ip_pim_state_cmd
,
3951 "show ip pim [vrf NAME] state [A.B.C.D [A.B.C.D]] [json]",
3956 "PIM state information\n"
3957 "Unicast or Multicast address\n"
3958 "Multicast address\n"
3961 const char *src_or_group
= NULL
;
3962 const char *group
= NULL
;
3964 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3965 bool uj
= use_json(argc
, argv
);
3973 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
3974 src_or_group
= argv
[idx
]->arg
;
3976 group
= argv
[idx
+ 1]->arg
;
3979 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
3984 DEFUN (show_ip_pim_state_vrf_all
,
3985 show_ip_pim_state_vrf_all_cmd
,
3986 "show ip pim vrf all state [A.B.C.D [A.B.C.D]] [json]",
3991 "PIM state information\n"
3992 "Unicast or Multicast address\n"
3993 "Multicast address\n"
3996 const char *src_or_group
= NULL
;
3997 const char *group
= NULL
;
3999 bool uj
= use_json(argc
, argv
);
4008 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
4009 src_or_group
= argv
[idx
]->arg
;
4011 group
= argv
[idx
+ 1]->arg
;
4014 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4018 vty_out(vty
, " \"%s\": ", vrf
->name
);
4021 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4022 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
4025 vty_out(vty
, "}\n");
4030 DEFPY (show_ip_pim_upstream
,
4031 show_ip_pim_upstream_cmd
,
4032 "show ip pim [vrf NAME] upstream [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
4037 "PIM upstream information\n"
4038 "The Source or Group\n"
4042 struct prefix_sg sg
= {0};
4045 struct pim_instance
*pim
;
4047 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
4050 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
4053 pim
= pim_get_pim_instance(v
->vrf_id
);
4056 vty_out(vty
, "%% Unable to find pim instance\n");
4060 if (s_or_g
.s_addr
!= 0) {
4061 if (g
.s_addr
!= 0) {
4067 pim_show_upstream(pim
, vty
, &sg
, uj
);
4072 DEFUN (show_ip_pim_upstream_vrf_all
,
4073 show_ip_pim_upstream_vrf_all_cmd
,
4074 "show ip pim vrf all upstream [json]",
4079 "PIM upstream information\n"
4082 struct prefix_sg sg
= {0};
4083 bool uj
= use_json(argc
, argv
);
4089 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4093 vty_out(vty
, " \"%s\": ", vrf
->name
);
4096 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4097 pim_show_upstream(vrf
->info
, vty
, &sg
, uj
);
4103 DEFUN (show_ip_pim_upstream_join_desired
,
4104 show_ip_pim_upstream_join_desired_cmd
,
4105 "show ip pim [vrf NAME] upstream-join-desired [json]",
4110 "PIM upstream join-desired\n"
4114 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4115 bool uj
= use_json(argc
, argv
);
4120 pim_show_join_desired(vrf
->info
, vty
, uj
);
4125 DEFUN (show_ip_pim_upstream_rpf
,
4126 show_ip_pim_upstream_rpf_cmd
,
4127 "show ip pim [vrf NAME] upstream-rpf [json]",
4132 "PIM upstream source rpf\n"
4136 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4137 bool uj
= use_json(argc
, argv
);
4142 pim_show_upstream_rpf(vrf
->info
, vty
, uj
);
4147 DEFUN (show_ip_pim_rp
,
4149 "show ip pim [vrf NAME] rp-info [json]",
4154 "PIM RP information\n"
4158 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4159 bool uj
= use_json(argc
, argv
);
4164 pim_rp_show_information(vrf
->info
, vty
, uj
);
4169 DEFUN (show_ip_pim_rp_vrf_all
,
4170 show_ip_pim_rp_vrf_all_cmd
,
4171 "show ip pim vrf all rp-info [json]",
4176 "PIM RP information\n"
4179 bool uj
= use_json(argc
, argv
);
4185 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4189 vty_out(vty
, " \"%s\": ", vrf
->name
);
4192 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4193 pim_rp_show_information(vrf
->info
, vty
, uj
);
4196 vty_out(vty
, "}\n");
4201 DEFUN (show_ip_pim_rpf
,
4202 show_ip_pim_rpf_cmd
,
4203 "show ip pim [vrf NAME] rpf [json]",
4208 "PIM cached source rpf information\n"
4212 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4213 bool uj
= use_json(argc
, argv
);
4218 pim_show_rpf(vrf
->info
, vty
, uj
);
4223 DEFUN (show_ip_pim_rpf_vrf_all
,
4224 show_ip_pim_rpf_vrf_all_cmd
,
4225 "show ip pim vrf all rpf [json]",
4230 "PIM cached source rpf information\n"
4233 bool uj
= use_json(argc
, argv
);
4239 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4243 vty_out(vty
, " \"%s\": ", vrf
->name
);
4246 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4247 pim_show_rpf(vrf
->info
, vty
, uj
);
4250 vty_out(vty
, "}\n");
4255 DEFUN (show_ip_pim_nexthop
,
4256 show_ip_pim_nexthop_cmd
,
4257 "show ip pim [vrf NAME] nexthop",
4262 "PIM cached nexthop rpf information\n")
4265 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4270 pim_show_nexthop(vrf
->info
, vty
);
4275 DEFUN (show_ip_pim_nexthop_lookup
,
4276 show_ip_pim_nexthop_lookup_cmd
,
4277 "show ip pim [vrf NAME] nexthop-lookup A.B.C.D A.B.C.D",
4282 "PIM cached nexthop rpf lookup\n"
4283 "Source/RP address\n"
4284 "Multicast Group address\n")
4286 struct prefix nht_p
;
4288 struct in_addr src_addr
, grp_addr
;
4289 struct in_addr vif_source
;
4290 const char *addr_str
, *addr_str1
;
4292 struct pim_nexthop nexthop
;
4293 char nexthop_addr_str
[PREFIX_STRLEN
];
4294 char grp_str
[PREFIX_STRLEN
];
4296 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4301 argv_find(argv
, argc
, "A.B.C.D", &idx
);
4302 addr_str
= argv
[idx
]->arg
;
4303 result
= inet_pton(AF_INET
, addr_str
, &src_addr
);
4305 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
4306 errno
, safe_strerror(errno
));
4310 if (pim_is_group_224_4(src_addr
)) {
4312 "Invalid argument. Expected Valid Source Address.\n");
4316 addr_str1
= argv
[idx
+ 1]->arg
;
4317 result
= inet_pton(AF_INET
, addr_str1
, &grp_addr
);
4319 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
4320 errno
, safe_strerror(errno
));
4324 if (!pim_is_group_224_4(grp_addr
)) {
4326 "Invalid argument. Expected Valid Multicast Group Address.\n");
4330 if (!pim_rp_set_upstream_addr(vrf
->info
, &vif_source
, src_addr
,
4334 nht_p
.family
= AF_INET
;
4335 nht_p
.prefixlen
= IPV4_MAX_BITLEN
;
4336 nht_p
.u
.prefix4
= vif_source
;
4337 grp
.family
= AF_INET
;
4338 grp
.prefixlen
= IPV4_MAX_BITLEN
;
4339 grp
.u
.prefix4
= grp_addr
;
4340 memset(&nexthop
, 0, sizeof(nexthop
));
4342 result
= pim_ecmp_nexthop_lookup(vrf
->info
, &nexthop
, &nht_p
, &grp
, 0);
4346 "Nexthop Lookup failed, no usable routes returned.\n");
4350 pim_addr_dump("<grp?>", &grp
, grp_str
, sizeof(grp_str
));
4351 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
4352 nexthop_addr_str
, sizeof(nexthop_addr_str
));
4353 vty_out(vty
, "Group %s --- Nexthop %s Interface %s \n", grp_str
,
4354 nexthop_addr_str
, nexthop
.interface
->name
);
4359 DEFUN (show_ip_pim_interface_traffic
,
4360 show_ip_pim_interface_traffic_cmd
,
4361 "show ip pim [vrf NAME] interface traffic [WORD] [json]",
4366 "PIM interface information\n"
4367 "Protocol Packet counters\n"
4372 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4373 bool uj
= use_json(argc
, argv
);
4378 if (argv_find(argv
, argc
, "WORD", &idx
))
4379 pim_show_interface_traffic_single(vrf
->info
, vty
,
4380 argv
[idx
]->arg
, uj
);
4382 pim_show_interface_traffic(vrf
->info
, vty
, uj
);
4387 static void show_multicast_interfaces(struct pim_instance
*pim
, struct vty
*vty
)
4389 struct interface
*ifp
;
4394 "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut\n");
4396 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
4397 struct pim_interface
*pim_ifp
;
4398 struct in_addr ifaddr
;
4399 struct sioc_vif_req vreq
;
4401 pim_ifp
= ifp
->info
;
4406 memset(&vreq
, 0, sizeof(vreq
));
4407 vreq
.vifi
= pim_ifp
->mroute_vif_index
;
4409 if (ioctl(pim
->mroute_socket
, SIOCGETVIFCNT
, &vreq
)) {
4411 "ioctl(SIOCGETVIFCNT=%lu) failure for interface %s vif_index=%d: errno=%d: %s",
4412 (unsigned long)SIOCGETVIFCNT
, ifp
->name
,
4413 pim_ifp
->mroute_vif_index
, errno
,
4414 safe_strerror(errno
));
4417 ifaddr
= pim_ifp
->primary_address
;
4419 vty_out(vty
, "%-16s %-15s %3d %3d %7lu %7lu %10lu %10lu\n",
4420 ifp
->name
, inet_ntoa(ifaddr
), ifp
->ifindex
,
4421 pim_ifp
->mroute_vif_index
, (unsigned long)vreq
.icount
,
4422 (unsigned long)vreq
.ocount
, (unsigned long)vreq
.ibytes
,
4423 (unsigned long)vreq
.obytes
);
4427 static void pim_cmd_show_ip_multicast_helper(struct pim_instance
*pim
,
4430 struct vrf
*vrf
= pim
->vrf
;
4431 time_t now
= pim_time_monotonic_sec();
4437 vty_out(vty
, "Router MLAG Role: %s\n",
4438 mlag_role2str(router
->role
, mlag_role
, sizeof(mlag_role
)));
4439 vty_out(vty
, "Mroute socket descriptor:");
4441 vty_out(vty
, " %d(%s)\n", pim
->mroute_socket
, vrf
->name
);
4443 pim_time_uptime(uptime
, sizeof(uptime
),
4444 now
- pim
->mroute_socket_creation
);
4445 vty_out(vty
, "Mroute socket uptime: %s\n", uptime
);
4449 pim_zebra_zclient_update(vty
);
4450 pim_zlookup_show_ip_multicast(vty
);
4453 vty_out(vty
, "Maximum highest VifIndex: %d\n", PIM_MAX_USABLE_VIFS
);
4456 vty_out(vty
, "Upstream Join Timer: %d secs\n", router
->t_periodic
);
4457 vty_out(vty
, "Join/Prune Holdtime: %d secs\n", PIM_JP_HOLDTIME
);
4458 vty_out(vty
, "PIM ECMP: %s\n", pim
->ecmp_enable
? "Enable" : "Disable");
4459 vty_out(vty
, "PIM ECMP Rebalance: %s\n",
4460 pim
->ecmp_rebalance_enable
? "Enable" : "Disable");
4464 show_rpf_refresh_stats(vty
, pim
, now
, NULL
);
4468 show_scan_oil_stats(pim
, vty
, now
);
4470 show_multicast_interfaces(pim
, vty
);
4473 DEFUN (show_ip_multicast
,
4474 show_ip_multicast_cmd
,
4475 "show ip multicast [vrf NAME]",
4479 "Multicast global information\n")
4482 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4487 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
4492 DEFUN (show_ip_multicast_vrf_all
,
4493 show_ip_multicast_vrf_all_cmd
,
4494 "show ip multicast vrf all",
4498 "Multicast global information\n")
4500 bool uj
= use_json(argc
, argv
);
4506 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4510 vty_out(vty
, " \"%s\": ", vrf
->name
);
4513 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4514 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
4517 vty_out(vty
, "}\n");
4522 static void show_mroute(struct pim_instance
*pim
, struct vty
*vty
, bool fill
,
4525 struct listnode
*node
;
4526 struct channel_oil
*c_oil
;
4527 struct static_route
*s_route
;
4529 json_object
*json
= NULL
;
4530 json_object
*json_group
= NULL
;
4531 json_object
*json_source
= NULL
;
4532 json_object
*json_oil
= NULL
;
4533 json_object
*json_ifp_out
= NULL
;
4536 char grp_str
[INET_ADDRSTRLEN
];
4537 char src_str
[INET_ADDRSTRLEN
];
4538 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
4539 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
4541 struct interface
*ifp_in
;
4545 json
= json_object_new_object();
4548 "Source Group Proto Input Output TTL Uptime\n");
4551 now
= pim_time_monotonic_sec();
4553 /* print list of PIM and IGMP routes */
4554 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
4557 if (!c_oil
->installed
&& !uj
)
4560 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
4562 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
4564 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
4567 strcpy(in_ifname
, ifp_in
->name
);
4569 strcpy(in_ifname
, "<iif?>");
4573 /* Find the group, create it if it doesn't exist */
4574 json_object_object_get_ex(json
, grp_str
, &json_group
);
4577 json_group
= json_object_new_object();
4578 json_object_object_add(json
, grp_str
,
4582 /* Find the source nested under the group, create it if
4583 * it doesn't exist */
4584 json_object_object_get_ex(json_group
, src_str
,
4588 json_source
= json_object_new_object();
4589 json_object_object_add(json_group
, src_str
,
4593 /* Find the inbound interface nested under the source,
4594 * create it if it doesn't exist */
4595 json_object_int_add(json_source
, "installed",
4597 json_object_int_add(json_source
, "refCount",
4598 c_oil
->oil_ref_count
);
4599 json_object_int_add(json_source
, "oilSize",
4601 json_object_int_add(json_source
, "OilInheritedRescan",
4602 c_oil
->oil_inherited_rescan
);
4603 json_object_string_add(json_source
, "iif", in_ifname
);
4607 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
4609 struct interface
*ifp_out
;
4610 char mroute_uptime
[10];
4613 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
4617 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
4619 mroute_uptime
, sizeof(mroute_uptime
),
4620 now
- c_oil
->mroute_creation
);
4624 strcpy(out_ifname
, ifp_out
->name
);
4626 strcpy(out_ifname
, "<oif?>");
4629 json_ifp_out
= json_object_new_object();
4630 json_object_string_add(json_ifp_out
, "source",
4632 json_object_string_add(json_ifp_out
, "group",
4635 if (c_oil
->oif_flags
[oif_vif_index
]
4636 & PIM_OIF_FLAG_PROTO_PIM
)
4637 json_object_boolean_true_add(
4638 json_ifp_out
, "protocolPim");
4640 if (c_oil
->oif_flags
[oif_vif_index
]
4641 & PIM_OIF_FLAG_PROTO_IGMP
)
4642 json_object_boolean_true_add(
4643 json_ifp_out
, "protocolIgmp");
4645 if (c_oil
->oif_flags
[oif_vif_index
]
4646 & PIM_OIF_FLAG_PROTO_SOURCE
)
4647 json_object_boolean_true_add(
4648 json_ifp_out
, "protocolSource");
4650 if (c_oil
->oif_flags
[oif_vif_index
]
4651 & PIM_OIF_FLAG_PROTO_STAR
)
4652 json_object_boolean_true_add(
4654 "protocolInherited");
4656 json_object_string_add(json_ifp_out
,
4659 json_object_int_add(json_ifp_out
, "iVifI",
4660 c_oil
->oil
.mfcc_parent
);
4661 json_object_string_add(json_ifp_out
,
4662 "outboundInterface",
4664 json_object_int_add(json_ifp_out
, "oVifI",
4666 json_object_int_add(json_ifp_out
, "ttl", ttl
);
4667 json_object_string_add(json_ifp_out
, "upTime",
4670 json_oil
= json_object_new_object();
4671 json_object_object_add(json_source
,
4674 json_object_object_add(json_oil
, out_ifname
,
4677 if (c_oil
->oif_flags
[oif_vif_index
]
4678 & PIM_OIF_FLAG_PROTO_PIM
) {
4679 strcpy(proto
, "PIM");
4682 if (c_oil
->oif_flags
[oif_vif_index
]
4683 & PIM_OIF_FLAG_PROTO_IGMP
) {
4684 strcpy(proto
, "IGMP");
4687 if (c_oil
->oif_flags
[oif_vif_index
]
4688 & PIM_OIF_FLAG_PROTO_SOURCE
) {
4689 strcpy(proto
, "SRC");
4692 if (c_oil
->oif_flags
[oif_vif_index
]
4693 & PIM_OIF_FLAG_PROTO_STAR
) {
4694 strcpy(proto
, "STAR");
4698 "%-15s %-15s %-6s %-16s %-16s %-3d %8s\n",
4699 src_str
, grp_str
, proto
, in_ifname
,
4700 out_ifname
, ttl
, mroute_uptime
);
4705 in_ifname
[0] = '\0';
4711 if (!uj
&& !found_oif
) {
4712 vty_out(vty
, "%-15s %-15s %-6s %-16s %-16s %-3d %8s\n",
4713 src_str
, grp_str
, "none", in_ifname
, "none", 0,
4718 /* Print list of static routes */
4719 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
4722 if (!s_route
->c_oil
.installed
)
4725 pim_inet4_dump("<group?>", s_route
->group
, grp_str
,
4727 pim_inet4_dump("<source?>", s_route
->source
, src_str
,
4729 ifp_in
= pim_if_find_by_vif_index(pim
, s_route
->iif
);
4733 strcpy(in_ifname
, ifp_in
->name
);
4735 strcpy(in_ifname
, "<iif?>");
4739 /* Find the group, create it if it doesn't exist */
4740 json_object_object_get_ex(json
, grp_str
, &json_group
);
4743 json_group
= json_object_new_object();
4744 json_object_object_add(json
, grp_str
,
4748 /* Find the source nested under the group, create it if
4749 * it doesn't exist */
4750 json_object_object_get_ex(json_group
, src_str
,
4754 json_source
= json_object_new_object();
4755 json_object_object_add(json_group
, src_str
,
4759 json_object_string_add(json_source
, "iif", in_ifname
);
4762 strcpy(proto
, "STATIC");
4765 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
4767 struct interface
*ifp_out
;
4768 char oif_uptime
[10];
4771 ttl
= s_route
->oif_ttls
[oif_vif_index
];
4775 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
4777 oif_uptime
, sizeof(oif_uptime
),
4780 .oif_creation
[oif_vif_index
]);
4784 strcpy(out_ifname
, ifp_out
->name
);
4786 strcpy(out_ifname
, "<oif?>");
4789 json_ifp_out
= json_object_new_object();
4790 json_object_string_add(json_ifp_out
, "source",
4792 json_object_string_add(json_ifp_out
, "group",
4794 json_object_boolean_true_add(json_ifp_out
,
4796 json_object_string_add(json_ifp_out
,
4799 json_object_int_add(
4800 json_ifp_out
, "iVifI",
4801 s_route
->c_oil
.oil
.mfcc_parent
);
4802 json_object_string_add(json_ifp_out
,
4803 "outboundInterface",
4805 json_object_int_add(json_ifp_out
, "oVifI",
4807 json_object_int_add(json_ifp_out
, "ttl", ttl
);
4808 json_object_string_add(json_ifp_out
, "upTime",
4811 json_oil
= json_object_new_object();
4812 json_object_object_add(json_source
,
4815 json_object_object_add(json_oil
, out_ifname
,
4819 "%-15s %-15s %-6s %-16s %-16s %-3d %8s %s\n",
4820 src_str
, grp_str
, proto
, in_ifname
,
4821 out_ifname
, ttl
, oif_uptime
,
4823 if (first
&& !fill
) {
4826 in_ifname
[0] = '\0';
4832 if (!uj
&& !found_oif
) {
4834 "%-15s %-15s %-6s %-16s %-16s %-3d %8s %s\n",
4835 src_str
, grp_str
, proto
, in_ifname
, "none", 0,
4836 "--:--:--", pim
->vrf
->name
);
4841 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4842 json
, JSON_C_TO_STRING_PRETTY
));
4843 json_object_free(json
);
4847 DEFUN (show_ip_mroute
,
4849 "show ip mroute [vrf NAME] [fill] [json]",
4854 "Fill in Assumed data\n"
4857 bool uj
= use_json(argc
, argv
);
4860 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4865 if (argv_find(argv
, argc
, "fill", &idx
))
4868 show_mroute(vrf
->info
, vty
, fill
, uj
);
4872 DEFUN (show_ip_mroute_vrf_all
,
4873 show_ip_mroute_vrf_all_cmd
,
4874 "show ip mroute vrf all [fill] [json]",
4879 "Fill in Assumed data\n"
4882 bool uj
= use_json(argc
, argv
);
4888 if (argv_find(argv
, argc
, "fill", &idx
))
4893 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4897 vty_out(vty
, " \"%s\": ", vrf
->name
);
4900 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4901 show_mroute(vrf
->info
, vty
, fill
, uj
);
4904 vty_out(vty
, "}\n");
4909 static void show_mroute_count(struct pim_instance
*pim
, struct vty
*vty
)
4911 struct listnode
*node
;
4912 struct channel_oil
*c_oil
;
4913 struct static_route
*s_route
;
4918 "Source Group LastUsed Packets Bytes WrongIf \n");
4920 /* Print PIM and IGMP route counts */
4921 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
4922 char group_str
[INET_ADDRSTRLEN
];
4923 char source_str
[INET_ADDRSTRLEN
];
4925 if (!c_oil
->installed
)
4928 pim_mroute_update_counters(c_oil
);
4930 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, group_str
,
4932 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, source_str
,
4933 sizeof(source_str
));
4935 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
4936 source_str
, group_str
, c_oil
->cc
.lastused
/ 100,
4937 c_oil
->cc
.pktcnt
, c_oil
->cc
.bytecnt
,
4938 c_oil
->cc
.wrong_if
);
4941 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
4942 char group_str
[INET_ADDRSTRLEN
];
4943 char source_str
[INET_ADDRSTRLEN
];
4945 if (!s_route
->c_oil
.installed
)
4948 pim_mroute_update_counters(&s_route
->c_oil
);
4950 pim_inet4_dump("<group?>", s_route
->c_oil
.oil
.mfcc_mcastgrp
,
4951 group_str
, sizeof(group_str
));
4952 pim_inet4_dump("<source?>", s_route
->c_oil
.oil
.mfcc_origin
,
4953 source_str
, sizeof(source_str
));
4955 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
4956 source_str
, group_str
, s_route
->c_oil
.cc
.lastused
,
4957 s_route
->c_oil
.cc
.pktcnt
, s_route
->c_oil
.cc
.bytecnt
,
4958 s_route
->c_oil
.cc
.wrong_if
);
4962 DEFUN (show_ip_mroute_count
,
4963 show_ip_mroute_count_cmd
,
4964 "show ip mroute [vrf NAME] count",
4969 "Route and packet count data\n")
4972 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4977 show_mroute_count(vrf
->info
, vty
);
4981 DEFUN (show_ip_mroute_count_vrf_all
,
4982 show_ip_mroute_count_vrf_all_cmd
,
4983 "show ip mroute vrf all count",
4988 "Route and packet count data\n")
4990 bool uj
= use_json(argc
, argv
);
4996 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5000 vty_out(vty
, " \"%s\": ", vrf
->name
);
5003 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5004 show_mroute_count(vrf
->info
, vty
);
5007 vty_out(vty
, "}\n");
5014 "show ip rib [vrf NAME] A.B.C.D",
5019 "Unicast address\n")
5022 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5023 struct in_addr addr
;
5024 const char *addr_str
;
5025 struct pim_nexthop nexthop
;
5026 char nexthop_addr_str
[PREFIX_STRLEN
];
5032 memset(&nexthop
, 0, sizeof(nexthop
));
5033 argv_find(argv
, argc
, "A.B.C.D", &idx
);
5034 addr_str
= argv
[idx
]->arg
;
5035 result
= inet_pton(AF_INET
, addr_str
, &addr
);
5037 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
5038 errno
, safe_strerror(errno
));
5042 if (!pim_nexthop_lookup(vrf
->info
, &nexthop
, addr
, 0)) {
5044 "Failure querying RIB nexthop for unicast address %s\n",
5050 "Address NextHop Interface Metric Preference\n");
5052 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
5053 nexthop_addr_str
, sizeof(nexthop_addr_str
));
5055 vty_out(vty
, "%-15s %-15s %-9s %6d %10d\n", addr_str
, nexthop_addr_str
,
5056 nexthop
.interface
? nexthop
.interface
->name
: "<ifname?>",
5057 nexthop
.mrib_route_metric
, nexthop
.mrib_metric_preference
);
5062 static void show_ssmpingd(struct pim_instance
*pim
, struct vty
*vty
)
5064 struct listnode
*node
;
5065 struct ssmpingd_sock
*ss
;
5069 "Source Socket Address Port Uptime Requests\n");
5071 if (!pim
->ssmpingd_list
)
5074 now
= pim_time_monotonic_sec();
5076 for (ALL_LIST_ELEMENTS_RO(pim
->ssmpingd_list
, node
, ss
)) {
5077 char source_str
[INET_ADDRSTRLEN
];
5079 struct sockaddr_in bind_addr
;
5080 socklen_t len
= sizeof(bind_addr
);
5081 char bind_addr_str
[INET_ADDRSTRLEN
];
5083 pim_inet4_dump("<src?>", ss
->source_addr
, source_str
,
5084 sizeof(source_str
));
5086 if (pim_socket_getsockname(
5087 ss
->sock_fd
, (struct sockaddr
*)&bind_addr
, &len
)) {
5089 "%% Failure reading socket name for ssmpingd source %s on fd=%d\n",
5090 source_str
, ss
->sock_fd
);
5093 pim_inet4_dump("<addr?>", bind_addr
.sin_addr
, bind_addr_str
,
5094 sizeof(bind_addr_str
));
5095 pim_time_uptime(ss_uptime
, sizeof(ss_uptime
),
5096 now
- ss
->creation
);
5098 vty_out(vty
, "%-15s %6d %-15s %5d %8s %8lld\n", source_str
,
5099 ss
->sock_fd
, bind_addr_str
, ntohs(bind_addr
.sin_port
),
5100 ss_uptime
, (long long)ss
->requests
);
5104 DEFUN (show_ip_ssmpingd
,
5105 show_ip_ssmpingd_cmd
,
5106 "show ip ssmpingd [vrf NAME]",
5113 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5118 show_ssmpingd(vrf
->info
, vty
);
5122 static int pim_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
5123 const char *rp
, const char *group
,
5128 result
= pim_rp_new(pim
, rp
, group
, plist
);
5130 if (result
== PIM_GROUP_BAD_ADDRESS
) {
5131 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
5132 return CMD_WARNING_CONFIG_FAILED
;
5135 if (result
== PIM_RP_BAD_ADDRESS
) {
5136 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
5137 return CMD_WARNING_CONFIG_FAILED
;
5140 if (result
== PIM_RP_NO_PATH
) {
5141 vty_out(vty
, "%% No Path to RP address specified: %s\n", rp
);
5145 if (result
== PIM_GROUP_OVERLAP
) {
5147 "%% Group range specified cannot exact match another\n");
5148 return CMD_WARNING_CONFIG_FAILED
;
5151 if (result
== PIM_GROUP_PFXLIST_OVERLAP
) {
5153 "%% This group is already covered by a RP prefix-list\n");
5154 return CMD_WARNING_CONFIG_FAILED
;
5157 if (result
== PIM_RP_PFXLIST_IN_USE
) {
5159 "%% The same prefix-list cannot be applied to multiple RPs\n");
5160 return CMD_WARNING_CONFIG_FAILED
;
5163 if (result
== PIM_GROUP_BAD_ADDR_MASK_COMBO
) {
5164 vty_out(vty
, "%% Inconsistent address and mask: %s\n",
5166 return CMD_WARNING_CONFIG_FAILED
;
5172 static int pim_cmd_spt_switchover(struct pim_instance
*pim
,
5173 enum pim_spt_switchover spt
,
5176 pim
->spt
.switchover
= spt
;
5178 switch (pim
->spt
.switchover
) {
5179 case PIM_SPT_IMMEDIATE
:
5180 XFREE(MTYPE_PIM_SPT_PLIST_NAME
, pim
->spt
.plist
);
5182 pim_upstream_add_lhr_star_pimreg(pim
);
5184 case PIM_SPT_INFINITY
:
5185 pim_upstream_remove_lhr_star_pimreg(pim
, plist
);
5187 XFREE(MTYPE_PIM_SPT_PLIST_NAME
, pim
->spt
.plist
);
5191 XSTRDUP(MTYPE_PIM_SPT_PLIST_NAME
, plist
);
5198 DEFUN (ip_pim_spt_switchover_infinity
,
5199 ip_pim_spt_switchover_infinity_cmd
,
5200 "ip pim spt-switchover infinity-and-beyond",
5204 "Never switch to SPT Tree\n")
5206 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5207 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, NULL
);
5210 DEFUN (ip_pim_spt_switchover_infinity_plist
,
5211 ip_pim_spt_switchover_infinity_plist_cmd
,
5212 "ip pim spt-switchover infinity-and-beyond prefix-list WORD",
5216 "Never switch to SPT Tree\n"
5217 "Prefix-List to control which groups to switch\n"
5218 "Prefix-List name\n")
5220 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5221 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, argv
[5]->arg
);
5224 DEFUN (no_ip_pim_spt_switchover_infinity
,
5225 no_ip_pim_spt_switchover_infinity_cmd
,
5226 "no ip pim spt-switchover infinity-and-beyond",
5231 "Never switch to SPT Tree\n")
5233 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5234 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
5237 DEFUN (no_ip_pim_spt_switchover_infinity_plist
,
5238 no_ip_pim_spt_switchover_infinity_plist_cmd
,
5239 "no ip pim spt-switchover infinity-and-beyond prefix-list WORD",
5244 "Never switch to SPT Tree\n"
5245 "Prefix-List to control which groups to switch\n"
5246 "Prefix-List name\n")
5248 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5249 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
5252 DEFUN (ip_pim_joinprune_time
,
5253 ip_pim_joinprune_time_cmd
,
5254 "ip pim join-prune-interval (60-600)",
5256 "pim multicast routing\n"
5257 "Join Prune Send Interval\n"
5260 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5261 router
->t_periodic
= atoi(argv
[3]->arg
);
5265 DEFUN (no_ip_pim_joinprune_time
,
5266 no_ip_pim_joinprune_time_cmd
,
5267 "no ip pim join-prune-interval (60-600)",
5270 "pim multicast routing\n"
5271 "Join Prune Send Interval\n"
5274 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5275 router
->t_periodic
= PIM_DEFAULT_T_PERIODIC
;
5279 DEFUN (ip_pim_register_suppress
,
5280 ip_pim_register_suppress_cmd
,
5281 "ip pim register-suppress-time (5-60000)",
5283 "pim multicast routing\n"
5284 "Register Suppress Timer\n"
5287 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5288 router
->register_suppress_time
= atoi(argv
[3]->arg
);
5292 DEFUN (no_ip_pim_register_suppress
,
5293 no_ip_pim_register_suppress_cmd
,
5294 "no ip pim register-suppress-time (5-60000)",
5297 "pim multicast routing\n"
5298 "Register Suppress Timer\n"
5301 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5302 router
->register_suppress_time
= PIM_REGISTER_SUPPRESSION_TIME_DEFAULT
;
5306 DEFUN (ip_pim_rp_keep_alive
,
5307 ip_pim_rp_keep_alive_cmd
,
5308 "ip pim rp keep-alive-timer (31-60000)",
5310 "pim multicast routing\n"
5312 "Keep alive Timer\n"
5315 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5316 pim
->rp_keep_alive_time
= atoi(argv
[4]->arg
);
5320 DEFUN (no_ip_pim_rp_keep_alive
,
5321 no_ip_pim_rp_keep_alive_cmd
,
5322 "no ip pim rp keep-alive-timer (31-60000)",
5325 "pim multicast routing\n"
5327 "Keep alive Timer\n"
5330 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5331 pim
->rp_keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
5335 DEFUN (ip_pim_keep_alive
,
5336 ip_pim_keep_alive_cmd
,
5337 "ip pim keep-alive-timer (31-60000)",
5339 "pim multicast routing\n"
5340 "Keep alive Timer\n"
5343 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5344 pim
->keep_alive_time
= atoi(argv
[3]->arg
);
5348 DEFUN (no_ip_pim_keep_alive
,
5349 no_ip_pim_keep_alive_cmd
,
5350 "no ip pim keep-alive-timer (31-60000)",
5353 "pim multicast routing\n"
5354 "Keep alive Timer\n"
5357 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5358 pim
->keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
5362 DEFUN (ip_pim_packets
,
5364 "ip pim packets (1-100)",
5366 "pim multicast routing\n"
5367 "packets to process at one time per fd\n"
5368 "Number of packets\n")
5370 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5371 router
->packet_process
= atoi(argv
[3]->arg
);
5375 DEFUN (no_ip_pim_packets
,
5376 no_ip_pim_packets_cmd
,
5377 "no ip pim packets (1-100)",
5380 "pim multicast routing\n"
5381 "packets to process at one time per fd\n"
5382 "Number of packets\n")
5384 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5385 router
->packet_process
= PIM_DEFAULT_PACKET_PROCESS
;
5389 DEFUN (ip_pim_v6_secondary
,
5390 ip_pim_v6_secondary_cmd
,
5391 "ip pim send-v6-secondary",
5393 "pim multicast routing\n"
5394 "Send v6 secondary addresses\n")
5396 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5397 pim
->send_v6_secondary
= 1;
5402 DEFUN (no_ip_pim_v6_secondary
,
5403 no_ip_pim_v6_secondary_cmd
,
5404 "no ip pim send-v6-secondary",
5407 "pim multicast routing\n"
5408 "Send v6 secondary addresses\n")
5410 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5411 pim
->send_v6_secondary
= 0;
5418 "ip pim rp A.B.C.D [A.B.C.D/M]",
5420 "pim multicast routing\n"
5422 "ip address of RP\n"
5423 "Group Address range to cover\n")
5425 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5428 if (argc
== (idx_ipv4
+ 1))
5429 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
5432 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
5433 argv
[idx_ipv4
+ 1]->arg
, NULL
);
5436 DEFUN (ip_pim_rp_prefix_list
,
5437 ip_pim_rp_prefix_list_cmd
,
5438 "ip pim rp A.B.C.D prefix-list WORD",
5440 "pim multicast routing\n"
5442 "ip address of RP\n"
5443 "group prefix-list filter\n"
5444 "Name of a prefix-list\n")
5446 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5447 return pim_rp_cmd_worker(pim
, vty
, argv
[3]->arg
, NULL
, argv
[5]->arg
);
5450 static int pim_no_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
5451 const char *rp
, const char *group
,
5454 int result
= pim_rp_del(pim
, rp
, group
, plist
);
5456 if (result
== PIM_GROUP_BAD_ADDRESS
) {
5457 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
5458 return CMD_WARNING_CONFIG_FAILED
;
5461 if (result
== PIM_RP_BAD_ADDRESS
) {
5462 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
5463 return CMD_WARNING_CONFIG_FAILED
;
5466 if (result
== PIM_RP_NOT_FOUND
) {
5467 vty_out(vty
, "%% Unable to find specified RP\n");
5468 return CMD_WARNING_CONFIG_FAILED
;
5474 DEFUN (no_ip_pim_rp
,
5476 "no ip pim rp A.B.C.D [A.B.C.D/M]",
5479 "pim multicast routing\n"
5481 "ip address of RP\n"
5482 "Group Address range to cover\n")
5484 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5485 int idx_ipv4
= 4, idx_group
= 0;
5487 if (argv_find(argv
, argc
, "A.B.C.D/M", &idx_group
))
5488 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
5489 argv
[idx_group
]->arg
, NULL
);
5491 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
5495 DEFUN (no_ip_pim_rp_prefix_list
,
5496 no_ip_pim_rp_prefix_list_cmd
,
5497 "no ip pim rp A.B.C.D prefix-list WORD",
5500 "pim multicast routing\n"
5502 "ip address of RP\n"
5503 "group prefix-list filter\n"
5504 "Name of a prefix-list\n")
5506 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5507 return pim_no_rp_cmd_worker(pim
, vty
, argv
[4]->arg
, NULL
, argv
[6]->arg
);
5510 static int pim_ssm_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
5513 int result
= pim_ssm_range_set(pim
, pim
->vrf_id
, plist
);
5515 if (result
== PIM_SSM_ERR_NONE
)
5519 case PIM_SSM_ERR_NO_VRF
:
5520 vty_out(vty
, "%% VRF doesn't exist\n");
5522 case PIM_SSM_ERR_DUP
:
5523 vty_out(vty
, "%% duplicate config\n");
5526 vty_out(vty
, "%% ssm range config failed\n");
5529 return CMD_WARNING_CONFIG_FAILED
;
5532 DEFUN (ip_pim_ssm_prefix_list
,
5533 ip_pim_ssm_prefix_list_cmd
,
5534 "ip pim ssm prefix-list WORD",
5536 "pim multicast routing\n"
5537 "Source Specific Multicast\n"
5538 "group range prefix-list filter\n"
5539 "Name of a prefix-list\n")
5541 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5542 return pim_ssm_cmd_worker(pim
, vty
, argv
[4]->arg
);
5545 DEFUN (no_ip_pim_ssm_prefix_list
,
5546 no_ip_pim_ssm_prefix_list_cmd
,
5547 "no ip pim ssm prefix-list",
5550 "pim multicast routing\n"
5551 "Source Specific Multicast\n"
5552 "group range prefix-list filter\n")
5554 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5555 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
5558 DEFUN (no_ip_pim_ssm_prefix_list_name
,
5559 no_ip_pim_ssm_prefix_list_name_cmd
,
5560 "no ip pim ssm prefix-list WORD",
5563 "pim multicast routing\n"
5564 "Source Specific Multicast\n"
5565 "group range prefix-list filter\n"
5566 "Name of a prefix-list\n")
5568 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5569 struct pim_ssm
*ssm
= pim
->ssm_info
;
5571 if (ssm
->plist_name
&& !strcmp(ssm
->plist_name
, argv
[5]->arg
))
5572 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
5574 vty_out(vty
, "%% pim ssm prefix-list %s doesn't exist\n", argv
[5]->arg
);
5576 return CMD_WARNING_CONFIG_FAILED
;
5579 static void ip_pim_ssm_show_group_range(struct pim_instance
*pim
,
5580 struct vty
*vty
, bool uj
)
5582 struct pim_ssm
*ssm
= pim
->ssm_info
;
5583 const char *range_str
=
5584 ssm
->plist_name
? ssm
->plist_name
: PIM_SSM_STANDARD_RANGE
;
5588 json
= json_object_new_object();
5589 json_object_string_add(json
, "ssmGroups", range_str
);
5590 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5591 json
, JSON_C_TO_STRING_PRETTY
));
5592 json_object_free(json
);
5594 vty_out(vty
, "SSM group range : %s\n", range_str
);
5597 DEFUN (show_ip_pim_ssm_range
,
5598 show_ip_pim_ssm_range_cmd
,
5599 "show ip pim [vrf NAME] group-type [json]",
5608 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5609 bool uj
= use_json(argc
, argv
);
5614 ip_pim_ssm_show_group_range(vrf
->info
, vty
, uj
);
5619 static void ip_pim_ssm_show_group_type(struct pim_instance
*pim
,
5620 struct vty
*vty
, bool uj
,
5623 struct in_addr group_addr
;
5624 const char *type_str
;
5627 result
= inet_pton(AF_INET
, group
, &group_addr
);
5629 type_str
= "invalid";
5631 if (pim_is_group_224_4(group_addr
))
5633 pim_is_grp_ssm(pim
, group_addr
) ? "SSM" : "ASM";
5635 type_str
= "not-multicast";
5640 json
= json_object_new_object();
5641 json_object_string_add(json
, "groupType", type_str
);
5642 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5643 json
, JSON_C_TO_STRING_PRETTY
));
5644 json_object_free(json
);
5646 vty_out(vty
, "Group type : %s\n", type_str
);
5649 DEFUN (show_ip_pim_group_type
,
5650 show_ip_pim_group_type_cmd
,
5651 "show ip pim [vrf NAME] group-type A.B.C.D [json]",
5656 "multicast group type\n"
5661 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5662 bool uj
= use_json(argc
, argv
);
5667 argv_find(argv
, argc
, "A.B.C.D", &idx
);
5668 ip_pim_ssm_show_group_type(vrf
->info
, vty
, uj
, argv
[idx
]->arg
);
5675 "ip ssmpingd [A.B.C.D]",
5680 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5683 struct in_addr source_addr
;
5684 const char *source_str
= (argc
== 3) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
5686 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
5688 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
5689 source_str
, errno
, safe_strerror(errno
));
5690 return CMD_WARNING_CONFIG_FAILED
;
5693 result
= pim_ssmpingd_start(pim
, source_addr
);
5695 vty_out(vty
, "%% Failure starting ssmpingd for source %s: %d\n",
5696 source_str
, result
);
5697 return CMD_WARNING_CONFIG_FAILED
;
5703 DEFUN (no_ip_ssmpingd
,
5705 "no ip ssmpingd [A.B.C.D]",
5711 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5714 struct in_addr source_addr
;
5715 const char *source_str
= (argc
== 4) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
5717 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
5719 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
5720 source_str
, errno
, safe_strerror(errno
));
5721 return CMD_WARNING_CONFIG_FAILED
;
5724 result
= pim_ssmpingd_stop(pim
, source_addr
);
5726 vty_out(vty
, "%% Failure stopping ssmpingd for source %s: %d\n",
5727 source_str
, result
);
5728 return CMD_WARNING_CONFIG_FAILED
;
5738 "pim multicast routing\n"
5739 "Enable PIM ECMP \n")
5741 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5742 pim
->ecmp_enable
= true;
5747 DEFUN (no_ip_pim_ecmp
,
5752 "pim multicast routing\n"
5753 "Disable PIM ECMP \n")
5755 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5756 pim
->ecmp_enable
= false;
5761 DEFUN (ip_pim_ecmp_rebalance
,
5762 ip_pim_ecmp_rebalance_cmd
,
5763 "ip pim ecmp rebalance",
5765 "pim multicast routing\n"
5766 "Enable PIM ECMP \n"
5767 "Enable PIM ECMP Rebalance\n")
5769 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5770 pim
->ecmp_enable
= true;
5771 pim
->ecmp_rebalance_enable
= true;
5776 DEFUN (no_ip_pim_ecmp_rebalance
,
5777 no_ip_pim_ecmp_rebalance_cmd
,
5778 "no ip pim ecmp rebalance",
5781 "pim multicast routing\n"
5782 "Disable PIM ECMP \n"
5783 "Disable PIM ECMP Rebalance\n")
5785 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5786 pim
->ecmp_rebalance_enable
= false;
5791 static int pim_cmd_igmp_start(struct vty
*vty
, struct interface
*ifp
)
5793 struct pim_interface
*pim_ifp
;
5794 uint8_t need_startup
= 0;
5796 pim_ifp
= ifp
->info
;
5799 pim_ifp
= pim_if_new(ifp
, true, false, false);
5801 vty_out(vty
, "Could not enable IGMP on interface %s\n",
5803 return CMD_WARNING_CONFIG_FAILED
;
5807 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
5808 PIM_IF_DO_IGMP(pim_ifp
->options
);
5813 /* 'ip igmp' executed multiple times, with need_startup
5814 avoid multiple if add all and membership refresh */
5816 pim_if_addr_add_all(ifp
);
5817 pim_if_membership_refresh(ifp
);
5823 DEFUN (interface_ip_igmp
,
5824 interface_ip_igmp_cmd
,
5829 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5831 return pim_cmd_igmp_start(vty
, ifp
);
5834 DEFUN (interface_no_ip_igmp
,
5835 interface_no_ip_igmp_cmd
,
5841 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5842 struct pim_interface
*pim_ifp
= ifp
->info
;
5847 PIM_IF_DONT_IGMP(pim_ifp
->options
);
5849 pim_if_membership_clear(ifp
);
5851 pim_if_addr_del_all_igmp(ifp
);
5853 if (!PIM_IF_TEST_PIM(pim_ifp
->options
)) {
5860 DEFUN (interface_ip_igmp_join
,
5861 interface_ip_igmp_join_cmd
,
5862 "ip igmp join A.B.C.D A.B.C.D",
5865 "IGMP join multicast group\n"
5866 "Multicast group address\n"
5869 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5872 const char *group_str
;
5873 const char *source_str
;
5874 struct in_addr group_addr
;
5875 struct in_addr source_addr
;
5879 group_str
= argv
[idx_ipv4
]->arg
;
5880 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
5882 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
5883 errno
, safe_strerror(errno
));
5884 return CMD_WARNING_CONFIG_FAILED
;
5887 /* Source address */
5888 source_str
= argv
[idx_ipv4_2
]->arg
;
5889 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
5891 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
5892 source_str
, errno
, safe_strerror(errno
));
5893 return CMD_WARNING_CONFIG_FAILED
;
5896 CMD_FERR_RETURN(pim_if_igmp_join_add(ifp
, group_addr
, source_addr
),
5897 "Failure joining IGMP group: $ERR");
5902 DEFUN (interface_no_ip_igmp_join
,
5903 interface_no_ip_igmp_join_cmd
,
5904 "no ip igmp join A.B.C.D A.B.C.D",
5908 "IGMP join multicast group\n"
5909 "Multicast group address\n"
5912 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5915 const char *group_str
;
5916 const char *source_str
;
5917 struct in_addr group_addr
;
5918 struct in_addr source_addr
;
5922 group_str
= argv
[idx_ipv4
]->arg
;
5923 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
5925 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
5926 errno
, safe_strerror(errno
));
5927 return CMD_WARNING_CONFIG_FAILED
;
5930 /* Source address */
5931 source_str
= argv
[idx_ipv4_2
]->arg
;
5932 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
5934 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
5935 source_str
, errno
, safe_strerror(errno
));
5936 return CMD_WARNING_CONFIG_FAILED
;
5939 result
= pim_if_igmp_join_del(ifp
, group_addr
, source_addr
);
5942 "%% Failure leaving IGMP group %s source %s on interface %s: %d\n",
5943 group_str
, source_str
, ifp
->name
, result
);
5944 return CMD_WARNING_CONFIG_FAILED
;
5951 CLI reconfiguration affects the interface level (struct pim_interface).
5952 This function propagates the reconfiguration to every active socket
5955 static void igmp_sock_query_interval_reconfig(struct igmp_sock
*igmp
)
5957 struct interface
*ifp
;
5958 struct pim_interface
*pim_ifp
;
5962 /* other querier present? */
5964 if (igmp
->t_other_querier_timer
)
5967 /* this is the querier */
5969 zassert(igmp
->interface
);
5970 zassert(igmp
->interface
->info
);
5972 ifp
= igmp
->interface
;
5973 pim_ifp
= ifp
->info
;
5975 if (PIM_DEBUG_IGMP_TRACE
) {
5976 char ifaddr_str
[INET_ADDRSTRLEN
];
5977 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
5978 sizeof(ifaddr_str
));
5979 zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
5980 __PRETTY_FUNCTION__
, ifaddr_str
, ifp
->name
,
5981 pim_ifp
->igmp_default_query_interval
);
5985 igmp_startup_mode_on() will reset QQI:
5987 igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
5989 igmp_startup_mode_on(igmp
);
5992 static void igmp_sock_query_reschedule(struct igmp_sock
*igmp
)
5994 if (igmp
->t_igmp_query_timer
) {
5995 /* other querier present */
5996 zassert(igmp
->t_igmp_query_timer
);
5997 zassert(!igmp
->t_other_querier_timer
);
5999 pim_igmp_general_query_off(igmp
);
6000 pim_igmp_general_query_on(igmp
);
6002 zassert(igmp
->t_igmp_query_timer
);
6003 zassert(!igmp
->t_other_querier_timer
);
6005 /* this is the querier */
6007 zassert(!igmp
->t_igmp_query_timer
);
6008 zassert(igmp
->t_other_querier_timer
);
6010 pim_igmp_other_querier_timer_off(igmp
);
6011 pim_igmp_other_querier_timer_on(igmp
);
6013 zassert(!igmp
->t_igmp_query_timer
);
6014 zassert(igmp
->t_other_querier_timer
);
6018 static void change_query_interval(struct pim_interface
*pim_ifp
,
6021 struct listnode
*sock_node
;
6022 struct igmp_sock
*igmp
;
6024 pim_ifp
->igmp_default_query_interval
= query_interval
;
6026 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
6027 igmp_sock_query_interval_reconfig(igmp
);
6028 igmp_sock_query_reschedule(igmp
);
6032 static void change_query_max_response_time(struct pim_interface
*pim_ifp
,
6033 int query_max_response_time_dsec
)
6035 struct listnode
*sock_node
;
6036 struct igmp_sock
*igmp
;
6038 pim_ifp
->igmp_query_max_response_time_dsec
=
6039 query_max_response_time_dsec
;
6042 Below we modify socket/group/source timers in order to quickly
6043 reflect the change. Otherwise, those timers would eventually catch
6047 /* scan all sockets */
6048 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
6049 struct listnode
*grp_node
;
6050 struct igmp_group
*grp
;
6052 /* reschedule socket general query */
6053 igmp_sock_query_reschedule(igmp
);
6055 /* scan socket groups */
6056 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grp_node
,
6058 struct listnode
*src_node
;
6059 struct igmp_source
*src
;
6061 /* reset group timers for groups in EXCLUDE mode */
6062 if (grp
->group_filtermode_isexcl
) {
6063 igmp_group_reset_gmi(grp
);
6066 /* scan group sources */
6067 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
,
6070 /* reset source timers for sources with running
6072 if (src
->t_source_timer
) {
6073 igmp_source_reset_gmi(igmp
, grp
, src
);
6080 #define IGMP_QUERY_INTERVAL_MIN (1)
6081 #define IGMP_QUERY_INTERVAL_MAX (1800)
6083 DEFUN (interface_ip_igmp_query_interval
,
6084 interface_ip_igmp_query_interval_cmd
,
6085 "ip igmp query-interval (1-1800)",
6088 IFACE_IGMP_QUERY_INTERVAL_STR
6089 "Query interval in seconds\n")
6091 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6092 struct pim_interface
*pim_ifp
= ifp
->info
;
6094 int query_interval_dsec
;
6098 ret
= pim_cmd_igmp_start(vty
, ifp
);
6099 if (ret
!= CMD_SUCCESS
)
6101 pim_ifp
= ifp
->info
;
6104 query_interval
= atoi(argv
[3]->arg
);
6105 query_interval_dsec
= 10 * query_interval
;
6108 It seems we don't need to check bounds since command.c does it
6109 already, but we verify them anyway for extra safety.
6111 if (query_interval
< IGMP_QUERY_INTERVAL_MIN
) {
6113 "General query interval %d lower than minimum %d\n",
6114 query_interval
, IGMP_QUERY_INTERVAL_MIN
);
6115 return CMD_WARNING_CONFIG_FAILED
;
6117 if (query_interval
> IGMP_QUERY_INTERVAL_MAX
) {
6119 "General query interval %d higher than maximum %d\n",
6120 query_interval
, IGMP_QUERY_INTERVAL_MAX
);
6121 return CMD_WARNING_CONFIG_FAILED
;
6124 if (query_interval_dsec
<= pim_ifp
->igmp_query_max_response_time_dsec
) {
6126 "Can't set general query interval %d dsec <= query max response time %d dsec.\n",
6127 query_interval_dsec
,
6128 pim_ifp
->igmp_query_max_response_time_dsec
);
6129 return CMD_WARNING_CONFIG_FAILED
;
6132 change_query_interval(pim_ifp
, query_interval
);
6137 DEFUN (interface_no_ip_igmp_query_interval
,
6138 interface_no_ip_igmp_query_interval_cmd
,
6139 "no ip igmp query-interval",
6143 IFACE_IGMP_QUERY_INTERVAL_STR
)
6145 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6146 struct pim_interface
*pim_ifp
= ifp
->info
;
6147 int default_query_interval_dsec
;
6152 default_query_interval_dsec
= IGMP_GENERAL_QUERY_INTERVAL
* 10;
6154 if (default_query_interval_dsec
6155 <= pim_ifp
->igmp_query_max_response_time_dsec
) {
6157 "Can't set default general query interval %d dsec <= query max response time %d dsec.\n",
6158 default_query_interval_dsec
,
6159 pim_ifp
->igmp_query_max_response_time_dsec
);
6160 return CMD_WARNING_CONFIG_FAILED
;
6163 change_query_interval(pim_ifp
, IGMP_GENERAL_QUERY_INTERVAL
);
6168 DEFUN (interface_ip_igmp_version
,
6169 interface_ip_igmp_version_cmd
,
6170 "ip igmp version (2-3)",
6174 "IGMP version number\n")
6176 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6177 struct pim_interface
*pim_ifp
= ifp
->info
;
6178 int igmp_version
, old_version
= 0;
6182 ret
= pim_cmd_igmp_start(vty
, ifp
);
6183 if (ret
!= CMD_SUCCESS
)
6185 pim_ifp
= ifp
->info
;
6188 igmp_version
= atoi(argv
[3]->arg
);
6189 old_version
= pim_ifp
->igmp_version
;
6190 pim_ifp
->igmp_version
= igmp_version
;
6192 // Check if IGMP is Enabled otherwise, enable on interface
6193 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
6194 PIM_IF_DO_IGMP(pim_ifp
->options
);
6195 pim_if_addr_add_all(ifp
);
6196 pim_if_membership_refresh(ifp
);
6197 old_version
= igmp_version
;
6198 // avoid refreshing membership again.
6200 /* Current and new version is different refresh existing
6201 membership. Going from 3 -> 2 or 2 -> 3. */
6202 if (old_version
!= igmp_version
)
6203 pim_if_membership_refresh(ifp
);
6208 DEFUN (interface_no_ip_igmp_version
,
6209 interface_no_ip_igmp_version_cmd
,
6210 "no ip igmp version (2-3)",
6215 "IGMP version number\n")
6217 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6218 struct pim_interface
*pim_ifp
= ifp
->info
;
6223 pim_ifp
->igmp_version
= IGMP_DEFAULT_VERSION
;
6228 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
6229 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
6231 DEFUN (interface_ip_igmp_query_max_response_time
,
6232 interface_ip_igmp_query_max_response_time_cmd
,
6233 "ip igmp query-max-response-time (10-250)",
6236 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
6237 "Query response value in deci-seconds\n")
6239 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6240 struct pim_interface
*pim_ifp
= ifp
->info
;
6241 int query_max_response_time
;
6245 ret
= pim_cmd_igmp_start(vty
, ifp
);
6246 if (ret
!= CMD_SUCCESS
)
6248 pim_ifp
= ifp
->info
;
6251 query_max_response_time
= atoi(argv
[3]->arg
);
6253 if (query_max_response_time
6254 >= pim_ifp
->igmp_default_query_interval
* 10) {
6256 "Can't set query max response time %d sec >= general query interval %d sec\n",
6257 query_max_response_time
,
6258 pim_ifp
->igmp_default_query_interval
);
6259 return CMD_WARNING_CONFIG_FAILED
;
6262 change_query_max_response_time(pim_ifp
, query_max_response_time
);
6267 DEFUN (interface_no_ip_igmp_query_max_response_time
,
6268 interface_no_ip_igmp_query_max_response_time_cmd
,
6269 "no ip igmp query-max-response-time (10-250)",
6273 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
6274 "Time for response in deci-seconds\n")
6276 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6277 struct pim_interface
*pim_ifp
= ifp
->info
;
6282 change_query_max_response_time(pim_ifp
,
6283 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
6288 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
6289 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
6291 DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec
,
6292 interface_ip_igmp_query_max_response_time_dsec_cmd
,
6293 "ip igmp query-max-response-time-dsec (10-250)",
6296 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
6297 "Query response value in deciseconds\n")
6299 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6300 struct pim_interface
*pim_ifp
= ifp
->info
;
6301 int query_max_response_time_dsec
;
6302 int default_query_interval_dsec
;
6306 ret
= pim_cmd_igmp_start(vty
, ifp
);
6307 if (ret
!= CMD_SUCCESS
)
6309 pim_ifp
= ifp
->info
;
6312 query_max_response_time_dsec
= atoi(argv
[4]->arg
);
6314 default_query_interval_dsec
= 10 * pim_ifp
->igmp_default_query_interval
;
6316 if (query_max_response_time_dsec
>= default_query_interval_dsec
) {
6318 "Can't set query max response time %d dsec >= general query interval %d dsec\n",
6319 query_max_response_time_dsec
,
6320 default_query_interval_dsec
);
6321 return CMD_WARNING_CONFIG_FAILED
;
6324 change_query_max_response_time(pim_ifp
, query_max_response_time_dsec
);
6329 DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec
,
6330 interface_no_ip_igmp_query_max_response_time_dsec_cmd
,
6331 "no ip igmp query-max-response-time-dsec",
6335 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
)
6337 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6338 struct pim_interface
*pim_ifp
= ifp
->info
;
6343 change_query_max_response_time(pim_ifp
,
6344 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
6349 DEFUN (interface_ip_pim_drprio
,
6350 interface_ip_pim_drprio_cmd
,
6351 "ip pim drpriority (1-4294967295)",
6354 "Set the Designated Router Election Priority\n"
6355 "Value of the new DR Priority\n")
6357 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6359 struct pim_interface
*pim_ifp
= ifp
->info
;
6360 uint32_t old_dr_prio
;
6363 vty_out(vty
, "Please enable PIM on interface, first\n");
6364 return CMD_WARNING_CONFIG_FAILED
;
6367 old_dr_prio
= pim_ifp
->pim_dr_priority
;
6369 pim_ifp
->pim_dr_priority
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
6371 if (old_dr_prio
!= pim_ifp
->pim_dr_priority
) {
6372 pim_if_dr_election(ifp
);
6373 pim_hello_restart_now(ifp
);
6379 DEFUN (interface_no_ip_pim_drprio
,
6380 interface_no_ip_pim_drprio_cmd
,
6381 "no ip pim drpriority [(1-4294967295)]",
6385 "Revert the Designated Router Priority to default\n"
6386 "Old Value of the Priority\n")
6388 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6389 struct pim_interface
*pim_ifp
= ifp
->info
;
6392 vty_out(vty
, "Pim not enabled on this interface\n");
6393 return CMD_WARNING_CONFIG_FAILED
;
6396 if (pim_ifp
->pim_dr_priority
!= PIM_DEFAULT_DR_PRIORITY
) {
6397 pim_ifp
->pim_dr_priority
= PIM_DEFAULT_DR_PRIORITY
;
6398 pim_if_dr_election(ifp
);
6399 pim_hello_restart_now(ifp
);
6405 static int pim_cmd_interface_add(struct interface
*ifp
)
6407 struct pim_interface
*pim_ifp
= ifp
->info
;
6410 pim_ifp
= pim_if_new(ifp
, false, true, false);
6415 PIM_IF_DO_PIM(pim_ifp
->options
);
6418 pim_if_addr_add_all(ifp
);
6419 pim_if_membership_refresh(ifp
);
6423 DEFPY_HIDDEN (pim_test_sg_keepalive
,
6424 pim_test_sg_keepalive_cmd
,
6425 "test pim [vrf NAME$name] keepalive-reset A.B.C.D$source A.B.C.D$group",
6429 "Reset the Keepalive Timer\n"
6430 "The Source we are resetting\n"
6431 "The Group we are resetting\n")
6433 struct pim_upstream
*up
;
6434 struct pim_instance
*pim
;
6435 struct prefix_sg sg
;
6441 pim
= pim_get_pim_instance(VRF_DEFAULT
);
6443 struct vrf
*vrf
= vrf_lookup_by_name(name
);
6446 vty_out(vty
, "%% Vrf specified: %s does not exist\n",
6451 pim
= pim_get_pim_instance(vrf
->vrf_id
);
6455 vty_out(vty
, "%% Unable to find pim instance\n");
6459 up
= pim_upstream_find(pim
, &sg
);
6461 vty_out(vty
, "%% Unable to find %s specified\n",
6462 pim_str_sg_dump(&sg
));
6466 vty_out(vty
, "Setting %s to current keep alive time: %d\n",
6467 pim_str_sg_dump(&sg
), pim
->keep_alive_time
);
6468 pim_upstream_keep_alive_timer_start(up
, pim
->keep_alive_time
);
6473 DEFPY_HIDDEN (interface_ip_pim_activeactive
,
6474 interface_ip_pim_activeactive_cmd
,
6475 "[no$no] ip pim active-active",
6479 "Mark interface as Active-Active for MLAG operations, Hidden because not finished yet\n")
6481 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6482 struct pim_interface
*pim_ifp
;
6484 if (!no
&& !pim_cmd_interface_add(ifp
)) {
6485 vty_out(vty
, "Could not enable PIM SM active-active on interface\n");
6486 return CMD_WARNING_CONFIG_FAILED
;
6489 pim_ifp
= ifp
->info
;
6491 pim_ifp
->activeactive
= false;
6493 pim_ifp
->activeactive
= true;
6498 DEFUN_HIDDEN (interface_ip_pim_ssm
,
6499 interface_ip_pim_ssm_cmd
,
6505 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6507 if (!pim_cmd_interface_add(ifp
)) {
6508 vty_out(vty
, "Could not enable PIM SM on interface\n");
6509 return CMD_WARNING_CONFIG_FAILED
;
6513 "WARN: Enabled PIM SM on interface; configure PIM SSM "
6514 "range if needed\n");
6518 static int interface_ip_pim_helper(struct vty
*vty
)
6520 struct pim_interface
*pim_ifp
;
6522 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6524 if (!pim_cmd_interface_add(ifp
)) {
6525 vty_out(vty
, "Could not enable PIM SM on interface\n");
6526 return CMD_WARNING_CONFIG_FAILED
;
6529 pim_ifp
= ifp
->info
;
6531 pim_if_create_pimreg(pim_ifp
->pim
);
6536 DEFUN_HIDDEN (interface_ip_pim_sm
,
6537 interface_ip_pim_sm_cmd
,
6543 return interface_ip_pim_helper(vty
);
6546 DEFUN (interface_ip_pim
,
6547 interface_ip_pim_cmd
,
6552 return interface_ip_pim_helper(vty
);
6555 static int pim_cmd_interface_delete(struct interface
*ifp
)
6557 struct pim_interface
*pim_ifp
= ifp
->info
;
6562 PIM_IF_DONT_PIM(pim_ifp
->options
);
6564 pim_if_membership_clear(ifp
);
6567 pim_sock_delete() removes all neighbors from
6568 pim_ifp->pim_neighbor_list.
6570 pim_sock_delete(ifp
, "pim unconfigured on interface");
6572 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
6573 pim_if_addr_del_all(ifp
);
6580 static int interface_no_ip_pim_helper(struct vty
*vty
)
6582 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6583 if (!pim_cmd_interface_delete(ifp
)) {
6584 vty_out(vty
, "Unable to delete interface information\n");
6585 return CMD_WARNING_CONFIG_FAILED
;
6591 DEFUN_HIDDEN (interface_no_ip_pim_ssm
,
6592 interface_no_ip_pim_ssm_cmd
,
6599 return interface_no_ip_pim_helper(vty
);
6602 DEFUN_HIDDEN (interface_no_ip_pim_sm
,
6603 interface_no_ip_pim_sm_cmd
,
6610 return interface_no_ip_pim_helper(vty
);
6613 DEFUN (interface_no_ip_pim
,
6614 interface_no_ip_pim_cmd
,
6620 return interface_no_ip_pim_helper(vty
);
6624 DEFUN(interface_ip_pim_boundary_oil
,
6625 interface_ip_pim_boundary_oil_cmd
,
6626 "ip multicast boundary oil WORD",
6628 "Generic multicast configuration options\n"
6629 "Define multicast boundary\n"
6630 "Filter OIL by group using prefix list\n"
6631 "Prefix list to filter OIL with\n")
6633 VTY_DECLVAR_CONTEXT(interface
, iif
);
6634 struct pim_interface
*pim_ifp
;
6637 argv_find(argv
, argc
, "WORD", &idx
);
6639 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6641 if (pim_ifp
->boundary_oil_plist
)
6642 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
6644 pim_ifp
->boundary_oil_plist
=
6645 XSTRDUP(MTYPE_PIM_INTERFACE
, argv
[idx
]->arg
);
6647 /* Interface will be pruned from OIL on next Join */
6651 DEFUN(interface_no_ip_pim_boundary_oil
,
6652 interface_no_ip_pim_boundary_oil_cmd
,
6653 "no ip multicast boundary oil [WORD]",
6656 "Generic multicast configuration options\n"
6657 "Define multicast boundary\n"
6658 "Filter OIL by group using prefix list\n"
6659 "Prefix list to filter OIL with\n")
6661 VTY_DECLVAR_CONTEXT(interface
, iif
);
6662 struct pim_interface
*pim_ifp
;
6665 argv_find(argv
, argc
, "WORD", &idx
);
6667 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6669 if (pim_ifp
->boundary_oil_plist
)
6670 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
6675 DEFUN (interface_ip_mroute
,
6676 interface_ip_mroute_cmd
,
6677 "ip mroute INTERFACE A.B.C.D",
6679 "Add multicast route\n"
6680 "Outgoing interface name\n"
6683 VTY_DECLVAR_CONTEXT(interface
, iif
);
6684 struct pim_interface
*pim_ifp
;
6685 struct pim_instance
*pim
;
6686 int idx_interface
= 2;
6688 struct interface
*oif
;
6689 const char *oifname
;
6690 const char *grp_str
;
6691 struct in_addr grp_addr
;
6692 struct in_addr src_addr
;
6695 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6698 oifname
= argv
[idx_interface
]->arg
;
6699 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6701 vty_out(vty
, "No such interface name %s\n", oifname
);
6705 grp_str
= argv
[idx_ipv4
]->arg
;
6706 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6708 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6709 errno
, safe_strerror(errno
));
6713 src_addr
.s_addr
= INADDR_ANY
;
6715 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6716 vty_out(vty
, "Failed to add route\n");
6723 DEFUN (interface_ip_mroute_source
,
6724 interface_ip_mroute_source_cmd
,
6725 "ip mroute INTERFACE A.B.C.D A.B.C.D",
6727 "Add multicast route\n"
6728 "Outgoing interface name\n"
6732 VTY_DECLVAR_CONTEXT(interface
, iif
);
6733 struct pim_interface
*pim_ifp
;
6734 struct pim_instance
*pim
;
6735 int idx_interface
= 2;
6738 struct interface
*oif
;
6739 const char *oifname
;
6740 const char *grp_str
;
6741 struct in_addr grp_addr
;
6742 const char *src_str
;
6743 struct in_addr src_addr
;
6746 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6749 oifname
= argv
[idx_interface
]->arg
;
6750 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6752 vty_out(vty
, "No such interface name %s\n", oifname
);
6756 grp_str
= argv
[idx_ipv4
]->arg
;
6757 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6759 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6760 errno
, safe_strerror(errno
));
6764 src_str
= argv
[idx_ipv4_2
]->arg
;
6765 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
6767 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
6768 errno
, safe_strerror(errno
));
6772 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6773 vty_out(vty
, "Failed to add route\n");
6780 DEFUN (interface_no_ip_mroute
,
6781 interface_no_ip_mroute_cmd
,
6782 "no ip mroute INTERFACE A.B.C.D",
6785 "Add multicast route\n"
6786 "Outgoing interface name\n"
6789 VTY_DECLVAR_CONTEXT(interface
, iif
);
6790 struct pim_interface
*pim_ifp
;
6791 struct pim_instance
*pim
;
6792 int idx_interface
= 3;
6794 struct interface
*oif
;
6795 const char *oifname
;
6796 const char *grp_str
;
6797 struct in_addr grp_addr
;
6798 struct in_addr src_addr
;
6801 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6804 oifname
= argv
[idx_interface
]->arg
;
6805 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6807 vty_out(vty
, "No such interface name %s\n", oifname
);
6811 grp_str
= argv
[idx_ipv4
]->arg
;
6812 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6814 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6815 errno
, safe_strerror(errno
));
6819 src_addr
.s_addr
= INADDR_ANY
;
6821 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6822 vty_out(vty
, "Failed to remove route\n");
6829 DEFUN (interface_no_ip_mroute_source
,
6830 interface_no_ip_mroute_source_cmd
,
6831 "no ip mroute INTERFACE A.B.C.D A.B.C.D",
6834 "Add multicast route\n"
6835 "Outgoing interface name\n"
6839 VTY_DECLVAR_CONTEXT(interface
, iif
);
6840 struct pim_interface
*pim_ifp
;
6841 struct pim_instance
*pim
;
6842 int idx_interface
= 3;
6845 struct interface
*oif
;
6846 const char *oifname
;
6847 const char *grp_str
;
6848 struct in_addr grp_addr
;
6849 const char *src_str
;
6850 struct in_addr src_addr
;
6853 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6856 oifname
= argv
[idx_interface
]->arg
;
6857 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6859 vty_out(vty
, "No such interface name %s\n", oifname
);
6863 grp_str
= argv
[idx_ipv4
]->arg
;
6864 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6866 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6867 errno
, safe_strerror(errno
));
6871 src_str
= argv
[idx_ipv4_2
]->arg
;
6872 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
6874 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
6875 errno
, safe_strerror(errno
));
6879 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6880 vty_out(vty
, "Failed to remove route\n");
6887 DEFUN (interface_ip_pim_hello
,
6888 interface_ip_pim_hello_cmd
,
6889 "ip pim hello (1-180) [(1-180)]",
6893 IFACE_PIM_HELLO_TIME_STR
6894 IFACE_PIM_HELLO_HOLD_STR
)
6896 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6899 struct pim_interface
*pim_ifp
= ifp
->info
;
6902 if (!pim_cmd_interface_add(ifp
)) {
6903 vty_out(vty
, "Could not enable PIM SM on interface\n");
6904 return CMD_WARNING_CONFIG_FAILED
;
6908 pim_ifp
= ifp
->info
;
6909 pim_ifp
->pim_hello_period
= strtol(argv
[idx_time
]->arg
, NULL
, 10);
6911 if (argc
== idx_hold
+ 1)
6912 pim_ifp
->pim_default_holdtime
=
6913 strtol(argv
[idx_hold
]->arg
, NULL
, 10);
6918 DEFUN (interface_no_ip_pim_hello
,
6919 interface_no_ip_pim_hello_cmd
,
6920 "no ip pim hello [(1-180) (1-180)]",
6925 IFACE_PIM_HELLO_TIME_STR
6926 IFACE_PIM_HELLO_HOLD_STR
)
6928 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6929 struct pim_interface
*pim_ifp
= ifp
->info
;
6932 vty_out(vty
, "Pim not enabled on this interface\n");
6933 return CMD_WARNING_CONFIG_FAILED
;
6936 pim_ifp
->pim_hello_period
= PIM_DEFAULT_HELLO_PERIOD
;
6937 pim_ifp
->pim_default_holdtime
= -1;
6948 PIM_DO_DEBUG_IGMP_EVENTS
;
6949 PIM_DO_DEBUG_IGMP_PACKETS
;
6950 PIM_DO_DEBUG_IGMP_TRACE
;
6954 DEFUN (no_debug_igmp
,
6961 PIM_DONT_DEBUG_IGMP_EVENTS
;
6962 PIM_DONT_DEBUG_IGMP_PACKETS
;
6963 PIM_DONT_DEBUG_IGMP_TRACE
;
6968 DEFUN (debug_igmp_events
,
6969 debug_igmp_events_cmd
,
6970 "debug igmp events",
6973 DEBUG_IGMP_EVENTS_STR
)
6975 PIM_DO_DEBUG_IGMP_EVENTS
;
6979 DEFUN (no_debug_igmp_events
,
6980 no_debug_igmp_events_cmd
,
6981 "no debug igmp events",
6985 DEBUG_IGMP_EVENTS_STR
)
6987 PIM_DONT_DEBUG_IGMP_EVENTS
;
6992 DEFUN (debug_igmp_packets
,
6993 debug_igmp_packets_cmd
,
6994 "debug igmp packets",
6997 DEBUG_IGMP_PACKETS_STR
)
6999 PIM_DO_DEBUG_IGMP_PACKETS
;
7003 DEFUN (no_debug_igmp_packets
,
7004 no_debug_igmp_packets_cmd
,
7005 "no debug igmp packets",
7009 DEBUG_IGMP_PACKETS_STR
)
7011 PIM_DONT_DEBUG_IGMP_PACKETS
;
7016 DEFUN (debug_igmp_trace
,
7017 debug_igmp_trace_cmd
,
7021 DEBUG_IGMP_TRACE_STR
)
7023 PIM_DO_DEBUG_IGMP_TRACE
;
7027 DEFUN (no_debug_igmp_trace
,
7028 no_debug_igmp_trace_cmd
,
7029 "no debug igmp trace",
7033 DEBUG_IGMP_TRACE_STR
)
7035 PIM_DONT_DEBUG_IGMP_TRACE
;
7040 DEFUN (debug_mroute
,
7046 PIM_DO_DEBUG_MROUTE
;
7050 DEFUN (debug_mroute_detail
,
7051 debug_mroute_detail_cmd
,
7052 "debug mroute detail",
7057 PIM_DO_DEBUG_MROUTE_DETAIL
;
7061 DEFUN (no_debug_mroute
,
7062 no_debug_mroute_cmd
,
7068 PIM_DONT_DEBUG_MROUTE
;
7072 DEFUN (no_debug_mroute_detail
,
7073 no_debug_mroute_detail_cmd
,
7074 "no debug mroute detail",
7080 PIM_DONT_DEBUG_MROUTE_DETAIL
;
7084 DEFUN (debug_pim_static
,
7085 debug_pim_static_cmd
,
7091 PIM_DO_DEBUG_STATIC
;
7095 DEFUN (no_debug_pim_static
,
7096 no_debug_pim_static_cmd
,
7097 "no debug pim static",
7103 PIM_DONT_DEBUG_STATIC
;
7114 PIM_DO_DEBUG_PIM_EVENTS
;
7115 PIM_DO_DEBUG_PIM_PACKETS
;
7116 PIM_DO_DEBUG_PIM_TRACE
;
7117 PIM_DO_DEBUG_MSDP_EVENTS
;
7118 PIM_DO_DEBUG_MSDP_PACKETS
;
7122 DEFUN (no_debug_pim
,
7129 PIM_DONT_DEBUG_PIM_EVENTS
;
7130 PIM_DONT_DEBUG_PIM_PACKETS
;
7131 PIM_DONT_DEBUG_PIM_TRACE
;
7132 PIM_DONT_DEBUG_MSDP_EVENTS
;
7133 PIM_DONT_DEBUG_MSDP_PACKETS
;
7135 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
7136 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
7141 DEFUN (debug_pim_nht
,
7146 "Nexthop Tracking\n")
7148 PIM_DO_DEBUG_PIM_NHT
;
7152 DEFUN (no_debug_pim_nht
,
7153 no_debug_pim_nht_cmd
,
7158 "Nexthop Tracking\n")
7160 PIM_DONT_DEBUG_PIM_NHT
;
7164 DEFUN (debug_pim_nht_rp
,
7165 debug_pim_nht_rp_cmd
,
7169 "Nexthop Tracking\n"
7170 "RP Nexthop Tracking\n")
7172 PIM_DO_DEBUG_PIM_NHT_RP
;
7176 DEFUN (no_debug_pim_nht_rp
,
7177 no_debug_pim_nht_rp_cmd
,
7178 "no debug pim nht rp",
7182 "Nexthop Tracking\n"
7183 "RP Nexthop Tracking\n")
7185 PIM_DONT_DEBUG_PIM_NHT_RP
;
7189 DEFUN (debug_pim_events
,
7190 debug_pim_events_cmd
,
7194 DEBUG_PIM_EVENTS_STR
)
7196 PIM_DO_DEBUG_PIM_EVENTS
;
7200 DEFUN (no_debug_pim_events
,
7201 no_debug_pim_events_cmd
,
7202 "no debug pim events",
7206 DEBUG_PIM_EVENTS_STR
)
7208 PIM_DONT_DEBUG_PIM_EVENTS
;
7212 DEFUN (debug_pim_packets
,
7213 debug_pim_packets_cmd
,
7214 "debug pim packets [<hello|joins|register>]",
7217 DEBUG_PIM_PACKETS_STR
7218 DEBUG_PIM_HELLO_PACKETS_STR
7219 DEBUG_PIM_J_P_PACKETS_STR
7220 DEBUG_PIM_PIM_REG_PACKETS_STR
)
7223 if (argv_find(argv
, argc
, "hello", &idx
)) {
7224 PIM_DO_DEBUG_PIM_HELLO
;
7225 vty_out(vty
, "PIM Hello debugging is on\n");
7226 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
7227 PIM_DO_DEBUG_PIM_J_P
;
7228 vty_out(vty
, "PIM Join/Prune debugging is on\n");
7229 } else if (argv_find(argv
, argc
, "register", &idx
)) {
7230 PIM_DO_DEBUG_PIM_REG
;
7231 vty_out(vty
, "PIM Register debugging is on\n");
7233 PIM_DO_DEBUG_PIM_PACKETS
;
7234 vty_out(vty
, "PIM Packet debugging is on \n");
7239 DEFUN (no_debug_pim_packets
,
7240 no_debug_pim_packets_cmd
,
7241 "no debug pim packets [<hello|joins|register>]",
7245 DEBUG_PIM_PACKETS_STR
7246 DEBUG_PIM_HELLO_PACKETS_STR
7247 DEBUG_PIM_J_P_PACKETS_STR
7248 DEBUG_PIM_PIM_REG_PACKETS_STR
)
7251 if (argv_find(argv
, argc
, "hello", &idx
)) {
7252 PIM_DONT_DEBUG_PIM_HELLO
;
7253 vty_out(vty
, "PIM Hello debugging is off \n");
7254 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
7255 PIM_DONT_DEBUG_PIM_J_P
;
7256 vty_out(vty
, "PIM Join/Prune debugging is off \n");
7257 } else if (argv_find(argv
, argc
, "register", &idx
)) {
7258 PIM_DONT_DEBUG_PIM_REG
;
7259 vty_out(vty
, "PIM Register debugging is off\n");
7261 PIM_DONT_DEBUG_PIM_PACKETS
;
7267 DEFUN (debug_pim_packetdump_send
,
7268 debug_pim_packetdump_send_cmd
,
7269 "debug pim packet-dump send",
7272 DEBUG_PIM_PACKETDUMP_STR
7273 DEBUG_PIM_PACKETDUMP_SEND_STR
)
7275 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND
;
7279 DEFUN (no_debug_pim_packetdump_send
,
7280 no_debug_pim_packetdump_send_cmd
,
7281 "no debug pim packet-dump send",
7285 DEBUG_PIM_PACKETDUMP_STR
7286 DEBUG_PIM_PACKETDUMP_SEND_STR
)
7288 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
7292 DEFUN (debug_pim_packetdump_recv
,
7293 debug_pim_packetdump_recv_cmd
,
7294 "debug pim packet-dump receive",
7297 DEBUG_PIM_PACKETDUMP_STR
7298 DEBUG_PIM_PACKETDUMP_RECV_STR
)
7300 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV
;
7304 DEFUN (no_debug_pim_packetdump_recv
,
7305 no_debug_pim_packetdump_recv_cmd
,
7306 "no debug pim packet-dump receive",
7310 DEBUG_PIM_PACKETDUMP_STR
7311 DEBUG_PIM_PACKETDUMP_RECV_STR
)
7313 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
7317 DEFUN (debug_pim_trace
,
7318 debug_pim_trace_cmd
,
7322 DEBUG_PIM_TRACE_STR
)
7324 PIM_DO_DEBUG_PIM_TRACE
;
7328 DEFUN (debug_pim_trace_detail
,
7329 debug_pim_trace_detail_cmd
,
7330 "debug pim trace detail",
7334 "Detailed Information\n")
7336 PIM_DO_DEBUG_PIM_TRACE_DETAIL
;
7340 DEFUN (no_debug_pim_trace
,
7341 no_debug_pim_trace_cmd
,
7342 "no debug pim trace",
7346 DEBUG_PIM_TRACE_STR
)
7348 PIM_DONT_DEBUG_PIM_TRACE
;
7352 DEFUN (no_debug_pim_trace_detail
,
7353 no_debug_pim_trace_detail_cmd
,
7354 "no debug pim trace detail",
7359 "Detailed Information\n")
7361 PIM_DONT_DEBUG_PIM_TRACE_DETAIL
;
7365 DEFUN (debug_ssmpingd
,
7371 PIM_DO_DEBUG_SSMPINGD
;
7375 DEFUN (no_debug_ssmpingd
,
7376 no_debug_ssmpingd_cmd
,
7377 "no debug ssmpingd",
7382 PIM_DONT_DEBUG_SSMPINGD
;
7386 DEFUN (debug_pim_zebra
,
7387 debug_pim_zebra_cmd
,
7391 DEBUG_PIM_ZEBRA_STR
)
7397 DEFUN (no_debug_pim_zebra
,
7398 no_debug_pim_zebra_cmd
,
7399 "no debug pim zebra",
7403 DEBUG_PIM_ZEBRA_STR
)
7405 PIM_DONT_DEBUG_ZEBRA
;
7415 PIM_DO_DEBUG_MSDP_EVENTS
;
7416 PIM_DO_DEBUG_MSDP_PACKETS
;
7420 DEFUN (no_debug_msdp
,
7427 PIM_DONT_DEBUG_MSDP_EVENTS
;
7428 PIM_DONT_DEBUG_MSDP_PACKETS
;
7432 DEFUN (debug_msdp_events
,
7433 debug_msdp_events_cmd
,
7434 "debug msdp events",
7437 DEBUG_MSDP_EVENTS_STR
)
7439 PIM_DO_DEBUG_MSDP_EVENTS
;
7443 DEFUN (no_debug_msdp_events
,
7444 no_debug_msdp_events_cmd
,
7445 "no debug msdp events",
7449 DEBUG_MSDP_EVENTS_STR
)
7451 PIM_DONT_DEBUG_MSDP_EVENTS
;
7455 DEFUN (debug_msdp_packets
,
7456 debug_msdp_packets_cmd
,
7457 "debug msdp packets",
7460 DEBUG_MSDP_PACKETS_STR
)
7462 PIM_DO_DEBUG_MSDP_PACKETS
;
7466 DEFUN (no_debug_msdp_packets
,
7467 no_debug_msdp_packets_cmd
,
7468 "no debug msdp packets",
7472 DEBUG_MSDP_PACKETS_STR
)
7474 PIM_DONT_DEBUG_MSDP_PACKETS
;
7478 DEFUN (debug_mtrace
,
7484 PIM_DO_DEBUG_MTRACE
;
7488 DEFUN (no_debug_mtrace
,
7489 no_debug_mtrace_cmd
,
7495 PIM_DONT_DEBUG_MTRACE
;
7499 DEFUN_NOSH (show_debugging_pim
,
7500 show_debugging_pim_cmd
,
7501 "show debugging [pim]",
7506 vty_out(vty
, "PIM debugging status\n");
7508 pim_debug_config_write(vty
);
7513 static int interface_pim_use_src_cmd_worker(struct vty
*vty
, const char *source
)
7516 struct in_addr source_addr
;
7517 int ret
= CMD_SUCCESS
;
7518 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7520 result
= inet_pton(AF_INET
, source
, &source_addr
);
7522 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", source
,
7523 errno
, safe_strerror(errno
));
7524 return CMD_WARNING_CONFIG_FAILED
;
7527 result
= pim_update_source_set(ifp
, source_addr
);
7531 case PIM_IFACE_NOT_FOUND
:
7532 ret
= CMD_WARNING_CONFIG_FAILED
;
7533 vty_out(vty
, "Pim not enabled on this interface\n");
7535 case PIM_UPDATE_SOURCE_DUP
:
7537 vty_out(vty
, "%% Source already set to %s\n", source
);
7540 ret
= CMD_WARNING_CONFIG_FAILED
;
7541 vty_out(vty
, "%% Source set failed\n");
7547 DEFUN (interface_pim_use_source
,
7548 interface_pim_use_source_cmd
,
7549 "ip pim use-source A.B.C.D",
7552 "Configure primary IP address\n"
7553 "source ip address\n")
7555 return interface_pim_use_src_cmd_worker(vty
, argv
[3]->arg
);
7558 DEFUN (interface_no_pim_use_source
,
7559 interface_no_pim_use_source_cmd
,
7560 "no ip pim use-source [A.B.C.D]",
7564 "Delete source IP address\n"
7565 "source ip address\n")
7567 return interface_pim_use_src_cmd_worker(vty
, "0.0.0.0");
7575 "Enables BFD support\n")
7577 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7578 struct pim_interface
*pim_ifp
= ifp
->info
;
7579 struct bfd_info
*bfd_info
= NULL
;
7582 if (!pim_cmd_interface_add(ifp
)) {
7583 vty_out(vty
, "Could not enable PIM SM on interface\n");
7587 pim_ifp
= ifp
->info
;
7589 bfd_info
= pim_ifp
->bfd_info
;
7591 if (!bfd_info
|| !CHECK_FLAG(bfd_info
->flags
, BFD_FLAG_PARAM_CFG
))
7592 pim_bfd_if_param_set(ifp
, BFD_DEF_MIN_RX
, BFD_DEF_MIN_TX
,
7593 BFD_DEF_DETECT_MULT
, 1);
7598 DEFUN (no_ip_pim_bfd
,
7604 "Disables BFD support\n")
7606 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7607 struct pim_interface
*pim_ifp
= ifp
->info
;
7610 vty_out(vty
, "Pim not enabled on this interface\n");
7614 if (pim_ifp
->bfd_info
) {
7615 pim_bfd_reg_dereg_all_nbr(ifp
, ZEBRA_BFD_DEST_DEREGISTER
);
7616 bfd_info_free(&(pim_ifp
->bfd_info
));
7626 #endif /* HAVE_BFDD */
7628 ip_pim_bfd_param_cmd
,
7629 "ip pim bfd (2-255) (50-60000) (50-60000)",
7632 "Enables BFD support\n"
7633 "Detect Multiplier\n"
7634 "Required min receive interval\n"
7635 "Desired min transmit interval\n")
7637 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7639 int idx_number_2
= 4;
7640 int idx_number_3
= 5;
7645 struct pim_interface
*pim_ifp
= ifp
->info
;
7648 if (!pim_cmd_interface_add(ifp
)) {
7649 vty_out(vty
, "Could not enable PIM SM on interface\n");
7654 if ((ret
= bfd_validate_param(
7655 vty
, argv
[idx_number
]->arg
, argv
[idx_number_2
]->arg
,
7656 argv
[idx_number_3
]->arg
, &dm_val
, &rx_val
, &tx_val
))
7660 pim_bfd_if_param_set(ifp
, rx_val
, tx_val
, dm_val
, 0);
7666 ALIAS(no_ip_pim_bfd
, no_ip_pim_bfd_param_cmd
,
7667 "no ip pim bfd (2-255) (50-60000) (50-60000)", NO_STR IP_STR PIM_STR
7668 "Enables BFD support\n"
7669 "Detect Multiplier\n"
7670 "Required min receive interval\n"
7671 "Desired min transmit interval\n")
7672 #endif /* !HAVE_BFDD */
7674 static int ip_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
7675 const char *peer
, const char *local
)
7677 enum pim_msdp_err result
;
7678 struct in_addr peer_addr
;
7679 struct in_addr local_addr
;
7680 int ret
= CMD_SUCCESS
;
7682 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
7684 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
7685 errno
, safe_strerror(errno
));
7686 return CMD_WARNING_CONFIG_FAILED
;
7689 result
= inet_pton(AF_INET
, local
, &local_addr
);
7691 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", local
,
7692 errno
, safe_strerror(errno
));
7693 return CMD_WARNING_CONFIG_FAILED
;
7696 result
= pim_msdp_peer_add(pim
, peer_addr
, local_addr
, "default",
7699 case PIM_MSDP_ERR_NONE
:
7701 case PIM_MSDP_ERR_OOM
:
7702 ret
= CMD_WARNING_CONFIG_FAILED
;
7703 vty_out(vty
, "%% Out of memory\n");
7705 case PIM_MSDP_ERR_PEER_EXISTS
:
7707 vty_out(vty
, "%% Peer exists\n");
7709 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
7710 ret
= CMD_WARNING_CONFIG_FAILED
;
7711 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
7714 ret
= CMD_WARNING_CONFIG_FAILED
;
7715 vty_out(vty
, "%% peer add failed\n");
7721 DEFUN_HIDDEN (ip_msdp_peer
,
7723 "ip msdp peer A.B.C.D source A.B.C.D",
7726 "Configure MSDP peer\n"
7728 "Source address for TCP connection\n"
7729 "local ip address\n")
7731 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7732 return ip_msdp_peer_cmd_worker(pim
, vty
, argv
[3]->arg
, argv
[5]->arg
);
7735 static int ip_no_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
7738 enum pim_msdp_err result
;
7739 struct in_addr peer_addr
;
7741 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
7743 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
7744 errno
, safe_strerror(errno
));
7745 return CMD_WARNING_CONFIG_FAILED
;
7748 result
= pim_msdp_peer_del(pim
, peer_addr
);
7750 case PIM_MSDP_ERR_NONE
:
7752 case PIM_MSDP_ERR_NO_PEER
:
7753 vty_out(vty
, "%% Peer does not exist\n");
7756 vty_out(vty
, "%% peer del failed\n");
7759 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7762 DEFUN_HIDDEN (no_ip_msdp_peer
,
7763 no_ip_msdp_peer_cmd
,
7764 "no ip msdp peer A.B.C.D",
7768 "Delete MSDP peer\n"
7769 "peer ip address\n")
7771 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7772 return ip_no_msdp_peer_cmd_worker(pim
, vty
, argv
[4]->arg
);
7775 static int ip_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
7776 struct vty
*vty
, const char *mg
,
7779 enum pim_msdp_err result
;
7780 struct in_addr mbr_ip
;
7781 int ret
= CMD_SUCCESS
;
7783 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
7785 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
7786 errno
, safe_strerror(errno
));
7787 return CMD_WARNING_CONFIG_FAILED
;
7790 result
= pim_msdp_mg_mbr_add(pim
, mg
, mbr_ip
);
7792 case PIM_MSDP_ERR_NONE
:
7794 case PIM_MSDP_ERR_OOM
:
7795 ret
= CMD_WARNING_CONFIG_FAILED
;
7796 vty_out(vty
, "%% Out of memory\n");
7798 case PIM_MSDP_ERR_MG_MBR_EXISTS
:
7800 vty_out(vty
, "%% mesh-group member exists\n");
7802 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
7803 ret
= CMD_WARNING_CONFIG_FAILED
;
7804 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
7807 ret
= CMD_WARNING_CONFIG_FAILED
;
7808 vty_out(vty
, "%% member add failed\n");
7814 DEFUN (ip_msdp_mesh_group_member
,
7815 ip_msdp_mesh_group_member_cmd
,
7816 "ip msdp mesh-group WORD member A.B.C.D",
7819 "Configure MSDP mesh-group\n"
7821 "mesh group member\n"
7822 "peer ip address\n")
7824 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7825 return ip_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[3]->arg
,
7829 static int ip_no_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
7834 enum pim_msdp_err result
;
7835 struct in_addr mbr_ip
;
7837 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
7839 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
7840 errno
, safe_strerror(errno
));
7841 return CMD_WARNING_CONFIG_FAILED
;
7844 result
= pim_msdp_mg_mbr_del(pim
, mg
, mbr_ip
);
7846 case PIM_MSDP_ERR_NONE
:
7848 case PIM_MSDP_ERR_NO_MG
:
7849 vty_out(vty
, "%% mesh-group does not exist\n");
7851 case PIM_MSDP_ERR_NO_MG_MBR
:
7852 vty_out(vty
, "%% mesh-group member does not exist\n");
7855 vty_out(vty
, "%% mesh-group member del failed\n");
7858 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7860 DEFUN (no_ip_msdp_mesh_group_member
,
7861 no_ip_msdp_mesh_group_member_cmd
,
7862 "no ip msdp mesh-group WORD member A.B.C.D",
7866 "Delete MSDP mesh-group member\n"
7868 "mesh group member\n"
7869 "peer ip address\n")
7871 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7872 return ip_no_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[4]->arg
,
7876 static int ip_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
7877 struct vty
*vty
, const char *mg
,
7880 enum pim_msdp_err result
;
7881 struct in_addr src_ip
;
7883 result
= inet_pton(AF_INET
, src
, &src_ip
);
7885 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", src
,
7886 errno
, safe_strerror(errno
));
7887 return CMD_WARNING_CONFIG_FAILED
;
7890 result
= pim_msdp_mg_src_add(pim
, mg
, src_ip
);
7892 case PIM_MSDP_ERR_NONE
:
7894 case PIM_MSDP_ERR_OOM
:
7895 vty_out(vty
, "%% Out of memory\n");
7897 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
7898 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
7901 vty_out(vty
, "%% source add failed\n");
7904 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7908 DEFUN (ip_msdp_mesh_group_source
,
7909 ip_msdp_mesh_group_source_cmd
,
7910 "ip msdp mesh-group WORD source A.B.C.D",
7913 "Configure MSDP mesh-group\n"
7915 "mesh group local address\n"
7916 "source ip address for the TCP connection\n")
7918 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7919 return ip_msdp_mesh_group_source_cmd_worker(pim
, vty
, argv
[3]->arg
,
7923 static int ip_no_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
7927 enum pim_msdp_err result
;
7929 result
= pim_msdp_mg_src_del(pim
, mg
);
7931 case PIM_MSDP_ERR_NONE
:
7933 case PIM_MSDP_ERR_NO_MG
:
7934 vty_out(vty
, "%% mesh-group does not exist\n");
7937 vty_out(vty
, "%% mesh-group source del failed\n");
7940 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7943 static int ip_no_msdp_mesh_group_cmd_worker(struct pim_instance
*pim
,
7944 struct vty
*vty
, const char *mg
)
7946 enum pim_msdp_err result
;
7948 result
= pim_msdp_mg_del(pim
, mg
);
7950 case PIM_MSDP_ERR_NONE
:
7952 case PIM_MSDP_ERR_NO_MG
:
7953 vty_out(vty
, "%% mesh-group does not exist\n");
7956 vty_out(vty
, "%% mesh-group source del failed\n");
7959 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7962 DEFUN (no_ip_msdp_mesh_group_source
,
7963 no_ip_msdp_mesh_group_source_cmd
,
7964 "no ip msdp mesh-group WORD source [A.B.C.D]",
7968 "Delete MSDP mesh-group source\n"
7970 "mesh group source\n"
7971 "mesh group local address\n")
7973 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7975 return ip_no_msdp_mesh_group_cmd_worker(pim
, vty
, argv
[6]->arg
);
7977 return ip_no_msdp_mesh_group_source_cmd_worker(pim
, vty
,
7981 static void print_empty_json_obj(struct vty
*vty
)
7984 json
= json_object_new_object();
7985 vty_out(vty
, "%s\n",
7986 json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
));
7987 json_object_free(json
);
7990 static void ip_msdp_show_mesh_group(struct pim_instance
*pim
, struct vty
*vty
,
7993 struct listnode
*mbrnode
;
7994 struct pim_msdp_mg_mbr
*mbr
;
7995 struct pim_msdp_mg
*mg
= pim
->msdp
.mg
;
7996 char mbr_str
[INET_ADDRSTRLEN
];
7997 char src_str
[INET_ADDRSTRLEN
];
7998 char state_str
[PIM_MSDP_STATE_STRLEN
];
7999 enum pim_msdp_peer_state state
;
8000 json_object
*json
= NULL
;
8001 json_object
*json_mg_row
= NULL
;
8002 json_object
*json_members
= NULL
;
8003 json_object
*json_row
= NULL
;
8007 print_empty_json_obj(vty
);
8011 pim_inet4_dump("<source?>", mg
->src_ip
, src_str
, sizeof(src_str
));
8013 json
= json_object_new_object();
8014 /* currently there is only one mesh group but we should still
8016 * it a dict with mg-name as key */
8017 json_mg_row
= json_object_new_object();
8018 json_object_string_add(json_mg_row
, "name",
8019 mg
->mesh_group_name
);
8020 json_object_string_add(json_mg_row
, "source", src_str
);
8022 vty_out(vty
, "Mesh group : %s\n", mg
->mesh_group_name
);
8023 vty_out(vty
, " Source : %s\n", src_str
);
8024 vty_out(vty
, " Member State\n");
8027 for (ALL_LIST_ELEMENTS_RO(mg
->mbr_list
, mbrnode
, mbr
)) {
8028 pim_inet4_dump("<mbr?>", mbr
->mbr_ip
, mbr_str
, sizeof(mbr_str
));
8030 state
= mbr
->mp
->state
;
8032 state
= PIM_MSDP_DISABLED
;
8034 pim_msdp_state_dump(state
, state_str
, sizeof(state_str
));
8036 json_row
= json_object_new_object();
8037 json_object_string_add(json_row
, "member", mbr_str
);
8038 json_object_string_add(json_row
, "state", state_str
);
8039 if (!json_members
) {
8040 json_members
= json_object_new_object();
8041 json_object_object_add(json_mg_row
, "members",
8044 json_object_object_add(json_members
, mbr_str
, json_row
);
8046 vty_out(vty
, " %-15s %11s\n", mbr_str
, state_str
);
8051 json_object_object_add(json
, mg
->mesh_group_name
, json_mg_row
);
8052 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8053 json
, JSON_C_TO_STRING_PRETTY
));
8054 json_object_free(json
);
8058 DEFUN (show_ip_msdp_mesh_group
,
8059 show_ip_msdp_mesh_group_cmd
,
8060 "show ip msdp [vrf NAME] mesh-group [json]",
8065 "MSDP mesh-group information\n"
8068 bool uj
= use_json(argc
, argv
);
8070 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
8075 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
8080 DEFUN (show_ip_msdp_mesh_group_vrf_all
,
8081 show_ip_msdp_mesh_group_vrf_all_cmd
,
8082 "show ip msdp vrf all mesh-group [json]",
8087 "MSDP mesh-group information\n"
8090 bool uj
= use_json(argc
, argv
);
8096 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
8100 vty_out(vty
, " \"%s\": ", vrf
->name
);
8103 vty_out(vty
, "VRF: %s\n", vrf
->name
);
8104 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
8107 vty_out(vty
, "}\n");
8112 static void ip_msdp_show_peers(struct pim_instance
*pim
, struct vty
*vty
,
8115 struct listnode
*mpnode
;
8116 struct pim_msdp_peer
*mp
;
8117 char peer_str
[INET_ADDRSTRLEN
];
8118 char local_str
[INET_ADDRSTRLEN
];
8119 char state_str
[PIM_MSDP_STATE_STRLEN
];
8120 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
8122 json_object
*json
= NULL
;
8123 json_object
*json_row
= NULL
;
8127 json
= json_object_new_object();
8130 "Peer Local State Uptime SaCnt\n");
8133 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
8134 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
8135 now
= pim_time_monotonic_sec();
8136 pim_time_uptime(timebuf
, sizeof(timebuf
),
8139 strcpy(timebuf
, "-");
8141 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
8142 pim_inet4_dump("<local?>", mp
->local
, local_str
,
8144 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
8146 json_row
= json_object_new_object();
8147 json_object_string_add(json_row
, "peer", peer_str
);
8148 json_object_string_add(json_row
, "local", local_str
);
8149 json_object_string_add(json_row
, "state", state_str
);
8150 json_object_string_add(json_row
, "upTime", timebuf
);
8151 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
8152 json_object_object_add(json
, peer_str
, json_row
);
8154 vty_out(vty
, "%-15s %15s %11s %8s %6d\n", peer_str
,
8155 local_str
, state_str
, timebuf
, mp
->sa_cnt
);
8160 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8161 json
, JSON_C_TO_STRING_PRETTY
));
8162 json_object_free(json
);
8166 static void ip_msdp_show_peers_detail(struct pim_instance
*pim
, struct vty
*vty
,
8167 const char *peer
, bool uj
)
8169 struct listnode
*mpnode
;
8170 struct pim_msdp_peer
*mp
;
8171 char peer_str
[INET_ADDRSTRLEN
];
8172 char local_str
[INET_ADDRSTRLEN
];
8173 char state_str
[PIM_MSDP_STATE_STRLEN
];
8174 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
8175 char katimer
[PIM_MSDP_TIMER_STRLEN
];
8176 char crtimer
[PIM_MSDP_TIMER_STRLEN
];
8177 char holdtimer
[PIM_MSDP_TIMER_STRLEN
];
8179 json_object
*json
= NULL
;
8180 json_object
*json_row
= NULL
;
8183 json
= json_object_new_object();
8186 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
8187 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
8188 if (strcmp(peer
, "detail") && strcmp(peer
, peer_str
))
8191 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
8192 now
= pim_time_monotonic_sec();
8193 pim_time_uptime(timebuf
, sizeof(timebuf
),
8196 strcpy(timebuf
, "-");
8198 pim_inet4_dump("<local?>", mp
->local
, local_str
,
8200 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
8201 pim_time_timer_to_hhmmss(katimer
, sizeof(katimer
),
8203 pim_time_timer_to_hhmmss(crtimer
, sizeof(crtimer
),
8205 pim_time_timer_to_hhmmss(holdtimer
, sizeof(holdtimer
),
8209 json_row
= json_object_new_object();
8210 json_object_string_add(json_row
, "peer", peer_str
);
8211 json_object_string_add(json_row
, "local", local_str
);
8212 json_object_string_add(json_row
, "meshGroupName",
8213 mp
->mesh_group_name
);
8214 json_object_string_add(json_row
, "state", state_str
);
8215 json_object_string_add(json_row
, "upTime", timebuf
);
8216 json_object_string_add(json_row
, "keepAliveTimer",
8218 json_object_string_add(json_row
, "connRetryTimer",
8220 json_object_string_add(json_row
, "holdTimer",
8222 json_object_string_add(json_row
, "lastReset",
8224 json_object_int_add(json_row
, "connAttempts",
8226 json_object_int_add(json_row
, "establishedChanges",
8228 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
8229 json_object_int_add(json_row
, "kaSent", mp
->ka_tx_cnt
);
8230 json_object_int_add(json_row
, "kaRcvd", mp
->ka_rx_cnt
);
8231 json_object_int_add(json_row
, "saSent", mp
->sa_tx_cnt
);
8232 json_object_int_add(json_row
, "saRcvd", mp
->sa_rx_cnt
);
8233 json_object_object_add(json
, peer_str
, json_row
);
8235 vty_out(vty
, "Peer : %s\n", peer_str
);
8236 vty_out(vty
, " Local : %s\n", local_str
);
8237 vty_out(vty
, " Mesh Group : %s\n",
8238 mp
->mesh_group_name
);
8239 vty_out(vty
, " State : %s\n", state_str
);
8240 vty_out(vty
, " Uptime : %s\n", timebuf
);
8242 vty_out(vty
, " Keepalive Timer : %s\n", katimer
);
8243 vty_out(vty
, " Conn Retry Timer : %s\n", crtimer
);
8244 vty_out(vty
, " Hold Timer : %s\n", holdtimer
);
8245 vty_out(vty
, " Last Reset : %s\n",
8247 vty_out(vty
, " Conn Attempts : %d\n",
8249 vty_out(vty
, " Established Changes : %d\n",
8251 vty_out(vty
, " SA Count : %d\n",
8253 vty_out(vty
, " Statistics :\n");
8256 vty_out(vty
, " Keepalives : %10d %10d\n",
8257 mp
->ka_tx_cnt
, mp
->ka_rx_cnt
);
8258 vty_out(vty
, " SAs : %10d %10d\n",
8259 mp
->sa_tx_cnt
, mp
->sa_rx_cnt
);
8265 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8266 json
, JSON_C_TO_STRING_PRETTY
));
8267 json_object_free(json
);
8271 DEFUN (show_ip_msdp_peer_detail
,
8272 show_ip_msdp_peer_detail_cmd
,
8273 "show ip msdp [vrf NAME] peer [detail|A.B.C.D] [json]",
8278 "MSDP peer information\n"
8283 bool uj
= use_json(argc
, argv
);
8285 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
8292 if (argv_find(argv
, argc
, "detail", &idx
))
8293 arg
= argv
[idx
]->text
;
8294 else if (argv_find(argv
, argc
, "A.B.C.D", &idx
))
8295 arg
= argv
[idx
]->arg
;
8298 ip_msdp_show_peers_detail(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
8300 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
8305 DEFUN (show_ip_msdp_peer_detail_vrf_all
,
8306 show_ip_msdp_peer_detail_vrf_all_cmd
,
8307 "show ip msdp vrf all peer [detail|A.B.C.D] [json]",
8312 "MSDP peer information\n"
8318 bool uj
= use_json(argc
, argv
);
8324 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
8328 vty_out(vty
, " \"%s\": ", vrf
->name
);
8331 vty_out(vty
, "VRF: %s\n", vrf
->name
);
8332 if (argv_find(argv
, argc
, "detail", &idx
)
8333 || argv_find(argv
, argc
, "A.B.C.D", &idx
))
8334 ip_msdp_show_peers_detail(vrf
->info
, vty
,
8335 argv
[idx
]->arg
, uj
);
8337 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
8340 vty_out(vty
, "}\n");
8345 static void ip_msdp_show_sa(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
8347 struct listnode
*sanode
;
8348 struct pim_msdp_sa
*sa
;
8349 char src_str
[INET_ADDRSTRLEN
];
8350 char grp_str
[INET_ADDRSTRLEN
];
8351 char rp_str
[INET_ADDRSTRLEN
];
8352 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
8356 json_object
*json
= NULL
;
8357 json_object
*json_group
= NULL
;
8358 json_object
*json_row
= NULL
;
8361 json
= json_object_new_object();
8364 "Source Group RP Local SPT Uptime\n");
8367 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
8368 now
= pim_time_monotonic_sec();
8369 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
8370 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
8371 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
8372 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
8373 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
8375 strcpy(spt_str
, "yes");
8377 strcpy(spt_str
, "no");
8380 strcpy(rp_str
, "-");
8381 strcpy(spt_str
, "-");
8383 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
8384 strcpy(local_str
, "yes");
8386 strcpy(local_str
, "no");
8389 json_object_object_get_ex(json
, grp_str
, &json_group
);
8392 json_group
= json_object_new_object();
8393 json_object_object_add(json
, grp_str
,
8397 json_row
= json_object_new_object();
8398 json_object_string_add(json_row
, "source", src_str
);
8399 json_object_string_add(json_row
, "group", grp_str
);
8400 json_object_string_add(json_row
, "rp", rp_str
);
8401 json_object_string_add(json_row
, "local", local_str
);
8402 json_object_string_add(json_row
, "sptSetup", spt_str
);
8403 json_object_string_add(json_row
, "upTime", timebuf
);
8404 json_object_object_add(json_group
, src_str
, json_row
);
8406 vty_out(vty
, "%-15s %15s %15s %5c %3c %8s\n",
8407 src_str
, grp_str
, rp_str
, local_str
[0],
8408 spt_str
[0], timebuf
);
8413 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8414 json
, JSON_C_TO_STRING_PRETTY
));
8415 json_object_free(json
);
8419 static void ip_msdp_show_sa_entry_detail(struct pim_msdp_sa
*sa
,
8420 const char *src_str
,
8421 const char *grp_str
, struct vty
*vty
,
8422 bool uj
, json_object
*json
)
8424 char rp_str
[INET_ADDRSTRLEN
];
8425 char peer_str
[INET_ADDRSTRLEN
];
8426 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
8429 char statetimer
[PIM_MSDP_TIMER_STRLEN
];
8431 json_object
*json_group
= NULL
;
8432 json_object
*json_row
= NULL
;
8434 now
= pim_time_monotonic_sec();
8435 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
8436 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
8437 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
8438 pim_inet4_dump("<peer?>", sa
->peer
, peer_str
, sizeof(peer_str
));
8440 strcpy(spt_str
, "yes");
8442 strcpy(spt_str
, "no");
8445 strcpy(rp_str
, "-");
8446 strcpy(peer_str
, "-");
8447 strcpy(spt_str
, "-");
8449 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
8450 strcpy(local_str
, "yes");
8452 strcpy(local_str
, "no");
8454 pim_time_timer_to_hhmmss(statetimer
, sizeof(statetimer
),
8455 sa
->sa_state_timer
);
8457 json_object_object_get_ex(json
, grp_str
, &json_group
);
8460 json_group
= json_object_new_object();
8461 json_object_object_add(json
, grp_str
, json_group
);
8464 json_row
= json_object_new_object();
8465 json_object_string_add(json_row
, "source", src_str
);
8466 json_object_string_add(json_row
, "group", grp_str
);
8467 json_object_string_add(json_row
, "rp", rp_str
);
8468 json_object_string_add(json_row
, "local", local_str
);
8469 json_object_string_add(json_row
, "sptSetup", spt_str
);
8470 json_object_string_add(json_row
, "upTime", timebuf
);
8471 json_object_string_add(json_row
, "stateTimer", statetimer
);
8472 json_object_object_add(json_group
, src_str
, json_row
);
8474 vty_out(vty
, "SA : %s\n", sa
->sg_str
);
8475 vty_out(vty
, " RP : %s\n", rp_str
);
8476 vty_out(vty
, " Peer : %s\n", peer_str
);
8477 vty_out(vty
, " Local : %s\n", local_str
);
8478 vty_out(vty
, " SPT Setup : %s\n", spt_str
);
8479 vty_out(vty
, " Uptime : %s\n", timebuf
);
8480 vty_out(vty
, " State Timer : %s\n", statetimer
);
8485 static void ip_msdp_show_sa_detail(struct pim_instance
*pim
, struct vty
*vty
,
8488 struct listnode
*sanode
;
8489 struct pim_msdp_sa
*sa
;
8490 char src_str
[INET_ADDRSTRLEN
];
8491 char grp_str
[INET_ADDRSTRLEN
];
8492 json_object
*json
= NULL
;
8495 json
= json_object_new_object();
8498 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
8499 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
8500 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
8501 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
, uj
,
8506 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8507 json
, JSON_C_TO_STRING_PRETTY
));
8508 json_object_free(json
);
8512 DEFUN (show_ip_msdp_sa_detail
,
8513 show_ip_msdp_sa_detail_cmd
,
8514 "show ip msdp [vrf NAME] sa detail [json]",
8519 "MSDP active-source information\n"
8523 bool uj
= use_json(argc
, argv
);
8525 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
8530 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
8535 DEFUN (show_ip_msdp_sa_detail_vrf_all
,
8536 show_ip_msdp_sa_detail_vrf_all_cmd
,
8537 "show ip msdp vrf all sa detail [json]",
8542 "MSDP active-source information\n"
8546 bool uj
= use_json(argc
, argv
);
8552 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
8556 vty_out(vty
, " \"%s\": ", vrf
->name
);
8559 vty_out(vty
, "VRF: %s\n", vrf
->name
);
8560 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
8563 vty_out(vty
, "}\n");
8568 static void ip_msdp_show_sa_addr(struct pim_instance
*pim
, struct vty
*vty
,
8569 const char *addr
, bool uj
)
8571 struct listnode
*sanode
;
8572 struct pim_msdp_sa
*sa
;
8573 char src_str
[INET_ADDRSTRLEN
];
8574 char grp_str
[INET_ADDRSTRLEN
];
8575 json_object
*json
= NULL
;
8578 json
= json_object_new_object();
8581 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
8582 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
8583 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
8584 if (!strcmp(addr
, src_str
) || !strcmp(addr
, grp_str
)) {
8585 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
8591 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8592 json
, JSON_C_TO_STRING_PRETTY
));
8593 json_object_free(json
);
8597 static void ip_msdp_show_sa_sg(struct pim_instance
*pim
, struct vty
*vty
,
8598 const char *src
, const char *grp
, bool uj
)
8600 struct listnode
*sanode
;
8601 struct pim_msdp_sa
*sa
;
8602 char src_str
[INET_ADDRSTRLEN
];
8603 char grp_str
[INET_ADDRSTRLEN
];
8604 json_object
*json
= NULL
;
8607 json
= json_object_new_object();
8610 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
8611 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
8612 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
8613 if (!strcmp(src
, src_str
) && !strcmp(grp
, grp_str
)) {
8614 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
8620 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8621 json
, JSON_C_TO_STRING_PRETTY
));
8622 json_object_free(json
);
8626 DEFUN (show_ip_msdp_sa_sg
,
8627 show_ip_msdp_sa_sg_cmd
,
8628 "show ip msdp [vrf NAME] sa [A.B.C.D [A.B.C.D]] [json]",
8633 "MSDP active-source information\n"
8634 "source or group ip\n"
8638 bool uj
= use_json(argc
, argv
);
8642 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
8647 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
8649 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
8653 if (src_ip
&& grp_ip
)
8654 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
8656 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
8658 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
8663 DEFUN (show_ip_msdp_sa_sg_vrf_all
,
8664 show_ip_msdp_sa_sg_vrf_all_cmd
,
8665 "show ip msdp vrf all sa [A.B.C.D [A.B.C.D]] [json]",
8670 "MSDP active-source information\n"
8671 "source or group ip\n"
8675 bool uj
= use_json(argc
, argv
);
8680 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
8682 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
8688 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
8692 vty_out(vty
, " \"%s\": ", vrf
->name
);
8695 vty_out(vty
, "VRF: %s\n", vrf
->name
);
8697 if (src_ip
&& grp_ip
)
8698 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
8700 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
8702 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
8705 vty_out(vty
, "}\n");
8710 void pim_cmd_init(void)
8712 install_node(&interface_node
,
8713 pim_interface_config_write
); /* INTERFACE_NODE */
8716 install_node(&debug_node
, pim_debug_config_write
);
8718 install_element(ENABLE_NODE
, &pim_test_sg_keepalive_cmd
);
8720 install_element(CONFIG_NODE
, &ip_pim_rp_cmd
);
8721 install_element(VRF_NODE
, &ip_pim_rp_cmd
);
8722 install_element(CONFIG_NODE
, &no_ip_pim_rp_cmd
);
8723 install_element(VRF_NODE
, &no_ip_pim_rp_cmd
);
8724 install_element(CONFIG_NODE
, &ip_pim_rp_prefix_list_cmd
);
8725 install_element(VRF_NODE
, &ip_pim_rp_prefix_list_cmd
);
8726 install_element(CONFIG_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
8727 install_element(VRF_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
8728 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
8729 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
8730 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
8731 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
8732 install_element(CONFIG_NODE
, &ip_pim_ssm_prefix_list_cmd
);
8733 install_element(VRF_NODE
, &ip_pim_ssm_prefix_list_cmd
);
8734 install_element(CONFIG_NODE
, &ip_pim_register_suppress_cmd
);
8735 install_element(VRF_NODE
, &ip_pim_register_suppress_cmd
);
8736 install_element(CONFIG_NODE
, &no_ip_pim_register_suppress_cmd
);
8737 install_element(VRF_NODE
, &no_ip_pim_register_suppress_cmd
);
8738 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
8739 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
8740 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
8741 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
8742 install_element(CONFIG_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
8743 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
8744 install_element(CONFIG_NODE
,
8745 &no_ip_pim_spt_switchover_infinity_plist_cmd
);
8746 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_plist_cmd
);
8747 install_element(CONFIG_NODE
, &ip_pim_joinprune_time_cmd
);
8748 install_element(VRF_NODE
, &ip_pim_joinprune_time_cmd
);
8749 install_element(CONFIG_NODE
, &no_ip_pim_joinprune_time_cmd
);
8750 install_element(VRF_NODE
, &no_ip_pim_joinprune_time_cmd
);
8751 install_element(CONFIG_NODE
, &ip_pim_keep_alive_cmd
);
8752 install_element(VRF_NODE
, &ip_pim_keep_alive_cmd
);
8753 install_element(CONFIG_NODE
, &ip_pim_rp_keep_alive_cmd
);
8754 install_element(VRF_NODE
, &ip_pim_rp_keep_alive_cmd
);
8755 install_element(CONFIG_NODE
, &no_ip_pim_keep_alive_cmd
);
8756 install_element(VRF_NODE
, &no_ip_pim_keep_alive_cmd
);
8757 install_element(CONFIG_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
8758 install_element(VRF_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
8759 install_element(CONFIG_NODE
, &ip_pim_packets_cmd
);
8760 install_element(VRF_NODE
, &ip_pim_packets_cmd
);
8761 install_element(CONFIG_NODE
, &no_ip_pim_packets_cmd
);
8762 install_element(VRF_NODE
, &no_ip_pim_packets_cmd
);
8763 install_element(CONFIG_NODE
, &ip_pim_v6_secondary_cmd
);
8764 install_element(VRF_NODE
, &ip_pim_v6_secondary_cmd
);
8765 install_element(CONFIG_NODE
, &no_ip_pim_v6_secondary_cmd
);
8766 install_element(VRF_NODE
, &no_ip_pim_v6_secondary_cmd
);
8767 install_element(CONFIG_NODE
, &ip_ssmpingd_cmd
);
8768 install_element(VRF_NODE
, &ip_ssmpingd_cmd
);
8769 install_element(CONFIG_NODE
, &no_ip_ssmpingd_cmd
);
8770 install_element(VRF_NODE
, &no_ip_ssmpingd_cmd
);
8771 install_element(CONFIG_NODE
, &ip_msdp_peer_cmd
);
8772 install_element(VRF_NODE
, &ip_msdp_peer_cmd
);
8773 install_element(CONFIG_NODE
, &no_ip_msdp_peer_cmd
);
8774 install_element(VRF_NODE
, &no_ip_msdp_peer_cmd
);
8775 install_element(CONFIG_NODE
, &ip_pim_ecmp_cmd
);
8776 install_element(VRF_NODE
, &ip_pim_ecmp_cmd
);
8777 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_cmd
);
8778 install_element(VRF_NODE
, &no_ip_pim_ecmp_cmd
);
8779 install_element(CONFIG_NODE
, &ip_pim_ecmp_rebalance_cmd
);
8780 install_element(VRF_NODE
, &ip_pim_ecmp_rebalance_cmd
);
8781 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
8782 install_element(VRF_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
8784 install_element(INTERFACE_NODE
, &interface_ip_igmp_cmd
);
8785 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_cmd
);
8786 install_element(INTERFACE_NODE
, &interface_ip_igmp_join_cmd
);
8787 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_join_cmd
);
8788 install_element(INTERFACE_NODE
, &interface_ip_igmp_version_cmd
);
8789 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_version_cmd
);
8790 install_element(INTERFACE_NODE
, &interface_ip_igmp_query_interval_cmd
);
8791 install_element(INTERFACE_NODE
,
8792 &interface_no_ip_igmp_query_interval_cmd
);
8793 install_element(INTERFACE_NODE
,
8794 &interface_ip_igmp_query_max_response_time_cmd
);
8795 install_element(INTERFACE_NODE
,
8796 &interface_no_ip_igmp_query_max_response_time_cmd
);
8797 install_element(INTERFACE_NODE
,
8798 &interface_ip_igmp_query_max_response_time_dsec_cmd
);
8799 install_element(INTERFACE_NODE
,
8800 &interface_no_ip_igmp_query_max_response_time_dsec_cmd
);
8801 install_element(INTERFACE_NODE
, &interface_ip_pim_activeactive_cmd
);
8802 install_element(INTERFACE_NODE
, &interface_ip_pim_ssm_cmd
);
8803 install_element(INTERFACE_NODE
, &interface_no_ip_pim_ssm_cmd
);
8804 install_element(INTERFACE_NODE
, &interface_ip_pim_sm_cmd
);
8805 install_element(INTERFACE_NODE
, &interface_no_ip_pim_sm_cmd
);
8806 install_element(INTERFACE_NODE
, &interface_ip_pim_cmd
);
8807 install_element(INTERFACE_NODE
, &interface_no_ip_pim_cmd
);
8808 install_element(INTERFACE_NODE
, &interface_ip_pim_drprio_cmd
);
8809 install_element(INTERFACE_NODE
, &interface_no_ip_pim_drprio_cmd
);
8810 install_element(INTERFACE_NODE
, &interface_ip_pim_hello_cmd
);
8811 install_element(INTERFACE_NODE
, &interface_no_ip_pim_hello_cmd
);
8812 install_element(INTERFACE_NODE
, &interface_ip_pim_boundary_oil_cmd
);
8813 install_element(INTERFACE_NODE
, &interface_no_ip_pim_boundary_oil_cmd
);
8815 // Static mroutes NEB
8816 install_element(INTERFACE_NODE
, &interface_ip_mroute_cmd
);
8817 install_element(INTERFACE_NODE
, &interface_ip_mroute_source_cmd
);
8818 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_cmd
);
8819 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_source_cmd
);
8821 install_element(VIEW_NODE
, &show_ip_igmp_interface_cmd
);
8822 install_element(VIEW_NODE
, &show_ip_igmp_interface_vrf_all_cmd
);
8823 install_element(VIEW_NODE
, &show_ip_igmp_join_cmd
);
8824 install_element(VIEW_NODE
, &show_ip_igmp_join_vrf_all_cmd
);
8825 install_element(VIEW_NODE
, &show_ip_igmp_groups_cmd
);
8826 install_element(VIEW_NODE
, &show_ip_igmp_groups_vrf_all_cmd
);
8827 install_element(VIEW_NODE
, &show_ip_igmp_groups_retransmissions_cmd
);
8828 install_element(VIEW_NODE
, &show_ip_igmp_sources_cmd
);
8829 install_element(VIEW_NODE
, &show_ip_igmp_sources_retransmissions_cmd
);
8830 install_element(VIEW_NODE
, &show_ip_igmp_statistics_cmd
);
8831 install_element(VIEW_NODE
, &show_ip_pim_assert_cmd
);
8832 install_element(VIEW_NODE
, &show_ip_pim_assert_internal_cmd
);
8833 install_element(VIEW_NODE
, &show_ip_pim_assert_metric_cmd
);
8834 install_element(VIEW_NODE
, &show_ip_pim_assert_winner_metric_cmd
);
8835 install_element(VIEW_NODE
, &show_ip_pim_interface_traffic_cmd
);
8836 install_element(VIEW_NODE
, &show_ip_pim_interface_cmd
);
8837 install_element(VIEW_NODE
, &show_ip_pim_interface_vrf_all_cmd
);
8838 install_element(VIEW_NODE
, &show_ip_pim_join_cmd
);
8839 install_element(VIEW_NODE
, &show_ip_pim_join_vrf_all_cmd
);
8840 install_element(VIEW_NODE
, &show_ip_pim_local_membership_cmd
);
8841 install_element(VIEW_NODE
, &show_ip_pim_neighbor_cmd
);
8842 install_element(VIEW_NODE
, &show_ip_pim_neighbor_vrf_all_cmd
);
8843 install_element(VIEW_NODE
, &show_ip_pim_rpf_cmd
);
8844 install_element(VIEW_NODE
, &show_ip_pim_rpf_vrf_all_cmd
);
8845 install_element(VIEW_NODE
, &show_ip_pim_secondary_cmd
);
8846 install_element(VIEW_NODE
, &show_ip_pim_state_cmd
);
8847 install_element(VIEW_NODE
, &show_ip_pim_state_vrf_all_cmd
);
8848 install_element(VIEW_NODE
, &show_ip_pim_upstream_cmd
);
8849 install_element(VIEW_NODE
, &show_ip_pim_upstream_vrf_all_cmd
);
8850 install_element(VIEW_NODE
, &show_ip_pim_upstream_join_desired_cmd
);
8851 install_element(VIEW_NODE
, &show_ip_pim_upstream_rpf_cmd
);
8852 install_element(VIEW_NODE
, &show_ip_pim_rp_cmd
);
8853 install_element(VIEW_NODE
, &show_ip_pim_rp_vrf_all_cmd
);
8854 install_element(VIEW_NODE
, &show_ip_multicast_cmd
);
8855 install_element(VIEW_NODE
, &show_ip_multicast_vrf_all_cmd
);
8856 install_element(VIEW_NODE
, &show_ip_mroute_cmd
);
8857 install_element(VIEW_NODE
, &show_ip_mroute_vrf_all_cmd
);
8858 install_element(VIEW_NODE
, &show_ip_mroute_count_cmd
);
8859 install_element(VIEW_NODE
, &show_ip_mroute_count_vrf_all_cmd
);
8860 install_element(VIEW_NODE
, &show_ip_rib_cmd
);
8861 install_element(VIEW_NODE
, &show_ip_ssmpingd_cmd
);
8862 install_element(VIEW_NODE
, &show_debugging_pim_cmd
);
8863 install_element(VIEW_NODE
, &show_ip_pim_nexthop_cmd
);
8864 install_element(VIEW_NODE
, &show_ip_pim_nexthop_lookup_cmd
);
8866 install_element(ENABLE_NODE
, &clear_ip_interfaces_cmd
);
8867 install_element(ENABLE_NODE
, &clear_ip_igmp_interfaces_cmd
);
8868 install_element(ENABLE_NODE
, &clear_ip_mroute_cmd
);
8869 install_element(ENABLE_NODE
, &clear_ip_pim_interfaces_cmd
);
8870 install_element(ENABLE_NODE
, &clear_ip_pim_interface_traffic_cmd
);
8871 install_element(ENABLE_NODE
, &clear_ip_pim_oil_cmd
);
8873 install_element(ENABLE_NODE
, &debug_igmp_cmd
);
8874 install_element(ENABLE_NODE
, &no_debug_igmp_cmd
);
8875 install_element(ENABLE_NODE
, &debug_igmp_events_cmd
);
8876 install_element(ENABLE_NODE
, &no_debug_igmp_events_cmd
);
8877 install_element(ENABLE_NODE
, &debug_igmp_packets_cmd
);
8878 install_element(ENABLE_NODE
, &no_debug_igmp_packets_cmd
);
8879 install_element(ENABLE_NODE
, &debug_igmp_trace_cmd
);
8880 install_element(ENABLE_NODE
, &no_debug_igmp_trace_cmd
);
8881 install_element(ENABLE_NODE
, &debug_mroute_cmd
);
8882 install_element(ENABLE_NODE
, &debug_mroute_detail_cmd
);
8883 install_element(ENABLE_NODE
, &no_debug_mroute_cmd
);
8884 install_element(ENABLE_NODE
, &no_debug_mroute_detail_cmd
);
8885 install_element(ENABLE_NODE
, &debug_pim_static_cmd
);
8886 install_element(ENABLE_NODE
, &no_debug_pim_static_cmd
);
8887 install_element(ENABLE_NODE
, &debug_pim_cmd
);
8888 install_element(ENABLE_NODE
, &no_debug_pim_cmd
);
8889 install_element(ENABLE_NODE
, &debug_pim_nht_cmd
);
8890 install_element(ENABLE_NODE
, &no_debug_pim_nht_cmd
);
8891 install_element(ENABLE_NODE
, &debug_pim_nht_rp_cmd
);
8892 install_element(ENABLE_NODE
, &no_debug_pim_nht_rp_cmd
);
8893 install_element(ENABLE_NODE
, &debug_pim_events_cmd
);
8894 install_element(ENABLE_NODE
, &no_debug_pim_events_cmd
);
8895 install_element(ENABLE_NODE
, &debug_pim_packets_cmd
);
8896 install_element(ENABLE_NODE
, &no_debug_pim_packets_cmd
);
8897 install_element(ENABLE_NODE
, &debug_pim_packetdump_send_cmd
);
8898 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_send_cmd
);
8899 install_element(ENABLE_NODE
, &debug_pim_packetdump_recv_cmd
);
8900 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_recv_cmd
);
8901 install_element(ENABLE_NODE
, &debug_pim_trace_cmd
);
8902 install_element(ENABLE_NODE
, &no_debug_pim_trace_cmd
);
8903 install_element(ENABLE_NODE
, &debug_pim_trace_detail_cmd
);
8904 install_element(ENABLE_NODE
, &no_debug_pim_trace_detail_cmd
);
8905 install_element(ENABLE_NODE
, &debug_ssmpingd_cmd
);
8906 install_element(ENABLE_NODE
, &no_debug_ssmpingd_cmd
);
8907 install_element(ENABLE_NODE
, &debug_pim_zebra_cmd
);
8908 install_element(ENABLE_NODE
, &no_debug_pim_zebra_cmd
);
8909 install_element(ENABLE_NODE
, &debug_msdp_cmd
);
8910 install_element(ENABLE_NODE
, &no_debug_msdp_cmd
);
8911 install_element(ENABLE_NODE
, &debug_msdp_events_cmd
);
8912 install_element(ENABLE_NODE
, &no_debug_msdp_events_cmd
);
8913 install_element(ENABLE_NODE
, &debug_msdp_packets_cmd
);
8914 install_element(ENABLE_NODE
, &no_debug_msdp_packets_cmd
);
8915 install_element(ENABLE_NODE
, &debug_mtrace_cmd
);
8916 install_element(ENABLE_NODE
, &no_debug_mtrace_cmd
);
8918 install_element(CONFIG_NODE
, &debug_igmp_cmd
);
8919 install_element(CONFIG_NODE
, &no_debug_igmp_cmd
);
8920 install_element(CONFIG_NODE
, &debug_igmp_events_cmd
);
8921 install_element(CONFIG_NODE
, &no_debug_igmp_events_cmd
);
8922 install_element(CONFIG_NODE
, &debug_igmp_packets_cmd
);
8923 install_element(CONFIG_NODE
, &no_debug_igmp_packets_cmd
);
8924 install_element(CONFIG_NODE
, &debug_igmp_trace_cmd
);
8925 install_element(CONFIG_NODE
, &no_debug_igmp_trace_cmd
);
8926 install_element(CONFIG_NODE
, &debug_mroute_cmd
);
8927 install_element(CONFIG_NODE
, &debug_mroute_detail_cmd
);
8928 install_element(CONFIG_NODE
, &no_debug_mroute_cmd
);
8929 install_element(CONFIG_NODE
, &no_debug_mroute_detail_cmd
);
8930 install_element(CONFIG_NODE
, &debug_pim_static_cmd
);
8931 install_element(CONFIG_NODE
, &no_debug_pim_static_cmd
);
8932 install_element(CONFIG_NODE
, &debug_pim_cmd
);
8933 install_element(CONFIG_NODE
, &no_debug_pim_cmd
);
8934 install_element(CONFIG_NODE
, &debug_pim_nht_cmd
);
8935 install_element(CONFIG_NODE
, &no_debug_pim_nht_cmd
);
8936 install_element(CONFIG_NODE
, &debug_pim_nht_rp_cmd
);
8937 install_element(CONFIG_NODE
, &no_debug_pim_nht_rp_cmd
);
8938 install_element(CONFIG_NODE
, &debug_pim_events_cmd
);
8939 install_element(CONFIG_NODE
, &no_debug_pim_events_cmd
);
8940 install_element(CONFIG_NODE
, &debug_pim_packets_cmd
);
8941 install_element(CONFIG_NODE
, &no_debug_pim_packets_cmd
);
8942 install_element(CONFIG_NODE
, &debug_pim_trace_cmd
);
8943 install_element(CONFIG_NODE
, &no_debug_pim_trace_cmd
);
8944 install_element(CONFIG_NODE
, &debug_pim_trace_detail_cmd
);
8945 install_element(CONFIG_NODE
, &no_debug_pim_trace_detail_cmd
);
8946 install_element(CONFIG_NODE
, &debug_ssmpingd_cmd
);
8947 install_element(CONFIG_NODE
, &no_debug_ssmpingd_cmd
);
8948 install_element(CONFIG_NODE
, &debug_pim_zebra_cmd
);
8949 install_element(CONFIG_NODE
, &no_debug_pim_zebra_cmd
);
8950 install_element(CONFIG_NODE
, &debug_msdp_cmd
);
8951 install_element(CONFIG_NODE
, &no_debug_msdp_cmd
);
8952 install_element(CONFIG_NODE
, &debug_msdp_events_cmd
);
8953 install_element(CONFIG_NODE
, &no_debug_msdp_events_cmd
);
8954 install_element(CONFIG_NODE
, &debug_msdp_packets_cmd
);
8955 install_element(CONFIG_NODE
, &no_debug_msdp_packets_cmd
);
8956 install_element(CONFIG_NODE
, &debug_mtrace_cmd
);
8957 install_element(CONFIG_NODE
, &no_debug_mtrace_cmd
);
8959 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_member_cmd
);
8960 install_element(VRF_NODE
, &ip_msdp_mesh_group_member_cmd
);
8961 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
8962 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
8963 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_source_cmd
);
8964 install_element(VRF_NODE
, &ip_msdp_mesh_group_source_cmd
);
8965 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
8966 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
8967 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_cmd
);
8968 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_vrf_all_cmd
);
8969 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_cmd
);
8970 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_vrf_all_cmd
);
8971 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_cmd
);
8972 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_vrf_all_cmd
);
8973 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_cmd
);
8974 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_vrf_all_cmd
);
8975 install_element(VIEW_NODE
, &show_ip_pim_ssm_range_cmd
);
8976 install_element(VIEW_NODE
, &show_ip_pim_group_type_cmd
);
8977 install_element(INTERFACE_NODE
, &interface_pim_use_source_cmd
);
8978 install_element(INTERFACE_NODE
, &interface_no_pim_use_source_cmd
);
8979 /* Install BFD command */
8980 install_element(INTERFACE_NODE
, &ip_pim_bfd_cmd
);
8981 install_element(INTERFACE_NODE
, &ip_pim_bfd_param_cmd
);
8982 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_cmd
);
8984 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_param_cmd
);
8985 #endif /* !HAVE_BFDD */