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
, bool 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
, bool 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
, bool 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
, bool 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
, bool 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
, bool 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
, bool uj
)
1938 struct channel_oil
*c_oil
;
1939 struct listnode
*node
;
1940 json_object
*json
= NULL
;
1941 json_object
*json_group
= NULL
;
1942 json_object
*json_ifp_in
= NULL
;
1943 json_object
*json_ifp_out
= NULL
;
1944 json_object
*json_source
= NULL
;
1947 now
= pim_time_monotonic_sec();
1950 json
= json_object_new_object();
1953 "Codes: J -> Pim Join, I -> IGMP Report, S -> Source, * -> Inherited from (*,G)");
1955 "\nInstalled Source Group IIF OIL\n");
1958 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
1959 char grp_str
[INET_ADDRSTRLEN
];
1960 char src_str
[INET_ADDRSTRLEN
];
1961 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
1962 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
1964 struct interface
*ifp_in
;
1967 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
1969 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
1971 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
1974 strcpy(in_ifname
, ifp_in
->name
);
1976 strcpy(in_ifname
, "<iif?>");
1979 if (strcmp(src_or_group
, src_str
)
1980 && strcmp(src_or_group
, grp_str
))
1983 if (group
&& strcmp(group
, grp_str
))
1989 /* Find the group, create it if it doesn't exist */
1990 json_object_object_get_ex(json
, grp_str
, &json_group
);
1993 json_group
= json_object_new_object();
1994 json_object_object_add(json
, grp_str
,
1998 /* Find the source nested under the group, create it if
1999 * it doesn't exist */
2000 json_object_object_get_ex(json_group
, src_str
,
2004 json_source
= json_object_new_object();
2005 json_object_object_add(json_group
, src_str
,
2009 /* Find the inbound interface nested under the source,
2010 * create it if it doesn't exist */
2011 json_object_object_get_ex(json_source
, in_ifname
,
2015 json_ifp_in
= json_object_new_object();
2016 json_object_object_add(json_source
, in_ifname
,
2018 json_object_int_add(json_source
, "Installed",
2020 json_object_int_add(json_source
, "RefCount",
2021 c_oil
->oil_ref_count
);
2022 json_object_int_add(json_source
, "OilListSize",
2024 json_object_int_add(
2025 json_source
, "OilRescan",
2026 c_oil
->oil_inherited_rescan
);
2027 json_object_int_add(json_source
, "LastUsed",
2028 c_oil
->cc
.lastused
);
2029 json_object_int_add(json_source
, "PacketCount",
2031 json_object_int_add(json_source
, "ByteCount",
2033 json_object_int_add(json_source
,
2035 c_oil
->cc
.wrong_if
);
2038 vty_out(vty
, "%-9d %-15s %-15s %-7s ",
2039 c_oil
->installed
, src_str
, grp_str
,
2043 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
2045 struct interface
*ifp_out
;
2046 char oif_uptime
[10];
2049 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
2053 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
2055 oif_uptime
, sizeof(oif_uptime
),
2056 now
- c_oil
->oif_creation
[oif_vif_index
]);
2059 strcpy(out_ifname
, ifp_out
->name
);
2061 strcpy(out_ifname
, "<oif?>");
2064 json_ifp_out
= json_object_new_object();
2065 json_object_string_add(json_ifp_out
, "source",
2067 json_object_string_add(json_ifp_out
, "group",
2069 json_object_string_add(json_ifp_out
,
2072 json_object_string_add(json_ifp_out
,
2073 "outboundInterface",
2075 json_object_int_add(json_ifp_out
, "installed",
2078 json_object_object_add(json_ifp_in
, out_ifname
,
2083 vty_out(vty
, "%s(%c%c%c%c)", out_ifname
,
2084 (c_oil
->oif_flags
[oif_vif_index
]
2085 & PIM_OIF_FLAG_PROTO_IGMP
)
2088 (c_oil
->oif_flags
[oif_vif_index
]
2089 & PIM_OIF_FLAG_PROTO_PIM
)
2092 (c_oil
->oif_flags
[oif_vif_index
]
2093 & PIM_OIF_FLAG_PROTO_SOURCE
)
2096 (c_oil
->oif_flags
[oif_vif_index
]
2097 & PIM_OIF_FLAG_PROTO_STAR
)
2101 vty_out(vty
, ", %s(%c%c%c%c)",
2103 (c_oil
->oif_flags
[oif_vif_index
]
2104 & PIM_OIF_FLAG_PROTO_IGMP
)
2107 (c_oil
->oif_flags
[oif_vif_index
]
2108 & PIM_OIF_FLAG_PROTO_PIM
)
2111 (c_oil
->oif_flags
[oif_vif_index
]
2112 & PIM_OIF_FLAG_PROTO_SOURCE
)
2115 (c_oil
->oif_flags
[oif_vif_index
]
2116 & PIM_OIF_FLAG_PROTO_STAR
)
2128 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2129 json
, JSON_C_TO_STRING_PRETTY
));
2130 json_object_free(json
);
2136 static void pim_show_neighbors(struct pim_instance
*pim
, struct vty
*vty
,
2139 struct listnode
*neighnode
;
2140 struct interface
*ifp
;
2141 struct pim_interface
*pim_ifp
;
2142 struct pim_neighbor
*neigh
;
2146 char neigh_src_str
[INET_ADDRSTRLEN
];
2147 json_object
*json
= NULL
;
2148 json_object
*json_ifp_rows
= NULL
;
2149 json_object
*json_row
= NULL
;
2151 now
= pim_time_monotonic_sec();
2154 json
= json_object_new_object();
2157 "Interface Neighbor Uptime Holdtime DR Pri\n");
2160 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2161 pim_ifp
= ifp
->info
;
2166 if (pim_ifp
->pim_sock_fd
< 0)
2170 json_ifp_rows
= json_object_new_object();
2172 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
2174 pim_inet4_dump("<src?>", neigh
->source_addr
,
2175 neigh_src_str
, sizeof(neigh_src_str
));
2176 pim_time_uptime(uptime
, sizeof(uptime
),
2177 now
- neigh
->creation
);
2178 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
2179 neigh
->t_expire_timer
);
2182 json_row
= json_object_new_object();
2183 json_object_string_add(json_row
, "interface",
2185 json_object_string_add(json_row
, "neighbor",
2187 json_object_string_add(json_row
, "upTime",
2189 json_object_string_add(json_row
, "holdTime",
2191 json_object_int_add(json_row
, "holdTimeMax",
2193 json_object_int_add(json_row
, "drPriority",
2194 neigh
->dr_priority
);
2195 json_object_object_add(json_ifp_rows
,
2196 neigh_src_str
, json_row
);
2199 vty_out(vty
, "%-9s %15s %8s %8s %6d\n",
2200 ifp
->name
, neigh_src_str
, uptime
,
2201 expire
, neigh
->dr_priority
);
2206 json_object_object_add(json
, ifp
->name
, json_ifp_rows
);
2207 json_ifp_rows
= NULL
;
2212 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2213 json
, JSON_C_TO_STRING_PRETTY
));
2214 json_object_free(json
);
2218 static void pim_show_neighbors_secondary(struct pim_instance
*pim
,
2221 struct interface
*ifp
;
2224 "Interface Address Neighbor Secondary \n");
2226 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2227 struct pim_interface
*pim_ifp
;
2228 struct in_addr ifaddr
;
2229 struct listnode
*neighnode
;
2230 struct pim_neighbor
*neigh
;
2232 pim_ifp
= ifp
->info
;
2237 if (pim_ifp
->pim_sock_fd
< 0)
2240 ifaddr
= pim_ifp
->primary_address
;
2242 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
2244 char neigh_src_str
[INET_ADDRSTRLEN
];
2245 struct listnode
*prefix_node
;
2248 if (!neigh
->prefix_list
)
2251 pim_inet4_dump("<src?>", neigh
->source_addr
,
2252 neigh_src_str
, sizeof(neigh_src_str
));
2254 for (ALL_LIST_ELEMENTS_RO(neigh
->prefix_list
,
2256 char neigh_sec_str
[PREFIX2STR_BUFFER
];
2258 prefix2str(p
, neigh_sec_str
,
2259 sizeof(neigh_sec_str
));
2261 vty_out(vty
, "%-9s %-15s %-15s %-15s\n",
2262 ifp
->name
, inet_ntoa(ifaddr
),
2263 neigh_src_str
, neigh_sec_str
);
2269 static void json_object_pim_upstream_add(json_object
*json
,
2270 struct pim_upstream
*up
)
2272 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED
)
2273 json_object_boolean_true_add(json
, "drJoinDesired");
2275 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED
)
2276 json_object_boolean_true_add(json
, "drJoinDesiredUpdated");
2278 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
2279 json_object_boolean_true_add(json
, "firstHopRouter");
2281 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_IGMP
)
2282 json_object_boolean_true_add(json
, "sourceIgmp");
2284 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_PIM
)
2285 json_object_boolean_true_add(json
, "sourcePim");
2287 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_STREAM
)
2288 json_object_boolean_true_add(json
, "sourceStream");
2290 /* XXX: need to print ths flag in the plain text display as well */
2291 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_MSDP
)
2292 json_object_boolean_true_add(json
, "sourceMsdp");
2296 pim_upstream_state2brief_str(enum pim_upstream_state join_state
,
2299 switch (join_state
) {
2300 case PIM_UPSTREAM_NOTJOINED
:
2301 strcpy(state_str
, "NotJ");
2303 case PIM_UPSTREAM_JOINED
:
2304 strcpy(state_str
, "J");
2307 strcpy(state_str
, "Unk");
2312 static const char *pim_reg_state2brief_str(enum pim_reg_state reg_state
,
2315 switch (reg_state
) {
2316 case PIM_REG_NOINFO
:
2317 strcpy(state_str
, "RegNI");
2320 strcpy(state_str
, "RegJ");
2322 case PIM_REG_JOIN_PENDING
:
2324 strcpy(state_str
, "RegP");
2327 strcpy(state_str
, "Unk");
2332 static void pim_show_upstream(struct pim_instance
*pim
, struct vty
*vty
,
2335 struct listnode
*upnode
;
2336 struct pim_upstream
*up
;
2338 json_object
*json
= NULL
;
2339 json_object
*json_group
= NULL
;
2340 json_object
*json_row
= NULL
;
2342 now
= pim_time_monotonic_sec();
2345 json
= json_object_new_object();
2348 "Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt\n");
2350 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
, up
)) {
2351 char src_str
[INET_ADDRSTRLEN
];
2352 char grp_str
[INET_ADDRSTRLEN
];
2354 char join_timer
[10];
2357 char msdp_reg_timer
[10];
2358 char state_str
[PIM_REG_STATE_STR_LEN
];
2360 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2361 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2362 pim_time_uptime(uptime
, sizeof(uptime
),
2363 now
- up
->state_transition
);
2364 pim_time_timer_to_hhmmss(join_timer
, sizeof(join_timer
),
2368 * If we have a J/P timer for the neighbor display that
2370 if (!up
->t_join_timer
) {
2371 struct pim_neighbor
*nbr
;
2373 nbr
= pim_neighbor_find(
2374 up
->rpf
.source_nexthop
.interface
,
2375 up
->rpf
.rpf_addr
.u
.prefix4
);
2377 pim_time_timer_to_hhmmss(join_timer
,
2382 pim_time_timer_to_hhmmss(rs_timer
, sizeof(rs_timer
),
2384 pim_time_timer_to_hhmmss(ka_timer
, sizeof(ka_timer
),
2386 pim_time_timer_to_hhmmss(msdp_reg_timer
, sizeof(msdp_reg_timer
),
2387 up
->t_msdp_reg_timer
);
2389 pim_upstream_state2brief_str(up
->join_state
, state_str
);
2390 if (up
->reg_state
!= PIM_REG_NOINFO
) {
2391 char tmp_str
[PIM_REG_STATE_STR_LEN
];
2393 sprintf(state_str
+ strlen(state_str
), ",%s",
2394 pim_reg_state2brief_str(up
->reg_state
,
2399 json_object_object_get_ex(json
, grp_str
, &json_group
);
2402 json_group
= json_object_new_object();
2403 json_object_object_add(json
, grp_str
,
2407 json_row
= json_object_new_object();
2408 json_object_pim_upstream_add(json_row
, up
);
2409 json_object_string_add(
2410 json_row
, "inboundInterface",
2411 up
->rpf
.source_nexthop
.interface
->name
);
2414 * The RPF address we use is slightly different
2415 * based upon what we are looking up.
2416 * If we have a S, list that unless
2417 * we are the FHR, else we just put
2418 * the RP as the rpfAddress
2420 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
2421 || up
->sg
.src
.s_addr
== INADDR_ANY
) {
2422 char rpf
[PREFIX_STRLEN
];
2423 struct pim_rpf
*rpg
;
2425 rpg
= RP(pim
, up
->sg
.grp
);
2426 pim_inet4_dump("<rpf?>",
2427 rpg
->rpf_addr
.u
.prefix4
, rpf
,
2429 json_object_string_add(json_row
, "rpfAddress",
2432 json_object_string_add(json_row
, "rpfAddress",
2436 json_object_string_add(json_row
, "source", src_str
);
2437 json_object_string_add(json_row
, "group", grp_str
);
2438 json_object_string_add(json_row
, "state", state_str
);
2439 json_object_string_add(
2440 json_row
, "joinState",
2441 pim_upstream_state2str(up
->join_state
));
2442 json_object_string_add(
2443 json_row
, "regState",
2444 pim_reg_state2str(up
->reg_state
, state_str
));
2445 json_object_string_add(json_row
, "upTime", uptime
);
2446 json_object_string_add(json_row
, "joinTimer",
2448 json_object_string_add(json_row
, "resetTimer",
2450 json_object_string_add(json_row
, "keepaliveTimer",
2452 json_object_string_add(json_row
, "msdpRegTimer",
2454 json_object_int_add(json_row
, "refCount",
2456 json_object_int_add(json_row
, "sptBit", up
->sptbit
);
2457 json_object_object_add(json_group
, src_str
, json_row
);
2460 "%-10s%-15s %-15s %-11s %-8s %-9s %-9s %-9s %6d\n",
2461 up
->rpf
.source_nexthop
.interface
->name
, src_str
,
2462 grp_str
, state_str
, uptime
, join_timer
,
2463 rs_timer
, ka_timer
, up
->ref_count
);
2468 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2469 json
, JSON_C_TO_STRING_PRETTY
));
2470 json_object_free(json
);
2474 static void pim_show_join_desired_helper(struct pim_instance
*pim
,
2476 struct pim_interface
*pim_ifp
,
2477 struct pim_ifchannel
*ch
,
2478 json_object
*json
, bool uj
)
2480 struct pim_upstream
*up
= ch
->upstream
;
2481 json_object
*json_group
= NULL
;
2482 char src_str
[INET_ADDRSTRLEN
];
2483 char grp_str
[INET_ADDRSTRLEN
];
2484 json_object
*json_row
= NULL
;
2486 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2487 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2490 json_object_object_get_ex(json
, grp_str
, &json_group
);
2493 json_group
= json_object_new_object();
2494 json_object_object_add(json
, grp_str
, json_group
);
2497 json_row
= json_object_new_object();
2498 json_object_pim_upstream_add(json_row
, up
);
2499 json_object_string_add(json_row
, "interface",
2500 ch
->interface
->name
);
2501 json_object_string_add(json_row
, "source", src_str
);
2502 json_object_string_add(json_row
, "group", grp_str
);
2504 if (pim_macro_ch_lost_assert(ch
))
2505 json_object_boolean_true_add(json_row
, "lostAssert");
2507 if (pim_macro_chisin_joins(ch
))
2508 json_object_boolean_true_add(json_row
, "joins");
2510 if (pim_macro_chisin_pim_include(ch
))
2511 json_object_boolean_true_add(json_row
, "pimInclude");
2513 if (pim_upstream_evaluate_join_desired(pim
, up
))
2514 json_object_boolean_true_add(json_row
,
2515 "evaluateJoinDesired");
2517 json_object_object_add(json_group
, src_str
, json_row
);
2520 vty_out(vty
, "%-9s %-15s %-15s %-10s %-5s %-10s %-11s %-6s\n",
2521 ch
->interface
->name
, src_str
, grp_str
,
2522 pim_macro_ch_lost_assert(ch
) ? "yes" : "no",
2523 pim_macro_chisin_joins(ch
) ? "yes" : "no",
2524 pim_macro_chisin_pim_include(ch
) ? "yes" : "no",
2525 PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(up
->flags
)
2528 pim_upstream_evaluate_join_desired(pim
, up
) ? "yes"
2533 static void pim_show_join_desired(struct pim_instance
*pim
, struct vty
*vty
,
2536 struct pim_interface
*pim_ifp
;
2537 struct pim_ifchannel
*ch
;
2538 struct interface
*ifp
;
2540 json_object
*json
= NULL
;
2543 json
= json_object_new_object();
2546 "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD\n");
2548 /* scan per-interface (S,G) state */
2549 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2550 pim_ifp
= ifp
->info
;
2555 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
2556 /* scan all interfaces */
2557 pim_show_join_desired_helper(pim
, vty
, pim_ifp
, ch
,
2563 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2564 json
, JSON_C_TO_STRING_PRETTY
));
2565 json_object_free(json
);
2569 static void pim_show_upstream_rpf(struct pim_instance
*pim
, struct vty
*vty
,
2572 struct listnode
*upnode
;
2573 struct pim_upstream
*up
;
2574 json_object
*json
= NULL
;
2575 json_object
*json_group
= NULL
;
2576 json_object
*json_row
= NULL
;
2579 json
= json_object_new_object();
2582 "Source Group RpfIface RibNextHop RpfAddress \n");
2584 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
, up
)) {
2585 char src_str
[INET_ADDRSTRLEN
];
2586 char grp_str
[INET_ADDRSTRLEN
];
2587 char rpf_nexthop_str
[PREFIX_STRLEN
];
2588 char rpf_addr_str
[PREFIX_STRLEN
];
2589 struct pim_rpf
*rpf
;
2590 const char *rpf_ifname
;
2594 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2595 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2596 pim_addr_dump("<nexthop?>",
2597 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2598 rpf_nexthop_str
, sizeof(rpf_nexthop_str
));
2599 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2600 sizeof(rpf_addr_str
));
2602 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2605 json_object_object_get_ex(json
, grp_str
, &json_group
);
2608 json_group
= json_object_new_object();
2609 json_object_object_add(json
, grp_str
,
2613 json_row
= json_object_new_object();
2614 json_object_pim_upstream_add(json_row
, up
);
2615 json_object_string_add(json_row
, "source", src_str
);
2616 json_object_string_add(json_row
, "group", grp_str
);
2617 json_object_string_add(json_row
, "rpfInterface",
2619 json_object_string_add(json_row
, "ribNexthop",
2621 json_object_string_add(json_row
, "rpfAddress",
2623 json_object_object_add(json_group
, src_str
, json_row
);
2625 vty_out(vty
, "%-15s %-15s %-8s %-15s %-15s\n", src_str
,
2626 grp_str
, rpf_ifname
, rpf_nexthop_str
,
2632 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2633 json
, JSON_C_TO_STRING_PRETTY
));
2634 json_object_free(json
);
2638 static void show_rpf_refresh_stats(struct vty
*vty
, struct pim_instance
*pim
,
2639 time_t now
, json_object
*json
)
2641 char refresh_uptime
[10];
2643 pim_time_uptime_begin(refresh_uptime
, sizeof(refresh_uptime
), now
,
2644 pim
->rpf_cache_refresh_last
);
2647 json_object_int_add(json
, "rpfCacheRefreshDelayMsecs",
2648 qpim_rpf_cache_refresh_delay_msec
);
2649 json_object_int_add(
2650 json
, "rpfCacheRefreshTimer",
2651 pim_time_timer_remain_msec(pim
->rpf_cache_refresher
));
2652 json_object_int_add(json
, "rpfCacheRefreshRequests",
2653 pim
->rpf_cache_refresh_requests
);
2654 json_object_int_add(json
, "rpfCacheRefreshEvents",
2655 pim
->rpf_cache_refresh_events
);
2656 json_object_string_add(json
, "rpfCacheRefreshLast",
2658 json_object_int_add(json
, "nexthopLookups",
2659 pim
->nexthop_lookups
);
2660 json_object_int_add(json
, "nexthopLookupsAvoided",
2661 pim
->nexthop_lookups_avoided
);
2664 "RPF Cache Refresh Delay: %ld msecs\n"
2665 "RPF Cache Refresh Timer: %ld msecs\n"
2666 "RPF Cache Refresh Requests: %lld\n"
2667 "RPF Cache Refresh Events: %lld\n"
2668 "RPF Cache Refresh Last: %s\n"
2669 "Nexthop Lookups: %lld\n"
2670 "Nexthop Lookups Avoided: %lld\n",
2671 qpim_rpf_cache_refresh_delay_msec
,
2672 pim_time_timer_remain_msec(pim
->rpf_cache_refresher
),
2673 (long long)pim
->rpf_cache_refresh_requests
,
2674 (long long)pim
->rpf_cache_refresh_events
,
2675 refresh_uptime
, (long long)pim
->nexthop_lookups
,
2676 (long long)pim
->nexthop_lookups_avoided
);
2680 static void show_scan_oil_stats(struct pim_instance
*pim
, struct vty
*vty
,
2683 char uptime_scan_oil
[10];
2684 char uptime_mroute_add
[10];
2685 char uptime_mroute_del
[10];
2687 pim_time_uptime_begin(uptime_scan_oil
, sizeof(uptime_scan_oil
), now
,
2688 pim
->scan_oil_last
);
2689 pim_time_uptime_begin(uptime_mroute_add
, sizeof(uptime_mroute_add
), now
,
2690 pim
->mroute_add_last
);
2691 pim_time_uptime_begin(uptime_mroute_del
, sizeof(uptime_mroute_del
), now
,
2692 pim
->mroute_del_last
);
2695 "Scan OIL - Last: %s Events: %lld\n"
2696 "MFC Add - Last: %s Events: %lld\n"
2697 "MFC Del - Last: %s Events: %lld\n",
2698 uptime_scan_oil
, (long long)pim
->scan_oil_events
,
2699 uptime_mroute_add
, (long long)pim
->mroute_add_events
,
2700 uptime_mroute_del
, (long long)pim
->mroute_del_events
);
2703 static void pim_show_rpf(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
2705 struct listnode
*up_node
;
2706 struct pim_upstream
*up
;
2707 time_t now
= pim_time_monotonic_sec();
2708 json_object
*json
= NULL
;
2709 json_object
*json_group
= NULL
;
2710 json_object
*json_row
= NULL
;
2713 json
= json_object_new_object();
2714 show_rpf_refresh_stats(vty
, pim
, now
, json
);
2716 show_rpf_refresh_stats(vty
, pim
, now
, json
);
2719 "Source Group RpfIface RpfAddress RibNextHop Metric Pref\n");
2722 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, up_node
, up
)) {
2723 char src_str
[INET_ADDRSTRLEN
];
2724 char grp_str
[INET_ADDRSTRLEN
];
2725 char rpf_addr_str
[PREFIX_STRLEN
];
2726 char rib_nexthop_str
[PREFIX_STRLEN
];
2727 const char *rpf_ifname
;
2728 struct pim_rpf
*rpf
= &up
->rpf
;
2730 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2731 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2732 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2733 sizeof(rpf_addr_str
));
2734 pim_addr_dump("<nexthop?>",
2735 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2736 rib_nexthop_str
, sizeof(rib_nexthop_str
));
2738 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2741 json_object_object_get_ex(json
, grp_str
, &json_group
);
2744 json_group
= json_object_new_object();
2745 json_object_object_add(json
, grp_str
,
2749 json_row
= json_object_new_object();
2750 json_object_string_add(json_row
, "source", src_str
);
2751 json_object_string_add(json_row
, "group", grp_str
);
2752 json_object_string_add(json_row
, "rpfInterface",
2754 json_object_string_add(json_row
, "rpfAddress",
2756 json_object_string_add(json_row
, "ribNexthop",
2758 json_object_int_add(
2759 json_row
, "routeMetric",
2760 rpf
->source_nexthop
.mrib_route_metric
);
2761 json_object_int_add(
2762 json_row
, "routePreference",
2763 rpf
->source_nexthop
.mrib_metric_preference
);
2764 json_object_object_add(json_group
, src_str
, json_row
);
2767 vty_out(vty
, "%-15s %-15s %-8s %-15s %-15s %6d %4d\n",
2768 src_str
, grp_str
, rpf_ifname
, rpf_addr_str
,
2770 rpf
->source_nexthop
.mrib_route_metric
,
2771 rpf
->source_nexthop
.mrib_metric_preference
);
2776 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2777 json
, JSON_C_TO_STRING_PRETTY
));
2778 json_object_free(json
);
2782 struct pnc_cache_walk_data
{
2784 struct pim_instance
*pim
;
2787 static int pim_print_pnc_cache_walkcb(struct hash_backet
*backet
, void *arg
)
2789 struct pim_nexthop_cache
*pnc
= backet
->data
;
2790 struct pnc_cache_walk_data
*cwd
= arg
;
2791 struct vty
*vty
= cwd
->vty
;
2792 struct pim_instance
*pim
= cwd
->pim
;
2793 struct nexthop
*nh_node
= NULL
;
2794 ifindex_t first_ifindex
;
2795 struct interface
*ifp
= NULL
;
2797 for (nh_node
= pnc
->nexthop
; nh_node
; nh_node
= nh_node
->next
) {
2798 first_ifindex
= nh_node
->ifindex
;
2799 ifp
= if_lookup_by_index(first_ifindex
, pim
->vrf_id
);
2801 vty_out(vty
, "%-15s ", inet_ntoa(pnc
->rpf
.rpf_addr
.u
.prefix4
));
2802 vty_out(vty
, "%-14s ", ifp
? ifp
->name
: "NULL");
2803 vty_out(vty
, "%s ", inet_ntoa(nh_node
->gate
.ipv4
));
2809 static void pim_show_nexthop(struct pim_instance
*pim
, struct vty
*vty
)
2811 struct pnc_cache_walk_data cwd
;
2815 vty_out(vty
, "Number of registered addresses: %lu\n",
2816 pim
->rpf_hash
->count
);
2817 vty_out(vty
, "Address Interface Nexthop\n");
2818 vty_out(vty
, "-------------------------------------------\n");
2820 hash_walk(pim
->rpf_hash
, pim_print_pnc_cache_walkcb
, &cwd
);
2823 static void igmp_show_groups(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
2825 struct interface
*ifp
;
2827 json_object
*json
= NULL
;
2828 json_object
*json_iface
= NULL
;
2829 json_object
*json_row
= NULL
;
2831 now
= pim_time_monotonic_sec();
2834 json
= json_object_new_object();
2837 "Interface Address Group Mode Timer Srcs V Uptime \n");
2839 /* scan interfaces */
2840 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2841 struct pim_interface
*pim_ifp
= ifp
->info
;
2842 struct listnode
*sock_node
;
2843 struct igmp_sock
*igmp
;
2848 /* scan igmp sockets */
2849 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
2851 char ifaddr_str
[INET_ADDRSTRLEN
];
2852 struct listnode
*grpnode
;
2853 struct igmp_group
*grp
;
2855 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
2856 sizeof(ifaddr_str
));
2858 /* scan igmp groups */
2859 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
2861 char group_str
[INET_ADDRSTRLEN
];
2865 pim_inet4_dump("<group?>", grp
->group_addr
,
2866 group_str
, sizeof(group_str
));
2867 pim_time_timer_to_hhmmss(hhmmss
, sizeof(hhmmss
),
2868 grp
->t_group_timer
);
2869 pim_time_uptime(uptime
, sizeof(uptime
),
2870 now
- grp
->group_creation
);
2873 json_object_object_get_ex(
2874 json
, ifp
->name
, &json_iface
);
2878 json_object_new_object();
2879 json_object_pim_ifp_add(
2881 json_object_object_add(
2886 json_row
= json_object_new_object();
2887 json_object_string_add(
2888 json_row
, "source", ifaddr_str
);
2889 json_object_string_add(
2890 json_row
, "group", group_str
);
2892 if (grp
->igmp_version
== 3)
2893 json_object_string_add(
2895 grp
->group_filtermode_isexcl
2899 json_object_string_add(json_row
,
2901 json_object_int_add(
2902 json_row
, "sourcesCount",
2903 grp
->group_source_list
2905 grp
->group_source_list
)
2907 json_object_int_add(json_row
, "version",
2909 json_object_string_add(
2910 json_row
, "uptime", uptime
);
2911 json_object_object_add(json_iface
,
2917 "%-9s %-15s %-15s %4s %8s %4d %d %8s\n",
2918 ifp
->name
, ifaddr_str
,
2920 grp
->igmp_version
== 3
2921 ? (grp
->group_filtermode_isexcl
2926 grp
->group_source_list
2928 grp
->group_source_list
)
2930 grp
->igmp_version
, uptime
);
2932 } /* scan igmp groups */
2933 } /* scan igmp sockets */
2934 } /* scan interfaces */
2937 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2938 json
, JSON_C_TO_STRING_PRETTY
));
2939 json_object_free(json
);
2943 static void igmp_show_group_retransmission(struct pim_instance
*pim
,
2946 struct interface
*ifp
;
2949 "Interface Address Group RetTimer Counter RetSrcs\n");
2951 /* scan interfaces */
2952 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2953 struct pim_interface
*pim_ifp
= ifp
->info
;
2954 struct listnode
*sock_node
;
2955 struct igmp_sock
*igmp
;
2960 /* scan igmp sockets */
2961 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
2963 char ifaddr_str
[INET_ADDRSTRLEN
];
2964 struct listnode
*grpnode
;
2965 struct igmp_group
*grp
;
2967 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
2968 sizeof(ifaddr_str
));
2970 /* scan igmp groups */
2971 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
2973 char group_str
[INET_ADDRSTRLEN
];
2974 char grp_retr_mmss
[10];
2975 struct listnode
*src_node
;
2976 struct igmp_source
*src
;
2977 int grp_retr_sources
= 0;
2979 pim_inet4_dump("<group?>", grp
->group_addr
,
2980 group_str
, sizeof(group_str
));
2981 pim_time_timer_to_mmss(
2982 grp_retr_mmss
, sizeof(grp_retr_mmss
),
2983 grp
->t_group_query_retransmit_timer
);
2986 /* count group sources with retransmission state
2988 for (ALL_LIST_ELEMENTS_RO(
2989 grp
->group_source_list
, src_node
,
2991 if (src
->source_query_retransmit_count
2997 vty_out(vty
, "%-9s %-15s %-15s %-8s %7d %7d\n",
2998 ifp
->name
, ifaddr_str
, group_str
,
3000 grp
->group_specific_query_retransmit_count
,
3003 } /* scan igmp groups */
3004 } /* scan igmp sockets */
3005 } /* scan interfaces */
3008 static void igmp_show_sources(struct pim_instance
*pim
, struct vty
*vty
)
3010 struct interface
*ifp
;
3013 now
= pim_time_monotonic_sec();
3016 "Interface Address Group Source Timer Fwd Uptime \n");
3018 /* scan interfaces */
3019 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3020 struct pim_interface
*pim_ifp
= ifp
->info
;
3021 struct listnode
*sock_node
;
3022 struct igmp_sock
*igmp
;
3027 /* scan igmp sockets */
3028 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3030 char ifaddr_str
[INET_ADDRSTRLEN
];
3031 struct listnode
*grpnode
;
3032 struct igmp_group
*grp
;
3034 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3035 sizeof(ifaddr_str
));
3037 /* scan igmp groups */
3038 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3040 char group_str
[INET_ADDRSTRLEN
];
3041 struct listnode
*srcnode
;
3042 struct igmp_source
*src
;
3044 pim_inet4_dump("<group?>", grp
->group_addr
,
3045 group_str
, sizeof(group_str
));
3047 /* scan group sources */
3048 for (ALL_LIST_ELEMENTS_RO(
3049 grp
->group_source_list
, srcnode
,
3051 char source_str
[INET_ADDRSTRLEN
];
3056 "<source?>", src
->source_addr
,
3057 source_str
, sizeof(source_str
));
3059 pim_time_timer_to_mmss(
3061 src
->t_source_timer
);
3064 uptime
, sizeof(uptime
),
3065 now
- src
->source_creation
);
3068 "%-9s %-15s %-15s %-15s %5s %3s %8s\n",
3069 ifp
->name
, ifaddr_str
,
3070 group_str
, source_str
, mmss
,
3071 IGMP_SOURCE_TEST_FORWARDING(
3077 } /* scan group sources */
3078 } /* scan igmp groups */
3079 } /* scan igmp sockets */
3080 } /* scan interfaces */
3083 static void igmp_show_source_retransmission(struct pim_instance
*pim
,
3086 struct interface
*ifp
;
3089 "Interface Address Group Source Counter\n");
3091 /* scan interfaces */
3092 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3093 struct pim_interface
*pim_ifp
= ifp
->info
;
3094 struct listnode
*sock_node
;
3095 struct igmp_sock
*igmp
;
3100 /* scan igmp sockets */
3101 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3103 char ifaddr_str
[INET_ADDRSTRLEN
];
3104 struct listnode
*grpnode
;
3105 struct igmp_group
*grp
;
3107 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3108 sizeof(ifaddr_str
));
3110 /* scan igmp groups */
3111 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3113 char group_str
[INET_ADDRSTRLEN
];
3114 struct listnode
*srcnode
;
3115 struct igmp_source
*src
;
3117 pim_inet4_dump("<group?>", grp
->group_addr
,
3118 group_str
, sizeof(group_str
));
3120 /* scan group sources */
3121 for (ALL_LIST_ELEMENTS_RO(
3122 grp
->group_source_list
, srcnode
,
3124 char source_str
[INET_ADDRSTRLEN
];
3127 "<source?>", src
->source_addr
,
3128 source_str
, sizeof(source_str
));
3131 "%-9s %-15s %-15s %-15s %7d\n",
3132 ifp
->name
, ifaddr_str
,
3133 group_str
, source_str
,
3134 src
->source_query_retransmit_count
);
3136 } /* scan group sources */
3137 } /* scan igmp groups */
3138 } /* scan igmp sockets */
3139 } /* scan interfaces */
3142 static void clear_igmp_interfaces(struct pim_instance
*pim
)
3144 struct interface
*ifp
;
3146 FOR_ALL_INTERFACES (pim
->vrf
, ifp
)
3147 pim_if_addr_del_all_igmp(ifp
);
3149 FOR_ALL_INTERFACES (pim
->vrf
, ifp
)
3150 pim_if_addr_add_all(ifp
);
3153 static void clear_pim_interfaces(struct pim_instance
*pim
)
3155 struct interface
*ifp
;
3157 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3159 pim_neighbor_delete_all(ifp
, "interface cleared");
3164 static void clear_interfaces(struct pim_instance
*pim
)
3166 clear_igmp_interfaces(pim
);
3167 clear_pim_interfaces(pim
);
3170 #define PIM_GET_PIM_INTERFACE(pim_ifp, ifp) \
3171 pim_ifp = ifp->info; \
3174 "%% Enable PIM and/or IGMP on this interface first\n"); \
3175 return CMD_WARNING_CONFIG_FAILED; \
3178 DEFUN (clear_ip_interfaces
,
3179 clear_ip_interfaces_cmd
,
3180 "clear ip interfaces [vrf NAME]",
3183 "Reset interfaces\n"
3187 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3192 clear_interfaces(vrf
->info
);
3197 DEFUN (clear_ip_igmp_interfaces
,
3198 clear_ip_igmp_interfaces_cmd
,
3199 "clear ip igmp [vrf NAME] interfaces",
3204 "Reset IGMP interfaces\n")
3207 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3212 clear_igmp_interfaces(vrf
->info
);
3217 static void mroute_add_all(struct pim_instance
*pim
)
3219 struct listnode
*node
;
3220 struct channel_oil
*c_oil
;
3222 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
3223 if (pim_mroute_add(c_oil
, __PRETTY_FUNCTION__
)) {
3224 /* just log warning */
3225 char source_str
[INET_ADDRSTRLEN
];
3226 char group_str
[INET_ADDRSTRLEN
];
3227 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
,
3228 source_str
, sizeof(source_str
));
3229 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
,
3230 group_str
, sizeof(group_str
));
3231 zlog_warn("%s %s: (S,G)=(%s,%s) failure writing MFC",
3232 __FILE__
, __PRETTY_FUNCTION__
, source_str
,
3238 static void mroute_del_all(struct pim_instance
*pim
)
3240 struct listnode
*node
;
3241 struct channel_oil
*c_oil
;
3243 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
3244 if (pim_mroute_del(c_oil
, __PRETTY_FUNCTION__
)) {
3245 /* just log warning */
3246 char source_str
[INET_ADDRSTRLEN
];
3247 char group_str
[INET_ADDRSTRLEN
];
3248 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
,
3249 source_str
, sizeof(source_str
));
3250 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
,
3251 group_str
, sizeof(group_str
));
3252 zlog_warn("%s %s: (S,G)=(%s,%s) failure clearing MFC",
3253 __FILE__
, __PRETTY_FUNCTION__
, source_str
,
3259 DEFUN (clear_ip_mroute
,
3260 clear_ip_mroute_cmd
,
3261 "clear ip mroute [vrf NAME]",
3264 "Reset multicast routes\n"
3268 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3273 mroute_del_all(vrf
->info
);
3274 mroute_add_all(vrf
->info
);
3279 DEFUN (clear_ip_pim_interfaces
,
3280 clear_ip_pim_interfaces_cmd
,
3281 "clear ip pim [vrf NAME] interfaces",
3286 "Reset PIM interfaces\n")
3289 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3294 clear_pim_interfaces(vrf
->info
);
3299 DEFUN (clear_ip_pim_interface_traffic
,
3300 clear_ip_pim_interface_traffic_cmd
,
3301 "clear ip pim [vrf NAME] interface traffic",
3304 "PIM clear commands\n"
3306 "Reset PIM interfaces\n"
3307 "Reset Protocol Packet counters\n")
3310 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3311 struct interface
*ifp
= NULL
;
3312 struct pim_interface
*pim_ifp
= NULL
;
3317 FOR_ALL_INTERFACES (vrf
, ifp
) {
3318 pim_ifp
= ifp
->info
;
3323 pim_ifp
->pim_ifstat_hello_recv
= 0;
3324 pim_ifp
->pim_ifstat_hello_sent
= 0;
3325 pim_ifp
->pim_ifstat_join_recv
= 0;
3326 pim_ifp
->pim_ifstat_join_send
= 0;
3327 pim_ifp
->pim_ifstat_prune_recv
= 0;
3328 pim_ifp
->pim_ifstat_prune_send
= 0;
3329 pim_ifp
->pim_ifstat_reg_recv
= 0;
3330 pim_ifp
->pim_ifstat_reg_send
= 0;
3331 pim_ifp
->pim_ifstat_reg_stop_recv
= 0;
3332 pim_ifp
->pim_ifstat_reg_stop_send
= 0;
3333 pim_ifp
->pim_ifstat_assert_recv
= 0;
3334 pim_ifp
->pim_ifstat_assert_send
= 0;
3340 DEFUN (clear_ip_pim_oil
,
3341 clear_ip_pim_oil_cmd
,
3342 "clear ip pim [vrf NAME] oil",
3347 "Rescan PIM OIL (output interface list)\n")
3350 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3355 pim_scan_oil(vrf
->info
);
3360 DEFUN (show_ip_igmp_interface
,
3361 show_ip_igmp_interface_cmd
,
3362 "show ip igmp [vrf NAME] interface [detail|WORD] [json]",
3367 "IGMP interface information\n"
3373 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3374 bool uj
= use_json(argc
, argv
);
3379 if (argv_find(argv
, argc
, "detail", &idx
)
3380 || argv_find(argv
, argc
, "WORD", &idx
))
3381 igmp_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
3383 igmp_show_interfaces(vrf
->info
, vty
, uj
);
3388 DEFUN (show_ip_igmp_interface_vrf_all
,
3389 show_ip_igmp_interface_vrf_all_cmd
,
3390 "show ip igmp vrf all interface [detail|WORD] [json]",
3395 "IGMP interface information\n"
3401 bool uj
= use_json(argc
, argv
);
3407 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3411 vty_out(vty
, " \"%s\": ", vrf
->name
);
3414 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3415 if (argv_find(argv
, argc
, "detail", &idx
)
3416 || argv_find(argv
, argc
, "WORD", &idx
))
3417 igmp_show_interfaces_single(vrf
->info
, vty
,
3418 argv
[idx
]->arg
, uj
);
3420 igmp_show_interfaces(vrf
->info
, vty
, uj
);
3423 vty_out(vty
, "}\n");
3428 DEFUN (show_ip_igmp_join
,
3429 show_ip_igmp_join_cmd
,
3430 "show ip igmp [vrf NAME] join",
3435 "IGMP static join information\n")
3438 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3443 igmp_show_interface_join(vrf
->info
, vty
);
3448 DEFUN (show_ip_igmp_join_vrf_all
,
3449 show_ip_igmp_join_vrf_all_cmd
,
3450 "show ip igmp vrf all join",
3455 "IGMP static join information\n")
3457 bool uj
= use_json(argc
, argv
);
3463 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3467 vty_out(vty
, " \"%s\": ", vrf
->name
);
3470 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3471 igmp_show_interface_join(vrf
->info
, vty
);
3474 vty_out(vty
, "}\n");
3479 DEFUN (show_ip_igmp_groups
,
3480 show_ip_igmp_groups_cmd
,
3481 "show ip igmp [vrf NAME] groups [json]",
3490 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3491 bool uj
= use_json(argc
, argv
);
3496 igmp_show_groups(vrf
->info
, vty
, uj
);
3501 DEFUN (show_ip_igmp_groups_vrf_all
,
3502 show_ip_igmp_groups_vrf_all_cmd
,
3503 "show ip igmp vrf all groups [json]",
3511 bool uj
= use_json(argc
, argv
);
3517 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3521 vty_out(vty
, " \"%s\": ", vrf
->name
);
3524 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3525 igmp_show_groups(vrf
->info
, vty
, uj
);
3528 vty_out(vty
, "}\n");
3533 DEFUN (show_ip_igmp_groups_retransmissions
,
3534 show_ip_igmp_groups_retransmissions_cmd
,
3535 "show ip igmp [vrf NAME] groups retransmissions",
3541 "IGMP group retransmissions\n")
3544 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3549 igmp_show_group_retransmission(vrf
->info
, vty
);
3554 DEFUN (show_ip_igmp_sources
,
3555 show_ip_igmp_sources_cmd
,
3556 "show ip igmp [vrf NAME] sources",
3564 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3569 igmp_show_sources(vrf
->info
, vty
);
3574 DEFUN (show_ip_igmp_sources_retransmissions
,
3575 show_ip_igmp_sources_retransmissions_cmd
,
3576 "show ip igmp [vrf NAME] sources retransmissions",
3582 "IGMP source retransmissions\n")
3585 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3590 igmp_show_source_retransmission(vrf
->info
, vty
);
3595 DEFUN (show_ip_igmp_statistics
,
3596 show_ip_igmp_statistics_cmd
,
3597 "show ip igmp [vrf NAME] statistics [interface WORD] [json]",
3608 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3609 bool uj
= use_json(argc
, argv
);
3614 if (argv_find(argv
, argc
, "WORD", &idx
))
3615 igmp_show_statistics(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
3617 igmp_show_statistics(vrf
->info
, vty
, NULL
, uj
);
3622 DEFUN (show_ip_pim_assert
,
3623 show_ip_pim_assert_cmd
,
3624 "show ip pim [vrf NAME] assert",
3629 "PIM interface assert\n")
3632 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3637 pim_show_assert(vrf
->info
, vty
);
3642 DEFUN (show_ip_pim_assert_internal
,
3643 show_ip_pim_assert_internal_cmd
,
3644 "show ip pim [vrf NAME] assert-internal",
3649 "PIM interface internal assert state\n")
3652 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3657 pim_show_assert_internal(vrf
->info
, vty
);
3662 DEFUN (show_ip_pim_assert_metric
,
3663 show_ip_pim_assert_metric_cmd
,
3664 "show ip pim [vrf NAME] assert-metric",
3669 "PIM interface assert metric\n")
3672 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3677 pim_show_assert_metric(vrf
->info
, vty
);
3682 DEFUN (show_ip_pim_assert_winner_metric
,
3683 show_ip_pim_assert_winner_metric_cmd
,
3684 "show ip pim [vrf NAME] assert-winner-metric",
3689 "PIM interface assert winner metric\n")
3692 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3697 pim_show_assert_winner_metric(vrf
->info
, vty
);
3702 DEFUN (show_ip_pim_interface
,
3703 show_ip_pim_interface_cmd
,
3704 "show ip pim [vrf NAME] interface [detail|WORD] [json]",
3709 "PIM interface information\n"
3715 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3716 bool uj
= use_json(argc
, argv
);
3721 if (argv_find(argv
, argc
, "WORD", &idx
)
3722 || argv_find(argv
, argc
, "detail", &idx
))
3723 pim_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
3725 pim_show_interfaces(vrf
->info
, vty
, uj
);
3730 DEFUN (show_ip_pim_interface_vrf_all
,
3731 show_ip_pim_interface_vrf_all_cmd
,
3732 "show ip pim vrf all interface [detail|WORD] [json]",
3737 "PIM interface information\n"
3743 bool uj
= use_json(argc
, argv
);
3749 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3753 vty_out(vty
, " \"%s\": ", vrf
->name
);
3756 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3757 if (argv_find(argv
, argc
, "WORD", &idx
)
3758 || argv_find(argv
, argc
, "detail", &idx
))
3759 pim_show_interfaces_single(vrf
->info
, vty
,
3760 argv
[idx
]->arg
, uj
);
3762 pim_show_interfaces(vrf
->info
, vty
, uj
);
3765 vty_out(vty
, "}\n");
3770 DEFUN (show_ip_pim_join
,
3771 show_ip_pim_join_cmd
,
3772 "show ip pim [vrf NAME] join [json]",
3777 "PIM interface join information\n"
3781 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3782 bool uj
= use_json(argc
, argv
);
3787 pim_show_join(vrf
->info
, vty
, uj
);
3792 DEFUN (show_ip_pim_join_vrf_all
,
3793 show_ip_pim_join_vrf_all_cmd
,
3794 "show ip pim vrf all join [json]",
3799 "PIM interface join information\n"
3802 bool uj
= use_json(argc
, argv
);
3808 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3812 vty_out(vty
, " \"%s\": ", vrf
->name
);
3815 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3816 pim_show_join(vrf
->info
, vty
, uj
);
3819 vty_out(vty
, "}\n");
3824 DEFUN (show_ip_pim_local_membership
,
3825 show_ip_pim_local_membership_cmd
,
3826 "show ip pim [vrf NAME] local-membership [json]",
3831 "PIM interface local-membership\n"
3835 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3836 bool uj
= use_json(argc
, argv
);
3841 pim_show_membership(vrf
->info
, vty
, uj
);
3846 DEFUN (show_ip_pim_neighbor
,
3847 show_ip_pim_neighbor_cmd
,
3848 "show ip pim [vrf NAME] neighbor [detail|WORD] [json]",
3853 "PIM neighbor information\n"
3855 "Name of interface or neighbor\n"
3859 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3860 bool uj
= use_json(argc
, argv
);
3865 if (argv_find(argv
, argc
, "detail", &idx
)
3866 || argv_find(argv
, argc
, "WORD", &idx
))
3867 pim_show_neighbors_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
3869 pim_show_neighbors(vrf
->info
, vty
, uj
);
3874 DEFUN (show_ip_pim_neighbor_vrf_all
,
3875 show_ip_pim_neighbor_vrf_all_cmd
,
3876 "show ip pim vrf all neighbor [detail|WORD] [json]",
3881 "PIM neighbor information\n"
3883 "Name of interface or neighbor\n"
3887 bool uj
= use_json(argc
, argv
);
3893 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3897 vty_out(vty
, " \"%s\": ", vrf
->name
);
3900 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3901 if (argv_find(argv
, argc
, "detail", &idx
)
3902 || argv_find(argv
, argc
, "WORD", &idx
))
3903 pim_show_neighbors_single(vrf
->info
, vty
,
3904 argv
[idx
]->arg
, uj
);
3906 pim_show_neighbors(vrf
->info
, vty
, uj
);
3909 vty_out(vty
, "}\n");
3914 DEFUN (show_ip_pim_secondary
,
3915 show_ip_pim_secondary_cmd
,
3916 "show ip pim [vrf NAME] secondary",
3921 "PIM neighbor addresses\n")
3924 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3929 pim_show_neighbors_secondary(vrf
->info
, vty
);
3934 DEFUN (show_ip_pim_state
,
3935 show_ip_pim_state_cmd
,
3936 "show ip pim [vrf NAME] state [A.B.C.D [A.B.C.D]] [json]",
3941 "PIM state information\n"
3942 "Unicast or Multicast address\n"
3943 "Multicast address\n"
3946 const char *src_or_group
= NULL
;
3947 const char *group
= NULL
;
3949 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3950 bool uj
= use_json(argc
, argv
);
3958 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
3959 src_or_group
= argv
[idx
]->arg
;
3961 group
= argv
[idx
+ 1]->arg
;
3964 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
3969 DEFUN (show_ip_pim_state_vrf_all
,
3970 show_ip_pim_state_vrf_all_cmd
,
3971 "show ip pim vrf all state [A.B.C.D [A.B.C.D]] [json]",
3976 "PIM state information\n"
3977 "Unicast or Multicast address\n"
3978 "Multicast address\n"
3981 const char *src_or_group
= NULL
;
3982 const char *group
= NULL
;
3984 bool uj
= use_json(argc
, argv
);
3993 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
3994 src_or_group
= argv
[idx
]->arg
;
3996 group
= argv
[idx
+ 1]->arg
;
3999 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4003 vty_out(vty
, " \"%s\": ", vrf
->name
);
4006 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4007 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
4010 vty_out(vty
, "}\n");
4015 DEFUN (show_ip_pim_upstream
,
4016 show_ip_pim_upstream_cmd
,
4017 "show ip pim [vrf NAME] upstream [json]",
4022 "PIM upstream information\n"
4026 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4027 bool uj
= use_json(argc
, argv
);
4032 pim_show_upstream(vrf
->info
, vty
, uj
);
4037 DEFUN (show_ip_pim_upstream_vrf_all
,
4038 show_ip_pim_upstream_vrf_all_cmd
,
4039 "show ip pim vrf all upstream [json]",
4044 "PIM upstream information\n"
4047 bool uj
= use_json(argc
, argv
);
4053 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4057 vty_out(vty
, " \"%s\": ", vrf
->name
);
4060 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4061 pim_show_upstream(vrf
->info
, vty
, uj
);
4067 DEFUN (show_ip_pim_upstream_join_desired
,
4068 show_ip_pim_upstream_join_desired_cmd
,
4069 "show ip pim [vrf NAME] upstream-join-desired [json]",
4074 "PIM upstream join-desired\n"
4078 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4079 bool uj
= use_json(argc
, argv
);
4084 pim_show_join_desired(vrf
->info
, vty
, uj
);
4089 DEFUN (show_ip_pim_upstream_rpf
,
4090 show_ip_pim_upstream_rpf_cmd
,
4091 "show ip pim [vrf NAME] upstream-rpf [json]",
4096 "PIM upstream source rpf\n"
4100 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4101 bool uj
= use_json(argc
, argv
);
4106 pim_show_upstream_rpf(vrf
->info
, vty
, uj
);
4111 DEFUN (show_ip_pim_rp
,
4113 "show ip pim [vrf NAME] rp-info [json]",
4118 "PIM RP information\n"
4122 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4123 bool uj
= use_json(argc
, argv
);
4128 pim_rp_show_information(vrf
->info
, vty
, uj
);
4133 DEFUN (show_ip_pim_rp_vrf_all
,
4134 show_ip_pim_rp_vrf_all_cmd
,
4135 "show ip pim vrf all rp-info [json]",
4140 "PIM RP information\n"
4143 bool uj
= use_json(argc
, argv
);
4149 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4153 vty_out(vty
, " \"%s\": ", vrf
->name
);
4156 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4157 pim_rp_show_information(vrf
->info
, vty
, uj
);
4160 vty_out(vty
, "}\n");
4165 DEFUN (show_ip_pim_rpf
,
4166 show_ip_pim_rpf_cmd
,
4167 "show ip pim [vrf NAME] rpf [json]",
4172 "PIM cached source rpf information\n"
4176 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4177 bool uj
= use_json(argc
, argv
);
4182 pim_show_rpf(vrf
->info
, vty
, uj
);
4187 DEFUN (show_ip_pim_rpf_vrf_all
,
4188 show_ip_pim_rpf_vrf_all_cmd
,
4189 "show ip pim vrf all rpf [json]",
4194 "PIM cached source rpf information\n"
4197 bool uj
= use_json(argc
, argv
);
4203 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4207 vty_out(vty
, " \"%s\": ", vrf
->name
);
4210 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4211 pim_show_rpf(vrf
->info
, vty
, uj
);
4214 vty_out(vty
, "}\n");
4219 DEFUN (show_ip_pim_nexthop
,
4220 show_ip_pim_nexthop_cmd
,
4221 "show ip pim [vrf NAME] nexthop",
4226 "PIM cached nexthop rpf information\n")
4229 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4234 pim_show_nexthop(vrf
->info
, vty
);
4239 DEFUN (show_ip_pim_nexthop_lookup
,
4240 show_ip_pim_nexthop_lookup_cmd
,
4241 "show ip pim [vrf NAME] nexthop-lookup A.B.C.D A.B.C.D",
4246 "PIM cached nexthop rpf lookup\n"
4247 "Source/RP address\n"
4248 "Multicast Group address\n")
4250 struct pim_nexthop_cache
*pnc
= NULL
;
4251 struct prefix nht_p
;
4253 struct in_addr src_addr
, grp_addr
;
4254 struct in_addr vif_source
;
4255 const char *addr_str
, *addr_str1
;
4257 struct pim_nexthop nexthop
;
4258 char nexthop_addr_str
[PREFIX_STRLEN
];
4259 char grp_str
[PREFIX_STRLEN
];
4261 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4267 argv_find(argv
, argc
, "A.B.C.D", &idx
);
4268 addr_str
= argv
[idx
]->arg
;
4269 result
= inet_pton(AF_INET
, addr_str
, &src_addr
);
4271 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
4272 errno
, safe_strerror(errno
));
4276 if (pim_is_group_224_4(src_addr
)) {
4278 "Invalid argument. Expected Valid Source Address.\n");
4282 addr_str1
= argv
[idx
+ 1]->arg
;
4283 result
= inet_pton(AF_INET
, addr_str1
, &grp_addr
);
4285 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
4286 errno
, safe_strerror(errno
));
4290 if (!pim_is_group_224_4(grp_addr
)) {
4292 "Invalid argument. Expected Valid Multicast Group Address.\n");
4296 if (!pim_rp_set_upstream_addr(vrf
->info
, &vif_source
, src_addr
,
4300 nht_p
.family
= AF_INET
;
4301 nht_p
.prefixlen
= IPV4_MAX_BITLEN
;
4302 nht_p
.u
.prefix4
= vif_source
;
4303 grp
.family
= AF_INET
;
4304 grp
.prefixlen
= IPV4_MAX_BITLEN
;
4305 grp
.u
.prefix4
= grp_addr
;
4306 memset(&nexthop
, 0, sizeof(nexthop
));
4308 memset(&rpf
, 0, sizeof(struct pim_rpf
));
4309 rpf
.rpf_addr
.family
= AF_INET
;
4310 rpf
.rpf_addr
.prefixlen
= IPV4_MAX_BITLEN
;
4311 rpf
.rpf_addr
.u
.prefix4
= vif_source
;
4313 pnc
= pim_nexthop_cache_find(vrf
->info
, &rpf
);
4315 result
= pim_ecmp_nexthop_search(vrf
->info
, pnc
, &nexthop
,
4318 result
= pim_ecmp_nexthop_lookup(vrf
->info
, &nexthop
, &nht_p
,
4323 "Nexthop Lookup failed, no usable routes returned.\n");
4327 pim_addr_dump("<grp?>", &grp
, grp_str
, sizeof(grp_str
));
4328 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
4329 nexthop_addr_str
, sizeof(nexthop_addr_str
));
4330 vty_out(vty
, "Group %s --- Nexthop %s Interface %s \n", grp_str
,
4331 nexthop_addr_str
, nexthop
.interface
->name
);
4336 DEFUN (show_ip_pim_interface_traffic
,
4337 show_ip_pim_interface_traffic_cmd
,
4338 "show ip pim [vrf NAME] interface traffic [WORD] [json]",
4343 "PIM interface information\n"
4344 "Protocol Packet counters\n"
4349 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4350 bool uj
= use_json(argc
, argv
);
4355 if (argv_find(argv
, argc
, "WORD", &idx
))
4356 pim_show_interface_traffic_single(vrf
->info
, vty
,
4357 argv
[idx
]->arg
, uj
);
4359 pim_show_interface_traffic(vrf
->info
, vty
, uj
);
4364 static void show_multicast_interfaces(struct pim_instance
*pim
, struct vty
*vty
)
4366 struct interface
*ifp
;
4371 "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut\n");
4373 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
4374 struct pim_interface
*pim_ifp
;
4375 struct in_addr ifaddr
;
4376 struct sioc_vif_req vreq
;
4378 pim_ifp
= ifp
->info
;
4383 memset(&vreq
, 0, sizeof(vreq
));
4384 vreq
.vifi
= pim_ifp
->mroute_vif_index
;
4386 if (ioctl(pim
->mroute_socket
, SIOCGETVIFCNT
, &vreq
)) {
4388 "ioctl(SIOCGETVIFCNT=%lu) failure for interface %s vif_index=%d: errno=%d: %s",
4389 (unsigned long)SIOCGETVIFCNT
, ifp
->name
,
4390 pim_ifp
->mroute_vif_index
, errno
,
4391 safe_strerror(errno
));
4394 ifaddr
= pim_ifp
->primary_address
;
4396 vty_out(vty
, "%-12s %-15s %3d %3d %7lu %7lu %10lu %10lu\n",
4397 ifp
->name
, inet_ntoa(ifaddr
), ifp
->ifindex
,
4398 pim_ifp
->mroute_vif_index
, (unsigned long)vreq
.icount
,
4399 (unsigned long)vreq
.ocount
, (unsigned long)vreq
.ibytes
,
4400 (unsigned long)vreq
.obytes
);
4404 static void pim_cmd_show_ip_multicast_helper(struct pim_instance
*pim
,
4407 struct vrf
*vrf
= pim
->vrf
;
4408 time_t now
= pim_time_monotonic_sec();
4413 vty_out(vty
, "Mroute socket descriptor:");
4415 vty_out(vty
, " %d(%s)\n", pim
->mroute_socket
, vrf
->name
);
4417 pim_time_uptime(uptime
, sizeof(uptime
),
4418 now
- pim
->mroute_socket_creation
);
4419 vty_out(vty
, "Mroute socket uptime: %s\n", uptime
);
4423 pim_zebra_zclient_update(vty
);
4424 pim_zlookup_show_ip_multicast(vty
);
4427 vty_out(vty
, "Maximum highest VifIndex: %d\n", PIM_MAX_USABLE_VIFS
);
4430 vty_out(vty
, "Upstream Join Timer: %d secs\n", qpim_t_periodic
);
4431 vty_out(vty
, "Join/Prune Holdtime: %d secs\n", PIM_JP_HOLDTIME
);
4432 vty_out(vty
, "PIM ECMP: %s\n", pim
->ecmp_enable
? "Enable" : "Disable");
4433 vty_out(vty
, "PIM ECMP Rebalance: %s\n",
4434 pim
->ecmp_rebalance_enable
? "Enable" : "Disable");
4438 show_rpf_refresh_stats(vty
, pim
, now
, NULL
);
4442 show_scan_oil_stats(pim
, vty
, now
);
4444 show_multicast_interfaces(pim
, vty
);
4447 DEFUN (show_ip_multicast
,
4448 show_ip_multicast_cmd
,
4449 "show ip multicast [vrf NAME]",
4453 "Multicast global information\n")
4456 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4461 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
4466 DEFUN (show_ip_multicast_vrf_all
,
4467 show_ip_multicast_vrf_all_cmd
,
4468 "show ip multicast vrf all",
4472 "Multicast global information\n")
4474 bool uj
= use_json(argc
, argv
);
4480 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4484 vty_out(vty
, " \"%s\": ", vrf
->name
);
4487 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4488 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
4491 vty_out(vty
, "}\n");
4496 static void show_mroute(struct pim_instance
*pim
, struct vty
*vty
, bool fill
,
4499 struct listnode
*node
;
4500 struct channel_oil
*c_oil
;
4501 struct static_route
*s_route
;
4503 json_object
*json
= NULL
;
4504 json_object
*json_group
= NULL
;
4505 json_object
*json_source
= NULL
;
4506 json_object
*json_oil
= NULL
;
4507 json_object
*json_ifp_out
= NULL
;
4510 char grp_str
[INET_ADDRSTRLEN
];
4511 char src_str
[INET_ADDRSTRLEN
];
4512 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
4513 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
4515 struct interface
*ifp_in
;
4519 json
= json_object_new_object();
4522 "Source Group Proto Input Output TTL Uptime\n");
4525 now
= pim_time_monotonic_sec();
4527 /* print list of PIM and IGMP routes */
4528 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
4531 if (!c_oil
->installed
&& !uj
)
4534 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
4536 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
4538 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
4541 strcpy(in_ifname
, ifp_in
->name
);
4543 strcpy(in_ifname
, "<iif?>");
4547 /* Find the group, create it if it doesn't exist */
4548 json_object_object_get_ex(json
, grp_str
, &json_group
);
4551 json_group
= json_object_new_object();
4552 json_object_object_add(json
, grp_str
,
4556 /* Find the source nested under the group, create it if
4557 * it doesn't exist */
4558 json_object_object_get_ex(json_group
, src_str
,
4562 json_source
= json_object_new_object();
4563 json_object_object_add(json_group
, src_str
,
4567 /* Find the inbound interface nested under the source,
4568 * create it if it doesn't exist */
4569 json_object_int_add(json_source
, "installed",
4571 json_object_int_add(json_source
, "refCount",
4572 c_oil
->oil_ref_count
);
4573 json_object_int_add(json_source
, "oilSize",
4575 json_object_int_add(json_source
, "OilInheritedRescan",
4576 c_oil
->oil_inherited_rescan
);
4577 json_object_string_add(json_source
, "iif", in_ifname
);
4581 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
4583 struct interface
*ifp_out
;
4584 char oif_uptime
[10];
4587 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
4591 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
4593 oif_uptime
, sizeof(oif_uptime
),
4594 now
- c_oil
->oif_creation
[oif_vif_index
]);
4598 strcpy(out_ifname
, ifp_out
->name
);
4600 strcpy(out_ifname
, "<oif?>");
4603 json_ifp_out
= json_object_new_object();
4604 json_object_string_add(json_ifp_out
, "source",
4606 json_object_string_add(json_ifp_out
, "group",
4609 if (c_oil
->oif_flags
[oif_vif_index
]
4610 & PIM_OIF_FLAG_PROTO_PIM
)
4611 json_object_boolean_true_add(
4612 json_ifp_out
, "protocolPim");
4614 if (c_oil
->oif_flags
[oif_vif_index
]
4615 & PIM_OIF_FLAG_PROTO_IGMP
)
4616 json_object_boolean_true_add(
4617 json_ifp_out
, "protocolIgmp");
4619 if (c_oil
->oif_flags
[oif_vif_index
]
4620 & PIM_OIF_FLAG_PROTO_SOURCE
)
4621 json_object_boolean_true_add(
4622 json_ifp_out
, "protocolSource");
4624 if (c_oil
->oif_flags
[oif_vif_index
]
4625 & PIM_OIF_FLAG_PROTO_STAR
)
4626 json_object_boolean_true_add(
4628 "protocolInherited");
4630 json_object_string_add(json_ifp_out
,
4633 json_object_int_add(json_ifp_out
, "iVifI",
4634 c_oil
->oil
.mfcc_parent
);
4635 json_object_string_add(json_ifp_out
,
4636 "outboundInterface",
4638 json_object_int_add(json_ifp_out
, "oVifI",
4640 json_object_int_add(json_ifp_out
, "ttl", ttl
);
4641 json_object_string_add(json_ifp_out
, "upTime",
4644 json_oil
= json_object_new_object();
4645 json_object_object_add(json_source
,
4648 json_object_object_add(json_oil
, out_ifname
,
4651 if (c_oil
->oif_flags
[oif_vif_index
]
4652 & PIM_OIF_FLAG_PROTO_PIM
) {
4653 strcpy(proto
, "PIM");
4656 if (c_oil
->oif_flags
[oif_vif_index
]
4657 & PIM_OIF_FLAG_PROTO_IGMP
) {
4658 strcpy(proto
, "IGMP");
4661 if (c_oil
->oif_flags
[oif_vif_index
]
4662 & PIM_OIF_FLAG_PROTO_SOURCE
) {
4663 strcpy(proto
, "SRC");
4666 if (c_oil
->oif_flags
[oif_vif_index
]
4667 & PIM_OIF_FLAG_PROTO_STAR
) {
4668 strcpy(proto
, "STAR");
4672 "%-15s %-15s %-6s %-10s %-10s %-3d %8s\n",
4673 src_str
, grp_str
, proto
, in_ifname
,
4674 out_ifname
, ttl
, oif_uptime
);
4679 in_ifname
[0] = '\0';
4685 if (!uj
&& !found_oif
) {
4686 vty_out(vty
, "%-15s %-15s %-6s %-10s %-10s %-3d %8s\n",
4687 src_str
, grp_str
, "none", in_ifname
, "none", 0,
4692 /* Print list of static routes */
4693 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
4696 if (!s_route
->c_oil
.installed
)
4699 pim_inet4_dump("<group?>", s_route
->group
, grp_str
,
4701 pim_inet4_dump("<source?>", s_route
->source
, src_str
,
4703 ifp_in
= pim_if_find_by_vif_index(pim
, s_route
->iif
);
4707 strcpy(in_ifname
, ifp_in
->name
);
4709 strcpy(in_ifname
, "<iif?>");
4713 /* Find the group, create it if it doesn't exist */
4714 json_object_object_get_ex(json
, grp_str
, &json_group
);
4717 json_group
= json_object_new_object();
4718 json_object_object_add(json
, grp_str
,
4722 /* Find the source nested under the group, create it if
4723 * it doesn't exist */
4724 json_object_object_get_ex(json_group
, src_str
,
4728 json_source
= json_object_new_object();
4729 json_object_object_add(json_group
, src_str
,
4733 json_object_string_add(json_source
, "iif", in_ifname
);
4736 strcpy(proto
, "STATIC");
4739 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
4741 struct interface
*ifp_out
;
4742 char oif_uptime
[10];
4745 ttl
= s_route
->oif_ttls
[oif_vif_index
];
4749 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
4751 oif_uptime
, sizeof(oif_uptime
),
4754 .oif_creation
[oif_vif_index
]);
4758 strcpy(out_ifname
, ifp_out
->name
);
4760 strcpy(out_ifname
, "<oif?>");
4763 json_ifp_out
= json_object_new_object();
4764 json_object_string_add(json_ifp_out
, "source",
4766 json_object_string_add(json_ifp_out
, "group",
4768 json_object_boolean_true_add(json_ifp_out
,
4770 json_object_string_add(json_ifp_out
,
4773 json_object_int_add(
4774 json_ifp_out
, "iVifI",
4775 s_route
->c_oil
.oil
.mfcc_parent
);
4776 json_object_string_add(json_ifp_out
,
4777 "outboundInterface",
4779 json_object_int_add(json_ifp_out
, "oVifI",
4781 json_object_int_add(json_ifp_out
, "ttl", ttl
);
4782 json_object_string_add(json_ifp_out
, "upTime",
4785 json_oil
= json_object_new_object();
4786 json_object_object_add(json_source
,
4789 json_object_object_add(json_oil
, out_ifname
,
4793 "%-15s %-15s %-6s %-10s %-10s %-3d %8s %s\n",
4794 src_str
, grp_str
, proto
, in_ifname
,
4795 out_ifname
, ttl
, oif_uptime
,
4797 if (first
&& !fill
) {
4800 in_ifname
[0] = '\0';
4806 if (!uj
&& !found_oif
) {
4808 "%-15s %-15s %-6s %-10s %-10s %-3d %8s %s\n",
4809 src_str
, grp_str
, proto
, in_ifname
, "none", 0,
4810 "--:--:--", pim
->vrf
->name
);
4815 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4816 json
, JSON_C_TO_STRING_PRETTY
));
4817 json_object_free(json
);
4821 DEFUN (show_ip_mroute
,
4823 "show ip mroute [vrf NAME] [fill] [json]",
4828 "Fill in Assumed data\n"
4831 bool uj
= use_json(argc
, argv
);
4834 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4839 if (argv_find(argv
, argc
, "fill", &idx
))
4842 show_mroute(vrf
->info
, vty
, fill
, uj
);
4846 DEFUN (show_ip_mroute_vrf_all
,
4847 show_ip_mroute_vrf_all_cmd
,
4848 "show ip mroute vrf all [fill] [json]",
4853 "Fill in Assumed data\n"
4856 bool uj
= use_json(argc
, argv
);
4862 if (argv_find(argv
, argc
, "fill", &idx
))
4867 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4871 vty_out(vty
, " \"%s\": ", vrf
->name
);
4874 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4875 show_mroute(vrf
->info
, vty
, fill
, uj
);
4878 vty_out(vty
, "}\n");
4883 static void show_mroute_count(struct pim_instance
*pim
, struct vty
*vty
)
4885 struct listnode
*node
;
4886 struct channel_oil
*c_oil
;
4887 struct static_route
*s_route
;
4892 "Source Group LastUsed Packets Bytes WrongIf \n");
4894 /* Print PIM and IGMP route counts */
4895 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
4896 char group_str
[INET_ADDRSTRLEN
];
4897 char source_str
[INET_ADDRSTRLEN
];
4899 if (!c_oil
->installed
)
4902 pim_mroute_update_counters(c_oil
);
4904 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, group_str
,
4906 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, source_str
,
4907 sizeof(source_str
));
4909 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
4910 source_str
, group_str
, c_oil
->cc
.lastused
/ 100,
4911 c_oil
->cc
.pktcnt
, c_oil
->cc
.bytecnt
,
4912 c_oil
->cc
.wrong_if
);
4915 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
4916 char group_str
[INET_ADDRSTRLEN
];
4917 char source_str
[INET_ADDRSTRLEN
];
4919 if (!s_route
->c_oil
.installed
)
4922 pim_mroute_update_counters(&s_route
->c_oil
);
4924 pim_inet4_dump("<group?>", s_route
->c_oil
.oil
.mfcc_mcastgrp
,
4925 group_str
, sizeof(group_str
));
4926 pim_inet4_dump("<source?>", s_route
->c_oil
.oil
.mfcc_origin
,
4927 source_str
, sizeof(source_str
));
4929 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
4930 source_str
, group_str
, s_route
->c_oil
.cc
.lastused
,
4931 s_route
->c_oil
.cc
.pktcnt
, s_route
->c_oil
.cc
.bytecnt
,
4932 s_route
->c_oil
.cc
.wrong_if
);
4936 DEFUN (show_ip_mroute_count
,
4937 show_ip_mroute_count_cmd
,
4938 "show ip mroute [vrf NAME] count",
4943 "Route and packet count data\n")
4946 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4951 show_mroute_count(vrf
->info
, vty
);
4955 DEFUN (show_ip_mroute_count_vrf_all
,
4956 show_ip_mroute_count_vrf_all_cmd
,
4957 "show ip mroute vrf all count",
4962 "Route and packet count data\n")
4964 bool uj
= use_json(argc
, argv
);
4970 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4974 vty_out(vty
, " \"%s\": ", vrf
->name
);
4977 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4978 show_mroute_count(vrf
->info
, vty
);
4981 vty_out(vty
, "}\n");
4988 "show ip rib [vrf NAME] A.B.C.D",
4993 "Unicast address\n")
4996 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4997 struct in_addr addr
;
4998 const char *addr_str
;
4999 struct pim_nexthop nexthop
;
5000 char nexthop_addr_str
[PREFIX_STRLEN
];
5006 memset(&nexthop
, 0, sizeof(nexthop
));
5007 argv_find(argv
, argc
, "A.B.C.D", &idx
);
5008 addr_str
= argv
[idx
]->arg
;
5009 result
= inet_pton(AF_INET
, addr_str
, &addr
);
5011 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
5012 errno
, safe_strerror(errno
));
5016 if (pim_nexthop_lookup(vrf
->info
, &nexthop
, addr
, 0)) {
5018 "Failure querying RIB nexthop for unicast address %s\n",
5024 "Address NextHop Interface Metric Preference\n");
5026 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
5027 nexthop_addr_str
, sizeof(nexthop_addr_str
));
5029 vty_out(vty
, "%-15s %-15s %-9s %6d %10d\n", addr_str
, nexthop_addr_str
,
5030 nexthop
.interface
? nexthop
.interface
->name
: "<ifname?>",
5031 nexthop
.mrib_route_metric
, nexthop
.mrib_metric_preference
);
5036 static void show_ssmpingd(struct pim_instance
*pim
, struct vty
*vty
)
5038 struct listnode
*node
;
5039 struct ssmpingd_sock
*ss
;
5043 "Source Socket Address Port Uptime Requests\n");
5045 if (!pim
->ssmpingd_list
)
5048 now
= pim_time_monotonic_sec();
5050 for (ALL_LIST_ELEMENTS_RO(pim
->ssmpingd_list
, node
, ss
)) {
5051 char source_str
[INET_ADDRSTRLEN
];
5053 struct sockaddr_in bind_addr
;
5054 socklen_t len
= sizeof(bind_addr
);
5055 char bind_addr_str
[INET_ADDRSTRLEN
];
5057 pim_inet4_dump("<src?>", ss
->source_addr
, source_str
,
5058 sizeof(source_str
));
5060 if (pim_socket_getsockname(
5061 ss
->sock_fd
, (struct sockaddr
*)&bind_addr
, &len
)) {
5063 "%% Failure reading socket name for ssmpingd source %s on fd=%d\n",
5064 source_str
, ss
->sock_fd
);
5067 pim_inet4_dump("<addr?>", bind_addr
.sin_addr
, bind_addr_str
,
5068 sizeof(bind_addr_str
));
5069 pim_time_uptime(ss_uptime
, sizeof(ss_uptime
),
5070 now
- ss
->creation
);
5072 vty_out(vty
, "%-15s %6d %-15s %5d %8s %8lld\n", source_str
,
5073 ss
->sock_fd
, bind_addr_str
, ntohs(bind_addr
.sin_port
),
5074 ss_uptime
, (long long)ss
->requests
);
5078 DEFUN (show_ip_ssmpingd
,
5079 show_ip_ssmpingd_cmd
,
5080 "show ip ssmpingd [vrf NAME]",
5087 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5092 show_ssmpingd(vrf
->info
, vty
);
5096 static int pim_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
5097 const char *rp
, const char *group
,
5102 result
= pim_rp_new(pim
, rp
, group
, plist
);
5104 if (result
== PIM_GROUP_BAD_ADDRESS
) {
5105 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
5106 return CMD_WARNING_CONFIG_FAILED
;
5109 if (result
== PIM_RP_BAD_ADDRESS
) {
5110 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
5111 return CMD_WARNING_CONFIG_FAILED
;
5114 if (result
== PIM_RP_NO_PATH
) {
5115 vty_out(vty
, "%% No Path to RP address specified: %s\n", rp
);
5119 if (result
== PIM_GROUP_OVERLAP
) {
5121 "%% Group range specified cannot exact match another\n");
5122 return CMD_WARNING_CONFIG_FAILED
;
5125 if (result
== PIM_GROUP_PFXLIST_OVERLAP
) {
5127 "%% This group is already covered by a RP prefix-list\n");
5128 return CMD_WARNING_CONFIG_FAILED
;
5131 if (result
== PIM_RP_PFXLIST_IN_USE
) {
5133 "%% The same prefix-list cannot be applied to multiple RPs\n");
5134 return CMD_WARNING_CONFIG_FAILED
;
5140 static int pim_cmd_spt_switchover(struct pim_instance
*pim
,
5141 enum pim_spt_switchover spt
,
5144 pim
->spt
.switchover
= spt
;
5146 switch (pim
->spt
.switchover
) {
5147 case PIM_SPT_IMMEDIATE
:
5149 XFREE(MTYPE_PIM_SPT_PLIST_NAME
, pim
->spt
.plist
);
5151 pim_upstream_add_lhr_star_pimreg(pim
);
5153 case PIM_SPT_INFINITY
:
5154 pim_upstream_remove_lhr_star_pimreg(pim
, plist
);
5157 XFREE(MTYPE_PIM_SPT_PLIST_NAME
, pim
->spt
.plist
);
5161 XSTRDUP(MTYPE_PIM_SPT_PLIST_NAME
, plist
);
5168 DEFUN (ip_pim_spt_switchover_infinity
,
5169 ip_pim_spt_switchover_infinity_cmd
,
5170 "ip pim spt-switchover infinity-and-beyond",
5174 "Never switch to SPT Tree\n")
5176 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5177 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, NULL
);
5180 DEFUN (ip_pim_spt_switchover_infinity_plist
,
5181 ip_pim_spt_switchover_infinity_plist_cmd
,
5182 "ip pim spt-switchover infinity-and-beyond prefix-list WORD",
5186 "Never switch to SPT Tree\n"
5187 "Prefix-List to control which groups to switch\n"
5188 "Prefix-List name\n")
5190 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5191 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, argv
[5]->arg
);
5194 DEFUN (no_ip_pim_spt_switchover_infinity
,
5195 no_ip_pim_spt_switchover_infinity_cmd
,
5196 "no ip pim spt-switchover infinity-and-beyond",
5201 "Never switch to SPT Tree\n")
5203 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5204 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
5207 DEFUN (no_ip_pim_spt_switchover_infinity_plist
,
5208 no_ip_pim_spt_switchover_infinity_plist_cmd
,
5209 "no ip pim spt-switchover infinity-and-beyond prefix-list WORD",
5214 "Never switch to SPT Tree\n"
5215 "Prefix-List to control which groups to switch\n"
5216 "Prefix-List name\n")
5218 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5219 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
5222 DEFUN (ip_pim_joinprune_time
,
5223 ip_pim_joinprune_time_cmd
,
5224 "ip pim join-prune-interval (60-600)",
5226 "pim multicast routing\n"
5227 "Join Prune Send Interval\n"
5230 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5231 qpim_t_periodic
= atoi(argv
[3]->arg
);
5235 DEFUN (no_ip_pim_joinprune_time
,
5236 no_ip_pim_joinprune_time_cmd
,
5237 "no ip pim join-prune-interval (60-600)",
5240 "pim multicast routing\n"
5241 "Join Prune Send Interval\n"
5244 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5245 qpim_t_periodic
= PIM_DEFAULT_T_PERIODIC
;
5249 DEFUN (ip_pim_register_suppress
,
5250 ip_pim_register_suppress_cmd
,
5251 "ip pim register-suppress-time (5-60000)",
5253 "pim multicast routing\n"
5254 "Register Suppress Timer\n"
5257 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5258 qpim_register_suppress_time
= atoi(argv
[3]->arg
);
5262 DEFUN (no_ip_pim_register_suppress
,
5263 no_ip_pim_register_suppress_cmd
,
5264 "no ip pim register-suppress-time (5-60000)",
5267 "pim multicast routing\n"
5268 "Register Suppress Timer\n"
5271 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5272 qpim_register_suppress_time
= PIM_REGISTER_SUPPRESSION_TIME_DEFAULT
;
5276 DEFUN (ip_pim_rp_keep_alive
,
5277 ip_pim_rp_keep_alive_cmd
,
5278 "ip pim rp keep-alive-timer (31-60000)",
5280 "pim multicast routing\n"
5282 "Keep alive Timer\n"
5285 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5286 pim
->rp_keep_alive_time
= atoi(argv
[4]->arg
);
5290 DEFUN (no_ip_pim_rp_keep_alive
,
5291 no_ip_pim_rp_keep_alive_cmd
,
5292 "no ip pim rp keep-alive-timer (31-60000)",
5295 "pim multicast routing\n"
5297 "Keep alive Timer\n"
5300 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5301 pim
->rp_keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
5305 DEFUN (ip_pim_keep_alive
,
5306 ip_pim_keep_alive_cmd
,
5307 "ip pim keep-alive-timer (31-60000)",
5309 "pim multicast routing\n"
5310 "Keep alive Timer\n"
5313 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5314 pim
->keep_alive_time
= atoi(argv
[3]->arg
);
5318 DEFUN (no_ip_pim_keep_alive
,
5319 no_ip_pim_keep_alive_cmd
,
5320 "no ip pim keep-alive-timer (31-60000)",
5323 "pim multicast routing\n"
5324 "Keep alive Timer\n"
5327 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5328 pim
->keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
5332 DEFUN (ip_pim_packets
,
5334 "ip pim packets (1-100)",
5336 "pim multicast routing\n"
5337 "packets to process at one time per fd\n"
5338 "Number of packets\n")
5340 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5341 qpim_packet_process
= atoi(argv
[3]->arg
);
5345 DEFUN (no_ip_pim_packets
,
5346 no_ip_pim_packets_cmd
,
5347 "no ip pim packets (1-100)",
5350 "pim multicast routing\n"
5351 "packets to process at one time per fd\n"
5352 "Number of packets\n")
5354 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5355 qpim_packet_process
= PIM_DEFAULT_PACKET_PROCESS
;
5359 DEFUN (ip_pim_v6_secondary
,
5360 ip_pim_v6_secondary_cmd
,
5361 "ip pim send-v6-secondary",
5363 "pim multicast routing\n"
5364 "Send v6 secondary addresses\n")
5366 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5367 pim
->send_v6_secondary
= 1;
5372 DEFUN (no_ip_pim_v6_secondary
,
5373 no_ip_pim_v6_secondary_cmd
,
5374 "no ip pim send-v6-secondary",
5377 "pim multicast routing\n"
5378 "Send v6 secondary addresses\n")
5380 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5381 pim
->send_v6_secondary
= 0;
5388 "ip pim rp A.B.C.D [A.B.C.D/M]",
5390 "pim multicast routing\n"
5392 "ip address of RP\n"
5393 "Group Address range to cover\n")
5395 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5398 if (argc
== (idx_ipv4
+ 1))
5399 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
5402 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
5403 argv
[idx_ipv4
+ 1]->arg
, NULL
);
5406 DEFUN (ip_pim_rp_prefix_list
,
5407 ip_pim_rp_prefix_list_cmd
,
5408 "ip pim rp A.B.C.D prefix-list WORD",
5410 "pim multicast routing\n"
5412 "ip address of RP\n"
5413 "group prefix-list filter\n"
5414 "Name of a prefix-list\n")
5416 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5417 return pim_rp_cmd_worker(pim
, vty
, argv
[3]->arg
, NULL
, argv
[5]->arg
);
5420 static int pim_no_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
5421 const char *rp
, const char *group
,
5424 int result
= pim_rp_del(pim
, rp
, group
, plist
);
5426 if (result
== PIM_GROUP_BAD_ADDRESS
) {
5427 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
5428 return CMD_WARNING_CONFIG_FAILED
;
5431 if (result
== PIM_RP_BAD_ADDRESS
) {
5432 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
5433 return CMD_WARNING_CONFIG_FAILED
;
5436 if (result
== PIM_RP_NOT_FOUND
) {
5437 vty_out(vty
, "%% Unable to find specified RP\n");
5438 return CMD_WARNING_CONFIG_FAILED
;
5444 DEFUN (no_ip_pim_rp
,
5446 "no ip pim rp A.B.C.D [A.B.C.D/M]",
5449 "pim multicast routing\n"
5451 "ip address of RP\n"
5452 "Group Address range to cover\n")
5454 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5455 int idx_ipv4
= 4, idx_group
= 0;
5457 if (argv_find(argv
, argc
, "A.B.C.D/M", &idx_group
))
5458 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
5459 argv
[idx_group
]->arg
, NULL
);
5461 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
5465 DEFUN (no_ip_pim_rp_prefix_list
,
5466 no_ip_pim_rp_prefix_list_cmd
,
5467 "no ip pim rp A.B.C.D prefix-list WORD",
5470 "pim multicast routing\n"
5472 "ip address of RP\n"
5473 "group prefix-list filter\n"
5474 "Name of a prefix-list\n")
5476 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5477 return pim_no_rp_cmd_worker(pim
, vty
, argv
[4]->arg
, NULL
, argv
[6]->arg
);
5480 static int pim_ssm_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
5483 int result
= pim_ssm_range_set(pim
, pim
->vrf_id
, plist
);
5485 if (result
== PIM_SSM_ERR_NONE
)
5489 case PIM_SSM_ERR_NO_VRF
:
5490 vty_out(vty
, "%% VRF doesn't exist\n");
5492 case PIM_SSM_ERR_DUP
:
5493 vty_out(vty
, "%% duplicate config\n");
5496 vty_out(vty
, "%% ssm range config failed\n");
5499 return CMD_WARNING_CONFIG_FAILED
;
5502 DEFUN (ip_pim_ssm_prefix_list
,
5503 ip_pim_ssm_prefix_list_cmd
,
5504 "ip pim ssm prefix-list WORD",
5506 "pim multicast routing\n"
5507 "Source Specific Multicast\n"
5508 "group range prefix-list filter\n"
5509 "Name of a prefix-list\n")
5511 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5512 return pim_ssm_cmd_worker(pim
, vty
, argv
[4]->arg
);
5515 DEFUN (no_ip_pim_ssm_prefix_list
,
5516 no_ip_pim_ssm_prefix_list_cmd
,
5517 "no ip pim ssm prefix-list",
5520 "pim multicast routing\n"
5521 "Source Specific Multicast\n"
5522 "group range prefix-list filter\n")
5524 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5525 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
5528 DEFUN (no_ip_pim_ssm_prefix_list_name
,
5529 no_ip_pim_ssm_prefix_list_name_cmd
,
5530 "no ip pim ssm prefix-list WORD",
5533 "pim multicast routing\n"
5534 "Source Specific Multicast\n"
5535 "group range prefix-list filter\n"
5536 "Name of a prefix-list\n")
5538 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5539 struct pim_ssm
*ssm
= pim
->ssm_info
;
5541 if (ssm
->plist_name
&& !strcmp(ssm
->plist_name
, argv
[5]->arg
))
5542 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
5544 vty_out(vty
, "%% pim ssm prefix-list %s doesn't exist\n", argv
[5]->arg
);
5546 return CMD_WARNING_CONFIG_FAILED
;
5549 static void ip_pim_ssm_show_group_range(struct pim_instance
*pim
,
5550 struct vty
*vty
, bool uj
)
5552 struct pim_ssm
*ssm
= pim
->ssm_info
;
5553 const char *range_str
=
5554 ssm
->plist_name
? ssm
->plist_name
: PIM_SSM_STANDARD_RANGE
;
5558 json
= json_object_new_object();
5559 json_object_string_add(json
, "ssmGroups", range_str
);
5560 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5561 json
, JSON_C_TO_STRING_PRETTY
));
5562 json_object_free(json
);
5564 vty_out(vty
, "SSM group range : %s\n", range_str
);
5567 DEFUN (show_ip_pim_ssm_range
,
5568 show_ip_pim_ssm_range_cmd
,
5569 "show ip pim [vrf NAME] group-type [json]",
5578 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5579 bool uj
= use_json(argc
, argv
);
5584 ip_pim_ssm_show_group_range(vrf
->info
, vty
, uj
);
5589 static void ip_pim_ssm_show_group_type(struct pim_instance
*pim
,
5590 struct vty
*vty
, bool uj
,
5593 struct in_addr group_addr
;
5594 const char *type_str
;
5597 result
= inet_pton(AF_INET
, group
, &group_addr
);
5599 type_str
= "invalid";
5601 if (pim_is_group_224_4(group_addr
))
5603 pim_is_grp_ssm(pim
, group_addr
) ? "SSM" : "ASM";
5605 type_str
= "not-multicast";
5610 json
= json_object_new_object();
5611 json_object_string_add(json
, "groupType", type_str
);
5612 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5613 json
, JSON_C_TO_STRING_PRETTY
));
5614 json_object_free(json
);
5616 vty_out(vty
, "Group type : %s\n", type_str
);
5619 DEFUN (show_ip_pim_group_type
,
5620 show_ip_pim_group_type_cmd
,
5621 "show ip pim [vrf NAME] group-type A.B.C.D [json]",
5626 "multicast group type\n"
5631 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5632 bool uj
= use_json(argc
, argv
);
5637 argv_find(argv
, argc
, "A.B.C.D", &idx
);
5638 ip_pim_ssm_show_group_type(vrf
->info
, vty
, uj
, argv
[idx
]->arg
);
5645 "ip ssmpingd [A.B.C.D]",
5650 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5653 struct in_addr source_addr
;
5654 const char *source_str
= (argc
== 3) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
5656 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
5658 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
5659 source_str
, errno
, safe_strerror(errno
));
5660 return CMD_WARNING_CONFIG_FAILED
;
5663 result
= pim_ssmpingd_start(pim
, source_addr
);
5665 vty_out(vty
, "%% Failure starting ssmpingd for source %s: %d\n",
5666 source_str
, result
);
5667 return CMD_WARNING_CONFIG_FAILED
;
5673 DEFUN (no_ip_ssmpingd
,
5675 "no ip ssmpingd [A.B.C.D]",
5681 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5684 struct in_addr source_addr
;
5685 const char *source_str
= (argc
== 4) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
5687 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
5689 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
5690 source_str
, errno
, safe_strerror(errno
));
5691 return CMD_WARNING_CONFIG_FAILED
;
5694 result
= pim_ssmpingd_stop(pim
, source_addr
);
5696 vty_out(vty
, "%% Failure stopping ssmpingd for source %s: %d\n",
5697 source_str
, result
);
5698 return CMD_WARNING_CONFIG_FAILED
;
5708 "pim multicast routing\n"
5709 "Enable PIM ECMP \n")
5711 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5712 pim
->ecmp_enable
= true;
5717 DEFUN (no_ip_pim_ecmp
,
5722 "pim multicast routing\n"
5723 "Disable PIM ECMP \n")
5725 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5726 pim
->ecmp_enable
= false;
5731 DEFUN (ip_pim_ecmp_rebalance
,
5732 ip_pim_ecmp_rebalance_cmd
,
5733 "ip pim ecmp rebalance",
5735 "pim multicast routing\n"
5736 "Enable PIM ECMP \n"
5737 "Enable PIM ECMP Rebalance\n")
5739 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5740 pim
->ecmp_enable
= true;
5741 pim
->ecmp_rebalance_enable
= true;
5746 DEFUN (no_ip_pim_ecmp_rebalance
,
5747 no_ip_pim_ecmp_rebalance_cmd
,
5748 "no ip pim ecmp rebalance",
5751 "pim multicast routing\n"
5752 "Disable PIM ECMP \n"
5753 "Disable PIM ECMP Rebalance\n")
5755 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5756 pim
->ecmp_rebalance_enable
= false;
5761 static int pim_cmd_igmp_start(struct vty
*vty
, struct interface
*ifp
)
5763 struct pim_interface
*pim_ifp
;
5764 uint8_t need_startup
= 0;
5766 pim_ifp
= ifp
->info
;
5769 pim_ifp
= pim_if_new(ifp
, 1 /* igmp=true */, 0 /* pim=false */);
5771 vty_out(vty
, "Could not enable IGMP on interface %s\n",
5773 return CMD_WARNING_CONFIG_FAILED
;
5777 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
5778 PIM_IF_DO_IGMP(pim_ifp
->options
);
5783 /* 'ip igmp' executed multiple times, with need_startup
5784 avoid multiple if add all and membership refresh */
5786 pim_if_addr_add_all(ifp
);
5787 pim_if_membership_refresh(ifp
);
5793 DEFUN (interface_ip_igmp
,
5794 interface_ip_igmp_cmd
,
5799 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5801 return pim_cmd_igmp_start(vty
, ifp
);
5804 DEFUN (interface_no_ip_igmp
,
5805 interface_no_ip_igmp_cmd
,
5811 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5812 struct pim_interface
*pim_ifp
= ifp
->info
;
5817 PIM_IF_DONT_IGMP(pim_ifp
->options
);
5819 pim_if_membership_clear(ifp
);
5821 pim_if_addr_del_all_igmp(ifp
);
5823 if (!PIM_IF_TEST_PIM(pim_ifp
->options
)) {
5830 DEFUN (interface_ip_igmp_join
,
5831 interface_ip_igmp_join_cmd
,
5832 "ip igmp join A.B.C.D A.B.C.D",
5835 "IGMP join multicast group\n"
5836 "Multicast group address\n"
5839 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5842 const char *group_str
;
5843 const char *source_str
;
5844 struct in_addr group_addr
;
5845 struct in_addr source_addr
;
5849 group_str
= argv
[idx_ipv4
]->arg
;
5850 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
5852 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
5853 errno
, safe_strerror(errno
));
5854 return CMD_WARNING_CONFIG_FAILED
;
5857 /* Source address */
5858 source_str
= argv
[idx_ipv4_2
]->arg
;
5859 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
5861 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
5862 source_str
, errno
, safe_strerror(errno
));
5863 return CMD_WARNING_CONFIG_FAILED
;
5866 CMD_FERR_RETURN(pim_if_igmp_join_add(ifp
, group_addr
, source_addr
),
5867 "Failure joining IGMP group: $ERR");
5872 DEFUN (interface_no_ip_igmp_join
,
5873 interface_no_ip_igmp_join_cmd
,
5874 "no ip igmp join A.B.C.D A.B.C.D",
5878 "IGMP join multicast group\n"
5879 "Multicast group address\n"
5882 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5885 const char *group_str
;
5886 const char *source_str
;
5887 struct in_addr group_addr
;
5888 struct in_addr source_addr
;
5892 group_str
= argv
[idx_ipv4
]->arg
;
5893 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
5895 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
5896 errno
, safe_strerror(errno
));
5897 return CMD_WARNING_CONFIG_FAILED
;
5900 /* Source address */
5901 source_str
= argv
[idx_ipv4_2
]->arg
;
5902 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
5904 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
5905 source_str
, errno
, safe_strerror(errno
));
5906 return CMD_WARNING_CONFIG_FAILED
;
5909 result
= pim_if_igmp_join_del(ifp
, group_addr
, source_addr
);
5912 "%% Failure leaving IGMP group %s source %s on interface %s: %d\n",
5913 group_str
, source_str
, ifp
->name
, result
);
5914 return CMD_WARNING_CONFIG_FAILED
;
5921 CLI reconfiguration affects the interface level (struct pim_interface).
5922 This function propagates the reconfiguration to every active socket
5925 static void igmp_sock_query_interval_reconfig(struct igmp_sock
*igmp
)
5927 struct interface
*ifp
;
5928 struct pim_interface
*pim_ifp
;
5932 /* other querier present? */
5934 if (igmp
->t_other_querier_timer
)
5937 /* this is the querier */
5939 zassert(igmp
->interface
);
5940 zassert(igmp
->interface
->info
);
5942 ifp
= igmp
->interface
;
5943 pim_ifp
= ifp
->info
;
5945 if (PIM_DEBUG_IGMP_TRACE
) {
5946 char ifaddr_str
[INET_ADDRSTRLEN
];
5947 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
5948 sizeof(ifaddr_str
));
5949 zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
5950 __PRETTY_FUNCTION__
, ifaddr_str
, ifp
->name
,
5951 pim_ifp
->igmp_default_query_interval
);
5955 igmp_startup_mode_on() will reset QQI:
5957 igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
5959 igmp_startup_mode_on(igmp
);
5962 static void igmp_sock_query_reschedule(struct igmp_sock
*igmp
)
5964 if (igmp
->t_igmp_query_timer
) {
5965 /* other querier present */
5966 zassert(igmp
->t_igmp_query_timer
);
5967 zassert(!igmp
->t_other_querier_timer
);
5969 pim_igmp_general_query_off(igmp
);
5970 pim_igmp_general_query_on(igmp
);
5972 zassert(igmp
->t_igmp_query_timer
);
5973 zassert(!igmp
->t_other_querier_timer
);
5975 /* this is the querier */
5977 zassert(!igmp
->t_igmp_query_timer
);
5978 zassert(igmp
->t_other_querier_timer
);
5980 pim_igmp_other_querier_timer_off(igmp
);
5981 pim_igmp_other_querier_timer_on(igmp
);
5983 zassert(!igmp
->t_igmp_query_timer
);
5984 zassert(igmp
->t_other_querier_timer
);
5988 static void change_query_interval(struct pim_interface
*pim_ifp
,
5991 struct listnode
*sock_node
;
5992 struct igmp_sock
*igmp
;
5994 pim_ifp
->igmp_default_query_interval
= query_interval
;
5996 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
5997 igmp_sock_query_interval_reconfig(igmp
);
5998 igmp_sock_query_reschedule(igmp
);
6002 static void change_query_max_response_time(struct pim_interface
*pim_ifp
,
6003 int query_max_response_time_dsec
)
6005 struct listnode
*sock_node
;
6006 struct igmp_sock
*igmp
;
6008 pim_ifp
->igmp_query_max_response_time_dsec
=
6009 query_max_response_time_dsec
;
6012 Below we modify socket/group/source timers in order to quickly
6013 reflect the change. Otherwise, those timers would eventually catch
6017 /* scan all sockets */
6018 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
6019 struct listnode
*grp_node
;
6020 struct igmp_group
*grp
;
6022 /* reschedule socket general query */
6023 igmp_sock_query_reschedule(igmp
);
6025 /* scan socket groups */
6026 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grp_node
,
6028 struct listnode
*src_node
;
6029 struct igmp_source
*src
;
6031 /* reset group timers for groups in EXCLUDE mode */
6032 if (grp
->group_filtermode_isexcl
) {
6033 igmp_group_reset_gmi(grp
);
6036 /* scan group sources */
6037 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
,
6040 /* reset source timers for sources with running
6042 if (src
->t_source_timer
) {
6043 igmp_source_reset_gmi(igmp
, grp
, src
);
6050 #define IGMP_QUERY_INTERVAL_MIN (1)
6051 #define IGMP_QUERY_INTERVAL_MAX (1800)
6053 DEFUN (interface_ip_igmp_query_interval
,
6054 interface_ip_igmp_query_interval_cmd
,
6055 "ip igmp query-interval (1-1800)",
6058 IFACE_IGMP_QUERY_INTERVAL_STR
6059 "Query interval in seconds\n")
6061 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6062 struct pim_interface
*pim_ifp
= ifp
->info
;
6064 int query_interval_dsec
;
6068 ret
= pim_cmd_igmp_start(vty
, ifp
);
6069 if (ret
!= CMD_SUCCESS
)
6071 pim_ifp
= ifp
->info
;
6074 query_interval
= atoi(argv
[3]->arg
);
6075 query_interval_dsec
= 10 * query_interval
;
6078 It seems we don't need to check bounds since command.c does it
6079 already, but we verify them anyway for extra safety.
6081 if (query_interval
< IGMP_QUERY_INTERVAL_MIN
) {
6083 "General query interval %d lower than minimum %d\n",
6084 query_interval
, IGMP_QUERY_INTERVAL_MIN
);
6085 return CMD_WARNING_CONFIG_FAILED
;
6087 if (query_interval
> IGMP_QUERY_INTERVAL_MAX
) {
6089 "General query interval %d higher than maximum %d\n",
6090 query_interval
, IGMP_QUERY_INTERVAL_MAX
);
6091 return CMD_WARNING_CONFIG_FAILED
;
6094 if (query_interval_dsec
<= pim_ifp
->igmp_query_max_response_time_dsec
) {
6096 "Can't set general query interval %d dsec <= query max response time %d dsec.\n",
6097 query_interval_dsec
,
6098 pim_ifp
->igmp_query_max_response_time_dsec
);
6099 return CMD_WARNING_CONFIG_FAILED
;
6102 change_query_interval(pim_ifp
, query_interval
);
6107 DEFUN (interface_no_ip_igmp_query_interval
,
6108 interface_no_ip_igmp_query_interval_cmd
,
6109 "no ip igmp query-interval",
6113 IFACE_IGMP_QUERY_INTERVAL_STR
)
6115 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6116 struct pim_interface
*pim_ifp
= ifp
->info
;
6117 int default_query_interval_dsec
;
6122 default_query_interval_dsec
= IGMP_GENERAL_QUERY_INTERVAL
* 10;
6124 if (default_query_interval_dsec
6125 <= pim_ifp
->igmp_query_max_response_time_dsec
) {
6127 "Can't set default general query interval %d dsec <= query max response time %d dsec.\n",
6128 default_query_interval_dsec
,
6129 pim_ifp
->igmp_query_max_response_time_dsec
);
6130 return CMD_WARNING_CONFIG_FAILED
;
6133 change_query_interval(pim_ifp
, IGMP_GENERAL_QUERY_INTERVAL
);
6138 DEFUN (interface_ip_igmp_version
,
6139 interface_ip_igmp_version_cmd
,
6140 "ip igmp version (2-3)",
6144 "IGMP version number\n")
6146 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6147 struct pim_interface
*pim_ifp
= ifp
->info
;
6148 int igmp_version
, old_version
= 0;
6152 ret
= pim_cmd_igmp_start(vty
, ifp
);
6153 if (ret
!= CMD_SUCCESS
)
6155 pim_ifp
= ifp
->info
;
6158 igmp_version
= atoi(argv
[3]->arg
);
6159 old_version
= pim_ifp
->igmp_version
;
6160 pim_ifp
->igmp_version
= igmp_version
;
6162 // Check if IGMP is Enabled otherwise, enable on interface
6163 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
6164 PIM_IF_DO_IGMP(pim_ifp
->options
);
6165 pim_if_addr_add_all(ifp
);
6166 pim_if_membership_refresh(ifp
);
6167 old_version
= igmp_version
;
6168 // avoid refreshing membership again.
6170 /* Current and new version is different refresh existing
6171 membership. Going from 3 -> 2 or 2 -> 3. */
6172 if (old_version
!= igmp_version
)
6173 pim_if_membership_refresh(ifp
);
6178 DEFUN (interface_no_ip_igmp_version
,
6179 interface_no_ip_igmp_version_cmd
,
6180 "no ip igmp version (2-3)",
6185 "IGMP version number\n")
6187 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6188 struct pim_interface
*pim_ifp
= ifp
->info
;
6193 pim_ifp
->igmp_version
= IGMP_DEFAULT_VERSION
;
6198 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
6199 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
6201 DEFUN (interface_ip_igmp_query_max_response_time
,
6202 interface_ip_igmp_query_max_response_time_cmd
,
6203 "ip igmp query-max-response-time (10-250)",
6206 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
6207 "Query response value in deci-seconds\n")
6209 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6210 struct pim_interface
*pim_ifp
= ifp
->info
;
6211 int query_max_response_time
;
6215 ret
= pim_cmd_igmp_start(vty
, ifp
);
6216 if (ret
!= CMD_SUCCESS
)
6218 pim_ifp
= ifp
->info
;
6221 query_max_response_time
= atoi(argv
[3]->arg
);
6223 if (query_max_response_time
6224 >= pim_ifp
->igmp_default_query_interval
* 10) {
6226 "Can't set query max response time %d sec >= general query interval %d sec\n",
6227 query_max_response_time
,
6228 pim_ifp
->igmp_default_query_interval
);
6229 return CMD_WARNING_CONFIG_FAILED
;
6232 change_query_max_response_time(pim_ifp
, query_max_response_time
);
6237 DEFUN (interface_no_ip_igmp_query_max_response_time
,
6238 interface_no_ip_igmp_query_max_response_time_cmd
,
6239 "no ip igmp query-max-response-time (10-250)",
6243 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
6244 "Time for response in deci-seconds\n")
6246 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6247 struct pim_interface
*pim_ifp
= ifp
->info
;
6252 change_query_max_response_time(pim_ifp
,
6253 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
6258 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
6259 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
6261 DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec
,
6262 interface_ip_igmp_query_max_response_time_dsec_cmd
,
6263 "ip igmp query-max-response-time-dsec (10-250)",
6266 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
6267 "Query response value in deciseconds\n")
6269 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6270 struct pim_interface
*pim_ifp
= ifp
->info
;
6271 int query_max_response_time_dsec
;
6272 int default_query_interval_dsec
;
6276 ret
= pim_cmd_igmp_start(vty
, ifp
);
6277 if (ret
!= CMD_SUCCESS
)
6279 pim_ifp
= ifp
->info
;
6282 query_max_response_time_dsec
= atoi(argv
[4]->arg
);
6284 default_query_interval_dsec
= 10 * pim_ifp
->igmp_default_query_interval
;
6286 if (query_max_response_time_dsec
>= default_query_interval_dsec
) {
6288 "Can't set query max response time %d dsec >= general query interval %d dsec\n",
6289 query_max_response_time_dsec
,
6290 default_query_interval_dsec
);
6291 return CMD_WARNING_CONFIG_FAILED
;
6294 change_query_max_response_time(pim_ifp
, query_max_response_time_dsec
);
6299 DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec
,
6300 interface_no_ip_igmp_query_max_response_time_dsec_cmd
,
6301 "no ip igmp query-max-response-time-dsec",
6305 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
)
6307 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6308 struct pim_interface
*pim_ifp
= ifp
->info
;
6313 change_query_max_response_time(pim_ifp
,
6314 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
6319 DEFUN (interface_ip_pim_drprio
,
6320 interface_ip_pim_drprio_cmd
,
6321 "ip pim drpriority (1-4294967295)",
6324 "Set the Designated Router Election Priority\n"
6325 "Value of the new DR Priority\n")
6327 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6329 struct pim_interface
*pim_ifp
= ifp
->info
;
6330 uint32_t old_dr_prio
;
6333 vty_out(vty
, "Please enable PIM on interface, first\n");
6334 return CMD_WARNING_CONFIG_FAILED
;
6337 old_dr_prio
= pim_ifp
->pim_dr_priority
;
6339 pim_ifp
->pim_dr_priority
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
6341 if (old_dr_prio
!= pim_ifp
->pim_dr_priority
) {
6342 if (pim_if_dr_election(ifp
))
6343 pim_hello_restart_now(ifp
);
6349 DEFUN (interface_no_ip_pim_drprio
,
6350 interface_no_ip_pim_drprio_cmd
,
6351 "no ip pim drpriority [(1-4294967295)]",
6355 "Revert the Designated Router Priority to default\n"
6356 "Old Value of the Priority\n")
6358 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6359 struct pim_interface
*pim_ifp
= ifp
->info
;
6362 vty_out(vty
, "Pim not enabled on this interface\n");
6363 return CMD_WARNING_CONFIG_FAILED
;
6366 if (pim_ifp
->pim_dr_priority
!= PIM_DEFAULT_DR_PRIORITY
) {
6367 pim_ifp
->pim_dr_priority
= PIM_DEFAULT_DR_PRIORITY
;
6368 if (pim_if_dr_election(ifp
))
6369 pim_hello_restart_now(ifp
);
6375 static int pim_cmd_interface_add(struct interface
*ifp
)
6377 struct pim_interface
*pim_ifp
= ifp
->info
;
6380 pim_ifp
= pim_if_new(ifp
, 0 /* igmp=false */, 1 /* pim=true */);
6385 PIM_IF_DO_PIM(pim_ifp
->options
);
6388 pim_if_addr_add_all(ifp
);
6389 pim_if_membership_refresh(ifp
);
6393 DEFUN_HIDDEN (interface_ip_pim_ssm
,
6394 interface_ip_pim_ssm_cmd
,
6400 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6402 if (!pim_cmd_interface_add(ifp
)) {
6403 vty_out(vty
, "Could not enable PIM SM on interface\n");
6404 return CMD_WARNING_CONFIG_FAILED
;
6408 "WARN: Enabled PIM SM on interface; configure PIM SSM "
6409 "range if needed\n");
6413 static int interface_ip_pim_helper(struct vty
*vty
)
6415 struct pim_interface
*pim_ifp
;
6417 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6419 if (!pim_cmd_interface_add(ifp
)) {
6420 vty_out(vty
, "Could not enable PIM SM on interface\n");
6421 return CMD_WARNING_CONFIG_FAILED
;
6424 pim_ifp
= ifp
->info
;
6426 pim_if_create_pimreg(pim_ifp
->pim
);
6431 DEFUN_HIDDEN (interface_ip_pim_sm
,
6432 interface_ip_pim_sm_cmd
,
6438 return interface_ip_pim_helper(vty
);
6441 DEFUN (interface_ip_pim
,
6442 interface_ip_pim_cmd
,
6447 return interface_ip_pim_helper(vty
);
6450 static int pim_cmd_interface_delete(struct interface
*ifp
)
6452 struct pim_interface
*pim_ifp
= ifp
->info
;
6457 PIM_IF_DONT_PIM(pim_ifp
->options
);
6459 pim_if_membership_clear(ifp
);
6462 pim_sock_delete() removes all neighbors from
6463 pim_ifp->pim_neighbor_list.
6465 pim_sock_delete(ifp
, "pim unconfigured on interface");
6467 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
6468 pim_if_addr_del_all(ifp
);
6475 static int interface_no_ip_pim_helper(struct vty
*vty
)
6477 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6478 if (!pim_cmd_interface_delete(ifp
)) {
6479 vty_out(vty
, "Unable to delete interface information\n");
6480 return CMD_WARNING_CONFIG_FAILED
;
6486 DEFUN_HIDDEN (interface_no_ip_pim_ssm
,
6487 interface_no_ip_pim_ssm_cmd
,
6494 return interface_no_ip_pim_helper(vty
);
6497 DEFUN_HIDDEN (interface_no_ip_pim_sm
,
6498 interface_no_ip_pim_sm_cmd
,
6505 return interface_no_ip_pim_helper(vty
);
6508 DEFUN (interface_no_ip_pim
,
6509 interface_no_ip_pim_cmd
,
6515 return interface_no_ip_pim_helper(vty
);
6519 DEFUN(interface_ip_pim_boundary_oil
,
6520 interface_ip_pim_boundary_oil_cmd
,
6521 "ip multicast boundary oil WORD",
6523 "Generic multicast configuration options\n"
6524 "Define multicast boundary\n"
6525 "Filter OIL by group using prefix list\n"
6526 "Prefix list to filter OIL with\n")
6528 VTY_DECLVAR_CONTEXT(interface
, iif
);
6529 struct pim_interface
*pim_ifp
;
6532 argv_find(argv
, argc
, "WORD", &idx
);
6534 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6536 if (pim_ifp
->boundary_oil_plist
)
6537 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
6539 pim_ifp
->boundary_oil_plist
=
6540 XSTRDUP(MTYPE_PIM_INTERFACE
, argv
[idx
]->arg
);
6542 /* Interface will be pruned from OIL on next Join */
6546 DEFUN(interface_no_ip_pim_boundary_oil
,
6547 interface_no_ip_pim_boundary_oil_cmd
,
6548 "no ip multicast boundary oil [WORD]",
6551 "Generic multicast configuration options\n"
6552 "Define multicast boundary\n"
6553 "Filter OIL by group using prefix list\n"
6554 "Prefix list to filter OIL with\n")
6556 VTY_DECLVAR_CONTEXT(interface
, iif
);
6557 struct pim_interface
*pim_ifp
;
6560 argv_find(argv
, argc
, "WORD", &idx
);
6562 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6564 if (pim_ifp
->boundary_oil_plist
)
6565 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
6570 DEFUN (interface_ip_mroute
,
6571 interface_ip_mroute_cmd
,
6572 "ip mroute INTERFACE A.B.C.D",
6574 "Add multicast route\n"
6575 "Outgoing interface name\n"
6578 VTY_DECLVAR_CONTEXT(interface
, iif
);
6579 struct pim_interface
*pim_ifp
;
6580 struct pim_instance
*pim
;
6581 int idx_interface
= 2;
6583 struct interface
*oif
;
6584 const char *oifname
;
6585 const char *grp_str
;
6586 struct in_addr grp_addr
;
6587 struct in_addr src_addr
;
6590 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6593 oifname
= argv
[idx_interface
]->arg
;
6594 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6596 vty_out(vty
, "No such interface name %s\n", oifname
);
6600 grp_str
= argv
[idx_ipv4
]->arg
;
6601 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6603 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6604 errno
, safe_strerror(errno
));
6608 src_addr
.s_addr
= INADDR_ANY
;
6610 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6611 vty_out(vty
, "Failed to add route\n");
6618 DEFUN (interface_ip_mroute_source
,
6619 interface_ip_mroute_source_cmd
,
6620 "ip mroute INTERFACE A.B.C.D A.B.C.D",
6622 "Add multicast route\n"
6623 "Outgoing interface name\n"
6627 VTY_DECLVAR_CONTEXT(interface
, iif
);
6628 struct pim_interface
*pim_ifp
;
6629 struct pim_instance
*pim
;
6630 int idx_interface
= 2;
6633 struct interface
*oif
;
6634 const char *oifname
;
6635 const char *grp_str
;
6636 struct in_addr grp_addr
;
6637 const char *src_str
;
6638 struct in_addr src_addr
;
6641 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6644 oifname
= argv
[idx_interface
]->arg
;
6645 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6647 vty_out(vty
, "No such interface name %s\n", oifname
);
6651 grp_str
= argv
[idx_ipv4
]->arg
;
6652 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6654 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6655 errno
, safe_strerror(errno
));
6659 src_str
= argv
[idx_ipv4_2
]->arg
;
6660 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
6662 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
6663 errno
, safe_strerror(errno
));
6667 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6668 vty_out(vty
, "Failed to add route\n");
6675 DEFUN (interface_no_ip_mroute
,
6676 interface_no_ip_mroute_cmd
,
6677 "no ip mroute INTERFACE A.B.C.D",
6680 "Add multicast route\n"
6681 "Outgoing interface name\n"
6684 VTY_DECLVAR_CONTEXT(interface
, iif
);
6685 struct pim_interface
*pim_ifp
;
6686 struct pim_instance
*pim
;
6687 int idx_interface
= 3;
6689 struct interface
*oif
;
6690 const char *oifname
;
6691 const char *grp_str
;
6692 struct in_addr grp_addr
;
6693 struct in_addr src_addr
;
6696 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6699 oifname
= argv
[idx_interface
]->arg
;
6700 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6702 vty_out(vty
, "No such interface name %s\n", oifname
);
6706 grp_str
= argv
[idx_ipv4
]->arg
;
6707 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6709 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6710 errno
, safe_strerror(errno
));
6714 src_addr
.s_addr
= INADDR_ANY
;
6716 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6717 vty_out(vty
, "Failed to remove route\n");
6724 DEFUN (interface_no_ip_mroute_source
,
6725 interface_no_ip_mroute_source_cmd
,
6726 "no ip mroute INTERFACE A.B.C.D A.B.C.D",
6729 "Add multicast route\n"
6730 "Outgoing interface name\n"
6734 VTY_DECLVAR_CONTEXT(interface
, iif
);
6735 struct pim_interface
*pim_ifp
;
6736 struct pim_instance
*pim
;
6737 int idx_interface
= 3;
6740 struct interface
*oif
;
6741 const char *oifname
;
6742 const char *grp_str
;
6743 struct in_addr grp_addr
;
6744 const char *src_str
;
6745 struct in_addr src_addr
;
6748 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6751 oifname
= argv
[idx_interface
]->arg
;
6752 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6754 vty_out(vty
, "No such interface name %s\n", oifname
);
6758 grp_str
= argv
[idx_ipv4
]->arg
;
6759 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6761 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6762 errno
, safe_strerror(errno
));
6766 src_str
= argv
[idx_ipv4_2
]->arg
;
6767 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
6769 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
6770 errno
, safe_strerror(errno
));
6774 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6775 vty_out(vty
, "Failed to remove route\n");
6782 DEFUN (interface_ip_pim_hello
,
6783 interface_ip_pim_hello_cmd
,
6784 "ip pim hello (1-180) [(1-180)]",
6788 IFACE_PIM_HELLO_TIME_STR
6789 IFACE_PIM_HELLO_HOLD_STR
)
6791 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6794 struct pim_interface
*pim_ifp
= ifp
->info
;
6797 if (!pim_cmd_interface_add(ifp
)) {
6798 vty_out(vty
, "Could not enable PIM SM on interface\n");
6799 return CMD_WARNING_CONFIG_FAILED
;
6803 pim_ifp
= ifp
->info
;
6804 pim_ifp
->pim_hello_period
= strtol(argv
[idx_time
]->arg
, NULL
, 10);
6806 if (argc
== idx_hold
+ 1)
6807 pim_ifp
->pim_default_holdtime
=
6808 strtol(argv
[idx_hold
]->arg
, NULL
, 10);
6813 DEFUN (interface_no_ip_pim_hello
,
6814 interface_no_ip_pim_hello_cmd
,
6815 "no ip pim hello [(1-180) (1-180)]",
6820 IFACE_PIM_HELLO_TIME_STR
6821 IFACE_PIM_HELLO_HOLD_STR
)
6823 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6824 struct pim_interface
*pim_ifp
= ifp
->info
;
6827 vty_out(vty
, "Pim not enabled on this interface\n");
6828 return CMD_WARNING_CONFIG_FAILED
;
6831 pim_ifp
->pim_hello_period
= PIM_DEFAULT_HELLO_PERIOD
;
6832 pim_ifp
->pim_default_holdtime
= -1;
6843 PIM_DO_DEBUG_IGMP_EVENTS
;
6844 PIM_DO_DEBUG_IGMP_PACKETS
;
6845 PIM_DO_DEBUG_IGMP_TRACE
;
6849 DEFUN (no_debug_igmp
,
6856 PIM_DONT_DEBUG_IGMP_EVENTS
;
6857 PIM_DONT_DEBUG_IGMP_PACKETS
;
6858 PIM_DONT_DEBUG_IGMP_TRACE
;
6863 DEFUN (debug_igmp_events
,
6864 debug_igmp_events_cmd
,
6865 "debug igmp events",
6868 DEBUG_IGMP_EVENTS_STR
)
6870 PIM_DO_DEBUG_IGMP_EVENTS
;
6874 DEFUN (no_debug_igmp_events
,
6875 no_debug_igmp_events_cmd
,
6876 "no debug igmp events",
6880 DEBUG_IGMP_EVENTS_STR
)
6882 PIM_DONT_DEBUG_IGMP_EVENTS
;
6887 DEFUN (debug_igmp_packets
,
6888 debug_igmp_packets_cmd
,
6889 "debug igmp packets",
6892 DEBUG_IGMP_PACKETS_STR
)
6894 PIM_DO_DEBUG_IGMP_PACKETS
;
6898 DEFUN (no_debug_igmp_packets
,
6899 no_debug_igmp_packets_cmd
,
6900 "no debug igmp packets",
6904 DEBUG_IGMP_PACKETS_STR
)
6906 PIM_DONT_DEBUG_IGMP_PACKETS
;
6911 DEFUN (debug_igmp_trace
,
6912 debug_igmp_trace_cmd
,
6916 DEBUG_IGMP_TRACE_STR
)
6918 PIM_DO_DEBUG_IGMP_TRACE
;
6922 DEFUN (no_debug_igmp_trace
,
6923 no_debug_igmp_trace_cmd
,
6924 "no debug igmp trace",
6928 DEBUG_IGMP_TRACE_STR
)
6930 PIM_DONT_DEBUG_IGMP_TRACE
;
6935 DEFUN (debug_mroute
,
6941 PIM_DO_DEBUG_MROUTE
;
6945 DEFUN (debug_mroute_detail
,
6946 debug_mroute_detail_cmd
,
6947 "debug mroute detail",
6952 PIM_DO_DEBUG_MROUTE_DETAIL
;
6956 DEFUN (no_debug_mroute
,
6957 no_debug_mroute_cmd
,
6963 PIM_DONT_DEBUG_MROUTE
;
6967 DEFUN (no_debug_mroute_detail
,
6968 no_debug_mroute_detail_cmd
,
6969 "no debug mroute detail",
6975 PIM_DONT_DEBUG_MROUTE_DETAIL
;
6979 DEFUN (debug_static
,
6985 PIM_DO_DEBUG_STATIC
;
6989 DEFUN (no_debug_static
,
6990 no_debug_static_cmd
,
6996 PIM_DONT_DEBUG_STATIC
;
7007 PIM_DO_DEBUG_PIM_EVENTS
;
7008 PIM_DO_DEBUG_PIM_PACKETS
;
7009 PIM_DO_DEBUG_PIM_TRACE
;
7010 PIM_DO_DEBUG_MSDP_EVENTS
;
7011 PIM_DO_DEBUG_MSDP_PACKETS
;
7015 DEFUN (no_debug_pim
,
7022 PIM_DONT_DEBUG_PIM_EVENTS
;
7023 PIM_DONT_DEBUG_PIM_PACKETS
;
7024 PIM_DONT_DEBUG_PIM_TRACE
;
7025 PIM_DONT_DEBUG_MSDP_EVENTS
;
7026 PIM_DONT_DEBUG_MSDP_PACKETS
;
7028 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
7029 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
7034 DEFUN (debug_pim_nht
,
7039 "Nexthop Tracking\n")
7041 PIM_DO_DEBUG_PIM_NHT
;
7045 DEFUN (no_debug_pim_nht
,
7046 no_debug_pim_nht_cmd
,
7051 "Nexthop Tracking\n")
7053 PIM_DONT_DEBUG_PIM_NHT
;
7057 DEFUN (debug_pim_nht_rp
,
7058 debug_pim_nht_rp_cmd
,
7062 "Nexthop Tracking\n"
7063 "RP Nexthop Tracking\n")
7065 PIM_DO_DEBUG_PIM_NHT_RP
;
7069 DEFUN (no_debug_pim_nht_rp
,
7070 no_debug_pim_nht_rp_cmd
,
7071 "no debug pim nht rp",
7075 "Nexthop Tracking\n"
7076 "RP Nexthop Tracking\n")
7078 PIM_DONT_DEBUG_PIM_NHT_RP
;
7082 DEFUN (debug_pim_events
,
7083 debug_pim_events_cmd
,
7087 DEBUG_PIM_EVENTS_STR
)
7089 PIM_DO_DEBUG_PIM_EVENTS
;
7093 DEFUN (no_debug_pim_events
,
7094 no_debug_pim_events_cmd
,
7095 "no debug pim events",
7099 DEBUG_PIM_EVENTS_STR
)
7101 PIM_DONT_DEBUG_PIM_EVENTS
;
7105 DEFUN (debug_pim_packets
,
7106 debug_pim_packets_cmd
,
7107 "debug pim packets [<hello|joins|register>]",
7110 DEBUG_PIM_PACKETS_STR
7111 DEBUG_PIM_HELLO_PACKETS_STR
7112 DEBUG_PIM_J_P_PACKETS_STR
7113 DEBUG_PIM_PIM_REG_PACKETS_STR
)
7116 if (argv_find(argv
, argc
, "hello", &idx
)) {
7117 PIM_DO_DEBUG_PIM_HELLO
;
7118 vty_out(vty
, "PIM Hello debugging is on\n");
7119 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
7120 PIM_DO_DEBUG_PIM_J_P
;
7121 vty_out(vty
, "PIM Join/Prune debugging is on\n");
7122 } else if (argv_find(argv
, argc
, "register", &idx
)) {
7123 PIM_DO_DEBUG_PIM_REG
;
7124 vty_out(vty
, "PIM Register debugging is on\n");
7126 PIM_DO_DEBUG_PIM_PACKETS
;
7127 vty_out(vty
, "PIM Packet debugging is on \n");
7132 DEFUN (no_debug_pim_packets
,
7133 no_debug_pim_packets_cmd
,
7134 "no debug pim packets [<hello|joins|register>]",
7138 DEBUG_PIM_PACKETS_STR
7139 DEBUG_PIM_HELLO_PACKETS_STR
7140 DEBUG_PIM_J_P_PACKETS_STR
7141 DEBUG_PIM_PIM_REG_PACKETS_STR
)
7144 if (argv_find(argv
, argc
, "hello", &idx
)) {
7145 PIM_DONT_DEBUG_PIM_HELLO
;
7146 vty_out(vty
, "PIM Hello debugging is off \n");
7147 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
7148 PIM_DONT_DEBUG_PIM_J_P
;
7149 vty_out(vty
, "PIM Join/Prune debugging is off \n");
7150 } else if (argv_find(argv
, argc
, "register", &idx
)) {
7151 PIM_DONT_DEBUG_PIM_REG
;
7152 vty_out(vty
, "PIM Register debugging is off\n");
7154 PIM_DONT_DEBUG_PIM_PACKETS
;
7160 DEFUN (debug_pim_packetdump_send
,
7161 debug_pim_packetdump_send_cmd
,
7162 "debug pim packet-dump send",
7165 DEBUG_PIM_PACKETDUMP_STR
7166 DEBUG_PIM_PACKETDUMP_SEND_STR
)
7168 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND
;
7172 DEFUN (no_debug_pim_packetdump_send
,
7173 no_debug_pim_packetdump_send_cmd
,
7174 "no debug pim packet-dump send",
7178 DEBUG_PIM_PACKETDUMP_STR
7179 DEBUG_PIM_PACKETDUMP_SEND_STR
)
7181 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
7185 DEFUN (debug_pim_packetdump_recv
,
7186 debug_pim_packetdump_recv_cmd
,
7187 "debug pim packet-dump receive",
7190 DEBUG_PIM_PACKETDUMP_STR
7191 DEBUG_PIM_PACKETDUMP_RECV_STR
)
7193 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV
;
7197 DEFUN (no_debug_pim_packetdump_recv
,
7198 no_debug_pim_packetdump_recv_cmd
,
7199 "no debug pim packet-dump receive",
7203 DEBUG_PIM_PACKETDUMP_STR
7204 DEBUG_PIM_PACKETDUMP_RECV_STR
)
7206 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
7210 DEFUN (debug_pim_trace
,
7211 debug_pim_trace_cmd
,
7215 DEBUG_PIM_TRACE_STR
)
7217 PIM_DO_DEBUG_PIM_TRACE
;
7221 DEFUN (debug_pim_trace_detail
,
7222 debug_pim_trace_detail_cmd
,
7223 "debug pim trace detail",
7227 "Detailed Information\n")
7229 PIM_DO_DEBUG_PIM_TRACE_DETAIL
;
7233 DEFUN (no_debug_pim_trace
,
7234 no_debug_pim_trace_cmd
,
7235 "no debug pim trace",
7239 DEBUG_PIM_TRACE_STR
)
7241 PIM_DONT_DEBUG_PIM_TRACE
;
7245 DEFUN (no_debug_pim_trace_detail
,
7246 no_debug_pim_trace_detail_cmd
,
7247 "no debug pim trace detail",
7252 "Detailed Information\n")
7254 PIM_DONT_DEBUG_PIM_TRACE_DETAIL
;
7258 DEFUN (debug_ssmpingd
,
7264 PIM_DO_DEBUG_SSMPINGD
;
7268 DEFUN (no_debug_ssmpingd
,
7269 no_debug_ssmpingd_cmd
,
7270 "no debug ssmpingd",
7275 PIM_DONT_DEBUG_SSMPINGD
;
7279 DEFUN (debug_pim_zebra
,
7280 debug_pim_zebra_cmd
,
7284 DEBUG_PIM_ZEBRA_STR
)
7290 DEFUN (no_debug_pim_zebra
,
7291 no_debug_pim_zebra_cmd
,
7292 "no debug pim zebra",
7296 DEBUG_PIM_ZEBRA_STR
)
7298 PIM_DONT_DEBUG_ZEBRA
;
7308 PIM_DO_DEBUG_MSDP_EVENTS
;
7309 PIM_DO_DEBUG_MSDP_PACKETS
;
7313 DEFUN (no_debug_msdp
,
7320 PIM_DONT_DEBUG_MSDP_EVENTS
;
7321 PIM_DONT_DEBUG_MSDP_PACKETS
;
7325 #if CONFDATE > 20190402
7326 CPP_NOTICE("bgpd: time to remove undebug commands")
7328 ALIAS_HIDDEN (no_debug_msdp
,
7331 UNDEBUG_STR DEBUG_MSDP_STR
)
7333 DEFUN (debug_msdp_events
,
7334 debug_msdp_events_cmd
,
7335 "debug msdp events",
7338 DEBUG_MSDP_EVENTS_STR
)
7340 PIM_DO_DEBUG_MSDP_EVENTS
;
7344 DEFUN (no_debug_msdp_events
,
7345 no_debug_msdp_events_cmd
,
7346 "no debug msdp events",
7350 DEBUG_MSDP_EVENTS_STR
)
7352 PIM_DONT_DEBUG_MSDP_EVENTS
;
7356 #if CONFDATE > 20190402
7357 CPP_NOTICE("bgpd: time to remove undebug commands")
7359 ALIAS_HIDDEN (no_debug_msdp_events
,
7360 undebug_msdp_events_cmd
,
7361 "undebug msdp events",
7364 DEBUG_MSDP_EVENTS_STR
)
7366 DEFUN (debug_msdp_packets
,
7367 debug_msdp_packets_cmd
,
7368 "debug msdp packets",
7371 DEBUG_MSDP_PACKETS_STR
)
7373 PIM_DO_DEBUG_MSDP_PACKETS
;
7377 DEFUN (no_debug_msdp_packets
,
7378 no_debug_msdp_packets_cmd
,
7379 "no debug msdp packets",
7383 DEBUG_MSDP_PACKETS_STR
)
7385 PIM_DONT_DEBUG_MSDP_PACKETS
;
7389 #if CONFDATE > 20190402
7390 CPP_NOTICE("bgpd: time to remove undebug commands")
7392 ALIAS_HIDDEN (no_debug_msdp_packets
,
7393 undebug_msdp_packets_cmd
,
7394 "undebug msdp packets",
7397 DEBUG_MSDP_PACKETS_STR
)
7399 DEFUN (debug_mtrace
,
7405 PIM_DO_DEBUG_MTRACE
;
7409 DEFUN (no_debug_mtrace
,
7410 no_debug_mtrace_cmd
,
7416 PIM_DONT_DEBUG_MTRACE
;
7420 DEFUN_NOSH (show_debugging_pim
,
7421 show_debugging_pim_cmd
,
7422 "show debugging [pim]",
7427 vty_out(vty
, "PIM debugging status\n");
7429 pim_debug_config_write(vty
);
7434 static int interface_pim_use_src_cmd_worker(struct vty
*vty
, const char *source
)
7437 struct in_addr source_addr
;
7438 int ret
= CMD_SUCCESS
;
7439 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7441 result
= inet_pton(AF_INET
, source
, &source_addr
);
7443 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", source
,
7444 errno
, safe_strerror(errno
));
7445 return CMD_WARNING_CONFIG_FAILED
;
7448 result
= pim_update_source_set(ifp
, source_addr
);
7452 case PIM_IFACE_NOT_FOUND
:
7453 ret
= CMD_WARNING_CONFIG_FAILED
;
7454 vty_out(vty
, "Pim not enabled on this interface\n");
7456 case PIM_UPDATE_SOURCE_DUP
:
7458 vty_out(vty
, "%% Source already set to %s\n", source
);
7461 ret
= CMD_WARNING_CONFIG_FAILED
;
7462 vty_out(vty
, "%% Source set failed\n");
7468 DEFUN (interface_pim_use_source
,
7469 interface_pim_use_source_cmd
,
7470 "ip pim use-source A.B.C.D",
7473 "Configure primary IP address\n"
7474 "source ip address\n")
7476 return interface_pim_use_src_cmd_worker(vty
, argv
[3]->arg
);
7479 DEFUN (interface_no_pim_use_source
,
7480 interface_no_pim_use_source_cmd
,
7481 "no ip pim use-source [A.B.C.D]",
7485 "Delete source IP address\n"
7486 "source ip address\n")
7488 return interface_pim_use_src_cmd_worker(vty
, "0.0.0.0");
7496 "Enables BFD support\n")
7498 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7499 struct pim_interface
*pim_ifp
= ifp
->info
;
7500 struct bfd_info
*bfd_info
= NULL
;
7503 if (!pim_cmd_interface_add(ifp
)) {
7504 vty_out(vty
, "Could not enable PIM SM on interface\n");
7508 pim_ifp
= ifp
->info
;
7510 bfd_info
= pim_ifp
->bfd_info
;
7512 if (!bfd_info
|| !CHECK_FLAG(bfd_info
->flags
, BFD_FLAG_PARAM_CFG
))
7513 pim_bfd_if_param_set(ifp
, BFD_DEF_MIN_RX
, BFD_DEF_MIN_TX
,
7514 BFD_DEF_DETECT_MULT
, 1);
7519 DEFUN (no_ip_pim_bfd
,
7525 "Disables BFD support\n")
7527 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7528 struct pim_interface
*pim_ifp
= ifp
->info
;
7531 vty_out(vty
, "Pim not enabled on this interface\n");
7535 if (pim_ifp
->bfd_info
) {
7536 pim_bfd_reg_dereg_all_nbr(ifp
, ZEBRA_BFD_DEST_DEREGISTER
);
7537 bfd_info_free(&(pim_ifp
->bfd_info
));
7547 #endif /* HAVE_BFDD */
7549 ip_pim_bfd_param_cmd
,
7550 "ip pim bfd (2-255) (50-60000) (50-60000)",
7553 "Enables BFD support\n"
7554 "Detect Multiplier\n"
7555 "Required min receive interval\n"
7556 "Desired min transmit interval\n")
7558 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7560 int idx_number_2
= 4;
7561 int idx_number_3
= 5;
7566 struct pim_interface
*pim_ifp
= ifp
->info
;
7569 if (!pim_cmd_interface_add(ifp
)) {
7570 vty_out(vty
, "Could not enable PIM SM on interface\n");
7575 if ((ret
= bfd_validate_param(
7576 vty
, argv
[idx_number
]->arg
, argv
[idx_number_2
]->arg
,
7577 argv
[idx_number_3
]->arg
, &dm_val
, &rx_val
, &tx_val
))
7581 pim_bfd_if_param_set(ifp
, rx_val
, tx_val
, dm_val
, 0);
7587 ALIAS(no_ip_pim_bfd
, no_ip_pim_bfd_param_cmd
,
7588 "no ip pim bfd (2-255) (50-60000) (50-60000)", NO_STR IP_STR PIM_STR
7589 "Enables BFD support\n"
7590 "Detect Multiplier\n"
7591 "Required min receive interval\n"
7592 "Desired min transmit interval\n")
7593 #endif /* !HAVE_BFDD */
7595 static int ip_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
7596 const char *peer
, const char *local
)
7598 enum pim_msdp_err result
;
7599 struct in_addr peer_addr
;
7600 struct in_addr local_addr
;
7601 int ret
= CMD_SUCCESS
;
7603 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
7605 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
7606 errno
, safe_strerror(errno
));
7607 return CMD_WARNING_CONFIG_FAILED
;
7610 result
= inet_pton(AF_INET
, local
, &local_addr
);
7612 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", local
,
7613 errno
, safe_strerror(errno
));
7614 return CMD_WARNING_CONFIG_FAILED
;
7617 result
= pim_msdp_peer_add(pim
, peer_addr
, local_addr
, "default",
7620 case PIM_MSDP_ERR_NONE
:
7622 case PIM_MSDP_ERR_OOM
:
7623 ret
= CMD_WARNING_CONFIG_FAILED
;
7624 vty_out(vty
, "%% Out of memory\n");
7626 case PIM_MSDP_ERR_PEER_EXISTS
:
7628 vty_out(vty
, "%% Peer exists\n");
7630 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
7631 ret
= CMD_WARNING_CONFIG_FAILED
;
7632 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
7635 ret
= CMD_WARNING_CONFIG_FAILED
;
7636 vty_out(vty
, "%% peer add failed\n");
7642 DEFUN_HIDDEN (ip_msdp_peer
,
7644 "ip msdp peer A.B.C.D source A.B.C.D",
7647 "Configure MSDP peer\n"
7649 "Source address for TCP connection\n"
7650 "local ip address\n")
7652 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7653 return ip_msdp_peer_cmd_worker(pim
, vty
, argv
[3]->arg
, argv
[5]->arg
);
7656 static int ip_no_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
7659 enum pim_msdp_err result
;
7660 struct in_addr peer_addr
;
7662 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
7664 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
7665 errno
, safe_strerror(errno
));
7666 return CMD_WARNING_CONFIG_FAILED
;
7669 result
= pim_msdp_peer_del(pim
, peer_addr
);
7671 case PIM_MSDP_ERR_NONE
:
7673 case PIM_MSDP_ERR_NO_PEER
:
7674 vty_out(vty
, "%% Peer does not exist\n");
7677 vty_out(vty
, "%% peer del failed\n");
7680 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7683 DEFUN_HIDDEN (no_ip_msdp_peer
,
7684 no_ip_msdp_peer_cmd
,
7685 "no ip msdp peer A.B.C.D",
7689 "Delete MSDP peer\n"
7690 "peer ip address\n")
7692 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7693 return ip_no_msdp_peer_cmd_worker(pim
, vty
, argv
[4]->arg
);
7696 static int ip_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
7697 struct vty
*vty
, const char *mg
,
7700 enum pim_msdp_err result
;
7701 struct in_addr mbr_ip
;
7702 int ret
= CMD_SUCCESS
;
7704 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
7706 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
7707 errno
, safe_strerror(errno
));
7708 return CMD_WARNING_CONFIG_FAILED
;
7711 result
= pim_msdp_mg_mbr_add(pim
, mg
, mbr_ip
);
7713 case PIM_MSDP_ERR_NONE
:
7715 case PIM_MSDP_ERR_OOM
:
7716 ret
= CMD_WARNING_CONFIG_FAILED
;
7717 vty_out(vty
, "%% Out of memory\n");
7719 case PIM_MSDP_ERR_MG_MBR_EXISTS
:
7721 vty_out(vty
, "%% mesh-group member exists\n");
7723 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
7724 ret
= CMD_WARNING_CONFIG_FAILED
;
7725 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
7728 ret
= CMD_WARNING_CONFIG_FAILED
;
7729 vty_out(vty
, "%% member add failed\n");
7735 DEFUN (ip_msdp_mesh_group_member
,
7736 ip_msdp_mesh_group_member_cmd
,
7737 "ip msdp mesh-group WORD member A.B.C.D",
7740 "Configure MSDP mesh-group\n"
7742 "mesh group member\n"
7743 "peer ip address\n")
7745 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7746 return ip_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[3]->arg
,
7750 static int ip_no_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
7755 enum pim_msdp_err result
;
7756 struct in_addr mbr_ip
;
7758 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
7760 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
7761 errno
, safe_strerror(errno
));
7762 return CMD_WARNING_CONFIG_FAILED
;
7765 result
= pim_msdp_mg_mbr_del(pim
, mg
, mbr_ip
);
7767 case PIM_MSDP_ERR_NONE
:
7769 case PIM_MSDP_ERR_NO_MG
:
7770 vty_out(vty
, "%% mesh-group does not exist\n");
7772 case PIM_MSDP_ERR_NO_MG_MBR
:
7773 vty_out(vty
, "%% mesh-group member does not exist\n");
7776 vty_out(vty
, "%% mesh-group member del failed\n");
7779 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7781 DEFUN (no_ip_msdp_mesh_group_member
,
7782 no_ip_msdp_mesh_group_member_cmd
,
7783 "no ip msdp mesh-group WORD member A.B.C.D",
7787 "Delete MSDP mesh-group member\n"
7789 "mesh group member\n"
7790 "peer ip address\n")
7792 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7793 return ip_no_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[4]->arg
,
7797 static int ip_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
7798 struct vty
*vty
, const char *mg
,
7801 enum pim_msdp_err result
;
7802 struct in_addr src_ip
;
7804 result
= inet_pton(AF_INET
, src
, &src_ip
);
7806 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", src
,
7807 errno
, safe_strerror(errno
));
7808 return CMD_WARNING_CONFIG_FAILED
;
7811 result
= pim_msdp_mg_src_add(pim
, mg
, src_ip
);
7813 case PIM_MSDP_ERR_NONE
:
7815 case PIM_MSDP_ERR_OOM
:
7816 vty_out(vty
, "%% Out of memory\n");
7818 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
7819 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
7822 vty_out(vty
, "%% source add failed\n");
7825 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7829 DEFUN (ip_msdp_mesh_group_source
,
7830 ip_msdp_mesh_group_source_cmd
,
7831 "ip msdp mesh-group WORD source A.B.C.D",
7834 "Configure MSDP mesh-group\n"
7836 "mesh group local address\n"
7837 "source ip address for the TCP connection\n")
7839 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7840 return ip_msdp_mesh_group_source_cmd_worker(pim
, vty
, argv
[3]->arg
,
7844 static int ip_no_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
7848 enum pim_msdp_err result
;
7850 result
= pim_msdp_mg_src_del(pim
, mg
);
7852 case PIM_MSDP_ERR_NONE
:
7854 case PIM_MSDP_ERR_NO_MG
:
7855 vty_out(vty
, "%% mesh-group does not exist\n");
7858 vty_out(vty
, "%% mesh-group source del failed\n");
7861 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7864 static int ip_no_msdp_mesh_group_cmd_worker(struct pim_instance
*pim
,
7865 struct vty
*vty
, const char *mg
)
7867 enum pim_msdp_err result
;
7869 result
= pim_msdp_mg_del(pim
, mg
);
7871 case PIM_MSDP_ERR_NONE
:
7873 case PIM_MSDP_ERR_NO_MG
:
7874 vty_out(vty
, "%% mesh-group does not exist\n");
7877 vty_out(vty
, "%% mesh-group source del failed\n");
7880 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7883 DEFUN (no_ip_msdp_mesh_group_source
,
7884 no_ip_msdp_mesh_group_source_cmd
,
7885 "no ip msdp mesh-group WORD source [A.B.C.D]",
7889 "Delete MSDP mesh-group source\n"
7891 "mesh group source\n"
7892 "mesh group local address\n")
7894 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7896 return ip_no_msdp_mesh_group_cmd_worker(pim
, vty
, argv
[6]->arg
);
7898 return ip_no_msdp_mesh_group_source_cmd_worker(pim
, vty
,
7902 static void print_empty_json_obj(struct vty
*vty
)
7905 json
= json_object_new_object();
7906 vty_out(vty
, "%s\n",
7907 json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
));
7908 json_object_free(json
);
7911 static void ip_msdp_show_mesh_group(struct pim_instance
*pim
, struct vty
*vty
,
7914 struct listnode
*mbrnode
;
7915 struct pim_msdp_mg_mbr
*mbr
;
7916 struct pim_msdp_mg
*mg
= pim
->msdp
.mg
;
7917 char mbr_str
[INET_ADDRSTRLEN
];
7918 char src_str
[INET_ADDRSTRLEN
];
7919 char state_str
[PIM_MSDP_STATE_STRLEN
];
7920 enum pim_msdp_peer_state state
;
7921 json_object
*json
= NULL
;
7922 json_object
*json_mg_row
= NULL
;
7923 json_object
*json_members
= NULL
;
7924 json_object
*json_row
= NULL
;
7928 print_empty_json_obj(vty
);
7932 pim_inet4_dump("<source?>", mg
->src_ip
, src_str
, sizeof(src_str
));
7934 json
= json_object_new_object();
7935 /* currently there is only one mesh group but we should still
7937 * it a dict with mg-name as key */
7938 json_mg_row
= json_object_new_object();
7939 json_object_string_add(json_mg_row
, "name",
7940 mg
->mesh_group_name
);
7941 json_object_string_add(json_mg_row
, "source", src_str
);
7943 vty_out(vty
, "Mesh group : %s\n", mg
->mesh_group_name
);
7944 vty_out(vty
, " Source : %s\n", src_str
);
7945 vty_out(vty
, " Member State\n");
7948 for (ALL_LIST_ELEMENTS_RO(mg
->mbr_list
, mbrnode
, mbr
)) {
7949 pim_inet4_dump("<mbr?>", mbr
->mbr_ip
, mbr_str
, sizeof(mbr_str
));
7951 state
= mbr
->mp
->state
;
7953 state
= PIM_MSDP_DISABLED
;
7955 pim_msdp_state_dump(state
, state_str
, sizeof(state_str
));
7957 json_row
= json_object_new_object();
7958 json_object_string_add(json_row
, "member", mbr_str
);
7959 json_object_string_add(json_row
, "state", state_str
);
7960 if (!json_members
) {
7961 json_members
= json_object_new_object();
7962 json_object_object_add(json_mg_row
, "members",
7965 json_object_object_add(json_members
, mbr_str
, json_row
);
7967 vty_out(vty
, " %-15s %11s\n", mbr_str
, state_str
);
7972 json_object_object_add(json
, mg
->mesh_group_name
, json_mg_row
);
7973 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
7974 json
, JSON_C_TO_STRING_PRETTY
));
7975 json_object_free(json
);
7979 DEFUN (show_ip_msdp_mesh_group
,
7980 show_ip_msdp_mesh_group_cmd
,
7981 "show ip msdp [vrf NAME] mesh-group [json]",
7986 "MSDP mesh-group information\n"
7989 bool uj
= use_json(argc
, argv
);
7991 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
7996 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
8001 DEFUN (show_ip_msdp_mesh_group_vrf_all
,
8002 show_ip_msdp_mesh_group_vrf_all_cmd
,
8003 "show ip msdp vrf all mesh-group [json]",
8008 "MSDP mesh-group information\n"
8011 bool uj
= use_json(argc
, argv
);
8017 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
8021 vty_out(vty
, " \"%s\": ", vrf
->name
);
8024 vty_out(vty
, "VRF: %s\n", vrf
->name
);
8025 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
8028 vty_out(vty
, "}\n");
8033 static void ip_msdp_show_peers(struct pim_instance
*pim
, struct vty
*vty
,
8036 struct listnode
*mpnode
;
8037 struct pim_msdp_peer
*mp
;
8038 char peer_str
[INET_ADDRSTRLEN
];
8039 char local_str
[INET_ADDRSTRLEN
];
8040 char state_str
[PIM_MSDP_STATE_STRLEN
];
8041 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
8043 json_object
*json
= NULL
;
8044 json_object
*json_row
= NULL
;
8048 json
= json_object_new_object();
8051 "Peer Local State Uptime SaCnt\n");
8054 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
8055 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
8056 now
= pim_time_monotonic_sec();
8057 pim_time_uptime(timebuf
, sizeof(timebuf
),
8060 strcpy(timebuf
, "-");
8062 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
8063 pim_inet4_dump("<local?>", mp
->local
, local_str
,
8065 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
8067 json_row
= json_object_new_object();
8068 json_object_string_add(json_row
, "peer", peer_str
);
8069 json_object_string_add(json_row
, "local", local_str
);
8070 json_object_string_add(json_row
, "state", state_str
);
8071 json_object_string_add(json_row
, "upTime", timebuf
);
8072 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
8073 json_object_object_add(json
, peer_str
, json_row
);
8075 vty_out(vty
, "%-15s %15s %11s %8s %6d\n", peer_str
,
8076 local_str
, state_str
, timebuf
, mp
->sa_cnt
);
8081 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8082 json
, JSON_C_TO_STRING_PRETTY
));
8083 json_object_free(json
);
8087 static void ip_msdp_show_peers_detail(struct pim_instance
*pim
, struct vty
*vty
,
8088 const char *peer
, bool uj
)
8090 struct listnode
*mpnode
;
8091 struct pim_msdp_peer
*mp
;
8092 char peer_str
[INET_ADDRSTRLEN
];
8093 char local_str
[INET_ADDRSTRLEN
];
8094 char state_str
[PIM_MSDP_STATE_STRLEN
];
8095 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
8096 char katimer
[PIM_MSDP_TIMER_STRLEN
];
8097 char crtimer
[PIM_MSDP_TIMER_STRLEN
];
8098 char holdtimer
[PIM_MSDP_TIMER_STRLEN
];
8100 json_object
*json
= NULL
;
8101 json_object
*json_row
= NULL
;
8104 json
= json_object_new_object();
8107 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
8108 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
8109 if (strcmp(peer
, "detail") && strcmp(peer
, peer_str
))
8112 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
8113 now
= pim_time_monotonic_sec();
8114 pim_time_uptime(timebuf
, sizeof(timebuf
),
8117 strcpy(timebuf
, "-");
8119 pim_inet4_dump("<local?>", mp
->local
, local_str
,
8121 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
8122 pim_time_timer_to_hhmmss(katimer
, sizeof(katimer
),
8124 pim_time_timer_to_hhmmss(crtimer
, sizeof(crtimer
),
8126 pim_time_timer_to_hhmmss(holdtimer
, sizeof(holdtimer
),
8130 json_row
= json_object_new_object();
8131 json_object_string_add(json_row
, "peer", peer_str
);
8132 json_object_string_add(json_row
, "local", local_str
);
8133 json_object_string_add(json_row
, "meshGroupName",
8134 mp
->mesh_group_name
);
8135 json_object_string_add(json_row
, "state", state_str
);
8136 json_object_string_add(json_row
, "upTime", timebuf
);
8137 json_object_string_add(json_row
, "keepAliveTimer",
8139 json_object_string_add(json_row
, "connRetryTimer",
8141 json_object_string_add(json_row
, "holdTimer",
8143 json_object_string_add(json_row
, "lastReset",
8145 json_object_int_add(json_row
, "connAttempts",
8147 json_object_int_add(json_row
, "establishedChanges",
8149 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
8150 json_object_int_add(json_row
, "kaSent", mp
->ka_tx_cnt
);
8151 json_object_int_add(json_row
, "kaRcvd", mp
->ka_rx_cnt
);
8152 json_object_int_add(json_row
, "saSent", mp
->sa_tx_cnt
);
8153 json_object_int_add(json_row
, "saRcvd", mp
->sa_rx_cnt
);
8154 json_object_object_add(json
, peer_str
, json_row
);
8156 vty_out(vty
, "Peer : %s\n", peer_str
);
8157 vty_out(vty
, " Local : %s\n", local_str
);
8158 vty_out(vty
, " Mesh Group : %s\n",
8159 mp
->mesh_group_name
);
8160 vty_out(vty
, " State : %s\n", state_str
);
8161 vty_out(vty
, " Uptime : %s\n", timebuf
);
8163 vty_out(vty
, " Keepalive Timer : %s\n", katimer
);
8164 vty_out(vty
, " Conn Retry Timer : %s\n", crtimer
);
8165 vty_out(vty
, " Hold Timer : %s\n", holdtimer
);
8166 vty_out(vty
, " Last Reset : %s\n",
8168 vty_out(vty
, " Conn Attempts : %d\n",
8170 vty_out(vty
, " Established Changes : %d\n",
8172 vty_out(vty
, " SA Count : %d\n",
8174 vty_out(vty
, " Statistics :\n");
8177 vty_out(vty
, " Keepalives : %10d %10d\n",
8178 mp
->ka_tx_cnt
, mp
->ka_rx_cnt
);
8179 vty_out(vty
, " SAs : %10d %10d\n",
8180 mp
->sa_tx_cnt
, mp
->sa_rx_cnt
);
8186 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8187 json
, JSON_C_TO_STRING_PRETTY
));
8188 json_object_free(json
);
8192 DEFUN (show_ip_msdp_peer_detail
,
8193 show_ip_msdp_peer_detail_cmd
,
8194 "show ip msdp [vrf NAME] peer [detail|A.B.C.D] [json]",
8199 "MSDP peer information\n"
8204 bool uj
= use_json(argc
, argv
);
8206 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
8213 if (argv_find(argv
, argc
, "detail", &idx
))
8214 arg
= argv
[idx
]->text
;
8215 else if (argv_find(argv
, argc
, "A.B.C.D", &idx
))
8216 arg
= argv
[idx
]->arg
;
8219 ip_msdp_show_peers_detail(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
8221 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
8226 DEFUN (show_ip_msdp_peer_detail_vrf_all
,
8227 show_ip_msdp_peer_detail_vrf_all_cmd
,
8228 "show ip msdp vrf all peer [detail|A.B.C.D] [json]",
8233 "MSDP peer information\n"
8239 bool uj
= use_json(argc
, argv
);
8245 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
8249 vty_out(vty
, " \"%s\": ", vrf
->name
);
8252 vty_out(vty
, "VRF: %s\n", vrf
->name
);
8253 if (argv_find(argv
, argc
, "detail", &idx
)
8254 || argv_find(argv
, argc
, "A.B.C.D", &idx
))
8255 ip_msdp_show_peers_detail(vrf
->info
, vty
,
8256 argv
[idx
]->arg
, uj
);
8258 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
8261 vty_out(vty
, "}\n");
8266 static void ip_msdp_show_sa(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
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 bool 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 bool 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 bool 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
, bool 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
, bool 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 bool 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 bool 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_pim_rp_cmd
);
8641 install_element(VRF_NODE
, &ip_pim_rp_cmd
);
8642 install_element(CONFIG_NODE
, &no_ip_pim_rp_cmd
);
8643 install_element(VRF_NODE
, &no_ip_pim_rp_cmd
);
8644 install_element(CONFIG_NODE
, &ip_pim_rp_prefix_list_cmd
);
8645 install_element(VRF_NODE
, &ip_pim_rp_prefix_list_cmd
);
8646 install_element(CONFIG_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
8647 install_element(VRF_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
8648 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
8649 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
8650 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
8651 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
8652 install_element(CONFIG_NODE
, &ip_pim_ssm_prefix_list_cmd
);
8653 install_element(VRF_NODE
, &ip_pim_ssm_prefix_list_cmd
);
8654 install_element(CONFIG_NODE
, &ip_pim_register_suppress_cmd
);
8655 install_element(VRF_NODE
, &ip_pim_register_suppress_cmd
);
8656 install_element(CONFIG_NODE
, &no_ip_pim_register_suppress_cmd
);
8657 install_element(VRF_NODE
, &no_ip_pim_register_suppress_cmd
);
8658 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
8659 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
8660 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
8661 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
8662 install_element(CONFIG_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
8663 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
8664 install_element(CONFIG_NODE
,
8665 &no_ip_pim_spt_switchover_infinity_plist_cmd
);
8666 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_plist_cmd
);
8667 install_element(CONFIG_NODE
, &ip_pim_joinprune_time_cmd
);
8668 install_element(VRF_NODE
, &ip_pim_joinprune_time_cmd
);
8669 install_element(CONFIG_NODE
, &no_ip_pim_joinprune_time_cmd
);
8670 install_element(VRF_NODE
, &no_ip_pim_joinprune_time_cmd
);
8671 install_element(CONFIG_NODE
, &ip_pim_keep_alive_cmd
);
8672 install_element(VRF_NODE
, &ip_pim_keep_alive_cmd
);
8673 install_element(CONFIG_NODE
, &ip_pim_rp_keep_alive_cmd
);
8674 install_element(VRF_NODE
, &ip_pim_rp_keep_alive_cmd
);
8675 install_element(CONFIG_NODE
, &no_ip_pim_keep_alive_cmd
);
8676 install_element(VRF_NODE
, &no_ip_pim_keep_alive_cmd
);
8677 install_element(CONFIG_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
8678 install_element(VRF_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
8679 install_element(CONFIG_NODE
, &ip_pim_packets_cmd
);
8680 install_element(VRF_NODE
, &ip_pim_packets_cmd
);
8681 install_element(CONFIG_NODE
, &no_ip_pim_packets_cmd
);
8682 install_element(VRF_NODE
, &no_ip_pim_packets_cmd
);
8683 install_element(CONFIG_NODE
, &ip_pim_v6_secondary_cmd
);
8684 install_element(VRF_NODE
, &ip_pim_v6_secondary_cmd
);
8685 install_element(CONFIG_NODE
, &no_ip_pim_v6_secondary_cmd
);
8686 install_element(VRF_NODE
, &no_ip_pim_v6_secondary_cmd
);
8687 install_element(CONFIG_NODE
, &ip_ssmpingd_cmd
);
8688 install_element(VRF_NODE
, &ip_ssmpingd_cmd
);
8689 install_element(CONFIG_NODE
, &no_ip_ssmpingd_cmd
);
8690 install_element(VRF_NODE
, &no_ip_ssmpingd_cmd
);
8691 install_element(CONFIG_NODE
, &ip_msdp_peer_cmd
);
8692 install_element(VRF_NODE
, &ip_msdp_peer_cmd
);
8693 install_element(CONFIG_NODE
, &no_ip_msdp_peer_cmd
);
8694 install_element(VRF_NODE
, &no_ip_msdp_peer_cmd
);
8695 install_element(CONFIG_NODE
, &ip_pim_ecmp_cmd
);
8696 install_element(VRF_NODE
, &ip_pim_ecmp_cmd
);
8697 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_cmd
);
8698 install_element(VRF_NODE
, &no_ip_pim_ecmp_cmd
);
8699 install_element(CONFIG_NODE
, &ip_pim_ecmp_rebalance_cmd
);
8700 install_element(VRF_NODE
, &ip_pim_ecmp_rebalance_cmd
);
8701 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
8702 install_element(VRF_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
8704 install_element(INTERFACE_NODE
, &interface_ip_igmp_cmd
);
8705 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_cmd
);
8706 install_element(INTERFACE_NODE
, &interface_ip_igmp_join_cmd
);
8707 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_join_cmd
);
8708 install_element(INTERFACE_NODE
, &interface_ip_igmp_version_cmd
);
8709 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_version_cmd
);
8710 install_element(INTERFACE_NODE
, &interface_ip_igmp_query_interval_cmd
);
8711 install_element(INTERFACE_NODE
,
8712 &interface_no_ip_igmp_query_interval_cmd
);
8713 install_element(INTERFACE_NODE
,
8714 &interface_ip_igmp_query_max_response_time_cmd
);
8715 install_element(INTERFACE_NODE
,
8716 &interface_no_ip_igmp_query_max_response_time_cmd
);
8717 install_element(INTERFACE_NODE
,
8718 &interface_ip_igmp_query_max_response_time_dsec_cmd
);
8719 install_element(INTERFACE_NODE
,
8720 &interface_no_ip_igmp_query_max_response_time_dsec_cmd
);
8721 install_element(INTERFACE_NODE
, &interface_ip_pim_ssm_cmd
);
8722 install_element(INTERFACE_NODE
, &interface_no_ip_pim_ssm_cmd
);
8723 install_element(INTERFACE_NODE
, &interface_ip_pim_sm_cmd
);
8724 install_element(INTERFACE_NODE
, &interface_no_ip_pim_sm_cmd
);
8725 install_element(INTERFACE_NODE
, &interface_ip_pim_cmd
);
8726 install_element(INTERFACE_NODE
, &interface_no_ip_pim_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 */