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 #ifndef VTYSH_EXTRACT_PL
66 #include "pimd/pim_cmd_clippy.c"
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
, time_t now
)
184 char ch_src_str
[INET_ADDRSTRLEN
];
185 char ch_grp_str
[INET_ADDRSTRLEN
];
186 char winner_str
[INET_ADDRSTRLEN
];
187 struct in_addr ifaddr
;
191 ifaddr
= pim_ifp
->primary_address
;
193 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
194 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
195 pim_inet4_dump("<assrt_win?>", ch
->ifassert_winner
, winner_str
,
198 pim_time_uptime(uptime
, sizeof(uptime
), now
- ch
->ifassert_creation
);
199 pim_time_timer_to_mmss(timer
, sizeof(timer
), ch
->t_ifassert_timer
);
201 vty_out(vty
, "%-16s %-15s %-15s %-15s %-6s %-15s %-8s %-5s\n",
202 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
, ch_grp_str
,
203 pim_ifchannel_ifassert_name(ch
->ifassert_state
), winner_str
,
207 static void pim_show_assert(struct pim_instance
*pim
, struct vty
*vty
)
209 struct pim_interface
*pim_ifp
;
210 struct pim_ifchannel
*ch
;
211 struct interface
*ifp
;
214 now
= pim_time_monotonic_sec();
217 "Interface Address Source Group State Winner Uptime Timer\n");
219 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
224 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
225 pim_show_assert_helper(vty
, pim_ifp
, ch
, now
);
226 } /* scan interface channels */
230 static void pim_show_assert_internal_helper(struct vty
*vty
,
231 struct pim_interface
*pim_ifp
,
232 struct pim_ifchannel
*ch
)
234 char ch_src_str
[INET_ADDRSTRLEN
];
235 char ch_grp_str
[INET_ADDRSTRLEN
];
236 struct in_addr ifaddr
;
238 ifaddr
= pim_ifp
->primary_address
;
240 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
241 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
242 vty_out(vty
, "%-16s %-15s %-15s %-15s %-3s %-3s %-3s %-4s\n",
243 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
, ch_grp_str
,
244 PIM_IF_FLAG_TEST_COULD_ASSERT(ch
->flags
) ? "yes" : "no",
245 pim_macro_ch_could_assert_eval(ch
) ? "yes" : "no",
246 PIM_IF_FLAG_TEST_ASSERT_TRACKING_DESIRED(ch
->flags
) ? "yes"
248 pim_macro_assert_tracking_desired_eval(ch
) ? "yes" : "no");
251 static void pim_show_assert_internal(struct pim_instance
*pim
, struct vty
*vty
)
253 struct pim_interface
*pim_ifp
;
254 struct pim_ifchannel
*ch
;
255 struct interface
*ifp
;
259 "ECA: Evaluate CouldAssert\n"
260 "ATD: AssertTrackingDesired\n"
261 "eATD: Evaluate AssertTrackingDesired\n\n");
264 "Interface Address Source Group CA eCA ATD eATD\n");
265 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
270 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
271 pim_show_assert_internal_helper(vty
, pim_ifp
, ch
);
272 } /* scan interface channels */
276 static void pim_show_assert_metric_helper(struct vty
*vty
,
277 struct pim_interface
*pim_ifp
,
278 struct pim_ifchannel
*ch
)
280 char ch_src_str
[INET_ADDRSTRLEN
];
281 char ch_grp_str
[INET_ADDRSTRLEN
];
282 char addr_str
[INET_ADDRSTRLEN
];
283 struct pim_assert_metric am
;
284 struct in_addr ifaddr
;
286 ifaddr
= pim_ifp
->primary_address
;
288 am
= pim_macro_spt_assert_metric(&ch
->upstream
->rpf
,
289 pim_ifp
->primary_address
);
291 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
292 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
293 pim_inet4_dump("<addr?>", am
.ip_address
, addr_str
, sizeof(addr_str
));
295 vty_out(vty
, "%-16s %-15s %-15s %-15s %-3s %4u %6u %-15s\n",
296 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
, ch_grp_str
,
297 am
.rpt_bit_flag
? "yes" : "no", am
.metric_preference
,
298 am
.route_metric
, addr_str
);
301 static void pim_show_assert_metric(struct pim_instance
*pim
, struct vty
*vty
)
303 struct pim_interface
*pim_ifp
;
304 struct pim_ifchannel
*ch
;
305 struct interface
*ifp
;
308 "Interface Address Source Group RPT Pref Metric Address \n");
310 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
315 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
316 pim_show_assert_metric_helper(vty
, pim_ifp
, ch
);
317 } /* scan interface channels */
321 static void pim_show_assert_winner_metric_helper(struct vty
*vty
,
322 struct pim_interface
*pim_ifp
,
323 struct pim_ifchannel
*ch
)
325 char ch_src_str
[INET_ADDRSTRLEN
];
326 char ch_grp_str
[INET_ADDRSTRLEN
];
327 char addr_str
[INET_ADDRSTRLEN
];
328 struct pim_assert_metric
*am
;
329 struct in_addr ifaddr
;
333 ifaddr
= pim_ifp
->primary_address
;
335 am
= &ch
->ifassert_winner_metric
;
337 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
338 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
339 pim_inet4_dump("<addr?>", am
->ip_address
, addr_str
, sizeof(addr_str
));
341 if (am
->metric_preference
== PIM_ASSERT_METRIC_PREFERENCE_MAX
)
342 snprintf(pref_str
, sizeof(pref_str
), "INFI");
344 snprintf(pref_str
, sizeof(pref_str
), "%4u",
345 am
->metric_preference
);
347 if (am
->route_metric
== PIM_ASSERT_ROUTE_METRIC_MAX
)
348 snprintf(metr_str
, sizeof(metr_str
), "INFI");
350 snprintf(metr_str
, sizeof(metr_str
), "%6u", am
->route_metric
);
352 vty_out(vty
, "%-16s %-15s %-15s %-15s %-3s %-4s %-6s %-15s\n",
353 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
, ch_grp_str
,
354 am
->rpt_bit_flag
? "yes" : "no", pref_str
, metr_str
, addr_str
);
357 static void pim_show_assert_winner_metric(struct pim_instance
*pim
,
360 struct pim_interface
*pim_ifp
;
361 struct pim_ifchannel
*ch
;
362 struct interface
*ifp
;
365 "Interface Address Source Group RPT Pref Metric Address \n");
367 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
372 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
373 pim_show_assert_winner_metric_helper(vty
, pim_ifp
, ch
);
374 } /* scan interface channels */
378 static void json_object_pim_ifp_add(struct json_object
*json
,
379 struct interface
*ifp
)
381 struct pim_interface
*pim_ifp
;
384 json_object_string_add(json
, "name", ifp
->name
);
385 json_object_string_add(json
, "state", if_is_up(ifp
) ? "up" : "down");
386 json_object_string_add(json
, "address",
387 inet_ntoa(pim_ifp
->primary_address
));
388 json_object_int_add(json
, "index", ifp
->ifindex
);
390 if (if_is_multicast(ifp
))
391 json_object_boolean_true_add(json
, "flagMulticast");
393 if (if_is_broadcast(ifp
))
394 json_object_boolean_true_add(json
, "flagBroadcast");
396 if (ifp
->flags
& IFF_ALLMULTI
)
397 json_object_boolean_true_add(json
, "flagAllMulticast");
399 if (ifp
->flags
& IFF_PROMISC
)
400 json_object_boolean_true_add(json
, "flagPromiscuous");
402 if (PIM_IF_IS_DELETED(ifp
))
403 json_object_boolean_true_add(json
, "flagDeleted");
405 if (pim_if_lan_delay_enabled(ifp
))
406 json_object_boolean_true_add(json
, "lanDelayEnabled");
409 static void pim_show_membership_helper(struct vty
*vty
,
410 struct pim_interface
*pim_ifp
,
411 struct pim_ifchannel
*ch
,
412 struct json_object
*json
)
414 char ch_src_str
[INET_ADDRSTRLEN
];
415 char ch_grp_str
[INET_ADDRSTRLEN
];
416 json_object
*json_iface
= NULL
;
417 json_object
*json_row
= NULL
;
419 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
420 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
422 json_object_object_get_ex(json
, ch
->interface
->name
, &json_iface
);
424 json_iface
= json_object_new_object();
425 json_object_pim_ifp_add(json_iface
, ch
->interface
);
426 json_object_object_add(json
, ch
->interface
->name
, json_iface
);
429 json_row
= json_object_new_object();
430 json_object_string_add(json_row
, "source", ch_src_str
);
431 json_object_string_add(json_row
, "group", ch_grp_str
);
432 json_object_string_add(json_row
, "localMembership",
433 ch
->local_ifmembership
== PIM_IFMEMBERSHIP_NOINFO
436 json_object_object_add(json_iface
, ch_grp_str
, json_row
);
438 static void pim_show_membership(struct pim_instance
*pim
, struct vty
*vty
,
441 struct pim_interface
*pim_ifp
;
442 struct pim_ifchannel
*ch
;
443 struct interface
*ifp
;
445 json_object
*json
= NULL
;
446 json_object
*json_tmp
= NULL
;
448 json
= json_object_new_object();
450 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
455 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
456 pim_show_membership_helper(vty
, pim_ifp
, ch
, json
);
457 } /* scan interface channels */
461 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
462 json
, JSON_C_TO_STRING_PRETTY
));
465 "Interface Address Source Group Membership\n");
468 * Example of the json data we are traversing
474 * "address":"10.1.20.1",
476 * "flagMulticast":true,
477 * "flagBroadcast":true,
478 * "lanDelayEnabled":true,
481 * "group":"226.10.10.10",
482 * "localMembership":"INCLUDE"
488 /* foreach interface */
489 json_object_object_foreach(json
, key
, val
)
492 /* Find all of the keys where the val is an object. In
494 * above the only one is 226.10.10.10
496 json_object_object_foreach(val
, if_field_key
,
499 type
= json_object_get_type(if_field_val
);
501 if (type
== json_type_object
) {
502 vty_out(vty
, "%-16s ", key
);
504 json_object_object_get_ex(
505 val
, "address", &json_tmp
);
506 vty_out(vty
, "%-15s ",
507 json_object_get_string(
510 json_object_object_get_ex(if_field_val
,
513 vty_out(vty
, "%-15s ",
514 json_object_get_string(
518 vty_out(vty
, "%-15s ", if_field_key
);
520 json_object_object_get_ex(
521 if_field_val
, "localMembership",
523 vty_out(vty
, "%-10s\n",
524 json_object_get_string(
531 json_object_free(json
);
534 static void pim_print_ifp_flags(struct vty
*vty
, struct interface
*ifp
,
537 vty_out(vty
, "Flags\n");
538 vty_out(vty
, "-----\n");
539 vty_out(vty
, "All Multicast : %s\n",
540 (ifp
->flags
& IFF_ALLMULTI
) ? "yes" : "no");
541 vty_out(vty
, "Broadcast : %s\n",
542 if_is_broadcast(ifp
) ? "yes" : "no");
543 vty_out(vty
, "Deleted : %s\n",
544 PIM_IF_IS_DELETED(ifp
) ? "yes" : "no");
545 vty_out(vty
, "Interface Index : %d\n", ifp
->ifindex
);
546 vty_out(vty
, "Multicast : %s\n",
547 if_is_multicast(ifp
) ? "yes" : "no");
548 vty_out(vty
, "Multicast Loop : %d\n", mloop
);
549 vty_out(vty
, "Promiscuous : %s\n",
550 (ifp
->flags
& IFF_PROMISC
) ? "yes" : "no");
555 static void igmp_show_interfaces(struct pim_instance
*pim
, struct vty
*vty
,
558 struct interface
*ifp
;
560 json_object
*json
= NULL
;
561 json_object
*json_row
= NULL
;
563 now
= pim_time_monotonic_sec();
566 json
= json_object_new_object();
569 "Interface State Address V Querier Query Timer Uptime\n");
571 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
572 struct pim_interface
*pim_ifp
;
573 struct listnode
*sock_node
;
574 struct igmp_sock
*igmp
;
581 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
584 char query_hhmmss
[10];
586 pim_time_uptime(uptime
, sizeof(uptime
),
587 now
- igmp
->sock_creation
);
588 pim_time_timer_to_hhmmss(query_hhmmss
,
589 sizeof(query_hhmmss
),
590 igmp
->t_igmp_query_timer
);
593 json_row
= json_object_new_object();
594 json_object_pim_ifp_add(json_row
, ifp
);
595 json_object_string_add(json_row
, "upTime",
597 json_object_int_add(json_row
, "version",
598 pim_ifp
->igmp_version
);
600 if (igmp
->t_igmp_query_timer
) {
601 json_object_boolean_true_add(json_row
,
603 json_object_string_add(json_row
,
608 json_object_object_add(json
, ifp
->name
,
611 if (igmp
->mtrace_only
) {
612 json_object_boolean_true_add(
613 json_row
, "mtraceOnly");
617 "%-16s %5s %15s %d %7s %11s %8s\n",
620 ? (igmp
->mtrace_only
? "mtrc"
623 inet_ntoa(igmp
->ifaddr
),
624 pim_ifp
->igmp_version
,
625 igmp
->t_igmp_query_timer
? "local"
627 query_hhmmss
, uptime
);
633 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
634 json
, JSON_C_TO_STRING_PRETTY
));
635 json_object_free(json
);
639 static void igmp_show_interfaces_single(struct pim_instance
*pim
,
640 struct vty
*vty
, const char *ifname
,
643 struct igmp_sock
*igmp
;
644 struct interface
*ifp
;
645 struct listnode
*sock_node
;
646 struct pim_interface
*pim_ifp
;
648 char query_hhmmss
[10];
649 char other_hhmmss
[10];
650 int found_ifname
= 0;
653 long gmi_msec
; /* Group Membership Interval */
656 long oqpi_msec
; /* Other Querier Present Interval */
660 json_object
*json
= NULL
;
661 json_object
*json_row
= NULL
;
664 json
= json_object_new_object();
666 now
= pim_time_monotonic_sec();
668 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
674 if (strcmp(ifname
, "detail") && strcmp(ifname
, ifp
->name
))
677 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
680 pim_time_uptime(uptime
, sizeof(uptime
),
681 now
- igmp
->sock_creation
);
682 pim_time_timer_to_hhmmss(query_hhmmss
,
683 sizeof(query_hhmmss
),
684 igmp
->t_igmp_query_timer
);
685 pim_time_timer_to_hhmmss(other_hhmmss
,
686 sizeof(other_hhmmss
),
687 igmp
->t_other_querier_timer
);
689 gmi_msec
= PIM_IGMP_GMI_MSEC(
690 igmp
->querier_robustness_variable
,
691 igmp
->querier_query_interval
,
692 pim_ifp
->igmp_query_max_response_time_dsec
);
695 pim_ifp
->igmp_default_query_interval
);
697 oqpi_msec
= PIM_IGMP_OQPI_MSEC(
698 igmp
->querier_robustness_variable
,
699 igmp
->querier_query_interval
,
700 pim_ifp
->igmp_query_max_response_time_dsec
);
702 lmqt_msec
= PIM_IGMP_LMQT_MSEC(
703 pim_ifp
->igmp_query_max_response_time_dsec
,
704 igmp
->querier_robustness_variable
);
708 igmp
->querier_robustness_variable
,
709 igmp
->querier_query_interval
,
710 pim_ifp
->igmp_query_max_response_time_dsec
)
713 qri_msec
= pim_ifp
->igmp_query_max_response_time_dsec
715 if (pim_ifp
->pim_sock_fd
>= 0)
716 mloop
= pim_socket_mcastloop_get(
717 pim_ifp
->pim_sock_fd
);
722 json_row
= json_object_new_object();
723 json_object_pim_ifp_add(json_row
, ifp
);
724 json_object_string_add(json_row
, "upTime",
726 json_object_string_add(json_row
, "querier",
727 igmp
->t_igmp_query_timer
730 json_object_int_add(json_row
, "queryStartCount",
731 igmp
->startup_query_count
);
732 json_object_string_add(json_row
,
735 json_object_string_add(json_row
,
738 json_object_int_add(json_row
, "version",
739 pim_ifp
->igmp_version
);
742 "timerGroupMembershipIntervalMsec",
744 json_object_int_add(json_row
,
745 "timerLastMemberQueryMsec",
749 "timerOlderHostPresentIntervalMsec",
753 "timerOtherQuerierPresentIntervalMsec",
756 json_row
, "timerQueryInterval",
757 igmp
->querier_query_interval
);
760 "timerQueryResponseIntervalMsec",
763 json_row
, "timerRobustnessVariable",
764 igmp
->querier_robustness_variable
);
765 json_object_int_add(json_row
,
766 "timerStartupQueryInterval",
769 json_object_object_add(json
, ifp
->name
,
772 if (igmp
->mtrace_only
) {
773 json_object_boolean_true_add(
774 json_row
, "mtraceOnly");
777 vty_out(vty
, "Interface : %s\n", ifp
->name
);
778 vty_out(vty
, "State : %s\n",
780 ? (igmp
->mtrace_only
? "mtrace"
783 vty_out(vty
, "Address : %s\n",
784 inet_ntoa(pim_ifp
->primary_address
));
785 vty_out(vty
, "Uptime : %s\n", uptime
);
786 vty_out(vty
, "Version : %d\n",
787 pim_ifp
->igmp_version
);
791 vty_out(vty
, "Querier\n");
792 vty_out(vty
, "-------\n");
793 vty_out(vty
, "Querier : %s\n",
794 igmp
->t_igmp_query_timer
? "local"
796 vty_out(vty
, "Start Count : %d\n",
797 igmp
->startup_query_count
);
798 vty_out(vty
, "Query Timer : %s\n",
800 vty_out(vty
, "Other Timer : %s\n",
805 vty_out(vty
, "Timers\n");
806 vty_out(vty
, "------\n");
808 "Group Membership Interval : %lis\n",
811 "Last Member Query Time : %lis\n",
814 "Older Host Present Interval : %lis\n",
817 "Other Querier Present Interval : %lis\n",
820 "Query Interval : %ds\n",
821 igmp
->querier_query_interval
);
823 "Query Response Interval : %lis\n",
826 "Robustness Variable : %d\n",
827 igmp
->querier_robustness_variable
);
829 "Startup Query Interval : %ds\n",
834 pim_print_ifp_flags(vty
, ifp
, mloop
);
840 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
841 json
, JSON_C_TO_STRING_PRETTY
));
842 json_object_free(json
);
845 vty_out(vty
, "%% No such interface\n");
849 static void igmp_show_interface_join(struct pim_instance
*pim
, struct vty
*vty
)
851 struct interface
*ifp
;
854 now
= pim_time_monotonic_sec();
857 "Interface Address Source Group Socket Uptime \n");
859 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
860 struct pim_interface
*pim_ifp
;
861 struct listnode
*join_node
;
862 struct igmp_join
*ij
;
863 struct in_addr pri_addr
;
864 char pri_addr_str
[INET_ADDRSTRLEN
];
871 if (!pim_ifp
->igmp_join_list
)
874 pri_addr
= pim_find_primary_addr(ifp
);
875 pim_inet4_dump("<pri?>", pri_addr
, pri_addr_str
,
876 sizeof(pri_addr_str
));
878 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_join_list
, join_node
,
880 char group_str
[INET_ADDRSTRLEN
];
881 char source_str
[INET_ADDRSTRLEN
];
884 pim_time_uptime(uptime
, sizeof(uptime
),
885 now
- ij
->sock_creation
);
886 pim_inet4_dump("<grp?>", ij
->group_addr
, group_str
,
888 pim_inet4_dump("<src?>", ij
->source_addr
, source_str
,
891 vty_out(vty
, "%-16s %-15s %-15s %-15s %6d %8s\n",
892 ifp
->name
, pri_addr_str
, source_str
, group_str
,
893 ij
->sock_fd
, uptime
);
894 } /* for (pim_ifp->igmp_join_list) */
899 static void pim_show_interfaces_single(struct pim_instance
*pim
,
900 struct vty
*vty
, const char *ifname
,
903 struct in_addr ifaddr
;
904 struct interface
*ifp
;
905 struct listnode
*neighnode
;
906 struct listnode
*upnode
;
907 struct pim_interface
*pim_ifp
;
908 struct pim_neighbor
*neigh
;
909 struct pim_upstream
*up
;
911 char dr_str
[INET_ADDRSTRLEN
];
914 char grp_str
[INET_ADDRSTRLEN
];
915 char hello_period
[10];
916 char hello_timer
[10];
917 char neigh_src_str
[INET_ADDRSTRLEN
];
918 char src_str
[INET_ADDRSTRLEN
];
919 char stat_uptime
[10];
922 int found_ifname
= 0;
924 json_object
*json
= NULL
;
925 json_object
*json_row
= NULL
;
926 json_object
*json_pim_neighbor
= NULL
;
927 json_object
*json_pim_neighbors
= NULL
;
928 json_object
*json_group
= NULL
;
929 json_object
*json_group_source
= NULL
;
930 json_object
*json_fhr_sources
= NULL
;
931 struct pim_secondary_addr
*sec_addr
;
932 struct listnode
*sec_node
;
934 now
= pim_time_monotonic_sec();
937 json
= json_object_new_object();
939 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
945 if (strcmp(ifname
, "detail") && strcmp(ifname
, ifp
->name
))
949 ifaddr
= pim_ifp
->primary_address
;
950 pim_inet4_dump("<dr?>", pim_ifp
->pim_dr_addr
, dr_str
,
952 pim_time_uptime_begin(dr_uptime
, sizeof(dr_uptime
), now
,
953 pim_ifp
->pim_dr_election_last
);
954 pim_time_timer_to_hhmmss(hello_timer
, sizeof(hello_timer
),
955 pim_ifp
->t_pim_hello_timer
);
956 pim_time_mmss(hello_period
, sizeof(hello_period
),
957 pim_ifp
->pim_hello_period
);
958 pim_time_uptime(stat_uptime
, sizeof(stat_uptime
),
959 now
- pim_ifp
->pim_ifstat_start
);
960 if (pim_ifp
->pim_sock_fd
>= 0)
961 mloop
= pim_socket_mcastloop_get(pim_ifp
->pim_sock_fd
);
966 char pbuf
[PREFIX2STR_BUFFER
];
967 json_row
= json_object_new_object();
968 json_object_pim_ifp_add(json_row
, ifp
);
970 if (pim_ifp
->update_source
.s_addr
!= INADDR_ANY
) {
971 json_object_string_add(
972 json_row
, "useSource",
973 inet_ntoa(pim_ifp
->update_source
));
975 if (pim_ifp
->sec_addr_list
) {
976 json_object
*sec_list
= NULL
;
978 sec_list
= json_object_new_array();
979 for (ALL_LIST_ELEMENTS_RO(
980 pim_ifp
->sec_addr_list
, sec_node
,
982 json_object_array_add(
984 json_object_new_string(
990 json_object_object_add(json_row
,
991 "secondaryAddressList",
996 if (pim_ifp
->pim_neighbor_list
->count
) {
997 json_pim_neighbors
= json_object_new_object();
999 for (ALL_LIST_ELEMENTS_RO(
1000 pim_ifp
->pim_neighbor_list
,
1001 neighnode
, neigh
)) {
1003 json_object_new_object();
1004 pim_inet4_dump("<src?>",
1007 sizeof(neigh_src_str
));
1008 pim_time_uptime(uptime
, sizeof(uptime
),
1009 now
- neigh
->creation
);
1010 pim_time_timer_to_hhmmss(
1011 expire
, sizeof(expire
),
1012 neigh
->t_expire_timer
);
1014 json_object_string_add(
1015 json_pim_neighbor
, "address",
1017 json_object_string_add(
1018 json_pim_neighbor
, "upTime",
1020 json_object_string_add(
1021 json_pim_neighbor
, "holdtime",
1024 json_object_object_add(
1030 json_object_object_add(json_row
, "neighbors",
1031 json_pim_neighbors
);
1034 json_object_string_add(json_row
, "drAddress", dr_str
);
1035 json_object_int_add(json_row
, "drPriority",
1036 pim_ifp
->pim_dr_priority
);
1037 json_object_string_add(json_row
, "drUptime", dr_uptime
);
1038 json_object_int_add(json_row
, "drElections",
1039 pim_ifp
->pim_dr_election_count
);
1040 json_object_int_add(json_row
, "drChanges",
1041 pim_ifp
->pim_dr_election_changes
);
1044 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
,
1046 if (ifp
!= up
->rpf
.source_nexthop
.interface
)
1049 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
))
1052 if (!json_fhr_sources
)
1054 json_object_new_object();
1056 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
,
1058 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
,
1060 pim_time_uptime(uptime
, sizeof(uptime
),
1061 now
- up
->state_transition
);
1064 * Does this group live in json_fhr_sources?
1067 json_object_object_get_ex(json_fhr_sources
,
1068 grp_str
, &json_group
);
1071 json_group
= json_object_new_object();
1072 json_object_object_add(json_fhr_sources
,
1077 json_group_source
= json_object_new_object();
1078 json_object_string_add(json_group_source
,
1080 json_object_string_add(json_group_source
,
1082 json_object_string_add(json_group_source
,
1084 json_object_object_add(json_group
, src_str
,
1088 if (json_fhr_sources
) {
1089 json_object_object_add(json_row
,
1094 json_object_int_add(json_row
, "helloPeriod",
1095 pim_ifp
->pim_hello_period
);
1096 json_object_string_add(json_row
, "helloTimer",
1098 json_object_string_add(json_row
, "helloStatStart",
1100 json_object_int_add(json_row
, "helloReceived",
1101 pim_ifp
->pim_ifstat_hello_recv
);
1102 json_object_int_add(json_row
, "helloReceivedFailed",
1103 pim_ifp
->pim_ifstat_hello_recvfail
);
1104 json_object_int_add(json_row
, "helloSend",
1105 pim_ifp
->pim_ifstat_hello_sent
);
1106 json_object_int_add(json_row
, "hellosendFailed",
1107 pim_ifp
->pim_ifstat_hello_sendfail
);
1108 json_object_int_add(json_row
, "helloGenerationId",
1109 pim_ifp
->pim_generation_id
);
1110 json_object_int_add(json_row
, "flagMulticastLoop",
1113 json_object_int_add(
1114 json_row
, "effectivePropagationDelay",
1115 pim_if_effective_propagation_delay_msec(ifp
));
1116 json_object_int_add(
1117 json_row
, "effectiveOverrideInterval",
1118 pim_if_effective_override_interval_msec(ifp
));
1119 json_object_int_add(
1120 json_row
, "joinPruneOverrideInterval",
1121 pim_if_jp_override_interval_msec(ifp
));
1123 json_object_int_add(
1124 json_row
, "propagationDelay",
1125 pim_ifp
->pim_propagation_delay_msec
);
1126 json_object_int_add(
1127 json_row
, "propagationDelayHighest",
1128 pim_ifp
->pim_neighbors_highest_propagation_delay_msec
);
1129 json_object_int_add(
1130 json_row
, "overrideInterval",
1131 pim_ifp
->pim_override_interval_msec
);
1132 json_object_int_add(
1133 json_row
, "overrideIntervalHighest",
1134 pim_ifp
->pim_neighbors_highest_override_interval_msec
);
1135 json_object_object_add(json
, ifp
->name
, json_row
);
1138 vty_out(vty
, "Interface : %s\n", ifp
->name
);
1139 vty_out(vty
, "State : %s\n",
1140 if_is_up(ifp
) ? "up" : "down");
1141 if (pim_ifp
->update_source
.s_addr
!= INADDR_ANY
) {
1142 vty_out(vty
, "Use Source : %s\n",
1143 inet_ntoa(pim_ifp
->update_source
));
1145 if (pim_ifp
->sec_addr_list
) {
1146 char pbuf
[PREFIX2STR_BUFFER
];
1147 vty_out(vty
, "Address : %s (primary)\n",
1149 for (ALL_LIST_ELEMENTS_RO(
1150 pim_ifp
->sec_addr_list
, sec_node
,
1152 vty_out(vty
, " %s\n",
1153 prefix2str(&sec_addr
->addr
,
1154 pbuf
, sizeof(pbuf
)));
1157 vty_out(vty
, "Address : %s\n",
1165 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
,
1166 neighnode
, neigh
)) {
1169 vty_out(vty
, "PIM Neighbors\n");
1170 vty_out(vty
, "-------------\n");
1174 pim_inet4_dump("<src?>", neigh
->source_addr
,
1176 sizeof(neigh_src_str
));
1177 pim_time_uptime(uptime
, sizeof(uptime
),
1178 now
- neigh
->creation
);
1179 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
1180 neigh
->t_expire_timer
);
1182 "%-15s : up for %s, holdtime expires in %s\n",
1183 neigh_src_str
, uptime
, expire
);
1186 if (!print_header
) {
1191 vty_out(vty
, "Designated Router\n");
1192 vty_out(vty
, "-----------------\n");
1193 vty_out(vty
, "Address : %s\n", dr_str
);
1194 vty_out(vty
, "Priority : %u(%d)\n",
1195 pim_ifp
->pim_dr_priority
,
1196 pim_ifp
->pim_dr_num_nondrpri_neighbors
);
1197 vty_out(vty
, "Uptime : %s\n", dr_uptime
);
1198 vty_out(vty
, "Elections : %d\n",
1199 pim_ifp
->pim_dr_election_count
);
1200 vty_out(vty
, "Changes : %d\n",
1201 pim_ifp
->pim_dr_election_changes
);
1207 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
,
1210 if (strcmp(ifp
->name
,
1211 up
->rpf
.source_nexthop
1216 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
))
1221 "FHR - First Hop Router\n");
1223 "----------------------\n");
1227 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
,
1229 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
,
1231 pim_time_uptime(uptime
, sizeof(uptime
),
1232 now
- up
->state_transition
);
1234 "%s : %s is a source, uptime is %s\n",
1235 grp_str
, src_str
, uptime
);
1238 if (!print_header
) {
1243 vty_out(vty
, "Hellos\n");
1244 vty_out(vty
, "------\n");
1245 vty_out(vty
, "Period : %d\n",
1246 pim_ifp
->pim_hello_period
);
1247 vty_out(vty
, "Timer : %s\n", hello_timer
);
1248 vty_out(vty
, "StatStart : %s\n", stat_uptime
);
1249 vty_out(vty
, "Receive : %d\n",
1250 pim_ifp
->pim_ifstat_hello_recv
);
1251 vty_out(vty
, "Receive Failed : %d\n",
1252 pim_ifp
->pim_ifstat_hello_recvfail
);
1253 vty_out(vty
, "Send : %d\n",
1254 pim_ifp
->pim_ifstat_hello_sent
);
1255 vty_out(vty
, "Send Failed : %d\n",
1256 pim_ifp
->pim_ifstat_hello_sendfail
);
1257 vty_out(vty
, "Generation ID : %08x\n",
1258 pim_ifp
->pim_generation_id
);
1262 pim_print_ifp_flags(vty
, ifp
, mloop
);
1264 vty_out(vty
, "Join Prune Interval\n");
1265 vty_out(vty
, "-------------------\n");
1266 vty_out(vty
, "LAN Delay : %s\n",
1267 pim_if_lan_delay_enabled(ifp
) ? "yes" : "no");
1268 vty_out(vty
, "Effective Propagation Delay : %d msec\n",
1269 pim_if_effective_propagation_delay_msec(ifp
));
1270 vty_out(vty
, "Effective Override Interval : %d msec\n",
1271 pim_if_effective_override_interval_msec(ifp
));
1272 vty_out(vty
, "Join Prune Override Interval : %d msec\n",
1273 pim_if_jp_override_interval_msec(ifp
));
1277 vty_out(vty
, "LAN Prune Delay\n");
1278 vty_out(vty
, "---------------\n");
1279 vty_out(vty
, "Propagation Delay : %d msec\n",
1280 pim_ifp
->pim_propagation_delay_msec
);
1281 vty_out(vty
, "Propagation Delay (Highest) : %d msec\n",
1282 pim_ifp
->pim_neighbors_highest_propagation_delay_msec
);
1283 vty_out(vty
, "Override Interval : %d msec\n",
1284 pim_ifp
->pim_override_interval_msec
);
1285 vty_out(vty
, "Override Interval (Highest) : %d msec\n",
1286 pim_ifp
->pim_neighbors_highest_override_interval_msec
);
1293 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1294 json
, JSON_C_TO_STRING_PRETTY
));
1295 json_object_free(json
);
1298 vty_out(vty
, "%% No such interface\n");
1302 static void igmp_show_statistics(struct pim_instance
*pim
, struct vty
*vty
,
1303 const char *ifname
, bool uj
)
1305 struct interface
*ifp
;
1306 struct igmp_stats rx_stats
;
1308 igmp_stats_init(&rx_stats
);
1310 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1311 struct pim_interface
*pim_ifp
;
1312 struct listnode
*sock_node
;
1313 struct igmp_sock
*igmp
;
1315 pim_ifp
= ifp
->info
;
1320 if (ifname
&& strcmp(ifname
, ifp
->name
))
1323 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
1325 igmp_stats_add(&rx_stats
, &igmp
->rx_stats
);
1329 json_object
*json
= NULL
;
1330 json_object
*json_row
= NULL
;
1332 json
= json_object_new_object();
1333 json_row
= json_object_new_object();
1335 json_object_string_add(json_row
, "name", ifname
? ifname
:
1337 json_object_int_add(json_row
, "queryV1", rx_stats
.query_v1
);
1338 json_object_int_add(json_row
, "queryV2", rx_stats
.query_v2
);
1339 json_object_int_add(json_row
, "queryV3", rx_stats
.query_v3
);
1340 json_object_int_add(json_row
, "leaveV3", rx_stats
.leave_v2
);
1341 json_object_int_add(json_row
, "reportV1", rx_stats
.report_v1
);
1342 json_object_int_add(json_row
, "reportV2", rx_stats
.report_v2
);
1343 json_object_int_add(json_row
, "reportV3", rx_stats
.report_v3
);
1344 json_object_int_add(json_row
, "mtraceResponse",
1345 rx_stats
.mtrace_rsp
);
1346 json_object_int_add(json_row
, "mtraceRequest",
1347 rx_stats
.mtrace_req
);
1348 json_object_int_add(json_row
, "unsupported",
1349 rx_stats
.unsupported
);
1350 json_object_object_add(json
, ifname
? ifname
: "global",
1352 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1353 json
, JSON_C_TO_STRING_PRETTY
));
1354 json_object_free(json
);
1356 vty_out(vty
, "IGMP RX statistics\n");
1357 vty_out(vty
, "Interface : %s\n",
1358 ifname
? ifname
: "global");
1359 vty_out(vty
, "V1 query : %u\n", rx_stats
.query_v1
);
1360 vty_out(vty
, "V2 query : %u\n", rx_stats
.query_v2
);
1361 vty_out(vty
, "V3 query : %u\n", rx_stats
.query_v3
);
1362 vty_out(vty
, "V2 leave : %u\n", rx_stats
.leave_v2
);
1363 vty_out(vty
, "V1 report : %u\n", rx_stats
.report_v1
);
1364 vty_out(vty
, "V2 report : %u\n", rx_stats
.report_v2
);
1365 vty_out(vty
, "V3 report : %u\n", rx_stats
.report_v3
);
1366 vty_out(vty
, "mtrace response : %u\n", rx_stats
.mtrace_rsp
);
1367 vty_out(vty
, "mtrace request : %u\n", rx_stats
.mtrace_req
);
1368 vty_out(vty
, "unsupported : %u\n", rx_stats
.unsupported
);
1372 static void pim_show_interfaces(struct pim_instance
*pim
, struct vty
*vty
,
1375 struct interface
*ifp
;
1376 struct listnode
*upnode
;
1377 struct pim_interface
*pim_ifp
;
1378 struct pim_upstream
*up
;
1381 int pim_ifchannels
= 0;
1382 json_object
*json
= NULL
;
1383 json_object
*json_row
= NULL
;
1384 json_object
*json_tmp
;
1386 json
= json_object_new_object();
1388 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1389 pim_ifp
= ifp
->info
;
1394 pim_nbrs
= pim_ifp
->pim_neighbor_list
->count
;
1395 pim_ifchannels
= pim_if_ifchannel_count(pim_ifp
);
1398 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
, up
))
1399 if (ifp
== up
->rpf
.source_nexthop
.interface
)
1400 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
1403 json_row
= json_object_new_object();
1404 json_object_pim_ifp_add(json_row
, ifp
);
1405 json_object_int_add(json_row
, "pimNeighbors", pim_nbrs
);
1406 json_object_int_add(json_row
, "pimIfChannels", pim_ifchannels
);
1407 json_object_int_add(json_row
, "firstHopRouterCount", fhr
);
1408 json_object_string_add(json_row
, "pimDesignatedRouter",
1409 inet_ntoa(pim_ifp
->pim_dr_addr
));
1411 if (pim_ifp
->pim_dr_addr
.s_addr
1412 == pim_ifp
->primary_address
.s_addr
)
1413 json_object_boolean_true_add(
1414 json_row
, "pimDesignatedRouterLocal");
1416 json_object_object_add(json
, ifp
->name
, json_row
);
1420 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1421 json
, JSON_C_TO_STRING_PRETTY
));
1424 "Interface State Address PIM Nbrs PIM DR FHR IfChannels\n");
1426 json_object_object_foreach(json
, key
, val
)
1428 vty_out(vty
, "%-16s ", key
);
1430 json_object_object_get_ex(val
, "state", &json_tmp
);
1431 vty_out(vty
, "%5s ", json_object_get_string(json_tmp
));
1433 json_object_object_get_ex(val
, "address", &json_tmp
);
1434 vty_out(vty
, "%15s ",
1435 json_object_get_string(json_tmp
));
1437 json_object_object_get_ex(val
, "pimNeighbors",
1439 vty_out(vty
, "%8d ", json_object_get_int(json_tmp
));
1441 if (json_object_object_get_ex(
1442 val
, "pimDesignatedRouterLocal",
1444 vty_out(vty
, "%15s ", "local");
1446 json_object_object_get_ex(
1447 val
, "pimDesignatedRouter", &json_tmp
);
1448 vty_out(vty
, "%15s ",
1449 json_object_get_string(json_tmp
));
1452 json_object_object_get_ex(val
, "firstHopRouter",
1454 vty_out(vty
, "%3d ", json_object_get_int(json_tmp
));
1456 json_object_object_get_ex(val
, "pimIfChannels",
1458 vty_out(vty
, "%9d\n", json_object_get_int(json_tmp
));
1462 json_object_free(json
);
1465 static void pim_show_interface_traffic(struct pim_instance
*pim
,
1466 struct vty
*vty
, bool uj
)
1468 struct interface
*ifp
= NULL
;
1469 struct pim_interface
*pim_ifp
= NULL
;
1470 json_object
*json
= NULL
;
1471 json_object
*json_row
= NULL
;
1474 json
= json_object_new_object();
1477 vty_out(vty
, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s\n",
1478 "Interface", " HELLO", " JOIN",
1479 " PRUNE", " REGISTER", "REGISTER-STOP",
1481 vty_out(vty
, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s\n", "",
1482 " Rx/Tx", " Rx/Tx", " Rx/Tx",
1483 " Rx/Tx", " Rx/Tx", " Rx/Tx");
1485 "---------------------------------------------------------------------------------------------------------------\n");
1488 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1489 pim_ifp
= ifp
->info
;
1494 if (pim_ifp
->pim_sock_fd
< 0)
1497 json_row
= json_object_new_object();
1498 json_object_pim_ifp_add(json_row
, ifp
);
1499 json_object_int_add(json_row
, "helloRx",
1500 pim_ifp
->pim_ifstat_hello_recv
);
1501 json_object_int_add(json_row
, "helloTx",
1502 pim_ifp
->pim_ifstat_hello_sent
);
1503 json_object_int_add(json_row
, "joinRx",
1504 pim_ifp
->pim_ifstat_join_recv
);
1505 json_object_int_add(json_row
, "joinTx",
1506 pim_ifp
->pim_ifstat_join_send
);
1507 json_object_int_add(json_row
, "registerRx",
1508 pim_ifp
->pim_ifstat_reg_recv
);
1509 json_object_int_add(json_row
, "registerTx",
1510 pim_ifp
->pim_ifstat_reg_recv
);
1511 json_object_int_add(json_row
, "registerStopRx",
1512 pim_ifp
->pim_ifstat_reg_stop_recv
);
1513 json_object_int_add(json_row
, "registerStopTx",
1514 pim_ifp
->pim_ifstat_reg_stop_send
);
1515 json_object_int_add(json_row
, "assertRx",
1516 pim_ifp
->pim_ifstat_assert_recv
);
1517 json_object_int_add(json_row
, "assertTx",
1518 pim_ifp
->pim_ifstat_assert_send
);
1520 json_object_object_add(json
, ifp
->name
, json_row
);
1523 "%-16s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u \n",
1524 ifp
->name
, pim_ifp
->pim_ifstat_hello_recv
,
1525 pim_ifp
->pim_ifstat_hello_sent
,
1526 pim_ifp
->pim_ifstat_join_recv
,
1527 pim_ifp
->pim_ifstat_join_send
,
1528 pim_ifp
->pim_ifstat_prune_recv
,
1529 pim_ifp
->pim_ifstat_prune_send
,
1530 pim_ifp
->pim_ifstat_reg_recv
,
1531 pim_ifp
->pim_ifstat_reg_send
,
1532 pim_ifp
->pim_ifstat_reg_stop_recv
,
1533 pim_ifp
->pim_ifstat_reg_stop_send
,
1534 pim_ifp
->pim_ifstat_assert_recv
,
1535 pim_ifp
->pim_ifstat_assert_send
);
1539 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1540 json
, JSON_C_TO_STRING_PRETTY
));
1541 json_object_free(json
);
1545 static void pim_show_interface_traffic_single(struct pim_instance
*pim
,
1547 const char *ifname
, bool uj
)
1549 struct interface
*ifp
= NULL
;
1550 struct pim_interface
*pim_ifp
= NULL
;
1551 json_object
*json
= NULL
;
1552 json_object
*json_row
= NULL
;
1553 uint8_t found_ifname
= 0;
1556 json
= json_object_new_object();
1559 vty_out(vty
, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s\n",
1560 "Interface", " HELLO", " JOIN", " PRUNE",
1561 " REGISTER", " REGISTER-STOP", " ASSERT");
1562 vty_out(vty
, "%-14s%-18s%-17s%-17s%-17s%-17s%-17s\n", "",
1563 " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1564 " Rx/Tx", " Rx/Tx");
1566 "---------------------------------------------------------------------------------------------------------------------\n");
1569 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1570 if (strcmp(ifname
, ifp
->name
))
1573 pim_ifp
= ifp
->info
;
1578 if (pim_ifp
->pim_sock_fd
< 0)
1583 json_row
= json_object_new_object();
1584 json_object_pim_ifp_add(json_row
, ifp
);
1585 json_object_int_add(json_row
, "helloRx",
1586 pim_ifp
->pim_ifstat_hello_recv
);
1587 json_object_int_add(json_row
, "helloTx",
1588 pim_ifp
->pim_ifstat_hello_sent
);
1589 json_object_int_add(json_row
, "joinRx",
1590 pim_ifp
->pim_ifstat_join_recv
);
1591 json_object_int_add(json_row
, "joinTx",
1592 pim_ifp
->pim_ifstat_join_send
);
1593 json_object_int_add(json_row
, "registerRx",
1594 pim_ifp
->pim_ifstat_reg_recv
);
1595 json_object_int_add(json_row
, "registerTx",
1596 pim_ifp
->pim_ifstat_reg_recv
);
1597 json_object_int_add(json_row
, "registerStopRx",
1598 pim_ifp
->pim_ifstat_reg_stop_recv
);
1599 json_object_int_add(json_row
, "registerStopTx",
1600 pim_ifp
->pim_ifstat_reg_stop_send
);
1601 json_object_int_add(json_row
, "assertRx",
1602 pim_ifp
->pim_ifstat_assert_recv
);
1603 json_object_int_add(json_row
, "assertTx",
1604 pim_ifp
->pim_ifstat_assert_send
);
1606 json_object_object_add(json
, ifp
->name
, json_row
);
1609 "%-16s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u \n",
1610 ifp
->name
, pim_ifp
->pim_ifstat_hello_recv
,
1611 pim_ifp
->pim_ifstat_hello_sent
,
1612 pim_ifp
->pim_ifstat_join_recv
,
1613 pim_ifp
->pim_ifstat_join_send
,
1614 pim_ifp
->pim_ifstat_prune_recv
,
1615 pim_ifp
->pim_ifstat_prune_send
,
1616 pim_ifp
->pim_ifstat_reg_recv
,
1617 pim_ifp
->pim_ifstat_reg_send
,
1618 pim_ifp
->pim_ifstat_reg_stop_recv
,
1619 pim_ifp
->pim_ifstat_reg_stop_send
,
1620 pim_ifp
->pim_ifstat_assert_recv
,
1621 pim_ifp
->pim_ifstat_assert_send
);
1625 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1626 json
, JSON_C_TO_STRING_PRETTY
));
1627 json_object_free(json
);
1630 vty_out(vty
, "%% No such interface\n");
1634 static void pim_show_join_helper(struct vty
*vty
, struct pim_interface
*pim_ifp
,
1635 struct pim_ifchannel
*ch
, json_object
*json
,
1636 time_t now
, bool uj
)
1638 char ch_src_str
[INET_ADDRSTRLEN
];
1639 char ch_grp_str
[INET_ADDRSTRLEN
];
1640 json_object
*json_iface
= NULL
;
1641 json_object
*json_row
= NULL
;
1642 json_object
*json_grp
= NULL
;
1643 struct in_addr ifaddr
;
1648 ifaddr
= pim_ifp
->primary_address
;
1650 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
1651 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
1653 pim_time_uptime_begin(uptime
, sizeof(uptime
), now
, ch
->ifjoin_creation
);
1654 pim_time_timer_to_mmss(expire
, sizeof(expire
),
1655 ch
->t_ifjoin_expiry_timer
);
1656 pim_time_timer_to_mmss(prune
, sizeof(prune
),
1657 ch
->t_ifjoin_prune_pending_timer
);
1660 json_object_object_get_ex(json
, ch
->interface
->name
,
1664 json_iface
= json_object_new_object();
1665 json_object_pim_ifp_add(json_iface
, ch
->interface
);
1666 json_object_object_add(json
, ch
->interface
->name
,
1670 json_row
= json_object_new_object();
1671 json_object_string_add(json_row
, "source", ch_src_str
);
1672 json_object_string_add(json_row
, "group", ch_grp_str
);
1673 json_object_string_add(json_row
, "upTime", uptime
);
1674 json_object_string_add(json_row
, "expire", expire
);
1675 json_object_string_add(json_row
, "prune", prune
);
1676 json_object_string_add(
1677 json_row
, "channelJoinName",
1678 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
, ch
->flags
));
1679 if (PIM_IF_FLAG_TEST_S_G_RPT(ch
->flags
))
1680 json_object_int_add(json_row
, "SGRpt", 1);
1682 json_object_object_get_ex(json_iface
, ch_grp_str
, &json_grp
);
1684 json_grp
= json_object_new_object();
1685 json_object_object_add(json_grp
, ch_src_str
, json_row
);
1686 json_object_object_add(json_iface
, ch_grp_str
,
1689 json_object_object_add(json_grp
, ch_src_str
, json_row
);
1691 vty_out(vty
, "%-16s %-15s %-15s %-15s %-10s %8s %-6s %5s\n",
1692 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
,
1694 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
, ch
->flags
),
1695 uptime
, expire
, prune
);
1699 static void pim_show_join(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
1701 struct pim_interface
*pim_ifp
;
1702 struct pim_ifchannel
*ch
;
1703 struct interface
*ifp
;
1705 json_object
*json
= NULL
;
1707 now
= pim_time_monotonic_sec();
1710 json
= json_object_new_object();
1713 "Interface Address Source Group State Uptime Expire Prune\n");
1715 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1716 pim_ifp
= ifp
->info
;
1720 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
1721 pim_show_join_helper(vty
, pim_ifp
, ch
, json
, now
, uj
);
1722 } /* scan interface channels */
1726 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1727 json
, JSON_C_TO_STRING_PRETTY
));
1728 json_object_free(json
);
1732 static void pim_show_neighbors_single(struct pim_instance
*pim
, struct vty
*vty
,
1733 const char *neighbor
, bool uj
)
1735 struct listnode
*neighnode
;
1736 struct interface
*ifp
;
1737 struct pim_interface
*pim_ifp
;
1738 struct pim_neighbor
*neigh
;
1740 int found_neighbor
= 0;
1741 int option_address_list
;
1742 int option_dr_priority
;
1743 int option_generation_id
;
1744 int option_holdtime
;
1745 int option_lan_prune_delay
;
1749 char neigh_src_str
[INET_ADDRSTRLEN
];
1751 json_object
*json
= NULL
;
1752 json_object
*json_ifp
= NULL
;
1753 json_object
*json_row
= NULL
;
1755 now
= pim_time_monotonic_sec();
1758 json
= json_object_new_object();
1760 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1761 pim_ifp
= ifp
->info
;
1766 if (pim_ifp
->pim_sock_fd
< 0)
1769 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
1771 pim_inet4_dump("<src?>", neigh
->source_addr
,
1772 neigh_src_str
, sizeof(neigh_src_str
));
1775 * The user can specify either the interface name or the
1777 * If this pim_ifp matches neither then skip.
1779 if (strcmp(neighbor
, "detail")
1780 && strcmp(neighbor
, ifp
->name
)
1781 && strcmp(neighbor
, neigh_src_str
))
1785 pim_time_uptime(uptime
, sizeof(uptime
),
1786 now
- neigh
->creation
);
1787 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
1788 neigh
->t_expire_timer
);
1790 option_address_list
= 0;
1791 option_dr_priority
= 0;
1792 option_generation_id
= 0;
1793 option_holdtime
= 0;
1794 option_lan_prune_delay
= 0;
1797 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1798 PIM_OPTION_MASK_ADDRESS_LIST
))
1799 option_address_list
= 1;
1801 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1802 PIM_OPTION_MASK_DR_PRIORITY
))
1803 option_dr_priority
= 1;
1805 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1806 PIM_OPTION_MASK_GENERATION_ID
))
1807 option_generation_id
= 1;
1809 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1810 PIM_OPTION_MASK_HOLDTIME
))
1811 option_holdtime
= 1;
1813 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1814 PIM_OPTION_MASK_LAN_PRUNE_DELAY
))
1815 option_lan_prune_delay
= 1;
1817 if (PIM_OPTION_IS_SET(
1818 neigh
->hello_options
,
1819 PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION
))
1824 /* Does this ifp live in json? If not create
1826 json_object_object_get_ex(json
, ifp
->name
,
1830 json_ifp
= json_object_new_object();
1831 json_object_pim_ifp_add(json_ifp
, ifp
);
1832 json_object_object_add(json
, ifp
->name
,
1836 json_row
= json_object_new_object();
1837 json_object_string_add(json_row
, "interface",
1839 json_object_string_add(json_row
, "address",
1841 json_object_string_add(json_row
, "upTime",
1843 json_object_string_add(json_row
, "holdtime",
1845 json_object_int_add(json_row
, "drPriority",
1846 neigh
->dr_priority
);
1847 json_object_int_add(json_row
, "generationId",
1848 neigh
->generation_id
);
1850 if (option_address_list
)
1851 json_object_boolean_true_add(
1853 "helloOptionAddressList");
1855 if (option_dr_priority
)
1856 json_object_boolean_true_add(
1858 "helloOptionDrPriority");
1860 if (option_generation_id
)
1861 json_object_boolean_true_add(
1863 "helloOptionGenerationId");
1865 if (option_holdtime
)
1866 json_object_boolean_true_add(
1868 "helloOptionHoldtime");
1870 if (option_lan_prune_delay
)
1871 json_object_boolean_true_add(
1873 "helloOptionLanPruneDelay");
1876 json_object_boolean_true_add(
1877 json_row
, "helloOptionTBit");
1879 json_object_object_add(json_ifp
, neigh_src_str
,
1883 vty_out(vty
, "Interface : %s\n", ifp
->name
);
1884 vty_out(vty
, "Neighbor : %s\n", neigh_src_str
);
1892 " DR Priority : %d\n",
1893 neigh
->dr_priority
);
1895 " Generation ID : %08x\n",
1896 neigh
->generation_id
);
1898 " Override Interval (msec) : %d\n",
1899 neigh
->override_interval_msec
);
1901 " Propagation Delay (msec) : %d\n",
1902 neigh
->propagation_delay_msec
);
1904 " Hello Option - Address List : %s\n",
1905 option_address_list
? "yes" : "no");
1907 " Hello Option - DR Priority : %s\n",
1908 option_dr_priority
? "yes" : "no");
1910 " Hello Option - Generation ID : %s\n",
1911 option_generation_id
? "yes" : "no");
1913 " Hello Option - Holdtime : %s\n",
1914 option_holdtime
? "yes" : "no");
1916 " Hello Option - LAN Prune Delay : %s\n",
1917 option_lan_prune_delay
? "yes" : "no");
1919 " Hello Option - T-bit : %s\n",
1920 option_t_bit
? "yes" : "no");
1921 pim_bfd_show_info(vty
, neigh
->bfd_info
,
1929 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1930 json
, JSON_C_TO_STRING_PRETTY
));
1931 json_object_free(json
);
1934 if (!found_neighbor
)
1936 "%% No such interface or neighbor\n");
1941 static void pim_show_state(struct pim_instance
*pim
, struct vty
*vty
,
1942 const char *src_or_group
, const char *group
, bool uj
)
1944 struct channel_oil
*c_oil
;
1945 struct listnode
*node
;
1946 json_object
*json
= NULL
;
1947 json_object
*json_group
= NULL
;
1948 json_object
*json_ifp_in
= NULL
;
1949 json_object
*json_ifp_out
= NULL
;
1950 json_object
*json_source
= NULL
;
1953 now
= pim_time_monotonic_sec();
1956 json
= json_object_new_object();
1959 "Codes: J -> Pim Join, I -> IGMP Report, S -> Source, * -> Inherited from (*,G)");
1961 "\nInstalled Source Group IIF OIL\n");
1964 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
1965 char grp_str
[INET_ADDRSTRLEN
];
1966 char src_str
[INET_ADDRSTRLEN
];
1967 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
1968 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
1970 struct interface
*ifp_in
;
1973 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
1975 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
1977 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
1980 strcpy(in_ifname
, ifp_in
->name
);
1982 strcpy(in_ifname
, "<iif?>");
1985 if (strcmp(src_or_group
, src_str
)
1986 && strcmp(src_or_group
, grp_str
))
1989 if (group
&& strcmp(group
, grp_str
))
1995 /* Find the group, create it if it doesn't exist */
1996 json_object_object_get_ex(json
, grp_str
, &json_group
);
1999 json_group
= json_object_new_object();
2000 json_object_object_add(json
, grp_str
,
2004 /* Find the source nested under the group, create it if
2005 * it doesn't exist */
2006 json_object_object_get_ex(json_group
, src_str
,
2010 json_source
= json_object_new_object();
2011 json_object_object_add(json_group
, src_str
,
2015 /* Find the inbound interface nested under the source,
2016 * create it if it doesn't exist */
2017 json_object_object_get_ex(json_source
, in_ifname
,
2021 json_ifp_in
= json_object_new_object();
2022 json_object_object_add(json_source
, in_ifname
,
2024 json_object_int_add(json_source
, "Installed",
2026 json_object_int_add(json_source
, "RefCount",
2027 c_oil
->oil_ref_count
);
2028 json_object_int_add(json_source
, "OilListSize",
2030 json_object_int_add(
2031 json_source
, "OilRescan",
2032 c_oil
->oil_inherited_rescan
);
2033 json_object_int_add(json_source
, "LastUsed",
2034 c_oil
->cc
.lastused
);
2035 json_object_int_add(json_source
, "PacketCount",
2037 json_object_int_add(json_source
, "ByteCount",
2039 json_object_int_add(json_source
,
2041 c_oil
->cc
.wrong_if
);
2044 vty_out(vty
, "%-9d %-15s %-15s %-16s ",
2045 c_oil
->installed
, src_str
, grp_str
, in_ifname
);
2048 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
2050 struct interface
*ifp_out
;
2051 char oif_uptime
[10];
2054 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
2058 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
2060 oif_uptime
, sizeof(oif_uptime
),
2061 now
- c_oil
->oif_creation
[oif_vif_index
]);
2064 strcpy(out_ifname
, ifp_out
->name
);
2066 strcpy(out_ifname
, "<oif?>");
2069 json_ifp_out
= json_object_new_object();
2070 json_object_string_add(json_ifp_out
, "source",
2072 json_object_string_add(json_ifp_out
, "group",
2074 json_object_string_add(json_ifp_out
,
2077 json_object_string_add(json_ifp_out
,
2078 "outboundInterface",
2080 json_object_int_add(json_ifp_out
, "installed",
2083 json_object_object_add(json_ifp_in
, out_ifname
,
2088 vty_out(vty
, "%s(%c%c%c%c)", out_ifname
,
2089 (c_oil
->oif_flags
[oif_vif_index
]
2090 & PIM_OIF_FLAG_PROTO_IGMP
)
2093 (c_oil
->oif_flags
[oif_vif_index
]
2094 & PIM_OIF_FLAG_PROTO_PIM
)
2097 (c_oil
->oif_flags
[oif_vif_index
]
2098 & PIM_OIF_FLAG_PROTO_SOURCE
)
2101 (c_oil
->oif_flags
[oif_vif_index
]
2102 & PIM_OIF_FLAG_PROTO_STAR
)
2106 vty_out(vty
, ", %s(%c%c%c%c)",
2108 (c_oil
->oif_flags
[oif_vif_index
]
2109 & PIM_OIF_FLAG_PROTO_IGMP
)
2112 (c_oil
->oif_flags
[oif_vif_index
]
2113 & PIM_OIF_FLAG_PROTO_PIM
)
2116 (c_oil
->oif_flags
[oif_vif_index
]
2117 & PIM_OIF_FLAG_PROTO_SOURCE
)
2120 (c_oil
->oif_flags
[oif_vif_index
]
2121 & PIM_OIF_FLAG_PROTO_STAR
)
2133 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2134 json
, JSON_C_TO_STRING_PRETTY
));
2135 json_object_free(json
);
2141 static void pim_show_neighbors(struct pim_instance
*pim
, struct vty
*vty
,
2144 struct listnode
*neighnode
;
2145 struct interface
*ifp
;
2146 struct pim_interface
*pim_ifp
;
2147 struct pim_neighbor
*neigh
;
2151 char neigh_src_str
[INET_ADDRSTRLEN
];
2152 json_object
*json
= NULL
;
2153 json_object
*json_ifp_rows
= NULL
;
2154 json_object
*json_row
= NULL
;
2156 now
= pim_time_monotonic_sec();
2159 json
= json_object_new_object();
2162 "Interface Neighbor Uptime Holdtime DR Pri\n");
2165 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2166 pim_ifp
= ifp
->info
;
2171 if (pim_ifp
->pim_sock_fd
< 0)
2175 json_ifp_rows
= json_object_new_object();
2177 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
2179 pim_inet4_dump("<src?>", neigh
->source_addr
,
2180 neigh_src_str
, sizeof(neigh_src_str
));
2181 pim_time_uptime(uptime
, sizeof(uptime
),
2182 now
- neigh
->creation
);
2183 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
2184 neigh
->t_expire_timer
);
2187 json_row
= json_object_new_object();
2188 json_object_string_add(json_row
, "interface",
2190 json_object_string_add(json_row
, "neighbor",
2192 json_object_string_add(json_row
, "upTime",
2194 json_object_string_add(json_row
, "holdTime",
2196 json_object_int_add(json_row
, "holdTimeMax",
2198 json_object_int_add(json_row
, "drPriority",
2199 neigh
->dr_priority
);
2200 json_object_object_add(json_ifp_rows
,
2201 neigh_src_str
, json_row
);
2204 vty_out(vty
, "%-16s %15s %8s %8s %6d\n",
2205 ifp
->name
, neigh_src_str
, uptime
,
2206 expire
, neigh
->dr_priority
);
2211 json_object_object_add(json
, ifp
->name
, json_ifp_rows
);
2212 json_ifp_rows
= NULL
;
2217 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2218 json
, JSON_C_TO_STRING_PRETTY
));
2219 json_object_free(json
);
2223 static void pim_show_neighbors_secondary(struct pim_instance
*pim
,
2226 struct interface
*ifp
;
2229 "Interface Address Neighbor Secondary \n");
2231 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2232 struct pim_interface
*pim_ifp
;
2233 struct in_addr ifaddr
;
2234 struct listnode
*neighnode
;
2235 struct pim_neighbor
*neigh
;
2237 pim_ifp
= ifp
->info
;
2242 if (pim_ifp
->pim_sock_fd
< 0)
2245 ifaddr
= pim_ifp
->primary_address
;
2247 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
2249 char neigh_src_str
[INET_ADDRSTRLEN
];
2250 struct listnode
*prefix_node
;
2253 if (!neigh
->prefix_list
)
2256 pim_inet4_dump("<src?>", neigh
->source_addr
,
2257 neigh_src_str
, sizeof(neigh_src_str
));
2259 for (ALL_LIST_ELEMENTS_RO(neigh
->prefix_list
,
2261 char neigh_sec_str
[PREFIX2STR_BUFFER
];
2263 prefix2str(p
, neigh_sec_str
,
2264 sizeof(neigh_sec_str
));
2266 vty_out(vty
, "%-16s %-15s %-15s %-15s\n",
2267 ifp
->name
, inet_ntoa(ifaddr
),
2268 neigh_src_str
, neigh_sec_str
);
2274 static void json_object_pim_upstream_add(json_object
*json
,
2275 struct pim_upstream
*up
)
2277 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED
)
2278 json_object_boolean_true_add(json
, "drJoinDesired");
2280 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED
)
2281 json_object_boolean_true_add(json
, "drJoinDesiredUpdated");
2283 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
2284 json_object_boolean_true_add(json
, "firstHopRouter");
2286 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_IGMP
)
2287 json_object_boolean_true_add(json
, "sourceIgmp");
2289 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_PIM
)
2290 json_object_boolean_true_add(json
, "sourcePim");
2292 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_STREAM
)
2293 json_object_boolean_true_add(json
, "sourceStream");
2295 /* XXX: need to print ths flag in the plain text display as well */
2296 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_MSDP
)
2297 json_object_boolean_true_add(json
, "sourceMsdp");
2301 pim_upstream_state2brief_str(enum pim_upstream_state join_state
,
2304 switch (join_state
) {
2305 case PIM_UPSTREAM_NOTJOINED
:
2306 strcpy(state_str
, "NotJ");
2308 case PIM_UPSTREAM_JOINED
:
2309 strcpy(state_str
, "J");
2312 strcpy(state_str
, "Unk");
2317 static const char *pim_reg_state2brief_str(enum pim_reg_state reg_state
,
2320 switch (reg_state
) {
2321 case PIM_REG_NOINFO
:
2322 strcpy(state_str
, "RegNI");
2325 strcpy(state_str
, "RegJ");
2327 case PIM_REG_JOIN_PENDING
:
2329 strcpy(state_str
, "RegP");
2332 strcpy(state_str
, "Unk");
2337 static void pim_show_upstream(struct pim_instance
*pim
, struct vty
*vty
,
2340 struct listnode
*upnode
;
2341 struct pim_upstream
*up
;
2343 json_object
*json
= NULL
;
2344 json_object
*json_group
= NULL
;
2345 json_object
*json_row
= NULL
;
2347 now
= pim_time_monotonic_sec();
2350 json
= json_object_new_object();
2353 "Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt\n");
2355 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
, up
)) {
2356 char src_str
[INET_ADDRSTRLEN
];
2357 char grp_str
[INET_ADDRSTRLEN
];
2359 char join_timer
[10];
2362 char msdp_reg_timer
[10];
2363 char state_str
[PIM_REG_STATE_STR_LEN
];
2365 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2366 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2367 pim_time_uptime(uptime
, sizeof(uptime
),
2368 now
- up
->state_transition
);
2369 pim_time_timer_to_hhmmss(join_timer
, sizeof(join_timer
),
2373 * If the upstream is not dummy and it has a J/P timer for the
2374 * neighbor display that
2376 if (!up
->t_join_timer
&& up
->rpf
.source_nexthop
.interface
) {
2377 struct pim_neighbor
*nbr
;
2379 nbr
= pim_neighbor_find(
2380 up
->rpf
.source_nexthop
.interface
,
2381 up
->rpf
.rpf_addr
.u
.prefix4
);
2383 pim_time_timer_to_hhmmss(join_timer
,
2388 pim_time_timer_to_hhmmss(rs_timer
, sizeof(rs_timer
),
2390 pim_time_timer_to_hhmmss(ka_timer
, sizeof(ka_timer
),
2392 pim_time_timer_to_hhmmss(msdp_reg_timer
, sizeof(msdp_reg_timer
),
2393 up
->t_msdp_reg_timer
);
2395 pim_upstream_state2brief_str(up
->join_state
, state_str
);
2396 if (up
->reg_state
!= PIM_REG_NOINFO
) {
2397 char tmp_str
[PIM_REG_STATE_STR_LEN
];
2399 sprintf(state_str
+ strlen(state_str
), ",%s",
2400 pim_reg_state2brief_str(up
->reg_state
,
2405 json_object_object_get_ex(json
, grp_str
, &json_group
);
2408 json_group
= json_object_new_object();
2409 json_object_object_add(json
, grp_str
,
2413 json_row
= json_object_new_object();
2414 json_object_pim_upstream_add(json_row
, up
);
2415 json_object_string_add(
2416 json_row
, "inboundInterface",
2417 up
->rpf
.source_nexthop
.interface
2418 ? up
->rpf
.source_nexthop
.interface
->name
2422 * The RPF address we use is slightly different
2423 * based upon what we are looking up.
2424 * If we have a S, list that unless
2425 * we are the FHR, else we just put
2426 * the RP as the rpfAddress
2428 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
2429 || up
->sg
.src
.s_addr
== INADDR_ANY
) {
2430 char rpf
[PREFIX_STRLEN
];
2431 struct pim_rpf
*rpg
;
2433 rpg
= RP(pim
, up
->sg
.grp
);
2434 pim_inet4_dump("<rpf?>",
2435 rpg
->rpf_addr
.u
.prefix4
, rpf
,
2437 json_object_string_add(json_row
, "rpfAddress",
2440 json_object_string_add(json_row
, "rpfAddress",
2444 json_object_string_add(json_row
, "source", src_str
);
2445 json_object_string_add(json_row
, "group", grp_str
);
2446 json_object_string_add(json_row
, "state", state_str
);
2447 json_object_string_add(
2448 json_row
, "joinState",
2449 pim_upstream_state2str(up
->join_state
));
2450 json_object_string_add(
2451 json_row
, "regState",
2452 pim_reg_state2str(up
->reg_state
, state_str
));
2453 json_object_string_add(json_row
, "upTime", uptime
);
2454 json_object_string_add(json_row
, "joinTimer",
2456 json_object_string_add(json_row
, "resetTimer",
2458 json_object_string_add(json_row
, "keepaliveTimer",
2460 json_object_string_add(json_row
, "msdpRegTimer",
2462 json_object_int_add(json_row
, "refCount",
2464 json_object_int_add(json_row
, "sptBit", up
->sptbit
);
2465 json_object_object_add(json_group
, src_str
, json_row
);
2468 "%-16s%-15s %-15s %-11s %-8s %-9s %-9s %-9s %6d\n",
2469 up
->rpf
.source_nexthop
.interface
2470 ? up
->rpf
.source_nexthop
.interface
->name
2472 src_str
, grp_str
, state_str
, uptime
, join_timer
,
2473 rs_timer
, ka_timer
, up
->ref_count
);
2478 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2479 json
, JSON_C_TO_STRING_PRETTY
));
2480 json_object_free(json
);
2484 static void pim_show_join_desired_helper(struct pim_instance
*pim
,
2486 struct pim_interface
*pim_ifp
,
2487 struct pim_ifchannel
*ch
,
2488 json_object
*json
, bool uj
)
2490 struct pim_upstream
*up
= ch
->upstream
;
2491 json_object
*json_group
= NULL
;
2492 char src_str
[INET_ADDRSTRLEN
];
2493 char grp_str
[INET_ADDRSTRLEN
];
2494 json_object
*json_row
= NULL
;
2496 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2497 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2500 json_object_object_get_ex(json
, grp_str
, &json_group
);
2503 json_group
= json_object_new_object();
2504 json_object_object_add(json
, grp_str
, json_group
);
2507 json_row
= json_object_new_object();
2508 json_object_pim_upstream_add(json_row
, up
);
2509 json_object_string_add(json_row
, "interface",
2510 ch
->interface
->name
);
2511 json_object_string_add(json_row
, "source", src_str
);
2512 json_object_string_add(json_row
, "group", grp_str
);
2514 if (pim_macro_ch_lost_assert(ch
))
2515 json_object_boolean_true_add(json_row
, "lostAssert");
2517 if (pim_macro_chisin_joins(ch
))
2518 json_object_boolean_true_add(json_row
, "joins");
2520 if (pim_macro_chisin_pim_include(ch
))
2521 json_object_boolean_true_add(json_row
, "pimInclude");
2523 if (pim_upstream_evaluate_join_desired(pim
, up
))
2524 json_object_boolean_true_add(json_row
,
2525 "evaluateJoinDesired");
2527 json_object_object_add(json_group
, src_str
, json_row
);
2530 vty_out(vty
, "%-16s %-15s %-15s %-10s %-5s %-10s %-11s %-6s\n",
2531 ch
->interface
->name
, src_str
, grp_str
,
2532 pim_macro_ch_lost_assert(ch
) ? "yes" : "no",
2533 pim_macro_chisin_joins(ch
) ? "yes" : "no",
2534 pim_macro_chisin_pim_include(ch
) ? "yes" : "no",
2535 PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(up
->flags
)
2538 pim_upstream_evaluate_join_desired(pim
, up
) ? "yes"
2543 static void pim_show_join_desired(struct pim_instance
*pim
, struct vty
*vty
,
2546 struct pim_interface
*pim_ifp
;
2547 struct pim_ifchannel
*ch
;
2548 struct interface
*ifp
;
2550 json_object
*json
= NULL
;
2553 json
= json_object_new_object();
2556 "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD\n");
2558 /* scan per-interface (S,G) state */
2559 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2560 pim_ifp
= ifp
->info
;
2565 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
2566 /* scan all interfaces */
2567 pim_show_join_desired_helper(pim
, vty
, pim_ifp
, ch
,
2573 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2574 json
, JSON_C_TO_STRING_PRETTY
));
2575 json_object_free(json
);
2579 static void pim_show_upstream_rpf(struct pim_instance
*pim
, struct vty
*vty
,
2582 struct listnode
*upnode
;
2583 struct pim_upstream
*up
;
2584 json_object
*json
= NULL
;
2585 json_object
*json_group
= NULL
;
2586 json_object
*json_row
= NULL
;
2589 json
= json_object_new_object();
2592 "Source Group RpfIface RibNextHop RpfAddress \n");
2594 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
, up
)) {
2595 char src_str
[INET_ADDRSTRLEN
];
2596 char grp_str
[INET_ADDRSTRLEN
];
2597 char rpf_nexthop_str
[PREFIX_STRLEN
];
2598 char rpf_addr_str
[PREFIX_STRLEN
];
2599 struct pim_rpf
*rpf
;
2600 const char *rpf_ifname
;
2604 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2605 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2606 pim_addr_dump("<nexthop?>",
2607 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2608 rpf_nexthop_str
, sizeof(rpf_nexthop_str
));
2609 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2610 sizeof(rpf_addr_str
));
2612 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2615 json_object_object_get_ex(json
, grp_str
, &json_group
);
2618 json_group
= json_object_new_object();
2619 json_object_object_add(json
, grp_str
,
2623 json_row
= json_object_new_object();
2624 json_object_pim_upstream_add(json_row
, up
);
2625 json_object_string_add(json_row
, "source", src_str
);
2626 json_object_string_add(json_row
, "group", grp_str
);
2627 json_object_string_add(json_row
, "rpfInterface",
2629 json_object_string_add(json_row
, "ribNexthop",
2631 json_object_string_add(json_row
, "rpfAddress",
2633 json_object_object_add(json_group
, src_str
, json_row
);
2635 vty_out(vty
, "%-15s %-15s %-16s %-15s %-15s\n", src_str
,
2636 grp_str
, rpf_ifname
, rpf_nexthop_str
,
2642 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2643 json
, JSON_C_TO_STRING_PRETTY
));
2644 json_object_free(json
);
2648 static void show_rpf_refresh_stats(struct vty
*vty
, struct pim_instance
*pim
,
2649 time_t now
, json_object
*json
)
2651 char refresh_uptime
[10];
2653 pim_time_uptime_begin(refresh_uptime
, sizeof(refresh_uptime
), now
,
2654 pim
->rpf_cache_refresh_last
);
2657 json_object_int_add(json
, "rpfCacheRefreshDelayMsecs",
2658 router
->rpf_cache_refresh_delay_msec
);
2659 json_object_int_add(
2660 json
, "rpfCacheRefreshTimer",
2661 pim_time_timer_remain_msec(pim
->rpf_cache_refresher
));
2662 json_object_int_add(json
, "rpfCacheRefreshRequests",
2663 pim
->rpf_cache_refresh_requests
);
2664 json_object_int_add(json
, "rpfCacheRefreshEvents",
2665 pim
->rpf_cache_refresh_events
);
2666 json_object_string_add(json
, "rpfCacheRefreshLast",
2668 json_object_int_add(json
, "nexthopLookups",
2669 pim
->nexthop_lookups
);
2670 json_object_int_add(json
, "nexthopLookupsAvoided",
2671 pim
->nexthop_lookups_avoided
);
2674 "RPF Cache Refresh Delay: %ld msecs\n"
2675 "RPF Cache Refresh Timer: %ld msecs\n"
2676 "RPF Cache Refresh Requests: %lld\n"
2677 "RPF Cache Refresh Events: %lld\n"
2678 "RPF Cache Refresh Last: %s\n"
2679 "Nexthop Lookups: %lld\n"
2680 "Nexthop Lookups Avoided: %lld\n",
2681 router
->rpf_cache_refresh_delay_msec
,
2682 pim_time_timer_remain_msec(pim
->rpf_cache_refresher
),
2683 (long long)pim
->rpf_cache_refresh_requests
,
2684 (long long)pim
->rpf_cache_refresh_events
,
2685 refresh_uptime
, (long long)pim
->nexthop_lookups
,
2686 (long long)pim
->nexthop_lookups_avoided
);
2690 static void show_scan_oil_stats(struct pim_instance
*pim
, struct vty
*vty
,
2693 char uptime_scan_oil
[10];
2694 char uptime_mroute_add
[10];
2695 char uptime_mroute_del
[10];
2697 pim_time_uptime_begin(uptime_scan_oil
, sizeof(uptime_scan_oil
), now
,
2698 pim
->scan_oil_last
);
2699 pim_time_uptime_begin(uptime_mroute_add
, sizeof(uptime_mroute_add
), now
,
2700 pim
->mroute_add_last
);
2701 pim_time_uptime_begin(uptime_mroute_del
, sizeof(uptime_mroute_del
), now
,
2702 pim
->mroute_del_last
);
2705 "Scan OIL - Last: %s Events: %lld\n"
2706 "MFC Add - Last: %s Events: %lld\n"
2707 "MFC Del - Last: %s Events: %lld\n",
2708 uptime_scan_oil
, (long long)pim
->scan_oil_events
,
2709 uptime_mroute_add
, (long long)pim
->mroute_add_events
,
2710 uptime_mroute_del
, (long long)pim
->mroute_del_events
);
2713 static void pim_show_rpf(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
2715 struct listnode
*up_node
;
2716 struct pim_upstream
*up
;
2717 time_t now
= pim_time_monotonic_sec();
2718 json_object
*json
= NULL
;
2719 json_object
*json_group
= NULL
;
2720 json_object
*json_row
= NULL
;
2723 json
= json_object_new_object();
2724 show_rpf_refresh_stats(vty
, pim
, now
, json
);
2726 show_rpf_refresh_stats(vty
, pim
, now
, json
);
2729 "Source Group RpfIface RpfAddress RibNextHop Metric Pref\n");
2732 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, up_node
, up
)) {
2733 char src_str
[INET_ADDRSTRLEN
];
2734 char grp_str
[INET_ADDRSTRLEN
];
2735 char rpf_addr_str
[PREFIX_STRLEN
];
2736 char rib_nexthop_str
[PREFIX_STRLEN
];
2737 const char *rpf_ifname
;
2738 struct pim_rpf
*rpf
= &up
->rpf
;
2740 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2741 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2742 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2743 sizeof(rpf_addr_str
));
2744 pim_addr_dump("<nexthop?>",
2745 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2746 rib_nexthop_str
, sizeof(rib_nexthop_str
));
2748 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2751 json_object_object_get_ex(json
, grp_str
, &json_group
);
2754 json_group
= json_object_new_object();
2755 json_object_object_add(json
, grp_str
,
2759 json_row
= json_object_new_object();
2760 json_object_string_add(json_row
, "source", src_str
);
2761 json_object_string_add(json_row
, "group", grp_str
);
2762 json_object_string_add(json_row
, "rpfInterface",
2764 json_object_string_add(json_row
, "rpfAddress",
2766 json_object_string_add(json_row
, "ribNexthop",
2768 json_object_int_add(
2769 json_row
, "routeMetric",
2770 rpf
->source_nexthop
.mrib_route_metric
);
2771 json_object_int_add(
2772 json_row
, "routePreference",
2773 rpf
->source_nexthop
.mrib_metric_preference
);
2774 json_object_object_add(json_group
, src_str
, json_row
);
2777 vty_out(vty
, "%-15s %-15s %-16s %-15s %-15s %6d %4d\n",
2778 src_str
, grp_str
, rpf_ifname
, rpf_addr_str
,
2780 rpf
->source_nexthop
.mrib_route_metric
,
2781 rpf
->source_nexthop
.mrib_metric_preference
);
2786 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2787 json
, JSON_C_TO_STRING_PRETTY
));
2788 json_object_free(json
);
2792 struct pnc_cache_walk_data
{
2794 struct pim_instance
*pim
;
2797 static int pim_print_pnc_cache_walkcb(struct hash_bucket
*bucket
, void *arg
)
2799 struct pim_nexthop_cache
*pnc
= bucket
->data
;
2800 struct pnc_cache_walk_data
*cwd
= arg
;
2801 struct vty
*vty
= cwd
->vty
;
2802 struct pim_instance
*pim
= cwd
->pim
;
2803 struct nexthop
*nh_node
= NULL
;
2804 ifindex_t first_ifindex
;
2805 struct interface
*ifp
= NULL
;
2807 for (nh_node
= pnc
->nexthop
; nh_node
; nh_node
= nh_node
->next
) {
2808 first_ifindex
= nh_node
->ifindex
;
2809 ifp
= if_lookup_by_index(first_ifindex
, pim
->vrf_id
);
2811 vty_out(vty
, "%-15s ", inet_ntoa(pnc
->rpf
.rpf_addr
.u
.prefix4
));
2812 vty_out(vty
, "%-16s ", ifp
? ifp
->name
: "NULL");
2813 vty_out(vty
, "%s ", inet_ntoa(nh_node
->gate
.ipv4
));
2819 static void pim_show_nexthop(struct pim_instance
*pim
, struct vty
*vty
)
2821 struct pnc_cache_walk_data cwd
;
2825 vty_out(vty
, "Number of registered addresses: %lu\n",
2826 pim
->rpf_hash
->count
);
2827 vty_out(vty
, "Address Interface Nexthop\n");
2828 vty_out(vty
, "---------------------------------------------\n");
2830 hash_walk(pim
->rpf_hash
, pim_print_pnc_cache_walkcb
, &cwd
);
2833 static void igmp_show_groups(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
2835 struct interface
*ifp
;
2837 json_object
*json
= NULL
;
2838 json_object
*json_iface
= NULL
;
2839 json_object
*json_row
= NULL
;
2841 now
= pim_time_monotonic_sec();
2844 json
= json_object_new_object();
2847 "Interface Address Group Mode Timer Srcs V Uptime \n");
2849 /* scan interfaces */
2850 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2851 struct pim_interface
*pim_ifp
= ifp
->info
;
2852 struct listnode
*sock_node
;
2853 struct igmp_sock
*igmp
;
2858 /* scan igmp sockets */
2859 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
2861 char ifaddr_str
[INET_ADDRSTRLEN
];
2862 struct listnode
*grpnode
;
2863 struct igmp_group
*grp
;
2865 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
2866 sizeof(ifaddr_str
));
2868 /* scan igmp groups */
2869 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
2871 char group_str
[INET_ADDRSTRLEN
];
2875 pim_inet4_dump("<group?>", grp
->group_addr
,
2876 group_str
, sizeof(group_str
));
2877 pim_time_timer_to_hhmmss(hhmmss
, sizeof(hhmmss
),
2878 grp
->t_group_timer
);
2879 pim_time_uptime(uptime
, sizeof(uptime
),
2880 now
- grp
->group_creation
);
2883 json_object_object_get_ex(
2884 json
, ifp
->name
, &json_iface
);
2888 json_object_new_object();
2889 json_object_pim_ifp_add(
2891 json_object_object_add(
2896 json_row
= json_object_new_object();
2897 json_object_string_add(
2898 json_row
, "source", ifaddr_str
);
2899 json_object_string_add(
2900 json_row
, "group", group_str
);
2902 if (grp
->igmp_version
== 3)
2903 json_object_string_add(
2905 grp
->group_filtermode_isexcl
2909 json_object_string_add(json_row
,
2911 json_object_int_add(
2912 json_row
, "sourcesCount",
2913 grp
->group_source_list
2915 grp
->group_source_list
)
2917 json_object_int_add(json_row
, "version",
2919 json_object_string_add(
2920 json_row
, "uptime", uptime
);
2921 json_object_object_add(json_iface
,
2927 "%-16s %-15s %-15s %4s %8s %4d %d %8s\n",
2928 ifp
->name
, ifaddr_str
,
2930 grp
->igmp_version
== 3
2931 ? (grp
->group_filtermode_isexcl
2936 grp
->group_source_list
2938 grp
->group_source_list
)
2940 grp
->igmp_version
, uptime
);
2942 } /* scan igmp groups */
2943 } /* scan igmp sockets */
2944 } /* scan interfaces */
2947 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2948 json
, JSON_C_TO_STRING_PRETTY
));
2949 json_object_free(json
);
2953 static void igmp_show_group_retransmission(struct pim_instance
*pim
,
2956 struct interface
*ifp
;
2959 "Interface Address Group RetTimer Counter RetSrcs\n");
2961 /* scan interfaces */
2962 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2963 struct pim_interface
*pim_ifp
= ifp
->info
;
2964 struct listnode
*sock_node
;
2965 struct igmp_sock
*igmp
;
2970 /* scan igmp sockets */
2971 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
2973 char ifaddr_str
[INET_ADDRSTRLEN
];
2974 struct listnode
*grpnode
;
2975 struct igmp_group
*grp
;
2977 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
2978 sizeof(ifaddr_str
));
2980 /* scan igmp groups */
2981 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
2983 char group_str
[INET_ADDRSTRLEN
];
2984 char grp_retr_mmss
[10];
2985 struct listnode
*src_node
;
2986 struct igmp_source
*src
;
2987 int grp_retr_sources
= 0;
2989 pim_inet4_dump("<group?>", grp
->group_addr
,
2990 group_str
, sizeof(group_str
));
2991 pim_time_timer_to_mmss(
2992 grp_retr_mmss
, sizeof(grp_retr_mmss
),
2993 grp
->t_group_query_retransmit_timer
);
2996 /* count group sources with retransmission state
2998 for (ALL_LIST_ELEMENTS_RO(
2999 grp
->group_source_list
, src_node
,
3001 if (src
->source_query_retransmit_count
3007 vty_out(vty
, "%-16s %-15s %-15s %-8s %7d %7d\n",
3008 ifp
->name
, ifaddr_str
, group_str
,
3010 grp
->group_specific_query_retransmit_count
,
3013 } /* scan igmp groups */
3014 } /* scan igmp sockets */
3015 } /* scan interfaces */
3018 static void igmp_show_sources(struct pim_instance
*pim
, struct vty
*vty
)
3020 struct interface
*ifp
;
3023 now
= pim_time_monotonic_sec();
3026 "Interface Address Group Source Timer Fwd Uptime \n");
3028 /* scan interfaces */
3029 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3030 struct pim_interface
*pim_ifp
= ifp
->info
;
3031 struct listnode
*sock_node
;
3032 struct igmp_sock
*igmp
;
3037 /* scan igmp sockets */
3038 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3040 char ifaddr_str
[INET_ADDRSTRLEN
];
3041 struct listnode
*grpnode
;
3042 struct igmp_group
*grp
;
3044 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3045 sizeof(ifaddr_str
));
3047 /* scan igmp groups */
3048 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3050 char group_str
[INET_ADDRSTRLEN
];
3051 struct listnode
*srcnode
;
3052 struct igmp_source
*src
;
3054 pim_inet4_dump("<group?>", grp
->group_addr
,
3055 group_str
, sizeof(group_str
));
3057 /* scan group sources */
3058 for (ALL_LIST_ELEMENTS_RO(
3059 grp
->group_source_list
, srcnode
,
3061 char source_str
[INET_ADDRSTRLEN
];
3066 "<source?>", src
->source_addr
,
3067 source_str
, sizeof(source_str
));
3069 pim_time_timer_to_mmss(
3071 src
->t_source_timer
);
3074 uptime
, sizeof(uptime
),
3075 now
- src
->source_creation
);
3078 "%-16s %-15s %-15s %-15s %5s %3s %8s\n",
3079 ifp
->name
, ifaddr_str
,
3080 group_str
, source_str
, mmss
,
3081 IGMP_SOURCE_TEST_FORWARDING(
3087 } /* scan group sources */
3088 } /* scan igmp groups */
3089 } /* scan igmp sockets */
3090 } /* scan interfaces */
3093 static void igmp_show_source_retransmission(struct pim_instance
*pim
,
3096 struct interface
*ifp
;
3099 "Interface Address Group Source Counter\n");
3101 /* scan interfaces */
3102 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3103 struct pim_interface
*pim_ifp
= ifp
->info
;
3104 struct listnode
*sock_node
;
3105 struct igmp_sock
*igmp
;
3110 /* scan igmp sockets */
3111 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3113 char ifaddr_str
[INET_ADDRSTRLEN
];
3114 struct listnode
*grpnode
;
3115 struct igmp_group
*grp
;
3117 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3118 sizeof(ifaddr_str
));
3120 /* scan igmp groups */
3121 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3123 char group_str
[INET_ADDRSTRLEN
];
3124 struct listnode
*srcnode
;
3125 struct igmp_source
*src
;
3127 pim_inet4_dump("<group?>", grp
->group_addr
,
3128 group_str
, sizeof(group_str
));
3130 /* scan group sources */
3131 for (ALL_LIST_ELEMENTS_RO(
3132 grp
->group_source_list
, srcnode
,
3134 char source_str
[INET_ADDRSTRLEN
];
3137 "<source?>", src
->source_addr
,
3138 source_str
, sizeof(source_str
));
3141 "%-16s %-15s %-15s %-15s %7d\n",
3142 ifp
->name
, ifaddr_str
,
3143 group_str
, source_str
,
3144 src
->source_query_retransmit_count
);
3146 } /* scan group sources */
3147 } /* scan igmp groups */
3148 } /* scan igmp sockets */
3149 } /* scan interfaces */
3152 static void clear_igmp_interfaces(struct pim_instance
*pim
)
3154 struct interface
*ifp
;
3156 FOR_ALL_INTERFACES (pim
->vrf
, ifp
)
3157 pim_if_addr_del_all_igmp(ifp
);
3159 FOR_ALL_INTERFACES (pim
->vrf
, ifp
)
3160 pim_if_addr_add_all(ifp
);
3163 static void clear_pim_interfaces(struct pim_instance
*pim
)
3165 struct interface
*ifp
;
3167 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3169 pim_neighbor_delete_all(ifp
, "interface cleared");
3174 static void clear_interfaces(struct pim_instance
*pim
)
3176 clear_igmp_interfaces(pim
);
3177 clear_pim_interfaces(pim
);
3180 #define PIM_GET_PIM_INTERFACE(pim_ifp, ifp) \
3181 pim_ifp = ifp->info; \
3184 "%% Enable PIM and/or IGMP on this interface first\n"); \
3185 return CMD_WARNING_CONFIG_FAILED; \
3188 DEFUN (clear_ip_interfaces
,
3189 clear_ip_interfaces_cmd
,
3190 "clear ip interfaces [vrf NAME]",
3193 "Reset interfaces\n"
3197 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3202 clear_interfaces(vrf
->info
);
3207 DEFUN (clear_ip_igmp_interfaces
,
3208 clear_ip_igmp_interfaces_cmd
,
3209 "clear ip igmp [vrf NAME] interfaces",
3214 "Reset IGMP interfaces\n")
3217 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3222 clear_igmp_interfaces(vrf
->info
);
3227 static void mroute_add_all(struct pim_instance
*pim
)
3229 struct listnode
*node
;
3230 struct channel_oil
*c_oil
;
3232 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
3233 if (pim_mroute_add(c_oil
, __PRETTY_FUNCTION__
)) {
3234 /* just log warning */
3235 char source_str
[INET_ADDRSTRLEN
];
3236 char group_str
[INET_ADDRSTRLEN
];
3237 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
,
3238 source_str
, sizeof(source_str
));
3239 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
,
3240 group_str
, sizeof(group_str
));
3241 zlog_warn("%s %s: (S,G)=(%s,%s) failure writing MFC",
3242 __FILE__
, __PRETTY_FUNCTION__
, source_str
,
3248 static void mroute_del_all(struct pim_instance
*pim
)
3250 struct listnode
*node
;
3251 struct channel_oil
*c_oil
;
3253 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
3254 if (pim_mroute_del(c_oil
, __PRETTY_FUNCTION__
)) {
3255 /* just log warning */
3256 char source_str
[INET_ADDRSTRLEN
];
3257 char group_str
[INET_ADDRSTRLEN
];
3258 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
,
3259 source_str
, sizeof(source_str
));
3260 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
,
3261 group_str
, sizeof(group_str
));
3262 zlog_warn("%s %s: (S,G)=(%s,%s) failure clearing MFC",
3263 __FILE__
, __PRETTY_FUNCTION__
, source_str
,
3269 DEFUN (clear_ip_mroute
,
3270 clear_ip_mroute_cmd
,
3271 "clear ip mroute [vrf NAME]",
3274 "Reset multicast routes\n"
3278 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3283 mroute_del_all(vrf
->info
);
3284 mroute_add_all(vrf
->info
);
3289 DEFUN (clear_ip_pim_interfaces
,
3290 clear_ip_pim_interfaces_cmd
,
3291 "clear ip pim [vrf NAME] interfaces",
3296 "Reset PIM interfaces\n")
3299 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3304 clear_pim_interfaces(vrf
->info
);
3309 DEFUN (clear_ip_pim_interface_traffic
,
3310 clear_ip_pim_interface_traffic_cmd
,
3311 "clear ip pim [vrf NAME] interface traffic",
3314 "PIM clear commands\n"
3316 "Reset PIM interfaces\n"
3317 "Reset Protocol Packet counters\n")
3320 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3321 struct interface
*ifp
= NULL
;
3322 struct pim_interface
*pim_ifp
= NULL
;
3327 FOR_ALL_INTERFACES (vrf
, ifp
) {
3328 pim_ifp
= ifp
->info
;
3333 pim_ifp
->pim_ifstat_hello_recv
= 0;
3334 pim_ifp
->pim_ifstat_hello_sent
= 0;
3335 pim_ifp
->pim_ifstat_join_recv
= 0;
3336 pim_ifp
->pim_ifstat_join_send
= 0;
3337 pim_ifp
->pim_ifstat_prune_recv
= 0;
3338 pim_ifp
->pim_ifstat_prune_send
= 0;
3339 pim_ifp
->pim_ifstat_reg_recv
= 0;
3340 pim_ifp
->pim_ifstat_reg_send
= 0;
3341 pim_ifp
->pim_ifstat_reg_stop_recv
= 0;
3342 pim_ifp
->pim_ifstat_reg_stop_send
= 0;
3343 pim_ifp
->pim_ifstat_assert_recv
= 0;
3344 pim_ifp
->pim_ifstat_assert_send
= 0;
3350 DEFUN (clear_ip_pim_oil
,
3351 clear_ip_pim_oil_cmd
,
3352 "clear ip pim [vrf NAME] oil",
3357 "Rescan PIM OIL (output interface list)\n")
3360 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3365 pim_scan_oil(vrf
->info
);
3370 DEFUN (show_ip_igmp_interface
,
3371 show_ip_igmp_interface_cmd
,
3372 "show ip igmp [vrf NAME] interface [detail|WORD] [json]",
3377 "IGMP interface information\n"
3383 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3384 bool uj
= use_json(argc
, argv
);
3389 if (argv_find(argv
, argc
, "detail", &idx
)
3390 || argv_find(argv
, argc
, "WORD", &idx
))
3391 igmp_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
3393 igmp_show_interfaces(vrf
->info
, vty
, uj
);
3398 DEFUN (show_ip_igmp_interface_vrf_all
,
3399 show_ip_igmp_interface_vrf_all_cmd
,
3400 "show ip igmp vrf all interface [detail|WORD] [json]",
3405 "IGMP interface information\n"
3411 bool uj
= use_json(argc
, argv
);
3417 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3421 vty_out(vty
, " \"%s\": ", vrf
->name
);
3424 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3425 if (argv_find(argv
, argc
, "detail", &idx
)
3426 || argv_find(argv
, argc
, "WORD", &idx
))
3427 igmp_show_interfaces_single(vrf
->info
, vty
,
3428 argv
[idx
]->arg
, uj
);
3430 igmp_show_interfaces(vrf
->info
, vty
, uj
);
3433 vty_out(vty
, "}\n");
3438 DEFUN (show_ip_igmp_join
,
3439 show_ip_igmp_join_cmd
,
3440 "show ip igmp [vrf NAME] join",
3445 "IGMP static join information\n")
3448 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3453 igmp_show_interface_join(vrf
->info
, vty
);
3458 DEFUN (show_ip_igmp_join_vrf_all
,
3459 show_ip_igmp_join_vrf_all_cmd
,
3460 "show ip igmp vrf all join",
3465 "IGMP static join information\n")
3467 bool uj
= use_json(argc
, argv
);
3473 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3477 vty_out(vty
, " \"%s\": ", vrf
->name
);
3480 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3481 igmp_show_interface_join(vrf
->info
, vty
);
3484 vty_out(vty
, "}\n");
3489 DEFUN (show_ip_igmp_groups
,
3490 show_ip_igmp_groups_cmd
,
3491 "show ip igmp [vrf NAME] groups [json]",
3500 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3501 bool uj
= use_json(argc
, argv
);
3506 igmp_show_groups(vrf
->info
, vty
, uj
);
3511 DEFUN (show_ip_igmp_groups_vrf_all
,
3512 show_ip_igmp_groups_vrf_all_cmd
,
3513 "show ip igmp vrf all groups [json]",
3521 bool uj
= use_json(argc
, argv
);
3527 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3531 vty_out(vty
, " \"%s\": ", vrf
->name
);
3534 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3535 igmp_show_groups(vrf
->info
, vty
, uj
);
3538 vty_out(vty
, "}\n");
3543 DEFUN (show_ip_igmp_groups_retransmissions
,
3544 show_ip_igmp_groups_retransmissions_cmd
,
3545 "show ip igmp [vrf NAME] groups retransmissions",
3551 "IGMP group retransmissions\n")
3554 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3559 igmp_show_group_retransmission(vrf
->info
, vty
);
3564 DEFUN (show_ip_igmp_sources
,
3565 show_ip_igmp_sources_cmd
,
3566 "show ip igmp [vrf NAME] sources",
3574 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3579 igmp_show_sources(vrf
->info
, vty
);
3584 DEFUN (show_ip_igmp_sources_retransmissions
,
3585 show_ip_igmp_sources_retransmissions_cmd
,
3586 "show ip igmp [vrf NAME] sources retransmissions",
3592 "IGMP source retransmissions\n")
3595 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3600 igmp_show_source_retransmission(vrf
->info
, vty
);
3605 DEFUN (show_ip_igmp_statistics
,
3606 show_ip_igmp_statistics_cmd
,
3607 "show ip igmp [vrf NAME] statistics [interface WORD] [json]",
3618 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3619 bool uj
= use_json(argc
, argv
);
3624 if (argv_find(argv
, argc
, "WORD", &idx
))
3625 igmp_show_statistics(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
3627 igmp_show_statistics(vrf
->info
, vty
, NULL
, uj
);
3632 DEFUN (show_ip_pim_assert
,
3633 show_ip_pim_assert_cmd
,
3634 "show ip pim [vrf NAME] assert",
3639 "PIM interface assert\n")
3642 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3647 pim_show_assert(vrf
->info
, vty
);
3652 DEFUN (show_ip_pim_assert_internal
,
3653 show_ip_pim_assert_internal_cmd
,
3654 "show ip pim [vrf NAME] assert-internal",
3659 "PIM interface internal assert state\n")
3662 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3667 pim_show_assert_internal(vrf
->info
, vty
);
3672 DEFUN (show_ip_pim_assert_metric
,
3673 show_ip_pim_assert_metric_cmd
,
3674 "show ip pim [vrf NAME] assert-metric",
3679 "PIM interface assert metric\n")
3682 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3687 pim_show_assert_metric(vrf
->info
, vty
);
3692 DEFUN (show_ip_pim_assert_winner_metric
,
3693 show_ip_pim_assert_winner_metric_cmd
,
3694 "show ip pim [vrf NAME] assert-winner-metric",
3699 "PIM interface assert winner metric\n")
3702 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3707 pim_show_assert_winner_metric(vrf
->info
, vty
);
3712 DEFUN (show_ip_pim_interface
,
3713 show_ip_pim_interface_cmd
,
3714 "show ip pim [vrf NAME] interface [detail|WORD] [json]",
3719 "PIM interface information\n"
3725 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3726 bool uj
= use_json(argc
, argv
);
3731 if (argv_find(argv
, argc
, "WORD", &idx
)
3732 || argv_find(argv
, argc
, "detail", &idx
))
3733 pim_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
3735 pim_show_interfaces(vrf
->info
, vty
, uj
);
3740 DEFUN (show_ip_pim_interface_vrf_all
,
3741 show_ip_pim_interface_vrf_all_cmd
,
3742 "show ip pim vrf all interface [detail|WORD] [json]",
3747 "PIM interface information\n"
3753 bool uj
= use_json(argc
, argv
);
3759 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3763 vty_out(vty
, " \"%s\": ", vrf
->name
);
3766 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3767 if (argv_find(argv
, argc
, "WORD", &idx
)
3768 || argv_find(argv
, argc
, "detail", &idx
))
3769 pim_show_interfaces_single(vrf
->info
, vty
,
3770 argv
[idx
]->arg
, uj
);
3772 pim_show_interfaces(vrf
->info
, vty
, uj
);
3775 vty_out(vty
, "}\n");
3780 DEFUN (show_ip_pim_join
,
3781 show_ip_pim_join_cmd
,
3782 "show ip pim [vrf NAME] join [json]",
3787 "PIM interface join information\n"
3791 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3792 bool uj
= use_json(argc
, argv
);
3797 pim_show_join(vrf
->info
, vty
, uj
);
3802 DEFUN (show_ip_pim_join_vrf_all
,
3803 show_ip_pim_join_vrf_all_cmd
,
3804 "show ip pim vrf all join [json]",
3809 "PIM interface join information\n"
3812 bool uj
= use_json(argc
, argv
);
3818 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3822 vty_out(vty
, " \"%s\": ", vrf
->name
);
3825 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3826 pim_show_join(vrf
->info
, vty
, uj
);
3829 vty_out(vty
, "}\n");
3834 DEFUN (show_ip_pim_local_membership
,
3835 show_ip_pim_local_membership_cmd
,
3836 "show ip pim [vrf NAME] local-membership [json]",
3841 "PIM interface local-membership\n"
3845 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3846 bool uj
= use_json(argc
, argv
);
3851 pim_show_membership(vrf
->info
, vty
, uj
);
3856 DEFUN (show_ip_pim_neighbor
,
3857 show_ip_pim_neighbor_cmd
,
3858 "show ip pim [vrf NAME] neighbor [detail|WORD] [json]",
3863 "PIM neighbor information\n"
3865 "Name of interface or neighbor\n"
3869 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3870 bool uj
= use_json(argc
, argv
);
3875 if (argv_find(argv
, argc
, "detail", &idx
)
3876 || argv_find(argv
, argc
, "WORD", &idx
))
3877 pim_show_neighbors_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
3879 pim_show_neighbors(vrf
->info
, vty
, uj
);
3884 DEFUN (show_ip_pim_neighbor_vrf_all
,
3885 show_ip_pim_neighbor_vrf_all_cmd
,
3886 "show ip pim vrf all neighbor [detail|WORD] [json]",
3891 "PIM neighbor information\n"
3893 "Name of interface or neighbor\n"
3897 bool uj
= use_json(argc
, argv
);
3903 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3907 vty_out(vty
, " \"%s\": ", vrf
->name
);
3910 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3911 if (argv_find(argv
, argc
, "detail", &idx
)
3912 || argv_find(argv
, argc
, "WORD", &idx
))
3913 pim_show_neighbors_single(vrf
->info
, vty
,
3914 argv
[idx
]->arg
, uj
);
3916 pim_show_neighbors(vrf
->info
, vty
, uj
);
3919 vty_out(vty
, "}\n");
3924 DEFUN (show_ip_pim_secondary
,
3925 show_ip_pim_secondary_cmd
,
3926 "show ip pim [vrf NAME] secondary",
3931 "PIM neighbor addresses\n")
3934 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3939 pim_show_neighbors_secondary(vrf
->info
, vty
);
3944 DEFUN (show_ip_pim_state
,
3945 show_ip_pim_state_cmd
,
3946 "show ip pim [vrf NAME] state [A.B.C.D [A.B.C.D]] [json]",
3951 "PIM state information\n"
3952 "Unicast or Multicast address\n"
3953 "Multicast address\n"
3956 const char *src_or_group
= NULL
;
3957 const char *group
= NULL
;
3959 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3960 bool uj
= use_json(argc
, argv
);
3968 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
3969 src_or_group
= argv
[idx
]->arg
;
3971 group
= argv
[idx
+ 1]->arg
;
3974 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
3979 DEFUN (show_ip_pim_state_vrf_all
,
3980 show_ip_pim_state_vrf_all_cmd
,
3981 "show ip pim vrf all state [A.B.C.D [A.B.C.D]] [json]",
3986 "PIM state information\n"
3987 "Unicast or Multicast address\n"
3988 "Multicast address\n"
3991 const char *src_or_group
= NULL
;
3992 const char *group
= NULL
;
3994 bool uj
= use_json(argc
, argv
);
4003 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
4004 src_or_group
= argv
[idx
]->arg
;
4006 group
= argv
[idx
+ 1]->arg
;
4009 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4013 vty_out(vty
, " \"%s\": ", vrf
->name
);
4016 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4017 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
4020 vty_out(vty
, "}\n");
4025 DEFUN (show_ip_pim_upstream
,
4026 show_ip_pim_upstream_cmd
,
4027 "show ip pim [vrf NAME] upstream [json]",
4032 "PIM upstream information\n"
4036 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4037 bool uj
= use_json(argc
, argv
);
4042 pim_show_upstream(vrf
->info
, vty
, uj
);
4047 DEFUN (show_ip_pim_upstream_vrf_all
,
4048 show_ip_pim_upstream_vrf_all_cmd
,
4049 "show ip pim vrf all upstream [json]",
4054 "PIM upstream information\n"
4057 bool uj
= use_json(argc
, argv
);
4063 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4067 vty_out(vty
, " \"%s\": ", vrf
->name
);
4070 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4071 pim_show_upstream(vrf
->info
, vty
, uj
);
4077 DEFUN (show_ip_pim_upstream_join_desired
,
4078 show_ip_pim_upstream_join_desired_cmd
,
4079 "show ip pim [vrf NAME] upstream-join-desired [json]",
4084 "PIM upstream join-desired\n"
4088 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4089 bool uj
= use_json(argc
, argv
);
4094 pim_show_join_desired(vrf
->info
, vty
, uj
);
4099 DEFUN (show_ip_pim_upstream_rpf
,
4100 show_ip_pim_upstream_rpf_cmd
,
4101 "show ip pim [vrf NAME] upstream-rpf [json]",
4106 "PIM upstream source rpf\n"
4110 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4111 bool uj
= use_json(argc
, argv
);
4116 pim_show_upstream_rpf(vrf
->info
, vty
, uj
);
4121 DEFUN (show_ip_pim_rp
,
4123 "show ip pim [vrf NAME] rp-info [json]",
4128 "PIM RP information\n"
4132 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4133 bool uj
= use_json(argc
, argv
);
4138 pim_rp_show_information(vrf
->info
, vty
, uj
);
4143 DEFUN (show_ip_pim_rp_vrf_all
,
4144 show_ip_pim_rp_vrf_all_cmd
,
4145 "show ip pim vrf all rp-info [json]",
4150 "PIM RP information\n"
4153 bool uj
= use_json(argc
, argv
);
4159 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4163 vty_out(vty
, " \"%s\": ", vrf
->name
);
4166 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4167 pim_rp_show_information(vrf
->info
, vty
, uj
);
4170 vty_out(vty
, "}\n");
4175 DEFUN (show_ip_pim_rpf
,
4176 show_ip_pim_rpf_cmd
,
4177 "show ip pim [vrf NAME] rpf [json]",
4182 "PIM cached source rpf information\n"
4186 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4187 bool uj
= use_json(argc
, argv
);
4192 pim_show_rpf(vrf
->info
, vty
, uj
);
4197 DEFUN (show_ip_pim_rpf_vrf_all
,
4198 show_ip_pim_rpf_vrf_all_cmd
,
4199 "show ip pim vrf all rpf [json]",
4204 "PIM cached source rpf information\n"
4207 bool uj
= use_json(argc
, argv
);
4213 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4217 vty_out(vty
, " \"%s\": ", vrf
->name
);
4220 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4221 pim_show_rpf(vrf
->info
, vty
, uj
);
4224 vty_out(vty
, "}\n");
4229 DEFUN (show_ip_pim_nexthop
,
4230 show_ip_pim_nexthop_cmd
,
4231 "show ip pim [vrf NAME] nexthop",
4236 "PIM cached nexthop rpf information\n")
4239 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4244 pim_show_nexthop(vrf
->info
, vty
);
4249 DEFUN (show_ip_pim_nexthop_lookup
,
4250 show_ip_pim_nexthop_lookup_cmd
,
4251 "show ip pim [vrf NAME] nexthop-lookup A.B.C.D A.B.C.D",
4256 "PIM cached nexthop rpf lookup\n"
4257 "Source/RP address\n"
4258 "Multicast Group address\n")
4260 struct pim_nexthop_cache
*pnc
= NULL
;
4261 struct prefix nht_p
;
4263 struct in_addr src_addr
, grp_addr
;
4264 struct in_addr vif_source
;
4265 const char *addr_str
, *addr_str1
;
4267 struct pim_nexthop nexthop
;
4268 char nexthop_addr_str
[PREFIX_STRLEN
];
4269 char grp_str
[PREFIX_STRLEN
];
4271 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4277 argv_find(argv
, argc
, "A.B.C.D", &idx
);
4278 addr_str
= argv
[idx
]->arg
;
4279 result
= inet_pton(AF_INET
, addr_str
, &src_addr
);
4281 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
4282 errno
, safe_strerror(errno
));
4286 if (pim_is_group_224_4(src_addr
)) {
4288 "Invalid argument. Expected Valid Source Address.\n");
4292 addr_str1
= argv
[idx
+ 1]->arg
;
4293 result
= inet_pton(AF_INET
, addr_str1
, &grp_addr
);
4295 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
4296 errno
, safe_strerror(errno
));
4300 if (!pim_is_group_224_4(grp_addr
)) {
4302 "Invalid argument. Expected Valid Multicast Group Address.\n");
4306 if (!pim_rp_set_upstream_addr(vrf
->info
, &vif_source
, src_addr
,
4310 nht_p
.family
= AF_INET
;
4311 nht_p
.prefixlen
= IPV4_MAX_BITLEN
;
4312 nht_p
.u
.prefix4
= vif_source
;
4313 grp
.family
= AF_INET
;
4314 grp
.prefixlen
= IPV4_MAX_BITLEN
;
4315 grp
.u
.prefix4
= grp_addr
;
4316 memset(&nexthop
, 0, sizeof(nexthop
));
4318 memset(&rpf
, 0, sizeof(struct pim_rpf
));
4319 rpf
.rpf_addr
.family
= AF_INET
;
4320 rpf
.rpf_addr
.prefixlen
= IPV4_MAX_BITLEN
;
4321 rpf
.rpf_addr
.u
.prefix4
= vif_source
;
4323 pnc
= pim_nexthop_cache_find(vrf
->info
, &rpf
);
4325 result
= pim_ecmp_nexthop_search(vrf
->info
, pnc
, &nexthop
,
4328 result
= pim_ecmp_nexthop_lookup(vrf
->info
, &nexthop
, &nht_p
,
4333 "Nexthop Lookup failed, no usable routes returned.\n");
4337 pim_addr_dump("<grp?>", &grp
, grp_str
, sizeof(grp_str
));
4338 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
4339 nexthop_addr_str
, sizeof(nexthop_addr_str
));
4340 vty_out(vty
, "Group %s --- Nexthop %s Interface %s \n", grp_str
,
4341 nexthop_addr_str
, nexthop
.interface
->name
);
4346 DEFUN (show_ip_pim_interface_traffic
,
4347 show_ip_pim_interface_traffic_cmd
,
4348 "show ip pim [vrf NAME] interface traffic [WORD] [json]",
4353 "PIM interface information\n"
4354 "Protocol Packet counters\n"
4359 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4360 bool uj
= use_json(argc
, argv
);
4365 if (argv_find(argv
, argc
, "WORD", &idx
))
4366 pim_show_interface_traffic_single(vrf
->info
, vty
,
4367 argv
[idx
]->arg
, uj
);
4369 pim_show_interface_traffic(vrf
->info
, vty
, uj
);
4374 static void show_multicast_interfaces(struct pim_instance
*pim
, struct vty
*vty
)
4376 struct interface
*ifp
;
4381 "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut\n");
4383 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
4384 struct pim_interface
*pim_ifp
;
4385 struct in_addr ifaddr
;
4386 struct sioc_vif_req vreq
;
4388 pim_ifp
= ifp
->info
;
4393 memset(&vreq
, 0, sizeof(vreq
));
4394 vreq
.vifi
= pim_ifp
->mroute_vif_index
;
4396 if (ioctl(pim
->mroute_socket
, SIOCGETVIFCNT
, &vreq
)) {
4398 "ioctl(SIOCGETVIFCNT=%lu) failure for interface %s vif_index=%d: errno=%d: %s",
4399 (unsigned long)SIOCGETVIFCNT
, ifp
->name
,
4400 pim_ifp
->mroute_vif_index
, errno
,
4401 safe_strerror(errno
));
4404 ifaddr
= pim_ifp
->primary_address
;
4406 vty_out(vty
, "%-16s %-15s %3d %3d %7lu %7lu %10lu %10lu\n",
4407 ifp
->name
, inet_ntoa(ifaddr
), ifp
->ifindex
,
4408 pim_ifp
->mroute_vif_index
, (unsigned long)vreq
.icount
,
4409 (unsigned long)vreq
.ocount
, (unsigned long)vreq
.ibytes
,
4410 (unsigned long)vreq
.obytes
);
4414 static void pim_cmd_show_ip_multicast_helper(struct pim_instance
*pim
,
4417 struct vrf
*vrf
= pim
->vrf
;
4418 time_t now
= pim_time_monotonic_sec();
4424 vty_out(vty
, "Router MLAG Role: %s\n",
4425 mlag_role2str(router
->role
, mlag_role
, sizeof(mlag_role
)));
4426 vty_out(vty
, "Mroute socket descriptor:");
4428 vty_out(vty
, " %d(%s)\n", pim
->mroute_socket
, vrf
->name
);
4430 pim_time_uptime(uptime
, sizeof(uptime
),
4431 now
- pim
->mroute_socket_creation
);
4432 vty_out(vty
, "Mroute socket uptime: %s\n", uptime
);
4436 pim_zebra_zclient_update(vty
);
4437 pim_zlookup_show_ip_multicast(vty
);
4440 vty_out(vty
, "Maximum highest VifIndex: %d\n", PIM_MAX_USABLE_VIFS
);
4443 vty_out(vty
, "Upstream Join Timer: %d secs\n", router
->t_periodic
);
4444 vty_out(vty
, "Join/Prune Holdtime: %d secs\n", PIM_JP_HOLDTIME
);
4445 vty_out(vty
, "PIM ECMP: %s\n", pim
->ecmp_enable
? "Enable" : "Disable");
4446 vty_out(vty
, "PIM ECMP Rebalance: %s\n",
4447 pim
->ecmp_rebalance_enable
? "Enable" : "Disable");
4451 show_rpf_refresh_stats(vty
, pim
, now
, NULL
);
4455 show_scan_oil_stats(pim
, vty
, now
);
4457 show_multicast_interfaces(pim
, vty
);
4460 DEFUN (show_ip_multicast
,
4461 show_ip_multicast_cmd
,
4462 "show ip multicast [vrf NAME]",
4466 "Multicast global information\n")
4469 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4474 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
4479 DEFUN (show_ip_multicast_vrf_all
,
4480 show_ip_multicast_vrf_all_cmd
,
4481 "show ip multicast vrf all",
4485 "Multicast global information\n")
4487 bool uj
= use_json(argc
, argv
);
4493 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4497 vty_out(vty
, " \"%s\": ", vrf
->name
);
4500 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4501 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
4504 vty_out(vty
, "}\n");
4509 static void show_mroute(struct pim_instance
*pim
, struct vty
*vty
, bool fill
,
4512 struct listnode
*node
;
4513 struct channel_oil
*c_oil
;
4514 struct static_route
*s_route
;
4516 json_object
*json
= NULL
;
4517 json_object
*json_group
= NULL
;
4518 json_object
*json_source
= NULL
;
4519 json_object
*json_oil
= NULL
;
4520 json_object
*json_ifp_out
= NULL
;
4523 char grp_str
[INET_ADDRSTRLEN
];
4524 char src_str
[INET_ADDRSTRLEN
];
4525 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
4526 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
4528 struct interface
*ifp_in
;
4532 json
= json_object_new_object();
4535 "Source Group Proto Input Output TTL Uptime\n");
4538 now
= pim_time_monotonic_sec();
4540 /* print list of PIM and IGMP routes */
4541 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
4544 if (!c_oil
->installed
&& !uj
)
4547 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
4549 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
4551 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
4554 strcpy(in_ifname
, ifp_in
->name
);
4556 strcpy(in_ifname
, "<iif?>");
4560 /* Find the group, create it if it doesn't exist */
4561 json_object_object_get_ex(json
, grp_str
, &json_group
);
4564 json_group
= json_object_new_object();
4565 json_object_object_add(json
, grp_str
,
4569 /* Find the source nested under the group, create it if
4570 * it doesn't exist */
4571 json_object_object_get_ex(json_group
, src_str
,
4575 json_source
= json_object_new_object();
4576 json_object_object_add(json_group
, src_str
,
4580 /* Find the inbound interface nested under the source,
4581 * create it if it doesn't exist */
4582 json_object_int_add(json_source
, "installed",
4584 json_object_int_add(json_source
, "refCount",
4585 c_oil
->oil_ref_count
);
4586 json_object_int_add(json_source
, "oilSize",
4588 json_object_int_add(json_source
, "OilInheritedRescan",
4589 c_oil
->oil_inherited_rescan
);
4590 json_object_string_add(json_source
, "iif", in_ifname
);
4594 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
4596 struct interface
*ifp_out
;
4597 char mroute_uptime
[10];
4600 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
4604 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
4606 mroute_uptime
, sizeof(mroute_uptime
),
4607 now
- c_oil
->mroute_creation
);
4611 strcpy(out_ifname
, ifp_out
->name
);
4613 strcpy(out_ifname
, "<oif?>");
4616 json_ifp_out
= json_object_new_object();
4617 json_object_string_add(json_ifp_out
, "source",
4619 json_object_string_add(json_ifp_out
, "group",
4622 if (c_oil
->oif_flags
[oif_vif_index
]
4623 & PIM_OIF_FLAG_PROTO_PIM
)
4624 json_object_boolean_true_add(
4625 json_ifp_out
, "protocolPim");
4627 if (c_oil
->oif_flags
[oif_vif_index
]
4628 & PIM_OIF_FLAG_PROTO_IGMP
)
4629 json_object_boolean_true_add(
4630 json_ifp_out
, "protocolIgmp");
4632 if (c_oil
->oif_flags
[oif_vif_index
]
4633 & PIM_OIF_FLAG_PROTO_SOURCE
)
4634 json_object_boolean_true_add(
4635 json_ifp_out
, "protocolSource");
4637 if (c_oil
->oif_flags
[oif_vif_index
]
4638 & PIM_OIF_FLAG_PROTO_STAR
)
4639 json_object_boolean_true_add(
4641 "protocolInherited");
4643 json_object_string_add(json_ifp_out
,
4646 json_object_int_add(json_ifp_out
, "iVifI",
4647 c_oil
->oil
.mfcc_parent
);
4648 json_object_string_add(json_ifp_out
,
4649 "outboundInterface",
4651 json_object_int_add(json_ifp_out
, "oVifI",
4653 json_object_int_add(json_ifp_out
, "ttl", ttl
);
4654 json_object_string_add(json_ifp_out
, "upTime",
4657 json_oil
= json_object_new_object();
4658 json_object_object_add(json_source
,
4661 json_object_object_add(json_oil
, out_ifname
,
4664 if (c_oil
->oif_flags
[oif_vif_index
]
4665 & PIM_OIF_FLAG_PROTO_PIM
) {
4666 strcpy(proto
, "PIM");
4669 if (c_oil
->oif_flags
[oif_vif_index
]
4670 & PIM_OIF_FLAG_PROTO_IGMP
) {
4671 strcpy(proto
, "IGMP");
4674 if (c_oil
->oif_flags
[oif_vif_index
]
4675 & PIM_OIF_FLAG_PROTO_SOURCE
) {
4676 strcpy(proto
, "SRC");
4679 if (c_oil
->oif_flags
[oif_vif_index
]
4680 & PIM_OIF_FLAG_PROTO_STAR
) {
4681 strcpy(proto
, "STAR");
4685 "%-15s %-15s %-6s %-16s %-16s %-3d %8s\n",
4686 src_str
, grp_str
, proto
, in_ifname
,
4687 out_ifname
, ttl
, mroute_uptime
);
4692 in_ifname
[0] = '\0';
4698 if (!uj
&& !found_oif
) {
4699 vty_out(vty
, "%-15s %-15s %-6s %-16s %-16s %-3d %8s\n",
4700 src_str
, grp_str
, "none", in_ifname
, "none", 0,
4705 /* Print list of static routes */
4706 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
4709 if (!s_route
->c_oil
.installed
)
4712 pim_inet4_dump("<group?>", s_route
->group
, grp_str
,
4714 pim_inet4_dump("<source?>", s_route
->source
, src_str
,
4716 ifp_in
= pim_if_find_by_vif_index(pim
, s_route
->iif
);
4720 strcpy(in_ifname
, ifp_in
->name
);
4722 strcpy(in_ifname
, "<iif?>");
4726 /* Find the group, create it if it doesn't exist */
4727 json_object_object_get_ex(json
, grp_str
, &json_group
);
4730 json_group
= json_object_new_object();
4731 json_object_object_add(json
, grp_str
,
4735 /* Find the source nested under the group, create it if
4736 * it doesn't exist */
4737 json_object_object_get_ex(json_group
, src_str
,
4741 json_source
= json_object_new_object();
4742 json_object_object_add(json_group
, src_str
,
4746 json_object_string_add(json_source
, "iif", in_ifname
);
4749 strcpy(proto
, "STATIC");
4752 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
4754 struct interface
*ifp_out
;
4755 char oif_uptime
[10];
4758 ttl
= s_route
->oif_ttls
[oif_vif_index
];
4762 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
4764 oif_uptime
, sizeof(oif_uptime
),
4767 .oif_creation
[oif_vif_index
]);
4771 strcpy(out_ifname
, ifp_out
->name
);
4773 strcpy(out_ifname
, "<oif?>");
4776 json_ifp_out
= json_object_new_object();
4777 json_object_string_add(json_ifp_out
, "source",
4779 json_object_string_add(json_ifp_out
, "group",
4781 json_object_boolean_true_add(json_ifp_out
,
4783 json_object_string_add(json_ifp_out
,
4786 json_object_int_add(
4787 json_ifp_out
, "iVifI",
4788 s_route
->c_oil
.oil
.mfcc_parent
);
4789 json_object_string_add(json_ifp_out
,
4790 "outboundInterface",
4792 json_object_int_add(json_ifp_out
, "oVifI",
4794 json_object_int_add(json_ifp_out
, "ttl", ttl
);
4795 json_object_string_add(json_ifp_out
, "upTime",
4798 json_oil
= json_object_new_object();
4799 json_object_object_add(json_source
,
4802 json_object_object_add(json_oil
, out_ifname
,
4806 "%-15s %-15s %-6s %-16s %-16s %-3d %8s %s\n",
4807 src_str
, grp_str
, proto
, in_ifname
,
4808 out_ifname
, ttl
, oif_uptime
,
4810 if (first
&& !fill
) {
4813 in_ifname
[0] = '\0';
4819 if (!uj
&& !found_oif
) {
4821 "%-15s %-15s %-6s %-16s %-16s %-3d %8s %s\n",
4822 src_str
, grp_str
, proto
, in_ifname
, "none", 0,
4823 "--:--:--", pim
->vrf
->name
);
4828 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4829 json
, JSON_C_TO_STRING_PRETTY
));
4830 json_object_free(json
);
4834 DEFUN (show_ip_mroute
,
4836 "show ip mroute [vrf NAME] [fill] [json]",
4841 "Fill in Assumed data\n"
4844 bool uj
= use_json(argc
, argv
);
4847 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4852 if (argv_find(argv
, argc
, "fill", &idx
))
4855 show_mroute(vrf
->info
, vty
, fill
, uj
);
4859 DEFUN (show_ip_mroute_vrf_all
,
4860 show_ip_mroute_vrf_all_cmd
,
4861 "show ip mroute vrf all [fill] [json]",
4866 "Fill in Assumed data\n"
4869 bool uj
= use_json(argc
, argv
);
4875 if (argv_find(argv
, argc
, "fill", &idx
))
4880 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4884 vty_out(vty
, " \"%s\": ", vrf
->name
);
4887 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4888 show_mroute(vrf
->info
, vty
, fill
, uj
);
4891 vty_out(vty
, "}\n");
4896 static void show_mroute_count(struct pim_instance
*pim
, struct vty
*vty
)
4898 struct listnode
*node
;
4899 struct channel_oil
*c_oil
;
4900 struct static_route
*s_route
;
4905 "Source Group LastUsed Packets Bytes WrongIf \n");
4907 /* Print PIM and IGMP route counts */
4908 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
4909 char group_str
[INET_ADDRSTRLEN
];
4910 char source_str
[INET_ADDRSTRLEN
];
4912 if (!c_oil
->installed
)
4915 pim_mroute_update_counters(c_oil
);
4917 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, group_str
,
4919 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, source_str
,
4920 sizeof(source_str
));
4922 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
4923 source_str
, group_str
, c_oil
->cc
.lastused
/ 100,
4924 c_oil
->cc
.pktcnt
, c_oil
->cc
.bytecnt
,
4925 c_oil
->cc
.wrong_if
);
4928 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
4929 char group_str
[INET_ADDRSTRLEN
];
4930 char source_str
[INET_ADDRSTRLEN
];
4932 if (!s_route
->c_oil
.installed
)
4935 pim_mroute_update_counters(&s_route
->c_oil
);
4937 pim_inet4_dump("<group?>", s_route
->c_oil
.oil
.mfcc_mcastgrp
,
4938 group_str
, sizeof(group_str
));
4939 pim_inet4_dump("<source?>", s_route
->c_oil
.oil
.mfcc_origin
,
4940 source_str
, sizeof(source_str
));
4942 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
4943 source_str
, group_str
, s_route
->c_oil
.cc
.lastused
,
4944 s_route
->c_oil
.cc
.pktcnt
, s_route
->c_oil
.cc
.bytecnt
,
4945 s_route
->c_oil
.cc
.wrong_if
);
4949 DEFUN (show_ip_mroute_count
,
4950 show_ip_mroute_count_cmd
,
4951 "show ip mroute [vrf NAME] count",
4956 "Route and packet count data\n")
4959 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4964 show_mroute_count(vrf
->info
, vty
);
4968 DEFUN (show_ip_mroute_count_vrf_all
,
4969 show_ip_mroute_count_vrf_all_cmd
,
4970 "show ip mroute vrf all count",
4975 "Route and packet count data\n")
4977 bool uj
= use_json(argc
, argv
);
4983 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4987 vty_out(vty
, " \"%s\": ", vrf
->name
);
4990 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4991 show_mroute_count(vrf
->info
, vty
);
4994 vty_out(vty
, "}\n");
5001 "show ip rib [vrf NAME] A.B.C.D",
5006 "Unicast address\n")
5009 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5010 struct in_addr addr
;
5011 const char *addr_str
;
5012 struct pim_nexthop nexthop
;
5013 char nexthop_addr_str
[PREFIX_STRLEN
];
5019 memset(&nexthop
, 0, sizeof(nexthop
));
5020 argv_find(argv
, argc
, "A.B.C.D", &idx
);
5021 addr_str
= argv
[idx
]->arg
;
5022 result
= inet_pton(AF_INET
, addr_str
, &addr
);
5024 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
5025 errno
, safe_strerror(errno
));
5029 if (!pim_nexthop_lookup(vrf
->info
, &nexthop
, addr
, 0)) {
5031 "Failure querying RIB nexthop for unicast address %s\n",
5037 "Address NextHop Interface Metric Preference\n");
5039 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
5040 nexthop_addr_str
, sizeof(nexthop_addr_str
));
5042 vty_out(vty
, "%-15s %-15s %-9s %6d %10d\n", addr_str
, nexthop_addr_str
,
5043 nexthop
.interface
? nexthop
.interface
->name
: "<ifname?>",
5044 nexthop
.mrib_route_metric
, nexthop
.mrib_metric_preference
);
5049 static void show_ssmpingd(struct pim_instance
*pim
, struct vty
*vty
)
5051 struct listnode
*node
;
5052 struct ssmpingd_sock
*ss
;
5056 "Source Socket Address Port Uptime Requests\n");
5058 if (!pim
->ssmpingd_list
)
5061 now
= pim_time_monotonic_sec();
5063 for (ALL_LIST_ELEMENTS_RO(pim
->ssmpingd_list
, node
, ss
)) {
5064 char source_str
[INET_ADDRSTRLEN
];
5066 struct sockaddr_in bind_addr
;
5067 socklen_t len
= sizeof(bind_addr
);
5068 char bind_addr_str
[INET_ADDRSTRLEN
];
5070 pim_inet4_dump("<src?>", ss
->source_addr
, source_str
,
5071 sizeof(source_str
));
5073 if (pim_socket_getsockname(
5074 ss
->sock_fd
, (struct sockaddr
*)&bind_addr
, &len
)) {
5076 "%% Failure reading socket name for ssmpingd source %s on fd=%d\n",
5077 source_str
, ss
->sock_fd
);
5080 pim_inet4_dump("<addr?>", bind_addr
.sin_addr
, bind_addr_str
,
5081 sizeof(bind_addr_str
));
5082 pim_time_uptime(ss_uptime
, sizeof(ss_uptime
),
5083 now
- ss
->creation
);
5085 vty_out(vty
, "%-15s %6d %-15s %5d %8s %8lld\n", source_str
,
5086 ss
->sock_fd
, bind_addr_str
, ntohs(bind_addr
.sin_port
),
5087 ss_uptime
, (long long)ss
->requests
);
5091 DEFUN (show_ip_ssmpingd
,
5092 show_ip_ssmpingd_cmd
,
5093 "show ip ssmpingd [vrf NAME]",
5100 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5105 show_ssmpingd(vrf
->info
, vty
);
5109 static int pim_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
5110 const char *rp
, const char *group
,
5115 result
= pim_rp_new(pim
, rp
, group
, plist
);
5117 if (result
== PIM_GROUP_BAD_ADDRESS
) {
5118 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
5119 return CMD_WARNING_CONFIG_FAILED
;
5122 if (result
== PIM_RP_BAD_ADDRESS
) {
5123 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
5124 return CMD_WARNING_CONFIG_FAILED
;
5127 if (result
== PIM_RP_NO_PATH
) {
5128 vty_out(vty
, "%% No Path to RP address specified: %s\n", rp
);
5132 if (result
== PIM_GROUP_OVERLAP
) {
5134 "%% Group range specified cannot exact match another\n");
5135 return CMD_WARNING_CONFIG_FAILED
;
5138 if (result
== PIM_GROUP_PFXLIST_OVERLAP
) {
5140 "%% This group is already covered by a RP prefix-list\n");
5141 return CMD_WARNING_CONFIG_FAILED
;
5144 if (result
== PIM_RP_PFXLIST_IN_USE
) {
5146 "%% The same prefix-list cannot be applied to multiple RPs\n");
5147 return CMD_WARNING_CONFIG_FAILED
;
5150 if (result
== PIM_GROUP_BAD_ADDR_MASK_COMBO
) {
5151 vty_out(vty
, "%% Inconsistent address and mask: %s\n",
5153 return CMD_WARNING_CONFIG_FAILED
;
5159 static int pim_cmd_spt_switchover(struct pim_instance
*pim
,
5160 enum pim_spt_switchover spt
,
5163 pim
->spt
.switchover
= spt
;
5165 switch (pim
->spt
.switchover
) {
5166 case PIM_SPT_IMMEDIATE
:
5167 XFREE(MTYPE_PIM_SPT_PLIST_NAME
, pim
->spt
.plist
);
5169 pim_upstream_add_lhr_star_pimreg(pim
);
5171 case PIM_SPT_INFINITY
:
5172 pim_upstream_remove_lhr_star_pimreg(pim
, plist
);
5174 XFREE(MTYPE_PIM_SPT_PLIST_NAME
, pim
->spt
.plist
);
5178 XSTRDUP(MTYPE_PIM_SPT_PLIST_NAME
, plist
);
5185 DEFUN (ip_pim_spt_switchover_infinity
,
5186 ip_pim_spt_switchover_infinity_cmd
,
5187 "ip pim spt-switchover infinity-and-beyond",
5191 "Never switch to SPT Tree\n")
5193 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5194 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, NULL
);
5197 DEFUN (ip_pim_spt_switchover_infinity_plist
,
5198 ip_pim_spt_switchover_infinity_plist_cmd
,
5199 "ip pim spt-switchover infinity-and-beyond prefix-list WORD",
5203 "Never switch to SPT Tree\n"
5204 "Prefix-List to control which groups to switch\n"
5205 "Prefix-List name\n")
5207 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5208 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, argv
[5]->arg
);
5211 DEFUN (no_ip_pim_spt_switchover_infinity
,
5212 no_ip_pim_spt_switchover_infinity_cmd
,
5213 "no ip pim spt-switchover infinity-and-beyond",
5218 "Never switch to SPT Tree\n")
5220 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5221 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
5224 DEFUN (no_ip_pim_spt_switchover_infinity_plist
,
5225 no_ip_pim_spt_switchover_infinity_plist_cmd
,
5226 "no ip pim spt-switchover infinity-and-beyond prefix-list WORD",
5231 "Never switch to SPT Tree\n"
5232 "Prefix-List to control which groups to switch\n"
5233 "Prefix-List name\n")
5235 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5236 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
5239 DEFUN (ip_pim_joinprune_time
,
5240 ip_pim_joinprune_time_cmd
,
5241 "ip pim join-prune-interval (60-600)",
5243 "pim multicast routing\n"
5244 "Join Prune Send Interval\n"
5247 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5248 router
->t_periodic
= atoi(argv
[3]->arg
);
5252 DEFUN (no_ip_pim_joinprune_time
,
5253 no_ip_pim_joinprune_time_cmd
,
5254 "no ip pim join-prune-interval (60-600)",
5257 "pim multicast routing\n"
5258 "Join Prune Send Interval\n"
5261 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5262 router
->t_periodic
= PIM_DEFAULT_T_PERIODIC
;
5266 DEFUN (ip_pim_register_suppress
,
5267 ip_pim_register_suppress_cmd
,
5268 "ip pim register-suppress-time (5-60000)",
5270 "pim multicast routing\n"
5271 "Register Suppress Timer\n"
5274 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5275 router
->register_suppress_time
= atoi(argv
[3]->arg
);
5279 DEFUN (no_ip_pim_register_suppress
,
5280 no_ip_pim_register_suppress_cmd
,
5281 "no ip pim register-suppress-time (5-60000)",
5284 "pim multicast routing\n"
5285 "Register Suppress Timer\n"
5288 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5289 router
->register_suppress_time
= PIM_REGISTER_SUPPRESSION_TIME_DEFAULT
;
5293 DEFUN (ip_pim_rp_keep_alive
,
5294 ip_pim_rp_keep_alive_cmd
,
5295 "ip pim rp keep-alive-timer (31-60000)",
5297 "pim multicast routing\n"
5299 "Keep alive Timer\n"
5302 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5303 pim
->rp_keep_alive_time
= atoi(argv
[4]->arg
);
5307 DEFUN (no_ip_pim_rp_keep_alive
,
5308 no_ip_pim_rp_keep_alive_cmd
,
5309 "no ip pim rp keep-alive-timer (31-60000)",
5312 "pim multicast routing\n"
5314 "Keep alive Timer\n"
5317 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5318 pim
->rp_keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
5322 DEFUN (ip_pim_keep_alive
,
5323 ip_pim_keep_alive_cmd
,
5324 "ip pim keep-alive-timer (31-60000)",
5326 "pim multicast routing\n"
5327 "Keep alive Timer\n"
5330 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5331 pim
->keep_alive_time
= atoi(argv
[3]->arg
);
5335 DEFUN (no_ip_pim_keep_alive
,
5336 no_ip_pim_keep_alive_cmd
,
5337 "no ip pim keep-alive-timer (31-60000)",
5340 "pim multicast routing\n"
5341 "Keep alive Timer\n"
5344 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5345 pim
->keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
5349 DEFUN (ip_pim_packets
,
5351 "ip pim packets (1-100)",
5353 "pim multicast routing\n"
5354 "packets to process at one time per fd\n"
5355 "Number of packets\n")
5357 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5358 router
->packet_process
= atoi(argv
[3]->arg
);
5362 DEFUN (no_ip_pim_packets
,
5363 no_ip_pim_packets_cmd
,
5364 "no ip pim packets (1-100)",
5367 "pim multicast routing\n"
5368 "packets to process at one time per fd\n"
5369 "Number of packets\n")
5371 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5372 router
->packet_process
= PIM_DEFAULT_PACKET_PROCESS
;
5376 DEFUN (ip_pim_v6_secondary
,
5377 ip_pim_v6_secondary_cmd
,
5378 "ip pim send-v6-secondary",
5380 "pim multicast routing\n"
5381 "Send v6 secondary addresses\n")
5383 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5384 pim
->send_v6_secondary
= 1;
5389 DEFUN (no_ip_pim_v6_secondary
,
5390 no_ip_pim_v6_secondary_cmd
,
5391 "no ip pim send-v6-secondary",
5394 "pim multicast routing\n"
5395 "Send v6 secondary addresses\n")
5397 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5398 pim
->send_v6_secondary
= 0;
5405 "ip pim rp A.B.C.D [A.B.C.D/M]",
5407 "pim multicast routing\n"
5409 "ip address of RP\n"
5410 "Group Address range to cover\n")
5412 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5415 if (argc
== (idx_ipv4
+ 1))
5416 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
5419 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
5420 argv
[idx_ipv4
+ 1]->arg
, NULL
);
5423 DEFUN (ip_pim_rp_prefix_list
,
5424 ip_pim_rp_prefix_list_cmd
,
5425 "ip pim rp A.B.C.D prefix-list WORD",
5427 "pim multicast routing\n"
5429 "ip address of RP\n"
5430 "group prefix-list filter\n"
5431 "Name of a prefix-list\n")
5433 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5434 return pim_rp_cmd_worker(pim
, vty
, argv
[3]->arg
, NULL
, argv
[5]->arg
);
5437 static int pim_no_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
5438 const char *rp
, const char *group
,
5441 int result
= pim_rp_del(pim
, rp
, group
, plist
);
5443 if (result
== PIM_GROUP_BAD_ADDRESS
) {
5444 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
5445 return CMD_WARNING_CONFIG_FAILED
;
5448 if (result
== PIM_RP_BAD_ADDRESS
) {
5449 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
5450 return CMD_WARNING_CONFIG_FAILED
;
5453 if (result
== PIM_RP_NOT_FOUND
) {
5454 vty_out(vty
, "%% Unable to find specified RP\n");
5455 return CMD_WARNING_CONFIG_FAILED
;
5461 DEFUN (no_ip_pim_rp
,
5463 "no ip pim rp A.B.C.D [A.B.C.D/M]",
5466 "pim multicast routing\n"
5468 "ip address of RP\n"
5469 "Group Address range to cover\n")
5471 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5472 int idx_ipv4
= 4, idx_group
= 0;
5474 if (argv_find(argv
, argc
, "A.B.C.D/M", &idx_group
))
5475 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
5476 argv
[idx_group
]->arg
, NULL
);
5478 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
5482 DEFUN (no_ip_pim_rp_prefix_list
,
5483 no_ip_pim_rp_prefix_list_cmd
,
5484 "no ip pim rp A.B.C.D prefix-list WORD",
5487 "pim multicast routing\n"
5489 "ip address of RP\n"
5490 "group prefix-list filter\n"
5491 "Name of a prefix-list\n")
5493 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5494 return pim_no_rp_cmd_worker(pim
, vty
, argv
[4]->arg
, NULL
, argv
[6]->arg
);
5497 static int pim_ssm_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
5500 int result
= pim_ssm_range_set(pim
, pim
->vrf_id
, plist
);
5502 if (result
== PIM_SSM_ERR_NONE
)
5506 case PIM_SSM_ERR_NO_VRF
:
5507 vty_out(vty
, "%% VRF doesn't exist\n");
5509 case PIM_SSM_ERR_DUP
:
5510 vty_out(vty
, "%% duplicate config\n");
5513 vty_out(vty
, "%% ssm range config failed\n");
5516 return CMD_WARNING_CONFIG_FAILED
;
5519 DEFUN (ip_pim_ssm_prefix_list
,
5520 ip_pim_ssm_prefix_list_cmd
,
5521 "ip pim ssm prefix-list WORD",
5523 "pim multicast routing\n"
5524 "Source Specific Multicast\n"
5525 "group range prefix-list filter\n"
5526 "Name of a prefix-list\n")
5528 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5529 return pim_ssm_cmd_worker(pim
, vty
, argv
[4]->arg
);
5532 DEFUN (no_ip_pim_ssm_prefix_list
,
5533 no_ip_pim_ssm_prefix_list_cmd
,
5534 "no ip pim ssm prefix-list",
5537 "pim multicast routing\n"
5538 "Source Specific Multicast\n"
5539 "group range prefix-list filter\n")
5541 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5542 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
5545 DEFUN (no_ip_pim_ssm_prefix_list_name
,
5546 no_ip_pim_ssm_prefix_list_name_cmd
,
5547 "no ip pim ssm prefix-list WORD",
5550 "pim multicast routing\n"
5551 "Source Specific Multicast\n"
5552 "group range prefix-list filter\n"
5553 "Name of a prefix-list\n")
5555 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5556 struct pim_ssm
*ssm
= pim
->ssm_info
;
5558 if (ssm
->plist_name
&& !strcmp(ssm
->plist_name
, argv
[5]->arg
))
5559 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
5561 vty_out(vty
, "%% pim ssm prefix-list %s doesn't exist\n", argv
[5]->arg
);
5563 return CMD_WARNING_CONFIG_FAILED
;
5566 static void ip_pim_ssm_show_group_range(struct pim_instance
*pim
,
5567 struct vty
*vty
, bool uj
)
5569 struct pim_ssm
*ssm
= pim
->ssm_info
;
5570 const char *range_str
=
5571 ssm
->plist_name
? ssm
->plist_name
: PIM_SSM_STANDARD_RANGE
;
5575 json
= json_object_new_object();
5576 json_object_string_add(json
, "ssmGroups", range_str
);
5577 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5578 json
, JSON_C_TO_STRING_PRETTY
));
5579 json_object_free(json
);
5581 vty_out(vty
, "SSM group range : %s\n", range_str
);
5584 DEFUN (show_ip_pim_ssm_range
,
5585 show_ip_pim_ssm_range_cmd
,
5586 "show ip pim [vrf NAME] group-type [json]",
5595 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5596 bool uj
= use_json(argc
, argv
);
5601 ip_pim_ssm_show_group_range(vrf
->info
, vty
, uj
);
5606 static void ip_pim_ssm_show_group_type(struct pim_instance
*pim
,
5607 struct vty
*vty
, bool uj
,
5610 struct in_addr group_addr
;
5611 const char *type_str
;
5614 result
= inet_pton(AF_INET
, group
, &group_addr
);
5616 type_str
= "invalid";
5618 if (pim_is_group_224_4(group_addr
))
5620 pim_is_grp_ssm(pim
, group_addr
) ? "SSM" : "ASM";
5622 type_str
= "not-multicast";
5627 json
= json_object_new_object();
5628 json_object_string_add(json
, "groupType", type_str
);
5629 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5630 json
, JSON_C_TO_STRING_PRETTY
));
5631 json_object_free(json
);
5633 vty_out(vty
, "Group type : %s\n", type_str
);
5636 DEFUN (show_ip_pim_group_type
,
5637 show_ip_pim_group_type_cmd
,
5638 "show ip pim [vrf NAME] group-type A.B.C.D [json]",
5643 "multicast group type\n"
5648 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5649 bool uj
= use_json(argc
, argv
);
5654 argv_find(argv
, argc
, "A.B.C.D", &idx
);
5655 ip_pim_ssm_show_group_type(vrf
->info
, vty
, uj
, argv
[idx
]->arg
);
5662 "ip ssmpingd [A.B.C.D]",
5667 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5670 struct in_addr source_addr
;
5671 const char *source_str
= (argc
== 3) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
5673 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
5675 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
5676 source_str
, errno
, safe_strerror(errno
));
5677 return CMD_WARNING_CONFIG_FAILED
;
5680 result
= pim_ssmpingd_start(pim
, source_addr
);
5682 vty_out(vty
, "%% Failure starting ssmpingd for source %s: %d\n",
5683 source_str
, result
);
5684 return CMD_WARNING_CONFIG_FAILED
;
5690 DEFUN (no_ip_ssmpingd
,
5692 "no ip ssmpingd [A.B.C.D]",
5698 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5701 struct in_addr source_addr
;
5702 const char *source_str
= (argc
== 4) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
5704 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
5706 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
5707 source_str
, errno
, safe_strerror(errno
));
5708 return CMD_WARNING_CONFIG_FAILED
;
5711 result
= pim_ssmpingd_stop(pim
, source_addr
);
5713 vty_out(vty
, "%% Failure stopping ssmpingd for source %s: %d\n",
5714 source_str
, result
);
5715 return CMD_WARNING_CONFIG_FAILED
;
5725 "pim multicast routing\n"
5726 "Enable PIM ECMP \n")
5728 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5729 pim
->ecmp_enable
= true;
5734 DEFUN (no_ip_pim_ecmp
,
5739 "pim multicast routing\n"
5740 "Disable PIM ECMP \n")
5742 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5743 pim
->ecmp_enable
= false;
5748 DEFUN (ip_pim_ecmp_rebalance
,
5749 ip_pim_ecmp_rebalance_cmd
,
5750 "ip pim ecmp rebalance",
5752 "pim multicast routing\n"
5753 "Enable PIM ECMP \n"
5754 "Enable PIM ECMP Rebalance\n")
5756 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5757 pim
->ecmp_enable
= true;
5758 pim
->ecmp_rebalance_enable
= true;
5763 DEFUN (no_ip_pim_ecmp_rebalance
,
5764 no_ip_pim_ecmp_rebalance_cmd
,
5765 "no ip pim ecmp rebalance",
5768 "pim multicast routing\n"
5769 "Disable PIM ECMP \n"
5770 "Disable PIM ECMP Rebalance\n")
5772 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5773 pim
->ecmp_rebalance_enable
= false;
5778 static int pim_cmd_igmp_start(struct vty
*vty
, struct interface
*ifp
)
5780 struct pim_interface
*pim_ifp
;
5781 uint8_t need_startup
= 0;
5783 pim_ifp
= ifp
->info
;
5786 pim_ifp
= pim_if_new(ifp
, true, false, false);
5788 vty_out(vty
, "Could not enable IGMP on interface %s\n",
5790 return CMD_WARNING_CONFIG_FAILED
;
5794 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
5795 PIM_IF_DO_IGMP(pim_ifp
->options
);
5800 /* 'ip igmp' executed multiple times, with need_startup
5801 avoid multiple if add all and membership refresh */
5803 pim_if_addr_add_all(ifp
);
5804 pim_if_membership_refresh(ifp
);
5810 DEFUN (interface_ip_igmp
,
5811 interface_ip_igmp_cmd
,
5816 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5818 return pim_cmd_igmp_start(vty
, ifp
);
5821 DEFUN (interface_no_ip_igmp
,
5822 interface_no_ip_igmp_cmd
,
5828 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5829 struct pim_interface
*pim_ifp
= ifp
->info
;
5834 PIM_IF_DONT_IGMP(pim_ifp
->options
);
5836 pim_if_membership_clear(ifp
);
5838 pim_if_addr_del_all_igmp(ifp
);
5840 if (!PIM_IF_TEST_PIM(pim_ifp
->options
)) {
5847 DEFUN (interface_ip_igmp_join
,
5848 interface_ip_igmp_join_cmd
,
5849 "ip igmp join A.B.C.D A.B.C.D",
5852 "IGMP join multicast group\n"
5853 "Multicast group address\n"
5856 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5859 const char *group_str
;
5860 const char *source_str
;
5861 struct in_addr group_addr
;
5862 struct in_addr source_addr
;
5866 group_str
= argv
[idx_ipv4
]->arg
;
5867 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
5869 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
5870 errno
, safe_strerror(errno
));
5871 return CMD_WARNING_CONFIG_FAILED
;
5874 /* Source address */
5875 source_str
= argv
[idx_ipv4_2
]->arg
;
5876 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
5878 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
5879 source_str
, errno
, safe_strerror(errno
));
5880 return CMD_WARNING_CONFIG_FAILED
;
5883 CMD_FERR_RETURN(pim_if_igmp_join_add(ifp
, group_addr
, source_addr
),
5884 "Failure joining IGMP group: $ERR");
5889 DEFUN (interface_no_ip_igmp_join
,
5890 interface_no_ip_igmp_join_cmd
,
5891 "no ip igmp join A.B.C.D A.B.C.D",
5895 "IGMP join multicast group\n"
5896 "Multicast group address\n"
5899 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5902 const char *group_str
;
5903 const char *source_str
;
5904 struct in_addr group_addr
;
5905 struct in_addr source_addr
;
5909 group_str
= argv
[idx_ipv4
]->arg
;
5910 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
5912 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
5913 errno
, safe_strerror(errno
));
5914 return CMD_WARNING_CONFIG_FAILED
;
5917 /* Source address */
5918 source_str
= argv
[idx_ipv4_2
]->arg
;
5919 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
5921 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
5922 source_str
, errno
, safe_strerror(errno
));
5923 return CMD_WARNING_CONFIG_FAILED
;
5926 result
= pim_if_igmp_join_del(ifp
, group_addr
, source_addr
);
5929 "%% Failure leaving IGMP group %s source %s on interface %s: %d\n",
5930 group_str
, source_str
, ifp
->name
, result
);
5931 return CMD_WARNING_CONFIG_FAILED
;
5938 CLI reconfiguration affects the interface level (struct pim_interface).
5939 This function propagates the reconfiguration to every active socket
5942 static void igmp_sock_query_interval_reconfig(struct igmp_sock
*igmp
)
5944 struct interface
*ifp
;
5945 struct pim_interface
*pim_ifp
;
5949 /* other querier present? */
5951 if (igmp
->t_other_querier_timer
)
5954 /* this is the querier */
5956 zassert(igmp
->interface
);
5957 zassert(igmp
->interface
->info
);
5959 ifp
= igmp
->interface
;
5960 pim_ifp
= ifp
->info
;
5962 if (PIM_DEBUG_IGMP_TRACE
) {
5963 char ifaddr_str
[INET_ADDRSTRLEN
];
5964 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
5965 sizeof(ifaddr_str
));
5966 zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
5967 __PRETTY_FUNCTION__
, ifaddr_str
, ifp
->name
,
5968 pim_ifp
->igmp_default_query_interval
);
5972 igmp_startup_mode_on() will reset QQI:
5974 igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
5976 igmp_startup_mode_on(igmp
);
5979 static void igmp_sock_query_reschedule(struct igmp_sock
*igmp
)
5981 if (igmp
->t_igmp_query_timer
) {
5982 /* other querier present */
5983 zassert(igmp
->t_igmp_query_timer
);
5984 zassert(!igmp
->t_other_querier_timer
);
5986 pim_igmp_general_query_off(igmp
);
5987 pim_igmp_general_query_on(igmp
);
5989 zassert(igmp
->t_igmp_query_timer
);
5990 zassert(!igmp
->t_other_querier_timer
);
5992 /* this is the querier */
5994 zassert(!igmp
->t_igmp_query_timer
);
5995 zassert(igmp
->t_other_querier_timer
);
5997 pim_igmp_other_querier_timer_off(igmp
);
5998 pim_igmp_other_querier_timer_on(igmp
);
6000 zassert(!igmp
->t_igmp_query_timer
);
6001 zassert(igmp
->t_other_querier_timer
);
6005 static void change_query_interval(struct pim_interface
*pim_ifp
,
6008 struct listnode
*sock_node
;
6009 struct igmp_sock
*igmp
;
6011 pim_ifp
->igmp_default_query_interval
= query_interval
;
6013 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
6014 igmp_sock_query_interval_reconfig(igmp
);
6015 igmp_sock_query_reschedule(igmp
);
6019 static void change_query_max_response_time(struct pim_interface
*pim_ifp
,
6020 int query_max_response_time_dsec
)
6022 struct listnode
*sock_node
;
6023 struct igmp_sock
*igmp
;
6025 pim_ifp
->igmp_query_max_response_time_dsec
=
6026 query_max_response_time_dsec
;
6029 Below we modify socket/group/source timers in order to quickly
6030 reflect the change. Otherwise, those timers would eventually catch
6034 /* scan all sockets */
6035 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
6036 struct listnode
*grp_node
;
6037 struct igmp_group
*grp
;
6039 /* reschedule socket general query */
6040 igmp_sock_query_reschedule(igmp
);
6042 /* scan socket groups */
6043 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grp_node
,
6045 struct listnode
*src_node
;
6046 struct igmp_source
*src
;
6048 /* reset group timers for groups in EXCLUDE mode */
6049 if (grp
->group_filtermode_isexcl
) {
6050 igmp_group_reset_gmi(grp
);
6053 /* scan group sources */
6054 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
,
6057 /* reset source timers for sources with running
6059 if (src
->t_source_timer
) {
6060 igmp_source_reset_gmi(igmp
, grp
, src
);
6067 #define IGMP_QUERY_INTERVAL_MIN (1)
6068 #define IGMP_QUERY_INTERVAL_MAX (1800)
6070 DEFUN (interface_ip_igmp_query_interval
,
6071 interface_ip_igmp_query_interval_cmd
,
6072 "ip igmp query-interval (1-1800)",
6075 IFACE_IGMP_QUERY_INTERVAL_STR
6076 "Query interval in seconds\n")
6078 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6079 struct pim_interface
*pim_ifp
= ifp
->info
;
6081 int query_interval_dsec
;
6085 ret
= pim_cmd_igmp_start(vty
, ifp
);
6086 if (ret
!= CMD_SUCCESS
)
6088 pim_ifp
= ifp
->info
;
6091 query_interval
= atoi(argv
[3]->arg
);
6092 query_interval_dsec
= 10 * query_interval
;
6095 It seems we don't need to check bounds since command.c does it
6096 already, but we verify them anyway for extra safety.
6098 if (query_interval
< IGMP_QUERY_INTERVAL_MIN
) {
6100 "General query interval %d lower than minimum %d\n",
6101 query_interval
, IGMP_QUERY_INTERVAL_MIN
);
6102 return CMD_WARNING_CONFIG_FAILED
;
6104 if (query_interval
> IGMP_QUERY_INTERVAL_MAX
) {
6106 "General query interval %d higher than maximum %d\n",
6107 query_interval
, IGMP_QUERY_INTERVAL_MAX
);
6108 return CMD_WARNING_CONFIG_FAILED
;
6111 if (query_interval_dsec
<= pim_ifp
->igmp_query_max_response_time_dsec
) {
6113 "Can't set general query interval %d dsec <= query max response time %d dsec.\n",
6114 query_interval_dsec
,
6115 pim_ifp
->igmp_query_max_response_time_dsec
);
6116 return CMD_WARNING_CONFIG_FAILED
;
6119 change_query_interval(pim_ifp
, query_interval
);
6124 DEFUN (interface_no_ip_igmp_query_interval
,
6125 interface_no_ip_igmp_query_interval_cmd
,
6126 "no ip igmp query-interval",
6130 IFACE_IGMP_QUERY_INTERVAL_STR
)
6132 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6133 struct pim_interface
*pim_ifp
= ifp
->info
;
6134 int default_query_interval_dsec
;
6139 default_query_interval_dsec
= IGMP_GENERAL_QUERY_INTERVAL
* 10;
6141 if (default_query_interval_dsec
6142 <= pim_ifp
->igmp_query_max_response_time_dsec
) {
6144 "Can't set default general query interval %d dsec <= query max response time %d dsec.\n",
6145 default_query_interval_dsec
,
6146 pim_ifp
->igmp_query_max_response_time_dsec
);
6147 return CMD_WARNING_CONFIG_FAILED
;
6150 change_query_interval(pim_ifp
, IGMP_GENERAL_QUERY_INTERVAL
);
6155 DEFUN (interface_ip_igmp_version
,
6156 interface_ip_igmp_version_cmd
,
6157 "ip igmp version (2-3)",
6161 "IGMP version number\n")
6163 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6164 struct pim_interface
*pim_ifp
= ifp
->info
;
6165 int igmp_version
, old_version
= 0;
6169 ret
= pim_cmd_igmp_start(vty
, ifp
);
6170 if (ret
!= CMD_SUCCESS
)
6172 pim_ifp
= ifp
->info
;
6175 igmp_version
= atoi(argv
[3]->arg
);
6176 old_version
= pim_ifp
->igmp_version
;
6177 pim_ifp
->igmp_version
= igmp_version
;
6179 // Check if IGMP is Enabled otherwise, enable on interface
6180 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
6181 PIM_IF_DO_IGMP(pim_ifp
->options
);
6182 pim_if_addr_add_all(ifp
);
6183 pim_if_membership_refresh(ifp
);
6184 old_version
= igmp_version
;
6185 // avoid refreshing membership again.
6187 /* Current and new version is different refresh existing
6188 membership. Going from 3 -> 2 or 2 -> 3. */
6189 if (old_version
!= igmp_version
)
6190 pim_if_membership_refresh(ifp
);
6195 DEFUN (interface_no_ip_igmp_version
,
6196 interface_no_ip_igmp_version_cmd
,
6197 "no ip igmp version (2-3)",
6202 "IGMP version number\n")
6204 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6205 struct pim_interface
*pim_ifp
= ifp
->info
;
6210 pim_ifp
->igmp_version
= IGMP_DEFAULT_VERSION
;
6215 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
6216 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
6218 DEFUN (interface_ip_igmp_query_max_response_time
,
6219 interface_ip_igmp_query_max_response_time_cmd
,
6220 "ip igmp query-max-response-time (10-250)",
6223 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
6224 "Query response value in deci-seconds\n")
6226 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6227 struct pim_interface
*pim_ifp
= ifp
->info
;
6228 int query_max_response_time
;
6232 ret
= pim_cmd_igmp_start(vty
, ifp
);
6233 if (ret
!= CMD_SUCCESS
)
6235 pim_ifp
= ifp
->info
;
6238 query_max_response_time
= atoi(argv
[3]->arg
);
6240 if (query_max_response_time
6241 >= pim_ifp
->igmp_default_query_interval
* 10) {
6243 "Can't set query max response time %d sec >= general query interval %d sec\n",
6244 query_max_response_time
,
6245 pim_ifp
->igmp_default_query_interval
);
6246 return CMD_WARNING_CONFIG_FAILED
;
6249 change_query_max_response_time(pim_ifp
, query_max_response_time
);
6254 DEFUN (interface_no_ip_igmp_query_max_response_time
,
6255 interface_no_ip_igmp_query_max_response_time_cmd
,
6256 "no ip igmp query-max-response-time (10-250)",
6260 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
6261 "Time for response in deci-seconds\n")
6263 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6264 struct pim_interface
*pim_ifp
= ifp
->info
;
6269 change_query_max_response_time(pim_ifp
,
6270 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
6275 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
6276 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
6278 DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec
,
6279 interface_ip_igmp_query_max_response_time_dsec_cmd
,
6280 "ip igmp query-max-response-time-dsec (10-250)",
6283 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
6284 "Query response value in deciseconds\n")
6286 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6287 struct pim_interface
*pim_ifp
= ifp
->info
;
6288 int query_max_response_time_dsec
;
6289 int default_query_interval_dsec
;
6293 ret
= pim_cmd_igmp_start(vty
, ifp
);
6294 if (ret
!= CMD_SUCCESS
)
6296 pim_ifp
= ifp
->info
;
6299 query_max_response_time_dsec
= atoi(argv
[4]->arg
);
6301 default_query_interval_dsec
= 10 * pim_ifp
->igmp_default_query_interval
;
6303 if (query_max_response_time_dsec
>= default_query_interval_dsec
) {
6305 "Can't set query max response time %d dsec >= general query interval %d dsec\n",
6306 query_max_response_time_dsec
,
6307 default_query_interval_dsec
);
6308 return CMD_WARNING_CONFIG_FAILED
;
6311 change_query_max_response_time(pim_ifp
, query_max_response_time_dsec
);
6316 DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec
,
6317 interface_no_ip_igmp_query_max_response_time_dsec_cmd
,
6318 "no ip igmp query-max-response-time-dsec",
6322 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
)
6324 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6325 struct pim_interface
*pim_ifp
= ifp
->info
;
6330 change_query_max_response_time(pim_ifp
,
6331 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
6336 DEFUN (interface_ip_pim_drprio
,
6337 interface_ip_pim_drprio_cmd
,
6338 "ip pim drpriority (1-4294967295)",
6341 "Set the Designated Router Election Priority\n"
6342 "Value of the new DR Priority\n")
6344 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6346 struct pim_interface
*pim_ifp
= ifp
->info
;
6347 uint32_t old_dr_prio
;
6350 vty_out(vty
, "Please enable PIM on interface, first\n");
6351 return CMD_WARNING_CONFIG_FAILED
;
6354 old_dr_prio
= pim_ifp
->pim_dr_priority
;
6356 pim_ifp
->pim_dr_priority
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
6358 if (old_dr_prio
!= pim_ifp
->pim_dr_priority
) {
6359 pim_if_dr_election(ifp
);
6360 pim_hello_restart_now(ifp
);
6366 DEFUN (interface_no_ip_pim_drprio
,
6367 interface_no_ip_pim_drprio_cmd
,
6368 "no ip pim drpriority [(1-4294967295)]",
6372 "Revert the Designated Router Priority to default\n"
6373 "Old Value of the Priority\n")
6375 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6376 struct pim_interface
*pim_ifp
= ifp
->info
;
6379 vty_out(vty
, "Pim not enabled on this interface\n");
6380 return CMD_WARNING_CONFIG_FAILED
;
6383 if (pim_ifp
->pim_dr_priority
!= PIM_DEFAULT_DR_PRIORITY
) {
6384 pim_ifp
->pim_dr_priority
= PIM_DEFAULT_DR_PRIORITY
;
6385 pim_if_dr_election(ifp
);
6386 pim_hello_restart_now(ifp
);
6392 static int pim_cmd_interface_add(struct interface
*ifp
)
6394 struct pim_interface
*pim_ifp
= ifp
->info
;
6397 pim_ifp
= pim_if_new(ifp
, false, true, false);
6402 PIM_IF_DO_PIM(pim_ifp
->options
);
6405 pim_if_addr_add_all(ifp
);
6406 pim_if_membership_refresh(ifp
);
6410 DEFPY_HIDDEN (pim_test_sg_keepalive
,
6411 pim_test_sg_keepalive_cmd
,
6412 "test pim [vrf NAME$name] keepalive-reset A.B.C.D$source A.B.C.D$group",
6416 "Reset the Keepalive Timer\n"
6417 "The Source we are resetting\n"
6418 "The Group we are resetting\n")
6420 struct pim_upstream
*up
;
6421 struct pim_instance
*pim
;
6422 struct prefix_sg sg
;
6428 pim
= pim_get_pim_instance(VRF_DEFAULT
);
6430 struct vrf
*vrf
= vrf_lookup_by_name(name
);
6433 vty_out(vty
, "%% Vrf specified: %s does not exist\n",
6438 pim
= pim_get_pim_instance(vrf
->vrf_id
);
6442 vty_out(vty
, "%% Unable to find pim instance\n");
6446 up
= pim_upstream_find(pim
, &sg
);
6448 vty_out(vty
, "%% Unable to find %s specified\n",
6449 pim_str_sg_dump(&sg
));
6453 vty_out(vty
, "Setting %s to current keep alive time: %d\n",
6454 pim_str_sg_dump(&sg
), pim
->keep_alive_time
);
6455 pim_upstream_keep_alive_timer_start(up
, pim
->keep_alive_time
);
6460 DEFPY_HIDDEN (interface_ip_pim_activeactive
,
6461 interface_ip_pim_activeactive_cmd
,
6462 "[no$no] ip pim active-active",
6466 "Mark interface as Active-Active for MLAG operations, Hidden because not finished yet\n")
6468 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6469 struct pim_interface
*pim_ifp
;
6471 if (!no
&& !pim_cmd_interface_add(ifp
)) {
6472 vty_out(vty
, "Could not enable PIM SM active-active on interface\n");
6473 return CMD_WARNING_CONFIG_FAILED
;
6476 pim_ifp
= ifp
->info
;
6478 pim_ifp
->activeactive
= false;
6480 pim_ifp
->activeactive
= true;
6485 DEFUN_HIDDEN (interface_ip_pim_ssm
,
6486 interface_ip_pim_ssm_cmd
,
6492 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6494 if (!pim_cmd_interface_add(ifp
)) {
6495 vty_out(vty
, "Could not enable PIM SM on interface\n");
6496 return CMD_WARNING_CONFIG_FAILED
;
6500 "WARN: Enabled PIM SM on interface; configure PIM SSM "
6501 "range if needed\n");
6505 static int interface_ip_pim_helper(struct vty
*vty
)
6507 struct pim_interface
*pim_ifp
;
6509 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6511 if (!pim_cmd_interface_add(ifp
)) {
6512 vty_out(vty
, "Could not enable PIM SM on interface\n");
6513 return CMD_WARNING_CONFIG_FAILED
;
6516 pim_ifp
= ifp
->info
;
6518 pim_if_create_pimreg(pim_ifp
->pim
);
6523 DEFUN_HIDDEN (interface_ip_pim_sm
,
6524 interface_ip_pim_sm_cmd
,
6530 return interface_ip_pim_helper(vty
);
6533 DEFUN (interface_ip_pim
,
6534 interface_ip_pim_cmd
,
6539 return interface_ip_pim_helper(vty
);
6542 static int pim_cmd_interface_delete(struct interface
*ifp
)
6544 struct pim_interface
*pim_ifp
= ifp
->info
;
6549 PIM_IF_DONT_PIM(pim_ifp
->options
);
6551 pim_if_membership_clear(ifp
);
6554 pim_sock_delete() removes all neighbors from
6555 pim_ifp->pim_neighbor_list.
6557 pim_sock_delete(ifp
, "pim unconfigured on interface");
6559 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
6560 pim_if_addr_del_all(ifp
);
6567 static int interface_no_ip_pim_helper(struct vty
*vty
)
6569 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6570 if (!pim_cmd_interface_delete(ifp
)) {
6571 vty_out(vty
, "Unable to delete interface information\n");
6572 return CMD_WARNING_CONFIG_FAILED
;
6578 DEFUN_HIDDEN (interface_no_ip_pim_ssm
,
6579 interface_no_ip_pim_ssm_cmd
,
6586 return interface_no_ip_pim_helper(vty
);
6589 DEFUN_HIDDEN (interface_no_ip_pim_sm
,
6590 interface_no_ip_pim_sm_cmd
,
6597 return interface_no_ip_pim_helper(vty
);
6600 DEFUN (interface_no_ip_pim
,
6601 interface_no_ip_pim_cmd
,
6607 return interface_no_ip_pim_helper(vty
);
6611 DEFUN(interface_ip_pim_boundary_oil
,
6612 interface_ip_pim_boundary_oil_cmd
,
6613 "ip multicast boundary oil WORD",
6615 "Generic multicast configuration options\n"
6616 "Define multicast boundary\n"
6617 "Filter OIL by group using prefix list\n"
6618 "Prefix list to filter OIL with\n")
6620 VTY_DECLVAR_CONTEXT(interface
, iif
);
6621 struct pim_interface
*pim_ifp
;
6624 argv_find(argv
, argc
, "WORD", &idx
);
6626 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6628 if (pim_ifp
->boundary_oil_plist
)
6629 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
6631 pim_ifp
->boundary_oil_plist
=
6632 XSTRDUP(MTYPE_PIM_INTERFACE
, argv
[idx
]->arg
);
6634 /* Interface will be pruned from OIL on next Join */
6638 DEFUN(interface_no_ip_pim_boundary_oil
,
6639 interface_no_ip_pim_boundary_oil_cmd
,
6640 "no ip multicast boundary oil [WORD]",
6643 "Generic multicast configuration options\n"
6644 "Define multicast boundary\n"
6645 "Filter OIL by group using prefix list\n"
6646 "Prefix list to filter OIL with\n")
6648 VTY_DECLVAR_CONTEXT(interface
, iif
);
6649 struct pim_interface
*pim_ifp
;
6652 argv_find(argv
, argc
, "WORD", &idx
);
6654 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6656 if (pim_ifp
->boundary_oil_plist
)
6657 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
6662 DEFUN (interface_ip_mroute
,
6663 interface_ip_mroute_cmd
,
6664 "ip mroute INTERFACE A.B.C.D",
6666 "Add multicast route\n"
6667 "Outgoing interface name\n"
6670 VTY_DECLVAR_CONTEXT(interface
, iif
);
6671 struct pim_interface
*pim_ifp
;
6672 struct pim_instance
*pim
;
6673 int idx_interface
= 2;
6675 struct interface
*oif
;
6676 const char *oifname
;
6677 const char *grp_str
;
6678 struct in_addr grp_addr
;
6679 struct in_addr src_addr
;
6682 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6685 oifname
= argv
[idx_interface
]->arg
;
6686 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6688 vty_out(vty
, "No such interface name %s\n", oifname
);
6692 grp_str
= argv
[idx_ipv4
]->arg
;
6693 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6695 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6696 errno
, safe_strerror(errno
));
6700 src_addr
.s_addr
= INADDR_ANY
;
6702 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6703 vty_out(vty
, "Failed to add route\n");
6710 DEFUN (interface_ip_mroute_source
,
6711 interface_ip_mroute_source_cmd
,
6712 "ip mroute INTERFACE A.B.C.D A.B.C.D",
6714 "Add multicast route\n"
6715 "Outgoing interface name\n"
6719 VTY_DECLVAR_CONTEXT(interface
, iif
);
6720 struct pim_interface
*pim_ifp
;
6721 struct pim_instance
*pim
;
6722 int idx_interface
= 2;
6725 struct interface
*oif
;
6726 const char *oifname
;
6727 const char *grp_str
;
6728 struct in_addr grp_addr
;
6729 const char *src_str
;
6730 struct in_addr src_addr
;
6733 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6736 oifname
= argv
[idx_interface
]->arg
;
6737 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6739 vty_out(vty
, "No such interface name %s\n", oifname
);
6743 grp_str
= argv
[idx_ipv4
]->arg
;
6744 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6746 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6747 errno
, safe_strerror(errno
));
6751 src_str
= argv
[idx_ipv4_2
]->arg
;
6752 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
6754 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
6755 errno
, safe_strerror(errno
));
6759 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6760 vty_out(vty
, "Failed to add route\n");
6767 DEFUN (interface_no_ip_mroute
,
6768 interface_no_ip_mroute_cmd
,
6769 "no ip mroute INTERFACE A.B.C.D",
6772 "Add multicast route\n"
6773 "Outgoing interface name\n"
6776 VTY_DECLVAR_CONTEXT(interface
, iif
);
6777 struct pim_interface
*pim_ifp
;
6778 struct pim_instance
*pim
;
6779 int idx_interface
= 3;
6781 struct interface
*oif
;
6782 const char *oifname
;
6783 const char *grp_str
;
6784 struct in_addr grp_addr
;
6785 struct in_addr src_addr
;
6788 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6791 oifname
= argv
[idx_interface
]->arg
;
6792 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6794 vty_out(vty
, "No such interface name %s\n", oifname
);
6798 grp_str
= argv
[idx_ipv4
]->arg
;
6799 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6801 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6802 errno
, safe_strerror(errno
));
6806 src_addr
.s_addr
= INADDR_ANY
;
6808 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6809 vty_out(vty
, "Failed to remove route\n");
6816 DEFUN (interface_no_ip_mroute_source
,
6817 interface_no_ip_mroute_source_cmd
,
6818 "no ip mroute INTERFACE A.B.C.D A.B.C.D",
6821 "Add multicast route\n"
6822 "Outgoing interface name\n"
6826 VTY_DECLVAR_CONTEXT(interface
, iif
);
6827 struct pim_interface
*pim_ifp
;
6828 struct pim_instance
*pim
;
6829 int idx_interface
= 3;
6832 struct interface
*oif
;
6833 const char *oifname
;
6834 const char *grp_str
;
6835 struct in_addr grp_addr
;
6836 const char *src_str
;
6837 struct in_addr src_addr
;
6840 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6843 oifname
= argv
[idx_interface
]->arg
;
6844 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6846 vty_out(vty
, "No such interface name %s\n", oifname
);
6850 grp_str
= argv
[idx_ipv4
]->arg
;
6851 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6853 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6854 errno
, safe_strerror(errno
));
6858 src_str
= argv
[idx_ipv4_2
]->arg
;
6859 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
6861 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
6862 errno
, safe_strerror(errno
));
6866 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6867 vty_out(vty
, "Failed to remove route\n");
6874 DEFUN (interface_ip_pim_hello
,
6875 interface_ip_pim_hello_cmd
,
6876 "ip pim hello (1-180) [(1-180)]",
6880 IFACE_PIM_HELLO_TIME_STR
6881 IFACE_PIM_HELLO_HOLD_STR
)
6883 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6886 struct pim_interface
*pim_ifp
= ifp
->info
;
6889 if (!pim_cmd_interface_add(ifp
)) {
6890 vty_out(vty
, "Could not enable PIM SM on interface\n");
6891 return CMD_WARNING_CONFIG_FAILED
;
6895 pim_ifp
= ifp
->info
;
6896 pim_ifp
->pim_hello_period
= strtol(argv
[idx_time
]->arg
, NULL
, 10);
6898 if (argc
== idx_hold
+ 1)
6899 pim_ifp
->pim_default_holdtime
=
6900 strtol(argv
[idx_hold
]->arg
, NULL
, 10);
6905 DEFUN (interface_no_ip_pim_hello
,
6906 interface_no_ip_pim_hello_cmd
,
6907 "no ip pim hello [(1-180) (1-180)]",
6912 IFACE_PIM_HELLO_TIME_STR
6913 IFACE_PIM_HELLO_HOLD_STR
)
6915 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6916 struct pim_interface
*pim_ifp
= ifp
->info
;
6919 vty_out(vty
, "Pim not enabled on this interface\n");
6920 return CMD_WARNING_CONFIG_FAILED
;
6923 pim_ifp
->pim_hello_period
= PIM_DEFAULT_HELLO_PERIOD
;
6924 pim_ifp
->pim_default_holdtime
= -1;
6935 PIM_DO_DEBUG_IGMP_EVENTS
;
6936 PIM_DO_DEBUG_IGMP_PACKETS
;
6937 PIM_DO_DEBUG_IGMP_TRACE
;
6941 DEFUN (no_debug_igmp
,
6948 PIM_DONT_DEBUG_IGMP_EVENTS
;
6949 PIM_DONT_DEBUG_IGMP_PACKETS
;
6950 PIM_DONT_DEBUG_IGMP_TRACE
;
6955 DEFUN (debug_igmp_events
,
6956 debug_igmp_events_cmd
,
6957 "debug igmp events",
6960 DEBUG_IGMP_EVENTS_STR
)
6962 PIM_DO_DEBUG_IGMP_EVENTS
;
6966 DEFUN (no_debug_igmp_events
,
6967 no_debug_igmp_events_cmd
,
6968 "no debug igmp events",
6972 DEBUG_IGMP_EVENTS_STR
)
6974 PIM_DONT_DEBUG_IGMP_EVENTS
;
6979 DEFUN (debug_igmp_packets
,
6980 debug_igmp_packets_cmd
,
6981 "debug igmp packets",
6984 DEBUG_IGMP_PACKETS_STR
)
6986 PIM_DO_DEBUG_IGMP_PACKETS
;
6990 DEFUN (no_debug_igmp_packets
,
6991 no_debug_igmp_packets_cmd
,
6992 "no debug igmp packets",
6996 DEBUG_IGMP_PACKETS_STR
)
6998 PIM_DONT_DEBUG_IGMP_PACKETS
;
7003 DEFUN (debug_igmp_trace
,
7004 debug_igmp_trace_cmd
,
7008 DEBUG_IGMP_TRACE_STR
)
7010 PIM_DO_DEBUG_IGMP_TRACE
;
7014 DEFUN (no_debug_igmp_trace
,
7015 no_debug_igmp_trace_cmd
,
7016 "no debug igmp trace",
7020 DEBUG_IGMP_TRACE_STR
)
7022 PIM_DONT_DEBUG_IGMP_TRACE
;
7027 DEFUN (debug_mroute
,
7033 PIM_DO_DEBUG_MROUTE
;
7037 DEFUN (debug_mroute_detail
,
7038 debug_mroute_detail_cmd
,
7039 "debug mroute detail",
7044 PIM_DO_DEBUG_MROUTE_DETAIL
;
7048 DEFUN (no_debug_mroute
,
7049 no_debug_mroute_cmd
,
7055 PIM_DONT_DEBUG_MROUTE
;
7059 DEFUN (no_debug_mroute_detail
,
7060 no_debug_mroute_detail_cmd
,
7061 "no debug mroute detail",
7067 PIM_DONT_DEBUG_MROUTE_DETAIL
;
7071 DEFUN (debug_pim_static
,
7072 debug_pim_static_cmd
,
7078 PIM_DO_DEBUG_STATIC
;
7082 DEFUN (no_debug_pim_static
,
7083 no_debug_pim_static_cmd
,
7084 "no debug pim static",
7090 PIM_DONT_DEBUG_STATIC
;
7101 PIM_DO_DEBUG_PIM_EVENTS
;
7102 PIM_DO_DEBUG_PIM_PACKETS
;
7103 PIM_DO_DEBUG_PIM_TRACE
;
7104 PIM_DO_DEBUG_MSDP_EVENTS
;
7105 PIM_DO_DEBUG_MSDP_PACKETS
;
7109 DEFUN (no_debug_pim
,
7116 PIM_DONT_DEBUG_PIM_EVENTS
;
7117 PIM_DONT_DEBUG_PIM_PACKETS
;
7118 PIM_DONT_DEBUG_PIM_TRACE
;
7119 PIM_DONT_DEBUG_MSDP_EVENTS
;
7120 PIM_DONT_DEBUG_MSDP_PACKETS
;
7122 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
7123 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
7128 DEFUN (debug_pim_nht
,
7133 "Nexthop Tracking\n")
7135 PIM_DO_DEBUG_PIM_NHT
;
7139 DEFUN (no_debug_pim_nht
,
7140 no_debug_pim_nht_cmd
,
7145 "Nexthop Tracking\n")
7147 PIM_DONT_DEBUG_PIM_NHT
;
7151 DEFUN (debug_pim_nht_rp
,
7152 debug_pim_nht_rp_cmd
,
7156 "Nexthop Tracking\n"
7157 "RP Nexthop Tracking\n")
7159 PIM_DO_DEBUG_PIM_NHT_RP
;
7163 DEFUN (no_debug_pim_nht_rp
,
7164 no_debug_pim_nht_rp_cmd
,
7165 "no debug pim nht rp",
7169 "Nexthop Tracking\n"
7170 "RP Nexthop Tracking\n")
7172 PIM_DONT_DEBUG_PIM_NHT_RP
;
7176 DEFUN (debug_pim_events
,
7177 debug_pim_events_cmd
,
7181 DEBUG_PIM_EVENTS_STR
)
7183 PIM_DO_DEBUG_PIM_EVENTS
;
7187 DEFUN (no_debug_pim_events
,
7188 no_debug_pim_events_cmd
,
7189 "no debug pim events",
7193 DEBUG_PIM_EVENTS_STR
)
7195 PIM_DONT_DEBUG_PIM_EVENTS
;
7199 DEFUN (debug_pim_packets
,
7200 debug_pim_packets_cmd
,
7201 "debug pim packets [<hello|joins|register>]",
7204 DEBUG_PIM_PACKETS_STR
7205 DEBUG_PIM_HELLO_PACKETS_STR
7206 DEBUG_PIM_J_P_PACKETS_STR
7207 DEBUG_PIM_PIM_REG_PACKETS_STR
)
7210 if (argv_find(argv
, argc
, "hello", &idx
)) {
7211 PIM_DO_DEBUG_PIM_HELLO
;
7212 vty_out(vty
, "PIM Hello debugging is on\n");
7213 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
7214 PIM_DO_DEBUG_PIM_J_P
;
7215 vty_out(vty
, "PIM Join/Prune debugging is on\n");
7216 } else if (argv_find(argv
, argc
, "register", &idx
)) {
7217 PIM_DO_DEBUG_PIM_REG
;
7218 vty_out(vty
, "PIM Register debugging is on\n");
7220 PIM_DO_DEBUG_PIM_PACKETS
;
7221 vty_out(vty
, "PIM Packet debugging is on \n");
7226 DEFUN (no_debug_pim_packets
,
7227 no_debug_pim_packets_cmd
,
7228 "no debug pim packets [<hello|joins|register>]",
7232 DEBUG_PIM_PACKETS_STR
7233 DEBUG_PIM_HELLO_PACKETS_STR
7234 DEBUG_PIM_J_P_PACKETS_STR
7235 DEBUG_PIM_PIM_REG_PACKETS_STR
)
7238 if (argv_find(argv
, argc
, "hello", &idx
)) {
7239 PIM_DONT_DEBUG_PIM_HELLO
;
7240 vty_out(vty
, "PIM Hello debugging is off \n");
7241 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
7242 PIM_DONT_DEBUG_PIM_J_P
;
7243 vty_out(vty
, "PIM Join/Prune debugging is off \n");
7244 } else if (argv_find(argv
, argc
, "register", &idx
)) {
7245 PIM_DONT_DEBUG_PIM_REG
;
7246 vty_out(vty
, "PIM Register debugging is off\n");
7248 PIM_DONT_DEBUG_PIM_PACKETS
;
7254 DEFUN (debug_pim_packetdump_send
,
7255 debug_pim_packetdump_send_cmd
,
7256 "debug pim packet-dump send",
7259 DEBUG_PIM_PACKETDUMP_STR
7260 DEBUG_PIM_PACKETDUMP_SEND_STR
)
7262 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND
;
7266 DEFUN (no_debug_pim_packetdump_send
,
7267 no_debug_pim_packetdump_send_cmd
,
7268 "no debug pim packet-dump send",
7272 DEBUG_PIM_PACKETDUMP_STR
7273 DEBUG_PIM_PACKETDUMP_SEND_STR
)
7275 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
7279 DEFUN (debug_pim_packetdump_recv
,
7280 debug_pim_packetdump_recv_cmd
,
7281 "debug pim packet-dump receive",
7284 DEBUG_PIM_PACKETDUMP_STR
7285 DEBUG_PIM_PACKETDUMP_RECV_STR
)
7287 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV
;
7291 DEFUN (no_debug_pim_packetdump_recv
,
7292 no_debug_pim_packetdump_recv_cmd
,
7293 "no debug pim packet-dump receive",
7297 DEBUG_PIM_PACKETDUMP_STR
7298 DEBUG_PIM_PACKETDUMP_RECV_STR
)
7300 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
7304 DEFUN (debug_pim_trace
,
7305 debug_pim_trace_cmd
,
7309 DEBUG_PIM_TRACE_STR
)
7311 PIM_DO_DEBUG_PIM_TRACE
;
7315 DEFUN (debug_pim_trace_detail
,
7316 debug_pim_trace_detail_cmd
,
7317 "debug pim trace detail",
7321 "Detailed Information\n")
7323 PIM_DO_DEBUG_PIM_TRACE_DETAIL
;
7327 DEFUN (no_debug_pim_trace
,
7328 no_debug_pim_trace_cmd
,
7329 "no debug pim trace",
7333 DEBUG_PIM_TRACE_STR
)
7335 PIM_DONT_DEBUG_PIM_TRACE
;
7339 DEFUN (no_debug_pim_trace_detail
,
7340 no_debug_pim_trace_detail_cmd
,
7341 "no debug pim trace detail",
7346 "Detailed Information\n")
7348 PIM_DONT_DEBUG_PIM_TRACE_DETAIL
;
7352 DEFUN (debug_ssmpingd
,
7358 PIM_DO_DEBUG_SSMPINGD
;
7362 DEFUN (no_debug_ssmpingd
,
7363 no_debug_ssmpingd_cmd
,
7364 "no debug ssmpingd",
7369 PIM_DONT_DEBUG_SSMPINGD
;
7373 DEFUN (debug_pim_zebra
,
7374 debug_pim_zebra_cmd
,
7378 DEBUG_PIM_ZEBRA_STR
)
7384 DEFUN (no_debug_pim_zebra
,
7385 no_debug_pim_zebra_cmd
,
7386 "no debug pim zebra",
7390 DEBUG_PIM_ZEBRA_STR
)
7392 PIM_DONT_DEBUG_ZEBRA
;
7402 PIM_DO_DEBUG_MSDP_EVENTS
;
7403 PIM_DO_DEBUG_MSDP_PACKETS
;
7407 DEFUN (no_debug_msdp
,
7414 PIM_DONT_DEBUG_MSDP_EVENTS
;
7415 PIM_DONT_DEBUG_MSDP_PACKETS
;
7419 DEFUN (debug_msdp_events
,
7420 debug_msdp_events_cmd
,
7421 "debug msdp events",
7424 DEBUG_MSDP_EVENTS_STR
)
7426 PIM_DO_DEBUG_MSDP_EVENTS
;
7430 DEFUN (no_debug_msdp_events
,
7431 no_debug_msdp_events_cmd
,
7432 "no debug msdp events",
7436 DEBUG_MSDP_EVENTS_STR
)
7438 PIM_DONT_DEBUG_MSDP_EVENTS
;
7442 DEFUN (debug_msdp_packets
,
7443 debug_msdp_packets_cmd
,
7444 "debug msdp packets",
7447 DEBUG_MSDP_PACKETS_STR
)
7449 PIM_DO_DEBUG_MSDP_PACKETS
;
7453 DEFUN (no_debug_msdp_packets
,
7454 no_debug_msdp_packets_cmd
,
7455 "no debug msdp packets",
7459 DEBUG_MSDP_PACKETS_STR
)
7461 PIM_DONT_DEBUG_MSDP_PACKETS
;
7465 DEFUN (debug_mtrace
,
7471 PIM_DO_DEBUG_MTRACE
;
7475 DEFUN (no_debug_mtrace
,
7476 no_debug_mtrace_cmd
,
7482 PIM_DONT_DEBUG_MTRACE
;
7486 DEFUN_NOSH (show_debugging_pim
,
7487 show_debugging_pim_cmd
,
7488 "show debugging [pim]",
7493 vty_out(vty
, "PIM debugging status\n");
7495 pim_debug_config_write(vty
);
7500 static int interface_pim_use_src_cmd_worker(struct vty
*vty
, const char *source
)
7503 struct in_addr source_addr
;
7504 int ret
= CMD_SUCCESS
;
7505 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7507 result
= inet_pton(AF_INET
, source
, &source_addr
);
7509 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", source
,
7510 errno
, safe_strerror(errno
));
7511 return CMD_WARNING_CONFIG_FAILED
;
7514 result
= pim_update_source_set(ifp
, source_addr
);
7518 case PIM_IFACE_NOT_FOUND
:
7519 ret
= CMD_WARNING_CONFIG_FAILED
;
7520 vty_out(vty
, "Pim not enabled on this interface\n");
7522 case PIM_UPDATE_SOURCE_DUP
:
7524 vty_out(vty
, "%% Source already set to %s\n", source
);
7527 ret
= CMD_WARNING_CONFIG_FAILED
;
7528 vty_out(vty
, "%% Source set failed\n");
7534 DEFUN (interface_pim_use_source
,
7535 interface_pim_use_source_cmd
,
7536 "ip pim use-source A.B.C.D",
7539 "Configure primary IP address\n"
7540 "source ip address\n")
7542 return interface_pim_use_src_cmd_worker(vty
, argv
[3]->arg
);
7545 DEFUN (interface_no_pim_use_source
,
7546 interface_no_pim_use_source_cmd
,
7547 "no ip pim use-source [A.B.C.D]",
7551 "Delete source IP address\n"
7552 "source ip address\n")
7554 return interface_pim_use_src_cmd_worker(vty
, "0.0.0.0");
7562 "Enables BFD support\n")
7564 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7565 struct pim_interface
*pim_ifp
= ifp
->info
;
7566 struct bfd_info
*bfd_info
= NULL
;
7569 if (!pim_cmd_interface_add(ifp
)) {
7570 vty_out(vty
, "Could not enable PIM SM on interface\n");
7574 pim_ifp
= ifp
->info
;
7576 bfd_info
= pim_ifp
->bfd_info
;
7578 if (!bfd_info
|| !CHECK_FLAG(bfd_info
->flags
, BFD_FLAG_PARAM_CFG
))
7579 pim_bfd_if_param_set(ifp
, BFD_DEF_MIN_RX
, BFD_DEF_MIN_TX
,
7580 BFD_DEF_DETECT_MULT
, 1);
7585 DEFUN (no_ip_pim_bfd
,
7591 "Disables BFD support\n")
7593 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7594 struct pim_interface
*pim_ifp
= ifp
->info
;
7597 vty_out(vty
, "Pim not enabled on this interface\n");
7601 if (pim_ifp
->bfd_info
) {
7602 pim_bfd_reg_dereg_all_nbr(ifp
, ZEBRA_BFD_DEST_DEREGISTER
);
7603 bfd_info_free(&(pim_ifp
->bfd_info
));
7613 #endif /* HAVE_BFDD */
7615 ip_pim_bfd_param_cmd
,
7616 "ip pim bfd (2-255) (50-60000) (50-60000)",
7619 "Enables BFD support\n"
7620 "Detect Multiplier\n"
7621 "Required min receive interval\n"
7622 "Desired min transmit interval\n")
7624 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7626 int idx_number_2
= 4;
7627 int idx_number_3
= 5;
7632 struct pim_interface
*pim_ifp
= ifp
->info
;
7635 if (!pim_cmd_interface_add(ifp
)) {
7636 vty_out(vty
, "Could not enable PIM SM on interface\n");
7641 if ((ret
= bfd_validate_param(
7642 vty
, argv
[idx_number
]->arg
, argv
[idx_number_2
]->arg
,
7643 argv
[idx_number_3
]->arg
, &dm_val
, &rx_val
, &tx_val
))
7647 pim_bfd_if_param_set(ifp
, rx_val
, tx_val
, dm_val
, 0);
7653 ALIAS(no_ip_pim_bfd
, no_ip_pim_bfd_param_cmd
,
7654 "no ip pim bfd (2-255) (50-60000) (50-60000)", NO_STR IP_STR PIM_STR
7655 "Enables BFD support\n"
7656 "Detect Multiplier\n"
7657 "Required min receive interval\n"
7658 "Desired min transmit interval\n")
7659 #endif /* !HAVE_BFDD */
7661 static int ip_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
7662 const char *peer
, const char *local
)
7664 enum pim_msdp_err result
;
7665 struct in_addr peer_addr
;
7666 struct in_addr local_addr
;
7667 int ret
= CMD_SUCCESS
;
7669 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
7671 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
7672 errno
, safe_strerror(errno
));
7673 return CMD_WARNING_CONFIG_FAILED
;
7676 result
= inet_pton(AF_INET
, local
, &local_addr
);
7678 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", local
,
7679 errno
, safe_strerror(errno
));
7680 return CMD_WARNING_CONFIG_FAILED
;
7683 result
= pim_msdp_peer_add(pim
, peer_addr
, local_addr
, "default",
7686 case PIM_MSDP_ERR_NONE
:
7688 case PIM_MSDP_ERR_OOM
:
7689 ret
= CMD_WARNING_CONFIG_FAILED
;
7690 vty_out(vty
, "%% Out of memory\n");
7692 case PIM_MSDP_ERR_PEER_EXISTS
:
7694 vty_out(vty
, "%% Peer exists\n");
7696 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
7697 ret
= CMD_WARNING_CONFIG_FAILED
;
7698 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
7701 ret
= CMD_WARNING_CONFIG_FAILED
;
7702 vty_out(vty
, "%% peer add failed\n");
7708 DEFUN_HIDDEN (ip_msdp_peer
,
7710 "ip msdp peer A.B.C.D source A.B.C.D",
7713 "Configure MSDP peer\n"
7715 "Source address for TCP connection\n"
7716 "local ip address\n")
7718 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7719 return ip_msdp_peer_cmd_worker(pim
, vty
, argv
[3]->arg
, argv
[5]->arg
);
7722 static int ip_no_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
7725 enum pim_msdp_err result
;
7726 struct in_addr peer_addr
;
7728 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
7730 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
7731 errno
, safe_strerror(errno
));
7732 return CMD_WARNING_CONFIG_FAILED
;
7735 result
= pim_msdp_peer_del(pim
, peer_addr
);
7737 case PIM_MSDP_ERR_NONE
:
7739 case PIM_MSDP_ERR_NO_PEER
:
7740 vty_out(vty
, "%% Peer does not exist\n");
7743 vty_out(vty
, "%% peer del failed\n");
7746 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7749 DEFUN_HIDDEN (no_ip_msdp_peer
,
7750 no_ip_msdp_peer_cmd
,
7751 "no ip msdp peer A.B.C.D",
7755 "Delete MSDP peer\n"
7756 "peer ip address\n")
7758 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7759 return ip_no_msdp_peer_cmd_worker(pim
, vty
, argv
[4]->arg
);
7762 static int ip_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
7763 struct vty
*vty
, const char *mg
,
7766 enum pim_msdp_err result
;
7767 struct in_addr mbr_ip
;
7768 int ret
= CMD_SUCCESS
;
7770 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
7772 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
7773 errno
, safe_strerror(errno
));
7774 return CMD_WARNING_CONFIG_FAILED
;
7777 result
= pim_msdp_mg_mbr_add(pim
, mg
, mbr_ip
);
7779 case PIM_MSDP_ERR_NONE
:
7781 case PIM_MSDP_ERR_OOM
:
7782 ret
= CMD_WARNING_CONFIG_FAILED
;
7783 vty_out(vty
, "%% Out of memory\n");
7785 case PIM_MSDP_ERR_MG_MBR_EXISTS
:
7787 vty_out(vty
, "%% mesh-group member exists\n");
7789 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
7790 ret
= CMD_WARNING_CONFIG_FAILED
;
7791 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
7794 ret
= CMD_WARNING_CONFIG_FAILED
;
7795 vty_out(vty
, "%% member add failed\n");
7801 DEFUN (ip_msdp_mesh_group_member
,
7802 ip_msdp_mesh_group_member_cmd
,
7803 "ip msdp mesh-group WORD member A.B.C.D",
7806 "Configure MSDP mesh-group\n"
7808 "mesh group member\n"
7809 "peer ip address\n")
7811 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7812 return ip_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[3]->arg
,
7816 static int ip_no_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
7821 enum pim_msdp_err result
;
7822 struct in_addr mbr_ip
;
7824 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
7826 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
7827 errno
, safe_strerror(errno
));
7828 return CMD_WARNING_CONFIG_FAILED
;
7831 result
= pim_msdp_mg_mbr_del(pim
, mg
, mbr_ip
);
7833 case PIM_MSDP_ERR_NONE
:
7835 case PIM_MSDP_ERR_NO_MG
:
7836 vty_out(vty
, "%% mesh-group does not exist\n");
7838 case PIM_MSDP_ERR_NO_MG_MBR
:
7839 vty_out(vty
, "%% mesh-group member does not exist\n");
7842 vty_out(vty
, "%% mesh-group member del failed\n");
7845 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7847 DEFUN (no_ip_msdp_mesh_group_member
,
7848 no_ip_msdp_mesh_group_member_cmd
,
7849 "no ip msdp mesh-group WORD member A.B.C.D",
7853 "Delete MSDP mesh-group member\n"
7855 "mesh group member\n"
7856 "peer ip address\n")
7858 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7859 return ip_no_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[4]->arg
,
7863 static int ip_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
7864 struct vty
*vty
, const char *mg
,
7867 enum pim_msdp_err result
;
7868 struct in_addr src_ip
;
7870 result
= inet_pton(AF_INET
, src
, &src_ip
);
7872 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", src
,
7873 errno
, safe_strerror(errno
));
7874 return CMD_WARNING_CONFIG_FAILED
;
7877 result
= pim_msdp_mg_src_add(pim
, mg
, src_ip
);
7879 case PIM_MSDP_ERR_NONE
:
7881 case PIM_MSDP_ERR_OOM
:
7882 vty_out(vty
, "%% Out of memory\n");
7884 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
7885 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
7888 vty_out(vty
, "%% source add failed\n");
7891 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7895 DEFUN (ip_msdp_mesh_group_source
,
7896 ip_msdp_mesh_group_source_cmd
,
7897 "ip msdp mesh-group WORD source A.B.C.D",
7900 "Configure MSDP mesh-group\n"
7902 "mesh group local address\n"
7903 "source ip address for the TCP connection\n")
7905 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7906 return ip_msdp_mesh_group_source_cmd_worker(pim
, vty
, argv
[3]->arg
,
7910 static int ip_no_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
7914 enum pim_msdp_err result
;
7916 result
= pim_msdp_mg_src_del(pim
, mg
);
7918 case PIM_MSDP_ERR_NONE
:
7920 case PIM_MSDP_ERR_NO_MG
:
7921 vty_out(vty
, "%% mesh-group does not exist\n");
7924 vty_out(vty
, "%% mesh-group source del failed\n");
7927 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7930 static int ip_no_msdp_mesh_group_cmd_worker(struct pim_instance
*pim
,
7931 struct vty
*vty
, const char *mg
)
7933 enum pim_msdp_err result
;
7935 result
= pim_msdp_mg_del(pim
, mg
);
7937 case PIM_MSDP_ERR_NONE
:
7939 case PIM_MSDP_ERR_NO_MG
:
7940 vty_out(vty
, "%% mesh-group does not exist\n");
7943 vty_out(vty
, "%% mesh-group source del failed\n");
7946 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7949 DEFUN (no_ip_msdp_mesh_group_source
,
7950 no_ip_msdp_mesh_group_source_cmd
,
7951 "no ip msdp mesh-group WORD source [A.B.C.D]",
7955 "Delete MSDP mesh-group source\n"
7957 "mesh group source\n"
7958 "mesh group local address\n")
7960 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7962 return ip_no_msdp_mesh_group_cmd_worker(pim
, vty
, argv
[6]->arg
);
7964 return ip_no_msdp_mesh_group_source_cmd_worker(pim
, vty
,
7968 static void print_empty_json_obj(struct vty
*vty
)
7971 json
= json_object_new_object();
7972 vty_out(vty
, "%s\n",
7973 json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
));
7974 json_object_free(json
);
7977 static void ip_msdp_show_mesh_group(struct pim_instance
*pim
, struct vty
*vty
,
7980 struct listnode
*mbrnode
;
7981 struct pim_msdp_mg_mbr
*mbr
;
7982 struct pim_msdp_mg
*mg
= pim
->msdp
.mg
;
7983 char mbr_str
[INET_ADDRSTRLEN
];
7984 char src_str
[INET_ADDRSTRLEN
];
7985 char state_str
[PIM_MSDP_STATE_STRLEN
];
7986 enum pim_msdp_peer_state state
;
7987 json_object
*json
= NULL
;
7988 json_object
*json_mg_row
= NULL
;
7989 json_object
*json_members
= NULL
;
7990 json_object
*json_row
= NULL
;
7994 print_empty_json_obj(vty
);
7998 pim_inet4_dump("<source?>", mg
->src_ip
, src_str
, sizeof(src_str
));
8000 json
= json_object_new_object();
8001 /* currently there is only one mesh group but we should still
8003 * it a dict with mg-name as key */
8004 json_mg_row
= json_object_new_object();
8005 json_object_string_add(json_mg_row
, "name",
8006 mg
->mesh_group_name
);
8007 json_object_string_add(json_mg_row
, "source", src_str
);
8009 vty_out(vty
, "Mesh group : %s\n", mg
->mesh_group_name
);
8010 vty_out(vty
, " Source : %s\n", src_str
);
8011 vty_out(vty
, " Member State\n");
8014 for (ALL_LIST_ELEMENTS_RO(mg
->mbr_list
, mbrnode
, mbr
)) {
8015 pim_inet4_dump("<mbr?>", mbr
->mbr_ip
, mbr_str
, sizeof(mbr_str
));
8017 state
= mbr
->mp
->state
;
8019 state
= PIM_MSDP_DISABLED
;
8021 pim_msdp_state_dump(state
, state_str
, sizeof(state_str
));
8023 json_row
= json_object_new_object();
8024 json_object_string_add(json_row
, "member", mbr_str
);
8025 json_object_string_add(json_row
, "state", state_str
);
8026 if (!json_members
) {
8027 json_members
= json_object_new_object();
8028 json_object_object_add(json_mg_row
, "members",
8031 json_object_object_add(json_members
, mbr_str
, json_row
);
8033 vty_out(vty
, " %-15s %11s\n", mbr_str
, state_str
);
8038 json_object_object_add(json
, mg
->mesh_group_name
, json_mg_row
);
8039 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8040 json
, JSON_C_TO_STRING_PRETTY
));
8041 json_object_free(json
);
8045 DEFUN (show_ip_msdp_mesh_group
,
8046 show_ip_msdp_mesh_group_cmd
,
8047 "show ip msdp [vrf NAME] mesh-group [json]",
8052 "MSDP mesh-group information\n"
8055 bool uj
= use_json(argc
, argv
);
8057 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
8062 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
8067 DEFUN (show_ip_msdp_mesh_group_vrf_all
,
8068 show_ip_msdp_mesh_group_vrf_all_cmd
,
8069 "show ip msdp vrf all mesh-group [json]",
8074 "MSDP mesh-group information\n"
8077 bool uj
= use_json(argc
, argv
);
8083 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
8087 vty_out(vty
, " \"%s\": ", vrf
->name
);
8090 vty_out(vty
, "VRF: %s\n", vrf
->name
);
8091 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
8094 vty_out(vty
, "}\n");
8099 static void ip_msdp_show_peers(struct pim_instance
*pim
, struct vty
*vty
,
8102 struct listnode
*mpnode
;
8103 struct pim_msdp_peer
*mp
;
8104 char peer_str
[INET_ADDRSTRLEN
];
8105 char local_str
[INET_ADDRSTRLEN
];
8106 char state_str
[PIM_MSDP_STATE_STRLEN
];
8107 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
8109 json_object
*json
= NULL
;
8110 json_object
*json_row
= NULL
;
8114 json
= json_object_new_object();
8117 "Peer Local State Uptime SaCnt\n");
8120 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
8121 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
8122 now
= pim_time_monotonic_sec();
8123 pim_time_uptime(timebuf
, sizeof(timebuf
),
8126 strcpy(timebuf
, "-");
8128 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
8129 pim_inet4_dump("<local?>", mp
->local
, local_str
,
8131 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
8133 json_row
= json_object_new_object();
8134 json_object_string_add(json_row
, "peer", peer_str
);
8135 json_object_string_add(json_row
, "local", local_str
);
8136 json_object_string_add(json_row
, "state", state_str
);
8137 json_object_string_add(json_row
, "upTime", timebuf
);
8138 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
8139 json_object_object_add(json
, peer_str
, json_row
);
8141 vty_out(vty
, "%-15s %15s %11s %8s %6d\n", peer_str
,
8142 local_str
, state_str
, timebuf
, mp
->sa_cnt
);
8147 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8148 json
, JSON_C_TO_STRING_PRETTY
));
8149 json_object_free(json
);
8153 static void ip_msdp_show_peers_detail(struct pim_instance
*pim
, struct vty
*vty
,
8154 const char *peer
, bool uj
)
8156 struct listnode
*mpnode
;
8157 struct pim_msdp_peer
*mp
;
8158 char peer_str
[INET_ADDRSTRLEN
];
8159 char local_str
[INET_ADDRSTRLEN
];
8160 char state_str
[PIM_MSDP_STATE_STRLEN
];
8161 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
8162 char katimer
[PIM_MSDP_TIMER_STRLEN
];
8163 char crtimer
[PIM_MSDP_TIMER_STRLEN
];
8164 char holdtimer
[PIM_MSDP_TIMER_STRLEN
];
8166 json_object
*json
= NULL
;
8167 json_object
*json_row
= NULL
;
8170 json
= json_object_new_object();
8173 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
8174 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
8175 if (strcmp(peer
, "detail") && strcmp(peer
, peer_str
))
8178 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
8179 now
= pim_time_monotonic_sec();
8180 pim_time_uptime(timebuf
, sizeof(timebuf
),
8183 strcpy(timebuf
, "-");
8185 pim_inet4_dump("<local?>", mp
->local
, local_str
,
8187 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
8188 pim_time_timer_to_hhmmss(katimer
, sizeof(katimer
),
8190 pim_time_timer_to_hhmmss(crtimer
, sizeof(crtimer
),
8192 pim_time_timer_to_hhmmss(holdtimer
, sizeof(holdtimer
),
8196 json_row
= json_object_new_object();
8197 json_object_string_add(json_row
, "peer", peer_str
);
8198 json_object_string_add(json_row
, "local", local_str
);
8199 json_object_string_add(json_row
, "meshGroupName",
8200 mp
->mesh_group_name
);
8201 json_object_string_add(json_row
, "state", state_str
);
8202 json_object_string_add(json_row
, "upTime", timebuf
);
8203 json_object_string_add(json_row
, "keepAliveTimer",
8205 json_object_string_add(json_row
, "connRetryTimer",
8207 json_object_string_add(json_row
, "holdTimer",
8209 json_object_string_add(json_row
, "lastReset",
8211 json_object_int_add(json_row
, "connAttempts",
8213 json_object_int_add(json_row
, "establishedChanges",
8215 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
8216 json_object_int_add(json_row
, "kaSent", mp
->ka_tx_cnt
);
8217 json_object_int_add(json_row
, "kaRcvd", mp
->ka_rx_cnt
);
8218 json_object_int_add(json_row
, "saSent", mp
->sa_tx_cnt
);
8219 json_object_int_add(json_row
, "saRcvd", mp
->sa_rx_cnt
);
8220 json_object_object_add(json
, peer_str
, json_row
);
8222 vty_out(vty
, "Peer : %s\n", peer_str
);
8223 vty_out(vty
, " Local : %s\n", local_str
);
8224 vty_out(vty
, " Mesh Group : %s\n",
8225 mp
->mesh_group_name
);
8226 vty_out(vty
, " State : %s\n", state_str
);
8227 vty_out(vty
, " Uptime : %s\n", timebuf
);
8229 vty_out(vty
, " Keepalive Timer : %s\n", katimer
);
8230 vty_out(vty
, " Conn Retry Timer : %s\n", crtimer
);
8231 vty_out(vty
, " Hold Timer : %s\n", holdtimer
);
8232 vty_out(vty
, " Last Reset : %s\n",
8234 vty_out(vty
, " Conn Attempts : %d\n",
8236 vty_out(vty
, " Established Changes : %d\n",
8238 vty_out(vty
, " SA Count : %d\n",
8240 vty_out(vty
, " Statistics :\n");
8243 vty_out(vty
, " Keepalives : %10d %10d\n",
8244 mp
->ka_tx_cnt
, mp
->ka_rx_cnt
);
8245 vty_out(vty
, " SAs : %10d %10d\n",
8246 mp
->sa_tx_cnt
, mp
->sa_rx_cnt
);
8252 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8253 json
, JSON_C_TO_STRING_PRETTY
));
8254 json_object_free(json
);
8258 DEFUN (show_ip_msdp_peer_detail
,
8259 show_ip_msdp_peer_detail_cmd
,
8260 "show ip msdp [vrf NAME] peer [detail|A.B.C.D] [json]",
8265 "MSDP peer information\n"
8270 bool uj
= use_json(argc
, argv
);
8272 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
8279 if (argv_find(argv
, argc
, "detail", &idx
))
8280 arg
= argv
[idx
]->text
;
8281 else if (argv_find(argv
, argc
, "A.B.C.D", &idx
))
8282 arg
= argv
[idx
]->arg
;
8285 ip_msdp_show_peers_detail(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
8287 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
8292 DEFUN (show_ip_msdp_peer_detail_vrf_all
,
8293 show_ip_msdp_peer_detail_vrf_all_cmd
,
8294 "show ip msdp vrf all peer [detail|A.B.C.D] [json]",
8299 "MSDP peer information\n"
8305 bool uj
= use_json(argc
, argv
);
8311 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
8315 vty_out(vty
, " \"%s\": ", vrf
->name
);
8318 vty_out(vty
, "VRF: %s\n", vrf
->name
);
8319 if (argv_find(argv
, argc
, "detail", &idx
)
8320 || argv_find(argv
, argc
, "A.B.C.D", &idx
))
8321 ip_msdp_show_peers_detail(vrf
->info
, vty
,
8322 argv
[idx
]->arg
, uj
);
8324 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
8327 vty_out(vty
, "}\n");
8332 static void ip_msdp_show_sa(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
8334 struct listnode
*sanode
;
8335 struct pim_msdp_sa
*sa
;
8336 char src_str
[INET_ADDRSTRLEN
];
8337 char grp_str
[INET_ADDRSTRLEN
];
8338 char rp_str
[INET_ADDRSTRLEN
];
8339 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
8343 json_object
*json
= NULL
;
8344 json_object
*json_group
= NULL
;
8345 json_object
*json_row
= NULL
;
8348 json
= json_object_new_object();
8351 "Source Group RP Local SPT Uptime\n");
8354 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
8355 now
= pim_time_monotonic_sec();
8356 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
8357 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
8358 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
8359 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
8360 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
8362 strcpy(spt_str
, "yes");
8364 strcpy(spt_str
, "no");
8367 strcpy(rp_str
, "-");
8368 strcpy(spt_str
, "-");
8370 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
8371 strcpy(local_str
, "yes");
8373 strcpy(local_str
, "no");
8376 json_object_object_get_ex(json
, grp_str
, &json_group
);
8379 json_group
= json_object_new_object();
8380 json_object_object_add(json
, grp_str
,
8384 json_row
= json_object_new_object();
8385 json_object_string_add(json_row
, "source", src_str
);
8386 json_object_string_add(json_row
, "group", grp_str
);
8387 json_object_string_add(json_row
, "rp", rp_str
);
8388 json_object_string_add(json_row
, "local", local_str
);
8389 json_object_string_add(json_row
, "sptSetup", spt_str
);
8390 json_object_string_add(json_row
, "upTime", timebuf
);
8391 json_object_object_add(json_group
, src_str
, json_row
);
8393 vty_out(vty
, "%-15s %15s %15s %5c %3c %8s\n",
8394 src_str
, grp_str
, rp_str
, local_str
[0],
8395 spt_str
[0], timebuf
);
8400 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8401 json
, JSON_C_TO_STRING_PRETTY
));
8402 json_object_free(json
);
8406 static void ip_msdp_show_sa_entry_detail(struct pim_msdp_sa
*sa
,
8407 const char *src_str
,
8408 const char *grp_str
, struct vty
*vty
,
8409 bool uj
, json_object
*json
)
8411 char rp_str
[INET_ADDRSTRLEN
];
8412 char peer_str
[INET_ADDRSTRLEN
];
8413 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
8416 char statetimer
[PIM_MSDP_TIMER_STRLEN
];
8418 json_object
*json_group
= NULL
;
8419 json_object
*json_row
= NULL
;
8421 now
= pim_time_monotonic_sec();
8422 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
8423 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
8424 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
8425 pim_inet4_dump("<peer?>", sa
->peer
, peer_str
, sizeof(peer_str
));
8427 strcpy(spt_str
, "yes");
8429 strcpy(spt_str
, "no");
8432 strcpy(rp_str
, "-");
8433 strcpy(peer_str
, "-");
8434 strcpy(spt_str
, "-");
8436 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
8437 strcpy(local_str
, "yes");
8439 strcpy(local_str
, "no");
8441 pim_time_timer_to_hhmmss(statetimer
, sizeof(statetimer
),
8442 sa
->sa_state_timer
);
8444 json_object_object_get_ex(json
, grp_str
, &json_group
);
8447 json_group
= json_object_new_object();
8448 json_object_object_add(json
, grp_str
, json_group
);
8451 json_row
= json_object_new_object();
8452 json_object_string_add(json_row
, "source", src_str
);
8453 json_object_string_add(json_row
, "group", grp_str
);
8454 json_object_string_add(json_row
, "rp", rp_str
);
8455 json_object_string_add(json_row
, "local", local_str
);
8456 json_object_string_add(json_row
, "sptSetup", spt_str
);
8457 json_object_string_add(json_row
, "upTime", timebuf
);
8458 json_object_string_add(json_row
, "stateTimer", statetimer
);
8459 json_object_object_add(json_group
, src_str
, json_row
);
8461 vty_out(vty
, "SA : %s\n", sa
->sg_str
);
8462 vty_out(vty
, " RP : %s\n", rp_str
);
8463 vty_out(vty
, " Peer : %s\n", peer_str
);
8464 vty_out(vty
, " Local : %s\n", local_str
);
8465 vty_out(vty
, " SPT Setup : %s\n", spt_str
);
8466 vty_out(vty
, " Uptime : %s\n", timebuf
);
8467 vty_out(vty
, " State Timer : %s\n", statetimer
);
8472 static void ip_msdp_show_sa_detail(struct pim_instance
*pim
, struct vty
*vty
,
8475 struct listnode
*sanode
;
8476 struct pim_msdp_sa
*sa
;
8477 char src_str
[INET_ADDRSTRLEN
];
8478 char grp_str
[INET_ADDRSTRLEN
];
8479 json_object
*json
= NULL
;
8482 json
= json_object_new_object();
8485 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
8486 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
8487 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
8488 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
, uj
,
8493 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8494 json
, JSON_C_TO_STRING_PRETTY
));
8495 json_object_free(json
);
8499 DEFUN (show_ip_msdp_sa_detail
,
8500 show_ip_msdp_sa_detail_cmd
,
8501 "show ip msdp [vrf NAME] sa detail [json]",
8506 "MSDP active-source information\n"
8510 bool uj
= use_json(argc
, argv
);
8512 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
8517 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
8522 DEFUN (show_ip_msdp_sa_detail_vrf_all
,
8523 show_ip_msdp_sa_detail_vrf_all_cmd
,
8524 "show ip msdp vrf all sa detail [json]",
8529 "MSDP active-source information\n"
8533 bool uj
= use_json(argc
, argv
);
8539 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
8543 vty_out(vty
, " \"%s\": ", vrf
->name
);
8546 vty_out(vty
, "VRF: %s\n", vrf
->name
);
8547 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
8550 vty_out(vty
, "}\n");
8555 static void ip_msdp_show_sa_addr(struct pim_instance
*pim
, struct vty
*vty
,
8556 const char *addr
, bool uj
)
8558 struct listnode
*sanode
;
8559 struct pim_msdp_sa
*sa
;
8560 char src_str
[INET_ADDRSTRLEN
];
8561 char grp_str
[INET_ADDRSTRLEN
];
8562 json_object
*json
= NULL
;
8565 json
= json_object_new_object();
8568 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
8569 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
8570 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
8571 if (!strcmp(addr
, src_str
) || !strcmp(addr
, grp_str
)) {
8572 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
8578 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8579 json
, JSON_C_TO_STRING_PRETTY
));
8580 json_object_free(json
);
8584 static void ip_msdp_show_sa_sg(struct pim_instance
*pim
, struct vty
*vty
,
8585 const char *src
, const char *grp
, bool uj
)
8587 struct listnode
*sanode
;
8588 struct pim_msdp_sa
*sa
;
8589 char src_str
[INET_ADDRSTRLEN
];
8590 char grp_str
[INET_ADDRSTRLEN
];
8591 json_object
*json
= NULL
;
8594 json
= json_object_new_object();
8597 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
8598 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
8599 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
8600 if (!strcmp(src
, src_str
) && !strcmp(grp
, grp_str
)) {
8601 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
8607 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8608 json
, JSON_C_TO_STRING_PRETTY
));
8609 json_object_free(json
);
8613 DEFUN (show_ip_msdp_sa_sg
,
8614 show_ip_msdp_sa_sg_cmd
,
8615 "show ip msdp [vrf NAME] sa [A.B.C.D [A.B.C.D]] [json]",
8620 "MSDP active-source information\n"
8621 "source or group ip\n"
8625 bool uj
= use_json(argc
, argv
);
8629 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
8634 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
8636 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
8640 if (src_ip
&& grp_ip
)
8641 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
8643 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
8645 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
8650 DEFUN (show_ip_msdp_sa_sg_vrf_all
,
8651 show_ip_msdp_sa_sg_vrf_all_cmd
,
8652 "show ip msdp vrf all sa [A.B.C.D [A.B.C.D]] [json]",
8657 "MSDP active-source information\n"
8658 "source or group ip\n"
8662 bool uj
= use_json(argc
, argv
);
8667 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
8669 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
8675 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
8679 vty_out(vty
, " \"%s\": ", vrf
->name
);
8682 vty_out(vty
, "VRF: %s\n", vrf
->name
);
8684 if (src_ip
&& grp_ip
)
8685 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
8687 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
8689 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
8692 vty_out(vty
, "}\n");
8697 void pim_cmd_init(void)
8699 install_node(&interface_node
,
8700 pim_interface_config_write
); /* INTERFACE_NODE */
8703 install_node(&debug_node
, pim_debug_config_write
);
8705 install_element(ENABLE_NODE
, &pim_test_sg_keepalive_cmd
);
8707 install_element(CONFIG_NODE
, &ip_pim_rp_cmd
);
8708 install_element(VRF_NODE
, &ip_pim_rp_cmd
);
8709 install_element(CONFIG_NODE
, &no_ip_pim_rp_cmd
);
8710 install_element(VRF_NODE
, &no_ip_pim_rp_cmd
);
8711 install_element(CONFIG_NODE
, &ip_pim_rp_prefix_list_cmd
);
8712 install_element(VRF_NODE
, &ip_pim_rp_prefix_list_cmd
);
8713 install_element(CONFIG_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
8714 install_element(VRF_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
8715 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
8716 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
8717 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
8718 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
8719 install_element(CONFIG_NODE
, &ip_pim_ssm_prefix_list_cmd
);
8720 install_element(VRF_NODE
, &ip_pim_ssm_prefix_list_cmd
);
8721 install_element(CONFIG_NODE
, &ip_pim_register_suppress_cmd
);
8722 install_element(VRF_NODE
, &ip_pim_register_suppress_cmd
);
8723 install_element(CONFIG_NODE
, &no_ip_pim_register_suppress_cmd
);
8724 install_element(VRF_NODE
, &no_ip_pim_register_suppress_cmd
);
8725 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
8726 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
8727 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
8728 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
8729 install_element(CONFIG_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
8730 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
8731 install_element(CONFIG_NODE
,
8732 &no_ip_pim_spt_switchover_infinity_plist_cmd
);
8733 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_plist_cmd
);
8734 install_element(CONFIG_NODE
, &ip_pim_joinprune_time_cmd
);
8735 install_element(VRF_NODE
, &ip_pim_joinprune_time_cmd
);
8736 install_element(CONFIG_NODE
, &no_ip_pim_joinprune_time_cmd
);
8737 install_element(VRF_NODE
, &no_ip_pim_joinprune_time_cmd
);
8738 install_element(CONFIG_NODE
, &ip_pim_keep_alive_cmd
);
8739 install_element(VRF_NODE
, &ip_pim_keep_alive_cmd
);
8740 install_element(CONFIG_NODE
, &ip_pim_rp_keep_alive_cmd
);
8741 install_element(VRF_NODE
, &ip_pim_rp_keep_alive_cmd
);
8742 install_element(CONFIG_NODE
, &no_ip_pim_keep_alive_cmd
);
8743 install_element(VRF_NODE
, &no_ip_pim_keep_alive_cmd
);
8744 install_element(CONFIG_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
8745 install_element(VRF_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
8746 install_element(CONFIG_NODE
, &ip_pim_packets_cmd
);
8747 install_element(VRF_NODE
, &ip_pim_packets_cmd
);
8748 install_element(CONFIG_NODE
, &no_ip_pim_packets_cmd
);
8749 install_element(VRF_NODE
, &no_ip_pim_packets_cmd
);
8750 install_element(CONFIG_NODE
, &ip_pim_v6_secondary_cmd
);
8751 install_element(VRF_NODE
, &ip_pim_v6_secondary_cmd
);
8752 install_element(CONFIG_NODE
, &no_ip_pim_v6_secondary_cmd
);
8753 install_element(VRF_NODE
, &no_ip_pim_v6_secondary_cmd
);
8754 install_element(CONFIG_NODE
, &ip_ssmpingd_cmd
);
8755 install_element(VRF_NODE
, &ip_ssmpingd_cmd
);
8756 install_element(CONFIG_NODE
, &no_ip_ssmpingd_cmd
);
8757 install_element(VRF_NODE
, &no_ip_ssmpingd_cmd
);
8758 install_element(CONFIG_NODE
, &ip_msdp_peer_cmd
);
8759 install_element(VRF_NODE
, &ip_msdp_peer_cmd
);
8760 install_element(CONFIG_NODE
, &no_ip_msdp_peer_cmd
);
8761 install_element(VRF_NODE
, &no_ip_msdp_peer_cmd
);
8762 install_element(CONFIG_NODE
, &ip_pim_ecmp_cmd
);
8763 install_element(VRF_NODE
, &ip_pim_ecmp_cmd
);
8764 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_cmd
);
8765 install_element(VRF_NODE
, &no_ip_pim_ecmp_cmd
);
8766 install_element(CONFIG_NODE
, &ip_pim_ecmp_rebalance_cmd
);
8767 install_element(VRF_NODE
, &ip_pim_ecmp_rebalance_cmd
);
8768 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
8769 install_element(VRF_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
8771 install_element(INTERFACE_NODE
, &interface_ip_igmp_cmd
);
8772 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_cmd
);
8773 install_element(INTERFACE_NODE
, &interface_ip_igmp_join_cmd
);
8774 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_join_cmd
);
8775 install_element(INTERFACE_NODE
, &interface_ip_igmp_version_cmd
);
8776 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_version_cmd
);
8777 install_element(INTERFACE_NODE
, &interface_ip_igmp_query_interval_cmd
);
8778 install_element(INTERFACE_NODE
,
8779 &interface_no_ip_igmp_query_interval_cmd
);
8780 install_element(INTERFACE_NODE
,
8781 &interface_ip_igmp_query_max_response_time_cmd
);
8782 install_element(INTERFACE_NODE
,
8783 &interface_no_ip_igmp_query_max_response_time_cmd
);
8784 install_element(INTERFACE_NODE
,
8785 &interface_ip_igmp_query_max_response_time_dsec_cmd
);
8786 install_element(INTERFACE_NODE
,
8787 &interface_no_ip_igmp_query_max_response_time_dsec_cmd
);
8788 install_element(INTERFACE_NODE
, &interface_ip_pim_activeactive_cmd
);
8789 install_element(INTERFACE_NODE
, &interface_ip_pim_ssm_cmd
);
8790 install_element(INTERFACE_NODE
, &interface_no_ip_pim_ssm_cmd
);
8791 install_element(INTERFACE_NODE
, &interface_ip_pim_sm_cmd
);
8792 install_element(INTERFACE_NODE
, &interface_no_ip_pim_sm_cmd
);
8793 install_element(INTERFACE_NODE
, &interface_ip_pim_cmd
);
8794 install_element(INTERFACE_NODE
, &interface_no_ip_pim_cmd
);
8795 install_element(INTERFACE_NODE
, &interface_ip_pim_drprio_cmd
);
8796 install_element(INTERFACE_NODE
, &interface_no_ip_pim_drprio_cmd
);
8797 install_element(INTERFACE_NODE
, &interface_ip_pim_hello_cmd
);
8798 install_element(INTERFACE_NODE
, &interface_no_ip_pim_hello_cmd
);
8799 install_element(INTERFACE_NODE
, &interface_ip_pim_boundary_oil_cmd
);
8800 install_element(INTERFACE_NODE
, &interface_no_ip_pim_boundary_oil_cmd
);
8802 // Static mroutes NEB
8803 install_element(INTERFACE_NODE
, &interface_ip_mroute_cmd
);
8804 install_element(INTERFACE_NODE
, &interface_ip_mroute_source_cmd
);
8805 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_cmd
);
8806 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_source_cmd
);
8808 install_element(VIEW_NODE
, &show_ip_igmp_interface_cmd
);
8809 install_element(VIEW_NODE
, &show_ip_igmp_interface_vrf_all_cmd
);
8810 install_element(VIEW_NODE
, &show_ip_igmp_join_cmd
);
8811 install_element(VIEW_NODE
, &show_ip_igmp_join_vrf_all_cmd
);
8812 install_element(VIEW_NODE
, &show_ip_igmp_groups_cmd
);
8813 install_element(VIEW_NODE
, &show_ip_igmp_groups_vrf_all_cmd
);
8814 install_element(VIEW_NODE
, &show_ip_igmp_groups_retransmissions_cmd
);
8815 install_element(VIEW_NODE
, &show_ip_igmp_sources_cmd
);
8816 install_element(VIEW_NODE
, &show_ip_igmp_sources_retransmissions_cmd
);
8817 install_element(VIEW_NODE
, &show_ip_igmp_statistics_cmd
);
8818 install_element(VIEW_NODE
, &show_ip_pim_assert_cmd
);
8819 install_element(VIEW_NODE
, &show_ip_pim_assert_internal_cmd
);
8820 install_element(VIEW_NODE
, &show_ip_pim_assert_metric_cmd
);
8821 install_element(VIEW_NODE
, &show_ip_pim_assert_winner_metric_cmd
);
8822 install_element(VIEW_NODE
, &show_ip_pim_interface_traffic_cmd
);
8823 install_element(VIEW_NODE
, &show_ip_pim_interface_cmd
);
8824 install_element(VIEW_NODE
, &show_ip_pim_interface_vrf_all_cmd
);
8825 install_element(VIEW_NODE
, &show_ip_pim_join_cmd
);
8826 install_element(VIEW_NODE
, &show_ip_pim_join_vrf_all_cmd
);
8827 install_element(VIEW_NODE
, &show_ip_pim_local_membership_cmd
);
8828 install_element(VIEW_NODE
, &show_ip_pim_neighbor_cmd
);
8829 install_element(VIEW_NODE
, &show_ip_pim_neighbor_vrf_all_cmd
);
8830 install_element(VIEW_NODE
, &show_ip_pim_rpf_cmd
);
8831 install_element(VIEW_NODE
, &show_ip_pim_rpf_vrf_all_cmd
);
8832 install_element(VIEW_NODE
, &show_ip_pim_secondary_cmd
);
8833 install_element(VIEW_NODE
, &show_ip_pim_state_cmd
);
8834 install_element(VIEW_NODE
, &show_ip_pim_state_vrf_all_cmd
);
8835 install_element(VIEW_NODE
, &show_ip_pim_upstream_cmd
);
8836 install_element(VIEW_NODE
, &show_ip_pim_upstream_vrf_all_cmd
);
8837 install_element(VIEW_NODE
, &show_ip_pim_upstream_join_desired_cmd
);
8838 install_element(VIEW_NODE
, &show_ip_pim_upstream_rpf_cmd
);
8839 install_element(VIEW_NODE
, &show_ip_pim_rp_cmd
);
8840 install_element(VIEW_NODE
, &show_ip_pim_rp_vrf_all_cmd
);
8841 install_element(VIEW_NODE
, &show_ip_multicast_cmd
);
8842 install_element(VIEW_NODE
, &show_ip_multicast_vrf_all_cmd
);
8843 install_element(VIEW_NODE
, &show_ip_mroute_cmd
);
8844 install_element(VIEW_NODE
, &show_ip_mroute_vrf_all_cmd
);
8845 install_element(VIEW_NODE
, &show_ip_mroute_count_cmd
);
8846 install_element(VIEW_NODE
, &show_ip_mroute_count_vrf_all_cmd
);
8847 install_element(VIEW_NODE
, &show_ip_rib_cmd
);
8848 install_element(VIEW_NODE
, &show_ip_ssmpingd_cmd
);
8849 install_element(VIEW_NODE
, &show_debugging_pim_cmd
);
8850 install_element(VIEW_NODE
, &show_ip_pim_nexthop_cmd
);
8851 install_element(VIEW_NODE
, &show_ip_pim_nexthop_lookup_cmd
);
8853 install_element(ENABLE_NODE
, &clear_ip_interfaces_cmd
);
8854 install_element(ENABLE_NODE
, &clear_ip_igmp_interfaces_cmd
);
8855 install_element(ENABLE_NODE
, &clear_ip_mroute_cmd
);
8856 install_element(ENABLE_NODE
, &clear_ip_pim_interfaces_cmd
);
8857 install_element(ENABLE_NODE
, &clear_ip_pim_interface_traffic_cmd
);
8858 install_element(ENABLE_NODE
, &clear_ip_pim_oil_cmd
);
8860 install_element(ENABLE_NODE
, &debug_igmp_cmd
);
8861 install_element(ENABLE_NODE
, &no_debug_igmp_cmd
);
8862 install_element(ENABLE_NODE
, &debug_igmp_events_cmd
);
8863 install_element(ENABLE_NODE
, &no_debug_igmp_events_cmd
);
8864 install_element(ENABLE_NODE
, &debug_igmp_packets_cmd
);
8865 install_element(ENABLE_NODE
, &no_debug_igmp_packets_cmd
);
8866 install_element(ENABLE_NODE
, &debug_igmp_trace_cmd
);
8867 install_element(ENABLE_NODE
, &no_debug_igmp_trace_cmd
);
8868 install_element(ENABLE_NODE
, &debug_mroute_cmd
);
8869 install_element(ENABLE_NODE
, &debug_mroute_detail_cmd
);
8870 install_element(ENABLE_NODE
, &no_debug_mroute_cmd
);
8871 install_element(ENABLE_NODE
, &no_debug_mroute_detail_cmd
);
8872 install_element(ENABLE_NODE
, &debug_pim_static_cmd
);
8873 install_element(ENABLE_NODE
, &no_debug_pim_static_cmd
);
8874 install_element(ENABLE_NODE
, &debug_pim_cmd
);
8875 install_element(ENABLE_NODE
, &no_debug_pim_cmd
);
8876 install_element(ENABLE_NODE
, &debug_pim_nht_cmd
);
8877 install_element(ENABLE_NODE
, &no_debug_pim_nht_cmd
);
8878 install_element(ENABLE_NODE
, &debug_pim_nht_rp_cmd
);
8879 install_element(ENABLE_NODE
, &no_debug_pim_nht_rp_cmd
);
8880 install_element(ENABLE_NODE
, &debug_pim_events_cmd
);
8881 install_element(ENABLE_NODE
, &no_debug_pim_events_cmd
);
8882 install_element(ENABLE_NODE
, &debug_pim_packets_cmd
);
8883 install_element(ENABLE_NODE
, &no_debug_pim_packets_cmd
);
8884 install_element(ENABLE_NODE
, &debug_pim_packetdump_send_cmd
);
8885 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_send_cmd
);
8886 install_element(ENABLE_NODE
, &debug_pim_packetdump_recv_cmd
);
8887 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_recv_cmd
);
8888 install_element(ENABLE_NODE
, &debug_pim_trace_cmd
);
8889 install_element(ENABLE_NODE
, &no_debug_pim_trace_cmd
);
8890 install_element(ENABLE_NODE
, &debug_pim_trace_detail_cmd
);
8891 install_element(ENABLE_NODE
, &no_debug_pim_trace_detail_cmd
);
8892 install_element(ENABLE_NODE
, &debug_ssmpingd_cmd
);
8893 install_element(ENABLE_NODE
, &no_debug_ssmpingd_cmd
);
8894 install_element(ENABLE_NODE
, &debug_pim_zebra_cmd
);
8895 install_element(ENABLE_NODE
, &no_debug_pim_zebra_cmd
);
8896 install_element(ENABLE_NODE
, &debug_msdp_cmd
);
8897 install_element(ENABLE_NODE
, &no_debug_msdp_cmd
);
8898 install_element(ENABLE_NODE
, &debug_msdp_events_cmd
);
8899 install_element(ENABLE_NODE
, &no_debug_msdp_events_cmd
);
8900 install_element(ENABLE_NODE
, &debug_msdp_packets_cmd
);
8901 install_element(ENABLE_NODE
, &no_debug_msdp_packets_cmd
);
8902 install_element(ENABLE_NODE
, &debug_mtrace_cmd
);
8903 install_element(ENABLE_NODE
, &no_debug_mtrace_cmd
);
8905 install_element(CONFIG_NODE
, &debug_igmp_cmd
);
8906 install_element(CONFIG_NODE
, &no_debug_igmp_cmd
);
8907 install_element(CONFIG_NODE
, &debug_igmp_events_cmd
);
8908 install_element(CONFIG_NODE
, &no_debug_igmp_events_cmd
);
8909 install_element(CONFIG_NODE
, &debug_igmp_packets_cmd
);
8910 install_element(CONFIG_NODE
, &no_debug_igmp_packets_cmd
);
8911 install_element(CONFIG_NODE
, &debug_igmp_trace_cmd
);
8912 install_element(CONFIG_NODE
, &no_debug_igmp_trace_cmd
);
8913 install_element(CONFIG_NODE
, &debug_mroute_cmd
);
8914 install_element(CONFIG_NODE
, &debug_mroute_detail_cmd
);
8915 install_element(CONFIG_NODE
, &no_debug_mroute_cmd
);
8916 install_element(CONFIG_NODE
, &no_debug_mroute_detail_cmd
);
8917 install_element(CONFIG_NODE
, &debug_pim_static_cmd
);
8918 install_element(CONFIG_NODE
, &no_debug_pim_static_cmd
);
8919 install_element(CONFIG_NODE
, &debug_pim_cmd
);
8920 install_element(CONFIG_NODE
, &no_debug_pim_cmd
);
8921 install_element(CONFIG_NODE
, &debug_pim_nht_cmd
);
8922 install_element(CONFIG_NODE
, &no_debug_pim_nht_cmd
);
8923 install_element(CONFIG_NODE
, &debug_pim_nht_rp_cmd
);
8924 install_element(CONFIG_NODE
, &no_debug_pim_nht_rp_cmd
);
8925 install_element(CONFIG_NODE
, &debug_pim_events_cmd
);
8926 install_element(CONFIG_NODE
, &no_debug_pim_events_cmd
);
8927 install_element(CONFIG_NODE
, &debug_pim_packets_cmd
);
8928 install_element(CONFIG_NODE
, &no_debug_pim_packets_cmd
);
8929 install_element(CONFIG_NODE
, &debug_pim_trace_cmd
);
8930 install_element(CONFIG_NODE
, &no_debug_pim_trace_cmd
);
8931 install_element(CONFIG_NODE
, &debug_pim_trace_detail_cmd
);
8932 install_element(CONFIG_NODE
, &no_debug_pim_trace_detail_cmd
);
8933 install_element(CONFIG_NODE
, &debug_ssmpingd_cmd
);
8934 install_element(CONFIG_NODE
, &no_debug_ssmpingd_cmd
);
8935 install_element(CONFIG_NODE
, &debug_pim_zebra_cmd
);
8936 install_element(CONFIG_NODE
, &no_debug_pim_zebra_cmd
);
8937 install_element(CONFIG_NODE
, &debug_msdp_cmd
);
8938 install_element(CONFIG_NODE
, &no_debug_msdp_cmd
);
8939 install_element(CONFIG_NODE
, &debug_msdp_events_cmd
);
8940 install_element(CONFIG_NODE
, &no_debug_msdp_events_cmd
);
8941 install_element(CONFIG_NODE
, &debug_msdp_packets_cmd
);
8942 install_element(CONFIG_NODE
, &no_debug_msdp_packets_cmd
);
8943 install_element(CONFIG_NODE
, &debug_mtrace_cmd
);
8944 install_element(CONFIG_NODE
, &no_debug_mtrace_cmd
);
8946 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_member_cmd
);
8947 install_element(VRF_NODE
, &ip_msdp_mesh_group_member_cmd
);
8948 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
8949 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
8950 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_source_cmd
);
8951 install_element(VRF_NODE
, &ip_msdp_mesh_group_source_cmd
);
8952 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
8953 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
8954 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_cmd
);
8955 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_vrf_all_cmd
);
8956 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_cmd
);
8957 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_vrf_all_cmd
);
8958 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_cmd
);
8959 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_vrf_all_cmd
);
8960 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_cmd
);
8961 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_vrf_all_cmd
);
8962 install_element(VIEW_NODE
, &show_ip_pim_ssm_range_cmd
);
8963 install_element(VIEW_NODE
, &show_ip_pim_group_type_cmd
);
8964 install_element(INTERFACE_NODE
, &interface_pim_use_source_cmd
);
8965 install_element(INTERFACE_NODE
, &interface_no_pim_use_source_cmd
);
8966 /* Install BFD command */
8967 install_element(INTERFACE_NODE
, &ip_pim_bfd_cmd
);
8968 install_element(INTERFACE_NODE
, &ip_pim_bfd_param_cmd
);
8969 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_cmd
);
8971 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_param_cmd
);
8972 #endif /* !HAVE_BFDD */