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 %7" PRIu64
"/%-7" PRIu64
"\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 %7" PRIu64
"/%-7" PRIu64
"\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)", 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_STAR
)
2138 vty_out(vty
, ", %s(%c%c%c%c)",
2140 (c_oil
->oif_flags
[oif_vif_index
]
2141 & PIM_OIF_FLAG_PROTO_IGMP
)
2144 (c_oil
->oif_flags
[oif_vif_index
]
2145 & PIM_OIF_FLAG_PROTO_PIM
)
2148 (c_oil
->oif_flags
[oif_vif_index
]
2149 & PIM_OIF_FLAG_PROTO_VXLAN
)
2152 (c_oil
->oif_flags
[oif_vif_index
]
2153 & PIM_OIF_FLAG_PROTO_STAR
)
2165 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2166 json
, JSON_C_TO_STRING_PRETTY
));
2167 json_object_free(json
);
2173 static void pim_show_neighbors(struct pim_instance
*pim
, struct vty
*vty
,
2176 struct listnode
*neighnode
;
2177 struct interface
*ifp
;
2178 struct pim_interface
*pim_ifp
;
2179 struct pim_neighbor
*neigh
;
2183 char neigh_src_str
[INET_ADDRSTRLEN
];
2184 json_object
*json
= NULL
;
2185 json_object
*json_ifp_rows
= NULL
;
2186 json_object
*json_row
= NULL
;
2188 now
= pim_time_monotonic_sec();
2191 json
= json_object_new_object();
2194 "Interface Neighbor Uptime Holdtime DR Pri\n");
2197 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2198 pim_ifp
= ifp
->info
;
2203 if (pim_ifp
->pim_sock_fd
< 0)
2207 json_ifp_rows
= json_object_new_object();
2209 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
2211 pim_inet4_dump("<src?>", neigh
->source_addr
,
2212 neigh_src_str
, sizeof(neigh_src_str
));
2213 pim_time_uptime(uptime
, sizeof(uptime
),
2214 now
- neigh
->creation
);
2215 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
2216 neigh
->t_expire_timer
);
2219 json_row
= json_object_new_object();
2220 json_object_string_add(json_row
, "interface",
2222 json_object_string_add(json_row
, "neighbor",
2224 json_object_string_add(json_row
, "upTime",
2226 json_object_string_add(json_row
, "holdTime",
2228 json_object_int_add(json_row
, "holdTimeMax",
2230 json_object_int_add(json_row
, "drPriority",
2231 neigh
->dr_priority
);
2232 json_object_object_add(json_ifp_rows
,
2233 neigh_src_str
, json_row
);
2236 vty_out(vty
, "%-16s %15s %8s %8s %6d\n",
2237 ifp
->name
, neigh_src_str
, uptime
,
2238 expire
, neigh
->dr_priority
);
2243 json_object_object_add(json
, ifp
->name
, json_ifp_rows
);
2244 json_ifp_rows
= NULL
;
2249 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2250 json
, JSON_C_TO_STRING_PRETTY
));
2251 json_object_free(json
);
2255 static void pim_show_neighbors_secondary(struct pim_instance
*pim
,
2258 struct interface
*ifp
;
2261 "Interface Address Neighbor Secondary \n");
2263 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2264 struct pim_interface
*pim_ifp
;
2265 struct in_addr ifaddr
;
2266 struct listnode
*neighnode
;
2267 struct pim_neighbor
*neigh
;
2269 pim_ifp
= ifp
->info
;
2274 if (pim_ifp
->pim_sock_fd
< 0)
2277 ifaddr
= pim_ifp
->primary_address
;
2279 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
2281 char neigh_src_str
[INET_ADDRSTRLEN
];
2282 struct listnode
*prefix_node
;
2285 if (!neigh
->prefix_list
)
2288 pim_inet4_dump("<src?>", neigh
->source_addr
,
2289 neigh_src_str
, sizeof(neigh_src_str
));
2291 for (ALL_LIST_ELEMENTS_RO(neigh
->prefix_list
,
2293 char neigh_sec_str
[PREFIX2STR_BUFFER
];
2295 prefix2str(p
, neigh_sec_str
,
2296 sizeof(neigh_sec_str
));
2298 vty_out(vty
, "%-16s %-15s %-15s %-15s\n",
2299 ifp
->name
, inet_ntoa(ifaddr
),
2300 neigh_src_str
, neigh_sec_str
);
2306 static void json_object_pim_upstream_add(json_object
*json
,
2307 struct pim_upstream
*up
)
2309 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED
)
2310 json_object_boolean_true_add(json
, "drJoinDesired");
2312 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED
)
2313 json_object_boolean_true_add(json
, "drJoinDesiredUpdated");
2315 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
2316 json_object_boolean_true_add(json
, "firstHopRouter");
2318 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_IGMP
)
2319 json_object_boolean_true_add(json
, "sourceIgmp");
2321 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_PIM
)
2322 json_object_boolean_true_add(json
, "sourcePim");
2324 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_STREAM
)
2325 json_object_boolean_true_add(json
, "sourceStream");
2327 /* XXX: need to print ths flag in the plain text display as well */
2328 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_MSDP
)
2329 json_object_boolean_true_add(json
, "sourceMsdp");
2331 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SEND_SG_RPT_PRUNE
)
2332 json_object_boolean_true_add(json
, "sendSGRptPrune");
2334 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_LHR
)
2335 json_object_boolean_true_add(json
, "lastHopRouter");
2337 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DISABLE_KAT_EXPIRY
)
2338 json_object_boolean_true_add(json
, "disableKATExpiry");
2340 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_STATIC_IIF
)
2341 json_object_boolean_true_add(json
, "staticIncomingInterface");
2343 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_ALLOW_IIF_IN_OIL
)
2344 json_object_boolean_true_add(json
,
2345 "allowIncomingInterfaceinOil");
2347 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_NO_PIMREG_DATA
)
2348 json_object_boolean_true_add(json
, "noPimRegistrationData");
2350 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FORCE_PIMREG
)
2351 json_object_boolean_true_add(json
, "forcePimRegistration");
2353 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_ORIG
)
2354 json_object_boolean_true_add(json
, "sourceVxlanOrigination");
2356 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_TERM
)
2357 json_object_boolean_true_add(json
, "sourceVxlanTermination");
2359 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_VXLAN
)
2360 json_object_boolean_true_add(json
, "mlagVxlan");
2362 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_NON_DF
)
2363 json_object_boolean_true_add(json
,
2364 "mlagNonDesignatedForwarder");
2368 pim_upstream_state2brief_str(enum pim_upstream_state join_state
,
2369 char *state_str
, size_t state_str_len
)
2371 switch (join_state
) {
2372 case PIM_UPSTREAM_NOTJOINED
:
2373 strlcpy(state_str
, "NotJ", state_str_len
);
2375 case PIM_UPSTREAM_JOINED
:
2376 strlcpy(state_str
, "J", state_str_len
);
2379 strlcpy(state_str
, "Unk", state_str_len
);
2384 static const char *pim_reg_state2brief_str(enum pim_reg_state reg_state
,
2385 char *state_str
, size_t state_str_len
)
2387 switch (reg_state
) {
2388 case PIM_REG_NOINFO
:
2389 strlcpy(state_str
, "RegNI", state_str_len
);
2392 strlcpy(state_str
, "RegJ", state_str_len
);
2394 case PIM_REG_JOIN_PENDING
:
2396 strlcpy(state_str
, "RegP", state_str_len
);
2399 strlcpy(state_str
, "Unk", state_str_len
);
2404 static void pim_show_upstream(struct pim_instance
*pim
, struct vty
*vty
,
2405 struct prefix_sg
*sg
, bool uj
)
2407 struct listnode
*upnode
;
2408 struct pim_upstream
*up
;
2410 json_object
*json
= NULL
;
2411 json_object
*json_group
= NULL
;
2412 json_object
*json_row
= NULL
;
2414 now
= pim_time_monotonic_sec();
2417 json
= json_object_new_object();
2420 "Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt\n");
2422 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
, up
)) {
2423 char src_str
[INET_ADDRSTRLEN
];
2424 char grp_str
[INET_ADDRSTRLEN
];
2426 char join_timer
[10];
2429 char msdp_reg_timer
[10];
2430 char state_str
[PIM_REG_STATE_STR_LEN
];
2432 if (sg
->grp
.s_addr
!= 0 && sg
->grp
.s_addr
!= up
->sg
.grp
.s_addr
)
2434 if (sg
->src
.s_addr
!= 0 && sg
->src
.s_addr
!= up
->sg
.src
.s_addr
)
2437 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2438 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2439 pim_time_uptime(uptime
, sizeof(uptime
),
2440 now
- up
->state_transition
);
2441 pim_time_timer_to_hhmmss(join_timer
, sizeof(join_timer
),
2445 * If the upstream is not dummy and it has a J/P timer for the
2446 * neighbor display that
2448 if (!up
->t_join_timer
&& up
->rpf
.source_nexthop
.interface
) {
2449 struct pim_neighbor
*nbr
;
2451 nbr
= pim_neighbor_find(
2452 up
->rpf
.source_nexthop
.interface
,
2453 up
->rpf
.rpf_addr
.u
.prefix4
);
2455 pim_time_timer_to_hhmmss(join_timer
,
2460 pim_time_timer_to_hhmmss(rs_timer
, sizeof(rs_timer
),
2462 pim_time_timer_to_hhmmss(ka_timer
, sizeof(ka_timer
),
2464 pim_time_timer_to_hhmmss(msdp_reg_timer
, sizeof(msdp_reg_timer
),
2465 up
->t_msdp_reg_timer
);
2467 pim_upstream_state2brief_str(up
->join_state
, state_str
, sizeof(state_str
));
2468 if (up
->reg_state
!= PIM_REG_NOINFO
) {
2469 char tmp_str
[PIM_REG_STATE_STR_LEN
];
2471 sprintf(state_str
+ strlen(state_str
), ",%s",
2472 pim_reg_state2brief_str(up
->reg_state
, tmp_str
,
2477 json_object_object_get_ex(json
, grp_str
, &json_group
);
2480 json_group
= json_object_new_object();
2481 json_object_object_add(json
, grp_str
,
2485 json_row
= json_object_new_object();
2486 json_object_pim_upstream_add(json_row
, up
);
2487 json_object_string_add(
2488 json_row
, "inboundInterface",
2489 up
->rpf
.source_nexthop
.interface
2490 ? up
->rpf
.source_nexthop
.interface
->name
2494 * The RPF address we use is slightly different
2495 * based upon what we are looking up.
2496 * If we have a S, list that unless
2497 * we are the FHR, else we just put
2498 * the RP as the rpfAddress
2500 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
2501 || up
->sg
.src
.s_addr
== INADDR_ANY
) {
2502 char rpf
[PREFIX_STRLEN
];
2503 struct pim_rpf
*rpg
;
2505 rpg
= RP(pim
, up
->sg
.grp
);
2506 pim_inet4_dump("<rpf?>",
2507 rpg
->rpf_addr
.u
.prefix4
, rpf
,
2509 json_object_string_add(json_row
, "rpfAddress",
2512 json_object_string_add(json_row
, "rpfAddress",
2516 json_object_string_add(json_row
, "source", src_str
);
2517 json_object_string_add(json_row
, "group", grp_str
);
2518 json_object_string_add(json_row
, "state", state_str
);
2519 json_object_string_add(
2520 json_row
, "joinState",
2521 pim_upstream_state2str(up
->join_state
));
2522 json_object_string_add(
2523 json_row
, "regState",
2524 pim_reg_state2str(up
->reg_state
, state_str
, sizeof(state_str
)));
2525 json_object_string_add(json_row
, "upTime", uptime
);
2526 json_object_string_add(json_row
, "joinTimer",
2528 json_object_string_add(json_row
, "resetTimer",
2530 json_object_string_add(json_row
, "keepaliveTimer",
2532 json_object_string_add(json_row
, "msdpRegTimer",
2534 json_object_int_add(json_row
, "refCount",
2536 json_object_int_add(json_row
, "sptBit", up
->sptbit
);
2537 json_object_object_add(json_group
, src_str
, json_row
);
2540 "%-16s%-15s %-15s %-11s %-8s %-9s %-9s %-9s %6d\n",
2541 up
->rpf
.source_nexthop
.interface
2542 ? up
->rpf
.source_nexthop
.interface
->name
2544 src_str
, grp_str
, state_str
, uptime
, join_timer
,
2545 rs_timer
, ka_timer
, up
->ref_count
);
2550 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2551 json
, JSON_C_TO_STRING_PRETTY
));
2552 json_object_free(json
);
2556 static void pim_show_join_desired_helper(struct pim_instance
*pim
,
2558 struct pim_interface
*pim_ifp
,
2559 struct pim_ifchannel
*ch
,
2560 json_object
*json
, bool uj
)
2562 struct pim_upstream
*up
= ch
->upstream
;
2563 json_object
*json_group
= NULL
;
2564 char src_str
[INET_ADDRSTRLEN
];
2565 char grp_str
[INET_ADDRSTRLEN
];
2566 json_object
*json_row
= NULL
;
2568 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2569 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2572 json_object_object_get_ex(json
, grp_str
, &json_group
);
2575 json_group
= json_object_new_object();
2576 json_object_object_add(json
, grp_str
, json_group
);
2579 json_row
= json_object_new_object();
2580 json_object_pim_upstream_add(json_row
, up
);
2581 json_object_string_add(json_row
, "interface",
2582 ch
->interface
->name
);
2583 json_object_string_add(json_row
, "source", src_str
);
2584 json_object_string_add(json_row
, "group", grp_str
);
2586 if (pim_macro_ch_lost_assert(ch
))
2587 json_object_boolean_true_add(json_row
, "lostAssert");
2589 if (pim_macro_chisin_joins(ch
))
2590 json_object_boolean_true_add(json_row
, "joins");
2592 if (pim_macro_chisin_pim_include(ch
))
2593 json_object_boolean_true_add(json_row
, "pimInclude");
2595 if (pim_upstream_evaluate_join_desired(pim
, up
))
2596 json_object_boolean_true_add(json_row
,
2597 "evaluateJoinDesired");
2599 json_object_object_add(json_group
, src_str
, json_row
);
2602 vty_out(vty
, "%-16s %-15s %-15s %-10s %-5s %-10s %-11s %-6s\n",
2603 ch
->interface
->name
, src_str
, grp_str
,
2604 pim_macro_ch_lost_assert(ch
) ? "yes" : "no",
2605 pim_macro_chisin_joins(ch
) ? "yes" : "no",
2606 pim_macro_chisin_pim_include(ch
) ? "yes" : "no",
2607 PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(up
->flags
)
2610 pim_upstream_evaluate_join_desired(pim
, up
) ? "yes"
2615 static void pim_show_join_desired(struct pim_instance
*pim
, struct vty
*vty
,
2618 struct pim_interface
*pim_ifp
;
2619 struct pim_ifchannel
*ch
;
2620 struct interface
*ifp
;
2622 json_object
*json
= NULL
;
2625 json
= json_object_new_object();
2628 "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD\n");
2630 /* scan per-interface (S,G) state */
2631 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2632 pim_ifp
= ifp
->info
;
2637 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
2638 /* scan all interfaces */
2639 pim_show_join_desired_helper(pim
, vty
, pim_ifp
, ch
,
2645 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2646 json
, JSON_C_TO_STRING_PRETTY
));
2647 json_object_free(json
);
2651 static void pim_show_upstream_rpf(struct pim_instance
*pim
, struct vty
*vty
,
2654 struct listnode
*upnode
;
2655 struct pim_upstream
*up
;
2656 json_object
*json
= NULL
;
2657 json_object
*json_group
= NULL
;
2658 json_object
*json_row
= NULL
;
2661 json
= json_object_new_object();
2664 "Source Group RpfIface RibNextHop RpfAddress \n");
2666 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
, up
)) {
2667 char src_str
[INET_ADDRSTRLEN
];
2668 char grp_str
[INET_ADDRSTRLEN
];
2669 char rpf_nexthop_str
[PREFIX_STRLEN
];
2670 char rpf_addr_str
[PREFIX_STRLEN
];
2671 struct pim_rpf
*rpf
;
2672 const char *rpf_ifname
;
2676 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2677 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2678 pim_addr_dump("<nexthop?>",
2679 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2680 rpf_nexthop_str
, sizeof(rpf_nexthop_str
));
2681 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2682 sizeof(rpf_addr_str
));
2684 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2687 json_object_object_get_ex(json
, grp_str
, &json_group
);
2690 json_group
= json_object_new_object();
2691 json_object_object_add(json
, grp_str
,
2695 json_row
= json_object_new_object();
2696 json_object_pim_upstream_add(json_row
, up
);
2697 json_object_string_add(json_row
, "source", src_str
);
2698 json_object_string_add(json_row
, "group", grp_str
);
2699 json_object_string_add(json_row
, "rpfInterface",
2701 json_object_string_add(json_row
, "ribNexthop",
2703 json_object_string_add(json_row
, "rpfAddress",
2705 json_object_object_add(json_group
, src_str
, json_row
);
2707 vty_out(vty
, "%-15s %-15s %-16s %-15s %-15s\n", src_str
,
2708 grp_str
, rpf_ifname
, rpf_nexthop_str
,
2714 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2715 json
, JSON_C_TO_STRING_PRETTY
));
2716 json_object_free(json
);
2720 static void show_rpf_refresh_stats(struct vty
*vty
, struct pim_instance
*pim
,
2721 time_t now
, json_object
*json
)
2723 char refresh_uptime
[10];
2725 pim_time_uptime_begin(refresh_uptime
, sizeof(refresh_uptime
), now
,
2726 pim
->rpf_cache_refresh_last
);
2729 json_object_int_add(json
, "rpfCacheRefreshDelayMsecs",
2730 router
->rpf_cache_refresh_delay_msec
);
2731 json_object_int_add(
2732 json
, "rpfCacheRefreshTimer",
2733 pim_time_timer_remain_msec(pim
->rpf_cache_refresher
));
2734 json_object_int_add(json
, "rpfCacheRefreshRequests",
2735 pim
->rpf_cache_refresh_requests
);
2736 json_object_int_add(json
, "rpfCacheRefreshEvents",
2737 pim
->rpf_cache_refresh_events
);
2738 json_object_string_add(json
, "rpfCacheRefreshLast",
2740 json_object_int_add(json
, "nexthopLookups",
2741 pim
->nexthop_lookups
);
2742 json_object_int_add(json
, "nexthopLookupsAvoided",
2743 pim
->nexthop_lookups_avoided
);
2746 "RPF Cache Refresh Delay: %ld msecs\n"
2747 "RPF Cache Refresh Timer: %ld msecs\n"
2748 "RPF Cache Refresh Requests: %lld\n"
2749 "RPF Cache Refresh Events: %lld\n"
2750 "RPF Cache Refresh Last: %s\n"
2751 "Nexthop Lookups: %lld\n"
2752 "Nexthop Lookups Avoided: %lld\n",
2753 router
->rpf_cache_refresh_delay_msec
,
2754 pim_time_timer_remain_msec(pim
->rpf_cache_refresher
),
2755 (long long)pim
->rpf_cache_refresh_requests
,
2756 (long long)pim
->rpf_cache_refresh_events
,
2757 refresh_uptime
, (long long)pim
->nexthop_lookups
,
2758 (long long)pim
->nexthop_lookups_avoided
);
2762 static void show_scan_oil_stats(struct pim_instance
*pim
, struct vty
*vty
,
2765 char uptime_scan_oil
[10];
2766 char uptime_mroute_add
[10];
2767 char uptime_mroute_del
[10];
2769 pim_time_uptime_begin(uptime_scan_oil
, sizeof(uptime_scan_oil
), now
,
2770 pim
->scan_oil_last
);
2771 pim_time_uptime_begin(uptime_mroute_add
, sizeof(uptime_mroute_add
), now
,
2772 pim
->mroute_add_last
);
2773 pim_time_uptime_begin(uptime_mroute_del
, sizeof(uptime_mroute_del
), now
,
2774 pim
->mroute_del_last
);
2777 "Scan OIL - Last: %s Events: %lld\n"
2778 "MFC Add - Last: %s Events: %lld\n"
2779 "MFC Del - Last: %s Events: %lld\n",
2780 uptime_scan_oil
, (long long)pim
->scan_oil_events
,
2781 uptime_mroute_add
, (long long)pim
->mroute_add_events
,
2782 uptime_mroute_del
, (long long)pim
->mroute_del_events
);
2785 static void pim_show_rpf(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
2787 struct listnode
*up_node
;
2788 struct pim_upstream
*up
;
2789 time_t now
= pim_time_monotonic_sec();
2790 json_object
*json
= NULL
;
2791 json_object
*json_group
= NULL
;
2792 json_object
*json_row
= NULL
;
2795 json
= json_object_new_object();
2796 show_rpf_refresh_stats(vty
, pim
, now
, json
);
2798 show_rpf_refresh_stats(vty
, pim
, now
, json
);
2801 "Source Group RpfIface RpfAddress RibNextHop Metric Pref\n");
2804 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, up_node
, up
)) {
2805 char src_str
[INET_ADDRSTRLEN
];
2806 char grp_str
[INET_ADDRSTRLEN
];
2807 char rpf_addr_str
[PREFIX_STRLEN
];
2808 char rib_nexthop_str
[PREFIX_STRLEN
];
2809 const char *rpf_ifname
;
2810 struct pim_rpf
*rpf
= &up
->rpf
;
2812 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2813 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2814 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2815 sizeof(rpf_addr_str
));
2816 pim_addr_dump("<nexthop?>",
2817 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2818 rib_nexthop_str
, sizeof(rib_nexthop_str
));
2820 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2823 json_object_object_get_ex(json
, grp_str
, &json_group
);
2826 json_group
= json_object_new_object();
2827 json_object_object_add(json
, grp_str
,
2831 json_row
= json_object_new_object();
2832 json_object_string_add(json_row
, "source", src_str
);
2833 json_object_string_add(json_row
, "group", grp_str
);
2834 json_object_string_add(json_row
, "rpfInterface",
2836 json_object_string_add(json_row
, "rpfAddress",
2838 json_object_string_add(json_row
, "ribNexthop",
2840 json_object_int_add(
2841 json_row
, "routeMetric",
2842 rpf
->source_nexthop
.mrib_route_metric
);
2843 json_object_int_add(
2844 json_row
, "routePreference",
2845 rpf
->source_nexthop
.mrib_metric_preference
);
2846 json_object_object_add(json_group
, src_str
, json_row
);
2849 vty_out(vty
, "%-15s %-15s %-16s %-15s %-15s %6d %4d\n",
2850 src_str
, grp_str
, rpf_ifname
, rpf_addr_str
,
2852 rpf
->source_nexthop
.mrib_route_metric
,
2853 rpf
->source_nexthop
.mrib_metric_preference
);
2858 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2859 json
, JSON_C_TO_STRING_PRETTY
));
2860 json_object_free(json
);
2864 struct pnc_cache_walk_data
{
2866 struct pim_instance
*pim
;
2869 static int pim_print_pnc_cache_walkcb(struct hash_bucket
*bucket
, void *arg
)
2871 struct pim_nexthop_cache
*pnc
= bucket
->data
;
2872 struct pnc_cache_walk_data
*cwd
= arg
;
2873 struct vty
*vty
= cwd
->vty
;
2874 struct pim_instance
*pim
= cwd
->pim
;
2875 struct nexthop
*nh_node
= NULL
;
2876 ifindex_t first_ifindex
;
2877 struct interface
*ifp
= NULL
;
2879 for (nh_node
= pnc
->nexthop
; nh_node
; nh_node
= nh_node
->next
) {
2880 first_ifindex
= nh_node
->ifindex
;
2881 ifp
= if_lookup_by_index(first_ifindex
, pim
->vrf_id
);
2883 vty_out(vty
, "%-15s ", inet_ntoa(pnc
->rpf
.rpf_addr
.u
.prefix4
));
2884 vty_out(vty
, "%-16s ", ifp
? ifp
->name
: "NULL");
2885 vty_out(vty
, "%s ", inet_ntoa(nh_node
->gate
.ipv4
));
2891 static void pim_show_nexthop(struct pim_instance
*pim
, struct vty
*vty
)
2893 struct pnc_cache_walk_data cwd
;
2897 vty_out(vty
, "Number of registered addresses: %lu\n",
2898 pim
->rpf_hash
->count
);
2899 vty_out(vty
, "Address Interface Nexthop\n");
2900 vty_out(vty
, "---------------------------------------------\n");
2902 hash_walk(pim
->rpf_hash
, pim_print_pnc_cache_walkcb
, &cwd
);
2905 /* Display the bsm database details */
2906 static void pim_show_bsm_db(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
2908 struct listnode
*bsmnode
;
2911 struct bsm_info
*bsm
;
2912 json_object
*json
= NULL
;
2913 json_object
*json_group
= NULL
;
2914 json_object
*json_row
= NULL
;
2916 count
= pim
->global_scope
.bsm_list
->count
;
2919 json
= json_object_new_object();
2920 json_object_int_add(json
, "Number of the fragments", count
);
2922 vty_out(vty
, "Scope Zone: Global\n");
2923 vty_out(vty
, "Number of the fragments: %d\n", count
);
2927 for (ALL_LIST_ELEMENTS_RO(pim
->global_scope
.bsm_list
, bsmnode
, bsm
)) {
2928 char grp_str
[INET_ADDRSTRLEN
];
2929 char rp_str
[INET_ADDRSTRLEN
];
2930 char bsr_str
[INET_ADDRSTRLEN
];
2931 struct bsmmsg_grpinfo
*group
;
2932 struct bsmmsg_rpinfo
*rpaddr
;
2934 struct bsm_hdr
*hdr
;
2935 uint32_t offset
= 0;
2938 uint32_t frag_rp_cnt
= 0;
2943 /* skip pim header */
2944 buf
+= PIM_MSG_HEADER_LEN
;
2945 len
-= PIM_MSG_HEADER_LEN
;
2947 hdr
= (struct bsm_hdr
*)buf
;
2949 /* BSM starts with bsr header */
2950 buf
+= sizeof(struct bsm_hdr
);
2951 len
-= sizeof(struct bsm_hdr
);
2953 pim_inet4_dump("<BSR Address?>", hdr
->bsr_addr
.addr
, bsr_str
,
2958 json_object_string_add(json
, "BSR address", bsr_str
);
2959 json_object_int_add(json
, "BSR priority",
2961 json_object_int_add(json
, "Hashmask Length",
2963 json_object_int_add(json
, "Fragment Tag",
2964 ntohs(hdr
->frag_tag
));
2966 vty_out(vty
, "BSM Fragment : %d\n", fragment
);
2967 vty_out(vty
, "------------------\n");
2968 vty_out(vty
, "%-15s %-15s %-15s %-15s\n", "BSR-Address",
2969 "BSR-Priority", "Hashmask-len", "Fragment-Tag");
2970 vty_out(vty
, "%-15s %-15d %-15d %-15d\n", bsr_str
,
2971 hdr
->bsr_prio
, hdr
->hm_len
,
2972 ntohs(hdr
->frag_tag
));
2977 while (offset
< len
) {
2978 group
= (struct bsmmsg_grpinfo
*)buf
;
2980 if (group
->group
.family
== PIM_MSG_ADDRESS_FAMILY_IPV4
)
2981 grp
.family
= AF_INET
;
2983 grp
.prefixlen
= group
->group
.mask
;
2984 grp
.u
.prefix4
.s_addr
= group
->group
.addr
.s_addr
;
2986 prefix2str(&grp
, grp_str
, sizeof(grp_str
));
2988 buf
+= sizeof(struct bsmmsg_grpinfo
);
2989 offset
+= sizeof(struct bsmmsg_grpinfo
);
2992 json_object_object_get_ex(json
, grp_str
,
2995 json_group
= json_object_new_object();
2996 json_object_int_add(json_group
,
2999 json_object_int_add(
3000 json_group
, "Fragment Rp count",
3001 group
->frag_rp_count
);
3002 json_object_object_add(json
, grp_str
,
3006 vty_out(vty
, "Group : %s\n", grp_str
);
3007 vty_out(vty
, "-------------------\n");
3008 vty_out(vty
, "Rp Count:%d\n", group
->rp_count
);
3009 vty_out(vty
, "Fragment Rp Count : %d\n",
3010 group
->frag_rp_count
);
3013 frag_rp_cnt
= group
->frag_rp_count
;
3020 "RpAddress HoldTime Priority\n");
3022 while (frag_rp_cnt
--) {
3023 rpaddr
= (struct bsmmsg_rpinfo
*)buf
;
3025 buf
+= sizeof(struct bsmmsg_rpinfo
);
3026 offset
+= sizeof(struct bsmmsg_rpinfo
);
3028 pim_inet4_dump("<Rp addr?>",
3029 rpaddr
->rpaddr
.addr
, rp_str
,
3033 json_row
= json_object_new_object();
3034 json_object_string_add(
3035 json_row
, "Rp Address", rp_str
);
3036 json_object_int_add(
3037 json_row
, "Rp HoldTime",
3038 ntohs(rpaddr
->rp_holdtime
));
3039 json_object_int_add(json_row
,
3042 json_object_object_add(
3043 json_group
, rp_str
, json_row
);
3045 vty_out(vty
, "%-15s %-12d %d\n", rp_str
,
3046 ntohs(rpaddr
->rp_holdtime
),
3057 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3058 json
, JSON_C_TO_STRING_PRETTY
));
3059 json_object_free(json
);
3063 /*Display the group-rp mappings */
3064 static void pim_show_group_rp_mappings_info(struct pim_instance
*pim
,
3065 struct vty
*vty
, bool uj
)
3067 struct bsgrp_node
*bsgrp
;
3068 struct listnode
*rpnode
;
3069 struct bsm_rpinfo
*bsm_rp
;
3070 struct route_node
*rn
;
3071 char bsr_str
[INET_ADDRSTRLEN
];
3072 json_object
*json
= NULL
;
3073 json_object
*json_group
= NULL
;
3074 json_object
*json_row
= NULL
;
3076 if (pim
->global_scope
.current_bsr
.s_addr
== INADDR_ANY
)
3077 strlcpy(bsr_str
, "0.0.0.0", sizeof(bsr_str
));
3080 pim_inet4_dump("<bsr?>", pim
->global_scope
.current_bsr
, bsr_str
,
3084 json
= json_object_new_object();
3085 json_object_string_add(json
, "BSR Address", bsr_str
);
3087 vty_out(vty
, "BSR Address %s\n", bsr_str
);
3090 for (rn
= route_top(pim
->global_scope
.bsrp_table
); rn
;
3091 rn
= route_next(rn
)) {
3092 bsgrp
= (struct bsgrp_node
*)rn
->info
;
3097 char grp_str
[INET_ADDRSTRLEN
];
3099 prefix2str(&bsgrp
->group
, grp_str
, sizeof(grp_str
));
3102 json_object_object_get_ex(json
, grp_str
, &json_group
);
3104 json_group
= json_object_new_object();
3105 json_object_object_add(json
, grp_str
,
3109 vty_out(vty
, "Group Address %s\n", grp_str
);
3110 vty_out(vty
, "--------------------------\n");
3111 vty_out(vty
, "%-15s %-15s %-15s %-15s\n", "Rp Address",
3112 "priority", "Holdtime", "Hash");
3114 vty_out(vty
, "(ACTIVE)\n");
3117 if (bsgrp
->bsrp_list
) {
3118 for (ALL_LIST_ELEMENTS_RO(bsgrp
->bsrp_list
, rpnode
,
3120 char rp_str
[INET_ADDRSTRLEN
];
3122 pim_inet4_dump("<Rp Address?>",
3123 bsm_rp
->rp_address
, rp_str
,
3127 json_row
= json_object_new_object();
3128 json_object_string_add(
3129 json_row
, "Rp Address", rp_str
);
3130 json_object_int_add(
3131 json_row
, "Rp HoldTime",
3132 bsm_rp
->rp_holdtime
);
3133 json_object_int_add(json_row
,
3136 json_object_int_add(json_row
,
3139 json_object_object_add(
3140 json_group
, rp_str
, json_row
);
3144 "%-15s %-15u %-15u %-15u\n",
3145 rp_str
, bsm_rp
->rp_prio
,
3146 bsm_rp
->rp_holdtime
,
3150 if (!bsgrp
->bsrp_list
->count
&& !uj
)
3151 vty_out(vty
, "Active List is empty.\n");
3155 json_object_int_add(json_group
, "Pending RP count",
3156 bsgrp
->pend_rp_cnt
);
3158 vty_out(vty
, "(PENDING)\n");
3159 vty_out(vty
, "Pending RP count :%d\n",
3160 bsgrp
->pend_rp_cnt
);
3161 if (bsgrp
->pend_rp_cnt
)
3162 vty_out(vty
, "%-15s %-15s %-15s %-15s\n",
3163 "Rp Address", "priority", "Holdtime",
3167 if (bsgrp
->partial_bsrp_list
) {
3168 for (ALL_LIST_ELEMENTS_RO(bsgrp
->partial_bsrp_list
,
3170 char rp_str
[INET_ADDRSTRLEN
];
3172 pim_inet4_dump("<Rp Addr?>", bsm_rp
->rp_address
,
3173 rp_str
, sizeof(rp_str
));
3176 json_row
= json_object_new_object();
3177 json_object_string_add(
3178 json_row
, "Rp Address", rp_str
);
3179 json_object_int_add(
3180 json_row
, "Rp HoldTime",
3181 bsm_rp
->rp_holdtime
);
3182 json_object_int_add(json_row
,
3185 json_object_int_add(json_row
,
3188 json_object_object_add(
3189 json_group
, rp_str
, json_row
);
3192 "%-15s %-15u %-15u %-15u\n",
3193 rp_str
, bsm_rp
->rp_prio
,
3194 bsm_rp
->rp_holdtime
,
3198 if (!bsgrp
->partial_bsrp_list
->count
&& !uj
)
3199 vty_out(vty
, "Partial List is empty\n");
3207 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3208 json
, JSON_C_TO_STRING_PRETTY
));
3209 json_object_free(json
);
3213 /* pim statistics - just adding only bsm related now.
3214 * We can continue to add all pim related stats here.
3216 static void pim_show_statistics(struct pim_instance
*pim
, struct vty
*vty
,
3217 const char *ifname
, bool uj
)
3219 json_object
*json
= NULL
;
3220 struct interface
*ifp
;
3223 json
= json_object_new_object();
3224 json_object_int_add(json
, "Number of Received BSMs",
3226 json_object_int_add(json
, "Number of Forwared BSMs",
3228 json_object_int_add(json
, "Number of Dropped BSMs",
3231 vty_out(vty
, "BSM Statistics :\n");
3232 vty_out(vty
, "----------------\n");
3233 vty_out(vty
, "Number of Received BSMs : %" PRIu64
"\n",
3235 vty_out(vty
, "Number of Forwared BSMs : %" PRIu64
"\n",
3237 vty_out(vty
, "Number of Dropped BSMs : %" PRIu64
"\n",
3243 /* scan interfaces */
3244 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3245 struct pim_interface
*pim_ifp
= ifp
->info
;
3247 if (ifname
&& strcmp(ifname
, ifp
->name
))
3254 vty_out(vty
, "Interface : %s\n", ifp
->name
);
3255 vty_out(vty
, "-------------------\n");
3257 "Number of BSMs dropped due to config miss : %u\n",
3258 pim_ifp
->pim_ifstat_bsm_cfg_miss
);
3259 vty_out(vty
, "Number of unicast BSMs dropped : %u\n",
3260 pim_ifp
->pim_ifstat_ucast_bsm_cfg_miss
);
3262 "Number of BSMs dropped due to invalid scope zone : %u\n",
3263 pim_ifp
->pim_ifstat_bsm_invalid_sz
);
3266 json_object
*json_row
= NULL
;
3268 json_row
= json_object_new_object();
3270 json_object_string_add(json_row
, "If Name", ifp
->name
);
3271 json_object_int_add(
3273 "Number of BSMs dropped due to config miss",
3274 pim_ifp
->pim_ifstat_bsm_cfg_miss
);
3275 json_object_int_add(
3276 json_row
, "Number of unicast BSMs dropped",
3277 pim_ifp
->pim_ifstat_ucast_bsm_cfg_miss
);
3278 json_object_int_add(json_row
,
3279 "Number of BSMs dropped due to invalid scope zone",
3280 pim_ifp
->pim_ifstat_bsm_invalid_sz
);
3281 json_object_object_add(json
, ifp
->name
, json_row
);
3287 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3288 json
, JSON_C_TO_STRING_PRETTY
));
3289 json_object_free(json
);
3293 static void clear_pim_statistics(struct pim_instance
*pim
)
3295 struct interface
*ifp
;
3299 pim
->bsm_dropped
= 0;
3301 /* scan interfaces */
3302 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3303 struct pim_interface
*pim_ifp
= ifp
->info
;
3308 pim_ifp
->pim_ifstat_bsm_cfg_miss
= 0;
3309 pim_ifp
->pim_ifstat_ucast_bsm_cfg_miss
= 0;
3310 pim_ifp
->pim_ifstat_bsm_invalid_sz
= 0;
3314 static void igmp_show_groups(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
3316 struct interface
*ifp
;
3318 json_object
*json
= NULL
;
3319 json_object
*json_iface
= NULL
;
3320 json_object
*json_row
= NULL
;
3322 now
= pim_time_monotonic_sec();
3325 json
= json_object_new_object();
3328 "Interface Address Group Mode Timer Srcs V Uptime \n");
3330 /* scan interfaces */
3331 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3332 struct pim_interface
*pim_ifp
= ifp
->info
;
3333 struct listnode
*sock_node
;
3334 struct igmp_sock
*igmp
;
3339 /* scan igmp sockets */
3340 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3342 char ifaddr_str
[INET_ADDRSTRLEN
];
3343 struct listnode
*grpnode
;
3344 struct igmp_group
*grp
;
3346 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3347 sizeof(ifaddr_str
));
3349 /* scan igmp groups */
3350 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3352 char group_str
[INET_ADDRSTRLEN
];
3356 pim_inet4_dump("<group?>", grp
->group_addr
,
3357 group_str
, sizeof(group_str
));
3358 pim_time_timer_to_hhmmss(hhmmss
, sizeof(hhmmss
),
3359 grp
->t_group_timer
);
3360 pim_time_uptime(uptime
, sizeof(uptime
),
3361 now
- grp
->group_creation
);
3364 json_object_object_get_ex(
3365 json
, ifp
->name
, &json_iface
);
3369 json_object_new_object();
3370 json_object_pim_ifp_add(
3372 json_object_object_add(
3377 json_row
= json_object_new_object();
3378 json_object_string_add(
3379 json_row
, "source", ifaddr_str
);
3380 json_object_string_add(
3381 json_row
, "group", group_str
);
3383 if (grp
->igmp_version
== 3)
3384 json_object_string_add(
3386 grp
->group_filtermode_isexcl
3390 json_object_string_add(json_row
,
3392 json_object_int_add(
3393 json_row
, "sourcesCount",
3394 grp
->group_source_list
3396 grp
->group_source_list
)
3398 json_object_int_add(json_row
, "version",
3400 json_object_string_add(
3401 json_row
, "uptime", uptime
);
3402 json_object_object_add(json_iface
,
3408 "%-16s %-15s %-15s %4s %8s %4d %d %8s\n",
3409 ifp
->name
, ifaddr_str
,
3411 grp
->igmp_version
== 3
3412 ? (grp
->group_filtermode_isexcl
3417 grp
->group_source_list
3419 grp
->group_source_list
)
3421 grp
->igmp_version
, uptime
);
3423 } /* scan igmp groups */
3424 } /* scan igmp sockets */
3425 } /* scan interfaces */
3428 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3429 json
, JSON_C_TO_STRING_PRETTY
));
3430 json_object_free(json
);
3434 static void igmp_show_group_retransmission(struct pim_instance
*pim
,
3437 struct interface
*ifp
;
3440 "Interface Address Group RetTimer Counter RetSrcs\n");
3442 /* scan interfaces */
3443 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3444 struct pim_interface
*pim_ifp
= ifp
->info
;
3445 struct listnode
*sock_node
;
3446 struct igmp_sock
*igmp
;
3451 /* scan igmp sockets */
3452 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3454 char ifaddr_str
[INET_ADDRSTRLEN
];
3455 struct listnode
*grpnode
;
3456 struct igmp_group
*grp
;
3458 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3459 sizeof(ifaddr_str
));
3461 /* scan igmp groups */
3462 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3464 char group_str
[INET_ADDRSTRLEN
];
3465 char grp_retr_mmss
[10];
3466 struct listnode
*src_node
;
3467 struct igmp_source
*src
;
3468 int grp_retr_sources
= 0;
3470 pim_inet4_dump("<group?>", grp
->group_addr
,
3471 group_str
, sizeof(group_str
));
3472 pim_time_timer_to_mmss(
3473 grp_retr_mmss
, sizeof(grp_retr_mmss
),
3474 grp
->t_group_query_retransmit_timer
);
3477 /* count group sources with retransmission state
3479 for (ALL_LIST_ELEMENTS_RO(
3480 grp
->group_source_list
, src_node
,
3482 if (src
->source_query_retransmit_count
3488 vty_out(vty
, "%-16s %-15s %-15s %-8s %7d %7d\n",
3489 ifp
->name
, ifaddr_str
, group_str
,
3491 grp
->group_specific_query_retransmit_count
,
3494 } /* scan igmp groups */
3495 } /* scan igmp sockets */
3496 } /* scan interfaces */
3499 static void igmp_show_sources(struct pim_instance
*pim
, struct vty
*vty
)
3501 struct interface
*ifp
;
3504 now
= pim_time_monotonic_sec();
3507 "Interface Address Group Source Timer Fwd Uptime \n");
3509 /* scan interfaces */
3510 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3511 struct pim_interface
*pim_ifp
= ifp
->info
;
3512 struct listnode
*sock_node
;
3513 struct igmp_sock
*igmp
;
3518 /* scan igmp sockets */
3519 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3521 char ifaddr_str
[INET_ADDRSTRLEN
];
3522 struct listnode
*grpnode
;
3523 struct igmp_group
*grp
;
3525 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3526 sizeof(ifaddr_str
));
3528 /* scan igmp groups */
3529 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3531 char group_str
[INET_ADDRSTRLEN
];
3532 struct listnode
*srcnode
;
3533 struct igmp_source
*src
;
3535 pim_inet4_dump("<group?>", grp
->group_addr
,
3536 group_str
, sizeof(group_str
));
3538 /* scan group sources */
3539 for (ALL_LIST_ELEMENTS_RO(
3540 grp
->group_source_list
, srcnode
,
3542 char source_str
[INET_ADDRSTRLEN
];
3547 "<source?>", src
->source_addr
,
3548 source_str
, sizeof(source_str
));
3550 pim_time_timer_to_mmss(
3552 src
->t_source_timer
);
3555 uptime
, sizeof(uptime
),
3556 now
- src
->source_creation
);
3559 "%-16s %-15s %-15s %-15s %5s %3s %8s\n",
3560 ifp
->name
, ifaddr_str
,
3561 group_str
, source_str
, mmss
,
3562 IGMP_SOURCE_TEST_FORWARDING(
3568 } /* scan group sources */
3569 } /* scan igmp groups */
3570 } /* scan igmp sockets */
3571 } /* scan interfaces */
3574 static void igmp_show_source_retransmission(struct pim_instance
*pim
,
3577 struct interface
*ifp
;
3580 "Interface Address Group Source Counter\n");
3582 /* scan interfaces */
3583 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3584 struct pim_interface
*pim_ifp
= ifp
->info
;
3585 struct listnode
*sock_node
;
3586 struct igmp_sock
*igmp
;
3591 /* scan igmp sockets */
3592 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3594 char ifaddr_str
[INET_ADDRSTRLEN
];
3595 struct listnode
*grpnode
;
3596 struct igmp_group
*grp
;
3598 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3599 sizeof(ifaddr_str
));
3601 /* scan igmp groups */
3602 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3604 char group_str
[INET_ADDRSTRLEN
];
3605 struct listnode
*srcnode
;
3606 struct igmp_source
*src
;
3608 pim_inet4_dump("<group?>", grp
->group_addr
,
3609 group_str
, sizeof(group_str
));
3611 /* scan group sources */
3612 for (ALL_LIST_ELEMENTS_RO(
3613 grp
->group_source_list
, srcnode
,
3615 char source_str
[INET_ADDRSTRLEN
];
3618 "<source?>", src
->source_addr
,
3619 source_str
, sizeof(source_str
));
3622 "%-16s %-15s %-15s %-15s %7d\n",
3623 ifp
->name
, ifaddr_str
,
3624 group_str
, source_str
,
3625 src
->source_query_retransmit_count
);
3627 } /* scan group sources */
3628 } /* scan igmp groups */
3629 } /* scan igmp sockets */
3630 } /* scan interfaces */
3633 static void pim_show_bsr(struct pim_instance
*pim
,
3638 char last_bsm_seen
[10];
3641 char bsr_str
[PREFIX_STRLEN
];
3642 json_object
*json
= NULL
;
3644 vty_out(vty
, "PIMv2 Bootstrap information\n");
3646 if (pim
->global_scope
.current_bsr
.s_addr
== INADDR_ANY
) {
3647 strlcpy(bsr_str
, "0.0.0.0", sizeof(bsr_str
));
3648 pim_time_uptime(uptime
, sizeof(uptime
),
3649 pim
->global_scope
.current_bsr_first_ts
);
3650 pim_time_uptime(last_bsm_seen
, sizeof(last_bsm_seen
),
3651 pim
->global_scope
.current_bsr_last_ts
);
3655 pim_inet4_dump("<bsr?>", pim
->global_scope
.current_bsr
,
3656 bsr_str
, sizeof(bsr_str
));
3657 now
= pim_time_monotonic_sec();
3658 pim_time_uptime(uptime
, sizeof(uptime
),
3659 (now
- pim
->global_scope
.current_bsr_first_ts
));
3660 pim_time_uptime(last_bsm_seen
, sizeof(last_bsm_seen
),
3661 now
- pim
->global_scope
.current_bsr_last_ts
);
3664 switch (pim
->global_scope
.state
) {
3666 strlcpy(bsr_state
, "NO_INFO", sizeof(bsr_state
));
3669 strlcpy(bsr_state
, "ACCEPT_ANY", sizeof(bsr_state
));
3671 case ACCEPT_PREFERRED
:
3672 strlcpy(bsr_state
, "ACCEPT_PREFERRED", sizeof(bsr_state
));
3675 strlcpy(bsr_state
, "", sizeof(bsr_state
));
3679 json
= json_object_new_object();
3680 json_object_string_add(json
, "bsr", bsr_str
);
3681 json_object_int_add(json
, "priority",
3682 pim
->global_scope
.current_bsr_prio
);
3683 json_object_int_add(json
, "fragment_tag",
3684 pim
->global_scope
.bsm_frag_tag
);
3685 json_object_string_add(json
, "state", bsr_state
);
3686 json_object_string_add(json
, "upTime", uptime
);
3687 json_object_string_add(json
, "last_bsm_seen", last_bsm_seen
);
3691 vty_out(vty
, "Current preferred BSR address: %s\n", bsr_str
);
3693 "Priority Fragment-Tag State UpTime\n");
3694 vty_out(vty
, " %-12d %-12d %-13s %7s\n",
3695 pim
->global_scope
.current_bsr_prio
,
3696 pim
->global_scope
.bsm_frag_tag
,
3699 vty_out(vty
, "Last BSM seen: %s\n", last_bsm_seen
);
3703 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3704 json
, JSON_C_TO_STRING_PRETTY
));
3705 json_object_free(json
);
3709 static void clear_igmp_interfaces(struct pim_instance
*pim
)
3711 struct interface
*ifp
;
3713 FOR_ALL_INTERFACES (pim
->vrf
, ifp
)
3714 pim_if_addr_del_all_igmp(ifp
);
3716 FOR_ALL_INTERFACES (pim
->vrf
, ifp
)
3717 pim_if_addr_add_all(ifp
);
3720 static void clear_pim_interfaces(struct pim_instance
*pim
)
3722 struct interface
*ifp
;
3724 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3726 pim_neighbor_delete_all(ifp
, "interface cleared");
3731 static void clear_interfaces(struct pim_instance
*pim
)
3733 clear_igmp_interfaces(pim
);
3734 clear_pim_interfaces(pim
);
3737 #define PIM_GET_PIM_INTERFACE(pim_ifp, ifp) \
3738 pim_ifp = ifp->info; \
3741 "%% Enable PIM and/or IGMP on this interface first\n"); \
3742 return CMD_WARNING_CONFIG_FAILED; \
3745 DEFUN (clear_ip_interfaces
,
3746 clear_ip_interfaces_cmd
,
3747 "clear ip interfaces [vrf NAME]",
3750 "Reset interfaces\n"
3754 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3759 clear_interfaces(vrf
->info
);
3764 DEFUN (clear_ip_igmp_interfaces
,
3765 clear_ip_igmp_interfaces_cmd
,
3766 "clear ip igmp [vrf NAME] interfaces",
3771 "Reset IGMP interfaces\n")
3774 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3779 clear_igmp_interfaces(vrf
->info
);
3784 DEFUN (clear_ip_pim_statistics
,
3785 clear_ip_pim_statistics_cmd
,
3786 "clear ip pim statistics [vrf NAME]",
3791 "Reset PIM statistics\n")
3794 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3799 clear_pim_statistics(vrf
->info
);
3803 static void clear_mroute(struct pim_instance
*pim
)
3805 struct pim_upstream
*up
;
3806 struct interface
*ifp
;
3808 /* scan interfaces */
3809 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3810 struct pim_interface
*pim_ifp
= ifp
->info
;
3811 struct listnode
*sock_node
;
3812 struct igmp_sock
*igmp
;
3813 struct pim_ifchannel
*ch
;
3818 /* deleting all ifchannels */
3819 while (!RB_EMPTY(pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
)) {
3820 ch
= RB_ROOT(pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
);
3822 pim_ifchannel_delete(ch
);
3825 /* clean up all igmp groups */
3826 /* scan igmp sockets */
3827 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3830 struct igmp_group
*grp
;
3832 if (igmp
->igmp_group_list
) {
3833 while (igmp
->igmp_group_list
->count
) {
3834 grp
= listnode_head(
3835 igmp
->igmp_group_list
);
3836 igmp_group_delete(grp
);
3843 /* clean up all upstreams*/
3844 if (pim
->upstream_list
) {
3845 while (pim
->upstream_list
->count
) {
3846 up
= listnode_head(pim
->upstream_list
);
3847 pim_upstream_del(pim
, up
, __PRETTY_FUNCTION__
);
3852 DEFUN (clear_ip_mroute
,
3853 clear_ip_mroute_cmd
,
3854 "clear ip mroute [vrf NAME]",
3857 "Reset multicast routes\n"
3861 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3866 clear_mroute(vrf
->info
);
3871 DEFUN (clear_ip_pim_interfaces
,
3872 clear_ip_pim_interfaces_cmd
,
3873 "clear ip pim [vrf NAME] interfaces",
3878 "Reset PIM interfaces\n")
3881 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3886 clear_pim_interfaces(vrf
->info
);
3891 DEFUN (clear_ip_pim_interface_traffic
,
3892 clear_ip_pim_interface_traffic_cmd
,
3893 "clear ip pim [vrf NAME] interface traffic",
3896 "PIM clear commands\n"
3898 "Reset PIM interfaces\n"
3899 "Reset Protocol Packet counters\n")
3902 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3903 struct interface
*ifp
= NULL
;
3904 struct pim_interface
*pim_ifp
= NULL
;
3909 FOR_ALL_INTERFACES (vrf
, ifp
) {
3910 pim_ifp
= ifp
->info
;
3915 pim_ifp
->pim_ifstat_hello_recv
= 0;
3916 pim_ifp
->pim_ifstat_hello_sent
= 0;
3917 pim_ifp
->pim_ifstat_join_recv
= 0;
3918 pim_ifp
->pim_ifstat_join_send
= 0;
3919 pim_ifp
->pim_ifstat_prune_recv
= 0;
3920 pim_ifp
->pim_ifstat_prune_send
= 0;
3921 pim_ifp
->pim_ifstat_reg_recv
= 0;
3922 pim_ifp
->pim_ifstat_reg_send
= 0;
3923 pim_ifp
->pim_ifstat_reg_stop_recv
= 0;
3924 pim_ifp
->pim_ifstat_reg_stop_send
= 0;
3925 pim_ifp
->pim_ifstat_assert_recv
= 0;
3926 pim_ifp
->pim_ifstat_assert_send
= 0;
3927 pim_ifp
->pim_ifstat_bsm_rx
= 0;
3928 pim_ifp
->pim_ifstat_bsm_tx
= 0;
3934 DEFUN (clear_ip_pim_oil
,
3935 clear_ip_pim_oil_cmd
,
3936 "clear ip pim [vrf NAME] oil",
3941 "Rescan PIM OIL (output interface list)\n")
3944 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3949 pim_scan_oil(vrf
->info
);
3954 DEFUN (show_ip_igmp_interface
,
3955 show_ip_igmp_interface_cmd
,
3956 "show ip igmp [vrf NAME] interface [detail|WORD] [json]",
3961 "IGMP interface information\n"
3967 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3968 bool uj
= use_json(argc
, argv
);
3973 if (argv_find(argv
, argc
, "detail", &idx
)
3974 || argv_find(argv
, argc
, "WORD", &idx
))
3975 igmp_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
3977 igmp_show_interfaces(vrf
->info
, vty
, uj
);
3982 DEFUN (show_ip_igmp_interface_vrf_all
,
3983 show_ip_igmp_interface_vrf_all_cmd
,
3984 "show ip igmp vrf all interface [detail|WORD] [json]",
3989 "IGMP interface information\n"
3995 bool uj
= use_json(argc
, argv
);
4001 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4005 vty_out(vty
, " \"%s\": ", vrf
->name
);
4008 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4009 if (argv_find(argv
, argc
, "detail", &idx
)
4010 || argv_find(argv
, argc
, "WORD", &idx
))
4011 igmp_show_interfaces_single(vrf
->info
, vty
,
4012 argv
[idx
]->arg
, uj
);
4014 igmp_show_interfaces(vrf
->info
, vty
, uj
);
4017 vty_out(vty
, "}\n");
4022 DEFUN (show_ip_igmp_join
,
4023 show_ip_igmp_join_cmd
,
4024 "show ip igmp [vrf NAME] join",
4029 "IGMP static join information\n")
4032 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4037 igmp_show_interface_join(vrf
->info
, vty
);
4042 DEFUN (show_ip_igmp_join_vrf_all
,
4043 show_ip_igmp_join_vrf_all_cmd
,
4044 "show ip igmp vrf all join",
4049 "IGMP static join information\n")
4051 bool uj
= use_json(argc
, argv
);
4057 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4061 vty_out(vty
, " \"%s\": ", vrf
->name
);
4064 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4065 igmp_show_interface_join(vrf
->info
, vty
);
4068 vty_out(vty
, "}\n");
4073 DEFUN (show_ip_igmp_groups
,
4074 show_ip_igmp_groups_cmd
,
4075 "show ip igmp [vrf NAME] groups [json]",
4084 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4085 bool uj
= use_json(argc
, argv
);
4090 igmp_show_groups(vrf
->info
, vty
, uj
);
4095 DEFUN (show_ip_igmp_groups_vrf_all
,
4096 show_ip_igmp_groups_vrf_all_cmd
,
4097 "show ip igmp vrf all groups [json]",
4105 bool uj
= use_json(argc
, argv
);
4111 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4115 vty_out(vty
, " \"%s\": ", vrf
->name
);
4118 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4119 igmp_show_groups(vrf
->info
, vty
, uj
);
4122 vty_out(vty
, "}\n");
4127 DEFUN (show_ip_igmp_groups_retransmissions
,
4128 show_ip_igmp_groups_retransmissions_cmd
,
4129 "show ip igmp [vrf NAME] groups retransmissions",
4135 "IGMP group retransmissions\n")
4138 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4143 igmp_show_group_retransmission(vrf
->info
, vty
);
4148 DEFUN (show_ip_igmp_sources
,
4149 show_ip_igmp_sources_cmd
,
4150 "show ip igmp [vrf NAME] sources",
4158 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4163 igmp_show_sources(vrf
->info
, vty
);
4168 DEFUN (show_ip_igmp_sources_retransmissions
,
4169 show_ip_igmp_sources_retransmissions_cmd
,
4170 "show ip igmp [vrf NAME] sources retransmissions",
4176 "IGMP source retransmissions\n")
4179 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4184 igmp_show_source_retransmission(vrf
->info
, vty
);
4189 DEFUN (show_ip_igmp_statistics
,
4190 show_ip_igmp_statistics_cmd
,
4191 "show ip igmp [vrf NAME] statistics [interface WORD] [json]",
4202 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4203 bool uj
= use_json(argc
, argv
);
4208 if (argv_find(argv
, argc
, "WORD", &idx
))
4209 igmp_show_statistics(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
4211 igmp_show_statistics(vrf
->info
, vty
, NULL
, uj
);
4216 DEFUN (show_ip_pim_assert
,
4217 show_ip_pim_assert_cmd
,
4218 "show ip pim [vrf NAME] assert",
4223 "PIM interface assert\n")
4226 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4231 pim_show_assert(vrf
->info
, vty
);
4236 DEFUN (show_ip_pim_assert_internal
,
4237 show_ip_pim_assert_internal_cmd
,
4238 "show ip pim [vrf NAME] assert-internal",
4243 "PIM interface internal assert state\n")
4246 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4251 pim_show_assert_internal(vrf
->info
, vty
);
4256 DEFUN (show_ip_pim_assert_metric
,
4257 show_ip_pim_assert_metric_cmd
,
4258 "show ip pim [vrf NAME] assert-metric",
4263 "PIM interface assert metric\n")
4266 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4271 pim_show_assert_metric(vrf
->info
, vty
);
4276 DEFUN (show_ip_pim_assert_winner_metric
,
4277 show_ip_pim_assert_winner_metric_cmd
,
4278 "show ip pim [vrf NAME] assert-winner-metric",
4283 "PIM interface assert winner metric\n")
4286 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4291 pim_show_assert_winner_metric(vrf
->info
, vty
);
4296 DEFUN (show_ip_pim_interface
,
4297 show_ip_pim_interface_cmd
,
4298 "show ip pim [vrf NAME] interface [detail|WORD] [json]",
4303 "PIM interface information\n"
4309 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4310 bool uj
= use_json(argc
, argv
);
4315 if (argv_find(argv
, argc
, "WORD", &idx
)
4316 || argv_find(argv
, argc
, "detail", &idx
))
4317 pim_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
4319 pim_show_interfaces(vrf
->info
, vty
, uj
);
4324 DEFUN (show_ip_pim_interface_vrf_all
,
4325 show_ip_pim_interface_vrf_all_cmd
,
4326 "show ip pim vrf all interface [detail|WORD] [json]",
4331 "PIM interface information\n"
4337 bool uj
= use_json(argc
, argv
);
4343 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4347 vty_out(vty
, " \"%s\": ", vrf
->name
);
4350 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4351 if (argv_find(argv
, argc
, "WORD", &idx
)
4352 || argv_find(argv
, argc
, "detail", &idx
))
4353 pim_show_interfaces_single(vrf
->info
, vty
,
4354 argv
[idx
]->arg
, uj
);
4356 pim_show_interfaces(vrf
->info
, vty
, uj
);
4359 vty_out(vty
, "}\n");
4364 DEFPY (show_ip_pim_join
,
4365 show_ip_pim_join_cmd
,
4366 "show ip pim [vrf NAME] join [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
4371 "PIM interface join information\n"
4372 "The Source or Group\n"
4376 struct prefix_sg sg
= {0};
4379 struct pim_instance
*pim
;
4381 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
4384 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
4387 pim
= pim_get_pim_instance(v
->vrf_id
);
4390 vty_out(vty
, "%% Unable to find pim instance\n");
4394 if (s_or_g
.s_addr
!= 0) {
4395 if (g
.s_addr
!= 0) {
4402 pim_show_join(pim
, vty
, &sg
, uj
);
4407 DEFUN (show_ip_pim_join_vrf_all
,
4408 show_ip_pim_join_vrf_all_cmd
,
4409 "show ip pim vrf all join [json]",
4414 "PIM interface join information\n"
4417 struct prefix_sg sg
= {0};
4418 bool uj
= use_json(argc
, argv
);
4424 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4428 vty_out(vty
, " \"%s\": ", vrf
->name
);
4431 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4432 pim_show_join(vrf
->info
, vty
, &sg
, uj
);
4435 vty_out(vty
, "}\n");
4440 DEFUN (show_ip_pim_local_membership
,
4441 show_ip_pim_local_membership_cmd
,
4442 "show ip pim [vrf NAME] local-membership [json]",
4447 "PIM interface local-membership\n"
4451 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4452 bool uj
= use_json(argc
, argv
);
4457 pim_show_membership(vrf
->info
, vty
, uj
);
4462 DEFUN (show_ip_pim_neighbor
,
4463 show_ip_pim_neighbor_cmd
,
4464 "show ip pim [vrf NAME] neighbor [detail|WORD] [json]",
4469 "PIM neighbor information\n"
4471 "Name of interface or neighbor\n"
4475 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4476 bool uj
= use_json(argc
, argv
);
4481 if (argv_find(argv
, argc
, "detail", &idx
)
4482 || argv_find(argv
, argc
, "WORD", &idx
))
4483 pim_show_neighbors_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
4485 pim_show_neighbors(vrf
->info
, vty
, uj
);
4490 DEFUN (show_ip_pim_neighbor_vrf_all
,
4491 show_ip_pim_neighbor_vrf_all_cmd
,
4492 "show ip pim vrf all neighbor [detail|WORD] [json]",
4497 "PIM neighbor information\n"
4499 "Name of interface or neighbor\n"
4503 bool uj
= use_json(argc
, argv
);
4509 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4513 vty_out(vty
, " \"%s\": ", vrf
->name
);
4516 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4517 if (argv_find(argv
, argc
, "detail", &idx
)
4518 || argv_find(argv
, argc
, "WORD", &idx
))
4519 pim_show_neighbors_single(vrf
->info
, vty
,
4520 argv
[idx
]->arg
, uj
);
4522 pim_show_neighbors(vrf
->info
, vty
, uj
);
4525 vty_out(vty
, "}\n");
4530 DEFUN (show_ip_pim_secondary
,
4531 show_ip_pim_secondary_cmd
,
4532 "show ip pim [vrf NAME] secondary",
4537 "PIM neighbor addresses\n")
4540 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4545 pim_show_neighbors_secondary(vrf
->info
, vty
);
4550 DEFUN (show_ip_pim_state
,
4551 show_ip_pim_state_cmd
,
4552 "show ip pim [vrf NAME] state [A.B.C.D [A.B.C.D]] [json]",
4557 "PIM state information\n"
4558 "Unicast or Multicast address\n"
4559 "Multicast address\n"
4562 const char *src_or_group
= NULL
;
4563 const char *group
= NULL
;
4565 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4566 bool uj
= use_json(argc
, argv
);
4574 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
4575 src_or_group
= argv
[idx
]->arg
;
4577 group
= argv
[idx
+ 1]->arg
;
4580 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
4585 DEFUN (show_ip_pim_state_vrf_all
,
4586 show_ip_pim_state_vrf_all_cmd
,
4587 "show ip pim vrf all state [A.B.C.D [A.B.C.D]] [json]",
4592 "PIM state information\n"
4593 "Unicast or Multicast address\n"
4594 "Multicast address\n"
4597 const char *src_or_group
= NULL
;
4598 const char *group
= NULL
;
4600 bool uj
= use_json(argc
, argv
);
4609 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
4610 src_or_group
= argv
[idx
]->arg
;
4612 group
= argv
[idx
+ 1]->arg
;
4615 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4619 vty_out(vty
, " \"%s\": ", vrf
->name
);
4622 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4623 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
4626 vty_out(vty
, "}\n");
4631 DEFPY (show_ip_pim_upstream
,
4632 show_ip_pim_upstream_cmd
,
4633 "show ip pim [vrf NAME] upstream [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
4638 "PIM upstream information\n"
4639 "The Source or Group\n"
4643 struct prefix_sg sg
= {0};
4646 struct pim_instance
*pim
;
4648 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
4651 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
4654 pim
= pim_get_pim_instance(v
->vrf_id
);
4657 vty_out(vty
, "%% Unable to find pim instance\n");
4661 if (s_or_g
.s_addr
!= 0) {
4662 if (g
.s_addr
!= 0) {
4668 pim_show_upstream(pim
, vty
, &sg
, uj
);
4673 DEFUN (show_ip_pim_upstream_vrf_all
,
4674 show_ip_pim_upstream_vrf_all_cmd
,
4675 "show ip pim vrf all upstream [json]",
4680 "PIM upstream information\n"
4683 struct prefix_sg sg
= {0};
4684 bool uj
= use_json(argc
, argv
);
4690 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4694 vty_out(vty
, " \"%s\": ", vrf
->name
);
4697 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4698 pim_show_upstream(vrf
->info
, vty
, &sg
, uj
);
4704 DEFUN (show_ip_pim_upstream_join_desired
,
4705 show_ip_pim_upstream_join_desired_cmd
,
4706 "show ip pim [vrf NAME] upstream-join-desired [json]",
4711 "PIM upstream join-desired\n"
4715 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4716 bool uj
= use_json(argc
, argv
);
4721 pim_show_join_desired(vrf
->info
, vty
, uj
);
4726 DEFUN (show_ip_pim_upstream_rpf
,
4727 show_ip_pim_upstream_rpf_cmd
,
4728 "show ip pim [vrf NAME] upstream-rpf [json]",
4733 "PIM upstream source rpf\n"
4737 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4738 bool uj
= use_json(argc
, argv
);
4743 pim_show_upstream_rpf(vrf
->info
, vty
, uj
);
4748 DEFUN (show_ip_pim_rp
,
4750 "show ip pim [vrf NAME] rp-info [json]",
4755 "PIM RP information\n"
4759 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4760 bool uj
= use_json(argc
, argv
);
4765 pim_rp_show_information(vrf
->info
, vty
, uj
);
4770 DEFUN (show_ip_pim_rp_vrf_all
,
4771 show_ip_pim_rp_vrf_all_cmd
,
4772 "show ip pim vrf all rp-info [json]",
4777 "PIM RP information\n"
4780 bool uj
= use_json(argc
, argv
);
4786 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4790 vty_out(vty
, " \"%s\": ", vrf
->name
);
4793 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4794 pim_rp_show_information(vrf
->info
, vty
, uj
);
4797 vty_out(vty
, "}\n");
4802 DEFUN (show_ip_pim_rpf
,
4803 show_ip_pim_rpf_cmd
,
4804 "show ip pim [vrf NAME] rpf [json]",
4809 "PIM cached source rpf information\n"
4813 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4814 bool uj
= use_json(argc
, argv
);
4819 pim_show_rpf(vrf
->info
, vty
, uj
);
4824 DEFUN (show_ip_pim_rpf_vrf_all
,
4825 show_ip_pim_rpf_vrf_all_cmd
,
4826 "show ip pim vrf all rpf [json]",
4831 "PIM cached source rpf information\n"
4834 bool uj
= use_json(argc
, argv
);
4840 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4844 vty_out(vty
, " \"%s\": ", vrf
->name
);
4847 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4848 pim_show_rpf(vrf
->info
, vty
, uj
);
4851 vty_out(vty
, "}\n");
4856 DEFUN (show_ip_pim_nexthop
,
4857 show_ip_pim_nexthop_cmd
,
4858 "show ip pim [vrf NAME] nexthop",
4863 "PIM cached nexthop rpf information\n")
4866 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4871 pim_show_nexthop(vrf
->info
, vty
);
4876 DEFUN (show_ip_pim_nexthop_lookup
,
4877 show_ip_pim_nexthop_lookup_cmd
,
4878 "show ip pim [vrf NAME] nexthop-lookup A.B.C.D A.B.C.D",
4883 "PIM cached nexthop rpf lookup\n"
4884 "Source/RP address\n"
4885 "Multicast Group address\n")
4887 struct prefix nht_p
;
4889 struct in_addr src_addr
, grp_addr
;
4890 struct in_addr vif_source
;
4891 const char *addr_str
, *addr_str1
;
4893 struct pim_nexthop nexthop
;
4894 char nexthop_addr_str
[PREFIX_STRLEN
];
4895 char grp_str
[PREFIX_STRLEN
];
4897 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4902 argv_find(argv
, argc
, "A.B.C.D", &idx
);
4903 addr_str
= argv
[idx
]->arg
;
4904 result
= inet_pton(AF_INET
, addr_str
, &src_addr
);
4906 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
4907 errno
, safe_strerror(errno
));
4911 if (pim_is_group_224_4(src_addr
)) {
4913 "Invalid argument. Expected Valid Source Address.\n");
4917 addr_str1
= argv
[idx
+ 1]->arg
;
4918 result
= inet_pton(AF_INET
, addr_str1
, &grp_addr
);
4920 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
4921 errno
, safe_strerror(errno
));
4925 if (!pim_is_group_224_4(grp_addr
)) {
4927 "Invalid argument. Expected Valid Multicast Group Address.\n");
4931 if (!pim_rp_set_upstream_addr(vrf
->info
, &vif_source
, src_addr
,
4935 nht_p
.family
= AF_INET
;
4936 nht_p
.prefixlen
= IPV4_MAX_BITLEN
;
4937 nht_p
.u
.prefix4
= vif_source
;
4938 grp
.family
= AF_INET
;
4939 grp
.prefixlen
= IPV4_MAX_BITLEN
;
4940 grp
.u
.prefix4
= grp_addr
;
4941 memset(&nexthop
, 0, sizeof(nexthop
));
4943 result
= pim_ecmp_nexthop_lookup(vrf
->info
, &nexthop
, &nht_p
, &grp
, 0);
4947 "Nexthop Lookup failed, no usable routes returned.\n");
4951 pim_addr_dump("<grp?>", &grp
, grp_str
, sizeof(grp_str
));
4952 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
4953 nexthop_addr_str
, sizeof(nexthop_addr_str
));
4954 vty_out(vty
, "Group %s --- Nexthop %s Interface %s \n", grp_str
,
4955 nexthop_addr_str
, nexthop
.interface
->name
);
4960 DEFUN (show_ip_pim_interface_traffic
,
4961 show_ip_pim_interface_traffic_cmd
,
4962 "show ip pim [vrf NAME] interface traffic [WORD] [json]",
4967 "PIM interface information\n"
4968 "Protocol Packet counters\n"
4973 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4974 bool uj
= use_json(argc
, argv
);
4979 if (argv_find(argv
, argc
, "WORD", &idx
))
4980 pim_show_interface_traffic_single(vrf
->info
, vty
,
4981 argv
[idx
]->arg
, uj
);
4983 pim_show_interface_traffic(vrf
->info
, vty
, uj
);
4988 DEFUN (show_ip_pim_bsm_db
,
4989 show_ip_pim_bsm_db_cmd
,
4990 "show ip pim bsm-database [vrf NAME] [json]",
4995 "PIM cached bsm packets information\n"
4999 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5000 bool uj
= use_json(argc
, argv
);
5005 pim_show_bsm_db(vrf
->info
, vty
, uj
);
5009 DEFUN (show_ip_pim_bsrp
,
5010 show_ip_pim_bsrp_cmd
,
5011 "show ip pim bsrp-info [vrf NAME] [json]",
5016 "PIM cached group-rp mappings information\n"
5020 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5021 bool uj
= use_json(argc
, argv
);
5026 pim_show_group_rp_mappings_info(vrf
->info
, vty
, uj
);
5031 DEFUN (show_ip_pim_statistics
,
5032 show_ip_pim_statistics_cmd
,
5033 "show ip pim [vrf NAME] statistics [interface WORD] [json]",
5044 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5045 bool uj
= use_json(argc
, argv
);
5050 if (argv_find(argv
, argc
, "WORD", &idx
))
5051 pim_show_statistics(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
5053 pim_show_statistics(vrf
->info
, vty
, NULL
, uj
);
5058 static void show_multicast_interfaces(struct pim_instance
*pim
, struct vty
*vty
)
5060 struct interface
*ifp
;
5065 "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut\n");
5067 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
5068 struct pim_interface
*pim_ifp
;
5069 struct in_addr ifaddr
;
5070 struct sioc_vif_req vreq
;
5072 pim_ifp
= ifp
->info
;
5077 memset(&vreq
, 0, sizeof(vreq
));
5078 vreq
.vifi
= pim_ifp
->mroute_vif_index
;
5080 if (ioctl(pim
->mroute_socket
, SIOCGETVIFCNT
, &vreq
)) {
5082 "ioctl(SIOCGETVIFCNT=%lu) failure for interface %s vif_index=%d: errno=%d: %s",
5083 (unsigned long)SIOCGETVIFCNT
, ifp
->name
,
5084 pim_ifp
->mroute_vif_index
, errno
,
5085 safe_strerror(errno
));
5088 ifaddr
= pim_ifp
->primary_address
;
5090 vty_out(vty
, "%-16s %-15s %3d %3d %7lu %7lu %10lu %10lu\n",
5091 ifp
->name
, inet_ntoa(ifaddr
), ifp
->ifindex
,
5092 pim_ifp
->mroute_vif_index
, (unsigned long)vreq
.icount
,
5093 (unsigned long)vreq
.ocount
, (unsigned long)vreq
.ibytes
,
5094 (unsigned long)vreq
.obytes
);
5098 static void pim_cmd_show_ip_multicast_helper(struct pim_instance
*pim
,
5101 struct vrf
*vrf
= pim
->vrf
;
5102 time_t now
= pim_time_monotonic_sec();
5108 vty_out(vty
, "Router MLAG Role: %s\n",
5109 mlag_role2str(router
->role
, mlag_role
, sizeof(mlag_role
)));
5110 vty_out(vty
, "Mroute socket descriptor:");
5112 vty_out(vty
, " %d(%s)\n", pim
->mroute_socket
, vrf
->name
);
5114 pim_time_uptime(uptime
, sizeof(uptime
),
5115 now
- pim
->mroute_socket_creation
);
5116 vty_out(vty
, "Mroute socket uptime: %s\n", uptime
);
5120 pim_zebra_zclient_update(vty
);
5121 pim_zlookup_show_ip_multicast(vty
);
5124 vty_out(vty
, "Maximum highest VifIndex: %d\n", PIM_MAX_USABLE_VIFS
);
5127 vty_out(vty
, "Upstream Join Timer: %d secs\n", router
->t_periodic
);
5128 vty_out(vty
, "Join/Prune Holdtime: %d secs\n", PIM_JP_HOLDTIME
);
5129 vty_out(vty
, "PIM ECMP: %s\n", pim
->ecmp_enable
? "Enable" : "Disable");
5130 vty_out(vty
, "PIM ECMP Rebalance: %s\n",
5131 pim
->ecmp_rebalance_enable
? "Enable" : "Disable");
5135 show_rpf_refresh_stats(vty
, pim
, now
, NULL
);
5139 show_scan_oil_stats(pim
, vty
, now
);
5141 show_multicast_interfaces(pim
, vty
);
5144 DEFUN (show_ip_multicast
,
5145 show_ip_multicast_cmd
,
5146 "show ip multicast [vrf NAME]",
5150 "Multicast global information\n")
5153 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5158 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
5163 DEFUN (show_ip_multicast_vrf_all
,
5164 show_ip_multicast_vrf_all_cmd
,
5165 "show ip multicast vrf all",
5169 "Multicast global information\n")
5171 bool uj
= use_json(argc
, argv
);
5177 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5181 vty_out(vty
, " \"%s\": ", vrf
->name
);
5184 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5185 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
5188 vty_out(vty
, "}\n");
5193 static void show_mroute(struct pim_instance
*pim
, struct vty
*vty
,
5194 struct prefix_sg
*sg
, bool fill
, bool uj
)
5196 struct listnode
*node
;
5197 struct channel_oil
*c_oil
;
5198 struct static_route
*s_route
;
5200 json_object
*json
= NULL
;
5201 json_object
*json_group
= NULL
;
5202 json_object
*json_source
= NULL
;
5203 json_object
*json_oil
= NULL
;
5204 json_object
*json_ifp_out
= NULL
;
5207 char grp_str
[INET_ADDRSTRLEN
];
5208 char src_str
[INET_ADDRSTRLEN
];
5209 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
5210 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
5212 struct interface
*ifp_in
;
5216 json
= json_object_new_object();
5219 "Source Group Proto Input Output TTL Uptime\n");
5222 now
= pim_time_monotonic_sec();
5224 /* print list of PIM and IGMP routes */
5225 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
5228 if (!c_oil
->installed
&& !uj
)
5231 if (sg
->grp
.s_addr
!= 0 &&
5232 sg
->grp
.s_addr
!= c_oil
->oil
.mfcc_mcastgrp
.s_addr
)
5234 if (sg
->src
.s_addr
!= 0 &&
5235 sg
->src
.s_addr
!= c_oil
->oil
.mfcc_origin
.s_addr
)
5238 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
5240 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
5242 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
5245 strlcpy(in_ifname
, ifp_in
->name
, sizeof(in_ifname
));
5247 strlcpy(in_ifname
, "<iif?>", sizeof(in_ifname
));
5251 /* Find the group, create it if it doesn't exist */
5252 json_object_object_get_ex(json
, grp_str
, &json_group
);
5255 json_group
= json_object_new_object();
5256 json_object_object_add(json
, grp_str
,
5260 /* Find the source nested under the group, create it if
5261 * it doesn't exist */
5262 json_object_object_get_ex(json_group
, src_str
,
5266 json_source
= json_object_new_object();
5267 json_object_object_add(json_group
, src_str
,
5271 /* Find the inbound interface nested under the source,
5272 * create it if it doesn't exist */
5273 json_object_int_add(json_source
, "installed",
5275 json_object_int_add(json_source
, "refCount",
5276 c_oil
->oil_ref_count
);
5277 json_object_int_add(json_source
, "oilSize",
5279 json_object_int_add(json_source
, "OilInheritedRescan",
5280 c_oil
->oil_inherited_rescan
);
5281 json_object_string_add(json_source
, "iif", in_ifname
);
5285 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
5287 struct interface
*ifp_out
;
5288 char mroute_uptime
[10];
5291 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
5295 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
5297 mroute_uptime
, sizeof(mroute_uptime
),
5298 now
- c_oil
->mroute_creation
);
5302 strlcpy(out_ifname
, ifp_out
->name
, sizeof(out_ifname
));
5304 strlcpy(out_ifname
, "<oif?>", sizeof(out_ifname
));
5307 json_ifp_out
= json_object_new_object();
5308 json_object_string_add(json_ifp_out
, "source",
5310 json_object_string_add(json_ifp_out
, "group",
5313 if (c_oil
->oif_flags
[oif_vif_index
]
5314 & PIM_OIF_FLAG_PROTO_PIM
)
5315 json_object_boolean_true_add(
5316 json_ifp_out
, "protocolPim");
5318 if (c_oil
->oif_flags
[oif_vif_index
]
5319 & PIM_OIF_FLAG_PROTO_IGMP
)
5320 json_object_boolean_true_add(
5321 json_ifp_out
, "protocolIgmp");
5323 if (c_oil
->oif_flags
[oif_vif_index
]
5324 & PIM_OIF_FLAG_PROTO_VXLAN
)
5325 json_object_boolean_true_add(
5326 json_ifp_out
, "protocolVxlan");
5328 if (c_oil
->oif_flags
[oif_vif_index
]
5329 & PIM_OIF_FLAG_PROTO_STAR
)
5330 json_object_boolean_true_add(
5332 "protocolInherited");
5334 json_object_string_add(json_ifp_out
,
5337 json_object_int_add(json_ifp_out
, "iVifI",
5338 c_oil
->oil
.mfcc_parent
);
5339 json_object_string_add(json_ifp_out
,
5340 "outboundInterface",
5342 json_object_int_add(json_ifp_out
, "oVifI",
5344 json_object_int_add(json_ifp_out
, "ttl", ttl
);
5345 json_object_string_add(json_ifp_out
, "upTime",
5348 json_oil
= json_object_new_object();
5349 json_object_object_add(json_source
,
5352 json_object_object_add(json_oil
, out_ifname
,
5355 if (c_oil
->oif_flags
[oif_vif_index
]
5356 & PIM_OIF_FLAG_PROTO_PIM
) {
5357 strlcpy(proto
, "PIM", sizeof(proto
));
5360 if (c_oil
->oif_flags
[oif_vif_index
]
5361 & PIM_OIF_FLAG_PROTO_IGMP
) {
5362 strlcpy(proto
, "IGMP", sizeof(proto
));
5365 if (c_oil
->oif_flags
[oif_vif_index
]
5366 & PIM_OIF_FLAG_PROTO_VXLAN
) {
5367 strlcpy(proto
, "VxLAN", sizeof(proto
));
5370 if (c_oil
->oif_flags
[oif_vif_index
]
5371 & PIM_OIF_FLAG_PROTO_STAR
) {
5372 strlcpy(proto
, "STAR", sizeof(proto
));
5376 "%-15s %-15s %-6s %-16s %-16s %-3d %8s\n",
5377 src_str
, grp_str
, proto
, in_ifname
,
5378 out_ifname
, ttl
, mroute_uptime
);
5383 in_ifname
[0] = '\0';
5389 if (!uj
&& !found_oif
) {
5390 vty_out(vty
, "%-15s %-15s %-6s %-16s %-16s %-3d %8s\n",
5391 src_str
, grp_str
, "none", in_ifname
, "none", 0,
5396 /* Print list of static routes */
5397 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
5400 if (!s_route
->c_oil
.installed
)
5403 pim_inet4_dump("<group?>", s_route
->group
, grp_str
,
5405 pim_inet4_dump("<source?>", s_route
->source
, src_str
,
5407 ifp_in
= pim_if_find_by_vif_index(pim
, s_route
->iif
);
5411 strlcpy(in_ifname
, ifp_in
->name
, sizeof(in_ifname
));
5413 strlcpy(in_ifname
, "<iif?>", sizeof(in_ifname
));
5417 /* Find the group, create it if it doesn't exist */
5418 json_object_object_get_ex(json
, grp_str
, &json_group
);
5421 json_group
= json_object_new_object();
5422 json_object_object_add(json
, grp_str
,
5426 /* Find the source nested under the group, create it if
5427 * it doesn't exist */
5428 json_object_object_get_ex(json_group
, src_str
,
5432 json_source
= json_object_new_object();
5433 json_object_object_add(json_group
, src_str
,
5437 json_object_string_add(json_source
, "iif", in_ifname
);
5440 strlcpy(proto
, "STATIC", sizeof(proto
));
5443 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
5445 struct interface
*ifp_out
;
5446 char oif_uptime
[10];
5449 ttl
= s_route
->oif_ttls
[oif_vif_index
];
5453 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
5455 oif_uptime
, sizeof(oif_uptime
),
5458 .oif_creation
[oif_vif_index
]);
5462 strlcpy(out_ifname
, ifp_out
->name
, sizeof(out_ifname
));
5464 strlcpy(out_ifname
, "<oif?>", sizeof(out_ifname
));
5467 json_ifp_out
= json_object_new_object();
5468 json_object_string_add(json_ifp_out
, "source",
5470 json_object_string_add(json_ifp_out
, "group",
5472 json_object_boolean_true_add(json_ifp_out
,
5474 json_object_string_add(json_ifp_out
,
5477 json_object_int_add(
5478 json_ifp_out
, "iVifI",
5479 s_route
->c_oil
.oil
.mfcc_parent
);
5480 json_object_string_add(json_ifp_out
,
5481 "outboundInterface",
5483 json_object_int_add(json_ifp_out
, "oVifI",
5485 json_object_int_add(json_ifp_out
, "ttl", ttl
);
5486 json_object_string_add(json_ifp_out
, "upTime",
5489 json_oil
= json_object_new_object();
5490 json_object_object_add(json_source
,
5493 json_object_object_add(json_oil
, out_ifname
,
5497 "%-15s %-15s %-6s %-16s %-16s %-3d %8s %s\n",
5498 src_str
, grp_str
, proto
, in_ifname
,
5499 out_ifname
, ttl
, oif_uptime
,
5501 if (first
&& !fill
) {
5504 in_ifname
[0] = '\0';
5510 if (!uj
&& !found_oif
) {
5512 "%-15s %-15s %-6s %-16s %-16s %-3d %8s %s\n",
5513 src_str
, grp_str
, proto
, in_ifname
, "none", 0,
5514 "--:--:--", pim
->vrf
->name
);
5519 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5520 json
, JSON_C_TO_STRING_PRETTY
));
5521 json_object_free(json
);
5525 DEFPY (show_ip_mroute
,
5527 "show ip mroute [vrf NAME] [A.B.C.D$s_or_g [A.B.C.D$g]] [fill$fill] [json$json]",
5532 "The Source or Group\n"
5534 "Fill in Assumed data\n"
5537 struct prefix_sg sg
= {0};
5538 struct pim_instance
*pim
;
5541 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
5544 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
5547 pim
= pim_get_pim_instance(v
->vrf_id
);
5550 vty_out(vty
, "%% Unable to find pim instance\n");
5554 if (s_or_g
.s_addr
!= 0) {
5555 if (g
.s_addr
!= 0) {
5561 show_mroute(pim
, vty
, &sg
, !!fill
, !!json
);
5565 DEFUN (show_ip_mroute_vrf_all
,
5566 show_ip_mroute_vrf_all_cmd
,
5567 "show ip mroute vrf all [fill] [json]",
5572 "Fill in Assumed data\n"
5575 struct prefix_sg sg
= {0};
5576 bool uj
= use_json(argc
, argv
);
5582 if (argv_find(argv
, argc
, "fill", &idx
))
5587 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5591 vty_out(vty
, " \"%s\": ", vrf
->name
);
5594 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5595 show_mroute(vrf
->info
, vty
, &sg
, fill
, uj
);
5598 vty_out(vty
, "}\n");
5603 DEFUN (clear_ip_mroute_count
,
5604 clear_ip_mroute_count_cmd
,
5605 "clear ip mroute [vrf NAME] count",
5610 "Route and packet count data\n")
5613 struct listnode
*node
;
5614 struct channel_oil
*c_oil
;
5615 struct static_route
*sr
;
5616 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5617 struct pim_instance
*pim
;
5623 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
5624 if (!c_oil
->installed
)
5627 pim_mroute_update_counters(c_oil
);
5628 c_oil
->cc
.origpktcnt
= c_oil
->cc
.pktcnt
;
5629 c_oil
->cc
.origbytecnt
= c_oil
->cc
.bytecnt
;
5630 c_oil
->cc
.origwrong_if
= c_oil
->cc
.wrong_if
;
5633 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, sr
)) {
5634 if (!sr
->c_oil
.installed
)
5637 pim_mroute_update_counters(&sr
->c_oil
);
5639 sr
->c_oil
.cc
.origpktcnt
= sr
->c_oil
.cc
.pktcnt
;
5640 sr
->c_oil
.cc
.origbytecnt
= sr
->c_oil
.cc
.bytecnt
;
5641 sr
->c_oil
.cc
.origwrong_if
= sr
->c_oil
.cc
.wrong_if
;
5646 static void show_mroute_count(struct pim_instance
*pim
, struct vty
*vty
)
5648 struct listnode
*node
;
5649 struct channel_oil
*c_oil
;
5650 struct static_route
*sr
;
5655 "Source Group LastUsed Packets Bytes WrongIf \n");
5657 /* Print PIM and IGMP route counts */
5658 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
5659 char group_str
[INET_ADDRSTRLEN
];
5660 char source_str
[INET_ADDRSTRLEN
];
5662 if (!c_oil
->installed
)
5665 pim_mroute_update_counters(c_oil
);
5667 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, group_str
,
5669 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, source_str
,
5670 sizeof(source_str
));
5672 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
5673 source_str
, group_str
, c_oil
->cc
.lastused
/ 100,
5674 c_oil
->cc
.pktcnt
- c_oil
->cc
.origpktcnt
,
5675 c_oil
->cc
.bytecnt
- c_oil
->cc
.origbytecnt
,
5676 c_oil
->cc
.wrong_if
- c_oil
->cc
.origwrong_if
);
5679 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, sr
)) {
5680 char group_str
[INET_ADDRSTRLEN
];
5681 char source_str
[INET_ADDRSTRLEN
];
5683 if (!sr
->c_oil
.installed
)
5686 pim_mroute_update_counters(&sr
->c_oil
);
5688 pim_inet4_dump("<group?>", sr
->c_oil
.oil
.mfcc_mcastgrp
,
5689 group_str
, sizeof(group_str
));
5690 pim_inet4_dump("<source?>", sr
->c_oil
.oil
.mfcc_origin
,
5691 source_str
, sizeof(source_str
));
5693 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
5694 source_str
, group_str
, sr
->c_oil
.cc
.lastused
,
5695 sr
->c_oil
.cc
.pktcnt
- sr
->c_oil
.cc
.origpktcnt
,
5696 sr
->c_oil
.cc
.bytecnt
- sr
->c_oil
.cc
.origbytecnt
,
5697 sr
->c_oil
.cc
.wrong_if
- sr
->c_oil
.cc
.origwrong_if
);
5701 DEFUN (show_ip_mroute_count
,
5702 show_ip_mroute_count_cmd
,
5703 "show ip mroute [vrf NAME] count",
5708 "Route and packet count data\n")
5711 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5716 show_mroute_count(vrf
->info
, vty
);
5720 DEFUN (show_ip_mroute_count_vrf_all
,
5721 show_ip_mroute_count_vrf_all_cmd
,
5722 "show ip mroute vrf all count",
5727 "Route and packet count data\n")
5729 bool uj
= use_json(argc
, argv
);
5735 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5739 vty_out(vty
, " \"%s\": ", vrf
->name
);
5742 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5743 show_mroute_count(vrf
->info
, vty
);
5746 vty_out(vty
, "}\n");
5751 static void show_mroute_summary(struct pim_instance
*pim
, struct vty
*vty
)
5753 struct listnode
*node
;
5754 struct channel_oil
*c_oil
;
5755 struct static_route
*s_route
;
5756 uint32_t starg_sw_mroute_cnt
= 0;
5757 uint32_t sg_sw_mroute_cnt
= 0;
5758 uint32_t starg_hw_mroute_cnt
= 0;
5759 uint32_t sg_hw_mroute_cnt
= 0;
5761 vty_out(vty
, "Mroute Type Installed/Total\n");
5763 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
5764 if (!c_oil
->installed
) {
5765 if (c_oil
->oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
5766 starg_sw_mroute_cnt
++;
5770 if (c_oil
->oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
5771 starg_hw_mroute_cnt
++;
5777 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
5778 if (!s_route
->c_oil
.installed
) {
5779 if (s_route
->c_oil
.oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
5780 starg_sw_mroute_cnt
++;
5784 if (s_route
->c_oil
.oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
5785 starg_hw_mroute_cnt
++;
5791 vty_out(vty
, "%-20s %d/%d\n", "(*, G)", starg_hw_mroute_cnt
,
5792 starg_sw_mroute_cnt
+ starg_hw_mroute_cnt
);
5793 vty_out(vty
, "%-20s %d/%d\n", "(S, G)", sg_hw_mroute_cnt
,
5794 sg_sw_mroute_cnt
+ sg_hw_mroute_cnt
);
5795 vty_out(vty
, "------\n");
5796 vty_out(vty
, "%-20s %d/%d\n", "Total",
5797 (starg_hw_mroute_cnt
+ sg_hw_mroute_cnt
),
5798 (starg_sw_mroute_cnt
+
5799 starg_hw_mroute_cnt
+
5804 DEFUN (show_ip_mroute_summary
,
5805 show_ip_mroute_summary_cmd
,
5806 "show ip mroute [vrf NAME] summary",
5811 "Summary of all mroutes\n")
5814 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5819 show_mroute_summary(vrf
->info
, vty
);
5823 DEFUN (show_ip_mroute_summary_vrf_all
,
5824 show_ip_mroute_summary_vrf_all_cmd
,
5825 "show ip mroute vrf all summary",
5830 "Summary of all mroutes\n")
5834 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5835 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5836 show_mroute_summary(vrf
->info
, vty
);
5844 "show ip rib [vrf NAME] A.B.C.D",
5849 "Unicast address\n")
5852 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5853 struct in_addr addr
;
5854 const char *addr_str
;
5855 struct pim_nexthop nexthop
;
5856 char nexthop_addr_str
[PREFIX_STRLEN
];
5862 memset(&nexthop
, 0, sizeof(nexthop
));
5863 argv_find(argv
, argc
, "A.B.C.D", &idx
);
5864 addr_str
= argv
[idx
]->arg
;
5865 result
= inet_pton(AF_INET
, addr_str
, &addr
);
5867 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
5868 errno
, safe_strerror(errno
));
5872 if (!pim_nexthop_lookup(vrf
->info
, &nexthop
, addr
, 0)) {
5874 "Failure querying RIB nexthop for unicast address %s\n",
5880 "Address NextHop Interface Metric Preference\n");
5882 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
5883 nexthop_addr_str
, sizeof(nexthop_addr_str
));
5885 vty_out(vty
, "%-15s %-15s %-9s %6d %10d\n", addr_str
, nexthop_addr_str
,
5886 nexthop
.interface
? nexthop
.interface
->name
: "<ifname?>",
5887 nexthop
.mrib_route_metric
, nexthop
.mrib_metric_preference
);
5892 static void show_ssmpingd(struct pim_instance
*pim
, struct vty
*vty
)
5894 struct listnode
*node
;
5895 struct ssmpingd_sock
*ss
;
5899 "Source Socket Address Port Uptime Requests\n");
5901 if (!pim
->ssmpingd_list
)
5904 now
= pim_time_monotonic_sec();
5906 for (ALL_LIST_ELEMENTS_RO(pim
->ssmpingd_list
, node
, ss
)) {
5907 char source_str
[INET_ADDRSTRLEN
];
5909 struct sockaddr_in bind_addr
;
5910 socklen_t len
= sizeof(bind_addr
);
5911 char bind_addr_str
[INET_ADDRSTRLEN
];
5913 pim_inet4_dump("<src?>", ss
->source_addr
, source_str
,
5914 sizeof(source_str
));
5916 if (pim_socket_getsockname(
5917 ss
->sock_fd
, (struct sockaddr
*)&bind_addr
, &len
)) {
5919 "%% Failure reading socket name for ssmpingd source %s on fd=%d\n",
5920 source_str
, ss
->sock_fd
);
5923 pim_inet4_dump("<addr?>", bind_addr
.sin_addr
, bind_addr_str
,
5924 sizeof(bind_addr_str
));
5925 pim_time_uptime(ss_uptime
, sizeof(ss_uptime
),
5926 now
- ss
->creation
);
5928 vty_out(vty
, "%-15s %6d %-15s %5d %8s %8lld\n", source_str
,
5929 ss
->sock_fd
, bind_addr_str
, ntohs(bind_addr
.sin_port
),
5930 ss_uptime
, (long long)ss
->requests
);
5934 DEFUN (show_ip_ssmpingd
,
5935 show_ip_ssmpingd_cmd
,
5936 "show ip ssmpingd [vrf NAME]",
5943 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5948 show_ssmpingd(vrf
->info
, vty
);
5952 static int pim_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
5953 const char *rp
, const char *group
,
5958 result
= pim_rp_new_config(pim
, rp
, group
, plist
);
5960 if (result
== PIM_GROUP_BAD_ADDR_MASK_COMBO
) {
5961 vty_out(vty
, "%% Inconsistent address and mask: %s\n",
5963 return CMD_WARNING_CONFIG_FAILED
;
5966 if (result
== PIM_GROUP_BAD_ADDRESS
) {
5967 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
5968 return CMD_WARNING_CONFIG_FAILED
;
5971 if (result
== PIM_RP_BAD_ADDRESS
) {
5972 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
5973 return CMD_WARNING_CONFIG_FAILED
;
5976 if (result
== PIM_RP_NO_PATH
) {
5977 vty_out(vty
, "%% No Path to RP address specified: %s\n", rp
);
5981 if (result
== PIM_GROUP_OVERLAP
) {
5983 "%% Group range specified cannot exact match another\n");
5984 return CMD_WARNING_CONFIG_FAILED
;
5987 if (result
== PIM_GROUP_PFXLIST_OVERLAP
) {
5989 "%% This group is already covered by a RP prefix-list\n");
5990 return CMD_WARNING_CONFIG_FAILED
;
5993 if (result
== PIM_RP_PFXLIST_IN_USE
) {
5995 "%% The same prefix-list cannot be applied to multiple RPs\n");
5996 return CMD_WARNING_CONFIG_FAILED
;
5999 if (result
== PIM_GROUP_BAD_ADDR_MASK_COMBO
) {
6000 vty_out(vty
, "%% Inconsistent address and mask: %s\n",
6002 return CMD_WARNING_CONFIG_FAILED
;
6008 static int pim_cmd_spt_switchover(struct pim_instance
*pim
,
6009 enum pim_spt_switchover spt
,
6012 pim
->spt
.switchover
= spt
;
6014 switch (pim
->spt
.switchover
) {
6015 case PIM_SPT_IMMEDIATE
:
6016 XFREE(MTYPE_PIM_SPT_PLIST_NAME
, pim
->spt
.plist
);
6018 pim_upstream_add_lhr_star_pimreg(pim
);
6020 case PIM_SPT_INFINITY
:
6021 pim_upstream_remove_lhr_star_pimreg(pim
, plist
);
6023 XFREE(MTYPE_PIM_SPT_PLIST_NAME
, pim
->spt
.plist
);
6027 XSTRDUP(MTYPE_PIM_SPT_PLIST_NAME
, plist
);
6034 DEFUN (ip_pim_spt_switchover_infinity
,
6035 ip_pim_spt_switchover_infinity_cmd
,
6036 "ip pim spt-switchover infinity-and-beyond",
6040 "Never switch to SPT Tree\n")
6042 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6043 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, NULL
);
6046 DEFUN (ip_pim_spt_switchover_infinity_plist
,
6047 ip_pim_spt_switchover_infinity_plist_cmd
,
6048 "ip pim spt-switchover infinity-and-beyond prefix-list WORD",
6052 "Never switch to SPT Tree\n"
6053 "Prefix-List to control which groups to switch\n"
6054 "Prefix-List name\n")
6056 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6057 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, argv
[5]->arg
);
6060 DEFUN (no_ip_pim_spt_switchover_infinity
,
6061 no_ip_pim_spt_switchover_infinity_cmd
,
6062 "no ip pim spt-switchover infinity-and-beyond",
6067 "Never switch to SPT Tree\n")
6069 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6070 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
6073 DEFUN (no_ip_pim_spt_switchover_infinity_plist
,
6074 no_ip_pim_spt_switchover_infinity_plist_cmd
,
6075 "no ip pim spt-switchover infinity-and-beyond prefix-list WORD",
6080 "Never switch to SPT Tree\n"
6081 "Prefix-List to control which groups to switch\n"
6082 "Prefix-List name\n")
6084 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6085 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
6088 DEFUN (ip_pim_joinprune_time
,
6089 ip_pim_joinprune_time_cmd
,
6090 "ip pim join-prune-interval (60-600)",
6092 "pim multicast routing\n"
6093 "Join Prune Send Interval\n"
6096 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6097 router
->t_periodic
= atoi(argv
[3]->arg
);
6101 DEFUN (no_ip_pim_joinprune_time
,
6102 no_ip_pim_joinprune_time_cmd
,
6103 "no ip pim join-prune-interval (60-600)",
6106 "pim multicast routing\n"
6107 "Join Prune Send Interval\n"
6110 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6111 router
->t_periodic
= PIM_DEFAULT_T_PERIODIC
;
6115 DEFUN (ip_pim_register_suppress
,
6116 ip_pim_register_suppress_cmd
,
6117 "ip pim register-suppress-time (5-60000)",
6119 "pim multicast routing\n"
6120 "Register Suppress Timer\n"
6123 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6124 router
->register_suppress_time
= atoi(argv
[3]->arg
);
6128 DEFUN (no_ip_pim_register_suppress
,
6129 no_ip_pim_register_suppress_cmd
,
6130 "no ip pim register-suppress-time (5-60000)",
6133 "pim multicast routing\n"
6134 "Register Suppress Timer\n"
6137 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6138 router
->register_suppress_time
= PIM_REGISTER_SUPPRESSION_TIME_DEFAULT
;
6142 DEFUN (ip_pim_rp_keep_alive
,
6143 ip_pim_rp_keep_alive_cmd
,
6144 "ip pim rp keep-alive-timer (31-60000)",
6146 "pim multicast routing\n"
6148 "Keep alive Timer\n"
6151 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6152 pim
->rp_keep_alive_time
= atoi(argv
[4]->arg
);
6156 DEFUN (no_ip_pim_rp_keep_alive
,
6157 no_ip_pim_rp_keep_alive_cmd
,
6158 "no ip pim rp keep-alive-timer (31-60000)",
6161 "pim multicast routing\n"
6163 "Keep alive Timer\n"
6166 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6167 pim
->rp_keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
6171 DEFUN (ip_pim_keep_alive
,
6172 ip_pim_keep_alive_cmd
,
6173 "ip pim keep-alive-timer (31-60000)",
6175 "pim multicast routing\n"
6176 "Keep alive Timer\n"
6179 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6180 pim
->keep_alive_time
= atoi(argv
[3]->arg
);
6184 DEFUN (no_ip_pim_keep_alive
,
6185 no_ip_pim_keep_alive_cmd
,
6186 "no ip pim keep-alive-timer (31-60000)",
6189 "pim multicast routing\n"
6190 "Keep alive Timer\n"
6193 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6194 pim
->keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
6198 DEFUN (ip_pim_packets
,
6200 "ip pim packets (1-100)",
6202 "pim multicast routing\n"
6203 "packets to process at one time per fd\n"
6204 "Number of packets\n")
6206 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6207 router
->packet_process
= atoi(argv
[3]->arg
);
6211 DEFUN (no_ip_pim_packets
,
6212 no_ip_pim_packets_cmd
,
6213 "no ip pim packets (1-100)",
6216 "pim multicast routing\n"
6217 "packets to process at one time per fd\n"
6218 "Number of packets\n")
6220 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6221 router
->packet_process
= PIM_DEFAULT_PACKET_PROCESS
;
6225 DEFUN (ip_pim_v6_secondary
,
6226 ip_pim_v6_secondary_cmd
,
6227 "ip pim send-v6-secondary",
6229 "pim multicast routing\n"
6230 "Send v6 secondary addresses\n")
6232 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6233 pim
->send_v6_secondary
= 1;
6238 DEFUN (no_ip_pim_v6_secondary
,
6239 no_ip_pim_v6_secondary_cmd
,
6240 "no ip pim send-v6-secondary",
6243 "pim multicast routing\n"
6244 "Send v6 secondary addresses\n")
6246 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6247 pim
->send_v6_secondary
= 0;
6254 "ip pim rp A.B.C.D [A.B.C.D/M]",
6256 "pim multicast routing\n"
6258 "ip address of RP\n"
6259 "Group Address range to cover\n")
6261 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6264 if (argc
== (idx_ipv4
+ 1))
6265 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
6268 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
6269 argv
[idx_ipv4
+ 1]->arg
, NULL
);
6272 DEFUN (ip_pim_rp_prefix_list
,
6273 ip_pim_rp_prefix_list_cmd
,
6274 "ip pim rp A.B.C.D prefix-list WORD",
6276 "pim multicast routing\n"
6278 "ip address of RP\n"
6279 "group prefix-list filter\n"
6280 "Name of a prefix-list\n")
6282 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6283 return pim_rp_cmd_worker(pim
, vty
, argv
[3]->arg
, NULL
, argv
[5]->arg
);
6286 static int pim_no_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
6287 const char *rp
, const char *group
,
6290 int result
= pim_rp_del_config(pim
, rp
, group
, plist
);
6292 if (result
== PIM_GROUP_BAD_ADDRESS
) {
6293 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
6294 return CMD_WARNING_CONFIG_FAILED
;
6297 if (result
== PIM_RP_BAD_ADDRESS
) {
6298 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
6299 return CMD_WARNING_CONFIG_FAILED
;
6302 if (result
== PIM_RP_NOT_FOUND
) {
6303 vty_out(vty
, "%% Unable to find specified RP\n");
6304 return CMD_WARNING_CONFIG_FAILED
;
6310 DEFUN (no_ip_pim_rp
,
6312 "no ip pim rp A.B.C.D [A.B.C.D/M]",
6315 "pim multicast routing\n"
6317 "ip address of RP\n"
6318 "Group Address range to cover\n")
6320 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6321 int idx_ipv4
= 4, idx_group
= 0;
6323 if (argv_find(argv
, argc
, "A.B.C.D/M", &idx_group
))
6324 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
6325 argv
[idx_group
]->arg
, NULL
);
6327 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
6331 DEFUN (no_ip_pim_rp_prefix_list
,
6332 no_ip_pim_rp_prefix_list_cmd
,
6333 "no ip pim rp A.B.C.D prefix-list WORD",
6336 "pim multicast routing\n"
6338 "ip address of RP\n"
6339 "group prefix-list filter\n"
6340 "Name of a prefix-list\n")
6342 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6343 return pim_no_rp_cmd_worker(pim
, vty
, argv
[4]->arg
, NULL
, argv
[6]->arg
);
6346 static int pim_ssm_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
6349 int result
= pim_ssm_range_set(pim
, pim
->vrf_id
, plist
);
6351 if (result
== PIM_SSM_ERR_NONE
)
6355 case PIM_SSM_ERR_NO_VRF
:
6356 vty_out(vty
, "%% VRF doesn't exist\n");
6358 case PIM_SSM_ERR_DUP
:
6359 vty_out(vty
, "%% duplicate config\n");
6362 vty_out(vty
, "%% ssm range config failed\n");
6365 return CMD_WARNING_CONFIG_FAILED
;
6368 DEFUN (ip_pim_ssm_prefix_list
,
6369 ip_pim_ssm_prefix_list_cmd
,
6370 "ip pim ssm prefix-list WORD",
6372 "pim multicast routing\n"
6373 "Source Specific Multicast\n"
6374 "group range prefix-list filter\n"
6375 "Name of a prefix-list\n")
6377 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6378 return pim_ssm_cmd_worker(pim
, vty
, argv
[4]->arg
);
6381 DEFUN (no_ip_pim_ssm_prefix_list
,
6382 no_ip_pim_ssm_prefix_list_cmd
,
6383 "no ip pim ssm prefix-list",
6386 "pim multicast routing\n"
6387 "Source Specific Multicast\n"
6388 "group range prefix-list filter\n")
6390 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6391 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
6394 DEFUN (no_ip_pim_ssm_prefix_list_name
,
6395 no_ip_pim_ssm_prefix_list_name_cmd
,
6396 "no ip pim ssm prefix-list WORD",
6399 "pim multicast routing\n"
6400 "Source Specific Multicast\n"
6401 "group range prefix-list filter\n"
6402 "Name of a prefix-list\n")
6404 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6405 struct pim_ssm
*ssm
= pim
->ssm_info
;
6407 if (ssm
->plist_name
&& !strcmp(ssm
->plist_name
, argv
[5]->arg
))
6408 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
6410 vty_out(vty
, "%% pim ssm prefix-list %s doesn't exist\n", argv
[5]->arg
);
6412 return CMD_WARNING_CONFIG_FAILED
;
6415 static void ip_pim_ssm_show_group_range(struct pim_instance
*pim
,
6416 struct vty
*vty
, bool uj
)
6418 struct pim_ssm
*ssm
= pim
->ssm_info
;
6419 const char *range_str
=
6420 ssm
->plist_name
? ssm
->plist_name
: PIM_SSM_STANDARD_RANGE
;
6424 json
= json_object_new_object();
6425 json_object_string_add(json
, "ssmGroups", range_str
);
6426 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
6427 json
, JSON_C_TO_STRING_PRETTY
));
6428 json_object_free(json
);
6430 vty_out(vty
, "SSM group range : %s\n", range_str
);
6433 DEFUN (show_ip_pim_ssm_range
,
6434 show_ip_pim_ssm_range_cmd
,
6435 "show ip pim [vrf NAME] group-type [json]",
6444 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6445 bool uj
= use_json(argc
, argv
);
6450 ip_pim_ssm_show_group_range(vrf
->info
, vty
, uj
);
6455 static void ip_pim_ssm_show_group_type(struct pim_instance
*pim
,
6456 struct vty
*vty
, bool uj
,
6459 struct in_addr group_addr
;
6460 const char *type_str
;
6463 result
= inet_pton(AF_INET
, group
, &group_addr
);
6465 type_str
= "invalid";
6467 if (pim_is_group_224_4(group_addr
))
6469 pim_is_grp_ssm(pim
, group_addr
) ? "SSM" : "ASM";
6471 type_str
= "not-multicast";
6476 json
= json_object_new_object();
6477 json_object_string_add(json
, "groupType", type_str
);
6478 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
6479 json
, JSON_C_TO_STRING_PRETTY
));
6480 json_object_free(json
);
6482 vty_out(vty
, "Group type : %s\n", type_str
);
6485 DEFUN (show_ip_pim_group_type
,
6486 show_ip_pim_group_type_cmd
,
6487 "show ip pim [vrf NAME] group-type A.B.C.D [json]",
6492 "multicast group type\n"
6497 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6498 bool uj
= use_json(argc
, argv
);
6503 argv_find(argv
, argc
, "A.B.C.D", &idx
);
6504 ip_pim_ssm_show_group_type(vrf
->info
, vty
, uj
, argv
[idx
]->arg
);
6509 DEFUN (show_ip_pim_bsr
,
6510 show_ip_pim_bsr_cmd
,
6511 "show ip pim bsr [json]",
6515 "boot-strap router information\n"
6519 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6520 bool uj
= use_json(argc
, argv
);
6525 pim_show_bsr(vrf
->info
, vty
, uj
);
6532 "ip ssmpingd [A.B.C.D]",
6537 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6540 struct in_addr source_addr
;
6541 const char *source_str
= (argc
== 3) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
6543 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
6545 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
6546 source_str
, errno
, safe_strerror(errno
));
6547 return CMD_WARNING_CONFIG_FAILED
;
6550 result
= pim_ssmpingd_start(pim
, source_addr
);
6552 vty_out(vty
, "%% Failure starting ssmpingd for source %s: %d\n",
6553 source_str
, result
);
6554 return CMD_WARNING_CONFIG_FAILED
;
6560 DEFUN (no_ip_ssmpingd
,
6562 "no ip ssmpingd [A.B.C.D]",
6568 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6571 struct in_addr source_addr
;
6572 const char *source_str
= (argc
== 4) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
6574 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
6576 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
6577 source_str
, errno
, safe_strerror(errno
));
6578 return CMD_WARNING_CONFIG_FAILED
;
6581 result
= pim_ssmpingd_stop(pim
, source_addr
);
6583 vty_out(vty
, "%% Failure stopping ssmpingd for source %s: %d\n",
6584 source_str
, result
);
6585 return CMD_WARNING_CONFIG_FAILED
;
6595 "pim multicast routing\n"
6596 "Enable PIM ECMP \n")
6598 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6599 pim
->ecmp_enable
= true;
6604 DEFUN (no_ip_pim_ecmp
,
6609 "pim multicast routing\n"
6610 "Disable PIM ECMP \n")
6612 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6613 pim
->ecmp_enable
= false;
6618 DEFUN (ip_pim_ecmp_rebalance
,
6619 ip_pim_ecmp_rebalance_cmd
,
6620 "ip pim ecmp rebalance",
6622 "pim multicast routing\n"
6623 "Enable PIM ECMP \n"
6624 "Enable PIM ECMP Rebalance\n")
6626 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6627 pim
->ecmp_enable
= true;
6628 pim
->ecmp_rebalance_enable
= true;
6633 DEFUN (no_ip_pim_ecmp_rebalance
,
6634 no_ip_pim_ecmp_rebalance_cmd
,
6635 "no ip pim ecmp rebalance",
6638 "pim multicast routing\n"
6639 "Disable PIM ECMP \n"
6640 "Disable PIM ECMP Rebalance\n")
6642 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6643 pim
->ecmp_rebalance_enable
= false;
6648 static int pim_cmd_igmp_start(struct vty
*vty
, struct interface
*ifp
)
6650 struct pim_interface
*pim_ifp
;
6651 uint8_t need_startup
= 0;
6653 pim_ifp
= ifp
->info
;
6656 pim_ifp
= pim_if_new(ifp
, true, false, false,
6657 false /*vxlan_term*/);
6659 vty_out(vty
, "Could not enable IGMP on interface %s\n",
6661 return CMD_WARNING_CONFIG_FAILED
;
6665 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
6666 PIM_IF_DO_IGMP(pim_ifp
->options
);
6671 /* 'ip igmp' executed multiple times, with need_startup
6672 avoid multiple if add all and membership refresh */
6674 pim_if_addr_add_all(ifp
);
6675 pim_if_membership_refresh(ifp
);
6681 DEFUN (interface_ip_igmp
,
6682 interface_ip_igmp_cmd
,
6687 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6689 return pim_cmd_igmp_start(vty
, ifp
);
6692 DEFUN (interface_no_ip_igmp
,
6693 interface_no_ip_igmp_cmd
,
6699 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6700 struct pim_interface
*pim_ifp
= ifp
->info
;
6705 PIM_IF_DONT_IGMP(pim_ifp
->options
);
6707 pim_if_membership_clear(ifp
);
6709 pim_if_addr_del_all_igmp(ifp
);
6711 if (!PIM_IF_TEST_PIM(pim_ifp
->options
)) {
6718 DEFUN (interface_ip_igmp_join
,
6719 interface_ip_igmp_join_cmd
,
6720 "ip igmp join A.B.C.D A.B.C.D",
6723 "IGMP join multicast group\n"
6724 "Multicast group address\n"
6727 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6730 const char *group_str
;
6731 const char *source_str
;
6732 struct in_addr group_addr
;
6733 struct in_addr source_addr
;
6737 group_str
= argv
[idx_ipv4
]->arg
;
6738 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
6740 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
6741 errno
, safe_strerror(errno
));
6742 return CMD_WARNING_CONFIG_FAILED
;
6745 /* Source address */
6746 source_str
= argv
[idx_ipv4_2
]->arg
;
6747 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
6749 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
6750 source_str
, errno
, safe_strerror(errno
));
6751 return CMD_WARNING_CONFIG_FAILED
;
6754 CMD_FERR_RETURN(pim_if_igmp_join_add(ifp
, group_addr
, source_addr
),
6755 "Failure joining IGMP group: $ERR");
6760 DEFUN (interface_no_ip_igmp_join
,
6761 interface_no_ip_igmp_join_cmd
,
6762 "no ip igmp join A.B.C.D A.B.C.D",
6766 "IGMP join multicast group\n"
6767 "Multicast group address\n"
6770 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6773 const char *group_str
;
6774 const char *source_str
;
6775 struct in_addr group_addr
;
6776 struct in_addr source_addr
;
6780 group_str
= argv
[idx_ipv4
]->arg
;
6781 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
6783 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
6784 errno
, safe_strerror(errno
));
6785 return CMD_WARNING_CONFIG_FAILED
;
6788 /* Source address */
6789 source_str
= argv
[idx_ipv4_2
]->arg
;
6790 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
6792 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
6793 source_str
, errno
, safe_strerror(errno
));
6794 return CMD_WARNING_CONFIG_FAILED
;
6797 result
= pim_if_igmp_join_del(ifp
, group_addr
, source_addr
);
6800 "%% Failure leaving IGMP group %s source %s on interface %s: %d\n",
6801 group_str
, source_str
, ifp
->name
, result
);
6802 return CMD_WARNING_CONFIG_FAILED
;
6809 CLI reconfiguration affects the interface level (struct pim_interface).
6810 This function propagates the reconfiguration to every active socket
6813 static void igmp_sock_query_interval_reconfig(struct igmp_sock
*igmp
)
6815 struct interface
*ifp
;
6816 struct pim_interface
*pim_ifp
;
6820 /* other querier present? */
6822 if (igmp
->t_other_querier_timer
)
6825 /* this is the querier */
6827 zassert(igmp
->interface
);
6828 zassert(igmp
->interface
->info
);
6830 ifp
= igmp
->interface
;
6831 pim_ifp
= ifp
->info
;
6833 if (PIM_DEBUG_IGMP_TRACE
) {
6834 char ifaddr_str
[INET_ADDRSTRLEN
];
6835 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
6836 sizeof(ifaddr_str
));
6837 zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
6838 __PRETTY_FUNCTION__
, ifaddr_str
, ifp
->name
,
6839 pim_ifp
->igmp_default_query_interval
);
6843 igmp_startup_mode_on() will reset QQI:
6845 igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
6847 igmp_startup_mode_on(igmp
);
6850 static void igmp_sock_query_reschedule(struct igmp_sock
*igmp
)
6852 if (igmp
->t_igmp_query_timer
) {
6853 /* other querier present */
6854 zassert(igmp
->t_igmp_query_timer
);
6855 zassert(!igmp
->t_other_querier_timer
);
6857 pim_igmp_general_query_off(igmp
);
6858 pim_igmp_general_query_on(igmp
);
6860 zassert(igmp
->t_igmp_query_timer
);
6861 zassert(!igmp
->t_other_querier_timer
);
6863 /* this is the querier */
6865 zassert(!igmp
->t_igmp_query_timer
);
6866 zassert(igmp
->t_other_querier_timer
);
6868 pim_igmp_other_querier_timer_off(igmp
);
6869 pim_igmp_other_querier_timer_on(igmp
);
6871 zassert(!igmp
->t_igmp_query_timer
);
6872 zassert(igmp
->t_other_querier_timer
);
6876 static void change_query_interval(struct pim_interface
*pim_ifp
,
6879 struct listnode
*sock_node
;
6880 struct igmp_sock
*igmp
;
6882 pim_ifp
->igmp_default_query_interval
= query_interval
;
6884 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
6885 igmp_sock_query_interval_reconfig(igmp
);
6886 igmp_sock_query_reschedule(igmp
);
6890 static void change_query_max_response_time(struct pim_interface
*pim_ifp
,
6891 int query_max_response_time_dsec
)
6893 struct listnode
*sock_node
;
6894 struct igmp_sock
*igmp
;
6896 pim_ifp
->igmp_query_max_response_time_dsec
=
6897 query_max_response_time_dsec
;
6900 Below we modify socket/group/source timers in order to quickly
6901 reflect the change. Otherwise, those timers would eventually catch
6905 /* scan all sockets */
6906 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
6907 struct listnode
*grp_node
;
6908 struct igmp_group
*grp
;
6910 /* reschedule socket general query */
6911 igmp_sock_query_reschedule(igmp
);
6913 /* scan socket groups */
6914 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grp_node
,
6916 struct listnode
*src_node
;
6917 struct igmp_source
*src
;
6919 /* reset group timers for groups in EXCLUDE mode */
6920 if (grp
->group_filtermode_isexcl
) {
6921 igmp_group_reset_gmi(grp
);
6924 /* scan group sources */
6925 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
,
6928 /* reset source timers for sources with running
6930 if (src
->t_source_timer
) {
6931 igmp_source_reset_gmi(igmp
, grp
, src
);
6938 #define IGMP_QUERY_INTERVAL_MIN (1)
6939 #define IGMP_QUERY_INTERVAL_MAX (1800)
6941 DEFUN (interface_ip_igmp_query_interval
,
6942 interface_ip_igmp_query_interval_cmd
,
6943 "ip igmp query-interval (1-1800)",
6946 IFACE_IGMP_QUERY_INTERVAL_STR
6947 "Query interval in seconds\n")
6949 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6950 struct pim_interface
*pim_ifp
= ifp
->info
;
6952 int query_interval_dsec
;
6956 ret
= pim_cmd_igmp_start(vty
, ifp
);
6957 if (ret
!= CMD_SUCCESS
)
6959 pim_ifp
= ifp
->info
;
6962 query_interval
= atoi(argv
[3]->arg
);
6963 query_interval_dsec
= 10 * query_interval
;
6966 It seems we don't need to check bounds since command.c does it
6967 already, but we verify them anyway for extra safety.
6969 if (query_interval
< IGMP_QUERY_INTERVAL_MIN
) {
6971 "General query interval %d lower than minimum %d\n",
6972 query_interval
, IGMP_QUERY_INTERVAL_MIN
);
6973 return CMD_WARNING_CONFIG_FAILED
;
6975 if (query_interval
> IGMP_QUERY_INTERVAL_MAX
) {
6977 "General query interval %d higher than maximum %d\n",
6978 query_interval
, IGMP_QUERY_INTERVAL_MAX
);
6979 return CMD_WARNING_CONFIG_FAILED
;
6982 if (query_interval_dsec
<= pim_ifp
->igmp_query_max_response_time_dsec
) {
6984 "Can't set general query interval %d dsec <= query max response time %d dsec.\n",
6985 query_interval_dsec
,
6986 pim_ifp
->igmp_query_max_response_time_dsec
);
6987 return CMD_WARNING_CONFIG_FAILED
;
6990 change_query_interval(pim_ifp
, query_interval
);
6995 DEFUN (interface_no_ip_igmp_query_interval
,
6996 interface_no_ip_igmp_query_interval_cmd
,
6997 "no ip igmp query-interval",
7001 IFACE_IGMP_QUERY_INTERVAL_STR
)
7003 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7004 struct pim_interface
*pim_ifp
= ifp
->info
;
7005 int default_query_interval_dsec
;
7010 default_query_interval_dsec
= IGMP_GENERAL_QUERY_INTERVAL
* 10;
7012 if (default_query_interval_dsec
7013 <= pim_ifp
->igmp_query_max_response_time_dsec
) {
7015 "Can't set default general query interval %d dsec <= query max response time %d dsec.\n",
7016 default_query_interval_dsec
,
7017 pim_ifp
->igmp_query_max_response_time_dsec
);
7018 return CMD_WARNING_CONFIG_FAILED
;
7021 change_query_interval(pim_ifp
, IGMP_GENERAL_QUERY_INTERVAL
);
7026 DEFUN (interface_ip_igmp_version
,
7027 interface_ip_igmp_version_cmd
,
7028 "ip igmp version (2-3)",
7032 "IGMP version number\n")
7034 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7035 struct pim_interface
*pim_ifp
= ifp
->info
;
7036 int igmp_version
, old_version
= 0;
7040 ret
= pim_cmd_igmp_start(vty
, ifp
);
7041 if (ret
!= CMD_SUCCESS
)
7043 pim_ifp
= ifp
->info
;
7046 igmp_version
= atoi(argv
[3]->arg
);
7047 old_version
= pim_ifp
->igmp_version
;
7048 pim_ifp
->igmp_version
= igmp_version
;
7050 // Check if IGMP is Enabled otherwise, enable on interface
7051 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
7052 PIM_IF_DO_IGMP(pim_ifp
->options
);
7053 pim_if_addr_add_all(ifp
);
7054 pim_if_membership_refresh(ifp
);
7055 old_version
= igmp_version
;
7056 // avoid refreshing membership again.
7058 /* Current and new version is different refresh existing
7059 membership. Going from 3 -> 2 or 2 -> 3. */
7060 if (old_version
!= igmp_version
)
7061 pim_if_membership_refresh(ifp
);
7066 DEFUN (interface_no_ip_igmp_version
,
7067 interface_no_ip_igmp_version_cmd
,
7068 "no ip igmp version (2-3)",
7073 "IGMP version number\n")
7075 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7076 struct pim_interface
*pim_ifp
= ifp
->info
;
7081 pim_ifp
->igmp_version
= IGMP_DEFAULT_VERSION
;
7086 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
7087 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
7089 DEFUN (interface_ip_igmp_query_max_response_time
,
7090 interface_ip_igmp_query_max_response_time_cmd
,
7091 "ip igmp query-max-response-time (10-250)",
7094 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
7095 "Query response value in deci-seconds\n")
7097 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7098 struct pim_interface
*pim_ifp
= ifp
->info
;
7099 int query_max_response_time
;
7103 ret
= pim_cmd_igmp_start(vty
, ifp
);
7104 if (ret
!= CMD_SUCCESS
)
7106 pim_ifp
= ifp
->info
;
7109 query_max_response_time
= atoi(argv
[3]->arg
);
7111 if (query_max_response_time
7112 >= pim_ifp
->igmp_default_query_interval
* 10) {
7114 "Can't set query max response time %d sec >= general query interval %d sec\n",
7115 query_max_response_time
,
7116 pim_ifp
->igmp_default_query_interval
);
7117 return CMD_WARNING_CONFIG_FAILED
;
7120 change_query_max_response_time(pim_ifp
, query_max_response_time
);
7125 DEFUN (interface_no_ip_igmp_query_max_response_time
,
7126 interface_no_ip_igmp_query_max_response_time_cmd
,
7127 "no ip igmp query-max-response-time (10-250)",
7131 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
7132 "Time for response in deci-seconds\n")
7134 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7135 struct pim_interface
*pim_ifp
= ifp
->info
;
7140 change_query_max_response_time(pim_ifp
,
7141 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
7146 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
7147 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
7149 DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec
,
7150 interface_ip_igmp_query_max_response_time_dsec_cmd
,
7151 "ip igmp query-max-response-time-dsec (10-250)",
7154 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
7155 "Query response value in deciseconds\n")
7157 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7158 struct pim_interface
*pim_ifp
= ifp
->info
;
7159 int query_max_response_time_dsec
;
7160 int default_query_interval_dsec
;
7164 ret
= pim_cmd_igmp_start(vty
, ifp
);
7165 if (ret
!= CMD_SUCCESS
)
7167 pim_ifp
= ifp
->info
;
7170 query_max_response_time_dsec
= atoi(argv
[4]->arg
);
7172 default_query_interval_dsec
= 10 * pim_ifp
->igmp_default_query_interval
;
7174 if (query_max_response_time_dsec
>= default_query_interval_dsec
) {
7176 "Can't set query max response time %d dsec >= general query interval %d dsec\n",
7177 query_max_response_time_dsec
,
7178 default_query_interval_dsec
);
7179 return CMD_WARNING_CONFIG_FAILED
;
7182 change_query_max_response_time(pim_ifp
, query_max_response_time_dsec
);
7187 DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec
,
7188 interface_no_ip_igmp_query_max_response_time_dsec_cmd
,
7189 "no ip igmp query-max-response-time-dsec",
7193 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
)
7195 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7196 struct pim_interface
*pim_ifp
= ifp
->info
;
7201 change_query_max_response_time(pim_ifp
,
7202 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
7207 #define IGMP_LAST_MEMBER_QUERY_COUNT_MIN (1)
7208 #define IGMP_LAST_MEMBER_QUERY_COUNT_MAX (7)
7210 DEFUN (interface_ip_igmp_last_member_query_count
,
7211 interface_ip_igmp_last_member_query_count_cmd
,
7212 "ip igmp last-member-query-count (1-7)",
7215 IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR
7216 "Last member query count\n")
7218 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7219 struct pim_interface
*pim_ifp
= ifp
->info
;
7220 int last_member_query_count
;
7224 ret
= pim_cmd_igmp_start(vty
, ifp
);
7225 if (ret
!= CMD_SUCCESS
)
7227 pim_ifp
= ifp
->info
;
7230 last_member_query_count
= atoi(argv
[3]->arg
);
7232 pim_ifp
->igmp_last_member_query_count
= last_member_query_count
;
7237 DEFUN (interface_no_ip_igmp_last_member_query_count
,
7238 interface_no_ip_igmp_last_member_query_count_cmd
,
7239 "no ip igmp last-member-query-count",
7243 IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR
)
7245 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7246 struct pim_interface
*pim_ifp
= ifp
->info
;
7251 pim_ifp
->igmp_last_member_query_count
=
7252 IGMP_DEFAULT_ROBUSTNESS_VARIABLE
;
7257 #define IGMP_LAST_MEMBER_QUERY_INTERVAL_MIN (1)
7258 #define IGMP_LAST_MEMBER_QUERY_INTERVAL_MAX (255)
7260 DEFUN (interface_ip_igmp_last_member_query_interval
,
7261 interface_ip_igmp_last_member_query_interval_cmd
,
7262 "ip igmp last-member-query-interval (1-255)",
7265 IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR
7266 "Last member query interval in deciseconds\n")
7268 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7269 struct pim_interface
*pim_ifp
= ifp
->info
;
7270 int last_member_query_interval
;
7274 ret
= pim_cmd_igmp_start(vty
, ifp
);
7275 if (ret
!= CMD_SUCCESS
)
7277 pim_ifp
= ifp
->info
;
7280 last_member_query_interval
= atoi(argv
[3]->arg
);
7281 pim_ifp
->igmp_specific_query_max_response_time_dsec
7282 = last_member_query_interval
;
7287 DEFUN (interface_no_ip_igmp_last_member_query_interval
,
7288 interface_no_ip_igmp_last_member_query_interval_cmd
,
7289 "no ip igmp last-member-query-interval",
7293 IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR
)
7295 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7296 struct pim_interface
*pim_ifp
= ifp
->info
;
7301 pim_ifp
->igmp_specific_query_max_response_time_dsec
=
7302 IGMP_SPECIFIC_QUERY_MAX_RESPONSE_TIME_DSEC
;
7307 DEFUN (interface_ip_pim_drprio
,
7308 interface_ip_pim_drprio_cmd
,
7309 "ip pim drpriority (1-4294967295)",
7312 "Set the Designated Router Election Priority\n"
7313 "Value of the new DR Priority\n")
7315 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7317 struct pim_interface
*pim_ifp
= ifp
->info
;
7318 uint32_t old_dr_prio
;
7321 vty_out(vty
, "Please enable PIM on interface, first\n");
7322 return CMD_WARNING_CONFIG_FAILED
;
7325 old_dr_prio
= pim_ifp
->pim_dr_priority
;
7327 pim_ifp
->pim_dr_priority
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
7329 if (old_dr_prio
!= pim_ifp
->pim_dr_priority
) {
7330 pim_if_dr_election(ifp
);
7331 pim_hello_restart_now(ifp
);
7337 DEFUN (interface_no_ip_pim_drprio
,
7338 interface_no_ip_pim_drprio_cmd
,
7339 "no ip pim drpriority [(1-4294967295)]",
7343 "Revert the Designated Router Priority to default\n"
7344 "Old Value of the Priority\n")
7346 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7347 struct pim_interface
*pim_ifp
= ifp
->info
;
7350 vty_out(vty
, "Pim not enabled on this interface\n");
7351 return CMD_WARNING_CONFIG_FAILED
;
7354 if (pim_ifp
->pim_dr_priority
!= PIM_DEFAULT_DR_PRIORITY
) {
7355 pim_ifp
->pim_dr_priority
= PIM_DEFAULT_DR_PRIORITY
;
7356 pim_if_dr_election(ifp
);
7357 pim_hello_restart_now(ifp
);
7363 static int pim_cmd_interface_add(struct interface
*ifp
)
7365 struct pim_interface
*pim_ifp
= ifp
->info
;
7368 pim_ifp
= pim_if_new(ifp
, false, true, false,
7369 false /*vxlan_term*/);
7374 PIM_IF_DO_PIM(pim_ifp
->options
);
7377 pim_if_addr_add_all(ifp
);
7378 pim_if_membership_refresh(ifp
);
7382 DEFPY_HIDDEN (pim_test_sg_keepalive
,
7383 pim_test_sg_keepalive_cmd
,
7384 "test pim [vrf NAME$name] keepalive-reset A.B.C.D$source A.B.C.D$group",
7388 "Reset the Keepalive Timer\n"
7389 "The Source we are resetting\n"
7390 "The Group we are resetting\n")
7392 struct pim_upstream
*up
;
7393 struct pim_instance
*pim
;
7394 struct prefix_sg sg
;
7400 pim
= pim_get_pim_instance(VRF_DEFAULT
);
7402 struct vrf
*vrf
= vrf_lookup_by_name(name
);
7405 vty_out(vty
, "%% Vrf specified: %s does not exist\n",
7410 pim
= pim_get_pim_instance(vrf
->vrf_id
);
7414 vty_out(vty
, "%% Unable to find pim instance\n");
7418 up
= pim_upstream_find(pim
, &sg
);
7420 vty_out(vty
, "%% Unable to find %s specified\n",
7421 pim_str_sg_dump(&sg
));
7425 vty_out(vty
, "Setting %s to current keep alive time: %d\n",
7426 pim_str_sg_dump(&sg
), pim
->keep_alive_time
);
7427 pim_upstream_keep_alive_timer_start(up
, pim
->keep_alive_time
);
7432 DEFPY_HIDDEN (interface_ip_pim_activeactive
,
7433 interface_ip_pim_activeactive_cmd
,
7434 "[no$no] ip pim active-active",
7438 "Mark interface as Active-Active for MLAG operations, Hidden because not finished yet\n")
7440 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7441 struct pim_interface
*pim_ifp
;
7443 if (!no
&& !pim_cmd_interface_add(ifp
)) {
7444 vty_out(vty
, "Could not enable PIM SM active-active on interface\n");
7445 return CMD_WARNING_CONFIG_FAILED
;
7448 pim_ifp
= ifp
->info
;
7450 pim_ifp
->activeactive
= false;
7452 pim_ifp
->activeactive
= true;
7457 DEFUN_HIDDEN (interface_ip_pim_ssm
,
7458 interface_ip_pim_ssm_cmd
,
7464 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7466 if (!pim_cmd_interface_add(ifp
)) {
7467 vty_out(vty
, "Could not enable PIM SM on interface\n");
7468 return CMD_WARNING_CONFIG_FAILED
;
7472 "WARN: Enabled PIM SM on interface; configure PIM SSM "
7473 "range if needed\n");
7477 static int interface_ip_pim_helper(struct vty
*vty
)
7479 struct pim_interface
*pim_ifp
;
7481 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7483 if (!pim_cmd_interface_add(ifp
)) {
7484 vty_out(vty
, "Could not enable PIM SM on interface\n");
7485 return CMD_WARNING_CONFIG_FAILED
;
7488 pim_ifp
= ifp
->info
;
7490 pim_if_create_pimreg(pim_ifp
->pim
);
7495 DEFUN_HIDDEN (interface_ip_pim_sm
,
7496 interface_ip_pim_sm_cmd
,
7502 return interface_ip_pim_helper(vty
);
7505 DEFUN (interface_ip_pim
,
7506 interface_ip_pim_cmd
,
7511 return interface_ip_pim_helper(vty
);
7514 static int pim_cmd_interface_delete(struct interface
*ifp
)
7516 struct pim_interface
*pim_ifp
= ifp
->info
;
7521 PIM_IF_DONT_PIM(pim_ifp
->options
);
7523 pim_if_membership_clear(ifp
);
7526 pim_sock_delete() removes all neighbors from
7527 pim_ifp->pim_neighbor_list.
7529 pim_sock_delete(ifp
, "pim unconfigured on interface");
7531 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
7532 pim_if_addr_del_all(ifp
);
7539 static int interface_no_ip_pim_helper(struct vty
*vty
)
7541 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7542 if (!pim_cmd_interface_delete(ifp
)) {
7543 vty_out(vty
, "Unable to delete interface information\n");
7544 return CMD_WARNING_CONFIG_FAILED
;
7550 DEFUN_HIDDEN (interface_no_ip_pim_ssm
,
7551 interface_no_ip_pim_ssm_cmd
,
7558 return interface_no_ip_pim_helper(vty
);
7561 DEFUN_HIDDEN (interface_no_ip_pim_sm
,
7562 interface_no_ip_pim_sm_cmd
,
7569 return interface_no_ip_pim_helper(vty
);
7572 DEFUN (interface_no_ip_pim
,
7573 interface_no_ip_pim_cmd
,
7579 return interface_no_ip_pim_helper(vty
);
7583 DEFUN(interface_ip_pim_boundary_oil
,
7584 interface_ip_pim_boundary_oil_cmd
,
7585 "ip multicast boundary oil WORD",
7587 "Generic multicast configuration options\n"
7588 "Define multicast boundary\n"
7589 "Filter OIL by group using prefix list\n"
7590 "Prefix list to filter OIL with\n")
7592 VTY_DECLVAR_CONTEXT(interface
, iif
);
7593 struct pim_interface
*pim_ifp
;
7596 argv_find(argv
, argc
, "WORD", &idx
);
7598 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
7600 if (pim_ifp
->boundary_oil_plist
)
7601 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
7603 pim_ifp
->boundary_oil_plist
=
7604 XSTRDUP(MTYPE_PIM_INTERFACE
, argv
[idx
]->arg
);
7606 /* Interface will be pruned from OIL on next Join */
7610 DEFUN(interface_no_ip_pim_boundary_oil
,
7611 interface_no_ip_pim_boundary_oil_cmd
,
7612 "no ip multicast boundary oil [WORD]",
7615 "Generic multicast configuration options\n"
7616 "Define multicast boundary\n"
7617 "Filter OIL by group using prefix list\n"
7618 "Prefix list to filter OIL with\n")
7620 VTY_DECLVAR_CONTEXT(interface
, iif
);
7621 struct pim_interface
*pim_ifp
;
7624 argv_find(argv
, argc
, "WORD", &idx
);
7626 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
7628 if (pim_ifp
->boundary_oil_plist
)
7629 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
7634 DEFUN (interface_ip_mroute
,
7635 interface_ip_mroute_cmd
,
7636 "ip mroute INTERFACE A.B.C.D",
7638 "Add multicast route\n"
7639 "Outgoing interface name\n"
7642 VTY_DECLVAR_CONTEXT(interface
, iif
);
7643 struct pim_interface
*pim_ifp
;
7644 struct pim_instance
*pim
;
7645 int idx_interface
= 2;
7647 struct interface
*oif
;
7648 const char *oifname
;
7649 const char *grp_str
;
7650 struct in_addr grp_addr
;
7651 struct in_addr src_addr
;
7654 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
7657 oifname
= argv
[idx_interface
]->arg
;
7658 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
7660 vty_out(vty
, "No such interface name %s\n", oifname
);
7664 grp_str
= argv
[idx_ipv4
]->arg
;
7665 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
7667 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
7668 errno
, safe_strerror(errno
));
7672 src_addr
.s_addr
= INADDR_ANY
;
7674 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
7675 vty_out(vty
, "Failed to add route\n");
7682 DEFUN (interface_ip_mroute_source
,
7683 interface_ip_mroute_source_cmd
,
7684 "ip mroute INTERFACE A.B.C.D A.B.C.D",
7686 "Add multicast route\n"
7687 "Outgoing interface name\n"
7691 VTY_DECLVAR_CONTEXT(interface
, iif
);
7692 struct pim_interface
*pim_ifp
;
7693 struct pim_instance
*pim
;
7694 int idx_interface
= 2;
7697 struct interface
*oif
;
7698 const char *oifname
;
7699 const char *grp_str
;
7700 struct in_addr grp_addr
;
7701 const char *src_str
;
7702 struct in_addr src_addr
;
7705 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
7708 oifname
= argv
[idx_interface
]->arg
;
7709 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
7711 vty_out(vty
, "No such interface name %s\n", oifname
);
7715 grp_str
= argv
[idx_ipv4
]->arg
;
7716 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
7718 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
7719 errno
, safe_strerror(errno
));
7723 src_str
= argv
[idx_ipv4_2
]->arg
;
7724 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
7726 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
7727 errno
, safe_strerror(errno
));
7731 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
7732 vty_out(vty
, "Failed to add route\n");
7739 DEFUN (interface_no_ip_mroute
,
7740 interface_no_ip_mroute_cmd
,
7741 "no ip mroute INTERFACE A.B.C.D",
7744 "Add multicast route\n"
7745 "Outgoing interface name\n"
7748 VTY_DECLVAR_CONTEXT(interface
, iif
);
7749 struct pim_interface
*pim_ifp
;
7750 struct pim_instance
*pim
;
7751 int idx_interface
= 3;
7753 struct interface
*oif
;
7754 const char *oifname
;
7755 const char *grp_str
;
7756 struct in_addr grp_addr
;
7757 struct in_addr src_addr
;
7760 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
7763 oifname
= argv
[idx_interface
]->arg
;
7764 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
7766 vty_out(vty
, "No such interface name %s\n", oifname
);
7770 grp_str
= argv
[idx_ipv4
]->arg
;
7771 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
7773 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
7774 errno
, safe_strerror(errno
));
7778 src_addr
.s_addr
= INADDR_ANY
;
7780 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
7781 vty_out(vty
, "Failed to remove route\n");
7788 DEFUN (interface_no_ip_mroute_source
,
7789 interface_no_ip_mroute_source_cmd
,
7790 "no ip mroute INTERFACE A.B.C.D A.B.C.D",
7793 "Add multicast route\n"
7794 "Outgoing interface name\n"
7798 VTY_DECLVAR_CONTEXT(interface
, iif
);
7799 struct pim_interface
*pim_ifp
;
7800 struct pim_instance
*pim
;
7801 int idx_interface
= 3;
7804 struct interface
*oif
;
7805 const char *oifname
;
7806 const char *grp_str
;
7807 struct in_addr grp_addr
;
7808 const char *src_str
;
7809 struct in_addr src_addr
;
7812 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
7815 oifname
= argv
[idx_interface
]->arg
;
7816 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
7818 vty_out(vty
, "No such interface name %s\n", oifname
);
7822 grp_str
= argv
[idx_ipv4
]->arg
;
7823 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
7825 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
7826 errno
, safe_strerror(errno
));
7830 src_str
= argv
[idx_ipv4_2
]->arg
;
7831 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
7833 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
7834 errno
, safe_strerror(errno
));
7838 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
7839 vty_out(vty
, "Failed to remove route\n");
7846 DEFUN (interface_ip_pim_hello
,
7847 interface_ip_pim_hello_cmd
,
7848 "ip pim hello (1-180) [(1-180)]",
7852 IFACE_PIM_HELLO_TIME_STR
7853 IFACE_PIM_HELLO_HOLD_STR
)
7855 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7858 struct pim_interface
*pim_ifp
= ifp
->info
;
7861 if (!pim_cmd_interface_add(ifp
)) {
7862 vty_out(vty
, "Could not enable PIM SM on interface\n");
7863 return CMD_WARNING_CONFIG_FAILED
;
7867 pim_ifp
= ifp
->info
;
7868 pim_ifp
->pim_hello_period
= strtol(argv
[idx_time
]->arg
, NULL
, 10);
7870 if (argc
== idx_hold
+ 1)
7871 pim_ifp
->pim_default_holdtime
=
7872 strtol(argv
[idx_hold
]->arg
, NULL
, 10);
7877 DEFUN (interface_no_ip_pim_hello
,
7878 interface_no_ip_pim_hello_cmd
,
7879 "no ip pim hello [(1-180) (1-180)]",
7884 IFACE_PIM_HELLO_TIME_STR
7885 IFACE_PIM_HELLO_HOLD_STR
)
7887 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7888 struct pim_interface
*pim_ifp
= ifp
->info
;
7891 vty_out(vty
, "Pim not enabled on this interface\n");
7892 return CMD_WARNING_CONFIG_FAILED
;
7895 pim_ifp
->pim_hello_period
= PIM_DEFAULT_HELLO_PERIOD
;
7896 pim_ifp
->pim_default_holdtime
= -1;
7907 PIM_DO_DEBUG_IGMP_EVENTS
;
7908 PIM_DO_DEBUG_IGMP_PACKETS
;
7909 PIM_DO_DEBUG_IGMP_TRACE
;
7913 DEFUN (no_debug_igmp
,
7920 PIM_DONT_DEBUG_IGMP_EVENTS
;
7921 PIM_DONT_DEBUG_IGMP_PACKETS
;
7922 PIM_DONT_DEBUG_IGMP_TRACE
;
7927 DEFUN (debug_igmp_events
,
7928 debug_igmp_events_cmd
,
7929 "debug igmp events",
7932 DEBUG_IGMP_EVENTS_STR
)
7934 PIM_DO_DEBUG_IGMP_EVENTS
;
7938 DEFUN (no_debug_igmp_events
,
7939 no_debug_igmp_events_cmd
,
7940 "no debug igmp events",
7944 DEBUG_IGMP_EVENTS_STR
)
7946 PIM_DONT_DEBUG_IGMP_EVENTS
;
7951 DEFUN (debug_igmp_packets
,
7952 debug_igmp_packets_cmd
,
7953 "debug igmp packets",
7956 DEBUG_IGMP_PACKETS_STR
)
7958 PIM_DO_DEBUG_IGMP_PACKETS
;
7962 DEFUN (no_debug_igmp_packets
,
7963 no_debug_igmp_packets_cmd
,
7964 "no debug igmp packets",
7968 DEBUG_IGMP_PACKETS_STR
)
7970 PIM_DONT_DEBUG_IGMP_PACKETS
;
7975 DEFUN (debug_igmp_trace
,
7976 debug_igmp_trace_cmd
,
7980 DEBUG_IGMP_TRACE_STR
)
7982 PIM_DO_DEBUG_IGMP_TRACE
;
7986 DEFUN (no_debug_igmp_trace
,
7987 no_debug_igmp_trace_cmd
,
7988 "no debug igmp trace",
7992 DEBUG_IGMP_TRACE_STR
)
7994 PIM_DONT_DEBUG_IGMP_TRACE
;
7999 DEFUN (debug_mroute
,
8005 PIM_DO_DEBUG_MROUTE
;
8009 DEFUN (debug_mroute_detail
,
8010 debug_mroute_detail_cmd
,
8011 "debug mroute detail",
8016 PIM_DO_DEBUG_MROUTE_DETAIL
;
8020 DEFUN (no_debug_mroute
,
8021 no_debug_mroute_cmd
,
8027 PIM_DONT_DEBUG_MROUTE
;
8031 DEFUN (no_debug_mroute_detail
,
8032 no_debug_mroute_detail_cmd
,
8033 "no debug mroute detail",
8039 PIM_DONT_DEBUG_MROUTE_DETAIL
;
8043 DEFUN (debug_pim_static
,
8044 debug_pim_static_cmd
,
8050 PIM_DO_DEBUG_STATIC
;
8054 DEFUN (no_debug_pim_static
,
8055 no_debug_pim_static_cmd
,
8056 "no debug pim static",
8062 PIM_DONT_DEBUG_STATIC
;
8073 PIM_DO_DEBUG_PIM_EVENTS
;
8074 PIM_DO_DEBUG_PIM_PACKETS
;
8075 PIM_DO_DEBUG_PIM_TRACE
;
8076 PIM_DO_DEBUG_MSDP_EVENTS
;
8077 PIM_DO_DEBUG_MSDP_PACKETS
;
8082 DEFUN (no_debug_pim
,
8089 PIM_DONT_DEBUG_PIM_EVENTS
;
8090 PIM_DONT_DEBUG_PIM_PACKETS
;
8091 PIM_DONT_DEBUG_PIM_TRACE
;
8092 PIM_DONT_DEBUG_MSDP_EVENTS
;
8093 PIM_DONT_DEBUG_MSDP_PACKETS
;
8095 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
8096 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
8102 DEFUN (debug_pim_nht
,
8107 "Nexthop Tracking\n")
8109 PIM_DO_DEBUG_PIM_NHT
;
8113 DEFUN (no_debug_pim_nht
,
8114 no_debug_pim_nht_cmd
,
8119 "Nexthop Tracking\n")
8121 PIM_DONT_DEBUG_PIM_NHT
;
8125 DEFUN (debug_pim_nht_rp
,
8126 debug_pim_nht_rp_cmd
,
8130 "Nexthop Tracking\n"
8131 "RP Nexthop Tracking\n")
8133 PIM_DO_DEBUG_PIM_NHT_RP
;
8137 DEFUN (no_debug_pim_nht_rp
,
8138 no_debug_pim_nht_rp_cmd
,
8139 "no debug pim nht rp",
8143 "Nexthop Tracking\n"
8144 "RP Nexthop Tracking\n")
8146 PIM_DONT_DEBUG_PIM_NHT_RP
;
8150 DEFUN (debug_pim_events
,
8151 debug_pim_events_cmd
,
8155 DEBUG_PIM_EVENTS_STR
)
8157 PIM_DO_DEBUG_PIM_EVENTS
;
8161 DEFUN (no_debug_pim_events
,
8162 no_debug_pim_events_cmd
,
8163 "no debug pim events",
8167 DEBUG_PIM_EVENTS_STR
)
8169 PIM_DONT_DEBUG_PIM_EVENTS
;
8173 DEFUN (debug_pim_packets
,
8174 debug_pim_packets_cmd
,
8175 "debug pim packets [<hello|joins|register>]",
8178 DEBUG_PIM_PACKETS_STR
8179 DEBUG_PIM_HELLO_PACKETS_STR
8180 DEBUG_PIM_J_P_PACKETS_STR
8181 DEBUG_PIM_PIM_REG_PACKETS_STR
)
8184 if (argv_find(argv
, argc
, "hello", &idx
)) {
8185 PIM_DO_DEBUG_PIM_HELLO
;
8186 vty_out(vty
, "PIM Hello debugging is on\n");
8187 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
8188 PIM_DO_DEBUG_PIM_J_P
;
8189 vty_out(vty
, "PIM Join/Prune debugging is on\n");
8190 } else if (argv_find(argv
, argc
, "register", &idx
)) {
8191 PIM_DO_DEBUG_PIM_REG
;
8192 vty_out(vty
, "PIM Register debugging is on\n");
8194 PIM_DO_DEBUG_PIM_PACKETS
;
8195 vty_out(vty
, "PIM Packet debugging is on \n");
8200 DEFUN (no_debug_pim_packets
,
8201 no_debug_pim_packets_cmd
,
8202 "no debug pim packets [<hello|joins|register>]",
8206 DEBUG_PIM_PACKETS_STR
8207 DEBUG_PIM_HELLO_PACKETS_STR
8208 DEBUG_PIM_J_P_PACKETS_STR
8209 DEBUG_PIM_PIM_REG_PACKETS_STR
)
8212 if (argv_find(argv
, argc
, "hello", &idx
)) {
8213 PIM_DONT_DEBUG_PIM_HELLO
;
8214 vty_out(vty
, "PIM Hello debugging is off \n");
8215 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
8216 PIM_DONT_DEBUG_PIM_J_P
;
8217 vty_out(vty
, "PIM Join/Prune debugging is off \n");
8218 } else if (argv_find(argv
, argc
, "register", &idx
)) {
8219 PIM_DONT_DEBUG_PIM_REG
;
8220 vty_out(vty
, "PIM Register debugging is off\n");
8222 PIM_DONT_DEBUG_PIM_PACKETS
;
8228 DEFUN (debug_pim_packetdump_send
,
8229 debug_pim_packetdump_send_cmd
,
8230 "debug pim packet-dump send",
8233 DEBUG_PIM_PACKETDUMP_STR
8234 DEBUG_PIM_PACKETDUMP_SEND_STR
)
8236 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND
;
8240 DEFUN (no_debug_pim_packetdump_send
,
8241 no_debug_pim_packetdump_send_cmd
,
8242 "no debug pim packet-dump send",
8246 DEBUG_PIM_PACKETDUMP_STR
8247 DEBUG_PIM_PACKETDUMP_SEND_STR
)
8249 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
8253 DEFUN (debug_pim_packetdump_recv
,
8254 debug_pim_packetdump_recv_cmd
,
8255 "debug pim packet-dump receive",
8258 DEBUG_PIM_PACKETDUMP_STR
8259 DEBUG_PIM_PACKETDUMP_RECV_STR
)
8261 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV
;
8265 DEFUN (no_debug_pim_packetdump_recv
,
8266 no_debug_pim_packetdump_recv_cmd
,
8267 "no debug pim packet-dump receive",
8271 DEBUG_PIM_PACKETDUMP_STR
8272 DEBUG_PIM_PACKETDUMP_RECV_STR
)
8274 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
8278 DEFUN (debug_pim_trace
,
8279 debug_pim_trace_cmd
,
8283 DEBUG_PIM_TRACE_STR
)
8285 PIM_DO_DEBUG_PIM_TRACE
;
8289 DEFUN (debug_pim_trace_detail
,
8290 debug_pim_trace_detail_cmd
,
8291 "debug pim trace detail",
8295 "Detailed Information\n")
8297 PIM_DO_DEBUG_PIM_TRACE_DETAIL
;
8301 DEFUN (no_debug_pim_trace
,
8302 no_debug_pim_trace_cmd
,
8303 "no debug pim trace",
8307 DEBUG_PIM_TRACE_STR
)
8309 PIM_DONT_DEBUG_PIM_TRACE
;
8313 DEFUN (no_debug_pim_trace_detail
,
8314 no_debug_pim_trace_detail_cmd
,
8315 "no debug pim trace detail",
8320 "Detailed Information\n")
8322 PIM_DONT_DEBUG_PIM_TRACE_DETAIL
;
8326 DEFUN (debug_ssmpingd
,
8332 PIM_DO_DEBUG_SSMPINGD
;
8336 DEFUN (no_debug_ssmpingd
,
8337 no_debug_ssmpingd_cmd
,
8338 "no debug ssmpingd",
8343 PIM_DONT_DEBUG_SSMPINGD
;
8347 DEFUN (debug_pim_zebra
,
8348 debug_pim_zebra_cmd
,
8352 DEBUG_PIM_ZEBRA_STR
)
8358 DEFUN (no_debug_pim_zebra
,
8359 no_debug_pim_zebra_cmd
,
8360 "no debug pim zebra",
8364 DEBUG_PIM_ZEBRA_STR
)
8366 PIM_DONT_DEBUG_ZEBRA
;
8370 DEFUN (debug_pim_vxlan
,
8371 debug_pim_vxlan_cmd
,
8375 DEBUG_PIM_VXLAN_STR
)
8381 DEFUN (no_debug_pim_vxlan
,
8382 no_debug_pim_vxlan_cmd
,
8383 "no debug pim vxlan",
8387 DEBUG_PIM_VXLAN_STR
)
8389 PIM_DONT_DEBUG_VXLAN
;
8399 PIM_DO_DEBUG_MSDP_EVENTS
;
8400 PIM_DO_DEBUG_MSDP_PACKETS
;
8404 DEFUN (no_debug_msdp
,
8411 PIM_DONT_DEBUG_MSDP_EVENTS
;
8412 PIM_DONT_DEBUG_MSDP_PACKETS
;
8416 DEFUN (debug_msdp_events
,
8417 debug_msdp_events_cmd
,
8418 "debug msdp events",
8421 DEBUG_MSDP_EVENTS_STR
)
8423 PIM_DO_DEBUG_MSDP_EVENTS
;
8427 DEFUN (no_debug_msdp_events
,
8428 no_debug_msdp_events_cmd
,
8429 "no debug msdp events",
8433 DEBUG_MSDP_EVENTS_STR
)
8435 PIM_DONT_DEBUG_MSDP_EVENTS
;
8439 DEFUN (debug_msdp_packets
,
8440 debug_msdp_packets_cmd
,
8441 "debug msdp packets",
8444 DEBUG_MSDP_PACKETS_STR
)
8446 PIM_DO_DEBUG_MSDP_PACKETS
;
8450 DEFUN (no_debug_msdp_packets
,
8451 no_debug_msdp_packets_cmd
,
8452 "no debug msdp packets",
8456 DEBUG_MSDP_PACKETS_STR
)
8458 PIM_DONT_DEBUG_MSDP_PACKETS
;
8462 DEFUN (debug_mtrace
,
8468 PIM_DO_DEBUG_MTRACE
;
8472 DEFUN (no_debug_mtrace
,
8473 no_debug_mtrace_cmd
,
8479 PIM_DONT_DEBUG_MTRACE
;
8494 DEFUN (no_debug_bsm
,
8507 DEFUN_NOSH (show_debugging_pim
,
8508 show_debugging_pim_cmd
,
8509 "show debugging [pim]",
8514 vty_out(vty
, "PIM debugging status\n");
8516 pim_debug_config_write(vty
);
8521 static int interface_pim_use_src_cmd_worker(struct vty
*vty
, const char *source
)
8524 struct in_addr source_addr
;
8525 int ret
= CMD_SUCCESS
;
8526 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8528 result
= inet_pton(AF_INET
, source
, &source_addr
);
8530 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", source
,
8531 errno
, safe_strerror(errno
));
8532 return CMD_WARNING_CONFIG_FAILED
;
8535 result
= pim_update_source_set(ifp
, source_addr
);
8539 case PIM_IFACE_NOT_FOUND
:
8540 ret
= CMD_WARNING_CONFIG_FAILED
;
8541 vty_out(vty
, "Pim not enabled on this interface\n");
8543 case PIM_UPDATE_SOURCE_DUP
:
8545 vty_out(vty
, "%% Source already set to %s\n", source
);
8548 ret
= CMD_WARNING_CONFIG_FAILED
;
8549 vty_out(vty
, "%% Source set failed\n");
8555 DEFUN (interface_pim_use_source
,
8556 interface_pim_use_source_cmd
,
8557 "ip pim use-source A.B.C.D",
8560 "Configure primary IP address\n"
8561 "source ip address\n")
8563 return interface_pim_use_src_cmd_worker(vty
, argv
[3]->arg
);
8566 DEFUN (interface_no_pim_use_source
,
8567 interface_no_pim_use_source_cmd
,
8568 "no ip pim use-source [A.B.C.D]",
8572 "Delete source IP address\n"
8573 "source ip address\n")
8575 return interface_pim_use_src_cmd_worker(vty
, "0.0.0.0");
8583 "Enables BFD support\n")
8585 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8586 struct pim_interface
*pim_ifp
= ifp
->info
;
8587 struct bfd_info
*bfd_info
= NULL
;
8590 if (!pim_cmd_interface_add(ifp
)) {
8591 vty_out(vty
, "Could not enable PIM SM on interface\n");
8595 pim_ifp
= ifp
->info
;
8597 bfd_info
= pim_ifp
->bfd_info
;
8599 if (!bfd_info
|| !CHECK_FLAG(bfd_info
->flags
, BFD_FLAG_PARAM_CFG
))
8600 pim_bfd_if_param_set(ifp
, BFD_DEF_MIN_RX
, BFD_DEF_MIN_TX
,
8601 BFD_DEF_DETECT_MULT
, 1);
8606 DEFUN (no_ip_pim_bfd
,
8612 "Disables BFD support\n")
8614 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8615 struct pim_interface
*pim_ifp
= ifp
->info
;
8618 vty_out(vty
, "Pim not enabled on this interface\n");
8622 if (pim_ifp
->bfd_info
) {
8623 pim_bfd_reg_dereg_all_nbr(ifp
, ZEBRA_BFD_DEST_DEREGISTER
);
8624 bfd_info_free(&(pim_ifp
->bfd_info
));
8635 "Enables BSM support on the interface\n")
8637 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8638 struct pim_interface
*pim_ifp
= ifp
->info
;
8641 if (!pim_cmd_interface_add(ifp
)) {
8642 vty_out(vty
, "Could not enable PIM SM on interface\n");
8647 pim_ifp
= ifp
->info
;
8648 pim_ifp
->bsm_enable
= true;
8653 DEFUN (no_ip_pim_bsm
,
8659 "Disables BSM support\n")
8661 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8662 struct pim_interface
*pim_ifp
= ifp
->info
;
8665 vty_out(vty
, "Pim not enabled on this interface\n");
8669 pim_ifp
->bsm_enable
= false;
8674 DEFUN (ip_pim_ucast_bsm
,
8675 ip_pim_ucast_bsm_cmd
,
8676 "ip pim unicast-bsm",
8679 "Accept/Send unicast BSM on the interface\n")
8681 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8682 struct pim_interface
*pim_ifp
= ifp
->info
;
8685 if (!pim_cmd_interface_add(ifp
)) {
8686 vty_out(vty
, "Could not enable PIM SM on interface\n");
8691 pim_ifp
= ifp
->info
;
8692 pim_ifp
->ucast_bsm_accept
= true;
8697 DEFUN (no_ip_pim_ucast_bsm
,
8698 no_ip_pim_ucast_bsm_cmd
,
8699 "no ip pim unicast-bsm",
8703 "Block send/receive unicast BSM on this interface\n")
8705 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8706 struct pim_interface
*pim_ifp
= ifp
->info
;
8709 vty_out(vty
, "Pim not enabled on this interface\n");
8713 pim_ifp
->ucast_bsm_accept
= false;
8722 #endif /* HAVE_BFDD */
8724 ip_pim_bfd_param_cmd
,
8725 "ip pim bfd (2-255) (50-60000) (50-60000)",
8728 "Enables BFD support\n"
8729 "Detect Multiplier\n"
8730 "Required min receive interval\n"
8731 "Desired min transmit interval\n")
8733 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8735 int idx_number_2
= 4;
8736 int idx_number_3
= 5;
8741 struct pim_interface
*pim_ifp
= ifp
->info
;
8744 if (!pim_cmd_interface_add(ifp
)) {
8745 vty_out(vty
, "Could not enable PIM SM on interface\n");
8750 if ((ret
= bfd_validate_param(
8751 vty
, argv
[idx_number
]->arg
, argv
[idx_number_2
]->arg
,
8752 argv
[idx_number_3
]->arg
, &dm_val
, &rx_val
, &tx_val
))
8756 pim_bfd_if_param_set(ifp
, rx_val
, tx_val
, dm_val
, 0);
8762 ALIAS(no_ip_pim_bfd
, no_ip_pim_bfd_param_cmd
,
8763 "no ip pim bfd (2-255) (50-60000) (50-60000)", NO_STR IP_STR PIM_STR
8764 "Enables BFD support\n"
8765 "Detect Multiplier\n"
8766 "Required min receive interval\n"
8767 "Desired min transmit interval\n")
8768 #endif /* !HAVE_BFDD */
8770 static int ip_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
8771 const char *peer
, const char *local
)
8773 enum pim_msdp_err result
;
8774 struct in_addr peer_addr
;
8775 struct in_addr local_addr
;
8776 int ret
= CMD_SUCCESS
;
8778 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
8780 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
8781 errno
, safe_strerror(errno
));
8782 return CMD_WARNING_CONFIG_FAILED
;
8785 result
= inet_pton(AF_INET
, local
, &local_addr
);
8787 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", local
,
8788 errno
, safe_strerror(errno
));
8789 return CMD_WARNING_CONFIG_FAILED
;
8792 result
= pim_msdp_peer_add(pim
, peer_addr
, local_addr
, "default",
8795 case PIM_MSDP_ERR_NONE
:
8797 case PIM_MSDP_ERR_OOM
:
8798 ret
= CMD_WARNING_CONFIG_FAILED
;
8799 vty_out(vty
, "%% Out of memory\n");
8801 case PIM_MSDP_ERR_PEER_EXISTS
:
8803 vty_out(vty
, "%% Peer exists\n");
8805 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
8806 ret
= CMD_WARNING_CONFIG_FAILED
;
8807 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
8810 ret
= CMD_WARNING_CONFIG_FAILED
;
8811 vty_out(vty
, "%% peer add failed\n");
8817 DEFUN_HIDDEN (ip_msdp_peer
,
8819 "ip msdp peer A.B.C.D source A.B.C.D",
8822 "Configure MSDP peer\n"
8824 "Source address for TCP connection\n"
8825 "local ip address\n")
8827 PIM_DECLVAR_CONTEXT(vrf
, pim
);
8828 return ip_msdp_peer_cmd_worker(pim
, vty
, argv
[3]->arg
, argv
[5]->arg
);
8831 static int ip_no_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
8834 enum pim_msdp_err result
;
8835 struct in_addr peer_addr
;
8837 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
8839 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
8840 errno
, safe_strerror(errno
));
8841 return CMD_WARNING_CONFIG_FAILED
;
8844 result
= pim_msdp_peer_del(pim
, peer_addr
);
8846 case PIM_MSDP_ERR_NONE
:
8848 case PIM_MSDP_ERR_NO_PEER
:
8849 vty_out(vty
, "%% Peer does not exist\n");
8852 vty_out(vty
, "%% peer del failed\n");
8855 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
8858 DEFUN_HIDDEN (no_ip_msdp_peer
,
8859 no_ip_msdp_peer_cmd
,
8860 "no ip msdp peer A.B.C.D",
8864 "Delete MSDP peer\n"
8865 "peer ip address\n")
8867 PIM_DECLVAR_CONTEXT(vrf
, pim
);
8868 return ip_no_msdp_peer_cmd_worker(pim
, vty
, argv
[4]->arg
);
8871 static int ip_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
8872 struct vty
*vty
, const char *mg
,
8875 enum pim_msdp_err result
;
8876 struct in_addr mbr_ip
;
8877 int ret
= CMD_SUCCESS
;
8879 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
8881 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
8882 errno
, safe_strerror(errno
));
8883 return CMD_WARNING_CONFIG_FAILED
;
8886 result
= pim_msdp_mg_mbr_add(pim
, mg
, mbr_ip
);
8888 case PIM_MSDP_ERR_NONE
:
8890 case PIM_MSDP_ERR_OOM
:
8891 ret
= CMD_WARNING_CONFIG_FAILED
;
8892 vty_out(vty
, "%% Out of memory\n");
8894 case PIM_MSDP_ERR_MG_MBR_EXISTS
:
8896 vty_out(vty
, "%% mesh-group member exists\n");
8898 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
8899 ret
= CMD_WARNING_CONFIG_FAILED
;
8900 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
8903 ret
= CMD_WARNING_CONFIG_FAILED
;
8904 vty_out(vty
, "%% member add failed\n");
8910 DEFUN (ip_msdp_mesh_group_member
,
8911 ip_msdp_mesh_group_member_cmd
,
8912 "ip msdp mesh-group WORD member A.B.C.D",
8915 "Configure MSDP mesh-group\n"
8917 "mesh group member\n"
8918 "peer ip address\n")
8920 PIM_DECLVAR_CONTEXT(vrf
, pim
);
8921 return ip_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[3]->arg
,
8925 static int ip_no_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
8930 enum pim_msdp_err result
;
8931 struct in_addr mbr_ip
;
8933 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
8935 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
8936 errno
, safe_strerror(errno
));
8937 return CMD_WARNING_CONFIG_FAILED
;
8940 result
= pim_msdp_mg_mbr_del(pim
, mg
, mbr_ip
);
8942 case PIM_MSDP_ERR_NONE
:
8944 case PIM_MSDP_ERR_NO_MG
:
8945 vty_out(vty
, "%% mesh-group does not exist\n");
8947 case PIM_MSDP_ERR_NO_MG_MBR
:
8948 vty_out(vty
, "%% mesh-group member does not exist\n");
8951 vty_out(vty
, "%% mesh-group member del failed\n");
8954 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
8956 DEFUN (no_ip_msdp_mesh_group_member
,
8957 no_ip_msdp_mesh_group_member_cmd
,
8958 "no ip msdp mesh-group WORD member A.B.C.D",
8962 "Delete MSDP mesh-group member\n"
8964 "mesh group member\n"
8965 "peer ip address\n")
8967 PIM_DECLVAR_CONTEXT(vrf
, pim
);
8968 return ip_no_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[4]->arg
,
8972 static int ip_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
8973 struct vty
*vty
, const char *mg
,
8976 enum pim_msdp_err result
;
8977 struct in_addr src_ip
;
8979 result
= inet_pton(AF_INET
, src
, &src_ip
);
8981 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", src
,
8982 errno
, safe_strerror(errno
));
8983 return CMD_WARNING_CONFIG_FAILED
;
8986 result
= pim_msdp_mg_src_add(pim
, mg
, src_ip
);
8988 case PIM_MSDP_ERR_NONE
:
8990 case PIM_MSDP_ERR_OOM
:
8991 vty_out(vty
, "%% Out of memory\n");
8993 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
8994 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
8997 vty_out(vty
, "%% source add failed\n");
9000 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9004 DEFUN (ip_msdp_mesh_group_source
,
9005 ip_msdp_mesh_group_source_cmd
,
9006 "ip msdp mesh-group WORD source A.B.C.D",
9009 "Configure MSDP mesh-group\n"
9011 "mesh group local address\n"
9012 "source ip address for the TCP connection\n")
9014 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9015 return ip_msdp_mesh_group_source_cmd_worker(pim
, vty
, argv
[3]->arg
,
9019 static int ip_no_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
9023 enum pim_msdp_err result
;
9025 result
= pim_msdp_mg_src_del(pim
, mg
);
9027 case PIM_MSDP_ERR_NONE
:
9029 case PIM_MSDP_ERR_NO_MG
:
9030 vty_out(vty
, "%% mesh-group does not exist\n");
9033 vty_out(vty
, "%% mesh-group source del failed\n");
9036 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9039 static int ip_no_msdp_mesh_group_cmd_worker(struct pim_instance
*pim
,
9040 struct vty
*vty
, const char *mg
)
9042 enum pim_msdp_err result
;
9044 result
= pim_msdp_mg_del(pim
, mg
);
9046 case PIM_MSDP_ERR_NONE
:
9048 case PIM_MSDP_ERR_NO_MG
:
9049 vty_out(vty
, "%% mesh-group does not exist\n");
9052 vty_out(vty
, "%% mesh-group source del failed\n");
9055 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9058 DEFUN (no_ip_msdp_mesh_group_source
,
9059 no_ip_msdp_mesh_group_source_cmd
,
9060 "no ip msdp mesh-group WORD source [A.B.C.D]",
9064 "Delete MSDP mesh-group source\n"
9066 "mesh group source\n"
9067 "mesh group local address\n")
9069 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9071 return ip_no_msdp_mesh_group_cmd_worker(pim
, vty
, argv
[6]->arg
);
9073 return ip_no_msdp_mesh_group_source_cmd_worker(pim
, vty
,
9077 static void print_empty_json_obj(struct vty
*vty
)
9080 json
= json_object_new_object();
9081 vty_out(vty
, "%s\n",
9082 json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
));
9083 json_object_free(json
);
9086 static void ip_msdp_show_mesh_group(struct pim_instance
*pim
, struct vty
*vty
,
9089 struct listnode
*mbrnode
;
9090 struct pim_msdp_mg_mbr
*mbr
;
9091 struct pim_msdp_mg
*mg
= pim
->msdp
.mg
;
9092 char mbr_str
[INET_ADDRSTRLEN
];
9093 char src_str
[INET_ADDRSTRLEN
];
9094 char state_str
[PIM_MSDP_STATE_STRLEN
];
9095 enum pim_msdp_peer_state state
;
9096 json_object
*json
= NULL
;
9097 json_object
*json_mg_row
= NULL
;
9098 json_object
*json_members
= NULL
;
9099 json_object
*json_row
= NULL
;
9103 print_empty_json_obj(vty
);
9107 pim_inet4_dump("<source?>", mg
->src_ip
, src_str
, sizeof(src_str
));
9109 json
= json_object_new_object();
9110 /* currently there is only one mesh group but we should still
9112 * it a dict with mg-name as key */
9113 json_mg_row
= json_object_new_object();
9114 json_object_string_add(json_mg_row
, "name",
9115 mg
->mesh_group_name
);
9116 json_object_string_add(json_mg_row
, "source", src_str
);
9118 vty_out(vty
, "Mesh group : %s\n", mg
->mesh_group_name
);
9119 vty_out(vty
, " Source : %s\n", src_str
);
9120 vty_out(vty
, " Member State\n");
9123 for (ALL_LIST_ELEMENTS_RO(mg
->mbr_list
, mbrnode
, mbr
)) {
9124 pim_inet4_dump("<mbr?>", mbr
->mbr_ip
, mbr_str
, sizeof(mbr_str
));
9126 state
= mbr
->mp
->state
;
9128 state
= PIM_MSDP_DISABLED
;
9130 pim_msdp_state_dump(state
, state_str
, sizeof(state_str
));
9132 json_row
= json_object_new_object();
9133 json_object_string_add(json_row
, "member", mbr_str
);
9134 json_object_string_add(json_row
, "state", state_str
);
9135 if (!json_members
) {
9136 json_members
= json_object_new_object();
9137 json_object_object_add(json_mg_row
, "members",
9140 json_object_object_add(json_members
, mbr_str
, json_row
);
9142 vty_out(vty
, " %-15s %11s\n", mbr_str
, state_str
);
9147 json_object_object_add(json
, mg
->mesh_group_name
, json_mg_row
);
9148 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9149 json
, JSON_C_TO_STRING_PRETTY
));
9150 json_object_free(json
);
9154 DEFUN (show_ip_msdp_mesh_group
,
9155 show_ip_msdp_mesh_group_cmd
,
9156 "show ip msdp [vrf NAME] mesh-group [json]",
9161 "MSDP mesh-group information\n"
9164 bool uj
= use_json(argc
, argv
);
9166 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
9171 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
9176 DEFUN (show_ip_msdp_mesh_group_vrf_all
,
9177 show_ip_msdp_mesh_group_vrf_all_cmd
,
9178 "show ip msdp vrf all mesh-group [json]",
9183 "MSDP mesh-group information\n"
9186 bool uj
= use_json(argc
, argv
);
9192 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
9196 vty_out(vty
, " \"%s\": ", vrf
->name
);
9199 vty_out(vty
, "VRF: %s\n", vrf
->name
);
9200 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
9203 vty_out(vty
, "}\n");
9208 static void ip_msdp_show_peers(struct pim_instance
*pim
, struct vty
*vty
,
9211 struct listnode
*mpnode
;
9212 struct pim_msdp_peer
*mp
;
9213 char peer_str
[INET_ADDRSTRLEN
];
9214 char local_str
[INET_ADDRSTRLEN
];
9215 char state_str
[PIM_MSDP_STATE_STRLEN
];
9216 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
9218 json_object
*json
= NULL
;
9219 json_object
*json_row
= NULL
;
9223 json
= json_object_new_object();
9226 "Peer Local State Uptime SaCnt\n");
9229 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
9230 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
9231 now
= pim_time_monotonic_sec();
9232 pim_time_uptime(timebuf
, sizeof(timebuf
),
9235 strlcpy(timebuf
, "-", sizeof(timebuf
));
9237 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
9238 pim_inet4_dump("<local?>", mp
->local
, local_str
,
9240 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
9242 json_row
= json_object_new_object();
9243 json_object_string_add(json_row
, "peer", peer_str
);
9244 json_object_string_add(json_row
, "local", local_str
);
9245 json_object_string_add(json_row
, "state", state_str
);
9246 json_object_string_add(json_row
, "upTime", timebuf
);
9247 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
9248 json_object_object_add(json
, peer_str
, json_row
);
9250 vty_out(vty
, "%-15s %15s %11s %8s %6d\n", peer_str
,
9251 local_str
, state_str
, timebuf
, mp
->sa_cnt
);
9256 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9257 json
, JSON_C_TO_STRING_PRETTY
));
9258 json_object_free(json
);
9262 static void ip_msdp_show_peers_detail(struct pim_instance
*pim
, struct vty
*vty
,
9263 const char *peer
, bool uj
)
9265 struct listnode
*mpnode
;
9266 struct pim_msdp_peer
*mp
;
9267 char peer_str
[INET_ADDRSTRLEN
];
9268 char local_str
[INET_ADDRSTRLEN
];
9269 char state_str
[PIM_MSDP_STATE_STRLEN
];
9270 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
9271 char katimer
[PIM_MSDP_TIMER_STRLEN
];
9272 char crtimer
[PIM_MSDP_TIMER_STRLEN
];
9273 char holdtimer
[PIM_MSDP_TIMER_STRLEN
];
9275 json_object
*json
= NULL
;
9276 json_object
*json_row
= NULL
;
9279 json
= json_object_new_object();
9282 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
9283 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
9284 if (strcmp(peer
, "detail") && strcmp(peer
, peer_str
))
9287 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
9288 now
= pim_time_monotonic_sec();
9289 pim_time_uptime(timebuf
, sizeof(timebuf
),
9292 strlcpy(timebuf
, "-", sizeof(timebuf
));
9294 pim_inet4_dump("<local?>", mp
->local
, local_str
,
9296 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
9297 pim_time_timer_to_hhmmss(katimer
, sizeof(katimer
),
9299 pim_time_timer_to_hhmmss(crtimer
, sizeof(crtimer
),
9301 pim_time_timer_to_hhmmss(holdtimer
, sizeof(holdtimer
),
9305 json_row
= json_object_new_object();
9306 json_object_string_add(json_row
, "peer", peer_str
);
9307 json_object_string_add(json_row
, "local", local_str
);
9308 json_object_string_add(json_row
, "meshGroupName",
9309 mp
->mesh_group_name
);
9310 json_object_string_add(json_row
, "state", state_str
);
9311 json_object_string_add(json_row
, "upTime", timebuf
);
9312 json_object_string_add(json_row
, "keepAliveTimer",
9314 json_object_string_add(json_row
, "connRetryTimer",
9316 json_object_string_add(json_row
, "holdTimer",
9318 json_object_string_add(json_row
, "lastReset",
9320 json_object_int_add(json_row
, "connAttempts",
9322 json_object_int_add(json_row
, "establishedChanges",
9324 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
9325 json_object_int_add(json_row
, "kaSent", mp
->ka_tx_cnt
);
9326 json_object_int_add(json_row
, "kaRcvd", mp
->ka_rx_cnt
);
9327 json_object_int_add(json_row
, "saSent", mp
->sa_tx_cnt
);
9328 json_object_int_add(json_row
, "saRcvd", mp
->sa_rx_cnt
);
9329 json_object_object_add(json
, peer_str
, json_row
);
9331 vty_out(vty
, "Peer : %s\n", peer_str
);
9332 vty_out(vty
, " Local : %s\n", local_str
);
9333 vty_out(vty
, " Mesh Group : %s\n",
9334 mp
->mesh_group_name
);
9335 vty_out(vty
, " State : %s\n", state_str
);
9336 vty_out(vty
, " Uptime : %s\n", timebuf
);
9338 vty_out(vty
, " Keepalive Timer : %s\n", katimer
);
9339 vty_out(vty
, " Conn Retry Timer : %s\n", crtimer
);
9340 vty_out(vty
, " Hold Timer : %s\n", holdtimer
);
9341 vty_out(vty
, " Last Reset : %s\n",
9343 vty_out(vty
, " Conn Attempts : %d\n",
9345 vty_out(vty
, " Established Changes : %d\n",
9347 vty_out(vty
, " SA Count : %d\n",
9349 vty_out(vty
, " Statistics :\n");
9352 vty_out(vty
, " Keepalives : %10d %10d\n",
9353 mp
->ka_tx_cnt
, mp
->ka_rx_cnt
);
9354 vty_out(vty
, " SAs : %10d %10d\n",
9355 mp
->sa_tx_cnt
, mp
->sa_rx_cnt
);
9361 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9362 json
, JSON_C_TO_STRING_PRETTY
));
9363 json_object_free(json
);
9367 DEFUN (show_ip_msdp_peer_detail
,
9368 show_ip_msdp_peer_detail_cmd
,
9369 "show ip msdp [vrf NAME] peer [detail|A.B.C.D] [json]",
9374 "MSDP peer information\n"
9379 bool uj
= use_json(argc
, argv
);
9381 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
9388 if (argv_find(argv
, argc
, "detail", &idx
))
9389 arg
= argv
[idx
]->text
;
9390 else if (argv_find(argv
, argc
, "A.B.C.D", &idx
))
9391 arg
= argv
[idx
]->arg
;
9394 ip_msdp_show_peers_detail(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
9396 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
9401 DEFUN (show_ip_msdp_peer_detail_vrf_all
,
9402 show_ip_msdp_peer_detail_vrf_all_cmd
,
9403 "show ip msdp vrf all peer [detail|A.B.C.D] [json]",
9408 "MSDP peer information\n"
9414 bool uj
= use_json(argc
, argv
);
9420 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
9424 vty_out(vty
, " \"%s\": ", vrf
->name
);
9427 vty_out(vty
, "VRF: %s\n", vrf
->name
);
9428 if (argv_find(argv
, argc
, "detail", &idx
)
9429 || argv_find(argv
, argc
, "A.B.C.D", &idx
))
9430 ip_msdp_show_peers_detail(vrf
->info
, vty
,
9431 argv
[idx
]->arg
, uj
);
9433 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
9436 vty_out(vty
, "}\n");
9441 static void ip_msdp_show_sa(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
9443 struct listnode
*sanode
;
9444 struct pim_msdp_sa
*sa
;
9445 char src_str
[INET_ADDRSTRLEN
];
9446 char grp_str
[INET_ADDRSTRLEN
];
9447 char rp_str
[INET_ADDRSTRLEN
];
9448 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
9452 json_object
*json
= NULL
;
9453 json_object
*json_group
= NULL
;
9454 json_object
*json_row
= NULL
;
9457 json
= json_object_new_object();
9460 "Source Group RP Local SPT Uptime\n");
9463 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
9464 now
= pim_time_monotonic_sec();
9465 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
9466 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
9467 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
9468 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
9469 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
9471 strlcpy(spt_str
, "yes", sizeof(spt_str
));
9473 strlcpy(spt_str
, "no", sizeof(spt_str
));
9476 strlcpy(rp_str
, "-", sizeof(rp_str
));
9477 strlcpy(spt_str
, "-", sizeof(spt_str
));
9479 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
9480 strlcpy(local_str
, "yes", sizeof(local_str
));
9482 strlcpy(local_str
, "no", sizeof(local_str
));
9485 json_object_object_get_ex(json
, grp_str
, &json_group
);
9488 json_group
= json_object_new_object();
9489 json_object_object_add(json
, grp_str
,
9493 json_row
= json_object_new_object();
9494 json_object_string_add(json_row
, "source", src_str
);
9495 json_object_string_add(json_row
, "group", grp_str
);
9496 json_object_string_add(json_row
, "rp", rp_str
);
9497 json_object_string_add(json_row
, "local", local_str
);
9498 json_object_string_add(json_row
, "sptSetup", spt_str
);
9499 json_object_string_add(json_row
, "upTime", timebuf
);
9500 json_object_object_add(json_group
, src_str
, json_row
);
9502 vty_out(vty
, "%-15s %15s %15s %5c %3c %8s\n",
9503 src_str
, grp_str
, rp_str
, local_str
[0],
9504 spt_str
[0], timebuf
);
9509 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9510 json
, JSON_C_TO_STRING_PRETTY
));
9511 json_object_free(json
);
9515 static void ip_msdp_show_sa_entry_detail(struct pim_msdp_sa
*sa
,
9516 const char *src_str
,
9517 const char *grp_str
, struct vty
*vty
,
9518 bool uj
, json_object
*json
)
9520 char rp_str
[INET_ADDRSTRLEN
];
9521 char peer_str
[INET_ADDRSTRLEN
];
9522 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
9525 char statetimer
[PIM_MSDP_TIMER_STRLEN
];
9527 json_object
*json_group
= NULL
;
9528 json_object
*json_row
= NULL
;
9530 now
= pim_time_monotonic_sec();
9531 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
9532 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
9533 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
9534 pim_inet4_dump("<peer?>", sa
->peer
, peer_str
, sizeof(peer_str
));
9536 strlcpy(spt_str
, "yes", sizeof(spt_str
));
9538 strlcpy(spt_str
, "no", sizeof(spt_str
));
9541 strlcpy(rp_str
, "-", sizeof(rp_str
));
9542 strlcpy(peer_str
, "-", sizeof(peer_str
));
9543 strlcpy(spt_str
, "-", sizeof(spt_str
));
9545 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
9546 strlcpy(local_str
, "yes", sizeof(local_str
));
9548 strlcpy(local_str
, "no", sizeof(local_str
));
9550 pim_time_timer_to_hhmmss(statetimer
, sizeof(statetimer
),
9551 sa
->sa_state_timer
);
9553 json_object_object_get_ex(json
, grp_str
, &json_group
);
9556 json_group
= json_object_new_object();
9557 json_object_object_add(json
, grp_str
, json_group
);
9560 json_row
= json_object_new_object();
9561 json_object_string_add(json_row
, "source", src_str
);
9562 json_object_string_add(json_row
, "group", grp_str
);
9563 json_object_string_add(json_row
, "rp", rp_str
);
9564 json_object_string_add(json_row
, "local", local_str
);
9565 json_object_string_add(json_row
, "sptSetup", spt_str
);
9566 json_object_string_add(json_row
, "upTime", timebuf
);
9567 json_object_string_add(json_row
, "stateTimer", statetimer
);
9568 json_object_object_add(json_group
, src_str
, json_row
);
9570 vty_out(vty
, "SA : %s\n", sa
->sg_str
);
9571 vty_out(vty
, " RP : %s\n", rp_str
);
9572 vty_out(vty
, " Peer : %s\n", peer_str
);
9573 vty_out(vty
, " Local : %s\n", local_str
);
9574 vty_out(vty
, " SPT Setup : %s\n", spt_str
);
9575 vty_out(vty
, " Uptime : %s\n", timebuf
);
9576 vty_out(vty
, " State Timer : %s\n", statetimer
);
9581 static void ip_msdp_show_sa_detail(struct pim_instance
*pim
, struct vty
*vty
,
9584 struct listnode
*sanode
;
9585 struct pim_msdp_sa
*sa
;
9586 char src_str
[INET_ADDRSTRLEN
];
9587 char grp_str
[INET_ADDRSTRLEN
];
9588 json_object
*json
= NULL
;
9591 json
= json_object_new_object();
9594 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
9595 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
9596 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
9597 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
, uj
,
9602 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9603 json
, JSON_C_TO_STRING_PRETTY
));
9604 json_object_free(json
);
9608 DEFUN (show_ip_msdp_sa_detail
,
9609 show_ip_msdp_sa_detail_cmd
,
9610 "show ip msdp [vrf NAME] sa detail [json]",
9615 "MSDP active-source information\n"
9619 bool uj
= use_json(argc
, argv
);
9621 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
9626 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
9631 DEFUN (show_ip_msdp_sa_detail_vrf_all
,
9632 show_ip_msdp_sa_detail_vrf_all_cmd
,
9633 "show ip msdp vrf all sa detail [json]",
9638 "MSDP active-source information\n"
9642 bool uj
= use_json(argc
, argv
);
9648 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
9652 vty_out(vty
, " \"%s\": ", vrf
->name
);
9655 vty_out(vty
, "VRF: %s\n", vrf
->name
);
9656 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
9659 vty_out(vty
, "}\n");
9664 static void ip_msdp_show_sa_addr(struct pim_instance
*pim
, struct vty
*vty
,
9665 const char *addr
, bool uj
)
9667 struct listnode
*sanode
;
9668 struct pim_msdp_sa
*sa
;
9669 char src_str
[INET_ADDRSTRLEN
];
9670 char grp_str
[INET_ADDRSTRLEN
];
9671 json_object
*json
= NULL
;
9674 json
= json_object_new_object();
9677 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
9678 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
9679 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
9680 if (!strcmp(addr
, src_str
) || !strcmp(addr
, grp_str
)) {
9681 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
9687 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9688 json
, JSON_C_TO_STRING_PRETTY
));
9689 json_object_free(json
);
9693 static void ip_msdp_show_sa_sg(struct pim_instance
*pim
, struct vty
*vty
,
9694 const char *src
, const char *grp
, bool uj
)
9696 struct listnode
*sanode
;
9697 struct pim_msdp_sa
*sa
;
9698 char src_str
[INET_ADDRSTRLEN
];
9699 char grp_str
[INET_ADDRSTRLEN
];
9700 json_object
*json
= NULL
;
9703 json
= json_object_new_object();
9706 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
9707 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
9708 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
9709 if (!strcmp(src
, src_str
) && !strcmp(grp
, grp_str
)) {
9710 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
9716 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9717 json
, JSON_C_TO_STRING_PRETTY
));
9718 json_object_free(json
);
9722 DEFUN (show_ip_msdp_sa_sg
,
9723 show_ip_msdp_sa_sg_cmd
,
9724 "show ip msdp [vrf NAME] sa [A.B.C.D [A.B.C.D]] [json]",
9729 "MSDP active-source information\n"
9730 "source or group ip\n"
9734 bool uj
= use_json(argc
, argv
);
9738 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
9743 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
9745 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
9749 if (src_ip
&& grp_ip
)
9750 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
9752 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
9754 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
9759 DEFUN (show_ip_msdp_sa_sg_vrf_all
,
9760 show_ip_msdp_sa_sg_vrf_all_cmd
,
9761 "show ip msdp vrf all sa [A.B.C.D [A.B.C.D]] [json]",
9766 "MSDP active-source information\n"
9767 "source or group ip\n"
9771 bool uj
= use_json(argc
, argv
);
9776 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
9778 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
9784 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
9788 vty_out(vty
, " \"%s\": ", vrf
->name
);
9791 vty_out(vty
, "VRF: %s\n", vrf
->name
);
9793 if (src_ip
&& grp_ip
)
9794 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
9796 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
9798 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
9801 vty_out(vty
, "}\n");
9806 struct pim_sg_cache_walk_data
{
9809 json_object
*json_group
;
9810 struct in_addr addr
;
9814 static void pim_show_vxlan_sg_entry(struct pim_vxlan_sg
*vxlan_sg
,
9815 struct pim_sg_cache_walk_data
*cwd
)
9817 struct vty
*vty
= cwd
->vty
;
9818 json_object
*json
= cwd
->json
;
9819 char src_str
[INET_ADDRSTRLEN
];
9820 char grp_str
[INET_ADDRSTRLEN
];
9821 json_object
*json_row
;
9822 bool installed
= (vxlan_sg
->up
)?TRUE
:FALSE
;
9823 const char *iif_name
= vxlan_sg
->iif
?vxlan_sg
->iif
->name
:"-";
9824 const char *oif_name
;
9826 if (pim_vxlan_is_orig_mroute(vxlan_sg
))
9827 oif_name
= vxlan_sg
->orig_oif
?vxlan_sg
->orig_oif
->name
:"";
9829 oif_name
= vxlan_sg
->term_oif
?vxlan_sg
->term_oif
->name
:"";
9831 if (cwd
->addr_match
&& (vxlan_sg
->sg
.src
.s_addr
!= cwd
->addr
.s_addr
) &&
9832 (vxlan_sg
->sg
.grp
.s_addr
!= cwd
->addr
.s_addr
)) {
9835 pim_inet4_dump("<src?>", vxlan_sg
->sg
.src
, src_str
, sizeof(src_str
));
9836 pim_inet4_dump("<grp?>", vxlan_sg
->sg
.grp
, grp_str
, sizeof(grp_str
));
9838 json_object_object_get_ex(json
, grp_str
, &cwd
->json_group
);
9840 if (!cwd
->json_group
) {
9841 cwd
->json_group
= json_object_new_object();
9842 json_object_object_add(json
, grp_str
,
9846 json_row
= json_object_new_object();
9847 json_object_string_add(json_row
, "source", src_str
);
9848 json_object_string_add(json_row
, "group", grp_str
);
9849 json_object_string_add(json_row
, "input", iif_name
);
9850 json_object_string_add(json_row
, "output", oif_name
);
9852 json_object_boolean_true_add(json_row
, "installed");
9854 json_object_boolean_false_add(json_row
, "installed");
9855 json_object_object_add(cwd
->json_group
, src_str
, json_row
);
9857 vty_out(vty
, "%-15s %-15s %-15s %-15s %-5s\n",
9858 src_str
, grp_str
, iif_name
, oif_name
,
9863 static void pim_show_vxlan_sg_hash_entry(struct hash_backet
*backet
, void *arg
)
9865 pim_show_vxlan_sg_entry((struct pim_vxlan_sg
*)backet
->data
,
9866 (struct pim_sg_cache_walk_data
*)arg
);
9869 static void pim_show_vxlan_sg(struct pim_instance
*pim
,
9870 struct vty
*vty
, bool uj
)
9872 json_object
*json
= NULL
;
9873 struct pim_sg_cache_walk_data cwd
;
9876 json
= json_object_new_object();
9878 vty_out(vty
, "Codes: I -> installed\n");
9880 "Source Group Input Output Flags\n");
9883 memset(&cwd
, 0, sizeof(cwd
));
9886 hash_iterate(pim
->vxlan
.sg_hash
, pim_show_vxlan_sg_hash_entry
, &cwd
);
9889 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9890 json
, JSON_C_TO_STRING_PRETTY
));
9891 json_object_free(json
);
9895 static void pim_show_vxlan_sg_match_addr(struct pim_instance
*pim
,
9896 struct vty
*vty
, char *addr_str
, bool uj
)
9898 json_object
*json
= NULL
;
9899 struct pim_sg_cache_walk_data cwd
;
9902 memset(&cwd
, 0, sizeof(cwd
));
9903 result
= inet_pton(AF_INET
, addr_str
, &cwd
.addr
);
9905 vty_out(vty
, "Bad address %s: errno=%d: %s\n", addr_str
,
9906 errno
, safe_strerror(errno
));
9911 json
= json_object_new_object();
9913 vty_out(vty
, "Codes: I -> installed\n");
9915 "Source Group Input Output Flags\n");
9920 cwd
.addr_match
= TRUE
;
9921 hash_iterate(pim
->vxlan
.sg_hash
, pim_show_vxlan_sg_hash_entry
, &cwd
);
9924 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9925 json
, JSON_C_TO_STRING_PRETTY
));
9926 json_object_free(json
);
9930 static void pim_show_vxlan_sg_one(struct pim_instance
*pim
,
9931 struct vty
*vty
, char *src_str
, char *grp_str
, bool uj
)
9933 json_object
*json
= NULL
;
9934 struct prefix_sg sg
;
9936 struct pim_vxlan_sg
*vxlan_sg
;
9937 const char *iif_name
;
9939 const char *oif_name
;
9941 result
= inet_pton(AF_INET
, src_str
, &sg
.src
);
9943 vty_out(vty
, "Bad src address %s: errno=%d: %s\n", src_str
,
9944 errno
, safe_strerror(errno
));
9947 result
= inet_pton(AF_INET
, grp_str
, &sg
.grp
);
9949 vty_out(vty
, "Bad grp address %s: errno=%d: %s\n", grp_str
,
9950 errno
, safe_strerror(errno
));
9954 sg
.family
= AF_INET
;
9955 sg
.prefixlen
= IPV4_MAX_BITLEN
;
9957 json
= json_object_new_object();
9959 vxlan_sg
= pim_vxlan_sg_find(pim
, &sg
);
9961 installed
= (vxlan_sg
->up
)?TRUE
:FALSE
;
9962 iif_name
= vxlan_sg
->iif
?vxlan_sg
->iif
->name
:"-";
9964 if (pim_vxlan_is_orig_mroute(vxlan_sg
))
9966 vxlan_sg
->orig_oif
?vxlan_sg
->orig_oif
->name
:"";
9969 vxlan_sg
->term_oif
?vxlan_sg
->term_oif
->name
:"";
9972 json_object_string_add(json
, "source", src_str
);
9973 json_object_string_add(json
, "group", grp_str
);
9974 json_object_string_add(json
, "input", iif_name
);
9975 json_object_string_add(json
, "output", oif_name
);
9977 json_object_boolean_true_add(json
, "installed");
9979 json_object_boolean_false_add(json
,
9982 vty_out(vty
, "SG : %s\n", vxlan_sg
->sg_str
);
9983 vty_out(vty
, " Input : %s\n", iif_name
);
9984 vty_out(vty
, " Output : %s\n", oif_name
);
9985 vty_out(vty
, " installed : %s\n",
9986 installed
?"yes":"no");
9991 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9992 json
, JSON_C_TO_STRING_PRETTY
));
9993 json_object_free(json
);
9997 DEFUN (show_ip_pim_vxlan_sg
,
9998 show_ip_pim_vxlan_sg_cmd
,
9999 "show ip pim [vrf NAME] vxlan-groups [A.B.C.D [A.B.C.D]] [json]",
10004 "VxLAN BUM groups\n"
10005 "source or group ip\n"
10009 bool uj
= use_json(argc
, argv
);
10013 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10016 return CMD_WARNING
;
10018 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ?
10019 argv
[idx
++]->arg
:NULL
;
10020 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
) ?
10021 argv
[idx
]->arg
:NULL
;
10023 if (src_ip
&& grp_ip
)
10024 pim_show_vxlan_sg_one(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
10026 pim_show_vxlan_sg_match_addr(vrf
->info
, vty
, src_ip
, uj
);
10028 pim_show_vxlan_sg(vrf
->info
, vty
, uj
);
10030 return CMD_SUCCESS
;
10033 static void pim_show_vxlan_sg_work(struct pim_instance
*pim
,
10034 struct vty
*vty
, bool uj
)
10036 json_object
*json
= NULL
;
10037 struct pim_sg_cache_walk_data cwd
;
10038 struct listnode
*node
;
10039 struct pim_vxlan_sg
*vxlan_sg
;
10042 json
= json_object_new_object();
10044 vty_out(vty
, "Codes: I -> installed\n");
10046 "Source Group Input Flags\n");
10049 memset(&cwd
, 0, sizeof(cwd
));
10052 for (ALL_LIST_ELEMENTS_RO(pim_vxlan_p
->work_list
, node
, vxlan_sg
))
10053 pim_show_vxlan_sg_entry(vxlan_sg
, &cwd
);
10056 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10057 json
, JSON_C_TO_STRING_PRETTY
));
10058 json_object_free(json
);
10062 DEFUN_HIDDEN (show_ip_pim_vxlan_sg_work
,
10063 show_ip_pim_vxlan_sg_work_cmd
,
10064 "show ip pim [vrf NAME] vxlan-work [json]",
10069 "VxLAN work list\n"
10072 bool uj
= use_json(argc
, argv
);
10076 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10079 return CMD_WARNING
;
10081 pim_show_vxlan_sg_work(vrf
->info
, vty
, uj
);
10083 return CMD_SUCCESS
;
10086 DEFUN_HIDDEN (no_ip_pim_mlag
,
10087 no_ip_pim_mlag_cmd
,
10094 struct in_addr addr
;
10097 pim_vxlan_mlag_update(TRUE
/*mlag_enable*/,
10098 FALSE
/*peer_state*/, PIM_VXLAN_MLAG_ROLE_SECONDARY
,
10099 NULL
/*peerlink*/, &addr
);
10101 return CMD_SUCCESS
;
10104 DEFUN_HIDDEN (ip_pim_mlag
,
10106 "ip pim mlag INTERFACE role [primary|secondary] state [up|down] addr A.B.C.D",
10110 "peerlink sub interface\n"
10112 "MLAG role primary\n"
10113 "MLAG role secondary\n"
10114 "peer session state\n"
10115 "peer session state up\n"
10116 "peer session state down\n"
10118 "unique ip address\n")
10120 struct interface
*ifp
;
10121 const char *peerlink
;
10126 struct in_addr reg_addr
;
10129 peerlink
= argv
[idx
]->arg
;
10130 ifp
= if_lookup_by_name(peerlink
, VRF_DEFAULT
);
10132 vty_out(vty
, "No such interface name %s\n", peerlink
);
10133 return CMD_WARNING
;
10137 if (!strcmp(argv
[idx
]->arg
, "primary")) {
10138 role
= PIM_VXLAN_MLAG_ROLE_PRIMARY
;
10139 } else if (!strcmp(argv
[idx
]->arg
, "secondary")) {
10140 role
= PIM_VXLAN_MLAG_ROLE_SECONDARY
;
10142 vty_out(vty
, "unknown MLAG role %s\n", argv
[idx
]->arg
);
10143 return CMD_WARNING
;
10147 if (!strcmp(argv
[idx
]->arg
, "up")) {
10149 } else if (strcmp(argv
[idx
]->arg
, "down")) {
10150 peer_state
= FALSE
;
10152 vty_out(vty
, "unknown MLAG state %s\n", argv
[idx
]->arg
);
10153 return CMD_WARNING
;
10157 result
= inet_pton(AF_INET
, argv
[idx
]->arg
, ®_addr
);
10159 vty_out(vty
, "%% Bad reg address %s: errno=%d: %s\n",
10161 errno
, safe_strerror(errno
));
10162 return CMD_WARNING_CONFIG_FAILED
;
10164 pim_vxlan_mlag_update(TRUE
, peer_state
, role
, ifp
, ®_addr
);
10166 return CMD_SUCCESS
;
10169 void pim_cmd_init(void)
10171 install_node(&interface_node
,
10172 pim_interface_config_write
); /* INTERFACE_NODE */
10175 install_node(&debug_node
, pim_debug_config_write
);
10177 install_element(ENABLE_NODE
, &pim_test_sg_keepalive_cmd
);
10179 install_element(CONFIG_NODE
, &ip_pim_rp_cmd
);
10180 install_element(VRF_NODE
, &ip_pim_rp_cmd
);
10181 install_element(CONFIG_NODE
, &no_ip_pim_rp_cmd
);
10182 install_element(VRF_NODE
, &no_ip_pim_rp_cmd
);
10183 install_element(CONFIG_NODE
, &ip_pim_rp_prefix_list_cmd
);
10184 install_element(VRF_NODE
, &ip_pim_rp_prefix_list_cmd
);
10185 install_element(CONFIG_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
10186 install_element(VRF_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
10187 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
10188 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
10189 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
10190 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
10191 install_element(CONFIG_NODE
, &ip_pim_ssm_prefix_list_cmd
);
10192 install_element(VRF_NODE
, &ip_pim_ssm_prefix_list_cmd
);
10193 install_element(CONFIG_NODE
, &ip_pim_register_suppress_cmd
);
10194 install_element(VRF_NODE
, &ip_pim_register_suppress_cmd
);
10195 install_element(CONFIG_NODE
, &no_ip_pim_register_suppress_cmd
);
10196 install_element(VRF_NODE
, &no_ip_pim_register_suppress_cmd
);
10197 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
10198 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
10199 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
10200 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
10201 install_element(CONFIG_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
10202 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
10203 install_element(CONFIG_NODE
,
10204 &no_ip_pim_spt_switchover_infinity_plist_cmd
);
10205 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_plist_cmd
);
10206 install_element(CONFIG_NODE
, &ip_pim_joinprune_time_cmd
);
10207 install_element(VRF_NODE
, &ip_pim_joinprune_time_cmd
);
10208 install_element(CONFIG_NODE
, &no_ip_pim_joinprune_time_cmd
);
10209 install_element(VRF_NODE
, &no_ip_pim_joinprune_time_cmd
);
10210 install_element(CONFIG_NODE
, &ip_pim_keep_alive_cmd
);
10211 install_element(VRF_NODE
, &ip_pim_keep_alive_cmd
);
10212 install_element(CONFIG_NODE
, &ip_pim_rp_keep_alive_cmd
);
10213 install_element(VRF_NODE
, &ip_pim_rp_keep_alive_cmd
);
10214 install_element(CONFIG_NODE
, &no_ip_pim_keep_alive_cmd
);
10215 install_element(VRF_NODE
, &no_ip_pim_keep_alive_cmd
);
10216 install_element(CONFIG_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
10217 install_element(VRF_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
10218 install_element(CONFIG_NODE
, &ip_pim_packets_cmd
);
10219 install_element(VRF_NODE
, &ip_pim_packets_cmd
);
10220 install_element(CONFIG_NODE
, &no_ip_pim_packets_cmd
);
10221 install_element(VRF_NODE
, &no_ip_pim_packets_cmd
);
10222 install_element(CONFIG_NODE
, &ip_pim_v6_secondary_cmd
);
10223 install_element(VRF_NODE
, &ip_pim_v6_secondary_cmd
);
10224 install_element(CONFIG_NODE
, &no_ip_pim_v6_secondary_cmd
);
10225 install_element(VRF_NODE
, &no_ip_pim_v6_secondary_cmd
);
10226 install_element(CONFIG_NODE
, &ip_ssmpingd_cmd
);
10227 install_element(VRF_NODE
, &ip_ssmpingd_cmd
);
10228 install_element(CONFIG_NODE
, &no_ip_ssmpingd_cmd
);
10229 install_element(VRF_NODE
, &no_ip_ssmpingd_cmd
);
10230 install_element(CONFIG_NODE
, &ip_msdp_peer_cmd
);
10231 install_element(VRF_NODE
, &ip_msdp_peer_cmd
);
10232 install_element(CONFIG_NODE
, &no_ip_msdp_peer_cmd
);
10233 install_element(VRF_NODE
, &no_ip_msdp_peer_cmd
);
10234 install_element(CONFIG_NODE
, &ip_pim_ecmp_cmd
);
10235 install_element(VRF_NODE
, &ip_pim_ecmp_cmd
);
10236 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_cmd
);
10237 install_element(VRF_NODE
, &no_ip_pim_ecmp_cmd
);
10238 install_element(CONFIG_NODE
, &ip_pim_ecmp_rebalance_cmd
);
10239 install_element(VRF_NODE
, &ip_pim_ecmp_rebalance_cmd
);
10240 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
10241 install_element(VRF_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
10242 install_element(CONFIG_NODE
, &ip_pim_mlag_cmd
);
10243 install_element(CONFIG_NODE
, &no_ip_pim_mlag_cmd
);
10245 install_element(INTERFACE_NODE
, &interface_ip_igmp_cmd
);
10246 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_cmd
);
10247 install_element(INTERFACE_NODE
, &interface_ip_igmp_join_cmd
);
10248 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_join_cmd
);
10249 install_element(INTERFACE_NODE
, &interface_ip_igmp_version_cmd
);
10250 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_version_cmd
);
10251 install_element(INTERFACE_NODE
, &interface_ip_igmp_query_interval_cmd
);
10252 install_element(INTERFACE_NODE
,
10253 &interface_no_ip_igmp_query_interval_cmd
);
10254 install_element(INTERFACE_NODE
,
10255 &interface_ip_igmp_query_max_response_time_cmd
);
10256 install_element(INTERFACE_NODE
,
10257 &interface_no_ip_igmp_query_max_response_time_cmd
);
10258 install_element(INTERFACE_NODE
,
10259 &interface_ip_igmp_query_max_response_time_dsec_cmd
);
10260 install_element(INTERFACE_NODE
,
10261 &interface_no_ip_igmp_query_max_response_time_dsec_cmd
);
10262 install_element(INTERFACE_NODE
,
10263 &interface_ip_igmp_last_member_query_count_cmd
);
10264 install_element(INTERFACE_NODE
,
10265 &interface_no_ip_igmp_last_member_query_count_cmd
);
10266 install_element(INTERFACE_NODE
,
10267 &interface_ip_igmp_last_member_query_interval_cmd
);
10268 install_element(INTERFACE_NODE
,
10269 &interface_no_ip_igmp_last_member_query_interval_cmd
);
10270 install_element(INTERFACE_NODE
, &interface_ip_pim_activeactive_cmd
);
10271 install_element(INTERFACE_NODE
, &interface_ip_pim_ssm_cmd
);
10272 install_element(INTERFACE_NODE
, &interface_no_ip_pim_ssm_cmd
);
10273 install_element(INTERFACE_NODE
, &interface_ip_pim_sm_cmd
);
10274 install_element(INTERFACE_NODE
, &interface_no_ip_pim_sm_cmd
);
10275 install_element(INTERFACE_NODE
, &interface_ip_pim_cmd
);
10276 install_element(INTERFACE_NODE
, &interface_no_ip_pim_cmd
);
10277 install_element(INTERFACE_NODE
, &interface_ip_pim_drprio_cmd
);
10278 install_element(INTERFACE_NODE
, &interface_no_ip_pim_drprio_cmd
);
10279 install_element(INTERFACE_NODE
, &interface_ip_pim_hello_cmd
);
10280 install_element(INTERFACE_NODE
, &interface_no_ip_pim_hello_cmd
);
10281 install_element(INTERFACE_NODE
, &interface_ip_pim_boundary_oil_cmd
);
10282 install_element(INTERFACE_NODE
, &interface_no_ip_pim_boundary_oil_cmd
);
10284 // Static mroutes NEB
10285 install_element(INTERFACE_NODE
, &interface_ip_mroute_cmd
);
10286 install_element(INTERFACE_NODE
, &interface_ip_mroute_source_cmd
);
10287 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_cmd
);
10288 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_source_cmd
);
10290 install_element(VIEW_NODE
, &show_ip_igmp_interface_cmd
);
10291 install_element(VIEW_NODE
, &show_ip_igmp_interface_vrf_all_cmd
);
10292 install_element(VIEW_NODE
, &show_ip_igmp_join_cmd
);
10293 install_element(VIEW_NODE
, &show_ip_igmp_join_vrf_all_cmd
);
10294 install_element(VIEW_NODE
, &show_ip_igmp_groups_cmd
);
10295 install_element(VIEW_NODE
, &show_ip_igmp_groups_vrf_all_cmd
);
10296 install_element(VIEW_NODE
, &show_ip_igmp_groups_retransmissions_cmd
);
10297 install_element(VIEW_NODE
, &show_ip_igmp_sources_cmd
);
10298 install_element(VIEW_NODE
, &show_ip_igmp_sources_retransmissions_cmd
);
10299 install_element(VIEW_NODE
, &show_ip_igmp_statistics_cmd
);
10300 install_element(VIEW_NODE
, &show_ip_pim_assert_cmd
);
10301 install_element(VIEW_NODE
, &show_ip_pim_assert_internal_cmd
);
10302 install_element(VIEW_NODE
, &show_ip_pim_assert_metric_cmd
);
10303 install_element(VIEW_NODE
, &show_ip_pim_assert_winner_metric_cmd
);
10304 install_element(VIEW_NODE
, &show_ip_pim_interface_traffic_cmd
);
10305 install_element(VIEW_NODE
, &show_ip_pim_interface_cmd
);
10306 install_element(VIEW_NODE
, &show_ip_pim_interface_vrf_all_cmd
);
10307 install_element(VIEW_NODE
, &show_ip_pim_join_cmd
);
10308 install_element(VIEW_NODE
, &show_ip_pim_join_vrf_all_cmd
);
10309 install_element(VIEW_NODE
, &show_ip_pim_local_membership_cmd
);
10310 install_element(VIEW_NODE
, &show_ip_pim_neighbor_cmd
);
10311 install_element(VIEW_NODE
, &show_ip_pim_neighbor_vrf_all_cmd
);
10312 install_element(VIEW_NODE
, &show_ip_pim_rpf_cmd
);
10313 install_element(VIEW_NODE
, &show_ip_pim_rpf_vrf_all_cmd
);
10314 install_element(VIEW_NODE
, &show_ip_pim_secondary_cmd
);
10315 install_element(VIEW_NODE
, &show_ip_pim_state_cmd
);
10316 install_element(VIEW_NODE
, &show_ip_pim_state_vrf_all_cmd
);
10317 install_element(VIEW_NODE
, &show_ip_pim_upstream_cmd
);
10318 install_element(VIEW_NODE
, &show_ip_pim_upstream_vrf_all_cmd
);
10319 install_element(VIEW_NODE
, &show_ip_pim_upstream_join_desired_cmd
);
10320 install_element(VIEW_NODE
, &show_ip_pim_upstream_rpf_cmd
);
10321 install_element(VIEW_NODE
, &show_ip_pim_rp_cmd
);
10322 install_element(VIEW_NODE
, &show_ip_pim_rp_vrf_all_cmd
);
10323 install_element(VIEW_NODE
, &show_ip_pim_bsr_cmd
);
10324 install_element(VIEW_NODE
, &show_ip_multicast_cmd
);
10325 install_element(VIEW_NODE
, &show_ip_multicast_vrf_all_cmd
);
10326 install_element(VIEW_NODE
, &show_ip_mroute_cmd
);
10327 install_element(VIEW_NODE
, &show_ip_mroute_vrf_all_cmd
);
10328 install_element(VIEW_NODE
, &show_ip_mroute_count_cmd
);
10329 install_element(VIEW_NODE
, &show_ip_mroute_count_vrf_all_cmd
);
10330 install_element(VIEW_NODE
, &show_ip_mroute_summary_cmd
);
10331 install_element(VIEW_NODE
, &show_ip_mroute_summary_vrf_all_cmd
);
10332 install_element(VIEW_NODE
, &show_ip_rib_cmd
);
10333 install_element(VIEW_NODE
, &show_ip_ssmpingd_cmd
);
10334 install_element(VIEW_NODE
, &show_debugging_pim_cmd
);
10335 install_element(VIEW_NODE
, &show_ip_pim_nexthop_cmd
);
10336 install_element(VIEW_NODE
, &show_ip_pim_nexthop_lookup_cmd
);
10337 install_element(VIEW_NODE
, &show_ip_pim_bsrp_cmd
);
10338 install_element(VIEW_NODE
, &show_ip_pim_bsm_db_cmd
);
10339 install_element(VIEW_NODE
, &show_ip_pim_statistics_cmd
);
10341 install_element(ENABLE_NODE
, &clear_ip_mroute_count_cmd
);
10342 install_element(ENABLE_NODE
, &clear_ip_interfaces_cmd
);
10343 install_element(ENABLE_NODE
, &clear_ip_igmp_interfaces_cmd
);
10344 install_element(ENABLE_NODE
, &clear_ip_mroute_cmd
);
10345 install_element(ENABLE_NODE
, &clear_ip_pim_interfaces_cmd
);
10346 install_element(ENABLE_NODE
, &clear_ip_pim_interface_traffic_cmd
);
10347 install_element(ENABLE_NODE
, &clear_ip_pim_oil_cmd
);
10348 install_element(ENABLE_NODE
, &clear_ip_pim_statistics_cmd
);
10350 install_element(ENABLE_NODE
, &debug_igmp_cmd
);
10351 install_element(ENABLE_NODE
, &no_debug_igmp_cmd
);
10352 install_element(ENABLE_NODE
, &debug_igmp_events_cmd
);
10353 install_element(ENABLE_NODE
, &no_debug_igmp_events_cmd
);
10354 install_element(ENABLE_NODE
, &debug_igmp_packets_cmd
);
10355 install_element(ENABLE_NODE
, &no_debug_igmp_packets_cmd
);
10356 install_element(ENABLE_NODE
, &debug_igmp_trace_cmd
);
10357 install_element(ENABLE_NODE
, &no_debug_igmp_trace_cmd
);
10358 install_element(ENABLE_NODE
, &debug_mroute_cmd
);
10359 install_element(ENABLE_NODE
, &debug_mroute_detail_cmd
);
10360 install_element(ENABLE_NODE
, &no_debug_mroute_cmd
);
10361 install_element(ENABLE_NODE
, &no_debug_mroute_detail_cmd
);
10362 install_element(ENABLE_NODE
, &debug_pim_static_cmd
);
10363 install_element(ENABLE_NODE
, &no_debug_pim_static_cmd
);
10364 install_element(ENABLE_NODE
, &debug_pim_cmd
);
10365 install_element(ENABLE_NODE
, &no_debug_pim_cmd
);
10366 install_element(ENABLE_NODE
, &debug_pim_nht_cmd
);
10367 install_element(ENABLE_NODE
, &no_debug_pim_nht_cmd
);
10368 install_element(ENABLE_NODE
, &debug_pim_nht_rp_cmd
);
10369 install_element(ENABLE_NODE
, &no_debug_pim_nht_rp_cmd
);
10370 install_element(ENABLE_NODE
, &debug_pim_events_cmd
);
10371 install_element(ENABLE_NODE
, &no_debug_pim_events_cmd
);
10372 install_element(ENABLE_NODE
, &debug_pim_packets_cmd
);
10373 install_element(ENABLE_NODE
, &no_debug_pim_packets_cmd
);
10374 install_element(ENABLE_NODE
, &debug_pim_packetdump_send_cmd
);
10375 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_send_cmd
);
10376 install_element(ENABLE_NODE
, &debug_pim_packetdump_recv_cmd
);
10377 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_recv_cmd
);
10378 install_element(ENABLE_NODE
, &debug_pim_trace_cmd
);
10379 install_element(ENABLE_NODE
, &no_debug_pim_trace_cmd
);
10380 install_element(ENABLE_NODE
, &debug_pim_trace_detail_cmd
);
10381 install_element(ENABLE_NODE
, &no_debug_pim_trace_detail_cmd
);
10382 install_element(ENABLE_NODE
, &debug_ssmpingd_cmd
);
10383 install_element(ENABLE_NODE
, &no_debug_ssmpingd_cmd
);
10384 install_element(ENABLE_NODE
, &debug_pim_zebra_cmd
);
10385 install_element(ENABLE_NODE
, &no_debug_pim_zebra_cmd
);
10386 install_element(ENABLE_NODE
, &debug_pim_vxlan_cmd
);
10387 install_element(ENABLE_NODE
, &no_debug_pim_vxlan_cmd
);
10388 install_element(ENABLE_NODE
, &debug_msdp_cmd
);
10389 install_element(ENABLE_NODE
, &no_debug_msdp_cmd
);
10390 install_element(ENABLE_NODE
, &debug_msdp_events_cmd
);
10391 install_element(ENABLE_NODE
, &no_debug_msdp_events_cmd
);
10392 install_element(ENABLE_NODE
, &debug_msdp_packets_cmd
);
10393 install_element(ENABLE_NODE
, &no_debug_msdp_packets_cmd
);
10394 install_element(ENABLE_NODE
, &debug_mtrace_cmd
);
10395 install_element(ENABLE_NODE
, &no_debug_mtrace_cmd
);
10396 install_element(ENABLE_NODE
, &debug_bsm_cmd
);
10397 install_element(ENABLE_NODE
, &no_debug_bsm_cmd
);
10399 install_element(CONFIG_NODE
, &debug_igmp_cmd
);
10400 install_element(CONFIG_NODE
, &no_debug_igmp_cmd
);
10401 install_element(CONFIG_NODE
, &debug_igmp_events_cmd
);
10402 install_element(CONFIG_NODE
, &no_debug_igmp_events_cmd
);
10403 install_element(CONFIG_NODE
, &debug_igmp_packets_cmd
);
10404 install_element(CONFIG_NODE
, &no_debug_igmp_packets_cmd
);
10405 install_element(CONFIG_NODE
, &debug_igmp_trace_cmd
);
10406 install_element(CONFIG_NODE
, &no_debug_igmp_trace_cmd
);
10407 install_element(CONFIG_NODE
, &debug_mroute_cmd
);
10408 install_element(CONFIG_NODE
, &debug_mroute_detail_cmd
);
10409 install_element(CONFIG_NODE
, &no_debug_mroute_cmd
);
10410 install_element(CONFIG_NODE
, &no_debug_mroute_detail_cmd
);
10411 install_element(CONFIG_NODE
, &debug_pim_static_cmd
);
10412 install_element(CONFIG_NODE
, &no_debug_pim_static_cmd
);
10413 install_element(CONFIG_NODE
, &debug_pim_cmd
);
10414 install_element(CONFIG_NODE
, &no_debug_pim_cmd
);
10415 install_element(CONFIG_NODE
, &debug_pim_nht_cmd
);
10416 install_element(CONFIG_NODE
, &no_debug_pim_nht_cmd
);
10417 install_element(CONFIG_NODE
, &debug_pim_nht_rp_cmd
);
10418 install_element(CONFIG_NODE
, &no_debug_pim_nht_rp_cmd
);
10419 install_element(CONFIG_NODE
, &debug_pim_events_cmd
);
10420 install_element(CONFIG_NODE
, &no_debug_pim_events_cmd
);
10421 install_element(CONFIG_NODE
, &debug_pim_packets_cmd
);
10422 install_element(CONFIG_NODE
, &no_debug_pim_packets_cmd
);
10423 install_element(CONFIG_NODE
, &debug_pim_trace_cmd
);
10424 install_element(CONFIG_NODE
, &no_debug_pim_trace_cmd
);
10425 install_element(CONFIG_NODE
, &debug_pim_trace_detail_cmd
);
10426 install_element(CONFIG_NODE
, &no_debug_pim_trace_detail_cmd
);
10427 install_element(CONFIG_NODE
, &debug_ssmpingd_cmd
);
10428 install_element(CONFIG_NODE
, &no_debug_ssmpingd_cmd
);
10429 install_element(CONFIG_NODE
, &debug_pim_zebra_cmd
);
10430 install_element(CONFIG_NODE
, &no_debug_pim_zebra_cmd
);
10431 install_element(CONFIG_NODE
, &debug_pim_vxlan_cmd
);
10432 install_element(CONFIG_NODE
, &no_debug_pim_vxlan_cmd
);
10433 install_element(CONFIG_NODE
, &debug_msdp_cmd
);
10434 install_element(CONFIG_NODE
, &no_debug_msdp_cmd
);
10435 install_element(CONFIG_NODE
, &debug_msdp_events_cmd
);
10436 install_element(CONFIG_NODE
, &no_debug_msdp_events_cmd
);
10437 install_element(CONFIG_NODE
, &debug_msdp_packets_cmd
);
10438 install_element(CONFIG_NODE
, &no_debug_msdp_packets_cmd
);
10439 install_element(CONFIG_NODE
, &debug_mtrace_cmd
);
10440 install_element(CONFIG_NODE
, &no_debug_mtrace_cmd
);
10441 install_element(CONFIG_NODE
, &debug_bsm_cmd
);
10442 install_element(CONFIG_NODE
, &no_debug_bsm_cmd
);
10444 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_member_cmd
);
10445 install_element(VRF_NODE
, &ip_msdp_mesh_group_member_cmd
);
10446 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
10447 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
10448 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_source_cmd
);
10449 install_element(VRF_NODE
, &ip_msdp_mesh_group_source_cmd
);
10450 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
10451 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
10452 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_cmd
);
10453 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_vrf_all_cmd
);
10454 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_cmd
);
10455 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_vrf_all_cmd
);
10456 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_cmd
);
10457 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_vrf_all_cmd
);
10458 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_cmd
);
10459 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_vrf_all_cmd
);
10460 install_element(VIEW_NODE
, &show_ip_pim_ssm_range_cmd
);
10461 install_element(VIEW_NODE
, &show_ip_pim_group_type_cmd
);
10462 install_element(VIEW_NODE
, &show_ip_pim_vxlan_sg_cmd
);
10463 install_element(VIEW_NODE
, &show_ip_pim_vxlan_sg_work_cmd
);
10464 install_element(INTERFACE_NODE
, &interface_pim_use_source_cmd
);
10465 install_element(INTERFACE_NODE
, &interface_no_pim_use_source_cmd
);
10466 /* Install BSM command */
10467 install_element(INTERFACE_NODE
, &ip_pim_bsm_cmd
);
10468 install_element(INTERFACE_NODE
, &no_ip_pim_bsm_cmd
);
10469 install_element(INTERFACE_NODE
, &ip_pim_ucast_bsm_cmd
);
10470 install_element(INTERFACE_NODE
, &no_ip_pim_ucast_bsm_cmd
);
10471 /* Install BFD command */
10472 install_element(INTERFACE_NODE
, &ip_pim_bfd_cmd
);
10473 install_element(INTERFACE_NODE
, &ip_pim_bfd_param_cmd
);
10474 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_cmd
);
10476 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_param_cmd
);
10477 #endif /* !HAVE_BFDD */