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
, u_char uj
)
4456 struct listnode
*node
;
4457 struct channel_oil
*c_oil
;
4458 struct static_route
*s_route
;
4460 json_object
*json
= NULL
;
4461 json_object
*json_group
= NULL
;
4462 json_object
*json_source
= NULL
;
4463 json_object
*json_oil
= NULL
;
4464 json_object
*json_ifp_out
= NULL
;
4467 char grp_str
[INET_ADDRSTRLEN
];
4468 char src_str
[INET_ADDRSTRLEN
];
4469 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
4470 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
4472 struct interface
*ifp_in
;
4476 json
= json_object_new_object();
4479 "Source Group Proto Input Output TTL Uptime\n");
4482 now
= pim_time_monotonic_sec();
4484 /* print list of PIM and IGMP routes */
4485 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
4488 if (!c_oil
->installed
&& !uj
)
4491 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
4493 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
4495 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
4498 strcpy(in_ifname
, ifp_in
->name
);
4500 strcpy(in_ifname
, "<iif?>");
4504 /* Find the group, create it if it doesn't exist */
4505 json_object_object_get_ex(json
, grp_str
, &json_group
);
4508 json_group
= json_object_new_object();
4509 json_object_object_add(json
, grp_str
,
4513 /* Find the source nested under the group, create it if
4514 * it doesn't exist */
4515 json_object_object_get_ex(json_group
, src_str
,
4519 json_source
= json_object_new_object();
4520 json_object_object_add(json_group
, src_str
,
4524 /* Find the inbound interface nested under the source,
4525 * create it if it doesn't exist */
4526 json_object_int_add(json_source
, "installed",
4528 json_object_int_add(json_source
, "refCount",
4529 c_oil
->oil_ref_count
);
4530 json_object_int_add(json_source
, "oilSize",
4532 json_object_int_add(json_source
, "OilInheritedRescan",
4533 c_oil
->oil_inherited_rescan
);
4534 json_object_string_add(json_source
, "iif", in_ifname
);
4538 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
4540 struct interface
*ifp_out
;
4541 char oif_uptime
[10];
4544 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
4548 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
4550 oif_uptime
, sizeof(oif_uptime
),
4551 now
- c_oil
->oif_creation
[oif_vif_index
]);
4555 strcpy(out_ifname
, ifp_out
->name
);
4557 strcpy(out_ifname
, "<oif?>");
4560 json_ifp_out
= json_object_new_object();
4561 json_object_string_add(json_ifp_out
, "source",
4563 json_object_string_add(json_ifp_out
, "group",
4566 if (c_oil
->oif_flags
[oif_vif_index
]
4567 & PIM_OIF_FLAG_PROTO_PIM
)
4568 json_object_boolean_true_add(
4569 json_ifp_out
, "protocolPim");
4571 if (c_oil
->oif_flags
[oif_vif_index
]
4572 & PIM_OIF_FLAG_PROTO_IGMP
)
4573 json_object_boolean_true_add(
4574 json_ifp_out
, "protocolIgmp");
4576 if (c_oil
->oif_flags
[oif_vif_index
]
4577 & PIM_OIF_FLAG_PROTO_SOURCE
)
4578 json_object_boolean_true_add(
4579 json_ifp_out
, "protocolSource");
4581 if (c_oil
->oif_flags
[oif_vif_index
]
4582 & PIM_OIF_FLAG_PROTO_STAR
)
4583 json_object_boolean_true_add(
4585 "protocolInherited");
4587 json_object_string_add(json_ifp_out
,
4590 json_object_int_add(json_ifp_out
, "iVifI",
4591 c_oil
->oil
.mfcc_parent
);
4592 json_object_string_add(json_ifp_out
,
4593 "outboundInterface",
4595 json_object_int_add(json_ifp_out
, "oVifI",
4597 json_object_int_add(json_ifp_out
, "ttl", ttl
);
4598 json_object_string_add(json_ifp_out
, "upTime",
4601 json_oil
= json_object_new_object();
4602 json_object_object_add(json_source
,
4605 json_object_object_add(json_oil
, out_ifname
,
4608 if (c_oil
->oif_flags
[oif_vif_index
]
4609 & PIM_OIF_FLAG_PROTO_PIM
) {
4610 strcpy(proto
, "PIM");
4613 if (c_oil
->oif_flags
[oif_vif_index
]
4614 & PIM_OIF_FLAG_PROTO_IGMP
) {
4615 strcpy(proto
, "IGMP");
4618 if (c_oil
->oif_flags
[oif_vif_index
]
4619 & PIM_OIF_FLAG_PROTO_SOURCE
) {
4620 strcpy(proto
, "SRC");
4623 if (c_oil
->oif_flags
[oif_vif_index
]
4624 & PIM_OIF_FLAG_PROTO_STAR
) {
4625 strcpy(proto
, "STAR");
4629 "%-15s %-15s %-6s %-10s %-10s %-3d %8s\n",
4630 src_str
, grp_str
, proto
, in_ifname
,
4631 out_ifname
, ttl
, oif_uptime
);
4636 in_ifname
[0] = '\0';
4642 if (!uj
&& !found_oif
) {
4643 vty_out(vty
, "%-15s %-15s %-6s %-10s %-10s %-3d %8s\n",
4644 src_str
, grp_str
, "none", in_ifname
, "none", 0,
4649 /* Print list of static routes */
4650 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
4653 if (!s_route
->c_oil
.installed
)
4656 pim_inet4_dump("<group?>", s_route
->group
, grp_str
,
4658 pim_inet4_dump("<source?>", s_route
->source
, src_str
,
4660 ifp_in
= pim_if_find_by_vif_index(pim
, s_route
->iif
);
4664 strcpy(in_ifname
, ifp_in
->name
);
4666 strcpy(in_ifname
, "<iif?>");
4670 /* Find the group, create it if it doesn't exist */
4671 json_object_object_get_ex(json
, grp_str
, &json_group
);
4674 json_group
= json_object_new_object();
4675 json_object_object_add(json
, grp_str
,
4679 /* Find the source nested under the group, create it if
4680 * it doesn't exist */
4681 json_object_object_get_ex(json_group
, src_str
,
4685 json_source
= json_object_new_object();
4686 json_object_object_add(json_group
, src_str
,
4690 json_object_string_add(json_source
, "iif", in_ifname
);
4693 strcpy(proto
, "STATIC");
4696 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
4698 struct interface
*ifp_out
;
4699 char oif_uptime
[10];
4702 ttl
= s_route
->oif_ttls
[oif_vif_index
];
4706 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
4708 oif_uptime
, sizeof(oif_uptime
),
4711 .oif_creation
[oif_vif_index
]);
4715 strcpy(out_ifname
, ifp_out
->name
);
4717 strcpy(out_ifname
, "<oif?>");
4720 json_ifp_out
= json_object_new_object();
4721 json_object_string_add(json_ifp_out
, "source",
4723 json_object_string_add(json_ifp_out
, "group",
4725 json_object_boolean_true_add(json_ifp_out
,
4727 json_object_string_add(json_ifp_out
,
4730 json_object_int_add(
4731 json_ifp_out
, "iVifI",
4732 s_route
->c_oil
.oil
.mfcc_parent
);
4733 json_object_string_add(json_ifp_out
,
4734 "outboundInterface",
4736 json_object_int_add(json_ifp_out
, "oVifI",
4738 json_object_int_add(json_ifp_out
, "ttl", ttl
);
4739 json_object_string_add(json_ifp_out
, "upTime",
4742 json_oil
= json_object_new_object();
4743 json_object_object_add(json_source
,
4746 json_object_object_add(json_oil
, out_ifname
,
4750 "%-15s %-15s %-6s %-10s %-10s %-3d %8s %s\n",
4751 src_str
, grp_str
, proto
, in_ifname
,
4752 out_ifname
, ttl
, oif_uptime
,
4757 in_ifname
[0] = '\0';
4763 if (!uj
&& !found_oif
) {
4765 "%-15s %-15s %-6s %-10s %-10s %-3d %8s %s\n",
4766 src_str
, grp_str
, proto
, in_ifname
, "none", 0,
4767 "--:--:--", pim
->vrf
->name
);
4772 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4773 json
, JSON_C_TO_STRING_PRETTY
));
4774 json_object_free(json
);
4778 DEFUN (show_ip_mroute
,
4780 "show ip mroute [vrf NAME] [json]",
4787 u_char uj
= use_json(argc
, argv
);
4789 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4794 show_mroute(vrf
->info
, vty
, uj
);
4798 DEFUN (show_ip_mroute_vrf_all
,
4799 show_ip_mroute_vrf_all_cmd
,
4800 "show ip mroute vrf all [json]",
4807 u_char uj
= use_json(argc
, argv
);
4813 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4817 vty_out(vty
, " \"%s\": ", vrf
->name
);
4820 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4821 show_mroute(vrf
->info
, vty
, uj
);
4824 vty_out(vty
, "}\n");
4829 static void show_mroute_count(struct pim_instance
*pim
, struct vty
*vty
)
4831 struct listnode
*node
;
4832 struct channel_oil
*c_oil
;
4833 struct static_route
*s_route
;
4838 "Source Group LastUsed Packets Bytes WrongIf \n");
4840 /* Print PIM and IGMP route counts */
4841 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
4842 char group_str
[INET_ADDRSTRLEN
];
4843 char source_str
[INET_ADDRSTRLEN
];
4845 if (!c_oil
->installed
)
4848 pim_mroute_update_counters(c_oil
);
4850 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, group_str
,
4852 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, source_str
,
4853 sizeof(source_str
));
4855 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
4856 source_str
, group_str
, c_oil
->cc
.lastused
/ 100,
4857 c_oil
->cc
.pktcnt
, c_oil
->cc
.bytecnt
,
4858 c_oil
->cc
.wrong_if
);
4861 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
4862 char group_str
[INET_ADDRSTRLEN
];
4863 char source_str
[INET_ADDRSTRLEN
];
4865 if (!s_route
->c_oil
.installed
)
4868 pim_mroute_update_counters(&s_route
->c_oil
);
4870 pim_inet4_dump("<group?>", s_route
->c_oil
.oil
.mfcc_mcastgrp
,
4871 group_str
, sizeof(group_str
));
4872 pim_inet4_dump("<source?>", s_route
->c_oil
.oil
.mfcc_origin
,
4873 source_str
, sizeof(source_str
));
4875 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
4876 source_str
, group_str
, s_route
->c_oil
.cc
.lastused
,
4877 s_route
->c_oil
.cc
.pktcnt
, s_route
->c_oil
.cc
.bytecnt
,
4878 s_route
->c_oil
.cc
.wrong_if
);
4882 DEFUN (show_ip_mroute_count
,
4883 show_ip_mroute_count_cmd
,
4884 "show ip mroute [vrf NAME] count",
4889 "Route and packet count data\n")
4892 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4897 show_mroute_count(vrf
->info
, vty
);
4901 DEFUN (show_ip_mroute_count_vrf_all
,
4902 show_ip_mroute_count_vrf_all_cmd
,
4903 "show ip mroute vrf all count",
4908 "Route and packet count data\n")
4910 u_char uj
= use_json(argc
, argv
);
4916 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4920 vty_out(vty
, " \"%s\": ", vrf
->name
);
4923 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4924 show_mroute_count(vrf
->info
, vty
);
4927 vty_out(vty
, "}\n");
4934 "show ip rib [vrf NAME] A.B.C.D",
4939 "Unicast address\n")
4942 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4943 struct in_addr addr
;
4944 const char *addr_str
;
4945 struct pim_nexthop nexthop
;
4946 char nexthop_addr_str
[PREFIX_STRLEN
];
4952 memset(&nexthop
, 0, sizeof(nexthop
));
4953 argv_find(argv
, argc
, "A.B.C.D", &idx
);
4954 addr_str
= argv
[idx
]->arg
;
4955 result
= inet_pton(AF_INET
, addr_str
, &addr
);
4957 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
4958 errno
, safe_strerror(errno
));
4962 if (pim_nexthop_lookup(vrf
->info
, &nexthop
, addr
, 0)) {
4964 "Failure querying RIB nexthop for unicast address %s\n",
4970 "Address NextHop Interface Metric Preference\n");
4972 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
4973 nexthop_addr_str
, sizeof(nexthop_addr_str
));
4975 vty_out(vty
, "%-15s %-15s %-9s %6d %10d\n", addr_str
, nexthop_addr_str
,
4976 nexthop
.interface
? nexthop
.interface
->name
: "<ifname?>",
4977 nexthop
.mrib_route_metric
, nexthop
.mrib_metric_preference
);
4982 static void show_ssmpingd(struct pim_instance
*pim
, struct vty
*vty
)
4984 struct listnode
*node
;
4985 struct ssmpingd_sock
*ss
;
4989 "Source Socket Address Port Uptime Requests\n");
4991 if (!pim
->ssmpingd_list
)
4994 now
= pim_time_monotonic_sec();
4996 for (ALL_LIST_ELEMENTS_RO(pim
->ssmpingd_list
, node
, ss
)) {
4997 char source_str
[INET_ADDRSTRLEN
];
4999 struct sockaddr_in bind_addr
;
5000 socklen_t len
= sizeof(bind_addr
);
5001 char bind_addr_str
[INET_ADDRSTRLEN
];
5003 pim_inet4_dump("<src?>", ss
->source_addr
, source_str
,
5004 sizeof(source_str
));
5006 if (pim_socket_getsockname(
5007 ss
->sock_fd
, (struct sockaddr
*)&bind_addr
, &len
)) {
5009 "%% Failure reading socket name for ssmpingd source %s on fd=%d\n",
5010 source_str
, ss
->sock_fd
);
5013 pim_inet4_dump("<addr?>", bind_addr
.sin_addr
, bind_addr_str
,
5014 sizeof(bind_addr_str
));
5015 pim_time_uptime(ss_uptime
, sizeof(ss_uptime
),
5016 now
- ss
->creation
);
5018 vty_out(vty
, "%-15s %6d %-15s %5d %8s %8lld\n", source_str
,
5019 ss
->sock_fd
, bind_addr_str
, ntohs(bind_addr
.sin_port
),
5020 ss_uptime
, (long long)ss
->requests
);
5024 DEFUN (show_ip_ssmpingd
,
5025 show_ip_ssmpingd_cmd
,
5026 "show ip ssmpingd [vrf NAME]",
5033 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5038 show_ssmpingd(vrf
->info
, vty
);
5042 static int pim_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
5043 const char *rp
, const char *group
,
5048 result
= pim_rp_new(pim
, rp
, group
, plist
);
5050 if (result
== PIM_MALLOC_FAIL
) {
5051 vty_out(vty
, "%% Out of memory\n");
5052 return CMD_WARNING_CONFIG_FAILED
;
5055 if (result
== PIM_GROUP_BAD_ADDRESS
) {
5056 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
5057 return CMD_WARNING_CONFIG_FAILED
;
5060 if (result
== PIM_RP_BAD_ADDRESS
) {
5061 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
5062 return CMD_WARNING_CONFIG_FAILED
;
5065 if (result
== PIM_RP_NO_PATH
) {
5066 vty_out(vty
, "%% No Path to RP address specified: %s\n", rp
);
5070 if (result
== PIM_GROUP_OVERLAP
) {
5071 vty_out(vty
, "%% Group range specified cannot exact match another\n");
5072 return CMD_WARNING_CONFIG_FAILED
;
5075 if (result
== PIM_GROUP_PFXLIST_OVERLAP
) {
5077 "%% This group is already covered by a RP prefix-list\n");
5078 return CMD_WARNING_CONFIG_FAILED
;
5081 if (result
== PIM_RP_PFXLIST_IN_USE
) {
5083 "%% The same prefix-list cannot be applied to multiple RPs\n");
5084 return CMD_WARNING_CONFIG_FAILED
;
5090 static int pim_cmd_spt_switchover(struct pim_instance
*pim
,
5091 enum pim_spt_switchover spt
,
5094 pim
->spt
.switchover
= spt
;
5096 switch (pim
->spt
.switchover
) {
5097 case PIM_SPT_IMMEDIATE
:
5099 XFREE(MTYPE_PIM_SPT_PLIST_NAME
, pim
->spt
.plist
);
5101 pim_upstream_add_lhr_star_pimreg(pim
);
5103 case PIM_SPT_INFINITY
:
5104 pim_upstream_remove_lhr_star_pimreg(pim
, plist
);
5107 XFREE(MTYPE_PIM_SPT_PLIST_NAME
, pim
->spt
.plist
);
5111 XSTRDUP(MTYPE_PIM_SPT_PLIST_NAME
, plist
);
5118 DEFUN (ip_pim_spt_switchover_infinity
,
5119 ip_pim_spt_switchover_infinity_cmd
,
5120 "ip pim spt-switchover infinity-and-beyond",
5124 "Never switch to SPT Tree\n")
5126 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5127 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, NULL
);
5130 DEFUN (ip_pim_spt_switchover_infinity_plist
,
5131 ip_pim_spt_switchover_infinity_plist_cmd
,
5132 "ip pim spt-switchover infinity-and-beyond prefix-list WORD",
5136 "Never switch to SPT Tree\n"
5137 "Prefix-List to control which groups to switch\n"
5138 "Prefix-List name\n")
5140 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5141 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, argv
[5]->arg
);
5144 DEFUN (no_ip_pim_spt_switchover_infinity
,
5145 no_ip_pim_spt_switchover_infinity_cmd
,
5146 "no ip pim spt-switchover infinity-and-beyond",
5151 "Never switch to SPT Tree\n")
5153 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5154 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
5157 DEFUN (no_ip_pim_spt_switchover_infinity_plist
,
5158 no_ip_pim_spt_switchover_infinity_plist_cmd
,
5159 "no ip pim spt-switchover infinity-and-beyond prefix-list WORD",
5164 "Never switch to SPT Tree\n"
5165 "Prefix-List to control which groups to switch\n"
5166 "Prefix-List name\n")
5168 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5169 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
5172 DEFUN (ip_pim_joinprune_time
,
5173 ip_pim_joinprune_time_cmd
,
5174 "ip pim join-prune-interval (60-600)",
5176 "pim multicast routing\n"
5177 "Join Prune Send Interval\n"
5180 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5181 qpim_t_periodic
= atoi(argv
[3]->arg
);
5185 DEFUN (no_ip_pim_joinprune_time
,
5186 no_ip_pim_joinprune_time_cmd
,
5187 "no ip pim join-prune-interval (60-600)",
5190 "pim multicast routing\n"
5191 "Join Prune Send Interval\n"
5194 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5195 qpim_t_periodic
= PIM_DEFAULT_T_PERIODIC
;
5199 DEFUN (ip_pim_register_suppress
,
5200 ip_pim_register_suppress_cmd
,
5201 "ip pim register-suppress-time (5-60000)",
5203 "pim multicast routing\n"
5204 "Register Suppress Timer\n"
5207 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5208 qpim_register_suppress_time
= atoi(argv
[3]->arg
);
5212 DEFUN (no_ip_pim_register_suppress
,
5213 no_ip_pim_register_suppress_cmd
,
5214 "no ip pim register-suppress-time (5-60000)",
5217 "pim multicast routing\n"
5218 "Register Suppress Timer\n"
5221 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5222 qpim_register_suppress_time
= PIM_REGISTER_SUPPRESSION_TIME_DEFAULT
;
5226 DEFUN (ip_pim_rp_keep_alive
,
5227 ip_pim_rp_keep_alive_cmd
,
5228 "ip pim rp keep-alive-timer (31-60000)",
5230 "pim multicast routing\n"
5232 "Keep alive Timer\n"
5235 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5236 pim
->rp_keep_alive_time
= atoi(argv
[4]->arg
);
5240 DEFUN (no_ip_pim_rp_keep_alive
,
5241 no_ip_pim_rp_keep_alive_cmd
,
5242 "no ip pim rp keep-alive-timer (31-60000)",
5245 "pim multicast routing\n"
5247 "Keep alive Timer\n"
5250 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5251 pim
->rp_keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
5255 DEFUN (ip_pim_keep_alive
,
5256 ip_pim_keep_alive_cmd
,
5257 "ip pim keep-alive-timer (31-60000)",
5259 "pim multicast routing\n"
5260 "Keep alive Timer\n"
5263 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5264 pim
->keep_alive_time
= atoi(argv
[3]->arg
);
5268 DEFUN (no_ip_pim_keep_alive
,
5269 no_ip_pim_keep_alive_cmd
,
5270 "no ip pim keep-alive-timer (31-60000)",
5273 "pim multicast routing\n"
5274 "Keep alive Timer\n"
5277 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5278 pim
->keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
5282 DEFUN (ip_pim_packets
,
5284 "ip pim packets (1-100)",
5286 "pim multicast routing\n"
5287 "packets to process at one time per fd\n"
5288 "Number of packets\n")
5290 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5291 qpim_packet_process
= atoi(argv
[3]->arg
);
5295 DEFUN (no_ip_pim_packets
,
5296 no_ip_pim_packets_cmd
,
5297 "no ip pim packets (1-100)",
5300 "pim multicast routing\n"
5301 "packets to process at one time per fd\n"
5302 "Number of packets\n")
5304 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5305 qpim_packet_process
= PIM_DEFAULT_PACKET_PROCESS
;
5309 DEFUN (ip_pim_v6_secondary
,
5310 ip_pim_v6_secondary_cmd
,
5311 "ip pim send-v6-secondary",
5313 "pim multicast routing\n"
5314 "Send v6 secondary addresses\n")
5316 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5317 pim
->send_v6_secondary
= 1;
5322 DEFUN (no_ip_pim_v6_secondary
,
5323 no_ip_pim_v6_secondary_cmd
,
5324 "no ip pim send-v6-secondary",
5327 "pim multicast routing\n"
5328 "Send v6 secondary addresses\n")
5330 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5331 pim
->send_v6_secondary
= 0;
5338 "ip pim rp A.B.C.D [A.B.C.D/M]",
5340 "pim multicast routing\n"
5342 "ip address of RP\n"
5343 "Group Address range to cover\n")
5345 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5348 if (argc
== (idx_ipv4
+ 1))
5349 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
5352 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
5353 argv
[idx_ipv4
+ 1]->arg
, NULL
);
5356 DEFUN (ip_pim_rp_prefix_list
,
5357 ip_pim_rp_prefix_list_cmd
,
5358 "ip pim rp A.B.C.D prefix-list WORD",
5360 "pim multicast routing\n"
5362 "ip address of RP\n"
5363 "group prefix-list filter\n"
5364 "Name of a prefix-list\n")
5366 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5367 return pim_rp_cmd_worker(pim
, vty
, argv
[3]->arg
, NULL
, argv
[5]->arg
);
5370 static int pim_no_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
5371 const char *rp
, const char *group
,
5374 int result
= pim_rp_del(pim
, rp
, group
, plist
);
5376 if (result
== PIM_GROUP_BAD_ADDRESS
) {
5377 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
5378 return CMD_WARNING_CONFIG_FAILED
;
5381 if (result
== PIM_RP_BAD_ADDRESS
) {
5382 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
5383 return CMD_WARNING_CONFIG_FAILED
;
5386 if (result
== PIM_RP_NOT_FOUND
) {
5387 vty_out(vty
, "%% Unable to find specified RP\n");
5388 return CMD_WARNING_CONFIG_FAILED
;
5394 DEFUN (no_ip_pim_rp
,
5396 "no ip pim rp A.B.C.D [A.B.C.D/M]",
5399 "pim multicast routing\n"
5401 "ip address of RP\n"
5402 "Group Address range to cover\n")
5404 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5405 int idx_ipv4
= 4, idx_group
= 0;
5407 if (argv_find(argv
, argc
, "A.B.C.D/M", &idx_group
))
5408 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
5409 argv
[idx_group
]->arg
, NULL
);
5411 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
5415 DEFUN (no_ip_pim_rp_prefix_list
,
5416 no_ip_pim_rp_prefix_list_cmd
,
5417 "no ip pim rp A.B.C.D prefix-list WORD",
5420 "pim multicast routing\n"
5422 "ip address of RP\n"
5423 "group prefix-list filter\n"
5424 "Name of a prefix-list\n")
5426 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5427 return pim_no_rp_cmd_worker(pim
, vty
, argv
[4]->arg
, NULL
, argv
[6]->arg
);
5430 static int pim_ssm_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
5433 int result
= pim_ssm_range_set(pim
, pim
->vrf_id
, plist
);
5435 if (result
== PIM_SSM_ERR_NONE
)
5439 case PIM_SSM_ERR_NO_VRF
:
5440 vty_out(vty
, "%% VRF doesn't exist\n");
5442 case PIM_SSM_ERR_DUP
:
5443 vty_out(vty
, "%% duplicate config\n");
5446 vty_out(vty
, "%% ssm range config failed\n");
5449 return CMD_WARNING_CONFIG_FAILED
;
5452 DEFUN (ip_pim_ssm_prefix_list
,
5453 ip_pim_ssm_prefix_list_cmd
,
5454 "ip pim ssm prefix-list WORD",
5456 "pim multicast routing\n"
5457 "Source Specific Multicast\n"
5458 "group range prefix-list filter\n"
5459 "Name of a prefix-list\n")
5461 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5462 return pim_ssm_cmd_worker(pim
, vty
, argv
[4]->arg
);
5465 DEFUN (no_ip_pim_ssm_prefix_list
,
5466 no_ip_pim_ssm_prefix_list_cmd
,
5467 "no ip pim ssm prefix-list",
5470 "pim multicast routing\n"
5471 "Source Specific Multicast\n"
5472 "group range prefix-list filter\n")
5474 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5475 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
5478 DEFUN (no_ip_pim_ssm_prefix_list_name
,
5479 no_ip_pim_ssm_prefix_list_name_cmd
,
5480 "no ip pim ssm prefix-list WORD",
5483 "pim multicast routing\n"
5484 "Source Specific Multicast\n"
5485 "group range prefix-list filter\n"
5486 "Name of a prefix-list\n")
5488 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5489 struct pim_ssm
*ssm
= pim
->ssm_info
;
5491 if (ssm
->plist_name
&& !strcmp(ssm
->plist_name
, argv
[5]->arg
))
5492 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
5494 vty_out(vty
, "%% pim ssm prefix-list %s doesn't exist\n", argv
[5]->arg
);
5496 return CMD_WARNING_CONFIG_FAILED
;
5499 static void ip_pim_ssm_show_group_range(struct pim_instance
*pim
,
5500 struct vty
*vty
, u_char uj
)
5502 struct pim_ssm
*ssm
= pim
->ssm_info
;
5503 const char *range_str
=
5504 ssm
->plist_name
? ssm
->plist_name
: PIM_SSM_STANDARD_RANGE
;
5508 json
= json_object_new_object();
5509 json_object_string_add(json
, "ssmGroups", range_str
);
5510 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5511 json
, JSON_C_TO_STRING_PRETTY
));
5512 json_object_free(json
);
5514 vty_out(vty
, "SSM group range : %s\n", range_str
);
5517 DEFUN (show_ip_pim_ssm_range
,
5518 show_ip_pim_ssm_range_cmd
,
5519 "show ip pim [vrf NAME] group-type [json]",
5528 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5529 u_char uj
= use_json(argc
, argv
);
5534 ip_pim_ssm_show_group_range(vrf
->info
, vty
, uj
);
5539 static void ip_pim_ssm_show_group_type(struct pim_instance
*pim
,
5540 struct vty
*vty
, u_char uj
,
5543 struct in_addr group_addr
;
5544 const char *type_str
;
5547 result
= inet_pton(AF_INET
, group
, &group_addr
);
5549 type_str
= "invalid";
5551 if (pim_is_group_224_4(group_addr
))
5553 pim_is_grp_ssm(pim
, group_addr
) ? "SSM" : "ASM";
5555 type_str
= "not-multicast";
5560 json
= json_object_new_object();
5561 json_object_string_add(json
, "groupType", type_str
);
5562 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5563 json
, JSON_C_TO_STRING_PRETTY
));
5564 json_object_free(json
);
5566 vty_out(vty
, "Group type : %s\n", type_str
);
5569 DEFUN (show_ip_pim_group_type
,
5570 show_ip_pim_group_type_cmd
,
5571 "show ip pim [vrf NAME] group-type A.B.C.D [json]",
5576 "multicast group type\n"
5581 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5582 u_char uj
= use_json(argc
, argv
);
5587 argv_find(argv
, argc
, "A.B.C.D", &idx
);
5588 ip_pim_ssm_show_group_type(vrf
->info
, vty
, uj
, argv
[idx
]->arg
);
5593 DEFUN_HIDDEN (ip_multicast_routing
,
5594 ip_multicast_routing_cmd
,
5595 "ip multicast-routing",
5597 "Enable IP multicast forwarding\n")
5602 DEFUN_HIDDEN (no_ip_multicast_routing
,
5603 no_ip_multicast_routing_cmd
,
5604 "no ip multicast-routing",
5607 "Enable IP multicast forwarding\n")
5610 "Command is Disabled and will be removed in a future version\n");
5616 "ip ssmpingd [A.B.C.D]",
5621 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5624 struct in_addr source_addr
;
5625 const char *source_str
= (argc
== 3) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
5627 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
5629 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
5630 source_str
, errno
, safe_strerror(errno
));
5631 return CMD_WARNING_CONFIG_FAILED
;
5634 result
= pim_ssmpingd_start(pim
, source_addr
);
5636 vty_out(vty
, "%% Failure starting ssmpingd for source %s: %d\n",
5637 source_str
, result
);
5638 return CMD_WARNING_CONFIG_FAILED
;
5644 DEFUN (no_ip_ssmpingd
,
5646 "no ip ssmpingd [A.B.C.D]",
5652 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5655 struct in_addr source_addr
;
5656 const char *source_str
= (argc
== 4) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
5658 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
5660 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
5661 source_str
, errno
, safe_strerror(errno
));
5662 return CMD_WARNING_CONFIG_FAILED
;
5665 result
= pim_ssmpingd_stop(pim
, source_addr
);
5667 vty_out(vty
, "%% Failure stopping ssmpingd for source %s: %d\n",
5668 source_str
, result
);
5669 return CMD_WARNING_CONFIG_FAILED
;
5679 "pim multicast routing\n"
5680 "Enable PIM ECMP \n")
5682 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5683 qpim_ecmp_enable
= 1;
5688 DEFUN (no_ip_pim_ecmp
,
5693 "pim multicast routing\n"
5694 "Disable PIM ECMP \n")
5696 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5697 qpim_ecmp_enable
= 0;
5702 DEFUN (ip_pim_ecmp_rebalance
,
5703 ip_pim_ecmp_rebalance_cmd
,
5704 "ip pim ecmp rebalance",
5706 "pim multicast routing\n"
5707 "Enable PIM ECMP \n"
5708 "Enable PIM ECMP Rebalance\n")
5710 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5711 qpim_ecmp_enable
= 1;
5712 qpim_ecmp_rebalance_enable
= 1;
5717 DEFUN (no_ip_pim_ecmp_rebalance
,
5718 no_ip_pim_ecmp_rebalance_cmd
,
5719 "no ip pim ecmp rebalance",
5722 "pim multicast routing\n"
5723 "Disable PIM ECMP \n"
5724 "Disable PIM ECMP Rebalance\n")
5726 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5727 qpim_ecmp_rebalance_enable
= 0;
5732 static int pim_cmd_igmp_start(struct vty
*vty
, struct interface
*ifp
)
5734 struct pim_interface
*pim_ifp
;
5735 uint8_t need_startup
= 0;
5737 pim_ifp
= ifp
->info
;
5740 pim_ifp
= pim_if_new(ifp
, 1 /* igmp=true */, 0 /* pim=false */);
5742 vty_out(vty
, "Could not enable IGMP on interface %s\n",
5744 return CMD_WARNING_CONFIG_FAILED
;
5748 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
5749 PIM_IF_DO_IGMP(pim_ifp
->options
);
5754 /* 'ip igmp' executed multiple times, with need_startup
5755 avoid multiple if add all and membership refresh */
5757 pim_if_addr_add_all(ifp
);
5758 pim_if_membership_refresh(ifp
);
5764 DEFUN (interface_ip_igmp
,
5765 interface_ip_igmp_cmd
,
5770 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5772 return pim_cmd_igmp_start(vty
, ifp
);
5775 DEFUN (interface_no_ip_igmp
,
5776 interface_no_ip_igmp_cmd
,
5782 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5783 struct pim_interface
*pim_ifp
= ifp
->info
;
5788 PIM_IF_DONT_IGMP(pim_ifp
->options
);
5790 pim_if_membership_clear(ifp
);
5792 pim_if_addr_del_all_igmp(ifp
);
5794 if (!PIM_IF_TEST_PIM(pim_ifp
->options
)) {
5801 DEFUN (interface_ip_igmp_join
,
5802 interface_ip_igmp_join_cmd
,
5803 "ip igmp join A.B.C.D A.B.C.D",
5806 "IGMP join multicast group\n"
5807 "Multicast group address\n"
5810 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5813 const char *group_str
;
5814 const char *source_str
;
5815 struct in_addr group_addr
;
5816 struct in_addr source_addr
;
5820 group_str
= argv
[idx_ipv4
]->arg
;
5821 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
5823 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
5824 errno
, safe_strerror(errno
));
5825 return CMD_WARNING_CONFIG_FAILED
;
5828 /* Source address */
5829 source_str
= argv
[idx_ipv4_2
]->arg
;
5830 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
5832 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
5833 source_str
, errno
, safe_strerror(errno
));
5834 return CMD_WARNING_CONFIG_FAILED
;
5837 CMD_FERR_RETURN(pim_if_igmp_join_add(ifp
, group_addr
, source_addr
),
5838 "Failure joining IGMP group: $ERR");
5843 DEFUN (interface_no_ip_igmp_join
,
5844 interface_no_ip_igmp_join_cmd
,
5845 "no ip igmp join A.B.C.D A.B.C.D",
5849 "IGMP join multicast group\n"
5850 "Multicast group address\n"
5853 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5856 const char *group_str
;
5857 const char *source_str
;
5858 struct in_addr group_addr
;
5859 struct in_addr source_addr
;
5863 group_str
= argv
[idx_ipv4
]->arg
;
5864 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
5866 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
5867 errno
, safe_strerror(errno
));
5868 return CMD_WARNING_CONFIG_FAILED
;
5871 /* Source address */
5872 source_str
= argv
[idx_ipv4_2
]->arg
;
5873 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
5875 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
5876 source_str
, errno
, safe_strerror(errno
));
5877 return CMD_WARNING_CONFIG_FAILED
;
5880 result
= pim_if_igmp_join_del(ifp
, group_addr
, source_addr
);
5883 "%% Failure leaving IGMP group %s source %s on interface %s: %d\n",
5884 group_str
, source_str
, ifp
->name
, result
);
5885 return CMD_WARNING_CONFIG_FAILED
;
5892 CLI reconfiguration affects the interface level (struct pim_interface).
5893 This function propagates the reconfiguration to every active socket
5896 static void igmp_sock_query_interval_reconfig(struct igmp_sock
*igmp
)
5898 struct interface
*ifp
;
5899 struct pim_interface
*pim_ifp
;
5903 /* other querier present? */
5905 if (igmp
->t_other_querier_timer
)
5908 /* this is the querier */
5910 zassert(igmp
->interface
);
5911 zassert(igmp
->interface
->info
);
5913 ifp
= igmp
->interface
;
5914 pim_ifp
= ifp
->info
;
5916 if (PIM_DEBUG_IGMP_TRACE
) {
5917 char ifaddr_str
[INET_ADDRSTRLEN
];
5918 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
5919 sizeof(ifaddr_str
));
5920 zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
5921 __PRETTY_FUNCTION__
, ifaddr_str
, ifp
->name
,
5922 pim_ifp
->igmp_default_query_interval
);
5926 igmp_startup_mode_on() will reset QQI:
5928 igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
5930 igmp_startup_mode_on(igmp
);
5933 static void igmp_sock_query_reschedule(struct igmp_sock
*igmp
)
5935 if (igmp
->t_igmp_query_timer
) {
5936 /* other querier present */
5937 zassert(igmp
->t_igmp_query_timer
);
5938 zassert(!igmp
->t_other_querier_timer
);
5940 pim_igmp_general_query_off(igmp
);
5941 pim_igmp_general_query_on(igmp
);
5943 zassert(igmp
->t_igmp_query_timer
);
5944 zassert(!igmp
->t_other_querier_timer
);
5946 /* this is the querier */
5948 zassert(!igmp
->t_igmp_query_timer
);
5949 zassert(igmp
->t_other_querier_timer
);
5951 pim_igmp_other_querier_timer_off(igmp
);
5952 pim_igmp_other_querier_timer_on(igmp
);
5954 zassert(!igmp
->t_igmp_query_timer
);
5955 zassert(igmp
->t_other_querier_timer
);
5959 static void change_query_interval(struct pim_interface
*pim_ifp
,
5962 struct listnode
*sock_node
;
5963 struct igmp_sock
*igmp
;
5965 pim_ifp
->igmp_default_query_interval
= query_interval
;
5967 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
5968 igmp_sock_query_interval_reconfig(igmp
);
5969 igmp_sock_query_reschedule(igmp
);
5973 static void change_query_max_response_time(struct pim_interface
*pim_ifp
,
5974 int query_max_response_time_dsec
)
5976 struct listnode
*sock_node
;
5977 struct igmp_sock
*igmp
;
5979 pim_ifp
->igmp_query_max_response_time_dsec
=
5980 query_max_response_time_dsec
;
5983 Below we modify socket/group/source timers in order to quickly
5984 reflect the change. Otherwise, those timers would eventually catch
5988 /* scan all sockets */
5989 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
5990 struct listnode
*grp_node
;
5991 struct igmp_group
*grp
;
5993 /* reschedule socket general query */
5994 igmp_sock_query_reschedule(igmp
);
5996 /* scan socket groups */
5997 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grp_node
,
5999 struct listnode
*src_node
;
6000 struct igmp_source
*src
;
6002 /* reset group timers for groups in EXCLUDE mode */
6003 if (grp
->group_filtermode_isexcl
) {
6004 igmp_group_reset_gmi(grp
);
6007 /* scan group sources */
6008 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
,
6011 /* reset source timers for sources with running
6013 if (src
->t_source_timer
) {
6014 igmp_source_reset_gmi(igmp
, grp
, src
);
6021 #define IGMP_QUERY_INTERVAL_MIN (1)
6022 #define IGMP_QUERY_INTERVAL_MAX (1800)
6024 DEFUN (interface_ip_igmp_query_interval
,
6025 interface_ip_igmp_query_interval_cmd
,
6026 "ip igmp query-interval (1-1800)",
6029 IFACE_IGMP_QUERY_INTERVAL_STR
6030 "Query interval in seconds\n")
6032 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6033 struct pim_interface
*pim_ifp
= ifp
->info
;
6035 int query_interval_dsec
;
6039 ret
= pim_cmd_igmp_start(vty
, ifp
);
6040 if (ret
!= CMD_SUCCESS
)
6042 pim_ifp
= ifp
->info
;
6045 query_interval
= atoi(argv
[3]->arg
);
6046 query_interval_dsec
= 10 * query_interval
;
6049 It seems we don't need to check bounds since command.c does it
6050 already, but we verify them anyway for extra safety.
6052 if (query_interval
< IGMP_QUERY_INTERVAL_MIN
) {
6054 "General query interval %d lower than minimum %d\n",
6055 query_interval
, IGMP_QUERY_INTERVAL_MIN
);
6056 return CMD_WARNING_CONFIG_FAILED
;
6058 if (query_interval
> IGMP_QUERY_INTERVAL_MAX
) {
6060 "General query interval %d higher than maximum %d\n",
6061 query_interval
, IGMP_QUERY_INTERVAL_MAX
);
6062 return CMD_WARNING_CONFIG_FAILED
;
6065 if (query_interval_dsec
<= pim_ifp
->igmp_query_max_response_time_dsec
) {
6067 "Can't set general query interval %d dsec <= query max response time %d dsec.\n",
6068 query_interval_dsec
,
6069 pim_ifp
->igmp_query_max_response_time_dsec
);
6070 return CMD_WARNING_CONFIG_FAILED
;
6073 change_query_interval(pim_ifp
, query_interval
);
6078 DEFUN (interface_no_ip_igmp_query_interval
,
6079 interface_no_ip_igmp_query_interval_cmd
,
6080 "no ip igmp query-interval",
6084 IFACE_IGMP_QUERY_INTERVAL_STR
)
6086 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6087 struct pim_interface
*pim_ifp
= ifp
->info
;
6088 int default_query_interval_dsec
;
6093 default_query_interval_dsec
= IGMP_GENERAL_QUERY_INTERVAL
* 10;
6095 if (default_query_interval_dsec
6096 <= pim_ifp
->igmp_query_max_response_time_dsec
) {
6098 "Can't set default general query interval %d dsec <= query max response time %d dsec.\n",
6099 default_query_interval_dsec
,
6100 pim_ifp
->igmp_query_max_response_time_dsec
);
6101 return CMD_WARNING_CONFIG_FAILED
;
6104 change_query_interval(pim_ifp
, IGMP_GENERAL_QUERY_INTERVAL
);
6109 DEFUN (interface_ip_igmp_version
,
6110 interface_ip_igmp_version_cmd
,
6111 "ip igmp version (2-3)",
6115 "IGMP version number\n")
6117 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6118 struct pim_interface
*pim_ifp
= ifp
->info
;
6119 int igmp_version
, old_version
= 0;
6123 ret
= pim_cmd_igmp_start(vty
, ifp
);
6124 if (ret
!= CMD_SUCCESS
)
6126 pim_ifp
= ifp
->info
;
6129 igmp_version
= atoi(argv
[3]->arg
);
6130 old_version
= pim_ifp
->igmp_version
;
6131 pim_ifp
->igmp_version
= igmp_version
;
6133 // Check if IGMP is Enabled otherwise, enable on interface
6134 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
6135 PIM_IF_DO_IGMP(pim_ifp
->options
);
6136 pim_if_addr_add_all(ifp
);
6137 pim_if_membership_refresh(ifp
);
6138 old_version
= igmp_version
; // avoid refreshing membership
6141 /* Current and new version is different refresh existing
6142 membership. Going from 3 -> 2 or 2 -> 3. */
6143 if (old_version
!= igmp_version
)
6144 pim_if_membership_refresh(ifp
);
6149 DEFUN (interface_no_ip_igmp_version
,
6150 interface_no_ip_igmp_version_cmd
,
6151 "no ip igmp version (2-3)",
6156 "IGMP version number\n")
6158 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6159 struct pim_interface
*pim_ifp
= ifp
->info
;
6164 pim_ifp
->igmp_version
= IGMP_DEFAULT_VERSION
;
6169 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
6170 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
6172 DEFUN (interface_ip_igmp_query_max_response_time
,
6173 interface_ip_igmp_query_max_response_time_cmd
,
6174 "ip igmp query-max-response-time (10-250)",
6177 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
6178 "Query response value in deci-seconds\n")
6180 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6181 struct pim_interface
*pim_ifp
= ifp
->info
;
6182 int query_max_response_time
;
6186 ret
= pim_cmd_igmp_start(vty
, ifp
);
6187 if (ret
!= CMD_SUCCESS
)
6189 pim_ifp
= ifp
->info
;
6192 query_max_response_time
= atoi(argv
[3]->arg
);
6194 if (query_max_response_time
6195 >= pim_ifp
->igmp_default_query_interval
* 10) {
6197 "Can't set query max response time %d sec >= general query interval %d sec\n",
6198 query_max_response_time
,
6199 pim_ifp
->igmp_default_query_interval
);
6200 return CMD_WARNING_CONFIG_FAILED
;
6203 change_query_max_response_time(pim_ifp
, query_max_response_time
);
6208 DEFUN (interface_no_ip_igmp_query_max_response_time
,
6209 interface_no_ip_igmp_query_max_response_time_cmd
,
6210 "no ip igmp query-max-response-time (10-250)",
6214 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
6215 "Time for response in deci-seconds\n")
6217 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6218 struct pim_interface
*pim_ifp
= ifp
->info
;
6223 change_query_max_response_time(pim_ifp
,
6224 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
6229 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
6230 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
6232 DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec
,
6233 interface_ip_igmp_query_max_response_time_dsec_cmd
,
6234 "ip igmp query-max-response-time-dsec (10-250)",
6237 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
6238 "Query response value in deciseconds\n")
6240 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6241 struct pim_interface
*pim_ifp
= ifp
->info
;
6242 int query_max_response_time_dsec
;
6243 int default_query_interval_dsec
;
6247 ret
= pim_cmd_igmp_start(vty
, ifp
);
6248 if (ret
!= CMD_SUCCESS
)
6250 pim_ifp
= ifp
->info
;
6253 query_max_response_time_dsec
= atoi(argv
[4]->arg
);
6255 default_query_interval_dsec
= 10 * pim_ifp
->igmp_default_query_interval
;
6257 if (query_max_response_time_dsec
>= default_query_interval_dsec
) {
6259 "Can't set query max response time %d dsec >= general query interval %d dsec\n",
6260 query_max_response_time_dsec
,
6261 default_query_interval_dsec
);
6262 return CMD_WARNING_CONFIG_FAILED
;
6265 change_query_max_response_time(pim_ifp
, query_max_response_time_dsec
);
6270 DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec
,
6271 interface_no_ip_igmp_query_max_response_time_dsec_cmd
,
6272 "no ip igmp query-max-response-time-dsec",
6276 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
)
6278 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6279 struct pim_interface
*pim_ifp
= ifp
->info
;
6284 change_query_max_response_time(pim_ifp
,
6285 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
6290 DEFUN (interface_ip_pim_drprio
,
6291 interface_ip_pim_drprio_cmd
,
6292 "ip pim drpriority (1-4294967295)",
6295 "Set the Designated Router Election Priority\n"
6296 "Value of the new DR Priority\n")
6298 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6300 struct pim_interface
*pim_ifp
= ifp
->info
;
6301 uint32_t old_dr_prio
;
6304 vty_out(vty
, "Please enable PIM on interface, first\n");
6305 return CMD_WARNING_CONFIG_FAILED
;
6308 old_dr_prio
= pim_ifp
->pim_dr_priority
;
6310 pim_ifp
->pim_dr_priority
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
6312 if (old_dr_prio
!= pim_ifp
->pim_dr_priority
) {
6313 if (pim_if_dr_election(ifp
))
6314 pim_hello_restart_now(ifp
);
6320 DEFUN (interface_no_ip_pim_drprio
,
6321 interface_no_ip_pim_drprio_cmd
,
6322 "no ip pim drpriority [(1-4294967295)]",
6326 "Revert the Designated Router Priority to default\n"
6327 "Old Value of the Priority\n")
6329 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6330 struct pim_interface
*pim_ifp
= ifp
->info
;
6333 vty_out(vty
, "Pim not enabled on this interface\n");
6334 return CMD_WARNING_CONFIG_FAILED
;
6337 if (pim_ifp
->pim_dr_priority
!= PIM_DEFAULT_DR_PRIORITY
) {
6338 pim_ifp
->pim_dr_priority
= PIM_DEFAULT_DR_PRIORITY
;
6339 if (pim_if_dr_election(ifp
))
6340 pim_hello_restart_now(ifp
);
6346 static int pim_cmd_interface_add(struct interface
*ifp
)
6348 struct pim_interface
*pim_ifp
= ifp
->info
;
6351 pim_ifp
= pim_if_new(ifp
, 0 /* igmp=false */, 1 /* pim=true */);
6356 PIM_IF_DO_PIM(pim_ifp
->options
);
6359 pim_if_addr_add_all(ifp
);
6360 pim_if_membership_refresh(ifp
);
6364 DEFUN_HIDDEN (interface_ip_pim_ssm
,
6365 interface_ip_pim_ssm_cmd
,
6371 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6373 if (!pim_cmd_interface_add(ifp
)) {
6374 vty_out(vty
, "Could not enable PIM SM on interface\n");
6375 return CMD_WARNING_CONFIG_FAILED
;
6379 "WARN: Enabled PIM SM on interface; configure PIM SSM "
6380 "range if needed\n");
6384 DEFUN (interface_ip_pim_sm
,
6385 interface_ip_pim_sm_cmd
,
6391 struct pim_interface
*pim_ifp
;
6393 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6394 if (!pim_cmd_interface_add(ifp
)) {
6395 vty_out(vty
, "Could not enable PIM SM on interface\n");
6396 return CMD_WARNING_CONFIG_FAILED
;
6399 pim_ifp
= ifp
->info
;
6401 pim_if_create_pimreg(pim_ifp
->pim
);
6406 static int pim_cmd_interface_delete(struct interface
*ifp
)
6408 struct pim_interface
*pim_ifp
= ifp
->info
;
6413 PIM_IF_DONT_PIM(pim_ifp
->options
);
6415 pim_if_membership_clear(ifp
);
6418 pim_sock_delete() removes all neighbors from
6419 pim_ifp->pim_neighbor_list.
6421 pim_sock_delete(ifp
, "pim unconfigured on interface");
6423 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
6424 pim_if_addr_del_all(ifp
);
6431 DEFUN_HIDDEN (interface_no_ip_pim_ssm
,
6432 interface_no_ip_pim_ssm_cmd
,
6439 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6440 if (!pim_cmd_interface_delete(ifp
)) {
6441 vty_out(vty
, "Unable to delete interface information\n");
6442 return CMD_WARNING_CONFIG_FAILED
;
6448 DEFUN (interface_no_ip_pim_sm
,
6449 interface_no_ip_pim_sm_cmd
,
6456 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6457 if (!pim_cmd_interface_delete(ifp
)) {
6458 vty_out(vty
, "Unable to delete interface information\n");
6459 return CMD_WARNING_CONFIG_FAILED
;
6465 DEFUN (interface_ip_mroute
,
6466 interface_ip_mroute_cmd
,
6467 "ip mroute INTERFACE A.B.C.D",
6469 "Add multicast route\n"
6470 "Outgoing interface name\n"
6473 VTY_DECLVAR_CONTEXT(interface
, iif
);
6474 struct pim_interface
*pim_ifp
;
6475 struct pim_instance
*pim
;
6476 int idx_interface
= 2;
6478 struct interface
*oif
;
6479 const char *oifname
;
6480 const char *grp_str
;
6481 struct in_addr grp_addr
;
6482 struct in_addr src_addr
;
6485 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6488 oifname
= argv
[idx_interface
]->arg
;
6489 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6491 vty_out(vty
, "No such interface name %s\n", oifname
);
6495 grp_str
= argv
[idx_ipv4
]->arg
;
6496 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6498 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6499 errno
, safe_strerror(errno
));
6503 src_addr
.s_addr
= INADDR_ANY
;
6505 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6506 vty_out(vty
, "Failed to add route\n");
6513 DEFUN (interface_ip_mroute_source
,
6514 interface_ip_mroute_source_cmd
,
6515 "ip mroute INTERFACE A.B.C.D A.B.C.D",
6517 "Add multicast route\n"
6518 "Outgoing interface name\n"
6522 VTY_DECLVAR_CONTEXT(interface
, iif
);
6523 struct pim_interface
*pim_ifp
;
6524 struct pim_instance
*pim
;
6525 int idx_interface
= 2;
6528 struct interface
*oif
;
6529 const char *oifname
;
6530 const char *grp_str
;
6531 struct in_addr grp_addr
;
6532 const char *src_str
;
6533 struct in_addr src_addr
;
6536 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6539 oifname
= argv
[idx_interface
]->arg
;
6540 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6542 vty_out(vty
, "No such interface name %s\n", oifname
);
6546 grp_str
= argv
[idx_ipv4
]->arg
;
6547 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6549 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6550 errno
, safe_strerror(errno
));
6554 src_str
= argv
[idx_ipv4_2
]->arg
;
6555 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
6557 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
6558 errno
, safe_strerror(errno
));
6562 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6563 vty_out(vty
, "Failed to add route\n");
6570 DEFUN (interface_no_ip_mroute
,
6571 interface_no_ip_mroute_cmd
,
6572 "no ip mroute INTERFACE A.B.C.D",
6575 "Add multicast route\n"
6576 "Outgoing interface name\n"
6579 VTY_DECLVAR_CONTEXT(interface
, iif
);
6580 struct pim_interface
*pim_ifp
;
6581 struct pim_instance
*pim
;
6582 int idx_interface
= 3;
6584 struct interface
*oif
;
6585 const char *oifname
;
6586 const char *grp_str
;
6587 struct in_addr grp_addr
;
6588 struct in_addr src_addr
;
6591 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6594 oifname
= argv
[idx_interface
]->arg
;
6595 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6597 vty_out(vty
, "No such interface name %s\n", oifname
);
6601 grp_str
= argv
[idx_ipv4
]->arg
;
6602 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6604 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6605 errno
, safe_strerror(errno
));
6609 src_addr
.s_addr
= INADDR_ANY
;
6611 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6612 vty_out(vty
, "Failed to remove route\n");
6619 DEFUN (interface_no_ip_mroute_source
,
6620 interface_no_ip_mroute_source_cmd
,
6621 "no ip mroute INTERFACE A.B.C.D A.B.C.D",
6624 "Add multicast route\n"
6625 "Outgoing interface name\n"
6629 VTY_DECLVAR_CONTEXT(interface
, iif
);
6630 struct pim_interface
*pim_ifp
;
6631 struct pim_instance
*pim
;
6632 int idx_interface
= 3;
6635 struct interface
*oif
;
6636 const char *oifname
;
6637 const char *grp_str
;
6638 struct in_addr grp_addr
;
6639 const char *src_str
;
6640 struct in_addr src_addr
;
6643 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6646 oifname
= argv
[idx_interface
]->arg
;
6647 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6649 vty_out(vty
, "No such interface name %s\n", oifname
);
6653 grp_str
= argv
[idx_ipv4
]->arg
;
6654 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6656 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6657 errno
, safe_strerror(errno
));
6661 src_str
= argv
[idx_ipv4_2
]->arg
;
6662 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
6664 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
6665 errno
, safe_strerror(errno
));
6669 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6670 vty_out(vty
, "Failed to remove route\n");
6677 DEFUN (interface_ip_pim_hello
,
6678 interface_ip_pim_hello_cmd
,
6679 "ip pim hello (1-180) [(1-180)]",
6683 IFACE_PIM_HELLO_TIME_STR
6684 IFACE_PIM_HELLO_HOLD_STR
)
6686 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6689 struct pim_interface
*pim_ifp
= ifp
->info
;
6692 if (!pim_cmd_interface_add(ifp
)) {
6693 vty_out(vty
, "Could not enable PIM SM on interface\n");
6694 return CMD_WARNING_CONFIG_FAILED
;
6698 pim_ifp
= ifp
->info
;
6699 pim_ifp
->pim_hello_period
= strtol(argv
[idx_time
]->arg
, NULL
, 10);
6701 if (argc
== idx_hold
+ 1)
6702 pim_ifp
->pim_default_holdtime
=
6703 strtol(argv
[idx_hold
]->arg
, NULL
, 10);
6708 DEFUN (interface_no_ip_pim_hello
,
6709 interface_no_ip_pim_hello_cmd
,
6710 "no ip pim hello [(1-180) (1-180)]",
6715 IFACE_PIM_HELLO_TIME_STR
6716 IFACE_PIM_HELLO_HOLD_STR
)
6718 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6719 struct pim_interface
*pim_ifp
= ifp
->info
;
6722 vty_out(vty
, "Pim not enabled on this interface\n");
6723 return CMD_WARNING_CONFIG_FAILED
;
6726 pim_ifp
->pim_hello_period
= PIM_DEFAULT_HELLO_PERIOD
;
6727 pim_ifp
->pim_default_holdtime
= -1;
6738 PIM_DO_DEBUG_IGMP_EVENTS
;
6739 PIM_DO_DEBUG_IGMP_PACKETS
;
6740 PIM_DO_DEBUG_IGMP_TRACE
;
6744 DEFUN (no_debug_igmp
,
6751 PIM_DONT_DEBUG_IGMP_EVENTS
;
6752 PIM_DONT_DEBUG_IGMP_PACKETS
;
6753 PIM_DONT_DEBUG_IGMP_TRACE
;
6758 DEFUN (debug_igmp_events
,
6759 debug_igmp_events_cmd
,
6760 "debug igmp events",
6763 DEBUG_IGMP_EVENTS_STR
)
6765 PIM_DO_DEBUG_IGMP_EVENTS
;
6769 DEFUN (no_debug_igmp_events
,
6770 no_debug_igmp_events_cmd
,
6771 "no debug igmp events",
6775 DEBUG_IGMP_EVENTS_STR
)
6777 PIM_DONT_DEBUG_IGMP_EVENTS
;
6782 DEFUN (debug_igmp_packets
,
6783 debug_igmp_packets_cmd
,
6784 "debug igmp packets",
6787 DEBUG_IGMP_PACKETS_STR
)
6789 PIM_DO_DEBUG_IGMP_PACKETS
;
6793 DEFUN (no_debug_igmp_packets
,
6794 no_debug_igmp_packets_cmd
,
6795 "no debug igmp packets",
6799 DEBUG_IGMP_PACKETS_STR
)
6801 PIM_DONT_DEBUG_IGMP_PACKETS
;
6806 DEFUN (debug_igmp_trace
,
6807 debug_igmp_trace_cmd
,
6811 DEBUG_IGMP_TRACE_STR
)
6813 PIM_DO_DEBUG_IGMP_TRACE
;
6817 DEFUN (no_debug_igmp_trace
,
6818 no_debug_igmp_trace_cmd
,
6819 "no debug igmp trace",
6823 DEBUG_IGMP_TRACE_STR
)
6825 PIM_DONT_DEBUG_IGMP_TRACE
;
6830 DEFUN (debug_mroute
,
6836 PIM_DO_DEBUG_MROUTE
;
6840 DEFUN (debug_mroute_detail
,
6841 debug_mroute_detail_cmd
,
6842 "debug mroute detail",
6847 PIM_DO_DEBUG_MROUTE_DETAIL
;
6851 DEFUN (no_debug_mroute
,
6852 no_debug_mroute_cmd
,
6858 PIM_DONT_DEBUG_MROUTE
;
6862 DEFUN (no_debug_mroute_detail
,
6863 no_debug_mroute_detail_cmd
,
6864 "no debug mroute detail",
6870 PIM_DONT_DEBUG_MROUTE_DETAIL
;
6874 DEFUN (debug_static
,
6880 PIM_DO_DEBUG_STATIC
;
6884 DEFUN (no_debug_static
,
6885 no_debug_static_cmd
,
6891 PIM_DONT_DEBUG_STATIC
;
6902 PIM_DO_DEBUG_PIM_EVENTS
;
6903 PIM_DO_DEBUG_PIM_PACKETS
;
6904 PIM_DO_DEBUG_PIM_TRACE
;
6905 PIM_DO_DEBUG_MSDP_EVENTS
;
6906 PIM_DO_DEBUG_MSDP_PACKETS
;
6910 DEFUN (no_debug_pim
,
6917 PIM_DONT_DEBUG_PIM_EVENTS
;
6918 PIM_DONT_DEBUG_PIM_PACKETS
;
6919 PIM_DONT_DEBUG_PIM_TRACE
;
6920 PIM_DONT_DEBUG_MSDP_EVENTS
;
6921 PIM_DONT_DEBUG_MSDP_PACKETS
;
6923 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
6924 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
6929 DEFUN (debug_pim_nht
,
6934 "Nexthop Tracking\n")
6936 PIM_DO_DEBUG_PIM_NHT
;
6940 DEFUN (no_debug_pim_nht
,
6941 no_debug_pim_nht_cmd
,
6946 "Nexthop Tracking\n")
6948 PIM_DONT_DEBUG_PIM_NHT
;
6952 DEFUN (debug_pim_nht_rp
,
6953 debug_pim_nht_rp_cmd
,
6957 "Nexthop Tracking\n"
6958 "RP Nexthop Tracking\n")
6960 PIM_DO_DEBUG_PIM_NHT_RP
;
6964 DEFUN (no_debug_pim_nht_rp
,
6965 no_debug_pim_nht_rp_cmd
,
6966 "no debug pim nht rp",
6970 "Nexthop Tracking\n"
6971 "RP Nexthop Tracking\n")
6973 PIM_DONT_DEBUG_PIM_NHT_RP
;
6977 DEFUN (debug_pim_events
,
6978 debug_pim_events_cmd
,
6982 DEBUG_PIM_EVENTS_STR
)
6984 PIM_DO_DEBUG_PIM_EVENTS
;
6988 DEFUN (no_debug_pim_events
,
6989 no_debug_pim_events_cmd
,
6990 "no debug pim events",
6994 DEBUG_PIM_EVENTS_STR
)
6996 PIM_DONT_DEBUG_PIM_EVENTS
;
7000 DEFUN (debug_pim_packets
,
7001 debug_pim_packets_cmd
,
7002 "debug pim packets [<hello|joins|register>]",
7005 DEBUG_PIM_PACKETS_STR
7006 DEBUG_PIM_HELLO_PACKETS_STR
7007 DEBUG_PIM_J_P_PACKETS_STR
7008 DEBUG_PIM_PIM_REG_PACKETS_STR
)
7011 if (argv_find(argv
, argc
, "hello", &idx
)) {
7012 PIM_DO_DEBUG_PIM_HELLO
;
7013 vty_out(vty
, "PIM Hello debugging is on\n");
7014 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
7015 PIM_DO_DEBUG_PIM_J_P
;
7016 vty_out(vty
, "PIM Join/Prune debugging is on\n");
7017 } else if (argv_find(argv
, argc
, "register", &idx
)) {
7018 PIM_DO_DEBUG_PIM_REG
;
7019 vty_out(vty
, "PIM Register debugging is on\n");
7021 PIM_DO_DEBUG_PIM_PACKETS
;
7022 vty_out(vty
, "PIM Packet debugging is on \n");
7027 DEFUN (no_debug_pim_packets
,
7028 no_debug_pim_packets_cmd
,
7029 "no debug pim packets [<hello|joins|register>]",
7033 DEBUG_PIM_PACKETS_STR
7034 DEBUG_PIM_HELLO_PACKETS_STR
7035 DEBUG_PIM_J_P_PACKETS_STR
7036 DEBUG_PIM_PIM_REG_PACKETS_STR
)
7039 if (argv_find(argv
, argc
, "hello", &idx
)) {
7040 PIM_DONT_DEBUG_PIM_HELLO
;
7041 vty_out(vty
, "PIM Hello debugging is off \n");
7042 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
7043 PIM_DONT_DEBUG_PIM_J_P
;
7044 vty_out(vty
, "PIM Join/Prune debugging is off \n");
7045 } else if (argv_find(argv
, argc
, "register", &idx
)) {
7046 PIM_DONT_DEBUG_PIM_REG
;
7047 vty_out(vty
, "PIM Register debugging is off\n");
7049 PIM_DONT_DEBUG_PIM_PACKETS
;
7055 DEFUN (debug_pim_packetdump_send
,
7056 debug_pim_packetdump_send_cmd
,
7057 "debug pim packet-dump send",
7060 DEBUG_PIM_PACKETDUMP_STR
7061 DEBUG_PIM_PACKETDUMP_SEND_STR
)
7063 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND
;
7067 DEFUN (no_debug_pim_packetdump_send
,
7068 no_debug_pim_packetdump_send_cmd
,
7069 "no debug pim packet-dump send",
7073 DEBUG_PIM_PACKETDUMP_STR
7074 DEBUG_PIM_PACKETDUMP_SEND_STR
)
7076 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
7080 DEFUN (debug_pim_packetdump_recv
,
7081 debug_pim_packetdump_recv_cmd
,
7082 "debug pim packet-dump receive",
7085 DEBUG_PIM_PACKETDUMP_STR
7086 DEBUG_PIM_PACKETDUMP_RECV_STR
)
7088 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV
;
7092 DEFUN (no_debug_pim_packetdump_recv
,
7093 no_debug_pim_packetdump_recv_cmd
,
7094 "no debug pim packet-dump receive",
7098 DEBUG_PIM_PACKETDUMP_STR
7099 DEBUG_PIM_PACKETDUMP_RECV_STR
)
7101 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
7105 DEFUN (debug_pim_trace
,
7106 debug_pim_trace_cmd
,
7110 DEBUG_PIM_TRACE_STR
)
7112 PIM_DO_DEBUG_PIM_TRACE
;
7116 DEFUN (debug_pim_trace_detail
,
7117 debug_pim_trace_detail_cmd
,
7118 "debug pim trace detail",
7122 "Detailed Information\n")
7124 PIM_DO_DEBUG_PIM_TRACE_DETAIL
;
7128 DEFUN (no_debug_pim_trace
,
7129 no_debug_pim_trace_cmd
,
7130 "no debug pim trace",
7134 DEBUG_PIM_TRACE_STR
)
7136 PIM_DONT_DEBUG_PIM_TRACE
;
7140 DEFUN (no_debug_pim_trace_detail
,
7141 no_debug_pim_trace_detail_cmd
,
7142 "no debug pim trace detail",
7147 "Detailed Information\n")
7149 PIM_DONT_DEBUG_PIM_TRACE_DETAIL
;
7153 DEFUN (debug_ssmpingd
,
7159 PIM_DO_DEBUG_SSMPINGD
;
7163 DEFUN (no_debug_ssmpingd
,
7164 no_debug_ssmpingd_cmd
,
7165 "no debug ssmpingd",
7170 PIM_DONT_DEBUG_SSMPINGD
;
7174 DEFUN (debug_pim_zebra
,
7175 debug_pim_zebra_cmd
,
7179 DEBUG_PIM_ZEBRA_STR
)
7185 DEFUN (no_debug_pim_zebra
,
7186 no_debug_pim_zebra_cmd
,
7187 "no debug pim zebra",
7191 DEBUG_PIM_ZEBRA_STR
)
7193 PIM_DONT_DEBUG_ZEBRA
;
7203 PIM_DO_DEBUG_MSDP_EVENTS
;
7204 PIM_DO_DEBUG_MSDP_PACKETS
;
7208 DEFUN (no_debug_msdp
,
7215 PIM_DONT_DEBUG_MSDP_EVENTS
;
7216 PIM_DONT_DEBUG_MSDP_PACKETS
;
7220 ALIAS(no_debug_msdp
, undebug_msdp_cmd
, "undebug msdp",
7221 UNDEBUG_STR DEBUG_MSDP_STR
)
7223 DEFUN (debug_msdp_events
,
7224 debug_msdp_events_cmd
,
7225 "debug msdp events",
7228 DEBUG_MSDP_EVENTS_STR
)
7230 PIM_DO_DEBUG_MSDP_EVENTS
;
7234 DEFUN (no_debug_msdp_events
,
7235 no_debug_msdp_events_cmd
,
7236 "no debug msdp events",
7240 DEBUG_MSDP_EVENTS_STR
)
7242 PIM_DONT_DEBUG_MSDP_EVENTS
;
7246 ALIAS(no_debug_msdp_events
, undebug_msdp_events_cmd
, "undebug msdp events",
7247 UNDEBUG_STR DEBUG_MSDP_STR DEBUG_MSDP_EVENTS_STR
)
7249 DEFUN (debug_msdp_packets
,
7250 debug_msdp_packets_cmd
,
7251 "debug msdp packets",
7254 DEBUG_MSDP_PACKETS_STR
)
7256 PIM_DO_DEBUG_MSDP_PACKETS
;
7260 DEFUN (no_debug_msdp_packets
,
7261 no_debug_msdp_packets_cmd
,
7262 "no debug msdp packets",
7266 DEBUG_MSDP_PACKETS_STR
)
7268 PIM_DONT_DEBUG_MSDP_PACKETS
;
7272 ALIAS(no_debug_msdp_packets
, undebug_msdp_packets_cmd
, "undebug msdp packets",
7273 UNDEBUG_STR DEBUG_MSDP_STR DEBUG_MSDP_PACKETS_STR
)
7275 DEFUN_NOSH (show_debugging_pim
,
7276 show_debugging_pim_cmd
,
7277 "show debugging [pim]",
7282 vty_out(vty
, "PIM debugging status\n");
7284 pim_debug_config_write(vty
);
7289 static int interface_pim_use_src_cmd_worker(struct vty
*vty
, const char *source
)
7292 struct in_addr source_addr
;
7293 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7295 result
= inet_pton(AF_INET
, source
, &source_addr
);
7297 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", source
,
7298 errno
, safe_strerror(errno
));
7299 return CMD_WARNING_CONFIG_FAILED
;
7302 result
= pim_update_source_set(ifp
, source_addr
);
7306 case PIM_IFACE_NOT_FOUND
:
7307 vty_out(vty
, "Pim not enabled on this interface\n");
7309 case PIM_UPDATE_SOURCE_DUP
:
7310 vty_out(vty
, "%% Source already set to %s\n", source
);
7313 vty_out(vty
, "%% Source set failed\n");
7316 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7319 DEFUN (interface_pim_use_source
,
7320 interface_pim_use_source_cmd
,
7321 "ip pim use-source A.B.C.D",
7323 "pim multicast routing\n"
7324 "Configure primary IP address\n"
7325 "source ip address\n")
7327 return interface_pim_use_src_cmd_worker(vty
, argv
[3]->arg
);
7330 DEFUN (interface_no_pim_use_source
,
7331 interface_no_pim_use_source_cmd
,
7332 "no ip pim use-source [A.B.C.D]",
7335 "pim multicast routing\n"
7336 "Delete source IP address\n"
7337 "source ip address\n")
7339 return interface_pim_use_src_cmd_worker(vty
, "0.0.0.0");
7347 "Enables BFD support\n")
7349 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7350 struct pim_interface
*pim_ifp
= ifp
->info
;
7351 struct bfd_info
*bfd_info
= NULL
;
7354 if (!pim_cmd_interface_add(ifp
)) {
7355 vty_out(vty
, "Could not enable PIM SM on interface\n");
7359 pim_ifp
= ifp
->info
;
7361 bfd_info
= pim_ifp
->bfd_info
;
7363 if (!bfd_info
|| !CHECK_FLAG(bfd_info
->flags
, BFD_FLAG_PARAM_CFG
))
7364 pim_bfd_if_param_set(ifp
, BFD_DEF_MIN_RX
, BFD_DEF_MIN_TX
,
7365 BFD_DEF_DETECT_MULT
, 1);
7370 DEFUN (no_ip_pim_bfd
,
7376 "Disables BFD support\n")
7378 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7379 struct pim_interface
*pim_ifp
= ifp
->info
;
7382 vty_out(vty
, "Pim not enabled on this interface\n");
7386 if (pim_ifp
->bfd_info
) {
7387 pim_bfd_reg_dereg_all_nbr(ifp
, ZEBRA_BFD_DEST_DEREGISTER
);
7388 bfd_info_free(&(pim_ifp
->bfd_info
));
7394 DEFUN (ip_pim_bfd_param
,
7395 ip_pim_bfd_param_cmd
,
7396 "ip pim bfd (2-255) (50-60000) (50-60000)",
7399 "Enables BFD support\n"
7400 "Detect Multiplier\n"
7401 "Required min receive interval\n"
7402 "Desired min transmit interval\n")
7404 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7406 int idx_number_2
= 4;
7407 int idx_number_3
= 5;
7412 struct pim_interface
*pim_ifp
= ifp
->info
;
7415 if (!pim_cmd_interface_add(ifp
)) {
7416 vty_out(vty
, "Could not enable PIM SM on interface\n");
7421 if ((ret
= bfd_validate_param(
7422 vty
, argv
[idx_number
]->arg
, argv
[idx_number_2
]->arg
,
7423 argv
[idx_number_3
]->arg
, &dm_val
, &rx_val
, &tx_val
))
7427 pim_bfd_if_param_set(ifp
, rx_val
, tx_val
, dm_val
, 0);
7432 ALIAS(no_ip_pim_bfd
, no_ip_pim_bfd_param_cmd
,
7433 "no ip pim bfd (2-255) (50-60000) (50-60000)", NO_STR IP_STR PIM_STR
7434 "Enables BFD support\n"
7435 "Detect Multiplier\n"
7436 "Required min receive interval\n"
7437 "Desired min transmit interval\n")
7439 static int ip_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
7440 const char *peer
, const char *local
)
7442 enum pim_msdp_err result
;
7443 struct in_addr peer_addr
;
7444 struct in_addr local_addr
;
7446 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
7448 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
7449 errno
, safe_strerror(errno
));
7450 return CMD_WARNING_CONFIG_FAILED
;
7453 result
= inet_pton(AF_INET
, local
, &local_addr
);
7455 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", local
,
7456 errno
, safe_strerror(errno
));
7457 return CMD_WARNING_CONFIG_FAILED
;
7460 result
= pim_msdp_peer_add(pim
, peer_addr
, local_addr
, "default",
7463 case PIM_MSDP_ERR_NONE
:
7465 case PIM_MSDP_ERR_OOM
:
7466 vty_out(vty
, "%% Out of memory\n");
7468 case PIM_MSDP_ERR_PEER_EXISTS
:
7469 vty_out(vty
, "%% Peer exists\n");
7471 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
7472 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
7475 vty_out(vty
, "%% peer add failed\n");
7478 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7481 DEFUN_HIDDEN (ip_msdp_peer
,
7483 "ip msdp peer A.B.C.D source A.B.C.D",
7486 "Configure MSDP peer\n"
7488 "Source address for TCP connection\n"
7489 "local ip address\n")
7491 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7492 return ip_msdp_peer_cmd_worker(pim
, vty
, argv
[3]->arg
, argv
[5]->arg
);
7495 static int ip_no_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
7498 enum pim_msdp_err result
;
7499 struct in_addr peer_addr
;
7501 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
7503 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
7504 errno
, safe_strerror(errno
));
7505 return CMD_WARNING_CONFIG_FAILED
;
7508 result
= pim_msdp_peer_del(pim
, peer_addr
);
7510 case PIM_MSDP_ERR_NONE
:
7512 case PIM_MSDP_ERR_NO_PEER
:
7513 vty_out(vty
, "%% Peer does not exist\n");
7516 vty_out(vty
, "%% peer del failed\n");
7519 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7522 DEFUN_HIDDEN (no_ip_msdp_peer
,
7523 no_ip_msdp_peer_cmd
,
7524 "no ip msdp peer A.B.C.D",
7528 "Delete MSDP peer\n"
7529 "peer ip address\n")
7531 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7532 return ip_no_msdp_peer_cmd_worker(pim
, vty
, argv
[4]->arg
);
7535 static int ip_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
7536 struct vty
*vty
, const char *mg
,
7539 enum pim_msdp_err result
;
7540 struct in_addr mbr_ip
;
7542 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
7544 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
7545 errno
, safe_strerror(errno
));
7546 return CMD_WARNING_CONFIG_FAILED
;
7549 result
= pim_msdp_mg_mbr_add(pim
, mg
, mbr_ip
);
7551 case PIM_MSDP_ERR_NONE
:
7553 case PIM_MSDP_ERR_OOM
:
7554 vty_out(vty
, "%% Out of memory\n");
7556 case PIM_MSDP_ERR_MG_MBR_EXISTS
:
7557 vty_out(vty
, "%% mesh-group member exists\n");
7559 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
7560 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
7563 vty_out(vty
, "%% member add failed\n");
7566 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7569 DEFUN (ip_msdp_mesh_group_member
,
7570 ip_msdp_mesh_group_member_cmd
,
7571 "ip msdp mesh-group WORD member A.B.C.D",
7574 "Configure MSDP mesh-group\n"
7576 "mesh group member\n"
7577 "peer ip address\n")
7579 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7580 return ip_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[3]->arg
,
7584 static int ip_no_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
7589 enum pim_msdp_err result
;
7590 struct in_addr mbr_ip
;
7592 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
7594 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
7595 errno
, safe_strerror(errno
));
7596 return CMD_WARNING_CONFIG_FAILED
;
7599 result
= pim_msdp_mg_mbr_del(pim
, mg
, mbr_ip
);
7601 case PIM_MSDP_ERR_NONE
:
7603 case PIM_MSDP_ERR_NO_MG
:
7604 vty_out(vty
, "%% mesh-group does not exist\n");
7606 case PIM_MSDP_ERR_NO_MG_MBR
:
7607 vty_out(vty
, "%% mesh-group member does not exist\n");
7610 vty_out(vty
, "%% mesh-group member del failed\n");
7613 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7615 DEFUN (no_ip_msdp_mesh_group_member
,
7616 no_ip_msdp_mesh_group_member_cmd
,
7617 "no ip msdp mesh-group WORD member A.B.C.D",
7621 "Delete MSDP mesh-group member\n"
7623 "mesh group member\n"
7624 "peer ip address\n")
7626 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7627 return ip_no_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[4]->arg
,
7631 static int ip_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
7632 struct vty
*vty
, const char *mg
,
7635 enum pim_msdp_err result
;
7636 struct in_addr src_ip
;
7638 result
= inet_pton(AF_INET
, src
, &src_ip
);
7640 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", src
,
7641 errno
, safe_strerror(errno
));
7642 return CMD_WARNING_CONFIG_FAILED
;
7645 result
= pim_msdp_mg_src_add(pim
, mg
, src_ip
);
7647 case PIM_MSDP_ERR_NONE
:
7649 case PIM_MSDP_ERR_OOM
:
7650 vty_out(vty
, "%% Out of memory\n");
7652 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
7653 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
7656 vty_out(vty
, "%% source add failed\n");
7659 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7663 DEFUN (ip_msdp_mesh_group_source
,
7664 ip_msdp_mesh_group_source_cmd
,
7665 "ip msdp mesh-group WORD source A.B.C.D",
7668 "Configure MSDP mesh-group\n"
7670 "mesh group local address\n"
7671 "source ip address for the TCP connection\n")
7673 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7674 return ip_msdp_mesh_group_source_cmd_worker(pim
, vty
, argv
[3]->arg
,
7678 static int ip_no_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
7682 enum pim_msdp_err result
;
7684 result
= pim_msdp_mg_src_del(pim
, mg
);
7686 case PIM_MSDP_ERR_NONE
:
7688 case PIM_MSDP_ERR_NO_MG
:
7689 vty_out(vty
, "%% mesh-group does not exist\n");
7692 vty_out(vty
, "%% mesh-group source del failed\n");
7695 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7698 static int ip_no_msdp_mesh_group_cmd_worker(struct pim_instance
*pim
,
7699 struct vty
*vty
, const char *mg
)
7701 enum pim_msdp_err result
;
7703 result
= pim_msdp_mg_del(pim
, mg
);
7705 case PIM_MSDP_ERR_NONE
:
7707 case PIM_MSDP_ERR_NO_MG
:
7708 vty_out(vty
, "%% mesh-group does not exist\n");
7711 vty_out(vty
, "%% mesh-group source del failed\n");
7714 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7717 DEFUN (no_ip_msdp_mesh_group_source
,
7718 no_ip_msdp_mesh_group_source_cmd
,
7719 "no ip msdp mesh-group WORD source [A.B.C.D]",
7723 "Delete MSDP mesh-group source\n"
7725 "mesh group source\n"
7726 "mesh group local address\n")
7728 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7730 return ip_no_msdp_mesh_group_cmd_worker(pim
, vty
, argv
[6]->arg
);
7732 return ip_no_msdp_mesh_group_source_cmd_worker(pim
, vty
,
7736 static void print_empty_json_obj(struct vty
*vty
)
7739 json
= json_object_new_object();
7740 vty_out(vty
, "%s\n",
7741 json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
));
7742 json_object_free(json
);
7745 static void ip_msdp_show_mesh_group(struct pim_instance
*pim
, struct vty
*vty
,
7748 struct listnode
*mbrnode
;
7749 struct pim_msdp_mg_mbr
*mbr
;
7750 struct pim_msdp_mg
*mg
= pim
->msdp
.mg
;
7751 char mbr_str
[INET_ADDRSTRLEN
];
7752 char src_str
[INET_ADDRSTRLEN
];
7753 char state_str
[PIM_MSDP_STATE_STRLEN
];
7754 enum pim_msdp_peer_state state
;
7755 json_object
*json
= NULL
;
7756 json_object
*json_mg_row
= NULL
;
7757 json_object
*json_members
= NULL
;
7758 json_object
*json_row
= NULL
;
7762 print_empty_json_obj(vty
);
7766 pim_inet4_dump("<source?>", mg
->src_ip
, src_str
, sizeof(src_str
));
7768 json
= json_object_new_object();
7769 /* currently there is only one mesh group but we should still
7771 * it a dict with mg-name as key */
7772 json_mg_row
= json_object_new_object();
7773 json_object_string_add(json_mg_row
, "name",
7774 mg
->mesh_group_name
);
7775 json_object_string_add(json_mg_row
, "source", src_str
);
7777 vty_out(vty
, "Mesh group : %s\n", mg
->mesh_group_name
);
7778 vty_out(vty
, " Source : %s\n", src_str
);
7779 vty_out(vty
, " Member State\n");
7782 for (ALL_LIST_ELEMENTS_RO(mg
->mbr_list
, mbrnode
, mbr
)) {
7783 pim_inet4_dump("<mbr?>", mbr
->mbr_ip
, mbr_str
, sizeof(mbr_str
));
7785 state
= mbr
->mp
->state
;
7787 state
= PIM_MSDP_DISABLED
;
7789 pim_msdp_state_dump(state
, state_str
, sizeof(state_str
));
7791 json_row
= json_object_new_object();
7792 json_object_string_add(json_row
, "member", mbr_str
);
7793 json_object_string_add(json_row
, "state", state_str
);
7794 if (!json_members
) {
7795 json_members
= json_object_new_object();
7796 json_object_object_add(json_mg_row
, "members",
7799 json_object_object_add(json_members
, mbr_str
, json_row
);
7801 vty_out(vty
, " %-15s %11s\n", mbr_str
, state_str
);
7806 json_object_object_add(json
, mg
->mesh_group_name
, json_mg_row
);
7807 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
7808 json
, JSON_C_TO_STRING_PRETTY
));
7809 json_object_free(json
);
7813 DEFUN (show_ip_msdp_mesh_group
,
7814 show_ip_msdp_mesh_group_cmd
,
7815 "show ip msdp [vrf NAME] mesh-group [json]",
7820 "MSDP mesh-group information\n"
7823 u_char uj
= use_json(argc
, argv
);
7825 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
7830 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
7835 DEFUN (show_ip_msdp_mesh_group_vrf_all
,
7836 show_ip_msdp_mesh_group_vrf_all_cmd
,
7837 "show ip msdp vrf all mesh-group [json]",
7842 "MSDP mesh-group information\n"
7845 u_char uj
= use_json(argc
, argv
);
7851 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
7855 vty_out(vty
, " \"%s\": ", vrf
->name
);
7858 vty_out(vty
, "VRF: %s\n", vrf
->name
);
7859 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
7862 vty_out(vty
, "}\n");
7867 static void ip_msdp_show_peers(struct pim_instance
*pim
, struct vty
*vty
,
7870 struct listnode
*mpnode
;
7871 struct pim_msdp_peer
*mp
;
7872 char peer_str
[INET_ADDRSTRLEN
];
7873 char local_str
[INET_ADDRSTRLEN
];
7874 char state_str
[PIM_MSDP_STATE_STRLEN
];
7875 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
7877 json_object
*json
= NULL
;
7878 json_object
*json_row
= NULL
;
7882 json
= json_object_new_object();
7885 "Peer Local State Uptime SaCnt\n");
7888 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
7889 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
7890 now
= pim_time_monotonic_sec();
7891 pim_time_uptime(timebuf
, sizeof(timebuf
),
7894 strcpy(timebuf
, "-");
7896 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
7897 pim_inet4_dump("<local?>", mp
->local
, local_str
,
7899 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
7901 json_row
= json_object_new_object();
7902 json_object_string_add(json_row
, "peer", peer_str
);
7903 json_object_string_add(json_row
, "local", local_str
);
7904 json_object_string_add(json_row
, "state", state_str
);
7905 json_object_string_add(json_row
, "upTime", timebuf
);
7906 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
7907 json_object_object_add(json
, peer_str
, json_row
);
7909 vty_out(vty
, "%-15s %15s %11s %8s %6d\n", peer_str
,
7910 local_str
, state_str
, timebuf
, mp
->sa_cnt
);
7915 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
7916 json
, JSON_C_TO_STRING_PRETTY
));
7917 json_object_free(json
);
7921 static void ip_msdp_show_peers_detail(struct pim_instance
*pim
, struct vty
*vty
,
7922 const char *peer
, u_char uj
)
7924 struct listnode
*mpnode
;
7925 struct pim_msdp_peer
*mp
;
7926 char peer_str
[INET_ADDRSTRLEN
];
7927 char local_str
[INET_ADDRSTRLEN
];
7928 char state_str
[PIM_MSDP_STATE_STRLEN
];
7929 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
7930 char katimer
[PIM_MSDP_TIMER_STRLEN
];
7931 char crtimer
[PIM_MSDP_TIMER_STRLEN
];
7932 char holdtimer
[PIM_MSDP_TIMER_STRLEN
];
7934 json_object
*json
= NULL
;
7935 json_object
*json_row
= NULL
;
7938 json
= json_object_new_object();
7941 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
7942 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
7943 if (strcmp(peer
, "detail") && strcmp(peer
, peer_str
))
7946 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
7947 now
= pim_time_monotonic_sec();
7948 pim_time_uptime(timebuf
, sizeof(timebuf
),
7951 strcpy(timebuf
, "-");
7953 pim_inet4_dump("<local?>", mp
->local
, local_str
,
7955 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
7956 pim_time_timer_to_hhmmss(katimer
, sizeof(katimer
),
7958 pim_time_timer_to_hhmmss(crtimer
, sizeof(crtimer
),
7960 pim_time_timer_to_hhmmss(holdtimer
, sizeof(holdtimer
),
7964 json_row
= json_object_new_object();
7965 json_object_string_add(json_row
, "peer", peer_str
);
7966 json_object_string_add(json_row
, "local", local_str
);
7967 json_object_string_add(json_row
, "meshGroupName",
7968 mp
->mesh_group_name
);
7969 json_object_string_add(json_row
, "state", state_str
);
7970 json_object_string_add(json_row
, "upTime", timebuf
);
7971 json_object_string_add(json_row
, "keepAliveTimer",
7973 json_object_string_add(json_row
, "connRetryTimer",
7975 json_object_string_add(json_row
, "holdTimer",
7977 json_object_string_add(json_row
, "lastReset",
7979 json_object_int_add(json_row
, "connAttempts",
7981 json_object_int_add(json_row
, "establishedChanges",
7983 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
7984 json_object_int_add(json_row
, "kaSent", mp
->ka_tx_cnt
);
7985 json_object_int_add(json_row
, "kaRcvd", mp
->ka_rx_cnt
);
7986 json_object_int_add(json_row
, "saSent", mp
->sa_tx_cnt
);
7987 json_object_int_add(json_row
, "saRcvd", mp
->sa_rx_cnt
);
7988 json_object_object_add(json
, peer_str
, json_row
);
7990 vty_out(vty
, "Peer : %s\n", peer_str
);
7991 vty_out(vty
, " Local : %s\n", local_str
);
7992 vty_out(vty
, " Mesh Group : %s\n",
7993 mp
->mesh_group_name
);
7994 vty_out(vty
, " State : %s\n", state_str
);
7995 vty_out(vty
, " Uptime : %s\n", timebuf
);
7997 vty_out(vty
, " Keepalive Timer : %s\n", katimer
);
7998 vty_out(vty
, " Conn Retry Timer : %s\n", crtimer
);
7999 vty_out(vty
, " Hold Timer : %s\n", holdtimer
);
8000 vty_out(vty
, " Last Reset : %s\n",
8002 vty_out(vty
, " Conn Attempts : %d\n",
8004 vty_out(vty
, " Established Changes : %d\n",
8006 vty_out(vty
, " SA Count : %d\n",
8008 vty_out(vty
, " Statistics :\n");
8011 vty_out(vty
, " Keepalives : %10d %10d\n",
8012 mp
->ka_tx_cnt
, mp
->ka_rx_cnt
);
8013 vty_out(vty
, " SAs : %10d %10d\n",
8014 mp
->sa_tx_cnt
, mp
->sa_rx_cnt
);
8020 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8021 json
, JSON_C_TO_STRING_PRETTY
));
8022 json_object_free(json
);
8026 DEFUN (show_ip_msdp_peer_detail
,
8027 show_ip_msdp_peer_detail_cmd
,
8028 "show ip msdp [vrf NAME] peer [detail|A.B.C.D] [json]",
8033 "MSDP peer information\n"
8038 u_char uj
= use_json(argc
, argv
);
8040 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
8047 if (argv_find(argv
, argc
, "detail", &idx
))
8048 arg
= argv
[idx
]->text
;
8049 else if (argv_find(argv
, argc
, "A.B.C.D", &idx
))
8050 arg
= argv
[idx
]->arg
;
8053 ip_msdp_show_peers_detail(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
8055 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
8060 DEFUN (show_ip_msdp_peer_detail_vrf_all
,
8061 show_ip_msdp_peer_detail_vrf_all_cmd
,
8062 "show ip msdp vrf all peer [detail|A.B.C.D] [json]",
8067 "MSDP peer information\n"
8073 u_char uj
= use_json(argc
, argv
);
8079 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
8083 vty_out(vty
, " \"%s\": ", vrf
->name
);
8086 vty_out(vty
, "VRF: %s\n", vrf
->name
);
8087 if (argv_find(argv
, argc
, "detail", &idx
)
8088 || argv_find(argv
, argc
, "A.B.C.D", &idx
))
8089 ip_msdp_show_peers_detail(vrf
->info
, vty
,
8090 argv
[idx
]->arg
, uj
);
8092 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
8095 vty_out(vty
, "}\n");
8100 static void ip_msdp_show_sa(struct pim_instance
*pim
, struct vty
*vty
,
8103 struct listnode
*sanode
;
8104 struct pim_msdp_sa
*sa
;
8105 char src_str
[INET_ADDRSTRLEN
];
8106 char grp_str
[INET_ADDRSTRLEN
];
8107 char rp_str
[INET_ADDRSTRLEN
];
8108 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
8112 json_object
*json
= NULL
;
8113 json_object
*json_group
= NULL
;
8114 json_object
*json_row
= NULL
;
8117 json
= json_object_new_object();
8120 "Source Group RP Local SPT Uptime\n");
8123 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
8124 now
= pim_time_monotonic_sec();
8125 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
8126 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
8127 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
8128 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
8129 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
8131 strcpy(spt_str
, "yes");
8133 strcpy(spt_str
, "no");
8136 strcpy(rp_str
, "-");
8137 strcpy(spt_str
, "-");
8139 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
8140 strcpy(local_str
, "yes");
8142 strcpy(local_str
, "no");
8145 json_object_object_get_ex(json
, grp_str
, &json_group
);
8148 json_group
= json_object_new_object();
8149 json_object_object_add(json
, grp_str
,
8153 json_row
= json_object_new_object();
8154 json_object_string_add(json_row
, "source", src_str
);
8155 json_object_string_add(json_row
, "group", grp_str
);
8156 json_object_string_add(json_row
, "rp", rp_str
);
8157 json_object_string_add(json_row
, "local", local_str
);
8158 json_object_string_add(json_row
, "sptSetup", spt_str
);
8159 json_object_string_add(json_row
, "upTime", timebuf
);
8160 json_object_object_add(json_group
, src_str
, json_row
);
8162 vty_out(vty
, "%-15s %15s %15s %5c %3c %8s\n",
8163 src_str
, grp_str
, rp_str
, local_str
[0],
8164 spt_str
[0], timebuf
);
8169 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8170 json
, JSON_C_TO_STRING_PRETTY
));
8171 json_object_free(json
);
8175 static void ip_msdp_show_sa_entry_detail(struct pim_msdp_sa
*sa
,
8176 const char *src_str
,
8177 const char *grp_str
, struct vty
*vty
,
8178 u_char uj
, json_object
*json
)
8180 char rp_str
[INET_ADDRSTRLEN
];
8181 char peer_str
[INET_ADDRSTRLEN
];
8182 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
8185 char statetimer
[PIM_MSDP_TIMER_STRLEN
];
8187 json_object
*json_group
= NULL
;
8188 json_object
*json_row
= NULL
;
8190 now
= pim_time_monotonic_sec();
8191 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
8192 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
8193 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
8194 pim_inet4_dump("<peer?>", sa
->peer
, peer_str
, sizeof(peer_str
));
8196 strcpy(spt_str
, "yes");
8198 strcpy(spt_str
, "no");
8201 strcpy(rp_str
, "-");
8202 strcpy(peer_str
, "-");
8203 strcpy(spt_str
, "-");
8205 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
8206 strcpy(local_str
, "yes");
8208 strcpy(local_str
, "no");
8210 pim_time_timer_to_hhmmss(statetimer
, sizeof(statetimer
),
8211 sa
->sa_state_timer
);
8213 json_object_object_get_ex(json
, grp_str
, &json_group
);
8216 json_group
= json_object_new_object();
8217 json_object_object_add(json
, grp_str
, json_group
);
8220 json_row
= json_object_new_object();
8221 json_object_string_add(json_row
, "source", src_str
);
8222 json_object_string_add(json_row
, "group", grp_str
);
8223 json_object_string_add(json_row
, "rp", rp_str
);
8224 json_object_string_add(json_row
, "local", local_str
);
8225 json_object_string_add(json_row
, "sptSetup", spt_str
);
8226 json_object_string_add(json_row
, "upTime", timebuf
);
8227 json_object_string_add(json_row
, "stateTimer", statetimer
);
8228 json_object_object_add(json_group
, src_str
, json_row
);
8230 vty_out(vty
, "SA : %s\n", sa
->sg_str
);
8231 vty_out(vty
, " RP : %s\n", rp_str
);
8232 vty_out(vty
, " Peer : %s\n", peer_str
);
8233 vty_out(vty
, " Local : %s\n", local_str
);
8234 vty_out(vty
, " SPT Setup : %s\n", spt_str
);
8235 vty_out(vty
, " Uptime : %s\n", timebuf
);
8236 vty_out(vty
, " State Timer : %s\n", statetimer
);
8241 static void ip_msdp_show_sa_detail(struct pim_instance
*pim
, struct vty
*vty
,
8244 struct listnode
*sanode
;
8245 struct pim_msdp_sa
*sa
;
8246 char src_str
[INET_ADDRSTRLEN
];
8247 char grp_str
[INET_ADDRSTRLEN
];
8248 json_object
*json
= NULL
;
8251 json
= json_object_new_object();
8254 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
8255 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
8256 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
8257 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
, uj
,
8262 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8263 json
, JSON_C_TO_STRING_PRETTY
));
8264 json_object_free(json
);
8268 DEFUN (show_ip_msdp_sa_detail
,
8269 show_ip_msdp_sa_detail_cmd
,
8270 "show ip msdp [vrf NAME] sa detail [json]",
8275 "MSDP active-source information\n"
8279 u_char uj
= use_json(argc
, argv
);
8281 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
8286 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
8291 DEFUN (show_ip_msdp_sa_detail_vrf_all
,
8292 show_ip_msdp_sa_detail_vrf_all_cmd
,
8293 "show ip msdp vrf all sa detail [json]",
8298 "MSDP active-source information\n"
8302 u_char uj
= use_json(argc
, argv
);
8308 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
8312 vty_out(vty
, " \"%s\": ", vrf
->name
);
8315 vty_out(vty
, "VRF: %s\n", vrf
->name
);
8316 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
8319 vty_out(vty
, "}\n");
8324 static void ip_msdp_show_sa_addr(struct pim_instance
*pim
, struct vty
*vty
,
8325 const char *addr
, u_char uj
)
8327 struct listnode
*sanode
;
8328 struct pim_msdp_sa
*sa
;
8329 char src_str
[INET_ADDRSTRLEN
];
8330 char grp_str
[INET_ADDRSTRLEN
];
8331 json_object
*json
= NULL
;
8334 json
= json_object_new_object();
8337 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
8338 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
8339 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
8340 if (!strcmp(addr
, src_str
) || !strcmp(addr
, grp_str
)) {
8341 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
8347 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8348 json
, JSON_C_TO_STRING_PRETTY
));
8349 json_object_free(json
);
8353 static void ip_msdp_show_sa_sg(struct pim_instance
*pim
, struct vty
*vty
,
8354 const char *src
, const char *grp
, u_char uj
)
8356 struct listnode
*sanode
;
8357 struct pim_msdp_sa
*sa
;
8358 char src_str
[INET_ADDRSTRLEN
];
8359 char grp_str
[INET_ADDRSTRLEN
];
8360 json_object
*json
= NULL
;
8363 json
= json_object_new_object();
8366 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
8367 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
8368 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
8369 if (!strcmp(src
, src_str
) && !strcmp(grp
, grp_str
)) {
8370 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
8376 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8377 json
, JSON_C_TO_STRING_PRETTY
));
8378 json_object_free(json
);
8382 DEFUN (show_ip_msdp_sa_sg
,
8383 show_ip_msdp_sa_sg_cmd
,
8384 "show ip msdp [vrf NAME] sa [A.B.C.D [A.B.C.D]] [json]",
8389 "MSDP active-source information\n"
8390 "source or group ip\n"
8394 u_char uj
= use_json(argc
, argv
);
8398 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
8403 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
8405 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
8409 if (src_ip
&& grp_ip
)
8410 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
8412 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
8414 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
8419 DEFUN (show_ip_msdp_sa_sg_vrf_all
,
8420 show_ip_msdp_sa_sg_vrf_all_cmd
,
8421 "show ip msdp vrf all sa [A.B.C.D [A.B.C.D]] [json]",
8426 "MSDP active-source information\n"
8427 "source or group ip\n"
8431 u_char uj
= use_json(argc
, argv
);
8436 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
8438 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
8444 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
8448 vty_out(vty
, " \"%s\": ", vrf
->name
);
8451 vty_out(vty
, "VRF: %s\n", vrf
->name
);
8453 if (src_ip
&& grp_ip
)
8454 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
8456 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
8458 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
8461 vty_out(vty
, "}\n");
8467 void pim_cmd_init(void)
8469 install_node(&pim_global_node
, pim_global_config_write
); /* PIM_NODE */
8470 install_node(&interface_node
,
8471 pim_interface_config_write
); /* INTERFACE_NODE */
8474 install_node(&debug_node
, pim_debug_config_write
);
8476 install_element(CONFIG_NODE
, &ip_multicast_routing_cmd
);
8477 install_element(CONFIG_NODE
, &no_ip_multicast_routing_cmd
);
8478 install_element(CONFIG_NODE
, &ip_pim_rp_cmd
);
8479 install_element(VRF_NODE
, &ip_pim_rp_cmd
);
8480 install_element(CONFIG_NODE
, &no_ip_pim_rp_cmd
);
8481 install_element(VRF_NODE
, &no_ip_pim_rp_cmd
);
8482 install_element(CONFIG_NODE
, &ip_pim_rp_prefix_list_cmd
);
8483 install_element(VRF_NODE
, &ip_pim_rp_prefix_list_cmd
);
8484 install_element(CONFIG_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
8485 install_element(VRF_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
8486 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
8487 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
8488 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
8489 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
8490 install_element(CONFIG_NODE
, &ip_pim_ssm_prefix_list_cmd
);
8491 install_element(VRF_NODE
, &ip_pim_ssm_prefix_list_cmd
);
8492 install_element(CONFIG_NODE
, &ip_pim_register_suppress_cmd
);
8493 install_element(VRF_NODE
, &ip_pim_register_suppress_cmd
);
8494 install_element(CONFIG_NODE
, &no_ip_pim_register_suppress_cmd
);
8495 install_element(VRF_NODE
, &no_ip_pim_register_suppress_cmd
);
8496 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
8497 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
8498 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
8499 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
8500 install_element(CONFIG_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
8501 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
8502 install_element(CONFIG_NODE
,
8503 &no_ip_pim_spt_switchover_infinity_plist_cmd
);
8504 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_plist_cmd
);
8505 install_element(CONFIG_NODE
, &ip_pim_joinprune_time_cmd
);
8506 install_element(VRF_NODE
, &ip_pim_joinprune_time_cmd
);
8507 install_element(CONFIG_NODE
, &no_ip_pim_joinprune_time_cmd
);
8508 install_element(VRF_NODE
, &no_ip_pim_joinprune_time_cmd
);
8509 install_element(CONFIG_NODE
, &ip_pim_keep_alive_cmd
);
8510 install_element(VRF_NODE
, &ip_pim_keep_alive_cmd
);
8511 install_element(CONFIG_NODE
, &ip_pim_rp_keep_alive_cmd
);
8512 install_element(VRF_NODE
, &ip_pim_rp_keep_alive_cmd
);
8513 install_element(CONFIG_NODE
, &no_ip_pim_keep_alive_cmd
);
8514 install_element(VRF_NODE
, &no_ip_pim_keep_alive_cmd
);
8515 install_element(CONFIG_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
8516 install_element(VRF_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
8517 install_element(CONFIG_NODE
, &ip_pim_packets_cmd
);
8518 install_element(VRF_NODE
, &ip_pim_packets_cmd
);
8519 install_element(CONFIG_NODE
, &no_ip_pim_packets_cmd
);
8520 install_element(VRF_NODE
, &no_ip_pim_packets_cmd
);
8521 install_element(CONFIG_NODE
, &ip_pim_v6_secondary_cmd
);
8522 install_element(VRF_NODE
, &ip_pim_v6_secondary_cmd
);
8523 install_element(CONFIG_NODE
, &no_ip_pim_v6_secondary_cmd
);
8524 install_element(VRF_NODE
, &no_ip_pim_v6_secondary_cmd
);
8525 install_element(CONFIG_NODE
, &ip_ssmpingd_cmd
);
8526 install_element(VRF_NODE
, &ip_ssmpingd_cmd
);
8527 install_element(CONFIG_NODE
, &no_ip_ssmpingd_cmd
);
8528 install_element(VRF_NODE
, &no_ip_ssmpingd_cmd
);
8529 install_element(CONFIG_NODE
, &ip_msdp_peer_cmd
);
8530 install_element(VRF_NODE
, &ip_msdp_peer_cmd
);
8531 install_element(CONFIG_NODE
, &no_ip_msdp_peer_cmd
);
8532 install_element(VRF_NODE
, &no_ip_msdp_peer_cmd
);
8533 install_element(CONFIG_NODE
, &ip_pim_ecmp_cmd
);
8534 install_element(VRF_NODE
, &ip_pim_ecmp_cmd
);
8535 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_cmd
);
8536 install_element(VRF_NODE
, &no_ip_pim_ecmp_cmd
);
8537 install_element(CONFIG_NODE
, &ip_pim_ecmp_rebalance_cmd
);
8538 install_element(VRF_NODE
, &ip_pim_ecmp_rebalance_cmd
);
8539 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
8540 install_element(VRF_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
8542 install_element(INTERFACE_NODE
, &interface_ip_igmp_cmd
);
8543 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_cmd
);
8544 install_element(INTERFACE_NODE
, &interface_ip_igmp_join_cmd
);
8545 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_join_cmd
);
8546 install_element(INTERFACE_NODE
, &interface_ip_igmp_version_cmd
);
8547 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_version_cmd
);
8548 install_element(INTERFACE_NODE
, &interface_ip_igmp_query_interval_cmd
);
8549 install_element(INTERFACE_NODE
,
8550 &interface_no_ip_igmp_query_interval_cmd
);
8551 install_element(INTERFACE_NODE
,
8552 &interface_ip_igmp_query_max_response_time_cmd
);
8553 install_element(INTERFACE_NODE
,
8554 &interface_no_ip_igmp_query_max_response_time_cmd
);
8555 install_element(INTERFACE_NODE
,
8556 &interface_ip_igmp_query_max_response_time_dsec_cmd
);
8557 install_element(INTERFACE_NODE
,
8558 &interface_no_ip_igmp_query_max_response_time_dsec_cmd
);
8559 install_element(INTERFACE_NODE
, &interface_ip_pim_ssm_cmd
);
8560 install_element(INTERFACE_NODE
, &interface_no_ip_pim_ssm_cmd
);
8561 install_element(INTERFACE_NODE
, &interface_ip_pim_sm_cmd
);
8562 install_element(INTERFACE_NODE
, &interface_no_ip_pim_sm_cmd
);
8563 install_element(INTERFACE_NODE
, &interface_ip_pim_drprio_cmd
);
8564 install_element(INTERFACE_NODE
, &interface_no_ip_pim_drprio_cmd
);
8565 install_element(INTERFACE_NODE
, &interface_ip_pim_hello_cmd
);
8566 install_element(INTERFACE_NODE
, &interface_no_ip_pim_hello_cmd
);
8568 // Static mroutes NEB
8569 install_element(INTERFACE_NODE
, &interface_ip_mroute_cmd
);
8570 install_element(INTERFACE_NODE
, &interface_ip_mroute_source_cmd
);
8571 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_cmd
);
8572 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_source_cmd
);
8574 install_element(VIEW_NODE
, &show_ip_igmp_interface_cmd
);
8575 install_element(VIEW_NODE
, &show_ip_igmp_interface_vrf_all_cmd
);
8576 install_element(VIEW_NODE
, &show_ip_igmp_join_cmd
);
8577 install_element(VIEW_NODE
, &show_ip_igmp_join_vrf_all_cmd
);
8578 install_element(VIEW_NODE
, &show_ip_igmp_groups_cmd
);
8579 install_element(VIEW_NODE
, &show_ip_igmp_groups_vrf_all_cmd
);
8580 install_element(VIEW_NODE
, &show_ip_igmp_groups_retransmissions_cmd
);
8581 install_element(VIEW_NODE
, &show_ip_igmp_sources_cmd
);
8582 install_element(VIEW_NODE
, &show_ip_igmp_sources_retransmissions_cmd
);
8583 install_element(VIEW_NODE
, &show_ip_pim_assert_cmd
);
8584 install_element(VIEW_NODE
, &show_ip_pim_assert_internal_cmd
);
8585 install_element(VIEW_NODE
, &show_ip_pim_assert_metric_cmd
);
8586 install_element(VIEW_NODE
, &show_ip_pim_assert_winner_metric_cmd
);
8587 install_element(VIEW_NODE
, &show_ip_pim_interface_traffic_cmd
);
8588 install_element(VIEW_NODE
, &show_ip_pim_interface_cmd
);
8589 install_element(VIEW_NODE
, &show_ip_pim_interface_vrf_all_cmd
);
8590 install_element(VIEW_NODE
, &show_ip_pim_join_cmd
);
8591 install_element(VIEW_NODE
, &show_ip_pim_join_vrf_all_cmd
);
8592 install_element(VIEW_NODE
, &show_ip_pim_local_membership_cmd
);
8593 install_element(VIEW_NODE
, &show_ip_pim_neighbor_cmd
);
8594 install_element(VIEW_NODE
, &show_ip_pim_neighbor_vrf_all_cmd
);
8595 install_element(VIEW_NODE
, &show_ip_pim_rpf_cmd
);
8596 install_element(VIEW_NODE
, &show_ip_pim_rpf_vrf_all_cmd
);
8597 install_element(VIEW_NODE
, &show_ip_pim_secondary_cmd
);
8598 install_element(VIEW_NODE
, &show_ip_pim_state_cmd
);
8599 install_element(VIEW_NODE
, &show_ip_pim_state_vrf_all_cmd
);
8600 install_element(VIEW_NODE
, &show_ip_pim_upstream_cmd
);
8601 install_element(VIEW_NODE
, &show_ip_pim_upstream_vrf_all_cmd
);
8602 install_element(VIEW_NODE
, &show_ip_pim_upstream_join_desired_cmd
);
8603 install_element(VIEW_NODE
, &show_ip_pim_upstream_rpf_cmd
);
8604 install_element(VIEW_NODE
, &show_ip_pim_rp_cmd
);
8605 install_element(VIEW_NODE
, &show_ip_pim_rp_vrf_all_cmd
);
8606 install_element(VIEW_NODE
, &show_ip_multicast_cmd
);
8607 install_element(VIEW_NODE
, &show_ip_multicast_vrf_all_cmd
);
8608 install_element(VIEW_NODE
, &show_ip_mroute_cmd
);
8609 install_element(VIEW_NODE
, &show_ip_mroute_vrf_all_cmd
);
8610 install_element(VIEW_NODE
, &show_ip_mroute_count_cmd
);
8611 install_element(VIEW_NODE
, &show_ip_mroute_count_vrf_all_cmd
);
8612 install_element(VIEW_NODE
, &show_ip_rib_cmd
);
8613 install_element(VIEW_NODE
, &show_ip_ssmpingd_cmd
);
8614 install_element(VIEW_NODE
, &show_debugging_pim_cmd
);
8615 install_element(VIEW_NODE
, &show_ip_pim_nexthop_cmd
);
8616 install_element(VIEW_NODE
, &show_ip_pim_nexthop_lookup_cmd
);
8618 install_element(ENABLE_NODE
, &clear_ip_interfaces_cmd
);
8619 install_element(ENABLE_NODE
, &clear_ip_igmp_interfaces_cmd
);
8620 install_element(ENABLE_NODE
, &clear_ip_mroute_cmd
);
8621 install_element(ENABLE_NODE
, &clear_ip_pim_interfaces_cmd
);
8622 install_element(ENABLE_NODE
, &clear_ip_pim_interface_traffic_cmd
);
8623 install_element(ENABLE_NODE
, &clear_ip_pim_oil_cmd
);
8625 install_element(ENABLE_NODE
, &debug_igmp_cmd
);
8626 install_element(ENABLE_NODE
, &no_debug_igmp_cmd
);
8627 install_element(ENABLE_NODE
, &debug_igmp_events_cmd
);
8628 install_element(ENABLE_NODE
, &no_debug_igmp_events_cmd
);
8629 install_element(ENABLE_NODE
, &debug_igmp_packets_cmd
);
8630 install_element(ENABLE_NODE
, &no_debug_igmp_packets_cmd
);
8631 install_element(ENABLE_NODE
, &debug_igmp_trace_cmd
);
8632 install_element(ENABLE_NODE
, &no_debug_igmp_trace_cmd
);
8633 install_element(ENABLE_NODE
, &debug_mroute_cmd
);
8634 install_element(ENABLE_NODE
, &debug_mroute_detail_cmd
);
8635 install_element(ENABLE_NODE
, &no_debug_mroute_cmd
);
8636 install_element(ENABLE_NODE
, &no_debug_mroute_detail_cmd
);
8637 install_element(ENABLE_NODE
, &debug_static_cmd
);
8638 install_element(ENABLE_NODE
, &no_debug_static_cmd
);
8639 install_element(ENABLE_NODE
, &debug_pim_cmd
);
8640 install_element(ENABLE_NODE
, &no_debug_pim_cmd
);
8641 install_element(ENABLE_NODE
, &debug_pim_nht_cmd
);
8642 install_element(ENABLE_NODE
, &no_debug_pim_nht_cmd
);
8643 install_element(ENABLE_NODE
, &debug_pim_nht_rp_cmd
);
8644 install_element(ENABLE_NODE
, &no_debug_pim_nht_rp_cmd
);
8645 install_element(ENABLE_NODE
, &debug_pim_events_cmd
);
8646 install_element(ENABLE_NODE
, &no_debug_pim_events_cmd
);
8647 install_element(ENABLE_NODE
, &debug_pim_packets_cmd
);
8648 install_element(ENABLE_NODE
, &no_debug_pim_packets_cmd
);
8649 install_element(ENABLE_NODE
, &debug_pim_packetdump_send_cmd
);
8650 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_send_cmd
);
8651 install_element(ENABLE_NODE
, &debug_pim_packetdump_recv_cmd
);
8652 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_recv_cmd
);
8653 install_element(ENABLE_NODE
, &debug_pim_trace_cmd
);
8654 install_element(ENABLE_NODE
, &no_debug_pim_trace_cmd
);
8655 install_element(ENABLE_NODE
, &debug_pim_trace_detail_cmd
);
8656 install_element(ENABLE_NODE
, &no_debug_pim_trace_detail_cmd
);
8657 install_element(ENABLE_NODE
, &debug_ssmpingd_cmd
);
8658 install_element(ENABLE_NODE
, &no_debug_ssmpingd_cmd
);
8659 install_element(ENABLE_NODE
, &debug_pim_zebra_cmd
);
8660 install_element(ENABLE_NODE
, &no_debug_pim_zebra_cmd
);
8661 install_element(ENABLE_NODE
, &debug_msdp_cmd
);
8662 install_element(ENABLE_NODE
, &no_debug_msdp_cmd
);
8663 install_element(ENABLE_NODE
, &undebug_msdp_cmd
);
8664 install_element(ENABLE_NODE
, &debug_msdp_events_cmd
);
8665 install_element(ENABLE_NODE
, &no_debug_msdp_events_cmd
);
8666 install_element(ENABLE_NODE
, &undebug_msdp_events_cmd
);
8667 install_element(ENABLE_NODE
, &debug_msdp_packets_cmd
);
8668 install_element(ENABLE_NODE
, &no_debug_msdp_packets_cmd
);
8669 install_element(ENABLE_NODE
, &undebug_msdp_packets_cmd
);
8671 install_element(CONFIG_NODE
, &debug_igmp_cmd
);
8672 install_element(CONFIG_NODE
, &no_debug_igmp_cmd
);
8673 install_element(CONFIG_NODE
, &debug_igmp_events_cmd
);
8674 install_element(CONFIG_NODE
, &no_debug_igmp_events_cmd
);
8675 install_element(CONFIG_NODE
, &debug_igmp_packets_cmd
);
8676 install_element(CONFIG_NODE
, &no_debug_igmp_packets_cmd
);
8677 install_element(CONFIG_NODE
, &debug_igmp_trace_cmd
);
8678 install_element(CONFIG_NODE
, &no_debug_igmp_trace_cmd
);
8679 install_element(CONFIG_NODE
, &debug_mroute_cmd
);
8680 install_element(CONFIG_NODE
, &debug_mroute_detail_cmd
);
8681 install_element(CONFIG_NODE
, &no_debug_mroute_cmd
);
8682 install_element(CONFIG_NODE
, &no_debug_mroute_detail_cmd
);
8683 install_element(CONFIG_NODE
, &debug_static_cmd
);
8684 install_element(CONFIG_NODE
, &no_debug_static_cmd
);
8685 install_element(CONFIG_NODE
, &debug_pim_cmd
);
8686 install_element(CONFIG_NODE
, &no_debug_pim_cmd
);
8687 install_element(CONFIG_NODE
, &debug_pim_nht_cmd
);
8688 install_element(CONFIG_NODE
, &no_debug_pim_nht_cmd
);
8689 install_element(CONFIG_NODE
, &debug_pim_nht_rp_cmd
);
8690 install_element(CONFIG_NODE
, &no_debug_pim_nht_rp_cmd
);
8691 install_element(CONFIG_NODE
, &debug_pim_events_cmd
);
8692 install_element(CONFIG_NODE
, &no_debug_pim_events_cmd
);
8693 install_element(CONFIG_NODE
, &debug_pim_packets_cmd
);
8694 install_element(CONFIG_NODE
, &no_debug_pim_packets_cmd
);
8695 install_element(CONFIG_NODE
, &debug_pim_trace_cmd
);
8696 install_element(CONFIG_NODE
, &no_debug_pim_trace_cmd
);
8697 install_element(CONFIG_NODE
, &debug_pim_trace_detail_cmd
);
8698 install_element(CONFIG_NODE
, &no_debug_pim_trace_detail_cmd
);
8699 install_element(CONFIG_NODE
, &debug_ssmpingd_cmd
);
8700 install_element(CONFIG_NODE
, &no_debug_ssmpingd_cmd
);
8701 install_element(CONFIG_NODE
, &debug_pim_zebra_cmd
);
8702 install_element(CONFIG_NODE
, &no_debug_pim_zebra_cmd
);
8703 install_element(CONFIG_NODE
, &debug_msdp_cmd
);
8704 install_element(CONFIG_NODE
, &no_debug_msdp_cmd
);
8705 install_element(CONFIG_NODE
, &undebug_msdp_cmd
);
8706 install_element(CONFIG_NODE
, &debug_msdp_events_cmd
);
8707 install_element(CONFIG_NODE
, &no_debug_msdp_events_cmd
);
8708 install_element(CONFIG_NODE
, &undebug_msdp_events_cmd
);
8709 install_element(CONFIG_NODE
, &debug_msdp_packets_cmd
);
8710 install_element(CONFIG_NODE
, &no_debug_msdp_packets_cmd
);
8711 install_element(CONFIG_NODE
, &undebug_msdp_packets_cmd
);
8713 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_member_cmd
);
8714 install_element(VRF_NODE
, &ip_msdp_mesh_group_member_cmd
);
8715 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
8716 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
8717 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_source_cmd
);
8718 install_element(VRF_NODE
, &ip_msdp_mesh_group_source_cmd
);
8719 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
8720 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
8721 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_cmd
);
8722 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_vrf_all_cmd
);
8723 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_cmd
);
8724 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_vrf_all_cmd
);
8725 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_cmd
);
8726 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_vrf_all_cmd
);
8727 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_cmd
);
8728 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_vrf_all_cmd
);
8729 install_element(VIEW_NODE
, &show_ip_pim_ssm_range_cmd
);
8730 install_element(VIEW_NODE
, &show_ip_pim_group_type_cmd
);
8731 install_element(INTERFACE_NODE
, &interface_pim_use_source_cmd
);
8732 install_element(INTERFACE_NODE
, &interface_no_pim_use_source_cmd
);
8733 /* Install BFD command */
8734 install_element(INTERFACE_NODE
, &ip_pim_bfd_cmd
);
8735 install_element(INTERFACE_NODE
, &ip_pim_bfd_param_cmd
);
8736 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_cmd
);
8737 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_param_cmd
);