3 * Copyright (C) 2008 Everton da Silva Marques
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; see the file COPYING; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
34 #include "pim_mroute.h"
36 #include "pim_iface.h"
38 #include "pim_mroute.h"
41 #include "pim_igmpv3.h"
46 #include "pim_neighbor.h"
48 #include "pim_ifchannel.h"
49 #include "pim_hello.h"
51 #include "pim_upstream.h"
53 #include "pim_macro.h"
54 #include "pim_ssmpingd.h"
55 #include "pim_zebra.h"
56 #include "pim_static.h"
58 #include "pim_zlookup.h"
65 static struct cmd_node interface_node
= {
66 INTERFACE_NODE
, "%s(config-if)# ", 1 /* vtysh ? yes */
69 static struct cmd_node debug_node
= {DEBUG_NODE
, "", 1};
71 static struct vrf
*pim_cmd_lookup_vrf(struct vty
*vty
, struct cmd_token
*argv
[],
72 const int argc
, int *idx
)
76 if (argv_find(argv
, argc
, "NAME", idx
))
77 vrf
= vrf_lookup_by_name(argv
[*idx
]->arg
);
79 vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
82 vty_out(vty
, "Specified VRF: %s does not exist\n",
88 static void pim_if_membership_clear(struct interface
*ifp
)
90 struct pim_interface
*pim_ifp
;
95 if (PIM_IF_TEST_PIM(pim_ifp
->options
)
96 && PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
100 pim_ifchannel_membership_clear(ifp
);
104 When PIM is disabled on interface, IGMPv3 local membership
105 information is not injected into PIM interface state.
107 The function pim_if_membership_refresh() fetches all IGMPv3 local
108 membership information into PIM. It is intented to be called
109 whenever PIM is enabled on the interface in order to collect missed
110 local membership information.
112 static void pim_if_membership_refresh(struct interface
*ifp
)
114 struct pim_interface
*pim_ifp
;
115 struct listnode
*sock_node
;
116 struct igmp_sock
*igmp
;
121 if (!PIM_IF_TEST_PIM(pim_ifp
->options
))
123 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
))
127 First clear off membership from all PIM (S,G) entries on the
131 pim_ifchannel_membership_clear(ifp
);
134 Then restore PIM (S,G) membership from all IGMPv3 (S,G) entries on
138 /* scan igmp sockets */
139 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
140 struct listnode
*grpnode
;
141 struct igmp_group
*grp
;
143 /* scan igmp groups */
144 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grpnode
,
146 struct listnode
*srcnode
;
147 struct igmp_source
*src
;
149 /* scan group sources */
150 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
,
153 if (IGMP_SOURCE_TEST_FORWARDING(
154 src
->source_flags
)) {
158 sizeof(struct prefix_sg
));
159 sg
.src
= src
->source_addr
;
160 sg
.grp
= grp
->group_addr
;
161 pim_ifchannel_local_membership_add(ifp
,
165 } /* scan group sources */
166 } /* scan igmp groups */
167 } /* scan igmp sockets */
170 Finally delete every PIM (S,G) entry lacking all state info
173 pim_ifchannel_delete_on_noinfo(ifp
);
176 static void pim_show_assert_helper(struct vty
*vty
,
177 struct pim_interface
*pim_ifp
,
178 struct pim_ifchannel
*ch
, time_t now
)
180 char ch_src_str
[INET_ADDRSTRLEN
];
181 char ch_grp_str
[INET_ADDRSTRLEN
];
182 char winner_str
[INET_ADDRSTRLEN
];
183 struct in_addr ifaddr
;
187 ifaddr
= pim_ifp
->primary_address
;
189 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
190 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
191 pim_inet4_dump("<assrt_win?>", ch
->ifassert_winner
, winner_str
,
194 pim_time_uptime(uptime
, sizeof(uptime
), now
- ch
->ifassert_creation
);
195 pim_time_timer_to_mmss(timer
, sizeof(timer
), ch
->t_ifassert_timer
);
197 vty_out(vty
, "%-9s %-15s %-15s %-15s %-6s %-15s %-8s %-5s\n",
198 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
, ch_grp_str
,
199 pim_ifchannel_ifassert_name(ch
->ifassert_state
), winner_str
,
203 static void pim_show_assert(struct pim_instance
*pim
, struct vty
*vty
)
205 struct pim_interface
*pim_ifp
;
206 struct pim_ifchannel
*ch
;
207 struct interface
*ifp
;
210 now
= pim_time_monotonic_sec();
213 "Interface Address Source Group State Winner Uptime Timer\n");
215 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
220 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
221 pim_show_assert_helper(vty
, pim_ifp
, ch
, now
);
222 } /* scan interface channels */
226 static void pim_show_assert_internal_helper(struct vty
*vty
,
227 struct pim_interface
*pim_ifp
,
228 struct pim_ifchannel
*ch
)
230 char ch_src_str
[INET_ADDRSTRLEN
];
231 char ch_grp_str
[INET_ADDRSTRLEN
];
232 struct in_addr ifaddr
;
234 ifaddr
= pim_ifp
->primary_address
;
236 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
237 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
238 vty_out(vty
, "%-9s %-15s %-15s %-15s %-3s %-3s %-3s %-4s\n",
239 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
, ch_grp_str
,
240 PIM_IF_FLAG_TEST_COULD_ASSERT(ch
->flags
) ? "yes" : "no",
241 pim_macro_ch_could_assert_eval(ch
) ? "yes" : "no",
242 PIM_IF_FLAG_TEST_ASSERT_TRACKING_DESIRED(ch
->flags
) ? "yes"
244 pim_macro_assert_tracking_desired_eval(ch
) ? "yes" : "no");
247 static void pim_show_assert_internal(struct pim_instance
*pim
, struct vty
*vty
)
249 struct pim_interface
*pim_ifp
;
250 struct pim_ifchannel
*ch
;
251 struct interface
*ifp
;
255 "ECA: Evaluate CouldAssert\n"
256 "ATD: AssertTrackingDesired\n"
257 "eATD: Evaluate AssertTrackingDesired\n\n");
260 "Interface Address Source Group CA eCA ATD eATD\n");
261 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
266 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
267 pim_show_assert_internal_helper(vty
, pim_ifp
, ch
);
268 } /* scan interface channels */
272 static void pim_show_assert_metric_helper(struct vty
*vty
,
273 struct pim_interface
*pim_ifp
,
274 struct pim_ifchannel
*ch
)
276 char ch_src_str
[INET_ADDRSTRLEN
];
277 char ch_grp_str
[INET_ADDRSTRLEN
];
278 char addr_str
[INET_ADDRSTRLEN
];
279 struct pim_assert_metric am
;
280 struct in_addr ifaddr
;
282 ifaddr
= pim_ifp
->primary_address
;
284 am
= pim_macro_spt_assert_metric(&ch
->upstream
->rpf
,
285 pim_ifp
->primary_address
);
287 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
288 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
289 pim_inet4_dump("<addr?>", am
.ip_address
, addr_str
, sizeof(addr_str
));
291 vty_out(vty
, "%-9s %-15s %-15s %-15s %-3s %4u %6u %-15s\n",
292 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
, ch_grp_str
,
293 am
.rpt_bit_flag
? "yes" : "no", am
.metric_preference
,
294 am
.route_metric
, addr_str
);
297 static void pim_show_assert_metric(struct pim_instance
*pim
, struct vty
*vty
)
299 struct pim_interface
*pim_ifp
;
300 struct pim_ifchannel
*ch
;
301 struct interface
*ifp
;
304 "Interface Address Source Group RPT Pref Metric Address \n");
306 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
311 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
312 pim_show_assert_metric_helper(vty
, pim_ifp
, ch
);
313 } /* scan interface channels */
317 static void pim_show_assert_winner_metric_helper(struct vty
*vty
,
318 struct pim_interface
*pim_ifp
,
319 struct pim_ifchannel
*ch
)
321 char ch_src_str
[INET_ADDRSTRLEN
];
322 char ch_grp_str
[INET_ADDRSTRLEN
];
323 char addr_str
[INET_ADDRSTRLEN
];
324 struct pim_assert_metric
*am
;
325 struct in_addr ifaddr
;
329 ifaddr
= pim_ifp
->primary_address
;
331 am
= &ch
->ifassert_winner_metric
;
333 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
334 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
335 pim_inet4_dump("<addr?>", am
->ip_address
, addr_str
, sizeof(addr_str
));
337 if (am
->metric_preference
== PIM_ASSERT_METRIC_PREFERENCE_MAX
)
338 snprintf(pref_str
, sizeof(pref_str
), "INFI");
340 snprintf(pref_str
, sizeof(pref_str
), "%4u",
341 am
->metric_preference
);
343 if (am
->route_metric
== PIM_ASSERT_ROUTE_METRIC_MAX
)
344 snprintf(metr_str
, sizeof(metr_str
), "INFI");
346 snprintf(metr_str
, sizeof(metr_str
), "%6u", am
->route_metric
);
348 vty_out(vty
, "%-9s %-15s %-15s %-15s %-3s %-4s %-6s %-15s\n",
349 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
, ch_grp_str
,
350 am
->rpt_bit_flag
? "yes" : "no", pref_str
, metr_str
, addr_str
);
353 static void pim_show_assert_winner_metric(struct pim_instance
*pim
,
356 struct pim_interface
*pim_ifp
;
357 struct pim_ifchannel
*ch
;
358 struct interface
*ifp
;
361 "Interface Address Source Group RPT Pref Metric Address \n");
363 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
368 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
369 pim_show_assert_winner_metric_helper(vty
, pim_ifp
, ch
);
370 } /* scan interface channels */
374 static void json_object_pim_ifp_add(struct json_object
*json
,
375 struct interface
*ifp
)
377 struct pim_interface
*pim_ifp
;
380 json_object_string_add(json
, "name", ifp
->name
);
381 json_object_string_add(json
, "state", if_is_up(ifp
) ? "up" : "down");
382 json_object_string_add(json
, "address",
383 inet_ntoa(pim_ifp
->primary_address
));
384 json_object_int_add(json
, "index", ifp
->ifindex
);
386 if (if_is_multicast(ifp
))
387 json_object_boolean_true_add(json
, "flagMulticast");
389 if (if_is_broadcast(ifp
))
390 json_object_boolean_true_add(json
, "flagBroadcast");
392 if (ifp
->flags
& IFF_ALLMULTI
)
393 json_object_boolean_true_add(json
, "flagAllMulticast");
395 if (ifp
->flags
& IFF_PROMISC
)
396 json_object_boolean_true_add(json
, "flagPromiscuous");
398 if (PIM_IF_IS_DELETED(ifp
))
399 json_object_boolean_true_add(json
, "flagDeleted");
401 if (pim_if_lan_delay_enabled(ifp
))
402 json_object_boolean_true_add(json
, "lanDelayEnabled");
405 static void pim_show_membership_helper(struct vty
*vty
,
406 struct pim_interface
*pim_ifp
,
407 struct pim_ifchannel
*ch
,
408 struct json_object
*json
)
410 char ch_src_str
[INET_ADDRSTRLEN
];
411 char ch_grp_str
[INET_ADDRSTRLEN
];
412 json_object
*json_iface
= NULL
;
413 json_object
*json_row
= NULL
;
415 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
416 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
418 json_object_object_get_ex(json
, ch
->interface
->name
, &json_iface
);
420 json_iface
= json_object_new_object();
421 json_object_pim_ifp_add(json_iface
, ch
->interface
);
422 json_object_object_add(json
, ch
->interface
->name
, json_iface
);
425 json_row
= json_object_new_object();
426 json_object_string_add(json_row
, "source", ch_src_str
);
427 json_object_string_add(json_row
, "group", ch_grp_str
);
428 json_object_string_add(json_row
, "localMembership",
429 ch
->local_ifmembership
== PIM_IFMEMBERSHIP_NOINFO
432 json_object_object_add(json_iface
, ch_grp_str
, json_row
);
434 static void pim_show_membership(struct pim_instance
*pim
, struct vty
*vty
,
437 struct pim_interface
*pim_ifp
;
438 struct pim_ifchannel
*ch
;
439 struct interface
*ifp
;
441 json_object
*json
= NULL
;
442 json_object
*json_tmp
= NULL
;
444 json
= json_object_new_object();
446 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
451 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
452 pim_show_membership_helper(vty
, pim_ifp
, ch
, json
);
453 } /* scan interface channels */
457 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
458 json
, JSON_C_TO_STRING_PRETTY
));
461 "Interface Address Source Group Membership\n");
464 * Example of the json data we are traversing
470 * "address":"10.1.20.1",
472 * "flagMulticast":true,
473 * "flagBroadcast":true,
474 * "lanDelayEnabled":true,
477 * "group":"226.10.10.10",
478 * "localMembership":"INCLUDE"
484 /* foreach interface */
485 json_object_object_foreach(json
, key
, val
)
488 /* Find all of the keys where the val is an object. In
490 * above the only one is 226.10.10.10
492 json_object_object_foreach(val
, if_field_key
,
495 type
= json_object_get_type(if_field_val
);
497 if (type
== json_type_object
) {
498 vty_out(vty
, "%-9s ", key
);
500 json_object_object_get_ex(
501 val
, "address", &json_tmp
);
502 vty_out(vty
, "%-15s ",
503 json_object_get_string(
506 json_object_object_get_ex(if_field_val
,
509 vty_out(vty
, "%-15s ",
510 json_object_get_string(
514 vty_out(vty
, "%-15s ", if_field_key
);
516 json_object_object_get_ex(
517 if_field_val
, "localMembership",
519 vty_out(vty
, "%-10s\n",
520 json_object_get_string(
527 json_object_free(json
);
530 static void pim_print_ifp_flags(struct vty
*vty
, struct interface
*ifp
,
533 vty_out(vty
, "Flags\n");
534 vty_out(vty
, "-----\n");
535 vty_out(vty
, "All Multicast : %s\n",
536 (ifp
->flags
& IFF_ALLMULTI
) ? "yes" : "no");
537 vty_out(vty
, "Broadcast : %s\n",
538 if_is_broadcast(ifp
) ? "yes" : "no");
539 vty_out(vty
, "Deleted : %s\n",
540 PIM_IF_IS_DELETED(ifp
) ? "yes" : "no");
541 vty_out(vty
, "Interface Index : %d\n", ifp
->ifindex
);
542 vty_out(vty
, "Multicast : %s\n",
543 if_is_multicast(ifp
) ? "yes" : "no");
544 vty_out(vty
, "Multicast Loop : %d\n", mloop
);
545 vty_out(vty
, "Promiscuous : %s\n",
546 (ifp
->flags
& IFF_PROMISC
) ? "yes" : "no");
551 static void igmp_show_interfaces(struct pim_instance
*pim
, struct vty
*vty
,
554 struct interface
*ifp
;
556 json_object
*json
= NULL
;
557 json_object
*json_row
= NULL
;
559 now
= pim_time_monotonic_sec();
562 json
= json_object_new_object();
565 "Interface State Address V Querier Query Timer Uptime\n");
567 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
568 struct pim_interface
*pim_ifp
;
569 struct listnode
*sock_node
;
570 struct igmp_sock
*igmp
;
577 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
580 char query_hhmmss
[10];
582 pim_time_uptime(uptime
, sizeof(uptime
),
583 now
- igmp
->sock_creation
);
584 pim_time_timer_to_hhmmss(query_hhmmss
,
585 sizeof(query_hhmmss
),
586 igmp
->t_igmp_query_timer
);
589 json_row
= json_object_new_object();
590 json_object_pim_ifp_add(json_row
, ifp
);
591 json_object_string_add(json_row
, "upTime",
593 json_object_int_add(json_row
, "version",
594 pim_ifp
->igmp_version
);
596 if (igmp
->t_igmp_query_timer
) {
597 json_object_boolean_true_add(json_row
,
599 json_object_string_add(json_row
,
604 json_object_object_add(json
, ifp
->name
,
607 if (igmp
->mtrace_only
) {
608 json_object_boolean_true_add(
609 json_row
, "mtraceOnly");
613 "%-9s %5s %15s %d %7s %11s %8s\n",
616 ? (igmp
->mtrace_only
? "mtrc"
619 inet_ntoa(igmp
->ifaddr
),
620 pim_ifp
->igmp_version
,
621 igmp
->t_igmp_query_timer
? "local"
623 query_hhmmss
, uptime
);
629 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
630 json
, JSON_C_TO_STRING_PRETTY
));
631 json_object_free(json
);
635 static void igmp_show_interfaces_single(struct pim_instance
*pim
,
636 struct vty
*vty
, const char *ifname
,
639 struct igmp_sock
*igmp
;
640 struct interface
*ifp
;
641 struct listnode
*sock_node
;
642 struct pim_interface
*pim_ifp
;
644 char query_hhmmss
[10];
645 char other_hhmmss
[10];
646 int found_ifname
= 0;
649 long gmi_msec
; /* Group Membership Interval */
652 long oqpi_msec
; /* Other Querier Present Interval */
656 json_object
*json
= NULL
;
657 json_object
*json_row
= NULL
;
660 json
= json_object_new_object();
662 now
= pim_time_monotonic_sec();
664 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
670 if (strcmp(ifname
, "detail") && strcmp(ifname
, ifp
->name
))
673 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
676 pim_time_uptime(uptime
, sizeof(uptime
),
677 now
- igmp
->sock_creation
);
678 pim_time_timer_to_hhmmss(query_hhmmss
,
679 sizeof(query_hhmmss
),
680 igmp
->t_igmp_query_timer
);
681 pim_time_timer_to_hhmmss(other_hhmmss
,
682 sizeof(other_hhmmss
),
683 igmp
->t_other_querier_timer
);
685 gmi_msec
= PIM_IGMP_GMI_MSEC(
686 igmp
->querier_robustness_variable
,
687 igmp
->querier_query_interval
,
688 pim_ifp
->igmp_query_max_response_time_dsec
);
691 pim_ifp
->igmp_default_query_interval
);
693 oqpi_msec
= PIM_IGMP_OQPI_MSEC(
694 igmp
->querier_robustness_variable
,
695 igmp
->querier_query_interval
,
696 pim_ifp
->igmp_query_max_response_time_dsec
);
698 lmqt_msec
= PIM_IGMP_LMQT_MSEC(
699 pim_ifp
->igmp_query_max_response_time_dsec
,
700 igmp
->querier_robustness_variable
);
704 igmp
->querier_robustness_variable
,
705 igmp
->querier_query_interval
,
706 pim_ifp
->igmp_query_max_response_time_dsec
)
709 qri_msec
= pim_ifp
->igmp_query_max_response_time_dsec
711 if (pim_ifp
->pim_sock_fd
>= 0)
712 mloop
= pim_socket_mcastloop_get(
713 pim_ifp
->pim_sock_fd
);
718 json_row
= json_object_new_object();
719 json_object_pim_ifp_add(json_row
, ifp
);
720 json_object_string_add(json_row
, "upTime",
722 json_object_string_add(json_row
, "querier",
723 igmp
->t_igmp_query_timer
726 json_object_int_add(json_row
, "queryStartCount",
727 igmp
->startup_query_count
);
728 json_object_string_add(json_row
,
731 json_object_string_add(json_row
,
734 json_object_int_add(json_row
, "version",
735 pim_ifp
->igmp_version
);
738 "timerGroupMembershipIntervalMsec",
740 json_object_int_add(json_row
,
741 "timerLastMemberQueryMsec",
745 "timerOlderHostPresentIntervalMsec",
749 "timerOtherQuerierPresentIntervalMsec",
752 json_row
, "timerQueryInterval",
753 igmp
->querier_query_interval
);
756 "timerQueryResponseIntervalMsec",
759 json_row
, "timerRobustnessVariable",
760 igmp
->querier_robustness_variable
);
761 json_object_int_add(json_row
,
762 "timerStartupQueryInterval",
765 json_object_object_add(json
, ifp
->name
,
768 if (igmp
->mtrace_only
) {
769 json_object_boolean_true_add(
770 json_row
, "mtraceOnly");
773 vty_out(vty
, "Interface : %s\n", ifp
->name
);
774 vty_out(vty
, "State : %s\n",
776 ? (igmp
->mtrace_only
? "mtrace"
779 vty_out(vty
, "Address : %s\n",
780 inet_ntoa(pim_ifp
->primary_address
));
781 vty_out(vty
, "Uptime : %s\n", uptime
);
782 vty_out(vty
, "Version : %d\n",
783 pim_ifp
->igmp_version
);
787 vty_out(vty
, "Querier\n");
788 vty_out(vty
, "-------\n");
789 vty_out(vty
, "Querier : %s\n",
790 igmp
->t_igmp_query_timer
? "local"
792 vty_out(vty
, "Start Count : %d\n",
793 igmp
->startup_query_count
);
794 vty_out(vty
, "Query Timer : %s\n",
796 vty_out(vty
, "Other Timer : %s\n",
801 vty_out(vty
, "Timers\n");
802 vty_out(vty
, "------\n");
804 "Group Membership Interval : %lis\n",
807 "Last Member Query Time : %lis\n",
810 "Older Host Present Interval : %lis\n",
813 "Other Querier Present Interval : %lis\n",
816 "Query Interval : %ds\n",
817 igmp
->querier_query_interval
);
819 "Query Response Interval : %lis\n",
822 "Robustness Variable : %d\n",
823 igmp
->querier_robustness_variable
);
825 "Startup Query Interval : %ds\n",
830 pim_print_ifp_flags(vty
, ifp
, mloop
);
836 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
837 json
, JSON_C_TO_STRING_PRETTY
));
838 json_object_free(json
);
841 vty_out(vty
, "%% No such interface\n");
845 static void igmp_show_interface_join(struct pim_instance
*pim
, struct vty
*vty
)
847 struct interface
*ifp
;
850 now
= pim_time_monotonic_sec();
853 "Interface Address Source Group Socket Uptime \n");
855 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
856 struct pim_interface
*pim_ifp
;
857 struct listnode
*join_node
;
858 struct igmp_join
*ij
;
859 struct in_addr pri_addr
;
860 char pri_addr_str
[INET_ADDRSTRLEN
];
867 if (!pim_ifp
->igmp_join_list
)
870 pri_addr
= pim_find_primary_addr(ifp
);
871 pim_inet4_dump("<pri?>", pri_addr
, pri_addr_str
,
872 sizeof(pri_addr_str
));
874 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_join_list
, join_node
,
876 char group_str
[INET_ADDRSTRLEN
];
877 char source_str
[INET_ADDRSTRLEN
];
880 pim_time_uptime(uptime
, sizeof(uptime
),
881 now
- ij
->sock_creation
);
882 pim_inet4_dump("<grp?>", ij
->group_addr
, group_str
,
884 pim_inet4_dump("<src?>", ij
->source_addr
, source_str
,
887 vty_out(vty
, "%-9s %-15s %-15s %-15s %6d %8s\n",
888 ifp
->name
, pri_addr_str
, source_str
, group_str
,
889 ij
->sock_fd
, uptime
);
890 } /* for (pim_ifp->igmp_join_list) */
895 static void pim_show_interfaces_single(struct pim_instance
*pim
,
896 struct vty
*vty
, const char *ifname
,
899 struct in_addr ifaddr
;
900 struct interface
*ifp
;
901 struct listnode
*neighnode
;
902 struct listnode
*upnode
;
903 struct pim_interface
*pim_ifp
;
904 struct pim_neighbor
*neigh
;
905 struct pim_upstream
*up
;
907 char dr_str
[INET_ADDRSTRLEN
];
910 char grp_str
[INET_ADDRSTRLEN
];
911 char hello_period
[10];
912 char hello_timer
[10];
913 char neigh_src_str
[INET_ADDRSTRLEN
];
914 char src_str
[INET_ADDRSTRLEN
];
915 char stat_uptime
[10];
918 int found_ifname
= 0;
920 json_object
*json
= NULL
;
921 json_object
*json_row
= NULL
;
922 json_object
*json_pim_neighbor
= NULL
;
923 json_object
*json_pim_neighbors
= NULL
;
924 json_object
*json_group
= NULL
;
925 json_object
*json_group_source
= NULL
;
926 json_object
*json_fhr_sources
= NULL
;
927 struct pim_secondary_addr
*sec_addr
;
928 struct listnode
*sec_node
;
930 now
= pim_time_monotonic_sec();
933 json
= json_object_new_object();
935 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
941 if (strcmp(ifname
, "detail") && strcmp(ifname
, ifp
->name
))
945 ifaddr
= pim_ifp
->primary_address
;
946 pim_inet4_dump("<dr?>", pim_ifp
->pim_dr_addr
, dr_str
,
948 pim_time_uptime_begin(dr_uptime
, sizeof(dr_uptime
), now
,
949 pim_ifp
->pim_dr_election_last
);
950 pim_time_timer_to_hhmmss(hello_timer
, sizeof(hello_timer
),
951 pim_ifp
->t_pim_hello_timer
);
952 pim_time_mmss(hello_period
, sizeof(hello_period
),
953 pim_ifp
->pim_hello_period
);
954 pim_time_uptime(stat_uptime
, sizeof(stat_uptime
),
955 now
- pim_ifp
->pim_ifstat_start
);
956 if (pim_ifp
->pim_sock_fd
>= 0)
957 mloop
= pim_socket_mcastloop_get(pim_ifp
->pim_sock_fd
);
962 char pbuf
[PREFIX2STR_BUFFER
];
963 json_row
= json_object_new_object();
964 json_object_pim_ifp_add(json_row
, ifp
);
966 if (pim_ifp
->update_source
.s_addr
!= INADDR_ANY
) {
967 json_object_string_add(
968 json_row
, "useSource",
969 inet_ntoa(pim_ifp
->update_source
));
971 if (pim_ifp
->sec_addr_list
) {
972 json_object
*sec_list
= NULL
;
974 sec_list
= json_object_new_array();
975 for (ALL_LIST_ELEMENTS_RO(
976 pim_ifp
->sec_addr_list
, sec_node
,
978 json_object_array_add(
980 json_object_new_string(
986 json_object_object_add(json_row
,
987 "secondaryAddressList",
992 if (pim_ifp
->pim_neighbor_list
->count
) {
993 json_pim_neighbors
= json_object_new_object();
995 for (ALL_LIST_ELEMENTS_RO(
996 pim_ifp
->pim_neighbor_list
,
999 json_object_new_object();
1000 pim_inet4_dump("<src?>",
1003 sizeof(neigh_src_str
));
1004 pim_time_uptime(uptime
, sizeof(uptime
),
1005 now
- neigh
->creation
);
1006 pim_time_timer_to_hhmmss(
1007 expire
, sizeof(expire
),
1008 neigh
->t_expire_timer
);
1010 json_object_string_add(
1011 json_pim_neighbor
, "address",
1013 json_object_string_add(
1014 json_pim_neighbor
, "upTime",
1016 json_object_string_add(
1017 json_pim_neighbor
, "holdtime",
1020 json_object_object_add(
1026 json_object_object_add(json_row
, "neighbors",
1027 json_pim_neighbors
);
1030 json_object_string_add(json_row
, "drAddress", dr_str
);
1031 json_object_int_add(json_row
, "drPriority",
1032 pim_ifp
->pim_dr_priority
);
1033 json_object_string_add(json_row
, "drUptime", dr_uptime
);
1034 json_object_int_add(json_row
, "drElections",
1035 pim_ifp
->pim_dr_election_count
);
1036 json_object_int_add(json_row
, "drChanges",
1037 pim_ifp
->pim_dr_election_changes
);
1040 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
,
1042 if (ifp
!= up
->rpf
.source_nexthop
.interface
)
1045 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
))
1048 if (!json_fhr_sources
)
1050 json_object_new_object();
1052 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
,
1054 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
,
1056 pim_time_uptime(uptime
, sizeof(uptime
),
1057 now
- up
->state_transition
);
1060 * Does this group live in json_fhr_sources?
1063 json_object_object_get_ex(json_fhr_sources
,
1064 grp_str
, &json_group
);
1067 json_group
= json_object_new_object();
1068 json_object_object_add(json_fhr_sources
,
1073 json_group_source
= json_object_new_object();
1074 json_object_string_add(json_group_source
,
1076 json_object_string_add(json_group_source
,
1078 json_object_string_add(json_group_source
,
1080 json_object_object_add(json_group
, src_str
,
1084 if (json_fhr_sources
) {
1085 json_object_object_add(json_row
,
1090 json_object_int_add(json_row
, "helloPeriod",
1091 pim_ifp
->pim_hello_period
);
1092 json_object_string_add(json_row
, "helloTimer",
1094 json_object_string_add(json_row
, "helloStatStart",
1096 json_object_int_add(json_row
, "helloReceived",
1097 pim_ifp
->pim_ifstat_hello_recv
);
1098 json_object_int_add(json_row
, "helloReceivedFailed",
1099 pim_ifp
->pim_ifstat_hello_recvfail
);
1100 json_object_int_add(json_row
, "helloSend",
1101 pim_ifp
->pim_ifstat_hello_sent
);
1102 json_object_int_add(json_row
, "hellosendFailed",
1103 pim_ifp
->pim_ifstat_hello_sendfail
);
1104 json_object_int_add(json_row
, "helloGenerationId",
1105 pim_ifp
->pim_generation_id
);
1106 json_object_int_add(json_row
, "flagMulticastLoop",
1109 json_object_int_add(
1110 json_row
, "effectivePropagationDelay",
1111 pim_if_effective_propagation_delay_msec(ifp
));
1112 json_object_int_add(
1113 json_row
, "effectiveOverrideInterval",
1114 pim_if_effective_override_interval_msec(ifp
));
1115 json_object_int_add(
1116 json_row
, "joinPruneOverrideInterval",
1117 pim_if_jp_override_interval_msec(ifp
));
1119 json_object_int_add(
1120 json_row
, "propagationDelay",
1121 pim_ifp
->pim_propagation_delay_msec
);
1122 json_object_int_add(
1123 json_row
, "propagationDelayHighest",
1124 pim_ifp
->pim_neighbors_highest_propagation_delay_msec
);
1125 json_object_int_add(
1126 json_row
, "overrideInterval",
1127 pim_ifp
->pim_override_interval_msec
);
1128 json_object_int_add(
1129 json_row
, "overrideIntervalHighest",
1130 pim_ifp
->pim_neighbors_highest_override_interval_msec
);
1131 json_object_object_add(json
, ifp
->name
, json_row
);
1134 vty_out(vty
, "Interface : %s\n", ifp
->name
);
1135 vty_out(vty
, "State : %s\n",
1136 if_is_up(ifp
) ? "up" : "down");
1137 if (pim_ifp
->update_source
.s_addr
!= INADDR_ANY
) {
1138 vty_out(vty
, "Use Source : %s\n",
1139 inet_ntoa(pim_ifp
->update_source
));
1141 if (pim_ifp
->sec_addr_list
) {
1142 char pbuf
[PREFIX2STR_BUFFER
];
1143 vty_out(vty
, "Address : %s (primary)\n",
1145 for (ALL_LIST_ELEMENTS_RO(
1146 pim_ifp
->sec_addr_list
, sec_node
,
1148 vty_out(vty
, " %s\n",
1149 prefix2str(&sec_addr
->addr
,
1150 pbuf
, sizeof(pbuf
)));
1153 vty_out(vty
, "Address : %s\n",
1161 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
,
1162 neighnode
, neigh
)) {
1165 vty_out(vty
, "PIM Neighbors\n");
1166 vty_out(vty
, "-------------\n");
1170 pim_inet4_dump("<src?>", neigh
->source_addr
,
1172 sizeof(neigh_src_str
));
1173 pim_time_uptime(uptime
, sizeof(uptime
),
1174 now
- neigh
->creation
);
1175 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
1176 neigh
->t_expire_timer
);
1178 "%-15s : up for %s, holdtime expires in %s\n",
1179 neigh_src_str
, uptime
, expire
);
1182 if (!print_header
) {
1187 vty_out(vty
, "Designated Router\n");
1188 vty_out(vty
, "-----------------\n");
1189 vty_out(vty
, "Address : %s\n", dr_str
);
1190 vty_out(vty
, "Priority : %d\n",
1191 pim_ifp
->pim_dr_priority
);
1192 vty_out(vty
, "Uptime : %s\n", dr_uptime
);
1193 vty_out(vty
, "Elections : %d\n",
1194 pim_ifp
->pim_dr_election_count
);
1195 vty_out(vty
, "Changes : %d\n",
1196 pim_ifp
->pim_dr_election_changes
);
1202 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
,
1205 if (strcmp(ifp
->name
,
1206 up
->rpf
.source_nexthop
1211 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
))
1216 "FHR - First Hop Router\n");
1218 "----------------------\n");
1222 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
,
1224 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
,
1226 pim_time_uptime(uptime
, sizeof(uptime
),
1227 now
- up
->state_transition
);
1229 "%s : %s is a source, uptime is %s\n",
1230 grp_str
, src_str
, uptime
);
1233 if (!print_header
) {
1238 vty_out(vty
, "Hellos\n");
1239 vty_out(vty
, "------\n");
1240 vty_out(vty
, "Period : %d\n",
1241 pim_ifp
->pim_hello_period
);
1242 vty_out(vty
, "Timer : %s\n", hello_timer
);
1243 vty_out(vty
, "StatStart : %s\n", stat_uptime
);
1244 vty_out(vty
, "Receive : %d\n",
1245 pim_ifp
->pim_ifstat_hello_recv
);
1246 vty_out(vty
, "Receive Failed : %d\n",
1247 pim_ifp
->pim_ifstat_hello_recvfail
);
1248 vty_out(vty
, "Send : %d\n",
1249 pim_ifp
->pim_ifstat_hello_sent
);
1250 vty_out(vty
, "Send Failed : %d\n",
1251 pim_ifp
->pim_ifstat_hello_sendfail
);
1252 vty_out(vty
, "Generation ID : %08x\n",
1253 pim_ifp
->pim_generation_id
);
1257 pim_print_ifp_flags(vty
, ifp
, mloop
);
1259 vty_out(vty
, "Join Prune Interval\n");
1260 vty_out(vty
, "-------------------\n");
1261 vty_out(vty
, "LAN Delay : %s\n",
1262 pim_if_lan_delay_enabled(ifp
) ? "yes" : "no");
1263 vty_out(vty
, "Effective Propagation Delay : %d msec\n",
1264 pim_if_effective_propagation_delay_msec(ifp
));
1265 vty_out(vty
, "Effective Override Interval : %d msec\n",
1266 pim_if_effective_override_interval_msec(ifp
));
1267 vty_out(vty
, "Join Prune Override Interval : %d msec\n",
1268 pim_if_jp_override_interval_msec(ifp
));
1272 vty_out(vty
, "LAN Prune Delay\n");
1273 vty_out(vty
, "---------------\n");
1274 vty_out(vty
, "Propagation Delay : %d msec\n",
1275 pim_ifp
->pim_propagation_delay_msec
);
1276 vty_out(vty
, "Propagation Delay (Highest) : %d msec\n",
1277 pim_ifp
->pim_neighbors_highest_propagation_delay_msec
);
1278 vty_out(vty
, "Override Interval : %d msec\n",
1279 pim_ifp
->pim_override_interval_msec
);
1280 vty_out(vty
, "Override Interval (Highest) : %d msec\n",
1281 pim_ifp
->pim_neighbors_highest_override_interval_msec
);
1288 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1289 json
, JSON_C_TO_STRING_PRETTY
));
1290 json_object_free(json
);
1293 vty_out(vty
, "%% No such interface\n");
1297 static void igmp_show_statistics(struct pim_instance
*pim
, struct vty
*vty
,
1298 const char *ifname
, uint8_t uj
)
1300 struct interface
*ifp
;
1301 struct igmp_stats rx_stats
;
1303 igmp_stats_init(&rx_stats
);
1305 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1306 struct pim_interface
*pim_ifp
;
1307 struct listnode
*sock_node
;
1308 struct igmp_sock
*igmp
;
1310 pim_ifp
= ifp
->info
;
1315 if (ifname
&& strcmp(ifname
, ifp
->name
))
1318 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
1320 igmp_stats_add(&rx_stats
, &igmp
->rx_stats
);
1324 json_object
*json
= NULL
;
1325 json_object
*json_row
= NULL
;
1327 json
= json_object_new_object();
1328 json_row
= json_object_new_object();
1330 json_object_string_add(json_row
, "name", ifname
? ifname
:
1332 json_object_int_add(json_row
, "queryV1", rx_stats
.query_v1
);
1333 json_object_int_add(json_row
, "queryV2", rx_stats
.query_v2
);
1334 json_object_int_add(json_row
, "queryV3", rx_stats
.query_v3
);
1335 json_object_int_add(json_row
, "leaveV3", rx_stats
.leave_v2
);
1336 json_object_int_add(json_row
, "reportV1", rx_stats
.report_v1
);
1337 json_object_int_add(json_row
, "reportV2", rx_stats
.report_v2
);
1338 json_object_int_add(json_row
, "reportV3", rx_stats
.report_v3
);
1339 json_object_int_add(json_row
, "mtraceResponse",
1340 rx_stats
.mtrace_rsp
);
1341 json_object_int_add(json_row
, "mtraceRequest",
1342 rx_stats
.mtrace_req
);
1343 json_object_int_add(json_row
, "unsupported",
1344 rx_stats
.unsupported
);
1345 json_object_object_add(json
, ifname
? ifname
: "global",
1347 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1348 json
, JSON_C_TO_STRING_PRETTY
));
1349 json_object_free(json
);
1351 vty_out(vty
, "IGMP RX statistics\n");
1352 vty_out(vty
, "Interface : %s\n",
1353 ifname
? ifname
: "global");
1354 vty_out(vty
, "V1 query : %u\n", rx_stats
.query_v1
);
1355 vty_out(vty
, "V2 query : %u\n", rx_stats
.query_v2
);
1356 vty_out(vty
, "V3 query : %u\n", rx_stats
.query_v3
);
1357 vty_out(vty
, "V2 leave : %u\n", rx_stats
.leave_v2
);
1358 vty_out(vty
, "V1 report : %u\n", rx_stats
.report_v1
);
1359 vty_out(vty
, "V2 report : %u\n", rx_stats
.report_v2
);
1360 vty_out(vty
, "V3 report : %u\n", rx_stats
.report_v3
);
1361 vty_out(vty
, "mtrace response : %u\n", rx_stats
.mtrace_rsp
);
1362 vty_out(vty
, "mtrace request : %u\n", rx_stats
.mtrace_req
);
1363 vty_out(vty
, "unsupported : %u\n", rx_stats
.unsupported
);
1367 static void pim_show_interfaces(struct pim_instance
*pim
, struct vty
*vty
,
1370 struct interface
*ifp
;
1371 struct listnode
*upnode
;
1372 struct pim_interface
*pim_ifp
;
1373 struct pim_upstream
*up
;
1376 int pim_ifchannels
= 0;
1377 json_object
*json
= NULL
;
1378 json_object
*json_row
= NULL
;
1379 json_object
*json_tmp
;
1381 json
= json_object_new_object();
1383 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1384 pim_ifp
= ifp
->info
;
1389 pim_nbrs
= pim_ifp
->pim_neighbor_list
->count
;
1390 pim_ifchannels
= pim_if_ifchannel_count(pim_ifp
);
1393 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
, up
))
1394 if (ifp
== up
->rpf
.source_nexthop
.interface
)
1395 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
1398 json_row
= json_object_new_object();
1399 json_object_pim_ifp_add(json_row
, ifp
);
1400 json_object_int_add(json_row
, "pimNeighbors", pim_nbrs
);
1401 json_object_int_add(json_row
, "pimIfChannels", pim_ifchannels
);
1402 json_object_int_add(json_row
, "firstHopRouterCount", fhr
);
1403 json_object_string_add(json_row
, "pimDesignatedRouter",
1404 inet_ntoa(pim_ifp
->pim_dr_addr
));
1406 if (pim_ifp
->pim_dr_addr
.s_addr
1407 == pim_ifp
->primary_address
.s_addr
)
1408 json_object_boolean_true_add(
1409 json_row
, "pimDesignatedRouterLocal");
1411 json_object_object_add(json
, ifp
->name
, json_row
);
1415 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1416 json
, JSON_C_TO_STRING_PRETTY
));
1419 "Interface State Address PIM Nbrs PIM DR FHR IfChannels\n");
1421 json_object_object_foreach(json
, key
, val
)
1423 vty_out(vty
, "%-9s ", key
);
1425 json_object_object_get_ex(val
, "state", &json_tmp
);
1426 vty_out(vty
, "%5s ", json_object_get_string(json_tmp
));
1428 json_object_object_get_ex(val
, "address", &json_tmp
);
1429 vty_out(vty
, "%15s ",
1430 json_object_get_string(json_tmp
));
1432 json_object_object_get_ex(val
, "pimNeighbors",
1434 vty_out(vty
, "%8d ", json_object_get_int(json_tmp
));
1436 if (json_object_object_get_ex(
1437 val
, "pimDesignatedRouterLocal",
1439 vty_out(vty
, "%15s ", "local");
1441 json_object_object_get_ex(
1442 val
, "pimDesignatedRouter", &json_tmp
);
1443 vty_out(vty
, "%15s ",
1444 json_object_get_string(json_tmp
));
1447 json_object_object_get_ex(val
, "firstHopRouter",
1449 vty_out(vty
, "%3d ", json_object_get_int(json_tmp
));
1451 json_object_object_get_ex(val
, "pimIfChannels",
1453 vty_out(vty
, "%9d\n", json_object_get_int(json_tmp
));
1457 json_object_free(json
);
1460 static void pim_show_interface_traffic(struct pim_instance
*pim
,
1461 struct vty
*vty
, uint8_t uj
)
1463 struct interface
*ifp
= NULL
;
1464 struct pim_interface
*pim_ifp
= NULL
;
1465 json_object
*json
= NULL
;
1466 json_object
*json_row
= NULL
;
1469 json
= json_object_new_object();
1472 vty_out(vty
, "%-12s%-17s%-17s%-17s%-17s%-17s%-17s\n",
1473 "Interface", " HELLO", " JOIN", " PRUNE",
1474 " REGISTER", " REGISTER-STOP", " ASSERT");
1475 vty_out(vty
, "%-10s%-18s%-17s%-17s%-17s%-17s%-17s\n", "",
1476 " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1477 " Rx/Tx", " Rx/Tx");
1479 "---------------------------------------------------------------------------------------------------------------\n");
1482 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1483 pim_ifp
= ifp
->info
;
1488 if (pim_ifp
->pim_sock_fd
< 0)
1491 json_row
= json_object_new_object();
1492 json_object_pim_ifp_add(json_row
, ifp
);
1493 json_object_int_add(json_row
, "helloRx",
1494 pim_ifp
->pim_ifstat_hello_recv
);
1495 json_object_int_add(json_row
, "helloTx",
1496 pim_ifp
->pim_ifstat_hello_sent
);
1497 json_object_int_add(json_row
, "joinRx",
1498 pim_ifp
->pim_ifstat_join_recv
);
1499 json_object_int_add(json_row
, "joinTx",
1500 pim_ifp
->pim_ifstat_join_send
);
1501 json_object_int_add(json_row
, "registerRx",
1502 pim_ifp
->pim_ifstat_reg_recv
);
1503 json_object_int_add(json_row
, "registerTx",
1504 pim_ifp
->pim_ifstat_reg_recv
);
1505 json_object_int_add(json_row
, "registerStopRx",
1506 pim_ifp
->pim_ifstat_reg_stop_recv
);
1507 json_object_int_add(json_row
, "registerStopTx",
1508 pim_ifp
->pim_ifstat_reg_stop_send
);
1509 json_object_int_add(json_row
, "assertRx",
1510 pim_ifp
->pim_ifstat_assert_recv
);
1511 json_object_int_add(json_row
, "assertTx",
1512 pim_ifp
->pim_ifstat_assert_send
);
1514 json_object_object_add(json
, ifp
->name
, json_row
);
1517 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u \n",
1518 ifp
->name
, pim_ifp
->pim_ifstat_hello_recv
,
1519 pim_ifp
->pim_ifstat_hello_sent
,
1520 pim_ifp
->pim_ifstat_join_recv
,
1521 pim_ifp
->pim_ifstat_join_send
,
1522 pim_ifp
->pim_ifstat_prune_recv
,
1523 pim_ifp
->pim_ifstat_prune_send
,
1524 pim_ifp
->pim_ifstat_reg_recv
,
1525 pim_ifp
->pim_ifstat_reg_send
,
1526 pim_ifp
->pim_ifstat_reg_stop_recv
,
1527 pim_ifp
->pim_ifstat_reg_stop_send
,
1528 pim_ifp
->pim_ifstat_assert_recv
,
1529 pim_ifp
->pim_ifstat_assert_send
);
1533 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1534 json
, JSON_C_TO_STRING_PRETTY
));
1535 json_object_free(json
);
1539 static void pim_show_interface_traffic_single(struct pim_instance
*pim
,
1541 const char *ifname
, uint8_t uj
)
1543 struct interface
*ifp
= NULL
;
1544 struct pim_interface
*pim_ifp
= NULL
;
1545 json_object
*json
= NULL
;
1546 json_object
*json_row
= NULL
;
1547 uint8_t found_ifname
= 0;
1550 json
= json_object_new_object();
1553 vty_out(vty
, "%-12s%-17s%-17s%-17s%-17s%-17s%-17s\n",
1554 "Interface", " HELLO", " JOIN", " PRUNE",
1555 " REGISTER", " REGISTER-STOP", " ASSERT");
1556 vty_out(vty
, "%-10s%-18s%-17s%-17s%-17s%-17s%-17s\n", "",
1557 " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1558 " Rx/Tx", " Rx/Tx");
1560 "---------------------------------------------------------------------------------------------------------------\n");
1563 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1564 if (strcmp(ifname
, ifp
->name
))
1567 pim_ifp
= ifp
->info
;
1572 if (pim_ifp
->pim_sock_fd
< 0)
1577 json_row
= json_object_new_object();
1578 json_object_pim_ifp_add(json_row
, ifp
);
1579 json_object_int_add(json_row
, "helloRx",
1580 pim_ifp
->pim_ifstat_hello_recv
);
1581 json_object_int_add(json_row
, "helloTx",
1582 pim_ifp
->pim_ifstat_hello_sent
);
1583 json_object_int_add(json_row
, "joinRx",
1584 pim_ifp
->pim_ifstat_join_recv
);
1585 json_object_int_add(json_row
, "joinTx",
1586 pim_ifp
->pim_ifstat_join_send
);
1587 json_object_int_add(json_row
, "registerRx",
1588 pim_ifp
->pim_ifstat_reg_recv
);
1589 json_object_int_add(json_row
, "registerTx",
1590 pim_ifp
->pim_ifstat_reg_recv
);
1591 json_object_int_add(json_row
, "registerStopRx",
1592 pim_ifp
->pim_ifstat_reg_stop_recv
);
1593 json_object_int_add(json_row
, "registerStopTx",
1594 pim_ifp
->pim_ifstat_reg_stop_send
);
1595 json_object_int_add(json_row
, "assertRx",
1596 pim_ifp
->pim_ifstat_assert_recv
);
1597 json_object_int_add(json_row
, "assertTx",
1598 pim_ifp
->pim_ifstat_assert_send
);
1600 json_object_object_add(json
, ifp
->name
, json_row
);
1603 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u \n",
1604 ifp
->name
, pim_ifp
->pim_ifstat_hello_recv
,
1605 pim_ifp
->pim_ifstat_hello_sent
,
1606 pim_ifp
->pim_ifstat_join_recv
,
1607 pim_ifp
->pim_ifstat_join_send
,
1608 pim_ifp
->pim_ifstat_prune_recv
,
1609 pim_ifp
->pim_ifstat_prune_send
,
1610 pim_ifp
->pim_ifstat_reg_recv
,
1611 pim_ifp
->pim_ifstat_reg_send
,
1612 pim_ifp
->pim_ifstat_reg_stop_recv
,
1613 pim_ifp
->pim_ifstat_reg_stop_send
,
1614 pim_ifp
->pim_ifstat_assert_recv
,
1615 pim_ifp
->pim_ifstat_assert_send
);
1619 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1620 json
, JSON_C_TO_STRING_PRETTY
));
1621 json_object_free(json
);
1624 vty_out(vty
, "%% No such interface\n");
1628 static void pim_show_join_helper(struct vty
*vty
, struct pim_interface
*pim_ifp
,
1629 struct pim_ifchannel
*ch
, json_object
*json
,
1630 time_t now
, uint8_t uj
)
1632 char ch_src_str
[INET_ADDRSTRLEN
];
1633 char ch_grp_str
[INET_ADDRSTRLEN
];
1634 json_object
*json_iface
= NULL
;
1635 json_object
*json_row
= NULL
;
1636 json_object
*json_grp
= NULL
;
1637 struct in_addr ifaddr
;
1642 ifaddr
= pim_ifp
->primary_address
;
1644 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
1645 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
1647 pim_time_uptime_begin(uptime
, sizeof(uptime
), now
, ch
->ifjoin_creation
);
1648 pim_time_timer_to_mmss(expire
, sizeof(expire
),
1649 ch
->t_ifjoin_expiry_timer
);
1650 pim_time_timer_to_mmss(prune
, sizeof(prune
),
1651 ch
->t_ifjoin_prune_pending_timer
);
1654 json_object_object_get_ex(json
, ch
->interface
->name
,
1658 json_iface
= json_object_new_object();
1659 json_object_pim_ifp_add(json_iface
, ch
->interface
);
1660 json_object_object_add(json
, ch
->interface
->name
,
1664 json_row
= json_object_new_object();
1665 json_object_string_add(json_row
, "source", ch_src_str
);
1666 json_object_string_add(json_row
, "group", ch_grp_str
);
1667 json_object_string_add(json_row
, "upTime", uptime
);
1668 json_object_string_add(json_row
, "expire", expire
);
1669 json_object_string_add(json_row
, "prune", prune
);
1670 json_object_string_add(
1671 json_row
, "channelJoinName",
1672 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
, ch
->flags
));
1673 if (PIM_IF_FLAG_TEST_S_G_RPT(ch
->flags
))
1674 json_object_int_add(json_row
, "SGRpt", 1);
1676 json_object_object_get_ex(json_iface
, ch_grp_str
, &json_grp
);
1678 json_grp
= json_object_new_object();
1679 json_object_object_add(json_grp
, ch_src_str
, json_row
);
1680 json_object_object_add(json_iface
, ch_grp_str
,
1683 json_object_object_add(json_grp
, ch_src_str
, json_row
);
1685 vty_out(vty
, "%-9s %-15s %-15s %-15s %-10s %8s %-6s %5s\n",
1686 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
,
1688 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
, ch
->flags
),
1689 uptime
, expire
, prune
);
1693 static void pim_show_join(struct pim_instance
*pim
, struct vty
*vty
, uint8_t uj
)
1695 struct pim_interface
*pim_ifp
;
1696 struct pim_ifchannel
*ch
;
1697 struct interface
*ifp
;
1699 json_object
*json
= NULL
;
1701 now
= pim_time_monotonic_sec();
1704 json
= json_object_new_object();
1707 "Interface Address Source Group State Uptime Expire Prune\n");
1709 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1710 pim_ifp
= ifp
->info
;
1714 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
1715 pim_show_join_helper(vty
, pim_ifp
, ch
, json
, now
, uj
);
1716 } /* scan interface channels */
1720 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1721 json
, JSON_C_TO_STRING_PRETTY
));
1722 json_object_free(json
);
1726 static void pim_show_neighbors_single(struct pim_instance
*pim
, struct vty
*vty
,
1727 const char *neighbor
, uint8_t uj
)
1729 struct listnode
*neighnode
;
1730 struct interface
*ifp
;
1731 struct pim_interface
*pim_ifp
;
1732 struct pim_neighbor
*neigh
;
1734 int found_neighbor
= 0;
1735 int option_address_list
;
1736 int option_dr_priority
;
1737 int option_generation_id
;
1738 int option_holdtime
;
1739 int option_lan_prune_delay
;
1743 char neigh_src_str
[INET_ADDRSTRLEN
];
1745 json_object
*json
= NULL
;
1746 json_object
*json_ifp
= NULL
;
1747 json_object
*json_row
= NULL
;
1749 now
= pim_time_monotonic_sec();
1752 json
= json_object_new_object();
1754 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1755 pim_ifp
= ifp
->info
;
1760 if (pim_ifp
->pim_sock_fd
< 0)
1763 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
1765 pim_inet4_dump("<src?>", neigh
->source_addr
,
1766 neigh_src_str
, sizeof(neigh_src_str
));
1769 * The user can specify either the interface name or the
1771 * If this pim_ifp matches neither then skip.
1773 if (strcmp(neighbor
, "detail")
1774 && strcmp(neighbor
, ifp
->name
)
1775 && strcmp(neighbor
, neigh_src_str
))
1779 pim_time_uptime(uptime
, sizeof(uptime
),
1780 now
- neigh
->creation
);
1781 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
1782 neigh
->t_expire_timer
);
1784 option_address_list
= 0;
1785 option_dr_priority
= 0;
1786 option_generation_id
= 0;
1787 option_holdtime
= 0;
1788 option_lan_prune_delay
= 0;
1791 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1792 PIM_OPTION_MASK_ADDRESS_LIST
))
1793 option_address_list
= 1;
1795 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1796 PIM_OPTION_MASK_DR_PRIORITY
))
1797 option_dr_priority
= 1;
1799 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1800 PIM_OPTION_MASK_GENERATION_ID
))
1801 option_generation_id
= 1;
1803 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1804 PIM_OPTION_MASK_HOLDTIME
))
1805 option_holdtime
= 1;
1807 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1808 PIM_OPTION_MASK_LAN_PRUNE_DELAY
))
1809 option_lan_prune_delay
= 1;
1811 if (PIM_OPTION_IS_SET(
1812 neigh
->hello_options
,
1813 PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION
))
1818 /* Does this ifp live in json? If not create
1820 json_object_object_get_ex(json
, ifp
->name
,
1824 json_ifp
= json_object_new_object();
1825 json_object_pim_ifp_add(json_ifp
, ifp
);
1826 json_object_object_add(json
, ifp
->name
,
1830 json_row
= json_object_new_object();
1831 json_object_string_add(json_row
, "interface",
1833 json_object_string_add(json_row
, "address",
1835 json_object_string_add(json_row
, "upTime",
1837 json_object_string_add(json_row
, "holdtime",
1839 json_object_int_add(json_row
, "drPriority",
1840 neigh
->dr_priority
);
1841 json_object_int_add(json_row
, "generationId",
1842 neigh
->generation_id
);
1844 if (option_address_list
)
1845 json_object_boolean_true_add(
1847 "helloOptionAddressList");
1849 if (option_dr_priority
)
1850 json_object_boolean_true_add(
1852 "helloOptionDrPriority");
1854 if (option_generation_id
)
1855 json_object_boolean_true_add(
1857 "helloOptionGenerationId");
1859 if (option_holdtime
)
1860 json_object_boolean_true_add(
1862 "helloOptionHoldtime");
1864 if (option_lan_prune_delay
)
1865 json_object_boolean_true_add(
1867 "helloOptionLanPruneDelay");
1870 json_object_boolean_true_add(
1871 json_row
, "helloOptionTBit");
1873 json_object_object_add(json_ifp
, neigh_src_str
,
1877 vty_out(vty
, "Interface : %s\n", ifp
->name
);
1878 vty_out(vty
, "Neighbor : %s\n", neigh_src_str
);
1886 " DR Priority : %d\n",
1887 neigh
->dr_priority
);
1889 " Generation ID : %08x\n",
1890 neigh
->generation_id
);
1892 " Override Interval (msec) : %d\n",
1893 neigh
->override_interval_msec
);
1895 " Propagation Delay (msec) : %d\n",
1896 neigh
->propagation_delay_msec
);
1898 " Hello Option - Address List : %s\n",
1899 option_address_list
? "yes" : "no");
1901 " Hello Option - DR Priority : %s\n",
1902 option_dr_priority
? "yes" : "no");
1904 " Hello Option - Generation ID : %s\n",
1905 option_generation_id
? "yes" : "no");
1907 " Hello Option - Holdtime : %s\n",
1908 option_holdtime
? "yes" : "no");
1910 " Hello Option - LAN Prune Delay : %s\n",
1911 option_lan_prune_delay
? "yes" : "no");
1913 " Hello Option - T-bit : %s\n",
1914 option_t_bit
? "yes" : "no");
1915 pim_bfd_show_info(vty
, neigh
->bfd_info
,
1923 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1924 json
, JSON_C_TO_STRING_PRETTY
));
1925 json_object_free(json
);
1928 if (!found_neighbor
)
1930 "%% No such interface or neighbor\n");
1935 static void pim_show_state(struct pim_instance
*pim
, struct vty
*vty
,
1936 const char *src_or_group
, const char *group
,
1939 struct channel_oil
*c_oil
;
1940 struct listnode
*node
;
1941 json_object
*json
= NULL
;
1942 json_object
*json_group
= NULL
;
1943 json_object
*json_ifp_in
= NULL
;
1944 json_object
*json_ifp_out
= NULL
;
1945 json_object
*json_source
= NULL
;
1948 now
= pim_time_monotonic_sec();
1951 json
= json_object_new_object();
1954 "Codes: J -> Pim Join, I -> IGMP Report, S -> Source, * -> Inherited from (*,G)");
1956 "\nInstalled Source Group IIF OIL\n");
1959 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
1960 char grp_str
[INET_ADDRSTRLEN
];
1961 char src_str
[INET_ADDRSTRLEN
];
1962 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
1963 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
1965 struct interface
*ifp_in
;
1968 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
1970 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
1972 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
1975 strcpy(in_ifname
, ifp_in
->name
);
1977 strcpy(in_ifname
, "<iif?>");
1980 if (strcmp(src_or_group
, src_str
)
1981 && strcmp(src_or_group
, grp_str
))
1984 if (group
&& strcmp(group
, grp_str
))
1990 /* Find the group, create it if it doesn't exist */
1991 json_object_object_get_ex(json
, grp_str
, &json_group
);
1994 json_group
= json_object_new_object();
1995 json_object_object_add(json
, grp_str
,
1999 /* Find the source nested under the group, create it if
2000 * it doesn't exist */
2001 json_object_object_get_ex(json_group
, src_str
,
2005 json_source
= json_object_new_object();
2006 json_object_object_add(json_group
, src_str
,
2010 /* Find the inbound interface nested under the source,
2011 * create it if it doesn't exist */
2012 json_object_object_get_ex(json_source
, in_ifname
,
2016 json_ifp_in
= json_object_new_object();
2017 json_object_object_add(json_source
, in_ifname
,
2019 json_object_int_add(json_source
, "Installed",
2021 json_object_int_add(json_source
, "RefCount",
2022 c_oil
->oil_ref_count
);
2023 json_object_int_add(json_source
, "OilListSize",
2025 json_object_int_add(
2026 json_source
, "OilRescan",
2027 c_oil
->oil_inherited_rescan
);
2028 json_object_int_add(json_source
, "LastUsed",
2029 c_oil
->cc
.lastused
);
2030 json_object_int_add(json_source
, "PacketCount",
2032 json_object_int_add(json_source
, "ByteCount",
2034 json_object_int_add(json_source
,
2036 c_oil
->cc
.wrong_if
);
2039 vty_out(vty
, "%-9d %-15s %-15s %-7s ",
2040 c_oil
->installed
, src_str
, grp_str
,
2044 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
2046 struct interface
*ifp_out
;
2047 char oif_uptime
[10];
2050 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
2054 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
2056 oif_uptime
, sizeof(oif_uptime
),
2057 now
- c_oil
->oif_creation
[oif_vif_index
]);
2060 strcpy(out_ifname
, ifp_out
->name
);
2062 strcpy(out_ifname
, "<oif?>");
2065 json_ifp_out
= json_object_new_object();
2066 json_object_string_add(json_ifp_out
, "source",
2068 json_object_string_add(json_ifp_out
, "group",
2070 json_object_string_add(json_ifp_out
,
2073 json_object_string_add(json_ifp_out
,
2074 "outboundInterface",
2076 json_object_int_add(json_ifp_out
, "installed",
2079 json_object_object_add(json_ifp_in
, out_ifname
,
2084 vty_out(vty
, "%s(%c%c%c%c)", out_ifname
,
2085 (c_oil
->oif_flags
[oif_vif_index
]
2086 & PIM_OIF_FLAG_PROTO_IGMP
)
2089 (c_oil
->oif_flags
[oif_vif_index
]
2090 & PIM_OIF_FLAG_PROTO_PIM
)
2093 (c_oil
->oif_flags
[oif_vif_index
]
2094 & PIM_OIF_FLAG_PROTO_SOURCE
)
2097 (c_oil
->oif_flags
[oif_vif_index
]
2098 & PIM_OIF_FLAG_PROTO_STAR
)
2102 vty_out(vty
, ", %s(%c%c%c%c)",
2104 (c_oil
->oif_flags
[oif_vif_index
]
2105 & PIM_OIF_FLAG_PROTO_IGMP
)
2108 (c_oil
->oif_flags
[oif_vif_index
]
2109 & PIM_OIF_FLAG_PROTO_PIM
)
2112 (c_oil
->oif_flags
[oif_vif_index
]
2113 & PIM_OIF_FLAG_PROTO_SOURCE
)
2116 (c_oil
->oif_flags
[oif_vif_index
]
2117 & PIM_OIF_FLAG_PROTO_STAR
)
2129 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2130 json
, JSON_C_TO_STRING_PRETTY
));
2131 json_object_free(json
);
2137 static void pim_show_neighbors(struct pim_instance
*pim
, struct vty
*vty
,
2140 struct listnode
*neighnode
;
2141 struct interface
*ifp
;
2142 struct pim_interface
*pim_ifp
;
2143 struct pim_neighbor
*neigh
;
2147 char neigh_src_str
[INET_ADDRSTRLEN
];
2148 json_object
*json
= NULL
;
2149 json_object
*json_ifp_rows
= NULL
;
2150 json_object
*json_row
= NULL
;
2152 now
= pim_time_monotonic_sec();
2155 json
= json_object_new_object();
2158 "Interface Neighbor Uptime Holdtime DR Pri\n");
2161 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2162 pim_ifp
= ifp
->info
;
2167 if (pim_ifp
->pim_sock_fd
< 0)
2171 json_ifp_rows
= json_object_new_object();
2173 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
2175 pim_inet4_dump("<src?>", neigh
->source_addr
,
2176 neigh_src_str
, sizeof(neigh_src_str
));
2177 pim_time_uptime(uptime
, sizeof(uptime
),
2178 now
- neigh
->creation
);
2179 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
2180 neigh
->t_expire_timer
);
2183 json_row
= json_object_new_object();
2184 json_object_string_add(json_row
, "interface",
2186 json_object_string_add(json_row
, "neighbor",
2188 json_object_string_add(json_row
, "upTime",
2190 json_object_string_add(json_row
, "holdTime",
2192 json_object_int_add(json_row
, "holdTimeMax",
2194 json_object_int_add(json_row
, "drPriority",
2195 neigh
->dr_priority
);
2196 json_object_object_add(json_ifp_rows
,
2197 neigh_src_str
, json_row
);
2200 vty_out(vty
, "%-9s %15s %8s %8s %6d\n",
2201 ifp
->name
, neigh_src_str
, uptime
,
2202 expire
, neigh
->dr_priority
);
2207 json_object_object_add(json
, ifp
->name
, json_ifp_rows
);
2208 json_ifp_rows
= NULL
;
2213 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2214 json
, JSON_C_TO_STRING_PRETTY
));
2215 json_object_free(json
);
2219 static void pim_show_neighbors_secondary(struct pim_instance
*pim
,
2222 struct interface
*ifp
;
2225 "Interface Address Neighbor Secondary \n");
2227 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2228 struct pim_interface
*pim_ifp
;
2229 struct in_addr ifaddr
;
2230 struct listnode
*neighnode
;
2231 struct pim_neighbor
*neigh
;
2233 pim_ifp
= ifp
->info
;
2238 if (pim_ifp
->pim_sock_fd
< 0)
2241 ifaddr
= pim_ifp
->primary_address
;
2243 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
2245 char neigh_src_str
[INET_ADDRSTRLEN
];
2246 struct listnode
*prefix_node
;
2249 if (!neigh
->prefix_list
)
2252 pim_inet4_dump("<src?>", neigh
->source_addr
,
2253 neigh_src_str
, sizeof(neigh_src_str
));
2255 for (ALL_LIST_ELEMENTS_RO(neigh
->prefix_list
,
2257 char neigh_sec_str
[PREFIX2STR_BUFFER
];
2259 prefix2str(p
, neigh_sec_str
,
2260 sizeof(neigh_sec_str
));
2262 vty_out(vty
, "%-9s %-15s %-15s %-15s\n",
2263 ifp
->name
, inet_ntoa(ifaddr
),
2264 neigh_src_str
, neigh_sec_str
);
2270 static void json_object_pim_upstream_add(json_object
*json
,
2271 struct pim_upstream
*up
)
2273 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED
)
2274 json_object_boolean_true_add(json
, "drJoinDesired");
2276 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED
)
2277 json_object_boolean_true_add(json
, "drJoinDesiredUpdated");
2279 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
2280 json_object_boolean_true_add(json
, "firstHopRouter");
2282 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_IGMP
)
2283 json_object_boolean_true_add(json
, "sourceIgmp");
2285 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_PIM
)
2286 json_object_boolean_true_add(json
, "sourcePim");
2288 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_STREAM
)
2289 json_object_boolean_true_add(json
, "sourceStream");
2291 /* XXX: need to print ths flag in the plain text display as well */
2292 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_MSDP
)
2293 json_object_boolean_true_add(json
, "sourceMsdp");
2297 pim_upstream_state2brief_str(enum pim_upstream_state join_state
,
2300 switch (join_state
) {
2301 case PIM_UPSTREAM_NOTJOINED
:
2302 strcpy(state_str
, "NotJ");
2304 case PIM_UPSTREAM_JOINED
:
2305 strcpy(state_str
, "J");
2308 strcpy(state_str
, "Unk");
2313 static const char *pim_reg_state2brief_str(enum pim_reg_state reg_state
,
2316 switch (reg_state
) {
2317 case PIM_REG_NOINFO
:
2318 strcpy(state_str
, "RegNI");
2321 strcpy(state_str
, "RegJ");
2323 case PIM_REG_JOIN_PENDING
:
2325 strcpy(state_str
, "RegP");
2328 strcpy(state_str
, "Unk");
2333 static void pim_show_upstream(struct pim_instance
*pim
, struct vty
*vty
,
2336 struct listnode
*upnode
;
2337 struct pim_upstream
*up
;
2339 json_object
*json
= NULL
;
2340 json_object
*json_group
= NULL
;
2341 json_object
*json_row
= NULL
;
2343 now
= pim_time_monotonic_sec();
2346 json
= json_object_new_object();
2349 "Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt\n");
2351 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
, up
)) {
2352 char src_str
[INET_ADDRSTRLEN
];
2353 char grp_str
[INET_ADDRSTRLEN
];
2355 char join_timer
[10];
2358 char msdp_reg_timer
[10];
2359 char state_str
[PIM_REG_STATE_STR_LEN
];
2361 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2362 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2363 pim_time_uptime(uptime
, sizeof(uptime
),
2364 now
- up
->state_transition
);
2365 pim_time_timer_to_hhmmss(join_timer
, sizeof(join_timer
),
2369 * If we have a J/P timer for the neighbor display that
2371 if (!up
->t_join_timer
) {
2372 struct pim_neighbor
*nbr
;
2374 nbr
= pim_neighbor_find(
2375 up
->rpf
.source_nexthop
.interface
,
2376 up
->rpf
.rpf_addr
.u
.prefix4
);
2378 pim_time_timer_to_hhmmss(join_timer
,
2383 pim_time_timer_to_hhmmss(rs_timer
, sizeof(rs_timer
),
2385 pim_time_timer_to_hhmmss(ka_timer
, sizeof(ka_timer
),
2387 pim_time_timer_to_hhmmss(msdp_reg_timer
, sizeof(msdp_reg_timer
),
2388 up
->t_msdp_reg_timer
);
2390 pim_upstream_state2brief_str(up
->join_state
, state_str
);
2391 if (up
->reg_state
!= PIM_REG_NOINFO
) {
2392 char tmp_str
[PIM_REG_STATE_STR_LEN
];
2394 sprintf(state_str
+ strlen(state_str
), ",%s",
2395 pim_reg_state2brief_str(up
->reg_state
,
2400 json_object_object_get_ex(json
, grp_str
, &json_group
);
2403 json_group
= json_object_new_object();
2404 json_object_object_add(json
, grp_str
,
2408 json_row
= json_object_new_object();
2409 json_object_pim_upstream_add(json_row
, up
);
2410 json_object_string_add(
2411 json_row
, "inboundInterface",
2412 up
->rpf
.source_nexthop
.interface
->name
);
2415 * The RPF address we use is slightly different
2416 * based upon what we are looking up.
2417 * If we have a S, list that unless
2418 * we are the FHR, else we just put
2419 * the RP as the rpfAddress
2421 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
2422 || up
->sg
.src
.s_addr
== INADDR_ANY
) {
2423 char rpf
[PREFIX_STRLEN
];
2424 struct pim_rpf
*rpg
;
2426 rpg
= RP(pim
, up
->sg
.grp
);
2427 pim_inet4_dump("<rpf?>",
2428 rpg
->rpf_addr
.u
.prefix4
, rpf
,
2430 json_object_string_add(json_row
, "rpfAddress",
2433 json_object_string_add(json_row
, "rpfAddress",
2437 json_object_string_add(json_row
, "source", src_str
);
2438 json_object_string_add(json_row
, "group", grp_str
);
2439 json_object_string_add(json_row
, "state", state_str
);
2440 json_object_string_add(
2441 json_row
, "joinState",
2442 pim_upstream_state2str(up
->join_state
));
2443 json_object_string_add(
2444 json_row
, "regState",
2445 pim_reg_state2str(up
->reg_state
, state_str
));
2446 json_object_string_add(json_row
, "upTime", uptime
);
2447 json_object_string_add(json_row
, "joinTimer",
2449 json_object_string_add(json_row
, "resetTimer",
2451 json_object_string_add(json_row
, "keepaliveTimer",
2453 json_object_string_add(json_row
, "msdpRegTimer",
2455 json_object_int_add(json_row
, "refCount",
2457 json_object_int_add(json_row
, "sptBit", up
->sptbit
);
2458 json_object_object_add(json_group
, src_str
, json_row
);
2461 "%-10s%-15s %-15s %-11s %-8s %-9s %-9s %-9s %6d\n",
2462 up
->rpf
.source_nexthop
.interface
->name
, src_str
,
2463 grp_str
, state_str
, uptime
, join_timer
,
2464 rs_timer
, ka_timer
, up
->ref_count
);
2469 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2470 json
, JSON_C_TO_STRING_PRETTY
));
2471 json_object_free(json
);
2475 static void pim_show_join_desired_helper(struct pim_instance
*pim
,
2477 struct pim_interface
*pim_ifp
,
2478 struct pim_ifchannel
*ch
,
2479 json_object
*json
, uint8_t uj
)
2481 struct pim_upstream
*up
= ch
->upstream
;
2482 json_object
*json_group
= NULL
;
2483 char src_str
[INET_ADDRSTRLEN
];
2484 char grp_str
[INET_ADDRSTRLEN
];
2485 json_object
*json_row
= NULL
;
2487 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2488 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2491 json_object_object_get_ex(json
, grp_str
, &json_group
);
2494 json_group
= json_object_new_object();
2495 json_object_object_add(json
, grp_str
, json_group
);
2498 json_row
= json_object_new_object();
2499 json_object_pim_upstream_add(json_row
, up
);
2500 json_object_string_add(json_row
, "interface",
2501 ch
->interface
->name
);
2502 json_object_string_add(json_row
, "source", src_str
);
2503 json_object_string_add(json_row
, "group", grp_str
);
2505 if (pim_macro_ch_lost_assert(ch
))
2506 json_object_boolean_true_add(json_row
, "lostAssert");
2508 if (pim_macro_chisin_joins(ch
))
2509 json_object_boolean_true_add(json_row
, "joins");
2511 if (pim_macro_chisin_pim_include(ch
))
2512 json_object_boolean_true_add(json_row
, "pimInclude");
2514 if (pim_upstream_evaluate_join_desired(pim
, up
))
2515 json_object_boolean_true_add(json_row
,
2516 "evaluateJoinDesired");
2518 json_object_object_add(json_group
, src_str
, json_row
);
2521 vty_out(vty
, "%-9s %-15s %-15s %-10s %-5s %-10s %-11s %-6s\n",
2522 ch
->interface
->name
, src_str
, grp_str
,
2523 pim_macro_ch_lost_assert(ch
) ? "yes" : "no",
2524 pim_macro_chisin_joins(ch
) ? "yes" : "no",
2525 pim_macro_chisin_pim_include(ch
) ? "yes" : "no",
2526 PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(up
->flags
)
2529 pim_upstream_evaluate_join_desired(pim
, up
) ? "yes"
2534 static void pim_show_join_desired(struct pim_instance
*pim
, struct vty
*vty
,
2537 struct pim_interface
*pim_ifp
;
2538 struct pim_ifchannel
*ch
;
2539 struct interface
*ifp
;
2541 json_object
*json
= NULL
;
2544 json
= json_object_new_object();
2547 "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD\n");
2549 /* scan per-interface (S,G) state */
2550 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2551 pim_ifp
= ifp
->info
;
2556 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
2557 /* scan all interfaces */
2558 pim_show_join_desired_helper(pim
, vty
, pim_ifp
, ch
,
2564 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2565 json
, JSON_C_TO_STRING_PRETTY
));
2566 json_object_free(json
);
2570 static void pim_show_upstream_rpf(struct pim_instance
*pim
, struct vty
*vty
,
2573 struct listnode
*upnode
;
2574 struct pim_upstream
*up
;
2575 json_object
*json
= NULL
;
2576 json_object
*json_group
= NULL
;
2577 json_object
*json_row
= NULL
;
2580 json
= json_object_new_object();
2583 "Source Group RpfIface RibNextHop RpfAddress \n");
2585 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
, up
)) {
2586 char src_str
[INET_ADDRSTRLEN
];
2587 char grp_str
[INET_ADDRSTRLEN
];
2588 char rpf_nexthop_str
[PREFIX_STRLEN
];
2589 char rpf_addr_str
[PREFIX_STRLEN
];
2590 struct pim_rpf
*rpf
;
2591 const char *rpf_ifname
;
2595 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2596 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2597 pim_addr_dump("<nexthop?>",
2598 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2599 rpf_nexthop_str
, sizeof(rpf_nexthop_str
));
2600 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2601 sizeof(rpf_addr_str
));
2603 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2606 json_object_object_get_ex(json
, grp_str
, &json_group
);
2609 json_group
= json_object_new_object();
2610 json_object_object_add(json
, grp_str
,
2614 json_row
= json_object_new_object();
2615 json_object_pim_upstream_add(json_row
, up
);
2616 json_object_string_add(json_row
, "source", src_str
);
2617 json_object_string_add(json_row
, "group", grp_str
);
2618 json_object_string_add(json_row
, "rpfInterface",
2620 json_object_string_add(json_row
, "ribNexthop",
2622 json_object_string_add(json_row
, "rpfAddress",
2624 json_object_object_add(json_group
, src_str
, json_row
);
2626 vty_out(vty
, "%-15s %-15s %-8s %-15s %-15s\n", src_str
,
2627 grp_str
, rpf_ifname
, rpf_nexthop_str
,
2633 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2634 json
, JSON_C_TO_STRING_PRETTY
));
2635 json_object_free(json
);
2639 static void show_rpf_refresh_stats(struct vty
*vty
, struct pim_instance
*pim
,
2640 time_t now
, json_object
*json
)
2642 char refresh_uptime
[10];
2644 pim_time_uptime_begin(refresh_uptime
, sizeof(refresh_uptime
), now
,
2645 pim
->rpf_cache_refresh_last
);
2648 json_object_int_add(json
, "rpfCacheRefreshDelayMsecs",
2649 qpim_rpf_cache_refresh_delay_msec
);
2650 json_object_int_add(
2651 json
, "rpfCacheRefreshTimer",
2652 pim_time_timer_remain_msec(pim
->rpf_cache_refresher
));
2653 json_object_int_add(json
, "rpfCacheRefreshRequests",
2654 pim
->rpf_cache_refresh_requests
);
2655 json_object_int_add(json
, "rpfCacheRefreshEvents",
2656 pim
->rpf_cache_refresh_events
);
2657 json_object_string_add(json
, "rpfCacheRefreshLast",
2659 json_object_int_add(json
, "nexthopLookups",
2660 pim
->nexthop_lookups
);
2661 json_object_int_add(json
, "nexthopLookupsAvoided",
2662 pim
->nexthop_lookups_avoided
);
2665 "RPF Cache Refresh Delay: %ld msecs\n"
2666 "RPF Cache Refresh Timer: %ld msecs\n"
2667 "RPF Cache Refresh Requests: %lld\n"
2668 "RPF Cache Refresh Events: %lld\n"
2669 "RPF Cache Refresh Last: %s\n"
2670 "Nexthop Lookups: %lld\n"
2671 "Nexthop Lookups Avoided: %lld\n",
2672 qpim_rpf_cache_refresh_delay_msec
,
2673 pim_time_timer_remain_msec(pim
->rpf_cache_refresher
),
2674 (long long)pim
->rpf_cache_refresh_requests
,
2675 (long long)pim
->rpf_cache_refresh_events
,
2676 refresh_uptime
, (long long)pim
->nexthop_lookups
,
2677 (long long)pim
->nexthop_lookups_avoided
);
2681 static void show_scan_oil_stats(struct pim_instance
*pim
, struct vty
*vty
,
2684 char uptime_scan_oil
[10];
2685 char uptime_mroute_add
[10];
2686 char uptime_mroute_del
[10];
2688 pim_time_uptime_begin(uptime_scan_oil
, sizeof(uptime_scan_oil
), now
,
2689 pim
->scan_oil_last
);
2690 pim_time_uptime_begin(uptime_mroute_add
, sizeof(uptime_mroute_add
), now
,
2691 pim
->mroute_add_last
);
2692 pim_time_uptime_begin(uptime_mroute_del
, sizeof(uptime_mroute_del
), now
,
2693 pim
->mroute_del_last
);
2696 "Scan OIL - Last: %s Events: %lld\n"
2697 "MFC Add - Last: %s Events: %lld\n"
2698 "MFC Del - Last: %s Events: %lld\n",
2699 uptime_scan_oil
, (long long)pim
->scan_oil_events
,
2700 uptime_mroute_add
, (long long)pim
->mroute_add_events
,
2701 uptime_mroute_del
, (long long)pim
->mroute_del_events
);
2704 static void pim_show_rpf(struct pim_instance
*pim
, struct vty
*vty
, uint8_t uj
)
2706 struct listnode
*up_node
;
2707 struct pim_upstream
*up
;
2708 time_t now
= pim_time_monotonic_sec();
2709 json_object
*json
= NULL
;
2710 json_object
*json_group
= NULL
;
2711 json_object
*json_row
= NULL
;
2714 json
= json_object_new_object();
2715 show_rpf_refresh_stats(vty
, pim
, now
, json
);
2717 show_rpf_refresh_stats(vty
, pim
, now
, json
);
2720 "Source Group RpfIface RpfAddress RibNextHop Metric Pref\n");
2723 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, up_node
, up
)) {
2724 char src_str
[INET_ADDRSTRLEN
];
2725 char grp_str
[INET_ADDRSTRLEN
];
2726 char rpf_addr_str
[PREFIX_STRLEN
];
2727 char rib_nexthop_str
[PREFIX_STRLEN
];
2728 const char *rpf_ifname
;
2729 struct pim_rpf
*rpf
= &up
->rpf
;
2731 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2732 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2733 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2734 sizeof(rpf_addr_str
));
2735 pim_addr_dump("<nexthop?>",
2736 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2737 rib_nexthop_str
, sizeof(rib_nexthop_str
));
2739 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2742 json_object_object_get_ex(json
, grp_str
, &json_group
);
2745 json_group
= json_object_new_object();
2746 json_object_object_add(json
, grp_str
,
2750 json_row
= json_object_new_object();
2751 json_object_string_add(json_row
, "source", src_str
);
2752 json_object_string_add(json_row
, "group", grp_str
);
2753 json_object_string_add(json_row
, "rpfInterface",
2755 json_object_string_add(json_row
, "rpfAddress",
2757 json_object_string_add(json_row
, "ribNexthop",
2759 json_object_int_add(
2760 json_row
, "routeMetric",
2761 rpf
->source_nexthop
.mrib_route_metric
);
2762 json_object_int_add(
2763 json_row
, "routePreference",
2764 rpf
->source_nexthop
.mrib_metric_preference
);
2765 json_object_object_add(json_group
, src_str
, json_row
);
2768 vty_out(vty
, "%-15s %-15s %-8s %-15s %-15s %6d %4d\n",
2769 src_str
, grp_str
, rpf_ifname
, rpf_addr_str
,
2771 rpf
->source_nexthop
.mrib_route_metric
,
2772 rpf
->source_nexthop
.mrib_metric_preference
);
2777 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2778 json
, JSON_C_TO_STRING_PRETTY
));
2779 json_object_free(json
);
2783 struct pnc_cache_walk_data
{
2785 struct pim_instance
*pim
;
2788 static int pim_print_pnc_cache_walkcb(struct hash_backet
*backet
, void *arg
)
2790 struct pim_nexthop_cache
*pnc
= backet
->data
;
2791 struct pnc_cache_walk_data
*cwd
= arg
;
2792 struct vty
*vty
= cwd
->vty
;
2793 struct pim_instance
*pim
= cwd
->pim
;
2794 struct nexthop
*nh_node
= NULL
;
2795 ifindex_t first_ifindex
;
2796 struct interface
*ifp
= NULL
;
2801 for (nh_node
= pnc
->nexthop
; nh_node
; nh_node
= nh_node
->next
) {
2802 first_ifindex
= nh_node
->ifindex
;
2803 ifp
= if_lookup_by_index(first_ifindex
, pim
->vrf_id
);
2805 vty_out(vty
, "%-15s ", inet_ntoa(pnc
->rpf
.rpf_addr
.u
.prefix4
));
2806 vty_out(vty
, "%-14s ", ifp
? ifp
->name
: "NULL");
2807 vty_out(vty
, "%s ", inet_ntoa(nh_node
->gate
.ipv4
));
2813 static void pim_show_nexthop(struct pim_instance
*pim
, struct vty
*vty
)
2815 struct pnc_cache_walk_data cwd
;
2819 vty_out(vty
, "Number of registered addresses: %lu\n",
2820 pim
->rpf_hash
->count
);
2821 vty_out(vty
, "Address Interface Nexthop\n");
2822 vty_out(vty
, "-------------------------------------------\n");
2824 hash_walk(pim
->rpf_hash
, pim_print_pnc_cache_walkcb
, &cwd
);
2827 static void igmp_show_groups(struct pim_instance
*pim
, struct vty
*vty
,
2830 struct interface
*ifp
;
2832 json_object
*json
= NULL
;
2833 json_object
*json_iface
= NULL
;
2834 json_object
*json_row
= NULL
;
2836 now
= pim_time_monotonic_sec();
2839 json
= json_object_new_object();
2842 "Interface Address Group Mode Timer Srcs V Uptime \n");
2844 /* scan interfaces */
2845 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2846 struct pim_interface
*pim_ifp
= ifp
->info
;
2847 struct listnode
*sock_node
;
2848 struct igmp_sock
*igmp
;
2853 /* scan igmp sockets */
2854 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
2856 char ifaddr_str
[INET_ADDRSTRLEN
];
2857 struct listnode
*grpnode
;
2858 struct igmp_group
*grp
;
2860 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
2861 sizeof(ifaddr_str
));
2863 /* scan igmp groups */
2864 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
2866 char group_str
[INET_ADDRSTRLEN
];
2870 pim_inet4_dump("<group?>", grp
->group_addr
,
2871 group_str
, sizeof(group_str
));
2872 pim_time_timer_to_hhmmss(hhmmss
, sizeof(hhmmss
),
2873 grp
->t_group_timer
);
2874 pim_time_uptime(uptime
, sizeof(uptime
),
2875 now
- grp
->group_creation
);
2878 json_object_object_get_ex(
2879 json
, ifp
->name
, &json_iface
);
2883 json_object_new_object();
2884 json_object_pim_ifp_add(
2886 json_object_object_add(
2891 json_row
= json_object_new_object();
2892 json_object_string_add(
2893 json_row
, "source", ifaddr_str
);
2894 json_object_string_add(
2895 json_row
, "group", group_str
);
2897 if (grp
->igmp_version
== 3)
2898 json_object_string_add(
2900 grp
->group_filtermode_isexcl
2904 json_object_string_add(json_row
,
2906 json_object_int_add(
2907 json_row
, "sourcesCount",
2908 grp
->group_source_list
2910 grp
->group_source_list
)
2912 json_object_int_add(json_row
, "version",
2914 json_object_string_add(
2915 json_row
, "uptime", uptime
);
2916 json_object_object_add(json_iface
,
2922 "%-9s %-15s %-15s %4s %8s %4d %d %8s\n",
2923 ifp
->name
, ifaddr_str
,
2925 grp
->igmp_version
== 3
2926 ? (grp
->group_filtermode_isexcl
2931 grp
->group_source_list
2933 grp
->group_source_list
)
2935 grp
->igmp_version
, uptime
);
2937 } /* scan igmp groups */
2938 } /* scan igmp sockets */
2939 } /* scan interfaces */
2942 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2943 json
, JSON_C_TO_STRING_PRETTY
));
2944 json_object_free(json
);
2948 static void igmp_show_group_retransmission(struct pim_instance
*pim
,
2951 struct interface
*ifp
;
2954 "Interface Address Group RetTimer Counter RetSrcs\n");
2956 /* scan interfaces */
2957 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2958 struct pim_interface
*pim_ifp
= ifp
->info
;
2959 struct listnode
*sock_node
;
2960 struct igmp_sock
*igmp
;
2965 /* scan igmp sockets */
2966 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
2968 char ifaddr_str
[INET_ADDRSTRLEN
];
2969 struct listnode
*grpnode
;
2970 struct igmp_group
*grp
;
2972 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
2973 sizeof(ifaddr_str
));
2975 /* scan igmp groups */
2976 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
2978 char group_str
[INET_ADDRSTRLEN
];
2979 char grp_retr_mmss
[10];
2980 struct listnode
*src_node
;
2981 struct igmp_source
*src
;
2982 int grp_retr_sources
= 0;
2984 pim_inet4_dump("<group?>", grp
->group_addr
,
2985 group_str
, sizeof(group_str
));
2986 pim_time_timer_to_mmss(
2987 grp_retr_mmss
, sizeof(grp_retr_mmss
),
2988 grp
->t_group_query_retransmit_timer
);
2991 /* count group sources with retransmission state
2993 for (ALL_LIST_ELEMENTS_RO(
2994 grp
->group_source_list
, src_node
,
2996 if (src
->source_query_retransmit_count
3002 vty_out(vty
, "%-9s %-15s %-15s %-8s %7d %7d\n",
3003 ifp
->name
, ifaddr_str
, group_str
,
3005 grp
->group_specific_query_retransmit_count
,
3008 } /* scan igmp groups */
3009 } /* scan igmp sockets */
3010 } /* scan interfaces */
3013 static void igmp_show_sources(struct pim_instance
*pim
, struct vty
*vty
)
3015 struct interface
*ifp
;
3018 now
= pim_time_monotonic_sec();
3021 "Interface Address Group Source Timer Fwd Uptime \n");
3023 /* scan interfaces */
3024 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3025 struct pim_interface
*pim_ifp
= ifp
->info
;
3026 struct listnode
*sock_node
;
3027 struct igmp_sock
*igmp
;
3032 /* scan igmp sockets */
3033 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3035 char ifaddr_str
[INET_ADDRSTRLEN
];
3036 struct listnode
*grpnode
;
3037 struct igmp_group
*grp
;
3039 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3040 sizeof(ifaddr_str
));
3042 /* scan igmp groups */
3043 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3045 char group_str
[INET_ADDRSTRLEN
];
3046 struct listnode
*srcnode
;
3047 struct igmp_source
*src
;
3049 pim_inet4_dump("<group?>", grp
->group_addr
,
3050 group_str
, sizeof(group_str
));
3052 /* scan group sources */
3053 for (ALL_LIST_ELEMENTS_RO(
3054 grp
->group_source_list
, srcnode
,
3056 char source_str
[INET_ADDRSTRLEN
];
3061 "<source?>", src
->source_addr
,
3062 source_str
, sizeof(source_str
));
3064 pim_time_timer_to_mmss(
3066 src
->t_source_timer
);
3069 uptime
, sizeof(uptime
),
3070 now
- src
->source_creation
);
3073 "%-9s %-15s %-15s %-15s %5s %3s %8s\n",
3074 ifp
->name
, ifaddr_str
,
3075 group_str
, source_str
, mmss
,
3076 IGMP_SOURCE_TEST_FORWARDING(
3082 } /* scan group sources */
3083 } /* scan igmp groups */
3084 } /* scan igmp sockets */
3085 } /* scan interfaces */
3088 static void igmp_show_source_retransmission(struct pim_instance
*pim
,
3091 struct interface
*ifp
;
3094 "Interface Address Group Source Counter\n");
3096 /* scan interfaces */
3097 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3098 struct pim_interface
*pim_ifp
= ifp
->info
;
3099 struct listnode
*sock_node
;
3100 struct igmp_sock
*igmp
;
3105 /* scan igmp sockets */
3106 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3108 char ifaddr_str
[INET_ADDRSTRLEN
];
3109 struct listnode
*grpnode
;
3110 struct igmp_group
*grp
;
3112 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3113 sizeof(ifaddr_str
));
3115 /* scan igmp groups */
3116 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3118 char group_str
[INET_ADDRSTRLEN
];
3119 struct listnode
*srcnode
;
3120 struct igmp_source
*src
;
3122 pim_inet4_dump("<group?>", grp
->group_addr
,
3123 group_str
, sizeof(group_str
));
3125 /* scan group sources */
3126 for (ALL_LIST_ELEMENTS_RO(
3127 grp
->group_source_list
, srcnode
,
3129 char source_str
[INET_ADDRSTRLEN
];
3132 "<source?>", src
->source_addr
,
3133 source_str
, sizeof(source_str
));
3136 "%-9s %-15s %-15s %-15s %7d\n",
3137 ifp
->name
, ifaddr_str
,
3138 group_str
, source_str
,
3139 src
->source_query_retransmit_count
);
3141 } /* scan group sources */
3142 } /* scan igmp groups */
3143 } /* scan igmp sockets */
3144 } /* scan interfaces */
3147 static void clear_igmp_interfaces(struct pim_instance
*pim
)
3149 struct interface
*ifp
;
3151 FOR_ALL_INTERFACES (pim
->vrf
, ifp
)
3152 pim_if_addr_del_all_igmp(ifp
);
3154 FOR_ALL_INTERFACES (pim
->vrf
, ifp
)
3155 pim_if_addr_add_all(ifp
);
3158 static void clear_pim_interfaces(struct pim_instance
*pim
)
3160 struct interface
*ifp
;
3162 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3164 pim_neighbor_delete_all(ifp
, "interface cleared");
3169 static void clear_interfaces(struct pim_instance
*pim
)
3171 clear_igmp_interfaces(pim
);
3172 clear_pim_interfaces(pim
);
3175 #define PIM_GET_PIM_INTERFACE(pim_ifp, ifp) \
3176 pim_ifp = ifp->info; \
3179 "%% Enable PIM and/or IGMP on this interface first\n"); \
3180 return CMD_WARNING_CONFIG_FAILED; \
3183 DEFUN (clear_ip_interfaces
,
3184 clear_ip_interfaces_cmd
,
3185 "clear ip interfaces [vrf NAME]",
3188 "Reset interfaces\n"
3192 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3197 clear_interfaces(vrf
->info
);
3202 DEFUN (clear_ip_igmp_interfaces
,
3203 clear_ip_igmp_interfaces_cmd
,
3204 "clear ip igmp [vrf NAME] interfaces",
3209 "Reset IGMP interfaces\n")
3212 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3217 clear_igmp_interfaces(vrf
->info
);
3222 static void mroute_add_all(struct pim_instance
*pim
)
3224 struct listnode
*node
;
3225 struct channel_oil
*c_oil
;
3227 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
3228 if (pim_mroute_add(c_oil
, __PRETTY_FUNCTION__
)) {
3229 /* just log warning */
3230 char source_str
[INET_ADDRSTRLEN
];
3231 char group_str
[INET_ADDRSTRLEN
];
3232 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
,
3233 source_str
, sizeof(source_str
));
3234 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
,
3235 group_str
, sizeof(group_str
));
3236 zlog_warn("%s %s: (S,G)=(%s,%s) failure writing MFC",
3237 __FILE__
, __PRETTY_FUNCTION__
, source_str
,
3243 static void mroute_del_all(struct pim_instance
*pim
)
3245 struct listnode
*node
;
3246 struct channel_oil
*c_oil
;
3248 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
3249 if (pim_mroute_del(c_oil
, __PRETTY_FUNCTION__
)) {
3250 /* just log warning */
3251 char source_str
[INET_ADDRSTRLEN
];
3252 char group_str
[INET_ADDRSTRLEN
];
3253 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
,
3254 source_str
, sizeof(source_str
));
3255 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
,
3256 group_str
, sizeof(group_str
));
3257 zlog_warn("%s %s: (S,G)=(%s,%s) failure clearing MFC",
3258 __FILE__
, __PRETTY_FUNCTION__
, source_str
,
3264 DEFUN (clear_ip_mroute
,
3265 clear_ip_mroute_cmd
,
3266 "clear ip mroute [vrf NAME]",
3269 "Reset multicast routes\n"
3273 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3278 mroute_del_all(vrf
->info
);
3279 mroute_add_all(vrf
->info
);
3284 DEFUN (clear_ip_pim_interfaces
,
3285 clear_ip_pim_interfaces_cmd
,
3286 "clear ip pim [vrf NAME] interfaces",
3291 "Reset PIM interfaces\n")
3294 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3299 clear_pim_interfaces(vrf
->info
);
3304 DEFUN (clear_ip_pim_interface_traffic
,
3305 clear_ip_pim_interface_traffic_cmd
,
3306 "clear ip pim [vrf NAME] interface traffic",
3309 "PIM clear commands\n"
3311 "Reset PIM interfaces\n"
3312 "Reset Protocol Packet counters\n")
3315 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3316 struct interface
*ifp
= NULL
;
3317 struct pim_interface
*pim_ifp
= NULL
;
3322 FOR_ALL_INTERFACES (vrf
, ifp
) {
3323 pim_ifp
= ifp
->info
;
3328 pim_ifp
->pim_ifstat_hello_recv
= 0;
3329 pim_ifp
->pim_ifstat_hello_sent
= 0;
3330 pim_ifp
->pim_ifstat_join_recv
= 0;
3331 pim_ifp
->pim_ifstat_join_send
= 0;
3332 pim_ifp
->pim_ifstat_prune_recv
= 0;
3333 pim_ifp
->pim_ifstat_prune_send
= 0;
3334 pim_ifp
->pim_ifstat_reg_recv
= 0;
3335 pim_ifp
->pim_ifstat_reg_send
= 0;
3336 pim_ifp
->pim_ifstat_reg_stop_recv
= 0;
3337 pim_ifp
->pim_ifstat_reg_stop_send
= 0;
3338 pim_ifp
->pim_ifstat_assert_recv
= 0;
3339 pim_ifp
->pim_ifstat_assert_send
= 0;
3345 DEFUN (clear_ip_pim_oil
,
3346 clear_ip_pim_oil_cmd
,
3347 "clear ip pim [vrf NAME] oil",
3352 "Rescan PIM OIL (output interface list)\n")
3355 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3360 pim_scan_oil(vrf
->info
);
3365 DEFUN (show_ip_igmp_interface
,
3366 show_ip_igmp_interface_cmd
,
3367 "show ip igmp [vrf NAME] interface [detail|WORD] [json]",
3372 "IGMP interface information\n"
3378 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3379 uint8_t uj
= use_json(argc
, argv
);
3384 if (argv_find(argv
, argc
, "detail", &idx
)
3385 || argv_find(argv
, argc
, "WORD", &idx
))
3386 igmp_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
3388 igmp_show_interfaces(vrf
->info
, vty
, uj
);
3393 DEFUN (show_ip_igmp_interface_vrf_all
,
3394 show_ip_igmp_interface_vrf_all_cmd
,
3395 "show ip igmp vrf all interface [detail|WORD] [json]",
3400 "IGMP interface information\n"
3406 uint8_t uj
= use_json(argc
, argv
);
3412 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3416 vty_out(vty
, " \"%s\": ", vrf
->name
);
3419 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3420 if (argv_find(argv
, argc
, "detail", &idx
)
3421 || argv_find(argv
, argc
, "WORD", &idx
))
3422 igmp_show_interfaces_single(vrf
->info
, vty
,
3423 argv
[idx
]->arg
, uj
);
3425 igmp_show_interfaces(vrf
->info
, vty
, uj
);
3428 vty_out(vty
, "}\n");
3433 DEFUN (show_ip_igmp_join
,
3434 show_ip_igmp_join_cmd
,
3435 "show ip igmp [vrf NAME] join",
3440 "IGMP static join information\n")
3443 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3448 igmp_show_interface_join(vrf
->info
, vty
);
3453 DEFUN (show_ip_igmp_join_vrf_all
,
3454 show_ip_igmp_join_vrf_all_cmd
,
3455 "show ip igmp vrf all join",
3460 "IGMP static join information\n")
3462 uint8_t uj
= use_json(argc
, argv
);
3468 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3472 vty_out(vty
, " \"%s\": ", vrf
->name
);
3475 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3476 igmp_show_interface_join(vrf
->info
, vty
);
3479 vty_out(vty
, "}\n");
3484 DEFUN (show_ip_igmp_groups
,
3485 show_ip_igmp_groups_cmd
,
3486 "show ip igmp [vrf NAME] groups [json]",
3495 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3496 uint8_t uj
= use_json(argc
, argv
);
3501 igmp_show_groups(vrf
->info
, vty
, uj
);
3506 DEFUN (show_ip_igmp_groups_vrf_all
,
3507 show_ip_igmp_groups_vrf_all_cmd
,
3508 "show ip igmp vrf all groups [json]",
3516 uint8_t uj
= use_json(argc
, argv
);
3522 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3526 vty_out(vty
, " \"%s\": ", vrf
->name
);
3529 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3530 igmp_show_groups(vrf
->info
, vty
, uj
);
3533 vty_out(vty
, "}\n");
3538 DEFUN (show_ip_igmp_groups_retransmissions
,
3539 show_ip_igmp_groups_retransmissions_cmd
,
3540 "show ip igmp [vrf NAME] groups retransmissions",
3546 "IGMP group retransmissions\n")
3549 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3554 igmp_show_group_retransmission(vrf
->info
, vty
);
3559 DEFUN (show_ip_igmp_sources
,
3560 show_ip_igmp_sources_cmd
,
3561 "show ip igmp [vrf NAME] sources",
3569 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3574 igmp_show_sources(vrf
->info
, vty
);
3579 DEFUN (show_ip_igmp_sources_retransmissions
,
3580 show_ip_igmp_sources_retransmissions_cmd
,
3581 "show ip igmp [vrf NAME] sources retransmissions",
3587 "IGMP source retransmissions\n")
3590 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3595 igmp_show_source_retransmission(vrf
->info
, vty
);
3600 DEFUN (show_ip_igmp_statistics
,
3601 show_ip_igmp_statistics_cmd
,
3602 "show ip igmp [vrf NAME] statistics [interface WORD] [json]",
3613 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3614 uint8_t uj
= use_json(argc
, argv
);
3619 if (argv_find(argv
, argc
, "WORD", &idx
))
3620 igmp_show_statistics(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
3622 igmp_show_statistics(vrf
->info
, vty
, NULL
, uj
);
3627 DEFUN (show_ip_pim_assert
,
3628 show_ip_pim_assert_cmd
,
3629 "show ip pim [vrf NAME] assert",
3634 "PIM interface assert\n")
3637 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3642 pim_show_assert(vrf
->info
, vty
);
3647 DEFUN (show_ip_pim_assert_internal
,
3648 show_ip_pim_assert_internal_cmd
,
3649 "show ip pim [vrf NAME] assert-internal",
3654 "PIM interface internal assert state\n")
3657 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3662 pim_show_assert_internal(vrf
->info
, vty
);
3667 DEFUN (show_ip_pim_assert_metric
,
3668 show_ip_pim_assert_metric_cmd
,
3669 "show ip pim [vrf NAME] assert-metric",
3674 "PIM interface assert metric\n")
3677 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3682 pim_show_assert_metric(vrf
->info
, vty
);
3687 DEFUN (show_ip_pim_assert_winner_metric
,
3688 show_ip_pim_assert_winner_metric_cmd
,
3689 "show ip pim [vrf NAME] assert-winner-metric",
3694 "PIM interface assert winner metric\n")
3697 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3702 pim_show_assert_winner_metric(vrf
->info
, vty
);
3707 DEFUN (show_ip_pim_interface
,
3708 show_ip_pim_interface_cmd
,
3709 "show ip pim [vrf NAME] interface [detail|WORD] [json]",
3714 "PIM interface information\n"
3720 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3721 uint8_t uj
= use_json(argc
, argv
);
3726 if (argv_find(argv
, argc
, "WORD", &idx
)
3727 || argv_find(argv
, argc
, "detail", &idx
))
3728 pim_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
3730 pim_show_interfaces(vrf
->info
, vty
, uj
);
3735 DEFUN (show_ip_pim_interface_vrf_all
,
3736 show_ip_pim_interface_vrf_all_cmd
,
3737 "show ip pim vrf all interface [detail|WORD] [json]",
3742 "PIM interface information\n"
3748 uint8_t uj
= use_json(argc
, argv
);
3754 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3758 vty_out(vty
, " \"%s\": ", vrf
->name
);
3761 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3762 if (argv_find(argv
, argc
, "WORD", &idx
)
3763 || argv_find(argv
, argc
, "detail", &idx
))
3764 pim_show_interfaces_single(vrf
->info
, vty
,
3765 argv
[idx
]->arg
, uj
);
3767 pim_show_interfaces(vrf
->info
, vty
, uj
);
3770 vty_out(vty
, "}\n");
3775 DEFUN (show_ip_pim_join
,
3776 show_ip_pim_join_cmd
,
3777 "show ip pim [vrf NAME] join [json]",
3782 "PIM interface join information\n"
3786 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3787 uint8_t uj
= use_json(argc
, argv
);
3792 pim_show_join(vrf
->info
, vty
, uj
);
3797 DEFUN (show_ip_pim_join_vrf_all
,
3798 show_ip_pim_join_vrf_all_cmd
,
3799 "show ip pim vrf all join [json]",
3804 "PIM interface join information\n"
3807 uint8_t uj
= use_json(argc
, argv
);
3813 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3817 vty_out(vty
, " \"%s\": ", vrf
->name
);
3820 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3821 pim_show_join(vrf
->info
, vty
, uj
);
3824 vty_out(vty
, "}\n");
3829 DEFUN (show_ip_pim_local_membership
,
3830 show_ip_pim_local_membership_cmd
,
3831 "show ip pim [vrf NAME] local-membership [json]",
3836 "PIM interface local-membership\n"
3840 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3841 uint8_t uj
= use_json(argc
, argv
);
3846 pim_show_membership(vrf
->info
, vty
, uj
);
3851 DEFUN (show_ip_pim_neighbor
,
3852 show_ip_pim_neighbor_cmd
,
3853 "show ip pim [vrf NAME] neighbor [detail|WORD] [json]",
3858 "PIM neighbor information\n"
3860 "Name of interface or neighbor\n"
3864 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3865 uint8_t uj
= use_json(argc
, argv
);
3870 if (argv_find(argv
, argc
, "detail", &idx
)
3871 || argv_find(argv
, argc
, "WORD", &idx
))
3872 pim_show_neighbors_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
3874 pim_show_neighbors(vrf
->info
, vty
, uj
);
3879 DEFUN (show_ip_pim_neighbor_vrf_all
,
3880 show_ip_pim_neighbor_vrf_all_cmd
,
3881 "show ip pim vrf all neighbor [detail|WORD] [json]",
3886 "PIM neighbor information\n"
3888 "Name of interface or neighbor\n"
3892 uint8_t uj
= use_json(argc
, argv
);
3898 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3902 vty_out(vty
, " \"%s\": ", vrf
->name
);
3905 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3906 if (argv_find(argv
, argc
, "detail", &idx
)
3907 || argv_find(argv
, argc
, "WORD", &idx
))
3908 pim_show_neighbors_single(vrf
->info
, vty
,
3909 argv
[idx
]->arg
, uj
);
3911 pim_show_neighbors(vrf
->info
, vty
, uj
);
3914 vty_out(vty
, "}\n");
3919 DEFUN (show_ip_pim_secondary
,
3920 show_ip_pim_secondary_cmd
,
3921 "show ip pim [vrf NAME] secondary",
3926 "PIM neighbor addresses\n")
3929 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3934 pim_show_neighbors_secondary(vrf
->info
, vty
);
3939 DEFUN (show_ip_pim_state
,
3940 show_ip_pim_state_cmd
,
3941 "show ip pim [vrf NAME] state [A.B.C.D [A.B.C.D]] [json]",
3946 "PIM state information\n"
3947 "Unicast or Multicast address\n"
3948 "Multicast address\n"
3951 const char *src_or_group
= NULL
;
3952 const char *group
= NULL
;
3954 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3955 uint8_t uj
= use_json(argc
, argv
);
3963 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
3964 src_or_group
= argv
[idx
]->arg
;
3966 group
= argv
[idx
+ 1]->arg
;
3969 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
3974 DEFUN (show_ip_pim_state_vrf_all
,
3975 show_ip_pim_state_vrf_all_cmd
,
3976 "show ip pim vrf all state [A.B.C.D [A.B.C.D]] [json]",
3981 "PIM state information\n"
3982 "Unicast or Multicast address\n"
3983 "Multicast address\n"
3986 const char *src_or_group
= NULL
;
3987 const char *group
= NULL
;
3989 uint8_t uj
= use_json(argc
, argv
);
3998 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
3999 src_or_group
= argv
[idx
]->arg
;
4001 group
= argv
[idx
+ 1]->arg
;
4004 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4008 vty_out(vty
, " \"%s\": ", vrf
->name
);
4011 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4012 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
4015 vty_out(vty
, "}\n");
4020 DEFUN (show_ip_pim_upstream
,
4021 show_ip_pim_upstream_cmd
,
4022 "show ip pim [vrf NAME] upstream [json]",
4027 "PIM upstream information\n"
4031 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4032 uint8_t uj
= use_json(argc
, argv
);
4037 pim_show_upstream(vrf
->info
, vty
, uj
);
4042 DEFUN (show_ip_pim_upstream_vrf_all
,
4043 show_ip_pim_upstream_vrf_all_cmd
,
4044 "show ip pim vrf all upstream [json]",
4049 "PIM upstream information\n"
4052 uint8_t uj
= use_json(argc
, argv
);
4058 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4062 vty_out(vty
, " \"%s\": ", vrf
->name
);
4065 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4066 pim_show_upstream(vrf
->info
, vty
, uj
);
4072 DEFUN (show_ip_pim_upstream_join_desired
,
4073 show_ip_pim_upstream_join_desired_cmd
,
4074 "show ip pim [vrf NAME] upstream-join-desired [json]",
4079 "PIM upstream join-desired\n"
4083 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4084 uint8_t uj
= use_json(argc
, argv
);
4089 pim_show_join_desired(vrf
->info
, vty
, uj
);
4094 DEFUN (show_ip_pim_upstream_rpf
,
4095 show_ip_pim_upstream_rpf_cmd
,
4096 "show ip pim [vrf NAME] upstream-rpf [json]",
4101 "PIM upstream source rpf\n"
4105 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4106 uint8_t uj
= use_json(argc
, argv
);
4111 pim_show_upstream_rpf(vrf
->info
, vty
, uj
);
4116 DEFUN (show_ip_pim_rp
,
4118 "show ip pim [vrf NAME] rp-info [json]",
4123 "PIM RP information\n"
4127 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4128 uint8_t uj
= use_json(argc
, argv
);
4133 pim_rp_show_information(vrf
->info
, vty
, uj
);
4138 DEFUN (show_ip_pim_rp_vrf_all
,
4139 show_ip_pim_rp_vrf_all_cmd
,
4140 "show ip pim vrf all rp-info [json]",
4145 "PIM RP information\n"
4148 uint8_t uj
= use_json(argc
, argv
);
4154 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4158 vty_out(vty
, " \"%s\": ", vrf
->name
);
4161 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4162 pim_rp_show_information(vrf
->info
, vty
, uj
);
4165 vty_out(vty
, "}\n");
4170 DEFUN (show_ip_pim_rpf
,
4171 show_ip_pim_rpf_cmd
,
4172 "show ip pim [vrf NAME] rpf [json]",
4177 "PIM cached source rpf information\n"
4181 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4182 uint8_t uj
= use_json(argc
, argv
);
4187 pim_show_rpf(vrf
->info
, vty
, uj
);
4192 DEFUN (show_ip_pim_rpf_vrf_all
,
4193 show_ip_pim_rpf_vrf_all_cmd
,
4194 "show ip pim vrf all rpf [json]",
4199 "PIM cached source rpf information\n"
4202 uint8_t uj
= use_json(argc
, argv
);
4208 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4212 vty_out(vty
, " \"%s\": ", vrf
->name
);
4215 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4216 pim_show_rpf(vrf
->info
, vty
, uj
);
4219 vty_out(vty
, "}\n");
4224 DEFUN (show_ip_pim_nexthop
,
4225 show_ip_pim_nexthop_cmd
,
4226 "show ip pim [vrf NAME] nexthop",
4231 "PIM cached nexthop rpf information\n")
4234 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4239 pim_show_nexthop(vrf
->info
, vty
);
4244 DEFUN (show_ip_pim_nexthop_lookup
,
4245 show_ip_pim_nexthop_lookup_cmd
,
4246 "show ip pim [vrf NAME] nexthop-lookup A.B.C.D A.B.C.D",
4251 "PIM cached nexthop rpf lookup\n"
4252 "Source/RP address\n"
4253 "Multicast Group address\n")
4255 struct pim_nexthop_cache
*pnc
= NULL
;
4256 struct prefix nht_p
;
4258 struct in_addr src_addr
, grp_addr
;
4259 struct in_addr vif_source
;
4260 const char *addr_str
, *addr_str1
;
4262 struct pim_nexthop nexthop
;
4263 char nexthop_addr_str
[PREFIX_STRLEN
];
4264 char grp_str
[PREFIX_STRLEN
];
4266 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4272 argv_find(argv
, argc
, "A.B.C.D", &idx
);
4273 addr_str
= argv
[idx
]->arg
;
4274 result
= inet_pton(AF_INET
, addr_str
, &src_addr
);
4276 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
4277 errno
, safe_strerror(errno
));
4281 if (pim_is_group_224_4(src_addr
)) {
4283 "Invalid argument. Expected Valid Source Address.\n");
4287 addr_str1
= argv
[idx
+ 1]->arg
;
4288 result
= inet_pton(AF_INET
, addr_str1
, &grp_addr
);
4290 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
4291 errno
, safe_strerror(errno
));
4295 if (!pim_is_group_224_4(grp_addr
)) {
4297 "Invalid argument. Expected Valid Multicast Group Address.\n");
4301 if (!pim_rp_set_upstream_addr(vrf
->info
, &vif_source
, src_addr
,
4305 nht_p
.family
= AF_INET
;
4306 nht_p
.prefixlen
= IPV4_MAX_BITLEN
;
4307 nht_p
.u
.prefix4
= vif_source
;
4308 grp
.family
= AF_INET
;
4309 grp
.prefixlen
= IPV4_MAX_BITLEN
;
4310 grp
.u
.prefix4
= grp_addr
;
4311 memset(&nexthop
, 0, sizeof(nexthop
));
4313 memset(&rpf
, 0, sizeof(struct pim_rpf
));
4314 rpf
.rpf_addr
.family
= AF_INET
;
4315 rpf
.rpf_addr
.prefixlen
= IPV4_MAX_BITLEN
;
4316 rpf
.rpf_addr
.u
.prefix4
= vif_source
;
4318 pnc
= pim_nexthop_cache_find(vrf
->info
, &rpf
);
4320 result
= pim_ecmp_nexthop_search(vrf
->info
, pnc
, &nexthop
,
4323 result
= pim_ecmp_nexthop_lookup(vrf
->info
, &nexthop
, &nht_p
,
4328 "Nexthop Lookup failed, no usable routes returned.\n");
4332 pim_addr_dump("<grp?>", &grp
, grp_str
, sizeof(grp_str
));
4333 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
4334 nexthop_addr_str
, sizeof(nexthop_addr_str
));
4335 vty_out(vty
, "Group %s --- Nexthop %s Interface %s \n", grp_str
,
4336 nexthop_addr_str
, nexthop
.interface
->name
);
4341 DEFUN (show_ip_pim_interface_traffic
,
4342 show_ip_pim_interface_traffic_cmd
,
4343 "show ip pim [vrf NAME] interface traffic [WORD] [json]",
4348 "PIM interface information\n"
4349 "Protocol Packet counters\n"
4354 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4355 uint8_t uj
= use_json(argc
, argv
);
4360 if (argv_find(argv
, argc
, "WORD", &idx
))
4361 pim_show_interface_traffic_single(vrf
->info
, vty
,
4362 argv
[idx
]->arg
, uj
);
4364 pim_show_interface_traffic(vrf
->info
, vty
, uj
);
4369 static void show_multicast_interfaces(struct pim_instance
*pim
, struct vty
*vty
)
4371 struct interface
*ifp
;
4376 "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut\n");
4378 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
4379 struct pim_interface
*pim_ifp
;
4380 struct in_addr ifaddr
;
4381 struct sioc_vif_req vreq
;
4383 pim_ifp
= ifp
->info
;
4388 memset(&vreq
, 0, sizeof(vreq
));
4389 vreq
.vifi
= pim_ifp
->mroute_vif_index
;
4391 if (ioctl(pim
->mroute_socket
, SIOCGETVIFCNT
, &vreq
)) {
4393 "ioctl(SIOCGETVIFCNT=%lu) failure for interface %s vif_index=%d: errno=%d: %s",
4394 (unsigned long)SIOCGETVIFCNT
, ifp
->name
,
4395 pim_ifp
->mroute_vif_index
, errno
,
4396 safe_strerror(errno
));
4399 ifaddr
= pim_ifp
->primary_address
;
4401 vty_out(vty
, "%-12s %-15s %3d %3d %7lu %7lu %10lu %10lu\n",
4402 ifp
->name
, inet_ntoa(ifaddr
), ifp
->ifindex
,
4403 pim_ifp
->mroute_vif_index
, (unsigned long)vreq
.icount
,
4404 (unsigned long)vreq
.ocount
, (unsigned long)vreq
.ibytes
,
4405 (unsigned long)vreq
.obytes
);
4409 static void pim_cmd_show_ip_multicast_helper(struct pim_instance
*pim
,
4412 struct vrf
*vrf
= pim
->vrf
;
4413 time_t now
= pim_time_monotonic_sec();
4418 vty_out(vty
, "Mroute socket descriptor:");
4420 vty_out(vty
, " %d(%s)\n", pim
->mroute_socket
, vrf
->name
);
4422 pim_time_uptime(uptime
, sizeof(uptime
),
4423 now
- pim
->mroute_socket_creation
);
4424 vty_out(vty
, "Mroute socket uptime: %s\n", uptime
);
4428 pim_zebra_zclient_update(vty
);
4429 pim_zlookup_show_ip_multicast(vty
);
4432 vty_out(vty
, "Maximum highest VifIndex: %d\n", PIM_MAX_USABLE_VIFS
);
4435 vty_out(vty
, "Upstream Join Timer: %d secs\n", qpim_t_periodic
);
4436 vty_out(vty
, "Join/Prune Holdtime: %d secs\n", PIM_JP_HOLDTIME
);
4437 vty_out(vty
, "PIM ECMP: %s\n", pim
->ecmp_enable
? "Enable" : "Disable");
4438 vty_out(vty
, "PIM ECMP Rebalance: %s\n",
4439 pim
->ecmp_rebalance_enable
? "Enable" : "Disable");
4443 show_rpf_refresh_stats(vty
, pim
, now
, NULL
);
4447 show_scan_oil_stats(pim
, vty
, now
);
4449 show_multicast_interfaces(pim
, vty
);
4452 DEFUN (show_ip_multicast
,
4453 show_ip_multicast_cmd
,
4454 "show ip multicast [vrf NAME]",
4458 "Multicast global information\n")
4461 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4466 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
4471 DEFUN (show_ip_multicast_vrf_all
,
4472 show_ip_multicast_vrf_all_cmd
,
4473 "show ip multicast vrf all",
4477 "Multicast global information\n")
4479 uint8_t uj
= use_json(argc
, argv
);
4485 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4489 vty_out(vty
, " \"%s\": ", vrf
->name
);
4492 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4493 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
4496 vty_out(vty
, "}\n");
4501 static void show_mroute(struct pim_instance
*pim
, struct vty
*vty
, bool fill
,
4504 struct listnode
*node
;
4505 struct channel_oil
*c_oil
;
4506 struct static_route
*s_route
;
4508 json_object
*json
= NULL
;
4509 json_object
*json_group
= NULL
;
4510 json_object
*json_source
= NULL
;
4511 json_object
*json_oil
= NULL
;
4512 json_object
*json_ifp_out
= NULL
;
4515 char grp_str
[INET_ADDRSTRLEN
];
4516 char src_str
[INET_ADDRSTRLEN
];
4517 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
4518 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
4520 struct interface
*ifp_in
;
4524 json
= json_object_new_object();
4527 "Source Group Proto Input Output TTL Uptime\n");
4530 now
= pim_time_monotonic_sec();
4532 /* print list of PIM and IGMP routes */
4533 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
4536 if (!c_oil
->installed
&& !uj
)
4539 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
4541 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
4543 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
4546 strcpy(in_ifname
, ifp_in
->name
);
4548 strcpy(in_ifname
, "<iif?>");
4552 /* Find the group, create it if it doesn't exist */
4553 json_object_object_get_ex(json
, grp_str
, &json_group
);
4556 json_group
= json_object_new_object();
4557 json_object_object_add(json
, grp_str
,
4561 /* Find the source nested under the group, create it if
4562 * it doesn't exist */
4563 json_object_object_get_ex(json_group
, src_str
,
4567 json_source
= json_object_new_object();
4568 json_object_object_add(json_group
, src_str
,
4572 /* Find the inbound interface nested under the source,
4573 * create it if it doesn't exist */
4574 json_object_int_add(json_source
, "installed",
4576 json_object_int_add(json_source
, "refCount",
4577 c_oil
->oil_ref_count
);
4578 json_object_int_add(json_source
, "oilSize",
4580 json_object_int_add(json_source
, "OilInheritedRescan",
4581 c_oil
->oil_inherited_rescan
);
4582 json_object_string_add(json_source
, "iif", in_ifname
);
4586 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
4588 struct interface
*ifp_out
;
4589 char oif_uptime
[10];
4592 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
4596 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
4598 oif_uptime
, sizeof(oif_uptime
),
4599 now
- c_oil
->oif_creation
[oif_vif_index
]);
4603 strcpy(out_ifname
, ifp_out
->name
);
4605 strcpy(out_ifname
, "<oif?>");
4608 json_ifp_out
= json_object_new_object();
4609 json_object_string_add(json_ifp_out
, "source",
4611 json_object_string_add(json_ifp_out
, "group",
4614 if (c_oil
->oif_flags
[oif_vif_index
]
4615 & PIM_OIF_FLAG_PROTO_PIM
)
4616 json_object_boolean_true_add(
4617 json_ifp_out
, "protocolPim");
4619 if (c_oil
->oif_flags
[oif_vif_index
]
4620 & PIM_OIF_FLAG_PROTO_IGMP
)
4621 json_object_boolean_true_add(
4622 json_ifp_out
, "protocolIgmp");
4624 if (c_oil
->oif_flags
[oif_vif_index
]
4625 & PIM_OIF_FLAG_PROTO_SOURCE
)
4626 json_object_boolean_true_add(
4627 json_ifp_out
, "protocolSource");
4629 if (c_oil
->oif_flags
[oif_vif_index
]
4630 & PIM_OIF_FLAG_PROTO_STAR
)
4631 json_object_boolean_true_add(
4633 "protocolInherited");
4635 json_object_string_add(json_ifp_out
,
4638 json_object_int_add(json_ifp_out
, "iVifI",
4639 c_oil
->oil
.mfcc_parent
);
4640 json_object_string_add(json_ifp_out
,
4641 "outboundInterface",
4643 json_object_int_add(json_ifp_out
, "oVifI",
4645 json_object_int_add(json_ifp_out
, "ttl", ttl
);
4646 json_object_string_add(json_ifp_out
, "upTime",
4649 json_oil
= json_object_new_object();
4650 json_object_object_add(json_source
,
4653 json_object_object_add(json_oil
, out_ifname
,
4656 if (c_oil
->oif_flags
[oif_vif_index
]
4657 & PIM_OIF_FLAG_PROTO_PIM
) {
4658 strcpy(proto
, "PIM");
4661 if (c_oil
->oif_flags
[oif_vif_index
]
4662 & PIM_OIF_FLAG_PROTO_IGMP
) {
4663 strcpy(proto
, "IGMP");
4666 if (c_oil
->oif_flags
[oif_vif_index
]
4667 & PIM_OIF_FLAG_PROTO_SOURCE
) {
4668 strcpy(proto
, "SRC");
4671 if (c_oil
->oif_flags
[oif_vif_index
]
4672 & PIM_OIF_FLAG_PROTO_STAR
) {
4673 strcpy(proto
, "STAR");
4677 "%-15s %-15s %-6s %-10s %-10s %-3d %8s\n",
4678 src_str
, grp_str
, proto
, in_ifname
,
4679 out_ifname
, ttl
, oif_uptime
);
4684 in_ifname
[0] = '\0';
4690 if (!uj
&& !found_oif
) {
4691 vty_out(vty
, "%-15s %-15s %-6s %-10s %-10s %-3d %8s\n",
4692 src_str
, grp_str
, "none", in_ifname
, "none", 0,
4697 /* Print list of static routes */
4698 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
4701 if (!s_route
->c_oil
.installed
)
4704 pim_inet4_dump("<group?>", s_route
->group
, grp_str
,
4706 pim_inet4_dump("<source?>", s_route
->source
, src_str
,
4708 ifp_in
= pim_if_find_by_vif_index(pim
, s_route
->iif
);
4712 strcpy(in_ifname
, ifp_in
->name
);
4714 strcpy(in_ifname
, "<iif?>");
4718 /* Find the group, create it if it doesn't exist */
4719 json_object_object_get_ex(json
, grp_str
, &json_group
);
4722 json_group
= json_object_new_object();
4723 json_object_object_add(json
, grp_str
,
4727 /* Find the source nested under the group, create it if
4728 * it doesn't exist */
4729 json_object_object_get_ex(json_group
, src_str
,
4733 json_source
= json_object_new_object();
4734 json_object_object_add(json_group
, src_str
,
4738 json_object_string_add(json_source
, "iif", in_ifname
);
4741 strcpy(proto
, "STATIC");
4744 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
4746 struct interface
*ifp_out
;
4747 char oif_uptime
[10];
4750 ttl
= s_route
->oif_ttls
[oif_vif_index
];
4754 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
4756 oif_uptime
, sizeof(oif_uptime
),
4759 .oif_creation
[oif_vif_index
]);
4763 strcpy(out_ifname
, ifp_out
->name
);
4765 strcpy(out_ifname
, "<oif?>");
4768 json_ifp_out
= json_object_new_object();
4769 json_object_string_add(json_ifp_out
, "source",
4771 json_object_string_add(json_ifp_out
, "group",
4773 json_object_boolean_true_add(json_ifp_out
,
4775 json_object_string_add(json_ifp_out
,
4778 json_object_int_add(
4779 json_ifp_out
, "iVifI",
4780 s_route
->c_oil
.oil
.mfcc_parent
);
4781 json_object_string_add(json_ifp_out
,
4782 "outboundInterface",
4784 json_object_int_add(json_ifp_out
, "oVifI",
4786 json_object_int_add(json_ifp_out
, "ttl", ttl
);
4787 json_object_string_add(json_ifp_out
, "upTime",
4790 json_oil
= json_object_new_object();
4791 json_object_object_add(json_source
,
4794 json_object_object_add(json_oil
, out_ifname
,
4798 "%-15s %-15s %-6s %-10s %-10s %-3d %8s %s\n",
4799 src_str
, grp_str
, proto
, in_ifname
,
4800 out_ifname
, ttl
, oif_uptime
,
4802 if (first
&& !fill
) {
4805 in_ifname
[0] = '\0';
4811 if (!uj
&& !found_oif
) {
4813 "%-15s %-15s %-6s %-10s %-10s %-3d %8s %s\n",
4814 src_str
, grp_str
, proto
, in_ifname
, "none", 0,
4815 "--:--:--", pim
->vrf
->name
);
4820 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4821 json
, JSON_C_TO_STRING_PRETTY
));
4822 json_object_free(json
);
4826 DEFUN (show_ip_mroute
,
4828 "show ip mroute [vrf NAME] [fill] [json]",
4833 "Fill in Assumed data\n"
4836 uint8_t uj
= use_json(argc
, argv
);
4839 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4844 if (argv_find(argv
, argc
, "fill", &idx
))
4847 show_mroute(vrf
->info
, vty
, fill
, uj
);
4851 DEFUN (show_ip_mroute_vrf_all
,
4852 show_ip_mroute_vrf_all_cmd
,
4853 "show ip mroute vrf all [fill] [json]",
4858 "Fill in Assumed data\n"
4861 uint8_t uj
= use_json(argc
, argv
);
4867 if (argv_find(argv
, argc
, "fill", &idx
))
4872 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4876 vty_out(vty
, " \"%s\": ", vrf
->name
);
4879 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4880 show_mroute(vrf
->info
, vty
, fill
, uj
);
4883 vty_out(vty
, "}\n");
4888 static void show_mroute_count(struct pim_instance
*pim
, struct vty
*vty
)
4890 struct listnode
*node
;
4891 struct channel_oil
*c_oil
;
4892 struct static_route
*s_route
;
4897 "Source Group LastUsed Packets Bytes WrongIf \n");
4899 /* Print PIM and IGMP route counts */
4900 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
4901 char group_str
[INET_ADDRSTRLEN
];
4902 char source_str
[INET_ADDRSTRLEN
];
4904 if (!c_oil
->installed
)
4907 pim_mroute_update_counters(c_oil
);
4909 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, group_str
,
4911 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, source_str
,
4912 sizeof(source_str
));
4914 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
4915 source_str
, group_str
, c_oil
->cc
.lastused
/ 100,
4916 c_oil
->cc
.pktcnt
, c_oil
->cc
.bytecnt
,
4917 c_oil
->cc
.wrong_if
);
4920 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
4921 char group_str
[INET_ADDRSTRLEN
];
4922 char source_str
[INET_ADDRSTRLEN
];
4924 if (!s_route
->c_oil
.installed
)
4927 pim_mroute_update_counters(&s_route
->c_oil
);
4929 pim_inet4_dump("<group?>", s_route
->c_oil
.oil
.mfcc_mcastgrp
,
4930 group_str
, sizeof(group_str
));
4931 pim_inet4_dump("<source?>", s_route
->c_oil
.oil
.mfcc_origin
,
4932 source_str
, sizeof(source_str
));
4934 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
4935 source_str
, group_str
, s_route
->c_oil
.cc
.lastused
,
4936 s_route
->c_oil
.cc
.pktcnt
, s_route
->c_oil
.cc
.bytecnt
,
4937 s_route
->c_oil
.cc
.wrong_if
);
4941 DEFUN (show_ip_mroute_count
,
4942 show_ip_mroute_count_cmd
,
4943 "show ip mroute [vrf NAME] count",
4948 "Route and packet count data\n")
4951 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4956 show_mroute_count(vrf
->info
, vty
);
4960 DEFUN (show_ip_mroute_count_vrf_all
,
4961 show_ip_mroute_count_vrf_all_cmd
,
4962 "show ip mroute vrf all count",
4967 "Route and packet count data\n")
4969 uint8_t uj
= use_json(argc
, argv
);
4975 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4979 vty_out(vty
, " \"%s\": ", vrf
->name
);
4982 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4983 show_mroute_count(vrf
->info
, vty
);
4986 vty_out(vty
, "}\n");
4993 "show ip rib [vrf NAME] A.B.C.D",
4998 "Unicast address\n")
5001 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5002 struct in_addr addr
;
5003 const char *addr_str
;
5004 struct pim_nexthop nexthop
;
5005 char nexthop_addr_str
[PREFIX_STRLEN
];
5011 memset(&nexthop
, 0, sizeof(nexthop
));
5012 argv_find(argv
, argc
, "A.B.C.D", &idx
);
5013 addr_str
= argv
[idx
]->arg
;
5014 result
= inet_pton(AF_INET
, addr_str
, &addr
);
5016 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
5017 errno
, safe_strerror(errno
));
5021 if (pim_nexthop_lookup(vrf
->info
, &nexthop
, addr
, 0)) {
5023 "Failure querying RIB nexthop for unicast address %s\n",
5029 "Address NextHop Interface Metric Preference\n");
5031 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
5032 nexthop_addr_str
, sizeof(nexthop_addr_str
));
5034 vty_out(vty
, "%-15s %-15s %-9s %6d %10d\n", addr_str
, nexthop_addr_str
,
5035 nexthop
.interface
? nexthop
.interface
->name
: "<ifname?>",
5036 nexthop
.mrib_route_metric
, nexthop
.mrib_metric_preference
);
5041 static void show_ssmpingd(struct pim_instance
*pim
, struct vty
*vty
)
5043 struct listnode
*node
;
5044 struct ssmpingd_sock
*ss
;
5048 "Source Socket Address Port Uptime Requests\n");
5050 if (!pim
->ssmpingd_list
)
5053 now
= pim_time_monotonic_sec();
5055 for (ALL_LIST_ELEMENTS_RO(pim
->ssmpingd_list
, node
, ss
)) {
5056 char source_str
[INET_ADDRSTRLEN
];
5058 struct sockaddr_in bind_addr
;
5059 socklen_t len
= sizeof(bind_addr
);
5060 char bind_addr_str
[INET_ADDRSTRLEN
];
5062 pim_inet4_dump("<src?>", ss
->source_addr
, source_str
,
5063 sizeof(source_str
));
5065 if (pim_socket_getsockname(
5066 ss
->sock_fd
, (struct sockaddr
*)&bind_addr
, &len
)) {
5068 "%% Failure reading socket name for ssmpingd source %s on fd=%d\n",
5069 source_str
, ss
->sock_fd
);
5072 pim_inet4_dump("<addr?>", bind_addr
.sin_addr
, bind_addr_str
,
5073 sizeof(bind_addr_str
));
5074 pim_time_uptime(ss_uptime
, sizeof(ss_uptime
),
5075 now
- ss
->creation
);
5077 vty_out(vty
, "%-15s %6d %-15s %5d %8s %8lld\n", source_str
,
5078 ss
->sock_fd
, bind_addr_str
, ntohs(bind_addr
.sin_port
),
5079 ss_uptime
, (long long)ss
->requests
);
5083 DEFUN (show_ip_ssmpingd
,
5084 show_ip_ssmpingd_cmd
,
5085 "show ip ssmpingd [vrf NAME]",
5092 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5097 show_ssmpingd(vrf
->info
, vty
);
5101 static int pim_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
5102 const char *rp
, const char *group
,
5107 result
= pim_rp_new(pim
, rp
, group
, plist
);
5109 if (result
== PIM_MALLOC_FAIL
) {
5110 vty_out(vty
, "%% Out of memory\n");
5111 return CMD_WARNING_CONFIG_FAILED
;
5114 if (result
== PIM_GROUP_BAD_ADDRESS
) {
5115 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
5116 return CMD_WARNING_CONFIG_FAILED
;
5119 if (result
== PIM_RP_BAD_ADDRESS
) {
5120 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
5121 return CMD_WARNING_CONFIG_FAILED
;
5124 if (result
== PIM_RP_NO_PATH
) {
5125 vty_out(vty
, "%% No Path to RP address specified: %s\n", rp
);
5129 if (result
== PIM_GROUP_OVERLAP
) {
5131 "%% Group range specified cannot exact match another\n");
5132 return CMD_WARNING_CONFIG_FAILED
;
5135 if (result
== PIM_GROUP_PFXLIST_OVERLAP
) {
5137 "%% This group is already covered by a RP prefix-list\n");
5138 return CMD_WARNING_CONFIG_FAILED
;
5141 if (result
== PIM_RP_PFXLIST_IN_USE
) {
5143 "%% The same prefix-list cannot be applied to multiple RPs\n");
5144 return CMD_WARNING_CONFIG_FAILED
;
5150 static int pim_cmd_spt_switchover(struct pim_instance
*pim
,
5151 enum pim_spt_switchover spt
,
5154 pim
->spt
.switchover
= spt
;
5156 switch (pim
->spt
.switchover
) {
5157 case PIM_SPT_IMMEDIATE
:
5159 XFREE(MTYPE_PIM_SPT_PLIST_NAME
, pim
->spt
.plist
);
5161 pim_upstream_add_lhr_star_pimreg(pim
);
5163 case PIM_SPT_INFINITY
:
5164 pim_upstream_remove_lhr_star_pimreg(pim
, plist
);
5167 XFREE(MTYPE_PIM_SPT_PLIST_NAME
, pim
->spt
.plist
);
5171 XSTRDUP(MTYPE_PIM_SPT_PLIST_NAME
, plist
);
5178 DEFUN (ip_pim_spt_switchover_infinity
,
5179 ip_pim_spt_switchover_infinity_cmd
,
5180 "ip pim spt-switchover infinity-and-beyond",
5184 "Never switch to SPT Tree\n")
5186 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5187 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, NULL
);
5190 DEFUN (ip_pim_spt_switchover_infinity_plist
,
5191 ip_pim_spt_switchover_infinity_plist_cmd
,
5192 "ip pim spt-switchover infinity-and-beyond prefix-list WORD",
5196 "Never switch to SPT Tree\n"
5197 "Prefix-List to control which groups to switch\n"
5198 "Prefix-List name\n")
5200 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5201 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, argv
[5]->arg
);
5204 DEFUN (no_ip_pim_spt_switchover_infinity
,
5205 no_ip_pim_spt_switchover_infinity_cmd
,
5206 "no ip pim spt-switchover infinity-and-beyond",
5211 "Never switch to SPT Tree\n")
5213 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5214 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
5217 DEFUN (no_ip_pim_spt_switchover_infinity_plist
,
5218 no_ip_pim_spt_switchover_infinity_plist_cmd
,
5219 "no ip pim spt-switchover infinity-and-beyond prefix-list WORD",
5224 "Never switch to SPT Tree\n"
5225 "Prefix-List to control which groups to switch\n"
5226 "Prefix-List name\n")
5228 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5229 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
5232 DEFUN (ip_pim_joinprune_time
,
5233 ip_pim_joinprune_time_cmd
,
5234 "ip pim join-prune-interval (60-600)",
5236 "pim multicast routing\n"
5237 "Join Prune Send Interval\n"
5240 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5241 qpim_t_periodic
= atoi(argv
[3]->arg
);
5245 DEFUN (no_ip_pim_joinprune_time
,
5246 no_ip_pim_joinprune_time_cmd
,
5247 "no ip pim join-prune-interval (60-600)",
5250 "pim multicast routing\n"
5251 "Join Prune Send Interval\n"
5254 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5255 qpim_t_periodic
= PIM_DEFAULT_T_PERIODIC
;
5259 DEFUN (ip_pim_register_suppress
,
5260 ip_pim_register_suppress_cmd
,
5261 "ip pim register-suppress-time (5-60000)",
5263 "pim multicast routing\n"
5264 "Register Suppress Timer\n"
5267 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5268 qpim_register_suppress_time
= atoi(argv
[3]->arg
);
5272 DEFUN (no_ip_pim_register_suppress
,
5273 no_ip_pim_register_suppress_cmd
,
5274 "no ip pim register-suppress-time (5-60000)",
5277 "pim multicast routing\n"
5278 "Register Suppress Timer\n"
5281 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5282 qpim_register_suppress_time
= PIM_REGISTER_SUPPRESSION_TIME_DEFAULT
;
5286 DEFUN (ip_pim_rp_keep_alive
,
5287 ip_pim_rp_keep_alive_cmd
,
5288 "ip pim rp keep-alive-timer (31-60000)",
5290 "pim multicast routing\n"
5292 "Keep alive Timer\n"
5295 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5296 pim
->rp_keep_alive_time
= atoi(argv
[4]->arg
);
5300 DEFUN (no_ip_pim_rp_keep_alive
,
5301 no_ip_pim_rp_keep_alive_cmd
,
5302 "no ip pim rp keep-alive-timer (31-60000)",
5305 "pim multicast routing\n"
5307 "Keep alive Timer\n"
5310 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5311 pim
->rp_keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
5315 DEFUN (ip_pim_keep_alive
,
5316 ip_pim_keep_alive_cmd
,
5317 "ip pim keep-alive-timer (31-60000)",
5319 "pim multicast routing\n"
5320 "Keep alive Timer\n"
5323 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5324 pim
->keep_alive_time
= atoi(argv
[3]->arg
);
5328 DEFUN (no_ip_pim_keep_alive
,
5329 no_ip_pim_keep_alive_cmd
,
5330 "no ip pim keep-alive-timer (31-60000)",
5333 "pim multicast routing\n"
5334 "Keep alive Timer\n"
5337 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5338 pim
->keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
5342 DEFUN (ip_pim_packets
,
5344 "ip pim packets (1-100)",
5346 "pim multicast routing\n"
5347 "packets to process at one time per fd\n"
5348 "Number of packets\n")
5350 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5351 qpim_packet_process
= atoi(argv
[3]->arg
);
5355 DEFUN (no_ip_pim_packets
,
5356 no_ip_pim_packets_cmd
,
5357 "no ip pim packets (1-100)",
5360 "pim multicast routing\n"
5361 "packets to process at one time per fd\n"
5362 "Number of packets\n")
5364 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5365 qpim_packet_process
= PIM_DEFAULT_PACKET_PROCESS
;
5369 DEFUN (ip_pim_v6_secondary
,
5370 ip_pim_v6_secondary_cmd
,
5371 "ip pim send-v6-secondary",
5373 "pim multicast routing\n"
5374 "Send v6 secondary addresses\n")
5376 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5377 pim
->send_v6_secondary
= 1;
5382 DEFUN (no_ip_pim_v6_secondary
,
5383 no_ip_pim_v6_secondary_cmd
,
5384 "no ip pim send-v6-secondary",
5387 "pim multicast routing\n"
5388 "Send v6 secondary addresses\n")
5390 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5391 pim
->send_v6_secondary
= 0;
5398 "ip pim rp A.B.C.D [A.B.C.D/M]",
5400 "pim multicast routing\n"
5402 "ip address of RP\n"
5403 "Group Address range to cover\n")
5405 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5408 if (argc
== (idx_ipv4
+ 1))
5409 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
5412 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
5413 argv
[idx_ipv4
+ 1]->arg
, NULL
);
5416 DEFUN (ip_pim_rp_prefix_list
,
5417 ip_pim_rp_prefix_list_cmd
,
5418 "ip pim rp A.B.C.D prefix-list WORD",
5420 "pim multicast routing\n"
5422 "ip address of RP\n"
5423 "group prefix-list filter\n"
5424 "Name of a prefix-list\n")
5426 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5427 return pim_rp_cmd_worker(pim
, vty
, argv
[3]->arg
, NULL
, argv
[5]->arg
);
5430 static int pim_no_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
5431 const char *rp
, const char *group
,
5434 int result
= pim_rp_del(pim
, rp
, group
, plist
);
5436 if (result
== PIM_GROUP_BAD_ADDRESS
) {
5437 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
5438 return CMD_WARNING_CONFIG_FAILED
;
5441 if (result
== PIM_RP_BAD_ADDRESS
) {
5442 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
5443 return CMD_WARNING_CONFIG_FAILED
;
5446 if (result
== PIM_RP_NOT_FOUND
) {
5447 vty_out(vty
, "%% Unable to find specified RP\n");
5448 return CMD_WARNING_CONFIG_FAILED
;
5454 DEFUN (no_ip_pim_rp
,
5456 "no ip pim rp A.B.C.D [A.B.C.D/M]",
5459 "pim multicast routing\n"
5461 "ip address of RP\n"
5462 "Group Address range to cover\n")
5464 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5465 int idx_ipv4
= 4, idx_group
= 0;
5467 if (argv_find(argv
, argc
, "A.B.C.D/M", &idx_group
))
5468 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
5469 argv
[idx_group
]->arg
, NULL
);
5471 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
5475 DEFUN (no_ip_pim_rp_prefix_list
,
5476 no_ip_pim_rp_prefix_list_cmd
,
5477 "no ip pim rp A.B.C.D prefix-list WORD",
5480 "pim multicast routing\n"
5482 "ip address of RP\n"
5483 "group prefix-list filter\n"
5484 "Name of a prefix-list\n")
5486 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5487 return pim_no_rp_cmd_worker(pim
, vty
, argv
[4]->arg
, NULL
, argv
[6]->arg
);
5490 static int pim_ssm_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
5493 int result
= pim_ssm_range_set(pim
, pim
->vrf_id
, plist
);
5495 if (result
== PIM_SSM_ERR_NONE
)
5499 case PIM_SSM_ERR_NO_VRF
:
5500 vty_out(vty
, "%% VRF doesn't exist\n");
5502 case PIM_SSM_ERR_DUP
:
5503 vty_out(vty
, "%% duplicate config\n");
5506 vty_out(vty
, "%% ssm range config failed\n");
5509 return CMD_WARNING_CONFIG_FAILED
;
5512 DEFUN (ip_pim_ssm_prefix_list
,
5513 ip_pim_ssm_prefix_list_cmd
,
5514 "ip pim ssm prefix-list WORD",
5516 "pim multicast routing\n"
5517 "Source Specific Multicast\n"
5518 "group range prefix-list filter\n"
5519 "Name of a prefix-list\n")
5521 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5522 return pim_ssm_cmd_worker(pim
, vty
, argv
[4]->arg
);
5525 DEFUN (no_ip_pim_ssm_prefix_list
,
5526 no_ip_pim_ssm_prefix_list_cmd
,
5527 "no ip pim ssm prefix-list",
5530 "pim multicast routing\n"
5531 "Source Specific Multicast\n"
5532 "group range prefix-list filter\n")
5534 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5535 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
5538 DEFUN (no_ip_pim_ssm_prefix_list_name
,
5539 no_ip_pim_ssm_prefix_list_name_cmd
,
5540 "no ip pim ssm prefix-list WORD",
5543 "pim multicast routing\n"
5544 "Source Specific Multicast\n"
5545 "group range prefix-list filter\n"
5546 "Name of a prefix-list\n")
5548 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5549 struct pim_ssm
*ssm
= pim
->ssm_info
;
5551 if (ssm
->plist_name
&& !strcmp(ssm
->plist_name
, argv
[5]->arg
))
5552 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
5554 vty_out(vty
, "%% pim ssm prefix-list %s doesn't exist\n", argv
[5]->arg
);
5556 return CMD_WARNING_CONFIG_FAILED
;
5559 static void ip_pim_ssm_show_group_range(struct pim_instance
*pim
,
5560 struct vty
*vty
, uint8_t uj
)
5562 struct pim_ssm
*ssm
= pim
->ssm_info
;
5563 const char *range_str
=
5564 ssm
->plist_name
? ssm
->plist_name
: PIM_SSM_STANDARD_RANGE
;
5568 json
= json_object_new_object();
5569 json_object_string_add(json
, "ssmGroups", range_str
);
5570 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5571 json
, JSON_C_TO_STRING_PRETTY
));
5572 json_object_free(json
);
5574 vty_out(vty
, "SSM group range : %s\n", range_str
);
5577 DEFUN (show_ip_pim_ssm_range
,
5578 show_ip_pim_ssm_range_cmd
,
5579 "show ip pim [vrf NAME] group-type [json]",
5588 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5589 uint8_t uj
= use_json(argc
, argv
);
5594 ip_pim_ssm_show_group_range(vrf
->info
, vty
, uj
);
5599 static void ip_pim_ssm_show_group_type(struct pim_instance
*pim
,
5600 struct vty
*vty
, uint8_t uj
,
5603 struct in_addr group_addr
;
5604 const char *type_str
;
5607 result
= inet_pton(AF_INET
, group
, &group_addr
);
5609 type_str
= "invalid";
5611 if (pim_is_group_224_4(group_addr
))
5613 pim_is_grp_ssm(pim
, group_addr
) ? "SSM" : "ASM";
5615 type_str
= "not-multicast";
5620 json
= json_object_new_object();
5621 json_object_string_add(json
, "groupType", type_str
);
5622 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5623 json
, JSON_C_TO_STRING_PRETTY
));
5624 json_object_free(json
);
5626 vty_out(vty
, "Group type : %s\n", type_str
);
5629 DEFUN (show_ip_pim_group_type
,
5630 show_ip_pim_group_type_cmd
,
5631 "show ip pim [vrf NAME] group-type A.B.C.D [json]",
5636 "multicast group type\n"
5641 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5642 uint8_t uj
= use_json(argc
, argv
);
5647 argv_find(argv
, argc
, "A.B.C.D", &idx
);
5648 ip_pim_ssm_show_group_type(vrf
->info
, vty
, uj
, argv
[idx
]->arg
);
5653 DEFUN_HIDDEN (ip_multicast_routing
,
5654 ip_multicast_routing_cmd
,
5655 "ip multicast-routing",
5657 "Enable IP multicast forwarding\n")
5662 DEFUN_HIDDEN (no_ip_multicast_routing
,
5663 no_ip_multicast_routing_cmd
,
5664 "no ip multicast-routing",
5667 "Enable IP multicast forwarding\n")
5670 "Command is Disabled and will be removed in a future version\n");
5676 "ip ssmpingd [A.B.C.D]",
5681 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5684 struct in_addr source_addr
;
5685 const char *source_str
= (argc
== 3) ? 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_start(pim
, source_addr
);
5696 vty_out(vty
, "%% Failure starting ssmpingd for source %s: %d\n",
5697 source_str
, result
);
5698 return CMD_WARNING_CONFIG_FAILED
;
5704 DEFUN (no_ip_ssmpingd
,
5706 "no ip ssmpingd [A.B.C.D]",
5712 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5715 struct in_addr source_addr
;
5716 const char *source_str
= (argc
== 4) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
5718 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
5720 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
5721 source_str
, errno
, safe_strerror(errno
));
5722 return CMD_WARNING_CONFIG_FAILED
;
5725 result
= pim_ssmpingd_stop(pim
, source_addr
);
5727 vty_out(vty
, "%% Failure stopping ssmpingd for source %s: %d\n",
5728 source_str
, result
);
5729 return CMD_WARNING_CONFIG_FAILED
;
5739 "pim multicast routing\n"
5740 "Enable PIM ECMP \n")
5742 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5743 pim
->ecmp_enable
= true;
5748 DEFUN (no_ip_pim_ecmp
,
5753 "pim multicast routing\n"
5754 "Disable PIM ECMP \n")
5756 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5757 pim
->ecmp_enable
= false;
5762 DEFUN (ip_pim_ecmp_rebalance
,
5763 ip_pim_ecmp_rebalance_cmd
,
5764 "ip pim ecmp rebalance",
5766 "pim multicast routing\n"
5767 "Enable PIM ECMP \n"
5768 "Enable PIM ECMP Rebalance\n")
5770 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5771 pim
->ecmp_enable
= true;
5772 pim
->ecmp_rebalance_enable
= true;
5777 DEFUN (no_ip_pim_ecmp_rebalance
,
5778 no_ip_pim_ecmp_rebalance_cmd
,
5779 "no ip pim ecmp rebalance",
5782 "pim multicast routing\n"
5783 "Disable PIM ECMP \n"
5784 "Disable PIM ECMP Rebalance\n")
5786 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5787 pim
->ecmp_rebalance_enable
= false;
5792 static int pim_cmd_igmp_start(struct vty
*vty
, struct interface
*ifp
)
5794 struct pim_interface
*pim_ifp
;
5795 uint8_t need_startup
= 0;
5797 pim_ifp
= ifp
->info
;
5800 pim_ifp
= pim_if_new(ifp
, 1 /* igmp=true */, 0 /* pim=false */);
5802 vty_out(vty
, "Could not enable IGMP on interface %s\n",
5804 return CMD_WARNING_CONFIG_FAILED
;
5808 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
5809 PIM_IF_DO_IGMP(pim_ifp
->options
);
5814 /* 'ip igmp' executed multiple times, with need_startup
5815 avoid multiple if add all and membership refresh */
5817 pim_if_addr_add_all(ifp
);
5818 pim_if_membership_refresh(ifp
);
5824 DEFUN (interface_ip_igmp
,
5825 interface_ip_igmp_cmd
,
5830 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5832 return pim_cmd_igmp_start(vty
, ifp
);
5835 DEFUN (interface_no_ip_igmp
,
5836 interface_no_ip_igmp_cmd
,
5842 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5843 struct pim_interface
*pim_ifp
= ifp
->info
;
5848 PIM_IF_DONT_IGMP(pim_ifp
->options
);
5850 pim_if_membership_clear(ifp
);
5852 pim_if_addr_del_all_igmp(ifp
);
5854 if (!PIM_IF_TEST_PIM(pim_ifp
->options
)) {
5861 DEFUN (interface_ip_igmp_join
,
5862 interface_ip_igmp_join_cmd
,
5863 "ip igmp join A.B.C.D A.B.C.D",
5866 "IGMP join multicast group\n"
5867 "Multicast group address\n"
5870 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5873 const char *group_str
;
5874 const char *source_str
;
5875 struct in_addr group_addr
;
5876 struct in_addr source_addr
;
5880 group_str
= argv
[idx_ipv4
]->arg
;
5881 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
5883 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
5884 errno
, safe_strerror(errno
));
5885 return CMD_WARNING_CONFIG_FAILED
;
5888 /* Source address */
5889 source_str
= argv
[idx_ipv4_2
]->arg
;
5890 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
5892 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
5893 source_str
, errno
, safe_strerror(errno
));
5894 return CMD_WARNING_CONFIG_FAILED
;
5897 CMD_FERR_RETURN(pim_if_igmp_join_add(ifp
, group_addr
, source_addr
),
5898 "Failure joining IGMP group: $ERR");
5903 DEFUN (interface_no_ip_igmp_join
,
5904 interface_no_ip_igmp_join_cmd
,
5905 "no ip igmp join A.B.C.D A.B.C.D",
5909 "IGMP join multicast group\n"
5910 "Multicast group address\n"
5913 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5916 const char *group_str
;
5917 const char *source_str
;
5918 struct in_addr group_addr
;
5919 struct in_addr source_addr
;
5923 group_str
= argv
[idx_ipv4
]->arg
;
5924 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
5926 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
5927 errno
, safe_strerror(errno
));
5928 return CMD_WARNING_CONFIG_FAILED
;
5931 /* Source address */
5932 source_str
= argv
[idx_ipv4_2
]->arg
;
5933 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
5935 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
5936 source_str
, errno
, safe_strerror(errno
));
5937 return CMD_WARNING_CONFIG_FAILED
;
5940 result
= pim_if_igmp_join_del(ifp
, group_addr
, source_addr
);
5943 "%% Failure leaving IGMP group %s source %s on interface %s: %d\n",
5944 group_str
, source_str
, ifp
->name
, result
);
5945 return CMD_WARNING_CONFIG_FAILED
;
5952 CLI reconfiguration affects the interface level (struct pim_interface).
5953 This function propagates the reconfiguration to every active socket
5956 static void igmp_sock_query_interval_reconfig(struct igmp_sock
*igmp
)
5958 struct interface
*ifp
;
5959 struct pim_interface
*pim_ifp
;
5963 /* other querier present? */
5965 if (igmp
->t_other_querier_timer
)
5968 /* this is the querier */
5970 zassert(igmp
->interface
);
5971 zassert(igmp
->interface
->info
);
5973 ifp
= igmp
->interface
;
5974 pim_ifp
= ifp
->info
;
5976 if (PIM_DEBUG_IGMP_TRACE
) {
5977 char ifaddr_str
[INET_ADDRSTRLEN
];
5978 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
5979 sizeof(ifaddr_str
));
5980 zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
5981 __PRETTY_FUNCTION__
, ifaddr_str
, ifp
->name
,
5982 pim_ifp
->igmp_default_query_interval
);
5986 igmp_startup_mode_on() will reset QQI:
5988 igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
5990 igmp_startup_mode_on(igmp
);
5993 static void igmp_sock_query_reschedule(struct igmp_sock
*igmp
)
5995 if (igmp
->t_igmp_query_timer
) {
5996 /* other querier present */
5997 zassert(igmp
->t_igmp_query_timer
);
5998 zassert(!igmp
->t_other_querier_timer
);
6000 pim_igmp_general_query_off(igmp
);
6001 pim_igmp_general_query_on(igmp
);
6003 zassert(igmp
->t_igmp_query_timer
);
6004 zassert(!igmp
->t_other_querier_timer
);
6006 /* this is the querier */
6008 zassert(!igmp
->t_igmp_query_timer
);
6009 zassert(igmp
->t_other_querier_timer
);
6011 pim_igmp_other_querier_timer_off(igmp
);
6012 pim_igmp_other_querier_timer_on(igmp
);
6014 zassert(!igmp
->t_igmp_query_timer
);
6015 zassert(igmp
->t_other_querier_timer
);
6019 static void change_query_interval(struct pim_interface
*pim_ifp
,
6022 struct listnode
*sock_node
;
6023 struct igmp_sock
*igmp
;
6025 pim_ifp
->igmp_default_query_interval
= query_interval
;
6027 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
6028 igmp_sock_query_interval_reconfig(igmp
);
6029 igmp_sock_query_reschedule(igmp
);
6033 static void change_query_max_response_time(struct pim_interface
*pim_ifp
,
6034 int query_max_response_time_dsec
)
6036 struct listnode
*sock_node
;
6037 struct igmp_sock
*igmp
;
6039 pim_ifp
->igmp_query_max_response_time_dsec
=
6040 query_max_response_time_dsec
;
6043 Below we modify socket/group/source timers in order to quickly
6044 reflect the change. Otherwise, those timers would eventually catch
6048 /* scan all sockets */
6049 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
6050 struct listnode
*grp_node
;
6051 struct igmp_group
*grp
;
6053 /* reschedule socket general query */
6054 igmp_sock_query_reschedule(igmp
);
6056 /* scan socket groups */
6057 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grp_node
,
6059 struct listnode
*src_node
;
6060 struct igmp_source
*src
;
6062 /* reset group timers for groups in EXCLUDE mode */
6063 if (grp
->group_filtermode_isexcl
) {
6064 igmp_group_reset_gmi(grp
);
6067 /* scan group sources */
6068 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
,
6071 /* reset source timers for sources with running
6073 if (src
->t_source_timer
) {
6074 igmp_source_reset_gmi(igmp
, grp
, src
);
6081 #define IGMP_QUERY_INTERVAL_MIN (1)
6082 #define IGMP_QUERY_INTERVAL_MAX (1800)
6084 DEFUN (interface_ip_igmp_query_interval
,
6085 interface_ip_igmp_query_interval_cmd
,
6086 "ip igmp query-interval (1-1800)",
6089 IFACE_IGMP_QUERY_INTERVAL_STR
6090 "Query interval in seconds\n")
6092 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6093 struct pim_interface
*pim_ifp
= ifp
->info
;
6095 int query_interval_dsec
;
6099 ret
= pim_cmd_igmp_start(vty
, ifp
);
6100 if (ret
!= CMD_SUCCESS
)
6102 pim_ifp
= ifp
->info
;
6105 query_interval
= atoi(argv
[3]->arg
);
6106 query_interval_dsec
= 10 * query_interval
;
6109 It seems we don't need to check bounds since command.c does it
6110 already, but we verify them anyway for extra safety.
6112 if (query_interval
< IGMP_QUERY_INTERVAL_MIN
) {
6114 "General query interval %d lower than minimum %d\n",
6115 query_interval
, IGMP_QUERY_INTERVAL_MIN
);
6116 return CMD_WARNING_CONFIG_FAILED
;
6118 if (query_interval
> IGMP_QUERY_INTERVAL_MAX
) {
6120 "General query interval %d higher than maximum %d\n",
6121 query_interval
, IGMP_QUERY_INTERVAL_MAX
);
6122 return CMD_WARNING_CONFIG_FAILED
;
6125 if (query_interval_dsec
<= pim_ifp
->igmp_query_max_response_time_dsec
) {
6127 "Can't set general query interval %d dsec <= query max response time %d dsec.\n",
6128 query_interval_dsec
,
6129 pim_ifp
->igmp_query_max_response_time_dsec
);
6130 return CMD_WARNING_CONFIG_FAILED
;
6133 change_query_interval(pim_ifp
, query_interval
);
6138 DEFUN (interface_no_ip_igmp_query_interval
,
6139 interface_no_ip_igmp_query_interval_cmd
,
6140 "no ip igmp query-interval",
6144 IFACE_IGMP_QUERY_INTERVAL_STR
)
6146 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6147 struct pim_interface
*pim_ifp
= ifp
->info
;
6148 int default_query_interval_dsec
;
6153 default_query_interval_dsec
= IGMP_GENERAL_QUERY_INTERVAL
* 10;
6155 if (default_query_interval_dsec
6156 <= pim_ifp
->igmp_query_max_response_time_dsec
) {
6158 "Can't set default general query interval %d dsec <= query max response time %d dsec.\n",
6159 default_query_interval_dsec
,
6160 pim_ifp
->igmp_query_max_response_time_dsec
);
6161 return CMD_WARNING_CONFIG_FAILED
;
6164 change_query_interval(pim_ifp
, IGMP_GENERAL_QUERY_INTERVAL
);
6169 DEFUN (interface_ip_igmp_version
,
6170 interface_ip_igmp_version_cmd
,
6171 "ip igmp version (2-3)",
6175 "IGMP version number\n")
6177 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6178 struct pim_interface
*pim_ifp
= ifp
->info
;
6179 int igmp_version
, old_version
= 0;
6183 ret
= pim_cmd_igmp_start(vty
, ifp
);
6184 if (ret
!= CMD_SUCCESS
)
6186 pim_ifp
= ifp
->info
;
6189 igmp_version
= atoi(argv
[3]->arg
);
6190 old_version
= pim_ifp
->igmp_version
;
6191 pim_ifp
->igmp_version
= igmp_version
;
6193 // Check if IGMP is Enabled otherwise, enable on interface
6194 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
6195 PIM_IF_DO_IGMP(pim_ifp
->options
);
6196 pim_if_addr_add_all(ifp
);
6197 pim_if_membership_refresh(ifp
);
6198 old_version
= igmp_version
;
6199 // avoid refreshing membership again.
6201 /* Current and new version is different refresh existing
6202 membership. Going from 3 -> 2 or 2 -> 3. */
6203 if (old_version
!= igmp_version
)
6204 pim_if_membership_refresh(ifp
);
6209 DEFUN (interface_no_ip_igmp_version
,
6210 interface_no_ip_igmp_version_cmd
,
6211 "no ip igmp version (2-3)",
6216 "IGMP version number\n")
6218 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6219 struct pim_interface
*pim_ifp
= ifp
->info
;
6224 pim_ifp
->igmp_version
= IGMP_DEFAULT_VERSION
;
6229 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
6230 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
6232 DEFUN (interface_ip_igmp_query_max_response_time
,
6233 interface_ip_igmp_query_max_response_time_cmd
,
6234 "ip igmp query-max-response-time (10-250)",
6237 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
6238 "Query response value in deci-seconds\n")
6240 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6241 struct pim_interface
*pim_ifp
= ifp
->info
;
6242 int query_max_response_time
;
6246 ret
= pim_cmd_igmp_start(vty
, ifp
);
6247 if (ret
!= CMD_SUCCESS
)
6249 pim_ifp
= ifp
->info
;
6252 query_max_response_time
= atoi(argv
[3]->arg
);
6254 if (query_max_response_time
6255 >= pim_ifp
->igmp_default_query_interval
* 10) {
6257 "Can't set query max response time %d sec >= general query interval %d sec\n",
6258 query_max_response_time
,
6259 pim_ifp
->igmp_default_query_interval
);
6260 return CMD_WARNING_CONFIG_FAILED
;
6263 change_query_max_response_time(pim_ifp
, query_max_response_time
);
6268 DEFUN (interface_no_ip_igmp_query_max_response_time
,
6269 interface_no_ip_igmp_query_max_response_time_cmd
,
6270 "no ip igmp query-max-response-time (10-250)",
6274 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
6275 "Time for response in deci-seconds\n")
6277 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6278 struct pim_interface
*pim_ifp
= ifp
->info
;
6283 change_query_max_response_time(pim_ifp
,
6284 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
6289 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
6290 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
6292 DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec
,
6293 interface_ip_igmp_query_max_response_time_dsec_cmd
,
6294 "ip igmp query-max-response-time-dsec (10-250)",
6297 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
6298 "Query response value in deciseconds\n")
6300 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6301 struct pim_interface
*pim_ifp
= ifp
->info
;
6302 int query_max_response_time_dsec
;
6303 int default_query_interval_dsec
;
6307 ret
= pim_cmd_igmp_start(vty
, ifp
);
6308 if (ret
!= CMD_SUCCESS
)
6310 pim_ifp
= ifp
->info
;
6313 query_max_response_time_dsec
= atoi(argv
[4]->arg
);
6315 default_query_interval_dsec
= 10 * pim_ifp
->igmp_default_query_interval
;
6317 if (query_max_response_time_dsec
>= default_query_interval_dsec
) {
6319 "Can't set query max response time %d dsec >= general query interval %d dsec\n",
6320 query_max_response_time_dsec
,
6321 default_query_interval_dsec
);
6322 return CMD_WARNING_CONFIG_FAILED
;
6325 change_query_max_response_time(pim_ifp
, query_max_response_time_dsec
);
6330 DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec
,
6331 interface_no_ip_igmp_query_max_response_time_dsec_cmd
,
6332 "no ip igmp query-max-response-time-dsec",
6336 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
)
6338 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6339 struct pim_interface
*pim_ifp
= ifp
->info
;
6344 change_query_max_response_time(pim_ifp
,
6345 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
6350 DEFUN (interface_ip_pim_drprio
,
6351 interface_ip_pim_drprio_cmd
,
6352 "ip pim drpriority (1-4294967295)",
6355 "Set the Designated Router Election Priority\n"
6356 "Value of the new DR Priority\n")
6358 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6360 struct pim_interface
*pim_ifp
= ifp
->info
;
6361 uint32_t old_dr_prio
;
6364 vty_out(vty
, "Please enable PIM on interface, first\n");
6365 return CMD_WARNING_CONFIG_FAILED
;
6368 old_dr_prio
= pim_ifp
->pim_dr_priority
;
6370 pim_ifp
->pim_dr_priority
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
6372 if (old_dr_prio
!= pim_ifp
->pim_dr_priority
) {
6373 if (pim_if_dr_election(ifp
))
6374 pim_hello_restart_now(ifp
);
6380 DEFUN (interface_no_ip_pim_drprio
,
6381 interface_no_ip_pim_drprio_cmd
,
6382 "no ip pim drpriority [(1-4294967295)]",
6386 "Revert the Designated Router Priority to default\n"
6387 "Old Value of the Priority\n")
6389 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6390 struct pim_interface
*pim_ifp
= ifp
->info
;
6393 vty_out(vty
, "Pim not enabled on this interface\n");
6394 return CMD_WARNING_CONFIG_FAILED
;
6397 if (pim_ifp
->pim_dr_priority
!= PIM_DEFAULT_DR_PRIORITY
) {
6398 pim_ifp
->pim_dr_priority
= PIM_DEFAULT_DR_PRIORITY
;
6399 if (pim_if_dr_election(ifp
))
6400 pim_hello_restart_now(ifp
);
6406 static int pim_cmd_interface_add(struct interface
*ifp
)
6408 struct pim_interface
*pim_ifp
= ifp
->info
;
6411 pim_ifp
= pim_if_new(ifp
, 0 /* igmp=false */, 1 /* pim=true */);
6416 PIM_IF_DO_PIM(pim_ifp
->options
);
6419 pim_if_addr_add_all(ifp
);
6420 pim_if_membership_refresh(ifp
);
6424 DEFUN_HIDDEN (interface_ip_pim_ssm
,
6425 interface_ip_pim_ssm_cmd
,
6431 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6433 if (!pim_cmd_interface_add(ifp
)) {
6434 vty_out(vty
, "Could not enable PIM SM on interface\n");
6435 return CMD_WARNING_CONFIG_FAILED
;
6439 "WARN: Enabled PIM SM on interface; configure PIM SSM "
6440 "range if needed\n");
6444 DEFUN (interface_ip_pim_sm
,
6445 interface_ip_pim_sm_cmd
,
6451 struct pim_interface
*pim_ifp
;
6453 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6454 if (!pim_cmd_interface_add(ifp
)) {
6455 vty_out(vty
, "Could not enable PIM SM on interface\n");
6456 return CMD_WARNING_CONFIG_FAILED
;
6459 pim_ifp
= ifp
->info
;
6461 pim_if_create_pimreg(pim_ifp
->pim
);
6466 static int pim_cmd_interface_delete(struct interface
*ifp
)
6468 struct pim_interface
*pim_ifp
= ifp
->info
;
6473 PIM_IF_DONT_PIM(pim_ifp
->options
);
6475 pim_if_membership_clear(ifp
);
6478 pim_sock_delete() removes all neighbors from
6479 pim_ifp->pim_neighbor_list.
6481 pim_sock_delete(ifp
, "pim unconfigured on interface");
6483 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
6484 pim_if_addr_del_all(ifp
);
6491 DEFUN_HIDDEN (interface_no_ip_pim_ssm
,
6492 interface_no_ip_pim_ssm_cmd
,
6499 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6500 if (!pim_cmd_interface_delete(ifp
)) {
6501 vty_out(vty
, "Unable to delete interface information\n");
6502 return CMD_WARNING_CONFIG_FAILED
;
6508 DEFUN (interface_no_ip_pim_sm
,
6509 interface_no_ip_pim_sm_cmd
,
6516 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6517 if (!pim_cmd_interface_delete(ifp
)) {
6518 vty_out(vty
, "Unable to delete interface information\n");
6519 return CMD_WARNING_CONFIG_FAILED
;
6526 DEFUN(interface_ip_pim_boundary_oil
,
6527 interface_ip_pim_boundary_oil_cmd
,
6528 "ip multicast boundary oil WORD",
6530 "Generic multicast configuration options\n"
6531 "Define multicast boundary\n"
6532 "Filter OIL by group using prefix list\n"
6533 "Prefix list to filter OIL with\n")
6535 VTY_DECLVAR_CONTEXT(interface
, iif
);
6536 struct pim_interface
*pim_ifp
;
6539 argv_find(argv
, argc
, "WORD", &idx
);
6541 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6543 if (pim_ifp
->boundary_oil_plist
)
6544 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
6546 pim_ifp
->boundary_oil_plist
=
6547 XSTRDUP(MTYPE_PIM_INTERFACE
, argv
[idx
]->arg
);
6549 /* Interface will be pruned from OIL on next Join */
6553 DEFUN(interface_no_ip_pim_boundary_oil
,
6554 interface_no_ip_pim_boundary_oil_cmd
,
6555 "no ip multicast boundary oil [WORD]",
6558 "Generic multicast configuration options\n"
6559 "Define multicast boundary\n"
6560 "Filter OIL by group using prefix list\n"
6561 "Prefix list to filter OIL with\n")
6563 VTY_DECLVAR_CONTEXT(interface
, iif
);
6564 struct pim_interface
*pim_ifp
;
6567 argv_find(argv
, argc
, "WORD", &idx
);
6569 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6571 if (pim_ifp
->boundary_oil_plist
)
6572 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
6577 DEFUN (interface_ip_mroute
,
6578 interface_ip_mroute_cmd
,
6579 "ip mroute INTERFACE A.B.C.D",
6581 "Add multicast route\n"
6582 "Outgoing interface name\n"
6585 VTY_DECLVAR_CONTEXT(interface
, iif
);
6586 struct pim_interface
*pim_ifp
;
6587 struct pim_instance
*pim
;
6588 int idx_interface
= 2;
6590 struct interface
*oif
;
6591 const char *oifname
;
6592 const char *grp_str
;
6593 struct in_addr grp_addr
;
6594 struct in_addr src_addr
;
6597 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6600 oifname
= argv
[idx_interface
]->arg
;
6601 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6603 vty_out(vty
, "No such interface name %s\n", oifname
);
6607 grp_str
= argv
[idx_ipv4
]->arg
;
6608 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6610 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6611 errno
, safe_strerror(errno
));
6615 src_addr
.s_addr
= INADDR_ANY
;
6617 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6618 vty_out(vty
, "Failed to add route\n");
6625 DEFUN (interface_ip_mroute_source
,
6626 interface_ip_mroute_source_cmd
,
6627 "ip mroute INTERFACE A.B.C.D A.B.C.D",
6629 "Add multicast route\n"
6630 "Outgoing interface name\n"
6634 VTY_DECLVAR_CONTEXT(interface
, iif
);
6635 struct pim_interface
*pim_ifp
;
6636 struct pim_instance
*pim
;
6637 int idx_interface
= 2;
6640 struct interface
*oif
;
6641 const char *oifname
;
6642 const char *grp_str
;
6643 struct in_addr grp_addr
;
6644 const char *src_str
;
6645 struct in_addr src_addr
;
6648 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6651 oifname
= argv
[idx_interface
]->arg
;
6652 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6654 vty_out(vty
, "No such interface name %s\n", oifname
);
6658 grp_str
= argv
[idx_ipv4
]->arg
;
6659 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6661 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6662 errno
, safe_strerror(errno
));
6666 src_str
= argv
[idx_ipv4_2
]->arg
;
6667 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
6669 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
6670 errno
, safe_strerror(errno
));
6674 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6675 vty_out(vty
, "Failed to add route\n");
6682 DEFUN (interface_no_ip_mroute
,
6683 interface_no_ip_mroute_cmd
,
6684 "no ip mroute INTERFACE A.B.C.D",
6687 "Add multicast route\n"
6688 "Outgoing interface name\n"
6691 VTY_DECLVAR_CONTEXT(interface
, iif
);
6692 struct pim_interface
*pim_ifp
;
6693 struct pim_instance
*pim
;
6694 int idx_interface
= 3;
6696 struct interface
*oif
;
6697 const char *oifname
;
6698 const char *grp_str
;
6699 struct in_addr grp_addr
;
6700 struct in_addr src_addr
;
6703 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6706 oifname
= argv
[idx_interface
]->arg
;
6707 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6709 vty_out(vty
, "No such interface name %s\n", oifname
);
6713 grp_str
= argv
[idx_ipv4
]->arg
;
6714 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6716 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6717 errno
, safe_strerror(errno
));
6721 src_addr
.s_addr
= INADDR_ANY
;
6723 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6724 vty_out(vty
, "Failed to remove route\n");
6731 DEFUN (interface_no_ip_mroute_source
,
6732 interface_no_ip_mroute_source_cmd
,
6733 "no ip mroute INTERFACE A.B.C.D A.B.C.D",
6736 "Add multicast route\n"
6737 "Outgoing interface name\n"
6741 VTY_DECLVAR_CONTEXT(interface
, iif
);
6742 struct pim_interface
*pim_ifp
;
6743 struct pim_instance
*pim
;
6744 int idx_interface
= 3;
6747 struct interface
*oif
;
6748 const char *oifname
;
6749 const char *grp_str
;
6750 struct in_addr grp_addr
;
6751 const char *src_str
;
6752 struct in_addr src_addr
;
6755 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6758 oifname
= argv
[idx_interface
]->arg
;
6759 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6761 vty_out(vty
, "No such interface name %s\n", oifname
);
6765 grp_str
= argv
[idx_ipv4
]->arg
;
6766 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6768 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6769 errno
, safe_strerror(errno
));
6773 src_str
= argv
[idx_ipv4_2
]->arg
;
6774 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
6776 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
6777 errno
, safe_strerror(errno
));
6781 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6782 vty_out(vty
, "Failed to remove route\n");
6789 DEFUN (interface_ip_pim_hello
,
6790 interface_ip_pim_hello_cmd
,
6791 "ip pim hello (1-180) [(1-180)]",
6795 IFACE_PIM_HELLO_TIME_STR
6796 IFACE_PIM_HELLO_HOLD_STR
)
6798 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6801 struct pim_interface
*pim_ifp
= ifp
->info
;
6804 if (!pim_cmd_interface_add(ifp
)) {
6805 vty_out(vty
, "Could not enable PIM SM on interface\n");
6806 return CMD_WARNING_CONFIG_FAILED
;
6810 pim_ifp
= ifp
->info
;
6811 pim_ifp
->pim_hello_period
= strtol(argv
[idx_time
]->arg
, NULL
, 10);
6813 if (argc
== idx_hold
+ 1)
6814 pim_ifp
->pim_default_holdtime
=
6815 strtol(argv
[idx_hold
]->arg
, NULL
, 10);
6820 DEFUN (interface_no_ip_pim_hello
,
6821 interface_no_ip_pim_hello_cmd
,
6822 "no ip pim hello [(1-180) (1-180)]",
6827 IFACE_PIM_HELLO_TIME_STR
6828 IFACE_PIM_HELLO_HOLD_STR
)
6830 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6831 struct pim_interface
*pim_ifp
= ifp
->info
;
6834 vty_out(vty
, "Pim not enabled on this interface\n");
6835 return CMD_WARNING_CONFIG_FAILED
;
6838 pim_ifp
->pim_hello_period
= PIM_DEFAULT_HELLO_PERIOD
;
6839 pim_ifp
->pim_default_holdtime
= -1;
6850 PIM_DO_DEBUG_IGMP_EVENTS
;
6851 PIM_DO_DEBUG_IGMP_PACKETS
;
6852 PIM_DO_DEBUG_IGMP_TRACE
;
6856 DEFUN (no_debug_igmp
,
6863 PIM_DONT_DEBUG_IGMP_EVENTS
;
6864 PIM_DONT_DEBUG_IGMP_PACKETS
;
6865 PIM_DONT_DEBUG_IGMP_TRACE
;
6870 DEFUN (debug_igmp_events
,
6871 debug_igmp_events_cmd
,
6872 "debug igmp events",
6875 DEBUG_IGMP_EVENTS_STR
)
6877 PIM_DO_DEBUG_IGMP_EVENTS
;
6881 DEFUN (no_debug_igmp_events
,
6882 no_debug_igmp_events_cmd
,
6883 "no debug igmp events",
6887 DEBUG_IGMP_EVENTS_STR
)
6889 PIM_DONT_DEBUG_IGMP_EVENTS
;
6894 DEFUN (debug_igmp_packets
,
6895 debug_igmp_packets_cmd
,
6896 "debug igmp packets",
6899 DEBUG_IGMP_PACKETS_STR
)
6901 PIM_DO_DEBUG_IGMP_PACKETS
;
6905 DEFUN (no_debug_igmp_packets
,
6906 no_debug_igmp_packets_cmd
,
6907 "no debug igmp packets",
6911 DEBUG_IGMP_PACKETS_STR
)
6913 PIM_DONT_DEBUG_IGMP_PACKETS
;
6918 DEFUN (debug_igmp_trace
,
6919 debug_igmp_trace_cmd
,
6923 DEBUG_IGMP_TRACE_STR
)
6925 PIM_DO_DEBUG_IGMP_TRACE
;
6929 DEFUN (no_debug_igmp_trace
,
6930 no_debug_igmp_trace_cmd
,
6931 "no debug igmp trace",
6935 DEBUG_IGMP_TRACE_STR
)
6937 PIM_DONT_DEBUG_IGMP_TRACE
;
6942 DEFUN (debug_mroute
,
6948 PIM_DO_DEBUG_MROUTE
;
6952 DEFUN (debug_mroute_detail
,
6953 debug_mroute_detail_cmd
,
6954 "debug mroute detail",
6959 PIM_DO_DEBUG_MROUTE_DETAIL
;
6963 DEFUN (no_debug_mroute
,
6964 no_debug_mroute_cmd
,
6970 PIM_DONT_DEBUG_MROUTE
;
6974 DEFUN (no_debug_mroute_detail
,
6975 no_debug_mroute_detail_cmd
,
6976 "no debug mroute detail",
6982 PIM_DONT_DEBUG_MROUTE_DETAIL
;
6986 DEFUN (debug_static
,
6992 PIM_DO_DEBUG_STATIC
;
6996 DEFUN (no_debug_static
,
6997 no_debug_static_cmd
,
7003 PIM_DONT_DEBUG_STATIC
;
7014 PIM_DO_DEBUG_PIM_EVENTS
;
7015 PIM_DO_DEBUG_PIM_PACKETS
;
7016 PIM_DO_DEBUG_PIM_TRACE
;
7017 PIM_DO_DEBUG_MSDP_EVENTS
;
7018 PIM_DO_DEBUG_MSDP_PACKETS
;
7022 DEFUN (no_debug_pim
,
7029 PIM_DONT_DEBUG_PIM_EVENTS
;
7030 PIM_DONT_DEBUG_PIM_PACKETS
;
7031 PIM_DONT_DEBUG_PIM_TRACE
;
7032 PIM_DONT_DEBUG_MSDP_EVENTS
;
7033 PIM_DONT_DEBUG_MSDP_PACKETS
;
7035 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
7036 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
7041 DEFUN (debug_pim_nht
,
7046 "Nexthop Tracking\n")
7048 PIM_DO_DEBUG_PIM_NHT
;
7052 DEFUN (no_debug_pim_nht
,
7053 no_debug_pim_nht_cmd
,
7058 "Nexthop Tracking\n")
7060 PIM_DONT_DEBUG_PIM_NHT
;
7064 DEFUN (debug_pim_nht_rp
,
7065 debug_pim_nht_rp_cmd
,
7069 "Nexthop Tracking\n"
7070 "RP Nexthop Tracking\n")
7072 PIM_DO_DEBUG_PIM_NHT_RP
;
7076 DEFUN (no_debug_pim_nht_rp
,
7077 no_debug_pim_nht_rp_cmd
,
7078 "no debug pim nht rp",
7082 "Nexthop Tracking\n"
7083 "RP Nexthop Tracking\n")
7085 PIM_DONT_DEBUG_PIM_NHT_RP
;
7089 DEFUN (debug_pim_events
,
7090 debug_pim_events_cmd
,
7094 DEBUG_PIM_EVENTS_STR
)
7096 PIM_DO_DEBUG_PIM_EVENTS
;
7100 DEFUN (no_debug_pim_events
,
7101 no_debug_pim_events_cmd
,
7102 "no debug pim events",
7106 DEBUG_PIM_EVENTS_STR
)
7108 PIM_DONT_DEBUG_PIM_EVENTS
;
7112 DEFUN (debug_pim_packets
,
7113 debug_pim_packets_cmd
,
7114 "debug pim packets [<hello|joins|register>]",
7117 DEBUG_PIM_PACKETS_STR
7118 DEBUG_PIM_HELLO_PACKETS_STR
7119 DEBUG_PIM_J_P_PACKETS_STR
7120 DEBUG_PIM_PIM_REG_PACKETS_STR
)
7123 if (argv_find(argv
, argc
, "hello", &idx
)) {
7124 PIM_DO_DEBUG_PIM_HELLO
;
7125 vty_out(vty
, "PIM Hello debugging is on\n");
7126 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
7127 PIM_DO_DEBUG_PIM_J_P
;
7128 vty_out(vty
, "PIM Join/Prune debugging is on\n");
7129 } else if (argv_find(argv
, argc
, "register", &idx
)) {
7130 PIM_DO_DEBUG_PIM_REG
;
7131 vty_out(vty
, "PIM Register debugging is on\n");
7133 PIM_DO_DEBUG_PIM_PACKETS
;
7134 vty_out(vty
, "PIM Packet debugging is on \n");
7139 DEFUN (no_debug_pim_packets
,
7140 no_debug_pim_packets_cmd
,
7141 "no debug pim packets [<hello|joins|register>]",
7145 DEBUG_PIM_PACKETS_STR
7146 DEBUG_PIM_HELLO_PACKETS_STR
7147 DEBUG_PIM_J_P_PACKETS_STR
7148 DEBUG_PIM_PIM_REG_PACKETS_STR
)
7151 if (argv_find(argv
, argc
, "hello", &idx
)) {
7152 PIM_DONT_DEBUG_PIM_HELLO
;
7153 vty_out(vty
, "PIM Hello debugging is off \n");
7154 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
7155 PIM_DONT_DEBUG_PIM_J_P
;
7156 vty_out(vty
, "PIM Join/Prune debugging is off \n");
7157 } else if (argv_find(argv
, argc
, "register", &idx
)) {
7158 PIM_DONT_DEBUG_PIM_REG
;
7159 vty_out(vty
, "PIM Register debugging is off\n");
7161 PIM_DONT_DEBUG_PIM_PACKETS
;
7167 DEFUN (debug_pim_packetdump_send
,
7168 debug_pim_packetdump_send_cmd
,
7169 "debug pim packet-dump send",
7172 DEBUG_PIM_PACKETDUMP_STR
7173 DEBUG_PIM_PACKETDUMP_SEND_STR
)
7175 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND
;
7179 DEFUN (no_debug_pim_packetdump_send
,
7180 no_debug_pim_packetdump_send_cmd
,
7181 "no debug pim packet-dump send",
7185 DEBUG_PIM_PACKETDUMP_STR
7186 DEBUG_PIM_PACKETDUMP_SEND_STR
)
7188 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
7192 DEFUN (debug_pim_packetdump_recv
,
7193 debug_pim_packetdump_recv_cmd
,
7194 "debug pim packet-dump receive",
7197 DEBUG_PIM_PACKETDUMP_STR
7198 DEBUG_PIM_PACKETDUMP_RECV_STR
)
7200 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV
;
7204 DEFUN (no_debug_pim_packetdump_recv
,
7205 no_debug_pim_packetdump_recv_cmd
,
7206 "no debug pim packet-dump receive",
7210 DEBUG_PIM_PACKETDUMP_STR
7211 DEBUG_PIM_PACKETDUMP_RECV_STR
)
7213 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
7217 DEFUN (debug_pim_trace
,
7218 debug_pim_trace_cmd
,
7222 DEBUG_PIM_TRACE_STR
)
7224 PIM_DO_DEBUG_PIM_TRACE
;
7228 DEFUN (debug_pim_trace_detail
,
7229 debug_pim_trace_detail_cmd
,
7230 "debug pim trace detail",
7234 "Detailed Information\n")
7236 PIM_DO_DEBUG_PIM_TRACE_DETAIL
;
7240 DEFUN (no_debug_pim_trace
,
7241 no_debug_pim_trace_cmd
,
7242 "no debug pim trace",
7246 DEBUG_PIM_TRACE_STR
)
7248 PIM_DONT_DEBUG_PIM_TRACE
;
7252 DEFUN (no_debug_pim_trace_detail
,
7253 no_debug_pim_trace_detail_cmd
,
7254 "no debug pim trace detail",
7259 "Detailed Information\n")
7261 PIM_DONT_DEBUG_PIM_TRACE_DETAIL
;
7265 DEFUN (debug_ssmpingd
,
7271 PIM_DO_DEBUG_SSMPINGD
;
7275 DEFUN (no_debug_ssmpingd
,
7276 no_debug_ssmpingd_cmd
,
7277 "no debug ssmpingd",
7282 PIM_DONT_DEBUG_SSMPINGD
;
7286 DEFUN (debug_pim_zebra
,
7287 debug_pim_zebra_cmd
,
7291 DEBUG_PIM_ZEBRA_STR
)
7297 DEFUN (no_debug_pim_zebra
,
7298 no_debug_pim_zebra_cmd
,
7299 "no debug pim zebra",
7303 DEBUG_PIM_ZEBRA_STR
)
7305 PIM_DONT_DEBUG_ZEBRA
;
7315 PIM_DO_DEBUG_MSDP_EVENTS
;
7316 PIM_DO_DEBUG_MSDP_PACKETS
;
7320 DEFUN (no_debug_msdp
,
7327 PIM_DONT_DEBUG_MSDP_EVENTS
;
7328 PIM_DONT_DEBUG_MSDP_PACKETS
;
7332 #if CONFDATE > 20190402
7333 CPP_NOTICE("bgpd: time to remove undebug commands")
7335 ALIAS_HIDDEN (no_debug_msdp
,
7338 UNDEBUG_STR DEBUG_MSDP_STR
)
7340 DEFUN (debug_msdp_events
,
7341 debug_msdp_events_cmd
,
7342 "debug msdp events",
7345 DEBUG_MSDP_EVENTS_STR
)
7347 PIM_DO_DEBUG_MSDP_EVENTS
;
7351 DEFUN (no_debug_msdp_events
,
7352 no_debug_msdp_events_cmd
,
7353 "no debug msdp events",
7357 DEBUG_MSDP_EVENTS_STR
)
7359 PIM_DONT_DEBUG_MSDP_EVENTS
;
7363 #if CONFDATE > 20190402
7364 CPP_NOTICE("bgpd: time to remove undebug commands")
7366 ALIAS_HIDDEN (no_debug_msdp_events
,
7367 undebug_msdp_events_cmd
,
7368 "undebug msdp events",
7371 DEBUG_MSDP_EVENTS_STR
)
7373 DEFUN (debug_msdp_packets
,
7374 debug_msdp_packets_cmd
,
7375 "debug msdp packets",
7378 DEBUG_MSDP_PACKETS_STR
)
7380 PIM_DO_DEBUG_MSDP_PACKETS
;
7384 DEFUN (no_debug_msdp_packets
,
7385 no_debug_msdp_packets_cmd
,
7386 "no debug msdp packets",
7390 DEBUG_MSDP_PACKETS_STR
)
7392 PIM_DONT_DEBUG_MSDP_PACKETS
;
7396 #if CONFDATE > 20190402
7397 CPP_NOTICE("bgpd: time to remove undebug commands")
7399 ALIAS_HIDDEN (no_debug_msdp_packets
,
7400 undebug_msdp_packets_cmd
,
7401 "undebug msdp packets",
7404 DEBUG_MSDP_PACKETS_STR
)
7406 DEFUN (debug_mtrace
,
7412 PIM_DO_DEBUG_MTRACE
;
7416 DEFUN (no_debug_mtrace
,
7417 no_debug_mtrace_cmd
,
7423 PIM_DONT_DEBUG_MTRACE
;
7427 DEFUN_NOSH (show_debugging_pim
,
7428 show_debugging_pim_cmd
,
7429 "show debugging [pim]",
7434 vty_out(vty
, "PIM debugging status\n");
7436 pim_debug_config_write(vty
);
7441 static int interface_pim_use_src_cmd_worker(struct vty
*vty
, const char *source
)
7444 struct in_addr source_addr
;
7445 int ret
= CMD_SUCCESS
;
7446 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7448 result
= inet_pton(AF_INET
, source
, &source_addr
);
7450 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", source
,
7451 errno
, safe_strerror(errno
));
7452 return CMD_WARNING_CONFIG_FAILED
;
7455 result
= pim_update_source_set(ifp
, source_addr
);
7459 case PIM_IFACE_NOT_FOUND
:
7460 ret
= CMD_WARNING_CONFIG_FAILED
;
7461 vty_out(vty
, "Pim not enabled on this interface\n");
7463 case PIM_UPDATE_SOURCE_DUP
:
7465 vty_out(vty
, "%% Source already set to %s\n", source
);
7468 ret
= CMD_WARNING_CONFIG_FAILED
;
7469 vty_out(vty
, "%% Source set failed\n");
7475 DEFUN (interface_pim_use_source
,
7476 interface_pim_use_source_cmd
,
7477 "ip pim use-source A.B.C.D",
7479 "pim multicast routing\n"
7480 "Configure primary IP address\n"
7481 "source ip address\n")
7483 return interface_pim_use_src_cmd_worker(vty
, argv
[3]->arg
);
7486 DEFUN (interface_no_pim_use_source
,
7487 interface_no_pim_use_source_cmd
,
7488 "no ip pim use-source [A.B.C.D]",
7491 "pim multicast routing\n"
7492 "Delete source IP address\n"
7493 "source ip address\n")
7495 return interface_pim_use_src_cmd_worker(vty
, "0.0.0.0");
7503 "Enables BFD support\n")
7505 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7506 struct pim_interface
*pim_ifp
= ifp
->info
;
7507 struct bfd_info
*bfd_info
= NULL
;
7510 if (!pim_cmd_interface_add(ifp
)) {
7511 vty_out(vty
, "Could not enable PIM SM on interface\n");
7515 pim_ifp
= ifp
->info
;
7517 bfd_info
= pim_ifp
->bfd_info
;
7519 if (!bfd_info
|| !CHECK_FLAG(bfd_info
->flags
, BFD_FLAG_PARAM_CFG
))
7520 pim_bfd_if_param_set(ifp
, BFD_DEF_MIN_RX
, BFD_DEF_MIN_TX
,
7521 BFD_DEF_DETECT_MULT
, 1);
7526 DEFUN (no_ip_pim_bfd
,
7532 "Disables BFD support\n")
7534 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7535 struct pim_interface
*pim_ifp
= ifp
->info
;
7538 vty_out(vty
, "Pim not enabled on this interface\n");
7542 if (pim_ifp
->bfd_info
) {
7543 pim_bfd_reg_dereg_all_nbr(ifp
, ZEBRA_BFD_DEST_DEREGISTER
);
7544 bfd_info_free(&(pim_ifp
->bfd_info
));
7550 DEFUN (ip_pim_bfd_param
,
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);
7588 ALIAS(no_ip_pim_bfd
, no_ip_pim_bfd_param_cmd
,
7589 "no ip pim bfd (2-255) (50-60000) (50-60000)", NO_STR IP_STR PIM_STR
7590 "Enables BFD support\n"
7591 "Detect Multiplier\n"
7592 "Required min receive interval\n"
7593 "Desired min transmit interval\n")
7595 static int ip_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
7596 const char *peer
, const char *local
)
7598 enum pim_msdp_err result
;
7599 struct in_addr peer_addr
;
7600 struct in_addr local_addr
;
7601 int ret
= CMD_SUCCESS
;
7603 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
7605 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
7606 errno
, safe_strerror(errno
));
7607 return CMD_WARNING_CONFIG_FAILED
;
7610 result
= inet_pton(AF_INET
, local
, &local_addr
);
7612 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", local
,
7613 errno
, safe_strerror(errno
));
7614 return CMD_WARNING_CONFIG_FAILED
;
7617 result
= pim_msdp_peer_add(pim
, peer_addr
, local_addr
, "default",
7620 case PIM_MSDP_ERR_NONE
:
7622 case PIM_MSDP_ERR_OOM
:
7623 ret
= CMD_WARNING_CONFIG_FAILED
;
7624 vty_out(vty
, "%% Out of memory\n");
7626 case PIM_MSDP_ERR_PEER_EXISTS
:
7628 vty_out(vty
, "%% Peer exists\n");
7630 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
7631 ret
= CMD_WARNING_CONFIG_FAILED
;
7632 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
7635 ret
= CMD_WARNING_CONFIG_FAILED
;
7636 vty_out(vty
, "%% peer add failed\n");
7642 DEFUN_HIDDEN (ip_msdp_peer
,
7644 "ip msdp peer A.B.C.D source A.B.C.D",
7647 "Configure MSDP peer\n"
7649 "Source address for TCP connection\n"
7650 "local ip address\n")
7652 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7653 return ip_msdp_peer_cmd_worker(pim
, vty
, argv
[3]->arg
, argv
[5]->arg
);
7656 static int ip_no_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
7659 enum pim_msdp_err result
;
7660 struct in_addr peer_addr
;
7662 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
7664 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
7665 errno
, safe_strerror(errno
));
7666 return CMD_WARNING_CONFIG_FAILED
;
7669 result
= pim_msdp_peer_del(pim
, peer_addr
);
7671 case PIM_MSDP_ERR_NONE
:
7673 case PIM_MSDP_ERR_NO_PEER
:
7674 vty_out(vty
, "%% Peer does not exist\n");
7677 vty_out(vty
, "%% peer del failed\n");
7680 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7683 DEFUN_HIDDEN (no_ip_msdp_peer
,
7684 no_ip_msdp_peer_cmd
,
7685 "no ip msdp peer A.B.C.D",
7689 "Delete MSDP peer\n"
7690 "peer ip address\n")
7692 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7693 return ip_no_msdp_peer_cmd_worker(pim
, vty
, argv
[4]->arg
);
7696 static int ip_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
7697 struct vty
*vty
, const char *mg
,
7700 enum pim_msdp_err result
;
7701 struct in_addr mbr_ip
;
7702 int ret
= CMD_SUCCESS
;
7704 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
7706 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
7707 errno
, safe_strerror(errno
));
7708 return CMD_WARNING_CONFIG_FAILED
;
7711 result
= pim_msdp_mg_mbr_add(pim
, mg
, mbr_ip
);
7713 case PIM_MSDP_ERR_NONE
:
7715 case PIM_MSDP_ERR_OOM
:
7716 ret
= CMD_WARNING_CONFIG_FAILED
;
7717 vty_out(vty
, "%% Out of memory\n");
7719 case PIM_MSDP_ERR_MG_MBR_EXISTS
:
7721 vty_out(vty
, "%% mesh-group member exists\n");
7723 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
7724 ret
= CMD_WARNING_CONFIG_FAILED
;
7725 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
7728 ret
= CMD_WARNING_CONFIG_FAILED
;
7729 vty_out(vty
, "%% member add failed\n");
7735 DEFUN (ip_msdp_mesh_group_member
,
7736 ip_msdp_mesh_group_member_cmd
,
7737 "ip msdp mesh-group WORD member A.B.C.D",
7740 "Configure MSDP mesh-group\n"
7742 "mesh group member\n"
7743 "peer ip address\n")
7745 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7746 return ip_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[3]->arg
,
7750 static int ip_no_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
7755 enum pim_msdp_err result
;
7756 struct in_addr mbr_ip
;
7758 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
7760 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
7761 errno
, safe_strerror(errno
));
7762 return CMD_WARNING_CONFIG_FAILED
;
7765 result
= pim_msdp_mg_mbr_del(pim
, mg
, mbr_ip
);
7767 case PIM_MSDP_ERR_NONE
:
7769 case PIM_MSDP_ERR_NO_MG
:
7770 vty_out(vty
, "%% mesh-group does not exist\n");
7772 case PIM_MSDP_ERR_NO_MG_MBR
:
7773 vty_out(vty
, "%% mesh-group member does not exist\n");
7776 vty_out(vty
, "%% mesh-group member del failed\n");
7779 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7781 DEFUN (no_ip_msdp_mesh_group_member
,
7782 no_ip_msdp_mesh_group_member_cmd
,
7783 "no ip msdp mesh-group WORD member A.B.C.D",
7787 "Delete MSDP mesh-group member\n"
7789 "mesh group member\n"
7790 "peer ip address\n")
7792 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7793 return ip_no_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[4]->arg
,
7797 static int ip_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
7798 struct vty
*vty
, const char *mg
,
7801 enum pim_msdp_err result
;
7802 struct in_addr src_ip
;
7804 result
= inet_pton(AF_INET
, src
, &src_ip
);
7806 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", src
,
7807 errno
, safe_strerror(errno
));
7808 return CMD_WARNING_CONFIG_FAILED
;
7811 result
= pim_msdp_mg_src_add(pim
, mg
, src_ip
);
7813 case PIM_MSDP_ERR_NONE
:
7815 case PIM_MSDP_ERR_OOM
:
7816 vty_out(vty
, "%% Out of memory\n");
7818 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
7819 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
7822 vty_out(vty
, "%% source add failed\n");
7825 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7829 DEFUN (ip_msdp_mesh_group_source
,
7830 ip_msdp_mesh_group_source_cmd
,
7831 "ip msdp mesh-group WORD source A.B.C.D",
7834 "Configure MSDP mesh-group\n"
7836 "mesh group local address\n"
7837 "source ip address for the TCP connection\n")
7839 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7840 return ip_msdp_mesh_group_source_cmd_worker(pim
, vty
, argv
[3]->arg
,
7844 static int ip_no_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
7848 enum pim_msdp_err result
;
7850 result
= pim_msdp_mg_src_del(pim
, mg
);
7852 case PIM_MSDP_ERR_NONE
:
7854 case PIM_MSDP_ERR_NO_MG
:
7855 vty_out(vty
, "%% mesh-group does not exist\n");
7858 vty_out(vty
, "%% mesh-group source del failed\n");
7861 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7864 static int ip_no_msdp_mesh_group_cmd_worker(struct pim_instance
*pim
,
7865 struct vty
*vty
, const char *mg
)
7867 enum pim_msdp_err result
;
7869 result
= pim_msdp_mg_del(pim
, mg
);
7871 case PIM_MSDP_ERR_NONE
:
7873 case PIM_MSDP_ERR_NO_MG
:
7874 vty_out(vty
, "%% mesh-group does not exist\n");
7877 vty_out(vty
, "%% mesh-group source del failed\n");
7880 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7883 DEFUN (no_ip_msdp_mesh_group_source
,
7884 no_ip_msdp_mesh_group_source_cmd
,
7885 "no ip msdp mesh-group WORD source [A.B.C.D]",
7889 "Delete MSDP mesh-group source\n"
7891 "mesh group source\n"
7892 "mesh group local address\n")
7894 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7896 return ip_no_msdp_mesh_group_cmd_worker(pim
, vty
, argv
[6]->arg
);
7898 return ip_no_msdp_mesh_group_source_cmd_worker(pim
, vty
,
7902 static void print_empty_json_obj(struct vty
*vty
)
7905 json
= json_object_new_object();
7906 vty_out(vty
, "%s\n",
7907 json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
));
7908 json_object_free(json
);
7911 static void ip_msdp_show_mesh_group(struct pim_instance
*pim
, struct vty
*vty
,
7914 struct listnode
*mbrnode
;
7915 struct pim_msdp_mg_mbr
*mbr
;
7916 struct pim_msdp_mg
*mg
= pim
->msdp
.mg
;
7917 char mbr_str
[INET_ADDRSTRLEN
];
7918 char src_str
[INET_ADDRSTRLEN
];
7919 char state_str
[PIM_MSDP_STATE_STRLEN
];
7920 enum pim_msdp_peer_state state
;
7921 json_object
*json
= NULL
;
7922 json_object
*json_mg_row
= NULL
;
7923 json_object
*json_members
= NULL
;
7924 json_object
*json_row
= NULL
;
7928 print_empty_json_obj(vty
);
7932 pim_inet4_dump("<source?>", mg
->src_ip
, src_str
, sizeof(src_str
));
7934 json
= json_object_new_object();
7935 /* currently there is only one mesh group but we should still
7937 * it a dict with mg-name as key */
7938 json_mg_row
= json_object_new_object();
7939 json_object_string_add(json_mg_row
, "name",
7940 mg
->mesh_group_name
);
7941 json_object_string_add(json_mg_row
, "source", src_str
);
7943 vty_out(vty
, "Mesh group : %s\n", mg
->mesh_group_name
);
7944 vty_out(vty
, " Source : %s\n", src_str
);
7945 vty_out(vty
, " Member State\n");
7948 for (ALL_LIST_ELEMENTS_RO(mg
->mbr_list
, mbrnode
, mbr
)) {
7949 pim_inet4_dump("<mbr?>", mbr
->mbr_ip
, mbr_str
, sizeof(mbr_str
));
7951 state
= mbr
->mp
->state
;
7953 state
= PIM_MSDP_DISABLED
;
7955 pim_msdp_state_dump(state
, state_str
, sizeof(state_str
));
7957 json_row
= json_object_new_object();
7958 json_object_string_add(json_row
, "member", mbr_str
);
7959 json_object_string_add(json_row
, "state", state_str
);
7960 if (!json_members
) {
7961 json_members
= json_object_new_object();
7962 json_object_object_add(json_mg_row
, "members",
7965 json_object_object_add(json_members
, mbr_str
, json_row
);
7967 vty_out(vty
, " %-15s %11s\n", mbr_str
, state_str
);
7972 json_object_object_add(json
, mg
->mesh_group_name
, json_mg_row
);
7973 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
7974 json
, JSON_C_TO_STRING_PRETTY
));
7975 json_object_free(json
);
7979 DEFUN (show_ip_msdp_mesh_group
,
7980 show_ip_msdp_mesh_group_cmd
,
7981 "show ip msdp [vrf NAME] mesh-group [json]",
7986 "MSDP mesh-group information\n"
7989 uint8_t uj
= use_json(argc
, argv
);
7991 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
7996 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
8001 DEFUN (show_ip_msdp_mesh_group_vrf_all
,
8002 show_ip_msdp_mesh_group_vrf_all_cmd
,
8003 "show ip msdp vrf all mesh-group [json]",
8008 "MSDP mesh-group information\n"
8011 uint8_t uj
= use_json(argc
, argv
);
8017 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
8021 vty_out(vty
, " \"%s\": ", vrf
->name
);
8024 vty_out(vty
, "VRF: %s\n", vrf
->name
);
8025 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
8028 vty_out(vty
, "}\n");
8033 static void ip_msdp_show_peers(struct pim_instance
*pim
, struct vty
*vty
,
8036 struct listnode
*mpnode
;
8037 struct pim_msdp_peer
*mp
;
8038 char peer_str
[INET_ADDRSTRLEN
];
8039 char local_str
[INET_ADDRSTRLEN
];
8040 char state_str
[PIM_MSDP_STATE_STRLEN
];
8041 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
8043 json_object
*json
= NULL
;
8044 json_object
*json_row
= NULL
;
8048 json
= json_object_new_object();
8051 "Peer Local State Uptime SaCnt\n");
8054 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
8055 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
8056 now
= pim_time_monotonic_sec();
8057 pim_time_uptime(timebuf
, sizeof(timebuf
),
8060 strcpy(timebuf
, "-");
8062 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
8063 pim_inet4_dump("<local?>", mp
->local
, local_str
,
8065 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
8067 json_row
= json_object_new_object();
8068 json_object_string_add(json_row
, "peer", peer_str
);
8069 json_object_string_add(json_row
, "local", local_str
);
8070 json_object_string_add(json_row
, "state", state_str
);
8071 json_object_string_add(json_row
, "upTime", timebuf
);
8072 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
8073 json_object_object_add(json
, peer_str
, json_row
);
8075 vty_out(vty
, "%-15s %15s %11s %8s %6d\n", peer_str
,
8076 local_str
, state_str
, timebuf
, mp
->sa_cnt
);
8081 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8082 json
, JSON_C_TO_STRING_PRETTY
));
8083 json_object_free(json
);
8087 static void ip_msdp_show_peers_detail(struct pim_instance
*pim
, struct vty
*vty
,
8088 const char *peer
, uint8_t uj
)
8090 struct listnode
*mpnode
;
8091 struct pim_msdp_peer
*mp
;
8092 char peer_str
[INET_ADDRSTRLEN
];
8093 char local_str
[INET_ADDRSTRLEN
];
8094 char state_str
[PIM_MSDP_STATE_STRLEN
];
8095 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
8096 char katimer
[PIM_MSDP_TIMER_STRLEN
];
8097 char crtimer
[PIM_MSDP_TIMER_STRLEN
];
8098 char holdtimer
[PIM_MSDP_TIMER_STRLEN
];
8100 json_object
*json
= NULL
;
8101 json_object
*json_row
= NULL
;
8104 json
= json_object_new_object();
8107 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
8108 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
8109 if (strcmp(peer
, "detail") && strcmp(peer
, peer_str
))
8112 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
8113 now
= pim_time_monotonic_sec();
8114 pim_time_uptime(timebuf
, sizeof(timebuf
),
8117 strcpy(timebuf
, "-");
8119 pim_inet4_dump("<local?>", mp
->local
, local_str
,
8121 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
8122 pim_time_timer_to_hhmmss(katimer
, sizeof(katimer
),
8124 pim_time_timer_to_hhmmss(crtimer
, sizeof(crtimer
),
8126 pim_time_timer_to_hhmmss(holdtimer
, sizeof(holdtimer
),
8130 json_row
= json_object_new_object();
8131 json_object_string_add(json_row
, "peer", peer_str
);
8132 json_object_string_add(json_row
, "local", local_str
);
8133 json_object_string_add(json_row
, "meshGroupName",
8134 mp
->mesh_group_name
);
8135 json_object_string_add(json_row
, "state", state_str
);
8136 json_object_string_add(json_row
, "upTime", timebuf
);
8137 json_object_string_add(json_row
, "keepAliveTimer",
8139 json_object_string_add(json_row
, "connRetryTimer",
8141 json_object_string_add(json_row
, "holdTimer",
8143 json_object_string_add(json_row
, "lastReset",
8145 json_object_int_add(json_row
, "connAttempts",
8147 json_object_int_add(json_row
, "establishedChanges",
8149 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
8150 json_object_int_add(json_row
, "kaSent", mp
->ka_tx_cnt
);
8151 json_object_int_add(json_row
, "kaRcvd", mp
->ka_rx_cnt
);
8152 json_object_int_add(json_row
, "saSent", mp
->sa_tx_cnt
);
8153 json_object_int_add(json_row
, "saRcvd", mp
->sa_rx_cnt
);
8154 json_object_object_add(json
, peer_str
, json_row
);
8156 vty_out(vty
, "Peer : %s\n", peer_str
);
8157 vty_out(vty
, " Local : %s\n", local_str
);
8158 vty_out(vty
, " Mesh Group : %s\n",
8159 mp
->mesh_group_name
);
8160 vty_out(vty
, " State : %s\n", state_str
);
8161 vty_out(vty
, " Uptime : %s\n", timebuf
);
8163 vty_out(vty
, " Keepalive Timer : %s\n", katimer
);
8164 vty_out(vty
, " Conn Retry Timer : %s\n", crtimer
);
8165 vty_out(vty
, " Hold Timer : %s\n", holdtimer
);
8166 vty_out(vty
, " Last Reset : %s\n",
8168 vty_out(vty
, " Conn Attempts : %d\n",
8170 vty_out(vty
, " Established Changes : %d\n",
8172 vty_out(vty
, " SA Count : %d\n",
8174 vty_out(vty
, " Statistics :\n");
8177 vty_out(vty
, " Keepalives : %10d %10d\n",
8178 mp
->ka_tx_cnt
, mp
->ka_rx_cnt
);
8179 vty_out(vty
, " SAs : %10d %10d\n",
8180 mp
->sa_tx_cnt
, mp
->sa_rx_cnt
);
8186 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8187 json
, JSON_C_TO_STRING_PRETTY
));
8188 json_object_free(json
);
8192 DEFUN (show_ip_msdp_peer_detail
,
8193 show_ip_msdp_peer_detail_cmd
,
8194 "show ip msdp [vrf NAME] peer [detail|A.B.C.D] [json]",
8199 "MSDP peer information\n"
8204 uint8_t uj
= use_json(argc
, argv
);
8206 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
8213 if (argv_find(argv
, argc
, "detail", &idx
))
8214 arg
= argv
[idx
]->text
;
8215 else if (argv_find(argv
, argc
, "A.B.C.D", &idx
))
8216 arg
= argv
[idx
]->arg
;
8219 ip_msdp_show_peers_detail(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
8221 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
8226 DEFUN (show_ip_msdp_peer_detail_vrf_all
,
8227 show_ip_msdp_peer_detail_vrf_all_cmd
,
8228 "show ip msdp vrf all peer [detail|A.B.C.D] [json]",
8233 "MSDP peer information\n"
8239 uint8_t uj
= use_json(argc
, argv
);
8245 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
8249 vty_out(vty
, " \"%s\": ", vrf
->name
);
8252 vty_out(vty
, "VRF: %s\n", vrf
->name
);
8253 if (argv_find(argv
, argc
, "detail", &idx
)
8254 || argv_find(argv
, argc
, "A.B.C.D", &idx
))
8255 ip_msdp_show_peers_detail(vrf
->info
, vty
,
8256 argv
[idx
]->arg
, uj
);
8258 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
8261 vty_out(vty
, "}\n");
8266 static void ip_msdp_show_sa(struct pim_instance
*pim
, struct vty
*vty
,
8269 struct listnode
*sanode
;
8270 struct pim_msdp_sa
*sa
;
8271 char src_str
[INET_ADDRSTRLEN
];
8272 char grp_str
[INET_ADDRSTRLEN
];
8273 char rp_str
[INET_ADDRSTRLEN
];
8274 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
8278 json_object
*json
= NULL
;
8279 json_object
*json_group
= NULL
;
8280 json_object
*json_row
= NULL
;
8283 json
= json_object_new_object();
8286 "Source Group RP Local SPT Uptime\n");
8289 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
8290 now
= pim_time_monotonic_sec();
8291 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
8292 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
8293 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
8294 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
8295 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
8297 strcpy(spt_str
, "yes");
8299 strcpy(spt_str
, "no");
8302 strcpy(rp_str
, "-");
8303 strcpy(spt_str
, "-");
8305 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
8306 strcpy(local_str
, "yes");
8308 strcpy(local_str
, "no");
8311 json_object_object_get_ex(json
, grp_str
, &json_group
);
8314 json_group
= json_object_new_object();
8315 json_object_object_add(json
, grp_str
,
8319 json_row
= json_object_new_object();
8320 json_object_string_add(json_row
, "source", src_str
);
8321 json_object_string_add(json_row
, "group", grp_str
);
8322 json_object_string_add(json_row
, "rp", rp_str
);
8323 json_object_string_add(json_row
, "local", local_str
);
8324 json_object_string_add(json_row
, "sptSetup", spt_str
);
8325 json_object_string_add(json_row
, "upTime", timebuf
);
8326 json_object_object_add(json_group
, src_str
, json_row
);
8328 vty_out(vty
, "%-15s %15s %15s %5c %3c %8s\n",
8329 src_str
, grp_str
, rp_str
, local_str
[0],
8330 spt_str
[0], timebuf
);
8335 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8336 json
, JSON_C_TO_STRING_PRETTY
));
8337 json_object_free(json
);
8341 static void ip_msdp_show_sa_entry_detail(struct pim_msdp_sa
*sa
,
8342 const char *src_str
,
8343 const char *grp_str
, struct vty
*vty
,
8344 uint8_t uj
, json_object
*json
)
8346 char rp_str
[INET_ADDRSTRLEN
];
8347 char peer_str
[INET_ADDRSTRLEN
];
8348 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
8351 char statetimer
[PIM_MSDP_TIMER_STRLEN
];
8353 json_object
*json_group
= NULL
;
8354 json_object
*json_row
= NULL
;
8356 now
= pim_time_monotonic_sec();
8357 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
8358 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
8359 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
8360 pim_inet4_dump("<peer?>", sa
->peer
, peer_str
, sizeof(peer_str
));
8362 strcpy(spt_str
, "yes");
8364 strcpy(spt_str
, "no");
8367 strcpy(rp_str
, "-");
8368 strcpy(peer_str
, "-");
8369 strcpy(spt_str
, "-");
8371 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
8372 strcpy(local_str
, "yes");
8374 strcpy(local_str
, "no");
8376 pim_time_timer_to_hhmmss(statetimer
, sizeof(statetimer
),
8377 sa
->sa_state_timer
);
8379 json_object_object_get_ex(json
, grp_str
, &json_group
);
8382 json_group
= json_object_new_object();
8383 json_object_object_add(json
, grp_str
, json_group
);
8386 json_row
= json_object_new_object();
8387 json_object_string_add(json_row
, "source", src_str
);
8388 json_object_string_add(json_row
, "group", grp_str
);
8389 json_object_string_add(json_row
, "rp", rp_str
);
8390 json_object_string_add(json_row
, "local", local_str
);
8391 json_object_string_add(json_row
, "sptSetup", spt_str
);
8392 json_object_string_add(json_row
, "upTime", timebuf
);
8393 json_object_string_add(json_row
, "stateTimer", statetimer
);
8394 json_object_object_add(json_group
, src_str
, json_row
);
8396 vty_out(vty
, "SA : %s\n", sa
->sg_str
);
8397 vty_out(vty
, " RP : %s\n", rp_str
);
8398 vty_out(vty
, " Peer : %s\n", peer_str
);
8399 vty_out(vty
, " Local : %s\n", local_str
);
8400 vty_out(vty
, " SPT Setup : %s\n", spt_str
);
8401 vty_out(vty
, " Uptime : %s\n", timebuf
);
8402 vty_out(vty
, " State Timer : %s\n", statetimer
);
8407 static void ip_msdp_show_sa_detail(struct pim_instance
*pim
, struct vty
*vty
,
8410 struct listnode
*sanode
;
8411 struct pim_msdp_sa
*sa
;
8412 char src_str
[INET_ADDRSTRLEN
];
8413 char grp_str
[INET_ADDRSTRLEN
];
8414 json_object
*json
= NULL
;
8417 json
= json_object_new_object();
8420 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
8421 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
8422 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
8423 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
, uj
,
8428 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8429 json
, JSON_C_TO_STRING_PRETTY
));
8430 json_object_free(json
);
8434 DEFUN (show_ip_msdp_sa_detail
,
8435 show_ip_msdp_sa_detail_cmd
,
8436 "show ip msdp [vrf NAME] sa detail [json]",
8441 "MSDP active-source information\n"
8445 uint8_t uj
= use_json(argc
, argv
);
8447 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
8452 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
8457 DEFUN (show_ip_msdp_sa_detail_vrf_all
,
8458 show_ip_msdp_sa_detail_vrf_all_cmd
,
8459 "show ip msdp vrf all sa detail [json]",
8464 "MSDP active-source information\n"
8468 uint8_t uj
= use_json(argc
, argv
);
8474 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
8478 vty_out(vty
, " \"%s\": ", vrf
->name
);
8481 vty_out(vty
, "VRF: %s\n", vrf
->name
);
8482 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
8485 vty_out(vty
, "}\n");
8490 static void ip_msdp_show_sa_addr(struct pim_instance
*pim
, struct vty
*vty
,
8491 const char *addr
, uint8_t uj
)
8493 struct listnode
*sanode
;
8494 struct pim_msdp_sa
*sa
;
8495 char src_str
[INET_ADDRSTRLEN
];
8496 char grp_str
[INET_ADDRSTRLEN
];
8497 json_object
*json
= NULL
;
8500 json
= json_object_new_object();
8503 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
8504 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
8505 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
8506 if (!strcmp(addr
, src_str
) || !strcmp(addr
, grp_str
)) {
8507 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
8513 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8514 json
, JSON_C_TO_STRING_PRETTY
));
8515 json_object_free(json
);
8519 static void ip_msdp_show_sa_sg(struct pim_instance
*pim
, struct vty
*vty
,
8520 const char *src
, const char *grp
, uint8_t uj
)
8522 struct listnode
*sanode
;
8523 struct pim_msdp_sa
*sa
;
8524 char src_str
[INET_ADDRSTRLEN
];
8525 char grp_str
[INET_ADDRSTRLEN
];
8526 json_object
*json
= NULL
;
8529 json
= json_object_new_object();
8532 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
8533 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
8534 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
8535 if (!strcmp(src
, src_str
) && !strcmp(grp
, grp_str
)) {
8536 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
8542 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8543 json
, JSON_C_TO_STRING_PRETTY
));
8544 json_object_free(json
);
8548 DEFUN (show_ip_msdp_sa_sg
,
8549 show_ip_msdp_sa_sg_cmd
,
8550 "show ip msdp [vrf NAME] sa [A.B.C.D [A.B.C.D]] [json]",
8555 "MSDP active-source information\n"
8556 "source or group ip\n"
8560 uint8_t uj
= use_json(argc
, argv
);
8564 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
8569 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
8571 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
8575 if (src_ip
&& grp_ip
)
8576 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
8578 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
8580 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
8585 DEFUN (show_ip_msdp_sa_sg_vrf_all
,
8586 show_ip_msdp_sa_sg_vrf_all_cmd
,
8587 "show ip msdp vrf all sa [A.B.C.D [A.B.C.D]] [json]",
8592 "MSDP active-source information\n"
8593 "source or group ip\n"
8597 uint8_t uj
= use_json(argc
, argv
);
8602 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
8604 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
8610 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
8614 vty_out(vty
, " \"%s\": ", vrf
->name
);
8617 vty_out(vty
, "VRF: %s\n", vrf
->name
);
8619 if (src_ip
&& grp_ip
)
8620 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
8622 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
8624 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
8627 vty_out(vty
, "}\n");
8633 void pim_cmd_init(void)
8635 install_node(&interface_node
,
8636 pim_interface_config_write
); /* INTERFACE_NODE */
8639 install_node(&debug_node
, pim_debug_config_write
);
8641 install_element(CONFIG_NODE
, &ip_multicast_routing_cmd
);
8642 install_element(CONFIG_NODE
, &no_ip_multicast_routing_cmd
);
8643 install_element(CONFIG_NODE
, &ip_pim_rp_cmd
);
8644 install_element(VRF_NODE
, &ip_pim_rp_cmd
);
8645 install_element(CONFIG_NODE
, &no_ip_pim_rp_cmd
);
8646 install_element(VRF_NODE
, &no_ip_pim_rp_cmd
);
8647 install_element(CONFIG_NODE
, &ip_pim_rp_prefix_list_cmd
);
8648 install_element(VRF_NODE
, &ip_pim_rp_prefix_list_cmd
);
8649 install_element(CONFIG_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
8650 install_element(VRF_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
8651 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
8652 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
8653 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
8654 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
8655 install_element(CONFIG_NODE
, &ip_pim_ssm_prefix_list_cmd
);
8656 install_element(VRF_NODE
, &ip_pim_ssm_prefix_list_cmd
);
8657 install_element(CONFIG_NODE
, &ip_pim_register_suppress_cmd
);
8658 install_element(VRF_NODE
, &ip_pim_register_suppress_cmd
);
8659 install_element(CONFIG_NODE
, &no_ip_pim_register_suppress_cmd
);
8660 install_element(VRF_NODE
, &no_ip_pim_register_suppress_cmd
);
8661 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
8662 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
8663 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
8664 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
8665 install_element(CONFIG_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
8666 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
8667 install_element(CONFIG_NODE
,
8668 &no_ip_pim_spt_switchover_infinity_plist_cmd
);
8669 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_plist_cmd
);
8670 install_element(CONFIG_NODE
, &ip_pim_joinprune_time_cmd
);
8671 install_element(VRF_NODE
, &ip_pim_joinprune_time_cmd
);
8672 install_element(CONFIG_NODE
, &no_ip_pim_joinprune_time_cmd
);
8673 install_element(VRF_NODE
, &no_ip_pim_joinprune_time_cmd
);
8674 install_element(CONFIG_NODE
, &ip_pim_keep_alive_cmd
);
8675 install_element(VRF_NODE
, &ip_pim_keep_alive_cmd
);
8676 install_element(CONFIG_NODE
, &ip_pim_rp_keep_alive_cmd
);
8677 install_element(VRF_NODE
, &ip_pim_rp_keep_alive_cmd
);
8678 install_element(CONFIG_NODE
, &no_ip_pim_keep_alive_cmd
);
8679 install_element(VRF_NODE
, &no_ip_pim_keep_alive_cmd
);
8680 install_element(CONFIG_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
8681 install_element(VRF_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
8682 install_element(CONFIG_NODE
, &ip_pim_packets_cmd
);
8683 install_element(VRF_NODE
, &ip_pim_packets_cmd
);
8684 install_element(CONFIG_NODE
, &no_ip_pim_packets_cmd
);
8685 install_element(VRF_NODE
, &no_ip_pim_packets_cmd
);
8686 install_element(CONFIG_NODE
, &ip_pim_v6_secondary_cmd
);
8687 install_element(VRF_NODE
, &ip_pim_v6_secondary_cmd
);
8688 install_element(CONFIG_NODE
, &no_ip_pim_v6_secondary_cmd
);
8689 install_element(VRF_NODE
, &no_ip_pim_v6_secondary_cmd
);
8690 install_element(CONFIG_NODE
, &ip_ssmpingd_cmd
);
8691 install_element(VRF_NODE
, &ip_ssmpingd_cmd
);
8692 install_element(CONFIG_NODE
, &no_ip_ssmpingd_cmd
);
8693 install_element(VRF_NODE
, &no_ip_ssmpingd_cmd
);
8694 install_element(CONFIG_NODE
, &ip_msdp_peer_cmd
);
8695 install_element(VRF_NODE
, &ip_msdp_peer_cmd
);
8696 install_element(CONFIG_NODE
, &no_ip_msdp_peer_cmd
);
8697 install_element(VRF_NODE
, &no_ip_msdp_peer_cmd
);
8698 install_element(CONFIG_NODE
, &ip_pim_ecmp_cmd
);
8699 install_element(VRF_NODE
, &ip_pim_ecmp_cmd
);
8700 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_cmd
);
8701 install_element(VRF_NODE
, &no_ip_pim_ecmp_cmd
);
8702 install_element(CONFIG_NODE
, &ip_pim_ecmp_rebalance_cmd
);
8703 install_element(VRF_NODE
, &ip_pim_ecmp_rebalance_cmd
);
8704 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
8705 install_element(VRF_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
8707 install_element(INTERFACE_NODE
, &interface_ip_igmp_cmd
);
8708 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_cmd
);
8709 install_element(INTERFACE_NODE
, &interface_ip_igmp_join_cmd
);
8710 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_join_cmd
);
8711 install_element(INTERFACE_NODE
, &interface_ip_igmp_version_cmd
);
8712 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_version_cmd
);
8713 install_element(INTERFACE_NODE
, &interface_ip_igmp_query_interval_cmd
);
8714 install_element(INTERFACE_NODE
,
8715 &interface_no_ip_igmp_query_interval_cmd
);
8716 install_element(INTERFACE_NODE
,
8717 &interface_ip_igmp_query_max_response_time_cmd
);
8718 install_element(INTERFACE_NODE
,
8719 &interface_no_ip_igmp_query_max_response_time_cmd
);
8720 install_element(INTERFACE_NODE
,
8721 &interface_ip_igmp_query_max_response_time_dsec_cmd
);
8722 install_element(INTERFACE_NODE
,
8723 &interface_no_ip_igmp_query_max_response_time_dsec_cmd
);
8724 install_element(INTERFACE_NODE
, &interface_ip_pim_ssm_cmd
);
8725 install_element(INTERFACE_NODE
, &interface_no_ip_pim_ssm_cmd
);
8726 install_element(INTERFACE_NODE
, &interface_ip_pim_sm_cmd
);
8727 install_element(INTERFACE_NODE
, &interface_no_ip_pim_sm_cmd
);
8728 install_element(INTERFACE_NODE
, &interface_ip_pim_drprio_cmd
);
8729 install_element(INTERFACE_NODE
, &interface_no_ip_pim_drprio_cmd
);
8730 install_element(INTERFACE_NODE
, &interface_ip_pim_hello_cmd
);
8731 install_element(INTERFACE_NODE
, &interface_no_ip_pim_hello_cmd
);
8732 install_element(INTERFACE_NODE
, &interface_ip_pim_boundary_oil_cmd
);
8733 install_element(INTERFACE_NODE
, &interface_no_ip_pim_boundary_oil_cmd
);
8735 // Static mroutes NEB
8736 install_element(INTERFACE_NODE
, &interface_ip_mroute_cmd
);
8737 install_element(INTERFACE_NODE
, &interface_ip_mroute_source_cmd
);
8738 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_cmd
);
8739 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_source_cmd
);
8741 install_element(VIEW_NODE
, &show_ip_igmp_interface_cmd
);
8742 install_element(VIEW_NODE
, &show_ip_igmp_interface_vrf_all_cmd
);
8743 install_element(VIEW_NODE
, &show_ip_igmp_join_cmd
);
8744 install_element(VIEW_NODE
, &show_ip_igmp_join_vrf_all_cmd
);
8745 install_element(VIEW_NODE
, &show_ip_igmp_groups_cmd
);
8746 install_element(VIEW_NODE
, &show_ip_igmp_groups_vrf_all_cmd
);
8747 install_element(VIEW_NODE
, &show_ip_igmp_groups_retransmissions_cmd
);
8748 install_element(VIEW_NODE
, &show_ip_igmp_sources_cmd
);
8749 install_element(VIEW_NODE
, &show_ip_igmp_sources_retransmissions_cmd
);
8750 install_element(VIEW_NODE
, &show_ip_igmp_statistics_cmd
);
8751 install_element(VIEW_NODE
, &show_ip_pim_assert_cmd
);
8752 install_element(VIEW_NODE
, &show_ip_pim_assert_internal_cmd
);
8753 install_element(VIEW_NODE
, &show_ip_pim_assert_metric_cmd
);
8754 install_element(VIEW_NODE
, &show_ip_pim_assert_winner_metric_cmd
);
8755 install_element(VIEW_NODE
, &show_ip_pim_interface_traffic_cmd
);
8756 install_element(VIEW_NODE
, &show_ip_pim_interface_cmd
);
8757 install_element(VIEW_NODE
, &show_ip_pim_interface_vrf_all_cmd
);
8758 install_element(VIEW_NODE
, &show_ip_pim_join_cmd
);
8759 install_element(VIEW_NODE
, &show_ip_pim_join_vrf_all_cmd
);
8760 install_element(VIEW_NODE
, &show_ip_pim_local_membership_cmd
);
8761 install_element(VIEW_NODE
, &show_ip_pim_neighbor_cmd
);
8762 install_element(VIEW_NODE
, &show_ip_pim_neighbor_vrf_all_cmd
);
8763 install_element(VIEW_NODE
, &show_ip_pim_rpf_cmd
);
8764 install_element(VIEW_NODE
, &show_ip_pim_rpf_vrf_all_cmd
);
8765 install_element(VIEW_NODE
, &show_ip_pim_secondary_cmd
);
8766 install_element(VIEW_NODE
, &show_ip_pim_state_cmd
);
8767 install_element(VIEW_NODE
, &show_ip_pim_state_vrf_all_cmd
);
8768 install_element(VIEW_NODE
, &show_ip_pim_upstream_cmd
);
8769 install_element(VIEW_NODE
, &show_ip_pim_upstream_vrf_all_cmd
);
8770 install_element(VIEW_NODE
, &show_ip_pim_upstream_join_desired_cmd
);
8771 install_element(VIEW_NODE
, &show_ip_pim_upstream_rpf_cmd
);
8772 install_element(VIEW_NODE
, &show_ip_pim_rp_cmd
);
8773 install_element(VIEW_NODE
, &show_ip_pim_rp_vrf_all_cmd
);
8774 install_element(VIEW_NODE
, &show_ip_multicast_cmd
);
8775 install_element(VIEW_NODE
, &show_ip_multicast_vrf_all_cmd
);
8776 install_element(VIEW_NODE
, &show_ip_mroute_cmd
);
8777 install_element(VIEW_NODE
, &show_ip_mroute_vrf_all_cmd
);
8778 install_element(VIEW_NODE
, &show_ip_mroute_count_cmd
);
8779 install_element(VIEW_NODE
, &show_ip_mroute_count_vrf_all_cmd
);
8780 install_element(VIEW_NODE
, &show_ip_rib_cmd
);
8781 install_element(VIEW_NODE
, &show_ip_ssmpingd_cmd
);
8782 install_element(VIEW_NODE
, &show_debugging_pim_cmd
);
8783 install_element(VIEW_NODE
, &show_ip_pim_nexthop_cmd
);
8784 install_element(VIEW_NODE
, &show_ip_pim_nexthop_lookup_cmd
);
8786 install_element(ENABLE_NODE
, &clear_ip_interfaces_cmd
);
8787 install_element(ENABLE_NODE
, &clear_ip_igmp_interfaces_cmd
);
8788 install_element(ENABLE_NODE
, &clear_ip_mroute_cmd
);
8789 install_element(ENABLE_NODE
, &clear_ip_pim_interfaces_cmd
);
8790 install_element(ENABLE_NODE
, &clear_ip_pim_interface_traffic_cmd
);
8791 install_element(ENABLE_NODE
, &clear_ip_pim_oil_cmd
);
8793 install_element(ENABLE_NODE
, &debug_igmp_cmd
);
8794 install_element(ENABLE_NODE
, &no_debug_igmp_cmd
);
8795 install_element(ENABLE_NODE
, &debug_igmp_events_cmd
);
8796 install_element(ENABLE_NODE
, &no_debug_igmp_events_cmd
);
8797 install_element(ENABLE_NODE
, &debug_igmp_packets_cmd
);
8798 install_element(ENABLE_NODE
, &no_debug_igmp_packets_cmd
);
8799 install_element(ENABLE_NODE
, &debug_igmp_trace_cmd
);
8800 install_element(ENABLE_NODE
, &no_debug_igmp_trace_cmd
);
8801 install_element(ENABLE_NODE
, &debug_mroute_cmd
);
8802 install_element(ENABLE_NODE
, &debug_mroute_detail_cmd
);
8803 install_element(ENABLE_NODE
, &no_debug_mroute_cmd
);
8804 install_element(ENABLE_NODE
, &no_debug_mroute_detail_cmd
);
8805 install_element(ENABLE_NODE
, &debug_static_cmd
);
8806 install_element(ENABLE_NODE
, &no_debug_static_cmd
);
8807 install_element(ENABLE_NODE
, &debug_pim_cmd
);
8808 install_element(ENABLE_NODE
, &no_debug_pim_cmd
);
8809 install_element(ENABLE_NODE
, &debug_pim_nht_cmd
);
8810 install_element(ENABLE_NODE
, &no_debug_pim_nht_cmd
);
8811 install_element(ENABLE_NODE
, &debug_pim_nht_rp_cmd
);
8812 install_element(ENABLE_NODE
, &no_debug_pim_nht_rp_cmd
);
8813 install_element(ENABLE_NODE
, &debug_pim_events_cmd
);
8814 install_element(ENABLE_NODE
, &no_debug_pim_events_cmd
);
8815 install_element(ENABLE_NODE
, &debug_pim_packets_cmd
);
8816 install_element(ENABLE_NODE
, &no_debug_pim_packets_cmd
);
8817 install_element(ENABLE_NODE
, &debug_pim_packetdump_send_cmd
);
8818 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_send_cmd
);
8819 install_element(ENABLE_NODE
, &debug_pim_packetdump_recv_cmd
);
8820 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_recv_cmd
);
8821 install_element(ENABLE_NODE
, &debug_pim_trace_cmd
);
8822 install_element(ENABLE_NODE
, &no_debug_pim_trace_cmd
);
8823 install_element(ENABLE_NODE
, &debug_pim_trace_detail_cmd
);
8824 install_element(ENABLE_NODE
, &no_debug_pim_trace_detail_cmd
);
8825 install_element(ENABLE_NODE
, &debug_ssmpingd_cmd
);
8826 install_element(ENABLE_NODE
, &no_debug_ssmpingd_cmd
);
8827 install_element(ENABLE_NODE
, &debug_pim_zebra_cmd
);
8828 install_element(ENABLE_NODE
, &no_debug_pim_zebra_cmd
);
8829 install_element(ENABLE_NODE
, &debug_msdp_cmd
);
8830 install_element(ENABLE_NODE
, &no_debug_msdp_cmd
);
8831 install_element(ENABLE_NODE
, &undebug_msdp_cmd
);
8832 install_element(ENABLE_NODE
, &debug_msdp_events_cmd
);
8833 install_element(ENABLE_NODE
, &no_debug_msdp_events_cmd
);
8834 install_element(ENABLE_NODE
, &undebug_msdp_events_cmd
);
8835 install_element(ENABLE_NODE
, &debug_msdp_packets_cmd
);
8836 install_element(ENABLE_NODE
, &no_debug_msdp_packets_cmd
);
8837 install_element(ENABLE_NODE
, &undebug_msdp_packets_cmd
);
8838 install_element(ENABLE_NODE
, &debug_mtrace_cmd
);
8839 install_element(ENABLE_NODE
, &no_debug_mtrace_cmd
);
8841 install_element(CONFIG_NODE
, &debug_igmp_cmd
);
8842 install_element(CONFIG_NODE
, &no_debug_igmp_cmd
);
8843 install_element(CONFIG_NODE
, &debug_igmp_events_cmd
);
8844 install_element(CONFIG_NODE
, &no_debug_igmp_events_cmd
);
8845 install_element(CONFIG_NODE
, &debug_igmp_packets_cmd
);
8846 install_element(CONFIG_NODE
, &no_debug_igmp_packets_cmd
);
8847 install_element(CONFIG_NODE
, &debug_igmp_trace_cmd
);
8848 install_element(CONFIG_NODE
, &no_debug_igmp_trace_cmd
);
8849 install_element(CONFIG_NODE
, &debug_mroute_cmd
);
8850 install_element(CONFIG_NODE
, &debug_mroute_detail_cmd
);
8851 install_element(CONFIG_NODE
, &no_debug_mroute_cmd
);
8852 install_element(CONFIG_NODE
, &no_debug_mroute_detail_cmd
);
8853 install_element(CONFIG_NODE
, &debug_static_cmd
);
8854 install_element(CONFIG_NODE
, &no_debug_static_cmd
);
8855 install_element(CONFIG_NODE
, &debug_pim_cmd
);
8856 install_element(CONFIG_NODE
, &no_debug_pim_cmd
);
8857 install_element(CONFIG_NODE
, &debug_pim_nht_cmd
);
8858 install_element(CONFIG_NODE
, &no_debug_pim_nht_cmd
);
8859 install_element(CONFIG_NODE
, &debug_pim_nht_rp_cmd
);
8860 install_element(CONFIG_NODE
, &no_debug_pim_nht_rp_cmd
);
8861 install_element(CONFIG_NODE
, &debug_pim_events_cmd
);
8862 install_element(CONFIG_NODE
, &no_debug_pim_events_cmd
);
8863 install_element(CONFIG_NODE
, &debug_pim_packets_cmd
);
8864 install_element(CONFIG_NODE
, &no_debug_pim_packets_cmd
);
8865 install_element(CONFIG_NODE
, &debug_pim_trace_cmd
);
8866 install_element(CONFIG_NODE
, &no_debug_pim_trace_cmd
);
8867 install_element(CONFIG_NODE
, &debug_pim_trace_detail_cmd
);
8868 install_element(CONFIG_NODE
, &no_debug_pim_trace_detail_cmd
);
8869 install_element(CONFIG_NODE
, &debug_ssmpingd_cmd
);
8870 install_element(CONFIG_NODE
, &no_debug_ssmpingd_cmd
);
8871 install_element(CONFIG_NODE
, &debug_pim_zebra_cmd
);
8872 install_element(CONFIG_NODE
, &no_debug_pim_zebra_cmd
);
8873 install_element(CONFIG_NODE
, &debug_msdp_cmd
);
8874 install_element(CONFIG_NODE
, &no_debug_msdp_cmd
);
8875 install_element(CONFIG_NODE
, &undebug_msdp_cmd
);
8876 install_element(CONFIG_NODE
, &debug_msdp_events_cmd
);
8877 install_element(CONFIG_NODE
, &no_debug_msdp_events_cmd
);
8878 install_element(CONFIG_NODE
, &undebug_msdp_events_cmd
);
8879 install_element(CONFIG_NODE
, &debug_msdp_packets_cmd
);
8880 install_element(CONFIG_NODE
, &no_debug_msdp_packets_cmd
);
8881 install_element(CONFIG_NODE
, &undebug_msdp_packets_cmd
);
8882 install_element(CONFIG_NODE
, &debug_mtrace_cmd
);
8883 install_element(CONFIG_NODE
, &no_debug_mtrace_cmd
);
8885 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_member_cmd
);
8886 install_element(VRF_NODE
, &ip_msdp_mesh_group_member_cmd
);
8887 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
8888 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
8889 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_source_cmd
);
8890 install_element(VRF_NODE
, &ip_msdp_mesh_group_source_cmd
);
8891 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
8892 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
8893 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_cmd
);
8894 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_vrf_all_cmd
);
8895 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_cmd
);
8896 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_vrf_all_cmd
);
8897 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_cmd
);
8898 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_vrf_all_cmd
);
8899 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_cmd
);
8900 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_vrf_all_cmd
);
8901 install_element(VIEW_NODE
, &show_ip_pim_ssm_range_cmd
);
8902 install_element(VIEW_NODE
, &show_ip_pim_group_type_cmd
);
8903 install_element(INTERFACE_NODE
, &interface_pim_use_source_cmd
);
8904 install_element(INTERFACE_NODE
, &interface_no_pim_use_source_cmd
);
8905 /* Install BFD command */
8906 install_element(INTERFACE_NODE
, &ip_pim_bfd_cmd
);
8907 install_element(INTERFACE_NODE
, &ip_pim_bfd_param_cmd
);
8908 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_cmd
);
8909 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_param_cmd
);