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
)
1069 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
))
1072 if (!json_fhr_sources
)
1074 json_object_new_object();
1076 pim_inet4_dump("<src?>", up
->sg
.src
,
1077 src_str
, sizeof(src_str
));
1078 pim_inet4_dump("<grp?>", up
->sg
.grp
,
1079 grp_str
, sizeof(grp_str
));
1080 pim_time_uptime(uptime
, sizeof(uptime
),
1081 now
- up
->state_transition
);
1084 * Does this group live in json_fhr_sources?
1087 json_object_object_get_ex(json_fhr_sources
,
1092 json_group
= json_object_new_object();
1093 json_object_object_add(
1099 json_group_source
= json_object_new_object();
1100 json_object_string_add(json_group_source
,
1102 json_object_string_add(json_group_source
,
1104 json_object_string_add(json_group_source
,
1106 json_object_object_add(json_group
, src_str
,
1110 if (json_fhr_sources
) {
1111 json_object_object_add(json_row
,
1116 json_object_int_add(json_row
, "helloPeriod",
1117 pim_ifp
->pim_hello_period
);
1118 json_object_string_add(json_row
, "helloTimer",
1120 json_object_string_add(json_row
, "helloStatStart",
1122 json_object_int_add(json_row
, "helloReceived",
1123 pim_ifp
->pim_ifstat_hello_recv
);
1124 json_object_int_add(json_row
, "helloReceivedFailed",
1125 pim_ifp
->pim_ifstat_hello_recvfail
);
1126 json_object_int_add(json_row
, "helloSend",
1127 pim_ifp
->pim_ifstat_hello_sent
);
1128 json_object_int_add(json_row
, "hellosendFailed",
1129 pim_ifp
->pim_ifstat_hello_sendfail
);
1130 json_object_int_add(json_row
, "helloGenerationId",
1131 pim_ifp
->pim_generation_id
);
1132 json_object_int_add(json_row
, "flagMulticastLoop",
1135 json_object_int_add(
1136 json_row
, "effectivePropagationDelay",
1137 pim_if_effective_propagation_delay_msec(ifp
));
1138 json_object_int_add(
1139 json_row
, "effectiveOverrideInterval",
1140 pim_if_effective_override_interval_msec(ifp
));
1141 json_object_int_add(
1142 json_row
, "joinPruneOverrideInterval",
1143 pim_if_jp_override_interval_msec(ifp
));
1145 json_object_int_add(
1146 json_row
, "propagationDelay",
1147 pim_ifp
->pim_propagation_delay_msec
);
1148 json_object_int_add(
1149 json_row
, "propagationDelayHighest",
1150 pim_ifp
->pim_neighbors_highest_propagation_delay_msec
);
1151 json_object_int_add(
1152 json_row
, "overrideInterval",
1153 pim_ifp
->pim_override_interval_msec
);
1154 json_object_int_add(
1155 json_row
, "overrideIntervalHighest",
1156 pim_ifp
->pim_neighbors_highest_override_interval_msec
);
1157 json_object_object_add(json
, ifp
->name
, json_row
);
1160 vty_out(vty
, "Interface : %s\n", ifp
->name
);
1161 vty_out(vty
, "State : %s\n",
1162 if_is_up(ifp
) ? "up" : "down");
1163 if (pim_ifp
->update_source
.s_addr
!= INADDR_ANY
) {
1164 vty_out(vty
, "Use Source : %s\n",
1165 inet_ntoa(pim_ifp
->update_source
));
1167 if (pim_ifp
->sec_addr_list
) {
1168 char pbuf
[PREFIX2STR_BUFFER
];
1169 vty_out(vty
, "Address : %s (primary)\n",
1171 for (ALL_LIST_ELEMENTS_RO(
1172 pim_ifp
->sec_addr_list
, sec_node
,
1174 vty_out(vty
, " %s\n",
1175 prefix2str(&sec_addr
->addr
,
1176 pbuf
, sizeof(pbuf
)));
1179 vty_out(vty
, "Address : %s\n",
1187 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
,
1188 neighnode
, neigh
)) {
1191 vty_out(vty
, "PIM Neighbors\n");
1192 vty_out(vty
, "-------------\n");
1196 pim_inet4_dump("<src?>", neigh
->source_addr
,
1198 sizeof(neigh_src_str
));
1199 pim_time_uptime(uptime
, sizeof(uptime
),
1200 now
- neigh
->creation
);
1201 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
1202 neigh
->t_expire_timer
);
1204 "%-15s : up for %s, holdtime expires in %s\n",
1205 neigh_src_str
, uptime
, expire
);
1208 if (!print_header
) {
1213 vty_out(vty
, "Designated Router\n");
1214 vty_out(vty
, "-----------------\n");
1215 vty_out(vty
, "Address : %s\n", dr_str
);
1216 vty_out(vty
, "Priority : %d\n",
1217 pim_ifp
->pim_dr_priority
);
1218 vty_out(vty
, "Uptime : %s\n", dr_uptime
);
1219 vty_out(vty
, "Elections : %d\n",
1220 pim_ifp
->pim_dr_election_count
);
1221 vty_out(vty
, "Changes : %d\n",
1222 pim_ifp
->pim_dr_election_changes
);
1228 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
,
1231 if (strcmp(ifp
->name
,
1232 up
->rpf
.source_nexthop
.
1233 interface
->name
) != 0)
1236 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
))
1241 "FHR - First Hop Router\n");
1243 "----------------------\n");
1247 pim_inet4_dump("<src?>", up
->sg
.src
,
1248 src_str
, sizeof(src_str
));
1249 pim_inet4_dump("<grp?>", up
->sg
.grp
,
1250 grp_str
, sizeof(grp_str
));
1251 pim_time_uptime(uptime
, sizeof(uptime
),
1252 now
- up
->state_transition
);
1254 "%s : %s is a source, uptime is %s\n",
1259 if (!print_header
) {
1264 vty_out(vty
, "Hellos\n");
1265 vty_out(vty
, "------\n");
1266 vty_out(vty
, "Period : %d\n",
1267 pim_ifp
->pim_hello_period
);
1268 vty_out(vty
, "Timer : %s\n", hello_timer
);
1269 vty_out(vty
, "StatStart : %s\n", stat_uptime
);
1270 vty_out(vty
, "Receive : %d\n",
1271 pim_ifp
->pim_ifstat_hello_recv
);
1272 vty_out(vty
, "Receive Failed : %d\n",
1273 pim_ifp
->pim_ifstat_hello_recvfail
);
1274 vty_out(vty
, "Send : %d\n",
1275 pim_ifp
->pim_ifstat_hello_sent
);
1276 vty_out(vty
, "Send Failed : %d\n",
1277 pim_ifp
->pim_ifstat_hello_sendfail
);
1278 vty_out(vty
, "Generation ID : %08x\n",
1279 pim_ifp
->pim_generation_id
);
1283 pim_print_ifp_flags(vty
, ifp
, mloop
);
1285 vty_out(vty
, "Join Prune Interval\n");
1286 vty_out(vty
, "-------------------\n");
1287 vty_out(vty
, "LAN Delay : %s\n",
1288 pim_if_lan_delay_enabled(ifp
) ? "yes" : "no");
1289 vty_out(vty
, "Effective Propagation Delay : %d msec\n",
1290 pim_if_effective_propagation_delay_msec(ifp
));
1291 vty_out(vty
, "Effective Override Interval : %d msec\n",
1292 pim_if_effective_override_interval_msec(ifp
));
1293 vty_out(vty
, "Join Prune Override Interval : %d msec\n",
1294 pim_if_jp_override_interval_msec(ifp
));
1298 vty_out(vty
, "LAN Prune Delay\n");
1299 vty_out(vty
, "---------------\n");
1300 vty_out(vty
, "Propagation Delay : %d msec\n",
1301 pim_ifp
->pim_propagation_delay_msec
);
1302 vty_out(vty
, "Propagation Delay (Highest) : %d msec\n",
1303 pim_ifp
->pim_neighbors_highest_propagation_delay_msec
);
1304 vty_out(vty
, "Override Interval : %d msec\n",
1305 pim_ifp
->pim_override_interval_msec
);
1306 vty_out(vty
, "Override Interval (Highest) : %d msec\n",
1307 pim_ifp
->pim_neighbors_highest_override_interval_msec
);
1314 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1315 json
, JSON_C_TO_STRING_PRETTY
));
1316 json_object_free(json
);
1319 vty_out(vty
, "%% No such interface\n");
1323 static void pim_show_interfaces(struct pim_instance
*pim
, struct vty
*vty
,
1326 struct interface
*ifp
;
1327 struct listnode
*node
;
1328 struct listnode
*upnode
;
1329 struct pim_interface
*pim_ifp
;
1330 struct pim_upstream
*up
;
1333 int pim_ifchannels
= 0;
1334 json_object
*json
= NULL
;
1335 json_object
*json_row
= NULL
;
1336 json_object
*json_tmp
;
1338 json
= json_object_new_object();
1340 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim
->vrf_id
), node
, ifp
)) {
1341 pim_ifp
= ifp
->info
;
1346 pim_nbrs
= pim_ifp
->pim_neighbor_list
->count
;
1347 pim_ifchannels
= pim_if_ifchannel_count(pim_ifp
);
1350 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
, up
))
1351 if (ifp
== up
->rpf
.source_nexthop
.interface
)
1352 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
1355 json_row
= json_object_new_object();
1356 json_object_pim_ifp_add(json_row
, ifp
);
1357 json_object_int_add(json_row
, "pimNeighbors", pim_nbrs
);
1358 json_object_int_add(json_row
, "pimIfChannels", pim_ifchannels
);
1359 json_object_int_add(json_row
, "firstHopRouterCount", fhr
);
1360 json_object_string_add(json_row
, "pimDesignatedRouter",
1361 inet_ntoa(pim_ifp
->pim_dr_addr
));
1363 if (pim_ifp
->pim_dr_addr
.s_addr
1364 == pim_ifp
->primary_address
.s_addr
)
1365 json_object_boolean_true_add(
1366 json_row
, "pimDesignatedRouterLocal");
1368 json_object_object_add(json
, ifp
->name
, json_row
);
1372 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1373 json
, JSON_C_TO_STRING_PRETTY
));
1376 "Interface State Address PIM Nbrs PIM DR FHR IfChannels\n");
1378 json_object_object_foreach(json
, key
, val
)
1380 vty_out(vty
, "%-9s ", key
);
1382 json_object_object_get_ex(val
, "state", &json_tmp
);
1383 vty_out(vty
, "%5s ", json_object_get_string(json_tmp
));
1385 json_object_object_get_ex(val
, "address", &json_tmp
);
1386 vty_out(vty
, "%15s ",
1387 json_object_get_string(json_tmp
));
1389 json_object_object_get_ex(val
, "pimNeighbors",
1391 vty_out(vty
, "%8d ", json_object_get_int(json_tmp
));
1393 if (json_object_object_get_ex(
1394 val
, "pimDesignatedRouterLocal",
1396 vty_out(vty
, "%15s ", "local");
1398 json_object_object_get_ex(
1399 val
, "pimDesignatedRouter", &json_tmp
);
1400 vty_out(vty
, "%15s ",
1401 json_object_get_string(json_tmp
));
1404 json_object_object_get_ex(val
, "firstHopRouter",
1406 vty_out(vty
, "%3d ", json_object_get_int(json_tmp
));
1408 json_object_object_get_ex(val
, "pimIfChannels",
1410 vty_out(vty
, "%9d\n", json_object_get_int(json_tmp
));
1414 json_object_free(json
);
1417 static void pim_show_interface_traffic(struct pim_instance
*pim
,
1418 struct vty
*vty
, u_char uj
)
1420 struct interface
*ifp
= NULL
;
1421 struct pim_interface
*pim_ifp
= NULL
;
1422 struct listnode
*node
= NULL
;
1423 json_object
*json
= NULL
;
1424 json_object
*json_row
= NULL
;
1427 json
= json_object_new_object();
1430 vty_out(vty
, "%-12s%-17s%-17s%-17s%-17s%-17s%-17s\n",
1431 "Interface", " HELLO", " JOIN", " PRUNE",
1432 " REGISTER", " REGISTER-STOP", " ASSERT");
1433 vty_out(vty
, "%-10s%-18s%-17s%-17s%-17s%-17s%-17s\n", "",
1434 " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1435 " Rx/Tx", " Rx/Tx");
1437 "---------------------------------------------------------------------------------------------------------------\n");
1440 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim
->vrf_id
), node
, ifp
)) {
1441 pim_ifp
= ifp
->info
;
1446 if (pim_ifp
->pim_sock_fd
< 0)
1449 json_row
= json_object_new_object();
1450 json_object_pim_ifp_add(json_row
, ifp
);
1451 json_object_int_add(json_row
, "helloRx",
1452 pim_ifp
->pim_ifstat_hello_recv
);
1453 json_object_int_add(json_row
, "helloTx",
1454 pim_ifp
->pim_ifstat_hello_sent
);
1455 json_object_int_add(json_row
, "joinRx",
1456 pim_ifp
->pim_ifstat_join_recv
);
1457 json_object_int_add(json_row
, "joinTx",
1458 pim_ifp
->pim_ifstat_join_send
);
1459 json_object_int_add(json_row
, "registerRx",
1460 pim_ifp
->pim_ifstat_reg_recv
);
1461 json_object_int_add(json_row
, "registerTx",
1462 pim_ifp
->pim_ifstat_reg_recv
);
1463 json_object_int_add(json_row
, "registerStopRx",
1464 pim_ifp
->pim_ifstat_reg_stop_recv
);
1465 json_object_int_add(json_row
, "registerStopTx",
1466 pim_ifp
->pim_ifstat_reg_stop_send
);
1467 json_object_int_add(json_row
, "assertRx",
1468 pim_ifp
->pim_ifstat_assert_recv
);
1469 json_object_int_add(json_row
, "assertTx",
1470 pim_ifp
->pim_ifstat_assert_send
);
1472 json_object_object_add(json
, ifp
->name
, json_row
);
1475 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u \n",
1476 ifp
->name
, pim_ifp
->pim_ifstat_hello_recv
,
1477 pim_ifp
->pim_ifstat_hello_sent
,
1478 pim_ifp
->pim_ifstat_join_recv
,
1479 pim_ifp
->pim_ifstat_join_send
,
1480 pim_ifp
->pim_ifstat_prune_recv
,
1481 pim_ifp
->pim_ifstat_prune_send
,
1482 pim_ifp
->pim_ifstat_reg_recv
,
1483 pim_ifp
->pim_ifstat_reg_send
,
1484 pim_ifp
->pim_ifstat_reg_stop_recv
,
1485 pim_ifp
->pim_ifstat_reg_stop_send
,
1486 pim_ifp
->pim_ifstat_assert_recv
,
1487 pim_ifp
->pim_ifstat_assert_send
);
1491 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1492 json
, JSON_C_TO_STRING_PRETTY
));
1493 json_object_free(json
);
1497 static void pim_show_interface_traffic_single(struct pim_instance
*pim
,
1499 const char *ifname
, u_char uj
)
1501 struct interface
*ifp
= NULL
;
1502 struct pim_interface
*pim_ifp
= NULL
;
1503 struct listnode
*node
= NULL
;
1504 json_object
*json
= NULL
;
1505 json_object
*json_row
= NULL
;
1506 uint8_t found_ifname
= 0;
1509 json
= json_object_new_object();
1512 vty_out(vty
, "%-12s%-17s%-17s%-17s%-17s%-17s%-17s\n",
1513 "Interface", " HELLO", " JOIN", " PRUNE",
1514 " REGISTER", " REGISTER-STOP", " ASSERT");
1515 vty_out(vty
, "%-10s%-18s%-17s%-17s%-17s%-17s%-17s\n", "",
1516 " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1517 " Rx/Tx", " Rx/Tx");
1519 "---------------------------------------------------------------------------------------------------------------\n");
1522 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim
->vrf_id
), node
, ifp
)) {
1523 if (strcmp(ifname
, ifp
->name
))
1526 pim_ifp
= ifp
->info
;
1531 if (pim_ifp
->pim_sock_fd
< 0)
1536 json_row
= json_object_new_object();
1537 json_object_pim_ifp_add(json_row
, ifp
);
1538 json_object_int_add(json_row
, "helloRx",
1539 pim_ifp
->pim_ifstat_hello_recv
);
1540 json_object_int_add(json_row
, "helloTx",
1541 pim_ifp
->pim_ifstat_hello_sent
);
1542 json_object_int_add(json_row
, "joinRx",
1543 pim_ifp
->pim_ifstat_join_recv
);
1544 json_object_int_add(json_row
, "joinTx",
1545 pim_ifp
->pim_ifstat_join_send
);
1546 json_object_int_add(json_row
, "registerRx",
1547 pim_ifp
->pim_ifstat_reg_recv
);
1548 json_object_int_add(json_row
, "registerTx",
1549 pim_ifp
->pim_ifstat_reg_recv
);
1550 json_object_int_add(json_row
, "registerStopRx",
1551 pim_ifp
->pim_ifstat_reg_stop_recv
);
1552 json_object_int_add(json_row
, "registerStopTx",
1553 pim_ifp
->pim_ifstat_reg_stop_send
);
1554 json_object_int_add(json_row
, "assertRx",
1555 pim_ifp
->pim_ifstat_assert_recv
);
1556 json_object_int_add(json_row
, "assertTx",
1557 pim_ifp
->pim_ifstat_assert_send
);
1559 json_object_object_add(json
, ifp
->name
, json_row
);
1562 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u \n",
1563 ifp
->name
, pim_ifp
->pim_ifstat_hello_recv
,
1564 pim_ifp
->pim_ifstat_hello_sent
,
1565 pim_ifp
->pim_ifstat_join_recv
,
1566 pim_ifp
->pim_ifstat_join_send
,
1567 pim_ifp
->pim_ifstat_prune_recv
,
1568 pim_ifp
->pim_ifstat_prune_send
,
1569 pim_ifp
->pim_ifstat_reg_recv
,
1570 pim_ifp
->pim_ifstat_reg_send
,
1571 pim_ifp
->pim_ifstat_reg_stop_recv
,
1572 pim_ifp
->pim_ifstat_reg_stop_send
,
1573 pim_ifp
->pim_ifstat_assert_recv
,
1574 pim_ifp
->pim_ifstat_assert_send
);
1578 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1579 json
, JSON_C_TO_STRING_PRETTY
));
1580 json_object_free(json
);
1583 vty_out(vty
, "%% No such interface\n");
1587 static void pim_show_join_helper(struct vty
*vty
,
1588 struct pim_interface
*pim_ifp
,
1589 struct pim_ifchannel
*ch
,
1594 char ch_src_str
[INET_ADDRSTRLEN
];
1595 char ch_grp_str
[INET_ADDRSTRLEN
];
1596 json_object
*json_iface
= NULL
;
1597 json_object
*json_row
= NULL
;
1598 json_object
*json_grp
= NULL
;
1599 struct in_addr ifaddr
;
1604 ifaddr
= pim_ifp
->primary_address
;
1606 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
,
1607 sizeof(ch_src_str
));
1608 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
,
1609 sizeof(ch_grp_str
));
1611 pim_time_uptime_begin(uptime
, sizeof(uptime
), now
,
1612 ch
->ifjoin_creation
);
1613 pim_time_timer_to_mmss(expire
, sizeof(expire
),
1614 ch
->t_ifjoin_expiry_timer
);
1615 pim_time_timer_to_mmss(prune
, sizeof(prune
),
1616 ch
->t_ifjoin_prune_pending_timer
);
1619 json_object_object_get_ex(json
, ch
->interface
->name
,
1623 json_iface
= json_object_new_object();
1624 json_object_pim_ifp_add(json_iface
,
1626 json_object_object_add(
1627 json
, ch
->interface
->name
, json_iface
);
1630 json_row
= json_object_new_object();
1631 json_object_string_add(json_row
, "source", ch_src_str
);
1632 json_object_string_add(json_row
, "group", ch_grp_str
);
1633 json_object_string_add(json_row
, "upTime", uptime
);
1634 json_object_string_add(json_row
, "expire", expire
);
1635 json_object_string_add(json_row
, "prune", prune
);
1636 json_object_string_add(
1637 json_row
, "channelJoinName",
1638 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
,
1640 if (PIM_IF_FLAG_TEST_S_G_RPT(ch
->flags
))
1641 json_object_int_add(json_row
, "SGRpt", 1);
1643 json_object_object_get_ex(json_iface
, ch_grp_str
,
1646 json_grp
= json_object_new_object();
1647 json_object_object_add(json_grp
, ch_src_str
,
1649 json_object_object_add(json_iface
, ch_grp_str
,
1652 json_object_object_add(json_grp
, ch_src_str
,
1656 "%-9s %-15s %-15s %-15s %-10s %8s %-6s %5s\n",
1657 ch
->interface
->name
, inet_ntoa(ifaddr
),
1658 ch_src_str
, ch_grp_str
,
1659 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
,
1661 uptime
, expire
, prune
);
1665 static void pim_show_join(struct pim_instance
*pim
, struct vty
*vty
, u_char uj
)
1667 struct listnode
*if_node
;
1668 struct pim_interface
*pim_ifp
;
1669 struct pim_ifchannel
*ch
;
1670 struct interface
*ifp
;
1672 json_object
*json
= NULL
;
1674 now
= pim_time_monotonic_sec();
1677 json
= json_object_new_object();
1680 "Interface Address Source Group State Uptime Expire Prune\n");
1682 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim
->vrf_id
), if_node
, ifp
)) {
1683 pim_ifp
= ifp
->info
;
1687 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
1688 pim_show_join_helper(vty
, pim_ifp
, ch
, json
, now
, uj
);
1689 } /* scan interface channels */
1693 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1694 json
, JSON_C_TO_STRING_PRETTY
));
1695 json_object_free(json
);
1699 static void pim_show_neighbors_single(struct pim_instance
*pim
, struct vty
*vty
,
1700 const char *neighbor
, u_char uj
)
1702 struct listnode
*node
;
1703 struct listnode
*neighnode
;
1704 struct interface
*ifp
;
1705 struct pim_interface
*pim_ifp
;
1706 struct pim_neighbor
*neigh
;
1708 int found_neighbor
= 0;
1709 int option_address_list
;
1710 int option_dr_priority
;
1711 int option_generation_id
;
1712 int option_holdtime
;
1713 int option_lan_prune_delay
;
1717 char neigh_src_str
[INET_ADDRSTRLEN
];
1719 json_object
*json
= NULL
;
1720 json_object
*json_ifp
= NULL
;
1721 json_object
*json_row
= NULL
;
1723 now
= pim_time_monotonic_sec();
1726 json
= json_object_new_object();
1728 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim
->vrf_id
), node
, ifp
)) {
1729 pim_ifp
= ifp
->info
;
1734 if (pim_ifp
->pim_sock_fd
< 0)
1737 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
1739 pim_inet4_dump("<src?>", neigh
->source_addr
,
1740 neigh_src_str
, sizeof(neigh_src_str
));
1743 * The user can specify either the interface name or the
1745 * If this pim_ifp matches neither then skip.
1747 if (strcmp(neighbor
, "detail")
1748 && strcmp(neighbor
, ifp
->name
)
1749 && strcmp(neighbor
, neigh_src_str
))
1753 pim_time_uptime(uptime
, sizeof(uptime
),
1754 now
- neigh
->creation
);
1755 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
1756 neigh
->t_expire_timer
);
1758 option_address_list
= 0;
1759 option_dr_priority
= 0;
1760 option_generation_id
= 0;
1761 option_holdtime
= 0;
1762 option_lan_prune_delay
= 0;
1765 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1766 PIM_OPTION_MASK_ADDRESS_LIST
))
1767 option_address_list
= 1;
1769 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1770 PIM_OPTION_MASK_DR_PRIORITY
))
1771 option_dr_priority
= 1;
1773 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1774 PIM_OPTION_MASK_GENERATION_ID
))
1775 option_generation_id
= 1;
1777 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1778 PIM_OPTION_MASK_HOLDTIME
))
1779 option_holdtime
= 1;
1781 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1782 PIM_OPTION_MASK_LAN_PRUNE_DELAY
))
1783 option_lan_prune_delay
= 1;
1785 if (PIM_OPTION_IS_SET(
1786 neigh
->hello_options
,
1787 PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION
))
1792 /* Does this ifp live in json? If not create
1794 json_object_object_get_ex(json
, ifp
->name
,
1798 json_ifp
= json_object_new_object();
1799 json_object_pim_ifp_add(json_ifp
, ifp
);
1800 json_object_object_add(json
, ifp
->name
,
1804 json_row
= json_object_new_object();
1805 json_object_string_add(json_row
, "interface",
1807 json_object_string_add(json_row
, "address",
1809 json_object_string_add(json_row
, "upTime",
1811 json_object_string_add(json_row
, "holdtime",
1813 json_object_int_add(json_row
, "drPriority",
1814 neigh
->dr_priority
);
1815 json_object_int_add(json_row
, "generationId",
1816 neigh
->generation_id
);
1818 if (option_address_list
)
1819 json_object_boolean_true_add(
1821 "helloOptionAddressList");
1823 if (option_dr_priority
)
1824 json_object_boolean_true_add(
1826 "helloOptionDrPriority");
1828 if (option_generation_id
)
1829 json_object_boolean_true_add(
1831 "helloOptionGenerationId");
1833 if (option_holdtime
)
1834 json_object_boolean_true_add(
1836 "helloOptionHoldtime");
1838 if (option_lan_prune_delay
)
1839 json_object_boolean_true_add(
1841 "helloOptionLanPruneDelay");
1844 json_object_boolean_true_add(
1845 json_row
, "helloOptionTBit");
1847 json_object_object_add(json_ifp
, neigh_src_str
,
1851 vty_out(vty
, "Interface : %s\n", ifp
->name
);
1852 vty_out(vty
, "Neighbor : %s\n", neigh_src_str
);
1860 " DR Priority : %d\n",
1861 neigh
->dr_priority
);
1863 " Generation ID : %08x\n",
1864 neigh
->generation_id
);
1866 " Override Interval (msec) : %d\n",
1867 neigh
->override_interval_msec
);
1869 " Propagation Delay (msec) : %d\n",
1870 neigh
->propagation_delay_msec
);
1872 " Hello Option - Address List : %s\n",
1873 option_address_list
? "yes" : "no");
1875 " Hello Option - DR Priority : %s\n",
1876 option_dr_priority
? "yes" : "no");
1878 " Hello Option - Generation ID : %s\n",
1879 option_generation_id
? "yes" : "no");
1881 " Hello Option - Holdtime : %s\n",
1882 option_holdtime
? "yes" : "no");
1884 " Hello Option - LAN Prune Delay : %s\n",
1885 option_lan_prune_delay
? "yes" : "no");
1887 " Hello Option - T-bit : %s\n",
1888 option_t_bit
? "yes" : "no");
1889 pim_bfd_show_info(vty
, neigh
->bfd_info
,
1897 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1898 json
, JSON_C_TO_STRING_PRETTY
));
1899 json_object_free(json
);
1902 if (!found_neighbor
)
1904 "%% No such interface or neighbor\n");
1909 static void pim_show_state(struct pim_instance
*pim
, struct vty
*vty
,
1910 const char *src_or_group
, const char *group
,
1913 struct channel_oil
*c_oil
;
1914 struct listnode
*node
;
1915 json_object
*json
= NULL
;
1916 json_object
*json_group
= NULL
;
1917 json_object
*json_ifp_in
= NULL
;
1918 json_object
*json_ifp_out
= NULL
;
1919 json_object
*json_source
= NULL
;
1922 now
= pim_time_monotonic_sec();
1925 json
= json_object_new_object();
1928 "Codes: J -> Pim Join, I -> IGMP Report, S -> Source, * -> Inherited from (*,G)");
1930 "\nInstalled Source Group IIF OIL\n");
1933 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
1934 char grp_str
[INET_ADDRSTRLEN
];
1935 char src_str
[INET_ADDRSTRLEN
];
1936 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
1937 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
1939 struct interface
*ifp_in
;
1942 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
1944 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
1946 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
1949 strcpy(in_ifname
, ifp_in
->name
);
1951 strcpy(in_ifname
, "<iif?>");
1954 if (strcmp(src_or_group
, src_str
)
1955 && strcmp(src_or_group
, grp_str
))
1958 if (group
&& strcmp(group
, grp_str
))
1964 /* Find the group, create it if it doesn't exist */
1965 json_object_object_get_ex(json
, grp_str
, &json_group
);
1968 json_group
= json_object_new_object();
1969 json_object_object_add(json
, grp_str
,
1973 /* Find the source nested under the group, create it if
1974 * it doesn't exist */
1975 json_object_object_get_ex(json_group
, src_str
,
1979 json_source
= json_object_new_object();
1980 json_object_object_add(json_group
, src_str
,
1984 /* Find the inbound interface nested under the source,
1985 * create it if it doesn't exist */
1986 json_object_object_get_ex(json_source
, in_ifname
,
1990 json_ifp_in
= json_object_new_object();
1991 json_object_object_add(json_source
, in_ifname
,
1993 json_object_int_add(json_source
, "Installed",
1995 json_object_int_add(json_source
, "RefCount",
1996 c_oil
->oil_ref_count
);
1997 json_object_int_add(json_source
, "OilListSize",
1999 json_object_int_add(
2000 json_source
, "OilRescan",
2001 c_oil
->oil_inherited_rescan
);
2002 json_object_int_add(json_source
, "LastUsed",
2003 c_oil
->cc
.lastused
);
2004 json_object_int_add(json_source
, "PacketCount",
2006 json_object_int_add(json_source
, "ByteCount",
2008 json_object_int_add(json_source
,
2010 c_oil
->cc
.wrong_if
);
2013 vty_out(vty
, "%-9d %-15s %-15s %-7s ",
2014 c_oil
->installed
, src_str
, grp_str
,
2018 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
2020 struct interface
*ifp_out
;
2021 char oif_uptime
[10];
2024 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
2028 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
2030 oif_uptime
, sizeof(oif_uptime
),
2031 now
- c_oil
->oif_creation
[oif_vif_index
]);
2034 strcpy(out_ifname
, ifp_out
->name
);
2036 strcpy(out_ifname
, "<oif?>");
2039 json_ifp_out
= json_object_new_object();
2040 json_object_string_add(json_ifp_out
, "source",
2042 json_object_string_add(json_ifp_out
, "group",
2044 json_object_string_add(json_ifp_out
,
2047 json_object_string_add(json_ifp_out
,
2048 "outboundInterface",
2050 json_object_int_add(json_ifp_out
, "installed",
2053 json_object_object_add(json_ifp_in
, out_ifname
,
2058 vty_out(vty
, "%s(%c%c%c%c)", out_ifname
,
2059 (c_oil
->oif_flags
[oif_vif_index
]
2060 & PIM_OIF_FLAG_PROTO_IGMP
)
2063 (c_oil
->oif_flags
[oif_vif_index
]
2064 & PIM_OIF_FLAG_PROTO_PIM
)
2067 (c_oil
->oif_flags
[oif_vif_index
]
2068 & PIM_OIF_FLAG_PROTO_SOURCE
)
2071 (c_oil
->oif_flags
[oif_vif_index
]
2072 & PIM_OIF_FLAG_PROTO_STAR
)
2076 vty_out(vty
, ", %s(%c%c%c%c)",
2078 (c_oil
->oif_flags
[oif_vif_index
]
2079 & PIM_OIF_FLAG_PROTO_IGMP
)
2082 (c_oil
->oif_flags
[oif_vif_index
]
2083 & PIM_OIF_FLAG_PROTO_PIM
)
2086 (c_oil
->oif_flags
[oif_vif_index
]
2087 & PIM_OIF_FLAG_PROTO_SOURCE
)
2090 (c_oil
->oif_flags
[oif_vif_index
]
2091 & PIM_OIF_FLAG_PROTO_STAR
)
2103 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2104 json
, JSON_C_TO_STRING_PRETTY
));
2105 json_object_free(json
);
2111 static void pim_show_neighbors(struct pim_instance
*pim
, struct vty
*vty
,
2114 struct listnode
*node
;
2115 struct listnode
*neighnode
;
2116 struct interface
*ifp
;
2117 struct pim_interface
*pim_ifp
;
2118 struct pim_neighbor
*neigh
;
2122 char neigh_src_str
[INET_ADDRSTRLEN
];
2123 json_object
*json
= NULL
;
2124 json_object
*json_ifp_rows
= NULL
;
2125 json_object
*json_row
= NULL
;
2127 now
= pim_time_monotonic_sec();
2130 json
= json_object_new_object();
2133 "Interface Neighbor Uptime Holdtime DR Pri\n");
2136 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim
->vrf_id
), node
, ifp
)) {
2137 pim_ifp
= ifp
->info
;
2142 if (pim_ifp
->pim_sock_fd
< 0)
2146 json_ifp_rows
= json_object_new_object();
2148 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
2150 pim_inet4_dump("<src?>", neigh
->source_addr
,
2151 neigh_src_str
, sizeof(neigh_src_str
));
2152 pim_time_uptime(uptime
, sizeof(uptime
),
2153 now
- neigh
->creation
);
2154 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
2155 neigh
->t_expire_timer
);
2158 json_row
= json_object_new_object();
2159 json_object_string_add(json_row
, "interface",
2161 json_object_string_add(json_row
, "neighbor",
2163 json_object_string_add(json_row
, "upTime",
2165 json_object_string_add(json_row
, "holdTime",
2167 json_object_int_add(json_row
, "holdTimeMax",
2169 json_object_int_add(json_row
, "drPriority",
2170 neigh
->dr_priority
);
2171 json_object_object_add(json_ifp_rows
,
2172 neigh_src_str
, json_row
);
2175 vty_out(vty
, "%-9s %15s %8s %8s %6d\n",
2176 ifp
->name
, neigh_src_str
, uptime
,
2177 expire
, neigh
->dr_priority
);
2182 json_object_object_add(json
, ifp
->name
, json_ifp_rows
);
2183 json_ifp_rows
= NULL
;
2188 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2189 json
, JSON_C_TO_STRING_PRETTY
));
2190 json_object_free(json
);
2194 static void pim_show_neighbors_secondary(struct pim_instance
*pim
,
2197 struct listnode
*node
;
2198 struct interface
*ifp
;
2201 "Interface Address Neighbor Secondary \n");
2203 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim
->vrf_id
), node
, ifp
)) {
2204 struct pim_interface
*pim_ifp
;
2205 struct in_addr ifaddr
;
2206 struct listnode
*neighnode
;
2207 struct pim_neighbor
*neigh
;
2209 pim_ifp
= ifp
->info
;
2214 if (pim_ifp
->pim_sock_fd
< 0)
2217 ifaddr
= pim_ifp
->primary_address
;
2219 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
2221 char neigh_src_str
[INET_ADDRSTRLEN
];
2222 struct listnode
*prefix_node
;
2225 if (!neigh
->prefix_list
)
2228 pim_inet4_dump("<src?>", neigh
->source_addr
,
2229 neigh_src_str
, sizeof(neigh_src_str
));
2231 for (ALL_LIST_ELEMENTS_RO(neigh
->prefix_list
,
2233 char neigh_sec_str
[PREFIX2STR_BUFFER
];
2235 prefix2str(p
, neigh_sec_str
,
2236 sizeof(neigh_sec_str
));
2238 vty_out(vty
, "%-9s %-15s %-15s %-15s\n",
2239 ifp
->name
, inet_ntoa(ifaddr
),
2240 neigh_src_str
, neigh_sec_str
);
2246 static void json_object_pim_upstream_add(json_object
*json
,
2247 struct pim_upstream
*up
)
2249 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED
)
2250 json_object_boolean_true_add(json
, "drJoinDesired");
2252 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED
)
2253 json_object_boolean_true_add(json
, "drJoinDesiredUpdated");
2255 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
2256 json_object_boolean_true_add(json
, "firstHopRouter");
2258 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_IGMP
)
2259 json_object_boolean_true_add(json
, "sourceIgmp");
2261 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_PIM
)
2262 json_object_boolean_true_add(json
, "sourcePim");
2264 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_STREAM
)
2265 json_object_boolean_true_add(json
, "sourceStream");
2267 /* XXX: need to print ths flag in the plain text display as well */
2268 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_MSDP
)
2269 json_object_boolean_true_add(json
, "sourceMsdp");
2273 pim_upstream_state2brief_str(enum pim_upstream_state join_state
,
2276 switch (join_state
) {
2277 case PIM_UPSTREAM_NOTJOINED
:
2278 strcpy(state_str
, "NotJ");
2280 case PIM_UPSTREAM_JOINED
:
2281 strcpy(state_str
, "J");
2284 strcpy(state_str
, "Unk");
2289 static const char *pim_reg_state2brief_str(enum pim_reg_state reg_state
,
2292 switch (reg_state
) {
2293 case PIM_REG_NOINFO
:
2294 strcpy(state_str
, "RegNI");
2297 strcpy(state_str
, "RegJ");
2299 case PIM_REG_JOIN_PENDING
:
2301 strcpy(state_str
, "RegP");
2304 strcpy(state_str
, "Unk");
2309 static void pim_show_upstream(struct pim_instance
*pim
, struct vty
*vty
,
2312 struct listnode
*upnode
;
2313 struct pim_upstream
*up
;
2315 json_object
*json
= NULL
;
2316 json_object
*json_group
= NULL
;
2317 json_object
*json_row
= NULL
;
2319 now
= pim_time_monotonic_sec();
2322 json
= json_object_new_object();
2325 "Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt\n");
2327 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
, up
)) {
2328 char src_str
[INET_ADDRSTRLEN
];
2329 char grp_str
[INET_ADDRSTRLEN
];
2331 char join_timer
[10];
2334 char msdp_reg_timer
[10];
2335 char state_str
[PIM_REG_STATE_STR_LEN
];
2337 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2338 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2339 pim_time_uptime(uptime
, sizeof(uptime
),
2340 now
- up
->state_transition
);
2341 pim_time_timer_to_hhmmss(join_timer
, sizeof(join_timer
),
2345 * If we have a J/P timer for the neighbor display that
2347 if (!up
->t_join_timer
) {
2348 struct pim_neighbor
*nbr
;
2350 nbr
= pim_neighbor_find(
2351 up
->rpf
.source_nexthop
.interface
,
2352 up
->rpf
.rpf_addr
.u
.prefix4
);
2354 pim_time_timer_to_hhmmss(join_timer
,
2359 pim_time_timer_to_hhmmss(rs_timer
, sizeof(rs_timer
),
2361 pim_time_timer_to_hhmmss(ka_timer
, sizeof(ka_timer
),
2363 pim_time_timer_to_hhmmss(msdp_reg_timer
, sizeof(msdp_reg_timer
),
2364 up
->t_msdp_reg_timer
);
2366 pim_upstream_state2brief_str(up
->join_state
, state_str
);
2367 if (up
->reg_state
!= PIM_REG_NOINFO
) {
2368 char tmp_str
[PIM_REG_STATE_STR_LEN
];
2370 sprintf(state_str
+ strlen(state_str
), ",%s",
2371 pim_reg_state2brief_str(up
->reg_state
,
2376 json_object_object_get_ex(json
, grp_str
, &json_group
);
2379 json_group
= json_object_new_object();
2380 json_object_object_add(json
, grp_str
,
2384 json_row
= json_object_new_object();
2385 json_object_pim_upstream_add(json_row
, up
);
2386 json_object_string_add(
2387 json_row
, "inboundInterface",
2388 up
->rpf
.source_nexthop
.interface
->name
);
2391 * The RPF address we use is slightly different
2392 * based upon what we are looking up.
2393 * If we have a S, list that unless
2394 * we are the FHR, else we just put
2395 * the RP as the rpfAddress
2397 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
||
2398 up
->sg
.src
.s_addr
== INADDR_ANY
) {
2399 char rpf
[PREFIX_STRLEN
];
2400 struct pim_rpf
*rpg
;
2402 rpg
= RP(pim
, up
->sg
.grp
);
2403 pim_inet4_dump("<rpf?>",
2404 rpg
->rpf_addr
.u
.prefix4
,
2406 json_object_string_add(json_row
,
2409 json_object_string_add(json_row
,
2410 "rpfAddress", src_str
);
2413 json_object_string_add(json_row
, "source", src_str
);
2414 json_object_string_add(json_row
, "group", grp_str
);
2415 json_object_string_add(json_row
, "state", state_str
);
2416 json_object_string_add(
2417 json_row
, "joinState",
2418 pim_upstream_state2str(up
->join_state
));
2419 json_object_string_add(
2420 json_row
, "regState",
2421 pim_reg_state2str(up
->reg_state
, state_str
));
2422 json_object_string_add(json_row
, "upTime", uptime
);
2423 json_object_string_add(json_row
, "joinTimer",
2425 json_object_string_add(json_row
, "resetTimer",
2427 json_object_string_add(json_row
, "keepaliveTimer",
2429 json_object_string_add(json_row
, "msdpRegTimer",
2431 json_object_int_add(json_row
, "refCount",
2433 json_object_int_add(json_row
, "sptBit", up
->sptbit
);
2434 json_object_object_add(json_group
, src_str
, json_row
);
2437 "%-10s%-15s %-15s %-11s %-8s %-9s %-9s %-9s %6d\n",
2438 up
->rpf
.source_nexthop
.interface
->name
, src_str
,
2439 grp_str
, state_str
, uptime
, join_timer
,
2440 rs_timer
, ka_timer
, up
->ref_count
);
2445 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2446 json
, JSON_C_TO_STRING_PRETTY
));
2447 json_object_free(json
);
2451 static void pim_show_join_desired_helper(struct pim_instance
*pim
,
2453 struct pim_interface
*pim_ifp
,
2454 struct pim_ifchannel
*ch
,
2458 struct pim_upstream
*up
= ch
->upstream
;
2459 json_object
*json_group
= NULL
;
2460 char src_str
[INET_ADDRSTRLEN
];
2461 char grp_str
[INET_ADDRSTRLEN
];
2462 json_object
*json_row
= NULL
;
2464 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2465 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2468 json_object_object_get_ex(json
, grp_str
, &json_group
);
2471 json_group
= json_object_new_object();
2472 json_object_object_add(json
, grp_str
,
2476 json_row
= json_object_new_object();
2477 json_object_pim_upstream_add(json_row
, up
);
2478 json_object_string_add(json_row
, "interface",
2479 ch
->interface
->name
);
2480 json_object_string_add(json_row
, "source", src_str
);
2481 json_object_string_add(json_row
, "group", grp_str
);
2483 if (pim_macro_ch_lost_assert(ch
))
2484 json_object_boolean_true_add(json_row
,
2487 if (pim_macro_chisin_joins(ch
))
2488 json_object_boolean_true_add(json_row
, "joins");
2490 if (pim_macro_chisin_pim_include(ch
))
2491 json_object_boolean_true_add(json_row
,
2494 if (pim_upstream_evaluate_join_desired(pim
, up
))
2495 json_object_boolean_true_add(
2496 json_row
, "evaluateJoinDesired");
2498 json_object_object_add(json_group
, src_str
, json_row
);
2502 "%-9s %-15s %-15s %-10s %-5s %-10s %-11s %-6s\n",
2503 ch
->interface
->name
, src_str
, grp_str
,
2504 pim_macro_ch_lost_assert(ch
) ? "yes" : "no",
2505 pim_macro_chisin_joins(ch
) ? "yes" : "no",
2506 pim_macro_chisin_pim_include(ch
) ? "yes" : "no",
2507 PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(
2511 pim_upstream_evaluate_join_desired(pim
, up
)
2517 static void pim_show_join_desired(struct pim_instance
*pim
, struct vty
*vty
,
2520 struct listnode
*if_node
;
2521 struct pim_interface
*pim_ifp
;
2522 struct pim_ifchannel
*ch
;
2523 struct interface
*ifp
;
2525 json_object
*json
= NULL
;
2528 json
= json_object_new_object();
2531 "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD\n");
2533 /* scan per-interface (S,G) state */
2534 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim
->vrf_id
), if_node
, ifp
)) {
2535 pim_ifp
= ifp
->info
;
2540 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
2541 /* scan all interfaces */
2542 pim_show_join_desired_helper(pim
, vty
,
2549 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2550 json
, JSON_C_TO_STRING_PRETTY
));
2551 json_object_free(json
);
2555 static void pim_show_upstream_rpf(struct pim_instance
*pim
, struct vty
*vty
,
2558 struct listnode
*upnode
;
2559 struct pim_upstream
*up
;
2560 json_object
*json
= NULL
;
2561 json_object
*json_group
= NULL
;
2562 json_object
*json_row
= NULL
;
2565 json
= json_object_new_object();
2568 "Source Group RpfIface RibNextHop RpfAddress \n");
2570 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
, up
)) {
2571 char src_str
[INET_ADDRSTRLEN
];
2572 char grp_str
[INET_ADDRSTRLEN
];
2573 char rpf_nexthop_str
[PREFIX_STRLEN
];
2574 char rpf_addr_str
[PREFIX_STRLEN
];
2575 struct pim_rpf
*rpf
;
2576 const char *rpf_ifname
;
2580 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2581 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2582 pim_addr_dump("<nexthop?>",
2583 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2584 rpf_nexthop_str
, sizeof(rpf_nexthop_str
));
2585 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2586 sizeof(rpf_addr_str
));
2588 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2591 json_object_object_get_ex(json
, grp_str
, &json_group
);
2594 json_group
= json_object_new_object();
2595 json_object_object_add(json
, grp_str
,
2599 json_row
= json_object_new_object();
2600 json_object_pim_upstream_add(json_row
, up
);
2601 json_object_string_add(json_row
, "source", src_str
);
2602 json_object_string_add(json_row
, "group", grp_str
);
2603 json_object_string_add(json_row
, "rpfInterface",
2605 json_object_string_add(json_row
, "ribNexthop",
2607 json_object_string_add(json_row
, "rpfAddress",
2609 json_object_object_add(json_group
, src_str
, json_row
);
2611 vty_out(vty
, "%-15s %-15s %-8s %-15s %-15s\n", src_str
,
2612 grp_str
, rpf_ifname
, rpf_nexthop_str
,
2618 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2619 json
, JSON_C_TO_STRING_PRETTY
));
2620 json_object_free(json
);
2624 static void show_rpf_refresh_stats(struct vty
*vty
, time_t now
,
2627 char refresh_uptime
[10];
2629 pim_time_uptime_begin(refresh_uptime
, sizeof(refresh_uptime
), now
,
2630 qpim_rpf_cache_refresh_last
);
2633 json_object_int_add(json
, "rpfCacheRefreshDelayMsecs",
2634 qpim_rpf_cache_refresh_delay_msec
);
2635 json_object_int_add(
2636 json
, "rpfCacheRefreshTimer",
2637 pim_time_timer_remain_msec(qpim_rpf_cache_refresher
));
2638 json_object_int_add(json
, "rpfCacheRefreshRequests",
2639 qpim_rpf_cache_refresh_requests
);
2640 json_object_int_add(json
, "rpfCacheRefreshEvents",
2641 qpim_rpf_cache_refresh_events
);
2642 json_object_string_add(json
, "rpfCacheRefreshLast",
2644 json_object_int_add(json
, "nexthopLookups",
2645 qpim_nexthop_lookups
);
2646 json_object_int_add(json
, "nexthopLookupsAvoided",
2647 nexthop_lookups_avoided
);
2650 "RPF Cache Refresh Delay: %ld msecs\n"
2651 "RPF Cache Refresh Timer: %ld msecs\n"
2652 "RPF Cache Refresh Requests: %lld\n"
2653 "RPF Cache Refresh Events: %lld\n"
2654 "RPF Cache Refresh Last: %s\n"
2655 "Nexthop Lookups: %lld\n"
2656 "Nexthop Lookups Avoided: %lld\n",
2657 qpim_rpf_cache_refresh_delay_msec
,
2658 pim_time_timer_remain_msec(qpim_rpf_cache_refresher
),
2659 (long long)qpim_rpf_cache_refresh_requests
,
2660 (long long)qpim_rpf_cache_refresh_events
,
2661 refresh_uptime
, (long long)qpim_nexthop_lookups
,
2662 (long long)nexthop_lookups_avoided
);
2666 static void show_scan_oil_stats(struct pim_instance
*pim
, struct vty
*vty
,
2669 char uptime_scan_oil
[10];
2670 char uptime_mroute_add
[10];
2671 char uptime_mroute_del
[10];
2673 pim_time_uptime_begin(uptime_scan_oil
, sizeof(uptime_scan_oil
), now
,
2674 qpim_scan_oil_last
);
2675 pim_time_uptime_begin(uptime_mroute_add
, sizeof(uptime_mroute_add
), now
,
2676 pim
->mroute_add_last
);
2677 pim_time_uptime_begin(uptime_mroute_del
, sizeof(uptime_mroute_del
), now
,
2678 pim
->mroute_del_last
);
2681 "Scan OIL - Last: %s Events: %lld\n"
2682 "MFC Add - Last: %s Events: %lld\n"
2683 "MFC Del - Last: %s Events: %lld\n",
2684 uptime_scan_oil
, (long long)qpim_scan_oil_events
,
2685 uptime_mroute_add
, (long long)pim
->mroute_add_events
,
2686 uptime_mroute_del
, (long long)pim
->mroute_del_events
);
2689 static void pim_show_rpf(struct pim_instance
*pim
, struct vty
*vty
, u_char uj
)
2691 struct listnode
*up_node
;
2692 struct pim_upstream
*up
;
2693 time_t now
= pim_time_monotonic_sec();
2694 json_object
*json
= NULL
;
2695 json_object
*json_group
= NULL
;
2696 json_object
*json_row
= NULL
;
2699 json
= json_object_new_object();
2700 show_rpf_refresh_stats(vty
, now
, json
);
2702 show_rpf_refresh_stats(vty
, now
, json
);
2705 "Source Group RpfIface RpfAddress RibNextHop Metric Pref\n");
2708 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, up_node
, up
)) {
2709 char src_str
[INET_ADDRSTRLEN
];
2710 char grp_str
[INET_ADDRSTRLEN
];
2711 char rpf_addr_str
[PREFIX_STRLEN
];
2712 char rib_nexthop_str
[PREFIX_STRLEN
];
2713 const char *rpf_ifname
;
2714 struct pim_rpf
*rpf
= &up
->rpf
;
2716 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2717 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2718 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2719 sizeof(rpf_addr_str
));
2720 pim_addr_dump("<nexthop?>",
2721 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2722 rib_nexthop_str
, sizeof(rib_nexthop_str
));
2724 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2727 json_object_object_get_ex(json
, grp_str
, &json_group
);
2730 json_group
= json_object_new_object();
2731 json_object_object_add(json
, grp_str
,
2735 json_row
= json_object_new_object();
2736 json_object_string_add(json_row
, "source", src_str
);
2737 json_object_string_add(json_row
, "group", grp_str
);
2738 json_object_string_add(json_row
, "rpfInterface",
2740 json_object_string_add(json_row
, "rpfAddress",
2742 json_object_string_add(json_row
, "ribNexthop",
2744 json_object_int_add(
2745 json_row
, "routeMetric",
2746 rpf
->source_nexthop
.mrib_route_metric
);
2747 json_object_int_add(
2748 json_row
, "routePreference",
2749 rpf
->source_nexthop
.mrib_metric_preference
);
2750 json_object_object_add(json_group
, src_str
, json_row
);
2753 vty_out(vty
, "%-15s %-15s %-8s %-15s %-15s %6d %4d\n",
2754 src_str
, grp_str
, rpf_ifname
, rpf_addr_str
,
2756 rpf
->source_nexthop
.mrib_route_metric
,
2757 rpf
->source_nexthop
.mrib_metric_preference
);
2762 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2763 json
, JSON_C_TO_STRING_PRETTY
));
2764 json_object_free(json
);
2768 struct pnc_cache_walk_data
{
2770 struct pim_instance
*pim
;
2773 static int pim_print_pnc_cache_walkcb(struct hash_backet
*backet
, void *arg
)
2775 struct pim_nexthop_cache
*pnc
= backet
->data
;
2776 struct pnc_cache_walk_data
*cwd
= arg
;
2777 struct vty
*vty
= cwd
->vty
;
2778 struct pim_instance
*pim
= cwd
->pim
;
2779 struct nexthop
*nh_node
= NULL
;
2780 ifindex_t first_ifindex
;
2781 struct interface
*ifp
= NULL
;
2786 for (nh_node
= pnc
->nexthop
; nh_node
; nh_node
= nh_node
->next
) {
2787 first_ifindex
= nh_node
->ifindex
;
2788 ifp
= if_lookup_by_index(first_ifindex
, pim
->vrf_id
);
2790 vty_out(vty
, "%-15s ", inet_ntoa(pnc
->rpf
.rpf_addr
.u
.prefix4
));
2791 vty_out(vty
, "%-14s ", ifp
? ifp
->name
: "NULL");
2792 vty_out(vty
, "%s ", inet_ntoa(nh_node
->gate
.ipv4
));
2798 static void pim_show_nexthop(struct pim_instance
*pim
, struct vty
*vty
)
2800 struct pnc_cache_walk_data cwd
;
2804 vty_out(vty
, "Number of registered addresses: %lu\n",
2805 pim
->rpf_hash
->count
);
2806 vty_out(vty
, "Address Interface Nexthop\n");
2807 vty_out(vty
, "-------------------------------------------\n");
2809 hash_walk(pim
->rpf_hash
, pim_print_pnc_cache_walkcb
, &cwd
);
2812 static void igmp_show_groups(struct pim_instance
*pim
, struct vty
*vty
,
2815 struct listnode
*ifnode
;
2816 struct interface
*ifp
;
2818 json_object
*json
= NULL
;
2819 json_object
*json_iface
= NULL
;
2820 json_object
*json_row
= NULL
;
2822 now
= pim_time_monotonic_sec();
2825 json
= json_object_new_object();
2828 "Interface Address Group Mode Timer Srcs V Uptime \n");
2830 /* scan interfaces */
2831 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim
->vrf_id
), ifnode
, ifp
)) {
2832 struct pim_interface
*pim_ifp
= ifp
->info
;
2833 struct listnode
*sock_node
;
2834 struct igmp_sock
*igmp
;
2839 /* scan igmp sockets */
2840 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
2842 char ifaddr_str
[INET_ADDRSTRLEN
];
2843 struct listnode
*grpnode
;
2844 struct igmp_group
*grp
;
2846 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
2847 sizeof(ifaddr_str
));
2849 /* scan igmp groups */
2850 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
2852 char group_str
[INET_ADDRSTRLEN
];
2856 pim_inet4_dump("<group?>", grp
->group_addr
,
2857 group_str
, sizeof(group_str
));
2858 pim_time_timer_to_hhmmss(hhmmss
, sizeof(hhmmss
),
2859 grp
->t_group_timer
);
2860 pim_time_uptime(uptime
, sizeof(uptime
),
2861 now
- grp
->group_creation
);
2864 json_object_object_get_ex(
2865 json
, ifp
->name
, &json_iface
);
2869 json_object_new_object();
2870 json_object_pim_ifp_add(
2872 json_object_object_add(
2877 json_row
= json_object_new_object();
2878 json_object_string_add(
2879 json_row
, "source", ifaddr_str
);
2880 json_object_string_add(
2881 json_row
, "group", group_str
);
2883 if (grp
->igmp_version
== 3)
2884 json_object_string_add(
2886 grp
->group_filtermode_isexcl
2890 json_object_string_add(json_row
,
2892 json_object_int_add(
2893 json_row
, "sourcesCount",
2894 grp
->group_source_list
2896 grp
->group_source_list
)
2898 json_object_int_add(json_row
, "version",
2900 json_object_string_add(
2901 json_row
, "uptime", uptime
);
2902 json_object_object_add(json_iface
,
2908 "%-9s %-15s %-15s %4s %8s %4d %d %8s\n",
2909 ifp
->name
, ifaddr_str
,
2911 grp
->igmp_version
== 3
2912 ? (grp
->group_filtermode_isexcl
2917 grp
->group_source_list
2919 grp
->group_source_list
)
2921 grp
->igmp_version
, uptime
);
2923 } /* scan igmp groups */
2924 } /* scan igmp sockets */
2925 } /* scan interfaces */
2928 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2929 json
, JSON_C_TO_STRING_PRETTY
));
2930 json_object_free(json
);
2934 static void igmp_show_group_retransmission(struct pim_instance
*pim
,
2937 struct listnode
*ifnode
;
2938 struct interface
*ifp
;
2941 "Interface Address Group RetTimer Counter RetSrcs\n");
2943 /* scan interfaces */
2944 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim
->vrf_id
), ifnode
, ifp
)) {
2945 struct pim_interface
*pim_ifp
= ifp
->info
;
2946 struct listnode
*sock_node
;
2947 struct igmp_sock
*igmp
;
2952 /* scan igmp sockets */
2953 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
2955 char ifaddr_str
[INET_ADDRSTRLEN
];
2956 struct listnode
*grpnode
;
2957 struct igmp_group
*grp
;
2959 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
2960 sizeof(ifaddr_str
));
2962 /* scan igmp groups */
2963 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
2965 char group_str
[INET_ADDRSTRLEN
];
2966 char grp_retr_mmss
[10];
2967 struct listnode
*src_node
;
2968 struct igmp_source
*src
;
2969 int grp_retr_sources
= 0;
2971 pim_inet4_dump("<group?>", grp
->group_addr
,
2972 group_str
, sizeof(group_str
));
2973 pim_time_timer_to_mmss(
2974 grp_retr_mmss
, sizeof(grp_retr_mmss
),
2975 grp
->t_group_query_retransmit_timer
);
2978 /* count group sources with retransmission state
2980 for (ALL_LIST_ELEMENTS_RO(
2981 grp
->group_source_list
, src_node
,
2983 if (src
->source_query_retransmit_count
2989 vty_out(vty
, "%-9s %-15s %-15s %-8s %7d %7d\n",
2990 ifp
->name
, ifaddr_str
, group_str
,
2992 grp
->group_specific_query_retransmit_count
,
2995 } /* scan igmp groups */
2996 } /* scan igmp sockets */
2997 } /* scan interfaces */
3000 static void igmp_show_sources(struct pim_instance
*pim
, struct vty
*vty
)
3002 struct listnode
*ifnode
;
3003 struct interface
*ifp
;
3006 now
= pim_time_monotonic_sec();
3009 "Interface Address Group Source Timer Fwd Uptime \n");
3011 /* scan interfaces */
3012 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim
->vrf_id
), ifnode
, ifp
)) {
3013 struct pim_interface
*pim_ifp
= ifp
->info
;
3014 struct listnode
*sock_node
;
3015 struct igmp_sock
*igmp
;
3020 /* scan igmp sockets */
3021 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3023 char ifaddr_str
[INET_ADDRSTRLEN
];
3024 struct listnode
*grpnode
;
3025 struct igmp_group
*grp
;
3027 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3028 sizeof(ifaddr_str
));
3030 /* scan igmp groups */
3031 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3033 char group_str
[INET_ADDRSTRLEN
];
3034 struct listnode
*srcnode
;
3035 struct igmp_source
*src
;
3037 pim_inet4_dump("<group?>", grp
->group_addr
,
3038 group_str
, sizeof(group_str
));
3040 /* scan group sources */
3041 for (ALL_LIST_ELEMENTS_RO(
3042 grp
->group_source_list
, srcnode
,
3044 char source_str
[INET_ADDRSTRLEN
];
3049 "<source?>", src
->source_addr
,
3050 source_str
, sizeof(source_str
));
3052 pim_time_timer_to_mmss(
3054 src
->t_source_timer
);
3057 uptime
, sizeof(uptime
),
3058 now
- src
->source_creation
);
3061 "%-9s %-15s %-15s %-15s %5s %3s %8s\n",
3062 ifp
->name
, ifaddr_str
,
3063 group_str
, source_str
, mmss
,
3064 IGMP_SOURCE_TEST_FORWARDING(
3070 } /* scan group sources */
3071 } /* scan igmp groups */
3072 } /* scan igmp sockets */
3073 } /* scan interfaces */
3076 static void igmp_show_source_retransmission(struct pim_instance
*pim
,
3079 struct listnode
*ifnode
;
3080 struct interface
*ifp
;
3083 "Interface Address Group Source Counter\n");
3085 /* scan interfaces */
3086 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim
->vrf_id
), ifnode
, ifp
)) {
3087 struct pim_interface
*pim_ifp
= ifp
->info
;
3088 struct listnode
*sock_node
;
3089 struct igmp_sock
*igmp
;
3094 /* scan igmp sockets */
3095 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3097 char ifaddr_str
[INET_ADDRSTRLEN
];
3098 struct listnode
*grpnode
;
3099 struct igmp_group
*grp
;
3101 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3102 sizeof(ifaddr_str
));
3104 /* scan igmp groups */
3105 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3107 char group_str
[INET_ADDRSTRLEN
];
3108 struct listnode
*srcnode
;
3109 struct igmp_source
*src
;
3111 pim_inet4_dump("<group?>", grp
->group_addr
,
3112 group_str
, sizeof(group_str
));
3114 /* scan group sources */
3115 for (ALL_LIST_ELEMENTS_RO(
3116 grp
->group_source_list
, srcnode
,
3118 char source_str
[INET_ADDRSTRLEN
];
3121 "<source?>", src
->source_addr
,
3122 source_str
, sizeof(source_str
));
3125 "%-9s %-15s %-15s %-15s %7d\n",
3126 ifp
->name
, ifaddr_str
,
3127 group_str
, source_str
,
3128 src
->source_query_retransmit_count
);
3130 } /* scan group sources */
3131 } /* scan igmp groups */
3132 } /* scan igmp sockets */
3133 } /* scan interfaces */
3136 static void clear_igmp_interfaces(struct pim_instance
*pim
)
3138 struct listnode
*ifnode
;
3139 struct listnode
*ifnextnode
;
3140 struct interface
*ifp
;
3142 for (ALL_LIST_ELEMENTS(vrf_iflist(pim
->vrf_id
), ifnode
, ifnextnode
,
3144 pim_if_addr_del_all_igmp(ifp
);
3147 for (ALL_LIST_ELEMENTS(vrf_iflist(pim
->vrf_id
), ifnode
, ifnextnode
,
3149 pim_if_addr_add_all(ifp
);
3153 static void clear_pim_interfaces(struct pim_instance
*pim
)
3155 struct listnode
*ifnode
;
3156 struct listnode
*ifnextnode
;
3157 struct interface
*ifp
;
3159 for (ALL_LIST_ELEMENTS(vrf_iflist(pim
->vrf_id
), ifnode
, ifnextnode
,
3162 pim_neighbor_delete_all(ifp
, "interface cleared");
3167 static void clear_interfaces(struct pim_instance
*pim
)
3169 clear_igmp_interfaces(pim
);
3170 clear_pim_interfaces(pim
);
3173 #define PIM_GET_PIM_INTERFACE(pim_ifp, ifp) \
3174 pim_ifp = ifp->info; \
3177 "%% Enable PIM and/or IGMP on this interface first\n"); \
3178 return CMD_WARNING_CONFIG_FAILED; \
3181 DEFUN (clear_ip_interfaces
,
3182 clear_ip_interfaces_cmd
,
3183 "clear ip interfaces [vrf NAME]",
3186 "Reset interfaces\n"
3190 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3195 clear_interfaces(vrf
->info
);
3200 DEFUN (clear_ip_igmp_interfaces
,
3201 clear_ip_igmp_interfaces_cmd
,
3202 "clear ip igmp [vrf NAME] interfaces",
3207 "Reset IGMP interfaces\n")
3210 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3215 clear_igmp_interfaces(vrf
->info
);
3220 static void mroute_add_all(struct pim_instance
*pim
)
3222 struct listnode
*node
;
3223 struct channel_oil
*c_oil
;
3225 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
3226 if (pim_mroute_add(c_oil
, __PRETTY_FUNCTION__
)) {
3227 /* just log warning */
3228 char source_str
[INET_ADDRSTRLEN
];
3229 char group_str
[INET_ADDRSTRLEN
];
3230 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
,
3231 source_str
, sizeof(source_str
));
3232 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
,
3233 group_str
, sizeof(group_str
));
3234 zlog_warn("%s %s: (S,G)=(%s,%s) failure writing MFC",
3235 __FILE__
, __PRETTY_FUNCTION__
, source_str
,
3241 static void mroute_del_all(struct pim_instance
*pim
)
3243 struct listnode
*node
;
3244 struct channel_oil
*c_oil
;
3246 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
3247 if (pim_mroute_del(c_oil
, __PRETTY_FUNCTION__
)) {
3248 /* just log warning */
3249 char source_str
[INET_ADDRSTRLEN
];
3250 char group_str
[INET_ADDRSTRLEN
];
3251 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
,
3252 source_str
, sizeof(source_str
));
3253 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
,
3254 group_str
, sizeof(group_str
));
3255 zlog_warn("%s %s: (S,G)=(%s,%s) failure clearing MFC",
3256 __FILE__
, __PRETTY_FUNCTION__
, source_str
,
3262 DEFUN (clear_ip_mroute
,
3263 clear_ip_mroute_cmd
,
3264 "clear ip mroute [vrf NAME]",
3267 "Reset multicast routes\n"
3271 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3276 mroute_del_all(vrf
->info
);
3277 mroute_add_all(vrf
->info
);
3282 DEFUN (clear_ip_pim_interfaces
,
3283 clear_ip_pim_interfaces_cmd
,
3284 "clear ip pim [vrf NAME] interfaces",
3289 "Reset PIM interfaces\n")
3292 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3297 clear_pim_interfaces(vrf
->info
);
3302 DEFUN (clear_ip_pim_interface_traffic
,
3303 clear_ip_pim_interface_traffic_cmd
,
3304 "clear ip pim [vrf NAME] interface traffic",
3307 "PIM clear commands\n"
3309 "Reset PIM interfaces\n"
3310 "Reset Protocol Packet counters\n")
3313 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3314 struct listnode
*ifnode
= NULL
;
3315 struct listnode
*ifnextnode
= NULL
;
3316 struct interface
*ifp
= NULL
;
3317 struct pim_interface
*pim_ifp
= NULL
;
3322 for (ALL_LIST_ELEMENTS(vrf_iflist(vrf
->vrf_id
), ifnode
, ifnextnode
,
3324 pim_ifp
= ifp
->info
;
3329 pim_ifp
->pim_ifstat_hello_recv
= 0;
3330 pim_ifp
->pim_ifstat_hello_sent
= 0;
3331 pim_ifp
->pim_ifstat_join_recv
= 0;
3332 pim_ifp
->pim_ifstat_join_send
= 0;
3333 pim_ifp
->pim_ifstat_prune_recv
= 0;
3334 pim_ifp
->pim_ifstat_prune_send
= 0;
3335 pim_ifp
->pim_ifstat_reg_recv
= 0;
3336 pim_ifp
->pim_ifstat_reg_send
= 0;
3337 pim_ifp
->pim_ifstat_reg_stop_recv
= 0;
3338 pim_ifp
->pim_ifstat_reg_stop_send
= 0;
3339 pim_ifp
->pim_ifstat_assert_recv
= 0;
3340 pim_ifp
->pim_ifstat_assert_send
= 0;
3346 DEFUN (clear_ip_pim_oil
,
3347 clear_ip_pim_oil_cmd
,
3348 "clear ip pim [vrf NAME] oil",
3353 "Rescan PIM OIL (output interface list)\n")
3356 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3361 pim_scan_oil(vrf
->info
);
3366 DEFUN (show_ip_igmp_interface
,
3367 show_ip_igmp_interface_cmd
,
3368 "show ip igmp [vrf NAME] interface [detail|WORD] [json]",
3373 "IGMP interface information\n"
3379 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3380 u_char uj
= use_json(argc
, argv
);
3385 if (argv_find(argv
, argc
, "detail", &idx
)
3386 || argv_find(argv
, argc
, "WORD", &idx
))
3387 igmp_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
3389 igmp_show_interfaces(vrf
->info
, vty
, uj
);
3394 DEFUN (show_ip_igmp_interface_vrf_all
,
3395 show_ip_igmp_interface_vrf_all_cmd
,
3396 "show ip igmp vrf all interface [detail|WORD] [json]",
3401 "IGMP interface information\n"
3407 u_char uj
= use_json(argc
, argv
);
3413 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3417 vty_out(vty
, " \"%s\": ", vrf
->name
);
3420 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3421 if (argv_find(argv
, argc
, "detail", &idx
)
3422 || argv_find(argv
, argc
, "WORD", &idx
))
3423 igmp_show_interfaces_single(vrf
->info
, vty
,
3424 argv
[idx
]->arg
, uj
);
3426 igmp_show_interfaces(vrf
->info
, vty
, uj
);
3429 vty_out(vty
, "}\n");
3434 DEFUN (show_ip_igmp_join
,
3435 show_ip_igmp_join_cmd
,
3436 "show ip igmp [vrf NAME] join",
3441 "IGMP static join information\n")
3444 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3449 igmp_show_interface_join(vrf
->info
, vty
);
3454 DEFUN (show_ip_igmp_join_vrf_all
,
3455 show_ip_igmp_join_vrf_all_cmd
,
3456 "show ip igmp vrf all join",
3461 "IGMP static join information\n")
3463 u_char uj
= use_json(argc
, argv
);
3469 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3473 vty_out(vty
, " \"%s\": ", vrf
->name
);
3476 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3477 igmp_show_interface_join(vrf
->info
, vty
);
3480 vty_out(vty
, "}\n");
3485 DEFUN (show_ip_igmp_groups
,
3486 show_ip_igmp_groups_cmd
,
3487 "show ip igmp [vrf NAME] groups [json]",
3496 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3497 u_char uj
= use_json(argc
, argv
);
3502 igmp_show_groups(vrf
->info
, vty
, uj
);
3507 DEFUN (show_ip_igmp_groups_vrf_all
,
3508 show_ip_igmp_groups_vrf_all_cmd
,
3509 "show ip igmp vrf all groups [json]",
3517 u_char uj
= use_json(argc
, argv
);
3523 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3527 vty_out(vty
, " \"%s\": ", vrf
->name
);
3530 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3531 igmp_show_groups(vrf
->info
, vty
, uj
);
3534 vty_out(vty
, "}\n");
3539 DEFUN (show_ip_igmp_groups_retransmissions
,
3540 show_ip_igmp_groups_retransmissions_cmd
,
3541 "show ip igmp [vrf NAME] groups retransmissions",
3547 "IGMP group retransmissions\n")
3550 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3555 igmp_show_group_retransmission(vrf
->info
, vty
);
3560 DEFUN (show_ip_igmp_sources
,
3561 show_ip_igmp_sources_cmd
,
3562 "show ip igmp [vrf NAME] sources",
3570 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3575 igmp_show_sources(vrf
->info
, vty
);
3580 DEFUN (show_ip_igmp_sources_retransmissions
,
3581 show_ip_igmp_sources_retransmissions_cmd
,
3582 "show ip igmp [vrf NAME] sources retransmissions",
3588 "IGMP source retransmissions\n")
3591 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3596 igmp_show_source_retransmission(vrf
->info
, vty
);
3601 DEFUN (show_ip_pim_assert
,
3602 show_ip_pim_assert_cmd
,
3603 "show ip pim [vrf NAME] assert",
3608 "PIM interface assert\n")
3611 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3616 pim_show_assert(vrf
->info
, vty
);
3621 DEFUN (show_ip_pim_assert_internal
,
3622 show_ip_pim_assert_internal_cmd
,
3623 "show ip pim [vrf NAME] assert-internal",
3628 "PIM interface internal assert state\n")
3631 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3636 pim_show_assert_internal(vrf
->info
, vty
);
3641 DEFUN (show_ip_pim_assert_metric
,
3642 show_ip_pim_assert_metric_cmd
,
3643 "show ip pim [vrf NAME] assert-metric",
3648 "PIM interface assert metric\n")
3651 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3656 pim_show_assert_metric(vrf
->info
, vty
);
3661 DEFUN (show_ip_pim_assert_winner_metric
,
3662 show_ip_pim_assert_winner_metric_cmd
,
3663 "show ip pim [vrf NAME] assert-winner-metric",
3668 "PIM interface assert winner metric\n")
3671 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3676 pim_show_assert_winner_metric(vrf
->info
, vty
);
3681 DEFUN (show_ip_pim_interface
,
3682 show_ip_pim_interface_cmd
,
3683 "show ip pim [vrf NAME] interface [detail|WORD] [json]",
3688 "PIM interface information\n"
3694 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3695 u_char uj
= use_json(argc
, argv
);
3700 if (argv_find(argv
, argc
, "WORD", &idx
)
3701 || argv_find(argv
, argc
, "detail", &idx
))
3702 pim_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
3704 pim_show_interfaces(vrf
->info
, vty
, uj
);
3709 DEFUN (show_ip_pim_interface_vrf_all
,
3710 show_ip_pim_interface_vrf_all_cmd
,
3711 "show ip pim vrf all interface [detail|WORD] [json]",
3716 "PIM interface information\n"
3722 u_char uj
= use_json(argc
, argv
);
3728 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3732 vty_out(vty
, " \"%s\": ", vrf
->name
);
3735 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3736 if (argv_find(argv
, argc
, "WORD", &idx
)
3737 || argv_find(argv
, argc
, "detail", &idx
))
3738 pim_show_interfaces_single(vrf
->info
, vty
,
3739 argv
[idx
]->arg
, uj
);
3741 pim_show_interfaces(vrf
->info
, vty
, uj
);
3744 vty_out(vty
, "}\n");
3749 DEFUN (show_ip_pim_join
,
3750 show_ip_pim_join_cmd
,
3751 "show ip pim [vrf NAME] join [json]",
3756 "PIM interface join information\n"
3760 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3761 u_char uj
= use_json(argc
, argv
);
3766 pim_show_join(vrf
->info
, vty
, uj
);
3771 DEFUN (show_ip_pim_join_vrf_all
,
3772 show_ip_pim_join_vrf_all_cmd
,
3773 "show ip pim vrf all join [json]",
3778 "PIM interface join information\n"
3781 u_char uj
= use_json(argc
, argv
);
3787 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3791 vty_out(vty
, " \"%s\": ", vrf
->name
);
3794 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3795 pim_show_join(vrf
->info
, vty
, uj
);
3798 vty_out(vty
, "}\n");
3803 DEFUN (show_ip_pim_local_membership
,
3804 show_ip_pim_local_membership_cmd
,
3805 "show ip pim [vrf NAME] local-membership [json]",
3810 "PIM interface local-membership\n"
3814 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3815 u_char uj
= use_json(argc
, argv
);
3820 pim_show_membership(vrf
->info
, vty
, uj
);
3825 DEFUN (show_ip_pim_neighbor
,
3826 show_ip_pim_neighbor_cmd
,
3827 "show ip pim [vrf NAME] neighbor [detail|WORD] [json]",
3832 "PIM neighbor information\n"
3834 "Name of interface or neighbor\n"
3838 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3839 u_char uj
= use_json(argc
, argv
);
3844 if (argv_find(argv
, argc
, "detail", &idx
)
3845 || argv_find(argv
, argc
, "WORD", &idx
))
3846 pim_show_neighbors_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
3848 pim_show_neighbors(vrf
->info
, vty
, uj
);
3853 DEFUN (show_ip_pim_neighbor_vrf_all
,
3854 show_ip_pim_neighbor_vrf_all_cmd
,
3855 "show ip pim vrf all neighbor [detail|WORD] [json]",
3860 "PIM neighbor information\n"
3862 "Name of interface or neighbor\n"
3866 u_char uj
= use_json(argc
, argv
);
3872 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3876 vty_out(vty
, " \"%s\": ", vrf
->name
);
3879 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3880 if (argv_find(argv
, argc
, "detail", &idx
)
3881 || argv_find(argv
, argc
, "WORD", &idx
))
3882 pim_show_neighbors_single(vrf
->info
, vty
,
3883 argv
[idx
]->arg
, uj
);
3885 pim_show_neighbors(vrf
->info
, vty
, uj
);
3888 vty_out(vty
, "}\n");
3893 DEFUN (show_ip_pim_secondary
,
3894 show_ip_pim_secondary_cmd
,
3895 "show ip pim [vrf NAME] secondary",
3900 "PIM neighbor addresses\n")
3903 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3908 pim_show_neighbors_secondary(vrf
->info
, vty
);
3913 DEFUN (show_ip_pim_state
,
3914 show_ip_pim_state_cmd
,
3915 "show ip pim [vrf NAME] state [A.B.C.D [A.B.C.D]] [json]",
3920 "PIM state information\n"
3921 "Unicast or Multicast address\n"
3922 "Multicast address\n"
3925 const char *src_or_group
= NULL
;
3926 const char *group
= NULL
;
3928 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3929 u_char uj
= use_json(argc
, argv
);
3937 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
3938 src_or_group
= argv
[idx
]->arg
;
3940 group
= argv
[idx
+ 1]->arg
;
3943 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
3948 DEFUN (show_ip_pim_state_vrf_all
,
3949 show_ip_pim_state_vrf_all_cmd
,
3950 "show ip pim vrf all state [A.B.C.D [A.B.C.D]] [json]",
3955 "PIM state information\n"
3956 "Unicast or Multicast address\n"
3957 "Multicast address\n"
3960 const char *src_or_group
= NULL
;
3961 const char *group
= NULL
;
3963 u_char uj
= use_json(argc
, argv
);
3972 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
3973 src_or_group
= argv
[idx
]->arg
;
3975 group
= argv
[idx
+ 1]->arg
;
3978 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3982 vty_out(vty
, " \"%s\": ", vrf
->name
);
3985 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3986 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
3989 vty_out(vty
, "}\n");
3994 DEFUN (show_ip_pim_upstream
,
3995 show_ip_pim_upstream_cmd
,
3996 "show ip pim [vrf NAME] upstream [json]",
4001 "PIM upstream information\n"
4005 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4006 u_char uj
= use_json(argc
, argv
);
4011 pim_show_upstream(vrf
->info
, vty
, uj
);
4016 DEFUN (show_ip_pim_upstream_vrf_all
,
4017 show_ip_pim_upstream_vrf_all_cmd
,
4018 "show ip pim vrf all upstream [json]",
4023 "PIM upstream information\n"
4026 u_char uj
= use_json(argc
, argv
);
4032 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4036 vty_out(vty
, " \"%s\": ", vrf
->name
);
4039 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4040 pim_show_upstream(vrf
->info
, vty
, uj
);
4046 DEFUN (show_ip_pim_upstream_join_desired
,
4047 show_ip_pim_upstream_join_desired_cmd
,
4048 "show ip pim [vrf NAME] upstream-join-desired [json]",
4053 "PIM upstream join-desired\n"
4057 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4058 u_char uj
= use_json(argc
, argv
);
4063 pim_show_join_desired(vrf
->info
, vty
, uj
);
4068 DEFUN (show_ip_pim_upstream_rpf
,
4069 show_ip_pim_upstream_rpf_cmd
,
4070 "show ip pim [vrf NAME] upstream-rpf [json]",
4075 "PIM upstream source rpf\n"
4079 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4080 u_char uj
= use_json(argc
, argv
);
4085 pim_show_upstream_rpf(vrf
->info
, vty
, uj
);
4090 DEFUN (show_ip_pim_rp
,
4092 "show ip pim [vrf NAME] rp-info [json]",
4097 "PIM RP information\n"
4101 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4102 u_char uj
= use_json(argc
, argv
);
4107 pim_rp_show_information(vrf
->info
, vty
, uj
);
4112 DEFUN (show_ip_pim_rp_vrf_all
,
4113 show_ip_pim_rp_vrf_all_cmd
,
4114 "show ip pim vrf all rp-info [json]",
4119 "PIM RP information\n"
4122 u_char uj
= use_json(argc
, argv
);
4128 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4132 vty_out(vty
, " \"%s\": ", vrf
->name
);
4135 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4136 pim_rp_show_information(vrf
->info
, vty
, uj
);
4139 vty_out(vty
, "}\n");
4144 DEFUN (show_ip_pim_rpf
,
4145 show_ip_pim_rpf_cmd
,
4146 "show ip pim [vrf NAME] rpf [json]",
4151 "PIM cached source rpf information\n"
4155 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4156 u_char uj
= use_json(argc
, argv
);
4161 pim_show_rpf(vrf
->info
, vty
, uj
);
4166 DEFUN (show_ip_pim_rpf_vrf_all
,
4167 show_ip_pim_rpf_vrf_all_cmd
,
4168 "show ip pim vrf all rpf [json]",
4173 "PIM cached source rpf information\n"
4176 u_char uj
= use_json(argc
, argv
);
4182 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4186 vty_out(vty
, " \"%s\": ", vrf
->name
);
4189 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4190 pim_show_rpf(vrf
->info
, vty
, uj
);
4193 vty_out(vty
, "}\n");
4198 DEFUN (show_ip_pim_nexthop
,
4199 show_ip_pim_nexthop_cmd
,
4200 "show ip pim [vrf NAME] nexthop",
4205 "PIM cached nexthop rpf information\n")
4208 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4213 pim_show_nexthop(vrf
->info
, vty
);
4218 DEFUN (show_ip_pim_nexthop_lookup
,
4219 show_ip_pim_nexthop_lookup_cmd
,
4220 "show ip pim [vrf NAME] nexthop-lookup A.B.C.D A.B.C.D",
4225 "PIM cached nexthop rpf lookup\n"
4226 "Source/RP address\n"
4227 "Multicast Group address\n")
4229 struct pim_nexthop_cache pnc
;
4230 struct prefix nht_p
;
4232 struct in_addr src_addr
, grp_addr
;
4233 struct in_addr vif_source
;
4234 const char *addr_str
, *addr_str1
;
4236 struct pim_nexthop nexthop
;
4237 char nexthop_addr_str
[PREFIX_STRLEN
];
4238 char grp_str
[PREFIX_STRLEN
];
4240 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4245 argv_find(argv
, argc
, "A.B.C.D", &idx
);
4246 addr_str
= argv
[idx
]->arg
;
4247 result
= inet_pton(AF_INET
, addr_str
, &src_addr
);
4249 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
4250 errno
, safe_strerror(errno
));
4254 if (pim_is_group_224_4(src_addr
)) {
4256 "Invalid argument. Expected Valid Source Address.\n");
4260 addr_str1
= argv
[idx
+ 1]->arg
;
4261 result
= inet_pton(AF_INET
, addr_str1
, &grp_addr
);
4263 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
4264 errno
, safe_strerror(errno
));
4268 if (!pim_is_group_224_4(grp_addr
)) {
4270 "Invalid argument. Expected Valid Multicast Group Address.\n");
4274 if (!pim_rp_set_upstream_addr(vrf
->info
, &vif_source
, src_addr
,
4278 memset(&pnc
, 0, sizeof(struct pim_nexthop_cache
));
4279 nht_p
.family
= AF_INET
;
4280 nht_p
.prefixlen
= IPV4_MAX_BITLEN
;
4281 nht_p
.u
.prefix4
= vif_source
;
4282 grp
.family
= AF_INET
;
4283 grp
.prefixlen
= IPV4_MAX_BITLEN
;
4284 grp
.u
.prefix4
= grp_addr
;
4285 memset(&nexthop
, 0, sizeof(nexthop
));
4287 if (pim_find_or_track_nexthop(vrf
->info
, &nht_p
, NULL
, NULL
, &pnc
))
4288 pim_ecmp_nexthop_search(vrf
->info
, &pnc
, &nexthop
, &nht_p
, &grp
,
4291 pim_ecmp_nexthop_lookup(vrf
->info
, &nexthop
, vif_source
, &nht_p
,
4294 pim_addr_dump("<grp?>", &grp
, grp_str
, sizeof(grp_str
));
4295 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
4296 nexthop_addr_str
, sizeof(nexthop_addr_str
));
4297 vty_out(vty
, "Group %s --- Nexthop %s Interface %s \n", grp_str
,
4298 nexthop_addr_str
, nexthop
.interface
->name
);
4303 DEFUN (show_ip_pim_interface_traffic
,
4304 show_ip_pim_interface_traffic_cmd
,
4305 "show ip pim [vrf NAME] interface traffic [WORD] [json]",
4310 "PIM interface information\n"
4311 "Protocol Packet counters\n"
4316 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4317 u_char uj
= use_json(argc
, argv
);
4322 if (argv_find(argv
, argc
, "WORD", &idx
))
4323 pim_show_interface_traffic_single(vrf
->info
, vty
,
4324 argv
[idx
]->arg
, uj
);
4326 pim_show_interface_traffic(vrf
->info
, vty
, uj
);
4331 static void show_multicast_interfaces(struct pim_instance
*pim
, struct vty
*vty
)
4333 struct listnode
*node
;
4334 struct interface
*ifp
;
4339 "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut\n");
4341 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim
->vrf_id
), node
, ifp
)) {
4342 struct pim_interface
*pim_ifp
;
4343 struct in_addr ifaddr
;
4344 struct sioc_vif_req vreq
;
4346 pim_ifp
= ifp
->info
;
4351 memset(&vreq
, 0, sizeof(vreq
));
4352 vreq
.vifi
= pim_ifp
->mroute_vif_index
;
4354 if (ioctl(pim
->mroute_socket
, SIOCGETVIFCNT
, &vreq
)) {
4356 "ioctl(SIOCGETVIFCNT=%lu) failure for interface %s vif_index=%d: errno=%d: %s",
4357 (unsigned long)SIOCGETVIFCNT
, ifp
->name
,
4358 pim_ifp
->mroute_vif_index
, errno
,
4359 safe_strerror(errno
));
4362 ifaddr
= pim_ifp
->primary_address
;
4364 vty_out(vty
, "%-12s %-15s %3d %3d %7lu %7lu %10lu %10lu\n",
4365 ifp
->name
, inet_ntoa(ifaddr
), ifp
->ifindex
,
4366 pim_ifp
->mroute_vif_index
, (unsigned long)vreq
.icount
,
4367 (unsigned long)vreq
.ocount
, (unsigned long)vreq
.ibytes
,
4368 (unsigned long)vreq
.obytes
);
4372 static void pim_cmd_show_ip_multicast_helper(struct pim_instance
*pim
,
4375 struct vrf
*vrf
= pim
->vrf
;
4376 time_t now
= pim_time_monotonic_sec();
4381 vty_out(vty
, "Mroute socket descriptor:");
4383 vty_out(vty
, " %d(%s)\n", pim
->mroute_socket
, vrf
->name
);
4385 pim_time_uptime(uptime
, sizeof(uptime
),
4386 now
- pim
->mroute_socket_creation
);
4387 vty_out(vty
, "Mroute socket uptime: %s\n", uptime
);
4391 pim_zebra_zclient_update(vty
);
4392 pim_zlookup_show_ip_multicast(vty
);
4395 vty_out(vty
, "Maximum highest VifIndex: %d\n", PIM_MAX_USABLE_VIFS
);
4398 vty_out(vty
, "Upstream Join Timer: %d secs\n", qpim_t_periodic
);
4399 vty_out(vty
, "Join/Prune Holdtime: %d secs\n", PIM_JP_HOLDTIME
);
4400 vty_out(vty
, "PIM ECMP: %s\n", qpim_ecmp_enable
? "Enable" : "Disable");
4401 vty_out(vty
, "PIM ECMP Rebalance: %s\n",
4402 qpim_ecmp_rebalance_enable
? "Enable" : "Disable");
4406 show_rpf_refresh_stats(vty
, now
, NULL
);
4410 show_scan_oil_stats(pim
, vty
, now
);
4412 show_multicast_interfaces(pim
, vty
);
4415 DEFUN (show_ip_multicast
,
4416 show_ip_multicast_cmd
,
4417 "show ip multicast [vrf NAME]",
4421 "Multicast global information\n")
4424 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4429 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
4434 DEFUN (show_ip_multicast_vrf_all
,
4435 show_ip_multicast_vrf_all_cmd
,
4436 "show ip multicast vrf all",
4440 "Multicast global information\n")
4442 u_char uj
= use_json(argc
, argv
);
4448 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4452 vty_out(vty
, " \"%s\": ", vrf
->name
);
4455 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4456 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
4459 vty_out(vty
, "}\n");
4464 static void show_mroute(struct pim_instance
*pim
, struct vty
*vty
,
4465 bool fill
, u_char uj
)
4467 struct listnode
*node
;
4468 struct channel_oil
*c_oil
;
4469 struct static_route
*s_route
;
4471 json_object
*json
= NULL
;
4472 json_object
*json_group
= NULL
;
4473 json_object
*json_source
= NULL
;
4474 json_object
*json_oil
= NULL
;
4475 json_object
*json_ifp_out
= NULL
;
4478 char grp_str
[INET_ADDRSTRLEN
];
4479 char src_str
[INET_ADDRSTRLEN
];
4480 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
4481 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
4483 struct interface
*ifp_in
;
4487 json
= json_object_new_object();
4490 "Source Group Proto Input Output TTL Uptime\n");
4493 now
= pim_time_monotonic_sec();
4495 /* print list of PIM and IGMP routes */
4496 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
4499 if (!c_oil
->installed
&& !uj
)
4502 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
4504 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
4506 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
4509 strcpy(in_ifname
, ifp_in
->name
);
4511 strcpy(in_ifname
, "<iif?>");
4515 /* Find the group, create it if it doesn't exist */
4516 json_object_object_get_ex(json
, grp_str
, &json_group
);
4519 json_group
= json_object_new_object();
4520 json_object_object_add(json
, grp_str
,
4524 /* Find the source nested under the group, create it if
4525 * it doesn't exist */
4526 json_object_object_get_ex(json_group
, src_str
,
4530 json_source
= json_object_new_object();
4531 json_object_object_add(json_group
, src_str
,
4535 /* Find the inbound interface nested under the source,
4536 * create it if it doesn't exist */
4537 json_object_int_add(json_source
, "installed",
4539 json_object_int_add(json_source
, "refCount",
4540 c_oil
->oil_ref_count
);
4541 json_object_int_add(json_source
, "oilSize",
4543 json_object_int_add(json_source
, "OilInheritedRescan",
4544 c_oil
->oil_inherited_rescan
);
4545 json_object_string_add(json_source
, "iif", in_ifname
);
4549 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
4551 struct interface
*ifp_out
;
4552 char oif_uptime
[10];
4555 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
4559 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
4561 oif_uptime
, sizeof(oif_uptime
),
4562 now
- c_oil
->oif_creation
[oif_vif_index
]);
4566 strcpy(out_ifname
, ifp_out
->name
);
4568 strcpy(out_ifname
, "<oif?>");
4571 json_ifp_out
= json_object_new_object();
4572 json_object_string_add(json_ifp_out
, "source",
4574 json_object_string_add(json_ifp_out
, "group",
4577 if (c_oil
->oif_flags
[oif_vif_index
]
4578 & PIM_OIF_FLAG_PROTO_PIM
)
4579 json_object_boolean_true_add(
4580 json_ifp_out
, "protocolPim");
4582 if (c_oil
->oif_flags
[oif_vif_index
]
4583 & PIM_OIF_FLAG_PROTO_IGMP
)
4584 json_object_boolean_true_add(
4585 json_ifp_out
, "protocolIgmp");
4587 if (c_oil
->oif_flags
[oif_vif_index
]
4588 & PIM_OIF_FLAG_PROTO_SOURCE
)
4589 json_object_boolean_true_add(
4590 json_ifp_out
, "protocolSource");
4592 if (c_oil
->oif_flags
[oif_vif_index
]
4593 & PIM_OIF_FLAG_PROTO_STAR
)
4594 json_object_boolean_true_add(
4596 "protocolInherited");
4598 json_object_string_add(json_ifp_out
,
4601 json_object_int_add(json_ifp_out
, "iVifI",
4602 c_oil
->oil
.mfcc_parent
);
4603 json_object_string_add(json_ifp_out
,
4604 "outboundInterface",
4606 json_object_int_add(json_ifp_out
, "oVifI",
4608 json_object_int_add(json_ifp_out
, "ttl", ttl
);
4609 json_object_string_add(json_ifp_out
, "upTime",
4612 json_oil
= json_object_new_object();
4613 json_object_object_add(json_source
,
4616 json_object_object_add(json_oil
, out_ifname
,
4619 if (c_oil
->oif_flags
[oif_vif_index
]
4620 & PIM_OIF_FLAG_PROTO_PIM
) {
4621 strcpy(proto
, "PIM");
4624 if (c_oil
->oif_flags
[oif_vif_index
]
4625 & PIM_OIF_FLAG_PROTO_IGMP
) {
4626 strcpy(proto
, "IGMP");
4629 if (c_oil
->oif_flags
[oif_vif_index
]
4630 & PIM_OIF_FLAG_PROTO_SOURCE
) {
4631 strcpy(proto
, "SRC");
4634 if (c_oil
->oif_flags
[oif_vif_index
]
4635 & PIM_OIF_FLAG_PROTO_STAR
) {
4636 strcpy(proto
, "STAR");
4640 "%-15s %-15s %-6s %-10s %-10s %-3d %8s\n",
4641 src_str
, grp_str
, proto
, in_ifname
,
4642 out_ifname
, ttl
, oif_uptime
);
4647 in_ifname
[0] = '\0';
4653 if (!uj
&& !found_oif
) {
4654 vty_out(vty
, "%-15s %-15s %-6s %-10s %-10s %-3d %8s\n",
4655 src_str
, grp_str
, "none", in_ifname
, "none", 0,
4660 /* Print list of static routes */
4661 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
4664 if (!s_route
->c_oil
.installed
)
4667 pim_inet4_dump("<group?>", s_route
->group
, grp_str
,
4669 pim_inet4_dump("<source?>", s_route
->source
, src_str
,
4671 ifp_in
= pim_if_find_by_vif_index(pim
, s_route
->iif
);
4675 strcpy(in_ifname
, ifp_in
->name
);
4677 strcpy(in_ifname
, "<iif?>");
4681 /* Find the group, create it if it doesn't exist */
4682 json_object_object_get_ex(json
, grp_str
, &json_group
);
4685 json_group
= json_object_new_object();
4686 json_object_object_add(json
, grp_str
,
4690 /* Find the source nested under the group, create it if
4691 * it doesn't exist */
4692 json_object_object_get_ex(json_group
, src_str
,
4696 json_source
= json_object_new_object();
4697 json_object_object_add(json_group
, src_str
,
4701 json_object_string_add(json_source
, "iif", in_ifname
);
4704 strcpy(proto
, "STATIC");
4707 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
4709 struct interface
*ifp_out
;
4710 char oif_uptime
[10];
4713 ttl
= s_route
->oif_ttls
[oif_vif_index
];
4717 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
4718 pim_time_uptime(oif_uptime
, sizeof(oif_uptime
),
4720 s_route
->c_oil
.oif_creation
[oif_vif_index
]);
4724 strcpy(out_ifname
, ifp_out
->name
);
4726 strcpy(out_ifname
, "<oif?>");
4729 json_ifp_out
= json_object_new_object();
4730 json_object_string_add(json_ifp_out
, "source",
4732 json_object_string_add(json_ifp_out
, "group",
4734 json_object_boolean_true_add(json_ifp_out
,
4736 json_object_string_add(json_ifp_out
,
4739 json_object_int_add(
4740 json_ifp_out
, "iVifI",
4741 s_route
->c_oil
.oil
.mfcc_parent
);
4742 json_object_string_add(json_ifp_out
,
4743 "outboundInterface",
4745 json_object_int_add(json_ifp_out
, "oVifI",
4747 json_object_int_add(json_ifp_out
, "ttl", ttl
);
4748 json_object_string_add(json_ifp_out
, "upTime",
4751 json_oil
= json_object_new_object();
4752 json_object_object_add(json_source
,
4755 json_object_object_add(json_oil
, out_ifname
,
4759 "%-15s %-15s %-6s %-10s %-10s %-3d %8s %s\n",
4760 src_str
, grp_str
, proto
, in_ifname
,
4761 out_ifname
, ttl
, oif_uptime
,
4763 if (first
&& !fill
) {
4766 in_ifname
[0] = '\0';
4772 if (!uj
&& !found_oif
) {
4774 "%-15s %-15s %-6s %-10s %-10s %-3d %8s %s\n",
4775 src_str
, grp_str
, proto
, in_ifname
, "none", 0,
4776 "--:--:--", pim
->vrf
->name
);
4781 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4782 json
, JSON_C_TO_STRING_PRETTY
));
4783 json_object_free(json
);
4787 DEFUN (show_ip_mroute
,
4789 "show ip mroute [vrf NAME] [fill] [json]",
4794 "Fill in Assumed data\n"
4797 u_char uj
= use_json(argc
, argv
);
4800 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4805 if (argv_find(argv
, argc
, "fill", &idx
))
4808 show_mroute(vrf
->info
, vty
, fill
, uj
);
4812 DEFUN (show_ip_mroute_vrf_all
,
4813 show_ip_mroute_vrf_all_cmd
,
4814 "show ip mroute vrf all [fill] [json]",
4819 "Fill in Assumed data\n"
4822 u_char uj
= use_json(argc
, argv
);
4828 if (argv_find(argv
, argc
, "fill", &idx
))
4833 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4837 vty_out(vty
, " \"%s\": ", vrf
->name
);
4840 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4841 show_mroute(vrf
->info
, vty
, fill
, uj
);
4844 vty_out(vty
, "}\n");
4849 static void show_mroute_count(struct pim_instance
*pim
, struct vty
*vty
)
4851 struct listnode
*node
;
4852 struct channel_oil
*c_oil
;
4853 struct static_route
*s_route
;
4858 "Source Group LastUsed Packets Bytes WrongIf \n");
4860 /* Print PIM and IGMP route counts */
4861 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
4862 char group_str
[INET_ADDRSTRLEN
];
4863 char source_str
[INET_ADDRSTRLEN
];
4865 if (!c_oil
->installed
)
4868 pim_mroute_update_counters(c_oil
);
4870 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, group_str
,
4872 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, source_str
,
4873 sizeof(source_str
));
4875 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
4876 source_str
, group_str
, c_oil
->cc
.lastused
/ 100,
4877 c_oil
->cc
.pktcnt
, c_oil
->cc
.bytecnt
,
4878 c_oil
->cc
.wrong_if
);
4881 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
4882 char group_str
[INET_ADDRSTRLEN
];
4883 char source_str
[INET_ADDRSTRLEN
];
4885 if (!s_route
->c_oil
.installed
)
4888 pim_mroute_update_counters(&s_route
->c_oil
);
4890 pim_inet4_dump("<group?>", s_route
->c_oil
.oil
.mfcc_mcastgrp
,
4891 group_str
, sizeof(group_str
));
4892 pim_inet4_dump("<source?>", s_route
->c_oil
.oil
.mfcc_origin
,
4893 source_str
, sizeof(source_str
));
4895 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
4896 source_str
, group_str
, s_route
->c_oil
.cc
.lastused
,
4897 s_route
->c_oil
.cc
.pktcnt
, s_route
->c_oil
.cc
.bytecnt
,
4898 s_route
->c_oil
.cc
.wrong_if
);
4902 DEFUN (show_ip_mroute_count
,
4903 show_ip_mroute_count_cmd
,
4904 "show ip mroute [vrf NAME] count",
4909 "Route and packet count data\n")
4912 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4917 show_mroute_count(vrf
->info
, vty
);
4921 DEFUN (show_ip_mroute_count_vrf_all
,
4922 show_ip_mroute_count_vrf_all_cmd
,
4923 "show ip mroute vrf all count",
4928 "Route and packet count data\n")
4930 u_char uj
= use_json(argc
, argv
);
4936 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4940 vty_out(vty
, " \"%s\": ", vrf
->name
);
4943 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4944 show_mroute_count(vrf
->info
, vty
);
4947 vty_out(vty
, "}\n");
4954 "show ip rib [vrf NAME] A.B.C.D",
4959 "Unicast address\n")
4962 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4963 struct in_addr addr
;
4964 const char *addr_str
;
4965 struct pim_nexthop nexthop
;
4966 char nexthop_addr_str
[PREFIX_STRLEN
];
4972 memset(&nexthop
, 0, sizeof(nexthop
));
4973 argv_find(argv
, argc
, "A.B.C.D", &idx
);
4974 addr_str
= argv
[idx
]->arg
;
4975 result
= inet_pton(AF_INET
, addr_str
, &addr
);
4977 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
4978 errno
, safe_strerror(errno
));
4982 if (pim_nexthop_lookup(vrf
->info
, &nexthop
, addr
, 0)) {
4984 "Failure querying RIB nexthop for unicast address %s\n",
4990 "Address NextHop Interface Metric Preference\n");
4992 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
4993 nexthop_addr_str
, sizeof(nexthop_addr_str
));
4995 vty_out(vty
, "%-15s %-15s %-9s %6d %10d\n", addr_str
, nexthop_addr_str
,
4996 nexthop
.interface
? nexthop
.interface
->name
: "<ifname?>",
4997 nexthop
.mrib_route_metric
, nexthop
.mrib_metric_preference
);
5002 static void show_ssmpingd(struct pim_instance
*pim
, struct vty
*vty
)
5004 struct listnode
*node
;
5005 struct ssmpingd_sock
*ss
;
5009 "Source Socket Address Port Uptime Requests\n");
5011 if (!pim
->ssmpingd_list
)
5014 now
= pim_time_monotonic_sec();
5016 for (ALL_LIST_ELEMENTS_RO(pim
->ssmpingd_list
, node
, ss
)) {
5017 char source_str
[INET_ADDRSTRLEN
];
5019 struct sockaddr_in bind_addr
;
5020 socklen_t len
= sizeof(bind_addr
);
5021 char bind_addr_str
[INET_ADDRSTRLEN
];
5023 pim_inet4_dump("<src?>", ss
->source_addr
, source_str
,
5024 sizeof(source_str
));
5026 if (pim_socket_getsockname(
5027 ss
->sock_fd
, (struct sockaddr
*)&bind_addr
, &len
)) {
5029 "%% Failure reading socket name for ssmpingd source %s on fd=%d\n",
5030 source_str
, ss
->sock_fd
);
5033 pim_inet4_dump("<addr?>", bind_addr
.sin_addr
, bind_addr_str
,
5034 sizeof(bind_addr_str
));
5035 pim_time_uptime(ss_uptime
, sizeof(ss_uptime
),
5036 now
- ss
->creation
);
5038 vty_out(vty
, "%-15s %6d %-15s %5d %8s %8lld\n", source_str
,
5039 ss
->sock_fd
, bind_addr_str
, ntohs(bind_addr
.sin_port
),
5040 ss_uptime
, (long long)ss
->requests
);
5044 DEFUN (show_ip_ssmpingd
,
5045 show_ip_ssmpingd_cmd
,
5046 "show ip ssmpingd [vrf NAME]",
5053 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5058 show_ssmpingd(vrf
->info
, vty
);
5062 static int pim_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
5063 const char *rp
, const char *group
,
5068 result
= pim_rp_new(pim
, rp
, group
, plist
);
5070 if (result
== PIM_MALLOC_FAIL
) {
5071 vty_out(vty
, "%% Out of memory\n");
5072 return CMD_WARNING_CONFIG_FAILED
;
5075 if (result
== PIM_GROUP_BAD_ADDRESS
) {
5076 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
5077 return CMD_WARNING_CONFIG_FAILED
;
5080 if (result
== PIM_RP_BAD_ADDRESS
) {
5081 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
5082 return CMD_WARNING_CONFIG_FAILED
;
5085 if (result
== PIM_RP_NO_PATH
) {
5086 vty_out(vty
, "%% No Path to RP address specified: %s\n", rp
);
5090 if (result
== PIM_GROUP_OVERLAP
) {
5091 vty_out(vty
, "%% Group range specified cannot exact match another\n");
5092 return CMD_WARNING_CONFIG_FAILED
;
5095 if (result
== PIM_GROUP_PFXLIST_OVERLAP
) {
5097 "%% This group is already covered by a RP prefix-list\n");
5098 return CMD_WARNING_CONFIG_FAILED
;
5101 if (result
== PIM_RP_PFXLIST_IN_USE
) {
5103 "%% The same prefix-list cannot be applied to multiple RPs\n");
5104 return CMD_WARNING_CONFIG_FAILED
;
5110 static int pim_cmd_spt_switchover(struct pim_instance
*pim
,
5111 enum pim_spt_switchover spt
,
5114 pim
->spt
.switchover
= spt
;
5116 switch (pim
->spt
.switchover
) {
5117 case PIM_SPT_IMMEDIATE
:
5119 XFREE(MTYPE_PIM_SPT_PLIST_NAME
, pim
->spt
.plist
);
5121 pim_upstream_add_lhr_star_pimreg(pim
);
5123 case PIM_SPT_INFINITY
:
5124 pim_upstream_remove_lhr_star_pimreg(pim
, plist
);
5127 XFREE(MTYPE_PIM_SPT_PLIST_NAME
, pim
->spt
.plist
);
5131 XSTRDUP(MTYPE_PIM_SPT_PLIST_NAME
, plist
);
5138 DEFUN (ip_pim_spt_switchover_infinity
,
5139 ip_pim_spt_switchover_infinity_cmd
,
5140 "ip pim spt-switchover infinity-and-beyond",
5144 "Never switch to SPT Tree\n")
5146 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5147 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, NULL
);
5150 DEFUN (ip_pim_spt_switchover_infinity_plist
,
5151 ip_pim_spt_switchover_infinity_plist_cmd
,
5152 "ip pim spt-switchover infinity-and-beyond prefix-list WORD",
5156 "Never switch to SPT Tree\n"
5157 "Prefix-List to control which groups to switch\n"
5158 "Prefix-List name\n")
5160 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5161 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, argv
[5]->arg
);
5164 DEFUN (no_ip_pim_spt_switchover_infinity
,
5165 no_ip_pim_spt_switchover_infinity_cmd
,
5166 "no ip pim spt-switchover infinity-and-beyond",
5171 "Never switch to SPT Tree\n")
5173 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5174 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
5177 DEFUN (no_ip_pim_spt_switchover_infinity_plist
,
5178 no_ip_pim_spt_switchover_infinity_plist_cmd
,
5179 "no ip pim spt-switchover infinity-and-beyond prefix-list WORD",
5184 "Never switch to SPT Tree\n"
5185 "Prefix-List to control which groups to switch\n"
5186 "Prefix-List name\n")
5188 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5189 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
5192 DEFUN (ip_pim_joinprune_time
,
5193 ip_pim_joinprune_time_cmd
,
5194 "ip pim join-prune-interval (60-600)",
5196 "pim multicast routing\n"
5197 "Join Prune Send Interval\n"
5200 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5201 qpim_t_periodic
= atoi(argv
[3]->arg
);
5205 DEFUN (no_ip_pim_joinprune_time
,
5206 no_ip_pim_joinprune_time_cmd
,
5207 "no ip pim join-prune-interval (60-600)",
5210 "pim multicast routing\n"
5211 "Join Prune Send Interval\n"
5214 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5215 qpim_t_periodic
= PIM_DEFAULT_T_PERIODIC
;
5219 DEFUN (ip_pim_register_suppress
,
5220 ip_pim_register_suppress_cmd
,
5221 "ip pim register-suppress-time (5-60000)",
5223 "pim multicast routing\n"
5224 "Register Suppress Timer\n"
5227 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5228 qpim_register_suppress_time
= atoi(argv
[3]->arg
);
5232 DEFUN (no_ip_pim_register_suppress
,
5233 no_ip_pim_register_suppress_cmd
,
5234 "no ip pim register-suppress-time (5-60000)",
5237 "pim multicast routing\n"
5238 "Register Suppress Timer\n"
5241 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5242 qpim_register_suppress_time
= PIM_REGISTER_SUPPRESSION_TIME_DEFAULT
;
5246 DEFUN (ip_pim_rp_keep_alive
,
5247 ip_pim_rp_keep_alive_cmd
,
5248 "ip pim rp keep-alive-timer (31-60000)",
5250 "pim multicast routing\n"
5252 "Keep alive Timer\n"
5255 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5256 pim
->rp_keep_alive_time
= atoi(argv
[4]->arg
);
5260 DEFUN (no_ip_pim_rp_keep_alive
,
5261 no_ip_pim_rp_keep_alive_cmd
,
5262 "no ip pim rp keep-alive-timer (31-60000)",
5265 "pim multicast routing\n"
5267 "Keep alive Timer\n"
5270 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5271 pim
->rp_keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
5275 DEFUN (ip_pim_keep_alive
,
5276 ip_pim_keep_alive_cmd
,
5277 "ip pim keep-alive-timer (31-60000)",
5279 "pim multicast routing\n"
5280 "Keep alive Timer\n"
5283 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5284 pim
->keep_alive_time
= atoi(argv
[3]->arg
);
5288 DEFUN (no_ip_pim_keep_alive
,
5289 no_ip_pim_keep_alive_cmd
,
5290 "no ip pim keep-alive-timer (31-60000)",
5293 "pim multicast routing\n"
5294 "Keep alive Timer\n"
5297 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5298 pim
->keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
5302 DEFUN (ip_pim_packets
,
5304 "ip pim packets (1-100)",
5306 "pim multicast routing\n"
5307 "packets to process at one time per fd\n"
5308 "Number of packets\n")
5310 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5311 qpim_packet_process
= atoi(argv
[3]->arg
);
5315 DEFUN (no_ip_pim_packets
,
5316 no_ip_pim_packets_cmd
,
5317 "no ip pim packets (1-100)",
5320 "pim multicast routing\n"
5321 "packets to process at one time per fd\n"
5322 "Number of packets\n")
5324 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5325 qpim_packet_process
= PIM_DEFAULT_PACKET_PROCESS
;
5329 DEFUN (ip_pim_v6_secondary
,
5330 ip_pim_v6_secondary_cmd
,
5331 "ip pim send-v6-secondary",
5333 "pim multicast routing\n"
5334 "Send v6 secondary addresses\n")
5336 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5337 pim
->send_v6_secondary
= 1;
5342 DEFUN (no_ip_pim_v6_secondary
,
5343 no_ip_pim_v6_secondary_cmd
,
5344 "no ip pim send-v6-secondary",
5347 "pim multicast routing\n"
5348 "Send v6 secondary addresses\n")
5350 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5351 pim
->send_v6_secondary
= 0;
5358 "ip pim rp A.B.C.D [A.B.C.D/M]",
5360 "pim multicast routing\n"
5362 "ip address of RP\n"
5363 "Group Address range to cover\n")
5365 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5368 if (argc
== (idx_ipv4
+ 1))
5369 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
5372 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
5373 argv
[idx_ipv4
+ 1]->arg
, NULL
);
5376 DEFUN (ip_pim_rp_prefix_list
,
5377 ip_pim_rp_prefix_list_cmd
,
5378 "ip pim rp A.B.C.D prefix-list WORD",
5380 "pim multicast routing\n"
5382 "ip address of RP\n"
5383 "group prefix-list filter\n"
5384 "Name of a prefix-list\n")
5386 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5387 return pim_rp_cmd_worker(pim
, vty
, argv
[3]->arg
, NULL
, argv
[5]->arg
);
5390 static int pim_no_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
5391 const char *rp
, const char *group
,
5394 int result
= pim_rp_del(pim
, rp
, group
, plist
);
5396 if (result
== PIM_GROUP_BAD_ADDRESS
) {
5397 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
5398 return CMD_WARNING_CONFIG_FAILED
;
5401 if (result
== PIM_RP_BAD_ADDRESS
) {
5402 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
5403 return CMD_WARNING_CONFIG_FAILED
;
5406 if (result
== PIM_RP_NOT_FOUND
) {
5407 vty_out(vty
, "%% Unable to find specified RP\n");
5408 return CMD_WARNING_CONFIG_FAILED
;
5414 DEFUN (no_ip_pim_rp
,
5416 "no ip pim rp A.B.C.D [A.B.C.D/M]",
5419 "pim multicast routing\n"
5421 "ip address of RP\n"
5422 "Group Address range to cover\n")
5424 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5425 int idx_ipv4
= 4, idx_group
= 0;
5427 if (argv_find(argv
, argc
, "A.B.C.D/M", &idx_group
))
5428 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
5429 argv
[idx_group
]->arg
, NULL
);
5431 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
5435 DEFUN (no_ip_pim_rp_prefix_list
,
5436 no_ip_pim_rp_prefix_list_cmd
,
5437 "no ip pim rp A.B.C.D prefix-list WORD",
5440 "pim multicast routing\n"
5442 "ip address of RP\n"
5443 "group prefix-list filter\n"
5444 "Name of a prefix-list\n")
5446 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5447 return pim_no_rp_cmd_worker(pim
, vty
, argv
[4]->arg
, NULL
, argv
[6]->arg
);
5450 static int pim_ssm_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
5453 int result
= pim_ssm_range_set(pim
, pim
->vrf_id
, plist
);
5455 if (result
== PIM_SSM_ERR_NONE
)
5459 case PIM_SSM_ERR_NO_VRF
:
5460 vty_out(vty
, "%% VRF doesn't exist\n");
5462 case PIM_SSM_ERR_DUP
:
5463 vty_out(vty
, "%% duplicate config\n");
5466 vty_out(vty
, "%% ssm range config failed\n");
5469 return CMD_WARNING_CONFIG_FAILED
;
5472 DEFUN (ip_pim_ssm_prefix_list
,
5473 ip_pim_ssm_prefix_list_cmd
,
5474 "ip pim ssm prefix-list WORD",
5476 "pim multicast routing\n"
5477 "Source Specific Multicast\n"
5478 "group range prefix-list filter\n"
5479 "Name of a prefix-list\n")
5481 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5482 return pim_ssm_cmd_worker(pim
, vty
, argv
[4]->arg
);
5485 DEFUN (no_ip_pim_ssm_prefix_list
,
5486 no_ip_pim_ssm_prefix_list_cmd
,
5487 "no ip pim ssm prefix-list",
5490 "pim multicast routing\n"
5491 "Source Specific Multicast\n"
5492 "group range prefix-list filter\n")
5494 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5495 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
5498 DEFUN (no_ip_pim_ssm_prefix_list_name
,
5499 no_ip_pim_ssm_prefix_list_name_cmd
,
5500 "no ip pim ssm prefix-list WORD",
5503 "pim multicast routing\n"
5504 "Source Specific Multicast\n"
5505 "group range prefix-list filter\n"
5506 "Name of a prefix-list\n")
5508 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5509 struct pim_ssm
*ssm
= pim
->ssm_info
;
5511 if (ssm
->plist_name
&& !strcmp(ssm
->plist_name
, argv
[5]->arg
))
5512 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
5514 vty_out(vty
, "%% pim ssm prefix-list %s doesn't exist\n", argv
[5]->arg
);
5516 return CMD_WARNING_CONFIG_FAILED
;
5519 static void ip_pim_ssm_show_group_range(struct pim_instance
*pim
,
5520 struct vty
*vty
, u_char uj
)
5522 struct pim_ssm
*ssm
= pim
->ssm_info
;
5523 const char *range_str
=
5524 ssm
->plist_name
? ssm
->plist_name
: PIM_SSM_STANDARD_RANGE
;
5528 json
= json_object_new_object();
5529 json_object_string_add(json
, "ssmGroups", range_str
);
5530 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5531 json
, JSON_C_TO_STRING_PRETTY
));
5532 json_object_free(json
);
5534 vty_out(vty
, "SSM group range : %s\n", range_str
);
5537 DEFUN (show_ip_pim_ssm_range
,
5538 show_ip_pim_ssm_range_cmd
,
5539 "show ip pim [vrf NAME] group-type [json]",
5548 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5549 u_char uj
= use_json(argc
, argv
);
5554 ip_pim_ssm_show_group_range(vrf
->info
, vty
, uj
);
5559 static void ip_pim_ssm_show_group_type(struct pim_instance
*pim
,
5560 struct vty
*vty
, u_char uj
,
5563 struct in_addr group_addr
;
5564 const char *type_str
;
5567 result
= inet_pton(AF_INET
, group
, &group_addr
);
5569 type_str
= "invalid";
5571 if (pim_is_group_224_4(group_addr
))
5573 pim_is_grp_ssm(pim
, group_addr
) ? "SSM" : "ASM";
5575 type_str
= "not-multicast";
5580 json
= json_object_new_object();
5581 json_object_string_add(json
, "groupType", type_str
);
5582 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5583 json
, JSON_C_TO_STRING_PRETTY
));
5584 json_object_free(json
);
5586 vty_out(vty
, "Group type : %s\n", type_str
);
5589 DEFUN (show_ip_pim_group_type
,
5590 show_ip_pim_group_type_cmd
,
5591 "show ip pim [vrf NAME] group-type A.B.C.D [json]",
5596 "multicast group type\n"
5601 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5602 u_char uj
= use_json(argc
, argv
);
5607 argv_find(argv
, argc
, "A.B.C.D", &idx
);
5608 ip_pim_ssm_show_group_type(vrf
->info
, vty
, uj
, argv
[idx
]->arg
);
5613 DEFUN_HIDDEN (ip_multicast_routing
,
5614 ip_multicast_routing_cmd
,
5615 "ip multicast-routing",
5617 "Enable IP multicast forwarding\n")
5622 DEFUN_HIDDEN (no_ip_multicast_routing
,
5623 no_ip_multicast_routing_cmd
,
5624 "no ip multicast-routing",
5627 "Enable IP multicast forwarding\n")
5630 "Command is Disabled and will be removed in a future version\n");
5636 "ip ssmpingd [A.B.C.D]",
5641 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5644 struct in_addr source_addr
;
5645 const char *source_str
= (argc
== 3) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
5647 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
5649 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
5650 source_str
, errno
, safe_strerror(errno
));
5651 return CMD_WARNING_CONFIG_FAILED
;
5654 result
= pim_ssmpingd_start(pim
, source_addr
);
5656 vty_out(vty
, "%% Failure starting ssmpingd for source %s: %d\n",
5657 source_str
, result
);
5658 return CMD_WARNING_CONFIG_FAILED
;
5664 DEFUN (no_ip_ssmpingd
,
5666 "no ip ssmpingd [A.B.C.D]",
5672 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5675 struct in_addr source_addr
;
5676 const char *source_str
= (argc
== 4) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
5678 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
5680 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
5681 source_str
, errno
, safe_strerror(errno
));
5682 return CMD_WARNING_CONFIG_FAILED
;
5685 result
= pim_ssmpingd_stop(pim
, source_addr
);
5687 vty_out(vty
, "%% Failure stopping ssmpingd for source %s: %d\n",
5688 source_str
, result
);
5689 return CMD_WARNING_CONFIG_FAILED
;
5699 "pim multicast routing\n"
5700 "Enable PIM ECMP \n")
5702 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5703 qpim_ecmp_enable
= 1;
5708 DEFUN (no_ip_pim_ecmp
,
5713 "pim multicast routing\n"
5714 "Disable PIM ECMP \n")
5716 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5717 qpim_ecmp_enable
= 0;
5722 DEFUN (ip_pim_ecmp_rebalance
,
5723 ip_pim_ecmp_rebalance_cmd
,
5724 "ip pim ecmp rebalance",
5726 "pim multicast routing\n"
5727 "Enable PIM ECMP \n"
5728 "Enable PIM ECMP Rebalance\n")
5730 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5731 qpim_ecmp_enable
= 1;
5732 qpim_ecmp_rebalance_enable
= 1;
5737 DEFUN (no_ip_pim_ecmp_rebalance
,
5738 no_ip_pim_ecmp_rebalance_cmd
,
5739 "no ip pim ecmp rebalance",
5742 "pim multicast routing\n"
5743 "Disable PIM ECMP \n"
5744 "Disable PIM ECMP Rebalance\n")
5746 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5747 qpim_ecmp_rebalance_enable
= 0;
5752 static int pim_cmd_igmp_start(struct vty
*vty
, struct interface
*ifp
)
5754 struct pim_interface
*pim_ifp
;
5755 uint8_t need_startup
= 0;
5757 pim_ifp
= ifp
->info
;
5760 pim_ifp
= pim_if_new(ifp
, 1 /* igmp=true */, 0 /* pim=false */);
5762 vty_out(vty
, "Could not enable IGMP on interface %s\n",
5764 return CMD_WARNING_CONFIG_FAILED
;
5768 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
5769 PIM_IF_DO_IGMP(pim_ifp
->options
);
5774 /* 'ip igmp' executed multiple times, with need_startup
5775 avoid multiple if add all and membership refresh */
5777 pim_if_addr_add_all(ifp
);
5778 pim_if_membership_refresh(ifp
);
5784 DEFUN (interface_ip_igmp
,
5785 interface_ip_igmp_cmd
,
5790 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5792 return pim_cmd_igmp_start(vty
, ifp
);
5795 DEFUN (interface_no_ip_igmp
,
5796 interface_no_ip_igmp_cmd
,
5802 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5803 struct pim_interface
*pim_ifp
= ifp
->info
;
5808 PIM_IF_DONT_IGMP(pim_ifp
->options
);
5810 pim_if_membership_clear(ifp
);
5812 pim_if_addr_del_all_igmp(ifp
);
5814 if (!PIM_IF_TEST_PIM(pim_ifp
->options
)) {
5821 DEFUN (interface_ip_igmp_join
,
5822 interface_ip_igmp_join_cmd
,
5823 "ip igmp join A.B.C.D A.B.C.D",
5826 "IGMP join multicast group\n"
5827 "Multicast group address\n"
5830 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5833 const char *group_str
;
5834 const char *source_str
;
5835 struct in_addr group_addr
;
5836 struct in_addr source_addr
;
5840 group_str
= argv
[idx_ipv4
]->arg
;
5841 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
5843 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
5844 errno
, safe_strerror(errno
));
5845 return CMD_WARNING_CONFIG_FAILED
;
5848 /* Source address */
5849 source_str
= argv
[idx_ipv4_2
]->arg
;
5850 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
5852 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
5853 source_str
, errno
, safe_strerror(errno
));
5854 return CMD_WARNING_CONFIG_FAILED
;
5857 CMD_FERR_RETURN(pim_if_igmp_join_add(ifp
, group_addr
, source_addr
),
5858 "Failure joining IGMP group: $ERR");
5863 DEFUN (interface_no_ip_igmp_join
,
5864 interface_no_ip_igmp_join_cmd
,
5865 "no ip igmp join A.B.C.D A.B.C.D",
5869 "IGMP join multicast group\n"
5870 "Multicast group address\n"
5873 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5876 const char *group_str
;
5877 const char *source_str
;
5878 struct in_addr group_addr
;
5879 struct in_addr source_addr
;
5883 group_str
= argv
[idx_ipv4
]->arg
;
5884 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
5886 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
5887 errno
, safe_strerror(errno
));
5888 return CMD_WARNING_CONFIG_FAILED
;
5891 /* Source address */
5892 source_str
= argv
[idx_ipv4_2
]->arg
;
5893 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
5895 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
5896 source_str
, errno
, safe_strerror(errno
));
5897 return CMD_WARNING_CONFIG_FAILED
;
5900 result
= pim_if_igmp_join_del(ifp
, group_addr
, source_addr
);
5903 "%% Failure leaving IGMP group %s source %s on interface %s: %d\n",
5904 group_str
, source_str
, ifp
->name
, result
);
5905 return CMD_WARNING_CONFIG_FAILED
;
5912 CLI reconfiguration affects the interface level (struct pim_interface).
5913 This function propagates the reconfiguration to every active socket
5916 static void igmp_sock_query_interval_reconfig(struct igmp_sock
*igmp
)
5918 struct interface
*ifp
;
5919 struct pim_interface
*pim_ifp
;
5923 /* other querier present? */
5925 if (igmp
->t_other_querier_timer
)
5928 /* this is the querier */
5930 zassert(igmp
->interface
);
5931 zassert(igmp
->interface
->info
);
5933 ifp
= igmp
->interface
;
5934 pim_ifp
= ifp
->info
;
5936 if (PIM_DEBUG_IGMP_TRACE
) {
5937 char ifaddr_str
[INET_ADDRSTRLEN
];
5938 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
5939 sizeof(ifaddr_str
));
5940 zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
5941 __PRETTY_FUNCTION__
, ifaddr_str
, ifp
->name
,
5942 pim_ifp
->igmp_default_query_interval
);
5946 igmp_startup_mode_on() will reset QQI:
5948 igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
5950 igmp_startup_mode_on(igmp
);
5953 static void igmp_sock_query_reschedule(struct igmp_sock
*igmp
)
5955 if (igmp
->t_igmp_query_timer
) {
5956 /* other querier present */
5957 zassert(igmp
->t_igmp_query_timer
);
5958 zassert(!igmp
->t_other_querier_timer
);
5960 pim_igmp_general_query_off(igmp
);
5961 pim_igmp_general_query_on(igmp
);
5963 zassert(igmp
->t_igmp_query_timer
);
5964 zassert(!igmp
->t_other_querier_timer
);
5966 /* this is the querier */
5968 zassert(!igmp
->t_igmp_query_timer
);
5969 zassert(igmp
->t_other_querier_timer
);
5971 pim_igmp_other_querier_timer_off(igmp
);
5972 pim_igmp_other_querier_timer_on(igmp
);
5974 zassert(!igmp
->t_igmp_query_timer
);
5975 zassert(igmp
->t_other_querier_timer
);
5979 static void change_query_interval(struct pim_interface
*pim_ifp
,
5982 struct listnode
*sock_node
;
5983 struct igmp_sock
*igmp
;
5985 pim_ifp
->igmp_default_query_interval
= query_interval
;
5987 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
5988 igmp_sock_query_interval_reconfig(igmp
);
5989 igmp_sock_query_reschedule(igmp
);
5993 static void change_query_max_response_time(struct pim_interface
*pim_ifp
,
5994 int query_max_response_time_dsec
)
5996 struct listnode
*sock_node
;
5997 struct igmp_sock
*igmp
;
5999 pim_ifp
->igmp_query_max_response_time_dsec
=
6000 query_max_response_time_dsec
;
6003 Below we modify socket/group/source timers in order to quickly
6004 reflect the change. Otherwise, those timers would eventually catch
6008 /* scan all sockets */
6009 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
6010 struct listnode
*grp_node
;
6011 struct igmp_group
*grp
;
6013 /* reschedule socket general query */
6014 igmp_sock_query_reschedule(igmp
);
6016 /* scan socket groups */
6017 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grp_node
,
6019 struct listnode
*src_node
;
6020 struct igmp_source
*src
;
6022 /* reset group timers for groups in EXCLUDE mode */
6023 if (grp
->group_filtermode_isexcl
) {
6024 igmp_group_reset_gmi(grp
);
6027 /* scan group sources */
6028 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
,
6031 /* reset source timers for sources with running
6033 if (src
->t_source_timer
) {
6034 igmp_source_reset_gmi(igmp
, grp
, src
);
6041 #define IGMP_QUERY_INTERVAL_MIN (1)
6042 #define IGMP_QUERY_INTERVAL_MAX (1800)
6044 DEFUN (interface_ip_igmp_query_interval
,
6045 interface_ip_igmp_query_interval_cmd
,
6046 "ip igmp query-interval (1-1800)",
6049 IFACE_IGMP_QUERY_INTERVAL_STR
6050 "Query interval in seconds\n")
6052 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6053 struct pim_interface
*pim_ifp
= ifp
->info
;
6055 int query_interval_dsec
;
6059 ret
= pim_cmd_igmp_start(vty
, ifp
);
6060 if (ret
!= CMD_SUCCESS
)
6062 pim_ifp
= ifp
->info
;
6065 query_interval
= atoi(argv
[3]->arg
);
6066 query_interval_dsec
= 10 * query_interval
;
6069 It seems we don't need to check bounds since command.c does it
6070 already, but we verify them anyway for extra safety.
6072 if (query_interval
< IGMP_QUERY_INTERVAL_MIN
) {
6074 "General query interval %d lower than minimum %d\n",
6075 query_interval
, IGMP_QUERY_INTERVAL_MIN
);
6076 return CMD_WARNING_CONFIG_FAILED
;
6078 if (query_interval
> IGMP_QUERY_INTERVAL_MAX
) {
6080 "General query interval %d higher than maximum %d\n",
6081 query_interval
, IGMP_QUERY_INTERVAL_MAX
);
6082 return CMD_WARNING_CONFIG_FAILED
;
6085 if (query_interval_dsec
<= pim_ifp
->igmp_query_max_response_time_dsec
) {
6087 "Can't set general query interval %d dsec <= query max response time %d dsec.\n",
6088 query_interval_dsec
,
6089 pim_ifp
->igmp_query_max_response_time_dsec
);
6090 return CMD_WARNING_CONFIG_FAILED
;
6093 change_query_interval(pim_ifp
, query_interval
);
6098 DEFUN (interface_no_ip_igmp_query_interval
,
6099 interface_no_ip_igmp_query_interval_cmd
,
6100 "no ip igmp query-interval",
6104 IFACE_IGMP_QUERY_INTERVAL_STR
)
6106 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6107 struct pim_interface
*pim_ifp
= ifp
->info
;
6108 int default_query_interval_dsec
;
6113 default_query_interval_dsec
= IGMP_GENERAL_QUERY_INTERVAL
* 10;
6115 if (default_query_interval_dsec
6116 <= pim_ifp
->igmp_query_max_response_time_dsec
) {
6118 "Can't set default general query interval %d dsec <= query max response time %d dsec.\n",
6119 default_query_interval_dsec
,
6120 pim_ifp
->igmp_query_max_response_time_dsec
);
6121 return CMD_WARNING_CONFIG_FAILED
;
6124 change_query_interval(pim_ifp
, IGMP_GENERAL_QUERY_INTERVAL
);
6129 DEFUN (interface_ip_igmp_version
,
6130 interface_ip_igmp_version_cmd
,
6131 "ip igmp version (2-3)",
6135 "IGMP version number\n")
6137 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6138 struct pim_interface
*pim_ifp
= ifp
->info
;
6139 int igmp_version
, old_version
= 0;
6143 ret
= pim_cmd_igmp_start(vty
, ifp
);
6144 if (ret
!= CMD_SUCCESS
)
6146 pim_ifp
= ifp
->info
;
6149 igmp_version
= atoi(argv
[3]->arg
);
6150 old_version
= pim_ifp
->igmp_version
;
6151 pim_ifp
->igmp_version
= igmp_version
;
6153 // Check if IGMP is Enabled otherwise, enable on interface
6154 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
6155 PIM_IF_DO_IGMP(pim_ifp
->options
);
6156 pim_if_addr_add_all(ifp
);
6157 pim_if_membership_refresh(ifp
);
6158 old_version
= igmp_version
; // avoid refreshing membership
6161 /* Current and new version is different refresh existing
6162 membership. Going from 3 -> 2 or 2 -> 3. */
6163 if (old_version
!= igmp_version
)
6164 pim_if_membership_refresh(ifp
);
6169 DEFUN (interface_no_ip_igmp_version
,
6170 interface_no_ip_igmp_version_cmd
,
6171 "no ip igmp version (2-3)",
6176 "IGMP version number\n")
6178 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6179 struct pim_interface
*pim_ifp
= ifp
->info
;
6184 pim_ifp
->igmp_version
= IGMP_DEFAULT_VERSION
;
6189 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
6190 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
6192 DEFUN (interface_ip_igmp_query_max_response_time
,
6193 interface_ip_igmp_query_max_response_time_cmd
,
6194 "ip igmp query-max-response-time (10-250)",
6197 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
6198 "Query response value in deci-seconds\n")
6200 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6201 struct pim_interface
*pim_ifp
= ifp
->info
;
6202 int query_max_response_time
;
6206 ret
= pim_cmd_igmp_start(vty
, ifp
);
6207 if (ret
!= CMD_SUCCESS
)
6209 pim_ifp
= ifp
->info
;
6212 query_max_response_time
= atoi(argv
[3]->arg
);
6214 if (query_max_response_time
6215 >= pim_ifp
->igmp_default_query_interval
* 10) {
6217 "Can't set query max response time %d sec >= general query interval %d sec\n",
6218 query_max_response_time
,
6219 pim_ifp
->igmp_default_query_interval
);
6220 return CMD_WARNING_CONFIG_FAILED
;
6223 change_query_max_response_time(pim_ifp
, query_max_response_time
);
6228 DEFUN (interface_no_ip_igmp_query_max_response_time
,
6229 interface_no_ip_igmp_query_max_response_time_cmd
,
6230 "no ip igmp query-max-response-time (10-250)",
6234 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
6235 "Time for response in deci-seconds\n")
6237 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6238 struct pim_interface
*pim_ifp
= ifp
->info
;
6243 change_query_max_response_time(pim_ifp
,
6244 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
6249 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
6250 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
6252 DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec
,
6253 interface_ip_igmp_query_max_response_time_dsec_cmd
,
6254 "ip igmp query-max-response-time-dsec (10-250)",
6257 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
6258 "Query response value in deciseconds\n")
6260 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6261 struct pim_interface
*pim_ifp
= ifp
->info
;
6262 int query_max_response_time_dsec
;
6263 int default_query_interval_dsec
;
6267 ret
= pim_cmd_igmp_start(vty
, ifp
);
6268 if (ret
!= CMD_SUCCESS
)
6270 pim_ifp
= ifp
->info
;
6273 query_max_response_time_dsec
= atoi(argv
[4]->arg
);
6275 default_query_interval_dsec
= 10 * pim_ifp
->igmp_default_query_interval
;
6277 if (query_max_response_time_dsec
>= default_query_interval_dsec
) {
6279 "Can't set query max response time %d dsec >= general query interval %d dsec\n",
6280 query_max_response_time_dsec
,
6281 default_query_interval_dsec
);
6282 return CMD_WARNING_CONFIG_FAILED
;
6285 change_query_max_response_time(pim_ifp
, query_max_response_time_dsec
);
6290 DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec
,
6291 interface_no_ip_igmp_query_max_response_time_dsec_cmd
,
6292 "no ip igmp query-max-response-time-dsec",
6296 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
)
6298 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6299 struct pim_interface
*pim_ifp
= ifp
->info
;
6304 change_query_max_response_time(pim_ifp
,
6305 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
6310 DEFUN (interface_ip_pim_drprio
,
6311 interface_ip_pim_drprio_cmd
,
6312 "ip pim drpriority (1-4294967295)",
6315 "Set the Designated Router Election Priority\n"
6316 "Value of the new DR Priority\n")
6318 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6320 struct pim_interface
*pim_ifp
= ifp
->info
;
6321 uint32_t old_dr_prio
;
6324 vty_out(vty
, "Please enable PIM on interface, first\n");
6325 return CMD_WARNING_CONFIG_FAILED
;
6328 old_dr_prio
= pim_ifp
->pim_dr_priority
;
6330 pim_ifp
->pim_dr_priority
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
6332 if (old_dr_prio
!= pim_ifp
->pim_dr_priority
) {
6333 if (pim_if_dr_election(ifp
))
6334 pim_hello_restart_now(ifp
);
6340 DEFUN (interface_no_ip_pim_drprio
,
6341 interface_no_ip_pim_drprio_cmd
,
6342 "no ip pim drpriority [(1-4294967295)]",
6346 "Revert the Designated Router Priority to default\n"
6347 "Old Value of the Priority\n")
6349 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6350 struct pim_interface
*pim_ifp
= ifp
->info
;
6353 vty_out(vty
, "Pim not enabled on this interface\n");
6354 return CMD_WARNING_CONFIG_FAILED
;
6357 if (pim_ifp
->pim_dr_priority
!= PIM_DEFAULT_DR_PRIORITY
) {
6358 pim_ifp
->pim_dr_priority
= PIM_DEFAULT_DR_PRIORITY
;
6359 if (pim_if_dr_election(ifp
))
6360 pim_hello_restart_now(ifp
);
6366 static int pim_cmd_interface_add(struct interface
*ifp
)
6368 struct pim_interface
*pim_ifp
= ifp
->info
;
6371 pim_ifp
= pim_if_new(ifp
, 0 /* igmp=false */, 1 /* pim=true */);
6376 PIM_IF_DO_PIM(pim_ifp
->options
);
6379 pim_if_addr_add_all(ifp
);
6380 pim_if_membership_refresh(ifp
);
6384 DEFUN_HIDDEN (interface_ip_pim_ssm
,
6385 interface_ip_pim_ssm_cmd
,
6391 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6393 if (!pim_cmd_interface_add(ifp
)) {
6394 vty_out(vty
, "Could not enable PIM SM on interface\n");
6395 return CMD_WARNING_CONFIG_FAILED
;
6399 "WARN: Enabled PIM SM on interface; configure PIM SSM "
6400 "range if needed\n");
6404 DEFUN (interface_ip_pim_sm
,
6405 interface_ip_pim_sm_cmd
,
6411 struct pim_interface
*pim_ifp
;
6413 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6414 if (!pim_cmd_interface_add(ifp
)) {
6415 vty_out(vty
, "Could not enable PIM SM on interface\n");
6416 return CMD_WARNING_CONFIG_FAILED
;
6419 pim_ifp
= ifp
->info
;
6421 pim_if_create_pimreg(pim_ifp
->pim
);
6426 static int pim_cmd_interface_delete(struct interface
*ifp
)
6428 struct pim_interface
*pim_ifp
= ifp
->info
;
6433 PIM_IF_DONT_PIM(pim_ifp
->options
);
6435 pim_if_membership_clear(ifp
);
6438 pim_sock_delete() removes all neighbors from
6439 pim_ifp->pim_neighbor_list.
6441 pim_sock_delete(ifp
, "pim unconfigured on interface");
6443 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
6444 pim_if_addr_del_all(ifp
);
6451 DEFUN_HIDDEN (interface_no_ip_pim_ssm
,
6452 interface_no_ip_pim_ssm_cmd
,
6459 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6460 if (!pim_cmd_interface_delete(ifp
)) {
6461 vty_out(vty
, "Unable to delete interface information\n");
6462 return CMD_WARNING_CONFIG_FAILED
;
6468 DEFUN (interface_no_ip_pim_sm
,
6469 interface_no_ip_pim_sm_cmd
,
6476 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6477 if (!pim_cmd_interface_delete(ifp
)) {
6478 vty_out(vty
, "Unable to delete interface information\n");
6479 return CMD_WARNING_CONFIG_FAILED
;
6486 DEFUN(interface_ip_pim_boundary_oil
,
6487 interface_ip_pim_boundary_oil_cmd
,
6488 "ip multicast boundary oil WORD",
6490 "Generic multicast configuration options\n"
6491 "Define multicast boundary\n"
6492 "Filter OIL by group using prefix list\n"
6493 "Prefix list to filter OIL with\n")
6495 VTY_DECLVAR_CONTEXT(interface
, iif
);
6496 struct pim_interface
*pim_ifp
;
6499 argv_find(argv
, argc
, "WORD", &idx
);
6501 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6503 if (pim_ifp
->boundary_oil_plist
)
6504 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
6506 pim_ifp
->boundary_oil_plist
=
6507 XSTRDUP(MTYPE_PIM_INTERFACE
, argv
[idx
]->arg
);
6509 /* Interface will be pruned from OIL on next Join */
6513 DEFUN(interface_no_ip_pim_boundary_oil
,
6514 interface_no_ip_pim_boundary_oil_cmd
,
6515 "no ip multicast boundary oil [WORD]",
6518 "Generic multicast configuration options\n"
6519 "Define multicast boundary\n"
6520 "Filter OIL by group using prefix list\n"
6521 "Prefix list to filter OIL with\n")
6523 VTY_DECLVAR_CONTEXT(interface
, iif
);
6524 struct pim_interface
*pim_ifp
;
6527 argv_find(argv
, argc
, "WORD", &idx
);
6529 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6531 if (pim_ifp
->boundary_oil_plist
)
6532 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
6537 DEFUN (interface_ip_mroute
,
6538 interface_ip_mroute_cmd
,
6539 "ip mroute INTERFACE A.B.C.D",
6541 "Add multicast route\n"
6542 "Outgoing interface name\n"
6545 VTY_DECLVAR_CONTEXT(interface
, iif
);
6546 struct pim_interface
*pim_ifp
;
6547 struct pim_instance
*pim
;
6548 int idx_interface
= 2;
6550 struct interface
*oif
;
6551 const char *oifname
;
6552 const char *grp_str
;
6553 struct in_addr grp_addr
;
6554 struct in_addr src_addr
;
6557 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6560 oifname
= argv
[idx_interface
]->arg
;
6561 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6563 vty_out(vty
, "No such interface name %s\n", oifname
);
6567 grp_str
= argv
[idx_ipv4
]->arg
;
6568 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6570 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6571 errno
, safe_strerror(errno
));
6575 src_addr
.s_addr
= INADDR_ANY
;
6577 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6578 vty_out(vty
, "Failed to add route\n");
6585 DEFUN (interface_ip_mroute_source
,
6586 interface_ip_mroute_source_cmd
,
6587 "ip mroute INTERFACE A.B.C.D A.B.C.D",
6589 "Add multicast route\n"
6590 "Outgoing interface name\n"
6594 VTY_DECLVAR_CONTEXT(interface
, iif
);
6595 struct pim_interface
*pim_ifp
;
6596 struct pim_instance
*pim
;
6597 int idx_interface
= 2;
6600 struct interface
*oif
;
6601 const char *oifname
;
6602 const char *grp_str
;
6603 struct in_addr grp_addr
;
6604 const char *src_str
;
6605 struct in_addr src_addr
;
6608 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6611 oifname
= argv
[idx_interface
]->arg
;
6612 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6614 vty_out(vty
, "No such interface name %s\n", oifname
);
6618 grp_str
= argv
[idx_ipv4
]->arg
;
6619 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6621 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6622 errno
, safe_strerror(errno
));
6626 src_str
= argv
[idx_ipv4_2
]->arg
;
6627 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
6629 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
6630 errno
, safe_strerror(errno
));
6634 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6635 vty_out(vty
, "Failed to add route\n");
6642 DEFUN (interface_no_ip_mroute
,
6643 interface_no_ip_mroute_cmd
,
6644 "no ip mroute INTERFACE A.B.C.D",
6647 "Add multicast route\n"
6648 "Outgoing interface name\n"
6651 VTY_DECLVAR_CONTEXT(interface
, iif
);
6652 struct pim_interface
*pim_ifp
;
6653 struct pim_instance
*pim
;
6654 int idx_interface
= 3;
6656 struct interface
*oif
;
6657 const char *oifname
;
6658 const char *grp_str
;
6659 struct in_addr grp_addr
;
6660 struct in_addr src_addr
;
6663 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6666 oifname
= argv
[idx_interface
]->arg
;
6667 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6669 vty_out(vty
, "No such interface name %s\n", oifname
);
6673 grp_str
= argv
[idx_ipv4
]->arg
;
6674 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6676 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6677 errno
, safe_strerror(errno
));
6681 src_addr
.s_addr
= INADDR_ANY
;
6683 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6684 vty_out(vty
, "Failed to remove route\n");
6691 DEFUN (interface_no_ip_mroute_source
,
6692 interface_no_ip_mroute_source_cmd
,
6693 "no ip mroute INTERFACE A.B.C.D A.B.C.D",
6696 "Add multicast route\n"
6697 "Outgoing interface name\n"
6701 VTY_DECLVAR_CONTEXT(interface
, iif
);
6702 struct pim_interface
*pim_ifp
;
6703 struct pim_instance
*pim
;
6704 int idx_interface
= 3;
6707 struct interface
*oif
;
6708 const char *oifname
;
6709 const char *grp_str
;
6710 struct in_addr grp_addr
;
6711 const char *src_str
;
6712 struct in_addr src_addr
;
6715 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6718 oifname
= argv
[idx_interface
]->arg
;
6719 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6721 vty_out(vty
, "No such interface name %s\n", oifname
);
6725 grp_str
= argv
[idx_ipv4
]->arg
;
6726 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6728 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6729 errno
, safe_strerror(errno
));
6733 src_str
= argv
[idx_ipv4_2
]->arg
;
6734 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
6736 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
6737 errno
, safe_strerror(errno
));
6741 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6742 vty_out(vty
, "Failed to remove route\n");
6749 DEFUN (interface_ip_pim_hello
,
6750 interface_ip_pim_hello_cmd
,
6751 "ip pim hello (1-180) [(1-180)]",
6755 IFACE_PIM_HELLO_TIME_STR
6756 IFACE_PIM_HELLO_HOLD_STR
)
6758 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6761 struct pim_interface
*pim_ifp
= ifp
->info
;
6764 if (!pim_cmd_interface_add(ifp
)) {
6765 vty_out(vty
, "Could not enable PIM SM on interface\n");
6766 return CMD_WARNING_CONFIG_FAILED
;
6770 pim_ifp
= ifp
->info
;
6771 pim_ifp
->pim_hello_period
= strtol(argv
[idx_time
]->arg
, NULL
, 10);
6773 if (argc
== idx_hold
+ 1)
6774 pim_ifp
->pim_default_holdtime
=
6775 strtol(argv
[idx_hold
]->arg
, NULL
, 10);
6780 DEFUN (interface_no_ip_pim_hello
,
6781 interface_no_ip_pim_hello_cmd
,
6782 "no ip pim hello [(1-180) (1-180)]",
6787 IFACE_PIM_HELLO_TIME_STR
6788 IFACE_PIM_HELLO_HOLD_STR
)
6790 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6791 struct pim_interface
*pim_ifp
= ifp
->info
;
6794 vty_out(vty
, "Pim not enabled on this interface\n");
6795 return CMD_WARNING_CONFIG_FAILED
;
6798 pim_ifp
->pim_hello_period
= PIM_DEFAULT_HELLO_PERIOD
;
6799 pim_ifp
->pim_default_holdtime
= -1;
6810 PIM_DO_DEBUG_IGMP_EVENTS
;
6811 PIM_DO_DEBUG_IGMP_PACKETS
;
6812 PIM_DO_DEBUG_IGMP_TRACE
;
6816 DEFUN (no_debug_igmp
,
6823 PIM_DONT_DEBUG_IGMP_EVENTS
;
6824 PIM_DONT_DEBUG_IGMP_PACKETS
;
6825 PIM_DONT_DEBUG_IGMP_TRACE
;
6830 DEFUN (debug_igmp_events
,
6831 debug_igmp_events_cmd
,
6832 "debug igmp events",
6835 DEBUG_IGMP_EVENTS_STR
)
6837 PIM_DO_DEBUG_IGMP_EVENTS
;
6841 DEFUN (no_debug_igmp_events
,
6842 no_debug_igmp_events_cmd
,
6843 "no debug igmp events",
6847 DEBUG_IGMP_EVENTS_STR
)
6849 PIM_DONT_DEBUG_IGMP_EVENTS
;
6854 DEFUN (debug_igmp_packets
,
6855 debug_igmp_packets_cmd
,
6856 "debug igmp packets",
6859 DEBUG_IGMP_PACKETS_STR
)
6861 PIM_DO_DEBUG_IGMP_PACKETS
;
6865 DEFUN (no_debug_igmp_packets
,
6866 no_debug_igmp_packets_cmd
,
6867 "no debug igmp packets",
6871 DEBUG_IGMP_PACKETS_STR
)
6873 PIM_DONT_DEBUG_IGMP_PACKETS
;
6878 DEFUN (debug_igmp_trace
,
6879 debug_igmp_trace_cmd
,
6883 DEBUG_IGMP_TRACE_STR
)
6885 PIM_DO_DEBUG_IGMP_TRACE
;
6889 DEFUN (no_debug_igmp_trace
,
6890 no_debug_igmp_trace_cmd
,
6891 "no debug igmp trace",
6895 DEBUG_IGMP_TRACE_STR
)
6897 PIM_DONT_DEBUG_IGMP_TRACE
;
6902 DEFUN (debug_mroute
,
6908 PIM_DO_DEBUG_MROUTE
;
6912 DEFUN (debug_mroute_detail
,
6913 debug_mroute_detail_cmd
,
6914 "debug mroute detail",
6919 PIM_DO_DEBUG_MROUTE_DETAIL
;
6923 DEFUN (no_debug_mroute
,
6924 no_debug_mroute_cmd
,
6930 PIM_DONT_DEBUG_MROUTE
;
6934 DEFUN (no_debug_mroute_detail
,
6935 no_debug_mroute_detail_cmd
,
6936 "no debug mroute detail",
6942 PIM_DONT_DEBUG_MROUTE_DETAIL
;
6946 DEFUN (debug_static
,
6952 PIM_DO_DEBUG_STATIC
;
6956 DEFUN (no_debug_static
,
6957 no_debug_static_cmd
,
6963 PIM_DONT_DEBUG_STATIC
;
6974 PIM_DO_DEBUG_PIM_EVENTS
;
6975 PIM_DO_DEBUG_PIM_PACKETS
;
6976 PIM_DO_DEBUG_PIM_TRACE
;
6977 PIM_DO_DEBUG_MSDP_EVENTS
;
6978 PIM_DO_DEBUG_MSDP_PACKETS
;
6982 DEFUN (no_debug_pim
,
6989 PIM_DONT_DEBUG_PIM_EVENTS
;
6990 PIM_DONT_DEBUG_PIM_PACKETS
;
6991 PIM_DONT_DEBUG_PIM_TRACE
;
6992 PIM_DONT_DEBUG_MSDP_EVENTS
;
6993 PIM_DONT_DEBUG_MSDP_PACKETS
;
6995 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
6996 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
7001 DEFUN (debug_pim_nht
,
7006 "Nexthop Tracking\n")
7008 PIM_DO_DEBUG_PIM_NHT
;
7012 DEFUN (no_debug_pim_nht
,
7013 no_debug_pim_nht_cmd
,
7018 "Nexthop Tracking\n")
7020 PIM_DONT_DEBUG_PIM_NHT
;
7024 DEFUN (debug_pim_nht_rp
,
7025 debug_pim_nht_rp_cmd
,
7029 "Nexthop Tracking\n"
7030 "RP Nexthop Tracking\n")
7032 PIM_DO_DEBUG_PIM_NHT_RP
;
7036 DEFUN (no_debug_pim_nht_rp
,
7037 no_debug_pim_nht_rp_cmd
,
7038 "no debug pim nht rp",
7042 "Nexthop Tracking\n"
7043 "RP Nexthop Tracking\n")
7045 PIM_DONT_DEBUG_PIM_NHT_RP
;
7049 DEFUN (debug_pim_events
,
7050 debug_pim_events_cmd
,
7054 DEBUG_PIM_EVENTS_STR
)
7056 PIM_DO_DEBUG_PIM_EVENTS
;
7060 DEFUN (no_debug_pim_events
,
7061 no_debug_pim_events_cmd
,
7062 "no debug pim events",
7066 DEBUG_PIM_EVENTS_STR
)
7068 PIM_DONT_DEBUG_PIM_EVENTS
;
7072 DEFUN (debug_pim_packets
,
7073 debug_pim_packets_cmd
,
7074 "debug pim packets [<hello|joins|register>]",
7077 DEBUG_PIM_PACKETS_STR
7078 DEBUG_PIM_HELLO_PACKETS_STR
7079 DEBUG_PIM_J_P_PACKETS_STR
7080 DEBUG_PIM_PIM_REG_PACKETS_STR
)
7083 if (argv_find(argv
, argc
, "hello", &idx
)) {
7084 PIM_DO_DEBUG_PIM_HELLO
;
7085 vty_out(vty
, "PIM Hello debugging is on\n");
7086 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
7087 PIM_DO_DEBUG_PIM_J_P
;
7088 vty_out(vty
, "PIM Join/Prune debugging is on\n");
7089 } else if (argv_find(argv
, argc
, "register", &idx
)) {
7090 PIM_DO_DEBUG_PIM_REG
;
7091 vty_out(vty
, "PIM Register debugging is on\n");
7093 PIM_DO_DEBUG_PIM_PACKETS
;
7094 vty_out(vty
, "PIM Packet debugging is on \n");
7099 DEFUN (no_debug_pim_packets
,
7100 no_debug_pim_packets_cmd
,
7101 "no debug pim packets [<hello|joins|register>]",
7105 DEBUG_PIM_PACKETS_STR
7106 DEBUG_PIM_HELLO_PACKETS_STR
7107 DEBUG_PIM_J_P_PACKETS_STR
7108 DEBUG_PIM_PIM_REG_PACKETS_STR
)
7111 if (argv_find(argv
, argc
, "hello", &idx
)) {
7112 PIM_DONT_DEBUG_PIM_HELLO
;
7113 vty_out(vty
, "PIM Hello debugging is off \n");
7114 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
7115 PIM_DONT_DEBUG_PIM_J_P
;
7116 vty_out(vty
, "PIM Join/Prune debugging is off \n");
7117 } else if (argv_find(argv
, argc
, "register", &idx
)) {
7118 PIM_DONT_DEBUG_PIM_REG
;
7119 vty_out(vty
, "PIM Register debugging is off\n");
7121 PIM_DONT_DEBUG_PIM_PACKETS
;
7127 DEFUN (debug_pim_packetdump_send
,
7128 debug_pim_packetdump_send_cmd
,
7129 "debug pim packet-dump send",
7132 DEBUG_PIM_PACKETDUMP_STR
7133 DEBUG_PIM_PACKETDUMP_SEND_STR
)
7135 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND
;
7139 DEFUN (no_debug_pim_packetdump_send
,
7140 no_debug_pim_packetdump_send_cmd
,
7141 "no debug pim packet-dump send",
7145 DEBUG_PIM_PACKETDUMP_STR
7146 DEBUG_PIM_PACKETDUMP_SEND_STR
)
7148 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
7152 DEFUN (debug_pim_packetdump_recv
,
7153 debug_pim_packetdump_recv_cmd
,
7154 "debug pim packet-dump receive",
7157 DEBUG_PIM_PACKETDUMP_STR
7158 DEBUG_PIM_PACKETDUMP_RECV_STR
)
7160 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV
;
7164 DEFUN (no_debug_pim_packetdump_recv
,
7165 no_debug_pim_packetdump_recv_cmd
,
7166 "no debug pim packet-dump receive",
7170 DEBUG_PIM_PACKETDUMP_STR
7171 DEBUG_PIM_PACKETDUMP_RECV_STR
)
7173 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
7177 DEFUN (debug_pim_trace
,
7178 debug_pim_trace_cmd
,
7182 DEBUG_PIM_TRACE_STR
)
7184 PIM_DO_DEBUG_PIM_TRACE
;
7188 DEFUN (debug_pim_trace_detail
,
7189 debug_pim_trace_detail_cmd
,
7190 "debug pim trace detail",
7194 "Detailed Information\n")
7196 PIM_DO_DEBUG_PIM_TRACE_DETAIL
;
7200 DEFUN (no_debug_pim_trace
,
7201 no_debug_pim_trace_cmd
,
7202 "no debug pim trace",
7206 DEBUG_PIM_TRACE_STR
)
7208 PIM_DONT_DEBUG_PIM_TRACE
;
7212 DEFUN (no_debug_pim_trace_detail
,
7213 no_debug_pim_trace_detail_cmd
,
7214 "no debug pim trace detail",
7219 "Detailed Information\n")
7221 PIM_DONT_DEBUG_PIM_TRACE_DETAIL
;
7225 DEFUN (debug_ssmpingd
,
7231 PIM_DO_DEBUG_SSMPINGD
;
7235 DEFUN (no_debug_ssmpingd
,
7236 no_debug_ssmpingd_cmd
,
7237 "no debug ssmpingd",
7242 PIM_DONT_DEBUG_SSMPINGD
;
7246 DEFUN (debug_pim_zebra
,
7247 debug_pim_zebra_cmd
,
7251 DEBUG_PIM_ZEBRA_STR
)
7257 DEFUN (no_debug_pim_zebra
,
7258 no_debug_pim_zebra_cmd
,
7259 "no debug pim zebra",
7263 DEBUG_PIM_ZEBRA_STR
)
7265 PIM_DONT_DEBUG_ZEBRA
;
7275 PIM_DO_DEBUG_MSDP_EVENTS
;
7276 PIM_DO_DEBUG_MSDP_PACKETS
;
7280 DEFUN (no_debug_msdp
,
7287 PIM_DONT_DEBUG_MSDP_EVENTS
;
7288 PIM_DONT_DEBUG_MSDP_PACKETS
;
7292 ALIAS(no_debug_msdp
, undebug_msdp_cmd
, "undebug msdp",
7293 UNDEBUG_STR DEBUG_MSDP_STR
)
7295 DEFUN (debug_msdp_events
,
7296 debug_msdp_events_cmd
,
7297 "debug msdp events",
7300 DEBUG_MSDP_EVENTS_STR
)
7302 PIM_DO_DEBUG_MSDP_EVENTS
;
7306 DEFUN (no_debug_msdp_events
,
7307 no_debug_msdp_events_cmd
,
7308 "no debug msdp events",
7312 DEBUG_MSDP_EVENTS_STR
)
7314 PIM_DONT_DEBUG_MSDP_EVENTS
;
7318 ALIAS(no_debug_msdp_events
, undebug_msdp_events_cmd
, "undebug msdp events",
7319 UNDEBUG_STR DEBUG_MSDP_STR DEBUG_MSDP_EVENTS_STR
)
7321 DEFUN (debug_msdp_packets
,
7322 debug_msdp_packets_cmd
,
7323 "debug msdp packets",
7326 DEBUG_MSDP_PACKETS_STR
)
7328 PIM_DO_DEBUG_MSDP_PACKETS
;
7332 DEFUN (no_debug_msdp_packets
,
7333 no_debug_msdp_packets_cmd
,
7334 "no debug msdp packets",
7338 DEBUG_MSDP_PACKETS_STR
)
7340 PIM_DONT_DEBUG_MSDP_PACKETS
;
7344 ALIAS(no_debug_msdp_packets
, undebug_msdp_packets_cmd
, "undebug msdp packets",
7345 UNDEBUG_STR DEBUG_MSDP_STR DEBUG_MSDP_PACKETS_STR
)
7347 DEFUN_NOSH (show_debugging_pim
,
7348 show_debugging_pim_cmd
,
7349 "show debugging [pim]",
7354 vty_out(vty
, "PIM debugging status\n");
7356 pim_debug_config_write(vty
);
7361 static int interface_pim_use_src_cmd_worker(struct vty
*vty
, const char *source
)
7364 struct in_addr source_addr
;
7365 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7367 result
= inet_pton(AF_INET
, source
, &source_addr
);
7369 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", source
,
7370 errno
, safe_strerror(errno
));
7371 return CMD_WARNING_CONFIG_FAILED
;
7374 result
= pim_update_source_set(ifp
, source_addr
);
7378 case PIM_IFACE_NOT_FOUND
:
7379 vty_out(vty
, "Pim not enabled on this interface\n");
7381 case PIM_UPDATE_SOURCE_DUP
:
7382 vty_out(vty
, "%% Source already set to %s\n", source
);
7385 vty_out(vty
, "%% Source set failed\n");
7388 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7391 DEFUN (interface_pim_use_source
,
7392 interface_pim_use_source_cmd
,
7393 "ip pim use-source A.B.C.D",
7395 "pim multicast routing\n"
7396 "Configure primary IP address\n"
7397 "source ip address\n")
7399 return interface_pim_use_src_cmd_worker(vty
, argv
[3]->arg
);
7402 DEFUN (interface_no_pim_use_source
,
7403 interface_no_pim_use_source_cmd
,
7404 "no ip pim use-source [A.B.C.D]",
7407 "pim multicast routing\n"
7408 "Delete source IP address\n"
7409 "source ip address\n")
7411 return interface_pim_use_src_cmd_worker(vty
, "0.0.0.0");
7419 "Enables BFD support\n")
7421 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7422 struct pim_interface
*pim_ifp
= ifp
->info
;
7423 struct bfd_info
*bfd_info
= NULL
;
7426 if (!pim_cmd_interface_add(ifp
)) {
7427 vty_out(vty
, "Could not enable PIM SM on interface\n");
7431 pim_ifp
= ifp
->info
;
7433 bfd_info
= pim_ifp
->bfd_info
;
7435 if (!bfd_info
|| !CHECK_FLAG(bfd_info
->flags
, BFD_FLAG_PARAM_CFG
))
7436 pim_bfd_if_param_set(ifp
, BFD_DEF_MIN_RX
, BFD_DEF_MIN_TX
,
7437 BFD_DEF_DETECT_MULT
, 1);
7442 DEFUN (no_ip_pim_bfd
,
7448 "Disables BFD support\n")
7450 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7451 struct pim_interface
*pim_ifp
= ifp
->info
;
7454 vty_out(vty
, "Pim not enabled on this interface\n");
7458 if (pim_ifp
->bfd_info
) {
7459 pim_bfd_reg_dereg_all_nbr(ifp
, ZEBRA_BFD_DEST_DEREGISTER
);
7460 bfd_info_free(&(pim_ifp
->bfd_info
));
7466 DEFUN (ip_pim_bfd_param
,
7467 ip_pim_bfd_param_cmd
,
7468 "ip pim bfd (2-255) (50-60000) (50-60000)",
7471 "Enables BFD support\n"
7472 "Detect Multiplier\n"
7473 "Required min receive interval\n"
7474 "Desired min transmit interval\n")
7476 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7478 int idx_number_2
= 4;
7479 int idx_number_3
= 5;
7484 struct pim_interface
*pim_ifp
= ifp
->info
;
7487 if (!pim_cmd_interface_add(ifp
)) {
7488 vty_out(vty
, "Could not enable PIM SM on interface\n");
7493 if ((ret
= bfd_validate_param(
7494 vty
, argv
[idx_number
]->arg
, argv
[idx_number_2
]->arg
,
7495 argv
[idx_number_3
]->arg
, &dm_val
, &rx_val
, &tx_val
))
7499 pim_bfd_if_param_set(ifp
, rx_val
, tx_val
, dm_val
, 0);
7504 ALIAS(no_ip_pim_bfd
, no_ip_pim_bfd_param_cmd
,
7505 "no ip pim bfd (2-255) (50-60000) (50-60000)", NO_STR IP_STR PIM_STR
7506 "Enables BFD support\n"
7507 "Detect Multiplier\n"
7508 "Required min receive interval\n"
7509 "Desired min transmit interval\n")
7511 static int ip_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
7512 const char *peer
, const char *local
)
7514 enum pim_msdp_err result
;
7515 struct in_addr peer_addr
;
7516 struct in_addr local_addr
;
7518 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
7520 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
7521 errno
, safe_strerror(errno
));
7522 return CMD_WARNING_CONFIG_FAILED
;
7525 result
= inet_pton(AF_INET
, local
, &local_addr
);
7527 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", local
,
7528 errno
, safe_strerror(errno
));
7529 return CMD_WARNING_CONFIG_FAILED
;
7532 result
= pim_msdp_peer_add(pim
, peer_addr
, local_addr
, "default",
7535 case PIM_MSDP_ERR_NONE
:
7537 case PIM_MSDP_ERR_OOM
:
7538 vty_out(vty
, "%% Out of memory\n");
7540 case PIM_MSDP_ERR_PEER_EXISTS
:
7541 vty_out(vty
, "%% Peer exists\n");
7543 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
7544 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
7547 vty_out(vty
, "%% peer add failed\n");
7550 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7553 DEFUN_HIDDEN (ip_msdp_peer
,
7555 "ip msdp peer A.B.C.D source A.B.C.D",
7558 "Configure MSDP peer\n"
7560 "Source address for TCP connection\n"
7561 "local ip address\n")
7563 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7564 return ip_msdp_peer_cmd_worker(pim
, vty
, argv
[3]->arg
, argv
[5]->arg
);
7567 static int ip_no_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
7570 enum pim_msdp_err result
;
7571 struct in_addr peer_addr
;
7573 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
7575 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
7576 errno
, safe_strerror(errno
));
7577 return CMD_WARNING_CONFIG_FAILED
;
7580 result
= pim_msdp_peer_del(pim
, peer_addr
);
7582 case PIM_MSDP_ERR_NONE
:
7584 case PIM_MSDP_ERR_NO_PEER
:
7585 vty_out(vty
, "%% Peer does not exist\n");
7588 vty_out(vty
, "%% peer del failed\n");
7591 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7594 DEFUN_HIDDEN (no_ip_msdp_peer
,
7595 no_ip_msdp_peer_cmd
,
7596 "no ip msdp peer A.B.C.D",
7600 "Delete MSDP peer\n"
7601 "peer ip address\n")
7603 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7604 return ip_no_msdp_peer_cmd_worker(pim
, vty
, argv
[4]->arg
);
7607 static int ip_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
7608 struct vty
*vty
, const char *mg
,
7611 enum pim_msdp_err result
;
7612 struct in_addr mbr_ip
;
7614 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
7616 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
7617 errno
, safe_strerror(errno
));
7618 return CMD_WARNING_CONFIG_FAILED
;
7621 result
= pim_msdp_mg_mbr_add(pim
, mg
, mbr_ip
);
7623 case PIM_MSDP_ERR_NONE
:
7625 case PIM_MSDP_ERR_OOM
:
7626 vty_out(vty
, "%% Out of memory\n");
7628 case PIM_MSDP_ERR_MG_MBR_EXISTS
:
7629 vty_out(vty
, "%% mesh-group member exists\n");
7631 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
7632 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
7635 vty_out(vty
, "%% member add failed\n");
7638 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7641 DEFUN (ip_msdp_mesh_group_member
,
7642 ip_msdp_mesh_group_member_cmd
,
7643 "ip msdp mesh-group WORD member A.B.C.D",
7646 "Configure MSDP mesh-group\n"
7648 "mesh group member\n"
7649 "peer ip address\n")
7651 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7652 return ip_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[3]->arg
,
7656 static int ip_no_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
7661 enum pim_msdp_err result
;
7662 struct in_addr mbr_ip
;
7664 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
7666 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
7667 errno
, safe_strerror(errno
));
7668 return CMD_WARNING_CONFIG_FAILED
;
7671 result
= pim_msdp_mg_mbr_del(pim
, mg
, mbr_ip
);
7673 case PIM_MSDP_ERR_NONE
:
7675 case PIM_MSDP_ERR_NO_MG
:
7676 vty_out(vty
, "%% mesh-group does not exist\n");
7678 case PIM_MSDP_ERR_NO_MG_MBR
:
7679 vty_out(vty
, "%% mesh-group member does not exist\n");
7682 vty_out(vty
, "%% mesh-group member del failed\n");
7685 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7687 DEFUN (no_ip_msdp_mesh_group_member
,
7688 no_ip_msdp_mesh_group_member_cmd
,
7689 "no ip msdp mesh-group WORD member A.B.C.D",
7693 "Delete MSDP mesh-group member\n"
7695 "mesh group member\n"
7696 "peer ip address\n")
7698 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7699 return ip_no_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[4]->arg
,
7703 static int ip_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
7704 struct vty
*vty
, const char *mg
,
7707 enum pim_msdp_err result
;
7708 struct in_addr src_ip
;
7710 result
= inet_pton(AF_INET
, src
, &src_ip
);
7712 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", src
,
7713 errno
, safe_strerror(errno
));
7714 return CMD_WARNING_CONFIG_FAILED
;
7717 result
= pim_msdp_mg_src_add(pim
, mg
, src_ip
);
7719 case PIM_MSDP_ERR_NONE
:
7721 case PIM_MSDP_ERR_OOM
:
7722 vty_out(vty
, "%% Out of memory\n");
7724 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
7725 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
7728 vty_out(vty
, "%% source add failed\n");
7731 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7735 DEFUN (ip_msdp_mesh_group_source
,
7736 ip_msdp_mesh_group_source_cmd
,
7737 "ip msdp mesh-group WORD source A.B.C.D",
7740 "Configure MSDP mesh-group\n"
7742 "mesh group local address\n"
7743 "source ip address for the TCP connection\n")
7745 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7746 return ip_msdp_mesh_group_source_cmd_worker(pim
, vty
, argv
[3]->arg
,
7750 static int ip_no_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
7754 enum pim_msdp_err result
;
7756 result
= pim_msdp_mg_src_del(pim
, mg
);
7758 case PIM_MSDP_ERR_NONE
:
7760 case PIM_MSDP_ERR_NO_MG
:
7761 vty_out(vty
, "%% mesh-group does not exist\n");
7764 vty_out(vty
, "%% mesh-group source del failed\n");
7767 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7770 static int ip_no_msdp_mesh_group_cmd_worker(struct pim_instance
*pim
,
7771 struct vty
*vty
, const char *mg
)
7773 enum pim_msdp_err result
;
7775 result
= pim_msdp_mg_del(pim
, mg
);
7777 case PIM_MSDP_ERR_NONE
:
7779 case PIM_MSDP_ERR_NO_MG
:
7780 vty_out(vty
, "%% mesh-group does not exist\n");
7783 vty_out(vty
, "%% mesh-group source del failed\n");
7786 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7789 DEFUN (no_ip_msdp_mesh_group_source
,
7790 no_ip_msdp_mesh_group_source_cmd
,
7791 "no ip msdp mesh-group WORD source [A.B.C.D]",
7795 "Delete MSDP mesh-group source\n"
7797 "mesh group source\n"
7798 "mesh group local address\n")
7800 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7802 return ip_no_msdp_mesh_group_cmd_worker(pim
, vty
, argv
[6]->arg
);
7804 return ip_no_msdp_mesh_group_source_cmd_worker(pim
, vty
,
7808 static void print_empty_json_obj(struct vty
*vty
)
7811 json
= json_object_new_object();
7812 vty_out(vty
, "%s\n",
7813 json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
));
7814 json_object_free(json
);
7817 static void ip_msdp_show_mesh_group(struct pim_instance
*pim
, struct vty
*vty
,
7820 struct listnode
*mbrnode
;
7821 struct pim_msdp_mg_mbr
*mbr
;
7822 struct pim_msdp_mg
*mg
= pim
->msdp
.mg
;
7823 char mbr_str
[INET_ADDRSTRLEN
];
7824 char src_str
[INET_ADDRSTRLEN
];
7825 char state_str
[PIM_MSDP_STATE_STRLEN
];
7826 enum pim_msdp_peer_state state
;
7827 json_object
*json
= NULL
;
7828 json_object
*json_mg_row
= NULL
;
7829 json_object
*json_members
= NULL
;
7830 json_object
*json_row
= NULL
;
7834 print_empty_json_obj(vty
);
7838 pim_inet4_dump("<source?>", mg
->src_ip
, src_str
, sizeof(src_str
));
7840 json
= json_object_new_object();
7841 /* currently there is only one mesh group but we should still
7843 * it a dict with mg-name as key */
7844 json_mg_row
= json_object_new_object();
7845 json_object_string_add(json_mg_row
, "name",
7846 mg
->mesh_group_name
);
7847 json_object_string_add(json_mg_row
, "source", src_str
);
7849 vty_out(vty
, "Mesh group : %s\n", mg
->mesh_group_name
);
7850 vty_out(vty
, " Source : %s\n", src_str
);
7851 vty_out(vty
, " Member State\n");
7854 for (ALL_LIST_ELEMENTS_RO(mg
->mbr_list
, mbrnode
, mbr
)) {
7855 pim_inet4_dump("<mbr?>", mbr
->mbr_ip
, mbr_str
, sizeof(mbr_str
));
7857 state
= mbr
->mp
->state
;
7859 state
= PIM_MSDP_DISABLED
;
7861 pim_msdp_state_dump(state
, state_str
, sizeof(state_str
));
7863 json_row
= json_object_new_object();
7864 json_object_string_add(json_row
, "member", mbr_str
);
7865 json_object_string_add(json_row
, "state", state_str
);
7866 if (!json_members
) {
7867 json_members
= json_object_new_object();
7868 json_object_object_add(json_mg_row
, "members",
7871 json_object_object_add(json_members
, mbr_str
, json_row
);
7873 vty_out(vty
, " %-15s %11s\n", mbr_str
, state_str
);
7878 json_object_object_add(json
, mg
->mesh_group_name
, json_mg_row
);
7879 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
7880 json
, JSON_C_TO_STRING_PRETTY
));
7881 json_object_free(json
);
7885 DEFUN (show_ip_msdp_mesh_group
,
7886 show_ip_msdp_mesh_group_cmd
,
7887 "show ip msdp [vrf NAME] mesh-group [json]",
7892 "MSDP mesh-group information\n"
7895 u_char uj
= use_json(argc
, argv
);
7897 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
7902 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
7907 DEFUN (show_ip_msdp_mesh_group_vrf_all
,
7908 show_ip_msdp_mesh_group_vrf_all_cmd
,
7909 "show ip msdp vrf all mesh-group [json]",
7914 "MSDP mesh-group information\n"
7917 u_char uj
= use_json(argc
, argv
);
7923 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
7927 vty_out(vty
, " \"%s\": ", vrf
->name
);
7930 vty_out(vty
, "VRF: %s\n", vrf
->name
);
7931 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
7934 vty_out(vty
, "}\n");
7939 static void ip_msdp_show_peers(struct pim_instance
*pim
, struct vty
*vty
,
7942 struct listnode
*mpnode
;
7943 struct pim_msdp_peer
*mp
;
7944 char peer_str
[INET_ADDRSTRLEN
];
7945 char local_str
[INET_ADDRSTRLEN
];
7946 char state_str
[PIM_MSDP_STATE_STRLEN
];
7947 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
7949 json_object
*json
= NULL
;
7950 json_object
*json_row
= NULL
;
7954 json
= json_object_new_object();
7957 "Peer Local State Uptime SaCnt\n");
7960 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
7961 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
7962 now
= pim_time_monotonic_sec();
7963 pim_time_uptime(timebuf
, sizeof(timebuf
),
7966 strcpy(timebuf
, "-");
7968 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
7969 pim_inet4_dump("<local?>", mp
->local
, local_str
,
7971 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
7973 json_row
= json_object_new_object();
7974 json_object_string_add(json_row
, "peer", peer_str
);
7975 json_object_string_add(json_row
, "local", local_str
);
7976 json_object_string_add(json_row
, "state", state_str
);
7977 json_object_string_add(json_row
, "upTime", timebuf
);
7978 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
7979 json_object_object_add(json
, peer_str
, json_row
);
7981 vty_out(vty
, "%-15s %15s %11s %8s %6d\n", peer_str
,
7982 local_str
, state_str
, timebuf
, mp
->sa_cnt
);
7987 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
7988 json
, JSON_C_TO_STRING_PRETTY
));
7989 json_object_free(json
);
7993 static void ip_msdp_show_peers_detail(struct pim_instance
*pim
, struct vty
*vty
,
7994 const char *peer
, u_char uj
)
7996 struct listnode
*mpnode
;
7997 struct pim_msdp_peer
*mp
;
7998 char peer_str
[INET_ADDRSTRLEN
];
7999 char local_str
[INET_ADDRSTRLEN
];
8000 char state_str
[PIM_MSDP_STATE_STRLEN
];
8001 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
8002 char katimer
[PIM_MSDP_TIMER_STRLEN
];
8003 char crtimer
[PIM_MSDP_TIMER_STRLEN
];
8004 char holdtimer
[PIM_MSDP_TIMER_STRLEN
];
8006 json_object
*json
= NULL
;
8007 json_object
*json_row
= NULL
;
8010 json
= json_object_new_object();
8013 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
8014 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
8015 if (strcmp(peer
, "detail") && strcmp(peer
, peer_str
))
8018 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
8019 now
= pim_time_monotonic_sec();
8020 pim_time_uptime(timebuf
, sizeof(timebuf
),
8023 strcpy(timebuf
, "-");
8025 pim_inet4_dump("<local?>", mp
->local
, local_str
,
8027 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
8028 pim_time_timer_to_hhmmss(katimer
, sizeof(katimer
),
8030 pim_time_timer_to_hhmmss(crtimer
, sizeof(crtimer
),
8032 pim_time_timer_to_hhmmss(holdtimer
, sizeof(holdtimer
),
8036 json_row
= json_object_new_object();
8037 json_object_string_add(json_row
, "peer", peer_str
);
8038 json_object_string_add(json_row
, "local", local_str
);
8039 json_object_string_add(json_row
, "meshGroupName",
8040 mp
->mesh_group_name
);
8041 json_object_string_add(json_row
, "state", state_str
);
8042 json_object_string_add(json_row
, "upTime", timebuf
);
8043 json_object_string_add(json_row
, "keepAliveTimer",
8045 json_object_string_add(json_row
, "connRetryTimer",
8047 json_object_string_add(json_row
, "holdTimer",
8049 json_object_string_add(json_row
, "lastReset",
8051 json_object_int_add(json_row
, "connAttempts",
8053 json_object_int_add(json_row
, "establishedChanges",
8055 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
8056 json_object_int_add(json_row
, "kaSent", mp
->ka_tx_cnt
);
8057 json_object_int_add(json_row
, "kaRcvd", mp
->ka_rx_cnt
);
8058 json_object_int_add(json_row
, "saSent", mp
->sa_tx_cnt
);
8059 json_object_int_add(json_row
, "saRcvd", mp
->sa_rx_cnt
);
8060 json_object_object_add(json
, peer_str
, json_row
);
8062 vty_out(vty
, "Peer : %s\n", peer_str
);
8063 vty_out(vty
, " Local : %s\n", local_str
);
8064 vty_out(vty
, " Mesh Group : %s\n",
8065 mp
->mesh_group_name
);
8066 vty_out(vty
, " State : %s\n", state_str
);
8067 vty_out(vty
, " Uptime : %s\n", timebuf
);
8069 vty_out(vty
, " Keepalive Timer : %s\n", katimer
);
8070 vty_out(vty
, " Conn Retry Timer : %s\n", crtimer
);
8071 vty_out(vty
, " Hold Timer : %s\n", holdtimer
);
8072 vty_out(vty
, " Last Reset : %s\n",
8074 vty_out(vty
, " Conn Attempts : %d\n",
8076 vty_out(vty
, " Established Changes : %d\n",
8078 vty_out(vty
, " SA Count : %d\n",
8080 vty_out(vty
, " Statistics :\n");
8083 vty_out(vty
, " Keepalives : %10d %10d\n",
8084 mp
->ka_tx_cnt
, mp
->ka_rx_cnt
);
8085 vty_out(vty
, " SAs : %10d %10d\n",
8086 mp
->sa_tx_cnt
, mp
->sa_rx_cnt
);
8092 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8093 json
, JSON_C_TO_STRING_PRETTY
));
8094 json_object_free(json
);
8098 DEFUN (show_ip_msdp_peer_detail
,
8099 show_ip_msdp_peer_detail_cmd
,
8100 "show ip msdp [vrf NAME] peer [detail|A.B.C.D] [json]",
8105 "MSDP peer information\n"
8110 u_char uj
= use_json(argc
, argv
);
8112 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
8119 if (argv_find(argv
, argc
, "detail", &idx
))
8120 arg
= argv
[idx
]->text
;
8121 else if (argv_find(argv
, argc
, "A.B.C.D", &idx
))
8122 arg
= argv
[idx
]->arg
;
8125 ip_msdp_show_peers_detail(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
8127 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
8132 DEFUN (show_ip_msdp_peer_detail_vrf_all
,
8133 show_ip_msdp_peer_detail_vrf_all_cmd
,
8134 "show ip msdp vrf all peer [detail|A.B.C.D] [json]",
8139 "MSDP peer information\n"
8145 u_char uj
= use_json(argc
, argv
);
8151 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
8155 vty_out(vty
, " \"%s\": ", vrf
->name
);
8158 vty_out(vty
, "VRF: %s\n", vrf
->name
);
8159 if (argv_find(argv
, argc
, "detail", &idx
)
8160 || argv_find(argv
, argc
, "A.B.C.D", &idx
))
8161 ip_msdp_show_peers_detail(vrf
->info
, vty
,
8162 argv
[idx
]->arg
, uj
);
8164 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
8167 vty_out(vty
, "}\n");
8172 static void ip_msdp_show_sa(struct pim_instance
*pim
, struct vty
*vty
,
8175 struct listnode
*sanode
;
8176 struct pim_msdp_sa
*sa
;
8177 char src_str
[INET_ADDRSTRLEN
];
8178 char grp_str
[INET_ADDRSTRLEN
];
8179 char rp_str
[INET_ADDRSTRLEN
];
8180 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
8184 json_object
*json
= NULL
;
8185 json_object
*json_group
= NULL
;
8186 json_object
*json_row
= NULL
;
8189 json
= json_object_new_object();
8192 "Source Group RP Local SPT Uptime\n");
8195 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
8196 now
= pim_time_monotonic_sec();
8197 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
8198 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
8199 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
8200 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
8201 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
8203 strcpy(spt_str
, "yes");
8205 strcpy(spt_str
, "no");
8208 strcpy(rp_str
, "-");
8209 strcpy(spt_str
, "-");
8211 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
8212 strcpy(local_str
, "yes");
8214 strcpy(local_str
, "no");
8217 json_object_object_get_ex(json
, grp_str
, &json_group
);
8220 json_group
= json_object_new_object();
8221 json_object_object_add(json
, grp_str
,
8225 json_row
= json_object_new_object();
8226 json_object_string_add(json_row
, "source", src_str
);
8227 json_object_string_add(json_row
, "group", grp_str
);
8228 json_object_string_add(json_row
, "rp", rp_str
);
8229 json_object_string_add(json_row
, "local", local_str
);
8230 json_object_string_add(json_row
, "sptSetup", spt_str
);
8231 json_object_string_add(json_row
, "upTime", timebuf
);
8232 json_object_object_add(json_group
, src_str
, json_row
);
8234 vty_out(vty
, "%-15s %15s %15s %5c %3c %8s\n",
8235 src_str
, grp_str
, rp_str
, local_str
[0],
8236 spt_str
[0], timebuf
);
8241 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8242 json
, JSON_C_TO_STRING_PRETTY
));
8243 json_object_free(json
);
8247 static void ip_msdp_show_sa_entry_detail(struct pim_msdp_sa
*sa
,
8248 const char *src_str
,
8249 const char *grp_str
, struct vty
*vty
,
8250 u_char uj
, json_object
*json
)
8252 char rp_str
[INET_ADDRSTRLEN
];
8253 char peer_str
[INET_ADDRSTRLEN
];
8254 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
8257 char statetimer
[PIM_MSDP_TIMER_STRLEN
];
8259 json_object
*json_group
= NULL
;
8260 json_object
*json_row
= NULL
;
8262 now
= pim_time_monotonic_sec();
8263 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
8264 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
8265 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
8266 pim_inet4_dump("<peer?>", sa
->peer
, peer_str
, sizeof(peer_str
));
8268 strcpy(spt_str
, "yes");
8270 strcpy(spt_str
, "no");
8273 strcpy(rp_str
, "-");
8274 strcpy(peer_str
, "-");
8275 strcpy(spt_str
, "-");
8277 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
8278 strcpy(local_str
, "yes");
8280 strcpy(local_str
, "no");
8282 pim_time_timer_to_hhmmss(statetimer
, sizeof(statetimer
),
8283 sa
->sa_state_timer
);
8285 json_object_object_get_ex(json
, grp_str
, &json_group
);
8288 json_group
= json_object_new_object();
8289 json_object_object_add(json
, grp_str
, json_group
);
8292 json_row
= json_object_new_object();
8293 json_object_string_add(json_row
, "source", src_str
);
8294 json_object_string_add(json_row
, "group", grp_str
);
8295 json_object_string_add(json_row
, "rp", rp_str
);
8296 json_object_string_add(json_row
, "local", local_str
);
8297 json_object_string_add(json_row
, "sptSetup", spt_str
);
8298 json_object_string_add(json_row
, "upTime", timebuf
);
8299 json_object_string_add(json_row
, "stateTimer", statetimer
);
8300 json_object_object_add(json_group
, src_str
, json_row
);
8302 vty_out(vty
, "SA : %s\n", sa
->sg_str
);
8303 vty_out(vty
, " RP : %s\n", rp_str
);
8304 vty_out(vty
, " Peer : %s\n", peer_str
);
8305 vty_out(vty
, " Local : %s\n", local_str
);
8306 vty_out(vty
, " SPT Setup : %s\n", spt_str
);
8307 vty_out(vty
, " Uptime : %s\n", timebuf
);
8308 vty_out(vty
, " State Timer : %s\n", statetimer
);
8313 static void ip_msdp_show_sa_detail(struct pim_instance
*pim
, struct vty
*vty
,
8316 struct listnode
*sanode
;
8317 struct pim_msdp_sa
*sa
;
8318 char src_str
[INET_ADDRSTRLEN
];
8319 char grp_str
[INET_ADDRSTRLEN
];
8320 json_object
*json
= NULL
;
8323 json
= json_object_new_object();
8326 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
8327 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
8328 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
8329 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
, uj
,
8334 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8335 json
, JSON_C_TO_STRING_PRETTY
));
8336 json_object_free(json
);
8340 DEFUN (show_ip_msdp_sa_detail
,
8341 show_ip_msdp_sa_detail_cmd
,
8342 "show ip msdp [vrf NAME] sa detail [json]",
8347 "MSDP active-source information\n"
8351 u_char uj
= use_json(argc
, argv
);
8353 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
8358 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
8363 DEFUN (show_ip_msdp_sa_detail_vrf_all
,
8364 show_ip_msdp_sa_detail_vrf_all_cmd
,
8365 "show ip msdp vrf all sa detail [json]",
8370 "MSDP active-source information\n"
8374 u_char uj
= use_json(argc
, argv
);
8380 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
8384 vty_out(vty
, " \"%s\": ", vrf
->name
);
8387 vty_out(vty
, "VRF: %s\n", vrf
->name
);
8388 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
8391 vty_out(vty
, "}\n");
8396 static void ip_msdp_show_sa_addr(struct pim_instance
*pim
, struct vty
*vty
,
8397 const char *addr
, u_char uj
)
8399 struct listnode
*sanode
;
8400 struct pim_msdp_sa
*sa
;
8401 char src_str
[INET_ADDRSTRLEN
];
8402 char grp_str
[INET_ADDRSTRLEN
];
8403 json_object
*json
= NULL
;
8406 json
= json_object_new_object();
8409 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
8410 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
8411 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
8412 if (!strcmp(addr
, src_str
) || !strcmp(addr
, grp_str
)) {
8413 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
8419 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8420 json
, JSON_C_TO_STRING_PRETTY
));
8421 json_object_free(json
);
8425 static void ip_msdp_show_sa_sg(struct pim_instance
*pim
, struct vty
*vty
,
8426 const char *src
, const char *grp
, u_char uj
)
8428 struct listnode
*sanode
;
8429 struct pim_msdp_sa
*sa
;
8430 char src_str
[INET_ADDRSTRLEN
];
8431 char grp_str
[INET_ADDRSTRLEN
];
8432 json_object
*json
= NULL
;
8435 json
= json_object_new_object();
8438 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
8439 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
8440 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
8441 if (!strcmp(src
, src_str
) && !strcmp(grp
, grp_str
)) {
8442 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
8448 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8449 json
, JSON_C_TO_STRING_PRETTY
));
8450 json_object_free(json
);
8454 DEFUN (show_ip_msdp_sa_sg
,
8455 show_ip_msdp_sa_sg_cmd
,
8456 "show ip msdp [vrf NAME] sa [A.B.C.D [A.B.C.D]] [json]",
8461 "MSDP active-source information\n"
8462 "source or group ip\n"
8466 u_char uj
= use_json(argc
, argv
);
8470 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
8475 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
8477 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
8481 if (src_ip
&& grp_ip
)
8482 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
8484 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
8486 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
8491 DEFUN (show_ip_msdp_sa_sg_vrf_all
,
8492 show_ip_msdp_sa_sg_vrf_all_cmd
,
8493 "show ip msdp vrf all sa [A.B.C.D [A.B.C.D]] [json]",
8498 "MSDP active-source information\n"
8499 "source or group ip\n"
8503 u_char uj
= use_json(argc
, argv
);
8508 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
8510 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
8516 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
8520 vty_out(vty
, " \"%s\": ", vrf
->name
);
8523 vty_out(vty
, "VRF: %s\n", vrf
->name
);
8525 if (src_ip
&& grp_ip
)
8526 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
8528 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
8530 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
8533 vty_out(vty
, "}\n");
8539 void pim_cmd_init(void)
8541 install_node(&pim_global_node
, pim_global_config_write
); /* PIM_NODE */
8542 install_node(&interface_node
,
8543 pim_interface_config_write
); /* INTERFACE_NODE */
8546 install_node(&debug_node
, pim_debug_config_write
);
8548 install_element(CONFIG_NODE
, &ip_multicast_routing_cmd
);
8549 install_element(CONFIG_NODE
, &no_ip_multicast_routing_cmd
);
8550 install_element(CONFIG_NODE
, &ip_pim_rp_cmd
);
8551 install_element(VRF_NODE
, &ip_pim_rp_cmd
);
8552 install_element(CONFIG_NODE
, &no_ip_pim_rp_cmd
);
8553 install_element(VRF_NODE
, &no_ip_pim_rp_cmd
);
8554 install_element(CONFIG_NODE
, &ip_pim_rp_prefix_list_cmd
);
8555 install_element(VRF_NODE
, &ip_pim_rp_prefix_list_cmd
);
8556 install_element(CONFIG_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
8557 install_element(VRF_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
8558 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
8559 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
8560 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
8561 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
8562 install_element(CONFIG_NODE
, &ip_pim_ssm_prefix_list_cmd
);
8563 install_element(VRF_NODE
, &ip_pim_ssm_prefix_list_cmd
);
8564 install_element(CONFIG_NODE
, &ip_pim_register_suppress_cmd
);
8565 install_element(VRF_NODE
, &ip_pim_register_suppress_cmd
);
8566 install_element(CONFIG_NODE
, &no_ip_pim_register_suppress_cmd
);
8567 install_element(VRF_NODE
, &no_ip_pim_register_suppress_cmd
);
8568 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
8569 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
8570 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
8571 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
8572 install_element(CONFIG_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
8573 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
8574 install_element(CONFIG_NODE
,
8575 &no_ip_pim_spt_switchover_infinity_plist_cmd
);
8576 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_plist_cmd
);
8577 install_element(CONFIG_NODE
, &ip_pim_joinprune_time_cmd
);
8578 install_element(VRF_NODE
, &ip_pim_joinprune_time_cmd
);
8579 install_element(CONFIG_NODE
, &no_ip_pim_joinprune_time_cmd
);
8580 install_element(VRF_NODE
, &no_ip_pim_joinprune_time_cmd
);
8581 install_element(CONFIG_NODE
, &ip_pim_keep_alive_cmd
);
8582 install_element(VRF_NODE
, &ip_pim_keep_alive_cmd
);
8583 install_element(CONFIG_NODE
, &ip_pim_rp_keep_alive_cmd
);
8584 install_element(VRF_NODE
, &ip_pim_rp_keep_alive_cmd
);
8585 install_element(CONFIG_NODE
, &no_ip_pim_keep_alive_cmd
);
8586 install_element(VRF_NODE
, &no_ip_pim_keep_alive_cmd
);
8587 install_element(CONFIG_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
8588 install_element(VRF_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
8589 install_element(CONFIG_NODE
, &ip_pim_packets_cmd
);
8590 install_element(VRF_NODE
, &ip_pim_packets_cmd
);
8591 install_element(CONFIG_NODE
, &no_ip_pim_packets_cmd
);
8592 install_element(VRF_NODE
, &no_ip_pim_packets_cmd
);
8593 install_element(CONFIG_NODE
, &ip_pim_v6_secondary_cmd
);
8594 install_element(VRF_NODE
, &ip_pim_v6_secondary_cmd
);
8595 install_element(CONFIG_NODE
, &no_ip_pim_v6_secondary_cmd
);
8596 install_element(VRF_NODE
, &no_ip_pim_v6_secondary_cmd
);
8597 install_element(CONFIG_NODE
, &ip_ssmpingd_cmd
);
8598 install_element(VRF_NODE
, &ip_ssmpingd_cmd
);
8599 install_element(CONFIG_NODE
, &no_ip_ssmpingd_cmd
);
8600 install_element(VRF_NODE
, &no_ip_ssmpingd_cmd
);
8601 install_element(CONFIG_NODE
, &ip_msdp_peer_cmd
);
8602 install_element(VRF_NODE
, &ip_msdp_peer_cmd
);
8603 install_element(CONFIG_NODE
, &no_ip_msdp_peer_cmd
);
8604 install_element(VRF_NODE
, &no_ip_msdp_peer_cmd
);
8605 install_element(CONFIG_NODE
, &ip_pim_ecmp_cmd
);
8606 install_element(VRF_NODE
, &ip_pim_ecmp_cmd
);
8607 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_cmd
);
8608 install_element(VRF_NODE
, &no_ip_pim_ecmp_cmd
);
8609 install_element(CONFIG_NODE
, &ip_pim_ecmp_rebalance_cmd
);
8610 install_element(VRF_NODE
, &ip_pim_ecmp_rebalance_cmd
);
8611 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
8612 install_element(VRF_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
8614 install_element(INTERFACE_NODE
, &interface_ip_igmp_cmd
);
8615 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_cmd
);
8616 install_element(INTERFACE_NODE
, &interface_ip_igmp_join_cmd
);
8617 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_join_cmd
);
8618 install_element(INTERFACE_NODE
, &interface_ip_igmp_version_cmd
);
8619 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_version_cmd
);
8620 install_element(INTERFACE_NODE
, &interface_ip_igmp_query_interval_cmd
);
8621 install_element(INTERFACE_NODE
,
8622 &interface_no_ip_igmp_query_interval_cmd
);
8623 install_element(INTERFACE_NODE
,
8624 &interface_ip_igmp_query_max_response_time_cmd
);
8625 install_element(INTERFACE_NODE
,
8626 &interface_no_ip_igmp_query_max_response_time_cmd
);
8627 install_element(INTERFACE_NODE
,
8628 &interface_ip_igmp_query_max_response_time_dsec_cmd
);
8629 install_element(INTERFACE_NODE
,
8630 &interface_no_ip_igmp_query_max_response_time_dsec_cmd
);
8631 install_element(INTERFACE_NODE
, &interface_ip_pim_ssm_cmd
);
8632 install_element(INTERFACE_NODE
, &interface_no_ip_pim_ssm_cmd
);
8633 install_element(INTERFACE_NODE
, &interface_ip_pim_sm_cmd
);
8634 install_element(INTERFACE_NODE
, &interface_no_ip_pim_sm_cmd
);
8635 install_element(INTERFACE_NODE
, &interface_ip_pim_drprio_cmd
);
8636 install_element(INTERFACE_NODE
, &interface_no_ip_pim_drprio_cmd
);
8637 install_element(INTERFACE_NODE
, &interface_ip_pim_hello_cmd
);
8638 install_element(INTERFACE_NODE
, &interface_no_ip_pim_hello_cmd
);
8639 install_element(INTERFACE_NODE
, &interface_ip_pim_boundary_oil_cmd
);
8640 install_element(INTERFACE_NODE
, &interface_no_ip_pim_boundary_oil_cmd
);
8642 // Static mroutes NEB
8643 install_element(INTERFACE_NODE
, &interface_ip_mroute_cmd
);
8644 install_element(INTERFACE_NODE
, &interface_ip_mroute_source_cmd
);
8645 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_cmd
);
8646 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_source_cmd
);
8648 install_element(VIEW_NODE
, &show_ip_igmp_interface_cmd
);
8649 install_element(VIEW_NODE
, &show_ip_igmp_interface_vrf_all_cmd
);
8650 install_element(VIEW_NODE
, &show_ip_igmp_join_cmd
);
8651 install_element(VIEW_NODE
, &show_ip_igmp_join_vrf_all_cmd
);
8652 install_element(VIEW_NODE
, &show_ip_igmp_groups_cmd
);
8653 install_element(VIEW_NODE
, &show_ip_igmp_groups_vrf_all_cmd
);
8654 install_element(VIEW_NODE
, &show_ip_igmp_groups_retransmissions_cmd
);
8655 install_element(VIEW_NODE
, &show_ip_igmp_sources_cmd
);
8656 install_element(VIEW_NODE
, &show_ip_igmp_sources_retransmissions_cmd
);
8657 install_element(VIEW_NODE
, &show_ip_pim_assert_cmd
);
8658 install_element(VIEW_NODE
, &show_ip_pim_assert_internal_cmd
);
8659 install_element(VIEW_NODE
, &show_ip_pim_assert_metric_cmd
);
8660 install_element(VIEW_NODE
, &show_ip_pim_assert_winner_metric_cmd
);
8661 install_element(VIEW_NODE
, &show_ip_pim_interface_traffic_cmd
);
8662 install_element(VIEW_NODE
, &show_ip_pim_interface_cmd
);
8663 install_element(VIEW_NODE
, &show_ip_pim_interface_vrf_all_cmd
);
8664 install_element(VIEW_NODE
, &show_ip_pim_join_cmd
);
8665 install_element(VIEW_NODE
, &show_ip_pim_join_vrf_all_cmd
);
8666 install_element(VIEW_NODE
, &show_ip_pim_local_membership_cmd
);
8667 install_element(VIEW_NODE
, &show_ip_pim_neighbor_cmd
);
8668 install_element(VIEW_NODE
, &show_ip_pim_neighbor_vrf_all_cmd
);
8669 install_element(VIEW_NODE
, &show_ip_pim_rpf_cmd
);
8670 install_element(VIEW_NODE
, &show_ip_pim_rpf_vrf_all_cmd
);
8671 install_element(VIEW_NODE
, &show_ip_pim_secondary_cmd
);
8672 install_element(VIEW_NODE
, &show_ip_pim_state_cmd
);
8673 install_element(VIEW_NODE
, &show_ip_pim_state_vrf_all_cmd
);
8674 install_element(VIEW_NODE
, &show_ip_pim_upstream_cmd
);
8675 install_element(VIEW_NODE
, &show_ip_pim_upstream_vrf_all_cmd
);
8676 install_element(VIEW_NODE
, &show_ip_pim_upstream_join_desired_cmd
);
8677 install_element(VIEW_NODE
, &show_ip_pim_upstream_rpf_cmd
);
8678 install_element(VIEW_NODE
, &show_ip_pim_rp_cmd
);
8679 install_element(VIEW_NODE
, &show_ip_pim_rp_vrf_all_cmd
);
8680 install_element(VIEW_NODE
, &show_ip_multicast_cmd
);
8681 install_element(VIEW_NODE
, &show_ip_multicast_vrf_all_cmd
);
8682 install_element(VIEW_NODE
, &show_ip_mroute_cmd
);
8683 install_element(VIEW_NODE
, &show_ip_mroute_vrf_all_cmd
);
8684 install_element(VIEW_NODE
, &show_ip_mroute_count_cmd
);
8685 install_element(VIEW_NODE
, &show_ip_mroute_count_vrf_all_cmd
);
8686 install_element(VIEW_NODE
, &show_ip_rib_cmd
);
8687 install_element(VIEW_NODE
, &show_ip_ssmpingd_cmd
);
8688 install_element(VIEW_NODE
, &show_debugging_pim_cmd
);
8689 install_element(VIEW_NODE
, &show_ip_pim_nexthop_cmd
);
8690 install_element(VIEW_NODE
, &show_ip_pim_nexthop_lookup_cmd
);
8692 install_element(ENABLE_NODE
, &clear_ip_interfaces_cmd
);
8693 install_element(ENABLE_NODE
, &clear_ip_igmp_interfaces_cmd
);
8694 install_element(ENABLE_NODE
, &clear_ip_mroute_cmd
);
8695 install_element(ENABLE_NODE
, &clear_ip_pim_interfaces_cmd
);
8696 install_element(ENABLE_NODE
, &clear_ip_pim_interface_traffic_cmd
);
8697 install_element(ENABLE_NODE
, &clear_ip_pim_oil_cmd
);
8699 install_element(ENABLE_NODE
, &debug_igmp_cmd
);
8700 install_element(ENABLE_NODE
, &no_debug_igmp_cmd
);
8701 install_element(ENABLE_NODE
, &debug_igmp_events_cmd
);
8702 install_element(ENABLE_NODE
, &no_debug_igmp_events_cmd
);
8703 install_element(ENABLE_NODE
, &debug_igmp_packets_cmd
);
8704 install_element(ENABLE_NODE
, &no_debug_igmp_packets_cmd
);
8705 install_element(ENABLE_NODE
, &debug_igmp_trace_cmd
);
8706 install_element(ENABLE_NODE
, &no_debug_igmp_trace_cmd
);
8707 install_element(ENABLE_NODE
, &debug_mroute_cmd
);
8708 install_element(ENABLE_NODE
, &debug_mroute_detail_cmd
);
8709 install_element(ENABLE_NODE
, &no_debug_mroute_cmd
);
8710 install_element(ENABLE_NODE
, &no_debug_mroute_detail_cmd
);
8711 install_element(ENABLE_NODE
, &debug_static_cmd
);
8712 install_element(ENABLE_NODE
, &no_debug_static_cmd
);
8713 install_element(ENABLE_NODE
, &debug_pim_cmd
);
8714 install_element(ENABLE_NODE
, &no_debug_pim_cmd
);
8715 install_element(ENABLE_NODE
, &debug_pim_nht_cmd
);
8716 install_element(ENABLE_NODE
, &no_debug_pim_nht_cmd
);
8717 install_element(ENABLE_NODE
, &debug_pim_nht_rp_cmd
);
8718 install_element(ENABLE_NODE
, &no_debug_pim_nht_rp_cmd
);
8719 install_element(ENABLE_NODE
, &debug_pim_events_cmd
);
8720 install_element(ENABLE_NODE
, &no_debug_pim_events_cmd
);
8721 install_element(ENABLE_NODE
, &debug_pim_packets_cmd
);
8722 install_element(ENABLE_NODE
, &no_debug_pim_packets_cmd
);
8723 install_element(ENABLE_NODE
, &debug_pim_packetdump_send_cmd
);
8724 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_send_cmd
);
8725 install_element(ENABLE_NODE
, &debug_pim_packetdump_recv_cmd
);
8726 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_recv_cmd
);
8727 install_element(ENABLE_NODE
, &debug_pim_trace_cmd
);
8728 install_element(ENABLE_NODE
, &no_debug_pim_trace_cmd
);
8729 install_element(ENABLE_NODE
, &debug_pim_trace_detail_cmd
);
8730 install_element(ENABLE_NODE
, &no_debug_pim_trace_detail_cmd
);
8731 install_element(ENABLE_NODE
, &debug_ssmpingd_cmd
);
8732 install_element(ENABLE_NODE
, &no_debug_ssmpingd_cmd
);
8733 install_element(ENABLE_NODE
, &debug_pim_zebra_cmd
);
8734 install_element(ENABLE_NODE
, &no_debug_pim_zebra_cmd
);
8735 install_element(ENABLE_NODE
, &debug_msdp_cmd
);
8736 install_element(ENABLE_NODE
, &no_debug_msdp_cmd
);
8737 install_element(ENABLE_NODE
, &undebug_msdp_cmd
);
8738 install_element(ENABLE_NODE
, &debug_msdp_events_cmd
);
8739 install_element(ENABLE_NODE
, &no_debug_msdp_events_cmd
);
8740 install_element(ENABLE_NODE
, &undebug_msdp_events_cmd
);
8741 install_element(ENABLE_NODE
, &debug_msdp_packets_cmd
);
8742 install_element(ENABLE_NODE
, &no_debug_msdp_packets_cmd
);
8743 install_element(ENABLE_NODE
, &undebug_msdp_packets_cmd
);
8745 install_element(CONFIG_NODE
, &debug_igmp_cmd
);
8746 install_element(CONFIG_NODE
, &no_debug_igmp_cmd
);
8747 install_element(CONFIG_NODE
, &debug_igmp_events_cmd
);
8748 install_element(CONFIG_NODE
, &no_debug_igmp_events_cmd
);
8749 install_element(CONFIG_NODE
, &debug_igmp_packets_cmd
);
8750 install_element(CONFIG_NODE
, &no_debug_igmp_packets_cmd
);
8751 install_element(CONFIG_NODE
, &debug_igmp_trace_cmd
);
8752 install_element(CONFIG_NODE
, &no_debug_igmp_trace_cmd
);
8753 install_element(CONFIG_NODE
, &debug_mroute_cmd
);
8754 install_element(CONFIG_NODE
, &debug_mroute_detail_cmd
);
8755 install_element(CONFIG_NODE
, &no_debug_mroute_cmd
);
8756 install_element(CONFIG_NODE
, &no_debug_mroute_detail_cmd
);
8757 install_element(CONFIG_NODE
, &debug_static_cmd
);
8758 install_element(CONFIG_NODE
, &no_debug_static_cmd
);
8759 install_element(CONFIG_NODE
, &debug_pim_cmd
);
8760 install_element(CONFIG_NODE
, &no_debug_pim_cmd
);
8761 install_element(CONFIG_NODE
, &debug_pim_nht_cmd
);
8762 install_element(CONFIG_NODE
, &no_debug_pim_nht_cmd
);
8763 install_element(CONFIG_NODE
, &debug_pim_nht_rp_cmd
);
8764 install_element(CONFIG_NODE
, &no_debug_pim_nht_rp_cmd
);
8765 install_element(CONFIG_NODE
, &debug_pim_events_cmd
);
8766 install_element(CONFIG_NODE
, &no_debug_pim_events_cmd
);
8767 install_element(CONFIG_NODE
, &debug_pim_packets_cmd
);
8768 install_element(CONFIG_NODE
, &no_debug_pim_packets_cmd
);
8769 install_element(CONFIG_NODE
, &debug_pim_trace_cmd
);
8770 install_element(CONFIG_NODE
, &no_debug_pim_trace_cmd
);
8771 install_element(CONFIG_NODE
, &debug_pim_trace_detail_cmd
);
8772 install_element(CONFIG_NODE
, &no_debug_pim_trace_detail_cmd
);
8773 install_element(CONFIG_NODE
, &debug_ssmpingd_cmd
);
8774 install_element(CONFIG_NODE
, &no_debug_ssmpingd_cmd
);
8775 install_element(CONFIG_NODE
, &debug_pim_zebra_cmd
);
8776 install_element(CONFIG_NODE
, &no_debug_pim_zebra_cmd
);
8777 install_element(CONFIG_NODE
, &debug_msdp_cmd
);
8778 install_element(CONFIG_NODE
, &no_debug_msdp_cmd
);
8779 install_element(CONFIG_NODE
, &undebug_msdp_cmd
);
8780 install_element(CONFIG_NODE
, &debug_msdp_events_cmd
);
8781 install_element(CONFIG_NODE
, &no_debug_msdp_events_cmd
);
8782 install_element(CONFIG_NODE
, &undebug_msdp_events_cmd
);
8783 install_element(CONFIG_NODE
, &debug_msdp_packets_cmd
);
8784 install_element(CONFIG_NODE
, &no_debug_msdp_packets_cmd
);
8785 install_element(CONFIG_NODE
, &undebug_msdp_packets_cmd
);
8787 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_member_cmd
);
8788 install_element(VRF_NODE
, &ip_msdp_mesh_group_member_cmd
);
8789 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
8790 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
8791 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_source_cmd
);
8792 install_element(VRF_NODE
, &ip_msdp_mesh_group_source_cmd
);
8793 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
8794 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
8795 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_cmd
);
8796 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_vrf_all_cmd
);
8797 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_cmd
);
8798 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_vrf_all_cmd
);
8799 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_cmd
);
8800 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_vrf_all_cmd
);
8801 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_cmd
);
8802 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_vrf_all_cmd
);
8803 install_element(VIEW_NODE
, &show_ip_pim_ssm_range_cmd
);
8804 install_element(VIEW_NODE
, &show_ip_pim_group_type_cmd
);
8805 install_element(INTERFACE_NODE
, &interface_pim_use_source_cmd
);
8806 install_element(INTERFACE_NODE
, &interface_no_pim_use_source_cmd
);
8807 /* Install BFD command */
8808 install_element(INTERFACE_NODE
, &ip_pim_bfd_cmd
);
8809 install_element(INTERFACE_NODE
, &ip_pim_bfd_param_cmd
);
8810 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_cmd
);
8811 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_param_cmd
);