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
16 along with this program; see the file COPYING; if not, write to the
17 Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
33 #include "pim_mroute.h"
35 #include "pim_iface.h"
37 #include "pim_mroute.h"
40 #include "pim_igmpv3.h"
45 #include "pim_neighbor.h"
47 #include "pim_ifchannel.h"
48 #include "pim_hello.h"
50 #include "pim_upstream.h"
52 #include "pim_macro.h"
53 #include "pim_ssmpingd.h"
54 #include "pim_zebra.h"
55 #include "pim_static.h"
57 #include "pim_zlookup.h"
62 static struct cmd_node pim_global_node
= {
63 PIM_NODE
, "", 1 /* vtysh ? yes */
66 static struct cmd_node interface_node
= {
67 INTERFACE_NODE
, "%s(config-if)# ", 1 /* vtysh ? yes */
70 static struct cmd_node debug_node
= {DEBUG_NODE
, "", 1};
72 static void pim_if_membership_clear(struct interface
*ifp
)
74 struct pim_interface
*pim_ifp
;
79 if (PIM_IF_TEST_PIM(pim_ifp
->options
)
80 && PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
84 pim_ifchannel_membership_clear(ifp
);
88 When PIM is disabled on interface, IGMPv3 local membership
89 information is not injected into PIM interface state.
91 The function pim_if_membership_refresh() fetches all IGMPv3 local
92 membership information into PIM. It is intented to be called
93 whenever PIM is enabled on the interface in order to collect missed
94 local membership information.
96 static void pim_if_membership_refresh(struct interface
*ifp
)
98 struct pim_interface
*pim_ifp
;
99 struct listnode
*sock_node
;
100 struct igmp_sock
*igmp
;
105 if (!PIM_IF_TEST_PIM(pim_ifp
->options
))
107 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
))
111 First clear off membership from all PIM (S,G) entries on the
115 pim_ifchannel_membership_clear(ifp
);
118 Then restore PIM (S,G) membership from all IGMPv3 (S,G) entries on
122 /* scan igmp sockets */
123 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
124 struct listnode
*grpnode
;
125 struct igmp_group
*grp
;
127 /* scan igmp groups */
128 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grpnode
,
130 struct listnode
*srcnode
;
131 struct igmp_source
*src
;
133 /* scan group sources */
134 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
,
137 if (IGMP_SOURCE_TEST_FORWARDING(
138 src
->source_flags
)) {
142 sizeof(struct prefix_sg
));
143 sg
.src
= src
->source_addr
;
144 sg
.grp
= grp
->group_addr
;
145 pim_ifchannel_local_membership_add(ifp
,
149 } /* scan group sources */
150 } /* scan igmp groups */
151 } /* scan igmp sockets */
154 Finally delete every PIM (S,G) entry lacking all state info
157 pim_ifchannel_delete_on_noinfo(ifp
);
160 static void pim_show_assert(struct vty
*vty
)
162 struct pim_interface
*pim_ifp
;
163 struct pim_ifchannel
*ch
;
164 struct listnode
*ch_node
;
165 struct in_addr ifaddr
;
168 now
= pim_time_monotonic_sec();
171 "Interface Address Source Group State Winner Uptime Timer%s",
174 for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list
, ch_node
, ch
)) {
175 char ch_src_str
[INET_ADDRSTRLEN
];
176 char ch_grp_str
[INET_ADDRSTRLEN
];
177 char winner_str
[INET_ADDRSTRLEN
];
181 pim_ifp
= ch
->interface
->info
;
186 ifaddr
= pim_ifp
->primary_address
;
188 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
,
190 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
,
192 pim_inet4_dump("<assrt_win?>", ch
->ifassert_winner
, winner_str
,
195 pim_time_uptime(uptime
, sizeof(uptime
),
196 now
- ch
->ifassert_creation
);
197 pim_time_timer_to_mmss(timer
, sizeof(timer
),
198 ch
->t_ifassert_timer
);
200 vty_out(vty
, "%-9s %-15s %-15s %-15s %-6s %-15s %-8s %-5s%s",
201 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
,
203 pim_ifchannel_ifassert_name(ch
->ifassert_state
),
204 winner_str
, uptime
, timer
, VTY_NEWLINE
);
205 } /* scan interface channels */
208 static void pim_show_assert_internal(struct vty
*vty
)
210 struct pim_interface
*pim_ifp
;
211 struct listnode
*ch_node
;
212 struct pim_ifchannel
*ch
;
213 struct in_addr ifaddr
;
217 "ECA: Evaluate CouldAssert%s"
218 "ATD: AssertTrackingDesired%s"
219 "eATD: Evaluate AssertTrackingDesired%s%s",
220 VTY_NEWLINE
, VTY_NEWLINE
, VTY_NEWLINE
, VTY_NEWLINE
,
224 "Interface Address Source Group CA eCA ATD eATD%s",
227 for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list
, ch_node
, ch
)) {
228 pim_ifp
= ch
->interface
->info
;
233 ifaddr
= pim_ifp
->primary_address
;
235 char ch_src_str
[INET_ADDRSTRLEN
];
236 char ch_grp_str
[INET_ADDRSTRLEN
];
238 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
,
240 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
,
242 vty_out(vty
, "%-9s %-15s %-15s %-15s %-3s %-3s %-3s %-4s%s",
243 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
,
245 PIM_IF_FLAG_TEST_COULD_ASSERT(ch
->flags
) ? "yes" : "no",
246 pim_macro_ch_could_assert_eval(ch
) ? "yes" : "no",
247 PIM_IF_FLAG_TEST_ASSERT_TRACKING_DESIRED(ch
->flags
)
250 pim_macro_assert_tracking_desired_eval(ch
) ? "yes"
253 } /* scan interface channels */
256 static void pim_show_assert_metric(struct vty
*vty
)
258 struct pim_interface
*pim_ifp
;
259 struct listnode
*ch_node
;
260 struct pim_ifchannel
*ch
;
261 struct in_addr ifaddr
;
264 "Interface Address Source Group RPT Pref Metric Address %s",
267 for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list
, ch_node
, ch
)) {
268 pim_ifp
= ch
->interface
->info
;
273 ifaddr
= pim_ifp
->primary_address
;
275 char ch_src_str
[INET_ADDRSTRLEN
];
276 char ch_grp_str
[INET_ADDRSTRLEN
];
277 char addr_str
[INET_ADDRSTRLEN
];
278 struct pim_assert_metric am
;
280 am
= pim_macro_spt_assert_metric(&ch
->upstream
->rpf
,
281 pim_ifp
->primary_address
);
283 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
,
285 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
,
287 pim_inet4_dump("<addr?>", am
.ip_address
, addr_str
,
290 vty_out(vty
, "%-9s %-15s %-15s %-15s %-3s %4u %6u %-15s%s",
291 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
,
292 ch_grp_str
, am
.rpt_bit_flag
? "yes" : "no",
293 am
.metric_preference
, am
.route_metric
, addr_str
,
295 } /* scan interface channels */
298 static void pim_show_assert_winner_metric(struct vty
*vty
)
300 struct pim_interface
*pim_ifp
;
301 struct listnode
*ch_node
;
302 struct pim_ifchannel
*ch
;
303 struct in_addr ifaddr
;
306 "Interface Address Source Group RPT Pref Metric Address %s",
309 for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list
, ch_node
, ch
)) {
310 pim_ifp
= ch
->interface
->info
;
315 ifaddr
= pim_ifp
->primary_address
;
317 char ch_src_str
[INET_ADDRSTRLEN
];
318 char ch_grp_str
[INET_ADDRSTRLEN
];
319 char addr_str
[INET_ADDRSTRLEN
];
320 struct pim_assert_metric
*am
;
324 am
= &ch
->ifassert_winner_metric
;
326 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
,
328 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
,
330 pim_inet4_dump("<addr?>", am
->ip_address
, addr_str
,
333 if (am
->metric_preference
== PIM_ASSERT_METRIC_PREFERENCE_MAX
)
334 snprintf(pref_str
, sizeof(pref_str
), "INFI");
336 snprintf(pref_str
, sizeof(pref_str
), "%4u",
337 am
->metric_preference
);
339 if (am
->route_metric
== PIM_ASSERT_ROUTE_METRIC_MAX
)
340 snprintf(metr_str
, sizeof(metr_str
), "INFI");
342 snprintf(metr_str
, sizeof(metr_str
), "%6u",
345 vty_out(vty
, "%-9s %-15s %-15s %-15s %-3s %-4s %-6s %-15s%s",
346 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
,
347 ch_grp_str
, am
->rpt_bit_flag
? "yes" : "no", pref_str
,
348 metr_str
, addr_str
, VTY_NEWLINE
);
349 } /* scan interface channels */
352 static void json_object_pim_ifp_add(struct json_object
*json
,
353 struct interface
*ifp
)
355 struct pim_interface
*pim_ifp
;
358 json_object_string_add(json
, "name", ifp
->name
);
359 json_object_string_add(json
, "state", if_is_up(ifp
) ? "up" : "down");
360 json_object_string_add(json
, "address",
361 inet_ntoa(pim_ifp
->primary_address
));
362 json_object_int_add(json
, "index", ifp
->ifindex
);
364 if (if_is_multicast(ifp
))
365 json_object_boolean_true_add(json
, "flagMulticast");
367 if (if_is_broadcast(ifp
))
368 json_object_boolean_true_add(json
, "flagBroadcast");
370 if (ifp
->flags
& IFF_ALLMULTI
)
371 json_object_boolean_true_add(json
, "flagAllMulticast");
373 if (ifp
->flags
& IFF_PROMISC
)
374 json_object_boolean_true_add(json
, "flagPromiscuous");
376 if (PIM_IF_IS_DELETED(ifp
))
377 json_object_boolean_true_add(json
, "flagDeleted");
379 if (pim_if_lan_delay_enabled(ifp
))
380 json_object_boolean_true_add(json
, "lanDelayEnabled");
383 static void pim_show_membership(struct vty
*vty
, u_char uj
)
385 struct pim_interface
*pim_ifp
;
386 struct listnode
*ch_node
;
387 struct pim_ifchannel
*ch
;
389 json_object
*json
= NULL
;
390 json_object
*json_iface
= NULL
;
391 json_object
*json_row
= NULL
;
392 json_object
*json_tmp
= NULL
;
394 json
= json_object_new_object();
396 for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list
, ch_node
, ch
)) {
398 pim_ifp
= ch
->interface
->info
;
403 char ch_src_str
[INET_ADDRSTRLEN
];
404 char ch_grp_str
[INET_ADDRSTRLEN
];
406 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
,
408 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
,
411 json_object_object_get_ex(json
, ch
->interface
->name
,
415 json_iface
= json_object_new_object();
416 json_object_pim_ifp_add(json_iface
, ch
->interface
);
417 json_object_object_add(json
, ch
->interface
->name
,
421 json_row
= json_object_new_object();
422 json_object_string_add(json_row
, "source", ch_src_str
);
423 json_object_string_add(json_row
, "group", ch_grp_str
);
424 json_object_string_add(
425 json_row
, "localMembership",
426 ch
->local_ifmembership
== PIM_IFMEMBERSHIP_NOINFO
429 json_object_object_add(json_iface
, ch_grp_str
, json_row
);
430 } /* scan interface channels */
433 vty_out(vty
, "%s%s", json_object_to_json_string_ext(
434 json
, JSON_C_TO_STRING_PRETTY
),
438 "Interface Address Source Group Membership%s",
442 * Example of the json data we are traversing
448 * "address":"10.1.20.1",
450 * "flagMulticast":true,
451 * "flagBroadcast":true,
452 * "lanDelayEnabled":true,
455 * "group":"226.10.10.10",
456 * "localMembership":"INCLUDE"
462 /* foreach interface */
463 json_object_object_foreach(json
, key
, val
)
466 /* Find all of the keys where the val is an object. In
468 * above the only one is 226.10.10.10
470 json_object_object_foreach(val
, if_field_key
,
473 type
= json_object_get_type(if_field_val
);
475 if (type
== json_type_object
) {
476 vty_out(vty
, "%-9s ", key
);
478 json_object_object_get_ex(
479 val
, "address", &json_tmp
);
480 vty_out(vty
, "%-15s ",
481 json_object_get_string(
484 json_object_object_get_ex(if_field_val
,
487 vty_out(vty
, "%-15s ",
488 json_object_get_string(
492 vty_out(vty
, "%-15s ", if_field_key
);
494 json_object_object_get_ex(
495 if_field_val
, "localMembership",
497 vty_out(vty
, "%-10s%s",
498 json_object_get_string(
506 json_object_free(json
);
509 static void pim_print_ifp_flags(struct vty
*vty
, struct interface
*ifp
,
512 vty_out(vty
, "Flags%s", VTY_NEWLINE
);
513 vty_out(vty
, "-----%s", VTY_NEWLINE
);
514 vty_out(vty
, "All Multicast : %s%s",
515 (ifp
->flags
& IFF_ALLMULTI
) ? "yes" : "no", VTY_NEWLINE
);
516 vty_out(vty
, "Broadcast : %s%s",
517 if_is_broadcast(ifp
) ? "yes" : "no", VTY_NEWLINE
);
518 vty_out(vty
, "Deleted : %s%s",
519 PIM_IF_IS_DELETED(ifp
) ? "yes" : "no", VTY_NEWLINE
);
520 vty_out(vty
, "Interface Index : %d%s", ifp
->ifindex
, VTY_NEWLINE
);
521 vty_out(vty
, "Multicast : %s%s",
522 if_is_multicast(ifp
) ? "yes" : "no", VTY_NEWLINE
);
523 vty_out(vty
, "Multicast Loop : %d%s", mloop
, VTY_NEWLINE
);
524 vty_out(vty
, "Promiscuous : %s%s",
525 (ifp
->flags
& IFF_PROMISC
) ? "yes" : "no", VTY_NEWLINE
);
526 vty_out(vty
, "%s", VTY_NEWLINE
);
527 vty_out(vty
, "%s", VTY_NEWLINE
);
530 static void igmp_show_interfaces(struct vty
*vty
, u_char uj
)
532 struct listnode
*node
;
533 struct interface
*ifp
;
535 json_object
*json
= NULL
;
536 json_object
*json_row
= NULL
;
538 now
= pim_time_monotonic_sec();
541 json
= json_object_new_object();
544 "Interface State Address V Querier Query Timer Uptime%s",
547 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT
), node
, ifp
)) {
548 struct pim_interface
*pim_ifp
;
549 struct listnode
*sock_node
;
550 struct igmp_sock
*igmp
;
557 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
560 char query_hhmmss
[10];
562 pim_time_uptime(uptime
, sizeof(uptime
),
563 now
- igmp
->sock_creation
);
564 pim_time_timer_to_hhmmss(query_hhmmss
,
565 sizeof(query_hhmmss
),
566 igmp
->t_igmp_query_timer
);
569 json_row
= json_object_new_object();
570 json_object_pim_ifp_add(json_row
, ifp
);
571 json_object_string_add(json_row
, "upTime",
573 json_object_int_add(json_row
, "version",
574 pim_ifp
->igmp_version
);
576 if (igmp
->t_igmp_query_timer
) {
577 json_object_boolean_true_add(json_row
,
579 json_object_string_add(json_row
,
584 json_object_object_add(json
, ifp
->name
,
589 "%-9s %5s %15s %d %7s %11s %8s%s",
591 if_is_up(ifp
) ? "up" : "down",
592 inet_ntoa(igmp
->ifaddr
),
593 pim_ifp
->igmp_version
,
594 igmp
->t_igmp_query_timer
? "local"
596 query_hhmmss
, uptime
, VTY_NEWLINE
);
602 vty_out(vty
, "%s%s", json_object_to_json_string_ext(
603 json
, JSON_C_TO_STRING_PRETTY
),
605 json_object_free(json
);
609 static void igmp_show_interfaces_single(struct vty
*vty
, const char *ifname
,
612 struct igmp_sock
*igmp
;
613 struct interface
*ifp
;
614 struct listnode
*node
;
615 struct listnode
*sock_node
;
616 struct pim_interface
*pim_ifp
;
618 char query_hhmmss
[10];
619 char other_hhmmss
[10];
620 int found_ifname
= 0;
623 long gmi_msec
; /* Group Membership Interval */
626 long oqpi_msec
; /* Other Querier Present Interval */
630 json_object
*json
= NULL
;
631 json_object
*json_row
= NULL
;
634 json
= json_object_new_object();
636 now
= pim_time_monotonic_sec();
638 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT
), node
, ifp
)) {
644 if (strcmp(ifname
, "detail") && strcmp(ifname
, ifp
->name
))
647 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
650 pim_time_uptime(uptime
, sizeof(uptime
),
651 now
- igmp
->sock_creation
);
652 pim_time_timer_to_hhmmss(query_hhmmss
,
653 sizeof(query_hhmmss
),
654 igmp
->t_igmp_query_timer
);
655 pim_time_timer_to_hhmmss(other_hhmmss
,
656 sizeof(other_hhmmss
),
657 igmp
->t_other_querier_timer
);
659 gmi_msec
= PIM_IGMP_GMI_MSEC(
660 igmp
->querier_robustness_variable
,
661 igmp
->querier_query_interval
,
662 pim_ifp
->igmp_query_max_response_time_dsec
);
665 pim_ifp
->igmp_default_query_interval
);
667 oqpi_msec
= PIM_IGMP_OQPI_MSEC(
668 igmp
->querier_robustness_variable
,
669 igmp
->querier_query_interval
,
670 pim_ifp
->igmp_query_max_response_time_dsec
);
672 lmqt_msec
= PIM_IGMP_LMQT_MSEC(
673 pim_ifp
->igmp_query_max_response_time_dsec
,
674 igmp
->querier_robustness_variable
);
678 igmp
->querier_robustness_variable
,
679 igmp
->querier_query_interval
,
680 pim_ifp
->igmp_query_max_response_time_dsec
)
683 qri_msec
= pim_ifp
->igmp_query_max_response_time_dsec
685 mloop
= pim_socket_mcastloop_get(pim_ifp
->pim_sock_fd
);
688 json_row
= json_object_new_object();
689 json_object_pim_ifp_add(json_row
, ifp
);
690 json_object_string_add(json_row
, "upTime",
692 json_object_string_add(json_row
, "querier",
693 igmp
->t_igmp_query_timer
696 json_object_int_add(json_row
, "queryStartCount",
697 igmp
->startup_query_count
);
698 json_object_string_add(json_row
,
701 json_object_string_add(json_row
,
704 json_object_int_add(json_row
, "version",
705 pim_ifp
->igmp_version
);
708 "timerGroupMembershipIntervalMsec",
710 json_object_int_add(json_row
,
711 "timerLastMemberQueryMsec",
715 "timerOlderHostPresentIntervalMsec",
719 "timerOtherQuerierPresentIntervalMsec",
722 json_row
, "timerQueryInterval",
723 igmp
->querier_query_interval
);
726 "timerQueryResponseIntervalMsec",
729 json_row
, "timerRobustnessVariable",
730 igmp
->querier_robustness_variable
);
731 json_object_int_add(json_row
,
732 "timerStartupQueryInterval",
735 json_object_object_add(json
, ifp
->name
,
739 vty_out(vty
, "Interface : %s%s", ifp
->name
,
741 vty_out(vty
, "State : %s%s",
742 if_is_up(ifp
) ? "up" : "down",
744 vty_out(vty
, "Address : %s%s",
745 inet_ntoa(pim_ifp
->primary_address
),
747 vty_out(vty
, "Uptime : %s%s", uptime
,
749 vty_out(vty
, "Version : %d%s",
750 pim_ifp
->igmp_version
, VTY_NEWLINE
);
751 vty_out(vty
, "%s", VTY_NEWLINE
);
752 vty_out(vty
, "%s", VTY_NEWLINE
);
754 vty_out(vty
, "Querier%s", VTY_NEWLINE
);
755 vty_out(vty
, "-------%s", VTY_NEWLINE
);
756 vty_out(vty
, "Querier : %s%s",
757 igmp
->t_igmp_query_timer
? "local"
760 vty_out(vty
, "Start Count : %d%s",
761 igmp
->startup_query_count
, VTY_NEWLINE
);
762 vty_out(vty
, "Query Timer : %s%s", query_hhmmss
,
764 vty_out(vty
, "Other Timer : %s%s", other_hhmmss
,
766 vty_out(vty
, "%s", VTY_NEWLINE
);
767 vty_out(vty
, "%s", VTY_NEWLINE
);
769 vty_out(vty
, "Timers%s", VTY_NEWLINE
);
770 vty_out(vty
, "------%s", VTY_NEWLINE
);
772 "Group Membership Interval : %lis%s",
773 gmi_msec
/ 1000, VTY_NEWLINE
);
775 "Last Member Query Time : %lis%s",
776 lmqt_msec
/ 1000, VTY_NEWLINE
);
778 "Older Host Present Interval : %lis%s",
779 ohpi_msec
/ 1000, VTY_NEWLINE
);
781 "Other Querier Present Interval : %lis%s",
782 oqpi_msec
/ 1000, VTY_NEWLINE
);
784 "Query Interval : %ds%s",
785 igmp
->querier_query_interval
,
788 "Query Response Interval : %lis%s",
789 qri_msec
/ 1000, VTY_NEWLINE
);
791 "Robustness Variable : %d%s",
792 igmp
->querier_robustness_variable
,
795 "Startup Query Interval : %ds%s",
797 vty_out(vty
, "%s", VTY_NEWLINE
);
798 vty_out(vty
, "%s", VTY_NEWLINE
);
800 pim_print_ifp_flags(vty
, ifp
, mloop
);
806 vty_out(vty
, "%s%s", json_object_to_json_string_ext(
807 json
, JSON_C_TO_STRING_PRETTY
),
809 json_object_free(json
);
812 vty_out(vty
, "%% No such interface%s", VTY_NEWLINE
);
816 static void igmp_show_interface_join(struct vty
*vty
)
818 struct listnode
*node
;
819 struct interface
*ifp
;
822 now
= pim_time_monotonic_sec();
825 "Interface Address Source Group Socket Uptime %s",
828 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT
), node
, ifp
)) {
829 struct pim_interface
*pim_ifp
;
830 struct listnode
*join_node
;
831 struct igmp_join
*ij
;
832 struct in_addr pri_addr
;
833 char pri_addr_str
[INET_ADDRSTRLEN
];
840 if (!pim_ifp
->igmp_join_list
)
843 pri_addr
= pim_find_primary_addr(ifp
);
844 pim_inet4_dump("<pri?>", pri_addr
, pri_addr_str
,
845 sizeof(pri_addr_str
));
847 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_join_list
, join_node
,
849 char group_str
[INET_ADDRSTRLEN
];
850 char source_str
[INET_ADDRSTRLEN
];
853 pim_time_uptime(uptime
, sizeof(uptime
),
854 now
- ij
->sock_creation
);
855 pim_inet4_dump("<grp?>", ij
->group_addr
, group_str
,
857 pim_inet4_dump("<src?>", ij
->source_addr
, source_str
,
860 vty_out(vty
, "%-9s %-15s %-15s %-15s %6d %8s%s",
861 ifp
->name
, pri_addr_str
, source_str
, group_str
,
862 ij
->sock_fd
, uptime
, VTY_NEWLINE
);
863 } /* for (pim_ifp->igmp_join_list) */
868 static void pim_show_interfaces_single(struct vty
*vty
, const char *ifname
,
871 struct in_addr ifaddr
;
872 struct interface
*ifp
;
873 struct listnode
*neighnode
;
874 struct listnode
*node
;
875 struct listnode
*upnode
;
876 struct pim_interface
*pim_ifp
;
877 struct pim_neighbor
*neigh
;
878 struct pim_upstream
*up
;
880 char dr_str
[INET_ADDRSTRLEN
];
883 char grp_str
[INET_ADDRSTRLEN
];
884 char hello_period
[10];
885 char hello_timer
[10];
886 char neigh_src_str
[INET_ADDRSTRLEN
];
887 char src_str
[INET_ADDRSTRLEN
];
888 char stat_uptime
[10];
891 int found_ifname
= 0;
893 json_object
*json
= NULL
;
894 json_object
*json_row
= NULL
;
895 json_object
*json_pim_neighbor
= NULL
;
896 json_object
*json_pim_neighbors
= NULL
;
897 json_object
*json_group
= NULL
;
898 json_object
*json_group_source
= NULL
;
899 json_object
*json_fhr_sources
= NULL
;
900 struct pim_secondary_addr
*sec_addr
;
901 struct listnode
*sec_node
;
903 now
= pim_time_monotonic_sec();
906 json
= json_object_new_object();
908 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT
), node
, ifp
)) {
914 if (pim_ifp
->pim_sock_fd
< 0)
917 if (strcmp(ifname
, "detail") && strcmp(ifname
, ifp
->name
))
921 ifaddr
= pim_ifp
->primary_address
;
922 pim_inet4_dump("<dr?>", pim_ifp
->pim_dr_addr
, dr_str
,
924 pim_time_uptime_begin(dr_uptime
, sizeof(dr_uptime
), now
,
925 pim_ifp
->pim_dr_election_last
);
926 pim_time_timer_to_hhmmss(hello_timer
, sizeof(hello_timer
),
927 pim_ifp
->t_pim_hello_timer
);
928 pim_time_mmss(hello_period
, sizeof(hello_period
),
929 pim_ifp
->pim_hello_period
);
930 pim_time_uptime(stat_uptime
, sizeof(stat_uptime
),
931 now
- pim_ifp
->pim_ifstat_start
);
932 mloop
= pim_socket_mcastloop_get(pim_ifp
->pim_sock_fd
);
935 json_row
= json_object_new_object();
936 json_object_pim_ifp_add(json_row
, ifp
);
938 if (pim_ifp
->update_source
.s_addr
!= INADDR_ANY
) {
939 json_object_string_add(
940 json_row
, "useSource",
941 inet_ntoa(pim_ifp
->update_source
));
943 if (pim_ifp
->sec_addr_list
) {
944 json_object
*sec_list
= NULL
;
946 sec_list
= json_object_new_array();
947 for (ALL_LIST_ELEMENTS_RO(
948 pim_ifp
->sec_addr_list
, sec_node
,
950 json_object_array_add(
952 json_object_new_string(inet_ntoa(
955 json_object_object_add(json_row
,
956 "secondaryAddressList",
961 if (pim_ifp
->pim_neighbor_list
->count
) {
962 json_pim_neighbors
= json_object_new_object();
964 for (ALL_LIST_ELEMENTS_RO(
965 pim_ifp
->pim_neighbor_list
,
968 json_object_new_object();
969 pim_inet4_dump("<src?>",
972 sizeof(neigh_src_str
));
973 pim_time_uptime(uptime
, sizeof(uptime
),
974 now
- neigh
->creation
);
975 pim_time_timer_to_hhmmss(
976 expire
, sizeof(expire
),
977 neigh
->t_expire_timer
);
979 json_object_string_add(
980 json_pim_neighbor
, "address",
982 json_object_string_add(
983 json_pim_neighbor
, "upTime",
985 json_object_string_add(
986 json_pim_neighbor
, "holdtime",
989 json_object_object_add(
995 json_object_object_add(json_row
, "neighbors",
999 json_object_string_add(json_row
, "drAddress", dr_str
);
1000 json_object_int_add(json_row
, "drPriority",
1001 pim_ifp
->pim_dr_priority
);
1002 json_object_string_add(json_row
, "drUptime", dr_uptime
);
1003 json_object_int_add(json_row
, "drElections",
1004 pim_ifp
->pim_dr_election_count
);
1005 json_object_int_add(json_row
, "drChanges",
1006 pim_ifp
->pim_dr_election_changes
);
1009 for (ALL_LIST_ELEMENTS_RO(pim_upstream_list
, upnode
,
1011 if (ifp
== up
->rpf
.source_nexthop
.interface
) {
1013 & PIM_UPSTREAM_FLAG_MASK_FHR
) {
1014 if (!json_fhr_sources
) {
1016 json_object_new_object();
1019 pim_inet4_dump("<src?>",
1023 pim_inet4_dump("<grp?>",
1028 uptime
, sizeof(uptime
),
1029 now
- up
->state_transition
);
1031 /* Does this group live in
1032 * json_fhr_sources? If not
1034 json_object_object_get_ex(
1036 grp_str
, &json_group
);
1040 json_object_new_object();
1041 json_object_object_add(
1048 json_object_new_object();
1049 json_object_string_add(
1052 json_object_string_add(
1055 json_object_string_add(
1058 json_object_object_add(
1059 json_group
, src_str
,
1065 if (json_fhr_sources
) {
1066 json_object_object_add(json_row
,
1071 json_object_int_add(json_row
, "helloPeriod",
1072 pim_ifp
->pim_hello_period
);
1073 json_object_string_add(json_row
, "helloTimer",
1075 json_object_string_add(json_row
, "helloStatStart",
1077 json_object_int_add(json_row
, "helloReceived",
1078 pim_ifp
->pim_ifstat_hello_recv
);
1079 json_object_int_add(json_row
, "helloReceivedFailed",
1080 pim_ifp
->pim_ifstat_hello_recvfail
);
1081 json_object_int_add(json_row
, "helloSend",
1082 pim_ifp
->pim_ifstat_hello_sent
);
1083 json_object_int_add(json_row
, "hellosendFailed",
1084 pim_ifp
->pim_ifstat_hello_sendfail
);
1085 json_object_int_add(json_row
, "helloGenerationId",
1086 pim_ifp
->pim_generation_id
);
1087 json_object_int_add(json_row
, "flagMulticastLoop",
1090 json_object_int_add(
1091 json_row
, "effectivePropagationDelay",
1092 pim_if_effective_propagation_delay_msec(ifp
));
1093 json_object_int_add(
1094 json_row
, "effectiveOverrideInterval",
1095 pim_if_effective_override_interval_msec(ifp
));
1096 json_object_int_add(
1097 json_row
, "joinPruneOverrideInterval",
1098 pim_if_jp_override_interval_msec(ifp
));
1100 json_object_int_add(
1101 json_row
, "propagationDelay",
1102 pim_ifp
->pim_propagation_delay_msec
);
1103 json_object_int_add(
1104 json_row
, "propagationDelayHighest",
1105 pim_ifp
->pim_neighbors_highest_propagation_delay_msec
);
1106 json_object_int_add(
1107 json_row
, "overrideInterval",
1108 pim_ifp
->pim_override_interval_msec
);
1109 json_object_int_add(
1110 json_row
, "overrideIntervalHighest",
1111 pim_ifp
->pim_neighbors_highest_override_interval_msec
);
1112 json_object_object_add(json
, ifp
->name
, json_row
);
1115 vty_out(vty
, "Interface : %s%s", ifp
->name
,
1117 vty_out(vty
, "State : %s%s",
1118 if_is_up(ifp
) ? "up" : "down", VTY_NEWLINE
);
1119 if (pim_ifp
->update_source
.s_addr
!= INADDR_ANY
) {
1120 vty_out(vty
, "Use Source : %s%s",
1121 inet_ntoa(pim_ifp
->update_source
),
1124 if (pim_ifp
->sec_addr_list
) {
1125 vty_out(vty
, "Address : %s (primary)%s",
1126 inet_ntoa(ifaddr
), VTY_NEWLINE
);
1127 for (ALL_LIST_ELEMENTS_RO(
1128 pim_ifp
->sec_addr_list
, sec_node
,
1130 vty_out(vty
, " %s%s",
1131 inet_ntoa(sec_addr
->addr
),
1135 vty_out(vty
, "Address : %s%s",
1136 inet_ntoa(ifaddr
), VTY_NEWLINE
);
1138 vty_out(vty
, "%s", VTY_NEWLINE
);
1143 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
,
1144 neighnode
, neigh
)) {
1147 vty_out(vty
, "PIM Neighbors%s",
1149 vty_out(vty
, "-------------%s",
1154 pim_inet4_dump("<src?>", neigh
->source_addr
,
1156 sizeof(neigh_src_str
));
1157 pim_time_uptime(uptime
, sizeof(uptime
),
1158 now
- neigh
->creation
);
1159 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
1160 neigh
->t_expire_timer
);
1162 "%-15s : up for %s, holdtime expires in %s%s",
1163 neigh_src_str
, uptime
, expire
,
1167 if (!print_header
) {
1168 vty_out(vty
, "%s", VTY_NEWLINE
);
1169 vty_out(vty
, "%s", VTY_NEWLINE
);
1172 vty_out(vty
, "Designated Router%s", VTY_NEWLINE
);
1173 vty_out(vty
, "-----------------%s", VTY_NEWLINE
);
1174 vty_out(vty
, "Address : %s%s", dr_str
, VTY_NEWLINE
);
1175 vty_out(vty
, "Priority : %d%s",
1176 pim_ifp
->pim_dr_priority
, VTY_NEWLINE
);
1177 vty_out(vty
, "Uptime : %s%s", dr_uptime
,
1179 vty_out(vty
, "Elections : %d%s",
1180 pim_ifp
->pim_dr_election_count
, VTY_NEWLINE
);
1181 vty_out(vty
, "Changes : %d%s",
1182 pim_ifp
->pim_dr_election_changes
, VTY_NEWLINE
);
1183 vty_out(vty
, "%s", VTY_NEWLINE
);
1184 vty_out(vty
, "%s", VTY_NEWLINE
);
1188 for (ALL_LIST_ELEMENTS_RO(pim_upstream_list
, upnode
,
1190 if (strcmp(ifp
->name
,
1191 up
->rpf
.source_nexthop
1195 & PIM_UPSTREAM_FLAG_MASK_FHR
) {
1199 "FHR - First Hop Router%s",
1202 "----------------------%s",
1207 pim_inet4_dump("<src?>",
1211 pim_inet4_dump("<grp?>",
1216 uptime
, sizeof(uptime
),
1217 now
- up
->state_transition
);
1219 "%s : %s is a source, uptime is %s%s",
1221 uptime
, VTY_NEWLINE
);
1226 if (!print_header
) {
1227 vty_out(vty
, "%s", VTY_NEWLINE
);
1228 vty_out(vty
, "%s", VTY_NEWLINE
);
1231 vty_out(vty
, "Hellos%s", VTY_NEWLINE
);
1232 vty_out(vty
, "------%s", VTY_NEWLINE
);
1233 vty_out(vty
, "Period : %d%s",
1234 pim_ifp
->pim_hello_period
, VTY_NEWLINE
);
1235 vty_out(vty
, "Timer : %s%s", hello_timer
,
1237 vty_out(vty
, "StatStart : %s%s", stat_uptime
,
1239 vty_out(vty
, "Receive : %d%s",
1240 pim_ifp
->pim_ifstat_hello_recv
, VTY_NEWLINE
);
1241 vty_out(vty
, "Receive Failed : %d%s",
1242 pim_ifp
->pim_ifstat_hello_recvfail
,
1244 vty_out(vty
, "Send : %d%s",
1245 pim_ifp
->pim_ifstat_hello_sent
, VTY_NEWLINE
);
1246 vty_out(vty
, "Send Failed : %d%s",
1247 pim_ifp
->pim_ifstat_hello_sendfail
,
1249 vty_out(vty
, "Generation ID : %08x%s",
1250 pim_ifp
->pim_generation_id
, VTY_NEWLINE
);
1251 vty_out(vty
, "%s", VTY_NEWLINE
);
1252 vty_out(vty
, "%s", VTY_NEWLINE
);
1254 pim_print_ifp_flags(vty
, ifp
, mloop
);
1256 vty_out(vty
, "Join Prune Interval%s", VTY_NEWLINE
);
1257 vty_out(vty
, "-------------------%s", VTY_NEWLINE
);
1258 vty_out(vty
, "LAN Delay : %s%s",
1259 pim_if_lan_delay_enabled(ifp
) ? "yes" : "no",
1261 vty_out(vty
, "Effective Propagation Delay : %d msec%s",
1262 pim_if_effective_propagation_delay_msec(ifp
),
1264 vty_out(vty
, "Effective Override Interval : %d msec%s",
1265 pim_if_effective_override_interval_msec(ifp
),
1267 vty_out(vty
, "Join Prune Override Interval : %d msec%s",
1268 pim_if_jp_override_interval_msec(ifp
),
1270 vty_out(vty
, "%s", VTY_NEWLINE
);
1271 vty_out(vty
, "%s", VTY_NEWLINE
);
1273 vty_out(vty
, "LAN Prune Delay%s", VTY_NEWLINE
);
1274 vty_out(vty
, "---------------%s", VTY_NEWLINE
);
1275 vty_out(vty
, "Propagation Delay : %d msec%s",
1276 pim_ifp
->pim_propagation_delay_msec
,
1278 vty_out(vty
, "Propagation Delay (Highest) : %d msec%s",
1279 pim_ifp
->pim_neighbors_highest_propagation_delay_msec
,
1281 vty_out(vty
, "Override Interval : %d msec%s",
1282 pim_ifp
->pim_override_interval_msec
,
1284 vty_out(vty
, "Override Interval (Highest) : %d msec%s",
1285 pim_ifp
->pim_neighbors_highest_override_interval_msec
,
1287 vty_out(vty
, "%s", VTY_NEWLINE
);
1288 vty_out(vty
, "%s", VTY_NEWLINE
);
1293 vty_out(vty
, "%s%s", json_object_to_json_string_ext(
1294 json
, JSON_C_TO_STRING_PRETTY
),
1296 json_object_free(json
);
1299 vty_out(vty
, "%% No such interface%s", VTY_NEWLINE
);
1303 static void pim_show_interfaces(struct vty
*vty
, u_char uj
)
1305 struct interface
*ifp
;
1306 struct listnode
*node
;
1307 struct listnode
*upnode
;
1308 struct pim_interface
*pim_ifp
;
1309 struct pim_upstream
*up
;
1312 int pim_ifchannels
= 0;
1313 json_object
*json
= NULL
;
1314 json_object
*json_row
= NULL
;
1315 json_object
*json_tmp
;
1317 json
= json_object_new_object();
1319 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT
), node
, ifp
)) {
1320 pim_ifp
= ifp
->info
;
1325 if (pim_ifp
->pim_sock_fd
< 0)
1328 pim_nbrs
= pim_ifp
->pim_neighbor_list
->count
;
1329 pim_ifchannels
= pim_ifp
->pim_ifchannel_list
->count
;
1332 for (ALL_LIST_ELEMENTS_RO(pim_upstream_list
, upnode
, up
))
1333 if (ifp
== up
->rpf
.source_nexthop
.interface
)
1334 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
1337 json_row
= json_object_new_object();
1338 json_object_pim_ifp_add(json_row
, ifp
);
1339 json_object_int_add(json_row
, "pimNeighbors", pim_nbrs
);
1340 json_object_int_add(json_row
, "pimIfChannels", pim_ifchannels
);
1341 json_object_int_add(json_row
, "firstHopRouter", fhr
);
1342 json_object_string_add(json_row
, "pimDesignatedRouter",
1343 inet_ntoa(pim_ifp
->pim_dr_addr
));
1345 if (pim_ifp
->pim_dr_addr
.s_addr
1346 == pim_ifp
->primary_address
.s_addr
)
1347 json_object_boolean_true_add(
1348 json_row
, "pimDesignatedRouterLocal");
1350 json_object_object_add(json
, ifp
->name
, json_row
);
1354 vty_out(vty
, "%s%s", json_object_to_json_string_ext(
1355 json
, JSON_C_TO_STRING_PRETTY
),
1359 "Interface State Address PIM Nbrs PIM DR FHR IfChannels%s",
1362 json_object_object_foreach(json
, key
, val
)
1364 vty_out(vty
, "%-9s ", key
);
1366 json_object_object_get_ex(val
, "state", &json_tmp
);
1367 vty_out(vty
, "%5s ", json_object_get_string(json_tmp
));
1369 json_object_object_get_ex(val
, "address", &json_tmp
);
1370 vty_out(vty
, "%15s ",
1371 json_object_get_string(json_tmp
));
1373 json_object_object_get_ex(val
, "pimNeighbors",
1375 vty_out(vty
, "%8d ", json_object_get_int(json_tmp
));
1377 if (json_object_object_get_ex(
1378 val
, "pimDesignatedRouterLocal",
1380 vty_out(vty
, "%15s ", "local");
1382 json_object_object_get_ex(
1383 val
, "pimDesignatedRouter", &json_tmp
);
1384 vty_out(vty
, "%15s ",
1385 json_object_get_string(json_tmp
));
1388 json_object_object_get_ex(val
, "firstHopRouter",
1390 vty_out(vty
, "%3d ", json_object_get_int(json_tmp
));
1392 json_object_object_get_ex(val
, "pimIfChannels",
1394 vty_out(vty
, "%9d%s", json_object_get_int(json_tmp
),
1399 json_object_free(json
);
1402 static void pim_show_join(struct vty
*vty
, u_char uj
)
1404 struct pim_interface
*pim_ifp
;
1405 struct in_addr ifaddr
;
1406 struct listnode
*ch_node
;
1407 struct pim_ifchannel
*ch
;
1409 json_object
*json
= NULL
;
1410 json_object
*json_iface
= NULL
;
1411 json_object
*json_row
= NULL
;
1412 json_object
*json_grp
= NULL
;
1414 now
= pim_time_monotonic_sec();
1417 json
= json_object_new_object();
1420 "Interface Address Source Group State Uptime Expire Prune%s",
1423 for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list
, ch_node
, ch
)) {
1425 pim_ifp
= ch
->interface
->info
;
1430 ifaddr
= pim_ifp
->primary_address
;
1432 char ch_src_str
[INET_ADDRSTRLEN
];
1433 char ch_grp_str
[INET_ADDRSTRLEN
];
1438 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
,
1439 sizeof(ch_src_str
));
1440 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
,
1441 sizeof(ch_grp_str
));
1443 pim_time_uptime_begin(uptime
, sizeof(uptime
), now
,
1444 ch
->ifjoin_creation
);
1445 pim_time_timer_to_mmss(expire
, sizeof(expire
),
1446 ch
->t_ifjoin_expiry_timer
);
1447 pim_time_timer_to_mmss(prune
, sizeof(prune
),
1448 ch
->t_ifjoin_prune_pending_timer
);
1451 json_object_object_get_ex(json
, ch
->interface
->name
,
1455 json_iface
= json_object_new_object();
1456 json_object_pim_ifp_add(json_iface
,
1458 json_object_object_add(
1459 json
, ch
->interface
->name
, json_iface
);
1462 json_row
= json_object_new_object();
1463 json_object_string_add(json_row
, "source", ch_src_str
);
1464 json_object_string_add(json_row
, "group", ch_grp_str
);
1465 json_object_string_add(json_row
, "upTime", uptime
);
1466 json_object_string_add(json_row
, "expire", expire
);
1467 json_object_string_add(json_row
, "prune", prune
);
1468 json_object_string_add(
1469 json_row
, "channelJoinName",
1470 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
,
1472 if (PIM_IF_FLAG_TEST_S_G_RPT(ch
->flags
))
1473 json_object_int_add(json_row
, "SGRpt", 1);
1475 json_object_object_get_ex(json_iface
, ch_grp_str
,
1478 json_grp
= json_object_new_object();
1479 json_object_object_add(json_grp
, ch_src_str
,
1481 json_object_object_add(json_iface
, ch_grp_str
,
1484 json_object_object_add(json_grp
, ch_src_str
,
1488 "%-9s %-15s %-15s %-15s %-6s %8s %-6s %5s%s",
1489 ch
->interface
->name
, inet_ntoa(ifaddr
),
1490 ch_src_str
, ch_grp_str
,
1491 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
,
1493 uptime
, expire
, prune
, VTY_NEWLINE
);
1495 } /* scan interface channels */
1498 vty_out(vty
, "%s%s", json_object_to_json_string_ext(
1499 json
, JSON_C_TO_STRING_PRETTY
),
1501 json_object_free(json
);
1505 static void pim_show_neighbors_single(struct vty
*vty
, const char *neighbor
,
1508 struct listnode
*node
;
1509 struct listnode
*neighnode
;
1510 struct interface
*ifp
;
1511 struct pim_interface
*pim_ifp
;
1512 struct pim_neighbor
*neigh
;
1514 int found_neighbor
= 0;
1515 int option_address_list
;
1516 int option_dr_priority
;
1517 int option_generation_id
;
1518 int option_holdtime
;
1519 int option_lan_prune_delay
;
1523 char neigh_src_str
[INET_ADDRSTRLEN
];
1525 json_object
*json
= NULL
;
1526 json_object
*json_ifp
= NULL
;
1527 json_object
*json_row
= NULL
;
1529 now
= pim_time_monotonic_sec();
1532 json
= json_object_new_object();
1534 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT
), node
, ifp
)) {
1535 pim_ifp
= ifp
->info
;
1540 if (pim_ifp
->pim_sock_fd
< 0)
1543 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
1545 pim_inet4_dump("<src?>", neigh
->source_addr
,
1546 neigh_src_str
, sizeof(neigh_src_str
));
1549 * The user can specify either the interface name or the
1551 * If this pim_ifp matches neither then skip.
1553 if (strcmp(neighbor
, "detail")
1554 && strcmp(neighbor
, ifp
->name
)
1555 && strcmp(neighbor
, neigh_src_str
))
1559 pim_time_uptime(uptime
, sizeof(uptime
),
1560 now
- neigh
->creation
);
1561 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
1562 neigh
->t_expire_timer
);
1564 option_address_list
= 0;
1565 option_dr_priority
= 0;
1566 option_generation_id
= 0;
1567 option_holdtime
= 0;
1568 option_lan_prune_delay
= 0;
1571 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1572 PIM_OPTION_MASK_ADDRESS_LIST
))
1573 option_address_list
= 1;
1575 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1576 PIM_OPTION_MASK_DR_PRIORITY
))
1577 option_dr_priority
= 1;
1579 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1580 PIM_OPTION_MASK_GENERATION_ID
))
1581 option_generation_id
= 1;
1583 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1584 PIM_OPTION_MASK_HOLDTIME
))
1585 option_holdtime
= 1;
1587 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1588 PIM_OPTION_MASK_LAN_PRUNE_DELAY
))
1589 option_lan_prune_delay
= 1;
1591 if (PIM_OPTION_IS_SET(
1592 neigh
->hello_options
,
1593 PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION
))
1598 /* Does this ifp live in json? If not create
1600 json_object_object_get_ex(json
, ifp
->name
,
1604 json_ifp
= json_object_new_object();
1605 json_object_pim_ifp_add(json_ifp
, ifp
);
1606 json_object_object_add(json
, ifp
->name
,
1610 json_row
= json_object_new_object();
1611 json_object_string_add(json_row
, "interface",
1613 json_object_string_add(json_row
, "address",
1615 json_object_string_add(json_row
, "upTime",
1617 json_object_string_add(json_row
, "holdtime",
1619 json_object_int_add(json_row
, "drPriority",
1620 neigh
->dr_priority
);
1621 json_object_int_add(json_row
, "generationId",
1622 neigh
->generation_id
);
1624 if (option_address_list
)
1625 json_object_boolean_true_add(
1627 "helloOptionAddressList");
1629 if (option_dr_priority
)
1630 json_object_boolean_true_add(
1632 "helloOptionDrPriority");
1634 if (option_generation_id
)
1635 json_object_boolean_true_add(
1637 "helloOptionGenerationId");
1639 if (option_holdtime
)
1640 json_object_boolean_true_add(
1642 "helloOptionHoldtime");
1644 if (option_lan_prune_delay
)
1645 json_object_boolean_true_add(
1647 "helloOptionLanPruneDelay");
1650 json_object_boolean_true_add(
1651 json_row
, "helloOptionTBit");
1653 json_object_object_add(json_ifp
, neigh_src_str
,
1657 vty_out(vty
, "Interface : %s%s", ifp
->name
,
1659 vty_out(vty
, "Neighbor : %s%s", neigh_src_str
,
1663 uptime
, VTY_NEWLINE
);
1666 expire
, VTY_NEWLINE
);
1668 " DR Priority : %d%s",
1669 neigh
->dr_priority
, VTY_NEWLINE
);
1671 " Generation ID : %08x%s",
1672 neigh
->generation_id
, VTY_NEWLINE
);
1674 " Override Interval (msec) : %d%s",
1675 neigh
->override_interval_msec
,
1678 " Propagation Delay (msec) : %d%s",
1679 neigh
->propagation_delay_msec
,
1682 " Hello Option - Address List : %s%s",
1683 option_address_list
? "yes" : "no",
1686 " Hello Option - DR Priority : %s%s",
1687 option_dr_priority
? "yes" : "no",
1690 " Hello Option - Generation ID : %s%s",
1691 option_generation_id
? "yes" : "no",
1694 " Hello Option - Holdtime : %s%s",
1695 option_holdtime
? "yes" : "no",
1698 " Hello Option - LAN Prune Delay : %s%s",
1699 option_lan_prune_delay
? "yes" : "no",
1702 " Hello Option - T-bit : %s%s",
1703 option_t_bit
? "yes" : "no",
1705 vty_out(vty
, "%s", VTY_NEWLINE
);
1711 vty_out(vty
, "%s%s", json_object_to_json_string_ext(
1712 json
, JSON_C_TO_STRING_PRETTY
),
1714 json_object_free(json
);
1717 if (!found_neighbor
)
1719 "%% No such interface or neighbor%s",
1725 static void pim_show_state(struct vty
*vty
, const char *src_or_group
,
1726 const char *group
, u_char uj
)
1728 struct channel_oil
*c_oil
;
1729 struct listnode
*node
;
1730 json_object
*json
= NULL
;
1731 json_object
*json_group
= NULL
;
1732 json_object
*json_ifp_in
= NULL
;
1733 json_object
*json_ifp_out
= NULL
;
1734 json_object
*json_source
= NULL
;
1737 now
= pim_time_monotonic_sec();
1740 json
= json_object_new_object();
1743 "Codes: J -> Pim Join, I -> IGMP Report, S -> Source, * -> Inherited from (*,G)");
1745 "%sInstalled Source Group IIF OIL%s",
1746 VTY_NEWLINE
, VTY_NEWLINE
);
1749 for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list
, node
, c_oil
)) {
1750 char grp_str
[INET_ADDRSTRLEN
];
1751 char src_str
[INET_ADDRSTRLEN
];
1752 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
1753 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
1755 struct interface
*ifp_in
;
1758 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
1760 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
1762 ifp_in
= pim_if_find_by_vif_index(c_oil
->oil
.mfcc_parent
);
1765 strcpy(in_ifname
, ifp_in
->name
);
1767 strcpy(in_ifname
, "<iif?>");
1770 if (strcmp(src_or_group
, src_str
)
1771 && strcmp(src_or_group
, grp_str
))
1774 if (group
&& strcmp(group
, grp_str
))
1780 /* Find the group, create it if it doesn't exist */
1781 json_object_object_get_ex(json
, grp_str
, &json_group
);
1784 json_group
= json_object_new_object();
1785 json_object_object_add(json
, grp_str
,
1789 /* Find the source nested under the group, create it if
1790 * it doesn't exist */
1791 json_object_object_get_ex(json_group
, src_str
,
1795 json_source
= json_object_new_object();
1796 json_object_object_add(json_group
, src_str
,
1800 /* Find the inbound interface nested under the source,
1801 * create it if it doesn't exist */
1802 json_object_object_get_ex(json_source
, in_ifname
,
1806 json_ifp_in
= json_object_new_object();
1807 json_object_object_add(json_source
, in_ifname
,
1809 json_object_int_add(json_source
, "Installed",
1811 json_object_int_add(json_source
, "RefCount",
1812 c_oil
->oil_ref_count
);
1813 json_object_int_add(json_source
, "OilListSize",
1815 json_object_int_add(
1816 json_source
, "OilRescan",
1817 c_oil
->oil_inherited_rescan
);
1818 json_object_int_add(json_source
, "LastUsed",
1819 c_oil
->cc
.lastused
);
1820 json_object_int_add(json_source
, "PacketCount",
1822 json_object_int_add(json_source
, "ByteCount",
1824 json_object_int_add(json_source
,
1826 c_oil
->cc
.wrong_if
);
1829 vty_out(vty
, "%-9d %-15s %-15s %-7s ",
1830 c_oil
->installed
, src_str
, grp_str
,
1834 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
1836 struct interface
*ifp_out
;
1837 char oif_uptime
[10];
1840 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
1844 ifp_out
= pim_if_find_by_vif_index(oif_vif_index
);
1846 oif_uptime
, sizeof(oif_uptime
),
1847 now
- c_oil
->oif_creation
[oif_vif_index
]);
1850 strcpy(out_ifname
, ifp_out
->name
);
1852 strcpy(out_ifname
, "<oif?>");
1855 json_ifp_out
= json_object_new_object();
1856 json_object_string_add(json_ifp_out
, "source",
1858 json_object_string_add(json_ifp_out
, "group",
1860 json_object_string_add(json_ifp_out
,
1863 json_object_string_add(json_ifp_out
,
1864 "outboundInterface",
1866 json_object_int_add(json_ifp_out
, "installed",
1869 json_object_object_add(json_ifp_in
, out_ifname
,
1874 vty_out(vty
, "%s(%c%c%c%c)", out_ifname
,
1875 (c_oil
->oif_flags
[oif_vif_index
]
1876 & PIM_OIF_FLAG_PROTO_IGMP
)
1879 (c_oil
->oif_flags
[oif_vif_index
]
1880 & PIM_OIF_FLAG_PROTO_PIM
)
1883 (c_oil
->oif_flags
[oif_vif_index
]
1884 & PIM_OIF_FLAG_PROTO_SOURCE
)
1887 (c_oil
->oif_flags
[oif_vif_index
]
1888 & PIM_OIF_FLAG_PROTO_STAR
)
1892 vty_out(vty
, ", %s(%c%c%c%c)",
1894 (c_oil
->oif_flags
[oif_vif_index
]
1895 & PIM_OIF_FLAG_PROTO_IGMP
)
1898 (c_oil
->oif_flags
[oif_vif_index
]
1899 & PIM_OIF_FLAG_PROTO_PIM
)
1902 (c_oil
->oif_flags
[oif_vif_index
]
1903 & PIM_OIF_FLAG_PROTO_SOURCE
)
1906 (c_oil
->oif_flags
[oif_vif_index
]
1907 & PIM_OIF_FLAG_PROTO_STAR
)
1914 vty_out(vty
, "%s", VTY_NEWLINE
);
1919 vty_out(vty
, "%s%s", json_object_to_json_string_ext(
1920 json
, JSON_C_TO_STRING_PRETTY
),
1922 json_object_free(json
);
1924 vty_out(vty
, "%s", VTY_NEWLINE
);
1928 static void pim_show_neighbors(struct vty
*vty
, u_char uj
)
1930 struct listnode
*node
;
1931 struct listnode
*neighnode
;
1932 struct interface
*ifp
;
1933 struct pim_interface
*pim_ifp
;
1934 struct pim_neighbor
*neigh
;
1938 char neigh_src_str
[INET_ADDRSTRLEN
];
1939 json_object
*json
= NULL
;
1940 json_object
*json_ifp_rows
= NULL
;
1941 json_object
*json_row
= NULL
;
1943 now
= pim_time_monotonic_sec();
1946 json
= json_object_new_object();
1949 "Interface Neighbor Uptime Holdtime DR Pri%s",
1953 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT
), node
, ifp
)) {
1954 pim_ifp
= ifp
->info
;
1959 if (pim_ifp
->pim_sock_fd
< 0)
1963 json_ifp_rows
= json_object_new_object();
1965 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
1967 pim_inet4_dump("<src?>", neigh
->source_addr
,
1968 neigh_src_str
, sizeof(neigh_src_str
));
1969 pim_time_uptime(uptime
, sizeof(uptime
),
1970 now
- neigh
->creation
);
1971 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
1972 neigh
->t_expire_timer
);
1975 json_row
= json_object_new_object();
1976 json_object_string_add(json_row
, "interface",
1978 json_object_string_add(json_row
, "neighbor",
1980 json_object_string_add(json_row
, "upTime",
1982 json_object_string_add(json_row
, "holdTime",
1984 json_object_int_add(json_row
, "holdTimeMax",
1986 json_object_int_add(json_row
, "drPriority",
1987 neigh
->dr_priority
);
1988 json_object_object_add(json_ifp_rows
,
1989 neigh_src_str
, json_row
);
1992 vty_out(vty
, "%-9s %15s %8s %8s %6d%s",
1993 ifp
->name
, neigh_src_str
, uptime
,
1994 expire
, neigh
->dr_priority
,
2000 json_object_object_add(json
, ifp
->name
, json_ifp_rows
);
2001 json_ifp_rows
= NULL
;
2006 vty_out(vty
, "%s%s", json_object_to_json_string_ext(
2007 json
, JSON_C_TO_STRING_PRETTY
),
2009 json_object_free(json
);
2013 static void pim_show_neighbors_secondary(struct vty
*vty
)
2015 struct listnode
*node
;
2016 struct interface
*ifp
;
2019 "Interface Address Neighbor Secondary %s",
2022 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT
), node
, ifp
)) {
2023 struct pim_interface
*pim_ifp
;
2024 struct in_addr ifaddr
;
2025 struct listnode
*neighnode
;
2026 struct pim_neighbor
*neigh
;
2028 pim_ifp
= ifp
->info
;
2033 if (pim_ifp
->pim_sock_fd
< 0)
2036 ifaddr
= pim_ifp
->primary_address
;
2038 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
2040 char neigh_src_str
[INET_ADDRSTRLEN
];
2041 struct listnode
*prefix_node
;
2044 if (!neigh
->prefix_list
)
2047 pim_inet4_dump("<src?>", neigh
->source_addr
,
2048 neigh_src_str
, sizeof(neigh_src_str
));
2050 for (ALL_LIST_ELEMENTS_RO(neigh
->prefix_list
,
2052 char neigh_sec_str
[INET_ADDRSTRLEN
];
2054 if (p
->family
!= AF_INET
)
2057 pim_inet4_dump("<src?>", p
->u
.prefix4
,
2059 sizeof(neigh_sec_str
));
2061 vty_out(vty
, "%-9s %-15s %-15s %-15s%s",
2062 ifp
->name
, inet_ntoa(ifaddr
),
2063 neigh_src_str
, neigh_sec_str
,
2070 static void json_object_pim_upstream_add(json_object
*json
,
2071 struct pim_upstream
*up
)
2073 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED
)
2074 json_object_boolean_true_add(json
, "drJoinDesired");
2076 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED
)
2077 json_object_boolean_true_add(json
, "drJoinDesiredUpdated");
2079 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
2080 json_object_boolean_true_add(json
, "firstHopRouter");
2082 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_IGMP
)
2083 json_object_boolean_true_add(json
, "sourceIgmp");
2085 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_PIM
)
2086 json_object_boolean_true_add(json
, "sourcePim");
2088 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_STREAM
)
2089 json_object_boolean_true_add(json
, "sourceStream");
2091 /* XXX: need to print ths flag in the plain text display as well */
2092 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_MSDP
)
2093 json_object_boolean_true_add(json
, "sourceMsdp");
2097 pim_upstream_state2brief_str(enum pim_upstream_state join_state
,
2100 switch (join_state
) {
2101 case PIM_UPSTREAM_NOTJOINED
:
2102 strcpy(state_str
, "NotJ");
2104 case PIM_UPSTREAM_JOINED
:
2105 strcpy(state_str
, "J");
2108 strcpy(state_str
, "Unk");
2113 static const char *pim_reg_state2brief_str(enum pim_reg_state reg_state
,
2116 switch (reg_state
) {
2117 case PIM_REG_NOINFO
:
2118 strcpy(state_str
, "RegNI");
2121 strcpy(state_str
, "RegJ");
2123 case PIM_REG_JOIN_PENDING
:
2125 strcpy(state_str
, "RegP");
2128 strcpy(state_str
, "Unk");
2133 static void pim_show_upstream(struct vty
*vty
, u_char uj
)
2135 struct listnode
*upnode
;
2136 struct pim_upstream
*up
;
2138 json_object
*json
= NULL
;
2139 json_object
*json_group
= NULL
;
2140 json_object
*json_row
= NULL
;
2142 now
= pim_time_monotonic_sec();
2145 json
= json_object_new_object();
2148 "Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt%s",
2151 for (ALL_LIST_ELEMENTS_RO(pim_upstream_list
, upnode
, up
)) {
2152 char src_str
[INET_ADDRSTRLEN
];
2153 char grp_str
[INET_ADDRSTRLEN
];
2155 char join_timer
[10];
2158 char msdp_reg_timer
[10];
2159 char state_str
[PIM_REG_STATE_STR_LEN
];
2161 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2162 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2163 pim_time_uptime(uptime
, sizeof(uptime
),
2164 now
- up
->state_transition
);
2165 pim_time_timer_to_hhmmss(join_timer
, sizeof(join_timer
),
2169 * If we have a J/P timer for the neighbor display that
2171 if (!up
->t_join_timer
) {
2172 struct pim_neighbor
*nbr
;
2174 nbr
= pim_neighbor_find(
2175 up
->rpf
.source_nexthop
.interface
,
2176 up
->rpf
.rpf_addr
.u
.prefix4
);
2178 pim_time_timer_to_hhmmss(join_timer
,
2183 pim_time_timer_to_hhmmss(rs_timer
, sizeof(rs_timer
),
2185 pim_time_timer_to_hhmmss(ka_timer
, sizeof(ka_timer
),
2187 pim_time_timer_to_hhmmss(msdp_reg_timer
, sizeof(msdp_reg_timer
),
2188 up
->t_msdp_reg_timer
);
2190 pim_upstream_state2brief_str(up
->join_state
, state_str
);
2191 if (up
->reg_state
!= PIM_REG_NOINFO
) {
2192 char tmp_str
[PIM_REG_STATE_STR_LEN
];
2194 sprintf(state_str
+ strlen(state_str
), ",%s",
2195 pim_reg_state2brief_str(up
->reg_state
,
2200 json_object_object_get_ex(json
, grp_str
, &json_group
);
2203 json_group
= json_object_new_object();
2204 json_object_object_add(json
, grp_str
,
2208 json_row
= json_object_new_object();
2209 json_object_pim_upstream_add(json_row
, up
);
2210 json_object_string_add(
2211 json_row
, "inboundInterface",
2212 up
->rpf
.source_nexthop
.interface
->name
);
2213 json_object_string_add(json_row
, "source", src_str
);
2214 json_object_string_add(json_row
, "group", grp_str
);
2215 json_object_string_add(json_row
, "state", state_str
);
2216 json_object_string_add(
2217 json_row
, "joinState",
2218 pim_upstream_state2str(up
->join_state
));
2219 json_object_string_add(
2220 json_row
, "regState",
2221 pim_reg_state2str(up
->reg_state
, state_str
));
2222 json_object_string_add(json_row
, "upTime", uptime
);
2223 json_object_string_add(json_row
, "joinTimer",
2225 json_object_string_add(json_row
, "resetTimer",
2227 json_object_string_add(json_row
, "keepaliveTimer",
2229 json_object_string_add(json_row
, "msdpRegTimer",
2231 json_object_int_add(json_row
, "refCount",
2233 json_object_int_add(json_row
, "sptBit", up
->sptbit
);
2234 json_object_object_add(json_group
, src_str
, json_row
);
2237 "%-10s%-15s %-15s %-11s %-8s %-9s %-9s %-9s %6d%s",
2238 up
->rpf
.source_nexthop
.interface
->name
, src_str
,
2239 grp_str
, state_str
, uptime
, join_timer
,
2240 rs_timer
, ka_timer
, up
->ref_count
, VTY_NEWLINE
);
2245 vty_out(vty
, "%s%s", json_object_to_json_string_ext(
2246 json
, JSON_C_TO_STRING_PRETTY
),
2248 json_object_free(json
);
2252 static void pim_show_join_desired(struct vty
*vty
, u_char uj
)
2254 struct listnode
*chnode
;
2255 struct pim_interface
*pim_ifp
;
2256 struct pim_ifchannel
*ch
;
2257 char src_str
[INET_ADDRSTRLEN
];
2258 char grp_str
[INET_ADDRSTRLEN
];
2259 json_object
*json
= NULL
;
2260 json_object
*json_group
= NULL
;
2261 json_object
*json_row
= NULL
;
2264 json
= json_object_new_object();
2267 "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD%s",
2270 /* scan per-interface (S,G) state */
2271 for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list
, chnode
, ch
)) {
2272 /* scan all interfaces */
2273 pim_ifp
= ch
->interface
->info
;
2277 struct pim_upstream
*up
= ch
->upstream
;
2279 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2280 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2283 json_object_object_get_ex(json
, grp_str
, &json_group
);
2286 json_group
= json_object_new_object();
2287 json_object_object_add(json
, grp_str
,
2291 json_row
= json_object_new_object();
2292 json_object_pim_upstream_add(json_row
, up
);
2293 json_object_string_add(json_row
, "interface",
2294 ch
->interface
->name
);
2295 json_object_string_add(json_row
, "source", src_str
);
2296 json_object_string_add(json_row
, "group", grp_str
);
2298 if (pim_macro_ch_lost_assert(ch
))
2299 json_object_boolean_true_add(json_row
,
2302 if (pim_macro_chisin_joins(ch
))
2303 json_object_boolean_true_add(json_row
, "joins");
2305 if (pim_macro_chisin_pim_include(ch
))
2306 json_object_boolean_true_add(json_row
,
2309 if (pim_upstream_evaluate_join_desired(up
))
2310 json_object_boolean_true_add(
2311 json_row
, "evaluateJoinDesired");
2313 json_object_object_add(json_group
, src_str
, json_row
);
2317 "%-9s %-15s %-15s %-10s %-5s %-10s %-11s %-6s%s",
2318 ch
->interface
->name
, src_str
, grp_str
,
2319 pim_macro_ch_lost_assert(ch
) ? "yes" : "no",
2320 pim_macro_chisin_joins(ch
) ? "yes" : "no",
2321 pim_macro_chisin_pim_include(ch
) ? "yes" : "no",
2322 PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(
2326 pim_upstream_evaluate_join_desired(up
) ? "yes"
2333 vty_out(vty
, "%s%s", json_object_to_json_string_ext(
2334 json
, JSON_C_TO_STRING_PRETTY
),
2336 json_object_free(json
);
2340 static void pim_show_upstream_rpf(struct vty
*vty
, u_char uj
)
2342 struct listnode
*upnode
;
2343 struct pim_upstream
*up
;
2344 json_object
*json
= NULL
;
2345 json_object
*json_group
= NULL
;
2346 json_object
*json_row
= NULL
;
2349 json
= json_object_new_object();
2352 "Source Group RpfIface RibNextHop RpfAddress %s",
2355 for (ALL_LIST_ELEMENTS_RO(pim_upstream_list
, upnode
, up
)) {
2356 char src_str
[INET_ADDRSTRLEN
];
2357 char grp_str
[INET_ADDRSTRLEN
];
2358 char rpf_nexthop_str
[PREFIX_STRLEN
];
2359 char rpf_addr_str
[PREFIX_STRLEN
];
2360 struct pim_rpf
*rpf
;
2361 const char *rpf_ifname
;
2365 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2366 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2367 pim_addr_dump("<nexthop?>",
2368 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2369 rpf_nexthop_str
, sizeof(rpf_nexthop_str
));
2370 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2371 sizeof(rpf_addr_str
));
2373 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2376 json_object_object_get_ex(json
, grp_str
, &json_group
);
2379 json_group
= json_object_new_object();
2380 json_object_object_add(json
, grp_str
,
2384 json_row
= json_object_new_object();
2385 json_object_pim_upstream_add(json_row
, up
);
2386 json_object_string_add(json_row
, "source", src_str
);
2387 json_object_string_add(json_row
, "group", grp_str
);
2388 json_object_string_add(json_row
, "rpfInterface",
2390 json_object_string_add(json_row
, "ribNexthop",
2392 json_object_string_add(json_row
, "rpfAddress",
2394 json_object_object_add(json_group
, src_str
, json_row
);
2396 vty_out(vty
, "%-15s %-15s %-8s %-15s %-15s%s", src_str
,
2397 grp_str
, rpf_ifname
, rpf_nexthop_str
,
2398 rpf_addr_str
, VTY_NEWLINE
);
2403 vty_out(vty
, "%s%s", json_object_to_json_string_ext(
2404 json
, JSON_C_TO_STRING_PRETTY
),
2406 json_object_free(json
);
2410 static void show_rpf_refresh_stats(struct vty
*vty
, time_t now
,
2413 char refresh_uptime
[10];
2415 pim_time_uptime_begin(refresh_uptime
, sizeof(refresh_uptime
), now
,
2416 qpim_rpf_cache_refresh_last
);
2419 json_object_int_add(json
, "rpfCacheRefreshDelayMsecs",
2420 qpim_rpf_cache_refresh_delay_msec
);
2421 json_object_int_add(
2422 json
, "rpfCacheRefreshTimer",
2423 pim_time_timer_remain_msec(qpim_rpf_cache_refresher
));
2424 json_object_int_add(json
, "rpfCacheRefreshRequests",
2425 qpim_rpf_cache_refresh_requests
);
2426 json_object_int_add(json
, "rpfCacheRefreshEvents",
2427 qpim_rpf_cache_refresh_events
);
2428 json_object_string_add(json
, "rpfCacheRefreshLast",
2430 json_object_int_add(json
, "nexthopLookups",
2431 qpim_nexthop_lookups
);
2432 json_object_int_add(json
, "nexthopLookupsAvoided",
2433 nexthop_lookups_avoided
);
2436 "RPF Cache Refresh Delay: %ld msecs%s"
2437 "RPF Cache Refresh Timer: %ld msecs%s"
2438 "RPF Cache Refresh Requests: %lld%s"
2439 "RPF Cache Refresh Events: %lld%s"
2440 "RPF Cache Refresh Last: %s%s"
2441 "Nexthop Lookups: %lld%s"
2442 "Nexthop Lookups Avoided: %lld%s",
2443 qpim_rpf_cache_refresh_delay_msec
, VTY_NEWLINE
,
2444 pim_time_timer_remain_msec(qpim_rpf_cache_refresher
),
2445 VTY_NEWLINE
, (long long)qpim_rpf_cache_refresh_requests
,
2446 VTY_NEWLINE
, (long long)qpim_rpf_cache_refresh_events
,
2447 VTY_NEWLINE
, refresh_uptime
, VTY_NEWLINE
,
2448 (long long)qpim_nexthop_lookups
, VTY_NEWLINE
,
2449 (long long)nexthop_lookups_avoided
, VTY_NEWLINE
);
2453 static void show_scan_oil_stats(struct vty
*vty
, time_t now
)
2455 char uptime_scan_oil
[10];
2456 char uptime_mroute_add
[10];
2457 char uptime_mroute_del
[10];
2459 pim_time_uptime_begin(uptime_scan_oil
, sizeof(uptime_scan_oil
), now
,
2460 qpim_scan_oil_last
);
2461 pim_time_uptime_begin(uptime_mroute_add
, sizeof(uptime_mroute_add
), now
,
2462 qpim_mroute_add_last
);
2463 pim_time_uptime_begin(uptime_mroute_del
, sizeof(uptime_mroute_del
), now
,
2464 qpim_mroute_del_last
);
2467 "Scan OIL - Last: %s Events: %lld%s"
2468 "MFC Add - Last: %s Events: %lld%s"
2469 "MFC Del - Last: %s Events: %lld%s",
2470 uptime_scan_oil
, (long long)qpim_scan_oil_events
, VTY_NEWLINE
,
2471 uptime_mroute_add
, (long long)qpim_mroute_add_events
,
2472 VTY_NEWLINE
, uptime_mroute_del
,
2473 (long long)qpim_mroute_del_events
, VTY_NEWLINE
);
2476 static void pim_show_rpf(struct vty
*vty
, u_char uj
)
2478 struct listnode
*up_node
;
2479 struct pim_upstream
*up
;
2480 time_t now
= pim_time_monotonic_sec();
2481 json_object
*json
= NULL
;
2482 json_object
*json_group
= NULL
;
2483 json_object
*json_row
= NULL
;
2486 json
= json_object_new_object();
2487 show_rpf_refresh_stats(vty
, now
, json
);
2489 show_rpf_refresh_stats(vty
, now
, json
);
2490 vty_out(vty
, "%s", VTY_NEWLINE
);
2492 "Source Group RpfIface RpfAddress RibNextHop Metric Pref%s",
2496 for (ALL_LIST_ELEMENTS_RO(pim_upstream_list
, up_node
, up
)) {
2497 char src_str
[INET_ADDRSTRLEN
];
2498 char grp_str
[INET_ADDRSTRLEN
];
2499 char rpf_addr_str
[PREFIX_STRLEN
];
2500 char rib_nexthop_str
[PREFIX_STRLEN
];
2501 const char *rpf_ifname
;
2502 struct pim_rpf
*rpf
= &up
->rpf
;
2504 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2505 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2506 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2507 sizeof(rpf_addr_str
));
2508 pim_addr_dump("<nexthop?>",
2509 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2510 rib_nexthop_str
, sizeof(rib_nexthop_str
));
2512 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2515 json_object_object_get_ex(json
, grp_str
, &json_group
);
2518 json_group
= json_object_new_object();
2519 json_object_object_add(json
, grp_str
,
2523 json_row
= json_object_new_object();
2524 json_object_string_add(json_row
, "source", src_str
);
2525 json_object_string_add(json_row
, "group", grp_str
);
2526 json_object_string_add(json_row
, "rpfInterface",
2528 json_object_string_add(json_row
, "rpfAddress",
2530 json_object_string_add(json_row
, "ribNexthop",
2532 json_object_int_add(
2533 json_row
, "routeMetric",
2534 rpf
->source_nexthop
.mrib_route_metric
);
2535 json_object_int_add(
2536 json_row
, "routePreference",
2537 rpf
->source_nexthop
.mrib_metric_preference
);
2538 json_object_object_add(json_group
, src_str
, json_row
);
2541 vty_out(vty
, "%-15s %-15s %-8s %-15s %-15s %6d %4d%s",
2542 src_str
, grp_str
, rpf_ifname
, rpf_addr_str
,
2544 rpf
->source_nexthop
.mrib_route_metric
,
2545 rpf
->source_nexthop
.mrib_metric_preference
,
2551 vty_out(vty
, "%s%s", json_object_to_json_string_ext(
2552 json
, JSON_C_TO_STRING_PRETTY
),
2554 json_object_free(json
);
2558 static int pim_print_pnc_cache_walkcb(struct hash_backet
*backet
, void *arg
)
2560 struct pim_nexthop_cache
*pnc
= backet
->data
;
2561 struct vty
*vty
= arg
;
2562 struct nexthop
*nh_node
= NULL
;
2563 ifindex_t first_ifindex
;
2564 struct interface
*ifp
= NULL
;
2569 for (nh_node
= pnc
->nexthop
; nh_node
; nh_node
= nh_node
->next
) {
2570 first_ifindex
= nh_node
->ifindex
;
2571 ifp
= if_lookup_by_index(first_ifindex
, VRF_DEFAULT
);
2573 vty_out(vty
, "%-15s ", inet_ntoa(pnc
->rpf
.rpf_addr
.u
.prefix4
));
2574 vty_out(vty
, "%-14s ", ifp
? ifp
->name
: "NULL");
2575 vty_out(vty
, "%s ", inet_ntoa(nh_node
->gate
.ipv4
));
2576 vty_out(vty
, "%s", VTY_NEWLINE
);
2581 static void pim_show_nexthop(struct vty
*vty
)
2584 if (pimg
&& !pimg
->rpf_hash
) {
2585 vty_out(vty
, "no nexthop cache %s", VTY_NEWLINE
);
2589 vty_out(vty
, "Number of registered addresses: %lu %s",
2590 pimg
->rpf_hash
->count
, VTY_NEWLINE
);
2591 vty_out(vty
, "Address Interface Nexthop%s", VTY_NEWLINE
);
2592 vty_out(vty
, "-------------------------------------------%s",
2595 hash_walk(pimg
->rpf_hash
, pim_print_pnc_cache_walkcb
, vty
);
2598 static void igmp_show_groups(struct vty
*vty
, u_char uj
)
2600 struct listnode
*ifnode
;
2601 struct interface
*ifp
;
2603 json_object
*json
= NULL
;
2604 json_object
*json_iface
= NULL
;
2605 json_object
*json_row
= NULL
;
2607 now
= pim_time_monotonic_sec();
2610 json
= json_object_new_object();
2613 "Interface Address Group Mode Timer Srcs V Uptime %s",
2616 /* scan interfaces */
2617 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT
), ifnode
, ifp
)) {
2618 struct pim_interface
*pim_ifp
= ifp
->info
;
2619 struct listnode
*sock_node
;
2620 struct igmp_sock
*igmp
;
2625 /* scan igmp sockets */
2626 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
2628 char ifaddr_str
[INET_ADDRSTRLEN
];
2629 struct listnode
*grpnode
;
2630 struct igmp_group
*grp
;
2632 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
2633 sizeof(ifaddr_str
));
2635 /* scan igmp groups */
2636 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
2638 char group_str
[INET_ADDRSTRLEN
];
2642 pim_inet4_dump("<group?>", grp
->group_addr
,
2643 group_str
, sizeof(group_str
));
2644 pim_time_timer_to_hhmmss(hhmmss
, sizeof(hhmmss
),
2645 grp
->t_group_timer
);
2646 pim_time_uptime(uptime
, sizeof(uptime
),
2647 now
- grp
->group_creation
);
2650 json_object_object_get_ex(
2651 json
, ifp
->name
, &json_iface
);
2655 json_object_new_object();
2656 json_object_pim_ifp_add(
2658 json_object_object_add(
2663 json_row
= json_object_new_object();
2664 json_object_string_add(
2665 json_row
, "source", ifaddr_str
);
2666 json_object_string_add(
2667 json_row
, "group", group_str
);
2669 if (grp
->igmp_version
== 3)
2670 json_object_string_add(
2672 grp
->group_filtermode_isexcl
2676 json_object_string_add(json_row
,
2678 json_object_int_add(
2679 json_row
, "sourcesCount",
2680 grp
->group_source_list
2682 grp
->group_source_list
)
2684 json_object_int_add(json_row
, "version",
2686 json_object_string_add(
2687 json_row
, "uptime", uptime
);
2688 json_object_object_add(json_iface
,
2694 "%-9s %-15s %-15s %4s %8s %4d %d %8s%s",
2695 ifp
->name
, ifaddr_str
,
2697 grp
->igmp_version
== 3
2698 ? (grp
->group_filtermode_isexcl
2703 grp
->group_source_list
2705 grp
->group_source_list
)
2707 grp
->igmp_version
, uptime
,
2710 } /* scan igmp groups */
2711 } /* scan igmp sockets */
2712 } /* scan interfaces */
2715 vty_out(vty
, "%s%s", json_object_to_json_string_ext(
2716 json
, JSON_C_TO_STRING_PRETTY
),
2718 json_object_free(json
);
2722 static void igmp_show_group_retransmission(struct vty
*vty
)
2724 struct listnode
*ifnode
;
2725 struct interface
*ifp
;
2728 "Interface Address Group RetTimer Counter RetSrcs%s",
2731 /* scan interfaces */
2732 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT
), ifnode
, ifp
)) {
2733 struct pim_interface
*pim_ifp
= ifp
->info
;
2734 struct listnode
*sock_node
;
2735 struct igmp_sock
*igmp
;
2740 /* scan igmp sockets */
2741 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
2743 char ifaddr_str
[INET_ADDRSTRLEN
];
2744 struct listnode
*grpnode
;
2745 struct igmp_group
*grp
;
2747 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
2748 sizeof(ifaddr_str
));
2750 /* scan igmp groups */
2751 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
2753 char group_str
[INET_ADDRSTRLEN
];
2754 char grp_retr_mmss
[10];
2755 struct listnode
*src_node
;
2756 struct igmp_source
*src
;
2757 int grp_retr_sources
= 0;
2759 pim_inet4_dump("<group?>", grp
->group_addr
,
2760 group_str
, sizeof(group_str
));
2761 pim_time_timer_to_mmss(
2762 grp_retr_mmss
, sizeof(grp_retr_mmss
),
2763 grp
->t_group_query_retransmit_timer
);
2766 /* count group sources with retransmission state
2768 for (ALL_LIST_ELEMENTS_RO(
2769 grp
->group_source_list
, src_node
,
2771 if (src
->source_query_retransmit_count
2777 vty_out(vty
, "%-9s %-15s %-15s %-8s %7d %7d%s",
2778 ifp
->name
, ifaddr_str
, group_str
,
2780 grp
->group_specific_query_retransmit_count
,
2781 grp_retr_sources
, VTY_NEWLINE
);
2783 } /* scan igmp groups */
2784 } /* scan igmp sockets */
2785 } /* scan interfaces */
2788 static void igmp_show_sources(struct vty
*vty
)
2790 struct listnode
*ifnode
;
2791 struct interface
*ifp
;
2794 now
= pim_time_monotonic_sec();
2797 "Interface Address Group Source Timer Fwd Uptime %s",
2800 /* scan interfaces */
2801 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT
), ifnode
, ifp
)) {
2802 struct pim_interface
*pim_ifp
= ifp
->info
;
2803 struct listnode
*sock_node
;
2804 struct igmp_sock
*igmp
;
2809 /* scan igmp sockets */
2810 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
2812 char ifaddr_str
[INET_ADDRSTRLEN
];
2813 struct listnode
*grpnode
;
2814 struct igmp_group
*grp
;
2816 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
2817 sizeof(ifaddr_str
));
2819 /* scan igmp groups */
2820 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
2822 char group_str
[INET_ADDRSTRLEN
];
2823 struct listnode
*srcnode
;
2824 struct igmp_source
*src
;
2826 pim_inet4_dump("<group?>", grp
->group_addr
,
2827 group_str
, sizeof(group_str
));
2829 /* scan group sources */
2830 for (ALL_LIST_ELEMENTS_RO(
2831 grp
->group_source_list
, srcnode
,
2833 char source_str
[INET_ADDRSTRLEN
];
2838 "<source?>", src
->source_addr
,
2839 source_str
, sizeof(source_str
));
2841 pim_time_timer_to_mmss(
2843 src
->t_source_timer
);
2846 uptime
, sizeof(uptime
),
2847 now
- src
->source_creation
);
2850 "%-9s %-15s %-15s %-15s %5s %3s %8s%s",
2851 ifp
->name
, ifaddr_str
,
2852 group_str
, source_str
, mmss
,
2853 IGMP_SOURCE_TEST_FORWARDING(
2857 uptime
, VTY_NEWLINE
);
2859 } /* scan group sources */
2860 } /* scan igmp groups */
2861 } /* scan igmp sockets */
2862 } /* scan interfaces */
2865 static void igmp_show_source_retransmission(struct vty
*vty
)
2867 struct listnode
*ifnode
;
2868 struct interface
*ifp
;
2871 "Interface Address Group Source Counter%s",
2874 /* scan interfaces */
2875 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT
), ifnode
, ifp
)) {
2876 struct pim_interface
*pim_ifp
= ifp
->info
;
2877 struct listnode
*sock_node
;
2878 struct igmp_sock
*igmp
;
2883 /* scan igmp sockets */
2884 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
2886 char ifaddr_str
[INET_ADDRSTRLEN
];
2887 struct listnode
*grpnode
;
2888 struct igmp_group
*grp
;
2890 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
2891 sizeof(ifaddr_str
));
2893 /* scan igmp groups */
2894 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
2896 char group_str
[INET_ADDRSTRLEN
];
2897 struct listnode
*srcnode
;
2898 struct igmp_source
*src
;
2900 pim_inet4_dump("<group?>", grp
->group_addr
,
2901 group_str
, sizeof(group_str
));
2903 /* scan group sources */
2904 for (ALL_LIST_ELEMENTS_RO(
2905 grp
->group_source_list
, srcnode
,
2907 char source_str
[INET_ADDRSTRLEN
];
2910 "<source?>", src
->source_addr
,
2911 source_str
, sizeof(source_str
));
2914 "%-9s %-15s %-15s %-15s %7d%s",
2915 ifp
->name
, ifaddr_str
,
2916 group_str
, source_str
,
2917 src
->source_query_retransmit_count
,
2920 } /* scan group sources */
2921 } /* scan igmp groups */
2922 } /* scan igmp sockets */
2923 } /* scan interfaces */
2926 static void clear_igmp_interfaces()
2928 struct listnode
*ifnode
;
2929 struct listnode
*ifnextnode
;
2930 struct interface
*ifp
;
2932 for (ALL_LIST_ELEMENTS(vrf_iflist(VRF_DEFAULT
), ifnode
, ifnextnode
,
2934 pim_if_addr_del_all_igmp(ifp
);
2937 for (ALL_LIST_ELEMENTS(vrf_iflist(VRF_DEFAULT
), ifnode
, ifnextnode
,
2939 pim_if_addr_add_all(ifp
);
2943 static void clear_pim_interfaces()
2945 struct listnode
*ifnode
;
2946 struct listnode
*ifnextnode
;
2947 struct interface
*ifp
;
2949 for (ALL_LIST_ELEMENTS(vrf_iflist(VRF_DEFAULT
), ifnode
, ifnextnode
,
2952 pim_neighbor_delete_all(ifp
, "interface cleared");
2957 static void clear_interfaces()
2959 clear_igmp_interfaces();
2960 clear_pim_interfaces();
2963 DEFUN (clear_ip_interfaces
,
2964 clear_ip_interfaces_cmd
,
2965 "clear ip interfaces",
2968 "Reset interfaces\n")
2975 DEFUN (clear_ip_igmp_interfaces
,
2976 clear_ip_igmp_interfaces_cmd
,
2977 "clear ip igmp interfaces",
2981 "Reset IGMP interfaces\n")
2983 clear_igmp_interfaces();
2988 static void mroute_add_all()
2990 struct listnode
*node
;
2991 struct channel_oil
*c_oil
;
2993 for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list
, node
, c_oil
)) {
2994 if (pim_mroute_add(c_oil
, __PRETTY_FUNCTION__
)) {
2995 /* just log warning */
2996 char source_str
[INET_ADDRSTRLEN
];
2997 char group_str
[INET_ADDRSTRLEN
];
2998 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
,
2999 source_str
, sizeof(source_str
));
3000 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
,
3001 group_str
, sizeof(group_str
));
3002 zlog_warn("%s %s: (S,G)=(%s,%s) failure writing MFC",
3003 __FILE__
, __PRETTY_FUNCTION__
, source_str
,
3009 static void mroute_del_all()
3011 struct listnode
*node
;
3012 struct channel_oil
*c_oil
;
3014 for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list
, node
, c_oil
)) {
3015 if (pim_mroute_del(c_oil
, __PRETTY_FUNCTION__
)) {
3016 /* just log warning */
3017 char source_str
[INET_ADDRSTRLEN
];
3018 char group_str
[INET_ADDRSTRLEN
];
3019 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
,
3020 source_str
, sizeof(source_str
));
3021 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
,
3022 group_str
, sizeof(group_str
));
3023 zlog_warn("%s %s: (S,G)=(%s,%s) failure clearing MFC",
3024 __FILE__
, __PRETTY_FUNCTION__
, source_str
,
3030 DEFUN (clear_ip_mroute
,
3031 clear_ip_mroute_cmd
,
3035 "Reset multicast routes\n")
3043 DEFUN (clear_ip_pim_interfaces
,
3044 clear_ip_pim_interfaces_cmd
,
3045 "clear ip pim interfaces",
3049 "Reset PIM interfaces\n")
3051 clear_pim_interfaces();
3056 DEFUN (clear_ip_pim_oil
,
3057 clear_ip_pim_oil_cmd
,
3062 "Rescan PIM OIL (output interface list)\n")
3069 DEFUN (show_ip_igmp_interface
,
3070 show_ip_igmp_interface_cmd
,
3071 "show ip igmp interface [detail|WORD] [json]",
3075 "IGMP interface information\n"
3078 "JavaScript Object Notation\n")
3080 u_char uj
= use_json(argc
, argv
);
3083 if (argv_find(argv
, argc
, "detail", &idx
)
3084 || argv_find(argv
, argc
, "WORD", &idx
))
3085 igmp_show_interfaces_single(vty
, argv
[idx
]->arg
, uj
);
3087 igmp_show_interfaces(vty
, uj
);
3092 DEFUN (show_ip_igmp_join
,
3093 show_ip_igmp_join_cmd
,
3094 "show ip igmp join",
3098 "IGMP static join information\n")
3100 igmp_show_interface_join(vty
);
3105 DEFUN (show_ip_igmp_groups
,
3106 show_ip_igmp_groups_cmd
,
3107 "show ip igmp groups [json]",
3112 "JavaScript Object Notation\n")
3114 u_char uj
= use_json(argc
, argv
);
3115 igmp_show_groups(vty
, uj
);
3120 DEFUN (show_ip_igmp_groups_retransmissions
,
3121 show_ip_igmp_groups_retransmissions_cmd
,
3122 "show ip igmp groups retransmissions",
3127 "IGMP group retransmissions\n")
3129 igmp_show_group_retransmission(vty
);
3134 DEFUN (show_ip_igmp_sources
,
3135 show_ip_igmp_sources_cmd
,
3136 "show ip igmp sources",
3142 igmp_show_sources(vty
);
3147 DEFUN (show_ip_igmp_sources_retransmissions
,
3148 show_ip_igmp_sources_retransmissions_cmd
,
3149 "show ip igmp sources retransmissions",
3154 "IGMP source retransmissions\n")
3156 igmp_show_source_retransmission(vty
);
3161 DEFUN (show_ip_pim_assert
,
3162 show_ip_pim_assert_cmd
,
3163 "show ip pim assert",
3167 "PIM interface assert\n")
3169 pim_show_assert(vty
);
3174 DEFUN (show_ip_pim_assert_internal
,
3175 show_ip_pim_assert_internal_cmd
,
3176 "show ip pim assert-internal",
3180 "PIM interface internal assert state\n")
3182 pim_show_assert_internal(vty
);
3187 DEFUN (show_ip_pim_assert_metric
,
3188 show_ip_pim_assert_metric_cmd
,
3189 "show ip pim assert-metric",
3193 "PIM interface assert metric\n")
3195 pim_show_assert_metric(vty
);
3200 DEFUN (show_ip_pim_assert_winner_metric
,
3201 show_ip_pim_assert_winner_metric_cmd
,
3202 "show ip pim assert-winner-metric",
3206 "PIM interface assert winner metric\n")
3208 pim_show_assert_winner_metric(vty
);
3213 DEFUN (show_ip_pim_interface
,
3214 show_ip_pim_interface_cmd
,
3215 "show ip pim interface [detail|WORD] [json]",
3219 "PIM interface information\n"
3222 "JavaScript Object Notation\n")
3224 u_char uj
= use_json(argc
, argv
);
3227 if (argv_find(argv
, argc
, "WORD", &idx
)
3228 || argv_find(argv
, argc
, "detail", &idx
))
3229 pim_show_interfaces_single(vty
, argv
[idx
]->arg
, uj
);
3232 pim_show_interfaces(vty
, uj
);
3237 DEFUN (show_ip_pim_join
,
3238 show_ip_pim_join_cmd
,
3239 "show ip pim join [json]",
3243 "PIM interface join information\n"
3246 u_char uj
= use_json(argc
, argv
);
3247 pim_show_join(vty
, uj
);
3252 DEFUN (show_ip_pim_local_membership
,
3253 show_ip_pim_local_membership_cmd
,
3254 "show ip pim local-membership [json]",
3258 "PIM interface local-membership\n"
3261 u_char uj
= use_json(argc
, argv
);
3262 pim_show_membership(vty
, uj
);
3267 DEFUN (show_ip_pim_neighbor
,
3268 show_ip_pim_neighbor_cmd
,
3269 "show ip pim neighbor [detail|WORD] [json]",
3273 "PIM neighbor information\n"
3275 "Name of interface or neighbor\n"
3276 "JavaScript Object Notation\n")
3278 u_char uj
= use_json(argc
, argv
);
3281 if (argv_find(argv
, argc
, "detail", &idx
)
3282 || argv_find(argv
, argc
, "WORD", &idx
))
3283 pim_show_neighbors_single(vty
, argv
[idx
]->arg
, uj
);
3285 pim_show_neighbors(vty
, uj
);
3290 DEFUN (show_ip_pim_secondary
,
3291 show_ip_pim_secondary_cmd
,
3292 "show ip pim secondary",
3296 "PIM neighbor addresses\n")
3298 pim_show_neighbors_secondary(vty
);
3303 DEFUN (show_ip_pim_state
,
3304 show_ip_pim_state_cmd
,
3305 "show ip pim state [A.B.C.D [A.B.C.D]] [json]",
3309 "PIM state information\n"
3310 "Unicast or Multicast address\n"
3311 "Multicast address\n"
3312 "JavaScript Object Notation\n")
3314 const char *src_or_group
= NULL
;
3315 const char *group
= NULL
;
3316 u_char uj
= use_json(argc
, argv
);
3321 src_or_group
= argv
[4]->arg
;
3322 group
= argv
[5]->arg
;
3323 } else if (argc
== 5)
3324 src_or_group
= argv
[4]->arg
;
3326 pim_show_state(vty
, src_or_group
, group
, uj
);
3331 DEFUN (show_ip_pim_upstream
,
3332 show_ip_pim_upstream_cmd
,
3333 "show ip pim upstream [json]",
3337 "PIM upstream information\n"
3338 "JavaScript Object Notation\n")
3340 u_char uj
= use_json(argc
, argv
);
3341 pim_show_upstream(vty
, uj
);
3346 DEFUN (show_ip_pim_upstream_join_desired
,
3347 show_ip_pim_upstream_join_desired_cmd
,
3348 "show ip pim upstream-join-desired [json]",
3352 "PIM upstream join-desired\n"
3353 "JavaScript Object Notation\n")
3355 u_char uj
= use_json(argc
, argv
);
3356 pim_show_join_desired(vty
, uj
);
3361 DEFUN (show_ip_pim_upstream_rpf
,
3362 show_ip_pim_upstream_rpf_cmd
,
3363 "show ip pim upstream-rpf [json]",
3367 "PIM upstream source rpf\n"
3368 "JavaScript Object Notation\n")
3370 u_char uj
= use_json(argc
, argv
);
3371 pim_show_upstream_rpf(vty
, uj
);
3376 DEFUN (show_ip_pim_rp
,
3378 "show ip pim rp-info [json]",
3382 "PIM RP information\n"
3383 "JavaScript Object Notation\n")
3385 u_char uj
= use_json(argc
, argv
);
3386 pim_rp_show_information(vty
, uj
);
3391 DEFUN (show_ip_pim_rpf
,
3392 show_ip_pim_rpf_cmd
,
3393 "show ip pim rpf [json]",
3397 "PIM cached source rpf information\n"
3398 "JavaScript Object Notation\n")
3400 u_char uj
= use_json(argc
, argv
);
3401 pim_show_rpf(vty
, uj
);
3406 DEFUN (show_ip_pim_nexthop
,
3407 show_ip_pim_nexthop_cmd
,
3408 "show ip pim nexthop",
3412 "PIM cached nexthop rpf information\n")
3414 pim_show_nexthop(vty
);
3419 DEFUN (show_ip_pim_nexthop_lookup
,
3420 show_ip_pim_nexthop_lookup_cmd
,
3421 "show ip pim nexthop-lookup A.B.C.D A.B.C.D",
3425 "PIM cached nexthop rpf lookup\n"
3426 "Source/RP address\n"
3427 "Multicast Group address\n")
3429 struct pim_nexthop_cache pnc
;
3430 struct prefix nht_p
;
3432 struct in_addr src_addr
, grp_addr
;
3433 struct in_addr vif_source
;
3434 const char *addr_str
, *addr_str1
;
3436 struct pim_nexthop nexthop
;
3437 char nexthop_addr_str
[PREFIX_STRLEN
];
3438 char grp_str
[PREFIX_STRLEN
];
3440 addr_str
= (const char *)argv
[0];
3441 result
= inet_pton(AF_INET
, addr_str
, &src_addr
);
3443 vty_out(vty
, "Bad unicast address %s: errno=%d: %s%s", addr_str
,
3444 errno
, safe_strerror(errno
), VTY_NEWLINE
);
3448 if (pim_is_group_224_4(src_addr
)) {
3450 "Invalid argument. Expected Valid Source Address.%s",
3455 addr_str1
= (const char *)argv
[1];
3456 result
= inet_pton(AF_INET
, addr_str1
, &grp_addr
);
3458 vty_out(vty
, "Bad unicast address %s: errno=%d: %s%s", addr_str
,
3459 errno
, safe_strerror(errno
), VTY_NEWLINE
);
3463 if (!pim_is_group_224_4(grp_addr
)) {
3465 "Invalid argument. Expected Valid Multicast Group Address.%s",
3470 if (!pim_rp_set_upstream_addr(&vif_source
, src_addr
, grp_addr
))
3473 memset(&pnc
, 0, sizeof(struct pim_nexthop_cache
));
3474 nht_p
.family
= AF_INET
;
3475 nht_p
.prefixlen
= IPV4_MAX_BITLEN
;
3476 nht_p
.u
.prefix4
= vif_source
;
3477 grp
.family
= AF_INET
;
3478 grp
.prefixlen
= IPV4_MAX_BITLEN
;
3479 grp
.u
.prefix4
= grp_addr
;
3480 memset(&nexthop
, 0, sizeof(nexthop
));
3482 if ((pim_find_or_track_nexthop(&nht_p
, NULL
, NULL
, &pnc
)) == 1) {
3483 // Compute PIM RPF using Cached nexthop
3484 pim_ecmp_nexthop_search(&pnc
, &nexthop
, &nht_p
, &grp
, 0);
3486 pim_ecmp_nexthop_lookup(&nexthop
, vif_source
, &nht_p
, &grp
, 0);
3488 pim_addr_dump("<grp?>", &grp
, grp_str
, sizeof(grp_str
));
3489 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
3490 nexthop_addr_str
, sizeof(nexthop_addr_str
));
3491 vty_out(vty
, "Group %s --- Nexthop %s Interface %s %s", grp_str
,
3492 nexthop_addr_str
, nexthop
.interface
->name
, VTY_NEWLINE
);
3497 static void show_multicast_interfaces(struct vty
*vty
)
3499 struct listnode
*node
;
3500 struct interface
*ifp
;
3502 vty_out(vty
, "%s", VTY_NEWLINE
);
3505 "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut%s",
3508 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT
), node
, ifp
)) {
3509 struct pim_interface
*pim_ifp
;
3510 struct in_addr ifaddr
;
3511 struct sioc_vif_req vreq
;
3513 pim_ifp
= ifp
->info
;
3518 memset(&vreq
, 0, sizeof(vreq
));
3519 vreq
.vifi
= pim_ifp
->mroute_vif_index
;
3521 if (ioctl(qpim_mroute_socket_fd
, SIOCGETVIFCNT
, &vreq
)) {
3523 "ioctl(SIOCGETVIFCNT=%lu) failure for interface %s vif_index=%d: errno=%d: %s%s",
3524 (unsigned long)SIOCGETVIFCNT
, ifp
->name
,
3525 pim_ifp
->mroute_vif_index
, errno
,
3526 safe_strerror(errno
), VTY_NEWLINE
);
3529 ifaddr
= pim_ifp
->primary_address
;
3531 vty_out(vty
, "%-9s %-15s %3d %3d %7lu %7lu %10lu %10lu%s",
3532 ifp
->name
, inet_ntoa(ifaddr
), ifp
->ifindex
,
3533 pim_ifp
->mroute_vif_index
, (unsigned long)vreq
.icount
,
3534 (unsigned long)vreq
.ocount
, (unsigned long)vreq
.ibytes
,
3535 (unsigned long)vreq
.obytes
, VTY_NEWLINE
);
3539 DEFUN (show_ip_multicast
,
3540 show_ip_multicast_cmd
,
3541 "show ip multicast",
3544 "Multicast global information\n")
3546 time_t now
= pim_time_monotonic_sec();
3550 vty_out(vty
, "Mroute socket descriptor: %d%s", qpim_mroute_socket_fd
,
3553 pim_time_uptime(uptime
, sizeof(uptime
),
3554 now
- qpim_mroute_socket_creation
);
3555 vty_out(vty
, "Mroute socket uptime: %s%s", uptime
, VTY_NEWLINE
);
3557 vty_out(vty
, "%s", VTY_NEWLINE
);
3559 pim_zebra_zclient_update(vty
);
3560 pim_zlookup_show_ip_multicast(vty
);
3562 vty_out(vty
, "%s", VTY_NEWLINE
);
3563 vty_out(vty
, "Maximum highest VifIndex: %d%s", PIM_MAX_USABLE_VIFS
,
3566 vty_out(vty
, "%s", VTY_NEWLINE
);
3567 vty_out(vty
, "Upstream Join Timer: %d secs%s", qpim_t_periodic
,
3569 vty_out(vty
, "Join/Prune Holdtime: %d secs%s", PIM_JP_HOLDTIME
,
3571 vty_out(vty
, "PIM ECMP: %s%s", qpim_ecmp_enable
? "Enable" : "Disable",
3573 vty_out(vty
, "PIM ECMP Rebalance: %s%s",
3574 qpim_ecmp_rebalance_enable
? "Enable" : "Disable", VTY_NEWLINE
);
3576 vty_out(vty
, "%s", VTY_NEWLINE
);
3578 show_rpf_refresh_stats(vty
, now
, NULL
);
3580 vty_out(vty
, "%s", VTY_NEWLINE
);
3582 show_scan_oil_stats(vty
, now
);
3584 show_multicast_interfaces(vty
);
3589 static void show_mroute(struct vty
*vty
, u_char uj
)
3591 struct listnode
*node
;
3592 struct channel_oil
*c_oil
;
3593 struct static_route
*s_route
;
3595 json_object
*json
= NULL
;
3596 json_object
*json_group
= NULL
;
3597 json_object
*json_source
= NULL
;
3598 json_object
*json_oil
= NULL
;
3599 json_object
*json_ifp_out
= NULL
;
3602 char grp_str
[INET_ADDRSTRLEN
];
3603 char src_str
[INET_ADDRSTRLEN
];
3604 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
3605 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
3607 struct interface
*ifp_in
;
3611 json
= json_object_new_object();
3614 "Source Group Proto Input Output TTL Uptime%s",
3618 now
= pim_time_monotonic_sec();
3620 /* print list of PIM and IGMP routes */
3621 for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list
, node
, c_oil
)) {
3624 if (!c_oil
->installed
&& !uj
)
3627 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
3629 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
3631 ifp_in
= pim_if_find_by_vif_index(c_oil
->oil
.mfcc_parent
);
3634 strcpy(in_ifname
, ifp_in
->name
);
3636 strcpy(in_ifname
, "<iif?>");
3640 /* Find the group, create it if it doesn't exist */
3641 json_object_object_get_ex(json
, grp_str
, &json_group
);
3644 json_group
= json_object_new_object();
3645 json_object_object_add(json
, grp_str
,
3649 /* Find the source nested under the group, create it if
3650 * it doesn't exist */
3651 json_object_object_get_ex(json_group
, src_str
,
3655 json_source
= json_object_new_object();
3656 json_object_object_add(json_group
, src_str
,
3660 /* Find the inbound interface nested under the source,
3661 * create it if it doesn't exist */
3662 json_object_int_add(json_source
, "installed",
3664 json_object_int_add(json_source
, "refCount",
3665 c_oil
->oil_ref_count
);
3666 json_object_int_add(json_source
, "oilSize",
3668 json_object_int_add(json_source
, "OilInheritedRescan",
3669 c_oil
->oil_inherited_rescan
);
3670 json_object_string_add(json_source
, "iif", in_ifname
);
3674 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
3676 struct interface
*ifp_out
;
3677 char oif_uptime
[10];
3680 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
3684 ifp_out
= pim_if_find_by_vif_index(oif_vif_index
);
3686 oif_uptime
, sizeof(oif_uptime
),
3687 now
- c_oil
->oif_creation
[oif_vif_index
]);
3691 strcpy(out_ifname
, ifp_out
->name
);
3693 strcpy(out_ifname
, "<oif?>");
3696 json_ifp_out
= json_object_new_object();
3697 json_object_string_add(json_ifp_out
, "source",
3699 json_object_string_add(json_ifp_out
, "group",
3702 if (c_oil
->oif_flags
[oif_vif_index
]
3703 & PIM_OIF_FLAG_PROTO_PIM
)
3704 json_object_boolean_true_add(
3705 json_ifp_out
, "protocolPim");
3707 if (c_oil
->oif_flags
[oif_vif_index
]
3708 & PIM_OIF_FLAG_PROTO_IGMP
)
3709 json_object_boolean_true_add(
3710 json_ifp_out
, "protocolIgmp");
3712 if (c_oil
->oif_flags
[oif_vif_index
]
3713 & PIM_OIF_FLAG_PROTO_SOURCE
)
3714 json_object_boolean_true_add(
3715 json_ifp_out
, "protocolSource");
3717 if (c_oil
->oif_flags
[oif_vif_index
]
3718 & PIM_OIF_FLAG_PROTO_STAR
)
3719 json_object_boolean_true_add(
3721 "protocolInherited");
3723 json_object_string_add(json_ifp_out
,
3726 json_object_int_add(json_ifp_out
, "iVifI",
3727 c_oil
->oil
.mfcc_parent
);
3728 json_object_string_add(json_ifp_out
,
3729 "outboundInterface",
3731 json_object_int_add(json_ifp_out
, "oVifI",
3733 json_object_int_add(json_ifp_out
, "ttl", ttl
);
3734 json_object_string_add(json_ifp_out
, "upTime",
3737 json_oil
= json_object_new_object();
3738 json_object_object_add(json_source
,
3741 json_object_object_add(json_oil
, out_ifname
,
3744 if (c_oil
->oif_flags
[oif_vif_index
]
3745 & PIM_OIF_FLAG_PROTO_PIM
) {
3746 strcpy(proto
, "PIM");
3749 if (c_oil
->oif_flags
[oif_vif_index
]
3750 & PIM_OIF_FLAG_PROTO_IGMP
) {
3751 strcpy(proto
, "IGMP");
3754 if (c_oil
->oif_flags
[oif_vif_index
]
3755 & PIM_OIF_FLAG_PROTO_SOURCE
) {
3756 strcpy(proto
, "SRC");
3759 if (c_oil
->oif_flags
[oif_vif_index
]
3760 & PIM_OIF_FLAG_PROTO_STAR
) {
3761 strcpy(proto
, "STAR");
3765 "%-15s %-15s %-6s %-10s %-10s %-3d %8s%s",
3766 src_str
, grp_str
, proto
, in_ifname
,
3767 out_ifname
, ttl
, oif_uptime
,
3773 in_ifname
[0] = '\0';
3779 if (!uj
&& !found_oif
) {
3780 vty_out(vty
, "%-15s %-15s %-6s %-10s %-10s %-3d %8s%s",
3781 src_str
, grp_str
, "none", in_ifname
, "none", 0,
3782 "--:--:--", VTY_NEWLINE
);
3786 /* Print list of static routes */
3787 for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list
, node
, s_route
)) {
3790 if (!s_route
->c_oil
.installed
)
3793 pim_inet4_dump("<group?>", s_route
->group
, grp_str
,
3795 pim_inet4_dump("<source?>", s_route
->source
, src_str
,
3797 ifp_in
= pim_if_find_by_vif_index(s_route
->iif
);
3801 strcpy(in_ifname
, ifp_in
->name
);
3803 strcpy(in_ifname
, "<iif?>");
3807 /* Find the group, create it if it doesn't exist */
3808 json_object_object_get_ex(json
, grp_str
, &json_group
);
3811 json_group
= json_object_new_object();
3812 json_object_object_add(json
, grp_str
,
3816 /* Find the source nested under the group, create it if
3817 * it doesn't exist */
3818 json_object_object_get_ex(json_group
, src_str
,
3822 json_source
= json_object_new_object();
3823 json_object_object_add(json_group
, src_str
,
3827 json_object_string_add(json_source
, "iif", in_ifname
);
3830 strcpy(proto
, "STATIC");
3833 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
3835 struct interface
*ifp_out
;
3836 char oif_uptime
[10];
3839 ttl
= s_route
->oif_ttls
[oif_vif_index
];
3843 ifp_out
= pim_if_find_by_vif_index(oif_vif_index
);
3845 oif_uptime
, sizeof(oif_uptime
),
3848 .oif_creation
[oif_vif_index
]);
3852 strcpy(out_ifname
, ifp_out
->name
);
3854 strcpy(out_ifname
, "<oif?>");
3857 json_ifp_out
= json_object_new_object();
3858 json_object_string_add(json_ifp_out
, "source",
3860 json_object_string_add(json_ifp_out
, "group",
3862 json_object_boolean_true_add(json_ifp_out
,
3864 json_object_string_add(json_ifp_out
,
3867 json_object_int_add(
3868 json_ifp_out
, "iVifI",
3869 s_route
->c_oil
.oil
.mfcc_parent
);
3870 json_object_string_add(json_ifp_out
,
3871 "outboundInterface",
3873 json_object_int_add(json_ifp_out
, "oVifI",
3875 json_object_int_add(json_ifp_out
, "ttl", ttl
);
3876 json_object_string_add(json_ifp_out
, "upTime",
3879 json_oil
= json_object_new_object();
3880 json_object_object_add(json_source
,
3883 json_object_object_add(json_oil
, out_ifname
,
3887 "%-15s %-15s %-6s %-10s %-10s %-3d %8s%s",
3888 src_str
, grp_str
, proto
, in_ifname
,
3889 out_ifname
, ttl
, oif_uptime
,
3894 in_ifname
[0] = '\0';
3900 if (!uj
&& !found_oif
) {
3901 vty_out(vty
, "%-15s %-15s %-6s %-10s %-10s %-3d %8s%s",
3902 src_str
, grp_str
, proto
, in_ifname
, "none", 0,
3903 "--:--:--", VTY_NEWLINE
);
3908 vty_out(vty
, "%s%s", json_object_to_json_string_ext(
3909 json
, JSON_C_TO_STRING_PRETTY
),
3911 json_object_free(json
);
3915 DEFUN (show_ip_mroute
,
3917 "show ip mroute [json]",
3923 u_char uj
= use_json(argc
, argv
);
3924 show_mroute(vty
, uj
);
3928 static void show_mroute_count(struct vty
*vty
)
3930 struct listnode
*node
;
3931 struct channel_oil
*c_oil
;
3932 struct static_route
*s_route
;
3934 vty_out(vty
, "%s", VTY_NEWLINE
);
3937 "Source Group LastUsed Packets Bytes WrongIf %s",
3940 /* Print PIM and IGMP route counts */
3941 for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list
, node
, c_oil
)) {
3942 char group_str
[INET_ADDRSTRLEN
];
3943 char source_str
[INET_ADDRSTRLEN
];
3945 if (!c_oil
->installed
)
3948 pim_mroute_update_counters(c_oil
);
3950 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, group_str
,
3952 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, source_str
,
3953 sizeof(source_str
));
3955 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld%s",
3956 source_str
, group_str
, c_oil
->cc
.lastused
/ 100,
3957 c_oil
->cc
.pktcnt
, c_oil
->cc
.bytecnt
, c_oil
->cc
.wrong_if
,
3961 /* Print static route counts */
3962 for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list
, node
, s_route
)) {
3963 char group_str
[INET_ADDRSTRLEN
];
3964 char source_str
[INET_ADDRSTRLEN
];
3966 if (!s_route
->c_oil
.installed
)
3969 pim_mroute_update_counters(&s_route
->c_oil
);
3971 pim_inet4_dump("<group?>", s_route
->c_oil
.oil
.mfcc_mcastgrp
,
3972 group_str
, sizeof(group_str
));
3973 pim_inet4_dump("<source?>", s_route
->c_oil
.oil
.mfcc_origin
,
3974 source_str
, sizeof(source_str
));
3976 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld%s",
3977 source_str
, group_str
, s_route
->c_oil
.cc
.lastused
,
3978 s_route
->c_oil
.cc
.pktcnt
, s_route
->c_oil
.cc
.bytecnt
,
3979 s_route
->c_oil
.cc
.wrong_if
, VTY_NEWLINE
);
3983 DEFUN (show_ip_mroute_count
,
3984 show_ip_mroute_count_cmd
,
3985 "show ip mroute count",
3989 "Route and packet count data\n")
3991 show_mroute_count(vty
);
3997 "show ip rib A.B.C.D",
4001 "Unicast address\n")
4004 struct in_addr addr
;
4005 const char *addr_str
;
4006 struct pim_nexthop nexthop
;
4007 char nexthop_addr_str
[PREFIX_STRLEN
];
4010 memset(&nexthop
, 0, sizeof(nexthop
));
4011 addr_str
= argv
[idx_ipv4
]->arg
;
4012 result
= inet_pton(AF_INET
, addr_str
, &addr
);
4014 vty_out(vty
, "Bad unicast address %s: errno=%d: %s%s", addr_str
,
4015 errno
, safe_strerror(errno
), VTY_NEWLINE
);
4019 if (pim_nexthop_lookup(&nexthop
, addr
, 0)) {
4021 "Failure querying RIB nexthop for unicast address %s%s",
4022 addr_str
, VTY_NEWLINE
);
4027 "Address NextHop Interface Metric Preference%s",
4030 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
4031 nexthop_addr_str
, sizeof(nexthop_addr_str
));
4033 vty_out(vty
, "%-15s %-15s %-9s %6d %10d%s", addr_str
, nexthop_addr_str
,
4034 nexthop
.interface
? nexthop
.interface
->name
: "<ifname?>",
4035 nexthop
.mrib_route_metric
, nexthop
.mrib_metric_preference
,
4041 static void show_ssmpingd(struct vty
*vty
)
4043 struct listnode
*node
;
4044 struct ssmpingd_sock
*ss
;
4048 "Source Socket Address Port Uptime Requests%s",
4051 if (!qpim_ssmpingd_list
)
4054 now
= pim_time_monotonic_sec();
4056 for (ALL_LIST_ELEMENTS_RO(qpim_ssmpingd_list
, node
, ss
)) {
4057 char source_str
[INET_ADDRSTRLEN
];
4059 struct sockaddr_in bind_addr
;
4060 socklen_t len
= sizeof(bind_addr
);
4061 char bind_addr_str
[INET_ADDRSTRLEN
];
4063 pim_inet4_dump("<src?>", ss
->source_addr
, source_str
,
4064 sizeof(source_str
));
4066 if (pim_socket_getsockname(
4067 ss
->sock_fd
, (struct sockaddr
*)&bind_addr
, &len
)) {
4069 "%% Failure reading socket name for ssmpingd source %s on fd=%d%s",
4070 source_str
, ss
->sock_fd
, VTY_NEWLINE
);
4073 pim_inet4_dump("<addr?>", bind_addr
.sin_addr
, bind_addr_str
,
4074 sizeof(bind_addr_str
));
4075 pim_time_uptime(ss_uptime
, sizeof(ss_uptime
),
4076 now
- ss
->creation
);
4078 vty_out(vty
, "%-15s %6d %-15s %5d %8s %8lld%s", source_str
,
4079 ss
->sock_fd
, bind_addr_str
, ntohs(bind_addr
.sin_port
),
4080 ss_uptime
, (long long)ss
->requests
, VTY_NEWLINE
);
4084 DEFUN (show_ip_ssmpingd
,
4085 show_ip_ssmpingd_cmd
,
4095 static int pim_rp_cmd_worker(struct vty
*vty
, const char *rp
, const char *group
,
4100 result
= pim_rp_new(rp
, group
, plist
);
4102 if (result
== PIM_MALLOC_FAIL
) {
4103 vty_out(vty
, "%% Out of memory%s", VTY_NEWLINE
);
4107 if (result
== PIM_GROUP_BAD_ADDRESS
) {
4108 vty_out(vty
, "%% Bad group address specified: %s%s", group
,
4113 if (result
== PIM_RP_BAD_ADDRESS
) {
4114 vty_out(vty
, "%% Bad RP address specified: %s%s", rp
,
4119 if (result
== PIM_RP_NO_PATH
) {
4120 vty_out(vty
, "%% No Path to RP address specified: %s%s", rp
,
4125 if (result
== PIM_GROUP_OVERLAP
) {
4126 vty_out(vty
, "%% Group range specified cannot overlap%s",
4131 if (result
== PIM_GROUP_PFXLIST_OVERLAP
) {
4133 "%% This group is already covered by a RP prefix-list%s",
4138 if (result
== PIM_RP_PFXLIST_IN_USE
) {
4140 "%% The same prefix-list cannot be applied to multiple RPs%s",
4148 static int pim_cmd_spt_switchover(enum pim_spt_switchover spt
,
4151 pimg
->spt
.switchover
= spt
;
4153 switch (pimg
->spt
.switchover
) {
4154 case PIM_SPT_IMMEDIATE
:
4155 if (pimg
->spt
.plist
)
4156 XFREE(MTYPE_PIM_SPT_PLIST_NAME
, pimg
->spt
.plist
);
4158 pim_upstream_add_lhr_star_pimreg();
4160 case PIM_SPT_INFINITY
:
4161 pim_upstream_remove_lhr_star_pimreg(plist
);
4163 if (pimg
->spt
.plist
)
4164 XFREE(MTYPE_PIM_SPT_PLIST_NAME
, pimg
->spt
.plist
);
4168 XSTRDUP(MTYPE_PIM_SPT_PLIST_NAME
, plist
);
4175 DEFUN (ip_pim_spt_switchover_infinity
,
4176 ip_pim_spt_switchover_infinity_cmd
,
4177 "ip pim spt-switchover infinity-and-beyond",
4181 "Never switch to SPT Tree\n")
4183 return pim_cmd_spt_switchover(PIM_SPT_INFINITY
, NULL
);
4186 DEFUN (ip_pim_spt_switchover_infinity_plist
,
4187 ip_pim_spt_switchover_infinity_plist_cmd
,
4188 "ip pim spt-switchover infinity-and-beyond prefix-list WORD",
4192 "Never switch to SPT Tree\n"
4193 "Prefix-List to control which groups to switch\n"
4194 "Prefix-List name\n")
4196 return pim_cmd_spt_switchover(PIM_SPT_INFINITY
, argv
[5]->arg
);
4199 DEFUN (no_ip_pim_spt_switchover_infinity
,
4200 no_ip_pim_spt_switchover_infinity_cmd
,
4201 "no ip pim spt-switchover infinity-and-beyond",
4206 "Never switch to SPT Tree\n")
4208 return pim_cmd_spt_switchover(PIM_SPT_IMMEDIATE
, NULL
);
4211 DEFUN (no_ip_pim_spt_switchover_infinity_plist
,
4212 no_ip_pim_spt_switchover_infinity_plist_cmd
,
4213 "no ip pim spt-switchover infinity-and-beyond prefix-list WORD",
4218 "Never switch to SPT Tree\n"
4219 "Prefix-List to control which groups to switch\n"
4220 "Prefix-List name\n")
4222 return pim_cmd_spt_switchover(PIM_SPT_IMMEDIATE
, NULL
);
4225 DEFUN (ip_pim_joinprune_time
,
4226 ip_pim_joinprune_time_cmd
,
4227 "ip pim join-prune-interval (60-600)",
4229 "pim multicast routing\n"
4230 "Join Prune Send Interval\n"
4233 qpim_t_periodic
= atoi(argv
[3]->arg
);
4237 DEFUN (no_ip_pim_joinprune_time
,
4238 no_ip_pim_joinprune_time_cmd
,
4239 "no ip pim join-prune-interval (60-600)",
4242 "pim multicast routing\n"
4243 "Join Prune Send Interval\n"
4246 qpim_t_periodic
= PIM_DEFAULT_T_PERIODIC
;
4250 DEFUN (ip_pim_register_suppress
,
4251 ip_pim_register_suppress_cmd
,
4252 "ip pim register-suppress-time (5-60000)",
4254 "pim multicast routing\n"
4255 "Register Suppress Timer\n"
4258 qpim_register_suppress_time
= atoi(argv
[3]->arg
);
4262 DEFUN (no_ip_pim_register_suppress
,
4263 no_ip_pim_register_suppress_cmd
,
4264 "no ip pim register-suppress-time (5-60000)",
4267 "pim multicast routing\n"
4268 "Register Suppress Timer\n"
4271 qpim_register_suppress_time
= PIM_REGISTER_SUPPRESSION_TIME_DEFAULT
;
4275 DEFUN (ip_pim_keep_alive
,
4276 ip_pim_keep_alive_cmd
,
4277 "ip pim keep-alive-timer (31-60000)",
4279 "pim multicast routing\n"
4280 "Keep alive Timer\n"
4283 qpim_keep_alive_time
= atoi(argv
[3]->arg
);
4287 DEFUN (no_ip_pim_keep_alive
,
4288 no_ip_pim_keep_alive_cmd
,
4289 "no ip pim keep-alive-timer (31-60000)",
4292 "pim multicast routing\n"
4293 "Keep alive Timer\n"
4296 qpim_keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
4300 DEFUN (ip_pim_packets
,
4302 "ip pim packets (1-100)",
4304 "pim multicast routing\n"
4305 "packets to process at one time per fd\n"
4306 "Number of packets\n")
4308 qpim_packet_process
= atoi(argv
[3]->arg
);
4312 DEFUN (no_ip_pim_packets
,
4313 no_ip_pim_packets_cmd
,
4314 "no ip pim packets (1-100)",
4317 "pim multicast routing\n"
4318 "packets to process at one time per fd\n"
4319 "Number of packets\n")
4321 qpim_packet_process
= PIM_DEFAULT_PACKET_PROCESS
;
4327 "ip pim rp A.B.C.D [A.B.C.D/M]",
4329 "pim multicast routing\n"
4331 "ip address of RP\n"
4332 "Group Address range to cover\n")
4336 if (argc
== (idx_ipv4
+ 1))
4337 return pim_rp_cmd_worker(vty
, argv
[idx_ipv4
]->arg
, NULL
, NULL
);
4339 return pim_rp_cmd_worker(vty
, argv
[idx_ipv4
]->arg
,
4340 argv
[idx_ipv4
+ 1]->arg
, NULL
);
4343 DEFUN (ip_pim_rp_prefix_list
,
4344 ip_pim_rp_prefix_list_cmd
,
4345 "ip pim rp A.B.C.D prefix-list WORD",
4347 "pim multicast routing\n"
4349 "ip address of RP\n"
4350 "group prefix-list filter\n"
4351 "Name of a prefix-list\n")
4353 return pim_rp_cmd_worker(vty
, argv
[3]->arg
, NULL
, argv
[5]->arg
);
4356 static int pim_no_rp_cmd_worker(struct vty
*vty
, const char *rp
,
4357 const char *group
, const char *plist
)
4359 int result
= pim_rp_del(rp
, group
, plist
);
4361 if (result
== PIM_GROUP_BAD_ADDRESS
) {
4362 vty_out(vty
, "%% Bad group address specified: %s%s", group
,
4367 if (result
== PIM_RP_BAD_ADDRESS
) {
4368 vty_out(vty
, "%% Bad RP address specified: %s%s", rp
,
4373 if (result
== PIM_RP_NOT_FOUND
) {
4374 vty_out(vty
, "%% Unable to find specified RP%s", VTY_NEWLINE
);
4381 DEFUN (no_ip_pim_rp
,
4383 "no ip pim rp A.B.C.D [A.B.C.D/M]",
4386 "pim multicast routing\n"
4388 "ip address of RP\n"
4389 "Group Address range to cover\n")
4393 if (argc
== (idx_ipv4
+ 1))
4394 return pim_no_rp_cmd_worker(vty
, argv
[idx_ipv4
]->arg
, NULL
,
4397 return pim_no_rp_cmd_worker(vty
, argv
[idx_ipv4
]->arg
,
4398 argv
[idx_ipv4
+ 1]->arg
, NULL
);
4401 DEFUN (no_ip_pim_rp_prefix_list
,
4402 no_ip_pim_rp_prefix_list_cmd
,
4403 "no ip pim rp A.B.C.D prefix-list WORD",
4406 "pim multicast routing\n"
4408 "ip address of RP\n"
4409 "group prefix-list filter\n"
4410 "Name of a prefix-list\n")
4412 return pim_no_rp_cmd_worker(vty
, argv
[4]->arg
, NULL
, argv
[6]->arg
);
4415 static int pim_ssm_cmd_worker(struct vty
*vty
, const char *plist
)
4417 int result
= pim_ssm_range_set(VRF_DEFAULT
, plist
);
4419 if (result
== PIM_SSM_ERR_NONE
)
4423 case PIM_SSM_ERR_NO_VRF
:
4424 vty_out(vty
, "%% VRF doesn't exist%s", VTY_NEWLINE
);
4426 case PIM_SSM_ERR_DUP
:
4427 vty_out(vty
, "%% duplicate config%s", VTY_NEWLINE
);
4430 vty_out(vty
, "%% ssm range config failed%s", VTY_NEWLINE
);
4436 DEFUN (ip_pim_ssm_prefix_list
,
4437 ip_pim_ssm_prefix_list_cmd
,
4438 "ip pim ssm prefix-list WORD",
4440 "pim multicast routing\n"
4441 "Source Specific Multicast\n"
4442 "group range prefix-list filter\n"
4443 "Name of a prefix-list\n")
4445 return pim_ssm_cmd_worker(vty
, argv
[0]->arg
);
4448 DEFUN (no_ip_pim_ssm_prefix_list
,
4449 no_ip_pim_ssm_prefix_list_cmd
,
4450 "no ip pim ssm prefix-list",
4453 "pim multicast routing\n"
4454 "Source Specific Multicast\n"
4455 "group range prefix-list filter\n")
4457 return pim_ssm_cmd_worker(vty
, NULL
);
4460 DEFUN (no_ip_pim_ssm_prefix_list_name
,
4461 no_ip_pim_ssm_prefix_list_name_cmd
,
4462 "no ip pim ssm prefix-list WORD",
4465 "pim multicast routing\n"
4466 "Source Specific Multicast\n"
4467 "group range prefix-list filter\n"
4468 "Name of a prefix-list\n")
4470 struct pim_ssm
*ssm
= pimg
->ssm_info
;
4472 if (ssm
->plist_name
&& !strcmp(ssm
->plist_name
, argv
[0]->arg
))
4473 return pim_ssm_cmd_worker(vty
, NULL
);
4475 vty_out(vty
, "%% pim ssm prefix-list %s doesn't exist%s", argv
[0]->arg
,
4481 static void ip_pim_ssm_show_group_range(struct vty
*vty
, u_char uj
)
4483 struct pim_ssm
*ssm
= pimg
->ssm_info
;
4484 const char *range_str
=
4485 ssm
->plist_name
? ssm
->plist_name
: PIM_SSM_STANDARD_RANGE
;
4489 json
= json_object_new_object();
4490 json_object_string_add(json
, "ssmGroups", range_str
);
4491 vty_out(vty
, "%s%s", json_object_to_json_string_ext(
4492 json
, JSON_C_TO_STRING_PRETTY
),
4494 json_object_free(json
);
4496 vty_out(vty
, "SSM group range : %s%s", range_str
, VTY_NEWLINE
);
4499 DEFUN (show_ip_pim_ssm_range
,
4500 show_ip_pim_ssm_range_cmd
,
4501 "show ip pim group-type [json]",
4506 "JavaScript Object Notation\n")
4508 u_char uj
= use_json(argc
, argv
);
4509 ip_pim_ssm_show_group_range(vty
, uj
);
4514 static void ip_pim_ssm_show_group_type(struct vty
*vty
, u_char uj
,
4517 struct in_addr group_addr
;
4518 const char *type_str
;
4521 result
= inet_pton(AF_INET
, group
, &group_addr
);
4523 type_str
= "invalid";
4525 if (pim_is_group_224_4(group_addr
))
4526 type_str
= pim_is_grp_ssm(group_addr
) ? "SSM" : "ASM";
4528 type_str
= "not-multicast";
4533 json
= json_object_new_object();
4534 json_object_string_add(json
, "groupType", type_str
);
4535 vty_out(vty
, "%s%s", json_object_to_json_string_ext(
4536 json
, JSON_C_TO_STRING_PRETTY
),
4538 json_object_free(json
);
4540 vty_out(vty
, "Group type : %s%s", type_str
, VTY_NEWLINE
);
4543 DEFUN (show_ip_pim_group_type
,
4544 show_ip_pim_group_type_cmd
,
4545 "show ip pim group-type A.B.C.D [json]",
4549 "multicast group type\n"
4551 "JavaScript Object Notation\n")
4553 u_char uj
= use_json(argc
, argv
);
4554 ip_pim_ssm_show_group_type(vty
, uj
, argv
[0]->arg
);
4559 DEFUN_HIDDEN (ip_multicast_routing
,
4560 ip_multicast_routing_cmd
,
4561 "ip multicast-routing",
4563 "Enable IP multicast forwarding\n")
4568 DEFUN_HIDDEN (no_ip_multicast_routing
,
4569 no_ip_multicast_routing_cmd
,
4570 "no ip multicast-routing",
4573 "Global IP configuration subcommands\n"
4574 "Enable IP multicast forwarding\n")
4577 "Command is Disabled and will be removed in a future version%s",
4584 "ip ssmpingd [A.B.C.D]",
4591 struct in_addr source_addr
;
4592 const char *source_str
= (argc
== 3) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
4594 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
4596 vty_out(vty
, "%% Bad source address %s: errno=%d: %s%s",
4597 source_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
4601 result
= pim_ssmpingd_start(source_addr
);
4603 vty_out(vty
, "%% Failure starting ssmpingd for source %s: %d%s",
4604 source_str
, result
, VTY_NEWLINE
);
4611 DEFUN (no_ip_ssmpingd
,
4613 "no ip ssmpingd [A.B.C.D]",
4621 struct in_addr source_addr
;
4622 const char *source_str
= (argc
== 4) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
4624 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
4626 vty_out(vty
, "%% Bad source address %s: errno=%d: %s%s",
4627 source_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
4631 result
= pim_ssmpingd_stop(source_addr
);
4633 vty_out(vty
, "%% Failure stopping ssmpingd for source %s: %d%s",
4634 source_str
, result
, VTY_NEWLINE
);
4645 "pim multicast routing\n"
4646 "Enable PIM ECMP \n")
4648 qpim_ecmp_enable
= 1;
4653 DEFUN (no_ip_pim_ecmp
,
4658 "pim multicast routing\n"
4659 "Disable PIM ECMP \n")
4661 qpim_ecmp_enable
= 0;
4666 DEFUN (ip_pim_ecmp_rebalance
,
4667 ip_pim_ecmp_rebalance_cmd
,
4668 "ip pim ecmp rebalance",
4670 "pim multicast routing\n"
4671 "Enable PIM ECMP \n"
4672 "Enable PIM ECMP Rebalance\n")
4674 qpim_ecmp_enable
= 1;
4675 qpim_ecmp_rebalance_enable
= 1;
4680 DEFUN (no_ip_pim_ecmp_rebalance
,
4681 no_ip_pim_ecmp_rebalance_cmd
,
4682 "no ip pim ecmp rebalance",
4685 "pim multicast routing\n"
4686 "Disable PIM ECMP \n"
4687 "Disable PIM ECMP Rebalance\n")
4689 qpim_ecmp_rebalance_enable
= 0;
4694 static int pim_cmd_igmp_start(struct vty
*vty
, struct interface
*ifp
)
4696 struct pim_interface
*pim_ifp
;
4697 uint8_t need_startup
= 0;
4699 pim_ifp
= ifp
->info
;
4702 pim_ifp
= pim_if_new(ifp
, 1 /* igmp=true */, 0 /* pim=false */);
4704 vty_out(vty
, "Could not enable IGMP on interface %s%s",
4705 ifp
->name
, VTY_NEWLINE
);
4710 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
4711 PIM_IF_DO_IGMP(pim_ifp
->options
);
4716 /* 'ip igmp' executed multiple times, with need_startup
4717 avoid multiple if add all and membership refresh */
4719 pim_if_addr_add_all(ifp
);
4720 pim_if_membership_refresh(ifp
);
4726 DEFUN (interface_ip_igmp
,
4727 interface_ip_igmp_cmd
,
4732 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4734 return pim_cmd_igmp_start(vty
, ifp
);
4737 DEFUN (interface_no_ip_igmp
,
4738 interface_no_ip_igmp_cmd
,
4744 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4745 struct pim_interface
*pim_ifp
;
4747 pim_ifp
= ifp
->info
;
4751 PIM_IF_DONT_IGMP(pim_ifp
->options
);
4753 pim_if_membership_clear(ifp
);
4755 pim_if_addr_del_all_igmp(ifp
);
4757 if (!PIM_IF_TEST_PIM(pim_ifp
->options
)) {
4764 DEFUN (interface_ip_igmp_join
,
4765 interface_ip_igmp_join_cmd
,
4766 "ip igmp join A.B.C.D A.B.C.D",
4769 "IGMP join multicast group\n"
4770 "Multicast group address\n"
4773 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4776 const char *group_str
;
4777 const char *source_str
;
4778 struct in_addr group_addr
;
4779 struct in_addr source_addr
;
4783 group_str
= argv
[idx_ipv4
]->arg
;
4784 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
4786 vty_out(vty
, "Bad group address %s: errno=%d: %s%s", group_str
,
4787 errno
, safe_strerror(errno
), VTY_NEWLINE
);
4791 /* Source address */
4792 source_str
= argv
[idx_ipv4_2
]->arg
;
4793 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
4795 vty_out(vty
, "Bad source address %s: errno=%d: %s%s",
4796 source_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
4800 result
= pim_if_igmp_join_add(ifp
, group_addr
, source_addr
);
4803 "%% Failure joining IGMP group %s source %s on interface %s: %d%s",
4804 group_str
, source_str
, ifp
->name
, result
, VTY_NEWLINE
);
4811 DEFUN (interface_no_ip_igmp_join
,
4812 interface_no_ip_igmp_join_cmd
,
4813 "no ip igmp join A.B.C.D A.B.C.D",
4817 "IGMP join multicast group\n"
4818 "Multicast group address\n"
4821 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4824 const char *group_str
;
4825 const char *source_str
;
4826 struct in_addr group_addr
;
4827 struct in_addr source_addr
;
4831 group_str
= argv
[idx_ipv4
]->arg
;
4832 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
4834 vty_out(vty
, "Bad group address %s: errno=%d: %s%s", group_str
,
4835 errno
, safe_strerror(errno
), VTY_NEWLINE
);
4839 /* Source address */
4840 source_str
= argv
[idx_ipv4_2
]->arg
;
4841 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
4843 vty_out(vty
, "Bad source address %s: errno=%d: %s%s",
4844 source_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
4848 result
= pim_if_igmp_join_del(ifp
, group_addr
, source_addr
);
4851 "%% Failure leaving IGMP group %s source %s on interface %s: %d%s",
4852 group_str
, source_str
, ifp
->name
, result
, VTY_NEWLINE
);
4860 CLI reconfiguration affects the interface level (struct pim_interface).
4861 This function propagates the reconfiguration to every active socket
4864 static void igmp_sock_query_interval_reconfig(struct igmp_sock
*igmp
)
4866 struct interface
*ifp
;
4867 struct pim_interface
*pim_ifp
;
4871 /* other querier present? */
4873 if (igmp
->t_other_querier_timer
)
4876 /* this is the querier */
4878 zassert(igmp
->interface
);
4879 zassert(igmp
->interface
->info
);
4881 ifp
= igmp
->interface
;
4882 pim_ifp
= ifp
->info
;
4884 if (PIM_DEBUG_IGMP_TRACE
) {
4885 char ifaddr_str
[INET_ADDRSTRLEN
];
4886 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
4887 sizeof(ifaddr_str
));
4888 zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
4889 __PRETTY_FUNCTION__
, ifaddr_str
, ifp
->name
,
4890 pim_ifp
->igmp_default_query_interval
);
4894 igmp_startup_mode_on() will reset QQI:
4896 igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
4898 igmp_startup_mode_on(igmp
);
4901 static void igmp_sock_query_reschedule(struct igmp_sock
*igmp
)
4903 if (igmp
->t_igmp_query_timer
) {
4904 /* other querier present */
4905 zassert(igmp
->t_igmp_query_timer
);
4906 zassert(!igmp
->t_other_querier_timer
);
4908 pim_igmp_general_query_off(igmp
);
4909 pim_igmp_general_query_on(igmp
);
4911 zassert(igmp
->t_igmp_query_timer
);
4912 zassert(!igmp
->t_other_querier_timer
);
4914 /* this is the querier */
4916 zassert(!igmp
->t_igmp_query_timer
);
4917 zassert(igmp
->t_other_querier_timer
);
4919 pim_igmp_other_querier_timer_off(igmp
);
4920 pim_igmp_other_querier_timer_on(igmp
);
4922 zassert(!igmp
->t_igmp_query_timer
);
4923 zassert(igmp
->t_other_querier_timer
);
4927 static void change_query_interval(struct pim_interface
*pim_ifp
,
4930 struct listnode
*sock_node
;
4931 struct igmp_sock
*igmp
;
4933 pim_ifp
->igmp_default_query_interval
= query_interval
;
4935 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
4936 igmp_sock_query_interval_reconfig(igmp
);
4937 igmp_sock_query_reschedule(igmp
);
4941 static void change_query_max_response_time(struct pim_interface
*pim_ifp
,
4942 int query_max_response_time_dsec
)
4944 struct listnode
*sock_node
;
4945 struct igmp_sock
*igmp
;
4947 pim_ifp
->igmp_query_max_response_time_dsec
=
4948 query_max_response_time_dsec
;
4951 Below we modify socket/group/source timers in order to quickly
4952 reflect the change. Otherwise, those timers would eventually catch
4956 /* scan all sockets */
4957 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
4958 struct listnode
*grp_node
;
4959 struct igmp_group
*grp
;
4961 /* reschedule socket general query */
4962 igmp_sock_query_reschedule(igmp
);
4964 /* scan socket groups */
4965 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grp_node
,
4967 struct listnode
*src_node
;
4968 struct igmp_source
*src
;
4970 /* reset group timers for groups in EXCLUDE mode */
4971 if (grp
->group_filtermode_isexcl
) {
4972 igmp_group_reset_gmi(grp
);
4975 /* scan group sources */
4976 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
,
4979 /* reset source timers for sources with running
4981 if (src
->t_source_timer
) {
4982 igmp_source_reset_gmi(igmp
, grp
, src
);
4989 #define IGMP_QUERY_INTERVAL_MIN (1)
4990 #define IGMP_QUERY_INTERVAL_MAX (1800)
4992 DEFUN (interface_ip_igmp_query_interval
,
4993 interface_ip_igmp_query_interval_cmd
,
4994 "ip igmp query-interval (1-1800)",
4997 IFACE_IGMP_QUERY_INTERVAL_STR
4998 "Query interval in seconds\n")
5000 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5001 struct pim_interface
*pim_ifp
;
5003 int query_interval_dsec
;
5006 pim_ifp
= ifp
->info
;
5009 ret
= pim_cmd_igmp_start(vty
, ifp
);
5010 if (ret
!= CMD_SUCCESS
)
5012 pim_ifp
= ifp
->info
;
5015 query_interval
= atoi(argv
[3]->arg
);
5016 query_interval_dsec
= 10 * query_interval
;
5019 It seems we don't need to check bounds since command.c does it
5020 already, but we verify them anyway for extra safety.
5022 if (query_interval
< IGMP_QUERY_INTERVAL_MIN
) {
5024 "General query interval %d lower than minimum %d%s",
5025 query_interval
, IGMP_QUERY_INTERVAL_MIN
, VTY_NEWLINE
);
5028 if (query_interval
> IGMP_QUERY_INTERVAL_MAX
) {
5030 "General query interval %d higher than maximum %d%s",
5031 query_interval
, IGMP_QUERY_INTERVAL_MAX
, VTY_NEWLINE
);
5035 if (query_interval_dsec
<= pim_ifp
->igmp_query_max_response_time_dsec
) {
5037 "Can't set general query interval %d dsec <= query max response time %d dsec.%s",
5038 query_interval_dsec
,
5039 pim_ifp
->igmp_query_max_response_time_dsec
,
5044 change_query_interval(pim_ifp
, query_interval
);
5049 DEFUN (interface_no_ip_igmp_query_interval
,
5050 interface_no_ip_igmp_query_interval_cmd
,
5051 "no ip igmp query-interval",
5055 IFACE_IGMP_QUERY_INTERVAL_STR
)
5057 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5058 struct pim_interface
*pim_ifp
;
5059 int default_query_interval_dsec
;
5061 pim_ifp
= ifp
->info
;
5066 default_query_interval_dsec
= IGMP_GENERAL_QUERY_INTERVAL
* 10;
5068 if (default_query_interval_dsec
5069 <= pim_ifp
->igmp_query_max_response_time_dsec
) {
5071 "Can't set default general query interval %d dsec <= query max response time %d dsec.%s",
5072 default_query_interval_dsec
,
5073 pim_ifp
->igmp_query_max_response_time_dsec
,
5078 change_query_interval(pim_ifp
, IGMP_GENERAL_QUERY_INTERVAL
);
5083 DEFUN (interface_ip_igmp_version
,
5084 interface_ip_igmp_version_cmd
,
5085 "ip igmp version (2-3)",
5089 "IGMP version number\n")
5091 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5092 struct pim_interface
*pim_ifp
= NULL
;
5093 int igmp_version
, old_version
= 0;
5096 pim_ifp
= ifp
->info
;
5099 ret
= pim_cmd_igmp_start(vty
, ifp
);
5100 if (ret
!= CMD_SUCCESS
)
5102 pim_ifp
= ifp
->info
;
5105 igmp_version
= atoi(argv
[3]->arg
);
5106 old_version
= pim_ifp
->igmp_version
;
5107 pim_ifp
->igmp_version
= igmp_version
;
5109 // Check if IGMP is Enabled otherwise, enable on interface
5110 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
5111 PIM_IF_DO_IGMP(pim_ifp
->options
);
5112 pim_if_addr_add_all(ifp
);
5113 pim_if_membership_refresh(ifp
);
5114 old_version
= igmp_version
; // avoid refreshing membership
5117 /* Current and new version is different refresh existing
5118 membership. Going from 3 -> 2 or 2 -> 3. */
5119 if (old_version
!= igmp_version
)
5120 pim_if_membership_refresh(ifp
);
5125 DEFUN (interface_no_ip_igmp_version
,
5126 interface_no_ip_igmp_version_cmd
,
5127 "no ip igmp version (2-3)",
5132 "IGMP version number\n")
5134 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5135 struct pim_interface
*pim_ifp
;
5137 pim_ifp
= ifp
->info
;
5142 pim_ifp
->igmp_version
= IGMP_DEFAULT_VERSION
;
5147 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
5148 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
5150 DEFUN (interface_ip_igmp_query_max_response_time
,
5151 interface_ip_igmp_query_max_response_time_cmd
,
5152 "ip igmp query-max-response-time (10-250)",
5155 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
5156 "Query response value in deci-seconds\n")
5158 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5159 struct pim_interface
*pim_ifp
;
5160 int query_max_response_time
;
5163 pim_ifp
= ifp
->info
;
5166 ret
= pim_cmd_igmp_start(vty
, ifp
);
5167 if (ret
!= CMD_SUCCESS
)
5169 pim_ifp
= ifp
->info
;
5172 query_max_response_time
= atoi(argv
[3]->arg
);
5174 if (query_max_response_time
5175 >= pim_ifp
->igmp_default_query_interval
* 10) {
5177 "Can't set query max response time %d sec >= general query interval %d sec%s",
5178 query_max_response_time
,
5179 pim_ifp
->igmp_default_query_interval
, VTY_NEWLINE
);
5183 change_query_max_response_time(pim_ifp
, query_max_response_time
);
5188 DEFUN (interface_no_ip_igmp_query_max_response_time
,
5189 interface_no_ip_igmp_query_max_response_time_cmd
,
5190 "no ip igmp query-max-response-time (10-250)",
5194 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
5195 "Time for response in deci-seconds\n")
5197 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5198 struct pim_interface
*pim_ifp
;
5200 pim_ifp
= ifp
->info
;
5205 change_query_max_response_time(pim_ifp
,
5206 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
5211 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
5212 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
5214 DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec
,
5215 interface_ip_igmp_query_max_response_time_dsec_cmd
,
5216 "ip igmp query-max-response-time-dsec (10-250)",
5219 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
5220 "Query response value in deciseconds\n")
5222 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5223 struct pim_interface
*pim_ifp
;
5224 int query_max_response_time_dsec
;
5225 int default_query_interval_dsec
;
5228 pim_ifp
= ifp
->info
;
5231 ret
= pim_cmd_igmp_start(vty
, ifp
);
5232 if (ret
!= CMD_SUCCESS
)
5234 pim_ifp
= ifp
->info
;
5237 query_max_response_time_dsec
= atoi(argv
[4]->arg
);
5239 default_query_interval_dsec
= 10 * pim_ifp
->igmp_default_query_interval
;
5241 if (query_max_response_time_dsec
>= default_query_interval_dsec
) {
5243 "Can't set query max response time %d dsec >= general query interval %d dsec%s",
5244 query_max_response_time_dsec
,
5245 default_query_interval_dsec
, VTY_NEWLINE
);
5249 change_query_max_response_time(pim_ifp
, query_max_response_time_dsec
);
5254 DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec
,
5255 interface_no_ip_igmp_query_max_response_time_dsec_cmd
,
5256 "no ip igmp query-max-response-time-dsec",
5260 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
)
5262 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5263 struct pim_interface
*pim_ifp
;
5265 pim_ifp
= ifp
->info
;
5270 change_query_max_response_time(pim_ifp
,
5271 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
5276 DEFUN (interface_ip_pim_drprio
,
5277 interface_ip_pim_drprio_cmd
,
5278 "ip pim drpriority (1-4294967295)",
5281 "Set the Designated Router Election Priority\n"
5282 "Value of the new DR Priority\n")
5284 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5286 struct pim_interface
*pim_ifp
;
5287 uint32_t old_dr_prio
;
5289 pim_ifp
= ifp
->info
;
5292 vty_out(vty
, "Please enable PIM on interface, first%s",
5297 old_dr_prio
= pim_ifp
->pim_dr_priority
;
5299 pim_ifp
->pim_dr_priority
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
5301 if (old_dr_prio
!= pim_ifp
->pim_dr_priority
) {
5302 if (pim_if_dr_election(ifp
))
5303 pim_hello_restart_now(ifp
);
5309 DEFUN (interface_no_ip_pim_drprio
,
5310 interface_no_ip_pim_drprio_cmd
,
5311 "no ip pim drpriority [(1-4294967295)]",
5315 "Revert the Designated Router Priority to default\n"
5316 "Old Value of the Priority\n")
5318 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5319 struct pim_interface
*pim_ifp
;
5321 pim_ifp
= ifp
->info
;
5324 vty_out(vty
, "Pim not enabled on this interface%s",
5329 if (pim_ifp
->pim_dr_priority
!= PIM_DEFAULT_DR_PRIORITY
) {
5330 pim_ifp
->pim_dr_priority
= PIM_DEFAULT_DR_PRIORITY
;
5331 if (pim_if_dr_election(ifp
))
5332 pim_hello_restart_now(ifp
);
5338 static int pim_cmd_interface_add(struct interface
*ifp
)
5340 struct pim_interface
*pim_ifp
= ifp
->info
;
5343 pim_ifp
= pim_if_new(ifp
, 0 /* igmp=false */, 1 /* pim=true */);
5348 PIM_IF_DO_PIM(pim_ifp
->options
);
5351 pim_if_addr_add_all(ifp
);
5352 pim_if_membership_refresh(ifp
);
5356 DEFUN_HIDDEN (interface_ip_pim_ssm
,
5357 interface_ip_pim_ssm_cmd
,
5363 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5365 if (!pim_cmd_interface_add(ifp
)) {
5366 vty_out(vty
, "Could not enable PIM SM on interface%s",
5372 "WARN: Enabled PIM SM on interface; configure PIM SSM range if needed%s",
5377 DEFUN (interface_ip_pim_sm
,
5378 interface_ip_pim_sm_cmd
,
5384 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5385 if (!pim_cmd_interface_add(ifp
)) {
5386 vty_out(vty
, "Could not enable PIM SM on interface%s",
5391 pim_if_create_pimreg();
5396 static int pim_cmd_interface_delete(struct interface
*ifp
)
5398 struct pim_interface
*pim_ifp
= ifp
->info
;
5403 PIM_IF_DONT_PIM(pim_ifp
->options
);
5405 pim_if_membership_clear(ifp
);
5408 pim_sock_delete() removes all neighbors from
5409 pim_ifp->pim_neighbor_list.
5411 pim_sock_delete(ifp
, "pim unconfigured on interface");
5413 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
5414 pim_if_addr_del_all(ifp
);
5421 DEFUN_HIDDEN (interface_no_ip_pim_ssm
,
5422 interface_no_ip_pim_ssm_cmd
,
5429 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5430 if (!pim_cmd_interface_delete(ifp
)) {
5431 vty_out(vty
, "Unable to delete interface information%s",
5439 DEFUN (interface_no_ip_pim_sm
,
5440 interface_no_ip_pim_sm_cmd
,
5447 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5448 if (!pim_cmd_interface_delete(ifp
)) {
5449 vty_out(vty
, "Unable to delete interface information%s",
5457 DEFUN (interface_ip_mroute
,
5458 interface_ip_mroute_cmd
,
5459 "ip mroute INTERFACE A.B.C.D",
5461 "Add multicast route\n"
5462 "Outgoing interface name\n"
5465 VTY_DECLVAR_CONTEXT(interface
, iif
);
5466 int idx_interface
= 2;
5468 struct interface
*oif
;
5469 const char *oifname
;
5470 const char *grp_str
;
5471 struct in_addr grp_addr
;
5472 struct in_addr src_addr
;
5475 oifname
= argv
[idx_interface
]->arg
;
5476 oif
= if_lookup_by_name(oifname
, VRF_DEFAULT
);
5478 vty_out(vty
, "No such interface name %s%s", oifname
,
5483 grp_str
= argv
[idx_ipv4
]->arg
;
5484 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
5486 vty_out(vty
, "Bad group address %s: errno=%d: %s%s", grp_str
,
5487 errno
, safe_strerror(errno
), VTY_NEWLINE
);
5491 src_addr
.s_addr
= INADDR_ANY
;
5493 if (pim_static_add(iif
, oif
, grp_addr
, src_addr
)) {
5494 vty_out(vty
, "Failed to add route%s", VTY_NEWLINE
);
5501 DEFUN (interface_ip_mroute_source
,
5502 interface_ip_mroute_source_cmd
,
5503 "ip mroute INTERFACE A.B.C.D A.B.C.D",
5505 "Add multicast route\n"
5506 "Outgoing interface name\n"
5510 VTY_DECLVAR_CONTEXT(interface
, iif
);
5511 int idx_interface
= 2;
5514 struct interface
*oif
;
5515 const char *oifname
;
5516 const char *grp_str
;
5517 struct in_addr grp_addr
;
5518 const char *src_str
;
5519 struct in_addr src_addr
;
5522 oifname
= argv
[idx_interface
]->arg
;
5523 oif
= if_lookup_by_name(oifname
, VRF_DEFAULT
);
5525 vty_out(vty
, "No such interface name %s%s", oifname
,
5530 grp_str
= argv
[idx_ipv4
]->arg
;
5531 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
5533 vty_out(vty
, "Bad group address %s: errno=%d: %s%s", grp_str
,
5534 errno
, safe_strerror(errno
), VTY_NEWLINE
);
5538 src_str
= argv
[idx_ipv4_2
]->arg
;
5539 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
5541 vty_out(vty
, "Bad source address %s: errno=%d: %s%s", src_str
,
5542 errno
, safe_strerror(errno
), VTY_NEWLINE
);
5546 if (pim_static_add(iif
, oif
, grp_addr
, src_addr
)) {
5547 vty_out(vty
, "Failed to add route%s", VTY_NEWLINE
);
5554 DEFUN (interface_no_ip_mroute
,
5555 interface_no_ip_mroute_cmd
,
5556 "no ip mroute INTERFACE A.B.C.D",
5559 "Add multicast route\n"
5560 "Outgoing interface name\n"
5563 VTY_DECLVAR_CONTEXT(interface
, iif
);
5564 int idx_interface
= 3;
5566 struct interface
*oif
;
5567 const char *oifname
;
5568 const char *grp_str
;
5569 struct in_addr grp_addr
;
5570 struct in_addr src_addr
;
5573 oifname
= argv
[idx_interface
]->arg
;
5574 oif
= if_lookup_by_name(oifname
, VRF_DEFAULT
);
5576 vty_out(vty
, "No such interface name %s%s", oifname
,
5581 grp_str
= argv
[idx_ipv4
]->arg
;
5582 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
5584 vty_out(vty
, "Bad group address %s: errno=%d: %s%s", grp_str
,
5585 errno
, safe_strerror(errno
), VTY_NEWLINE
);
5589 src_addr
.s_addr
= INADDR_ANY
;
5591 if (pim_static_del(iif
, oif
, grp_addr
, src_addr
)) {
5592 vty_out(vty
, "Failed to remove route%s", VTY_NEWLINE
);
5599 DEFUN (interface_no_ip_mroute_source
,
5600 interface_no_ip_mroute_source_cmd
,
5601 "no ip mroute INTERFACE A.B.C.D A.B.C.D",
5604 "Add multicast route\n"
5605 "Outgoing interface name\n"
5609 VTY_DECLVAR_CONTEXT(interface
, iif
);
5610 int idx_interface
= 3;
5613 struct interface
*oif
;
5614 const char *oifname
;
5615 const char *grp_str
;
5616 struct in_addr grp_addr
;
5617 const char *src_str
;
5618 struct in_addr src_addr
;
5621 oifname
= argv
[idx_interface
]->arg
;
5622 oif
= if_lookup_by_name(oifname
, VRF_DEFAULT
);
5624 vty_out(vty
, "No such interface name %s%s", oifname
,
5629 grp_str
= argv
[idx_ipv4
]->arg
;
5630 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
5632 vty_out(vty
, "Bad group address %s: errno=%d: %s%s", grp_str
,
5633 errno
, safe_strerror(errno
), VTY_NEWLINE
);
5637 src_str
= argv
[idx_ipv4_2
]->arg
;
5638 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
5640 vty_out(vty
, "Bad source address %s: errno=%d: %s%s", src_str
,
5641 errno
, safe_strerror(errno
), VTY_NEWLINE
);
5645 if (pim_static_del(iif
, oif
, grp_addr
, src_addr
)) {
5646 vty_out(vty
, "Failed to remove route%s", VTY_NEWLINE
);
5653 DEFUN (interface_ip_pim_hello
,
5654 interface_ip_pim_hello_cmd
,
5655 "ip pim hello (1-180) [(1-180)]",
5659 IFACE_PIM_HELLO_TIME_STR
5660 IFACE_PIM_HELLO_HOLD_STR
)
5662 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5665 struct pim_interface
*pim_ifp
;
5667 pim_ifp
= ifp
->info
;
5670 if (!pim_cmd_interface_add(ifp
)) {
5671 vty_out(vty
, "Could not enable PIM SM on interface%s",
5677 pim_ifp
= ifp
->info
;
5678 pim_ifp
->pim_hello_period
= strtol(argv
[idx_time
]->arg
, NULL
, 10);
5680 if (argc
== idx_hold
+ 1)
5681 pim_ifp
->pim_default_holdtime
=
5682 strtol(argv
[idx_hold
]->arg
, NULL
, 10);
5688 DEFUN (interface_no_ip_pim_hello
,
5689 interface_no_ip_pim_hello_cmd
,
5690 "no ip pim hello [(1-180) (1-180)]",
5695 IFACE_PIM_HELLO_TIME_STR
5696 IFACE_PIM_HELLO_HOLD_STR
)
5698 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5699 struct pim_interface
*pim_ifp
;
5701 pim_ifp
= ifp
->info
;
5704 vty_out(vty
, "Pim not enabled on this interface%s",
5709 pim_ifp
->pim_hello_period
= PIM_DEFAULT_HELLO_PERIOD
;
5710 pim_ifp
->pim_default_holdtime
= -1;
5721 PIM_DO_DEBUG_IGMP_EVENTS
;
5722 PIM_DO_DEBUG_IGMP_PACKETS
;
5723 PIM_DO_DEBUG_IGMP_TRACE
;
5727 DEFUN (no_debug_igmp
,
5734 PIM_DONT_DEBUG_IGMP_EVENTS
;
5735 PIM_DONT_DEBUG_IGMP_PACKETS
;
5736 PIM_DONT_DEBUG_IGMP_TRACE
;
5741 DEFUN (debug_igmp_events
,
5742 debug_igmp_events_cmd
,
5743 "debug igmp events",
5746 DEBUG_IGMP_EVENTS_STR
)
5748 PIM_DO_DEBUG_IGMP_EVENTS
;
5752 DEFUN (no_debug_igmp_events
,
5753 no_debug_igmp_events_cmd
,
5754 "no debug igmp events",
5758 DEBUG_IGMP_EVENTS_STR
)
5760 PIM_DONT_DEBUG_IGMP_EVENTS
;
5765 DEFUN (debug_igmp_packets
,
5766 debug_igmp_packets_cmd
,
5767 "debug igmp packets",
5770 DEBUG_IGMP_PACKETS_STR
)
5772 PIM_DO_DEBUG_IGMP_PACKETS
;
5776 DEFUN (no_debug_igmp_packets
,
5777 no_debug_igmp_packets_cmd
,
5778 "no debug igmp packets",
5782 DEBUG_IGMP_PACKETS_STR
)
5784 PIM_DONT_DEBUG_IGMP_PACKETS
;
5789 DEFUN (debug_igmp_trace
,
5790 debug_igmp_trace_cmd
,
5794 DEBUG_IGMP_TRACE_STR
)
5796 PIM_DO_DEBUG_IGMP_TRACE
;
5800 DEFUN (no_debug_igmp_trace
,
5801 no_debug_igmp_trace_cmd
,
5802 "no debug igmp trace",
5806 DEBUG_IGMP_TRACE_STR
)
5808 PIM_DONT_DEBUG_IGMP_TRACE
;
5813 DEFUN (debug_mroute
,
5819 PIM_DO_DEBUG_MROUTE
;
5823 DEFUN (debug_mroute_detail
,
5824 debug_mroute_detail_cmd
,
5825 "debug mroute detail",
5830 PIM_DO_DEBUG_MROUTE_DETAIL
;
5834 DEFUN (no_debug_mroute
,
5835 no_debug_mroute_cmd
,
5841 PIM_DONT_DEBUG_MROUTE
;
5845 DEFUN (no_debug_mroute_detail
,
5846 no_debug_mroute_detail_cmd
,
5847 "no debug mroute detail",
5853 PIM_DONT_DEBUG_MROUTE_DETAIL
;
5857 DEFUN (debug_static
,
5863 PIM_DO_DEBUG_STATIC
;
5867 DEFUN (no_debug_static
,
5868 no_debug_static_cmd
,
5874 PIM_DONT_DEBUG_STATIC
;
5885 PIM_DO_DEBUG_PIM_EVENTS
;
5886 PIM_DO_DEBUG_PIM_PACKETS
;
5887 PIM_DO_DEBUG_PIM_TRACE
;
5888 PIM_DO_DEBUG_MSDP_EVENTS
;
5889 PIM_DO_DEBUG_MSDP_PACKETS
;
5893 DEFUN (no_debug_pim
,
5900 PIM_DONT_DEBUG_PIM_EVENTS
;
5901 PIM_DONT_DEBUG_PIM_PACKETS
;
5902 PIM_DONT_DEBUG_PIM_TRACE
;
5903 PIM_DONT_DEBUG_MSDP_EVENTS
;
5904 PIM_DONT_DEBUG_MSDP_PACKETS
;
5906 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
5907 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
5913 DEFUN (debug_pim_events
,
5914 debug_pim_events_cmd
,
5918 DEBUG_PIM_EVENTS_STR
)
5920 PIM_DO_DEBUG_PIM_EVENTS
;
5924 DEFUN (no_debug_pim_events
,
5925 no_debug_pim_events_cmd
,
5926 "no debug pim events",
5930 DEBUG_PIM_EVENTS_STR
)
5932 PIM_DONT_DEBUG_PIM_EVENTS
;
5936 DEFUN (debug_pim_packets
,
5937 debug_pim_packets_cmd
,
5938 "debug pim packets [<hello|joins|register>]",
5941 DEBUG_PIM_PACKETS_STR
5942 DEBUG_PIM_HELLO_PACKETS_STR
5943 DEBUG_PIM_J_P_PACKETS_STR
5944 DEBUG_PIM_PIM_REG_PACKETS_STR
)
5947 if (argv_find(argv
, argc
, "hello", &idx
)) {
5948 PIM_DO_DEBUG_PIM_HELLO
;
5949 vty_out(vty
, "PIM Hello debugging is on%s", VTY_NEWLINE
);
5950 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
5951 PIM_DO_DEBUG_PIM_J_P
;
5952 vty_out(vty
, "PIM Join/Prune debugging is on%s", VTY_NEWLINE
);
5953 } else if (argv_find(argv
, argc
, "register", &idx
)) {
5954 PIM_DO_DEBUG_PIM_REG
;
5955 vty_out(vty
, "PIM Register debugging is on%s", VTY_NEWLINE
);
5957 PIM_DO_DEBUG_PIM_PACKETS
;
5958 vty_out(vty
, "PIM Packet debugging is on %s", VTY_NEWLINE
);
5963 DEFUN (no_debug_pim_packets
,
5964 no_debug_pim_packets_cmd
,
5965 "no debug pim packets [<hello|joins|register>]",
5969 DEBUG_PIM_PACKETS_STR
5970 DEBUG_PIM_HELLO_PACKETS_STR
5971 DEBUG_PIM_J_P_PACKETS_STR
5972 DEBUG_PIM_PIM_REG_PACKETS_STR
)
5975 if (argv_find(argv
, argc
, "hello", &idx
)) {
5976 PIM_DONT_DEBUG_PIM_HELLO
;
5977 vty_out(vty
, "PIM Hello debugging is off %s", VTY_NEWLINE
);
5978 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
5979 PIM_DONT_DEBUG_PIM_J_P
;
5980 vty_out(vty
, "PIM Join/Prune debugging is off %s", VTY_NEWLINE
);
5981 } else if (argv_find(argv
, argc
, "register", &idx
)) {
5982 PIM_DONT_DEBUG_PIM_REG
;
5983 vty_out(vty
, "PIM Register debugging is off%s", VTY_NEWLINE
);
5985 PIM_DONT_DEBUG_PIM_PACKETS
;
5991 DEFUN (debug_pim_packetdump_send
,
5992 debug_pim_packetdump_send_cmd
,
5993 "debug pim packet-dump send",
5996 DEBUG_PIM_PACKETDUMP_STR
5997 DEBUG_PIM_PACKETDUMP_SEND_STR
)
5999 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND
;
6003 DEFUN (no_debug_pim_packetdump_send
,
6004 no_debug_pim_packetdump_send_cmd
,
6005 "no debug pim packet-dump send",
6009 DEBUG_PIM_PACKETDUMP_STR
6010 DEBUG_PIM_PACKETDUMP_SEND_STR
)
6012 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
6017 DEFUN (debug_pim_packetdump_recv
,
6018 debug_pim_packetdump_recv_cmd
,
6019 "debug pim packet-dump receive",
6022 DEBUG_PIM_PACKETDUMP_STR
6023 DEBUG_PIM_PACKETDUMP_RECV_STR
)
6025 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV
;
6029 DEFUN (no_debug_pim_packetdump_recv
,
6030 no_debug_pim_packetdump_recv_cmd
,
6031 "no debug pim packet-dump receive",
6035 DEBUG_PIM_PACKETDUMP_STR
6036 DEBUG_PIM_PACKETDUMP_RECV_STR
)
6038 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
6043 DEFUN (debug_pim_trace
,
6044 debug_pim_trace_cmd
,
6048 DEBUG_PIM_TRACE_STR
)
6050 PIM_DO_DEBUG_PIM_TRACE
;
6054 DEFUN (no_debug_pim_trace
,
6055 no_debug_pim_trace_cmd
,
6056 "no debug pim trace",
6060 DEBUG_PIM_TRACE_STR
)
6062 PIM_DONT_DEBUG_PIM_TRACE
;
6067 DEFUN (debug_ssmpingd
,
6074 PIM_DO_DEBUG_SSMPINGD
;
6078 DEFUN (no_debug_ssmpingd
,
6079 no_debug_ssmpingd_cmd
,
6080 "no debug ssmpingd",
6086 PIM_DONT_DEBUG_SSMPINGD
;
6091 DEFUN (debug_pim_zebra
,
6092 debug_pim_zebra_cmd
,
6096 DEBUG_PIM_ZEBRA_STR
)
6102 DEFUN (no_debug_pim_zebra
,
6103 no_debug_pim_zebra_cmd
,
6104 "no debug pim zebra",
6108 DEBUG_PIM_ZEBRA_STR
)
6110 PIM_DONT_DEBUG_ZEBRA
;
6121 PIM_DO_DEBUG_MSDP_EVENTS
;
6122 PIM_DO_DEBUG_MSDP_PACKETS
;
6126 DEFUN (no_debug_msdp
,
6133 PIM_DONT_DEBUG_MSDP_EVENTS
;
6134 PIM_DONT_DEBUG_MSDP_PACKETS
;
6138 ALIAS(no_debug_msdp
, undebug_msdp_cmd
, "undebug msdp",
6139 UNDEBUG_STR DEBUG_MSDP_STR
)
6141 DEFUN (debug_msdp_events
,
6142 debug_msdp_events_cmd
,
6143 "debug msdp events",
6146 DEBUG_MSDP_EVENTS_STR
)
6148 PIM_DO_DEBUG_MSDP_EVENTS
;
6152 DEFUN (no_debug_msdp_events
,
6153 no_debug_msdp_events_cmd
,
6154 "no debug msdp events",
6158 DEBUG_MSDP_EVENTS_STR
)
6160 PIM_DONT_DEBUG_MSDP_EVENTS
;
6164 ALIAS(no_debug_msdp_events
, undebug_msdp_events_cmd
, "undebug msdp events",
6165 UNDEBUG_STR DEBUG_MSDP_STR DEBUG_MSDP_EVENTS_STR
)
6167 DEFUN (debug_msdp_packets
,
6168 debug_msdp_packets_cmd
,
6169 "debug msdp packets",
6172 DEBUG_MSDP_PACKETS_STR
)
6174 PIM_DO_DEBUG_MSDP_PACKETS
;
6178 DEFUN (no_debug_msdp_packets
,
6179 no_debug_msdp_packets_cmd
,
6180 "no debug msdp packets",
6184 DEBUG_MSDP_PACKETS_STR
)
6186 PIM_DONT_DEBUG_MSDP_PACKETS
;
6190 ALIAS(no_debug_msdp_packets
, undebug_msdp_packets_cmd
, "undebug msdp packets",
6191 UNDEBUG_STR DEBUG_MSDP_STR DEBUG_MSDP_PACKETS_STR
)
6193 DEFUN (show_debugging_pim
,
6194 show_debugging_pim_cmd
,
6195 "show debugging pim",
6200 pim_debug_config_write(vty
);
6204 static int interface_pim_use_src_cmd_worker(struct vty
*vty
, const char *source
)
6207 struct in_addr source_addr
;
6208 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6210 result
= inet_pton(AF_INET
, source
, &source_addr
);
6212 vty_out(vty
, "%% Bad source address %s: errno=%d: %s%s", source
,
6213 errno
, safe_strerror(errno
), VTY_NEWLINE
);
6217 result
= pim_update_source_set(ifp
, source_addr
);
6221 case PIM_IFACE_NOT_FOUND
:
6222 vty_out(vty
, "Pim not enabled on this interface%s",
6225 case PIM_UPDATE_SOURCE_DUP
:
6226 vty_out(vty
, "%% Source already set to %s%s", source
,
6230 vty_out(vty
, "%% Source set failed%s", VTY_NEWLINE
);
6233 return result
? CMD_WARNING
: CMD_SUCCESS
;
6236 DEFUN (interface_pim_use_source
,
6237 interface_pim_use_source_cmd
,
6238 "ip pim use-source A.B.C.D",
6240 "pim multicast routing\n"
6241 "Configure primary IP address\n"
6242 "source ip address\n")
6244 return interface_pim_use_src_cmd_worker(vty
, argv
[3]->arg
);
6247 DEFUN (interface_no_pim_use_source
,
6248 interface_no_pim_use_source_cmd
,
6249 "no ip pim use-source",
6252 "pim multicast routing\n"
6253 "Delete source IP address\n")
6255 return interface_pim_use_src_cmd_worker(vty
, "0.0.0.0");
6258 static int ip_msdp_peer_cmd_worker(struct vty
*vty
, const char *peer
,
6261 enum pim_msdp_err result
;
6262 struct in_addr peer_addr
;
6263 struct in_addr local_addr
;
6265 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
6267 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s%s", peer
,
6268 errno
, safe_strerror(errno
), VTY_NEWLINE
);
6272 result
= inet_pton(AF_INET
, local
, &local_addr
);
6274 vty_out(vty
, "%% Bad source address %s: errno=%d: %s%s", local
,
6275 errno
, safe_strerror(errno
), VTY_NEWLINE
);
6279 result
= pim_msdp_peer_add(peer_addr
, local_addr
, "default",
6282 case PIM_MSDP_ERR_NONE
:
6284 case PIM_MSDP_ERR_OOM
:
6285 vty_out(vty
, "%% Out of memory%s", VTY_NEWLINE
);
6287 case PIM_MSDP_ERR_PEER_EXISTS
:
6288 vty_out(vty
, "%% Peer exists%s", VTY_NEWLINE
);
6290 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
6291 vty_out(vty
, "%% Only one mesh-group allowed currently%s",
6295 vty_out(vty
, "%% peer add failed%s", VTY_NEWLINE
);
6298 return result
? CMD_WARNING
: CMD_SUCCESS
;
6301 DEFUN_HIDDEN (ip_msdp_peer
,
6303 "ip msdp peer A.B.C.D source A.B.C.D",
6306 "Configure MSDP peer\n"
6308 "Source address for TCP connection\n"
6309 "local ip address\n")
6311 return ip_msdp_peer_cmd_worker(vty
, argv
[3]->arg
, argv
[5]->arg
);
6314 static int ip_no_msdp_peer_cmd_worker(struct vty
*vty
, const char *peer
)
6316 enum pim_msdp_err result
;
6317 struct in_addr peer_addr
;
6319 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
6321 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s%s", peer
,
6322 errno
, safe_strerror(errno
), VTY_NEWLINE
);
6326 result
= pim_msdp_peer_del(peer_addr
);
6328 case PIM_MSDP_ERR_NONE
:
6330 case PIM_MSDP_ERR_NO_PEER
:
6331 vty_out(vty
, "%% Peer does not exist%s", VTY_NEWLINE
);
6334 vty_out(vty
, "%% peer del failed%s", VTY_NEWLINE
);
6337 return result
? CMD_WARNING
: CMD_SUCCESS
;
6340 DEFUN_HIDDEN (no_ip_msdp_peer
,
6341 no_ip_msdp_peer_cmd
,
6342 "no ip msdp peer A.B.C.D",
6346 "Delete MSDP peer\n"
6347 "peer ip address\n")
6349 return ip_no_msdp_peer_cmd_worker(vty
, argv
[4]->arg
);
6352 static int ip_msdp_mesh_group_member_cmd_worker(struct vty
*vty
, const char *mg
,
6355 enum pim_msdp_err result
;
6356 struct in_addr mbr_ip
;
6358 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
6360 vty_out(vty
, "%% Bad member address %s: errno=%d: %s%s", mbr
,
6361 errno
, safe_strerror(errno
), VTY_NEWLINE
);
6365 result
= pim_msdp_mg_mbr_add(mg
, mbr_ip
);
6367 case PIM_MSDP_ERR_NONE
:
6369 case PIM_MSDP_ERR_OOM
:
6370 vty_out(vty
, "%% Out of memory%s", VTY_NEWLINE
);
6372 case PIM_MSDP_ERR_MG_MBR_EXISTS
:
6373 vty_out(vty
, "%% mesh-group member exists%s", VTY_NEWLINE
);
6375 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
6376 vty_out(vty
, "%% Only one mesh-group allowed currently%s",
6380 vty_out(vty
, "%% member add failed%s", VTY_NEWLINE
);
6383 return result
? CMD_WARNING
: CMD_SUCCESS
;
6386 DEFUN (ip_msdp_mesh_group_member
,
6387 ip_msdp_mesh_group_member_cmd
,
6388 "ip msdp mesh-group WORD member A.B.C.D",
6391 "Configure MSDP mesh-group\n"
6393 "mesh group member\n"
6394 "peer ip address\n")
6396 return ip_msdp_mesh_group_member_cmd_worker(vty
, argv
[3]->arg
,
6400 static int ip_no_msdp_mesh_group_member_cmd_worker(struct vty
*vty
,
6404 enum pim_msdp_err result
;
6405 struct in_addr mbr_ip
;
6407 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
6409 vty_out(vty
, "%% Bad member address %s: errno=%d: %s%s", mbr
,
6410 errno
, safe_strerror(errno
), VTY_NEWLINE
);
6414 result
= pim_msdp_mg_mbr_del(mg
, mbr_ip
);
6416 case PIM_MSDP_ERR_NONE
:
6418 case PIM_MSDP_ERR_NO_MG
:
6419 vty_out(vty
, "%% mesh-group does not exist%s", VTY_NEWLINE
);
6421 case PIM_MSDP_ERR_NO_MG_MBR
:
6422 vty_out(vty
, "%% mesh-group member does not exist%s",
6426 vty_out(vty
, "%% mesh-group member del failed%s", VTY_NEWLINE
);
6429 return result
? CMD_WARNING
: CMD_SUCCESS
;
6431 DEFUN (no_ip_msdp_mesh_group_member
,
6432 no_ip_msdp_mesh_group_member_cmd
,
6433 "no ip msdp mesh-group WORD member A.B.C.D",
6437 "Delete MSDP mesh-group member\n"
6439 "mesh group member\n"
6440 "peer ip address\n")
6442 return ip_no_msdp_mesh_group_member_cmd_worker(vty
, argv
[4]->arg
,
6446 static int ip_msdp_mesh_group_source_cmd_worker(struct vty
*vty
, const char *mg
,
6449 enum pim_msdp_err result
;
6450 struct in_addr src_ip
;
6452 result
= inet_pton(AF_INET
, src
, &src_ip
);
6454 vty_out(vty
, "%% Bad source address %s: errno=%d: %s%s", src
,
6455 errno
, safe_strerror(errno
), VTY_NEWLINE
);
6459 result
= pim_msdp_mg_src_add(mg
, src_ip
);
6461 case PIM_MSDP_ERR_NONE
:
6463 case PIM_MSDP_ERR_OOM
:
6464 vty_out(vty
, "%% Out of memory%s", VTY_NEWLINE
);
6466 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
6467 vty_out(vty
, "%% Only one mesh-group allowed currently%s",
6471 vty_out(vty
, "%% source add failed%s", VTY_NEWLINE
);
6474 return result
? CMD_WARNING
: CMD_SUCCESS
;
6478 DEFUN (ip_msdp_mesh_group_source
,
6479 ip_msdp_mesh_group_source_cmd
,
6480 "ip msdp mesh-group WORD source A.B.C.D",
6483 "Configure MSDP mesh-group\n"
6485 "mesh group local address\n"
6486 "source ip address for the TCP connection\n")
6488 return ip_msdp_mesh_group_source_cmd_worker(vty
, argv
[3]->arg
,
6492 static int ip_no_msdp_mesh_group_source_cmd_worker(struct vty
*vty
,
6495 enum pim_msdp_err result
;
6497 result
= pim_msdp_mg_src_del(mg
);
6499 case PIM_MSDP_ERR_NONE
:
6501 case PIM_MSDP_ERR_NO_MG
:
6502 vty_out(vty
, "%% mesh-group does not exist%s", VTY_NEWLINE
);
6505 vty_out(vty
, "%% mesh-group source del failed%s", VTY_NEWLINE
);
6508 return result
? CMD_WARNING
: CMD_SUCCESS
;
6511 static int ip_no_msdp_mesh_group_cmd_worker(struct vty
*vty
, const char *mg
)
6513 enum pim_msdp_err result
;
6515 result
= pim_msdp_mg_del(mg
);
6517 case PIM_MSDP_ERR_NONE
:
6519 case PIM_MSDP_ERR_NO_MG
:
6520 vty_out(vty
, "%% mesh-group does not exist%s", VTY_NEWLINE
);
6523 vty_out(vty
, "%% mesh-group source del failed%s", VTY_NEWLINE
);
6526 return result
? CMD_WARNING
: CMD_SUCCESS
;
6529 DEFUN (no_ip_msdp_mesh_group_source
,
6530 no_ip_msdp_mesh_group_source_cmd
,
6531 "no ip msdp mesh-group WORD source [A.B.C.D]",
6535 "Delete MSDP mesh-group source\n"
6537 "mesh group source\n"
6538 "mesh group local address\n")
6541 return ip_no_msdp_mesh_group_cmd_worker(vty
, argv
[6]->arg
);
6543 return ip_no_msdp_mesh_group_source_cmd_worker(vty
,
6547 static void print_empty_json_obj(struct vty
*vty
)
6550 json
= json_object_new_object();
6551 vty_out(vty
, "%s%s",
6552 json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
),
6554 json_object_free(json
);
6557 static void ip_msdp_show_mesh_group(struct vty
*vty
, u_char uj
)
6559 struct listnode
*mbrnode
;
6560 struct pim_msdp_mg_mbr
*mbr
;
6561 struct pim_msdp_mg
*mg
= msdp
->mg
;
6562 char mbr_str
[INET_ADDRSTRLEN
];
6563 char src_str
[INET_ADDRSTRLEN
];
6564 char state_str
[PIM_MSDP_STATE_STRLEN
];
6565 enum pim_msdp_peer_state state
;
6566 json_object
*json
= NULL
;
6567 json_object
*json_mg_row
= NULL
;
6568 json_object
*json_members
= NULL
;
6569 json_object
*json_row
= NULL
;
6573 print_empty_json_obj(vty
);
6577 pim_inet4_dump("<source?>", mg
->src_ip
, src_str
, sizeof(src_str
));
6579 json
= json_object_new_object();
6580 /* currently there is only one mesh group but we should still
6582 * it a dict with mg-name as key */
6583 json_mg_row
= json_object_new_object();
6584 json_object_string_add(json_mg_row
, "name",
6585 mg
->mesh_group_name
);
6586 json_object_string_add(json_mg_row
, "source", src_str
);
6588 vty_out(vty
, "Mesh group : %s%s", mg
->mesh_group_name
,
6590 vty_out(vty
, " Source : %s%s", src_str
, VTY_NEWLINE
);
6591 vty_out(vty
, " Member State%s", VTY_NEWLINE
);
6594 for (ALL_LIST_ELEMENTS_RO(mg
->mbr_list
, mbrnode
, mbr
)) {
6595 pim_inet4_dump("<mbr?>", mbr
->mbr_ip
, mbr_str
, sizeof(mbr_str
));
6597 state
= mbr
->mp
->state
;
6599 state
= PIM_MSDP_DISABLED
;
6601 pim_msdp_state_dump(state
, state_str
, sizeof(state_str
));
6603 json_row
= json_object_new_object();
6604 json_object_string_add(json_row
, "member", mbr_str
);
6605 json_object_string_add(json_row
, "state", state_str
);
6606 if (!json_members
) {
6607 json_members
= json_object_new_object();
6608 json_object_object_add(json_mg_row
, "members",
6611 json_object_object_add(json_members
, mbr_str
, json_row
);
6613 vty_out(vty
, " %-15s %11s%s", mbr_str
, state_str
,
6619 json_object_object_add(json
, mg
->mesh_group_name
, json_mg_row
);
6620 vty_out(vty
, "%s%s", json_object_to_json_string_ext(
6621 json
, JSON_C_TO_STRING_PRETTY
),
6623 json_object_free(json
);
6627 DEFUN (show_ip_msdp_mesh_group
,
6628 show_ip_msdp_mesh_group_cmd
,
6629 "show ip msdp mesh-group [json]",
6633 "MSDP mesh-group information\n"
6634 "JavaScript Object Notation\n")
6636 u_char uj
= use_json(argc
, argv
);
6637 ip_msdp_show_mesh_group(vty
, uj
);
6642 static void ip_msdp_show_peers(struct vty
*vty
, u_char uj
)
6644 struct listnode
*mpnode
;
6645 struct pim_msdp_peer
*mp
;
6646 char peer_str
[INET_ADDRSTRLEN
];
6647 char local_str
[INET_ADDRSTRLEN
];
6648 char state_str
[PIM_MSDP_STATE_STRLEN
];
6649 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
6651 json_object
*json
= NULL
;
6652 json_object
*json_row
= NULL
;
6656 json
= json_object_new_object();
6659 "Peer Local State Uptime SaCnt%s",
6663 for (ALL_LIST_ELEMENTS_RO(msdp
->peer_list
, mpnode
, mp
)) {
6664 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
6665 now
= pim_time_monotonic_sec();
6666 pim_time_uptime(timebuf
, sizeof(timebuf
),
6669 strcpy(timebuf
, "-");
6671 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
6672 pim_inet4_dump("<local?>", mp
->local
, local_str
,
6674 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
6676 json_row
= json_object_new_object();
6677 json_object_string_add(json_row
, "peer", peer_str
);
6678 json_object_string_add(json_row
, "local", local_str
);
6679 json_object_string_add(json_row
, "state", state_str
);
6680 json_object_string_add(json_row
, "upTime", timebuf
);
6681 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
6682 json_object_object_add(json
, peer_str
, json_row
);
6684 vty_out(vty
, "%-15s %15s %11s %8s %6d%s", peer_str
,
6685 local_str
, state_str
, timebuf
, mp
->sa_cnt
,
6691 vty_out(vty
, "%s%s", json_object_to_json_string_ext(
6692 json
, JSON_C_TO_STRING_PRETTY
),
6694 json_object_free(json
);
6698 static void ip_msdp_show_peers_detail(struct vty
*vty
, const char *peer
,
6701 struct listnode
*mpnode
;
6702 struct pim_msdp_peer
*mp
;
6703 char peer_str
[INET_ADDRSTRLEN
];
6704 char local_str
[INET_ADDRSTRLEN
];
6705 char state_str
[PIM_MSDP_STATE_STRLEN
];
6706 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
6707 char katimer
[PIM_MSDP_TIMER_STRLEN
];
6708 char crtimer
[PIM_MSDP_TIMER_STRLEN
];
6709 char holdtimer
[PIM_MSDP_TIMER_STRLEN
];
6711 json_object
*json
= NULL
;
6712 json_object
*json_row
= NULL
;
6715 json
= json_object_new_object();
6718 for (ALL_LIST_ELEMENTS_RO(msdp
->peer_list
, mpnode
, mp
)) {
6719 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
6720 if (strcmp(peer
, "detail") && strcmp(peer
, peer_str
))
6723 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
6724 now
= pim_time_monotonic_sec();
6725 pim_time_uptime(timebuf
, sizeof(timebuf
),
6728 strcpy(timebuf
, "-");
6730 pim_inet4_dump("<local?>", mp
->local
, local_str
,
6732 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
6733 pim_time_timer_to_hhmmss(katimer
, sizeof(katimer
),
6735 pim_time_timer_to_hhmmss(crtimer
, sizeof(crtimer
),
6737 pim_time_timer_to_hhmmss(holdtimer
, sizeof(holdtimer
),
6741 json_row
= json_object_new_object();
6742 json_object_string_add(json_row
, "peer", peer_str
);
6743 json_object_string_add(json_row
, "local", local_str
);
6744 json_object_string_add(json_row
, "meshGroupName",
6745 mp
->mesh_group_name
);
6746 json_object_string_add(json_row
, "state", state_str
);
6747 json_object_string_add(json_row
, "upTime", timebuf
);
6748 json_object_string_add(json_row
, "keepAliveTimer",
6750 json_object_string_add(json_row
, "connRetryTimer",
6752 json_object_string_add(json_row
, "holdTimer",
6754 json_object_string_add(json_row
, "lastReset",
6756 json_object_int_add(json_row
, "connAttempts",
6758 json_object_int_add(json_row
, "establishedChanges",
6760 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
6761 json_object_int_add(json_row
, "kaSent", mp
->ka_tx_cnt
);
6762 json_object_int_add(json_row
, "kaRcvd", mp
->ka_rx_cnt
);
6763 json_object_int_add(json_row
, "saSent", mp
->sa_tx_cnt
);
6764 json_object_int_add(json_row
, "saRcvd", mp
->sa_rx_cnt
);
6765 json_object_object_add(json
, peer_str
, json_row
);
6767 vty_out(vty
, "Peer : %s%s", peer_str
, VTY_NEWLINE
);
6768 vty_out(vty
, " Local : %s%s", local_str
,
6770 vty_out(vty
, " Mesh Group : %s%s",
6771 mp
->mesh_group_name
, VTY_NEWLINE
);
6772 vty_out(vty
, " State : %s%s", state_str
,
6774 vty_out(vty
, " Uptime : %s%s", timebuf
,
6777 vty_out(vty
, " Keepalive Timer : %s%s", katimer
,
6779 vty_out(vty
, " Conn Retry Timer : %s%s", crtimer
,
6781 vty_out(vty
, " Hold Timer : %s%s", holdtimer
,
6783 vty_out(vty
, " Last Reset : %s%s",
6784 mp
->last_reset
, VTY_NEWLINE
);
6785 vty_out(vty
, " Conn Attempts : %d%s",
6786 mp
->conn_attempts
, VTY_NEWLINE
);
6787 vty_out(vty
, " Established Changes : %d%s",
6788 mp
->est_flaps
, VTY_NEWLINE
);
6789 vty_out(vty
, " SA Count : %d%s", mp
->sa_cnt
,
6791 vty_out(vty
, " Statistics :%s", VTY_NEWLINE
);
6792 vty_out(vty
, " Sent Rcvd%s",
6794 vty_out(vty
, " Keepalives : %10d %10d%s",
6795 mp
->ka_tx_cnt
, mp
->ka_rx_cnt
, VTY_NEWLINE
);
6796 vty_out(vty
, " SAs : %10d %10d%s",
6797 mp
->sa_tx_cnt
, mp
->sa_rx_cnt
, VTY_NEWLINE
);
6798 vty_out(vty
, "%s", VTY_NEWLINE
);
6803 vty_out(vty
, "%s%s", json_object_to_json_string_ext(
6804 json
, JSON_C_TO_STRING_PRETTY
),
6806 json_object_free(json
);
6810 DEFUN (show_ip_msdp_peer_detail
,
6811 show_ip_msdp_peer_detail_cmd
,
6812 "show ip msdp peer [detail|A.B.C.D] [json]",
6816 "MSDP peer information\n"
6819 "JavaScript Object Notation\n")
6821 u_char uj
= use_json(argc
, argv
);
6826 ip_msdp_show_peers_detail(vty
, argv
[4]->arg
, uj
);
6828 ip_msdp_show_peers(vty
, uj
);
6833 static void ip_msdp_show_sa(struct vty
*vty
, u_char uj
)
6835 struct listnode
*sanode
;
6836 struct pim_msdp_sa
*sa
;
6837 char src_str
[INET_ADDRSTRLEN
];
6838 char grp_str
[INET_ADDRSTRLEN
];
6839 char rp_str
[INET_ADDRSTRLEN
];
6840 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
6844 json_object
*json
= NULL
;
6845 json_object
*json_group
= NULL
;
6846 json_object
*json_row
= NULL
;
6849 json
= json_object_new_object();
6852 "Source Group RP Local SPT Uptime%s",
6856 for (ALL_LIST_ELEMENTS_RO(msdp
->sa_list
, sanode
, sa
)) {
6857 now
= pim_time_monotonic_sec();
6858 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
6859 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
6860 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
6861 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
6862 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
6864 strcpy(spt_str
, "yes");
6866 strcpy(spt_str
, "no");
6869 strcpy(rp_str
, "-");
6870 strcpy(spt_str
, "-");
6872 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
6873 strcpy(local_str
, "yes");
6875 strcpy(local_str
, "no");
6878 json_object_object_get_ex(json
, grp_str
, &json_group
);
6881 json_group
= json_object_new_object();
6882 json_object_object_add(json
, grp_str
,
6886 json_row
= json_object_new_object();
6887 json_object_string_add(json_row
, "source", src_str
);
6888 json_object_string_add(json_row
, "group", grp_str
);
6889 json_object_string_add(json_row
, "rp", rp_str
);
6890 json_object_string_add(json_row
, "local", local_str
);
6891 json_object_string_add(json_row
, "sptSetup", spt_str
);
6892 json_object_string_add(json_row
, "upTime", timebuf
);
6893 json_object_object_add(json_group
, src_str
, json_row
);
6895 vty_out(vty
, "%-15s %15s %15s %5c %3c %8s%s",
6896 src_str
, grp_str
, rp_str
, local_str
[0],
6897 spt_str
[0], timebuf
, VTY_NEWLINE
);
6903 vty_out(vty
, "%s%s", json_object_to_json_string_ext(
6904 json
, JSON_C_TO_STRING_PRETTY
),
6906 json_object_free(json
);
6910 static void ip_msdp_show_sa_entry_detail(struct pim_msdp_sa
*sa
,
6911 const char *src_str
,
6912 const char *grp_str
, struct vty
*vty
,
6913 u_char uj
, json_object
*json
)
6915 char rp_str
[INET_ADDRSTRLEN
];
6916 char peer_str
[INET_ADDRSTRLEN
];
6917 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
6920 char statetimer
[PIM_MSDP_TIMER_STRLEN
];
6922 json_object
*json_group
= NULL
;
6923 json_object
*json_row
= NULL
;
6925 now
= pim_time_monotonic_sec();
6926 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
6927 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
6928 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
6929 pim_inet4_dump("<peer?>", sa
->peer
, peer_str
, sizeof(peer_str
));
6931 strcpy(spt_str
, "yes");
6933 strcpy(spt_str
, "no");
6936 strcpy(rp_str
, "-");
6937 strcpy(peer_str
, "-");
6938 strcpy(spt_str
, "-");
6940 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
6941 strcpy(local_str
, "yes");
6943 strcpy(local_str
, "no");
6945 pim_time_timer_to_hhmmss(statetimer
, sizeof(statetimer
),
6946 sa
->sa_state_timer
);
6948 json_object_object_get_ex(json
, grp_str
, &json_group
);
6951 json_group
= json_object_new_object();
6952 json_object_object_add(json
, grp_str
, json_group
);
6955 json_row
= json_object_new_object();
6956 json_object_string_add(json_row
, "source", src_str
);
6957 json_object_string_add(json_row
, "group", grp_str
);
6958 json_object_string_add(json_row
, "rp", rp_str
);
6959 json_object_string_add(json_row
, "local", local_str
);
6960 json_object_string_add(json_row
, "sptSetup", spt_str
);
6961 json_object_string_add(json_row
, "upTime", timebuf
);
6962 json_object_string_add(json_row
, "stateTimer", statetimer
);
6963 json_object_object_add(json_group
, src_str
, json_row
);
6965 vty_out(vty
, "SA : %s%s", sa
->sg_str
, VTY_NEWLINE
);
6966 vty_out(vty
, " RP : %s%s", rp_str
, VTY_NEWLINE
);
6967 vty_out(vty
, " Peer : %s%s", peer_str
, VTY_NEWLINE
);
6968 vty_out(vty
, " Local : %s%s", local_str
, VTY_NEWLINE
);
6969 vty_out(vty
, " SPT Setup : %s%s", spt_str
, VTY_NEWLINE
);
6970 vty_out(vty
, " Uptime : %s%s", timebuf
, VTY_NEWLINE
);
6971 vty_out(vty
, " State Timer : %s%s", statetimer
, VTY_NEWLINE
);
6972 vty_out(vty
, "%s", VTY_NEWLINE
);
6976 static void ip_msdp_show_sa_detail(struct vty
*vty
, u_char uj
)
6978 struct listnode
*sanode
;
6979 struct pim_msdp_sa
*sa
;
6980 char src_str
[INET_ADDRSTRLEN
];
6981 char grp_str
[INET_ADDRSTRLEN
];
6982 json_object
*json
= NULL
;
6985 json
= json_object_new_object();
6988 for (ALL_LIST_ELEMENTS_RO(msdp
->sa_list
, sanode
, sa
)) {
6989 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
6990 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
6991 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
, uj
,
6996 vty_out(vty
, "%s%s", json_object_to_json_string_ext(
6997 json
, JSON_C_TO_STRING_PRETTY
),
6999 json_object_free(json
);
7003 DEFUN (show_ip_msdp_sa_detail
,
7004 show_ip_msdp_sa_detail_cmd
,
7005 "show ip msdp sa detail [json]",
7009 "MSDP active-source information\n"
7011 "JavaScript Object Notation\n")
7013 u_char uj
= use_json(argc
, argv
);
7014 ip_msdp_show_sa_detail(vty
, uj
);
7019 static void ip_msdp_show_sa_addr(struct vty
*vty
, const char *addr
, u_char uj
)
7021 struct listnode
*sanode
;
7022 struct pim_msdp_sa
*sa
;
7023 char src_str
[INET_ADDRSTRLEN
];
7024 char grp_str
[INET_ADDRSTRLEN
];
7025 json_object
*json
= NULL
;
7028 json
= json_object_new_object();
7031 for (ALL_LIST_ELEMENTS_RO(msdp
->sa_list
, sanode
, sa
)) {
7032 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
7033 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
7034 if (!strcmp(addr
, src_str
) || !strcmp(addr
, grp_str
)) {
7035 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
7041 vty_out(vty
, "%s%s", json_object_to_json_string_ext(
7042 json
, JSON_C_TO_STRING_PRETTY
),
7044 json_object_free(json
);
7048 static void ip_msdp_show_sa_sg(struct vty
*vty
, const char *src
,
7049 const char *grp
, u_char uj
)
7051 struct listnode
*sanode
;
7052 struct pim_msdp_sa
*sa
;
7053 char src_str
[INET_ADDRSTRLEN
];
7054 char grp_str
[INET_ADDRSTRLEN
];
7055 json_object
*json
= NULL
;
7058 json
= json_object_new_object();
7061 for (ALL_LIST_ELEMENTS_RO(msdp
->sa_list
, sanode
, sa
)) {
7062 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
7063 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
7064 if (!strcmp(src
, src_str
) && !strcmp(grp
, grp_str
)) {
7065 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
7071 vty_out(vty
, "%s%s", json_object_to_json_string_ext(
7072 json
, JSON_C_TO_STRING_PRETTY
),
7074 json_object_free(json
);
7078 DEFUN (show_ip_msdp_sa_sg
,
7079 show_ip_msdp_sa_sg_cmd
,
7080 "show ip msdp sa [A.B.C.D [A.B.C.D]] [json]",
7084 "MSDP active-source information\n"
7085 "source or group ip\n"
7087 "JavaScript Object Notation\n")
7089 u_char uj
= use_json(argc
, argv
);
7094 ip_msdp_show_sa_sg(vty
, argv
[4]->arg
, argv
[5]->arg
, uj
);
7096 ip_msdp_show_sa_addr(vty
, argv
[4]->arg
, uj
);
7098 ip_msdp_show_sa(vty
, uj
);
7105 install_node(&pim_global_node
, pim_global_config_write
); /* PIM_NODE */
7106 install_node(&interface_node
,
7107 pim_interface_config_write
); /* INTERFACE_NODE */
7110 install_node(&debug_node
, pim_debug_config_write
);
7112 install_element(CONFIG_NODE
, &ip_multicast_routing_cmd
);
7113 install_element(CONFIG_NODE
, &no_ip_multicast_routing_cmd
);
7114 install_element(CONFIG_NODE
, &ip_pim_rp_cmd
);
7115 install_element(CONFIG_NODE
, &no_ip_pim_rp_cmd
);
7116 install_element(CONFIG_NODE
, &ip_pim_rp_prefix_list_cmd
);
7117 install_element(CONFIG_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
7118 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
7119 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
7120 install_element(CONFIG_NODE
, &ip_pim_ssm_prefix_list_cmd
);
7121 install_element(CONFIG_NODE
, &ip_pim_register_suppress_cmd
);
7122 install_element(CONFIG_NODE
, &no_ip_pim_register_suppress_cmd
);
7123 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
7124 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
7125 install_element(CONFIG_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
7126 install_element(CONFIG_NODE
,
7127 &no_ip_pim_spt_switchover_infinity_plist_cmd
);
7128 install_element(CONFIG_NODE
, &ip_pim_joinprune_time_cmd
);
7129 install_element(CONFIG_NODE
, &no_ip_pim_joinprune_time_cmd
);
7130 install_element(CONFIG_NODE
, &ip_pim_keep_alive_cmd
);
7131 install_element(CONFIG_NODE
, &no_ip_pim_keep_alive_cmd
);
7132 install_element(CONFIG_NODE
, &ip_pim_packets_cmd
);
7133 install_element(CONFIG_NODE
, &no_ip_pim_packets_cmd
);
7134 install_element(CONFIG_NODE
, &ip_ssmpingd_cmd
);
7135 install_element(CONFIG_NODE
, &no_ip_ssmpingd_cmd
);
7136 install_element(CONFIG_NODE
, &ip_msdp_peer_cmd
);
7137 install_element(CONFIG_NODE
, &no_ip_msdp_peer_cmd
);
7138 install_element(CONFIG_NODE
, &ip_pim_ecmp_cmd
);
7139 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_cmd
);
7140 install_element(CONFIG_NODE
, &ip_pim_ecmp_rebalance_cmd
);
7141 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
7143 install_element(INTERFACE_NODE
, &interface_ip_igmp_cmd
);
7144 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_cmd
);
7145 install_element(INTERFACE_NODE
, &interface_ip_igmp_join_cmd
);
7146 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_join_cmd
);
7147 install_element(INTERFACE_NODE
, &interface_ip_igmp_version_cmd
);
7148 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_version_cmd
);
7149 install_element(INTERFACE_NODE
, &interface_ip_igmp_query_interval_cmd
);
7150 install_element(INTERFACE_NODE
,
7151 &interface_no_ip_igmp_query_interval_cmd
);
7152 install_element(INTERFACE_NODE
,
7153 &interface_ip_igmp_query_max_response_time_cmd
);
7154 install_element(INTERFACE_NODE
,
7155 &interface_no_ip_igmp_query_max_response_time_cmd
);
7156 install_element(INTERFACE_NODE
,
7157 &interface_ip_igmp_query_max_response_time_dsec_cmd
);
7158 install_element(INTERFACE_NODE
,
7159 &interface_no_ip_igmp_query_max_response_time_dsec_cmd
);
7160 install_element(INTERFACE_NODE
, &interface_ip_pim_ssm_cmd
);
7161 install_element(INTERFACE_NODE
, &interface_no_ip_pim_ssm_cmd
);
7162 install_element(INTERFACE_NODE
, &interface_ip_pim_sm_cmd
);
7163 install_element(INTERFACE_NODE
, &interface_no_ip_pim_sm_cmd
);
7164 install_element(INTERFACE_NODE
, &interface_ip_pim_drprio_cmd
);
7165 install_element(INTERFACE_NODE
, &interface_no_ip_pim_drprio_cmd
);
7166 install_element(INTERFACE_NODE
, &interface_ip_pim_hello_cmd
);
7167 install_element(INTERFACE_NODE
, &interface_no_ip_pim_hello_cmd
);
7169 // Static mroutes NEB
7170 install_element(INTERFACE_NODE
, &interface_ip_mroute_cmd
);
7171 install_element(INTERFACE_NODE
, &interface_ip_mroute_source_cmd
);
7172 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_cmd
);
7173 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_source_cmd
);
7175 install_element(VIEW_NODE
, &show_ip_igmp_interface_cmd
);
7176 install_element(VIEW_NODE
, &show_ip_igmp_join_cmd
);
7177 install_element(VIEW_NODE
, &show_ip_igmp_groups_cmd
);
7178 install_element(VIEW_NODE
, &show_ip_igmp_groups_retransmissions_cmd
);
7179 install_element(VIEW_NODE
, &show_ip_igmp_sources_cmd
);
7180 install_element(VIEW_NODE
, &show_ip_igmp_sources_retransmissions_cmd
);
7181 install_element(VIEW_NODE
, &show_ip_pim_assert_cmd
);
7182 install_element(VIEW_NODE
, &show_ip_pim_assert_internal_cmd
);
7183 install_element(VIEW_NODE
, &show_ip_pim_assert_metric_cmd
);
7184 install_element(VIEW_NODE
, &show_ip_pim_assert_winner_metric_cmd
);
7185 install_element(VIEW_NODE
, &show_ip_pim_interface_cmd
);
7186 install_element(VIEW_NODE
, &show_ip_pim_join_cmd
);
7187 install_element(VIEW_NODE
, &show_ip_pim_local_membership_cmd
);
7188 install_element(VIEW_NODE
, &show_ip_pim_neighbor_cmd
);
7189 install_element(VIEW_NODE
, &show_ip_pim_rpf_cmd
);
7190 install_element(VIEW_NODE
, &show_ip_pim_secondary_cmd
);
7191 install_element(VIEW_NODE
, &show_ip_pim_state_cmd
);
7192 install_element(VIEW_NODE
, &show_ip_pim_upstream_cmd
);
7193 install_element(VIEW_NODE
, &show_ip_pim_upstream_join_desired_cmd
);
7194 install_element(VIEW_NODE
, &show_ip_pim_upstream_rpf_cmd
);
7195 install_element(VIEW_NODE
, &show_ip_pim_rp_cmd
);
7196 install_element(VIEW_NODE
, &show_ip_multicast_cmd
);
7197 install_element(VIEW_NODE
, &show_ip_mroute_cmd
);
7198 install_element(VIEW_NODE
, &show_ip_mroute_count_cmd
);
7199 install_element(VIEW_NODE
, &show_ip_rib_cmd
);
7200 install_element(VIEW_NODE
, &show_ip_ssmpingd_cmd
);
7201 install_element(VIEW_NODE
, &show_debugging_pim_cmd
);
7202 install_element(VIEW_NODE
, &show_ip_pim_nexthop_cmd
);
7203 install_element(VIEW_NODE
, &show_ip_pim_nexthop_lookup_cmd
);
7205 install_element(ENABLE_NODE
, &clear_ip_interfaces_cmd
);
7206 install_element(ENABLE_NODE
, &clear_ip_igmp_interfaces_cmd
);
7207 install_element(ENABLE_NODE
, &clear_ip_mroute_cmd
);
7208 install_element(ENABLE_NODE
, &clear_ip_pim_interfaces_cmd
);
7209 install_element(ENABLE_NODE
, &clear_ip_pim_oil_cmd
);
7211 install_element(ENABLE_NODE
, &debug_igmp_cmd
);
7212 install_element(ENABLE_NODE
, &no_debug_igmp_cmd
);
7213 install_element(ENABLE_NODE
, &debug_igmp_events_cmd
);
7214 install_element(ENABLE_NODE
, &no_debug_igmp_events_cmd
);
7215 install_element(ENABLE_NODE
, &debug_igmp_packets_cmd
);
7216 install_element(ENABLE_NODE
, &no_debug_igmp_packets_cmd
);
7217 install_element(ENABLE_NODE
, &debug_igmp_trace_cmd
);
7218 install_element(ENABLE_NODE
, &no_debug_igmp_trace_cmd
);
7219 install_element(ENABLE_NODE
, &debug_mroute_cmd
);
7220 install_element(ENABLE_NODE
, &debug_mroute_detail_cmd
);
7221 install_element(ENABLE_NODE
, &no_debug_mroute_cmd
);
7222 install_element(ENABLE_NODE
, &no_debug_mroute_detail_cmd
);
7223 install_element(ENABLE_NODE
, &debug_static_cmd
);
7224 install_element(ENABLE_NODE
, &no_debug_static_cmd
);
7225 install_element(ENABLE_NODE
, &debug_pim_cmd
);
7226 install_element(ENABLE_NODE
, &no_debug_pim_cmd
);
7227 install_element(ENABLE_NODE
, &debug_pim_events_cmd
);
7228 install_element(ENABLE_NODE
, &no_debug_pim_events_cmd
);
7229 install_element(ENABLE_NODE
, &debug_pim_packets_cmd
);
7230 install_element(ENABLE_NODE
, &no_debug_pim_packets_cmd
);
7231 install_element(ENABLE_NODE
, &debug_pim_packetdump_send_cmd
);
7232 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_send_cmd
);
7233 install_element(ENABLE_NODE
, &debug_pim_packetdump_recv_cmd
);
7234 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_recv_cmd
);
7235 install_element(ENABLE_NODE
, &debug_pim_trace_cmd
);
7236 install_element(ENABLE_NODE
, &no_debug_pim_trace_cmd
);
7237 install_element(ENABLE_NODE
, &debug_ssmpingd_cmd
);
7238 install_element(ENABLE_NODE
, &no_debug_ssmpingd_cmd
);
7239 install_element(ENABLE_NODE
, &debug_pim_zebra_cmd
);
7240 install_element(ENABLE_NODE
, &no_debug_pim_zebra_cmd
);
7241 install_element(ENABLE_NODE
, &debug_msdp_cmd
);
7242 install_element(ENABLE_NODE
, &no_debug_msdp_cmd
);
7243 install_element(ENABLE_NODE
, &undebug_msdp_cmd
);
7244 install_element(ENABLE_NODE
, &debug_msdp_events_cmd
);
7245 install_element(ENABLE_NODE
, &no_debug_msdp_events_cmd
);
7246 install_element(ENABLE_NODE
, &undebug_msdp_events_cmd
);
7247 install_element(ENABLE_NODE
, &debug_msdp_packets_cmd
);
7248 install_element(ENABLE_NODE
, &no_debug_msdp_packets_cmd
);
7249 install_element(ENABLE_NODE
, &undebug_msdp_packets_cmd
);
7251 install_element(CONFIG_NODE
, &debug_igmp_cmd
);
7252 install_element(CONFIG_NODE
, &no_debug_igmp_cmd
);
7253 install_element(CONFIG_NODE
, &debug_igmp_events_cmd
);
7254 install_element(CONFIG_NODE
, &no_debug_igmp_events_cmd
);
7255 install_element(CONFIG_NODE
, &debug_igmp_packets_cmd
);
7256 install_element(CONFIG_NODE
, &no_debug_igmp_packets_cmd
);
7257 install_element(CONFIG_NODE
, &debug_igmp_trace_cmd
);
7258 install_element(CONFIG_NODE
, &no_debug_igmp_trace_cmd
);
7259 install_element(CONFIG_NODE
, &debug_mroute_cmd
);
7260 install_element(CONFIG_NODE
, &debug_mroute_detail_cmd
);
7261 install_element(CONFIG_NODE
, &no_debug_mroute_cmd
);
7262 install_element(CONFIG_NODE
, &no_debug_mroute_detail_cmd
);
7263 install_element(CONFIG_NODE
, &debug_static_cmd
);
7264 install_element(CONFIG_NODE
, &no_debug_static_cmd
);
7265 install_element(CONFIG_NODE
, &debug_pim_cmd
);
7266 install_element(CONFIG_NODE
, &no_debug_pim_cmd
);
7267 install_element(CONFIG_NODE
, &debug_pim_events_cmd
);
7268 install_element(CONFIG_NODE
, &no_debug_pim_events_cmd
);
7269 install_element(CONFIG_NODE
, &debug_pim_packets_cmd
);
7270 install_element(CONFIG_NODE
, &no_debug_pim_packets_cmd
);
7271 install_element(CONFIG_NODE
, &debug_pim_trace_cmd
);
7272 install_element(CONFIG_NODE
, &no_debug_pim_trace_cmd
);
7273 install_element(CONFIG_NODE
, &debug_ssmpingd_cmd
);
7274 install_element(CONFIG_NODE
, &no_debug_ssmpingd_cmd
);
7275 install_element(CONFIG_NODE
, &debug_pim_zebra_cmd
);
7276 install_element(CONFIG_NODE
, &no_debug_pim_zebra_cmd
);
7277 install_element(CONFIG_NODE
, &debug_msdp_cmd
);
7278 install_element(CONFIG_NODE
, &no_debug_msdp_cmd
);
7279 install_element(CONFIG_NODE
, &undebug_msdp_cmd
);
7280 install_element(CONFIG_NODE
, &debug_msdp_events_cmd
);
7281 install_element(CONFIG_NODE
, &no_debug_msdp_events_cmd
);
7282 install_element(CONFIG_NODE
, &undebug_msdp_events_cmd
);
7283 install_element(CONFIG_NODE
, &debug_msdp_packets_cmd
);
7284 install_element(CONFIG_NODE
, &no_debug_msdp_packets_cmd
);
7285 install_element(CONFIG_NODE
, &undebug_msdp_packets_cmd
);
7286 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_member_cmd
);
7287 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
7288 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_source_cmd
);
7289 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
7290 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_cmd
);
7291 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_cmd
);
7292 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_cmd
);
7293 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_cmd
);
7294 install_element(VIEW_NODE
, &show_ip_pim_ssm_range_cmd
);
7295 install_element(VIEW_NODE
, &show_ip_pim_group_type_cmd
);
7296 install_element(INTERFACE_NODE
, &interface_pim_use_source_cmd
);
7297 install_element(INTERFACE_NODE
, &interface_no_pim_use_source_cmd
);