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
,
609 "%-9s %5s %15s %d %7s %11s %8s\n",
611 if_is_up(ifp
) ? "up" : "down",
612 inet_ntoa(igmp
->ifaddr
),
613 pim_ifp
->igmp_version
,
614 igmp
->t_igmp_query_timer
? "local"
616 query_hhmmss
, uptime
);
622 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
623 json
, JSON_C_TO_STRING_PRETTY
));
624 json_object_free(json
);
628 static void igmp_show_interfaces_single(struct pim_instance
*pim
,
629 struct vty
*vty
, const char *ifname
,
632 struct igmp_sock
*igmp
;
633 struct interface
*ifp
;
634 struct listnode
*sock_node
;
635 struct pim_interface
*pim_ifp
;
637 char query_hhmmss
[10];
638 char other_hhmmss
[10];
639 int found_ifname
= 0;
642 long gmi_msec
; /* Group Membership Interval */
645 long oqpi_msec
; /* Other Querier Present Interval */
649 json_object
*json
= NULL
;
650 json_object
*json_row
= NULL
;
653 json
= json_object_new_object();
655 now
= pim_time_monotonic_sec();
657 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
663 if (strcmp(ifname
, "detail") && strcmp(ifname
, ifp
->name
))
666 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
669 pim_time_uptime(uptime
, sizeof(uptime
),
670 now
- igmp
->sock_creation
);
671 pim_time_timer_to_hhmmss(query_hhmmss
,
672 sizeof(query_hhmmss
),
673 igmp
->t_igmp_query_timer
);
674 pim_time_timer_to_hhmmss(other_hhmmss
,
675 sizeof(other_hhmmss
),
676 igmp
->t_other_querier_timer
);
678 gmi_msec
= PIM_IGMP_GMI_MSEC(
679 igmp
->querier_robustness_variable
,
680 igmp
->querier_query_interval
,
681 pim_ifp
->igmp_query_max_response_time_dsec
);
684 pim_ifp
->igmp_default_query_interval
);
686 oqpi_msec
= PIM_IGMP_OQPI_MSEC(
687 igmp
->querier_robustness_variable
,
688 igmp
->querier_query_interval
,
689 pim_ifp
->igmp_query_max_response_time_dsec
);
691 lmqt_msec
= PIM_IGMP_LMQT_MSEC(
692 pim_ifp
->igmp_query_max_response_time_dsec
,
693 igmp
->querier_robustness_variable
);
697 igmp
->querier_robustness_variable
,
698 igmp
->querier_query_interval
,
699 pim_ifp
->igmp_query_max_response_time_dsec
)
702 qri_msec
= pim_ifp
->igmp_query_max_response_time_dsec
704 if (pim_ifp
->pim_sock_fd
>= 0)
705 mloop
= pim_socket_mcastloop_get(
706 pim_ifp
->pim_sock_fd
);
711 json_row
= json_object_new_object();
712 json_object_pim_ifp_add(json_row
, ifp
);
713 json_object_string_add(json_row
, "upTime",
715 json_object_string_add(json_row
, "querier",
716 igmp
->t_igmp_query_timer
719 json_object_int_add(json_row
, "queryStartCount",
720 igmp
->startup_query_count
);
721 json_object_string_add(json_row
,
724 json_object_string_add(json_row
,
727 json_object_int_add(json_row
, "version",
728 pim_ifp
->igmp_version
);
731 "timerGroupMembershipIntervalMsec",
733 json_object_int_add(json_row
,
734 "timerLastMemberQueryMsec",
738 "timerOlderHostPresentIntervalMsec",
742 "timerOtherQuerierPresentIntervalMsec",
745 json_row
, "timerQueryInterval",
746 igmp
->querier_query_interval
);
749 "timerQueryResponseIntervalMsec",
752 json_row
, "timerRobustnessVariable",
753 igmp
->querier_robustness_variable
);
754 json_object_int_add(json_row
,
755 "timerStartupQueryInterval",
758 json_object_object_add(json
, ifp
->name
,
762 vty_out(vty
, "Interface : %s\n", ifp
->name
);
763 vty_out(vty
, "State : %s\n",
764 if_is_up(ifp
) ? "up" : "down");
765 vty_out(vty
, "Address : %s\n",
766 inet_ntoa(pim_ifp
->primary_address
));
767 vty_out(vty
, "Uptime : %s\n", uptime
);
768 vty_out(vty
, "Version : %d\n",
769 pim_ifp
->igmp_version
);
773 vty_out(vty
, "Querier\n");
774 vty_out(vty
, "-------\n");
775 vty_out(vty
, "Querier : %s\n",
776 igmp
->t_igmp_query_timer
? "local"
778 vty_out(vty
, "Start Count : %d\n",
779 igmp
->startup_query_count
);
780 vty_out(vty
, "Query Timer : %s\n",
782 vty_out(vty
, "Other Timer : %s\n",
787 vty_out(vty
, "Timers\n");
788 vty_out(vty
, "------\n");
790 "Group Membership Interval : %lis\n",
793 "Last Member Query Time : %lis\n",
796 "Older Host Present Interval : %lis\n",
799 "Other Querier Present Interval : %lis\n",
802 "Query Interval : %ds\n",
803 igmp
->querier_query_interval
);
805 "Query Response Interval : %lis\n",
808 "Robustness Variable : %d\n",
809 igmp
->querier_robustness_variable
);
811 "Startup Query Interval : %ds\n",
816 pim_print_ifp_flags(vty
, ifp
, mloop
);
822 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
823 json
, JSON_C_TO_STRING_PRETTY
));
824 json_object_free(json
);
827 vty_out(vty
, "%% No such interface\n");
831 static void igmp_show_interface_join(struct pim_instance
*pim
, struct vty
*vty
)
833 struct interface
*ifp
;
836 now
= pim_time_monotonic_sec();
839 "Interface Address Source Group Socket Uptime \n");
841 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
842 struct pim_interface
*pim_ifp
;
843 struct listnode
*join_node
;
844 struct igmp_join
*ij
;
845 struct in_addr pri_addr
;
846 char pri_addr_str
[INET_ADDRSTRLEN
];
853 if (!pim_ifp
->igmp_join_list
)
856 pri_addr
= pim_find_primary_addr(ifp
);
857 pim_inet4_dump("<pri?>", pri_addr
, pri_addr_str
,
858 sizeof(pri_addr_str
));
860 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_join_list
, join_node
,
862 char group_str
[INET_ADDRSTRLEN
];
863 char source_str
[INET_ADDRSTRLEN
];
866 pim_time_uptime(uptime
, sizeof(uptime
),
867 now
- ij
->sock_creation
);
868 pim_inet4_dump("<grp?>", ij
->group_addr
, group_str
,
870 pim_inet4_dump("<src?>", ij
->source_addr
, source_str
,
873 vty_out(vty
, "%-9s %-15s %-15s %-15s %6d %8s\n",
874 ifp
->name
, pri_addr_str
, source_str
, group_str
,
875 ij
->sock_fd
, uptime
);
876 } /* for (pim_ifp->igmp_join_list) */
881 static void pim_show_interfaces_single(struct pim_instance
*pim
,
882 struct vty
*vty
, const char *ifname
,
885 struct in_addr ifaddr
;
886 struct interface
*ifp
;
887 struct listnode
*neighnode
;
888 struct listnode
*upnode
;
889 struct pim_interface
*pim_ifp
;
890 struct pim_neighbor
*neigh
;
891 struct pim_upstream
*up
;
893 char dr_str
[INET_ADDRSTRLEN
];
896 char grp_str
[INET_ADDRSTRLEN
];
897 char hello_period
[10];
898 char hello_timer
[10];
899 char neigh_src_str
[INET_ADDRSTRLEN
];
900 char src_str
[INET_ADDRSTRLEN
];
901 char stat_uptime
[10];
904 int found_ifname
= 0;
906 json_object
*json
= NULL
;
907 json_object
*json_row
= NULL
;
908 json_object
*json_pim_neighbor
= NULL
;
909 json_object
*json_pim_neighbors
= NULL
;
910 json_object
*json_group
= NULL
;
911 json_object
*json_group_source
= NULL
;
912 json_object
*json_fhr_sources
= NULL
;
913 struct pim_secondary_addr
*sec_addr
;
914 struct listnode
*sec_node
;
916 now
= pim_time_monotonic_sec();
919 json
= json_object_new_object();
921 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
927 if (strcmp(ifname
, "detail") && strcmp(ifname
, ifp
->name
))
931 ifaddr
= pim_ifp
->primary_address
;
932 pim_inet4_dump("<dr?>", pim_ifp
->pim_dr_addr
, dr_str
,
934 pim_time_uptime_begin(dr_uptime
, sizeof(dr_uptime
), now
,
935 pim_ifp
->pim_dr_election_last
);
936 pim_time_timer_to_hhmmss(hello_timer
, sizeof(hello_timer
),
937 pim_ifp
->t_pim_hello_timer
);
938 pim_time_mmss(hello_period
, sizeof(hello_period
),
939 pim_ifp
->pim_hello_period
);
940 pim_time_uptime(stat_uptime
, sizeof(stat_uptime
),
941 now
- pim_ifp
->pim_ifstat_start
);
942 if (pim_ifp
->pim_sock_fd
>= 0)
943 mloop
= pim_socket_mcastloop_get(pim_ifp
->pim_sock_fd
);
948 char pbuf
[PREFIX2STR_BUFFER
];
949 json_row
= json_object_new_object();
950 json_object_pim_ifp_add(json_row
, ifp
);
952 if (pim_ifp
->update_source
.s_addr
!= INADDR_ANY
) {
953 json_object_string_add(
954 json_row
, "useSource",
955 inet_ntoa(pim_ifp
->update_source
));
957 if (pim_ifp
->sec_addr_list
) {
958 json_object
*sec_list
= NULL
;
960 sec_list
= json_object_new_array();
961 for (ALL_LIST_ELEMENTS_RO(
962 pim_ifp
->sec_addr_list
, sec_node
,
964 json_object_array_add(
966 json_object_new_string(
972 json_object_object_add(json_row
,
973 "secondaryAddressList",
978 if (pim_ifp
->pim_neighbor_list
->count
) {
979 json_pim_neighbors
= json_object_new_object();
981 for (ALL_LIST_ELEMENTS_RO(
982 pim_ifp
->pim_neighbor_list
,
985 json_object_new_object();
986 pim_inet4_dump("<src?>",
989 sizeof(neigh_src_str
));
990 pim_time_uptime(uptime
, sizeof(uptime
),
991 now
- neigh
->creation
);
992 pim_time_timer_to_hhmmss(
993 expire
, sizeof(expire
),
994 neigh
->t_expire_timer
);
996 json_object_string_add(
997 json_pim_neighbor
, "address",
999 json_object_string_add(
1000 json_pim_neighbor
, "upTime",
1002 json_object_string_add(
1003 json_pim_neighbor
, "holdtime",
1006 json_object_object_add(
1012 json_object_object_add(json_row
, "neighbors",
1013 json_pim_neighbors
);
1016 json_object_string_add(json_row
, "drAddress", dr_str
);
1017 json_object_int_add(json_row
, "drPriority",
1018 pim_ifp
->pim_dr_priority
);
1019 json_object_string_add(json_row
, "drUptime", dr_uptime
);
1020 json_object_int_add(json_row
, "drElections",
1021 pim_ifp
->pim_dr_election_count
);
1022 json_object_int_add(json_row
, "drChanges",
1023 pim_ifp
->pim_dr_election_changes
);
1026 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
,
1028 if (ifp
!= up
->rpf
.source_nexthop
.interface
)
1031 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
))
1034 if (!json_fhr_sources
)
1036 json_object_new_object();
1038 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
,
1040 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
,
1042 pim_time_uptime(uptime
, sizeof(uptime
),
1043 now
- up
->state_transition
);
1046 * Does this group live in json_fhr_sources?
1049 json_object_object_get_ex(json_fhr_sources
,
1050 grp_str
, &json_group
);
1053 json_group
= json_object_new_object();
1054 json_object_object_add(json_fhr_sources
,
1059 json_group_source
= json_object_new_object();
1060 json_object_string_add(json_group_source
,
1062 json_object_string_add(json_group_source
,
1064 json_object_string_add(json_group_source
,
1066 json_object_object_add(json_group
, src_str
,
1070 if (json_fhr_sources
) {
1071 json_object_object_add(json_row
,
1076 json_object_int_add(json_row
, "helloPeriod",
1077 pim_ifp
->pim_hello_period
);
1078 json_object_string_add(json_row
, "helloTimer",
1080 json_object_string_add(json_row
, "helloStatStart",
1082 json_object_int_add(json_row
, "helloReceived",
1083 pim_ifp
->pim_ifstat_hello_recv
);
1084 json_object_int_add(json_row
, "helloReceivedFailed",
1085 pim_ifp
->pim_ifstat_hello_recvfail
);
1086 json_object_int_add(json_row
, "helloSend",
1087 pim_ifp
->pim_ifstat_hello_sent
);
1088 json_object_int_add(json_row
, "hellosendFailed",
1089 pim_ifp
->pim_ifstat_hello_sendfail
);
1090 json_object_int_add(json_row
, "helloGenerationId",
1091 pim_ifp
->pim_generation_id
);
1092 json_object_int_add(json_row
, "flagMulticastLoop",
1095 json_object_int_add(
1096 json_row
, "effectivePropagationDelay",
1097 pim_if_effective_propagation_delay_msec(ifp
));
1098 json_object_int_add(
1099 json_row
, "effectiveOverrideInterval",
1100 pim_if_effective_override_interval_msec(ifp
));
1101 json_object_int_add(
1102 json_row
, "joinPruneOverrideInterval",
1103 pim_if_jp_override_interval_msec(ifp
));
1105 json_object_int_add(
1106 json_row
, "propagationDelay",
1107 pim_ifp
->pim_propagation_delay_msec
);
1108 json_object_int_add(
1109 json_row
, "propagationDelayHighest",
1110 pim_ifp
->pim_neighbors_highest_propagation_delay_msec
);
1111 json_object_int_add(
1112 json_row
, "overrideInterval",
1113 pim_ifp
->pim_override_interval_msec
);
1114 json_object_int_add(
1115 json_row
, "overrideIntervalHighest",
1116 pim_ifp
->pim_neighbors_highest_override_interval_msec
);
1117 json_object_object_add(json
, ifp
->name
, json_row
);
1120 vty_out(vty
, "Interface : %s\n", ifp
->name
);
1121 vty_out(vty
, "State : %s\n",
1122 if_is_up(ifp
) ? "up" : "down");
1123 if (pim_ifp
->update_source
.s_addr
!= INADDR_ANY
) {
1124 vty_out(vty
, "Use Source : %s\n",
1125 inet_ntoa(pim_ifp
->update_source
));
1127 if (pim_ifp
->sec_addr_list
) {
1128 char pbuf
[PREFIX2STR_BUFFER
];
1129 vty_out(vty
, "Address : %s (primary)\n",
1131 for (ALL_LIST_ELEMENTS_RO(
1132 pim_ifp
->sec_addr_list
, sec_node
,
1134 vty_out(vty
, " %s\n",
1135 prefix2str(&sec_addr
->addr
,
1136 pbuf
, sizeof(pbuf
)));
1139 vty_out(vty
, "Address : %s\n",
1147 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
,
1148 neighnode
, neigh
)) {
1151 vty_out(vty
, "PIM Neighbors\n");
1152 vty_out(vty
, "-------------\n");
1156 pim_inet4_dump("<src?>", neigh
->source_addr
,
1158 sizeof(neigh_src_str
));
1159 pim_time_uptime(uptime
, sizeof(uptime
),
1160 now
- neigh
->creation
);
1161 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
1162 neigh
->t_expire_timer
);
1164 "%-15s : up for %s, holdtime expires in %s\n",
1165 neigh_src_str
, uptime
, expire
);
1168 if (!print_header
) {
1173 vty_out(vty
, "Designated Router\n");
1174 vty_out(vty
, "-----------------\n");
1175 vty_out(vty
, "Address : %s\n", dr_str
);
1176 vty_out(vty
, "Priority : %d\n",
1177 pim_ifp
->pim_dr_priority
);
1178 vty_out(vty
, "Uptime : %s\n", dr_uptime
);
1179 vty_out(vty
, "Elections : %d\n",
1180 pim_ifp
->pim_dr_election_count
);
1181 vty_out(vty
, "Changes : %d\n",
1182 pim_ifp
->pim_dr_election_changes
);
1188 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
,
1191 if (strcmp(ifp
->name
,
1192 up
->rpf
.source_nexthop
1197 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
))
1202 "FHR - First Hop Router\n");
1204 "----------------------\n");
1208 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
,
1210 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
,
1212 pim_time_uptime(uptime
, sizeof(uptime
),
1213 now
- up
->state_transition
);
1215 "%s : %s is a source, uptime is %s\n",
1216 grp_str
, src_str
, uptime
);
1219 if (!print_header
) {
1224 vty_out(vty
, "Hellos\n");
1225 vty_out(vty
, "------\n");
1226 vty_out(vty
, "Period : %d\n",
1227 pim_ifp
->pim_hello_period
);
1228 vty_out(vty
, "Timer : %s\n", hello_timer
);
1229 vty_out(vty
, "StatStart : %s\n", stat_uptime
);
1230 vty_out(vty
, "Receive : %d\n",
1231 pim_ifp
->pim_ifstat_hello_recv
);
1232 vty_out(vty
, "Receive Failed : %d\n",
1233 pim_ifp
->pim_ifstat_hello_recvfail
);
1234 vty_out(vty
, "Send : %d\n",
1235 pim_ifp
->pim_ifstat_hello_sent
);
1236 vty_out(vty
, "Send Failed : %d\n",
1237 pim_ifp
->pim_ifstat_hello_sendfail
);
1238 vty_out(vty
, "Generation ID : %08x\n",
1239 pim_ifp
->pim_generation_id
);
1243 pim_print_ifp_flags(vty
, ifp
, mloop
);
1245 vty_out(vty
, "Join Prune Interval\n");
1246 vty_out(vty
, "-------------------\n");
1247 vty_out(vty
, "LAN Delay : %s\n",
1248 pim_if_lan_delay_enabled(ifp
) ? "yes" : "no");
1249 vty_out(vty
, "Effective Propagation Delay : %d msec\n",
1250 pim_if_effective_propagation_delay_msec(ifp
));
1251 vty_out(vty
, "Effective Override Interval : %d msec\n",
1252 pim_if_effective_override_interval_msec(ifp
));
1253 vty_out(vty
, "Join Prune Override Interval : %d msec\n",
1254 pim_if_jp_override_interval_msec(ifp
));
1258 vty_out(vty
, "LAN Prune Delay\n");
1259 vty_out(vty
, "---------------\n");
1260 vty_out(vty
, "Propagation Delay : %d msec\n",
1261 pim_ifp
->pim_propagation_delay_msec
);
1262 vty_out(vty
, "Propagation Delay (Highest) : %d msec\n",
1263 pim_ifp
->pim_neighbors_highest_propagation_delay_msec
);
1264 vty_out(vty
, "Override Interval : %d msec\n",
1265 pim_ifp
->pim_override_interval_msec
);
1266 vty_out(vty
, "Override Interval (Highest) : %d msec\n",
1267 pim_ifp
->pim_neighbors_highest_override_interval_msec
);
1274 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1275 json
, JSON_C_TO_STRING_PRETTY
));
1276 json_object_free(json
);
1279 vty_out(vty
, "%% No such interface\n");
1283 static void pim_show_interfaces(struct pim_instance
*pim
, struct vty
*vty
,
1286 struct interface
*ifp
;
1287 struct listnode
*upnode
;
1288 struct pim_interface
*pim_ifp
;
1289 struct pim_upstream
*up
;
1292 int pim_ifchannels
= 0;
1293 json_object
*json
= NULL
;
1294 json_object
*json_row
= NULL
;
1295 json_object
*json_tmp
;
1297 json
= json_object_new_object();
1299 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1300 pim_ifp
= ifp
->info
;
1305 pim_nbrs
= pim_ifp
->pim_neighbor_list
->count
;
1306 pim_ifchannels
= pim_if_ifchannel_count(pim_ifp
);
1309 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
, up
))
1310 if (ifp
== up
->rpf
.source_nexthop
.interface
)
1311 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
1314 json_row
= json_object_new_object();
1315 json_object_pim_ifp_add(json_row
, ifp
);
1316 json_object_int_add(json_row
, "pimNeighbors", pim_nbrs
);
1317 json_object_int_add(json_row
, "pimIfChannels", pim_ifchannels
);
1318 json_object_int_add(json_row
, "firstHopRouterCount", fhr
);
1319 json_object_string_add(json_row
, "pimDesignatedRouter",
1320 inet_ntoa(pim_ifp
->pim_dr_addr
));
1322 if (pim_ifp
->pim_dr_addr
.s_addr
1323 == pim_ifp
->primary_address
.s_addr
)
1324 json_object_boolean_true_add(
1325 json_row
, "pimDesignatedRouterLocal");
1327 json_object_object_add(json
, ifp
->name
, json_row
);
1331 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1332 json
, JSON_C_TO_STRING_PRETTY
));
1335 "Interface State Address PIM Nbrs PIM DR FHR IfChannels\n");
1337 json_object_object_foreach(json
, key
, val
)
1339 vty_out(vty
, "%-9s ", key
);
1341 json_object_object_get_ex(val
, "state", &json_tmp
);
1342 vty_out(vty
, "%5s ", json_object_get_string(json_tmp
));
1344 json_object_object_get_ex(val
, "address", &json_tmp
);
1345 vty_out(vty
, "%15s ",
1346 json_object_get_string(json_tmp
));
1348 json_object_object_get_ex(val
, "pimNeighbors",
1350 vty_out(vty
, "%8d ", json_object_get_int(json_tmp
));
1352 if (json_object_object_get_ex(
1353 val
, "pimDesignatedRouterLocal",
1355 vty_out(vty
, "%15s ", "local");
1357 json_object_object_get_ex(
1358 val
, "pimDesignatedRouter", &json_tmp
);
1359 vty_out(vty
, "%15s ",
1360 json_object_get_string(json_tmp
));
1363 json_object_object_get_ex(val
, "firstHopRouter",
1365 vty_out(vty
, "%3d ", json_object_get_int(json_tmp
));
1367 json_object_object_get_ex(val
, "pimIfChannels",
1369 vty_out(vty
, "%9d\n", json_object_get_int(json_tmp
));
1373 json_object_free(json
);
1376 static void pim_show_interface_traffic(struct pim_instance
*pim
,
1377 struct vty
*vty
, u_char uj
)
1379 struct interface
*ifp
= NULL
;
1380 struct pim_interface
*pim_ifp
= NULL
;
1381 json_object
*json
= NULL
;
1382 json_object
*json_row
= NULL
;
1385 json
= json_object_new_object();
1388 vty_out(vty
, "%-12s%-17s%-17s%-17s%-17s%-17s%-17s\n",
1389 "Interface", " HELLO", " JOIN", " PRUNE",
1390 " REGISTER", " REGISTER-STOP", " ASSERT");
1391 vty_out(vty
, "%-10s%-18s%-17s%-17s%-17s%-17s%-17s\n", "",
1392 " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1393 " Rx/Tx", " Rx/Tx");
1395 "---------------------------------------------------------------------------------------------------------------\n");
1398 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1399 pim_ifp
= ifp
->info
;
1404 if (pim_ifp
->pim_sock_fd
< 0)
1407 json_row
= json_object_new_object();
1408 json_object_pim_ifp_add(json_row
, ifp
);
1409 json_object_int_add(json_row
, "helloRx",
1410 pim_ifp
->pim_ifstat_hello_recv
);
1411 json_object_int_add(json_row
, "helloTx",
1412 pim_ifp
->pim_ifstat_hello_sent
);
1413 json_object_int_add(json_row
, "joinRx",
1414 pim_ifp
->pim_ifstat_join_recv
);
1415 json_object_int_add(json_row
, "joinTx",
1416 pim_ifp
->pim_ifstat_join_send
);
1417 json_object_int_add(json_row
, "registerRx",
1418 pim_ifp
->pim_ifstat_reg_recv
);
1419 json_object_int_add(json_row
, "registerTx",
1420 pim_ifp
->pim_ifstat_reg_recv
);
1421 json_object_int_add(json_row
, "registerStopRx",
1422 pim_ifp
->pim_ifstat_reg_stop_recv
);
1423 json_object_int_add(json_row
, "registerStopTx",
1424 pim_ifp
->pim_ifstat_reg_stop_send
);
1425 json_object_int_add(json_row
, "assertRx",
1426 pim_ifp
->pim_ifstat_assert_recv
);
1427 json_object_int_add(json_row
, "assertTx",
1428 pim_ifp
->pim_ifstat_assert_send
);
1430 json_object_object_add(json
, ifp
->name
, json_row
);
1433 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u \n",
1434 ifp
->name
, pim_ifp
->pim_ifstat_hello_recv
,
1435 pim_ifp
->pim_ifstat_hello_sent
,
1436 pim_ifp
->pim_ifstat_join_recv
,
1437 pim_ifp
->pim_ifstat_join_send
,
1438 pim_ifp
->pim_ifstat_prune_recv
,
1439 pim_ifp
->pim_ifstat_prune_send
,
1440 pim_ifp
->pim_ifstat_reg_recv
,
1441 pim_ifp
->pim_ifstat_reg_send
,
1442 pim_ifp
->pim_ifstat_reg_stop_recv
,
1443 pim_ifp
->pim_ifstat_reg_stop_send
,
1444 pim_ifp
->pim_ifstat_assert_recv
,
1445 pim_ifp
->pim_ifstat_assert_send
);
1449 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1450 json
, JSON_C_TO_STRING_PRETTY
));
1451 json_object_free(json
);
1455 static void pim_show_interface_traffic_single(struct pim_instance
*pim
,
1457 const char *ifname
, u_char uj
)
1459 struct interface
*ifp
= NULL
;
1460 struct pim_interface
*pim_ifp
= NULL
;
1461 json_object
*json
= NULL
;
1462 json_object
*json_row
= NULL
;
1463 uint8_t found_ifname
= 0;
1466 json
= json_object_new_object();
1469 vty_out(vty
, "%-12s%-17s%-17s%-17s%-17s%-17s%-17s\n",
1470 "Interface", " HELLO", " JOIN", " PRUNE",
1471 " REGISTER", " REGISTER-STOP", " ASSERT");
1472 vty_out(vty
, "%-10s%-18s%-17s%-17s%-17s%-17s%-17s\n", "",
1473 " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1474 " Rx/Tx", " Rx/Tx");
1476 "---------------------------------------------------------------------------------------------------------------\n");
1479 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1480 if (strcmp(ifname
, ifp
->name
))
1483 pim_ifp
= ifp
->info
;
1488 if (pim_ifp
->pim_sock_fd
< 0)
1493 json_row
= json_object_new_object();
1494 json_object_pim_ifp_add(json_row
, ifp
);
1495 json_object_int_add(json_row
, "helloRx",
1496 pim_ifp
->pim_ifstat_hello_recv
);
1497 json_object_int_add(json_row
, "helloTx",
1498 pim_ifp
->pim_ifstat_hello_sent
);
1499 json_object_int_add(json_row
, "joinRx",
1500 pim_ifp
->pim_ifstat_join_recv
);
1501 json_object_int_add(json_row
, "joinTx",
1502 pim_ifp
->pim_ifstat_join_send
);
1503 json_object_int_add(json_row
, "registerRx",
1504 pim_ifp
->pim_ifstat_reg_recv
);
1505 json_object_int_add(json_row
, "registerTx",
1506 pim_ifp
->pim_ifstat_reg_recv
);
1507 json_object_int_add(json_row
, "registerStopRx",
1508 pim_ifp
->pim_ifstat_reg_stop_recv
);
1509 json_object_int_add(json_row
, "registerStopTx",
1510 pim_ifp
->pim_ifstat_reg_stop_send
);
1511 json_object_int_add(json_row
, "assertRx",
1512 pim_ifp
->pim_ifstat_assert_recv
);
1513 json_object_int_add(json_row
, "assertTx",
1514 pim_ifp
->pim_ifstat_assert_send
);
1516 json_object_object_add(json
, ifp
->name
, json_row
);
1519 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u \n",
1520 ifp
->name
, pim_ifp
->pim_ifstat_hello_recv
,
1521 pim_ifp
->pim_ifstat_hello_sent
,
1522 pim_ifp
->pim_ifstat_join_recv
,
1523 pim_ifp
->pim_ifstat_join_send
,
1524 pim_ifp
->pim_ifstat_prune_recv
,
1525 pim_ifp
->pim_ifstat_prune_send
,
1526 pim_ifp
->pim_ifstat_reg_recv
,
1527 pim_ifp
->pim_ifstat_reg_send
,
1528 pim_ifp
->pim_ifstat_reg_stop_recv
,
1529 pim_ifp
->pim_ifstat_reg_stop_send
,
1530 pim_ifp
->pim_ifstat_assert_recv
,
1531 pim_ifp
->pim_ifstat_assert_send
);
1535 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1536 json
, JSON_C_TO_STRING_PRETTY
));
1537 json_object_free(json
);
1540 vty_out(vty
, "%% No such interface\n");
1544 static void pim_show_join_helper(struct vty
*vty
, struct pim_interface
*pim_ifp
,
1545 struct pim_ifchannel
*ch
, json_object
*json
,
1546 time_t now
, u_char uj
)
1548 char ch_src_str
[INET_ADDRSTRLEN
];
1549 char ch_grp_str
[INET_ADDRSTRLEN
];
1550 json_object
*json_iface
= NULL
;
1551 json_object
*json_row
= NULL
;
1552 json_object
*json_grp
= NULL
;
1553 struct in_addr ifaddr
;
1558 ifaddr
= pim_ifp
->primary_address
;
1560 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
1561 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
1563 pim_time_uptime_begin(uptime
, sizeof(uptime
), now
, ch
->ifjoin_creation
);
1564 pim_time_timer_to_mmss(expire
, sizeof(expire
),
1565 ch
->t_ifjoin_expiry_timer
);
1566 pim_time_timer_to_mmss(prune
, sizeof(prune
),
1567 ch
->t_ifjoin_prune_pending_timer
);
1570 json_object_object_get_ex(json
, ch
->interface
->name
,
1574 json_iface
= json_object_new_object();
1575 json_object_pim_ifp_add(json_iface
, ch
->interface
);
1576 json_object_object_add(json
, ch
->interface
->name
,
1580 json_row
= json_object_new_object();
1581 json_object_string_add(json_row
, "source", ch_src_str
);
1582 json_object_string_add(json_row
, "group", ch_grp_str
);
1583 json_object_string_add(json_row
, "upTime", uptime
);
1584 json_object_string_add(json_row
, "expire", expire
);
1585 json_object_string_add(json_row
, "prune", prune
);
1586 json_object_string_add(
1587 json_row
, "channelJoinName",
1588 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
, ch
->flags
));
1589 if (PIM_IF_FLAG_TEST_S_G_RPT(ch
->flags
))
1590 json_object_int_add(json_row
, "SGRpt", 1);
1592 json_object_object_get_ex(json_iface
, ch_grp_str
, &json_grp
);
1594 json_grp
= json_object_new_object();
1595 json_object_object_add(json_grp
, ch_src_str
, json_row
);
1596 json_object_object_add(json_iface
, ch_grp_str
,
1599 json_object_object_add(json_grp
, ch_src_str
, json_row
);
1601 vty_out(vty
, "%-9s %-15s %-15s %-15s %-10s %8s %-6s %5s\n",
1602 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
,
1604 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
, ch
->flags
),
1605 uptime
, expire
, prune
);
1609 static void pim_show_join(struct pim_instance
*pim
, struct vty
*vty
, u_char uj
)
1611 struct pim_interface
*pim_ifp
;
1612 struct pim_ifchannel
*ch
;
1613 struct interface
*ifp
;
1615 json_object
*json
= NULL
;
1617 now
= pim_time_monotonic_sec();
1620 json
= json_object_new_object();
1623 "Interface Address Source Group State Uptime Expire Prune\n");
1625 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1626 pim_ifp
= ifp
->info
;
1630 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
1631 pim_show_join_helper(vty
, pim_ifp
, ch
, json
, now
, uj
);
1632 } /* scan interface channels */
1636 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1637 json
, JSON_C_TO_STRING_PRETTY
));
1638 json_object_free(json
);
1642 static void pim_show_neighbors_single(struct pim_instance
*pim
, struct vty
*vty
,
1643 const char *neighbor
, u_char uj
)
1645 struct listnode
*neighnode
;
1646 struct interface
*ifp
;
1647 struct pim_interface
*pim_ifp
;
1648 struct pim_neighbor
*neigh
;
1650 int found_neighbor
= 0;
1651 int option_address_list
;
1652 int option_dr_priority
;
1653 int option_generation_id
;
1654 int option_holdtime
;
1655 int option_lan_prune_delay
;
1659 char neigh_src_str
[INET_ADDRSTRLEN
];
1661 json_object
*json
= NULL
;
1662 json_object
*json_ifp
= NULL
;
1663 json_object
*json_row
= NULL
;
1665 now
= pim_time_monotonic_sec();
1668 json
= json_object_new_object();
1670 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1671 pim_ifp
= ifp
->info
;
1676 if (pim_ifp
->pim_sock_fd
< 0)
1679 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
1681 pim_inet4_dump("<src?>", neigh
->source_addr
,
1682 neigh_src_str
, sizeof(neigh_src_str
));
1685 * The user can specify either the interface name or the
1687 * If this pim_ifp matches neither then skip.
1689 if (strcmp(neighbor
, "detail")
1690 && strcmp(neighbor
, ifp
->name
)
1691 && strcmp(neighbor
, neigh_src_str
))
1695 pim_time_uptime(uptime
, sizeof(uptime
),
1696 now
- neigh
->creation
);
1697 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
1698 neigh
->t_expire_timer
);
1700 option_address_list
= 0;
1701 option_dr_priority
= 0;
1702 option_generation_id
= 0;
1703 option_holdtime
= 0;
1704 option_lan_prune_delay
= 0;
1707 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1708 PIM_OPTION_MASK_ADDRESS_LIST
))
1709 option_address_list
= 1;
1711 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1712 PIM_OPTION_MASK_DR_PRIORITY
))
1713 option_dr_priority
= 1;
1715 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1716 PIM_OPTION_MASK_GENERATION_ID
))
1717 option_generation_id
= 1;
1719 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1720 PIM_OPTION_MASK_HOLDTIME
))
1721 option_holdtime
= 1;
1723 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1724 PIM_OPTION_MASK_LAN_PRUNE_DELAY
))
1725 option_lan_prune_delay
= 1;
1727 if (PIM_OPTION_IS_SET(
1728 neigh
->hello_options
,
1729 PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION
))
1734 /* Does this ifp live in json? If not create
1736 json_object_object_get_ex(json
, ifp
->name
,
1740 json_ifp
= json_object_new_object();
1741 json_object_pim_ifp_add(json_ifp
, ifp
);
1742 json_object_object_add(json
, ifp
->name
,
1746 json_row
= json_object_new_object();
1747 json_object_string_add(json_row
, "interface",
1749 json_object_string_add(json_row
, "address",
1751 json_object_string_add(json_row
, "upTime",
1753 json_object_string_add(json_row
, "holdtime",
1755 json_object_int_add(json_row
, "drPriority",
1756 neigh
->dr_priority
);
1757 json_object_int_add(json_row
, "generationId",
1758 neigh
->generation_id
);
1760 if (option_address_list
)
1761 json_object_boolean_true_add(
1763 "helloOptionAddressList");
1765 if (option_dr_priority
)
1766 json_object_boolean_true_add(
1768 "helloOptionDrPriority");
1770 if (option_generation_id
)
1771 json_object_boolean_true_add(
1773 "helloOptionGenerationId");
1775 if (option_holdtime
)
1776 json_object_boolean_true_add(
1778 "helloOptionHoldtime");
1780 if (option_lan_prune_delay
)
1781 json_object_boolean_true_add(
1783 "helloOptionLanPruneDelay");
1786 json_object_boolean_true_add(
1787 json_row
, "helloOptionTBit");
1789 json_object_object_add(json_ifp
, neigh_src_str
,
1793 vty_out(vty
, "Interface : %s\n", ifp
->name
);
1794 vty_out(vty
, "Neighbor : %s\n", neigh_src_str
);
1802 " DR Priority : %d\n",
1803 neigh
->dr_priority
);
1805 " Generation ID : %08x\n",
1806 neigh
->generation_id
);
1808 " Override Interval (msec) : %d\n",
1809 neigh
->override_interval_msec
);
1811 " Propagation Delay (msec) : %d\n",
1812 neigh
->propagation_delay_msec
);
1814 " Hello Option - Address List : %s\n",
1815 option_address_list
? "yes" : "no");
1817 " Hello Option - DR Priority : %s\n",
1818 option_dr_priority
? "yes" : "no");
1820 " Hello Option - Generation ID : %s\n",
1821 option_generation_id
? "yes" : "no");
1823 " Hello Option - Holdtime : %s\n",
1824 option_holdtime
? "yes" : "no");
1826 " Hello Option - LAN Prune Delay : %s\n",
1827 option_lan_prune_delay
? "yes" : "no");
1829 " Hello Option - T-bit : %s\n",
1830 option_t_bit
? "yes" : "no");
1831 pim_bfd_show_info(vty
, neigh
->bfd_info
,
1839 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1840 json
, JSON_C_TO_STRING_PRETTY
));
1841 json_object_free(json
);
1844 if (!found_neighbor
)
1846 "%% No such interface or neighbor\n");
1851 static void pim_show_state(struct pim_instance
*pim
, struct vty
*vty
,
1852 const char *src_or_group
, const char *group
,
1855 struct channel_oil
*c_oil
;
1856 struct listnode
*node
;
1857 json_object
*json
= NULL
;
1858 json_object
*json_group
= NULL
;
1859 json_object
*json_ifp_in
= NULL
;
1860 json_object
*json_ifp_out
= NULL
;
1861 json_object
*json_source
= NULL
;
1864 now
= pim_time_monotonic_sec();
1867 json
= json_object_new_object();
1870 "Codes: J -> Pim Join, I -> IGMP Report, S -> Source, * -> Inherited from (*,G)");
1872 "\nInstalled Source Group IIF OIL\n");
1875 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
1876 char grp_str
[INET_ADDRSTRLEN
];
1877 char src_str
[INET_ADDRSTRLEN
];
1878 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
1879 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
1881 struct interface
*ifp_in
;
1884 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
1886 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
1888 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
1891 strcpy(in_ifname
, ifp_in
->name
);
1893 strcpy(in_ifname
, "<iif?>");
1896 if (strcmp(src_or_group
, src_str
)
1897 && strcmp(src_or_group
, grp_str
))
1900 if (group
&& strcmp(group
, grp_str
))
1906 /* Find the group, create it if it doesn't exist */
1907 json_object_object_get_ex(json
, grp_str
, &json_group
);
1910 json_group
= json_object_new_object();
1911 json_object_object_add(json
, grp_str
,
1915 /* Find the source nested under the group, create it if
1916 * it doesn't exist */
1917 json_object_object_get_ex(json_group
, src_str
,
1921 json_source
= json_object_new_object();
1922 json_object_object_add(json_group
, src_str
,
1926 /* Find the inbound interface nested under the source,
1927 * create it if it doesn't exist */
1928 json_object_object_get_ex(json_source
, in_ifname
,
1932 json_ifp_in
= json_object_new_object();
1933 json_object_object_add(json_source
, in_ifname
,
1935 json_object_int_add(json_source
, "Installed",
1937 json_object_int_add(json_source
, "RefCount",
1938 c_oil
->oil_ref_count
);
1939 json_object_int_add(json_source
, "OilListSize",
1941 json_object_int_add(
1942 json_source
, "OilRescan",
1943 c_oil
->oil_inherited_rescan
);
1944 json_object_int_add(json_source
, "LastUsed",
1945 c_oil
->cc
.lastused
);
1946 json_object_int_add(json_source
, "PacketCount",
1948 json_object_int_add(json_source
, "ByteCount",
1950 json_object_int_add(json_source
,
1952 c_oil
->cc
.wrong_if
);
1955 vty_out(vty
, "%-9d %-15s %-15s %-7s ",
1956 c_oil
->installed
, src_str
, grp_str
,
1960 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
1962 struct interface
*ifp_out
;
1963 char oif_uptime
[10];
1966 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
1970 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
1972 oif_uptime
, sizeof(oif_uptime
),
1973 now
- c_oil
->oif_creation
[oif_vif_index
]);
1976 strcpy(out_ifname
, ifp_out
->name
);
1978 strcpy(out_ifname
, "<oif?>");
1981 json_ifp_out
= json_object_new_object();
1982 json_object_string_add(json_ifp_out
, "source",
1984 json_object_string_add(json_ifp_out
, "group",
1986 json_object_string_add(json_ifp_out
,
1989 json_object_string_add(json_ifp_out
,
1990 "outboundInterface",
1992 json_object_int_add(json_ifp_out
, "installed",
1995 json_object_object_add(json_ifp_in
, out_ifname
,
2000 vty_out(vty
, "%s(%c%c%c%c)", out_ifname
,
2001 (c_oil
->oif_flags
[oif_vif_index
]
2002 & PIM_OIF_FLAG_PROTO_IGMP
)
2005 (c_oil
->oif_flags
[oif_vif_index
]
2006 & PIM_OIF_FLAG_PROTO_PIM
)
2009 (c_oil
->oif_flags
[oif_vif_index
]
2010 & PIM_OIF_FLAG_PROTO_SOURCE
)
2013 (c_oil
->oif_flags
[oif_vif_index
]
2014 & PIM_OIF_FLAG_PROTO_STAR
)
2018 vty_out(vty
, ", %s(%c%c%c%c)",
2020 (c_oil
->oif_flags
[oif_vif_index
]
2021 & PIM_OIF_FLAG_PROTO_IGMP
)
2024 (c_oil
->oif_flags
[oif_vif_index
]
2025 & PIM_OIF_FLAG_PROTO_PIM
)
2028 (c_oil
->oif_flags
[oif_vif_index
]
2029 & PIM_OIF_FLAG_PROTO_SOURCE
)
2032 (c_oil
->oif_flags
[oif_vif_index
]
2033 & PIM_OIF_FLAG_PROTO_STAR
)
2045 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2046 json
, JSON_C_TO_STRING_PRETTY
));
2047 json_object_free(json
);
2053 static void pim_show_neighbors(struct pim_instance
*pim
, struct vty
*vty
,
2056 struct listnode
*neighnode
;
2057 struct interface
*ifp
;
2058 struct pim_interface
*pim_ifp
;
2059 struct pim_neighbor
*neigh
;
2063 char neigh_src_str
[INET_ADDRSTRLEN
];
2064 json_object
*json
= NULL
;
2065 json_object
*json_ifp_rows
= NULL
;
2066 json_object
*json_row
= NULL
;
2068 now
= pim_time_monotonic_sec();
2071 json
= json_object_new_object();
2074 "Interface Neighbor Uptime Holdtime DR Pri\n");
2077 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2078 pim_ifp
= ifp
->info
;
2083 if (pim_ifp
->pim_sock_fd
< 0)
2087 json_ifp_rows
= json_object_new_object();
2089 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
2091 pim_inet4_dump("<src?>", neigh
->source_addr
,
2092 neigh_src_str
, sizeof(neigh_src_str
));
2093 pim_time_uptime(uptime
, sizeof(uptime
),
2094 now
- neigh
->creation
);
2095 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
2096 neigh
->t_expire_timer
);
2099 json_row
= json_object_new_object();
2100 json_object_string_add(json_row
, "interface",
2102 json_object_string_add(json_row
, "neighbor",
2104 json_object_string_add(json_row
, "upTime",
2106 json_object_string_add(json_row
, "holdTime",
2108 json_object_int_add(json_row
, "holdTimeMax",
2110 json_object_int_add(json_row
, "drPriority",
2111 neigh
->dr_priority
);
2112 json_object_object_add(json_ifp_rows
,
2113 neigh_src_str
, json_row
);
2116 vty_out(vty
, "%-9s %15s %8s %8s %6d\n",
2117 ifp
->name
, neigh_src_str
, uptime
,
2118 expire
, neigh
->dr_priority
);
2123 json_object_object_add(json
, ifp
->name
, json_ifp_rows
);
2124 json_ifp_rows
= NULL
;
2129 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2130 json
, JSON_C_TO_STRING_PRETTY
));
2131 json_object_free(json
);
2135 static void pim_show_neighbors_secondary(struct pim_instance
*pim
,
2138 struct interface
*ifp
;
2141 "Interface Address Neighbor Secondary \n");
2143 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2144 struct pim_interface
*pim_ifp
;
2145 struct in_addr ifaddr
;
2146 struct listnode
*neighnode
;
2147 struct pim_neighbor
*neigh
;
2149 pim_ifp
= ifp
->info
;
2154 if (pim_ifp
->pim_sock_fd
< 0)
2157 ifaddr
= pim_ifp
->primary_address
;
2159 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
2161 char neigh_src_str
[INET_ADDRSTRLEN
];
2162 struct listnode
*prefix_node
;
2165 if (!neigh
->prefix_list
)
2168 pim_inet4_dump("<src?>", neigh
->source_addr
,
2169 neigh_src_str
, sizeof(neigh_src_str
));
2171 for (ALL_LIST_ELEMENTS_RO(neigh
->prefix_list
,
2173 char neigh_sec_str
[PREFIX2STR_BUFFER
];
2175 prefix2str(p
, neigh_sec_str
,
2176 sizeof(neigh_sec_str
));
2178 vty_out(vty
, "%-9s %-15s %-15s %-15s\n",
2179 ifp
->name
, inet_ntoa(ifaddr
),
2180 neigh_src_str
, neigh_sec_str
);
2186 static void json_object_pim_upstream_add(json_object
*json
,
2187 struct pim_upstream
*up
)
2189 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED
)
2190 json_object_boolean_true_add(json
, "drJoinDesired");
2192 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED
)
2193 json_object_boolean_true_add(json
, "drJoinDesiredUpdated");
2195 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
2196 json_object_boolean_true_add(json
, "firstHopRouter");
2198 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_IGMP
)
2199 json_object_boolean_true_add(json
, "sourceIgmp");
2201 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_PIM
)
2202 json_object_boolean_true_add(json
, "sourcePim");
2204 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_STREAM
)
2205 json_object_boolean_true_add(json
, "sourceStream");
2207 /* XXX: need to print ths flag in the plain text display as well */
2208 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_MSDP
)
2209 json_object_boolean_true_add(json
, "sourceMsdp");
2213 pim_upstream_state2brief_str(enum pim_upstream_state join_state
,
2216 switch (join_state
) {
2217 case PIM_UPSTREAM_NOTJOINED
:
2218 strcpy(state_str
, "NotJ");
2220 case PIM_UPSTREAM_JOINED
:
2221 strcpy(state_str
, "J");
2224 strcpy(state_str
, "Unk");
2229 static const char *pim_reg_state2brief_str(enum pim_reg_state reg_state
,
2232 switch (reg_state
) {
2233 case PIM_REG_NOINFO
:
2234 strcpy(state_str
, "RegNI");
2237 strcpy(state_str
, "RegJ");
2239 case PIM_REG_JOIN_PENDING
:
2241 strcpy(state_str
, "RegP");
2244 strcpy(state_str
, "Unk");
2249 static void pim_show_upstream(struct pim_instance
*pim
, struct vty
*vty
,
2252 struct listnode
*upnode
;
2253 struct pim_upstream
*up
;
2255 json_object
*json
= NULL
;
2256 json_object
*json_group
= NULL
;
2257 json_object
*json_row
= NULL
;
2259 now
= pim_time_monotonic_sec();
2262 json
= json_object_new_object();
2265 "Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt\n");
2267 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
, up
)) {
2268 char src_str
[INET_ADDRSTRLEN
];
2269 char grp_str
[INET_ADDRSTRLEN
];
2271 char join_timer
[10];
2274 char msdp_reg_timer
[10];
2275 char state_str
[PIM_REG_STATE_STR_LEN
];
2277 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2278 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2279 pim_time_uptime(uptime
, sizeof(uptime
),
2280 now
- up
->state_transition
);
2281 pim_time_timer_to_hhmmss(join_timer
, sizeof(join_timer
),
2285 * If we have a J/P timer for the neighbor display that
2287 if (!up
->t_join_timer
) {
2288 struct pim_neighbor
*nbr
;
2290 nbr
= pim_neighbor_find(
2291 up
->rpf
.source_nexthop
.interface
,
2292 up
->rpf
.rpf_addr
.u
.prefix4
);
2294 pim_time_timer_to_hhmmss(join_timer
,
2299 pim_time_timer_to_hhmmss(rs_timer
, sizeof(rs_timer
),
2301 pim_time_timer_to_hhmmss(ka_timer
, sizeof(ka_timer
),
2303 pim_time_timer_to_hhmmss(msdp_reg_timer
, sizeof(msdp_reg_timer
),
2304 up
->t_msdp_reg_timer
);
2306 pim_upstream_state2brief_str(up
->join_state
, state_str
);
2307 if (up
->reg_state
!= PIM_REG_NOINFO
) {
2308 char tmp_str
[PIM_REG_STATE_STR_LEN
];
2310 sprintf(state_str
+ strlen(state_str
), ",%s",
2311 pim_reg_state2brief_str(up
->reg_state
,
2316 json_object_object_get_ex(json
, grp_str
, &json_group
);
2319 json_group
= json_object_new_object();
2320 json_object_object_add(json
, grp_str
,
2324 json_row
= json_object_new_object();
2325 json_object_pim_upstream_add(json_row
, up
);
2326 json_object_string_add(
2327 json_row
, "inboundInterface",
2328 up
->rpf
.source_nexthop
.interface
->name
);
2331 * The RPF address we use is slightly different
2332 * based upon what we are looking up.
2333 * If we have a S, list that unless
2334 * we are the FHR, else we just put
2335 * the RP as the rpfAddress
2337 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
2338 || up
->sg
.src
.s_addr
== INADDR_ANY
) {
2339 char rpf
[PREFIX_STRLEN
];
2340 struct pim_rpf
*rpg
;
2342 rpg
= RP(pim
, up
->sg
.grp
);
2343 pim_inet4_dump("<rpf?>",
2344 rpg
->rpf_addr
.u
.prefix4
, rpf
,
2346 json_object_string_add(json_row
, "rpfAddress",
2349 json_object_string_add(json_row
, "rpfAddress",
2353 json_object_string_add(json_row
, "source", src_str
);
2354 json_object_string_add(json_row
, "group", grp_str
);
2355 json_object_string_add(json_row
, "state", state_str
);
2356 json_object_string_add(
2357 json_row
, "joinState",
2358 pim_upstream_state2str(up
->join_state
));
2359 json_object_string_add(
2360 json_row
, "regState",
2361 pim_reg_state2str(up
->reg_state
, state_str
));
2362 json_object_string_add(json_row
, "upTime", uptime
);
2363 json_object_string_add(json_row
, "joinTimer",
2365 json_object_string_add(json_row
, "resetTimer",
2367 json_object_string_add(json_row
, "keepaliveTimer",
2369 json_object_string_add(json_row
, "msdpRegTimer",
2371 json_object_int_add(json_row
, "refCount",
2373 json_object_int_add(json_row
, "sptBit", up
->sptbit
);
2374 json_object_object_add(json_group
, src_str
, json_row
);
2377 "%-10s%-15s %-15s %-11s %-8s %-9s %-9s %-9s %6d\n",
2378 up
->rpf
.source_nexthop
.interface
->name
, src_str
,
2379 grp_str
, state_str
, uptime
, join_timer
,
2380 rs_timer
, ka_timer
, up
->ref_count
);
2385 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2386 json
, JSON_C_TO_STRING_PRETTY
));
2387 json_object_free(json
);
2391 static void pim_show_join_desired_helper(struct pim_instance
*pim
,
2393 struct pim_interface
*pim_ifp
,
2394 struct pim_ifchannel
*ch
,
2395 json_object
*json
, u_char uj
)
2397 struct pim_upstream
*up
= ch
->upstream
;
2398 json_object
*json_group
= NULL
;
2399 char src_str
[INET_ADDRSTRLEN
];
2400 char grp_str
[INET_ADDRSTRLEN
];
2401 json_object
*json_row
= NULL
;
2403 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2404 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2407 json_object_object_get_ex(json
, grp_str
, &json_group
);
2410 json_group
= json_object_new_object();
2411 json_object_object_add(json
, grp_str
, json_group
);
2414 json_row
= json_object_new_object();
2415 json_object_pim_upstream_add(json_row
, up
);
2416 json_object_string_add(json_row
, "interface",
2417 ch
->interface
->name
);
2418 json_object_string_add(json_row
, "source", src_str
);
2419 json_object_string_add(json_row
, "group", grp_str
);
2421 if (pim_macro_ch_lost_assert(ch
))
2422 json_object_boolean_true_add(json_row
, "lostAssert");
2424 if (pim_macro_chisin_joins(ch
))
2425 json_object_boolean_true_add(json_row
, "joins");
2427 if (pim_macro_chisin_pim_include(ch
))
2428 json_object_boolean_true_add(json_row
, "pimInclude");
2430 if (pim_upstream_evaluate_join_desired(pim
, up
))
2431 json_object_boolean_true_add(json_row
,
2432 "evaluateJoinDesired");
2434 json_object_object_add(json_group
, src_str
, json_row
);
2437 vty_out(vty
, "%-9s %-15s %-15s %-10s %-5s %-10s %-11s %-6s\n",
2438 ch
->interface
->name
, src_str
, grp_str
,
2439 pim_macro_ch_lost_assert(ch
) ? "yes" : "no",
2440 pim_macro_chisin_joins(ch
) ? "yes" : "no",
2441 pim_macro_chisin_pim_include(ch
) ? "yes" : "no",
2442 PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(up
->flags
)
2445 pim_upstream_evaluate_join_desired(pim
, up
) ? "yes"
2450 static void pim_show_join_desired(struct pim_instance
*pim
, struct vty
*vty
,
2453 struct pim_interface
*pim_ifp
;
2454 struct pim_ifchannel
*ch
;
2455 struct interface
*ifp
;
2457 json_object
*json
= NULL
;
2460 json
= json_object_new_object();
2463 "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD\n");
2465 /* scan per-interface (S,G) state */
2466 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2467 pim_ifp
= ifp
->info
;
2472 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
2473 /* scan all interfaces */
2474 pim_show_join_desired_helper(pim
, vty
, pim_ifp
, ch
,
2480 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2481 json
, JSON_C_TO_STRING_PRETTY
));
2482 json_object_free(json
);
2486 static void pim_show_upstream_rpf(struct pim_instance
*pim
, struct vty
*vty
,
2489 struct listnode
*upnode
;
2490 struct pim_upstream
*up
;
2491 json_object
*json
= NULL
;
2492 json_object
*json_group
= NULL
;
2493 json_object
*json_row
= NULL
;
2496 json
= json_object_new_object();
2499 "Source Group RpfIface RibNextHop RpfAddress \n");
2501 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
, up
)) {
2502 char src_str
[INET_ADDRSTRLEN
];
2503 char grp_str
[INET_ADDRSTRLEN
];
2504 char rpf_nexthop_str
[PREFIX_STRLEN
];
2505 char rpf_addr_str
[PREFIX_STRLEN
];
2506 struct pim_rpf
*rpf
;
2507 const char *rpf_ifname
;
2511 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2512 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2513 pim_addr_dump("<nexthop?>",
2514 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2515 rpf_nexthop_str
, sizeof(rpf_nexthop_str
));
2516 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2517 sizeof(rpf_addr_str
));
2519 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2522 json_object_object_get_ex(json
, grp_str
, &json_group
);
2525 json_group
= json_object_new_object();
2526 json_object_object_add(json
, grp_str
,
2530 json_row
= json_object_new_object();
2531 json_object_pim_upstream_add(json_row
, up
);
2532 json_object_string_add(json_row
, "source", src_str
);
2533 json_object_string_add(json_row
, "group", grp_str
);
2534 json_object_string_add(json_row
, "rpfInterface",
2536 json_object_string_add(json_row
, "ribNexthop",
2538 json_object_string_add(json_row
, "rpfAddress",
2540 json_object_object_add(json_group
, src_str
, json_row
);
2542 vty_out(vty
, "%-15s %-15s %-8s %-15s %-15s\n", src_str
,
2543 grp_str
, rpf_ifname
, rpf_nexthop_str
,
2549 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2550 json
, JSON_C_TO_STRING_PRETTY
));
2551 json_object_free(json
);
2555 static void show_rpf_refresh_stats(struct vty
*vty
, time_t now
,
2558 char refresh_uptime
[10];
2560 pim_time_uptime_begin(refresh_uptime
, sizeof(refresh_uptime
), now
,
2561 qpim_rpf_cache_refresh_last
);
2564 json_object_int_add(json
, "rpfCacheRefreshDelayMsecs",
2565 qpim_rpf_cache_refresh_delay_msec
);
2566 json_object_int_add(
2567 json
, "rpfCacheRefreshTimer",
2568 pim_time_timer_remain_msec(qpim_rpf_cache_refresher
));
2569 json_object_int_add(json
, "rpfCacheRefreshRequests",
2570 qpim_rpf_cache_refresh_requests
);
2571 json_object_int_add(json
, "rpfCacheRefreshEvents",
2572 qpim_rpf_cache_refresh_events
);
2573 json_object_string_add(json
, "rpfCacheRefreshLast",
2575 json_object_int_add(json
, "nexthopLookups",
2576 qpim_nexthop_lookups
);
2577 json_object_int_add(json
, "nexthopLookupsAvoided",
2578 nexthop_lookups_avoided
);
2581 "RPF Cache Refresh Delay: %ld msecs\n"
2582 "RPF Cache Refresh Timer: %ld msecs\n"
2583 "RPF Cache Refresh Requests: %lld\n"
2584 "RPF Cache Refresh Events: %lld\n"
2585 "RPF Cache Refresh Last: %s\n"
2586 "Nexthop Lookups: %lld\n"
2587 "Nexthop Lookups Avoided: %lld\n",
2588 qpim_rpf_cache_refresh_delay_msec
,
2589 pim_time_timer_remain_msec(qpim_rpf_cache_refresher
),
2590 (long long)qpim_rpf_cache_refresh_requests
,
2591 (long long)qpim_rpf_cache_refresh_events
,
2592 refresh_uptime
, (long long)qpim_nexthop_lookups
,
2593 (long long)nexthop_lookups_avoided
);
2597 static void show_scan_oil_stats(struct pim_instance
*pim
, struct vty
*vty
,
2600 char uptime_scan_oil
[10];
2601 char uptime_mroute_add
[10];
2602 char uptime_mroute_del
[10];
2604 pim_time_uptime_begin(uptime_scan_oil
, sizeof(uptime_scan_oil
), now
,
2605 qpim_scan_oil_last
);
2606 pim_time_uptime_begin(uptime_mroute_add
, sizeof(uptime_mroute_add
), now
,
2607 pim
->mroute_add_last
);
2608 pim_time_uptime_begin(uptime_mroute_del
, sizeof(uptime_mroute_del
), now
,
2609 pim
->mroute_del_last
);
2612 "Scan OIL - Last: %s Events: %lld\n"
2613 "MFC Add - Last: %s Events: %lld\n"
2614 "MFC Del - Last: %s Events: %lld\n",
2615 uptime_scan_oil
, (long long)qpim_scan_oil_events
,
2616 uptime_mroute_add
, (long long)pim
->mroute_add_events
,
2617 uptime_mroute_del
, (long long)pim
->mroute_del_events
);
2620 static void pim_show_rpf(struct pim_instance
*pim
, struct vty
*vty
, u_char uj
)
2622 struct listnode
*up_node
;
2623 struct pim_upstream
*up
;
2624 time_t now
= pim_time_monotonic_sec();
2625 json_object
*json
= NULL
;
2626 json_object
*json_group
= NULL
;
2627 json_object
*json_row
= NULL
;
2630 json
= json_object_new_object();
2631 show_rpf_refresh_stats(vty
, now
, json
);
2633 show_rpf_refresh_stats(vty
, now
, json
);
2636 "Source Group RpfIface RpfAddress RibNextHop Metric Pref\n");
2639 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, up_node
, up
)) {
2640 char src_str
[INET_ADDRSTRLEN
];
2641 char grp_str
[INET_ADDRSTRLEN
];
2642 char rpf_addr_str
[PREFIX_STRLEN
];
2643 char rib_nexthop_str
[PREFIX_STRLEN
];
2644 const char *rpf_ifname
;
2645 struct pim_rpf
*rpf
= &up
->rpf
;
2647 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2648 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2649 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2650 sizeof(rpf_addr_str
));
2651 pim_addr_dump("<nexthop?>",
2652 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2653 rib_nexthop_str
, sizeof(rib_nexthop_str
));
2655 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2658 json_object_object_get_ex(json
, grp_str
, &json_group
);
2661 json_group
= json_object_new_object();
2662 json_object_object_add(json
, grp_str
,
2666 json_row
= json_object_new_object();
2667 json_object_string_add(json_row
, "source", src_str
);
2668 json_object_string_add(json_row
, "group", grp_str
);
2669 json_object_string_add(json_row
, "rpfInterface",
2671 json_object_string_add(json_row
, "rpfAddress",
2673 json_object_string_add(json_row
, "ribNexthop",
2675 json_object_int_add(
2676 json_row
, "routeMetric",
2677 rpf
->source_nexthop
.mrib_route_metric
);
2678 json_object_int_add(
2679 json_row
, "routePreference",
2680 rpf
->source_nexthop
.mrib_metric_preference
);
2681 json_object_object_add(json_group
, src_str
, json_row
);
2684 vty_out(vty
, "%-15s %-15s %-8s %-15s %-15s %6d %4d\n",
2685 src_str
, grp_str
, rpf_ifname
, rpf_addr_str
,
2687 rpf
->source_nexthop
.mrib_route_metric
,
2688 rpf
->source_nexthop
.mrib_metric_preference
);
2693 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2694 json
, JSON_C_TO_STRING_PRETTY
));
2695 json_object_free(json
);
2699 struct pnc_cache_walk_data
{
2701 struct pim_instance
*pim
;
2704 static int pim_print_pnc_cache_walkcb(struct hash_backet
*backet
, void *arg
)
2706 struct pim_nexthop_cache
*pnc
= backet
->data
;
2707 struct pnc_cache_walk_data
*cwd
= arg
;
2708 struct vty
*vty
= cwd
->vty
;
2709 struct pim_instance
*pim
= cwd
->pim
;
2710 struct nexthop
*nh_node
= NULL
;
2711 ifindex_t first_ifindex
;
2712 struct interface
*ifp
= NULL
;
2717 for (nh_node
= pnc
->nexthop
; nh_node
; nh_node
= nh_node
->next
) {
2718 first_ifindex
= nh_node
->ifindex
;
2719 ifp
= if_lookup_by_index(first_ifindex
, pim
->vrf_id
);
2721 vty_out(vty
, "%-15s ", inet_ntoa(pnc
->rpf
.rpf_addr
.u
.prefix4
));
2722 vty_out(vty
, "%-14s ", ifp
? ifp
->name
: "NULL");
2723 vty_out(vty
, "%s ", inet_ntoa(nh_node
->gate
.ipv4
));
2729 static void pim_show_nexthop(struct pim_instance
*pim
, struct vty
*vty
)
2731 struct pnc_cache_walk_data cwd
;
2735 vty_out(vty
, "Number of registered addresses: %lu\n",
2736 pim
->rpf_hash
->count
);
2737 vty_out(vty
, "Address Interface Nexthop\n");
2738 vty_out(vty
, "-------------------------------------------\n");
2740 hash_walk(pim
->rpf_hash
, pim_print_pnc_cache_walkcb
, &cwd
);
2743 static void igmp_show_groups(struct pim_instance
*pim
, struct vty
*vty
,
2746 struct interface
*ifp
;
2748 json_object
*json
= NULL
;
2749 json_object
*json_iface
= NULL
;
2750 json_object
*json_row
= NULL
;
2752 now
= pim_time_monotonic_sec();
2755 json
= json_object_new_object();
2758 "Interface Address Group Mode Timer Srcs V Uptime \n");
2760 /* scan interfaces */
2761 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2762 struct pim_interface
*pim_ifp
= ifp
->info
;
2763 struct listnode
*sock_node
;
2764 struct igmp_sock
*igmp
;
2769 /* scan igmp sockets */
2770 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
2772 char ifaddr_str
[INET_ADDRSTRLEN
];
2773 struct listnode
*grpnode
;
2774 struct igmp_group
*grp
;
2776 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
2777 sizeof(ifaddr_str
));
2779 /* scan igmp groups */
2780 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
2782 char group_str
[INET_ADDRSTRLEN
];
2786 pim_inet4_dump("<group?>", grp
->group_addr
,
2787 group_str
, sizeof(group_str
));
2788 pim_time_timer_to_hhmmss(hhmmss
, sizeof(hhmmss
),
2789 grp
->t_group_timer
);
2790 pim_time_uptime(uptime
, sizeof(uptime
),
2791 now
- grp
->group_creation
);
2794 json_object_object_get_ex(
2795 json
, ifp
->name
, &json_iface
);
2799 json_object_new_object();
2800 json_object_pim_ifp_add(
2802 json_object_object_add(
2807 json_row
= json_object_new_object();
2808 json_object_string_add(
2809 json_row
, "source", ifaddr_str
);
2810 json_object_string_add(
2811 json_row
, "group", group_str
);
2813 if (grp
->igmp_version
== 3)
2814 json_object_string_add(
2816 grp
->group_filtermode_isexcl
2820 json_object_string_add(json_row
,
2822 json_object_int_add(
2823 json_row
, "sourcesCount",
2824 grp
->group_source_list
2826 grp
->group_source_list
)
2828 json_object_int_add(json_row
, "version",
2830 json_object_string_add(
2831 json_row
, "uptime", uptime
);
2832 json_object_object_add(json_iface
,
2838 "%-9s %-15s %-15s %4s %8s %4d %d %8s\n",
2839 ifp
->name
, ifaddr_str
,
2841 grp
->igmp_version
== 3
2842 ? (grp
->group_filtermode_isexcl
2847 grp
->group_source_list
2849 grp
->group_source_list
)
2851 grp
->igmp_version
, uptime
);
2853 } /* scan igmp groups */
2854 } /* scan igmp sockets */
2855 } /* scan interfaces */
2858 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2859 json
, JSON_C_TO_STRING_PRETTY
));
2860 json_object_free(json
);
2864 static void igmp_show_group_retransmission(struct pim_instance
*pim
,
2867 struct interface
*ifp
;
2870 "Interface Address Group RetTimer Counter RetSrcs\n");
2872 /* scan interfaces */
2873 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2874 struct pim_interface
*pim_ifp
= ifp
->info
;
2875 struct listnode
*sock_node
;
2876 struct igmp_sock
*igmp
;
2881 /* scan igmp sockets */
2882 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
2884 char ifaddr_str
[INET_ADDRSTRLEN
];
2885 struct listnode
*grpnode
;
2886 struct igmp_group
*grp
;
2888 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
2889 sizeof(ifaddr_str
));
2891 /* scan igmp groups */
2892 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
2894 char group_str
[INET_ADDRSTRLEN
];
2895 char grp_retr_mmss
[10];
2896 struct listnode
*src_node
;
2897 struct igmp_source
*src
;
2898 int grp_retr_sources
= 0;
2900 pim_inet4_dump("<group?>", grp
->group_addr
,
2901 group_str
, sizeof(group_str
));
2902 pim_time_timer_to_mmss(
2903 grp_retr_mmss
, sizeof(grp_retr_mmss
),
2904 grp
->t_group_query_retransmit_timer
);
2907 /* count group sources with retransmission state
2909 for (ALL_LIST_ELEMENTS_RO(
2910 grp
->group_source_list
, src_node
,
2912 if (src
->source_query_retransmit_count
2918 vty_out(vty
, "%-9s %-15s %-15s %-8s %7d %7d\n",
2919 ifp
->name
, ifaddr_str
, group_str
,
2921 grp
->group_specific_query_retransmit_count
,
2924 } /* scan igmp groups */
2925 } /* scan igmp sockets */
2926 } /* scan interfaces */
2929 static void igmp_show_sources(struct pim_instance
*pim
, struct vty
*vty
)
2931 struct interface
*ifp
;
2934 now
= pim_time_monotonic_sec();
2937 "Interface Address Group Source Timer Fwd Uptime \n");
2939 /* scan interfaces */
2940 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2941 struct pim_interface
*pim_ifp
= ifp
->info
;
2942 struct listnode
*sock_node
;
2943 struct igmp_sock
*igmp
;
2948 /* scan igmp sockets */
2949 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
2951 char ifaddr_str
[INET_ADDRSTRLEN
];
2952 struct listnode
*grpnode
;
2953 struct igmp_group
*grp
;
2955 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
2956 sizeof(ifaddr_str
));
2958 /* scan igmp groups */
2959 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
2961 char group_str
[INET_ADDRSTRLEN
];
2962 struct listnode
*srcnode
;
2963 struct igmp_source
*src
;
2965 pim_inet4_dump("<group?>", grp
->group_addr
,
2966 group_str
, sizeof(group_str
));
2968 /* scan group sources */
2969 for (ALL_LIST_ELEMENTS_RO(
2970 grp
->group_source_list
, srcnode
,
2972 char source_str
[INET_ADDRSTRLEN
];
2977 "<source?>", src
->source_addr
,
2978 source_str
, sizeof(source_str
));
2980 pim_time_timer_to_mmss(
2982 src
->t_source_timer
);
2985 uptime
, sizeof(uptime
),
2986 now
- src
->source_creation
);
2989 "%-9s %-15s %-15s %-15s %5s %3s %8s\n",
2990 ifp
->name
, ifaddr_str
,
2991 group_str
, source_str
, mmss
,
2992 IGMP_SOURCE_TEST_FORWARDING(
2998 } /* scan group sources */
2999 } /* scan igmp groups */
3000 } /* scan igmp sockets */
3001 } /* scan interfaces */
3004 static void igmp_show_source_retransmission(struct pim_instance
*pim
,
3007 struct interface
*ifp
;
3010 "Interface Address Group Source Counter\n");
3012 /* scan interfaces */
3013 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3014 struct pim_interface
*pim_ifp
= ifp
->info
;
3015 struct listnode
*sock_node
;
3016 struct igmp_sock
*igmp
;
3021 /* scan igmp sockets */
3022 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3024 char ifaddr_str
[INET_ADDRSTRLEN
];
3025 struct listnode
*grpnode
;
3026 struct igmp_group
*grp
;
3028 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3029 sizeof(ifaddr_str
));
3031 /* scan igmp groups */
3032 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3034 char group_str
[INET_ADDRSTRLEN
];
3035 struct listnode
*srcnode
;
3036 struct igmp_source
*src
;
3038 pim_inet4_dump("<group?>", grp
->group_addr
,
3039 group_str
, sizeof(group_str
));
3041 /* scan group sources */
3042 for (ALL_LIST_ELEMENTS_RO(
3043 grp
->group_source_list
, srcnode
,
3045 char source_str
[INET_ADDRSTRLEN
];
3048 "<source?>", src
->source_addr
,
3049 source_str
, sizeof(source_str
));
3052 "%-9s %-15s %-15s %-15s %7d\n",
3053 ifp
->name
, ifaddr_str
,
3054 group_str
, source_str
,
3055 src
->source_query_retransmit_count
);
3057 } /* scan group sources */
3058 } /* scan igmp groups */
3059 } /* scan igmp sockets */
3060 } /* scan interfaces */
3063 static void clear_igmp_interfaces(struct pim_instance
*pim
)
3065 struct interface
*ifp
;
3067 FOR_ALL_INTERFACES (pim
->vrf
, ifp
)
3068 pim_if_addr_del_all_igmp(ifp
);
3070 FOR_ALL_INTERFACES (pim
->vrf
, ifp
)
3071 pim_if_addr_add_all(ifp
);
3074 static void clear_pim_interfaces(struct pim_instance
*pim
)
3076 struct interface
*ifp
;
3078 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3080 pim_neighbor_delete_all(ifp
, "interface cleared");
3085 static void clear_interfaces(struct pim_instance
*pim
)
3087 clear_igmp_interfaces(pim
);
3088 clear_pim_interfaces(pim
);
3091 #define PIM_GET_PIM_INTERFACE(pim_ifp, ifp) \
3092 pim_ifp = ifp->info; \
3095 "%% Enable PIM and/or IGMP on this interface first\n"); \
3096 return CMD_WARNING_CONFIG_FAILED; \
3099 DEFUN (clear_ip_interfaces
,
3100 clear_ip_interfaces_cmd
,
3101 "clear ip interfaces [vrf NAME]",
3104 "Reset interfaces\n"
3108 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3113 clear_interfaces(vrf
->info
);
3118 DEFUN (clear_ip_igmp_interfaces
,
3119 clear_ip_igmp_interfaces_cmd
,
3120 "clear ip igmp [vrf NAME] interfaces",
3125 "Reset IGMP interfaces\n")
3128 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3133 clear_igmp_interfaces(vrf
->info
);
3138 static void mroute_add_all(struct pim_instance
*pim
)
3140 struct listnode
*node
;
3141 struct channel_oil
*c_oil
;
3143 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
3144 if (pim_mroute_add(c_oil
, __PRETTY_FUNCTION__
)) {
3145 /* just log warning */
3146 char source_str
[INET_ADDRSTRLEN
];
3147 char group_str
[INET_ADDRSTRLEN
];
3148 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
,
3149 source_str
, sizeof(source_str
));
3150 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
,
3151 group_str
, sizeof(group_str
));
3152 zlog_warn("%s %s: (S,G)=(%s,%s) failure writing MFC",
3153 __FILE__
, __PRETTY_FUNCTION__
, source_str
,
3159 static void mroute_del_all(struct pim_instance
*pim
)
3161 struct listnode
*node
;
3162 struct channel_oil
*c_oil
;
3164 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
3165 if (pim_mroute_del(c_oil
, __PRETTY_FUNCTION__
)) {
3166 /* just log warning */
3167 char source_str
[INET_ADDRSTRLEN
];
3168 char group_str
[INET_ADDRSTRLEN
];
3169 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
,
3170 source_str
, sizeof(source_str
));
3171 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
,
3172 group_str
, sizeof(group_str
));
3173 zlog_warn("%s %s: (S,G)=(%s,%s) failure clearing MFC",
3174 __FILE__
, __PRETTY_FUNCTION__
, source_str
,
3180 DEFUN (clear_ip_mroute
,
3181 clear_ip_mroute_cmd
,
3182 "clear ip mroute [vrf NAME]",
3185 "Reset multicast routes\n"
3189 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3194 mroute_del_all(vrf
->info
);
3195 mroute_add_all(vrf
->info
);
3200 DEFUN (clear_ip_pim_interfaces
,
3201 clear_ip_pim_interfaces_cmd
,
3202 "clear ip pim [vrf NAME] interfaces",
3207 "Reset PIM interfaces\n")
3210 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3215 clear_pim_interfaces(vrf
->info
);
3220 DEFUN (clear_ip_pim_interface_traffic
,
3221 clear_ip_pim_interface_traffic_cmd
,
3222 "clear ip pim [vrf NAME] interface traffic",
3225 "PIM clear commands\n"
3227 "Reset PIM interfaces\n"
3228 "Reset Protocol Packet counters\n")
3231 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3232 struct interface
*ifp
= NULL
;
3233 struct pim_interface
*pim_ifp
= NULL
;
3238 FOR_ALL_INTERFACES (vrf
, ifp
) {
3239 pim_ifp
= ifp
->info
;
3244 pim_ifp
->pim_ifstat_hello_recv
= 0;
3245 pim_ifp
->pim_ifstat_hello_sent
= 0;
3246 pim_ifp
->pim_ifstat_join_recv
= 0;
3247 pim_ifp
->pim_ifstat_join_send
= 0;
3248 pim_ifp
->pim_ifstat_prune_recv
= 0;
3249 pim_ifp
->pim_ifstat_prune_send
= 0;
3250 pim_ifp
->pim_ifstat_reg_recv
= 0;
3251 pim_ifp
->pim_ifstat_reg_send
= 0;
3252 pim_ifp
->pim_ifstat_reg_stop_recv
= 0;
3253 pim_ifp
->pim_ifstat_reg_stop_send
= 0;
3254 pim_ifp
->pim_ifstat_assert_recv
= 0;
3255 pim_ifp
->pim_ifstat_assert_send
= 0;
3261 DEFUN (clear_ip_pim_oil
,
3262 clear_ip_pim_oil_cmd
,
3263 "clear ip pim [vrf NAME] oil",
3268 "Rescan PIM OIL (output interface list)\n")
3271 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3276 pim_scan_oil(vrf
->info
);
3281 DEFUN (show_ip_igmp_interface
,
3282 show_ip_igmp_interface_cmd
,
3283 "show ip igmp [vrf NAME] interface [detail|WORD] [json]",
3288 "IGMP interface information\n"
3294 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3295 u_char uj
= use_json(argc
, argv
);
3300 if (argv_find(argv
, argc
, "detail", &idx
)
3301 || argv_find(argv
, argc
, "WORD", &idx
))
3302 igmp_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
3304 igmp_show_interfaces(vrf
->info
, vty
, uj
);
3309 DEFUN (show_ip_igmp_interface_vrf_all
,
3310 show_ip_igmp_interface_vrf_all_cmd
,
3311 "show ip igmp vrf all interface [detail|WORD] [json]",
3316 "IGMP interface information\n"
3322 u_char uj
= use_json(argc
, argv
);
3328 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3332 vty_out(vty
, " \"%s\": ", vrf
->name
);
3335 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3336 if (argv_find(argv
, argc
, "detail", &idx
)
3337 || argv_find(argv
, argc
, "WORD", &idx
))
3338 igmp_show_interfaces_single(vrf
->info
, vty
,
3339 argv
[idx
]->arg
, uj
);
3341 igmp_show_interfaces(vrf
->info
, vty
, uj
);
3344 vty_out(vty
, "}\n");
3349 DEFUN (show_ip_igmp_join
,
3350 show_ip_igmp_join_cmd
,
3351 "show ip igmp [vrf NAME] join",
3356 "IGMP static join information\n")
3359 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3364 igmp_show_interface_join(vrf
->info
, vty
);
3369 DEFUN (show_ip_igmp_join_vrf_all
,
3370 show_ip_igmp_join_vrf_all_cmd
,
3371 "show ip igmp vrf all join",
3376 "IGMP static join information\n")
3378 u_char uj
= use_json(argc
, argv
);
3384 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3388 vty_out(vty
, " \"%s\": ", vrf
->name
);
3391 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3392 igmp_show_interface_join(vrf
->info
, vty
);
3395 vty_out(vty
, "}\n");
3400 DEFUN (show_ip_igmp_groups
,
3401 show_ip_igmp_groups_cmd
,
3402 "show ip igmp [vrf NAME] groups [json]",
3411 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3412 u_char uj
= use_json(argc
, argv
);
3417 igmp_show_groups(vrf
->info
, vty
, uj
);
3422 DEFUN (show_ip_igmp_groups_vrf_all
,
3423 show_ip_igmp_groups_vrf_all_cmd
,
3424 "show ip igmp vrf all groups [json]",
3432 u_char uj
= use_json(argc
, argv
);
3438 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3442 vty_out(vty
, " \"%s\": ", vrf
->name
);
3445 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3446 igmp_show_groups(vrf
->info
, vty
, uj
);
3449 vty_out(vty
, "}\n");
3454 DEFUN (show_ip_igmp_groups_retransmissions
,
3455 show_ip_igmp_groups_retransmissions_cmd
,
3456 "show ip igmp [vrf NAME] groups retransmissions",
3462 "IGMP group retransmissions\n")
3465 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3470 igmp_show_group_retransmission(vrf
->info
, vty
);
3475 DEFUN (show_ip_igmp_sources
,
3476 show_ip_igmp_sources_cmd
,
3477 "show ip igmp [vrf NAME] sources",
3485 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3490 igmp_show_sources(vrf
->info
, vty
);
3495 DEFUN (show_ip_igmp_sources_retransmissions
,
3496 show_ip_igmp_sources_retransmissions_cmd
,
3497 "show ip igmp [vrf NAME] sources retransmissions",
3503 "IGMP source retransmissions\n")
3506 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3511 igmp_show_source_retransmission(vrf
->info
, vty
);
3516 DEFUN (show_ip_pim_assert
,
3517 show_ip_pim_assert_cmd
,
3518 "show ip pim [vrf NAME] assert",
3523 "PIM interface assert\n")
3526 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3531 pim_show_assert(vrf
->info
, vty
);
3536 DEFUN (show_ip_pim_assert_internal
,
3537 show_ip_pim_assert_internal_cmd
,
3538 "show ip pim [vrf NAME] assert-internal",
3543 "PIM interface internal assert state\n")
3546 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3551 pim_show_assert_internal(vrf
->info
, vty
);
3556 DEFUN (show_ip_pim_assert_metric
,
3557 show_ip_pim_assert_metric_cmd
,
3558 "show ip pim [vrf NAME] assert-metric",
3563 "PIM interface assert metric\n")
3566 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3571 pim_show_assert_metric(vrf
->info
, vty
);
3576 DEFUN (show_ip_pim_assert_winner_metric
,
3577 show_ip_pim_assert_winner_metric_cmd
,
3578 "show ip pim [vrf NAME] assert-winner-metric",
3583 "PIM interface assert winner metric\n")
3586 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3591 pim_show_assert_winner_metric(vrf
->info
, vty
);
3596 DEFUN (show_ip_pim_interface
,
3597 show_ip_pim_interface_cmd
,
3598 "show ip pim [vrf NAME] interface [detail|WORD] [json]",
3603 "PIM interface information\n"
3609 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3610 u_char uj
= use_json(argc
, argv
);
3615 if (argv_find(argv
, argc
, "WORD", &idx
)
3616 || argv_find(argv
, argc
, "detail", &idx
))
3617 pim_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
3619 pim_show_interfaces(vrf
->info
, vty
, uj
);
3624 DEFUN (show_ip_pim_interface_vrf_all
,
3625 show_ip_pim_interface_vrf_all_cmd
,
3626 "show ip pim vrf all interface [detail|WORD] [json]",
3631 "PIM interface information\n"
3637 u_char uj
= use_json(argc
, argv
);
3643 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3647 vty_out(vty
, " \"%s\": ", vrf
->name
);
3650 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3651 if (argv_find(argv
, argc
, "WORD", &idx
)
3652 || argv_find(argv
, argc
, "detail", &idx
))
3653 pim_show_interfaces_single(vrf
->info
, vty
,
3654 argv
[idx
]->arg
, uj
);
3656 pim_show_interfaces(vrf
->info
, vty
, uj
);
3659 vty_out(vty
, "}\n");
3664 DEFUN (show_ip_pim_join
,
3665 show_ip_pim_join_cmd
,
3666 "show ip pim [vrf NAME] join [json]",
3671 "PIM interface join information\n"
3675 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3676 u_char uj
= use_json(argc
, argv
);
3681 pim_show_join(vrf
->info
, vty
, uj
);
3686 DEFUN (show_ip_pim_join_vrf_all
,
3687 show_ip_pim_join_vrf_all_cmd
,
3688 "show ip pim vrf all join [json]",
3693 "PIM interface join information\n"
3696 u_char uj
= use_json(argc
, argv
);
3702 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3706 vty_out(vty
, " \"%s\": ", vrf
->name
);
3709 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3710 pim_show_join(vrf
->info
, vty
, uj
);
3713 vty_out(vty
, "}\n");
3718 DEFUN (show_ip_pim_local_membership
,
3719 show_ip_pim_local_membership_cmd
,
3720 "show ip pim [vrf NAME] local-membership [json]",
3725 "PIM interface local-membership\n"
3729 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3730 u_char uj
= use_json(argc
, argv
);
3735 pim_show_membership(vrf
->info
, vty
, uj
);
3740 DEFUN (show_ip_pim_neighbor
,
3741 show_ip_pim_neighbor_cmd
,
3742 "show ip pim [vrf NAME] neighbor [detail|WORD] [json]",
3747 "PIM neighbor information\n"
3749 "Name of interface or neighbor\n"
3753 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3754 u_char uj
= use_json(argc
, argv
);
3759 if (argv_find(argv
, argc
, "detail", &idx
)
3760 || argv_find(argv
, argc
, "WORD", &idx
))
3761 pim_show_neighbors_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
3763 pim_show_neighbors(vrf
->info
, vty
, uj
);
3768 DEFUN (show_ip_pim_neighbor_vrf_all
,
3769 show_ip_pim_neighbor_vrf_all_cmd
,
3770 "show ip pim vrf all neighbor [detail|WORD] [json]",
3775 "PIM neighbor information\n"
3777 "Name of interface or neighbor\n"
3781 u_char uj
= use_json(argc
, argv
);
3787 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3791 vty_out(vty
, " \"%s\": ", vrf
->name
);
3794 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3795 if (argv_find(argv
, argc
, "detail", &idx
)
3796 || argv_find(argv
, argc
, "WORD", &idx
))
3797 pim_show_neighbors_single(vrf
->info
, vty
,
3798 argv
[idx
]->arg
, uj
);
3800 pim_show_neighbors(vrf
->info
, vty
, uj
);
3803 vty_out(vty
, "}\n");
3808 DEFUN (show_ip_pim_secondary
,
3809 show_ip_pim_secondary_cmd
,
3810 "show ip pim [vrf NAME] secondary",
3815 "PIM neighbor addresses\n")
3818 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3823 pim_show_neighbors_secondary(vrf
->info
, vty
);
3828 DEFUN (show_ip_pim_state
,
3829 show_ip_pim_state_cmd
,
3830 "show ip pim [vrf NAME] state [A.B.C.D [A.B.C.D]] [json]",
3835 "PIM state information\n"
3836 "Unicast or Multicast address\n"
3837 "Multicast address\n"
3840 const char *src_or_group
= NULL
;
3841 const char *group
= NULL
;
3843 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3844 u_char uj
= use_json(argc
, argv
);
3852 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
3853 src_or_group
= argv
[idx
]->arg
;
3855 group
= argv
[idx
+ 1]->arg
;
3858 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
3863 DEFUN (show_ip_pim_state_vrf_all
,
3864 show_ip_pim_state_vrf_all_cmd
,
3865 "show ip pim vrf all state [A.B.C.D [A.B.C.D]] [json]",
3870 "PIM state information\n"
3871 "Unicast or Multicast address\n"
3872 "Multicast address\n"
3875 const char *src_or_group
= NULL
;
3876 const char *group
= NULL
;
3878 u_char uj
= use_json(argc
, argv
);
3887 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
3888 src_or_group
= argv
[idx
]->arg
;
3890 group
= argv
[idx
+ 1]->arg
;
3893 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3897 vty_out(vty
, " \"%s\": ", vrf
->name
);
3900 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3901 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
3904 vty_out(vty
, "}\n");
3909 DEFUN (show_ip_pim_upstream
,
3910 show_ip_pim_upstream_cmd
,
3911 "show ip pim [vrf NAME] upstream [json]",
3916 "PIM upstream information\n"
3920 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3921 u_char uj
= use_json(argc
, argv
);
3926 pim_show_upstream(vrf
->info
, vty
, uj
);
3931 DEFUN (show_ip_pim_upstream_vrf_all
,
3932 show_ip_pim_upstream_vrf_all_cmd
,
3933 "show ip pim vrf all upstream [json]",
3938 "PIM upstream information\n"
3941 u_char uj
= use_json(argc
, argv
);
3947 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3951 vty_out(vty
, " \"%s\": ", vrf
->name
);
3954 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3955 pim_show_upstream(vrf
->info
, vty
, uj
);
3961 DEFUN (show_ip_pim_upstream_join_desired
,
3962 show_ip_pim_upstream_join_desired_cmd
,
3963 "show ip pim [vrf NAME] upstream-join-desired [json]",
3968 "PIM upstream join-desired\n"
3972 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3973 u_char uj
= use_json(argc
, argv
);
3978 pim_show_join_desired(vrf
->info
, vty
, uj
);
3983 DEFUN (show_ip_pim_upstream_rpf
,
3984 show_ip_pim_upstream_rpf_cmd
,
3985 "show ip pim [vrf NAME] upstream-rpf [json]",
3990 "PIM upstream source rpf\n"
3994 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3995 u_char uj
= use_json(argc
, argv
);
4000 pim_show_upstream_rpf(vrf
->info
, vty
, uj
);
4005 DEFUN (show_ip_pim_rp
,
4007 "show ip pim [vrf NAME] rp-info [json]",
4012 "PIM RP information\n"
4016 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4017 u_char uj
= use_json(argc
, argv
);
4022 pim_rp_show_information(vrf
->info
, vty
, uj
);
4027 DEFUN (show_ip_pim_rp_vrf_all
,
4028 show_ip_pim_rp_vrf_all_cmd
,
4029 "show ip pim vrf all rp-info [json]",
4034 "PIM RP information\n"
4037 u_char uj
= use_json(argc
, argv
);
4043 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4047 vty_out(vty
, " \"%s\": ", vrf
->name
);
4050 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4051 pim_rp_show_information(vrf
->info
, vty
, uj
);
4054 vty_out(vty
, "}\n");
4059 DEFUN (show_ip_pim_rpf
,
4060 show_ip_pim_rpf_cmd
,
4061 "show ip pim [vrf NAME] rpf [json]",
4066 "PIM cached source rpf information\n"
4070 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4071 u_char uj
= use_json(argc
, argv
);
4076 pim_show_rpf(vrf
->info
, vty
, uj
);
4081 DEFUN (show_ip_pim_rpf_vrf_all
,
4082 show_ip_pim_rpf_vrf_all_cmd
,
4083 "show ip pim vrf all rpf [json]",
4088 "PIM cached source rpf information\n"
4091 u_char uj
= use_json(argc
, argv
);
4097 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4101 vty_out(vty
, " \"%s\": ", vrf
->name
);
4104 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4105 pim_show_rpf(vrf
->info
, vty
, uj
);
4108 vty_out(vty
, "}\n");
4113 DEFUN (show_ip_pim_nexthop
,
4114 show_ip_pim_nexthop_cmd
,
4115 "show ip pim [vrf NAME] nexthop",
4120 "PIM cached nexthop rpf information\n")
4123 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4128 pim_show_nexthop(vrf
->info
, vty
);
4133 DEFUN (show_ip_pim_nexthop_lookup
,
4134 show_ip_pim_nexthop_lookup_cmd
,
4135 "show ip pim [vrf NAME] nexthop-lookup A.B.C.D A.B.C.D",
4140 "PIM cached nexthop rpf lookup\n"
4141 "Source/RP address\n"
4142 "Multicast Group address\n")
4144 struct pim_nexthop_cache pnc
;
4145 struct prefix nht_p
;
4147 struct in_addr src_addr
, grp_addr
;
4148 struct in_addr vif_source
;
4149 const char *addr_str
, *addr_str1
;
4151 struct pim_nexthop nexthop
;
4152 char nexthop_addr_str
[PREFIX_STRLEN
];
4153 char grp_str
[PREFIX_STRLEN
];
4155 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4160 argv_find(argv
, argc
, "A.B.C.D", &idx
);
4161 addr_str
= argv
[idx
]->arg
;
4162 result
= inet_pton(AF_INET
, addr_str
, &src_addr
);
4164 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
4165 errno
, safe_strerror(errno
));
4169 if (pim_is_group_224_4(src_addr
)) {
4171 "Invalid argument. Expected Valid Source Address.\n");
4175 addr_str1
= argv
[idx
+ 1]->arg
;
4176 result
= inet_pton(AF_INET
, addr_str1
, &grp_addr
);
4178 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
4179 errno
, safe_strerror(errno
));
4183 if (!pim_is_group_224_4(grp_addr
)) {
4185 "Invalid argument. Expected Valid Multicast Group Address.\n");
4189 if (!pim_rp_set_upstream_addr(vrf
->info
, &vif_source
, src_addr
,
4193 memset(&pnc
, 0, sizeof(struct pim_nexthop_cache
));
4194 nht_p
.family
= AF_INET
;
4195 nht_p
.prefixlen
= IPV4_MAX_BITLEN
;
4196 nht_p
.u
.prefix4
= vif_source
;
4197 grp
.family
= AF_INET
;
4198 grp
.prefixlen
= IPV4_MAX_BITLEN
;
4199 grp
.u
.prefix4
= grp_addr
;
4200 memset(&nexthop
, 0, sizeof(nexthop
));
4202 if (pim_find_or_track_nexthop(vrf
->info
, &nht_p
, NULL
, NULL
, &pnc
))
4203 result
= pim_ecmp_nexthop_search(vrf
->info
, &pnc
, &nexthop
,
4206 result
= pim_ecmp_nexthop_lookup(vrf
->info
, &nexthop
,
4207 vif_source
, &nht_p
, &grp
, 0);
4211 "Nexthop Lookup failed, no usable routes returned.\n");
4215 pim_addr_dump("<grp?>", &grp
, grp_str
, sizeof(grp_str
));
4216 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
4217 nexthop_addr_str
, sizeof(nexthop_addr_str
));
4218 vty_out(vty
, "Group %s --- Nexthop %s Interface %s \n", grp_str
,
4219 nexthop_addr_str
, nexthop
.interface
->name
);
4224 DEFUN (show_ip_pim_interface_traffic
,
4225 show_ip_pim_interface_traffic_cmd
,
4226 "show ip pim [vrf NAME] interface traffic [WORD] [json]",
4231 "PIM interface information\n"
4232 "Protocol Packet counters\n"
4237 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4238 u_char uj
= use_json(argc
, argv
);
4243 if (argv_find(argv
, argc
, "WORD", &idx
))
4244 pim_show_interface_traffic_single(vrf
->info
, vty
,
4245 argv
[idx
]->arg
, uj
);
4247 pim_show_interface_traffic(vrf
->info
, vty
, uj
);
4252 static void show_multicast_interfaces(struct pim_instance
*pim
, struct vty
*vty
)
4254 struct interface
*ifp
;
4259 "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut\n");
4261 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
4262 struct pim_interface
*pim_ifp
;
4263 struct in_addr ifaddr
;
4264 struct sioc_vif_req vreq
;
4266 pim_ifp
= ifp
->info
;
4271 memset(&vreq
, 0, sizeof(vreq
));
4272 vreq
.vifi
= pim_ifp
->mroute_vif_index
;
4274 if (ioctl(pim
->mroute_socket
, SIOCGETVIFCNT
, &vreq
)) {
4276 "ioctl(SIOCGETVIFCNT=%lu) failure for interface %s vif_index=%d: errno=%d: %s",
4277 (unsigned long)SIOCGETVIFCNT
, ifp
->name
,
4278 pim_ifp
->mroute_vif_index
, errno
,
4279 safe_strerror(errno
));
4282 ifaddr
= pim_ifp
->primary_address
;
4284 vty_out(vty
, "%-12s %-15s %3d %3d %7lu %7lu %10lu %10lu\n",
4285 ifp
->name
, inet_ntoa(ifaddr
), ifp
->ifindex
,
4286 pim_ifp
->mroute_vif_index
, (unsigned long)vreq
.icount
,
4287 (unsigned long)vreq
.ocount
, (unsigned long)vreq
.ibytes
,
4288 (unsigned long)vreq
.obytes
);
4292 static void pim_cmd_show_ip_multicast_helper(struct pim_instance
*pim
,
4295 struct vrf
*vrf
= pim
->vrf
;
4296 time_t now
= pim_time_monotonic_sec();
4301 vty_out(vty
, "Mroute socket descriptor:");
4303 vty_out(vty
, " %d(%s)\n", pim
->mroute_socket
, vrf
->name
);
4305 pim_time_uptime(uptime
, sizeof(uptime
),
4306 now
- pim
->mroute_socket_creation
);
4307 vty_out(vty
, "Mroute socket uptime: %s\n", uptime
);
4311 pim_zebra_zclient_update(vty
);
4312 pim_zlookup_show_ip_multicast(vty
);
4315 vty_out(vty
, "Maximum highest VifIndex: %d\n", PIM_MAX_USABLE_VIFS
);
4318 vty_out(vty
, "Upstream Join Timer: %d secs\n", qpim_t_periodic
);
4319 vty_out(vty
, "Join/Prune Holdtime: %d secs\n", PIM_JP_HOLDTIME
);
4320 vty_out(vty
, "PIM ECMP: %s\n", qpim_ecmp_enable
? "Enable" : "Disable");
4321 vty_out(vty
, "PIM ECMP Rebalance: %s\n",
4322 qpim_ecmp_rebalance_enable
? "Enable" : "Disable");
4326 show_rpf_refresh_stats(vty
, now
, NULL
);
4330 show_scan_oil_stats(pim
, vty
, now
);
4332 show_multicast_interfaces(pim
, vty
);
4335 DEFUN (show_ip_multicast
,
4336 show_ip_multicast_cmd
,
4337 "show ip multicast [vrf NAME]",
4341 "Multicast global information\n")
4344 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4349 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
4354 DEFUN (show_ip_multicast_vrf_all
,
4355 show_ip_multicast_vrf_all_cmd
,
4356 "show ip multicast vrf all",
4360 "Multicast global information\n")
4362 u_char uj
= use_json(argc
, argv
);
4368 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4372 vty_out(vty
, " \"%s\": ", vrf
->name
);
4375 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4376 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
4379 vty_out(vty
, "}\n");
4384 static void show_mroute(struct pim_instance
*pim
, struct vty
*vty
, bool fill
,
4387 struct listnode
*node
;
4388 struct channel_oil
*c_oil
;
4389 struct static_route
*s_route
;
4391 json_object
*json
= NULL
;
4392 json_object
*json_group
= NULL
;
4393 json_object
*json_source
= NULL
;
4394 json_object
*json_oil
= NULL
;
4395 json_object
*json_ifp_out
= NULL
;
4398 char grp_str
[INET_ADDRSTRLEN
];
4399 char src_str
[INET_ADDRSTRLEN
];
4400 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
4401 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
4403 struct interface
*ifp_in
;
4407 json
= json_object_new_object();
4410 "Source Group Proto Input Output TTL Uptime\n");
4413 now
= pim_time_monotonic_sec();
4415 /* print list of PIM and IGMP routes */
4416 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
4419 if (!c_oil
->installed
&& !uj
)
4422 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
4424 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
4426 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
4429 strcpy(in_ifname
, ifp_in
->name
);
4431 strcpy(in_ifname
, "<iif?>");
4435 /* Find the group, create it if it doesn't exist */
4436 json_object_object_get_ex(json
, grp_str
, &json_group
);
4439 json_group
= json_object_new_object();
4440 json_object_object_add(json
, grp_str
,
4444 /* Find the source nested under the group, create it if
4445 * it doesn't exist */
4446 json_object_object_get_ex(json_group
, src_str
,
4450 json_source
= json_object_new_object();
4451 json_object_object_add(json_group
, src_str
,
4455 /* Find the inbound interface nested under the source,
4456 * create it if it doesn't exist */
4457 json_object_int_add(json_source
, "installed",
4459 json_object_int_add(json_source
, "refCount",
4460 c_oil
->oil_ref_count
);
4461 json_object_int_add(json_source
, "oilSize",
4463 json_object_int_add(json_source
, "OilInheritedRescan",
4464 c_oil
->oil_inherited_rescan
);
4465 json_object_string_add(json_source
, "iif", in_ifname
);
4469 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
4471 struct interface
*ifp_out
;
4472 char oif_uptime
[10];
4475 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
4479 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
4481 oif_uptime
, sizeof(oif_uptime
),
4482 now
- c_oil
->oif_creation
[oif_vif_index
]);
4486 strcpy(out_ifname
, ifp_out
->name
);
4488 strcpy(out_ifname
, "<oif?>");
4491 json_ifp_out
= json_object_new_object();
4492 json_object_string_add(json_ifp_out
, "source",
4494 json_object_string_add(json_ifp_out
, "group",
4497 if (c_oil
->oif_flags
[oif_vif_index
]
4498 & PIM_OIF_FLAG_PROTO_PIM
)
4499 json_object_boolean_true_add(
4500 json_ifp_out
, "protocolPim");
4502 if (c_oil
->oif_flags
[oif_vif_index
]
4503 & PIM_OIF_FLAG_PROTO_IGMP
)
4504 json_object_boolean_true_add(
4505 json_ifp_out
, "protocolIgmp");
4507 if (c_oil
->oif_flags
[oif_vif_index
]
4508 & PIM_OIF_FLAG_PROTO_SOURCE
)
4509 json_object_boolean_true_add(
4510 json_ifp_out
, "protocolSource");
4512 if (c_oil
->oif_flags
[oif_vif_index
]
4513 & PIM_OIF_FLAG_PROTO_STAR
)
4514 json_object_boolean_true_add(
4516 "protocolInherited");
4518 json_object_string_add(json_ifp_out
,
4521 json_object_int_add(json_ifp_out
, "iVifI",
4522 c_oil
->oil
.mfcc_parent
);
4523 json_object_string_add(json_ifp_out
,
4524 "outboundInterface",
4526 json_object_int_add(json_ifp_out
, "oVifI",
4528 json_object_int_add(json_ifp_out
, "ttl", ttl
);
4529 json_object_string_add(json_ifp_out
, "upTime",
4532 json_oil
= json_object_new_object();
4533 json_object_object_add(json_source
,
4536 json_object_object_add(json_oil
, out_ifname
,
4539 if (c_oil
->oif_flags
[oif_vif_index
]
4540 & PIM_OIF_FLAG_PROTO_PIM
) {
4541 strcpy(proto
, "PIM");
4544 if (c_oil
->oif_flags
[oif_vif_index
]
4545 & PIM_OIF_FLAG_PROTO_IGMP
) {
4546 strcpy(proto
, "IGMP");
4549 if (c_oil
->oif_flags
[oif_vif_index
]
4550 & PIM_OIF_FLAG_PROTO_SOURCE
) {
4551 strcpy(proto
, "SRC");
4554 if (c_oil
->oif_flags
[oif_vif_index
]
4555 & PIM_OIF_FLAG_PROTO_STAR
) {
4556 strcpy(proto
, "STAR");
4560 "%-15s %-15s %-6s %-10s %-10s %-3d %8s\n",
4561 src_str
, grp_str
, proto
, in_ifname
,
4562 out_ifname
, ttl
, oif_uptime
);
4567 in_ifname
[0] = '\0';
4573 if (!uj
&& !found_oif
) {
4574 vty_out(vty
, "%-15s %-15s %-6s %-10s %-10s %-3d %8s\n",
4575 src_str
, grp_str
, "none", in_ifname
, "none", 0,
4580 /* Print list of static routes */
4581 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
4584 if (!s_route
->c_oil
.installed
)
4587 pim_inet4_dump("<group?>", s_route
->group
, grp_str
,
4589 pim_inet4_dump("<source?>", s_route
->source
, src_str
,
4591 ifp_in
= pim_if_find_by_vif_index(pim
, s_route
->iif
);
4595 strcpy(in_ifname
, ifp_in
->name
);
4597 strcpy(in_ifname
, "<iif?>");
4601 /* Find the group, create it if it doesn't exist */
4602 json_object_object_get_ex(json
, grp_str
, &json_group
);
4605 json_group
= json_object_new_object();
4606 json_object_object_add(json
, grp_str
,
4610 /* Find the source nested under the group, create it if
4611 * it doesn't exist */
4612 json_object_object_get_ex(json_group
, src_str
,
4616 json_source
= json_object_new_object();
4617 json_object_object_add(json_group
, src_str
,
4621 json_object_string_add(json_source
, "iif", in_ifname
);
4624 strcpy(proto
, "STATIC");
4627 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
4629 struct interface
*ifp_out
;
4630 char oif_uptime
[10];
4633 ttl
= s_route
->oif_ttls
[oif_vif_index
];
4637 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
4639 oif_uptime
, sizeof(oif_uptime
),
4642 .oif_creation
[oif_vif_index
]);
4646 strcpy(out_ifname
, ifp_out
->name
);
4648 strcpy(out_ifname
, "<oif?>");
4651 json_ifp_out
= json_object_new_object();
4652 json_object_string_add(json_ifp_out
, "source",
4654 json_object_string_add(json_ifp_out
, "group",
4656 json_object_boolean_true_add(json_ifp_out
,
4658 json_object_string_add(json_ifp_out
,
4661 json_object_int_add(
4662 json_ifp_out
, "iVifI",
4663 s_route
->c_oil
.oil
.mfcc_parent
);
4664 json_object_string_add(json_ifp_out
,
4665 "outboundInterface",
4667 json_object_int_add(json_ifp_out
, "oVifI",
4669 json_object_int_add(json_ifp_out
, "ttl", ttl
);
4670 json_object_string_add(json_ifp_out
, "upTime",
4673 json_oil
= json_object_new_object();
4674 json_object_object_add(json_source
,
4677 json_object_object_add(json_oil
, out_ifname
,
4681 "%-15s %-15s %-6s %-10s %-10s %-3d %8s %s\n",
4682 src_str
, grp_str
, proto
, in_ifname
,
4683 out_ifname
, ttl
, oif_uptime
,
4685 if (first
&& !fill
) {
4688 in_ifname
[0] = '\0';
4694 if (!uj
&& !found_oif
) {
4696 "%-15s %-15s %-6s %-10s %-10s %-3d %8s %s\n",
4697 src_str
, grp_str
, proto
, in_ifname
, "none", 0,
4698 "--:--:--", pim
->vrf
->name
);
4703 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4704 json
, JSON_C_TO_STRING_PRETTY
));
4705 json_object_free(json
);
4709 DEFUN (show_ip_mroute
,
4711 "show ip mroute [vrf NAME] [fill] [json]",
4716 "Fill in Assumed data\n"
4719 u_char uj
= use_json(argc
, argv
);
4722 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4727 if (argv_find(argv
, argc
, "fill", &idx
))
4730 show_mroute(vrf
->info
, vty
, fill
, uj
);
4734 DEFUN (show_ip_mroute_vrf_all
,
4735 show_ip_mroute_vrf_all_cmd
,
4736 "show ip mroute vrf all [fill] [json]",
4741 "Fill in Assumed data\n"
4744 u_char uj
= use_json(argc
, argv
);
4750 if (argv_find(argv
, argc
, "fill", &idx
))
4755 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4759 vty_out(vty
, " \"%s\": ", vrf
->name
);
4762 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4763 show_mroute(vrf
->info
, vty
, fill
, uj
);
4766 vty_out(vty
, "}\n");
4771 static void show_mroute_count(struct pim_instance
*pim
, struct vty
*vty
)
4773 struct listnode
*node
;
4774 struct channel_oil
*c_oil
;
4775 struct static_route
*s_route
;
4780 "Source Group LastUsed Packets Bytes WrongIf \n");
4782 /* Print PIM and IGMP route counts */
4783 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
4784 char group_str
[INET_ADDRSTRLEN
];
4785 char source_str
[INET_ADDRSTRLEN
];
4787 if (!c_oil
->installed
)
4790 pim_mroute_update_counters(c_oil
);
4792 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, group_str
,
4794 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, source_str
,
4795 sizeof(source_str
));
4797 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
4798 source_str
, group_str
, c_oil
->cc
.lastused
/ 100,
4799 c_oil
->cc
.pktcnt
, c_oil
->cc
.bytecnt
,
4800 c_oil
->cc
.wrong_if
);
4803 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
4804 char group_str
[INET_ADDRSTRLEN
];
4805 char source_str
[INET_ADDRSTRLEN
];
4807 if (!s_route
->c_oil
.installed
)
4810 pim_mroute_update_counters(&s_route
->c_oil
);
4812 pim_inet4_dump("<group?>", s_route
->c_oil
.oil
.mfcc_mcastgrp
,
4813 group_str
, sizeof(group_str
));
4814 pim_inet4_dump("<source?>", s_route
->c_oil
.oil
.mfcc_origin
,
4815 source_str
, sizeof(source_str
));
4817 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
4818 source_str
, group_str
, s_route
->c_oil
.cc
.lastused
,
4819 s_route
->c_oil
.cc
.pktcnt
, s_route
->c_oil
.cc
.bytecnt
,
4820 s_route
->c_oil
.cc
.wrong_if
);
4824 DEFUN (show_ip_mroute_count
,
4825 show_ip_mroute_count_cmd
,
4826 "show ip mroute [vrf NAME] count",
4831 "Route and packet count data\n")
4834 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4839 show_mroute_count(vrf
->info
, vty
);
4843 DEFUN (show_ip_mroute_count_vrf_all
,
4844 show_ip_mroute_count_vrf_all_cmd
,
4845 "show ip mroute vrf all count",
4850 "Route and packet count data\n")
4852 u_char uj
= use_json(argc
, argv
);
4858 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4862 vty_out(vty
, " \"%s\": ", vrf
->name
);
4865 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4866 show_mroute_count(vrf
->info
, vty
);
4869 vty_out(vty
, "}\n");
4876 "show ip rib [vrf NAME] A.B.C.D",
4881 "Unicast address\n")
4884 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4885 struct in_addr addr
;
4886 const char *addr_str
;
4887 struct pim_nexthop nexthop
;
4888 char nexthop_addr_str
[PREFIX_STRLEN
];
4894 memset(&nexthop
, 0, sizeof(nexthop
));
4895 argv_find(argv
, argc
, "A.B.C.D", &idx
);
4896 addr_str
= argv
[idx
]->arg
;
4897 result
= inet_pton(AF_INET
, addr_str
, &addr
);
4899 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
4900 errno
, safe_strerror(errno
));
4904 if (pim_nexthop_lookup(vrf
->info
, &nexthop
, addr
, 0)) {
4906 "Failure querying RIB nexthop for unicast address %s\n",
4912 "Address NextHop Interface Metric Preference\n");
4914 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
4915 nexthop_addr_str
, sizeof(nexthop_addr_str
));
4917 vty_out(vty
, "%-15s %-15s %-9s %6d %10d\n", addr_str
, nexthop_addr_str
,
4918 nexthop
.interface
? nexthop
.interface
->name
: "<ifname?>",
4919 nexthop
.mrib_route_metric
, nexthop
.mrib_metric_preference
);
4924 static void show_ssmpingd(struct pim_instance
*pim
, struct vty
*vty
)
4926 struct listnode
*node
;
4927 struct ssmpingd_sock
*ss
;
4931 "Source Socket Address Port Uptime Requests\n");
4933 if (!pim
->ssmpingd_list
)
4936 now
= pim_time_monotonic_sec();
4938 for (ALL_LIST_ELEMENTS_RO(pim
->ssmpingd_list
, node
, ss
)) {
4939 char source_str
[INET_ADDRSTRLEN
];
4941 struct sockaddr_in bind_addr
;
4942 socklen_t len
= sizeof(bind_addr
);
4943 char bind_addr_str
[INET_ADDRSTRLEN
];
4945 pim_inet4_dump("<src?>", ss
->source_addr
, source_str
,
4946 sizeof(source_str
));
4948 if (pim_socket_getsockname(
4949 ss
->sock_fd
, (struct sockaddr
*)&bind_addr
, &len
)) {
4951 "%% Failure reading socket name for ssmpingd source %s on fd=%d\n",
4952 source_str
, ss
->sock_fd
);
4955 pim_inet4_dump("<addr?>", bind_addr
.sin_addr
, bind_addr_str
,
4956 sizeof(bind_addr_str
));
4957 pim_time_uptime(ss_uptime
, sizeof(ss_uptime
),
4958 now
- ss
->creation
);
4960 vty_out(vty
, "%-15s %6d %-15s %5d %8s %8lld\n", source_str
,
4961 ss
->sock_fd
, bind_addr_str
, ntohs(bind_addr
.sin_port
),
4962 ss_uptime
, (long long)ss
->requests
);
4966 DEFUN (show_ip_ssmpingd
,
4967 show_ip_ssmpingd_cmd
,
4968 "show ip ssmpingd [vrf NAME]",
4975 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4980 show_ssmpingd(vrf
->info
, vty
);
4984 static int pim_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
4985 const char *rp
, const char *group
,
4990 result
= pim_rp_new(pim
, rp
, group
, plist
);
4992 if (result
== PIM_MALLOC_FAIL
) {
4993 vty_out(vty
, "%% Out of memory\n");
4994 return CMD_WARNING_CONFIG_FAILED
;
4997 if (result
== PIM_GROUP_BAD_ADDRESS
) {
4998 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
4999 return CMD_WARNING_CONFIG_FAILED
;
5002 if (result
== PIM_RP_BAD_ADDRESS
) {
5003 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
5004 return CMD_WARNING_CONFIG_FAILED
;
5007 if (result
== PIM_RP_NO_PATH
) {
5008 vty_out(vty
, "%% No Path to RP address specified: %s\n", rp
);
5012 if (result
== PIM_GROUP_OVERLAP
) {
5014 "%% Group range specified cannot exact match another\n");
5015 return CMD_WARNING_CONFIG_FAILED
;
5018 if (result
== PIM_GROUP_PFXLIST_OVERLAP
) {
5020 "%% This group is already covered by a RP prefix-list\n");
5021 return CMD_WARNING_CONFIG_FAILED
;
5024 if (result
== PIM_RP_PFXLIST_IN_USE
) {
5026 "%% The same prefix-list cannot be applied to multiple RPs\n");
5027 return CMD_WARNING_CONFIG_FAILED
;
5033 static int pim_cmd_spt_switchover(struct pim_instance
*pim
,
5034 enum pim_spt_switchover spt
,
5037 pim
->spt
.switchover
= spt
;
5039 switch (pim
->spt
.switchover
) {
5040 case PIM_SPT_IMMEDIATE
:
5042 XFREE(MTYPE_PIM_SPT_PLIST_NAME
, pim
->spt
.plist
);
5044 pim_upstream_add_lhr_star_pimreg(pim
);
5046 case PIM_SPT_INFINITY
:
5047 pim_upstream_remove_lhr_star_pimreg(pim
, plist
);
5050 XFREE(MTYPE_PIM_SPT_PLIST_NAME
, pim
->spt
.plist
);
5054 XSTRDUP(MTYPE_PIM_SPT_PLIST_NAME
, plist
);
5061 DEFUN (ip_pim_spt_switchover_infinity
,
5062 ip_pim_spt_switchover_infinity_cmd
,
5063 "ip pim spt-switchover infinity-and-beyond",
5067 "Never switch to SPT Tree\n")
5069 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5070 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, NULL
);
5073 DEFUN (ip_pim_spt_switchover_infinity_plist
,
5074 ip_pim_spt_switchover_infinity_plist_cmd
,
5075 "ip pim spt-switchover infinity-and-beyond prefix-list WORD",
5079 "Never switch to SPT Tree\n"
5080 "Prefix-List to control which groups to switch\n"
5081 "Prefix-List name\n")
5083 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5084 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, argv
[5]->arg
);
5087 DEFUN (no_ip_pim_spt_switchover_infinity
,
5088 no_ip_pim_spt_switchover_infinity_cmd
,
5089 "no ip pim spt-switchover infinity-and-beyond",
5094 "Never switch to SPT Tree\n")
5096 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5097 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
5100 DEFUN (no_ip_pim_spt_switchover_infinity_plist
,
5101 no_ip_pim_spt_switchover_infinity_plist_cmd
,
5102 "no ip pim spt-switchover infinity-and-beyond prefix-list WORD",
5107 "Never switch to SPT Tree\n"
5108 "Prefix-List to control which groups to switch\n"
5109 "Prefix-List name\n")
5111 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5112 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
5115 DEFUN (ip_pim_joinprune_time
,
5116 ip_pim_joinprune_time_cmd
,
5117 "ip pim join-prune-interval (60-600)",
5119 "pim multicast routing\n"
5120 "Join Prune Send Interval\n"
5123 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5124 qpim_t_periodic
= atoi(argv
[3]->arg
);
5128 DEFUN (no_ip_pim_joinprune_time
,
5129 no_ip_pim_joinprune_time_cmd
,
5130 "no ip pim join-prune-interval (60-600)",
5133 "pim multicast routing\n"
5134 "Join Prune Send Interval\n"
5137 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5138 qpim_t_periodic
= PIM_DEFAULT_T_PERIODIC
;
5142 DEFUN (ip_pim_register_suppress
,
5143 ip_pim_register_suppress_cmd
,
5144 "ip pim register-suppress-time (5-60000)",
5146 "pim multicast routing\n"
5147 "Register Suppress Timer\n"
5150 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5151 qpim_register_suppress_time
= atoi(argv
[3]->arg
);
5155 DEFUN (no_ip_pim_register_suppress
,
5156 no_ip_pim_register_suppress_cmd
,
5157 "no ip pim register-suppress-time (5-60000)",
5160 "pim multicast routing\n"
5161 "Register Suppress Timer\n"
5164 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5165 qpim_register_suppress_time
= PIM_REGISTER_SUPPRESSION_TIME_DEFAULT
;
5169 DEFUN (ip_pim_rp_keep_alive
,
5170 ip_pim_rp_keep_alive_cmd
,
5171 "ip pim rp keep-alive-timer (31-60000)",
5173 "pim multicast routing\n"
5175 "Keep alive Timer\n"
5178 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5179 pim
->rp_keep_alive_time
= atoi(argv
[4]->arg
);
5183 DEFUN (no_ip_pim_rp_keep_alive
,
5184 no_ip_pim_rp_keep_alive_cmd
,
5185 "no ip pim rp keep-alive-timer (31-60000)",
5188 "pim multicast routing\n"
5190 "Keep alive Timer\n"
5193 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5194 pim
->rp_keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
5198 DEFUN (ip_pim_keep_alive
,
5199 ip_pim_keep_alive_cmd
,
5200 "ip pim keep-alive-timer (31-60000)",
5202 "pim multicast routing\n"
5203 "Keep alive Timer\n"
5206 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5207 pim
->keep_alive_time
= atoi(argv
[3]->arg
);
5211 DEFUN (no_ip_pim_keep_alive
,
5212 no_ip_pim_keep_alive_cmd
,
5213 "no ip pim keep-alive-timer (31-60000)",
5216 "pim multicast routing\n"
5217 "Keep alive Timer\n"
5220 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5221 pim
->keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
5225 DEFUN (ip_pim_packets
,
5227 "ip pim packets (1-100)",
5229 "pim multicast routing\n"
5230 "packets to process at one time per fd\n"
5231 "Number of packets\n")
5233 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5234 qpim_packet_process
= atoi(argv
[3]->arg
);
5238 DEFUN (no_ip_pim_packets
,
5239 no_ip_pim_packets_cmd
,
5240 "no ip pim packets (1-100)",
5243 "pim multicast routing\n"
5244 "packets to process at one time per fd\n"
5245 "Number of packets\n")
5247 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5248 qpim_packet_process
= PIM_DEFAULT_PACKET_PROCESS
;
5252 DEFUN (ip_pim_v6_secondary
,
5253 ip_pim_v6_secondary_cmd
,
5254 "ip pim send-v6-secondary",
5256 "pim multicast routing\n"
5257 "Send v6 secondary addresses\n")
5259 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5260 pim
->send_v6_secondary
= 1;
5265 DEFUN (no_ip_pim_v6_secondary
,
5266 no_ip_pim_v6_secondary_cmd
,
5267 "no ip pim send-v6-secondary",
5270 "pim multicast routing\n"
5271 "Send v6 secondary addresses\n")
5273 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5274 pim
->send_v6_secondary
= 0;
5281 "ip pim rp A.B.C.D [A.B.C.D/M]",
5283 "pim multicast routing\n"
5285 "ip address of RP\n"
5286 "Group Address range to cover\n")
5288 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5291 if (argc
== (idx_ipv4
+ 1))
5292 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
5295 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
5296 argv
[idx_ipv4
+ 1]->arg
, NULL
);
5299 DEFUN (ip_pim_rp_prefix_list
,
5300 ip_pim_rp_prefix_list_cmd
,
5301 "ip pim rp A.B.C.D prefix-list WORD",
5303 "pim multicast routing\n"
5305 "ip address of RP\n"
5306 "group prefix-list filter\n"
5307 "Name of a prefix-list\n")
5309 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5310 return pim_rp_cmd_worker(pim
, vty
, argv
[3]->arg
, NULL
, argv
[5]->arg
);
5313 static int pim_no_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
5314 const char *rp
, const char *group
,
5317 int result
= pim_rp_del(pim
, rp
, group
, plist
);
5319 if (result
== PIM_GROUP_BAD_ADDRESS
) {
5320 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
5321 return CMD_WARNING_CONFIG_FAILED
;
5324 if (result
== PIM_RP_BAD_ADDRESS
) {
5325 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
5326 return CMD_WARNING_CONFIG_FAILED
;
5329 if (result
== PIM_RP_NOT_FOUND
) {
5330 vty_out(vty
, "%% Unable to find specified RP\n");
5331 return CMD_WARNING_CONFIG_FAILED
;
5337 DEFUN (no_ip_pim_rp
,
5339 "no ip pim rp A.B.C.D [A.B.C.D/M]",
5342 "pim multicast routing\n"
5344 "ip address of RP\n"
5345 "Group Address range to cover\n")
5347 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5348 int idx_ipv4
= 4, idx_group
= 0;
5350 if (argv_find(argv
, argc
, "A.B.C.D/M", &idx_group
))
5351 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
5352 argv
[idx_group
]->arg
, NULL
);
5354 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
5358 DEFUN (no_ip_pim_rp_prefix_list
,
5359 no_ip_pim_rp_prefix_list_cmd
,
5360 "no ip pim rp A.B.C.D prefix-list WORD",
5363 "pim multicast routing\n"
5365 "ip address of RP\n"
5366 "group prefix-list filter\n"
5367 "Name of a prefix-list\n")
5369 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5370 return pim_no_rp_cmd_worker(pim
, vty
, argv
[4]->arg
, NULL
, argv
[6]->arg
);
5373 static int pim_ssm_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
5376 int result
= pim_ssm_range_set(pim
, pim
->vrf_id
, plist
);
5378 if (result
== PIM_SSM_ERR_NONE
)
5382 case PIM_SSM_ERR_NO_VRF
:
5383 vty_out(vty
, "%% VRF doesn't exist\n");
5385 case PIM_SSM_ERR_DUP
:
5386 vty_out(vty
, "%% duplicate config\n");
5389 vty_out(vty
, "%% ssm range config failed\n");
5392 return CMD_WARNING_CONFIG_FAILED
;
5395 DEFUN (ip_pim_ssm_prefix_list
,
5396 ip_pim_ssm_prefix_list_cmd
,
5397 "ip pim ssm prefix-list WORD",
5399 "pim multicast routing\n"
5400 "Source Specific Multicast\n"
5401 "group range prefix-list filter\n"
5402 "Name of a prefix-list\n")
5404 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5405 return pim_ssm_cmd_worker(pim
, vty
, argv
[4]->arg
);
5408 DEFUN (no_ip_pim_ssm_prefix_list
,
5409 no_ip_pim_ssm_prefix_list_cmd
,
5410 "no ip pim ssm prefix-list",
5413 "pim multicast routing\n"
5414 "Source Specific Multicast\n"
5415 "group range prefix-list filter\n")
5417 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5418 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
5421 DEFUN (no_ip_pim_ssm_prefix_list_name
,
5422 no_ip_pim_ssm_prefix_list_name_cmd
,
5423 "no ip pim ssm prefix-list WORD",
5426 "pim multicast routing\n"
5427 "Source Specific Multicast\n"
5428 "group range prefix-list filter\n"
5429 "Name of a prefix-list\n")
5431 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5432 struct pim_ssm
*ssm
= pim
->ssm_info
;
5434 if (ssm
->plist_name
&& !strcmp(ssm
->plist_name
, argv
[5]->arg
))
5435 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
5437 vty_out(vty
, "%% pim ssm prefix-list %s doesn't exist\n", argv
[5]->arg
);
5439 return CMD_WARNING_CONFIG_FAILED
;
5442 static void ip_pim_ssm_show_group_range(struct pim_instance
*pim
,
5443 struct vty
*vty
, u_char uj
)
5445 struct pim_ssm
*ssm
= pim
->ssm_info
;
5446 const char *range_str
=
5447 ssm
->plist_name
? ssm
->plist_name
: PIM_SSM_STANDARD_RANGE
;
5451 json
= json_object_new_object();
5452 json_object_string_add(json
, "ssmGroups", range_str
);
5453 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5454 json
, JSON_C_TO_STRING_PRETTY
));
5455 json_object_free(json
);
5457 vty_out(vty
, "SSM group range : %s\n", range_str
);
5460 DEFUN (show_ip_pim_ssm_range
,
5461 show_ip_pim_ssm_range_cmd
,
5462 "show ip pim [vrf NAME] group-type [json]",
5471 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5472 u_char uj
= use_json(argc
, argv
);
5477 ip_pim_ssm_show_group_range(vrf
->info
, vty
, uj
);
5482 static void ip_pim_ssm_show_group_type(struct pim_instance
*pim
,
5483 struct vty
*vty
, u_char uj
,
5486 struct in_addr group_addr
;
5487 const char *type_str
;
5490 result
= inet_pton(AF_INET
, group
, &group_addr
);
5492 type_str
= "invalid";
5494 if (pim_is_group_224_4(group_addr
))
5496 pim_is_grp_ssm(pim
, group_addr
) ? "SSM" : "ASM";
5498 type_str
= "not-multicast";
5503 json
= json_object_new_object();
5504 json_object_string_add(json
, "groupType", type_str
);
5505 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5506 json
, JSON_C_TO_STRING_PRETTY
));
5507 json_object_free(json
);
5509 vty_out(vty
, "Group type : %s\n", type_str
);
5512 DEFUN (show_ip_pim_group_type
,
5513 show_ip_pim_group_type_cmd
,
5514 "show ip pim [vrf NAME] group-type A.B.C.D [json]",
5519 "multicast group type\n"
5524 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5525 u_char uj
= use_json(argc
, argv
);
5530 argv_find(argv
, argc
, "A.B.C.D", &idx
);
5531 ip_pim_ssm_show_group_type(vrf
->info
, vty
, uj
, argv
[idx
]->arg
);
5536 DEFUN_HIDDEN (ip_multicast_routing
,
5537 ip_multicast_routing_cmd
,
5538 "ip multicast-routing",
5540 "Enable IP multicast forwarding\n")
5545 DEFUN_HIDDEN (no_ip_multicast_routing
,
5546 no_ip_multicast_routing_cmd
,
5547 "no ip multicast-routing",
5550 "Enable IP multicast forwarding\n")
5553 "Command is Disabled and will be removed in a future version\n");
5559 "ip ssmpingd [A.B.C.D]",
5564 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5567 struct in_addr source_addr
;
5568 const char *source_str
= (argc
== 3) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
5570 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
5572 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
5573 source_str
, errno
, safe_strerror(errno
));
5574 return CMD_WARNING_CONFIG_FAILED
;
5577 result
= pim_ssmpingd_start(pim
, source_addr
);
5579 vty_out(vty
, "%% Failure starting ssmpingd for source %s: %d\n",
5580 source_str
, result
);
5581 return CMD_WARNING_CONFIG_FAILED
;
5587 DEFUN (no_ip_ssmpingd
,
5589 "no ip ssmpingd [A.B.C.D]",
5595 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5598 struct in_addr source_addr
;
5599 const char *source_str
= (argc
== 4) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
5601 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
5603 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
5604 source_str
, errno
, safe_strerror(errno
));
5605 return CMD_WARNING_CONFIG_FAILED
;
5608 result
= pim_ssmpingd_stop(pim
, source_addr
);
5610 vty_out(vty
, "%% Failure stopping ssmpingd for source %s: %d\n",
5611 source_str
, result
);
5612 return CMD_WARNING_CONFIG_FAILED
;
5622 "pim multicast routing\n"
5623 "Enable PIM ECMP \n")
5625 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5626 qpim_ecmp_enable
= 1;
5631 DEFUN (no_ip_pim_ecmp
,
5636 "pim multicast routing\n"
5637 "Disable PIM ECMP \n")
5639 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5640 qpim_ecmp_enable
= 0;
5645 DEFUN (ip_pim_ecmp_rebalance
,
5646 ip_pim_ecmp_rebalance_cmd
,
5647 "ip pim ecmp rebalance",
5649 "pim multicast routing\n"
5650 "Enable PIM ECMP \n"
5651 "Enable PIM ECMP Rebalance\n")
5653 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5654 qpim_ecmp_enable
= 1;
5655 qpim_ecmp_rebalance_enable
= 1;
5660 DEFUN (no_ip_pim_ecmp_rebalance
,
5661 no_ip_pim_ecmp_rebalance_cmd
,
5662 "no ip pim ecmp rebalance",
5665 "pim multicast routing\n"
5666 "Disable PIM ECMP \n"
5667 "Disable PIM ECMP Rebalance\n")
5669 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5670 qpim_ecmp_rebalance_enable
= 0;
5675 static int pim_cmd_igmp_start(struct vty
*vty
, struct interface
*ifp
)
5677 struct pim_interface
*pim_ifp
;
5678 uint8_t need_startup
= 0;
5680 pim_ifp
= ifp
->info
;
5683 pim_ifp
= pim_if_new(ifp
, 1 /* igmp=true */, 0 /* pim=false */);
5685 vty_out(vty
, "Could not enable IGMP on interface %s\n",
5687 return CMD_WARNING_CONFIG_FAILED
;
5691 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
5692 PIM_IF_DO_IGMP(pim_ifp
->options
);
5697 /* 'ip igmp' executed multiple times, with need_startup
5698 avoid multiple if add all and membership refresh */
5700 pim_if_addr_add_all(ifp
);
5701 pim_if_membership_refresh(ifp
);
5707 DEFUN (interface_ip_igmp
,
5708 interface_ip_igmp_cmd
,
5713 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5715 return pim_cmd_igmp_start(vty
, ifp
);
5718 DEFUN (interface_no_ip_igmp
,
5719 interface_no_ip_igmp_cmd
,
5725 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5726 struct pim_interface
*pim_ifp
= ifp
->info
;
5731 PIM_IF_DONT_IGMP(pim_ifp
->options
);
5733 pim_if_membership_clear(ifp
);
5735 pim_if_addr_del_all_igmp(ifp
);
5737 if (!PIM_IF_TEST_PIM(pim_ifp
->options
)) {
5744 DEFUN (interface_ip_igmp_join
,
5745 interface_ip_igmp_join_cmd
,
5746 "ip igmp join A.B.C.D A.B.C.D",
5749 "IGMP join multicast group\n"
5750 "Multicast group address\n"
5753 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5756 const char *group_str
;
5757 const char *source_str
;
5758 struct in_addr group_addr
;
5759 struct in_addr source_addr
;
5763 group_str
= argv
[idx_ipv4
]->arg
;
5764 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
5766 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
5767 errno
, safe_strerror(errno
));
5768 return CMD_WARNING_CONFIG_FAILED
;
5771 /* Source address */
5772 source_str
= argv
[idx_ipv4_2
]->arg
;
5773 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
5775 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
5776 source_str
, errno
, safe_strerror(errno
));
5777 return CMD_WARNING_CONFIG_FAILED
;
5780 CMD_FERR_RETURN(pim_if_igmp_join_add(ifp
, group_addr
, source_addr
),
5781 "Failure joining IGMP group: $ERR");
5786 DEFUN (interface_no_ip_igmp_join
,
5787 interface_no_ip_igmp_join_cmd
,
5788 "no ip igmp join A.B.C.D A.B.C.D",
5792 "IGMP join multicast group\n"
5793 "Multicast group address\n"
5796 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5799 const char *group_str
;
5800 const char *source_str
;
5801 struct in_addr group_addr
;
5802 struct in_addr source_addr
;
5806 group_str
= argv
[idx_ipv4
]->arg
;
5807 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
5809 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
5810 errno
, safe_strerror(errno
));
5811 return CMD_WARNING_CONFIG_FAILED
;
5814 /* Source address */
5815 source_str
= argv
[idx_ipv4_2
]->arg
;
5816 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
5818 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
5819 source_str
, errno
, safe_strerror(errno
));
5820 return CMD_WARNING_CONFIG_FAILED
;
5823 result
= pim_if_igmp_join_del(ifp
, group_addr
, source_addr
);
5826 "%% Failure leaving IGMP group %s source %s on interface %s: %d\n",
5827 group_str
, source_str
, ifp
->name
, result
);
5828 return CMD_WARNING_CONFIG_FAILED
;
5835 CLI reconfiguration affects the interface level (struct pim_interface).
5836 This function propagates the reconfiguration to every active socket
5839 static void igmp_sock_query_interval_reconfig(struct igmp_sock
*igmp
)
5841 struct interface
*ifp
;
5842 struct pim_interface
*pim_ifp
;
5846 /* other querier present? */
5848 if (igmp
->t_other_querier_timer
)
5851 /* this is the querier */
5853 zassert(igmp
->interface
);
5854 zassert(igmp
->interface
->info
);
5856 ifp
= igmp
->interface
;
5857 pim_ifp
= ifp
->info
;
5859 if (PIM_DEBUG_IGMP_TRACE
) {
5860 char ifaddr_str
[INET_ADDRSTRLEN
];
5861 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
5862 sizeof(ifaddr_str
));
5863 zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
5864 __PRETTY_FUNCTION__
, ifaddr_str
, ifp
->name
,
5865 pim_ifp
->igmp_default_query_interval
);
5869 igmp_startup_mode_on() will reset QQI:
5871 igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
5873 igmp_startup_mode_on(igmp
);
5876 static void igmp_sock_query_reschedule(struct igmp_sock
*igmp
)
5878 if (igmp
->t_igmp_query_timer
) {
5879 /* other querier present */
5880 zassert(igmp
->t_igmp_query_timer
);
5881 zassert(!igmp
->t_other_querier_timer
);
5883 pim_igmp_general_query_off(igmp
);
5884 pim_igmp_general_query_on(igmp
);
5886 zassert(igmp
->t_igmp_query_timer
);
5887 zassert(!igmp
->t_other_querier_timer
);
5889 /* this is the querier */
5891 zassert(!igmp
->t_igmp_query_timer
);
5892 zassert(igmp
->t_other_querier_timer
);
5894 pim_igmp_other_querier_timer_off(igmp
);
5895 pim_igmp_other_querier_timer_on(igmp
);
5897 zassert(!igmp
->t_igmp_query_timer
);
5898 zassert(igmp
->t_other_querier_timer
);
5902 static void change_query_interval(struct pim_interface
*pim_ifp
,
5905 struct listnode
*sock_node
;
5906 struct igmp_sock
*igmp
;
5908 pim_ifp
->igmp_default_query_interval
= query_interval
;
5910 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
5911 igmp_sock_query_interval_reconfig(igmp
);
5912 igmp_sock_query_reschedule(igmp
);
5916 static void change_query_max_response_time(struct pim_interface
*pim_ifp
,
5917 int query_max_response_time_dsec
)
5919 struct listnode
*sock_node
;
5920 struct igmp_sock
*igmp
;
5922 pim_ifp
->igmp_query_max_response_time_dsec
=
5923 query_max_response_time_dsec
;
5926 Below we modify socket/group/source timers in order to quickly
5927 reflect the change. Otherwise, those timers would eventually catch
5931 /* scan all sockets */
5932 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
5933 struct listnode
*grp_node
;
5934 struct igmp_group
*grp
;
5936 /* reschedule socket general query */
5937 igmp_sock_query_reschedule(igmp
);
5939 /* scan socket groups */
5940 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grp_node
,
5942 struct listnode
*src_node
;
5943 struct igmp_source
*src
;
5945 /* reset group timers for groups in EXCLUDE mode */
5946 if (grp
->group_filtermode_isexcl
) {
5947 igmp_group_reset_gmi(grp
);
5950 /* scan group sources */
5951 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
,
5954 /* reset source timers for sources with running
5956 if (src
->t_source_timer
) {
5957 igmp_source_reset_gmi(igmp
, grp
, src
);
5964 #define IGMP_QUERY_INTERVAL_MIN (1)
5965 #define IGMP_QUERY_INTERVAL_MAX (1800)
5967 DEFUN (interface_ip_igmp_query_interval
,
5968 interface_ip_igmp_query_interval_cmd
,
5969 "ip igmp query-interval (1-1800)",
5972 IFACE_IGMP_QUERY_INTERVAL_STR
5973 "Query interval in seconds\n")
5975 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5976 struct pim_interface
*pim_ifp
= ifp
->info
;
5978 int query_interval_dsec
;
5982 ret
= pim_cmd_igmp_start(vty
, ifp
);
5983 if (ret
!= CMD_SUCCESS
)
5985 pim_ifp
= ifp
->info
;
5988 query_interval
= atoi(argv
[3]->arg
);
5989 query_interval_dsec
= 10 * query_interval
;
5992 It seems we don't need to check bounds since command.c does it
5993 already, but we verify them anyway for extra safety.
5995 if (query_interval
< IGMP_QUERY_INTERVAL_MIN
) {
5997 "General query interval %d lower than minimum %d\n",
5998 query_interval
, IGMP_QUERY_INTERVAL_MIN
);
5999 return CMD_WARNING_CONFIG_FAILED
;
6001 if (query_interval
> IGMP_QUERY_INTERVAL_MAX
) {
6003 "General query interval %d higher than maximum %d\n",
6004 query_interval
, IGMP_QUERY_INTERVAL_MAX
);
6005 return CMD_WARNING_CONFIG_FAILED
;
6008 if (query_interval_dsec
<= pim_ifp
->igmp_query_max_response_time_dsec
) {
6010 "Can't set general query interval %d dsec <= query max response time %d dsec.\n",
6011 query_interval_dsec
,
6012 pim_ifp
->igmp_query_max_response_time_dsec
);
6013 return CMD_WARNING_CONFIG_FAILED
;
6016 change_query_interval(pim_ifp
, query_interval
);
6021 DEFUN (interface_no_ip_igmp_query_interval
,
6022 interface_no_ip_igmp_query_interval_cmd
,
6023 "no ip igmp query-interval",
6027 IFACE_IGMP_QUERY_INTERVAL_STR
)
6029 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6030 struct pim_interface
*pim_ifp
= ifp
->info
;
6031 int default_query_interval_dsec
;
6036 default_query_interval_dsec
= IGMP_GENERAL_QUERY_INTERVAL
* 10;
6038 if (default_query_interval_dsec
6039 <= pim_ifp
->igmp_query_max_response_time_dsec
) {
6041 "Can't set default general query interval %d dsec <= query max response time %d dsec.\n",
6042 default_query_interval_dsec
,
6043 pim_ifp
->igmp_query_max_response_time_dsec
);
6044 return CMD_WARNING_CONFIG_FAILED
;
6047 change_query_interval(pim_ifp
, IGMP_GENERAL_QUERY_INTERVAL
);
6052 DEFUN (interface_ip_igmp_version
,
6053 interface_ip_igmp_version_cmd
,
6054 "ip igmp version (2-3)",
6058 "IGMP version number\n")
6060 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6061 struct pim_interface
*pim_ifp
= ifp
->info
;
6062 int igmp_version
, old_version
= 0;
6066 ret
= pim_cmd_igmp_start(vty
, ifp
);
6067 if (ret
!= CMD_SUCCESS
)
6069 pim_ifp
= ifp
->info
;
6072 igmp_version
= atoi(argv
[3]->arg
);
6073 old_version
= pim_ifp
->igmp_version
;
6074 pim_ifp
->igmp_version
= igmp_version
;
6076 // Check if IGMP is Enabled otherwise, enable on interface
6077 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
6078 PIM_IF_DO_IGMP(pim_ifp
->options
);
6079 pim_if_addr_add_all(ifp
);
6080 pim_if_membership_refresh(ifp
);
6081 old_version
= igmp_version
;
6082 // avoid refreshing membership again.
6084 /* Current and new version is different refresh existing
6085 membership. Going from 3 -> 2 or 2 -> 3. */
6086 if (old_version
!= igmp_version
)
6087 pim_if_membership_refresh(ifp
);
6092 DEFUN (interface_no_ip_igmp_version
,
6093 interface_no_ip_igmp_version_cmd
,
6094 "no ip igmp version (2-3)",
6099 "IGMP version number\n")
6101 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6102 struct pim_interface
*pim_ifp
= ifp
->info
;
6107 pim_ifp
->igmp_version
= IGMP_DEFAULT_VERSION
;
6112 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
6113 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
6115 DEFUN (interface_ip_igmp_query_max_response_time
,
6116 interface_ip_igmp_query_max_response_time_cmd
,
6117 "ip igmp query-max-response-time (10-250)",
6120 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
6121 "Query response value in deci-seconds\n")
6123 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6124 struct pim_interface
*pim_ifp
= ifp
->info
;
6125 int query_max_response_time
;
6129 ret
= pim_cmd_igmp_start(vty
, ifp
);
6130 if (ret
!= CMD_SUCCESS
)
6132 pim_ifp
= ifp
->info
;
6135 query_max_response_time
= atoi(argv
[3]->arg
);
6137 if (query_max_response_time
6138 >= pim_ifp
->igmp_default_query_interval
* 10) {
6140 "Can't set query max response time %d sec >= general query interval %d sec\n",
6141 query_max_response_time
,
6142 pim_ifp
->igmp_default_query_interval
);
6143 return CMD_WARNING_CONFIG_FAILED
;
6146 change_query_max_response_time(pim_ifp
, query_max_response_time
);
6151 DEFUN (interface_no_ip_igmp_query_max_response_time
,
6152 interface_no_ip_igmp_query_max_response_time_cmd
,
6153 "no ip igmp query-max-response-time (10-250)",
6157 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
6158 "Time for response in deci-seconds\n")
6160 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6161 struct pim_interface
*pim_ifp
= ifp
->info
;
6166 change_query_max_response_time(pim_ifp
,
6167 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
6172 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
6173 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
6175 DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec
,
6176 interface_ip_igmp_query_max_response_time_dsec_cmd
,
6177 "ip igmp query-max-response-time-dsec (10-250)",
6180 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
6181 "Query response value in deciseconds\n")
6183 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6184 struct pim_interface
*pim_ifp
= ifp
->info
;
6185 int query_max_response_time_dsec
;
6186 int default_query_interval_dsec
;
6190 ret
= pim_cmd_igmp_start(vty
, ifp
);
6191 if (ret
!= CMD_SUCCESS
)
6193 pim_ifp
= ifp
->info
;
6196 query_max_response_time_dsec
= atoi(argv
[4]->arg
);
6198 default_query_interval_dsec
= 10 * pim_ifp
->igmp_default_query_interval
;
6200 if (query_max_response_time_dsec
>= default_query_interval_dsec
) {
6202 "Can't set query max response time %d dsec >= general query interval %d dsec\n",
6203 query_max_response_time_dsec
,
6204 default_query_interval_dsec
);
6205 return CMD_WARNING_CONFIG_FAILED
;
6208 change_query_max_response_time(pim_ifp
, query_max_response_time_dsec
);
6213 DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec
,
6214 interface_no_ip_igmp_query_max_response_time_dsec_cmd
,
6215 "no ip igmp query-max-response-time-dsec",
6219 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
)
6221 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6222 struct pim_interface
*pim_ifp
= ifp
->info
;
6227 change_query_max_response_time(pim_ifp
,
6228 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
6233 DEFUN (interface_ip_pim_drprio
,
6234 interface_ip_pim_drprio_cmd
,
6235 "ip pim drpriority (1-4294967295)",
6238 "Set the Designated Router Election Priority\n"
6239 "Value of the new DR Priority\n")
6241 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6243 struct pim_interface
*pim_ifp
= ifp
->info
;
6244 uint32_t old_dr_prio
;
6247 vty_out(vty
, "Please enable PIM on interface, first\n");
6248 return CMD_WARNING_CONFIG_FAILED
;
6251 old_dr_prio
= pim_ifp
->pim_dr_priority
;
6253 pim_ifp
->pim_dr_priority
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
6255 if (old_dr_prio
!= pim_ifp
->pim_dr_priority
) {
6256 if (pim_if_dr_election(ifp
))
6257 pim_hello_restart_now(ifp
);
6263 DEFUN (interface_no_ip_pim_drprio
,
6264 interface_no_ip_pim_drprio_cmd
,
6265 "no ip pim drpriority [(1-4294967295)]",
6269 "Revert the Designated Router Priority to default\n"
6270 "Old Value of the Priority\n")
6272 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6273 struct pim_interface
*pim_ifp
= ifp
->info
;
6276 vty_out(vty
, "Pim not enabled on this interface\n");
6277 return CMD_WARNING_CONFIG_FAILED
;
6280 if (pim_ifp
->pim_dr_priority
!= PIM_DEFAULT_DR_PRIORITY
) {
6281 pim_ifp
->pim_dr_priority
= PIM_DEFAULT_DR_PRIORITY
;
6282 if (pim_if_dr_election(ifp
))
6283 pim_hello_restart_now(ifp
);
6289 static int pim_cmd_interface_add(struct interface
*ifp
)
6291 struct pim_interface
*pim_ifp
= ifp
->info
;
6294 pim_ifp
= pim_if_new(ifp
, 0 /* igmp=false */, 1 /* pim=true */);
6299 PIM_IF_DO_PIM(pim_ifp
->options
);
6302 pim_if_addr_add_all(ifp
);
6303 pim_if_membership_refresh(ifp
);
6307 DEFUN_HIDDEN (interface_ip_pim_ssm
,
6308 interface_ip_pim_ssm_cmd
,
6314 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6316 if (!pim_cmd_interface_add(ifp
)) {
6317 vty_out(vty
, "Could not enable PIM SM on interface\n");
6318 return CMD_WARNING_CONFIG_FAILED
;
6322 "WARN: Enabled PIM SM on interface; configure PIM SSM "
6323 "range if needed\n");
6327 DEFUN (interface_ip_pim_sm
,
6328 interface_ip_pim_sm_cmd
,
6334 struct pim_interface
*pim_ifp
;
6336 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6337 if (!pim_cmd_interface_add(ifp
)) {
6338 vty_out(vty
, "Could not enable PIM SM on interface\n");
6339 return CMD_WARNING_CONFIG_FAILED
;
6342 pim_ifp
= ifp
->info
;
6344 pim_if_create_pimreg(pim_ifp
->pim
);
6349 static int pim_cmd_interface_delete(struct interface
*ifp
)
6351 struct pim_interface
*pim_ifp
= ifp
->info
;
6356 PIM_IF_DONT_PIM(pim_ifp
->options
);
6358 pim_if_membership_clear(ifp
);
6361 pim_sock_delete() removes all neighbors from
6362 pim_ifp->pim_neighbor_list.
6364 pim_sock_delete(ifp
, "pim unconfigured on interface");
6366 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
6367 pim_if_addr_del_all(ifp
);
6374 DEFUN_HIDDEN (interface_no_ip_pim_ssm
,
6375 interface_no_ip_pim_ssm_cmd
,
6382 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6383 if (!pim_cmd_interface_delete(ifp
)) {
6384 vty_out(vty
, "Unable to delete interface information\n");
6385 return CMD_WARNING_CONFIG_FAILED
;
6391 DEFUN (interface_no_ip_pim_sm
,
6392 interface_no_ip_pim_sm_cmd
,
6399 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6400 if (!pim_cmd_interface_delete(ifp
)) {
6401 vty_out(vty
, "Unable to delete interface information\n");
6402 return CMD_WARNING_CONFIG_FAILED
;
6409 DEFUN(interface_ip_pim_boundary_oil
,
6410 interface_ip_pim_boundary_oil_cmd
,
6411 "ip multicast boundary oil WORD",
6413 "Generic multicast configuration options\n"
6414 "Define multicast boundary\n"
6415 "Filter OIL by group using prefix list\n"
6416 "Prefix list to filter OIL with\n")
6418 VTY_DECLVAR_CONTEXT(interface
, iif
);
6419 struct pim_interface
*pim_ifp
;
6422 argv_find(argv
, argc
, "WORD", &idx
);
6424 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6426 if (pim_ifp
->boundary_oil_plist
)
6427 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
6429 pim_ifp
->boundary_oil_plist
=
6430 XSTRDUP(MTYPE_PIM_INTERFACE
, argv
[idx
]->arg
);
6432 /* Interface will be pruned from OIL on next Join */
6436 DEFUN(interface_no_ip_pim_boundary_oil
,
6437 interface_no_ip_pim_boundary_oil_cmd
,
6438 "no ip multicast boundary oil [WORD]",
6441 "Generic multicast configuration options\n"
6442 "Define multicast boundary\n"
6443 "Filter OIL by group using prefix list\n"
6444 "Prefix list to filter OIL with\n")
6446 VTY_DECLVAR_CONTEXT(interface
, iif
);
6447 struct pim_interface
*pim_ifp
;
6450 argv_find(argv
, argc
, "WORD", &idx
);
6452 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6454 if (pim_ifp
->boundary_oil_plist
)
6455 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
6460 DEFUN (interface_ip_mroute
,
6461 interface_ip_mroute_cmd
,
6462 "ip mroute INTERFACE A.B.C.D",
6464 "Add multicast route\n"
6465 "Outgoing interface name\n"
6468 VTY_DECLVAR_CONTEXT(interface
, iif
);
6469 struct pim_interface
*pim_ifp
;
6470 struct pim_instance
*pim
;
6471 int idx_interface
= 2;
6473 struct interface
*oif
;
6474 const char *oifname
;
6475 const char *grp_str
;
6476 struct in_addr grp_addr
;
6477 struct in_addr src_addr
;
6480 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6483 oifname
= argv
[idx_interface
]->arg
;
6484 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6486 vty_out(vty
, "No such interface name %s\n", oifname
);
6490 grp_str
= argv
[idx_ipv4
]->arg
;
6491 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6493 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6494 errno
, safe_strerror(errno
));
6498 src_addr
.s_addr
= INADDR_ANY
;
6500 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6501 vty_out(vty
, "Failed to add route\n");
6508 DEFUN (interface_ip_mroute_source
,
6509 interface_ip_mroute_source_cmd
,
6510 "ip mroute INTERFACE A.B.C.D A.B.C.D",
6512 "Add multicast route\n"
6513 "Outgoing interface name\n"
6517 VTY_DECLVAR_CONTEXT(interface
, iif
);
6518 struct pim_interface
*pim_ifp
;
6519 struct pim_instance
*pim
;
6520 int idx_interface
= 2;
6523 struct interface
*oif
;
6524 const char *oifname
;
6525 const char *grp_str
;
6526 struct in_addr grp_addr
;
6527 const char *src_str
;
6528 struct in_addr src_addr
;
6531 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6534 oifname
= argv
[idx_interface
]->arg
;
6535 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6537 vty_out(vty
, "No such interface name %s\n", oifname
);
6541 grp_str
= argv
[idx_ipv4
]->arg
;
6542 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6544 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6545 errno
, safe_strerror(errno
));
6549 src_str
= argv
[idx_ipv4_2
]->arg
;
6550 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
6552 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
6553 errno
, safe_strerror(errno
));
6557 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6558 vty_out(vty
, "Failed to add route\n");
6565 DEFUN (interface_no_ip_mroute
,
6566 interface_no_ip_mroute_cmd
,
6567 "no ip mroute INTERFACE A.B.C.D",
6570 "Add multicast route\n"
6571 "Outgoing interface name\n"
6574 VTY_DECLVAR_CONTEXT(interface
, iif
);
6575 struct pim_interface
*pim_ifp
;
6576 struct pim_instance
*pim
;
6577 int idx_interface
= 3;
6579 struct interface
*oif
;
6580 const char *oifname
;
6581 const char *grp_str
;
6582 struct in_addr grp_addr
;
6583 struct in_addr src_addr
;
6586 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6589 oifname
= argv
[idx_interface
]->arg
;
6590 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6592 vty_out(vty
, "No such interface name %s\n", oifname
);
6596 grp_str
= argv
[idx_ipv4
]->arg
;
6597 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6599 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6600 errno
, safe_strerror(errno
));
6604 src_addr
.s_addr
= INADDR_ANY
;
6606 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6607 vty_out(vty
, "Failed to remove route\n");
6614 DEFUN (interface_no_ip_mroute_source
,
6615 interface_no_ip_mroute_source_cmd
,
6616 "no ip mroute INTERFACE A.B.C.D A.B.C.D",
6619 "Add multicast route\n"
6620 "Outgoing interface name\n"
6624 VTY_DECLVAR_CONTEXT(interface
, iif
);
6625 struct pim_interface
*pim_ifp
;
6626 struct pim_instance
*pim
;
6627 int idx_interface
= 3;
6630 struct interface
*oif
;
6631 const char *oifname
;
6632 const char *grp_str
;
6633 struct in_addr grp_addr
;
6634 const char *src_str
;
6635 struct in_addr src_addr
;
6638 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6641 oifname
= argv
[idx_interface
]->arg
;
6642 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6644 vty_out(vty
, "No such interface name %s\n", oifname
);
6648 grp_str
= argv
[idx_ipv4
]->arg
;
6649 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6651 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6652 errno
, safe_strerror(errno
));
6656 src_str
= argv
[idx_ipv4_2
]->arg
;
6657 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
6659 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
6660 errno
, safe_strerror(errno
));
6664 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6665 vty_out(vty
, "Failed to remove route\n");
6672 DEFUN (interface_ip_pim_hello
,
6673 interface_ip_pim_hello_cmd
,
6674 "ip pim hello (1-180) [(1-180)]",
6678 IFACE_PIM_HELLO_TIME_STR
6679 IFACE_PIM_HELLO_HOLD_STR
)
6681 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6684 struct pim_interface
*pim_ifp
= ifp
->info
;
6687 if (!pim_cmd_interface_add(ifp
)) {
6688 vty_out(vty
, "Could not enable PIM SM on interface\n");
6689 return CMD_WARNING_CONFIG_FAILED
;
6693 pim_ifp
= ifp
->info
;
6694 pim_ifp
->pim_hello_period
= strtol(argv
[idx_time
]->arg
, NULL
, 10);
6696 if (argc
== idx_hold
+ 1)
6697 pim_ifp
->pim_default_holdtime
=
6698 strtol(argv
[idx_hold
]->arg
, NULL
, 10);
6703 DEFUN (interface_no_ip_pim_hello
,
6704 interface_no_ip_pim_hello_cmd
,
6705 "no ip pim hello [(1-180) (1-180)]",
6710 IFACE_PIM_HELLO_TIME_STR
6711 IFACE_PIM_HELLO_HOLD_STR
)
6713 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6714 struct pim_interface
*pim_ifp
= ifp
->info
;
6717 vty_out(vty
, "Pim not enabled on this interface\n");
6718 return CMD_WARNING_CONFIG_FAILED
;
6721 pim_ifp
->pim_hello_period
= PIM_DEFAULT_HELLO_PERIOD
;
6722 pim_ifp
->pim_default_holdtime
= -1;
6733 PIM_DO_DEBUG_IGMP_EVENTS
;
6734 PIM_DO_DEBUG_IGMP_PACKETS
;
6735 PIM_DO_DEBUG_IGMP_TRACE
;
6739 DEFUN (no_debug_igmp
,
6746 PIM_DONT_DEBUG_IGMP_EVENTS
;
6747 PIM_DONT_DEBUG_IGMP_PACKETS
;
6748 PIM_DONT_DEBUG_IGMP_TRACE
;
6753 DEFUN (debug_igmp_events
,
6754 debug_igmp_events_cmd
,
6755 "debug igmp events",
6758 DEBUG_IGMP_EVENTS_STR
)
6760 PIM_DO_DEBUG_IGMP_EVENTS
;
6764 DEFUN (no_debug_igmp_events
,
6765 no_debug_igmp_events_cmd
,
6766 "no debug igmp events",
6770 DEBUG_IGMP_EVENTS_STR
)
6772 PIM_DONT_DEBUG_IGMP_EVENTS
;
6777 DEFUN (debug_igmp_packets
,
6778 debug_igmp_packets_cmd
,
6779 "debug igmp packets",
6782 DEBUG_IGMP_PACKETS_STR
)
6784 PIM_DO_DEBUG_IGMP_PACKETS
;
6788 DEFUN (no_debug_igmp_packets
,
6789 no_debug_igmp_packets_cmd
,
6790 "no debug igmp packets",
6794 DEBUG_IGMP_PACKETS_STR
)
6796 PIM_DONT_DEBUG_IGMP_PACKETS
;
6801 DEFUN (debug_igmp_trace
,
6802 debug_igmp_trace_cmd
,
6806 DEBUG_IGMP_TRACE_STR
)
6808 PIM_DO_DEBUG_IGMP_TRACE
;
6812 DEFUN (no_debug_igmp_trace
,
6813 no_debug_igmp_trace_cmd
,
6814 "no debug igmp trace",
6818 DEBUG_IGMP_TRACE_STR
)
6820 PIM_DONT_DEBUG_IGMP_TRACE
;
6825 DEFUN (debug_mroute
,
6831 PIM_DO_DEBUG_MROUTE
;
6835 DEFUN (debug_mroute_detail
,
6836 debug_mroute_detail_cmd
,
6837 "debug mroute detail",
6842 PIM_DO_DEBUG_MROUTE_DETAIL
;
6846 DEFUN (no_debug_mroute
,
6847 no_debug_mroute_cmd
,
6853 PIM_DONT_DEBUG_MROUTE
;
6857 DEFUN (no_debug_mroute_detail
,
6858 no_debug_mroute_detail_cmd
,
6859 "no debug mroute detail",
6865 PIM_DONT_DEBUG_MROUTE_DETAIL
;
6869 DEFUN (debug_static
,
6875 PIM_DO_DEBUG_STATIC
;
6879 DEFUN (no_debug_static
,
6880 no_debug_static_cmd
,
6886 PIM_DONT_DEBUG_STATIC
;
6897 PIM_DO_DEBUG_PIM_EVENTS
;
6898 PIM_DO_DEBUG_PIM_PACKETS
;
6899 PIM_DO_DEBUG_PIM_TRACE
;
6900 PIM_DO_DEBUG_MSDP_EVENTS
;
6901 PIM_DO_DEBUG_MSDP_PACKETS
;
6905 DEFUN (no_debug_pim
,
6912 PIM_DONT_DEBUG_PIM_EVENTS
;
6913 PIM_DONT_DEBUG_PIM_PACKETS
;
6914 PIM_DONT_DEBUG_PIM_TRACE
;
6915 PIM_DONT_DEBUG_MSDP_EVENTS
;
6916 PIM_DONT_DEBUG_MSDP_PACKETS
;
6918 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
6919 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
6924 DEFUN (debug_pim_nht
,
6929 "Nexthop Tracking\n")
6931 PIM_DO_DEBUG_PIM_NHT
;
6935 DEFUN (no_debug_pim_nht
,
6936 no_debug_pim_nht_cmd
,
6941 "Nexthop Tracking\n")
6943 PIM_DONT_DEBUG_PIM_NHT
;
6947 DEFUN (debug_pim_nht_rp
,
6948 debug_pim_nht_rp_cmd
,
6952 "Nexthop Tracking\n"
6953 "RP Nexthop Tracking\n")
6955 PIM_DO_DEBUG_PIM_NHT_RP
;
6959 DEFUN (no_debug_pim_nht_rp
,
6960 no_debug_pim_nht_rp_cmd
,
6961 "no debug pim nht rp",
6965 "Nexthop Tracking\n"
6966 "RP Nexthop Tracking\n")
6968 PIM_DONT_DEBUG_PIM_NHT_RP
;
6972 DEFUN (debug_pim_events
,
6973 debug_pim_events_cmd
,
6977 DEBUG_PIM_EVENTS_STR
)
6979 PIM_DO_DEBUG_PIM_EVENTS
;
6983 DEFUN (no_debug_pim_events
,
6984 no_debug_pim_events_cmd
,
6985 "no debug pim events",
6989 DEBUG_PIM_EVENTS_STR
)
6991 PIM_DONT_DEBUG_PIM_EVENTS
;
6995 DEFUN (debug_pim_packets
,
6996 debug_pim_packets_cmd
,
6997 "debug pim packets [<hello|joins|register>]",
7000 DEBUG_PIM_PACKETS_STR
7001 DEBUG_PIM_HELLO_PACKETS_STR
7002 DEBUG_PIM_J_P_PACKETS_STR
7003 DEBUG_PIM_PIM_REG_PACKETS_STR
)
7006 if (argv_find(argv
, argc
, "hello", &idx
)) {
7007 PIM_DO_DEBUG_PIM_HELLO
;
7008 vty_out(vty
, "PIM Hello debugging is on\n");
7009 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
7010 PIM_DO_DEBUG_PIM_J_P
;
7011 vty_out(vty
, "PIM Join/Prune debugging is on\n");
7012 } else if (argv_find(argv
, argc
, "register", &idx
)) {
7013 PIM_DO_DEBUG_PIM_REG
;
7014 vty_out(vty
, "PIM Register debugging is on\n");
7016 PIM_DO_DEBUG_PIM_PACKETS
;
7017 vty_out(vty
, "PIM Packet debugging is on \n");
7022 DEFUN (no_debug_pim_packets
,
7023 no_debug_pim_packets_cmd
,
7024 "no debug pim packets [<hello|joins|register>]",
7028 DEBUG_PIM_PACKETS_STR
7029 DEBUG_PIM_HELLO_PACKETS_STR
7030 DEBUG_PIM_J_P_PACKETS_STR
7031 DEBUG_PIM_PIM_REG_PACKETS_STR
)
7034 if (argv_find(argv
, argc
, "hello", &idx
)) {
7035 PIM_DONT_DEBUG_PIM_HELLO
;
7036 vty_out(vty
, "PIM Hello debugging is off \n");
7037 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
7038 PIM_DONT_DEBUG_PIM_J_P
;
7039 vty_out(vty
, "PIM Join/Prune debugging is off \n");
7040 } else if (argv_find(argv
, argc
, "register", &idx
)) {
7041 PIM_DONT_DEBUG_PIM_REG
;
7042 vty_out(vty
, "PIM Register debugging is off\n");
7044 PIM_DONT_DEBUG_PIM_PACKETS
;
7050 DEFUN (debug_pim_packetdump_send
,
7051 debug_pim_packetdump_send_cmd
,
7052 "debug pim packet-dump send",
7055 DEBUG_PIM_PACKETDUMP_STR
7056 DEBUG_PIM_PACKETDUMP_SEND_STR
)
7058 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND
;
7062 DEFUN (no_debug_pim_packetdump_send
,
7063 no_debug_pim_packetdump_send_cmd
,
7064 "no debug pim packet-dump send",
7068 DEBUG_PIM_PACKETDUMP_STR
7069 DEBUG_PIM_PACKETDUMP_SEND_STR
)
7071 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
7075 DEFUN (debug_pim_packetdump_recv
,
7076 debug_pim_packetdump_recv_cmd
,
7077 "debug pim packet-dump receive",
7080 DEBUG_PIM_PACKETDUMP_STR
7081 DEBUG_PIM_PACKETDUMP_RECV_STR
)
7083 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV
;
7087 DEFUN (no_debug_pim_packetdump_recv
,
7088 no_debug_pim_packetdump_recv_cmd
,
7089 "no debug pim packet-dump receive",
7093 DEBUG_PIM_PACKETDUMP_STR
7094 DEBUG_PIM_PACKETDUMP_RECV_STR
)
7096 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
7100 DEFUN (debug_pim_trace
,
7101 debug_pim_trace_cmd
,
7105 DEBUG_PIM_TRACE_STR
)
7107 PIM_DO_DEBUG_PIM_TRACE
;
7111 DEFUN (debug_pim_trace_detail
,
7112 debug_pim_trace_detail_cmd
,
7113 "debug pim trace detail",
7117 "Detailed Information\n")
7119 PIM_DO_DEBUG_PIM_TRACE_DETAIL
;
7123 DEFUN (no_debug_pim_trace
,
7124 no_debug_pim_trace_cmd
,
7125 "no debug pim trace",
7129 DEBUG_PIM_TRACE_STR
)
7131 PIM_DONT_DEBUG_PIM_TRACE
;
7135 DEFUN (no_debug_pim_trace_detail
,
7136 no_debug_pim_trace_detail_cmd
,
7137 "no debug pim trace detail",
7142 "Detailed Information\n")
7144 PIM_DONT_DEBUG_PIM_TRACE_DETAIL
;
7148 DEFUN (debug_ssmpingd
,
7154 PIM_DO_DEBUG_SSMPINGD
;
7158 DEFUN (no_debug_ssmpingd
,
7159 no_debug_ssmpingd_cmd
,
7160 "no debug ssmpingd",
7165 PIM_DONT_DEBUG_SSMPINGD
;
7169 DEFUN (debug_pim_zebra
,
7170 debug_pim_zebra_cmd
,
7174 DEBUG_PIM_ZEBRA_STR
)
7180 DEFUN (no_debug_pim_zebra
,
7181 no_debug_pim_zebra_cmd
,
7182 "no debug pim zebra",
7186 DEBUG_PIM_ZEBRA_STR
)
7188 PIM_DONT_DEBUG_ZEBRA
;
7198 PIM_DO_DEBUG_MSDP_EVENTS
;
7199 PIM_DO_DEBUG_MSDP_PACKETS
;
7203 DEFUN (no_debug_msdp
,
7210 PIM_DONT_DEBUG_MSDP_EVENTS
;
7211 PIM_DONT_DEBUG_MSDP_PACKETS
;
7215 ALIAS(no_debug_msdp
, undebug_msdp_cmd
, "undebug msdp",
7216 UNDEBUG_STR DEBUG_MSDP_STR
)
7218 DEFUN (debug_msdp_events
,
7219 debug_msdp_events_cmd
,
7220 "debug msdp events",
7223 DEBUG_MSDP_EVENTS_STR
)
7225 PIM_DO_DEBUG_MSDP_EVENTS
;
7229 DEFUN (no_debug_msdp_events
,
7230 no_debug_msdp_events_cmd
,
7231 "no debug msdp events",
7235 DEBUG_MSDP_EVENTS_STR
)
7237 PIM_DONT_DEBUG_MSDP_EVENTS
;
7241 ALIAS(no_debug_msdp_events
, undebug_msdp_events_cmd
, "undebug msdp events",
7242 UNDEBUG_STR DEBUG_MSDP_STR DEBUG_MSDP_EVENTS_STR
)
7244 DEFUN (debug_msdp_packets
,
7245 debug_msdp_packets_cmd
,
7246 "debug msdp packets",
7249 DEBUG_MSDP_PACKETS_STR
)
7251 PIM_DO_DEBUG_MSDP_PACKETS
;
7255 DEFUN (no_debug_msdp_packets
,
7256 no_debug_msdp_packets_cmd
,
7257 "no debug msdp packets",
7261 DEBUG_MSDP_PACKETS_STR
)
7263 PIM_DONT_DEBUG_MSDP_PACKETS
;
7267 ALIAS(no_debug_msdp_packets
, undebug_msdp_packets_cmd
, "undebug msdp packets",
7268 UNDEBUG_STR DEBUG_MSDP_STR DEBUG_MSDP_PACKETS_STR
)
7270 DEFUN (debug_mtrace
,
7276 PIM_DO_DEBUG_MTRACE
;
7280 DEFUN (no_debug_mtrace
,
7281 no_debug_mtrace_cmd
,
7287 PIM_DONT_DEBUG_MTRACE
;
7291 DEFUN_NOSH (show_debugging_pim
,
7292 show_debugging_pim_cmd
,
7293 "show debugging [pim]",
7298 vty_out(vty
, "PIM debugging status\n");
7300 pim_debug_config_write(vty
);
7305 static int interface_pim_use_src_cmd_worker(struct vty
*vty
, const char *source
)
7308 struct in_addr source_addr
;
7309 int ret
= CMD_SUCCESS
;
7310 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7312 result
= inet_pton(AF_INET
, source
, &source_addr
);
7314 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", source
,
7315 errno
, safe_strerror(errno
));
7316 return CMD_WARNING_CONFIG_FAILED
;
7319 result
= pim_update_source_set(ifp
, source_addr
);
7323 case PIM_IFACE_NOT_FOUND
:
7324 ret
= CMD_WARNING_CONFIG_FAILED
;
7325 vty_out(vty
, "Pim not enabled on this interface\n");
7327 case PIM_UPDATE_SOURCE_DUP
:
7329 vty_out(vty
, "%% Source already set to %s\n", source
);
7332 ret
= CMD_WARNING_CONFIG_FAILED
;
7333 vty_out(vty
, "%% Source set failed\n");
7339 DEFUN (interface_pim_use_source
,
7340 interface_pim_use_source_cmd
,
7341 "ip pim use-source A.B.C.D",
7343 "pim multicast routing\n"
7344 "Configure primary IP address\n"
7345 "source ip address\n")
7347 return interface_pim_use_src_cmd_worker(vty
, argv
[3]->arg
);
7350 DEFUN (interface_no_pim_use_source
,
7351 interface_no_pim_use_source_cmd
,
7352 "no ip pim use-source [A.B.C.D]",
7355 "pim multicast routing\n"
7356 "Delete source IP address\n"
7357 "source ip address\n")
7359 return interface_pim_use_src_cmd_worker(vty
, "0.0.0.0");
7367 "Enables BFD support\n")
7369 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7370 struct pim_interface
*pim_ifp
= ifp
->info
;
7371 struct bfd_info
*bfd_info
= NULL
;
7374 if (!pim_cmd_interface_add(ifp
)) {
7375 vty_out(vty
, "Could not enable PIM SM on interface\n");
7379 pim_ifp
= ifp
->info
;
7381 bfd_info
= pim_ifp
->bfd_info
;
7383 if (!bfd_info
|| !CHECK_FLAG(bfd_info
->flags
, BFD_FLAG_PARAM_CFG
))
7384 pim_bfd_if_param_set(ifp
, BFD_DEF_MIN_RX
, BFD_DEF_MIN_TX
,
7385 BFD_DEF_DETECT_MULT
, 1);
7390 DEFUN (no_ip_pim_bfd
,
7396 "Disables BFD support\n")
7398 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7399 struct pim_interface
*pim_ifp
= ifp
->info
;
7402 vty_out(vty
, "Pim not enabled on this interface\n");
7406 if (pim_ifp
->bfd_info
) {
7407 pim_bfd_reg_dereg_all_nbr(ifp
, ZEBRA_BFD_DEST_DEREGISTER
);
7408 bfd_info_free(&(pim_ifp
->bfd_info
));
7414 DEFUN (ip_pim_bfd_param
,
7415 ip_pim_bfd_param_cmd
,
7416 "ip pim bfd (2-255) (50-60000) (50-60000)",
7419 "Enables BFD support\n"
7420 "Detect Multiplier\n"
7421 "Required min receive interval\n"
7422 "Desired min transmit interval\n")
7424 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7426 int idx_number_2
= 4;
7427 int idx_number_3
= 5;
7432 struct pim_interface
*pim_ifp
= ifp
->info
;
7435 if (!pim_cmd_interface_add(ifp
)) {
7436 vty_out(vty
, "Could not enable PIM SM on interface\n");
7441 if ((ret
= bfd_validate_param(
7442 vty
, argv
[idx_number
]->arg
, argv
[idx_number_2
]->arg
,
7443 argv
[idx_number_3
]->arg
, &dm_val
, &rx_val
, &tx_val
))
7447 pim_bfd_if_param_set(ifp
, rx_val
, tx_val
, dm_val
, 0);
7452 ALIAS(no_ip_pim_bfd
, no_ip_pim_bfd_param_cmd
,
7453 "no ip pim bfd (2-255) (50-60000) (50-60000)", NO_STR IP_STR PIM_STR
7454 "Enables BFD support\n"
7455 "Detect Multiplier\n"
7456 "Required min receive interval\n"
7457 "Desired min transmit interval\n")
7459 static int ip_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
7460 const char *peer
, const char *local
)
7462 enum pim_msdp_err result
;
7463 struct in_addr peer_addr
;
7464 struct in_addr local_addr
;
7465 int ret
= CMD_SUCCESS
;
7467 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
7469 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
7470 errno
, safe_strerror(errno
));
7471 return CMD_WARNING_CONFIG_FAILED
;
7474 result
= inet_pton(AF_INET
, local
, &local_addr
);
7476 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", local
,
7477 errno
, safe_strerror(errno
));
7478 return CMD_WARNING_CONFIG_FAILED
;
7481 result
= pim_msdp_peer_add(pim
, peer_addr
, local_addr
, "default",
7484 case PIM_MSDP_ERR_NONE
:
7486 case PIM_MSDP_ERR_OOM
:
7487 ret
= CMD_WARNING_CONFIG_FAILED
;
7488 vty_out(vty
, "%% Out of memory\n");
7490 case PIM_MSDP_ERR_PEER_EXISTS
:
7492 vty_out(vty
, "%% Peer exists\n");
7494 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
7495 ret
= CMD_WARNING_CONFIG_FAILED
;
7496 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
7499 ret
= CMD_WARNING_CONFIG_FAILED
;
7500 vty_out(vty
, "%% peer add failed\n");
7506 DEFUN_HIDDEN (ip_msdp_peer
,
7508 "ip msdp peer A.B.C.D source A.B.C.D",
7511 "Configure MSDP peer\n"
7513 "Source address for TCP connection\n"
7514 "local ip address\n")
7516 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7517 return ip_msdp_peer_cmd_worker(pim
, vty
, argv
[3]->arg
, argv
[5]->arg
);
7520 static int ip_no_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
7523 enum pim_msdp_err result
;
7524 struct in_addr peer_addr
;
7526 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
7528 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
7529 errno
, safe_strerror(errno
));
7530 return CMD_WARNING_CONFIG_FAILED
;
7533 result
= pim_msdp_peer_del(pim
, peer_addr
);
7535 case PIM_MSDP_ERR_NONE
:
7537 case PIM_MSDP_ERR_NO_PEER
:
7538 vty_out(vty
, "%% Peer does not exist\n");
7541 vty_out(vty
, "%% peer del failed\n");
7544 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7547 DEFUN_HIDDEN (no_ip_msdp_peer
,
7548 no_ip_msdp_peer_cmd
,
7549 "no ip msdp peer A.B.C.D",
7553 "Delete MSDP peer\n"
7554 "peer ip address\n")
7556 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7557 return ip_no_msdp_peer_cmd_worker(pim
, vty
, argv
[4]->arg
);
7560 static int ip_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
7561 struct vty
*vty
, const char *mg
,
7564 enum pim_msdp_err result
;
7565 struct in_addr mbr_ip
;
7566 int ret
= CMD_SUCCESS
;
7568 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
7570 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
7571 errno
, safe_strerror(errno
));
7572 return CMD_WARNING_CONFIG_FAILED
;
7575 result
= pim_msdp_mg_mbr_add(pim
, mg
, mbr_ip
);
7577 case PIM_MSDP_ERR_NONE
:
7579 case PIM_MSDP_ERR_OOM
:
7580 ret
= CMD_WARNING_CONFIG_FAILED
;
7581 vty_out(vty
, "%% Out of memory\n");
7583 case PIM_MSDP_ERR_MG_MBR_EXISTS
:
7585 vty_out(vty
, "%% mesh-group member exists\n");
7587 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
7588 ret
= CMD_WARNING_CONFIG_FAILED
;
7589 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
7592 ret
= CMD_WARNING_CONFIG_FAILED
;
7593 vty_out(vty
, "%% member add failed\n");
7599 DEFUN (ip_msdp_mesh_group_member
,
7600 ip_msdp_mesh_group_member_cmd
,
7601 "ip msdp mesh-group WORD member A.B.C.D",
7604 "Configure MSDP mesh-group\n"
7606 "mesh group member\n"
7607 "peer ip address\n")
7609 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7610 return ip_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[3]->arg
,
7614 static int ip_no_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
7619 enum pim_msdp_err result
;
7620 struct in_addr mbr_ip
;
7622 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
7624 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
7625 errno
, safe_strerror(errno
));
7626 return CMD_WARNING_CONFIG_FAILED
;
7629 result
= pim_msdp_mg_mbr_del(pim
, mg
, mbr_ip
);
7631 case PIM_MSDP_ERR_NONE
:
7633 case PIM_MSDP_ERR_NO_MG
:
7634 vty_out(vty
, "%% mesh-group does not exist\n");
7636 case PIM_MSDP_ERR_NO_MG_MBR
:
7637 vty_out(vty
, "%% mesh-group member does not exist\n");
7640 vty_out(vty
, "%% mesh-group member del failed\n");
7643 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7645 DEFUN (no_ip_msdp_mesh_group_member
,
7646 no_ip_msdp_mesh_group_member_cmd
,
7647 "no ip msdp mesh-group WORD member A.B.C.D",
7651 "Delete MSDP mesh-group member\n"
7653 "mesh group member\n"
7654 "peer ip address\n")
7656 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7657 return ip_no_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[4]->arg
,
7661 static int ip_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
7662 struct vty
*vty
, const char *mg
,
7665 enum pim_msdp_err result
;
7666 struct in_addr src_ip
;
7668 result
= inet_pton(AF_INET
, src
, &src_ip
);
7670 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", src
,
7671 errno
, safe_strerror(errno
));
7672 return CMD_WARNING_CONFIG_FAILED
;
7675 result
= pim_msdp_mg_src_add(pim
, mg
, src_ip
);
7677 case PIM_MSDP_ERR_NONE
:
7679 case PIM_MSDP_ERR_OOM
:
7680 vty_out(vty
, "%% Out of memory\n");
7682 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
7683 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
7686 vty_out(vty
, "%% source add failed\n");
7689 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7693 DEFUN (ip_msdp_mesh_group_source
,
7694 ip_msdp_mesh_group_source_cmd
,
7695 "ip msdp mesh-group WORD source A.B.C.D",
7698 "Configure MSDP mesh-group\n"
7700 "mesh group local address\n"
7701 "source ip address for the TCP connection\n")
7703 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7704 return ip_msdp_mesh_group_source_cmd_worker(pim
, vty
, argv
[3]->arg
,
7708 static int ip_no_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
7712 enum pim_msdp_err result
;
7714 result
= pim_msdp_mg_src_del(pim
, mg
);
7716 case PIM_MSDP_ERR_NONE
:
7718 case PIM_MSDP_ERR_NO_MG
:
7719 vty_out(vty
, "%% mesh-group does not exist\n");
7722 vty_out(vty
, "%% mesh-group source del failed\n");
7725 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7728 static int ip_no_msdp_mesh_group_cmd_worker(struct pim_instance
*pim
,
7729 struct vty
*vty
, const char *mg
)
7731 enum pim_msdp_err result
;
7733 result
= pim_msdp_mg_del(pim
, mg
);
7735 case PIM_MSDP_ERR_NONE
:
7737 case PIM_MSDP_ERR_NO_MG
:
7738 vty_out(vty
, "%% mesh-group does not exist\n");
7741 vty_out(vty
, "%% mesh-group source del failed\n");
7744 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7747 DEFUN (no_ip_msdp_mesh_group_source
,
7748 no_ip_msdp_mesh_group_source_cmd
,
7749 "no ip msdp mesh-group WORD source [A.B.C.D]",
7753 "Delete MSDP mesh-group source\n"
7755 "mesh group source\n"
7756 "mesh group local address\n")
7758 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7760 return ip_no_msdp_mesh_group_cmd_worker(pim
, vty
, argv
[6]->arg
);
7762 return ip_no_msdp_mesh_group_source_cmd_worker(pim
, vty
,
7766 static void print_empty_json_obj(struct vty
*vty
)
7769 json
= json_object_new_object();
7770 vty_out(vty
, "%s\n",
7771 json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
));
7772 json_object_free(json
);
7775 static void ip_msdp_show_mesh_group(struct pim_instance
*pim
, struct vty
*vty
,
7778 struct listnode
*mbrnode
;
7779 struct pim_msdp_mg_mbr
*mbr
;
7780 struct pim_msdp_mg
*mg
= pim
->msdp
.mg
;
7781 char mbr_str
[INET_ADDRSTRLEN
];
7782 char src_str
[INET_ADDRSTRLEN
];
7783 char state_str
[PIM_MSDP_STATE_STRLEN
];
7784 enum pim_msdp_peer_state state
;
7785 json_object
*json
= NULL
;
7786 json_object
*json_mg_row
= NULL
;
7787 json_object
*json_members
= NULL
;
7788 json_object
*json_row
= NULL
;
7792 print_empty_json_obj(vty
);
7796 pim_inet4_dump("<source?>", mg
->src_ip
, src_str
, sizeof(src_str
));
7798 json
= json_object_new_object();
7799 /* currently there is only one mesh group but we should still
7801 * it a dict with mg-name as key */
7802 json_mg_row
= json_object_new_object();
7803 json_object_string_add(json_mg_row
, "name",
7804 mg
->mesh_group_name
);
7805 json_object_string_add(json_mg_row
, "source", src_str
);
7807 vty_out(vty
, "Mesh group : %s\n", mg
->mesh_group_name
);
7808 vty_out(vty
, " Source : %s\n", src_str
);
7809 vty_out(vty
, " Member State\n");
7812 for (ALL_LIST_ELEMENTS_RO(mg
->mbr_list
, mbrnode
, mbr
)) {
7813 pim_inet4_dump("<mbr?>", mbr
->mbr_ip
, mbr_str
, sizeof(mbr_str
));
7815 state
= mbr
->mp
->state
;
7817 state
= PIM_MSDP_DISABLED
;
7819 pim_msdp_state_dump(state
, state_str
, sizeof(state_str
));
7821 json_row
= json_object_new_object();
7822 json_object_string_add(json_row
, "member", mbr_str
);
7823 json_object_string_add(json_row
, "state", state_str
);
7824 if (!json_members
) {
7825 json_members
= json_object_new_object();
7826 json_object_object_add(json_mg_row
, "members",
7829 json_object_object_add(json_members
, mbr_str
, json_row
);
7831 vty_out(vty
, " %-15s %11s\n", mbr_str
, state_str
);
7836 json_object_object_add(json
, mg
->mesh_group_name
, json_mg_row
);
7837 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
7838 json
, JSON_C_TO_STRING_PRETTY
));
7839 json_object_free(json
);
7843 DEFUN (show_ip_msdp_mesh_group
,
7844 show_ip_msdp_mesh_group_cmd
,
7845 "show ip msdp [vrf NAME] mesh-group [json]",
7850 "MSDP mesh-group information\n"
7853 u_char uj
= use_json(argc
, argv
);
7855 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
7860 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
7865 DEFUN (show_ip_msdp_mesh_group_vrf_all
,
7866 show_ip_msdp_mesh_group_vrf_all_cmd
,
7867 "show ip msdp vrf all mesh-group [json]",
7872 "MSDP mesh-group information\n"
7875 u_char uj
= use_json(argc
, argv
);
7881 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
7885 vty_out(vty
, " \"%s\": ", vrf
->name
);
7888 vty_out(vty
, "VRF: %s\n", vrf
->name
);
7889 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
7892 vty_out(vty
, "}\n");
7897 static void ip_msdp_show_peers(struct pim_instance
*pim
, struct vty
*vty
,
7900 struct listnode
*mpnode
;
7901 struct pim_msdp_peer
*mp
;
7902 char peer_str
[INET_ADDRSTRLEN
];
7903 char local_str
[INET_ADDRSTRLEN
];
7904 char state_str
[PIM_MSDP_STATE_STRLEN
];
7905 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
7907 json_object
*json
= NULL
;
7908 json_object
*json_row
= NULL
;
7912 json
= json_object_new_object();
7915 "Peer Local State Uptime SaCnt\n");
7918 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
7919 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
7920 now
= pim_time_monotonic_sec();
7921 pim_time_uptime(timebuf
, sizeof(timebuf
),
7924 strcpy(timebuf
, "-");
7926 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
7927 pim_inet4_dump("<local?>", mp
->local
, local_str
,
7929 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
7931 json_row
= json_object_new_object();
7932 json_object_string_add(json_row
, "peer", peer_str
);
7933 json_object_string_add(json_row
, "local", local_str
);
7934 json_object_string_add(json_row
, "state", state_str
);
7935 json_object_string_add(json_row
, "upTime", timebuf
);
7936 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
7937 json_object_object_add(json
, peer_str
, json_row
);
7939 vty_out(vty
, "%-15s %15s %11s %8s %6d\n", peer_str
,
7940 local_str
, state_str
, timebuf
, mp
->sa_cnt
);
7945 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
7946 json
, JSON_C_TO_STRING_PRETTY
));
7947 json_object_free(json
);
7951 static void ip_msdp_show_peers_detail(struct pim_instance
*pim
, struct vty
*vty
,
7952 const char *peer
, u_char uj
)
7954 struct listnode
*mpnode
;
7955 struct pim_msdp_peer
*mp
;
7956 char peer_str
[INET_ADDRSTRLEN
];
7957 char local_str
[INET_ADDRSTRLEN
];
7958 char state_str
[PIM_MSDP_STATE_STRLEN
];
7959 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
7960 char katimer
[PIM_MSDP_TIMER_STRLEN
];
7961 char crtimer
[PIM_MSDP_TIMER_STRLEN
];
7962 char holdtimer
[PIM_MSDP_TIMER_STRLEN
];
7964 json_object
*json
= NULL
;
7965 json_object
*json_row
= NULL
;
7968 json
= json_object_new_object();
7971 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
7972 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
7973 if (strcmp(peer
, "detail") && strcmp(peer
, peer_str
))
7976 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
7977 now
= pim_time_monotonic_sec();
7978 pim_time_uptime(timebuf
, sizeof(timebuf
),
7981 strcpy(timebuf
, "-");
7983 pim_inet4_dump("<local?>", mp
->local
, local_str
,
7985 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
7986 pim_time_timer_to_hhmmss(katimer
, sizeof(katimer
),
7988 pim_time_timer_to_hhmmss(crtimer
, sizeof(crtimer
),
7990 pim_time_timer_to_hhmmss(holdtimer
, sizeof(holdtimer
),
7994 json_row
= json_object_new_object();
7995 json_object_string_add(json_row
, "peer", peer_str
);
7996 json_object_string_add(json_row
, "local", local_str
);
7997 json_object_string_add(json_row
, "meshGroupName",
7998 mp
->mesh_group_name
);
7999 json_object_string_add(json_row
, "state", state_str
);
8000 json_object_string_add(json_row
, "upTime", timebuf
);
8001 json_object_string_add(json_row
, "keepAliveTimer",
8003 json_object_string_add(json_row
, "connRetryTimer",
8005 json_object_string_add(json_row
, "holdTimer",
8007 json_object_string_add(json_row
, "lastReset",
8009 json_object_int_add(json_row
, "connAttempts",
8011 json_object_int_add(json_row
, "establishedChanges",
8013 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
8014 json_object_int_add(json_row
, "kaSent", mp
->ka_tx_cnt
);
8015 json_object_int_add(json_row
, "kaRcvd", mp
->ka_rx_cnt
);
8016 json_object_int_add(json_row
, "saSent", mp
->sa_tx_cnt
);
8017 json_object_int_add(json_row
, "saRcvd", mp
->sa_rx_cnt
);
8018 json_object_object_add(json
, peer_str
, json_row
);
8020 vty_out(vty
, "Peer : %s\n", peer_str
);
8021 vty_out(vty
, " Local : %s\n", local_str
);
8022 vty_out(vty
, " Mesh Group : %s\n",
8023 mp
->mesh_group_name
);
8024 vty_out(vty
, " State : %s\n", state_str
);
8025 vty_out(vty
, " Uptime : %s\n", timebuf
);
8027 vty_out(vty
, " Keepalive Timer : %s\n", katimer
);
8028 vty_out(vty
, " Conn Retry Timer : %s\n", crtimer
);
8029 vty_out(vty
, " Hold Timer : %s\n", holdtimer
);
8030 vty_out(vty
, " Last Reset : %s\n",
8032 vty_out(vty
, " Conn Attempts : %d\n",
8034 vty_out(vty
, " Established Changes : %d\n",
8036 vty_out(vty
, " SA Count : %d\n",
8038 vty_out(vty
, " Statistics :\n");
8041 vty_out(vty
, " Keepalives : %10d %10d\n",
8042 mp
->ka_tx_cnt
, mp
->ka_rx_cnt
);
8043 vty_out(vty
, " SAs : %10d %10d\n",
8044 mp
->sa_tx_cnt
, mp
->sa_rx_cnt
);
8050 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8051 json
, JSON_C_TO_STRING_PRETTY
));
8052 json_object_free(json
);
8056 DEFUN (show_ip_msdp_peer_detail
,
8057 show_ip_msdp_peer_detail_cmd
,
8058 "show ip msdp [vrf NAME] peer [detail|A.B.C.D] [json]",
8063 "MSDP peer information\n"
8068 u_char uj
= use_json(argc
, argv
);
8070 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
8077 if (argv_find(argv
, argc
, "detail", &idx
))
8078 arg
= argv
[idx
]->text
;
8079 else if (argv_find(argv
, argc
, "A.B.C.D", &idx
))
8080 arg
= argv
[idx
]->arg
;
8083 ip_msdp_show_peers_detail(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
8085 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
8090 DEFUN (show_ip_msdp_peer_detail_vrf_all
,
8091 show_ip_msdp_peer_detail_vrf_all_cmd
,
8092 "show ip msdp vrf all peer [detail|A.B.C.D] [json]",
8097 "MSDP peer information\n"
8103 u_char uj
= use_json(argc
, argv
);
8109 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
8113 vty_out(vty
, " \"%s\": ", vrf
->name
);
8116 vty_out(vty
, "VRF: %s\n", vrf
->name
);
8117 if (argv_find(argv
, argc
, "detail", &idx
)
8118 || argv_find(argv
, argc
, "A.B.C.D", &idx
))
8119 ip_msdp_show_peers_detail(vrf
->info
, vty
,
8120 argv
[idx
]->arg
, uj
);
8122 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
8125 vty_out(vty
, "}\n");
8130 static void ip_msdp_show_sa(struct pim_instance
*pim
, struct vty
*vty
,
8133 struct listnode
*sanode
;
8134 struct pim_msdp_sa
*sa
;
8135 char src_str
[INET_ADDRSTRLEN
];
8136 char grp_str
[INET_ADDRSTRLEN
];
8137 char rp_str
[INET_ADDRSTRLEN
];
8138 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
8142 json_object
*json
= NULL
;
8143 json_object
*json_group
= NULL
;
8144 json_object
*json_row
= NULL
;
8147 json
= json_object_new_object();
8150 "Source Group RP Local SPT Uptime\n");
8153 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
8154 now
= pim_time_monotonic_sec();
8155 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
8156 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
8157 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
8158 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
8159 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
8161 strcpy(spt_str
, "yes");
8163 strcpy(spt_str
, "no");
8166 strcpy(rp_str
, "-");
8167 strcpy(spt_str
, "-");
8169 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
8170 strcpy(local_str
, "yes");
8172 strcpy(local_str
, "no");
8175 json_object_object_get_ex(json
, grp_str
, &json_group
);
8178 json_group
= json_object_new_object();
8179 json_object_object_add(json
, grp_str
,
8183 json_row
= json_object_new_object();
8184 json_object_string_add(json_row
, "source", src_str
);
8185 json_object_string_add(json_row
, "group", grp_str
);
8186 json_object_string_add(json_row
, "rp", rp_str
);
8187 json_object_string_add(json_row
, "local", local_str
);
8188 json_object_string_add(json_row
, "sptSetup", spt_str
);
8189 json_object_string_add(json_row
, "upTime", timebuf
);
8190 json_object_object_add(json_group
, src_str
, json_row
);
8192 vty_out(vty
, "%-15s %15s %15s %5c %3c %8s\n",
8193 src_str
, grp_str
, rp_str
, local_str
[0],
8194 spt_str
[0], timebuf
);
8199 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8200 json
, JSON_C_TO_STRING_PRETTY
));
8201 json_object_free(json
);
8205 static void ip_msdp_show_sa_entry_detail(struct pim_msdp_sa
*sa
,
8206 const char *src_str
,
8207 const char *grp_str
, struct vty
*vty
,
8208 u_char uj
, json_object
*json
)
8210 char rp_str
[INET_ADDRSTRLEN
];
8211 char peer_str
[INET_ADDRSTRLEN
];
8212 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
8215 char statetimer
[PIM_MSDP_TIMER_STRLEN
];
8217 json_object
*json_group
= NULL
;
8218 json_object
*json_row
= NULL
;
8220 now
= pim_time_monotonic_sec();
8221 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
8222 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
8223 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
8224 pim_inet4_dump("<peer?>", sa
->peer
, peer_str
, sizeof(peer_str
));
8226 strcpy(spt_str
, "yes");
8228 strcpy(spt_str
, "no");
8231 strcpy(rp_str
, "-");
8232 strcpy(peer_str
, "-");
8233 strcpy(spt_str
, "-");
8235 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
8236 strcpy(local_str
, "yes");
8238 strcpy(local_str
, "no");
8240 pim_time_timer_to_hhmmss(statetimer
, sizeof(statetimer
),
8241 sa
->sa_state_timer
);
8243 json_object_object_get_ex(json
, grp_str
, &json_group
);
8246 json_group
= json_object_new_object();
8247 json_object_object_add(json
, grp_str
, json_group
);
8250 json_row
= json_object_new_object();
8251 json_object_string_add(json_row
, "source", src_str
);
8252 json_object_string_add(json_row
, "group", grp_str
);
8253 json_object_string_add(json_row
, "rp", rp_str
);
8254 json_object_string_add(json_row
, "local", local_str
);
8255 json_object_string_add(json_row
, "sptSetup", spt_str
);
8256 json_object_string_add(json_row
, "upTime", timebuf
);
8257 json_object_string_add(json_row
, "stateTimer", statetimer
);
8258 json_object_object_add(json_group
, src_str
, json_row
);
8260 vty_out(vty
, "SA : %s\n", sa
->sg_str
);
8261 vty_out(vty
, " RP : %s\n", rp_str
);
8262 vty_out(vty
, " Peer : %s\n", peer_str
);
8263 vty_out(vty
, " Local : %s\n", local_str
);
8264 vty_out(vty
, " SPT Setup : %s\n", spt_str
);
8265 vty_out(vty
, " Uptime : %s\n", timebuf
);
8266 vty_out(vty
, " State Timer : %s\n", statetimer
);
8271 static void ip_msdp_show_sa_detail(struct pim_instance
*pim
, struct vty
*vty
,
8274 struct listnode
*sanode
;
8275 struct pim_msdp_sa
*sa
;
8276 char src_str
[INET_ADDRSTRLEN
];
8277 char grp_str
[INET_ADDRSTRLEN
];
8278 json_object
*json
= NULL
;
8281 json
= json_object_new_object();
8284 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
8285 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
8286 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
8287 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
, uj
,
8292 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8293 json
, JSON_C_TO_STRING_PRETTY
));
8294 json_object_free(json
);
8298 DEFUN (show_ip_msdp_sa_detail
,
8299 show_ip_msdp_sa_detail_cmd
,
8300 "show ip msdp [vrf NAME] sa detail [json]",
8305 "MSDP active-source information\n"
8309 u_char uj
= use_json(argc
, argv
);
8311 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
8316 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
8321 DEFUN (show_ip_msdp_sa_detail_vrf_all
,
8322 show_ip_msdp_sa_detail_vrf_all_cmd
,
8323 "show ip msdp vrf all sa detail [json]",
8328 "MSDP active-source information\n"
8332 u_char uj
= use_json(argc
, argv
);
8338 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
8342 vty_out(vty
, " \"%s\": ", vrf
->name
);
8345 vty_out(vty
, "VRF: %s\n", vrf
->name
);
8346 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
8349 vty_out(vty
, "}\n");
8354 static void ip_msdp_show_sa_addr(struct pim_instance
*pim
, struct vty
*vty
,
8355 const char *addr
, u_char uj
)
8357 struct listnode
*sanode
;
8358 struct pim_msdp_sa
*sa
;
8359 char src_str
[INET_ADDRSTRLEN
];
8360 char grp_str
[INET_ADDRSTRLEN
];
8361 json_object
*json
= NULL
;
8364 json
= json_object_new_object();
8367 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
8368 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
8369 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
8370 if (!strcmp(addr
, src_str
) || !strcmp(addr
, grp_str
)) {
8371 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
8377 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8378 json
, JSON_C_TO_STRING_PRETTY
));
8379 json_object_free(json
);
8383 static void ip_msdp_show_sa_sg(struct pim_instance
*pim
, struct vty
*vty
,
8384 const char *src
, const char *grp
, u_char uj
)
8386 struct listnode
*sanode
;
8387 struct pim_msdp_sa
*sa
;
8388 char src_str
[INET_ADDRSTRLEN
];
8389 char grp_str
[INET_ADDRSTRLEN
];
8390 json_object
*json
= NULL
;
8393 json
= json_object_new_object();
8396 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
8397 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
8398 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
8399 if (!strcmp(src
, src_str
) && !strcmp(grp
, grp_str
)) {
8400 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
8406 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8407 json
, JSON_C_TO_STRING_PRETTY
));
8408 json_object_free(json
);
8412 DEFUN (show_ip_msdp_sa_sg
,
8413 show_ip_msdp_sa_sg_cmd
,
8414 "show ip msdp [vrf NAME] sa [A.B.C.D [A.B.C.D]] [json]",
8419 "MSDP active-source information\n"
8420 "source or group ip\n"
8424 u_char uj
= use_json(argc
, argv
);
8428 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
8433 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
8435 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
8439 if (src_ip
&& grp_ip
)
8440 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
8442 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
8444 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
8449 DEFUN (show_ip_msdp_sa_sg_vrf_all
,
8450 show_ip_msdp_sa_sg_vrf_all_cmd
,
8451 "show ip msdp vrf all sa [A.B.C.D [A.B.C.D]] [json]",
8456 "MSDP active-source information\n"
8457 "source or group ip\n"
8461 u_char uj
= use_json(argc
, argv
);
8466 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
8468 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
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
);
8483 if (src_ip
&& grp_ip
)
8484 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
8486 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
8488 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
8491 vty_out(vty
, "}\n");
8497 void pim_cmd_init(void)
8499 install_node(&interface_node
,
8500 pim_interface_config_write
); /* INTERFACE_NODE */
8503 install_node(&debug_node
, pim_debug_config_write
);
8505 install_element(CONFIG_NODE
, &ip_multicast_routing_cmd
);
8506 install_element(CONFIG_NODE
, &no_ip_multicast_routing_cmd
);
8507 install_element(CONFIG_NODE
, &ip_pim_rp_cmd
);
8508 install_element(VRF_NODE
, &ip_pim_rp_cmd
);
8509 install_element(CONFIG_NODE
, &no_ip_pim_rp_cmd
);
8510 install_element(VRF_NODE
, &no_ip_pim_rp_cmd
);
8511 install_element(CONFIG_NODE
, &ip_pim_rp_prefix_list_cmd
);
8512 install_element(VRF_NODE
, &ip_pim_rp_prefix_list_cmd
);
8513 install_element(CONFIG_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
8514 install_element(VRF_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
8515 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
8516 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
8517 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
8518 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
8519 install_element(CONFIG_NODE
, &ip_pim_ssm_prefix_list_cmd
);
8520 install_element(VRF_NODE
, &ip_pim_ssm_prefix_list_cmd
);
8521 install_element(CONFIG_NODE
, &ip_pim_register_suppress_cmd
);
8522 install_element(VRF_NODE
, &ip_pim_register_suppress_cmd
);
8523 install_element(CONFIG_NODE
, &no_ip_pim_register_suppress_cmd
);
8524 install_element(VRF_NODE
, &no_ip_pim_register_suppress_cmd
);
8525 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
8526 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
8527 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
8528 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
8529 install_element(CONFIG_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
8530 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
8531 install_element(CONFIG_NODE
,
8532 &no_ip_pim_spt_switchover_infinity_plist_cmd
);
8533 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_plist_cmd
);
8534 install_element(CONFIG_NODE
, &ip_pim_joinprune_time_cmd
);
8535 install_element(VRF_NODE
, &ip_pim_joinprune_time_cmd
);
8536 install_element(CONFIG_NODE
, &no_ip_pim_joinprune_time_cmd
);
8537 install_element(VRF_NODE
, &no_ip_pim_joinprune_time_cmd
);
8538 install_element(CONFIG_NODE
, &ip_pim_keep_alive_cmd
);
8539 install_element(VRF_NODE
, &ip_pim_keep_alive_cmd
);
8540 install_element(CONFIG_NODE
, &ip_pim_rp_keep_alive_cmd
);
8541 install_element(VRF_NODE
, &ip_pim_rp_keep_alive_cmd
);
8542 install_element(CONFIG_NODE
, &no_ip_pim_keep_alive_cmd
);
8543 install_element(VRF_NODE
, &no_ip_pim_keep_alive_cmd
);
8544 install_element(CONFIG_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
8545 install_element(VRF_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
8546 install_element(CONFIG_NODE
, &ip_pim_packets_cmd
);
8547 install_element(VRF_NODE
, &ip_pim_packets_cmd
);
8548 install_element(CONFIG_NODE
, &no_ip_pim_packets_cmd
);
8549 install_element(VRF_NODE
, &no_ip_pim_packets_cmd
);
8550 install_element(CONFIG_NODE
, &ip_pim_v6_secondary_cmd
);
8551 install_element(VRF_NODE
, &ip_pim_v6_secondary_cmd
);
8552 install_element(CONFIG_NODE
, &no_ip_pim_v6_secondary_cmd
);
8553 install_element(VRF_NODE
, &no_ip_pim_v6_secondary_cmd
);
8554 install_element(CONFIG_NODE
, &ip_ssmpingd_cmd
);
8555 install_element(VRF_NODE
, &ip_ssmpingd_cmd
);
8556 install_element(CONFIG_NODE
, &no_ip_ssmpingd_cmd
);
8557 install_element(VRF_NODE
, &no_ip_ssmpingd_cmd
);
8558 install_element(CONFIG_NODE
, &ip_msdp_peer_cmd
);
8559 install_element(VRF_NODE
, &ip_msdp_peer_cmd
);
8560 install_element(CONFIG_NODE
, &no_ip_msdp_peer_cmd
);
8561 install_element(VRF_NODE
, &no_ip_msdp_peer_cmd
);
8562 install_element(CONFIG_NODE
, &ip_pim_ecmp_cmd
);
8563 install_element(VRF_NODE
, &ip_pim_ecmp_cmd
);
8564 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_cmd
);
8565 install_element(VRF_NODE
, &no_ip_pim_ecmp_cmd
);
8566 install_element(CONFIG_NODE
, &ip_pim_ecmp_rebalance_cmd
);
8567 install_element(VRF_NODE
, &ip_pim_ecmp_rebalance_cmd
);
8568 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
8569 install_element(VRF_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
8571 install_element(INTERFACE_NODE
, &interface_ip_igmp_cmd
);
8572 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_cmd
);
8573 install_element(INTERFACE_NODE
, &interface_ip_igmp_join_cmd
);
8574 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_join_cmd
);
8575 install_element(INTERFACE_NODE
, &interface_ip_igmp_version_cmd
);
8576 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_version_cmd
);
8577 install_element(INTERFACE_NODE
, &interface_ip_igmp_query_interval_cmd
);
8578 install_element(INTERFACE_NODE
,
8579 &interface_no_ip_igmp_query_interval_cmd
);
8580 install_element(INTERFACE_NODE
,
8581 &interface_ip_igmp_query_max_response_time_cmd
);
8582 install_element(INTERFACE_NODE
,
8583 &interface_no_ip_igmp_query_max_response_time_cmd
);
8584 install_element(INTERFACE_NODE
,
8585 &interface_ip_igmp_query_max_response_time_dsec_cmd
);
8586 install_element(INTERFACE_NODE
,
8587 &interface_no_ip_igmp_query_max_response_time_dsec_cmd
);
8588 install_element(INTERFACE_NODE
, &interface_ip_pim_ssm_cmd
);
8589 install_element(INTERFACE_NODE
, &interface_no_ip_pim_ssm_cmd
);
8590 install_element(INTERFACE_NODE
, &interface_ip_pim_sm_cmd
);
8591 install_element(INTERFACE_NODE
, &interface_no_ip_pim_sm_cmd
);
8592 install_element(INTERFACE_NODE
, &interface_ip_pim_drprio_cmd
);
8593 install_element(INTERFACE_NODE
, &interface_no_ip_pim_drprio_cmd
);
8594 install_element(INTERFACE_NODE
, &interface_ip_pim_hello_cmd
);
8595 install_element(INTERFACE_NODE
, &interface_no_ip_pim_hello_cmd
);
8596 install_element(INTERFACE_NODE
, &interface_ip_pim_boundary_oil_cmd
);
8597 install_element(INTERFACE_NODE
, &interface_no_ip_pim_boundary_oil_cmd
);
8599 // Static mroutes NEB
8600 install_element(INTERFACE_NODE
, &interface_ip_mroute_cmd
);
8601 install_element(INTERFACE_NODE
, &interface_ip_mroute_source_cmd
);
8602 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_cmd
);
8603 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_source_cmd
);
8605 install_element(VIEW_NODE
, &show_ip_igmp_interface_cmd
);
8606 install_element(VIEW_NODE
, &show_ip_igmp_interface_vrf_all_cmd
);
8607 install_element(VIEW_NODE
, &show_ip_igmp_join_cmd
);
8608 install_element(VIEW_NODE
, &show_ip_igmp_join_vrf_all_cmd
);
8609 install_element(VIEW_NODE
, &show_ip_igmp_groups_cmd
);
8610 install_element(VIEW_NODE
, &show_ip_igmp_groups_vrf_all_cmd
);
8611 install_element(VIEW_NODE
, &show_ip_igmp_groups_retransmissions_cmd
);
8612 install_element(VIEW_NODE
, &show_ip_igmp_sources_cmd
);
8613 install_element(VIEW_NODE
, &show_ip_igmp_sources_retransmissions_cmd
);
8614 install_element(VIEW_NODE
, &show_ip_pim_assert_cmd
);
8615 install_element(VIEW_NODE
, &show_ip_pim_assert_internal_cmd
);
8616 install_element(VIEW_NODE
, &show_ip_pim_assert_metric_cmd
);
8617 install_element(VIEW_NODE
, &show_ip_pim_assert_winner_metric_cmd
);
8618 install_element(VIEW_NODE
, &show_ip_pim_interface_traffic_cmd
);
8619 install_element(VIEW_NODE
, &show_ip_pim_interface_cmd
);
8620 install_element(VIEW_NODE
, &show_ip_pim_interface_vrf_all_cmd
);
8621 install_element(VIEW_NODE
, &show_ip_pim_join_cmd
);
8622 install_element(VIEW_NODE
, &show_ip_pim_join_vrf_all_cmd
);
8623 install_element(VIEW_NODE
, &show_ip_pim_local_membership_cmd
);
8624 install_element(VIEW_NODE
, &show_ip_pim_neighbor_cmd
);
8625 install_element(VIEW_NODE
, &show_ip_pim_neighbor_vrf_all_cmd
);
8626 install_element(VIEW_NODE
, &show_ip_pim_rpf_cmd
);
8627 install_element(VIEW_NODE
, &show_ip_pim_rpf_vrf_all_cmd
);
8628 install_element(VIEW_NODE
, &show_ip_pim_secondary_cmd
);
8629 install_element(VIEW_NODE
, &show_ip_pim_state_cmd
);
8630 install_element(VIEW_NODE
, &show_ip_pim_state_vrf_all_cmd
);
8631 install_element(VIEW_NODE
, &show_ip_pim_upstream_cmd
);
8632 install_element(VIEW_NODE
, &show_ip_pim_upstream_vrf_all_cmd
);
8633 install_element(VIEW_NODE
, &show_ip_pim_upstream_join_desired_cmd
);
8634 install_element(VIEW_NODE
, &show_ip_pim_upstream_rpf_cmd
);
8635 install_element(VIEW_NODE
, &show_ip_pim_rp_cmd
);
8636 install_element(VIEW_NODE
, &show_ip_pim_rp_vrf_all_cmd
);
8637 install_element(VIEW_NODE
, &show_ip_multicast_cmd
);
8638 install_element(VIEW_NODE
, &show_ip_multicast_vrf_all_cmd
);
8639 install_element(VIEW_NODE
, &show_ip_mroute_cmd
);
8640 install_element(VIEW_NODE
, &show_ip_mroute_vrf_all_cmd
);
8641 install_element(VIEW_NODE
, &show_ip_mroute_count_cmd
);
8642 install_element(VIEW_NODE
, &show_ip_mroute_count_vrf_all_cmd
);
8643 install_element(VIEW_NODE
, &show_ip_rib_cmd
);
8644 install_element(VIEW_NODE
, &show_ip_ssmpingd_cmd
);
8645 install_element(VIEW_NODE
, &show_debugging_pim_cmd
);
8646 install_element(VIEW_NODE
, &show_ip_pim_nexthop_cmd
);
8647 install_element(VIEW_NODE
, &show_ip_pim_nexthop_lookup_cmd
);
8649 install_element(ENABLE_NODE
, &clear_ip_interfaces_cmd
);
8650 install_element(ENABLE_NODE
, &clear_ip_igmp_interfaces_cmd
);
8651 install_element(ENABLE_NODE
, &clear_ip_mroute_cmd
);
8652 install_element(ENABLE_NODE
, &clear_ip_pim_interfaces_cmd
);
8653 install_element(ENABLE_NODE
, &clear_ip_pim_interface_traffic_cmd
);
8654 install_element(ENABLE_NODE
, &clear_ip_pim_oil_cmd
);
8656 install_element(ENABLE_NODE
, &debug_igmp_cmd
);
8657 install_element(ENABLE_NODE
, &no_debug_igmp_cmd
);
8658 install_element(ENABLE_NODE
, &debug_igmp_events_cmd
);
8659 install_element(ENABLE_NODE
, &no_debug_igmp_events_cmd
);
8660 install_element(ENABLE_NODE
, &debug_igmp_packets_cmd
);
8661 install_element(ENABLE_NODE
, &no_debug_igmp_packets_cmd
);
8662 install_element(ENABLE_NODE
, &debug_igmp_trace_cmd
);
8663 install_element(ENABLE_NODE
, &no_debug_igmp_trace_cmd
);
8664 install_element(ENABLE_NODE
, &debug_mroute_cmd
);
8665 install_element(ENABLE_NODE
, &debug_mroute_detail_cmd
);
8666 install_element(ENABLE_NODE
, &no_debug_mroute_cmd
);
8667 install_element(ENABLE_NODE
, &no_debug_mroute_detail_cmd
);
8668 install_element(ENABLE_NODE
, &debug_static_cmd
);
8669 install_element(ENABLE_NODE
, &no_debug_static_cmd
);
8670 install_element(ENABLE_NODE
, &debug_pim_cmd
);
8671 install_element(ENABLE_NODE
, &no_debug_pim_cmd
);
8672 install_element(ENABLE_NODE
, &debug_pim_nht_cmd
);
8673 install_element(ENABLE_NODE
, &no_debug_pim_nht_cmd
);
8674 install_element(ENABLE_NODE
, &debug_pim_nht_rp_cmd
);
8675 install_element(ENABLE_NODE
, &no_debug_pim_nht_rp_cmd
);
8676 install_element(ENABLE_NODE
, &debug_pim_events_cmd
);
8677 install_element(ENABLE_NODE
, &no_debug_pim_events_cmd
);
8678 install_element(ENABLE_NODE
, &debug_pim_packets_cmd
);
8679 install_element(ENABLE_NODE
, &no_debug_pim_packets_cmd
);
8680 install_element(ENABLE_NODE
, &debug_pim_packetdump_send_cmd
);
8681 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_send_cmd
);
8682 install_element(ENABLE_NODE
, &debug_pim_packetdump_recv_cmd
);
8683 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_recv_cmd
);
8684 install_element(ENABLE_NODE
, &debug_pim_trace_cmd
);
8685 install_element(ENABLE_NODE
, &no_debug_pim_trace_cmd
);
8686 install_element(ENABLE_NODE
, &debug_pim_trace_detail_cmd
);
8687 install_element(ENABLE_NODE
, &no_debug_pim_trace_detail_cmd
);
8688 install_element(ENABLE_NODE
, &debug_ssmpingd_cmd
);
8689 install_element(ENABLE_NODE
, &no_debug_ssmpingd_cmd
);
8690 install_element(ENABLE_NODE
, &debug_pim_zebra_cmd
);
8691 install_element(ENABLE_NODE
, &no_debug_pim_zebra_cmd
);
8692 install_element(ENABLE_NODE
, &debug_msdp_cmd
);
8693 install_element(ENABLE_NODE
, &no_debug_msdp_cmd
);
8694 install_element(ENABLE_NODE
, &undebug_msdp_cmd
);
8695 install_element(ENABLE_NODE
, &debug_msdp_events_cmd
);
8696 install_element(ENABLE_NODE
, &no_debug_msdp_events_cmd
);
8697 install_element(ENABLE_NODE
, &undebug_msdp_events_cmd
);
8698 install_element(ENABLE_NODE
, &debug_msdp_packets_cmd
);
8699 install_element(ENABLE_NODE
, &no_debug_msdp_packets_cmd
);
8700 install_element(ENABLE_NODE
, &undebug_msdp_packets_cmd
);
8701 install_element(ENABLE_NODE
, &debug_mtrace_cmd
);
8702 install_element(ENABLE_NODE
, &no_debug_mtrace_cmd
);
8704 install_element(CONFIG_NODE
, &debug_igmp_cmd
);
8705 install_element(CONFIG_NODE
, &no_debug_igmp_cmd
);
8706 install_element(CONFIG_NODE
, &debug_igmp_events_cmd
);
8707 install_element(CONFIG_NODE
, &no_debug_igmp_events_cmd
);
8708 install_element(CONFIG_NODE
, &debug_igmp_packets_cmd
);
8709 install_element(CONFIG_NODE
, &no_debug_igmp_packets_cmd
);
8710 install_element(CONFIG_NODE
, &debug_igmp_trace_cmd
);
8711 install_element(CONFIG_NODE
, &no_debug_igmp_trace_cmd
);
8712 install_element(CONFIG_NODE
, &debug_mroute_cmd
);
8713 install_element(CONFIG_NODE
, &debug_mroute_detail_cmd
);
8714 install_element(CONFIG_NODE
, &no_debug_mroute_cmd
);
8715 install_element(CONFIG_NODE
, &no_debug_mroute_detail_cmd
);
8716 install_element(CONFIG_NODE
, &debug_static_cmd
);
8717 install_element(CONFIG_NODE
, &no_debug_static_cmd
);
8718 install_element(CONFIG_NODE
, &debug_pim_cmd
);
8719 install_element(CONFIG_NODE
, &no_debug_pim_cmd
);
8720 install_element(CONFIG_NODE
, &debug_pim_nht_cmd
);
8721 install_element(CONFIG_NODE
, &no_debug_pim_nht_cmd
);
8722 install_element(CONFIG_NODE
, &debug_pim_nht_rp_cmd
);
8723 install_element(CONFIG_NODE
, &no_debug_pim_nht_rp_cmd
);
8724 install_element(CONFIG_NODE
, &debug_pim_events_cmd
);
8725 install_element(CONFIG_NODE
, &no_debug_pim_events_cmd
);
8726 install_element(CONFIG_NODE
, &debug_pim_packets_cmd
);
8727 install_element(CONFIG_NODE
, &no_debug_pim_packets_cmd
);
8728 install_element(CONFIG_NODE
, &debug_pim_trace_cmd
);
8729 install_element(CONFIG_NODE
, &no_debug_pim_trace_cmd
);
8730 install_element(CONFIG_NODE
, &debug_pim_trace_detail_cmd
);
8731 install_element(CONFIG_NODE
, &no_debug_pim_trace_detail_cmd
);
8732 install_element(CONFIG_NODE
, &debug_ssmpingd_cmd
);
8733 install_element(CONFIG_NODE
, &no_debug_ssmpingd_cmd
);
8734 install_element(CONFIG_NODE
, &debug_pim_zebra_cmd
);
8735 install_element(CONFIG_NODE
, &no_debug_pim_zebra_cmd
);
8736 install_element(CONFIG_NODE
, &debug_msdp_cmd
);
8737 install_element(CONFIG_NODE
, &no_debug_msdp_cmd
);
8738 install_element(CONFIG_NODE
, &undebug_msdp_cmd
);
8739 install_element(CONFIG_NODE
, &debug_msdp_events_cmd
);
8740 install_element(CONFIG_NODE
, &no_debug_msdp_events_cmd
);
8741 install_element(CONFIG_NODE
, &undebug_msdp_events_cmd
);
8742 install_element(CONFIG_NODE
, &debug_msdp_packets_cmd
);
8743 install_element(CONFIG_NODE
, &no_debug_msdp_packets_cmd
);
8744 install_element(CONFIG_NODE
, &undebug_msdp_packets_cmd
);
8745 install_element(CONFIG_NODE
, &debug_mtrace_cmd
);
8746 install_element(CONFIG_NODE
, &no_debug_mtrace_cmd
);
8748 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_member_cmd
);
8749 install_element(VRF_NODE
, &ip_msdp_mesh_group_member_cmd
);
8750 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
8751 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
8752 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_source_cmd
);
8753 install_element(VRF_NODE
, &ip_msdp_mesh_group_source_cmd
);
8754 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
8755 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
8756 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_cmd
);
8757 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_vrf_all_cmd
);
8758 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_cmd
);
8759 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_vrf_all_cmd
);
8760 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_cmd
);
8761 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_vrf_all_cmd
);
8762 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_cmd
);
8763 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_vrf_all_cmd
);
8764 install_element(VIEW_NODE
, &show_ip_pim_ssm_range_cmd
);
8765 install_element(VIEW_NODE
, &show_ip_pim_group_type_cmd
);
8766 install_element(INTERFACE_NODE
, &interface_pim_use_source_cmd
);
8767 install_element(INTERFACE_NODE
, &interface_no_pim_use_source_cmd
);
8768 /* Install BFD command */
8769 install_element(INTERFACE_NODE
, &ip_pim_bfd_cmd
);
8770 install_element(INTERFACE_NODE
, &ip_pim_bfd_param_cmd
);
8771 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_cmd
);
8772 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_param_cmd
);