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 listnode
*if_node
;
218 struct interface
*ifp
;
221 now
= pim_time_monotonic_sec();
224 "Interface Address Source Group State Winner Uptime Timer\n");
226 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim
->vrf_id
), if_node
, ifp
)) {
231 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
232 pim_show_assert_helper(vty
, pim_ifp
, ch
, now
);
233 } /* scan interface channels */
237 static void pim_show_assert_internal_helper(struct vty
*vty
,
238 struct pim_interface
*pim_ifp
,
239 struct pim_ifchannel
*ch
)
241 char ch_src_str
[INET_ADDRSTRLEN
];
242 char ch_grp_str
[INET_ADDRSTRLEN
];
243 struct in_addr ifaddr
;
245 ifaddr
= pim_ifp
->primary_address
;
247 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
,
249 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
,
251 vty_out(vty
, "%-9s %-15s %-15s %-15s %-3s %-3s %-3s %-4s\n",
252 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
,
254 PIM_IF_FLAG_TEST_COULD_ASSERT(ch
->flags
) ? "yes" : "no",
255 pim_macro_ch_could_assert_eval(ch
) ? "yes" : "no",
256 PIM_IF_FLAG_TEST_ASSERT_TRACKING_DESIRED(ch
->flags
)
259 pim_macro_assert_tracking_desired_eval(ch
) ? "yes"
263 static void pim_show_assert_internal(struct pim_instance
*pim
, struct vty
*vty
)
265 struct pim_interface
*pim_ifp
;
266 struct listnode
*if_node
;
267 struct pim_ifchannel
*ch
;
268 struct interface
*ifp
;
272 "ECA: Evaluate CouldAssert\n"
273 "ATD: AssertTrackingDesired\n"
274 "eATD: Evaluate AssertTrackingDesired\n\n");
277 "Interface Address Source Group CA eCA ATD eATD\n");
278 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim
->vrf_id
), if_node
, ifp
)) {
283 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
284 pim_show_assert_internal_helper(vty
, pim_ifp
, ch
);
285 } /* scan interface channels */
289 static void pim_show_assert_metric_helper(struct vty
*vty
,
290 struct pim_interface
*pim_ifp
,
291 struct pim_ifchannel
*ch
)
293 char ch_src_str
[INET_ADDRSTRLEN
];
294 char ch_grp_str
[INET_ADDRSTRLEN
];
295 char addr_str
[INET_ADDRSTRLEN
];
296 struct pim_assert_metric am
;
297 struct in_addr ifaddr
;
299 ifaddr
= pim_ifp
->primary_address
;
301 am
= pim_macro_spt_assert_metric(&ch
->upstream
->rpf
,
302 pim_ifp
->primary_address
);
304 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
,
306 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
,
308 pim_inet4_dump("<addr?>", am
.ip_address
, addr_str
,
311 vty_out(vty
, "%-9s %-15s %-15s %-15s %-3s %4u %6u %-15s\n",
312 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
,
313 ch_grp_str
, am
.rpt_bit_flag
? "yes" : "no",
314 am
.metric_preference
, am
.route_metric
, addr_str
);
317 static void pim_show_assert_metric(struct pim_instance
*pim
, struct vty
*vty
)
319 struct pim_interface
*pim_ifp
;
320 struct listnode
*if_node
;
321 struct pim_ifchannel
*ch
;
322 struct interface
*ifp
;
325 "Interface Address Source Group RPT Pref Metric Address \n");
327 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim
->vrf_id
), if_node
, ifp
)) {
332 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
333 pim_show_assert_metric_helper(vty
, pim_ifp
, ch
);
334 } /* scan interface channels */
338 static void pim_show_assert_winner_metric_helper(struct vty
*vty
,
339 struct pim_interface
*pim_ifp
,
340 struct pim_ifchannel
*ch
)
342 char ch_src_str
[INET_ADDRSTRLEN
];
343 char ch_grp_str
[INET_ADDRSTRLEN
];
344 char addr_str
[INET_ADDRSTRLEN
];
345 struct pim_assert_metric
*am
;
346 struct in_addr ifaddr
;
350 ifaddr
= pim_ifp
->primary_address
;
352 am
= &ch
->ifassert_winner_metric
;
354 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
,
356 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
,
358 pim_inet4_dump("<addr?>", am
->ip_address
, addr_str
,
361 if (am
->metric_preference
== PIM_ASSERT_METRIC_PREFERENCE_MAX
)
362 snprintf(pref_str
, sizeof(pref_str
), "INFI");
364 snprintf(pref_str
, sizeof(pref_str
), "%4u",
365 am
->metric_preference
);
367 if (am
->route_metric
== PIM_ASSERT_ROUTE_METRIC_MAX
)
368 snprintf(metr_str
, sizeof(metr_str
), "INFI");
370 snprintf(metr_str
, sizeof(metr_str
), "%6u",
373 vty_out(vty
, "%-9s %-15s %-15s %-15s %-3s %-4s %-6s %-15s\n",
374 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
,
375 ch_grp_str
, am
->rpt_bit_flag
? "yes" : "no", pref_str
,
379 static void pim_show_assert_winner_metric(struct pim_instance
*pim
,
382 struct listnode
*if_node
;
383 struct pim_interface
*pim_ifp
;
384 struct pim_ifchannel
*ch
;
385 struct interface
*ifp
;
388 "Interface Address Source Group RPT Pref Metric Address \n");
390 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim
->vrf_id
), if_node
, ifp
)) {
395 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
396 pim_show_assert_winner_metric_helper(vty
, pim_ifp
, ch
);
397 } /* scan interface channels */
401 static void json_object_pim_ifp_add(struct json_object
*json
,
402 struct interface
*ifp
)
404 struct pim_interface
*pim_ifp
;
407 json_object_string_add(json
, "name", ifp
->name
);
408 json_object_string_add(json
, "state", if_is_up(ifp
) ? "up" : "down");
409 json_object_string_add(json
, "address",
410 inet_ntoa(pim_ifp
->primary_address
));
411 json_object_int_add(json
, "index", ifp
->ifindex
);
413 if (if_is_multicast(ifp
))
414 json_object_boolean_true_add(json
, "flagMulticast");
416 if (if_is_broadcast(ifp
))
417 json_object_boolean_true_add(json
, "flagBroadcast");
419 if (ifp
->flags
& IFF_ALLMULTI
)
420 json_object_boolean_true_add(json
, "flagAllMulticast");
422 if (ifp
->flags
& IFF_PROMISC
)
423 json_object_boolean_true_add(json
, "flagPromiscuous");
425 if (PIM_IF_IS_DELETED(ifp
))
426 json_object_boolean_true_add(json
, "flagDeleted");
428 if (pim_if_lan_delay_enabled(ifp
))
429 json_object_boolean_true_add(json
, "lanDelayEnabled");
432 static void pim_show_membership_helper(struct vty
*vty
,
433 struct pim_interface
*pim_ifp
,
434 struct pim_ifchannel
*ch
,
435 struct json_object
*json
)
437 char ch_src_str
[INET_ADDRSTRLEN
];
438 char ch_grp_str
[INET_ADDRSTRLEN
];
439 json_object
*json_iface
= NULL
;
440 json_object
*json_row
= NULL
;
442 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
,
444 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
,
447 json_object_object_get_ex(json
, ch
->interface
->name
,
450 json_iface
= json_object_new_object();
451 json_object_pim_ifp_add(json_iface
, ch
->interface
);
452 json_object_object_add(json
, ch
->interface
->name
,
456 json_row
= json_object_new_object();
457 json_object_string_add(json_row
, "source", ch_src_str
);
458 json_object_string_add(json_row
, "group", ch_grp_str
);
459 json_object_string_add(
460 json_row
, "localMembership",
461 ch
->local_ifmembership
== PIM_IFMEMBERSHIP_NOINFO
464 json_object_object_add(json_iface
, ch_grp_str
, json_row
);
467 static void pim_show_membership(struct pim_instance
*pim
, struct vty
*vty
,
470 struct listnode
*if_node
;
471 struct pim_interface
*pim_ifp
;
472 struct pim_ifchannel
*ch
;
473 struct interface
*ifp
;
475 json_object
*json
= NULL
;
476 json_object
*json_tmp
= NULL
;
478 json
= json_object_new_object();
480 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim
->vrf_id
), if_node
, ifp
)) {
485 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
486 pim_show_membership_helper(vty
, pim_ifp
, ch
, json
);
487 } /* scan interface channels */
491 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
492 json
, JSON_C_TO_STRING_PRETTY
));
495 "Interface Address Source Group Membership\n");
498 * Example of the json data we are traversing
504 * "address":"10.1.20.1",
506 * "flagMulticast":true,
507 * "flagBroadcast":true,
508 * "lanDelayEnabled":true,
511 * "group":"226.10.10.10",
512 * "localMembership":"INCLUDE"
518 /* foreach interface */
519 json_object_object_foreach(json
, key
, val
)
522 /* Find all of the keys where the val is an object. In
524 * above the only one is 226.10.10.10
526 json_object_object_foreach(val
, if_field_key
,
529 type
= json_object_get_type(if_field_val
);
531 if (type
== json_type_object
) {
532 vty_out(vty
, "%-9s ", key
);
534 json_object_object_get_ex(
535 val
, "address", &json_tmp
);
536 vty_out(vty
, "%-15s ",
537 json_object_get_string(
540 json_object_object_get_ex(if_field_val
,
543 vty_out(vty
, "%-15s ",
544 json_object_get_string(
548 vty_out(vty
, "%-15s ", if_field_key
);
550 json_object_object_get_ex(
551 if_field_val
, "localMembership",
553 vty_out(vty
, "%-10s\n",
554 json_object_get_string(
561 json_object_free(json
);
564 static void pim_print_ifp_flags(struct vty
*vty
, struct interface
*ifp
,
567 vty_out(vty
, "Flags\n");
568 vty_out(vty
, "-----\n");
569 vty_out(vty
, "All Multicast : %s\n",
570 (ifp
->flags
& IFF_ALLMULTI
) ? "yes" : "no");
571 vty_out(vty
, "Broadcast : %s\n",
572 if_is_broadcast(ifp
) ? "yes" : "no");
573 vty_out(vty
, "Deleted : %s\n",
574 PIM_IF_IS_DELETED(ifp
) ? "yes" : "no");
575 vty_out(vty
, "Interface Index : %d\n", ifp
->ifindex
);
576 vty_out(vty
, "Multicast : %s\n",
577 if_is_multicast(ifp
) ? "yes" : "no");
578 vty_out(vty
, "Multicast Loop : %d\n", mloop
);
579 vty_out(vty
, "Promiscuous : %s\n",
580 (ifp
->flags
& IFF_PROMISC
) ? "yes" : "no");
585 static void igmp_show_interfaces(struct pim_instance
*pim
, struct vty
*vty
,
588 struct listnode
*node
;
589 struct interface
*ifp
;
591 json_object
*json
= NULL
;
592 json_object
*json_row
= NULL
;
594 now
= pim_time_monotonic_sec();
597 json
= json_object_new_object();
600 "Interface State Address V Querier Query Timer Uptime\n");
602 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim
->vrf_id
), node
, ifp
)) {
603 struct pim_interface
*pim_ifp
;
604 struct listnode
*sock_node
;
605 struct igmp_sock
*igmp
;
612 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
615 char query_hhmmss
[10];
617 pim_time_uptime(uptime
, sizeof(uptime
),
618 now
- igmp
->sock_creation
);
619 pim_time_timer_to_hhmmss(query_hhmmss
,
620 sizeof(query_hhmmss
),
621 igmp
->t_igmp_query_timer
);
624 json_row
= json_object_new_object();
625 json_object_pim_ifp_add(json_row
, ifp
);
626 json_object_string_add(json_row
, "upTime",
628 json_object_int_add(json_row
, "version",
629 pim_ifp
->igmp_version
);
631 if (igmp
->t_igmp_query_timer
) {
632 json_object_boolean_true_add(json_row
,
634 json_object_string_add(json_row
,
639 json_object_object_add(json
, ifp
->name
,
644 "%-9s %5s %15s %d %7s %11s %8s\n",
646 if_is_up(ifp
) ? "up" : "down",
647 inet_ntoa(igmp
->ifaddr
),
648 pim_ifp
->igmp_version
,
649 igmp
->t_igmp_query_timer
? "local"
651 query_hhmmss
, uptime
);
657 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
658 json
, JSON_C_TO_STRING_PRETTY
));
659 json_object_free(json
);
663 static void igmp_show_interfaces_single(struct pim_instance
*pim
,
664 struct vty
*vty
, const char *ifname
,
667 struct igmp_sock
*igmp
;
668 struct interface
*ifp
;
669 struct listnode
*node
;
670 struct listnode
*sock_node
;
671 struct pim_interface
*pim_ifp
;
673 char query_hhmmss
[10];
674 char other_hhmmss
[10];
675 int found_ifname
= 0;
678 long gmi_msec
; /* Group Membership Interval */
681 long oqpi_msec
; /* Other Querier Present Interval */
685 json_object
*json
= NULL
;
686 json_object
*json_row
= NULL
;
689 json
= json_object_new_object();
691 now
= pim_time_monotonic_sec();
693 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim
->vrf_id
), node
, ifp
)) {
699 if (strcmp(ifname
, "detail") && strcmp(ifname
, ifp
->name
))
702 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
705 pim_time_uptime(uptime
, sizeof(uptime
),
706 now
- igmp
->sock_creation
);
707 pim_time_timer_to_hhmmss(query_hhmmss
,
708 sizeof(query_hhmmss
),
709 igmp
->t_igmp_query_timer
);
710 pim_time_timer_to_hhmmss(other_hhmmss
,
711 sizeof(other_hhmmss
),
712 igmp
->t_other_querier_timer
);
714 gmi_msec
= PIM_IGMP_GMI_MSEC(
715 igmp
->querier_robustness_variable
,
716 igmp
->querier_query_interval
,
717 pim_ifp
->igmp_query_max_response_time_dsec
);
720 pim_ifp
->igmp_default_query_interval
);
722 oqpi_msec
= PIM_IGMP_OQPI_MSEC(
723 igmp
->querier_robustness_variable
,
724 igmp
->querier_query_interval
,
725 pim_ifp
->igmp_query_max_response_time_dsec
);
727 lmqt_msec
= PIM_IGMP_LMQT_MSEC(
728 pim_ifp
->igmp_query_max_response_time_dsec
,
729 igmp
->querier_robustness_variable
);
733 igmp
->querier_robustness_variable
,
734 igmp
->querier_query_interval
,
735 pim_ifp
->igmp_query_max_response_time_dsec
)
738 qri_msec
= pim_ifp
->igmp_query_max_response_time_dsec
740 if (pim_ifp
->pim_sock_fd
>= 0)
741 mloop
= pim_socket_mcastloop_get(
742 pim_ifp
->pim_sock_fd
);
747 json_row
= json_object_new_object();
748 json_object_pim_ifp_add(json_row
, ifp
);
749 json_object_string_add(json_row
, "upTime",
751 json_object_string_add(json_row
, "querier",
752 igmp
->t_igmp_query_timer
755 json_object_int_add(json_row
, "queryStartCount",
756 igmp
->startup_query_count
);
757 json_object_string_add(json_row
,
760 json_object_string_add(json_row
,
763 json_object_int_add(json_row
, "version",
764 pim_ifp
->igmp_version
);
767 "timerGroupMembershipIntervalMsec",
769 json_object_int_add(json_row
,
770 "timerLastMemberQueryMsec",
774 "timerOlderHostPresentIntervalMsec",
778 "timerOtherQuerierPresentIntervalMsec",
781 json_row
, "timerQueryInterval",
782 igmp
->querier_query_interval
);
785 "timerQueryResponseIntervalMsec",
788 json_row
, "timerRobustnessVariable",
789 igmp
->querier_robustness_variable
);
790 json_object_int_add(json_row
,
791 "timerStartupQueryInterval",
794 json_object_object_add(json
, ifp
->name
,
798 vty_out(vty
, "Interface : %s\n", ifp
->name
);
799 vty_out(vty
, "State : %s\n",
800 if_is_up(ifp
) ? "up" : "down");
801 vty_out(vty
, "Address : %s\n",
802 inet_ntoa(pim_ifp
->primary_address
));
803 vty_out(vty
, "Uptime : %s\n", uptime
);
804 vty_out(vty
, "Version : %d\n",
805 pim_ifp
->igmp_version
);
809 vty_out(vty
, "Querier\n");
810 vty_out(vty
, "-------\n");
811 vty_out(vty
, "Querier : %s\n",
812 igmp
->t_igmp_query_timer
? "local"
814 vty_out(vty
, "Start Count : %d\n",
815 igmp
->startup_query_count
);
816 vty_out(vty
, "Query Timer : %s\n",
818 vty_out(vty
, "Other Timer : %s\n",
823 vty_out(vty
, "Timers\n");
824 vty_out(vty
, "------\n");
826 "Group Membership Interval : %lis\n",
829 "Last Member Query Time : %lis\n",
832 "Older Host Present Interval : %lis\n",
835 "Other Querier Present Interval : %lis\n",
838 "Query Interval : %ds\n",
839 igmp
->querier_query_interval
);
841 "Query Response Interval : %lis\n",
844 "Robustness Variable : %d\n",
845 igmp
->querier_robustness_variable
);
847 "Startup Query Interval : %ds\n",
852 pim_print_ifp_flags(vty
, ifp
, mloop
);
858 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
859 json
, JSON_C_TO_STRING_PRETTY
));
860 json_object_free(json
);
863 vty_out(vty
, "%% No such interface\n");
867 static void igmp_show_interface_join(struct pim_instance
*pim
, struct vty
*vty
)
869 struct listnode
*node
;
870 struct interface
*ifp
;
873 now
= pim_time_monotonic_sec();
876 "Interface Address Source Group Socket Uptime \n");
878 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim
->vrf_id
), node
, ifp
)) {
879 struct pim_interface
*pim_ifp
;
880 struct listnode
*join_node
;
881 struct igmp_join
*ij
;
882 struct in_addr pri_addr
;
883 char pri_addr_str
[INET_ADDRSTRLEN
];
890 if (!pim_ifp
->igmp_join_list
)
893 pri_addr
= pim_find_primary_addr(ifp
);
894 pim_inet4_dump("<pri?>", pri_addr
, pri_addr_str
,
895 sizeof(pri_addr_str
));
897 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_join_list
, join_node
,
899 char group_str
[INET_ADDRSTRLEN
];
900 char source_str
[INET_ADDRSTRLEN
];
903 pim_time_uptime(uptime
, sizeof(uptime
),
904 now
- ij
->sock_creation
);
905 pim_inet4_dump("<grp?>", ij
->group_addr
, group_str
,
907 pim_inet4_dump("<src?>", ij
->source_addr
, source_str
,
910 vty_out(vty
, "%-9s %-15s %-15s %-15s %6d %8s\n",
911 ifp
->name
, pri_addr_str
, source_str
, group_str
,
912 ij
->sock_fd
, uptime
);
913 } /* for (pim_ifp->igmp_join_list) */
918 static void pim_show_interfaces_single(struct pim_instance
*pim
,
919 struct vty
*vty
, const char *ifname
,
922 struct in_addr ifaddr
;
923 struct interface
*ifp
;
924 struct listnode
*neighnode
;
925 struct listnode
*node
;
926 struct listnode
*upnode
;
927 struct pim_interface
*pim_ifp
;
928 struct pim_neighbor
*neigh
;
929 struct pim_upstream
*up
;
931 char dr_str
[INET_ADDRSTRLEN
];
934 char grp_str
[INET_ADDRSTRLEN
];
935 char hello_period
[10];
936 char hello_timer
[10];
937 char neigh_src_str
[INET_ADDRSTRLEN
];
938 char src_str
[INET_ADDRSTRLEN
];
939 char stat_uptime
[10];
942 int found_ifname
= 0;
944 json_object
*json
= NULL
;
945 json_object
*json_row
= NULL
;
946 json_object
*json_pim_neighbor
= NULL
;
947 json_object
*json_pim_neighbors
= NULL
;
948 json_object
*json_group
= NULL
;
949 json_object
*json_group_source
= NULL
;
950 json_object
*json_fhr_sources
= NULL
;
951 struct pim_secondary_addr
*sec_addr
;
952 struct listnode
*sec_node
;
954 now
= pim_time_monotonic_sec();
957 json
= json_object_new_object();
959 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim
->vrf_id
), node
, ifp
)) {
965 if (strcmp(ifname
, "detail") && strcmp(ifname
, ifp
->name
))
969 ifaddr
= pim_ifp
->primary_address
;
970 pim_inet4_dump("<dr?>", pim_ifp
->pim_dr_addr
, dr_str
,
972 pim_time_uptime_begin(dr_uptime
, sizeof(dr_uptime
), now
,
973 pim_ifp
->pim_dr_election_last
);
974 pim_time_timer_to_hhmmss(hello_timer
, sizeof(hello_timer
),
975 pim_ifp
->t_pim_hello_timer
);
976 pim_time_mmss(hello_period
, sizeof(hello_period
),
977 pim_ifp
->pim_hello_period
);
978 pim_time_uptime(stat_uptime
, sizeof(stat_uptime
),
979 now
- pim_ifp
->pim_ifstat_start
);
980 if (pim_ifp
->pim_sock_fd
>= 0)
981 mloop
= pim_socket_mcastloop_get(pim_ifp
->pim_sock_fd
);
986 char pbuf
[PREFIX2STR_BUFFER
];
987 json_row
= json_object_new_object();
988 json_object_pim_ifp_add(json_row
, ifp
);
990 if (pim_ifp
->update_source
.s_addr
!= INADDR_ANY
) {
991 json_object_string_add(
992 json_row
, "useSource",
993 inet_ntoa(pim_ifp
->update_source
));
995 if (pim_ifp
->sec_addr_list
) {
996 json_object
*sec_list
= NULL
;
998 sec_list
= json_object_new_array();
999 for (ALL_LIST_ELEMENTS_RO(
1000 pim_ifp
->sec_addr_list
, sec_node
,
1002 json_object_array_add(
1004 json_object_new_string(
1010 json_object_object_add(json_row
,
1011 "secondaryAddressList",
1016 if (pim_ifp
->pim_neighbor_list
->count
) {
1017 json_pim_neighbors
= json_object_new_object();
1019 for (ALL_LIST_ELEMENTS_RO(
1020 pim_ifp
->pim_neighbor_list
,
1021 neighnode
, neigh
)) {
1023 json_object_new_object();
1024 pim_inet4_dump("<src?>",
1027 sizeof(neigh_src_str
));
1028 pim_time_uptime(uptime
, sizeof(uptime
),
1029 now
- neigh
->creation
);
1030 pim_time_timer_to_hhmmss(
1031 expire
, sizeof(expire
),
1032 neigh
->t_expire_timer
);
1034 json_object_string_add(
1035 json_pim_neighbor
, "address",
1037 json_object_string_add(
1038 json_pim_neighbor
, "upTime",
1040 json_object_string_add(
1041 json_pim_neighbor
, "holdtime",
1044 json_object_object_add(
1050 json_object_object_add(json_row
, "neighbors",
1051 json_pim_neighbors
);
1054 json_object_string_add(json_row
, "drAddress", dr_str
);
1055 json_object_int_add(json_row
, "drPriority",
1056 pim_ifp
->pim_dr_priority
);
1057 json_object_string_add(json_row
, "drUptime", dr_uptime
);
1058 json_object_int_add(json_row
, "drElections",
1059 pim_ifp
->pim_dr_election_count
);
1060 json_object_int_add(json_row
, "drChanges",
1061 pim_ifp
->pim_dr_election_changes
);
1064 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
,
1066 if (ifp
== up
->rpf
.source_nexthop
.interface
) {
1068 & PIM_UPSTREAM_FLAG_MASK_FHR
) {
1069 if (!json_fhr_sources
) {
1071 json_object_new_object();
1074 pim_inet4_dump("<src?>",
1078 pim_inet4_dump("<grp?>",
1083 uptime
, sizeof(uptime
),
1084 now
- up
->state_transition
);
1086 /* Does this group live in
1087 * json_fhr_sources? If not
1089 json_object_object_get_ex(
1091 grp_str
, &json_group
);
1095 json_object_new_object();
1096 json_object_object_add(
1103 json_object_new_object();
1104 json_object_string_add(
1107 json_object_string_add(
1110 json_object_string_add(
1113 json_object_object_add(
1114 json_group
, src_str
,
1120 if (json_fhr_sources
) {
1121 json_object_object_add(json_row
,
1126 json_object_int_add(json_row
, "helloPeriod",
1127 pim_ifp
->pim_hello_period
);
1128 json_object_string_add(json_row
, "helloTimer",
1130 json_object_string_add(json_row
, "helloStatStart",
1132 json_object_int_add(json_row
, "helloReceived",
1133 pim_ifp
->pim_ifstat_hello_recv
);
1134 json_object_int_add(json_row
, "helloReceivedFailed",
1135 pim_ifp
->pim_ifstat_hello_recvfail
);
1136 json_object_int_add(json_row
, "helloSend",
1137 pim_ifp
->pim_ifstat_hello_sent
);
1138 json_object_int_add(json_row
, "hellosendFailed",
1139 pim_ifp
->pim_ifstat_hello_sendfail
);
1140 json_object_int_add(json_row
, "helloGenerationId",
1141 pim_ifp
->pim_generation_id
);
1142 json_object_int_add(json_row
, "flagMulticastLoop",
1145 json_object_int_add(
1146 json_row
, "effectivePropagationDelay",
1147 pim_if_effective_propagation_delay_msec(ifp
));
1148 json_object_int_add(
1149 json_row
, "effectiveOverrideInterval",
1150 pim_if_effective_override_interval_msec(ifp
));
1151 json_object_int_add(
1152 json_row
, "joinPruneOverrideInterval",
1153 pim_if_jp_override_interval_msec(ifp
));
1155 json_object_int_add(
1156 json_row
, "propagationDelay",
1157 pim_ifp
->pim_propagation_delay_msec
);
1158 json_object_int_add(
1159 json_row
, "propagationDelayHighest",
1160 pim_ifp
->pim_neighbors_highest_propagation_delay_msec
);
1161 json_object_int_add(
1162 json_row
, "overrideInterval",
1163 pim_ifp
->pim_override_interval_msec
);
1164 json_object_int_add(
1165 json_row
, "overrideIntervalHighest",
1166 pim_ifp
->pim_neighbors_highest_override_interval_msec
);
1167 json_object_object_add(json
, ifp
->name
, json_row
);
1170 vty_out(vty
, "Interface : %s\n", ifp
->name
);
1171 vty_out(vty
, "State : %s\n",
1172 if_is_up(ifp
) ? "up" : "down");
1173 if (pim_ifp
->update_source
.s_addr
!= INADDR_ANY
) {
1174 vty_out(vty
, "Use Source : %s\n",
1175 inet_ntoa(pim_ifp
->update_source
));
1177 if (pim_ifp
->sec_addr_list
) {
1178 char pbuf
[PREFIX2STR_BUFFER
];
1179 vty_out(vty
, "Address : %s (primary)\n",
1181 for (ALL_LIST_ELEMENTS_RO(
1182 pim_ifp
->sec_addr_list
, sec_node
,
1184 vty_out(vty
, " %s\n",
1185 prefix2str(&sec_addr
->addr
,
1186 pbuf
, sizeof(pbuf
)));
1189 vty_out(vty
, "Address : %s\n",
1197 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
,
1198 neighnode
, neigh
)) {
1201 vty_out(vty
, "PIM Neighbors\n");
1202 vty_out(vty
, "-------------\n");
1206 pim_inet4_dump("<src?>", neigh
->source_addr
,
1208 sizeof(neigh_src_str
));
1209 pim_time_uptime(uptime
, sizeof(uptime
),
1210 now
- neigh
->creation
);
1211 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
1212 neigh
->t_expire_timer
);
1214 "%-15s : up for %s, holdtime expires in %s\n",
1215 neigh_src_str
, uptime
, expire
);
1218 if (!print_header
) {
1223 vty_out(vty
, "Designated Router\n");
1224 vty_out(vty
, "-----------------\n");
1225 vty_out(vty
, "Address : %s\n", dr_str
);
1226 vty_out(vty
, "Priority : %d\n",
1227 pim_ifp
->pim_dr_priority
);
1228 vty_out(vty
, "Uptime : %s\n", dr_uptime
);
1229 vty_out(vty
, "Elections : %d\n",
1230 pim_ifp
->pim_dr_election_count
);
1231 vty_out(vty
, "Changes : %d\n",
1232 pim_ifp
->pim_dr_election_changes
);
1238 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
,
1240 if (strcmp(ifp
->name
, up
->rpf
.source_nexthop
1244 & PIM_UPSTREAM_FLAG_MASK_FHR
) {
1248 "FHR - First Hop Router\n");
1250 "----------------------\n");
1254 pim_inet4_dump("<src?>",
1258 pim_inet4_dump("<grp?>",
1263 uptime
, sizeof(uptime
),
1264 now
- up
->state_transition
);
1266 "%s : %s is a source, uptime is %s\n",
1273 if (!print_header
) {
1278 vty_out(vty
, "Hellos\n");
1279 vty_out(vty
, "------\n");
1280 vty_out(vty
, "Period : %d\n",
1281 pim_ifp
->pim_hello_period
);
1282 vty_out(vty
, "Timer : %s\n", hello_timer
);
1283 vty_out(vty
, "StatStart : %s\n", stat_uptime
);
1284 vty_out(vty
, "Receive : %d\n",
1285 pim_ifp
->pim_ifstat_hello_recv
);
1286 vty_out(vty
, "Receive Failed : %d\n",
1287 pim_ifp
->pim_ifstat_hello_recvfail
);
1288 vty_out(vty
, "Send : %d\n",
1289 pim_ifp
->pim_ifstat_hello_sent
);
1290 vty_out(vty
, "Send Failed : %d\n",
1291 pim_ifp
->pim_ifstat_hello_sendfail
);
1292 vty_out(vty
, "Generation ID : %08x\n",
1293 pim_ifp
->pim_generation_id
);
1297 pim_print_ifp_flags(vty
, ifp
, mloop
);
1299 vty_out(vty
, "Join Prune Interval\n");
1300 vty_out(vty
, "-------------------\n");
1301 vty_out(vty
, "LAN Delay : %s\n",
1302 pim_if_lan_delay_enabled(ifp
) ? "yes" : "no");
1303 vty_out(vty
, "Effective Propagation Delay : %d msec\n",
1304 pim_if_effective_propagation_delay_msec(ifp
));
1305 vty_out(vty
, "Effective Override Interval : %d msec\n",
1306 pim_if_effective_override_interval_msec(ifp
));
1307 vty_out(vty
, "Join Prune Override Interval : %d msec\n",
1308 pim_if_jp_override_interval_msec(ifp
));
1312 vty_out(vty
, "LAN Prune Delay\n");
1313 vty_out(vty
, "---------------\n");
1314 vty_out(vty
, "Propagation Delay : %d msec\n",
1315 pim_ifp
->pim_propagation_delay_msec
);
1316 vty_out(vty
, "Propagation Delay (Highest) : %d msec\n",
1317 pim_ifp
->pim_neighbors_highest_propagation_delay_msec
);
1318 vty_out(vty
, "Override Interval : %d msec\n",
1319 pim_ifp
->pim_override_interval_msec
);
1320 vty_out(vty
, "Override Interval (Highest) : %d msec\n",
1321 pim_ifp
->pim_neighbors_highest_override_interval_msec
);
1328 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1329 json
, JSON_C_TO_STRING_PRETTY
));
1330 json_object_free(json
);
1333 vty_out(vty
, "%% No such interface\n");
1337 static void pim_show_interfaces(struct pim_instance
*pim
, struct vty
*vty
,
1340 struct interface
*ifp
;
1341 struct listnode
*node
;
1342 struct listnode
*upnode
;
1343 struct pim_interface
*pim_ifp
;
1344 struct pim_upstream
*up
;
1347 int pim_ifchannels
= 0;
1348 json_object
*json
= NULL
;
1349 json_object
*json_row
= NULL
;
1350 json_object
*json_tmp
;
1352 json
= json_object_new_object();
1354 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim
->vrf_id
), node
, ifp
)) {
1355 pim_ifp
= ifp
->info
;
1360 pim_nbrs
= pim_ifp
->pim_neighbor_list
->count
;
1361 pim_ifchannels
= pim_if_ifchannel_count(pim_ifp
);
1364 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
, up
))
1365 if (ifp
== up
->rpf
.source_nexthop
.interface
)
1366 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
1369 json_row
= json_object_new_object();
1370 json_object_pim_ifp_add(json_row
, ifp
);
1371 json_object_int_add(json_row
, "pimNeighbors", pim_nbrs
);
1372 json_object_int_add(json_row
, "pimIfChannels", pim_ifchannels
);
1373 json_object_int_add(json_row
, "firstHopRouterCount", fhr
);
1374 json_object_string_add(json_row
, "pimDesignatedRouter",
1375 inet_ntoa(pim_ifp
->pim_dr_addr
));
1377 if (pim_ifp
->pim_dr_addr
.s_addr
1378 == pim_ifp
->primary_address
.s_addr
)
1379 json_object_boolean_true_add(
1380 json_row
, "pimDesignatedRouterLocal");
1382 json_object_object_add(json
, ifp
->name
, json_row
);
1386 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1387 json
, JSON_C_TO_STRING_PRETTY
));
1390 "Interface State Address PIM Nbrs PIM DR FHR IfChannels\n");
1392 json_object_object_foreach(json
, key
, val
)
1394 vty_out(vty
, "%-9s ", key
);
1396 json_object_object_get_ex(val
, "state", &json_tmp
);
1397 vty_out(vty
, "%5s ", json_object_get_string(json_tmp
));
1399 json_object_object_get_ex(val
, "address", &json_tmp
);
1400 vty_out(vty
, "%15s ",
1401 json_object_get_string(json_tmp
));
1403 json_object_object_get_ex(val
, "pimNeighbors",
1405 vty_out(vty
, "%8d ", json_object_get_int(json_tmp
));
1407 if (json_object_object_get_ex(
1408 val
, "pimDesignatedRouterLocal",
1410 vty_out(vty
, "%15s ", "local");
1412 json_object_object_get_ex(
1413 val
, "pimDesignatedRouter", &json_tmp
);
1414 vty_out(vty
, "%15s ",
1415 json_object_get_string(json_tmp
));
1418 json_object_object_get_ex(val
, "firstHopRouter",
1420 vty_out(vty
, "%3d ", json_object_get_int(json_tmp
));
1422 json_object_object_get_ex(val
, "pimIfChannels",
1424 vty_out(vty
, "%9d\n", json_object_get_int(json_tmp
));
1428 json_object_free(json
);
1431 static void pim_show_interface_traffic(struct pim_instance
*pim
,
1432 struct vty
*vty
, u_char uj
)
1434 struct interface
*ifp
= NULL
;
1435 struct pim_interface
*pim_ifp
= NULL
;
1436 struct listnode
*node
= NULL
;
1437 json_object
*json
= NULL
;
1438 json_object
*json_row
= NULL
;
1441 json
= json_object_new_object();
1444 vty_out(vty
, "%-12s%-17s%-17s%-17s%-17s%-17s%-17s\n",
1445 "Interface", " HELLO", " JOIN", " PRUNE",
1446 " REGISTER", " REGISTER-STOP", " ASSERT");
1447 vty_out(vty
, "%-10s%-18s%-17s%-17s%-17s%-17s%-17s\n", "",
1448 " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1449 " Rx/Tx", " Rx/Tx");
1451 "---------------------------------------------------------------------------------------------------------------\n");
1454 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim
->vrf_id
), node
, ifp
)) {
1455 pim_ifp
= ifp
->info
;
1460 if (pim_ifp
->pim_sock_fd
< 0)
1463 json_row
= json_object_new_object();
1464 json_object_pim_ifp_add(json_row
, ifp
);
1465 json_object_int_add(json_row
, "helloRx",
1466 pim_ifp
->pim_ifstat_hello_recv
);
1467 json_object_int_add(json_row
, "helloTx",
1468 pim_ifp
->pim_ifstat_hello_sent
);
1469 json_object_int_add(json_row
, "joinRx",
1470 pim_ifp
->pim_ifstat_join_recv
);
1471 json_object_int_add(json_row
, "joinTx",
1472 pim_ifp
->pim_ifstat_join_send
);
1473 json_object_int_add(json_row
, "registerRx",
1474 pim_ifp
->pim_ifstat_reg_recv
);
1475 json_object_int_add(json_row
, "registerTx",
1476 pim_ifp
->pim_ifstat_reg_recv
);
1477 json_object_int_add(json_row
, "registerStopRx",
1478 pim_ifp
->pim_ifstat_reg_stop_recv
);
1479 json_object_int_add(json_row
, "registerStopTx",
1480 pim_ifp
->pim_ifstat_reg_stop_send
);
1481 json_object_int_add(json_row
, "assertRx",
1482 pim_ifp
->pim_ifstat_assert_recv
);
1483 json_object_int_add(json_row
, "assertTx",
1484 pim_ifp
->pim_ifstat_assert_send
);
1486 json_object_object_add(json
, ifp
->name
, json_row
);
1489 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u \n",
1490 ifp
->name
, pim_ifp
->pim_ifstat_hello_recv
,
1491 pim_ifp
->pim_ifstat_hello_sent
,
1492 pim_ifp
->pim_ifstat_join_recv
,
1493 pim_ifp
->pim_ifstat_join_send
,
1494 pim_ifp
->pim_ifstat_prune_recv
,
1495 pim_ifp
->pim_ifstat_prune_send
,
1496 pim_ifp
->pim_ifstat_reg_recv
,
1497 pim_ifp
->pim_ifstat_reg_send
,
1498 pim_ifp
->pim_ifstat_reg_stop_recv
,
1499 pim_ifp
->pim_ifstat_reg_stop_send
,
1500 pim_ifp
->pim_ifstat_assert_recv
,
1501 pim_ifp
->pim_ifstat_assert_send
);
1505 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1506 json
, JSON_C_TO_STRING_PRETTY
));
1507 json_object_free(json
);
1511 static void pim_show_interface_traffic_single(struct pim_instance
*pim
,
1513 const char *ifname
, u_char uj
)
1515 struct interface
*ifp
= NULL
;
1516 struct pim_interface
*pim_ifp
= NULL
;
1517 struct listnode
*node
= NULL
;
1518 json_object
*json
= NULL
;
1519 json_object
*json_row
= NULL
;
1520 uint8_t found_ifname
= 0;
1523 json
= json_object_new_object();
1526 vty_out(vty
, "%-12s%-17s%-17s%-17s%-17s%-17s%-17s\n",
1527 "Interface", " HELLO", " JOIN", " PRUNE",
1528 " REGISTER", " REGISTER-STOP", " ASSERT");
1529 vty_out(vty
, "%-10s%-18s%-17s%-17s%-17s%-17s%-17s\n", "",
1530 " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1531 " Rx/Tx", " Rx/Tx");
1533 "---------------------------------------------------------------------------------------------------------------\n");
1536 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim
->vrf_id
), node
, ifp
)) {
1537 if (strcmp(ifname
, ifp
->name
))
1540 pim_ifp
= ifp
->info
;
1545 if (pim_ifp
->pim_sock_fd
< 0)
1550 json_row
= json_object_new_object();
1551 json_object_pim_ifp_add(json_row
, ifp
);
1552 json_object_int_add(json_row
, "helloRx",
1553 pim_ifp
->pim_ifstat_hello_recv
);
1554 json_object_int_add(json_row
, "helloTx",
1555 pim_ifp
->pim_ifstat_hello_sent
);
1556 json_object_int_add(json_row
, "joinRx",
1557 pim_ifp
->pim_ifstat_join_recv
);
1558 json_object_int_add(json_row
, "joinTx",
1559 pim_ifp
->pim_ifstat_join_send
);
1560 json_object_int_add(json_row
, "registerRx",
1561 pim_ifp
->pim_ifstat_reg_recv
);
1562 json_object_int_add(json_row
, "registerTx",
1563 pim_ifp
->pim_ifstat_reg_recv
);
1564 json_object_int_add(json_row
, "registerStopRx",
1565 pim_ifp
->pim_ifstat_reg_stop_recv
);
1566 json_object_int_add(json_row
, "registerStopTx",
1567 pim_ifp
->pim_ifstat_reg_stop_send
);
1568 json_object_int_add(json_row
, "assertRx",
1569 pim_ifp
->pim_ifstat_assert_recv
);
1570 json_object_int_add(json_row
, "assertTx",
1571 pim_ifp
->pim_ifstat_assert_send
);
1573 json_object_object_add(json
, ifp
->name
, json_row
);
1576 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u \n",
1577 ifp
->name
, pim_ifp
->pim_ifstat_hello_recv
,
1578 pim_ifp
->pim_ifstat_hello_sent
,
1579 pim_ifp
->pim_ifstat_join_recv
,
1580 pim_ifp
->pim_ifstat_join_send
,
1581 pim_ifp
->pim_ifstat_prune_recv
,
1582 pim_ifp
->pim_ifstat_prune_send
,
1583 pim_ifp
->pim_ifstat_reg_recv
,
1584 pim_ifp
->pim_ifstat_reg_send
,
1585 pim_ifp
->pim_ifstat_reg_stop_recv
,
1586 pim_ifp
->pim_ifstat_reg_stop_send
,
1587 pim_ifp
->pim_ifstat_assert_recv
,
1588 pim_ifp
->pim_ifstat_assert_send
);
1592 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1593 json
, JSON_C_TO_STRING_PRETTY
));
1594 json_object_free(json
);
1597 vty_out(vty
, "%% No such interface\n");
1601 static void pim_show_join_helper(struct vty
*vty
,
1602 struct pim_interface
*pim_ifp
,
1603 struct pim_ifchannel
*ch
,
1608 char ch_src_str
[INET_ADDRSTRLEN
];
1609 char ch_grp_str
[INET_ADDRSTRLEN
];
1610 json_object
*json_iface
= NULL
;
1611 json_object
*json_row
= NULL
;
1612 json_object
*json_grp
= NULL
;
1613 struct in_addr ifaddr
;
1618 ifaddr
= pim_ifp
->primary_address
;
1620 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
,
1621 sizeof(ch_src_str
));
1622 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
,
1623 sizeof(ch_grp_str
));
1625 pim_time_uptime_begin(uptime
, sizeof(uptime
), now
,
1626 ch
->ifjoin_creation
);
1627 pim_time_timer_to_mmss(expire
, sizeof(expire
),
1628 ch
->t_ifjoin_expiry_timer
);
1629 pim_time_timer_to_mmss(prune
, sizeof(prune
),
1630 ch
->t_ifjoin_prune_pending_timer
);
1633 json_object_object_get_ex(json
, ch
->interface
->name
,
1637 json_iface
= json_object_new_object();
1638 json_object_pim_ifp_add(json_iface
,
1640 json_object_object_add(
1641 json
, ch
->interface
->name
, json_iface
);
1644 json_row
= json_object_new_object();
1645 json_object_string_add(json_row
, "source", ch_src_str
);
1646 json_object_string_add(json_row
, "group", ch_grp_str
);
1647 json_object_string_add(json_row
, "upTime", uptime
);
1648 json_object_string_add(json_row
, "expire", expire
);
1649 json_object_string_add(json_row
, "prune", prune
);
1650 json_object_string_add(
1651 json_row
, "channelJoinName",
1652 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
,
1654 if (PIM_IF_FLAG_TEST_S_G_RPT(ch
->flags
))
1655 json_object_int_add(json_row
, "SGRpt", 1);
1657 json_object_object_get_ex(json_iface
, ch_grp_str
,
1660 json_grp
= json_object_new_object();
1661 json_object_object_add(json_grp
, ch_src_str
,
1663 json_object_object_add(json_iface
, ch_grp_str
,
1666 json_object_object_add(json_grp
, ch_src_str
,
1670 "%-9s %-15s %-15s %-15s %-10s %8s %-6s %5s\n",
1671 ch
->interface
->name
, inet_ntoa(ifaddr
),
1672 ch_src_str
, ch_grp_str
,
1673 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
,
1675 uptime
, expire
, prune
);
1679 static void pim_show_join(struct pim_instance
*pim
, struct vty
*vty
, u_char uj
)
1681 struct listnode
*if_node
;
1682 struct pim_interface
*pim_ifp
;
1683 struct pim_ifchannel
*ch
;
1684 struct interface
*ifp
;
1686 json_object
*json
= NULL
;
1688 now
= pim_time_monotonic_sec();
1691 json
= json_object_new_object();
1694 "Interface Address Source Group State Uptime Expire Prune\n");
1696 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim
->vrf_id
), if_node
, ifp
)) {
1697 pim_ifp
= ifp
->info
;
1701 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
1702 pim_show_join_helper(vty
, pim_ifp
, ch
, json
, now
, uj
);
1703 } /* scan interface channels */
1707 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1708 json
, JSON_C_TO_STRING_PRETTY
));
1709 json_object_free(json
);
1713 static void pim_show_neighbors_single(struct pim_instance
*pim
, struct vty
*vty
,
1714 const char *neighbor
, u_char uj
)
1716 struct listnode
*node
;
1717 struct listnode
*neighnode
;
1718 struct interface
*ifp
;
1719 struct pim_interface
*pim_ifp
;
1720 struct pim_neighbor
*neigh
;
1722 int found_neighbor
= 0;
1723 int option_address_list
;
1724 int option_dr_priority
;
1725 int option_generation_id
;
1726 int option_holdtime
;
1727 int option_lan_prune_delay
;
1731 char neigh_src_str
[INET_ADDRSTRLEN
];
1733 json_object
*json
= NULL
;
1734 json_object
*json_ifp
= NULL
;
1735 json_object
*json_row
= NULL
;
1737 now
= pim_time_monotonic_sec();
1740 json
= json_object_new_object();
1742 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim
->vrf_id
), node
, ifp
)) {
1743 pim_ifp
= ifp
->info
;
1748 if (pim_ifp
->pim_sock_fd
< 0)
1751 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
1753 pim_inet4_dump("<src?>", neigh
->source_addr
,
1754 neigh_src_str
, sizeof(neigh_src_str
));
1757 * The user can specify either the interface name or the
1759 * If this pim_ifp matches neither then skip.
1761 if (strcmp(neighbor
, "detail")
1762 && strcmp(neighbor
, ifp
->name
)
1763 && strcmp(neighbor
, neigh_src_str
))
1767 pim_time_uptime(uptime
, sizeof(uptime
),
1768 now
- neigh
->creation
);
1769 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
1770 neigh
->t_expire_timer
);
1772 option_address_list
= 0;
1773 option_dr_priority
= 0;
1774 option_generation_id
= 0;
1775 option_holdtime
= 0;
1776 option_lan_prune_delay
= 0;
1779 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1780 PIM_OPTION_MASK_ADDRESS_LIST
))
1781 option_address_list
= 1;
1783 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1784 PIM_OPTION_MASK_DR_PRIORITY
))
1785 option_dr_priority
= 1;
1787 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1788 PIM_OPTION_MASK_GENERATION_ID
))
1789 option_generation_id
= 1;
1791 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1792 PIM_OPTION_MASK_HOLDTIME
))
1793 option_holdtime
= 1;
1795 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1796 PIM_OPTION_MASK_LAN_PRUNE_DELAY
))
1797 option_lan_prune_delay
= 1;
1799 if (PIM_OPTION_IS_SET(
1800 neigh
->hello_options
,
1801 PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION
))
1806 /* Does this ifp live in json? If not create
1808 json_object_object_get_ex(json
, ifp
->name
,
1812 json_ifp
= json_object_new_object();
1813 json_object_pim_ifp_add(json_ifp
, ifp
);
1814 json_object_object_add(json
, ifp
->name
,
1818 json_row
= json_object_new_object();
1819 json_object_string_add(json_row
, "interface",
1821 json_object_string_add(json_row
, "address",
1823 json_object_string_add(json_row
, "upTime",
1825 json_object_string_add(json_row
, "holdtime",
1827 json_object_int_add(json_row
, "drPriority",
1828 neigh
->dr_priority
);
1829 json_object_int_add(json_row
, "generationId",
1830 neigh
->generation_id
);
1832 if (option_address_list
)
1833 json_object_boolean_true_add(
1835 "helloOptionAddressList");
1837 if (option_dr_priority
)
1838 json_object_boolean_true_add(
1840 "helloOptionDrPriority");
1842 if (option_generation_id
)
1843 json_object_boolean_true_add(
1845 "helloOptionGenerationId");
1847 if (option_holdtime
)
1848 json_object_boolean_true_add(
1850 "helloOptionHoldtime");
1852 if (option_lan_prune_delay
)
1853 json_object_boolean_true_add(
1855 "helloOptionLanPruneDelay");
1858 json_object_boolean_true_add(
1859 json_row
, "helloOptionTBit");
1861 json_object_object_add(json_ifp
, neigh_src_str
,
1865 vty_out(vty
, "Interface : %s\n", ifp
->name
);
1866 vty_out(vty
, "Neighbor : %s\n", neigh_src_str
);
1874 " DR Priority : %d\n",
1875 neigh
->dr_priority
);
1877 " Generation ID : %08x\n",
1878 neigh
->generation_id
);
1880 " Override Interval (msec) : %d\n",
1881 neigh
->override_interval_msec
);
1883 " Propagation Delay (msec) : %d\n",
1884 neigh
->propagation_delay_msec
);
1886 " Hello Option - Address List : %s\n",
1887 option_address_list
? "yes" : "no");
1889 " Hello Option - DR Priority : %s\n",
1890 option_dr_priority
? "yes" : "no");
1892 " Hello Option - Generation ID : %s\n",
1893 option_generation_id
? "yes" : "no");
1895 " Hello Option - Holdtime : %s\n",
1896 option_holdtime
? "yes" : "no");
1898 " Hello Option - LAN Prune Delay : %s\n",
1899 option_lan_prune_delay
? "yes" : "no");
1901 " Hello Option - T-bit : %s\n",
1902 option_t_bit
? "yes" : "no");
1903 pim_bfd_show_info(vty
, neigh
->bfd_info
,
1911 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1912 json
, JSON_C_TO_STRING_PRETTY
));
1913 json_object_free(json
);
1916 if (!found_neighbor
)
1918 "%% No such interface or neighbor\n");
1923 static void pim_show_state(struct pim_instance
*pim
, struct vty
*vty
,
1924 const char *src_or_group
, const char *group
,
1927 struct channel_oil
*c_oil
;
1928 struct listnode
*node
;
1929 json_object
*json
= NULL
;
1930 json_object
*json_group
= NULL
;
1931 json_object
*json_ifp_in
= NULL
;
1932 json_object
*json_ifp_out
= NULL
;
1933 json_object
*json_source
= NULL
;
1936 now
= pim_time_monotonic_sec();
1939 json
= json_object_new_object();
1942 "Codes: J -> Pim Join, I -> IGMP Report, S -> Source, * -> Inherited from (*,G)");
1944 "\nInstalled Source Group IIF OIL\n");
1947 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
1948 char grp_str
[INET_ADDRSTRLEN
];
1949 char src_str
[INET_ADDRSTRLEN
];
1950 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
1951 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
1953 struct interface
*ifp_in
;
1956 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
1958 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
1960 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
1963 strcpy(in_ifname
, ifp_in
->name
);
1965 strcpy(in_ifname
, "<iif?>");
1968 if (strcmp(src_or_group
, src_str
)
1969 && strcmp(src_or_group
, grp_str
))
1972 if (group
&& strcmp(group
, grp_str
))
1978 /* Find the group, create it if it doesn't exist */
1979 json_object_object_get_ex(json
, grp_str
, &json_group
);
1982 json_group
= json_object_new_object();
1983 json_object_object_add(json
, grp_str
,
1987 /* Find the source nested under the group, create it if
1988 * it doesn't exist */
1989 json_object_object_get_ex(json_group
, src_str
,
1993 json_source
= json_object_new_object();
1994 json_object_object_add(json_group
, src_str
,
1998 /* Find the inbound interface nested under the source,
1999 * create it if it doesn't exist */
2000 json_object_object_get_ex(json_source
, in_ifname
,
2004 json_ifp_in
= json_object_new_object();
2005 json_object_object_add(json_source
, in_ifname
,
2007 json_object_int_add(json_source
, "Installed",
2009 json_object_int_add(json_source
, "RefCount",
2010 c_oil
->oil_ref_count
);
2011 json_object_int_add(json_source
, "OilListSize",
2013 json_object_int_add(
2014 json_source
, "OilRescan",
2015 c_oil
->oil_inherited_rescan
);
2016 json_object_int_add(json_source
, "LastUsed",
2017 c_oil
->cc
.lastused
);
2018 json_object_int_add(json_source
, "PacketCount",
2020 json_object_int_add(json_source
, "ByteCount",
2022 json_object_int_add(json_source
,
2024 c_oil
->cc
.wrong_if
);
2027 vty_out(vty
, "%-9d %-15s %-15s %-7s ",
2028 c_oil
->installed
, src_str
, grp_str
,
2032 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
2034 struct interface
*ifp_out
;
2035 char oif_uptime
[10];
2038 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
2042 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
2044 oif_uptime
, sizeof(oif_uptime
),
2045 now
- c_oil
->oif_creation
[oif_vif_index
]);
2048 strcpy(out_ifname
, ifp_out
->name
);
2050 strcpy(out_ifname
, "<oif?>");
2053 json_ifp_out
= json_object_new_object();
2054 json_object_string_add(json_ifp_out
, "source",
2056 json_object_string_add(json_ifp_out
, "group",
2058 json_object_string_add(json_ifp_out
,
2061 json_object_string_add(json_ifp_out
,
2062 "outboundInterface",
2064 json_object_int_add(json_ifp_out
, "installed",
2067 json_object_object_add(json_ifp_in
, out_ifname
,
2072 vty_out(vty
, "%s(%c%c%c%c)", out_ifname
,
2073 (c_oil
->oif_flags
[oif_vif_index
]
2074 & PIM_OIF_FLAG_PROTO_IGMP
)
2077 (c_oil
->oif_flags
[oif_vif_index
]
2078 & PIM_OIF_FLAG_PROTO_PIM
)
2081 (c_oil
->oif_flags
[oif_vif_index
]
2082 & PIM_OIF_FLAG_PROTO_SOURCE
)
2085 (c_oil
->oif_flags
[oif_vif_index
]
2086 & PIM_OIF_FLAG_PROTO_STAR
)
2090 vty_out(vty
, ", %s(%c%c%c%c)",
2092 (c_oil
->oif_flags
[oif_vif_index
]
2093 & PIM_OIF_FLAG_PROTO_IGMP
)
2096 (c_oil
->oif_flags
[oif_vif_index
]
2097 & PIM_OIF_FLAG_PROTO_PIM
)
2100 (c_oil
->oif_flags
[oif_vif_index
]
2101 & PIM_OIF_FLAG_PROTO_SOURCE
)
2104 (c_oil
->oif_flags
[oif_vif_index
]
2105 & PIM_OIF_FLAG_PROTO_STAR
)
2117 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2118 json
, JSON_C_TO_STRING_PRETTY
));
2119 json_object_free(json
);
2125 static void pim_show_neighbors(struct pim_instance
*pim
, struct vty
*vty
,
2128 struct listnode
*node
;
2129 struct listnode
*neighnode
;
2130 struct interface
*ifp
;
2131 struct pim_interface
*pim_ifp
;
2132 struct pim_neighbor
*neigh
;
2136 char neigh_src_str
[INET_ADDRSTRLEN
];
2137 json_object
*json
= NULL
;
2138 json_object
*json_ifp_rows
= NULL
;
2139 json_object
*json_row
= NULL
;
2141 now
= pim_time_monotonic_sec();
2144 json
= json_object_new_object();
2147 "Interface Neighbor Uptime Holdtime DR Pri\n");
2150 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim
->vrf_id
), node
, ifp
)) {
2151 pim_ifp
= ifp
->info
;
2156 if (pim_ifp
->pim_sock_fd
< 0)
2160 json_ifp_rows
= json_object_new_object();
2162 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
2164 pim_inet4_dump("<src?>", neigh
->source_addr
,
2165 neigh_src_str
, sizeof(neigh_src_str
));
2166 pim_time_uptime(uptime
, sizeof(uptime
),
2167 now
- neigh
->creation
);
2168 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
2169 neigh
->t_expire_timer
);
2172 json_row
= json_object_new_object();
2173 json_object_string_add(json_row
, "interface",
2175 json_object_string_add(json_row
, "neighbor",
2177 json_object_string_add(json_row
, "upTime",
2179 json_object_string_add(json_row
, "holdTime",
2181 json_object_int_add(json_row
, "holdTimeMax",
2183 json_object_int_add(json_row
, "drPriority",
2184 neigh
->dr_priority
);
2185 json_object_object_add(json_ifp_rows
,
2186 neigh_src_str
, json_row
);
2189 vty_out(vty
, "%-9s %15s %8s %8s %6d\n",
2190 ifp
->name
, neigh_src_str
, uptime
,
2191 expire
, neigh
->dr_priority
);
2196 json_object_object_add(json
, ifp
->name
, json_ifp_rows
);
2197 json_ifp_rows
= NULL
;
2202 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2203 json
, JSON_C_TO_STRING_PRETTY
));
2204 json_object_free(json
);
2208 static void pim_show_neighbors_secondary(struct pim_instance
*pim
,
2211 struct listnode
*node
;
2212 struct interface
*ifp
;
2215 "Interface Address Neighbor Secondary \n");
2217 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim
->vrf_id
), node
, ifp
)) {
2218 struct pim_interface
*pim_ifp
;
2219 struct in_addr ifaddr
;
2220 struct listnode
*neighnode
;
2221 struct pim_neighbor
*neigh
;
2223 pim_ifp
= ifp
->info
;
2228 if (pim_ifp
->pim_sock_fd
< 0)
2231 ifaddr
= pim_ifp
->primary_address
;
2233 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
2235 char neigh_src_str
[INET_ADDRSTRLEN
];
2236 struct listnode
*prefix_node
;
2239 if (!neigh
->prefix_list
)
2242 pim_inet4_dump("<src?>", neigh
->source_addr
,
2243 neigh_src_str
, sizeof(neigh_src_str
));
2245 for (ALL_LIST_ELEMENTS_RO(neigh
->prefix_list
,
2247 char neigh_sec_str
[PREFIX2STR_BUFFER
];
2249 prefix2str(p
, neigh_sec_str
,
2250 sizeof(neigh_sec_str
));
2252 vty_out(vty
, "%-9s %-15s %-15s %-15s\n",
2253 ifp
->name
, inet_ntoa(ifaddr
),
2254 neigh_src_str
, neigh_sec_str
);
2260 static void json_object_pim_upstream_add(json_object
*json
,
2261 struct pim_upstream
*up
)
2263 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED
)
2264 json_object_boolean_true_add(json
, "drJoinDesired");
2266 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED
)
2267 json_object_boolean_true_add(json
, "drJoinDesiredUpdated");
2269 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
2270 json_object_boolean_true_add(json
, "firstHopRouter");
2272 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_IGMP
)
2273 json_object_boolean_true_add(json
, "sourceIgmp");
2275 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_PIM
)
2276 json_object_boolean_true_add(json
, "sourcePim");
2278 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_STREAM
)
2279 json_object_boolean_true_add(json
, "sourceStream");
2281 /* XXX: need to print ths flag in the plain text display as well */
2282 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_MSDP
)
2283 json_object_boolean_true_add(json
, "sourceMsdp");
2287 pim_upstream_state2brief_str(enum pim_upstream_state join_state
,
2290 switch (join_state
) {
2291 case PIM_UPSTREAM_NOTJOINED
:
2292 strcpy(state_str
, "NotJ");
2294 case PIM_UPSTREAM_JOINED
:
2295 strcpy(state_str
, "J");
2298 strcpy(state_str
, "Unk");
2303 static const char *pim_reg_state2brief_str(enum pim_reg_state reg_state
,
2306 switch (reg_state
) {
2307 case PIM_REG_NOINFO
:
2308 strcpy(state_str
, "RegNI");
2311 strcpy(state_str
, "RegJ");
2313 case PIM_REG_JOIN_PENDING
:
2315 strcpy(state_str
, "RegP");
2318 strcpy(state_str
, "Unk");
2323 static void pim_show_upstream(struct pim_instance
*pim
, struct vty
*vty
,
2326 struct listnode
*upnode
;
2327 struct pim_upstream
*up
;
2329 json_object
*json
= NULL
;
2330 json_object
*json_group
= NULL
;
2331 json_object
*json_row
= NULL
;
2333 now
= pim_time_monotonic_sec();
2336 json
= json_object_new_object();
2339 "Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt\n");
2341 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
, up
)) {
2342 char src_str
[INET_ADDRSTRLEN
];
2343 char grp_str
[INET_ADDRSTRLEN
];
2345 char join_timer
[10];
2348 char msdp_reg_timer
[10];
2349 char state_str
[PIM_REG_STATE_STR_LEN
];
2351 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2352 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2353 pim_time_uptime(uptime
, sizeof(uptime
),
2354 now
- up
->state_transition
);
2355 pim_time_timer_to_hhmmss(join_timer
, sizeof(join_timer
),
2359 * If we have a J/P timer for the neighbor display that
2361 if (!up
->t_join_timer
) {
2362 struct pim_neighbor
*nbr
;
2364 nbr
= pim_neighbor_find(
2365 up
->rpf
.source_nexthop
.interface
,
2366 up
->rpf
.rpf_addr
.u
.prefix4
);
2368 pim_time_timer_to_hhmmss(join_timer
,
2373 pim_time_timer_to_hhmmss(rs_timer
, sizeof(rs_timer
),
2375 pim_time_timer_to_hhmmss(ka_timer
, sizeof(ka_timer
),
2377 pim_time_timer_to_hhmmss(msdp_reg_timer
, sizeof(msdp_reg_timer
),
2378 up
->t_msdp_reg_timer
);
2380 pim_upstream_state2brief_str(up
->join_state
, state_str
);
2381 if (up
->reg_state
!= PIM_REG_NOINFO
) {
2382 char tmp_str
[PIM_REG_STATE_STR_LEN
];
2384 sprintf(state_str
+ strlen(state_str
), ",%s",
2385 pim_reg_state2brief_str(up
->reg_state
,
2390 json_object_object_get_ex(json
, grp_str
, &json_group
);
2393 json_group
= json_object_new_object();
2394 json_object_object_add(json
, grp_str
,
2398 json_row
= json_object_new_object();
2399 json_object_pim_upstream_add(json_row
, up
);
2400 json_object_string_add(
2401 json_row
, "inboundInterface",
2402 up
->rpf
.source_nexthop
.interface
->name
);
2403 json_object_string_add(json_row
, "source", src_str
);
2404 json_object_string_add(json_row
, "group", grp_str
);
2405 json_object_string_add(json_row
, "state", state_str
);
2406 json_object_string_add(
2407 json_row
, "joinState",
2408 pim_upstream_state2str(up
->join_state
));
2409 json_object_string_add(
2410 json_row
, "regState",
2411 pim_reg_state2str(up
->reg_state
, state_str
));
2412 json_object_string_add(json_row
, "upTime", uptime
);
2413 json_object_string_add(json_row
, "joinTimer",
2415 json_object_string_add(json_row
, "resetTimer",
2417 json_object_string_add(json_row
, "keepaliveTimer",
2419 json_object_string_add(json_row
, "msdpRegTimer",
2421 json_object_int_add(json_row
, "refCount",
2423 json_object_int_add(json_row
, "sptBit", up
->sptbit
);
2424 json_object_object_add(json_group
, src_str
, json_row
);
2427 "%-10s%-15s %-15s %-11s %-8s %-9s %-9s %-9s %6d\n",
2428 up
->rpf
.source_nexthop
.interface
->name
, src_str
,
2429 grp_str
, state_str
, uptime
, join_timer
,
2430 rs_timer
, ka_timer
, up
->ref_count
);
2435 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2436 json
, JSON_C_TO_STRING_PRETTY
));
2437 json_object_free(json
);
2441 static void pim_show_join_desired_helper(struct pim_instance
*pim
,
2443 struct pim_interface
*pim_ifp
,
2444 struct pim_ifchannel
*ch
,
2448 struct pim_upstream
*up
= ch
->upstream
;
2449 json_object
*json_group
= NULL
;
2450 char src_str
[INET_ADDRSTRLEN
];
2451 char grp_str
[INET_ADDRSTRLEN
];
2452 json_object
*json_row
= NULL
;
2454 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2455 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2458 json_object_object_get_ex(json
, grp_str
, &json_group
);
2461 json_group
= json_object_new_object();
2462 json_object_object_add(json
, grp_str
,
2466 json_row
= json_object_new_object();
2467 json_object_pim_upstream_add(json_row
, up
);
2468 json_object_string_add(json_row
, "interface",
2469 ch
->interface
->name
);
2470 json_object_string_add(json_row
, "source", src_str
);
2471 json_object_string_add(json_row
, "group", grp_str
);
2473 if (pim_macro_ch_lost_assert(ch
))
2474 json_object_boolean_true_add(json_row
,
2477 if (pim_macro_chisin_joins(ch
))
2478 json_object_boolean_true_add(json_row
, "joins");
2480 if (pim_macro_chisin_pim_include(ch
))
2481 json_object_boolean_true_add(json_row
,
2484 if (pim_upstream_evaluate_join_desired(pim
, up
))
2485 json_object_boolean_true_add(
2486 json_row
, "evaluateJoinDesired");
2488 json_object_object_add(json_group
, src_str
, json_row
);
2492 "%-9s %-15s %-15s %-10s %-5s %-10s %-11s %-6s\n",
2493 ch
->interface
->name
, src_str
, grp_str
,
2494 pim_macro_ch_lost_assert(ch
) ? "yes" : "no",
2495 pim_macro_chisin_joins(ch
) ? "yes" : "no",
2496 pim_macro_chisin_pim_include(ch
) ? "yes" : "no",
2497 PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(
2501 pim_upstream_evaluate_join_desired(pim
, up
)
2507 static void pim_show_join_desired(struct pim_instance
*pim
, struct vty
*vty
,
2510 struct listnode
*if_node
;
2511 struct pim_interface
*pim_ifp
;
2512 struct pim_ifchannel
*ch
;
2513 struct interface
*ifp
;
2515 json_object
*json
= NULL
;
2518 json
= json_object_new_object();
2521 "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD\n");
2523 /* scan per-interface (S,G) state */
2524 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim
->vrf_id
), if_node
, ifp
)) {
2525 pim_ifp
= ifp
->info
;
2530 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
2531 /* scan all interfaces */
2532 pim_show_join_desired_helper(pim
, vty
,
2539 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2540 json
, JSON_C_TO_STRING_PRETTY
));
2541 json_object_free(json
);
2545 static void pim_show_upstream_rpf(struct pim_instance
*pim
, struct vty
*vty
,
2548 struct listnode
*upnode
;
2549 struct pim_upstream
*up
;
2550 json_object
*json
= NULL
;
2551 json_object
*json_group
= NULL
;
2552 json_object
*json_row
= NULL
;
2555 json
= json_object_new_object();
2558 "Source Group RpfIface RibNextHop RpfAddress \n");
2560 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
, up
)) {
2561 char src_str
[INET_ADDRSTRLEN
];
2562 char grp_str
[INET_ADDRSTRLEN
];
2563 char rpf_nexthop_str
[PREFIX_STRLEN
];
2564 char rpf_addr_str
[PREFIX_STRLEN
];
2565 struct pim_rpf
*rpf
;
2566 const char *rpf_ifname
;
2570 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2571 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2572 pim_addr_dump("<nexthop?>",
2573 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2574 rpf_nexthop_str
, sizeof(rpf_nexthop_str
));
2575 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2576 sizeof(rpf_addr_str
));
2578 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2581 json_object_object_get_ex(json
, grp_str
, &json_group
);
2584 json_group
= json_object_new_object();
2585 json_object_object_add(json
, grp_str
,
2589 json_row
= json_object_new_object();
2590 json_object_pim_upstream_add(json_row
, up
);
2591 json_object_string_add(json_row
, "source", src_str
);
2592 json_object_string_add(json_row
, "group", grp_str
);
2593 json_object_string_add(json_row
, "rpfInterface",
2595 json_object_string_add(json_row
, "ribNexthop",
2597 json_object_string_add(json_row
, "rpfAddress",
2599 json_object_object_add(json_group
, src_str
, json_row
);
2601 vty_out(vty
, "%-15s %-15s %-8s %-15s %-15s\n", src_str
,
2602 grp_str
, rpf_ifname
, rpf_nexthop_str
,
2608 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2609 json
, JSON_C_TO_STRING_PRETTY
));
2610 json_object_free(json
);
2614 static void show_rpf_refresh_stats(struct vty
*vty
, time_t now
,
2617 char refresh_uptime
[10];
2619 pim_time_uptime_begin(refresh_uptime
, sizeof(refresh_uptime
), now
,
2620 qpim_rpf_cache_refresh_last
);
2623 json_object_int_add(json
, "rpfCacheRefreshDelayMsecs",
2624 qpim_rpf_cache_refresh_delay_msec
);
2625 json_object_int_add(
2626 json
, "rpfCacheRefreshTimer",
2627 pim_time_timer_remain_msec(qpim_rpf_cache_refresher
));
2628 json_object_int_add(json
, "rpfCacheRefreshRequests",
2629 qpim_rpf_cache_refresh_requests
);
2630 json_object_int_add(json
, "rpfCacheRefreshEvents",
2631 qpim_rpf_cache_refresh_events
);
2632 json_object_string_add(json
, "rpfCacheRefreshLast",
2634 json_object_int_add(json
, "nexthopLookups",
2635 qpim_nexthop_lookups
);
2636 json_object_int_add(json
, "nexthopLookupsAvoided",
2637 nexthop_lookups_avoided
);
2640 "RPF Cache Refresh Delay: %ld msecs\n"
2641 "RPF Cache Refresh Timer: %ld msecs\n"
2642 "RPF Cache Refresh Requests: %lld\n"
2643 "RPF Cache Refresh Events: %lld\n"
2644 "RPF Cache Refresh Last: %s\n"
2645 "Nexthop Lookups: %lld\n"
2646 "Nexthop Lookups Avoided: %lld\n",
2647 qpim_rpf_cache_refresh_delay_msec
,
2648 pim_time_timer_remain_msec(qpim_rpf_cache_refresher
),
2649 (long long)qpim_rpf_cache_refresh_requests
,
2650 (long long)qpim_rpf_cache_refresh_events
,
2651 refresh_uptime
, (long long)qpim_nexthop_lookups
,
2652 (long long)nexthop_lookups_avoided
);
2656 static void show_scan_oil_stats(struct pim_instance
*pim
, struct vty
*vty
,
2659 char uptime_scan_oil
[10];
2660 char uptime_mroute_add
[10];
2661 char uptime_mroute_del
[10];
2663 pim_time_uptime_begin(uptime_scan_oil
, sizeof(uptime_scan_oil
), now
,
2664 qpim_scan_oil_last
);
2665 pim_time_uptime_begin(uptime_mroute_add
, sizeof(uptime_mroute_add
), now
,
2666 pim
->mroute_add_last
);
2667 pim_time_uptime_begin(uptime_mroute_del
, sizeof(uptime_mroute_del
), now
,
2668 pim
->mroute_del_last
);
2671 "Scan OIL - Last: %s Events: %lld\n"
2672 "MFC Add - Last: %s Events: %lld\n"
2673 "MFC Del - Last: %s Events: %lld\n",
2674 uptime_scan_oil
, (long long)qpim_scan_oil_events
,
2675 uptime_mroute_add
, (long long)pim
->mroute_add_events
,
2676 uptime_mroute_del
, (long long)pim
->mroute_del_events
);
2679 static void pim_show_rpf(struct pim_instance
*pim
, struct vty
*vty
, u_char uj
)
2681 struct listnode
*up_node
;
2682 struct pim_upstream
*up
;
2683 time_t now
= pim_time_monotonic_sec();
2684 json_object
*json
= NULL
;
2685 json_object
*json_group
= NULL
;
2686 json_object
*json_row
= NULL
;
2689 json
= json_object_new_object();
2690 show_rpf_refresh_stats(vty
, now
, json
);
2692 show_rpf_refresh_stats(vty
, now
, json
);
2695 "Source Group RpfIface RpfAddress RibNextHop Metric Pref\n");
2698 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, up_node
, up
)) {
2699 char src_str
[INET_ADDRSTRLEN
];
2700 char grp_str
[INET_ADDRSTRLEN
];
2701 char rpf_addr_str
[PREFIX_STRLEN
];
2702 char rib_nexthop_str
[PREFIX_STRLEN
];
2703 const char *rpf_ifname
;
2704 struct pim_rpf
*rpf
= &up
->rpf
;
2706 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2707 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2708 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2709 sizeof(rpf_addr_str
));
2710 pim_addr_dump("<nexthop?>",
2711 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2712 rib_nexthop_str
, sizeof(rib_nexthop_str
));
2714 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2717 json_object_object_get_ex(json
, grp_str
, &json_group
);
2720 json_group
= json_object_new_object();
2721 json_object_object_add(json
, grp_str
,
2725 json_row
= json_object_new_object();
2726 json_object_string_add(json_row
, "source", src_str
);
2727 json_object_string_add(json_row
, "group", grp_str
);
2728 json_object_string_add(json_row
, "rpfInterface",
2730 json_object_string_add(json_row
, "rpfAddress",
2732 json_object_string_add(json_row
, "ribNexthop",
2734 json_object_int_add(
2735 json_row
, "routeMetric",
2736 rpf
->source_nexthop
.mrib_route_metric
);
2737 json_object_int_add(
2738 json_row
, "routePreference",
2739 rpf
->source_nexthop
.mrib_metric_preference
);
2740 json_object_object_add(json_group
, src_str
, json_row
);
2743 vty_out(vty
, "%-15s %-15s %-8s %-15s %-15s %6d %4d\n",
2744 src_str
, grp_str
, rpf_ifname
, rpf_addr_str
,
2746 rpf
->source_nexthop
.mrib_route_metric
,
2747 rpf
->source_nexthop
.mrib_metric_preference
);
2752 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2753 json
, JSON_C_TO_STRING_PRETTY
));
2754 json_object_free(json
);
2758 struct pnc_cache_walk_data
{
2760 struct pim_instance
*pim
;
2763 static int pim_print_pnc_cache_walkcb(struct hash_backet
*backet
, void *arg
)
2765 struct pim_nexthop_cache
*pnc
= backet
->data
;
2766 struct pnc_cache_walk_data
*cwd
= arg
;
2767 struct vty
*vty
= cwd
->vty
;
2768 struct pim_instance
*pim
= cwd
->pim
;
2769 struct nexthop
*nh_node
= NULL
;
2770 ifindex_t first_ifindex
;
2771 struct interface
*ifp
= NULL
;
2776 for (nh_node
= pnc
->nexthop
; nh_node
; nh_node
= nh_node
->next
) {
2777 first_ifindex
= nh_node
->ifindex
;
2778 ifp
= if_lookup_by_index(first_ifindex
, pim
->vrf_id
);
2780 vty_out(vty
, "%-15s ", inet_ntoa(pnc
->rpf
.rpf_addr
.u
.prefix4
));
2781 vty_out(vty
, "%-14s ", ifp
? ifp
->name
: "NULL");
2782 vty_out(vty
, "%s ", inet_ntoa(nh_node
->gate
.ipv4
));
2788 static void pim_show_nexthop(struct pim_instance
*pim
, struct vty
*vty
)
2790 struct pnc_cache_walk_data cwd
;
2794 vty_out(vty
, "Number of registered addresses: %lu\n",
2795 pim
->rpf_hash
->count
);
2796 vty_out(vty
, "Address Interface Nexthop\n");
2797 vty_out(vty
, "-------------------------------------------\n");
2799 hash_walk(pim
->rpf_hash
, pim_print_pnc_cache_walkcb
, &cwd
);
2802 static void igmp_show_groups(struct pim_instance
*pim
, struct vty
*vty
,
2805 struct listnode
*ifnode
;
2806 struct interface
*ifp
;
2808 json_object
*json
= NULL
;
2809 json_object
*json_iface
= NULL
;
2810 json_object
*json_row
= NULL
;
2812 now
= pim_time_monotonic_sec();
2815 json
= json_object_new_object();
2818 "Interface Address Group Mode Timer Srcs V Uptime \n");
2820 /* scan interfaces */
2821 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim
->vrf_id
), ifnode
, ifp
)) {
2822 struct pim_interface
*pim_ifp
= ifp
->info
;
2823 struct listnode
*sock_node
;
2824 struct igmp_sock
*igmp
;
2829 /* scan igmp sockets */
2830 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
2832 char ifaddr_str
[INET_ADDRSTRLEN
];
2833 struct listnode
*grpnode
;
2834 struct igmp_group
*grp
;
2836 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
2837 sizeof(ifaddr_str
));
2839 /* scan igmp groups */
2840 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
2842 char group_str
[INET_ADDRSTRLEN
];
2846 pim_inet4_dump("<group?>", grp
->group_addr
,
2847 group_str
, sizeof(group_str
));
2848 pim_time_timer_to_hhmmss(hhmmss
, sizeof(hhmmss
),
2849 grp
->t_group_timer
);
2850 pim_time_uptime(uptime
, sizeof(uptime
),
2851 now
- grp
->group_creation
);
2854 json_object_object_get_ex(
2855 json
, ifp
->name
, &json_iface
);
2859 json_object_new_object();
2860 json_object_pim_ifp_add(
2862 json_object_object_add(
2867 json_row
= json_object_new_object();
2868 json_object_string_add(
2869 json_row
, "source", ifaddr_str
);
2870 json_object_string_add(
2871 json_row
, "group", group_str
);
2873 if (grp
->igmp_version
== 3)
2874 json_object_string_add(
2876 grp
->group_filtermode_isexcl
2880 json_object_string_add(json_row
,
2882 json_object_int_add(
2883 json_row
, "sourcesCount",
2884 grp
->group_source_list
2886 grp
->group_source_list
)
2888 json_object_int_add(json_row
, "version",
2890 json_object_string_add(
2891 json_row
, "uptime", uptime
);
2892 json_object_object_add(json_iface
,
2898 "%-9s %-15s %-15s %4s %8s %4d %d %8s\n",
2899 ifp
->name
, ifaddr_str
,
2901 grp
->igmp_version
== 3
2902 ? (grp
->group_filtermode_isexcl
2907 grp
->group_source_list
2909 grp
->group_source_list
)
2911 grp
->igmp_version
, uptime
);
2913 } /* scan igmp groups */
2914 } /* scan igmp sockets */
2915 } /* scan interfaces */
2918 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2919 json
, JSON_C_TO_STRING_PRETTY
));
2920 json_object_free(json
);
2924 static void igmp_show_group_retransmission(struct pim_instance
*pim
,
2927 struct listnode
*ifnode
;
2928 struct interface
*ifp
;
2931 "Interface Address Group RetTimer Counter RetSrcs\n");
2933 /* scan interfaces */
2934 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim
->vrf_id
), ifnode
, ifp
)) {
2935 struct pim_interface
*pim_ifp
= ifp
->info
;
2936 struct listnode
*sock_node
;
2937 struct igmp_sock
*igmp
;
2942 /* scan igmp sockets */
2943 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
2945 char ifaddr_str
[INET_ADDRSTRLEN
];
2946 struct listnode
*grpnode
;
2947 struct igmp_group
*grp
;
2949 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
2950 sizeof(ifaddr_str
));
2952 /* scan igmp groups */
2953 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
2955 char group_str
[INET_ADDRSTRLEN
];
2956 char grp_retr_mmss
[10];
2957 struct listnode
*src_node
;
2958 struct igmp_source
*src
;
2959 int grp_retr_sources
= 0;
2961 pim_inet4_dump("<group?>", grp
->group_addr
,
2962 group_str
, sizeof(group_str
));
2963 pim_time_timer_to_mmss(
2964 grp_retr_mmss
, sizeof(grp_retr_mmss
),
2965 grp
->t_group_query_retransmit_timer
);
2968 /* count group sources with retransmission state
2970 for (ALL_LIST_ELEMENTS_RO(
2971 grp
->group_source_list
, src_node
,
2973 if (src
->source_query_retransmit_count
2979 vty_out(vty
, "%-9s %-15s %-15s %-8s %7d %7d\n",
2980 ifp
->name
, ifaddr_str
, group_str
,
2982 grp
->group_specific_query_retransmit_count
,
2985 } /* scan igmp groups */
2986 } /* scan igmp sockets */
2987 } /* scan interfaces */
2990 static void igmp_show_sources(struct pim_instance
*pim
, struct vty
*vty
)
2992 struct listnode
*ifnode
;
2993 struct interface
*ifp
;
2996 now
= pim_time_monotonic_sec();
2999 "Interface Address Group Source Timer Fwd Uptime \n");
3001 /* scan interfaces */
3002 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim
->vrf_id
), ifnode
, ifp
)) {
3003 struct pim_interface
*pim_ifp
= ifp
->info
;
3004 struct listnode
*sock_node
;
3005 struct igmp_sock
*igmp
;
3010 /* scan igmp sockets */
3011 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3013 char ifaddr_str
[INET_ADDRSTRLEN
];
3014 struct listnode
*grpnode
;
3015 struct igmp_group
*grp
;
3017 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3018 sizeof(ifaddr_str
));
3020 /* scan igmp groups */
3021 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3023 char group_str
[INET_ADDRSTRLEN
];
3024 struct listnode
*srcnode
;
3025 struct igmp_source
*src
;
3027 pim_inet4_dump("<group?>", grp
->group_addr
,
3028 group_str
, sizeof(group_str
));
3030 /* scan group sources */
3031 for (ALL_LIST_ELEMENTS_RO(
3032 grp
->group_source_list
, srcnode
,
3034 char source_str
[INET_ADDRSTRLEN
];
3039 "<source?>", src
->source_addr
,
3040 source_str
, sizeof(source_str
));
3042 pim_time_timer_to_mmss(
3044 src
->t_source_timer
);
3047 uptime
, sizeof(uptime
),
3048 now
- src
->source_creation
);
3051 "%-9s %-15s %-15s %-15s %5s %3s %8s\n",
3052 ifp
->name
, ifaddr_str
,
3053 group_str
, source_str
, mmss
,
3054 IGMP_SOURCE_TEST_FORWARDING(
3060 } /* scan group sources */
3061 } /* scan igmp groups */
3062 } /* scan igmp sockets */
3063 } /* scan interfaces */
3066 static void igmp_show_source_retransmission(struct pim_instance
*pim
,
3069 struct listnode
*ifnode
;
3070 struct interface
*ifp
;
3073 "Interface Address Group Source Counter\n");
3075 /* scan interfaces */
3076 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim
->vrf_id
), ifnode
, ifp
)) {
3077 struct pim_interface
*pim_ifp
= ifp
->info
;
3078 struct listnode
*sock_node
;
3079 struct igmp_sock
*igmp
;
3084 /* scan igmp sockets */
3085 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3087 char ifaddr_str
[INET_ADDRSTRLEN
];
3088 struct listnode
*grpnode
;
3089 struct igmp_group
*grp
;
3091 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3092 sizeof(ifaddr_str
));
3094 /* scan igmp groups */
3095 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3097 char group_str
[INET_ADDRSTRLEN
];
3098 struct listnode
*srcnode
;
3099 struct igmp_source
*src
;
3101 pim_inet4_dump("<group?>", grp
->group_addr
,
3102 group_str
, sizeof(group_str
));
3104 /* scan group sources */
3105 for (ALL_LIST_ELEMENTS_RO(
3106 grp
->group_source_list
, srcnode
,
3108 char source_str
[INET_ADDRSTRLEN
];
3111 "<source?>", src
->source_addr
,
3112 source_str
, sizeof(source_str
));
3115 "%-9s %-15s %-15s %-15s %7d\n",
3116 ifp
->name
, ifaddr_str
,
3117 group_str
, source_str
,
3118 src
->source_query_retransmit_count
);
3120 } /* scan group sources */
3121 } /* scan igmp groups */
3122 } /* scan igmp sockets */
3123 } /* scan interfaces */
3126 static void clear_igmp_interfaces(struct pim_instance
*pim
)
3128 struct listnode
*ifnode
;
3129 struct listnode
*ifnextnode
;
3130 struct interface
*ifp
;
3132 for (ALL_LIST_ELEMENTS(vrf_iflist(pim
->vrf_id
), ifnode
, ifnextnode
,
3134 pim_if_addr_del_all_igmp(ifp
);
3137 for (ALL_LIST_ELEMENTS(vrf_iflist(pim
->vrf_id
), ifnode
, ifnextnode
,
3139 pim_if_addr_add_all(ifp
);
3143 static void clear_pim_interfaces(struct pim_instance
*pim
)
3145 struct listnode
*ifnode
;
3146 struct listnode
*ifnextnode
;
3147 struct interface
*ifp
;
3149 for (ALL_LIST_ELEMENTS(vrf_iflist(pim
->vrf_id
), ifnode
, ifnextnode
,
3152 pim_neighbor_delete_all(ifp
, "interface cleared");
3157 static void clear_interfaces(struct pim_instance
*pim
)
3159 clear_igmp_interfaces(pim
);
3160 clear_pim_interfaces(pim
);
3163 #define PIM_GET_PIM_INTERFACE(pim_ifp, ifp) \
3164 pim_ifp = ifp->info; \
3167 "%% Enable PIM and/or IGMP on this interface first\n"); \
3168 return CMD_WARNING_CONFIG_FAILED; \
3171 DEFUN (clear_ip_interfaces
,
3172 clear_ip_interfaces_cmd
,
3173 "clear ip interfaces [vrf NAME]",
3176 "Reset interfaces\n"
3180 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3185 clear_interfaces(vrf
->info
);
3190 DEFUN (clear_ip_igmp_interfaces
,
3191 clear_ip_igmp_interfaces_cmd
,
3192 "clear ip igmp [vrf NAME] interfaces",
3197 "Reset IGMP interfaces\n")
3200 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3205 clear_igmp_interfaces(vrf
->info
);
3210 static void mroute_add_all(struct pim_instance
*pim
)
3212 struct listnode
*node
;
3213 struct channel_oil
*c_oil
;
3215 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
3216 if (pim_mroute_add(c_oil
, __PRETTY_FUNCTION__
)) {
3217 /* just log warning */
3218 char source_str
[INET_ADDRSTRLEN
];
3219 char group_str
[INET_ADDRSTRLEN
];
3220 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
,
3221 source_str
, sizeof(source_str
));
3222 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
,
3223 group_str
, sizeof(group_str
));
3224 zlog_warn("%s %s: (S,G)=(%s,%s) failure writing MFC",
3225 __FILE__
, __PRETTY_FUNCTION__
, source_str
,
3231 static void mroute_del_all(struct pim_instance
*pim
)
3233 struct listnode
*node
;
3234 struct channel_oil
*c_oil
;
3236 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
3237 if (pim_mroute_del(c_oil
, __PRETTY_FUNCTION__
)) {
3238 /* just log warning */
3239 char source_str
[INET_ADDRSTRLEN
];
3240 char group_str
[INET_ADDRSTRLEN
];
3241 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
,
3242 source_str
, sizeof(source_str
));
3243 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
,
3244 group_str
, sizeof(group_str
));
3245 zlog_warn("%s %s: (S,G)=(%s,%s) failure clearing MFC",
3246 __FILE__
, __PRETTY_FUNCTION__
, source_str
,
3252 DEFUN (clear_ip_mroute
,
3253 clear_ip_mroute_cmd
,
3254 "clear ip mroute [vrf NAME]",
3257 "Reset multicast routes\n"
3261 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3266 mroute_del_all(vrf
->info
);
3267 mroute_add_all(vrf
->info
);
3272 DEFUN (clear_ip_pim_interfaces
,
3273 clear_ip_pim_interfaces_cmd
,
3274 "clear ip pim [vrf NAME] interfaces",
3279 "Reset PIM interfaces\n")
3282 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3287 clear_pim_interfaces(vrf
->info
);
3292 DEFUN (clear_ip_pim_interface_traffic
,
3293 clear_ip_pim_interface_traffic_cmd
,
3294 "clear ip pim [vrf NAME] interface traffic",
3297 "PIM clear commands\n"
3299 "Reset PIM interfaces\n"
3300 "Reset Protocol Packet counters\n")
3303 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3304 struct listnode
*ifnode
= NULL
;
3305 struct listnode
*ifnextnode
= NULL
;
3306 struct interface
*ifp
= NULL
;
3307 struct pim_interface
*pim_ifp
= NULL
;
3312 for (ALL_LIST_ELEMENTS(vrf_iflist(vrf
->vrf_id
), ifnode
, ifnextnode
,
3314 pim_ifp
= ifp
->info
;
3319 pim_ifp
->pim_ifstat_hello_recv
= 0;
3320 pim_ifp
->pim_ifstat_hello_sent
= 0;
3321 pim_ifp
->pim_ifstat_join_recv
= 0;
3322 pim_ifp
->pim_ifstat_join_send
= 0;
3323 pim_ifp
->pim_ifstat_prune_recv
= 0;
3324 pim_ifp
->pim_ifstat_prune_send
= 0;
3325 pim_ifp
->pim_ifstat_reg_recv
= 0;
3326 pim_ifp
->pim_ifstat_reg_send
= 0;
3327 pim_ifp
->pim_ifstat_reg_stop_recv
= 0;
3328 pim_ifp
->pim_ifstat_reg_stop_send
= 0;
3329 pim_ifp
->pim_ifstat_assert_recv
= 0;
3330 pim_ifp
->pim_ifstat_assert_send
= 0;
3336 DEFUN (clear_ip_pim_oil
,
3337 clear_ip_pim_oil_cmd
,
3338 "clear ip pim [vrf NAME] oil",
3343 "Rescan PIM OIL (output interface list)\n")
3346 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3351 pim_scan_oil(vrf
->info
);
3356 DEFUN (show_ip_igmp_interface
,
3357 show_ip_igmp_interface_cmd
,
3358 "show ip igmp [vrf NAME] interface [detail|WORD] [json]",
3363 "IGMP interface information\n"
3369 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3370 u_char uj
= use_json(argc
, argv
);
3375 if (argv_find(argv
, argc
, "detail", &idx
)
3376 || argv_find(argv
, argc
, "WORD", &idx
))
3377 igmp_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
3379 igmp_show_interfaces(vrf
->info
, vty
, uj
);
3384 DEFUN (show_ip_igmp_interface_vrf_all
,
3385 show_ip_igmp_interface_vrf_all_cmd
,
3386 "show ip igmp vrf all interface [detail|WORD] [json]",
3391 "IGMP interface information\n"
3397 u_char uj
= use_json(argc
, argv
);
3403 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3407 vty_out(vty
, " \"%s\": ", vrf
->name
);
3410 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3411 if (argv_find(argv
, argc
, "detail", &idx
)
3412 || argv_find(argv
, argc
, "WORD", &idx
))
3413 igmp_show_interfaces_single(vrf
->info
, vty
,
3414 argv
[idx
]->arg
, uj
);
3416 igmp_show_interfaces(vrf
->info
, vty
, uj
);
3419 vty_out(vty
, "}\n");
3424 DEFUN (show_ip_igmp_join
,
3425 show_ip_igmp_join_cmd
,
3426 "show ip igmp [vrf NAME] join",
3431 "IGMP static join information\n")
3434 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3439 igmp_show_interface_join(vrf
->info
, vty
);
3444 DEFUN (show_ip_igmp_join_vrf_all
,
3445 show_ip_igmp_join_vrf_all_cmd
,
3446 "show ip igmp vrf all join",
3451 "IGMP static join information\n")
3453 u_char uj
= use_json(argc
, argv
);
3459 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3463 vty_out(vty
, " \"%s\": ", vrf
->name
);
3466 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3467 igmp_show_interface_join(vrf
->info
, vty
);
3470 vty_out(vty
, "}\n");
3475 DEFUN (show_ip_igmp_groups
,
3476 show_ip_igmp_groups_cmd
,
3477 "show ip igmp [vrf NAME] groups [json]",
3486 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3487 u_char uj
= use_json(argc
, argv
);
3492 igmp_show_groups(vrf
->info
, vty
, uj
);
3497 DEFUN (show_ip_igmp_groups_vrf_all
,
3498 show_ip_igmp_groups_vrf_all_cmd
,
3499 "show ip igmp vrf all groups [json]",
3507 u_char uj
= use_json(argc
, argv
);
3513 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3517 vty_out(vty
, " \"%s\": ", vrf
->name
);
3520 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3521 igmp_show_groups(vrf
->info
, vty
, uj
);
3524 vty_out(vty
, "}\n");
3529 DEFUN (show_ip_igmp_groups_retransmissions
,
3530 show_ip_igmp_groups_retransmissions_cmd
,
3531 "show ip igmp [vrf NAME] groups retransmissions",
3537 "IGMP group retransmissions\n")
3540 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3545 igmp_show_group_retransmission(vrf
->info
, vty
);
3550 DEFUN (show_ip_igmp_sources
,
3551 show_ip_igmp_sources_cmd
,
3552 "show ip igmp [vrf NAME] sources",
3560 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3565 igmp_show_sources(vrf
->info
, vty
);
3570 DEFUN (show_ip_igmp_sources_retransmissions
,
3571 show_ip_igmp_sources_retransmissions_cmd
,
3572 "show ip igmp [vrf NAME] sources retransmissions",
3578 "IGMP source retransmissions\n")
3581 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3586 igmp_show_source_retransmission(vrf
->info
, vty
);
3591 DEFUN (show_ip_pim_assert
,
3592 show_ip_pim_assert_cmd
,
3593 "show ip pim [vrf NAME] assert",
3598 "PIM interface assert\n")
3601 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3606 pim_show_assert(vrf
->info
, vty
);
3611 DEFUN (show_ip_pim_assert_internal
,
3612 show_ip_pim_assert_internal_cmd
,
3613 "show ip pim [vrf NAME] assert-internal",
3618 "PIM interface internal assert state\n")
3621 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3626 pim_show_assert_internal(vrf
->info
, vty
);
3631 DEFUN (show_ip_pim_assert_metric
,
3632 show_ip_pim_assert_metric_cmd
,
3633 "show ip pim [vrf NAME] assert-metric",
3638 "PIM interface assert metric\n")
3641 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3646 pim_show_assert_metric(vrf
->info
, vty
);
3651 DEFUN (show_ip_pim_assert_winner_metric
,
3652 show_ip_pim_assert_winner_metric_cmd
,
3653 "show ip pim [vrf NAME] assert-winner-metric",
3658 "PIM interface assert winner metric\n")
3661 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3666 pim_show_assert_winner_metric(vrf
->info
, vty
);
3671 DEFUN (show_ip_pim_interface
,
3672 show_ip_pim_interface_cmd
,
3673 "show ip pim [vrf NAME] interface [detail|WORD] [json]",
3678 "PIM interface information\n"
3684 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3685 u_char uj
= use_json(argc
, argv
);
3690 if (argv_find(argv
, argc
, "WORD", &idx
)
3691 || argv_find(argv
, argc
, "detail", &idx
))
3692 pim_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
3694 pim_show_interfaces(vrf
->info
, vty
, uj
);
3699 DEFUN (show_ip_pim_interface_vrf_all
,
3700 show_ip_pim_interface_vrf_all_cmd
,
3701 "show ip pim vrf all interface [detail|WORD] [json]",
3706 "PIM interface information\n"
3712 u_char uj
= use_json(argc
, argv
);
3718 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3722 vty_out(vty
, " \"%s\": ", vrf
->name
);
3725 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3726 if (argv_find(argv
, argc
, "WORD", &idx
)
3727 || argv_find(argv
, argc
, "detail", &idx
))
3728 pim_show_interfaces_single(vrf
->info
, vty
,
3729 argv
[idx
]->arg
, uj
);
3731 pim_show_interfaces(vrf
->info
, vty
, uj
);
3734 vty_out(vty
, "}\n");
3739 DEFUN (show_ip_pim_join
,
3740 show_ip_pim_join_cmd
,
3741 "show ip pim [vrf NAME] join [json]",
3746 "PIM interface join information\n"
3750 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3751 u_char uj
= use_json(argc
, argv
);
3756 pim_show_join(vrf
->info
, vty
, uj
);
3761 DEFUN (show_ip_pim_join_vrf_all
,
3762 show_ip_pim_join_vrf_all_cmd
,
3763 "show ip pim vrf all join [json]",
3768 "PIM interface join information\n"
3771 u_char uj
= use_json(argc
, argv
);
3777 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3781 vty_out(vty
, " \"%s\": ", vrf
->name
);
3784 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3785 pim_show_join(vrf
->info
, vty
, uj
);
3788 vty_out(vty
, "}\n");
3793 DEFUN (show_ip_pim_local_membership
,
3794 show_ip_pim_local_membership_cmd
,
3795 "show ip pim [vrf NAME] local-membership [json]",
3800 "PIM interface local-membership\n"
3804 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3805 u_char uj
= use_json(argc
, argv
);
3810 pim_show_membership(vrf
->info
, vty
, uj
);
3815 DEFUN (show_ip_pim_neighbor
,
3816 show_ip_pim_neighbor_cmd
,
3817 "show ip pim [vrf NAME] neighbor [detail|WORD] [json]",
3822 "PIM neighbor information\n"
3824 "Name of interface or neighbor\n"
3828 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3829 u_char uj
= use_json(argc
, argv
);
3834 if (argv_find(argv
, argc
, "detail", &idx
)
3835 || argv_find(argv
, argc
, "WORD", &idx
))
3836 pim_show_neighbors_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
3838 pim_show_neighbors(vrf
->info
, vty
, uj
);
3843 DEFUN (show_ip_pim_neighbor_vrf_all
,
3844 show_ip_pim_neighbor_vrf_all_cmd
,
3845 "show ip pim vrf all neighbor [detail|WORD] [json]",
3850 "PIM neighbor information\n"
3852 "Name of interface or neighbor\n"
3856 u_char uj
= use_json(argc
, argv
);
3862 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3866 vty_out(vty
, " \"%s\": ", vrf
->name
);
3869 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3870 if (argv_find(argv
, argc
, "detail", &idx
)
3871 || argv_find(argv
, argc
, "WORD", &idx
))
3872 pim_show_neighbors_single(vrf
->info
, vty
,
3873 argv
[idx
]->arg
, uj
);
3875 pim_show_neighbors(vrf
->info
, vty
, uj
);
3878 vty_out(vty
, "}\n");
3883 DEFUN (show_ip_pim_secondary
,
3884 show_ip_pim_secondary_cmd
,
3885 "show ip pim [vrf NAME] secondary",
3890 "PIM neighbor addresses\n")
3893 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3898 pim_show_neighbors_secondary(vrf
->info
, vty
);
3903 DEFUN (show_ip_pim_state
,
3904 show_ip_pim_state_cmd
,
3905 "show ip pim [vrf NAME] state [A.B.C.D [A.B.C.D]] [json]",
3910 "PIM state information\n"
3911 "Unicast or Multicast address\n"
3912 "Multicast address\n"
3915 const char *src_or_group
= NULL
;
3916 const char *group
= NULL
;
3918 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3919 u_char uj
= use_json(argc
, argv
);
3927 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
3928 src_or_group
= argv
[idx
]->arg
;
3930 group
= argv
[idx
+ 1]->arg
;
3933 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
3938 DEFUN (show_ip_pim_state_vrf_all
,
3939 show_ip_pim_state_vrf_all_cmd
,
3940 "show ip pim vrf all state [A.B.C.D [A.B.C.D]] [json]",
3945 "PIM state information\n"
3946 "Unicast or Multicast address\n"
3947 "Multicast address\n"
3950 const char *src_or_group
= NULL
;
3951 const char *group
= NULL
;
3953 u_char uj
= use_json(argc
, argv
);
3962 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
3963 src_or_group
= argv
[idx
]->arg
;
3965 group
= argv
[idx
+ 1]->arg
;
3968 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3972 vty_out(vty
, " \"%s\": ", vrf
->name
);
3975 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3976 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
3979 vty_out(vty
, "}\n");
3984 DEFUN (show_ip_pim_upstream
,
3985 show_ip_pim_upstream_cmd
,
3986 "show ip pim [vrf NAME] upstream [json]",
3991 "PIM upstream information\n"
3995 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3996 u_char uj
= use_json(argc
, argv
);
4001 pim_show_upstream(vrf
->info
, vty
, uj
);
4006 DEFUN (show_ip_pim_upstream_vrf_all
,
4007 show_ip_pim_upstream_vrf_all_cmd
,
4008 "show ip pim vrf all upstream [json]",
4013 "PIM upstream information\n"
4016 u_char uj
= use_json(argc
, argv
);
4022 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4026 vty_out(vty
, " \"%s\": ", vrf
->name
);
4029 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4030 pim_show_upstream(vrf
->info
, vty
, uj
);
4036 DEFUN (show_ip_pim_upstream_join_desired
,
4037 show_ip_pim_upstream_join_desired_cmd
,
4038 "show ip pim [vrf NAME] upstream-join-desired [json]",
4043 "PIM upstream join-desired\n"
4047 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4048 u_char uj
= use_json(argc
, argv
);
4053 pim_show_join_desired(vrf
->info
, vty
, uj
);
4058 DEFUN (show_ip_pim_upstream_rpf
,
4059 show_ip_pim_upstream_rpf_cmd
,
4060 "show ip pim [vrf NAME] upstream-rpf [json]",
4065 "PIM upstream source rpf\n"
4069 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4070 u_char uj
= use_json(argc
, argv
);
4075 pim_show_upstream_rpf(vrf
->info
, vty
, uj
);
4080 DEFUN (show_ip_pim_rp
,
4082 "show ip pim [vrf NAME] rp-info [json]",
4087 "PIM RP information\n"
4091 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4092 u_char uj
= use_json(argc
, argv
);
4097 pim_rp_show_information(vrf
->info
, vty
, uj
);
4102 DEFUN (show_ip_pim_rp_vrf_all
,
4103 show_ip_pim_rp_vrf_all_cmd
,
4104 "show ip pim vrf all rp-info [json]",
4109 "PIM RP information\n"
4112 u_char uj
= use_json(argc
, argv
);
4118 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4122 vty_out(vty
, " \"%s\": ", vrf
->name
);
4125 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4126 pim_rp_show_information(vrf
->info
, vty
, uj
);
4129 vty_out(vty
, "}\n");
4134 DEFUN (show_ip_pim_rpf
,
4135 show_ip_pim_rpf_cmd
,
4136 "show ip pim [vrf NAME] rpf [json]",
4141 "PIM cached source rpf information\n"
4145 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4146 u_char uj
= use_json(argc
, argv
);
4151 pim_show_rpf(vrf
->info
, vty
, uj
);
4156 DEFUN (show_ip_pim_rpf_vrf_all
,
4157 show_ip_pim_rpf_vrf_all_cmd
,
4158 "show ip pim vrf all rpf [json]",
4163 "PIM cached source rpf information\n"
4166 u_char uj
= use_json(argc
, argv
);
4172 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4176 vty_out(vty
, " \"%s\": ", vrf
->name
);
4179 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4180 pim_show_rpf(vrf
->info
, vty
, uj
);
4183 vty_out(vty
, "}\n");
4188 DEFUN (show_ip_pim_nexthop
,
4189 show_ip_pim_nexthop_cmd
,
4190 "show ip pim [vrf NAME] nexthop",
4195 "PIM cached nexthop rpf information\n")
4198 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4203 pim_show_nexthop(vrf
->info
, vty
);
4208 DEFUN (show_ip_pim_nexthop_lookup
,
4209 show_ip_pim_nexthop_lookup_cmd
,
4210 "show ip pim [vrf NAME] nexthop-lookup A.B.C.D A.B.C.D",
4215 "PIM cached nexthop rpf lookup\n"
4216 "Source/RP address\n"
4217 "Multicast Group address\n")
4219 struct pim_nexthop_cache pnc
;
4220 struct prefix nht_p
;
4222 struct in_addr src_addr
, grp_addr
;
4223 struct in_addr vif_source
;
4224 const char *addr_str
, *addr_str1
;
4226 struct pim_nexthop nexthop
;
4227 char nexthop_addr_str
[PREFIX_STRLEN
];
4228 char grp_str
[PREFIX_STRLEN
];
4230 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4235 argv_find(argv
, argc
, "A.B.C.D", &idx
);
4236 addr_str
= argv
[idx
]->arg
;
4237 result
= inet_pton(AF_INET
, addr_str
, &src_addr
);
4239 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
4240 errno
, safe_strerror(errno
));
4244 if (pim_is_group_224_4(src_addr
)) {
4246 "Invalid argument. Expected Valid Source Address.\n");
4250 addr_str1
= argv
[idx
+ 1]->arg
;
4251 result
= inet_pton(AF_INET
, addr_str1
, &grp_addr
);
4253 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
4254 errno
, safe_strerror(errno
));
4258 if (!pim_is_group_224_4(grp_addr
)) {
4260 "Invalid argument. Expected Valid Multicast Group Address.\n");
4264 if (!pim_rp_set_upstream_addr(vrf
->info
, &vif_source
, src_addr
,
4268 memset(&pnc
, 0, sizeof(struct pim_nexthop_cache
));
4269 nht_p
.family
= AF_INET
;
4270 nht_p
.prefixlen
= IPV4_MAX_BITLEN
;
4271 nht_p
.u
.prefix4
= vif_source
;
4272 grp
.family
= AF_INET
;
4273 grp
.prefixlen
= IPV4_MAX_BITLEN
;
4274 grp
.u
.prefix4
= grp_addr
;
4275 memset(&nexthop
, 0, sizeof(nexthop
));
4277 if (pim_find_or_track_nexthop(vrf
->info
, &nht_p
, NULL
, NULL
, &pnc
))
4278 pim_ecmp_nexthop_search(vrf
->info
, &pnc
, &nexthop
, &nht_p
, &grp
,
4281 pim_ecmp_nexthop_lookup(vrf
->info
, &nexthop
, vif_source
, &nht_p
,
4284 pim_addr_dump("<grp?>", &grp
, grp_str
, sizeof(grp_str
));
4285 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
4286 nexthop_addr_str
, sizeof(nexthop_addr_str
));
4287 vty_out(vty
, "Group %s --- Nexthop %s Interface %s \n", grp_str
,
4288 nexthop_addr_str
, nexthop
.interface
->name
);
4293 DEFUN (show_ip_pim_interface_traffic
,
4294 show_ip_pim_interface_traffic_cmd
,
4295 "show ip pim [vrf NAME] interface traffic [WORD] [json]",
4300 "PIM interface information\n"
4301 "Protocol Packet counters\n"
4306 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4307 u_char uj
= use_json(argc
, argv
);
4312 if (argv_find(argv
, argc
, "WORD", &idx
))
4313 pim_show_interface_traffic_single(vrf
->info
, vty
,
4314 argv
[idx
]->arg
, uj
);
4316 pim_show_interface_traffic(vrf
->info
, vty
, uj
);
4321 static void show_multicast_interfaces(struct pim_instance
*pim
, struct vty
*vty
)
4323 struct listnode
*node
;
4324 struct interface
*ifp
;
4329 "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut\n");
4331 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim
->vrf_id
), node
, ifp
)) {
4332 struct pim_interface
*pim_ifp
;
4333 struct in_addr ifaddr
;
4334 struct sioc_vif_req vreq
;
4336 pim_ifp
= ifp
->info
;
4341 memset(&vreq
, 0, sizeof(vreq
));
4342 vreq
.vifi
= pim_ifp
->mroute_vif_index
;
4344 if (ioctl(pim
->mroute_socket
, SIOCGETVIFCNT
, &vreq
)) {
4346 "ioctl(SIOCGETVIFCNT=%lu) failure for interface %s vif_index=%d: errno=%d: %s",
4347 (unsigned long)SIOCGETVIFCNT
, ifp
->name
,
4348 pim_ifp
->mroute_vif_index
, errno
,
4349 safe_strerror(errno
));
4352 ifaddr
= pim_ifp
->primary_address
;
4354 vty_out(vty
, "%-12s %-15s %3d %3d %7lu %7lu %10lu %10lu\n",
4355 ifp
->name
, inet_ntoa(ifaddr
), ifp
->ifindex
,
4356 pim_ifp
->mroute_vif_index
, (unsigned long)vreq
.icount
,
4357 (unsigned long)vreq
.ocount
, (unsigned long)vreq
.ibytes
,
4358 (unsigned long)vreq
.obytes
);
4362 static void pim_cmd_show_ip_multicast_helper(struct pim_instance
*pim
,
4365 struct vrf
*vrf
= pim
->vrf
;
4366 time_t now
= pim_time_monotonic_sec();
4371 vty_out(vty
, "Mroute socket descriptor:");
4373 vty_out(vty
, " %d(%s)\n", pim
->mroute_socket
, vrf
->name
);
4375 pim_time_uptime(uptime
, sizeof(uptime
),
4376 now
- pim
->mroute_socket_creation
);
4377 vty_out(vty
, "Mroute socket uptime: %s\n", uptime
);
4381 pim_zebra_zclient_update(vty
);
4382 pim_zlookup_show_ip_multicast(vty
);
4385 vty_out(vty
, "Maximum highest VifIndex: %d\n", PIM_MAX_USABLE_VIFS
);
4388 vty_out(vty
, "Upstream Join Timer: %d secs\n", qpim_t_periodic
);
4389 vty_out(vty
, "Join/Prune Holdtime: %d secs\n", PIM_JP_HOLDTIME
);
4390 vty_out(vty
, "PIM ECMP: %s\n", qpim_ecmp_enable
? "Enable" : "Disable");
4391 vty_out(vty
, "PIM ECMP Rebalance: %s\n",
4392 qpim_ecmp_rebalance_enable
? "Enable" : "Disable");
4396 show_rpf_refresh_stats(vty
, now
, NULL
);
4400 show_scan_oil_stats(pim
, vty
, now
);
4402 show_multicast_interfaces(pim
, vty
);
4405 DEFUN (show_ip_multicast
,
4406 show_ip_multicast_cmd
,
4407 "show ip multicast [vrf NAME]",
4411 "Multicast global information\n")
4414 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4419 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
4424 DEFUN (show_ip_multicast_vrf_all
,
4425 show_ip_multicast_vrf_all_cmd
,
4426 "show ip multicast vrf all",
4430 "Multicast global information\n")
4432 u_char uj
= use_json(argc
, argv
);
4438 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4442 vty_out(vty
, " \"%s\": ", vrf
->name
);
4445 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4446 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
4449 vty_out(vty
, "}\n");
4454 static void show_mroute(struct pim_instance
*pim
, struct vty
*vty
,
4455 bool fill
, u_char uj
)
4457 struct listnode
*node
;
4458 struct channel_oil
*c_oil
;
4459 struct static_route
*s_route
;
4461 json_object
*json
= NULL
;
4462 json_object
*json_group
= NULL
;
4463 json_object
*json_source
= NULL
;
4464 json_object
*json_oil
= NULL
;
4465 json_object
*json_ifp_out
= NULL
;
4468 char grp_str
[INET_ADDRSTRLEN
];
4469 char src_str
[INET_ADDRSTRLEN
];
4470 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
4471 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
4473 struct interface
*ifp_in
;
4477 json
= json_object_new_object();
4480 "Source Group Proto Input Output TTL Uptime\n");
4483 now
= pim_time_monotonic_sec();
4485 /* print list of PIM and IGMP routes */
4486 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
4489 if (!c_oil
->installed
&& !uj
)
4492 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
4494 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
4496 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
4499 strcpy(in_ifname
, ifp_in
->name
);
4501 strcpy(in_ifname
, "<iif?>");
4505 /* Find the group, create it if it doesn't exist */
4506 json_object_object_get_ex(json
, grp_str
, &json_group
);
4509 json_group
= json_object_new_object();
4510 json_object_object_add(json
, grp_str
,
4514 /* Find the source nested under the group, create it if
4515 * it doesn't exist */
4516 json_object_object_get_ex(json_group
, src_str
,
4520 json_source
= json_object_new_object();
4521 json_object_object_add(json_group
, src_str
,
4525 /* Find the inbound interface nested under the source,
4526 * create it if it doesn't exist */
4527 json_object_int_add(json_source
, "installed",
4529 json_object_int_add(json_source
, "refCount",
4530 c_oil
->oil_ref_count
);
4531 json_object_int_add(json_source
, "oilSize",
4533 json_object_int_add(json_source
, "OilInheritedRescan",
4534 c_oil
->oil_inherited_rescan
);
4535 json_object_string_add(json_source
, "iif", in_ifname
);
4539 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
4541 struct interface
*ifp_out
;
4542 char oif_uptime
[10];
4545 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
4549 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
4551 oif_uptime
, sizeof(oif_uptime
),
4552 now
- c_oil
->oif_creation
[oif_vif_index
]);
4556 strcpy(out_ifname
, ifp_out
->name
);
4558 strcpy(out_ifname
, "<oif?>");
4561 json_ifp_out
= json_object_new_object();
4562 json_object_string_add(json_ifp_out
, "source",
4564 json_object_string_add(json_ifp_out
, "group",
4567 if (c_oil
->oif_flags
[oif_vif_index
]
4568 & PIM_OIF_FLAG_PROTO_PIM
)
4569 json_object_boolean_true_add(
4570 json_ifp_out
, "protocolPim");
4572 if (c_oil
->oif_flags
[oif_vif_index
]
4573 & PIM_OIF_FLAG_PROTO_IGMP
)
4574 json_object_boolean_true_add(
4575 json_ifp_out
, "protocolIgmp");
4577 if (c_oil
->oif_flags
[oif_vif_index
]
4578 & PIM_OIF_FLAG_PROTO_SOURCE
)
4579 json_object_boolean_true_add(
4580 json_ifp_out
, "protocolSource");
4582 if (c_oil
->oif_flags
[oif_vif_index
]
4583 & PIM_OIF_FLAG_PROTO_STAR
)
4584 json_object_boolean_true_add(
4586 "protocolInherited");
4588 json_object_string_add(json_ifp_out
,
4591 json_object_int_add(json_ifp_out
, "iVifI",
4592 c_oil
->oil
.mfcc_parent
);
4593 json_object_string_add(json_ifp_out
,
4594 "outboundInterface",
4596 json_object_int_add(json_ifp_out
, "oVifI",
4598 json_object_int_add(json_ifp_out
, "ttl", ttl
);
4599 json_object_string_add(json_ifp_out
, "upTime",
4602 json_oil
= json_object_new_object();
4603 json_object_object_add(json_source
,
4606 json_object_object_add(json_oil
, out_ifname
,
4609 if (c_oil
->oif_flags
[oif_vif_index
]
4610 & PIM_OIF_FLAG_PROTO_PIM
) {
4611 strcpy(proto
, "PIM");
4614 if (c_oil
->oif_flags
[oif_vif_index
]
4615 & PIM_OIF_FLAG_PROTO_IGMP
) {
4616 strcpy(proto
, "IGMP");
4619 if (c_oil
->oif_flags
[oif_vif_index
]
4620 & PIM_OIF_FLAG_PROTO_SOURCE
) {
4621 strcpy(proto
, "SRC");
4624 if (c_oil
->oif_flags
[oif_vif_index
]
4625 & PIM_OIF_FLAG_PROTO_STAR
) {
4626 strcpy(proto
, "STAR");
4630 "%-15s %-15s %-6s %-10s %-10s %-3d %8s\n",
4631 src_str
, grp_str
, proto
, in_ifname
,
4632 out_ifname
, ttl
, oif_uptime
);
4637 in_ifname
[0] = '\0';
4643 if (!uj
&& !found_oif
) {
4644 vty_out(vty
, "%-15s %-15s %-6s %-10s %-10s %-3d %8s\n",
4645 src_str
, grp_str
, "none", in_ifname
, "none", 0,
4650 /* Print list of static routes */
4651 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
4654 if (!s_route
->c_oil
.installed
)
4657 pim_inet4_dump("<group?>", s_route
->group
, grp_str
,
4659 pim_inet4_dump("<source?>", s_route
->source
, src_str
,
4661 ifp_in
= pim_if_find_by_vif_index(pim
, s_route
->iif
);
4665 strcpy(in_ifname
, ifp_in
->name
);
4667 strcpy(in_ifname
, "<iif?>");
4671 /* Find the group, create it if it doesn't exist */
4672 json_object_object_get_ex(json
, grp_str
, &json_group
);
4675 json_group
= json_object_new_object();
4676 json_object_object_add(json
, grp_str
,
4680 /* Find the source nested under the group, create it if
4681 * it doesn't exist */
4682 json_object_object_get_ex(json_group
, src_str
,
4686 json_source
= json_object_new_object();
4687 json_object_object_add(json_group
, src_str
,
4691 json_object_string_add(json_source
, "iif", in_ifname
);
4694 strcpy(proto
, "STATIC");
4697 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
4699 struct interface
*ifp_out
;
4700 char oif_uptime
[10];
4703 ttl
= s_route
->oif_ttls
[oif_vif_index
];
4707 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
4708 pim_time_uptime(oif_uptime
, sizeof(oif_uptime
),
4710 s_route
->c_oil
.oif_creation
[oif_vif_index
]);
4714 strcpy(out_ifname
, ifp_out
->name
);
4716 strcpy(out_ifname
, "<oif?>");
4719 json_ifp_out
= json_object_new_object();
4720 json_object_string_add(json_ifp_out
, "source",
4722 json_object_string_add(json_ifp_out
, "group",
4724 json_object_boolean_true_add(json_ifp_out
,
4726 json_object_string_add(json_ifp_out
,
4729 json_object_int_add(
4730 json_ifp_out
, "iVifI",
4731 s_route
->c_oil
.oil
.mfcc_parent
);
4732 json_object_string_add(json_ifp_out
,
4733 "outboundInterface",
4735 json_object_int_add(json_ifp_out
, "oVifI",
4737 json_object_int_add(json_ifp_out
, "ttl", ttl
);
4738 json_object_string_add(json_ifp_out
, "upTime",
4741 json_oil
= json_object_new_object();
4742 json_object_object_add(json_source
,
4745 json_object_object_add(json_oil
, out_ifname
,
4749 "%-15s %-15s %-6s %-10s %-10s %-3d %8s %s\n",
4750 src_str
, grp_str
, proto
, in_ifname
,
4751 out_ifname
, ttl
, oif_uptime
,
4753 if (first
&& !fill
) {
4756 in_ifname
[0] = '\0';
4762 if (!uj
&& !found_oif
) {
4764 "%-15s %-15s %-6s %-10s %-10s %-3d %8s %s\n",
4765 src_str
, grp_str
, proto
, in_ifname
, "none", 0,
4766 "--:--:--", pim
->vrf
->name
);
4771 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4772 json
, JSON_C_TO_STRING_PRETTY
));
4773 json_object_free(json
);
4777 DEFUN (show_ip_mroute
,
4779 "show ip mroute [vrf NAME] [fill] [json]",
4784 "Fill in Assumed data\n"
4787 u_char uj
= use_json(argc
, argv
);
4790 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4795 if (argv_find(argv
, argc
, "fill", &idx
))
4798 show_mroute(vrf
->info
, vty
, fill
, uj
);
4802 DEFUN (show_ip_mroute_vrf_all
,
4803 show_ip_mroute_vrf_all_cmd
,
4804 "show ip mroute vrf all [fill] [json]",
4809 "Fill in Assumed data\n"
4812 u_char uj
= use_json(argc
, argv
);
4818 if (argv_find(argv
, argc
, "fill", &idx
))
4823 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4827 vty_out(vty
, " \"%s\": ", vrf
->name
);
4830 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4831 show_mroute(vrf
->info
, vty
, fill
, uj
);
4834 vty_out(vty
, "}\n");
4839 static void show_mroute_count(struct pim_instance
*pim
, struct vty
*vty
)
4841 struct listnode
*node
;
4842 struct channel_oil
*c_oil
;
4843 struct static_route
*s_route
;
4848 "Source Group LastUsed Packets Bytes WrongIf \n");
4850 /* Print PIM and IGMP route counts */
4851 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
4852 char group_str
[INET_ADDRSTRLEN
];
4853 char source_str
[INET_ADDRSTRLEN
];
4855 if (!c_oil
->installed
)
4858 pim_mroute_update_counters(c_oil
);
4860 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, group_str
,
4862 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, source_str
,
4863 sizeof(source_str
));
4865 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
4866 source_str
, group_str
, c_oil
->cc
.lastused
/ 100,
4867 c_oil
->cc
.pktcnt
, c_oil
->cc
.bytecnt
,
4868 c_oil
->cc
.wrong_if
);
4871 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
4872 char group_str
[INET_ADDRSTRLEN
];
4873 char source_str
[INET_ADDRSTRLEN
];
4875 if (!s_route
->c_oil
.installed
)
4878 pim_mroute_update_counters(&s_route
->c_oil
);
4880 pim_inet4_dump("<group?>", s_route
->c_oil
.oil
.mfcc_mcastgrp
,
4881 group_str
, sizeof(group_str
));
4882 pim_inet4_dump("<source?>", s_route
->c_oil
.oil
.mfcc_origin
,
4883 source_str
, sizeof(source_str
));
4885 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
4886 source_str
, group_str
, s_route
->c_oil
.cc
.lastused
,
4887 s_route
->c_oil
.cc
.pktcnt
, s_route
->c_oil
.cc
.bytecnt
,
4888 s_route
->c_oil
.cc
.wrong_if
);
4892 DEFUN (show_ip_mroute_count
,
4893 show_ip_mroute_count_cmd
,
4894 "show ip mroute [vrf NAME] count",
4899 "Route and packet count data\n")
4902 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4907 show_mroute_count(vrf
->info
, vty
);
4911 DEFUN (show_ip_mroute_count_vrf_all
,
4912 show_ip_mroute_count_vrf_all_cmd
,
4913 "show ip mroute vrf all count",
4918 "Route and packet count data\n")
4920 u_char uj
= use_json(argc
, argv
);
4926 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4930 vty_out(vty
, " \"%s\": ", vrf
->name
);
4933 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4934 show_mroute_count(vrf
->info
, vty
);
4937 vty_out(vty
, "}\n");
4944 "show ip rib [vrf NAME] A.B.C.D",
4949 "Unicast address\n")
4952 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4953 struct in_addr addr
;
4954 const char *addr_str
;
4955 struct pim_nexthop nexthop
;
4956 char nexthop_addr_str
[PREFIX_STRLEN
];
4962 memset(&nexthop
, 0, sizeof(nexthop
));
4963 argv_find(argv
, argc
, "A.B.C.D", &idx
);
4964 addr_str
= argv
[idx
]->arg
;
4965 result
= inet_pton(AF_INET
, addr_str
, &addr
);
4967 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
4968 errno
, safe_strerror(errno
));
4972 if (pim_nexthop_lookup(vrf
->info
, &nexthop
, addr
, 0)) {
4974 "Failure querying RIB nexthop for unicast address %s\n",
4980 "Address NextHop Interface Metric Preference\n");
4982 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
4983 nexthop_addr_str
, sizeof(nexthop_addr_str
));
4985 vty_out(vty
, "%-15s %-15s %-9s %6d %10d\n", addr_str
, nexthop_addr_str
,
4986 nexthop
.interface
? nexthop
.interface
->name
: "<ifname?>",
4987 nexthop
.mrib_route_metric
, nexthop
.mrib_metric_preference
);
4992 static void show_ssmpingd(struct pim_instance
*pim
, struct vty
*vty
)
4994 struct listnode
*node
;
4995 struct ssmpingd_sock
*ss
;
4999 "Source Socket Address Port Uptime Requests\n");
5001 if (!pim
->ssmpingd_list
)
5004 now
= pim_time_monotonic_sec();
5006 for (ALL_LIST_ELEMENTS_RO(pim
->ssmpingd_list
, node
, ss
)) {
5007 char source_str
[INET_ADDRSTRLEN
];
5009 struct sockaddr_in bind_addr
;
5010 socklen_t len
= sizeof(bind_addr
);
5011 char bind_addr_str
[INET_ADDRSTRLEN
];
5013 pim_inet4_dump("<src?>", ss
->source_addr
, source_str
,
5014 sizeof(source_str
));
5016 if (pim_socket_getsockname(
5017 ss
->sock_fd
, (struct sockaddr
*)&bind_addr
, &len
)) {
5019 "%% Failure reading socket name for ssmpingd source %s on fd=%d\n",
5020 source_str
, ss
->sock_fd
);
5023 pim_inet4_dump("<addr?>", bind_addr
.sin_addr
, bind_addr_str
,
5024 sizeof(bind_addr_str
));
5025 pim_time_uptime(ss_uptime
, sizeof(ss_uptime
),
5026 now
- ss
->creation
);
5028 vty_out(vty
, "%-15s %6d %-15s %5d %8s %8lld\n", source_str
,
5029 ss
->sock_fd
, bind_addr_str
, ntohs(bind_addr
.sin_port
),
5030 ss_uptime
, (long long)ss
->requests
);
5034 DEFUN (show_ip_ssmpingd
,
5035 show_ip_ssmpingd_cmd
,
5036 "show ip ssmpingd [vrf NAME]",
5043 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5048 show_ssmpingd(vrf
->info
, vty
);
5052 static int pim_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
5053 const char *rp
, const char *group
,
5058 result
= pim_rp_new(pim
, rp
, group
, plist
);
5060 if (result
== PIM_MALLOC_FAIL
) {
5061 vty_out(vty
, "%% Out of memory\n");
5062 return CMD_WARNING_CONFIG_FAILED
;
5065 if (result
== PIM_GROUP_BAD_ADDRESS
) {
5066 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
5067 return CMD_WARNING_CONFIG_FAILED
;
5070 if (result
== PIM_RP_BAD_ADDRESS
) {
5071 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
5072 return CMD_WARNING_CONFIG_FAILED
;
5075 if (result
== PIM_RP_NO_PATH
) {
5076 vty_out(vty
, "%% No Path to RP address specified: %s\n", rp
);
5080 if (result
== PIM_GROUP_OVERLAP
) {
5081 vty_out(vty
, "%% Group range specified cannot exact match another\n");
5082 return CMD_WARNING_CONFIG_FAILED
;
5085 if (result
== PIM_GROUP_PFXLIST_OVERLAP
) {
5087 "%% This group is already covered by a RP prefix-list\n");
5088 return CMD_WARNING_CONFIG_FAILED
;
5091 if (result
== PIM_RP_PFXLIST_IN_USE
) {
5093 "%% The same prefix-list cannot be applied to multiple RPs\n");
5094 return CMD_WARNING_CONFIG_FAILED
;
5100 static int pim_cmd_spt_switchover(struct pim_instance
*pim
,
5101 enum pim_spt_switchover spt
,
5104 pim
->spt
.switchover
= spt
;
5106 switch (pim
->spt
.switchover
) {
5107 case PIM_SPT_IMMEDIATE
:
5109 XFREE(MTYPE_PIM_SPT_PLIST_NAME
, pim
->spt
.plist
);
5111 pim_upstream_add_lhr_star_pimreg(pim
);
5113 case PIM_SPT_INFINITY
:
5114 pim_upstream_remove_lhr_star_pimreg(pim
, plist
);
5117 XFREE(MTYPE_PIM_SPT_PLIST_NAME
, pim
->spt
.plist
);
5121 XSTRDUP(MTYPE_PIM_SPT_PLIST_NAME
, plist
);
5128 DEFUN (ip_pim_spt_switchover_infinity
,
5129 ip_pim_spt_switchover_infinity_cmd
,
5130 "ip pim spt-switchover infinity-and-beyond",
5134 "Never switch to SPT Tree\n")
5136 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5137 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, NULL
);
5140 DEFUN (ip_pim_spt_switchover_infinity_plist
,
5141 ip_pim_spt_switchover_infinity_plist_cmd
,
5142 "ip pim spt-switchover infinity-and-beyond prefix-list WORD",
5146 "Never switch to SPT Tree\n"
5147 "Prefix-List to control which groups to switch\n"
5148 "Prefix-List name\n")
5150 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5151 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, argv
[5]->arg
);
5154 DEFUN (no_ip_pim_spt_switchover_infinity
,
5155 no_ip_pim_spt_switchover_infinity_cmd
,
5156 "no ip pim spt-switchover infinity-and-beyond",
5161 "Never switch to SPT Tree\n")
5163 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5164 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
5167 DEFUN (no_ip_pim_spt_switchover_infinity_plist
,
5168 no_ip_pim_spt_switchover_infinity_plist_cmd
,
5169 "no ip pim spt-switchover infinity-and-beyond prefix-list WORD",
5174 "Never switch to SPT Tree\n"
5175 "Prefix-List to control which groups to switch\n"
5176 "Prefix-List name\n")
5178 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5179 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
5182 DEFUN (ip_pim_joinprune_time
,
5183 ip_pim_joinprune_time_cmd
,
5184 "ip pim join-prune-interval (60-600)",
5186 "pim multicast routing\n"
5187 "Join Prune Send Interval\n"
5190 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5191 qpim_t_periodic
= atoi(argv
[3]->arg
);
5195 DEFUN (no_ip_pim_joinprune_time
,
5196 no_ip_pim_joinprune_time_cmd
,
5197 "no ip pim join-prune-interval (60-600)",
5200 "pim multicast routing\n"
5201 "Join Prune Send Interval\n"
5204 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5205 qpim_t_periodic
= PIM_DEFAULT_T_PERIODIC
;
5209 DEFUN (ip_pim_register_suppress
,
5210 ip_pim_register_suppress_cmd
,
5211 "ip pim register-suppress-time (5-60000)",
5213 "pim multicast routing\n"
5214 "Register Suppress Timer\n"
5217 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5218 qpim_register_suppress_time
= atoi(argv
[3]->arg
);
5222 DEFUN (no_ip_pim_register_suppress
,
5223 no_ip_pim_register_suppress_cmd
,
5224 "no ip pim register-suppress-time (5-60000)",
5227 "pim multicast routing\n"
5228 "Register Suppress Timer\n"
5231 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5232 qpim_register_suppress_time
= PIM_REGISTER_SUPPRESSION_TIME_DEFAULT
;
5236 DEFUN (ip_pim_rp_keep_alive
,
5237 ip_pim_rp_keep_alive_cmd
,
5238 "ip pim rp keep-alive-timer (31-60000)",
5240 "pim multicast routing\n"
5242 "Keep alive Timer\n"
5245 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5246 pim
->rp_keep_alive_time
= atoi(argv
[4]->arg
);
5250 DEFUN (no_ip_pim_rp_keep_alive
,
5251 no_ip_pim_rp_keep_alive_cmd
,
5252 "no ip pim rp keep-alive-timer (31-60000)",
5255 "pim multicast routing\n"
5257 "Keep alive Timer\n"
5260 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5261 pim
->rp_keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
5265 DEFUN (ip_pim_keep_alive
,
5266 ip_pim_keep_alive_cmd
,
5267 "ip pim keep-alive-timer (31-60000)",
5269 "pim multicast routing\n"
5270 "Keep alive Timer\n"
5273 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5274 pim
->keep_alive_time
= atoi(argv
[3]->arg
);
5278 DEFUN (no_ip_pim_keep_alive
,
5279 no_ip_pim_keep_alive_cmd
,
5280 "no ip pim keep-alive-timer (31-60000)",
5283 "pim multicast routing\n"
5284 "Keep alive Timer\n"
5287 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5288 pim
->keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
5292 DEFUN (ip_pim_packets
,
5294 "ip pim packets (1-100)",
5296 "pim multicast routing\n"
5297 "packets to process at one time per fd\n"
5298 "Number of packets\n")
5300 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5301 qpim_packet_process
= atoi(argv
[3]->arg
);
5305 DEFUN (no_ip_pim_packets
,
5306 no_ip_pim_packets_cmd
,
5307 "no ip pim packets (1-100)",
5310 "pim multicast routing\n"
5311 "packets to process at one time per fd\n"
5312 "Number of packets\n")
5314 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5315 qpim_packet_process
= PIM_DEFAULT_PACKET_PROCESS
;
5319 DEFUN (ip_pim_v6_secondary
,
5320 ip_pim_v6_secondary_cmd
,
5321 "ip pim send-v6-secondary",
5323 "pim multicast routing\n"
5324 "Send v6 secondary addresses\n")
5326 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5327 pim
->send_v6_secondary
= 1;
5332 DEFUN (no_ip_pim_v6_secondary
,
5333 no_ip_pim_v6_secondary_cmd
,
5334 "no ip pim send-v6-secondary",
5337 "pim multicast routing\n"
5338 "Send v6 secondary addresses\n")
5340 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5341 pim
->send_v6_secondary
= 0;
5348 "ip pim rp A.B.C.D [A.B.C.D/M]",
5350 "pim multicast routing\n"
5352 "ip address of RP\n"
5353 "Group Address range to cover\n")
5355 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5358 if (argc
== (idx_ipv4
+ 1))
5359 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
5362 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
5363 argv
[idx_ipv4
+ 1]->arg
, NULL
);
5366 DEFUN (ip_pim_rp_prefix_list
,
5367 ip_pim_rp_prefix_list_cmd
,
5368 "ip pim rp A.B.C.D prefix-list WORD",
5370 "pim multicast routing\n"
5372 "ip address of RP\n"
5373 "group prefix-list filter\n"
5374 "Name of a prefix-list\n")
5376 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5377 return pim_rp_cmd_worker(pim
, vty
, argv
[3]->arg
, NULL
, argv
[5]->arg
);
5380 static int pim_no_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
5381 const char *rp
, const char *group
,
5384 int result
= pim_rp_del(pim
, rp
, group
, plist
);
5386 if (result
== PIM_GROUP_BAD_ADDRESS
) {
5387 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
5388 return CMD_WARNING_CONFIG_FAILED
;
5391 if (result
== PIM_RP_BAD_ADDRESS
) {
5392 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
5393 return CMD_WARNING_CONFIG_FAILED
;
5396 if (result
== PIM_RP_NOT_FOUND
) {
5397 vty_out(vty
, "%% Unable to find specified RP\n");
5398 return CMD_WARNING_CONFIG_FAILED
;
5404 DEFUN (no_ip_pim_rp
,
5406 "no ip pim rp A.B.C.D [A.B.C.D/M]",
5409 "pim multicast routing\n"
5411 "ip address of RP\n"
5412 "Group Address range to cover\n")
5414 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5415 int idx_ipv4
= 4, idx_group
= 0;
5417 if (argv_find(argv
, argc
, "A.B.C.D/M", &idx_group
))
5418 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
5419 argv
[idx_group
]->arg
, NULL
);
5421 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
5425 DEFUN (no_ip_pim_rp_prefix_list
,
5426 no_ip_pim_rp_prefix_list_cmd
,
5427 "no ip pim rp A.B.C.D prefix-list WORD",
5430 "pim multicast routing\n"
5432 "ip address of RP\n"
5433 "group prefix-list filter\n"
5434 "Name of a prefix-list\n")
5436 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5437 return pim_no_rp_cmd_worker(pim
, vty
, argv
[4]->arg
, NULL
, argv
[6]->arg
);
5440 static int pim_ssm_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
5443 int result
= pim_ssm_range_set(pim
, pim
->vrf_id
, plist
);
5445 if (result
== PIM_SSM_ERR_NONE
)
5449 case PIM_SSM_ERR_NO_VRF
:
5450 vty_out(vty
, "%% VRF doesn't exist\n");
5452 case PIM_SSM_ERR_DUP
:
5453 vty_out(vty
, "%% duplicate config\n");
5456 vty_out(vty
, "%% ssm range config failed\n");
5459 return CMD_WARNING_CONFIG_FAILED
;
5462 DEFUN (ip_pim_ssm_prefix_list
,
5463 ip_pim_ssm_prefix_list_cmd
,
5464 "ip pim ssm prefix-list WORD",
5466 "pim multicast routing\n"
5467 "Source Specific Multicast\n"
5468 "group range prefix-list filter\n"
5469 "Name of a prefix-list\n")
5471 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5472 return pim_ssm_cmd_worker(pim
, vty
, argv
[4]->arg
);
5475 DEFUN (no_ip_pim_ssm_prefix_list
,
5476 no_ip_pim_ssm_prefix_list_cmd
,
5477 "no ip pim ssm prefix-list",
5480 "pim multicast routing\n"
5481 "Source Specific Multicast\n"
5482 "group range prefix-list filter\n")
5484 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5485 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
5488 DEFUN (no_ip_pim_ssm_prefix_list_name
,
5489 no_ip_pim_ssm_prefix_list_name_cmd
,
5490 "no ip pim ssm prefix-list WORD",
5493 "pim multicast routing\n"
5494 "Source Specific Multicast\n"
5495 "group range prefix-list filter\n"
5496 "Name of a prefix-list\n")
5498 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5499 struct pim_ssm
*ssm
= pim
->ssm_info
;
5501 if (ssm
->plist_name
&& !strcmp(ssm
->plist_name
, argv
[5]->arg
))
5502 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
5504 vty_out(vty
, "%% pim ssm prefix-list %s doesn't exist\n", argv
[5]->arg
);
5506 return CMD_WARNING_CONFIG_FAILED
;
5509 static void ip_pim_ssm_show_group_range(struct pim_instance
*pim
,
5510 struct vty
*vty
, u_char uj
)
5512 struct pim_ssm
*ssm
= pim
->ssm_info
;
5513 const char *range_str
=
5514 ssm
->plist_name
? ssm
->plist_name
: PIM_SSM_STANDARD_RANGE
;
5518 json
= json_object_new_object();
5519 json_object_string_add(json
, "ssmGroups", range_str
);
5520 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5521 json
, JSON_C_TO_STRING_PRETTY
));
5522 json_object_free(json
);
5524 vty_out(vty
, "SSM group range : %s\n", range_str
);
5527 DEFUN (show_ip_pim_ssm_range
,
5528 show_ip_pim_ssm_range_cmd
,
5529 "show ip pim [vrf NAME] group-type [json]",
5538 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5539 u_char uj
= use_json(argc
, argv
);
5544 ip_pim_ssm_show_group_range(vrf
->info
, vty
, uj
);
5549 static void ip_pim_ssm_show_group_type(struct pim_instance
*pim
,
5550 struct vty
*vty
, u_char uj
,
5553 struct in_addr group_addr
;
5554 const char *type_str
;
5557 result
= inet_pton(AF_INET
, group
, &group_addr
);
5559 type_str
= "invalid";
5561 if (pim_is_group_224_4(group_addr
))
5563 pim_is_grp_ssm(pim
, group_addr
) ? "SSM" : "ASM";
5565 type_str
= "not-multicast";
5570 json
= json_object_new_object();
5571 json_object_string_add(json
, "groupType", type_str
);
5572 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5573 json
, JSON_C_TO_STRING_PRETTY
));
5574 json_object_free(json
);
5576 vty_out(vty
, "Group type : %s\n", type_str
);
5579 DEFUN (show_ip_pim_group_type
,
5580 show_ip_pim_group_type_cmd
,
5581 "show ip pim [vrf NAME] group-type A.B.C.D [json]",
5586 "multicast group type\n"
5591 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5592 u_char uj
= use_json(argc
, argv
);
5597 argv_find(argv
, argc
, "A.B.C.D", &idx
);
5598 ip_pim_ssm_show_group_type(vrf
->info
, vty
, uj
, argv
[idx
]->arg
);
5603 DEFUN_HIDDEN (ip_multicast_routing
,
5604 ip_multicast_routing_cmd
,
5605 "ip multicast-routing",
5607 "Enable IP multicast forwarding\n")
5612 DEFUN_HIDDEN (no_ip_multicast_routing
,
5613 no_ip_multicast_routing_cmd
,
5614 "no ip multicast-routing",
5617 "Enable IP multicast forwarding\n")
5620 "Command is Disabled and will be removed in a future version\n");
5626 "ip ssmpingd [A.B.C.D]",
5631 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5634 struct in_addr source_addr
;
5635 const char *source_str
= (argc
== 3) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
5637 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
5639 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
5640 source_str
, errno
, safe_strerror(errno
));
5641 return CMD_WARNING_CONFIG_FAILED
;
5644 result
= pim_ssmpingd_start(pim
, source_addr
);
5646 vty_out(vty
, "%% Failure starting ssmpingd for source %s: %d\n",
5647 source_str
, result
);
5648 return CMD_WARNING_CONFIG_FAILED
;
5654 DEFUN (no_ip_ssmpingd
,
5656 "no ip ssmpingd [A.B.C.D]",
5662 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5665 struct in_addr source_addr
;
5666 const char *source_str
= (argc
== 4) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
5668 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
5670 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
5671 source_str
, errno
, safe_strerror(errno
));
5672 return CMD_WARNING_CONFIG_FAILED
;
5675 result
= pim_ssmpingd_stop(pim
, source_addr
);
5677 vty_out(vty
, "%% Failure stopping ssmpingd for source %s: %d\n",
5678 source_str
, result
);
5679 return CMD_WARNING_CONFIG_FAILED
;
5689 "pim multicast routing\n"
5690 "Enable PIM ECMP \n")
5692 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5693 qpim_ecmp_enable
= 1;
5698 DEFUN (no_ip_pim_ecmp
,
5703 "pim multicast routing\n"
5704 "Disable PIM ECMP \n")
5706 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5707 qpim_ecmp_enable
= 0;
5712 DEFUN (ip_pim_ecmp_rebalance
,
5713 ip_pim_ecmp_rebalance_cmd
,
5714 "ip pim ecmp rebalance",
5716 "pim multicast routing\n"
5717 "Enable PIM ECMP \n"
5718 "Enable PIM ECMP Rebalance\n")
5720 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5721 qpim_ecmp_enable
= 1;
5722 qpim_ecmp_rebalance_enable
= 1;
5727 DEFUN (no_ip_pim_ecmp_rebalance
,
5728 no_ip_pim_ecmp_rebalance_cmd
,
5729 "no ip pim ecmp rebalance",
5732 "pim multicast routing\n"
5733 "Disable PIM ECMP \n"
5734 "Disable PIM ECMP Rebalance\n")
5736 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5737 qpim_ecmp_rebalance_enable
= 0;
5742 static int pim_cmd_igmp_start(struct vty
*vty
, struct interface
*ifp
)
5744 struct pim_interface
*pim_ifp
;
5745 uint8_t need_startup
= 0;
5747 pim_ifp
= ifp
->info
;
5750 pim_ifp
= pim_if_new(ifp
, 1 /* igmp=true */, 0 /* pim=false */);
5752 vty_out(vty
, "Could not enable IGMP on interface %s\n",
5754 return CMD_WARNING_CONFIG_FAILED
;
5758 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
5759 PIM_IF_DO_IGMP(pim_ifp
->options
);
5764 /* 'ip igmp' executed multiple times, with need_startup
5765 avoid multiple if add all and membership refresh */
5767 pim_if_addr_add_all(ifp
);
5768 pim_if_membership_refresh(ifp
);
5774 DEFUN (interface_ip_igmp
,
5775 interface_ip_igmp_cmd
,
5780 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5782 return pim_cmd_igmp_start(vty
, ifp
);
5785 DEFUN (interface_no_ip_igmp
,
5786 interface_no_ip_igmp_cmd
,
5792 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5793 struct pim_interface
*pim_ifp
= ifp
->info
;
5798 PIM_IF_DONT_IGMP(pim_ifp
->options
);
5800 pim_if_membership_clear(ifp
);
5802 pim_if_addr_del_all_igmp(ifp
);
5804 if (!PIM_IF_TEST_PIM(pim_ifp
->options
)) {
5811 DEFUN (interface_ip_igmp_join
,
5812 interface_ip_igmp_join_cmd
,
5813 "ip igmp join A.B.C.D A.B.C.D",
5816 "IGMP join multicast group\n"
5817 "Multicast group address\n"
5820 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5823 const char *group_str
;
5824 const char *source_str
;
5825 struct in_addr group_addr
;
5826 struct in_addr source_addr
;
5830 group_str
= argv
[idx_ipv4
]->arg
;
5831 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
5833 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
5834 errno
, safe_strerror(errno
));
5835 return CMD_WARNING_CONFIG_FAILED
;
5838 /* Source address */
5839 source_str
= argv
[idx_ipv4_2
]->arg
;
5840 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
5842 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
5843 source_str
, errno
, safe_strerror(errno
));
5844 return CMD_WARNING_CONFIG_FAILED
;
5847 CMD_FERR_RETURN(pim_if_igmp_join_add(ifp
, group_addr
, source_addr
),
5848 "Failure joining IGMP group: $ERR");
5853 DEFUN (interface_no_ip_igmp_join
,
5854 interface_no_ip_igmp_join_cmd
,
5855 "no ip igmp join A.B.C.D A.B.C.D",
5859 "IGMP join multicast group\n"
5860 "Multicast group address\n"
5863 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5866 const char *group_str
;
5867 const char *source_str
;
5868 struct in_addr group_addr
;
5869 struct in_addr source_addr
;
5873 group_str
= argv
[idx_ipv4
]->arg
;
5874 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
5876 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
5877 errno
, safe_strerror(errno
));
5878 return CMD_WARNING_CONFIG_FAILED
;
5881 /* Source address */
5882 source_str
= argv
[idx_ipv4_2
]->arg
;
5883 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
5885 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
5886 source_str
, errno
, safe_strerror(errno
));
5887 return CMD_WARNING_CONFIG_FAILED
;
5890 result
= pim_if_igmp_join_del(ifp
, group_addr
, source_addr
);
5893 "%% Failure leaving IGMP group %s source %s on interface %s: %d\n",
5894 group_str
, source_str
, ifp
->name
, result
);
5895 return CMD_WARNING_CONFIG_FAILED
;
5902 CLI reconfiguration affects the interface level (struct pim_interface).
5903 This function propagates the reconfiguration to every active socket
5906 static void igmp_sock_query_interval_reconfig(struct igmp_sock
*igmp
)
5908 struct interface
*ifp
;
5909 struct pim_interface
*pim_ifp
;
5913 /* other querier present? */
5915 if (igmp
->t_other_querier_timer
)
5918 /* this is the querier */
5920 zassert(igmp
->interface
);
5921 zassert(igmp
->interface
->info
);
5923 ifp
= igmp
->interface
;
5924 pim_ifp
= ifp
->info
;
5926 if (PIM_DEBUG_IGMP_TRACE
) {
5927 char ifaddr_str
[INET_ADDRSTRLEN
];
5928 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
5929 sizeof(ifaddr_str
));
5930 zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
5931 __PRETTY_FUNCTION__
, ifaddr_str
, ifp
->name
,
5932 pim_ifp
->igmp_default_query_interval
);
5936 igmp_startup_mode_on() will reset QQI:
5938 igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
5940 igmp_startup_mode_on(igmp
);
5943 static void igmp_sock_query_reschedule(struct igmp_sock
*igmp
)
5945 if (igmp
->t_igmp_query_timer
) {
5946 /* other querier present */
5947 zassert(igmp
->t_igmp_query_timer
);
5948 zassert(!igmp
->t_other_querier_timer
);
5950 pim_igmp_general_query_off(igmp
);
5951 pim_igmp_general_query_on(igmp
);
5953 zassert(igmp
->t_igmp_query_timer
);
5954 zassert(!igmp
->t_other_querier_timer
);
5956 /* this is the querier */
5958 zassert(!igmp
->t_igmp_query_timer
);
5959 zassert(igmp
->t_other_querier_timer
);
5961 pim_igmp_other_querier_timer_off(igmp
);
5962 pim_igmp_other_querier_timer_on(igmp
);
5964 zassert(!igmp
->t_igmp_query_timer
);
5965 zassert(igmp
->t_other_querier_timer
);
5969 static void change_query_interval(struct pim_interface
*pim_ifp
,
5972 struct listnode
*sock_node
;
5973 struct igmp_sock
*igmp
;
5975 pim_ifp
->igmp_default_query_interval
= query_interval
;
5977 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
5978 igmp_sock_query_interval_reconfig(igmp
);
5979 igmp_sock_query_reschedule(igmp
);
5983 static void change_query_max_response_time(struct pim_interface
*pim_ifp
,
5984 int query_max_response_time_dsec
)
5986 struct listnode
*sock_node
;
5987 struct igmp_sock
*igmp
;
5989 pim_ifp
->igmp_query_max_response_time_dsec
=
5990 query_max_response_time_dsec
;
5993 Below we modify socket/group/source timers in order to quickly
5994 reflect the change. Otherwise, those timers would eventually catch
5998 /* scan all sockets */
5999 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
6000 struct listnode
*grp_node
;
6001 struct igmp_group
*grp
;
6003 /* reschedule socket general query */
6004 igmp_sock_query_reschedule(igmp
);
6006 /* scan socket groups */
6007 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grp_node
,
6009 struct listnode
*src_node
;
6010 struct igmp_source
*src
;
6012 /* reset group timers for groups in EXCLUDE mode */
6013 if (grp
->group_filtermode_isexcl
) {
6014 igmp_group_reset_gmi(grp
);
6017 /* scan group sources */
6018 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
,
6021 /* reset source timers for sources with running
6023 if (src
->t_source_timer
) {
6024 igmp_source_reset_gmi(igmp
, grp
, src
);
6031 #define IGMP_QUERY_INTERVAL_MIN (1)
6032 #define IGMP_QUERY_INTERVAL_MAX (1800)
6034 DEFUN (interface_ip_igmp_query_interval
,
6035 interface_ip_igmp_query_interval_cmd
,
6036 "ip igmp query-interval (1-1800)",
6039 IFACE_IGMP_QUERY_INTERVAL_STR
6040 "Query interval in seconds\n")
6042 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6043 struct pim_interface
*pim_ifp
= ifp
->info
;
6045 int query_interval_dsec
;
6049 ret
= pim_cmd_igmp_start(vty
, ifp
);
6050 if (ret
!= CMD_SUCCESS
)
6052 pim_ifp
= ifp
->info
;
6055 query_interval
= atoi(argv
[3]->arg
);
6056 query_interval_dsec
= 10 * query_interval
;
6059 It seems we don't need to check bounds since command.c does it
6060 already, but we verify them anyway for extra safety.
6062 if (query_interval
< IGMP_QUERY_INTERVAL_MIN
) {
6064 "General query interval %d lower than minimum %d\n",
6065 query_interval
, IGMP_QUERY_INTERVAL_MIN
);
6066 return CMD_WARNING_CONFIG_FAILED
;
6068 if (query_interval
> IGMP_QUERY_INTERVAL_MAX
) {
6070 "General query interval %d higher than maximum %d\n",
6071 query_interval
, IGMP_QUERY_INTERVAL_MAX
);
6072 return CMD_WARNING_CONFIG_FAILED
;
6075 if (query_interval_dsec
<= pim_ifp
->igmp_query_max_response_time_dsec
) {
6077 "Can't set general query interval %d dsec <= query max response time %d dsec.\n",
6078 query_interval_dsec
,
6079 pim_ifp
->igmp_query_max_response_time_dsec
);
6080 return CMD_WARNING_CONFIG_FAILED
;
6083 change_query_interval(pim_ifp
, query_interval
);
6088 DEFUN (interface_no_ip_igmp_query_interval
,
6089 interface_no_ip_igmp_query_interval_cmd
,
6090 "no ip igmp query-interval",
6094 IFACE_IGMP_QUERY_INTERVAL_STR
)
6096 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6097 struct pim_interface
*pim_ifp
= ifp
->info
;
6098 int default_query_interval_dsec
;
6103 default_query_interval_dsec
= IGMP_GENERAL_QUERY_INTERVAL
* 10;
6105 if (default_query_interval_dsec
6106 <= pim_ifp
->igmp_query_max_response_time_dsec
) {
6108 "Can't set default general query interval %d dsec <= query max response time %d dsec.\n",
6109 default_query_interval_dsec
,
6110 pim_ifp
->igmp_query_max_response_time_dsec
);
6111 return CMD_WARNING_CONFIG_FAILED
;
6114 change_query_interval(pim_ifp
, IGMP_GENERAL_QUERY_INTERVAL
);
6119 DEFUN (interface_ip_igmp_version
,
6120 interface_ip_igmp_version_cmd
,
6121 "ip igmp version (2-3)",
6125 "IGMP version number\n")
6127 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6128 struct pim_interface
*pim_ifp
= ifp
->info
;
6129 int igmp_version
, old_version
= 0;
6133 ret
= pim_cmd_igmp_start(vty
, ifp
);
6134 if (ret
!= CMD_SUCCESS
)
6136 pim_ifp
= ifp
->info
;
6139 igmp_version
= atoi(argv
[3]->arg
);
6140 old_version
= pim_ifp
->igmp_version
;
6141 pim_ifp
->igmp_version
= igmp_version
;
6143 // Check if IGMP is Enabled otherwise, enable on interface
6144 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
6145 PIM_IF_DO_IGMP(pim_ifp
->options
);
6146 pim_if_addr_add_all(ifp
);
6147 pim_if_membership_refresh(ifp
);
6148 old_version
= igmp_version
; // avoid refreshing membership
6151 /* Current and new version is different refresh existing
6152 membership. Going from 3 -> 2 or 2 -> 3. */
6153 if (old_version
!= igmp_version
)
6154 pim_if_membership_refresh(ifp
);
6159 DEFUN (interface_no_ip_igmp_version
,
6160 interface_no_ip_igmp_version_cmd
,
6161 "no ip igmp version (2-3)",
6166 "IGMP version number\n")
6168 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6169 struct pim_interface
*pim_ifp
= ifp
->info
;
6174 pim_ifp
->igmp_version
= IGMP_DEFAULT_VERSION
;
6179 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
6180 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
6182 DEFUN (interface_ip_igmp_query_max_response_time
,
6183 interface_ip_igmp_query_max_response_time_cmd
,
6184 "ip igmp query-max-response-time (10-250)",
6187 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
6188 "Query response value in deci-seconds\n")
6190 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6191 struct pim_interface
*pim_ifp
= ifp
->info
;
6192 int query_max_response_time
;
6196 ret
= pim_cmd_igmp_start(vty
, ifp
);
6197 if (ret
!= CMD_SUCCESS
)
6199 pim_ifp
= ifp
->info
;
6202 query_max_response_time
= atoi(argv
[3]->arg
);
6204 if (query_max_response_time
6205 >= pim_ifp
->igmp_default_query_interval
* 10) {
6207 "Can't set query max response time %d sec >= general query interval %d sec\n",
6208 query_max_response_time
,
6209 pim_ifp
->igmp_default_query_interval
);
6210 return CMD_WARNING_CONFIG_FAILED
;
6213 change_query_max_response_time(pim_ifp
, query_max_response_time
);
6218 DEFUN (interface_no_ip_igmp_query_max_response_time
,
6219 interface_no_ip_igmp_query_max_response_time_cmd
,
6220 "no ip igmp query-max-response-time (10-250)",
6224 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
6225 "Time for response in deci-seconds\n")
6227 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6228 struct pim_interface
*pim_ifp
= ifp
->info
;
6233 change_query_max_response_time(pim_ifp
,
6234 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
6239 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
6240 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
6242 DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec
,
6243 interface_ip_igmp_query_max_response_time_dsec_cmd
,
6244 "ip igmp query-max-response-time-dsec (10-250)",
6247 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
6248 "Query response value in deciseconds\n")
6250 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6251 struct pim_interface
*pim_ifp
= ifp
->info
;
6252 int query_max_response_time_dsec
;
6253 int default_query_interval_dsec
;
6257 ret
= pim_cmd_igmp_start(vty
, ifp
);
6258 if (ret
!= CMD_SUCCESS
)
6260 pim_ifp
= ifp
->info
;
6263 query_max_response_time_dsec
= atoi(argv
[4]->arg
);
6265 default_query_interval_dsec
= 10 * pim_ifp
->igmp_default_query_interval
;
6267 if (query_max_response_time_dsec
>= default_query_interval_dsec
) {
6269 "Can't set query max response time %d dsec >= general query interval %d dsec\n",
6270 query_max_response_time_dsec
,
6271 default_query_interval_dsec
);
6272 return CMD_WARNING_CONFIG_FAILED
;
6275 change_query_max_response_time(pim_ifp
, query_max_response_time_dsec
);
6280 DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec
,
6281 interface_no_ip_igmp_query_max_response_time_dsec_cmd
,
6282 "no ip igmp query-max-response-time-dsec",
6286 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
)
6288 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6289 struct pim_interface
*pim_ifp
= ifp
->info
;
6294 change_query_max_response_time(pim_ifp
,
6295 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
6300 DEFUN (interface_ip_pim_drprio
,
6301 interface_ip_pim_drprio_cmd
,
6302 "ip pim drpriority (1-4294967295)",
6305 "Set the Designated Router Election Priority\n"
6306 "Value of the new DR Priority\n")
6308 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6310 struct pim_interface
*pim_ifp
= ifp
->info
;
6311 uint32_t old_dr_prio
;
6314 vty_out(vty
, "Please enable PIM on interface, first\n");
6315 return CMD_WARNING_CONFIG_FAILED
;
6318 old_dr_prio
= pim_ifp
->pim_dr_priority
;
6320 pim_ifp
->pim_dr_priority
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
6322 if (old_dr_prio
!= pim_ifp
->pim_dr_priority
) {
6323 if (pim_if_dr_election(ifp
))
6324 pim_hello_restart_now(ifp
);
6330 DEFUN (interface_no_ip_pim_drprio
,
6331 interface_no_ip_pim_drprio_cmd
,
6332 "no ip pim drpriority [(1-4294967295)]",
6336 "Revert the Designated Router Priority to default\n"
6337 "Old Value of the Priority\n")
6339 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6340 struct pim_interface
*pim_ifp
= ifp
->info
;
6343 vty_out(vty
, "Pim not enabled on this interface\n");
6344 return CMD_WARNING_CONFIG_FAILED
;
6347 if (pim_ifp
->pim_dr_priority
!= PIM_DEFAULT_DR_PRIORITY
) {
6348 pim_ifp
->pim_dr_priority
= PIM_DEFAULT_DR_PRIORITY
;
6349 if (pim_if_dr_election(ifp
))
6350 pim_hello_restart_now(ifp
);
6356 static int pim_cmd_interface_add(struct interface
*ifp
)
6358 struct pim_interface
*pim_ifp
= ifp
->info
;
6361 pim_ifp
= pim_if_new(ifp
, 0 /* igmp=false */, 1 /* pim=true */);
6366 PIM_IF_DO_PIM(pim_ifp
->options
);
6369 pim_if_addr_add_all(ifp
);
6370 pim_if_membership_refresh(ifp
);
6374 DEFUN_HIDDEN (interface_ip_pim_ssm
,
6375 interface_ip_pim_ssm_cmd
,
6381 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6383 if (!pim_cmd_interface_add(ifp
)) {
6384 vty_out(vty
, "Could not enable PIM SM on interface\n");
6385 return CMD_WARNING_CONFIG_FAILED
;
6389 "WARN: Enabled PIM SM on interface; configure PIM SSM "
6390 "range if needed\n");
6394 DEFUN (interface_ip_pim_sm
,
6395 interface_ip_pim_sm_cmd
,
6401 struct pim_interface
*pim_ifp
;
6403 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6404 if (!pim_cmd_interface_add(ifp
)) {
6405 vty_out(vty
, "Could not enable PIM SM on interface\n");
6406 return CMD_WARNING_CONFIG_FAILED
;
6409 pim_ifp
= ifp
->info
;
6411 pim_if_create_pimreg(pim_ifp
->pim
);
6416 static int pim_cmd_interface_delete(struct interface
*ifp
)
6418 struct pim_interface
*pim_ifp
= ifp
->info
;
6423 PIM_IF_DONT_PIM(pim_ifp
->options
);
6425 pim_if_membership_clear(ifp
);
6428 pim_sock_delete() removes all neighbors from
6429 pim_ifp->pim_neighbor_list.
6431 pim_sock_delete(ifp
, "pim unconfigured on interface");
6433 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
6434 pim_if_addr_del_all(ifp
);
6441 DEFUN_HIDDEN (interface_no_ip_pim_ssm
,
6442 interface_no_ip_pim_ssm_cmd
,
6449 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6450 if (!pim_cmd_interface_delete(ifp
)) {
6451 vty_out(vty
, "Unable to delete interface information\n");
6452 return CMD_WARNING_CONFIG_FAILED
;
6458 DEFUN (interface_no_ip_pim_sm
,
6459 interface_no_ip_pim_sm_cmd
,
6466 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6467 if (!pim_cmd_interface_delete(ifp
)) {
6468 vty_out(vty
, "Unable to delete interface information\n");
6469 return CMD_WARNING_CONFIG_FAILED
;
6476 DEFUN(interface_ip_pim_boundary_oil
,
6477 interface_ip_pim_boundary_oil_cmd
,
6478 "ip multicast boundary oil WORD",
6480 "Generic multicast configuration options\n"
6481 "Define multicast boundary\n"
6482 "Filter OIL by group using prefix list\n"
6483 "Prefix list to filter OIL with\n")
6485 VTY_DECLVAR_CONTEXT(interface
, iif
);
6486 struct pim_interface
*pim_ifp
;
6489 argv_find(argv
, argc
, "WORD", &idx
);
6491 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6493 if (pim_ifp
->boundary_oil_plist
)
6494 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
6496 pim_ifp
->boundary_oil_plist
=
6497 XSTRDUP(MTYPE_PIM_INTERFACE
, argv
[idx
]->arg
);
6499 /* Interface will be pruned from OIL on next Join */
6503 DEFUN(interface_no_ip_pim_boundary_oil
,
6504 interface_no_ip_pim_boundary_oil_cmd
,
6505 "no ip multicast boundary oil [WORD]",
6508 "Generic multicast configuration options\n"
6509 "Define multicast boundary\n"
6510 "Filter OIL by group using prefix list\n"
6511 "Prefix list to filter OIL with\n")
6513 VTY_DECLVAR_CONTEXT(interface
, iif
);
6514 struct pim_interface
*pim_ifp
;
6517 argv_find(argv
, argc
, "WORD", &idx
);
6519 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6521 if (pim_ifp
->boundary_oil_plist
)
6522 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
6527 DEFUN (interface_ip_mroute
,
6528 interface_ip_mroute_cmd
,
6529 "ip mroute INTERFACE A.B.C.D",
6531 "Add multicast route\n"
6532 "Outgoing interface name\n"
6535 VTY_DECLVAR_CONTEXT(interface
, iif
);
6536 struct pim_interface
*pim_ifp
;
6537 struct pim_instance
*pim
;
6538 int idx_interface
= 2;
6540 struct interface
*oif
;
6541 const char *oifname
;
6542 const char *grp_str
;
6543 struct in_addr grp_addr
;
6544 struct in_addr src_addr
;
6547 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6550 oifname
= argv
[idx_interface
]->arg
;
6551 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6553 vty_out(vty
, "No such interface name %s\n", oifname
);
6557 grp_str
= argv
[idx_ipv4
]->arg
;
6558 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6560 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6561 errno
, safe_strerror(errno
));
6565 src_addr
.s_addr
= INADDR_ANY
;
6567 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6568 vty_out(vty
, "Failed to add route\n");
6575 DEFUN (interface_ip_mroute_source
,
6576 interface_ip_mroute_source_cmd
,
6577 "ip mroute INTERFACE A.B.C.D A.B.C.D",
6579 "Add multicast route\n"
6580 "Outgoing interface name\n"
6584 VTY_DECLVAR_CONTEXT(interface
, iif
);
6585 struct pim_interface
*pim_ifp
;
6586 struct pim_instance
*pim
;
6587 int idx_interface
= 2;
6590 struct interface
*oif
;
6591 const char *oifname
;
6592 const char *grp_str
;
6593 struct in_addr grp_addr
;
6594 const char *src_str
;
6595 struct in_addr src_addr
;
6598 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6601 oifname
= argv
[idx_interface
]->arg
;
6602 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6604 vty_out(vty
, "No such interface name %s\n", oifname
);
6608 grp_str
= argv
[idx_ipv4
]->arg
;
6609 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6611 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6612 errno
, safe_strerror(errno
));
6616 src_str
= argv
[idx_ipv4_2
]->arg
;
6617 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
6619 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
6620 errno
, safe_strerror(errno
));
6624 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6625 vty_out(vty
, "Failed to add route\n");
6632 DEFUN (interface_no_ip_mroute
,
6633 interface_no_ip_mroute_cmd
,
6634 "no ip mroute INTERFACE A.B.C.D",
6637 "Add multicast route\n"
6638 "Outgoing interface name\n"
6641 VTY_DECLVAR_CONTEXT(interface
, iif
);
6642 struct pim_interface
*pim_ifp
;
6643 struct pim_instance
*pim
;
6644 int idx_interface
= 3;
6646 struct interface
*oif
;
6647 const char *oifname
;
6648 const char *grp_str
;
6649 struct in_addr grp_addr
;
6650 struct in_addr src_addr
;
6653 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6656 oifname
= argv
[idx_interface
]->arg
;
6657 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6659 vty_out(vty
, "No such interface name %s\n", oifname
);
6663 grp_str
= argv
[idx_ipv4
]->arg
;
6664 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6666 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6667 errno
, safe_strerror(errno
));
6671 src_addr
.s_addr
= INADDR_ANY
;
6673 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6674 vty_out(vty
, "Failed to remove route\n");
6681 DEFUN (interface_no_ip_mroute_source
,
6682 interface_no_ip_mroute_source_cmd
,
6683 "no ip mroute INTERFACE A.B.C.D A.B.C.D",
6686 "Add multicast route\n"
6687 "Outgoing interface name\n"
6691 VTY_DECLVAR_CONTEXT(interface
, iif
);
6692 struct pim_interface
*pim_ifp
;
6693 struct pim_instance
*pim
;
6694 int idx_interface
= 3;
6697 struct interface
*oif
;
6698 const char *oifname
;
6699 const char *grp_str
;
6700 struct in_addr grp_addr
;
6701 const char *src_str
;
6702 struct in_addr src_addr
;
6705 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6708 oifname
= argv
[idx_interface
]->arg
;
6709 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6711 vty_out(vty
, "No such interface name %s\n", oifname
);
6715 grp_str
= argv
[idx_ipv4
]->arg
;
6716 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6718 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6719 errno
, safe_strerror(errno
));
6723 src_str
= argv
[idx_ipv4_2
]->arg
;
6724 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
6726 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
6727 errno
, safe_strerror(errno
));
6731 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6732 vty_out(vty
, "Failed to remove route\n");
6739 DEFUN (interface_ip_pim_hello
,
6740 interface_ip_pim_hello_cmd
,
6741 "ip pim hello (1-180) [(1-180)]",
6745 IFACE_PIM_HELLO_TIME_STR
6746 IFACE_PIM_HELLO_HOLD_STR
)
6748 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6751 struct pim_interface
*pim_ifp
= ifp
->info
;
6754 if (!pim_cmd_interface_add(ifp
)) {
6755 vty_out(vty
, "Could not enable PIM SM on interface\n");
6756 return CMD_WARNING_CONFIG_FAILED
;
6760 pim_ifp
= ifp
->info
;
6761 pim_ifp
->pim_hello_period
= strtol(argv
[idx_time
]->arg
, NULL
, 10);
6763 if (argc
== idx_hold
+ 1)
6764 pim_ifp
->pim_default_holdtime
=
6765 strtol(argv
[idx_hold
]->arg
, NULL
, 10);
6770 DEFUN (interface_no_ip_pim_hello
,
6771 interface_no_ip_pim_hello_cmd
,
6772 "no ip pim hello [(1-180) (1-180)]",
6777 IFACE_PIM_HELLO_TIME_STR
6778 IFACE_PIM_HELLO_HOLD_STR
)
6780 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6781 struct pim_interface
*pim_ifp
= ifp
->info
;
6784 vty_out(vty
, "Pim not enabled on this interface\n");
6785 return CMD_WARNING_CONFIG_FAILED
;
6788 pim_ifp
->pim_hello_period
= PIM_DEFAULT_HELLO_PERIOD
;
6789 pim_ifp
->pim_default_holdtime
= -1;
6800 PIM_DO_DEBUG_IGMP_EVENTS
;
6801 PIM_DO_DEBUG_IGMP_PACKETS
;
6802 PIM_DO_DEBUG_IGMP_TRACE
;
6806 DEFUN (no_debug_igmp
,
6813 PIM_DONT_DEBUG_IGMP_EVENTS
;
6814 PIM_DONT_DEBUG_IGMP_PACKETS
;
6815 PIM_DONT_DEBUG_IGMP_TRACE
;
6820 DEFUN (debug_igmp_events
,
6821 debug_igmp_events_cmd
,
6822 "debug igmp events",
6825 DEBUG_IGMP_EVENTS_STR
)
6827 PIM_DO_DEBUG_IGMP_EVENTS
;
6831 DEFUN (no_debug_igmp_events
,
6832 no_debug_igmp_events_cmd
,
6833 "no debug igmp events",
6837 DEBUG_IGMP_EVENTS_STR
)
6839 PIM_DONT_DEBUG_IGMP_EVENTS
;
6844 DEFUN (debug_igmp_packets
,
6845 debug_igmp_packets_cmd
,
6846 "debug igmp packets",
6849 DEBUG_IGMP_PACKETS_STR
)
6851 PIM_DO_DEBUG_IGMP_PACKETS
;
6855 DEFUN (no_debug_igmp_packets
,
6856 no_debug_igmp_packets_cmd
,
6857 "no debug igmp packets",
6861 DEBUG_IGMP_PACKETS_STR
)
6863 PIM_DONT_DEBUG_IGMP_PACKETS
;
6868 DEFUN (debug_igmp_trace
,
6869 debug_igmp_trace_cmd
,
6873 DEBUG_IGMP_TRACE_STR
)
6875 PIM_DO_DEBUG_IGMP_TRACE
;
6879 DEFUN (no_debug_igmp_trace
,
6880 no_debug_igmp_trace_cmd
,
6881 "no debug igmp trace",
6885 DEBUG_IGMP_TRACE_STR
)
6887 PIM_DONT_DEBUG_IGMP_TRACE
;
6892 DEFUN (debug_mroute
,
6898 PIM_DO_DEBUG_MROUTE
;
6902 DEFUN (debug_mroute_detail
,
6903 debug_mroute_detail_cmd
,
6904 "debug mroute detail",
6909 PIM_DO_DEBUG_MROUTE_DETAIL
;
6913 DEFUN (no_debug_mroute
,
6914 no_debug_mroute_cmd
,
6920 PIM_DONT_DEBUG_MROUTE
;
6924 DEFUN (no_debug_mroute_detail
,
6925 no_debug_mroute_detail_cmd
,
6926 "no debug mroute detail",
6932 PIM_DONT_DEBUG_MROUTE_DETAIL
;
6936 DEFUN (debug_static
,
6942 PIM_DO_DEBUG_STATIC
;
6946 DEFUN (no_debug_static
,
6947 no_debug_static_cmd
,
6953 PIM_DONT_DEBUG_STATIC
;
6964 PIM_DO_DEBUG_PIM_EVENTS
;
6965 PIM_DO_DEBUG_PIM_PACKETS
;
6966 PIM_DO_DEBUG_PIM_TRACE
;
6967 PIM_DO_DEBUG_MSDP_EVENTS
;
6968 PIM_DO_DEBUG_MSDP_PACKETS
;
6972 DEFUN (no_debug_pim
,
6979 PIM_DONT_DEBUG_PIM_EVENTS
;
6980 PIM_DONT_DEBUG_PIM_PACKETS
;
6981 PIM_DONT_DEBUG_PIM_TRACE
;
6982 PIM_DONT_DEBUG_MSDP_EVENTS
;
6983 PIM_DONT_DEBUG_MSDP_PACKETS
;
6985 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
6986 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
6991 DEFUN (debug_pim_nht
,
6996 "Nexthop Tracking\n")
6998 PIM_DO_DEBUG_PIM_NHT
;
7002 DEFUN (no_debug_pim_nht
,
7003 no_debug_pim_nht_cmd
,
7008 "Nexthop Tracking\n")
7010 PIM_DONT_DEBUG_PIM_NHT
;
7014 DEFUN (debug_pim_nht_rp
,
7015 debug_pim_nht_rp_cmd
,
7019 "Nexthop Tracking\n"
7020 "RP Nexthop Tracking\n")
7022 PIM_DO_DEBUG_PIM_NHT_RP
;
7026 DEFUN (no_debug_pim_nht_rp
,
7027 no_debug_pim_nht_rp_cmd
,
7028 "no debug pim nht rp",
7032 "Nexthop Tracking\n"
7033 "RP Nexthop Tracking\n")
7035 PIM_DONT_DEBUG_PIM_NHT_RP
;
7039 DEFUN (debug_pim_events
,
7040 debug_pim_events_cmd
,
7044 DEBUG_PIM_EVENTS_STR
)
7046 PIM_DO_DEBUG_PIM_EVENTS
;
7050 DEFUN (no_debug_pim_events
,
7051 no_debug_pim_events_cmd
,
7052 "no debug pim events",
7056 DEBUG_PIM_EVENTS_STR
)
7058 PIM_DONT_DEBUG_PIM_EVENTS
;
7062 DEFUN (debug_pim_packets
,
7063 debug_pim_packets_cmd
,
7064 "debug pim packets [<hello|joins|register>]",
7067 DEBUG_PIM_PACKETS_STR
7068 DEBUG_PIM_HELLO_PACKETS_STR
7069 DEBUG_PIM_J_P_PACKETS_STR
7070 DEBUG_PIM_PIM_REG_PACKETS_STR
)
7073 if (argv_find(argv
, argc
, "hello", &idx
)) {
7074 PIM_DO_DEBUG_PIM_HELLO
;
7075 vty_out(vty
, "PIM Hello debugging is on\n");
7076 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
7077 PIM_DO_DEBUG_PIM_J_P
;
7078 vty_out(vty
, "PIM Join/Prune debugging is on\n");
7079 } else if (argv_find(argv
, argc
, "register", &idx
)) {
7080 PIM_DO_DEBUG_PIM_REG
;
7081 vty_out(vty
, "PIM Register debugging is on\n");
7083 PIM_DO_DEBUG_PIM_PACKETS
;
7084 vty_out(vty
, "PIM Packet debugging is on \n");
7089 DEFUN (no_debug_pim_packets
,
7090 no_debug_pim_packets_cmd
,
7091 "no debug pim packets [<hello|joins|register>]",
7095 DEBUG_PIM_PACKETS_STR
7096 DEBUG_PIM_HELLO_PACKETS_STR
7097 DEBUG_PIM_J_P_PACKETS_STR
7098 DEBUG_PIM_PIM_REG_PACKETS_STR
)
7101 if (argv_find(argv
, argc
, "hello", &idx
)) {
7102 PIM_DONT_DEBUG_PIM_HELLO
;
7103 vty_out(vty
, "PIM Hello debugging is off \n");
7104 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
7105 PIM_DONT_DEBUG_PIM_J_P
;
7106 vty_out(vty
, "PIM Join/Prune debugging is off \n");
7107 } else if (argv_find(argv
, argc
, "register", &idx
)) {
7108 PIM_DONT_DEBUG_PIM_REG
;
7109 vty_out(vty
, "PIM Register debugging is off\n");
7111 PIM_DONT_DEBUG_PIM_PACKETS
;
7117 DEFUN (debug_pim_packetdump_send
,
7118 debug_pim_packetdump_send_cmd
,
7119 "debug pim packet-dump send",
7122 DEBUG_PIM_PACKETDUMP_STR
7123 DEBUG_PIM_PACKETDUMP_SEND_STR
)
7125 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND
;
7129 DEFUN (no_debug_pim_packetdump_send
,
7130 no_debug_pim_packetdump_send_cmd
,
7131 "no debug pim packet-dump send",
7135 DEBUG_PIM_PACKETDUMP_STR
7136 DEBUG_PIM_PACKETDUMP_SEND_STR
)
7138 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
7142 DEFUN (debug_pim_packetdump_recv
,
7143 debug_pim_packetdump_recv_cmd
,
7144 "debug pim packet-dump receive",
7147 DEBUG_PIM_PACKETDUMP_STR
7148 DEBUG_PIM_PACKETDUMP_RECV_STR
)
7150 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV
;
7154 DEFUN (no_debug_pim_packetdump_recv
,
7155 no_debug_pim_packetdump_recv_cmd
,
7156 "no debug pim packet-dump receive",
7160 DEBUG_PIM_PACKETDUMP_STR
7161 DEBUG_PIM_PACKETDUMP_RECV_STR
)
7163 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
7167 DEFUN (debug_pim_trace
,
7168 debug_pim_trace_cmd
,
7172 DEBUG_PIM_TRACE_STR
)
7174 PIM_DO_DEBUG_PIM_TRACE
;
7178 DEFUN (debug_pim_trace_detail
,
7179 debug_pim_trace_detail_cmd
,
7180 "debug pim trace detail",
7184 "Detailed Information\n")
7186 PIM_DO_DEBUG_PIM_TRACE_DETAIL
;
7190 DEFUN (no_debug_pim_trace
,
7191 no_debug_pim_trace_cmd
,
7192 "no debug pim trace",
7196 DEBUG_PIM_TRACE_STR
)
7198 PIM_DONT_DEBUG_PIM_TRACE
;
7202 DEFUN (no_debug_pim_trace_detail
,
7203 no_debug_pim_trace_detail_cmd
,
7204 "no debug pim trace detail",
7209 "Detailed Information\n")
7211 PIM_DONT_DEBUG_PIM_TRACE_DETAIL
;
7215 DEFUN (debug_ssmpingd
,
7221 PIM_DO_DEBUG_SSMPINGD
;
7225 DEFUN (no_debug_ssmpingd
,
7226 no_debug_ssmpingd_cmd
,
7227 "no debug ssmpingd",
7232 PIM_DONT_DEBUG_SSMPINGD
;
7236 DEFUN (debug_pim_zebra
,
7237 debug_pim_zebra_cmd
,
7241 DEBUG_PIM_ZEBRA_STR
)
7247 DEFUN (no_debug_pim_zebra
,
7248 no_debug_pim_zebra_cmd
,
7249 "no debug pim zebra",
7253 DEBUG_PIM_ZEBRA_STR
)
7255 PIM_DONT_DEBUG_ZEBRA
;
7265 PIM_DO_DEBUG_MSDP_EVENTS
;
7266 PIM_DO_DEBUG_MSDP_PACKETS
;
7270 DEFUN (no_debug_msdp
,
7277 PIM_DONT_DEBUG_MSDP_EVENTS
;
7278 PIM_DONT_DEBUG_MSDP_PACKETS
;
7282 ALIAS(no_debug_msdp
, undebug_msdp_cmd
, "undebug msdp",
7283 UNDEBUG_STR DEBUG_MSDP_STR
)
7285 DEFUN (debug_msdp_events
,
7286 debug_msdp_events_cmd
,
7287 "debug msdp events",
7290 DEBUG_MSDP_EVENTS_STR
)
7292 PIM_DO_DEBUG_MSDP_EVENTS
;
7296 DEFUN (no_debug_msdp_events
,
7297 no_debug_msdp_events_cmd
,
7298 "no debug msdp events",
7302 DEBUG_MSDP_EVENTS_STR
)
7304 PIM_DONT_DEBUG_MSDP_EVENTS
;
7308 ALIAS(no_debug_msdp_events
, undebug_msdp_events_cmd
, "undebug msdp events",
7309 UNDEBUG_STR DEBUG_MSDP_STR DEBUG_MSDP_EVENTS_STR
)
7311 DEFUN (debug_msdp_packets
,
7312 debug_msdp_packets_cmd
,
7313 "debug msdp packets",
7316 DEBUG_MSDP_PACKETS_STR
)
7318 PIM_DO_DEBUG_MSDP_PACKETS
;
7322 DEFUN (no_debug_msdp_packets
,
7323 no_debug_msdp_packets_cmd
,
7324 "no debug msdp packets",
7328 DEBUG_MSDP_PACKETS_STR
)
7330 PIM_DONT_DEBUG_MSDP_PACKETS
;
7334 ALIAS(no_debug_msdp_packets
, undebug_msdp_packets_cmd
, "undebug msdp packets",
7335 UNDEBUG_STR DEBUG_MSDP_STR DEBUG_MSDP_PACKETS_STR
)
7337 DEFUN_NOSH (show_debugging_pim
,
7338 show_debugging_pim_cmd
,
7339 "show debugging [pim]",
7344 vty_out(vty
, "PIM debugging status\n");
7346 pim_debug_config_write(vty
);
7351 static int interface_pim_use_src_cmd_worker(struct vty
*vty
, const char *source
)
7354 struct in_addr source_addr
;
7355 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7357 result
= inet_pton(AF_INET
, source
, &source_addr
);
7359 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", source
,
7360 errno
, safe_strerror(errno
));
7361 return CMD_WARNING_CONFIG_FAILED
;
7364 result
= pim_update_source_set(ifp
, source_addr
);
7368 case PIM_IFACE_NOT_FOUND
:
7369 vty_out(vty
, "Pim not enabled on this interface\n");
7371 case PIM_UPDATE_SOURCE_DUP
:
7372 vty_out(vty
, "%% Source already set to %s\n", source
);
7375 vty_out(vty
, "%% Source set failed\n");
7378 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7381 DEFUN (interface_pim_use_source
,
7382 interface_pim_use_source_cmd
,
7383 "ip pim use-source A.B.C.D",
7385 "pim multicast routing\n"
7386 "Configure primary IP address\n"
7387 "source ip address\n")
7389 return interface_pim_use_src_cmd_worker(vty
, argv
[3]->arg
);
7392 DEFUN (interface_no_pim_use_source
,
7393 interface_no_pim_use_source_cmd
,
7394 "no ip pim use-source [A.B.C.D]",
7397 "pim multicast routing\n"
7398 "Delete source IP address\n"
7399 "source ip address\n")
7401 return interface_pim_use_src_cmd_worker(vty
, "0.0.0.0");
7409 "Enables BFD support\n")
7411 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7412 struct pim_interface
*pim_ifp
= ifp
->info
;
7413 struct bfd_info
*bfd_info
= NULL
;
7416 if (!pim_cmd_interface_add(ifp
)) {
7417 vty_out(vty
, "Could not enable PIM SM on interface\n");
7421 pim_ifp
= ifp
->info
;
7423 bfd_info
= pim_ifp
->bfd_info
;
7425 if (!bfd_info
|| !CHECK_FLAG(bfd_info
->flags
, BFD_FLAG_PARAM_CFG
))
7426 pim_bfd_if_param_set(ifp
, BFD_DEF_MIN_RX
, BFD_DEF_MIN_TX
,
7427 BFD_DEF_DETECT_MULT
, 1);
7432 DEFUN (no_ip_pim_bfd
,
7438 "Disables BFD support\n")
7440 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7441 struct pim_interface
*pim_ifp
= ifp
->info
;
7444 vty_out(vty
, "Pim not enabled on this interface\n");
7448 if (pim_ifp
->bfd_info
) {
7449 pim_bfd_reg_dereg_all_nbr(ifp
, ZEBRA_BFD_DEST_DEREGISTER
);
7450 bfd_info_free(&(pim_ifp
->bfd_info
));
7456 DEFUN (ip_pim_bfd_param
,
7457 ip_pim_bfd_param_cmd
,
7458 "ip pim bfd (2-255) (50-60000) (50-60000)",
7461 "Enables BFD support\n"
7462 "Detect Multiplier\n"
7463 "Required min receive interval\n"
7464 "Desired min transmit interval\n")
7466 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7468 int idx_number_2
= 4;
7469 int idx_number_3
= 5;
7474 struct pim_interface
*pim_ifp
= ifp
->info
;
7477 if (!pim_cmd_interface_add(ifp
)) {
7478 vty_out(vty
, "Could not enable PIM SM on interface\n");
7483 if ((ret
= bfd_validate_param(
7484 vty
, argv
[idx_number
]->arg
, argv
[idx_number_2
]->arg
,
7485 argv
[idx_number_3
]->arg
, &dm_val
, &rx_val
, &tx_val
))
7489 pim_bfd_if_param_set(ifp
, rx_val
, tx_val
, dm_val
, 0);
7494 ALIAS(no_ip_pim_bfd
, no_ip_pim_bfd_param_cmd
,
7495 "no ip pim bfd (2-255) (50-60000) (50-60000)", NO_STR IP_STR PIM_STR
7496 "Enables BFD support\n"
7497 "Detect Multiplier\n"
7498 "Required min receive interval\n"
7499 "Desired min transmit interval\n")
7501 static int ip_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
7502 const char *peer
, const char *local
)
7504 enum pim_msdp_err result
;
7505 struct in_addr peer_addr
;
7506 struct in_addr local_addr
;
7508 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
7510 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
7511 errno
, safe_strerror(errno
));
7512 return CMD_WARNING_CONFIG_FAILED
;
7515 result
= inet_pton(AF_INET
, local
, &local_addr
);
7517 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", local
,
7518 errno
, safe_strerror(errno
));
7519 return CMD_WARNING_CONFIG_FAILED
;
7522 result
= pim_msdp_peer_add(pim
, peer_addr
, local_addr
, "default",
7525 case PIM_MSDP_ERR_NONE
:
7527 case PIM_MSDP_ERR_OOM
:
7528 vty_out(vty
, "%% Out of memory\n");
7530 case PIM_MSDP_ERR_PEER_EXISTS
:
7531 vty_out(vty
, "%% Peer exists\n");
7533 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
7534 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
7537 vty_out(vty
, "%% peer add failed\n");
7540 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7543 DEFUN_HIDDEN (ip_msdp_peer
,
7545 "ip msdp peer A.B.C.D source A.B.C.D",
7548 "Configure MSDP peer\n"
7550 "Source address for TCP connection\n"
7551 "local ip address\n")
7553 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7554 return ip_msdp_peer_cmd_worker(pim
, vty
, argv
[3]->arg
, argv
[5]->arg
);
7557 static int ip_no_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
7560 enum pim_msdp_err result
;
7561 struct in_addr peer_addr
;
7563 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
7565 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
7566 errno
, safe_strerror(errno
));
7567 return CMD_WARNING_CONFIG_FAILED
;
7570 result
= pim_msdp_peer_del(pim
, peer_addr
);
7572 case PIM_MSDP_ERR_NONE
:
7574 case PIM_MSDP_ERR_NO_PEER
:
7575 vty_out(vty
, "%% Peer does not exist\n");
7578 vty_out(vty
, "%% peer del failed\n");
7581 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7584 DEFUN_HIDDEN (no_ip_msdp_peer
,
7585 no_ip_msdp_peer_cmd
,
7586 "no ip msdp peer A.B.C.D",
7590 "Delete MSDP peer\n"
7591 "peer ip address\n")
7593 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7594 return ip_no_msdp_peer_cmd_worker(pim
, vty
, argv
[4]->arg
);
7597 static int ip_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
7598 struct vty
*vty
, const char *mg
,
7601 enum pim_msdp_err result
;
7602 struct in_addr mbr_ip
;
7604 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
7606 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
7607 errno
, safe_strerror(errno
));
7608 return CMD_WARNING_CONFIG_FAILED
;
7611 result
= pim_msdp_mg_mbr_add(pim
, mg
, mbr_ip
);
7613 case PIM_MSDP_ERR_NONE
:
7615 case PIM_MSDP_ERR_OOM
:
7616 vty_out(vty
, "%% Out of memory\n");
7618 case PIM_MSDP_ERR_MG_MBR_EXISTS
:
7619 vty_out(vty
, "%% mesh-group member exists\n");
7621 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
7622 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
7625 vty_out(vty
, "%% member add failed\n");
7628 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7631 DEFUN (ip_msdp_mesh_group_member
,
7632 ip_msdp_mesh_group_member_cmd
,
7633 "ip msdp mesh-group WORD member A.B.C.D",
7636 "Configure MSDP mesh-group\n"
7638 "mesh group member\n"
7639 "peer ip address\n")
7641 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7642 return ip_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[3]->arg
,
7646 static int ip_no_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
7651 enum pim_msdp_err result
;
7652 struct in_addr mbr_ip
;
7654 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
7656 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
7657 errno
, safe_strerror(errno
));
7658 return CMD_WARNING_CONFIG_FAILED
;
7661 result
= pim_msdp_mg_mbr_del(pim
, mg
, mbr_ip
);
7663 case PIM_MSDP_ERR_NONE
:
7665 case PIM_MSDP_ERR_NO_MG
:
7666 vty_out(vty
, "%% mesh-group does not exist\n");
7668 case PIM_MSDP_ERR_NO_MG_MBR
:
7669 vty_out(vty
, "%% mesh-group member does not exist\n");
7672 vty_out(vty
, "%% mesh-group member del failed\n");
7675 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7677 DEFUN (no_ip_msdp_mesh_group_member
,
7678 no_ip_msdp_mesh_group_member_cmd
,
7679 "no ip msdp mesh-group WORD member A.B.C.D",
7683 "Delete MSDP mesh-group member\n"
7685 "mesh group member\n"
7686 "peer ip address\n")
7688 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7689 return ip_no_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[4]->arg
,
7693 static int ip_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
7694 struct vty
*vty
, const char *mg
,
7697 enum pim_msdp_err result
;
7698 struct in_addr src_ip
;
7700 result
= inet_pton(AF_INET
, src
, &src_ip
);
7702 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", src
,
7703 errno
, safe_strerror(errno
));
7704 return CMD_WARNING_CONFIG_FAILED
;
7707 result
= pim_msdp_mg_src_add(pim
, mg
, src_ip
);
7709 case PIM_MSDP_ERR_NONE
:
7711 case PIM_MSDP_ERR_OOM
:
7712 vty_out(vty
, "%% Out of memory\n");
7714 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
7715 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
7718 vty_out(vty
, "%% source add failed\n");
7721 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7725 DEFUN (ip_msdp_mesh_group_source
,
7726 ip_msdp_mesh_group_source_cmd
,
7727 "ip msdp mesh-group WORD source A.B.C.D",
7730 "Configure MSDP mesh-group\n"
7732 "mesh group local address\n"
7733 "source ip address for the TCP connection\n")
7735 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7736 return ip_msdp_mesh_group_source_cmd_worker(pim
, vty
, argv
[3]->arg
,
7740 static int ip_no_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
7744 enum pim_msdp_err result
;
7746 result
= pim_msdp_mg_src_del(pim
, mg
);
7748 case PIM_MSDP_ERR_NONE
:
7750 case PIM_MSDP_ERR_NO_MG
:
7751 vty_out(vty
, "%% mesh-group does not exist\n");
7754 vty_out(vty
, "%% mesh-group source del failed\n");
7757 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7760 static int ip_no_msdp_mesh_group_cmd_worker(struct pim_instance
*pim
,
7761 struct vty
*vty
, const char *mg
)
7763 enum pim_msdp_err result
;
7765 result
= pim_msdp_mg_del(pim
, mg
);
7767 case PIM_MSDP_ERR_NONE
:
7769 case PIM_MSDP_ERR_NO_MG
:
7770 vty_out(vty
, "%% mesh-group does not exist\n");
7773 vty_out(vty
, "%% mesh-group source del failed\n");
7776 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7779 DEFUN (no_ip_msdp_mesh_group_source
,
7780 no_ip_msdp_mesh_group_source_cmd
,
7781 "no ip msdp mesh-group WORD source [A.B.C.D]",
7785 "Delete MSDP mesh-group source\n"
7787 "mesh group source\n"
7788 "mesh group local address\n")
7790 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7792 return ip_no_msdp_mesh_group_cmd_worker(pim
, vty
, argv
[6]->arg
);
7794 return ip_no_msdp_mesh_group_source_cmd_worker(pim
, vty
,
7798 static void print_empty_json_obj(struct vty
*vty
)
7801 json
= json_object_new_object();
7802 vty_out(vty
, "%s\n",
7803 json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
));
7804 json_object_free(json
);
7807 static void ip_msdp_show_mesh_group(struct pim_instance
*pim
, struct vty
*vty
,
7810 struct listnode
*mbrnode
;
7811 struct pim_msdp_mg_mbr
*mbr
;
7812 struct pim_msdp_mg
*mg
= pim
->msdp
.mg
;
7813 char mbr_str
[INET_ADDRSTRLEN
];
7814 char src_str
[INET_ADDRSTRLEN
];
7815 char state_str
[PIM_MSDP_STATE_STRLEN
];
7816 enum pim_msdp_peer_state state
;
7817 json_object
*json
= NULL
;
7818 json_object
*json_mg_row
= NULL
;
7819 json_object
*json_members
= NULL
;
7820 json_object
*json_row
= NULL
;
7824 print_empty_json_obj(vty
);
7828 pim_inet4_dump("<source?>", mg
->src_ip
, src_str
, sizeof(src_str
));
7830 json
= json_object_new_object();
7831 /* currently there is only one mesh group but we should still
7833 * it a dict with mg-name as key */
7834 json_mg_row
= json_object_new_object();
7835 json_object_string_add(json_mg_row
, "name",
7836 mg
->mesh_group_name
);
7837 json_object_string_add(json_mg_row
, "source", src_str
);
7839 vty_out(vty
, "Mesh group : %s\n", mg
->mesh_group_name
);
7840 vty_out(vty
, " Source : %s\n", src_str
);
7841 vty_out(vty
, " Member State\n");
7844 for (ALL_LIST_ELEMENTS_RO(mg
->mbr_list
, mbrnode
, mbr
)) {
7845 pim_inet4_dump("<mbr?>", mbr
->mbr_ip
, mbr_str
, sizeof(mbr_str
));
7847 state
= mbr
->mp
->state
;
7849 state
= PIM_MSDP_DISABLED
;
7851 pim_msdp_state_dump(state
, state_str
, sizeof(state_str
));
7853 json_row
= json_object_new_object();
7854 json_object_string_add(json_row
, "member", mbr_str
);
7855 json_object_string_add(json_row
, "state", state_str
);
7856 if (!json_members
) {
7857 json_members
= json_object_new_object();
7858 json_object_object_add(json_mg_row
, "members",
7861 json_object_object_add(json_members
, mbr_str
, json_row
);
7863 vty_out(vty
, " %-15s %11s\n", mbr_str
, state_str
);
7868 json_object_object_add(json
, mg
->mesh_group_name
, json_mg_row
);
7869 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
7870 json
, JSON_C_TO_STRING_PRETTY
));
7871 json_object_free(json
);
7875 DEFUN (show_ip_msdp_mesh_group
,
7876 show_ip_msdp_mesh_group_cmd
,
7877 "show ip msdp [vrf NAME] mesh-group [json]",
7882 "MSDP mesh-group information\n"
7885 u_char uj
= use_json(argc
, argv
);
7887 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
7892 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
7897 DEFUN (show_ip_msdp_mesh_group_vrf_all
,
7898 show_ip_msdp_mesh_group_vrf_all_cmd
,
7899 "show ip msdp vrf all mesh-group [json]",
7904 "MSDP mesh-group information\n"
7907 u_char uj
= use_json(argc
, argv
);
7913 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
7917 vty_out(vty
, " \"%s\": ", vrf
->name
);
7920 vty_out(vty
, "VRF: %s\n", vrf
->name
);
7921 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
7924 vty_out(vty
, "}\n");
7929 static void ip_msdp_show_peers(struct pim_instance
*pim
, struct vty
*vty
,
7932 struct listnode
*mpnode
;
7933 struct pim_msdp_peer
*mp
;
7934 char peer_str
[INET_ADDRSTRLEN
];
7935 char local_str
[INET_ADDRSTRLEN
];
7936 char state_str
[PIM_MSDP_STATE_STRLEN
];
7937 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
7939 json_object
*json
= NULL
;
7940 json_object
*json_row
= NULL
;
7944 json
= json_object_new_object();
7947 "Peer Local State Uptime SaCnt\n");
7950 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
7951 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
7952 now
= pim_time_monotonic_sec();
7953 pim_time_uptime(timebuf
, sizeof(timebuf
),
7956 strcpy(timebuf
, "-");
7958 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
7959 pim_inet4_dump("<local?>", mp
->local
, local_str
,
7961 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
7963 json_row
= json_object_new_object();
7964 json_object_string_add(json_row
, "peer", peer_str
);
7965 json_object_string_add(json_row
, "local", local_str
);
7966 json_object_string_add(json_row
, "state", state_str
);
7967 json_object_string_add(json_row
, "upTime", timebuf
);
7968 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
7969 json_object_object_add(json
, peer_str
, json_row
);
7971 vty_out(vty
, "%-15s %15s %11s %8s %6d\n", peer_str
,
7972 local_str
, state_str
, timebuf
, mp
->sa_cnt
);
7977 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
7978 json
, JSON_C_TO_STRING_PRETTY
));
7979 json_object_free(json
);
7983 static void ip_msdp_show_peers_detail(struct pim_instance
*pim
, struct vty
*vty
,
7984 const char *peer
, u_char uj
)
7986 struct listnode
*mpnode
;
7987 struct pim_msdp_peer
*mp
;
7988 char peer_str
[INET_ADDRSTRLEN
];
7989 char local_str
[INET_ADDRSTRLEN
];
7990 char state_str
[PIM_MSDP_STATE_STRLEN
];
7991 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
7992 char katimer
[PIM_MSDP_TIMER_STRLEN
];
7993 char crtimer
[PIM_MSDP_TIMER_STRLEN
];
7994 char holdtimer
[PIM_MSDP_TIMER_STRLEN
];
7996 json_object
*json
= NULL
;
7997 json_object
*json_row
= NULL
;
8000 json
= json_object_new_object();
8003 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
8004 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
8005 if (strcmp(peer
, "detail") && strcmp(peer
, peer_str
))
8008 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
8009 now
= pim_time_monotonic_sec();
8010 pim_time_uptime(timebuf
, sizeof(timebuf
),
8013 strcpy(timebuf
, "-");
8015 pim_inet4_dump("<local?>", mp
->local
, local_str
,
8017 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
8018 pim_time_timer_to_hhmmss(katimer
, sizeof(katimer
),
8020 pim_time_timer_to_hhmmss(crtimer
, sizeof(crtimer
),
8022 pim_time_timer_to_hhmmss(holdtimer
, sizeof(holdtimer
),
8026 json_row
= json_object_new_object();
8027 json_object_string_add(json_row
, "peer", peer_str
);
8028 json_object_string_add(json_row
, "local", local_str
);
8029 json_object_string_add(json_row
, "meshGroupName",
8030 mp
->mesh_group_name
);
8031 json_object_string_add(json_row
, "state", state_str
);
8032 json_object_string_add(json_row
, "upTime", timebuf
);
8033 json_object_string_add(json_row
, "keepAliveTimer",
8035 json_object_string_add(json_row
, "connRetryTimer",
8037 json_object_string_add(json_row
, "holdTimer",
8039 json_object_string_add(json_row
, "lastReset",
8041 json_object_int_add(json_row
, "connAttempts",
8043 json_object_int_add(json_row
, "establishedChanges",
8045 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
8046 json_object_int_add(json_row
, "kaSent", mp
->ka_tx_cnt
);
8047 json_object_int_add(json_row
, "kaRcvd", mp
->ka_rx_cnt
);
8048 json_object_int_add(json_row
, "saSent", mp
->sa_tx_cnt
);
8049 json_object_int_add(json_row
, "saRcvd", mp
->sa_rx_cnt
);
8050 json_object_object_add(json
, peer_str
, json_row
);
8052 vty_out(vty
, "Peer : %s\n", peer_str
);
8053 vty_out(vty
, " Local : %s\n", local_str
);
8054 vty_out(vty
, " Mesh Group : %s\n",
8055 mp
->mesh_group_name
);
8056 vty_out(vty
, " State : %s\n", state_str
);
8057 vty_out(vty
, " Uptime : %s\n", timebuf
);
8059 vty_out(vty
, " Keepalive Timer : %s\n", katimer
);
8060 vty_out(vty
, " Conn Retry Timer : %s\n", crtimer
);
8061 vty_out(vty
, " Hold Timer : %s\n", holdtimer
);
8062 vty_out(vty
, " Last Reset : %s\n",
8064 vty_out(vty
, " Conn Attempts : %d\n",
8066 vty_out(vty
, " Established Changes : %d\n",
8068 vty_out(vty
, " SA Count : %d\n",
8070 vty_out(vty
, " Statistics :\n");
8073 vty_out(vty
, " Keepalives : %10d %10d\n",
8074 mp
->ka_tx_cnt
, mp
->ka_rx_cnt
);
8075 vty_out(vty
, " SAs : %10d %10d\n",
8076 mp
->sa_tx_cnt
, mp
->sa_rx_cnt
);
8082 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8083 json
, JSON_C_TO_STRING_PRETTY
));
8084 json_object_free(json
);
8088 DEFUN (show_ip_msdp_peer_detail
,
8089 show_ip_msdp_peer_detail_cmd
,
8090 "show ip msdp [vrf NAME] peer [detail|A.B.C.D] [json]",
8095 "MSDP peer information\n"
8100 u_char uj
= use_json(argc
, argv
);
8102 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
8109 if (argv_find(argv
, argc
, "detail", &idx
))
8110 arg
= argv
[idx
]->text
;
8111 else if (argv_find(argv
, argc
, "A.B.C.D", &idx
))
8112 arg
= argv
[idx
]->arg
;
8115 ip_msdp_show_peers_detail(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
8117 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
8122 DEFUN (show_ip_msdp_peer_detail_vrf_all
,
8123 show_ip_msdp_peer_detail_vrf_all_cmd
,
8124 "show ip msdp vrf all peer [detail|A.B.C.D] [json]",
8129 "MSDP peer information\n"
8135 u_char uj
= use_json(argc
, argv
);
8141 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
8145 vty_out(vty
, " \"%s\": ", vrf
->name
);
8148 vty_out(vty
, "VRF: %s\n", vrf
->name
);
8149 if (argv_find(argv
, argc
, "detail", &idx
)
8150 || argv_find(argv
, argc
, "A.B.C.D", &idx
))
8151 ip_msdp_show_peers_detail(vrf
->info
, vty
,
8152 argv
[idx
]->arg
, uj
);
8154 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
8157 vty_out(vty
, "}\n");
8162 static void ip_msdp_show_sa(struct pim_instance
*pim
, struct vty
*vty
,
8165 struct listnode
*sanode
;
8166 struct pim_msdp_sa
*sa
;
8167 char src_str
[INET_ADDRSTRLEN
];
8168 char grp_str
[INET_ADDRSTRLEN
];
8169 char rp_str
[INET_ADDRSTRLEN
];
8170 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
8174 json_object
*json
= NULL
;
8175 json_object
*json_group
= NULL
;
8176 json_object
*json_row
= NULL
;
8179 json
= json_object_new_object();
8182 "Source Group RP Local SPT Uptime\n");
8185 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
8186 now
= pim_time_monotonic_sec();
8187 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
8188 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
8189 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
8190 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
8191 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
8193 strcpy(spt_str
, "yes");
8195 strcpy(spt_str
, "no");
8198 strcpy(rp_str
, "-");
8199 strcpy(spt_str
, "-");
8201 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
8202 strcpy(local_str
, "yes");
8204 strcpy(local_str
, "no");
8207 json_object_object_get_ex(json
, grp_str
, &json_group
);
8210 json_group
= json_object_new_object();
8211 json_object_object_add(json
, grp_str
,
8215 json_row
= json_object_new_object();
8216 json_object_string_add(json_row
, "source", src_str
);
8217 json_object_string_add(json_row
, "group", grp_str
);
8218 json_object_string_add(json_row
, "rp", rp_str
);
8219 json_object_string_add(json_row
, "local", local_str
);
8220 json_object_string_add(json_row
, "sptSetup", spt_str
);
8221 json_object_string_add(json_row
, "upTime", timebuf
);
8222 json_object_object_add(json_group
, src_str
, json_row
);
8224 vty_out(vty
, "%-15s %15s %15s %5c %3c %8s\n",
8225 src_str
, grp_str
, rp_str
, local_str
[0],
8226 spt_str
[0], timebuf
);
8231 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8232 json
, JSON_C_TO_STRING_PRETTY
));
8233 json_object_free(json
);
8237 static void ip_msdp_show_sa_entry_detail(struct pim_msdp_sa
*sa
,
8238 const char *src_str
,
8239 const char *grp_str
, struct vty
*vty
,
8240 u_char uj
, json_object
*json
)
8242 char rp_str
[INET_ADDRSTRLEN
];
8243 char peer_str
[INET_ADDRSTRLEN
];
8244 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
8247 char statetimer
[PIM_MSDP_TIMER_STRLEN
];
8249 json_object
*json_group
= NULL
;
8250 json_object
*json_row
= NULL
;
8252 now
= pim_time_monotonic_sec();
8253 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
8254 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
8255 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
8256 pim_inet4_dump("<peer?>", sa
->peer
, peer_str
, sizeof(peer_str
));
8258 strcpy(spt_str
, "yes");
8260 strcpy(spt_str
, "no");
8263 strcpy(rp_str
, "-");
8264 strcpy(peer_str
, "-");
8265 strcpy(spt_str
, "-");
8267 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
8268 strcpy(local_str
, "yes");
8270 strcpy(local_str
, "no");
8272 pim_time_timer_to_hhmmss(statetimer
, sizeof(statetimer
),
8273 sa
->sa_state_timer
);
8275 json_object_object_get_ex(json
, grp_str
, &json_group
);
8278 json_group
= json_object_new_object();
8279 json_object_object_add(json
, grp_str
, json_group
);
8282 json_row
= json_object_new_object();
8283 json_object_string_add(json_row
, "source", src_str
);
8284 json_object_string_add(json_row
, "group", grp_str
);
8285 json_object_string_add(json_row
, "rp", rp_str
);
8286 json_object_string_add(json_row
, "local", local_str
);
8287 json_object_string_add(json_row
, "sptSetup", spt_str
);
8288 json_object_string_add(json_row
, "upTime", timebuf
);
8289 json_object_string_add(json_row
, "stateTimer", statetimer
);
8290 json_object_object_add(json_group
, src_str
, json_row
);
8292 vty_out(vty
, "SA : %s\n", sa
->sg_str
);
8293 vty_out(vty
, " RP : %s\n", rp_str
);
8294 vty_out(vty
, " Peer : %s\n", peer_str
);
8295 vty_out(vty
, " Local : %s\n", local_str
);
8296 vty_out(vty
, " SPT Setup : %s\n", spt_str
);
8297 vty_out(vty
, " Uptime : %s\n", timebuf
);
8298 vty_out(vty
, " State Timer : %s\n", statetimer
);
8303 static void ip_msdp_show_sa_detail(struct pim_instance
*pim
, struct vty
*vty
,
8306 struct listnode
*sanode
;
8307 struct pim_msdp_sa
*sa
;
8308 char src_str
[INET_ADDRSTRLEN
];
8309 char grp_str
[INET_ADDRSTRLEN
];
8310 json_object
*json
= NULL
;
8313 json
= json_object_new_object();
8316 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
8317 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
8318 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
8319 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
, uj
,
8324 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8325 json
, JSON_C_TO_STRING_PRETTY
));
8326 json_object_free(json
);
8330 DEFUN (show_ip_msdp_sa_detail
,
8331 show_ip_msdp_sa_detail_cmd
,
8332 "show ip msdp [vrf NAME] sa detail [json]",
8337 "MSDP active-source information\n"
8341 u_char uj
= use_json(argc
, argv
);
8343 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
8348 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
8353 DEFUN (show_ip_msdp_sa_detail_vrf_all
,
8354 show_ip_msdp_sa_detail_vrf_all_cmd
,
8355 "show ip msdp vrf all sa detail [json]",
8360 "MSDP active-source information\n"
8364 u_char uj
= use_json(argc
, argv
);
8370 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
8374 vty_out(vty
, " \"%s\": ", vrf
->name
);
8377 vty_out(vty
, "VRF: %s\n", vrf
->name
);
8378 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
8381 vty_out(vty
, "}\n");
8386 static void ip_msdp_show_sa_addr(struct pim_instance
*pim
, struct vty
*vty
,
8387 const char *addr
, u_char uj
)
8389 struct listnode
*sanode
;
8390 struct pim_msdp_sa
*sa
;
8391 char src_str
[INET_ADDRSTRLEN
];
8392 char grp_str
[INET_ADDRSTRLEN
];
8393 json_object
*json
= NULL
;
8396 json
= json_object_new_object();
8399 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
8400 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
8401 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
8402 if (!strcmp(addr
, src_str
) || !strcmp(addr
, grp_str
)) {
8403 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
8409 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8410 json
, JSON_C_TO_STRING_PRETTY
));
8411 json_object_free(json
);
8415 static void ip_msdp_show_sa_sg(struct pim_instance
*pim
, struct vty
*vty
,
8416 const char *src
, const char *grp
, u_char uj
)
8418 struct listnode
*sanode
;
8419 struct pim_msdp_sa
*sa
;
8420 char src_str
[INET_ADDRSTRLEN
];
8421 char grp_str
[INET_ADDRSTRLEN
];
8422 json_object
*json
= NULL
;
8425 json
= json_object_new_object();
8428 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
8429 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
8430 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
8431 if (!strcmp(src
, src_str
) && !strcmp(grp
, grp_str
)) {
8432 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
8438 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8439 json
, JSON_C_TO_STRING_PRETTY
));
8440 json_object_free(json
);
8444 DEFUN (show_ip_msdp_sa_sg
,
8445 show_ip_msdp_sa_sg_cmd
,
8446 "show ip msdp [vrf NAME] sa [A.B.C.D [A.B.C.D]] [json]",
8451 "MSDP active-source information\n"
8452 "source or group ip\n"
8456 u_char uj
= use_json(argc
, argv
);
8460 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
8465 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
8467 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
8471 if (src_ip
&& grp_ip
)
8472 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
8474 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
8476 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
8481 DEFUN (show_ip_msdp_sa_sg_vrf_all
,
8482 show_ip_msdp_sa_sg_vrf_all_cmd
,
8483 "show ip msdp vrf all sa [A.B.C.D [A.B.C.D]] [json]",
8488 "MSDP active-source information\n"
8489 "source or group ip\n"
8493 u_char uj
= use_json(argc
, argv
);
8498 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
8500 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
8506 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
8510 vty_out(vty
, " \"%s\": ", vrf
->name
);
8513 vty_out(vty
, "VRF: %s\n", vrf
->name
);
8515 if (src_ip
&& grp_ip
)
8516 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
8518 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
8520 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
8523 vty_out(vty
, "}\n");
8529 void pim_cmd_init(void)
8531 install_node(&pim_global_node
, pim_global_config_write
); /* PIM_NODE */
8532 install_node(&interface_node
,
8533 pim_interface_config_write
); /* INTERFACE_NODE */
8536 install_node(&debug_node
, pim_debug_config_write
);
8538 install_element(CONFIG_NODE
, &ip_multicast_routing_cmd
);
8539 install_element(CONFIG_NODE
, &no_ip_multicast_routing_cmd
);
8540 install_element(CONFIG_NODE
, &ip_pim_rp_cmd
);
8541 install_element(VRF_NODE
, &ip_pim_rp_cmd
);
8542 install_element(CONFIG_NODE
, &no_ip_pim_rp_cmd
);
8543 install_element(VRF_NODE
, &no_ip_pim_rp_cmd
);
8544 install_element(CONFIG_NODE
, &ip_pim_rp_prefix_list_cmd
);
8545 install_element(VRF_NODE
, &ip_pim_rp_prefix_list_cmd
);
8546 install_element(CONFIG_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
8547 install_element(VRF_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
8548 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
8549 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
8550 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
8551 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
8552 install_element(CONFIG_NODE
, &ip_pim_ssm_prefix_list_cmd
);
8553 install_element(VRF_NODE
, &ip_pim_ssm_prefix_list_cmd
);
8554 install_element(CONFIG_NODE
, &ip_pim_register_suppress_cmd
);
8555 install_element(VRF_NODE
, &ip_pim_register_suppress_cmd
);
8556 install_element(CONFIG_NODE
, &no_ip_pim_register_suppress_cmd
);
8557 install_element(VRF_NODE
, &no_ip_pim_register_suppress_cmd
);
8558 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
8559 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
8560 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
8561 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
8562 install_element(CONFIG_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
8563 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
8564 install_element(CONFIG_NODE
,
8565 &no_ip_pim_spt_switchover_infinity_plist_cmd
);
8566 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_plist_cmd
);
8567 install_element(CONFIG_NODE
, &ip_pim_joinprune_time_cmd
);
8568 install_element(VRF_NODE
, &ip_pim_joinprune_time_cmd
);
8569 install_element(CONFIG_NODE
, &no_ip_pim_joinprune_time_cmd
);
8570 install_element(VRF_NODE
, &no_ip_pim_joinprune_time_cmd
);
8571 install_element(CONFIG_NODE
, &ip_pim_keep_alive_cmd
);
8572 install_element(VRF_NODE
, &ip_pim_keep_alive_cmd
);
8573 install_element(CONFIG_NODE
, &ip_pim_rp_keep_alive_cmd
);
8574 install_element(VRF_NODE
, &ip_pim_rp_keep_alive_cmd
);
8575 install_element(CONFIG_NODE
, &no_ip_pim_keep_alive_cmd
);
8576 install_element(VRF_NODE
, &no_ip_pim_keep_alive_cmd
);
8577 install_element(CONFIG_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
8578 install_element(VRF_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
8579 install_element(CONFIG_NODE
, &ip_pim_packets_cmd
);
8580 install_element(VRF_NODE
, &ip_pim_packets_cmd
);
8581 install_element(CONFIG_NODE
, &no_ip_pim_packets_cmd
);
8582 install_element(VRF_NODE
, &no_ip_pim_packets_cmd
);
8583 install_element(CONFIG_NODE
, &ip_pim_v6_secondary_cmd
);
8584 install_element(VRF_NODE
, &ip_pim_v6_secondary_cmd
);
8585 install_element(CONFIG_NODE
, &no_ip_pim_v6_secondary_cmd
);
8586 install_element(VRF_NODE
, &no_ip_pim_v6_secondary_cmd
);
8587 install_element(CONFIG_NODE
, &ip_ssmpingd_cmd
);
8588 install_element(VRF_NODE
, &ip_ssmpingd_cmd
);
8589 install_element(CONFIG_NODE
, &no_ip_ssmpingd_cmd
);
8590 install_element(VRF_NODE
, &no_ip_ssmpingd_cmd
);
8591 install_element(CONFIG_NODE
, &ip_msdp_peer_cmd
);
8592 install_element(VRF_NODE
, &ip_msdp_peer_cmd
);
8593 install_element(CONFIG_NODE
, &no_ip_msdp_peer_cmd
);
8594 install_element(VRF_NODE
, &no_ip_msdp_peer_cmd
);
8595 install_element(CONFIG_NODE
, &ip_pim_ecmp_cmd
);
8596 install_element(VRF_NODE
, &ip_pim_ecmp_cmd
);
8597 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_cmd
);
8598 install_element(VRF_NODE
, &no_ip_pim_ecmp_cmd
);
8599 install_element(CONFIG_NODE
, &ip_pim_ecmp_rebalance_cmd
);
8600 install_element(VRF_NODE
, &ip_pim_ecmp_rebalance_cmd
);
8601 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
8602 install_element(VRF_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
8604 install_element(INTERFACE_NODE
, &interface_ip_igmp_cmd
);
8605 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_cmd
);
8606 install_element(INTERFACE_NODE
, &interface_ip_igmp_join_cmd
);
8607 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_join_cmd
);
8608 install_element(INTERFACE_NODE
, &interface_ip_igmp_version_cmd
);
8609 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_version_cmd
);
8610 install_element(INTERFACE_NODE
, &interface_ip_igmp_query_interval_cmd
);
8611 install_element(INTERFACE_NODE
,
8612 &interface_no_ip_igmp_query_interval_cmd
);
8613 install_element(INTERFACE_NODE
,
8614 &interface_ip_igmp_query_max_response_time_cmd
);
8615 install_element(INTERFACE_NODE
,
8616 &interface_no_ip_igmp_query_max_response_time_cmd
);
8617 install_element(INTERFACE_NODE
,
8618 &interface_ip_igmp_query_max_response_time_dsec_cmd
);
8619 install_element(INTERFACE_NODE
,
8620 &interface_no_ip_igmp_query_max_response_time_dsec_cmd
);
8621 install_element(INTERFACE_NODE
, &interface_ip_pim_ssm_cmd
);
8622 install_element(INTERFACE_NODE
, &interface_no_ip_pim_ssm_cmd
);
8623 install_element(INTERFACE_NODE
, &interface_ip_pim_sm_cmd
);
8624 install_element(INTERFACE_NODE
, &interface_no_ip_pim_sm_cmd
);
8625 install_element(INTERFACE_NODE
, &interface_ip_pim_drprio_cmd
);
8626 install_element(INTERFACE_NODE
, &interface_no_ip_pim_drprio_cmd
);
8627 install_element(INTERFACE_NODE
, &interface_ip_pim_hello_cmd
);
8628 install_element(INTERFACE_NODE
, &interface_no_ip_pim_hello_cmd
);
8629 install_element(INTERFACE_NODE
, &interface_ip_pim_boundary_oil_cmd
);
8630 install_element(INTERFACE_NODE
, &interface_no_ip_pim_boundary_oil_cmd
);
8632 // Static mroutes NEB
8633 install_element(INTERFACE_NODE
, &interface_ip_mroute_cmd
);
8634 install_element(INTERFACE_NODE
, &interface_ip_mroute_source_cmd
);
8635 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_cmd
);
8636 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_source_cmd
);
8638 install_element(VIEW_NODE
, &show_ip_igmp_interface_cmd
);
8639 install_element(VIEW_NODE
, &show_ip_igmp_interface_vrf_all_cmd
);
8640 install_element(VIEW_NODE
, &show_ip_igmp_join_cmd
);
8641 install_element(VIEW_NODE
, &show_ip_igmp_join_vrf_all_cmd
);
8642 install_element(VIEW_NODE
, &show_ip_igmp_groups_cmd
);
8643 install_element(VIEW_NODE
, &show_ip_igmp_groups_vrf_all_cmd
);
8644 install_element(VIEW_NODE
, &show_ip_igmp_groups_retransmissions_cmd
);
8645 install_element(VIEW_NODE
, &show_ip_igmp_sources_cmd
);
8646 install_element(VIEW_NODE
, &show_ip_igmp_sources_retransmissions_cmd
);
8647 install_element(VIEW_NODE
, &show_ip_pim_assert_cmd
);
8648 install_element(VIEW_NODE
, &show_ip_pim_assert_internal_cmd
);
8649 install_element(VIEW_NODE
, &show_ip_pim_assert_metric_cmd
);
8650 install_element(VIEW_NODE
, &show_ip_pim_assert_winner_metric_cmd
);
8651 install_element(VIEW_NODE
, &show_ip_pim_interface_traffic_cmd
);
8652 install_element(VIEW_NODE
, &show_ip_pim_interface_cmd
);
8653 install_element(VIEW_NODE
, &show_ip_pim_interface_vrf_all_cmd
);
8654 install_element(VIEW_NODE
, &show_ip_pim_join_cmd
);
8655 install_element(VIEW_NODE
, &show_ip_pim_join_vrf_all_cmd
);
8656 install_element(VIEW_NODE
, &show_ip_pim_local_membership_cmd
);
8657 install_element(VIEW_NODE
, &show_ip_pim_neighbor_cmd
);
8658 install_element(VIEW_NODE
, &show_ip_pim_neighbor_vrf_all_cmd
);
8659 install_element(VIEW_NODE
, &show_ip_pim_rpf_cmd
);
8660 install_element(VIEW_NODE
, &show_ip_pim_rpf_vrf_all_cmd
);
8661 install_element(VIEW_NODE
, &show_ip_pim_secondary_cmd
);
8662 install_element(VIEW_NODE
, &show_ip_pim_state_cmd
);
8663 install_element(VIEW_NODE
, &show_ip_pim_state_vrf_all_cmd
);
8664 install_element(VIEW_NODE
, &show_ip_pim_upstream_cmd
);
8665 install_element(VIEW_NODE
, &show_ip_pim_upstream_vrf_all_cmd
);
8666 install_element(VIEW_NODE
, &show_ip_pim_upstream_join_desired_cmd
);
8667 install_element(VIEW_NODE
, &show_ip_pim_upstream_rpf_cmd
);
8668 install_element(VIEW_NODE
, &show_ip_pim_rp_cmd
);
8669 install_element(VIEW_NODE
, &show_ip_pim_rp_vrf_all_cmd
);
8670 install_element(VIEW_NODE
, &show_ip_multicast_cmd
);
8671 install_element(VIEW_NODE
, &show_ip_multicast_vrf_all_cmd
);
8672 install_element(VIEW_NODE
, &show_ip_mroute_cmd
);
8673 install_element(VIEW_NODE
, &show_ip_mroute_vrf_all_cmd
);
8674 install_element(VIEW_NODE
, &show_ip_mroute_count_cmd
);
8675 install_element(VIEW_NODE
, &show_ip_mroute_count_vrf_all_cmd
);
8676 install_element(VIEW_NODE
, &show_ip_rib_cmd
);
8677 install_element(VIEW_NODE
, &show_ip_ssmpingd_cmd
);
8678 install_element(VIEW_NODE
, &show_debugging_pim_cmd
);
8679 install_element(VIEW_NODE
, &show_ip_pim_nexthop_cmd
);
8680 install_element(VIEW_NODE
, &show_ip_pim_nexthop_lookup_cmd
);
8682 install_element(ENABLE_NODE
, &clear_ip_interfaces_cmd
);
8683 install_element(ENABLE_NODE
, &clear_ip_igmp_interfaces_cmd
);
8684 install_element(ENABLE_NODE
, &clear_ip_mroute_cmd
);
8685 install_element(ENABLE_NODE
, &clear_ip_pim_interfaces_cmd
);
8686 install_element(ENABLE_NODE
, &clear_ip_pim_interface_traffic_cmd
);
8687 install_element(ENABLE_NODE
, &clear_ip_pim_oil_cmd
);
8689 install_element(ENABLE_NODE
, &debug_igmp_cmd
);
8690 install_element(ENABLE_NODE
, &no_debug_igmp_cmd
);
8691 install_element(ENABLE_NODE
, &debug_igmp_events_cmd
);
8692 install_element(ENABLE_NODE
, &no_debug_igmp_events_cmd
);
8693 install_element(ENABLE_NODE
, &debug_igmp_packets_cmd
);
8694 install_element(ENABLE_NODE
, &no_debug_igmp_packets_cmd
);
8695 install_element(ENABLE_NODE
, &debug_igmp_trace_cmd
);
8696 install_element(ENABLE_NODE
, &no_debug_igmp_trace_cmd
);
8697 install_element(ENABLE_NODE
, &debug_mroute_cmd
);
8698 install_element(ENABLE_NODE
, &debug_mroute_detail_cmd
);
8699 install_element(ENABLE_NODE
, &no_debug_mroute_cmd
);
8700 install_element(ENABLE_NODE
, &no_debug_mroute_detail_cmd
);
8701 install_element(ENABLE_NODE
, &debug_static_cmd
);
8702 install_element(ENABLE_NODE
, &no_debug_static_cmd
);
8703 install_element(ENABLE_NODE
, &debug_pim_cmd
);
8704 install_element(ENABLE_NODE
, &no_debug_pim_cmd
);
8705 install_element(ENABLE_NODE
, &debug_pim_nht_cmd
);
8706 install_element(ENABLE_NODE
, &no_debug_pim_nht_cmd
);
8707 install_element(ENABLE_NODE
, &debug_pim_nht_rp_cmd
);
8708 install_element(ENABLE_NODE
, &no_debug_pim_nht_rp_cmd
);
8709 install_element(ENABLE_NODE
, &debug_pim_events_cmd
);
8710 install_element(ENABLE_NODE
, &no_debug_pim_events_cmd
);
8711 install_element(ENABLE_NODE
, &debug_pim_packets_cmd
);
8712 install_element(ENABLE_NODE
, &no_debug_pim_packets_cmd
);
8713 install_element(ENABLE_NODE
, &debug_pim_packetdump_send_cmd
);
8714 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_send_cmd
);
8715 install_element(ENABLE_NODE
, &debug_pim_packetdump_recv_cmd
);
8716 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_recv_cmd
);
8717 install_element(ENABLE_NODE
, &debug_pim_trace_cmd
);
8718 install_element(ENABLE_NODE
, &no_debug_pim_trace_cmd
);
8719 install_element(ENABLE_NODE
, &debug_pim_trace_detail_cmd
);
8720 install_element(ENABLE_NODE
, &no_debug_pim_trace_detail_cmd
);
8721 install_element(ENABLE_NODE
, &debug_ssmpingd_cmd
);
8722 install_element(ENABLE_NODE
, &no_debug_ssmpingd_cmd
);
8723 install_element(ENABLE_NODE
, &debug_pim_zebra_cmd
);
8724 install_element(ENABLE_NODE
, &no_debug_pim_zebra_cmd
);
8725 install_element(ENABLE_NODE
, &debug_msdp_cmd
);
8726 install_element(ENABLE_NODE
, &no_debug_msdp_cmd
);
8727 install_element(ENABLE_NODE
, &undebug_msdp_cmd
);
8728 install_element(ENABLE_NODE
, &debug_msdp_events_cmd
);
8729 install_element(ENABLE_NODE
, &no_debug_msdp_events_cmd
);
8730 install_element(ENABLE_NODE
, &undebug_msdp_events_cmd
);
8731 install_element(ENABLE_NODE
, &debug_msdp_packets_cmd
);
8732 install_element(ENABLE_NODE
, &no_debug_msdp_packets_cmd
);
8733 install_element(ENABLE_NODE
, &undebug_msdp_packets_cmd
);
8735 install_element(CONFIG_NODE
, &debug_igmp_cmd
);
8736 install_element(CONFIG_NODE
, &no_debug_igmp_cmd
);
8737 install_element(CONFIG_NODE
, &debug_igmp_events_cmd
);
8738 install_element(CONFIG_NODE
, &no_debug_igmp_events_cmd
);
8739 install_element(CONFIG_NODE
, &debug_igmp_packets_cmd
);
8740 install_element(CONFIG_NODE
, &no_debug_igmp_packets_cmd
);
8741 install_element(CONFIG_NODE
, &debug_igmp_trace_cmd
);
8742 install_element(CONFIG_NODE
, &no_debug_igmp_trace_cmd
);
8743 install_element(CONFIG_NODE
, &debug_mroute_cmd
);
8744 install_element(CONFIG_NODE
, &debug_mroute_detail_cmd
);
8745 install_element(CONFIG_NODE
, &no_debug_mroute_cmd
);
8746 install_element(CONFIG_NODE
, &no_debug_mroute_detail_cmd
);
8747 install_element(CONFIG_NODE
, &debug_static_cmd
);
8748 install_element(CONFIG_NODE
, &no_debug_static_cmd
);
8749 install_element(CONFIG_NODE
, &debug_pim_cmd
);
8750 install_element(CONFIG_NODE
, &no_debug_pim_cmd
);
8751 install_element(CONFIG_NODE
, &debug_pim_nht_cmd
);
8752 install_element(CONFIG_NODE
, &no_debug_pim_nht_cmd
);
8753 install_element(CONFIG_NODE
, &debug_pim_nht_rp_cmd
);
8754 install_element(CONFIG_NODE
, &no_debug_pim_nht_rp_cmd
);
8755 install_element(CONFIG_NODE
, &debug_pim_events_cmd
);
8756 install_element(CONFIG_NODE
, &no_debug_pim_events_cmd
);
8757 install_element(CONFIG_NODE
, &debug_pim_packets_cmd
);
8758 install_element(CONFIG_NODE
, &no_debug_pim_packets_cmd
);
8759 install_element(CONFIG_NODE
, &debug_pim_trace_cmd
);
8760 install_element(CONFIG_NODE
, &no_debug_pim_trace_cmd
);
8761 install_element(CONFIG_NODE
, &debug_pim_trace_detail_cmd
);
8762 install_element(CONFIG_NODE
, &no_debug_pim_trace_detail_cmd
);
8763 install_element(CONFIG_NODE
, &debug_ssmpingd_cmd
);
8764 install_element(CONFIG_NODE
, &no_debug_ssmpingd_cmd
);
8765 install_element(CONFIG_NODE
, &debug_pim_zebra_cmd
);
8766 install_element(CONFIG_NODE
, &no_debug_pim_zebra_cmd
);
8767 install_element(CONFIG_NODE
, &debug_msdp_cmd
);
8768 install_element(CONFIG_NODE
, &no_debug_msdp_cmd
);
8769 install_element(CONFIG_NODE
, &undebug_msdp_cmd
);
8770 install_element(CONFIG_NODE
, &debug_msdp_events_cmd
);
8771 install_element(CONFIG_NODE
, &no_debug_msdp_events_cmd
);
8772 install_element(CONFIG_NODE
, &undebug_msdp_events_cmd
);
8773 install_element(CONFIG_NODE
, &debug_msdp_packets_cmd
);
8774 install_element(CONFIG_NODE
, &no_debug_msdp_packets_cmd
);
8775 install_element(CONFIG_NODE
, &undebug_msdp_packets_cmd
);
8777 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_member_cmd
);
8778 install_element(VRF_NODE
, &ip_msdp_mesh_group_member_cmd
);
8779 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
8780 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
8781 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_source_cmd
);
8782 install_element(VRF_NODE
, &ip_msdp_mesh_group_source_cmd
);
8783 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
8784 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
8785 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_cmd
);
8786 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_vrf_all_cmd
);
8787 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_cmd
);
8788 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_vrf_all_cmd
);
8789 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_cmd
);
8790 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_vrf_all_cmd
);
8791 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_cmd
);
8792 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_vrf_all_cmd
);
8793 install_element(VIEW_NODE
, &show_ip_pim_ssm_range_cmd
);
8794 install_element(VIEW_NODE
, &show_ip_pim_group_type_cmd
);
8795 install_element(INTERFACE_NODE
, &interface_pim_use_source_cmd
);
8796 install_element(INTERFACE_NODE
, &interface_no_pim_use_source_cmd
);
8797 /* Install BFD command */
8798 install_element(INTERFACE_NODE
, &ip_pim_bfd_cmd
);
8799 install_element(INTERFACE_NODE
, &ip_pim_bfd_param_cmd
);
8800 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_cmd
);
8801 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_param_cmd
);