3 * Copyright (C) 2008 Everton da Silva Marques
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; see the file COPYING; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
34 #include "pim_mroute.h"
36 #include "pim_iface.h"
38 #include "pim_mroute.h"
41 #include "pim_igmpv3.h"
46 #include "pim_neighbor.h"
48 #include "pim_ifchannel.h"
49 #include "pim_hello.h"
51 #include "pim_upstream.h"
53 #include "pim_macro.h"
54 #include "pim_ssmpingd.h"
55 #include "pim_zebra.h"
56 #include "pim_static.h"
58 #include "pim_zlookup.h"
65 static struct cmd_node pim_global_node
= {
66 PIM_NODE
, "", 1 /* vtysh ? yes */
69 static struct cmd_node interface_node
= {
70 INTERFACE_NODE
, "%s(config-if)# ", 1 /* vtysh ? yes */
73 static struct cmd_node debug_node
= {DEBUG_NODE
, "", 1};
75 static struct vrf
*pim_cmd_lookup_vrf(struct vty
*vty
, struct cmd_token
*argv
[],
76 const int argc
, int *idx
)
80 if (argv_find(argv
, argc
, "NAME", idx
))
81 vrf
= vrf_lookup_by_name(argv
[*idx
]->arg
);
83 vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
86 vty_out(vty
, "Specified VRF: %s does not exist\n",
92 static void pim_if_membership_clear(struct interface
*ifp
)
94 struct pim_interface
*pim_ifp
;
99 if (PIM_IF_TEST_PIM(pim_ifp
->options
)
100 && PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
104 pim_ifchannel_membership_clear(ifp
);
108 When PIM is disabled on interface, IGMPv3 local membership
109 information is not injected into PIM interface state.
111 The function pim_if_membership_refresh() fetches all IGMPv3 local
112 membership information into PIM. It is intented to be called
113 whenever PIM is enabled on the interface in order to collect missed
114 local membership information.
116 static void pim_if_membership_refresh(struct interface
*ifp
)
118 struct pim_interface
*pim_ifp
;
119 struct listnode
*sock_node
;
120 struct igmp_sock
*igmp
;
125 if (!PIM_IF_TEST_PIM(pim_ifp
->options
))
127 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
))
131 First clear off membership from all PIM (S,G) entries on the
135 pim_ifchannel_membership_clear(ifp
);
138 Then restore PIM (S,G) membership from all IGMPv3 (S,G) entries on
142 /* scan igmp sockets */
143 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
144 struct listnode
*grpnode
;
145 struct igmp_group
*grp
;
147 /* scan igmp groups */
148 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grpnode
,
150 struct listnode
*srcnode
;
151 struct igmp_source
*src
;
153 /* scan group sources */
154 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
,
157 if (IGMP_SOURCE_TEST_FORWARDING(
158 src
->source_flags
)) {
162 sizeof(struct prefix_sg
));
163 sg
.src
= src
->source_addr
;
164 sg
.grp
= grp
->group_addr
;
165 pim_ifchannel_local_membership_add(ifp
,
169 } /* scan group sources */
170 } /* scan igmp groups */
171 } /* scan igmp sockets */
174 Finally delete every PIM (S,G) entry lacking all state info
177 pim_ifchannel_delete_on_noinfo(ifp
);
180 static void pim_show_assert_helper(struct vty
*vty
,
181 struct pim_interface
*pim_ifp
,
182 struct pim_ifchannel
*ch
,
185 char ch_src_str
[INET_ADDRSTRLEN
];
186 char ch_grp_str
[INET_ADDRSTRLEN
];
187 char winner_str
[INET_ADDRSTRLEN
];
188 struct in_addr ifaddr
;
192 ifaddr
= pim_ifp
->primary_address
;
194 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
,
196 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
,
198 pim_inet4_dump("<assrt_win?>", ch
->ifassert_winner
, winner_str
,
201 pim_time_uptime(uptime
, sizeof(uptime
),
202 now
- ch
->ifassert_creation
);
203 pim_time_timer_to_mmss(timer
, sizeof(timer
),
204 ch
->t_ifassert_timer
);
206 vty_out(vty
, "%-9s %-15s %-15s %-15s %-6s %-15s %-8s %-5s\n",
207 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
,
209 pim_ifchannel_ifassert_name(ch
->ifassert_state
),
210 winner_str
, uptime
, timer
);
213 static void pim_show_assert(struct pim_instance
*pim
, struct vty
*vty
)
215 struct pim_interface
*pim_ifp
;
216 struct pim_ifchannel
*ch
;
217 struct interface
*ifp
;
220 now
= pim_time_monotonic_sec();
223 "Interface Address Source Group State Winner Uptime Timer\n");
225 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
230 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
231 pim_show_assert_helper(vty
, pim_ifp
, ch
, now
);
232 } /* scan interface channels */
236 static void pim_show_assert_internal_helper(struct vty
*vty
,
237 struct pim_interface
*pim_ifp
,
238 struct pim_ifchannel
*ch
)
240 char ch_src_str
[INET_ADDRSTRLEN
];
241 char ch_grp_str
[INET_ADDRSTRLEN
];
242 struct in_addr ifaddr
;
244 ifaddr
= pim_ifp
->primary_address
;
246 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
,
248 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
,
250 vty_out(vty
, "%-9s %-15s %-15s %-15s %-3s %-3s %-3s %-4s\n",
251 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
,
253 PIM_IF_FLAG_TEST_COULD_ASSERT(ch
->flags
) ? "yes" : "no",
254 pim_macro_ch_could_assert_eval(ch
) ? "yes" : "no",
255 PIM_IF_FLAG_TEST_ASSERT_TRACKING_DESIRED(ch
->flags
)
258 pim_macro_assert_tracking_desired_eval(ch
) ? "yes"
262 static void pim_show_assert_internal(struct pim_instance
*pim
, struct vty
*vty
)
264 struct pim_interface
*pim_ifp
;
265 struct pim_ifchannel
*ch
;
266 struct interface
*ifp
;
270 "ECA: Evaluate CouldAssert\n"
271 "ATD: AssertTrackingDesired\n"
272 "eATD: Evaluate AssertTrackingDesired\n\n");
275 "Interface Address Source Group CA eCA ATD eATD\n");
276 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
281 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
282 pim_show_assert_internal_helper(vty
, pim_ifp
, ch
);
283 } /* scan interface channels */
287 static void pim_show_assert_metric_helper(struct vty
*vty
,
288 struct pim_interface
*pim_ifp
,
289 struct pim_ifchannel
*ch
)
291 char ch_src_str
[INET_ADDRSTRLEN
];
292 char ch_grp_str
[INET_ADDRSTRLEN
];
293 char addr_str
[INET_ADDRSTRLEN
];
294 struct pim_assert_metric am
;
295 struct in_addr ifaddr
;
297 ifaddr
= pim_ifp
->primary_address
;
299 am
= pim_macro_spt_assert_metric(&ch
->upstream
->rpf
,
300 pim_ifp
->primary_address
);
302 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
,
304 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
,
306 pim_inet4_dump("<addr?>", am
.ip_address
, addr_str
,
309 vty_out(vty
, "%-9s %-15s %-15s %-15s %-3s %4u %6u %-15s\n",
310 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
,
311 ch_grp_str
, am
.rpt_bit_flag
? "yes" : "no",
312 am
.metric_preference
, am
.route_metric
, addr_str
);
315 static void pim_show_assert_metric(struct pim_instance
*pim
, struct vty
*vty
)
317 struct pim_interface
*pim_ifp
;
318 struct pim_ifchannel
*ch
;
319 struct interface
*ifp
;
322 "Interface Address Source Group RPT Pref Metric Address \n");
324 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
329 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
330 pim_show_assert_metric_helper(vty
, pim_ifp
, ch
);
331 } /* scan interface channels */
335 static void pim_show_assert_winner_metric_helper(struct vty
*vty
,
336 struct pim_interface
*pim_ifp
,
337 struct pim_ifchannel
*ch
)
339 char ch_src_str
[INET_ADDRSTRLEN
];
340 char ch_grp_str
[INET_ADDRSTRLEN
];
341 char addr_str
[INET_ADDRSTRLEN
];
342 struct pim_assert_metric
*am
;
343 struct in_addr ifaddr
;
347 ifaddr
= pim_ifp
->primary_address
;
349 am
= &ch
->ifassert_winner_metric
;
351 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
,
353 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
,
355 pim_inet4_dump("<addr?>", am
->ip_address
, addr_str
,
358 if (am
->metric_preference
== PIM_ASSERT_METRIC_PREFERENCE_MAX
)
359 snprintf(pref_str
, sizeof(pref_str
), "INFI");
361 snprintf(pref_str
, sizeof(pref_str
), "%4u",
362 am
->metric_preference
);
364 if (am
->route_metric
== PIM_ASSERT_ROUTE_METRIC_MAX
)
365 snprintf(metr_str
, sizeof(metr_str
), "INFI");
367 snprintf(metr_str
, sizeof(metr_str
), "%6u",
370 vty_out(vty
, "%-9s %-15s %-15s %-15s %-3s %-4s %-6s %-15s\n",
371 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
,
372 ch_grp_str
, am
->rpt_bit_flag
? "yes" : "no", pref_str
,
376 static void pim_show_assert_winner_metric(struct pim_instance
*pim
,
379 struct pim_interface
*pim_ifp
;
380 struct pim_ifchannel
*ch
;
381 struct interface
*ifp
;
384 "Interface Address Source Group RPT Pref Metric Address \n");
386 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
391 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
392 pim_show_assert_winner_metric_helper(vty
, pim_ifp
, ch
);
393 } /* scan interface channels */
397 static void json_object_pim_ifp_add(struct json_object
*json
,
398 struct interface
*ifp
)
400 struct pim_interface
*pim_ifp
;
403 json_object_string_add(json
, "name", ifp
->name
);
404 json_object_string_add(json
, "state", if_is_up(ifp
) ? "up" : "down");
405 json_object_string_add(json
, "address",
406 inet_ntoa(pim_ifp
->primary_address
));
407 json_object_int_add(json
, "index", ifp
->ifindex
);
409 if (if_is_multicast(ifp
))
410 json_object_boolean_true_add(json
, "flagMulticast");
412 if (if_is_broadcast(ifp
))
413 json_object_boolean_true_add(json
, "flagBroadcast");
415 if (ifp
->flags
& IFF_ALLMULTI
)
416 json_object_boolean_true_add(json
, "flagAllMulticast");
418 if (ifp
->flags
& IFF_PROMISC
)
419 json_object_boolean_true_add(json
, "flagPromiscuous");
421 if (PIM_IF_IS_DELETED(ifp
))
422 json_object_boolean_true_add(json
, "flagDeleted");
424 if (pim_if_lan_delay_enabled(ifp
))
425 json_object_boolean_true_add(json
, "lanDelayEnabled");
428 static void pim_show_membership_helper(struct vty
*vty
,
429 struct pim_interface
*pim_ifp
,
430 struct pim_ifchannel
*ch
,
431 struct json_object
*json
)
433 char ch_src_str
[INET_ADDRSTRLEN
];
434 char ch_grp_str
[INET_ADDRSTRLEN
];
435 json_object
*json_iface
= NULL
;
436 json_object
*json_row
= NULL
;
438 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
,
440 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
,
443 json_object_object_get_ex(json
, ch
->interface
->name
,
446 json_iface
= json_object_new_object();
447 json_object_pim_ifp_add(json_iface
, ch
->interface
);
448 json_object_object_add(json
, ch
->interface
->name
,
452 json_row
= json_object_new_object();
453 json_object_string_add(json_row
, "source", ch_src_str
);
454 json_object_string_add(json_row
, "group", ch_grp_str
);
455 json_object_string_add(
456 json_row
, "localMembership",
457 ch
->local_ifmembership
== PIM_IFMEMBERSHIP_NOINFO
460 json_object_object_add(json_iface
, ch_grp_str
, json_row
);
463 static void pim_show_membership(struct pim_instance
*pim
, struct vty
*vty
,
466 struct pim_interface
*pim_ifp
;
467 struct pim_ifchannel
*ch
;
468 struct interface
*ifp
;
470 json_object
*json
= NULL
;
471 json_object
*json_tmp
= NULL
;
473 json
= json_object_new_object();
475 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
480 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
481 pim_show_membership_helper(vty
, pim_ifp
, ch
, json
);
482 } /* scan interface channels */
486 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
487 json
, JSON_C_TO_STRING_PRETTY
));
490 "Interface Address Source Group Membership\n");
493 * Example of the json data we are traversing
499 * "address":"10.1.20.1",
501 * "flagMulticast":true,
502 * "flagBroadcast":true,
503 * "lanDelayEnabled":true,
506 * "group":"226.10.10.10",
507 * "localMembership":"INCLUDE"
513 /* foreach interface */
514 json_object_object_foreach(json
, key
, val
)
517 /* Find all of the keys where the val is an object. In
519 * above the only one is 226.10.10.10
521 json_object_object_foreach(val
, if_field_key
,
524 type
= json_object_get_type(if_field_val
);
526 if (type
== json_type_object
) {
527 vty_out(vty
, "%-9s ", key
);
529 json_object_object_get_ex(
530 val
, "address", &json_tmp
);
531 vty_out(vty
, "%-15s ",
532 json_object_get_string(
535 json_object_object_get_ex(if_field_val
,
538 vty_out(vty
, "%-15s ",
539 json_object_get_string(
543 vty_out(vty
, "%-15s ", if_field_key
);
545 json_object_object_get_ex(
546 if_field_val
, "localMembership",
548 vty_out(vty
, "%-10s\n",
549 json_object_get_string(
556 json_object_free(json
);
559 static void pim_print_ifp_flags(struct vty
*vty
, struct interface
*ifp
,
562 vty_out(vty
, "Flags\n");
563 vty_out(vty
, "-----\n");
564 vty_out(vty
, "All Multicast : %s\n",
565 (ifp
->flags
& IFF_ALLMULTI
) ? "yes" : "no");
566 vty_out(vty
, "Broadcast : %s\n",
567 if_is_broadcast(ifp
) ? "yes" : "no");
568 vty_out(vty
, "Deleted : %s\n",
569 PIM_IF_IS_DELETED(ifp
) ? "yes" : "no");
570 vty_out(vty
, "Interface Index : %d\n", ifp
->ifindex
);
571 vty_out(vty
, "Multicast : %s\n",
572 if_is_multicast(ifp
) ? "yes" : "no");
573 vty_out(vty
, "Multicast Loop : %d\n", mloop
);
574 vty_out(vty
, "Promiscuous : %s\n",
575 (ifp
->flags
& IFF_PROMISC
) ? "yes" : "no");
580 static void igmp_show_interfaces(struct pim_instance
*pim
, struct vty
*vty
,
583 struct interface
*ifp
;
585 json_object
*json
= NULL
;
586 json_object
*json_row
= NULL
;
588 now
= pim_time_monotonic_sec();
591 json
= json_object_new_object();
594 "Interface State Address V Querier Query Timer Uptime\n");
596 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
597 struct pim_interface
*pim_ifp
;
598 struct listnode
*sock_node
;
599 struct igmp_sock
*igmp
;
606 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
609 char query_hhmmss
[10];
611 pim_time_uptime(uptime
, sizeof(uptime
),
612 now
- igmp
->sock_creation
);
613 pim_time_timer_to_hhmmss(query_hhmmss
,
614 sizeof(query_hhmmss
),
615 igmp
->t_igmp_query_timer
);
618 json_row
= json_object_new_object();
619 json_object_pim_ifp_add(json_row
, ifp
);
620 json_object_string_add(json_row
, "upTime",
622 json_object_int_add(json_row
, "version",
623 pim_ifp
->igmp_version
);
625 if (igmp
->t_igmp_query_timer
) {
626 json_object_boolean_true_add(json_row
,
628 json_object_string_add(json_row
,
633 json_object_object_add(json
, ifp
->name
,
638 "%-9s %5s %15s %d %7s %11s %8s\n",
640 if_is_up(ifp
) ? "up" : "down",
641 inet_ntoa(igmp
->ifaddr
),
642 pim_ifp
->igmp_version
,
643 igmp
->t_igmp_query_timer
? "local"
645 query_hhmmss
, uptime
);
651 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
652 json
, JSON_C_TO_STRING_PRETTY
));
653 json_object_free(json
);
657 static void igmp_show_interfaces_single(struct pim_instance
*pim
,
658 struct vty
*vty
, const char *ifname
,
661 struct igmp_sock
*igmp
;
662 struct interface
*ifp
;
663 struct listnode
*sock_node
;
664 struct pim_interface
*pim_ifp
;
666 char query_hhmmss
[10];
667 char other_hhmmss
[10];
668 int found_ifname
= 0;
671 long gmi_msec
; /* Group Membership Interval */
674 long oqpi_msec
; /* Other Querier Present Interval */
678 json_object
*json
= NULL
;
679 json_object
*json_row
= NULL
;
682 json
= json_object_new_object();
684 now
= pim_time_monotonic_sec();
686 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
692 if (strcmp(ifname
, "detail") && strcmp(ifname
, ifp
->name
))
695 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
698 pim_time_uptime(uptime
, sizeof(uptime
),
699 now
- igmp
->sock_creation
);
700 pim_time_timer_to_hhmmss(query_hhmmss
,
701 sizeof(query_hhmmss
),
702 igmp
->t_igmp_query_timer
);
703 pim_time_timer_to_hhmmss(other_hhmmss
,
704 sizeof(other_hhmmss
),
705 igmp
->t_other_querier_timer
);
707 gmi_msec
= PIM_IGMP_GMI_MSEC(
708 igmp
->querier_robustness_variable
,
709 igmp
->querier_query_interval
,
710 pim_ifp
->igmp_query_max_response_time_dsec
);
713 pim_ifp
->igmp_default_query_interval
);
715 oqpi_msec
= PIM_IGMP_OQPI_MSEC(
716 igmp
->querier_robustness_variable
,
717 igmp
->querier_query_interval
,
718 pim_ifp
->igmp_query_max_response_time_dsec
);
720 lmqt_msec
= PIM_IGMP_LMQT_MSEC(
721 pim_ifp
->igmp_query_max_response_time_dsec
,
722 igmp
->querier_robustness_variable
);
726 igmp
->querier_robustness_variable
,
727 igmp
->querier_query_interval
,
728 pim_ifp
->igmp_query_max_response_time_dsec
)
731 qri_msec
= pim_ifp
->igmp_query_max_response_time_dsec
733 if (pim_ifp
->pim_sock_fd
>= 0)
734 mloop
= pim_socket_mcastloop_get(
735 pim_ifp
->pim_sock_fd
);
740 json_row
= json_object_new_object();
741 json_object_pim_ifp_add(json_row
, ifp
);
742 json_object_string_add(json_row
, "upTime",
744 json_object_string_add(json_row
, "querier",
745 igmp
->t_igmp_query_timer
748 json_object_int_add(json_row
, "queryStartCount",
749 igmp
->startup_query_count
);
750 json_object_string_add(json_row
,
753 json_object_string_add(json_row
,
756 json_object_int_add(json_row
, "version",
757 pim_ifp
->igmp_version
);
760 "timerGroupMembershipIntervalMsec",
762 json_object_int_add(json_row
,
763 "timerLastMemberQueryMsec",
767 "timerOlderHostPresentIntervalMsec",
771 "timerOtherQuerierPresentIntervalMsec",
774 json_row
, "timerQueryInterval",
775 igmp
->querier_query_interval
);
778 "timerQueryResponseIntervalMsec",
781 json_row
, "timerRobustnessVariable",
782 igmp
->querier_robustness_variable
);
783 json_object_int_add(json_row
,
784 "timerStartupQueryInterval",
787 json_object_object_add(json
, ifp
->name
,
791 vty_out(vty
, "Interface : %s\n", ifp
->name
);
792 vty_out(vty
, "State : %s\n",
793 if_is_up(ifp
) ? "up" : "down");
794 vty_out(vty
, "Address : %s\n",
795 inet_ntoa(pim_ifp
->primary_address
));
796 vty_out(vty
, "Uptime : %s\n", uptime
);
797 vty_out(vty
, "Version : %d\n",
798 pim_ifp
->igmp_version
);
802 vty_out(vty
, "Querier\n");
803 vty_out(vty
, "-------\n");
804 vty_out(vty
, "Querier : %s\n",
805 igmp
->t_igmp_query_timer
? "local"
807 vty_out(vty
, "Start Count : %d\n",
808 igmp
->startup_query_count
);
809 vty_out(vty
, "Query Timer : %s\n",
811 vty_out(vty
, "Other Timer : %s\n",
816 vty_out(vty
, "Timers\n");
817 vty_out(vty
, "------\n");
819 "Group Membership Interval : %lis\n",
822 "Last Member Query Time : %lis\n",
825 "Older Host Present Interval : %lis\n",
828 "Other Querier Present Interval : %lis\n",
831 "Query Interval : %ds\n",
832 igmp
->querier_query_interval
);
834 "Query Response Interval : %lis\n",
837 "Robustness Variable : %d\n",
838 igmp
->querier_robustness_variable
);
840 "Startup Query Interval : %ds\n",
845 pim_print_ifp_flags(vty
, ifp
, mloop
);
851 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
852 json
, JSON_C_TO_STRING_PRETTY
));
853 json_object_free(json
);
856 vty_out(vty
, "%% No such interface\n");
860 static void igmp_show_interface_join(struct pim_instance
*pim
, struct vty
*vty
)
862 struct interface
*ifp
;
865 now
= pim_time_monotonic_sec();
868 "Interface Address Source Group Socket Uptime \n");
870 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
871 struct pim_interface
*pim_ifp
;
872 struct listnode
*join_node
;
873 struct igmp_join
*ij
;
874 struct in_addr pri_addr
;
875 char pri_addr_str
[INET_ADDRSTRLEN
];
882 if (!pim_ifp
->igmp_join_list
)
885 pri_addr
= pim_find_primary_addr(ifp
);
886 pim_inet4_dump("<pri?>", pri_addr
, pri_addr_str
,
887 sizeof(pri_addr_str
));
889 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_join_list
, join_node
,
891 char group_str
[INET_ADDRSTRLEN
];
892 char source_str
[INET_ADDRSTRLEN
];
895 pim_time_uptime(uptime
, sizeof(uptime
),
896 now
- ij
->sock_creation
);
897 pim_inet4_dump("<grp?>", ij
->group_addr
, group_str
,
899 pim_inet4_dump("<src?>", ij
->source_addr
, source_str
,
902 vty_out(vty
, "%-9s %-15s %-15s %-15s %6d %8s\n",
903 ifp
->name
, pri_addr_str
, source_str
, group_str
,
904 ij
->sock_fd
, uptime
);
905 } /* for (pim_ifp->igmp_join_list) */
910 static void pim_show_interfaces_single(struct pim_instance
*pim
,
911 struct vty
*vty
, const char *ifname
,
914 struct in_addr ifaddr
;
915 struct interface
*ifp
;
916 struct listnode
*neighnode
;
917 struct listnode
*upnode
;
918 struct pim_interface
*pim_ifp
;
919 struct pim_neighbor
*neigh
;
920 struct pim_upstream
*up
;
922 char dr_str
[INET_ADDRSTRLEN
];
925 char grp_str
[INET_ADDRSTRLEN
];
926 char hello_period
[10];
927 char hello_timer
[10];
928 char neigh_src_str
[INET_ADDRSTRLEN
];
929 char src_str
[INET_ADDRSTRLEN
];
930 char stat_uptime
[10];
933 int found_ifname
= 0;
935 json_object
*json
= NULL
;
936 json_object
*json_row
= NULL
;
937 json_object
*json_pim_neighbor
= NULL
;
938 json_object
*json_pim_neighbors
= NULL
;
939 json_object
*json_group
= NULL
;
940 json_object
*json_group_source
= NULL
;
941 json_object
*json_fhr_sources
= NULL
;
942 struct pim_secondary_addr
*sec_addr
;
943 struct listnode
*sec_node
;
945 now
= pim_time_monotonic_sec();
948 json
= json_object_new_object();
950 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
956 if (strcmp(ifname
, "detail") && strcmp(ifname
, ifp
->name
))
960 ifaddr
= pim_ifp
->primary_address
;
961 pim_inet4_dump("<dr?>", pim_ifp
->pim_dr_addr
, dr_str
,
963 pim_time_uptime_begin(dr_uptime
, sizeof(dr_uptime
), now
,
964 pim_ifp
->pim_dr_election_last
);
965 pim_time_timer_to_hhmmss(hello_timer
, sizeof(hello_timer
),
966 pim_ifp
->t_pim_hello_timer
);
967 pim_time_mmss(hello_period
, sizeof(hello_period
),
968 pim_ifp
->pim_hello_period
);
969 pim_time_uptime(stat_uptime
, sizeof(stat_uptime
),
970 now
- pim_ifp
->pim_ifstat_start
);
971 if (pim_ifp
->pim_sock_fd
>= 0)
972 mloop
= pim_socket_mcastloop_get(pim_ifp
->pim_sock_fd
);
977 char pbuf
[PREFIX2STR_BUFFER
];
978 json_row
= json_object_new_object();
979 json_object_pim_ifp_add(json_row
, ifp
);
981 if (pim_ifp
->update_source
.s_addr
!= INADDR_ANY
) {
982 json_object_string_add(
983 json_row
, "useSource",
984 inet_ntoa(pim_ifp
->update_source
));
986 if (pim_ifp
->sec_addr_list
) {
987 json_object
*sec_list
= NULL
;
989 sec_list
= json_object_new_array();
990 for (ALL_LIST_ELEMENTS_RO(
991 pim_ifp
->sec_addr_list
, sec_node
,
993 json_object_array_add(
995 json_object_new_string(
1001 json_object_object_add(json_row
,
1002 "secondaryAddressList",
1007 if (pim_ifp
->pim_neighbor_list
->count
) {
1008 json_pim_neighbors
= json_object_new_object();
1010 for (ALL_LIST_ELEMENTS_RO(
1011 pim_ifp
->pim_neighbor_list
,
1012 neighnode
, neigh
)) {
1014 json_object_new_object();
1015 pim_inet4_dump("<src?>",
1018 sizeof(neigh_src_str
));
1019 pim_time_uptime(uptime
, sizeof(uptime
),
1020 now
- neigh
->creation
);
1021 pim_time_timer_to_hhmmss(
1022 expire
, sizeof(expire
),
1023 neigh
->t_expire_timer
);
1025 json_object_string_add(
1026 json_pim_neighbor
, "address",
1028 json_object_string_add(
1029 json_pim_neighbor
, "upTime",
1031 json_object_string_add(
1032 json_pim_neighbor
, "holdtime",
1035 json_object_object_add(
1041 json_object_object_add(json_row
, "neighbors",
1042 json_pim_neighbors
);
1045 json_object_string_add(json_row
, "drAddress", dr_str
);
1046 json_object_int_add(json_row
, "drPriority",
1047 pim_ifp
->pim_dr_priority
);
1048 json_object_string_add(json_row
, "drUptime", dr_uptime
);
1049 json_object_int_add(json_row
, "drElections",
1050 pim_ifp
->pim_dr_election_count
);
1051 json_object_int_add(json_row
, "drChanges",
1052 pim_ifp
->pim_dr_election_changes
);
1055 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
,
1057 if (ifp
!= up
->rpf
.source_nexthop
.interface
)
1060 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
))
1063 if (!json_fhr_sources
)
1065 json_object_new_object();
1067 pim_inet4_dump("<src?>", up
->sg
.src
,
1068 src_str
, sizeof(src_str
));
1069 pim_inet4_dump("<grp?>", up
->sg
.grp
,
1070 grp_str
, sizeof(grp_str
));
1071 pim_time_uptime(uptime
, sizeof(uptime
),
1072 now
- up
->state_transition
);
1075 * Does this group live in json_fhr_sources?
1078 json_object_object_get_ex(json_fhr_sources
,
1083 json_group
= json_object_new_object();
1084 json_object_object_add(
1090 json_group_source
= json_object_new_object();
1091 json_object_string_add(json_group_source
,
1093 json_object_string_add(json_group_source
,
1095 json_object_string_add(json_group_source
,
1097 json_object_object_add(json_group
, src_str
,
1101 if (json_fhr_sources
) {
1102 json_object_object_add(json_row
,
1107 json_object_int_add(json_row
, "helloPeriod",
1108 pim_ifp
->pim_hello_period
);
1109 json_object_string_add(json_row
, "helloTimer",
1111 json_object_string_add(json_row
, "helloStatStart",
1113 json_object_int_add(json_row
, "helloReceived",
1114 pim_ifp
->pim_ifstat_hello_recv
);
1115 json_object_int_add(json_row
, "helloReceivedFailed",
1116 pim_ifp
->pim_ifstat_hello_recvfail
);
1117 json_object_int_add(json_row
, "helloSend",
1118 pim_ifp
->pim_ifstat_hello_sent
);
1119 json_object_int_add(json_row
, "hellosendFailed",
1120 pim_ifp
->pim_ifstat_hello_sendfail
);
1121 json_object_int_add(json_row
, "helloGenerationId",
1122 pim_ifp
->pim_generation_id
);
1123 json_object_int_add(json_row
, "flagMulticastLoop",
1126 json_object_int_add(
1127 json_row
, "effectivePropagationDelay",
1128 pim_if_effective_propagation_delay_msec(ifp
));
1129 json_object_int_add(
1130 json_row
, "effectiveOverrideInterval",
1131 pim_if_effective_override_interval_msec(ifp
));
1132 json_object_int_add(
1133 json_row
, "joinPruneOverrideInterval",
1134 pim_if_jp_override_interval_msec(ifp
));
1136 json_object_int_add(
1137 json_row
, "propagationDelay",
1138 pim_ifp
->pim_propagation_delay_msec
);
1139 json_object_int_add(
1140 json_row
, "propagationDelayHighest",
1141 pim_ifp
->pim_neighbors_highest_propagation_delay_msec
);
1142 json_object_int_add(
1143 json_row
, "overrideInterval",
1144 pim_ifp
->pim_override_interval_msec
);
1145 json_object_int_add(
1146 json_row
, "overrideIntervalHighest",
1147 pim_ifp
->pim_neighbors_highest_override_interval_msec
);
1148 json_object_object_add(json
, ifp
->name
, json_row
);
1151 vty_out(vty
, "Interface : %s\n", ifp
->name
);
1152 vty_out(vty
, "State : %s\n",
1153 if_is_up(ifp
) ? "up" : "down");
1154 if (pim_ifp
->update_source
.s_addr
!= INADDR_ANY
) {
1155 vty_out(vty
, "Use Source : %s\n",
1156 inet_ntoa(pim_ifp
->update_source
));
1158 if (pim_ifp
->sec_addr_list
) {
1159 char pbuf
[PREFIX2STR_BUFFER
];
1160 vty_out(vty
, "Address : %s (primary)\n",
1162 for (ALL_LIST_ELEMENTS_RO(
1163 pim_ifp
->sec_addr_list
, sec_node
,
1165 vty_out(vty
, " %s\n",
1166 prefix2str(&sec_addr
->addr
,
1167 pbuf
, sizeof(pbuf
)));
1170 vty_out(vty
, "Address : %s\n",
1178 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
,
1179 neighnode
, neigh
)) {
1182 vty_out(vty
, "PIM Neighbors\n");
1183 vty_out(vty
, "-------------\n");
1187 pim_inet4_dump("<src?>", neigh
->source_addr
,
1189 sizeof(neigh_src_str
));
1190 pim_time_uptime(uptime
, sizeof(uptime
),
1191 now
- neigh
->creation
);
1192 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
1193 neigh
->t_expire_timer
);
1195 "%-15s : up for %s, holdtime expires in %s\n",
1196 neigh_src_str
, uptime
, expire
);
1199 if (!print_header
) {
1204 vty_out(vty
, "Designated Router\n");
1205 vty_out(vty
, "-----------------\n");
1206 vty_out(vty
, "Address : %s\n", dr_str
);
1207 vty_out(vty
, "Priority : %d\n",
1208 pim_ifp
->pim_dr_priority
);
1209 vty_out(vty
, "Uptime : %s\n", dr_uptime
);
1210 vty_out(vty
, "Elections : %d\n",
1211 pim_ifp
->pim_dr_election_count
);
1212 vty_out(vty
, "Changes : %d\n",
1213 pim_ifp
->pim_dr_election_changes
);
1219 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
,
1222 if (strcmp(ifp
->name
,
1223 up
->rpf
.source_nexthop
.
1224 interface
->name
) != 0)
1227 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
))
1232 "FHR - First Hop Router\n");
1234 "----------------------\n");
1238 pim_inet4_dump("<src?>", up
->sg
.src
,
1239 src_str
, sizeof(src_str
));
1240 pim_inet4_dump("<grp?>", up
->sg
.grp
,
1241 grp_str
, sizeof(grp_str
));
1242 pim_time_uptime(uptime
, sizeof(uptime
),
1243 now
- up
->state_transition
);
1245 "%s : %s is a source, uptime is %s\n",
1250 if (!print_header
) {
1255 vty_out(vty
, "Hellos\n");
1256 vty_out(vty
, "------\n");
1257 vty_out(vty
, "Period : %d\n",
1258 pim_ifp
->pim_hello_period
);
1259 vty_out(vty
, "Timer : %s\n", hello_timer
);
1260 vty_out(vty
, "StatStart : %s\n", stat_uptime
);
1261 vty_out(vty
, "Receive : %d\n",
1262 pim_ifp
->pim_ifstat_hello_recv
);
1263 vty_out(vty
, "Receive Failed : %d\n",
1264 pim_ifp
->pim_ifstat_hello_recvfail
);
1265 vty_out(vty
, "Send : %d\n",
1266 pim_ifp
->pim_ifstat_hello_sent
);
1267 vty_out(vty
, "Send Failed : %d\n",
1268 pim_ifp
->pim_ifstat_hello_sendfail
);
1269 vty_out(vty
, "Generation ID : %08x\n",
1270 pim_ifp
->pim_generation_id
);
1274 pim_print_ifp_flags(vty
, ifp
, mloop
);
1276 vty_out(vty
, "Join Prune Interval\n");
1277 vty_out(vty
, "-------------------\n");
1278 vty_out(vty
, "LAN Delay : %s\n",
1279 pim_if_lan_delay_enabled(ifp
) ? "yes" : "no");
1280 vty_out(vty
, "Effective Propagation Delay : %d msec\n",
1281 pim_if_effective_propagation_delay_msec(ifp
));
1282 vty_out(vty
, "Effective Override Interval : %d msec\n",
1283 pim_if_effective_override_interval_msec(ifp
));
1284 vty_out(vty
, "Join Prune Override Interval : %d msec\n",
1285 pim_if_jp_override_interval_msec(ifp
));
1289 vty_out(vty
, "LAN Prune Delay\n");
1290 vty_out(vty
, "---------------\n");
1291 vty_out(vty
, "Propagation Delay : %d msec\n",
1292 pim_ifp
->pim_propagation_delay_msec
);
1293 vty_out(vty
, "Propagation Delay (Highest) : %d msec\n",
1294 pim_ifp
->pim_neighbors_highest_propagation_delay_msec
);
1295 vty_out(vty
, "Override Interval : %d msec\n",
1296 pim_ifp
->pim_override_interval_msec
);
1297 vty_out(vty
, "Override Interval (Highest) : %d msec\n",
1298 pim_ifp
->pim_neighbors_highest_override_interval_msec
);
1305 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1306 json
, JSON_C_TO_STRING_PRETTY
));
1307 json_object_free(json
);
1310 vty_out(vty
, "%% No such interface\n");
1314 static void pim_show_interfaces(struct pim_instance
*pim
, struct vty
*vty
,
1317 struct interface
*ifp
;
1318 struct listnode
*upnode
;
1319 struct pim_interface
*pim_ifp
;
1320 struct pim_upstream
*up
;
1323 int pim_ifchannels
= 0;
1324 json_object
*json
= NULL
;
1325 json_object
*json_row
= NULL
;
1326 json_object
*json_tmp
;
1328 json
= json_object_new_object();
1330 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1331 pim_ifp
= ifp
->info
;
1336 pim_nbrs
= pim_ifp
->pim_neighbor_list
->count
;
1337 pim_ifchannels
= pim_if_ifchannel_count(pim_ifp
);
1340 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
, up
))
1341 if (ifp
== up
->rpf
.source_nexthop
.interface
)
1342 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
1345 json_row
= json_object_new_object();
1346 json_object_pim_ifp_add(json_row
, ifp
);
1347 json_object_int_add(json_row
, "pimNeighbors", pim_nbrs
);
1348 json_object_int_add(json_row
, "pimIfChannels", pim_ifchannels
);
1349 json_object_int_add(json_row
, "firstHopRouterCount", fhr
);
1350 json_object_string_add(json_row
, "pimDesignatedRouter",
1351 inet_ntoa(pim_ifp
->pim_dr_addr
));
1353 if (pim_ifp
->pim_dr_addr
.s_addr
1354 == pim_ifp
->primary_address
.s_addr
)
1355 json_object_boolean_true_add(
1356 json_row
, "pimDesignatedRouterLocal");
1358 json_object_object_add(json
, ifp
->name
, json_row
);
1362 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1363 json
, JSON_C_TO_STRING_PRETTY
));
1366 "Interface State Address PIM Nbrs PIM DR FHR IfChannels\n");
1368 json_object_object_foreach(json
, key
, val
)
1370 vty_out(vty
, "%-9s ", key
);
1372 json_object_object_get_ex(val
, "state", &json_tmp
);
1373 vty_out(vty
, "%5s ", json_object_get_string(json_tmp
));
1375 json_object_object_get_ex(val
, "address", &json_tmp
);
1376 vty_out(vty
, "%15s ",
1377 json_object_get_string(json_tmp
));
1379 json_object_object_get_ex(val
, "pimNeighbors",
1381 vty_out(vty
, "%8d ", json_object_get_int(json_tmp
));
1383 if (json_object_object_get_ex(
1384 val
, "pimDesignatedRouterLocal",
1386 vty_out(vty
, "%15s ", "local");
1388 json_object_object_get_ex(
1389 val
, "pimDesignatedRouter", &json_tmp
);
1390 vty_out(vty
, "%15s ",
1391 json_object_get_string(json_tmp
));
1394 json_object_object_get_ex(val
, "firstHopRouter",
1396 vty_out(vty
, "%3d ", json_object_get_int(json_tmp
));
1398 json_object_object_get_ex(val
, "pimIfChannels",
1400 vty_out(vty
, "%9d\n", json_object_get_int(json_tmp
));
1404 json_object_free(json
);
1407 static void pim_show_interface_traffic(struct pim_instance
*pim
,
1408 struct vty
*vty
, u_char uj
)
1410 struct interface
*ifp
= NULL
;
1411 struct pim_interface
*pim_ifp
= NULL
;
1412 json_object
*json
= NULL
;
1413 json_object
*json_row
= NULL
;
1416 json
= json_object_new_object();
1419 vty_out(vty
, "%-12s%-17s%-17s%-17s%-17s%-17s%-17s\n",
1420 "Interface", " HELLO", " JOIN", " PRUNE",
1421 " REGISTER", " REGISTER-STOP", " ASSERT");
1422 vty_out(vty
, "%-10s%-18s%-17s%-17s%-17s%-17s%-17s\n", "",
1423 " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1424 " Rx/Tx", " Rx/Tx");
1426 "---------------------------------------------------------------------------------------------------------------\n");
1429 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1430 pim_ifp
= ifp
->info
;
1435 if (pim_ifp
->pim_sock_fd
< 0)
1438 json_row
= json_object_new_object();
1439 json_object_pim_ifp_add(json_row
, ifp
);
1440 json_object_int_add(json_row
, "helloRx",
1441 pim_ifp
->pim_ifstat_hello_recv
);
1442 json_object_int_add(json_row
, "helloTx",
1443 pim_ifp
->pim_ifstat_hello_sent
);
1444 json_object_int_add(json_row
, "joinRx",
1445 pim_ifp
->pim_ifstat_join_recv
);
1446 json_object_int_add(json_row
, "joinTx",
1447 pim_ifp
->pim_ifstat_join_send
);
1448 json_object_int_add(json_row
, "registerRx",
1449 pim_ifp
->pim_ifstat_reg_recv
);
1450 json_object_int_add(json_row
, "registerTx",
1451 pim_ifp
->pim_ifstat_reg_recv
);
1452 json_object_int_add(json_row
, "registerStopRx",
1453 pim_ifp
->pim_ifstat_reg_stop_recv
);
1454 json_object_int_add(json_row
, "registerStopTx",
1455 pim_ifp
->pim_ifstat_reg_stop_send
);
1456 json_object_int_add(json_row
, "assertRx",
1457 pim_ifp
->pim_ifstat_assert_recv
);
1458 json_object_int_add(json_row
, "assertTx",
1459 pim_ifp
->pim_ifstat_assert_send
);
1461 json_object_object_add(json
, ifp
->name
, json_row
);
1464 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u \n",
1465 ifp
->name
, pim_ifp
->pim_ifstat_hello_recv
,
1466 pim_ifp
->pim_ifstat_hello_sent
,
1467 pim_ifp
->pim_ifstat_join_recv
,
1468 pim_ifp
->pim_ifstat_join_send
,
1469 pim_ifp
->pim_ifstat_prune_recv
,
1470 pim_ifp
->pim_ifstat_prune_send
,
1471 pim_ifp
->pim_ifstat_reg_recv
,
1472 pim_ifp
->pim_ifstat_reg_send
,
1473 pim_ifp
->pim_ifstat_reg_stop_recv
,
1474 pim_ifp
->pim_ifstat_reg_stop_send
,
1475 pim_ifp
->pim_ifstat_assert_recv
,
1476 pim_ifp
->pim_ifstat_assert_send
);
1480 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1481 json
, JSON_C_TO_STRING_PRETTY
));
1482 json_object_free(json
);
1486 static void pim_show_interface_traffic_single(struct pim_instance
*pim
,
1488 const char *ifname
, u_char uj
)
1490 struct interface
*ifp
= NULL
;
1491 struct pim_interface
*pim_ifp
= NULL
;
1492 json_object
*json
= NULL
;
1493 json_object
*json_row
= NULL
;
1494 uint8_t found_ifname
= 0;
1497 json
= json_object_new_object();
1500 vty_out(vty
, "%-12s%-17s%-17s%-17s%-17s%-17s%-17s\n",
1501 "Interface", " HELLO", " JOIN", " PRUNE",
1502 " REGISTER", " REGISTER-STOP", " ASSERT");
1503 vty_out(vty
, "%-10s%-18s%-17s%-17s%-17s%-17s%-17s\n", "",
1504 " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1505 " Rx/Tx", " Rx/Tx");
1507 "---------------------------------------------------------------------------------------------------------------\n");
1510 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1511 if (strcmp(ifname
, ifp
->name
))
1514 pim_ifp
= ifp
->info
;
1519 if (pim_ifp
->pim_sock_fd
< 0)
1524 json_row
= json_object_new_object();
1525 json_object_pim_ifp_add(json_row
, ifp
);
1526 json_object_int_add(json_row
, "helloRx",
1527 pim_ifp
->pim_ifstat_hello_recv
);
1528 json_object_int_add(json_row
, "helloTx",
1529 pim_ifp
->pim_ifstat_hello_sent
);
1530 json_object_int_add(json_row
, "joinRx",
1531 pim_ifp
->pim_ifstat_join_recv
);
1532 json_object_int_add(json_row
, "joinTx",
1533 pim_ifp
->pim_ifstat_join_send
);
1534 json_object_int_add(json_row
, "registerRx",
1535 pim_ifp
->pim_ifstat_reg_recv
);
1536 json_object_int_add(json_row
, "registerTx",
1537 pim_ifp
->pim_ifstat_reg_recv
);
1538 json_object_int_add(json_row
, "registerStopRx",
1539 pim_ifp
->pim_ifstat_reg_stop_recv
);
1540 json_object_int_add(json_row
, "registerStopTx",
1541 pim_ifp
->pim_ifstat_reg_stop_send
);
1542 json_object_int_add(json_row
, "assertRx",
1543 pim_ifp
->pim_ifstat_assert_recv
);
1544 json_object_int_add(json_row
, "assertTx",
1545 pim_ifp
->pim_ifstat_assert_send
);
1547 json_object_object_add(json
, ifp
->name
, json_row
);
1550 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u \n",
1551 ifp
->name
, pim_ifp
->pim_ifstat_hello_recv
,
1552 pim_ifp
->pim_ifstat_hello_sent
,
1553 pim_ifp
->pim_ifstat_join_recv
,
1554 pim_ifp
->pim_ifstat_join_send
,
1555 pim_ifp
->pim_ifstat_prune_recv
,
1556 pim_ifp
->pim_ifstat_prune_send
,
1557 pim_ifp
->pim_ifstat_reg_recv
,
1558 pim_ifp
->pim_ifstat_reg_send
,
1559 pim_ifp
->pim_ifstat_reg_stop_recv
,
1560 pim_ifp
->pim_ifstat_reg_stop_send
,
1561 pim_ifp
->pim_ifstat_assert_recv
,
1562 pim_ifp
->pim_ifstat_assert_send
);
1566 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1567 json
, JSON_C_TO_STRING_PRETTY
));
1568 json_object_free(json
);
1571 vty_out(vty
, "%% No such interface\n");
1575 static void pim_show_join_helper(struct vty
*vty
,
1576 struct pim_interface
*pim_ifp
,
1577 struct pim_ifchannel
*ch
,
1582 char ch_src_str
[INET_ADDRSTRLEN
];
1583 char ch_grp_str
[INET_ADDRSTRLEN
];
1584 json_object
*json_iface
= NULL
;
1585 json_object
*json_row
= NULL
;
1586 json_object
*json_grp
= NULL
;
1587 struct in_addr ifaddr
;
1592 ifaddr
= pim_ifp
->primary_address
;
1594 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
,
1595 sizeof(ch_src_str
));
1596 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
,
1597 sizeof(ch_grp_str
));
1599 pim_time_uptime_begin(uptime
, sizeof(uptime
), now
,
1600 ch
->ifjoin_creation
);
1601 pim_time_timer_to_mmss(expire
, sizeof(expire
),
1602 ch
->t_ifjoin_expiry_timer
);
1603 pim_time_timer_to_mmss(prune
, sizeof(prune
),
1604 ch
->t_ifjoin_prune_pending_timer
);
1607 json_object_object_get_ex(json
, ch
->interface
->name
,
1611 json_iface
= json_object_new_object();
1612 json_object_pim_ifp_add(json_iface
,
1614 json_object_object_add(
1615 json
, ch
->interface
->name
, json_iface
);
1618 json_row
= json_object_new_object();
1619 json_object_string_add(json_row
, "source", ch_src_str
);
1620 json_object_string_add(json_row
, "group", ch_grp_str
);
1621 json_object_string_add(json_row
, "upTime", uptime
);
1622 json_object_string_add(json_row
, "expire", expire
);
1623 json_object_string_add(json_row
, "prune", prune
);
1624 json_object_string_add(
1625 json_row
, "channelJoinName",
1626 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
,
1628 if (PIM_IF_FLAG_TEST_S_G_RPT(ch
->flags
))
1629 json_object_int_add(json_row
, "SGRpt", 1);
1631 json_object_object_get_ex(json_iface
, ch_grp_str
,
1634 json_grp
= json_object_new_object();
1635 json_object_object_add(json_grp
, ch_src_str
,
1637 json_object_object_add(json_iface
, ch_grp_str
,
1640 json_object_object_add(json_grp
, ch_src_str
,
1644 "%-9s %-15s %-15s %-15s %-10s %8s %-6s %5s\n",
1645 ch
->interface
->name
, inet_ntoa(ifaddr
),
1646 ch_src_str
, ch_grp_str
,
1647 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
,
1649 uptime
, expire
, prune
);
1653 static void pim_show_join(struct pim_instance
*pim
, struct vty
*vty
, u_char uj
)
1655 struct pim_interface
*pim_ifp
;
1656 struct pim_ifchannel
*ch
;
1657 struct interface
*ifp
;
1659 json_object
*json
= NULL
;
1661 now
= pim_time_monotonic_sec();
1664 json
= json_object_new_object();
1667 "Interface Address Source Group State Uptime Expire Prune\n");
1669 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1670 pim_ifp
= ifp
->info
;
1674 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
1675 pim_show_join_helper(vty
, pim_ifp
, ch
, json
, now
, uj
);
1676 } /* scan interface channels */
1680 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1681 json
, JSON_C_TO_STRING_PRETTY
));
1682 json_object_free(json
);
1686 static void pim_show_neighbors_single(struct pim_instance
*pim
, struct vty
*vty
,
1687 const char *neighbor
, u_char uj
)
1689 struct listnode
*neighnode
;
1690 struct interface
*ifp
;
1691 struct pim_interface
*pim_ifp
;
1692 struct pim_neighbor
*neigh
;
1694 int found_neighbor
= 0;
1695 int option_address_list
;
1696 int option_dr_priority
;
1697 int option_generation_id
;
1698 int option_holdtime
;
1699 int option_lan_prune_delay
;
1703 char neigh_src_str
[INET_ADDRSTRLEN
];
1705 json_object
*json
= NULL
;
1706 json_object
*json_ifp
= NULL
;
1707 json_object
*json_row
= NULL
;
1709 now
= pim_time_monotonic_sec();
1712 json
= json_object_new_object();
1714 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1715 pim_ifp
= ifp
->info
;
1720 if (pim_ifp
->pim_sock_fd
< 0)
1723 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
1725 pim_inet4_dump("<src?>", neigh
->source_addr
,
1726 neigh_src_str
, sizeof(neigh_src_str
));
1729 * The user can specify either the interface name or the
1731 * If this pim_ifp matches neither then skip.
1733 if (strcmp(neighbor
, "detail")
1734 && strcmp(neighbor
, ifp
->name
)
1735 && strcmp(neighbor
, neigh_src_str
))
1739 pim_time_uptime(uptime
, sizeof(uptime
),
1740 now
- neigh
->creation
);
1741 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
1742 neigh
->t_expire_timer
);
1744 option_address_list
= 0;
1745 option_dr_priority
= 0;
1746 option_generation_id
= 0;
1747 option_holdtime
= 0;
1748 option_lan_prune_delay
= 0;
1751 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1752 PIM_OPTION_MASK_ADDRESS_LIST
))
1753 option_address_list
= 1;
1755 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1756 PIM_OPTION_MASK_DR_PRIORITY
))
1757 option_dr_priority
= 1;
1759 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1760 PIM_OPTION_MASK_GENERATION_ID
))
1761 option_generation_id
= 1;
1763 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1764 PIM_OPTION_MASK_HOLDTIME
))
1765 option_holdtime
= 1;
1767 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1768 PIM_OPTION_MASK_LAN_PRUNE_DELAY
))
1769 option_lan_prune_delay
= 1;
1771 if (PIM_OPTION_IS_SET(
1772 neigh
->hello_options
,
1773 PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION
))
1778 /* Does this ifp live in json? If not create
1780 json_object_object_get_ex(json
, ifp
->name
,
1784 json_ifp
= json_object_new_object();
1785 json_object_pim_ifp_add(json_ifp
, ifp
);
1786 json_object_object_add(json
, ifp
->name
,
1790 json_row
= json_object_new_object();
1791 json_object_string_add(json_row
, "interface",
1793 json_object_string_add(json_row
, "address",
1795 json_object_string_add(json_row
, "upTime",
1797 json_object_string_add(json_row
, "holdtime",
1799 json_object_int_add(json_row
, "drPriority",
1800 neigh
->dr_priority
);
1801 json_object_int_add(json_row
, "generationId",
1802 neigh
->generation_id
);
1804 if (option_address_list
)
1805 json_object_boolean_true_add(
1807 "helloOptionAddressList");
1809 if (option_dr_priority
)
1810 json_object_boolean_true_add(
1812 "helloOptionDrPriority");
1814 if (option_generation_id
)
1815 json_object_boolean_true_add(
1817 "helloOptionGenerationId");
1819 if (option_holdtime
)
1820 json_object_boolean_true_add(
1822 "helloOptionHoldtime");
1824 if (option_lan_prune_delay
)
1825 json_object_boolean_true_add(
1827 "helloOptionLanPruneDelay");
1830 json_object_boolean_true_add(
1831 json_row
, "helloOptionTBit");
1833 json_object_object_add(json_ifp
, neigh_src_str
,
1837 vty_out(vty
, "Interface : %s\n", ifp
->name
);
1838 vty_out(vty
, "Neighbor : %s\n", neigh_src_str
);
1846 " DR Priority : %d\n",
1847 neigh
->dr_priority
);
1849 " Generation ID : %08x\n",
1850 neigh
->generation_id
);
1852 " Override Interval (msec) : %d\n",
1853 neigh
->override_interval_msec
);
1855 " Propagation Delay (msec) : %d\n",
1856 neigh
->propagation_delay_msec
);
1858 " Hello Option - Address List : %s\n",
1859 option_address_list
? "yes" : "no");
1861 " Hello Option - DR Priority : %s\n",
1862 option_dr_priority
? "yes" : "no");
1864 " Hello Option - Generation ID : %s\n",
1865 option_generation_id
? "yes" : "no");
1867 " Hello Option - Holdtime : %s\n",
1868 option_holdtime
? "yes" : "no");
1870 " Hello Option - LAN Prune Delay : %s\n",
1871 option_lan_prune_delay
? "yes" : "no");
1873 " Hello Option - T-bit : %s\n",
1874 option_t_bit
? "yes" : "no");
1875 pim_bfd_show_info(vty
, neigh
->bfd_info
,
1883 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1884 json
, JSON_C_TO_STRING_PRETTY
));
1885 json_object_free(json
);
1888 if (!found_neighbor
)
1890 "%% No such interface or neighbor\n");
1895 static void pim_show_state(struct pim_instance
*pim
, struct vty
*vty
,
1896 const char *src_or_group
, const char *group
,
1899 struct channel_oil
*c_oil
;
1900 struct listnode
*node
;
1901 json_object
*json
= NULL
;
1902 json_object
*json_group
= NULL
;
1903 json_object
*json_ifp_in
= NULL
;
1904 json_object
*json_ifp_out
= NULL
;
1905 json_object
*json_source
= NULL
;
1908 now
= pim_time_monotonic_sec();
1911 json
= json_object_new_object();
1914 "Codes: J -> Pim Join, I -> IGMP Report, S -> Source, * -> Inherited from (*,G)");
1916 "\nInstalled Source Group IIF OIL\n");
1919 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
1920 char grp_str
[INET_ADDRSTRLEN
];
1921 char src_str
[INET_ADDRSTRLEN
];
1922 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
1923 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
1925 struct interface
*ifp_in
;
1928 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
1930 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
1932 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
1935 strcpy(in_ifname
, ifp_in
->name
);
1937 strcpy(in_ifname
, "<iif?>");
1940 if (strcmp(src_or_group
, src_str
)
1941 && strcmp(src_or_group
, grp_str
))
1944 if (group
&& strcmp(group
, grp_str
))
1950 /* Find the group, create it if it doesn't exist */
1951 json_object_object_get_ex(json
, grp_str
, &json_group
);
1954 json_group
= json_object_new_object();
1955 json_object_object_add(json
, grp_str
,
1959 /* Find the source nested under the group, create it if
1960 * it doesn't exist */
1961 json_object_object_get_ex(json_group
, src_str
,
1965 json_source
= json_object_new_object();
1966 json_object_object_add(json_group
, src_str
,
1970 /* Find the inbound interface nested under the source,
1971 * create it if it doesn't exist */
1972 json_object_object_get_ex(json_source
, in_ifname
,
1976 json_ifp_in
= json_object_new_object();
1977 json_object_object_add(json_source
, in_ifname
,
1979 json_object_int_add(json_source
, "Installed",
1981 json_object_int_add(json_source
, "RefCount",
1982 c_oil
->oil_ref_count
);
1983 json_object_int_add(json_source
, "OilListSize",
1985 json_object_int_add(
1986 json_source
, "OilRescan",
1987 c_oil
->oil_inherited_rescan
);
1988 json_object_int_add(json_source
, "LastUsed",
1989 c_oil
->cc
.lastused
);
1990 json_object_int_add(json_source
, "PacketCount",
1992 json_object_int_add(json_source
, "ByteCount",
1994 json_object_int_add(json_source
,
1996 c_oil
->cc
.wrong_if
);
1999 vty_out(vty
, "%-9d %-15s %-15s %-7s ",
2000 c_oil
->installed
, src_str
, grp_str
,
2004 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
2006 struct interface
*ifp_out
;
2007 char oif_uptime
[10];
2010 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
2014 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
2016 oif_uptime
, sizeof(oif_uptime
),
2017 now
- c_oil
->oif_creation
[oif_vif_index
]);
2020 strcpy(out_ifname
, ifp_out
->name
);
2022 strcpy(out_ifname
, "<oif?>");
2025 json_ifp_out
= json_object_new_object();
2026 json_object_string_add(json_ifp_out
, "source",
2028 json_object_string_add(json_ifp_out
, "group",
2030 json_object_string_add(json_ifp_out
,
2033 json_object_string_add(json_ifp_out
,
2034 "outboundInterface",
2036 json_object_int_add(json_ifp_out
, "installed",
2039 json_object_object_add(json_ifp_in
, out_ifname
,
2044 vty_out(vty
, "%s(%c%c%c%c)", out_ifname
,
2045 (c_oil
->oif_flags
[oif_vif_index
]
2046 & PIM_OIF_FLAG_PROTO_IGMP
)
2049 (c_oil
->oif_flags
[oif_vif_index
]
2050 & PIM_OIF_FLAG_PROTO_PIM
)
2053 (c_oil
->oif_flags
[oif_vif_index
]
2054 & PIM_OIF_FLAG_PROTO_SOURCE
)
2057 (c_oil
->oif_flags
[oif_vif_index
]
2058 & PIM_OIF_FLAG_PROTO_STAR
)
2062 vty_out(vty
, ", %s(%c%c%c%c)",
2064 (c_oil
->oif_flags
[oif_vif_index
]
2065 & PIM_OIF_FLAG_PROTO_IGMP
)
2068 (c_oil
->oif_flags
[oif_vif_index
]
2069 & PIM_OIF_FLAG_PROTO_PIM
)
2072 (c_oil
->oif_flags
[oif_vif_index
]
2073 & PIM_OIF_FLAG_PROTO_SOURCE
)
2076 (c_oil
->oif_flags
[oif_vif_index
]
2077 & PIM_OIF_FLAG_PROTO_STAR
)
2089 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2090 json
, JSON_C_TO_STRING_PRETTY
));
2091 json_object_free(json
);
2097 static void pim_show_neighbors(struct pim_instance
*pim
, struct vty
*vty
,
2100 struct listnode
*neighnode
;
2101 struct interface
*ifp
;
2102 struct pim_interface
*pim_ifp
;
2103 struct pim_neighbor
*neigh
;
2107 char neigh_src_str
[INET_ADDRSTRLEN
];
2108 json_object
*json
= NULL
;
2109 json_object
*json_ifp_rows
= NULL
;
2110 json_object
*json_row
= NULL
;
2112 now
= pim_time_monotonic_sec();
2115 json
= json_object_new_object();
2118 "Interface Neighbor Uptime Holdtime DR Pri\n");
2121 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2122 pim_ifp
= ifp
->info
;
2127 if (pim_ifp
->pim_sock_fd
< 0)
2131 json_ifp_rows
= json_object_new_object();
2133 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
2135 pim_inet4_dump("<src?>", neigh
->source_addr
,
2136 neigh_src_str
, sizeof(neigh_src_str
));
2137 pim_time_uptime(uptime
, sizeof(uptime
),
2138 now
- neigh
->creation
);
2139 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
2140 neigh
->t_expire_timer
);
2143 json_row
= json_object_new_object();
2144 json_object_string_add(json_row
, "interface",
2146 json_object_string_add(json_row
, "neighbor",
2148 json_object_string_add(json_row
, "upTime",
2150 json_object_string_add(json_row
, "holdTime",
2152 json_object_int_add(json_row
, "holdTimeMax",
2154 json_object_int_add(json_row
, "drPriority",
2155 neigh
->dr_priority
);
2156 json_object_object_add(json_ifp_rows
,
2157 neigh_src_str
, json_row
);
2160 vty_out(vty
, "%-9s %15s %8s %8s %6d\n",
2161 ifp
->name
, neigh_src_str
, uptime
,
2162 expire
, neigh
->dr_priority
);
2167 json_object_object_add(json
, ifp
->name
, json_ifp_rows
);
2168 json_ifp_rows
= NULL
;
2173 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2174 json
, JSON_C_TO_STRING_PRETTY
));
2175 json_object_free(json
);
2179 static void pim_show_neighbors_secondary(struct pim_instance
*pim
,
2182 struct interface
*ifp
;
2185 "Interface Address Neighbor Secondary \n");
2187 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2188 struct pim_interface
*pim_ifp
;
2189 struct in_addr ifaddr
;
2190 struct listnode
*neighnode
;
2191 struct pim_neighbor
*neigh
;
2193 pim_ifp
= ifp
->info
;
2198 if (pim_ifp
->pim_sock_fd
< 0)
2201 ifaddr
= pim_ifp
->primary_address
;
2203 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
2205 char neigh_src_str
[INET_ADDRSTRLEN
];
2206 struct listnode
*prefix_node
;
2209 if (!neigh
->prefix_list
)
2212 pim_inet4_dump("<src?>", neigh
->source_addr
,
2213 neigh_src_str
, sizeof(neigh_src_str
));
2215 for (ALL_LIST_ELEMENTS_RO(neigh
->prefix_list
,
2217 char neigh_sec_str
[PREFIX2STR_BUFFER
];
2219 prefix2str(p
, neigh_sec_str
,
2220 sizeof(neigh_sec_str
));
2222 vty_out(vty
, "%-9s %-15s %-15s %-15s\n",
2223 ifp
->name
, inet_ntoa(ifaddr
),
2224 neigh_src_str
, neigh_sec_str
);
2230 static void json_object_pim_upstream_add(json_object
*json
,
2231 struct pim_upstream
*up
)
2233 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED
)
2234 json_object_boolean_true_add(json
, "drJoinDesired");
2236 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED
)
2237 json_object_boolean_true_add(json
, "drJoinDesiredUpdated");
2239 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
2240 json_object_boolean_true_add(json
, "firstHopRouter");
2242 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_IGMP
)
2243 json_object_boolean_true_add(json
, "sourceIgmp");
2245 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_PIM
)
2246 json_object_boolean_true_add(json
, "sourcePim");
2248 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_STREAM
)
2249 json_object_boolean_true_add(json
, "sourceStream");
2251 /* XXX: need to print ths flag in the plain text display as well */
2252 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_MSDP
)
2253 json_object_boolean_true_add(json
, "sourceMsdp");
2257 pim_upstream_state2brief_str(enum pim_upstream_state join_state
,
2260 switch (join_state
) {
2261 case PIM_UPSTREAM_NOTJOINED
:
2262 strcpy(state_str
, "NotJ");
2264 case PIM_UPSTREAM_JOINED
:
2265 strcpy(state_str
, "J");
2268 strcpy(state_str
, "Unk");
2273 static const char *pim_reg_state2brief_str(enum pim_reg_state reg_state
,
2276 switch (reg_state
) {
2277 case PIM_REG_NOINFO
:
2278 strcpy(state_str
, "RegNI");
2281 strcpy(state_str
, "RegJ");
2283 case PIM_REG_JOIN_PENDING
:
2285 strcpy(state_str
, "RegP");
2288 strcpy(state_str
, "Unk");
2293 static void pim_show_upstream(struct pim_instance
*pim
, struct vty
*vty
,
2296 struct listnode
*upnode
;
2297 struct pim_upstream
*up
;
2299 json_object
*json
= NULL
;
2300 json_object
*json_group
= NULL
;
2301 json_object
*json_row
= NULL
;
2303 now
= pim_time_monotonic_sec();
2306 json
= json_object_new_object();
2309 "Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt\n");
2311 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
, up
)) {
2312 char src_str
[INET_ADDRSTRLEN
];
2313 char grp_str
[INET_ADDRSTRLEN
];
2315 char join_timer
[10];
2318 char msdp_reg_timer
[10];
2319 char state_str
[PIM_REG_STATE_STR_LEN
];
2321 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2322 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2323 pim_time_uptime(uptime
, sizeof(uptime
),
2324 now
- up
->state_transition
);
2325 pim_time_timer_to_hhmmss(join_timer
, sizeof(join_timer
),
2329 * If we have a J/P timer for the neighbor display that
2331 if (!up
->t_join_timer
) {
2332 struct pim_neighbor
*nbr
;
2334 nbr
= pim_neighbor_find(
2335 up
->rpf
.source_nexthop
.interface
,
2336 up
->rpf
.rpf_addr
.u
.prefix4
);
2338 pim_time_timer_to_hhmmss(join_timer
,
2343 pim_time_timer_to_hhmmss(rs_timer
, sizeof(rs_timer
),
2345 pim_time_timer_to_hhmmss(ka_timer
, sizeof(ka_timer
),
2347 pim_time_timer_to_hhmmss(msdp_reg_timer
, sizeof(msdp_reg_timer
),
2348 up
->t_msdp_reg_timer
);
2350 pim_upstream_state2brief_str(up
->join_state
, state_str
);
2351 if (up
->reg_state
!= PIM_REG_NOINFO
) {
2352 char tmp_str
[PIM_REG_STATE_STR_LEN
];
2354 sprintf(state_str
+ strlen(state_str
), ",%s",
2355 pim_reg_state2brief_str(up
->reg_state
,
2360 json_object_object_get_ex(json
, grp_str
, &json_group
);
2363 json_group
= json_object_new_object();
2364 json_object_object_add(json
, grp_str
,
2368 json_row
= json_object_new_object();
2369 json_object_pim_upstream_add(json_row
, up
);
2370 json_object_string_add(
2371 json_row
, "inboundInterface",
2372 up
->rpf
.source_nexthop
.interface
->name
);
2375 * The RPF address we use is slightly different
2376 * based upon what we are looking up.
2377 * If we have a S, list that unless
2378 * we are the FHR, else we just put
2379 * the RP as the rpfAddress
2381 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
||
2382 up
->sg
.src
.s_addr
== INADDR_ANY
) {
2383 char rpf
[PREFIX_STRLEN
];
2384 struct pim_rpf
*rpg
;
2386 rpg
= RP(pim
, up
->sg
.grp
);
2387 pim_inet4_dump("<rpf?>",
2388 rpg
->rpf_addr
.u
.prefix4
,
2390 json_object_string_add(json_row
,
2393 json_object_string_add(json_row
,
2394 "rpfAddress", src_str
);
2397 json_object_string_add(json_row
, "source", src_str
);
2398 json_object_string_add(json_row
, "group", grp_str
);
2399 json_object_string_add(json_row
, "state", state_str
);
2400 json_object_string_add(
2401 json_row
, "joinState",
2402 pim_upstream_state2str(up
->join_state
));
2403 json_object_string_add(
2404 json_row
, "regState",
2405 pim_reg_state2str(up
->reg_state
, state_str
));
2406 json_object_string_add(json_row
, "upTime", uptime
);
2407 json_object_string_add(json_row
, "joinTimer",
2409 json_object_string_add(json_row
, "resetTimer",
2411 json_object_string_add(json_row
, "keepaliveTimer",
2413 json_object_string_add(json_row
, "msdpRegTimer",
2415 json_object_int_add(json_row
, "refCount",
2417 json_object_int_add(json_row
, "sptBit", up
->sptbit
);
2418 json_object_object_add(json_group
, src_str
, json_row
);
2421 "%-10s%-15s %-15s %-11s %-8s %-9s %-9s %-9s %6d\n",
2422 up
->rpf
.source_nexthop
.interface
->name
, src_str
,
2423 grp_str
, state_str
, uptime
, join_timer
,
2424 rs_timer
, ka_timer
, up
->ref_count
);
2429 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2430 json
, JSON_C_TO_STRING_PRETTY
));
2431 json_object_free(json
);
2435 static void pim_show_join_desired_helper(struct pim_instance
*pim
,
2437 struct pim_interface
*pim_ifp
,
2438 struct pim_ifchannel
*ch
,
2442 struct pim_upstream
*up
= ch
->upstream
;
2443 json_object
*json_group
= NULL
;
2444 char src_str
[INET_ADDRSTRLEN
];
2445 char grp_str
[INET_ADDRSTRLEN
];
2446 json_object
*json_row
= NULL
;
2448 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2449 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2452 json_object_object_get_ex(json
, grp_str
, &json_group
);
2455 json_group
= json_object_new_object();
2456 json_object_object_add(json
, grp_str
,
2460 json_row
= json_object_new_object();
2461 json_object_pim_upstream_add(json_row
, up
);
2462 json_object_string_add(json_row
, "interface",
2463 ch
->interface
->name
);
2464 json_object_string_add(json_row
, "source", src_str
);
2465 json_object_string_add(json_row
, "group", grp_str
);
2467 if (pim_macro_ch_lost_assert(ch
))
2468 json_object_boolean_true_add(json_row
,
2471 if (pim_macro_chisin_joins(ch
))
2472 json_object_boolean_true_add(json_row
, "joins");
2474 if (pim_macro_chisin_pim_include(ch
))
2475 json_object_boolean_true_add(json_row
,
2478 if (pim_upstream_evaluate_join_desired(pim
, up
))
2479 json_object_boolean_true_add(
2480 json_row
, "evaluateJoinDesired");
2482 json_object_object_add(json_group
, src_str
, json_row
);
2486 "%-9s %-15s %-15s %-10s %-5s %-10s %-11s %-6s\n",
2487 ch
->interface
->name
, src_str
, grp_str
,
2488 pim_macro_ch_lost_assert(ch
) ? "yes" : "no",
2489 pim_macro_chisin_joins(ch
) ? "yes" : "no",
2490 pim_macro_chisin_pim_include(ch
) ? "yes" : "no",
2491 PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(
2495 pim_upstream_evaluate_join_desired(pim
, up
)
2501 static void pim_show_join_desired(struct pim_instance
*pim
, struct vty
*vty
,
2504 struct pim_interface
*pim_ifp
;
2505 struct pim_ifchannel
*ch
;
2506 struct interface
*ifp
;
2508 json_object
*json
= NULL
;
2511 json
= json_object_new_object();
2514 "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD\n");
2516 /* scan per-interface (S,G) state */
2517 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2518 pim_ifp
= ifp
->info
;
2523 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
2524 /* scan all interfaces */
2525 pim_show_join_desired_helper(pim
, vty
,
2532 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2533 json
, JSON_C_TO_STRING_PRETTY
));
2534 json_object_free(json
);
2538 static void pim_show_upstream_rpf(struct pim_instance
*pim
, struct vty
*vty
,
2541 struct listnode
*upnode
;
2542 struct pim_upstream
*up
;
2543 json_object
*json
= NULL
;
2544 json_object
*json_group
= NULL
;
2545 json_object
*json_row
= NULL
;
2548 json
= json_object_new_object();
2551 "Source Group RpfIface RibNextHop RpfAddress \n");
2553 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
, up
)) {
2554 char src_str
[INET_ADDRSTRLEN
];
2555 char grp_str
[INET_ADDRSTRLEN
];
2556 char rpf_nexthop_str
[PREFIX_STRLEN
];
2557 char rpf_addr_str
[PREFIX_STRLEN
];
2558 struct pim_rpf
*rpf
;
2559 const char *rpf_ifname
;
2563 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2564 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2565 pim_addr_dump("<nexthop?>",
2566 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2567 rpf_nexthop_str
, sizeof(rpf_nexthop_str
));
2568 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2569 sizeof(rpf_addr_str
));
2571 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2574 json_object_object_get_ex(json
, grp_str
, &json_group
);
2577 json_group
= json_object_new_object();
2578 json_object_object_add(json
, grp_str
,
2582 json_row
= json_object_new_object();
2583 json_object_pim_upstream_add(json_row
, up
);
2584 json_object_string_add(json_row
, "source", src_str
);
2585 json_object_string_add(json_row
, "group", grp_str
);
2586 json_object_string_add(json_row
, "rpfInterface",
2588 json_object_string_add(json_row
, "ribNexthop",
2590 json_object_string_add(json_row
, "rpfAddress",
2592 json_object_object_add(json_group
, src_str
, json_row
);
2594 vty_out(vty
, "%-15s %-15s %-8s %-15s %-15s\n", src_str
,
2595 grp_str
, rpf_ifname
, rpf_nexthop_str
,
2601 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2602 json
, JSON_C_TO_STRING_PRETTY
));
2603 json_object_free(json
);
2607 static void show_rpf_refresh_stats(struct vty
*vty
, time_t now
,
2610 char refresh_uptime
[10];
2612 pim_time_uptime_begin(refresh_uptime
, sizeof(refresh_uptime
), now
,
2613 qpim_rpf_cache_refresh_last
);
2616 json_object_int_add(json
, "rpfCacheRefreshDelayMsecs",
2617 qpim_rpf_cache_refresh_delay_msec
);
2618 json_object_int_add(
2619 json
, "rpfCacheRefreshTimer",
2620 pim_time_timer_remain_msec(qpim_rpf_cache_refresher
));
2621 json_object_int_add(json
, "rpfCacheRefreshRequests",
2622 qpim_rpf_cache_refresh_requests
);
2623 json_object_int_add(json
, "rpfCacheRefreshEvents",
2624 qpim_rpf_cache_refresh_events
);
2625 json_object_string_add(json
, "rpfCacheRefreshLast",
2627 json_object_int_add(json
, "nexthopLookups",
2628 qpim_nexthop_lookups
);
2629 json_object_int_add(json
, "nexthopLookupsAvoided",
2630 nexthop_lookups_avoided
);
2633 "RPF Cache Refresh Delay: %ld msecs\n"
2634 "RPF Cache Refresh Timer: %ld msecs\n"
2635 "RPF Cache Refresh Requests: %lld\n"
2636 "RPF Cache Refresh Events: %lld\n"
2637 "RPF Cache Refresh Last: %s\n"
2638 "Nexthop Lookups: %lld\n"
2639 "Nexthop Lookups Avoided: %lld\n",
2640 qpim_rpf_cache_refresh_delay_msec
,
2641 pim_time_timer_remain_msec(qpim_rpf_cache_refresher
),
2642 (long long)qpim_rpf_cache_refresh_requests
,
2643 (long long)qpim_rpf_cache_refresh_events
,
2644 refresh_uptime
, (long long)qpim_nexthop_lookups
,
2645 (long long)nexthop_lookups_avoided
);
2649 static void show_scan_oil_stats(struct pim_instance
*pim
, struct vty
*vty
,
2652 char uptime_scan_oil
[10];
2653 char uptime_mroute_add
[10];
2654 char uptime_mroute_del
[10];
2656 pim_time_uptime_begin(uptime_scan_oil
, sizeof(uptime_scan_oil
), now
,
2657 qpim_scan_oil_last
);
2658 pim_time_uptime_begin(uptime_mroute_add
, sizeof(uptime_mroute_add
), now
,
2659 pim
->mroute_add_last
);
2660 pim_time_uptime_begin(uptime_mroute_del
, sizeof(uptime_mroute_del
), now
,
2661 pim
->mroute_del_last
);
2664 "Scan OIL - Last: %s Events: %lld\n"
2665 "MFC Add - Last: %s Events: %lld\n"
2666 "MFC Del - Last: %s Events: %lld\n",
2667 uptime_scan_oil
, (long long)qpim_scan_oil_events
,
2668 uptime_mroute_add
, (long long)pim
->mroute_add_events
,
2669 uptime_mroute_del
, (long long)pim
->mroute_del_events
);
2672 static void pim_show_rpf(struct pim_instance
*pim
, struct vty
*vty
, u_char uj
)
2674 struct listnode
*up_node
;
2675 struct pim_upstream
*up
;
2676 time_t now
= pim_time_monotonic_sec();
2677 json_object
*json
= NULL
;
2678 json_object
*json_group
= NULL
;
2679 json_object
*json_row
= NULL
;
2682 json
= json_object_new_object();
2683 show_rpf_refresh_stats(vty
, now
, json
);
2685 show_rpf_refresh_stats(vty
, now
, json
);
2688 "Source Group RpfIface RpfAddress RibNextHop Metric Pref\n");
2691 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, up_node
, up
)) {
2692 char src_str
[INET_ADDRSTRLEN
];
2693 char grp_str
[INET_ADDRSTRLEN
];
2694 char rpf_addr_str
[PREFIX_STRLEN
];
2695 char rib_nexthop_str
[PREFIX_STRLEN
];
2696 const char *rpf_ifname
;
2697 struct pim_rpf
*rpf
= &up
->rpf
;
2699 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2700 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2701 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2702 sizeof(rpf_addr_str
));
2703 pim_addr_dump("<nexthop?>",
2704 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2705 rib_nexthop_str
, sizeof(rib_nexthop_str
));
2707 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2710 json_object_object_get_ex(json
, grp_str
, &json_group
);
2713 json_group
= json_object_new_object();
2714 json_object_object_add(json
, grp_str
,
2718 json_row
= json_object_new_object();
2719 json_object_string_add(json_row
, "source", src_str
);
2720 json_object_string_add(json_row
, "group", grp_str
);
2721 json_object_string_add(json_row
, "rpfInterface",
2723 json_object_string_add(json_row
, "rpfAddress",
2725 json_object_string_add(json_row
, "ribNexthop",
2727 json_object_int_add(
2728 json_row
, "routeMetric",
2729 rpf
->source_nexthop
.mrib_route_metric
);
2730 json_object_int_add(
2731 json_row
, "routePreference",
2732 rpf
->source_nexthop
.mrib_metric_preference
);
2733 json_object_object_add(json_group
, src_str
, json_row
);
2736 vty_out(vty
, "%-15s %-15s %-8s %-15s %-15s %6d %4d\n",
2737 src_str
, grp_str
, rpf_ifname
, rpf_addr_str
,
2739 rpf
->source_nexthop
.mrib_route_metric
,
2740 rpf
->source_nexthop
.mrib_metric_preference
);
2745 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2746 json
, JSON_C_TO_STRING_PRETTY
));
2747 json_object_free(json
);
2751 struct pnc_cache_walk_data
{
2753 struct pim_instance
*pim
;
2756 static int pim_print_pnc_cache_walkcb(struct hash_backet
*backet
, void *arg
)
2758 struct pim_nexthop_cache
*pnc
= backet
->data
;
2759 struct pnc_cache_walk_data
*cwd
= arg
;
2760 struct vty
*vty
= cwd
->vty
;
2761 struct pim_instance
*pim
= cwd
->pim
;
2762 struct nexthop
*nh_node
= NULL
;
2763 ifindex_t first_ifindex
;
2764 struct interface
*ifp
= NULL
;
2769 for (nh_node
= pnc
->nexthop
; nh_node
; nh_node
= nh_node
->next
) {
2770 first_ifindex
= nh_node
->ifindex
;
2771 ifp
= if_lookup_by_index(first_ifindex
, pim
->vrf_id
);
2773 vty_out(vty
, "%-15s ", inet_ntoa(pnc
->rpf
.rpf_addr
.u
.prefix4
));
2774 vty_out(vty
, "%-14s ", ifp
? ifp
->name
: "NULL");
2775 vty_out(vty
, "%s ", inet_ntoa(nh_node
->gate
.ipv4
));
2781 static void pim_show_nexthop(struct pim_instance
*pim
, struct vty
*vty
)
2783 struct pnc_cache_walk_data cwd
;
2787 vty_out(vty
, "Number of registered addresses: %lu\n",
2788 pim
->rpf_hash
->count
);
2789 vty_out(vty
, "Address Interface Nexthop\n");
2790 vty_out(vty
, "-------------------------------------------\n");
2792 hash_walk(pim
->rpf_hash
, pim_print_pnc_cache_walkcb
, &cwd
);
2795 static void igmp_show_groups(struct pim_instance
*pim
, struct vty
*vty
,
2798 struct interface
*ifp
;
2800 json_object
*json
= NULL
;
2801 json_object
*json_iface
= NULL
;
2802 json_object
*json_row
= NULL
;
2804 now
= pim_time_monotonic_sec();
2807 json
= json_object_new_object();
2810 "Interface Address Group Mode Timer Srcs V Uptime \n");
2812 /* scan interfaces */
2813 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2814 struct pim_interface
*pim_ifp
= ifp
->info
;
2815 struct listnode
*sock_node
;
2816 struct igmp_sock
*igmp
;
2821 /* scan igmp sockets */
2822 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
2824 char ifaddr_str
[INET_ADDRSTRLEN
];
2825 struct listnode
*grpnode
;
2826 struct igmp_group
*grp
;
2828 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
2829 sizeof(ifaddr_str
));
2831 /* scan igmp groups */
2832 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
2834 char group_str
[INET_ADDRSTRLEN
];
2838 pim_inet4_dump("<group?>", grp
->group_addr
,
2839 group_str
, sizeof(group_str
));
2840 pim_time_timer_to_hhmmss(hhmmss
, sizeof(hhmmss
),
2841 grp
->t_group_timer
);
2842 pim_time_uptime(uptime
, sizeof(uptime
),
2843 now
- grp
->group_creation
);
2846 json_object_object_get_ex(
2847 json
, ifp
->name
, &json_iface
);
2851 json_object_new_object();
2852 json_object_pim_ifp_add(
2854 json_object_object_add(
2859 json_row
= json_object_new_object();
2860 json_object_string_add(
2861 json_row
, "source", ifaddr_str
);
2862 json_object_string_add(
2863 json_row
, "group", group_str
);
2865 if (grp
->igmp_version
== 3)
2866 json_object_string_add(
2868 grp
->group_filtermode_isexcl
2872 json_object_string_add(json_row
,
2874 json_object_int_add(
2875 json_row
, "sourcesCount",
2876 grp
->group_source_list
2878 grp
->group_source_list
)
2880 json_object_int_add(json_row
, "version",
2882 json_object_string_add(
2883 json_row
, "uptime", uptime
);
2884 json_object_object_add(json_iface
,
2890 "%-9s %-15s %-15s %4s %8s %4d %d %8s\n",
2891 ifp
->name
, ifaddr_str
,
2893 grp
->igmp_version
== 3
2894 ? (grp
->group_filtermode_isexcl
2899 grp
->group_source_list
2901 grp
->group_source_list
)
2903 grp
->igmp_version
, uptime
);
2905 } /* scan igmp groups */
2906 } /* scan igmp sockets */
2907 } /* scan interfaces */
2910 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2911 json
, JSON_C_TO_STRING_PRETTY
));
2912 json_object_free(json
);
2916 static void igmp_show_group_retransmission(struct pim_instance
*pim
,
2919 struct interface
*ifp
;
2922 "Interface Address Group RetTimer Counter RetSrcs\n");
2924 /* scan interfaces */
2925 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2926 struct pim_interface
*pim_ifp
= ifp
->info
;
2927 struct listnode
*sock_node
;
2928 struct igmp_sock
*igmp
;
2933 /* scan igmp sockets */
2934 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
2936 char ifaddr_str
[INET_ADDRSTRLEN
];
2937 struct listnode
*grpnode
;
2938 struct igmp_group
*grp
;
2940 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
2941 sizeof(ifaddr_str
));
2943 /* scan igmp groups */
2944 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
2946 char group_str
[INET_ADDRSTRLEN
];
2947 char grp_retr_mmss
[10];
2948 struct listnode
*src_node
;
2949 struct igmp_source
*src
;
2950 int grp_retr_sources
= 0;
2952 pim_inet4_dump("<group?>", grp
->group_addr
,
2953 group_str
, sizeof(group_str
));
2954 pim_time_timer_to_mmss(
2955 grp_retr_mmss
, sizeof(grp_retr_mmss
),
2956 grp
->t_group_query_retransmit_timer
);
2959 /* count group sources with retransmission state
2961 for (ALL_LIST_ELEMENTS_RO(
2962 grp
->group_source_list
, src_node
,
2964 if (src
->source_query_retransmit_count
2970 vty_out(vty
, "%-9s %-15s %-15s %-8s %7d %7d\n",
2971 ifp
->name
, ifaddr_str
, group_str
,
2973 grp
->group_specific_query_retransmit_count
,
2976 } /* scan igmp groups */
2977 } /* scan igmp sockets */
2978 } /* scan interfaces */
2981 static void igmp_show_sources(struct pim_instance
*pim
, struct vty
*vty
)
2983 struct interface
*ifp
;
2986 now
= pim_time_monotonic_sec();
2989 "Interface Address Group Source Timer Fwd Uptime \n");
2991 /* scan interfaces */
2992 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2993 struct pim_interface
*pim_ifp
= ifp
->info
;
2994 struct listnode
*sock_node
;
2995 struct igmp_sock
*igmp
;
3000 /* scan igmp sockets */
3001 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3003 char ifaddr_str
[INET_ADDRSTRLEN
];
3004 struct listnode
*grpnode
;
3005 struct igmp_group
*grp
;
3007 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3008 sizeof(ifaddr_str
));
3010 /* scan igmp groups */
3011 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3013 char group_str
[INET_ADDRSTRLEN
];
3014 struct listnode
*srcnode
;
3015 struct igmp_source
*src
;
3017 pim_inet4_dump("<group?>", grp
->group_addr
,
3018 group_str
, sizeof(group_str
));
3020 /* scan group sources */
3021 for (ALL_LIST_ELEMENTS_RO(
3022 grp
->group_source_list
, srcnode
,
3024 char source_str
[INET_ADDRSTRLEN
];
3029 "<source?>", src
->source_addr
,
3030 source_str
, sizeof(source_str
));
3032 pim_time_timer_to_mmss(
3034 src
->t_source_timer
);
3037 uptime
, sizeof(uptime
),
3038 now
- src
->source_creation
);
3041 "%-9s %-15s %-15s %-15s %5s %3s %8s\n",
3042 ifp
->name
, ifaddr_str
,
3043 group_str
, source_str
, mmss
,
3044 IGMP_SOURCE_TEST_FORWARDING(
3050 } /* scan group sources */
3051 } /* scan igmp groups */
3052 } /* scan igmp sockets */
3053 } /* scan interfaces */
3056 static void igmp_show_source_retransmission(struct pim_instance
*pim
,
3059 struct interface
*ifp
;
3062 "Interface Address Group Source Counter\n");
3064 /* scan interfaces */
3065 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3066 struct pim_interface
*pim_ifp
= ifp
->info
;
3067 struct listnode
*sock_node
;
3068 struct igmp_sock
*igmp
;
3073 /* scan igmp sockets */
3074 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3076 char ifaddr_str
[INET_ADDRSTRLEN
];
3077 struct listnode
*grpnode
;
3078 struct igmp_group
*grp
;
3080 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3081 sizeof(ifaddr_str
));
3083 /* scan igmp groups */
3084 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3086 char group_str
[INET_ADDRSTRLEN
];
3087 struct listnode
*srcnode
;
3088 struct igmp_source
*src
;
3090 pim_inet4_dump("<group?>", grp
->group_addr
,
3091 group_str
, sizeof(group_str
));
3093 /* scan group sources */
3094 for (ALL_LIST_ELEMENTS_RO(
3095 grp
->group_source_list
, srcnode
,
3097 char source_str
[INET_ADDRSTRLEN
];
3100 "<source?>", src
->source_addr
,
3101 source_str
, sizeof(source_str
));
3104 "%-9s %-15s %-15s %-15s %7d\n",
3105 ifp
->name
, ifaddr_str
,
3106 group_str
, source_str
,
3107 src
->source_query_retransmit_count
);
3109 } /* scan group sources */
3110 } /* scan igmp groups */
3111 } /* scan igmp sockets */
3112 } /* scan interfaces */
3115 static void clear_igmp_interfaces(struct pim_instance
*pim
)
3117 struct interface
*ifp
;
3119 FOR_ALL_INTERFACES (pim
->vrf
, ifp
)
3120 pim_if_addr_del_all_igmp(ifp
);
3122 FOR_ALL_INTERFACES (pim
->vrf
, ifp
)
3123 pim_if_addr_add_all(ifp
);
3126 static void clear_pim_interfaces(struct pim_instance
*pim
)
3128 struct interface
*ifp
;
3130 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3132 pim_neighbor_delete_all(ifp
, "interface cleared");
3137 static void clear_interfaces(struct pim_instance
*pim
)
3139 clear_igmp_interfaces(pim
);
3140 clear_pim_interfaces(pim
);
3143 #define PIM_GET_PIM_INTERFACE(pim_ifp, ifp) \
3144 pim_ifp = ifp->info; \
3147 "%% Enable PIM and/or IGMP on this interface first\n"); \
3148 return CMD_WARNING_CONFIG_FAILED; \
3151 DEFUN (clear_ip_interfaces
,
3152 clear_ip_interfaces_cmd
,
3153 "clear ip interfaces [vrf NAME]",
3156 "Reset interfaces\n"
3160 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3165 clear_interfaces(vrf
->info
);
3170 DEFUN (clear_ip_igmp_interfaces
,
3171 clear_ip_igmp_interfaces_cmd
,
3172 "clear ip igmp [vrf NAME] interfaces",
3177 "Reset IGMP interfaces\n")
3180 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3185 clear_igmp_interfaces(vrf
->info
);
3190 static void mroute_add_all(struct pim_instance
*pim
)
3192 struct listnode
*node
;
3193 struct channel_oil
*c_oil
;
3195 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
3196 if (pim_mroute_add(c_oil
, __PRETTY_FUNCTION__
)) {
3197 /* just log warning */
3198 char source_str
[INET_ADDRSTRLEN
];
3199 char group_str
[INET_ADDRSTRLEN
];
3200 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
,
3201 source_str
, sizeof(source_str
));
3202 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
,
3203 group_str
, sizeof(group_str
));
3204 zlog_warn("%s %s: (S,G)=(%s,%s) failure writing MFC",
3205 __FILE__
, __PRETTY_FUNCTION__
, source_str
,
3211 static void mroute_del_all(struct pim_instance
*pim
)
3213 struct listnode
*node
;
3214 struct channel_oil
*c_oil
;
3216 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
3217 if (pim_mroute_del(c_oil
, __PRETTY_FUNCTION__
)) {
3218 /* just log warning */
3219 char source_str
[INET_ADDRSTRLEN
];
3220 char group_str
[INET_ADDRSTRLEN
];
3221 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
,
3222 source_str
, sizeof(source_str
));
3223 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
,
3224 group_str
, sizeof(group_str
));
3225 zlog_warn("%s %s: (S,G)=(%s,%s) failure clearing MFC",
3226 __FILE__
, __PRETTY_FUNCTION__
, source_str
,
3232 DEFUN (clear_ip_mroute
,
3233 clear_ip_mroute_cmd
,
3234 "clear ip mroute [vrf NAME]",
3237 "Reset multicast routes\n"
3241 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3246 mroute_del_all(vrf
->info
);
3247 mroute_add_all(vrf
->info
);
3252 DEFUN (clear_ip_pim_interfaces
,
3253 clear_ip_pim_interfaces_cmd
,
3254 "clear ip pim [vrf NAME] interfaces",
3259 "Reset PIM interfaces\n")
3262 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3267 clear_pim_interfaces(vrf
->info
);
3272 DEFUN (clear_ip_pim_interface_traffic
,
3273 clear_ip_pim_interface_traffic_cmd
,
3274 "clear ip pim [vrf NAME] interface traffic",
3277 "PIM clear commands\n"
3279 "Reset PIM interfaces\n"
3280 "Reset Protocol Packet counters\n")
3283 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3284 struct interface
*ifp
= NULL
;
3285 struct pim_interface
*pim_ifp
= NULL
;
3290 FOR_ALL_INTERFACES (vrf
, ifp
) {
3291 pim_ifp
= ifp
->info
;
3296 pim_ifp
->pim_ifstat_hello_recv
= 0;
3297 pim_ifp
->pim_ifstat_hello_sent
= 0;
3298 pim_ifp
->pim_ifstat_join_recv
= 0;
3299 pim_ifp
->pim_ifstat_join_send
= 0;
3300 pim_ifp
->pim_ifstat_prune_recv
= 0;
3301 pim_ifp
->pim_ifstat_prune_send
= 0;
3302 pim_ifp
->pim_ifstat_reg_recv
= 0;
3303 pim_ifp
->pim_ifstat_reg_send
= 0;
3304 pim_ifp
->pim_ifstat_reg_stop_recv
= 0;
3305 pim_ifp
->pim_ifstat_reg_stop_send
= 0;
3306 pim_ifp
->pim_ifstat_assert_recv
= 0;
3307 pim_ifp
->pim_ifstat_assert_send
= 0;
3313 DEFUN (clear_ip_pim_oil
,
3314 clear_ip_pim_oil_cmd
,
3315 "clear ip pim [vrf NAME] oil",
3320 "Rescan PIM OIL (output interface list)\n")
3323 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3328 pim_scan_oil(vrf
->info
);
3333 DEFUN (show_ip_igmp_interface
,
3334 show_ip_igmp_interface_cmd
,
3335 "show ip igmp [vrf NAME] interface [detail|WORD] [json]",
3340 "IGMP interface information\n"
3346 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3347 u_char uj
= use_json(argc
, argv
);
3352 if (argv_find(argv
, argc
, "detail", &idx
)
3353 || argv_find(argv
, argc
, "WORD", &idx
))
3354 igmp_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
3356 igmp_show_interfaces(vrf
->info
, vty
, uj
);
3361 DEFUN (show_ip_igmp_interface_vrf_all
,
3362 show_ip_igmp_interface_vrf_all_cmd
,
3363 "show ip igmp vrf all interface [detail|WORD] [json]",
3368 "IGMP interface information\n"
3374 u_char uj
= use_json(argc
, argv
);
3380 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3384 vty_out(vty
, " \"%s\": ", vrf
->name
);
3387 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3388 if (argv_find(argv
, argc
, "detail", &idx
)
3389 || argv_find(argv
, argc
, "WORD", &idx
))
3390 igmp_show_interfaces_single(vrf
->info
, vty
,
3391 argv
[idx
]->arg
, uj
);
3393 igmp_show_interfaces(vrf
->info
, vty
, uj
);
3396 vty_out(vty
, "}\n");
3401 DEFUN (show_ip_igmp_join
,
3402 show_ip_igmp_join_cmd
,
3403 "show ip igmp [vrf NAME] join",
3408 "IGMP static join information\n")
3411 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3416 igmp_show_interface_join(vrf
->info
, vty
);
3421 DEFUN (show_ip_igmp_join_vrf_all
,
3422 show_ip_igmp_join_vrf_all_cmd
,
3423 "show ip igmp vrf all join",
3428 "IGMP static join information\n")
3430 u_char uj
= use_json(argc
, argv
);
3436 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3440 vty_out(vty
, " \"%s\": ", vrf
->name
);
3443 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3444 igmp_show_interface_join(vrf
->info
, vty
);
3447 vty_out(vty
, "}\n");
3452 DEFUN (show_ip_igmp_groups
,
3453 show_ip_igmp_groups_cmd
,
3454 "show ip igmp [vrf NAME] groups [json]",
3463 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3464 u_char uj
= use_json(argc
, argv
);
3469 igmp_show_groups(vrf
->info
, vty
, uj
);
3474 DEFUN (show_ip_igmp_groups_vrf_all
,
3475 show_ip_igmp_groups_vrf_all_cmd
,
3476 "show ip igmp vrf all groups [json]",
3484 u_char uj
= use_json(argc
, argv
);
3490 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3494 vty_out(vty
, " \"%s\": ", vrf
->name
);
3497 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3498 igmp_show_groups(vrf
->info
, vty
, uj
);
3501 vty_out(vty
, "}\n");
3506 DEFUN (show_ip_igmp_groups_retransmissions
,
3507 show_ip_igmp_groups_retransmissions_cmd
,
3508 "show ip igmp [vrf NAME] groups retransmissions",
3514 "IGMP group retransmissions\n")
3517 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3522 igmp_show_group_retransmission(vrf
->info
, vty
);
3527 DEFUN (show_ip_igmp_sources
,
3528 show_ip_igmp_sources_cmd
,
3529 "show ip igmp [vrf NAME] sources",
3537 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3542 igmp_show_sources(vrf
->info
, vty
);
3547 DEFUN (show_ip_igmp_sources_retransmissions
,
3548 show_ip_igmp_sources_retransmissions_cmd
,
3549 "show ip igmp [vrf NAME] sources retransmissions",
3555 "IGMP source retransmissions\n")
3558 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3563 igmp_show_source_retransmission(vrf
->info
, vty
);
3568 DEFUN (show_ip_pim_assert
,
3569 show_ip_pim_assert_cmd
,
3570 "show ip pim [vrf NAME] assert",
3575 "PIM interface assert\n")
3578 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3583 pim_show_assert(vrf
->info
, vty
);
3588 DEFUN (show_ip_pim_assert_internal
,
3589 show_ip_pim_assert_internal_cmd
,
3590 "show ip pim [vrf NAME] assert-internal",
3595 "PIM interface internal assert state\n")
3598 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3603 pim_show_assert_internal(vrf
->info
, vty
);
3608 DEFUN (show_ip_pim_assert_metric
,
3609 show_ip_pim_assert_metric_cmd
,
3610 "show ip pim [vrf NAME] assert-metric",
3615 "PIM interface assert metric\n")
3618 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3623 pim_show_assert_metric(vrf
->info
, vty
);
3628 DEFUN (show_ip_pim_assert_winner_metric
,
3629 show_ip_pim_assert_winner_metric_cmd
,
3630 "show ip pim [vrf NAME] assert-winner-metric",
3635 "PIM interface assert winner metric\n")
3638 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3643 pim_show_assert_winner_metric(vrf
->info
, vty
);
3648 DEFUN (show_ip_pim_interface
,
3649 show_ip_pim_interface_cmd
,
3650 "show ip pim [vrf NAME] interface [detail|WORD] [json]",
3655 "PIM interface information\n"
3661 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3662 u_char uj
= use_json(argc
, argv
);
3667 if (argv_find(argv
, argc
, "WORD", &idx
)
3668 || argv_find(argv
, argc
, "detail", &idx
))
3669 pim_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
3671 pim_show_interfaces(vrf
->info
, vty
, uj
);
3676 DEFUN (show_ip_pim_interface_vrf_all
,
3677 show_ip_pim_interface_vrf_all_cmd
,
3678 "show ip pim vrf all interface [detail|WORD] [json]",
3683 "PIM interface information\n"
3689 u_char uj
= use_json(argc
, argv
);
3695 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3699 vty_out(vty
, " \"%s\": ", vrf
->name
);
3702 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3703 if (argv_find(argv
, argc
, "WORD", &idx
)
3704 || argv_find(argv
, argc
, "detail", &idx
))
3705 pim_show_interfaces_single(vrf
->info
, vty
,
3706 argv
[idx
]->arg
, uj
);
3708 pim_show_interfaces(vrf
->info
, vty
, uj
);
3711 vty_out(vty
, "}\n");
3716 DEFUN (show_ip_pim_join
,
3717 show_ip_pim_join_cmd
,
3718 "show ip pim [vrf NAME] join [json]",
3723 "PIM interface join information\n"
3727 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3728 u_char uj
= use_json(argc
, argv
);
3733 pim_show_join(vrf
->info
, vty
, uj
);
3738 DEFUN (show_ip_pim_join_vrf_all
,
3739 show_ip_pim_join_vrf_all_cmd
,
3740 "show ip pim vrf all join [json]",
3745 "PIM interface join information\n"
3748 u_char uj
= use_json(argc
, argv
);
3754 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3758 vty_out(vty
, " \"%s\": ", vrf
->name
);
3761 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3762 pim_show_join(vrf
->info
, vty
, uj
);
3765 vty_out(vty
, "}\n");
3770 DEFUN (show_ip_pim_local_membership
,
3771 show_ip_pim_local_membership_cmd
,
3772 "show ip pim [vrf NAME] local-membership [json]",
3777 "PIM interface local-membership\n"
3781 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3782 u_char uj
= use_json(argc
, argv
);
3787 pim_show_membership(vrf
->info
, vty
, uj
);
3792 DEFUN (show_ip_pim_neighbor
,
3793 show_ip_pim_neighbor_cmd
,
3794 "show ip pim [vrf NAME] neighbor [detail|WORD] [json]",
3799 "PIM neighbor information\n"
3801 "Name of interface or neighbor\n"
3805 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3806 u_char uj
= use_json(argc
, argv
);
3811 if (argv_find(argv
, argc
, "detail", &idx
)
3812 || argv_find(argv
, argc
, "WORD", &idx
))
3813 pim_show_neighbors_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
3815 pim_show_neighbors(vrf
->info
, vty
, uj
);
3820 DEFUN (show_ip_pim_neighbor_vrf_all
,
3821 show_ip_pim_neighbor_vrf_all_cmd
,
3822 "show ip pim vrf all neighbor [detail|WORD] [json]",
3827 "PIM neighbor information\n"
3829 "Name of interface or neighbor\n"
3833 u_char uj
= use_json(argc
, argv
);
3839 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3843 vty_out(vty
, " \"%s\": ", vrf
->name
);
3846 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3847 if (argv_find(argv
, argc
, "detail", &idx
)
3848 || argv_find(argv
, argc
, "WORD", &idx
))
3849 pim_show_neighbors_single(vrf
->info
, vty
,
3850 argv
[idx
]->arg
, uj
);
3852 pim_show_neighbors(vrf
->info
, vty
, uj
);
3855 vty_out(vty
, "}\n");
3860 DEFUN (show_ip_pim_secondary
,
3861 show_ip_pim_secondary_cmd
,
3862 "show ip pim [vrf NAME] secondary",
3867 "PIM neighbor addresses\n")
3870 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3875 pim_show_neighbors_secondary(vrf
->info
, vty
);
3880 DEFUN (show_ip_pim_state
,
3881 show_ip_pim_state_cmd
,
3882 "show ip pim [vrf NAME] state [A.B.C.D [A.B.C.D]] [json]",
3887 "PIM state information\n"
3888 "Unicast or Multicast address\n"
3889 "Multicast address\n"
3892 const char *src_or_group
= NULL
;
3893 const char *group
= NULL
;
3895 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3896 u_char uj
= use_json(argc
, argv
);
3904 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
3905 src_or_group
= argv
[idx
]->arg
;
3907 group
= argv
[idx
+ 1]->arg
;
3910 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
3915 DEFUN (show_ip_pim_state_vrf_all
,
3916 show_ip_pim_state_vrf_all_cmd
,
3917 "show ip pim vrf all state [A.B.C.D [A.B.C.D]] [json]",
3922 "PIM state information\n"
3923 "Unicast or Multicast address\n"
3924 "Multicast address\n"
3927 const char *src_or_group
= NULL
;
3928 const char *group
= NULL
;
3930 u_char uj
= use_json(argc
, argv
);
3939 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
3940 src_or_group
= argv
[idx
]->arg
;
3942 group
= argv
[idx
+ 1]->arg
;
3945 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3949 vty_out(vty
, " \"%s\": ", vrf
->name
);
3952 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3953 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
3956 vty_out(vty
, "}\n");
3961 DEFUN (show_ip_pim_upstream
,
3962 show_ip_pim_upstream_cmd
,
3963 "show ip pim [vrf NAME] upstream [json]",
3968 "PIM upstream information\n"
3972 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3973 u_char uj
= use_json(argc
, argv
);
3978 pim_show_upstream(vrf
->info
, vty
, uj
);
3983 DEFUN (show_ip_pim_upstream_vrf_all
,
3984 show_ip_pim_upstream_vrf_all_cmd
,
3985 "show ip pim vrf all upstream [json]",
3990 "PIM upstream information\n"
3993 u_char uj
= use_json(argc
, argv
);
3999 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4003 vty_out(vty
, " \"%s\": ", vrf
->name
);
4006 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4007 pim_show_upstream(vrf
->info
, vty
, uj
);
4013 DEFUN (show_ip_pim_upstream_join_desired
,
4014 show_ip_pim_upstream_join_desired_cmd
,
4015 "show ip pim [vrf NAME] upstream-join-desired [json]",
4020 "PIM upstream join-desired\n"
4024 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4025 u_char uj
= use_json(argc
, argv
);
4030 pim_show_join_desired(vrf
->info
, vty
, uj
);
4035 DEFUN (show_ip_pim_upstream_rpf
,
4036 show_ip_pim_upstream_rpf_cmd
,
4037 "show ip pim [vrf NAME] upstream-rpf [json]",
4042 "PIM upstream source rpf\n"
4046 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4047 u_char uj
= use_json(argc
, argv
);
4052 pim_show_upstream_rpf(vrf
->info
, vty
, uj
);
4057 DEFUN (show_ip_pim_rp
,
4059 "show ip pim [vrf NAME] rp-info [json]",
4064 "PIM RP information\n"
4068 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4069 u_char uj
= use_json(argc
, argv
);
4074 pim_rp_show_information(vrf
->info
, vty
, uj
);
4079 DEFUN (show_ip_pim_rp_vrf_all
,
4080 show_ip_pim_rp_vrf_all_cmd
,
4081 "show ip pim vrf all rp-info [json]",
4086 "PIM RP information\n"
4089 u_char uj
= use_json(argc
, argv
);
4095 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4099 vty_out(vty
, " \"%s\": ", vrf
->name
);
4102 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4103 pim_rp_show_information(vrf
->info
, vty
, uj
);
4106 vty_out(vty
, "}\n");
4111 DEFUN (show_ip_pim_rpf
,
4112 show_ip_pim_rpf_cmd
,
4113 "show ip pim [vrf NAME] rpf [json]",
4118 "PIM cached source rpf information\n"
4122 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4123 u_char uj
= use_json(argc
, argv
);
4128 pim_show_rpf(vrf
->info
, vty
, uj
);
4133 DEFUN (show_ip_pim_rpf_vrf_all
,
4134 show_ip_pim_rpf_vrf_all_cmd
,
4135 "show ip pim vrf all rpf [json]",
4140 "PIM cached source rpf information\n"
4143 u_char uj
= use_json(argc
, argv
);
4149 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4153 vty_out(vty
, " \"%s\": ", vrf
->name
);
4156 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4157 pim_show_rpf(vrf
->info
, vty
, uj
);
4160 vty_out(vty
, "}\n");
4165 DEFUN (show_ip_pim_nexthop
,
4166 show_ip_pim_nexthop_cmd
,
4167 "show ip pim [vrf NAME] nexthop",
4172 "PIM cached nexthop rpf information\n")
4175 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4180 pim_show_nexthop(vrf
->info
, vty
);
4185 DEFUN (show_ip_pim_nexthop_lookup
,
4186 show_ip_pim_nexthop_lookup_cmd
,
4187 "show ip pim [vrf NAME] nexthop-lookup A.B.C.D A.B.C.D",
4192 "PIM cached nexthop rpf lookup\n"
4193 "Source/RP address\n"
4194 "Multicast Group address\n")
4196 struct pim_nexthop_cache pnc
;
4197 struct prefix nht_p
;
4199 struct in_addr src_addr
, grp_addr
;
4200 struct in_addr vif_source
;
4201 const char *addr_str
, *addr_str1
;
4203 struct pim_nexthop nexthop
;
4204 char nexthop_addr_str
[PREFIX_STRLEN
];
4205 char grp_str
[PREFIX_STRLEN
];
4207 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4212 argv_find(argv
, argc
, "A.B.C.D", &idx
);
4213 addr_str
= argv
[idx
]->arg
;
4214 result
= inet_pton(AF_INET
, addr_str
, &src_addr
);
4216 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
4217 errno
, safe_strerror(errno
));
4221 if (pim_is_group_224_4(src_addr
)) {
4223 "Invalid argument. Expected Valid Source Address.\n");
4227 addr_str1
= argv
[idx
+ 1]->arg
;
4228 result
= inet_pton(AF_INET
, addr_str1
, &grp_addr
);
4230 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
4231 errno
, safe_strerror(errno
));
4235 if (!pim_is_group_224_4(grp_addr
)) {
4237 "Invalid argument. Expected Valid Multicast Group Address.\n");
4241 if (!pim_rp_set_upstream_addr(vrf
->info
, &vif_source
, src_addr
,
4245 memset(&pnc
, 0, sizeof(struct pim_nexthop_cache
));
4246 nht_p
.family
= AF_INET
;
4247 nht_p
.prefixlen
= IPV4_MAX_BITLEN
;
4248 nht_p
.u
.prefix4
= vif_source
;
4249 grp
.family
= AF_INET
;
4250 grp
.prefixlen
= IPV4_MAX_BITLEN
;
4251 grp
.u
.prefix4
= grp_addr
;
4252 memset(&nexthop
, 0, sizeof(nexthop
));
4254 if (pim_find_or_track_nexthop(vrf
->info
, &nht_p
, NULL
, NULL
, &pnc
))
4255 result
= pim_ecmp_nexthop_search(vrf
->info
, &pnc
, &nexthop
,
4258 result
= pim_ecmp_nexthop_lookup(vrf
->info
, &nexthop
, vif_source
,
4262 vty_out(vty
, "Nexthop Lookup failed, no usable routes returned.\n");
4266 pim_addr_dump("<grp?>", &grp
, grp_str
, sizeof(grp_str
));
4267 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
4268 nexthop_addr_str
, sizeof(nexthop_addr_str
));
4269 vty_out(vty
, "Group %s --- Nexthop %s Interface %s \n", grp_str
,
4270 nexthop_addr_str
, nexthop
.interface
->name
);
4275 DEFUN (show_ip_pim_interface_traffic
,
4276 show_ip_pim_interface_traffic_cmd
,
4277 "show ip pim [vrf NAME] interface traffic [WORD] [json]",
4282 "PIM interface information\n"
4283 "Protocol Packet counters\n"
4288 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4289 u_char uj
= use_json(argc
, argv
);
4294 if (argv_find(argv
, argc
, "WORD", &idx
))
4295 pim_show_interface_traffic_single(vrf
->info
, vty
,
4296 argv
[idx
]->arg
, uj
);
4298 pim_show_interface_traffic(vrf
->info
, vty
, uj
);
4303 static void show_multicast_interfaces(struct pim_instance
*pim
, struct vty
*vty
)
4305 struct interface
*ifp
;
4310 "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut\n");
4312 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
4313 struct pim_interface
*pim_ifp
;
4314 struct in_addr ifaddr
;
4315 struct sioc_vif_req vreq
;
4317 pim_ifp
= ifp
->info
;
4322 memset(&vreq
, 0, sizeof(vreq
));
4323 vreq
.vifi
= pim_ifp
->mroute_vif_index
;
4325 if (ioctl(pim
->mroute_socket
, SIOCGETVIFCNT
, &vreq
)) {
4327 "ioctl(SIOCGETVIFCNT=%lu) failure for interface %s vif_index=%d: errno=%d: %s",
4328 (unsigned long)SIOCGETVIFCNT
, ifp
->name
,
4329 pim_ifp
->mroute_vif_index
, errno
,
4330 safe_strerror(errno
));
4333 ifaddr
= pim_ifp
->primary_address
;
4335 vty_out(vty
, "%-12s %-15s %3d %3d %7lu %7lu %10lu %10lu\n",
4336 ifp
->name
, inet_ntoa(ifaddr
), ifp
->ifindex
,
4337 pim_ifp
->mroute_vif_index
, (unsigned long)vreq
.icount
,
4338 (unsigned long)vreq
.ocount
, (unsigned long)vreq
.ibytes
,
4339 (unsigned long)vreq
.obytes
);
4343 static void pim_cmd_show_ip_multicast_helper(struct pim_instance
*pim
,
4346 struct vrf
*vrf
= pim
->vrf
;
4347 time_t now
= pim_time_monotonic_sec();
4352 vty_out(vty
, "Mroute socket descriptor:");
4354 vty_out(vty
, " %d(%s)\n", pim
->mroute_socket
, vrf
->name
);
4356 pim_time_uptime(uptime
, sizeof(uptime
),
4357 now
- pim
->mroute_socket_creation
);
4358 vty_out(vty
, "Mroute socket uptime: %s\n", uptime
);
4362 pim_zebra_zclient_update(vty
);
4363 pim_zlookup_show_ip_multicast(vty
);
4366 vty_out(vty
, "Maximum highest VifIndex: %d\n", PIM_MAX_USABLE_VIFS
);
4369 vty_out(vty
, "Upstream Join Timer: %d secs\n", qpim_t_periodic
);
4370 vty_out(vty
, "Join/Prune Holdtime: %d secs\n", PIM_JP_HOLDTIME
);
4371 vty_out(vty
, "PIM ECMP: %s\n", qpim_ecmp_enable
? "Enable" : "Disable");
4372 vty_out(vty
, "PIM ECMP Rebalance: %s\n",
4373 qpim_ecmp_rebalance_enable
? "Enable" : "Disable");
4377 show_rpf_refresh_stats(vty
, now
, NULL
);
4381 show_scan_oil_stats(pim
, vty
, now
);
4383 show_multicast_interfaces(pim
, vty
);
4386 DEFUN (show_ip_multicast
,
4387 show_ip_multicast_cmd
,
4388 "show ip multicast [vrf NAME]",
4392 "Multicast global information\n")
4395 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4400 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
4405 DEFUN (show_ip_multicast_vrf_all
,
4406 show_ip_multicast_vrf_all_cmd
,
4407 "show ip multicast vrf all",
4411 "Multicast global information\n")
4413 u_char uj
= use_json(argc
, argv
);
4419 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4423 vty_out(vty
, " \"%s\": ", vrf
->name
);
4426 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4427 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
4430 vty_out(vty
, "}\n");
4435 static void show_mroute(struct pim_instance
*pim
, struct vty
*vty
,
4436 bool fill
, u_char uj
)
4438 struct listnode
*node
;
4439 struct channel_oil
*c_oil
;
4440 struct static_route
*s_route
;
4442 json_object
*json
= NULL
;
4443 json_object
*json_group
= NULL
;
4444 json_object
*json_source
= NULL
;
4445 json_object
*json_oil
= NULL
;
4446 json_object
*json_ifp_out
= NULL
;
4449 char grp_str
[INET_ADDRSTRLEN
];
4450 char src_str
[INET_ADDRSTRLEN
];
4451 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
4452 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
4454 struct interface
*ifp_in
;
4458 json
= json_object_new_object();
4461 "Source Group Proto Input Output TTL Uptime\n");
4464 now
= pim_time_monotonic_sec();
4466 /* print list of PIM and IGMP routes */
4467 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
4470 if (!c_oil
->installed
&& !uj
)
4473 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
4475 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
4477 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
4480 strcpy(in_ifname
, ifp_in
->name
);
4482 strcpy(in_ifname
, "<iif?>");
4486 /* Find the group, create it if it doesn't exist */
4487 json_object_object_get_ex(json
, grp_str
, &json_group
);
4490 json_group
= json_object_new_object();
4491 json_object_object_add(json
, grp_str
,
4495 /* Find the source nested under the group, create it if
4496 * it doesn't exist */
4497 json_object_object_get_ex(json_group
, src_str
,
4501 json_source
= json_object_new_object();
4502 json_object_object_add(json_group
, src_str
,
4506 /* Find the inbound interface nested under the source,
4507 * create it if it doesn't exist */
4508 json_object_int_add(json_source
, "installed",
4510 json_object_int_add(json_source
, "refCount",
4511 c_oil
->oil_ref_count
);
4512 json_object_int_add(json_source
, "oilSize",
4514 json_object_int_add(json_source
, "OilInheritedRescan",
4515 c_oil
->oil_inherited_rescan
);
4516 json_object_string_add(json_source
, "iif", in_ifname
);
4520 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
4522 struct interface
*ifp_out
;
4523 char oif_uptime
[10];
4526 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
4530 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
4532 oif_uptime
, sizeof(oif_uptime
),
4533 now
- c_oil
->oif_creation
[oif_vif_index
]);
4537 strcpy(out_ifname
, ifp_out
->name
);
4539 strcpy(out_ifname
, "<oif?>");
4542 json_ifp_out
= json_object_new_object();
4543 json_object_string_add(json_ifp_out
, "source",
4545 json_object_string_add(json_ifp_out
, "group",
4548 if (c_oil
->oif_flags
[oif_vif_index
]
4549 & PIM_OIF_FLAG_PROTO_PIM
)
4550 json_object_boolean_true_add(
4551 json_ifp_out
, "protocolPim");
4553 if (c_oil
->oif_flags
[oif_vif_index
]
4554 & PIM_OIF_FLAG_PROTO_IGMP
)
4555 json_object_boolean_true_add(
4556 json_ifp_out
, "protocolIgmp");
4558 if (c_oil
->oif_flags
[oif_vif_index
]
4559 & PIM_OIF_FLAG_PROTO_SOURCE
)
4560 json_object_boolean_true_add(
4561 json_ifp_out
, "protocolSource");
4563 if (c_oil
->oif_flags
[oif_vif_index
]
4564 & PIM_OIF_FLAG_PROTO_STAR
)
4565 json_object_boolean_true_add(
4567 "protocolInherited");
4569 json_object_string_add(json_ifp_out
,
4572 json_object_int_add(json_ifp_out
, "iVifI",
4573 c_oil
->oil
.mfcc_parent
);
4574 json_object_string_add(json_ifp_out
,
4575 "outboundInterface",
4577 json_object_int_add(json_ifp_out
, "oVifI",
4579 json_object_int_add(json_ifp_out
, "ttl", ttl
);
4580 json_object_string_add(json_ifp_out
, "upTime",
4583 json_oil
= json_object_new_object();
4584 json_object_object_add(json_source
,
4587 json_object_object_add(json_oil
, out_ifname
,
4590 if (c_oil
->oif_flags
[oif_vif_index
]
4591 & PIM_OIF_FLAG_PROTO_PIM
) {
4592 strcpy(proto
, "PIM");
4595 if (c_oil
->oif_flags
[oif_vif_index
]
4596 & PIM_OIF_FLAG_PROTO_IGMP
) {
4597 strcpy(proto
, "IGMP");
4600 if (c_oil
->oif_flags
[oif_vif_index
]
4601 & PIM_OIF_FLAG_PROTO_SOURCE
) {
4602 strcpy(proto
, "SRC");
4605 if (c_oil
->oif_flags
[oif_vif_index
]
4606 & PIM_OIF_FLAG_PROTO_STAR
) {
4607 strcpy(proto
, "STAR");
4611 "%-15s %-15s %-6s %-10s %-10s %-3d %8s\n",
4612 src_str
, grp_str
, proto
, in_ifname
,
4613 out_ifname
, ttl
, oif_uptime
);
4618 in_ifname
[0] = '\0';
4624 if (!uj
&& !found_oif
) {
4625 vty_out(vty
, "%-15s %-15s %-6s %-10s %-10s %-3d %8s\n",
4626 src_str
, grp_str
, "none", in_ifname
, "none", 0,
4631 /* Print list of static routes */
4632 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
4635 if (!s_route
->c_oil
.installed
)
4638 pim_inet4_dump("<group?>", s_route
->group
, grp_str
,
4640 pim_inet4_dump("<source?>", s_route
->source
, src_str
,
4642 ifp_in
= pim_if_find_by_vif_index(pim
, s_route
->iif
);
4646 strcpy(in_ifname
, ifp_in
->name
);
4648 strcpy(in_ifname
, "<iif?>");
4652 /* Find the group, create it if it doesn't exist */
4653 json_object_object_get_ex(json
, grp_str
, &json_group
);
4656 json_group
= json_object_new_object();
4657 json_object_object_add(json
, grp_str
,
4661 /* Find the source nested under the group, create it if
4662 * it doesn't exist */
4663 json_object_object_get_ex(json_group
, src_str
,
4667 json_source
= json_object_new_object();
4668 json_object_object_add(json_group
, src_str
,
4672 json_object_string_add(json_source
, "iif", in_ifname
);
4675 strcpy(proto
, "STATIC");
4678 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
4680 struct interface
*ifp_out
;
4681 char oif_uptime
[10];
4684 ttl
= s_route
->oif_ttls
[oif_vif_index
];
4688 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
4689 pim_time_uptime(oif_uptime
, sizeof(oif_uptime
),
4691 s_route
->c_oil
.oif_creation
[oif_vif_index
]);
4695 strcpy(out_ifname
, ifp_out
->name
);
4697 strcpy(out_ifname
, "<oif?>");
4700 json_ifp_out
= json_object_new_object();
4701 json_object_string_add(json_ifp_out
, "source",
4703 json_object_string_add(json_ifp_out
, "group",
4705 json_object_boolean_true_add(json_ifp_out
,
4707 json_object_string_add(json_ifp_out
,
4710 json_object_int_add(
4711 json_ifp_out
, "iVifI",
4712 s_route
->c_oil
.oil
.mfcc_parent
);
4713 json_object_string_add(json_ifp_out
,
4714 "outboundInterface",
4716 json_object_int_add(json_ifp_out
, "oVifI",
4718 json_object_int_add(json_ifp_out
, "ttl", ttl
);
4719 json_object_string_add(json_ifp_out
, "upTime",
4722 json_oil
= json_object_new_object();
4723 json_object_object_add(json_source
,
4726 json_object_object_add(json_oil
, out_ifname
,
4730 "%-15s %-15s %-6s %-10s %-10s %-3d %8s %s\n",
4731 src_str
, grp_str
, proto
, in_ifname
,
4732 out_ifname
, ttl
, oif_uptime
,
4734 if (first
&& !fill
) {
4737 in_ifname
[0] = '\0';
4743 if (!uj
&& !found_oif
) {
4745 "%-15s %-15s %-6s %-10s %-10s %-3d %8s %s\n",
4746 src_str
, grp_str
, proto
, in_ifname
, "none", 0,
4747 "--:--:--", pim
->vrf
->name
);
4752 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4753 json
, JSON_C_TO_STRING_PRETTY
));
4754 json_object_free(json
);
4758 DEFUN (show_ip_mroute
,
4760 "show ip mroute [vrf NAME] [fill] [json]",
4765 "Fill in Assumed data\n"
4768 u_char uj
= use_json(argc
, argv
);
4771 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4776 if (argv_find(argv
, argc
, "fill", &idx
))
4779 show_mroute(vrf
->info
, vty
, fill
, uj
);
4783 DEFUN (show_ip_mroute_vrf_all
,
4784 show_ip_mroute_vrf_all_cmd
,
4785 "show ip mroute vrf all [fill] [json]",
4790 "Fill in Assumed data\n"
4793 u_char uj
= use_json(argc
, argv
);
4799 if (argv_find(argv
, argc
, "fill", &idx
))
4804 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4808 vty_out(vty
, " \"%s\": ", vrf
->name
);
4811 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4812 show_mroute(vrf
->info
, vty
, fill
, uj
);
4815 vty_out(vty
, "}\n");
4820 static void show_mroute_count(struct pim_instance
*pim
, struct vty
*vty
)
4822 struct listnode
*node
;
4823 struct channel_oil
*c_oil
;
4824 struct static_route
*s_route
;
4829 "Source Group LastUsed Packets Bytes WrongIf \n");
4831 /* Print PIM and IGMP route counts */
4832 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
4833 char group_str
[INET_ADDRSTRLEN
];
4834 char source_str
[INET_ADDRSTRLEN
];
4836 if (!c_oil
->installed
)
4839 pim_mroute_update_counters(c_oil
);
4841 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, group_str
,
4843 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, source_str
,
4844 sizeof(source_str
));
4846 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
4847 source_str
, group_str
, c_oil
->cc
.lastused
/ 100,
4848 c_oil
->cc
.pktcnt
, c_oil
->cc
.bytecnt
,
4849 c_oil
->cc
.wrong_if
);
4852 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
4853 char group_str
[INET_ADDRSTRLEN
];
4854 char source_str
[INET_ADDRSTRLEN
];
4856 if (!s_route
->c_oil
.installed
)
4859 pim_mroute_update_counters(&s_route
->c_oil
);
4861 pim_inet4_dump("<group?>", s_route
->c_oil
.oil
.mfcc_mcastgrp
,
4862 group_str
, sizeof(group_str
));
4863 pim_inet4_dump("<source?>", s_route
->c_oil
.oil
.mfcc_origin
,
4864 source_str
, sizeof(source_str
));
4866 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
4867 source_str
, group_str
, s_route
->c_oil
.cc
.lastused
,
4868 s_route
->c_oil
.cc
.pktcnt
, s_route
->c_oil
.cc
.bytecnt
,
4869 s_route
->c_oil
.cc
.wrong_if
);
4873 DEFUN (show_ip_mroute_count
,
4874 show_ip_mroute_count_cmd
,
4875 "show ip mroute [vrf NAME] count",
4880 "Route and packet count data\n")
4883 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4888 show_mroute_count(vrf
->info
, vty
);
4892 DEFUN (show_ip_mroute_count_vrf_all
,
4893 show_ip_mroute_count_vrf_all_cmd
,
4894 "show ip mroute vrf all count",
4899 "Route and packet count data\n")
4901 u_char uj
= use_json(argc
, argv
);
4907 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4911 vty_out(vty
, " \"%s\": ", vrf
->name
);
4914 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4915 show_mroute_count(vrf
->info
, vty
);
4918 vty_out(vty
, "}\n");
4925 "show ip rib [vrf NAME] A.B.C.D",
4930 "Unicast address\n")
4933 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4934 struct in_addr addr
;
4935 const char *addr_str
;
4936 struct pim_nexthop nexthop
;
4937 char nexthop_addr_str
[PREFIX_STRLEN
];
4943 memset(&nexthop
, 0, sizeof(nexthop
));
4944 argv_find(argv
, argc
, "A.B.C.D", &idx
);
4945 addr_str
= argv
[idx
]->arg
;
4946 result
= inet_pton(AF_INET
, addr_str
, &addr
);
4948 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
4949 errno
, safe_strerror(errno
));
4953 if (pim_nexthop_lookup(vrf
->info
, &nexthop
, addr
, 0)) {
4955 "Failure querying RIB nexthop for unicast address %s\n",
4961 "Address NextHop Interface Metric Preference\n");
4963 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
4964 nexthop_addr_str
, sizeof(nexthop_addr_str
));
4966 vty_out(vty
, "%-15s %-15s %-9s %6d %10d\n", addr_str
, nexthop_addr_str
,
4967 nexthop
.interface
? nexthop
.interface
->name
: "<ifname?>",
4968 nexthop
.mrib_route_metric
, nexthop
.mrib_metric_preference
);
4973 static void show_ssmpingd(struct pim_instance
*pim
, struct vty
*vty
)
4975 struct listnode
*node
;
4976 struct ssmpingd_sock
*ss
;
4980 "Source Socket Address Port Uptime Requests\n");
4982 if (!pim
->ssmpingd_list
)
4985 now
= pim_time_monotonic_sec();
4987 for (ALL_LIST_ELEMENTS_RO(pim
->ssmpingd_list
, node
, ss
)) {
4988 char source_str
[INET_ADDRSTRLEN
];
4990 struct sockaddr_in bind_addr
;
4991 socklen_t len
= sizeof(bind_addr
);
4992 char bind_addr_str
[INET_ADDRSTRLEN
];
4994 pim_inet4_dump("<src?>", ss
->source_addr
, source_str
,
4995 sizeof(source_str
));
4997 if (pim_socket_getsockname(
4998 ss
->sock_fd
, (struct sockaddr
*)&bind_addr
, &len
)) {
5000 "%% Failure reading socket name for ssmpingd source %s on fd=%d\n",
5001 source_str
, ss
->sock_fd
);
5004 pim_inet4_dump("<addr?>", bind_addr
.sin_addr
, bind_addr_str
,
5005 sizeof(bind_addr_str
));
5006 pim_time_uptime(ss_uptime
, sizeof(ss_uptime
),
5007 now
- ss
->creation
);
5009 vty_out(vty
, "%-15s %6d %-15s %5d %8s %8lld\n", source_str
,
5010 ss
->sock_fd
, bind_addr_str
, ntohs(bind_addr
.sin_port
),
5011 ss_uptime
, (long long)ss
->requests
);
5015 DEFUN (show_ip_ssmpingd
,
5016 show_ip_ssmpingd_cmd
,
5017 "show ip ssmpingd [vrf NAME]",
5024 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5029 show_ssmpingd(vrf
->info
, vty
);
5033 static int pim_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
5034 const char *rp
, const char *group
,
5039 result
= pim_rp_new(pim
, rp
, group
, plist
);
5041 if (result
== PIM_MALLOC_FAIL
) {
5042 vty_out(vty
, "%% Out of memory\n");
5043 return CMD_WARNING_CONFIG_FAILED
;
5046 if (result
== PIM_GROUP_BAD_ADDRESS
) {
5047 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
5048 return CMD_WARNING_CONFIG_FAILED
;
5051 if (result
== PIM_RP_BAD_ADDRESS
) {
5052 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
5053 return CMD_WARNING_CONFIG_FAILED
;
5056 if (result
== PIM_RP_NO_PATH
) {
5057 vty_out(vty
, "%% No Path to RP address specified: %s\n", rp
);
5061 if (result
== PIM_GROUP_OVERLAP
) {
5062 vty_out(vty
, "%% Group range specified cannot exact match another\n");
5063 return CMD_WARNING_CONFIG_FAILED
;
5066 if (result
== PIM_GROUP_PFXLIST_OVERLAP
) {
5068 "%% This group is already covered by a RP prefix-list\n");
5069 return CMD_WARNING_CONFIG_FAILED
;
5072 if (result
== PIM_RP_PFXLIST_IN_USE
) {
5074 "%% The same prefix-list cannot be applied to multiple RPs\n");
5075 return CMD_WARNING_CONFIG_FAILED
;
5081 static int pim_cmd_spt_switchover(struct pim_instance
*pim
,
5082 enum pim_spt_switchover spt
,
5085 pim
->spt
.switchover
= spt
;
5087 switch (pim
->spt
.switchover
) {
5088 case PIM_SPT_IMMEDIATE
:
5090 XFREE(MTYPE_PIM_SPT_PLIST_NAME
, pim
->spt
.plist
);
5092 pim_upstream_add_lhr_star_pimreg(pim
);
5094 case PIM_SPT_INFINITY
:
5095 pim_upstream_remove_lhr_star_pimreg(pim
, plist
);
5098 XFREE(MTYPE_PIM_SPT_PLIST_NAME
, pim
->spt
.plist
);
5102 XSTRDUP(MTYPE_PIM_SPT_PLIST_NAME
, plist
);
5109 DEFUN (ip_pim_spt_switchover_infinity
,
5110 ip_pim_spt_switchover_infinity_cmd
,
5111 "ip pim spt-switchover infinity-and-beyond",
5115 "Never switch to SPT Tree\n")
5117 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5118 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, NULL
);
5121 DEFUN (ip_pim_spt_switchover_infinity_plist
,
5122 ip_pim_spt_switchover_infinity_plist_cmd
,
5123 "ip pim spt-switchover infinity-and-beyond prefix-list WORD",
5127 "Never switch to SPT Tree\n"
5128 "Prefix-List to control which groups to switch\n"
5129 "Prefix-List name\n")
5131 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5132 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, argv
[5]->arg
);
5135 DEFUN (no_ip_pim_spt_switchover_infinity
,
5136 no_ip_pim_spt_switchover_infinity_cmd
,
5137 "no ip pim spt-switchover infinity-and-beyond",
5142 "Never switch to SPT Tree\n")
5144 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5145 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
5148 DEFUN (no_ip_pim_spt_switchover_infinity_plist
,
5149 no_ip_pim_spt_switchover_infinity_plist_cmd
,
5150 "no ip pim spt-switchover infinity-and-beyond prefix-list WORD",
5155 "Never switch to SPT Tree\n"
5156 "Prefix-List to control which groups to switch\n"
5157 "Prefix-List name\n")
5159 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5160 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
5163 DEFUN (ip_pim_joinprune_time
,
5164 ip_pim_joinprune_time_cmd
,
5165 "ip pim join-prune-interval (60-600)",
5167 "pim multicast routing\n"
5168 "Join Prune Send Interval\n"
5171 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5172 qpim_t_periodic
= atoi(argv
[3]->arg
);
5176 DEFUN (no_ip_pim_joinprune_time
,
5177 no_ip_pim_joinprune_time_cmd
,
5178 "no ip pim join-prune-interval (60-600)",
5181 "pim multicast routing\n"
5182 "Join Prune Send Interval\n"
5185 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5186 qpim_t_periodic
= PIM_DEFAULT_T_PERIODIC
;
5190 DEFUN (ip_pim_register_suppress
,
5191 ip_pim_register_suppress_cmd
,
5192 "ip pim register-suppress-time (5-60000)",
5194 "pim multicast routing\n"
5195 "Register Suppress Timer\n"
5198 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5199 qpim_register_suppress_time
= atoi(argv
[3]->arg
);
5203 DEFUN (no_ip_pim_register_suppress
,
5204 no_ip_pim_register_suppress_cmd
,
5205 "no ip pim register-suppress-time (5-60000)",
5208 "pim multicast routing\n"
5209 "Register Suppress Timer\n"
5212 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5213 qpim_register_suppress_time
= PIM_REGISTER_SUPPRESSION_TIME_DEFAULT
;
5217 DEFUN (ip_pim_rp_keep_alive
,
5218 ip_pim_rp_keep_alive_cmd
,
5219 "ip pim rp keep-alive-timer (31-60000)",
5221 "pim multicast routing\n"
5223 "Keep alive Timer\n"
5226 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5227 pim
->rp_keep_alive_time
= atoi(argv
[4]->arg
);
5231 DEFUN (no_ip_pim_rp_keep_alive
,
5232 no_ip_pim_rp_keep_alive_cmd
,
5233 "no ip pim rp keep-alive-timer (31-60000)",
5236 "pim multicast routing\n"
5238 "Keep alive Timer\n"
5241 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5242 pim
->rp_keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
5246 DEFUN (ip_pim_keep_alive
,
5247 ip_pim_keep_alive_cmd
,
5248 "ip pim keep-alive-timer (31-60000)",
5250 "pim multicast routing\n"
5251 "Keep alive Timer\n"
5254 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5255 pim
->keep_alive_time
= atoi(argv
[3]->arg
);
5259 DEFUN (no_ip_pim_keep_alive
,
5260 no_ip_pim_keep_alive_cmd
,
5261 "no ip pim keep-alive-timer (31-60000)",
5264 "pim multicast routing\n"
5265 "Keep alive Timer\n"
5268 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5269 pim
->keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
5273 DEFUN (ip_pim_packets
,
5275 "ip pim packets (1-100)",
5277 "pim multicast routing\n"
5278 "packets to process at one time per fd\n"
5279 "Number of packets\n")
5281 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5282 qpim_packet_process
= atoi(argv
[3]->arg
);
5286 DEFUN (no_ip_pim_packets
,
5287 no_ip_pim_packets_cmd
,
5288 "no ip pim packets (1-100)",
5291 "pim multicast routing\n"
5292 "packets to process at one time per fd\n"
5293 "Number of packets\n")
5295 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5296 qpim_packet_process
= PIM_DEFAULT_PACKET_PROCESS
;
5300 DEFUN (ip_pim_v6_secondary
,
5301 ip_pim_v6_secondary_cmd
,
5302 "ip pim send-v6-secondary",
5304 "pim multicast routing\n"
5305 "Send v6 secondary addresses\n")
5307 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5308 pim
->send_v6_secondary
= 1;
5313 DEFUN (no_ip_pim_v6_secondary
,
5314 no_ip_pim_v6_secondary_cmd
,
5315 "no ip pim send-v6-secondary",
5318 "pim multicast routing\n"
5319 "Send v6 secondary addresses\n")
5321 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5322 pim
->send_v6_secondary
= 0;
5329 "ip pim rp A.B.C.D [A.B.C.D/M]",
5331 "pim multicast routing\n"
5333 "ip address of RP\n"
5334 "Group Address range to cover\n")
5336 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5339 if (argc
== (idx_ipv4
+ 1))
5340 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
5343 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
5344 argv
[idx_ipv4
+ 1]->arg
, NULL
);
5347 DEFUN (ip_pim_rp_prefix_list
,
5348 ip_pim_rp_prefix_list_cmd
,
5349 "ip pim rp A.B.C.D prefix-list WORD",
5351 "pim multicast routing\n"
5353 "ip address of RP\n"
5354 "group prefix-list filter\n"
5355 "Name of a prefix-list\n")
5357 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5358 return pim_rp_cmd_worker(pim
, vty
, argv
[3]->arg
, NULL
, argv
[5]->arg
);
5361 static int pim_no_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
5362 const char *rp
, const char *group
,
5365 int result
= pim_rp_del(pim
, rp
, group
, plist
);
5367 if (result
== PIM_GROUP_BAD_ADDRESS
) {
5368 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
5369 return CMD_WARNING_CONFIG_FAILED
;
5372 if (result
== PIM_RP_BAD_ADDRESS
) {
5373 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
5374 return CMD_WARNING_CONFIG_FAILED
;
5377 if (result
== PIM_RP_NOT_FOUND
) {
5378 vty_out(vty
, "%% Unable to find specified RP\n");
5379 return CMD_WARNING_CONFIG_FAILED
;
5385 DEFUN (no_ip_pim_rp
,
5387 "no ip pim rp A.B.C.D [A.B.C.D/M]",
5390 "pim multicast routing\n"
5392 "ip address of RP\n"
5393 "Group Address range to cover\n")
5395 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5396 int idx_ipv4
= 4, idx_group
= 0;
5398 if (argv_find(argv
, argc
, "A.B.C.D/M", &idx_group
))
5399 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
5400 argv
[idx_group
]->arg
, NULL
);
5402 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
5406 DEFUN (no_ip_pim_rp_prefix_list
,
5407 no_ip_pim_rp_prefix_list_cmd
,
5408 "no ip pim rp A.B.C.D prefix-list WORD",
5411 "pim multicast routing\n"
5413 "ip address of RP\n"
5414 "group prefix-list filter\n"
5415 "Name of a prefix-list\n")
5417 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5418 return pim_no_rp_cmd_worker(pim
, vty
, argv
[4]->arg
, NULL
, argv
[6]->arg
);
5421 static int pim_ssm_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
5424 int result
= pim_ssm_range_set(pim
, pim
->vrf_id
, plist
);
5426 if (result
== PIM_SSM_ERR_NONE
)
5430 case PIM_SSM_ERR_NO_VRF
:
5431 vty_out(vty
, "%% VRF doesn't exist\n");
5433 case PIM_SSM_ERR_DUP
:
5434 vty_out(vty
, "%% duplicate config\n");
5437 vty_out(vty
, "%% ssm range config failed\n");
5440 return CMD_WARNING_CONFIG_FAILED
;
5443 DEFUN (ip_pim_ssm_prefix_list
,
5444 ip_pim_ssm_prefix_list_cmd
,
5445 "ip pim ssm prefix-list WORD",
5447 "pim multicast routing\n"
5448 "Source Specific Multicast\n"
5449 "group range prefix-list filter\n"
5450 "Name of a prefix-list\n")
5452 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5453 return pim_ssm_cmd_worker(pim
, vty
, argv
[4]->arg
);
5456 DEFUN (no_ip_pim_ssm_prefix_list
,
5457 no_ip_pim_ssm_prefix_list_cmd
,
5458 "no ip pim ssm prefix-list",
5461 "pim multicast routing\n"
5462 "Source Specific Multicast\n"
5463 "group range prefix-list filter\n")
5465 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5466 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
5469 DEFUN (no_ip_pim_ssm_prefix_list_name
,
5470 no_ip_pim_ssm_prefix_list_name_cmd
,
5471 "no ip pim ssm prefix-list WORD",
5474 "pim multicast routing\n"
5475 "Source Specific Multicast\n"
5476 "group range prefix-list filter\n"
5477 "Name of a prefix-list\n")
5479 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5480 struct pim_ssm
*ssm
= pim
->ssm_info
;
5482 if (ssm
->plist_name
&& !strcmp(ssm
->plist_name
, argv
[5]->arg
))
5483 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
5485 vty_out(vty
, "%% pim ssm prefix-list %s doesn't exist\n", argv
[5]->arg
);
5487 return CMD_WARNING_CONFIG_FAILED
;
5490 static void ip_pim_ssm_show_group_range(struct pim_instance
*pim
,
5491 struct vty
*vty
, u_char uj
)
5493 struct pim_ssm
*ssm
= pim
->ssm_info
;
5494 const char *range_str
=
5495 ssm
->plist_name
? ssm
->plist_name
: PIM_SSM_STANDARD_RANGE
;
5499 json
= json_object_new_object();
5500 json_object_string_add(json
, "ssmGroups", range_str
);
5501 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5502 json
, JSON_C_TO_STRING_PRETTY
));
5503 json_object_free(json
);
5505 vty_out(vty
, "SSM group range : %s\n", range_str
);
5508 DEFUN (show_ip_pim_ssm_range
,
5509 show_ip_pim_ssm_range_cmd
,
5510 "show ip pim [vrf NAME] group-type [json]",
5519 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5520 u_char uj
= use_json(argc
, argv
);
5525 ip_pim_ssm_show_group_range(vrf
->info
, vty
, uj
);
5530 static void ip_pim_ssm_show_group_type(struct pim_instance
*pim
,
5531 struct vty
*vty
, u_char uj
,
5534 struct in_addr group_addr
;
5535 const char *type_str
;
5538 result
= inet_pton(AF_INET
, group
, &group_addr
);
5540 type_str
= "invalid";
5542 if (pim_is_group_224_4(group_addr
))
5544 pim_is_grp_ssm(pim
, group_addr
) ? "SSM" : "ASM";
5546 type_str
= "not-multicast";
5551 json
= json_object_new_object();
5552 json_object_string_add(json
, "groupType", type_str
);
5553 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5554 json
, JSON_C_TO_STRING_PRETTY
));
5555 json_object_free(json
);
5557 vty_out(vty
, "Group type : %s\n", type_str
);
5560 DEFUN (show_ip_pim_group_type
,
5561 show_ip_pim_group_type_cmd
,
5562 "show ip pim [vrf NAME] group-type A.B.C.D [json]",
5567 "multicast group type\n"
5572 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5573 u_char uj
= use_json(argc
, argv
);
5578 argv_find(argv
, argc
, "A.B.C.D", &idx
);
5579 ip_pim_ssm_show_group_type(vrf
->info
, vty
, uj
, argv
[idx
]->arg
);
5584 DEFUN_HIDDEN (ip_multicast_routing
,
5585 ip_multicast_routing_cmd
,
5586 "ip multicast-routing",
5588 "Enable IP multicast forwarding\n")
5593 DEFUN_HIDDEN (no_ip_multicast_routing
,
5594 no_ip_multicast_routing_cmd
,
5595 "no ip multicast-routing",
5598 "Enable IP multicast forwarding\n")
5601 "Command is Disabled and will be removed in a future version\n");
5607 "ip ssmpingd [A.B.C.D]",
5612 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5615 struct in_addr source_addr
;
5616 const char *source_str
= (argc
== 3) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
5618 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
5620 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
5621 source_str
, errno
, safe_strerror(errno
));
5622 return CMD_WARNING_CONFIG_FAILED
;
5625 result
= pim_ssmpingd_start(pim
, source_addr
);
5627 vty_out(vty
, "%% Failure starting ssmpingd for source %s: %d\n",
5628 source_str
, result
);
5629 return CMD_WARNING_CONFIG_FAILED
;
5635 DEFUN (no_ip_ssmpingd
,
5637 "no ip ssmpingd [A.B.C.D]",
5643 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5646 struct in_addr source_addr
;
5647 const char *source_str
= (argc
== 4) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
5649 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
5651 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
5652 source_str
, errno
, safe_strerror(errno
));
5653 return CMD_WARNING_CONFIG_FAILED
;
5656 result
= pim_ssmpingd_stop(pim
, source_addr
);
5658 vty_out(vty
, "%% Failure stopping ssmpingd for source %s: %d\n",
5659 source_str
, result
);
5660 return CMD_WARNING_CONFIG_FAILED
;
5670 "pim multicast routing\n"
5671 "Enable PIM ECMP \n")
5673 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5674 qpim_ecmp_enable
= 1;
5679 DEFUN (no_ip_pim_ecmp
,
5684 "pim multicast routing\n"
5685 "Disable PIM ECMP \n")
5687 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5688 qpim_ecmp_enable
= 0;
5693 DEFUN (ip_pim_ecmp_rebalance
,
5694 ip_pim_ecmp_rebalance_cmd
,
5695 "ip pim ecmp rebalance",
5697 "pim multicast routing\n"
5698 "Enable PIM ECMP \n"
5699 "Enable PIM ECMP Rebalance\n")
5701 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5702 qpim_ecmp_enable
= 1;
5703 qpim_ecmp_rebalance_enable
= 1;
5708 DEFUN (no_ip_pim_ecmp_rebalance
,
5709 no_ip_pim_ecmp_rebalance_cmd
,
5710 "no ip pim ecmp rebalance",
5713 "pim multicast routing\n"
5714 "Disable PIM ECMP \n"
5715 "Disable PIM ECMP Rebalance\n")
5717 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5718 qpim_ecmp_rebalance_enable
= 0;
5723 static int pim_cmd_igmp_start(struct vty
*vty
, struct interface
*ifp
)
5725 struct pim_interface
*pim_ifp
;
5726 uint8_t need_startup
= 0;
5728 pim_ifp
= ifp
->info
;
5731 pim_ifp
= pim_if_new(ifp
, 1 /* igmp=true */, 0 /* pim=false */);
5733 vty_out(vty
, "Could not enable IGMP on interface %s\n",
5735 return CMD_WARNING_CONFIG_FAILED
;
5739 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
5740 PIM_IF_DO_IGMP(pim_ifp
->options
);
5745 /* 'ip igmp' executed multiple times, with need_startup
5746 avoid multiple if add all and membership refresh */
5748 pim_if_addr_add_all(ifp
);
5749 pim_if_membership_refresh(ifp
);
5755 DEFUN (interface_ip_igmp
,
5756 interface_ip_igmp_cmd
,
5761 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5763 return pim_cmd_igmp_start(vty
, ifp
);
5766 DEFUN (interface_no_ip_igmp
,
5767 interface_no_ip_igmp_cmd
,
5773 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5774 struct pim_interface
*pim_ifp
= ifp
->info
;
5779 PIM_IF_DONT_IGMP(pim_ifp
->options
);
5781 pim_if_membership_clear(ifp
);
5783 pim_if_addr_del_all_igmp(ifp
);
5785 if (!PIM_IF_TEST_PIM(pim_ifp
->options
)) {
5792 DEFUN (interface_ip_igmp_join
,
5793 interface_ip_igmp_join_cmd
,
5794 "ip igmp join A.B.C.D A.B.C.D",
5797 "IGMP join multicast group\n"
5798 "Multicast group address\n"
5801 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5804 const char *group_str
;
5805 const char *source_str
;
5806 struct in_addr group_addr
;
5807 struct in_addr source_addr
;
5811 group_str
= argv
[idx_ipv4
]->arg
;
5812 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
5814 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
5815 errno
, safe_strerror(errno
));
5816 return CMD_WARNING_CONFIG_FAILED
;
5819 /* Source address */
5820 source_str
= argv
[idx_ipv4_2
]->arg
;
5821 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
5823 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
5824 source_str
, errno
, safe_strerror(errno
));
5825 return CMD_WARNING_CONFIG_FAILED
;
5828 CMD_FERR_RETURN(pim_if_igmp_join_add(ifp
, group_addr
, source_addr
),
5829 "Failure joining IGMP group: $ERR");
5834 DEFUN (interface_no_ip_igmp_join
,
5835 interface_no_ip_igmp_join_cmd
,
5836 "no ip igmp join A.B.C.D A.B.C.D",
5840 "IGMP join multicast group\n"
5841 "Multicast group address\n"
5844 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5847 const char *group_str
;
5848 const char *source_str
;
5849 struct in_addr group_addr
;
5850 struct in_addr source_addr
;
5854 group_str
= argv
[idx_ipv4
]->arg
;
5855 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
5857 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
5858 errno
, safe_strerror(errno
));
5859 return CMD_WARNING_CONFIG_FAILED
;
5862 /* Source address */
5863 source_str
= argv
[idx_ipv4_2
]->arg
;
5864 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
5866 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
5867 source_str
, errno
, safe_strerror(errno
));
5868 return CMD_WARNING_CONFIG_FAILED
;
5871 result
= pim_if_igmp_join_del(ifp
, group_addr
, source_addr
);
5874 "%% Failure leaving IGMP group %s source %s on interface %s: %d\n",
5875 group_str
, source_str
, ifp
->name
, result
);
5876 return CMD_WARNING_CONFIG_FAILED
;
5883 CLI reconfiguration affects the interface level (struct pim_interface).
5884 This function propagates the reconfiguration to every active socket
5887 static void igmp_sock_query_interval_reconfig(struct igmp_sock
*igmp
)
5889 struct interface
*ifp
;
5890 struct pim_interface
*pim_ifp
;
5894 /* other querier present? */
5896 if (igmp
->t_other_querier_timer
)
5899 /* this is the querier */
5901 zassert(igmp
->interface
);
5902 zassert(igmp
->interface
->info
);
5904 ifp
= igmp
->interface
;
5905 pim_ifp
= ifp
->info
;
5907 if (PIM_DEBUG_IGMP_TRACE
) {
5908 char ifaddr_str
[INET_ADDRSTRLEN
];
5909 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
5910 sizeof(ifaddr_str
));
5911 zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
5912 __PRETTY_FUNCTION__
, ifaddr_str
, ifp
->name
,
5913 pim_ifp
->igmp_default_query_interval
);
5917 igmp_startup_mode_on() will reset QQI:
5919 igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
5921 igmp_startup_mode_on(igmp
);
5924 static void igmp_sock_query_reschedule(struct igmp_sock
*igmp
)
5926 if (igmp
->t_igmp_query_timer
) {
5927 /* other querier present */
5928 zassert(igmp
->t_igmp_query_timer
);
5929 zassert(!igmp
->t_other_querier_timer
);
5931 pim_igmp_general_query_off(igmp
);
5932 pim_igmp_general_query_on(igmp
);
5934 zassert(igmp
->t_igmp_query_timer
);
5935 zassert(!igmp
->t_other_querier_timer
);
5937 /* this is the querier */
5939 zassert(!igmp
->t_igmp_query_timer
);
5940 zassert(igmp
->t_other_querier_timer
);
5942 pim_igmp_other_querier_timer_off(igmp
);
5943 pim_igmp_other_querier_timer_on(igmp
);
5945 zassert(!igmp
->t_igmp_query_timer
);
5946 zassert(igmp
->t_other_querier_timer
);
5950 static void change_query_interval(struct pim_interface
*pim_ifp
,
5953 struct listnode
*sock_node
;
5954 struct igmp_sock
*igmp
;
5956 pim_ifp
->igmp_default_query_interval
= query_interval
;
5958 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
5959 igmp_sock_query_interval_reconfig(igmp
);
5960 igmp_sock_query_reschedule(igmp
);
5964 static void change_query_max_response_time(struct pim_interface
*pim_ifp
,
5965 int query_max_response_time_dsec
)
5967 struct listnode
*sock_node
;
5968 struct igmp_sock
*igmp
;
5970 pim_ifp
->igmp_query_max_response_time_dsec
=
5971 query_max_response_time_dsec
;
5974 Below we modify socket/group/source timers in order to quickly
5975 reflect the change. Otherwise, those timers would eventually catch
5979 /* scan all sockets */
5980 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
5981 struct listnode
*grp_node
;
5982 struct igmp_group
*grp
;
5984 /* reschedule socket general query */
5985 igmp_sock_query_reschedule(igmp
);
5987 /* scan socket groups */
5988 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grp_node
,
5990 struct listnode
*src_node
;
5991 struct igmp_source
*src
;
5993 /* reset group timers for groups in EXCLUDE mode */
5994 if (grp
->group_filtermode_isexcl
) {
5995 igmp_group_reset_gmi(grp
);
5998 /* scan group sources */
5999 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
,
6002 /* reset source timers for sources with running
6004 if (src
->t_source_timer
) {
6005 igmp_source_reset_gmi(igmp
, grp
, src
);
6012 #define IGMP_QUERY_INTERVAL_MIN (1)
6013 #define IGMP_QUERY_INTERVAL_MAX (1800)
6015 DEFUN (interface_ip_igmp_query_interval
,
6016 interface_ip_igmp_query_interval_cmd
,
6017 "ip igmp query-interval (1-1800)",
6020 IFACE_IGMP_QUERY_INTERVAL_STR
6021 "Query interval in seconds\n")
6023 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6024 struct pim_interface
*pim_ifp
= ifp
->info
;
6026 int query_interval_dsec
;
6030 ret
= pim_cmd_igmp_start(vty
, ifp
);
6031 if (ret
!= CMD_SUCCESS
)
6033 pim_ifp
= ifp
->info
;
6036 query_interval
= atoi(argv
[3]->arg
);
6037 query_interval_dsec
= 10 * query_interval
;
6040 It seems we don't need to check bounds since command.c does it
6041 already, but we verify them anyway for extra safety.
6043 if (query_interval
< IGMP_QUERY_INTERVAL_MIN
) {
6045 "General query interval %d lower than minimum %d\n",
6046 query_interval
, IGMP_QUERY_INTERVAL_MIN
);
6047 return CMD_WARNING_CONFIG_FAILED
;
6049 if (query_interval
> IGMP_QUERY_INTERVAL_MAX
) {
6051 "General query interval %d higher than maximum %d\n",
6052 query_interval
, IGMP_QUERY_INTERVAL_MAX
);
6053 return CMD_WARNING_CONFIG_FAILED
;
6056 if (query_interval_dsec
<= pim_ifp
->igmp_query_max_response_time_dsec
) {
6058 "Can't set general query interval %d dsec <= query max response time %d dsec.\n",
6059 query_interval_dsec
,
6060 pim_ifp
->igmp_query_max_response_time_dsec
);
6061 return CMD_WARNING_CONFIG_FAILED
;
6064 change_query_interval(pim_ifp
, query_interval
);
6069 DEFUN (interface_no_ip_igmp_query_interval
,
6070 interface_no_ip_igmp_query_interval_cmd
,
6071 "no ip igmp query-interval",
6075 IFACE_IGMP_QUERY_INTERVAL_STR
)
6077 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6078 struct pim_interface
*pim_ifp
= ifp
->info
;
6079 int default_query_interval_dsec
;
6084 default_query_interval_dsec
= IGMP_GENERAL_QUERY_INTERVAL
* 10;
6086 if (default_query_interval_dsec
6087 <= pim_ifp
->igmp_query_max_response_time_dsec
) {
6089 "Can't set default general query interval %d dsec <= query max response time %d dsec.\n",
6090 default_query_interval_dsec
,
6091 pim_ifp
->igmp_query_max_response_time_dsec
);
6092 return CMD_WARNING_CONFIG_FAILED
;
6095 change_query_interval(pim_ifp
, IGMP_GENERAL_QUERY_INTERVAL
);
6100 DEFUN (interface_ip_igmp_version
,
6101 interface_ip_igmp_version_cmd
,
6102 "ip igmp version (2-3)",
6106 "IGMP version number\n")
6108 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6109 struct pim_interface
*pim_ifp
= ifp
->info
;
6110 int igmp_version
, old_version
= 0;
6114 ret
= pim_cmd_igmp_start(vty
, ifp
);
6115 if (ret
!= CMD_SUCCESS
)
6117 pim_ifp
= ifp
->info
;
6120 igmp_version
= atoi(argv
[3]->arg
);
6121 old_version
= pim_ifp
->igmp_version
;
6122 pim_ifp
->igmp_version
= igmp_version
;
6124 // Check if IGMP is Enabled otherwise, enable on interface
6125 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
6126 PIM_IF_DO_IGMP(pim_ifp
->options
);
6127 pim_if_addr_add_all(ifp
);
6128 pim_if_membership_refresh(ifp
);
6129 old_version
= igmp_version
; // avoid refreshing membership
6132 /* Current and new version is different refresh existing
6133 membership. Going from 3 -> 2 or 2 -> 3. */
6134 if (old_version
!= igmp_version
)
6135 pim_if_membership_refresh(ifp
);
6140 DEFUN (interface_no_ip_igmp_version
,
6141 interface_no_ip_igmp_version_cmd
,
6142 "no ip igmp version (2-3)",
6147 "IGMP version number\n")
6149 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6150 struct pim_interface
*pim_ifp
= ifp
->info
;
6155 pim_ifp
->igmp_version
= IGMP_DEFAULT_VERSION
;
6160 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
6161 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
6163 DEFUN (interface_ip_igmp_query_max_response_time
,
6164 interface_ip_igmp_query_max_response_time_cmd
,
6165 "ip igmp query-max-response-time (10-250)",
6168 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
6169 "Query response value in deci-seconds\n")
6171 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6172 struct pim_interface
*pim_ifp
= ifp
->info
;
6173 int query_max_response_time
;
6177 ret
= pim_cmd_igmp_start(vty
, ifp
);
6178 if (ret
!= CMD_SUCCESS
)
6180 pim_ifp
= ifp
->info
;
6183 query_max_response_time
= atoi(argv
[3]->arg
);
6185 if (query_max_response_time
6186 >= pim_ifp
->igmp_default_query_interval
* 10) {
6188 "Can't set query max response time %d sec >= general query interval %d sec\n",
6189 query_max_response_time
,
6190 pim_ifp
->igmp_default_query_interval
);
6191 return CMD_WARNING_CONFIG_FAILED
;
6194 change_query_max_response_time(pim_ifp
, query_max_response_time
);
6199 DEFUN (interface_no_ip_igmp_query_max_response_time
,
6200 interface_no_ip_igmp_query_max_response_time_cmd
,
6201 "no ip igmp query-max-response-time (10-250)",
6205 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
6206 "Time for response in deci-seconds\n")
6208 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6209 struct pim_interface
*pim_ifp
= ifp
->info
;
6214 change_query_max_response_time(pim_ifp
,
6215 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
6220 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
6221 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
6223 DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec
,
6224 interface_ip_igmp_query_max_response_time_dsec_cmd
,
6225 "ip igmp query-max-response-time-dsec (10-250)",
6228 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
6229 "Query response value in deciseconds\n")
6231 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6232 struct pim_interface
*pim_ifp
= ifp
->info
;
6233 int query_max_response_time_dsec
;
6234 int default_query_interval_dsec
;
6238 ret
= pim_cmd_igmp_start(vty
, ifp
);
6239 if (ret
!= CMD_SUCCESS
)
6241 pim_ifp
= ifp
->info
;
6244 query_max_response_time_dsec
= atoi(argv
[4]->arg
);
6246 default_query_interval_dsec
= 10 * pim_ifp
->igmp_default_query_interval
;
6248 if (query_max_response_time_dsec
>= default_query_interval_dsec
) {
6250 "Can't set query max response time %d dsec >= general query interval %d dsec\n",
6251 query_max_response_time_dsec
,
6252 default_query_interval_dsec
);
6253 return CMD_WARNING_CONFIG_FAILED
;
6256 change_query_max_response_time(pim_ifp
, query_max_response_time_dsec
);
6261 DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec
,
6262 interface_no_ip_igmp_query_max_response_time_dsec_cmd
,
6263 "no ip igmp query-max-response-time-dsec",
6267 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
)
6269 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6270 struct pim_interface
*pim_ifp
= ifp
->info
;
6275 change_query_max_response_time(pim_ifp
,
6276 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
6281 DEFUN (interface_ip_pim_drprio
,
6282 interface_ip_pim_drprio_cmd
,
6283 "ip pim drpriority (1-4294967295)",
6286 "Set the Designated Router Election Priority\n"
6287 "Value of the new DR Priority\n")
6289 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6291 struct pim_interface
*pim_ifp
= ifp
->info
;
6292 uint32_t old_dr_prio
;
6295 vty_out(vty
, "Please enable PIM on interface, first\n");
6296 return CMD_WARNING_CONFIG_FAILED
;
6299 old_dr_prio
= pim_ifp
->pim_dr_priority
;
6301 pim_ifp
->pim_dr_priority
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
6303 if (old_dr_prio
!= pim_ifp
->pim_dr_priority
) {
6304 if (pim_if_dr_election(ifp
))
6305 pim_hello_restart_now(ifp
);
6311 DEFUN (interface_no_ip_pim_drprio
,
6312 interface_no_ip_pim_drprio_cmd
,
6313 "no ip pim drpriority [(1-4294967295)]",
6317 "Revert the Designated Router Priority to default\n"
6318 "Old Value of the Priority\n")
6320 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6321 struct pim_interface
*pim_ifp
= ifp
->info
;
6324 vty_out(vty
, "Pim not enabled on this interface\n");
6325 return CMD_WARNING_CONFIG_FAILED
;
6328 if (pim_ifp
->pim_dr_priority
!= PIM_DEFAULT_DR_PRIORITY
) {
6329 pim_ifp
->pim_dr_priority
= PIM_DEFAULT_DR_PRIORITY
;
6330 if (pim_if_dr_election(ifp
))
6331 pim_hello_restart_now(ifp
);
6337 static int pim_cmd_interface_add(struct interface
*ifp
)
6339 struct pim_interface
*pim_ifp
= ifp
->info
;
6342 pim_ifp
= pim_if_new(ifp
, 0 /* igmp=false */, 1 /* pim=true */);
6347 PIM_IF_DO_PIM(pim_ifp
->options
);
6350 pim_if_addr_add_all(ifp
);
6351 pim_if_membership_refresh(ifp
);
6355 DEFUN_HIDDEN (interface_ip_pim_ssm
,
6356 interface_ip_pim_ssm_cmd
,
6362 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6364 if (!pim_cmd_interface_add(ifp
)) {
6365 vty_out(vty
, "Could not enable PIM SM on interface\n");
6366 return CMD_WARNING_CONFIG_FAILED
;
6370 "WARN: Enabled PIM SM on interface; configure PIM SSM "
6371 "range if needed\n");
6375 DEFUN (interface_ip_pim_sm
,
6376 interface_ip_pim_sm_cmd
,
6382 struct pim_interface
*pim_ifp
;
6384 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6385 if (!pim_cmd_interface_add(ifp
)) {
6386 vty_out(vty
, "Could not enable PIM SM on interface\n");
6387 return CMD_WARNING_CONFIG_FAILED
;
6390 pim_ifp
= ifp
->info
;
6392 pim_if_create_pimreg(pim_ifp
->pim
);
6397 static int pim_cmd_interface_delete(struct interface
*ifp
)
6399 struct pim_interface
*pim_ifp
= ifp
->info
;
6404 PIM_IF_DONT_PIM(pim_ifp
->options
);
6406 pim_if_membership_clear(ifp
);
6409 pim_sock_delete() removes all neighbors from
6410 pim_ifp->pim_neighbor_list.
6412 pim_sock_delete(ifp
, "pim unconfigured on interface");
6414 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
6415 pim_if_addr_del_all(ifp
);
6422 DEFUN_HIDDEN (interface_no_ip_pim_ssm
,
6423 interface_no_ip_pim_ssm_cmd
,
6430 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6431 if (!pim_cmd_interface_delete(ifp
)) {
6432 vty_out(vty
, "Unable to delete interface information\n");
6433 return CMD_WARNING_CONFIG_FAILED
;
6439 DEFUN (interface_no_ip_pim_sm
,
6440 interface_no_ip_pim_sm_cmd
,
6447 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6448 if (!pim_cmd_interface_delete(ifp
)) {
6449 vty_out(vty
, "Unable to delete interface information\n");
6450 return CMD_WARNING_CONFIG_FAILED
;
6457 DEFUN(interface_ip_pim_boundary_oil
,
6458 interface_ip_pim_boundary_oil_cmd
,
6459 "ip multicast boundary oil WORD",
6461 "Generic multicast configuration options\n"
6462 "Define multicast boundary\n"
6463 "Filter OIL by group using prefix list\n"
6464 "Prefix list to filter OIL with\n")
6466 VTY_DECLVAR_CONTEXT(interface
, iif
);
6467 struct pim_interface
*pim_ifp
;
6470 argv_find(argv
, argc
, "WORD", &idx
);
6472 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6474 if (pim_ifp
->boundary_oil_plist
)
6475 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
6477 pim_ifp
->boundary_oil_plist
=
6478 XSTRDUP(MTYPE_PIM_INTERFACE
, argv
[idx
]->arg
);
6480 /* Interface will be pruned from OIL on next Join */
6484 DEFUN(interface_no_ip_pim_boundary_oil
,
6485 interface_no_ip_pim_boundary_oil_cmd
,
6486 "no ip multicast boundary oil [WORD]",
6489 "Generic multicast configuration options\n"
6490 "Define multicast boundary\n"
6491 "Filter OIL by group using prefix list\n"
6492 "Prefix list to filter OIL with\n")
6494 VTY_DECLVAR_CONTEXT(interface
, iif
);
6495 struct pim_interface
*pim_ifp
;
6498 argv_find(argv
, argc
, "WORD", &idx
);
6500 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6502 if (pim_ifp
->boundary_oil_plist
)
6503 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
6508 DEFUN (interface_ip_mroute
,
6509 interface_ip_mroute_cmd
,
6510 "ip mroute INTERFACE A.B.C.D",
6512 "Add multicast route\n"
6513 "Outgoing interface name\n"
6516 VTY_DECLVAR_CONTEXT(interface
, iif
);
6517 struct pim_interface
*pim_ifp
;
6518 struct pim_instance
*pim
;
6519 int idx_interface
= 2;
6521 struct interface
*oif
;
6522 const char *oifname
;
6523 const char *grp_str
;
6524 struct in_addr grp_addr
;
6525 struct in_addr src_addr
;
6528 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6531 oifname
= argv
[idx_interface
]->arg
;
6532 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6534 vty_out(vty
, "No such interface name %s\n", oifname
);
6538 grp_str
= argv
[idx_ipv4
]->arg
;
6539 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6541 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6542 errno
, safe_strerror(errno
));
6546 src_addr
.s_addr
= INADDR_ANY
;
6548 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6549 vty_out(vty
, "Failed to add route\n");
6556 DEFUN (interface_ip_mroute_source
,
6557 interface_ip_mroute_source_cmd
,
6558 "ip mroute INTERFACE A.B.C.D A.B.C.D",
6560 "Add multicast route\n"
6561 "Outgoing interface name\n"
6565 VTY_DECLVAR_CONTEXT(interface
, iif
);
6566 struct pim_interface
*pim_ifp
;
6567 struct pim_instance
*pim
;
6568 int idx_interface
= 2;
6571 struct interface
*oif
;
6572 const char *oifname
;
6573 const char *grp_str
;
6574 struct in_addr grp_addr
;
6575 const char *src_str
;
6576 struct in_addr src_addr
;
6579 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6582 oifname
= argv
[idx_interface
]->arg
;
6583 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6585 vty_out(vty
, "No such interface name %s\n", oifname
);
6589 grp_str
= argv
[idx_ipv4
]->arg
;
6590 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6592 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6593 errno
, safe_strerror(errno
));
6597 src_str
= argv
[idx_ipv4_2
]->arg
;
6598 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
6600 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
6601 errno
, safe_strerror(errno
));
6605 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6606 vty_out(vty
, "Failed to add route\n");
6613 DEFUN (interface_no_ip_mroute
,
6614 interface_no_ip_mroute_cmd
,
6615 "no ip mroute INTERFACE A.B.C.D",
6618 "Add multicast route\n"
6619 "Outgoing interface name\n"
6622 VTY_DECLVAR_CONTEXT(interface
, iif
);
6623 struct pim_interface
*pim_ifp
;
6624 struct pim_instance
*pim
;
6625 int idx_interface
= 3;
6627 struct interface
*oif
;
6628 const char *oifname
;
6629 const char *grp_str
;
6630 struct in_addr grp_addr
;
6631 struct in_addr src_addr
;
6634 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6637 oifname
= argv
[idx_interface
]->arg
;
6638 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6640 vty_out(vty
, "No such interface name %s\n", oifname
);
6644 grp_str
= argv
[idx_ipv4
]->arg
;
6645 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6647 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6648 errno
, safe_strerror(errno
));
6652 src_addr
.s_addr
= INADDR_ANY
;
6654 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6655 vty_out(vty
, "Failed to remove route\n");
6662 DEFUN (interface_no_ip_mroute_source
,
6663 interface_no_ip_mroute_source_cmd
,
6664 "no ip mroute INTERFACE A.B.C.D A.B.C.D",
6667 "Add multicast route\n"
6668 "Outgoing interface name\n"
6672 VTY_DECLVAR_CONTEXT(interface
, iif
);
6673 struct pim_interface
*pim_ifp
;
6674 struct pim_instance
*pim
;
6675 int idx_interface
= 3;
6678 struct interface
*oif
;
6679 const char *oifname
;
6680 const char *grp_str
;
6681 struct in_addr grp_addr
;
6682 const char *src_str
;
6683 struct in_addr src_addr
;
6686 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6689 oifname
= argv
[idx_interface
]->arg
;
6690 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6692 vty_out(vty
, "No such interface name %s\n", oifname
);
6696 grp_str
= argv
[idx_ipv4
]->arg
;
6697 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6699 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6700 errno
, safe_strerror(errno
));
6704 src_str
= argv
[idx_ipv4_2
]->arg
;
6705 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
6707 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
6708 errno
, safe_strerror(errno
));
6712 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6713 vty_out(vty
, "Failed to remove route\n");
6720 DEFUN (interface_ip_pim_hello
,
6721 interface_ip_pim_hello_cmd
,
6722 "ip pim hello (1-180) [(1-180)]",
6726 IFACE_PIM_HELLO_TIME_STR
6727 IFACE_PIM_HELLO_HOLD_STR
)
6729 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6732 struct pim_interface
*pim_ifp
= ifp
->info
;
6735 if (!pim_cmd_interface_add(ifp
)) {
6736 vty_out(vty
, "Could not enable PIM SM on interface\n");
6737 return CMD_WARNING_CONFIG_FAILED
;
6741 pim_ifp
= ifp
->info
;
6742 pim_ifp
->pim_hello_period
= strtol(argv
[idx_time
]->arg
, NULL
, 10);
6744 if (argc
== idx_hold
+ 1)
6745 pim_ifp
->pim_default_holdtime
=
6746 strtol(argv
[idx_hold
]->arg
, NULL
, 10);
6751 DEFUN (interface_no_ip_pim_hello
,
6752 interface_no_ip_pim_hello_cmd
,
6753 "no ip pim hello [(1-180) (1-180)]",
6758 IFACE_PIM_HELLO_TIME_STR
6759 IFACE_PIM_HELLO_HOLD_STR
)
6761 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6762 struct pim_interface
*pim_ifp
= ifp
->info
;
6765 vty_out(vty
, "Pim not enabled on this interface\n");
6766 return CMD_WARNING_CONFIG_FAILED
;
6769 pim_ifp
->pim_hello_period
= PIM_DEFAULT_HELLO_PERIOD
;
6770 pim_ifp
->pim_default_holdtime
= -1;
6781 PIM_DO_DEBUG_IGMP_EVENTS
;
6782 PIM_DO_DEBUG_IGMP_PACKETS
;
6783 PIM_DO_DEBUG_IGMP_TRACE
;
6787 DEFUN (no_debug_igmp
,
6794 PIM_DONT_DEBUG_IGMP_EVENTS
;
6795 PIM_DONT_DEBUG_IGMP_PACKETS
;
6796 PIM_DONT_DEBUG_IGMP_TRACE
;
6801 DEFUN (debug_igmp_events
,
6802 debug_igmp_events_cmd
,
6803 "debug igmp events",
6806 DEBUG_IGMP_EVENTS_STR
)
6808 PIM_DO_DEBUG_IGMP_EVENTS
;
6812 DEFUN (no_debug_igmp_events
,
6813 no_debug_igmp_events_cmd
,
6814 "no debug igmp events",
6818 DEBUG_IGMP_EVENTS_STR
)
6820 PIM_DONT_DEBUG_IGMP_EVENTS
;
6825 DEFUN (debug_igmp_packets
,
6826 debug_igmp_packets_cmd
,
6827 "debug igmp packets",
6830 DEBUG_IGMP_PACKETS_STR
)
6832 PIM_DO_DEBUG_IGMP_PACKETS
;
6836 DEFUN (no_debug_igmp_packets
,
6837 no_debug_igmp_packets_cmd
,
6838 "no debug igmp packets",
6842 DEBUG_IGMP_PACKETS_STR
)
6844 PIM_DONT_DEBUG_IGMP_PACKETS
;
6849 DEFUN (debug_igmp_trace
,
6850 debug_igmp_trace_cmd
,
6854 DEBUG_IGMP_TRACE_STR
)
6856 PIM_DO_DEBUG_IGMP_TRACE
;
6860 DEFUN (no_debug_igmp_trace
,
6861 no_debug_igmp_trace_cmd
,
6862 "no debug igmp trace",
6866 DEBUG_IGMP_TRACE_STR
)
6868 PIM_DONT_DEBUG_IGMP_TRACE
;
6873 DEFUN (debug_mroute
,
6879 PIM_DO_DEBUG_MROUTE
;
6883 DEFUN (debug_mroute_detail
,
6884 debug_mroute_detail_cmd
,
6885 "debug mroute detail",
6890 PIM_DO_DEBUG_MROUTE_DETAIL
;
6894 DEFUN (no_debug_mroute
,
6895 no_debug_mroute_cmd
,
6901 PIM_DONT_DEBUG_MROUTE
;
6905 DEFUN (no_debug_mroute_detail
,
6906 no_debug_mroute_detail_cmd
,
6907 "no debug mroute detail",
6913 PIM_DONT_DEBUG_MROUTE_DETAIL
;
6917 DEFUN (debug_static
,
6923 PIM_DO_DEBUG_STATIC
;
6927 DEFUN (no_debug_static
,
6928 no_debug_static_cmd
,
6934 PIM_DONT_DEBUG_STATIC
;
6945 PIM_DO_DEBUG_PIM_EVENTS
;
6946 PIM_DO_DEBUG_PIM_PACKETS
;
6947 PIM_DO_DEBUG_PIM_TRACE
;
6948 PIM_DO_DEBUG_MSDP_EVENTS
;
6949 PIM_DO_DEBUG_MSDP_PACKETS
;
6953 DEFUN (no_debug_pim
,
6960 PIM_DONT_DEBUG_PIM_EVENTS
;
6961 PIM_DONT_DEBUG_PIM_PACKETS
;
6962 PIM_DONT_DEBUG_PIM_TRACE
;
6963 PIM_DONT_DEBUG_MSDP_EVENTS
;
6964 PIM_DONT_DEBUG_MSDP_PACKETS
;
6966 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
6967 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
6972 DEFUN (debug_pim_nht
,
6977 "Nexthop Tracking\n")
6979 PIM_DO_DEBUG_PIM_NHT
;
6983 DEFUN (no_debug_pim_nht
,
6984 no_debug_pim_nht_cmd
,
6989 "Nexthop Tracking\n")
6991 PIM_DONT_DEBUG_PIM_NHT
;
6995 DEFUN (debug_pim_nht_rp
,
6996 debug_pim_nht_rp_cmd
,
7000 "Nexthop Tracking\n"
7001 "RP Nexthop Tracking\n")
7003 PIM_DO_DEBUG_PIM_NHT_RP
;
7007 DEFUN (no_debug_pim_nht_rp
,
7008 no_debug_pim_nht_rp_cmd
,
7009 "no debug pim nht rp",
7013 "Nexthop Tracking\n"
7014 "RP Nexthop Tracking\n")
7016 PIM_DONT_DEBUG_PIM_NHT_RP
;
7020 DEFUN (debug_pim_events
,
7021 debug_pim_events_cmd
,
7025 DEBUG_PIM_EVENTS_STR
)
7027 PIM_DO_DEBUG_PIM_EVENTS
;
7031 DEFUN (no_debug_pim_events
,
7032 no_debug_pim_events_cmd
,
7033 "no debug pim events",
7037 DEBUG_PIM_EVENTS_STR
)
7039 PIM_DONT_DEBUG_PIM_EVENTS
;
7043 DEFUN (debug_pim_packets
,
7044 debug_pim_packets_cmd
,
7045 "debug pim packets [<hello|joins|register>]",
7048 DEBUG_PIM_PACKETS_STR
7049 DEBUG_PIM_HELLO_PACKETS_STR
7050 DEBUG_PIM_J_P_PACKETS_STR
7051 DEBUG_PIM_PIM_REG_PACKETS_STR
)
7054 if (argv_find(argv
, argc
, "hello", &idx
)) {
7055 PIM_DO_DEBUG_PIM_HELLO
;
7056 vty_out(vty
, "PIM Hello debugging is on\n");
7057 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
7058 PIM_DO_DEBUG_PIM_J_P
;
7059 vty_out(vty
, "PIM Join/Prune debugging is on\n");
7060 } else if (argv_find(argv
, argc
, "register", &idx
)) {
7061 PIM_DO_DEBUG_PIM_REG
;
7062 vty_out(vty
, "PIM Register debugging is on\n");
7064 PIM_DO_DEBUG_PIM_PACKETS
;
7065 vty_out(vty
, "PIM Packet debugging is on \n");
7070 DEFUN (no_debug_pim_packets
,
7071 no_debug_pim_packets_cmd
,
7072 "no debug pim packets [<hello|joins|register>]",
7076 DEBUG_PIM_PACKETS_STR
7077 DEBUG_PIM_HELLO_PACKETS_STR
7078 DEBUG_PIM_J_P_PACKETS_STR
7079 DEBUG_PIM_PIM_REG_PACKETS_STR
)
7082 if (argv_find(argv
, argc
, "hello", &idx
)) {
7083 PIM_DONT_DEBUG_PIM_HELLO
;
7084 vty_out(vty
, "PIM Hello debugging is off \n");
7085 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
7086 PIM_DONT_DEBUG_PIM_J_P
;
7087 vty_out(vty
, "PIM Join/Prune debugging is off \n");
7088 } else if (argv_find(argv
, argc
, "register", &idx
)) {
7089 PIM_DONT_DEBUG_PIM_REG
;
7090 vty_out(vty
, "PIM Register debugging is off\n");
7092 PIM_DONT_DEBUG_PIM_PACKETS
;
7098 DEFUN (debug_pim_packetdump_send
,
7099 debug_pim_packetdump_send_cmd
,
7100 "debug pim packet-dump send",
7103 DEBUG_PIM_PACKETDUMP_STR
7104 DEBUG_PIM_PACKETDUMP_SEND_STR
)
7106 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND
;
7110 DEFUN (no_debug_pim_packetdump_send
,
7111 no_debug_pim_packetdump_send_cmd
,
7112 "no debug pim packet-dump send",
7116 DEBUG_PIM_PACKETDUMP_STR
7117 DEBUG_PIM_PACKETDUMP_SEND_STR
)
7119 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
7123 DEFUN (debug_pim_packetdump_recv
,
7124 debug_pim_packetdump_recv_cmd
,
7125 "debug pim packet-dump receive",
7128 DEBUG_PIM_PACKETDUMP_STR
7129 DEBUG_PIM_PACKETDUMP_RECV_STR
)
7131 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV
;
7135 DEFUN (no_debug_pim_packetdump_recv
,
7136 no_debug_pim_packetdump_recv_cmd
,
7137 "no debug pim packet-dump receive",
7141 DEBUG_PIM_PACKETDUMP_STR
7142 DEBUG_PIM_PACKETDUMP_RECV_STR
)
7144 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
7148 DEFUN (debug_pim_trace
,
7149 debug_pim_trace_cmd
,
7153 DEBUG_PIM_TRACE_STR
)
7155 PIM_DO_DEBUG_PIM_TRACE
;
7159 DEFUN (debug_pim_trace_detail
,
7160 debug_pim_trace_detail_cmd
,
7161 "debug pim trace detail",
7165 "Detailed Information\n")
7167 PIM_DO_DEBUG_PIM_TRACE_DETAIL
;
7171 DEFUN (no_debug_pim_trace
,
7172 no_debug_pim_trace_cmd
,
7173 "no debug pim trace",
7177 DEBUG_PIM_TRACE_STR
)
7179 PIM_DONT_DEBUG_PIM_TRACE
;
7183 DEFUN (no_debug_pim_trace_detail
,
7184 no_debug_pim_trace_detail_cmd
,
7185 "no debug pim trace detail",
7190 "Detailed Information\n")
7192 PIM_DONT_DEBUG_PIM_TRACE_DETAIL
;
7196 DEFUN (debug_ssmpingd
,
7202 PIM_DO_DEBUG_SSMPINGD
;
7206 DEFUN (no_debug_ssmpingd
,
7207 no_debug_ssmpingd_cmd
,
7208 "no debug ssmpingd",
7213 PIM_DONT_DEBUG_SSMPINGD
;
7217 DEFUN (debug_pim_zebra
,
7218 debug_pim_zebra_cmd
,
7222 DEBUG_PIM_ZEBRA_STR
)
7228 DEFUN (no_debug_pim_zebra
,
7229 no_debug_pim_zebra_cmd
,
7230 "no debug pim zebra",
7234 DEBUG_PIM_ZEBRA_STR
)
7236 PIM_DONT_DEBUG_ZEBRA
;
7246 PIM_DO_DEBUG_MSDP_EVENTS
;
7247 PIM_DO_DEBUG_MSDP_PACKETS
;
7251 DEFUN (no_debug_msdp
,
7258 PIM_DONT_DEBUG_MSDP_EVENTS
;
7259 PIM_DONT_DEBUG_MSDP_PACKETS
;
7263 ALIAS(no_debug_msdp
, undebug_msdp_cmd
, "undebug msdp",
7264 UNDEBUG_STR DEBUG_MSDP_STR
)
7266 DEFUN (debug_msdp_events
,
7267 debug_msdp_events_cmd
,
7268 "debug msdp events",
7271 DEBUG_MSDP_EVENTS_STR
)
7273 PIM_DO_DEBUG_MSDP_EVENTS
;
7277 DEFUN (no_debug_msdp_events
,
7278 no_debug_msdp_events_cmd
,
7279 "no debug msdp events",
7283 DEBUG_MSDP_EVENTS_STR
)
7285 PIM_DONT_DEBUG_MSDP_EVENTS
;
7289 ALIAS(no_debug_msdp_events
, undebug_msdp_events_cmd
, "undebug msdp events",
7290 UNDEBUG_STR DEBUG_MSDP_STR DEBUG_MSDP_EVENTS_STR
)
7292 DEFUN (debug_msdp_packets
,
7293 debug_msdp_packets_cmd
,
7294 "debug msdp packets",
7297 DEBUG_MSDP_PACKETS_STR
)
7299 PIM_DO_DEBUG_MSDP_PACKETS
;
7303 DEFUN (no_debug_msdp_packets
,
7304 no_debug_msdp_packets_cmd
,
7305 "no debug msdp packets",
7309 DEBUG_MSDP_PACKETS_STR
)
7311 PIM_DONT_DEBUG_MSDP_PACKETS
;
7315 ALIAS(no_debug_msdp_packets
, undebug_msdp_packets_cmd
, "undebug msdp packets",
7316 UNDEBUG_STR DEBUG_MSDP_STR DEBUG_MSDP_PACKETS_STR
)
7318 DEFUN_NOSH (show_debugging_pim
,
7319 show_debugging_pim_cmd
,
7320 "show debugging [pim]",
7325 vty_out(vty
, "PIM debugging status\n");
7327 pim_debug_config_write(vty
);
7332 static int interface_pim_use_src_cmd_worker(struct vty
*vty
, const char *source
)
7335 struct in_addr source_addr
;
7336 int ret
= CMD_SUCCESS
;
7337 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7339 result
= inet_pton(AF_INET
, source
, &source_addr
);
7341 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", source
,
7342 errno
, safe_strerror(errno
));
7343 return CMD_WARNING_CONFIG_FAILED
;
7346 result
= pim_update_source_set(ifp
, source_addr
);
7350 case PIM_IFACE_NOT_FOUND
:
7351 ret
= CMD_WARNING_CONFIG_FAILED
;
7352 vty_out(vty
, "Pim not enabled on this interface\n");
7354 case PIM_UPDATE_SOURCE_DUP
:
7356 vty_out(vty
, "%% Source already set to %s\n", source
);
7359 ret
= CMD_WARNING_CONFIG_FAILED
;
7360 vty_out(vty
, "%% Source set failed\n");
7366 DEFUN (interface_pim_use_source
,
7367 interface_pim_use_source_cmd
,
7368 "ip pim use-source A.B.C.D",
7370 "pim multicast routing\n"
7371 "Configure primary IP address\n"
7372 "source ip address\n")
7374 return interface_pim_use_src_cmd_worker(vty
, argv
[3]->arg
);
7377 DEFUN (interface_no_pim_use_source
,
7378 interface_no_pim_use_source_cmd
,
7379 "no ip pim use-source [A.B.C.D]",
7382 "pim multicast routing\n"
7383 "Delete source IP address\n"
7384 "source ip address\n")
7386 return interface_pim_use_src_cmd_worker(vty
, "0.0.0.0");
7394 "Enables BFD support\n")
7396 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7397 struct pim_interface
*pim_ifp
= ifp
->info
;
7398 struct bfd_info
*bfd_info
= NULL
;
7401 if (!pim_cmd_interface_add(ifp
)) {
7402 vty_out(vty
, "Could not enable PIM SM on interface\n");
7406 pim_ifp
= ifp
->info
;
7408 bfd_info
= pim_ifp
->bfd_info
;
7410 if (!bfd_info
|| !CHECK_FLAG(bfd_info
->flags
, BFD_FLAG_PARAM_CFG
))
7411 pim_bfd_if_param_set(ifp
, BFD_DEF_MIN_RX
, BFD_DEF_MIN_TX
,
7412 BFD_DEF_DETECT_MULT
, 1);
7417 DEFUN (no_ip_pim_bfd
,
7423 "Disables BFD support\n")
7425 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7426 struct pim_interface
*pim_ifp
= ifp
->info
;
7429 vty_out(vty
, "Pim not enabled on this interface\n");
7433 if (pim_ifp
->bfd_info
) {
7434 pim_bfd_reg_dereg_all_nbr(ifp
, ZEBRA_BFD_DEST_DEREGISTER
);
7435 bfd_info_free(&(pim_ifp
->bfd_info
));
7441 DEFUN (ip_pim_bfd_param
,
7442 ip_pim_bfd_param_cmd
,
7443 "ip pim bfd (2-255) (50-60000) (50-60000)",
7446 "Enables BFD support\n"
7447 "Detect Multiplier\n"
7448 "Required min receive interval\n"
7449 "Desired min transmit interval\n")
7451 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7453 int idx_number_2
= 4;
7454 int idx_number_3
= 5;
7459 struct pim_interface
*pim_ifp
= ifp
->info
;
7462 if (!pim_cmd_interface_add(ifp
)) {
7463 vty_out(vty
, "Could not enable PIM SM on interface\n");
7468 if ((ret
= bfd_validate_param(
7469 vty
, argv
[idx_number
]->arg
, argv
[idx_number_2
]->arg
,
7470 argv
[idx_number_3
]->arg
, &dm_val
, &rx_val
, &tx_val
))
7474 pim_bfd_if_param_set(ifp
, rx_val
, tx_val
, dm_val
, 0);
7479 ALIAS(no_ip_pim_bfd
, no_ip_pim_bfd_param_cmd
,
7480 "no ip pim bfd (2-255) (50-60000) (50-60000)", NO_STR IP_STR PIM_STR
7481 "Enables BFD support\n"
7482 "Detect Multiplier\n"
7483 "Required min receive interval\n"
7484 "Desired min transmit interval\n")
7486 static int ip_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
7487 const char *peer
, const char *local
)
7489 enum pim_msdp_err result
;
7490 struct in_addr peer_addr
;
7491 struct in_addr local_addr
;
7492 int ret
= CMD_SUCCESS
;
7494 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
7496 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
7497 errno
, safe_strerror(errno
));
7498 return CMD_WARNING_CONFIG_FAILED
;
7501 result
= inet_pton(AF_INET
, local
, &local_addr
);
7503 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", local
,
7504 errno
, safe_strerror(errno
));
7505 return CMD_WARNING_CONFIG_FAILED
;
7508 result
= pim_msdp_peer_add(pim
, peer_addr
, local_addr
, "default",
7511 case PIM_MSDP_ERR_NONE
:
7513 case PIM_MSDP_ERR_OOM
:
7514 ret
= CMD_WARNING_CONFIG_FAILED
;
7515 vty_out(vty
, "%% Out of memory\n");
7517 case PIM_MSDP_ERR_PEER_EXISTS
:
7519 vty_out(vty
, "%% Peer exists\n");
7521 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
7522 ret
= CMD_WARNING_CONFIG_FAILED
;
7523 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
7526 ret
= CMD_WARNING_CONFIG_FAILED
;
7527 vty_out(vty
, "%% peer add failed\n");
7533 DEFUN_HIDDEN (ip_msdp_peer
,
7535 "ip msdp peer A.B.C.D source A.B.C.D",
7538 "Configure MSDP peer\n"
7540 "Source address for TCP connection\n"
7541 "local ip address\n")
7543 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7544 return ip_msdp_peer_cmd_worker(pim
, vty
, argv
[3]->arg
, argv
[5]->arg
);
7547 static int ip_no_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
7550 enum pim_msdp_err result
;
7551 struct in_addr peer_addr
;
7553 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
7555 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
7556 errno
, safe_strerror(errno
));
7557 return CMD_WARNING_CONFIG_FAILED
;
7560 result
= pim_msdp_peer_del(pim
, peer_addr
);
7562 case PIM_MSDP_ERR_NONE
:
7564 case PIM_MSDP_ERR_NO_PEER
:
7565 vty_out(vty
, "%% Peer does not exist\n");
7568 vty_out(vty
, "%% peer del failed\n");
7571 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7574 DEFUN_HIDDEN (no_ip_msdp_peer
,
7575 no_ip_msdp_peer_cmd
,
7576 "no ip msdp peer A.B.C.D",
7580 "Delete MSDP peer\n"
7581 "peer ip address\n")
7583 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7584 return ip_no_msdp_peer_cmd_worker(pim
, vty
, argv
[4]->arg
);
7587 static int ip_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
7588 struct vty
*vty
, const char *mg
,
7591 enum pim_msdp_err result
;
7592 struct in_addr mbr_ip
;
7593 int ret
= CMD_SUCCESS
;
7595 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
7597 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
7598 errno
, safe_strerror(errno
));
7599 return CMD_WARNING_CONFIG_FAILED
;
7602 result
= pim_msdp_mg_mbr_add(pim
, mg
, mbr_ip
);
7604 case PIM_MSDP_ERR_NONE
:
7606 case PIM_MSDP_ERR_OOM
:
7607 ret
= CMD_WARNING_CONFIG_FAILED
;
7608 vty_out(vty
, "%% Out of memory\n");
7610 case PIM_MSDP_ERR_MG_MBR_EXISTS
:
7612 vty_out(vty
, "%% mesh-group member exists\n");
7614 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
7615 ret
= CMD_WARNING_CONFIG_FAILED
;
7616 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
7619 ret
= CMD_WARNING_CONFIG_FAILED
;
7620 vty_out(vty
, "%% member add failed\n");
7626 DEFUN (ip_msdp_mesh_group_member
,
7627 ip_msdp_mesh_group_member_cmd
,
7628 "ip msdp mesh-group WORD member A.B.C.D",
7631 "Configure MSDP mesh-group\n"
7633 "mesh group member\n"
7634 "peer ip address\n")
7636 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7637 return ip_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[3]->arg
,
7641 static int ip_no_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
7646 enum pim_msdp_err result
;
7647 struct in_addr mbr_ip
;
7649 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
7651 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
7652 errno
, safe_strerror(errno
));
7653 return CMD_WARNING_CONFIG_FAILED
;
7656 result
= pim_msdp_mg_mbr_del(pim
, mg
, mbr_ip
);
7658 case PIM_MSDP_ERR_NONE
:
7660 case PIM_MSDP_ERR_NO_MG
:
7661 vty_out(vty
, "%% mesh-group does not exist\n");
7663 case PIM_MSDP_ERR_NO_MG_MBR
:
7664 vty_out(vty
, "%% mesh-group member does not exist\n");
7667 vty_out(vty
, "%% mesh-group member del failed\n");
7670 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7672 DEFUN (no_ip_msdp_mesh_group_member
,
7673 no_ip_msdp_mesh_group_member_cmd
,
7674 "no ip msdp mesh-group WORD member A.B.C.D",
7678 "Delete MSDP mesh-group member\n"
7680 "mesh group member\n"
7681 "peer ip address\n")
7683 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7684 return ip_no_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[4]->arg
,
7688 static int ip_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
7689 struct vty
*vty
, const char *mg
,
7692 enum pim_msdp_err result
;
7693 struct in_addr src_ip
;
7695 result
= inet_pton(AF_INET
, src
, &src_ip
);
7697 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", src
,
7698 errno
, safe_strerror(errno
));
7699 return CMD_WARNING_CONFIG_FAILED
;
7702 result
= pim_msdp_mg_src_add(pim
, mg
, src_ip
);
7704 case PIM_MSDP_ERR_NONE
:
7706 case PIM_MSDP_ERR_OOM
:
7707 vty_out(vty
, "%% Out of memory\n");
7709 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
7710 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
7713 vty_out(vty
, "%% source add failed\n");
7716 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7720 DEFUN (ip_msdp_mesh_group_source
,
7721 ip_msdp_mesh_group_source_cmd
,
7722 "ip msdp mesh-group WORD source A.B.C.D",
7725 "Configure MSDP mesh-group\n"
7727 "mesh group local address\n"
7728 "source ip address for the TCP connection\n")
7730 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7731 return ip_msdp_mesh_group_source_cmd_worker(pim
, vty
, argv
[3]->arg
,
7735 static int ip_no_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
7739 enum pim_msdp_err result
;
7741 result
= pim_msdp_mg_src_del(pim
, mg
);
7743 case PIM_MSDP_ERR_NONE
:
7745 case PIM_MSDP_ERR_NO_MG
:
7746 vty_out(vty
, "%% mesh-group does not exist\n");
7749 vty_out(vty
, "%% mesh-group source del failed\n");
7752 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7755 static int ip_no_msdp_mesh_group_cmd_worker(struct pim_instance
*pim
,
7756 struct vty
*vty
, const char *mg
)
7758 enum pim_msdp_err result
;
7760 result
= pim_msdp_mg_del(pim
, mg
);
7762 case PIM_MSDP_ERR_NONE
:
7764 case PIM_MSDP_ERR_NO_MG
:
7765 vty_out(vty
, "%% mesh-group does not exist\n");
7768 vty_out(vty
, "%% mesh-group source del failed\n");
7771 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7774 DEFUN (no_ip_msdp_mesh_group_source
,
7775 no_ip_msdp_mesh_group_source_cmd
,
7776 "no ip msdp mesh-group WORD source [A.B.C.D]",
7780 "Delete MSDP mesh-group source\n"
7782 "mesh group source\n"
7783 "mesh group local address\n")
7785 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7787 return ip_no_msdp_mesh_group_cmd_worker(pim
, vty
, argv
[6]->arg
);
7789 return ip_no_msdp_mesh_group_source_cmd_worker(pim
, vty
,
7793 static void print_empty_json_obj(struct vty
*vty
)
7796 json
= json_object_new_object();
7797 vty_out(vty
, "%s\n",
7798 json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
));
7799 json_object_free(json
);
7802 static void ip_msdp_show_mesh_group(struct pim_instance
*pim
, struct vty
*vty
,
7805 struct listnode
*mbrnode
;
7806 struct pim_msdp_mg_mbr
*mbr
;
7807 struct pim_msdp_mg
*mg
= pim
->msdp
.mg
;
7808 char mbr_str
[INET_ADDRSTRLEN
];
7809 char src_str
[INET_ADDRSTRLEN
];
7810 char state_str
[PIM_MSDP_STATE_STRLEN
];
7811 enum pim_msdp_peer_state state
;
7812 json_object
*json
= NULL
;
7813 json_object
*json_mg_row
= NULL
;
7814 json_object
*json_members
= NULL
;
7815 json_object
*json_row
= NULL
;
7819 print_empty_json_obj(vty
);
7823 pim_inet4_dump("<source?>", mg
->src_ip
, src_str
, sizeof(src_str
));
7825 json
= json_object_new_object();
7826 /* currently there is only one mesh group but we should still
7828 * it a dict with mg-name as key */
7829 json_mg_row
= json_object_new_object();
7830 json_object_string_add(json_mg_row
, "name",
7831 mg
->mesh_group_name
);
7832 json_object_string_add(json_mg_row
, "source", src_str
);
7834 vty_out(vty
, "Mesh group : %s\n", mg
->mesh_group_name
);
7835 vty_out(vty
, " Source : %s\n", src_str
);
7836 vty_out(vty
, " Member State\n");
7839 for (ALL_LIST_ELEMENTS_RO(mg
->mbr_list
, mbrnode
, mbr
)) {
7840 pim_inet4_dump("<mbr?>", mbr
->mbr_ip
, mbr_str
, sizeof(mbr_str
));
7842 state
= mbr
->mp
->state
;
7844 state
= PIM_MSDP_DISABLED
;
7846 pim_msdp_state_dump(state
, state_str
, sizeof(state_str
));
7848 json_row
= json_object_new_object();
7849 json_object_string_add(json_row
, "member", mbr_str
);
7850 json_object_string_add(json_row
, "state", state_str
);
7851 if (!json_members
) {
7852 json_members
= json_object_new_object();
7853 json_object_object_add(json_mg_row
, "members",
7856 json_object_object_add(json_members
, mbr_str
, json_row
);
7858 vty_out(vty
, " %-15s %11s\n", mbr_str
, state_str
);
7863 json_object_object_add(json
, mg
->mesh_group_name
, json_mg_row
);
7864 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
7865 json
, JSON_C_TO_STRING_PRETTY
));
7866 json_object_free(json
);
7870 DEFUN (show_ip_msdp_mesh_group
,
7871 show_ip_msdp_mesh_group_cmd
,
7872 "show ip msdp [vrf NAME] mesh-group [json]",
7877 "MSDP mesh-group information\n"
7880 u_char uj
= use_json(argc
, argv
);
7882 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
7887 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
7892 DEFUN (show_ip_msdp_mesh_group_vrf_all
,
7893 show_ip_msdp_mesh_group_vrf_all_cmd
,
7894 "show ip msdp vrf all mesh-group [json]",
7899 "MSDP mesh-group information\n"
7902 u_char uj
= use_json(argc
, argv
);
7908 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
7912 vty_out(vty
, " \"%s\": ", vrf
->name
);
7915 vty_out(vty
, "VRF: %s\n", vrf
->name
);
7916 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
7919 vty_out(vty
, "}\n");
7924 static void ip_msdp_show_peers(struct pim_instance
*pim
, struct vty
*vty
,
7927 struct listnode
*mpnode
;
7928 struct pim_msdp_peer
*mp
;
7929 char peer_str
[INET_ADDRSTRLEN
];
7930 char local_str
[INET_ADDRSTRLEN
];
7931 char state_str
[PIM_MSDP_STATE_STRLEN
];
7932 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
7934 json_object
*json
= NULL
;
7935 json_object
*json_row
= NULL
;
7939 json
= json_object_new_object();
7942 "Peer Local State Uptime SaCnt\n");
7945 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
7946 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
7947 now
= pim_time_monotonic_sec();
7948 pim_time_uptime(timebuf
, sizeof(timebuf
),
7951 strcpy(timebuf
, "-");
7953 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
7954 pim_inet4_dump("<local?>", mp
->local
, local_str
,
7956 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
7958 json_row
= json_object_new_object();
7959 json_object_string_add(json_row
, "peer", peer_str
);
7960 json_object_string_add(json_row
, "local", local_str
);
7961 json_object_string_add(json_row
, "state", state_str
);
7962 json_object_string_add(json_row
, "upTime", timebuf
);
7963 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
7964 json_object_object_add(json
, peer_str
, json_row
);
7966 vty_out(vty
, "%-15s %15s %11s %8s %6d\n", peer_str
,
7967 local_str
, state_str
, timebuf
, mp
->sa_cnt
);
7972 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
7973 json
, JSON_C_TO_STRING_PRETTY
));
7974 json_object_free(json
);
7978 static void ip_msdp_show_peers_detail(struct pim_instance
*pim
, struct vty
*vty
,
7979 const char *peer
, u_char uj
)
7981 struct listnode
*mpnode
;
7982 struct pim_msdp_peer
*mp
;
7983 char peer_str
[INET_ADDRSTRLEN
];
7984 char local_str
[INET_ADDRSTRLEN
];
7985 char state_str
[PIM_MSDP_STATE_STRLEN
];
7986 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
7987 char katimer
[PIM_MSDP_TIMER_STRLEN
];
7988 char crtimer
[PIM_MSDP_TIMER_STRLEN
];
7989 char holdtimer
[PIM_MSDP_TIMER_STRLEN
];
7991 json_object
*json
= NULL
;
7992 json_object
*json_row
= NULL
;
7995 json
= json_object_new_object();
7998 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
7999 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
8000 if (strcmp(peer
, "detail") && strcmp(peer
, peer_str
))
8003 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
8004 now
= pim_time_monotonic_sec();
8005 pim_time_uptime(timebuf
, sizeof(timebuf
),
8008 strcpy(timebuf
, "-");
8010 pim_inet4_dump("<local?>", mp
->local
, local_str
,
8012 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
8013 pim_time_timer_to_hhmmss(katimer
, sizeof(katimer
),
8015 pim_time_timer_to_hhmmss(crtimer
, sizeof(crtimer
),
8017 pim_time_timer_to_hhmmss(holdtimer
, sizeof(holdtimer
),
8021 json_row
= json_object_new_object();
8022 json_object_string_add(json_row
, "peer", peer_str
);
8023 json_object_string_add(json_row
, "local", local_str
);
8024 json_object_string_add(json_row
, "meshGroupName",
8025 mp
->mesh_group_name
);
8026 json_object_string_add(json_row
, "state", state_str
);
8027 json_object_string_add(json_row
, "upTime", timebuf
);
8028 json_object_string_add(json_row
, "keepAliveTimer",
8030 json_object_string_add(json_row
, "connRetryTimer",
8032 json_object_string_add(json_row
, "holdTimer",
8034 json_object_string_add(json_row
, "lastReset",
8036 json_object_int_add(json_row
, "connAttempts",
8038 json_object_int_add(json_row
, "establishedChanges",
8040 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
8041 json_object_int_add(json_row
, "kaSent", mp
->ka_tx_cnt
);
8042 json_object_int_add(json_row
, "kaRcvd", mp
->ka_rx_cnt
);
8043 json_object_int_add(json_row
, "saSent", mp
->sa_tx_cnt
);
8044 json_object_int_add(json_row
, "saRcvd", mp
->sa_rx_cnt
);
8045 json_object_object_add(json
, peer_str
, json_row
);
8047 vty_out(vty
, "Peer : %s\n", peer_str
);
8048 vty_out(vty
, " Local : %s\n", local_str
);
8049 vty_out(vty
, " Mesh Group : %s\n",
8050 mp
->mesh_group_name
);
8051 vty_out(vty
, " State : %s\n", state_str
);
8052 vty_out(vty
, " Uptime : %s\n", timebuf
);
8054 vty_out(vty
, " Keepalive Timer : %s\n", katimer
);
8055 vty_out(vty
, " Conn Retry Timer : %s\n", crtimer
);
8056 vty_out(vty
, " Hold Timer : %s\n", holdtimer
);
8057 vty_out(vty
, " Last Reset : %s\n",
8059 vty_out(vty
, " Conn Attempts : %d\n",
8061 vty_out(vty
, " Established Changes : %d\n",
8063 vty_out(vty
, " SA Count : %d\n",
8065 vty_out(vty
, " Statistics :\n");
8068 vty_out(vty
, " Keepalives : %10d %10d\n",
8069 mp
->ka_tx_cnt
, mp
->ka_rx_cnt
);
8070 vty_out(vty
, " SAs : %10d %10d\n",
8071 mp
->sa_tx_cnt
, mp
->sa_rx_cnt
);
8077 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8078 json
, JSON_C_TO_STRING_PRETTY
));
8079 json_object_free(json
);
8083 DEFUN (show_ip_msdp_peer_detail
,
8084 show_ip_msdp_peer_detail_cmd
,
8085 "show ip msdp [vrf NAME] peer [detail|A.B.C.D] [json]",
8090 "MSDP peer information\n"
8095 u_char uj
= use_json(argc
, argv
);
8097 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
8104 if (argv_find(argv
, argc
, "detail", &idx
))
8105 arg
= argv
[idx
]->text
;
8106 else if (argv_find(argv
, argc
, "A.B.C.D", &idx
))
8107 arg
= argv
[idx
]->arg
;
8110 ip_msdp_show_peers_detail(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
8112 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
8117 DEFUN (show_ip_msdp_peer_detail_vrf_all
,
8118 show_ip_msdp_peer_detail_vrf_all_cmd
,
8119 "show ip msdp vrf all peer [detail|A.B.C.D] [json]",
8124 "MSDP peer information\n"
8130 u_char uj
= use_json(argc
, argv
);
8136 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
8140 vty_out(vty
, " \"%s\": ", vrf
->name
);
8143 vty_out(vty
, "VRF: %s\n", vrf
->name
);
8144 if (argv_find(argv
, argc
, "detail", &idx
)
8145 || argv_find(argv
, argc
, "A.B.C.D", &idx
))
8146 ip_msdp_show_peers_detail(vrf
->info
, vty
,
8147 argv
[idx
]->arg
, uj
);
8149 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
8152 vty_out(vty
, "}\n");
8157 static void ip_msdp_show_sa(struct pim_instance
*pim
, struct vty
*vty
,
8160 struct listnode
*sanode
;
8161 struct pim_msdp_sa
*sa
;
8162 char src_str
[INET_ADDRSTRLEN
];
8163 char grp_str
[INET_ADDRSTRLEN
];
8164 char rp_str
[INET_ADDRSTRLEN
];
8165 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
8169 json_object
*json
= NULL
;
8170 json_object
*json_group
= NULL
;
8171 json_object
*json_row
= NULL
;
8174 json
= json_object_new_object();
8177 "Source Group RP Local SPT Uptime\n");
8180 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
8181 now
= pim_time_monotonic_sec();
8182 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
8183 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
8184 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
8185 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
8186 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
8188 strcpy(spt_str
, "yes");
8190 strcpy(spt_str
, "no");
8193 strcpy(rp_str
, "-");
8194 strcpy(spt_str
, "-");
8196 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
8197 strcpy(local_str
, "yes");
8199 strcpy(local_str
, "no");
8202 json_object_object_get_ex(json
, grp_str
, &json_group
);
8205 json_group
= json_object_new_object();
8206 json_object_object_add(json
, grp_str
,
8210 json_row
= json_object_new_object();
8211 json_object_string_add(json_row
, "source", src_str
);
8212 json_object_string_add(json_row
, "group", grp_str
);
8213 json_object_string_add(json_row
, "rp", rp_str
);
8214 json_object_string_add(json_row
, "local", local_str
);
8215 json_object_string_add(json_row
, "sptSetup", spt_str
);
8216 json_object_string_add(json_row
, "upTime", timebuf
);
8217 json_object_object_add(json_group
, src_str
, json_row
);
8219 vty_out(vty
, "%-15s %15s %15s %5c %3c %8s\n",
8220 src_str
, grp_str
, rp_str
, local_str
[0],
8221 spt_str
[0], timebuf
);
8226 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8227 json
, JSON_C_TO_STRING_PRETTY
));
8228 json_object_free(json
);
8232 static void ip_msdp_show_sa_entry_detail(struct pim_msdp_sa
*sa
,
8233 const char *src_str
,
8234 const char *grp_str
, struct vty
*vty
,
8235 u_char uj
, json_object
*json
)
8237 char rp_str
[INET_ADDRSTRLEN
];
8238 char peer_str
[INET_ADDRSTRLEN
];
8239 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
8242 char statetimer
[PIM_MSDP_TIMER_STRLEN
];
8244 json_object
*json_group
= NULL
;
8245 json_object
*json_row
= NULL
;
8247 now
= pim_time_monotonic_sec();
8248 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
8249 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
8250 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
8251 pim_inet4_dump("<peer?>", sa
->peer
, peer_str
, sizeof(peer_str
));
8253 strcpy(spt_str
, "yes");
8255 strcpy(spt_str
, "no");
8258 strcpy(rp_str
, "-");
8259 strcpy(peer_str
, "-");
8260 strcpy(spt_str
, "-");
8262 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
8263 strcpy(local_str
, "yes");
8265 strcpy(local_str
, "no");
8267 pim_time_timer_to_hhmmss(statetimer
, sizeof(statetimer
),
8268 sa
->sa_state_timer
);
8270 json_object_object_get_ex(json
, grp_str
, &json_group
);
8273 json_group
= json_object_new_object();
8274 json_object_object_add(json
, grp_str
, json_group
);
8277 json_row
= json_object_new_object();
8278 json_object_string_add(json_row
, "source", src_str
);
8279 json_object_string_add(json_row
, "group", grp_str
);
8280 json_object_string_add(json_row
, "rp", rp_str
);
8281 json_object_string_add(json_row
, "local", local_str
);
8282 json_object_string_add(json_row
, "sptSetup", spt_str
);
8283 json_object_string_add(json_row
, "upTime", timebuf
);
8284 json_object_string_add(json_row
, "stateTimer", statetimer
);
8285 json_object_object_add(json_group
, src_str
, json_row
);
8287 vty_out(vty
, "SA : %s\n", sa
->sg_str
);
8288 vty_out(vty
, " RP : %s\n", rp_str
);
8289 vty_out(vty
, " Peer : %s\n", peer_str
);
8290 vty_out(vty
, " Local : %s\n", local_str
);
8291 vty_out(vty
, " SPT Setup : %s\n", spt_str
);
8292 vty_out(vty
, " Uptime : %s\n", timebuf
);
8293 vty_out(vty
, " State Timer : %s\n", statetimer
);
8298 static void ip_msdp_show_sa_detail(struct pim_instance
*pim
, struct vty
*vty
,
8301 struct listnode
*sanode
;
8302 struct pim_msdp_sa
*sa
;
8303 char src_str
[INET_ADDRSTRLEN
];
8304 char grp_str
[INET_ADDRSTRLEN
];
8305 json_object
*json
= NULL
;
8308 json
= json_object_new_object();
8311 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
8312 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
8313 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
8314 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
, uj
,
8319 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8320 json
, JSON_C_TO_STRING_PRETTY
));
8321 json_object_free(json
);
8325 DEFUN (show_ip_msdp_sa_detail
,
8326 show_ip_msdp_sa_detail_cmd
,
8327 "show ip msdp [vrf NAME] sa detail [json]",
8332 "MSDP active-source information\n"
8336 u_char uj
= use_json(argc
, argv
);
8338 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
8343 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
8348 DEFUN (show_ip_msdp_sa_detail_vrf_all
,
8349 show_ip_msdp_sa_detail_vrf_all_cmd
,
8350 "show ip msdp vrf all sa detail [json]",
8355 "MSDP active-source information\n"
8359 u_char uj
= use_json(argc
, argv
);
8365 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
8369 vty_out(vty
, " \"%s\": ", vrf
->name
);
8372 vty_out(vty
, "VRF: %s\n", vrf
->name
);
8373 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
8376 vty_out(vty
, "}\n");
8381 static void ip_msdp_show_sa_addr(struct pim_instance
*pim
, struct vty
*vty
,
8382 const char *addr
, u_char uj
)
8384 struct listnode
*sanode
;
8385 struct pim_msdp_sa
*sa
;
8386 char src_str
[INET_ADDRSTRLEN
];
8387 char grp_str
[INET_ADDRSTRLEN
];
8388 json_object
*json
= NULL
;
8391 json
= json_object_new_object();
8394 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
8395 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
8396 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
8397 if (!strcmp(addr
, src_str
) || !strcmp(addr
, grp_str
)) {
8398 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
8404 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8405 json
, JSON_C_TO_STRING_PRETTY
));
8406 json_object_free(json
);
8410 static void ip_msdp_show_sa_sg(struct pim_instance
*pim
, struct vty
*vty
,
8411 const char *src
, const char *grp
, u_char uj
)
8413 struct listnode
*sanode
;
8414 struct pim_msdp_sa
*sa
;
8415 char src_str
[INET_ADDRSTRLEN
];
8416 char grp_str
[INET_ADDRSTRLEN
];
8417 json_object
*json
= NULL
;
8420 json
= json_object_new_object();
8423 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
8424 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
8425 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
8426 if (!strcmp(src
, src_str
) && !strcmp(grp
, grp_str
)) {
8427 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
8433 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8434 json
, JSON_C_TO_STRING_PRETTY
));
8435 json_object_free(json
);
8439 DEFUN (show_ip_msdp_sa_sg
,
8440 show_ip_msdp_sa_sg_cmd
,
8441 "show ip msdp [vrf NAME] sa [A.B.C.D [A.B.C.D]] [json]",
8446 "MSDP active-source information\n"
8447 "source or group ip\n"
8451 u_char uj
= use_json(argc
, argv
);
8455 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
8460 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
8462 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
8466 if (src_ip
&& grp_ip
)
8467 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
8469 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
8471 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
8476 DEFUN (show_ip_msdp_sa_sg_vrf_all
,
8477 show_ip_msdp_sa_sg_vrf_all_cmd
,
8478 "show ip msdp vrf all sa [A.B.C.D [A.B.C.D]] [json]",
8483 "MSDP active-source information\n"
8484 "source or group ip\n"
8488 u_char uj
= use_json(argc
, argv
);
8493 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
8495 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
8501 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
8505 vty_out(vty
, " \"%s\": ", vrf
->name
);
8508 vty_out(vty
, "VRF: %s\n", vrf
->name
);
8510 if (src_ip
&& grp_ip
)
8511 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
8513 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
8515 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
8518 vty_out(vty
, "}\n");
8524 void pim_cmd_init(void)
8526 install_node(&pim_global_node
, pim_global_config_write
); /* PIM_NODE */
8527 install_node(&interface_node
,
8528 pim_interface_config_write
); /* INTERFACE_NODE */
8531 install_node(&debug_node
, pim_debug_config_write
);
8533 install_element(CONFIG_NODE
, &ip_multicast_routing_cmd
);
8534 install_element(CONFIG_NODE
, &no_ip_multicast_routing_cmd
);
8535 install_element(CONFIG_NODE
, &ip_pim_rp_cmd
);
8536 install_element(VRF_NODE
, &ip_pim_rp_cmd
);
8537 install_element(CONFIG_NODE
, &no_ip_pim_rp_cmd
);
8538 install_element(VRF_NODE
, &no_ip_pim_rp_cmd
);
8539 install_element(CONFIG_NODE
, &ip_pim_rp_prefix_list_cmd
);
8540 install_element(VRF_NODE
, &ip_pim_rp_prefix_list_cmd
);
8541 install_element(CONFIG_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
8542 install_element(VRF_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
8543 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
8544 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
8545 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
8546 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
8547 install_element(CONFIG_NODE
, &ip_pim_ssm_prefix_list_cmd
);
8548 install_element(VRF_NODE
, &ip_pim_ssm_prefix_list_cmd
);
8549 install_element(CONFIG_NODE
, &ip_pim_register_suppress_cmd
);
8550 install_element(VRF_NODE
, &ip_pim_register_suppress_cmd
);
8551 install_element(CONFIG_NODE
, &no_ip_pim_register_suppress_cmd
);
8552 install_element(VRF_NODE
, &no_ip_pim_register_suppress_cmd
);
8553 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
8554 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
8555 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
8556 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
8557 install_element(CONFIG_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
8558 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
8559 install_element(CONFIG_NODE
,
8560 &no_ip_pim_spt_switchover_infinity_plist_cmd
);
8561 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_plist_cmd
);
8562 install_element(CONFIG_NODE
, &ip_pim_joinprune_time_cmd
);
8563 install_element(VRF_NODE
, &ip_pim_joinprune_time_cmd
);
8564 install_element(CONFIG_NODE
, &no_ip_pim_joinprune_time_cmd
);
8565 install_element(VRF_NODE
, &no_ip_pim_joinprune_time_cmd
);
8566 install_element(CONFIG_NODE
, &ip_pim_keep_alive_cmd
);
8567 install_element(VRF_NODE
, &ip_pim_keep_alive_cmd
);
8568 install_element(CONFIG_NODE
, &ip_pim_rp_keep_alive_cmd
);
8569 install_element(VRF_NODE
, &ip_pim_rp_keep_alive_cmd
);
8570 install_element(CONFIG_NODE
, &no_ip_pim_keep_alive_cmd
);
8571 install_element(VRF_NODE
, &no_ip_pim_keep_alive_cmd
);
8572 install_element(CONFIG_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
8573 install_element(VRF_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
8574 install_element(CONFIG_NODE
, &ip_pim_packets_cmd
);
8575 install_element(VRF_NODE
, &ip_pim_packets_cmd
);
8576 install_element(CONFIG_NODE
, &no_ip_pim_packets_cmd
);
8577 install_element(VRF_NODE
, &no_ip_pim_packets_cmd
);
8578 install_element(CONFIG_NODE
, &ip_pim_v6_secondary_cmd
);
8579 install_element(VRF_NODE
, &ip_pim_v6_secondary_cmd
);
8580 install_element(CONFIG_NODE
, &no_ip_pim_v6_secondary_cmd
);
8581 install_element(VRF_NODE
, &no_ip_pim_v6_secondary_cmd
);
8582 install_element(CONFIG_NODE
, &ip_ssmpingd_cmd
);
8583 install_element(VRF_NODE
, &ip_ssmpingd_cmd
);
8584 install_element(CONFIG_NODE
, &no_ip_ssmpingd_cmd
);
8585 install_element(VRF_NODE
, &no_ip_ssmpingd_cmd
);
8586 install_element(CONFIG_NODE
, &ip_msdp_peer_cmd
);
8587 install_element(VRF_NODE
, &ip_msdp_peer_cmd
);
8588 install_element(CONFIG_NODE
, &no_ip_msdp_peer_cmd
);
8589 install_element(VRF_NODE
, &no_ip_msdp_peer_cmd
);
8590 install_element(CONFIG_NODE
, &ip_pim_ecmp_cmd
);
8591 install_element(VRF_NODE
, &ip_pim_ecmp_cmd
);
8592 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_cmd
);
8593 install_element(VRF_NODE
, &no_ip_pim_ecmp_cmd
);
8594 install_element(CONFIG_NODE
, &ip_pim_ecmp_rebalance_cmd
);
8595 install_element(VRF_NODE
, &ip_pim_ecmp_rebalance_cmd
);
8596 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
8597 install_element(VRF_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
8599 install_element(INTERFACE_NODE
, &interface_ip_igmp_cmd
);
8600 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_cmd
);
8601 install_element(INTERFACE_NODE
, &interface_ip_igmp_join_cmd
);
8602 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_join_cmd
);
8603 install_element(INTERFACE_NODE
, &interface_ip_igmp_version_cmd
);
8604 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_version_cmd
);
8605 install_element(INTERFACE_NODE
, &interface_ip_igmp_query_interval_cmd
);
8606 install_element(INTERFACE_NODE
,
8607 &interface_no_ip_igmp_query_interval_cmd
);
8608 install_element(INTERFACE_NODE
,
8609 &interface_ip_igmp_query_max_response_time_cmd
);
8610 install_element(INTERFACE_NODE
,
8611 &interface_no_ip_igmp_query_max_response_time_cmd
);
8612 install_element(INTERFACE_NODE
,
8613 &interface_ip_igmp_query_max_response_time_dsec_cmd
);
8614 install_element(INTERFACE_NODE
,
8615 &interface_no_ip_igmp_query_max_response_time_dsec_cmd
);
8616 install_element(INTERFACE_NODE
, &interface_ip_pim_ssm_cmd
);
8617 install_element(INTERFACE_NODE
, &interface_no_ip_pim_ssm_cmd
);
8618 install_element(INTERFACE_NODE
, &interface_ip_pim_sm_cmd
);
8619 install_element(INTERFACE_NODE
, &interface_no_ip_pim_sm_cmd
);
8620 install_element(INTERFACE_NODE
, &interface_ip_pim_drprio_cmd
);
8621 install_element(INTERFACE_NODE
, &interface_no_ip_pim_drprio_cmd
);
8622 install_element(INTERFACE_NODE
, &interface_ip_pim_hello_cmd
);
8623 install_element(INTERFACE_NODE
, &interface_no_ip_pim_hello_cmd
);
8624 install_element(INTERFACE_NODE
, &interface_ip_pim_boundary_oil_cmd
);
8625 install_element(INTERFACE_NODE
, &interface_no_ip_pim_boundary_oil_cmd
);
8627 // Static mroutes NEB
8628 install_element(INTERFACE_NODE
, &interface_ip_mroute_cmd
);
8629 install_element(INTERFACE_NODE
, &interface_ip_mroute_source_cmd
);
8630 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_cmd
);
8631 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_source_cmd
);
8633 install_element(VIEW_NODE
, &show_ip_igmp_interface_cmd
);
8634 install_element(VIEW_NODE
, &show_ip_igmp_interface_vrf_all_cmd
);
8635 install_element(VIEW_NODE
, &show_ip_igmp_join_cmd
);
8636 install_element(VIEW_NODE
, &show_ip_igmp_join_vrf_all_cmd
);
8637 install_element(VIEW_NODE
, &show_ip_igmp_groups_cmd
);
8638 install_element(VIEW_NODE
, &show_ip_igmp_groups_vrf_all_cmd
);
8639 install_element(VIEW_NODE
, &show_ip_igmp_groups_retransmissions_cmd
);
8640 install_element(VIEW_NODE
, &show_ip_igmp_sources_cmd
);
8641 install_element(VIEW_NODE
, &show_ip_igmp_sources_retransmissions_cmd
);
8642 install_element(VIEW_NODE
, &show_ip_pim_assert_cmd
);
8643 install_element(VIEW_NODE
, &show_ip_pim_assert_internal_cmd
);
8644 install_element(VIEW_NODE
, &show_ip_pim_assert_metric_cmd
);
8645 install_element(VIEW_NODE
, &show_ip_pim_assert_winner_metric_cmd
);
8646 install_element(VIEW_NODE
, &show_ip_pim_interface_traffic_cmd
);
8647 install_element(VIEW_NODE
, &show_ip_pim_interface_cmd
);
8648 install_element(VIEW_NODE
, &show_ip_pim_interface_vrf_all_cmd
);
8649 install_element(VIEW_NODE
, &show_ip_pim_join_cmd
);
8650 install_element(VIEW_NODE
, &show_ip_pim_join_vrf_all_cmd
);
8651 install_element(VIEW_NODE
, &show_ip_pim_local_membership_cmd
);
8652 install_element(VIEW_NODE
, &show_ip_pim_neighbor_cmd
);
8653 install_element(VIEW_NODE
, &show_ip_pim_neighbor_vrf_all_cmd
);
8654 install_element(VIEW_NODE
, &show_ip_pim_rpf_cmd
);
8655 install_element(VIEW_NODE
, &show_ip_pim_rpf_vrf_all_cmd
);
8656 install_element(VIEW_NODE
, &show_ip_pim_secondary_cmd
);
8657 install_element(VIEW_NODE
, &show_ip_pim_state_cmd
);
8658 install_element(VIEW_NODE
, &show_ip_pim_state_vrf_all_cmd
);
8659 install_element(VIEW_NODE
, &show_ip_pim_upstream_cmd
);
8660 install_element(VIEW_NODE
, &show_ip_pim_upstream_vrf_all_cmd
);
8661 install_element(VIEW_NODE
, &show_ip_pim_upstream_join_desired_cmd
);
8662 install_element(VIEW_NODE
, &show_ip_pim_upstream_rpf_cmd
);
8663 install_element(VIEW_NODE
, &show_ip_pim_rp_cmd
);
8664 install_element(VIEW_NODE
, &show_ip_pim_rp_vrf_all_cmd
);
8665 install_element(VIEW_NODE
, &show_ip_multicast_cmd
);
8666 install_element(VIEW_NODE
, &show_ip_multicast_vrf_all_cmd
);
8667 install_element(VIEW_NODE
, &show_ip_mroute_cmd
);
8668 install_element(VIEW_NODE
, &show_ip_mroute_vrf_all_cmd
);
8669 install_element(VIEW_NODE
, &show_ip_mroute_count_cmd
);
8670 install_element(VIEW_NODE
, &show_ip_mroute_count_vrf_all_cmd
);
8671 install_element(VIEW_NODE
, &show_ip_rib_cmd
);
8672 install_element(VIEW_NODE
, &show_ip_ssmpingd_cmd
);
8673 install_element(VIEW_NODE
, &show_debugging_pim_cmd
);
8674 install_element(VIEW_NODE
, &show_ip_pim_nexthop_cmd
);
8675 install_element(VIEW_NODE
, &show_ip_pim_nexthop_lookup_cmd
);
8677 install_element(ENABLE_NODE
, &clear_ip_interfaces_cmd
);
8678 install_element(ENABLE_NODE
, &clear_ip_igmp_interfaces_cmd
);
8679 install_element(ENABLE_NODE
, &clear_ip_mroute_cmd
);
8680 install_element(ENABLE_NODE
, &clear_ip_pim_interfaces_cmd
);
8681 install_element(ENABLE_NODE
, &clear_ip_pim_interface_traffic_cmd
);
8682 install_element(ENABLE_NODE
, &clear_ip_pim_oil_cmd
);
8684 install_element(ENABLE_NODE
, &debug_igmp_cmd
);
8685 install_element(ENABLE_NODE
, &no_debug_igmp_cmd
);
8686 install_element(ENABLE_NODE
, &debug_igmp_events_cmd
);
8687 install_element(ENABLE_NODE
, &no_debug_igmp_events_cmd
);
8688 install_element(ENABLE_NODE
, &debug_igmp_packets_cmd
);
8689 install_element(ENABLE_NODE
, &no_debug_igmp_packets_cmd
);
8690 install_element(ENABLE_NODE
, &debug_igmp_trace_cmd
);
8691 install_element(ENABLE_NODE
, &no_debug_igmp_trace_cmd
);
8692 install_element(ENABLE_NODE
, &debug_mroute_cmd
);
8693 install_element(ENABLE_NODE
, &debug_mroute_detail_cmd
);
8694 install_element(ENABLE_NODE
, &no_debug_mroute_cmd
);
8695 install_element(ENABLE_NODE
, &no_debug_mroute_detail_cmd
);
8696 install_element(ENABLE_NODE
, &debug_static_cmd
);
8697 install_element(ENABLE_NODE
, &no_debug_static_cmd
);
8698 install_element(ENABLE_NODE
, &debug_pim_cmd
);
8699 install_element(ENABLE_NODE
, &no_debug_pim_cmd
);
8700 install_element(ENABLE_NODE
, &debug_pim_nht_cmd
);
8701 install_element(ENABLE_NODE
, &no_debug_pim_nht_cmd
);
8702 install_element(ENABLE_NODE
, &debug_pim_nht_rp_cmd
);
8703 install_element(ENABLE_NODE
, &no_debug_pim_nht_rp_cmd
);
8704 install_element(ENABLE_NODE
, &debug_pim_events_cmd
);
8705 install_element(ENABLE_NODE
, &no_debug_pim_events_cmd
);
8706 install_element(ENABLE_NODE
, &debug_pim_packets_cmd
);
8707 install_element(ENABLE_NODE
, &no_debug_pim_packets_cmd
);
8708 install_element(ENABLE_NODE
, &debug_pim_packetdump_send_cmd
);
8709 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_send_cmd
);
8710 install_element(ENABLE_NODE
, &debug_pim_packetdump_recv_cmd
);
8711 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_recv_cmd
);
8712 install_element(ENABLE_NODE
, &debug_pim_trace_cmd
);
8713 install_element(ENABLE_NODE
, &no_debug_pim_trace_cmd
);
8714 install_element(ENABLE_NODE
, &debug_pim_trace_detail_cmd
);
8715 install_element(ENABLE_NODE
, &no_debug_pim_trace_detail_cmd
);
8716 install_element(ENABLE_NODE
, &debug_ssmpingd_cmd
);
8717 install_element(ENABLE_NODE
, &no_debug_ssmpingd_cmd
);
8718 install_element(ENABLE_NODE
, &debug_pim_zebra_cmd
);
8719 install_element(ENABLE_NODE
, &no_debug_pim_zebra_cmd
);
8720 install_element(ENABLE_NODE
, &debug_msdp_cmd
);
8721 install_element(ENABLE_NODE
, &no_debug_msdp_cmd
);
8722 install_element(ENABLE_NODE
, &undebug_msdp_cmd
);
8723 install_element(ENABLE_NODE
, &debug_msdp_events_cmd
);
8724 install_element(ENABLE_NODE
, &no_debug_msdp_events_cmd
);
8725 install_element(ENABLE_NODE
, &undebug_msdp_events_cmd
);
8726 install_element(ENABLE_NODE
, &debug_msdp_packets_cmd
);
8727 install_element(ENABLE_NODE
, &no_debug_msdp_packets_cmd
);
8728 install_element(ENABLE_NODE
, &undebug_msdp_packets_cmd
);
8730 install_element(CONFIG_NODE
, &debug_igmp_cmd
);
8731 install_element(CONFIG_NODE
, &no_debug_igmp_cmd
);
8732 install_element(CONFIG_NODE
, &debug_igmp_events_cmd
);
8733 install_element(CONFIG_NODE
, &no_debug_igmp_events_cmd
);
8734 install_element(CONFIG_NODE
, &debug_igmp_packets_cmd
);
8735 install_element(CONFIG_NODE
, &no_debug_igmp_packets_cmd
);
8736 install_element(CONFIG_NODE
, &debug_igmp_trace_cmd
);
8737 install_element(CONFIG_NODE
, &no_debug_igmp_trace_cmd
);
8738 install_element(CONFIG_NODE
, &debug_mroute_cmd
);
8739 install_element(CONFIG_NODE
, &debug_mroute_detail_cmd
);
8740 install_element(CONFIG_NODE
, &no_debug_mroute_cmd
);
8741 install_element(CONFIG_NODE
, &no_debug_mroute_detail_cmd
);
8742 install_element(CONFIG_NODE
, &debug_static_cmd
);
8743 install_element(CONFIG_NODE
, &no_debug_static_cmd
);
8744 install_element(CONFIG_NODE
, &debug_pim_cmd
);
8745 install_element(CONFIG_NODE
, &no_debug_pim_cmd
);
8746 install_element(CONFIG_NODE
, &debug_pim_nht_cmd
);
8747 install_element(CONFIG_NODE
, &no_debug_pim_nht_cmd
);
8748 install_element(CONFIG_NODE
, &debug_pim_nht_rp_cmd
);
8749 install_element(CONFIG_NODE
, &no_debug_pim_nht_rp_cmd
);
8750 install_element(CONFIG_NODE
, &debug_pim_events_cmd
);
8751 install_element(CONFIG_NODE
, &no_debug_pim_events_cmd
);
8752 install_element(CONFIG_NODE
, &debug_pim_packets_cmd
);
8753 install_element(CONFIG_NODE
, &no_debug_pim_packets_cmd
);
8754 install_element(CONFIG_NODE
, &debug_pim_trace_cmd
);
8755 install_element(CONFIG_NODE
, &no_debug_pim_trace_cmd
);
8756 install_element(CONFIG_NODE
, &debug_pim_trace_detail_cmd
);
8757 install_element(CONFIG_NODE
, &no_debug_pim_trace_detail_cmd
);
8758 install_element(CONFIG_NODE
, &debug_ssmpingd_cmd
);
8759 install_element(CONFIG_NODE
, &no_debug_ssmpingd_cmd
);
8760 install_element(CONFIG_NODE
, &debug_pim_zebra_cmd
);
8761 install_element(CONFIG_NODE
, &no_debug_pim_zebra_cmd
);
8762 install_element(CONFIG_NODE
, &debug_msdp_cmd
);
8763 install_element(CONFIG_NODE
, &no_debug_msdp_cmd
);
8764 install_element(CONFIG_NODE
, &undebug_msdp_cmd
);
8765 install_element(CONFIG_NODE
, &debug_msdp_events_cmd
);
8766 install_element(CONFIG_NODE
, &no_debug_msdp_events_cmd
);
8767 install_element(CONFIG_NODE
, &undebug_msdp_events_cmd
);
8768 install_element(CONFIG_NODE
, &debug_msdp_packets_cmd
);
8769 install_element(CONFIG_NODE
, &no_debug_msdp_packets_cmd
);
8770 install_element(CONFIG_NODE
, &undebug_msdp_packets_cmd
);
8772 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_member_cmd
);
8773 install_element(VRF_NODE
, &ip_msdp_mesh_group_member_cmd
);
8774 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
8775 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
8776 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_source_cmd
);
8777 install_element(VRF_NODE
, &ip_msdp_mesh_group_source_cmd
);
8778 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
8779 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
8780 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_cmd
);
8781 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_vrf_all_cmd
);
8782 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_cmd
);
8783 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_vrf_all_cmd
);
8784 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_cmd
);
8785 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_vrf_all_cmd
);
8786 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_cmd
);
8787 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_vrf_all_cmd
);
8788 install_element(VIEW_NODE
, &show_ip_pim_ssm_range_cmd
);
8789 install_element(VIEW_NODE
, &show_ip_pim_group_type_cmd
);
8790 install_element(INTERFACE_NODE
, &interface_pim_use_source_cmd
);
8791 install_element(INTERFACE_NODE
, &interface_no_pim_use_source_cmd
);
8792 /* Install BFD command */
8793 install_element(INTERFACE_NODE
, &ip_pim_bfd_cmd
);
8794 install_element(INTERFACE_NODE
, &ip_pim_bfd_param_cmd
);
8795 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_cmd
);
8796 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_param_cmd
);