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"
63 #include "pim_vxlan.h"
67 #ifndef VTYSH_EXTRACT_PL
68 #include "pimd/pim_cmd_clippy.c"
71 static struct cmd_node interface_node
= {
72 INTERFACE_NODE
, "%s(config-if)# ", 1 /* vtysh ? yes */
75 static struct cmd_node debug_node
= {DEBUG_NODE
, "", 1};
77 static struct vrf
*pim_cmd_lookup_vrf(struct vty
*vty
, struct cmd_token
*argv
[],
78 const int argc
, int *idx
)
82 if (argv_find(argv
, argc
, "NAME", idx
))
83 vrf
= vrf_lookup_by_name(argv
[*idx
]->arg
);
85 vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
88 vty_out(vty
, "Specified VRF: %s does not exist\n",
94 static void pim_if_membership_clear(struct interface
*ifp
)
96 struct pim_interface
*pim_ifp
;
101 if (PIM_IF_TEST_PIM(pim_ifp
->options
)
102 && PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
106 pim_ifchannel_membership_clear(ifp
);
110 When PIM is disabled on interface, IGMPv3 local membership
111 information is not injected into PIM interface state.
113 The function pim_if_membership_refresh() fetches all IGMPv3 local
114 membership information into PIM. It is intented to be called
115 whenever PIM is enabled on the interface in order to collect missed
116 local membership information.
118 static void pim_if_membership_refresh(struct interface
*ifp
)
120 struct pim_interface
*pim_ifp
;
121 struct listnode
*sock_node
;
122 struct igmp_sock
*igmp
;
127 if (!PIM_IF_TEST_PIM(pim_ifp
->options
))
129 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
))
133 First clear off membership from all PIM (S,G) entries on the
137 pim_ifchannel_membership_clear(ifp
);
140 Then restore PIM (S,G) membership from all IGMPv3 (S,G) entries on
144 /* scan igmp sockets */
145 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
146 struct listnode
*grpnode
;
147 struct igmp_group
*grp
;
149 /* scan igmp groups */
150 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grpnode
,
152 struct listnode
*srcnode
;
153 struct igmp_source
*src
;
155 /* scan group sources */
156 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
,
159 if (IGMP_SOURCE_TEST_FORWARDING(
160 src
->source_flags
)) {
164 sizeof(struct prefix_sg
));
165 sg
.src
= src
->source_addr
;
166 sg
.grp
= grp
->group_addr
;
167 pim_ifchannel_local_membership_add(ifp
,
171 } /* scan group sources */
172 } /* scan igmp groups */
173 } /* scan igmp sockets */
176 Finally delete every PIM (S,G) entry lacking all state info
179 pim_ifchannel_delete_on_noinfo(ifp
);
182 static void pim_show_assert_helper(struct vty
*vty
,
183 struct pim_interface
*pim_ifp
,
184 struct pim_ifchannel
*ch
, time_t now
)
186 char ch_src_str
[INET_ADDRSTRLEN
];
187 char ch_grp_str
[INET_ADDRSTRLEN
];
188 char winner_str
[INET_ADDRSTRLEN
];
189 struct in_addr ifaddr
;
193 ifaddr
= pim_ifp
->primary_address
;
195 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
196 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
197 pim_inet4_dump("<assrt_win?>", ch
->ifassert_winner
, winner_str
,
200 pim_time_uptime(uptime
, sizeof(uptime
), now
- ch
->ifassert_creation
);
201 pim_time_timer_to_mmss(timer
, sizeof(timer
), ch
->t_ifassert_timer
);
203 vty_out(vty
, "%-16s %-15s %-15s %-15s %-6s %-15s %-8s %-5s\n",
204 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
, ch_grp_str
,
205 pim_ifchannel_ifassert_name(ch
->ifassert_state
), winner_str
,
209 static void pim_show_assert(struct pim_instance
*pim
, struct vty
*vty
)
211 struct pim_interface
*pim_ifp
;
212 struct pim_ifchannel
*ch
;
213 struct interface
*ifp
;
216 now
= pim_time_monotonic_sec();
219 "Interface Address Source Group State Winner Uptime Timer\n");
221 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
226 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
227 pim_show_assert_helper(vty
, pim_ifp
, ch
, now
);
228 } /* scan interface channels */
232 static void pim_show_assert_internal_helper(struct vty
*vty
,
233 struct pim_interface
*pim_ifp
,
234 struct pim_ifchannel
*ch
)
236 char ch_src_str
[INET_ADDRSTRLEN
];
237 char ch_grp_str
[INET_ADDRSTRLEN
];
238 struct in_addr ifaddr
;
240 ifaddr
= pim_ifp
->primary_address
;
242 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
243 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
244 vty_out(vty
, "%-16s %-15s %-15s %-15s %-3s %-3s %-3s %-4s\n",
245 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
, ch_grp_str
,
246 PIM_IF_FLAG_TEST_COULD_ASSERT(ch
->flags
) ? "yes" : "no",
247 pim_macro_ch_could_assert_eval(ch
) ? "yes" : "no",
248 PIM_IF_FLAG_TEST_ASSERT_TRACKING_DESIRED(ch
->flags
) ? "yes"
250 pim_macro_assert_tracking_desired_eval(ch
) ? "yes" : "no");
253 static void pim_show_assert_internal(struct pim_instance
*pim
, struct vty
*vty
)
255 struct pim_interface
*pim_ifp
;
256 struct pim_ifchannel
*ch
;
257 struct interface
*ifp
;
261 "ECA: Evaluate CouldAssert\n"
262 "ATD: AssertTrackingDesired\n"
263 "eATD: Evaluate AssertTrackingDesired\n\n");
266 "Interface Address Source Group CA eCA ATD eATD\n");
267 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
272 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
273 pim_show_assert_internal_helper(vty
, pim_ifp
, ch
);
274 } /* scan interface channels */
278 static void pim_show_assert_metric_helper(struct vty
*vty
,
279 struct pim_interface
*pim_ifp
,
280 struct pim_ifchannel
*ch
)
282 char ch_src_str
[INET_ADDRSTRLEN
];
283 char ch_grp_str
[INET_ADDRSTRLEN
];
284 char addr_str
[INET_ADDRSTRLEN
];
285 struct pim_assert_metric am
;
286 struct in_addr ifaddr
;
288 ifaddr
= pim_ifp
->primary_address
;
290 am
= pim_macro_spt_assert_metric(&ch
->upstream
->rpf
,
291 pim_ifp
->primary_address
);
293 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
294 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
295 pim_inet4_dump("<addr?>", am
.ip_address
, addr_str
, sizeof(addr_str
));
297 vty_out(vty
, "%-16s %-15s %-15s %-15s %-3s %4u %6u %-15s\n",
298 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
, ch_grp_str
,
299 am
.rpt_bit_flag
? "yes" : "no", am
.metric_preference
,
300 am
.route_metric
, addr_str
);
303 static void pim_show_assert_metric(struct pim_instance
*pim
, struct vty
*vty
)
305 struct pim_interface
*pim_ifp
;
306 struct pim_ifchannel
*ch
;
307 struct interface
*ifp
;
310 "Interface Address Source Group RPT Pref Metric Address \n");
312 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
317 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
318 pim_show_assert_metric_helper(vty
, pim_ifp
, ch
);
319 } /* scan interface channels */
323 static void pim_show_assert_winner_metric_helper(struct vty
*vty
,
324 struct pim_interface
*pim_ifp
,
325 struct pim_ifchannel
*ch
)
327 char ch_src_str
[INET_ADDRSTRLEN
];
328 char ch_grp_str
[INET_ADDRSTRLEN
];
329 char addr_str
[INET_ADDRSTRLEN
];
330 struct pim_assert_metric
*am
;
331 struct in_addr ifaddr
;
335 ifaddr
= pim_ifp
->primary_address
;
337 am
= &ch
->ifassert_winner_metric
;
339 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
340 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
341 pim_inet4_dump("<addr?>", am
->ip_address
, addr_str
, sizeof(addr_str
));
343 if (am
->metric_preference
== PIM_ASSERT_METRIC_PREFERENCE_MAX
)
344 snprintf(pref_str
, sizeof(pref_str
), "INFI");
346 snprintf(pref_str
, sizeof(pref_str
), "%4u",
347 am
->metric_preference
);
349 if (am
->route_metric
== PIM_ASSERT_ROUTE_METRIC_MAX
)
350 snprintf(metr_str
, sizeof(metr_str
), "INFI");
352 snprintf(metr_str
, sizeof(metr_str
), "%6u", am
->route_metric
);
354 vty_out(vty
, "%-16s %-15s %-15s %-15s %-3s %-4s %-6s %-15s\n",
355 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
, ch_grp_str
,
356 am
->rpt_bit_flag
? "yes" : "no", pref_str
, metr_str
, addr_str
);
359 static void pim_show_assert_winner_metric(struct pim_instance
*pim
,
362 struct pim_interface
*pim_ifp
;
363 struct pim_ifchannel
*ch
;
364 struct interface
*ifp
;
367 "Interface Address Source Group RPT Pref Metric Address \n");
369 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
374 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
375 pim_show_assert_winner_metric_helper(vty
, pim_ifp
, ch
);
376 } /* scan interface channels */
380 static void json_object_pim_ifp_add(struct json_object
*json
,
381 struct interface
*ifp
)
383 struct pim_interface
*pim_ifp
;
386 json_object_string_add(json
, "name", ifp
->name
);
387 json_object_string_add(json
, "state", if_is_up(ifp
) ? "up" : "down");
388 json_object_string_add(json
, "address",
389 inet_ntoa(pim_ifp
->primary_address
));
390 json_object_int_add(json
, "index", ifp
->ifindex
);
392 if (if_is_multicast(ifp
))
393 json_object_boolean_true_add(json
, "flagMulticast");
395 if (if_is_broadcast(ifp
))
396 json_object_boolean_true_add(json
, "flagBroadcast");
398 if (ifp
->flags
& IFF_ALLMULTI
)
399 json_object_boolean_true_add(json
, "flagAllMulticast");
401 if (ifp
->flags
& IFF_PROMISC
)
402 json_object_boolean_true_add(json
, "flagPromiscuous");
404 if (PIM_IF_IS_DELETED(ifp
))
405 json_object_boolean_true_add(json
, "flagDeleted");
407 if (pim_if_lan_delay_enabled(ifp
))
408 json_object_boolean_true_add(json
, "lanDelayEnabled");
411 static void pim_show_membership_helper(struct vty
*vty
,
412 struct pim_interface
*pim_ifp
,
413 struct pim_ifchannel
*ch
,
414 struct json_object
*json
)
416 char ch_src_str
[INET_ADDRSTRLEN
];
417 char ch_grp_str
[INET_ADDRSTRLEN
];
418 json_object
*json_iface
= NULL
;
419 json_object
*json_row
= NULL
;
421 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
422 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
424 json_object_object_get_ex(json
, ch
->interface
->name
, &json_iface
);
426 json_iface
= json_object_new_object();
427 json_object_pim_ifp_add(json_iface
, ch
->interface
);
428 json_object_object_add(json
, ch
->interface
->name
, json_iface
);
431 json_row
= json_object_new_object();
432 json_object_string_add(json_row
, "source", ch_src_str
);
433 json_object_string_add(json_row
, "group", ch_grp_str
);
434 json_object_string_add(json_row
, "localMembership",
435 ch
->local_ifmembership
== PIM_IFMEMBERSHIP_NOINFO
438 json_object_object_add(json_iface
, ch_grp_str
, json_row
);
440 static void pim_show_membership(struct pim_instance
*pim
, struct vty
*vty
,
443 struct pim_interface
*pim_ifp
;
444 struct pim_ifchannel
*ch
;
445 struct interface
*ifp
;
447 json_object
*json
= NULL
;
448 json_object
*json_tmp
= NULL
;
450 json
= json_object_new_object();
452 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
457 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
458 pim_show_membership_helper(vty
, pim_ifp
, ch
, json
);
459 } /* scan interface channels */
463 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
464 json
, JSON_C_TO_STRING_PRETTY
));
467 "Interface Address Source Group Membership\n");
470 * Example of the json data we are traversing
476 * "address":"10.1.20.1",
478 * "flagMulticast":true,
479 * "flagBroadcast":true,
480 * "lanDelayEnabled":true,
483 * "group":"226.10.10.10",
484 * "localMembership":"INCLUDE"
490 /* foreach interface */
491 json_object_object_foreach(json
, key
, val
)
494 /* Find all of the keys where the val is an object. In
496 * above the only one is 226.10.10.10
498 json_object_object_foreach(val
, if_field_key
,
501 type
= json_object_get_type(if_field_val
);
503 if (type
== json_type_object
) {
504 vty_out(vty
, "%-16s ", key
);
506 json_object_object_get_ex(
507 val
, "address", &json_tmp
);
508 vty_out(vty
, "%-15s ",
509 json_object_get_string(
512 json_object_object_get_ex(if_field_val
,
515 vty_out(vty
, "%-15s ",
516 json_object_get_string(
520 vty_out(vty
, "%-15s ", if_field_key
);
522 json_object_object_get_ex(
523 if_field_val
, "localMembership",
525 vty_out(vty
, "%-10s\n",
526 json_object_get_string(
533 json_object_free(json
);
536 static void pim_print_ifp_flags(struct vty
*vty
, struct interface
*ifp
,
539 vty_out(vty
, "Flags\n");
540 vty_out(vty
, "-----\n");
541 vty_out(vty
, "All Multicast : %s\n",
542 (ifp
->flags
& IFF_ALLMULTI
) ? "yes" : "no");
543 vty_out(vty
, "Broadcast : %s\n",
544 if_is_broadcast(ifp
) ? "yes" : "no");
545 vty_out(vty
, "Deleted : %s\n",
546 PIM_IF_IS_DELETED(ifp
) ? "yes" : "no");
547 vty_out(vty
, "Interface Index : %d\n", ifp
->ifindex
);
548 vty_out(vty
, "Multicast : %s\n",
549 if_is_multicast(ifp
) ? "yes" : "no");
550 vty_out(vty
, "Multicast Loop : %d\n", mloop
);
551 vty_out(vty
, "Promiscuous : %s\n",
552 (ifp
->flags
& IFF_PROMISC
) ? "yes" : "no");
557 static void igmp_show_interfaces(struct pim_instance
*pim
, struct vty
*vty
,
560 struct interface
*ifp
;
562 json_object
*json
= NULL
;
563 json_object
*json_row
= NULL
;
565 now
= pim_time_monotonic_sec();
568 json
= json_object_new_object();
571 "Interface State Address V Querier Query Timer Uptime\n");
573 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
574 struct pim_interface
*pim_ifp
;
575 struct listnode
*sock_node
;
576 struct igmp_sock
*igmp
;
583 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
586 char query_hhmmss
[10];
588 pim_time_uptime(uptime
, sizeof(uptime
),
589 now
- igmp
->sock_creation
);
590 pim_time_timer_to_hhmmss(query_hhmmss
,
591 sizeof(query_hhmmss
),
592 igmp
->t_igmp_query_timer
);
595 json_row
= json_object_new_object();
596 json_object_pim_ifp_add(json_row
, ifp
);
597 json_object_string_add(json_row
, "upTime",
599 json_object_int_add(json_row
, "version",
600 pim_ifp
->igmp_version
);
602 if (igmp
->t_igmp_query_timer
) {
603 json_object_boolean_true_add(json_row
,
605 json_object_string_add(json_row
,
610 json_object_object_add(json
, ifp
->name
,
613 if (igmp
->mtrace_only
) {
614 json_object_boolean_true_add(
615 json_row
, "mtraceOnly");
619 "%-16s %5s %15s %d %7s %11s %8s\n",
622 ? (igmp
->mtrace_only
? "mtrc"
625 inet_ntoa(igmp
->ifaddr
),
626 pim_ifp
->igmp_version
,
627 igmp
->t_igmp_query_timer
? "local"
629 query_hhmmss
, uptime
);
635 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
636 json
, JSON_C_TO_STRING_PRETTY
));
637 json_object_free(json
);
641 static void igmp_show_interfaces_single(struct pim_instance
*pim
,
642 struct vty
*vty
, const char *ifname
,
645 struct igmp_sock
*igmp
;
646 struct interface
*ifp
;
647 struct listnode
*sock_node
;
648 struct pim_interface
*pim_ifp
;
650 char query_hhmmss
[10];
651 char other_hhmmss
[10];
652 int found_ifname
= 0;
655 long gmi_msec
; /* Group Membership Interval */
658 long oqpi_msec
; /* Other Querier Present Interval */
663 json_object
*json
= NULL
;
664 json_object
*json_row
= NULL
;
667 json
= json_object_new_object();
669 now
= pim_time_monotonic_sec();
671 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
677 if (strcmp(ifname
, "detail") && strcmp(ifname
, ifp
->name
))
680 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
683 pim_time_uptime(uptime
, sizeof(uptime
),
684 now
- igmp
->sock_creation
);
685 pim_time_timer_to_hhmmss(query_hhmmss
,
686 sizeof(query_hhmmss
),
687 igmp
->t_igmp_query_timer
);
688 pim_time_timer_to_hhmmss(other_hhmmss
,
689 sizeof(other_hhmmss
),
690 igmp
->t_other_querier_timer
);
692 gmi_msec
= PIM_IGMP_GMI_MSEC(
693 igmp
->querier_robustness_variable
,
694 igmp
->querier_query_interval
,
695 pim_ifp
->igmp_query_max_response_time_dsec
);
698 pim_ifp
->igmp_default_query_interval
);
700 oqpi_msec
= PIM_IGMP_OQPI_MSEC(
701 igmp
->querier_robustness_variable
,
702 igmp
->querier_query_interval
,
703 pim_ifp
->igmp_query_max_response_time_dsec
);
705 lmqt_msec
= PIM_IGMP_LMQT_MSEC(
706 pim_ifp
->igmp_specific_query_max_response_time_dsec
,
707 pim_ifp
->igmp_last_member_query_count
);
711 igmp
->querier_robustness_variable
,
712 igmp
->querier_query_interval
,
713 pim_ifp
->igmp_query_max_response_time_dsec
)
716 qri_msec
= pim_ifp
->igmp_query_max_response_time_dsec
718 if (pim_ifp
->pim_sock_fd
>= 0)
719 mloop
= pim_socket_mcastloop_get(
720 pim_ifp
->pim_sock_fd
);
723 lmqc
= pim_ifp
->igmp_last_member_query_count
;
726 json_row
= json_object_new_object();
727 json_object_pim_ifp_add(json_row
, ifp
);
728 json_object_string_add(json_row
, "upTime",
730 json_object_string_add(json_row
, "querier",
731 igmp
->t_igmp_query_timer
734 json_object_int_add(json_row
, "queryStartCount",
735 igmp
->startup_query_count
);
736 json_object_string_add(json_row
,
739 json_object_string_add(json_row
,
742 json_object_int_add(json_row
, "version",
743 pim_ifp
->igmp_version
);
746 "timerGroupMembershipIntervalMsec",
748 json_object_int_add(json_row
,
749 "lastMemberQueryCount",
751 json_object_int_add(json_row
,
752 "timerLastMemberQueryMsec",
756 "timerOlderHostPresentIntervalMsec",
760 "timerOtherQuerierPresentIntervalMsec",
763 json_row
, "timerQueryInterval",
764 igmp
->querier_query_interval
);
767 "timerQueryResponseIntervalMsec",
770 json_row
, "timerRobustnessVariable",
771 igmp
->querier_robustness_variable
);
772 json_object_int_add(json_row
,
773 "timerStartupQueryInterval",
776 json_object_object_add(json
, ifp
->name
,
779 if (igmp
->mtrace_only
) {
780 json_object_boolean_true_add(
781 json_row
, "mtraceOnly");
784 vty_out(vty
, "Interface : %s\n", ifp
->name
);
785 vty_out(vty
, "State : %s\n",
787 ? (igmp
->mtrace_only
? "mtrace"
790 vty_out(vty
, "Address : %s\n",
791 inet_ntoa(pim_ifp
->primary_address
));
792 vty_out(vty
, "Uptime : %s\n", uptime
);
793 vty_out(vty
, "Version : %d\n",
794 pim_ifp
->igmp_version
);
798 vty_out(vty
, "Querier\n");
799 vty_out(vty
, "-------\n");
800 vty_out(vty
, "Querier : %s\n",
801 igmp
->t_igmp_query_timer
? "local"
803 vty_out(vty
, "Start Count : %d\n",
804 igmp
->startup_query_count
);
805 vty_out(vty
, "Query Timer : %s\n",
807 vty_out(vty
, "Other Timer : %s\n",
812 vty_out(vty
, "Timers\n");
813 vty_out(vty
, "------\n");
815 "Group Membership Interval : %lis\n",
818 "Last Member Query Count : %d\n",
821 "Last Member Query Time : %lis\n",
824 "Older Host Present Interval : %lis\n",
827 "Other Querier Present Interval : %lis\n",
830 "Query Interval : %ds\n",
831 igmp
->querier_query_interval
);
833 "Query Response Interval : %lis\n",
836 "Robustness Variable : %d\n",
837 igmp
->querier_robustness_variable
);
839 "Startup Query Interval : %ds\n",
844 pim_print_ifp_flags(vty
, ifp
, mloop
);
850 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
851 json
, JSON_C_TO_STRING_PRETTY
));
852 json_object_free(json
);
855 vty_out(vty
, "%% No such interface\n");
859 static void igmp_show_interface_join(struct pim_instance
*pim
, struct vty
*vty
)
861 struct interface
*ifp
;
864 now
= pim_time_monotonic_sec();
867 "Interface Address Source Group Socket Uptime \n");
869 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
870 struct pim_interface
*pim_ifp
;
871 struct listnode
*join_node
;
872 struct igmp_join
*ij
;
873 struct in_addr pri_addr
;
874 char pri_addr_str
[INET_ADDRSTRLEN
];
881 if (!pim_ifp
->igmp_join_list
)
884 pri_addr
= pim_find_primary_addr(ifp
);
885 pim_inet4_dump("<pri?>", pri_addr
, pri_addr_str
,
886 sizeof(pri_addr_str
));
888 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_join_list
, join_node
,
890 char group_str
[INET_ADDRSTRLEN
];
891 char source_str
[INET_ADDRSTRLEN
];
894 pim_time_uptime(uptime
, sizeof(uptime
),
895 now
- ij
->sock_creation
);
896 pim_inet4_dump("<grp?>", ij
->group_addr
, group_str
,
898 pim_inet4_dump("<src?>", ij
->source_addr
, source_str
,
901 vty_out(vty
, "%-16s %-15s %-15s %-15s %6d %8s\n",
902 ifp
->name
, pri_addr_str
, source_str
, group_str
,
903 ij
->sock_fd
, uptime
);
904 } /* for (pim_ifp->igmp_join_list) */
909 static void pim_show_interfaces_single(struct pim_instance
*pim
,
910 struct vty
*vty
, const char *ifname
,
913 struct in_addr ifaddr
;
914 struct interface
*ifp
;
915 struct listnode
*neighnode
;
916 struct listnode
*upnode
;
917 struct pim_interface
*pim_ifp
;
918 struct pim_neighbor
*neigh
;
919 struct pim_upstream
*up
;
921 char dr_str
[INET_ADDRSTRLEN
];
924 char grp_str
[INET_ADDRSTRLEN
];
925 char hello_period
[10];
926 char hello_timer
[10];
927 char neigh_src_str
[INET_ADDRSTRLEN
];
928 char src_str
[INET_ADDRSTRLEN
];
929 char stat_uptime
[10];
932 int found_ifname
= 0;
934 json_object
*json
= NULL
;
935 json_object
*json_row
= NULL
;
936 json_object
*json_pim_neighbor
= NULL
;
937 json_object
*json_pim_neighbors
= NULL
;
938 json_object
*json_group
= NULL
;
939 json_object
*json_group_source
= NULL
;
940 json_object
*json_fhr_sources
= NULL
;
941 struct pim_secondary_addr
*sec_addr
;
942 struct listnode
*sec_node
;
944 now
= pim_time_monotonic_sec();
947 json
= json_object_new_object();
949 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
955 if (strcmp(ifname
, "detail") && strcmp(ifname
, ifp
->name
))
959 ifaddr
= pim_ifp
->primary_address
;
960 pim_inet4_dump("<dr?>", pim_ifp
->pim_dr_addr
, dr_str
,
962 pim_time_uptime_begin(dr_uptime
, sizeof(dr_uptime
), now
,
963 pim_ifp
->pim_dr_election_last
);
964 pim_time_timer_to_hhmmss(hello_timer
, sizeof(hello_timer
),
965 pim_ifp
->t_pim_hello_timer
);
966 pim_time_mmss(hello_period
, sizeof(hello_period
),
967 pim_ifp
->pim_hello_period
);
968 pim_time_uptime(stat_uptime
, sizeof(stat_uptime
),
969 now
- pim_ifp
->pim_ifstat_start
);
970 if (pim_ifp
->pim_sock_fd
>= 0)
971 mloop
= pim_socket_mcastloop_get(pim_ifp
->pim_sock_fd
);
976 char pbuf
[PREFIX2STR_BUFFER
];
977 json_row
= json_object_new_object();
978 json_object_pim_ifp_add(json_row
, ifp
);
980 if (pim_ifp
->update_source
.s_addr
!= INADDR_ANY
) {
981 json_object_string_add(
982 json_row
, "useSource",
983 inet_ntoa(pim_ifp
->update_source
));
985 if (pim_ifp
->sec_addr_list
) {
986 json_object
*sec_list
= NULL
;
988 sec_list
= json_object_new_array();
989 for (ALL_LIST_ELEMENTS_RO(
990 pim_ifp
->sec_addr_list
, sec_node
,
992 json_object_array_add(
994 json_object_new_string(
1000 json_object_object_add(json_row
,
1001 "secondaryAddressList",
1006 if (pim_ifp
->pim_neighbor_list
->count
) {
1007 json_pim_neighbors
= json_object_new_object();
1009 for (ALL_LIST_ELEMENTS_RO(
1010 pim_ifp
->pim_neighbor_list
,
1011 neighnode
, neigh
)) {
1013 json_object_new_object();
1014 pim_inet4_dump("<src?>",
1017 sizeof(neigh_src_str
));
1018 pim_time_uptime(uptime
, sizeof(uptime
),
1019 now
- neigh
->creation
);
1020 pim_time_timer_to_hhmmss(
1021 expire
, sizeof(expire
),
1022 neigh
->t_expire_timer
);
1024 json_object_string_add(
1025 json_pim_neighbor
, "address",
1027 json_object_string_add(
1028 json_pim_neighbor
, "upTime",
1030 json_object_string_add(
1031 json_pim_neighbor
, "holdtime",
1034 json_object_object_add(
1040 json_object_object_add(json_row
, "neighbors",
1041 json_pim_neighbors
);
1044 json_object_string_add(json_row
, "drAddress", dr_str
);
1045 json_object_int_add(json_row
, "drPriority",
1046 pim_ifp
->pim_dr_priority
);
1047 json_object_string_add(json_row
, "drUptime", dr_uptime
);
1048 json_object_int_add(json_row
, "drElections",
1049 pim_ifp
->pim_dr_election_count
);
1050 json_object_int_add(json_row
, "drChanges",
1051 pim_ifp
->pim_dr_election_changes
);
1054 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
,
1056 if (ifp
!= up
->rpf
.source_nexthop
.interface
)
1059 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
))
1062 if (!json_fhr_sources
)
1064 json_object_new_object();
1066 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
,
1068 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
,
1070 pim_time_uptime(uptime
, sizeof(uptime
),
1071 now
- up
->state_transition
);
1074 * Does this group live in json_fhr_sources?
1077 json_object_object_get_ex(json_fhr_sources
,
1078 grp_str
, &json_group
);
1081 json_group
= json_object_new_object();
1082 json_object_object_add(json_fhr_sources
,
1087 json_group_source
= json_object_new_object();
1088 json_object_string_add(json_group_source
,
1090 json_object_string_add(json_group_source
,
1092 json_object_string_add(json_group_source
,
1094 json_object_object_add(json_group
, src_str
,
1098 if (json_fhr_sources
) {
1099 json_object_object_add(json_row
,
1104 json_object_int_add(json_row
, "helloPeriod",
1105 pim_ifp
->pim_hello_period
);
1106 json_object_string_add(json_row
, "helloTimer",
1108 json_object_string_add(json_row
, "helloStatStart",
1110 json_object_int_add(json_row
, "helloReceived",
1111 pim_ifp
->pim_ifstat_hello_recv
);
1112 json_object_int_add(json_row
, "helloReceivedFailed",
1113 pim_ifp
->pim_ifstat_hello_recvfail
);
1114 json_object_int_add(json_row
, "helloSend",
1115 pim_ifp
->pim_ifstat_hello_sent
);
1116 json_object_int_add(json_row
, "hellosendFailed",
1117 pim_ifp
->pim_ifstat_hello_sendfail
);
1118 json_object_int_add(json_row
, "helloGenerationId",
1119 pim_ifp
->pim_generation_id
);
1120 json_object_int_add(json_row
, "flagMulticastLoop",
1123 json_object_int_add(
1124 json_row
, "effectivePropagationDelay",
1125 pim_if_effective_propagation_delay_msec(ifp
));
1126 json_object_int_add(
1127 json_row
, "effectiveOverrideInterval",
1128 pim_if_effective_override_interval_msec(ifp
));
1129 json_object_int_add(
1130 json_row
, "joinPruneOverrideInterval",
1131 pim_if_jp_override_interval_msec(ifp
));
1133 json_object_int_add(
1134 json_row
, "propagationDelay",
1135 pim_ifp
->pim_propagation_delay_msec
);
1136 json_object_int_add(
1137 json_row
, "propagationDelayHighest",
1138 pim_ifp
->pim_neighbors_highest_propagation_delay_msec
);
1139 json_object_int_add(
1140 json_row
, "overrideInterval",
1141 pim_ifp
->pim_override_interval_msec
);
1142 json_object_int_add(
1143 json_row
, "overrideIntervalHighest",
1144 pim_ifp
->pim_neighbors_highest_override_interval_msec
);
1145 json_object_object_add(json
, ifp
->name
, json_row
);
1148 vty_out(vty
, "Interface : %s\n", ifp
->name
);
1149 vty_out(vty
, "State : %s\n",
1150 if_is_up(ifp
) ? "up" : "down");
1151 if (pim_ifp
->update_source
.s_addr
!= INADDR_ANY
) {
1152 vty_out(vty
, "Use Source : %s\n",
1153 inet_ntoa(pim_ifp
->update_source
));
1155 if (pim_ifp
->sec_addr_list
) {
1156 char pbuf
[PREFIX2STR_BUFFER
];
1157 vty_out(vty
, "Address : %s (primary)\n",
1159 for (ALL_LIST_ELEMENTS_RO(
1160 pim_ifp
->sec_addr_list
, sec_node
,
1162 vty_out(vty
, " %s\n",
1163 prefix2str(&sec_addr
->addr
,
1164 pbuf
, sizeof(pbuf
)));
1167 vty_out(vty
, "Address : %s\n",
1175 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
,
1176 neighnode
, neigh
)) {
1179 vty_out(vty
, "PIM Neighbors\n");
1180 vty_out(vty
, "-------------\n");
1184 pim_inet4_dump("<src?>", neigh
->source_addr
,
1186 sizeof(neigh_src_str
));
1187 pim_time_uptime(uptime
, sizeof(uptime
),
1188 now
- neigh
->creation
);
1189 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
1190 neigh
->t_expire_timer
);
1192 "%-15s : up for %s, holdtime expires in %s\n",
1193 neigh_src_str
, uptime
, expire
);
1196 if (!print_header
) {
1201 vty_out(vty
, "Designated Router\n");
1202 vty_out(vty
, "-----------------\n");
1203 vty_out(vty
, "Address : %s\n", dr_str
);
1204 vty_out(vty
, "Priority : %u(%d)\n",
1205 pim_ifp
->pim_dr_priority
,
1206 pim_ifp
->pim_dr_num_nondrpri_neighbors
);
1207 vty_out(vty
, "Uptime : %s\n", dr_uptime
);
1208 vty_out(vty
, "Elections : %d\n",
1209 pim_ifp
->pim_dr_election_count
);
1210 vty_out(vty
, "Changes : %d\n",
1211 pim_ifp
->pim_dr_election_changes
);
1217 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
,
1219 if (!up
->rpf
.source_nexthop
.interface
)
1222 if (strcmp(ifp
->name
,
1223 up
->rpf
.source_nexthop
1228 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
))
1233 "FHR - First Hop Router\n");
1235 "----------------------\n");
1239 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
,
1241 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
,
1243 pim_time_uptime(uptime
, sizeof(uptime
),
1244 now
- up
->state_transition
);
1246 "%s : %s is a source, uptime is %s\n",
1247 grp_str
, src_str
, uptime
);
1250 if (!print_header
) {
1255 vty_out(vty
, "Hellos\n");
1256 vty_out(vty
, "------\n");
1257 vty_out(vty
, "Period : %d\n",
1258 pim_ifp
->pim_hello_period
);
1259 vty_out(vty
, "Timer : %s\n", hello_timer
);
1260 vty_out(vty
, "StatStart : %s\n", stat_uptime
);
1261 vty_out(vty
, "Receive : %d\n",
1262 pim_ifp
->pim_ifstat_hello_recv
);
1263 vty_out(vty
, "Receive Failed : %d\n",
1264 pim_ifp
->pim_ifstat_hello_recvfail
);
1265 vty_out(vty
, "Send : %d\n",
1266 pim_ifp
->pim_ifstat_hello_sent
);
1267 vty_out(vty
, "Send Failed : %d\n",
1268 pim_ifp
->pim_ifstat_hello_sendfail
);
1269 vty_out(vty
, "Generation ID : %08x\n",
1270 pim_ifp
->pim_generation_id
);
1274 pim_print_ifp_flags(vty
, ifp
, mloop
);
1276 vty_out(vty
, "Join Prune Interval\n");
1277 vty_out(vty
, "-------------------\n");
1278 vty_out(vty
, "LAN Delay : %s\n",
1279 pim_if_lan_delay_enabled(ifp
) ? "yes" : "no");
1280 vty_out(vty
, "Effective Propagation Delay : %d msec\n",
1281 pim_if_effective_propagation_delay_msec(ifp
));
1282 vty_out(vty
, "Effective Override Interval : %d msec\n",
1283 pim_if_effective_override_interval_msec(ifp
));
1284 vty_out(vty
, "Join Prune Override Interval : %d msec\n",
1285 pim_if_jp_override_interval_msec(ifp
));
1289 vty_out(vty
, "LAN Prune Delay\n");
1290 vty_out(vty
, "---------------\n");
1291 vty_out(vty
, "Propagation Delay : %d msec\n",
1292 pim_ifp
->pim_propagation_delay_msec
);
1293 vty_out(vty
, "Propagation Delay (Highest) : %d msec\n",
1294 pim_ifp
->pim_neighbors_highest_propagation_delay_msec
);
1295 vty_out(vty
, "Override Interval : %d msec\n",
1296 pim_ifp
->pim_override_interval_msec
);
1297 vty_out(vty
, "Override Interval (Highest) : %d msec\n",
1298 pim_ifp
->pim_neighbors_highest_override_interval_msec
);
1305 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1306 json
, JSON_C_TO_STRING_PRETTY
));
1307 json_object_free(json
);
1310 vty_out(vty
, "%% No such interface\n");
1314 static void igmp_show_statistics(struct pim_instance
*pim
, struct vty
*vty
,
1315 const char *ifname
, bool uj
)
1317 struct interface
*ifp
;
1318 struct igmp_stats rx_stats
;
1320 igmp_stats_init(&rx_stats
);
1322 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1323 struct pim_interface
*pim_ifp
;
1324 struct listnode
*sock_node
;
1325 struct igmp_sock
*igmp
;
1327 pim_ifp
= ifp
->info
;
1332 if (ifname
&& strcmp(ifname
, ifp
->name
))
1335 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
1337 igmp_stats_add(&rx_stats
, &igmp
->rx_stats
);
1341 json_object
*json
= NULL
;
1342 json_object
*json_row
= NULL
;
1344 json
= json_object_new_object();
1345 json_row
= json_object_new_object();
1347 json_object_string_add(json_row
, "name", ifname
? ifname
:
1349 json_object_int_add(json_row
, "queryV1", rx_stats
.query_v1
);
1350 json_object_int_add(json_row
, "queryV2", rx_stats
.query_v2
);
1351 json_object_int_add(json_row
, "queryV3", rx_stats
.query_v3
);
1352 json_object_int_add(json_row
, "leaveV3", rx_stats
.leave_v2
);
1353 json_object_int_add(json_row
, "reportV1", rx_stats
.report_v1
);
1354 json_object_int_add(json_row
, "reportV2", rx_stats
.report_v2
);
1355 json_object_int_add(json_row
, "reportV3", rx_stats
.report_v3
);
1356 json_object_int_add(json_row
, "mtraceResponse",
1357 rx_stats
.mtrace_rsp
);
1358 json_object_int_add(json_row
, "mtraceRequest",
1359 rx_stats
.mtrace_req
);
1360 json_object_int_add(json_row
, "unsupported",
1361 rx_stats
.unsupported
);
1362 json_object_object_add(json
, ifname
? ifname
: "global",
1364 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1365 json
, JSON_C_TO_STRING_PRETTY
));
1366 json_object_free(json
);
1368 vty_out(vty
, "IGMP RX statistics\n");
1369 vty_out(vty
, "Interface : %s\n",
1370 ifname
? ifname
: "global");
1371 vty_out(vty
, "V1 query : %u\n", rx_stats
.query_v1
);
1372 vty_out(vty
, "V2 query : %u\n", rx_stats
.query_v2
);
1373 vty_out(vty
, "V3 query : %u\n", rx_stats
.query_v3
);
1374 vty_out(vty
, "V2 leave : %u\n", rx_stats
.leave_v2
);
1375 vty_out(vty
, "V1 report : %u\n", rx_stats
.report_v1
);
1376 vty_out(vty
, "V2 report : %u\n", rx_stats
.report_v2
);
1377 vty_out(vty
, "V3 report : %u\n", rx_stats
.report_v3
);
1378 vty_out(vty
, "mtrace response : %u\n", rx_stats
.mtrace_rsp
);
1379 vty_out(vty
, "mtrace request : %u\n", rx_stats
.mtrace_req
);
1380 vty_out(vty
, "unsupported : %u\n", rx_stats
.unsupported
);
1384 static void pim_show_interfaces(struct pim_instance
*pim
, struct vty
*vty
,
1387 struct interface
*ifp
;
1388 struct listnode
*upnode
;
1389 struct pim_interface
*pim_ifp
;
1390 struct pim_upstream
*up
;
1393 int pim_ifchannels
= 0;
1394 json_object
*json
= NULL
;
1395 json_object
*json_row
= NULL
;
1396 json_object
*json_tmp
;
1398 json
= json_object_new_object();
1400 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1401 pim_ifp
= ifp
->info
;
1406 pim_nbrs
= pim_ifp
->pim_neighbor_list
->count
;
1407 pim_ifchannels
= pim_if_ifchannel_count(pim_ifp
);
1410 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
, up
))
1411 if (ifp
== up
->rpf
.source_nexthop
.interface
)
1412 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
1415 json_row
= json_object_new_object();
1416 json_object_pim_ifp_add(json_row
, ifp
);
1417 json_object_int_add(json_row
, "pimNeighbors", pim_nbrs
);
1418 json_object_int_add(json_row
, "pimIfChannels", pim_ifchannels
);
1419 json_object_int_add(json_row
, "firstHopRouterCount", fhr
);
1420 json_object_string_add(json_row
, "pimDesignatedRouter",
1421 inet_ntoa(pim_ifp
->pim_dr_addr
));
1423 if (pim_ifp
->pim_dr_addr
.s_addr
1424 == pim_ifp
->primary_address
.s_addr
)
1425 json_object_boolean_true_add(
1426 json_row
, "pimDesignatedRouterLocal");
1428 json_object_object_add(json
, ifp
->name
, json_row
);
1432 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1433 json
, JSON_C_TO_STRING_PRETTY
));
1436 "Interface State Address PIM Nbrs PIM DR FHR IfChannels\n");
1438 json_object_object_foreach(json
, key
, val
)
1440 vty_out(vty
, "%-16s ", key
);
1442 json_object_object_get_ex(val
, "state", &json_tmp
);
1443 vty_out(vty
, "%5s ", json_object_get_string(json_tmp
));
1445 json_object_object_get_ex(val
, "address", &json_tmp
);
1446 vty_out(vty
, "%15s ",
1447 json_object_get_string(json_tmp
));
1449 json_object_object_get_ex(val
, "pimNeighbors",
1451 vty_out(vty
, "%8d ", json_object_get_int(json_tmp
));
1453 if (json_object_object_get_ex(
1454 val
, "pimDesignatedRouterLocal",
1456 vty_out(vty
, "%15s ", "local");
1458 json_object_object_get_ex(
1459 val
, "pimDesignatedRouter", &json_tmp
);
1460 vty_out(vty
, "%15s ",
1461 json_object_get_string(json_tmp
));
1464 json_object_object_get_ex(val
, "firstHopRouter",
1466 vty_out(vty
, "%3d ", json_object_get_int(json_tmp
));
1468 json_object_object_get_ex(val
, "pimIfChannels",
1470 vty_out(vty
, "%9d\n", json_object_get_int(json_tmp
));
1474 json_object_free(json
);
1477 static void pim_show_interface_traffic(struct pim_instance
*pim
,
1478 struct vty
*vty
, bool uj
)
1480 struct interface
*ifp
= NULL
;
1481 struct pim_interface
*pim_ifp
= NULL
;
1482 json_object
*json
= NULL
;
1483 json_object
*json_row
= NULL
;
1486 json
= json_object_new_object();
1489 vty_out(vty
, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s%-17s\n",
1490 "Interface", " HELLO", " JOIN",
1491 " PRUNE", " REGISTER", "REGISTER-STOP",
1493 vty_out(vty
, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s%-17s\n", "",
1494 " Rx/Tx", " Rx/Tx", " Rx/Tx",
1495 " Rx/Tx", " Rx/Tx", " Rx/Tx",
1498 "---------------------------------------------------------------------------------------------------------------\n");
1501 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1502 pim_ifp
= ifp
->info
;
1507 if (pim_ifp
->pim_sock_fd
< 0)
1510 json_row
= json_object_new_object();
1511 json_object_pim_ifp_add(json_row
, ifp
);
1512 json_object_int_add(json_row
, "helloRx",
1513 pim_ifp
->pim_ifstat_hello_recv
);
1514 json_object_int_add(json_row
, "helloTx",
1515 pim_ifp
->pim_ifstat_hello_sent
);
1516 json_object_int_add(json_row
, "joinRx",
1517 pim_ifp
->pim_ifstat_join_recv
);
1518 json_object_int_add(json_row
, "joinTx",
1519 pim_ifp
->pim_ifstat_join_send
);
1520 json_object_int_add(json_row
, "registerRx",
1521 pim_ifp
->pim_ifstat_reg_recv
);
1522 json_object_int_add(json_row
, "registerTx",
1523 pim_ifp
->pim_ifstat_reg_recv
);
1524 json_object_int_add(json_row
, "registerStopRx",
1525 pim_ifp
->pim_ifstat_reg_stop_recv
);
1526 json_object_int_add(json_row
, "registerStopTx",
1527 pim_ifp
->pim_ifstat_reg_stop_send
);
1528 json_object_int_add(json_row
, "assertRx",
1529 pim_ifp
->pim_ifstat_assert_recv
);
1530 json_object_int_add(json_row
, "assertTx",
1531 pim_ifp
->pim_ifstat_assert_send
);
1532 json_object_int_add(json_row
, "bsmRx",
1533 pim_ifp
->pim_ifstat_bsm_rx
);
1534 json_object_int_add(json_row
, "bsmTx",
1535 pim_ifp
->pim_ifstat_bsm_tx
);
1536 json_object_object_add(json
, ifp
->name
, json_row
);
1539 "%-16s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7lu/%-7lu \n",
1540 ifp
->name
, pim_ifp
->pim_ifstat_hello_recv
,
1541 pim_ifp
->pim_ifstat_hello_sent
,
1542 pim_ifp
->pim_ifstat_join_recv
,
1543 pim_ifp
->pim_ifstat_join_send
,
1544 pim_ifp
->pim_ifstat_prune_recv
,
1545 pim_ifp
->pim_ifstat_prune_send
,
1546 pim_ifp
->pim_ifstat_reg_recv
,
1547 pim_ifp
->pim_ifstat_reg_send
,
1548 pim_ifp
->pim_ifstat_reg_stop_recv
,
1549 pim_ifp
->pim_ifstat_reg_stop_send
,
1550 pim_ifp
->pim_ifstat_assert_recv
,
1551 pim_ifp
->pim_ifstat_assert_send
,
1552 pim_ifp
->pim_ifstat_bsm_rx
,
1553 pim_ifp
->pim_ifstat_bsm_tx
);
1557 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1558 json
, JSON_C_TO_STRING_PRETTY
));
1559 json_object_free(json
);
1563 static void pim_show_interface_traffic_single(struct pim_instance
*pim
,
1565 const char *ifname
, bool uj
)
1567 struct interface
*ifp
= NULL
;
1568 struct pim_interface
*pim_ifp
= NULL
;
1569 json_object
*json
= NULL
;
1570 json_object
*json_row
= NULL
;
1571 uint8_t found_ifname
= 0;
1574 json
= json_object_new_object();
1577 vty_out(vty
, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s%-17s\n",
1578 "Interface", " HELLO", " JOIN", " PRUNE",
1579 " REGISTER", " REGISTER-STOP", " ASSERT",
1581 vty_out(vty
, "%-14s%-18s%-17s%-17s%-17s%-17s%-17s%-17s\n", "",
1582 " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1583 " Rx/Tx", " Rx/Tx", " Rx/Tx");
1585 "-------------------------------------------------------------------------------------------------------------------------------\n");
1588 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1589 if (strcmp(ifname
, ifp
->name
))
1592 pim_ifp
= ifp
->info
;
1597 if (pim_ifp
->pim_sock_fd
< 0)
1602 json_row
= json_object_new_object();
1603 json_object_pim_ifp_add(json_row
, ifp
);
1604 json_object_int_add(json_row
, "helloRx",
1605 pim_ifp
->pim_ifstat_hello_recv
);
1606 json_object_int_add(json_row
, "helloTx",
1607 pim_ifp
->pim_ifstat_hello_sent
);
1608 json_object_int_add(json_row
, "joinRx",
1609 pim_ifp
->pim_ifstat_join_recv
);
1610 json_object_int_add(json_row
, "joinTx",
1611 pim_ifp
->pim_ifstat_join_send
);
1612 json_object_int_add(json_row
, "registerRx",
1613 pim_ifp
->pim_ifstat_reg_recv
);
1614 json_object_int_add(json_row
, "registerTx",
1615 pim_ifp
->pim_ifstat_reg_recv
);
1616 json_object_int_add(json_row
, "registerStopRx",
1617 pim_ifp
->pim_ifstat_reg_stop_recv
);
1618 json_object_int_add(json_row
, "registerStopTx",
1619 pim_ifp
->pim_ifstat_reg_stop_send
);
1620 json_object_int_add(json_row
, "assertRx",
1621 pim_ifp
->pim_ifstat_assert_recv
);
1622 json_object_int_add(json_row
, "assertTx",
1623 pim_ifp
->pim_ifstat_assert_send
);
1624 json_object_int_add(json_row
, "bsmRx",
1625 pim_ifp
->pim_ifstat_bsm_rx
);
1626 json_object_int_add(json_row
, "bsmTx",
1627 pim_ifp
->pim_ifstat_bsm_tx
);
1629 json_object_object_add(json
, ifp
->name
, json_row
);
1632 "%-16s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7lu/%-7lu \n",
1633 ifp
->name
, pim_ifp
->pim_ifstat_hello_recv
,
1634 pim_ifp
->pim_ifstat_hello_sent
,
1635 pim_ifp
->pim_ifstat_join_recv
,
1636 pim_ifp
->pim_ifstat_join_send
,
1637 pim_ifp
->pim_ifstat_prune_recv
,
1638 pim_ifp
->pim_ifstat_prune_send
,
1639 pim_ifp
->pim_ifstat_reg_recv
,
1640 pim_ifp
->pim_ifstat_reg_send
,
1641 pim_ifp
->pim_ifstat_reg_stop_recv
,
1642 pim_ifp
->pim_ifstat_reg_stop_send
,
1643 pim_ifp
->pim_ifstat_assert_recv
,
1644 pim_ifp
->pim_ifstat_assert_send
,
1645 pim_ifp
->pim_ifstat_bsm_rx
,
1646 pim_ifp
->pim_ifstat_bsm_tx
);
1650 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1651 json
, JSON_C_TO_STRING_PRETTY
));
1652 json_object_free(json
);
1655 vty_out(vty
, "%% No such interface\n");
1659 static void pim_show_join_helper(struct vty
*vty
, struct pim_interface
*pim_ifp
,
1660 struct pim_ifchannel
*ch
, json_object
*json
,
1661 time_t now
, bool uj
)
1663 char ch_src_str
[INET_ADDRSTRLEN
];
1664 char ch_grp_str
[INET_ADDRSTRLEN
];
1665 json_object
*json_iface
= NULL
;
1666 json_object
*json_row
= NULL
;
1667 json_object
*json_grp
= NULL
;
1668 struct in_addr ifaddr
;
1673 ifaddr
= pim_ifp
->primary_address
;
1675 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
1676 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
1678 pim_time_uptime_begin(uptime
, sizeof(uptime
), now
, ch
->ifjoin_creation
);
1679 pim_time_timer_to_mmss(expire
, sizeof(expire
),
1680 ch
->t_ifjoin_expiry_timer
);
1681 pim_time_timer_to_mmss(prune
, sizeof(prune
),
1682 ch
->t_ifjoin_prune_pending_timer
);
1685 json_object_object_get_ex(json
, ch
->interface
->name
,
1689 json_iface
= json_object_new_object();
1690 json_object_pim_ifp_add(json_iface
, ch
->interface
);
1691 json_object_object_add(json
, ch
->interface
->name
,
1695 json_row
= json_object_new_object();
1696 json_object_string_add(json_row
, "source", ch_src_str
);
1697 json_object_string_add(json_row
, "group", ch_grp_str
);
1698 json_object_string_add(json_row
, "upTime", uptime
);
1699 json_object_string_add(json_row
, "expire", expire
);
1700 json_object_string_add(json_row
, "prune", prune
);
1701 json_object_string_add(
1702 json_row
, "channelJoinName",
1703 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
, ch
->flags
));
1704 if (PIM_IF_FLAG_TEST_S_G_RPT(ch
->flags
))
1705 json_object_int_add(json_row
, "SGRpt", 1);
1707 json_object_object_get_ex(json_iface
, ch_grp_str
, &json_grp
);
1709 json_grp
= json_object_new_object();
1710 json_object_object_add(json_grp
, ch_src_str
, json_row
);
1711 json_object_object_add(json_iface
, ch_grp_str
,
1714 json_object_object_add(json_grp
, ch_src_str
, json_row
);
1716 vty_out(vty
, "%-16s %-15s %-15s %-15s %-10s %8s %-6s %5s\n",
1717 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
,
1719 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
, ch
->flags
),
1720 uptime
, expire
, prune
);
1724 static void pim_show_join(struct pim_instance
*pim
, struct vty
*vty
,
1725 struct prefix_sg
*sg
, bool uj
)
1727 struct pim_interface
*pim_ifp
;
1728 struct pim_ifchannel
*ch
;
1729 struct interface
*ifp
;
1731 json_object
*json
= NULL
;
1733 now
= pim_time_monotonic_sec();
1736 json
= json_object_new_object();
1739 "Interface Address Source Group State Uptime Expire Prune\n");
1741 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1742 pim_ifp
= ifp
->info
;
1746 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
1747 if (sg
->grp
.s_addr
!= 0
1748 && sg
->grp
.s_addr
!= ch
->sg
.grp
.s_addr
)
1750 if (sg
->src
.s_addr
!= 0
1751 && sg
->src
.s_addr
!= ch
->sg
.src
.s_addr
)
1753 pim_show_join_helper(vty
, pim_ifp
, ch
, json
, now
, uj
);
1754 } /* scan interface channels */
1758 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1759 json
, JSON_C_TO_STRING_PRETTY
));
1760 json_object_free(json
);
1764 static void pim_show_neighbors_single(struct pim_instance
*pim
, struct vty
*vty
,
1765 const char *neighbor
, bool uj
)
1767 struct listnode
*neighnode
;
1768 struct interface
*ifp
;
1769 struct pim_interface
*pim_ifp
;
1770 struct pim_neighbor
*neigh
;
1772 int found_neighbor
= 0;
1773 int option_address_list
;
1774 int option_dr_priority
;
1775 int option_generation_id
;
1776 int option_holdtime
;
1777 int option_lan_prune_delay
;
1781 char neigh_src_str
[INET_ADDRSTRLEN
];
1783 json_object
*json
= NULL
;
1784 json_object
*json_ifp
= NULL
;
1785 json_object
*json_row
= NULL
;
1787 now
= pim_time_monotonic_sec();
1790 json
= json_object_new_object();
1792 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1793 pim_ifp
= ifp
->info
;
1798 if (pim_ifp
->pim_sock_fd
< 0)
1801 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
1803 pim_inet4_dump("<src?>", neigh
->source_addr
,
1804 neigh_src_str
, sizeof(neigh_src_str
));
1807 * The user can specify either the interface name or the
1809 * If this pim_ifp matches neither then skip.
1811 if (strcmp(neighbor
, "detail")
1812 && strcmp(neighbor
, ifp
->name
)
1813 && strcmp(neighbor
, neigh_src_str
))
1817 pim_time_uptime(uptime
, sizeof(uptime
),
1818 now
- neigh
->creation
);
1819 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
1820 neigh
->t_expire_timer
);
1822 option_address_list
= 0;
1823 option_dr_priority
= 0;
1824 option_generation_id
= 0;
1825 option_holdtime
= 0;
1826 option_lan_prune_delay
= 0;
1829 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1830 PIM_OPTION_MASK_ADDRESS_LIST
))
1831 option_address_list
= 1;
1833 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1834 PIM_OPTION_MASK_DR_PRIORITY
))
1835 option_dr_priority
= 1;
1837 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1838 PIM_OPTION_MASK_GENERATION_ID
))
1839 option_generation_id
= 1;
1841 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1842 PIM_OPTION_MASK_HOLDTIME
))
1843 option_holdtime
= 1;
1845 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1846 PIM_OPTION_MASK_LAN_PRUNE_DELAY
))
1847 option_lan_prune_delay
= 1;
1849 if (PIM_OPTION_IS_SET(
1850 neigh
->hello_options
,
1851 PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION
))
1856 /* Does this ifp live in json? If not create
1858 json_object_object_get_ex(json
, ifp
->name
,
1862 json_ifp
= json_object_new_object();
1863 json_object_pim_ifp_add(json_ifp
, ifp
);
1864 json_object_object_add(json
, ifp
->name
,
1868 json_row
= json_object_new_object();
1869 json_object_string_add(json_row
, "interface",
1871 json_object_string_add(json_row
, "address",
1873 json_object_string_add(json_row
, "upTime",
1875 json_object_string_add(json_row
, "holdtime",
1877 json_object_int_add(json_row
, "drPriority",
1878 neigh
->dr_priority
);
1879 json_object_int_add(json_row
, "generationId",
1880 neigh
->generation_id
);
1882 if (option_address_list
)
1883 json_object_boolean_true_add(
1885 "helloOptionAddressList");
1887 if (option_dr_priority
)
1888 json_object_boolean_true_add(
1890 "helloOptionDrPriority");
1892 if (option_generation_id
)
1893 json_object_boolean_true_add(
1895 "helloOptionGenerationId");
1897 if (option_holdtime
)
1898 json_object_boolean_true_add(
1900 "helloOptionHoldtime");
1902 if (option_lan_prune_delay
)
1903 json_object_boolean_true_add(
1905 "helloOptionLanPruneDelay");
1908 json_object_boolean_true_add(
1909 json_row
, "helloOptionTBit");
1911 json_object_object_add(json_ifp
, neigh_src_str
,
1915 vty_out(vty
, "Interface : %s\n", ifp
->name
);
1916 vty_out(vty
, "Neighbor : %s\n", neigh_src_str
);
1924 " DR Priority : %d\n",
1925 neigh
->dr_priority
);
1927 " Generation ID : %08x\n",
1928 neigh
->generation_id
);
1930 " Override Interval (msec) : %d\n",
1931 neigh
->override_interval_msec
);
1933 " Propagation Delay (msec) : %d\n",
1934 neigh
->propagation_delay_msec
);
1936 " Hello Option - Address List : %s\n",
1937 option_address_list
? "yes" : "no");
1939 " Hello Option - DR Priority : %s\n",
1940 option_dr_priority
? "yes" : "no");
1942 " Hello Option - Generation ID : %s\n",
1943 option_generation_id
? "yes" : "no");
1945 " Hello Option - Holdtime : %s\n",
1946 option_holdtime
? "yes" : "no");
1948 " Hello Option - LAN Prune Delay : %s\n",
1949 option_lan_prune_delay
? "yes" : "no");
1951 " Hello Option - T-bit : %s\n",
1952 option_t_bit
? "yes" : "no");
1953 pim_bfd_show_info(vty
, neigh
->bfd_info
,
1961 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1962 json
, JSON_C_TO_STRING_PRETTY
));
1963 json_object_free(json
);
1966 if (!found_neighbor
)
1968 "%% No such interface or neighbor\n");
1973 static void pim_show_state(struct pim_instance
*pim
, struct vty
*vty
,
1974 const char *src_or_group
, const char *group
, bool uj
)
1976 struct channel_oil
*c_oil
;
1977 struct listnode
*node
;
1978 json_object
*json
= NULL
;
1979 json_object
*json_group
= NULL
;
1980 json_object
*json_ifp_in
= NULL
;
1981 json_object
*json_ifp_out
= NULL
;
1982 json_object
*json_source
= NULL
;
1985 now
= pim_time_monotonic_sec();
1988 json
= json_object_new_object();
1991 "Codes: J -> Pim Join, I -> IGMP Report, S -> Source, * -> Inherited from (*,G), V -> VxLAN");
1993 "\nInstalled Source Group IIF OIL\n");
1996 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
1997 char grp_str
[INET_ADDRSTRLEN
];
1998 char src_str
[INET_ADDRSTRLEN
];
1999 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
2000 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
2002 struct interface
*ifp_in
;
2005 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
2007 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
2009 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
2012 strlcpy(in_ifname
, ifp_in
->name
, sizeof(in_ifname
));
2014 strlcpy(in_ifname
, "<iif?>", sizeof(in_ifname
));
2017 if (strcmp(src_or_group
, src_str
)
2018 && strcmp(src_or_group
, grp_str
))
2021 if (group
&& strcmp(group
, grp_str
))
2027 /* Find the group, create it if it doesn't exist */
2028 json_object_object_get_ex(json
, grp_str
, &json_group
);
2031 json_group
= json_object_new_object();
2032 json_object_object_add(json
, grp_str
,
2036 /* Find the source nested under the group, create it if
2037 * it doesn't exist */
2038 json_object_object_get_ex(json_group
, src_str
,
2042 json_source
= json_object_new_object();
2043 json_object_object_add(json_group
, src_str
,
2047 /* Find the inbound interface nested under the source,
2048 * create it if it doesn't exist */
2049 json_object_object_get_ex(json_source
, in_ifname
,
2053 json_ifp_in
= json_object_new_object();
2054 json_object_object_add(json_source
, in_ifname
,
2056 json_object_int_add(json_source
, "Installed",
2058 json_object_int_add(json_source
, "RefCount",
2059 c_oil
->oil_ref_count
);
2060 json_object_int_add(json_source
, "OilListSize",
2062 json_object_int_add(
2063 json_source
, "OilRescan",
2064 c_oil
->oil_inherited_rescan
);
2065 json_object_int_add(json_source
, "LastUsed",
2066 c_oil
->cc
.lastused
);
2067 json_object_int_add(json_source
, "PacketCount",
2069 json_object_int_add(json_source
, "ByteCount",
2071 json_object_int_add(json_source
,
2073 c_oil
->cc
.wrong_if
);
2076 vty_out(vty
, "%-9d %-15s %-15s %-16s ",
2077 c_oil
->installed
, src_str
, grp_str
, in_ifname
);
2080 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
2082 struct interface
*ifp_out
;
2083 char oif_uptime
[10];
2086 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
2090 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
2092 oif_uptime
, sizeof(oif_uptime
),
2093 now
- c_oil
->oif_creation
[oif_vif_index
]);
2096 strlcpy(out_ifname
, ifp_out
->name
, sizeof(out_ifname
));
2098 strlcpy(out_ifname
, "<oif?>", sizeof(out_ifname
));
2101 json_ifp_out
= json_object_new_object();
2102 json_object_string_add(json_ifp_out
, "source",
2104 json_object_string_add(json_ifp_out
, "group",
2106 json_object_string_add(json_ifp_out
,
2109 json_object_string_add(json_ifp_out
,
2110 "outboundInterface",
2112 json_object_int_add(json_ifp_out
, "installed",
2115 json_object_object_add(json_ifp_in
, out_ifname
,
2120 vty_out(vty
, "%s(%c%c%c%c%c)", out_ifname
,
2121 (c_oil
->oif_flags
[oif_vif_index
]
2122 & PIM_OIF_FLAG_PROTO_IGMP
)
2125 (c_oil
->oif_flags
[oif_vif_index
]
2126 & PIM_OIF_FLAG_PROTO_PIM
)
2129 (c_oil
->oif_flags
[oif_vif_index
]
2130 & PIM_OIF_FLAG_PROTO_VXLAN
)
2133 (c_oil
->oif_flags
[oif_vif_index
]
2134 & PIM_OIF_FLAG_PROTO_SOURCE
)
2137 (c_oil
->oif_flags
[oif_vif_index
]
2138 & PIM_OIF_FLAG_PROTO_STAR
)
2142 vty_out(vty
, ", %s(%c%c%c%c%c)",
2144 (c_oil
->oif_flags
[oif_vif_index
]
2145 & PIM_OIF_FLAG_PROTO_IGMP
)
2148 (c_oil
->oif_flags
[oif_vif_index
]
2149 & PIM_OIF_FLAG_PROTO_PIM
)
2152 (c_oil
->oif_flags
[oif_vif_index
]
2153 & PIM_OIF_FLAG_PROTO_VXLAN
)
2156 (c_oil
->oif_flags
[oif_vif_index
]
2157 & PIM_OIF_FLAG_PROTO_SOURCE
)
2160 (c_oil
->oif_flags
[oif_vif_index
]
2161 & PIM_OIF_FLAG_PROTO_STAR
)
2173 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2174 json
, JSON_C_TO_STRING_PRETTY
));
2175 json_object_free(json
);
2181 static void pim_show_neighbors(struct pim_instance
*pim
, struct vty
*vty
,
2184 struct listnode
*neighnode
;
2185 struct interface
*ifp
;
2186 struct pim_interface
*pim_ifp
;
2187 struct pim_neighbor
*neigh
;
2191 char neigh_src_str
[INET_ADDRSTRLEN
];
2192 json_object
*json
= NULL
;
2193 json_object
*json_ifp_rows
= NULL
;
2194 json_object
*json_row
= NULL
;
2196 now
= pim_time_monotonic_sec();
2199 json
= json_object_new_object();
2202 "Interface Neighbor Uptime Holdtime DR Pri\n");
2205 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2206 pim_ifp
= ifp
->info
;
2211 if (pim_ifp
->pim_sock_fd
< 0)
2215 json_ifp_rows
= json_object_new_object();
2217 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
2219 pim_inet4_dump("<src?>", neigh
->source_addr
,
2220 neigh_src_str
, sizeof(neigh_src_str
));
2221 pim_time_uptime(uptime
, sizeof(uptime
),
2222 now
- neigh
->creation
);
2223 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
2224 neigh
->t_expire_timer
);
2227 json_row
= json_object_new_object();
2228 json_object_string_add(json_row
, "interface",
2230 json_object_string_add(json_row
, "neighbor",
2232 json_object_string_add(json_row
, "upTime",
2234 json_object_string_add(json_row
, "holdTime",
2236 json_object_int_add(json_row
, "holdTimeMax",
2238 json_object_int_add(json_row
, "drPriority",
2239 neigh
->dr_priority
);
2240 json_object_object_add(json_ifp_rows
,
2241 neigh_src_str
, json_row
);
2244 vty_out(vty
, "%-16s %15s %8s %8s %6d\n",
2245 ifp
->name
, neigh_src_str
, uptime
,
2246 expire
, neigh
->dr_priority
);
2251 json_object_object_add(json
, ifp
->name
, json_ifp_rows
);
2252 json_ifp_rows
= NULL
;
2257 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2258 json
, JSON_C_TO_STRING_PRETTY
));
2259 json_object_free(json
);
2263 static void pim_show_neighbors_secondary(struct pim_instance
*pim
,
2266 struct interface
*ifp
;
2269 "Interface Address Neighbor Secondary \n");
2271 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2272 struct pim_interface
*pim_ifp
;
2273 struct in_addr ifaddr
;
2274 struct listnode
*neighnode
;
2275 struct pim_neighbor
*neigh
;
2277 pim_ifp
= ifp
->info
;
2282 if (pim_ifp
->pim_sock_fd
< 0)
2285 ifaddr
= pim_ifp
->primary_address
;
2287 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
2289 char neigh_src_str
[INET_ADDRSTRLEN
];
2290 struct listnode
*prefix_node
;
2293 if (!neigh
->prefix_list
)
2296 pim_inet4_dump("<src?>", neigh
->source_addr
,
2297 neigh_src_str
, sizeof(neigh_src_str
));
2299 for (ALL_LIST_ELEMENTS_RO(neigh
->prefix_list
,
2301 char neigh_sec_str
[PREFIX2STR_BUFFER
];
2303 prefix2str(p
, neigh_sec_str
,
2304 sizeof(neigh_sec_str
));
2306 vty_out(vty
, "%-16s %-15s %-15s %-15s\n",
2307 ifp
->name
, inet_ntoa(ifaddr
),
2308 neigh_src_str
, neigh_sec_str
);
2314 static void json_object_pim_upstream_add(json_object
*json
,
2315 struct pim_upstream
*up
)
2317 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED
)
2318 json_object_boolean_true_add(json
, "drJoinDesired");
2320 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED
)
2321 json_object_boolean_true_add(json
, "drJoinDesiredUpdated");
2323 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
2324 json_object_boolean_true_add(json
, "firstHopRouter");
2326 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_IGMP
)
2327 json_object_boolean_true_add(json
, "sourceIgmp");
2329 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_PIM
)
2330 json_object_boolean_true_add(json
, "sourcePim");
2332 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_STREAM
)
2333 json_object_boolean_true_add(json
, "sourceStream");
2335 /* XXX: need to print ths flag in the plain text display as well */
2336 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_MSDP
)
2337 json_object_boolean_true_add(json
, "sourceMsdp");
2339 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SEND_SG_RPT_PRUNE
)
2340 json_object_boolean_true_add(json
, "sendSGRptPrune");
2342 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_LHR
)
2343 json_object_boolean_true_add(json
, "lastHopRouter");
2345 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DISABLE_KAT_EXPIRY
)
2346 json_object_boolean_true_add(json
, "disableKATExpiry");
2348 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_STATIC_IIF
)
2349 json_object_boolean_true_add(json
, "staticIncomingInterface");
2351 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_ALLOW_IIF_IN_OIL
)
2352 json_object_boolean_true_add(json
,
2353 "allowIncomingInterfaceinOil");
2355 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_NO_PIMREG_DATA
)
2356 json_object_boolean_true_add(json
, "noPimRegistrationData");
2358 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FORCE_PIMREG
)
2359 json_object_boolean_true_add(json
, "forcePimRegistration");
2361 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_ORIG
)
2362 json_object_boolean_true_add(json
, "sourceVxlanOrigination");
2364 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_TERM
)
2365 json_object_boolean_true_add(json
, "sourceVxlanTermination");
2367 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_VXLAN
)
2368 json_object_boolean_true_add(json
, "mlagVxlan");
2370 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_NON_DF
)
2371 json_object_boolean_true_add(json
,
2372 "mlagNonDesignatedForwarder");
2376 pim_upstream_state2brief_str(enum pim_upstream_state join_state
,
2377 char *state_str
, size_t state_str_len
)
2379 switch (join_state
) {
2380 case PIM_UPSTREAM_NOTJOINED
:
2381 strlcpy(state_str
, "NotJ", state_str_len
);
2383 case PIM_UPSTREAM_JOINED
:
2384 strlcpy(state_str
, "J", state_str_len
);
2387 strlcpy(state_str
, "Unk", state_str_len
);
2392 static const char *pim_reg_state2brief_str(enum pim_reg_state reg_state
,
2393 char *state_str
, size_t state_str_len
)
2395 switch (reg_state
) {
2396 case PIM_REG_NOINFO
:
2397 strlcpy(state_str
, "RegNI", state_str_len
);
2400 strlcpy(state_str
, "RegJ", state_str_len
);
2402 case PIM_REG_JOIN_PENDING
:
2404 strlcpy(state_str
, "RegP", state_str_len
);
2407 strlcpy(state_str
, "Unk", state_str_len
);
2412 static void pim_show_upstream(struct pim_instance
*pim
, struct vty
*vty
,
2413 struct prefix_sg
*sg
, bool uj
)
2415 struct listnode
*upnode
;
2416 struct pim_upstream
*up
;
2418 json_object
*json
= NULL
;
2419 json_object
*json_group
= NULL
;
2420 json_object
*json_row
= NULL
;
2422 now
= pim_time_monotonic_sec();
2425 json
= json_object_new_object();
2428 "Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt\n");
2430 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
, up
)) {
2431 char src_str
[INET_ADDRSTRLEN
];
2432 char grp_str
[INET_ADDRSTRLEN
];
2434 char join_timer
[10];
2437 char msdp_reg_timer
[10];
2438 char state_str
[PIM_REG_STATE_STR_LEN
];
2440 if (sg
->grp
.s_addr
!= 0 && sg
->grp
.s_addr
!= up
->sg
.grp
.s_addr
)
2442 if (sg
->src
.s_addr
!= 0 && sg
->src
.s_addr
!= up
->sg
.src
.s_addr
)
2445 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2446 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2447 pim_time_uptime(uptime
, sizeof(uptime
),
2448 now
- up
->state_transition
);
2449 pim_time_timer_to_hhmmss(join_timer
, sizeof(join_timer
),
2453 * If the upstream is not dummy and it has a J/P timer for the
2454 * neighbor display that
2456 if (!up
->t_join_timer
&& up
->rpf
.source_nexthop
.interface
) {
2457 struct pim_neighbor
*nbr
;
2459 nbr
= pim_neighbor_find(
2460 up
->rpf
.source_nexthop
.interface
,
2461 up
->rpf
.rpf_addr
.u
.prefix4
);
2463 pim_time_timer_to_hhmmss(join_timer
,
2468 pim_time_timer_to_hhmmss(rs_timer
, sizeof(rs_timer
),
2470 pim_time_timer_to_hhmmss(ka_timer
, sizeof(ka_timer
),
2472 pim_time_timer_to_hhmmss(msdp_reg_timer
, sizeof(msdp_reg_timer
),
2473 up
->t_msdp_reg_timer
);
2475 pim_upstream_state2brief_str(up
->join_state
, state_str
, sizeof(state_str
));
2476 if (up
->reg_state
!= PIM_REG_NOINFO
) {
2477 char tmp_str
[PIM_REG_STATE_STR_LEN
];
2479 sprintf(state_str
+ strlen(state_str
), ",%s",
2480 pim_reg_state2brief_str(up
->reg_state
, tmp_str
,
2485 json_object_object_get_ex(json
, grp_str
, &json_group
);
2488 json_group
= json_object_new_object();
2489 json_object_object_add(json
, grp_str
,
2493 json_row
= json_object_new_object();
2494 json_object_pim_upstream_add(json_row
, up
);
2495 json_object_string_add(
2496 json_row
, "inboundInterface",
2497 up
->rpf
.source_nexthop
.interface
2498 ? up
->rpf
.source_nexthop
.interface
->name
2502 * The RPF address we use is slightly different
2503 * based upon what we are looking up.
2504 * If we have a S, list that unless
2505 * we are the FHR, else we just put
2506 * the RP as the rpfAddress
2508 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
2509 || up
->sg
.src
.s_addr
== INADDR_ANY
) {
2510 char rpf
[PREFIX_STRLEN
];
2511 struct pim_rpf
*rpg
;
2513 rpg
= RP(pim
, up
->sg
.grp
);
2514 pim_inet4_dump("<rpf?>",
2515 rpg
->rpf_addr
.u
.prefix4
, rpf
,
2517 json_object_string_add(json_row
, "rpfAddress",
2520 json_object_string_add(json_row
, "rpfAddress",
2524 json_object_string_add(json_row
, "source", src_str
);
2525 json_object_string_add(json_row
, "group", grp_str
);
2526 json_object_string_add(json_row
, "state", state_str
);
2527 json_object_string_add(
2528 json_row
, "joinState",
2529 pim_upstream_state2str(up
->join_state
));
2530 json_object_string_add(
2531 json_row
, "regState",
2532 pim_reg_state2str(up
->reg_state
, state_str
, sizeof(state_str
)));
2533 json_object_string_add(json_row
, "upTime", uptime
);
2534 json_object_string_add(json_row
, "joinTimer",
2536 json_object_string_add(json_row
, "resetTimer",
2538 json_object_string_add(json_row
, "keepaliveTimer",
2540 json_object_string_add(json_row
, "msdpRegTimer",
2542 json_object_int_add(json_row
, "refCount",
2544 json_object_int_add(json_row
, "sptBit", up
->sptbit
);
2545 json_object_object_add(json_group
, src_str
, json_row
);
2548 "%-16s%-15s %-15s %-11s %-8s %-9s %-9s %-9s %6d\n",
2549 up
->rpf
.source_nexthop
.interface
2550 ? up
->rpf
.source_nexthop
.interface
->name
2552 src_str
, grp_str
, state_str
, uptime
, join_timer
,
2553 rs_timer
, ka_timer
, up
->ref_count
);
2558 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2559 json
, JSON_C_TO_STRING_PRETTY
));
2560 json_object_free(json
);
2564 static void pim_show_join_desired_helper(struct pim_instance
*pim
,
2566 struct pim_interface
*pim_ifp
,
2567 struct pim_ifchannel
*ch
,
2568 json_object
*json
, bool uj
)
2570 struct pim_upstream
*up
= ch
->upstream
;
2571 json_object
*json_group
= NULL
;
2572 char src_str
[INET_ADDRSTRLEN
];
2573 char grp_str
[INET_ADDRSTRLEN
];
2574 json_object
*json_row
= NULL
;
2576 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2577 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2580 json_object_object_get_ex(json
, grp_str
, &json_group
);
2583 json_group
= json_object_new_object();
2584 json_object_object_add(json
, grp_str
, json_group
);
2587 json_row
= json_object_new_object();
2588 json_object_pim_upstream_add(json_row
, up
);
2589 json_object_string_add(json_row
, "interface",
2590 ch
->interface
->name
);
2591 json_object_string_add(json_row
, "source", src_str
);
2592 json_object_string_add(json_row
, "group", grp_str
);
2594 if (pim_macro_ch_lost_assert(ch
))
2595 json_object_boolean_true_add(json_row
, "lostAssert");
2597 if (pim_macro_chisin_joins(ch
))
2598 json_object_boolean_true_add(json_row
, "joins");
2600 if (pim_macro_chisin_pim_include(ch
))
2601 json_object_boolean_true_add(json_row
, "pimInclude");
2603 if (pim_upstream_evaluate_join_desired(pim
, up
))
2604 json_object_boolean_true_add(json_row
,
2605 "evaluateJoinDesired");
2607 json_object_object_add(json_group
, src_str
, json_row
);
2610 vty_out(vty
, "%-16s %-15s %-15s %-10s %-5s %-10s %-11s %-6s\n",
2611 ch
->interface
->name
, src_str
, grp_str
,
2612 pim_macro_ch_lost_assert(ch
) ? "yes" : "no",
2613 pim_macro_chisin_joins(ch
) ? "yes" : "no",
2614 pim_macro_chisin_pim_include(ch
) ? "yes" : "no",
2615 PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(up
->flags
)
2618 pim_upstream_evaluate_join_desired(pim
, up
) ? "yes"
2623 static void pim_show_join_desired(struct pim_instance
*pim
, struct vty
*vty
,
2626 struct pim_interface
*pim_ifp
;
2627 struct pim_ifchannel
*ch
;
2628 struct interface
*ifp
;
2630 json_object
*json
= NULL
;
2633 json
= json_object_new_object();
2636 "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD\n");
2638 /* scan per-interface (S,G) state */
2639 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2640 pim_ifp
= ifp
->info
;
2645 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
2646 /* scan all interfaces */
2647 pim_show_join_desired_helper(pim
, vty
, pim_ifp
, ch
,
2653 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2654 json
, JSON_C_TO_STRING_PRETTY
));
2655 json_object_free(json
);
2659 static void pim_show_upstream_rpf(struct pim_instance
*pim
, struct vty
*vty
,
2662 struct listnode
*upnode
;
2663 struct pim_upstream
*up
;
2664 json_object
*json
= NULL
;
2665 json_object
*json_group
= NULL
;
2666 json_object
*json_row
= NULL
;
2669 json
= json_object_new_object();
2672 "Source Group RpfIface RibNextHop RpfAddress \n");
2674 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
, up
)) {
2675 char src_str
[INET_ADDRSTRLEN
];
2676 char grp_str
[INET_ADDRSTRLEN
];
2677 char rpf_nexthop_str
[PREFIX_STRLEN
];
2678 char rpf_addr_str
[PREFIX_STRLEN
];
2679 struct pim_rpf
*rpf
;
2680 const char *rpf_ifname
;
2684 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2685 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2686 pim_addr_dump("<nexthop?>",
2687 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2688 rpf_nexthop_str
, sizeof(rpf_nexthop_str
));
2689 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2690 sizeof(rpf_addr_str
));
2692 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2695 json_object_object_get_ex(json
, grp_str
, &json_group
);
2698 json_group
= json_object_new_object();
2699 json_object_object_add(json
, grp_str
,
2703 json_row
= json_object_new_object();
2704 json_object_pim_upstream_add(json_row
, up
);
2705 json_object_string_add(json_row
, "source", src_str
);
2706 json_object_string_add(json_row
, "group", grp_str
);
2707 json_object_string_add(json_row
, "rpfInterface",
2709 json_object_string_add(json_row
, "ribNexthop",
2711 json_object_string_add(json_row
, "rpfAddress",
2713 json_object_object_add(json_group
, src_str
, json_row
);
2715 vty_out(vty
, "%-15s %-15s %-16s %-15s %-15s\n", src_str
,
2716 grp_str
, rpf_ifname
, rpf_nexthop_str
,
2722 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2723 json
, JSON_C_TO_STRING_PRETTY
));
2724 json_object_free(json
);
2728 static void show_rpf_refresh_stats(struct vty
*vty
, struct pim_instance
*pim
,
2729 time_t now
, json_object
*json
)
2731 char refresh_uptime
[10];
2733 pim_time_uptime_begin(refresh_uptime
, sizeof(refresh_uptime
), now
,
2734 pim
->rpf_cache_refresh_last
);
2737 json_object_int_add(json
, "rpfCacheRefreshDelayMsecs",
2738 router
->rpf_cache_refresh_delay_msec
);
2739 json_object_int_add(
2740 json
, "rpfCacheRefreshTimer",
2741 pim_time_timer_remain_msec(pim
->rpf_cache_refresher
));
2742 json_object_int_add(json
, "rpfCacheRefreshRequests",
2743 pim
->rpf_cache_refresh_requests
);
2744 json_object_int_add(json
, "rpfCacheRefreshEvents",
2745 pim
->rpf_cache_refresh_events
);
2746 json_object_string_add(json
, "rpfCacheRefreshLast",
2748 json_object_int_add(json
, "nexthopLookups",
2749 pim
->nexthop_lookups
);
2750 json_object_int_add(json
, "nexthopLookupsAvoided",
2751 pim
->nexthop_lookups_avoided
);
2754 "RPF Cache Refresh Delay: %ld msecs\n"
2755 "RPF Cache Refresh Timer: %ld msecs\n"
2756 "RPF Cache Refresh Requests: %lld\n"
2757 "RPF Cache Refresh Events: %lld\n"
2758 "RPF Cache Refresh Last: %s\n"
2759 "Nexthop Lookups: %lld\n"
2760 "Nexthop Lookups Avoided: %lld\n",
2761 router
->rpf_cache_refresh_delay_msec
,
2762 pim_time_timer_remain_msec(pim
->rpf_cache_refresher
),
2763 (long long)pim
->rpf_cache_refresh_requests
,
2764 (long long)pim
->rpf_cache_refresh_events
,
2765 refresh_uptime
, (long long)pim
->nexthop_lookups
,
2766 (long long)pim
->nexthop_lookups_avoided
);
2770 static void show_scan_oil_stats(struct pim_instance
*pim
, struct vty
*vty
,
2773 char uptime_scan_oil
[10];
2774 char uptime_mroute_add
[10];
2775 char uptime_mroute_del
[10];
2777 pim_time_uptime_begin(uptime_scan_oil
, sizeof(uptime_scan_oil
), now
,
2778 pim
->scan_oil_last
);
2779 pim_time_uptime_begin(uptime_mroute_add
, sizeof(uptime_mroute_add
), now
,
2780 pim
->mroute_add_last
);
2781 pim_time_uptime_begin(uptime_mroute_del
, sizeof(uptime_mroute_del
), now
,
2782 pim
->mroute_del_last
);
2785 "Scan OIL - Last: %s Events: %lld\n"
2786 "MFC Add - Last: %s Events: %lld\n"
2787 "MFC Del - Last: %s Events: %lld\n",
2788 uptime_scan_oil
, (long long)pim
->scan_oil_events
,
2789 uptime_mroute_add
, (long long)pim
->mroute_add_events
,
2790 uptime_mroute_del
, (long long)pim
->mroute_del_events
);
2793 static void pim_show_rpf(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
2795 struct listnode
*up_node
;
2796 struct pim_upstream
*up
;
2797 time_t now
= pim_time_monotonic_sec();
2798 json_object
*json
= NULL
;
2799 json_object
*json_group
= NULL
;
2800 json_object
*json_row
= NULL
;
2803 json
= json_object_new_object();
2804 show_rpf_refresh_stats(vty
, pim
, now
, json
);
2806 show_rpf_refresh_stats(vty
, pim
, now
, json
);
2809 "Source Group RpfIface RpfAddress RibNextHop Metric Pref\n");
2812 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, up_node
, up
)) {
2813 char src_str
[INET_ADDRSTRLEN
];
2814 char grp_str
[INET_ADDRSTRLEN
];
2815 char rpf_addr_str
[PREFIX_STRLEN
];
2816 char rib_nexthop_str
[PREFIX_STRLEN
];
2817 const char *rpf_ifname
;
2818 struct pim_rpf
*rpf
= &up
->rpf
;
2820 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2821 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2822 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2823 sizeof(rpf_addr_str
));
2824 pim_addr_dump("<nexthop?>",
2825 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2826 rib_nexthop_str
, sizeof(rib_nexthop_str
));
2828 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2831 json_object_object_get_ex(json
, grp_str
, &json_group
);
2834 json_group
= json_object_new_object();
2835 json_object_object_add(json
, grp_str
,
2839 json_row
= json_object_new_object();
2840 json_object_string_add(json_row
, "source", src_str
);
2841 json_object_string_add(json_row
, "group", grp_str
);
2842 json_object_string_add(json_row
, "rpfInterface",
2844 json_object_string_add(json_row
, "rpfAddress",
2846 json_object_string_add(json_row
, "ribNexthop",
2848 json_object_int_add(
2849 json_row
, "routeMetric",
2850 rpf
->source_nexthop
.mrib_route_metric
);
2851 json_object_int_add(
2852 json_row
, "routePreference",
2853 rpf
->source_nexthop
.mrib_metric_preference
);
2854 json_object_object_add(json_group
, src_str
, json_row
);
2857 vty_out(vty
, "%-15s %-15s %-16s %-15s %-15s %6d %4d\n",
2858 src_str
, grp_str
, rpf_ifname
, rpf_addr_str
,
2860 rpf
->source_nexthop
.mrib_route_metric
,
2861 rpf
->source_nexthop
.mrib_metric_preference
);
2866 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2867 json
, JSON_C_TO_STRING_PRETTY
));
2868 json_object_free(json
);
2872 struct pnc_cache_walk_data
{
2874 struct pim_instance
*pim
;
2877 static int pim_print_pnc_cache_walkcb(struct hash_bucket
*bucket
, void *arg
)
2879 struct pim_nexthop_cache
*pnc
= bucket
->data
;
2880 struct pnc_cache_walk_data
*cwd
= arg
;
2881 struct vty
*vty
= cwd
->vty
;
2882 struct pim_instance
*pim
= cwd
->pim
;
2883 struct nexthop
*nh_node
= NULL
;
2884 ifindex_t first_ifindex
;
2885 struct interface
*ifp
= NULL
;
2887 for (nh_node
= pnc
->nexthop
; nh_node
; nh_node
= nh_node
->next
) {
2888 first_ifindex
= nh_node
->ifindex
;
2889 ifp
= if_lookup_by_index(first_ifindex
, pim
->vrf_id
);
2891 vty_out(vty
, "%-15s ", inet_ntoa(pnc
->rpf
.rpf_addr
.u
.prefix4
));
2892 vty_out(vty
, "%-16s ", ifp
? ifp
->name
: "NULL");
2893 vty_out(vty
, "%s ", inet_ntoa(nh_node
->gate
.ipv4
));
2899 static void pim_show_nexthop(struct pim_instance
*pim
, struct vty
*vty
)
2901 struct pnc_cache_walk_data cwd
;
2905 vty_out(vty
, "Number of registered addresses: %lu\n",
2906 pim
->rpf_hash
->count
);
2907 vty_out(vty
, "Address Interface Nexthop\n");
2908 vty_out(vty
, "---------------------------------------------\n");
2910 hash_walk(pim
->rpf_hash
, pim_print_pnc_cache_walkcb
, &cwd
);
2913 /* Display the bsm database details */
2914 static void pim_show_bsm_db(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
2916 struct listnode
*bsmnode
;
2919 struct bsm_info
*bsm
;
2920 json_object
*json
= NULL
;
2921 json_object
*json_group
= NULL
;
2922 json_object
*json_row
= NULL
;
2924 count
= pim
->global_scope
.bsm_list
->count
;
2927 json
= json_object_new_object();
2928 json_object_int_add(json
, "Number of the fragments", count
);
2930 vty_out(vty
, "Scope Zone: Global\n");
2931 vty_out(vty
, "Number of the fragments: %d\n", count
);
2935 for (ALL_LIST_ELEMENTS_RO(pim
->global_scope
.bsm_list
, bsmnode
, bsm
)) {
2936 char grp_str
[INET_ADDRSTRLEN
];
2937 char rp_str
[INET_ADDRSTRLEN
];
2938 char bsr_str
[INET_ADDRSTRLEN
];
2939 struct bsmmsg_grpinfo
*group
;
2940 struct bsmmsg_rpinfo
*rpaddr
;
2942 struct bsm_hdr
*hdr
;
2943 uint32_t offset
= 0;
2946 uint32_t frag_rp_cnt
= 0;
2951 /* skip pim header */
2952 buf
+= PIM_MSG_HEADER_LEN
;
2953 len
-= PIM_MSG_HEADER_LEN
;
2955 hdr
= (struct bsm_hdr
*)buf
;
2957 /* BSM starts with bsr header */
2958 buf
+= sizeof(struct bsm_hdr
);
2959 len
-= sizeof(struct bsm_hdr
);
2961 pim_inet4_dump("<BSR Address?>", hdr
->bsr_addr
.addr
, bsr_str
,
2966 json_object_string_add(json
, "BSR address", bsr_str
);
2967 json_object_int_add(json
, "BSR priority",
2969 json_object_int_add(json
, "Hashmask Length",
2971 json_object_int_add(json
, "Fragment Tag",
2972 ntohs(hdr
->frag_tag
));
2974 vty_out(vty
, "BSM Fragment : %d\n", fragment
);
2975 vty_out(vty
, "------------------\n");
2976 vty_out(vty
, "%-15s %-15s %-15s %-15s\n", "BSR-Address",
2977 "BSR-Priority", "Hashmask-len", "Fragment-Tag");
2978 vty_out(vty
, "%-15s %-15d %-15d %-15d\n", bsr_str
,
2979 hdr
->bsr_prio
, hdr
->hm_len
,
2980 ntohs(hdr
->frag_tag
));
2985 while (offset
< len
) {
2986 group
= (struct bsmmsg_grpinfo
*)buf
;
2988 if (group
->group
.family
== PIM_MSG_ADDRESS_FAMILY_IPV4
)
2989 grp
.family
= AF_INET
;
2991 grp
.prefixlen
= group
->group
.mask
;
2992 grp
.u
.prefix4
.s_addr
= group
->group
.addr
.s_addr
;
2994 prefix2str(&grp
, grp_str
, sizeof(grp_str
));
2996 buf
+= sizeof(struct bsmmsg_grpinfo
);
2997 offset
+= sizeof(struct bsmmsg_grpinfo
);
3000 json_object_object_get_ex(json
, grp_str
,
3003 json_group
= json_object_new_object();
3004 json_object_int_add(json_group
,
3007 json_object_int_add(
3008 json_group
, "Fragment Rp count",
3009 group
->frag_rp_count
);
3010 json_object_object_add(json
, grp_str
,
3014 vty_out(vty
, "Group : %s\n", grp_str
);
3015 vty_out(vty
, "-------------------\n");
3016 vty_out(vty
, "Rp Count:%d\n", group
->rp_count
);
3017 vty_out(vty
, "Fragment Rp Count : %d\n",
3018 group
->frag_rp_count
);
3021 frag_rp_cnt
= group
->frag_rp_count
;
3028 "RpAddress HoldTime Priority\n");
3030 while (frag_rp_cnt
--) {
3031 rpaddr
= (struct bsmmsg_rpinfo
*)buf
;
3033 buf
+= sizeof(struct bsmmsg_rpinfo
);
3034 offset
+= sizeof(struct bsmmsg_rpinfo
);
3036 pim_inet4_dump("<Rp addr?>",
3037 rpaddr
->rpaddr
.addr
, rp_str
,
3041 json_row
= json_object_new_object();
3042 json_object_string_add(
3043 json_row
, "Rp Address", rp_str
);
3044 json_object_int_add(
3045 json_row
, "Rp HoldTime",
3046 ntohs(rpaddr
->rp_holdtime
));
3047 json_object_int_add(json_row
,
3050 json_object_object_add(
3051 json_group
, rp_str
, json_row
);
3053 vty_out(vty
, "%-15s %-12d %d\n", rp_str
,
3054 ntohs(rpaddr
->rp_holdtime
),
3065 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3066 json
, JSON_C_TO_STRING_PRETTY
));
3067 json_object_free(json
);
3071 /*Display the group-rp mappings */
3072 static void pim_show_group_rp_mappings_info(struct pim_instance
*pim
,
3073 struct vty
*vty
, bool uj
)
3075 struct bsgrp_node
*bsgrp
;
3076 struct listnode
*rpnode
;
3077 struct bsm_rpinfo
*bsm_rp
;
3078 struct route_node
*rn
;
3079 char bsr_str
[INET_ADDRSTRLEN
];
3080 json_object
*json
= NULL
;
3081 json_object
*json_group
= NULL
;
3082 json_object
*json_row
= NULL
;
3084 if (pim
->global_scope
.current_bsr
.s_addr
== INADDR_ANY
)
3085 strlcpy(bsr_str
, "0.0.0.0", sizeof(bsr_str
));
3088 pim_inet4_dump("<bsr?>", pim
->global_scope
.current_bsr
, bsr_str
,
3092 json
= json_object_new_object();
3093 json_object_string_add(json
, "BSR Address", bsr_str
);
3095 vty_out(vty
, "BSR Address %s\n", bsr_str
);
3098 for (rn
= route_top(pim
->global_scope
.bsrp_table
); rn
;
3099 rn
= route_next(rn
)) {
3100 bsgrp
= (struct bsgrp_node
*)rn
->info
;
3105 char grp_str
[INET_ADDRSTRLEN
];
3107 prefix2str(&bsgrp
->group
, grp_str
, sizeof(grp_str
));
3110 json_object_object_get_ex(json
, grp_str
, &json_group
);
3112 json_group
= json_object_new_object();
3113 json_object_object_add(json
, grp_str
,
3117 vty_out(vty
, "Group Address %s\n", grp_str
);
3118 vty_out(vty
, "--------------------------\n");
3119 vty_out(vty
, "%-15s %-15s %-15s %-15s\n", "Rp Address",
3120 "priority", "Holdtime", "Hash");
3122 vty_out(vty
, "(ACTIVE)\n");
3125 if (bsgrp
->bsrp_list
) {
3126 for (ALL_LIST_ELEMENTS_RO(bsgrp
->bsrp_list
, rpnode
,
3128 char rp_str
[INET_ADDRSTRLEN
];
3130 pim_inet4_dump("<Rp Address?>",
3131 bsm_rp
->rp_address
, rp_str
,
3135 json_row
= json_object_new_object();
3136 json_object_string_add(
3137 json_row
, "Rp Address", rp_str
);
3138 json_object_int_add(
3139 json_row
, "Rp HoldTime",
3140 bsm_rp
->rp_holdtime
);
3141 json_object_int_add(json_row
,
3144 json_object_int_add(json_row
,
3147 json_object_object_add(
3148 json_group
, rp_str
, json_row
);
3152 "%-15s %-15u %-15u %-15u\n",
3153 rp_str
, bsm_rp
->rp_prio
,
3154 bsm_rp
->rp_holdtime
,
3158 if (!bsgrp
->bsrp_list
->count
&& !uj
)
3159 vty_out(vty
, "Active List is empty.\n");
3163 json_object_int_add(json_group
, "Pending RP count",
3164 bsgrp
->pend_rp_cnt
);
3166 vty_out(vty
, "(PENDING)\n");
3167 vty_out(vty
, "Pending RP count :%d\n",
3168 bsgrp
->pend_rp_cnt
);
3169 if (bsgrp
->pend_rp_cnt
)
3170 vty_out(vty
, "%-15s %-15s %-15s %-15s\n",
3171 "Rp Address", "priority", "Holdtime",
3175 if (bsgrp
->partial_bsrp_list
) {
3176 for (ALL_LIST_ELEMENTS_RO(bsgrp
->partial_bsrp_list
,
3178 char rp_str
[INET_ADDRSTRLEN
];
3180 pim_inet4_dump("<Rp Addr?>", bsm_rp
->rp_address
,
3181 rp_str
, sizeof(rp_str
));
3184 json_row
= json_object_new_object();
3185 json_object_string_add(
3186 json_row
, "Rp Address", rp_str
);
3187 json_object_int_add(
3188 json_row
, "Rp HoldTime",
3189 bsm_rp
->rp_holdtime
);
3190 json_object_int_add(json_row
,
3193 json_object_int_add(json_row
,
3196 json_object_object_add(
3197 json_group
, rp_str
, json_row
);
3200 "%-15s %-15u %-15u %-15u\n",
3201 rp_str
, bsm_rp
->rp_prio
,
3202 bsm_rp
->rp_holdtime
,
3206 if (!bsgrp
->partial_bsrp_list
->count
&& !uj
)
3207 vty_out(vty
, "Partial List is empty\n");
3215 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3216 json
, JSON_C_TO_STRING_PRETTY
));
3217 json_object_free(json
);
3221 /* pim statistics - just adding only bsm related now.
3222 * We can continue to add all pim related stats here.
3224 static void pim_show_statistics(struct pim_instance
*pim
, struct vty
*vty
,
3225 const char *ifname
, bool uj
)
3227 json_object
*json
= NULL
;
3228 struct interface
*ifp
;
3231 json
= json_object_new_object();
3232 json_object_int_add(json
, "Number of Received BSMs",
3234 json_object_int_add(json
, "Number of Forwared BSMs",
3236 json_object_int_add(json
, "Number of Dropped BSMs",
3239 vty_out(vty
, "BSM Statistics :\n");
3240 vty_out(vty
, "----------------\n");
3241 vty_out(vty
, "Number of Received BSMs : %ld\n", pim
->bsm_rcvd
);
3242 vty_out(vty
, "Number of Forwared BSMs : %ld\n", pim
->bsm_sent
);
3243 vty_out(vty
, "Number of Dropped BSMs : %ld\n",
3249 /* scan interfaces */
3250 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3251 struct pim_interface
*pim_ifp
= ifp
->info
;
3253 if (ifname
&& strcmp(ifname
, ifp
->name
))
3260 vty_out(vty
, "Interface : %s\n", ifp
->name
);
3261 vty_out(vty
, "-------------------\n");
3263 "Number of BSMs dropped due to config miss : %u\n",
3264 pim_ifp
->pim_ifstat_bsm_cfg_miss
);
3265 vty_out(vty
, "Number of unicast BSMs dropped : %u\n",
3266 pim_ifp
->pim_ifstat_ucast_bsm_cfg_miss
);
3268 "Number of BSMs dropped due to invalid scope zone : %u\n",
3269 pim_ifp
->pim_ifstat_bsm_invalid_sz
);
3272 json_object
*json_row
= NULL
;
3274 json_row
= json_object_new_object();
3276 json_object_string_add(json_row
, "If Name", ifp
->name
);
3277 json_object_int_add(
3279 "Number of BSMs dropped due to config miss",
3280 pim_ifp
->pim_ifstat_bsm_cfg_miss
);
3281 json_object_int_add(
3282 json_row
, "Number of unicast BSMs dropped",
3283 pim_ifp
->pim_ifstat_ucast_bsm_cfg_miss
);
3284 json_object_int_add(json_row
,
3285 "Number of BSMs dropped due to invalid scope zone",
3286 pim_ifp
->pim_ifstat_bsm_invalid_sz
);
3287 json_object_object_add(json
, ifp
->name
, json_row
);
3293 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3294 json
, JSON_C_TO_STRING_PRETTY
));
3295 json_object_free(json
);
3299 static void clear_pim_statistics(struct pim_instance
*pim
)
3301 struct interface
*ifp
;
3305 pim
->bsm_dropped
= 0;
3307 /* scan interfaces */
3308 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3309 struct pim_interface
*pim_ifp
= ifp
->info
;
3314 pim_ifp
->pim_ifstat_bsm_cfg_miss
= 0;
3315 pim_ifp
->pim_ifstat_ucast_bsm_cfg_miss
= 0;
3316 pim_ifp
->pim_ifstat_bsm_invalid_sz
= 0;
3320 static void igmp_show_groups(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
3322 struct interface
*ifp
;
3324 json_object
*json
= NULL
;
3325 json_object
*json_iface
= NULL
;
3326 json_object
*json_row
= NULL
;
3328 now
= pim_time_monotonic_sec();
3331 json
= json_object_new_object();
3334 "Interface Address Group Mode Timer Srcs V Uptime \n");
3336 /* scan interfaces */
3337 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3338 struct pim_interface
*pim_ifp
= ifp
->info
;
3339 struct listnode
*sock_node
;
3340 struct igmp_sock
*igmp
;
3345 /* scan igmp sockets */
3346 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3348 char ifaddr_str
[INET_ADDRSTRLEN
];
3349 struct listnode
*grpnode
;
3350 struct igmp_group
*grp
;
3352 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3353 sizeof(ifaddr_str
));
3355 /* scan igmp groups */
3356 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3358 char group_str
[INET_ADDRSTRLEN
];
3362 pim_inet4_dump("<group?>", grp
->group_addr
,
3363 group_str
, sizeof(group_str
));
3364 pim_time_timer_to_hhmmss(hhmmss
, sizeof(hhmmss
),
3365 grp
->t_group_timer
);
3366 pim_time_uptime(uptime
, sizeof(uptime
),
3367 now
- grp
->group_creation
);
3370 json_object_object_get_ex(
3371 json
, ifp
->name
, &json_iface
);
3375 json_object_new_object();
3376 json_object_pim_ifp_add(
3378 json_object_object_add(
3383 json_row
= json_object_new_object();
3384 json_object_string_add(
3385 json_row
, "source", ifaddr_str
);
3386 json_object_string_add(
3387 json_row
, "group", group_str
);
3389 if (grp
->igmp_version
== 3)
3390 json_object_string_add(
3392 grp
->group_filtermode_isexcl
3396 json_object_string_add(json_row
,
3398 json_object_int_add(
3399 json_row
, "sourcesCount",
3400 grp
->group_source_list
3402 grp
->group_source_list
)
3404 json_object_int_add(json_row
, "version",
3406 json_object_string_add(
3407 json_row
, "uptime", uptime
);
3408 json_object_object_add(json_iface
,
3414 "%-16s %-15s %-15s %4s %8s %4d %d %8s\n",
3415 ifp
->name
, ifaddr_str
,
3417 grp
->igmp_version
== 3
3418 ? (grp
->group_filtermode_isexcl
3423 grp
->group_source_list
3425 grp
->group_source_list
)
3427 grp
->igmp_version
, uptime
);
3429 } /* scan igmp groups */
3430 } /* scan igmp sockets */
3431 } /* scan interfaces */
3434 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3435 json
, JSON_C_TO_STRING_PRETTY
));
3436 json_object_free(json
);
3440 static void igmp_show_group_retransmission(struct pim_instance
*pim
,
3443 struct interface
*ifp
;
3446 "Interface Address Group RetTimer Counter RetSrcs\n");
3448 /* scan interfaces */
3449 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3450 struct pim_interface
*pim_ifp
= ifp
->info
;
3451 struct listnode
*sock_node
;
3452 struct igmp_sock
*igmp
;
3457 /* scan igmp sockets */
3458 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3460 char ifaddr_str
[INET_ADDRSTRLEN
];
3461 struct listnode
*grpnode
;
3462 struct igmp_group
*grp
;
3464 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3465 sizeof(ifaddr_str
));
3467 /* scan igmp groups */
3468 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3470 char group_str
[INET_ADDRSTRLEN
];
3471 char grp_retr_mmss
[10];
3472 struct listnode
*src_node
;
3473 struct igmp_source
*src
;
3474 int grp_retr_sources
= 0;
3476 pim_inet4_dump("<group?>", grp
->group_addr
,
3477 group_str
, sizeof(group_str
));
3478 pim_time_timer_to_mmss(
3479 grp_retr_mmss
, sizeof(grp_retr_mmss
),
3480 grp
->t_group_query_retransmit_timer
);
3483 /* count group sources with retransmission state
3485 for (ALL_LIST_ELEMENTS_RO(
3486 grp
->group_source_list
, src_node
,
3488 if (src
->source_query_retransmit_count
3494 vty_out(vty
, "%-16s %-15s %-15s %-8s %7d %7d\n",
3495 ifp
->name
, ifaddr_str
, group_str
,
3497 grp
->group_specific_query_retransmit_count
,
3500 } /* scan igmp groups */
3501 } /* scan igmp sockets */
3502 } /* scan interfaces */
3505 static void igmp_show_sources(struct pim_instance
*pim
, struct vty
*vty
)
3507 struct interface
*ifp
;
3510 now
= pim_time_monotonic_sec();
3513 "Interface Address Group Source Timer Fwd Uptime \n");
3515 /* scan interfaces */
3516 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3517 struct pim_interface
*pim_ifp
= ifp
->info
;
3518 struct listnode
*sock_node
;
3519 struct igmp_sock
*igmp
;
3524 /* scan igmp sockets */
3525 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3527 char ifaddr_str
[INET_ADDRSTRLEN
];
3528 struct listnode
*grpnode
;
3529 struct igmp_group
*grp
;
3531 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3532 sizeof(ifaddr_str
));
3534 /* scan igmp groups */
3535 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3537 char group_str
[INET_ADDRSTRLEN
];
3538 struct listnode
*srcnode
;
3539 struct igmp_source
*src
;
3541 pim_inet4_dump("<group?>", grp
->group_addr
,
3542 group_str
, sizeof(group_str
));
3544 /* scan group sources */
3545 for (ALL_LIST_ELEMENTS_RO(
3546 grp
->group_source_list
, srcnode
,
3548 char source_str
[INET_ADDRSTRLEN
];
3553 "<source?>", src
->source_addr
,
3554 source_str
, sizeof(source_str
));
3556 pim_time_timer_to_mmss(
3558 src
->t_source_timer
);
3561 uptime
, sizeof(uptime
),
3562 now
- src
->source_creation
);
3565 "%-16s %-15s %-15s %-15s %5s %3s %8s\n",
3566 ifp
->name
, ifaddr_str
,
3567 group_str
, source_str
, mmss
,
3568 IGMP_SOURCE_TEST_FORWARDING(
3574 } /* scan group sources */
3575 } /* scan igmp groups */
3576 } /* scan igmp sockets */
3577 } /* scan interfaces */
3580 static void igmp_show_source_retransmission(struct pim_instance
*pim
,
3583 struct interface
*ifp
;
3586 "Interface Address Group Source Counter\n");
3588 /* scan interfaces */
3589 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3590 struct pim_interface
*pim_ifp
= ifp
->info
;
3591 struct listnode
*sock_node
;
3592 struct igmp_sock
*igmp
;
3597 /* scan igmp sockets */
3598 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3600 char ifaddr_str
[INET_ADDRSTRLEN
];
3601 struct listnode
*grpnode
;
3602 struct igmp_group
*grp
;
3604 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3605 sizeof(ifaddr_str
));
3607 /* scan igmp groups */
3608 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3610 char group_str
[INET_ADDRSTRLEN
];
3611 struct listnode
*srcnode
;
3612 struct igmp_source
*src
;
3614 pim_inet4_dump("<group?>", grp
->group_addr
,
3615 group_str
, sizeof(group_str
));
3617 /* scan group sources */
3618 for (ALL_LIST_ELEMENTS_RO(
3619 grp
->group_source_list
, srcnode
,
3621 char source_str
[INET_ADDRSTRLEN
];
3624 "<source?>", src
->source_addr
,
3625 source_str
, sizeof(source_str
));
3628 "%-16s %-15s %-15s %-15s %7d\n",
3629 ifp
->name
, ifaddr_str
,
3630 group_str
, source_str
,
3631 src
->source_query_retransmit_count
);
3633 } /* scan group sources */
3634 } /* scan igmp groups */
3635 } /* scan igmp sockets */
3636 } /* scan interfaces */
3639 static void pim_show_bsr(struct pim_instance
*pim
,
3644 char last_bsm_seen
[10];
3647 char bsr_str
[PREFIX_STRLEN
];
3648 json_object
*json
= NULL
;
3650 vty_out(vty
, "PIMv2 Bootstrap information\n");
3652 if (pim
->global_scope
.current_bsr
.s_addr
== INADDR_ANY
) {
3653 strlcpy(bsr_str
, "0.0.0.0", sizeof(bsr_str
));
3654 pim_time_uptime(uptime
, sizeof(uptime
),
3655 pim
->global_scope
.current_bsr_first_ts
);
3656 pim_time_uptime(last_bsm_seen
, sizeof(last_bsm_seen
),
3657 pim
->global_scope
.current_bsr_last_ts
);
3661 pim_inet4_dump("<bsr?>", pim
->global_scope
.current_bsr
,
3662 bsr_str
, sizeof(bsr_str
));
3663 now
= pim_time_monotonic_sec();
3664 pim_time_uptime(uptime
, sizeof(uptime
),
3665 (now
- pim
->global_scope
.current_bsr_first_ts
));
3666 pim_time_uptime(last_bsm_seen
, sizeof(last_bsm_seen
),
3667 now
- pim
->global_scope
.current_bsr_last_ts
);
3670 switch (pim
->global_scope
.state
) {
3672 strlcpy(bsr_state
, "NO_INFO", sizeof(bsr_state
));
3675 strlcpy(bsr_state
, "ACCEPT_ANY", sizeof(bsr_state
));
3677 case ACCEPT_PREFERRED
:
3678 strlcpy(bsr_state
, "ACCEPT_PREFERRED", sizeof(bsr_state
));
3681 strlcpy(bsr_state
, "", sizeof(bsr_state
));
3685 json
= json_object_new_object();
3686 json_object_string_add(json
, "bsr", bsr_str
);
3687 json_object_int_add(json
, "priority",
3688 pim
->global_scope
.current_bsr_prio
);
3689 json_object_int_add(json
, "fragment_tag",
3690 pim
->global_scope
.bsm_frag_tag
);
3691 json_object_string_add(json
, "state", bsr_state
);
3692 json_object_string_add(json
, "upTime", uptime
);
3693 json_object_string_add(json
, "last_bsm_seen", last_bsm_seen
);
3697 vty_out(vty
, "Current preferred BSR address: %s\n", bsr_str
);
3699 "Priority Fragment-Tag State UpTime\n");
3700 vty_out(vty
, " %-12d %-12d %-13s %7s\n",
3701 pim
->global_scope
.current_bsr_prio
,
3702 pim
->global_scope
.bsm_frag_tag
,
3705 vty_out(vty
, "Last BSM seen: %s\n", last_bsm_seen
);
3709 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3710 json
, JSON_C_TO_STRING_PRETTY
));
3711 json_object_free(json
);
3715 static void clear_igmp_interfaces(struct pim_instance
*pim
)
3717 struct interface
*ifp
;
3719 FOR_ALL_INTERFACES (pim
->vrf
, ifp
)
3720 pim_if_addr_del_all_igmp(ifp
);
3722 FOR_ALL_INTERFACES (pim
->vrf
, ifp
)
3723 pim_if_addr_add_all(ifp
);
3726 static void clear_pim_interfaces(struct pim_instance
*pim
)
3728 struct interface
*ifp
;
3730 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3732 pim_neighbor_delete_all(ifp
, "interface cleared");
3737 static void clear_interfaces(struct pim_instance
*pim
)
3739 clear_igmp_interfaces(pim
);
3740 clear_pim_interfaces(pim
);
3743 #define PIM_GET_PIM_INTERFACE(pim_ifp, ifp) \
3744 pim_ifp = ifp->info; \
3747 "%% Enable PIM and/or IGMP on this interface first\n"); \
3748 return CMD_WARNING_CONFIG_FAILED; \
3751 DEFUN (clear_ip_interfaces
,
3752 clear_ip_interfaces_cmd
,
3753 "clear ip interfaces [vrf NAME]",
3756 "Reset interfaces\n"
3760 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3765 clear_interfaces(vrf
->info
);
3770 DEFUN (clear_ip_igmp_interfaces
,
3771 clear_ip_igmp_interfaces_cmd
,
3772 "clear ip igmp [vrf NAME] interfaces",
3777 "Reset IGMP interfaces\n")
3780 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3785 clear_igmp_interfaces(vrf
->info
);
3790 DEFUN (clear_ip_pim_statistics
,
3791 clear_ip_pim_statistics_cmd
,
3792 "clear ip pim statistics [vrf NAME]",
3797 "Reset PIM statistics\n")
3800 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3805 clear_pim_statistics(vrf
->info
);
3809 static void clear_mroute(struct pim_instance
*pim
)
3811 struct pim_upstream
*up
;
3812 struct interface
*ifp
;
3814 /* scan interfaces */
3815 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3816 struct pim_interface
*pim_ifp
= ifp
->info
;
3817 struct listnode
*sock_node
;
3818 struct igmp_sock
*igmp
;
3819 struct pim_ifchannel
*ch
;
3824 /* deleting all ifchannels */
3825 while (!RB_EMPTY(pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
)) {
3826 ch
= RB_ROOT(pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
);
3828 pim_ifchannel_delete(ch
);
3831 /* clean up all igmp groups */
3832 /* scan igmp sockets */
3833 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3836 struct igmp_group
*grp
;
3838 if (igmp
->igmp_group_list
) {
3839 while (igmp
->igmp_group_list
->count
) {
3840 grp
= listnode_head(
3841 igmp
->igmp_group_list
);
3842 igmp_group_delete(grp
);
3849 /* clean up all upstreams*/
3850 if (pim
->upstream_list
) {
3851 while (pim
->upstream_list
->count
) {
3852 up
= listnode_head(pim
->upstream_list
);
3853 pim_upstream_del(pim
, up
, __PRETTY_FUNCTION__
);
3858 DEFUN (clear_ip_mroute
,
3859 clear_ip_mroute_cmd
,
3860 "clear ip mroute [vrf NAME]",
3863 "Reset multicast routes\n"
3867 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3872 clear_mroute(vrf
->info
);
3877 DEFUN (clear_ip_pim_interfaces
,
3878 clear_ip_pim_interfaces_cmd
,
3879 "clear ip pim [vrf NAME] interfaces",
3884 "Reset PIM interfaces\n")
3887 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3892 clear_pim_interfaces(vrf
->info
);
3897 DEFUN (clear_ip_pim_interface_traffic
,
3898 clear_ip_pim_interface_traffic_cmd
,
3899 "clear ip pim [vrf NAME] interface traffic",
3902 "PIM clear commands\n"
3904 "Reset PIM interfaces\n"
3905 "Reset Protocol Packet counters\n")
3908 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3909 struct interface
*ifp
= NULL
;
3910 struct pim_interface
*pim_ifp
= NULL
;
3915 FOR_ALL_INTERFACES (vrf
, ifp
) {
3916 pim_ifp
= ifp
->info
;
3921 pim_ifp
->pim_ifstat_hello_recv
= 0;
3922 pim_ifp
->pim_ifstat_hello_sent
= 0;
3923 pim_ifp
->pim_ifstat_join_recv
= 0;
3924 pim_ifp
->pim_ifstat_join_send
= 0;
3925 pim_ifp
->pim_ifstat_prune_recv
= 0;
3926 pim_ifp
->pim_ifstat_prune_send
= 0;
3927 pim_ifp
->pim_ifstat_reg_recv
= 0;
3928 pim_ifp
->pim_ifstat_reg_send
= 0;
3929 pim_ifp
->pim_ifstat_reg_stop_recv
= 0;
3930 pim_ifp
->pim_ifstat_reg_stop_send
= 0;
3931 pim_ifp
->pim_ifstat_assert_recv
= 0;
3932 pim_ifp
->pim_ifstat_assert_send
= 0;
3933 pim_ifp
->pim_ifstat_bsm_rx
= 0;
3934 pim_ifp
->pim_ifstat_bsm_tx
= 0;
3940 DEFUN (clear_ip_pim_oil
,
3941 clear_ip_pim_oil_cmd
,
3942 "clear ip pim [vrf NAME] oil",
3947 "Rescan PIM OIL (output interface list)\n")
3950 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3955 pim_scan_oil(vrf
->info
);
3960 DEFUN (show_ip_igmp_interface
,
3961 show_ip_igmp_interface_cmd
,
3962 "show ip igmp [vrf NAME] interface [detail|WORD] [json]",
3967 "IGMP interface information\n"
3973 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3974 bool uj
= use_json(argc
, argv
);
3979 if (argv_find(argv
, argc
, "detail", &idx
)
3980 || argv_find(argv
, argc
, "WORD", &idx
))
3981 igmp_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
3983 igmp_show_interfaces(vrf
->info
, vty
, uj
);
3988 DEFUN (show_ip_igmp_interface_vrf_all
,
3989 show_ip_igmp_interface_vrf_all_cmd
,
3990 "show ip igmp vrf all interface [detail|WORD] [json]",
3995 "IGMP interface information\n"
4001 bool uj
= use_json(argc
, argv
);
4007 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4011 vty_out(vty
, " \"%s\": ", vrf
->name
);
4014 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4015 if (argv_find(argv
, argc
, "detail", &idx
)
4016 || argv_find(argv
, argc
, "WORD", &idx
))
4017 igmp_show_interfaces_single(vrf
->info
, vty
,
4018 argv
[idx
]->arg
, uj
);
4020 igmp_show_interfaces(vrf
->info
, vty
, uj
);
4023 vty_out(vty
, "}\n");
4028 DEFUN (show_ip_igmp_join
,
4029 show_ip_igmp_join_cmd
,
4030 "show ip igmp [vrf NAME] join",
4035 "IGMP static join information\n")
4038 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4043 igmp_show_interface_join(vrf
->info
, vty
);
4048 DEFUN (show_ip_igmp_join_vrf_all
,
4049 show_ip_igmp_join_vrf_all_cmd
,
4050 "show ip igmp vrf all join",
4055 "IGMP static join information\n")
4057 bool uj
= use_json(argc
, argv
);
4063 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4067 vty_out(vty
, " \"%s\": ", vrf
->name
);
4070 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4071 igmp_show_interface_join(vrf
->info
, vty
);
4074 vty_out(vty
, "}\n");
4079 DEFUN (show_ip_igmp_groups
,
4080 show_ip_igmp_groups_cmd
,
4081 "show ip igmp [vrf NAME] groups [json]",
4090 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4091 bool uj
= use_json(argc
, argv
);
4096 igmp_show_groups(vrf
->info
, vty
, uj
);
4101 DEFUN (show_ip_igmp_groups_vrf_all
,
4102 show_ip_igmp_groups_vrf_all_cmd
,
4103 "show ip igmp vrf all groups [json]",
4111 bool uj
= use_json(argc
, argv
);
4117 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4121 vty_out(vty
, " \"%s\": ", vrf
->name
);
4124 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4125 igmp_show_groups(vrf
->info
, vty
, uj
);
4128 vty_out(vty
, "}\n");
4133 DEFUN (show_ip_igmp_groups_retransmissions
,
4134 show_ip_igmp_groups_retransmissions_cmd
,
4135 "show ip igmp [vrf NAME] groups retransmissions",
4141 "IGMP group retransmissions\n")
4144 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4149 igmp_show_group_retransmission(vrf
->info
, vty
);
4154 DEFUN (show_ip_igmp_sources
,
4155 show_ip_igmp_sources_cmd
,
4156 "show ip igmp [vrf NAME] sources",
4164 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4169 igmp_show_sources(vrf
->info
, vty
);
4174 DEFUN (show_ip_igmp_sources_retransmissions
,
4175 show_ip_igmp_sources_retransmissions_cmd
,
4176 "show ip igmp [vrf NAME] sources retransmissions",
4182 "IGMP source retransmissions\n")
4185 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4190 igmp_show_source_retransmission(vrf
->info
, vty
);
4195 DEFUN (show_ip_igmp_statistics
,
4196 show_ip_igmp_statistics_cmd
,
4197 "show ip igmp [vrf NAME] statistics [interface WORD] [json]",
4208 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4209 bool uj
= use_json(argc
, argv
);
4214 if (argv_find(argv
, argc
, "WORD", &idx
))
4215 igmp_show_statistics(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
4217 igmp_show_statistics(vrf
->info
, vty
, NULL
, uj
);
4222 DEFUN (show_ip_pim_assert
,
4223 show_ip_pim_assert_cmd
,
4224 "show ip pim [vrf NAME] assert",
4229 "PIM interface assert\n")
4232 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4237 pim_show_assert(vrf
->info
, vty
);
4242 DEFUN (show_ip_pim_assert_internal
,
4243 show_ip_pim_assert_internal_cmd
,
4244 "show ip pim [vrf NAME] assert-internal",
4249 "PIM interface internal assert state\n")
4252 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4257 pim_show_assert_internal(vrf
->info
, vty
);
4262 DEFUN (show_ip_pim_assert_metric
,
4263 show_ip_pim_assert_metric_cmd
,
4264 "show ip pim [vrf NAME] assert-metric",
4269 "PIM interface assert metric\n")
4272 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4277 pim_show_assert_metric(vrf
->info
, vty
);
4282 DEFUN (show_ip_pim_assert_winner_metric
,
4283 show_ip_pim_assert_winner_metric_cmd
,
4284 "show ip pim [vrf NAME] assert-winner-metric",
4289 "PIM interface assert winner metric\n")
4292 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4297 pim_show_assert_winner_metric(vrf
->info
, vty
);
4302 DEFUN (show_ip_pim_interface
,
4303 show_ip_pim_interface_cmd
,
4304 "show ip pim [vrf NAME] interface [detail|WORD] [json]",
4309 "PIM interface information\n"
4315 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4316 bool uj
= use_json(argc
, argv
);
4321 if (argv_find(argv
, argc
, "WORD", &idx
)
4322 || argv_find(argv
, argc
, "detail", &idx
))
4323 pim_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
4325 pim_show_interfaces(vrf
->info
, vty
, uj
);
4330 DEFUN (show_ip_pim_interface_vrf_all
,
4331 show_ip_pim_interface_vrf_all_cmd
,
4332 "show ip pim vrf all interface [detail|WORD] [json]",
4337 "PIM interface information\n"
4343 bool uj
= use_json(argc
, argv
);
4349 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4353 vty_out(vty
, " \"%s\": ", vrf
->name
);
4356 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4357 if (argv_find(argv
, argc
, "WORD", &idx
)
4358 || argv_find(argv
, argc
, "detail", &idx
))
4359 pim_show_interfaces_single(vrf
->info
, vty
,
4360 argv
[idx
]->arg
, uj
);
4362 pim_show_interfaces(vrf
->info
, vty
, uj
);
4365 vty_out(vty
, "}\n");
4370 DEFPY (show_ip_pim_join
,
4371 show_ip_pim_join_cmd
,
4372 "show ip pim [vrf NAME] join [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
4377 "PIM interface join information\n"
4378 "The Source or Group\n"
4382 struct prefix_sg sg
= {0};
4385 struct pim_instance
*pim
;
4387 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
4390 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
4393 pim
= pim_get_pim_instance(v
->vrf_id
);
4396 vty_out(vty
, "%% Unable to find pim instance\n");
4400 if (s_or_g
.s_addr
!= 0) {
4401 if (g
.s_addr
!= 0) {
4408 pim_show_join(pim
, vty
, &sg
, uj
);
4413 DEFUN (show_ip_pim_join_vrf_all
,
4414 show_ip_pim_join_vrf_all_cmd
,
4415 "show ip pim vrf all join [json]",
4420 "PIM interface join information\n"
4423 struct prefix_sg sg
= {0};
4424 bool uj
= use_json(argc
, argv
);
4430 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4434 vty_out(vty
, " \"%s\": ", vrf
->name
);
4437 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4438 pim_show_join(vrf
->info
, vty
, &sg
, uj
);
4441 vty_out(vty
, "}\n");
4446 DEFUN (show_ip_pim_local_membership
,
4447 show_ip_pim_local_membership_cmd
,
4448 "show ip pim [vrf NAME] local-membership [json]",
4453 "PIM interface local-membership\n"
4457 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4458 bool uj
= use_json(argc
, argv
);
4463 pim_show_membership(vrf
->info
, vty
, uj
);
4468 DEFUN (show_ip_pim_neighbor
,
4469 show_ip_pim_neighbor_cmd
,
4470 "show ip pim [vrf NAME] neighbor [detail|WORD] [json]",
4475 "PIM neighbor information\n"
4477 "Name of interface or neighbor\n"
4481 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4482 bool uj
= use_json(argc
, argv
);
4487 if (argv_find(argv
, argc
, "detail", &idx
)
4488 || argv_find(argv
, argc
, "WORD", &idx
))
4489 pim_show_neighbors_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
4491 pim_show_neighbors(vrf
->info
, vty
, uj
);
4496 DEFUN (show_ip_pim_neighbor_vrf_all
,
4497 show_ip_pim_neighbor_vrf_all_cmd
,
4498 "show ip pim vrf all neighbor [detail|WORD] [json]",
4503 "PIM neighbor information\n"
4505 "Name of interface or neighbor\n"
4509 bool uj
= use_json(argc
, argv
);
4515 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4519 vty_out(vty
, " \"%s\": ", vrf
->name
);
4522 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4523 if (argv_find(argv
, argc
, "detail", &idx
)
4524 || argv_find(argv
, argc
, "WORD", &idx
))
4525 pim_show_neighbors_single(vrf
->info
, vty
,
4526 argv
[idx
]->arg
, uj
);
4528 pim_show_neighbors(vrf
->info
, vty
, uj
);
4531 vty_out(vty
, "}\n");
4536 DEFUN (show_ip_pim_secondary
,
4537 show_ip_pim_secondary_cmd
,
4538 "show ip pim [vrf NAME] secondary",
4543 "PIM neighbor addresses\n")
4546 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4551 pim_show_neighbors_secondary(vrf
->info
, vty
);
4556 DEFUN (show_ip_pim_state
,
4557 show_ip_pim_state_cmd
,
4558 "show ip pim [vrf NAME] state [A.B.C.D [A.B.C.D]] [json]",
4563 "PIM state information\n"
4564 "Unicast or Multicast address\n"
4565 "Multicast address\n"
4568 const char *src_or_group
= NULL
;
4569 const char *group
= NULL
;
4571 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4572 bool uj
= use_json(argc
, argv
);
4580 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
4581 src_or_group
= argv
[idx
]->arg
;
4583 group
= argv
[idx
+ 1]->arg
;
4586 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
4591 DEFUN (show_ip_pim_state_vrf_all
,
4592 show_ip_pim_state_vrf_all_cmd
,
4593 "show ip pim vrf all state [A.B.C.D [A.B.C.D]] [json]",
4598 "PIM state information\n"
4599 "Unicast or Multicast address\n"
4600 "Multicast address\n"
4603 const char *src_or_group
= NULL
;
4604 const char *group
= NULL
;
4606 bool uj
= use_json(argc
, argv
);
4615 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
4616 src_or_group
= argv
[idx
]->arg
;
4618 group
= argv
[idx
+ 1]->arg
;
4621 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4625 vty_out(vty
, " \"%s\": ", vrf
->name
);
4628 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4629 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
4632 vty_out(vty
, "}\n");
4637 DEFPY (show_ip_pim_upstream
,
4638 show_ip_pim_upstream_cmd
,
4639 "show ip pim [vrf NAME] upstream [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
4644 "PIM upstream information\n"
4645 "The Source or Group\n"
4649 struct prefix_sg sg
= {0};
4652 struct pim_instance
*pim
;
4654 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
4657 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
4660 pim
= pim_get_pim_instance(v
->vrf_id
);
4663 vty_out(vty
, "%% Unable to find pim instance\n");
4667 if (s_or_g
.s_addr
!= 0) {
4668 if (g
.s_addr
!= 0) {
4674 pim_show_upstream(pim
, vty
, &sg
, uj
);
4679 DEFUN (show_ip_pim_upstream_vrf_all
,
4680 show_ip_pim_upstream_vrf_all_cmd
,
4681 "show ip pim vrf all upstream [json]",
4686 "PIM upstream information\n"
4689 struct prefix_sg sg
= {0};
4690 bool uj
= use_json(argc
, argv
);
4696 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4700 vty_out(vty
, " \"%s\": ", vrf
->name
);
4703 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4704 pim_show_upstream(vrf
->info
, vty
, &sg
, uj
);
4710 DEFUN (show_ip_pim_upstream_join_desired
,
4711 show_ip_pim_upstream_join_desired_cmd
,
4712 "show ip pim [vrf NAME] upstream-join-desired [json]",
4717 "PIM upstream join-desired\n"
4721 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4722 bool uj
= use_json(argc
, argv
);
4727 pim_show_join_desired(vrf
->info
, vty
, uj
);
4732 DEFUN (show_ip_pim_upstream_rpf
,
4733 show_ip_pim_upstream_rpf_cmd
,
4734 "show ip pim [vrf NAME] upstream-rpf [json]",
4739 "PIM upstream source rpf\n"
4743 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4744 bool uj
= use_json(argc
, argv
);
4749 pim_show_upstream_rpf(vrf
->info
, vty
, uj
);
4754 DEFUN (show_ip_pim_rp
,
4756 "show ip pim [vrf NAME] rp-info [json]",
4761 "PIM RP information\n"
4765 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4766 bool uj
= use_json(argc
, argv
);
4771 pim_rp_show_information(vrf
->info
, vty
, uj
);
4776 DEFUN (show_ip_pim_rp_vrf_all
,
4777 show_ip_pim_rp_vrf_all_cmd
,
4778 "show ip pim vrf all rp-info [json]",
4783 "PIM RP information\n"
4786 bool uj
= use_json(argc
, argv
);
4792 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4796 vty_out(vty
, " \"%s\": ", vrf
->name
);
4799 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4800 pim_rp_show_information(vrf
->info
, vty
, uj
);
4803 vty_out(vty
, "}\n");
4808 DEFUN (show_ip_pim_rpf
,
4809 show_ip_pim_rpf_cmd
,
4810 "show ip pim [vrf NAME] rpf [json]",
4815 "PIM cached source rpf information\n"
4819 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4820 bool uj
= use_json(argc
, argv
);
4825 pim_show_rpf(vrf
->info
, vty
, uj
);
4830 DEFUN (show_ip_pim_rpf_vrf_all
,
4831 show_ip_pim_rpf_vrf_all_cmd
,
4832 "show ip pim vrf all rpf [json]",
4837 "PIM cached source rpf information\n"
4840 bool uj
= use_json(argc
, argv
);
4846 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4850 vty_out(vty
, " \"%s\": ", vrf
->name
);
4853 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4854 pim_show_rpf(vrf
->info
, vty
, uj
);
4857 vty_out(vty
, "}\n");
4862 DEFUN (show_ip_pim_nexthop
,
4863 show_ip_pim_nexthop_cmd
,
4864 "show ip pim [vrf NAME] nexthop",
4869 "PIM cached nexthop rpf information\n")
4872 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4877 pim_show_nexthop(vrf
->info
, vty
);
4882 DEFUN (show_ip_pim_nexthop_lookup
,
4883 show_ip_pim_nexthop_lookup_cmd
,
4884 "show ip pim [vrf NAME] nexthop-lookup A.B.C.D A.B.C.D",
4889 "PIM cached nexthop rpf lookup\n"
4890 "Source/RP address\n"
4891 "Multicast Group address\n")
4893 struct prefix nht_p
;
4895 struct in_addr src_addr
, grp_addr
;
4896 struct in_addr vif_source
;
4897 const char *addr_str
, *addr_str1
;
4899 struct pim_nexthop nexthop
;
4900 char nexthop_addr_str
[PREFIX_STRLEN
];
4901 char grp_str
[PREFIX_STRLEN
];
4903 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4908 argv_find(argv
, argc
, "A.B.C.D", &idx
);
4909 addr_str
= argv
[idx
]->arg
;
4910 result
= inet_pton(AF_INET
, addr_str
, &src_addr
);
4912 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
4913 errno
, safe_strerror(errno
));
4917 if (pim_is_group_224_4(src_addr
)) {
4919 "Invalid argument. Expected Valid Source Address.\n");
4923 addr_str1
= argv
[idx
+ 1]->arg
;
4924 result
= inet_pton(AF_INET
, addr_str1
, &grp_addr
);
4926 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
4927 errno
, safe_strerror(errno
));
4931 if (!pim_is_group_224_4(grp_addr
)) {
4933 "Invalid argument. Expected Valid Multicast Group Address.\n");
4937 if (!pim_rp_set_upstream_addr(vrf
->info
, &vif_source
, src_addr
,
4941 nht_p
.family
= AF_INET
;
4942 nht_p
.prefixlen
= IPV4_MAX_BITLEN
;
4943 nht_p
.u
.prefix4
= vif_source
;
4944 grp
.family
= AF_INET
;
4945 grp
.prefixlen
= IPV4_MAX_BITLEN
;
4946 grp
.u
.prefix4
= grp_addr
;
4947 memset(&nexthop
, 0, sizeof(nexthop
));
4949 result
= pim_ecmp_nexthop_lookup(vrf
->info
, &nexthop
, &nht_p
, &grp
, 0);
4953 "Nexthop Lookup failed, no usable routes returned.\n");
4957 pim_addr_dump("<grp?>", &grp
, grp_str
, sizeof(grp_str
));
4958 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
4959 nexthop_addr_str
, sizeof(nexthop_addr_str
));
4960 vty_out(vty
, "Group %s --- Nexthop %s Interface %s \n", grp_str
,
4961 nexthop_addr_str
, nexthop
.interface
->name
);
4966 DEFUN (show_ip_pim_interface_traffic
,
4967 show_ip_pim_interface_traffic_cmd
,
4968 "show ip pim [vrf NAME] interface traffic [WORD] [json]",
4973 "PIM interface information\n"
4974 "Protocol Packet counters\n"
4979 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4980 bool uj
= use_json(argc
, argv
);
4985 if (argv_find(argv
, argc
, "WORD", &idx
))
4986 pim_show_interface_traffic_single(vrf
->info
, vty
,
4987 argv
[idx
]->arg
, uj
);
4989 pim_show_interface_traffic(vrf
->info
, vty
, uj
);
4994 DEFUN (show_ip_pim_bsm_db
,
4995 show_ip_pim_bsm_db_cmd
,
4996 "show ip pim bsm-database [vrf NAME] [json]",
5001 "PIM cached bsm packets information\n"
5005 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5006 bool uj
= use_json(argc
, argv
);
5011 pim_show_bsm_db(vrf
->info
, vty
, uj
);
5015 DEFUN (show_ip_pim_bsrp
,
5016 show_ip_pim_bsrp_cmd
,
5017 "show ip pim bsrp-info [vrf NAME] [json]",
5022 "PIM cached group-rp mappings information\n"
5026 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5027 bool uj
= use_json(argc
, argv
);
5032 pim_show_group_rp_mappings_info(vrf
->info
, vty
, uj
);
5037 DEFUN (show_ip_pim_statistics
,
5038 show_ip_pim_statistics_cmd
,
5039 "show ip pim [vrf NAME] statistics [interface WORD] [json]",
5050 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5051 bool uj
= use_json(argc
, argv
);
5056 if (argv_find(argv
, argc
, "WORD", &idx
))
5057 pim_show_statistics(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
5059 pim_show_statistics(vrf
->info
, vty
, NULL
, uj
);
5064 static void show_multicast_interfaces(struct pim_instance
*pim
, struct vty
*vty
)
5066 struct interface
*ifp
;
5071 "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut\n");
5073 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
5074 struct pim_interface
*pim_ifp
;
5075 struct in_addr ifaddr
;
5076 struct sioc_vif_req vreq
;
5078 pim_ifp
= ifp
->info
;
5083 memset(&vreq
, 0, sizeof(vreq
));
5084 vreq
.vifi
= pim_ifp
->mroute_vif_index
;
5086 if (ioctl(pim
->mroute_socket
, SIOCGETVIFCNT
, &vreq
)) {
5088 "ioctl(SIOCGETVIFCNT=%lu) failure for interface %s vif_index=%d: errno=%d: %s",
5089 (unsigned long)SIOCGETVIFCNT
, ifp
->name
,
5090 pim_ifp
->mroute_vif_index
, errno
,
5091 safe_strerror(errno
));
5094 ifaddr
= pim_ifp
->primary_address
;
5096 vty_out(vty
, "%-16s %-15s %3d %3d %7lu %7lu %10lu %10lu\n",
5097 ifp
->name
, inet_ntoa(ifaddr
), ifp
->ifindex
,
5098 pim_ifp
->mroute_vif_index
, (unsigned long)vreq
.icount
,
5099 (unsigned long)vreq
.ocount
, (unsigned long)vreq
.ibytes
,
5100 (unsigned long)vreq
.obytes
);
5104 static void pim_cmd_show_ip_multicast_helper(struct pim_instance
*pim
,
5107 struct vrf
*vrf
= pim
->vrf
;
5108 time_t now
= pim_time_monotonic_sec();
5114 vty_out(vty
, "Router MLAG Role: %s\n",
5115 mlag_role2str(router
->role
, mlag_role
, sizeof(mlag_role
)));
5116 vty_out(vty
, "Mroute socket descriptor:");
5118 vty_out(vty
, " %d(%s)\n", pim
->mroute_socket
, vrf
->name
);
5120 pim_time_uptime(uptime
, sizeof(uptime
),
5121 now
- pim
->mroute_socket_creation
);
5122 vty_out(vty
, "Mroute socket uptime: %s\n", uptime
);
5126 pim_zebra_zclient_update(vty
);
5127 pim_zlookup_show_ip_multicast(vty
);
5130 vty_out(vty
, "Maximum highest VifIndex: %d\n", PIM_MAX_USABLE_VIFS
);
5133 vty_out(vty
, "Upstream Join Timer: %d secs\n", router
->t_periodic
);
5134 vty_out(vty
, "Join/Prune Holdtime: %d secs\n", PIM_JP_HOLDTIME
);
5135 vty_out(vty
, "PIM ECMP: %s\n", pim
->ecmp_enable
? "Enable" : "Disable");
5136 vty_out(vty
, "PIM ECMP Rebalance: %s\n",
5137 pim
->ecmp_rebalance_enable
? "Enable" : "Disable");
5141 show_rpf_refresh_stats(vty
, pim
, now
, NULL
);
5145 show_scan_oil_stats(pim
, vty
, now
);
5147 show_multicast_interfaces(pim
, vty
);
5150 DEFUN (show_ip_multicast
,
5151 show_ip_multicast_cmd
,
5152 "show ip multicast [vrf NAME]",
5156 "Multicast global information\n")
5159 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5164 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
5169 DEFUN (show_ip_multicast_vrf_all
,
5170 show_ip_multicast_vrf_all_cmd
,
5171 "show ip multicast vrf all",
5175 "Multicast global information\n")
5177 bool uj
= use_json(argc
, argv
);
5183 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5187 vty_out(vty
, " \"%s\": ", vrf
->name
);
5190 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5191 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
5194 vty_out(vty
, "}\n");
5199 static void show_mroute(struct pim_instance
*pim
, struct vty
*vty
,
5200 struct prefix_sg
*sg
, bool fill
, bool uj
)
5202 struct listnode
*node
;
5203 struct channel_oil
*c_oil
;
5204 struct static_route
*s_route
;
5206 json_object
*json
= NULL
;
5207 json_object
*json_group
= NULL
;
5208 json_object
*json_source
= NULL
;
5209 json_object
*json_oil
= NULL
;
5210 json_object
*json_ifp_out
= NULL
;
5213 char grp_str
[INET_ADDRSTRLEN
];
5214 char src_str
[INET_ADDRSTRLEN
];
5215 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
5216 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
5218 struct interface
*ifp_in
;
5222 json
= json_object_new_object();
5225 "Source Group Proto Input Output TTL Uptime\n");
5228 now
= pim_time_monotonic_sec();
5230 /* print list of PIM and IGMP routes */
5231 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
5234 if (!c_oil
->installed
&& !uj
)
5237 if (sg
->grp
.s_addr
!= 0 &&
5238 sg
->grp
.s_addr
!= c_oil
->oil
.mfcc_mcastgrp
.s_addr
)
5240 if (sg
->src
.s_addr
!= 0 &&
5241 sg
->src
.s_addr
!= c_oil
->oil
.mfcc_origin
.s_addr
)
5244 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
5246 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
5248 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
5251 strlcpy(in_ifname
, ifp_in
->name
, sizeof(in_ifname
));
5253 strlcpy(in_ifname
, "<iif?>", sizeof(in_ifname
));
5257 /* Find the group, create it if it doesn't exist */
5258 json_object_object_get_ex(json
, grp_str
, &json_group
);
5261 json_group
= json_object_new_object();
5262 json_object_object_add(json
, grp_str
,
5266 /* Find the source nested under the group, create it if
5267 * it doesn't exist */
5268 json_object_object_get_ex(json_group
, src_str
,
5272 json_source
= json_object_new_object();
5273 json_object_object_add(json_group
, src_str
,
5277 /* Find the inbound interface nested under the source,
5278 * create it if it doesn't exist */
5279 json_object_int_add(json_source
, "installed",
5281 json_object_int_add(json_source
, "refCount",
5282 c_oil
->oil_ref_count
);
5283 json_object_int_add(json_source
, "oilSize",
5285 json_object_int_add(json_source
, "OilInheritedRescan",
5286 c_oil
->oil_inherited_rescan
);
5287 json_object_string_add(json_source
, "iif", in_ifname
);
5291 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
5293 struct interface
*ifp_out
;
5294 char mroute_uptime
[10];
5297 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
5301 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
5303 mroute_uptime
, sizeof(mroute_uptime
),
5304 now
- c_oil
->mroute_creation
);
5308 strlcpy(out_ifname
, ifp_out
->name
, sizeof(out_ifname
));
5310 strlcpy(out_ifname
, "<oif?>", sizeof(out_ifname
));
5313 json_ifp_out
= json_object_new_object();
5314 json_object_string_add(json_ifp_out
, "source",
5316 json_object_string_add(json_ifp_out
, "group",
5319 if (c_oil
->oif_flags
[oif_vif_index
]
5320 & PIM_OIF_FLAG_PROTO_PIM
)
5321 json_object_boolean_true_add(
5322 json_ifp_out
, "protocolPim");
5324 if (c_oil
->oif_flags
[oif_vif_index
]
5325 & PIM_OIF_FLAG_PROTO_IGMP
)
5326 json_object_boolean_true_add(
5327 json_ifp_out
, "protocolIgmp");
5329 if (c_oil
->oif_flags
[oif_vif_index
]
5330 & PIM_OIF_FLAG_PROTO_VXLAN
)
5331 json_object_boolean_true_add(
5332 json_ifp_out
, "protocolVxlan");
5334 if (c_oil
->oif_flags
[oif_vif_index
]
5335 & PIM_OIF_FLAG_PROTO_SOURCE
)
5336 json_object_boolean_true_add(
5337 json_ifp_out
, "protocolSource");
5339 if (c_oil
->oif_flags
[oif_vif_index
]
5340 & PIM_OIF_FLAG_PROTO_STAR
)
5341 json_object_boolean_true_add(
5343 "protocolInherited");
5345 json_object_string_add(json_ifp_out
,
5348 json_object_int_add(json_ifp_out
, "iVifI",
5349 c_oil
->oil
.mfcc_parent
);
5350 json_object_string_add(json_ifp_out
,
5351 "outboundInterface",
5353 json_object_int_add(json_ifp_out
, "oVifI",
5355 json_object_int_add(json_ifp_out
, "ttl", ttl
);
5356 json_object_string_add(json_ifp_out
, "upTime",
5359 json_oil
= json_object_new_object();
5360 json_object_object_add(json_source
,
5363 json_object_object_add(json_oil
, out_ifname
,
5366 if (c_oil
->oif_flags
[oif_vif_index
]
5367 & PIM_OIF_FLAG_PROTO_PIM
) {
5368 strlcpy(proto
, "PIM", sizeof(proto
));
5371 if (c_oil
->oif_flags
[oif_vif_index
]
5372 & PIM_OIF_FLAG_PROTO_IGMP
) {
5373 strlcpy(proto
, "IGMP", sizeof(proto
));
5376 if (c_oil
->oif_flags
[oif_vif_index
]
5377 & PIM_OIF_FLAG_PROTO_VXLAN
) {
5378 strlcpy(proto
, "VxLAN", sizeof(proto
));
5381 if (c_oil
->oif_flags
[oif_vif_index
]
5382 & PIM_OIF_FLAG_PROTO_SOURCE
) {
5383 strlcpy(proto
, "SRC", sizeof(proto
));
5386 if (c_oil
->oif_flags
[oif_vif_index
]
5387 & PIM_OIF_FLAG_PROTO_STAR
) {
5388 strlcpy(proto
, "STAR", sizeof(proto
));
5392 "%-15s %-15s %-6s %-16s %-16s %-3d %8s\n",
5393 src_str
, grp_str
, proto
, in_ifname
,
5394 out_ifname
, ttl
, mroute_uptime
);
5399 in_ifname
[0] = '\0';
5405 if (!uj
&& !found_oif
) {
5406 vty_out(vty
, "%-15s %-15s %-6s %-16s %-16s %-3d %8s\n",
5407 src_str
, grp_str
, "none", in_ifname
, "none", 0,
5412 /* Print list of static routes */
5413 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
5416 if (!s_route
->c_oil
.installed
)
5419 pim_inet4_dump("<group?>", s_route
->group
, grp_str
,
5421 pim_inet4_dump("<source?>", s_route
->source
, src_str
,
5423 ifp_in
= pim_if_find_by_vif_index(pim
, s_route
->iif
);
5427 strlcpy(in_ifname
, ifp_in
->name
, sizeof(in_ifname
));
5429 strlcpy(in_ifname
, "<iif?>", sizeof(in_ifname
));
5433 /* Find the group, create it if it doesn't exist */
5434 json_object_object_get_ex(json
, grp_str
, &json_group
);
5437 json_group
= json_object_new_object();
5438 json_object_object_add(json
, grp_str
,
5442 /* Find the source nested under the group, create it if
5443 * it doesn't exist */
5444 json_object_object_get_ex(json_group
, src_str
,
5448 json_source
= json_object_new_object();
5449 json_object_object_add(json_group
, src_str
,
5453 json_object_string_add(json_source
, "iif", in_ifname
);
5456 strlcpy(proto
, "STATIC", sizeof(proto
));
5459 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
5461 struct interface
*ifp_out
;
5462 char oif_uptime
[10];
5465 ttl
= s_route
->oif_ttls
[oif_vif_index
];
5469 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
5471 oif_uptime
, sizeof(oif_uptime
),
5474 .oif_creation
[oif_vif_index
]);
5478 strlcpy(out_ifname
, ifp_out
->name
, sizeof(out_ifname
));
5480 strlcpy(out_ifname
, "<oif?>", sizeof(out_ifname
));
5483 json_ifp_out
= json_object_new_object();
5484 json_object_string_add(json_ifp_out
, "source",
5486 json_object_string_add(json_ifp_out
, "group",
5488 json_object_boolean_true_add(json_ifp_out
,
5490 json_object_string_add(json_ifp_out
,
5493 json_object_int_add(
5494 json_ifp_out
, "iVifI",
5495 s_route
->c_oil
.oil
.mfcc_parent
);
5496 json_object_string_add(json_ifp_out
,
5497 "outboundInterface",
5499 json_object_int_add(json_ifp_out
, "oVifI",
5501 json_object_int_add(json_ifp_out
, "ttl", ttl
);
5502 json_object_string_add(json_ifp_out
, "upTime",
5505 json_oil
= json_object_new_object();
5506 json_object_object_add(json_source
,
5509 json_object_object_add(json_oil
, out_ifname
,
5513 "%-15s %-15s %-6s %-16s %-16s %-3d %8s %s\n",
5514 src_str
, grp_str
, proto
, in_ifname
,
5515 out_ifname
, ttl
, oif_uptime
,
5517 if (first
&& !fill
) {
5520 in_ifname
[0] = '\0';
5526 if (!uj
&& !found_oif
) {
5528 "%-15s %-15s %-6s %-16s %-16s %-3d %8s %s\n",
5529 src_str
, grp_str
, proto
, in_ifname
, "none", 0,
5530 "--:--:--", pim
->vrf
->name
);
5535 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5536 json
, JSON_C_TO_STRING_PRETTY
));
5537 json_object_free(json
);
5541 DEFPY (show_ip_mroute
,
5543 "show ip mroute [vrf NAME] [A.B.C.D$s_or_g [A.B.C.D$g]] [fill$fill] [json$json]",
5548 "The Source or Group\n"
5550 "Fill in Assumed data\n"
5553 struct prefix_sg sg
= {0};
5554 struct pim_instance
*pim
;
5557 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
5560 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
5563 pim
= pim_get_pim_instance(v
->vrf_id
);
5566 vty_out(vty
, "%% Unable to find pim instance\n");
5570 if (s_or_g
.s_addr
!= 0) {
5571 if (g
.s_addr
!= 0) {
5577 show_mroute(pim
, vty
, &sg
, !!fill
, !!json
);
5581 DEFUN (show_ip_mroute_vrf_all
,
5582 show_ip_mroute_vrf_all_cmd
,
5583 "show ip mroute vrf all [fill] [json]",
5588 "Fill in Assumed data\n"
5591 struct prefix_sg sg
= {0};
5592 bool uj
= use_json(argc
, argv
);
5598 if (argv_find(argv
, argc
, "fill", &idx
))
5603 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5607 vty_out(vty
, " \"%s\": ", vrf
->name
);
5610 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5611 show_mroute(vrf
->info
, vty
, &sg
, fill
, uj
);
5614 vty_out(vty
, "}\n");
5619 DEFUN (clear_ip_mroute_count
,
5620 clear_ip_mroute_count_cmd
,
5621 "clear ip mroute [vrf NAME] count",
5626 "Route and packet count data\n")
5629 struct listnode
*node
;
5630 struct channel_oil
*c_oil
;
5631 struct static_route
*sr
;
5632 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5633 struct pim_instance
*pim
;
5639 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
5640 if (!c_oil
->installed
)
5643 pim_mroute_update_counters(c_oil
);
5644 c_oil
->cc
.origpktcnt
= c_oil
->cc
.pktcnt
;
5645 c_oil
->cc
.origbytecnt
= c_oil
->cc
.bytecnt
;
5646 c_oil
->cc
.origwrong_if
= c_oil
->cc
.wrong_if
;
5649 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, sr
)) {
5650 if (!sr
->c_oil
.installed
)
5653 pim_mroute_update_counters(&sr
->c_oil
);
5655 sr
->c_oil
.cc
.origpktcnt
= sr
->c_oil
.cc
.pktcnt
;
5656 sr
->c_oil
.cc
.origbytecnt
= sr
->c_oil
.cc
.bytecnt
;
5657 sr
->c_oil
.cc
.origwrong_if
= sr
->c_oil
.cc
.wrong_if
;
5662 static void show_mroute_count(struct pim_instance
*pim
, struct vty
*vty
)
5664 struct listnode
*node
;
5665 struct channel_oil
*c_oil
;
5666 struct static_route
*sr
;
5671 "Source Group LastUsed Packets Bytes WrongIf \n");
5673 /* Print PIM and IGMP route counts */
5674 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
5675 char group_str
[INET_ADDRSTRLEN
];
5676 char source_str
[INET_ADDRSTRLEN
];
5678 if (!c_oil
->installed
)
5681 pim_mroute_update_counters(c_oil
);
5683 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, group_str
,
5685 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, source_str
,
5686 sizeof(source_str
));
5688 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
5689 source_str
, group_str
, c_oil
->cc
.lastused
/ 100,
5690 c_oil
->cc
.pktcnt
- c_oil
->cc
.origpktcnt
,
5691 c_oil
->cc
.bytecnt
- c_oil
->cc
.origbytecnt
,
5692 c_oil
->cc
.wrong_if
- c_oil
->cc
.origwrong_if
);
5695 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, sr
)) {
5696 char group_str
[INET_ADDRSTRLEN
];
5697 char source_str
[INET_ADDRSTRLEN
];
5699 if (!sr
->c_oil
.installed
)
5702 pim_mroute_update_counters(&sr
->c_oil
);
5704 pim_inet4_dump("<group?>", sr
->c_oil
.oil
.mfcc_mcastgrp
,
5705 group_str
, sizeof(group_str
));
5706 pim_inet4_dump("<source?>", sr
->c_oil
.oil
.mfcc_origin
,
5707 source_str
, sizeof(source_str
));
5709 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
5710 source_str
, group_str
, sr
->c_oil
.cc
.lastused
,
5711 sr
->c_oil
.cc
.pktcnt
- sr
->c_oil
.cc
.origpktcnt
,
5712 sr
->c_oil
.cc
.bytecnt
- sr
->c_oil
.cc
.origbytecnt
,
5713 sr
->c_oil
.cc
.wrong_if
- sr
->c_oil
.cc
.origwrong_if
);
5717 DEFUN (show_ip_mroute_count
,
5718 show_ip_mroute_count_cmd
,
5719 "show ip mroute [vrf NAME] count",
5724 "Route and packet count data\n")
5727 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5732 show_mroute_count(vrf
->info
, vty
);
5736 DEFUN (show_ip_mroute_count_vrf_all
,
5737 show_ip_mroute_count_vrf_all_cmd
,
5738 "show ip mroute vrf all count",
5743 "Route and packet count data\n")
5745 bool uj
= use_json(argc
, argv
);
5751 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5755 vty_out(vty
, " \"%s\": ", vrf
->name
);
5758 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5759 show_mroute_count(vrf
->info
, vty
);
5762 vty_out(vty
, "}\n");
5767 static void show_mroute_summary(struct pim_instance
*pim
, struct vty
*vty
)
5769 struct listnode
*node
;
5770 struct channel_oil
*c_oil
;
5771 struct static_route
*s_route
;
5772 uint32_t starg_sw_mroute_cnt
= 0;
5773 uint32_t sg_sw_mroute_cnt
= 0;
5774 uint32_t starg_hw_mroute_cnt
= 0;
5775 uint32_t sg_hw_mroute_cnt
= 0;
5777 vty_out(vty
, "Mroute Type Installed/Total\n");
5779 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
5780 if (!c_oil
->installed
) {
5781 if (c_oil
->oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
5782 starg_sw_mroute_cnt
++;
5786 if (c_oil
->oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
5787 starg_hw_mroute_cnt
++;
5793 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
5794 if (!s_route
->c_oil
.installed
) {
5795 if (s_route
->c_oil
.oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
5796 starg_sw_mroute_cnt
++;
5800 if (s_route
->c_oil
.oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
5801 starg_hw_mroute_cnt
++;
5807 vty_out(vty
, "%-20s %d/%d\n", "(*, G)", starg_hw_mroute_cnt
,
5808 starg_sw_mroute_cnt
+ starg_hw_mroute_cnt
);
5809 vty_out(vty
, "%-20s %d/%d\n", "(S, G)", sg_hw_mroute_cnt
,
5810 sg_sw_mroute_cnt
+ sg_hw_mroute_cnt
);
5811 vty_out(vty
, "------\n");
5812 vty_out(vty
, "%-20s %d/%d\n", "Total",
5813 (starg_hw_mroute_cnt
+ sg_hw_mroute_cnt
),
5814 (starg_sw_mroute_cnt
+
5815 starg_hw_mroute_cnt
+
5820 DEFUN (show_ip_mroute_summary
,
5821 show_ip_mroute_summary_cmd
,
5822 "show ip mroute [vrf NAME] summary",
5827 "Summary of all mroutes\n")
5830 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5835 show_mroute_summary(vrf
->info
, vty
);
5839 DEFUN (show_ip_mroute_summary_vrf_all
,
5840 show_ip_mroute_summary_vrf_all_cmd
,
5841 "show ip mroute vrf all summary",
5846 "Summary of all mroutes\n")
5850 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5851 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5852 show_mroute_summary(vrf
->info
, vty
);
5860 "show ip rib [vrf NAME] A.B.C.D",
5865 "Unicast address\n")
5868 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5869 struct in_addr addr
;
5870 const char *addr_str
;
5871 struct pim_nexthop nexthop
;
5872 char nexthop_addr_str
[PREFIX_STRLEN
];
5878 memset(&nexthop
, 0, sizeof(nexthop
));
5879 argv_find(argv
, argc
, "A.B.C.D", &idx
);
5880 addr_str
= argv
[idx
]->arg
;
5881 result
= inet_pton(AF_INET
, addr_str
, &addr
);
5883 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
5884 errno
, safe_strerror(errno
));
5888 if (!pim_nexthop_lookup(vrf
->info
, &nexthop
, addr
, 0)) {
5890 "Failure querying RIB nexthop for unicast address %s\n",
5896 "Address NextHop Interface Metric Preference\n");
5898 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
5899 nexthop_addr_str
, sizeof(nexthop_addr_str
));
5901 vty_out(vty
, "%-15s %-15s %-9s %6d %10d\n", addr_str
, nexthop_addr_str
,
5902 nexthop
.interface
? nexthop
.interface
->name
: "<ifname?>",
5903 nexthop
.mrib_route_metric
, nexthop
.mrib_metric_preference
);
5908 static void show_ssmpingd(struct pim_instance
*pim
, struct vty
*vty
)
5910 struct listnode
*node
;
5911 struct ssmpingd_sock
*ss
;
5915 "Source Socket Address Port Uptime Requests\n");
5917 if (!pim
->ssmpingd_list
)
5920 now
= pim_time_monotonic_sec();
5922 for (ALL_LIST_ELEMENTS_RO(pim
->ssmpingd_list
, node
, ss
)) {
5923 char source_str
[INET_ADDRSTRLEN
];
5925 struct sockaddr_in bind_addr
;
5926 socklen_t len
= sizeof(bind_addr
);
5927 char bind_addr_str
[INET_ADDRSTRLEN
];
5929 pim_inet4_dump("<src?>", ss
->source_addr
, source_str
,
5930 sizeof(source_str
));
5932 if (pim_socket_getsockname(
5933 ss
->sock_fd
, (struct sockaddr
*)&bind_addr
, &len
)) {
5935 "%% Failure reading socket name for ssmpingd source %s on fd=%d\n",
5936 source_str
, ss
->sock_fd
);
5939 pim_inet4_dump("<addr?>", bind_addr
.sin_addr
, bind_addr_str
,
5940 sizeof(bind_addr_str
));
5941 pim_time_uptime(ss_uptime
, sizeof(ss_uptime
),
5942 now
- ss
->creation
);
5944 vty_out(vty
, "%-15s %6d %-15s %5d %8s %8lld\n", source_str
,
5945 ss
->sock_fd
, bind_addr_str
, ntohs(bind_addr
.sin_port
),
5946 ss_uptime
, (long long)ss
->requests
);
5950 DEFUN (show_ip_ssmpingd
,
5951 show_ip_ssmpingd_cmd
,
5952 "show ip ssmpingd [vrf NAME]",
5959 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5964 show_ssmpingd(vrf
->info
, vty
);
5968 static int pim_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
5969 const char *rp
, const char *group
,
5974 result
= pim_rp_new_config(pim
, rp
, group
, plist
);
5976 if (result
== PIM_GROUP_BAD_ADDR_MASK_COMBO
) {
5977 vty_out(vty
, "%% Inconsistent address and mask: %s\n",
5979 return CMD_WARNING_CONFIG_FAILED
;
5982 if (result
== PIM_GROUP_BAD_ADDRESS
) {
5983 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
5984 return CMD_WARNING_CONFIG_FAILED
;
5987 if (result
== PIM_RP_BAD_ADDRESS
) {
5988 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
5989 return CMD_WARNING_CONFIG_FAILED
;
5992 if (result
== PIM_RP_NO_PATH
) {
5993 vty_out(vty
, "%% No Path to RP address specified: %s\n", rp
);
5997 if (result
== PIM_GROUP_OVERLAP
) {
5999 "%% Group range specified cannot exact match another\n");
6000 return CMD_WARNING_CONFIG_FAILED
;
6003 if (result
== PIM_GROUP_PFXLIST_OVERLAP
) {
6005 "%% This group is already covered by a RP prefix-list\n");
6006 return CMD_WARNING_CONFIG_FAILED
;
6009 if (result
== PIM_RP_PFXLIST_IN_USE
) {
6011 "%% The same prefix-list cannot be applied to multiple RPs\n");
6012 return CMD_WARNING_CONFIG_FAILED
;
6015 if (result
== PIM_GROUP_BAD_ADDR_MASK_COMBO
) {
6016 vty_out(vty
, "%% Inconsistent address and mask: %s\n",
6018 return CMD_WARNING_CONFIG_FAILED
;
6024 static int pim_cmd_spt_switchover(struct pim_instance
*pim
,
6025 enum pim_spt_switchover spt
,
6028 pim
->spt
.switchover
= spt
;
6030 switch (pim
->spt
.switchover
) {
6031 case PIM_SPT_IMMEDIATE
:
6032 XFREE(MTYPE_PIM_SPT_PLIST_NAME
, pim
->spt
.plist
);
6034 pim_upstream_add_lhr_star_pimreg(pim
);
6036 case PIM_SPT_INFINITY
:
6037 pim_upstream_remove_lhr_star_pimreg(pim
, plist
);
6039 XFREE(MTYPE_PIM_SPT_PLIST_NAME
, pim
->spt
.plist
);
6043 XSTRDUP(MTYPE_PIM_SPT_PLIST_NAME
, plist
);
6050 DEFUN (ip_pim_spt_switchover_infinity
,
6051 ip_pim_spt_switchover_infinity_cmd
,
6052 "ip pim spt-switchover infinity-and-beyond",
6056 "Never switch to SPT Tree\n")
6058 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6059 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, NULL
);
6062 DEFUN (ip_pim_spt_switchover_infinity_plist
,
6063 ip_pim_spt_switchover_infinity_plist_cmd
,
6064 "ip pim spt-switchover infinity-and-beyond prefix-list WORD",
6068 "Never switch to SPT Tree\n"
6069 "Prefix-List to control which groups to switch\n"
6070 "Prefix-List name\n")
6072 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6073 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, argv
[5]->arg
);
6076 DEFUN (no_ip_pim_spt_switchover_infinity
,
6077 no_ip_pim_spt_switchover_infinity_cmd
,
6078 "no ip pim spt-switchover infinity-and-beyond",
6083 "Never switch to SPT Tree\n")
6085 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6086 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
6089 DEFUN (no_ip_pim_spt_switchover_infinity_plist
,
6090 no_ip_pim_spt_switchover_infinity_plist_cmd
,
6091 "no ip pim spt-switchover infinity-and-beyond prefix-list WORD",
6096 "Never switch to SPT Tree\n"
6097 "Prefix-List to control which groups to switch\n"
6098 "Prefix-List name\n")
6100 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6101 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
6104 DEFUN (ip_pim_joinprune_time
,
6105 ip_pim_joinprune_time_cmd
,
6106 "ip pim join-prune-interval (60-600)",
6108 "pim multicast routing\n"
6109 "Join Prune Send Interval\n"
6112 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6113 router
->t_periodic
= atoi(argv
[3]->arg
);
6117 DEFUN (no_ip_pim_joinprune_time
,
6118 no_ip_pim_joinprune_time_cmd
,
6119 "no ip pim join-prune-interval (60-600)",
6122 "pim multicast routing\n"
6123 "Join Prune Send Interval\n"
6126 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6127 router
->t_periodic
= PIM_DEFAULT_T_PERIODIC
;
6131 DEFUN (ip_pim_register_suppress
,
6132 ip_pim_register_suppress_cmd
,
6133 "ip pim register-suppress-time (5-60000)",
6135 "pim multicast routing\n"
6136 "Register Suppress Timer\n"
6139 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6140 router
->register_suppress_time
= atoi(argv
[3]->arg
);
6144 DEFUN (no_ip_pim_register_suppress
,
6145 no_ip_pim_register_suppress_cmd
,
6146 "no ip pim register-suppress-time (5-60000)",
6149 "pim multicast routing\n"
6150 "Register Suppress Timer\n"
6153 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6154 router
->register_suppress_time
= PIM_REGISTER_SUPPRESSION_TIME_DEFAULT
;
6158 DEFUN (ip_pim_rp_keep_alive
,
6159 ip_pim_rp_keep_alive_cmd
,
6160 "ip pim rp keep-alive-timer (31-60000)",
6162 "pim multicast routing\n"
6164 "Keep alive Timer\n"
6167 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6168 pim
->rp_keep_alive_time
= atoi(argv
[4]->arg
);
6172 DEFUN (no_ip_pim_rp_keep_alive
,
6173 no_ip_pim_rp_keep_alive_cmd
,
6174 "no ip pim rp keep-alive-timer (31-60000)",
6177 "pim multicast routing\n"
6179 "Keep alive Timer\n"
6182 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6183 pim
->rp_keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
6187 DEFUN (ip_pim_keep_alive
,
6188 ip_pim_keep_alive_cmd
,
6189 "ip pim keep-alive-timer (31-60000)",
6191 "pim multicast routing\n"
6192 "Keep alive Timer\n"
6195 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6196 pim
->keep_alive_time
= atoi(argv
[3]->arg
);
6200 DEFUN (no_ip_pim_keep_alive
,
6201 no_ip_pim_keep_alive_cmd
,
6202 "no ip pim keep-alive-timer (31-60000)",
6205 "pim multicast routing\n"
6206 "Keep alive Timer\n"
6209 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6210 pim
->keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
6214 DEFUN (ip_pim_packets
,
6216 "ip pim packets (1-100)",
6218 "pim multicast routing\n"
6219 "packets to process at one time per fd\n"
6220 "Number of packets\n")
6222 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6223 router
->packet_process
= atoi(argv
[3]->arg
);
6227 DEFUN (no_ip_pim_packets
,
6228 no_ip_pim_packets_cmd
,
6229 "no ip pim packets (1-100)",
6232 "pim multicast routing\n"
6233 "packets to process at one time per fd\n"
6234 "Number of packets\n")
6236 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6237 router
->packet_process
= PIM_DEFAULT_PACKET_PROCESS
;
6241 DEFUN (ip_pim_v6_secondary
,
6242 ip_pim_v6_secondary_cmd
,
6243 "ip pim send-v6-secondary",
6245 "pim multicast routing\n"
6246 "Send v6 secondary addresses\n")
6248 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6249 pim
->send_v6_secondary
= 1;
6254 DEFUN (no_ip_pim_v6_secondary
,
6255 no_ip_pim_v6_secondary_cmd
,
6256 "no ip pim send-v6-secondary",
6259 "pim multicast routing\n"
6260 "Send v6 secondary addresses\n")
6262 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6263 pim
->send_v6_secondary
= 0;
6270 "ip pim rp A.B.C.D [A.B.C.D/M]",
6272 "pim multicast routing\n"
6274 "ip address of RP\n"
6275 "Group Address range to cover\n")
6277 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6280 if (argc
== (idx_ipv4
+ 1))
6281 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
6284 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
6285 argv
[idx_ipv4
+ 1]->arg
, NULL
);
6288 DEFUN (ip_pim_rp_prefix_list
,
6289 ip_pim_rp_prefix_list_cmd
,
6290 "ip pim rp A.B.C.D prefix-list WORD",
6292 "pim multicast routing\n"
6294 "ip address of RP\n"
6295 "group prefix-list filter\n"
6296 "Name of a prefix-list\n")
6298 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6299 return pim_rp_cmd_worker(pim
, vty
, argv
[3]->arg
, NULL
, argv
[5]->arg
);
6302 static int pim_no_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
6303 const char *rp
, const char *group
,
6306 int result
= pim_rp_del_config(pim
, rp
, group
, plist
);
6308 if (result
== PIM_GROUP_BAD_ADDRESS
) {
6309 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
6310 return CMD_WARNING_CONFIG_FAILED
;
6313 if (result
== PIM_RP_BAD_ADDRESS
) {
6314 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
6315 return CMD_WARNING_CONFIG_FAILED
;
6318 if (result
== PIM_RP_NOT_FOUND
) {
6319 vty_out(vty
, "%% Unable to find specified RP\n");
6320 return CMD_WARNING_CONFIG_FAILED
;
6326 DEFUN (no_ip_pim_rp
,
6328 "no ip pim rp A.B.C.D [A.B.C.D/M]",
6331 "pim multicast routing\n"
6333 "ip address of RP\n"
6334 "Group Address range to cover\n")
6336 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6337 int idx_ipv4
= 4, idx_group
= 0;
6339 if (argv_find(argv
, argc
, "A.B.C.D/M", &idx_group
))
6340 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
6341 argv
[idx_group
]->arg
, NULL
);
6343 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
6347 DEFUN (no_ip_pim_rp_prefix_list
,
6348 no_ip_pim_rp_prefix_list_cmd
,
6349 "no ip pim rp A.B.C.D prefix-list WORD",
6352 "pim multicast routing\n"
6354 "ip address of RP\n"
6355 "group prefix-list filter\n"
6356 "Name of a prefix-list\n")
6358 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6359 return pim_no_rp_cmd_worker(pim
, vty
, argv
[4]->arg
, NULL
, argv
[6]->arg
);
6362 static int pim_ssm_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
6365 int result
= pim_ssm_range_set(pim
, pim
->vrf_id
, plist
);
6367 if (result
== PIM_SSM_ERR_NONE
)
6371 case PIM_SSM_ERR_NO_VRF
:
6372 vty_out(vty
, "%% VRF doesn't exist\n");
6374 case PIM_SSM_ERR_DUP
:
6375 vty_out(vty
, "%% duplicate config\n");
6378 vty_out(vty
, "%% ssm range config failed\n");
6381 return CMD_WARNING_CONFIG_FAILED
;
6384 DEFUN (ip_pim_ssm_prefix_list
,
6385 ip_pim_ssm_prefix_list_cmd
,
6386 "ip pim ssm prefix-list WORD",
6388 "pim multicast routing\n"
6389 "Source Specific Multicast\n"
6390 "group range prefix-list filter\n"
6391 "Name of a prefix-list\n")
6393 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6394 return pim_ssm_cmd_worker(pim
, vty
, argv
[4]->arg
);
6397 DEFUN (no_ip_pim_ssm_prefix_list
,
6398 no_ip_pim_ssm_prefix_list_cmd
,
6399 "no ip pim ssm prefix-list",
6402 "pim multicast routing\n"
6403 "Source Specific Multicast\n"
6404 "group range prefix-list filter\n")
6406 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6407 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
6410 DEFUN (no_ip_pim_ssm_prefix_list_name
,
6411 no_ip_pim_ssm_prefix_list_name_cmd
,
6412 "no ip pim ssm prefix-list WORD",
6415 "pim multicast routing\n"
6416 "Source Specific Multicast\n"
6417 "group range prefix-list filter\n"
6418 "Name of a prefix-list\n")
6420 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6421 struct pim_ssm
*ssm
= pim
->ssm_info
;
6423 if (ssm
->plist_name
&& !strcmp(ssm
->plist_name
, argv
[5]->arg
))
6424 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
6426 vty_out(vty
, "%% pim ssm prefix-list %s doesn't exist\n", argv
[5]->arg
);
6428 return CMD_WARNING_CONFIG_FAILED
;
6431 static void ip_pim_ssm_show_group_range(struct pim_instance
*pim
,
6432 struct vty
*vty
, bool uj
)
6434 struct pim_ssm
*ssm
= pim
->ssm_info
;
6435 const char *range_str
=
6436 ssm
->plist_name
? ssm
->plist_name
: PIM_SSM_STANDARD_RANGE
;
6440 json
= json_object_new_object();
6441 json_object_string_add(json
, "ssmGroups", range_str
);
6442 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
6443 json
, JSON_C_TO_STRING_PRETTY
));
6444 json_object_free(json
);
6446 vty_out(vty
, "SSM group range : %s\n", range_str
);
6449 DEFUN (show_ip_pim_ssm_range
,
6450 show_ip_pim_ssm_range_cmd
,
6451 "show ip pim [vrf NAME] group-type [json]",
6460 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6461 bool uj
= use_json(argc
, argv
);
6466 ip_pim_ssm_show_group_range(vrf
->info
, vty
, uj
);
6471 static void ip_pim_ssm_show_group_type(struct pim_instance
*pim
,
6472 struct vty
*vty
, bool uj
,
6475 struct in_addr group_addr
;
6476 const char *type_str
;
6479 result
= inet_pton(AF_INET
, group
, &group_addr
);
6481 type_str
= "invalid";
6483 if (pim_is_group_224_4(group_addr
))
6485 pim_is_grp_ssm(pim
, group_addr
) ? "SSM" : "ASM";
6487 type_str
= "not-multicast";
6492 json
= json_object_new_object();
6493 json_object_string_add(json
, "groupType", type_str
);
6494 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
6495 json
, JSON_C_TO_STRING_PRETTY
));
6496 json_object_free(json
);
6498 vty_out(vty
, "Group type : %s\n", type_str
);
6501 DEFUN (show_ip_pim_group_type
,
6502 show_ip_pim_group_type_cmd
,
6503 "show ip pim [vrf NAME] group-type A.B.C.D [json]",
6508 "multicast group type\n"
6513 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6514 bool uj
= use_json(argc
, argv
);
6519 argv_find(argv
, argc
, "A.B.C.D", &idx
);
6520 ip_pim_ssm_show_group_type(vrf
->info
, vty
, uj
, argv
[idx
]->arg
);
6525 DEFUN (show_ip_pim_bsr
,
6526 show_ip_pim_bsr_cmd
,
6527 "show ip pim bsr [json]",
6531 "boot-strap router information\n"
6535 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6536 bool uj
= use_json(argc
, argv
);
6541 pim_show_bsr(vrf
->info
, vty
, uj
);
6548 "ip ssmpingd [A.B.C.D]",
6553 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6556 struct in_addr source_addr
;
6557 const char *source_str
= (argc
== 3) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
6559 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
6561 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
6562 source_str
, errno
, safe_strerror(errno
));
6563 return CMD_WARNING_CONFIG_FAILED
;
6566 result
= pim_ssmpingd_start(pim
, source_addr
);
6568 vty_out(vty
, "%% Failure starting ssmpingd for source %s: %d\n",
6569 source_str
, result
);
6570 return CMD_WARNING_CONFIG_FAILED
;
6576 DEFUN (no_ip_ssmpingd
,
6578 "no ip ssmpingd [A.B.C.D]",
6584 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6587 struct in_addr source_addr
;
6588 const char *source_str
= (argc
== 4) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
6590 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
6592 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
6593 source_str
, errno
, safe_strerror(errno
));
6594 return CMD_WARNING_CONFIG_FAILED
;
6597 result
= pim_ssmpingd_stop(pim
, source_addr
);
6599 vty_out(vty
, "%% Failure stopping ssmpingd for source %s: %d\n",
6600 source_str
, result
);
6601 return CMD_WARNING_CONFIG_FAILED
;
6611 "pim multicast routing\n"
6612 "Enable PIM ECMP \n")
6614 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6615 pim
->ecmp_enable
= true;
6620 DEFUN (no_ip_pim_ecmp
,
6625 "pim multicast routing\n"
6626 "Disable PIM ECMP \n")
6628 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6629 pim
->ecmp_enable
= false;
6634 DEFUN (ip_pim_ecmp_rebalance
,
6635 ip_pim_ecmp_rebalance_cmd
,
6636 "ip pim ecmp rebalance",
6638 "pim multicast routing\n"
6639 "Enable PIM ECMP \n"
6640 "Enable PIM ECMP Rebalance\n")
6642 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6643 pim
->ecmp_enable
= true;
6644 pim
->ecmp_rebalance_enable
= true;
6649 DEFUN (no_ip_pim_ecmp_rebalance
,
6650 no_ip_pim_ecmp_rebalance_cmd
,
6651 "no ip pim ecmp rebalance",
6654 "pim multicast routing\n"
6655 "Disable PIM ECMP \n"
6656 "Disable PIM ECMP Rebalance\n")
6658 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6659 pim
->ecmp_rebalance_enable
= false;
6664 static int pim_cmd_igmp_start(struct vty
*vty
, struct interface
*ifp
)
6666 struct pim_interface
*pim_ifp
;
6667 uint8_t need_startup
= 0;
6669 pim_ifp
= ifp
->info
;
6672 pim_ifp
= pim_if_new(ifp
, true, false, false,
6673 false /*vxlan_term*/);
6675 vty_out(vty
, "Could not enable IGMP on interface %s\n",
6677 return CMD_WARNING_CONFIG_FAILED
;
6681 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
6682 PIM_IF_DO_IGMP(pim_ifp
->options
);
6687 /* 'ip igmp' executed multiple times, with need_startup
6688 avoid multiple if add all and membership refresh */
6690 pim_if_addr_add_all(ifp
);
6691 pim_if_membership_refresh(ifp
);
6697 DEFUN (interface_ip_igmp
,
6698 interface_ip_igmp_cmd
,
6703 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6705 return pim_cmd_igmp_start(vty
, ifp
);
6708 DEFUN (interface_no_ip_igmp
,
6709 interface_no_ip_igmp_cmd
,
6715 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6716 struct pim_interface
*pim_ifp
= ifp
->info
;
6721 PIM_IF_DONT_IGMP(pim_ifp
->options
);
6723 pim_if_membership_clear(ifp
);
6725 pim_if_addr_del_all_igmp(ifp
);
6727 if (!PIM_IF_TEST_PIM(pim_ifp
->options
)) {
6734 DEFUN (interface_ip_igmp_join
,
6735 interface_ip_igmp_join_cmd
,
6736 "ip igmp join A.B.C.D A.B.C.D",
6739 "IGMP join multicast group\n"
6740 "Multicast group address\n"
6743 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6746 const char *group_str
;
6747 const char *source_str
;
6748 struct in_addr group_addr
;
6749 struct in_addr source_addr
;
6753 group_str
= argv
[idx_ipv4
]->arg
;
6754 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
6756 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
6757 errno
, safe_strerror(errno
));
6758 return CMD_WARNING_CONFIG_FAILED
;
6761 /* Source address */
6762 source_str
= argv
[idx_ipv4_2
]->arg
;
6763 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
6765 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
6766 source_str
, errno
, safe_strerror(errno
));
6767 return CMD_WARNING_CONFIG_FAILED
;
6770 CMD_FERR_RETURN(pim_if_igmp_join_add(ifp
, group_addr
, source_addr
),
6771 "Failure joining IGMP group: $ERR");
6776 DEFUN (interface_no_ip_igmp_join
,
6777 interface_no_ip_igmp_join_cmd
,
6778 "no ip igmp join A.B.C.D A.B.C.D",
6782 "IGMP join multicast group\n"
6783 "Multicast group address\n"
6786 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6789 const char *group_str
;
6790 const char *source_str
;
6791 struct in_addr group_addr
;
6792 struct in_addr source_addr
;
6796 group_str
= argv
[idx_ipv4
]->arg
;
6797 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
6799 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
6800 errno
, safe_strerror(errno
));
6801 return CMD_WARNING_CONFIG_FAILED
;
6804 /* Source address */
6805 source_str
= argv
[idx_ipv4_2
]->arg
;
6806 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
6808 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
6809 source_str
, errno
, safe_strerror(errno
));
6810 return CMD_WARNING_CONFIG_FAILED
;
6813 result
= pim_if_igmp_join_del(ifp
, group_addr
, source_addr
);
6816 "%% Failure leaving IGMP group %s source %s on interface %s: %d\n",
6817 group_str
, source_str
, ifp
->name
, result
);
6818 return CMD_WARNING_CONFIG_FAILED
;
6825 CLI reconfiguration affects the interface level (struct pim_interface).
6826 This function propagates the reconfiguration to every active socket
6829 static void igmp_sock_query_interval_reconfig(struct igmp_sock
*igmp
)
6831 struct interface
*ifp
;
6832 struct pim_interface
*pim_ifp
;
6836 /* other querier present? */
6838 if (igmp
->t_other_querier_timer
)
6841 /* this is the querier */
6843 zassert(igmp
->interface
);
6844 zassert(igmp
->interface
->info
);
6846 ifp
= igmp
->interface
;
6847 pim_ifp
= ifp
->info
;
6849 if (PIM_DEBUG_IGMP_TRACE
) {
6850 char ifaddr_str
[INET_ADDRSTRLEN
];
6851 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
6852 sizeof(ifaddr_str
));
6853 zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
6854 __PRETTY_FUNCTION__
, ifaddr_str
, ifp
->name
,
6855 pim_ifp
->igmp_default_query_interval
);
6859 igmp_startup_mode_on() will reset QQI:
6861 igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
6863 igmp_startup_mode_on(igmp
);
6866 static void igmp_sock_query_reschedule(struct igmp_sock
*igmp
)
6868 if (igmp
->t_igmp_query_timer
) {
6869 /* other querier present */
6870 zassert(igmp
->t_igmp_query_timer
);
6871 zassert(!igmp
->t_other_querier_timer
);
6873 pim_igmp_general_query_off(igmp
);
6874 pim_igmp_general_query_on(igmp
);
6876 zassert(igmp
->t_igmp_query_timer
);
6877 zassert(!igmp
->t_other_querier_timer
);
6879 /* this is the querier */
6881 zassert(!igmp
->t_igmp_query_timer
);
6882 zassert(igmp
->t_other_querier_timer
);
6884 pim_igmp_other_querier_timer_off(igmp
);
6885 pim_igmp_other_querier_timer_on(igmp
);
6887 zassert(!igmp
->t_igmp_query_timer
);
6888 zassert(igmp
->t_other_querier_timer
);
6892 static void change_query_interval(struct pim_interface
*pim_ifp
,
6895 struct listnode
*sock_node
;
6896 struct igmp_sock
*igmp
;
6898 pim_ifp
->igmp_default_query_interval
= query_interval
;
6900 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
6901 igmp_sock_query_interval_reconfig(igmp
);
6902 igmp_sock_query_reschedule(igmp
);
6906 static void change_query_max_response_time(struct pim_interface
*pim_ifp
,
6907 int query_max_response_time_dsec
)
6909 struct listnode
*sock_node
;
6910 struct igmp_sock
*igmp
;
6912 pim_ifp
->igmp_query_max_response_time_dsec
=
6913 query_max_response_time_dsec
;
6916 Below we modify socket/group/source timers in order to quickly
6917 reflect the change. Otherwise, those timers would eventually catch
6921 /* scan all sockets */
6922 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
6923 struct listnode
*grp_node
;
6924 struct igmp_group
*grp
;
6926 /* reschedule socket general query */
6927 igmp_sock_query_reschedule(igmp
);
6929 /* scan socket groups */
6930 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grp_node
,
6932 struct listnode
*src_node
;
6933 struct igmp_source
*src
;
6935 /* reset group timers for groups in EXCLUDE mode */
6936 if (grp
->group_filtermode_isexcl
) {
6937 igmp_group_reset_gmi(grp
);
6940 /* scan group sources */
6941 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
,
6944 /* reset source timers for sources with running
6946 if (src
->t_source_timer
) {
6947 igmp_source_reset_gmi(igmp
, grp
, src
);
6954 #define IGMP_QUERY_INTERVAL_MIN (1)
6955 #define IGMP_QUERY_INTERVAL_MAX (1800)
6957 DEFUN (interface_ip_igmp_query_interval
,
6958 interface_ip_igmp_query_interval_cmd
,
6959 "ip igmp query-interval (1-1800)",
6962 IFACE_IGMP_QUERY_INTERVAL_STR
6963 "Query interval in seconds\n")
6965 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6966 struct pim_interface
*pim_ifp
= ifp
->info
;
6968 int query_interval_dsec
;
6972 ret
= pim_cmd_igmp_start(vty
, ifp
);
6973 if (ret
!= CMD_SUCCESS
)
6975 pim_ifp
= ifp
->info
;
6978 query_interval
= atoi(argv
[3]->arg
);
6979 query_interval_dsec
= 10 * query_interval
;
6982 It seems we don't need to check bounds since command.c does it
6983 already, but we verify them anyway for extra safety.
6985 if (query_interval
< IGMP_QUERY_INTERVAL_MIN
) {
6987 "General query interval %d lower than minimum %d\n",
6988 query_interval
, IGMP_QUERY_INTERVAL_MIN
);
6989 return CMD_WARNING_CONFIG_FAILED
;
6991 if (query_interval
> IGMP_QUERY_INTERVAL_MAX
) {
6993 "General query interval %d higher than maximum %d\n",
6994 query_interval
, IGMP_QUERY_INTERVAL_MAX
);
6995 return CMD_WARNING_CONFIG_FAILED
;
6998 if (query_interval_dsec
<= pim_ifp
->igmp_query_max_response_time_dsec
) {
7000 "Can't set general query interval %d dsec <= query max response time %d dsec.\n",
7001 query_interval_dsec
,
7002 pim_ifp
->igmp_query_max_response_time_dsec
);
7003 return CMD_WARNING_CONFIG_FAILED
;
7006 change_query_interval(pim_ifp
, query_interval
);
7011 DEFUN (interface_no_ip_igmp_query_interval
,
7012 interface_no_ip_igmp_query_interval_cmd
,
7013 "no ip igmp query-interval",
7017 IFACE_IGMP_QUERY_INTERVAL_STR
)
7019 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7020 struct pim_interface
*pim_ifp
= ifp
->info
;
7021 int default_query_interval_dsec
;
7026 default_query_interval_dsec
= IGMP_GENERAL_QUERY_INTERVAL
* 10;
7028 if (default_query_interval_dsec
7029 <= pim_ifp
->igmp_query_max_response_time_dsec
) {
7031 "Can't set default general query interval %d dsec <= query max response time %d dsec.\n",
7032 default_query_interval_dsec
,
7033 pim_ifp
->igmp_query_max_response_time_dsec
);
7034 return CMD_WARNING_CONFIG_FAILED
;
7037 change_query_interval(pim_ifp
, IGMP_GENERAL_QUERY_INTERVAL
);
7042 DEFUN (interface_ip_igmp_version
,
7043 interface_ip_igmp_version_cmd
,
7044 "ip igmp version (2-3)",
7048 "IGMP version number\n")
7050 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7051 struct pim_interface
*pim_ifp
= ifp
->info
;
7052 int igmp_version
, old_version
= 0;
7056 ret
= pim_cmd_igmp_start(vty
, ifp
);
7057 if (ret
!= CMD_SUCCESS
)
7059 pim_ifp
= ifp
->info
;
7062 igmp_version
= atoi(argv
[3]->arg
);
7063 old_version
= pim_ifp
->igmp_version
;
7064 pim_ifp
->igmp_version
= igmp_version
;
7066 // Check if IGMP is Enabled otherwise, enable on interface
7067 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
7068 PIM_IF_DO_IGMP(pim_ifp
->options
);
7069 pim_if_addr_add_all(ifp
);
7070 pim_if_membership_refresh(ifp
);
7071 old_version
= igmp_version
;
7072 // avoid refreshing membership again.
7074 /* Current and new version is different refresh existing
7075 membership. Going from 3 -> 2 or 2 -> 3. */
7076 if (old_version
!= igmp_version
)
7077 pim_if_membership_refresh(ifp
);
7082 DEFUN (interface_no_ip_igmp_version
,
7083 interface_no_ip_igmp_version_cmd
,
7084 "no ip igmp version (2-3)",
7089 "IGMP version number\n")
7091 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7092 struct pim_interface
*pim_ifp
= ifp
->info
;
7097 pim_ifp
->igmp_version
= IGMP_DEFAULT_VERSION
;
7102 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
7103 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
7105 DEFUN (interface_ip_igmp_query_max_response_time
,
7106 interface_ip_igmp_query_max_response_time_cmd
,
7107 "ip igmp query-max-response-time (10-250)",
7110 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
7111 "Query response value in deci-seconds\n")
7113 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7114 struct pim_interface
*pim_ifp
= ifp
->info
;
7115 int query_max_response_time
;
7119 ret
= pim_cmd_igmp_start(vty
, ifp
);
7120 if (ret
!= CMD_SUCCESS
)
7122 pim_ifp
= ifp
->info
;
7125 query_max_response_time
= atoi(argv
[3]->arg
);
7127 if (query_max_response_time
7128 >= pim_ifp
->igmp_default_query_interval
* 10) {
7130 "Can't set query max response time %d sec >= general query interval %d sec\n",
7131 query_max_response_time
,
7132 pim_ifp
->igmp_default_query_interval
);
7133 return CMD_WARNING_CONFIG_FAILED
;
7136 change_query_max_response_time(pim_ifp
, query_max_response_time
);
7141 DEFUN (interface_no_ip_igmp_query_max_response_time
,
7142 interface_no_ip_igmp_query_max_response_time_cmd
,
7143 "no ip igmp query-max-response-time (10-250)",
7147 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
7148 "Time for response in deci-seconds\n")
7150 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7151 struct pim_interface
*pim_ifp
= ifp
->info
;
7156 change_query_max_response_time(pim_ifp
,
7157 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
7162 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
7163 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
7165 DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec
,
7166 interface_ip_igmp_query_max_response_time_dsec_cmd
,
7167 "ip igmp query-max-response-time-dsec (10-250)",
7170 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
7171 "Query response value in deciseconds\n")
7173 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7174 struct pim_interface
*pim_ifp
= ifp
->info
;
7175 int query_max_response_time_dsec
;
7176 int default_query_interval_dsec
;
7180 ret
= pim_cmd_igmp_start(vty
, ifp
);
7181 if (ret
!= CMD_SUCCESS
)
7183 pim_ifp
= ifp
->info
;
7186 query_max_response_time_dsec
= atoi(argv
[4]->arg
);
7188 default_query_interval_dsec
= 10 * pim_ifp
->igmp_default_query_interval
;
7190 if (query_max_response_time_dsec
>= default_query_interval_dsec
) {
7192 "Can't set query max response time %d dsec >= general query interval %d dsec\n",
7193 query_max_response_time_dsec
,
7194 default_query_interval_dsec
);
7195 return CMD_WARNING_CONFIG_FAILED
;
7198 change_query_max_response_time(pim_ifp
, query_max_response_time_dsec
);
7203 DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec
,
7204 interface_no_ip_igmp_query_max_response_time_dsec_cmd
,
7205 "no ip igmp query-max-response-time-dsec",
7209 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
)
7211 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7212 struct pim_interface
*pim_ifp
= ifp
->info
;
7217 change_query_max_response_time(pim_ifp
,
7218 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
7223 #define IGMP_LAST_MEMBER_QUERY_COUNT_MIN (1)
7224 #define IGMP_LAST_MEMBER_QUERY_COUNT_MAX (7)
7226 DEFUN (interface_ip_igmp_last_member_query_count
,
7227 interface_ip_igmp_last_member_query_count_cmd
,
7228 "ip igmp last-member-query-count (1-7)",
7231 IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR
7232 "Last member query count\n")
7234 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7235 struct pim_interface
*pim_ifp
= ifp
->info
;
7236 int last_member_query_count
;
7240 ret
= pim_cmd_igmp_start(vty
, ifp
);
7241 if (ret
!= CMD_SUCCESS
)
7243 pim_ifp
= ifp
->info
;
7246 last_member_query_count
= atoi(argv
[3]->arg
);
7248 pim_ifp
->igmp_last_member_query_count
= last_member_query_count
;
7253 DEFUN (interface_no_ip_igmp_last_member_query_count
,
7254 interface_no_ip_igmp_last_member_query_count_cmd
,
7255 "no ip igmp last-member-query-count",
7259 IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR
)
7261 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7262 struct pim_interface
*pim_ifp
= ifp
->info
;
7267 pim_ifp
->igmp_last_member_query_count
=
7268 IGMP_DEFAULT_ROBUSTNESS_VARIABLE
;
7273 #define IGMP_LAST_MEMBER_QUERY_INTERVAL_MIN (1)
7274 #define IGMP_LAST_MEMBER_QUERY_INTERVAL_MAX (255)
7276 DEFUN (interface_ip_igmp_last_member_query_interval
,
7277 interface_ip_igmp_last_member_query_interval_cmd
,
7278 "ip igmp last-member-query-interval (1-255)",
7281 IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR
7282 "Last member query interval in deciseconds\n")
7284 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7285 struct pim_interface
*pim_ifp
= ifp
->info
;
7286 int last_member_query_interval
;
7290 ret
= pim_cmd_igmp_start(vty
, ifp
);
7291 if (ret
!= CMD_SUCCESS
)
7293 pim_ifp
= ifp
->info
;
7296 last_member_query_interval
= atoi(argv
[3]->arg
);
7297 pim_ifp
->igmp_specific_query_max_response_time_dsec
7298 = last_member_query_interval
;
7303 DEFUN (interface_no_ip_igmp_last_member_query_interval
,
7304 interface_no_ip_igmp_last_member_query_interval_cmd
,
7305 "no ip igmp last-member-query-interval",
7309 IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR
)
7311 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7312 struct pim_interface
*pim_ifp
= ifp
->info
;
7317 pim_ifp
->igmp_specific_query_max_response_time_dsec
=
7318 IGMP_SPECIFIC_QUERY_MAX_RESPONSE_TIME_DSEC
;
7323 DEFUN (interface_ip_pim_drprio
,
7324 interface_ip_pim_drprio_cmd
,
7325 "ip pim drpriority (1-4294967295)",
7328 "Set the Designated Router Election Priority\n"
7329 "Value of the new DR Priority\n")
7331 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7333 struct pim_interface
*pim_ifp
= ifp
->info
;
7334 uint32_t old_dr_prio
;
7337 vty_out(vty
, "Please enable PIM on interface, first\n");
7338 return CMD_WARNING_CONFIG_FAILED
;
7341 old_dr_prio
= pim_ifp
->pim_dr_priority
;
7343 pim_ifp
->pim_dr_priority
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
7345 if (old_dr_prio
!= pim_ifp
->pim_dr_priority
) {
7346 pim_if_dr_election(ifp
);
7347 pim_hello_restart_now(ifp
);
7353 DEFUN (interface_no_ip_pim_drprio
,
7354 interface_no_ip_pim_drprio_cmd
,
7355 "no ip pim drpriority [(1-4294967295)]",
7359 "Revert the Designated Router Priority to default\n"
7360 "Old Value of the Priority\n")
7362 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7363 struct pim_interface
*pim_ifp
= ifp
->info
;
7366 vty_out(vty
, "Pim not enabled on this interface\n");
7367 return CMD_WARNING_CONFIG_FAILED
;
7370 if (pim_ifp
->pim_dr_priority
!= PIM_DEFAULT_DR_PRIORITY
) {
7371 pim_ifp
->pim_dr_priority
= PIM_DEFAULT_DR_PRIORITY
;
7372 pim_if_dr_election(ifp
);
7373 pim_hello_restart_now(ifp
);
7379 static int pim_cmd_interface_add(struct interface
*ifp
)
7381 struct pim_interface
*pim_ifp
= ifp
->info
;
7384 pim_ifp
= pim_if_new(ifp
, false, true, false,
7385 false /*vxlan_term*/);
7390 PIM_IF_DO_PIM(pim_ifp
->options
);
7393 pim_if_addr_add_all(ifp
);
7394 pim_if_membership_refresh(ifp
);
7398 DEFPY_HIDDEN (pim_test_sg_keepalive
,
7399 pim_test_sg_keepalive_cmd
,
7400 "test pim [vrf NAME$name] keepalive-reset A.B.C.D$source A.B.C.D$group",
7404 "Reset the Keepalive Timer\n"
7405 "The Source we are resetting\n"
7406 "The Group we are resetting\n")
7408 struct pim_upstream
*up
;
7409 struct pim_instance
*pim
;
7410 struct prefix_sg sg
;
7416 pim
= pim_get_pim_instance(VRF_DEFAULT
);
7418 struct vrf
*vrf
= vrf_lookup_by_name(name
);
7421 vty_out(vty
, "%% Vrf specified: %s does not exist\n",
7426 pim
= pim_get_pim_instance(vrf
->vrf_id
);
7430 vty_out(vty
, "%% Unable to find pim instance\n");
7434 up
= pim_upstream_find(pim
, &sg
);
7436 vty_out(vty
, "%% Unable to find %s specified\n",
7437 pim_str_sg_dump(&sg
));
7441 vty_out(vty
, "Setting %s to current keep alive time: %d\n",
7442 pim_str_sg_dump(&sg
), pim
->keep_alive_time
);
7443 pim_upstream_keep_alive_timer_start(up
, pim
->keep_alive_time
);
7448 DEFPY_HIDDEN (interface_ip_pim_activeactive
,
7449 interface_ip_pim_activeactive_cmd
,
7450 "[no$no] ip pim active-active",
7454 "Mark interface as Active-Active for MLAG operations, Hidden because not finished yet\n")
7456 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7457 struct pim_interface
*pim_ifp
;
7459 if (!no
&& !pim_cmd_interface_add(ifp
)) {
7460 vty_out(vty
, "Could not enable PIM SM active-active on interface\n");
7461 return CMD_WARNING_CONFIG_FAILED
;
7464 pim_ifp
= ifp
->info
;
7466 pim_ifp
->activeactive
= false;
7468 pim_ifp
->activeactive
= true;
7473 DEFUN_HIDDEN (interface_ip_pim_ssm
,
7474 interface_ip_pim_ssm_cmd
,
7480 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7482 if (!pim_cmd_interface_add(ifp
)) {
7483 vty_out(vty
, "Could not enable PIM SM on interface\n");
7484 return CMD_WARNING_CONFIG_FAILED
;
7488 "WARN: Enabled PIM SM on interface; configure PIM SSM "
7489 "range if needed\n");
7493 static int interface_ip_pim_helper(struct vty
*vty
)
7495 struct pim_interface
*pim_ifp
;
7497 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7499 if (!pim_cmd_interface_add(ifp
)) {
7500 vty_out(vty
, "Could not enable PIM SM on interface\n");
7501 return CMD_WARNING_CONFIG_FAILED
;
7504 pim_ifp
= ifp
->info
;
7506 pim_if_create_pimreg(pim_ifp
->pim
);
7511 DEFUN_HIDDEN (interface_ip_pim_sm
,
7512 interface_ip_pim_sm_cmd
,
7518 return interface_ip_pim_helper(vty
);
7521 DEFUN (interface_ip_pim
,
7522 interface_ip_pim_cmd
,
7527 return interface_ip_pim_helper(vty
);
7530 static int pim_cmd_interface_delete(struct interface
*ifp
)
7532 struct pim_interface
*pim_ifp
= ifp
->info
;
7537 PIM_IF_DONT_PIM(pim_ifp
->options
);
7539 pim_if_membership_clear(ifp
);
7542 pim_sock_delete() removes all neighbors from
7543 pim_ifp->pim_neighbor_list.
7545 pim_sock_delete(ifp
, "pim unconfigured on interface");
7547 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
7548 pim_if_addr_del_all(ifp
);
7555 static int interface_no_ip_pim_helper(struct vty
*vty
)
7557 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7558 if (!pim_cmd_interface_delete(ifp
)) {
7559 vty_out(vty
, "Unable to delete interface information\n");
7560 return CMD_WARNING_CONFIG_FAILED
;
7566 DEFUN_HIDDEN (interface_no_ip_pim_ssm
,
7567 interface_no_ip_pim_ssm_cmd
,
7574 return interface_no_ip_pim_helper(vty
);
7577 DEFUN_HIDDEN (interface_no_ip_pim_sm
,
7578 interface_no_ip_pim_sm_cmd
,
7585 return interface_no_ip_pim_helper(vty
);
7588 DEFUN (interface_no_ip_pim
,
7589 interface_no_ip_pim_cmd
,
7595 return interface_no_ip_pim_helper(vty
);
7599 DEFUN(interface_ip_pim_boundary_oil
,
7600 interface_ip_pim_boundary_oil_cmd
,
7601 "ip multicast boundary oil WORD",
7603 "Generic multicast configuration options\n"
7604 "Define multicast boundary\n"
7605 "Filter OIL by group using prefix list\n"
7606 "Prefix list to filter OIL with\n")
7608 VTY_DECLVAR_CONTEXT(interface
, iif
);
7609 struct pim_interface
*pim_ifp
;
7612 argv_find(argv
, argc
, "WORD", &idx
);
7614 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
7616 if (pim_ifp
->boundary_oil_plist
)
7617 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
7619 pim_ifp
->boundary_oil_plist
=
7620 XSTRDUP(MTYPE_PIM_INTERFACE
, argv
[idx
]->arg
);
7622 /* Interface will be pruned from OIL on next Join */
7626 DEFUN(interface_no_ip_pim_boundary_oil
,
7627 interface_no_ip_pim_boundary_oil_cmd
,
7628 "no ip multicast boundary oil [WORD]",
7631 "Generic multicast configuration options\n"
7632 "Define multicast boundary\n"
7633 "Filter OIL by group using prefix list\n"
7634 "Prefix list to filter OIL with\n")
7636 VTY_DECLVAR_CONTEXT(interface
, iif
);
7637 struct pim_interface
*pim_ifp
;
7640 argv_find(argv
, argc
, "WORD", &idx
);
7642 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
7644 if (pim_ifp
->boundary_oil_plist
)
7645 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
7650 DEFUN (interface_ip_mroute
,
7651 interface_ip_mroute_cmd
,
7652 "ip mroute INTERFACE A.B.C.D",
7654 "Add multicast route\n"
7655 "Outgoing interface name\n"
7658 VTY_DECLVAR_CONTEXT(interface
, iif
);
7659 struct pim_interface
*pim_ifp
;
7660 struct pim_instance
*pim
;
7661 int idx_interface
= 2;
7663 struct interface
*oif
;
7664 const char *oifname
;
7665 const char *grp_str
;
7666 struct in_addr grp_addr
;
7667 struct in_addr src_addr
;
7670 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
7673 oifname
= argv
[idx_interface
]->arg
;
7674 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
7676 vty_out(vty
, "No such interface name %s\n", oifname
);
7680 grp_str
= argv
[idx_ipv4
]->arg
;
7681 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
7683 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
7684 errno
, safe_strerror(errno
));
7688 src_addr
.s_addr
= INADDR_ANY
;
7690 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
7691 vty_out(vty
, "Failed to add route\n");
7698 DEFUN (interface_ip_mroute_source
,
7699 interface_ip_mroute_source_cmd
,
7700 "ip mroute INTERFACE A.B.C.D A.B.C.D",
7702 "Add multicast route\n"
7703 "Outgoing interface name\n"
7707 VTY_DECLVAR_CONTEXT(interface
, iif
);
7708 struct pim_interface
*pim_ifp
;
7709 struct pim_instance
*pim
;
7710 int idx_interface
= 2;
7713 struct interface
*oif
;
7714 const char *oifname
;
7715 const char *grp_str
;
7716 struct in_addr grp_addr
;
7717 const char *src_str
;
7718 struct in_addr src_addr
;
7721 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
7724 oifname
= argv
[idx_interface
]->arg
;
7725 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
7727 vty_out(vty
, "No such interface name %s\n", oifname
);
7731 grp_str
= argv
[idx_ipv4
]->arg
;
7732 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
7734 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
7735 errno
, safe_strerror(errno
));
7739 src_str
= argv
[idx_ipv4_2
]->arg
;
7740 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
7742 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
7743 errno
, safe_strerror(errno
));
7747 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
7748 vty_out(vty
, "Failed to add route\n");
7755 DEFUN (interface_no_ip_mroute
,
7756 interface_no_ip_mroute_cmd
,
7757 "no ip mroute INTERFACE A.B.C.D",
7760 "Add multicast route\n"
7761 "Outgoing interface name\n"
7764 VTY_DECLVAR_CONTEXT(interface
, iif
);
7765 struct pim_interface
*pim_ifp
;
7766 struct pim_instance
*pim
;
7767 int idx_interface
= 3;
7769 struct interface
*oif
;
7770 const char *oifname
;
7771 const char *grp_str
;
7772 struct in_addr grp_addr
;
7773 struct in_addr src_addr
;
7776 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
7779 oifname
= argv
[idx_interface
]->arg
;
7780 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
7782 vty_out(vty
, "No such interface name %s\n", oifname
);
7786 grp_str
= argv
[idx_ipv4
]->arg
;
7787 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
7789 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
7790 errno
, safe_strerror(errno
));
7794 src_addr
.s_addr
= INADDR_ANY
;
7796 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
7797 vty_out(vty
, "Failed to remove route\n");
7804 DEFUN (interface_no_ip_mroute_source
,
7805 interface_no_ip_mroute_source_cmd
,
7806 "no ip mroute INTERFACE A.B.C.D A.B.C.D",
7809 "Add multicast route\n"
7810 "Outgoing interface name\n"
7814 VTY_DECLVAR_CONTEXT(interface
, iif
);
7815 struct pim_interface
*pim_ifp
;
7816 struct pim_instance
*pim
;
7817 int idx_interface
= 3;
7820 struct interface
*oif
;
7821 const char *oifname
;
7822 const char *grp_str
;
7823 struct in_addr grp_addr
;
7824 const char *src_str
;
7825 struct in_addr src_addr
;
7828 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
7831 oifname
= argv
[idx_interface
]->arg
;
7832 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
7834 vty_out(vty
, "No such interface name %s\n", oifname
);
7838 grp_str
= argv
[idx_ipv4
]->arg
;
7839 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
7841 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
7842 errno
, safe_strerror(errno
));
7846 src_str
= argv
[idx_ipv4_2
]->arg
;
7847 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
7849 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
7850 errno
, safe_strerror(errno
));
7854 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
7855 vty_out(vty
, "Failed to remove route\n");
7862 DEFUN (interface_ip_pim_hello
,
7863 interface_ip_pim_hello_cmd
,
7864 "ip pim hello (1-180) [(1-180)]",
7868 IFACE_PIM_HELLO_TIME_STR
7869 IFACE_PIM_HELLO_HOLD_STR
)
7871 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7874 struct pim_interface
*pim_ifp
= ifp
->info
;
7877 if (!pim_cmd_interface_add(ifp
)) {
7878 vty_out(vty
, "Could not enable PIM SM on interface\n");
7879 return CMD_WARNING_CONFIG_FAILED
;
7883 pim_ifp
= ifp
->info
;
7884 pim_ifp
->pim_hello_period
= strtol(argv
[idx_time
]->arg
, NULL
, 10);
7886 if (argc
== idx_hold
+ 1)
7887 pim_ifp
->pim_default_holdtime
=
7888 strtol(argv
[idx_hold
]->arg
, NULL
, 10);
7893 DEFUN (interface_no_ip_pim_hello
,
7894 interface_no_ip_pim_hello_cmd
,
7895 "no ip pim hello [(1-180) (1-180)]",
7900 IFACE_PIM_HELLO_TIME_STR
7901 IFACE_PIM_HELLO_HOLD_STR
)
7903 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7904 struct pim_interface
*pim_ifp
= ifp
->info
;
7907 vty_out(vty
, "Pim not enabled on this interface\n");
7908 return CMD_WARNING_CONFIG_FAILED
;
7911 pim_ifp
->pim_hello_period
= PIM_DEFAULT_HELLO_PERIOD
;
7912 pim_ifp
->pim_default_holdtime
= -1;
7923 PIM_DO_DEBUG_IGMP_EVENTS
;
7924 PIM_DO_DEBUG_IGMP_PACKETS
;
7925 PIM_DO_DEBUG_IGMP_TRACE
;
7929 DEFUN (no_debug_igmp
,
7936 PIM_DONT_DEBUG_IGMP_EVENTS
;
7937 PIM_DONT_DEBUG_IGMP_PACKETS
;
7938 PIM_DONT_DEBUG_IGMP_TRACE
;
7943 DEFUN (debug_igmp_events
,
7944 debug_igmp_events_cmd
,
7945 "debug igmp events",
7948 DEBUG_IGMP_EVENTS_STR
)
7950 PIM_DO_DEBUG_IGMP_EVENTS
;
7954 DEFUN (no_debug_igmp_events
,
7955 no_debug_igmp_events_cmd
,
7956 "no debug igmp events",
7960 DEBUG_IGMP_EVENTS_STR
)
7962 PIM_DONT_DEBUG_IGMP_EVENTS
;
7967 DEFUN (debug_igmp_packets
,
7968 debug_igmp_packets_cmd
,
7969 "debug igmp packets",
7972 DEBUG_IGMP_PACKETS_STR
)
7974 PIM_DO_DEBUG_IGMP_PACKETS
;
7978 DEFUN (no_debug_igmp_packets
,
7979 no_debug_igmp_packets_cmd
,
7980 "no debug igmp packets",
7984 DEBUG_IGMP_PACKETS_STR
)
7986 PIM_DONT_DEBUG_IGMP_PACKETS
;
7991 DEFUN (debug_igmp_trace
,
7992 debug_igmp_trace_cmd
,
7996 DEBUG_IGMP_TRACE_STR
)
7998 PIM_DO_DEBUG_IGMP_TRACE
;
8002 DEFUN (no_debug_igmp_trace
,
8003 no_debug_igmp_trace_cmd
,
8004 "no debug igmp trace",
8008 DEBUG_IGMP_TRACE_STR
)
8010 PIM_DONT_DEBUG_IGMP_TRACE
;
8015 DEFUN (debug_mroute
,
8021 PIM_DO_DEBUG_MROUTE
;
8025 DEFUN (debug_mroute_detail
,
8026 debug_mroute_detail_cmd
,
8027 "debug mroute detail",
8032 PIM_DO_DEBUG_MROUTE_DETAIL
;
8036 DEFUN (no_debug_mroute
,
8037 no_debug_mroute_cmd
,
8043 PIM_DONT_DEBUG_MROUTE
;
8047 DEFUN (no_debug_mroute_detail
,
8048 no_debug_mroute_detail_cmd
,
8049 "no debug mroute detail",
8055 PIM_DONT_DEBUG_MROUTE_DETAIL
;
8059 DEFUN (debug_pim_static
,
8060 debug_pim_static_cmd
,
8066 PIM_DO_DEBUG_STATIC
;
8070 DEFUN (no_debug_pim_static
,
8071 no_debug_pim_static_cmd
,
8072 "no debug pim static",
8078 PIM_DONT_DEBUG_STATIC
;
8089 PIM_DO_DEBUG_PIM_EVENTS
;
8090 PIM_DO_DEBUG_PIM_PACKETS
;
8091 PIM_DO_DEBUG_PIM_TRACE
;
8092 PIM_DO_DEBUG_MSDP_EVENTS
;
8093 PIM_DO_DEBUG_MSDP_PACKETS
;
8098 DEFUN (no_debug_pim
,
8105 PIM_DONT_DEBUG_PIM_EVENTS
;
8106 PIM_DONT_DEBUG_PIM_PACKETS
;
8107 PIM_DONT_DEBUG_PIM_TRACE
;
8108 PIM_DONT_DEBUG_MSDP_EVENTS
;
8109 PIM_DONT_DEBUG_MSDP_PACKETS
;
8111 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
8112 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
8118 DEFUN (debug_pim_nht
,
8123 "Nexthop Tracking\n")
8125 PIM_DO_DEBUG_PIM_NHT
;
8129 DEFUN (no_debug_pim_nht
,
8130 no_debug_pim_nht_cmd
,
8135 "Nexthop Tracking\n")
8137 PIM_DONT_DEBUG_PIM_NHT
;
8141 DEFUN (debug_pim_nht_rp
,
8142 debug_pim_nht_rp_cmd
,
8146 "Nexthop Tracking\n"
8147 "RP Nexthop Tracking\n")
8149 PIM_DO_DEBUG_PIM_NHT_RP
;
8153 DEFUN (no_debug_pim_nht_rp
,
8154 no_debug_pim_nht_rp_cmd
,
8155 "no debug pim nht rp",
8159 "Nexthop Tracking\n"
8160 "RP Nexthop Tracking\n")
8162 PIM_DONT_DEBUG_PIM_NHT_RP
;
8166 DEFUN (debug_pim_events
,
8167 debug_pim_events_cmd
,
8171 DEBUG_PIM_EVENTS_STR
)
8173 PIM_DO_DEBUG_PIM_EVENTS
;
8177 DEFUN (no_debug_pim_events
,
8178 no_debug_pim_events_cmd
,
8179 "no debug pim events",
8183 DEBUG_PIM_EVENTS_STR
)
8185 PIM_DONT_DEBUG_PIM_EVENTS
;
8189 DEFUN (debug_pim_packets
,
8190 debug_pim_packets_cmd
,
8191 "debug pim packets [<hello|joins|register>]",
8194 DEBUG_PIM_PACKETS_STR
8195 DEBUG_PIM_HELLO_PACKETS_STR
8196 DEBUG_PIM_J_P_PACKETS_STR
8197 DEBUG_PIM_PIM_REG_PACKETS_STR
)
8200 if (argv_find(argv
, argc
, "hello", &idx
)) {
8201 PIM_DO_DEBUG_PIM_HELLO
;
8202 vty_out(vty
, "PIM Hello debugging is on\n");
8203 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
8204 PIM_DO_DEBUG_PIM_J_P
;
8205 vty_out(vty
, "PIM Join/Prune debugging is on\n");
8206 } else if (argv_find(argv
, argc
, "register", &idx
)) {
8207 PIM_DO_DEBUG_PIM_REG
;
8208 vty_out(vty
, "PIM Register debugging is on\n");
8210 PIM_DO_DEBUG_PIM_PACKETS
;
8211 vty_out(vty
, "PIM Packet debugging is on \n");
8216 DEFUN (no_debug_pim_packets
,
8217 no_debug_pim_packets_cmd
,
8218 "no debug pim packets [<hello|joins|register>]",
8222 DEBUG_PIM_PACKETS_STR
8223 DEBUG_PIM_HELLO_PACKETS_STR
8224 DEBUG_PIM_J_P_PACKETS_STR
8225 DEBUG_PIM_PIM_REG_PACKETS_STR
)
8228 if (argv_find(argv
, argc
, "hello", &idx
)) {
8229 PIM_DONT_DEBUG_PIM_HELLO
;
8230 vty_out(vty
, "PIM Hello debugging is off \n");
8231 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
8232 PIM_DONT_DEBUG_PIM_J_P
;
8233 vty_out(vty
, "PIM Join/Prune debugging is off \n");
8234 } else if (argv_find(argv
, argc
, "register", &idx
)) {
8235 PIM_DONT_DEBUG_PIM_REG
;
8236 vty_out(vty
, "PIM Register debugging is off\n");
8238 PIM_DONT_DEBUG_PIM_PACKETS
;
8244 DEFUN (debug_pim_packetdump_send
,
8245 debug_pim_packetdump_send_cmd
,
8246 "debug pim packet-dump send",
8249 DEBUG_PIM_PACKETDUMP_STR
8250 DEBUG_PIM_PACKETDUMP_SEND_STR
)
8252 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND
;
8256 DEFUN (no_debug_pim_packetdump_send
,
8257 no_debug_pim_packetdump_send_cmd
,
8258 "no debug pim packet-dump send",
8262 DEBUG_PIM_PACKETDUMP_STR
8263 DEBUG_PIM_PACKETDUMP_SEND_STR
)
8265 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
8269 DEFUN (debug_pim_packetdump_recv
,
8270 debug_pim_packetdump_recv_cmd
,
8271 "debug pim packet-dump receive",
8274 DEBUG_PIM_PACKETDUMP_STR
8275 DEBUG_PIM_PACKETDUMP_RECV_STR
)
8277 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV
;
8281 DEFUN (no_debug_pim_packetdump_recv
,
8282 no_debug_pim_packetdump_recv_cmd
,
8283 "no debug pim packet-dump receive",
8287 DEBUG_PIM_PACKETDUMP_STR
8288 DEBUG_PIM_PACKETDUMP_RECV_STR
)
8290 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
8294 DEFUN (debug_pim_trace
,
8295 debug_pim_trace_cmd
,
8299 DEBUG_PIM_TRACE_STR
)
8301 PIM_DO_DEBUG_PIM_TRACE
;
8305 DEFUN (debug_pim_trace_detail
,
8306 debug_pim_trace_detail_cmd
,
8307 "debug pim trace detail",
8311 "Detailed Information\n")
8313 PIM_DO_DEBUG_PIM_TRACE_DETAIL
;
8317 DEFUN (no_debug_pim_trace
,
8318 no_debug_pim_trace_cmd
,
8319 "no debug pim trace",
8323 DEBUG_PIM_TRACE_STR
)
8325 PIM_DONT_DEBUG_PIM_TRACE
;
8329 DEFUN (no_debug_pim_trace_detail
,
8330 no_debug_pim_trace_detail_cmd
,
8331 "no debug pim trace detail",
8336 "Detailed Information\n")
8338 PIM_DONT_DEBUG_PIM_TRACE_DETAIL
;
8342 DEFUN (debug_ssmpingd
,
8348 PIM_DO_DEBUG_SSMPINGD
;
8352 DEFUN (no_debug_ssmpingd
,
8353 no_debug_ssmpingd_cmd
,
8354 "no debug ssmpingd",
8359 PIM_DONT_DEBUG_SSMPINGD
;
8363 DEFUN (debug_pim_zebra
,
8364 debug_pim_zebra_cmd
,
8368 DEBUG_PIM_ZEBRA_STR
)
8374 DEFUN (no_debug_pim_zebra
,
8375 no_debug_pim_zebra_cmd
,
8376 "no debug pim zebra",
8380 DEBUG_PIM_ZEBRA_STR
)
8382 PIM_DONT_DEBUG_ZEBRA
;
8386 DEFUN (debug_pim_vxlan
,
8387 debug_pim_vxlan_cmd
,
8391 DEBUG_PIM_VXLAN_STR
)
8397 DEFUN (no_debug_pim_vxlan
,
8398 no_debug_pim_vxlan_cmd
,
8399 "no debug pim vxlan",
8403 DEBUG_PIM_VXLAN_STR
)
8405 PIM_DONT_DEBUG_VXLAN
;
8415 PIM_DO_DEBUG_MSDP_EVENTS
;
8416 PIM_DO_DEBUG_MSDP_PACKETS
;
8420 DEFUN (no_debug_msdp
,
8427 PIM_DONT_DEBUG_MSDP_EVENTS
;
8428 PIM_DONT_DEBUG_MSDP_PACKETS
;
8432 DEFUN (debug_msdp_events
,
8433 debug_msdp_events_cmd
,
8434 "debug msdp events",
8437 DEBUG_MSDP_EVENTS_STR
)
8439 PIM_DO_DEBUG_MSDP_EVENTS
;
8443 DEFUN (no_debug_msdp_events
,
8444 no_debug_msdp_events_cmd
,
8445 "no debug msdp events",
8449 DEBUG_MSDP_EVENTS_STR
)
8451 PIM_DONT_DEBUG_MSDP_EVENTS
;
8455 DEFUN (debug_msdp_packets
,
8456 debug_msdp_packets_cmd
,
8457 "debug msdp packets",
8460 DEBUG_MSDP_PACKETS_STR
)
8462 PIM_DO_DEBUG_MSDP_PACKETS
;
8466 DEFUN (no_debug_msdp_packets
,
8467 no_debug_msdp_packets_cmd
,
8468 "no debug msdp packets",
8472 DEBUG_MSDP_PACKETS_STR
)
8474 PIM_DONT_DEBUG_MSDP_PACKETS
;
8478 DEFUN (debug_mtrace
,
8484 PIM_DO_DEBUG_MTRACE
;
8488 DEFUN (no_debug_mtrace
,
8489 no_debug_mtrace_cmd
,
8495 PIM_DONT_DEBUG_MTRACE
;
8510 DEFUN (no_debug_bsm
,
8523 DEFUN_NOSH (show_debugging_pim
,
8524 show_debugging_pim_cmd
,
8525 "show debugging [pim]",
8530 vty_out(vty
, "PIM debugging status\n");
8532 pim_debug_config_write(vty
);
8537 static int interface_pim_use_src_cmd_worker(struct vty
*vty
, const char *source
)
8540 struct in_addr source_addr
;
8541 int ret
= CMD_SUCCESS
;
8542 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8544 result
= inet_pton(AF_INET
, source
, &source_addr
);
8546 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", source
,
8547 errno
, safe_strerror(errno
));
8548 return CMD_WARNING_CONFIG_FAILED
;
8551 result
= pim_update_source_set(ifp
, source_addr
);
8555 case PIM_IFACE_NOT_FOUND
:
8556 ret
= CMD_WARNING_CONFIG_FAILED
;
8557 vty_out(vty
, "Pim not enabled on this interface\n");
8559 case PIM_UPDATE_SOURCE_DUP
:
8561 vty_out(vty
, "%% Source already set to %s\n", source
);
8564 ret
= CMD_WARNING_CONFIG_FAILED
;
8565 vty_out(vty
, "%% Source set failed\n");
8571 DEFUN (interface_pim_use_source
,
8572 interface_pim_use_source_cmd
,
8573 "ip pim use-source A.B.C.D",
8576 "Configure primary IP address\n"
8577 "source ip address\n")
8579 return interface_pim_use_src_cmd_worker(vty
, argv
[3]->arg
);
8582 DEFUN (interface_no_pim_use_source
,
8583 interface_no_pim_use_source_cmd
,
8584 "no ip pim use-source [A.B.C.D]",
8588 "Delete source IP address\n"
8589 "source ip address\n")
8591 return interface_pim_use_src_cmd_worker(vty
, "0.0.0.0");
8599 "Enables BFD support\n")
8601 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8602 struct pim_interface
*pim_ifp
= ifp
->info
;
8603 struct bfd_info
*bfd_info
= NULL
;
8606 if (!pim_cmd_interface_add(ifp
)) {
8607 vty_out(vty
, "Could not enable PIM SM on interface\n");
8611 pim_ifp
= ifp
->info
;
8613 bfd_info
= pim_ifp
->bfd_info
;
8615 if (!bfd_info
|| !CHECK_FLAG(bfd_info
->flags
, BFD_FLAG_PARAM_CFG
))
8616 pim_bfd_if_param_set(ifp
, BFD_DEF_MIN_RX
, BFD_DEF_MIN_TX
,
8617 BFD_DEF_DETECT_MULT
, 1);
8622 DEFUN (no_ip_pim_bfd
,
8628 "Disables BFD support\n")
8630 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8631 struct pim_interface
*pim_ifp
= ifp
->info
;
8634 vty_out(vty
, "Pim not enabled on this interface\n");
8638 if (pim_ifp
->bfd_info
) {
8639 pim_bfd_reg_dereg_all_nbr(ifp
, ZEBRA_BFD_DEST_DEREGISTER
);
8640 bfd_info_free(&(pim_ifp
->bfd_info
));
8651 "Enables BSM support on the interface\n")
8653 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8654 struct pim_interface
*pim_ifp
= ifp
->info
;
8657 if (!pim_cmd_interface_add(ifp
)) {
8658 vty_out(vty
, "Could not enable PIM SM on interface\n");
8663 pim_ifp
= ifp
->info
;
8664 pim_ifp
->bsm_enable
= true;
8669 DEFUN (no_ip_pim_bsm
,
8675 "Disables BSM support\n")
8677 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8678 struct pim_interface
*pim_ifp
= ifp
->info
;
8681 vty_out(vty
, "Pim not enabled on this interface\n");
8685 pim_ifp
->bsm_enable
= false;
8690 DEFUN (ip_pim_ucast_bsm
,
8691 ip_pim_ucast_bsm_cmd
,
8692 "ip pim unicast-bsm",
8695 "Accept/Send unicast BSM on the interface\n")
8697 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8698 struct pim_interface
*pim_ifp
= ifp
->info
;
8701 if (!pim_cmd_interface_add(ifp
)) {
8702 vty_out(vty
, "Could not enable PIM SM on interface\n");
8707 pim_ifp
= ifp
->info
;
8708 pim_ifp
->ucast_bsm_accept
= true;
8713 DEFUN (no_ip_pim_ucast_bsm
,
8714 no_ip_pim_ucast_bsm_cmd
,
8715 "no ip pim unicast-bsm",
8719 "Block send/receive unicast BSM on this interface\n")
8721 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8722 struct pim_interface
*pim_ifp
= ifp
->info
;
8725 vty_out(vty
, "Pim not enabled on this interface\n");
8729 pim_ifp
->ucast_bsm_accept
= false;
8738 #endif /* HAVE_BFDD */
8740 ip_pim_bfd_param_cmd
,
8741 "ip pim bfd (2-255) (50-60000) (50-60000)",
8744 "Enables BFD support\n"
8745 "Detect Multiplier\n"
8746 "Required min receive interval\n"
8747 "Desired min transmit interval\n")
8749 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8751 int idx_number_2
= 4;
8752 int idx_number_3
= 5;
8757 struct pim_interface
*pim_ifp
= ifp
->info
;
8760 if (!pim_cmd_interface_add(ifp
)) {
8761 vty_out(vty
, "Could not enable PIM SM on interface\n");
8766 if ((ret
= bfd_validate_param(
8767 vty
, argv
[idx_number
]->arg
, argv
[idx_number_2
]->arg
,
8768 argv
[idx_number_3
]->arg
, &dm_val
, &rx_val
, &tx_val
))
8772 pim_bfd_if_param_set(ifp
, rx_val
, tx_val
, dm_val
, 0);
8778 ALIAS(no_ip_pim_bfd
, no_ip_pim_bfd_param_cmd
,
8779 "no ip pim bfd (2-255) (50-60000) (50-60000)", NO_STR IP_STR PIM_STR
8780 "Enables BFD support\n"
8781 "Detect Multiplier\n"
8782 "Required min receive interval\n"
8783 "Desired min transmit interval\n")
8784 #endif /* !HAVE_BFDD */
8786 static int ip_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
8787 const char *peer
, const char *local
)
8789 enum pim_msdp_err result
;
8790 struct in_addr peer_addr
;
8791 struct in_addr local_addr
;
8792 int ret
= CMD_SUCCESS
;
8794 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
8796 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
8797 errno
, safe_strerror(errno
));
8798 return CMD_WARNING_CONFIG_FAILED
;
8801 result
= inet_pton(AF_INET
, local
, &local_addr
);
8803 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", local
,
8804 errno
, safe_strerror(errno
));
8805 return CMD_WARNING_CONFIG_FAILED
;
8808 result
= pim_msdp_peer_add(pim
, peer_addr
, local_addr
, "default",
8811 case PIM_MSDP_ERR_NONE
:
8813 case PIM_MSDP_ERR_OOM
:
8814 ret
= CMD_WARNING_CONFIG_FAILED
;
8815 vty_out(vty
, "%% Out of memory\n");
8817 case PIM_MSDP_ERR_PEER_EXISTS
:
8819 vty_out(vty
, "%% Peer exists\n");
8821 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
8822 ret
= CMD_WARNING_CONFIG_FAILED
;
8823 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
8826 ret
= CMD_WARNING_CONFIG_FAILED
;
8827 vty_out(vty
, "%% peer add failed\n");
8833 DEFUN_HIDDEN (ip_msdp_peer
,
8835 "ip msdp peer A.B.C.D source A.B.C.D",
8838 "Configure MSDP peer\n"
8840 "Source address for TCP connection\n"
8841 "local ip address\n")
8843 PIM_DECLVAR_CONTEXT(vrf
, pim
);
8844 return ip_msdp_peer_cmd_worker(pim
, vty
, argv
[3]->arg
, argv
[5]->arg
);
8847 static int ip_no_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
8850 enum pim_msdp_err result
;
8851 struct in_addr peer_addr
;
8853 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
8855 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
8856 errno
, safe_strerror(errno
));
8857 return CMD_WARNING_CONFIG_FAILED
;
8860 result
= pim_msdp_peer_del(pim
, peer_addr
);
8862 case PIM_MSDP_ERR_NONE
:
8864 case PIM_MSDP_ERR_NO_PEER
:
8865 vty_out(vty
, "%% Peer does not exist\n");
8868 vty_out(vty
, "%% peer del failed\n");
8871 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
8874 DEFUN_HIDDEN (no_ip_msdp_peer
,
8875 no_ip_msdp_peer_cmd
,
8876 "no ip msdp peer A.B.C.D",
8880 "Delete MSDP peer\n"
8881 "peer ip address\n")
8883 PIM_DECLVAR_CONTEXT(vrf
, pim
);
8884 return ip_no_msdp_peer_cmd_worker(pim
, vty
, argv
[4]->arg
);
8887 static int ip_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
8888 struct vty
*vty
, const char *mg
,
8891 enum pim_msdp_err result
;
8892 struct in_addr mbr_ip
;
8893 int ret
= CMD_SUCCESS
;
8895 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
8897 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
8898 errno
, safe_strerror(errno
));
8899 return CMD_WARNING_CONFIG_FAILED
;
8902 result
= pim_msdp_mg_mbr_add(pim
, mg
, mbr_ip
);
8904 case PIM_MSDP_ERR_NONE
:
8906 case PIM_MSDP_ERR_OOM
:
8907 ret
= CMD_WARNING_CONFIG_FAILED
;
8908 vty_out(vty
, "%% Out of memory\n");
8910 case PIM_MSDP_ERR_MG_MBR_EXISTS
:
8912 vty_out(vty
, "%% mesh-group member exists\n");
8914 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
8915 ret
= CMD_WARNING_CONFIG_FAILED
;
8916 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
8919 ret
= CMD_WARNING_CONFIG_FAILED
;
8920 vty_out(vty
, "%% member add failed\n");
8926 DEFUN (ip_msdp_mesh_group_member
,
8927 ip_msdp_mesh_group_member_cmd
,
8928 "ip msdp mesh-group WORD member A.B.C.D",
8931 "Configure MSDP mesh-group\n"
8933 "mesh group member\n"
8934 "peer ip address\n")
8936 PIM_DECLVAR_CONTEXT(vrf
, pim
);
8937 return ip_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[3]->arg
,
8941 static int ip_no_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
8946 enum pim_msdp_err result
;
8947 struct in_addr mbr_ip
;
8949 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
8951 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
8952 errno
, safe_strerror(errno
));
8953 return CMD_WARNING_CONFIG_FAILED
;
8956 result
= pim_msdp_mg_mbr_del(pim
, mg
, mbr_ip
);
8958 case PIM_MSDP_ERR_NONE
:
8960 case PIM_MSDP_ERR_NO_MG
:
8961 vty_out(vty
, "%% mesh-group does not exist\n");
8963 case PIM_MSDP_ERR_NO_MG_MBR
:
8964 vty_out(vty
, "%% mesh-group member does not exist\n");
8967 vty_out(vty
, "%% mesh-group member del failed\n");
8970 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
8972 DEFUN (no_ip_msdp_mesh_group_member
,
8973 no_ip_msdp_mesh_group_member_cmd
,
8974 "no ip msdp mesh-group WORD member A.B.C.D",
8978 "Delete MSDP mesh-group member\n"
8980 "mesh group member\n"
8981 "peer ip address\n")
8983 PIM_DECLVAR_CONTEXT(vrf
, pim
);
8984 return ip_no_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[4]->arg
,
8988 static int ip_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
8989 struct vty
*vty
, const char *mg
,
8992 enum pim_msdp_err result
;
8993 struct in_addr src_ip
;
8995 result
= inet_pton(AF_INET
, src
, &src_ip
);
8997 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", src
,
8998 errno
, safe_strerror(errno
));
8999 return CMD_WARNING_CONFIG_FAILED
;
9002 result
= pim_msdp_mg_src_add(pim
, mg
, src_ip
);
9004 case PIM_MSDP_ERR_NONE
:
9006 case PIM_MSDP_ERR_OOM
:
9007 vty_out(vty
, "%% Out of memory\n");
9009 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
9010 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
9013 vty_out(vty
, "%% source add failed\n");
9016 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9020 DEFUN (ip_msdp_mesh_group_source
,
9021 ip_msdp_mesh_group_source_cmd
,
9022 "ip msdp mesh-group WORD source A.B.C.D",
9025 "Configure MSDP mesh-group\n"
9027 "mesh group local address\n"
9028 "source ip address for the TCP connection\n")
9030 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9031 return ip_msdp_mesh_group_source_cmd_worker(pim
, vty
, argv
[3]->arg
,
9035 static int ip_no_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
9039 enum pim_msdp_err result
;
9041 result
= pim_msdp_mg_src_del(pim
, mg
);
9043 case PIM_MSDP_ERR_NONE
:
9045 case PIM_MSDP_ERR_NO_MG
:
9046 vty_out(vty
, "%% mesh-group does not exist\n");
9049 vty_out(vty
, "%% mesh-group source del failed\n");
9052 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9055 static int ip_no_msdp_mesh_group_cmd_worker(struct pim_instance
*pim
,
9056 struct vty
*vty
, const char *mg
)
9058 enum pim_msdp_err result
;
9060 result
= pim_msdp_mg_del(pim
, mg
);
9062 case PIM_MSDP_ERR_NONE
:
9064 case PIM_MSDP_ERR_NO_MG
:
9065 vty_out(vty
, "%% mesh-group does not exist\n");
9068 vty_out(vty
, "%% mesh-group source del failed\n");
9071 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9074 DEFUN (no_ip_msdp_mesh_group_source
,
9075 no_ip_msdp_mesh_group_source_cmd
,
9076 "no ip msdp mesh-group WORD source [A.B.C.D]",
9080 "Delete MSDP mesh-group source\n"
9082 "mesh group source\n"
9083 "mesh group local address\n")
9085 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9087 return ip_no_msdp_mesh_group_cmd_worker(pim
, vty
, argv
[6]->arg
);
9089 return ip_no_msdp_mesh_group_source_cmd_worker(pim
, vty
,
9093 static void print_empty_json_obj(struct vty
*vty
)
9096 json
= json_object_new_object();
9097 vty_out(vty
, "%s\n",
9098 json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
));
9099 json_object_free(json
);
9102 static void ip_msdp_show_mesh_group(struct pim_instance
*pim
, struct vty
*vty
,
9105 struct listnode
*mbrnode
;
9106 struct pim_msdp_mg_mbr
*mbr
;
9107 struct pim_msdp_mg
*mg
= pim
->msdp
.mg
;
9108 char mbr_str
[INET_ADDRSTRLEN
];
9109 char src_str
[INET_ADDRSTRLEN
];
9110 char state_str
[PIM_MSDP_STATE_STRLEN
];
9111 enum pim_msdp_peer_state state
;
9112 json_object
*json
= NULL
;
9113 json_object
*json_mg_row
= NULL
;
9114 json_object
*json_members
= NULL
;
9115 json_object
*json_row
= NULL
;
9119 print_empty_json_obj(vty
);
9123 pim_inet4_dump("<source?>", mg
->src_ip
, src_str
, sizeof(src_str
));
9125 json
= json_object_new_object();
9126 /* currently there is only one mesh group but we should still
9128 * it a dict with mg-name as key */
9129 json_mg_row
= json_object_new_object();
9130 json_object_string_add(json_mg_row
, "name",
9131 mg
->mesh_group_name
);
9132 json_object_string_add(json_mg_row
, "source", src_str
);
9134 vty_out(vty
, "Mesh group : %s\n", mg
->mesh_group_name
);
9135 vty_out(vty
, " Source : %s\n", src_str
);
9136 vty_out(vty
, " Member State\n");
9139 for (ALL_LIST_ELEMENTS_RO(mg
->mbr_list
, mbrnode
, mbr
)) {
9140 pim_inet4_dump("<mbr?>", mbr
->mbr_ip
, mbr_str
, sizeof(mbr_str
));
9142 state
= mbr
->mp
->state
;
9144 state
= PIM_MSDP_DISABLED
;
9146 pim_msdp_state_dump(state
, state_str
, sizeof(state_str
));
9148 json_row
= json_object_new_object();
9149 json_object_string_add(json_row
, "member", mbr_str
);
9150 json_object_string_add(json_row
, "state", state_str
);
9151 if (!json_members
) {
9152 json_members
= json_object_new_object();
9153 json_object_object_add(json_mg_row
, "members",
9156 json_object_object_add(json_members
, mbr_str
, json_row
);
9158 vty_out(vty
, " %-15s %11s\n", mbr_str
, state_str
);
9163 json_object_object_add(json
, mg
->mesh_group_name
, json_mg_row
);
9164 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9165 json
, JSON_C_TO_STRING_PRETTY
));
9166 json_object_free(json
);
9170 DEFUN (show_ip_msdp_mesh_group
,
9171 show_ip_msdp_mesh_group_cmd
,
9172 "show ip msdp [vrf NAME] mesh-group [json]",
9177 "MSDP mesh-group information\n"
9180 bool uj
= use_json(argc
, argv
);
9182 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
9187 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
9192 DEFUN (show_ip_msdp_mesh_group_vrf_all
,
9193 show_ip_msdp_mesh_group_vrf_all_cmd
,
9194 "show ip msdp vrf all mesh-group [json]",
9199 "MSDP mesh-group information\n"
9202 bool uj
= use_json(argc
, argv
);
9208 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
9212 vty_out(vty
, " \"%s\": ", vrf
->name
);
9215 vty_out(vty
, "VRF: %s\n", vrf
->name
);
9216 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
9219 vty_out(vty
, "}\n");
9224 static void ip_msdp_show_peers(struct pim_instance
*pim
, struct vty
*vty
,
9227 struct listnode
*mpnode
;
9228 struct pim_msdp_peer
*mp
;
9229 char peer_str
[INET_ADDRSTRLEN
];
9230 char local_str
[INET_ADDRSTRLEN
];
9231 char state_str
[PIM_MSDP_STATE_STRLEN
];
9232 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
9234 json_object
*json
= NULL
;
9235 json_object
*json_row
= NULL
;
9239 json
= json_object_new_object();
9242 "Peer Local State Uptime SaCnt\n");
9245 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
9246 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
9247 now
= pim_time_monotonic_sec();
9248 pim_time_uptime(timebuf
, sizeof(timebuf
),
9251 strlcpy(timebuf
, "-", sizeof(timebuf
));
9253 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
9254 pim_inet4_dump("<local?>", mp
->local
, local_str
,
9256 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
9258 json_row
= json_object_new_object();
9259 json_object_string_add(json_row
, "peer", peer_str
);
9260 json_object_string_add(json_row
, "local", local_str
);
9261 json_object_string_add(json_row
, "state", state_str
);
9262 json_object_string_add(json_row
, "upTime", timebuf
);
9263 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
9264 json_object_object_add(json
, peer_str
, json_row
);
9266 vty_out(vty
, "%-15s %15s %11s %8s %6d\n", peer_str
,
9267 local_str
, state_str
, timebuf
, mp
->sa_cnt
);
9272 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9273 json
, JSON_C_TO_STRING_PRETTY
));
9274 json_object_free(json
);
9278 static void ip_msdp_show_peers_detail(struct pim_instance
*pim
, struct vty
*vty
,
9279 const char *peer
, bool uj
)
9281 struct listnode
*mpnode
;
9282 struct pim_msdp_peer
*mp
;
9283 char peer_str
[INET_ADDRSTRLEN
];
9284 char local_str
[INET_ADDRSTRLEN
];
9285 char state_str
[PIM_MSDP_STATE_STRLEN
];
9286 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
9287 char katimer
[PIM_MSDP_TIMER_STRLEN
];
9288 char crtimer
[PIM_MSDP_TIMER_STRLEN
];
9289 char holdtimer
[PIM_MSDP_TIMER_STRLEN
];
9291 json_object
*json
= NULL
;
9292 json_object
*json_row
= NULL
;
9295 json
= json_object_new_object();
9298 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
9299 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
9300 if (strcmp(peer
, "detail") && strcmp(peer
, peer_str
))
9303 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
9304 now
= pim_time_monotonic_sec();
9305 pim_time_uptime(timebuf
, sizeof(timebuf
),
9308 strlcpy(timebuf
, "-", sizeof(timebuf
));
9310 pim_inet4_dump("<local?>", mp
->local
, local_str
,
9312 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
9313 pim_time_timer_to_hhmmss(katimer
, sizeof(katimer
),
9315 pim_time_timer_to_hhmmss(crtimer
, sizeof(crtimer
),
9317 pim_time_timer_to_hhmmss(holdtimer
, sizeof(holdtimer
),
9321 json_row
= json_object_new_object();
9322 json_object_string_add(json_row
, "peer", peer_str
);
9323 json_object_string_add(json_row
, "local", local_str
);
9324 json_object_string_add(json_row
, "meshGroupName",
9325 mp
->mesh_group_name
);
9326 json_object_string_add(json_row
, "state", state_str
);
9327 json_object_string_add(json_row
, "upTime", timebuf
);
9328 json_object_string_add(json_row
, "keepAliveTimer",
9330 json_object_string_add(json_row
, "connRetryTimer",
9332 json_object_string_add(json_row
, "holdTimer",
9334 json_object_string_add(json_row
, "lastReset",
9336 json_object_int_add(json_row
, "connAttempts",
9338 json_object_int_add(json_row
, "establishedChanges",
9340 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
9341 json_object_int_add(json_row
, "kaSent", mp
->ka_tx_cnt
);
9342 json_object_int_add(json_row
, "kaRcvd", mp
->ka_rx_cnt
);
9343 json_object_int_add(json_row
, "saSent", mp
->sa_tx_cnt
);
9344 json_object_int_add(json_row
, "saRcvd", mp
->sa_rx_cnt
);
9345 json_object_object_add(json
, peer_str
, json_row
);
9347 vty_out(vty
, "Peer : %s\n", peer_str
);
9348 vty_out(vty
, " Local : %s\n", local_str
);
9349 vty_out(vty
, " Mesh Group : %s\n",
9350 mp
->mesh_group_name
);
9351 vty_out(vty
, " State : %s\n", state_str
);
9352 vty_out(vty
, " Uptime : %s\n", timebuf
);
9354 vty_out(vty
, " Keepalive Timer : %s\n", katimer
);
9355 vty_out(vty
, " Conn Retry Timer : %s\n", crtimer
);
9356 vty_out(vty
, " Hold Timer : %s\n", holdtimer
);
9357 vty_out(vty
, " Last Reset : %s\n",
9359 vty_out(vty
, " Conn Attempts : %d\n",
9361 vty_out(vty
, " Established Changes : %d\n",
9363 vty_out(vty
, " SA Count : %d\n",
9365 vty_out(vty
, " Statistics :\n");
9368 vty_out(vty
, " Keepalives : %10d %10d\n",
9369 mp
->ka_tx_cnt
, mp
->ka_rx_cnt
);
9370 vty_out(vty
, " SAs : %10d %10d\n",
9371 mp
->sa_tx_cnt
, mp
->sa_rx_cnt
);
9377 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9378 json
, JSON_C_TO_STRING_PRETTY
));
9379 json_object_free(json
);
9383 DEFUN (show_ip_msdp_peer_detail
,
9384 show_ip_msdp_peer_detail_cmd
,
9385 "show ip msdp [vrf NAME] peer [detail|A.B.C.D] [json]",
9390 "MSDP peer information\n"
9395 bool uj
= use_json(argc
, argv
);
9397 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
9404 if (argv_find(argv
, argc
, "detail", &idx
))
9405 arg
= argv
[idx
]->text
;
9406 else if (argv_find(argv
, argc
, "A.B.C.D", &idx
))
9407 arg
= argv
[idx
]->arg
;
9410 ip_msdp_show_peers_detail(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
9412 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
9417 DEFUN (show_ip_msdp_peer_detail_vrf_all
,
9418 show_ip_msdp_peer_detail_vrf_all_cmd
,
9419 "show ip msdp vrf all peer [detail|A.B.C.D] [json]",
9424 "MSDP peer information\n"
9430 bool uj
= use_json(argc
, argv
);
9436 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
9440 vty_out(vty
, " \"%s\": ", vrf
->name
);
9443 vty_out(vty
, "VRF: %s\n", vrf
->name
);
9444 if (argv_find(argv
, argc
, "detail", &idx
)
9445 || argv_find(argv
, argc
, "A.B.C.D", &idx
))
9446 ip_msdp_show_peers_detail(vrf
->info
, vty
,
9447 argv
[idx
]->arg
, uj
);
9449 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
9452 vty_out(vty
, "}\n");
9457 static void ip_msdp_show_sa(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
9459 struct listnode
*sanode
;
9460 struct pim_msdp_sa
*sa
;
9461 char src_str
[INET_ADDRSTRLEN
];
9462 char grp_str
[INET_ADDRSTRLEN
];
9463 char rp_str
[INET_ADDRSTRLEN
];
9464 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
9468 json_object
*json
= NULL
;
9469 json_object
*json_group
= NULL
;
9470 json_object
*json_row
= NULL
;
9473 json
= json_object_new_object();
9476 "Source Group RP Local SPT Uptime\n");
9479 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
9480 now
= pim_time_monotonic_sec();
9481 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
9482 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
9483 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
9484 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
9485 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
9487 strlcpy(spt_str
, "yes", sizeof(spt_str
));
9489 strlcpy(spt_str
, "no", sizeof(spt_str
));
9492 strlcpy(rp_str
, "-", sizeof(rp_str
));
9493 strlcpy(spt_str
, "-", sizeof(spt_str
));
9495 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
9496 strlcpy(local_str
, "yes", sizeof(local_str
));
9498 strlcpy(local_str
, "no", sizeof(local_str
));
9501 json_object_object_get_ex(json
, grp_str
, &json_group
);
9504 json_group
= json_object_new_object();
9505 json_object_object_add(json
, grp_str
,
9509 json_row
= json_object_new_object();
9510 json_object_string_add(json_row
, "source", src_str
);
9511 json_object_string_add(json_row
, "group", grp_str
);
9512 json_object_string_add(json_row
, "rp", rp_str
);
9513 json_object_string_add(json_row
, "local", local_str
);
9514 json_object_string_add(json_row
, "sptSetup", spt_str
);
9515 json_object_string_add(json_row
, "upTime", timebuf
);
9516 json_object_object_add(json_group
, src_str
, json_row
);
9518 vty_out(vty
, "%-15s %15s %15s %5c %3c %8s\n",
9519 src_str
, grp_str
, rp_str
, local_str
[0],
9520 spt_str
[0], timebuf
);
9525 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9526 json
, JSON_C_TO_STRING_PRETTY
));
9527 json_object_free(json
);
9531 static void ip_msdp_show_sa_entry_detail(struct pim_msdp_sa
*sa
,
9532 const char *src_str
,
9533 const char *grp_str
, struct vty
*vty
,
9534 bool uj
, json_object
*json
)
9536 char rp_str
[INET_ADDRSTRLEN
];
9537 char peer_str
[INET_ADDRSTRLEN
];
9538 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
9541 char statetimer
[PIM_MSDP_TIMER_STRLEN
];
9543 json_object
*json_group
= NULL
;
9544 json_object
*json_row
= NULL
;
9546 now
= pim_time_monotonic_sec();
9547 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
9548 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
9549 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
9550 pim_inet4_dump("<peer?>", sa
->peer
, peer_str
, sizeof(peer_str
));
9552 strlcpy(spt_str
, "yes", sizeof(spt_str
));
9554 strlcpy(spt_str
, "no", sizeof(spt_str
));
9557 strlcpy(rp_str
, "-", sizeof(rp_str
));
9558 strlcpy(peer_str
, "-", sizeof(peer_str
));
9559 strlcpy(spt_str
, "-", sizeof(spt_str
));
9561 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
9562 strlcpy(local_str
, "yes", sizeof(local_str
));
9564 strlcpy(local_str
, "no", sizeof(local_str
));
9566 pim_time_timer_to_hhmmss(statetimer
, sizeof(statetimer
),
9567 sa
->sa_state_timer
);
9569 json_object_object_get_ex(json
, grp_str
, &json_group
);
9572 json_group
= json_object_new_object();
9573 json_object_object_add(json
, grp_str
, json_group
);
9576 json_row
= json_object_new_object();
9577 json_object_string_add(json_row
, "source", src_str
);
9578 json_object_string_add(json_row
, "group", grp_str
);
9579 json_object_string_add(json_row
, "rp", rp_str
);
9580 json_object_string_add(json_row
, "local", local_str
);
9581 json_object_string_add(json_row
, "sptSetup", spt_str
);
9582 json_object_string_add(json_row
, "upTime", timebuf
);
9583 json_object_string_add(json_row
, "stateTimer", statetimer
);
9584 json_object_object_add(json_group
, src_str
, json_row
);
9586 vty_out(vty
, "SA : %s\n", sa
->sg_str
);
9587 vty_out(vty
, " RP : %s\n", rp_str
);
9588 vty_out(vty
, " Peer : %s\n", peer_str
);
9589 vty_out(vty
, " Local : %s\n", local_str
);
9590 vty_out(vty
, " SPT Setup : %s\n", spt_str
);
9591 vty_out(vty
, " Uptime : %s\n", timebuf
);
9592 vty_out(vty
, " State Timer : %s\n", statetimer
);
9597 static void ip_msdp_show_sa_detail(struct pim_instance
*pim
, struct vty
*vty
,
9600 struct listnode
*sanode
;
9601 struct pim_msdp_sa
*sa
;
9602 char src_str
[INET_ADDRSTRLEN
];
9603 char grp_str
[INET_ADDRSTRLEN
];
9604 json_object
*json
= NULL
;
9607 json
= json_object_new_object();
9610 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
9611 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
9612 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
9613 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
, uj
,
9618 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9619 json
, JSON_C_TO_STRING_PRETTY
));
9620 json_object_free(json
);
9624 DEFUN (show_ip_msdp_sa_detail
,
9625 show_ip_msdp_sa_detail_cmd
,
9626 "show ip msdp [vrf NAME] sa detail [json]",
9631 "MSDP active-source information\n"
9635 bool uj
= use_json(argc
, argv
);
9637 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
9642 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
9647 DEFUN (show_ip_msdp_sa_detail_vrf_all
,
9648 show_ip_msdp_sa_detail_vrf_all_cmd
,
9649 "show ip msdp vrf all sa detail [json]",
9654 "MSDP active-source information\n"
9658 bool uj
= use_json(argc
, argv
);
9664 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
9668 vty_out(vty
, " \"%s\": ", vrf
->name
);
9671 vty_out(vty
, "VRF: %s\n", vrf
->name
);
9672 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
9675 vty_out(vty
, "}\n");
9680 static void ip_msdp_show_sa_addr(struct pim_instance
*pim
, struct vty
*vty
,
9681 const char *addr
, bool uj
)
9683 struct listnode
*sanode
;
9684 struct pim_msdp_sa
*sa
;
9685 char src_str
[INET_ADDRSTRLEN
];
9686 char grp_str
[INET_ADDRSTRLEN
];
9687 json_object
*json
= NULL
;
9690 json
= json_object_new_object();
9693 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
9694 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
9695 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
9696 if (!strcmp(addr
, src_str
) || !strcmp(addr
, grp_str
)) {
9697 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
9703 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9704 json
, JSON_C_TO_STRING_PRETTY
));
9705 json_object_free(json
);
9709 static void ip_msdp_show_sa_sg(struct pim_instance
*pim
, struct vty
*vty
,
9710 const char *src
, const char *grp
, bool uj
)
9712 struct listnode
*sanode
;
9713 struct pim_msdp_sa
*sa
;
9714 char src_str
[INET_ADDRSTRLEN
];
9715 char grp_str
[INET_ADDRSTRLEN
];
9716 json_object
*json
= NULL
;
9719 json
= json_object_new_object();
9722 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
9723 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
9724 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
9725 if (!strcmp(src
, src_str
) && !strcmp(grp
, grp_str
)) {
9726 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
9732 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9733 json
, JSON_C_TO_STRING_PRETTY
));
9734 json_object_free(json
);
9738 DEFUN (show_ip_msdp_sa_sg
,
9739 show_ip_msdp_sa_sg_cmd
,
9740 "show ip msdp [vrf NAME] sa [A.B.C.D [A.B.C.D]] [json]",
9745 "MSDP active-source information\n"
9746 "source or group ip\n"
9750 bool uj
= use_json(argc
, argv
);
9754 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
9759 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
9761 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
9765 if (src_ip
&& grp_ip
)
9766 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
9768 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
9770 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
9775 DEFUN (show_ip_msdp_sa_sg_vrf_all
,
9776 show_ip_msdp_sa_sg_vrf_all_cmd
,
9777 "show ip msdp vrf all sa [A.B.C.D [A.B.C.D]] [json]",
9782 "MSDP active-source information\n"
9783 "source or group ip\n"
9787 bool uj
= use_json(argc
, argv
);
9792 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
9794 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
9800 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
9804 vty_out(vty
, " \"%s\": ", vrf
->name
);
9807 vty_out(vty
, "VRF: %s\n", vrf
->name
);
9809 if (src_ip
&& grp_ip
)
9810 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
9812 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
9814 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
9817 vty_out(vty
, "}\n");
9822 struct pim_sg_cache_walk_data
{
9825 json_object
*json_group
;
9826 struct in_addr addr
;
9830 static void pim_show_vxlan_sg_entry(struct pim_vxlan_sg
*vxlan_sg
,
9831 struct pim_sg_cache_walk_data
*cwd
)
9833 struct vty
*vty
= cwd
->vty
;
9834 json_object
*json
= cwd
->json
;
9835 char src_str
[INET_ADDRSTRLEN
];
9836 char grp_str
[INET_ADDRSTRLEN
];
9837 json_object
*json_row
;
9838 bool installed
= (vxlan_sg
->up
)?TRUE
:FALSE
;
9839 const char *iif_name
= vxlan_sg
->iif
?vxlan_sg
->iif
->name
:"-";
9840 const char *oif_name
;
9842 if (pim_vxlan_is_orig_mroute(vxlan_sg
))
9843 oif_name
= vxlan_sg
->orig_oif
?vxlan_sg
->orig_oif
->name
:"";
9845 oif_name
= vxlan_sg
->term_oif
?vxlan_sg
->term_oif
->name
:"";
9847 if (cwd
->addr_match
&& (vxlan_sg
->sg
.src
.s_addr
!= cwd
->addr
.s_addr
) &&
9848 (vxlan_sg
->sg
.grp
.s_addr
!= cwd
->addr
.s_addr
)) {
9851 pim_inet4_dump("<src?>", vxlan_sg
->sg
.src
, src_str
, sizeof(src_str
));
9852 pim_inet4_dump("<grp?>", vxlan_sg
->sg
.grp
, grp_str
, sizeof(grp_str
));
9854 json_object_object_get_ex(json
, grp_str
, &cwd
->json_group
);
9856 if (!cwd
->json_group
) {
9857 cwd
->json_group
= json_object_new_object();
9858 json_object_object_add(json
, grp_str
,
9862 json_row
= json_object_new_object();
9863 json_object_string_add(json_row
, "source", src_str
);
9864 json_object_string_add(json_row
, "group", grp_str
);
9865 json_object_string_add(json_row
, "input", iif_name
);
9866 json_object_string_add(json_row
, "output", oif_name
);
9868 json_object_boolean_true_add(json_row
, "installed");
9870 json_object_boolean_false_add(json_row
, "installed");
9871 json_object_object_add(cwd
->json_group
, src_str
, json_row
);
9873 vty_out(vty
, "%-15s %-15s %-15s %-15s %-5s\n",
9874 src_str
, grp_str
, iif_name
, oif_name
,
9879 static void pim_show_vxlan_sg_hash_entry(struct hash_backet
*backet
, void *arg
)
9881 pim_show_vxlan_sg_entry((struct pim_vxlan_sg
*)backet
->data
,
9882 (struct pim_sg_cache_walk_data
*)arg
);
9885 static void pim_show_vxlan_sg(struct pim_instance
*pim
,
9886 struct vty
*vty
, bool uj
)
9888 json_object
*json
= NULL
;
9889 struct pim_sg_cache_walk_data cwd
;
9892 json
= json_object_new_object();
9894 vty_out(vty
, "Codes: I -> installed\n");
9896 "Source Group Input Output Flags\n");
9899 memset(&cwd
, 0, sizeof(cwd
));
9902 hash_iterate(pim
->vxlan
.sg_hash
, pim_show_vxlan_sg_hash_entry
, &cwd
);
9905 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9906 json
, JSON_C_TO_STRING_PRETTY
));
9907 json_object_free(json
);
9911 static void pim_show_vxlan_sg_match_addr(struct pim_instance
*pim
,
9912 struct vty
*vty
, char *addr_str
, bool uj
)
9914 json_object
*json
= NULL
;
9915 struct pim_sg_cache_walk_data cwd
;
9918 memset(&cwd
, 0, sizeof(cwd
));
9919 result
= inet_pton(AF_INET
, addr_str
, &cwd
.addr
);
9921 vty_out(vty
, "Bad address %s: errno=%d: %s\n", addr_str
,
9922 errno
, safe_strerror(errno
));
9927 json
= json_object_new_object();
9929 vty_out(vty
, "Codes: I -> installed\n");
9931 "Source Group Input Output Flags\n");
9936 cwd
.addr_match
= TRUE
;
9937 hash_iterate(pim
->vxlan
.sg_hash
, pim_show_vxlan_sg_hash_entry
, &cwd
);
9940 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9941 json
, JSON_C_TO_STRING_PRETTY
));
9942 json_object_free(json
);
9946 static void pim_show_vxlan_sg_one(struct pim_instance
*pim
,
9947 struct vty
*vty
, char *src_str
, char *grp_str
, bool uj
)
9949 json_object
*json
= NULL
;
9950 struct prefix_sg sg
;
9952 struct pim_vxlan_sg
*vxlan_sg
;
9953 const char *iif_name
;
9955 const char *oif_name
;
9957 result
= inet_pton(AF_INET
, src_str
, &sg
.src
);
9959 vty_out(vty
, "Bad src address %s: errno=%d: %s\n", src_str
,
9960 errno
, safe_strerror(errno
));
9963 result
= inet_pton(AF_INET
, grp_str
, &sg
.grp
);
9965 vty_out(vty
, "Bad grp address %s: errno=%d: %s\n", grp_str
,
9966 errno
, safe_strerror(errno
));
9970 sg
.family
= AF_INET
;
9971 sg
.prefixlen
= IPV4_MAX_BITLEN
;
9973 json
= json_object_new_object();
9975 vxlan_sg
= pim_vxlan_sg_find(pim
, &sg
);
9977 installed
= (vxlan_sg
->up
)?TRUE
:FALSE
;
9978 iif_name
= vxlan_sg
->iif
?vxlan_sg
->iif
->name
:"-";
9980 if (pim_vxlan_is_orig_mroute(vxlan_sg
))
9982 vxlan_sg
->orig_oif
?vxlan_sg
->orig_oif
->name
:"";
9985 vxlan_sg
->term_oif
?vxlan_sg
->term_oif
->name
:"";
9988 json_object_string_add(json
, "source", src_str
);
9989 json_object_string_add(json
, "group", grp_str
);
9990 json_object_string_add(json
, "input", iif_name
);
9991 json_object_string_add(json
, "output", oif_name
);
9993 json_object_boolean_true_add(json
, "installed");
9995 json_object_boolean_false_add(json
,
9998 vty_out(vty
, "SG : %s\n", vxlan_sg
->sg_str
);
9999 vty_out(vty
, " Input : %s\n", iif_name
);
10000 vty_out(vty
, " Output : %s\n", oif_name
);
10001 vty_out(vty
, " installed : %s\n",
10002 installed
?"yes":"no");
10007 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10008 json
, JSON_C_TO_STRING_PRETTY
));
10009 json_object_free(json
);
10013 DEFUN (show_ip_pim_vxlan_sg
,
10014 show_ip_pim_vxlan_sg_cmd
,
10015 "show ip pim [vrf NAME] vxlan-groups [A.B.C.D [A.B.C.D]] [json]",
10020 "VxLAN BUM groups\n"
10021 "source or group ip\n"
10025 bool uj
= use_json(argc
, argv
);
10029 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10032 return CMD_WARNING
;
10034 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ?
10035 argv
[idx
++]->arg
:NULL
;
10036 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
) ?
10037 argv
[idx
]->arg
:NULL
;
10039 if (src_ip
&& grp_ip
)
10040 pim_show_vxlan_sg_one(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
10042 pim_show_vxlan_sg_match_addr(vrf
->info
, vty
, src_ip
, uj
);
10044 pim_show_vxlan_sg(vrf
->info
, vty
, uj
);
10046 return CMD_SUCCESS
;
10049 static void pim_show_vxlan_sg_work(struct pim_instance
*pim
,
10050 struct vty
*vty
, bool uj
)
10052 json_object
*json
= NULL
;
10053 struct pim_sg_cache_walk_data cwd
;
10054 struct listnode
*node
;
10055 struct pim_vxlan_sg
*vxlan_sg
;
10058 json
= json_object_new_object();
10060 vty_out(vty
, "Codes: I -> installed\n");
10062 "Source Group Input Flags\n");
10065 memset(&cwd
, 0, sizeof(cwd
));
10068 for (ALL_LIST_ELEMENTS_RO(pim_vxlan_p
->work_list
, node
, vxlan_sg
))
10069 pim_show_vxlan_sg_entry(vxlan_sg
, &cwd
);
10072 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10073 json
, JSON_C_TO_STRING_PRETTY
));
10074 json_object_free(json
);
10078 DEFUN_HIDDEN (show_ip_pim_vxlan_sg_work
,
10079 show_ip_pim_vxlan_sg_work_cmd
,
10080 "show ip pim [vrf NAME] vxlan-work [json]",
10085 "VxLAN work list\n"
10088 bool uj
= use_json(argc
, argv
);
10092 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10095 return CMD_WARNING
;
10097 pim_show_vxlan_sg_work(vrf
->info
, vty
, uj
);
10099 return CMD_SUCCESS
;
10102 DEFUN_HIDDEN (no_ip_pim_mlag
,
10103 no_ip_pim_mlag_cmd
,
10110 struct in_addr addr
;
10113 pim_vxlan_mlag_update(TRUE
/*mlag_enable*/,
10114 FALSE
/*peer_state*/, PIM_VXLAN_MLAG_ROLE_SECONDARY
,
10115 NULL
/*peerlink*/, &addr
);
10117 return CMD_SUCCESS
;
10120 DEFUN_HIDDEN (ip_pim_mlag
,
10122 "ip pim mlag INTERFACE role [primary|secondary] state [up|down] addr A.B.C.D",
10126 "peerlink sub interface\n"
10128 "MLAG role primary\n"
10129 "MLAG role secondary\n"
10130 "peer session state\n"
10131 "peer session state up\n"
10132 "peer session state down\n"
10134 "unique ip address\n")
10136 struct interface
*ifp
;
10137 const char *peerlink
;
10142 struct in_addr reg_addr
;
10145 peerlink
= argv
[idx
]->arg
;
10146 ifp
= if_lookup_by_name(peerlink
, VRF_DEFAULT
);
10148 vty_out(vty
, "No such interface name %s\n", peerlink
);
10149 return CMD_WARNING
;
10153 if (!strcmp(argv
[idx
]->arg
, "primary")) {
10154 role
= PIM_VXLAN_MLAG_ROLE_PRIMARY
;
10155 } else if (!strcmp(argv
[idx
]->arg
, "secondary")) {
10156 role
= PIM_VXLAN_MLAG_ROLE_SECONDARY
;
10158 vty_out(vty
, "unknown MLAG role %s\n", argv
[idx
]->arg
);
10159 return CMD_WARNING
;
10163 if (!strcmp(argv
[idx
]->arg
, "up")) {
10165 } else if (strcmp(argv
[idx
]->arg
, "down")) {
10166 peer_state
= FALSE
;
10168 vty_out(vty
, "unknown MLAG state %s\n", argv
[idx
]->arg
);
10169 return CMD_WARNING
;
10173 result
= inet_pton(AF_INET
, argv
[idx
]->arg
, ®_addr
);
10175 vty_out(vty
, "%% Bad reg address %s: errno=%d: %s\n",
10177 errno
, safe_strerror(errno
));
10178 return CMD_WARNING_CONFIG_FAILED
;
10180 pim_vxlan_mlag_update(TRUE
, peer_state
, role
, ifp
, ®_addr
);
10182 return CMD_SUCCESS
;
10185 void pim_cmd_init(void)
10187 install_node(&interface_node
,
10188 pim_interface_config_write
); /* INTERFACE_NODE */
10191 install_node(&debug_node
, pim_debug_config_write
);
10193 install_element(ENABLE_NODE
, &pim_test_sg_keepalive_cmd
);
10195 install_element(CONFIG_NODE
, &ip_pim_rp_cmd
);
10196 install_element(VRF_NODE
, &ip_pim_rp_cmd
);
10197 install_element(CONFIG_NODE
, &no_ip_pim_rp_cmd
);
10198 install_element(VRF_NODE
, &no_ip_pim_rp_cmd
);
10199 install_element(CONFIG_NODE
, &ip_pim_rp_prefix_list_cmd
);
10200 install_element(VRF_NODE
, &ip_pim_rp_prefix_list_cmd
);
10201 install_element(CONFIG_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
10202 install_element(VRF_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
10203 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
10204 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
10205 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
10206 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
10207 install_element(CONFIG_NODE
, &ip_pim_ssm_prefix_list_cmd
);
10208 install_element(VRF_NODE
, &ip_pim_ssm_prefix_list_cmd
);
10209 install_element(CONFIG_NODE
, &ip_pim_register_suppress_cmd
);
10210 install_element(VRF_NODE
, &ip_pim_register_suppress_cmd
);
10211 install_element(CONFIG_NODE
, &no_ip_pim_register_suppress_cmd
);
10212 install_element(VRF_NODE
, &no_ip_pim_register_suppress_cmd
);
10213 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
10214 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
10215 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
10216 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
10217 install_element(CONFIG_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
10218 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
10219 install_element(CONFIG_NODE
,
10220 &no_ip_pim_spt_switchover_infinity_plist_cmd
);
10221 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_plist_cmd
);
10222 install_element(CONFIG_NODE
, &ip_pim_joinprune_time_cmd
);
10223 install_element(VRF_NODE
, &ip_pim_joinprune_time_cmd
);
10224 install_element(CONFIG_NODE
, &no_ip_pim_joinprune_time_cmd
);
10225 install_element(VRF_NODE
, &no_ip_pim_joinprune_time_cmd
);
10226 install_element(CONFIG_NODE
, &ip_pim_keep_alive_cmd
);
10227 install_element(VRF_NODE
, &ip_pim_keep_alive_cmd
);
10228 install_element(CONFIG_NODE
, &ip_pim_rp_keep_alive_cmd
);
10229 install_element(VRF_NODE
, &ip_pim_rp_keep_alive_cmd
);
10230 install_element(CONFIG_NODE
, &no_ip_pim_keep_alive_cmd
);
10231 install_element(VRF_NODE
, &no_ip_pim_keep_alive_cmd
);
10232 install_element(CONFIG_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
10233 install_element(VRF_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
10234 install_element(CONFIG_NODE
, &ip_pim_packets_cmd
);
10235 install_element(VRF_NODE
, &ip_pim_packets_cmd
);
10236 install_element(CONFIG_NODE
, &no_ip_pim_packets_cmd
);
10237 install_element(VRF_NODE
, &no_ip_pim_packets_cmd
);
10238 install_element(CONFIG_NODE
, &ip_pim_v6_secondary_cmd
);
10239 install_element(VRF_NODE
, &ip_pim_v6_secondary_cmd
);
10240 install_element(CONFIG_NODE
, &no_ip_pim_v6_secondary_cmd
);
10241 install_element(VRF_NODE
, &no_ip_pim_v6_secondary_cmd
);
10242 install_element(CONFIG_NODE
, &ip_ssmpingd_cmd
);
10243 install_element(VRF_NODE
, &ip_ssmpingd_cmd
);
10244 install_element(CONFIG_NODE
, &no_ip_ssmpingd_cmd
);
10245 install_element(VRF_NODE
, &no_ip_ssmpingd_cmd
);
10246 install_element(CONFIG_NODE
, &ip_msdp_peer_cmd
);
10247 install_element(VRF_NODE
, &ip_msdp_peer_cmd
);
10248 install_element(CONFIG_NODE
, &no_ip_msdp_peer_cmd
);
10249 install_element(VRF_NODE
, &no_ip_msdp_peer_cmd
);
10250 install_element(CONFIG_NODE
, &ip_pim_ecmp_cmd
);
10251 install_element(VRF_NODE
, &ip_pim_ecmp_cmd
);
10252 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_cmd
);
10253 install_element(VRF_NODE
, &no_ip_pim_ecmp_cmd
);
10254 install_element(CONFIG_NODE
, &ip_pim_ecmp_rebalance_cmd
);
10255 install_element(VRF_NODE
, &ip_pim_ecmp_rebalance_cmd
);
10256 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
10257 install_element(VRF_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
10258 install_element(CONFIG_NODE
, &ip_pim_mlag_cmd
);
10259 install_element(CONFIG_NODE
, &no_ip_pim_mlag_cmd
);
10261 install_element(INTERFACE_NODE
, &interface_ip_igmp_cmd
);
10262 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_cmd
);
10263 install_element(INTERFACE_NODE
, &interface_ip_igmp_join_cmd
);
10264 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_join_cmd
);
10265 install_element(INTERFACE_NODE
, &interface_ip_igmp_version_cmd
);
10266 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_version_cmd
);
10267 install_element(INTERFACE_NODE
, &interface_ip_igmp_query_interval_cmd
);
10268 install_element(INTERFACE_NODE
,
10269 &interface_no_ip_igmp_query_interval_cmd
);
10270 install_element(INTERFACE_NODE
,
10271 &interface_ip_igmp_query_max_response_time_cmd
);
10272 install_element(INTERFACE_NODE
,
10273 &interface_no_ip_igmp_query_max_response_time_cmd
);
10274 install_element(INTERFACE_NODE
,
10275 &interface_ip_igmp_query_max_response_time_dsec_cmd
);
10276 install_element(INTERFACE_NODE
,
10277 &interface_no_ip_igmp_query_max_response_time_dsec_cmd
);
10278 install_element(INTERFACE_NODE
,
10279 &interface_ip_igmp_last_member_query_count_cmd
);
10280 install_element(INTERFACE_NODE
,
10281 &interface_no_ip_igmp_last_member_query_count_cmd
);
10282 install_element(INTERFACE_NODE
,
10283 &interface_ip_igmp_last_member_query_interval_cmd
);
10284 install_element(INTERFACE_NODE
,
10285 &interface_no_ip_igmp_last_member_query_interval_cmd
);
10286 install_element(INTERFACE_NODE
, &interface_ip_pim_activeactive_cmd
);
10287 install_element(INTERFACE_NODE
, &interface_ip_pim_ssm_cmd
);
10288 install_element(INTERFACE_NODE
, &interface_no_ip_pim_ssm_cmd
);
10289 install_element(INTERFACE_NODE
, &interface_ip_pim_sm_cmd
);
10290 install_element(INTERFACE_NODE
, &interface_no_ip_pim_sm_cmd
);
10291 install_element(INTERFACE_NODE
, &interface_ip_pim_cmd
);
10292 install_element(INTERFACE_NODE
, &interface_no_ip_pim_cmd
);
10293 install_element(INTERFACE_NODE
, &interface_ip_pim_drprio_cmd
);
10294 install_element(INTERFACE_NODE
, &interface_no_ip_pim_drprio_cmd
);
10295 install_element(INTERFACE_NODE
, &interface_ip_pim_hello_cmd
);
10296 install_element(INTERFACE_NODE
, &interface_no_ip_pim_hello_cmd
);
10297 install_element(INTERFACE_NODE
, &interface_ip_pim_boundary_oil_cmd
);
10298 install_element(INTERFACE_NODE
, &interface_no_ip_pim_boundary_oil_cmd
);
10300 // Static mroutes NEB
10301 install_element(INTERFACE_NODE
, &interface_ip_mroute_cmd
);
10302 install_element(INTERFACE_NODE
, &interface_ip_mroute_source_cmd
);
10303 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_cmd
);
10304 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_source_cmd
);
10306 install_element(VIEW_NODE
, &show_ip_igmp_interface_cmd
);
10307 install_element(VIEW_NODE
, &show_ip_igmp_interface_vrf_all_cmd
);
10308 install_element(VIEW_NODE
, &show_ip_igmp_join_cmd
);
10309 install_element(VIEW_NODE
, &show_ip_igmp_join_vrf_all_cmd
);
10310 install_element(VIEW_NODE
, &show_ip_igmp_groups_cmd
);
10311 install_element(VIEW_NODE
, &show_ip_igmp_groups_vrf_all_cmd
);
10312 install_element(VIEW_NODE
, &show_ip_igmp_groups_retransmissions_cmd
);
10313 install_element(VIEW_NODE
, &show_ip_igmp_sources_cmd
);
10314 install_element(VIEW_NODE
, &show_ip_igmp_sources_retransmissions_cmd
);
10315 install_element(VIEW_NODE
, &show_ip_igmp_statistics_cmd
);
10316 install_element(VIEW_NODE
, &show_ip_pim_assert_cmd
);
10317 install_element(VIEW_NODE
, &show_ip_pim_assert_internal_cmd
);
10318 install_element(VIEW_NODE
, &show_ip_pim_assert_metric_cmd
);
10319 install_element(VIEW_NODE
, &show_ip_pim_assert_winner_metric_cmd
);
10320 install_element(VIEW_NODE
, &show_ip_pim_interface_traffic_cmd
);
10321 install_element(VIEW_NODE
, &show_ip_pim_interface_cmd
);
10322 install_element(VIEW_NODE
, &show_ip_pim_interface_vrf_all_cmd
);
10323 install_element(VIEW_NODE
, &show_ip_pim_join_cmd
);
10324 install_element(VIEW_NODE
, &show_ip_pim_join_vrf_all_cmd
);
10325 install_element(VIEW_NODE
, &show_ip_pim_local_membership_cmd
);
10326 install_element(VIEW_NODE
, &show_ip_pim_neighbor_cmd
);
10327 install_element(VIEW_NODE
, &show_ip_pim_neighbor_vrf_all_cmd
);
10328 install_element(VIEW_NODE
, &show_ip_pim_rpf_cmd
);
10329 install_element(VIEW_NODE
, &show_ip_pim_rpf_vrf_all_cmd
);
10330 install_element(VIEW_NODE
, &show_ip_pim_secondary_cmd
);
10331 install_element(VIEW_NODE
, &show_ip_pim_state_cmd
);
10332 install_element(VIEW_NODE
, &show_ip_pim_state_vrf_all_cmd
);
10333 install_element(VIEW_NODE
, &show_ip_pim_upstream_cmd
);
10334 install_element(VIEW_NODE
, &show_ip_pim_upstream_vrf_all_cmd
);
10335 install_element(VIEW_NODE
, &show_ip_pim_upstream_join_desired_cmd
);
10336 install_element(VIEW_NODE
, &show_ip_pim_upstream_rpf_cmd
);
10337 install_element(VIEW_NODE
, &show_ip_pim_rp_cmd
);
10338 install_element(VIEW_NODE
, &show_ip_pim_rp_vrf_all_cmd
);
10339 install_element(VIEW_NODE
, &show_ip_pim_bsr_cmd
);
10340 install_element(VIEW_NODE
, &show_ip_multicast_cmd
);
10341 install_element(VIEW_NODE
, &show_ip_multicast_vrf_all_cmd
);
10342 install_element(VIEW_NODE
, &show_ip_mroute_cmd
);
10343 install_element(VIEW_NODE
, &show_ip_mroute_vrf_all_cmd
);
10344 install_element(VIEW_NODE
, &show_ip_mroute_count_cmd
);
10345 install_element(VIEW_NODE
, &show_ip_mroute_count_vrf_all_cmd
);
10346 install_element(VIEW_NODE
, &show_ip_mroute_summary_cmd
);
10347 install_element(VIEW_NODE
, &show_ip_mroute_summary_vrf_all_cmd
);
10348 install_element(VIEW_NODE
, &show_ip_rib_cmd
);
10349 install_element(VIEW_NODE
, &show_ip_ssmpingd_cmd
);
10350 install_element(VIEW_NODE
, &show_debugging_pim_cmd
);
10351 install_element(VIEW_NODE
, &show_ip_pim_nexthop_cmd
);
10352 install_element(VIEW_NODE
, &show_ip_pim_nexthop_lookup_cmd
);
10353 install_element(VIEW_NODE
, &show_ip_pim_bsrp_cmd
);
10354 install_element(VIEW_NODE
, &show_ip_pim_bsm_db_cmd
);
10355 install_element(VIEW_NODE
, &show_ip_pim_statistics_cmd
);
10357 install_element(ENABLE_NODE
, &clear_ip_mroute_count_cmd
);
10358 install_element(ENABLE_NODE
, &clear_ip_interfaces_cmd
);
10359 install_element(ENABLE_NODE
, &clear_ip_igmp_interfaces_cmd
);
10360 install_element(ENABLE_NODE
, &clear_ip_mroute_cmd
);
10361 install_element(ENABLE_NODE
, &clear_ip_pim_interfaces_cmd
);
10362 install_element(ENABLE_NODE
, &clear_ip_pim_interface_traffic_cmd
);
10363 install_element(ENABLE_NODE
, &clear_ip_pim_oil_cmd
);
10364 install_element(ENABLE_NODE
, &clear_ip_pim_statistics_cmd
);
10366 install_element(ENABLE_NODE
, &debug_igmp_cmd
);
10367 install_element(ENABLE_NODE
, &no_debug_igmp_cmd
);
10368 install_element(ENABLE_NODE
, &debug_igmp_events_cmd
);
10369 install_element(ENABLE_NODE
, &no_debug_igmp_events_cmd
);
10370 install_element(ENABLE_NODE
, &debug_igmp_packets_cmd
);
10371 install_element(ENABLE_NODE
, &no_debug_igmp_packets_cmd
);
10372 install_element(ENABLE_NODE
, &debug_igmp_trace_cmd
);
10373 install_element(ENABLE_NODE
, &no_debug_igmp_trace_cmd
);
10374 install_element(ENABLE_NODE
, &debug_mroute_cmd
);
10375 install_element(ENABLE_NODE
, &debug_mroute_detail_cmd
);
10376 install_element(ENABLE_NODE
, &no_debug_mroute_cmd
);
10377 install_element(ENABLE_NODE
, &no_debug_mroute_detail_cmd
);
10378 install_element(ENABLE_NODE
, &debug_pim_static_cmd
);
10379 install_element(ENABLE_NODE
, &no_debug_pim_static_cmd
);
10380 install_element(ENABLE_NODE
, &debug_pim_cmd
);
10381 install_element(ENABLE_NODE
, &no_debug_pim_cmd
);
10382 install_element(ENABLE_NODE
, &debug_pim_nht_cmd
);
10383 install_element(ENABLE_NODE
, &no_debug_pim_nht_cmd
);
10384 install_element(ENABLE_NODE
, &debug_pim_nht_rp_cmd
);
10385 install_element(ENABLE_NODE
, &no_debug_pim_nht_rp_cmd
);
10386 install_element(ENABLE_NODE
, &debug_pim_events_cmd
);
10387 install_element(ENABLE_NODE
, &no_debug_pim_events_cmd
);
10388 install_element(ENABLE_NODE
, &debug_pim_packets_cmd
);
10389 install_element(ENABLE_NODE
, &no_debug_pim_packets_cmd
);
10390 install_element(ENABLE_NODE
, &debug_pim_packetdump_send_cmd
);
10391 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_send_cmd
);
10392 install_element(ENABLE_NODE
, &debug_pim_packetdump_recv_cmd
);
10393 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_recv_cmd
);
10394 install_element(ENABLE_NODE
, &debug_pim_trace_cmd
);
10395 install_element(ENABLE_NODE
, &no_debug_pim_trace_cmd
);
10396 install_element(ENABLE_NODE
, &debug_pim_trace_detail_cmd
);
10397 install_element(ENABLE_NODE
, &no_debug_pim_trace_detail_cmd
);
10398 install_element(ENABLE_NODE
, &debug_ssmpingd_cmd
);
10399 install_element(ENABLE_NODE
, &no_debug_ssmpingd_cmd
);
10400 install_element(ENABLE_NODE
, &debug_pim_zebra_cmd
);
10401 install_element(ENABLE_NODE
, &no_debug_pim_zebra_cmd
);
10402 install_element(ENABLE_NODE
, &debug_pim_vxlan_cmd
);
10403 install_element(ENABLE_NODE
, &no_debug_pim_vxlan_cmd
);
10404 install_element(ENABLE_NODE
, &debug_msdp_cmd
);
10405 install_element(ENABLE_NODE
, &no_debug_msdp_cmd
);
10406 install_element(ENABLE_NODE
, &debug_msdp_events_cmd
);
10407 install_element(ENABLE_NODE
, &no_debug_msdp_events_cmd
);
10408 install_element(ENABLE_NODE
, &debug_msdp_packets_cmd
);
10409 install_element(ENABLE_NODE
, &no_debug_msdp_packets_cmd
);
10410 install_element(ENABLE_NODE
, &debug_mtrace_cmd
);
10411 install_element(ENABLE_NODE
, &no_debug_mtrace_cmd
);
10412 install_element(ENABLE_NODE
, &debug_bsm_cmd
);
10413 install_element(ENABLE_NODE
, &no_debug_bsm_cmd
);
10415 install_element(CONFIG_NODE
, &debug_igmp_cmd
);
10416 install_element(CONFIG_NODE
, &no_debug_igmp_cmd
);
10417 install_element(CONFIG_NODE
, &debug_igmp_events_cmd
);
10418 install_element(CONFIG_NODE
, &no_debug_igmp_events_cmd
);
10419 install_element(CONFIG_NODE
, &debug_igmp_packets_cmd
);
10420 install_element(CONFIG_NODE
, &no_debug_igmp_packets_cmd
);
10421 install_element(CONFIG_NODE
, &debug_igmp_trace_cmd
);
10422 install_element(CONFIG_NODE
, &no_debug_igmp_trace_cmd
);
10423 install_element(CONFIG_NODE
, &debug_mroute_cmd
);
10424 install_element(CONFIG_NODE
, &debug_mroute_detail_cmd
);
10425 install_element(CONFIG_NODE
, &no_debug_mroute_cmd
);
10426 install_element(CONFIG_NODE
, &no_debug_mroute_detail_cmd
);
10427 install_element(CONFIG_NODE
, &debug_pim_static_cmd
);
10428 install_element(CONFIG_NODE
, &no_debug_pim_static_cmd
);
10429 install_element(CONFIG_NODE
, &debug_pim_cmd
);
10430 install_element(CONFIG_NODE
, &no_debug_pim_cmd
);
10431 install_element(CONFIG_NODE
, &debug_pim_nht_cmd
);
10432 install_element(CONFIG_NODE
, &no_debug_pim_nht_cmd
);
10433 install_element(CONFIG_NODE
, &debug_pim_nht_rp_cmd
);
10434 install_element(CONFIG_NODE
, &no_debug_pim_nht_rp_cmd
);
10435 install_element(CONFIG_NODE
, &debug_pim_events_cmd
);
10436 install_element(CONFIG_NODE
, &no_debug_pim_events_cmd
);
10437 install_element(CONFIG_NODE
, &debug_pim_packets_cmd
);
10438 install_element(CONFIG_NODE
, &no_debug_pim_packets_cmd
);
10439 install_element(CONFIG_NODE
, &debug_pim_trace_cmd
);
10440 install_element(CONFIG_NODE
, &no_debug_pim_trace_cmd
);
10441 install_element(CONFIG_NODE
, &debug_pim_trace_detail_cmd
);
10442 install_element(CONFIG_NODE
, &no_debug_pim_trace_detail_cmd
);
10443 install_element(CONFIG_NODE
, &debug_ssmpingd_cmd
);
10444 install_element(CONFIG_NODE
, &no_debug_ssmpingd_cmd
);
10445 install_element(CONFIG_NODE
, &debug_pim_zebra_cmd
);
10446 install_element(CONFIG_NODE
, &no_debug_pim_zebra_cmd
);
10447 install_element(CONFIG_NODE
, &debug_pim_vxlan_cmd
);
10448 install_element(CONFIG_NODE
, &no_debug_pim_vxlan_cmd
);
10449 install_element(CONFIG_NODE
, &debug_msdp_cmd
);
10450 install_element(CONFIG_NODE
, &no_debug_msdp_cmd
);
10451 install_element(CONFIG_NODE
, &debug_msdp_events_cmd
);
10452 install_element(CONFIG_NODE
, &no_debug_msdp_events_cmd
);
10453 install_element(CONFIG_NODE
, &debug_msdp_packets_cmd
);
10454 install_element(CONFIG_NODE
, &no_debug_msdp_packets_cmd
);
10455 install_element(CONFIG_NODE
, &debug_mtrace_cmd
);
10456 install_element(CONFIG_NODE
, &no_debug_mtrace_cmd
);
10457 install_element(CONFIG_NODE
, &debug_bsm_cmd
);
10458 install_element(CONFIG_NODE
, &no_debug_bsm_cmd
);
10460 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_member_cmd
);
10461 install_element(VRF_NODE
, &ip_msdp_mesh_group_member_cmd
);
10462 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
10463 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
10464 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_source_cmd
);
10465 install_element(VRF_NODE
, &ip_msdp_mesh_group_source_cmd
);
10466 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
10467 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
10468 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_cmd
);
10469 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_vrf_all_cmd
);
10470 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_cmd
);
10471 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_vrf_all_cmd
);
10472 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_cmd
);
10473 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_vrf_all_cmd
);
10474 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_cmd
);
10475 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_vrf_all_cmd
);
10476 install_element(VIEW_NODE
, &show_ip_pim_ssm_range_cmd
);
10477 install_element(VIEW_NODE
, &show_ip_pim_group_type_cmd
);
10478 install_element(VIEW_NODE
, &show_ip_pim_vxlan_sg_cmd
);
10479 install_element(VIEW_NODE
, &show_ip_pim_vxlan_sg_work_cmd
);
10480 install_element(INTERFACE_NODE
, &interface_pim_use_source_cmd
);
10481 install_element(INTERFACE_NODE
, &interface_no_pim_use_source_cmd
);
10482 /* Install BSM command */
10483 install_element(INTERFACE_NODE
, &ip_pim_bsm_cmd
);
10484 install_element(INTERFACE_NODE
, &no_ip_pim_bsm_cmd
);
10485 install_element(INTERFACE_NODE
, &ip_pim_ucast_bsm_cmd
);
10486 install_element(INTERFACE_NODE
, &no_ip_pim_ucast_bsm_cmd
);
10487 /* Install BFD command */
10488 install_element(INTERFACE_NODE
, &ip_pim_bfd_cmd
);
10489 install_element(INTERFACE_NODE
, &ip_pim_bfd_param_cmd
);
10490 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_cmd
);
10492 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_param_cmd
);
10493 #endif /* !HAVE_BFDD */