3 * Copyright (C) 2008 Everton da Silva Marques
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; see the file COPYING; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
34 #include "pim_mroute.h"
36 #include "pim_iface.h"
38 #include "pim_mroute.h"
41 #include "pim_igmpv3.h"
46 #include "pim_neighbor.h"
48 #include "pim_ifchannel.h"
49 #include "pim_hello.h"
51 #include "pim_upstream.h"
53 #include "pim_macro.h"
54 #include "pim_ssmpingd.h"
55 #include "pim_zebra.h"
56 #include "pim_static.h"
58 #include "pim_zlookup.h"
65 static struct cmd_node interface_node
= {
66 INTERFACE_NODE
, "%s(config-if)# ", 1 /* vtysh ? yes */
69 static struct cmd_node debug_node
= {DEBUG_NODE
, "", 1};
71 static struct vrf
*pim_cmd_lookup_vrf(struct vty
*vty
, struct cmd_token
*argv
[],
72 const int argc
, int *idx
)
76 if (argv_find(argv
, argc
, "NAME", idx
))
77 vrf
= vrf_lookup_by_name(argv
[*idx
]->arg
);
79 vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
82 vty_out(vty
, "Specified VRF: %s does not exist\n",
88 static void pim_if_membership_clear(struct interface
*ifp
)
90 struct pim_interface
*pim_ifp
;
95 if (PIM_IF_TEST_PIM(pim_ifp
->options
)
96 && PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
100 pim_ifchannel_membership_clear(ifp
);
104 When PIM is disabled on interface, IGMPv3 local membership
105 information is not injected into PIM interface state.
107 The function pim_if_membership_refresh() fetches all IGMPv3 local
108 membership information into PIM. It is intented to be called
109 whenever PIM is enabled on the interface in order to collect missed
110 local membership information.
112 static void pim_if_membership_refresh(struct interface
*ifp
)
114 struct pim_interface
*pim_ifp
;
115 struct listnode
*sock_node
;
116 struct igmp_sock
*igmp
;
121 if (!PIM_IF_TEST_PIM(pim_ifp
->options
))
123 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
))
127 First clear off membership from all PIM (S,G) entries on the
131 pim_ifchannel_membership_clear(ifp
);
134 Then restore PIM (S,G) membership from all IGMPv3 (S,G) entries on
138 /* scan igmp sockets */
139 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
140 struct listnode
*grpnode
;
141 struct igmp_group
*grp
;
143 /* scan igmp groups */
144 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grpnode
,
146 struct listnode
*srcnode
;
147 struct igmp_source
*src
;
149 /* scan group sources */
150 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
,
153 if (IGMP_SOURCE_TEST_FORWARDING(
154 src
->source_flags
)) {
158 sizeof(struct prefix_sg
));
159 sg
.src
= src
->source_addr
;
160 sg
.grp
= grp
->group_addr
;
161 pim_ifchannel_local_membership_add(ifp
,
165 } /* scan group sources */
166 } /* scan igmp groups */
167 } /* scan igmp sockets */
170 Finally delete every PIM (S,G) entry lacking all state info
173 pim_ifchannel_delete_on_noinfo(ifp
);
176 static void pim_show_assert_helper(struct vty
*vty
,
177 struct pim_interface
*pim_ifp
,
178 struct pim_ifchannel
*ch
, time_t now
)
180 char ch_src_str
[INET_ADDRSTRLEN
];
181 char ch_grp_str
[INET_ADDRSTRLEN
];
182 char winner_str
[INET_ADDRSTRLEN
];
183 struct in_addr ifaddr
;
187 ifaddr
= pim_ifp
->primary_address
;
189 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
190 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
191 pim_inet4_dump("<assrt_win?>", ch
->ifassert_winner
, winner_str
,
194 pim_time_uptime(uptime
, sizeof(uptime
), now
- ch
->ifassert_creation
);
195 pim_time_timer_to_mmss(timer
, sizeof(timer
), ch
->t_ifassert_timer
);
197 vty_out(vty
, "%-9s %-15s %-15s %-15s %-6s %-15s %-8s %-5s\n",
198 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
, ch_grp_str
,
199 pim_ifchannel_ifassert_name(ch
->ifassert_state
), winner_str
,
203 static void pim_show_assert(struct pim_instance
*pim
, struct vty
*vty
)
205 struct pim_interface
*pim_ifp
;
206 struct pim_ifchannel
*ch
;
207 struct interface
*ifp
;
210 now
= pim_time_monotonic_sec();
213 "Interface Address Source Group State Winner Uptime Timer\n");
215 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
220 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
221 pim_show_assert_helper(vty
, pim_ifp
, ch
, now
);
222 } /* scan interface channels */
226 static void pim_show_assert_internal_helper(struct vty
*vty
,
227 struct pim_interface
*pim_ifp
,
228 struct pim_ifchannel
*ch
)
230 char ch_src_str
[INET_ADDRSTRLEN
];
231 char ch_grp_str
[INET_ADDRSTRLEN
];
232 struct in_addr ifaddr
;
234 ifaddr
= pim_ifp
->primary_address
;
236 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
237 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
238 vty_out(vty
, "%-9s %-15s %-15s %-15s %-3s %-3s %-3s %-4s\n",
239 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
, ch_grp_str
,
240 PIM_IF_FLAG_TEST_COULD_ASSERT(ch
->flags
) ? "yes" : "no",
241 pim_macro_ch_could_assert_eval(ch
) ? "yes" : "no",
242 PIM_IF_FLAG_TEST_ASSERT_TRACKING_DESIRED(ch
->flags
) ? "yes"
244 pim_macro_assert_tracking_desired_eval(ch
) ? "yes" : "no");
247 static void pim_show_assert_internal(struct pim_instance
*pim
, struct vty
*vty
)
249 struct pim_interface
*pim_ifp
;
250 struct pim_ifchannel
*ch
;
251 struct interface
*ifp
;
255 "ECA: Evaluate CouldAssert\n"
256 "ATD: AssertTrackingDesired\n"
257 "eATD: Evaluate AssertTrackingDesired\n\n");
260 "Interface Address Source Group CA eCA ATD eATD\n");
261 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
266 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
267 pim_show_assert_internal_helper(vty
, pim_ifp
, ch
);
268 } /* scan interface channels */
272 static void pim_show_assert_metric_helper(struct vty
*vty
,
273 struct pim_interface
*pim_ifp
,
274 struct pim_ifchannel
*ch
)
276 char ch_src_str
[INET_ADDRSTRLEN
];
277 char ch_grp_str
[INET_ADDRSTRLEN
];
278 char addr_str
[INET_ADDRSTRLEN
];
279 struct pim_assert_metric am
;
280 struct in_addr ifaddr
;
282 ifaddr
= pim_ifp
->primary_address
;
284 am
= pim_macro_spt_assert_metric(&ch
->upstream
->rpf
,
285 pim_ifp
->primary_address
);
287 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
288 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
289 pim_inet4_dump("<addr?>", am
.ip_address
, addr_str
, sizeof(addr_str
));
291 vty_out(vty
, "%-9s %-15s %-15s %-15s %-3s %4u %6u %-15s\n",
292 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
, ch_grp_str
,
293 am
.rpt_bit_flag
? "yes" : "no", am
.metric_preference
,
294 am
.route_metric
, addr_str
);
297 static void pim_show_assert_metric(struct pim_instance
*pim
, struct vty
*vty
)
299 struct pim_interface
*pim_ifp
;
300 struct pim_ifchannel
*ch
;
301 struct interface
*ifp
;
304 "Interface Address Source Group RPT Pref Metric Address \n");
306 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
311 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
312 pim_show_assert_metric_helper(vty
, pim_ifp
, ch
);
313 } /* scan interface channels */
317 static void pim_show_assert_winner_metric_helper(struct vty
*vty
,
318 struct pim_interface
*pim_ifp
,
319 struct pim_ifchannel
*ch
)
321 char ch_src_str
[INET_ADDRSTRLEN
];
322 char ch_grp_str
[INET_ADDRSTRLEN
];
323 char addr_str
[INET_ADDRSTRLEN
];
324 struct pim_assert_metric
*am
;
325 struct in_addr ifaddr
;
329 ifaddr
= pim_ifp
->primary_address
;
331 am
= &ch
->ifassert_winner_metric
;
333 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
334 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
335 pim_inet4_dump("<addr?>", am
->ip_address
, addr_str
, sizeof(addr_str
));
337 if (am
->metric_preference
== PIM_ASSERT_METRIC_PREFERENCE_MAX
)
338 snprintf(pref_str
, sizeof(pref_str
), "INFI");
340 snprintf(pref_str
, sizeof(pref_str
), "%4u",
341 am
->metric_preference
);
343 if (am
->route_metric
== PIM_ASSERT_ROUTE_METRIC_MAX
)
344 snprintf(metr_str
, sizeof(metr_str
), "INFI");
346 snprintf(metr_str
, sizeof(metr_str
), "%6u", am
->route_metric
);
348 vty_out(vty
, "%-9s %-15s %-15s %-15s %-3s %-4s %-6s %-15s\n",
349 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
, ch_grp_str
,
350 am
->rpt_bit_flag
? "yes" : "no", pref_str
, metr_str
, addr_str
);
353 static void pim_show_assert_winner_metric(struct pim_instance
*pim
,
356 struct pim_interface
*pim_ifp
;
357 struct pim_ifchannel
*ch
;
358 struct interface
*ifp
;
361 "Interface Address Source Group RPT Pref Metric Address \n");
363 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
368 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
369 pim_show_assert_winner_metric_helper(vty
, pim_ifp
, ch
);
370 } /* scan interface channels */
374 static void json_object_pim_ifp_add(struct json_object
*json
,
375 struct interface
*ifp
)
377 struct pim_interface
*pim_ifp
;
380 json_object_string_add(json
, "name", ifp
->name
);
381 json_object_string_add(json
, "state", if_is_up(ifp
) ? "up" : "down");
382 json_object_string_add(json
, "address",
383 inet_ntoa(pim_ifp
->primary_address
));
384 json_object_int_add(json
, "index", ifp
->ifindex
);
386 if (if_is_multicast(ifp
))
387 json_object_boolean_true_add(json
, "flagMulticast");
389 if (if_is_broadcast(ifp
))
390 json_object_boolean_true_add(json
, "flagBroadcast");
392 if (ifp
->flags
& IFF_ALLMULTI
)
393 json_object_boolean_true_add(json
, "flagAllMulticast");
395 if (ifp
->flags
& IFF_PROMISC
)
396 json_object_boolean_true_add(json
, "flagPromiscuous");
398 if (PIM_IF_IS_DELETED(ifp
))
399 json_object_boolean_true_add(json
, "flagDeleted");
401 if (pim_if_lan_delay_enabled(ifp
))
402 json_object_boolean_true_add(json
, "lanDelayEnabled");
405 static void pim_show_membership_helper(struct vty
*vty
,
406 struct pim_interface
*pim_ifp
,
407 struct pim_ifchannel
*ch
,
408 struct json_object
*json
)
410 char ch_src_str
[INET_ADDRSTRLEN
];
411 char ch_grp_str
[INET_ADDRSTRLEN
];
412 json_object
*json_iface
= NULL
;
413 json_object
*json_row
= NULL
;
415 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
416 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
418 json_object_object_get_ex(json
, ch
->interface
->name
, &json_iface
);
420 json_iface
= json_object_new_object();
421 json_object_pim_ifp_add(json_iface
, ch
->interface
);
422 json_object_object_add(json
, ch
->interface
->name
, json_iface
);
425 json_row
= json_object_new_object();
426 json_object_string_add(json_row
, "source", ch_src_str
);
427 json_object_string_add(json_row
, "group", ch_grp_str
);
428 json_object_string_add(json_row
, "localMembership",
429 ch
->local_ifmembership
== PIM_IFMEMBERSHIP_NOINFO
432 json_object_object_add(json_iface
, ch_grp_str
, json_row
);
434 static void pim_show_membership(struct pim_instance
*pim
, struct vty
*vty
,
437 struct pim_interface
*pim_ifp
;
438 struct pim_ifchannel
*ch
;
439 struct interface
*ifp
;
441 json_object
*json
= NULL
;
442 json_object
*json_tmp
= NULL
;
444 json
= json_object_new_object();
446 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
451 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
452 pim_show_membership_helper(vty
, pim_ifp
, ch
, json
);
453 } /* scan interface channels */
457 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
458 json
, JSON_C_TO_STRING_PRETTY
));
461 "Interface Address Source Group Membership\n");
464 * Example of the json data we are traversing
470 * "address":"10.1.20.1",
472 * "flagMulticast":true,
473 * "flagBroadcast":true,
474 * "lanDelayEnabled":true,
477 * "group":"226.10.10.10",
478 * "localMembership":"INCLUDE"
484 /* foreach interface */
485 json_object_object_foreach(json
, key
, val
)
488 /* Find all of the keys where the val is an object. In
490 * above the only one is 226.10.10.10
492 json_object_object_foreach(val
, if_field_key
,
495 type
= json_object_get_type(if_field_val
);
497 if (type
== json_type_object
) {
498 vty_out(vty
, "%-9s ", key
);
500 json_object_object_get_ex(
501 val
, "address", &json_tmp
);
502 vty_out(vty
, "%-15s ",
503 json_object_get_string(
506 json_object_object_get_ex(if_field_val
,
509 vty_out(vty
, "%-15s ",
510 json_object_get_string(
514 vty_out(vty
, "%-15s ", if_field_key
);
516 json_object_object_get_ex(
517 if_field_val
, "localMembership",
519 vty_out(vty
, "%-10s\n",
520 json_object_get_string(
527 json_object_free(json
);
530 static void pim_print_ifp_flags(struct vty
*vty
, struct interface
*ifp
,
533 vty_out(vty
, "Flags\n");
534 vty_out(vty
, "-----\n");
535 vty_out(vty
, "All Multicast : %s\n",
536 (ifp
->flags
& IFF_ALLMULTI
) ? "yes" : "no");
537 vty_out(vty
, "Broadcast : %s\n",
538 if_is_broadcast(ifp
) ? "yes" : "no");
539 vty_out(vty
, "Deleted : %s\n",
540 PIM_IF_IS_DELETED(ifp
) ? "yes" : "no");
541 vty_out(vty
, "Interface Index : %d\n", ifp
->ifindex
);
542 vty_out(vty
, "Multicast : %s\n",
543 if_is_multicast(ifp
) ? "yes" : "no");
544 vty_out(vty
, "Multicast Loop : %d\n", mloop
);
545 vty_out(vty
, "Promiscuous : %s\n",
546 (ifp
->flags
& IFF_PROMISC
) ? "yes" : "no");
551 static void igmp_show_interfaces(struct pim_instance
*pim
, struct vty
*vty
,
554 struct interface
*ifp
;
556 json_object
*json
= NULL
;
557 json_object
*json_row
= NULL
;
559 now
= pim_time_monotonic_sec();
562 json
= json_object_new_object();
565 "Interface State Address V Querier Query Timer Uptime\n");
567 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
568 struct pim_interface
*pim_ifp
;
569 struct listnode
*sock_node
;
570 struct igmp_sock
*igmp
;
577 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
580 char query_hhmmss
[10];
582 pim_time_uptime(uptime
, sizeof(uptime
),
583 now
- igmp
->sock_creation
);
584 pim_time_timer_to_hhmmss(query_hhmmss
,
585 sizeof(query_hhmmss
),
586 igmp
->t_igmp_query_timer
);
589 json_row
= json_object_new_object();
590 json_object_pim_ifp_add(json_row
, ifp
);
591 json_object_string_add(json_row
, "upTime",
593 json_object_int_add(json_row
, "version",
594 pim_ifp
->igmp_version
);
596 if (igmp
->t_igmp_query_timer
) {
597 json_object_boolean_true_add(json_row
,
599 json_object_string_add(json_row
,
604 json_object_object_add(json
, ifp
->name
,
607 if (igmp
->mtrace_only
) {
608 json_object_boolean_true_add(
609 json_row
, "mtraceOnly");
613 "%-9s %5s %15s %d %7s %11s %8s\n",
616 ? (igmp
->mtrace_only
? "mtrc"
619 inet_ntoa(igmp
->ifaddr
),
620 pim_ifp
->igmp_version
,
621 igmp
->t_igmp_query_timer
? "local"
623 query_hhmmss
, uptime
);
629 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
630 json
, JSON_C_TO_STRING_PRETTY
));
631 json_object_free(json
);
635 static void igmp_show_interfaces_single(struct pim_instance
*pim
,
636 struct vty
*vty
, const char *ifname
,
639 struct igmp_sock
*igmp
;
640 struct interface
*ifp
;
641 struct listnode
*sock_node
;
642 struct pim_interface
*pim_ifp
;
644 char query_hhmmss
[10];
645 char other_hhmmss
[10];
646 int found_ifname
= 0;
649 long gmi_msec
; /* Group Membership Interval */
652 long oqpi_msec
; /* Other Querier Present Interval */
656 json_object
*json
= NULL
;
657 json_object
*json_row
= NULL
;
660 json
= json_object_new_object();
662 now
= pim_time_monotonic_sec();
664 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
670 if (strcmp(ifname
, "detail") && strcmp(ifname
, ifp
->name
))
673 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
676 pim_time_uptime(uptime
, sizeof(uptime
),
677 now
- igmp
->sock_creation
);
678 pim_time_timer_to_hhmmss(query_hhmmss
,
679 sizeof(query_hhmmss
),
680 igmp
->t_igmp_query_timer
);
681 pim_time_timer_to_hhmmss(other_hhmmss
,
682 sizeof(other_hhmmss
),
683 igmp
->t_other_querier_timer
);
685 gmi_msec
= PIM_IGMP_GMI_MSEC(
686 igmp
->querier_robustness_variable
,
687 igmp
->querier_query_interval
,
688 pim_ifp
->igmp_query_max_response_time_dsec
);
691 pim_ifp
->igmp_default_query_interval
);
693 oqpi_msec
= PIM_IGMP_OQPI_MSEC(
694 igmp
->querier_robustness_variable
,
695 igmp
->querier_query_interval
,
696 pim_ifp
->igmp_query_max_response_time_dsec
);
698 lmqt_msec
= PIM_IGMP_LMQT_MSEC(
699 pim_ifp
->igmp_query_max_response_time_dsec
,
700 igmp
->querier_robustness_variable
);
704 igmp
->querier_robustness_variable
,
705 igmp
->querier_query_interval
,
706 pim_ifp
->igmp_query_max_response_time_dsec
)
709 qri_msec
= pim_ifp
->igmp_query_max_response_time_dsec
711 if (pim_ifp
->pim_sock_fd
>= 0)
712 mloop
= pim_socket_mcastloop_get(
713 pim_ifp
->pim_sock_fd
);
718 json_row
= json_object_new_object();
719 json_object_pim_ifp_add(json_row
, ifp
);
720 json_object_string_add(json_row
, "upTime",
722 json_object_string_add(json_row
, "querier",
723 igmp
->t_igmp_query_timer
726 json_object_int_add(json_row
, "queryStartCount",
727 igmp
->startup_query_count
);
728 json_object_string_add(json_row
,
731 json_object_string_add(json_row
,
734 json_object_int_add(json_row
, "version",
735 pim_ifp
->igmp_version
);
738 "timerGroupMembershipIntervalMsec",
740 json_object_int_add(json_row
,
741 "timerLastMemberQueryMsec",
745 "timerOlderHostPresentIntervalMsec",
749 "timerOtherQuerierPresentIntervalMsec",
752 json_row
, "timerQueryInterval",
753 igmp
->querier_query_interval
);
756 "timerQueryResponseIntervalMsec",
759 json_row
, "timerRobustnessVariable",
760 igmp
->querier_robustness_variable
);
761 json_object_int_add(json_row
,
762 "timerStartupQueryInterval",
765 json_object_object_add(json
, ifp
->name
,
768 if (igmp
->mtrace_only
) {
769 json_object_boolean_true_add(
770 json_row
, "mtraceOnly");
773 vty_out(vty
, "Interface : %s\n", ifp
->name
);
774 vty_out(vty
, "State : %s\n",
776 ? (igmp
->mtrace_only
? "mtrace"
779 vty_out(vty
, "Address : %s\n",
780 inet_ntoa(pim_ifp
->primary_address
));
781 vty_out(vty
, "Uptime : %s\n", uptime
);
782 vty_out(vty
, "Version : %d\n",
783 pim_ifp
->igmp_version
);
787 vty_out(vty
, "Querier\n");
788 vty_out(vty
, "-------\n");
789 vty_out(vty
, "Querier : %s\n",
790 igmp
->t_igmp_query_timer
? "local"
792 vty_out(vty
, "Start Count : %d\n",
793 igmp
->startup_query_count
);
794 vty_out(vty
, "Query Timer : %s\n",
796 vty_out(vty
, "Other Timer : %s\n",
801 vty_out(vty
, "Timers\n");
802 vty_out(vty
, "------\n");
804 "Group Membership Interval : %lis\n",
807 "Last Member Query Time : %lis\n",
810 "Older Host Present Interval : %lis\n",
813 "Other Querier Present Interval : %lis\n",
816 "Query Interval : %ds\n",
817 igmp
->querier_query_interval
);
819 "Query Response Interval : %lis\n",
822 "Robustness Variable : %d\n",
823 igmp
->querier_robustness_variable
);
825 "Startup Query Interval : %ds\n",
830 pim_print_ifp_flags(vty
, ifp
, mloop
);
836 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
837 json
, JSON_C_TO_STRING_PRETTY
));
838 json_object_free(json
);
841 vty_out(vty
, "%% No such interface\n");
845 static void igmp_show_interface_join(struct pim_instance
*pim
, struct vty
*vty
)
847 struct interface
*ifp
;
850 now
= pim_time_monotonic_sec();
853 "Interface Address Source Group Socket Uptime \n");
855 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
856 struct pim_interface
*pim_ifp
;
857 struct listnode
*join_node
;
858 struct igmp_join
*ij
;
859 struct in_addr pri_addr
;
860 char pri_addr_str
[INET_ADDRSTRLEN
];
867 if (!pim_ifp
->igmp_join_list
)
870 pri_addr
= pim_find_primary_addr(ifp
);
871 pim_inet4_dump("<pri?>", pri_addr
, pri_addr_str
,
872 sizeof(pri_addr_str
));
874 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_join_list
, join_node
,
876 char group_str
[INET_ADDRSTRLEN
];
877 char source_str
[INET_ADDRSTRLEN
];
880 pim_time_uptime(uptime
, sizeof(uptime
),
881 now
- ij
->sock_creation
);
882 pim_inet4_dump("<grp?>", ij
->group_addr
, group_str
,
884 pim_inet4_dump("<src?>", ij
->source_addr
, source_str
,
887 vty_out(vty
, "%-9s %-15s %-15s %-15s %6d %8s\n",
888 ifp
->name
, pri_addr_str
, source_str
, group_str
,
889 ij
->sock_fd
, uptime
);
890 } /* for (pim_ifp->igmp_join_list) */
895 static void pim_show_interfaces_single(struct pim_instance
*pim
,
896 struct vty
*vty
, const char *ifname
,
899 struct in_addr ifaddr
;
900 struct interface
*ifp
;
901 struct listnode
*neighnode
;
902 struct listnode
*upnode
;
903 struct pim_interface
*pim_ifp
;
904 struct pim_neighbor
*neigh
;
905 struct pim_upstream
*up
;
907 char dr_str
[INET_ADDRSTRLEN
];
910 char grp_str
[INET_ADDRSTRLEN
];
911 char hello_period
[10];
912 char hello_timer
[10];
913 char neigh_src_str
[INET_ADDRSTRLEN
];
914 char src_str
[INET_ADDRSTRLEN
];
915 char stat_uptime
[10];
918 int found_ifname
= 0;
920 json_object
*json
= NULL
;
921 json_object
*json_row
= NULL
;
922 json_object
*json_pim_neighbor
= NULL
;
923 json_object
*json_pim_neighbors
= NULL
;
924 json_object
*json_group
= NULL
;
925 json_object
*json_group_source
= NULL
;
926 json_object
*json_fhr_sources
= NULL
;
927 struct pim_secondary_addr
*sec_addr
;
928 struct listnode
*sec_node
;
930 now
= pim_time_monotonic_sec();
933 json
= json_object_new_object();
935 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
941 if (strcmp(ifname
, "detail") && strcmp(ifname
, ifp
->name
))
945 ifaddr
= pim_ifp
->primary_address
;
946 pim_inet4_dump("<dr?>", pim_ifp
->pim_dr_addr
, dr_str
,
948 pim_time_uptime_begin(dr_uptime
, sizeof(dr_uptime
), now
,
949 pim_ifp
->pim_dr_election_last
);
950 pim_time_timer_to_hhmmss(hello_timer
, sizeof(hello_timer
),
951 pim_ifp
->t_pim_hello_timer
);
952 pim_time_mmss(hello_period
, sizeof(hello_period
),
953 pim_ifp
->pim_hello_period
);
954 pim_time_uptime(stat_uptime
, sizeof(stat_uptime
),
955 now
- pim_ifp
->pim_ifstat_start
);
956 if (pim_ifp
->pim_sock_fd
>= 0)
957 mloop
= pim_socket_mcastloop_get(pim_ifp
->pim_sock_fd
);
962 char pbuf
[PREFIX2STR_BUFFER
];
963 json_row
= json_object_new_object();
964 json_object_pim_ifp_add(json_row
, ifp
);
966 if (pim_ifp
->update_source
.s_addr
!= INADDR_ANY
) {
967 json_object_string_add(
968 json_row
, "useSource",
969 inet_ntoa(pim_ifp
->update_source
));
971 if (pim_ifp
->sec_addr_list
) {
972 json_object
*sec_list
= NULL
;
974 sec_list
= json_object_new_array();
975 for (ALL_LIST_ELEMENTS_RO(
976 pim_ifp
->sec_addr_list
, sec_node
,
978 json_object_array_add(
980 json_object_new_string(
986 json_object_object_add(json_row
,
987 "secondaryAddressList",
992 if (pim_ifp
->pim_neighbor_list
->count
) {
993 json_pim_neighbors
= json_object_new_object();
995 for (ALL_LIST_ELEMENTS_RO(
996 pim_ifp
->pim_neighbor_list
,
999 json_object_new_object();
1000 pim_inet4_dump("<src?>",
1003 sizeof(neigh_src_str
));
1004 pim_time_uptime(uptime
, sizeof(uptime
),
1005 now
- neigh
->creation
);
1006 pim_time_timer_to_hhmmss(
1007 expire
, sizeof(expire
),
1008 neigh
->t_expire_timer
);
1010 json_object_string_add(
1011 json_pim_neighbor
, "address",
1013 json_object_string_add(
1014 json_pim_neighbor
, "upTime",
1016 json_object_string_add(
1017 json_pim_neighbor
, "holdtime",
1020 json_object_object_add(
1026 json_object_object_add(json_row
, "neighbors",
1027 json_pim_neighbors
);
1030 json_object_string_add(json_row
, "drAddress", dr_str
);
1031 json_object_int_add(json_row
, "drPriority",
1032 pim_ifp
->pim_dr_priority
);
1033 json_object_string_add(json_row
, "drUptime", dr_uptime
);
1034 json_object_int_add(json_row
, "drElections",
1035 pim_ifp
->pim_dr_election_count
);
1036 json_object_int_add(json_row
, "drChanges",
1037 pim_ifp
->pim_dr_election_changes
);
1040 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
,
1042 if (ifp
!= up
->rpf
.source_nexthop
.interface
)
1045 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
))
1048 if (!json_fhr_sources
)
1050 json_object_new_object();
1052 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
,
1054 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
,
1056 pim_time_uptime(uptime
, sizeof(uptime
),
1057 now
- up
->state_transition
);
1060 * Does this group live in json_fhr_sources?
1063 json_object_object_get_ex(json_fhr_sources
,
1064 grp_str
, &json_group
);
1067 json_group
= json_object_new_object();
1068 json_object_object_add(json_fhr_sources
,
1073 json_group_source
= json_object_new_object();
1074 json_object_string_add(json_group_source
,
1076 json_object_string_add(json_group_source
,
1078 json_object_string_add(json_group_source
,
1080 json_object_object_add(json_group
, src_str
,
1084 if (json_fhr_sources
) {
1085 json_object_object_add(json_row
,
1090 json_object_int_add(json_row
, "helloPeriod",
1091 pim_ifp
->pim_hello_period
);
1092 json_object_string_add(json_row
, "helloTimer",
1094 json_object_string_add(json_row
, "helloStatStart",
1096 json_object_int_add(json_row
, "helloReceived",
1097 pim_ifp
->pim_ifstat_hello_recv
);
1098 json_object_int_add(json_row
, "helloReceivedFailed",
1099 pim_ifp
->pim_ifstat_hello_recvfail
);
1100 json_object_int_add(json_row
, "helloSend",
1101 pim_ifp
->pim_ifstat_hello_sent
);
1102 json_object_int_add(json_row
, "hellosendFailed",
1103 pim_ifp
->pim_ifstat_hello_sendfail
);
1104 json_object_int_add(json_row
, "helloGenerationId",
1105 pim_ifp
->pim_generation_id
);
1106 json_object_int_add(json_row
, "flagMulticastLoop",
1109 json_object_int_add(
1110 json_row
, "effectivePropagationDelay",
1111 pim_if_effective_propagation_delay_msec(ifp
));
1112 json_object_int_add(
1113 json_row
, "effectiveOverrideInterval",
1114 pim_if_effective_override_interval_msec(ifp
));
1115 json_object_int_add(
1116 json_row
, "joinPruneOverrideInterval",
1117 pim_if_jp_override_interval_msec(ifp
));
1119 json_object_int_add(
1120 json_row
, "propagationDelay",
1121 pim_ifp
->pim_propagation_delay_msec
);
1122 json_object_int_add(
1123 json_row
, "propagationDelayHighest",
1124 pim_ifp
->pim_neighbors_highest_propagation_delay_msec
);
1125 json_object_int_add(
1126 json_row
, "overrideInterval",
1127 pim_ifp
->pim_override_interval_msec
);
1128 json_object_int_add(
1129 json_row
, "overrideIntervalHighest",
1130 pim_ifp
->pim_neighbors_highest_override_interval_msec
);
1131 json_object_object_add(json
, ifp
->name
, json_row
);
1134 vty_out(vty
, "Interface : %s\n", ifp
->name
);
1135 vty_out(vty
, "State : %s\n",
1136 if_is_up(ifp
) ? "up" : "down");
1137 if (pim_ifp
->update_source
.s_addr
!= INADDR_ANY
) {
1138 vty_out(vty
, "Use Source : %s\n",
1139 inet_ntoa(pim_ifp
->update_source
));
1141 if (pim_ifp
->sec_addr_list
) {
1142 char pbuf
[PREFIX2STR_BUFFER
];
1143 vty_out(vty
, "Address : %s (primary)\n",
1145 for (ALL_LIST_ELEMENTS_RO(
1146 pim_ifp
->sec_addr_list
, sec_node
,
1148 vty_out(vty
, " %s\n",
1149 prefix2str(&sec_addr
->addr
,
1150 pbuf
, sizeof(pbuf
)));
1153 vty_out(vty
, "Address : %s\n",
1161 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
,
1162 neighnode
, neigh
)) {
1165 vty_out(vty
, "PIM Neighbors\n");
1166 vty_out(vty
, "-------------\n");
1170 pim_inet4_dump("<src?>", neigh
->source_addr
,
1172 sizeof(neigh_src_str
));
1173 pim_time_uptime(uptime
, sizeof(uptime
),
1174 now
- neigh
->creation
);
1175 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
1176 neigh
->t_expire_timer
);
1178 "%-15s : up for %s, holdtime expires in %s\n",
1179 neigh_src_str
, uptime
, expire
);
1182 if (!print_header
) {
1187 vty_out(vty
, "Designated Router\n");
1188 vty_out(vty
, "-----------------\n");
1189 vty_out(vty
, "Address : %s\n", dr_str
);
1190 vty_out(vty
, "Priority : %d\n",
1191 pim_ifp
->pim_dr_priority
);
1192 vty_out(vty
, "Uptime : %s\n", dr_uptime
);
1193 vty_out(vty
, "Elections : %d\n",
1194 pim_ifp
->pim_dr_election_count
);
1195 vty_out(vty
, "Changes : %d\n",
1196 pim_ifp
->pim_dr_election_changes
);
1202 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
,
1205 if (strcmp(ifp
->name
,
1206 up
->rpf
.source_nexthop
1211 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
))
1216 "FHR - First Hop Router\n");
1218 "----------------------\n");
1222 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
,
1224 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
,
1226 pim_time_uptime(uptime
, sizeof(uptime
),
1227 now
- up
->state_transition
);
1229 "%s : %s is a source, uptime is %s\n",
1230 grp_str
, src_str
, uptime
);
1233 if (!print_header
) {
1238 vty_out(vty
, "Hellos\n");
1239 vty_out(vty
, "------\n");
1240 vty_out(vty
, "Period : %d\n",
1241 pim_ifp
->pim_hello_period
);
1242 vty_out(vty
, "Timer : %s\n", hello_timer
);
1243 vty_out(vty
, "StatStart : %s\n", stat_uptime
);
1244 vty_out(vty
, "Receive : %d\n",
1245 pim_ifp
->pim_ifstat_hello_recv
);
1246 vty_out(vty
, "Receive Failed : %d\n",
1247 pim_ifp
->pim_ifstat_hello_recvfail
);
1248 vty_out(vty
, "Send : %d\n",
1249 pim_ifp
->pim_ifstat_hello_sent
);
1250 vty_out(vty
, "Send Failed : %d\n",
1251 pim_ifp
->pim_ifstat_hello_sendfail
);
1252 vty_out(vty
, "Generation ID : %08x\n",
1253 pim_ifp
->pim_generation_id
);
1257 pim_print_ifp_flags(vty
, ifp
, mloop
);
1259 vty_out(vty
, "Join Prune Interval\n");
1260 vty_out(vty
, "-------------------\n");
1261 vty_out(vty
, "LAN Delay : %s\n",
1262 pim_if_lan_delay_enabled(ifp
) ? "yes" : "no");
1263 vty_out(vty
, "Effective Propagation Delay : %d msec\n",
1264 pim_if_effective_propagation_delay_msec(ifp
));
1265 vty_out(vty
, "Effective Override Interval : %d msec\n",
1266 pim_if_effective_override_interval_msec(ifp
));
1267 vty_out(vty
, "Join Prune Override Interval : %d msec\n",
1268 pim_if_jp_override_interval_msec(ifp
));
1272 vty_out(vty
, "LAN Prune Delay\n");
1273 vty_out(vty
, "---------------\n");
1274 vty_out(vty
, "Propagation Delay : %d msec\n",
1275 pim_ifp
->pim_propagation_delay_msec
);
1276 vty_out(vty
, "Propagation Delay (Highest) : %d msec\n",
1277 pim_ifp
->pim_neighbors_highest_propagation_delay_msec
);
1278 vty_out(vty
, "Override Interval : %d msec\n",
1279 pim_ifp
->pim_override_interval_msec
);
1280 vty_out(vty
, "Override Interval (Highest) : %d msec\n",
1281 pim_ifp
->pim_neighbors_highest_override_interval_msec
);
1288 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1289 json
, JSON_C_TO_STRING_PRETTY
));
1290 json_object_free(json
);
1293 vty_out(vty
, "%% No such interface\n");
1297 static void igmp_show_statistics(struct pim_instance
*pim
, struct vty
*vty
,
1298 const char *ifname
, uint8_t uj
)
1300 struct interface
*ifp
;
1301 struct igmp_stats rx_stats
;
1303 igmp_stats_init(&rx_stats
);
1305 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1306 struct pim_interface
*pim_ifp
;
1307 struct listnode
*sock_node
;
1308 struct igmp_sock
*igmp
;
1310 pim_ifp
= ifp
->info
;
1315 if (ifname
&& strcmp(ifname
, ifp
->name
))
1318 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
1320 igmp_stats_add(&rx_stats
, &igmp
->rx_stats
);
1324 json_object
*json
= NULL
;
1325 json_object
*json_row
= NULL
;
1327 json
= json_object_new_object();
1328 json_row
= json_object_new_object();
1330 json_object_string_add(json_row
, "name", ifname
? ifname
:
1332 json_object_int_add(json_row
, "queryV1", rx_stats
.query_v1
);
1333 json_object_int_add(json_row
, "queryV2", rx_stats
.query_v2
);
1334 json_object_int_add(json_row
, "queryV3", rx_stats
.query_v3
);
1335 json_object_int_add(json_row
, "leaveV3", rx_stats
.leave_v2
);
1336 json_object_int_add(json_row
, "reportV1", rx_stats
.report_v1
);
1337 json_object_int_add(json_row
, "reportV2", rx_stats
.report_v2
);
1338 json_object_int_add(json_row
, "reportV3", rx_stats
.report_v3
);
1339 json_object_int_add(json_row
, "mtraceResponse",
1340 rx_stats
.mtrace_rsp
);
1341 json_object_int_add(json_row
, "mtraceRequest",
1342 rx_stats
.mtrace_req
);
1343 json_object_int_add(json_row
, "unsupported",
1344 rx_stats
.unsupported
);
1345 json_object_object_add(json
, ifname
? ifname
: "global",
1347 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1348 json
, JSON_C_TO_STRING_PRETTY
));
1349 json_object_free(json
);
1351 vty_out(vty
, "IGMP RX statistics\n");
1352 vty_out(vty
, "Interface : %s\n",
1353 ifname
? ifname
: "global");
1354 vty_out(vty
, "V1 query : %u\n", rx_stats
.query_v1
);
1355 vty_out(vty
, "V2 query : %u\n", rx_stats
.query_v2
);
1356 vty_out(vty
, "V3 query : %u\n", rx_stats
.query_v3
);
1357 vty_out(vty
, "V2 leave : %u\n", rx_stats
.leave_v2
);
1358 vty_out(vty
, "V1 report : %u\n", rx_stats
.report_v1
);
1359 vty_out(vty
, "V2 report : %u\n", rx_stats
.report_v2
);
1360 vty_out(vty
, "V3 report : %u\n", rx_stats
.report_v3
);
1361 vty_out(vty
, "mtrace response : %u\n", rx_stats
.mtrace_rsp
);
1362 vty_out(vty
, "mtrace request : %u\n", rx_stats
.mtrace_req
);
1363 vty_out(vty
, "unsupported : %u\n", rx_stats
.unsupported
);
1367 static void pim_show_interfaces(struct pim_instance
*pim
, struct vty
*vty
,
1370 struct interface
*ifp
;
1371 struct listnode
*upnode
;
1372 struct pim_interface
*pim_ifp
;
1373 struct pim_upstream
*up
;
1376 int pim_ifchannels
= 0;
1377 json_object
*json
= NULL
;
1378 json_object
*json_row
= NULL
;
1379 json_object
*json_tmp
;
1381 json
= json_object_new_object();
1383 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1384 pim_ifp
= ifp
->info
;
1389 pim_nbrs
= pim_ifp
->pim_neighbor_list
->count
;
1390 pim_ifchannels
= pim_if_ifchannel_count(pim_ifp
);
1393 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
, up
))
1394 if (ifp
== up
->rpf
.source_nexthop
.interface
)
1395 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
1398 json_row
= json_object_new_object();
1399 json_object_pim_ifp_add(json_row
, ifp
);
1400 json_object_int_add(json_row
, "pimNeighbors", pim_nbrs
);
1401 json_object_int_add(json_row
, "pimIfChannels", pim_ifchannels
);
1402 json_object_int_add(json_row
, "firstHopRouterCount", fhr
);
1403 json_object_string_add(json_row
, "pimDesignatedRouter",
1404 inet_ntoa(pim_ifp
->pim_dr_addr
));
1406 if (pim_ifp
->pim_dr_addr
.s_addr
1407 == pim_ifp
->primary_address
.s_addr
)
1408 json_object_boolean_true_add(
1409 json_row
, "pimDesignatedRouterLocal");
1411 json_object_object_add(json
, ifp
->name
, json_row
);
1415 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1416 json
, JSON_C_TO_STRING_PRETTY
));
1419 "Interface State Address PIM Nbrs PIM DR FHR IfChannels\n");
1421 json_object_object_foreach(json
, key
, val
)
1423 vty_out(vty
, "%-9s ", key
);
1425 json_object_object_get_ex(val
, "state", &json_tmp
);
1426 vty_out(vty
, "%5s ", json_object_get_string(json_tmp
));
1428 json_object_object_get_ex(val
, "address", &json_tmp
);
1429 vty_out(vty
, "%15s ",
1430 json_object_get_string(json_tmp
));
1432 json_object_object_get_ex(val
, "pimNeighbors",
1434 vty_out(vty
, "%8d ", json_object_get_int(json_tmp
));
1436 if (json_object_object_get_ex(
1437 val
, "pimDesignatedRouterLocal",
1439 vty_out(vty
, "%15s ", "local");
1441 json_object_object_get_ex(
1442 val
, "pimDesignatedRouter", &json_tmp
);
1443 vty_out(vty
, "%15s ",
1444 json_object_get_string(json_tmp
));
1447 json_object_object_get_ex(val
, "firstHopRouter",
1449 vty_out(vty
, "%3d ", json_object_get_int(json_tmp
));
1451 json_object_object_get_ex(val
, "pimIfChannels",
1453 vty_out(vty
, "%9d\n", json_object_get_int(json_tmp
));
1457 json_object_free(json
);
1460 static void pim_show_interface_traffic(struct pim_instance
*pim
,
1461 struct vty
*vty
, uint8_t uj
)
1463 struct interface
*ifp
= NULL
;
1464 struct pim_interface
*pim_ifp
= NULL
;
1465 json_object
*json
= NULL
;
1466 json_object
*json_row
= NULL
;
1469 json
= json_object_new_object();
1472 vty_out(vty
, "%-12s%-17s%-17s%-17s%-17s%-17s%-17s\n",
1473 "Interface", " HELLO", " JOIN", " PRUNE",
1474 " REGISTER", " REGISTER-STOP", " ASSERT");
1475 vty_out(vty
, "%-10s%-18s%-17s%-17s%-17s%-17s%-17s\n", "",
1476 " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1477 " Rx/Tx", " Rx/Tx");
1479 "---------------------------------------------------------------------------------------------------------------\n");
1482 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1483 pim_ifp
= ifp
->info
;
1488 if (pim_ifp
->pim_sock_fd
< 0)
1491 json_row
= json_object_new_object();
1492 json_object_pim_ifp_add(json_row
, ifp
);
1493 json_object_int_add(json_row
, "helloRx",
1494 pim_ifp
->pim_ifstat_hello_recv
);
1495 json_object_int_add(json_row
, "helloTx",
1496 pim_ifp
->pim_ifstat_hello_sent
);
1497 json_object_int_add(json_row
, "joinRx",
1498 pim_ifp
->pim_ifstat_join_recv
);
1499 json_object_int_add(json_row
, "joinTx",
1500 pim_ifp
->pim_ifstat_join_send
);
1501 json_object_int_add(json_row
, "registerRx",
1502 pim_ifp
->pim_ifstat_reg_recv
);
1503 json_object_int_add(json_row
, "registerTx",
1504 pim_ifp
->pim_ifstat_reg_recv
);
1505 json_object_int_add(json_row
, "registerStopRx",
1506 pim_ifp
->pim_ifstat_reg_stop_recv
);
1507 json_object_int_add(json_row
, "registerStopTx",
1508 pim_ifp
->pim_ifstat_reg_stop_send
);
1509 json_object_int_add(json_row
, "assertRx",
1510 pim_ifp
->pim_ifstat_assert_recv
);
1511 json_object_int_add(json_row
, "assertTx",
1512 pim_ifp
->pim_ifstat_assert_send
);
1514 json_object_object_add(json
, ifp
->name
, json_row
);
1517 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u \n",
1518 ifp
->name
, pim_ifp
->pim_ifstat_hello_recv
,
1519 pim_ifp
->pim_ifstat_hello_sent
,
1520 pim_ifp
->pim_ifstat_join_recv
,
1521 pim_ifp
->pim_ifstat_join_send
,
1522 pim_ifp
->pim_ifstat_prune_recv
,
1523 pim_ifp
->pim_ifstat_prune_send
,
1524 pim_ifp
->pim_ifstat_reg_recv
,
1525 pim_ifp
->pim_ifstat_reg_send
,
1526 pim_ifp
->pim_ifstat_reg_stop_recv
,
1527 pim_ifp
->pim_ifstat_reg_stop_send
,
1528 pim_ifp
->pim_ifstat_assert_recv
,
1529 pim_ifp
->pim_ifstat_assert_send
);
1533 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1534 json
, JSON_C_TO_STRING_PRETTY
));
1535 json_object_free(json
);
1539 static void pim_show_interface_traffic_single(struct pim_instance
*pim
,
1541 const char *ifname
, uint8_t uj
)
1543 struct interface
*ifp
= NULL
;
1544 struct pim_interface
*pim_ifp
= NULL
;
1545 json_object
*json
= NULL
;
1546 json_object
*json_row
= NULL
;
1547 uint8_t found_ifname
= 0;
1550 json
= json_object_new_object();
1553 vty_out(vty
, "%-12s%-17s%-17s%-17s%-17s%-17s%-17s\n",
1554 "Interface", " HELLO", " JOIN", " PRUNE",
1555 " REGISTER", " REGISTER-STOP", " ASSERT");
1556 vty_out(vty
, "%-10s%-18s%-17s%-17s%-17s%-17s%-17s\n", "",
1557 " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1558 " Rx/Tx", " Rx/Tx");
1560 "---------------------------------------------------------------------------------------------------------------\n");
1563 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1564 if (strcmp(ifname
, ifp
->name
))
1567 pim_ifp
= ifp
->info
;
1572 if (pim_ifp
->pim_sock_fd
< 0)
1577 json_row
= json_object_new_object();
1578 json_object_pim_ifp_add(json_row
, ifp
);
1579 json_object_int_add(json_row
, "helloRx",
1580 pim_ifp
->pim_ifstat_hello_recv
);
1581 json_object_int_add(json_row
, "helloTx",
1582 pim_ifp
->pim_ifstat_hello_sent
);
1583 json_object_int_add(json_row
, "joinRx",
1584 pim_ifp
->pim_ifstat_join_recv
);
1585 json_object_int_add(json_row
, "joinTx",
1586 pim_ifp
->pim_ifstat_join_send
);
1587 json_object_int_add(json_row
, "registerRx",
1588 pim_ifp
->pim_ifstat_reg_recv
);
1589 json_object_int_add(json_row
, "registerTx",
1590 pim_ifp
->pim_ifstat_reg_recv
);
1591 json_object_int_add(json_row
, "registerStopRx",
1592 pim_ifp
->pim_ifstat_reg_stop_recv
);
1593 json_object_int_add(json_row
, "registerStopTx",
1594 pim_ifp
->pim_ifstat_reg_stop_send
);
1595 json_object_int_add(json_row
, "assertRx",
1596 pim_ifp
->pim_ifstat_assert_recv
);
1597 json_object_int_add(json_row
, "assertTx",
1598 pim_ifp
->pim_ifstat_assert_send
);
1600 json_object_object_add(json
, ifp
->name
, json_row
);
1603 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u \n",
1604 ifp
->name
, pim_ifp
->pim_ifstat_hello_recv
,
1605 pim_ifp
->pim_ifstat_hello_sent
,
1606 pim_ifp
->pim_ifstat_join_recv
,
1607 pim_ifp
->pim_ifstat_join_send
,
1608 pim_ifp
->pim_ifstat_prune_recv
,
1609 pim_ifp
->pim_ifstat_prune_send
,
1610 pim_ifp
->pim_ifstat_reg_recv
,
1611 pim_ifp
->pim_ifstat_reg_send
,
1612 pim_ifp
->pim_ifstat_reg_stop_recv
,
1613 pim_ifp
->pim_ifstat_reg_stop_send
,
1614 pim_ifp
->pim_ifstat_assert_recv
,
1615 pim_ifp
->pim_ifstat_assert_send
);
1619 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1620 json
, JSON_C_TO_STRING_PRETTY
));
1621 json_object_free(json
);
1624 vty_out(vty
, "%% No such interface\n");
1628 static void pim_show_join_helper(struct vty
*vty
, struct pim_interface
*pim_ifp
,
1629 struct pim_ifchannel
*ch
, json_object
*json
,
1630 time_t now
, uint8_t uj
)
1632 char ch_src_str
[INET_ADDRSTRLEN
];
1633 char ch_grp_str
[INET_ADDRSTRLEN
];
1634 json_object
*json_iface
= NULL
;
1635 json_object
*json_row
= NULL
;
1636 json_object
*json_grp
= NULL
;
1637 struct in_addr ifaddr
;
1642 ifaddr
= pim_ifp
->primary_address
;
1644 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
1645 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
1647 pim_time_uptime_begin(uptime
, sizeof(uptime
), now
, ch
->ifjoin_creation
);
1648 pim_time_timer_to_mmss(expire
, sizeof(expire
),
1649 ch
->t_ifjoin_expiry_timer
);
1650 pim_time_timer_to_mmss(prune
, sizeof(prune
),
1651 ch
->t_ifjoin_prune_pending_timer
);
1654 json_object_object_get_ex(json
, ch
->interface
->name
,
1658 json_iface
= json_object_new_object();
1659 json_object_pim_ifp_add(json_iface
, ch
->interface
);
1660 json_object_object_add(json
, ch
->interface
->name
,
1664 json_row
= json_object_new_object();
1665 json_object_string_add(json_row
, "source", ch_src_str
);
1666 json_object_string_add(json_row
, "group", ch_grp_str
);
1667 json_object_string_add(json_row
, "upTime", uptime
);
1668 json_object_string_add(json_row
, "expire", expire
);
1669 json_object_string_add(json_row
, "prune", prune
);
1670 json_object_string_add(
1671 json_row
, "channelJoinName",
1672 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
, ch
->flags
));
1673 if (PIM_IF_FLAG_TEST_S_G_RPT(ch
->flags
))
1674 json_object_int_add(json_row
, "SGRpt", 1);
1676 json_object_object_get_ex(json_iface
, ch_grp_str
, &json_grp
);
1678 json_grp
= json_object_new_object();
1679 json_object_object_add(json_grp
, ch_src_str
, json_row
);
1680 json_object_object_add(json_iface
, ch_grp_str
,
1683 json_object_object_add(json_grp
, ch_src_str
, json_row
);
1685 vty_out(vty
, "%-9s %-15s %-15s %-15s %-10s %8s %-6s %5s\n",
1686 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
,
1688 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
, ch
->flags
),
1689 uptime
, expire
, prune
);
1693 static void pim_show_join(struct pim_instance
*pim
, struct vty
*vty
, uint8_t uj
)
1695 struct pim_interface
*pim_ifp
;
1696 struct pim_ifchannel
*ch
;
1697 struct interface
*ifp
;
1699 json_object
*json
= NULL
;
1701 now
= pim_time_monotonic_sec();
1704 json
= json_object_new_object();
1707 "Interface Address Source Group State Uptime Expire Prune\n");
1709 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1710 pim_ifp
= ifp
->info
;
1714 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
1715 pim_show_join_helper(vty
, pim_ifp
, ch
, json
, now
, uj
);
1716 } /* scan interface channels */
1720 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1721 json
, JSON_C_TO_STRING_PRETTY
));
1722 json_object_free(json
);
1726 static void pim_show_neighbors_single(struct pim_instance
*pim
, struct vty
*vty
,
1727 const char *neighbor
, uint8_t uj
)
1729 struct listnode
*neighnode
;
1730 struct interface
*ifp
;
1731 struct pim_interface
*pim_ifp
;
1732 struct pim_neighbor
*neigh
;
1734 int found_neighbor
= 0;
1735 int option_address_list
;
1736 int option_dr_priority
;
1737 int option_generation_id
;
1738 int option_holdtime
;
1739 int option_lan_prune_delay
;
1743 char neigh_src_str
[INET_ADDRSTRLEN
];
1745 json_object
*json
= NULL
;
1746 json_object
*json_ifp
= NULL
;
1747 json_object
*json_row
= NULL
;
1749 now
= pim_time_monotonic_sec();
1752 json
= json_object_new_object();
1754 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1755 pim_ifp
= ifp
->info
;
1760 if (pim_ifp
->pim_sock_fd
< 0)
1763 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
1765 pim_inet4_dump("<src?>", neigh
->source_addr
,
1766 neigh_src_str
, sizeof(neigh_src_str
));
1769 * The user can specify either the interface name or the
1771 * If this pim_ifp matches neither then skip.
1773 if (strcmp(neighbor
, "detail")
1774 && strcmp(neighbor
, ifp
->name
)
1775 && strcmp(neighbor
, neigh_src_str
))
1779 pim_time_uptime(uptime
, sizeof(uptime
),
1780 now
- neigh
->creation
);
1781 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
1782 neigh
->t_expire_timer
);
1784 option_address_list
= 0;
1785 option_dr_priority
= 0;
1786 option_generation_id
= 0;
1787 option_holdtime
= 0;
1788 option_lan_prune_delay
= 0;
1791 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1792 PIM_OPTION_MASK_ADDRESS_LIST
))
1793 option_address_list
= 1;
1795 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1796 PIM_OPTION_MASK_DR_PRIORITY
))
1797 option_dr_priority
= 1;
1799 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1800 PIM_OPTION_MASK_GENERATION_ID
))
1801 option_generation_id
= 1;
1803 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1804 PIM_OPTION_MASK_HOLDTIME
))
1805 option_holdtime
= 1;
1807 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1808 PIM_OPTION_MASK_LAN_PRUNE_DELAY
))
1809 option_lan_prune_delay
= 1;
1811 if (PIM_OPTION_IS_SET(
1812 neigh
->hello_options
,
1813 PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION
))
1818 /* Does this ifp live in json? If not create
1820 json_object_object_get_ex(json
, ifp
->name
,
1824 json_ifp
= json_object_new_object();
1825 json_object_pim_ifp_add(json_ifp
, ifp
);
1826 json_object_object_add(json
, ifp
->name
,
1830 json_row
= json_object_new_object();
1831 json_object_string_add(json_row
, "interface",
1833 json_object_string_add(json_row
, "address",
1835 json_object_string_add(json_row
, "upTime",
1837 json_object_string_add(json_row
, "holdtime",
1839 json_object_int_add(json_row
, "drPriority",
1840 neigh
->dr_priority
);
1841 json_object_int_add(json_row
, "generationId",
1842 neigh
->generation_id
);
1844 if (option_address_list
)
1845 json_object_boolean_true_add(
1847 "helloOptionAddressList");
1849 if (option_dr_priority
)
1850 json_object_boolean_true_add(
1852 "helloOptionDrPriority");
1854 if (option_generation_id
)
1855 json_object_boolean_true_add(
1857 "helloOptionGenerationId");
1859 if (option_holdtime
)
1860 json_object_boolean_true_add(
1862 "helloOptionHoldtime");
1864 if (option_lan_prune_delay
)
1865 json_object_boolean_true_add(
1867 "helloOptionLanPruneDelay");
1870 json_object_boolean_true_add(
1871 json_row
, "helloOptionTBit");
1873 json_object_object_add(json_ifp
, neigh_src_str
,
1877 vty_out(vty
, "Interface : %s\n", ifp
->name
);
1878 vty_out(vty
, "Neighbor : %s\n", neigh_src_str
);
1886 " DR Priority : %d\n",
1887 neigh
->dr_priority
);
1889 " Generation ID : %08x\n",
1890 neigh
->generation_id
);
1892 " Override Interval (msec) : %d\n",
1893 neigh
->override_interval_msec
);
1895 " Propagation Delay (msec) : %d\n",
1896 neigh
->propagation_delay_msec
);
1898 " Hello Option - Address List : %s\n",
1899 option_address_list
? "yes" : "no");
1901 " Hello Option - DR Priority : %s\n",
1902 option_dr_priority
? "yes" : "no");
1904 " Hello Option - Generation ID : %s\n",
1905 option_generation_id
? "yes" : "no");
1907 " Hello Option - Holdtime : %s\n",
1908 option_holdtime
? "yes" : "no");
1910 " Hello Option - LAN Prune Delay : %s\n",
1911 option_lan_prune_delay
? "yes" : "no");
1913 " Hello Option - T-bit : %s\n",
1914 option_t_bit
? "yes" : "no");
1915 pim_bfd_show_info(vty
, neigh
->bfd_info
,
1923 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1924 json
, JSON_C_TO_STRING_PRETTY
));
1925 json_object_free(json
);
1928 if (!found_neighbor
)
1930 "%% No such interface or neighbor\n");
1935 static void pim_show_state(struct pim_instance
*pim
, struct vty
*vty
,
1936 const char *src_or_group
, const char *group
,
1939 struct channel_oil
*c_oil
;
1940 struct listnode
*node
;
1941 json_object
*json
= NULL
;
1942 json_object
*json_group
= NULL
;
1943 json_object
*json_ifp_in
= NULL
;
1944 json_object
*json_ifp_out
= NULL
;
1945 json_object
*json_source
= NULL
;
1948 now
= pim_time_monotonic_sec();
1951 json
= json_object_new_object();
1954 "Codes: J -> Pim Join, I -> IGMP Report, S -> Source, * -> Inherited from (*,G)");
1956 "\nInstalled Source Group IIF OIL\n");
1959 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
1960 char grp_str
[INET_ADDRSTRLEN
];
1961 char src_str
[INET_ADDRSTRLEN
];
1962 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
1963 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
1965 struct interface
*ifp_in
;
1968 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
1970 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
1972 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
1975 strcpy(in_ifname
, ifp_in
->name
);
1977 strcpy(in_ifname
, "<iif?>");
1980 if (strcmp(src_or_group
, src_str
)
1981 && strcmp(src_or_group
, grp_str
))
1984 if (group
&& strcmp(group
, grp_str
))
1990 /* Find the group, create it if it doesn't exist */
1991 json_object_object_get_ex(json
, grp_str
, &json_group
);
1994 json_group
= json_object_new_object();
1995 json_object_object_add(json
, grp_str
,
1999 /* Find the source nested under the group, create it if
2000 * it doesn't exist */
2001 json_object_object_get_ex(json_group
, src_str
,
2005 json_source
= json_object_new_object();
2006 json_object_object_add(json_group
, src_str
,
2010 /* Find the inbound interface nested under the source,
2011 * create it if it doesn't exist */
2012 json_object_object_get_ex(json_source
, in_ifname
,
2016 json_ifp_in
= json_object_new_object();
2017 json_object_object_add(json_source
, in_ifname
,
2019 json_object_int_add(json_source
, "Installed",
2021 json_object_int_add(json_source
, "RefCount",
2022 c_oil
->oil_ref_count
);
2023 json_object_int_add(json_source
, "OilListSize",
2025 json_object_int_add(
2026 json_source
, "OilRescan",
2027 c_oil
->oil_inherited_rescan
);
2028 json_object_int_add(json_source
, "LastUsed",
2029 c_oil
->cc
.lastused
);
2030 json_object_int_add(json_source
, "PacketCount",
2032 json_object_int_add(json_source
, "ByteCount",
2034 json_object_int_add(json_source
,
2036 c_oil
->cc
.wrong_if
);
2039 vty_out(vty
, "%-9d %-15s %-15s %-7s ",
2040 c_oil
->installed
, src_str
, grp_str
,
2044 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
2046 struct interface
*ifp_out
;
2047 char oif_uptime
[10];
2050 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
2054 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
2056 oif_uptime
, sizeof(oif_uptime
),
2057 now
- c_oil
->oif_creation
[oif_vif_index
]);
2060 strcpy(out_ifname
, ifp_out
->name
);
2062 strcpy(out_ifname
, "<oif?>");
2065 json_ifp_out
= json_object_new_object();
2066 json_object_string_add(json_ifp_out
, "source",
2068 json_object_string_add(json_ifp_out
, "group",
2070 json_object_string_add(json_ifp_out
,
2073 json_object_string_add(json_ifp_out
,
2074 "outboundInterface",
2076 json_object_int_add(json_ifp_out
, "installed",
2079 json_object_object_add(json_ifp_in
, out_ifname
,
2084 vty_out(vty
, "%s(%c%c%c%c)", out_ifname
,
2085 (c_oil
->oif_flags
[oif_vif_index
]
2086 & PIM_OIF_FLAG_PROTO_IGMP
)
2089 (c_oil
->oif_flags
[oif_vif_index
]
2090 & PIM_OIF_FLAG_PROTO_PIM
)
2093 (c_oil
->oif_flags
[oif_vif_index
]
2094 & PIM_OIF_FLAG_PROTO_SOURCE
)
2097 (c_oil
->oif_flags
[oif_vif_index
]
2098 & PIM_OIF_FLAG_PROTO_STAR
)
2102 vty_out(vty
, ", %s(%c%c%c%c)",
2104 (c_oil
->oif_flags
[oif_vif_index
]
2105 & PIM_OIF_FLAG_PROTO_IGMP
)
2108 (c_oil
->oif_flags
[oif_vif_index
]
2109 & PIM_OIF_FLAG_PROTO_PIM
)
2112 (c_oil
->oif_flags
[oif_vif_index
]
2113 & PIM_OIF_FLAG_PROTO_SOURCE
)
2116 (c_oil
->oif_flags
[oif_vif_index
]
2117 & PIM_OIF_FLAG_PROTO_STAR
)
2129 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2130 json
, JSON_C_TO_STRING_PRETTY
));
2131 json_object_free(json
);
2137 static void pim_show_neighbors(struct pim_instance
*pim
, struct vty
*vty
,
2140 struct listnode
*neighnode
;
2141 struct interface
*ifp
;
2142 struct pim_interface
*pim_ifp
;
2143 struct pim_neighbor
*neigh
;
2147 char neigh_src_str
[INET_ADDRSTRLEN
];
2148 json_object
*json
= NULL
;
2149 json_object
*json_ifp_rows
= NULL
;
2150 json_object
*json_row
= NULL
;
2152 now
= pim_time_monotonic_sec();
2155 json
= json_object_new_object();
2158 "Interface Neighbor Uptime Holdtime DR Pri\n");
2161 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2162 pim_ifp
= ifp
->info
;
2167 if (pim_ifp
->pim_sock_fd
< 0)
2171 json_ifp_rows
= json_object_new_object();
2173 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
2175 pim_inet4_dump("<src?>", neigh
->source_addr
,
2176 neigh_src_str
, sizeof(neigh_src_str
));
2177 pim_time_uptime(uptime
, sizeof(uptime
),
2178 now
- neigh
->creation
);
2179 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
2180 neigh
->t_expire_timer
);
2183 json_row
= json_object_new_object();
2184 json_object_string_add(json_row
, "interface",
2186 json_object_string_add(json_row
, "neighbor",
2188 json_object_string_add(json_row
, "upTime",
2190 json_object_string_add(json_row
, "holdTime",
2192 json_object_int_add(json_row
, "holdTimeMax",
2194 json_object_int_add(json_row
, "drPriority",
2195 neigh
->dr_priority
);
2196 json_object_object_add(json_ifp_rows
,
2197 neigh_src_str
, json_row
);
2200 vty_out(vty
, "%-9s %15s %8s %8s %6d\n",
2201 ifp
->name
, neigh_src_str
, uptime
,
2202 expire
, neigh
->dr_priority
);
2207 json_object_object_add(json
, ifp
->name
, json_ifp_rows
);
2208 json_ifp_rows
= NULL
;
2213 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2214 json
, JSON_C_TO_STRING_PRETTY
));
2215 json_object_free(json
);
2219 static void pim_show_neighbors_secondary(struct pim_instance
*pim
,
2222 struct interface
*ifp
;
2225 "Interface Address Neighbor Secondary \n");
2227 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2228 struct pim_interface
*pim_ifp
;
2229 struct in_addr ifaddr
;
2230 struct listnode
*neighnode
;
2231 struct pim_neighbor
*neigh
;
2233 pim_ifp
= ifp
->info
;
2238 if (pim_ifp
->pim_sock_fd
< 0)
2241 ifaddr
= pim_ifp
->primary_address
;
2243 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
2245 char neigh_src_str
[INET_ADDRSTRLEN
];
2246 struct listnode
*prefix_node
;
2249 if (!neigh
->prefix_list
)
2252 pim_inet4_dump("<src?>", neigh
->source_addr
,
2253 neigh_src_str
, sizeof(neigh_src_str
));
2255 for (ALL_LIST_ELEMENTS_RO(neigh
->prefix_list
,
2257 char neigh_sec_str
[PREFIX2STR_BUFFER
];
2259 prefix2str(p
, neigh_sec_str
,
2260 sizeof(neigh_sec_str
));
2262 vty_out(vty
, "%-9s %-15s %-15s %-15s\n",
2263 ifp
->name
, inet_ntoa(ifaddr
),
2264 neigh_src_str
, neigh_sec_str
);
2270 static void json_object_pim_upstream_add(json_object
*json
,
2271 struct pim_upstream
*up
)
2273 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED
)
2274 json_object_boolean_true_add(json
, "drJoinDesired");
2276 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED
)
2277 json_object_boolean_true_add(json
, "drJoinDesiredUpdated");
2279 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
2280 json_object_boolean_true_add(json
, "firstHopRouter");
2282 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_IGMP
)
2283 json_object_boolean_true_add(json
, "sourceIgmp");
2285 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_PIM
)
2286 json_object_boolean_true_add(json
, "sourcePim");
2288 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_STREAM
)
2289 json_object_boolean_true_add(json
, "sourceStream");
2291 /* XXX: need to print ths flag in the plain text display as well */
2292 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_MSDP
)
2293 json_object_boolean_true_add(json
, "sourceMsdp");
2297 pim_upstream_state2brief_str(enum pim_upstream_state join_state
,
2300 switch (join_state
) {
2301 case PIM_UPSTREAM_NOTJOINED
:
2302 strcpy(state_str
, "NotJ");
2304 case PIM_UPSTREAM_JOINED
:
2305 strcpy(state_str
, "J");
2308 strcpy(state_str
, "Unk");
2313 static const char *pim_reg_state2brief_str(enum pim_reg_state reg_state
,
2316 switch (reg_state
) {
2317 case PIM_REG_NOINFO
:
2318 strcpy(state_str
, "RegNI");
2321 strcpy(state_str
, "RegJ");
2323 case PIM_REG_JOIN_PENDING
:
2325 strcpy(state_str
, "RegP");
2328 strcpy(state_str
, "Unk");
2333 static void pim_show_upstream(struct pim_instance
*pim
, struct vty
*vty
,
2336 struct listnode
*upnode
;
2337 struct pim_upstream
*up
;
2339 json_object
*json
= NULL
;
2340 json_object
*json_group
= NULL
;
2341 json_object
*json_row
= NULL
;
2343 now
= pim_time_monotonic_sec();
2346 json
= json_object_new_object();
2349 "Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt\n");
2351 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
, up
)) {
2352 char src_str
[INET_ADDRSTRLEN
];
2353 char grp_str
[INET_ADDRSTRLEN
];
2355 char join_timer
[10];
2358 char msdp_reg_timer
[10];
2359 char state_str
[PIM_REG_STATE_STR_LEN
];
2361 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2362 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2363 pim_time_uptime(uptime
, sizeof(uptime
),
2364 now
- up
->state_transition
);
2365 pim_time_timer_to_hhmmss(join_timer
, sizeof(join_timer
),
2369 * If we have a J/P timer for the neighbor display that
2371 if (!up
->t_join_timer
) {
2372 struct pim_neighbor
*nbr
;
2374 nbr
= pim_neighbor_find(
2375 up
->rpf
.source_nexthop
.interface
,
2376 up
->rpf
.rpf_addr
.u
.prefix4
);
2378 pim_time_timer_to_hhmmss(join_timer
,
2383 pim_time_timer_to_hhmmss(rs_timer
, sizeof(rs_timer
),
2385 pim_time_timer_to_hhmmss(ka_timer
, sizeof(ka_timer
),
2387 pim_time_timer_to_hhmmss(msdp_reg_timer
, sizeof(msdp_reg_timer
),
2388 up
->t_msdp_reg_timer
);
2390 pim_upstream_state2brief_str(up
->join_state
, state_str
);
2391 if (up
->reg_state
!= PIM_REG_NOINFO
) {
2392 char tmp_str
[PIM_REG_STATE_STR_LEN
];
2394 sprintf(state_str
+ strlen(state_str
), ",%s",
2395 pim_reg_state2brief_str(up
->reg_state
,
2400 json_object_object_get_ex(json
, grp_str
, &json_group
);
2403 json_group
= json_object_new_object();
2404 json_object_object_add(json
, grp_str
,
2408 json_row
= json_object_new_object();
2409 json_object_pim_upstream_add(json_row
, up
);
2410 json_object_string_add(
2411 json_row
, "inboundInterface",
2412 up
->rpf
.source_nexthop
.interface
->name
);
2415 * The RPF address we use is slightly different
2416 * based upon what we are looking up.
2417 * If we have a S, list that unless
2418 * we are the FHR, else we just put
2419 * the RP as the rpfAddress
2421 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
2422 || up
->sg
.src
.s_addr
== INADDR_ANY
) {
2423 char rpf
[PREFIX_STRLEN
];
2424 struct pim_rpf
*rpg
;
2426 rpg
= RP(pim
, up
->sg
.grp
);
2427 pim_inet4_dump("<rpf?>",
2428 rpg
->rpf_addr
.u
.prefix4
, rpf
,
2430 json_object_string_add(json_row
, "rpfAddress",
2433 json_object_string_add(json_row
, "rpfAddress",
2437 json_object_string_add(json_row
, "source", src_str
);
2438 json_object_string_add(json_row
, "group", grp_str
);
2439 json_object_string_add(json_row
, "state", state_str
);
2440 json_object_string_add(
2441 json_row
, "joinState",
2442 pim_upstream_state2str(up
->join_state
));
2443 json_object_string_add(
2444 json_row
, "regState",
2445 pim_reg_state2str(up
->reg_state
, state_str
));
2446 json_object_string_add(json_row
, "upTime", uptime
);
2447 json_object_string_add(json_row
, "joinTimer",
2449 json_object_string_add(json_row
, "resetTimer",
2451 json_object_string_add(json_row
, "keepaliveTimer",
2453 json_object_string_add(json_row
, "msdpRegTimer",
2455 json_object_int_add(json_row
, "refCount",
2457 json_object_int_add(json_row
, "sptBit", up
->sptbit
);
2458 json_object_object_add(json_group
, src_str
, json_row
);
2461 "%-10s%-15s %-15s %-11s %-8s %-9s %-9s %-9s %6d\n",
2462 up
->rpf
.source_nexthop
.interface
->name
, src_str
,
2463 grp_str
, state_str
, uptime
, join_timer
,
2464 rs_timer
, ka_timer
, up
->ref_count
);
2469 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2470 json
, JSON_C_TO_STRING_PRETTY
));
2471 json_object_free(json
);
2475 static void pim_show_join_desired_helper(struct pim_instance
*pim
,
2477 struct pim_interface
*pim_ifp
,
2478 struct pim_ifchannel
*ch
,
2479 json_object
*json
, uint8_t uj
)
2481 struct pim_upstream
*up
= ch
->upstream
;
2482 json_object
*json_group
= NULL
;
2483 char src_str
[INET_ADDRSTRLEN
];
2484 char grp_str
[INET_ADDRSTRLEN
];
2485 json_object
*json_row
= NULL
;
2487 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2488 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2491 json_object_object_get_ex(json
, grp_str
, &json_group
);
2494 json_group
= json_object_new_object();
2495 json_object_object_add(json
, grp_str
, json_group
);
2498 json_row
= json_object_new_object();
2499 json_object_pim_upstream_add(json_row
, up
);
2500 json_object_string_add(json_row
, "interface",
2501 ch
->interface
->name
);
2502 json_object_string_add(json_row
, "source", src_str
);
2503 json_object_string_add(json_row
, "group", grp_str
);
2505 if (pim_macro_ch_lost_assert(ch
))
2506 json_object_boolean_true_add(json_row
, "lostAssert");
2508 if (pim_macro_chisin_joins(ch
))
2509 json_object_boolean_true_add(json_row
, "joins");
2511 if (pim_macro_chisin_pim_include(ch
))
2512 json_object_boolean_true_add(json_row
, "pimInclude");
2514 if (pim_upstream_evaluate_join_desired(pim
, up
))
2515 json_object_boolean_true_add(json_row
,
2516 "evaluateJoinDesired");
2518 json_object_object_add(json_group
, src_str
, json_row
);
2521 vty_out(vty
, "%-9s %-15s %-15s %-10s %-5s %-10s %-11s %-6s\n",
2522 ch
->interface
->name
, src_str
, grp_str
,
2523 pim_macro_ch_lost_assert(ch
) ? "yes" : "no",
2524 pim_macro_chisin_joins(ch
) ? "yes" : "no",
2525 pim_macro_chisin_pim_include(ch
) ? "yes" : "no",
2526 PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(up
->flags
)
2529 pim_upstream_evaluate_join_desired(pim
, up
) ? "yes"
2534 static void pim_show_join_desired(struct pim_instance
*pim
, struct vty
*vty
,
2537 struct pim_interface
*pim_ifp
;
2538 struct pim_ifchannel
*ch
;
2539 struct interface
*ifp
;
2541 json_object
*json
= NULL
;
2544 json
= json_object_new_object();
2547 "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD\n");
2549 /* scan per-interface (S,G) state */
2550 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2551 pim_ifp
= ifp
->info
;
2556 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
2557 /* scan all interfaces */
2558 pim_show_join_desired_helper(pim
, vty
, pim_ifp
, ch
,
2564 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2565 json
, JSON_C_TO_STRING_PRETTY
));
2566 json_object_free(json
);
2570 static void pim_show_upstream_rpf(struct pim_instance
*pim
, struct vty
*vty
,
2573 struct listnode
*upnode
;
2574 struct pim_upstream
*up
;
2575 json_object
*json
= NULL
;
2576 json_object
*json_group
= NULL
;
2577 json_object
*json_row
= NULL
;
2580 json
= json_object_new_object();
2583 "Source Group RpfIface RibNextHop RpfAddress \n");
2585 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
, up
)) {
2586 char src_str
[INET_ADDRSTRLEN
];
2587 char grp_str
[INET_ADDRSTRLEN
];
2588 char rpf_nexthop_str
[PREFIX_STRLEN
];
2589 char rpf_addr_str
[PREFIX_STRLEN
];
2590 struct pim_rpf
*rpf
;
2591 const char *rpf_ifname
;
2595 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2596 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2597 pim_addr_dump("<nexthop?>",
2598 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2599 rpf_nexthop_str
, sizeof(rpf_nexthop_str
));
2600 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2601 sizeof(rpf_addr_str
));
2603 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2606 json_object_object_get_ex(json
, grp_str
, &json_group
);
2609 json_group
= json_object_new_object();
2610 json_object_object_add(json
, grp_str
,
2614 json_row
= json_object_new_object();
2615 json_object_pim_upstream_add(json_row
, up
);
2616 json_object_string_add(json_row
, "source", src_str
);
2617 json_object_string_add(json_row
, "group", grp_str
);
2618 json_object_string_add(json_row
, "rpfInterface",
2620 json_object_string_add(json_row
, "ribNexthop",
2622 json_object_string_add(json_row
, "rpfAddress",
2624 json_object_object_add(json_group
, src_str
, json_row
);
2626 vty_out(vty
, "%-15s %-15s %-8s %-15s %-15s\n", src_str
,
2627 grp_str
, rpf_ifname
, rpf_nexthop_str
,
2633 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2634 json
, JSON_C_TO_STRING_PRETTY
));
2635 json_object_free(json
);
2639 static void show_rpf_refresh_stats(struct vty
*vty
, struct pim_instance
*pim
,
2640 time_t now
, json_object
*json
)
2642 char refresh_uptime
[10];
2644 pim_time_uptime_begin(refresh_uptime
, sizeof(refresh_uptime
), now
,
2645 pim
->rpf_cache_refresh_last
);
2648 json_object_int_add(json
, "rpfCacheRefreshDelayMsecs",
2649 qpim_rpf_cache_refresh_delay_msec
);
2650 json_object_int_add(
2651 json
, "rpfCacheRefreshTimer",
2652 pim_time_timer_remain_msec(pim
->rpf_cache_refresher
));
2653 json_object_int_add(json
, "rpfCacheRefreshRequests",
2654 pim
->rpf_cache_refresh_requests
);
2655 json_object_int_add(json
, "rpfCacheRefreshEvents",
2656 pim
->rpf_cache_refresh_events
);
2657 json_object_string_add(json
, "rpfCacheRefreshLast",
2659 json_object_int_add(json
, "nexthopLookups",
2660 pim
->nexthop_lookups
);
2661 json_object_int_add(json
, "nexthopLookupsAvoided",
2662 pim
->nexthop_lookups_avoided
);
2665 "RPF Cache Refresh Delay: %ld msecs\n"
2666 "RPF Cache Refresh Timer: %ld msecs\n"
2667 "RPF Cache Refresh Requests: %lld\n"
2668 "RPF Cache Refresh Events: %lld\n"
2669 "RPF Cache Refresh Last: %s\n"
2670 "Nexthop Lookups: %lld\n"
2671 "Nexthop Lookups Avoided: %lld\n",
2672 qpim_rpf_cache_refresh_delay_msec
,
2673 pim_time_timer_remain_msec(pim
->rpf_cache_refresher
),
2674 (long long)pim
->rpf_cache_refresh_requests
,
2675 (long long)pim
->rpf_cache_refresh_events
,
2676 refresh_uptime
, (long long)pim
->nexthop_lookups
,
2677 (long long)pim
->nexthop_lookups_avoided
);
2681 static void show_scan_oil_stats(struct pim_instance
*pim
, struct vty
*vty
,
2684 char uptime_scan_oil
[10];
2685 char uptime_mroute_add
[10];
2686 char uptime_mroute_del
[10];
2688 pim_time_uptime_begin(uptime_scan_oil
, sizeof(uptime_scan_oil
), now
,
2689 pim
->scan_oil_last
);
2690 pim_time_uptime_begin(uptime_mroute_add
, sizeof(uptime_mroute_add
), now
,
2691 pim
->mroute_add_last
);
2692 pim_time_uptime_begin(uptime_mroute_del
, sizeof(uptime_mroute_del
), now
,
2693 pim
->mroute_del_last
);
2696 "Scan OIL - Last: %s Events: %lld\n"
2697 "MFC Add - Last: %s Events: %lld\n"
2698 "MFC Del - Last: %s Events: %lld\n",
2699 uptime_scan_oil
, (long long)pim
->scan_oil_events
,
2700 uptime_mroute_add
, (long long)pim
->mroute_add_events
,
2701 uptime_mroute_del
, (long long)pim
->mroute_del_events
);
2704 static void pim_show_rpf(struct pim_instance
*pim
, struct vty
*vty
, uint8_t uj
)
2706 struct listnode
*up_node
;
2707 struct pim_upstream
*up
;
2708 time_t now
= pim_time_monotonic_sec();
2709 json_object
*json
= NULL
;
2710 json_object
*json_group
= NULL
;
2711 json_object
*json_row
= NULL
;
2714 json
= json_object_new_object();
2715 show_rpf_refresh_stats(vty
, pim
, now
, json
);
2717 show_rpf_refresh_stats(vty
, pim
, now
, json
);
2720 "Source Group RpfIface RpfAddress RibNextHop Metric Pref\n");
2723 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, up_node
, up
)) {
2724 char src_str
[INET_ADDRSTRLEN
];
2725 char grp_str
[INET_ADDRSTRLEN
];
2726 char rpf_addr_str
[PREFIX_STRLEN
];
2727 char rib_nexthop_str
[PREFIX_STRLEN
];
2728 const char *rpf_ifname
;
2729 struct pim_rpf
*rpf
= &up
->rpf
;
2731 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2732 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2733 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2734 sizeof(rpf_addr_str
));
2735 pim_addr_dump("<nexthop?>",
2736 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2737 rib_nexthop_str
, sizeof(rib_nexthop_str
));
2739 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2742 json_object_object_get_ex(json
, grp_str
, &json_group
);
2745 json_group
= json_object_new_object();
2746 json_object_object_add(json
, grp_str
,
2750 json_row
= json_object_new_object();
2751 json_object_string_add(json_row
, "source", src_str
);
2752 json_object_string_add(json_row
, "group", grp_str
);
2753 json_object_string_add(json_row
, "rpfInterface",
2755 json_object_string_add(json_row
, "rpfAddress",
2757 json_object_string_add(json_row
, "ribNexthop",
2759 json_object_int_add(
2760 json_row
, "routeMetric",
2761 rpf
->source_nexthop
.mrib_route_metric
);
2762 json_object_int_add(
2763 json_row
, "routePreference",
2764 rpf
->source_nexthop
.mrib_metric_preference
);
2765 json_object_object_add(json_group
, src_str
, json_row
);
2768 vty_out(vty
, "%-15s %-15s %-8s %-15s %-15s %6d %4d\n",
2769 src_str
, grp_str
, rpf_ifname
, rpf_addr_str
,
2771 rpf
->source_nexthop
.mrib_route_metric
,
2772 rpf
->source_nexthop
.mrib_metric_preference
);
2777 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2778 json
, JSON_C_TO_STRING_PRETTY
));
2779 json_object_free(json
);
2783 struct pnc_cache_walk_data
{
2785 struct pim_instance
*pim
;
2788 static int pim_print_pnc_cache_walkcb(struct hash_backet
*backet
, void *arg
)
2790 struct pim_nexthop_cache
*pnc
= backet
->data
;
2791 struct pnc_cache_walk_data
*cwd
= arg
;
2792 struct vty
*vty
= cwd
->vty
;
2793 struct pim_instance
*pim
= cwd
->pim
;
2794 struct nexthop
*nh_node
= NULL
;
2795 ifindex_t first_ifindex
;
2796 struct interface
*ifp
= NULL
;
2798 for (nh_node
= pnc
->nexthop
; nh_node
; nh_node
= nh_node
->next
) {
2799 first_ifindex
= nh_node
->ifindex
;
2800 ifp
= if_lookup_by_index(first_ifindex
, pim
->vrf_id
);
2802 vty_out(vty
, "%-15s ", inet_ntoa(pnc
->rpf
.rpf_addr
.u
.prefix4
));
2803 vty_out(vty
, "%-14s ", ifp
? ifp
->name
: "NULL");
2804 vty_out(vty
, "%s ", inet_ntoa(nh_node
->gate
.ipv4
));
2810 static void pim_show_nexthop(struct pim_instance
*pim
, struct vty
*vty
)
2812 struct pnc_cache_walk_data cwd
;
2816 vty_out(vty
, "Number of registered addresses: %lu\n",
2817 pim
->rpf_hash
->count
);
2818 vty_out(vty
, "Address Interface Nexthop\n");
2819 vty_out(vty
, "-------------------------------------------\n");
2821 hash_walk(pim
->rpf_hash
, pim_print_pnc_cache_walkcb
, &cwd
);
2824 static void igmp_show_groups(struct pim_instance
*pim
, struct vty
*vty
,
2827 struct interface
*ifp
;
2829 json_object
*json
= NULL
;
2830 json_object
*json_iface
= NULL
;
2831 json_object
*json_row
= NULL
;
2833 now
= pim_time_monotonic_sec();
2836 json
= json_object_new_object();
2839 "Interface Address Group Mode Timer Srcs V Uptime \n");
2841 /* scan interfaces */
2842 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2843 struct pim_interface
*pim_ifp
= ifp
->info
;
2844 struct listnode
*sock_node
;
2845 struct igmp_sock
*igmp
;
2850 /* scan igmp sockets */
2851 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
2853 char ifaddr_str
[INET_ADDRSTRLEN
];
2854 struct listnode
*grpnode
;
2855 struct igmp_group
*grp
;
2857 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
2858 sizeof(ifaddr_str
));
2860 /* scan igmp groups */
2861 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
2863 char group_str
[INET_ADDRSTRLEN
];
2867 pim_inet4_dump("<group?>", grp
->group_addr
,
2868 group_str
, sizeof(group_str
));
2869 pim_time_timer_to_hhmmss(hhmmss
, sizeof(hhmmss
),
2870 grp
->t_group_timer
);
2871 pim_time_uptime(uptime
, sizeof(uptime
),
2872 now
- grp
->group_creation
);
2875 json_object_object_get_ex(
2876 json
, ifp
->name
, &json_iface
);
2880 json_object_new_object();
2881 json_object_pim_ifp_add(
2883 json_object_object_add(
2888 json_row
= json_object_new_object();
2889 json_object_string_add(
2890 json_row
, "source", ifaddr_str
);
2891 json_object_string_add(
2892 json_row
, "group", group_str
);
2894 if (grp
->igmp_version
== 3)
2895 json_object_string_add(
2897 grp
->group_filtermode_isexcl
2901 json_object_string_add(json_row
,
2903 json_object_int_add(
2904 json_row
, "sourcesCount",
2905 grp
->group_source_list
2907 grp
->group_source_list
)
2909 json_object_int_add(json_row
, "version",
2911 json_object_string_add(
2912 json_row
, "uptime", uptime
);
2913 json_object_object_add(json_iface
,
2919 "%-9s %-15s %-15s %4s %8s %4d %d %8s\n",
2920 ifp
->name
, ifaddr_str
,
2922 grp
->igmp_version
== 3
2923 ? (grp
->group_filtermode_isexcl
2928 grp
->group_source_list
2930 grp
->group_source_list
)
2932 grp
->igmp_version
, uptime
);
2934 } /* scan igmp groups */
2935 } /* scan igmp sockets */
2936 } /* scan interfaces */
2939 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2940 json
, JSON_C_TO_STRING_PRETTY
));
2941 json_object_free(json
);
2945 static void igmp_show_group_retransmission(struct pim_instance
*pim
,
2948 struct interface
*ifp
;
2951 "Interface Address Group RetTimer Counter RetSrcs\n");
2953 /* scan interfaces */
2954 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2955 struct pim_interface
*pim_ifp
= ifp
->info
;
2956 struct listnode
*sock_node
;
2957 struct igmp_sock
*igmp
;
2962 /* scan igmp sockets */
2963 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
2965 char ifaddr_str
[INET_ADDRSTRLEN
];
2966 struct listnode
*grpnode
;
2967 struct igmp_group
*grp
;
2969 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
2970 sizeof(ifaddr_str
));
2972 /* scan igmp groups */
2973 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
2975 char group_str
[INET_ADDRSTRLEN
];
2976 char grp_retr_mmss
[10];
2977 struct listnode
*src_node
;
2978 struct igmp_source
*src
;
2979 int grp_retr_sources
= 0;
2981 pim_inet4_dump("<group?>", grp
->group_addr
,
2982 group_str
, sizeof(group_str
));
2983 pim_time_timer_to_mmss(
2984 grp_retr_mmss
, sizeof(grp_retr_mmss
),
2985 grp
->t_group_query_retransmit_timer
);
2988 /* count group sources with retransmission state
2990 for (ALL_LIST_ELEMENTS_RO(
2991 grp
->group_source_list
, src_node
,
2993 if (src
->source_query_retransmit_count
2999 vty_out(vty
, "%-9s %-15s %-15s %-8s %7d %7d\n",
3000 ifp
->name
, ifaddr_str
, group_str
,
3002 grp
->group_specific_query_retransmit_count
,
3005 } /* scan igmp groups */
3006 } /* scan igmp sockets */
3007 } /* scan interfaces */
3010 static void igmp_show_sources(struct pim_instance
*pim
, struct vty
*vty
)
3012 struct interface
*ifp
;
3015 now
= pim_time_monotonic_sec();
3018 "Interface Address Group Source Timer Fwd Uptime \n");
3020 /* scan interfaces */
3021 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3022 struct pim_interface
*pim_ifp
= ifp
->info
;
3023 struct listnode
*sock_node
;
3024 struct igmp_sock
*igmp
;
3029 /* scan igmp sockets */
3030 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3032 char ifaddr_str
[INET_ADDRSTRLEN
];
3033 struct listnode
*grpnode
;
3034 struct igmp_group
*grp
;
3036 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3037 sizeof(ifaddr_str
));
3039 /* scan igmp groups */
3040 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3042 char group_str
[INET_ADDRSTRLEN
];
3043 struct listnode
*srcnode
;
3044 struct igmp_source
*src
;
3046 pim_inet4_dump("<group?>", grp
->group_addr
,
3047 group_str
, sizeof(group_str
));
3049 /* scan group sources */
3050 for (ALL_LIST_ELEMENTS_RO(
3051 grp
->group_source_list
, srcnode
,
3053 char source_str
[INET_ADDRSTRLEN
];
3058 "<source?>", src
->source_addr
,
3059 source_str
, sizeof(source_str
));
3061 pim_time_timer_to_mmss(
3063 src
->t_source_timer
);
3066 uptime
, sizeof(uptime
),
3067 now
- src
->source_creation
);
3070 "%-9s %-15s %-15s %-15s %5s %3s %8s\n",
3071 ifp
->name
, ifaddr_str
,
3072 group_str
, source_str
, mmss
,
3073 IGMP_SOURCE_TEST_FORWARDING(
3079 } /* scan group sources */
3080 } /* scan igmp groups */
3081 } /* scan igmp sockets */
3082 } /* scan interfaces */
3085 static void igmp_show_source_retransmission(struct pim_instance
*pim
,
3088 struct interface
*ifp
;
3091 "Interface Address Group Source Counter\n");
3093 /* scan interfaces */
3094 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3095 struct pim_interface
*pim_ifp
= ifp
->info
;
3096 struct listnode
*sock_node
;
3097 struct igmp_sock
*igmp
;
3102 /* scan igmp sockets */
3103 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3105 char ifaddr_str
[INET_ADDRSTRLEN
];
3106 struct listnode
*grpnode
;
3107 struct igmp_group
*grp
;
3109 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3110 sizeof(ifaddr_str
));
3112 /* scan igmp groups */
3113 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3115 char group_str
[INET_ADDRSTRLEN
];
3116 struct listnode
*srcnode
;
3117 struct igmp_source
*src
;
3119 pim_inet4_dump("<group?>", grp
->group_addr
,
3120 group_str
, sizeof(group_str
));
3122 /* scan group sources */
3123 for (ALL_LIST_ELEMENTS_RO(
3124 grp
->group_source_list
, srcnode
,
3126 char source_str
[INET_ADDRSTRLEN
];
3129 "<source?>", src
->source_addr
,
3130 source_str
, sizeof(source_str
));
3133 "%-9s %-15s %-15s %-15s %7d\n",
3134 ifp
->name
, ifaddr_str
,
3135 group_str
, source_str
,
3136 src
->source_query_retransmit_count
);
3138 } /* scan group sources */
3139 } /* scan igmp groups */
3140 } /* scan igmp sockets */
3141 } /* scan interfaces */
3144 static void clear_igmp_interfaces(struct pim_instance
*pim
)
3146 struct interface
*ifp
;
3148 FOR_ALL_INTERFACES (pim
->vrf
, ifp
)
3149 pim_if_addr_del_all_igmp(ifp
);
3151 FOR_ALL_INTERFACES (pim
->vrf
, ifp
)
3152 pim_if_addr_add_all(ifp
);
3155 static void clear_pim_interfaces(struct pim_instance
*pim
)
3157 struct interface
*ifp
;
3159 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3161 pim_neighbor_delete_all(ifp
, "interface cleared");
3166 static void clear_interfaces(struct pim_instance
*pim
)
3168 clear_igmp_interfaces(pim
);
3169 clear_pim_interfaces(pim
);
3172 #define PIM_GET_PIM_INTERFACE(pim_ifp, ifp) \
3173 pim_ifp = ifp->info; \
3176 "%% Enable PIM and/or IGMP on this interface first\n"); \
3177 return CMD_WARNING_CONFIG_FAILED; \
3180 DEFUN (clear_ip_interfaces
,
3181 clear_ip_interfaces_cmd
,
3182 "clear ip interfaces [vrf NAME]",
3185 "Reset interfaces\n"
3189 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3194 clear_interfaces(vrf
->info
);
3199 DEFUN (clear_ip_igmp_interfaces
,
3200 clear_ip_igmp_interfaces_cmd
,
3201 "clear ip igmp [vrf NAME] interfaces",
3206 "Reset IGMP interfaces\n")
3209 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3214 clear_igmp_interfaces(vrf
->info
);
3219 static void mroute_add_all(struct pim_instance
*pim
)
3221 struct listnode
*node
;
3222 struct channel_oil
*c_oil
;
3224 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
3225 if (pim_mroute_add(c_oil
, __PRETTY_FUNCTION__
)) {
3226 /* just log warning */
3227 char source_str
[INET_ADDRSTRLEN
];
3228 char group_str
[INET_ADDRSTRLEN
];
3229 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
,
3230 source_str
, sizeof(source_str
));
3231 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
,
3232 group_str
, sizeof(group_str
));
3233 zlog_warn("%s %s: (S,G)=(%s,%s) failure writing MFC",
3234 __FILE__
, __PRETTY_FUNCTION__
, source_str
,
3240 static void mroute_del_all(struct pim_instance
*pim
)
3242 struct listnode
*node
;
3243 struct channel_oil
*c_oil
;
3245 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
3246 if (pim_mroute_del(c_oil
, __PRETTY_FUNCTION__
)) {
3247 /* just log warning */
3248 char source_str
[INET_ADDRSTRLEN
];
3249 char group_str
[INET_ADDRSTRLEN
];
3250 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
,
3251 source_str
, sizeof(source_str
));
3252 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
,
3253 group_str
, sizeof(group_str
));
3254 zlog_warn("%s %s: (S,G)=(%s,%s) failure clearing MFC",
3255 __FILE__
, __PRETTY_FUNCTION__
, source_str
,
3261 DEFUN (clear_ip_mroute
,
3262 clear_ip_mroute_cmd
,
3263 "clear ip mroute [vrf NAME]",
3266 "Reset multicast routes\n"
3270 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3275 mroute_del_all(vrf
->info
);
3276 mroute_add_all(vrf
->info
);
3281 DEFUN (clear_ip_pim_interfaces
,
3282 clear_ip_pim_interfaces_cmd
,
3283 "clear ip pim [vrf NAME] interfaces",
3288 "Reset PIM interfaces\n")
3291 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3296 clear_pim_interfaces(vrf
->info
);
3301 DEFUN (clear_ip_pim_interface_traffic
,
3302 clear_ip_pim_interface_traffic_cmd
,
3303 "clear ip pim [vrf NAME] interface traffic",
3306 "PIM clear commands\n"
3308 "Reset PIM interfaces\n"
3309 "Reset Protocol Packet counters\n")
3312 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3313 struct interface
*ifp
= NULL
;
3314 struct pim_interface
*pim_ifp
= NULL
;
3319 FOR_ALL_INTERFACES (vrf
, ifp
) {
3320 pim_ifp
= ifp
->info
;
3325 pim_ifp
->pim_ifstat_hello_recv
= 0;
3326 pim_ifp
->pim_ifstat_hello_sent
= 0;
3327 pim_ifp
->pim_ifstat_join_recv
= 0;
3328 pim_ifp
->pim_ifstat_join_send
= 0;
3329 pim_ifp
->pim_ifstat_prune_recv
= 0;
3330 pim_ifp
->pim_ifstat_prune_send
= 0;
3331 pim_ifp
->pim_ifstat_reg_recv
= 0;
3332 pim_ifp
->pim_ifstat_reg_send
= 0;
3333 pim_ifp
->pim_ifstat_reg_stop_recv
= 0;
3334 pim_ifp
->pim_ifstat_reg_stop_send
= 0;
3335 pim_ifp
->pim_ifstat_assert_recv
= 0;
3336 pim_ifp
->pim_ifstat_assert_send
= 0;
3342 DEFUN (clear_ip_pim_oil
,
3343 clear_ip_pim_oil_cmd
,
3344 "clear ip pim [vrf NAME] oil",
3349 "Rescan PIM OIL (output interface list)\n")
3352 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3357 pim_scan_oil(vrf
->info
);
3362 DEFUN (show_ip_igmp_interface
,
3363 show_ip_igmp_interface_cmd
,
3364 "show ip igmp [vrf NAME] interface [detail|WORD] [json]",
3369 "IGMP interface information\n"
3375 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3376 uint8_t uj
= use_json(argc
, argv
);
3381 if (argv_find(argv
, argc
, "detail", &idx
)
3382 || argv_find(argv
, argc
, "WORD", &idx
))
3383 igmp_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
3385 igmp_show_interfaces(vrf
->info
, vty
, uj
);
3390 DEFUN (show_ip_igmp_interface_vrf_all
,
3391 show_ip_igmp_interface_vrf_all_cmd
,
3392 "show ip igmp vrf all interface [detail|WORD] [json]",
3397 "IGMP interface information\n"
3403 uint8_t uj
= use_json(argc
, argv
);
3409 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3413 vty_out(vty
, " \"%s\": ", vrf
->name
);
3416 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3417 if (argv_find(argv
, argc
, "detail", &idx
)
3418 || argv_find(argv
, argc
, "WORD", &idx
))
3419 igmp_show_interfaces_single(vrf
->info
, vty
,
3420 argv
[idx
]->arg
, uj
);
3422 igmp_show_interfaces(vrf
->info
, vty
, uj
);
3425 vty_out(vty
, "}\n");
3430 DEFUN (show_ip_igmp_join
,
3431 show_ip_igmp_join_cmd
,
3432 "show ip igmp [vrf NAME] join",
3437 "IGMP static join information\n")
3440 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3445 igmp_show_interface_join(vrf
->info
, vty
);
3450 DEFUN (show_ip_igmp_join_vrf_all
,
3451 show_ip_igmp_join_vrf_all_cmd
,
3452 "show ip igmp vrf all join",
3457 "IGMP static join information\n")
3459 uint8_t uj
= use_json(argc
, argv
);
3465 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3469 vty_out(vty
, " \"%s\": ", vrf
->name
);
3472 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3473 igmp_show_interface_join(vrf
->info
, vty
);
3476 vty_out(vty
, "}\n");
3481 DEFUN (show_ip_igmp_groups
,
3482 show_ip_igmp_groups_cmd
,
3483 "show ip igmp [vrf NAME] groups [json]",
3492 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3493 uint8_t uj
= use_json(argc
, argv
);
3498 igmp_show_groups(vrf
->info
, vty
, uj
);
3503 DEFUN (show_ip_igmp_groups_vrf_all
,
3504 show_ip_igmp_groups_vrf_all_cmd
,
3505 "show ip igmp vrf all groups [json]",
3513 uint8_t uj
= use_json(argc
, argv
);
3519 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3523 vty_out(vty
, " \"%s\": ", vrf
->name
);
3526 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3527 igmp_show_groups(vrf
->info
, vty
, uj
);
3530 vty_out(vty
, "}\n");
3535 DEFUN (show_ip_igmp_groups_retransmissions
,
3536 show_ip_igmp_groups_retransmissions_cmd
,
3537 "show ip igmp [vrf NAME] groups retransmissions",
3543 "IGMP group retransmissions\n")
3546 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3551 igmp_show_group_retransmission(vrf
->info
, vty
);
3556 DEFUN (show_ip_igmp_sources
,
3557 show_ip_igmp_sources_cmd
,
3558 "show ip igmp [vrf NAME] sources",
3566 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3571 igmp_show_sources(vrf
->info
, vty
);
3576 DEFUN (show_ip_igmp_sources_retransmissions
,
3577 show_ip_igmp_sources_retransmissions_cmd
,
3578 "show ip igmp [vrf NAME] sources retransmissions",
3584 "IGMP source retransmissions\n")
3587 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3592 igmp_show_source_retransmission(vrf
->info
, vty
);
3597 DEFUN (show_ip_igmp_statistics
,
3598 show_ip_igmp_statistics_cmd
,
3599 "show ip igmp [vrf NAME] statistics [interface WORD] [json]",
3610 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3611 uint8_t uj
= use_json(argc
, argv
);
3616 if (argv_find(argv
, argc
, "WORD", &idx
))
3617 igmp_show_statistics(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
3619 igmp_show_statistics(vrf
->info
, vty
, NULL
, uj
);
3624 DEFUN (show_ip_pim_assert
,
3625 show_ip_pim_assert_cmd
,
3626 "show ip pim [vrf NAME] assert",
3631 "PIM interface assert\n")
3634 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3639 pim_show_assert(vrf
->info
, vty
);
3644 DEFUN (show_ip_pim_assert_internal
,
3645 show_ip_pim_assert_internal_cmd
,
3646 "show ip pim [vrf NAME] assert-internal",
3651 "PIM interface internal assert state\n")
3654 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3659 pim_show_assert_internal(vrf
->info
, vty
);
3664 DEFUN (show_ip_pim_assert_metric
,
3665 show_ip_pim_assert_metric_cmd
,
3666 "show ip pim [vrf NAME] assert-metric",
3671 "PIM interface assert metric\n")
3674 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3679 pim_show_assert_metric(vrf
->info
, vty
);
3684 DEFUN (show_ip_pim_assert_winner_metric
,
3685 show_ip_pim_assert_winner_metric_cmd
,
3686 "show ip pim [vrf NAME] assert-winner-metric",
3691 "PIM interface assert winner metric\n")
3694 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3699 pim_show_assert_winner_metric(vrf
->info
, vty
);
3704 DEFUN (show_ip_pim_interface
,
3705 show_ip_pim_interface_cmd
,
3706 "show ip pim [vrf NAME] interface [detail|WORD] [json]",
3711 "PIM interface information\n"
3717 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3718 uint8_t uj
= use_json(argc
, argv
);
3723 if (argv_find(argv
, argc
, "WORD", &idx
)
3724 || argv_find(argv
, argc
, "detail", &idx
))
3725 pim_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
3727 pim_show_interfaces(vrf
->info
, vty
, uj
);
3732 DEFUN (show_ip_pim_interface_vrf_all
,
3733 show_ip_pim_interface_vrf_all_cmd
,
3734 "show ip pim vrf all interface [detail|WORD] [json]",
3739 "PIM interface information\n"
3745 uint8_t uj
= use_json(argc
, argv
);
3751 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3755 vty_out(vty
, " \"%s\": ", vrf
->name
);
3758 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3759 if (argv_find(argv
, argc
, "WORD", &idx
)
3760 || argv_find(argv
, argc
, "detail", &idx
))
3761 pim_show_interfaces_single(vrf
->info
, vty
,
3762 argv
[idx
]->arg
, uj
);
3764 pim_show_interfaces(vrf
->info
, vty
, uj
);
3767 vty_out(vty
, "}\n");
3772 DEFUN (show_ip_pim_join
,
3773 show_ip_pim_join_cmd
,
3774 "show ip pim [vrf NAME] join [json]",
3779 "PIM interface join information\n"
3783 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3784 uint8_t uj
= use_json(argc
, argv
);
3789 pim_show_join(vrf
->info
, vty
, uj
);
3794 DEFUN (show_ip_pim_join_vrf_all
,
3795 show_ip_pim_join_vrf_all_cmd
,
3796 "show ip pim vrf all join [json]",
3801 "PIM interface join information\n"
3804 uint8_t uj
= use_json(argc
, argv
);
3810 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3814 vty_out(vty
, " \"%s\": ", vrf
->name
);
3817 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3818 pim_show_join(vrf
->info
, vty
, uj
);
3821 vty_out(vty
, "}\n");
3826 DEFUN (show_ip_pim_local_membership
,
3827 show_ip_pim_local_membership_cmd
,
3828 "show ip pim [vrf NAME] local-membership [json]",
3833 "PIM interface local-membership\n"
3837 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3838 uint8_t uj
= use_json(argc
, argv
);
3843 pim_show_membership(vrf
->info
, vty
, uj
);
3848 DEFUN (show_ip_pim_neighbor
,
3849 show_ip_pim_neighbor_cmd
,
3850 "show ip pim [vrf NAME] neighbor [detail|WORD] [json]",
3855 "PIM neighbor information\n"
3857 "Name of interface or neighbor\n"
3861 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3862 uint8_t uj
= use_json(argc
, argv
);
3867 if (argv_find(argv
, argc
, "detail", &idx
)
3868 || argv_find(argv
, argc
, "WORD", &idx
))
3869 pim_show_neighbors_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
3871 pim_show_neighbors(vrf
->info
, vty
, uj
);
3876 DEFUN (show_ip_pim_neighbor_vrf_all
,
3877 show_ip_pim_neighbor_vrf_all_cmd
,
3878 "show ip pim vrf all neighbor [detail|WORD] [json]",
3883 "PIM neighbor information\n"
3885 "Name of interface or neighbor\n"
3889 uint8_t uj
= use_json(argc
, argv
);
3895 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3899 vty_out(vty
, " \"%s\": ", vrf
->name
);
3902 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3903 if (argv_find(argv
, argc
, "detail", &idx
)
3904 || argv_find(argv
, argc
, "WORD", &idx
))
3905 pim_show_neighbors_single(vrf
->info
, vty
,
3906 argv
[idx
]->arg
, uj
);
3908 pim_show_neighbors(vrf
->info
, vty
, uj
);
3911 vty_out(vty
, "}\n");
3916 DEFUN (show_ip_pim_secondary
,
3917 show_ip_pim_secondary_cmd
,
3918 "show ip pim [vrf NAME] secondary",
3923 "PIM neighbor addresses\n")
3926 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3931 pim_show_neighbors_secondary(vrf
->info
, vty
);
3936 DEFUN (show_ip_pim_state
,
3937 show_ip_pim_state_cmd
,
3938 "show ip pim [vrf NAME] state [A.B.C.D [A.B.C.D]] [json]",
3943 "PIM state information\n"
3944 "Unicast or Multicast address\n"
3945 "Multicast address\n"
3948 const char *src_or_group
= NULL
;
3949 const char *group
= NULL
;
3951 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3952 uint8_t uj
= use_json(argc
, argv
);
3960 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
3961 src_or_group
= argv
[idx
]->arg
;
3963 group
= argv
[idx
+ 1]->arg
;
3966 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
3971 DEFUN (show_ip_pim_state_vrf_all
,
3972 show_ip_pim_state_vrf_all_cmd
,
3973 "show ip pim vrf all state [A.B.C.D [A.B.C.D]] [json]",
3978 "PIM state information\n"
3979 "Unicast or Multicast address\n"
3980 "Multicast address\n"
3983 const char *src_or_group
= NULL
;
3984 const char *group
= NULL
;
3986 uint8_t uj
= use_json(argc
, argv
);
3995 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
3996 src_or_group
= argv
[idx
]->arg
;
3998 group
= argv
[idx
+ 1]->arg
;
4001 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4005 vty_out(vty
, " \"%s\": ", vrf
->name
);
4008 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4009 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
4012 vty_out(vty
, "}\n");
4017 DEFUN (show_ip_pim_upstream
,
4018 show_ip_pim_upstream_cmd
,
4019 "show ip pim [vrf NAME] upstream [json]",
4024 "PIM upstream information\n"
4028 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4029 uint8_t uj
= use_json(argc
, argv
);
4034 pim_show_upstream(vrf
->info
, vty
, uj
);
4039 DEFUN (show_ip_pim_upstream_vrf_all
,
4040 show_ip_pim_upstream_vrf_all_cmd
,
4041 "show ip pim vrf all upstream [json]",
4046 "PIM upstream information\n"
4049 uint8_t uj
= use_json(argc
, argv
);
4055 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4059 vty_out(vty
, " \"%s\": ", vrf
->name
);
4062 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4063 pim_show_upstream(vrf
->info
, vty
, uj
);
4069 DEFUN (show_ip_pim_upstream_join_desired
,
4070 show_ip_pim_upstream_join_desired_cmd
,
4071 "show ip pim [vrf NAME] upstream-join-desired [json]",
4076 "PIM upstream join-desired\n"
4080 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4081 uint8_t uj
= use_json(argc
, argv
);
4086 pim_show_join_desired(vrf
->info
, vty
, uj
);
4091 DEFUN (show_ip_pim_upstream_rpf
,
4092 show_ip_pim_upstream_rpf_cmd
,
4093 "show ip pim [vrf NAME] upstream-rpf [json]",
4098 "PIM upstream source rpf\n"
4102 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4103 uint8_t uj
= use_json(argc
, argv
);
4108 pim_show_upstream_rpf(vrf
->info
, vty
, uj
);
4113 DEFUN (show_ip_pim_rp
,
4115 "show ip pim [vrf NAME] rp-info [json]",
4120 "PIM RP information\n"
4124 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4125 uint8_t uj
= use_json(argc
, argv
);
4130 pim_rp_show_information(vrf
->info
, vty
, uj
);
4135 DEFUN (show_ip_pim_rp_vrf_all
,
4136 show_ip_pim_rp_vrf_all_cmd
,
4137 "show ip pim vrf all rp-info [json]",
4142 "PIM RP information\n"
4145 uint8_t uj
= use_json(argc
, argv
);
4151 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4155 vty_out(vty
, " \"%s\": ", vrf
->name
);
4158 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4159 pim_rp_show_information(vrf
->info
, vty
, uj
);
4162 vty_out(vty
, "}\n");
4167 DEFUN (show_ip_pim_rpf
,
4168 show_ip_pim_rpf_cmd
,
4169 "show ip pim [vrf NAME] rpf [json]",
4174 "PIM cached source rpf information\n"
4178 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4179 uint8_t uj
= use_json(argc
, argv
);
4184 pim_show_rpf(vrf
->info
, vty
, uj
);
4189 DEFUN (show_ip_pim_rpf_vrf_all
,
4190 show_ip_pim_rpf_vrf_all_cmd
,
4191 "show ip pim vrf all rpf [json]",
4196 "PIM cached source rpf information\n"
4199 uint8_t uj
= use_json(argc
, argv
);
4205 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4209 vty_out(vty
, " \"%s\": ", vrf
->name
);
4212 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4213 pim_show_rpf(vrf
->info
, vty
, uj
);
4216 vty_out(vty
, "}\n");
4221 DEFUN (show_ip_pim_nexthop
,
4222 show_ip_pim_nexthop_cmd
,
4223 "show ip pim [vrf NAME] nexthop",
4228 "PIM cached nexthop rpf information\n")
4231 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4236 pim_show_nexthop(vrf
->info
, vty
);
4241 DEFUN (show_ip_pim_nexthop_lookup
,
4242 show_ip_pim_nexthop_lookup_cmd
,
4243 "show ip pim [vrf NAME] nexthop-lookup A.B.C.D A.B.C.D",
4248 "PIM cached nexthop rpf lookup\n"
4249 "Source/RP address\n"
4250 "Multicast Group address\n")
4252 struct pim_nexthop_cache
*pnc
= NULL
;
4253 struct prefix nht_p
;
4255 struct in_addr src_addr
, grp_addr
;
4256 struct in_addr vif_source
;
4257 const char *addr_str
, *addr_str1
;
4259 struct pim_nexthop nexthop
;
4260 char nexthop_addr_str
[PREFIX_STRLEN
];
4261 char grp_str
[PREFIX_STRLEN
];
4263 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4269 argv_find(argv
, argc
, "A.B.C.D", &idx
);
4270 addr_str
= argv
[idx
]->arg
;
4271 result
= inet_pton(AF_INET
, addr_str
, &src_addr
);
4273 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
4274 errno
, safe_strerror(errno
));
4278 if (pim_is_group_224_4(src_addr
)) {
4280 "Invalid argument. Expected Valid Source Address.\n");
4284 addr_str1
= argv
[idx
+ 1]->arg
;
4285 result
= inet_pton(AF_INET
, addr_str1
, &grp_addr
);
4287 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
4288 errno
, safe_strerror(errno
));
4292 if (!pim_is_group_224_4(grp_addr
)) {
4294 "Invalid argument. Expected Valid Multicast Group Address.\n");
4298 if (!pim_rp_set_upstream_addr(vrf
->info
, &vif_source
, src_addr
,
4302 nht_p
.family
= AF_INET
;
4303 nht_p
.prefixlen
= IPV4_MAX_BITLEN
;
4304 nht_p
.u
.prefix4
= vif_source
;
4305 grp
.family
= AF_INET
;
4306 grp
.prefixlen
= IPV4_MAX_BITLEN
;
4307 grp
.u
.prefix4
= grp_addr
;
4308 memset(&nexthop
, 0, sizeof(nexthop
));
4310 memset(&rpf
, 0, sizeof(struct pim_rpf
));
4311 rpf
.rpf_addr
.family
= AF_INET
;
4312 rpf
.rpf_addr
.prefixlen
= IPV4_MAX_BITLEN
;
4313 rpf
.rpf_addr
.u
.prefix4
= vif_source
;
4315 pnc
= pim_nexthop_cache_find(vrf
->info
, &rpf
);
4317 result
= pim_ecmp_nexthop_search(vrf
->info
, pnc
, &nexthop
,
4320 result
= pim_ecmp_nexthop_lookup(vrf
->info
, &nexthop
, &nht_p
,
4325 "Nexthop Lookup failed, no usable routes returned.\n");
4329 pim_addr_dump("<grp?>", &grp
, grp_str
, sizeof(grp_str
));
4330 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
4331 nexthop_addr_str
, sizeof(nexthop_addr_str
));
4332 vty_out(vty
, "Group %s --- Nexthop %s Interface %s \n", grp_str
,
4333 nexthop_addr_str
, nexthop
.interface
->name
);
4338 DEFUN (show_ip_pim_interface_traffic
,
4339 show_ip_pim_interface_traffic_cmd
,
4340 "show ip pim [vrf NAME] interface traffic [WORD] [json]",
4345 "PIM interface information\n"
4346 "Protocol Packet counters\n"
4351 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4352 uint8_t uj
= use_json(argc
, argv
);
4357 if (argv_find(argv
, argc
, "WORD", &idx
))
4358 pim_show_interface_traffic_single(vrf
->info
, vty
,
4359 argv
[idx
]->arg
, uj
);
4361 pim_show_interface_traffic(vrf
->info
, vty
, uj
);
4366 static void show_multicast_interfaces(struct pim_instance
*pim
, struct vty
*vty
)
4368 struct interface
*ifp
;
4373 "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut\n");
4375 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
4376 struct pim_interface
*pim_ifp
;
4377 struct in_addr ifaddr
;
4378 struct sioc_vif_req vreq
;
4380 pim_ifp
= ifp
->info
;
4385 memset(&vreq
, 0, sizeof(vreq
));
4386 vreq
.vifi
= pim_ifp
->mroute_vif_index
;
4388 if (ioctl(pim
->mroute_socket
, SIOCGETVIFCNT
, &vreq
)) {
4390 "ioctl(SIOCGETVIFCNT=%lu) failure for interface %s vif_index=%d: errno=%d: %s",
4391 (unsigned long)SIOCGETVIFCNT
, ifp
->name
,
4392 pim_ifp
->mroute_vif_index
, errno
,
4393 safe_strerror(errno
));
4396 ifaddr
= pim_ifp
->primary_address
;
4398 vty_out(vty
, "%-12s %-15s %3d %3d %7lu %7lu %10lu %10lu\n",
4399 ifp
->name
, inet_ntoa(ifaddr
), ifp
->ifindex
,
4400 pim_ifp
->mroute_vif_index
, (unsigned long)vreq
.icount
,
4401 (unsigned long)vreq
.ocount
, (unsigned long)vreq
.ibytes
,
4402 (unsigned long)vreq
.obytes
);
4406 static void pim_cmd_show_ip_multicast_helper(struct pim_instance
*pim
,
4409 struct vrf
*vrf
= pim
->vrf
;
4410 time_t now
= pim_time_monotonic_sec();
4415 vty_out(vty
, "Mroute socket descriptor:");
4417 vty_out(vty
, " %d(%s)\n", pim
->mroute_socket
, vrf
->name
);
4419 pim_time_uptime(uptime
, sizeof(uptime
),
4420 now
- pim
->mroute_socket_creation
);
4421 vty_out(vty
, "Mroute socket uptime: %s\n", uptime
);
4425 pim_zebra_zclient_update(vty
);
4426 pim_zlookup_show_ip_multicast(vty
);
4429 vty_out(vty
, "Maximum highest VifIndex: %d\n", PIM_MAX_USABLE_VIFS
);
4432 vty_out(vty
, "Upstream Join Timer: %d secs\n", qpim_t_periodic
);
4433 vty_out(vty
, "Join/Prune Holdtime: %d secs\n", PIM_JP_HOLDTIME
);
4434 vty_out(vty
, "PIM ECMP: %s\n", pim
->ecmp_enable
? "Enable" : "Disable");
4435 vty_out(vty
, "PIM ECMP Rebalance: %s\n",
4436 pim
->ecmp_rebalance_enable
? "Enable" : "Disable");
4440 show_rpf_refresh_stats(vty
, pim
, now
, NULL
);
4444 show_scan_oil_stats(pim
, vty
, now
);
4446 show_multicast_interfaces(pim
, vty
);
4449 DEFUN (show_ip_multicast
,
4450 show_ip_multicast_cmd
,
4451 "show ip multicast [vrf NAME]",
4455 "Multicast global information\n")
4458 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4463 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
4468 DEFUN (show_ip_multicast_vrf_all
,
4469 show_ip_multicast_vrf_all_cmd
,
4470 "show ip multicast vrf all",
4474 "Multicast global information\n")
4476 uint8_t uj
= use_json(argc
, argv
);
4482 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4486 vty_out(vty
, " \"%s\": ", vrf
->name
);
4489 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4490 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
4493 vty_out(vty
, "}\n");
4498 static void show_mroute(struct pim_instance
*pim
, struct vty
*vty
, bool fill
,
4501 struct listnode
*node
;
4502 struct channel_oil
*c_oil
;
4503 struct static_route
*s_route
;
4505 json_object
*json
= NULL
;
4506 json_object
*json_group
= NULL
;
4507 json_object
*json_source
= NULL
;
4508 json_object
*json_oil
= NULL
;
4509 json_object
*json_ifp_out
= NULL
;
4512 char grp_str
[INET_ADDRSTRLEN
];
4513 char src_str
[INET_ADDRSTRLEN
];
4514 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
4515 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
4517 struct interface
*ifp_in
;
4521 json
= json_object_new_object();
4524 "Source Group Proto Input Output TTL Uptime\n");
4527 now
= pim_time_monotonic_sec();
4529 /* print list of PIM and IGMP routes */
4530 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
4533 if (!c_oil
->installed
&& !uj
)
4536 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
4538 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
4540 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
4543 strcpy(in_ifname
, ifp_in
->name
);
4545 strcpy(in_ifname
, "<iif?>");
4549 /* Find the group, create it if it doesn't exist */
4550 json_object_object_get_ex(json
, grp_str
, &json_group
);
4553 json_group
= json_object_new_object();
4554 json_object_object_add(json
, grp_str
,
4558 /* Find the source nested under the group, create it if
4559 * it doesn't exist */
4560 json_object_object_get_ex(json_group
, src_str
,
4564 json_source
= json_object_new_object();
4565 json_object_object_add(json_group
, src_str
,
4569 /* Find the inbound interface nested under the source,
4570 * create it if it doesn't exist */
4571 json_object_int_add(json_source
, "installed",
4573 json_object_int_add(json_source
, "refCount",
4574 c_oil
->oil_ref_count
);
4575 json_object_int_add(json_source
, "oilSize",
4577 json_object_int_add(json_source
, "OilInheritedRescan",
4578 c_oil
->oil_inherited_rescan
);
4579 json_object_string_add(json_source
, "iif", in_ifname
);
4583 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
4585 struct interface
*ifp_out
;
4586 char oif_uptime
[10];
4589 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
4593 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
4595 oif_uptime
, sizeof(oif_uptime
),
4596 now
- c_oil
->oif_creation
[oif_vif_index
]);
4600 strcpy(out_ifname
, ifp_out
->name
);
4602 strcpy(out_ifname
, "<oif?>");
4605 json_ifp_out
= json_object_new_object();
4606 json_object_string_add(json_ifp_out
, "source",
4608 json_object_string_add(json_ifp_out
, "group",
4611 if (c_oil
->oif_flags
[oif_vif_index
]
4612 & PIM_OIF_FLAG_PROTO_PIM
)
4613 json_object_boolean_true_add(
4614 json_ifp_out
, "protocolPim");
4616 if (c_oil
->oif_flags
[oif_vif_index
]
4617 & PIM_OIF_FLAG_PROTO_IGMP
)
4618 json_object_boolean_true_add(
4619 json_ifp_out
, "protocolIgmp");
4621 if (c_oil
->oif_flags
[oif_vif_index
]
4622 & PIM_OIF_FLAG_PROTO_SOURCE
)
4623 json_object_boolean_true_add(
4624 json_ifp_out
, "protocolSource");
4626 if (c_oil
->oif_flags
[oif_vif_index
]
4627 & PIM_OIF_FLAG_PROTO_STAR
)
4628 json_object_boolean_true_add(
4630 "protocolInherited");
4632 json_object_string_add(json_ifp_out
,
4635 json_object_int_add(json_ifp_out
, "iVifI",
4636 c_oil
->oil
.mfcc_parent
);
4637 json_object_string_add(json_ifp_out
,
4638 "outboundInterface",
4640 json_object_int_add(json_ifp_out
, "oVifI",
4642 json_object_int_add(json_ifp_out
, "ttl", ttl
);
4643 json_object_string_add(json_ifp_out
, "upTime",
4646 json_oil
= json_object_new_object();
4647 json_object_object_add(json_source
,
4650 json_object_object_add(json_oil
, out_ifname
,
4653 if (c_oil
->oif_flags
[oif_vif_index
]
4654 & PIM_OIF_FLAG_PROTO_PIM
) {
4655 strcpy(proto
, "PIM");
4658 if (c_oil
->oif_flags
[oif_vif_index
]
4659 & PIM_OIF_FLAG_PROTO_IGMP
) {
4660 strcpy(proto
, "IGMP");
4663 if (c_oil
->oif_flags
[oif_vif_index
]
4664 & PIM_OIF_FLAG_PROTO_SOURCE
) {
4665 strcpy(proto
, "SRC");
4668 if (c_oil
->oif_flags
[oif_vif_index
]
4669 & PIM_OIF_FLAG_PROTO_STAR
) {
4670 strcpy(proto
, "STAR");
4674 "%-15s %-15s %-6s %-10s %-10s %-3d %8s\n",
4675 src_str
, grp_str
, proto
, in_ifname
,
4676 out_ifname
, ttl
, oif_uptime
);
4681 in_ifname
[0] = '\0';
4687 if (!uj
&& !found_oif
) {
4688 vty_out(vty
, "%-15s %-15s %-6s %-10s %-10s %-3d %8s\n",
4689 src_str
, grp_str
, "none", in_ifname
, "none", 0,
4694 /* Print list of static routes */
4695 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
4698 if (!s_route
->c_oil
.installed
)
4701 pim_inet4_dump("<group?>", s_route
->group
, grp_str
,
4703 pim_inet4_dump("<source?>", s_route
->source
, src_str
,
4705 ifp_in
= pim_if_find_by_vif_index(pim
, s_route
->iif
);
4709 strcpy(in_ifname
, ifp_in
->name
);
4711 strcpy(in_ifname
, "<iif?>");
4715 /* Find the group, create it if it doesn't exist */
4716 json_object_object_get_ex(json
, grp_str
, &json_group
);
4719 json_group
= json_object_new_object();
4720 json_object_object_add(json
, grp_str
,
4724 /* Find the source nested under the group, create it if
4725 * it doesn't exist */
4726 json_object_object_get_ex(json_group
, src_str
,
4730 json_source
= json_object_new_object();
4731 json_object_object_add(json_group
, src_str
,
4735 json_object_string_add(json_source
, "iif", in_ifname
);
4738 strcpy(proto
, "STATIC");
4741 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
4743 struct interface
*ifp_out
;
4744 char oif_uptime
[10];
4747 ttl
= s_route
->oif_ttls
[oif_vif_index
];
4751 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
4753 oif_uptime
, sizeof(oif_uptime
),
4756 .oif_creation
[oif_vif_index
]);
4760 strcpy(out_ifname
, ifp_out
->name
);
4762 strcpy(out_ifname
, "<oif?>");
4765 json_ifp_out
= json_object_new_object();
4766 json_object_string_add(json_ifp_out
, "source",
4768 json_object_string_add(json_ifp_out
, "group",
4770 json_object_boolean_true_add(json_ifp_out
,
4772 json_object_string_add(json_ifp_out
,
4775 json_object_int_add(
4776 json_ifp_out
, "iVifI",
4777 s_route
->c_oil
.oil
.mfcc_parent
);
4778 json_object_string_add(json_ifp_out
,
4779 "outboundInterface",
4781 json_object_int_add(json_ifp_out
, "oVifI",
4783 json_object_int_add(json_ifp_out
, "ttl", ttl
);
4784 json_object_string_add(json_ifp_out
, "upTime",
4787 json_oil
= json_object_new_object();
4788 json_object_object_add(json_source
,
4791 json_object_object_add(json_oil
, out_ifname
,
4795 "%-15s %-15s %-6s %-10s %-10s %-3d %8s %s\n",
4796 src_str
, grp_str
, proto
, in_ifname
,
4797 out_ifname
, ttl
, oif_uptime
,
4799 if (first
&& !fill
) {
4802 in_ifname
[0] = '\0';
4808 if (!uj
&& !found_oif
) {
4810 "%-15s %-15s %-6s %-10s %-10s %-3d %8s %s\n",
4811 src_str
, grp_str
, proto
, in_ifname
, "none", 0,
4812 "--:--:--", pim
->vrf
->name
);
4817 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4818 json
, JSON_C_TO_STRING_PRETTY
));
4819 json_object_free(json
);
4823 DEFUN (show_ip_mroute
,
4825 "show ip mroute [vrf NAME] [fill] [json]",
4830 "Fill in Assumed data\n"
4833 uint8_t uj
= use_json(argc
, argv
);
4836 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4841 if (argv_find(argv
, argc
, "fill", &idx
))
4844 show_mroute(vrf
->info
, vty
, fill
, uj
);
4848 DEFUN (show_ip_mroute_vrf_all
,
4849 show_ip_mroute_vrf_all_cmd
,
4850 "show ip mroute vrf all [fill] [json]",
4855 "Fill in Assumed data\n"
4858 uint8_t uj
= use_json(argc
, argv
);
4864 if (argv_find(argv
, argc
, "fill", &idx
))
4869 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4873 vty_out(vty
, " \"%s\": ", vrf
->name
);
4876 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4877 show_mroute(vrf
->info
, vty
, fill
, uj
);
4880 vty_out(vty
, "}\n");
4885 static void show_mroute_count(struct pim_instance
*pim
, struct vty
*vty
)
4887 struct listnode
*node
;
4888 struct channel_oil
*c_oil
;
4889 struct static_route
*s_route
;
4894 "Source Group LastUsed Packets Bytes WrongIf \n");
4896 /* Print PIM and IGMP route counts */
4897 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
4898 char group_str
[INET_ADDRSTRLEN
];
4899 char source_str
[INET_ADDRSTRLEN
];
4901 if (!c_oil
->installed
)
4904 pim_mroute_update_counters(c_oil
);
4906 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, group_str
,
4908 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, source_str
,
4909 sizeof(source_str
));
4911 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
4912 source_str
, group_str
, c_oil
->cc
.lastused
/ 100,
4913 c_oil
->cc
.pktcnt
, c_oil
->cc
.bytecnt
,
4914 c_oil
->cc
.wrong_if
);
4917 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
4918 char group_str
[INET_ADDRSTRLEN
];
4919 char source_str
[INET_ADDRSTRLEN
];
4921 if (!s_route
->c_oil
.installed
)
4924 pim_mroute_update_counters(&s_route
->c_oil
);
4926 pim_inet4_dump("<group?>", s_route
->c_oil
.oil
.mfcc_mcastgrp
,
4927 group_str
, sizeof(group_str
));
4928 pim_inet4_dump("<source?>", s_route
->c_oil
.oil
.mfcc_origin
,
4929 source_str
, sizeof(source_str
));
4931 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
4932 source_str
, group_str
, s_route
->c_oil
.cc
.lastused
,
4933 s_route
->c_oil
.cc
.pktcnt
, s_route
->c_oil
.cc
.bytecnt
,
4934 s_route
->c_oil
.cc
.wrong_if
);
4938 DEFUN (show_ip_mroute_count
,
4939 show_ip_mroute_count_cmd
,
4940 "show ip mroute [vrf NAME] count",
4945 "Route and packet count data\n")
4948 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4953 show_mroute_count(vrf
->info
, vty
);
4957 DEFUN (show_ip_mroute_count_vrf_all
,
4958 show_ip_mroute_count_vrf_all_cmd
,
4959 "show ip mroute vrf all count",
4964 "Route and packet count data\n")
4966 uint8_t uj
= use_json(argc
, argv
);
4972 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4976 vty_out(vty
, " \"%s\": ", vrf
->name
);
4979 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4980 show_mroute_count(vrf
->info
, vty
);
4983 vty_out(vty
, "}\n");
4990 "show ip rib [vrf NAME] A.B.C.D",
4995 "Unicast address\n")
4998 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4999 struct in_addr addr
;
5000 const char *addr_str
;
5001 struct pim_nexthop nexthop
;
5002 char nexthop_addr_str
[PREFIX_STRLEN
];
5008 memset(&nexthop
, 0, sizeof(nexthop
));
5009 argv_find(argv
, argc
, "A.B.C.D", &idx
);
5010 addr_str
= argv
[idx
]->arg
;
5011 result
= inet_pton(AF_INET
, addr_str
, &addr
);
5013 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
5014 errno
, safe_strerror(errno
));
5018 if (pim_nexthop_lookup(vrf
->info
, &nexthop
, addr
, 0)) {
5020 "Failure querying RIB nexthop for unicast address %s\n",
5026 "Address NextHop Interface Metric Preference\n");
5028 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
5029 nexthop_addr_str
, sizeof(nexthop_addr_str
));
5031 vty_out(vty
, "%-15s %-15s %-9s %6d %10d\n", addr_str
, nexthop_addr_str
,
5032 nexthop
.interface
? nexthop
.interface
->name
: "<ifname?>",
5033 nexthop
.mrib_route_metric
, nexthop
.mrib_metric_preference
);
5038 static void show_ssmpingd(struct pim_instance
*pim
, struct vty
*vty
)
5040 struct listnode
*node
;
5041 struct ssmpingd_sock
*ss
;
5045 "Source Socket Address Port Uptime Requests\n");
5047 if (!pim
->ssmpingd_list
)
5050 now
= pim_time_monotonic_sec();
5052 for (ALL_LIST_ELEMENTS_RO(pim
->ssmpingd_list
, node
, ss
)) {
5053 char source_str
[INET_ADDRSTRLEN
];
5055 struct sockaddr_in bind_addr
;
5056 socklen_t len
= sizeof(bind_addr
);
5057 char bind_addr_str
[INET_ADDRSTRLEN
];
5059 pim_inet4_dump("<src?>", ss
->source_addr
, source_str
,
5060 sizeof(source_str
));
5062 if (pim_socket_getsockname(
5063 ss
->sock_fd
, (struct sockaddr
*)&bind_addr
, &len
)) {
5065 "%% Failure reading socket name for ssmpingd source %s on fd=%d\n",
5066 source_str
, ss
->sock_fd
);
5069 pim_inet4_dump("<addr?>", bind_addr
.sin_addr
, bind_addr_str
,
5070 sizeof(bind_addr_str
));
5071 pim_time_uptime(ss_uptime
, sizeof(ss_uptime
),
5072 now
- ss
->creation
);
5074 vty_out(vty
, "%-15s %6d %-15s %5d %8s %8lld\n", source_str
,
5075 ss
->sock_fd
, bind_addr_str
, ntohs(bind_addr
.sin_port
),
5076 ss_uptime
, (long long)ss
->requests
);
5080 DEFUN (show_ip_ssmpingd
,
5081 show_ip_ssmpingd_cmd
,
5082 "show ip ssmpingd [vrf NAME]",
5089 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5094 show_ssmpingd(vrf
->info
, vty
);
5098 static int pim_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
5099 const char *rp
, const char *group
,
5104 result
= pim_rp_new(pim
, rp
, group
, plist
);
5106 if (result
== PIM_GROUP_BAD_ADDRESS
) {
5107 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
5108 return CMD_WARNING_CONFIG_FAILED
;
5111 if (result
== PIM_RP_BAD_ADDRESS
) {
5112 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
5113 return CMD_WARNING_CONFIG_FAILED
;
5116 if (result
== PIM_RP_NO_PATH
) {
5117 vty_out(vty
, "%% No Path to RP address specified: %s\n", rp
);
5121 if (result
== PIM_GROUP_OVERLAP
) {
5123 "%% Group range specified cannot exact match another\n");
5124 return CMD_WARNING_CONFIG_FAILED
;
5127 if (result
== PIM_GROUP_PFXLIST_OVERLAP
) {
5129 "%% This group is already covered by a RP prefix-list\n");
5130 return CMD_WARNING_CONFIG_FAILED
;
5133 if (result
== PIM_RP_PFXLIST_IN_USE
) {
5135 "%% The same prefix-list cannot be applied to multiple RPs\n");
5136 return CMD_WARNING_CONFIG_FAILED
;
5142 static int pim_cmd_spt_switchover(struct pim_instance
*pim
,
5143 enum pim_spt_switchover spt
,
5146 pim
->spt
.switchover
= spt
;
5148 switch (pim
->spt
.switchover
) {
5149 case PIM_SPT_IMMEDIATE
:
5151 XFREE(MTYPE_PIM_SPT_PLIST_NAME
, pim
->spt
.plist
);
5153 pim_upstream_add_lhr_star_pimreg(pim
);
5155 case PIM_SPT_INFINITY
:
5156 pim_upstream_remove_lhr_star_pimreg(pim
, plist
);
5159 XFREE(MTYPE_PIM_SPT_PLIST_NAME
, pim
->spt
.plist
);
5163 XSTRDUP(MTYPE_PIM_SPT_PLIST_NAME
, plist
);
5170 DEFUN (ip_pim_spt_switchover_infinity
,
5171 ip_pim_spt_switchover_infinity_cmd
,
5172 "ip pim spt-switchover infinity-and-beyond",
5176 "Never switch to SPT Tree\n")
5178 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5179 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, NULL
);
5182 DEFUN (ip_pim_spt_switchover_infinity_plist
,
5183 ip_pim_spt_switchover_infinity_plist_cmd
,
5184 "ip pim spt-switchover infinity-and-beyond prefix-list WORD",
5188 "Never switch to SPT Tree\n"
5189 "Prefix-List to control which groups to switch\n"
5190 "Prefix-List name\n")
5192 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5193 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, argv
[5]->arg
);
5196 DEFUN (no_ip_pim_spt_switchover_infinity
,
5197 no_ip_pim_spt_switchover_infinity_cmd
,
5198 "no ip pim spt-switchover infinity-and-beyond",
5203 "Never switch to SPT Tree\n")
5205 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5206 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
5209 DEFUN (no_ip_pim_spt_switchover_infinity_plist
,
5210 no_ip_pim_spt_switchover_infinity_plist_cmd
,
5211 "no ip pim spt-switchover infinity-and-beyond prefix-list WORD",
5216 "Never switch to SPT Tree\n"
5217 "Prefix-List to control which groups to switch\n"
5218 "Prefix-List name\n")
5220 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5221 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
5224 DEFUN (ip_pim_joinprune_time
,
5225 ip_pim_joinprune_time_cmd
,
5226 "ip pim join-prune-interval (60-600)",
5228 "pim multicast routing\n"
5229 "Join Prune Send Interval\n"
5232 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5233 qpim_t_periodic
= atoi(argv
[3]->arg
);
5237 DEFUN (no_ip_pim_joinprune_time
,
5238 no_ip_pim_joinprune_time_cmd
,
5239 "no ip pim join-prune-interval (60-600)",
5242 "pim multicast routing\n"
5243 "Join Prune Send Interval\n"
5246 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5247 qpim_t_periodic
= PIM_DEFAULT_T_PERIODIC
;
5251 DEFUN (ip_pim_register_suppress
,
5252 ip_pim_register_suppress_cmd
,
5253 "ip pim register-suppress-time (5-60000)",
5255 "pim multicast routing\n"
5256 "Register Suppress Timer\n"
5259 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5260 qpim_register_suppress_time
= atoi(argv
[3]->arg
);
5264 DEFUN (no_ip_pim_register_suppress
,
5265 no_ip_pim_register_suppress_cmd
,
5266 "no ip pim register-suppress-time (5-60000)",
5269 "pim multicast routing\n"
5270 "Register Suppress Timer\n"
5273 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5274 qpim_register_suppress_time
= PIM_REGISTER_SUPPRESSION_TIME_DEFAULT
;
5278 DEFUN (ip_pim_rp_keep_alive
,
5279 ip_pim_rp_keep_alive_cmd
,
5280 "ip pim rp keep-alive-timer (31-60000)",
5282 "pim multicast routing\n"
5284 "Keep alive Timer\n"
5287 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5288 pim
->rp_keep_alive_time
= atoi(argv
[4]->arg
);
5292 DEFUN (no_ip_pim_rp_keep_alive
,
5293 no_ip_pim_rp_keep_alive_cmd
,
5294 "no 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
= PIM_KEEPALIVE_PERIOD
;
5307 DEFUN (ip_pim_keep_alive
,
5308 ip_pim_keep_alive_cmd
,
5309 "ip pim keep-alive-timer (31-60000)",
5311 "pim multicast routing\n"
5312 "Keep alive Timer\n"
5315 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5316 pim
->keep_alive_time
= atoi(argv
[3]->arg
);
5320 DEFUN (no_ip_pim_keep_alive
,
5321 no_ip_pim_keep_alive_cmd
,
5322 "no ip pim keep-alive-timer (31-60000)",
5325 "pim multicast routing\n"
5326 "Keep alive Timer\n"
5329 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5330 pim
->keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
5334 DEFUN (ip_pim_packets
,
5336 "ip pim packets (1-100)",
5338 "pim multicast routing\n"
5339 "packets to process at one time per fd\n"
5340 "Number of packets\n")
5342 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5343 qpim_packet_process
= atoi(argv
[3]->arg
);
5347 DEFUN (no_ip_pim_packets
,
5348 no_ip_pim_packets_cmd
,
5349 "no ip pim packets (1-100)",
5352 "pim multicast routing\n"
5353 "packets to process at one time per fd\n"
5354 "Number of packets\n")
5356 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5357 qpim_packet_process
= PIM_DEFAULT_PACKET_PROCESS
;
5361 DEFUN (ip_pim_v6_secondary
,
5362 ip_pim_v6_secondary_cmd
,
5363 "ip pim send-v6-secondary",
5365 "pim multicast routing\n"
5366 "Send v6 secondary addresses\n")
5368 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5369 pim
->send_v6_secondary
= 1;
5374 DEFUN (no_ip_pim_v6_secondary
,
5375 no_ip_pim_v6_secondary_cmd
,
5376 "no ip pim send-v6-secondary",
5379 "pim multicast routing\n"
5380 "Send v6 secondary addresses\n")
5382 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5383 pim
->send_v6_secondary
= 0;
5390 "ip pim rp A.B.C.D [A.B.C.D/M]",
5392 "pim multicast routing\n"
5394 "ip address of RP\n"
5395 "Group Address range to cover\n")
5397 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5400 if (argc
== (idx_ipv4
+ 1))
5401 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
5404 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
5405 argv
[idx_ipv4
+ 1]->arg
, NULL
);
5408 DEFUN (ip_pim_rp_prefix_list
,
5409 ip_pim_rp_prefix_list_cmd
,
5410 "ip pim rp A.B.C.D prefix-list WORD",
5412 "pim multicast routing\n"
5414 "ip address of RP\n"
5415 "group prefix-list filter\n"
5416 "Name of a prefix-list\n")
5418 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5419 return pim_rp_cmd_worker(pim
, vty
, argv
[3]->arg
, NULL
, argv
[5]->arg
);
5422 static int pim_no_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
5423 const char *rp
, const char *group
,
5426 int result
= pim_rp_del(pim
, rp
, group
, plist
);
5428 if (result
== PIM_GROUP_BAD_ADDRESS
) {
5429 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
5430 return CMD_WARNING_CONFIG_FAILED
;
5433 if (result
== PIM_RP_BAD_ADDRESS
) {
5434 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
5435 return CMD_WARNING_CONFIG_FAILED
;
5438 if (result
== PIM_RP_NOT_FOUND
) {
5439 vty_out(vty
, "%% Unable to find specified RP\n");
5440 return CMD_WARNING_CONFIG_FAILED
;
5446 DEFUN (no_ip_pim_rp
,
5448 "no ip pim rp A.B.C.D [A.B.C.D/M]",
5451 "pim multicast routing\n"
5453 "ip address of RP\n"
5454 "Group Address range to cover\n")
5456 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5457 int idx_ipv4
= 4, idx_group
= 0;
5459 if (argv_find(argv
, argc
, "A.B.C.D/M", &idx_group
))
5460 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
5461 argv
[idx_group
]->arg
, NULL
);
5463 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
5467 DEFUN (no_ip_pim_rp_prefix_list
,
5468 no_ip_pim_rp_prefix_list_cmd
,
5469 "no ip pim rp A.B.C.D prefix-list WORD",
5472 "pim multicast routing\n"
5474 "ip address of RP\n"
5475 "group prefix-list filter\n"
5476 "Name of a prefix-list\n")
5478 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5479 return pim_no_rp_cmd_worker(pim
, vty
, argv
[4]->arg
, NULL
, argv
[6]->arg
);
5482 static int pim_ssm_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
5485 int result
= pim_ssm_range_set(pim
, pim
->vrf_id
, plist
);
5487 if (result
== PIM_SSM_ERR_NONE
)
5491 case PIM_SSM_ERR_NO_VRF
:
5492 vty_out(vty
, "%% VRF doesn't exist\n");
5494 case PIM_SSM_ERR_DUP
:
5495 vty_out(vty
, "%% duplicate config\n");
5498 vty_out(vty
, "%% ssm range config failed\n");
5501 return CMD_WARNING_CONFIG_FAILED
;
5504 DEFUN (ip_pim_ssm_prefix_list
,
5505 ip_pim_ssm_prefix_list_cmd
,
5506 "ip pim ssm prefix-list WORD",
5508 "pim multicast routing\n"
5509 "Source Specific Multicast\n"
5510 "group range prefix-list filter\n"
5511 "Name of a prefix-list\n")
5513 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5514 return pim_ssm_cmd_worker(pim
, vty
, argv
[4]->arg
);
5517 DEFUN (no_ip_pim_ssm_prefix_list
,
5518 no_ip_pim_ssm_prefix_list_cmd
,
5519 "no ip pim ssm prefix-list",
5522 "pim multicast routing\n"
5523 "Source Specific Multicast\n"
5524 "group range prefix-list filter\n")
5526 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5527 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
5530 DEFUN (no_ip_pim_ssm_prefix_list_name
,
5531 no_ip_pim_ssm_prefix_list_name_cmd
,
5532 "no ip pim ssm prefix-list WORD",
5535 "pim multicast routing\n"
5536 "Source Specific Multicast\n"
5537 "group range prefix-list filter\n"
5538 "Name of a prefix-list\n")
5540 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5541 struct pim_ssm
*ssm
= pim
->ssm_info
;
5543 if (ssm
->plist_name
&& !strcmp(ssm
->plist_name
, argv
[5]->arg
))
5544 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
5546 vty_out(vty
, "%% pim ssm prefix-list %s doesn't exist\n", argv
[5]->arg
);
5548 return CMD_WARNING_CONFIG_FAILED
;
5551 static void ip_pim_ssm_show_group_range(struct pim_instance
*pim
,
5552 struct vty
*vty
, uint8_t uj
)
5554 struct pim_ssm
*ssm
= pim
->ssm_info
;
5555 const char *range_str
=
5556 ssm
->plist_name
? ssm
->plist_name
: PIM_SSM_STANDARD_RANGE
;
5560 json
= json_object_new_object();
5561 json_object_string_add(json
, "ssmGroups", range_str
);
5562 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5563 json
, JSON_C_TO_STRING_PRETTY
));
5564 json_object_free(json
);
5566 vty_out(vty
, "SSM group range : %s\n", range_str
);
5569 DEFUN (show_ip_pim_ssm_range
,
5570 show_ip_pim_ssm_range_cmd
,
5571 "show ip pim [vrf NAME] group-type [json]",
5580 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5581 uint8_t uj
= use_json(argc
, argv
);
5586 ip_pim_ssm_show_group_range(vrf
->info
, vty
, uj
);
5591 static void ip_pim_ssm_show_group_type(struct pim_instance
*pim
,
5592 struct vty
*vty
, uint8_t uj
,
5595 struct in_addr group_addr
;
5596 const char *type_str
;
5599 result
= inet_pton(AF_INET
, group
, &group_addr
);
5601 type_str
= "invalid";
5603 if (pim_is_group_224_4(group_addr
))
5605 pim_is_grp_ssm(pim
, group_addr
) ? "SSM" : "ASM";
5607 type_str
= "not-multicast";
5612 json
= json_object_new_object();
5613 json_object_string_add(json
, "groupType", type_str
);
5614 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5615 json
, JSON_C_TO_STRING_PRETTY
));
5616 json_object_free(json
);
5618 vty_out(vty
, "Group type : %s\n", type_str
);
5621 DEFUN (show_ip_pim_group_type
,
5622 show_ip_pim_group_type_cmd
,
5623 "show ip pim [vrf NAME] group-type A.B.C.D [json]",
5628 "multicast group type\n"
5633 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5634 uint8_t uj
= use_json(argc
, argv
);
5639 argv_find(argv
, argc
, "A.B.C.D", &idx
);
5640 ip_pim_ssm_show_group_type(vrf
->info
, vty
, uj
, argv
[idx
]->arg
);
5645 DEFUN_HIDDEN (ip_multicast_routing
,
5646 ip_multicast_routing_cmd
,
5647 "ip multicast-routing",
5649 "Enable IP multicast forwarding\n")
5654 DEFUN_HIDDEN (no_ip_multicast_routing
,
5655 no_ip_multicast_routing_cmd
,
5656 "no ip multicast-routing",
5659 "Enable IP multicast forwarding\n")
5662 "Command is Disabled and will be removed in a future version\n");
5668 "ip ssmpingd [A.B.C.D]",
5673 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5676 struct in_addr source_addr
;
5677 const char *source_str
= (argc
== 3) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
5679 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
5681 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
5682 source_str
, errno
, safe_strerror(errno
));
5683 return CMD_WARNING_CONFIG_FAILED
;
5686 result
= pim_ssmpingd_start(pim
, source_addr
);
5688 vty_out(vty
, "%% Failure starting ssmpingd for source %s: %d\n",
5689 source_str
, result
);
5690 return CMD_WARNING_CONFIG_FAILED
;
5696 DEFUN (no_ip_ssmpingd
,
5698 "no ip ssmpingd [A.B.C.D]",
5704 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5707 struct in_addr source_addr
;
5708 const char *source_str
= (argc
== 4) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
5710 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
5712 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
5713 source_str
, errno
, safe_strerror(errno
));
5714 return CMD_WARNING_CONFIG_FAILED
;
5717 result
= pim_ssmpingd_stop(pim
, source_addr
);
5719 vty_out(vty
, "%% Failure stopping ssmpingd for source %s: %d\n",
5720 source_str
, result
);
5721 return CMD_WARNING_CONFIG_FAILED
;
5731 "pim multicast routing\n"
5732 "Enable PIM ECMP \n")
5734 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5735 pim
->ecmp_enable
= true;
5740 DEFUN (no_ip_pim_ecmp
,
5745 "pim multicast routing\n"
5746 "Disable PIM ECMP \n")
5748 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5749 pim
->ecmp_enable
= false;
5754 DEFUN (ip_pim_ecmp_rebalance
,
5755 ip_pim_ecmp_rebalance_cmd
,
5756 "ip pim ecmp rebalance",
5758 "pim multicast routing\n"
5759 "Enable PIM ECMP \n"
5760 "Enable PIM ECMP Rebalance\n")
5762 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5763 pim
->ecmp_enable
= true;
5764 pim
->ecmp_rebalance_enable
= true;
5769 DEFUN (no_ip_pim_ecmp_rebalance
,
5770 no_ip_pim_ecmp_rebalance_cmd
,
5771 "no ip pim ecmp rebalance",
5774 "pim multicast routing\n"
5775 "Disable PIM ECMP \n"
5776 "Disable PIM ECMP Rebalance\n")
5778 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5779 pim
->ecmp_rebalance_enable
= false;
5784 static int pim_cmd_igmp_start(struct vty
*vty
, struct interface
*ifp
)
5786 struct pim_interface
*pim_ifp
;
5787 uint8_t need_startup
= 0;
5789 pim_ifp
= ifp
->info
;
5792 pim_ifp
= pim_if_new(ifp
, 1 /* igmp=true */, 0 /* pim=false */);
5794 vty_out(vty
, "Could not enable IGMP on interface %s\n",
5796 return CMD_WARNING_CONFIG_FAILED
;
5800 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
5801 PIM_IF_DO_IGMP(pim_ifp
->options
);
5806 /* 'ip igmp' executed multiple times, with need_startup
5807 avoid multiple if add all and membership refresh */
5809 pim_if_addr_add_all(ifp
);
5810 pim_if_membership_refresh(ifp
);
5816 DEFUN (interface_ip_igmp
,
5817 interface_ip_igmp_cmd
,
5822 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5824 return pim_cmd_igmp_start(vty
, ifp
);
5827 DEFUN (interface_no_ip_igmp
,
5828 interface_no_ip_igmp_cmd
,
5834 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5835 struct pim_interface
*pim_ifp
= ifp
->info
;
5840 PIM_IF_DONT_IGMP(pim_ifp
->options
);
5842 pim_if_membership_clear(ifp
);
5844 pim_if_addr_del_all_igmp(ifp
);
5846 if (!PIM_IF_TEST_PIM(pim_ifp
->options
)) {
5853 DEFUN (interface_ip_igmp_join
,
5854 interface_ip_igmp_join_cmd
,
5855 "ip igmp join A.B.C.D A.B.C.D",
5858 "IGMP join multicast group\n"
5859 "Multicast group address\n"
5862 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5865 const char *group_str
;
5866 const char *source_str
;
5867 struct in_addr group_addr
;
5868 struct in_addr source_addr
;
5872 group_str
= argv
[idx_ipv4
]->arg
;
5873 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
5875 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
5876 errno
, safe_strerror(errno
));
5877 return CMD_WARNING_CONFIG_FAILED
;
5880 /* Source address */
5881 source_str
= argv
[idx_ipv4_2
]->arg
;
5882 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
5884 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
5885 source_str
, errno
, safe_strerror(errno
));
5886 return CMD_WARNING_CONFIG_FAILED
;
5889 CMD_FERR_RETURN(pim_if_igmp_join_add(ifp
, group_addr
, source_addr
),
5890 "Failure joining IGMP group: $ERR");
5895 DEFUN (interface_no_ip_igmp_join
,
5896 interface_no_ip_igmp_join_cmd
,
5897 "no ip igmp join A.B.C.D A.B.C.D",
5901 "IGMP join multicast group\n"
5902 "Multicast group address\n"
5905 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5908 const char *group_str
;
5909 const char *source_str
;
5910 struct in_addr group_addr
;
5911 struct in_addr source_addr
;
5915 group_str
= argv
[idx_ipv4
]->arg
;
5916 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
5918 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
5919 errno
, safe_strerror(errno
));
5920 return CMD_WARNING_CONFIG_FAILED
;
5923 /* Source address */
5924 source_str
= argv
[idx_ipv4_2
]->arg
;
5925 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
5927 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
5928 source_str
, errno
, safe_strerror(errno
));
5929 return CMD_WARNING_CONFIG_FAILED
;
5932 result
= pim_if_igmp_join_del(ifp
, group_addr
, source_addr
);
5935 "%% Failure leaving IGMP group %s source %s on interface %s: %d\n",
5936 group_str
, source_str
, ifp
->name
, result
);
5937 return CMD_WARNING_CONFIG_FAILED
;
5944 CLI reconfiguration affects the interface level (struct pim_interface).
5945 This function propagates the reconfiguration to every active socket
5948 static void igmp_sock_query_interval_reconfig(struct igmp_sock
*igmp
)
5950 struct interface
*ifp
;
5951 struct pim_interface
*pim_ifp
;
5955 /* other querier present? */
5957 if (igmp
->t_other_querier_timer
)
5960 /* this is the querier */
5962 zassert(igmp
->interface
);
5963 zassert(igmp
->interface
->info
);
5965 ifp
= igmp
->interface
;
5966 pim_ifp
= ifp
->info
;
5968 if (PIM_DEBUG_IGMP_TRACE
) {
5969 char ifaddr_str
[INET_ADDRSTRLEN
];
5970 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
5971 sizeof(ifaddr_str
));
5972 zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
5973 __PRETTY_FUNCTION__
, ifaddr_str
, ifp
->name
,
5974 pim_ifp
->igmp_default_query_interval
);
5978 igmp_startup_mode_on() will reset QQI:
5980 igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
5982 igmp_startup_mode_on(igmp
);
5985 static void igmp_sock_query_reschedule(struct igmp_sock
*igmp
)
5987 if (igmp
->t_igmp_query_timer
) {
5988 /* other querier present */
5989 zassert(igmp
->t_igmp_query_timer
);
5990 zassert(!igmp
->t_other_querier_timer
);
5992 pim_igmp_general_query_off(igmp
);
5993 pim_igmp_general_query_on(igmp
);
5995 zassert(igmp
->t_igmp_query_timer
);
5996 zassert(!igmp
->t_other_querier_timer
);
5998 /* this is the querier */
6000 zassert(!igmp
->t_igmp_query_timer
);
6001 zassert(igmp
->t_other_querier_timer
);
6003 pim_igmp_other_querier_timer_off(igmp
);
6004 pim_igmp_other_querier_timer_on(igmp
);
6006 zassert(!igmp
->t_igmp_query_timer
);
6007 zassert(igmp
->t_other_querier_timer
);
6011 static void change_query_interval(struct pim_interface
*pim_ifp
,
6014 struct listnode
*sock_node
;
6015 struct igmp_sock
*igmp
;
6017 pim_ifp
->igmp_default_query_interval
= query_interval
;
6019 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
6020 igmp_sock_query_interval_reconfig(igmp
);
6021 igmp_sock_query_reschedule(igmp
);
6025 static void change_query_max_response_time(struct pim_interface
*pim_ifp
,
6026 int query_max_response_time_dsec
)
6028 struct listnode
*sock_node
;
6029 struct igmp_sock
*igmp
;
6031 pim_ifp
->igmp_query_max_response_time_dsec
=
6032 query_max_response_time_dsec
;
6035 Below we modify socket/group/source timers in order to quickly
6036 reflect the change. Otherwise, those timers would eventually catch
6040 /* scan all sockets */
6041 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
6042 struct listnode
*grp_node
;
6043 struct igmp_group
*grp
;
6045 /* reschedule socket general query */
6046 igmp_sock_query_reschedule(igmp
);
6048 /* scan socket groups */
6049 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grp_node
,
6051 struct listnode
*src_node
;
6052 struct igmp_source
*src
;
6054 /* reset group timers for groups in EXCLUDE mode */
6055 if (grp
->group_filtermode_isexcl
) {
6056 igmp_group_reset_gmi(grp
);
6059 /* scan group sources */
6060 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
,
6063 /* reset source timers for sources with running
6065 if (src
->t_source_timer
) {
6066 igmp_source_reset_gmi(igmp
, grp
, src
);
6073 #define IGMP_QUERY_INTERVAL_MIN (1)
6074 #define IGMP_QUERY_INTERVAL_MAX (1800)
6076 DEFUN (interface_ip_igmp_query_interval
,
6077 interface_ip_igmp_query_interval_cmd
,
6078 "ip igmp query-interval (1-1800)",
6081 IFACE_IGMP_QUERY_INTERVAL_STR
6082 "Query interval in seconds\n")
6084 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6085 struct pim_interface
*pim_ifp
= ifp
->info
;
6087 int query_interval_dsec
;
6091 ret
= pim_cmd_igmp_start(vty
, ifp
);
6092 if (ret
!= CMD_SUCCESS
)
6094 pim_ifp
= ifp
->info
;
6097 query_interval
= atoi(argv
[3]->arg
);
6098 query_interval_dsec
= 10 * query_interval
;
6101 It seems we don't need to check bounds since command.c does it
6102 already, but we verify them anyway for extra safety.
6104 if (query_interval
< IGMP_QUERY_INTERVAL_MIN
) {
6106 "General query interval %d lower than minimum %d\n",
6107 query_interval
, IGMP_QUERY_INTERVAL_MIN
);
6108 return CMD_WARNING_CONFIG_FAILED
;
6110 if (query_interval
> IGMP_QUERY_INTERVAL_MAX
) {
6112 "General query interval %d higher than maximum %d\n",
6113 query_interval
, IGMP_QUERY_INTERVAL_MAX
);
6114 return CMD_WARNING_CONFIG_FAILED
;
6117 if (query_interval_dsec
<= pim_ifp
->igmp_query_max_response_time_dsec
) {
6119 "Can't set general query interval %d dsec <= query max response time %d dsec.\n",
6120 query_interval_dsec
,
6121 pim_ifp
->igmp_query_max_response_time_dsec
);
6122 return CMD_WARNING_CONFIG_FAILED
;
6125 change_query_interval(pim_ifp
, query_interval
);
6130 DEFUN (interface_no_ip_igmp_query_interval
,
6131 interface_no_ip_igmp_query_interval_cmd
,
6132 "no ip igmp query-interval",
6136 IFACE_IGMP_QUERY_INTERVAL_STR
)
6138 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6139 struct pim_interface
*pim_ifp
= ifp
->info
;
6140 int default_query_interval_dsec
;
6145 default_query_interval_dsec
= IGMP_GENERAL_QUERY_INTERVAL
* 10;
6147 if (default_query_interval_dsec
6148 <= pim_ifp
->igmp_query_max_response_time_dsec
) {
6150 "Can't set default general query interval %d dsec <= query max response time %d dsec.\n",
6151 default_query_interval_dsec
,
6152 pim_ifp
->igmp_query_max_response_time_dsec
);
6153 return CMD_WARNING_CONFIG_FAILED
;
6156 change_query_interval(pim_ifp
, IGMP_GENERAL_QUERY_INTERVAL
);
6161 DEFUN (interface_ip_igmp_version
,
6162 interface_ip_igmp_version_cmd
,
6163 "ip igmp version (2-3)",
6167 "IGMP version number\n")
6169 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6170 struct pim_interface
*pim_ifp
= ifp
->info
;
6171 int igmp_version
, old_version
= 0;
6175 ret
= pim_cmd_igmp_start(vty
, ifp
);
6176 if (ret
!= CMD_SUCCESS
)
6178 pim_ifp
= ifp
->info
;
6181 igmp_version
= atoi(argv
[3]->arg
);
6182 old_version
= pim_ifp
->igmp_version
;
6183 pim_ifp
->igmp_version
= igmp_version
;
6185 // Check if IGMP is Enabled otherwise, enable on interface
6186 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
6187 PIM_IF_DO_IGMP(pim_ifp
->options
);
6188 pim_if_addr_add_all(ifp
);
6189 pim_if_membership_refresh(ifp
);
6190 old_version
= igmp_version
;
6191 // avoid refreshing membership again.
6193 /* Current and new version is different refresh existing
6194 membership. Going from 3 -> 2 or 2 -> 3. */
6195 if (old_version
!= igmp_version
)
6196 pim_if_membership_refresh(ifp
);
6201 DEFUN (interface_no_ip_igmp_version
,
6202 interface_no_ip_igmp_version_cmd
,
6203 "no ip igmp version (2-3)",
6208 "IGMP version number\n")
6210 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6211 struct pim_interface
*pim_ifp
= ifp
->info
;
6216 pim_ifp
->igmp_version
= IGMP_DEFAULT_VERSION
;
6221 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
6222 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
6224 DEFUN (interface_ip_igmp_query_max_response_time
,
6225 interface_ip_igmp_query_max_response_time_cmd
,
6226 "ip igmp query-max-response-time (10-250)",
6229 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
6230 "Query response value in deci-seconds\n")
6232 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6233 struct pim_interface
*pim_ifp
= ifp
->info
;
6234 int query_max_response_time
;
6238 ret
= pim_cmd_igmp_start(vty
, ifp
);
6239 if (ret
!= CMD_SUCCESS
)
6241 pim_ifp
= ifp
->info
;
6244 query_max_response_time
= atoi(argv
[3]->arg
);
6246 if (query_max_response_time
6247 >= pim_ifp
->igmp_default_query_interval
* 10) {
6249 "Can't set query max response time %d sec >= general query interval %d sec\n",
6250 query_max_response_time
,
6251 pim_ifp
->igmp_default_query_interval
);
6252 return CMD_WARNING_CONFIG_FAILED
;
6255 change_query_max_response_time(pim_ifp
, query_max_response_time
);
6260 DEFUN (interface_no_ip_igmp_query_max_response_time
,
6261 interface_no_ip_igmp_query_max_response_time_cmd
,
6262 "no ip igmp query-max-response-time (10-250)",
6266 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
6267 "Time for response in deci-seconds\n")
6269 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6270 struct pim_interface
*pim_ifp
= ifp
->info
;
6275 change_query_max_response_time(pim_ifp
,
6276 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
6281 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
6282 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
6284 DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec
,
6285 interface_ip_igmp_query_max_response_time_dsec_cmd
,
6286 "ip igmp query-max-response-time-dsec (10-250)",
6289 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
6290 "Query response value in deciseconds\n")
6292 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6293 struct pim_interface
*pim_ifp
= ifp
->info
;
6294 int query_max_response_time_dsec
;
6295 int default_query_interval_dsec
;
6299 ret
= pim_cmd_igmp_start(vty
, ifp
);
6300 if (ret
!= CMD_SUCCESS
)
6302 pim_ifp
= ifp
->info
;
6305 query_max_response_time_dsec
= atoi(argv
[4]->arg
);
6307 default_query_interval_dsec
= 10 * pim_ifp
->igmp_default_query_interval
;
6309 if (query_max_response_time_dsec
>= default_query_interval_dsec
) {
6311 "Can't set query max response time %d dsec >= general query interval %d dsec\n",
6312 query_max_response_time_dsec
,
6313 default_query_interval_dsec
);
6314 return CMD_WARNING_CONFIG_FAILED
;
6317 change_query_max_response_time(pim_ifp
, query_max_response_time_dsec
);
6322 DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec
,
6323 interface_no_ip_igmp_query_max_response_time_dsec_cmd
,
6324 "no ip igmp query-max-response-time-dsec",
6328 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
)
6330 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6331 struct pim_interface
*pim_ifp
= ifp
->info
;
6336 change_query_max_response_time(pim_ifp
,
6337 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
6342 DEFUN (interface_ip_pim_drprio
,
6343 interface_ip_pim_drprio_cmd
,
6344 "ip pim drpriority (1-4294967295)",
6347 "Set the Designated Router Election Priority\n"
6348 "Value of the new DR Priority\n")
6350 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6352 struct pim_interface
*pim_ifp
= ifp
->info
;
6353 uint32_t old_dr_prio
;
6356 vty_out(vty
, "Please enable PIM on interface, first\n");
6357 return CMD_WARNING_CONFIG_FAILED
;
6360 old_dr_prio
= pim_ifp
->pim_dr_priority
;
6362 pim_ifp
->pim_dr_priority
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
6364 if (old_dr_prio
!= pim_ifp
->pim_dr_priority
) {
6365 if (pim_if_dr_election(ifp
))
6366 pim_hello_restart_now(ifp
);
6372 DEFUN (interface_no_ip_pim_drprio
,
6373 interface_no_ip_pim_drprio_cmd
,
6374 "no ip pim drpriority [(1-4294967295)]",
6378 "Revert the Designated Router Priority to default\n"
6379 "Old Value of the Priority\n")
6381 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6382 struct pim_interface
*pim_ifp
= ifp
->info
;
6385 vty_out(vty
, "Pim not enabled on this interface\n");
6386 return CMD_WARNING_CONFIG_FAILED
;
6389 if (pim_ifp
->pim_dr_priority
!= PIM_DEFAULT_DR_PRIORITY
) {
6390 pim_ifp
->pim_dr_priority
= PIM_DEFAULT_DR_PRIORITY
;
6391 if (pim_if_dr_election(ifp
))
6392 pim_hello_restart_now(ifp
);
6398 static int pim_cmd_interface_add(struct interface
*ifp
)
6400 struct pim_interface
*pim_ifp
= ifp
->info
;
6403 pim_ifp
= pim_if_new(ifp
, 0 /* igmp=false */, 1 /* pim=true */);
6408 PIM_IF_DO_PIM(pim_ifp
->options
);
6411 pim_if_addr_add_all(ifp
);
6412 pim_if_membership_refresh(ifp
);
6416 DEFUN_HIDDEN (interface_ip_pim_ssm
,
6417 interface_ip_pim_ssm_cmd
,
6423 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6425 if (!pim_cmd_interface_add(ifp
)) {
6426 vty_out(vty
, "Could not enable PIM SM on interface\n");
6427 return CMD_WARNING_CONFIG_FAILED
;
6431 "WARN: Enabled PIM SM on interface; configure PIM SSM "
6432 "range if needed\n");
6436 DEFUN (interface_ip_pim_sm
,
6437 interface_ip_pim_sm_cmd
,
6443 struct pim_interface
*pim_ifp
;
6445 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6446 if (!pim_cmd_interface_add(ifp
)) {
6447 vty_out(vty
, "Could not enable PIM SM on interface\n");
6448 return CMD_WARNING_CONFIG_FAILED
;
6451 pim_ifp
= ifp
->info
;
6453 pim_if_create_pimreg(pim_ifp
->pim
);
6458 static int pim_cmd_interface_delete(struct interface
*ifp
)
6460 struct pim_interface
*pim_ifp
= ifp
->info
;
6465 PIM_IF_DONT_PIM(pim_ifp
->options
);
6467 pim_if_membership_clear(ifp
);
6470 pim_sock_delete() removes all neighbors from
6471 pim_ifp->pim_neighbor_list.
6473 pim_sock_delete(ifp
, "pim unconfigured on interface");
6475 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
6476 pim_if_addr_del_all(ifp
);
6483 DEFUN_HIDDEN (interface_no_ip_pim_ssm
,
6484 interface_no_ip_pim_ssm_cmd
,
6491 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6492 if (!pim_cmd_interface_delete(ifp
)) {
6493 vty_out(vty
, "Unable to delete interface information\n");
6494 return CMD_WARNING_CONFIG_FAILED
;
6500 DEFUN (interface_no_ip_pim_sm
,
6501 interface_no_ip_pim_sm_cmd
,
6508 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6509 if (!pim_cmd_interface_delete(ifp
)) {
6510 vty_out(vty
, "Unable to delete interface information\n");
6511 return CMD_WARNING_CONFIG_FAILED
;
6518 DEFUN(interface_ip_pim_boundary_oil
,
6519 interface_ip_pim_boundary_oil_cmd
,
6520 "ip multicast boundary oil WORD",
6522 "Generic multicast configuration options\n"
6523 "Define multicast boundary\n"
6524 "Filter OIL by group using prefix list\n"
6525 "Prefix list to filter OIL with\n")
6527 VTY_DECLVAR_CONTEXT(interface
, iif
);
6528 struct pim_interface
*pim_ifp
;
6531 argv_find(argv
, argc
, "WORD", &idx
);
6533 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6535 if (pim_ifp
->boundary_oil_plist
)
6536 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
6538 pim_ifp
->boundary_oil_plist
=
6539 XSTRDUP(MTYPE_PIM_INTERFACE
, argv
[idx
]->arg
);
6541 /* Interface will be pruned from OIL on next Join */
6545 DEFUN(interface_no_ip_pim_boundary_oil
,
6546 interface_no_ip_pim_boundary_oil_cmd
,
6547 "no ip multicast boundary oil [WORD]",
6550 "Generic multicast configuration options\n"
6551 "Define multicast boundary\n"
6552 "Filter OIL by group using prefix list\n"
6553 "Prefix list to filter OIL with\n")
6555 VTY_DECLVAR_CONTEXT(interface
, iif
);
6556 struct pim_interface
*pim_ifp
;
6559 argv_find(argv
, argc
, "WORD", &idx
);
6561 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6563 if (pim_ifp
->boundary_oil_plist
)
6564 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
6569 DEFUN (interface_ip_mroute
,
6570 interface_ip_mroute_cmd
,
6571 "ip mroute INTERFACE A.B.C.D",
6573 "Add multicast route\n"
6574 "Outgoing interface name\n"
6577 VTY_DECLVAR_CONTEXT(interface
, iif
);
6578 struct pim_interface
*pim_ifp
;
6579 struct pim_instance
*pim
;
6580 int idx_interface
= 2;
6582 struct interface
*oif
;
6583 const char *oifname
;
6584 const char *grp_str
;
6585 struct in_addr grp_addr
;
6586 struct in_addr src_addr
;
6589 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6592 oifname
= argv
[idx_interface
]->arg
;
6593 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6595 vty_out(vty
, "No such interface name %s\n", oifname
);
6599 grp_str
= argv
[idx_ipv4
]->arg
;
6600 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6602 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6603 errno
, safe_strerror(errno
));
6607 src_addr
.s_addr
= INADDR_ANY
;
6609 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6610 vty_out(vty
, "Failed to add route\n");
6617 DEFUN (interface_ip_mroute_source
,
6618 interface_ip_mroute_source_cmd
,
6619 "ip mroute INTERFACE A.B.C.D A.B.C.D",
6621 "Add multicast route\n"
6622 "Outgoing interface name\n"
6626 VTY_DECLVAR_CONTEXT(interface
, iif
);
6627 struct pim_interface
*pim_ifp
;
6628 struct pim_instance
*pim
;
6629 int idx_interface
= 2;
6632 struct interface
*oif
;
6633 const char *oifname
;
6634 const char *grp_str
;
6635 struct in_addr grp_addr
;
6636 const char *src_str
;
6637 struct in_addr src_addr
;
6640 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6643 oifname
= argv
[idx_interface
]->arg
;
6644 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6646 vty_out(vty
, "No such interface name %s\n", oifname
);
6650 grp_str
= argv
[idx_ipv4
]->arg
;
6651 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6653 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6654 errno
, safe_strerror(errno
));
6658 src_str
= argv
[idx_ipv4_2
]->arg
;
6659 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
6661 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
6662 errno
, safe_strerror(errno
));
6666 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6667 vty_out(vty
, "Failed to add route\n");
6674 DEFUN (interface_no_ip_mroute
,
6675 interface_no_ip_mroute_cmd
,
6676 "no ip mroute INTERFACE A.B.C.D",
6679 "Add multicast route\n"
6680 "Outgoing interface name\n"
6683 VTY_DECLVAR_CONTEXT(interface
, iif
);
6684 struct pim_interface
*pim_ifp
;
6685 struct pim_instance
*pim
;
6686 int idx_interface
= 3;
6688 struct interface
*oif
;
6689 const char *oifname
;
6690 const char *grp_str
;
6691 struct in_addr grp_addr
;
6692 struct in_addr src_addr
;
6695 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6698 oifname
= argv
[idx_interface
]->arg
;
6699 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6701 vty_out(vty
, "No such interface name %s\n", oifname
);
6705 grp_str
= argv
[idx_ipv4
]->arg
;
6706 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6708 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6709 errno
, safe_strerror(errno
));
6713 src_addr
.s_addr
= INADDR_ANY
;
6715 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6716 vty_out(vty
, "Failed to remove route\n");
6723 DEFUN (interface_no_ip_mroute_source
,
6724 interface_no_ip_mroute_source_cmd
,
6725 "no ip mroute INTERFACE A.B.C.D A.B.C.D",
6728 "Add multicast route\n"
6729 "Outgoing interface name\n"
6733 VTY_DECLVAR_CONTEXT(interface
, iif
);
6734 struct pim_interface
*pim_ifp
;
6735 struct pim_instance
*pim
;
6736 int idx_interface
= 3;
6739 struct interface
*oif
;
6740 const char *oifname
;
6741 const char *grp_str
;
6742 struct in_addr grp_addr
;
6743 const char *src_str
;
6744 struct in_addr src_addr
;
6747 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6750 oifname
= argv
[idx_interface
]->arg
;
6751 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6753 vty_out(vty
, "No such interface name %s\n", oifname
);
6757 grp_str
= argv
[idx_ipv4
]->arg
;
6758 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6760 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6761 errno
, safe_strerror(errno
));
6765 src_str
= argv
[idx_ipv4_2
]->arg
;
6766 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
6768 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
6769 errno
, safe_strerror(errno
));
6773 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6774 vty_out(vty
, "Failed to remove route\n");
6781 DEFUN (interface_ip_pim_hello
,
6782 interface_ip_pim_hello_cmd
,
6783 "ip pim hello (1-180) [(1-180)]",
6787 IFACE_PIM_HELLO_TIME_STR
6788 IFACE_PIM_HELLO_HOLD_STR
)
6790 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6793 struct pim_interface
*pim_ifp
= ifp
->info
;
6796 if (!pim_cmd_interface_add(ifp
)) {
6797 vty_out(vty
, "Could not enable PIM SM on interface\n");
6798 return CMD_WARNING_CONFIG_FAILED
;
6802 pim_ifp
= ifp
->info
;
6803 pim_ifp
->pim_hello_period
= strtol(argv
[idx_time
]->arg
, NULL
, 10);
6805 if (argc
== idx_hold
+ 1)
6806 pim_ifp
->pim_default_holdtime
=
6807 strtol(argv
[idx_hold
]->arg
, NULL
, 10);
6812 DEFUN (interface_no_ip_pim_hello
,
6813 interface_no_ip_pim_hello_cmd
,
6814 "no ip pim hello [(1-180) (1-180)]",
6819 IFACE_PIM_HELLO_TIME_STR
6820 IFACE_PIM_HELLO_HOLD_STR
)
6822 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6823 struct pim_interface
*pim_ifp
= ifp
->info
;
6826 vty_out(vty
, "Pim not enabled on this interface\n");
6827 return CMD_WARNING_CONFIG_FAILED
;
6830 pim_ifp
->pim_hello_period
= PIM_DEFAULT_HELLO_PERIOD
;
6831 pim_ifp
->pim_default_holdtime
= -1;
6842 PIM_DO_DEBUG_IGMP_EVENTS
;
6843 PIM_DO_DEBUG_IGMP_PACKETS
;
6844 PIM_DO_DEBUG_IGMP_TRACE
;
6848 DEFUN (no_debug_igmp
,
6855 PIM_DONT_DEBUG_IGMP_EVENTS
;
6856 PIM_DONT_DEBUG_IGMP_PACKETS
;
6857 PIM_DONT_DEBUG_IGMP_TRACE
;
6862 DEFUN (debug_igmp_events
,
6863 debug_igmp_events_cmd
,
6864 "debug igmp events",
6867 DEBUG_IGMP_EVENTS_STR
)
6869 PIM_DO_DEBUG_IGMP_EVENTS
;
6873 DEFUN (no_debug_igmp_events
,
6874 no_debug_igmp_events_cmd
,
6875 "no debug igmp events",
6879 DEBUG_IGMP_EVENTS_STR
)
6881 PIM_DONT_DEBUG_IGMP_EVENTS
;
6886 DEFUN (debug_igmp_packets
,
6887 debug_igmp_packets_cmd
,
6888 "debug igmp packets",
6891 DEBUG_IGMP_PACKETS_STR
)
6893 PIM_DO_DEBUG_IGMP_PACKETS
;
6897 DEFUN (no_debug_igmp_packets
,
6898 no_debug_igmp_packets_cmd
,
6899 "no debug igmp packets",
6903 DEBUG_IGMP_PACKETS_STR
)
6905 PIM_DONT_DEBUG_IGMP_PACKETS
;
6910 DEFUN (debug_igmp_trace
,
6911 debug_igmp_trace_cmd
,
6915 DEBUG_IGMP_TRACE_STR
)
6917 PIM_DO_DEBUG_IGMP_TRACE
;
6921 DEFUN (no_debug_igmp_trace
,
6922 no_debug_igmp_trace_cmd
,
6923 "no debug igmp trace",
6927 DEBUG_IGMP_TRACE_STR
)
6929 PIM_DONT_DEBUG_IGMP_TRACE
;
6934 DEFUN (debug_mroute
,
6940 PIM_DO_DEBUG_MROUTE
;
6944 DEFUN (debug_mroute_detail
,
6945 debug_mroute_detail_cmd
,
6946 "debug mroute detail",
6951 PIM_DO_DEBUG_MROUTE_DETAIL
;
6955 DEFUN (no_debug_mroute
,
6956 no_debug_mroute_cmd
,
6962 PIM_DONT_DEBUG_MROUTE
;
6966 DEFUN (no_debug_mroute_detail
,
6967 no_debug_mroute_detail_cmd
,
6968 "no debug mroute detail",
6974 PIM_DONT_DEBUG_MROUTE_DETAIL
;
6978 DEFUN (debug_static
,
6984 PIM_DO_DEBUG_STATIC
;
6988 DEFUN (no_debug_static
,
6989 no_debug_static_cmd
,
6995 PIM_DONT_DEBUG_STATIC
;
7006 PIM_DO_DEBUG_PIM_EVENTS
;
7007 PIM_DO_DEBUG_PIM_PACKETS
;
7008 PIM_DO_DEBUG_PIM_TRACE
;
7009 PIM_DO_DEBUG_MSDP_EVENTS
;
7010 PIM_DO_DEBUG_MSDP_PACKETS
;
7014 DEFUN (no_debug_pim
,
7021 PIM_DONT_DEBUG_PIM_EVENTS
;
7022 PIM_DONT_DEBUG_PIM_PACKETS
;
7023 PIM_DONT_DEBUG_PIM_TRACE
;
7024 PIM_DONT_DEBUG_MSDP_EVENTS
;
7025 PIM_DONT_DEBUG_MSDP_PACKETS
;
7027 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
7028 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
7033 DEFUN (debug_pim_nht
,
7038 "Nexthop Tracking\n")
7040 PIM_DO_DEBUG_PIM_NHT
;
7044 DEFUN (no_debug_pim_nht
,
7045 no_debug_pim_nht_cmd
,
7050 "Nexthop Tracking\n")
7052 PIM_DONT_DEBUG_PIM_NHT
;
7056 DEFUN (debug_pim_nht_rp
,
7057 debug_pim_nht_rp_cmd
,
7061 "Nexthop Tracking\n"
7062 "RP Nexthop Tracking\n")
7064 PIM_DO_DEBUG_PIM_NHT_RP
;
7068 DEFUN (no_debug_pim_nht_rp
,
7069 no_debug_pim_nht_rp_cmd
,
7070 "no debug pim nht rp",
7074 "Nexthop Tracking\n"
7075 "RP Nexthop Tracking\n")
7077 PIM_DONT_DEBUG_PIM_NHT_RP
;
7081 DEFUN (debug_pim_events
,
7082 debug_pim_events_cmd
,
7086 DEBUG_PIM_EVENTS_STR
)
7088 PIM_DO_DEBUG_PIM_EVENTS
;
7092 DEFUN (no_debug_pim_events
,
7093 no_debug_pim_events_cmd
,
7094 "no debug pim events",
7098 DEBUG_PIM_EVENTS_STR
)
7100 PIM_DONT_DEBUG_PIM_EVENTS
;
7104 DEFUN (debug_pim_packets
,
7105 debug_pim_packets_cmd
,
7106 "debug pim packets [<hello|joins|register>]",
7109 DEBUG_PIM_PACKETS_STR
7110 DEBUG_PIM_HELLO_PACKETS_STR
7111 DEBUG_PIM_J_P_PACKETS_STR
7112 DEBUG_PIM_PIM_REG_PACKETS_STR
)
7115 if (argv_find(argv
, argc
, "hello", &idx
)) {
7116 PIM_DO_DEBUG_PIM_HELLO
;
7117 vty_out(vty
, "PIM Hello debugging is on\n");
7118 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
7119 PIM_DO_DEBUG_PIM_J_P
;
7120 vty_out(vty
, "PIM Join/Prune debugging is on\n");
7121 } else if (argv_find(argv
, argc
, "register", &idx
)) {
7122 PIM_DO_DEBUG_PIM_REG
;
7123 vty_out(vty
, "PIM Register debugging is on\n");
7125 PIM_DO_DEBUG_PIM_PACKETS
;
7126 vty_out(vty
, "PIM Packet debugging is on \n");
7131 DEFUN (no_debug_pim_packets
,
7132 no_debug_pim_packets_cmd
,
7133 "no debug pim packets [<hello|joins|register>]",
7137 DEBUG_PIM_PACKETS_STR
7138 DEBUG_PIM_HELLO_PACKETS_STR
7139 DEBUG_PIM_J_P_PACKETS_STR
7140 DEBUG_PIM_PIM_REG_PACKETS_STR
)
7143 if (argv_find(argv
, argc
, "hello", &idx
)) {
7144 PIM_DONT_DEBUG_PIM_HELLO
;
7145 vty_out(vty
, "PIM Hello debugging is off \n");
7146 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
7147 PIM_DONT_DEBUG_PIM_J_P
;
7148 vty_out(vty
, "PIM Join/Prune debugging is off \n");
7149 } else if (argv_find(argv
, argc
, "register", &idx
)) {
7150 PIM_DONT_DEBUG_PIM_REG
;
7151 vty_out(vty
, "PIM Register debugging is off\n");
7153 PIM_DONT_DEBUG_PIM_PACKETS
;
7159 DEFUN (debug_pim_packetdump_send
,
7160 debug_pim_packetdump_send_cmd
,
7161 "debug pim packet-dump send",
7164 DEBUG_PIM_PACKETDUMP_STR
7165 DEBUG_PIM_PACKETDUMP_SEND_STR
)
7167 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND
;
7171 DEFUN (no_debug_pim_packetdump_send
,
7172 no_debug_pim_packetdump_send_cmd
,
7173 "no debug pim packet-dump send",
7177 DEBUG_PIM_PACKETDUMP_STR
7178 DEBUG_PIM_PACKETDUMP_SEND_STR
)
7180 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
7184 DEFUN (debug_pim_packetdump_recv
,
7185 debug_pim_packetdump_recv_cmd
,
7186 "debug pim packet-dump receive",
7189 DEBUG_PIM_PACKETDUMP_STR
7190 DEBUG_PIM_PACKETDUMP_RECV_STR
)
7192 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV
;
7196 DEFUN (no_debug_pim_packetdump_recv
,
7197 no_debug_pim_packetdump_recv_cmd
,
7198 "no debug pim packet-dump receive",
7202 DEBUG_PIM_PACKETDUMP_STR
7203 DEBUG_PIM_PACKETDUMP_RECV_STR
)
7205 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
7209 DEFUN (debug_pim_trace
,
7210 debug_pim_trace_cmd
,
7214 DEBUG_PIM_TRACE_STR
)
7216 PIM_DO_DEBUG_PIM_TRACE
;
7220 DEFUN (debug_pim_trace_detail
,
7221 debug_pim_trace_detail_cmd
,
7222 "debug pim trace detail",
7226 "Detailed Information\n")
7228 PIM_DO_DEBUG_PIM_TRACE_DETAIL
;
7232 DEFUN (no_debug_pim_trace
,
7233 no_debug_pim_trace_cmd
,
7234 "no debug pim trace",
7238 DEBUG_PIM_TRACE_STR
)
7240 PIM_DONT_DEBUG_PIM_TRACE
;
7244 DEFUN (no_debug_pim_trace_detail
,
7245 no_debug_pim_trace_detail_cmd
,
7246 "no debug pim trace detail",
7251 "Detailed Information\n")
7253 PIM_DONT_DEBUG_PIM_TRACE_DETAIL
;
7257 DEFUN (debug_ssmpingd
,
7263 PIM_DO_DEBUG_SSMPINGD
;
7267 DEFUN (no_debug_ssmpingd
,
7268 no_debug_ssmpingd_cmd
,
7269 "no debug ssmpingd",
7274 PIM_DONT_DEBUG_SSMPINGD
;
7278 DEFUN (debug_pim_zebra
,
7279 debug_pim_zebra_cmd
,
7283 DEBUG_PIM_ZEBRA_STR
)
7289 DEFUN (no_debug_pim_zebra
,
7290 no_debug_pim_zebra_cmd
,
7291 "no debug pim zebra",
7295 DEBUG_PIM_ZEBRA_STR
)
7297 PIM_DONT_DEBUG_ZEBRA
;
7307 PIM_DO_DEBUG_MSDP_EVENTS
;
7308 PIM_DO_DEBUG_MSDP_PACKETS
;
7312 DEFUN (no_debug_msdp
,
7319 PIM_DONT_DEBUG_MSDP_EVENTS
;
7320 PIM_DONT_DEBUG_MSDP_PACKETS
;
7324 #if CONFDATE > 20190402
7325 CPP_NOTICE("bgpd: time to remove undebug commands")
7327 ALIAS_HIDDEN (no_debug_msdp
,
7330 UNDEBUG_STR DEBUG_MSDP_STR
)
7332 DEFUN (debug_msdp_events
,
7333 debug_msdp_events_cmd
,
7334 "debug msdp events",
7337 DEBUG_MSDP_EVENTS_STR
)
7339 PIM_DO_DEBUG_MSDP_EVENTS
;
7343 DEFUN (no_debug_msdp_events
,
7344 no_debug_msdp_events_cmd
,
7345 "no debug msdp events",
7349 DEBUG_MSDP_EVENTS_STR
)
7351 PIM_DONT_DEBUG_MSDP_EVENTS
;
7355 #if CONFDATE > 20190402
7356 CPP_NOTICE("bgpd: time to remove undebug commands")
7358 ALIAS_HIDDEN (no_debug_msdp_events
,
7359 undebug_msdp_events_cmd
,
7360 "undebug msdp events",
7363 DEBUG_MSDP_EVENTS_STR
)
7365 DEFUN (debug_msdp_packets
,
7366 debug_msdp_packets_cmd
,
7367 "debug msdp packets",
7370 DEBUG_MSDP_PACKETS_STR
)
7372 PIM_DO_DEBUG_MSDP_PACKETS
;
7376 DEFUN (no_debug_msdp_packets
,
7377 no_debug_msdp_packets_cmd
,
7378 "no debug msdp packets",
7382 DEBUG_MSDP_PACKETS_STR
)
7384 PIM_DONT_DEBUG_MSDP_PACKETS
;
7388 #if CONFDATE > 20190402
7389 CPP_NOTICE("bgpd: time to remove undebug commands")
7391 ALIAS_HIDDEN (no_debug_msdp_packets
,
7392 undebug_msdp_packets_cmd
,
7393 "undebug msdp packets",
7396 DEBUG_MSDP_PACKETS_STR
)
7398 DEFUN (debug_mtrace
,
7404 PIM_DO_DEBUG_MTRACE
;
7408 DEFUN (no_debug_mtrace
,
7409 no_debug_mtrace_cmd
,
7415 PIM_DONT_DEBUG_MTRACE
;
7419 DEFUN_NOSH (show_debugging_pim
,
7420 show_debugging_pim_cmd
,
7421 "show debugging [pim]",
7426 vty_out(vty
, "PIM debugging status\n");
7428 pim_debug_config_write(vty
);
7433 static int interface_pim_use_src_cmd_worker(struct vty
*vty
, const char *source
)
7436 struct in_addr source_addr
;
7437 int ret
= CMD_SUCCESS
;
7438 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7440 result
= inet_pton(AF_INET
, source
, &source_addr
);
7442 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", source
,
7443 errno
, safe_strerror(errno
));
7444 return CMD_WARNING_CONFIG_FAILED
;
7447 result
= pim_update_source_set(ifp
, source_addr
);
7451 case PIM_IFACE_NOT_FOUND
:
7452 ret
= CMD_WARNING_CONFIG_FAILED
;
7453 vty_out(vty
, "Pim not enabled on this interface\n");
7455 case PIM_UPDATE_SOURCE_DUP
:
7457 vty_out(vty
, "%% Source already set to %s\n", source
);
7460 ret
= CMD_WARNING_CONFIG_FAILED
;
7461 vty_out(vty
, "%% Source set failed\n");
7467 DEFUN (interface_pim_use_source
,
7468 interface_pim_use_source_cmd
,
7469 "ip pim use-source A.B.C.D",
7471 "pim multicast routing\n"
7472 "Configure primary IP address\n"
7473 "source ip address\n")
7475 return interface_pim_use_src_cmd_worker(vty
, argv
[3]->arg
);
7478 DEFUN (interface_no_pim_use_source
,
7479 interface_no_pim_use_source_cmd
,
7480 "no ip pim use-source [A.B.C.D]",
7483 "pim multicast routing\n"
7484 "Delete source IP address\n"
7485 "source ip address\n")
7487 return interface_pim_use_src_cmd_worker(vty
, "0.0.0.0");
7495 "Enables BFD support\n")
7497 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7498 struct pim_interface
*pim_ifp
= ifp
->info
;
7499 struct bfd_info
*bfd_info
= NULL
;
7502 if (!pim_cmd_interface_add(ifp
)) {
7503 vty_out(vty
, "Could not enable PIM SM on interface\n");
7507 pim_ifp
= ifp
->info
;
7509 bfd_info
= pim_ifp
->bfd_info
;
7511 if (!bfd_info
|| !CHECK_FLAG(bfd_info
->flags
, BFD_FLAG_PARAM_CFG
))
7512 pim_bfd_if_param_set(ifp
, BFD_DEF_MIN_RX
, BFD_DEF_MIN_TX
,
7513 BFD_DEF_DETECT_MULT
, 1);
7518 DEFUN (no_ip_pim_bfd
,
7524 "Disables BFD support\n")
7526 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7527 struct pim_interface
*pim_ifp
= ifp
->info
;
7530 vty_out(vty
, "Pim not enabled on this interface\n");
7534 if (pim_ifp
->bfd_info
) {
7535 pim_bfd_reg_dereg_all_nbr(ifp
, ZEBRA_BFD_DEST_DEREGISTER
);
7536 bfd_info_free(&(pim_ifp
->bfd_info
));
7546 #endif /* HAVE_BFDD */
7548 ip_pim_bfd_param_cmd
,
7549 "ip pim bfd (2-255) (50-60000) (50-60000)",
7552 "Enables BFD support\n"
7553 "Detect Multiplier\n"
7554 "Required min receive interval\n"
7555 "Desired min transmit interval\n")
7557 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7559 int idx_number_2
= 4;
7560 int idx_number_3
= 5;
7565 struct pim_interface
*pim_ifp
= ifp
->info
;
7568 if (!pim_cmd_interface_add(ifp
)) {
7569 vty_out(vty
, "Could not enable PIM SM on interface\n");
7574 if ((ret
= bfd_validate_param(
7575 vty
, argv
[idx_number
]->arg
, argv
[idx_number_2
]->arg
,
7576 argv
[idx_number_3
]->arg
, &dm_val
, &rx_val
, &tx_val
))
7580 pim_bfd_if_param_set(ifp
, rx_val
, tx_val
, dm_val
, 0);
7586 ALIAS(no_ip_pim_bfd
, no_ip_pim_bfd_param_cmd
,
7587 "no ip pim bfd (2-255) (50-60000) (50-60000)", NO_STR IP_STR PIM_STR
7588 "Enables BFD support\n"
7589 "Detect Multiplier\n"
7590 "Required min receive interval\n"
7591 "Desired min transmit interval\n")
7592 #endif /* !HAVE_BFDD */
7594 static int ip_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
7595 const char *peer
, const char *local
)
7597 enum pim_msdp_err result
;
7598 struct in_addr peer_addr
;
7599 struct in_addr local_addr
;
7600 int ret
= CMD_SUCCESS
;
7602 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
7604 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
7605 errno
, safe_strerror(errno
));
7606 return CMD_WARNING_CONFIG_FAILED
;
7609 result
= inet_pton(AF_INET
, local
, &local_addr
);
7611 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", local
,
7612 errno
, safe_strerror(errno
));
7613 return CMD_WARNING_CONFIG_FAILED
;
7616 result
= pim_msdp_peer_add(pim
, peer_addr
, local_addr
, "default",
7619 case PIM_MSDP_ERR_NONE
:
7621 case PIM_MSDP_ERR_OOM
:
7622 ret
= CMD_WARNING_CONFIG_FAILED
;
7623 vty_out(vty
, "%% Out of memory\n");
7625 case PIM_MSDP_ERR_PEER_EXISTS
:
7627 vty_out(vty
, "%% Peer exists\n");
7629 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
7630 ret
= CMD_WARNING_CONFIG_FAILED
;
7631 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
7634 ret
= CMD_WARNING_CONFIG_FAILED
;
7635 vty_out(vty
, "%% peer add failed\n");
7641 DEFUN_HIDDEN (ip_msdp_peer
,
7643 "ip msdp peer A.B.C.D source A.B.C.D",
7646 "Configure MSDP peer\n"
7648 "Source address for TCP connection\n"
7649 "local ip address\n")
7651 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7652 return ip_msdp_peer_cmd_worker(pim
, vty
, argv
[3]->arg
, argv
[5]->arg
);
7655 static int ip_no_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
7658 enum pim_msdp_err result
;
7659 struct in_addr peer_addr
;
7661 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
7663 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
7664 errno
, safe_strerror(errno
));
7665 return CMD_WARNING_CONFIG_FAILED
;
7668 result
= pim_msdp_peer_del(pim
, peer_addr
);
7670 case PIM_MSDP_ERR_NONE
:
7672 case PIM_MSDP_ERR_NO_PEER
:
7673 vty_out(vty
, "%% Peer does not exist\n");
7676 vty_out(vty
, "%% peer del failed\n");
7679 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7682 DEFUN_HIDDEN (no_ip_msdp_peer
,
7683 no_ip_msdp_peer_cmd
,
7684 "no ip msdp peer A.B.C.D",
7688 "Delete MSDP peer\n"
7689 "peer ip address\n")
7691 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7692 return ip_no_msdp_peer_cmd_worker(pim
, vty
, argv
[4]->arg
);
7695 static int ip_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
7696 struct vty
*vty
, const char *mg
,
7699 enum pim_msdp_err result
;
7700 struct in_addr mbr_ip
;
7701 int ret
= CMD_SUCCESS
;
7703 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
7705 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
7706 errno
, safe_strerror(errno
));
7707 return CMD_WARNING_CONFIG_FAILED
;
7710 result
= pim_msdp_mg_mbr_add(pim
, mg
, mbr_ip
);
7712 case PIM_MSDP_ERR_NONE
:
7714 case PIM_MSDP_ERR_OOM
:
7715 ret
= CMD_WARNING_CONFIG_FAILED
;
7716 vty_out(vty
, "%% Out of memory\n");
7718 case PIM_MSDP_ERR_MG_MBR_EXISTS
:
7720 vty_out(vty
, "%% mesh-group member exists\n");
7722 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
7723 ret
= CMD_WARNING_CONFIG_FAILED
;
7724 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
7727 ret
= CMD_WARNING_CONFIG_FAILED
;
7728 vty_out(vty
, "%% member add failed\n");
7734 DEFUN (ip_msdp_mesh_group_member
,
7735 ip_msdp_mesh_group_member_cmd
,
7736 "ip msdp mesh-group WORD member A.B.C.D",
7739 "Configure MSDP mesh-group\n"
7741 "mesh group member\n"
7742 "peer ip address\n")
7744 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7745 return ip_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[3]->arg
,
7749 static int ip_no_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
7754 enum pim_msdp_err result
;
7755 struct in_addr mbr_ip
;
7757 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
7759 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
7760 errno
, safe_strerror(errno
));
7761 return CMD_WARNING_CONFIG_FAILED
;
7764 result
= pim_msdp_mg_mbr_del(pim
, mg
, mbr_ip
);
7766 case PIM_MSDP_ERR_NONE
:
7768 case PIM_MSDP_ERR_NO_MG
:
7769 vty_out(vty
, "%% mesh-group does not exist\n");
7771 case PIM_MSDP_ERR_NO_MG_MBR
:
7772 vty_out(vty
, "%% mesh-group member does not exist\n");
7775 vty_out(vty
, "%% mesh-group member del failed\n");
7778 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7780 DEFUN (no_ip_msdp_mesh_group_member
,
7781 no_ip_msdp_mesh_group_member_cmd
,
7782 "no ip msdp mesh-group WORD member A.B.C.D",
7786 "Delete MSDP mesh-group member\n"
7788 "mesh group member\n"
7789 "peer ip address\n")
7791 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7792 return ip_no_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[4]->arg
,
7796 static int ip_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
7797 struct vty
*vty
, const char *mg
,
7800 enum pim_msdp_err result
;
7801 struct in_addr src_ip
;
7803 result
= inet_pton(AF_INET
, src
, &src_ip
);
7805 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", src
,
7806 errno
, safe_strerror(errno
));
7807 return CMD_WARNING_CONFIG_FAILED
;
7810 result
= pim_msdp_mg_src_add(pim
, mg
, src_ip
);
7812 case PIM_MSDP_ERR_NONE
:
7814 case PIM_MSDP_ERR_OOM
:
7815 vty_out(vty
, "%% Out of memory\n");
7817 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
7818 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
7821 vty_out(vty
, "%% source add failed\n");
7824 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7828 DEFUN (ip_msdp_mesh_group_source
,
7829 ip_msdp_mesh_group_source_cmd
,
7830 "ip msdp mesh-group WORD source A.B.C.D",
7833 "Configure MSDP mesh-group\n"
7835 "mesh group local address\n"
7836 "source ip address for the TCP connection\n")
7838 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7839 return ip_msdp_mesh_group_source_cmd_worker(pim
, vty
, argv
[3]->arg
,
7843 static int ip_no_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
7847 enum pim_msdp_err result
;
7849 result
= pim_msdp_mg_src_del(pim
, mg
);
7851 case PIM_MSDP_ERR_NONE
:
7853 case PIM_MSDP_ERR_NO_MG
:
7854 vty_out(vty
, "%% mesh-group does not exist\n");
7857 vty_out(vty
, "%% mesh-group source del failed\n");
7860 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7863 static int ip_no_msdp_mesh_group_cmd_worker(struct pim_instance
*pim
,
7864 struct vty
*vty
, const char *mg
)
7866 enum pim_msdp_err result
;
7868 result
= pim_msdp_mg_del(pim
, mg
);
7870 case PIM_MSDP_ERR_NONE
:
7872 case PIM_MSDP_ERR_NO_MG
:
7873 vty_out(vty
, "%% mesh-group does not exist\n");
7876 vty_out(vty
, "%% mesh-group source del failed\n");
7879 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7882 DEFUN (no_ip_msdp_mesh_group_source
,
7883 no_ip_msdp_mesh_group_source_cmd
,
7884 "no ip msdp mesh-group WORD source [A.B.C.D]",
7888 "Delete MSDP mesh-group source\n"
7890 "mesh group source\n"
7891 "mesh group local address\n")
7893 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7895 return ip_no_msdp_mesh_group_cmd_worker(pim
, vty
, argv
[6]->arg
);
7897 return ip_no_msdp_mesh_group_source_cmd_worker(pim
, vty
,
7901 static void print_empty_json_obj(struct vty
*vty
)
7904 json
= json_object_new_object();
7905 vty_out(vty
, "%s\n",
7906 json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
));
7907 json_object_free(json
);
7910 static void ip_msdp_show_mesh_group(struct pim_instance
*pim
, struct vty
*vty
,
7913 struct listnode
*mbrnode
;
7914 struct pim_msdp_mg_mbr
*mbr
;
7915 struct pim_msdp_mg
*mg
= pim
->msdp
.mg
;
7916 char mbr_str
[INET_ADDRSTRLEN
];
7917 char src_str
[INET_ADDRSTRLEN
];
7918 char state_str
[PIM_MSDP_STATE_STRLEN
];
7919 enum pim_msdp_peer_state state
;
7920 json_object
*json
= NULL
;
7921 json_object
*json_mg_row
= NULL
;
7922 json_object
*json_members
= NULL
;
7923 json_object
*json_row
= NULL
;
7927 print_empty_json_obj(vty
);
7931 pim_inet4_dump("<source?>", mg
->src_ip
, src_str
, sizeof(src_str
));
7933 json
= json_object_new_object();
7934 /* currently there is only one mesh group but we should still
7936 * it a dict with mg-name as key */
7937 json_mg_row
= json_object_new_object();
7938 json_object_string_add(json_mg_row
, "name",
7939 mg
->mesh_group_name
);
7940 json_object_string_add(json_mg_row
, "source", src_str
);
7942 vty_out(vty
, "Mesh group : %s\n", mg
->mesh_group_name
);
7943 vty_out(vty
, " Source : %s\n", src_str
);
7944 vty_out(vty
, " Member State\n");
7947 for (ALL_LIST_ELEMENTS_RO(mg
->mbr_list
, mbrnode
, mbr
)) {
7948 pim_inet4_dump("<mbr?>", mbr
->mbr_ip
, mbr_str
, sizeof(mbr_str
));
7950 state
= mbr
->mp
->state
;
7952 state
= PIM_MSDP_DISABLED
;
7954 pim_msdp_state_dump(state
, state_str
, sizeof(state_str
));
7956 json_row
= json_object_new_object();
7957 json_object_string_add(json_row
, "member", mbr_str
);
7958 json_object_string_add(json_row
, "state", state_str
);
7959 if (!json_members
) {
7960 json_members
= json_object_new_object();
7961 json_object_object_add(json_mg_row
, "members",
7964 json_object_object_add(json_members
, mbr_str
, json_row
);
7966 vty_out(vty
, " %-15s %11s\n", mbr_str
, state_str
);
7971 json_object_object_add(json
, mg
->mesh_group_name
, json_mg_row
);
7972 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
7973 json
, JSON_C_TO_STRING_PRETTY
));
7974 json_object_free(json
);
7978 DEFUN (show_ip_msdp_mesh_group
,
7979 show_ip_msdp_mesh_group_cmd
,
7980 "show ip msdp [vrf NAME] mesh-group [json]",
7985 "MSDP mesh-group information\n"
7988 uint8_t uj
= use_json(argc
, argv
);
7990 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
7995 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
8000 DEFUN (show_ip_msdp_mesh_group_vrf_all
,
8001 show_ip_msdp_mesh_group_vrf_all_cmd
,
8002 "show ip msdp vrf all mesh-group [json]",
8007 "MSDP mesh-group information\n"
8010 uint8_t uj
= use_json(argc
, argv
);
8016 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
8020 vty_out(vty
, " \"%s\": ", vrf
->name
);
8023 vty_out(vty
, "VRF: %s\n", vrf
->name
);
8024 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
8027 vty_out(vty
, "}\n");
8032 static void ip_msdp_show_peers(struct pim_instance
*pim
, struct vty
*vty
,
8035 struct listnode
*mpnode
;
8036 struct pim_msdp_peer
*mp
;
8037 char peer_str
[INET_ADDRSTRLEN
];
8038 char local_str
[INET_ADDRSTRLEN
];
8039 char state_str
[PIM_MSDP_STATE_STRLEN
];
8040 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
8042 json_object
*json
= NULL
;
8043 json_object
*json_row
= NULL
;
8047 json
= json_object_new_object();
8050 "Peer Local State Uptime SaCnt\n");
8053 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
8054 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
8055 now
= pim_time_monotonic_sec();
8056 pim_time_uptime(timebuf
, sizeof(timebuf
),
8059 strcpy(timebuf
, "-");
8061 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
8062 pim_inet4_dump("<local?>", mp
->local
, local_str
,
8064 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
8066 json_row
= json_object_new_object();
8067 json_object_string_add(json_row
, "peer", peer_str
);
8068 json_object_string_add(json_row
, "local", local_str
);
8069 json_object_string_add(json_row
, "state", state_str
);
8070 json_object_string_add(json_row
, "upTime", timebuf
);
8071 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
8072 json_object_object_add(json
, peer_str
, json_row
);
8074 vty_out(vty
, "%-15s %15s %11s %8s %6d\n", peer_str
,
8075 local_str
, state_str
, timebuf
, mp
->sa_cnt
);
8080 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8081 json
, JSON_C_TO_STRING_PRETTY
));
8082 json_object_free(json
);
8086 static void ip_msdp_show_peers_detail(struct pim_instance
*pim
, struct vty
*vty
,
8087 const char *peer
, uint8_t uj
)
8089 struct listnode
*mpnode
;
8090 struct pim_msdp_peer
*mp
;
8091 char peer_str
[INET_ADDRSTRLEN
];
8092 char local_str
[INET_ADDRSTRLEN
];
8093 char state_str
[PIM_MSDP_STATE_STRLEN
];
8094 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
8095 char katimer
[PIM_MSDP_TIMER_STRLEN
];
8096 char crtimer
[PIM_MSDP_TIMER_STRLEN
];
8097 char holdtimer
[PIM_MSDP_TIMER_STRLEN
];
8099 json_object
*json
= NULL
;
8100 json_object
*json_row
= NULL
;
8103 json
= json_object_new_object();
8106 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
8107 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
8108 if (strcmp(peer
, "detail") && strcmp(peer
, peer_str
))
8111 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
8112 now
= pim_time_monotonic_sec();
8113 pim_time_uptime(timebuf
, sizeof(timebuf
),
8116 strcpy(timebuf
, "-");
8118 pim_inet4_dump("<local?>", mp
->local
, local_str
,
8120 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
8121 pim_time_timer_to_hhmmss(katimer
, sizeof(katimer
),
8123 pim_time_timer_to_hhmmss(crtimer
, sizeof(crtimer
),
8125 pim_time_timer_to_hhmmss(holdtimer
, sizeof(holdtimer
),
8129 json_row
= json_object_new_object();
8130 json_object_string_add(json_row
, "peer", peer_str
);
8131 json_object_string_add(json_row
, "local", local_str
);
8132 json_object_string_add(json_row
, "meshGroupName",
8133 mp
->mesh_group_name
);
8134 json_object_string_add(json_row
, "state", state_str
);
8135 json_object_string_add(json_row
, "upTime", timebuf
);
8136 json_object_string_add(json_row
, "keepAliveTimer",
8138 json_object_string_add(json_row
, "connRetryTimer",
8140 json_object_string_add(json_row
, "holdTimer",
8142 json_object_string_add(json_row
, "lastReset",
8144 json_object_int_add(json_row
, "connAttempts",
8146 json_object_int_add(json_row
, "establishedChanges",
8148 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
8149 json_object_int_add(json_row
, "kaSent", mp
->ka_tx_cnt
);
8150 json_object_int_add(json_row
, "kaRcvd", mp
->ka_rx_cnt
);
8151 json_object_int_add(json_row
, "saSent", mp
->sa_tx_cnt
);
8152 json_object_int_add(json_row
, "saRcvd", mp
->sa_rx_cnt
);
8153 json_object_object_add(json
, peer_str
, json_row
);
8155 vty_out(vty
, "Peer : %s\n", peer_str
);
8156 vty_out(vty
, " Local : %s\n", local_str
);
8157 vty_out(vty
, " Mesh Group : %s\n",
8158 mp
->mesh_group_name
);
8159 vty_out(vty
, " State : %s\n", state_str
);
8160 vty_out(vty
, " Uptime : %s\n", timebuf
);
8162 vty_out(vty
, " Keepalive Timer : %s\n", katimer
);
8163 vty_out(vty
, " Conn Retry Timer : %s\n", crtimer
);
8164 vty_out(vty
, " Hold Timer : %s\n", holdtimer
);
8165 vty_out(vty
, " Last Reset : %s\n",
8167 vty_out(vty
, " Conn Attempts : %d\n",
8169 vty_out(vty
, " Established Changes : %d\n",
8171 vty_out(vty
, " SA Count : %d\n",
8173 vty_out(vty
, " Statistics :\n");
8176 vty_out(vty
, " Keepalives : %10d %10d\n",
8177 mp
->ka_tx_cnt
, mp
->ka_rx_cnt
);
8178 vty_out(vty
, " SAs : %10d %10d\n",
8179 mp
->sa_tx_cnt
, mp
->sa_rx_cnt
);
8185 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8186 json
, JSON_C_TO_STRING_PRETTY
));
8187 json_object_free(json
);
8191 DEFUN (show_ip_msdp_peer_detail
,
8192 show_ip_msdp_peer_detail_cmd
,
8193 "show ip msdp [vrf NAME] peer [detail|A.B.C.D] [json]",
8198 "MSDP peer information\n"
8203 uint8_t uj
= use_json(argc
, argv
);
8205 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
8212 if (argv_find(argv
, argc
, "detail", &idx
))
8213 arg
= argv
[idx
]->text
;
8214 else if (argv_find(argv
, argc
, "A.B.C.D", &idx
))
8215 arg
= argv
[idx
]->arg
;
8218 ip_msdp_show_peers_detail(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
8220 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
8225 DEFUN (show_ip_msdp_peer_detail_vrf_all
,
8226 show_ip_msdp_peer_detail_vrf_all_cmd
,
8227 "show ip msdp vrf all peer [detail|A.B.C.D] [json]",
8232 "MSDP peer information\n"
8238 uint8_t uj
= use_json(argc
, argv
);
8244 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
8248 vty_out(vty
, " \"%s\": ", vrf
->name
);
8251 vty_out(vty
, "VRF: %s\n", vrf
->name
);
8252 if (argv_find(argv
, argc
, "detail", &idx
)
8253 || argv_find(argv
, argc
, "A.B.C.D", &idx
))
8254 ip_msdp_show_peers_detail(vrf
->info
, vty
,
8255 argv
[idx
]->arg
, uj
);
8257 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
8260 vty_out(vty
, "}\n");
8265 static void ip_msdp_show_sa(struct pim_instance
*pim
, struct vty
*vty
,
8268 struct listnode
*sanode
;
8269 struct pim_msdp_sa
*sa
;
8270 char src_str
[INET_ADDRSTRLEN
];
8271 char grp_str
[INET_ADDRSTRLEN
];
8272 char rp_str
[INET_ADDRSTRLEN
];
8273 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
8277 json_object
*json
= NULL
;
8278 json_object
*json_group
= NULL
;
8279 json_object
*json_row
= NULL
;
8282 json
= json_object_new_object();
8285 "Source Group RP Local SPT Uptime\n");
8288 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
8289 now
= pim_time_monotonic_sec();
8290 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
8291 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
8292 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
8293 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
8294 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
8296 strcpy(spt_str
, "yes");
8298 strcpy(spt_str
, "no");
8301 strcpy(rp_str
, "-");
8302 strcpy(spt_str
, "-");
8304 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
8305 strcpy(local_str
, "yes");
8307 strcpy(local_str
, "no");
8310 json_object_object_get_ex(json
, grp_str
, &json_group
);
8313 json_group
= json_object_new_object();
8314 json_object_object_add(json
, grp_str
,
8318 json_row
= json_object_new_object();
8319 json_object_string_add(json_row
, "source", src_str
);
8320 json_object_string_add(json_row
, "group", grp_str
);
8321 json_object_string_add(json_row
, "rp", rp_str
);
8322 json_object_string_add(json_row
, "local", local_str
);
8323 json_object_string_add(json_row
, "sptSetup", spt_str
);
8324 json_object_string_add(json_row
, "upTime", timebuf
);
8325 json_object_object_add(json_group
, src_str
, json_row
);
8327 vty_out(vty
, "%-15s %15s %15s %5c %3c %8s\n",
8328 src_str
, grp_str
, rp_str
, local_str
[0],
8329 spt_str
[0], timebuf
);
8334 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8335 json
, JSON_C_TO_STRING_PRETTY
));
8336 json_object_free(json
);
8340 static void ip_msdp_show_sa_entry_detail(struct pim_msdp_sa
*sa
,
8341 const char *src_str
,
8342 const char *grp_str
, struct vty
*vty
,
8343 uint8_t uj
, json_object
*json
)
8345 char rp_str
[INET_ADDRSTRLEN
];
8346 char peer_str
[INET_ADDRSTRLEN
];
8347 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
8350 char statetimer
[PIM_MSDP_TIMER_STRLEN
];
8352 json_object
*json_group
= NULL
;
8353 json_object
*json_row
= NULL
;
8355 now
= pim_time_monotonic_sec();
8356 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
8357 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
8358 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
8359 pim_inet4_dump("<peer?>", sa
->peer
, peer_str
, sizeof(peer_str
));
8361 strcpy(spt_str
, "yes");
8363 strcpy(spt_str
, "no");
8366 strcpy(rp_str
, "-");
8367 strcpy(peer_str
, "-");
8368 strcpy(spt_str
, "-");
8370 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
8371 strcpy(local_str
, "yes");
8373 strcpy(local_str
, "no");
8375 pim_time_timer_to_hhmmss(statetimer
, sizeof(statetimer
),
8376 sa
->sa_state_timer
);
8378 json_object_object_get_ex(json
, grp_str
, &json_group
);
8381 json_group
= json_object_new_object();
8382 json_object_object_add(json
, grp_str
, json_group
);
8385 json_row
= json_object_new_object();
8386 json_object_string_add(json_row
, "source", src_str
);
8387 json_object_string_add(json_row
, "group", grp_str
);
8388 json_object_string_add(json_row
, "rp", rp_str
);
8389 json_object_string_add(json_row
, "local", local_str
);
8390 json_object_string_add(json_row
, "sptSetup", spt_str
);
8391 json_object_string_add(json_row
, "upTime", timebuf
);
8392 json_object_string_add(json_row
, "stateTimer", statetimer
);
8393 json_object_object_add(json_group
, src_str
, json_row
);
8395 vty_out(vty
, "SA : %s\n", sa
->sg_str
);
8396 vty_out(vty
, " RP : %s\n", rp_str
);
8397 vty_out(vty
, " Peer : %s\n", peer_str
);
8398 vty_out(vty
, " Local : %s\n", local_str
);
8399 vty_out(vty
, " SPT Setup : %s\n", spt_str
);
8400 vty_out(vty
, " Uptime : %s\n", timebuf
);
8401 vty_out(vty
, " State Timer : %s\n", statetimer
);
8406 static void ip_msdp_show_sa_detail(struct pim_instance
*pim
, struct vty
*vty
,
8409 struct listnode
*sanode
;
8410 struct pim_msdp_sa
*sa
;
8411 char src_str
[INET_ADDRSTRLEN
];
8412 char grp_str
[INET_ADDRSTRLEN
];
8413 json_object
*json
= NULL
;
8416 json
= json_object_new_object();
8419 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
8420 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
8421 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
8422 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
, uj
,
8427 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8428 json
, JSON_C_TO_STRING_PRETTY
));
8429 json_object_free(json
);
8433 DEFUN (show_ip_msdp_sa_detail
,
8434 show_ip_msdp_sa_detail_cmd
,
8435 "show ip msdp [vrf NAME] sa detail [json]",
8440 "MSDP active-source information\n"
8444 uint8_t uj
= use_json(argc
, argv
);
8446 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
8451 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
8456 DEFUN (show_ip_msdp_sa_detail_vrf_all
,
8457 show_ip_msdp_sa_detail_vrf_all_cmd
,
8458 "show ip msdp vrf all sa detail [json]",
8463 "MSDP active-source information\n"
8467 uint8_t uj
= use_json(argc
, argv
);
8473 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
8477 vty_out(vty
, " \"%s\": ", vrf
->name
);
8480 vty_out(vty
, "VRF: %s\n", vrf
->name
);
8481 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
8484 vty_out(vty
, "}\n");
8489 static void ip_msdp_show_sa_addr(struct pim_instance
*pim
, struct vty
*vty
,
8490 const char *addr
, uint8_t uj
)
8492 struct listnode
*sanode
;
8493 struct pim_msdp_sa
*sa
;
8494 char src_str
[INET_ADDRSTRLEN
];
8495 char grp_str
[INET_ADDRSTRLEN
];
8496 json_object
*json
= NULL
;
8499 json
= json_object_new_object();
8502 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
8503 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
8504 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
8505 if (!strcmp(addr
, src_str
) || !strcmp(addr
, grp_str
)) {
8506 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
8512 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8513 json
, JSON_C_TO_STRING_PRETTY
));
8514 json_object_free(json
);
8518 static void ip_msdp_show_sa_sg(struct pim_instance
*pim
, struct vty
*vty
,
8519 const char *src
, const char *grp
, uint8_t uj
)
8521 struct listnode
*sanode
;
8522 struct pim_msdp_sa
*sa
;
8523 char src_str
[INET_ADDRSTRLEN
];
8524 char grp_str
[INET_ADDRSTRLEN
];
8525 json_object
*json
= NULL
;
8528 json
= json_object_new_object();
8531 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
8532 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
8533 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
8534 if (!strcmp(src
, src_str
) && !strcmp(grp
, grp_str
)) {
8535 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
8541 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8542 json
, JSON_C_TO_STRING_PRETTY
));
8543 json_object_free(json
);
8547 DEFUN (show_ip_msdp_sa_sg
,
8548 show_ip_msdp_sa_sg_cmd
,
8549 "show ip msdp [vrf NAME] sa [A.B.C.D [A.B.C.D]] [json]",
8554 "MSDP active-source information\n"
8555 "source or group ip\n"
8559 uint8_t uj
= use_json(argc
, argv
);
8563 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
8568 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
8570 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
8574 if (src_ip
&& grp_ip
)
8575 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
8577 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
8579 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
8584 DEFUN (show_ip_msdp_sa_sg_vrf_all
,
8585 show_ip_msdp_sa_sg_vrf_all_cmd
,
8586 "show ip msdp vrf all sa [A.B.C.D [A.B.C.D]] [json]",
8591 "MSDP active-source information\n"
8592 "source or group ip\n"
8596 uint8_t uj
= use_json(argc
, argv
);
8601 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
8603 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
8609 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
8613 vty_out(vty
, " \"%s\": ", vrf
->name
);
8616 vty_out(vty
, "VRF: %s\n", vrf
->name
);
8618 if (src_ip
&& grp_ip
)
8619 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
8621 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
8623 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
8626 vty_out(vty
, "}\n");
8632 void pim_cmd_init(void)
8634 install_node(&interface_node
,
8635 pim_interface_config_write
); /* INTERFACE_NODE */
8638 install_node(&debug_node
, pim_debug_config_write
);
8640 install_element(CONFIG_NODE
, &ip_multicast_routing_cmd
);
8641 install_element(CONFIG_NODE
, &no_ip_multicast_routing_cmd
);
8642 install_element(CONFIG_NODE
, &ip_pim_rp_cmd
);
8643 install_element(VRF_NODE
, &ip_pim_rp_cmd
);
8644 install_element(CONFIG_NODE
, &no_ip_pim_rp_cmd
);
8645 install_element(VRF_NODE
, &no_ip_pim_rp_cmd
);
8646 install_element(CONFIG_NODE
, &ip_pim_rp_prefix_list_cmd
);
8647 install_element(VRF_NODE
, &ip_pim_rp_prefix_list_cmd
);
8648 install_element(CONFIG_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
8649 install_element(VRF_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
8650 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
8651 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
8652 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
8653 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
8654 install_element(CONFIG_NODE
, &ip_pim_ssm_prefix_list_cmd
);
8655 install_element(VRF_NODE
, &ip_pim_ssm_prefix_list_cmd
);
8656 install_element(CONFIG_NODE
, &ip_pim_register_suppress_cmd
);
8657 install_element(VRF_NODE
, &ip_pim_register_suppress_cmd
);
8658 install_element(CONFIG_NODE
, &no_ip_pim_register_suppress_cmd
);
8659 install_element(VRF_NODE
, &no_ip_pim_register_suppress_cmd
);
8660 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
8661 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
8662 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
8663 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
8664 install_element(CONFIG_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
8665 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
8666 install_element(CONFIG_NODE
,
8667 &no_ip_pim_spt_switchover_infinity_plist_cmd
);
8668 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_plist_cmd
);
8669 install_element(CONFIG_NODE
, &ip_pim_joinprune_time_cmd
);
8670 install_element(VRF_NODE
, &ip_pim_joinprune_time_cmd
);
8671 install_element(CONFIG_NODE
, &no_ip_pim_joinprune_time_cmd
);
8672 install_element(VRF_NODE
, &no_ip_pim_joinprune_time_cmd
);
8673 install_element(CONFIG_NODE
, &ip_pim_keep_alive_cmd
);
8674 install_element(VRF_NODE
, &ip_pim_keep_alive_cmd
);
8675 install_element(CONFIG_NODE
, &ip_pim_rp_keep_alive_cmd
);
8676 install_element(VRF_NODE
, &ip_pim_rp_keep_alive_cmd
);
8677 install_element(CONFIG_NODE
, &no_ip_pim_keep_alive_cmd
);
8678 install_element(VRF_NODE
, &no_ip_pim_keep_alive_cmd
);
8679 install_element(CONFIG_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
8680 install_element(VRF_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
8681 install_element(CONFIG_NODE
, &ip_pim_packets_cmd
);
8682 install_element(VRF_NODE
, &ip_pim_packets_cmd
);
8683 install_element(CONFIG_NODE
, &no_ip_pim_packets_cmd
);
8684 install_element(VRF_NODE
, &no_ip_pim_packets_cmd
);
8685 install_element(CONFIG_NODE
, &ip_pim_v6_secondary_cmd
);
8686 install_element(VRF_NODE
, &ip_pim_v6_secondary_cmd
);
8687 install_element(CONFIG_NODE
, &no_ip_pim_v6_secondary_cmd
);
8688 install_element(VRF_NODE
, &no_ip_pim_v6_secondary_cmd
);
8689 install_element(CONFIG_NODE
, &ip_ssmpingd_cmd
);
8690 install_element(VRF_NODE
, &ip_ssmpingd_cmd
);
8691 install_element(CONFIG_NODE
, &no_ip_ssmpingd_cmd
);
8692 install_element(VRF_NODE
, &no_ip_ssmpingd_cmd
);
8693 install_element(CONFIG_NODE
, &ip_msdp_peer_cmd
);
8694 install_element(VRF_NODE
, &ip_msdp_peer_cmd
);
8695 install_element(CONFIG_NODE
, &no_ip_msdp_peer_cmd
);
8696 install_element(VRF_NODE
, &no_ip_msdp_peer_cmd
);
8697 install_element(CONFIG_NODE
, &ip_pim_ecmp_cmd
);
8698 install_element(VRF_NODE
, &ip_pim_ecmp_cmd
);
8699 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_cmd
);
8700 install_element(VRF_NODE
, &no_ip_pim_ecmp_cmd
);
8701 install_element(CONFIG_NODE
, &ip_pim_ecmp_rebalance_cmd
);
8702 install_element(VRF_NODE
, &ip_pim_ecmp_rebalance_cmd
);
8703 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
8704 install_element(VRF_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
8706 install_element(INTERFACE_NODE
, &interface_ip_igmp_cmd
);
8707 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_cmd
);
8708 install_element(INTERFACE_NODE
, &interface_ip_igmp_join_cmd
);
8709 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_join_cmd
);
8710 install_element(INTERFACE_NODE
, &interface_ip_igmp_version_cmd
);
8711 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_version_cmd
);
8712 install_element(INTERFACE_NODE
, &interface_ip_igmp_query_interval_cmd
);
8713 install_element(INTERFACE_NODE
,
8714 &interface_no_ip_igmp_query_interval_cmd
);
8715 install_element(INTERFACE_NODE
,
8716 &interface_ip_igmp_query_max_response_time_cmd
);
8717 install_element(INTERFACE_NODE
,
8718 &interface_no_ip_igmp_query_max_response_time_cmd
);
8719 install_element(INTERFACE_NODE
,
8720 &interface_ip_igmp_query_max_response_time_dsec_cmd
);
8721 install_element(INTERFACE_NODE
,
8722 &interface_no_ip_igmp_query_max_response_time_dsec_cmd
);
8723 install_element(INTERFACE_NODE
, &interface_ip_pim_ssm_cmd
);
8724 install_element(INTERFACE_NODE
, &interface_no_ip_pim_ssm_cmd
);
8725 install_element(INTERFACE_NODE
, &interface_ip_pim_sm_cmd
);
8726 install_element(INTERFACE_NODE
, &interface_no_ip_pim_sm_cmd
);
8727 install_element(INTERFACE_NODE
, &interface_ip_pim_drprio_cmd
);
8728 install_element(INTERFACE_NODE
, &interface_no_ip_pim_drprio_cmd
);
8729 install_element(INTERFACE_NODE
, &interface_ip_pim_hello_cmd
);
8730 install_element(INTERFACE_NODE
, &interface_no_ip_pim_hello_cmd
);
8731 install_element(INTERFACE_NODE
, &interface_ip_pim_boundary_oil_cmd
);
8732 install_element(INTERFACE_NODE
, &interface_no_ip_pim_boundary_oil_cmd
);
8734 // Static mroutes NEB
8735 install_element(INTERFACE_NODE
, &interface_ip_mroute_cmd
);
8736 install_element(INTERFACE_NODE
, &interface_ip_mroute_source_cmd
);
8737 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_cmd
);
8738 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_source_cmd
);
8740 install_element(VIEW_NODE
, &show_ip_igmp_interface_cmd
);
8741 install_element(VIEW_NODE
, &show_ip_igmp_interface_vrf_all_cmd
);
8742 install_element(VIEW_NODE
, &show_ip_igmp_join_cmd
);
8743 install_element(VIEW_NODE
, &show_ip_igmp_join_vrf_all_cmd
);
8744 install_element(VIEW_NODE
, &show_ip_igmp_groups_cmd
);
8745 install_element(VIEW_NODE
, &show_ip_igmp_groups_vrf_all_cmd
);
8746 install_element(VIEW_NODE
, &show_ip_igmp_groups_retransmissions_cmd
);
8747 install_element(VIEW_NODE
, &show_ip_igmp_sources_cmd
);
8748 install_element(VIEW_NODE
, &show_ip_igmp_sources_retransmissions_cmd
);
8749 install_element(VIEW_NODE
, &show_ip_igmp_statistics_cmd
);
8750 install_element(VIEW_NODE
, &show_ip_pim_assert_cmd
);
8751 install_element(VIEW_NODE
, &show_ip_pim_assert_internal_cmd
);
8752 install_element(VIEW_NODE
, &show_ip_pim_assert_metric_cmd
);
8753 install_element(VIEW_NODE
, &show_ip_pim_assert_winner_metric_cmd
);
8754 install_element(VIEW_NODE
, &show_ip_pim_interface_traffic_cmd
);
8755 install_element(VIEW_NODE
, &show_ip_pim_interface_cmd
);
8756 install_element(VIEW_NODE
, &show_ip_pim_interface_vrf_all_cmd
);
8757 install_element(VIEW_NODE
, &show_ip_pim_join_cmd
);
8758 install_element(VIEW_NODE
, &show_ip_pim_join_vrf_all_cmd
);
8759 install_element(VIEW_NODE
, &show_ip_pim_local_membership_cmd
);
8760 install_element(VIEW_NODE
, &show_ip_pim_neighbor_cmd
);
8761 install_element(VIEW_NODE
, &show_ip_pim_neighbor_vrf_all_cmd
);
8762 install_element(VIEW_NODE
, &show_ip_pim_rpf_cmd
);
8763 install_element(VIEW_NODE
, &show_ip_pim_rpf_vrf_all_cmd
);
8764 install_element(VIEW_NODE
, &show_ip_pim_secondary_cmd
);
8765 install_element(VIEW_NODE
, &show_ip_pim_state_cmd
);
8766 install_element(VIEW_NODE
, &show_ip_pim_state_vrf_all_cmd
);
8767 install_element(VIEW_NODE
, &show_ip_pim_upstream_cmd
);
8768 install_element(VIEW_NODE
, &show_ip_pim_upstream_vrf_all_cmd
);
8769 install_element(VIEW_NODE
, &show_ip_pim_upstream_join_desired_cmd
);
8770 install_element(VIEW_NODE
, &show_ip_pim_upstream_rpf_cmd
);
8771 install_element(VIEW_NODE
, &show_ip_pim_rp_cmd
);
8772 install_element(VIEW_NODE
, &show_ip_pim_rp_vrf_all_cmd
);
8773 install_element(VIEW_NODE
, &show_ip_multicast_cmd
);
8774 install_element(VIEW_NODE
, &show_ip_multicast_vrf_all_cmd
);
8775 install_element(VIEW_NODE
, &show_ip_mroute_cmd
);
8776 install_element(VIEW_NODE
, &show_ip_mroute_vrf_all_cmd
);
8777 install_element(VIEW_NODE
, &show_ip_mroute_count_cmd
);
8778 install_element(VIEW_NODE
, &show_ip_mroute_count_vrf_all_cmd
);
8779 install_element(VIEW_NODE
, &show_ip_rib_cmd
);
8780 install_element(VIEW_NODE
, &show_ip_ssmpingd_cmd
);
8781 install_element(VIEW_NODE
, &show_debugging_pim_cmd
);
8782 install_element(VIEW_NODE
, &show_ip_pim_nexthop_cmd
);
8783 install_element(VIEW_NODE
, &show_ip_pim_nexthop_lookup_cmd
);
8785 install_element(ENABLE_NODE
, &clear_ip_interfaces_cmd
);
8786 install_element(ENABLE_NODE
, &clear_ip_igmp_interfaces_cmd
);
8787 install_element(ENABLE_NODE
, &clear_ip_mroute_cmd
);
8788 install_element(ENABLE_NODE
, &clear_ip_pim_interfaces_cmd
);
8789 install_element(ENABLE_NODE
, &clear_ip_pim_interface_traffic_cmd
);
8790 install_element(ENABLE_NODE
, &clear_ip_pim_oil_cmd
);
8792 install_element(ENABLE_NODE
, &debug_igmp_cmd
);
8793 install_element(ENABLE_NODE
, &no_debug_igmp_cmd
);
8794 install_element(ENABLE_NODE
, &debug_igmp_events_cmd
);
8795 install_element(ENABLE_NODE
, &no_debug_igmp_events_cmd
);
8796 install_element(ENABLE_NODE
, &debug_igmp_packets_cmd
);
8797 install_element(ENABLE_NODE
, &no_debug_igmp_packets_cmd
);
8798 install_element(ENABLE_NODE
, &debug_igmp_trace_cmd
);
8799 install_element(ENABLE_NODE
, &no_debug_igmp_trace_cmd
);
8800 install_element(ENABLE_NODE
, &debug_mroute_cmd
);
8801 install_element(ENABLE_NODE
, &debug_mroute_detail_cmd
);
8802 install_element(ENABLE_NODE
, &no_debug_mroute_cmd
);
8803 install_element(ENABLE_NODE
, &no_debug_mroute_detail_cmd
);
8804 install_element(ENABLE_NODE
, &debug_static_cmd
);
8805 install_element(ENABLE_NODE
, &no_debug_static_cmd
);
8806 install_element(ENABLE_NODE
, &debug_pim_cmd
);
8807 install_element(ENABLE_NODE
, &no_debug_pim_cmd
);
8808 install_element(ENABLE_NODE
, &debug_pim_nht_cmd
);
8809 install_element(ENABLE_NODE
, &no_debug_pim_nht_cmd
);
8810 install_element(ENABLE_NODE
, &debug_pim_nht_rp_cmd
);
8811 install_element(ENABLE_NODE
, &no_debug_pim_nht_rp_cmd
);
8812 install_element(ENABLE_NODE
, &debug_pim_events_cmd
);
8813 install_element(ENABLE_NODE
, &no_debug_pim_events_cmd
);
8814 install_element(ENABLE_NODE
, &debug_pim_packets_cmd
);
8815 install_element(ENABLE_NODE
, &no_debug_pim_packets_cmd
);
8816 install_element(ENABLE_NODE
, &debug_pim_packetdump_send_cmd
);
8817 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_send_cmd
);
8818 install_element(ENABLE_NODE
, &debug_pim_packetdump_recv_cmd
);
8819 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_recv_cmd
);
8820 install_element(ENABLE_NODE
, &debug_pim_trace_cmd
);
8821 install_element(ENABLE_NODE
, &no_debug_pim_trace_cmd
);
8822 install_element(ENABLE_NODE
, &debug_pim_trace_detail_cmd
);
8823 install_element(ENABLE_NODE
, &no_debug_pim_trace_detail_cmd
);
8824 install_element(ENABLE_NODE
, &debug_ssmpingd_cmd
);
8825 install_element(ENABLE_NODE
, &no_debug_ssmpingd_cmd
);
8826 install_element(ENABLE_NODE
, &debug_pim_zebra_cmd
);
8827 install_element(ENABLE_NODE
, &no_debug_pim_zebra_cmd
);
8828 install_element(ENABLE_NODE
, &debug_msdp_cmd
);
8829 install_element(ENABLE_NODE
, &no_debug_msdp_cmd
);
8830 install_element(ENABLE_NODE
, &undebug_msdp_cmd
);
8831 install_element(ENABLE_NODE
, &debug_msdp_events_cmd
);
8832 install_element(ENABLE_NODE
, &no_debug_msdp_events_cmd
);
8833 install_element(ENABLE_NODE
, &undebug_msdp_events_cmd
);
8834 install_element(ENABLE_NODE
, &debug_msdp_packets_cmd
);
8835 install_element(ENABLE_NODE
, &no_debug_msdp_packets_cmd
);
8836 install_element(ENABLE_NODE
, &undebug_msdp_packets_cmd
);
8837 install_element(ENABLE_NODE
, &debug_mtrace_cmd
);
8838 install_element(ENABLE_NODE
, &no_debug_mtrace_cmd
);
8840 install_element(CONFIG_NODE
, &debug_igmp_cmd
);
8841 install_element(CONFIG_NODE
, &no_debug_igmp_cmd
);
8842 install_element(CONFIG_NODE
, &debug_igmp_events_cmd
);
8843 install_element(CONFIG_NODE
, &no_debug_igmp_events_cmd
);
8844 install_element(CONFIG_NODE
, &debug_igmp_packets_cmd
);
8845 install_element(CONFIG_NODE
, &no_debug_igmp_packets_cmd
);
8846 install_element(CONFIG_NODE
, &debug_igmp_trace_cmd
);
8847 install_element(CONFIG_NODE
, &no_debug_igmp_trace_cmd
);
8848 install_element(CONFIG_NODE
, &debug_mroute_cmd
);
8849 install_element(CONFIG_NODE
, &debug_mroute_detail_cmd
);
8850 install_element(CONFIG_NODE
, &no_debug_mroute_cmd
);
8851 install_element(CONFIG_NODE
, &no_debug_mroute_detail_cmd
);
8852 install_element(CONFIG_NODE
, &debug_static_cmd
);
8853 install_element(CONFIG_NODE
, &no_debug_static_cmd
);
8854 install_element(CONFIG_NODE
, &debug_pim_cmd
);
8855 install_element(CONFIG_NODE
, &no_debug_pim_cmd
);
8856 install_element(CONFIG_NODE
, &debug_pim_nht_cmd
);
8857 install_element(CONFIG_NODE
, &no_debug_pim_nht_cmd
);
8858 install_element(CONFIG_NODE
, &debug_pim_nht_rp_cmd
);
8859 install_element(CONFIG_NODE
, &no_debug_pim_nht_rp_cmd
);
8860 install_element(CONFIG_NODE
, &debug_pim_events_cmd
);
8861 install_element(CONFIG_NODE
, &no_debug_pim_events_cmd
);
8862 install_element(CONFIG_NODE
, &debug_pim_packets_cmd
);
8863 install_element(CONFIG_NODE
, &no_debug_pim_packets_cmd
);
8864 install_element(CONFIG_NODE
, &debug_pim_trace_cmd
);
8865 install_element(CONFIG_NODE
, &no_debug_pim_trace_cmd
);
8866 install_element(CONFIG_NODE
, &debug_pim_trace_detail_cmd
);
8867 install_element(CONFIG_NODE
, &no_debug_pim_trace_detail_cmd
);
8868 install_element(CONFIG_NODE
, &debug_ssmpingd_cmd
);
8869 install_element(CONFIG_NODE
, &no_debug_ssmpingd_cmd
);
8870 install_element(CONFIG_NODE
, &debug_pim_zebra_cmd
);
8871 install_element(CONFIG_NODE
, &no_debug_pim_zebra_cmd
);
8872 install_element(CONFIG_NODE
, &debug_msdp_cmd
);
8873 install_element(CONFIG_NODE
, &no_debug_msdp_cmd
);
8874 install_element(CONFIG_NODE
, &undebug_msdp_cmd
);
8875 install_element(CONFIG_NODE
, &debug_msdp_events_cmd
);
8876 install_element(CONFIG_NODE
, &no_debug_msdp_events_cmd
);
8877 install_element(CONFIG_NODE
, &undebug_msdp_events_cmd
);
8878 install_element(CONFIG_NODE
, &debug_msdp_packets_cmd
);
8879 install_element(CONFIG_NODE
, &no_debug_msdp_packets_cmd
);
8880 install_element(CONFIG_NODE
, &undebug_msdp_packets_cmd
);
8881 install_element(CONFIG_NODE
, &debug_mtrace_cmd
);
8882 install_element(CONFIG_NODE
, &no_debug_mtrace_cmd
);
8884 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_member_cmd
);
8885 install_element(VRF_NODE
, &ip_msdp_mesh_group_member_cmd
);
8886 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
8887 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
8888 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_source_cmd
);
8889 install_element(VRF_NODE
, &ip_msdp_mesh_group_source_cmd
);
8890 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
8891 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
8892 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_cmd
);
8893 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_vrf_all_cmd
);
8894 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_cmd
);
8895 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_vrf_all_cmd
);
8896 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_cmd
);
8897 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_vrf_all_cmd
);
8898 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_cmd
);
8899 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_vrf_all_cmd
);
8900 install_element(VIEW_NODE
, &show_ip_pim_ssm_range_cmd
);
8901 install_element(VIEW_NODE
, &show_ip_pim_group_type_cmd
);
8902 install_element(INTERFACE_NODE
, &interface_pim_use_source_cmd
);
8903 install_element(INTERFACE_NODE
, &interface_no_pim_use_source_cmd
);
8904 /* Install BFD command */
8905 install_element(INTERFACE_NODE
, &ip_pim_bfd_cmd
);
8906 install_element(INTERFACE_NODE
, &ip_pim_bfd_param_cmd
);
8907 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_cmd
);
8909 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_param_cmd
);
8910 #endif /* !HAVE_BFDD */