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 RB_FOREACH (ifp
, if_name_head
, &pim
->vrf
->ifaces_by_name
) {
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 RB_FOREACH (ifp
, if_name_head
, &pim
->vrf
->ifaces_by_name
) {
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 RB_FOREACH (ifp
, if_name_head
, &pim
->vrf
->ifaces_by_name
) {
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 RB_FOREACH (ifp
, if_name_head
, &pim
->vrf
->ifaces_by_name
) {
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 RB_FOREACH (ifp
, if_name_head
, &pim
->vrf
->ifaces_by_name
) {
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 RB_FOREACH (ifp
, if_name_head
, &pim
->vrf
->ifaces_by_name
) {
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 RB_FOREACH (ifp
, if_name_head
, &pim
->vrf
->ifaces_by_name
) {
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 RB_FOREACH (ifp
, if_name_head
, &pim
->vrf
->ifaces_by_name
) {
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 RB_FOREACH (ifp
, if_name_head
, &pim
->vrf
->ifaces_by_name
) {
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
) {
1059 & PIM_UPSTREAM_FLAG_MASK_FHR
) {
1060 if (!json_fhr_sources
) {
1062 json_object_new_object();
1065 pim_inet4_dump("<src?>",
1069 pim_inet4_dump("<grp?>",
1074 uptime
, sizeof(uptime
),
1075 now
- up
->state_transition
);
1077 /* Does this group live in
1078 * json_fhr_sources? If not
1080 json_object_object_get_ex(
1082 grp_str
, &json_group
);
1086 json_object_new_object();
1087 json_object_object_add(
1094 json_object_new_object();
1095 json_object_string_add(
1098 json_object_string_add(
1101 json_object_string_add(
1104 json_object_object_add(
1105 json_group
, src_str
,
1111 if (json_fhr_sources
) {
1112 json_object_object_add(json_row
,
1117 json_object_int_add(json_row
, "helloPeriod",
1118 pim_ifp
->pim_hello_period
);
1119 json_object_string_add(json_row
, "helloTimer",
1121 json_object_string_add(json_row
, "helloStatStart",
1123 json_object_int_add(json_row
, "helloReceived",
1124 pim_ifp
->pim_ifstat_hello_recv
);
1125 json_object_int_add(json_row
, "helloReceivedFailed",
1126 pim_ifp
->pim_ifstat_hello_recvfail
);
1127 json_object_int_add(json_row
, "helloSend",
1128 pim_ifp
->pim_ifstat_hello_sent
);
1129 json_object_int_add(json_row
, "hellosendFailed",
1130 pim_ifp
->pim_ifstat_hello_sendfail
);
1131 json_object_int_add(json_row
, "helloGenerationId",
1132 pim_ifp
->pim_generation_id
);
1133 json_object_int_add(json_row
, "flagMulticastLoop",
1136 json_object_int_add(
1137 json_row
, "effectivePropagationDelay",
1138 pim_if_effective_propagation_delay_msec(ifp
));
1139 json_object_int_add(
1140 json_row
, "effectiveOverrideInterval",
1141 pim_if_effective_override_interval_msec(ifp
));
1142 json_object_int_add(
1143 json_row
, "joinPruneOverrideInterval",
1144 pim_if_jp_override_interval_msec(ifp
));
1146 json_object_int_add(
1147 json_row
, "propagationDelay",
1148 pim_ifp
->pim_propagation_delay_msec
);
1149 json_object_int_add(
1150 json_row
, "propagationDelayHighest",
1151 pim_ifp
->pim_neighbors_highest_propagation_delay_msec
);
1152 json_object_int_add(
1153 json_row
, "overrideInterval",
1154 pim_ifp
->pim_override_interval_msec
);
1155 json_object_int_add(
1156 json_row
, "overrideIntervalHighest",
1157 pim_ifp
->pim_neighbors_highest_override_interval_msec
);
1158 json_object_object_add(json
, ifp
->name
, json_row
);
1161 vty_out(vty
, "Interface : %s\n", ifp
->name
);
1162 vty_out(vty
, "State : %s\n",
1163 if_is_up(ifp
) ? "up" : "down");
1164 if (pim_ifp
->update_source
.s_addr
!= INADDR_ANY
) {
1165 vty_out(vty
, "Use Source : %s\n",
1166 inet_ntoa(pim_ifp
->update_source
));
1168 if (pim_ifp
->sec_addr_list
) {
1169 char pbuf
[PREFIX2STR_BUFFER
];
1170 vty_out(vty
, "Address : %s (primary)\n",
1172 for (ALL_LIST_ELEMENTS_RO(
1173 pim_ifp
->sec_addr_list
, sec_node
,
1175 vty_out(vty
, " %s\n",
1176 prefix2str(&sec_addr
->addr
,
1177 pbuf
, sizeof(pbuf
)));
1180 vty_out(vty
, "Address : %s\n",
1188 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
,
1189 neighnode
, neigh
)) {
1192 vty_out(vty
, "PIM Neighbors\n");
1193 vty_out(vty
, "-------------\n");
1197 pim_inet4_dump("<src?>", neigh
->source_addr
,
1199 sizeof(neigh_src_str
));
1200 pim_time_uptime(uptime
, sizeof(uptime
),
1201 now
- neigh
->creation
);
1202 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
1203 neigh
->t_expire_timer
);
1205 "%-15s : up for %s, holdtime expires in %s\n",
1206 neigh_src_str
, uptime
, expire
);
1209 if (!print_header
) {
1214 vty_out(vty
, "Designated Router\n");
1215 vty_out(vty
, "-----------------\n");
1216 vty_out(vty
, "Address : %s\n", dr_str
);
1217 vty_out(vty
, "Priority : %d\n",
1218 pim_ifp
->pim_dr_priority
);
1219 vty_out(vty
, "Uptime : %s\n", dr_uptime
);
1220 vty_out(vty
, "Elections : %d\n",
1221 pim_ifp
->pim_dr_election_count
);
1222 vty_out(vty
, "Changes : %d\n",
1223 pim_ifp
->pim_dr_election_changes
);
1229 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
,
1231 if (strcmp(ifp
->name
, up
->rpf
.source_nexthop
1235 & PIM_UPSTREAM_FLAG_MASK_FHR
) {
1239 "FHR - First Hop Router\n");
1241 "----------------------\n");
1245 pim_inet4_dump("<src?>",
1249 pim_inet4_dump("<grp?>",
1254 uptime
, sizeof(uptime
),
1255 now
- up
->state_transition
);
1257 "%s : %s is a source, uptime is %s\n",
1264 if (!print_header
) {
1269 vty_out(vty
, "Hellos\n");
1270 vty_out(vty
, "------\n");
1271 vty_out(vty
, "Period : %d\n",
1272 pim_ifp
->pim_hello_period
);
1273 vty_out(vty
, "Timer : %s\n", hello_timer
);
1274 vty_out(vty
, "StatStart : %s\n", stat_uptime
);
1275 vty_out(vty
, "Receive : %d\n",
1276 pim_ifp
->pim_ifstat_hello_recv
);
1277 vty_out(vty
, "Receive Failed : %d\n",
1278 pim_ifp
->pim_ifstat_hello_recvfail
);
1279 vty_out(vty
, "Send : %d\n",
1280 pim_ifp
->pim_ifstat_hello_sent
);
1281 vty_out(vty
, "Send Failed : %d\n",
1282 pim_ifp
->pim_ifstat_hello_sendfail
);
1283 vty_out(vty
, "Generation ID : %08x\n",
1284 pim_ifp
->pim_generation_id
);
1288 pim_print_ifp_flags(vty
, ifp
, mloop
);
1290 vty_out(vty
, "Join Prune Interval\n");
1291 vty_out(vty
, "-------------------\n");
1292 vty_out(vty
, "LAN Delay : %s\n",
1293 pim_if_lan_delay_enabled(ifp
) ? "yes" : "no");
1294 vty_out(vty
, "Effective Propagation Delay : %d msec\n",
1295 pim_if_effective_propagation_delay_msec(ifp
));
1296 vty_out(vty
, "Effective Override Interval : %d msec\n",
1297 pim_if_effective_override_interval_msec(ifp
));
1298 vty_out(vty
, "Join Prune Override Interval : %d msec\n",
1299 pim_if_jp_override_interval_msec(ifp
));
1303 vty_out(vty
, "LAN Prune Delay\n");
1304 vty_out(vty
, "---------------\n");
1305 vty_out(vty
, "Propagation Delay : %d msec\n",
1306 pim_ifp
->pim_propagation_delay_msec
);
1307 vty_out(vty
, "Propagation Delay (Highest) : %d msec\n",
1308 pim_ifp
->pim_neighbors_highest_propagation_delay_msec
);
1309 vty_out(vty
, "Override Interval : %d msec\n",
1310 pim_ifp
->pim_override_interval_msec
);
1311 vty_out(vty
, "Override Interval (Highest) : %d msec\n",
1312 pim_ifp
->pim_neighbors_highest_override_interval_msec
);
1319 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1320 json
, JSON_C_TO_STRING_PRETTY
));
1321 json_object_free(json
);
1324 vty_out(vty
, "%% No such interface\n");
1328 static void pim_show_interfaces(struct pim_instance
*pim
, struct vty
*vty
,
1331 struct interface
*ifp
;
1332 struct listnode
*upnode
;
1333 struct pim_interface
*pim_ifp
;
1334 struct pim_upstream
*up
;
1337 int pim_ifchannels
= 0;
1338 json_object
*json
= NULL
;
1339 json_object
*json_row
= NULL
;
1340 json_object
*json_tmp
;
1342 json
= json_object_new_object();
1344 RB_FOREACH (ifp
, if_name_head
, &pim
->vrf
->ifaces_by_name
) {
1345 pim_ifp
= ifp
->info
;
1350 pim_nbrs
= pim_ifp
->pim_neighbor_list
->count
;
1351 pim_ifchannels
= pim_if_ifchannel_count(pim_ifp
);
1354 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
, up
))
1355 if (ifp
== up
->rpf
.source_nexthop
.interface
)
1356 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
1359 json_row
= json_object_new_object();
1360 json_object_pim_ifp_add(json_row
, ifp
);
1361 json_object_int_add(json_row
, "pimNeighbors", pim_nbrs
);
1362 json_object_int_add(json_row
, "pimIfChannels", pim_ifchannels
);
1363 json_object_int_add(json_row
, "firstHopRouterCount", fhr
);
1364 json_object_string_add(json_row
, "pimDesignatedRouter",
1365 inet_ntoa(pim_ifp
->pim_dr_addr
));
1367 if (pim_ifp
->pim_dr_addr
.s_addr
1368 == pim_ifp
->primary_address
.s_addr
)
1369 json_object_boolean_true_add(
1370 json_row
, "pimDesignatedRouterLocal");
1372 json_object_object_add(json
, ifp
->name
, json_row
);
1376 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1377 json
, JSON_C_TO_STRING_PRETTY
));
1380 "Interface State Address PIM Nbrs PIM DR FHR IfChannels\n");
1382 json_object_object_foreach(json
, key
, val
)
1384 vty_out(vty
, "%-9s ", key
);
1386 json_object_object_get_ex(val
, "state", &json_tmp
);
1387 vty_out(vty
, "%5s ", json_object_get_string(json_tmp
));
1389 json_object_object_get_ex(val
, "address", &json_tmp
);
1390 vty_out(vty
, "%15s ",
1391 json_object_get_string(json_tmp
));
1393 json_object_object_get_ex(val
, "pimNeighbors",
1395 vty_out(vty
, "%8d ", json_object_get_int(json_tmp
));
1397 if (json_object_object_get_ex(
1398 val
, "pimDesignatedRouterLocal",
1400 vty_out(vty
, "%15s ", "local");
1402 json_object_object_get_ex(
1403 val
, "pimDesignatedRouter", &json_tmp
);
1404 vty_out(vty
, "%15s ",
1405 json_object_get_string(json_tmp
));
1408 json_object_object_get_ex(val
, "firstHopRouter",
1410 vty_out(vty
, "%3d ", json_object_get_int(json_tmp
));
1412 json_object_object_get_ex(val
, "pimIfChannels",
1414 vty_out(vty
, "%9d\n", json_object_get_int(json_tmp
));
1418 json_object_free(json
);
1421 static void pim_show_interface_traffic(struct pim_instance
*pim
,
1422 struct vty
*vty
, u_char uj
)
1424 struct interface
*ifp
= NULL
;
1425 struct pim_interface
*pim_ifp
= NULL
;
1426 json_object
*json
= NULL
;
1427 json_object
*json_row
= NULL
;
1430 json
= json_object_new_object();
1433 vty_out(vty
, "%-12s%-17s%-17s%-17s%-17s%-17s%-17s\n",
1434 "Interface", " HELLO", " JOIN", " PRUNE",
1435 " REGISTER", " REGISTER-STOP", " ASSERT");
1436 vty_out(vty
, "%-10s%-18s%-17s%-17s%-17s%-17s%-17s\n", "",
1437 " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1438 " Rx/Tx", " Rx/Tx");
1440 "---------------------------------------------------------------------------------------------------------------\n");
1443 RB_FOREACH (ifp
, if_name_head
, &pim
->vrf
->ifaces_by_name
) {
1444 pim_ifp
= ifp
->info
;
1449 if (pim_ifp
->pim_sock_fd
< 0)
1452 json_row
= json_object_new_object();
1453 json_object_pim_ifp_add(json_row
, ifp
);
1454 json_object_int_add(json_row
, "helloRx",
1455 pim_ifp
->pim_ifstat_hello_recv
);
1456 json_object_int_add(json_row
, "helloTx",
1457 pim_ifp
->pim_ifstat_hello_sent
);
1458 json_object_int_add(json_row
, "joinRx",
1459 pim_ifp
->pim_ifstat_join_recv
);
1460 json_object_int_add(json_row
, "joinTx",
1461 pim_ifp
->pim_ifstat_join_send
);
1462 json_object_int_add(json_row
, "registerRx",
1463 pim_ifp
->pim_ifstat_reg_recv
);
1464 json_object_int_add(json_row
, "registerTx",
1465 pim_ifp
->pim_ifstat_reg_recv
);
1466 json_object_int_add(json_row
, "registerStopRx",
1467 pim_ifp
->pim_ifstat_reg_stop_recv
);
1468 json_object_int_add(json_row
, "registerStopTx",
1469 pim_ifp
->pim_ifstat_reg_stop_send
);
1470 json_object_int_add(json_row
, "assertRx",
1471 pim_ifp
->pim_ifstat_assert_recv
);
1472 json_object_int_add(json_row
, "assertTx",
1473 pim_ifp
->pim_ifstat_assert_send
);
1475 json_object_object_add(json
, ifp
->name
, json_row
);
1478 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u \n",
1479 ifp
->name
, pim_ifp
->pim_ifstat_hello_recv
,
1480 pim_ifp
->pim_ifstat_hello_sent
,
1481 pim_ifp
->pim_ifstat_join_recv
,
1482 pim_ifp
->pim_ifstat_join_send
,
1483 pim_ifp
->pim_ifstat_prune_recv
,
1484 pim_ifp
->pim_ifstat_prune_send
,
1485 pim_ifp
->pim_ifstat_reg_recv
,
1486 pim_ifp
->pim_ifstat_reg_send
,
1487 pim_ifp
->pim_ifstat_reg_stop_recv
,
1488 pim_ifp
->pim_ifstat_reg_stop_send
,
1489 pim_ifp
->pim_ifstat_assert_recv
,
1490 pim_ifp
->pim_ifstat_assert_send
);
1494 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1495 json
, JSON_C_TO_STRING_PRETTY
));
1496 json_object_free(json
);
1500 static void pim_show_interface_traffic_single(struct pim_instance
*pim
,
1502 const char *ifname
, u_char uj
)
1504 struct interface
*ifp
= NULL
;
1505 struct pim_interface
*pim_ifp
= NULL
;
1506 json_object
*json
= NULL
;
1507 json_object
*json_row
= NULL
;
1508 uint8_t found_ifname
= 0;
1511 json
= json_object_new_object();
1514 vty_out(vty
, "%-12s%-17s%-17s%-17s%-17s%-17s%-17s\n",
1515 "Interface", " HELLO", " JOIN", " PRUNE",
1516 " REGISTER", " REGISTER-STOP", " ASSERT");
1517 vty_out(vty
, "%-10s%-18s%-17s%-17s%-17s%-17s%-17s\n", "",
1518 " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1519 " Rx/Tx", " Rx/Tx");
1521 "---------------------------------------------------------------------------------------------------------------\n");
1524 RB_FOREACH (ifp
, if_name_head
, &pim
->vrf
->ifaces_by_name
) {
1525 if (strcmp(ifname
, ifp
->name
))
1528 pim_ifp
= ifp
->info
;
1533 if (pim_ifp
->pim_sock_fd
< 0)
1538 json_row
= json_object_new_object();
1539 json_object_pim_ifp_add(json_row
, ifp
);
1540 json_object_int_add(json_row
, "helloRx",
1541 pim_ifp
->pim_ifstat_hello_recv
);
1542 json_object_int_add(json_row
, "helloTx",
1543 pim_ifp
->pim_ifstat_hello_sent
);
1544 json_object_int_add(json_row
, "joinRx",
1545 pim_ifp
->pim_ifstat_join_recv
);
1546 json_object_int_add(json_row
, "joinTx",
1547 pim_ifp
->pim_ifstat_join_send
);
1548 json_object_int_add(json_row
, "registerRx",
1549 pim_ifp
->pim_ifstat_reg_recv
);
1550 json_object_int_add(json_row
, "registerTx",
1551 pim_ifp
->pim_ifstat_reg_recv
);
1552 json_object_int_add(json_row
, "registerStopRx",
1553 pim_ifp
->pim_ifstat_reg_stop_recv
);
1554 json_object_int_add(json_row
, "registerStopTx",
1555 pim_ifp
->pim_ifstat_reg_stop_send
);
1556 json_object_int_add(json_row
, "assertRx",
1557 pim_ifp
->pim_ifstat_assert_recv
);
1558 json_object_int_add(json_row
, "assertTx",
1559 pim_ifp
->pim_ifstat_assert_send
);
1561 json_object_object_add(json
, ifp
->name
, json_row
);
1564 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u \n",
1565 ifp
->name
, pim_ifp
->pim_ifstat_hello_recv
,
1566 pim_ifp
->pim_ifstat_hello_sent
,
1567 pim_ifp
->pim_ifstat_join_recv
,
1568 pim_ifp
->pim_ifstat_join_send
,
1569 pim_ifp
->pim_ifstat_prune_recv
,
1570 pim_ifp
->pim_ifstat_prune_send
,
1571 pim_ifp
->pim_ifstat_reg_recv
,
1572 pim_ifp
->pim_ifstat_reg_send
,
1573 pim_ifp
->pim_ifstat_reg_stop_recv
,
1574 pim_ifp
->pim_ifstat_reg_stop_send
,
1575 pim_ifp
->pim_ifstat_assert_recv
,
1576 pim_ifp
->pim_ifstat_assert_send
);
1580 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1581 json
, JSON_C_TO_STRING_PRETTY
));
1582 json_object_free(json
);
1585 vty_out(vty
, "%% No such interface\n");
1589 static void pim_show_join_helper(struct vty
*vty
,
1590 struct pim_interface
*pim_ifp
,
1591 struct pim_ifchannel
*ch
,
1596 char ch_src_str
[INET_ADDRSTRLEN
];
1597 char ch_grp_str
[INET_ADDRSTRLEN
];
1598 json_object
*json_iface
= NULL
;
1599 json_object
*json_row
= NULL
;
1600 json_object
*json_grp
= NULL
;
1601 struct in_addr ifaddr
;
1606 ifaddr
= pim_ifp
->primary_address
;
1608 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
,
1609 sizeof(ch_src_str
));
1610 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
,
1611 sizeof(ch_grp_str
));
1613 pim_time_uptime_begin(uptime
, sizeof(uptime
), now
,
1614 ch
->ifjoin_creation
);
1615 pim_time_timer_to_mmss(expire
, sizeof(expire
),
1616 ch
->t_ifjoin_expiry_timer
);
1617 pim_time_timer_to_mmss(prune
, sizeof(prune
),
1618 ch
->t_ifjoin_prune_pending_timer
);
1621 json_object_object_get_ex(json
, ch
->interface
->name
,
1625 json_iface
= json_object_new_object();
1626 json_object_pim_ifp_add(json_iface
,
1628 json_object_object_add(
1629 json
, ch
->interface
->name
, json_iface
);
1632 json_row
= json_object_new_object();
1633 json_object_string_add(json_row
, "source", ch_src_str
);
1634 json_object_string_add(json_row
, "group", ch_grp_str
);
1635 json_object_string_add(json_row
, "upTime", uptime
);
1636 json_object_string_add(json_row
, "expire", expire
);
1637 json_object_string_add(json_row
, "prune", prune
);
1638 json_object_string_add(
1639 json_row
, "channelJoinName",
1640 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
,
1642 if (PIM_IF_FLAG_TEST_S_G_RPT(ch
->flags
))
1643 json_object_int_add(json_row
, "SGRpt", 1);
1645 json_object_object_get_ex(json_iface
, ch_grp_str
,
1648 json_grp
= json_object_new_object();
1649 json_object_object_add(json_grp
, ch_src_str
,
1651 json_object_object_add(json_iface
, ch_grp_str
,
1654 json_object_object_add(json_grp
, ch_src_str
,
1658 "%-9s %-15s %-15s %-15s %-10s %8s %-6s %5s\n",
1659 ch
->interface
->name
, inet_ntoa(ifaddr
),
1660 ch_src_str
, ch_grp_str
,
1661 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
,
1663 uptime
, expire
, prune
);
1667 static void pim_show_join(struct pim_instance
*pim
, struct vty
*vty
, u_char uj
)
1669 struct pim_interface
*pim_ifp
;
1670 struct pim_ifchannel
*ch
;
1671 struct interface
*ifp
;
1673 json_object
*json
= NULL
;
1675 now
= pim_time_monotonic_sec();
1678 json
= json_object_new_object();
1681 "Interface Address Source Group State Uptime Expire Prune\n");
1683 RB_FOREACH (ifp
, if_name_head
, &pim
->vrf
->ifaces_by_name
) {
1684 pim_ifp
= ifp
->info
;
1688 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
1689 pim_show_join_helper(vty
, pim_ifp
, ch
, json
, now
, uj
);
1690 } /* scan interface channels */
1694 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1695 json
, JSON_C_TO_STRING_PRETTY
));
1696 json_object_free(json
);
1700 static void pim_show_neighbors_single(struct pim_instance
*pim
, struct vty
*vty
,
1701 const char *neighbor
, u_char uj
)
1703 struct listnode
*neighnode
;
1704 struct interface
*ifp
;
1705 struct pim_interface
*pim_ifp
;
1706 struct pim_neighbor
*neigh
;
1708 int found_neighbor
= 0;
1709 int option_address_list
;
1710 int option_dr_priority
;
1711 int option_generation_id
;
1712 int option_holdtime
;
1713 int option_lan_prune_delay
;
1717 char neigh_src_str
[INET_ADDRSTRLEN
];
1719 json_object
*json
= NULL
;
1720 json_object
*json_ifp
= NULL
;
1721 json_object
*json_row
= NULL
;
1723 now
= pim_time_monotonic_sec();
1726 json
= json_object_new_object();
1728 RB_FOREACH (ifp
, if_name_head
, &pim
->vrf
->ifaces_by_name
) {
1729 pim_ifp
= ifp
->info
;
1734 if (pim_ifp
->pim_sock_fd
< 0)
1737 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
1739 pim_inet4_dump("<src?>", neigh
->source_addr
,
1740 neigh_src_str
, sizeof(neigh_src_str
));
1743 * The user can specify either the interface name or the
1745 * If this pim_ifp matches neither then skip.
1747 if (strcmp(neighbor
, "detail")
1748 && strcmp(neighbor
, ifp
->name
)
1749 && strcmp(neighbor
, neigh_src_str
))
1753 pim_time_uptime(uptime
, sizeof(uptime
),
1754 now
- neigh
->creation
);
1755 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
1756 neigh
->t_expire_timer
);
1758 option_address_list
= 0;
1759 option_dr_priority
= 0;
1760 option_generation_id
= 0;
1761 option_holdtime
= 0;
1762 option_lan_prune_delay
= 0;
1765 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1766 PIM_OPTION_MASK_ADDRESS_LIST
))
1767 option_address_list
= 1;
1769 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1770 PIM_OPTION_MASK_DR_PRIORITY
))
1771 option_dr_priority
= 1;
1773 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1774 PIM_OPTION_MASK_GENERATION_ID
))
1775 option_generation_id
= 1;
1777 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1778 PIM_OPTION_MASK_HOLDTIME
))
1779 option_holdtime
= 1;
1781 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1782 PIM_OPTION_MASK_LAN_PRUNE_DELAY
))
1783 option_lan_prune_delay
= 1;
1785 if (PIM_OPTION_IS_SET(
1786 neigh
->hello_options
,
1787 PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION
))
1792 /* Does this ifp live in json? If not create
1794 json_object_object_get_ex(json
, ifp
->name
,
1798 json_ifp
= json_object_new_object();
1799 json_object_pim_ifp_add(json_ifp
, ifp
);
1800 json_object_object_add(json
, ifp
->name
,
1804 json_row
= json_object_new_object();
1805 json_object_string_add(json_row
, "interface",
1807 json_object_string_add(json_row
, "address",
1809 json_object_string_add(json_row
, "upTime",
1811 json_object_string_add(json_row
, "holdtime",
1813 json_object_int_add(json_row
, "drPriority",
1814 neigh
->dr_priority
);
1815 json_object_int_add(json_row
, "generationId",
1816 neigh
->generation_id
);
1818 if (option_address_list
)
1819 json_object_boolean_true_add(
1821 "helloOptionAddressList");
1823 if (option_dr_priority
)
1824 json_object_boolean_true_add(
1826 "helloOptionDrPriority");
1828 if (option_generation_id
)
1829 json_object_boolean_true_add(
1831 "helloOptionGenerationId");
1833 if (option_holdtime
)
1834 json_object_boolean_true_add(
1836 "helloOptionHoldtime");
1838 if (option_lan_prune_delay
)
1839 json_object_boolean_true_add(
1841 "helloOptionLanPruneDelay");
1844 json_object_boolean_true_add(
1845 json_row
, "helloOptionTBit");
1847 json_object_object_add(json_ifp
, neigh_src_str
,
1851 vty_out(vty
, "Interface : %s\n", ifp
->name
);
1852 vty_out(vty
, "Neighbor : %s\n", neigh_src_str
);
1860 " DR Priority : %d\n",
1861 neigh
->dr_priority
);
1863 " Generation ID : %08x\n",
1864 neigh
->generation_id
);
1866 " Override Interval (msec) : %d\n",
1867 neigh
->override_interval_msec
);
1869 " Propagation Delay (msec) : %d\n",
1870 neigh
->propagation_delay_msec
);
1872 " Hello Option - Address List : %s\n",
1873 option_address_list
? "yes" : "no");
1875 " Hello Option - DR Priority : %s\n",
1876 option_dr_priority
? "yes" : "no");
1878 " Hello Option - Generation ID : %s\n",
1879 option_generation_id
? "yes" : "no");
1881 " Hello Option - Holdtime : %s\n",
1882 option_holdtime
? "yes" : "no");
1884 " Hello Option - LAN Prune Delay : %s\n",
1885 option_lan_prune_delay
? "yes" : "no");
1887 " Hello Option - T-bit : %s\n",
1888 option_t_bit
? "yes" : "no");
1889 pim_bfd_show_info(vty
, neigh
->bfd_info
,
1897 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1898 json
, JSON_C_TO_STRING_PRETTY
));
1899 json_object_free(json
);
1902 if (!found_neighbor
)
1904 "%% No such interface or neighbor\n");
1909 static void pim_show_state(struct pim_instance
*pim
, struct vty
*vty
,
1910 const char *src_or_group
, const char *group
,
1913 struct channel_oil
*c_oil
;
1914 struct listnode
*node
;
1915 json_object
*json
= NULL
;
1916 json_object
*json_group
= NULL
;
1917 json_object
*json_ifp_in
= NULL
;
1918 json_object
*json_ifp_out
= NULL
;
1919 json_object
*json_source
= NULL
;
1922 now
= pim_time_monotonic_sec();
1925 json
= json_object_new_object();
1928 "Codes: J -> Pim Join, I -> IGMP Report, S -> Source, * -> Inherited from (*,G)");
1930 "\nInstalled Source Group IIF OIL\n");
1933 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
1934 char grp_str
[INET_ADDRSTRLEN
];
1935 char src_str
[INET_ADDRSTRLEN
];
1936 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
1937 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
1939 struct interface
*ifp_in
;
1942 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
1944 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
1946 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
1949 strcpy(in_ifname
, ifp_in
->name
);
1951 strcpy(in_ifname
, "<iif?>");
1954 if (strcmp(src_or_group
, src_str
)
1955 && strcmp(src_or_group
, grp_str
))
1958 if (group
&& strcmp(group
, grp_str
))
1964 /* Find the group, create it if it doesn't exist */
1965 json_object_object_get_ex(json
, grp_str
, &json_group
);
1968 json_group
= json_object_new_object();
1969 json_object_object_add(json
, grp_str
,
1973 /* Find the source nested under the group, create it if
1974 * it doesn't exist */
1975 json_object_object_get_ex(json_group
, src_str
,
1979 json_source
= json_object_new_object();
1980 json_object_object_add(json_group
, src_str
,
1984 /* Find the inbound interface nested under the source,
1985 * create it if it doesn't exist */
1986 json_object_object_get_ex(json_source
, in_ifname
,
1990 json_ifp_in
= json_object_new_object();
1991 json_object_object_add(json_source
, in_ifname
,
1993 json_object_int_add(json_source
, "Installed",
1995 json_object_int_add(json_source
, "RefCount",
1996 c_oil
->oil_ref_count
);
1997 json_object_int_add(json_source
, "OilListSize",
1999 json_object_int_add(
2000 json_source
, "OilRescan",
2001 c_oil
->oil_inherited_rescan
);
2002 json_object_int_add(json_source
, "LastUsed",
2003 c_oil
->cc
.lastused
);
2004 json_object_int_add(json_source
, "PacketCount",
2006 json_object_int_add(json_source
, "ByteCount",
2008 json_object_int_add(json_source
,
2010 c_oil
->cc
.wrong_if
);
2013 vty_out(vty
, "%-9d %-15s %-15s %-7s ",
2014 c_oil
->installed
, src_str
, grp_str
,
2018 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
2020 struct interface
*ifp_out
;
2021 char oif_uptime
[10];
2024 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
2028 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
2030 oif_uptime
, sizeof(oif_uptime
),
2031 now
- c_oil
->oif_creation
[oif_vif_index
]);
2034 strcpy(out_ifname
, ifp_out
->name
);
2036 strcpy(out_ifname
, "<oif?>");
2039 json_ifp_out
= json_object_new_object();
2040 json_object_string_add(json_ifp_out
, "source",
2042 json_object_string_add(json_ifp_out
, "group",
2044 json_object_string_add(json_ifp_out
,
2047 json_object_string_add(json_ifp_out
,
2048 "outboundInterface",
2050 json_object_int_add(json_ifp_out
, "installed",
2053 json_object_object_add(json_ifp_in
, out_ifname
,
2058 vty_out(vty
, "%s(%c%c%c%c)", out_ifname
,
2059 (c_oil
->oif_flags
[oif_vif_index
]
2060 & PIM_OIF_FLAG_PROTO_IGMP
)
2063 (c_oil
->oif_flags
[oif_vif_index
]
2064 & PIM_OIF_FLAG_PROTO_PIM
)
2067 (c_oil
->oif_flags
[oif_vif_index
]
2068 & PIM_OIF_FLAG_PROTO_SOURCE
)
2071 (c_oil
->oif_flags
[oif_vif_index
]
2072 & PIM_OIF_FLAG_PROTO_STAR
)
2076 vty_out(vty
, ", %s(%c%c%c%c)",
2078 (c_oil
->oif_flags
[oif_vif_index
]
2079 & PIM_OIF_FLAG_PROTO_IGMP
)
2082 (c_oil
->oif_flags
[oif_vif_index
]
2083 & PIM_OIF_FLAG_PROTO_PIM
)
2086 (c_oil
->oif_flags
[oif_vif_index
]
2087 & PIM_OIF_FLAG_PROTO_SOURCE
)
2090 (c_oil
->oif_flags
[oif_vif_index
]
2091 & PIM_OIF_FLAG_PROTO_STAR
)
2103 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2104 json
, JSON_C_TO_STRING_PRETTY
));
2105 json_object_free(json
);
2111 static void pim_show_neighbors(struct pim_instance
*pim
, struct vty
*vty
,
2114 struct listnode
*neighnode
;
2115 struct interface
*ifp
;
2116 struct pim_interface
*pim_ifp
;
2117 struct pim_neighbor
*neigh
;
2121 char neigh_src_str
[INET_ADDRSTRLEN
];
2122 json_object
*json
= NULL
;
2123 json_object
*json_ifp_rows
= NULL
;
2124 json_object
*json_row
= NULL
;
2126 now
= pim_time_monotonic_sec();
2129 json
= json_object_new_object();
2132 "Interface Neighbor Uptime Holdtime DR Pri\n");
2135 RB_FOREACH (ifp
, if_name_head
, &pim
->vrf
->ifaces_by_name
) {
2136 pim_ifp
= ifp
->info
;
2141 if (pim_ifp
->pim_sock_fd
< 0)
2145 json_ifp_rows
= json_object_new_object();
2147 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
2149 pim_inet4_dump("<src?>", neigh
->source_addr
,
2150 neigh_src_str
, sizeof(neigh_src_str
));
2151 pim_time_uptime(uptime
, sizeof(uptime
),
2152 now
- neigh
->creation
);
2153 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
2154 neigh
->t_expire_timer
);
2157 json_row
= json_object_new_object();
2158 json_object_string_add(json_row
, "interface",
2160 json_object_string_add(json_row
, "neighbor",
2162 json_object_string_add(json_row
, "upTime",
2164 json_object_string_add(json_row
, "holdTime",
2166 json_object_int_add(json_row
, "holdTimeMax",
2168 json_object_int_add(json_row
, "drPriority",
2169 neigh
->dr_priority
);
2170 json_object_object_add(json_ifp_rows
,
2171 neigh_src_str
, json_row
);
2174 vty_out(vty
, "%-9s %15s %8s %8s %6d\n",
2175 ifp
->name
, neigh_src_str
, uptime
,
2176 expire
, neigh
->dr_priority
);
2181 json_object_object_add(json
, ifp
->name
, json_ifp_rows
);
2182 json_ifp_rows
= NULL
;
2187 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2188 json
, JSON_C_TO_STRING_PRETTY
));
2189 json_object_free(json
);
2193 static void pim_show_neighbors_secondary(struct pim_instance
*pim
,
2196 struct interface
*ifp
;
2199 "Interface Address Neighbor Secondary \n");
2201 RB_FOREACH (ifp
, if_name_head
, &pim
->vrf
->ifaces_by_name
) {
2202 struct pim_interface
*pim_ifp
;
2203 struct in_addr ifaddr
;
2204 struct listnode
*neighnode
;
2205 struct pim_neighbor
*neigh
;
2207 pim_ifp
= ifp
->info
;
2212 if (pim_ifp
->pim_sock_fd
< 0)
2215 ifaddr
= pim_ifp
->primary_address
;
2217 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
2219 char neigh_src_str
[INET_ADDRSTRLEN
];
2220 struct listnode
*prefix_node
;
2223 if (!neigh
->prefix_list
)
2226 pim_inet4_dump("<src?>", neigh
->source_addr
,
2227 neigh_src_str
, sizeof(neigh_src_str
));
2229 for (ALL_LIST_ELEMENTS_RO(neigh
->prefix_list
,
2231 char neigh_sec_str
[PREFIX2STR_BUFFER
];
2233 prefix2str(p
, neigh_sec_str
,
2234 sizeof(neigh_sec_str
));
2236 vty_out(vty
, "%-9s %-15s %-15s %-15s\n",
2237 ifp
->name
, inet_ntoa(ifaddr
),
2238 neigh_src_str
, neigh_sec_str
);
2244 static void json_object_pim_upstream_add(json_object
*json
,
2245 struct pim_upstream
*up
)
2247 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED
)
2248 json_object_boolean_true_add(json
, "drJoinDesired");
2250 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED
)
2251 json_object_boolean_true_add(json
, "drJoinDesiredUpdated");
2253 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
2254 json_object_boolean_true_add(json
, "firstHopRouter");
2256 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_IGMP
)
2257 json_object_boolean_true_add(json
, "sourceIgmp");
2259 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_PIM
)
2260 json_object_boolean_true_add(json
, "sourcePim");
2262 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_STREAM
)
2263 json_object_boolean_true_add(json
, "sourceStream");
2265 /* XXX: need to print ths flag in the plain text display as well */
2266 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_MSDP
)
2267 json_object_boolean_true_add(json
, "sourceMsdp");
2271 pim_upstream_state2brief_str(enum pim_upstream_state join_state
,
2274 switch (join_state
) {
2275 case PIM_UPSTREAM_NOTJOINED
:
2276 strcpy(state_str
, "NotJ");
2278 case PIM_UPSTREAM_JOINED
:
2279 strcpy(state_str
, "J");
2282 strcpy(state_str
, "Unk");
2287 static const char *pim_reg_state2brief_str(enum pim_reg_state reg_state
,
2290 switch (reg_state
) {
2291 case PIM_REG_NOINFO
:
2292 strcpy(state_str
, "RegNI");
2295 strcpy(state_str
, "RegJ");
2297 case PIM_REG_JOIN_PENDING
:
2299 strcpy(state_str
, "RegP");
2302 strcpy(state_str
, "Unk");
2307 static void pim_show_upstream(struct pim_instance
*pim
, struct vty
*vty
,
2310 struct listnode
*upnode
;
2311 struct pim_upstream
*up
;
2313 json_object
*json
= NULL
;
2314 json_object
*json_group
= NULL
;
2315 json_object
*json_row
= NULL
;
2317 now
= pim_time_monotonic_sec();
2320 json
= json_object_new_object();
2323 "Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt\n");
2325 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
, up
)) {
2326 char src_str
[INET_ADDRSTRLEN
];
2327 char grp_str
[INET_ADDRSTRLEN
];
2329 char join_timer
[10];
2332 char msdp_reg_timer
[10];
2333 char state_str
[PIM_REG_STATE_STR_LEN
];
2335 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2336 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2337 pim_time_uptime(uptime
, sizeof(uptime
),
2338 now
- up
->state_transition
);
2339 pim_time_timer_to_hhmmss(join_timer
, sizeof(join_timer
),
2343 * If we have a J/P timer for the neighbor display that
2345 if (!up
->t_join_timer
) {
2346 struct pim_neighbor
*nbr
;
2348 nbr
= pim_neighbor_find(
2349 up
->rpf
.source_nexthop
.interface
,
2350 up
->rpf
.rpf_addr
.u
.prefix4
);
2352 pim_time_timer_to_hhmmss(join_timer
,
2357 pim_time_timer_to_hhmmss(rs_timer
, sizeof(rs_timer
),
2359 pim_time_timer_to_hhmmss(ka_timer
, sizeof(ka_timer
),
2361 pim_time_timer_to_hhmmss(msdp_reg_timer
, sizeof(msdp_reg_timer
),
2362 up
->t_msdp_reg_timer
);
2364 pim_upstream_state2brief_str(up
->join_state
, state_str
);
2365 if (up
->reg_state
!= PIM_REG_NOINFO
) {
2366 char tmp_str
[PIM_REG_STATE_STR_LEN
];
2368 sprintf(state_str
+ strlen(state_str
), ",%s",
2369 pim_reg_state2brief_str(up
->reg_state
,
2374 json_object_object_get_ex(json
, grp_str
, &json_group
);
2377 json_group
= json_object_new_object();
2378 json_object_object_add(json
, grp_str
,
2382 json_row
= json_object_new_object();
2383 json_object_pim_upstream_add(json_row
, up
);
2384 json_object_string_add(
2385 json_row
, "inboundInterface",
2386 up
->rpf
.source_nexthop
.interface
->name
);
2387 json_object_string_add(json_row
, "source", src_str
);
2388 json_object_string_add(json_row
, "group", grp_str
);
2389 json_object_string_add(json_row
, "state", state_str
);
2390 json_object_string_add(
2391 json_row
, "joinState",
2392 pim_upstream_state2str(up
->join_state
));
2393 json_object_string_add(
2394 json_row
, "regState",
2395 pim_reg_state2str(up
->reg_state
, state_str
));
2396 json_object_string_add(json_row
, "upTime", uptime
);
2397 json_object_string_add(json_row
, "joinTimer",
2399 json_object_string_add(json_row
, "resetTimer",
2401 json_object_string_add(json_row
, "keepaliveTimer",
2403 json_object_string_add(json_row
, "msdpRegTimer",
2405 json_object_int_add(json_row
, "refCount",
2407 json_object_int_add(json_row
, "sptBit", up
->sptbit
);
2408 json_object_object_add(json_group
, src_str
, json_row
);
2411 "%-10s%-15s %-15s %-11s %-8s %-9s %-9s %-9s %6d\n",
2412 up
->rpf
.source_nexthop
.interface
->name
, src_str
,
2413 grp_str
, state_str
, uptime
, join_timer
,
2414 rs_timer
, ka_timer
, up
->ref_count
);
2419 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2420 json
, JSON_C_TO_STRING_PRETTY
));
2421 json_object_free(json
);
2425 static void pim_show_join_desired_helper(struct pim_instance
*pim
,
2427 struct pim_interface
*pim_ifp
,
2428 struct pim_ifchannel
*ch
,
2432 struct pim_upstream
*up
= ch
->upstream
;
2433 json_object
*json_group
= NULL
;
2434 char src_str
[INET_ADDRSTRLEN
];
2435 char grp_str
[INET_ADDRSTRLEN
];
2436 json_object
*json_row
= NULL
;
2438 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2439 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2442 json_object_object_get_ex(json
, grp_str
, &json_group
);
2445 json_group
= json_object_new_object();
2446 json_object_object_add(json
, grp_str
,
2450 json_row
= json_object_new_object();
2451 json_object_pim_upstream_add(json_row
, up
);
2452 json_object_string_add(json_row
, "interface",
2453 ch
->interface
->name
);
2454 json_object_string_add(json_row
, "source", src_str
);
2455 json_object_string_add(json_row
, "group", grp_str
);
2457 if (pim_macro_ch_lost_assert(ch
))
2458 json_object_boolean_true_add(json_row
,
2461 if (pim_macro_chisin_joins(ch
))
2462 json_object_boolean_true_add(json_row
, "joins");
2464 if (pim_macro_chisin_pim_include(ch
))
2465 json_object_boolean_true_add(json_row
,
2468 if (pim_upstream_evaluate_join_desired(pim
, up
))
2469 json_object_boolean_true_add(
2470 json_row
, "evaluateJoinDesired");
2472 json_object_object_add(json_group
, src_str
, json_row
);
2476 "%-9s %-15s %-15s %-10s %-5s %-10s %-11s %-6s\n",
2477 ch
->interface
->name
, src_str
, grp_str
,
2478 pim_macro_ch_lost_assert(ch
) ? "yes" : "no",
2479 pim_macro_chisin_joins(ch
) ? "yes" : "no",
2480 pim_macro_chisin_pim_include(ch
) ? "yes" : "no",
2481 PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(
2485 pim_upstream_evaluate_join_desired(pim
, up
)
2491 static void pim_show_join_desired(struct pim_instance
*pim
, struct vty
*vty
,
2494 struct pim_interface
*pim_ifp
;
2495 struct pim_ifchannel
*ch
;
2496 struct interface
*ifp
;
2498 json_object
*json
= NULL
;
2501 json
= json_object_new_object();
2504 "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD\n");
2506 /* scan per-interface (S,G) state */
2507 RB_FOREACH (ifp
, if_name_head
, &pim
->vrf
->ifaces_by_name
) {
2508 pim_ifp
= ifp
->info
;
2513 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
2514 /* scan all interfaces */
2515 pim_show_join_desired_helper(pim
, vty
,
2522 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2523 json
, JSON_C_TO_STRING_PRETTY
));
2524 json_object_free(json
);
2528 static void pim_show_upstream_rpf(struct pim_instance
*pim
, struct vty
*vty
,
2531 struct listnode
*upnode
;
2532 struct pim_upstream
*up
;
2533 json_object
*json
= NULL
;
2534 json_object
*json_group
= NULL
;
2535 json_object
*json_row
= NULL
;
2538 json
= json_object_new_object();
2541 "Source Group RpfIface RibNextHop RpfAddress \n");
2543 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
, up
)) {
2544 char src_str
[INET_ADDRSTRLEN
];
2545 char grp_str
[INET_ADDRSTRLEN
];
2546 char rpf_nexthop_str
[PREFIX_STRLEN
];
2547 char rpf_addr_str
[PREFIX_STRLEN
];
2548 struct pim_rpf
*rpf
;
2549 const char *rpf_ifname
;
2553 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2554 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2555 pim_addr_dump("<nexthop?>",
2556 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2557 rpf_nexthop_str
, sizeof(rpf_nexthop_str
));
2558 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2559 sizeof(rpf_addr_str
));
2561 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2564 json_object_object_get_ex(json
, grp_str
, &json_group
);
2567 json_group
= json_object_new_object();
2568 json_object_object_add(json
, grp_str
,
2572 json_row
= json_object_new_object();
2573 json_object_pim_upstream_add(json_row
, up
);
2574 json_object_string_add(json_row
, "source", src_str
);
2575 json_object_string_add(json_row
, "group", grp_str
);
2576 json_object_string_add(json_row
, "rpfInterface",
2578 json_object_string_add(json_row
, "ribNexthop",
2580 json_object_string_add(json_row
, "rpfAddress",
2582 json_object_object_add(json_group
, src_str
, json_row
);
2584 vty_out(vty
, "%-15s %-15s %-8s %-15s %-15s\n", src_str
,
2585 grp_str
, rpf_ifname
, rpf_nexthop_str
,
2591 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2592 json
, JSON_C_TO_STRING_PRETTY
));
2593 json_object_free(json
);
2597 static void show_rpf_refresh_stats(struct vty
*vty
, time_t now
,
2600 char refresh_uptime
[10];
2602 pim_time_uptime_begin(refresh_uptime
, sizeof(refresh_uptime
), now
,
2603 qpim_rpf_cache_refresh_last
);
2606 json_object_int_add(json
, "rpfCacheRefreshDelayMsecs",
2607 qpim_rpf_cache_refresh_delay_msec
);
2608 json_object_int_add(
2609 json
, "rpfCacheRefreshTimer",
2610 pim_time_timer_remain_msec(qpim_rpf_cache_refresher
));
2611 json_object_int_add(json
, "rpfCacheRefreshRequests",
2612 qpim_rpf_cache_refresh_requests
);
2613 json_object_int_add(json
, "rpfCacheRefreshEvents",
2614 qpim_rpf_cache_refresh_events
);
2615 json_object_string_add(json
, "rpfCacheRefreshLast",
2617 json_object_int_add(json
, "nexthopLookups",
2618 qpim_nexthop_lookups
);
2619 json_object_int_add(json
, "nexthopLookupsAvoided",
2620 nexthop_lookups_avoided
);
2623 "RPF Cache Refresh Delay: %ld msecs\n"
2624 "RPF Cache Refresh Timer: %ld msecs\n"
2625 "RPF Cache Refresh Requests: %lld\n"
2626 "RPF Cache Refresh Events: %lld\n"
2627 "RPF Cache Refresh Last: %s\n"
2628 "Nexthop Lookups: %lld\n"
2629 "Nexthop Lookups Avoided: %lld\n",
2630 qpim_rpf_cache_refresh_delay_msec
,
2631 pim_time_timer_remain_msec(qpim_rpf_cache_refresher
),
2632 (long long)qpim_rpf_cache_refresh_requests
,
2633 (long long)qpim_rpf_cache_refresh_events
,
2634 refresh_uptime
, (long long)qpim_nexthop_lookups
,
2635 (long long)nexthop_lookups_avoided
);
2639 static void show_scan_oil_stats(struct pim_instance
*pim
, struct vty
*vty
,
2642 char uptime_scan_oil
[10];
2643 char uptime_mroute_add
[10];
2644 char uptime_mroute_del
[10];
2646 pim_time_uptime_begin(uptime_scan_oil
, sizeof(uptime_scan_oil
), now
,
2647 qpim_scan_oil_last
);
2648 pim_time_uptime_begin(uptime_mroute_add
, sizeof(uptime_mroute_add
), now
,
2649 pim
->mroute_add_last
);
2650 pim_time_uptime_begin(uptime_mroute_del
, sizeof(uptime_mroute_del
), now
,
2651 pim
->mroute_del_last
);
2654 "Scan OIL - Last: %s Events: %lld\n"
2655 "MFC Add - Last: %s Events: %lld\n"
2656 "MFC Del - Last: %s Events: %lld\n",
2657 uptime_scan_oil
, (long long)qpim_scan_oil_events
,
2658 uptime_mroute_add
, (long long)pim
->mroute_add_events
,
2659 uptime_mroute_del
, (long long)pim
->mroute_del_events
);
2662 static void pim_show_rpf(struct pim_instance
*pim
, struct vty
*vty
, u_char uj
)
2664 struct listnode
*up_node
;
2665 struct pim_upstream
*up
;
2666 time_t now
= pim_time_monotonic_sec();
2667 json_object
*json
= NULL
;
2668 json_object
*json_group
= NULL
;
2669 json_object
*json_row
= NULL
;
2672 json
= json_object_new_object();
2673 show_rpf_refresh_stats(vty
, now
, json
);
2675 show_rpf_refresh_stats(vty
, now
, json
);
2678 "Source Group RpfIface RpfAddress RibNextHop Metric Pref\n");
2681 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, up_node
, up
)) {
2682 char src_str
[INET_ADDRSTRLEN
];
2683 char grp_str
[INET_ADDRSTRLEN
];
2684 char rpf_addr_str
[PREFIX_STRLEN
];
2685 char rib_nexthop_str
[PREFIX_STRLEN
];
2686 const char *rpf_ifname
;
2687 struct pim_rpf
*rpf
= &up
->rpf
;
2689 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2690 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2691 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2692 sizeof(rpf_addr_str
));
2693 pim_addr_dump("<nexthop?>",
2694 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2695 rib_nexthop_str
, sizeof(rib_nexthop_str
));
2697 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2700 json_object_object_get_ex(json
, grp_str
, &json_group
);
2703 json_group
= json_object_new_object();
2704 json_object_object_add(json
, grp_str
,
2708 json_row
= json_object_new_object();
2709 json_object_string_add(json_row
, "source", src_str
);
2710 json_object_string_add(json_row
, "group", grp_str
);
2711 json_object_string_add(json_row
, "rpfInterface",
2713 json_object_string_add(json_row
, "rpfAddress",
2715 json_object_string_add(json_row
, "ribNexthop",
2717 json_object_int_add(
2718 json_row
, "routeMetric",
2719 rpf
->source_nexthop
.mrib_route_metric
);
2720 json_object_int_add(
2721 json_row
, "routePreference",
2722 rpf
->source_nexthop
.mrib_metric_preference
);
2723 json_object_object_add(json_group
, src_str
, json_row
);
2726 vty_out(vty
, "%-15s %-15s %-8s %-15s %-15s %6d %4d\n",
2727 src_str
, grp_str
, rpf_ifname
, rpf_addr_str
,
2729 rpf
->source_nexthop
.mrib_route_metric
,
2730 rpf
->source_nexthop
.mrib_metric_preference
);
2735 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2736 json
, JSON_C_TO_STRING_PRETTY
));
2737 json_object_free(json
);
2741 struct pnc_cache_walk_data
{
2743 struct pim_instance
*pim
;
2746 static int pim_print_pnc_cache_walkcb(struct hash_backet
*backet
, void *arg
)
2748 struct pim_nexthop_cache
*pnc
= backet
->data
;
2749 struct pnc_cache_walk_data
*cwd
= arg
;
2750 struct vty
*vty
= cwd
->vty
;
2751 struct pim_instance
*pim
= cwd
->pim
;
2752 struct nexthop
*nh_node
= NULL
;
2753 ifindex_t first_ifindex
;
2754 struct interface
*ifp
= NULL
;
2759 for (nh_node
= pnc
->nexthop
; nh_node
; nh_node
= nh_node
->next
) {
2760 first_ifindex
= nh_node
->ifindex
;
2761 ifp
= if_lookup_by_index(first_ifindex
, pim
->vrf_id
);
2763 vty_out(vty
, "%-15s ", inet_ntoa(pnc
->rpf
.rpf_addr
.u
.prefix4
));
2764 vty_out(vty
, "%-14s ", ifp
? ifp
->name
: "NULL");
2765 vty_out(vty
, "%s ", inet_ntoa(nh_node
->gate
.ipv4
));
2771 static void pim_show_nexthop(struct pim_instance
*pim
, struct vty
*vty
)
2773 struct pnc_cache_walk_data cwd
;
2777 vty_out(vty
, "Number of registered addresses: %lu\n",
2778 pim
->rpf_hash
->count
);
2779 vty_out(vty
, "Address Interface Nexthop\n");
2780 vty_out(vty
, "-------------------------------------------\n");
2782 hash_walk(pim
->rpf_hash
, pim_print_pnc_cache_walkcb
, &cwd
);
2785 static void igmp_show_groups(struct pim_instance
*pim
, struct vty
*vty
,
2788 struct interface
*ifp
;
2790 json_object
*json
= NULL
;
2791 json_object
*json_iface
= NULL
;
2792 json_object
*json_row
= NULL
;
2794 now
= pim_time_monotonic_sec();
2797 json
= json_object_new_object();
2800 "Interface Address Group Mode Timer Srcs V Uptime \n");
2802 /* scan interfaces */
2803 RB_FOREACH (ifp
, if_name_head
, &pim
->vrf
->ifaces_by_name
) {
2804 struct pim_interface
*pim_ifp
= ifp
->info
;
2805 struct listnode
*sock_node
;
2806 struct igmp_sock
*igmp
;
2811 /* scan igmp sockets */
2812 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
2814 char ifaddr_str
[INET_ADDRSTRLEN
];
2815 struct listnode
*grpnode
;
2816 struct igmp_group
*grp
;
2818 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
2819 sizeof(ifaddr_str
));
2821 /* scan igmp groups */
2822 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
2824 char group_str
[INET_ADDRSTRLEN
];
2828 pim_inet4_dump("<group?>", grp
->group_addr
,
2829 group_str
, sizeof(group_str
));
2830 pim_time_timer_to_hhmmss(hhmmss
, sizeof(hhmmss
),
2831 grp
->t_group_timer
);
2832 pim_time_uptime(uptime
, sizeof(uptime
),
2833 now
- grp
->group_creation
);
2836 json_object_object_get_ex(
2837 json
, ifp
->name
, &json_iface
);
2841 json_object_new_object();
2842 json_object_pim_ifp_add(
2844 json_object_object_add(
2849 json_row
= json_object_new_object();
2850 json_object_string_add(
2851 json_row
, "source", ifaddr_str
);
2852 json_object_string_add(
2853 json_row
, "group", group_str
);
2855 if (grp
->igmp_version
== 3)
2856 json_object_string_add(
2858 grp
->group_filtermode_isexcl
2862 json_object_string_add(json_row
,
2864 json_object_int_add(
2865 json_row
, "sourcesCount",
2866 grp
->group_source_list
2868 grp
->group_source_list
)
2870 json_object_int_add(json_row
, "version",
2872 json_object_string_add(
2873 json_row
, "uptime", uptime
);
2874 json_object_object_add(json_iface
,
2880 "%-9s %-15s %-15s %4s %8s %4d %d %8s\n",
2881 ifp
->name
, ifaddr_str
,
2883 grp
->igmp_version
== 3
2884 ? (grp
->group_filtermode_isexcl
2889 grp
->group_source_list
2891 grp
->group_source_list
)
2893 grp
->igmp_version
, uptime
);
2895 } /* scan igmp groups */
2896 } /* scan igmp sockets */
2897 } /* scan interfaces */
2900 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2901 json
, JSON_C_TO_STRING_PRETTY
));
2902 json_object_free(json
);
2906 static void igmp_show_group_retransmission(struct pim_instance
*pim
,
2909 struct interface
*ifp
;
2912 "Interface Address Group RetTimer Counter RetSrcs\n");
2914 /* scan interfaces */
2915 RB_FOREACH (ifp
, if_name_head
, &pim
->vrf
->ifaces_by_name
) {
2916 struct pim_interface
*pim_ifp
= ifp
->info
;
2917 struct listnode
*sock_node
;
2918 struct igmp_sock
*igmp
;
2923 /* scan igmp sockets */
2924 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
2926 char ifaddr_str
[INET_ADDRSTRLEN
];
2927 struct listnode
*grpnode
;
2928 struct igmp_group
*grp
;
2930 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
2931 sizeof(ifaddr_str
));
2933 /* scan igmp groups */
2934 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
2936 char group_str
[INET_ADDRSTRLEN
];
2937 char grp_retr_mmss
[10];
2938 struct listnode
*src_node
;
2939 struct igmp_source
*src
;
2940 int grp_retr_sources
= 0;
2942 pim_inet4_dump("<group?>", grp
->group_addr
,
2943 group_str
, sizeof(group_str
));
2944 pim_time_timer_to_mmss(
2945 grp_retr_mmss
, sizeof(grp_retr_mmss
),
2946 grp
->t_group_query_retransmit_timer
);
2949 /* count group sources with retransmission state
2951 for (ALL_LIST_ELEMENTS_RO(
2952 grp
->group_source_list
, src_node
,
2954 if (src
->source_query_retransmit_count
2960 vty_out(vty
, "%-9s %-15s %-15s %-8s %7d %7d\n",
2961 ifp
->name
, ifaddr_str
, group_str
,
2963 grp
->group_specific_query_retransmit_count
,
2966 } /* scan igmp groups */
2967 } /* scan igmp sockets */
2968 } /* scan interfaces */
2971 static void igmp_show_sources(struct pim_instance
*pim
, struct vty
*vty
)
2973 struct interface
*ifp
;
2976 now
= pim_time_monotonic_sec();
2979 "Interface Address Group Source Timer Fwd Uptime \n");
2981 /* scan interfaces */
2982 RB_FOREACH (ifp
, if_name_head
, &pim
->vrf
->ifaces_by_name
) {
2983 struct pim_interface
*pim_ifp
= ifp
->info
;
2984 struct listnode
*sock_node
;
2985 struct igmp_sock
*igmp
;
2990 /* scan igmp sockets */
2991 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
2993 char ifaddr_str
[INET_ADDRSTRLEN
];
2994 struct listnode
*grpnode
;
2995 struct igmp_group
*grp
;
2997 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
2998 sizeof(ifaddr_str
));
3000 /* scan igmp groups */
3001 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3003 char group_str
[INET_ADDRSTRLEN
];
3004 struct listnode
*srcnode
;
3005 struct igmp_source
*src
;
3007 pim_inet4_dump("<group?>", grp
->group_addr
,
3008 group_str
, sizeof(group_str
));
3010 /* scan group sources */
3011 for (ALL_LIST_ELEMENTS_RO(
3012 grp
->group_source_list
, srcnode
,
3014 char source_str
[INET_ADDRSTRLEN
];
3019 "<source?>", src
->source_addr
,
3020 source_str
, sizeof(source_str
));
3022 pim_time_timer_to_mmss(
3024 src
->t_source_timer
);
3027 uptime
, sizeof(uptime
),
3028 now
- src
->source_creation
);
3031 "%-9s %-15s %-15s %-15s %5s %3s %8s\n",
3032 ifp
->name
, ifaddr_str
,
3033 group_str
, source_str
, mmss
,
3034 IGMP_SOURCE_TEST_FORWARDING(
3040 } /* scan group sources */
3041 } /* scan igmp groups */
3042 } /* scan igmp sockets */
3043 } /* scan interfaces */
3046 static void igmp_show_source_retransmission(struct pim_instance
*pim
,
3049 struct interface
*ifp
;
3052 "Interface Address Group Source Counter\n");
3054 /* scan interfaces */
3055 RB_FOREACH (ifp
, if_name_head
, &pim
->vrf
->ifaces_by_name
) {
3056 struct pim_interface
*pim_ifp
= ifp
->info
;
3057 struct listnode
*sock_node
;
3058 struct igmp_sock
*igmp
;
3063 /* scan igmp sockets */
3064 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3066 char ifaddr_str
[INET_ADDRSTRLEN
];
3067 struct listnode
*grpnode
;
3068 struct igmp_group
*grp
;
3070 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3071 sizeof(ifaddr_str
));
3073 /* scan igmp groups */
3074 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3076 char group_str
[INET_ADDRSTRLEN
];
3077 struct listnode
*srcnode
;
3078 struct igmp_source
*src
;
3080 pim_inet4_dump("<group?>", grp
->group_addr
,
3081 group_str
, sizeof(group_str
));
3083 /* scan group sources */
3084 for (ALL_LIST_ELEMENTS_RO(
3085 grp
->group_source_list
, srcnode
,
3087 char source_str
[INET_ADDRSTRLEN
];
3090 "<source?>", src
->source_addr
,
3091 source_str
, sizeof(source_str
));
3094 "%-9s %-15s %-15s %-15s %7d\n",
3095 ifp
->name
, ifaddr_str
,
3096 group_str
, source_str
,
3097 src
->source_query_retransmit_count
);
3099 } /* scan group sources */
3100 } /* scan igmp groups */
3101 } /* scan igmp sockets */
3102 } /* scan interfaces */
3105 static void clear_igmp_interfaces(struct pim_instance
*pim
)
3107 struct interface
*ifp
;
3109 RB_FOREACH (ifp
, if_name_head
, &pim
->vrf
->ifaces_by_name
)
3110 pim_if_addr_del_all_igmp(ifp
);
3112 RB_FOREACH (ifp
, if_name_head
, &pim
->vrf
->ifaces_by_name
)
3113 pim_if_addr_add_all(ifp
);
3116 static void clear_pim_interfaces(struct pim_instance
*pim
)
3118 struct interface
*ifp
;
3120 RB_FOREACH (ifp
, if_name_head
, &pim
->vrf
->ifaces_by_name
) {
3122 pim_neighbor_delete_all(ifp
, "interface cleared");
3127 static void clear_interfaces(struct pim_instance
*pim
)
3129 clear_igmp_interfaces(pim
);
3130 clear_pim_interfaces(pim
);
3133 #define PIM_GET_PIM_INTERFACE(pim_ifp, ifp) \
3134 pim_ifp = ifp->info; \
3137 "%% Enable PIM and/or IGMP on this interface first\n"); \
3138 return CMD_WARNING_CONFIG_FAILED; \
3141 DEFUN (clear_ip_interfaces
,
3142 clear_ip_interfaces_cmd
,
3143 "clear ip interfaces [vrf NAME]",
3146 "Reset interfaces\n"
3150 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3155 clear_interfaces(vrf
->info
);
3160 DEFUN (clear_ip_igmp_interfaces
,
3161 clear_ip_igmp_interfaces_cmd
,
3162 "clear ip igmp [vrf NAME] interfaces",
3167 "Reset IGMP interfaces\n")
3170 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3175 clear_igmp_interfaces(vrf
->info
);
3180 static void mroute_add_all(struct pim_instance
*pim
)
3182 struct listnode
*node
;
3183 struct channel_oil
*c_oil
;
3185 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
3186 if (pim_mroute_add(c_oil
, __PRETTY_FUNCTION__
)) {
3187 /* just log warning */
3188 char source_str
[INET_ADDRSTRLEN
];
3189 char group_str
[INET_ADDRSTRLEN
];
3190 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
,
3191 source_str
, sizeof(source_str
));
3192 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
,
3193 group_str
, sizeof(group_str
));
3194 zlog_warn("%s %s: (S,G)=(%s,%s) failure writing MFC",
3195 __FILE__
, __PRETTY_FUNCTION__
, source_str
,
3201 static void mroute_del_all(struct pim_instance
*pim
)
3203 struct listnode
*node
;
3204 struct channel_oil
*c_oil
;
3206 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
3207 if (pim_mroute_del(c_oil
, __PRETTY_FUNCTION__
)) {
3208 /* just log warning */
3209 char source_str
[INET_ADDRSTRLEN
];
3210 char group_str
[INET_ADDRSTRLEN
];
3211 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
,
3212 source_str
, sizeof(source_str
));
3213 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
,
3214 group_str
, sizeof(group_str
));
3215 zlog_warn("%s %s: (S,G)=(%s,%s) failure clearing MFC",
3216 __FILE__
, __PRETTY_FUNCTION__
, source_str
,
3222 DEFUN (clear_ip_mroute
,
3223 clear_ip_mroute_cmd
,
3224 "clear ip mroute [vrf NAME]",
3227 "Reset multicast routes\n"
3231 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3236 mroute_del_all(vrf
->info
);
3237 mroute_add_all(vrf
->info
);
3242 DEFUN (clear_ip_pim_interfaces
,
3243 clear_ip_pim_interfaces_cmd
,
3244 "clear ip pim [vrf NAME] interfaces",
3249 "Reset PIM interfaces\n")
3252 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3257 clear_pim_interfaces(vrf
->info
);
3262 DEFUN (clear_ip_pim_interface_traffic
,
3263 clear_ip_pim_interface_traffic_cmd
,
3264 "clear ip pim [vrf NAME] interface traffic",
3267 "PIM clear commands\n"
3269 "Reset PIM interfaces\n"
3270 "Reset Protocol Packet counters\n")
3273 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3274 struct interface
*ifp
= NULL
;
3275 struct pim_interface
*pim_ifp
= NULL
;
3280 RB_FOREACH (ifp
, if_name_head
, &vrf
->ifaces_by_name
) {
3281 pim_ifp
= ifp
->info
;
3286 pim_ifp
->pim_ifstat_hello_recv
= 0;
3287 pim_ifp
->pim_ifstat_hello_sent
= 0;
3288 pim_ifp
->pim_ifstat_join_recv
= 0;
3289 pim_ifp
->pim_ifstat_join_send
= 0;
3290 pim_ifp
->pim_ifstat_prune_recv
= 0;
3291 pim_ifp
->pim_ifstat_prune_send
= 0;
3292 pim_ifp
->pim_ifstat_reg_recv
= 0;
3293 pim_ifp
->pim_ifstat_reg_send
= 0;
3294 pim_ifp
->pim_ifstat_reg_stop_recv
= 0;
3295 pim_ifp
->pim_ifstat_reg_stop_send
= 0;
3296 pim_ifp
->pim_ifstat_assert_recv
= 0;
3297 pim_ifp
->pim_ifstat_assert_send
= 0;
3303 DEFUN (clear_ip_pim_oil
,
3304 clear_ip_pim_oil_cmd
,
3305 "clear ip pim [vrf NAME] oil",
3310 "Rescan PIM OIL (output interface list)\n")
3313 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3318 pim_scan_oil(vrf
->info
);
3323 DEFUN (show_ip_igmp_interface
,
3324 show_ip_igmp_interface_cmd
,
3325 "show ip igmp [vrf NAME] interface [detail|WORD] [json]",
3330 "IGMP interface information\n"
3336 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3337 u_char uj
= use_json(argc
, argv
);
3342 if (argv_find(argv
, argc
, "detail", &idx
)
3343 || argv_find(argv
, argc
, "WORD", &idx
))
3344 igmp_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
3346 igmp_show_interfaces(vrf
->info
, vty
, uj
);
3351 DEFUN (show_ip_igmp_interface_vrf_all
,
3352 show_ip_igmp_interface_vrf_all_cmd
,
3353 "show ip igmp vrf all interface [detail|WORD] [json]",
3358 "IGMP interface information\n"
3364 u_char uj
= use_json(argc
, argv
);
3370 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3374 vty_out(vty
, " \"%s\": ", vrf
->name
);
3377 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3378 if (argv_find(argv
, argc
, "detail", &idx
)
3379 || argv_find(argv
, argc
, "WORD", &idx
))
3380 igmp_show_interfaces_single(vrf
->info
, vty
,
3381 argv
[idx
]->arg
, uj
);
3383 igmp_show_interfaces(vrf
->info
, vty
, uj
);
3386 vty_out(vty
, "}\n");
3391 DEFUN (show_ip_igmp_join
,
3392 show_ip_igmp_join_cmd
,
3393 "show ip igmp [vrf NAME] join",
3398 "IGMP static join information\n")
3401 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3406 igmp_show_interface_join(vrf
->info
, vty
);
3411 DEFUN (show_ip_igmp_join_vrf_all
,
3412 show_ip_igmp_join_vrf_all_cmd
,
3413 "show ip igmp vrf all join",
3418 "IGMP static join information\n")
3420 u_char uj
= use_json(argc
, argv
);
3426 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3430 vty_out(vty
, " \"%s\": ", vrf
->name
);
3433 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3434 igmp_show_interface_join(vrf
->info
, vty
);
3437 vty_out(vty
, "}\n");
3442 DEFUN (show_ip_igmp_groups
,
3443 show_ip_igmp_groups_cmd
,
3444 "show ip igmp [vrf NAME] groups [json]",
3453 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3454 u_char uj
= use_json(argc
, argv
);
3459 igmp_show_groups(vrf
->info
, vty
, uj
);
3464 DEFUN (show_ip_igmp_groups_vrf_all
,
3465 show_ip_igmp_groups_vrf_all_cmd
,
3466 "show ip igmp vrf all groups [json]",
3474 u_char uj
= use_json(argc
, argv
);
3480 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3484 vty_out(vty
, " \"%s\": ", vrf
->name
);
3487 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3488 igmp_show_groups(vrf
->info
, vty
, uj
);
3491 vty_out(vty
, "}\n");
3496 DEFUN (show_ip_igmp_groups_retransmissions
,
3497 show_ip_igmp_groups_retransmissions_cmd
,
3498 "show ip igmp [vrf NAME] groups retransmissions",
3504 "IGMP group retransmissions\n")
3507 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3512 igmp_show_group_retransmission(vrf
->info
, vty
);
3517 DEFUN (show_ip_igmp_sources
,
3518 show_ip_igmp_sources_cmd
,
3519 "show ip igmp [vrf NAME] sources",
3527 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3532 igmp_show_sources(vrf
->info
, vty
);
3537 DEFUN (show_ip_igmp_sources_retransmissions
,
3538 show_ip_igmp_sources_retransmissions_cmd
,
3539 "show ip igmp [vrf NAME] sources retransmissions",
3545 "IGMP source retransmissions\n")
3548 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3553 igmp_show_source_retransmission(vrf
->info
, vty
);
3558 DEFUN (show_ip_pim_assert
,
3559 show_ip_pim_assert_cmd
,
3560 "show ip pim [vrf NAME] assert",
3565 "PIM interface assert\n")
3568 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3573 pim_show_assert(vrf
->info
, vty
);
3578 DEFUN (show_ip_pim_assert_internal
,
3579 show_ip_pim_assert_internal_cmd
,
3580 "show ip pim [vrf NAME] assert-internal",
3585 "PIM interface internal assert state\n")
3588 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3593 pim_show_assert_internal(vrf
->info
, vty
);
3598 DEFUN (show_ip_pim_assert_metric
,
3599 show_ip_pim_assert_metric_cmd
,
3600 "show ip pim [vrf NAME] assert-metric",
3605 "PIM interface assert metric\n")
3608 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3613 pim_show_assert_metric(vrf
->info
, vty
);
3618 DEFUN (show_ip_pim_assert_winner_metric
,
3619 show_ip_pim_assert_winner_metric_cmd
,
3620 "show ip pim [vrf NAME] assert-winner-metric",
3625 "PIM interface assert winner metric\n")
3628 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3633 pim_show_assert_winner_metric(vrf
->info
, vty
);
3638 DEFUN (show_ip_pim_interface
,
3639 show_ip_pim_interface_cmd
,
3640 "show ip pim [vrf NAME] interface [detail|WORD] [json]",
3645 "PIM interface information\n"
3651 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3652 u_char uj
= use_json(argc
, argv
);
3657 if (argv_find(argv
, argc
, "WORD", &idx
)
3658 || argv_find(argv
, argc
, "detail", &idx
))
3659 pim_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
3661 pim_show_interfaces(vrf
->info
, vty
, uj
);
3666 DEFUN (show_ip_pim_interface_vrf_all
,
3667 show_ip_pim_interface_vrf_all_cmd
,
3668 "show ip pim vrf all interface [detail|WORD] [json]",
3673 "PIM interface information\n"
3679 u_char uj
= use_json(argc
, argv
);
3685 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3689 vty_out(vty
, " \"%s\": ", vrf
->name
);
3692 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3693 if (argv_find(argv
, argc
, "WORD", &idx
)
3694 || argv_find(argv
, argc
, "detail", &idx
))
3695 pim_show_interfaces_single(vrf
->info
, vty
,
3696 argv
[idx
]->arg
, uj
);
3698 pim_show_interfaces(vrf
->info
, vty
, uj
);
3701 vty_out(vty
, "}\n");
3706 DEFUN (show_ip_pim_join
,
3707 show_ip_pim_join_cmd
,
3708 "show ip pim [vrf NAME] join [json]",
3713 "PIM interface join information\n"
3717 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3718 u_char uj
= use_json(argc
, argv
);
3723 pim_show_join(vrf
->info
, vty
, uj
);
3728 DEFUN (show_ip_pim_join_vrf_all
,
3729 show_ip_pim_join_vrf_all_cmd
,
3730 "show ip pim vrf all join [json]",
3735 "PIM interface join information\n"
3738 u_char uj
= use_json(argc
, argv
);
3744 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3748 vty_out(vty
, " \"%s\": ", vrf
->name
);
3751 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3752 pim_show_join(vrf
->info
, vty
, uj
);
3755 vty_out(vty
, "}\n");
3760 DEFUN (show_ip_pim_local_membership
,
3761 show_ip_pim_local_membership_cmd
,
3762 "show ip pim [vrf NAME] local-membership [json]",
3767 "PIM interface local-membership\n"
3771 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3772 u_char uj
= use_json(argc
, argv
);
3777 pim_show_membership(vrf
->info
, vty
, uj
);
3782 DEFUN (show_ip_pim_neighbor
,
3783 show_ip_pim_neighbor_cmd
,
3784 "show ip pim [vrf NAME] neighbor [detail|WORD] [json]",
3789 "PIM neighbor information\n"
3791 "Name of interface or neighbor\n"
3795 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3796 u_char uj
= use_json(argc
, argv
);
3801 if (argv_find(argv
, argc
, "detail", &idx
)
3802 || argv_find(argv
, argc
, "WORD", &idx
))
3803 pim_show_neighbors_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
3805 pim_show_neighbors(vrf
->info
, vty
, uj
);
3810 DEFUN (show_ip_pim_neighbor_vrf_all
,
3811 show_ip_pim_neighbor_vrf_all_cmd
,
3812 "show ip pim vrf all neighbor [detail|WORD] [json]",
3817 "PIM neighbor information\n"
3819 "Name of interface or neighbor\n"
3823 u_char uj
= use_json(argc
, argv
);
3829 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3833 vty_out(vty
, " \"%s\": ", vrf
->name
);
3836 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3837 if (argv_find(argv
, argc
, "detail", &idx
)
3838 || argv_find(argv
, argc
, "WORD", &idx
))
3839 pim_show_neighbors_single(vrf
->info
, vty
,
3840 argv
[idx
]->arg
, uj
);
3842 pim_show_neighbors(vrf
->info
, vty
, uj
);
3845 vty_out(vty
, "}\n");
3850 DEFUN (show_ip_pim_secondary
,
3851 show_ip_pim_secondary_cmd
,
3852 "show ip pim [vrf NAME] secondary",
3857 "PIM neighbor addresses\n")
3860 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3865 pim_show_neighbors_secondary(vrf
->info
, vty
);
3870 DEFUN (show_ip_pim_state
,
3871 show_ip_pim_state_cmd
,
3872 "show ip pim [vrf NAME] state [A.B.C.D [A.B.C.D]] [json]",
3877 "PIM state information\n"
3878 "Unicast or Multicast address\n"
3879 "Multicast address\n"
3882 const char *src_or_group
= NULL
;
3883 const char *group
= NULL
;
3885 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3886 u_char uj
= use_json(argc
, argv
);
3894 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
3895 src_or_group
= argv
[idx
]->arg
;
3897 group
= argv
[idx
+ 1]->arg
;
3900 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
3905 DEFUN (show_ip_pim_state_vrf_all
,
3906 show_ip_pim_state_vrf_all_cmd
,
3907 "show ip pim vrf all state [A.B.C.D [A.B.C.D]] [json]",
3912 "PIM state information\n"
3913 "Unicast or Multicast address\n"
3914 "Multicast address\n"
3917 const char *src_or_group
= NULL
;
3918 const char *group
= NULL
;
3920 u_char uj
= use_json(argc
, argv
);
3929 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
3930 src_or_group
= argv
[idx
]->arg
;
3932 group
= argv
[idx
+ 1]->arg
;
3935 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3939 vty_out(vty
, " \"%s\": ", vrf
->name
);
3942 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3943 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
3946 vty_out(vty
, "}\n");
3951 DEFUN (show_ip_pim_upstream
,
3952 show_ip_pim_upstream_cmd
,
3953 "show ip pim [vrf NAME] upstream [json]",
3958 "PIM upstream information\n"
3962 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3963 u_char uj
= use_json(argc
, argv
);
3968 pim_show_upstream(vrf
->info
, vty
, uj
);
3973 DEFUN (show_ip_pim_upstream_vrf_all
,
3974 show_ip_pim_upstream_vrf_all_cmd
,
3975 "show ip pim vrf all upstream [json]",
3980 "PIM upstream information\n"
3983 u_char uj
= use_json(argc
, argv
);
3989 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3993 vty_out(vty
, " \"%s\": ", vrf
->name
);
3996 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3997 pim_show_upstream(vrf
->info
, vty
, uj
);
4003 DEFUN (show_ip_pim_upstream_join_desired
,
4004 show_ip_pim_upstream_join_desired_cmd
,
4005 "show ip pim [vrf NAME] upstream-join-desired [json]",
4010 "PIM upstream join-desired\n"
4014 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4015 u_char uj
= use_json(argc
, argv
);
4020 pim_show_join_desired(vrf
->info
, vty
, uj
);
4025 DEFUN (show_ip_pim_upstream_rpf
,
4026 show_ip_pim_upstream_rpf_cmd
,
4027 "show ip pim [vrf NAME] upstream-rpf [json]",
4032 "PIM upstream source rpf\n"
4036 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4037 u_char uj
= use_json(argc
, argv
);
4042 pim_show_upstream_rpf(vrf
->info
, vty
, uj
);
4047 DEFUN (show_ip_pim_rp
,
4049 "show ip pim [vrf NAME] rp-info [json]",
4054 "PIM RP information\n"
4058 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4059 u_char uj
= use_json(argc
, argv
);
4064 pim_rp_show_information(vrf
->info
, vty
, uj
);
4069 DEFUN (show_ip_pim_rp_vrf_all
,
4070 show_ip_pim_rp_vrf_all_cmd
,
4071 "show ip pim vrf all rp-info [json]",
4076 "PIM RP information\n"
4079 u_char uj
= use_json(argc
, argv
);
4085 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4089 vty_out(vty
, " \"%s\": ", vrf
->name
);
4092 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4093 pim_rp_show_information(vrf
->info
, vty
, uj
);
4096 vty_out(vty
, "}\n");
4101 DEFUN (show_ip_pim_rpf
,
4102 show_ip_pim_rpf_cmd
,
4103 "show ip pim [vrf NAME] rpf [json]",
4108 "PIM cached source rpf information\n"
4112 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4113 u_char uj
= use_json(argc
, argv
);
4118 pim_show_rpf(vrf
->info
, vty
, uj
);
4123 DEFUN (show_ip_pim_rpf_vrf_all
,
4124 show_ip_pim_rpf_vrf_all_cmd
,
4125 "show ip pim vrf all rpf [json]",
4130 "PIM cached source rpf information\n"
4133 u_char uj
= use_json(argc
, argv
);
4139 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4143 vty_out(vty
, " \"%s\": ", vrf
->name
);
4146 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4147 pim_show_rpf(vrf
->info
, vty
, uj
);
4150 vty_out(vty
, "}\n");
4155 DEFUN (show_ip_pim_nexthop
,
4156 show_ip_pim_nexthop_cmd
,
4157 "show ip pim [vrf NAME] nexthop",
4162 "PIM cached nexthop rpf information\n")
4165 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4170 pim_show_nexthop(vrf
->info
, vty
);
4175 DEFUN (show_ip_pim_nexthop_lookup
,
4176 show_ip_pim_nexthop_lookup_cmd
,
4177 "show ip pim [vrf NAME] nexthop-lookup A.B.C.D A.B.C.D",
4182 "PIM cached nexthop rpf lookup\n"
4183 "Source/RP address\n"
4184 "Multicast Group address\n")
4186 struct pim_nexthop_cache pnc
;
4187 struct prefix nht_p
;
4189 struct in_addr src_addr
, grp_addr
;
4190 struct in_addr vif_source
;
4191 const char *addr_str
, *addr_str1
;
4193 struct pim_nexthop nexthop
;
4194 char nexthop_addr_str
[PREFIX_STRLEN
];
4195 char grp_str
[PREFIX_STRLEN
];
4197 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4202 argv_find(argv
, argc
, "A.B.C.D", &idx
);
4203 addr_str
= argv
[idx
]->arg
;
4204 result
= inet_pton(AF_INET
, addr_str
, &src_addr
);
4206 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
4207 errno
, safe_strerror(errno
));
4211 if (pim_is_group_224_4(src_addr
)) {
4213 "Invalid argument. Expected Valid Source Address.\n");
4217 addr_str1
= argv
[idx
+ 1]->arg
;
4218 result
= inet_pton(AF_INET
, addr_str1
, &grp_addr
);
4220 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
4221 errno
, safe_strerror(errno
));
4225 if (!pim_is_group_224_4(grp_addr
)) {
4227 "Invalid argument. Expected Valid Multicast Group Address.\n");
4231 if (!pim_rp_set_upstream_addr(vrf
->info
, &vif_source
, src_addr
,
4235 memset(&pnc
, 0, sizeof(struct pim_nexthop_cache
));
4236 nht_p
.family
= AF_INET
;
4237 nht_p
.prefixlen
= IPV4_MAX_BITLEN
;
4238 nht_p
.u
.prefix4
= vif_source
;
4239 grp
.family
= AF_INET
;
4240 grp
.prefixlen
= IPV4_MAX_BITLEN
;
4241 grp
.u
.prefix4
= grp_addr
;
4242 memset(&nexthop
, 0, sizeof(nexthop
));
4244 if (pim_find_or_track_nexthop(vrf
->info
, &nht_p
, NULL
, NULL
, &pnc
))
4245 pim_ecmp_nexthop_search(vrf
->info
, &pnc
, &nexthop
, &nht_p
, &grp
,
4248 pim_ecmp_nexthop_lookup(vrf
->info
, &nexthop
, vif_source
, &nht_p
,
4251 pim_addr_dump("<grp?>", &grp
, grp_str
, sizeof(grp_str
));
4252 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
4253 nexthop_addr_str
, sizeof(nexthop_addr_str
));
4254 vty_out(vty
, "Group %s --- Nexthop %s Interface %s \n", grp_str
,
4255 nexthop_addr_str
, nexthop
.interface
->name
);
4260 DEFUN (show_ip_pim_interface_traffic
,
4261 show_ip_pim_interface_traffic_cmd
,
4262 "show ip pim [vrf NAME] interface traffic [WORD] [json]",
4267 "PIM interface information\n"
4268 "Protocol Packet counters\n"
4273 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4274 u_char uj
= use_json(argc
, argv
);
4279 if (argv_find(argv
, argc
, "WORD", &idx
))
4280 pim_show_interface_traffic_single(vrf
->info
, vty
,
4281 argv
[idx
]->arg
, uj
);
4283 pim_show_interface_traffic(vrf
->info
, vty
, uj
);
4288 static void show_multicast_interfaces(struct pim_instance
*pim
, struct vty
*vty
)
4290 struct interface
*ifp
;
4295 "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut\n");
4297 RB_FOREACH (ifp
, if_name_head
, &pim
->vrf
->ifaces_by_name
) {
4298 struct pim_interface
*pim_ifp
;
4299 struct in_addr ifaddr
;
4300 struct sioc_vif_req vreq
;
4302 pim_ifp
= ifp
->info
;
4307 memset(&vreq
, 0, sizeof(vreq
));
4308 vreq
.vifi
= pim_ifp
->mroute_vif_index
;
4310 if (ioctl(pim
->mroute_socket
, SIOCGETVIFCNT
, &vreq
)) {
4312 "ioctl(SIOCGETVIFCNT=%lu) failure for interface %s vif_index=%d: errno=%d: %s",
4313 (unsigned long)SIOCGETVIFCNT
, ifp
->name
,
4314 pim_ifp
->mroute_vif_index
, errno
,
4315 safe_strerror(errno
));
4318 ifaddr
= pim_ifp
->primary_address
;
4320 vty_out(vty
, "%-12s %-15s %3d %3d %7lu %7lu %10lu %10lu\n",
4321 ifp
->name
, inet_ntoa(ifaddr
), ifp
->ifindex
,
4322 pim_ifp
->mroute_vif_index
, (unsigned long)vreq
.icount
,
4323 (unsigned long)vreq
.ocount
, (unsigned long)vreq
.ibytes
,
4324 (unsigned long)vreq
.obytes
);
4328 static void pim_cmd_show_ip_multicast_helper(struct pim_instance
*pim
,
4331 struct vrf
*vrf
= pim
->vrf
;
4332 time_t now
= pim_time_monotonic_sec();
4337 vty_out(vty
, "Mroute socket descriptor:");
4339 vty_out(vty
, " %d(%s)\n", pim
->mroute_socket
, vrf
->name
);
4341 pim_time_uptime(uptime
, sizeof(uptime
),
4342 now
- pim
->mroute_socket_creation
);
4343 vty_out(vty
, "Mroute socket uptime: %s\n", uptime
);
4347 pim_zebra_zclient_update(vty
);
4348 pim_zlookup_show_ip_multicast(vty
);
4351 vty_out(vty
, "Maximum highest VifIndex: %d\n", PIM_MAX_USABLE_VIFS
);
4354 vty_out(vty
, "Upstream Join Timer: %d secs\n", qpim_t_periodic
);
4355 vty_out(vty
, "Join/Prune Holdtime: %d secs\n", PIM_JP_HOLDTIME
);
4356 vty_out(vty
, "PIM ECMP: %s\n", qpim_ecmp_enable
? "Enable" : "Disable");
4357 vty_out(vty
, "PIM ECMP Rebalance: %s\n",
4358 qpim_ecmp_rebalance_enable
? "Enable" : "Disable");
4362 show_rpf_refresh_stats(vty
, now
, NULL
);
4366 show_scan_oil_stats(pim
, vty
, now
);
4368 show_multicast_interfaces(pim
, vty
);
4371 DEFUN (show_ip_multicast
,
4372 show_ip_multicast_cmd
,
4373 "show ip multicast [vrf NAME]",
4377 "Multicast global information\n")
4380 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4385 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
4390 DEFUN (show_ip_multicast_vrf_all
,
4391 show_ip_multicast_vrf_all_cmd
,
4392 "show ip multicast vrf all",
4396 "Multicast global information\n")
4398 u_char uj
= use_json(argc
, argv
);
4404 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4408 vty_out(vty
, " \"%s\": ", vrf
->name
);
4411 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4412 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
4415 vty_out(vty
, "}\n");
4420 static void show_mroute(struct pim_instance
*pim
, struct vty
*vty
,
4421 bool fill
, u_char uj
)
4423 struct listnode
*node
;
4424 struct channel_oil
*c_oil
;
4425 struct static_route
*s_route
;
4427 json_object
*json
= NULL
;
4428 json_object
*json_group
= NULL
;
4429 json_object
*json_source
= NULL
;
4430 json_object
*json_oil
= NULL
;
4431 json_object
*json_ifp_out
= NULL
;
4434 char grp_str
[INET_ADDRSTRLEN
];
4435 char src_str
[INET_ADDRSTRLEN
];
4436 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
4437 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
4439 struct interface
*ifp_in
;
4443 json
= json_object_new_object();
4446 "Source Group Proto Input Output TTL Uptime\n");
4449 now
= pim_time_monotonic_sec();
4451 /* print list of PIM and IGMP routes */
4452 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
4455 if (!c_oil
->installed
&& !uj
)
4458 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
4460 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
4462 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
4465 strcpy(in_ifname
, ifp_in
->name
);
4467 strcpy(in_ifname
, "<iif?>");
4471 /* Find the group, create it if it doesn't exist */
4472 json_object_object_get_ex(json
, grp_str
, &json_group
);
4475 json_group
= json_object_new_object();
4476 json_object_object_add(json
, grp_str
,
4480 /* Find the source nested under the group, create it if
4481 * it doesn't exist */
4482 json_object_object_get_ex(json_group
, src_str
,
4486 json_source
= json_object_new_object();
4487 json_object_object_add(json_group
, src_str
,
4491 /* Find the inbound interface nested under the source,
4492 * create it if it doesn't exist */
4493 json_object_int_add(json_source
, "installed",
4495 json_object_int_add(json_source
, "refCount",
4496 c_oil
->oil_ref_count
);
4497 json_object_int_add(json_source
, "oilSize",
4499 json_object_int_add(json_source
, "OilInheritedRescan",
4500 c_oil
->oil_inherited_rescan
);
4501 json_object_string_add(json_source
, "iif", in_ifname
);
4505 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
4507 struct interface
*ifp_out
;
4508 char oif_uptime
[10];
4511 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
4515 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
4517 oif_uptime
, sizeof(oif_uptime
),
4518 now
- c_oil
->oif_creation
[oif_vif_index
]);
4522 strcpy(out_ifname
, ifp_out
->name
);
4524 strcpy(out_ifname
, "<oif?>");
4527 json_ifp_out
= json_object_new_object();
4528 json_object_string_add(json_ifp_out
, "source",
4530 json_object_string_add(json_ifp_out
, "group",
4533 if (c_oil
->oif_flags
[oif_vif_index
]
4534 & PIM_OIF_FLAG_PROTO_PIM
)
4535 json_object_boolean_true_add(
4536 json_ifp_out
, "protocolPim");
4538 if (c_oil
->oif_flags
[oif_vif_index
]
4539 & PIM_OIF_FLAG_PROTO_IGMP
)
4540 json_object_boolean_true_add(
4541 json_ifp_out
, "protocolIgmp");
4543 if (c_oil
->oif_flags
[oif_vif_index
]
4544 & PIM_OIF_FLAG_PROTO_SOURCE
)
4545 json_object_boolean_true_add(
4546 json_ifp_out
, "protocolSource");
4548 if (c_oil
->oif_flags
[oif_vif_index
]
4549 & PIM_OIF_FLAG_PROTO_STAR
)
4550 json_object_boolean_true_add(
4552 "protocolInherited");
4554 json_object_string_add(json_ifp_out
,
4557 json_object_int_add(json_ifp_out
, "iVifI",
4558 c_oil
->oil
.mfcc_parent
);
4559 json_object_string_add(json_ifp_out
,
4560 "outboundInterface",
4562 json_object_int_add(json_ifp_out
, "oVifI",
4564 json_object_int_add(json_ifp_out
, "ttl", ttl
);
4565 json_object_string_add(json_ifp_out
, "upTime",
4568 json_oil
= json_object_new_object();
4569 json_object_object_add(json_source
,
4572 json_object_object_add(json_oil
, out_ifname
,
4575 if (c_oil
->oif_flags
[oif_vif_index
]
4576 & PIM_OIF_FLAG_PROTO_PIM
) {
4577 strcpy(proto
, "PIM");
4580 if (c_oil
->oif_flags
[oif_vif_index
]
4581 & PIM_OIF_FLAG_PROTO_IGMP
) {
4582 strcpy(proto
, "IGMP");
4585 if (c_oil
->oif_flags
[oif_vif_index
]
4586 & PIM_OIF_FLAG_PROTO_SOURCE
) {
4587 strcpy(proto
, "SRC");
4590 if (c_oil
->oif_flags
[oif_vif_index
]
4591 & PIM_OIF_FLAG_PROTO_STAR
) {
4592 strcpy(proto
, "STAR");
4596 "%-15s %-15s %-6s %-10s %-10s %-3d %8s\n",
4597 src_str
, grp_str
, proto
, in_ifname
,
4598 out_ifname
, ttl
, oif_uptime
);
4603 in_ifname
[0] = '\0';
4609 if (!uj
&& !found_oif
) {
4610 vty_out(vty
, "%-15s %-15s %-6s %-10s %-10s %-3d %8s\n",
4611 src_str
, grp_str
, "none", in_ifname
, "none", 0,
4616 /* Print list of static routes */
4617 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
4620 if (!s_route
->c_oil
.installed
)
4623 pim_inet4_dump("<group?>", s_route
->group
, grp_str
,
4625 pim_inet4_dump("<source?>", s_route
->source
, src_str
,
4627 ifp_in
= pim_if_find_by_vif_index(pim
, s_route
->iif
);
4631 strcpy(in_ifname
, ifp_in
->name
);
4633 strcpy(in_ifname
, "<iif?>");
4637 /* Find the group, create it if it doesn't exist */
4638 json_object_object_get_ex(json
, grp_str
, &json_group
);
4641 json_group
= json_object_new_object();
4642 json_object_object_add(json
, grp_str
,
4646 /* Find the source nested under the group, create it if
4647 * it doesn't exist */
4648 json_object_object_get_ex(json_group
, src_str
,
4652 json_source
= json_object_new_object();
4653 json_object_object_add(json_group
, src_str
,
4657 json_object_string_add(json_source
, "iif", in_ifname
);
4660 strcpy(proto
, "STATIC");
4663 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
4665 struct interface
*ifp_out
;
4666 char oif_uptime
[10];
4669 ttl
= s_route
->oif_ttls
[oif_vif_index
];
4673 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
4674 pim_time_uptime(oif_uptime
, sizeof(oif_uptime
),
4676 s_route
->c_oil
.oif_creation
[oif_vif_index
]);
4680 strcpy(out_ifname
, ifp_out
->name
);
4682 strcpy(out_ifname
, "<oif?>");
4685 json_ifp_out
= json_object_new_object();
4686 json_object_string_add(json_ifp_out
, "source",
4688 json_object_string_add(json_ifp_out
, "group",
4690 json_object_boolean_true_add(json_ifp_out
,
4692 json_object_string_add(json_ifp_out
,
4695 json_object_int_add(
4696 json_ifp_out
, "iVifI",
4697 s_route
->c_oil
.oil
.mfcc_parent
);
4698 json_object_string_add(json_ifp_out
,
4699 "outboundInterface",
4701 json_object_int_add(json_ifp_out
, "oVifI",
4703 json_object_int_add(json_ifp_out
, "ttl", ttl
);
4704 json_object_string_add(json_ifp_out
, "upTime",
4707 json_oil
= json_object_new_object();
4708 json_object_object_add(json_source
,
4711 json_object_object_add(json_oil
, out_ifname
,
4715 "%-15s %-15s %-6s %-10s %-10s %-3d %8s %s\n",
4716 src_str
, grp_str
, proto
, in_ifname
,
4717 out_ifname
, ttl
, oif_uptime
,
4719 if (first
&& !fill
) {
4722 in_ifname
[0] = '\0';
4728 if (!uj
&& !found_oif
) {
4730 "%-15s %-15s %-6s %-10s %-10s %-3d %8s %s\n",
4731 src_str
, grp_str
, proto
, in_ifname
, "none", 0,
4732 "--:--:--", pim
->vrf
->name
);
4737 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4738 json
, JSON_C_TO_STRING_PRETTY
));
4739 json_object_free(json
);
4743 DEFUN (show_ip_mroute
,
4745 "show ip mroute [vrf NAME] [fill] [json]",
4750 "Fill in Assumed data\n"
4753 u_char uj
= use_json(argc
, argv
);
4756 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4761 if (argv_find(argv
, argc
, "fill", &idx
))
4764 show_mroute(vrf
->info
, vty
, fill
, uj
);
4768 DEFUN (show_ip_mroute_vrf_all
,
4769 show_ip_mroute_vrf_all_cmd
,
4770 "show ip mroute vrf all [fill] [json]",
4775 "Fill in Assumed data\n"
4778 u_char uj
= use_json(argc
, argv
);
4784 if (argv_find(argv
, argc
, "fill", &idx
))
4789 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4793 vty_out(vty
, " \"%s\": ", vrf
->name
);
4796 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4797 show_mroute(vrf
->info
, vty
, fill
, uj
);
4800 vty_out(vty
, "}\n");
4805 static void show_mroute_count(struct pim_instance
*pim
, struct vty
*vty
)
4807 struct listnode
*node
;
4808 struct channel_oil
*c_oil
;
4809 struct static_route
*s_route
;
4814 "Source Group LastUsed Packets Bytes WrongIf \n");
4816 /* Print PIM and IGMP route counts */
4817 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
4818 char group_str
[INET_ADDRSTRLEN
];
4819 char source_str
[INET_ADDRSTRLEN
];
4821 if (!c_oil
->installed
)
4824 pim_mroute_update_counters(c_oil
);
4826 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, group_str
,
4828 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, source_str
,
4829 sizeof(source_str
));
4831 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
4832 source_str
, group_str
, c_oil
->cc
.lastused
/ 100,
4833 c_oil
->cc
.pktcnt
, c_oil
->cc
.bytecnt
,
4834 c_oil
->cc
.wrong_if
);
4837 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
4838 char group_str
[INET_ADDRSTRLEN
];
4839 char source_str
[INET_ADDRSTRLEN
];
4841 if (!s_route
->c_oil
.installed
)
4844 pim_mroute_update_counters(&s_route
->c_oil
);
4846 pim_inet4_dump("<group?>", s_route
->c_oil
.oil
.mfcc_mcastgrp
,
4847 group_str
, sizeof(group_str
));
4848 pim_inet4_dump("<source?>", s_route
->c_oil
.oil
.mfcc_origin
,
4849 source_str
, sizeof(source_str
));
4851 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
4852 source_str
, group_str
, s_route
->c_oil
.cc
.lastused
,
4853 s_route
->c_oil
.cc
.pktcnt
, s_route
->c_oil
.cc
.bytecnt
,
4854 s_route
->c_oil
.cc
.wrong_if
);
4858 DEFUN (show_ip_mroute_count
,
4859 show_ip_mroute_count_cmd
,
4860 "show ip mroute [vrf NAME] count",
4865 "Route and packet count data\n")
4868 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4873 show_mroute_count(vrf
->info
, vty
);
4877 DEFUN (show_ip_mroute_count_vrf_all
,
4878 show_ip_mroute_count_vrf_all_cmd
,
4879 "show ip mroute vrf all count",
4884 "Route and packet count data\n")
4886 u_char uj
= use_json(argc
, argv
);
4892 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4896 vty_out(vty
, " \"%s\": ", vrf
->name
);
4899 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4900 show_mroute_count(vrf
->info
, vty
);
4903 vty_out(vty
, "}\n");
4910 "show ip rib [vrf NAME] A.B.C.D",
4915 "Unicast address\n")
4918 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4919 struct in_addr addr
;
4920 const char *addr_str
;
4921 struct pim_nexthop nexthop
;
4922 char nexthop_addr_str
[PREFIX_STRLEN
];
4928 memset(&nexthop
, 0, sizeof(nexthop
));
4929 argv_find(argv
, argc
, "A.B.C.D", &idx
);
4930 addr_str
= argv
[idx
]->arg
;
4931 result
= inet_pton(AF_INET
, addr_str
, &addr
);
4933 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
4934 errno
, safe_strerror(errno
));
4938 if (pim_nexthop_lookup(vrf
->info
, &nexthop
, addr
, 0)) {
4940 "Failure querying RIB nexthop for unicast address %s\n",
4946 "Address NextHop Interface Metric Preference\n");
4948 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
4949 nexthop_addr_str
, sizeof(nexthop_addr_str
));
4951 vty_out(vty
, "%-15s %-15s %-9s %6d %10d\n", addr_str
, nexthop_addr_str
,
4952 nexthop
.interface
? nexthop
.interface
->name
: "<ifname?>",
4953 nexthop
.mrib_route_metric
, nexthop
.mrib_metric_preference
);
4958 static void show_ssmpingd(struct pim_instance
*pim
, struct vty
*vty
)
4960 struct listnode
*node
;
4961 struct ssmpingd_sock
*ss
;
4965 "Source Socket Address Port Uptime Requests\n");
4967 if (!pim
->ssmpingd_list
)
4970 now
= pim_time_monotonic_sec();
4972 for (ALL_LIST_ELEMENTS_RO(pim
->ssmpingd_list
, node
, ss
)) {
4973 char source_str
[INET_ADDRSTRLEN
];
4975 struct sockaddr_in bind_addr
;
4976 socklen_t len
= sizeof(bind_addr
);
4977 char bind_addr_str
[INET_ADDRSTRLEN
];
4979 pim_inet4_dump("<src?>", ss
->source_addr
, source_str
,
4980 sizeof(source_str
));
4982 if (pim_socket_getsockname(
4983 ss
->sock_fd
, (struct sockaddr
*)&bind_addr
, &len
)) {
4985 "%% Failure reading socket name for ssmpingd source %s on fd=%d\n",
4986 source_str
, ss
->sock_fd
);
4989 pim_inet4_dump("<addr?>", bind_addr
.sin_addr
, bind_addr_str
,
4990 sizeof(bind_addr_str
));
4991 pim_time_uptime(ss_uptime
, sizeof(ss_uptime
),
4992 now
- ss
->creation
);
4994 vty_out(vty
, "%-15s %6d %-15s %5d %8s %8lld\n", source_str
,
4995 ss
->sock_fd
, bind_addr_str
, ntohs(bind_addr
.sin_port
),
4996 ss_uptime
, (long long)ss
->requests
);
5000 DEFUN (show_ip_ssmpingd
,
5001 show_ip_ssmpingd_cmd
,
5002 "show ip ssmpingd [vrf NAME]",
5009 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5014 show_ssmpingd(vrf
->info
, vty
);
5018 static int pim_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
5019 const char *rp
, const char *group
,
5024 result
= pim_rp_new(pim
, rp
, group
, plist
);
5026 if (result
== PIM_MALLOC_FAIL
) {
5027 vty_out(vty
, "%% Out of memory\n");
5028 return CMD_WARNING_CONFIG_FAILED
;
5031 if (result
== PIM_GROUP_BAD_ADDRESS
) {
5032 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
5033 return CMD_WARNING_CONFIG_FAILED
;
5036 if (result
== PIM_RP_BAD_ADDRESS
) {
5037 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
5038 return CMD_WARNING_CONFIG_FAILED
;
5041 if (result
== PIM_RP_NO_PATH
) {
5042 vty_out(vty
, "%% No Path to RP address specified: %s\n", rp
);
5046 if (result
== PIM_GROUP_OVERLAP
) {
5047 vty_out(vty
, "%% Group range specified cannot exact match another\n");
5048 return CMD_WARNING_CONFIG_FAILED
;
5051 if (result
== PIM_GROUP_PFXLIST_OVERLAP
) {
5053 "%% This group is already covered by a RP prefix-list\n");
5054 return CMD_WARNING_CONFIG_FAILED
;
5057 if (result
== PIM_RP_PFXLIST_IN_USE
) {
5059 "%% The same prefix-list cannot be applied to multiple RPs\n");
5060 return CMD_WARNING_CONFIG_FAILED
;
5066 static int pim_cmd_spt_switchover(struct pim_instance
*pim
,
5067 enum pim_spt_switchover spt
,
5070 pim
->spt
.switchover
= spt
;
5072 switch (pim
->spt
.switchover
) {
5073 case PIM_SPT_IMMEDIATE
:
5075 XFREE(MTYPE_PIM_SPT_PLIST_NAME
, pim
->spt
.plist
);
5077 pim_upstream_add_lhr_star_pimreg(pim
);
5079 case PIM_SPT_INFINITY
:
5080 pim_upstream_remove_lhr_star_pimreg(pim
, plist
);
5083 XFREE(MTYPE_PIM_SPT_PLIST_NAME
, pim
->spt
.plist
);
5087 XSTRDUP(MTYPE_PIM_SPT_PLIST_NAME
, plist
);
5094 DEFUN (ip_pim_spt_switchover_infinity
,
5095 ip_pim_spt_switchover_infinity_cmd
,
5096 "ip pim spt-switchover infinity-and-beyond",
5100 "Never switch to SPT Tree\n")
5102 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5103 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, NULL
);
5106 DEFUN (ip_pim_spt_switchover_infinity_plist
,
5107 ip_pim_spt_switchover_infinity_plist_cmd
,
5108 "ip pim spt-switchover infinity-and-beyond prefix-list WORD",
5112 "Never switch to SPT Tree\n"
5113 "Prefix-List to control which groups to switch\n"
5114 "Prefix-List name\n")
5116 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5117 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, argv
[5]->arg
);
5120 DEFUN (no_ip_pim_spt_switchover_infinity
,
5121 no_ip_pim_spt_switchover_infinity_cmd
,
5122 "no ip pim spt-switchover infinity-and-beyond",
5127 "Never switch to SPT Tree\n")
5129 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5130 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
5133 DEFUN (no_ip_pim_spt_switchover_infinity_plist
,
5134 no_ip_pim_spt_switchover_infinity_plist_cmd
,
5135 "no ip pim spt-switchover infinity-and-beyond prefix-list WORD",
5140 "Never switch to SPT Tree\n"
5141 "Prefix-List to control which groups to switch\n"
5142 "Prefix-List name\n")
5144 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5145 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
5148 DEFUN (ip_pim_joinprune_time
,
5149 ip_pim_joinprune_time_cmd
,
5150 "ip pim join-prune-interval (60-600)",
5152 "pim multicast routing\n"
5153 "Join Prune Send Interval\n"
5156 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5157 qpim_t_periodic
= atoi(argv
[3]->arg
);
5161 DEFUN (no_ip_pim_joinprune_time
,
5162 no_ip_pim_joinprune_time_cmd
,
5163 "no ip pim join-prune-interval (60-600)",
5166 "pim multicast routing\n"
5167 "Join Prune Send Interval\n"
5170 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5171 qpim_t_periodic
= PIM_DEFAULT_T_PERIODIC
;
5175 DEFUN (ip_pim_register_suppress
,
5176 ip_pim_register_suppress_cmd
,
5177 "ip pim register-suppress-time (5-60000)",
5179 "pim multicast routing\n"
5180 "Register Suppress Timer\n"
5183 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5184 qpim_register_suppress_time
= atoi(argv
[3]->arg
);
5188 DEFUN (no_ip_pim_register_suppress
,
5189 no_ip_pim_register_suppress_cmd
,
5190 "no ip pim register-suppress-time (5-60000)",
5193 "pim multicast routing\n"
5194 "Register Suppress Timer\n"
5197 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5198 qpim_register_suppress_time
= PIM_REGISTER_SUPPRESSION_TIME_DEFAULT
;
5202 DEFUN (ip_pim_rp_keep_alive
,
5203 ip_pim_rp_keep_alive_cmd
,
5204 "ip pim rp keep-alive-timer (31-60000)",
5206 "pim multicast routing\n"
5208 "Keep alive Timer\n"
5211 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5212 pim
->rp_keep_alive_time
= atoi(argv
[4]->arg
);
5216 DEFUN (no_ip_pim_rp_keep_alive
,
5217 no_ip_pim_rp_keep_alive_cmd
,
5218 "no 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
= PIM_KEEPALIVE_PERIOD
;
5231 DEFUN (ip_pim_keep_alive
,
5232 ip_pim_keep_alive_cmd
,
5233 "ip pim keep-alive-timer (31-60000)",
5235 "pim multicast routing\n"
5236 "Keep alive Timer\n"
5239 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5240 pim
->keep_alive_time
= atoi(argv
[3]->arg
);
5244 DEFUN (no_ip_pim_keep_alive
,
5245 no_ip_pim_keep_alive_cmd
,
5246 "no ip pim keep-alive-timer (31-60000)",
5249 "pim multicast routing\n"
5250 "Keep alive Timer\n"
5253 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5254 pim
->keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
5258 DEFUN (ip_pim_packets
,
5260 "ip pim packets (1-100)",
5262 "pim multicast routing\n"
5263 "packets to process at one time per fd\n"
5264 "Number of packets\n")
5266 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5267 qpim_packet_process
= atoi(argv
[3]->arg
);
5271 DEFUN (no_ip_pim_packets
,
5272 no_ip_pim_packets_cmd
,
5273 "no ip pim packets (1-100)",
5276 "pim multicast routing\n"
5277 "packets to process at one time per fd\n"
5278 "Number of packets\n")
5280 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5281 qpim_packet_process
= PIM_DEFAULT_PACKET_PROCESS
;
5285 DEFUN (ip_pim_v6_secondary
,
5286 ip_pim_v6_secondary_cmd
,
5287 "ip pim send-v6-secondary",
5289 "pim multicast routing\n"
5290 "Send v6 secondary addresses\n")
5292 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5293 pim
->send_v6_secondary
= 1;
5298 DEFUN (no_ip_pim_v6_secondary
,
5299 no_ip_pim_v6_secondary_cmd
,
5300 "no ip pim send-v6-secondary",
5303 "pim multicast routing\n"
5304 "Send v6 secondary addresses\n")
5306 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5307 pim
->send_v6_secondary
= 0;
5314 "ip pim rp A.B.C.D [A.B.C.D/M]",
5316 "pim multicast routing\n"
5318 "ip address of RP\n"
5319 "Group Address range to cover\n")
5321 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5324 if (argc
== (idx_ipv4
+ 1))
5325 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
5328 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
5329 argv
[idx_ipv4
+ 1]->arg
, NULL
);
5332 DEFUN (ip_pim_rp_prefix_list
,
5333 ip_pim_rp_prefix_list_cmd
,
5334 "ip pim rp A.B.C.D prefix-list WORD",
5336 "pim multicast routing\n"
5338 "ip address of RP\n"
5339 "group prefix-list filter\n"
5340 "Name of a prefix-list\n")
5342 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5343 return pim_rp_cmd_worker(pim
, vty
, argv
[3]->arg
, NULL
, argv
[5]->arg
);
5346 static int pim_no_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
5347 const char *rp
, const char *group
,
5350 int result
= pim_rp_del(pim
, rp
, group
, plist
);
5352 if (result
== PIM_GROUP_BAD_ADDRESS
) {
5353 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
5354 return CMD_WARNING_CONFIG_FAILED
;
5357 if (result
== PIM_RP_BAD_ADDRESS
) {
5358 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
5359 return CMD_WARNING_CONFIG_FAILED
;
5362 if (result
== PIM_RP_NOT_FOUND
) {
5363 vty_out(vty
, "%% Unable to find specified RP\n");
5364 return CMD_WARNING_CONFIG_FAILED
;
5370 DEFUN (no_ip_pim_rp
,
5372 "no ip pim rp A.B.C.D [A.B.C.D/M]",
5375 "pim multicast routing\n"
5377 "ip address of RP\n"
5378 "Group Address range to cover\n")
5380 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5381 int idx_ipv4
= 4, idx_group
= 0;
5383 if (argv_find(argv
, argc
, "A.B.C.D/M", &idx_group
))
5384 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
5385 argv
[idx_group
]->arg
, NULL
);
5387 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
5391 DEFUN (no_ip_pim_rp_prefix_list
,
5392 no_ip_pim_rp_prefix_list_cmd
,
5393 "no ip pim rp A.B.C.D prefix-list WORD",
5396 "pim multicast routing\n"
5398 "ip address of RP\n"
5399 "group prefix-list filter\n"
5400 "Name of a prefix-list\n")
5402 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5403 return pim_no_rp_cmd_worker(pim
, vty
, argv
[4]->arg
, NULL
, argv
[6]->arg
);
5406 static int pim_ssm_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
5409 int result
= pim_ssm_range_set(pim
, pim
->vrf_id
, plist
);
5411 if (result
== PIM_SSM_ERR_NONE
)
5415 case PIM_SSM_ERR_NO_VRF
:
5416 vty_out(vty
, "%% VRF doesn't exist\n");
5418 case PIM_SSM_ERR_DUP
:
5419 vty_out(vty
, "%% duplicate config\n");
5422 vty_out(vty
, "%% ssm range config failed\n");
5425 return CMD_WARNING_CONFIG_FAILED
;
5428 DEFUN (ip_pim_ssm_prefix_list
,
5429 ip_pim_ssm_prefix_list_cmd
,
5430 "ip pim ssm prefix-list WORD",
5432 "pim multicast routing\n"
5433 "Source Specific Multicast\n"
5434 "group range prefix-list filter\n"
5435 "Name of a prefix-list\n")
5437 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5438 return pim_ssm_cmd_worker(pim
, vty
, argv
[4]->arg
);
5441 DEFUN (no_ip_pim_ssm_prefix_list
,
5442 no_ip_pim_ssm_prefix_list_cmd
,
5443 "no ip pim ssm prefix-list",
5446 "pim multicast routing\n"
5447 "Source Specific Multicast\n"
5448 "group range prefix-list filter\n")
5450 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5451 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
5454 DEFUN (no_ip_pim_ssm_prefix_list_name
,
5455 no_ip_pim_ssm_prefix_list_name_cmd
,
5456 "no ip pim ssm prefix-list WORD",
5459 "pim multicast routing\n"
5460 "Source Specific Multicast\n"
5461 "group range prefix-list filter\n"
5462 "Name of a prefix-list\n")
5464 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5465 struct pim_ssm
*ssm
= pim
->ssm_info
;
5467 if (ssm
->plist_name
&& !strcmp(ssm
->plist_name
, argv
[5]->arg
))
5468 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
5470 vty_out(vty
, "%% pim ssm prefix-list %s doesn't exist\n", argv
[5]->arg
);
5472 return CMD_WARNING_CONFIG_FAILED
;
5475 static void ip_pim_ssm_show_group_range(struct pim_instance
*pim
,
5476 struct vty
*vty
, u_char uj
)
5478 struct pim_ssm
*ssm
= pim
->ssm_info
;
5479 const char *range_str
=
5480 ssm
->plist_name
? ssm
->plist_name
: PIM_SSM_STANDARD_RANGE
;
5484 json
= json_object_new_object();
5485 json_object_string_add(json
, "ssmGroups", range_str
);
5486 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5487 json
, JSON_C_TO_STRING_PRETTY
));
5488 json_object_free(json
);
5490 vty_out(vty
, "SSM group range : %s\n", range_str
);
5493 DEFUN (show_ip_pim_ssm_range
,
5494 show_ip_pim_ssm_range_cmd
,
5495 "show ip pim [vrf NAME] group-type [json]",
5504 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5505 u_char uj
= use_json(argc
, argv
);
5510 ip_pim_ssm_show_group_range(vrf
->info
, vty
, uj
);
5515 static void ip_pim_ssm_show_group_type(struct pim_instance
*pim
,
5516 struct vty
*vty
, u_char uj
,
5519 struct in_addr group_addr
;
5520 const char *type_str
;
5523 result
= inet_pton(AF_INET
, group
, &group_addr
);
5525 type_str
= "invalid";
5527 if (pim_is_group_224_4(group_addr
))
5529 pim_is_grp_ssm(pim
, group_addr
) ? "SSM" : "ASM";
5531 type_str
= "not-multicast";
5536 json
= json_object_new_object();
5537 json_object_string_add(json
, "groupType", type_str
);
5538 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5539 json
, JSON_C_TO_STRING_PRETTY
));
5540 json_object_free(json
);
5542 vty_out(vty
, "Group type : %s\n", type_str
);
5545 DEFUN (show_ip_pim_group_type
,
5546 show_ip_pim_group_type_cmd
,
5547 "show ip pim [vrf NAME] group-type A.B.C.D [json]",
5552 "multicast group type\n"
5557 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5558 u_char uj
= use_json(argc
, argv
);
5563 argv_find(argv
, argc
, "A.B.C.D", &idx
);
5564 ip_pim_ssm_show_group_type(vrf
->info
, vty
, uj
, argv
[idx
]->arg
);
5569 DEFUN_HIDDEN (ip_multicast_routing
,
5570 ip_multicast_routing_cmd
,
5571 "ip multicast-routing",
5573 "Enable IP multicast forwarding\n")
5578 DEFUN_HIDDEN (no_ip_multicast_routing
,
5579 no_ip_multicast_routing_cmd
,
5580 "no ip multicast-routing",
5583 "Enable IP multicast forwarding\n")
5586 "Command is Disabled and will be removed in a future version\n");
5592 "ip ssmpingd [A.B.C.D]",
5597 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5600 struct in_addr source_addr
;
5601 const char *source_str
= (argc
== 3) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
5603 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
5605 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
5606 source_str
, errno
, safe_strerror(errno
));
5607 return CMD_WARNING_CONFIG_FAILED
;
5610 result
= pim_ssmpingd_start(pim
, source_addr
);
5612 vty_out(vty
, "%% Failure starting ssmpingd for source %s: %d\n",
5613 source_str
, result
);
5614 return CMD_WARNING_CONFIG_FAILED
;
5620 DEFUN (no_ip_ssmpingd
,
5622 "no ip ssmpingd [A.B.C.D]",
5628 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5631 struct in_addr source_addr
;
5632 const char *source_str
= (argc
== 4) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
5634 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
5636 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
5637 source_str
, errno
, safe_strerror(errno
));
5638 return CMD_WARNING_CONFIG_FAILED
;
5641 result
= pim_ssmpingd_stop(pim
, source_addr
);
5643 vty_out(vty
, "%% Failure stopping ssmpingd for source %s: %d\n",
5644 source_str
, result
);
5645 return CMD_WARNING_CONFIG_FAILED
;
5655 "pim multicast routing\n"
5656 "Enable PIM ECMP \n")
5658 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5659 qpim_ecmp_enable
= 1;
5664 DEFUN (no_ip_pim_ecmp
,
5669 "pim multicast routing\n"
5670 "Disable PIM ECMP \n")
5672 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5673 qpim_ecmp_enable
= 0;
5678 DEFUN (ip_pim_ecmp_rebalance
,
5679 ip_pim_ecmp_rebalance_cmd
,
5680 "ip pim ecmp rebalance",
5682 "pim multicast routing\n"
5683 "Enable PIM ECMP \n"
5684 "Enable PIM ECMP Rebalance\n")
5686 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5687 qpim_ecmp_enable
= 1;
5688 qpim_ecmp_rebalance_enable
= 1;
5693 DEFUN (no_ip_pim_ecmp_rebalance
,
5694 no_ip_pim_ecmp_rebalance_cmd
,
5695 "no ip pim ecmp rebalance",
5698 "pim multicast routing\n"
5699 "Disable PIM ECMP \n"
5700 "Disable PIM ECMP Rebalance\n")
5702 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5703 qpim_ecmp_rebalance_enable
= 0;
5708 static int pim_cmd_igmp_start(struct vty
*vty
, struct interface
*ifp
)
5710 struct pim_interface
*pim_ifp
;
5711 uint8_t need_startup
= 0;
5713 pim_ifp
= ifp
->info
;
5716 pim_ifp
= pim_if_new(ifp
, 1 /* igmp=true */, 0 /* pim=false */);
5718 vty_out(vty
, "Could not enable IGMP on interface %s\n",
5720 return CMD_WARNING_CONFIG_FAILED
;
5724 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
5725 PIM_IF_DO_IGMP(pim_ifp
->options
);
5730 /* 'ip igmp' executed multiple times, with need_startup
5731 avoid multiple if add all and membership refresh */
5733 pim_if_addr_add_all(ifp
);
5734 pim_if_membership_refresh(ifp
);
5740 DEFUN (interface_ip_igmp
,
5741 interface_ip_igmp_cmd
,
5746 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5748 return pim_cmd_igmp_start(vty
, ifp
);
5751 DEFUN (interface_no_ip_igmp
,
5752 interface_no_ip_igmp_cmd
,
5758 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5759 struct pim_interface
*pim_ifp
= ifp
->info
;
5764 PIM_IF_DONT_IGMP(pim_ifp
->options
);
5766 pim_if_membership_clear(ifp
);
5768 pim_if_addr_del_all_igmp(ifp
);
5770 if (!PIM_IF_TEST_PIM(pim_ifp
->options
)) {
5777 DEFUN (interface_ip_igmp_join
,
5778 interface_ip_igmp_join_cmd
,
5779 "ip igmp join A.B.C.D A.B.C.D",
5782 "IGMP join multicast group\n"
5783 "Multicast group address\n"
5786 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5789 const char *group_str
;
5790 const char *source_str
;
5791 struct in_addr group_addr
;
5792 struct in_addr source_addr
;
5796 group_str
= argv
[idx_ipv4
]->arg
;
5797 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
5799 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
5800 errno
, safe_strerror(errno
));
5801 return CMD_WARNING_CONFIG_FAILED
;
5804 /* Source address */
5805 source_str
= argv
[idx_ipv4_2
]->arg
;
5806 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
5808 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
5809 source_str
, errno
, safe_strerror(errno
));
5810 return CMD_WARNING_CONFIG_FAILED
;
5813 CMD_FERR_RETURN(pim_if_igmp_join_add(ifp
, group_addr
, source_addr
),
5814 "Failure joining IGMP group: $ERR");
5819 DEFUN (interface_no_ip_igmp_join
,
5820 interface_no_ip_igmp_join_cmd
,
5821 "no ip igmp join A.B.C.D A.B.C.D",
5825 "IGMP join multicast group\n"
5826 "Multicast group address\n"
5829 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5832 const char *group_str
;
5833 const char *source_str
;
5834 struct in_addr group_addr
;
5835 struct in_addr source_addr
;
5839 group_str
= argv
[idx_ipv4
]->arg
;
5840 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
5842 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
5843 errno
, safe_strerror(errno
));
5844 return CMD_WARNING_CONFIG_FAILED
;
5847 /* Source address */
5848 source_str
= argv
[idx_ipv4_2
]->arg
;
5849 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
5851 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
5852 source_str
, errno
, safe_strerror(errno
));
5853 return CMD_WARNING_CONFIG_FAILED
;
5856 result
= pim_if_igmp_join_del(ifp
, group_addr
, source_addr
);
5859 "%% Failure leaving IGMP group %s source %s on interface %s: %d\n",
5860 group_str
, source_str
, ifp
->name
, result
);
5861 return CMD_WARNING_CONFIG_FAILED
;
5868 CLI reconfiguration affects the interface level (struct pim_interface).
5869 This function propagates the reconfiguration to every active socket
5872 static void igmp_sock_query_interval_reconfig(struct igmp_sock
*igmp
)
5874 struct interface
*ifp
;
5875 struct pim_interface
*pim_ifp
;
5879 /* other querier present? */
5881 if (igmp
->t_other_querier_timer
)
5884 /* this is the querier */
5886 zassert(igmp
->interface
);
5887 zassert(igmp
->interface
->info
);
5889 ifp
= igmp
->interface
;
5890 pim_ifp
= ifp
->info
;
5892 if (PIM_DEBUG_IGMP_TRACE
) {
5893 char ifaddr_str
[INET_ADDRSTRLEN
];
5894 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
5895 sizeof(ifaddr_str
));
5896 zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
5897 __PRETTY_FUNCTION__
, ifaddr_str
, ifp
->name
,
5898 pim_ifp
->igmp_default_query_interval
);
5902 igmp_startup_mode_on() will reset QQI:
5904 igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
5906 igmp_startup_mode_on(igmp
);
5909 static void igmp_sock_query_reschedule(struct igmp_sock
*igmp
)
5911 if (igmp
->t_igmp_query_timer
) {
5912 /* other querier present */
5913 zassert(igmp
->t_igmp_query_timer
);
5914 zassert(!igmp
->t_other_querier_timer
);
5916 pim_igmp_general_query_off(igmp
);
5917 pim_igmp_general_query_on(igmp
);
5919 zassert(igmp
->t_igmp_query_timer
);
5920 zassert(!igmp
->t_other_querier_timer
);
5922 /* this is the querier */
5924 zassert(!igmp
->t_igmp_query_timer
);
5925 zassert(igmp
->t_other_querier_timer
);
5927 pim_igmp_other_querier_timer_off(igmp
);
5928 pim_igmp_other_querier_timer_on(igmp
);
5930 zassert(!igmp
->t_igmp_query_timer
);
5931 zassert(igmp
->t_other_querier_timer
);
5935 static void change_query_interval(struct pim_interface
*pim_ifp
,
5938 struct listnode
*sock_node
;
5939 struct igmp_sock
*igmp
;
5941 pim_ifp
->igmp_default_query_interval
= query_interval
;
5943 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
5944 igmp_sock_query_interval_reconfig(igmp
);
5945 igmp_sock_query_reschedule(igmp
);
5949 static void change_query_max_response_time(struct pim_interface
*pim_ifp
,
5950 int query_max_response_time_dsec
)
5952 struct listnode
*sock_node
;
5953 struct igmp_sock
*igmp
;
5955 pim_ifp
->igmp_query_max_response_time_dsec
=
5956 query_max_response_time_dsec
;
5959 Below we modify socket/group/source timers in order to quickly
5960 reflect the change. Otherwise, those timers would eventually catch
5964 /* scan all sockets */
5965 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
5966 struct listnode
*grp_node
;
5967 struct igmp_group
*grp
;
5969 /* reschedule socket general query */
5970 igmp_sock_query_reschedule(igmp
);
5972 /* scan socket groups */
5973 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grp_node
,
5975 struct listnode
*src_node
;
5976 struct igmp_source
*src
;
5978 /* reset group timers for groups in EXCLUDE mode */
5979 if (grp
->group_filtermode_isexcl
) {
5980 igmp_group_reset_gmi(grp
);
5983 /* scan group sources */
5984 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
,
5987 /* reset source timers for sources with running
5989 if (src
->t_source_timer
) {
5990 igmp_source_reset_gmi(igmp
, grp
, src
);
5997 #define IGMP_QUERY_INTERVAL_MIN (1)
5998 #define IGMP_QUERY_INTERVAL_MAX (1800)
6000 DEFUN (interface_ip_igmp_query_interval
,
6001 interface_ip_igmp_query_interval_cmd
,
6002 "ip igmp query-interval (1-1800)",
6005 IFACE_IGMP_QUERY_INTERVAL_STR
6006 "Query interval in seconds\n")
6008 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6009 struct pim_interface
*pim_ifp
= ifp
->info
;
6011 int query_interval_dsec
;
6015 ret
= pim_cmd_igmp_start(vty
, ifp
);
6016 if (ret
!= CMD_SUCCESS
)
6018 pim_ifp
= ifp
->info
;
6021 query_interval
= atoi(argv
[3]->arg
);
6022 query_interval_dsec
= 10 * query_interval
;
6025 It seems we don't need to check bounds since command.c does it
6026 already, but we verify them anyway for extra safety.
6028 if (query_interval
< IGMP_QUERY_INTERVAL_MIN
) {
6030 "General query interval %d lower than minimum %d\n",
6031 query_interval
, IGMP_QUERY_INTERVAL_MIN
);
6032 return CMD_WARNING_CONFIG_FAILED
;
6034 if (query_interval
> IGMP_QUERY_INTERVAL_MAX
) {
6036 "General query interval %d higher than maximum %d\n",
6037 query_interval
, IGMP_QUERY_INTERVAL_MAX
);
6038 return CMD_WARNING_CONFIG_FAILED
;
6041 if (query_interval_dsec
<= pim_ifp
->igmp_query_max_response_time_dsec
) {
6043 "Can't set general query interval %d dsec <= query max response time %d dsec.\n",
6044 query_interval_dsec
,
6045 pim_ifp
->igmp_query_max_response_time_dsec
);
6046 return CMD_WARNING_CONFIG_FAILED
;
6049 change_query_interval(pim_ifp
, query_interval
);
6054 DEFUN (interface_no_ip_igmp_query_interval
,
6055 interface_no_ip_igmp_query_interval_cmd
,
6056 "no ip igmp query-interval",
6060 IFACE_IGMP_QUERY_INTERVAL_STR
)
6062 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6063 struct pim_interface
*pim_ifp
= ifp
->info
;
6064 int default_query_interval_dsec
;
6069 default_query_interval_dsec
= IGMP_GENERAL_QUERY_INTERVAL
* 10;
6071 if (default_query_interval_dsec
6072 <= pim_ifp
->igmp_query_max_response_time_dsec
) {
6074 "Can't set default general query interval %d dsec <= query max response time %d dsec.\n",
6075 default_query_interval_dsec
,
6076 pim_ifp
->igmp_query_max_response_time_dsec
);
6077 return CMD_WARNING_CONFIG_FAILED
;
6080 change_query_interval(pim_ifp
, IGMP_GENERAL_QUERY_INTERVAL
);
6085 DEFUN (interface_ip_igmp_version
,
6086 interface_ip_igmp_version_cmd
,
6087 "ip igmp version (2-3)",
6091 "IGMP version number\n")
6093 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6094 struct pim_interface
*pim_ifp
= ifp
->info
;
6095 int igmp_version
, old_version
= 0;
6099 ret
= pim_cmd_igmp_start(vty
, ifp
);
6100 if (ret
!= CMD_SUCCESS
)
6102 pim_ifp
= ifp
->info
;
6105 igmp_version
= atoi(argv
[3]->arg
);
6106 old_version
= pim_ifp
->igmp_version
;
6107 pim_ifp
->igmp_version
= igmp_version
;
6109 // Check if IGMP is Enabled otherwise, enable on interface
6110 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
6111 PIM_IF_DO_IGMP(pim_ifp
->options
);
6112 pim_if_addr_add_all(ifp
);
6113 pim_if_membership_refresh(ifp
);
6114 old_version
= igmp_version
; // avoid refreshing membership
6117 /* Current and new version is different refresh existing
6118 membership. Going from 3 -> 2 or 2 -> 3. */
6119 if (old_version
!= igmp_version
)
6120 pim_if_membership_refresh(ifp
);
6125 DEFUN (interface_no_ip_igmp_version
,
6126 interface_no_ip_igmp_version_cmd
,
6127 "no ip igmp version (2-3)",
6132 "IGMP version number\n")
6134 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6135 struct pim_interface
*pim_ifp
= ifp
->info
;
6140 pim_ifp
->igmp_version
= IGMP_DEFAULT_VERSION
;
6145 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
6146 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
6148 DEFUN (interface_ip_igmp_query_max_response_time
,
6149 interface_ip_igmp_query_max_response_time_cmd
,
6150 "ip igmp query-max-response-time (10-250)",
6153 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
6154 "Query response value in deci-seconds\n")
6156 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6157 struct pim_interface
*pim_ifp
= ifp
->info
;
6158 int query_max_response_time
;
6162 ret
= pim_cmd_igmp_start(vty
, ifp
);
6163 if (ret
!= CMD_SUCCESS
)
6165 pim_ifp
= ifp
->info
;
6168 query_max_response_time
= atoi(argv
[3]->arg
);
6170 if (query_max_response_time
6171 >= pim_ifp
->igmp_default_query_interval
* 10) {
6173 "Can't set query max response time %d sec >= general query interval %d sec\n",
6174 query_max_response_time
,
6175 pim_ifp
->igmp_default_query_interval
);
6176 return CMD_WARNING_CONFIG_FAILED
;
6179 change_query_max_response_time(pim_ifp
, query_max_response_time
);
6184 DEFUN (interface_no_ip_igmp_query_max_response_time
,
6185 interface_no_ip_igmp_query_max_response_time_cmd
,
6186 "no ip igmp query-max-response-time (10-250)",
6190 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
6191 "Time for response in deci-seconds\n")
6193 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6194 struct pim_interface
*pim_ifp
= ifp
->info
;
6199 change_query_max_response_time(pim_ifp
,
6200 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
6205 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
6206 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
6208 DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec
,
6209 interface_ip_igmp_query_max_response_time_dsec_cmd
,
6210 "ip igmp query-max-response-time-dsec (10-250)",
6213 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
6214 "Query response value in deciseconds\n")
6216 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6217 struct pim_interface
*pim_ifp
= ifp
->info
;
6218 int query_max_response_time_dsec
;
6219 int default_query_interval_dsec
;
6223 ret
= pim_cmd_igmp_start(vty
, ifp
);
6224 if (ret
!= CMD_SUCCESS
)
6226 pim_ifp
= ifp
->info
;
6229 query_max_response_time_dsec
= atoi(argv
[4]->arg
);
6231 default_query_interval_dsec
= 10 * pim_ifp
->igmp_default_query_interval
;
6233 if (query_max_response_time_dsec
>= default_query_interval_dsec
) {
6235 "Can't set query max response time %d dsec >= general query interval %d dsec\n",
6236 query_max_response_time_dsec
,
6237 default_query_interval_dsec
);
6238 return CMD_WARNING_CONFIG_FAILED
;
6241 change_query_max_response_time(pim_ifp
, query_max_response_time_dsec
);
6246 DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec
,
6247 interface_no_ip_igmp_query_max_response_time_dsec_cmd
,
6248 "no ip igmp query-max-response-time-dsec",
6252 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
)
6254 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6255 struct pim_interface
*pim_ifp
= ifp
->info
;
6260 change_query_max_response_time(pim_ifp
,
6261 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
6266 DEFUN (interface_ip_pim_drprio
,
6267 interface_ip_pim_drprio_cmd
,
6268 "ip pim drpriority (1-4294967295)",
6271 "Set the Designated Router Election Priority\n"
6272 "Value of the new DR Priority\n")
6274 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6276 struct pim_interface
*pim_ifp
= ifp
->info
;
6277 uint32_t old_dr_prio
;
6280 vty_out(vty
, "Please enable PIM on interface, first\n");
6281 return CMD_WARNING_CONFIG_FAILED
;
6284 old_dr_prio
= pim_ifp
->pim_dr_priority
;
6286 pim_ifp
->pim_dr_priority
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
6288 if (old_dr_prio
!= pim_ifp
->pim_dr_priority
) {
6289 if (pim_if_dr_election(ifp
))
6290 pim_hello_restart_now(ifp
);
6296 DEFUN (interface_no_ip_pim_drprio
,
6297 interface_no_ip_pim_drprio_cmd
,
6298 "no ip pim drpriority [(1-4294967295)]",
6302 "Revert the Designated Router Priority to default\n"
6303 "Old Value of the Priority\n")
6305 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6306 struct pim_interface
*pim_ifp
= ifp
->info
;
6309 vty_out(vty
, "Pim not enabled on this interface\n");
6310 return CMD_WARNING_CONFIG_FAILED
;
6313 if (pim_ifp
->pim_dr_priority
!= PIM_DEFAULT_DR_PRIORITY
) {
6314 pim_ifp
->pim_dr_priority
= PIM_DEFAULT_DR_PRIORITY
;
6315 if (pim_if_dr_election(ifp
))
6316 pim_hello_restart_now(ifp
);
6322 static int pim_cmd_interface_add(struct interface
*ifp
)
6324 struct pim_interface
*pim_ifp
= ifp
->info
;
6327 pim_ifp
= pim_if_new(ifp
, 0 /* igmp=false */, 1 /* pim=true */);
6332 PIM_IF_DO_PIM(pim_ifp
->options
);
6335 pim_if_addr_add_all(ifp
);
6336 pim_if_membership_refresh(ifp
);
6340 DEFUN_HIDDEN (interface_ip_pim_ssm
,
6341 interface_ip_pim_ssm_cmd
,
6347 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6349 if (!pim_cmd_interface_add(ifp
)) {
6350 vty_out(vty
, "Could not enable PIM SM on interface\n");
6351 return CMD_WARNING_CONFIG_FAILED
;
6355 "WARN: Enabled PIM SM on interface; configure PIM SSM "
6356 "range if needed\n");
6360 DEFUN (interface_ip_pim_sm
,
6361 interface_ip_pim_sm_cmd
,
6367 struct pim_interface
*pim_ifp
;
6369 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6370 if (!pim_cmd_interface_add(ifp
)) {
6371 vty_out(vty
, "Could not enable PIM SM on interface\n");
6372 return CMD_WARNING_CONFIG_FAILED
;
6375 pim_ifp
= ifp
->info
;
6377 pim_if_create_pimreg(pim_ifp
->pim
);
6382 static int pim_cmd_interface_delete(struct interface
*ifp
)
6384 struct pim_interface
*pim_ifp
= ifp
->info
;
6389 PIM_IF_DONT_PIM(pim_ifp
->options
);
6391 pim_if_membership_clear(ifp
);
6394 pim_sock_delete() removes all neighbors from
6395 pim_ifp->pim_neighbor_list.
6397 pim_sock_delete(ifp
, "pim unconfigured on interface");
6399 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
6400 pim_if_addr_del_all(ifp
);
6407 DEFUN_HIDDEN (interface_no_ip_pim_ssm
,
6408 interface_no_ip_pim_ssm_cmd
,
6415 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6416 if (!pim_cmd_interface_delete(ifp
)) {
6417 vty_out(vty
, "Unable to delete interface information\n");
6418 return CMD_WARNING_CONFIG_FAILED
;
6424 DEFUN (interface_no_ip_pim_sm
,
6425 interface_no_ip_pim_sm_cmd
,
6432 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6433 if (!pim_cmd_interface_delete(ifp
)) {
6434 vty_out(vty
, "Unable to delete interface information\n");
6435 return CMD_WARNING_CONFIG_FAILED
;
6442 DEFUN(interface_ip_pim_boundary_oil
,
6443 interface_ip_pim_boundary_oil_cmd
,
6444 "ip multicast boundary oil WORD",
6446 "Generic multicast configuration options\n"
6447 "Define multicast boundary\n"
6448 "Filter OIL by group using prefix list\n"
6449 "Prefix list to filter OIL with\n")
6451 VTY_DECLVAR_CONTEXT(interface
, iif
);
6452 struct pim_interface
*pim_ifp
;
6455 argv_find(argv
, argc
, "WORD", &idx
);
6457 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6459 if (pim_ifp
->boundary_oil_plist
)
6460 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
6462 pim_ifp
->boundary_oil_plist
=
6463 XSTRDUP(MTYPE_PIM_INTERFACE
, argv
[idx
]->arg
);
6465 /* Interface will be pruned from OIL on next Join */
6469 DEFUN(interface_no_ip_pim_boundary_oil
,
6470 interface_no_ip_pim_boundary_oil_cmd
,
6471 "no ip multicast boundary oil [WORD]",
6474 "Generic multicast configuration options\n"
6475 "Define multicast boundary\n"
6476 "Filter OIL by group using prefix list\n"
6477 "Prefix list to filter OIL with\n")
6479 VTY_DECLVAR_CONTEXT(interface
, iif
);
6480 struct pim_interface
*pim_ifp
;
6483 argv_find(argv
, argc
, "WORD", &idx
);
6485 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6487 if (pim_ifp
->boundary_oil_plist
)
6488 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
6493 DEFUN (interface_ip_mroute
,
6494 interface_ip_mroute_cmd
,
6495 "ip mroute INTERFACE A.B.C.D",
6497 "Add multicast route\n"
6498 "Outgoing interface name\n"
6501 VTY_DECLVAR_CONTEXT(interface
, iif
);
6502 struct pim_interface
*pim_ifp
;
6503 struct pim_instance
*pim
;
6504 int idx_interface
= 2;
6506 struct interface
*oif
;
6507 const char *oifname
;
6508 const char *grp_str
;
6509 struct in_addr grp_addr
;
6510 struct in_addr src_addr
;
6513 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6516 oifname
= argv
[idx_interface
]->arg
;
6517 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6519 vty_out(vty
, "No such interface name %s\n", oifname
);
6523 grp_str
= argv
[idx_ipv4
]->arg
;
6524 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6526 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6527 errno
, safe_strerror(errno
));
6531 src_addr
.s_addr
= INADDR_ANY
;
6533 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6534 vty_out(vty
, "Failed to add route\n");
6541 DEFUN (interface_ip_mroute_source
,
6542 interface_ip_mroute_source_cmd
,
6543 "ip mroute INTERFACE A.B.C.D A.B.C.D",
6545 "Add multicast route\n"
6546 "Outgoing interface name\n"
6550 VTY_DECLVAR_CONTEXT(interface
, iif
);
6551 struct pim_interface
*pim_ifp
;
6552 struct pim_instance
*pim
;
6553 int idx_interface
= 2;
6556 struct interface
*oif
;
6557 const char *oifname
;
6558 const char *grp_str
;
6559 struct in_addr grp_addr
;
6560 const char *src_str
;
6561 struct in_addr src_addr
;
6564 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6567 oifname
= argv
[idx_interface
]->arg
;
6568 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6570 vty_out(vty
, "No such interface name %s\n", oifname
);
6574 grp_str
= argv
[idx_ipv4
]->arg
;
6575 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6577 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6578 errno
, safe_strerror(errno
));
6582 src_str
= argv
[idx_ipv4_2
]->arg
;
6583 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
6585 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
6586 errno
, safe_strerror(errno
));
6590 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6591 vty_out(vty
, "Failed to add route\n");
6598 DEFUN (interface_no_ip_mroute
,
6599 interface_no_ip_mroute_cmd
,
6600 "no ip mroute INTERFACE A.B.C.D",
6603 "Add multicast route\n"
6604 "Outgoing interface name\n"
6607 VTY_DECLVAR_CONTEXT(interface
, iif
);
6608 struct pim_interface
*pim_ifp
;
6609 struct pim_instance
*pim
;
6610 int idx_interface
= 3;
6612 struct interface
*oif
;
6613 const char *oifname
;
6614 const char *grp_str
;
6615 struct in_addr grp_addr
;
6616 struct in_addr src_addr
;
6619 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6622 oifname
= argv
[idx_interface
]->arg
;
6623 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6625 vty_out(vty
, "No such interface name %s\n", oifname
);
6629 grp_str
= argv
[idx_ipv4
]->arg
;
6630 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6632 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6633 errno
, safe_strerror(errno
));
6637 src_addr
.s_addr
= INADDR_ANY
;
6639 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6640 vty_out(vty
, "Failed to remove route\n");
6647 DEFUN (interface_no_ip_mroute_source
,
6648 interface_no_ip_mroute_source_cmd
,
6649 "no ip mroute INTERFACE A.B.C.D A.B.C.D",
6652 "Add multicast route\n"
6653 "Outgoing interface name\n"
6657 VTY_DECLVAR_CONTEXT(interface
, iif
);
6658 struct pim_interface
*pim_ifp
;
6659 struct pim_instance
*pim
;
6660 int idx_interface
= 3;
6663 struct interface
*oif
;
6664 const char *oifname
;
6665 const char *grp_str
;
6666 struct in_addr grp_addr
;
6667 const char *src_str
;
6668 struct in_addr src_addr
;
6671 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6674 oifname
= argv
[idx_interface
]->arg
;
6675 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6677 vty_out(vty
, "No such interface name %s\n", oifname
);
6681 grp_str
= argv
[idx_ipv4
]->arg
;
6682 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6684 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6685 errno
, safe_strerror(errno
));
6689 src_str
= argv
[idx_ipv4_2
]->arg
;
6690 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
6692 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
6693 errno
, safe_strerror(errno
));
6697 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6698 vty_out(vty
, "Failed to remove route\n");
6705 DEFUN (interface_ip_pim_hello
,
6706 interface_ip_pim_hello_cmd
,
6707 "ip pim hello (1-180) [(1-180)]",
6711 IFACE_PIM_HELLO_TIME_STR
6712 IFACE_PIM_HELLO_HOLD_STR
)
6714 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6717 struct pim_interface
*pim_ifp
= ifp
->info
;
6720 if (!pim_cmd_interface_add(ifp
)) {
6721 vty_out(vty
, "Could not enable PIM SM on interface\n");
6722 return CMD_WARNING_CONFIG_FAILED
;
6726 pim_ifp
= ifp
->info
;
6727 pim_ifp
->pim_hello_period
= strtol(argv
[idx_time
]->arg
, NULL
, 10);
6729 if (argc
== idx_hold
+ 1)
6730 pim_ifp
->pim_default_holdtime
=
6731 strtol(argv
[idx_hold
]->arg
, NULL
, 10);
6736 DEFUN (interface_no_ip_pim_hello
,
6737 interface_no_ip_pim_hello_cmd
,
6738 "no ip pim hello [(1-180) (1-180)]",
6743 IFACE_PIM_HELLO_TIME_STR
6744 IFACE_PIM_HELLO_HOLD_STR
)
6746 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6747 struct pim_interface
*pim_ifp
= ifp
->info
;
6750 vty_out(vty
, "Pim not enabled on this interface\n");
6751 return CMD_WARNING_CONFIG_FAILED
;
6754 pim_ifp
->pim_hello_period
= PIM_DEFAULT_HELLO_PERIOD
;
6755 pim_ifp
->pim_default_holdtime
= -1;
6766 PIM_DO_DEBUG_IGMP_EVENTS
;
6767 PIM_DO_DEBUG_IGMP_PACKETS
;
6768 PIM_DO_DEBUG_IGMP_TRACE
;
6772 DEFUN (no_debug_igmp
,
6779 PIM_DONT_DEBUG_IGMP_EVENTS
;
6780 PIM_DONT_DEBUG_IGMP_PACKETS
;
6781 PIM_DONT_DEBUG_IGMP_TRACE
;
6786 DEFUN (debug_igmp_events
,
6787 debug_igmp_events_cmd
,
6788 "debug igmp events",
6791 DEBUG_IGMP_EVENTS_STR
)
6793 PIM_DO_DEBUG_IGMP_EVENTS
;
6797 DEFUN (no_debug_igmp_events
,
6798 no_debug_igmp_events_cmd
,
6799 "no debug igmp events",
6803 DEBUG_IGMP_EVENTS_STR
)
6805 PIM_DONT_DEBUG_IGMP_EVENTS
;
6810 DEFUN (debug_igmp_packets
,
6811 debug_igmp_packets_cmd
,
6812 "debug igmp packets",
6815 DEBUG_IGMP_PACKETS_STR
)
6817 PIM_DO_DEBUG_IGMP_PACKETS
;
6821 DEFUN (no_debug_igmp_packets
,
6822 no_debug_igmp_packets_cmd
,
6823 "no debug igmp packets",
6827 DEBUG_IGMP_PACKETS_STR
)
6829 PIM_DONT_DEBUG_IGMP_PACKETS
;
6834 DEFUN (debug_igmp_trace
,
6835 debug_igmp_trace_cmd
,
6839 DEBUG_IGMP_TRACE_STR
)
6841 PIM_DO_DEBUG_IGMP_TRACE
;
6845 DEFUN (no_debug_igmp_trace
,
6846 no_debug_igmp_trace_cmd
,
6847 "no debug igmp trace",
6851 DEBUG_IGMP_TRACE_STR
)
6853 PIM_DONT_DEBUG_IGMP_TRACE
;
6858 DEFUN (debug_mroute
,
6864 PIM_DO_DEBUG_MROUTE
;
6868 DEFUN (debug_mroute_detail
,
6869 debug_mroute_detail_cmd
,
6870 "debug mroute detail",
6875 PIM_DO_DEBUG_MROUTE_DETAIL
;
6879 DEFUN (no_debug_mroute
,
6880 no_debug_mroute_cmd
,
6886 PIM_DONT_DEBUG_MROUTE
;
6890 DEFUN (no_debug_mroute_detail
,
6891 no_debug_mroute_detail_cmd
,
6892 "no debug mroute detail",
6898 PIM_DONT_DEBUG_MROUTE_DETAIL
;
6902 DEFUN (debug_static
,
6908 PIM_DO_DEBUG_STATIC
;
6912 DEFUN (no_debug_static
,
6913 no_debug_static_cmd
,
6919 PIM_DONT_DEBUG_STATIC
;
6930 PIM_DO_DEBUG_PIM_EVENTS
;
6931 PIM_DO_DEBUG_PIM_PACKETS
;
6932 PIM_DO_DEBUG_PIM_TRACE
;
6933 PIM_DO_DEBUG_MSDP_EVENTS
;
6934 PIM_DO_DEBUG_MSDP_PACKETS
;
6938 DEFUN (no_debug_pim
,
6945 PIM_DONT_DEBUG_PIM_EVENTS
;
6946 PIM_DONT_DEBUG_PIM_PACKETS
;
6947 PIM_DONT_DEBUG_PIM_TRACE
;
6948 PIM_DONT_DEBUG_MSDP_EVENTS
;
6949 PIM_DONT_DEBUG_MSDP_PACKETS
;
6951 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
6952 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
6957 DEFUN (debug_pim_nht
,
6962 "Nexthop Tracking\n")
6964 PIM_DO_DEBUG_PIM_NHT
;
6968 DEFUN (no_debug_pim_nht
,
6969 no_debug_pim_nht_cmd
,
6974 "Nexthop Tracking\n")
6976 PIM_DONT_DEBUG_PIM_NHT
;
6980 DEFUN (debug_pim_nht_rp
,
6981 debug_pim_nht_rp_cmd
,
6985 "Nexthop Tracking\n"
6986 "RP Nexthop Tracking\n")
6988 PIM_DO_DEBUG_PIM_NHT_RP
;
6992 DEFUN (no_debug_pim_nht_rp
,
6993 no_debug_pim_nht_rp_cmd
,
6994 "no debug pim nht rp",
6998 "Nexthop Tracking\n"
6999 "RP Nexthop Tracking\n")
7001 PIM_DONT_DEBUG_PIM_NHT_RP
;
7005 DEFUN (debug_pim_events
,
7006 debug_pim_events_cmd
,
7010 DEBUG_PIM_EVENTS_STR
)
7012 PIM_DO_DEBUG_PIM_EVENTS
;
7016 DEFUN (no_debug_pim_events
,
7017 no_debug_pim_events_cmd
,
7018 "no debug pim events",
7022 DEBUG_PIM_EVENTS_STR
)
7024 PIM_DONT_DEBUG_PIM_EVENTS
;
7028 DEFUN (debug_pim_packets
,
7029 debug_pim_packets_cmd
,
7030 "debug pim packets [<hello|joins|register>]",
7033 DEBUG_PIM_PACKETS_STR
7034 DEBUG_PIM_HELLO_PACKETS_STR
7035 DEBUG_PIM_J_P_PACKETS_STR
7036 DEBUG_PIM_PIM_REG_PACKETS_STR
)
7039 if (argv_find(argv
, argc
, "hello", &idx
)) {
7040 PIM_DO_DEBUG_PIM_HELLO
;
7041 vty_out(vty
, "PIM Hello debugging is on\n");
7042 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
7043 PIM_DO_DEBUG_PIM_J_P
;
7044 vty_out(vty
, "PIM Join/Prune debugging is on\n");
7045 } else if (argv_find(argv
, argc
, "register", &idx
)) {
7046 PIM_DO_DEBUG_PIM_REG
;
7047 vty_out(vty
, "PIM Register debugging is on\n");
7049 PIM_DO_DEBUG_PIM_PACKETS
;
7050 vty_out(vty
, "PIM Packet debugging is on \n");
7055 DEFUN (no_debug_pim_packets
,
7056 no_debug_pim_packets_cmd
,
7057 "no debug pim packets [<hello|joins|register>]",
7061 DEBUG_PIM_PACKETS_STR
7062 DEBUG_PIM_HELLO_PACKETS_STR
7063 DEBUG_PIM_J_P_PACKETS_STR
7064 DEBUG_PIM_PIM_REG_PACKETS_STR
)
7067 if (argv_find(argv
, argc
, "hello", &idx
)) {
7068 PIM_DONT_DEBUG_PIM_HELLO
;
7069 vty_out(vty
, "PIM Hello debugging is off \n");
7070 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
7071 PIM_DONT_DEBUG_PIM_J_P
;
7072 vty_out(vty
, "PIM Join/Prune debugging is off \n");
7073 } else if (argv_find(argv
, argc
, "register", &idx
)) {
7074 PIM_DONT_DEBUG_PIM_REG
;
7075 vty_out(vty
, "PIM Register debugging is off\n");
7077 PIM_DONT_DEBUG_PIM_PACKETS
;
7083 DEFUN (debug_pim_packetdump_send
,
7084 debug_pim_packetdump_send_cmd
,
7085 "debug pim packet-dump send",
7088 DEBUG_PIM_PACKETDUMP_STR
7089 DEBUG_PIM_PACKETDUMP_SEND_STR
)
7091 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND
;
7095 DEFUN (no_debug_pim_packetdump_send
,
7096 no_debug_pim_packetdump_send_cmd
,
7097 "no debug pim packet-dump send",
7101 DEBUG_PIM_PACKETDUMP_STR
7102 DEBUG_PIM_PACKETDUMP_SEND_STR
)
7104 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
7108 DEFUN (debug_pim_packetdump_recv
,
7109 debug_pim_packetdump_recv_cmd
,
7110 "debug pim packet-dump receive",
7113 DEBUG_PIM_PACKETDUMP_STR
7114 DEBUG_PIM_PACKETDUMP_RECV_STR
)
7116 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV
;
7120 DEFUN (no_debug_pim_packetdump_recv
,
7121 no_debug_pim_packetdump_recv_cmd
,
7122 "no debug pim packet-dump receive",
7126 DEBUG_PIM_PACKETDUMP_STR
7127 DEBUG_PIM_PACKETDUMP_RECV_STR
)
7129 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
7133 DEFUN (debug_pim_trace
,
7134 debug_pim_trace_cmd
,
7138 DEBUG_PIM_TRACE_STR
)
7140 PIM_DO_DEBUG_PIM_TRACE
;
7144 DEFUN (debug_pim_trace_detail
,
7145 debug_pim_trace_detail_cmd
,
7146 "debug pim trace detail",
7150 "Detailed Information\n")
7152 PIM_DO_DEBUG_PIM_TRACE_DETAIL
;
7156 DEFUN (no_debug_pim_trace
,
7157 no_debug_pim_trace_cmd
,
7158 "no debug pim trace",
7162 DEBUG_PIM_TRACE_STR
)
7164 PIM_DONT_DEBUG_PIM_TRACE
;
7168 DEFUN (no_debug_pim_trace_detail
,
7169 no_debug_pim_trace_detail_cmd
,
7170 "no debug pim trace detail",
7175 "Detailed Information\n")
7177 PIM_DONT_DEBUG_PIM_TRACE_DETAIL
;
7181 DEFUN (debug_ssmpingd
,
7187 PIM_DO_DEBUG_SSMPINGD
;
7191 DEFUN (no_debug_ssmpingd
,
7192 no_debug_ssmpingd_cmd
,
7193 "no debug ssmpingd",
7198 PIM_DONT_DEBUG_SSMPINGD
;
7202 DEFUN (debug_pim_zebra
,
7203 debug_pim_zebra_cmd
,
7207 DEBUG_PIM_ZEBRA_STR
)
7213 DEFUN (no_debug_pim_zebra
,
7214 no_debug_pim_zebra_cmd
,
7215 "no debug pim zebra",
7219 DEBUG_PIM_ZEBRA_STR
)
7221 PIM_DONT_DEBUG_ZEBRA
;
7231 PIM_DO_DEBUG_MSDP_EVENTS
;
7232 PIM_DO_DEBUG_MSDP_PACKETS
;
7236 DEFUN (no_debug_msdp
,
7243 PIM_DONT_DEBUG_MSDP_EVENTS
;
7244 PIM_DONT_DEBUG_MSDP_PACKETS
;
7248 ALIAS(no_debug_msdp
, undebug_msdp_cmd
, "undebug msdp",
7249 UNDEBUG_STR DEBUG_MSDP_STR
)
7251 DEFUN (debug_msdp_events
,
7252 debug_msdp_events_cmd
,
7253 "debug msdp events",
7256 DEBUG_MSDP_EVENTS_STR
)
7258 PIM_DO_DEBUG_MSDP_EVENTS
;
7262 DEFUN (no_debug_msdp_events
,
7263 no_debug_msdp_events_cmd
,
7264 "no debug msdp events",
7268 DEBUG_MSDP_EVENTS_STR
)
7270 PIM_DONT_DEBUG_MSDP_EVENTS
;
7274 ALIAS(no_debug_msdp_events
, undebug_msdp_events_cmd
, "undebug msdp events",
7275 UNDEBUG_STR DEBUG_MSDP_STR DEBUG_MSDP_EVENTS_STR
)
7277 DEFUN (debug_msdp_packets
,
7278 debug_msdp_packets_cmd
,
7279 "debug msdp packets",
7282 DEBUG_MSDP_PACKETS_STR
)
7284 PIM_DO_DEBUG_MSDP_PACKETS
;
7288 DEFUN (no_debug_msdp_packets
,
7289 no_debug_msdp_packets_cmd
,
7290 "no debug msdp packets",
7294 DEBUG_MSDP_PACKETS_STR
)
7296 PIM_DONT_DEBUG_MSDP_PACKETS
;
7300 ALIAS(no_debug_msdp_packets
, undebug_msdp_packets_cmd
, "undebug msdp packets",
7301 UNDEBUG_STR DEBUG_MSDP_STR DEBUG_MSDP_PACKETS_STR
)
7303 DEFUN_NOSH (show_debugging_pim
,
7304 show_debugging_pim_cmd
,
7305 "show debugging [pim]",
7310 vty_out(vty
, "PIM debugging status\n");
7312 pim_debug_config_write(vty
);
7317 static int interface_pim_use_src_cmd_worker(struct vty
*vty
, const char *source
)
7320 struct in_addr source_addr
;
7321 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7323 result
= inet_pton(AF_INET
, source
, &source_addr
);
7325 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", source
,
7326 errno
, safe_strerror(errno
));
7327 return CMD_WARNING_CONFIG_FAILED
;
7330 result
= pim_update_source_set(ifp
, source_addr
);
7334 case PIM_IFACE_NOT_FOUND
:
7335 vty_out(vty
, "Pim not enabled on this interface\n");
7337 case PIM_UPDATE_SOURCE_DUP
:
7338 vty_out(vty
, "%% Source already set to %s\n", source
);
7341 vty_out(vty
, "%% Source set failed\n");
7344 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7347 DEFUN (interface_pim_use_source
,
7348 interface_pim_use_source_cmd
,
7349 "ip pim use-source A.B.C.D",
7351 "pim multicast routing\n"
7352 "Configure primary IP address\n"
7353 "source ip address\n")
7355 return interface_pim_use_src_cmd_worker(vty
, argv
[3]->arg
);
7358 DEFUN (interface_no_pim_use_source
,
7359 interface_no_pim_use_source_cmd
,
7360 "no ip pim use-source [A.B.C.D]",
7363 "pim multicast routing\n"
7364 "Delete source IP address\n"
7365 "source ip address\n")
7367 return interface_pim_use_src_cmd_worker(vty
, "0.0.0.0");
7375 "Enables BFD support\n")
7377 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7378 struct pim_interface
*pim_ifp
= ifp
->info
;
7379 struct bfd_info
*bfd_info
= NULL
;
7382 if (!pim_cmd_interface_add(ifp
)) {
7383 vty_out(vty
, "Could not enable PIM SM on interface\n");
7387 pim_ifp
= ifp
->info
;
7389 bfd_info
= pim_ifp
->bfd_info
;
7391 if (!bfd_info
|| !CHECK_FLAG(bfd_info
->flags
, BFD_FLAG_PARAM_CFG
))
7392 pim_bfd_if_param_set(ifp
, BFD_DEF_MIN_RX
, BFD_DEF_MIN_TX
,
7393 BFD_DEF_DETECT_MULT
, 1);
7398 DEFUN (no_ip_pim_bfd
,
7404 "Disables BFD support\n")
7406 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7407 struct pim_interface
*pim_ifp
= ifp
->info
;
7410 vty_out(vty
, "Pim not enabled on this interface\n");
7414 if (pim_ifp
->bfd_info
) {
7415 pim_bfd_reg_dereg_all_nbr(ifp
, ZEBRA_BFD_DEST_DEREGISTER
);
7416 bfd_info_free(&(pim_ifp
->bfd_info
));
7422 DEFUN (ip_pim_bfd_param
,
7423 ip_pim_bfd_param_cmd
,
7424 "ip pim bfd (2-255) (50-60000) (50-60000)",
7427 "Enables BFD support\n"
7428 "Detect Multiplier\n"
7429 "Required min receive interval\n"
7430 "Desired min transmit interval\n")
7432 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7434 int idx_number_2
= 4;
7435 int idx_number_3
= 5;
7440 struct pim_interface
*pim_ifp
= ifp
->info
;
7443 if (!pim_cmd_interface_add(ifp
)) {
7444 vty_out(vty
, "Could not enable PIM SM on interface\n");
7449 if ((ret
= bfd_validate_param(
7450 vty
, argv
[idx_number
]->arg
, argv
[idx_number_2
]->arg
,
7451 argv
[idx_number_3
]->arg
, &dm_val
, &rx_val
, &tx_val
))
7455 pim_bfd_if_param_set(ifp
, rx_val
, tx_val
, dm_val
, 0);
7460 ALIAS(no_ip_pim_bfd
, no_ip_pim_bfd_param_cmd
,
7461 "no ip pim bfd (2-255) (50-60000) (50-60000)", NO_STR IP_STR PIM_STR
7462 "Enables BFD support\n"
7463 "Detect Multiplier\n"
7464 "Required min receive interval\n"
7465 "Desired min transmit interval\n")
7467 static int ip_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
7468 const char *peer
, const char *local
)
7470 enum pim_msdp_err result
;
7471 struct in_addr peer_addr
;
7472 struct in_addr local_addr
;
7474 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
7476 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
7477 errno
, safe_strerror(errno
));
7478 return CMD_WARNING_CONFIG_FAILED
;
7481 result
= inet_pton(AF_INET
, local
, &local_addr
);
7483 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", local
,
7484 errno
, safe_strerror(errno
));
7485 return CMD_WARNING_CONFIG_FAILED
;
7488 result
= pim_msdp_peer_add(pim
, peer_addr
, local_addr
, "default",
7491 case PIM_MSDP_ERR_NONE
:
7493 case PIM_MSDP_ERR_OOM
:
7494 vty_out(vty
, "%% Out of memory\n");
7496 case PIM_MSDP_ERR_PEER_EXISTS
:
7497 vty_out(vty
, "%% Peer exists\n");
7499 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
7500 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
7503 vty_out(vty
, "%% peer add failed\n");
7506 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7509 DEFUN_HIDDEN (ip_msdp_peer
,
7511 "ip msdp peer A.B.C.D source A.B.C.D",
7514 "Configure MSDP peer\n"
7516 "Source address for TCP connection\n"
7517 "local ip address\n")
7519 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7520 return ip_msdp_peer_cmd_worker(pim
, vty
, argv
[3]->arg
, argv
[5]->arg
);
7523 static int ip_no_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
7526 enum pim_msdp_err result
;
7527 struct in_addr peer_addr
;
7529 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
7531 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
7532 errno
, safe_strerror(errno
));
7533 return CMD_WARNING_CONFIG_FAILED
;
7536 result
= pim_msdp_peer_del(pim
, peer_addr
);
7538 case PIM_MSDP_ERR_NONE
:
7540 case PIM_MSDP_ERR_NO_PEER
:
7541 vty_out(vty
, "%% Peer does not exist\n");
7544 vty_out(vty
, "%% peer del failed\n");
7547 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7550 DEFUN_HIDDEN (no_ip_msdp_peer
,
7551 no_ip_msdp_peer_cmd
,
7552 "no ip msdp peer A.B.C.D",
7556 "Delete MSDP peer\n"
7557 "peer ip address\n")
7559 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7560 return ip_no_msdp_peer_cmd_worker(pim
, vty
, argv
[4]->arg
);
7563 static int ip_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
7564 struct vty
*vty
, const char *mg
,
7567 enum pim_msdp_err result
;
7568 struct in_addr mbr_ip
;
7570 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
7572 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
7573 errno
, safe_strerror(errno
));
7574 return CMD_WARNING_CONFIG_FAILED
;
7577 result
= pim_msdp_mg_mbr_add(pim
, mg
, mbr_ip
);
7579 case PIM_MSDP_ERR_NONE
:
7581 case PIM_MSDP_ERR_OOM
:
7582 vty_out(vty
, "%% Out of memory\n");
7584 case PIM_MSDP_ERR_MG_MBR_EXISTS
:
7585 vty_out(vty
, "%% mesh-group member exists\n");
7587 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
7588 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
7591 vty_out(vty
, "%% member add failed\n");
7594 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7597 DEFUN (ip_msdp_mesh_group_member
,
7598 ip_msdp_mesh_group_member_cmd
,
7599 "ip msdp mesh-group WORD member A.B.C.D",
7602 "Configure MSDP mesh-group\n"
7604 "mesh group member\n"
7605 "peer ip address\n")
7607 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7608 return ip_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[3]->arg
,
7612 static int ip_no_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
7617 enum pim_msdp_err result
;
7618 struct in_addr mbr_ip
;
7620 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
7622 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
7623 errno
, safe_strerror(errno
));
7624 return CMD_WARNING_CONFIG_FAILED
;
7627 result
= pim_msdp_mg_mbr_del(pim
, mg
, mbr_ip
);
7629 case PIM_MSDP_ERR_NONE
:
7631 case PIM_MSDP_ERR_NO_MG
:
7632 vty_out(vty
, "%% mesh-group does not exist\n");
7634 case PIM_MSDP_ERR_NO_MG_MBR
:
7635 vty_out(vty
, "%% mesh-group member does not exist\n");
7638 vty_out(vty
, "%% mesh-group member del failed\n");
7641 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7643 DEFUN (no_ip_msdp_mesh_group_member
,
7644 no_ip_msdp_mesh_group_member_cmd
,
7645 "no ip msdp mesh-group WORD member A.B.C.D",
7649 "Delete MSDP mesh-group member\n"
7651 "mesh group member\n"
7652 "peer ip address\n")
7654 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7655 return ip_no_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[4]->arg
,
7659 static int ip_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
7660 struct vty
*vty
, const char *mg
,
7663 enum pim_msdp_err result
;
7664 struct in_addr src_ip
;
7666 result
= inet_pton(AF_INET
, src
, &src_ip
);
7668 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", src
,
7669 errno
, safe_strerror(errno
));
7670 return CMD_WARNING_CONFIG_FAILED
;
7673 result
= pim_msdp_mg_src_add(pim
, mg
, src_ip
);
7675 case PIM_MSDP_ERR_NONE
:
7677 case PIM_MSDP_ERR_OOM
:
7678 vty_out(vty
, "%% Out of memory\n");
7680 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
7681 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
7684 vty_out(vty
, "%% source add failed\n");
7687 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7691 DEFUN (ip_msdp_mesh_group_source
,
7692 ip_msdp_mesh_group_source_cmd
,
7693 "ip msdp mesh-group WORD source A.B.C.D",
7696 "Configure MSDP mesh-group\n"
7698 "mesh group local address\n"
7699 "source ip address for the TCP connection\n")
7701 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7702 return ip_msdp_mesh_group_source_cmd_worker(pim
, vty
, argv
[3]->arg
,
7706 static int ip_no_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
7710 enum pim_msdp_err result
;
7712 result
= pim_msdp_mg_src_del(pim
, mg
);
7714 case PIM_MSDP_ERR_NONE
:
7716 case PIM_MSDP_ERR_NO_MG
:
7717 vty_out(vty
, "%% mesh-group does not exist\n");
7720 vty_out(vty
, "%% mesh-group source del failed\n");
7723 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7726 static int ip_no_msdp_mesh_group_cmd_worker(struct pim_instance
*pim
,
7727 struct vty
*vty
, const char *mg
)
7729 enum pim_msdp_err result
;
7731 result
= pim_msdp_mg_del(pim
, mg
);
7733 case PIM_MSDP_ERR_NONE
:
7735 case PIM_MSDP_ERR_NO_MG
:
7736 vty_out(vty
, "%% mesh-group does not exist\n");
7739 vty_out(vty
, "%% mesh-group source del failed\n");
7742 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7745 DEFUN (no_ip_msdp_mesh_group_source
,
7746 no_ip_msdp_mesh_group_source_cmd
,
7747 "no ip msdp mesh-group WORD source [A.B.C.D]",
7751 "Delete MSDP mesh-group source\n"
7753 "mesh group source\n"
7754 "mesh group local address\n")
7756 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7758 return ip_no_msdp_mesh_group_cmd_worker(pim
, vty
, argv
[6]->arg
);
7760 return ip_no_msdp_mesh_group_source_cmd_worker(pim
, vty
,
7764 static void print_empty_json_obj(struct vty
*vty
)
7767 json
= json_object_new_object();
7768 vty_out(vty
, "%s\n",
7769 json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
));
7770 json_object_free(json
);
7773 static void ip_msdp_show_mesh_group(struct pim_instance
*pim
, struct vty
*vty
,
7776 struct listnode
*mbrnode
;
7777 struct pim_msdp_mg_mbr
*mbr
;
7778 struct pim_msdp_mg
*mg
= pim
->msdp
.mg
;
7779 char mbr_str
[INET_ADDRSTRLEN
];
7780 char src_str
[INET_ADDRSTRLEN
];
7781 char state_str
[PIM_MSDP_STATE_STRLEN
];
7782 enum pim_msdp_peer_state state
;
7783 json_object
*json
= NULL
;
7784 json_object
*json_mg_row
= NULL
;
7785 json_object
*json_members
= NULL
;
7786 json_object
*json_row
= NULL
;
7790 print_empty_json_obj(vty
);
7794 pim_inet4_dump("<source?>", mg
->src_ip
, src_str
, sizeof(src_str
));
7796 json
= json_object_new_object();
7797 /* currently there is only one mesh group but we should still
7799 * it a dict with mg-name as key */
7800 json_mg_row
= json_object_new_object();
7801 json_object_string_add(json_mg_row
, "name",
7802 mg
->mesh_group_name
);
7803 json_object_string_add(json_mg_row
, "source", src_str
);
7805 vty_out(vty
, "Mesh group : %s\n", mg
->mesh_group_name
);
7806 vty_out(vty
, " Source : %s\n", src_str
);
7807 vty_out(vty
, " Member State\n");
7810 for (ALL_LIST_ELEMENTS_RO(mg
->mbr_list
, mbrnode
, mbr
)) {
7811 pim_inet4_dump("<mbr?>", mbr
->mbr_ip
, mbr_str
, sizeof(mbr_str
));
7813 state
= mbr
->mp
->state
;
7815 state
= PIM_MSDP_DISABLED
;
7817 pim_msdp_state_dump(state
, state_str
, sizeof(state_str
));
7819 json_row
= json_object_new_object();
7820 json_object_string_add(json_row
, "member", mbr_str
);
7821 json_object_string_add(json_row
, "state", state_str
);
7822 if (!json_members
) {
7823 json_members
= json_object_new_object();
7824 json_object_object_add(json_mg_row
, "members",
7827 json_object_object_add(json_members
, mbr_str
, json_row
);
7829 vty_out(vty
, " %-15s %11s\n", mbr_str
, state_str
);
7834 json_object_object_add(json
, mg
->mesh_group_name
, json_mg_row
);
7835 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
7836 json
, JSON_C_TO_STRING_PRETTY
));
7837 json_object_free(json
);
7841 DEFUN (show_ip_msdp_mesh_group
,
7842 show_ip_msdp_mesh_group_cmd
,
7843 "show ip msdp [vrf NAME] mesh-group [json]",
7848 "MSDP mesh-group information\n"
7851 u_char uj
= use_json(argc
, argv
);
7853 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
7858 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
7863 DEFUN (show_ip_msdp_mesh_group_vrf_all
,
7864 show_ip_msdp_mesh_group_vrf_all_cmd
,
7865 "show ip msdp vrf all mesh-group [json]",
7870 "MSDP mesh-group information\n"
7873 u_char uj
= use_json(argc
, argv
);
7879 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
7883 vty_out(vty
, " \"%s\": ", vrf
->name
);
7886 vty_out(vty
, "VRF: %s\n", vrf
->name
);
7887 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
7890 vty_out(vty
, "}\n");
7895 static void ip_msdp_show_peers(struct pim_instance
*pim
, struct vty
*vty
,
7898 struct listnode
*mpnode
;
7899 struct pim_msdp_peer
*mp
;
7900 char peer_str
[INET_ADDRSTRLEN
];
7901 char local_str
[INET_ADDRSTRLEN
];
7902 char state_str
[PIM_MSDP_STATE_STRLEN
];
7903 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
7905 json_object
*json
= NULL
;
7906 json_object
*json_row
= NULL
;
7910 json
= json_object_new_object();
7913 "Peer Local State Uptime SaCnt\n");
7916 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
7917 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
7918 now
= pim_time_monotonic_sec();
7919 pim_time_uptime(timebuf
, sizeof(timebuf
),
7922 strcpy(timebuf
, "-");
7924 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
7925 pim_inet4_dump("<local?>", mp
->local
, local_str
,
7927 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
7929 json_row
= json_object_new_object();
7930 json_object_string_add(json_row
, "peer", peer_str
);
7931 json_object_string_add(json_row
, "local", local_str
);
7932 json_object_string_add(json_row
, "state", state_str
);
7933 json_object_string_add(json_row
, "upTime", timebuf
);
7934 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
7935 json_object_object_add(json
, peer_str
, json_row
);
7937 vty_out(vty
, "%-15s %15s %11s %8s %6d\n", peer_str
,
7938 local_str
, state_str
, timebuf
, mp
->sa_cnt
);
7943 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
7944 json
, JSON_C_TO_STRING_PRETTY
));
7945 json_object_free(json
);
7949 static void ip_msdp_show_peers_detail(struct pim_instance
*pim
, struct vty
*vty
,
7950 const char *peer
, u_char uj
)
7952 struct listnode
*mpnode
;
7953 struct pim_msdp_peer
*mp
;
7954 char peer_str
[INET_ADDRSTRLEN
];
7955 char local_str
[INET_ADDRSTRLEN
];
7956 char state_str
[PIM_MSDP_STATE_STRLEN
];
7957 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
7958 char katimer
[PIM_MSDP_TIMER_STRLEN
];
7959 char crtimer
[PIM_MSDP_TIMER_STRLEN
];
7960 char holdtimer
[PIM_MSDP_TIMER_STRLEN
];
7962 json_object
*json
= NULL
;
7963 json_object
*json_row
= NULL
;
7966 json
= json_object_new_object();
7969 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
7970 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
7971 if (strcmp(peer
, "detail") && strcmp(peer
, peer_str
))
7974 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
7975 now
= pim_time_monotonic_sec();
7976 pim_time_uptime(timebuf
, sizeof(timebuf
),
7979 strcpy(timebuf
, "-");
7981 pim_inet4_dump("<local?>", mp
->local
, local_str
,
7983 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
7984 pim_time_timer_to_hhmmss(katimer
, sizeof(katimer
),
7986 pim_time_timer_to_hhmmss(crtimer
, sizeof(crtimer
),
7988 pim_time_timer_to_hhmmss(holdtimer
, sizeof(holdtimer
),
7992 json_row
= json_object_new_object();
7993 json_object_string_add(json_row
, "peer", peer_str
);
7994 json_object_string_add(json_row
, "local", local_str
);
7995 json_object_string_add(json_row
, "meshGroupName",
7996 mp
->mesh_group_name
);
7997 json_object_string_add(json_row
, "state", state_str
);
7998 json_object_string_add(json_row
, "upTime", timebuf
);
7999 json_object_string_add(json_row
, "keepAliveTimer",
8001 json_object_string_add(json_row
, "connRetryTimer",
8003 json_object_string_add(json_row
, "holdTimer",
8005 json_object_string_add(json_row
, "lastReset",
8007 json_object_int_add(json_row
, "connAttempts",
8009 json_object_int_add(json_row
, "establishedChanges",
8011 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
8012 json_object_int_add(json_row
, "kaSent", mp
->ka_tx_cnt
);
8013 json_object_int_add(json_row
, "kaRcvd", mp
->ka_rx_cnt
);
8014 json_object_int_add(json_row
, "saSent", mp
->sa_tx_cnt
);
8015 json_object_int_add(json_row
, "saRcvd", mp
->sa_rx_cnt
);
8016 json_object_object_add(json
, peer_str
, json_row
);
8018 vty_out(vty
, "Peer : %s\n", peer_str
);
8019 vty_out(vty
, " Local : %s\n", local_str
);
8020 vty_out(vty
, " Mesh Group : %s\n",
8021 mp
->mesh_group_name
);
8022 vty_out(vty
, " State : %s\n", state_str
);
8023 vty_out(vty
, " Uptime : %s\n", timebuf
);
8025 vty_out(vty
, " Keepalive Timer : %s\n", katimer
);
8026 vty_out(vty
, " Conn Retry Timer : %s\n", crtimer
);
8027 vty_out(vty
, " Hold Timer : %s\n", holdtimer
);
8028 vty_out(vty
, " Last Reset : %s\n",
8030 vty_out(vty
, " Conn Attempts : %d\n",
8032 vty_out(vty
, " Established Changes : %d\n",
8034 vty_out(vty
, " SA Count : %d\n",
8036 vty_out(vty
, " Statistics :\n");
8039 vty_out(vty
, " Keepalives : %10d %10d\n",
8040 mp
->ka_tx_cnt
, mp
->ka_rx_cnt
);
8041 vty_out(vty
, " SAs : %10d %10d\n",
8042 mp
->sa_tx_cnt
, mp
->sa_rx_cnt
);
8048 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8049 json
, JSON_C_TO_STRING_PRETTY
));
8050 json_object_free(json
);
8054 DEFUN (show_ip_msdp_peer_detail
,
8055 show_ip_msdp_peer_detail_cmd
,
8056 "show ip msdp [vrf NAME] peer [detail|A.B.C.D] [json]",
8061 "MSDP peer information\n"
8066 u_char uj
= use_json(argc
, argv
);
8068 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
8075 if (argv_find(argv
, argc
, "detail", &idx
))
8076 arg
= argv
[idx
]->text
;
8077 else if (argv_find(argv
, argc
, "A.B.C.D", &idx
))
8078 arg
= argv
[idx
]->arg
;
8081 ip_msdp_show_peers_detail(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
8083 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
8088 DEFUN (show_ip_msdp_peer_detail_vrf_all
,
8089 show_ip_msdp_peer_detail_vrf_all_cmd
,
8090 "show ip msdp vrf all peer [detail|A.B.C.D] [json]",
8095 "MSDP peer information\n"
8101 u_char uj
= use_json(argc
, argv
);
8107 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
8111 vty_out(vty
, " \"%s\": ", vrf
->name
);
8114 vty_out(vty
, "VRF: %s\n", vrf
->name
);
8115 if (argv_find(argv
, argc
, "detail", &idx
)
8116 || argv_find(argv
, argc
, "A.B.C.D", &idx
))
8117 ip_msdp_show_peers_detail(vrf
->info
, vty
,
8118 argv
[idx
]->arg
, uj
);
8120 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
8123 vty_out(vty
, "}\n");
8128 static void ip_msdp_show_sa(struct pim_instance
*pim
, struct vty
*vty
,
8131 struct listnode
*sanode
;
8132 struct pim_msdp_sa
*sa
;
8133 char src_str
[INET_ADDRSTRLEN
];
8134 char grp_str
[INET_ADDRSTRLEN
];
8135 char rp_str
[INET_ADDRSTRLEN
];
8136 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
8140 json_object
*json
= NULL
;
8141 json_object
*json_group
= NULL
;
8142 json_object
*json_row
= NULL
;
8145 json
= json_object_new_object();
8148 "Source Group RP Local SPT Uptime\n");
8151 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
8152 now
= pim_time_monotonic_sec();
8153 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
8154 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
8155 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
8156 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
8157 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
8159 strcpy(spt_str
, "yes");
8161 strcpy(spt_str
, "no");
8164 strcpy(rp_str
, "-");
8165 strcpy(spt_str
, "-");
8167 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
8168 strcpy(local_str
, "yes");
8170 strcpy(local_str
, "no");
8173 json_object_object_get_ex(json
, grp_str
, &json_group
);
8176 json_group
= json_object_new_object();
8177 json_object_object_add(json
, grp_str
,
8181 json_row
= json_object_new_object();
8182 json_object_string_add(json_row
, "source", src_str
);
8183 json_object_string_add(json_row
, "group", grp_str
);
8184 json_object_string_add(json_row
, "rp", rp_str
);
8185 json_object_string_add(json_row
, "local", local_str
);
8186 json_object_string_add(json_row
, "sptSetup", spt_str
);
8187 json_object_string_add(json_row
, "upTime", timebuf
);
8188 json_object_object_add(json_group
, src_str
, json_row
);
8190 vty_out(vty
, "%-15s %15s %15s %5c %3c %8s\n",
8191 src_str
, grp_str
, rp_str
, local_str
[0],
8192 spt_str
[0], timebuf
);
8197 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8198 json
, JSON_C_TO_STRING_PRETTY
));
8199 json_object_free(json
);
8203 static void ip_msdp_show_sa_entry_detail(struct pim_msdp_sa
*sa
,
8204 const char *src_str
,
8205 const char *grp_str
, struct vty
*vty
,
8206 u_char uj
, json_object
*json
)
8208 char rp_str
[INET_ADDRSTRLEN
];
8209 char peer_str
[INET_ADDRSTRLEN
];
8210 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
8213 char statetimer
[PIM_MSDP_TIMER_STRLEN
];
8215 json_object
*json_group
= NULL
;
8216 json_object
*json_row
= NULL
;
8218 now
= pim_time_monotonic_sec();
8219 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
8220 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
8221 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
8222 pim_inet4_dump("<peer?>", sa
->peer
, peer_str
, sizeof(peer_str
));
8224 strcpy(spt_str
, "yes");
8226 strcpy(spt_str
, "no");
8229 strcpy(rp_str
, "-");
8230 strcpy(peer_str
, "-");
8231 strcpy(spt_str
, "-");
8233 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
8234 strcpy(local_str
, "yes");
8236 strcpy(local_str
, "no");
8238 pim_time_timer_to_hhmmss(statetimer
, sizeof(statetimer
),
8239 sa
->sa_state_timer
);
8241 json_object_object_get_ex(json
, grp_str
, &json_group
);
8244 json_group
= json_object_new_object();
8245 json_object_object_add(json
, grp_str
, json_group
);
8248 json_row
= json_object_new_object();
8249 json_object_string_add(json_row
, "source", src_str
);
8250 json_object_string_add(json_row
, "group", grp_str
);
8251 json_object_string_add(json_row
, "rp", rp_str
);
8252 json_object_string_add(json_row
, "local", local_str
);
8253 json_object_string_add(json_row
, "sptSetup", spt_str
);
8254 json_object_string_add(json_row
, "upTime", timebuf
);
8255 json_object_string_add(json_row
, "stateTimer", statetimer
);
8256 json_object_object_add(json_group
, src_str
, json_row
);
8258 vty_out(vty
, "SA : %s\n", sa
->sg_str
);
8259 vty_out(vty
, " RP : %s\n", rp_str
);
8260 vty_out(vty
, " Peer : %s\n", peer_str
);
8261 vty_out(vty
, " Local : %s\n", local_str
);
8262 vty_out(vty
, " SPT Setup : %s\n", spt_str
);
8263 vty_out(vty
, " Uptime : %s\n", timebuf
);
8264 vty_out(vty
, " State Timer : %s\n", statetimer
);
8269 static void ip_msdp_show_sa_detail(struct pim_instance
*pim
, struct vty
*vty
,
8272 struct listnode
*sanode
;
8273 struct pim_msdp_sa
*sa
;
8274 char src_str
[INET_ADDRSTRLEN
];
8275 char grp_str
[INET_ADDRSTRLEN
];
8276 json_object
*json
= NULL
;
8279 json
= json_object_new_object();
8282 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
8283 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
8284 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
8285 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
, uj
,
8290 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8291 json
, JSON_C_TO_STRING_PRETTY
));
8292 json_object_free(json
);
8296 DEFUN (show_ip_msdp_sa_detail
,
8297 show_ip_msdp_sa_detail_cmd
,
8298 "show ip msdp [vrf NAME] sa detail [json]",
8303 "MSDP active-source information\n"
8307 u_char uj
= use_json(argc
, argv
);
8309 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
8314 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
8319 DEFUN (show_ip_msdp_sa_detail_vrf_all
,
8320 show_ip_msdp_sa_detail_vrf_all_cmd
,
8321 "show ip msdp vrf all sa detail [json]",
8326 "MSDP active-source information\n"
8330 u_char uj
= use_json(argc
, argv
);
8336 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
8340 vty_out(vty
, " \"%s\": ", vrf
->name
);
8343 vty_out(vty
, "VRF: %s\n", vrf
->name
);
8344 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
8347 vty_out(vty
, "}\n");
8352 static void ip_msdp_show_sa_addr(struct pim_instance
*pim
, struct vty
*vty
,
8353 const char *addr
, u_char uj
)
8355 struct listnode
*sanode
;
8356 struct pim_msdp_sa
*sa
;
8357 char src_str
[INET_ADDRSTRLEN
];
8358 char grp_str
[INET_ADDRSTRLEN
];
8359 json_object
*json
= NULL
;
8362 json
= json_object_new_object();
8365 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
8366 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
8367 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
8368 if (!strcmp(addr
, src_str
) || !strcmp(addr
, grp_str
)) {
8369 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
8375 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8376 json
, JSON_C_TO_STRING_PRETTY
));
8377 json_object_free(json
);
8381 static void ip_msdp_show_sa_sg(struct pim_instance
*pim
, struct vty
*vty
,
8382 const char *src
, const char *grp
, 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(src
, src_str
) && !strcmp(grp
, 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 DEFUN (show_ip_msdp_sa_sg
,
8411 show_ip_msdp_sa_sg_cmd
,
8412 "show ip msdp [vrf NAME] sa [A.B.C.D [A.B.C.D]] [json]",
8417 "MSDP active-source information\n"
8418 "source or group ip\n"
8422 u_char uj
= use_json(argc
, argv
);
8426 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
8431 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
8433 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
8437 if (src_ip
&& grp_ip
)
8438 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
8440 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
8442 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
8447 DEFUN (show_ip_msdp_sa_sg_vrf_all
,
8448 show_ip_msdp_sa_sg_vrf_all_cmd
,
8449 "show ip msdp vrf all sa [A.B.C.D [A.B.C.D]] [json]",
8454 "MSDP active-source information\n"
8455 "source or group ip\n"
8459 u_char uj
= use_json(argc
, argv
);
8464 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
8466 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
8472 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
8476 vty_out(vty
, " \"%s\": ", vrf
->name
);
8479 vty_out(vty
, "VRF: %s\n", vrf
->name
);
8481 if (src_ip
&& grp_ip
)
8482 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
8484 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
8486 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
8489 vty_out(vty
, "}\n");
8495 void pim_cmd_init(void)
8497 install_node(&pim_global_node
, pim_global_config_write
); /* PIM_NODE */
8498 install_node(&interface_node
,
8499 pim_interface_config_write
); /* INTERFACE_NODE */
8502 install_node(&debug_node
, pim_debug_config_write
);
8504 install_element(CONFIG_NODE
, &ip_multicast_routing_cmd
);
8505 install_element(CONFIG_NODE
, &no_ip_multicast_routing_cmd
);
8506 install_element(CONFIG_NODE
, &ip_pim_rp_cmd
);
8507 install_element(VRF_NODE
, &ip_pim_rp_cmd
);
8508 install_element(CONFIG_NODE
, &no_ip_pim_rp_cmd
);
8509 install_element(VRF_NODE
, &no_ip_pim_rp_cmd
);
8510 install_element(CONFIG_NODE
, &ip_pim_rp_prefix_list_cmd
);
8511 install_element(VRF_NODE
, &ip_pim_rp_prefix_list_cmd
);
8512 install_element(CONFIG_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
8513 install_element(VRF_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
8514 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
8515 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
8516 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
8517 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
8518 install_element(CONFIG_NODE
, &ip_pim_ssm_prefix_list_cmd
);
8519 install_element(VRF_NODE
, &ip_pim_ssm_prefix_list_cmd
);
8520 install_element(CONFIG_NODE
, &ip_pim_register_suppress_cmd
);
8521 install_element(VRF_NODE
, &ip_pim_register_suppress_cmd
);
8522 install_element(CONFIG_NODE
, &no_ip_pim_register_suppress_cmd
);
8523 install_element(VRF_NODE
, &no_ip_pim_register_suppress_cmd
);
8524 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
8525 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
8526 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
8527 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
8528 install_element(CONFIG_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
8529 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
8530 install_element(CONFIG_NODE
,
8531 &no_ip_pim_spt_switchover_infinity_plist_cmd
);
8532 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_plist_cmd
);
8533 install_element(CONFIG_NODE
, &ip_pim_joinprune_time_cmd
);
8534 install_element(VRF_NODE
, &ip_pim_joinprune_time_cmd
);
8535 install_element(CONFIG_NODE
, &no_ip_pim_joinprune_time_cmd
);
8536 install_element(VRF_NODE
, &no_ip_pim_joinprune_time_cmd
);
8537 install_element(CONFIG_NODE
, &ip_pim_keep_alive_cmd
);
8538 install_element(VRF_NODE
, &ip_pim_keep_alive_cmd
);
8539 install_element(CONFIG_NODE
, &ip_pim_rp_keep_alive_cmd
);
8540 install_element(VRF_NODE
, &ip_pim_rp_keep_alive_cmd
);
8541 install_element(CONFIG_NODE
, &no_ip_pim_keep_alive_cmd
);
8542 install_element(VRF_NODE
, &no_ip_pim_keep_alive_cmd
);
8543 install_element(CONFIG_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
8544 install_element(VRF_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
8545 install_element(CONFIG_NODE
, &ip_pim_packets_cmd
);
8546 install_element(VRF_NODE
, &ip_pim_packets_cmd
);
8547 install_element(CONFIG_NODE
, &no_ip_pim_packets_cmd
);
8548 install_element(VRF_NODE
, &no_ip_pim_packets_cmd
);
8549 install_element(CONFIG_NODE
, &ip_pim_v6_secondary_cmd
);
8550 install_element(VRF_NODE
, &ip_pim_v6_secondary_cmd
);
8551 install_element(CONFIG_NODE
, &no_ip_pim_v6_secondary_cmd
);
8552 install_element(VRF_NODE
, &no_ip_pim_v6_secondary_cmd
);
8553 install_element(CONFIG_NODE
, &ip_ssmpingd_cmd
);
8554 install_element(VRF_NODE
, &ip_ssmpingd_cmd
);
8555 install_element(CONFIG_NODE
, &no_ip_ssmpingd_cmd
);
8556 install_element(VRF_NODE
, &no_ip_ssmpingd_cmd
);
8557 install_element(CONFIG_NODE
, &ip_msdp_peer_cmd
);
8558 install_element(VRF_NODE
, &ip_msdp_peer_cmd
);
8559 install_element(CONFIG_NODE
, &no_ip_msdp_peer_cmd
);
8560 install_element(VRF_NODE
, &no_ip_msdp_peer_cmd
);
8561 install_element(CONFIG_NODE
, &ip_pim_ecmp_cmd
);
8562 install_element(VRF_NODE
, &ip_pim_ecmp_cmd
);
8563 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_cmd
);
8564 install_element(VRF_NODE
, &no_ip_pim_ecmp_cmd
);
8565 install_element(CONFIG_NODE
, &ip_pim_ecmp_rebalance_cmd
);
8566 install_element(VRF_NODE
, &ip_pim_ecmp_rebalance_cmd
);
8567 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
8568 install_element(VRF_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
8570 install_element(INTERFACE_NODE
, &interface_ip_igmp_cmd
);
8571 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_cmd
);
8572 install_element(INTERFACE_NODE
, &interface_ip_igmp_join_cmd
);
8573 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_join_cmd
);
8574 install_element(INTERFACE_NODE
, &interface_ip_igmp_version_cmd
);
8575 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_version_cmd
);
8576 install_element(INTERFACE_NODE
, &interface_ip_igmp_query_interval_cmd
);
8577 install_element(INTERFACE_NODE
,
8578 &interface_no_ip_igmp_query_interval_cmd
);
8579 install_element(INTERFACE_NODE
,
8580 &interface_ip_igmp_query_max_response_time_cmd
);
8581 install_element(INTERFACE_NODE
,
8582 &interface_no_ip_igmp_query_max_response_time_cmd
);
8583 install_element(INTERFACE_NODE
,
8584 &interface_ip_igmp_query_max_response_time_dsec_cmd
);
8585 install_element(INTERFACE_NODE
,
8586 &interface_no_ip_igmp_query_max_response_time_dsec_cmd
);
8587 install_element(INTERFACE_NODE
, &interface_ip_pim_ssm_cmd
);
8588 install_element(INTERFACE_NODE
, &interface_no_ip_pim_ssm_cmd
);
8589 install_element(INTERFACE_NODE
, &interface_ip_pim_sm_cmd
);
8590 install_element(INTERFACE_NODE
, &interface_no_ip_pim_sm_cmd
);
8591 install_element(INTERFACE_NODE
, &interface_ip_pim_drprio_cmd
);
8592 install_element(INTERFACE_NODE
, &interface_no_ip_pim_drprio_cmd
);
8593 install_element(INTERFACE_NODE
, &interface_ip_pim_hello_cmd
);
8594 install_element(INTERFACE_NODE
, &interface_no_ip_pim_hello_cmd
);
8595 install_element(INTERFACE_NODE
, &interface_ip_pim_boundary_oil_cmd
);
8596 install_element(INTERFACE_NODE
, &interface_no_ip_pim_boundary_oil_cmd
);
8598 // Static mroutes NEB
8599 install_element(INTERFACE_NODE
, &interface_ip_mroute_cmd
);
8600 install_element(INTERFACE_NODE
, &interface_ip_mroute_source_cmd
);
8601 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_cmd
);
8602 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_source_cmd
);
8604 install_element(VIEW_NODE
, &show_ip_igmp_interface_cmd
);
8605 install_element(VIEW_NODE
, &show_ip_igmp_interface_vrf_all_cmd
);
8606 install_element(VIEW_NODE
, &show_ip_igmp_join_cmd
);
8607 install_element(VIEW_NODE
, &show_ip_igmp_join_vrf_all_cmd
);
8608 install_element(VIEW_NODE
, &show_ip_igmp_groups_cmd
);
8609 install_element(VIEW_NODE
, &show_ip_igmp_groups_vrf_all_cmd
);
8610 install_element(VIEW_NODE
, &show_ip_igmp_groups_retransmissions_cmd
);
8611 install_element(VIEW_NODE
, &show_ip_igmp_sources_cmd
);
8612 install_element(VIEW_NODE
, &show_ip_igmp_sources_retransmissions_cmd
);
8613 install_element(VIEW_NODE
, &show_ip_pim_assert_cmd
);
8614 install_element(VIEW_NODE
, &show_ip_pim_assert_internal_cmd
);
8615 install_element(VIEW_NODE
, &show_ip_pim_assert_metric_cmd
);
8616 install_element(VIEW_NODE
, &show_ip_pim_assert_winner_metric_cmd
);
8617 install_element(VIEW_NODE
, &show_ip_pim_interface_traffic_cmd
);
8618 install_element(VIEW_NODE
, &show_ip_pim_interface_cmd
);
8619 install_element(VIEW_NODE
, &show_ip_pim_interface_vrf_all_cmd
);
8620 install_element(VIEW_NODE
, &show_ip_pim_join_cmd
);
8621 install_element(VIEW_NODE
, &show_ip_pim_join_vrf_all_cmd
);
8622 install_element(VIEW_NODE
, &show_ip_pim_local_membership_cmd
);
8623 install_element(VIEW_NODE
, &show_ip_pim_neighbor_cmd
);
8624 install_element(VIEW_NODE
, &show_ip_pim_neighbor_vrf_all_cmd
);
8625 install_element(VIEW_NODE
, &show_ip_pim_rpf_cmd
);
8626 install_element(VIEW_NODE
, &show_ip_pim_rpf_vrf_all_cmd
);
8627 install_element(VIEW_NODE
, &show_ip_pim_secondary_cmd
);
8628 install_element(VIEW_NODE
, &show_ip_pim_state_cmd
);
8629 install_element(VIEW_NODE
, &show_ip_pim_state_vrf_all_cmd
);
8630 install_element(VIEW_NODE
, &show_ip_pim_upstream_cmd
);
8631 install_element(VIEW_NODE
, &show_ip_pim_upstream_vrf_all_cmd
);
8632 install_element(VIEW_NODE
, &show_ip_pim_upstream_join_desired_cmd
);
8633 install_element(VIEW_NODE
, &show_ip_pim_upstream_rpf_cmd
);
8634 install_element(VIEW_NODE
, &show_ip_pim_rp_cmd
);
8635 install_element(VIEW_NODE
, &show_ip_pim_rp_vrf_all_cmd
);
8636 install_element(VIEW_NODE
, &show_ip_multicast_cmd
);
8637 install_element(VIEW_NODE
, &show_ip_multicast_vrf_all_cmd
);
8638 install_element(VIEW_NODE
, &show_ip_mroute_cmd
);
8639 install_element(VIEW_NODE
, &show_ip_mroute_vrf_all_cmd
);
8640 install_element(VIEW_NODE
, &show_ip_mroute_count_cmd
);
8641 install_element(VIEW_NODE
, &show_ip_mroute_count_vrf_all_cmd
);
8642 install_element(VIEW_NODE
, &show_ip_rib_cmd
);
8643 install_element(VIEW_NODE
, &show_ip_ssmpingd_cmd
);
8644 install_element(VIEW_NODE
, &show_debugging_pim_cmd
);
8645 install_element(VIEW_NODE
, &show_ip_pim_nexthop_cmd
);
8646 install_element(VIEW_NODE
, &show_ip_pim_nexthop_lookup_cmd
);
8648 install_element(ENABLE_NODE
, &clear_ip_interfaces_cmd
);
8649 install_element(ENABLE_NODE
, &clear_ip_igmp_interfaces_cmd
);
8650 install_element(ENABLE_NODE
, &clear_ip_mroute_cmd
);
8651 install_element(ENABLE_NODE
, &clear_ip_pim_interfaces_cmd
);
8652 install_element(ENABLE_NODE
, &clear_ip_pim_interface_traffic_cmd
);
8653 install_element(ENABLE_NODE
, &clear_ip_pim_oil_cmd
);
8655 install_element(ENABLE_NODE
, &debug_igmp_cmd
);
8656 install_element(ENABLE_NODE
, &no_debug_igmp_cmd
);
8657 install_element(ENABLE_NODE
, &debug_igmp_events_cmd
);
8658 install_element(ENABLE_NODE
, &no_debug_igmp_events_cmd
);
8659 install_element(ENABLE_NODE
, &debug_igmp_packets_cmd
);
8660 install_element(ENABLE_NODE
, &no_debug_igmp_packets_cmd
);
8661 install_element(ENABLE_NODE
, &debug_igmp_trace_cmd
);
8662 install_element(ENABLE_NODE
, &no_debug_igmp_trace_cmd
);
8663 install_element(ENABLE_NODE
, &debug_mroute_cmd
);
8664 install_element(ENABLE_NODE
, &debug_mroute_detail_cmd
);
8665 install_element(ENABLE_NODE
, &no_debug_mroute_cmd
);
8666 install_element(ENABLE_NODE
, &no_debug_mroute_detail_cmd
);
8667 install_element(ENABLE_NODE
, &debug_static_cmd
);
8668 install_element(ENABLE_NODE
, &no_debug_static_cmd
);
8669 install_element(ENABLE_NODE
, &debug_pim_cmd
);
8670 install_element(ENABLE_NODE
, &no_debug_pim_cmd
);
8671 install_element(ENABLE_NODE
, &debug_pim_nht_cmd
);
8672 install_element(ENABLE_NODE
, &no_debug_pim_nht_cmd
);
8673 install_element(ENABLE_NODE
, &debug_pim_nht_rp_cmd
);
8674 install_element(ENABLE_NODE
, &no_debug_pim_nht_rp_cmd
);
8675 install_element(ENABLE_NODE
, &debug_pim_events_cmd
);
8676 install_element(ENABLE_NODE
, &no_debug_pim_events_cmd
);
8677 install_element(ENABLE_NODE
, &debug_pim_packets_cmd
);
8678 install_element(ENABLE_NODE
, &no_debug_pim_packets_cmd
);
8679 install_element(ENABLE_NODE
, &debug_pim_packetdump_send_cmd
);
8680 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_send_cmd
);
8681 install_element(ENABLE_NODE
, &debug_pim_packetdump_recv_cmd
);
8682 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_recv_cmd
);
8683 install_element(ENABLE_NODE
, &debug_pim_trace_cmd
);
8684 install_element(ENABLE_NODE
, &no_debug_pim_trace_cmd
);
8685 install_element(ENABLE_NODE
, &debug_pim_trace_detail_cmd
);
8686 install_element(ENABLE_NODE
, &no_debug_pim_trace_detail_cmd
);
8687 install_element(ENABLE_NODE
, &debug_ssmpingd_cmd
);
8688 install_element(ENABLE_NODE
, &no_debug_ssmpingd_cmd
);
8689 install_element(ENABLE_NODE
, &debug_pim_zebra_cmd
);
8690 install_element(ENABLE_NODE
, &no_debug_pim_zebra_cmd
);
8691 install_element(ENABLE_NODE
, &debug_msdp_cmd
);
8692 install_element(ENABLE_NODE
, &no_debug_msdp_cmd
);
8693 install_element(ENABLE_NODE
, &undebug_msdp_cmd
);
8694 install_element(ENABLE_NODE
, &debug_msdp_events_cmd
);
8695 install_element(ENABLE_NODE
, &no_debug_msdp_events_cmd
);
8696 install_element(ENABLE_NODE
, &undebug_msdp_events_cmd
);
8697 install_element(ENABLE_NODE
, &debug_msdp_packets_cmd
);
8698 install_element(ENABLE_NODE
, &no_debug_msdp_packets_cmd
);
8699 install_element(ENABLE_NODE
, &undebug_msdp_packets_cmd
);
8701 install_element(CONFIG_NODE
, &debug_igmp_cmd
);
8702 install_element(CONFIG_NODE
, &no_debug_igmp_cmd
);
8703 install_element(CONFIG_NODE
, &debug_igmp_events_cmd
);
8704 install_element(CONFIG_NODE
, &no_debug_igmp_events_cmd
);
8705 install_element(CONFIG_NODE
, &debug_igmp_packets_cmd
);
8706 install_element(CONFIG_NODE
, &no_debug_igmp_packets_cmd
);
8707 install_element(CONFIG_NODE
, &debug_igmp_trace_cmd
);
8708 install_element(CONFIG_NODE
, &no_debug_igmp_trace_cmd
);
8709 install_element(CONFIG_NODE
, &debug_mroute_cmd
);
8710 install_element(CONFIG_NODE
, &debug_mroute_detail_cmd
);
8711 install_element(CONFIG_NODE
, &no_debug_mroute_cmd
);
8712 install_element(CONFIG_NODE
, &no_debug_mroute_detail_cmd
);
8713 install_element(CONFIG_NODE
, &debug_static_cmd
);
8714 install_element(CONFIG_NODE
, &no_debug_static_cmd
);
8715 install_element(CONFIG_NODE
, &debug_pim_cmd
);
8716 install_element(CONFIG_NODE
, &no_debug_pim_cmd
);
8717 install_element(CONFIG_NODE
, &debug_pim_nht_cmd
);
8718 install_element(CONFIG_NODE
, &no_debug_pim_nht_cmd
);
8719 install_element(CONFIG_NODE
, &debug_pim_nht_rp_cmd
);
8720 install_element(CONFIG_NODE
, &no_debug_pim_nht_rp_cmd
);
8721 install_element(CONFIG_NODE
, &debug_pim_events_cmd
);
8722 install_element(CONFIG_NODE
, &no_debug_pim_events_cmd
);
8723 install_element(CONFIG_NODE
, &debug_pim_packets_cmd
);
8724 install_element(CONFIG_NODE
, &no_debug_pim_packets_cmd
);
8725 install_element(CONFIG_NODE
, &debug_pim_trace_cmd
);
8726 install_element(CONFIG_NODE
, &no_debug_pim_trace_cmd
);
8727 install_element(CONFIG_NODE
, &debug_pim_trace_detail_cmd
);
8728 install_element(CONFIG_NODE
, &no_debug_pim_trace_detail_cmd
);
8729 install_element(CONFIG_NODE
, &debug_ssmpingd_cmd
);
8730 install_element(CONFIG_NODE
, &no_debug_ssmpingd_cmd
);
8731 install_element(CONFIG_NODE
, &debug_pim_zebra_cmd
);
8732 install_element(CONFIG_NODE
, &no_debug_pim_zebra_cmd
);
8733 install_element(CONFIG_NODE
, &debug_msdp_cmd
);
8734 install_element(CONFIG_NODE
, &no_debug_msdp_cmd
);
8735 install_element(CONFIG_NODE
, &undebug_msdp_cmd
);
8736 install_element(CONFIG_NODE
, &debug_msdp_events_cmd
);
8737 install_element(CONFIG_NODE
, &no_debug_msdp_events_cmd
);
8738 install_element(CONFIG_NODE
, &undebug_msdp_events_cmd
);
8739 install_element(CONFIG_NODE
, &debug_msdp_packets_cmd
);
8740 install_element(CONFIG_NODE
, &no_debug_msdp_packets_cmd
);
8741 install_element(CONFIG_NODE
, &undebug_msdp_packets_cmd
);
8743 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_member_cmd
);
8744 install_element(VRF_NODE
, &ip_msdp_mesh_group_member_cmd
);
8745 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
8746 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
8747 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_source_cmd
);
8748 install_element(VRF_NODE
, &ip_msdp_mesh_group_source_cmd
);
8749 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
8750 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
8751 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_cmd
);
8752 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_vrf_all_cmd
);
8753 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_cmd
);
8754 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_vrf_all_cmd
);
8755 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_cmd
);
8756 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_vrf_all_cmd
);
8757 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_cmd
);
8758 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_vrf_all_cmd
);
8759 install_element(VIEW_NODE
, &show_ip_pim_ssm_range_cmd
);
8760 install_element(VIEW_NODE
, &show_ip_pim_group_type_cmd
);
8761 install_element(INTERFACE_NODE
, &interface_pim_use_source_cmd
);
8762 install_element(INTERFACE_NODE
, &interface_no_pim_use_source_cmd
);
8763 /* Install BFD command */
8764 install_element(INTERFACE_NODE
, &ip_pim_bfd_cmd
);
8765 install_element(INTERFACE_NODE
, &ip_pim_bfd_param_cmd
);
8766 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_cmd
);
8767 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_param_cmd
);