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 */,
5772 vty_out(vty
, "Could not enable IGMP on interface %s\n",
5774 return CMD_WARNING_CONFIG_FAILED
;
5778 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
5779 PIM_IF_DO_IGMP(pim_ifp
->options
);
5784 /* 'ip igmp' executed multiple times, with need_startup
5785 avoid multiple if add all and membership refresh */
5787 pim_if_addr_add_all(ifp
);
5788 pim_if_membership_refresh(ifp
);
5794 DEFUN (interface_ip_igmp
,
5795 interface_ip_igmp_cmd
,
5800 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5802 return pim_cmd_igmp_start(vty
, ifp
);
5805 DEFUN (interface_no_ip_igmp
,
5806 interface_no_ip_igmp_cmd
,
5812 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5813 struct pim_interface
*pim_ifp
= ifp
->info
;
5818 PIM_IF_DONT_IGMP(pim_ifp
->options
);
5820 pim_if_membership_clear(ifp
);
5822 pim_if_addr_del_all_igmp(ifp
);
5824 if (!PIM_IF_TEST_PIM(pim_ifp
->options
)) {
5831 DEFUN (interface_ip_igmp_join
,
5832 interface_ip_igmp_join_cmd
,
5833 "ip igmp join A.B.C.D A.B.C.D",
5836 "IGMP join multicast group\n"
5837 "Multicast group address\n"
5840 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5843 const char *group_str
;
5844 const char *source_str
;
5845 struct in_addr group_addr
;
5846 struct in_addr source_addr
;
5850 group_str
= argv
[idx_ipv4
]->arg
;
5851 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
5853 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
5854 errno
, safe_strerror(errno
));
5855 return CMD_WARNING_CONFIG_FAILED
;
5858 /* Source address */
5859 source_str
= argv
[idx_ipv4_2
]->arg
;
5860 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
5862 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
5863 source_str
, errno
, safe_strerror(errno
));
5864 return CMD_WARNING_CONFIG_FAILED
;
5867 CMD_FERR_RETURN(pim_if_igmp_join_add(ifp
, group_addr
, source_addr
),
5868 "Failure joining IGMP group: $ERR");
5873 DEFUN (interface_no_ip_igmp_join
,
5874 interface_no_ip_igmp_join_cmd
,
5875 "no ip igmp join A.B.C.D A.B.C.D",
5879 "IGMP join multicast group\n"
5880 "Multicast group address\n"
5883 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5886 const char *group_str
;
5887 const char *source_str
;
5888 struct in_addr group_addr
;
5889 struct in_addr source_addr
;
5893 group_str
= argv
[idx_ipv4
]->arg
;
5894 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
5896 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
5897 errno
, safe_strerror(errno
));
5898 return CMD_WARNING_CONFIG_FAILED
;
5901 /* Source address */
5902 source_str
= argv
[idx_ipv4_2
]->arg
;
5903 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
5905 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
5906 source_str
, errno
, safe_strerror(errno
));
5907 return CMD_WARNING_CONFIG_FAILED
;
5910 result
= pim_if_igmp_join_del(ifp
, group_addr
, source_addr
);
5913 "%% Failure leaving IGMP group %s source %s on interface %s: %d\n",
5914 group_str
, source_str
, ifp
->name
, result
);
5915 return CMD_WARNING_CONFIG_FAILED
;
5922 CLI reconfiguration affects the interface level (struct pim_interface).
5923 This function propagates the reconfiguration to every active socket
5926 static void igmp_sock_query_interval_reconfig(struct igmp_sock
*igmp
)
5928 struct interface
*ifp
;
5929 struct pim_interface
*pim_ifp
;
5933 /* other querier present? */
5935 if (igmp
->t_other_querier_timer
)
5938 /* this is the querier */
5940 zassert(igmp
->interface
);
5941 zassert(igmp
->interface
->info
);
5943 ifp
= igmp
->interface
;
5944 pim_ifp
= ifp
->info
;
5946 if (PIM_DEBUG_IGMP_TRACE
) {
5947 char ifaddr_str
[INET_ADDRSTRLEN
];
5948 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
5949 sizeof(ifaddr_str
));
5950 zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
5951 __PRETTY_FUNCTION__
, ifaddr_str
, ifp
->name
,
5952 pim_ifp
->igmp_default_query_interval
);
5956 igmp_startup_mode_on() will reset QQI:
5958 igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
5960 igmp_startup_mode_on(igmp
);
5963 static void igmp_sock_query_reschedule(struct igmp_sock
*igmp
)
5965 if (igmp
->t_igmp_query_timer
) {
5966 /* other querier present */
5967 zassert(igmp
->t_igmp_query_timer
);
5968 zassert(!igmp
->t_other_querier_timer
);
5970 pim_igmp_general_query_off(igmp
);
5971 pim_igmp_general_query_on(igmp
);
5973 zassert(igmp
->t_igmp_query_timer
);
5974 zassert(!igmp
->t_other_querier_timer
);
5976 /* this is the querier */
5978 zassert(!igmp
->t_igmp_query_timer
);
5979 zassert(igmp
->t_other_querier_timer
);
5981 pim_igmp_other_querier_timer_off(igmp
);
5982 pim_igmp_other_querier_timer_on(igmp
);
5984 zassert(!igmp
->t_igmp_query_timer
);
5985 zassert(igmp
->t_other_querier_timer
);
5989 static void change_query_interval(struct pim_interface
*pim_ifp
,
5992 struct listnode
*sock_node
;
5993 struct igmp_sock
*igmp
;
5995 pim_ifp
->igmp_default_query_interval
= query_interval
;
5997 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
5998 igmp_sock_query_interval_reconfig(igmp
);
5999 igmp_sock_query_reschedule(igmp
);
6003 static void change_query_max_response_time(struct pim_interface
*pim_ifp
,
6004 int query_max_response_time_dsec
)
6006 struct listnode
*sock_node
;
6007 struct igmp_sock
*igmp
;
6009 pim_ifp
->igmp_query_max_response_time_dsec
=
6010 query_max_response_time_dsec
;
6013 Below we modify socket/group/source timers in order to quickly
6014 reflect the change. Otherwise, those timers would eventually catch
6018 /* scan all sockets */
6019 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
6020 struct listnode
*grp_node
;
6021 struct igmp_group
*grp
;
6023 /* reschedule socket general query */
6024 igmp_sock_query_reschedule(igmp
);
6026 /* scan socket groups */
6027 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grp_node
,
6029 struct listnode
*src_node
;
6030 struct igmp_source
*src
;
6032 /* reset group timers for groups in EXCLUDE mode */
6033 if (grp
->group_filtermode_isexcl
) {
6034 igmp_group_reset_gmi(grp
);
6037 /* scan group sources */
6038 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
,
6041 /* reset source timers for sources with running
6043 if (src
->t_source_timer
) {
6044 igmp_source_reset_gmi(igmp
, grp
, src
);
6051 #define IGMP_QUERY_INTERVAL_MIN (1)
6052 #define IGMP_QUERY_INTERVAL_MAX (1800)
6054 DEFUN (interface_ip_igmp_query_interval
,
6055 interface_ip_igmp_query_interval_cmd
,
6056 "ip igmp query-interval (1-1800)",
6059 IFACE_IGMP_QUERY_INTERVAL_STR
6060 "Query interval in seconds\n")
6062 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6063 struct pim_interface
*pim_ifp
= ifp
->info
;
6065 int query_interval_dsec
;
6069 ret
= pim_cmd_igmp_start(vty
, ifp
);
6070 if (ret
!= CMD_SUCCESS
)
6072 pim_ifp
= ifp
->info
;
6075 query_interval
= atoi(argv
[3]->arg
);
6076 query_interval_dsec
= 10 * query_interval
;
6079 It seems we don't need to check bounds since command.c does it
6080 already, but we verify them anyway for extra safety.
6082 if (query_interval
< IGMP_QUERY_INTERVAL_MIN
) {
6084 "General query interval %d lower than minimum %d\n",
6085 query_interval
, IGMP_QUERY_INTERVAL_MIN
);
6086 return CMD_WARNING_CONFIG_FAILED
;
6088 if (query_interval
> IGMP_QUERY_INTERVAL_MAX
) {
6090 "General query interval %d higher than maximum %d\n",
6091 query_interval
, IGMP_QUERY_INTERVAL_MAX
);
6092 return CMD_WARNING_CONFIG_FAILED
;
6095 if (query_interval_dsec
<= pim_ifp
->igmp_query_max_response_time_dsec
) {
6097 "Can't set general query interval %d dsec <= query max response time %d dsec.\n",
6098 query_interval_dsec
,
6099 pim_ifp
->igmp_query_max_response_time_dsec
);
6100 return CMD_WARNING_CONFIG_FAILED
;
6103 change_query_interval(pim_ifp
, query_interval
);
6108 DEFUN (interface_no_ip_igmp_query_interval
,
6109 interface_no_ip_igmp_query_interval_cmd
,
6110 "no ip igmp query-interval",
6114 IFACE_IGMP_QUERY_INTERVAL_STR
)
6116 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6117 struct pim_interface
*pim_ifp
= ifp
->info
;
6118 int default_query_interval_dsec
;
6123 default_query_interval_dsec
= IGMP_GENERAL_QUERY_INTERVAL
* 10;
6125 if (default_query_interval_dsec
6126 <= pim_ifp
->igmp_query_max_response_time_dsec
) {
6128 "Can't set default general query interval %d dsec <= query max response time %d dsec.\n",
6129 default_query_interval_dsec
,
6130 pim_ifp
->igmp_query_max_response_time_dsec
);
6131 return CMD_WARNING_CONFIG_FAILED
;
6134 change_query_interval(pim_ifp
, IGMP_GENERAL_QUERY_INTERVAL
);
6139 DEFUN (interface_ip_igmp_version
,
6140 interface_ip_igmp_version_cmd
,
6141 "ip igmp version (2-3)",
6145 "IGMP version number\n")
6147 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6148 struct pim_interface
*pim_ifp
= ifp
->info
;
6149 int igmp_version
, old_version
= 0;
6153 ret
= pim_cmd_igmp_start(vty
, ifp
);
6154 if (ret
!= CMD_SUCCESS
)
6156 pim_ifp
= ifp
->info
;
6159 igmp_version
= atoi(argv
[3]->arg
);
6160 old_version
= pim_ifp
->igmp_version
;
6161 pim_ifp
->igmp_version
= igmp_version
;
6163 // Check if IGMP is Enabled otherwise, enable on interface
6164 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
6165 PIM_IF_DO_IGMP(pim_ifp
->options
);
6166 pim_if_addr_add_all(ifp
);
6167 pim_if_membership_refresh(ifp
);
6168 old_version
= igmp_version
;
6169 // avoid refreshing membership again.
6171 /* Current and new version is different refresh existing
6172 membership. Going from 3 -> 2 or 2 -> 3. */
6173 if (old_version
!= igmp_version
)
6174 pim_if_membership_refresh(ifp
);
6179 DEFUN (interface_no_ip_igmp_version
,
6180 interface_no_ip_igmp_version_cmd
,
6181 "no ip igmp version (2-3)",
6186 "IGMP version number\n")
6188 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6189 struct pim_interface
*pim_ifp
= ifp
->info
;
6194 pim_ifp
->igmp_version
= IGMP_DEFAULT_VERSION
;
6199 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
6200 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
6202 DEFUN (interface_ip_igmp_query_max_response_time
,
6203 interface_ip_igmp_query_max_response_time_cmd
,
6204 "ip igmp query-max-response-time (10-250)",
6207 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
6208 "Query response value in deci-seconds\n")
6210 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6211 struct pim_interface
*pim_ifp
= ifp
->info
;
6212 int query_max_response_time
;
6216 ret
= pim_cmd_igmp_start(vty
, ifp
);
6217 if (ret
!= CMD_SUCCESS
)
6219 pim_ifp
= ifp
->info
;
6222 query_max_response_time
= atoi(argv
[3]->arg
);
6224 if (query_max_response_time
6225 >= pim_ifp
->igmp_default_query_interval
* 10) {
6227 "Can't set query max response time %d sec >= general query interval %d sec\n",
6228 query_max_response_time
,
6229 pim_ifp
->igmp_default_query_interval
);
6230 return CMD_WARNING_CONFIG_FAILED
;
6233 change_query_max_response_time(pim_ifp
, query_max_response_time
);
6238 DEFUN (interface_no_ip_igmp_query_max_response_time
,
6239 interface_no_ip_igmp_query_max_response_time_cmd
,
6240 "no ip igmp query-max-response-time (10-250)",
6244 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
6245 "Time for response in deci-seconds\n")
6247 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6248 struct pim_interface
*pim_ifp
= ifp
->info
;
6253 change_query_max_response_time(pim_ifp
,
6254 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
6259 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
6260 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
6262 DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec
,
6263 interface_ip_igmp_query_max_response_time_dsec_cmd
,
6264 "ip igmp query-max-response-time-dsec (10-250)",
6267 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
6268 "Query response value in deciseconds\n")
6270 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6271 struct pim_interface
*pim_ifp
= ifp
->info
;
6272 int query_max_response_time_dsec
;
6273 int default_query_interval_dsec
;
6277 ret
= pim_cmd_igmp_start(vty
, ifp
);
6278 if (ret
!= CMD_SUCCESS
)
6280 pim_ifp
= ifp
->info
;
6283 query_max_response_time_dsec
= atoi(argv
[4]->arg
);
6285 default_query_interval_dsec
= 10 * pim_ifp
->igmp_default_query_interval
;
6287 if (query_max_response_time_dsec
>= default_query_interval_dsec
) {
6289 "Can't set query max response time %d dsec >= general query interval %d dsec\n",
6290 query_max_response_time_dsec
,
6291 default_query_interval_dsec
);
6292 return CMD_WARNING_CONFIG_FAILED
;
6295 change_query_max_response_time(pim_ifp
, query_max_response_time_dsec
);
6300 DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec
,
6301 interface_no_ip_igmp_query_max_response_time_dsec_cmd
,
6302 "no ip igmp query-max-response-time-dsec",
6306 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
)
6308 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6309 struct pim_interface
*pim_ifp
= ifp
->info
;
6314 change_query_max_response_time(pim_ifp
,
6315 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
6320 DEFUN (interface_ip_pim_drprio
,
6321 interface_ip_pim_drprio_cmd
,
6322 "ip pim drpriority (1-4294967295)",
6325 "Set the Designated Router Election Priority\n"
6326 "Value of the new DR Priority\n")
6328 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6330 struct pim_interface
*pim_ifp
= ifp
->info
;
6331 uint32_t old_dr_prio
;
6334 vty_out(vty
, "Please enable PIM on interface, first\n");
6335 return CMD_WARNING_CONFIG_FAILED
;
6338 old_dr_prio
= pim_ifp
->pim_dr_priority
;
6340 pim_ifp
->pim_dr_priority
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
6342 if (old_dr_prio
!= pim_ifp
->pim_dr_priority
) {
6343 if (pim_if_dr_election(ifp
))
6344 pim_hello_restart_now(ifp
);
6350 DEFUN (interface_no_ip_pim_drprio
,
6351 interface_no_ip_pim_drprio_cmd
,
6352 "no ip pim drpriority [(1-4294967295)]",
6356 "Revert the Designated Router Priority to default\n"
6357 "Old Value of the Priority\n")
6359 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6360 struct pim_interface
*pim_ifp
= ifp
->info
;
6363 vty_out(vty
, "Pim not enabled on this interface\n");
6364 return CMD_WARNING_CONFIG_FAILED
;
6367 if (pim_ifp
->pim_dr_priority
!= PIM_DEFAULT_DR_PRIORITY
) {
6368 pim_ifp
->pim_dr_priority
= PIM_DEFAULT_DR_PRIORITY
;
6369 if (pim_if_dr_election(ifp
))
6370 pim_hello_restart_now(ifp
);
6376 static int pim_cmd_interface_add(struct interface
*ifp
)
6378 struct pim_interface
*pim_ifp
= ifp
->info
;
6381 pim_ifp
= pim_if_new(ifp
, 0 /* igmp=false */, 1 /* pim=true */,
6387 PIM_IF_DO_PIM(pim_ifp
->options
);
6390 pim_if_addr_add_all(ifp
);
6391 pim_if_membership_refresh(ifp
);
6395 DEFUN_HIDDEN (interface_ip_pim_ssm
,
6396 interface_ip_pim_ssm_cmd
,
6402 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6404 if (!pim_cmd_interface_add(ifp
)) {
6405 vty_out(vty
, "Could not enable PIM SM on interface\n");
6406 return CMD_WARNING_CONFIG_FAILED
;
6410 "WARN: Enabled PIM SM on interface; configure PIM SSM "
6411 "range if needed\n");
6415 static int interface_ip_pim_helper(struct vty
*vty
)
6417 struct pim_interface
*pim_ifp
;
6419 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6421 if (!pim_cmd_interface_add(ifp
)) {
6422 vty_out(vty
, "Could not enable PIM SM on interface\n");
6423 return CMD_WARNING_CONFIG_FAILED
;
6426 pim_ifp
= ifp
->info
;
6428 pim_if_create_pimreg(pim_ifp
->pim
);
6433 DEFUN_HIDDEN (interface_ip_pim_sm
,
6434 interface_ip_pim_sm_cmd
,
6440 return interface_ip_pim_helper(vty
);
6443 DEFUN (interface_ip_pim
,
6444 interface_ip_pim_cmd
,
6449 return interface_ip_pim_helper(vty
);
6452 static int pim_cmd_interface_delete(struct interface
*ifp
)
6454 struct pim_interface
*pim_ifp
= ifp
->info
;
6459 PIM_IF_DONT_PIM(pim_ifp
->options
);
6461 pim_if_membership_clear(ifp
);
6464 pim_sock_delete() removes all neighbors from
6465 pim_ifp->pim_neighbor_list.
6467 pim_sock_delete(ifp
, "pim unconfigured on interface");
6469 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
6470 pim_if_addr_del_all(ifp
);
6477 static int interface_no_ip_pim_helper(struct vty
*vty
)
6479 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6480 if (!pim_cmd_interface_delete(ifp
)) {
6481 vty_out(vty
, "Unable to delete interface information\n");
6482 return CMD_WARNING_CONFIG_FAILED
;
6488 DEFUN_HIDDEN (interface_no_ip_pim_ssm
,
6489 interface_no_ip_pim_ssm_cmd
,
6496 return interface_no_ip_pim_helper(vty
);
6499 DEFUN_HIDDEN (interface_no_ip_pim_sm
,
6500 interface_no_ip_pim_sm_cmd
,
6507 return interface_no_ip_pim_helper(vty
);
6510 DEFUN (interface_no_ip_pim
,
6511 interface_no_ip_pim_cmd
,
6517 return interface_no_ip_pim_helper(vty
);
6521 DEFUN(interface_ip_pim_boundary_oil
,
6522 interface_ip_pim_boundary_oil_cmd
,
6523 "ip multicast boundary oil WORD",
6525 "Generic multicast configuration options\n"
6526 "Define multicast boundary\n"
6527 "Filter OIL by group using prefix list\n"
6528 "Prefix list to filter OIL with\n")
6530 VTY_DECLVAR_CONTEXT(interface
, iif
);
6531 struct pim_interface
*pim_ifp
;
6534 argv_find(argv
, argc
, "WORD", &idx
);
6536 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6538 if (pim_ifp
->boundary_oil_plist
)
6539 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
6541 pim_ifp
->boundary_oil_plist
=
6542 XSTRDUP(MTYPE_PIM_INTERFACE
, argv
[idx
]->arg
);
6544 /* Interface will be pruned from OIL on next Join */
6548 DEFUN(interface_no_ip_pim_boundary_oil
,
6549 interface_no_ip_pim_boundary_oil_cmd
,
6550 "no ip multicast boundary oil [WORD]",
6553 "Generic multicast configuration options\n"
6554 "Define multicast boundary\n"
6555 "Filter OIL by group using prefix list\n"
6556 "Prefix list to filter OIL with\n")
6558 VTY_DECLVAR_CONTEXT(interface
, iif
);
6559 struct pim_interface
*pim_ifp
;
6562 argv_find(argv
, argc
, "WORD", &idx
);
6564 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6566 if (pim_ifp
->boundary_oil_plist
)
6567 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
6572 DEFUN (interface_ip_mroute
,
6573 interface_ip_mroute_cmd
,
6574 "ip mroute INTERFACE A.B.C.D",
6576 "Add multicast route\n"
6577 "Outgoing interface name\n"
6580 VTY_DECLVAR_CONTEXT(interface
, iif
);
6581 struct pim_interface
*pim_ifp
;
6582 struct pim_instance
*pim
;
6583 int idx_interface
= 2;
6585 struct interface
*oif
;
6586 const char *oifname
;
6587 const char *grp_str
;
6588 struct in_addr grp_addr
;
6589 struct in_addr src_addr
;
6592 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6595 oifname
= argv
[idx_interface
]->arg
;
6596 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6598 vty_out(vty
, "No such interface name %s\n", oifname
);
6602 grp_str
= argv
[idx_ipv4
]->arg
;
6603 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6605 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6606 errno
, safe_strerror(errno
));
6610 src_addr
.s_addr
= INADDR_ANY
;
6612 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6613 vty_out(vty
, "Failed to add route\n");
6620 DEFUN (interface_ip_mroute_source
,
6621 interface_ip_mroute_source_cmd
,
6622 "ip mroute INTERFACE A.B.C.D A.B.C.D",
6624 "Add multicast route\n"
6625 "Outgoing interface name\n"
6629 VTY_DECLVAR_CONTEXT(interface
, iif
);
6630 struct pim_interface
*pim_ifp
;
6631 struct pim_instance
*pim
;
6632 int idx_interface
= 2;
6635 struct interface
*oif
;
6636 const char *oifname
;
6637 const char *grp_str
;
6638 struct in_addr grp_addr
;
6639 const char *src_str
;
6640 struct in_addr src_addr
;
6643 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6646 oifname
= argv
[idx_interface
]->arg
;
6647 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6649 vty_out(vty
, "No such interface name %s\n", oifname
);
6653 grp_str
= argv
[idx_ipv4
]->arg
;
6654 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6656 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6657 errno
, safe_strerror(errno
));
6661 src_str
= argv
[idx_ipv4_2
]->arg
;
6662 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
6664 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
6665 errno
, safe_strerror(errno
));
6669 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6670 vty_out(vty
, "Failed to add route\n");
6677 DEFUN (interface_no_ip_mroute
,
6678 interface_no_ip_mroute_cmd
,
6679 "no ip mroute INTERFACE A.B.C.D",
6682 "Add multicast route\n"
6683 "Outgoing interface name\n"
6686 VTY_DECLVAR_CONTEXT(interface
, iif
);
6687 struct pim_interface
*pim_ifp
;
6688 struct pim_instance
*pim
;
6689 int idx_interface
= 3;
6691 struct interface
*oif
;
6692 const char *oifname
;
6693 const char *grp_str
;
6694 struct in_addr grp_addr
;
6695 struct in_addr src_addr
;
6698 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6701 oifname
= argv
[idx_interface
]->arg
;
6702 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6704 vty_out(vty
, "No such interface name %s\n", oifname
);
6708 grp_str
= argv
[idx_ipv4
]->arg
;
6709 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6711 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6712 errno
, safe_strerror(errno
));
6716 src_addr
.s_addr
= INADDR_ANY
;
6718 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6719 vty_out(vty
, "Failed to remove route\n");
6726 DEFUN (interface_no_ip_mroute_source
,
6727 interface_no_ip_mroute_source_cmd
,
6728 "no ip mroute INTERFACE A.B.C.D A.B.C.D",
6731 "Add multicast route\n"
6732 "Outgoing interface name\n"
6736 VTY_DECLVAR_CONTEXT(interface
, iif
);
6737 struct pim_interface
*pim_ifp
;
6738 struct pim_instance
*pim
;
6739 int idx_interface
= 3;
6742 struct interface
*oif
;
6743 const char *oifname
;
6744 const char *grp_str
;
6745 struct in_addr grp_addr
;
6746 const char *src_str
;
6747 struct in_addr src_addr
;
6750 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6753 oifname
= argv
[idx_interface
]->arg
;
6754 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6756 vty_out(vty
, "No such interface name %s\n", oifname
);
6760 grp_str
= argv
[idx_ipv4
]->arg
;
6761 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6763 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6764 errno
, safe_strerror(errno
));
6768 src_str
= argv
[idx_ipv4_2
]->arg
;
6769 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
6771 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
6772 errno
, safe_strerror(errno
));
6776 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6777 vty_out(vty
, "Failed to remove route\n");
6784 DEFUN (interface_ip_pim_hello
,
6785 interface_ip_pim_hello_cmd
,
6786 "ip pim hello (1-180) [(1-180)]",
6790 IFACE_PIM_HELLO_TIME_STR
6791 IFACE_PIM_HELLO_HOLD_STR
)
6793 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6796 struct pim_interface
*pim_ifp
= ifp
->info
;
6799 if (!pim_cmd_interface_add(ifp
)) {
6800 vty_out(vty
, "Could not enable PIM SM on interface\n");
6801 return CMD_WARNING_CONFIG_FAILED
;
6805 pim_ifp
= ifp
->info
;
6806 pim_ifp
->pim_hello_period
= strtol(argv
[idx_time
]->arg
, NULL
, 10);
6808 if (argc
== idx_hold
+ 1)
6809 pim_ifp
->pim_default_holdtime
=
6810 strtol(argv
[idx_hold
]->arg
, NULL
, 10);
6815 DEFUN (interface_no_ip_pim_hello
,
6816 interface_no_ip_pim_hello_cmd
,
6817 "no ip pim hello [(1-180) (1-180)]",
6822 IFACE_PIM_HELLO_TIME_STR
6823 IFACE_PIM_HELLO_HOLD_STR
)
6825 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6826 struct pim_interface
*pim_ifp
= ifp
->info
;
6829 vty_out(vty
, "Pim not enabled on this interface\n");
6830 return CMD_WARNING_CONFIG_FAILED
;
6833 pim_ifp
->pim_hello_period
= PIM_DEFAULT_HELLO_PERIOD
;
6834 pim_ifp
->pim_default_holdtime
= -1;
6845 PIM_DO_DEBUG_IGMP_EVENTS
;
6846 PIM_DO_DEBUG_IGMP_PACKETS
;
6847 PIM_DO_DEBUG_IGMP_TRACE
;
6851 DEFUN (no_debug_igmp
,
6858 PIM_DONT_DEBUG_IGMP_EVENTS
;
6859 PIM_DONT_DEBUG_IGMP_PACKETS
;
6860 PIM_DONT_DEBUG_IGMP_TRACE
;
6865 DEFUN (debug_igmp_events
,
6866 debug_igmp_events_cmd
,
6867 "debug igmp events",
6870 DEBUG_IGMP_EVENTS_STR
)
6872 PIM_DO_DEBUG_IGMP_EVENTS
;
6876 DEFUN (no_debug_igmp_events
,
6877 no_debug_igmp_events_cmd
,
6878 "no debug igmp events",
6882 DEBUG_IGMP_EVENTS_STR
)
6884 PIM_DONT_DEBUG_IGMP_EVENTS
;
6889 DEFUN (debug_igmp_packets
,
6890 debug_igmp_packets_cmd
,
6891 "debug igmp packets",
6894 DEBUG_IGMP_PACKETS_STR
)
6896 PIM_DO_DEBUG_IGMP_PACKETS
;
6900 DEFUN (no_debug_igmp_packets
,
6901 no_debug_igmp_packets_cmd
,
6902 "no debug igmp packets",
6906 DEBUG_IGMP_PACKETS_STR
)
6908 PIM_DONT_DEBUG_IGMP_PACKETS
;
6913 DEFUN (debug_igmp_trace
,
6914 debug_igmp_trace_cmd
,
6918 DEBUG_IGMP_TRACE_STR
)
6920 PIM_DO_DEBUG_IGMP_TRACE
;
6924 DEFUN (no_debug_igmp_trace
,
6925 no_debug_igmp_trace_cmd
,
6926 "no debug igmp trace",
6930 DEBUG_IGMP_TRACE_STR
)
6932 PIM_DONT_DEBUG_IGMP_TRACE
;
6937 DEFUN (debug_mroute
,
6943 PIM_DO_DEBUG_MROUTE
;
6947 DEFUN (debug_mroute_detail
,
6948 debug_mroute_detail_cmd
,
6949 "debug mroute detail",
6954 PIM_DO_DEBUG_MROUTE_DETAIL
;
6958 DEFUN (no_debug_mroute
,
6959 no_debug_mroute_cmd
,
6965 PIM_DONT_DEBUG_MROUTE
;
6969 DEFUN (no_debug_mroute_detail
,
6970 no_debug_mroute_detail_cmd
,
6971 "no debug mroute detail",
6977 PIM_DONT_DEBUG_MROUTE_DETAIL
;
6981 DEFUN (debug_static
,
6987 PIM_DO_DEBUG_STATIC
;
6991 DEFUN (no_debug_static
,
6992 no_debug_static_cmd
,
6998 PIM_DONT_DEBUG_STATIC
;
7009 PIM_DO_DEBUG_PIM_EVENTS
;
7010 PIM_DO_DEBUG_PIM_PACKETS
;
7011 PIM_DO_DEBUG_PIM_TRACE
;
7012 PIM_DO_DEBUG_MSDP_EVENTS
;
7013 PIM_DO_DEBUG_MSDP_PACKETS
;
7017 DEFUN (no_debug_pim
,
7024 PIM_DONT_DEBUG_PIM_EVENTS
;
7025 PIM_DONT_DEBUG_PIM_PACKETS
;
7026 PIM_DONT_DEBUG_PIM_TRACE
;
7027 PIM_DONT_DEBUG_MSDP_EVENTS
;
7028 PIM_DONT_DEBUG_MSDP_PACKETS
;
7030 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
7031 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
7036 DEFUN (debug_pim_nht
,
7041 "Nexthop Tracking\n")
7043 PIM_DO_DEBUG_PIM_NHT
;
7047 DEFUN (no_debug_pim_nht
,
7048 no_debug_pim_nht_cmd
,
7053 "Nexthop Tracking\n")
7055 PIM_DONT_DEBUG_PIM_NHT
;
7059 DEFUN (debug_pim_nht_rp
,
7060 debug_pim_nht_rp_cmd
,
7064 "Nexthop Tracking\n"
7065 "RP Nexthop Tracking\n")
7067 PIM_DO_DEBUG_PIM_NHT_RP
;
7071 DEFUN (no_debug_pim_nht_rp
,
7072 no_debug_pim_nht_rp_cmd
,
7073 "no debug pim nht rp",
7077 "Nexthop Tracking\n"
7078 "RP Nexthop Tracking\n")
7080 PIM_DONT_DEBUG_PIM_NHT_RP
;
7084 DEFUN (debug_pim_events
,
7085 debug_pim_events_cmd
,
7089 DEBUG_PIM_EVENTS_STR
)
7091 PIM_DO_DEBUG_PIM_EVENTS
;
7095 DEFUN (no_debug_pim_events
,
7096 no_debug_pim_events_cmd
,
7097 "no debug pim events",
7101 DEBUG_PIM_EVENTS_STR
)
7103 PIM_DONT_DEBUG_PIM_EVENTS
;
7107 DEFUN (debug_pim_packets
,
7108 debug_pim_packets_cmd
,
7109 "debug pim packets [<hello|joins|register>]",
7112 DEBUG_PIM_PACKETS_STR
7113 DEBUG_PIM_HELLO_PACKETS_STR
7114 DEBUG_PIM_J_P_PACKETS_STR
7115 DEBUG_PIM_PIM_REG_PACKETS_STR
)
7118 if (argv_find(argv
, argc
, "hello", &idx
)) {
7119 PIM_DO_DEBUG_PIM_HELLO
;
7120 vty_out(vty
, "PIM Hello debugging is on\n");
7121 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
7122 PIM_DO_DEBUG_PIM_J_P
;
7123 vty_out(vty
, "PIM Join/Prune debugging is on\n");
7124 } else if (argv_find(argv
, argc
, "register", &idx
)) {
7125 PIM_DO_DEBUG_PIM_REG
;
7126 vty_out(vty
, "PIM Register debugging is on\n");
7128 PIM_DO_DEBUG_PIM_PACKETS
;
7129 vty_out(vty
, "PIM Packet debugging is on \n");
7134 DEFUN (no_debug_pim_packets
,
7135 no_debug_pim_packets_cmd
,
7136 "no debug pim packets [<hello|joins|register>]",
7140 DEBUG_PIM_PACKETS_STR
7141 DEBUG_PIM_HELLO_PACKETS_STR
7142 DEBUG_PIM_J_P_PACKETS_STR
7143 DEBUG_PIM_PIM_REG_PACKETS_STR
)
7146 if (argv_find(argv
, argc
, "hello", &idx
)) {
7147 PIM_DONT_DEBUG_PIM_HELLO
;
7148 vty_out(vty
, "PIM Hello debugging is off \n");
7149 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
7150 PIM_DONT_DEBUG_PIM_J_P
;
7151 vty_out(vty
, "PIM Join/Prune debugging is off \n");
7152 } else if (argv_find(argv
, argc
, "register", &idx
)) {
7153 PIM_DONT_DEBUG_PIM_REG
;
7154 vty_out(vty
, "PIM Register debugging is off\n");
7156 PIM_DONT_DEBUG_PIM_PACKETS
;
7162 DEFUN (debug_pim_packetdump_send
,
7163 debug_pim_packetdump_send_cmd
,
7164 "debug pim packet-dump send",
7167 DEBUG_PIM_PACKETDUMP_STR
7168 DEBUG_PIM_PACKETDUMP_SEND_STR
)
7170 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND
;
7174 DEFUN (no_debug_pim_packetdump_send
,
7175 no_debug_pim_packetdump_send_cmd
,
7176 "no debug pim packet-dump send",
7180 DEBUG_PIM_PACKETDUMP_STR
7181 DEBUG_PIM_PACKETDUMP_SEND_STR
)
7183 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
7187 DEFUN (debug_pim_packetdump_recv
,
7188 debug_pim_packetdump_recv_cmd
,
7189 "debug pim packet-dump receive",
7192 DEBUG_PIM_PACKETDUMP_STR
7193 DEBUG_PIM_PACKETDUMP_RECV_STR
)
7195 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV
;
7199 DEFUN (no_debug_pim_packetdump_recv
,
7200 no_debug_pim_packetdump_recv_cmd
,
7201 "no debug pim packet-dump receive",
7205 DEBUG_PIM_PACKETDUMP_STR
7206 DEBUG_PIM_PACKETDUMP_RECV_STR
)
7208 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
7212 DEFUN (debug_pim_trace
,
7213 debug_pim_trace_cmd
,
7217 DEBUG_PIM_TRACE_STR
)
7219 PIM_DO_DEBUG_PIM_TRACE
;
7223 DEFUN (debug_pim_trace_detail
,
7224 debug_pim_trace_detail_cmd
,
7225 "debug pim trace detail",
7229 "Detailed Information\n")
7231 PIM_DO_DEBUG_PIM_TRACE_DETAIL
;
7235 DEFUN (no_debug_pim_trace
,
7236 no_debug_pim_trace_cmd
,
7237 "no debug pim trace",
7241 DEBUG_PIM_TRACE_STR
)
7243 PIM_DONT_DEBUG_PIM_TRACE
;
7247 DEFUN (no_debug_pim_trace_detail
,
7248 no_debug_pim_trace_detail_cmd
,
7249 "no debug pim trace detail",
7254 "Detailed Information\n")
7256 PIM_DONT_DEBUG_PIM_TRACE_DETAIL
;
7260 DEFUN (debug_ssmpingd
,
7266 PIM_DO_DEBUG_SSMPINGD
;
7270 DEFUN (no_debug_ssmpingd
,
7271 no_debug_ssmpingd_cmd
,
7272 "no debug ssmpingd",
7277 PIM_DONT_DEBUG_SSMPINGD
;
7281 DEFUN (debug_pim_zebra
,
7282 debug_pim_zebra_cmd
,
7286 DEBUG_PIM_ZEBRA_STR
)
7292 DEFUN (no_debug_pim_zebra
,
7293 no_debug_pim_zebra_cmd
,
7294 "no debug pim zebra",
7298 DEBUG_PIM_ZEBRA_STR
)
7300 PIM_DONT_DEBUG_ZEBRA
;
7310 PIM_DO_DEBUG_MSDP_EVENTS
;
7311 PIM_DO_DEBUG_MSDP_PACKETS
;
7315 DEFUN (no_debug_msdp
,
7322 PIM_DONT_DEBUG_MSDP_EVENTS
;
7323 PIM_DONT_DEBUG_MSDP_PACKETS
;
7327 #if CONFDATE > 20190402
7328 CPP_NOTICE("bgpd: time to remove undebug commands")
7330 ALIAS_HIDDEN (no_debug_msdp
,
7333 UNDEBUG_STR DEBUG_MSDP_STR
)
7335 DEFUN (debug_msdp_events
,
7336 debug_msdp_events_cmd
,
7337 "debug msdp events",
7340 DEBUG_MSDP_EVENTS_STR
)
7342 PIM_DO_DEBUG_MSDP_EVENTS
;
7346 DEFUN (no_debug_msdp_events
,
7347 no_debug_msdp_events_cmd
,
7348 "no debug msdp events",
7352 DEBUG_MSDP_EVENTS_STR
)
7354 PIM_DONT_DEBUG_MSDP_EVENTS
;
7358 #if CONFDATE > 20190402
7359 CPP_NOTICE("bgpd: time to remove undebug commands")
7361 ALIAS_HIDDEN (no_debug_msdp_events
,
7362 undebug_msdp_events_cmd
,
7363 "undebug msdp events",
7366 DEBUG_MSDP_EVENTS_STR
)
7368 DEFUN (debug_msdp_packets
,
7369 debug_msdp_packets_cmd
,
7370 "debug msdp packets",
7373 DEBUG_MSDP_PACKETS_STR
)
7375 PIM_DO_DEBUG_MSDP_PACKETS
;
7379 DEFUN (no_debug_msdp_packets
,
7380 no_debug_msdp_packets_cmd
,
7381 "no debug msdp packets",
7385 DEBUG_MSDP_PACKETS_STR
)
7387 PIM_DONT_DEBUG_MSDP_PACKETS
;
7391 #if CONFDATE > 20190402
7392 CPP_NOTICE("bgpd: time to remove undebug commands")
7394 ALIAS_HIDDEN (no_debug_msdp_packets
,
7395 undebug_msdp_packets_cmd
,
7396 "undebug msdp packets",
7399 DEBUG_MSDP_PACKETS_STR
)
7401 DEFUN (debug_mtrace
,
7407 PIM_DO_DEBUG_MTRACE
;
7411 DEFUN (no_debug_mtrace
,
7412 no_debug_mtrace_cmd
,
7418 PIM_DONT_DEBUG_MTRACE
;
7422 DEFUN_NOSH (show_debugging_pim
,
7423 show_debugging_pim_cmd
,
7424 "show debugging [pim]",
7429 vty_out(vty
, "PIM debugging status\n");
7431 pim_debug_config_write(vty
);
7436 static int interface_pim_use_src_cmd_worker(struct vty
*vty
, const char *source
)
7439 struct in_addr source_addr
;
7440 int ret
= CMD_SUCCESS
;
7441 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7443 result
= inet_pton(AF_INET
, source
, &source_addr
);
7445 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", source
,
7446 errno
, safe_strerror(errno
));
7447 return CMD_WARNING_CONFIG_FAILED
;
7450 result
= pim_update_source_set(ifp
, source_addr
);
7454 case PIM_IFACE_NOT_FOUND
:
7455 ret
= CMD_WARNING_CONFIG_FAILED
;
7456 vty_out(vty
, "Pim not enabled on this interface\n");
7458 case PIM_UPDATE_SOURCE_DUP
:
7460 vty_out(vty
, "%% Source already set to %s\n", source
);
7463 ret
= CMD_WARNING_CONFIG_FAILED
;
7464 vty_out(vty
, "%% Source set failed\n");
7470 DEFUN (interface_pim_use_source
,
7471 interface_pim_use_source_cmd
,
7472 "ip pim use-source A.B.C.D",
7475 "Configure primary IP address\n"
7476 "source ip address\n")
7478 return interface_pim_use_src_cmd_worker(vty
, argv
[3]->arg
);
7481 DEFUN (interface_no_pim_use_source
,
7482 interface_no_pim_use_source_cmd
,
7483 "no ip pim use-source [A.B.C.D]",
7487 "Delete source IP address\n"
7488 "source ip address\n")
7490 return interface_pim_use_src_cmd_worker(vty
, "0.0.0.0");
7498 "Enables BFD support\n")
7500 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7501 struct pim_interface
*pim_ifp
= ifp
->info
;
7502 struct bfd_info
*bfd_info
= NULL
;
7505 if (!pim_cmd_interface_add(ifp
)) {
7506 vty_out(vty
, "Could not enable PIM SM on interface\n");
7510 pim_ifp
= ifp
->info
;
7512 bfd_info
= pim_ifp
->bfd_info
;
7514 if (!bfd_info
|| !CHECK_FLAG(bfd_info
->flags
, BFD_FLAG_PARAM_CFG
))
7515 pim_bfd_if_param_set(ifp
, BFD_DEF_MIN_RX
, BFD_DEF_MIN_TX
,
7516 BFD_DEF_DETECT_MULT
, 1);
7521 DEFUN (no_ip_pim_bfd
,
7527 "Disables BFD support\n")
7529 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7530 struct pim_interface
*pim_ifp
= ifp
->info
;
7533 vty_out(vty
, "Pim not enabled on this interface\n");
7537 if (pim_ifp
->bfd_info
) {
7538 pim_bfd_reg_dereg_all_nbr(ifp
, ZEBRA_BFD_DEST_DEREGISTER
);
7539 bfd_info_free(&(pim_ifp
->bfd_info
));
7549 #endif /* HAVE_BFDD */
7551 ip_pim_bfd_param_cmd
,
7552 "ip pim bfd (2-255) (50-60000) (50-60000)",
7555 "Enables BFD support\n"
7556 "Detect Multiplier\n"
7557 "Required min receive interval\n"
7558 "Desired min transmit interval\n")
7560 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7562 int idx_number_2
= 4;
7563 int idx_number_3
= 5;
7568 struct pim_interface
*pim_ifp
= ifp
->info
;
7571 if (!pim_cmd_interface_add(ifp
)) {
7572 vty_out(vty
, "Could not enable PIM SM on interface\n");
7577 if ((ret
= bfd_validate_param(
7578 vty
, argv
[idx_number
]->arg
, argv
[idx_number_2
]->arg
,
7579 argv
[idx_number_3
]->arg
, &dm_val
, &rx_val
, &tx_val
))
7583 pim_bfd_if_param_set(ifp
, rx_val
, tx_val
, dm_val
, 0);
7589 ALIAS(no_ip_pim_bfd
, no_ip_pim_bfd_param_cmd
,
7590 "no ip pim bfd (2-255) (50-60000) (50-60000)", NO_STR IP_STR PIM_STR
7591 "Enables BFD support\n"
7592 "Detect Multiplier\n"
7593 "Required min receive interval\n"
7594 "Desired min transmit interval\n")
7595 #endif /* !HAVE_BFDD */
7597 static int ip_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
7598 const char *peer
, const char *local
)
7600 enum pim_msdp_err result
;
7601 struct in_addr peer_addr
;
7602 struct in_addr local_addr
;
7603 int ret
= CMD_SUCCESS
;
7605 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
7607 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
7608 errno
, safe_strerror(errno
));
7609 return CMD_WARNING_CONFIG_FAILED
;
7612 result
= inet_pton(AF_INET
, local
, &local_addr
);
7614 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", local
,
7615 errno
, safe_strerror(errno
));
7616 return CMD_WARNING_CONFIG_FAILED
;
7619 result
= pim_msdp_peer_add(pim
, peer_addr
, local_addr
, "default",
7622 case PIM_MSDP_ERR_NONE
:
7624 case PIM_MSDP_ERR_OOM
:
7625 ret
= CMD_WARNING_CONFIG_FAILED
;
7626 vty_out(vty
, "%% Out of memory\n");
7628 case PIM_MSDP_ERR_PEER_EXISTS
:
7630 vty_out(vty
, "%% Peer exists\n");
7632 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
7633 ret
= CMD_WARNING_CONFIG_FAILED
;
7634 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
7637 ret
= CMD_WARNING_CONFIG_FAILED
;
7638 vty_out(vty
, "%% peer add failed\n");
7644 DEFUN_HIDDEN (ip_msdp_peer
,
7646 "ip msdp peer A.B.C.D source A.B.C.D",
7649 "Configure MSDP peer\n"
7651 "Source address for TCP connection\n"
7652 "local ip address\n")
7654 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7655 return ip_msdp_peer_cmd_worker(pim
, vty
, argv
[3]->arg
, argv
[5]->arg
);
7658 static int ip_no_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
7661 enum pim_msdp_err result
;
7662 struct in_addr peer_addr
;
7664 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
7666 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
7667 errno
, safe_strerror(errno
));
7668 return CMD_WARNING_CONFIG_FAILED
;
7671 result
= pim_msdp_peer_del(pim
, peer_addr
);
7673 case PIM_MSDP_ERR_NONE
:
7675 case PIM_MSDP_ERR_NO_PEER
:
7676 vty_out(vty
, "%% Peer does not exist\n");
7679 vty_out(vty
, "%% peer del failed\n");
7682 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7685 DEFUN_HIDDEN (no_ip_msdp_peer
,
7686 no_ip_msdp_peer_cmd
,
7687 "no ip msdp peer A.B.C.D",
7691 "Delete MSDP peer\n"
7692 "peer ip address\n")
7694 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7695 return ip_no_msdp_peer_cmd_worker(pim
, vty
, argv
[4]->arg
);
7698 static int ip_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
7699 struct vty
*vty
, const char *mg
,
7702 enum pim_msdp_err result
;
7703 struct in_addr mbr_ip
;
7704 int ret
= CMD_SUCCESS
;
7706 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
7708 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
7709 errno
, safe_strerror(errno
));
7710 return CMD_WARNING_CONFIG_FAILED
;
7713 result
= pim_msdp_mg_mbr_add(pim
, mg
, mbr_ip
);
7715 case PIM_MSDP_ERR_NONE
:
7717 case PIM_MSDP_ERR_OOM
:
7718 ret
= CMD_WARNING_CONFIG_FAILED
;
7719 vty_out(vty
, "%% Out of memory\n");
7721 case PIM_MSDP_ERR_MG_MBR_EXISTS
:
7723 vty_out(vty
, "%% mesh-group member exists\n");
7725 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
7726 ret
= CMD_WARNING_CONFIG_FAILED
;
7727 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
7730 ret
= CMD_WARNING_CONFIG_FAILED
;
7731 vty_out(vty
, "%% member add failed\n");
7737 DEFUN (ip_msdp_mesh_group_member
,
7738 ip_msdp_mesh_group_member_cmd
,
7739 "ip msdp mesh-group WORD member A.B.C.D",
7742 "Configure MSDP mesh-group\n"
7744 "mesh group member\n"
7745 "peer ip address\n")
7747 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7748 return ip_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[3]->arg
,
7752 static int ip_no_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
7757 enum pim_msdp_err result
;
7758 struct in_addr mbr_ip
;
7760 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
7762 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
7763 errno
, safe_strerror(errno
));
7764 return CMD_WARNING_CONFIG_FAILED
;
7767 result
= pim_msdp_mg_mbr_del(pim
, mg
, mbr_ip
);
7769 case PIM_MSDP_ERR_NONE
:
7771 case PIM_MSDP_ERR_NO_MG
:
7772 vty_out(vty
, "%% mesh-group does not exist\n");
7774 case PIM_MSDP_ERR_NO_MG_MBR
:
7775 vty_out(vty
, "%% mesh-group member does not exist\n");
7778 vty_out(vty
, "%% mesh-group member del failed\n");
7781 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7783 DEFUN (no_ip_msdp_mesh_group_member
,
7784 no_ip_msdp_mesh_group_member_cmd
,
7785 "no ip msdp mesh-group WORD member A.B.C.D",
7789 "Delete MSDP mesh-group member\n"
7791 "mesh group member\n"
7792 "peer ip address\n")
7794 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7795 return ip_no_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[4]->arg
,
7799 static int ip_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
7800 struct vty
*vty
, const char *mg
,
7803 enum pim_msdp_err result
;
7804 struct in_addr src_ip
;
7806 result
= inet_pton(AF_INET
, src
, &src_ip
);
7808 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", src
,
7809 errno
, safe_strerror(errno
));
7810 return CMD_WARNING_CONFIG_FAILED
;
7813 result
= pim_msdp_mg_src_add(pim
, mg
, src_ip
);
7815 case PIM_MSDP_ERR_NONE
:
7817 case PIM_MSDP_ERR_OOM
:
7818 vty_out(vty
, "%% Out of memory\n");
7820 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
7821 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
7824 vty_out(vty
, "%% source add failed\n");
7827 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7831 DEFUN (ip_msdp_mesh_group_source
,
7832 ip_msdp_mesh_group_source_cmd
,
7833 "ip msdp mesh-group WORD source A.B.C.D",
7836 "Configure MSDP mesh-group\n"
7838 "mesh group local address\n"
7839 "source ip address for the TCP connection\n")
7841 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7842 return ip_msdp_mesh_group_source_cmd_worker(pim
, vty
, argv
[3]->arg
,
7846 static int ip_no_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
7850 enum pim_msdp_err result
;
7852 result
= pim_msdp_mg_src_del(pim
, mg
);
7854 case PIM_MSDP_ERR_NONE
:
7856 case PIM_MSDP_ERR_NO_MG
:
7857 vty_out(vty
, "%% mesh-group does not exist\n");
7860 vty_out(vty
, "%% mesh-group source del failed\n");
7863 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7866 static int ip_no_msdp_mesh_group_cmd_worker(struct pim_instance
*pim
,
7867 struct vty
*vty
, const char *mg
)
7869 enum pim_msdp_err result
;
7871 result
= pim_msdp_mg_del(pim
, mg
);
7873 case PIM_MSDP_ERR_NONE
:
7875 case PIM_MSDP_ERR_NO_MG
:
7876 vty_out(vty
, "%% mesh-group does not exist\n");
7879 vty_out(vty
, "%% mesh-group source del failed\n");
7882 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7885 DEFUN (no_ip_msdp_mesh_group_source
,
7886 no_ip_msdp_mesh_group_source_cmd
,
7887 "no ip msdp mesh-group WORD source [A.B.C.D]",
7891 "Delete MSDP mesh-group source\n"
7893 "mesh group source\n"
7894 "mesh group local address\n")
7896 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7898 return ip_no_msdp_mesh_group_cmd_worker(pim
, vty
, argv
[6]->arg
);
7900 return ip_no_msdp_mesh_group_source_cmd_worker(pim
, vty
,
7904 static void print_empty_json_obj(struct vty
*vty
)
7907 json
= json_object_new_object();
7908 vty_out(vty
, "%s\n",
7909 json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
));
7910 json_object_free(json
);
7913 static void ip_msdp_show_mesh_group(struct pim_instance
*pim
, struct vty
*vty
,
7916 struct listnode
*mbrnode
;
7917 struct pim_msdp_mg_mbr
*mbr
;
7918 struct pim_msdp_mg
*mg
= pim
->msdp
.mg
;
7919 char mbr_str
[INET_ADDRSTRLEN
];
7920 char src_str
[INET_ADDRSTRLEN
];
7921 char state_str
[PIM_MSDP_STATE_STRLEN
];
7922 enum pim_msdp_peer_state state
;
7923 json_object
*json
= NULL
;
7924 json_object
*json_mg_row
= NULL
;
7925 json_object
*json_members
= NULL
;
7926 json_object
*json_row
= NULL
;
7930 print_empty_json_obj(vty
);
7934 pim_inet4_dump("<source?>", mg
->src_ip
, src_str
, sizeof(src_str
));
7936 json
= json_object_new_object();
7937 /* currently there is only one mesh group but we should still
7939 * it a dict with mg-name as key */
7940 json_mg_row
= json_object_new_object();
7941 json_object_string_add(json_mg_row
, "name",
7942 mg
->mesh_group_name
);
7943 json_object_string_add(json_mg_row
, "source", src_str
);
7945 vty_out(vty
, "Mesh group : %s\n", mg
->mesh_group_name
);
7946 vty_out(vty
, " Source : %s\n", src_str
);
7947 vty_out(vty
, " Member State\n");
7950 for (ALL_LIST_ELEMENTS_RO(mg
->mbr_list
, mbrnode
, mbr
)) {
7951 pim_inet4_dump("<mbr?>", mbr
->mbr_ip
, mbr_str
, sizeof(mbr_str
));
7953 state
= mbr
->mp
->state
;
7955 state
= PIM_MSDP_DISABLED
;
7957 pim_msdp_state_dump(state
, state_str
, sizeof(state_str
));
7959 json_row
= json_object_new_object();
7960 json_object_string_add(json_row
, "member", mbr_str
);
7961 json_object_string_add(json_row
, "state", state_str
);
7962 if (!json_members
) {
7963 json_members
= json_object_new_object();
7964 json_object_object_add(json_mg_row
, "members",
7967 json_object_object_add(json_members
, mbr_str
, json_row
);
7969 vty_out(vty
, " %-15s %11s\n", mbr_str
, state_str
);
7974 json_object_object_add(json
, mg
->mesh_group_name
, json_mg_row
);
7975 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
7976 json
, JSON_C_TO_STRING_PRETTY
));
7977 json_object_free(json
);
7981 DEFUN (show_ip_msdp_mesh_group
,
7982 show_ip_msdp_mesh_group_cmd
,
7983 "show ip msdp [vrf NAME] mesh-group [json]",
7988 "MSDP mesh-group information\n"
7991 bool uj
= use_json(argc
, argv
);
7993 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
7998 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
8003 DEFUN (show_ip_msdp_mesh_group_vrf_all
,
8004 show_ip_msdp_mesh_group_vrf_all_cmd
,
8005 "show ip msdp vrf all mesh-group [json]",
8010 "MSDP mesh-group information\n"
8013 bool uj
= use_json(argc
, argv
);
8019 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
8023 vty_out(vty
, " \"%s\": ", vrf
->name
);
8026 vty_out(vty
, "VRF: %s\n", vrf
->name
);
8027 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
8030 vty_out(vty
, "}\n");
8035 static void ip_msdp_show_peers(struct pim_instance
*pim
, struct vty
*vty
,
8038 struct listnode
*mpnode
;
8039 struct pim_msdp_peer
*mp
;
8040 char peer_str
[INET_ADDRSTRLEN
];
8041 char local_str
[INET_ADDRSTRLEN
];
8042 char state_str
[PIM_MSDP_STATE_STRLEN
];
8043 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
8045 json_object
*json
= NULL
;
8046 json_object
*json_row
= NULL
;
8050 json
= json_object_new_object();
8053 "Peer Local State Uptime SaCnt\n");
8056 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
8057 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
8058 now
= pim_time_monotonic_sec();
8059 pim_time_uptime(timebuf
, sizeof(timebuf
),
8062 strcpy(timebuf
, "-");
8064 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
8065 pim_inet4_dump("<local?>", mp
->local
, local_str
,
8067 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
8069 json_row
= json_object_new_object();
8070 json_object_string_add(json_row
, "peer", peer_str
);
8071 json_object_string_add(json_row
, "local", local_str
);
8072 json_object_string_add(json_row
, "state", state_str
);
8073 json_object_string_add(json_row
, "upTime", timebuf
);
8074 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
8075 json_object_object_add(json
, peer_str
, json_row
);
8077 vty_out(vty
, "%-15s %15s %11s %8s %6d\n", peer_str
,
8078 local_str
, state_str
, timebuf
, mp
->sa_cnt
);
8083 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8084 json
, JSON_C_TO_STRING_PRETTY
));
8085 json_object_free(json
);
8089 static void ip_msdp_show_peers_detail(struct pim_instance
*pim
, struct vty
*vty
,
8090 const char *peer
, bool uj
)
8092 struct listnode
*mpnode
;
8093 struct pim_msdp_peer
*mp
;
8094 char peer_str
[INET_ADDRSTRLEN
];
8095 char local_str
[INET_ADDRSTRLEN
];
8096 char state_str
[PIM_MSDP_STATE_STRLEN
];
8097 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
8098 char katimer
[PIM_MSDP_TIMER_STRLEN
];
8099 char crtimer
[PIM_MSDP_TIMER_STRLEN
];
8100 char holdtimer
[PIM_MSDP_TIMER_STRLEN
];
8102 json_object
*json
= NULL
;
8103 json_object
*json_row
= NULL
;
8106 json
= json_object_new_object();
8109 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
8110 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
8111 if (strcmp(peer
, "detail") && strcmp(peer
, peer_str
))
8114 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
8115 now
= pim_time_monotonic_sec();
8116 pim_time_uptime(timebuf
, sizeof(timebuf
),
8119 strcpy(timebuf
, "-");
8121 pim_inet4_dump("<local?>", mp
->local
, local_str
,
8123 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
8124 pim_time_timer_to_hhmmss(katimer
, sizeof(katimer
),
8126 pim_time_timer_to_hhmmss(crtimer
, sizeof(crtimer
),
8128 pim_time_timer_to_hhmmss(holdtimer
, sizeof(holdtimer
),
8132 json_row
= json_object_new_object();
8133 json_object_string_add(json_row
, "peer", peer_str
);
8134 json_object_string_add(json_row
, "local", local_str
);
8135 json_object_string_add(json_row
, "meshGroupName",
8136 mp
->mesh_group_name
);
8137 json_object_string_add(json_row
, "state", state_str
);
8138 json_object_string_add(json_row
, "upTime", timebuf
);
8139 json_object_string_add(json_row
, "keepAliveTimer",
8141 json_object_string_add(json_row
, "connRetryTimer",
8143 json_object_string_add(json_row
, "holdTimer",
8145 json_object_string_add(json_row
, "lastReset",
8147 json_object_int_add(json_row
, "connAttempts",
8149 json_object_int_add(json_row
, "establishedChanges",
8151 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
8152 json_object_int_add(json_row
, "kaSent", mp
->ka_tx_cnt
);
8153 json_object_int_add(json_row
, "kaRcvd", mp
->ka_rx_cnt
);
8154 json_object_int_add(json_row
, "saSent", mp
->sa_tx_cnt
);
8155 json_object_int_add(json_row
, "saRcvd", mp
->sa_rx_cnt
);
8156 json_object_object_add(json
, peer_str
, json_row
);
8158 vty_out(vty
, "Peer : %s\n", peer_str
);
8159 vty_out(vty
, " Local : %s\n", local_str
);
8160 vty_out(vty
, " Mesh Group : %s\n",
8161 mp
->mesh_group_name
);
8162 vty_out(vty
, " State : %s\n", state_str
);
8163 vty_out(vty
, " Uptime : %s\n", timebuf
);
8165 vty_out(vty
, " Keepalive Timer : %s\n", katimer
);
8166 vty_out(vty
, " Conn Retry Timer : %s\n", crtimer
);
8167 vty_out(vty
, " Hold Timer : %s\n", holdtimer
);
8168 vty_out(vty
, " Last Reset : %s\n",
8170 vty_out(vty
, " Conn Attempts : %d\n",
8172 vty_out(vty
, " Established Changes : %d\n",
8174 vty_out(vty
, " SA Count : %d\n",
8176 vty_out(vty
, " Statistics :\n");
8179 vty_out(vty
, " Keepalives : %10d %10d\n",
8180 mp
->ka_tx_cnt
, mp
->ka_rx_cnt
);
8181 vty_out(vty
, " SAs : %10d %10d\n",
8182 mp
->sa_tx_cnt
, mp
->sa_rx_cnt
);
8188 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8189 json
, JSON_C_TO_STRING_PRETTY
));
8190 json_object_free(json
);
8194 DEFUN (show_ip_msdp_peer_detail
,
8195 show_ip_msdp_peer_detail_cmd
,
8196 "show ip msdp [vrf NAME] peer [detail|A.B.C.D] [json]",
8201 "MSDP peer information\n"
8206 bool uj
= use_json(argc
, argv
);
8208 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
8215 if (argv_find(argv
, argc
, "detail", &idx
))
8216 arg
= argv
[idx
]->text
;
8217 else if (argv_find(argv
, argc
, "A.B.C.D", &idx
))
8218 arg
= argv
[idx
]->arg
;
8221 ip_msdp_show_peers_detail(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
8223 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
8228 DEFUN (show_ip_msdp_peer_detail_vrf_all
,
8229 show_ip_msdp_peer_detail_vrf_all_cmd
,
8230 "show ip msdp vrf all peer [detail|A.B.C.D] [json]",
8235 "MSDP peer information\n"
8241 bool uj
= use_json(argc
, argv
);
8247 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
8251 vty_out(vty
, " \"%s\": ", vrf
->name
);
8254 vty_out(vty
, "VRF: %s\n", vrf
->name
);
8255 if (argv_find(argv
, argc
, "detail", &idx
)
8256 || argv_find(argv
, argc
, "A.B.C.D", &idx
))
8257 ip_msdp_show_peers_detail(vrf
->info
, vty
,
8258 argv
[idx
]->arg
, uj
);
8260 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
8263 vty_out(vty
, "}\n");
8268 static void ip_msdp_show_sa(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
8270 struct listnode
*sanode
;
8271 struct pim_msdp_sa
*sa
;
8272 char src_str
[INET_ADDRSTRLEN
];
8273 char grp_str
[INET_ADDRSTRLEN
];
8274 char rp_str
[INET_ADDRSTRLEN
];
8275 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
8279 json_object
*json
= NULL
;
8280 json_object
*json_group
= NULL
;
8281 json_object
*json_row
= NULL
;
8284 json
= json_object_new_object();
8287 "Source Group RP Local SPT Uptime\n");
8290 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
8291 now
= pim_time_monotonic_sec();
8292 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
8293 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
8294 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
8295 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
8296 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
8298 strcpy(spt_str
, "yes");
8300 strcpy(spt_str
, "no");
8303 strcpy(rp_str
, "-");
8304 strcpy(spt_str
, "-");
8306 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
8307 strcpy(local_str
, "yes");
8309 strcpy(local_str
, "no");
8312 json_object_object_get_ex(json
, grp_str
, &json_group
);
8315 json_group
= json_object_new_object();
8316 json_object_object_add(json
, grp_str
,
8320 json_row
= json_object_new_object();
8321 json_object_string_add(json_row
, "source", src_str
);
8322 json_object_string_add(json_row
, "group", grp_str
);
8323 json_object_string_add(json_row
, "rp", rp_str
);
8324 json_object_string_add(json_row
, "local", local_str
);
8325 json_object_string_add(json_row
, "sptSetup", spt_str
);
8326 json_object_string_add(json_row
, "upTime", timebuf
);
8327 json_object_object_add(json_group
, src_str
, json_row
);
8329 vty_out(vty
, "%-15s %15s %15s %5c %3c %8s\n",
8330 src_str
, grp_str
, rp_str
, local_str
[0],
8331 spt_str
[0], timebuf
);
8336 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8337 json
, JSON_C_TO_STRING_PRETTY
));
8338 json_object_free(json
);
8342 static void ip_msdp_show_sa_entry_detail(struct pim_msdp_sa
*sa
,
8343 const char *src_str
,
8344 const char *grp_str
, struct vty
*vty
,
8345 bool uj
, json_object
*json
)
8347 char rp_str
[INET_ADDRSTRLEN
];
8348 char peer_str
[INET_ADDRSTRLEN
];
8349 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
8352 char statetimer
[PIM_MSDP_TIMER_STRLEN
];
8354 json_object
*json_group
= NULL
;
8355 json_object
*json_row
= NULL
;
8357 now
= pim_time_monotonic_sec();
8358 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
8359 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
8360 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
8361 pim_inet4_dump("<peer?>", sa
->peer
, peer_str
, sizeof(peer_str
));
8363 strcpy(spt_str
, "yes");
8365 strcpy(spt_str
, "no");
8368 strcpy(rp_str
, "-");
8369 strcpy(peer_str
, "-");
8370 strcpy(spt_str
, "-");
8372 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
8373 strcpy(local_str
, "yes");
8375 strcpy(local_str
, "no");
8377 pim_time_timer_to_hhmmss(statetimer
, sizeof(statetimer
),
8378 sa
->sa_state_timer
);
8380 json_object_object_get_ex(json
, grp_str
, &json_group
);
8383 json_group
= json_object_new_object();
8384 json_object_object_add(json
, grp_str
, json_group
);
8387 json_row
= json_object_new_object();
8388 json_object_string_add(json_row
, "source", src_str
);
8389 json_object_string_add(json_row
, "group", grp_str
);
8390 json_object_string_add(json_row
, "rp", rp_str
);
8391 json_object_string_add(json_row
, "local", local_str
);
8392 json_object_string_add(json_row
, "sptSetup", spt_str
);
8393 json_object_string_add(json_row
, "upTime", timebuf
);
8394 json_object_string_add(json_row
, "stateTimer", statetimer
);
8395 json_object_object_add(json_group
, src_str
, json_row
);
8397 vty_out(vty
, "SA : %s\n", sa
->sg_str
);
8398 vty_out(vty
, " RP : %s\n", rp_str
);
8399 vty_out(vty
, " Peer : %s\n", peer_str
);
8400 vty_out(vty
, " Local : %s\n", local_str
);
8401 vty_out(vty
, " SPT Setup : %s\n", spt_str
);
8402 vty_out(vty
, " Uptime : %s\n", timebuf
);
8403 vty_out(vty
, " State Timer : %s\n", statetimer
);
8408 static void ip_msdp_show_sa_detail(struct pim_instance
*pim
, struct vty
*vty
,
8411 struct listnode
*sanode
;
8412 struct pim_msdp_sa
*sa
;
8413 char src_str
[INET_ADDRSTRLEN
];
8414 char grp_str
[INET_ADDRSTRLEN
];
8415 json_object
*json
= NULL
;
8418 json
= json_object_new_object();
8421 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
8422 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
8423 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
8424 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
, uj
,
8429 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8430 json
, JSON_C_TO_STRING_PRETTY
));
8431 json_object_free(json
);
8435 DEFUN (show_ip_msdp_sa_detail
,
8436 show_ip_msdp_sa_detail_cmd
,
8437 "show ip msdp [vrf NAME] sa detail [json]",
8442 "MSDP active-source information\n"
8446 bool uj
= use_json(argc
, argv
);
8448 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
8453 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
8458 DEFUN (show_ip_msdp_sa_detail_vrf_all
,
8459 show_ip_msdp_sa_detail_vrf_all_cmd
,
8460 "show ip msdp vrf all sa detail [json]",
8465 "MSDP active-source information\n"
8469 bool uj
= use_json(argc
, argv
);
8475 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
8479 vty_out(vty
, " \"%s\": ", vrf
->name
);
8482 vty_out(vty
, "VRF: %s\n", vrf
->name
);
8483 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
8486 vty_out(vty
, "}\n");
8491 static void ip_msdp_show_sa_addr(struct pim_instance
*pim
, struct vty
*vty
,
8492 const char *addr
, bool uj
)
8494 struct listnode
*sanode
;
8495 struct pim_msdp_sa
*sa
;
8496 char src_str
[INET_ADDRSTRLEN
];
8497 char grp_str
[INET_ADDRSTRLEN
];
8498 json_object
*json
= NULL
;
8501 json
= json_object_new_object();
8504 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
8505 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
8506 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
8507 if (!strcmp(addr
, src_str
) || !strcmp(addr
, grp_str
)) {
8508 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
8514 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8515 json
, JSON_C_TO_STRING_PRETTY
));
8516 json_object_free(json
);
8520 static void ip_msdp_show_sa_sg(struct pim_instance
*pim
, struct vty
*vty
,
8521 const char *src
, const char *grp
, bool uj
)
8523 struct listnode
*sanode
;
8524 struct pim_msdp_sa
*sa
;
8525 char src_str
[INET_ADDRSTRLEN
];
8526 char grp_str
[INET_ADDRSTRLEN
];
8527 json_object
*json
= NULL
;
8530 json
= json_object_new_object();
8533 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
8534 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
8535 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
8536 if (!strcmp(src
, src_str
) && !strcmp(grp
, grp_str
)) {
8537 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
8543 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8544 json
, JSON_C_TO_STRING_PRETTY
));
8545 json_object_free(json
);
8549 DEFUN (show_ip_msdp_sa_sg
,
8550 show_ip_msdp_sa_sg_cmd
,
8551 "show ip msdp [vrf NAME] sa [A.B.C.D [A.B.C.D]] [json]",
8556 "MSDP active-source information\n"
8557 "source or group ip\n"
8561 bool uj
= use_json(argc
, argv
);
8565 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
8570 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
8572 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
8576 if (src_ip
&& grp_ip
)
8577 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
8579 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
8581 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
8586 DEFUN (show_ip_msdp_sa_sg_vrf_all
,
8587 show_ip_msdp_sa_sg_vrf_all_cmd
,
8588 "show ip msdp vrf all sa [A.B.C.D [A.B.C.D]] [json]",
8593 "MSDP active-source information\n"
8594 "source or group ip\n"
8598 bool uj
= use_json(argc
, argv
);
8603 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
8605 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
8611 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
8615 vty_out(vty
, " \"%s\": ", vrf
->name
);
8618 vty_out(vty
, "VRF: %s\n", vrf
->name
);
8620 if (src_ip
&& grp_ip
)
8621 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
8623 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
8625 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
8628 vty_out(vty
, "}\n");
8634 void pim_cmd_init(void)
8636 install_node(&interface_node
,
8637 pim_interface_config_write
); /* INTERFACE_NODE */
8640 install_node(&debug_node
, pim_debug_config_write
);
8642 install_element(CONFIG_NODE
, &ip_pim_rp_cmd
);
8643 install_element(VRF_NODE
, &ip_pim_rp_cmd
);
8644 install_element(CONFIG_NODE
, &no_ip_pim_rp_cmd
);
8645 install_element(VRF_NODE
, &no_ip_pim_rp_cmd
);
8646 install_element(CONFIG_NODE
, &ip_pim_rp_prefix_list_cmd
);
8647 install_element(VRF_NODE
, &ip_pim_rp_prefix_list_cmd
);
8648 install_element(CONFIG_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
8649 install_element(VRF_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
8650 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
8651 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
8652 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
8653 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
8654 install_element(CONFIG_NODE
, &ip_pim_ssm_prefix_list_cmd
);
8655 install_element(VRF_NODE
, &ip_pim_ssm_prefix_list_cmd
);
8656 install_element(CONFIG_NODE
, &ip_pim_register_suppress_cmd
);
8657 install_element(VRF_NODE
, &ip_pim_register_suppress_cmd
);
8658 install_element(CONFIG_NODE
, &no_ip_pim_register_suppress_cmd
);
8659 install_element(VRF_NODE
, &no_ip_pim_register_suppress_cmd
);
8660 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
8661 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
8662 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
8663 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
8664 install_element(CONFIG_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
8665 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
8666 install_element(CONFIG_NODE
,
8667 &no_ip_pim_spt_switchover_infinity_plist_cmd
);
8668 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_plist_cmd
);
8669 install_element(CONFIG_NODE
, &ip_pim_joinprune_time_cmd
);
8670 install_element(VRF_NODE
, &ip_pim_joinprune_time_cmd
);
8671 install_element(CONFIG_NODE
, &no_ip_pim_joinprune_time_cmd
);
8672 install_element(VRF_NODE
, &no_ip_pim_joinprune_time_cmd
);
8673 install_element(CONFIG_NODE
, &ip_pim_keep_alive_cmd
);
8674 install_element(VRF_NODE
, &ip_pim_keep_alive_cmd
);
8675 install_element(CONFIG_NODE
, &ip_pim_rp_keep_alive_cmd
);
8676 install_element(VRF_NODE
, &ip_pim_rp_keep_alive_cmd
);
8677 install_element(CONFIG_NODE
, &no_ip_pim_keep_alive_cmd
);
8678 install_element(VRF_NODE
, &no_ip_pim_keep_alive_cmd
);
8679 install_element(CONFIG_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
8680 install_element(VRF_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
8681 install_element(CONFIG_NODE
, &ip_pim_packets_cmd
);
8682 install_element(VRF_NODE
, &ip_pim_packets_cmd
);
8683 install_element(CONFIG_NODE
, &no_ip_pim_packets_cmd
);
8684 install_element(VRF_NODE
, &no_ip_pim_packets_cmd
);
8685 install_element(CONFIG_NODE
, &ip_pim_v6_secondary_cmd
);
8686 install_element(VRF_NODE
, &ip_pim_v6_secondary_cmd
);
8687 install_element(CONFIG_NODE
, &no_ip_pim_v6_secondary_cmd
);
8688 install_element(VRF_NODE
, &no_ip_pim_v6_secondary_cmd
);
8689 install_element(CONFIG_NODE
, &ip_ssmpingd_cmd
);
8690 install_element(VRF_NODE
, &ip_ssmpingd_cmd
);
8691 install_element(CONFIG_NODE
, &no_ip_ssmpingd_cmd
);
8692 install_element(VRF_NODE
, &no_ip_ssmpingd_cmd
);
8693 install_element(CONFIG_NODE
, &ip_msdp_peer_cmd
);
8694 install_element(VRF_NODE
, &ip_msdp_peer_cmd
);
8695 install_element(CONFIG_NODE
, &no_ip_msdp_peer_cmd
);
8696 install_element(VRF_NODE
, &no_ip_msdp_peer_cmd
);
8697 install_element(CONFIG_NODE
, &ip_pim_ecmp_cmd
);
8698 install_element(VRF_NODE
, &ip_pim_ecmp_cmd
);
8699 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_cmd
);
8700 install_element(VRF_NODE
, &no_ip_pim_ecmp_cmd
);
8701 install_element(CONFIG_NODE
, &ip_pim_ecmp_rebalance_cmd
);
8702 install_element(VRF_NODE
, &ip_pim_ecmp_rebalance_cmd
);
8703 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
8704 install_element(VRF_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
8706 install_element(INTERFACE_NODE
, &interface_ip_igmp_cmd
);
8707 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_cmd
);
8708 install_element(INTERFACE_NODE
, &interface_ip_igmp_join_cmd
);
8709 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_join_cmd
);
8710 install_element(INTERFACE_NODE
, &interface_ip_igmp_version_cmd
);
8711 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_version_cmd
);
8712 install_element(INTERFACE_NODE
, &interface_ip_igmp_query_interval_cmd
);
8713 install_element(INTERFACE_NODE
,
8714 &interface_no_ip_igmp_query_interval_cmd
);
8715 install_element(INTERFACE_NODE
,
8716 &interface_ip_igmp_query_max_response_time_cmd
);
8717 install_element(INTERFACE_NODE
,
8718 &interface_no_ip_igmp_query_max_response_time_cmd
);
8719 install_element(INTERFACE_NODE
,
8720 &interface_ip_igmp_query_max_response_time_dsec_cmd
);
8721 install_element(INTERFACE_NODE
,
8722 &interface_no_ip_igmp_query_max_response_time_dsec_cmd
);
8723 install_element(INTERFACE_NODE
, &interface_ip_pim_ssm_cmd
);
8724 install_element(INTERFACE_NODE
, &interface_no_ip_pim_ssm_cmd
);
8725 install_element(INTERFACE_NODE
, &interface_ip_pim_sm_cmd
);
8726 install_element(INTERFACE_NODE
, &interface_no_ip_pim_sm_cmd
);
8727 install_element(INTERFACE_NODE
, &interface_ip_pim_cmd
);
8728 install_element(INTERFACE_NODE
, &interface_no_ip_pim_cmd
);
8729 install_element(INTERFACE_NODE
, &interface_ip_pim_drprio_cmd
);
8730 install_element(INTERFACE_NODE
, &interface_no_ip_pim_drprio_cmd
);
8731 install_element(INTERFACE_NODE
, &interface_ip_pim_hello_cmd
);
8732 install_element(INTERFACE_NODE
, &interface_no_ip_pim_hello_cmd
);
8733 install_element(INTERFACE_NODE
, &interface_ip_pim_boundary_oil_cmd
);
8734 install_element(INTERFACE_NODE
, &interface_no_ip_pim_boundary_oil_cmd
);
8736 // Static mroutes NEB
8737 install_element(INTERFACE_NODE
, &interface_ip_mroute_cmd
);
8738 install_element(INTERFACE_NODE
, &interface_ip_mroute_source_cmd
);
8739 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_cmd
);
8740 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_source_cmd
);
8742 install_element(VIEW_NODE
, &show_ip_igmp_interface_cmd
);
8743 install_element(VIEW_NODE
, &show_ip_igmp_interface_vrf_all_cmd
);
8744 install_element(VIEW_NODE
, &show_ip_igmp_join_cmd
);
8745 install_element(VIEW_NODE
, &show_ip_igmp_join_vrf_all_cmd
);
8746 install_element(VIEW_NODE
, &show_ip_igmp_groups_cmd
);
8747 install_element(VIEW_NODE
, &show_ip_igmp_groups_vrf_all_cmd
);
8748 install_element(VIEW_NODE
, &show_ip_igmp_groups_retransmissions_cmd
);
8749 install_element(VIEW_NODE
, &show_ip_igmp_sources_cmd
);
8750 install_element(VIEW_NODE
, &show_ip_igmp_sources_retransmissions_cmd
);
8751 install_element(VIEW_NODE
, &show_ip_igmp_statistics_cmd
);
8752 install_element(VIEW_NODE
, &show_ip_pim_assert_cmd
);
8753 install_element(VIEW_NODE
, &show_ip_pim_assert_internal_cmd
);
8754 install_element(VIEW_NODE
, &show_ip_pim_assert_metric_cmd
);
8755 install_element(VIEW_NODE
, &show_ip_pim_assert_winner_metric_cmd
);
8756 install_element(VIEW_NODE
, &show_ip_pim_interface_traffic_cmd
);
8757 install_element(VIEW_NODE
, &show_ip_pim_interface_cmd
);
8758 install_element(VIEW_NODE
, &show_ip_pim_interface_vrf_all_cmd
);
8759 install_element(VIEW_NODE
, &show_ip_pim_join_cmd
);
8760 install_element(VIEW_NODE
, &show_ip_pim_join_vrf_all_cmd
);
8761 install_element(VIEW_NODE
, &show_ip_pim_local_membership_cmd
);
8762 install_element(VIEW_NODE
, &show_ip_pim_neighbor_cmd
);
8763 install_element(VIEW_NODE
, &show_ip_pim_neighbor_vrf_all_cmd
);
8764 install_element(VIEW_NODE
, &show_ip_pim_rpf_cmd
);
8765 install_element(VIEW_NODE
, &show_ip_pim_rpf_vrf_all_cmd
);
8766 install_element(VIEW_NODE
, &show_ip_pim_secondary_cmd
);
8767 install_element(VIEW_NODE
, &show_ip_pim_state_cmd
);
8768 install_element(VIEW_NODE
, &show_ip_pim_state_vrf_all_cmd
);
8769 install_element(VIEW_NODE
, &show_ip_pim_upstream_cmd
);
8770 install_element(VIEW_NODE
, &show_ip_pim_upstream_vrf_all_cmd
);
8771 install_element(VIEW_NODE
, &show_ip_pim_upstream_join_desired_cmd
);
8772 install_element(VIEW_NODE
, &show_ip_pim_upstream_rpf_cmd
);
8773 install_element(VIEW_NODE
, &show_ip_pim_rp_cmd
);
8774 install_element(VIEW_NODE
, &show_ip_pim_rp_vrf_all_cmd
);
8775 install_element(VIEW_NODE
, &show_ip_multicast_cmd
);
8776 install_element(VIEW_NODE
, &show_ip_multicast_vrf_all_cmd
);
8777 install_element(VIEW_NODE
, &show_ip_mroute_cmd
);
8778 install_element(VIEW_NODE
, &show_ip_mroute_vrf_all_cmd
);
8779 install_element(VIEW_NODE
, &show_ip_mroute_count_cmd
);
8780 install_element(VIEW_NODE
, &show_ip_mroute_count_vrf_all_cmd
);
8781 install_element(VIEW_NODE
, &show_ip_rib_cmd
);
8782 install_element(VIEW_NODE
, &show_ip_ssmpingd_cmd
);
8783 install_element(VIEW_NODE
, &show_debugging_pim_cmd
);
8784 install_element(VIEW_NODE
, &show_ip_pim_nexthop_cmd
);
8785 install_element(VIEW_NODE
, &show_ip_pim_nexthop_lookup_cmd
);
8787 install_element(ENABLE_NODE
, &clear_ip_interfaces_cmd
);
8788 install_element(ENABLE_NODE
, &clear_ip_igmp_interfaces_cmd
);
8789 install_element(ENABLE_NODE
, &clear_ip_mroute_cmd
);
8790 install_element(ENABLE_NODE
, &clear_ip_pim_interfaces_cmd
);
8791 install_element(ENABLE_NODE
, &clear_ip_pim_interface_traffic_cmd
);
8792 install_element(ENABLE_NODE
, &clear_ip_pim_oil_cmd
);
8794 install_element(ENABLE_NODE
, &debug_igmp_cmd
);
8795 install_element(ENABLE_NODE
, &no_debug_igmp_cmd
);
8796 install_element(ENABLE_NODE
, &debug_igmp_events_cmd
);
8797 install_element(ENABLE_NODE
, &no_debug_igmp_events_cmd
);
8798 install_element(ENABLE_NODE
, &debug_igmp_packets_cmd
);
8799 install_element(ENABLE_NODE
, &no_debug_igmp_packets_cmd
);
8800 install_element(ENABLE_NODE
, &debug_igmp_trace_cmd
);
8801 install_element(ENABLE_NODE
, &no_debug_igmp_trace_cmd
);
8802 install_element(ENABLE_NODE
, &debug_mroute_cmd
);
8803 install_element(ENABLE_NODE
, &debug_mroute_detail_cmd
);
8804 install_element(ENABLE_NODE
, &no_debug_mroute_cmd
);
8805 install_element(ENABLE_NODE
, &no_debug_mroute_detail_cmd
);
8806 install_element(ENABLE_NODE
, &debug_static_cmd
);
8807 install_element(ENABLE_NODE
, &no_debug_static_cmd
);
8808 install_element(ENABLE_NODE
, &debug_pim_cmd
);
8809 install_element(ENABLE_NODE
, &no_debug_pim_cmd
);
8810 install_element(ENABLE_NODE
, &debug_pim_nht_cmd
);
8811 install_element(ENABLE_NODE
, &no_debug_pim_nht_cmd
);
8812 install_element(ENABLE_NODE
, &debug_pim_nht_rp_cmd
);
8813 install_element(ENABLE_NODE
, &no_debug_pim_nht_rp_cmd
);
8814 install_element(ENABLE_NODE
, &debug_pim_events_cmd
);
8815 install_element(ENABLE_NODE
, &no_debug_pim_events_cmd
);
8816 install_element(ENABLE_NODE
, &debug_pim_packets_cmd
);
8817 install_element(ENABLE_NODE
, &no_debug_pim_packets_cmd
);
8818 install_element(ENABLE_NODE
, &debug_pim_packetdump_send_cmd
);
8819 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_send_cmd
);
8820 install_element(ENABLE_NODE
, &debug_pim_packetdump_recv_cmd
);
8821 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_recv_cmd
);
8822 install_element(ENABLE_NODE
, &debug_pim_trace_cmd
);
8823 install_element(ENABLE_NODE
, &no_debug_pim_trace_cmd
);
8824 install_element(ENABLE_NODE
, &debug_pim_trace_detail_cmd
);
8825 install_element(ENABLE_NODE
, &no_debug_pim_trace_detail_cmd
);
8826 install_element(ENABLE_NODE
, &debug_ssmpingd_cmd
);
8827 install_element(ENABLE_NODE
, &no_debug_ssmpingd_cmd
);
8828 install_element(ENABLE_NODE
, &debug_pim_zebra_cmd
);
8829 install_element(ENABLE_NODE
, &no_debug_pim_zebra_cmd
);
8830 install_element(ENABLE_NODE
, &debug_msdp_cmd
);
8831 install_element(ENABLE_NODE
, &no_debug_msdp_cmd
);
8832 install_element(ENABLE_NODE
, &undebug_msdp_cmd
);
8833 install_element(ENABLE_NODE
, &debug_msdp_events_cmd
);
8834 install_element(ENABLE_NODE
, &no_debug_msdp_events_cmd
);
8835 install_element(ENABLE_NODE
, &undebug_msdp_events_cmd
);
8836 install_element(ENABLE_NODE
, &debug_msdp_packets_cmd
);
8837 install_element(ENABLE_NODE
, &no_debug_msdp_packets_cmd
);
8838 install_element(ENABLE_NODE
, &undebug_msdp_packets_cmd
);
8839 install_element(ENABLE_NODE
, &debug_mtrace_cmd
);
8840 install_element(ENABLE_NODE
, &no_debug_mtrace_cmd
);
8842 install_element(CONFIG_NODE
, &debug_igmp_cmd
);
8843 install_element(CONFIG_NODE
, &no_debug_igmp_cmd
);
8844 install_element(CONFIG_NODE
, &debug_igmp_events_cmd
);
8845 install_element(CONFIG_NODE
, &no_debug_igmp_events_cmd
);
8846 install_element(CONFIG_NODE
, &debug_igmp_packets_cmd
);
8847 install_element(CONFIG_NODE
, &no_debug_igmp_packets_cmd
);
8848 install_element(CONFIG_NODE
, &debug_igmp_trace_cmd
);
8849 install_element(CONFIG_NODE
, &no_debug_igmp_trace_cmd
);
8850 install_element(CONFIG_NODE
, &debug_mroute_cmd
);
8851 install_element(CONFIG_NODE
, &debug_mroute_detail_cmd
);
8852 install_element(CONFIG_NODE
, &no_debug_mroute_cmd
);
8853 install_element(CONFIG_NODE
, &no_debug_mroute_detail_cmd
);
8854 install_element(CONFIG_NODE
, &debug_static_cmd
);
8855 install_element(CONFIG_NODE
, &no_debug_static_cmd
);
8856 install_element(CONFIG_NODE
, &debug_pim_cmd
);
8857 install_element(CONFIG_NODE
, &no_debug_pim_cmd
);
8858 install_element(CONFIG_NODE
, &debug_pim_nht_cmd
);
8859 install_element(CONFIG_NODE
, &no_debug_pim_nht_cmd
);
8860 install_element(CONFIG_NODE
, &debug_pim_nht_rp_cmd
);
8861 install_element(CONFIG_NODE
, &no_debug_pim_nht_rp_cmd
);
8862 install_element(CONFIG_NODE
, &debug_pim_events_cmd
);
8863 install_element(CONFIG_NODE
, &no_debug_pim_events_cmd
);
8864 install_element(CONFIG_NODE
, &debug_pim_packets_cmd
);
8865 install_element(CONFIG_NODE
, &no_debug_pim_packets_cmd
);
8866 install_element(CONFIG_NODE
, &debug_pim_trace_cmd
);
8867 install_element(CONFIG_NODE
, &no_debug_pim_trace_cmd
);
8868 install_element(CONFIG_NODE
, &debug_pim_trace_detail_cmd
);
8869 install_element(CONFIG_NODE
, &no_debug_pim_trace_detail_cmd
);
8870 install_element(CONFIG_NODE
, &debug_ssmpingd_cmd
);
8871 install_element(CONFIG_NODE
, &no_debug_ssmpingd_cmd
);
8872 install_element(CONFIG_NODE
, &debug_pim_zebra_cmd
);
8873 install_element(CONFIG_NODE
, &no_debug_pim_zebra_cmd
);
8874 install_element(CONFIG_NODE
, &debug_msdp_cmd
);
8875 install_element(CONFIG_NODE
, &no_debug_msdp_cmd
);
8876 install_element(CONFIG_NODE
, &undebug_msdp_cmd
);
8877 install_element(CONFIG_NODE
, &debug_msdp_events_cmd
);
8878 install_element(CONFIG_NODE
, &no_debug_msdp_events_cmd
);
8879 install_element(CONFIG_NODE
, &undebug_msdp_events_cmd
);
8880 install_element(CONFIG_NODE
, &debug_msdp_packets_cmd
);
8881 install_element(CONFIG_NODE
, &no_debug_msdp_packets_cmd
);
8882 install_element(CONFIG_NODE
, &undebug_msdp_packets_cmd
);
8883 install_element(CONFIG_NODE
, &debug_mtrace_cmd
);
8884 install_element(CONFIG_NODE
, &no_debug_mtrace_cmd
);
8886 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_member_cmd
);
8887 install_element(VRF_NODE
, &ip_msdp_mesh_group_member_cmd
);
8888 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
8889 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
8890 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_source_cmd
);
8891 install_element(VRF_NODE
, &ip_msdp_mesh_group_source_cmd
);
8892 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
8893 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
8894 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_cmd
);
8895 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_vrf_all_cmd
);
8896 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_cmd
);
8897 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_vrf_all_cmd
);
8898 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_cmd
);
8899 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_vrf_all_cmd
);
8900 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_cmd
);
8901 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_vrf_all_cmd
);
8902 install_element(VIEW_NODE
, &show_ip_pim_ssm_range_cmd
);
8903 install_element(VIEW_NODE
, &show_ip_pim_group_type_cmd
);
8904 install_element(INTERFACE_NODE
, &interface_pim_use_source_cmd
);
8905 install_element(INTERFACE_NODE
, &interface_no_pim_use_source_cmd
);
8906 /* Install BFD command */
8907 install_element(INTERFACE_NODE
, &ip_pim_bfd_cmd
);
8908 install_element(INTERFACE_NODE
, &ip_pim_bfd_param_cmd
);
8909 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_cmd
);
8911 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_param_cmd
);
8912 #endif /* !HAVE_BFDD */