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(%d)\n",
1191 pim_ifp
->pim_dr_priority
,
1192 pim_ifp
->pim_dr_num_nondrpri_neighbors
);
1193 vty_out(vty
, "Uptime : %s\n", dr_uptime
);
1194 vty_out(vty
, "Elections : %d\n",
1195 pim_ifp
->pim_dr_election_count
);
1196 vty_out(vty
, "Changes : %d\n",
1197 pim_ifp
->pim_dr_election_changes
);
1203 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
,
1206 if (strcmp(ifp
->name
,
1207 up
->rpf
.source_nexthop
1212 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
))
1217 "FHR - First Hop Router\n");
1219 "----------------------\n");
1223 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
,
1225 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
,
1227 pim_time_uptime(uptime
, sizeof(uptime
),
1228 now
- up
->state_transition
);
1230 "%s : %s is a source, uptime is %s\n",
1231 grp_str
, src_str
, uptime
);
1234 if (!print_header
) {
1239 vty_out(vty
, "Hellos\n");
1240 vty_out(vty
, "------\n");
1241 vty_out(vty
, "Period : %d\n",
1242 pim_ifp
->pim_hello_period
);
1243 vty_out(vty
, "Timer : %s\n", hello_timer
);
1244 vty_out(vty
, "StatStart : %s\n", stat_uptime
);
1245 vty_out(vty
, "Receive : %d\n",
1246 pim_ifp
->pim_ifstat_hello_recv
);
1247 vty_out(vty
, "Receive Failed : %d\n",
1248 pim_ifp
->pim_ifstat_hello_recvfail
);
1249 vty_out(vty
, "Send : %d\n",
1250 pim_ifp
->pim_ifstat_hello_sent
);
1251 vty_out(vty
, "Send Failed : %d\n",
1252 pim_ifp
->pim_ifstat_hello_sendfail
);
1253 vty_out(vty
, "Generation ID : %08x\n",
1254 pim_ifp
->pim_generation_id
);
1258 pim_print_ifp_flags(vty
, ifp
, mloop
);
1260 vty_out(vty
, "Join Prune Interval\n");
1261 vty_out(vty
, "-------------------\n");
1262 vty_out(vty
, "LAN Delay : %s\n",
1263 pim_if_lan_delay_enabled(ifp
) ? "yes" : "no");
1264 vty_out(vty
, "Effective Propagation Delay : %d msec\n",
1265 pim_if_effective_propagation_delay_msec(ifp
));
1266 vty_out(vty
, "Effective Override Interval : %d msec\n",
1267 pim_if_effective_override_interval_msec(ifp
));
1268 vty_out(vty
, "Join Prune Override Interval : %d msec\n",
1269 pim_if_jp_override_interval_msec(ifp
));
1273 vty_out(vty
, "LAN Prune Delay\n");
1274 vty_out(vty
, "---------------\n");
1275 vty_out(vty
, "Propagation Delay : %d msec\n",
1276 pim_ifp
->pim_propagation_delay_msec
);
1277 vty_out(vty
, "Propagation Delay (Highest) : %d msec\n",
1278 pim_ifp
->pim_neighbors_highest_propagation_delay_msec
);
1279 vty_out(vty
, "Override Interval : %d msec\n",
1280 pim_ifp
->pim_override_interval_msec
);
1281 vty_out(vty
, "Override Interval (Highest) : %d msec\n",
1282 pim_ifp
->pim_neighbors_highest_override_interval_msec
);
1289 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1290 json
, JSON_C_TO_STRING_PRETTY
));
1291 json_object_free(json
);
1294 vty_out(vty
, "%% No such interface\n");
1298 static void igmp_show_statistics(struct pim_instance
*pim
, struct vty
*vty
,
1299 const char *ifname
, bool uj
)
1301 struct interface
*ifp
;
1302 struct igmp_stats rx_stats
;
1304 igmp_stats_init(&rx_stats
);
1306 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1307 struct pim_interface
*pim_ifp
;
1308 struct listnode
*sock_node
;
1309 struct igmp_sock
*igmp
;
1311 pim_ifp
= ifp
->info
;
1316 if (ifname
&& strcmp(ifname
, ifp
->name
))
1319 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
1321 igmp_stats_add(&rx_stats
, &igmp
->rx_stats
);
1325 json_object
*json
= NULL
;
1326 json_object
*json_row
= NULL
;
1328 json
= json_object_new_object();
1329 json_row
= json_object_new_object();
1331 json_object_string_add(json_row
, "name", ifname
? ifname
:
1333 json_object_int_add(json_row
, "queryV1", rx_stats
.query_v1
);
1334 json_object_int_add(json_row
, "queryV2", rx_stats
.query_v2
);
1335 json_object_int_add(json_row
, "queryV3", rx_stats
.query_v3
);
1336 json_object_int_add(json_row
, "leaveV3", rx_stats
.leave_v2
);
1337 json_object_int_add(json_row
, "reportV1", rx_stats
.report_v1
);
1338 json_object_int_add(json_row
, "reportV2", rx_stats
.report_v2
);
1339 json_object_int_add(json_row
, "reportV3", rx_stats
.report_v3
);
1340 json_object_int_add(json_row
, "mtraceResponse",
1341 rx_stats
.mtrace_rsp
);
1342 json_object_int_add(json_row
, "mtraceRequest",
1343 rx_stats
.mtrace_req
);
1344 json_object_int_add(json_row
, "unsupported",
1345 rx_stats
.unsupported
);
1346 json_object_object_add(json
, ifname
? ifname
: "global",
1348 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1349 json
, JSON_C_TO_STRING_PRETTY
));
1350 json_object_free(json
);
1352 vty_out(vty
, "IGMP RX statistics\n");
1353 vty_out(vty
, "Interface : %s\n",
1354 ifname
? ifname
: "global");
1355 vty_out(vty
, "V1 query : %u\n", rx_stats
.query_v1
);
1356 vty_out(vty
, "V2 query : %u\n", rx_stats
.query_v2
);
1357 vty_out(vty
, "V3 query : %u\n", rx_stats
.query_v3
);
1358 vty_out(vty
, "V2 leave : %u\n", rx_stats
.leave_v2
);
1359 vty_out(vty
, "V1 report : %u\n", rx_stats
.report_v1
);
1360 vty_out(vty
, "V2 report : %u\n", rx_stats
.report_v2
);
1361 vty_out(vty
, "V3 report : %u\n", rx_stats
.report_v3
);
1362 vty_out(vty
, "mtrace response : %u\n", rx_stats
.mtrace_rsp
);
1363 vty_out(vty
, "mtrace request : %u\n", rx_stats
.mtrace_req
);
1364 vty_out(vty
, "unsupported : %u\n", rx_stats
.unsupported
);
1368 static void pim_show_interfaces(struct pim_instance
*pim
, struct vty
*vty
,
1371 struct interface
*ifp
;
1372 struct listnode
*upnode
;
1373 struct pim_interface
*pim_ifp
;
1374 struct pim_upstream
*up
;
1377 int pim_ifchannels
= 0;
1378 json_object
*json
= NULL
;
1379 json_object
*json_row
= NULL
;
1380 json_object
*json_tmp
;
1382 json
= json_object_new_object();
1384 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1385 pim_ifp
= ifp
->info
;
1390 pim_nbrs
= pim_ifp
->pim_neighbor_list
->count
;
1391 pim_ifchannels
= pim_if_ifchannel_count(pim_ifp
);
1394 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
, up
))
1395 if (ifp
== up
->rpf
.source_nexthop
.interface
)
1396 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
1399 json_row
= json_object_new_object();
1400 json_object_pim_ifp_add(json_row
, ifp
);
1401 json_object_int_add(json_row
, "pimNeighbors", pim_nbrs
);
1402 json_object_int_add(json_row
, "pimIfChannels", pim_ifchannels
);
1403 json_object_int_add(json_row
, "firstHopRouterCount", fhr
);
1404 json_object_string_add(json_row
, "pimDesignatedRouter",
1405 inet_ntoa(pim_ifp
->pim_dr_addr
));
1407 if (pim_ifp
->pim_dr_addr
.s_addr
1408 == pim_ifp
->primary_address
.s_addr
)
1409 json_object_boolean_true_add(
1410 json_row
, "pimDesignatedRouterLocal");
1412 json_object_object_add(json
, ifp
->name
, json_row
);
1416 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1417 json
, JSON_C_TO_STRING_PRETTY
));
1420 "Interface State Address PIM Nbrs PIM DR FHR IfChannels\n");
1422 json_object_object_foreach(json
, key
, val
)
1424 vty_out(vty
, "%-9s ", key
);
1426 json_object_object_get_ex(val
, "state", &json_tmp
);
1427 vty_out(vty
, "%5s ", json_object_get_string(json_tmp
));
1429 json_object_object_get_ex(val
, "address", &json_tmp
);
1430 vty_out(vty
, "%15s ",
1431 json_object_get_string(json_tmp
));
1433 json_object_object_get_ex(val
, "pimNeighbors",
1435 vty_out(vty
, "%8d ", json_object_get_int(json_tmp
));
1437 if (json_object_object_get_ex(
1438 val
, "pimDesignatedRouterLocal",
1440 vty_out(vty
, "%15s ", "local");
1442 json_object_object_get_ex(
1443 val
, "pimDesignatedRouter", &json_tmp
);
1444 vty_out(vty
, "%15s ",
1445 json_object_get_string(json_tmp
));
1448 json_object_object_get_ex(val
, "firstHopRouter",
1450 vty_out(vty
, "%3d ", json_object_get_int(json_tmp
));
1452 json_object_object_get_ex(val
, "pimIfChannels",
1454 vty_out(vty
, "%9d\n", json_object_get_int(json_tmp
));
1458 json_object_free(json
);
1461 static void pim_show_interface_traffic(struct pim_instance
*pim
,
1462 struct vty
*vty
, bool uj
)
1464 struct interface
*ifp
= NULL
;
1465 struct pim_interface
*pim_ifp
= NULL
;
1466 json_object
*json
= NULL
;
1467 json_object
*json_row
= NULL
;
1470 json
= json_object_new_object();
1473 vty_out(vty
, "%-12s%-17s%-17s%-17s%-17s%-17s%-17s\n",
1474 "Interface", " HELLO", " JOIN", " PRUNE",
1475 " REGISTER", " REGISTER-STOP", " ASSERT");
1476 vty_out(vty
, "%-10s%-18s%-17s%-17s%-17s%-17s%-17s\n", "",
1477 " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1478 " Rx/Tx", " Rx/Tx");
1480 "---------------------------------------------------------------------------------------------------------------\n");
1483 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1484 pim_ifp
= ifp
->info
;
1489 if (pim_ifp
->pim_sock_fd
< 0)
1492 json_row
= json_object_new_object();
1493 json_object_pim_ifp_add(json_row
, ifp
);
1494 json_object_int_add(json_row
, "helloRx",
1495 pim_ifp
->pim_ifstat_hello_recv
);
1496 json_object_int_add(json_row
, "helloTx",
1497 pim_ifp
->pim_ifstat_hello_sent
);
1498 json_object_int_add(json_row
, "joinRx",
1499 pim_ifp
->pim_ifstat_join_recv
);
1500 json_object_int_add(json_row
, "joinTx",
1501 pim_ifp
->pim_ifstat_join_send
);
1502 json_object_int_add(json_row
, "registerRx",
1503 pim_ifp
->pim_ifstat_reg_recv
);
1504 json_object_int_add(json_row
, "registerTx",
1505 pim_ifp
->pim_ifstat_reg_recv
);
1506 json_object_int_add(json_row
, "registerStopRx",
1507 pim_ifp
->pim_ifstat_reg_stop_recv
);
1508 json_object_int_add(json_row
, "registerStopTx",
1509 pim_ifp
->pim_ifstat_reg_stop_send
);
1510 json_object_int_add(json_row
, "assertRx",
1511 pim_ifp
->pim_ifstat_assert_recv
);
1512 json_object_int_add(json_row
, "assertTx",
1513 pim_ifp
->pim_ifstat_assert_send
);
1515 json_object_object_add(json
, ifp
->name
, json_row
);
1518 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u \n",
1519 ifp
->name
, pim_ifp
->pim_ifstat_hello_recv
,
1520 pim_ifp
->pim_ifstat_hello_sent
,
1521 pim_ifp
->pim_ifstat_join_recv
,
1522 pim_ifp
->pim_ifstat_join_send
,
1523 pim_ifp
->pim_ifstat_prune_recv
,
1524 pim_ifp
->pim_ifstat_prune_send
,
1525 pim_ifp
->pim_ifstat_reg_recv
,
1526 pim_ifp
->pim_ifstat_reg_send
,
1527 pim_ifp
->pim_ifstat_reg_stop_recv
,
1528 pim_ifp
->pim_ifstat_reg_stop_send
,
1529 pim_ifp
->pim_ifstat_assert_recv
,
1530 pim_ifp
->pim_ifstat_assert_send
);
1534 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1535 json
, JSON_C_TO_STRING_PRETTY
));
1536 json_object_free(json
);
1540 static void pim_show_interface_traffic_single(struct pim_instance
*pim
,
1542 const char *ifname
, bool uj
)
1544 struct interface
*ifp
= NULL
;
1545 struct pim_interface
*pim_ifp
= NULL
;
1546 json_object
*json
= NULL
;
1547 json_object
*json_row
= NULL
;
1548 uint8_t found_ifname
= 0;
1551 json
= json_object_new_object();
1554 vty_out(vty
, "%-12s%-17s%-17s%-17s%-17s%-17s%-17s\n",
1555 "Interface", " HELLO", " JOIN", " PRUNE",
1556 " REGISTER", " REGISTER-STOP", " ASSERT");
1557 vty_out(vty
, "%-10s%-18s%-17s%-17s%-17s%-17s%-17s\n", "",
1558 " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1559 " Rx/Tx", " Rx/Tx");
1561 "---------------------------------------------------------------------------------------------------------------\n");
1564 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1565 if (strcmp(ifname
, ifp
->name
))
1568 pim_ifp
= ifp
->info
;
1573 if (pim_ifp
->pim_sock_fd
< 0)
1578 json_row
= json_object_new_object();
1579 json_object_pim_ifp_add(json_row
, ifp
);
1580 json_object_int_add(json_row
, "helloRx",
1581 pim_ifp
->pim_ifstat_hello_recv
);
1582 json_object_int_add(json_row
, "helloTx",
1583 pim_ifp
->pim_ifstat_hello_sent
);
1584 json_object_int_add(json_row
, "joinRx",
1585 pim_ifp
->pim_ifstat_join_recv
);
1586 json_object_int_add(json_row
, "joinTx",
1587 pim_ifp
->pim_ifstat_join_send
);
1588 json_object_int_add(json_row
, "registerRx",
1589 pim_ifp
->pim_ifstat_reg_recv
);
1590 json_object_int_add(json_row
, "registerTx",
1591 pim_ifp
->pim_ifstat_reg_recv
);
1592 json_object_int_add(json_row
, "registerStopRx",
1593 pim_ifp
->pim_ifstat_reg_stop_recv
);
1594 json_object_int_add(json_row
, "registerStopTx",
1595 pim_ifp
->pim_ifstat_reg_stop_send
);
1596 json_object_int_add(json_row
, "assertRx",
1597 pim_ifp
->pim_ifstat_assert_recv
);
1598 json_object_int_add(json_row
, "assertTx",
1599 pim_ifp
->pim_ifstat_assert_send
);
1601 json_object_object_add(json
, ifp
->name
, json_row
);
1604 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u \n",
1605 ifp
->name
, pim_ifp
->pim_ifstat_hello_recv
,
1606 pim_ifp
->pim_ifstat_hello_sent
,
1607 pim_ifp
->pim_ifstat_join_recv
,
1608 pim_ifp
->pim_ifstat_join_send
,
1609 pim_ifp
->pim_ifstat_prune_recv
,
1610 pim_ifp
->pim_ifstat_prune_send
,
1611 pim_ifp
->pim_ifstat_reg_recv
,
1612 pim_ifp
->pim_ifstat_reg_send
,
1613 pim_ifp
->pim_ifstat_reg_stop_recv
,
1614 pim_ifp
->pim_ifstat_reg_stop_send
,
1615 pim_ifp
->pim_ifstat_assert_recv
,
1616 pim_ifp
->pim_ifstat_assert_send
);
1620 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1621 json
, JSON_C_TO_STRING_PRETTY
));
1622 json_object_free(json
);
1625 vty_out(vty
, "%% No such interface\n");
1629 static void pim_show_join_helper(struct vty
*vty
, struct pim_interface
*pim_ifp
,
1630 struct pim_ifchannel
*ch
, json_object
*json
,
1631 time_t now
, bool uj
)
1633 char ch_src_str
[INET_ADDRSTRLEN
];
1634 char ch_grp_str
[INET_ADDRSTRLEN
];
1635 json_object
*json_iface
= NULL
;
1636 json_object
*json_row
= NULL
;
1637 json_object
*json_grp
= NULL
;
1638 struct in_addr ifaddr
;
1643 ifaddr
= pim_ifp
->primary_address
;
1645 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
1646 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
1648 pim_time_uptime_begin(uptime
, sizeof(uptime
), now
, ch
->ifjoin_creation
);
1649 pim_time_timer_to_mmss(expire
, sizeof(expire
),
1650 ch
->t_ifjoin_expiry_timer
);
1651 pim_time_timer_to_mmss(prune
, sizeof(prune
),
1652 ch
->t_ifjoin_prune_pending_timer
);
1655 json_object_object_get_ex(json
, ch
->interface
->name
,
1659 json_iface
= json_object_new_object();
1660 json_object_pim_ifp_add(json_iface
, ch
->interface
);
1661 json_object_object_add(json
, ch
->interface
->name
,
1665 json_row
= json_object_new_object();
1666 json_object_string_add(json_row
, "source", ch_src_str
);
1667 json_object_string_add(json_row
, "group", ch_grp_str
);
1668 json_object_string_add(json_row
, "upTime", uptime
);
1669 json_object_string_add(json_row
, "expire", expire
);
1670 json_object_string_add(json_row
, "prune", prune
);
1671 json_object_string_add(
1672 json_row
, "channelJoinName",
1673 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
, ch
->flags
));
1674 if (PIM_IF_FLAG_TEST_S_G_RPT(ch
->flags
))
1675 json_object_int_add(json_row
, "SGRpt", 1);
1677 json_object_object_get_ex(json_iface
, ch_grp_str
, &json_grp
);
1679 json_grp
= json_object_new_object();
1680 json_object_object_add(json_grp
, ch_src_str
, json_row
);
1681 json_object_object_add(json_iface
, ch_grp_str
,
1684 json_object_object_add(json_grp
, ch_src_str
, json_row
);
1686 vty_out(vty
, "%-9s %-15s %-15s %-15s %-10s %8s %-6s %5s\n",
1687 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
,
1689 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
, ch
->flags
),
1690 uptime
, expire
, prune
);
1694 static void pim_show_join(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
1696 struct pim_interface
*pim_ifp
;
1697 struct pim_ifchannel
*ch
;
1698 struct interface
*ifp
;
1700 json_object
*json
= NULL
;
1702 now
= pim_time_monotonic_sec();
1705 json
= json_object_new_object();
1708 "Interface Address Source Group State Uptime Expire Prune\n");
1710 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1711 pim_ifp
= ifp
->info
;
1715 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
1716 pim_show_join_helper(vty
, pim_ifp
, ch
, json
, now
, uj
);
1717 } /* scan interface channels */
1721 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1722 json
, JSON_C_TO_STRING_PRETTY
));
1723 json_object_free(json
);
1727 static void pim_show_neighbors_single(struct pim_instance
*pim
, struct vty
*vty
,
1728 const char *neighbor
, bool uj
)
1730 struct listnode
*neighnode
;
1731 struct interface
*ifp
;
1732 struct pim_interface
*pim_ifp
;
1733 struct pim_neighbor
*neigh
;
1735 int found_neighbor
= 0;
1736 int option_address_list
;
1737 int option_dr_priority
;
1738 int option_generation_id
;
1739 int option_holdtime
;
1740 int option_lan_prune_delay
;
1744 char neigh_src_str
[INET_ADDRSTRLEN
];
1746 json_object
*json
= NULL
;
1747 json_object
*json_ifp
= NULL
;
1748 json_object
*json_row
= NULL
;
1750 now
= pim_time_monotonic_sec();
1753 json
= json_object_new_object();
1755 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1756 pim_ifp
= ifp
->info
;
1761 if (pim_ifp
->pim_sock_fd
< 0)
1764 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
1766 pim_inet4_dump("<src?>", neigh
->source_addr
,
1767 neigh_src_str
, sizeof(neigh_src_str
));
1770 * The user can specify either the interface name or the
1772 * If this pim_ifp matches neither then skip.
1774 if (strcmp(neighbor
, "detail")
1775 && strcmp(neighbor
, ifp
->name
)
1776 && strcmp(neighbor
, neigh_src_str
))
1780 pim_time_uptime(uptime
, sizeof(uptime
),
1781 now
- neigh
->creation
);
1782 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
1783 neigh
->t_expire_timer
);
1785 option_address_list
= 0;
1786 option_dr_priority
= 0;
1787 option_generation_id
= 0;
1788 option_holdtime
= 0;
1789 option_lan_prune_delay
= 0;
1792 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1793 PIM_OPTION_MASK_ADDRESS_LIST
))
1794 option_address_list
= 1;
1796 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1797 PIM_OPTION_MASK_DR_PRIORITY
))
1798 option_dr_priority
= 1;
1800 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1801 PIM_OPTION_MASK_GENERATION_ID
))
1802 option_generation_id
= 1;
1804 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1805 PIM_OPTION_MASK_HOLDTIME
))
1806 option_holdtime
= 1;
1808 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1809 PIM_OPTION_MASK_LAN_PRUNE_DELAY
))
1810 option_lan_prune_delay
= 1;
1812 if (PIM_OPTION_IS_SET(
1813 neigh
->hello_options
,
1814 PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION
))
1819 /* Does this ifp live in json? If not create
1821 json_object_object_get_ex(json
, ifp
->name
,
1825 json_ifp
= json_object_new_object();
1826 json_object_pim_ifp_add(json_ifp
, ifp
);
1827 json_object_object_add(json
, ifp
->name
,
1831 json_row
= json_object_new_object();
1832 json_object_string_add(json_row
, "interface",
1834 json_object_string_add(json_row
, "address",
1836 json_object_string_add(json_row
, "upTime",
1838 json_object_string_add(json_row
, "holdtime",
1840 json_object_int_add(json_row
, "drPriority",
1841 neigh
->dr_priority
);
1842 json_object_int_add(json_row
, "generationId",
1843 neigh
->generation_id
);
1845 if (option_address_list
)
1846 json_object_boolean_true_add(
1848 "helloOptionAddressList");
1850 if (option_dr_priority
)
1851 json_object_boolean_true_add(
1853 "helloOptionDrPriority");
1855 if (option_generation_id
)
1856 json_object_boolean_true_add(
1858 "helloOptionGenerationId");
1860 if (option_holdtime
)
1861 json_object_boolean_true_add(
1863 "helloOptionHoldtime");
1865 if (option_lan_prune_delay
)
1866 json_object_boolean_true_add(
1868 "helloOptionLanPruneDelay");
1871 json_object_boolean_true_add(
1872 json_row
, "helloOptionTBit");
1874 json_object_object_add(json_ifp
, neigh_src_str
,
1878 vty_out(vty
, "Interface : %s\n", ifp
->name
);
1879 vty_out(vty
, "Neighbor : %s\n", neigh_src_str
);
1887 " DR Priority : %d\n",
1888 neigh
->dr_priority
);
1890 " Generation ID : %08x\n",
1891 neigh
->generation_id
);
1893 " Override Interval (msec) : %d\n",
1894 neigh
->override_interval_msec
);
1896 " Propagation Delay (msec) : %d\n",
1897 neigh
->propagation_delay_msec
);
1899 " Hello Option - Address List : %s\n",
1900 option_address_list
? "yes" : "no");
1902 " Hello Option - DR Priority : %s\n",
1903 option_dr_priority
? "yes" : "no");
1905 " Hello Option - Generation ID : %s\n",
1906 option_generation_id
? "yes" : "no");
1908 " Hello Option - Holdtime : %s\n",
1909 option_holdtime
? "yes" : "no");
1911 " Hello Option - LAN Prune Delay : %s\n",
1912 option_lan_prune_delay
? "yes" : "no");
1914 " Hello Option - T-bit : %s\n",
1915 option_t_bit
? "yes" : "no");
1916 pim_bfd_show_info(vty
, neigh
->bfd_info
,
1924 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1925 json
, JSON_C_TO_STRING_PRETTY
));
1926 json_object_free(json
);
1929 if (!found_neighbor
)
1931 "%% No such interface or neighbor\n");
1936 static void pim_show_state(struct pim_instance
*pim
, struct vty
*vty
,
1937 const char *src_or_group
, const char *group
, bool uj
)
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
, bool 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
, bool uj
)
2706 struct listnode
*up_node
;
2707 struct pim_upstream
*up
;
2708 time_t now
= pim_time_monotonic_sec();
2709 json_object
*json
= NULL
;
2710 json_object
*json_group
= NULL
;
2711 json_object
*json_row
= NULL
;
2714 json
= json_object_new_object();
2715 show_rpf_refresh_stats(vty
, pim
, now
, json
);
2717 show_rpf_refresh_stats(vty
, pim
, now
, json
);
2720 "Source Group RpfIface RpfAddress RibNextHop Metric Pref\n");
2723 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, up_node
, up
)) {
2724 char src_str
[INET_ADDRSTRLEN
];
2725 char grp_str
[INET_ADDRSTRLEN
];
2726 char rpf_addr_str
[PREFIX_STRLEN
];
2727 char rib_nexthop_str
[PREFIX_STRLEN
];
2728 const char *rpf_ifname
;
2729 struct pim_rpf
*rpf
= &up
->rpf
;
2731 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2732 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2733 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2734 sizeof(rpf_addr_str
));
2735 pim_addr_dump("<nexthop?>",
2736 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2737 rib_nexthop_str
, sizeof(rib_nexthop_str
));
2739 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2742 json_object_object_get_ex(json
, grp_str
, &json_group
);
2745 json_group
= json_object_new_object();
2746 json_object_object_add(json
, grp_str
,
2750 json_row
= json_object_new_object();
2751 json_object_string_add(json_row
, "source", src_str
);
2752 json_object_string_add(json_row
, "group", grp_str
);
2753 json_object_string_add(json_row
, "rpfInterface",
2755 json_object_string_add(json_row
, "rpfAddress",
2757 json_object_string_add(json_row
, "ribNexthop",
2759 json_object_int_add(
2760 json_row
, "routeMetric",
2761 rpf
->source_nexthop
.mrib_route_metric
);
2762 json_object_int_add(
2763 json_row
, "routePreference",
2764 rpf
->source_nexthop
.mrib_metric_preference
);
2765 json_object_object_add(json_group
, src_str
, json_row
);
2768 vty_out(vty
, "%-15s %-15s %-8s %-15s %-15s %6d %4d\n",
2769 src_str
, grp_str
, rpf_ifname
, rpf_addr_str
,
2771 rpf
->source_nexthop
.mrib_route_metric
,
2772 rpf
->source_nexthop
.mrib_metric_preference
);
2777 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2778 json
, JSON_C_TO_STRING_PRETTY
));
2779 json_object_free(json
);
2783 struct pnc_cache_walk_data
{
2785 struct pim_instance
*pim
;
2788 static int pim_print_pnc_cache_walkcb(struct hash_backet
*backet
, void *arg
)
2790 struct pim_nexthop_cache
*pnc
= backet
->data
;
2791 struct pnc_cache_walk_data
*cwd
= arg
;
2792 struct vty
*vty
= cwd
->vty
;
2793 struct pim_instance
*pim
= cwd
->pim
;
2794 struct nexthop
*nh_node
= NULL
;
2795 ifindex_t first_ifindex
;
2796 struct interface
*ifp
= NULL
;
2798 for (nh_node
= pnc
->nexthop
; nh_node
; nh_node
= nh_node
->next
) {
2799 first_ifindex
= nh_node
->ifindex
;
2800 ifp
= if_lookup_by_index(first_ifindex
, pim
->vrf_id
);
2802 vty_out(vty
, "%-15s ", inet_ntoa(pnc
->rpf
.rpf_addr
.u
.prefix4
));
2803 vty_out(vty
, "%-14s ", ifp
? ifp
->name
: "NULL");
2804 vty_out(vty
, "%s ", inet_ntoa(nh_node
->gate
.ipv4
));
2810 static void pim_show_nexthop(struct pim_instance
*pim
, struct vty
*vty
)
2812 struct pnc_cache_walk_data cwd
;
2816 vty_out(vty
, "Number of registered addresses: %lu\n",
2817 pim
->rpf_hash
->count
);
2818 vty_out(vty
, "Address Interface Nexthop\n");
2819 vty_out(vty
, "-------------------------------------------\n");
2821 hash_walk(pim
->rpf_hash
, pim_print_pnc_cache_walkcb
, &cwd
);
2824 static void igmp_show_groups(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
2826 struct interface
*ifp
;
2828 json_object
*json
= NULL
;
2829 json_object
*json_iface
= NULL
;
2830 json_object
*json_row
= NULL
;
2832 now
= pim_time_monotonic_sec();
2835 json
= json_object_new_object();
2838 "Interface Address Group Mode Timer Srcs V Uptime \n");
2840 /* scan interfaces */
2841 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2842 struct pim_interface
*pim_ifp
= ifp
->info
;
2843 struct listnode
*sock_node
;
2844 struct igmp_sock
*igmp
;
2849 /* scan igmp sockets */
2850 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
2852 char ifaddr_str
[INET_ADDRSTRLEN
];
2853 struct listnode
*grpnode
;
2854 struct igmp_group
*grp
;
2856 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
2857 sizeof(ifaddr_str
));
2859 /* scan igmp groups */
2860 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
2862 char group_str
[INET_ADDRSTRLEN
];
2866 pim_inet4_dump("<group?>", grp
->group_addr
,
2867 group_str
, sizeof(group_str
));
2868 pim_time_timer_to_hhmmss(hhmmss
, sizeof(hhmmss
),
2869 grp
->t_group_timer
);
2870 pim_time_uptime(uptime
, sizeof(uptime
),
2871 now
- grp
->group_creation
);
2874 json_object_object_get_ex(
2875 json
, ifp
->name
, &json_iface
);
2879 json_object_new_object();
2880 json_object_pim_ifp_add(
2882 json_object_object_add(
2887 json_row
= json_object_new_object();
2888 json_object_string_add(
2889 json_row
, "source", ifaddr_str
);
2890 json_object_string_add(
2891 json_row
, "group", group_str
);
2893 if (grp
->igmp_version
== 3)
2894 json_object_string_add(
2896 grp
->group_filtermode_isexcl
2900 json_object_string_add(json_row
,
2902 json_object_int_add(
2903 json_row
, "sourcesCount",
2904 grp
->group_source_list
2906 grp
->group_source_list
)
2908 json_object_int_add(json_row
, "version",
2910 json_object_string_add(
2911 json_row
, "uptime", uptime
);
2912 json_object_object_add(json_iface
,
2918 "%-9s %-15s %-15s %4s %8s %4d %d %8s\n",
2919 ifp
->name
, ifaddr_str
,
2921 grp
->igmp_version
== 3
2922 ? (grp
->group_filtermode_isexcl
2927 grp
->group_source_list
2929 grp
->group_source_list
)
2931 grp
->igmp_version
, uptime
);
2933 } /* scan igmp groups */
2934 } /* scan igmp sockets */
2935 } /* scan interfaces */
2938 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2939 json
, JSON_C_TO_STRING_PRETTY
));
2940 json_object_free(json
);
2944 static void igmp_show_group_retransmission(struct pim_instance
*pim
,
2947 struct interface
*ifp
;
2950 "Interface Address Group RetTimer Counter RetSrcs\n");
2952 /* scan interfaces */
2953 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2954 struct pim_interface
*pim_ifp
= ifp
->info
;
2955 struct listnode
*sock_node
;
2956 struct igmp_sock
*igmp
;
2961 /* scan igmp sockets */
2962 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
2964 char ifaddr_str
[INET_ADDRSTRLEN
];
2965 struct listnode
*grpnode
;
2966 struct igmp_group
*grp
;
2968 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
2969 sizeof(ifaddr_str
));
2971 /* scan igmp groups */
2972 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
2974 char group_str
[INET_ADDRSTRLEN
];
2975 char grp_retr_mmss
[10];
2976 struct listnode
*src_node
;
2977 struct igmp_source
*src
;
2978 int grp_retr_sources
= 0;
2980 pim_inet4_dump("<group?>", grp
->group_addr
,
2981 group_str
, sizeof(group_str
));
2982 pim_time_timer_to_mmss(
2983 grp_retr_mmss
, sizeof(grp_retr_mmss
),
2984 grp
->t_group_query_retransmit_timer
);
2987 /* count group sources with retransmission state
2989 for (ALL_LIST_ELEMENTS_RO(
2990 grp
->group_source_list
, src_node
,
2992 if (src
->source_query_retransmit_count
2998 vty_out(vty
, "%-9s %-15s %-15s %-8s %7d %7d\n",
2999 ifp
->name
, ifaddr_str
, group_str
,
3001 grp
->group_specific_query_retransmit_count
,
3004 } /* scan igmp groups */
3005 } /* scan igmp sockets */
3006 } /* scan interfaces */
3009 static void igmp_show_sources(struct pim_instance
*pim
, struct vty
*vty
)
3011 struct interface
*ifp
;
3014 now
= pim_time_monotonic_sec();
3017 "Interface Address Group Source Timer Fwd Uptime \n");
3019 /* scan interfaces */
3020 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3021 struct pim_interface
*pim_ifp
= ifp
->info
;
3022 struct listnode
*sock_node
;
3023 struct igmp_sock
*igmp
;
3028 /* scan igmp sockets */
3029 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3031 char ifaddr_str
[INET_ADDRSTRLEN
];
3032 struct listnode
*grpnode
;
3033 struct igmp_group
*grp
;
3035 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3036 sizeof(ifaddr_str
));
3038 /* scan igmp groups */
3039 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3041 char group_str
[INET_ADDRSTRLEN
];
3042 struct listnode
*srcnode
;
3043 struct igmp_source
*src
;
3045 pim_inet4_dump("<group?>", grp
->group_addr
,
3046 group_str
, sizeof(group_str
));
3048 /* scan group sources */
3049 for (ALL_LIST_ELEMENTS_RO(
3050 grp
->group_source_list
, srcnode
,
3052 char source_str
[INET_ADDRSTRLEN
];
3057 "<source?>", src
->source_addr
,
3058 source_str
, sizeof(source_str
));
3060 pim_time_timer_to_mmss(
3062 src
->t_source_timer
);
3065 uptime
, sizeof(uptime
),
3066 now
- src
->source_creation
);
3069 "%-9s %-15s %-15s %-15s %5s %3s %8s\n",
3070 ifp
->name
, ifaddr_str
,
3071 group_str
, source_str
, mmss
,
3072 IGMP_SOURCE_TEST_FORWARDING(
3078 } /* scan group sources */
3079 } /* scan igmp groups */
3080 } /* scan igmp sockets */
3081 } /* scan interfaces */
3084 static void igmp_show_source_retransmission(struct pim_instance
*pim
,
3087 struct interface
*ifp
;
3090 "Interface Address Group Source Counter\n");
3092 /* scan interfaces */
3093 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3094 struct pim_interface
*pim_ifp
= ifp
->info
;
3095 struct listnode
*sock_node
;
3096 struct igmp_sock
*igmp
;
3101 /* scan igmp sockets */
3102 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3104 char ifaddr_str
[INET_ADDRSTRLEN
];
3105 struct listnode
*grpnode
;
3106 struct igmp_group
*grp
;
3108 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3109 sizeof(ifaddr_str
));
3111 /* scan igmp groups */
3112 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3114 char group_str
[INET_ADDRSTRLEN
];
3115 struct listnode
*srcnode
;
3116 struct igmp_source
*src
;
3118 pim_inet4_dump("<group?>", grp
->group_addr
,
3119 group_str
, sizeof(group_str
));
3121 /* scan group sources */
3122 for (ALL_LIST_ELEMENTS_RO(
3123 grp
->group_source_list
, srcnode
,
3125 char source_str
[INET_ADDRSTRLEN
];
3128 "<source?>", src
->source_addr
,
3129 source_str
, sizeof(source_str
));
3132 "%-9s %-15s %-15s %-15s %7d\n",
3133 ifp
->name
, ifaddr_str
,
3134 group_str
, source_str
,
3135 src
->source_query_retransmit_count
);
3137 } /* scan group sources */
3138 } /* scan igmp groups */
3139 } /* scan igmp sockets */
3140 } /* scan interfaces */
3143 static void clear_igmp_interfaces(struct pim_instance
*pim
)
3145 struct interface
*ifp
;
3147 FOR_ALL_INTERFACES (pim
->vrf
, ifp
)
3148 pim_if_addr_del_all_igmp(ifp
);
3150 FOR_ALL_INTERFACES (pim
->vrf
, ifp
)
3151 pim_if_addr_add_all(ifp
);
3154 static void clear_pim_interfaces(struct pim_instance
*pim
)
3156 struct interface
*ifp
;
3158 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3160 pim_neighbor_delete_all(ifp
, "interface cleared");
3165 static void clear_interfaces(struct pim_instance
*pim
)
3167 clear_igmp_interfaces(pim
);
3168 clear_pim_interfaces(pim
);
3171 #define PIM_GET_PIM_INTERFACE(pim_ifp, ifp) \
3172 pim_ifp = ifp->info; \
3175 "%% Enable PIM and/or IGMP on this interface first\n"); \
3176 return CMD_WARNING_CONFIG_FAILED; \
3179 DEFUN (clear_ip_interfaces
,
3180 clear_ip_interfaces_cmd
,
3181 "clear ip interfaces [vrf NAME]",
3184 "Reset interfaces\n"
3188 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3193 clear_interfaces(vrf
->info
);
3198 DEFUN (clear_ip_igmp_interfaces
,
3199 clear_ip_igmp_interfaces_cmd
,
3200 "clear ip igmp [vrf NAME] interfaces",
3205 "Reset IGMP interfaces\n")
3208 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3213 clear_igmp_interfaces(vrf
->info
);
3218 static void mroute_add_all(struct pim_instance
*pim
)
3220 struct listnode
*node
;
3221 struct channel_oil
*c_oil
;
3223 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
3224 if (pim_mroute_add(c_oil
, __PRETTY_FUNCTION__
)) {
3225 /* just log warning */
3226 char source_str
[INET_ADDRSTRLEN
];
3227 char group_str
[INET_ADDRSTRLEN
];
3228 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
,
3229 source_str
, sizeof(source_str
));
3230 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
,
3231 group_str
, sizeof(group_str
));
3232 zlog_warn("%s %s: (S,G)=(%s,%s) failure writing MFC",
3233 __FILE__
, __PRETTY_FUNCTION__
, source_str
,
3239 static void mroute_del_all(struct pim_instance
*pim
)
3241 struct listnode
*node
;
3242 struct channel_oil
*c_oil
;
3244 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
3245 if (pim_mroute_del(c_oil
, __PRETTY_FUNCTION__
)) {
3246 /* just log warning */
3247 char source_str
[INET_ADDRSTRLEN
];
3248 char group_str
[INET_ADDRSTRLEN
];
3249 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
,
3250 source_str
, sizeof(source_str
));
3251 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
,
3252 group_str
, sizeof(group_str
));
3253 zlog_warn("%s %s: (S,G)=(%s,%s) failure clearing MFC",
3254 __FILE__
, __PRETTY_FUNCTION__
, source_str
,
3260 DEFUN (clear_ip_mroute
,
3261 clear_ip_mroute_cmd
,
3262 "clear ip mroute [vrf NAME]",
3265 "Reset multicast routes\n"
3269 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3274 mroute_del_all(vrf
->info
);
3275 mroute_add_all(vrf
->info
);
3280 DEFUN (clear_ip_pim_interfaces
,
3281 clear_ip_pim_interfaces_cmd
,
3282 "clear ip pim [vrf NAME] interfaces",
3287 "Reset PIM interfaces\n")
3290 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3295 clear_pim_interfaces(vrf
->info
);
3300 DEFUN (clear_ip_pim_interface_traffic
,
3301 clear_ip_pim_interface_traffic_cmd
,
3302 "clear ip pim [vrf NAME] interface traffic",
3305 "PIM clear commands\n"
3307 "Reset PIM interfaces\n"
3308 "Reset Protocol Packet counters\n")
3311 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3312 struct interface
*ifp
= NULL
;
3313 struct pim_interface
*pim_ifp
= NULL
;
3318 FOR_ALL_INTERFACES (vrf
, ifp
) {
3319 pim_ifp
= ifp
->info
;
3324 pim_ifp
->pim_ifstat_hello_recv
= 0;
3325 pim_ifp
->pim_ifstat_hello_sent
= 0;
3326 pim_ifp
->pim_ifstat_join_recv
= 0;
3327 pim_ifp
->pim_ifstat_join_send
= 0;
3328 pim_ifp
->pim_ifstat_prune_recv
= 0;
3329 pim_ifp
->pim_ifstat_prune_send
= 0;
3330 pim_ifp
->pim_ifstat_reg_recv
= 0;
3331 pim_ifp
->pim_ifstat_reg_send
= 0;
3332 pim_ifp
->pim_ifstat_reg_stop_recv
= 0;
3333 pim_ifp
->pim_ifstat_reg_stop_send
= 0;
3334 pim_ifp
->pim_ifstat_assert_recv
= 0;
3335 pim_ifp
->pim_ifstat_assert_send
= 0;
3341 DEFUN (clear_ip_pim_oil
,
3342 clear_ip_pim_oil_cmd
,
3343 "clear ip pim [vrf NAME] oil",
3348 "Rescan PIM OIL (output interface list)\n")
3351 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3356 pim_scan_oil(vrf
->info
);
3361 DEFUN (show_ip_igmp_interface
,
3362 show_ip_igmp_interface_cmd
,
3363 "show ip igmp [vrf NAME] interface [detail|WORD] [json]",
3368 "IGMP interface information\n"
3374 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3375 bool uj
= use_json(argc
, argv
);
3380 if (argv_find(argv
, argc
, "detail", &idx
)
3381 || argv_find(argv
, argc
, "WORD", &idx
))
3382 igmp_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
3384 igmp_show_interfaces(vrf
->info
, vty
, uj
);
3389 DEFUN (show_ip_igmp_interface_vrf_all
,
3390 show_ip_igmp_interface_vrf_all_cmd
,
3391 "show ip igmp vrf all interface [detail|WORD] [json]",
3396 "IGMP interface information\n"
3402 bool uj
= use_json(argc
, argv
);
3408 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3412 vty_out(vty
, " \"%s\": ", vrf
->name
);
3415 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3416 if (argv_find(argv
, argc
, "detail", &idx
)
3417 || argv_find(argv
, argc
, "WORD", &idx
))
3418 igmp_show_interfaces_single(vrf
->info
, vty
,
3419 argv
[idx
]->arg
, uj
);
3421 igmp_show_interfaces(vrf
->info
, vty
, uj
);
3424 vty_out(vty
, "}\n");
3429 DEFUN (show_ip_igmp_join
,
3430 show_ip_igmp_join_cmd
,
3431 "show ip igmp [vrf NAME] join",
3436 "IGMP static join information\n")
3439 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3444 igmp_show_interface_join(vrf
->info
, vty
);
3449 DEFUN (show_ip_igmp_join_vrf_all
,
3450 show_ip_igmp_join_vrf_all_cmd
,
3451 "show ip igmp vrf all join",
3456 "IGMP static join information\n")
3458 bool uj
= use_json(argc
, argv
);
3464 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3468 vty_out(vty
, " \"%s\": ", vrf
->name
);
3471 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3472 igmp_show_interface_join(vrf
->info
, vty
);
3475 vty_out(vty
, "}\n");
3480 DEFUN (show_ip_igmp_groups
,
3481 show_ip_igmp_groups_cmd
,
3482 "show ip igmp [vrf NAME] groups [json]",
3491 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3492 bool uj
= use_json(argc
, argv
);
3497 igmp_show_groups(vrf
->info
, vty
, uj
);
3502 DEFUN (show_ip_igmp_groups_vrf_all
,
3503 show_ip_igmp_groups_vrf_all_cmd
,
3504 "show ip igmp vrf all groups [json]",
3512 bool uj
= use_json(argc
, argv
);
3518 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3522 vty_out(vty
, " \"%s\": ", vrf
->name
);
3525 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3526 igmp_show_groups(vrf
->info
, vty
, uj
);
3529 vty_out(vty
, "}\n");
3534 DEFUN (show_ip_igmp_groups_retransmissions
,
3535 show_ip_igmp_groups_retransmissions_cmd
,
3536 "show ip igmp [vrf NAME] groups retransmissions",
3542 "IGMP group retransmissions\n")
3545 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3550 igmp_show_group_retransmission(vrf
->info
, vty
);
3555 DEFUN (show_ip_igmp_sources
,
3556 show_ip_igmp_sources_cmd
,
3557 "show ip igmp [vrf NAME] sources",
3565 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3570 igmp_show_sources(vrf
->info
, vty
);
3575 DEFUN (show_ip_igmp_sources_retransmissions
,
3576 show_ip_igmp_sources_retransmissions_cmd
,
3577 "show ip igmp [vrf NAME] sources retransmissions",
3583 "IGMP source retransmissions\n")
3586 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3591 igmp_show_source_retransmission(vrf
->info
, vty
);
3596 DEFUN (show_ip_igmp_statistics
,
3597 show_ip_igmp_statistics_cmd
,
3598 "show ip igmp [vrf NAME] statistics [interface WORD] [json]",
3609 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3610 bool uj
= use_json(argc
, argv
);
3615 if (argv_find(argv
, argc
, "WORD", &idx
))
3616 igmp_show_statistics(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
3618 igmp_show_statistics(vrf
->info
, vty
, NULL
, uj
);
3623 DEFUN (show_ip_pim_assert
,
3624 show_ip_pim_assert_cmd
,
3625 "show ip pim [vrf NAME] assert",
3630 "PIM interface assert\n")
3633 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3638 pim_show_assert(vrf
->info
, vty
);
3643 DEFUN (show_ip_pim_assert_internal
,
3644 show_ip_pim_assert_internal_cmd
,
3645 "show ip pim [vrf NAME] assert-internal",
3650 "PIM interface internal assert state\n")
3653 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3658 pim_show_assert_internal(vrf
->info
, vty
);
3663 DEFUN (show_ip_pim_assert_metric
,
3664 show_ip_pim_assert_metric_cmd
,
3665 "show ip pim [vrf NAME] assert-metric",
3670 "PIM interface assert metric\n")
3673 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3678 pim_show_assert_metric(vrf
->info
, vty
);
3683 DEFUN (show_ip_pim_assert_winner_metric
,
3684 show_ip_pim_assert_winner_metric_cmd
,
3685 "show ip pim [vrf NAME] assert-winner-metric",
3690 "PIM interface assert winner metric\n")
3693 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3698 pim_show_assert_winner_metric(vrf
->info
, vty
);
3703 DEFUN (show_ip_pim_interface
,
3704 show_ip_pim_interface_cmd
,
3705 "show ip pim [vrf NAME] interface [detail|WORD] [json]",
3710 "PIM interface information\n"
3716 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3717 bool uj
= use_json(argc
, argv
);
3722 if (argv_find(argv
, argc
, "WORD", &idx
)
3723 || argv_find(argv
, argc
, "detail", &idx
))
3724 pim_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
3726 pim_show_interfaces(vrf
->info
, vty
, uj
);
3731 DEFUN (show_ip_pim_interface_vrf_all
,
3732 show_ip_pim_interface_vrf_all_cmd
,
3733 "show ip pim vrf all interface [detail|WORD] [json]",
3738 "PIM interface information\n"
3744 bool uj
= use_json(argc
, argv
);
3750 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3754 vty_out(vty
, " \"%s\": ", vrf
->name
);
3757 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3758 if (argv_find(argv
, argc
, "WORD", &idx
)
3759 || argv_find(argv
, argc
, "detail", &idx
))
3760 pim_show_interfaces_single(vrf
->info
, vty
,
3761 argv
[idx
]->arg
, uj
);
3763 pim_show_interfaces(vrf
->info
, vty
, uj
);
3766 vty_out(vty
, "}\n");
3771 DEFUN (show_ip_pim_join
,
3772 show_ip_pim_join_cmd
,
3773 "show ip pim [vrf NAME] join [json]",
3778 "PIM interface join information\n"
3782 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3783 bool uj
= use_json(argc
, argv
);
3788 pim_show_join(vrf
->info
, vty
, uj
);
3793 DEFUN (show_ip_pim_join_vrf_all
,
3794 show_ip_pim_join_vrf_all_cmd
,
3795 "show ip pim vrf all join [json]",
3800 "PIM interface join information\n"
3803 bool uj
= use_json(argc
, argv
);
3809 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3813 vty_out(vty
, " \"%s\": ", vrf
->name
);
3816 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3817 pim_show_join(vrf
->info
, vty
, uj
);
3820 vty_out(vty
, "}\n");
3825 DEFUN (show_ip_pim_local_membership
,
3826 show_ip_pim_local_membership_cmd
,
3827 "show ip pim [vrf NAME] local-membership [json]",
3832 "PIM interface local-membership\n"
3836 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3837 bool uj
= use_json(argc
, argv
);
3842 pim_show_membership(vrf
->info
, vty
, uj
);
3847 DEFUN (show_ip_pim_neighbor
,
3848 show_ip_pim_neighbor_cmd
,
3849 "show ip pim [vrf NAME] neighbor [detail|WORD] [json]",
3854 "PIM neighbor information\n"
3856 "Name of interface or neighbor\n"
3860 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3861 bool uj
= use_json(argc
, argv
);
3866 if (argv_find(argv
, argc
, "detail", &idx
)
3867 || argv_find(argv
, argc
, "WORD", &idx
))
3868 pim_show_neighbors_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
3870 pim_show_neighbors(vrf
->info
, vty
, uj
);
3875 DEFUN (show_ip_pim_neighbor_vrf_all
,
3876 show_ip_pim_neighbor_vrf_all_cmd
,
3877 "show ip pim vrf all neighbor [detail|WORD] [json]",
3882 "PIM neighbor information\n"
3884 "Name of interface or neighbor\n"
3888 bool uj
= use_json(argc
, argv
);
3894 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3898 vty_out(vty
, " \"%s\": ", vrf
->name
);
3901 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3902 if (argv_find(argv
, argc
, "detail", &idx
)
3903 || argv_find(argv
, argc
, "WORD", &idx
))
3904 pim_show_neighbors_single(vrf
->info
, vty
,
3905 argv
[idx
]->arg
, uj
);
3907 pim_show_neighbors(vrf
->info
, vty
, uj
);
3910 vty_out(vty
, "}\n");
3915 DEFUN (show_ip_pim_secondary
,
3916 show_ip_pim_secondary_cmd
,
3917 "show ip pim [vrf NAME] secondary",
3922 "PIM neighbor addresses\n")
3925 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3930 pim_show_neighbors_secondary(vrf
->info
, vty
);
3935 DEFUN (show_ip_pim_state
,
3936 show_ip_pim_state_cmd
,
3937 "show ip pim [vrf NAME] state [A.B.C.D [A.B.C.D]] [json]",
3942 "PIM state information\n"
3943 "Unicast or Multicast address\n"
3944 "Multicast address\n"
3947 const char *src_or_group
= NULL
;
3948 const char *group
= NULL
;
3950 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3951 bool uj
= use_json(argc
, argv
);
3959 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
3960 src_or_group
= argv
[idx
]->arg
;
3962 group
= argv
[idx
+ 1]->arg
;
3965 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
3970 DEFUN (show_ip_pim_state_vrf_all
,
3971 show_ip_pim_state_vrf_all_cmd
,
3972 "show ip pim vrf all state [A.B.C.D [A.B.C.D]] [json]",
3977 "PIM state information\n"
3978 "Unicast or Multicast address\n"
3979 "Multicast address\n"
3982 const char *src_or_group
= NULL
;
3983 const char *group
= NULL
;
3985 bool uj
= use_json(argc
, argv
);
3994 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
3995 src_or_group
= argv
[idx
]->arg
;
3997 group
= argv
[idx
+ 1]->arg
;
4000 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4004 vty_out(vty
, " \"%s\": ", vrf
->name
);
4007 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4008 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
4011 vty_out(vty
, "}\n");
4016 DEFUN (show_ip_pim_upstream
,
4017 show_ip_pim_upstream_cmd
,
4018 "show ip pim [vrf NAME] upstream [json]",
4023 "PIM upstream information\n"
4027 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4028 bool uj
= use_json(argc
, argv
);
4033 pim_show_upstream(vrf
->info
, vty
, uj
);
4038 DEFUN (show_ip_pim_upstream_vrf_all
,
4039 show_ip_pim_upstream_vrf_all_cmd
,
4040 "show ip pim vrf all upstream [json]",
4045 "PIM upstream information\n"
4048 bool uj
= use_json(argc
, argv
);
4054 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4058 vty_out(vty
, " \"%s\": ", vrf
->name
);
4061 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4062 pim_show_upstream(vrf
->info
, vty
, uj
);
4068 DEFUN (show_ip_pim_upstream_join_desired
,
4069 show_ip_pim_upstream_join_desired_cmd
,
4070 "show ip pim [vrf NAME] upstream-join-desired [json]",
4075 "PIM upstream join-desired\n"
4079 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4080 bool uj
= use_json(argc
, argv
);
4085 pim_show_join_desired(vrf
->info
, vty
, uj
);
4090 DEFUN (show_ip_pim_upstream_rpf
,
4091 show_ip_pim_upstream_rpf_cmd
,
4092 "show ip pim [vrf NAME] upstream-rpf [json]",
4097 "PIM upstream source rpf\n"
4101 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4102 bool uj
= use_json(argc
, argv
);
4107 pim_show_upstream_rpf(vrf
->info
, vty
, uj
);
4112 DEFUN (show_ip_pim_rp
,
4114 "show ip pim [vrf NAME] rp-info [json]",
4119 "PIM RP information\n"
4123 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4124 bool uj
= use_json(argc
, argv
);
4129 pim_rp_show_information(vrf
->info
, vty
, uj
);
4134 DEFUN (show_ip_pim_rp_vrf_all
,
4135 show_ip_pim_rp_vrf_all_cmd
,
4136 "show ip pim vrf all rp-info [json]",
4141 "PIM RP information\n"
4144 bool uj
= use_json(argc
, argv
);
4150 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4154 vty_out(vty
, " \"%s\": ", vrf
->name
);
4157 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4158 pim_rp_show_information(vrf
->info
, vty
, uj
);
4161 vty_out(vty
, "}\n");
4166 DEFUN (show_ip_pim_rpf
,
4167 show_ip_pim_rpf_cmd
,
4168 "show ip pim [vrf NAME] rpf [json]",
4173 "PIM cached source rpf information\n"
4177 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4178 bool uj
= use_json(argc
, argv
);
4183 pim_show_rpf(vrf
->info
, vty
, uj
);
4188 DEFUN (show_ip_pim_rpf_vrf_all
,
4189 show_ip_pim_rpf_vrf_all_cmd
,
4190 "show ip pim vrf all rpf [json]",
4195 "PIM cached source rpf information\n"
4198 bool uj
= use_json(argc
, argv
);
4204 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4208 vty_out(vty
, " \"%s\": ", vrf
->name
);
4211 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4212 pim_show_rpf(vrf
->info
, vty
, uj
);
4215 vty_out(vty
, "}\n");
4220 DEFUN (show_ip_pim_nexthop
,
4221 show_ip_pim_nexthop_cmd
,
4222 "show ip pim [vrf NAME] nexthop",
4227 "PIM cached nexthop rpf information\n")
4230 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4235 pim_show_nexthop(vrf
->info
, vty
);
4240 DEFUN (show_ip_pim_nexthop_lookup
,
4241 show_ip_pim_nexthop_lookup_cmd
,
4242 "show ip pim [vrf NAME] nexthop-lookup A.B.C.D A.B.C.D",
4247 "PIM cached nexthop rpf lookup\n"
4248 "Source/RP address\n"
4249 "Multicast Group address\n")
4251 struct pim_nexthop_cache
*pnc
= NULL
;
4252 struct prefix nht_p
;
4254 struct in_addr src_addr
, grp_addr
;
4255 struct in_addr vif_source
;
4256 const char *addr_str
, *addr_str1
;
4258 struct pim_nexthop nexthop
;
4259 char nexthop_addr_str
[PREFIX_STRLEN
];
4260 char grp_str
[PREFIX_STRLEN
];
4262 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4268 argv_find(argv
, argc
, "A.B.C.D", &idx
);
4269 addr_str
= argv
[idx
]->arg
;
4270 result
= inet_pton(AF_INET
, addr_str
, &src_addr
);
4272 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
4273 errno
, safe_strerror(errno
));
4277 if (pim_is_group_224_4(src_addr
)) {
4279 "Invalid argument. Expected Valid Source Address.\n");
4283 addr_str1
= argv
[idx
+ 1]->arg
;
4284 result
= inet_pton(AF_INET
, addr_str1
, &grp_addr
);
4286 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
4287 errno
, safe_strerror(errno
));
4291 if (!pim_is_group_224_4(grp_addr
)) {
4293 "Invalid argument. Expected Valid Multicast Group Address.\n");
4297 if (!pim_rp_set_upstream_addr(vrf
->info
, &vif_source
, src_addr
,
4301 nht_p
.family
= AF_INET
;
4302 nht_p
.prefixlen
= IPV4_MAX_BITLEN
;
4303 nht_p
.u
.prefix4
= vif_source
;
4304 grp
.family
= AF_INET
;
4305 grp
.prefixlen
= IPV4_MAX_BITLEN
;
4306 grp
.u
.prefix4
= grp_addr
;
4307 memset(&nexthop
, 0, sizeof(nexthop
));
4309 memset(&rpf
, 0, sizeof(struct pim_rpf
));
4310 rpf
.rpf_addr
.family
= AF_INET
;
4311 rpf
.rpf_addr
.prefixlen
= IPV4_MAX_BITLEN
;
4312 rpf
.rpf_addr
.u
.prefix4
= vif_source
;
4314 pnc
= pim_nexthop_cache_find(vrf
->info
, &rpf
);
4316 result
= pim_ecmp_nexthop_search(vrf
->info
, pnc
, &nexthop
,
4319 result
= pim_ecmp_nexthop_lookup(vrf
->info
, &nexthop
, &nht_p
,
4324 "Nexthop Lookup failed, no usable routes returned.\n");
4328 pim_addr_dump("<grp?>", &grp
, grp_str
, sizeof(grp_str
));
4329 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
4330 nexthop_addr_str
, sizeof(nexthop_addr_str
));
4331 vty_out(vty
, "Group %s --- Nexthop %s Interface %s \n", grp_str
,
4332 nexthop_addr_str
, nexthop
.interface
->name
);
4337 DEFUN (show_ip_pim_interface_traffic
,
4338 show_ip_pim_interface_traffic_cmd
,
4339 "show ip pim [vrf NAME] interface traffic [WORD] [json]",
4344 "PIM interface information\n"
4345 "Protocol Packet counters\n"
4350 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4351 bool uj
= use_json(argc
, argv
);
4356 if (argv_find(argv
, argc
, "WORD", &idx
))
4357 pim_show_interface_traffic_single(vrf
->info
, vty
,
4358 argv
[idx
]->arg
, uj
);
4360 pim_show_interface_traffic(vrf
->info
, vty
, uj
);
4365 static void show_multicast_interfaces(struct pim_instance
*pim
, struct vty
*vty
)
4367 struct interface
*ifp
;
4372 "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut\n");
4374 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
4375 struct pim_interface
*pim_ifp
;
4376 struct in_addr ifaddr
;
4377 struct sioc_vif_req vreq
;
4379 pim_ifp
= ifp
->info
;
4384 memset(&vreq
, 0, sizeof(vreq
));
4385 vreq
.vifi
= pim_ifp
->mroute_vif_index
;
4387 if (ioctl(pim
->mroute_socket
, SIOCGETVIFCNT
, &vreq
)) {
4389 "ioctl(SIOCGETVIFCNT=%lu) failure for interface %s vif_index=%d: errno=%d: %s",
4390 (unsigned long)SIOCGETVIFCNT
, ifp
->name
,
4391 pim_ifp
->mroute_vif_index
, errno
,
4392 safe_strerror(errno
));
4395 ifaddr
= pim_ifp
->primary_address
;
4397 vty_out(vty
, "%-12s %-15s %3d %3d %7lu %7lu %10lu %10lu\n",
4398 ifp
->name
, inet_ntoa(ifaddr
), ifp
->ifindex
,
4399 pim_ifp
->mroute_vif_index
, (unsigned long)vreq
.icount
,
4400 (unsigned long)vreq
.ocount
, (unsigned long)vreq
.ibytes
,
4401 (unsigned long)vreq
.obytes
);
4405 static void pim_cmd_show_ip_multicast_helper(struct pim_instance
*pim
,
4408 struct vrf
*vrf
= pim
->vrf
;
4409 time_t now
= pim_time_monotonic_sec();
4414 vty_out(vty
, "Mroute socket descriptor:");
4416 vty_out(vty
, " %d(%s)\n", pim
->mroute_socket
, vrf
->name
);
4418 pim_time_uptime(uptime
, sizeof(uptime
),
4419 now
- pim
->mroute_socket_creation
);
4420 vty_out(vty
, "Mroute socket uptime: %s\n", uptime
);
4424 pim_zebra_zclient_update(vty
);
4425 pim_zlookup_show_ip_multicast(vty
);
4428 vty_out(vty
, "Maximum highest VifIndex: %d\n", PIM_MAX_USABLE_VIFS
);
4431 vty_out(vty
, "Upstream Join Timer: %d secs\n", qpim_t_periodic
);
4432 vty_out(vty
, "Join/Prune Holdtime: %d secs\n", PIM_JP_HOLDTIME
);
4433 vty_out(vty
, "PIM ECMP: %s\n", pim
->ecmp_enable
? "Enable" : "Disable");
4434 vty_out(vty
, "PIM ECMP Rebalance: %s\n",
4435 pim
->ecmp_rebalance_enable
? "Enable" : "Disable");
4439 show_rpf_refresh_stats(vty
, pim
, now
, NULL
);
4443 show_scan_oil_stats(pim
, vty
, now
);
4445 show_multicast_interfaces(pim
, vty
);
4448 DEFUN (show_ip_multicast
,
4449 show_ip_multicast_cmd
,
4450 "show ip multicast [vrf NAME]",
4454 "Multicast global information\n")
4457 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4462 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
4467 DEFUN (show_ip_multicast_vrf_all
,
4468 show_ip_multicast_vrf_all_cmd
,
4469 "show ip multicast vrf all",
4473 "Multicast global information\n")
4475 bool uj
= use_json(argc
, argv
);
4481 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4485 vty_out(vty
, " \"%s\": ", vrf
->name
);
4488 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4489 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
4492 vty_out(vty
, "}\n");
4497 static void show_mroute(struct pim_instance
*pim
, struct vty
*vty
, bool fill
,
4500 struct listnode
*node
;
4501 struct channel_oil
*c_oil
;
4502 struct static_route
*s_route
;
4504 json_object
*json
= NULL
;
4505 json_object
*json_group
= NULL
;
4506 json_object
*json_source
= NULL
;
4507 json_object
*json_oil
= NULL
;
4508 json_object
*json_ifp_out
= NULL
;
4511 char grp_str
[INET_ADDRSTRLEN
];
4512 char src_str
[INET_ADDRSTRLEN
];
4513 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
4514 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
4516 struct interface
*ifp_in
;
4520 json
= json_object_new_object();
4523 "Source Group Proto Input Output TTL Uptime\n");
4526 now
= pim_time_monotonic_sec();
4528 /* print list of PIM and IGMP routes */
4529 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
4532 if (!c_oil
->installed
&& !uj
)
4535 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
4537 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
4539 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
4542 strcpy(in_ifname
, ifp_in
->name
);
4544 strcpy(in_ifname
, "<iif?>");
4548 /* Find the group, create it if it doesn't exist */
4549 json_object_object_get_ex(json
, grp_str
, &json_group
);
4552 json_group
= json_object_new_object();
4553 json_object_object_add(json
, grp_str
,
4557 /* Find the source nested under the group, create it if
4558 * it doesn't exist */
4559 json_object_object_get_ex(json_group
, src_str
,
4563 json_source
= json_object_new_object();
4564 json_object_object_add(json_group
, src_str
,
4568 /* Find the inbound interface nested under the source,
4569 * create it if it doesn't exist */
4570 json_object_int_add(json_source
, "installed",
4572 json_object_int_add(json_source
, "refCount",
4573 c_oil
->oil_ref_count
);
4574 json_object_int_add(json_source
, "oilSize",
4576 json_object_int_add(json_source
, "OilInheritedRescan",
4577 c_oil
->oil_inherited_rescan
);
4578 json_object_string_add(json_source
, "iif", in_ifname
);
4582 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
4584 struct interface
*ifp_out
;
4585 char oif_uptime
[10];
4588 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
4592 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
4594 oif_uptime
, sizeof(oif_uptime
),
4595 now
- c_oil
->oif_creation
[oif_vif_index
]);
4599 strcpy(out_ifname
, ifp_out
->name
);
4601 strcpy(out_ifname
, "<oif?>");
4604 json_ifp_out
= json_object_new_object();
4605 json_object_string_add(json_ifp_out
, "source",
4607 json_object_string_add(json_ifp_out
, "group",
4610 if (c_oil
->oif_flags
[oif_vif_index
]
4611 & PIM_OIF_FLAG_PROTO_PIM
)
4612 json_object_boolean_true_add(
4613 json_ifp_out
, "protocolPim");
4615 if (c_oil
->oif_flags
[oif_vif_index
]
4616 & PIM_OIF_FLAG_PROTO_IGMP
)
4617 json_object_boolean_true_add(
4618 json_ifp_out
, "protocolIgmp");
4620 if (c_oil
->oif_flags
[oif_vif_index
]
4621 & PIM_OIF_FLAG_PROTO_SOURCE
)
4622 json_object_boolean_true_add(
4623 json_ifp_out
, "protocolSource");
4625 if (c_oil
->oif_flags
[oif_vif_index
]
4626 & PIM_OIF_FLAG_PROTO_STAR
)
4627 json_object_boolean_true_add(
4629 "protocolInherited");
4631 json_object_string_add(json_ifp_out
,
4634 json_object_int_add(json_ifp_out
, "iVifI",
4635 c_oil
->oil
.mfcc_parent
);
4636 json_object_string_add(json_ifp_out
,
4637 "outboundInterface",
4639 json_object_int_add(json_ifp_out
, "oVifI",
4641 json_object_int_add(json_ifp_out
, "ttl", ttl
);
4642 json_object_string_add(json_ifp_out
, "upTime",
4645 json_oil
= json_object_new_object();
4646 json_object_object_add(json_source
,
4649 json_object_object_add(json_oil
, out_ifname
,
4652 if (c_oil
->oif_flags
[oif_vif_index
]
4653 & PIM_OIF_FLAG_PROTO_PIM
) {
4654 strcpy(proto
, "PIM");
4657 if (c_oil
->oif_flags
[oif_vif_index
]
4658 & PIM_OIF_FLAG_PROTO_IGMP
) {
4659 strcpy(proto
, "IGMP");
4662 if (c_oil
->oif_flags
[oif_vif_index
]
4663 & PIM_OIF_FLAG_PROTO_SOURCE
) {
4664 strcpy(proto
, "SRC");
4667 if (c_oil
->oif_flags
[oif_vif_index
]
4668 & PIM_OIF_FLAG_PROTO_STAR
) {
4669 strcpy(proto
, "STAR");
4673 "%-15s %-15s %-6s %-10s %-10s %-3d %8s\n",
4674 src_str
, grp_str
, proto
, in_ifname
,
4675 out_ifname
, ttl
, oif_uptime
);
4680 in_ifname
[0] = '\0';
4686 if (!uj
&& !found_oif
) {
4687 vty_out(vty
, "%-15s %-15s %-6s %-10s %-10s %-3d %8s\n",
4688 src_str
, grp_str
, "none", in_ifname
, "none", 0,
4693 /* Print list of static routes */
4694 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
4697 if (!s_route
->c_oil
.installed
)
4700 pim_inet4_dump("<group?>", s_route
->group
, grp_str
,
4702 pim_inet4_dump("<source?>", s_route
->source
, src_str
,
4704 ifp_in
= pim_if_find_by_vif_index(pim
, s_route
->iif
);
4708 strcpy(in_ifname
, ifp_in
->name
);
4710 strcpy(in_ifname
, "<iif?>");
4714 /* Find the group, create it if it doesn't exist */
4715 json_object_object_get_ex(json
, grp_str
, &json_group
);
4718 json_group
= json_object_new_object();
4719 json_object_object_add(json
, grp_str
,
4723 /* Find the source nested under the group, create it if
4724 * it doesn't exist */
4725 json_object_object_get_ex(json_group
, src_str
,
4729 json_source
= json_object_new_object();
4730 json_object_object_add(json_group
, src_str
,
4734 json_object_string_add(json_source
, "iif", in_ifname
);
4737 strcpy(proto
, "STATIC");
4740 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
4742 struct interface
*ifp_out
;
4743 char oif_uptime
[10];
4746 ttl
= s_route
->oif_ttls
[oif_vif_index
];
4750 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
4752 oif_uptime
, sizeof(oif_uptime
),
4755 .oif_creation
[oif_vif_index
]);
4759 strcpy(out_ifname
, ifp_out
->name
);
4761 strcpy(out_ifname
, "<oif?>");
4764 json_ifp_out
= json_object_new_object();
4765 json_object_string_add(json_ifp_out
, "source",
4767 json_object_string_add(json_ifp_out
, "group",
4769 json_object_boolean_true_add(json_ifp_out
,
4771 json_object_string_add(json_ifp_out
,
4774 json_object_int_add(
4775 json_ifp_out
, "iVifI",
4776 s_route
->c_oil
.oil
.mfcc_parent
);
4777 json_object_string_add(json_ifp_out
,
4778 "outboundInterface",
4780 json_object_int_add(json_ifp_out
, "oVifI",
4782 json_object_int_add(json_ifp_out
, "ttl", ttl
);
4783 json_object_string_add(json_ifp_out
, "upTime",
4786 json_oil
= json_object_new_object();
4787 json_object_object_add(json_source
,
4790 json_object_object_add(json_oil
, out_ifname
,
4794 "%-15s %-15s %-6s %-10s %-10s %-3d %8s %s\n",
4795 src_str
, grp_str
, proto
, in_ifname
,
4796 out_ifname
, ttl
, oif_uptime
,
4798 if (first
&& !fill
) {
4801 in_ifname
[0] = '\0';
4807 if (!uj
&& !found_oif
) {
4809 "%-15s %-15s %-6s %-10s %-10s %-3d %8s %s\n",
4810 src_str
, grp_str
, proto
, in_ifname
, "none", 0,
4811 "--:--:--", pim
->vrf
->name
);
4816 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4817 json
, JSON_C_TO_STRING_PRETTY
));
4818 json_object_free(json
);
4822 DEFUN (show_ip_mroute
,
4824 "show ip mroute [vrf NAME] [fill] [json]",
4829 "Fill in Assumed data\n"
4832 bool uj
= use_json(argc
, argv
);
4835 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4840 if (argv_find(argv
, argc
, "fill", &idx
))
4843 show_mroute(vrf
->info
, vty
, fill
, uj
);
4847 DEFUN (show_ip_mroute_vrf_all
,
4848 show_ip_mroute_vrf_all_cmd
,
4849 "show ip mroute vrf all [fill] [json]",
4854 "Fill in Assumed data\n"
4857 bool uj
= use_json(argc
, argv
);
4863 if (argv_find(argv
, argc
, "fill", &idx
))
4868 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4872 vty_out(vty
, " \"%s\": ", vrf
->name
);
4875 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4876 show_mroute(vrf
->info
, vty
, fill
, uj
);
4879 vty_out(vty
, "}\n");
4884 static void show_mroute_count(struct pim_instance
*pim
, struct vty
*vty
)
4886 struct listnode
*node
;
4887 struct channel_oil
*c_oil
;
4888 struct static_route
*s_route
;
4893 "Source Group LastUsed Packets Bytes WrongIf \n");
4895 /* Print PIM and IGMP route counts */
4896 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
4897 char group_str
[INET_ADDRSTRLEN
];
4898 char source_str
[INET_ADDRSTRLEN
];
4900 if (!c_oil
->installed
)
4903 pim_mroute_update_counters(c_oil
);
4905 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, group_str
,
4907 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, source_str
,
4908 sizeof(source_str
));
4910 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
4911 source_str
, group_str
, c_oil
->cc
.lastused
/ 100,
4912 c_oil
->cc
.pktcnt
, c_oil
->cc
.bytecnt
,
4913 c_oil
->cc
.wrong_if
);
4916 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
4917 char group_str
[INET_ADDRSTRLEN
];
4918 char source_str
[INET_ADDRSTRLEN
];
4920 if (!s_route
->c_oil
.installed
)
4923 pim_mroute_update_counters(&s_route
->c_oil
);
4925 pim_inet4_dump("<group?>", s_route
->c_oil
.oil
.mfcc_mcastgrp
,
4926 group_str
, sizeof(group_str
));
4927 pim_inet4_dump("<source?>", s_route
->c_oil
.oil
.mfcc_origin
,
4928 source_str
, sizeof(source_str
));
4930 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
4931 source_str
, group_str
, s_route
->c_oil
.cc
.lastused
,
4932 s_route
->c_oil
.cc
.pktcnt
, s_route
->c_oil
.cc
.bytecnt
,
4933 s_route
->c_oil
.cc
.wrong_if
);
4937 DEFUN (show_ip_mroute_count
,
4938 show_ip_mroute_count_cmd
,
4939 "show ip mroute [vrf NAME] count",
4944 "Route and packet count data\n")
4947 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4952 show_mroute_count(vrf
->info
, vty
);
4956 DEFUN (show_ip_mroute_count_vrf_all
,
4957 show_ip_mroute_count_vrf_all_cmd
,
4958 "show ip mroute vrf all count",
4963 "Route and packet count data\n")
4965 bool uj
= use_json(argc
, argv
);
4971 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4975 vty_out(vty
, " \"%s\": ", vrf
->name
);
4978 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4979 show_mroute_count(vrf
->info
, vty
);
4982 vty_out(vty
, "}\n");
4989 "show ip rib [vrf NAME] A.B.C.D",
4994 "Unicast address\n")
4997 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4998 struct in_addr addr
;
4999 const char *addr_str
;
5000 struct pim_nexthop nexthop
;
5001 char nexthop_addr_str
[PREFIX_STRLEN
];
5007 memset(&nexthop
, 0, sizeof(nexthop
));
5008 argv_find(argv
, argc
, "A.B.C.D", &idx
);
5009 addr_str
= argv
[idx
]->arg
;
5010 result
= inet_pton(AF_INET
, addr_str
, &addr
);
5012 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
5013 errno
, safe_strerror(errno
));
5017 if (pim_nexthop_lookup(vrf
->info
, &nexthop
, addr
, 0)) {
5019 "Failure querying RIB nexthop for unicast address %s\n",
5025 "Address NextHop Interface Metric Preference\n");
5027 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
5028 nexthop_addr_str
, sizeof(nexthop_addr_str
));
5030 vty_out(vty
, "%-15s %-15s %-9s %6d %10d\n", addr_str
, nexthop_addr_str
,
5031 nexthop
.interface
? nexthop
.interface
->name
: "<ifname?>",
5032 nexthop
.mrib_route_metric
, nexthop
.mrib_metric_preference
);
5037 static void show_ssmpingd(struct pim_instance
*pim
, struct vty
*vty
)
5039 struct listnode
*node
;
5040 struct ssmpingd_sock
*ss
;
5044 "Source Socket Address Port Uptime Requests\n");
5046 if (!pim
->ssmpingd_list
)
5049 now
= pim_time_monotonic_sec();
5051 for (ALL_LIST_ELEMENTS_RO(pim
->ssmpingd_list
, node
, ss
)) {
5052 char source_str
[INET_ADDRSTRLEN
];
5054 struct sockaddr_in bind_addr
;
5055 socklen_t len
= sizeof(bind_addr
);
5056 char bind_addr_str
[INET_ADDRSTRLEN
];
5058 pim_inet4_dump("<src?>", ss
->source_addr
, source_str
,
5059 sizeof(source_str
));
5061 if (pim_socket_getsockname(
5062 ss
->sock_fd
, (struct sockaddr
*)&bind_addr
, &len
)) {
5064 "%% Failure reading socket name for ssmpingd source %s on fd=%d\n",
5065 source_str
, ss
->sock_fd
);
5068 pim_inet4_dump("<addr?>", bind_addr
.sin_addr
, bind_addr_str
,
5069 sizeof(bind_addr_str
));
5070 pim_time_uptime(ss_uptime
, sizeof(ss_uptime
),
5071 now
- ss
->creation
);
5073 vty_out(vty
, "%-15s %6d %-15s %5d %8s %8lld\n", source_str
,
5074 ss
->sock_fd
, bind_addr_str
, ntohs(bind_addr
.sin_port
),
5075 ss_uptime
, (long long)ss
->requests
);
5079 DEFUN (show_ip_ssmpingd
,
5080 show_ip_ssmpingd_cmd
,
5081 "show ip ssmpingd [vrf NAME]",
5088 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5093 show_ssmpingd(vrf
->info
, vty
);
5097 static int pim_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
5098 const char *rp
, const char *group
,
5103 result
= pim_rp_new(pim
, rp
, group
, plist
);
5105 if (result
== PIM_GROUP_BAD_ADDRESS
) {
5106 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
5107 return CMD_WARNING_CONFIG_FAILED
;
5110 if (result
== PIM_RP_BAD_ADDRESS
) {
5111 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
5112 return CMD_WARNING_CONFIG_FAILED
;
5115 if (result
== PIM_RP_NO_PATH
) {
5116 vty_out(vty
, "%% No Path to RP address specified: %s\n", rp
);
5120 if (result
== PIM_GROUP_OVERLAP
) {
5122 "%% Group range specified cannot exact match another\n");
5123 return CMD_WARNING_CONFIG_FAILED
;
5126 if (result
== PIM_GROUP_PFXLIST_OVERLAP
) {
5128 "%% This group is already covered by a RP prefix-list\n");
5129 return CMD_WARNING_CONFIG_FAILED
;
5132 if (result
== PIM_RP_PFXLIST_IN_USE
) {
5134 "%% The same prefix-list cannot be applied to multiple RPs\n");
5135 return CMD_WARNING_CONFIG_FAILED
;
5141 static int pim_cmd_spt_switchover(struct pim_instance
*pim
,
5142 enum pim_spt_switchover spt
,
5145 pim
->spt
.switchover
= spt
;
5147 switch (pim
->spt
.switchover
) {
5148 case PIM_SPT_IMMEDIATE
:
5150 XFREE(MTYPE_PIM_SPT_PLIST_NAME
, pim
->spt
.plist
);
5152 pim_upstream_add_lhr_star_pimreg(pim
);
5154 case PIM_SPT_INFINITY
:
5155 pim_upstream_remove_lhr_star_pimreg(pim
, plist
);
5158 XFREE(MTYPE_PIM_SPT_PLIST_NAME
, pim
->spt
.plist
);
5162 XSTRDUP(MTYPE_PIM_SPT_PLIST_NAME
, plist
);
5169 DEFUN (ip_pim_spt_switchover_infinity
,
5170 ip_pim_spt_switchover_infinity_cmd
,
5171 "ip pim spt-switchover infinity-and-beyond",
5175 "Never switch to SPT Tree\n")
5177 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5178 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, NULL
);
5181 DEFUN (ip_pim_spt_switchover_infinity_plist
,
5182 ip_pim_spt_switchover_infinity_plist_cmd
,
5183 "ip pim spt-switchover infinity-and-beyond prefix-list WORD",
5187 "Never switch to SPT Tree\n"
5188 "Prefix-List to control which groups to switch\n"
5189 "Prefix-List name\n")
5191 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5192 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, argv
[5]->arg
);
5195 DEFUN (no_ip_pim_spt_switchover_infinity
,
5196 no_ip_pim_spt_switchover_infinity_cmd
,
5197 "no ip pim spt-switchover infinity-and-beyond",
5202 "Never switch to SPT Tree\n")
5204 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5205 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
5208 DEFUN (no_ip_pim_spt_switchover_infinity_plist
,
5209 no_ip_pim_spt_switchover_infinity_plist_cmd
,
5210 "no ip pim spt-switchover infinity-and-beyond prefix-list WORD",
5215 "Never switch to SPT Tree\n"
5216 "Prefix-List to control which groups to switch\n"
5217 "Prefix-List name\n")
5219 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5220 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
5223 DEFUN (ip_pim_joinprune_time
,
5224 ip_pim_joinprune_time_cmd
,
5225 "ip pim join-prune-interval (60-600)",
5227 "pim multicast routing\n"
5228 "Join Prune Send Interval\n"
5231 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5232 qpim_t_periodic
= atoi(argv
[3]->arg
);
5236 DEFUN (no_ip_pim_joinprune_time
,
5237 no_ip_pim_joinprune_time_cmd
,
5238 "no ip pim join-prune-interval (60-600)",
5241 "pim multicast routing\n"
5242 "Join Prune Send Interval\n"
5245 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5246 qpim_t_periodic
= PIM_DEFAULT_T_PERIODIC
;
5250 DEFUN (ip_pim_register_suppress
,
5251 ip_pim_register_suppress_cmd
,
5252 "ip pim register-suppress-time (5-60000)",
5254 "pim multicast routing\n"
5255 "Register Suppress Timer\n"
5258 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5259 qpim_register_suppress_time
= atoi(argv
[3]->arg
);
5263 DEFUN (no_ip_pim_register_suppress
,
5264 no_ip_pim_register_suppress_cmd
,
5265 "no ip pim register-suppress-time (5-60000)",
5268 "pim multicast routing\n"
5269 "Register Suppress Timer\n"
5272 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5273 qpim_register_suppress_time
= PIM_REGISTER_SUPPRESSION_TIME_DEFAULT
;
5277 DEFUN (ip_pim_rp_keep_alive
,
5278 ip_pim_rp_keep_alive_cmd
,
5279 "ip pim rp keep-alive-timer (31-60000)",
5281 "pim multicast routing\n"
5283 "Keep alive Timer\n"
5286 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5287 pim
->rp_keep_alive_time
= atoi(argv
[4]->arg
);
5291 DEFUN (no_ip_pim_rp_keep_alive
,
5292 no_ip_pim_rp_keep_alive_cmd
,
5293 "no ip pim rp keep-alive-timer (31-60000)",
5296 "pim multicast routing\n"
5298 "Keep alive Timer\n"
5301 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5302 pim
->rp_keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
5306 DEFUN (ip_pim_keep_alive
,
5307 ip_pim_keep_alive_cmd
,
5308 "ip pim keep-alive-timer (31-60000)",
5310 "pim multicast routing\n"
5311 "Keep alive Timer\n"
5314 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5315 pim
->keep_alive_time
= atoi(argv
[3]->arg
);
5319 DEFUN (no_ip_pim_keep_alive
,
5320 no_ip_pim_keep_alive_cmd
,
5321 "no ip pim keep-alive-timer (31-60000)",
5324 "pim multicast routing\n"
5325 "Keep alive Timer\n"
5328 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5329 pim
->keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
5333 DEFUN (ip_pim_packets
,
5335 "ip pim packets (1-100)",
5337 "pim multicast routing\n"
5338 "packets to process at one time per fd\n"
5339 "Number of packets\n")
5341 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5342 qpim_packet_process
= atoi(argv
[3]->arg
);
5346 DEFUN (no_ip_pim_packets
,
5347 no_ip_pim_packets_cmd
,
5348 "no ip pim packets (1-100)",
5351 "pim multicast routing\n"
5352 "packets to process at one time per fd\n"
5353 "Number of packets\n")
5355 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5356 qpim_packet_process
= PIM_DEFAULT_PACKET_PROCESS
;
5360 DEFUN (ip_pim_v6_secondary
,
5361 ip_pim_v6_secondary_cmd
,
5362 "ip pim send-v6-secondary",
5364 "pim multicast routing\n"
5365 "Send v6 secondary addresses\n")
5367 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5368 pim
->send_v6_secondary
= 1;
5373 DEFUN (no_ip_pim_v6_secondary
,
5374 no_ip_pim_v6_secondary_cmd
,
5375 "no ip pim send-v6-secondary",
5378 "pim multicast routing\n"
5379 "Send v6 secondary addresses\n")
5381 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5382 pim
->send_v6_secondary
= 0;
5389 "ip pim rp A.B.C.D [A.B.C.D/M]",
5391 "pim multicast routing\n"
5393 "ip address of RP\n"
5394 "Group Address range to cover\n")
5396 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5399 if (argc
== (idx_ipv4
+ 1))
5400 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
5403 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
5404 argv
[idx_ipv4
+ 1]->arg
, NULL
);
5407 DEFUN (ip_pim_rp_prefix_list
,
5408 ip_pim_rp_prefix_list_cmd
,
5409 "ip pim rp A.B.C.D prefix-list WORD",
5411 "pim multicast routing\n"
5413 "ip address of RP\n"
5414 "group prefix-list filter\n"
5415 "Name of a prefix-list\n")
5417 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5418 return pim_rp_cmd_worker(pim
, vty
, argv
[3]->arg
, NULL
, argv
[5]->arg
);
5421 static int pim_no_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
5422 const char *rp
, const char *group
,
5425 int result
= pim_rp_del(pim
, rp
, group
, plist
);
5427 if (result
== PIM_GROUP_BAD_ADDRESS
) {
5428 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
5429 return CMD_WARNING_CONFIG_FAILED
;
5432 if (result
== PIM_RP_BAD_ADDRESS
) {
5433 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
5434 return CMD_WARNING_CONFIG_FAILED
;
5437 if (result
== PIM_RP_NOT_FOUND
) {
5438 vty_out(vty
, "%% Unable to find specified RP\n");
5439 return CMD_WARNING_CONFIG_FAILED
;
5445 DEFUN (no_ip_pim_rp
,
5447 "no ip pim rp A.B.C.D [A.B.C.D/M]",
5450 "pim multicast routing\n"
5452 "ip address of RP\n"
5453 "Group Address range to cover\n")
5455 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5456 int idx_ipv4
= 4, idx_group
= 0;
5458 if (argv_find(argv
, argc
, "A.B.C.D/M", &idx_group
))
5459 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
5460 argv
[idx_group
]->arg
, NULL
);
5462 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
5466 DEFUN (no_ip_pim_rp_prefix_list
,
5467 no_ip_pim_rp_prefix_list_cmd
,
5468 "no ip pim rp A.B.C.D prefix-list WORD",
5471 "pim multicast routing\n"
5473 "ip address of RP\n"
5474 "group prefix-list filter\n"
5475 "Name of a prefix-list\n")
5477 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5478 return pim_no_rp_cmd_worker(pim
, vty
, argv
[4]->arg
, NULL
, argv
[6]->arg
);
5481 static int pim_ssm_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
5484 int result
= pim_ssm_range_set(pim
, pim
->vrf_id
, plist
);
5486 if (result
== PIM_SSM_ERR_NONE
)
5490 case PIM_SSM_ERR_NO_VRF
:
5491 vty_out(vty
, "%% VRF doesn't exist\n");
5493 case PIM_SSM_ERR_DUP
:
5494 vty_out(vty
, "%% duplicate config\n");
5497 vty_out(vty
, "%% ssm range config failed\n");
5500 return CMD_WARNING_CONFIG_FAILED
;
5503 DEFUN (ip_pim_ssm_prefix_list
,
5504 ip_pim_ssm_prefix_list_cmd
,
5505 "ip pim ssm prefix-list WORD",
5507 "pim multicast routing\n"
5508 "Source Specific Multicast\n"
5509 "group range prefix-list filter\n"
5510 "Name of a prefix-list\n")
5512 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5513 return pim_ssm_cmd_worker(pim
, vty
, argv
[4]->arg
);
5516 DEFUN (no_ip_pim_ssm_prefix_list
,
5517 no_ip_pim_ssm_prefix_list_cmd
,
5518 "no ip pim ssm prefix-list",
5521 "pim multicast routing\n"
5522 "Source Specific Multicast\n"
5523 "group range prefix-list filter\n")
5525 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5526 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
5529 DEFUN (no_ip_pim_ssm_prefix_list_name
,
5530 no_ip_pim_ssm_prefix_list_name_cmd
,
5531 "no ip pim ssm prefix-list WORD",
5534 "pim multicast routing\n"
5535 "Source Specific Multicast\n"
5536 "group range prefix-list filter\n"
5537 "Name of a prefix-list\n")
5539 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5540 struct pim_ssm
*ssm
= pim
->ssm_info
;
5542 if (ssm
->plist_name
&& !strcmp(ssm
->plist_name
, argv
[5]->arg
))
5543 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
5545 vty_out(vty
, "%% pim ssm prefix-list %s doesn't exist\n", argv
[5]->arg
);
5547 return CMD_WARNING_CONFIG_FAILED
;
5550 static void ip_pim_ssm_show_group_range(struct pim_instance
*pim
,
5551 struct vty
*vty
, bool uj
)
5553 struct pim_ssm
*ssm
= pim
->ssm_info
;
5554 const char *range_str
=
5555 ssm
->plist_name
? ssm
->plist_name
: PIM_SSM_STANDARD_RANGE
;
5559 json
= json_object_new_object();
5560 json_object_string_add(json
, "ssmGroups", range_str
);
5561 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5562 json
, JSON_C_TO_STRING_PRETTY
));
5563 json_object_free(json
);
5565 vty_out(vty
, "SSM group range : %s\n", range_str
);
5568 DEFUN (show_ip_pim_ssm_range
,
5569 show_ip_pim_ssm_range_cmd
,
5570 "show ip pim [vrf NAME] group-type [json]",
5579 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5580 bool uj
= use_json(argc
, argv
);
5585 ip_pim_ssm_show_group_range(vrf
->info
, vty
, uj
);
5590 static void ip_pim_ssm_show_group_type(struct pim_instance
*pim
,
5591 struct vty
*vty
, bool uj
,
5594 struct in_addr group_addr
;
5595 const char *type_str
;
5598 result
= inet_pton(AF_INET
, group
, &group_addr
);
5600 type_str
= "invalid";
5602 if (pim_is_group_224_4(group_addr
))
5604 pim_is_grp_ssm(pim
, group_addr
) ? "SSM" : "ASM";
5606 type_str
= "not-multicast";
5611 json
= json_object_new_object();
5612 json_object_string_add(json
, "groupType", type_str
);
5613 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5614 json
, JSON_C_TO_STRING_PRETTY
));
5615 json_object_free(json
);
5617 vty_out(vty
, "Group type : %s\n", type_str
);
5620 DEFUN (show_ip_pim_group_type
,
5621 show_ip_pim_group_type_cmd
,
5622 "show ip pim [vrf NAME] group-type A.B.C.D [json]",
5627 "multicast group type\n"
5632 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5633 bool uj
= use_json(argc
, argv
);
5638 argv_find(argv
, argc
, "A.B.C.D", &idx
);
5639 ip_pim_ssm_show_group_type(vrf
->info
, vty
, uj
, argv
[idx
]->arg
);
5646 "ip ssmpingd [A.B.C.D]",
5651 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5654 struct in_addr source_addr
;
5655 const char *source_str
= (argc
== 3) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
5657 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
5659 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
5660 source_str
, errno
, safe_strerror(errno
));
5661 return CMD_WARNING_CONFIG_FAILED
;
5664 result
= pim_ssmpingd_start(pim
, source_addr
);
5666 vty_out(vty
, "%% Failure starting ssmpingd for source %s: %d\n",
5667 source_str
, result
);
5668 return CMD_WARNING_CONFIG_FAILED
;
5674 DEFUN (no_ip_ssmpingd
,
5676 "no ip ssmpingd [A.B.C.D]",
5682 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5685 struct in_addr source_addr
;
5686 const char *source_str
= (argc
== 4) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
5688 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
5690 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
5691 source_str
, errno
, safe_strerror(errno
));
5692 return CMD_WARNING_CONFIG_FAILED
;
5695 result
= pim_ssmpingd_stop(pim
, source_addr
);
5697 vty_out(vty
, "%% Failure stopping ssmpingd for source %s: %d\n",
5698 source_str
, result
);
5699 return CMD_WARNING_CONFIG_FAILED
;
5709 "pim multicast routing\n"
5710 "Enable PIM ECMP \n")
5712 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5713 pim
->ecmp_enable
= true;
5718 DEFUN (no_ip_pim_ecmp
,
5723 "pim multicast routing\n"
5724 "Disable PIM ECMP \n")
5726 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5727 pim
->ecmp_enable
= false;
5732 DEFUN (ip_pim_ecmp_rebalance
,
5733 ip_pim_ecmp_rebalance_cmd
,
5734 "ip pim ecmp rebalance",
5736 "pim multicast routing\n"
5737 "Enable PIM ECMP \n"
5738 "Enable PIM ECMP Rebalance\n")
5740 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5741 pim
->ecmp_enable
= true;
5742 pim
->ecmp_rebalance_enable
= true;
5747 DEFUN (no_ip_pim_ecmp_rebalance
,
5748 no_ip_pim_ecmp_rebalance_cmd
,
5749 "no ip pim ecmp rebalance",
5752 "pim multicast routing\n"
5753 "Disable PIM ECMP \n"
5754 "Disable PIM ECMP Rebalance\n")
5756 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5757 pim
->ecmp_rebalance_enable
= false;
5762 static int pim_cmd_igmp_start(struct vty
*vty
, struct interface
*ifp
)
5764 struct pim_interface
*pim_ifp
;
5765 uint8_t need_startup
= 0;
5767 pim_ifp
= ifp
->info
;
5770 pim_ifp
= pim_if_new(ifp
, true, false, false);
5772 vty_out(vty
, "Could not enable IGMP on interface %s\n",
5774 return CMD_WARNING_CONFIG_FAILED
;
5778 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
5779 PIM_IF_DO_IGMP(pim_ifp
->options
);
5784 /* 'ip igmp' executed multiple times, with need_startup
5785 avoid multiple if add all and membership refresh */
5787 pim_if_addr_add_all(ifp
);
5788 pim_if_membership_refresh(ifp
);
5794 DEFUN (interface_ip_igmp
,
5795 interface_ip_igmp_cmd
,
5800 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5802 return pim_cmd_igmp_start(vty
, ifp
);
5805 DEFUN (interface_no_ip_igmp
,
5806 interface_no_ip_igmp_cmd
,
5812 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5813 struct pim_interface
*pim_ifp
= ifp
->info
;
5818 PIM_IF_DONT_IGMP(pim_ifp
->options
);
5820 pim_if_membership_clear(ifp
);
5822 pim_if_addr_del_all_igmp(ifp
);
5824 if (!PIM_IF_TEST_PIM(pim_ifp
->options
)) {
5831 DEFUN (interface_ip_igmp_join
,
5832 interface_ip_igmp_join_cmd
,
5833 "ip igmp join A.B.C.D A.B.C.D",
5836 "IGMP join multicast group\n"
5837 "Multicast group address\n"
5840 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5843 const char *group_str
;
5844 const char *source_str
;
5845 struct in_addr group_addr
;
5846 struct in_addr source_addr
;
5850 group_str
= argv
[idx_ipv4
]->arg
;
5851 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
5853 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
5854 errno
, safe_strerror(errno
));
5855 return CMD_WARNING_CONFIG_FAILED
;
5858 /* Source address */
5859 source_str
= argv
[idx_ipv4_2
]->arg
;
5860 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
5862 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
5863 source_str
, errno
, safe_strerror(errno
));
5864 return CMD_WARNING_CONFIG_FAILED
;
5867 CMD_FERR_RETURN(pim_if_igmp_join_add(ifp
, group_addr
, source_addr
),
5868 "Failure joining IGMP group: $ERR");
5873 DEFUN (interface_no_ip_igmp_join
,
5874 interface_no_ip_igmp_join_cmd
,
5875 "no ip igmp join A.B.C.D A.B.C.D",
5879 "IGMP join multicast group\n"
5880 "Multicast group address\n"
5883 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5886 const char *group_str
;
5887 const char *source_str
;
5888 struct in_addr group_addr
;
5889 struct in_addr source_addr
;
5893 group_str
= argv
[idx_ipv4
]->arg
;
5894 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
5896 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
5897 errno
, safe_strerror(errno
));
5898 return CMD_WARNING_CONFIG_FAILED
;
5901 /* Source address */
5902 source_str
= argv
[idx_ipv4_2
]->arg
;
5903 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
5905 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
5906 source_str
, errno
, safe_strerror(errno
));
5907 return CMD_WARNING_CONFIG_FAILED
;
5910 result
= pim_if_igmp_join_del(ifp
, group_addr
, source_addr
);
5913 "%% Failure leaving IGMP group %s source %s on interface %s: %d\n",
5914 group_str
, source_str
, ifp
->name
, result
);
5915 return CMD_WARNING_CONFIG_FAILED
;
5922 CLI reconfiguration affects the interface level (struct pim_interface).
5923 This function propagates the reconfiguration to every active socket
5926 static void igmp_sock_query_interval_reconfig(struct igmp_sock
*igmp
)
5928 struct interface
*ifp
;
5929 struct pim_interface
*pim_ifp
;
5933 /* other querier present? */
5935 if (igmp
->t_other_querier_timer
)
5938 /* this is the querier */
5940 zassert(igmp
->interface
);
5941 zassert(igmp
->interface
->info
);
5943 ifp
= igmp
->interface
;
5944 pim_ifp
= ifp
->info
;
5946 if (PIM_DEBUG_IGMP_TRACE
) {
5947 char ifaddr_str
[INET_ADDRSTRLEN
];
5948 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
5949 sizeof(ifaddr_str
));
5950 zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
5951 __PRETTY_FUNCTION__
, ifaddr_str
, ifp
->name
,
5952 pim_ifp
->igmp_default_query_interval
);
5956 igmp_startup_mode_on() will reset QQI:
5958 igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
5960 igmp_startup_mode_on(igmp
);
5963 static void igmp_sock_query_reschedule(struct igmp_sock
*igmp
)
5965 if (igmp
->t_igmp_query_timer
) {
5966 /* other querier present */
5967 zassert(igmp
->t_igmp_query_timer
);
5968 zassert(!igmp
->t_other_querier_timer
);
5970 pim_igmp_general_query_off(igmp
);
5971 pim_igmp_general_query_on(igmp
);
5973 zassert(igmp
->t_igmp_query_timer
);
5974 zassert(!igmp
->t_other_querier_timer
);
5976 /* this is the querier */
5978 zassert(!igmp
->t_igmp_query_timer
);
5979 zassert(igmp
->t_other_querier_timer
);
5981 pim_igmp_other_querier_timer_off(igmp
);
5982 pim_igmp_other_querier_timer_on(igmp
);
5984 zassert(!igmp
->t_igmp_query_timer
);
5985 zassert(igmp
->t_other_querier_timer
);
5989 static void change_query_interval(struct pim_interface
*pim_ifp
,
5992 struct listnode
*sock_node
;
5993 struct igmp_sock
*igmp
;
5995 pim_ifp
->igmp_default_query_interval
= query_interval
;
5997 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
5998 igmp_sock_query_interval_reconfig(igmp
);
5999 igmp_sock_query_reschedule(igmp
);
6003 static void change_query_max_response_time(struct pim_interface
*pim_ifp
,
6004 int query_max_response_time_dsec
)
6006 struct listnode
*sock_node
;
6007 struct igmp_sock
*igmp
;
6009 pim_ifp
->igmp_query_max_response_time_dsec
=
6010 query_max_response_time_dsec
;
6013 Below we modify socket/group/source timers in order to quickly
6014 reflect the change. Otherwise, those timers would eventually catch
6018 /* scan all sockets */
6019 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
6020 struct listnode
*grp_node
;
6021 struct igmp_group
*grp
;
6023 /* reschedule socket general query */
6024 igmp_sock_query_reschedule(igmp
);
6026 /* scan socket groups */
6027 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grp_node
,
6029 struct listnode
*src_node
;
6030 struct igmp_source
*src
;
6032 /* reset group timers for groups in EXCLUDE mode */
6033 if (grp
->group_filtermode_isexcl
) {
6034 igmp_group_reset_gmi(grp
);
6037 /* scan group sources */
6038 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
,
6041 /* reset source timers for sources with running
6043 if (src
->t_source_timer
) {
6044 igmp_source_reset_gmi(igmp
, grp
, src
);
6051 #define IGMP_QUERY_INTERVAL_MIN (1)
6052 #define IGMP_QUERY_INTERVAL_MAX (1800)
6054 DEFUN (interface_ip_igmp_query_interval
,
6055 interface_ip_igmp_query_interval_cmd
,
6056 "ip igmp query-interval (1-1800)",
6059 IFACE_IGMP_QUERY_INTERVAL_STR
6060 "Query interval in seconds\n")
6062 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6063 struct pim_interface
*pim_ifp
= ifp
->info
;
6065 int query_interval_dsec
;
6069 ret
= pim_cmd_igmp_start(vty
, ifp
);
6070 if (ret
!= CMD_SUCCESS
)
6072 pim_ifp
= ifp
->info
;
6075 query_interval
= atoi(argv
[3]->arg
);
6076 query_interval_dsec
= 10 * query_interval
;
6079 It seems we don't need to check bounds since command.c does it
6080 already, but we verify them anyway for extra safety.
6082 if (query_interval
< IGMP_QUERY_INTERVAL_MIN
) {
6084 "General query interval %d lower than minimum %d\n",
6085 query_interval
, IGMP_QUERY_INTERVAL_MIN
);
6086 return CMD_WARNING_CONFIG_FAILED
;
6088 if (query_interval
> IGMP_QUERY_INTERVAL_MAX
) {
6090 "General query interval %d higher than maximum %d\n",
6091 query_interval
, IGMP_QUERY_INTERVAL_MAX
);
6092 return CMD_WARNING_CONFIG_FAILED
;
6095 if (query_interval_dsec
<= pim_ifp
->igmp_query_max_response_time_dsec
) {
6097 "Can't set general query interval %d dsec <= query max response time %d dsec.\n",
6098 query_interval_dsec
,
6099 pim_ifp
->igmp_query_max_response_time_dsec
);
6100 return CMD_WARNING_CONFIG_FAILED
;
6103 change_query_interval(pim_ifp
, query_interval
);
6108 DEFUN (interface_no_ip_igmp_query_interval
,
6109 interface_no_ip_igmp_query_interval_cmd
,
6110 "no ip igmp query-interval",
6114 IFACE_IGMP_QUERY_INTERVAL_STR
)
6116 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6117 struct pim_interface
*pim_ifp
= ifp
->info
;
6118 int default_query_interval_dsec
;
6123 default_query_interval_dsec
= IGMP_GENERAL_QUERY_INTERVAL
* 10;
6125 if (default_query_interval_dsec
6126 <= pim_ifp
->igmp_query_max_response_time_dsec
) {
6128 "Can't set default general query interval %d dsec <= query max response time %d dsec.\n",
6129 default_query_interval_dsec
,
6130 pim_ifp
->igmp_query_max_response_time_dsec
);
6131 return CMD_WARNING_CONFIG_FAILED
;
6134 change_query_interval(pim_ifp
, IGMP_GENERAL_QUERY_INTERVAL
);
6139 DEFUN (interface_ip_igmp_version
,
6140 interface_ip_igmp_version_cmd
,
6141 "ip igmp version (2-3)",
6145 "IGMP version number\n")
6147 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6148 struct pim_interface
*pim_ifp
= ifp
->info
;
6149 int igmp_version
, old_version
= 0;
6153 ret
= pim_cmd_igmp_start(vty
, ifp
);
6154 if (ret
!= CMD_SUCCESS
)
6156 pim_ifp
= ifp
->info
;
6159 igmp_version
= atoi(argv
[3]->arg
);
6160 old_version
= pim_ifp
->igmp_version
;
6161 pim_ifp
->igmp_version
= igmp_version
;
6163 // Check if IGMP is Enabled otherwise, enable on interface
6164 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
6165 PIM_IF_DO_IGMP(pim_ifp
->options
);
6166 pim_if_addr_add_all(ifp
);
6167 pim_if_membership_refresh(ifp
);
6168 old_version
= igmp_version
;
6169 // avoid refreshing membership again.
6171 /* Current and new version is different refresh existing
6172 membership. Going from 3 -> 2 or 2 -> 3. */
6173 if (old_version
!= igmp_version
)
6174 pim_if_membership_refresh(ifp
);
6179 DEFUN (interface_no_ip_igmp_version
,
6180 interface_no_ip_igmp_version_cmd
,
6181 "no ip igmp version (2-3)",
6186 "IGMP version number\n")
6188 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6189 struct pim_interface
*pim_ifp
= ifp
->info
;
6194 pim_ifp
->igmp_version
= IGMP_DEFAULT_VERSION
;
6199 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
6200 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
6202 DEFUN (interface_ip_igmp_query_max_response_time
,
6203 interface_ip_igmp_query_max_response_time_cmd
,
6204 "ip igmp query-max-response-time (10-250)",
6207 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
6208 "Query response value in deci-seconds\n")
6210 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6211 struct pim_interface
*pim_ifp
= ifp
->info
;
6212 int query_max_response_time
;
6216 ret
= pim_cmd_igmp_start(vty
, ifp
);
6217 if (ret
!= CMD_SUCCESS
)
6219 pim_ifp
= ifp
->info
;
6222 query_max_response_time
= atoi(argv
[3]->arg
);
6224 if (query_max_response_time
6225 >= pim_ifp
->igmp_default_query_interval
* 10) {
6227 "Can't set query max response time %d sec >= general query interval %d sec\n",
6228 query_max_response_time
,
6229 pim_ifp
->igmp_default_query_interval
);
6230 return CMD_WARNING_CONFIG_FAILED
;
6233 change_query_max_response_time(pim_ifp
, query_max_response_time
);
6238 DEFUN (interface_no_ip_igmp_query_max_response_time
,
6239 interface_no_ip_igmp_query_max_response_time_cmd
,
6240 "no ip igmp query-max-response-time (10-250)",
6244 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
6245 "Time for response in deci-seconds\n")
6247 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6248 struct pim_interface
*pim_ifp
= ifp
->info
;
6253 change_query_max_response_time(pim_ifp
,
6254 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
6259 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
6260 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
6262 DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec
,
6263 interface_ip_igmp_query_max_response_time_dsec_cmd
,
6264 "ip igmp query-max-response-time-dsec (10-250)",
6267 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
6268 "Query response value in deciseconds\n")
6270 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6271 struct pim_interface
*pim_ifp
= ifp
->info
;
6272 int query_max_response_time_dsec
;
6273 int default_query_interval_dsec
;
6277 ret
= pim_cmd_igmp_start(vty
, ifp
);
6278 if (ret
!= CMD_SUCCESS
)
6280 pim_ifp
= ifp
->info
;
6283 query_max_response_time_dsec
= atoi(argv
[4]->arg
);
6285 default_query_interval_dsec
= 10 * pim_ifp
->igmp_default_query_interval
;
6287 if (query_max_response_time_dsec
>= default_query_interval_dsec
) {
6289 "Can't set query max response time %d dsec >= general query interval %d dsec\n",
6290 query_max_response_time_dsec
,
6291 default_query_interval_dsec
);
6292 return CMD_WARNING_CONFIG_FAILED
;
6295 change_query_max_response_time(pim_ifp
, query_max_response_time_dsec
);
6300 DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec
,
6301 interface_no_ip_igmp_query_max_response_time_dsec_cmd
,
6302 "no ip igmp query-max-response-time-dsec",
6306 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
)
6308 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6309 struct pim_interface
*pim_ifp
= ifp
->info
;
6314 change_query_max_response_time(pim_ifp
,
6315 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
6320 DEFUN (interface_ip_pim_drprio
,
6321 interface_ip_pim_drprio_cmd
,
6322 "ip pim drpriority (1-4294967295)",
6325 "Set the Designated Router Election Priority\n"
6326 "Value of the new DR Priority\n")
6328 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6330 struct pim_interface
*pim_ifp
= ifp
->info
;
6331 uint32_t old_dr_prio
;
6334 vty_out(vty
, "Please enable PIM on interface, first\n");
6335 return CMD_WARNING_CONFIG_FAILED
;
6338 old_dr_prio
= pim_ifp
->pim_dr_priority
;
6340 pim_ifp
->pim_dr_priority
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
6342 if (old_dr_prio
!= pim_ifp
->pim_dr_priority
) {
6343 if (pim_if_dr_election(ifp
))
6344 pim_hello_restart_now(ifp
);
6350 DEFUN (interface_no_ip_pim_drprio
,
6351 interface_no_ip_pim_drprio_cmd
,
6352 "no ip pim drpriority [(1-4294967295)]",
6356 "Revert the Designated Router Priority to default\n"
6357 "Old Value of the Priority\n")
6359 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6360 struct pim_interface
*pim_ifp
= ifp
->info
;
6363 vty_out(vty
, "Pim not enabled on this interface\n");
6364 return CMD_WARNING_CONFIG_FAILED
;
6367 if (pim_ifp
->pim_dr_priority
!= PIM_DEFAULT_DR_PRIORITY
) {
6368 pim_ifp
->pim_dr_priority
= PIM_DEFAULT_DR_PRIORITY
;
6369 if (pim_if_dr_election(ifp
))
6370 pim_hello_restart_now(ifp
);
6376 static int pim_cmd_interface_add(struct interface
*ifp
)
6378 struct pim_interface
*pim_ifp
= ifp
->info
;
6381 pim_ifp
= pim_if_new(ifp
, false, true, false);
6386 PIM_IF_DO_PIM(pim_ifp
->options
);
6389 pim_if_addr_add_all(ifp
);
6390 pim_if_membership_refresh(ifp
);
6394 DEFUN_HIDDEN (interface_ip_pim_ssm
,
6395 interface_ip_pim_ssm_cmd
,
6401 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6403 if (!pim_cmd_interface_add(ifp
)) {
6404 vty_out(vty
, "Could not enable PIM SM on interface\n");
6405 return CMD_WARNING_CONFIG_FAILED
;
6409 "WARN: Enabled PIM SM on interface; configure PIM SSM "
6410 "range if needed\n");
6414 static int interface_ip_pim_helper(struct vty
*vty
)
6416 struct pim_interface
*pim_ifp
;
6418 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6420 if (!pim_cmd_interface_add(ifp
)) {
6421 vty_out(vty
, "Could not enable PIM SM on interface\n");
6422 return CMD_WARNING_CONFIG_FAILED
;
6425 pim_ifp
= ifp
->info
;
6427 pim_if_create_pimreg(pim_ifp
->pim
);
6432 DEFUN_HIDDEN (interface_ip_pim_sm
,
6433 interface_ip_pim_sm_cmd
,
6439 return interface_ip_pim_helper(vty
);
6442 DEFUN (interface_ip_pim
,
6443 interface_ip_pim_cmd
,
6448 return interface_ip_pim_helper(vty
);
6451 static int pim_cmd_interface_delete(struct interface
*ifp
)
6453 struct pim_interface
*pim_ifp
= ifp
->info
;
6458 PIM_IF_DONT_PIM(pim_ifp
->options
);
6460 pim_if_membership_clear(ifp
);
6463 pim_sock_delete() removes all neighbors from
6464 pim_ifp->pim_neighbor_list.
6466 pim_sock_delete(ifp
, "pim unconfigured on interface");
6468 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
6469 pim_if_addr_del_all(ifp
);
6476 static int interface_no_ip_pim_helper(struct vty
*vty
)
6478 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6479 if (!pim_cmd_interface_delete(ifp
)) {
6480 vty_out(vty
, "Unable to delete interface information\n");
6481 return CMD_WARNING_CONFIG_FAILED
;
6487 DEFUN_HIDDEN (interface_no_ip_pim_ssm
,
6488 interface_no_ip_pim_ssm_cmd
,
6495 return interface_no_ip_pim_helper(vty
);
6498 DEFUN_HIDDEN (interface_no_ip_pim_sm
,
6499 interface_no_ip_pim_sm_cmd
,
6506 return interface_no_ip_pim_helper(vty
);
6509 DEFUN (interface_no_ip_pim
,
6510 interface_no_ip_pim_cmd
,
6516 return interface_no_ip_pim_helper(vty
);
6520 DEFUN(interface_ip_pim_boundary_oil
,
6521 interface_ip_pim_boundary_oil_cmd
,
6522 "ip multicast boundary oil WORD",
6524 "Generic multicast configuration options\n"
6525 "Define multicast boundary\n"
6526 "Filter OIL by group using prefix list\n"
6527 "Prefix list to filter OIL with\n")
6529 VTY_DECLVAR_CONTEXT(interface
, iif
);
6530 struct pim_interface
*pim_ifp
;
6533 argv_find(argv
, argc
, "WORD", &idx
);
6535 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6537 if (pim_ifp
->boundary_oil_plist
)
6538 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
6540 pim_ifp
->boundary_oil_plist
=
6541 XSTRDUP(MTYPE_PIM_INTERFACE
, argv
[idx
]->arg
);
6543 /* Interface will be pruned from OIL on next Join */
6547 DEFUN(interface_no_ip_pim_boundary_oil
,
6548 interface_no_ip_pim_boundary_oil_cmd
,
6549 "no ip multicast boundary oil [WORD]",
6552 "Generic multicast configuration options\n"
6553 "Define multicast boundary\n"
6554 "Filter OIL by group using prefix list\n"
6555 "Prefix list to filter OIL with\n")
6557 VTY_DECLVAR_CONTEXT(interface
, iif
);
6558 struct pim_interface
*pim_ifp
;
6561 argv_find(argv
, argc
, "WORD", &idx
);
6563 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6565 if (pim_ifp
->boundary_oil_plist
)
6566 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
6571 DEFUN (interface_ip_mroute
,
6572 interface_ip_mroute_cmd
,
6573 "ip mroute INTERFACE A.B.C.D",
6575 "Add multicast route\n"
6576 "Outgoing interface name\n"
6579 VTY_DECLVAR_CONTEXT(interface
, iif
);
6580 struct pim_interface
*pim_ifp
;
6581 struct pim_instance
*pim
;
6582 int idx_interface
= 2;
6584 struct interface
*oif
;
6585 const char *oifname
;
6586 const char *grp_str
;
6587 struct in_addr grp_addr
;
6588 struct in_addr src_addr
;
6591 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6594 oifname
= argv
[idx_interface
]->arg
;
6595 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6597 vty_out(vty
, "No such interface name %s\n", oifname
);
6601 grp_str
= argv
[idx_ipv4
]->arg
;
6602 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6604 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6605 errno
, safe_strerror(errno
));
6609 src_addr
.s_addr
= INADDR_ANY
;
6611 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6612 vty_out(vty
, "Failed to add route\n");
6619 DEFUN (interface_ip_mroute_source
,
6620 interface_ip_mroute_source_cmd
,
6621 "ip mroute INTERFACE A.B.C.D A.B.C.D",
6623 "Add multicast route\n"
6624 "Outgoing interface name\n"
6628 VTY_DECLVAR_CONTEXT(interface
, iif
);
6629 struct pim_interface
*pim_ifp
;
6630 struct pim_instance
*pim
;
6631 int idx_interface
= 2;
6634 struct interface
*oif
;
6635 const char *oifname
;
6636 const char *grp_str
;
6637 struct in_addr grp_addr
;
6638 const char *src_str
;
6639 struct in_addr src_addr
;
6642 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6645 oifname
= argv
[idx_interface
]->arg
;
6646 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6648 vty_out(vty
, "No such interface name %s\n", oifname
);
6652 grp_str
= argv
[idx_ipv4
]->arg
;
6653 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6655 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6656 errno
, safe_strerror(errno
));
6660 src_str
= argv
[idx_ipv4_2
]->arg
;
6661 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
6663 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
6664 errno
, safe_strerror(errno
));
6668 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6669 vty_out(vty
, "Failed to add route\n");
6676 DEFUN (interface_no_ip_mroute
,
6677 interface_no_ip_mroute_cmd
,
6678 "no ip mroute INTERFACE A.B.C.D",
6681 "Add multicast route\n"
6682 "Outgoing interface name\n"
6685 VTY_DECLVAR_CONTEXT(interface
, iif
);
6686 struct pim_interface
*pim_ifp
;
6687 struct pim_instance
*pim
;
6688 int idx_interface
= 3;
6690 struct interface
*oif
;
6691 const char *oifname
;
6692 const char *grp_str
;
6693 struct in_addr grp_addr
;
6694 struct in_addr src_addr
;
6697 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6700 oifname
= argv
[idx_interface
]->arg
;
6701 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6703 vty_out(vty
, "No such interface name %s\n", oifname
);
6707 grp_str
= argv
[idx_ipv4
]->arg
;
6708 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6710 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6711 errno
, safe_strerror(errno
));
6715 src_addr
.s_addr
= INADDR_ANY
;
6717 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6718 vty_out(vty
, "Failed to remove route\n");
6725 DEFUN (interface_no_ip_mroute_source
,
6726 interface_no_ip_mroute_source_cmd
,
6727 "no ip mroute INTERFACE A.B.C.D A.B.C.D",
6730 "Add multicast route\n"
6731 "Outgoing interface name\n"
6735 VTY_DECLVAR_CONTEXT(interface
, iif
);
6736 struct pim_interface
*pim_ifp
;
6737 struct pim_instance
*pim
;
6738 int idx_interface
= 3;
6741 struct interface
*oif
;
6742 const char *oifname
;
6743 const char *grp_str
;
6744 struct in_addr grp_addr
;
6745 const char *src_str
;
6746 struct in_addr src_addr
;
6749 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6752 oifname
= argv
[idx_interface
]->arg
;
6753 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6755 vty_out(vty
, "No such interface name %s\n", oifname
);
6759 grp_str
= argv
[idx_ipv4
]->arg
;
6760 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6762 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6763 errno
, safe_strerror(errno
));
6767 src_str
= argv
[idx_ipv4_2
]->arg
;
6768 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
6770 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
6771 errno
, safe_strerror(errno
));
6775 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6776 vty_out(vty
, "Failed to remove route\n");
6783 DEFUN (interface_ip_pim_hello
,
6784 interface_ip_pim_hello_cmd
,
6785 "ip pim hello (1-180) [(1-180)]",
6789 IFACE_PIM_HELLO_TIME_STR
6790 IFACE_PIM_HELLO_HOLD_STR
)
6792 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6795 struct pim_interface
*pim_ifp
= ifp
->info
;
6798 if (!pim_cmd_interface_add(ifp
)) {
6799 vty_out(vty
, "Could not enable PIM SM on interface\n");
6800 return CMD_WARNING_CONFIG_FAILED
;
6804 pim_ifp
= ifp
->info
;
6805 pim_ifp
->pim_hello_period
= strtol(argv
[idx_time
]->arg
, NULL
, 10);
6807 if (argc
== idx_hold
+ 1)
6808 pim_ifp
->pim_default_holdtime
=
6809 strtol(argv
[idx_hold
]->arg
, NULL
, 10);
6814 DEFUN (interface_no_ip_pim_hello
,
6815 interface_no_ip_pim_hello_cmd
,
6816 "no ip pim hello [(1-180) (1-180)]",
6821 IFACE_PIM_HELLO_TIME_STR
6822 IFACE_PIM_HELLO_HOLD_STR
)
6824 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6825 struct pim_interface
*pim_ifp
= ifp
->info
;
6828 vty_out(vty
, "Pim not enabled on this interface\n");
6829 return CMD_WARNING_CONFIG_FAILED
;
6832 pim_ifp
->pim_hello_period
= PIM_DEFAULT_HELLO_PERIOD
;
6833 pim_ifp
->pim_default_holdtime
= -1;
6844 PIM_DO_DEBUG_IGMP_EVENTS
;
6845 PIM_DO_DEBUG_IGMP_PACKETS
;
6846 PIM_DO_DEBUG_IGMP_TRACE
;
6850 DEFUN (no_debug_igmp
,
6857 PIM_DONT_DEBUG_IGMP_EVENTS
;
6858 PIM_DONT_DEBUG_IGMP_PACKETS
;
6859 PIM_DONT_DEBUG_IGMP_TRACE
;
6864 DEFUN (debug_igmp_events
,
6865 debug_igmp_events_cmd
,
6866 "debug igmp events",
6869 DEBUG_IGMP_EVENTS_STR
)
6871 PIM_DO_DEBUG_IGMP_EVENTS
;
6875 DEFUN (no_debug_igmp_events
,
6876 no_debug_igmp_events_cmd
,
6877 "no debug igmp events",
6881 DEBUG_IGMP_EVENTS_STR
)
6883 PIM_DONT_DEBUG_IGMP_EVENTS
;
6888 DEFUN (debug_igmp_packets
,
6889 debug_igmp_packets_cmd
,
6890 "debug igmp packets",
6893 DEBUG_IGMP_PACKETS_STR
)
6895 PIM_DO_DEBUG_IGMP_PACKETS
;
6899 DEFUN (no_debug_igmp_packets
,
6900 no_debug_igmp_packets_cmd
,
6901 "no debug igmp packets",
6905 DEBUG_IGMP_PACKETS_STR
)
6907 PIM_DONT_DEBUG_IGMP_PACKETS
;
6912 DEFUN (debug_igmp_trace
,
6913 debug_igmp_trace_cmd
,
6917 DEBUG_IGMP_TRACE_STR
)
6919 PIM_DO_DEBUG_IGMP_TRACE
;
6923 DEFUN (no_debug_igmp_trace
,
6924 no_debug_igmp_trace_cmd
,
6925 "no debug igmp trace",
6929 DEBUG_IGMP_TRACE_STR
)
6931 PIM_DONT_DEBUG_IGMP_TRACE
;
6936 DEFUN (debug_mroute
,
6942 PIM_DO_DEBUG_MROUTE
;
6946 DEFUN (debug_mroute_detail
,
6947 debug_mroute_detail_cmd
,
6948 "debug mroute detail",
6953 PIM_DO_DEBUG_MROUTE_DETAIL
;
6957 DEFUN (no_debug_mroute
,
6958 no_debug_mroute_cmd
,
6964 PIM_DONT_DEBUG_MROUTE
;
6968 DEFUN (no_debug_mroute_detail
,
6969 no_debug_mroute_detail_cmd
,
6970 "no debug mroute detail",
6976 PIM_DONT_DEBUG_MROUTE_DETAIL
;
6980 DEFUN (debug_static
,
6986 PIM_DO_DEBUG_STATIC
;
6990 DEFUN (no_debug_static
,
6991 no_debug_static_cmd
,
6997 PIM_DONT_DEBUG_STATIC
;
7008 PIM_DO_DEBUG_PIM_EVENTS
;
7009 PIM_DO_DEBUG_PIM_PACKETS
;
7010 PIM_DO_DEBUG_PIM_TRACE
;
7011 PIM_DO_DEBUG_MSDP_EVENTS
;
7012 PIM_DO_DEBUG_MSDP_PACKETS
;
7016 DEFUN (no_debug_pim
,
7023 PIM_DONT_DEBUG_PIM_EVENTS
;
7024 PIM_DONT_DEBUG_PIM_PACKETS
;
7025 PIM_DONT_DEBUG_PIM_TRACE
;
7026 PIM_DONT_DEBUG_MSDP_EVENTS
;
7027 PIM_DONT_DEBUG_MSDP_PACKETS
;
7029 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
7030 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
7035 DEFUN (debug_pim_nht
,
7040 "Nexthop Tracking\n")
7042 PIM_DO_DEBUG_PIM_NHT
;
7046 DEFUN (no_debug_pim_nht
,
7047 no_debug_pim_nht_cmd
,
7052 "Nexthop Tracking\n")
7054 PIM_DONT_DEBUG_PIM_NHT
;
7058 DEFUN (debug_pim_nht_rp
,
7059 debug_pim_nht_rp_cmd
,
7063 "Nexthop Tracking\n"
7064 "RP Nexthop Tracking\n")
7066 PIM_DO_DEBUG_PIM_NHT_RP
;
7070 DEFUN (no_debug_pim_nht_rp
,
7071 no_debug_pim_nht_rp_cmd
,
7072 "no debug pim nht rp",
7076 "Nexthop Tracking\n"
7077 "RP Nexthop Tracking\n")
7079 PIM_DONT_DEBUG_PIM_NHT_RP
;
7083 DEFUN (debug_pim_events
,
7084 debug_pim_events_cmd
,
7088 DEBUG_PIM_EVENTS_STR
)
7090 PIM_DO_DEBUG_PIM_EVENTS
;
7094 DEFUN (no_debug_pim_events
,
7095 no_debug_pim_events_cmd
,
7096 "no debug pim events",
7100 DEBUG_PIM_EVENTS_STR
)
7102 PIM_DONT_DEBUG_PIM_EVENTS
;
7106 DEFUN (debug_pim_packets
,
7107 debug_pim_packets_cmd
,
7108 "debug pim packets [<hello|joins|register>]",
7111 DEBUG_PIM_PACKETS_STR
7112 DEBUG_PIM_HELLO_PACKETS_STR
7113 DEBUG_PIM_J_P_PACKETS_STR
7114 DEBUG_PIM_PIM_REG_PACKETS_STR
)
7117 if (argv_find(argv
, argc
, "hello", &idx
)) {
7118 PIM_DO_DEBUG_PIM_HELLO
;
7119 vty_out(vty
, "PIM Hello debugging is on\n");
7120 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
7121 PIM_DO_DEBUG_PIM_J_P
;
7122 vty_out(vty
, "PIM Join/Prune debugging is on\n");
7123 } else if (argv_find(argv
, argc
, "register", &idx
)) {
7124 PIM_DO_DEBUG_PIM_REG
;
7125 vty_out(vty
, "PIM Register debugging is on\n");
7127 PIM_DO_DEBUG_PIM_PACKETS
;
7128 vty_out(vty
, "PIM Packet debugging is on \n");
7133 DEFUN (no_debug_pim_packets
,
7134 no_debug_pim_packets_cmd
,
7135 "no debug pim packets [<hello|joins|register>]",
7139 DEBUG_PIM_PACKETS_STR
7140 DEBUG_PIM_HELLO_PACKETS_STR
7141 DEBUG_PIM_J_P_PACKETS_STR
7142 DEBUG_PIM_PIM_REG_PACKETS_STR
)
7145 if (argv_find(argv
, argc
, "hello", &idx
)) {
7146 PIM_DONT_DEBUG_PIM_HELLO
;
7147 vty_out(vty
, "PIM Hello debugging is off \n");
7148 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
7149 PIM_DONT_DEBUG_PIM_J_P
;
7150 vty_out(vty
, "PIM Join/Prune debugging is off \n");
7151 } else if (argv_find(argv
, argc
, "register", &idx
)) {
7152 PIM_DONT_DEBUG_PIM_REG
;
7153 vty_out(vty
, "PIM Register debugging is off\n");
7155 PIM_DONT_DEBUG_PIM_PACKETS
;
7161 DEFUN (debug_pim_packetdump_send
,
7162 debug_pim_packetdump_send_cmd
,
7163 "debug pim packet-dump send",
7166 DEBUG_PIM_PACKETDUMP_STR
7167 DEBUG_PIM_PACKETDUMP_SEND_STR
)
7169 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND
;
7173 DEFUN (no_debug_pim_packetdump_send
,
7174 no_debug_pim_packetdump_send_cmd
,
7175 "no debug pim packet-dump send",
7179 DEBUG_PIM_PACKETDUMP_STR
7180 DEBUG_PIM_PACKETDUMP_SEND_STR
)
7182 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
7186 DEFUN (debug_pim_packetdump_recv
,
7187 debug_pim_packetdump_recv_cmd
,
7188 "debug pim packet-dump receive",
7191 DEBUG_PIM_PACKETDUMP_STR
7192 DEBUG_PIM_PACKETDUMP_RECV_STR
)
7194 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV
;
7198 DEFUN (no_debug_pim_packetdump_recv
,
7199 no_debug_pim_packetdump_recv_cmd
,
7200 "no debug pim packet-dump receive",
7204 DEBUG_PIM_PACKETDUMP_STR
7205 DEBUG_PIM_PACKETDUMP_RECV_STR
)
7207 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
7211 DEFUN (debug_pim_trace
,
7212 debug_pim_trace_cmd
,
7216 DEBUG_PIM_TRACE_STR
)
7218 PIM_DO_DEBUG_PIM_TRACE
;
7222 DEFUN (debug_pim_trace_detail
,
7223 debug_pim_trace_detail_cmd
,
7224 "debug pim trace detail",
7228 "Detailed Information\n")
7230 PIM_DO_DEBUG_PIM_TRACE_DETAIL
;
7234 DEFUN (no_debug_pim_trace
,
7235 no_debug_pim_trace_cmd
,
7236 "no debug pim trace",
7240 DEBUG_PIM_TRACE_STR
)
7242 PIM_DONT_DEBUG_PIM_TRACE
;
7246 DEFUN (no_debug_pim_trace_detail
,
7247 no_debug_pim_trace_detail_cmd
,
7248 "no debug pim trace detail",
7253 "Detailed Information\n")
7255 PIM_DONT_DEBUG_PIM_TRACE_DETAIL
;
7259 DEFUN (debug_ssmpingd
,
7265 PIM_DO_DEBUG_SSMPINGD
;
7269 DEFUN (no_debug_ssmpingd
,
7270 no_debug_ssmpingd_cmd
,
7271 "no debug ssmpingd",
7276 PIM_DONT_DEBUG_SSMPINGD
;
7280 DEFUN (debug_pim_zebra
,
7281 debug_pim_zebra_cmd
,
7285 DEBUG_PIM_ZEBRA_STR
)
7291 DEFUN (no_debug_pim_zebra
,
7292 no_debug_pim_zebra_cmd
,
7293 "no debug pim zebra",
7297 DEBUG_PIM_ZEBRA_STR
)
7299 PIM_DONT_DEBUG_ZEBRA
;
7309 PIM_DO_DEBUG_MSDP_EVENTS
;
7310 PIM_DO_DEBUG_MSDP_PACKETS
;
7314 DEFUN (no_debug_msdp
,
7321 PIM_DONT_DEBUG_MSDP_EVENTS
;
7322 PIM_DONT_DEBUG_MSDP_PACKETS
;
7326 #if CONFDATE > 20190402
7327 CPP_NOTICE("bgpd: time to remove undebug commands")
7329 ALIAS_HIDDEN (no_debug_msdp
,
7332 UNDEBUG_STR DEBUG_MSDP_STR
)
7334 DEFUN (debug_msdp_events
,
7335 debug_msdp_events_cmd
,
7336 "debug msdp events",
7339 DEBUG_MSDP_EVENTS_STR
)
7341 PIM_DO_DEBUG_MSDP_EVENTS
;
7345 DEFUN (no_debug_msdp_events
,
7346 no_debug_msdp_events_cmd
,
7347 "no debug msdp events",
7351 DEBUG_MSDP_EVENTS_STR
)
7353 PIM_DONT_DEBUG_MSDP_EVENTS
;
7357 #if CONFDATE > 20190402
7358 CPP_NOTICE("bgpd: time to remove undebug commands")
7360 ALIAS_HIDDEN (no_debug_msdp_events
,
7361 undebug_msdp_events_cmd
,
7362 "undebug msdp events",
7365 DEBUG_MSDP_EVENTS_STR
)
7367 DEFUN (debug_msdp_packets
,
7368 debug_msdp_packets_cmd
,
7369 "debug msdp packets",
7372 DEBUG_MSDP_PACKETS_STR
)
7374 PIM_DO_DEBUG_MSDP_PACKETS
;
7378 DEFUN (no_debug_msdp_packets
,
7379 no_debug_msdp_packets_cmd
,
7380 "no debug msdp packets",
7384 DEBUG_MSDP_PACKETS_STR
)
7386 PIM_DONT_DEBUG_MSDP_PACKETS
;
7390 #if CONFDATE > 20190402
7391 CPP_NOTICE("bgpd: time to remove undebug commands")
7393 ALIAS_HIDDEN (no_debug_msdp_packets
,
7394 undebug_msdp_packets_cmd
,
7395 "undebug msdp packets",
7398 DEBUG_MSDP_PACKETS_STR
)
7400 DEFUN (debug_mtrace
,
7406 PIM_DO_DEBUG_MTRACE
;
7410 DEFUN (no_debug_mtrace
,
7411 no_debug_mtrace_cmd
,
7417 PIM_DONT_DEBUG_MTRACE
;
7421 DEFUN_NOSH (show_debugging_pim
,
7422 show_debugging_pim_cmd
,
7423 "show debugging [pim]",
7428 vty_out(vty
, "PIM debugging status\n");
7430 pim_debug_config_write(vty
);
7435 static int interface_pim_use_src_cmd_worker(struct vty
*vty
, const char *source
)
7438 struct in_addr source_addr
;
7439 int ret
= CMD_SUCCESS
;
7440 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7442 result
= inet_pton(AF_INET
, source
, &source_addr
);
7444 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", source
,
7445 errno
, safe_strerror(errno
));
7446 return CMD_WARNING_CONFIG_FAILED
;
7449 result
= pim_update_source_set(ifp
, source_addr
);
7453 case PIM_IFACE_NOT_FOUND
:
7454 ret
= CMD_WARNING_CONFIG_FAILED
;
7455 vty_out(vty
, "Pim not enabled on this interface\n");
7457 case PIM_UPDATE_SOURCE_DUP
:
7459 vty_out(vty
, "%% Source already set to %s\n", source
);
7462 ret
= CMD_WARNING_CONFIG_FAILED
;
7463 vty_out(vty
, "%% Source set failed\n");
7469 DEFUN (interface_pim_use_source
,
7470 interface_pim_use_source_cmd
,
7471 "ip pim use-source A.B.C.D",
7474 "Configure primary IP address\n"
7475 "source ip address\n")
7477 return interface_pim_use_src_cmd_worker(vty
, argv
[3]->arg
);
7480 DEFUN (interface_no_pim_use_source
,
7481 interface_no_pim_use_source_cmd
,
7482 "no ip pim use-source [A.B.C.D]",
7486 "Delete source IP address\n"
7487 "source ip address\n")
7489 return interface_pim_use_src_cmd_worker(vty
, "0.0.0.0");
7497 "Enables BFD support\n")
7499 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7500 struct pim_interface
*pim_ifp
= ifp
->info
;
7501 struct bfd_info
*bfd_info
= NULL
;
7504 if (!pim_cmd_interface_add(ifp
)) {
7505 vty_out(vty
, "Could not enable PIM SM on interface\n");
7509 pim_ifp
= ifp
->info
;
7511 bfd_info
= pim_ifp
->bfd_info
;
7513 if (!bfd_info
|| !CHECK_FLAG(bfd_info
->flags
, BFD_FLAG_PARAM_CFG
))
7514 pim_bfd_if_param_set(ifp
, BFD_DEF_MIN_RX
, BFD_DEF_MIN_TX
,
7515 BFD_DEF_DETECT_MULT
, 1);
7520 DEFUN (no_ip_pim_bfd
,
7526 "Disables BFD support\n")
7528 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7529 struct pim_interface
*pim_ifp
= ifp
->info
;
7532 vty_out(vty
, "Pim not enabled on this interface\n");
7536 if (pim_ifp
->bfd_info
) {
7537 pim_bfd_reg_dereg_all_nbr(ifp
, ZEBRA_BFD_DEST_DEREGISTER
);
7538 bfd_info_free(&(pim_ifp
->bfd_info
));
7548 #endif /* HAVE_BFDD */
7550 ip_pim_bfd_param_cmd
,
7551 "ip pim bfd (2-255) (50-60000) (50-60000)",
7554 "Enables BFD support\n"
7555 "Detect Multiplier\n"
7556 "Required min receive interval\n"
7557 "Desired min transmit interval\n")
7559 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7561 int idx_number_2
= 4;
7562 int idx_number_3
= 5;
7567 struct pim_interface
*pim_ifp
= ifp
->info
;
7570 if (!pim_cmd_interface_add(ifp
)) {
7571 vty_out(vty
, "Could not enable PIM SM on interface\n");
7576 if ((ret
= bfd_validate_param(
7577 vty
, argv
[idx_number
]->arg
, argv
[idx_number_2
]->arg
,
7578 argv
[idx_number_3
]->arg
, &dm_val
, &rx_val
, &tx_val
))
7582 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")
7594 #endif /* !HAVE_BFDD */
7596 static int ip_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
7597 const char *peer
, const char *local
)
7599 enum pim_msdp_err result
;
7600 struct in_addr peer_addr
;
7601 struct in_addr local_addr
;
7602 int ret
= CMD_SUCCESS
;
7604 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
7606 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
7607 errno
, safe_strerror(errno
));
7608 return CMD_WARNING_CONFIG_FAILED
;
7611 result
= inet_pton(AF_INET
, local
, &local_addr
);
7613 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", local
,
7614 errno
, safe_strerror(errno
));
7615 return CMD_WARNING_CONFIG_FAILED
;
7618 result
= pim_msdp_peer_add(pim
, peer_addr
, local_addr
, "default",
7621 case PIM_MSDP_ERR_NONE
:
7623 case PIM_MSDP_ERR_OOM
:
7624 ret
= CMD_WARNING_CONFIG_FAILED
;
7625 vty_out(vty
, "%% Out of memory\n");
7627 case PIM_MSDP_ERR_PEER_EXISTS
:
7629 vty_out(vty
, "%% Peer exists\n");
7631 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
7632 ret
= CMD_WARNING_CONFIG_FAILED
;
7633 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
7636 ret
= CMD_WARNING_CONFIG_FAILED
;
7637 vty_out(vty
, "%% peer add failed\n");
7643 DEFUN_HIDDEN (ip_msdp_peer
,
7645 "ip msdp peer A.B.C.D source A.B.C.D",
7648 "Configure MSDP peer\n"
7650 "Source address for TCP connection\n"
7651 "local ip address\n")
7653 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7654 return ip_msdp_peer_cmd_worker(pim
, vty
, argv
[3]->arg
, argv
[5]->arg
);
7657 static int ip_no_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
7660 enum pim_msdp_err result
;
7661 struct in_addr peer_addr
;
7663 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
7665 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
7666 errno
, safe_strerror(errno
));
7667 return CMD_WARNING_CONFIG_FAILED
;
7670 result
= pim_msdp_peer_del(pim
, peer_addr
);
7672 case PIM_MSDP_ERR_NONE
:
7674 case PIM_MSDP_ERR_NO_PEER
:
7675 vty_out(vty
, "%% Peer does not exist\n");
7678 vty_out(vty
, "%% peer del failed\n");
7681 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7684 DEFUN_HIDDEN (no_ip_msdp_peer
,
7685 no_ip_msdp_peer_cmd
,
7686 "no ip msdp peer A.B.C.D",
7690 "Delete MSDP peer\n"
7691 "peer ip address\n")
7693 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7694 return ip_no_msdp_peer_cmd_worker(pim
, vty
, argv
[4]->arg
);
7697 static int ip_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
7698 struct vty
*vty
, const char *mg
,
7701 enum pim_msdp_err result
;
7702 struct in_addr mbr_ip
;
7703 int ret
= CMD_SUCCESS
;
7705 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
7707 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
7708 errno
, safe_strerror(errno
));
7709 return CMD_WARNING_CONFIG_FAILED
;
7712 result
= pim_msdp_mg_mbr_add(pim
, mg
, mbr_ip
);
7714 case PIM_MSDP_ERR_NONE
:
7716 case PIM_MSDP_ERR_OOM
:
7717 ret
= CMD_WARNING_CONFIG_FAILED
;
7718 vty_out(vty
, "%% Out of memory\n");
7720 case PIM_MSDP_ERR_MG_MBR_EXISTS
:
7722 vty_out(vty
, "%% mesh-group member exists\n");
7724 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
7725 ret
= CMD_WARNING_CONFIG_FAILED
;
7726 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
7729 ret
= CMD_WARNING_CONFIG_FAILED
;
7730 vty_out(vty
, "%% member add failed\n");
7736 DEFUN (ip_msdp_mesh_group_member
,
7737 ip_msdp_mesh_group_member_cmd
,
7738 "ip msdp mesh-group WORD member A.B.C.D",
7741 "Configure MSDP mesh-group\n"
7743 "mesh group member\n"
7744 "peer ip address\n")
7746 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7747 return ip_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[3]->arg
,
7751 static int ip_no_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
7756 enum pim_msdp_err result
;
7757 struct in_addr mbr_ip
;
7759 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
7761 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
7762 errno
, safe_strerror(errno
));
7763 return CMD_WARNING_CONFIG_FAILED
;
7766 result
= pim_msdp_mg_mbr_del(pim
, mg
, mbr_ip
);
7768 case PIM_MSDP_ERR_NONE
:
7770 case PIM_MSDP_ERR_NO_MG
:
7771 vty_out(vty
, "%% mesh-group does not exist\n");
7773 case PIM_MSDP_ERR_NO_MG_MBR
:
7774 vty_out(vty
, "%% mesh-group member does not exist\n");
7777 vty_out(vty
, "%% mesh-group member del failed\n");
7780 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7782 DEFUN (no_ip_msdp_mesh_group_member
,
7783 no_ip_msdp_mesh_group_member_cmd
,
7784 "no ip msdp mesh-group WORD member A.B.C.D",
7788 "Delete MSDP mesh-group member\n"
7790 "mesh group member\n"
7791 "peer ip address\n")
7793 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7794 return ip_no_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[4]->arg
,
7798 static int ip_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
7799 struct vty
*vty
, const char *mg
,
7802 enum pim_msdp_err result
;
7803 struct in_addr src_ip
;
7805 result
= inet_pton(AF_INET
, src
, &src_ip
);
7807 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", src
,
7808 errno
, safe_strerror(errno
));
7809 return CMD_WARNING_CONFIG_FAILED
;
7812 result
= pim_msdp_mg_src_add(pim
, mg
, src_ip
);
7814 case PIM_MSDP_ERR_NONE
:
7816 case PIM_MSDP_ERR_OOM
:
7817 vty_out(vty
, "%% Out of memory\n");
7819 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
7820 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
7823 vty_out(vty
, "%% source add failed\n");
7826 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7830 DEFUN (ip_msdp_mesh_group_source
,
7831 ip_msdp_mesh_group_source_cmd
,
7832 "ip msdp mesh-group WORD source A.B.C.D",
7835 "Configure MSDP mesh-group\n"
7837 "mesh group local address\n"
7838 "source ip address for the TCP connection\n")
7840 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7841 return ip_msdp_mesh_group_source_cmd_worker(pim
, vty
, argv
[3]->arg
,
7845 static int ip_no_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
7849 enum pim_msdp_err result
;
7851 result
= pim_msdp_mg_src_del(pim
, mg
);
7853 case PIM_MSDP_ERR_NONE
:
7855 case PIM_MSDP_ERR_NO_MG
:
7856 vty_out(vty
, "%% mesh-group does not exist\n");
7859 vty_out(vty
, "%% mesh-group source del failed\n");
7862 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7865 static int ip_no_msdp_mesh_group_cmd_worker(struct pim_instance
*pim
,
7866 struct vty
*vty
, const char *mg
)
7868 enum pim_msdp_err result
;
7870 result
= pim_msdp_mg_del(pim
, mg
);
7872 case PIM_MSDP_ERR_NONE
:
7874 case PIM_MSDP_ERR_NO_MG
:
7875 vty_out(vty
, "%% mesh-group does not exist\n");
7878 vty_out(vty
, "%% mesh-group source del failed\n");
7881 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7884 DEFUN (no_ip_msdp_mesh_group_source
,
7885 no_ip_msdp_mesh_group_source_cmd
,
7886 "no ip msdp mesh-group WORD source [A.B.C.D]",
7890 "Delete MSDP mesh-group source\n"
7892 "mesh group source\n"
7893 "mesh group local address\n")
7895 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7897 return ip_no_msdp_mesh_group_cmd_worker(pim
, vty
, argv
[6]->arg
);
7899 return ip_no_msdp_mesh_group_source_cmd_worker(pim
, vty
,
7903 static void print_empty_json_obj(struct vty
*vty
)
7906 json
= json_object_new_object();
7907 vty_out(vty
, "%s\n",
7908 json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
));
7909 json_object_free(json
);
7912 static void ip_msdp_show_mesh_group(struct pim_instance
*pim
, struct vty
*vty
,
7915 struct listnode
*mbrnode
;
7916 struct pim_msdp_mg_mbr
*mbr
;
7917 struct pim_msdp_mg
*mg
= pim
->msdp
.mg
;
7918 char mbr_str
[INET_ADDRSTRLEN
];
7919 char src_str
[INET_ADDRSTRLEN
];
7920 char state_str
[PIM_MSDP_STATE_STRLEN
];
7921 enum pim_msdp_peer_state state
;
7922 json_object
*json
= NULL
;
7923 json_object
*json_mg_row
= NULL
;
7924 json_object
*json_members
= NULL
;
7925 json_object
*json_row
= NULL
;
7929 print_empty_json_obj(vty
);
7933 pim_inet4_dump("<source?>", mg
->src_ip
, src_str
, sizeof(src_str
));
7935 json
= json_object_new_object();
7936 /* currently there is only one mesh group but we should still
7938 * it a dict with mg-name as key */
7939 json_mg_row
= json_object_new_object();
7940 json_object_string_add(json_mg_row
, "name",
7941 mg
->mesh_group_name
);
7942 json_object_string_add(json_mg_row
, "source", src_str
);
7944 vty_out(vty
, "Mesh group : %s\n", mg
->mesh_group_name
);
7945 vty_out(vty
, " Source : %s\n", src_str
);
7946 vty_out(vty
, " Member State\n");
7949 for (ALL_LIST_ELEMENTS_RO(mg
->mbr_list
, mbrnode
, mbr
)) {
7950 pim_inet4_dump("<mbr?>", mbr
->mbr_ip
, mbr_str
, sizeof(mbr_str
));
7952 state
= mbr
->mp
->state
;
7954 state
= PIM_MSDP_DISABLED
;
7956 pim_msdp_state_dump(state
, state_str
, sizeof(state_str
));
7958 json_row
= json_object_new_object();
7959 json_object_string_add(json_row
, "member", mbr_str
);
7960 json_object_string_add(json_row
, "state", state_str
);
7961 if (!json_members
) {
7962 json_members
= json_object_new_object();
7963 json_object_object_add(json_mg_row
, "members",
7966 json_object_object_add(json_members
, mbr_str
, json_row
);
7968 vty_out(vty
, " %-15s %11s\n", mbr_str
, state_str
);
7973 json_object_object_add(json
, mg
->mesh_group_name
, json_mg_row
);
7974 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
7975 json
, JSON_C_TO_STRING_PRETTY
));
7976 json_object_free(json
);
7980 DEFUN (show_ip_msdp_mesh_group
,
7981 show_ip_msdp_mesh_group_cmd
,
7982 "show ip msdp [vrf NAME] mesh-group [json]",
7987 "MSDP mesh-group information\n"
7990 bool uj
= use_json(argc
, argv
);
7992 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
7997 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
8002 DEFUN (show_ip_msdp_mesh_group_vrf_all
,
8003 show_ip_msdp_mesh_group_vrf_all_cmd
,
8004 "show ip msdp vrf all mesh-group [json]",
8009 "MSDP mesh-group information\n"
8012 bool uj
= use_json(argc
, argv
);
8018 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
8022 vty_out(vty
, " \"%s\": ", vrf
->name
);
8025 vty_out(vty
, "VRF: %s\n", vrf
->name
);
8026 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
8029 vty_out(vty
, "}\n");
8034 static void ip_msdp_show_peers(struct pim_instance
*pim
, struct vty
*vty
,
8037 struct listnode
*mpnode
;
8038 struct pim_msdp_peer
*mp
;
8039 char peer_str
[INET_ADDRSTRLEN
];
8040 char local_str
[INET_ADDRSTRLEN
];
8041 char state_str
[PIM_MSDP_STATE_STRLEN
];
8042 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
8044 json_object
*json
= NULL
;
8045 json_object
*json_row
= NULL
;
8049 json
= json_object_new_object();
8052 "Peer Local State Uptime SaCnt\n");
8055 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
8056 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
8057 now
= pim_time_monotonic_sec();
8058 pim_time_uptime(timebuf
, sizeof(timebuf
),
8061 strcpy(timebuf
, "-");
8063 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
8064 pim_inet4_dump("<local?>", mp
->local
, local_str
,
8066 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
8068 json_row
= json_object_new_object();
8069 json_object_string_add(json_row
, "peer", peer_str
);
8070 json_object_string_add(json_row
, "local", local_str
);
8071 json_object_string_add(json_row
, "state", state_str
);
8072 json_object_string_add(json_row
, "upTime", timebuf
);
8073 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
8074 json_object_object_add(json
, peer_str
, json_row
);
8076 vty_out(vty
, "%-15s %15s %11s %8s %6d\n", peer_str
,
8077 local_str
, state_str
, timebuf
, mp
->sa_cnt
);
8082 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8083 json
, JSON_C_TO_STRING_PRETTY
));
8084 json_object_free(json
);
8088 static void ip_msdp_show_peers_detail(struct pim_instance
*pim
, struct vty
*vty
,
8089 const char *peer
, bool uj
)
8091 struct listnode
*mpnode
;
8092 struct pim_msdp_peer
*mp
;
8093 char peer_str
[INET_ADDRSTRLEN
];
8094 char local_str
[INET_ADDRSTRLEN
];
8095 char state_str
[PIM_MSDP_STATE_STRLEN
];
8096 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
8097 char katimer
[PIM_MSDP_TIMER_STRLEN
];
8098 char crtimer
[PIM_MSDP_TIMER_STRLEN
];
8099 char holdtimer
[PIM_MSDP_TIMER_STRLEN
];
8101 json_object
*json
= NULL
;
8102 json_object
*json_row
= NULL
;
8105 json
= json_object_new_object();
8108 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
8109 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
8110 if (strcmp(peer
, "detail") && strcmp(peer
, peer_str
))
8113 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
8114 now
= pim_time_monotonic_sec();
8115 pim_time_uptime(timebuf
, sizeof(timebuf
),
8118 strcpy(timebuf
, "-");
8120 pim_inet4_dump("<local?>", mp
->local
, local_str
,
8122 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
8123 pim_time_timer_to_hhmmss(katimer
, sizeof(katimer
),
8125 pim_time_timer_to_hhmmss(crtimer
, sizeof(crtimer
),
8127 pim_time_timer_to_hhmmss(holdtimer
, sizeof(holdtimer
),
8131 json_row
= json_object_new_object();
8132 json_object_string_add(json_row
, "peer", peer_str
);
8133 json_object_string_add(json_row
, "local", local_str
);
8134 json_object_string_add(json_row
, "meshGroupName",
8135 mp
->mesh_group_name
);
8136 json_object_string_add(json_row
, "state", state_str
);
8137 json_object_string_add(json_row
, "upTime", timebuf
);
8138 json_object_string_add(json_row
, "keepAliveTimer",
8140 json_object_string_add(json_row
, "connRetryTimer",
8142 json_object_string_add(json_row
, "holdTimer",
8144 json_object_string_add(json_row
, "lastReset",
8146 json_object_int_add(json_row
, "connAttempts",
8148 json_object_int_add(json_row
, "establishedChanges",
8150 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
8151 json_object_int_add(json_row
, "kaSent", mp
->ka_tx_cnt
);
8152 json_object_int_add(json_row
, "kaRcvd", mp
->ka_rx_cnt
);
8153 json_object_int_add(json_row
, "saSent", mp
->sa_tx_cnt
);
8154 json_object_int_add(json_row
, "saRcvd", mp
->sa_rx_cnt
);
8155 json_object_object_add(json
, peer_str
, json_row
);
8157 vty_out(vty
, "Peer : %s\n", peer_str
);
8158 vty_out(vty
, " Local : %s\n", local_str
);
8159 vty_out(vty
, " Mesh Group : %s\n",
8160 mp
->mesh_group_name
);
8161 vty_out(vty
, " State : %s\n", state_str
);
8162 vty_out(vty
, " Uptime : %s\n", timebuf
);
8164 vty_out(vty
, " Keepalive Timer : %s\n", katimer
);
8165 vty_out(vty
, " Conn Retry Timer : %s\n", crtimer
);
8166 vty_out(vty
, " Hold Timer : %s\n", holdtimer
);
8167 vty_out(vty
, " Last Reset : %s\n",
8169 vty_out(vty
, " Conn Attempts : %d\n",
8171 vty_out(vty
, " Established Changes : %d\n",
8173 vty_out(vty
, " SA Count : %d\n",
8175 vty_out(vty
, " Statistics :\n");
8178 vty_out(vty
, " Keepalives : %10d %10d\n",
8179 mp
->ka_tx_cnt
, mp
->ka_rx_cnt
);
8180 vty_out(vty
, " SAs : %10d %10d\n",
8181 mp
->sa_tx_cnt
, mp
->sa_rx_cnt
);
8187 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8188 json
, JSON_C_TO_STRING_PRETTY
));
8189 json_object_free(json
);
8193 DEFUN (show_ip_msdp_peer_detail
,
8194 show_ip_msdp_peer_detail_cmd
,
8195 "show ip msdp [vrf NAME] peer [detail|A.B.C.D] [json]",
8200 "MSDP peer information\n"
8205 bool uj
= use_json(argc
, argv
);
8207 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
8214 if (argv_find(argv
, argc
, "detail", &idx
))
8215 arg
= argv
[idx
]->text
;
8216 else if (argv_find(argv
, argc
, "A.B.C.D", &idx
))
8217 arg
= argv
[idx
]->arg
;
8220 ip_msdp_show_peers_detail(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
8222 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
8227 DEFUN (show_ip_msdp_peer_detail_vrf_all
,
8228 show_ip_msdp_peer_detail_vrf_all_cmd
,
8229 "show ip msdp vrf all peer [detail|A.B.C.D] [json]",
8234 "MSDP peer information\n"
8240 bool uj
= use_json(argc
, argv
);
8246 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
8250 vty_out(vty
, " \"%s\": ", vrf
->name
);
8253 vty_out(vty
, "VRF: %s\n", vrf
->name
);
8254 if (argv_find(argv
, argc
, "detail", &idx
)
8255 || argv_find(argv
, argc
, "A.B.C.D", &idx
))
8256 ip_msdp_show_peers_detail(vrf
->info
, vty
,
8257 argv
[idx
]->arg
, uj
);
8259 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
8262 vty_out(vty
, "}\n");
8267 static void ip_msdp_show_sa(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
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 bool 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 bool 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 bool 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
, bool 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
, bool 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 bool 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 bool 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_pim_rp_cmd
);
8642 install_element(VRF_NODE
, &ip_pim_rp_cmd
);
8643 install_element(CONFIG_NODE
, &no_ip_pim_rp_cmd
);
8644 install_element(VRF_NODE
, &no_ip_pim_rp_cmd
);
8645 install_element(CONFIG_NODE
, &ip_pim_rp_prefix_list_cmd
);
8646 install_element(VRF_NODE
, &ip_pim_rp_prefix_list_cmd
);
8647 install_element(CONFIG_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
8648 install_element(VRF_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
8649 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
8650 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
8651 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
8652 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
8653 install_element(CONFIG_NODE
, &ip_pim_ssm_prefix_list_cmd
);
8654 install_element(VRF_NODE
, &ip_pim_ssm_prefix_list_cmd
);
8655 install_element(CONFIG_NODE
, &ip_pim_register_suppress_cmd
);
8656 install_element(VRF_NODE
, &ip_pim_register_suppress_cmd
);
8657 install_element(CONFIG_NODE
, &no_ip_pim_register_suppress_cmd
);
8658 install_element(VRF_NODE
, &no_ip_pim_register_suppress_cmd
);
8659 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
8660 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
8661 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
8662 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
8663 install_element(CONFIG_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
8664 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
8665 install_element(CONFIG_NODE
,
8666 &no_ip_pim_spt_switchover_infinity_plist_cmd
);
8667 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_plist_cmd
);
8668 install_element(CONFIG_NODE
, &ip_pim_joinprune_time_cmd
);
8669 install_element(VRF_NODE
, &ip_pim_joinprune_time_cmd
);
8670 install_element(CONFIG_NODE
, &no_ip_pim_joinprune_time_cmd
);
8671 install_element(VRF_NODE
, &no_ip_pim_joinprune_time_cmd
);
8672 install_element(CONFIG_NODE
, &ip_pim_keep_alive_cmd
);
8673 install_element(VRF_NODE
, &ip_pim_keep_alive_cmd
);
8674 install_element(CONFIG_NODE
, &ip_pim_rp_keep_alive_cmd
);
8675 install_element(VRF_NODE
, &ip_pim_rp_keep_alive_cmd
);
8676 install_element(CONFIG_NODE
, &no_ip_pim_keep_alive_cmd
);
8677 install_element(VRF_NODE
, &no_ip_pim_keep_alive_cmd
);
8678 install_element(CONFIG_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
8679 install_element(VRF_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
8680 install_element(CONFIG_NODE
, &ip_pim_packets_cmd
);
8681 install_element(VRF_NODE
, &ip_pim_packets_cmd
);
8682 install_element(CONFIG_NODE
, &no_ip_pim_packets_cmd
);
8683 install_element(VRF_NODE
, &no_ip_pim_packets_cmd
);
8684 install_element(CONFIG_NODE
, &ip_pim_v6_secondary_cmd
);
8685 install_element(VRF_NODE
, &ip_pim_v6_secondary_cmd
);
8686 install_element(CONFIG_NODE
, &no_ip_pim_v6_secondary_cmd
);
8687 install_element(VRF_NODE
, &no_ip_pim_v6_secondary_cmd
);
8688 install_element(CONFIG_NODE
, &ip_ssmpingd_cmd
);
8689 install_element(VRF_NODE
, &ip_ssmpingd_cmd
);
8690 install_element(CONFIG_NODE
, &no_ip_ssmpingd_cmd
);
8691 install_element(VRF_NODE
, &no_ip_ssmpingd_cmd
);
8692 install_element(CONFIG_NODE
, &ip_msdp_peer_cmd
);
8693 install_element(VRF_NODE
, &ip_msdp_peer_cmd
);
8694 install_element(CONFIG_NODE
, &no_ip_msdp_peer_cmd
);
8695 install_element(VRF_NODE
, &no_ip_msdp_peer_cmd
);
8696 install_element(CONFIG_NODE
, &ip_pim_ecmp_cmd
);
8697 install_element(VRF_NODE
, &ip_pim_ecmp_cmd
);
8698 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_cmd
);
8699 install_element(VRF_NODE
, &no_ip_pim_ecmp_cmd
);
8700 install_element(CONFIG_NODE
, &ip_pim_ecmp_rebalance_cmd
);
8701 install_element(VRF_NODE
, &ip_pim_ecmp_rebalance_cmd
);
8702 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
8703 install_element(VRF_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
8705 install_element(INTERFACE_NODE
, &interface_ip_igmp_cmd
);
8706 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_cmd
);
8707 install_element(INTERFACE_NODE
, &interface_ip_igmp_join_cmd
);
8708 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_join_cmd
);
8709 install_element(INTERFACE_NODE
, &interface_ip_igmp_version_cmd
);
8710 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_version_cmd
);
8711 install_element(INTERFACE_NODE
, &interface_ip_igmp_query_interval_cmd
);
8712 install_element(INTERFACE_NODE
,
8713 &interface_no_ip_igmp_query_interval_cmd
);
8714 install_element(INTERFACE_NODE
,
8715 &interface_ip_igmp_query_max_response_time_cmd
);
8716 install_element(INTERFACE_NODE
,
8717 &interface_no_ip_igmp_query_max_response_time_cmd
);
8718 install_element(INTERFACE_NODE
,
8719 &interface_ip_igmp_query_max_response_time_dsec_cmd
);
8720 install_element(INTERFACE_NODE
,
8721 &interface_no_ip_igmp_query_max_response_time_dsec_cmd
);
8722 install_element(INTERFACE_NODE
, &interface_ip_pim_ssm_cmd
);
8723 install_element(INTERFACE_NODE
, &interface_no_ip_pim_ssm_cmd
);
8724 install_element(INTERFACE_NODE
, &interface_ip_pim_sm_cmd
);
8725 install_element(INTERFACE_NODE
, &interface_no_ip_pim_sm_cmd
);
8726 install_element(INTERFACE_NODE
, &interface_ip_pim_cmd
);
8727 install_element(INTERFACE_NODE
, &interface_no_ip_pim_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
);
8910 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_param_cmd
);
8911 #endif /* !HAVE_BFDD */