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%c)", out_ifname
,
2121 (c_oil
->oif_flags
[oif_vif_index
]
2122 & PIM_OIF_FLAG_PROTO_IGMP
)
2125 (c_oil
->oif_flags
[oif_vif_index
]
2126 & PIM_OIF_FLAG_PROTO_PIM
)
2129 (c_oil
->oif_flags
[oif_vif_index
]
2130 & PIM_OIF_FLAG_PROTO_VXLAN
)
2133 (c_oil
->oif_flags
[oif_vif_index
]
2134 & PIM_OIF_FLAG_PROTO_SOURCE
)
2137 (c_oil
->oif_flags
[oif_vif_index
]
2138 & PIM_OIF_FLAG_PROTO_STAR
)
2142 vty_out(vty
, ", %s(%c%c%c%c%c)",
2144 (c_oil
->oif_flags
[oif_vif_index
]
2145 & PIM_OIF_FLAG_PROTO_IGMP
)
2148 (c_oil
->oif_flags
[oif_vif_index
]
2149 & PIM_OIF_FLAG_PROTO_PIM
)
2152 (c_oil
->oif_flags
[oif_vif_index
]
2153 & PIM_OIF_FLAG_PROTO_VXLAN
)
2156 (c_oil
->oif_flags
[oif_vif_index
]
2157 & PIM_OIF_FLAG_PROTO_SOURCE
)
2160 (c_oil
->oif_flags
[oif_vif_index
]
2161 & PIM_OIF_FLAG_PROTO_STAR
)
2173 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2174 json
, JSON_C_TO_STRING_PRETTY
));
2175 json_object_free(json
);
2181 static void pim_show_neighbors(struct pim_instance
*pim
, struct vty
*vty
,
2184 struct listnode
*neighnode
;
2185 struct interface
*ifp
;
2186 struct pim_interface
*pim_ifp
;
2187 struct pim_neighbor
*neigh
;
2191 char neigh_src_str
[INET_ADDRSTRLEN
];
2192 json_object
*json
= NULL
;
2193 json_object
*json_ifp_rows
= NULL
;
2194 json_object
*json_row
= NULL
;
2196 now
= pim_time_monotonic_sec();
2199 json
= json_object_new_object();
2202 "Interface Neighbor Uptime Holdtime DR Pri\n");
2205 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2206 pim_ifp
= ifp
->info
;
2211 if (pim_ifp
->pim_sock_fd
< 0)
2215 json_ifp_rows
= json_object_new_object();
2217 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
2219 pim_inet4_dump("<src?>", neigh
->source_addr
,
2220 neigh_src_str
, sizeof(neigh_src_str
));
2221 pim_time_uptime(uptime
, sizeof(uptime
),
2222 now
- neigh
->creation
);
2223 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
2224 neigh
->t_expire_timer
);
2227 json_row
= json_object_new_object();
2228 json_object_string_add(json_row
, "interface",
2230 json_object_string_add(json_row
, "neighbor",
2232 json_object_string_add(json_row
, "upTime",
2234 json_object_string_add(json_row
, "holdTime",
2236 json_object_int_add(json_row
, "holdTimeMax",
2238 json_object_int_add(json_row
, "drPriority",
2239 neigh
->dr_priority
);
2240 json_object_object_add(json_ifp_rows
,
2241 neigh_src_str
, json_row
);
2244 vty_out(vty
, "%-16s %15s %8s %8s %6d\n",
2245 ifp
->name
, neigh_src_str
, uptime
,
2246 expire
, neigh
->dr_priority
);
2251 json_object_object_add(json
, ifp
->name
, json_ifp_rows
);
2252 json_ifp_rows
= NULL
;
2257 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2258 json
, JSON_C_TO_STRING_PRETTY
));
2259 json_object_free(json
);
2263 static void pim_show_neighbors_secondary(struct pim_instance
*pim
,
2266 struct interface
*ifp
;
2269 "Interface Address Neighbor Secondary \n");
2271 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2272 struct pim_interface
*pim_ifp
;
2273 struct in_addr ifaddr
;
2274 struct listnode
*neighnode
;
2275 struct pim_neighbor
*neigh
;
2277 pim_ifp
= ifp
->info
;
2282 if (pim_ifp
->pim_sock_fd
< 0)
2285 ifaddr
= pim_ifp
->primary_address
;
2287 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
2289 char neigh_src_str
[INET_ADDRSTRLEN
];
2290 struct listnode
*prefix_node
;
2293 if (!neigh
->prefix_list
)
2296 pim_inet4_dump("<src?>", neigh
->source_addr
,
2297 neigh_src_str
, sizeof(neigh_src_str
));
2299 for (ALL_LIST_ELEMENTS_RO(neigh
->prefix_list
,
2301 char neigh_sec_str
[PREFIX2STR_BUFFER
];
2303 prefix2str(p
, neigh_sec_str
,
2304 sizeof(neigh_sec_str
));
2306 vty_out(vty
, "%-16s %-15s %-15s %-15s\n",
2307 ifp
->name
, inet_ntoa(ifaddr
),
2308 neigh_src_str
, neigh_sec_str
);
2314 static void json_object_pim_upstream_add(json_object
*json
,
2315 struct pim_upstream
*up
)
2317 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED
)
2318 json_object_boolean_true_add(json
, "drJoinDesired");
2320 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED
)
2321 json_object_boolean_true_add(json
, "drJoinDesiredUpdated");
2323 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
2324 json_object_boolean_true_add(json
, "firstHopRouter");
2326 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_IGMP
)
2327 json_object_boolean_true_add(json
, "sourceIgmp");
2329 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_PIM
)
2330 json_object_boolean_true_add(json
, "sourcePim");
2332 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_STREAM
)
2333 json_object_boolean_true_add(json
, "sourceStream");
2335 /* XXX: need to print ths flag in the plain text display as well */
2336 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_MSDP
)
2337 json_object_boolean_true_add(json
, "sourceMsdp");
2339 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SEND_SG_RPT_PRUNE
)
2340 json_object_boolean_true_add(json
, "sendSGRptPrune");
2342 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_LHR
)
2343 json_object_boolean_true_add(json
, "lastHopRouter");
2345 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DISABLE_KAT_EXPIRY
)
2346 json_object_boolean_true_add(json
, "disableKATExpiry");
2348 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_STATIC_IIF
)
2349 json_object_boolean_true_add(json
, "staticIncomingInterface");
2351 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_ALLOW_IIF_IN_OIL
)
2352 json_object_boolean_true_add(json
,
2353 "allowIncomingInterfaceinOil");
2355 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_NO_PIMREG_DATA
)
2356 json_object_boolean_true_add(json
, "noPimRegistrationData");
2358 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FORCE_PIMREG
)
2359 json_object_boolean_true_add(json
, "forcePimRegistration");
2361 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_ORIG
)
2362 json_object_boolean_true_add(json
, "sourceVxlanOrigination");
2364 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_TERM
)
2365 json_object_boolean_true_add(json
, "sourceVxlanTermination");
2367 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_VXLAN
)
2368 json_object_boolean_true_add(json
, "mlagVxlan");
2370 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_NON_DF
)
2371 json_object_boolean_true_add(json
,
2372 "mlagNonDesignatedForwarder");
2376 pim_upstream_state2brief_str(enum pim_upstream_state join_state
,
2377 char *state_str
, size_t state_str_len
)
2379 switch (join_state
) {
2380 case PIM_UPSTREAM_NOTJOINED
:
2381 strlcpy(state_str
, "NotJ", state_str_len
);
2383 case PIM_UPSTREAM_JOINED
:
2384 strlcpy(state_str
, "J", state_str_len
);
2387 strlcpy(state_str
, "Unk", state_str_len
);
2392 static const char *pim_reg_state2brief_str(enum pim_reg_state reg_state
,
2393 char *state_str
, size_t state_str_len
)
2395 switch (reg_state
) {
2396 case PIM_REG_NOINFO
:
2397 strlcpy(state_str
, "RegNI", state_str_len
);
2400 strlcpy(state_str
, "RegJ", state_str_len
);
2402 case PIM_REG_JOIN_PENDING
:
2404 strlcpy(state_str
, "RegP", state_str_len
);
2407 strlcpy(state_str
, "Unk", state_str_len
);
2412 static void pim_show_upstream(struct pim_instance
*pim
, struct vty
*vty
,
2413 struct prefix_sg
*sg
, bool uj
)
2415 struct listnode
*upnode
;
2416 struct pim_upstream
*up
;
2418 json_object
*json
= NULL
;
2419 json_object
*json_group
= NULL
;
2420 json_object
*json_row
= NULL
;
2422 now
= pim_time_monotonic_sec();
2425 json
= json_object_new_object();
2428 "Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt\n");
2430 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
, up
)) {
2431 char src_str
[INET_ADDRSTRLEN
];
2432 char grp_str
[INET_ADDRSTRLEN
];
2434 char join_timer
[10];
2437 char msdp_reg_timer
[10];
2438 char state_str
[PIM_REG_STATE_STR_LEN
];
2440 if (sg
->grp
.s_addr
!= 0 && sg
->grp
.s_addr
!= up
->sg
.grp
.s_addr
)
2442 if (sg
->src
.s_addr
!= 0 && sg
->src
.s_addr
!= up
->sg
.src
.s_addr
)
2445 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2446 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2447 pim_time_uptime(uptime
, sizeof(uptime
),
2448 now
- up
->state_transition
);
2449 pim_time_timer_to_hhmmss(join_timer
, sizeof(join_timer
),
2453 * If the upstream is not dummy and it has a J/P timer for the
2454 * neighbor display that
2456 if (!up
->t_join_timer
&& up
->rpf
.source_nexthop
.interface
) {
2457 struct pim_neighbor
*nbr
;
2459 nbr
= pim_neighbor_find(
2460 up
->rpf
.source_nexthop
.interface
,
2461 up
->rpf
.rpf_addr
.u
.prefix4
);
2463 pim_time_timer_to_hhmmss(join_timer
,
2468 pim_time_timer_to_hhmmss(rs_timer
, sizeof(rs_timer
),
2470 pim_time_timer_to_hhmmss(ka_timer
, sizeof(ka_timer
),
2472 pim_time_timer_to_hhmmss(msdp_reg_timer
, sizeof(msdp_reg_timer
),
2473 up
->t_msdp_reg_timer
);
2475 pim_upstream_state2brief_str(up
->join_state
, state_str
, sizeof(state_str
));
2476 if (up
->reg_state
!= PIM_REG_NOINFO
) {
2477 char tmp_str
[PIM_REG_STATE_STR_LEN
];
2479 sprintf(state_str
+ strlen(state_str
), ",%s",
2480 pim_reg_state2brief_str(up
->reg_state
, tmp_str
,
2485 json_object_object_get_ex(json
, grp_str
, &json_group
);
2488 json_group
= json_object_new_object();
2489 json_object_object_add(json
, grp_str
,
2493 json_row
= json_object_new_object();
2494 json_object_pim_upstream_add(json_row
, up
);
2495 json_object_string_add(
2496 json_row
, "inboundInterface",
2497 up
->rpf
.source_nexthop
.interface
2498 ? up
->rpf
.source_nexthop
.interface
->name
2502 * The RPF address we use is slightly different
2503 * based upon what we are looking up.
2504 * If we have a S, list that unless
2505 * we are the FHR, else we just put
2506 * the RP as the rpfAddress
2508 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
2509 || up
->sg
.src
.s_addr
== INADDR_ANY
) {
2510 char rpf
[PREFIX_STRLEN
];
2511 struct pim_rpf
*rpg
;
2513 rpg
= RP(pim
, up
->sg
.grp
);
2514 pim_inet4_dump("<rpf?>",
2515 rpg
->rpf_addr
.u
.prefix4
, rpf
,
2517 json_object_string_add(json_row
, "rpfAddress",
2520 json_object_string_add(json_row
, "rpfAddress",
2524 json_object_string_add(json_row
, "source", src_str
);
2525 json_object_string_add(json_row
, "group", grp_str
);
2526 json_object_string_add(json_row
, "state", state_str
);
2527 json_object_string_add(
2528 json_row
, "joinState",
2529 pim_upstream_state2str(up
->join_state
));
2530 json_object_string_add(
2531 json_row
, "regState",
2532 pim_reg_state2str(up
->reg_state
, state_str
, sizeof(state_str
)));
2533 json_object_string_add(json_row
, "upTime", uptime
);
2534 json_object_string_add(json_row
, "joinTimer",
2536 json_object_string_add(json_row
, "resetTimer",
2538 json_object_string_add(json_row
, "keepaliveTimer",
2540 json_object_string_add(json_row
, "msdpRegTimer",
2542 json_object_int_add(json_row
, "refCount",
2544 json_object_int_add(json_row
, "sptBit", up
->sptbit
);
2545 json_object_object_add(json_group
, src_str
, json_row
);
2548 "%-16s%-15s %-15s %-11s %-8s %-9s %-9s %-9s %6d\n",
2549 up
->rpf
.source_nexthop
.interface
2550 ? up
->rpf
.source_nexthop
.interface
->name
2552 src_str
, grp_str
, state_str
, uptime
, join_timer
,
2553 rs_timer
, ka_timer
, up
->ref_count
);
2558 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2559 json
, JSON_C_TO_STRING_PRETTY
));
2560 json_object_free(json
);
2564 static void pim_show_join_desired_helper(struct pim_instance
*pim
,
2566 struct pim_interface
*pim_ifp
,
2567 struct pim_ifchannel
*ch
,
2568 json_object
*json
, bool uj
)
2570 struct pim_upstream
*up
= ch
->upstream
;
2571 json_object
*json_group
= NULL
;
2572 char src_str
[INET_ADDRSTRLEN
];
2573 char grp_str
[INET_ADDRSTRLEN
];
2574 json_object
*json_row
= NULL
;
2576 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2577 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2580 json_object_object_get_ex(json
, grp_str
, &json_group
);
2583 json_group
= json_object_new_object();
2584 json_object_object_add(json
, grp_str
, json_group
);
2587 json_row
= json_object_new_object();
2588 json_object_pim_upstream_add(json_row
, up
);
2589 json_object_string_add(json_row
, "interface",
2590 ch
->interface
->name
);
2591 json_object_string_add(json_row
, "source", src_str
);
2592 json_object_string_add(json_row
, "group", grp_str
);
2594 if (pim_macro_ch_lost_assert(ch
))
2595 json_object_boolean_true_add(json_row
, "lostAssert");
2597 if (pim_macro_chisin_joins(ch
))
2598 json_object_boolean_true_add(json_row
, "joins");
2600 if (pim_macro_chisin_pim_include(ch
))
2601 json_object_boolean_true_add(json_row
, "pimInclude");
2603 if (pim_upstream_evaluate_join_desired(pim
, up
))
2604 json_object_boolean_true_add(json_row
,
2605 "evaluateJoinDesired");
2607 json_object_object_add(json_group
, src_str
, json_row
);
2610 vty_out(vty
, "%-16s %-15s %-15s %-10s %-5s %-10s %-11s %-6s\n",
2611 ch
->interface
->name
, src_str
, grp_str
,
2612 pim_macro_ch_lost_assert(ch
) ? "yes" : "no",
2613 pim_macro_chisin_joins(ch
) ? "yes" : "no",
2614 pim_macro_chisin_pim_include(ch
) ? "yes" : "no",
2615 PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(up
->flags
)
2618 pim_upstream_evaluate_join_desired(pim
, up
) ? "yes"
2623 static void pim_show_join_desired(struct pim_instance
*pim
, struct vty
*vty
,
2626 struct pim_interface
*pim_ifp
;
2627 struct pim_ifchannel
*ch
;
2628 struct interface
*ifp
;
2630 json_object
*json
= NULL
;
2633 json
= json_object_new_object();
2636 "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD\n");
2638 /* scan per-interface (S,G) state */
2639 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2640 pim_ifp
= ifp
->info
;
2645 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
2646 /* scan all interfaces */
2647 pim_show_join_desired_helper(pim
, vty
, pim_ifp
, ch
,
2653 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2654 json
, JSON_C_TO_STRING_PRETTY
));
2655 json_object_free(json
);
2659 static void pim_show_upstream_rpf(struct pim_instance
*pim
, struct vty
*vty
,
2662 struct listnode
*upnode
;
2663 struct pim_upstream
*up
;
2664 json_object
*json
= NULL
;
2665 json_object
*json_group
= NULL
;
2666 json_object
*json_row
= NULL
;
2669 json
= json_object_new_object();
2672 "Source Group RpfIface RibNextHop RpfAddress \n");
2674 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
, up
)) {
2675 char src_str
[INET_ADDRSTRLEN
];
2676 char grp_str
[INET_ADDRSTRLEN
];
2677 char rpf_nexthop_str
[PREFIX_STRLEN
];
2678 char rpf_addr_str
[PREFIX_STRLEN
];
2679 struct pim_rpf
*rpf
;
2680 const char *rpf_ifname
;
2684 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2685 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2686 pim_addr_dump("<nexthop?>",
2687 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2688 rpf_nexthop_str
, sizeof(rpf_nexthop_str
));
2689 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2690 sizeof(rpf_addr_str
));
2692 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2695 json_object_object_get_ex(json
, grp_str
, &json_group
);
2698 json_group
= json_object_new_object();
2699 json_object_object_add(json
, grp_str
,
2703 json_row
= json_object_new_object();
2704 json_object_pim_upstream_add(json_row
, up
);
2705 json_object_string_add(json_row
, "source", src_str
);
2706 json_object_string_add(json_row
, "group", grp_str
);
2707 json_object_string_add(json_row
, "rpfInterface",
2709 json_object_string_add(json_row
, "ribNexthop",
2711 json_object_string_add(json_row
, "rpfAddress",
2713 json_object_object_add(json_group
, src_str
, json_row
);
2715 vty_out(vty
, "%-15s %-15s %-16s %-15s %-15s\n", src_str
,
2716 grp_str
, rpf_ifname
, rpf_nexthop_str
,
2722 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2723 json
, JSON_C_TO_STRING_PRETTY
));
2724 json_object_free(json
);
2728 static void show_rpf_refresh_stats(struct vty
*vty
, struct pim_instance
*pim
,
2729 time_t now
, json_object
*json
)
2731 char refresh_uptime
[10];
2733 pim_time_uptime_begin(refresh_uptime
, sizeof(refresh_uptime
), now
,
2734 pim
->rpf_cache_refresh_last
);
2737 json_object_int_add(json
, "rpfCacheRefreshDelayMsecs",
2738 router
->rpf_cache_refresh_delay_msec
);
2739 json_object_int_add(
2740 json
, "rpfCacheRefreshTimer",
2741 pim_time_timer_remain_msec(pim
->rpf_cache_refresher
));
2742 json_object_int_add(json
, "rpfCacheRefreshRequests",
2743 pim
->rpf_cache_refresh_requests
);
2744 json_object_int_add(json
, "rpfCacheRefreshEvents",
2745 pim
->rpf_cache_refresh_events
);
2746 json_object_string_add(json
, "rpfCacheRefreshLast",
2748 json_object_int_add(json
, "nexthopLookups",
2749 pim
->nexthop_lookups
);
2750 json_object_int_add(json
, "nexthopLookupsAvoided",
2751 pim
->nexthop_lookups_avoided
);
2754 "RPF Cache Refresh Delay: %ld msecs\n"
2755 "RPF Cache Refresh Timer: %ld msecs\n"
2756 "RPF Cache Refresh Requests: %lld\n"
2757 "RPF Cache Refresh Events: %lld\n"
2758 "RPF Cache Refresh Last: %s\n"
2759 "Nexthop Lookups: %lld\n"
2760 "Nexthop Lookups Avoided: %lld\n",
2761 router
->rpf_cache_refresh_delay_msec
,
2762 pim_time_timer_remain_msec(pim
->rpf_cache_refresher
),
2763 (long long)pim
->rpf_cache_refresh_requests
,
2764 (long long)pim
->rpf_cache_refresh_events
,
2765 refresh_uptime
, (long long)pim
->nexthop_lookups
,
2766 (long long)pim
->nexthop_lookups_avoided
);
2770 static void show_scan_oil_stats(struct pim_instance
*pim
, struct vty
*vty
,
2773 char uptime_scan_oil
[10];
2774 char uptime_mroute_add
[10];
2775 char uptime_mroute_del
[10];
2777 pim_time_uptime_begin(uptime_scan_oil
, sizeof(uptime_scan_oil
), now
,
2778 pim
->scan_oil_last
);
2779 pim_time_uptime_begin(uptime_mroute_add
, sizeof(uptime_mroute_add
), now
,
2780 pim
->mroute_add_last
);
2781 pim_time_uptime_begin(uptime_mroute_del
, sizeof(uptime_mroute_del
), now
,
2782 pim
->mroute_del_last
);
2785 "Scan OIL - Last: %s Events: %lld\n"
2786 "MFC Add - Last: %s Events: %lld\n"
2787 "MFC Del - Last: %s Events: %lld\n",
2788 uptime_scan_oil
, (long long)pim
->scan_oil_events
,
2789 uptime_mroute_add
, (long long)pim
->mroute_add_events
,
2790 uptime_mroute_del
, (long long)pim
->mroute_del_events
);
2793 static void pim_show_rpf(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
2795 struct listnode
*up_node
;
2796 struct pim_upstream
*up
;
2797 time_t now
= pim_time_monotonic_sec();
2798 json_object
*json
= NULL
;
2799 json_object
*json_group
= NULL
;
2800 json_object
*json_row
= NULL
;
2803 json
= json_object_new_object();
2804 show_rpf_refresh_stats(vty
, pim
, now
, json
);
2806 show_rpf_refresh_stats(vty
, pim
, now
, json
);
2809 "Source Group RpfIface RpfAddress RibNextHop Metric Pref\n");
2812 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, up_node
, up
)) {
2813 char src_str
[INET_ADDRSTRLEN
];
2814 char grp_str
[INET_ADDRSTRLEN
];
2815 char rpf_addr_str
[PREFIX_STRLEN
];
2816 char rib_nexthop_str
[PREFIX_STRLEN
];
2817 const char *rpf_ifname
;
2818 struct pim_rpf
*rpf
= &up
->rpf
;
2820 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2821 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2822 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2823 sizeof(rpf_addr_str
));
2824 pim_addr_dump("<nexthop?>",
2825 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2826 rib_nexthop_str
, sizeof(rib_nexthop_str
));
2828 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2831 json_object_object_get_ex(json
, grp_str
, &json_group
);
2834 json_group
= json_object_new_object();
2835 json_object_object_add(json
, grp_str
,
2839 json_row
= json_object_new_object();
2840 json_object_string_add(json_row
, "source", src_str
);
2841 json_object_string_add(json_row
, "group", grp_str
);
2842 json_object_string_add(json_row
, "rpfInterface",
2844 json_object_string_add(json_row
, "rpfAddress",
2846 json_object_string_add(json_row
, "ribNexthop",
2848 json_object_int_add(
2849 json_row
, "routeMetric",
2850 rpf
->source_nexthop
.mrib_route_metric
);
2851 json_object_int_add(
2852 json_row
, "routePreference",
2853 rpf
->source_nexthop
.mrib_metric_preference
);
2854 json_object_object_add(json_group
, src_str
, json_row
);
2857 vty_out(vty
, "%-15s %-15s %-16s %-15s %-15s %6d %4d\n",
2858 src_str
, grp_str
, rpf_ifname
, rpf_addr_str
,
2860 rpf
->source_nexthop
.mrib_route_metric
,
2861 rpf
->source_nexthop
.mrib_metric_preference
);
2866 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2867 json
, JSON_C_TO_STRING_PRETTY
));
2868 json_object_free(json
);
2872 struct pnc_cache_walk_data
{
2874 struct pim_instance
*pim
;
2877 static int pim_print_pnc_cache_walkcb(struct hash_bucket
*bucket
, void *arg
)
2879 struct pim_nexthop_cache
*pnc
= bucket
->data
;
2880 struct pnc_cache_walk_data
*cwd
= arg
;
2881 struct vty
*vty
= cwd
->vty
;
2882 struct pim_instance
*pim
= cwd
->pim
;
2883 struct nexthop
*nh_node
= NULL
;
2884 ifindex_t first_ifindex
;
2885 struct interface
*ifp
= NULL
;
2887 for (nh_node
= pnc
->nexthop
; nh_node
; nh_node
= nh_node
->next
) {
2888 first_ifindex
= nh_node
->ifindex
;
2889 ifp
= if_lookup_by_index(first_ifindex
, pim
->vrf_id
);
2891 vty_out(vty
, "%-15s ", inet_ntoa(pnc
->rpf
.rpf_addr
.u
.prefix4
));
2892 vty_out(vty
, "%-16s ", ifp
? ifp
->name
: "NULL");
2893 vty_out(vty
, "%s ", inet_ntoa(nh_node
->gate
.ipv4
));
2899 static void pim_show_nexthop(struct pim_instance
*pim
, struct vty
*vty
)
2901 struct pnc_cache_walk_data cwd
;
2905 vty_out(vty
, "Number of registered addresses: %lu\n",
2906 pim
->rpf_hash
->count
);
2907 vty_out(vty
, "Address Interface Nexthop\n");
2908 vty_out(vty
, "---------------------------------------------\n");
2910 hash_walk(pim
->rpf_hash
, pim_print_pnc_cache_walkcb
, &cwd
);
2913 /* Display the bsm database details */
2914 static void pim_show_bsm_db(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
2916 struct listnode
*bsmnode
;
2919 struct bsm_info
*bsm
;
2920 json_object
*json
= NULL
;
2921 json_object
*json_group
= NULL
;
2922 json_object
*json_row
= NULL
;
2924 count
= pim
->global_scope
.bsm_list
->count
;
2927 json
= json_object_new_object();
2928 json_object_int_add(json
, "Number of the fragments", count
);
2930 vty_out(vty
, "Scope Zone: Global\n");
2931 vty_out(vty
, "Number of the fragments: %d\n", count
);
2935 for (ALL_LIST_ELEMENTS_RO(pim
->global_scope
.bsm_list
, bsmnode
, bsm
)) {
2936 char grp_str
[INET_ADDRSTRLEN
];
2937 char rp_str
[INET_ADDRSTRLEN
];
2938 char bsr_str
[INET_ADDRSTRLEN
];
2939 struct bsmmsg_grpinfo
*group
;
2940 struct bsmmsg_rpinfo
*rpaddr
;
2942 struct bsm_hdr
*hdr
;
2943 uint32_t offset
= 0;
2946 uint32_t frag_rp_cnt
= 0;
2951 /* skip pim header */
2952 buf
+= PIM_MSG_HEADER_LEN
;
2953 len
-= PIM_MSG_HEADER_LEN
;
2955 hdr
= (struct bsm_hdr
*)buf
;
2957 /* BSM starts with bsr header */
2958 buf
+= sizeof(struct bsm_hdr
);
2959 len
-= sizeof(struct bsm_hdr
);
2961 pim_inet4_dump("<BSR Address?>", hdr
->bsr_addr
.addr
, bsr_str
,
2966 json_object_string_add(json
, "BSR address", bsr_str
);
2967 json_object_int_add(json
, "BSR priority",
2969 json_object_int_add(json
, "Hashmask Length",
2971 json_object_int_add(json
, "Fragment Tag",
2972 ntohs(hdr
->frag_tag
));
2974 vty_out(vty
, "BSM Fragment : %d\n", fragment
);
2975 vty_out(vty
, "------------------\n");
2976 vty_out(vty
, "%-15s %-15s %-15s %-15s\n", "BSR-Address",
2977 "BSR-Priority", "Hashmask-len", "Fragment-Tag");
2978 vty_out(vty
, "%-15s %-15d %-15d %-15d\n", bsr_str
,
2979 hdr
->bsr_prio
, hdr
->hm_len
,
2980 ntohs(hdr
->frag_tag
));
2985 while (offset
< len
) {
2986 group
= (struct bsmmsg_grpinfo
*)buf
;
2988 if (group
->group
.family
== PIM_MSG_ADDRESS_FAMILY_IPV4
)
2989 grp
.family
= AF_INET
;
2991 grp
.prefixlen
= group
->group
.mask
;
2992 grp
.u
.prefix4
.s_addr
= group
->group
.addr
.s_addr
;
2994 prefix2str(&grp
, grp_str
, sizeof(grp_str
));
2996 buf
+= sizeof(struct bsmmsg_grpinfo
);
2997 offset
+= sizeof(struct bsmmsg_grpinfo
);
3000 json_object_object_get_ex(json
, grp_str
,
3003 json_group
= json_object_new_object();
3004 json_object_int_add(json_group
,
3007 json_object_int_add(
3008 json_group
, "Fragment Rp count",
3009 group
->frag_rp_count
);
3010 json_object_object_add(json
, grp_str
,
3014 vty_out(vty
, "Group : %s\n", grp_str
);
3015 vty_out(vty
, "-------------------\n");
3016 vty_out(vty
, "Rp Count:%d\n", group
->rp_count
);
3017 vty_out(vty
, "Fragment Rp Count : %d\n",
3018 group
->frag_rp_count
);
3021 frag_rp_cnt
= group
->frag_rp_count
;
3028 "RpAddress HoldTime Priority\n");
3030 while (frag_rp_cnt
--) {
3031 rpaddr
= (struct bsmmsg_rpinfo
*)buf
;
3033 buf
+= sizeof(struct bsmmsg_rpinfo
);
3034 offset
+= sizeof(struct bsmmsg_rpinfo
);
3036 pim_inet4_dump("<Rp addr?>",
3037 rpaddr
->rpaddr
.addr
, rp_str
,
3041 json_row
= json_object_new_object();
3042 json_object_string_add(
3043 json_row
, "Rp Address", rp_str
);
3044 json_object_int_add(
3045 json_row
, "Rp HoldTime",
3046 ntohs(rpaddr
->rp_holdtime
));
3047 json_object_int_add(json_row
,
3050 json_object_object_add(
3051 json_group
, rp_str
, json_row
);
3053 vty_out(vty
, "%-15s %-12d %d\n", rp_str
,
3054 ntohs(rpaddr
->rp_holdtime
),
3065 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3066 json
, JSON_C_TO_STRING_PRETTY
));
3067 json_object_free(json
);
3071 /*Display the group-rp mappings */
3072 static void pim_show_group_rp_mappings_info(struct pim_instance
*pim
,
3073 struct vty
*vty
, bool uj
)
3075 struct bsgrp_node
*bsgrp
;
3076 struct listnode
*rpnode
;
3077 struct bsm_rpinfo
*bsm_rp
;
3078 struct route_node
*rn
;
3079 char bsr_str
[INET_ADDRSTRLEN
];
3080 json_object
*json
= NULL
;
3081 json_object
*json_group
= NULL
;
3082 json_object
*json_row
= NULL
;
3084 if (pim
->global_scope
.current_bsr
.s_addr
== INADDR_ANY
)
3085 strlcpy(bsr_str
, "0.0.0.0", sizeof(bsr_str
));
3088 pim_inet4_dump("<bsr?>", pim
->global_scope
.current_bsr
, bsr_str
,
3092 json
= json_object_new_object();
3093 json_object_string_add(json
, "BSR Address", bsr_str
);
3095 vty_out(vty
, "BSR Address %s\n", bsr_str
);
3098 for (rn
= route_top(pim
->global_scope
.bsrp_table
); rn
;
3099 rn
= route_next(rn
)) {
3100 bsgrp
= (struct bsgrp_node
*)rn
->info
;
3105 char grp_str
[INET_ADDRSTRLEN
];
3107 prefix2str(&bsgrp
->group
, grp_str
, sizeof(grp_str
));
3110 json_object_object_get_ex(json
, grp_str
, &json_group
);
3112 json_group
= json_object_new_object();
3113 json_object_object_add(json
, grp_str
,
3117 vty_out(vty
, "Group Address %s\n", grp_str
);
3118 vty_out(vty
, "--------------------------\n");
3119 vty_out(vty
, "%-15s %-15s %-15s %-15s\n", "Rp Address",
3120 "priority", "Holdtime", "Hash");
3122 vty_out(vty
, "(ACTIVE)\n");
3125 if (bsgrp
->bsrp_list
) {
3126 for (ALL_LIST_ELEMENTS_RO(bsgrp
->bsrp_list
, rpnode
,
3128 char rp_str
[INET_ADDRSTRLEN
];
3130 pim_inet4_dump("<Rp Address?>",
3131 bsm_rp
->rp_address
, rp_str
,
3135 json_row
= json_object_new_object();
3136 json_object_string_add(
3137 json_row
, "Rp Address", rp_str
);
3138 json_object_int_add(
3139 json_row
, "Rp HoldTime",
3140 bsm_rp
->rp_holdtime
);
3141 json_object_int_add(json_row
,
3144 json_object_int_add(json_row
,
3147 json_object_object_add(
3148 json_group
, rp_str
, json_row
);
3152 "%-15s %-15u %-15u %-15u\n",
3153 rp_str
, bsm_rp
->rp_prio
,
3154 bsm_rp
->rp_holdtime
,
3158 if (!bsgrp
->bsrp_list
->count
&& !uj
)
3159 vty_out(vty
, "Active List is empty.\n");
3163 json_object_int_add(json_group
, "Pending RP count",
3164 bsgrp
->pend_rp_cnt
);
3166 vty_out(vty
, "(PENDING)\n");
3167 vty_out(vty
, "Pending RP count :%d\n",
3168 bsgrp
->pend_rp_cnt
);
3169 if (bsgrp
->pend_rp_cnt
)
3170 vty_out(vty
, "%-15s %-15s %-15s %-15s\n",
3171 "Rp Address", "priority", "Holdtime",
3175 if (bsgrp
->partial_bsrp_list
) {
3176 for (ALL_LIST_ELEMENTS_RO(bsgrp
->partial_bsrp_list
,
3178 char rp_str
[INET_ADDRSTRLEN
];
3180 pim_inet4_dump("<Rp Addr?>", bsm_rp
->rp_address
,
3181 rp_str
, sizeof(rp_str
));
3184 json_row
= json_object_new_object();
3185 json_object_string_add(
3186 json_row
, "Rp Address", rp_str
);
3187 json_object_int_add(
3188 json_row
, "Rp HoldTime",
3189 bsm_rp
->rp_holdtime
);
3190 json_object_int_add(json_row
,
3193 json_object_int_add(json_row
,
3196 json_object_object_add(
3197 json_group
, rp_str
, json_row
);
3200 "%-15s %-15u %-15u %-15u\n",
3201 rp_str
, bsm_rp
->rp_prio
,
3202 bsm_rp
->rp_holdtime
,
3206 if (!bsgrp
->partial_bsrp_list
->count
&& !uj
)
3207 vty_out(vty
, "Partial List is empty\n");
3215 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3216 json
, JSON_C_TO_STRING_PRETTY
));
3217 json_object_free(json
);
3221 /* pim statistics - just adding only bsm related now.
3222 * We can continue to add all pim related stats here.
3224 static void pim_show_statistics(struct pim_instance
*pim
, struct vty
*vty
,
3225 const char *ifname
, bool uj
)
3227 json_object
*json
= NULL
;
3228 struct interface
*ifp
;
3231 json
= json_object_new_object();
3232 json_object_int_add(json
, "Number of Received BSMs",
3234 json_object_int_add(json
, "Number of Forwared BSMs",
3236 json_object_int_add(json
, "Number of Dropped BSMs",
3239 vty_out(vty
, "BSM Statistics :\n");
3240 vty_out(vty
, "----------------\n");
3241 vty_out(vty
, "Number of Received BSMs : %" PRIu64
"\n",
3243 vty_out(vty
, "Number of Forwared BSMs : %" PRIu64
"\n",
3245 vty_out(vty
, "Number of Dropped BSMs : %" PRIu64
"\n",
3251 /* scan interfaces */
3252 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3253 struct pim_interface
*pim_ifp
= ifp
->info
;
3255 if (ifname
&& strcmp(ifname
, ifp
->name
))
3262 vty_out(vty
, "Interface : %s\n", ifp
->name
);
3263 vty_out(vty
, "-------------------\n");
3265 "Number of BSMs dropped due to config miss : %u\n",
3266 pim_ifp
->pim_ifstat_bsm_cfg_miss
);
3267 vty_out(vty
, "Number of unicast BSMs dropped : %u\n",
3268 pim_ifp
->pim_ifstat_ucast_bsm_cfg_miss
);
3270 "Number of BSMs dropped due to invalid scope zone : %u\n",
3271 pim_ifp
->pim_ifstat_bsm_invalid_sz
);
3274 json_object
*json_row
= NULL
;
3276 json_row
= json_object_new_object();
3278 json_object_string_add(json_row
, "If Name", ifp
->name
);
3279 json_object_int_add(
3281 "Number of BSMs dropped due to config miss",
3282 pim_ifp
->pim_ifstat_bsm_cfg_miss
);
3283 json_object_int_add(
3284 json_row
, "Number of unicast BSMs dropped",
3285 pim_ifp
->pim_ifstat_ucast_bsm_cfg_miss
);
3286 json_object_int_add(json_row
,
3287 "Number of BSMs dropped due to invalid scope zone",
3288 pim_ifp
->pim_ifstat_bsm_invalid_sz
);
3289 json_object_object_add(json
, ifp
->name
, json_row
);
3295 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3296 json
, JSON_C_TO_STRING_PRETTY
));
3297 json_object_free(json
);
3301 static void clear_pim_statistics(struct pim_instance
*pim
)
3303 struct interface
*ifp
;
3307 pim
->bsm_dropped
= 0;
3309 /* scan interfaces */
3310 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3311 struct pim_interface
*pim_ifp
= ifp
->info
;
3316 pim_ifp
->pim_ifstat_bsm_cfg_miss
= 0;
3317 pim_ifp
->pim_ifstat_ucast_bsm_cfg_miss
= 0;
3318 pim_ifp
->pim_ifstat_bsm_invalid_sz
= 0;
3322 static void igmp_show_groups(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
3324 struct interface
*ifp
;
3326 json_object
*json
= NULL
;
3327 json_object
*json_iface
= NULL
;
3328 json_object
*json_row
= NULL
;
3330 now
= pim_time_monotonic_sec();
3333 json
= json_object_new_object();
3336 "Interface Address Group Mode Timer Srcs V Uptime \n");
3338 /* scan interfaces */
3339 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3340 struct pim_interface
*pim_ifp
= ifp
->info
;
3341 struct listnode
*sock_node
;
3342 struct igmp_sock
*igmp
;
3347 /* scan igmp sockets */
3348 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3350 char ifaddr_str
[INET_ADDRSTRLEN
];
3351 struct listnode
*grpnode
;
3352 struct igmp_group
*grp
;
3354 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3355 sizeof(ifaddr_str
));
3357 /* scan igmp groups */
3358 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3360 char group_str
[INET_ADDRSTRLEN
];
3364 pim_inet4_dump("<group?>", grp
->group_addr
,
3365 group_str
, sizeof(group_str
));
3366 pim_time_timer_to_hhmmss(hhmmss
, sizeof(hhmmss
),
3367 grp
->t_group_timer
);
3368 pim_time_uptime(uptime
, sizeof(uptime
),
3369 now
- grp
->group_creation
);
3372 json_object_object_get_ex(
3373 json
, ifp
->name
, &json_iface
);
3377 json_object_new_object();
3378 json_object_pim_ifp_add(
3380 json_object_object_add(
3385 json_row
= json_object_new_object();
3386 json_object_string_add(
3387 json_row
, "source", ifaddr_str
);
3388 json_object_string_add(
3389 json_row
, "group", group_str
);
3391 if (grp
->igmp_version
== 3)
3392 json_object_string_add(
3394 grp
->group_filtermode_isexcl
3398 json_object_string_add(json_row
,
3400 json_object_int_add(
3401 json_row
, "sourcesCount",
3402 grp
->group_source_list
3404 grp
->group_source_list
)
3406 json_object_int_add(json_row
, "version",
3408 json_object_string_add(
3409 json_row
, "uptime", uptime
);
3410 json_object_object_add(json_iface
,
3416 "%-16s %-15s %-15s %4s %8s %4d %d %8s\n",
3417 ifp
->name
, ifaddr_str
,
3419 grp
->igmp_version
== 3
3420 ? (grp
->group_filtermode_isexcl
3425 grp
->group_source_list
3427 grp
->group_source_list
)
3429 grp
->igmp_version
, uptime
);
3431 } /* scan igmp groups */
3432 } /* scan igmp sockets */
3433 } /* scan interfaces */
3436 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3437 json
, JSON_C_TO_STRING_PRETTY
));
3438 json_object_free(json
);
3442 static void igmp_show_group_retransmission(struct pim_instance
*pim
,
3445 struct interface
*ifp
;
3448 "Interface Address Group RetTimer Counter RetSrcs\n");
3450 /* scan interfaces */
3451 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3452 struct pim_interface
*pim_ifp
= ifp
->info
;
3453 struct listnode
*sock_node
;
3454 struct igmp_sock
*igmp
;
3459 /* scan igmp sockets */
3460 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3462 char ifaddr_str
[INET_ADDRSTRLEN
];
3463 struct listnode
*grpnode
;
3464 struct igmp_group
*grp
;
3466 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3467 sizeof(ifaddr_str
));
3469 /* scan igmp groups */
3470 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3472 char group_str
[INET_ADDRSTRLEN
];
3473 char grp_retr_mmss
[10];
3474 struct listnode
*src_node
;
3475 struct igmp_source
*src
;
3476 int grp_retr_sources
= 0;
3478 pim_inet4_dump("<group?>", grp
->group_addr
,
3479 group_str
, sizeof(group_str
));
3480 pim_time_timer_to_mmss(
3481 grp_retr_mmss
, sizeof(grp_retr_mmss
),
3482 grp
->t_group_query_retransmit_timer
);
3485 /* count group sources with retransmission state
3487 for (ALL_LIST_ELEMENTS_RO(
3488 grp
->group_source_list
, src_node
,
3490 if (src
->source_query_retransmit_count
3496 vty_out(vty
, "%-16s %-15s %-15s %-8s %7d %7d\n",
3497 ifp
->name
, ifaddr_str
, group_str
,
3499 grp
->group_specific_query_retransmit_count
,
3502 } /* scan igmp groups */
3503 } /* scan igmp sockets */
3504 } /* scan interfaces */
3507 static void igmp_show_sources(struct pim_instance
*pim
, struct vty
*vty
)
3509 struct interface
*ifp
;
3512 now
= pim_time_monotonic_sec();
3515 "Interface Address Group Source Timer Fwd Uptime \n");
3517 /* scan interfaces */
3518 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3519 struct pim_interface
*pim_ifp
= ifp
->info
;
3520 struct listnode
*sock_node
;
3521 struct igmp_sock
*igmp
;
3526 /* scan igmp sockets */
3527 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3529 char ifaddr_str
[INET_ADDRSTRLEN
];
3530 struct listnode
*grpnode
;
3531 struct igmp_group
*grp
;
3533 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3534 sizeof(ifaddr_str
));
3536 /* scan igmp groups */
3537 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3539 char group_str
[INET_ADDRSTRLEN
];
3540 struct listnode
*srcnode
;
3541 struct igmp_source
*src
;
3543 pim_inet4_dump("<group?>", grp
->group_addr
,
3544 group_str
, sizeof(group_str
));
3546 /* scan group sources */
3547 for (ALL_LIST_ELEMENTS_RO(
3548 grp
->group_source_list
, srcnode
,
3550 char source_str
[INET_ADDRSTRLEN
];
3555 "<source?>", src
->source_addr
,
3556 source_str
, sizeof(source_str
));
3558 pim_time_timer_to_mmss(
3560 src
->t_source_timer
);
3563 uptime
, sizeof(uptime
),
3564 now
- src
->source_creation
);
3567 "%-16s %-15s %-15s %-15s %5s %3s %8s\n",
3568 ifp
->name
, ifaddr_str
,
3569 group_str
, source_str
, mmss
,
3570 IGMP_SOURCE_TEST_FORWARDING(
3576 } /* scan group sources */
3577 } /* scan igmp groups */
3578 } /* scan igmp sockets */
3579 } /* scan interfaces */
3582 static void igmp_show_source_retransmission(struct pim_instance
*pim
,
3585 struct interface
*ifp
;
3588 "Interface Address Group Source Counter\n");
3590 /* scan interfaces */
3591 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3592 struct pim_interface
*pim_ifp
= ifp
->info
;
3593 struct listnode
*sock_node
;
3594 struct igmp_sock
*igmp
;
3599 /* scan igmp sockets */
3600 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3602 char ifaddr_str
[INET_ADDRSTRLEN
];
3603 struct listnode
*grpnode
;
3604 struct igmp_group
*grp
;
3606 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3607 sizeof(ifaddr_str
));
3609 /* scan igmp groups */
3610 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3612 char group_str
[INET_ADDRSTRLEN
];
3613 struct listnode
*srcnode
;
3614 struct igmp_source
*src
;
3616 pim_inet4_dump("<group?>", grp
->group_addr
,
3617 group_str
, sizeof(group_str
));
3619 /* scan group sources */
3620 for (ALL_LIST_ELEMENTS_RO(
3621 grp
->group_source_list
, srcnode
,
3623 char source_str
[INET_ADDRSTRLEN
];
3626 "<source?>", src
->source_addr
,
3627 source_str
, sizeof(source_str
));
3630 "%-16s %-15s %-15s %-15s %7d\n",
3631 ifp
->name
, ifaddr_str
,
3632 group_str
, source_str
,
3633 src
->source_query_retransmit_count
);
3635 } /* scan group sources */
3636 } /* scan igmp groups */
3637 } /* scan igmp sockets */
3638 } /* scan interfaces */
3641 static void pim_show_bsr(struct pim_instance
*pim
,
3646 char last_bsm_seen
[10];
3649 char bsr_str
[PREFIX_STRLEN
];
3650 json_object
*json
= NULL
;
3652 vty_out(vty
, "PIMv2 Bootstrap information\n");
3654 if (pim
->global_scope
.current_bsr
.s_addr
== INADDR_ANY
) {
3655 strlcpy(bsr_str
, "0.0.0.0", sizeof(bsr_str
));
3656 pim_time_uptime(uptime
, sizeof(uptime
),
3657 pim
->global_scope
.current_bsr_first_ts
);
3658 pim_time_uptime(last_bsm_seen
, sizeof(last_bsm_seen
),
3659 pim
->global_scope
.current_bsr_last_ts
);
3663 pim_inet4_dump("<bsr?>", pim
->global_scope
.current_bsr
,
3664 bsr_str
, sizeof(bsr_str
));
3665 now
= pim_time_monotonic_sec();
3666 pim_time_uptime(uptime
, sizeof(uptime
),
3667 (now
- pim
->global_scope
.current_bsr_first_ts
));
3668 pim_time_uptime(last_bsm_seen
, sizeof(last_bsm_seen
),
3669 now
- pim
->global_scope
.current_bsr_last_ts
);
3672 switch (pim
->global_scope
.state
) {
3674 strlcpy(bsr_state
, "NO_INFO", sizeof(bsr_state
));
3677 strlcpy(bsr_state
, "ACCEPT_ANY", sizeof(bsr_state
));
3679 case ACCEPT_PREFERRED
:
3680 strlcpy(bsr_state
, "ACCEPT_PREFERRED", sizeof(bsr_state
));
3683 strlcpy(bsr_state
, "", sizeof(bsr_state
));
3687 json
= json_object_new_object();
3688 json_object_string_add(json
, "bsr", bsr_str
);
3689 json_object_int_add(json
, "priority",
3690 pim
->global_scope
.current_bsr_prio
);
3691 json_object_int_add(json
, "fragment_tag",
3692 pim
->global_scope
.bsm_frag_tag
);
3693 json_object_string_add(json
, "state", bsr_state
);
3694 json_object_string_add(json
, "upTime", uptime
);
3695 json_object_string_add(json
, "last_bsm_seen", last_bsm_seen
);
3699 vty_out(vty
, "Current preferred BSR address: %s\n", bsr_str
);
3701 "Priority Fragment-Tag State UpTime\n");
3702 vty_out(vty
, " %-12d %-12d %-13s %7s\n",
3703 pim
->global_scope
.current_bsr_prio
,
3704 pim
->global_scope
.bsm_frag_tag
,
3707 vty_out(vty
, "Last BSM seen: %s\n", last_bsm_seen
);
3711 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3712 json
, JSON_C_TO_STRING_PRETTY
));
3713 json_object_free(json
);
3717 static void clear_igmp_interfaces(struct pim_instance
*pim
)
3719 struct interface
*ifp
;
3721 FOR_ALL_INTERFACES (pim
->vrf
, ifp
)
3722 pim_if_addr_del_all_igmp(ifp
);
3724 FOR_ALL_INTERFACES (pim
->vrf
, ifp
)
3725 pim_if_addr_add_all(ifp
);
3728 static void clear_pim_interfaces(struct pim_instance
*pim
)
3730 struct interface
*ifp
;
3732 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3734 pim_neighbor_delete_all(ifp
, "interface cleared");
3739 static void clear_interfaces(struct pim_instance
*pim
)
3741 clear_igmp_interfaces(pim
);
3742 clear_pim_interfaces(pim
);
3745 #define PIM_GET_PIM_INTERFACE(pim_ifp, ifp) \
3746 pim_ifp = ifp->info; \
3749 "%% Enable PIM and/or IGMP on this interface first\n"); \
3750 return CMD_WARNING_CONFIG_FAILED; \
3753 DEFUN (clear_ip_interfaces
,
3754 clear_ip_interfaces_cmd
,
3755 "clear ip interfaces [vrf NAME]",
3758 "Reset interfaces\n"
3762 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3767 clear_interfaces(vrf
->info
);
3772 DEFUN (clear_ip_igmp_interfaces
,
3773 clear_ip_igmp_interfaces_cmd
,
3774 "clear ip igmp [vrf NAME] interfaces",
3779 "Reset IGMP interfaces\n")
3782 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3787 clear_igmp_interfaces(vrf
->info
);
3792 DEFUN (clear_ip_pim_statistics
,
3793 clear_ip_pim_statistics_cmd
,
3794 "clear ip pim statistics [vrf NAME]",
3799 "Reset PIM statistics\n")
3802 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3807 clear_pim_statistics(vrf
->info
);
3811 static void clear_mroute(struct pim_instance
*pim
)
3813 struct pim_upstream
*up
;
3814 struct interface
*ifp
;
3816 /* scan interfaces */
3817 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3818 struct pim_interface
*pim_ifp
= ifp
->info
;
3819 struct listnode
*sock_node
;
3820 struct igmp_sock
*igmp
;
3821 struct pim_ifchannel
*ch
;
3826 /* deleting all ifchannels */
3827 while (!RB_EMPTY(pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
)) {
3828 ch
= RB_ROOT(pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
);
3830 pim_ifchannel_delete(ch
);
3833 /* clean up all igmp groups */
3834 /* scan igmp sockets */
3835 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3838 struct igmp_group
*grp
;
3840 if (igmp
->igmp_group_list
) {
3841 while (igmp
->igmp_group_list
->count
) {
3842 grp
= listnode_head(
3843 igmp
->igmp_group_list
);
3844 igmp_group_delete(grp
);
3851 /* clean up all upstreams*/
3852 if (pim
->upstream_list
) {
3853 while (pim
->upstream_list
->count
) {
3854 up
= listnode_head(pim
->upstream_list
);
3855 pim_upstream_del(pim
, up
, __PRETTY_FUNCTION__
);
3860 DEFUN (clear_ip_mroute
,
3861 clear_ip_mroute_cmd
,
3862 "clear ip mroute [vrf NAME]",
3865 "Reset multicast routes\n"
3869 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3874 clear_mroute(vrf
->info
);
3879 DEFUN (clear_ip_pim_interfaces
,
3880 clear_ip_pim_interfaces_cmd
,
3881 "clear ip pim [vrf NAME] interfaces",
3886 "Reset PIM interfaces\n")
3889 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3894 clear_pim_interfaces(vrf
->info
);
3899 DEFUN (clear_ip_pim_interface_traffic
,
3900 clear_ip_pim_interface_traffic_cmd
,
3901 "clear ip pim [vrf NAME] interface traffic",
3904 "PIM clear commands\n"
3906 "Reset PIM interfaces\n"
3907 "Reset Protocol Packet counters\n")
3910 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3911 struct interface
*ifp
= NULL
;
3912 struct pim_interface
*pim_ifp
= NULL
;
3917 FOR_ALL_INTERFACES (vrf
, ifp
) {
3918 pim_ifp
= ifp
->info
;
3923 pim_ifp
->pim_ifstat_hello_recv
= 0;
3924 pim_ifp
->pim_ifstat_hello_sent
= 0;
3925 pim_ifp
->pim_ifstat_join_recv
= 0;
3926 pim_ifp
->pim_ifstat_join_send
= 0;
3927 pim_ifp
->pim_ifstat_prune_recv
= 0;
3928 pim_ifp
->pim_ifstat_prune_send
= 0;
3929 pim_ifp
->pim_ifstat_reg_recv
= 0;
3930 pim_ifp
->pim_ifstat_reg_send
= 0;
3931 pim_ifp
->pim_ifstat_reg_stop_recv
= 0;
3932 pim_ifp
->pim_ifstat_reg_stop_send
= 0;
3933 pim_ifp
->pim_ifstat_assert_recv
= 0;
3934 pim_ifp
->pim_ifstat_assert_send
= 0;
3935 pim_ifp
->pim_ifstat_bsm_rx
= 0;
3936 pim_ifp
->pim_ifstat_bsm_tx
= 0;
3942 DEFUN (clear_ip_pim_oil
,
3943 clear_ip_pim_oil_cmd
,
3944 "clear ip pim [vrf NAME] oil",
3949 "Rescan PIM OIL (output interface list)\n")
3952 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3957 pim_scan_oil(vrf
->info
);
3962 DEFUN (show_ip_igmp_interface
,
3963 show_ip_igmp_interface_cmd
,
3964 "show ip igmp [vrf NAME] interface [detail|WORD] [json]",
3969 "IGMP interface information\n"
3975 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3976 bool uj
= use_json(argc
, argv
);
3981 if (argv_find(argv
, argc
, "detail", &idx
)
3982 || argv_find(argv
, argc
, "WORD", &idx
))
3983 igmp_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
3985 igmp_show_interfaces(vrf
->info
, vty
, uj
);
3990 DEFUN (show_ip_igmp_interface_vrf_all
,
3991 show_ip_igmp_interface_vrf_all_cmd
,
3992 "show ip igmp vrf all interface [detail|WORD] [json]",
3997 "IGMP interface information\n"
4003 bool uj
= use_json(argc
, argv
);
4009 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4013 vty_out(vty
, " \"%s\": ", vrf
->name
);
4016 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4017 if (argv_find(argv
, argc
, "detail", &idx
)
4018 || argv_find(argv
, argc
, "WORD", &idx
))
4019 igmp_show_interfaces_single(vrf
->info
, vty
,
4020 argv
[idx
]->arg
, uj
);
4022 igmp_show_interfaces(vrf
->info
, vty
, uj
);
4025 vty_out(vty
, "}\n");
4030 DEFUN (show_ip_igmp_join
,
4031 show_ip_igmp_join_cmd
,
4032 "show ip igmp [vrf NAME] join",
4037 "IGMP static join information\n")
4040 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4045 igmp_show_interface_join(vrf
->info
, vty
);
4050 DEFUN (show_ip_igmp_join_vrf_all
,
4051 show_ip_igmp_join_vrf_all_cmd
,
4052 "show ip igmp vrf all join",
4057 "IGMP static join information\n")
4059 bool uj
= use_json(argc
, argv
);
4065 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4069 vty_out(vty
, " \"%s\": ", vrf
->name
);
4072 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4073 igmp_show_interface_join(vrf
->info
, vty
);
4076 vty_out(vty
, "}\n");
4081 DEFUN (show_ip_igmp_groups
,
4082 show_ip_igmp_groups_cmd
,
4083 "show ip igmp [vrf NAME] groups [json]",
4092 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4093 bool uj
= use_json(argc
, argv
);
4098 igmp_show_groups(vrf
->info
, vty
, uj
);
4103 DEFUN (show_ip_igmp_groups_vrf_all
,
4104 show_ip_igmp_groups_vrf_all_cmd
,
4105 "show ip igmp vrf all groups [json]",
4113 bool uj
= use_json(argc
, argv
);
4119 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4123 vty_out(vty
, " \"%s\": ", vrf
->name
);
4126 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4127 igmp_show_groups(vrf
->info
, vty
, uj
);
4130 vty_out(vty
, "}\n");
4135 DEFUN (show_ip_igmp_groups_retransmissions
,
4136 show_ip_igmp_groups_retransmissions_cmd
,
4137 "show ip igmp [vrf NAME] groups retransmissions",
4143 "IGMP group retransmissions\n")
4146 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4151 igmp_show_group_retransmission(vrf
->info
, vty
);
4156 DEFUN (show_ip_igmp_sources
,
4157 show_ip_igmp_sources_cmd
,
4158 "show ip igmp [vrf NAME] sources",
4166 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4171 igmp_show_sources(vrf
->info
, vty
);
4176 DEFUN (show_ip_igmp_sources_retransmissions
,
4177 show_ip_igmp_sources_retransmissions_cmd
,
4178 "show ip igmp [vrf NAME] sources retransmissions",
4184 "IGMP source retransmissions\n")
4187 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4192 igmp_show_source_retransmission(vrf
->info
, vty
);
4197 DEFUN (show_ip_igmp_statistics
,
4198 show_ip_igmp_statistics_cmd
,
4199 "show ip igmp [vrf NAME] statistics [interface WORD] [json]",
4210 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4211 bool uj
= use_json(argc
, argv
);
4216 if (argv_find(argv
, argc
, "WORD", &idx
))
4217 igmp_show_statistics(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
4219 igmp_show_statistics(vrf
->info
, vty
, NULL
, uj
);
4224 DEFUN (show_ip_pim_assert
,
4225 show_ip_pim_assert_cmd
,
4226 "show ip pim [vrf NAME] assert",
4231 "PIM interface assert\n")
4234 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4239 pim_show_assert(vrf
->info
, vty
);
4244 DEFUN (show_ip_pim_assert_internal
,
4245 show_ip_pim_assert_internal_cmd
,
4246 "show ip pim [vrf NAME] assert-internal",
4251 "PIM interface internal assert state\n")
4254 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4259 pim_show_assert_internal(vrf
->info
, vty
);
4264 DEFUN (show_ip_pim_assert_metric
,
4265 show_ip_pim_assert_metric_cmd
,
4266 "show ip pim [vrf NAME] assert-metric",
4271 "PIM interface assert metric\n")
4274 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4279 pim_show_assert_metric(vrf
->info
, vty
);
4284 DEFUN (show_ip_pim_assert_winner_metric
,
4285 show_ip_pim_assert_winner_metric_cmd
,
4286 "show ip pim [vrf NAME] assert-winner-metric",
4291 "PIM interface assert winner metric\n")
4294 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4299 pim_show_assert_winner_metric(vrf
->info
, vty
);
4304 DEFUN (show_ip_pim_interface
,
4305 show_ip_pim_interface_cmd
,
4306 "show ip pim [vrf NAME] interface [detail|WORD] [json]",
4311 "PIM interface information\n"
4317 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4318 bool uj
= use_json(argc
, argv
);
4323 if (argv_find(argv
, argc
, "WORD", &idx
)
4324 || argv_find(argv
, argc
, "detail", &idx
))
4325 pim_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
4327 pim_show_interfaces(vrf
->info
, vty
, uj
);
4332 DEFUN (show_ip_pim_interface_vrf_all
,
4333 show_ip_pim_interface_vrf_all_cmd
,
4334 "show ip pim vrf all interface [detail|WORD] [json]",
4339 "PIM interface information\n"
4345 bool uj
= use_json(argc
, argv
);
4351 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4355 vty_out(vty
, " \"%s\": ", vrf
->name
);
4358 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4359 if (argv_find(argv
, argc
, "WORD", &idx
)
4360 || argv_find(argv
, argc
, "detail", &idx
))
4361 pim_show_interfaces_single(vrf
->info
, vty
,
4362 argv
[idx
]->arg
, uj
);
4364 pim_show_interfaces(vrf
->info
, vty
, uj
);
4367 vty_out(vty
, "}\n");
4372 DEFPY (show_ip_pim_join
,
4373 show_ip_pim_join_cmd
,
4374 "show ip pim [vrf NAME] join [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
4379 "PIM interface join information\n"
4380 "The Source or Group\n"
4384 struct prefix_sg sg
= {0};
4387 struct pim_instance
*pim
;
4389 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
4392 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
4395 pim
= pim_get_pim_instance(v
->vrf_id
);
4398 vty_out(vty
, "%% Unable to find pim instance\n");
4402 if (s_or_g
.s_addr
!= 0) {
4403 if (g
.s_addr
!= 0) {
4410 pim_show_join(pim
, vty
, &sg
, uj
);
4415 DEFUN (show_ip_pim_join_vrf_all
,
4416 show_ip_pim_join_vrf_all_cmd
,
4417 "show ip pim vrf all join [json]",
4422 "PIM interface join information\n"
4425 struct prefix_sg sg
= {0};
4426 bool uj
= use_json(argc
, argv
);
4432 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4436 vty_out(vty
, " \"%s\": ", vrf
->name
);
4439 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4440 pim_show_join(vrf
->info
, vty
, &sg
, uj
);
4443 vty_out(vty
, "}\n");
4448 DEFUN (show_ip_pim_local_membership
,
4449 show_ip_pim_local_membership_cmd
,
4450 "show ip pim [vrf NAME] local-membership [json]",
4455 "PIM interface local-membership\n"
4459 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4460 bool uj
= use_json(argc
, argv
);
4465 pim_show_membership(vrf
->info
, vty
, uj
);
4470 DEFUN (show_ip_pim_neighbor
,
4471 show_ip_pim_neighbor_cmd
,
4472 "show ip pim [vrf NAME] neighbor [detail|WORD] [json]",
4477 "PIM neighbor information\n"
4479 "Name of interface or neighbor\n"
4483 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4484 bool uj
= use_json(argc
, argv
);
4489 if (argv_find(argv
, argc
, "detail", &idx
)
4490 || argv_find(argv
, argc
, "WORD", &idx
))
4491 pim_show_neighbors_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
4493 pim_show_neighbors(vrf
->info
, vty
, uj
);
4498 DEFUN (show_ip_pim_neighbor_vrf_all
,
4499 show_ip_pim_neighbor_vrf_all_cmd
,
4500 "show ip pim vrf all neighbor [detail|WORD] [json]",
4505 "PIM neighbor information\n"
4507 "Name of interface or neighbor\n"
4511 bool uj
= use_json(argc
, argv
);
4517 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4521 vty_out(vty
, " \"%s\": ", vrf
->name
);
4524 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4525 if (argv_find(argv
, argc
, "detail", &idx
)
4526 || argv_find(argv
, argc
, "WORD", &idx
))
4527 pim_show_neighbors_single(vrf
->info
, vty
,
4528 argv
[idx
]->arg
, uj
);
4530 pim_show_neighbors(vrf
->info
, vty
, uj
);
4533 vty_out(vty
, "}\n");
4538 DEFUN (show_ip_pim_secondary
,
4539 show_ip_pim_secondary_cmd
,
4540 "show ip pim [vrf NAME] secondary",
4545 "PIM neighbor addresses\n")
4548 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4553 pim_show_neighbors_secondary(vrf
->info
, vty
);
4558 DEFUN (show_ip_pim_state
,
4559 show_ip_pim_state_cmd
,
4560 "show ip pim [vrf NAME] state [A.B.C.D [A.B.C.D]] [json]",
4565 "PIM state information\n"
4566 "Unicast or Multicast address\n"
4567 "Multicast address\n"
4570 const char *src_or_group
= NULL
;
4571 const char *group
= NULL
;
4573 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4574 bool uj
= use_json(argc
, argv
);
4582 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
4583 src_or_group
= argv
[idx
]->arg
;
4585 group
= argv
[idx
+ 1]->arg
;
4588 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
4593 DEFUN (show_ip_pim_state_vrf_all
,
4594 show_ip_pim_state_vrf_all_cmd
,
4595 "show ip pim vrf all state [A.B.C.D [A.B.C.D]] [json]",
4600 "PIM state information\n"
4601 "Unicast or Multicast address\n"
4602 "Multicast address\n"
4605 const char *src_or_group
= NULL
;
4606 const char *group
= NULL
;
4608 bool uj
= use_json(argc
, argv
);
4617 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
4618 src_or_group
= argv
[idx
]->arg
;
4620 group
= argv
[idx
+ 1]->arg
;
4623 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4627 vty_out(vty
, " \"%s\": ", vrf
->name
);
4630 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4631 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
4634 vty_out(vty
, "}\n");
4639 DEFPY (show_ip_pim_upstream
,
4640 show_ip_pim_upstream_cmd
,
4641 "show ip pim [vrf NAME] upstream [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
4646 "PIM upstream information\n"
4647 "The Source or Group\n"
4651 struct prefix_sg sg
= {0};
4654 struct pim_instance
*pim
;
4656 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
4659 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
4662 pim
= pim_get_pim_instance(v
->vrf_id
);
4665 vty_out(vty
, "%% Unable to find pim instance\n");
4669 if (s_or_g
.s_addr
!= 0) {
4670 if (g
.s_addr
!= 0) {
4676 pim_show_upstream(pim
, vty
, &sg
, uj
);
4681 DEFUN (show_ip_pim_upstream_vrf_all
,
4682 show_ip_pim_upstream_vrf_all_cmd
,
4683 "show ip pim vrf all upstream [json]",
4688 "PIM upstream information\n"
4691 struct prefix_sg sg
= {0};
4692 bool uj
= use_json(argc
, argv
);
4698 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4702 vty_out(vty
, " \"%s\": ", vrf
->name
);
4705 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4706 pim_show_upstream(vrf
->info
, vty
, &sg
, uj
);
4712 DEFUN (show_ip_pim_upstream_join_desired
,
4713 show_ip_pim_upstream_join_desired_cmd
,
4714 "show ip pim [vrf NAME] upstream-join-desired [json]",
4719 "PIM upstream join-desired\n"
4723 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4724 bool uj
= use_json(argc
, argv
);
4729 pim_show_join_desired(vrf
->info
, vty
, uj
);
4734 DEFUN (show_ip_pim_upstream_rpf
,
4735 show_ip_pim_upstream_rpf_cmd
,
4736 "show ip pim [vrf NAME] upstream-rpf [json]",
4741 "PIM upstream source rpf\n"
4745 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4746 bool uj
= use_json(argc
, argv
);
4751 pim_show_upstream_rpf(vrf
->info
, vty
, uj
);
4756 DEFUN (show_ip_pim_rp
,
4758 "show ip pim [vrf NAME] rp-info [json]",
4763 "PIM RP information\n"
4767 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4768 bool uj
= use_json(argc
, argv
);
4773 pim_rp_show_information(vrf
->info
, vty
, uj
);
4778 DEFUN (show_ip_pim_rp_vrf_all
,
4779 show_ip_pim_rp_vrf_all_cmd
,
4780 "show ip pim vrf all rp-info [json]",
4785 "PIM RP information\n"
4788 bool uj
= use_json(argc
, argv
);
4794 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4798 vty_out(vty
, " \"%s\": ", vrf
->name
);
4801 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4802 pim_rp_show_information(vrf
->info
, vty
, uj
);
4805 vty_out(vty
, "}\n");
4810 DEFUN (show_ip_pim_rpf
,
4811 show_ip_pim_rpf_cmd
,
4812 "show ip pim [vrf NAME] rpf [json]",
4817 "PIM cached source rpf information\n"
4821 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4822 bool uj
= use_json(argc
, argv
);
4827 pim_show_rpf(vrf
->info
, vty
, uj
);
4832 DEFUN (show_ip_pim_rpf_vrf_all
,
4833 show_ip_pim_rpf_vrf_all_cmd
,
4834 "show ip pim vrf all rpf [json]",
4839 "PIM cached source rpf information\n"
4842 bool uj
= use_json(argc
, argv
);
4848 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4852 vty_out(vty
, " \"%s\": ", vrf
->name
);
4855 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4856 pim_show_rpf(vrf
->info
, vty
, uj
);
4859 vty_out(vty
, "}\n");
4864 DEFUN (show_ip_pim_nexthop
,
4865 show_ip_pim_nexthop_cmd
,
4866 "show ip pim [vrf NAME] nexthop",
4871 "PIM cached nexthop rpf information\n")
4874 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4879 pim_show_nexthop(vrf
->info
, vty
);
4884 DEFUN (show_ip_pim_nexthop_lookup
,
4885 show_ip_pim_nexthop_lookup_cmd
,
4886 "show ip pim [vrf NAME] nexthop-lookup A.B.C.D A.B.C.D",
4891 "PIM cached nexthop rpf lookup\n"
4892 "Source/RP address\n"
4893 "Multicast Group address\n")
4895 struct prefix nht_p
;
4897 struct in_addr src_addr
, grp_addr
;
4898 struct in_addr vif_source
;
4899 const char *addr_str
, *addr_str1
;
4901 struct pim_nexthop nexthop
;
4902 char nexthop_addr_str
[PREFIX_STRLEN
];
4903 char grp_str
[PREFIX_STRLEN
];
4905 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4910 argv_find(argv
, argc
, "A.B.C.D", &idx
);
4911 addr_str
= argv
[idx
]->arg
;
4912 result
= inet_pton(AF_INET
, addr_str
, &src_addr
);
4914 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
4915 errno
, safe_strerror(errno
));
4919 if (pim_is_group_224_4(src_addr
)) {
4921 "Invalid argument. Expected Valid Source Address.\n");
4925 addr_str1
= argv
[idx
+ 1]->arg
;
4926 result
= inet_pton(AF_INET
, addr_str1
, &grp_addr
);
4928 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
4929 errno
, safe_strerror(errno
));
4933 if (!pim_is_group_224_4(grp_addr
)) {
4935 "Invalid argument. Expected Valid Multicast Group Address.\n");
4939 if (!pim_rp_set_upstream_addr(vrf
->info
, &vif_source
, src_addr
,
4943 nht_p
.family
= AF_INET
;
4944 nht_p
.prefixlen
= IPV4_MAX_BITLEN
;
4945 nht_p
.u
.prefix4
= vif_source
;
4946 grp
.family
= AF_INET
;
4947 grp
.prefixlen
= IPV4_MAX_BITLEN
;
4948 grp
.u
.prefix4
= grp_addr
;
4949 memset(&nexthop
, 0, sizeof(nexthop
));
4951 result
= pim_ecmp_nexthop_lookup(vrf
->info
, &nexthop
, &nht_p
, &grp
, 0);
4955 "Nexthop Lookup failed, no usable routes returned.\n");
4959 pim_addr_dump("<grp?>", &grp
, grp_str
, sizeof(grp_str
));
4960 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
4961 nexthop_addr_str
, sizeof(nexthop_addr_str
));
4962 vty_out(vty
, "Group %s --- Nexthop %s Interface %s \n", grp_str
,
4963 nexthop_addr_str
, nexthop
.interface
->name
);
4968 DEFUN (show_ip_pim_interface_traffic
,
4969 show_ip_pim_interface_traffic_cmd
,
4970 "show ip pim [vrf NAME] interface traffic [WORD] [json]",
4975 "PIM interface information\n"
4976 "Protocol Packet counters\n"
4981 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4982 bool uj
= use_json(argc
, argv
);
4987 if (argv_find(argv
, argc
, "WORD", &idx
))
4988 pim_show_interface_traffic_single(vrf
->info
, vty
,
4989 argv
[idx
]->arg
, uj
);
4991 pim_show_interface_traffic(vrf
->info
, vty
, uj
);
4996 DEFUN (show_ip_pim_bsm_db
,
4997 show_ip_pim_bsm_db_cmd
,
4998 "show ip pim bsm-database [vrf NAME] [json]",
5003 "PIM cached bsm packets information\n"
5007 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5008 bool uj
= use_json(argc
, argv
);
5013 pim_show_bsm_db(vrf
->info
, vty
, uj
);
5017 DEFUN (show_ip_pim_bsrp
,
5018 show_ip_pim_bsrp_cmd
,
5019 "show ip pim bsrp-info [vrf NAME] [json]",
5024 "PIM cached group-rp mappings information\n"
5028 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5029 bool uj
= use_json(argc
, argv
);
5034 pim_show_group_rp_mappings_info(vrf
->info
, vty
, uj
);
5039 DEFUN (show_ip_pim_statistics
,
5040 show_ip_pim_statistics_cmd
,
5041 "show ip pim [vrf NAME] statistics [interface WORD] [json]",
5052 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5053 bool uj
= use_json(argc
, argv
);
5058 if (argv_find(argv
, argc
, "WORD", &idx
))
5059 pim_show_statistics(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
5061 pim_show_statistics(vrf
->info
, vty
, NULL
, uj
);
5066 static void show_multicast_interfaces(struct pim_instance
*pim
, struct vty
*vty
)
5068 struct interface
*ifp
;
5073 "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut\n");
5075 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
5076 struct pim_interface
*pim_ifp
;
5077 struct in_addr ifaddr
;
5078 struct sioc_vif_req vreq
;
5080 pim_ifp
= ifp
->info
;
5085 memset(&vreq
, 0, sizeof(vreq
));
5086 vreq
.vifi
= pim_ifp
->mroute_vif_index
;
5088 if (ioctl(pim
->mroute_socket
, SIOCGETVIFCNT
, &vreq
)) {
5090 "ioctl(SIOCGETVIFCNT=%lu) failure for interface %s vif_index=%d: errno=%d: %s",
5091 (unsigned long)SIOCGETVIFCNT
, ifp
->name
,
5092 pim_ifp
->mroute_vif_index
, errno
,
5093 safe_strerror(errno
));
5096 ifaddr
= pim_ifp
->primary_address
;
5098 vty_out(vty
, "%-16s %-15s %3d %3d %7lu %7lu %10lu %10lu\n",
5099 ifp
->name
, inet_ntoa(ifaddr
), ifp
->ifindex
,
5100 pim_ifp
->mroute_vif_index
, (unsigned long)vreq
.icount
,
5101 (unsigned long)vreq
.ocount
, (unsigned long)vreq
.ibytes
,
5102 (unsigned long)vreq
.obytes
);
5106 static void pim_cmd_show_ip_multicast_helper(struct pim_instance
*pim
,
5109 struct vrf
*vrf
= pim
->vrf
;
5110 time_t now
= pim_time_monotonic_sec();
5116 vty_out(vty
, "Router MLAG Role: %s\n",
5117 mlag_role2str(router
->role
, mlag_role
, sizeof(mlag_role
)));
5118 vty_out(vty
, "Mroute socket descriptor:");
5120 vty_out(vty
, " %d(%s)\n", pim
->mroute_socket
, vrf
->name
);
5122 pim_time_uptime(uptime
, sizeof(uptime
),
5123 now
- pim
->mroute_socket_creation
);
5124 vty_out(vty
, "Mroute socket uptime: %s\n", uptime
);
5128 pim_zebra_zclient_update(vty
);
5129 pim_zlookup_show_ip_multicast(vty
);
5132 vty_out(vty
, "Maximum highest VifIndex: %d\n", PIM_MAX_USABLE_VIFS
);
5135 vty_out(vty
, "Upstream Join Timer: %d secs\n", router
->t_periodic
);
5136 vty_out(vty
, "Join/Prune Holdtime: %d secs\n", PIM_JP_HOLDTIME
);
5137 vty_out(vty
, "PIM ECMP: %s\n", pim
->ecmp_enable
? "Enable" : "Disable");
5138 vty_out(vty
, "PIM ECMP Rebalance: %s\n",
5139 pim
->ecmp_rebalance_enable
? "Enable" : "Disable");
5143 show_rpf_refresh_stats(vty
, pim
, now
, NULL
);
5147 show_scan_oil_stats(pim
, vty
, now
);
5149 show_multicast_interfaces(pim
, vty
);
5152 DEFUN (show_ip_multicast
,
5153 show_ip_multicast_cmd
,
5154 "show ip multicast [vrf NAME]",
5158 "Multicast global information\n")
5161 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5166 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
5171 DEFUN (show_ip_multicast_vrf_all
,
5172 show_ip_multicast_vrf_all_cmd
,
5173 "show ip multicast vrf all",
5177 "Multicast global information\n")
5179 bool uj
= use_json(argc
, argv
);
5185 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5189 vty_out(vty
, " \"%s\": ", vrf
->name
);
5192 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5193 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
5196 vty_out(vty
, "}\n");
5201 static void show_mroute(struct pim_instance
*pim
, struct vty
*vty
,
5202 struct prefix_sg
*sg
, bool fill
, bool uj
)
5204 struct listnode
*node
;
5205 struct channel_oil
*c_oil
;
5206 struct static_route
*s_route
;
5208 json_object
*json
= NULL
;
5209 json_object
*json_group
= NULL
;
5210 json_object
*json_source
= NULL
;
5211 json_object
*json_oil
= NULL
;
5212 json_object
*json_ifp_out
= NULL
;
5215 char grp_str
[INET_ADDRSTRLEN
];
5216 char src_str
[INET_ADDRSTRLEN
];
5217 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
5218 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
5220 struct interface
*ifp_in
;
5224 json
= json_object_new_object();
5227 "Source Group Proto Input Output TTL Uptime\n");
5230 now
= pim_time_monotonic_sec();
5232 /* print list of PIM and IGMP routes */
5233 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
5236 if (!c_oil
->installed
&& !uj
)
5239 if (sg
->grp
.s_addr
!= 0 &&
5240 sg
->grp
.s_addr
!= c_oil
->oil
.mfcc_mcastgrp
.s_addr
)
5242 if (sg
->src
.s_addr
!= 0 &&
5243 sg
->src
.s_addr
!= c_oil
->oil
.mfcc_origin
.s_addr
)
5246 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
5248 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
5250 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
5253 strlcpy(in_ifname
, ifp_in
->name
, sizeof(in_ifname
));
5255 strlcpy(in_ifname
, "<iif?>", sizeof(in_ifname
));
5259 /* Find the group, create it if it doesn't exist */
5260 json_object_object_get_ex(json
, grp_str
, &json_group
);
5263 json_group
= json_object_new_object();
5264 json_object_object_add(json
, grp_str
,
5268 /* Find the source nested under the group, create it if
5269 * it doesn't exist */
5270 json_object_object_get_ex(json_group
, src_str
,
5274 json_source
= json_object_new_object();
5275 json_object_object_add(json_group
, src_str
,
5279 /* Find the inbound interface nested under the source,
5280 * create it if it doesn't exist */
5281 json_object_int_add(json_source
, "installed",
5283 json_object_int_add(json_source
, "refCount",
5284 c_oil
->oil_ref_count
);
5285 json_object_int_add(json_source
, "oilSize",
5287 json_object_int_add(json_source
, "OilInheritedRescan",
5288 c_oil
->oil_inherited_rescan
);
5289 json_object_string_add(json_source
, "iif", in_ifname
);
5293 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
5295 struct interface
*ifp_out
;
5296 char mroute_uptime
[10];
5299 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
5303 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
5305 mroute_uptime
, sizeof(mroute_uptime
),
5306 now
- c_oil
->mroute_creation
);
5310 strlcpy(out_ifname
, ifp_out
->name
, sizeof(out_ifname
));
5312 strlcpy(out_ifname
, "<oif?>", sizeof(out_ifname
));
5315 json_ifp_out
= json_object_new_object();
5316 json_object_string_add(json_ifp_out
, "source",
5318 json_object_string_add(json_ifp_out
, "group",
5321 if (c_oil
->oif_flags
[oif_vif_index
]
5322 & PIM_OIF_FLAG_PROTO_PIM
)
5323 json_object_boolean_true_add(
5324 json_ifp_out
, "protocolPim");
5326 if (c_oil
->oif_flags
[oif_vif_index
]
5327 & PIM_OIF_FLAG_PROTO_IGMP
)
5328 json_object_boolean_true_add(
5329 json_ifp_out
, "protocolIgmp");
5331 if (c_oil
->oif_flags
[oif_vif_index
]
5332 & PIM_OIF_FLAG_PROTO_VXLAN
)
5333 json_object_boolean_true_add(
5334 json_ifp_out
, "protocolVxlan");
5336 if (c_oil
->oif_flags
[oif_vif_index
]
5337 & PIM_OIF_FLAG_PROTO_SOURCE
)
5338 json_object_boolean_true_add(
5339 json_ifp_out
, "protocolSource");
5341 if (c_oil
->oif_flags
[oif_vif_index
]
5342 & PIM_OIF_FLAG_PROTO_STAR
)
5343 json_object_boolean_true_add(
5345 "protocolInherited");
5347 json_object_string_add(json_ifp_out
,
5350 json_object_int_add(json_ifp_out
, "iVifI",
5351 c_oil
->oil
.mfcc_parent
);
5352 json_object_string_add(json_ifp_out
,
5353 "outboundInterface",
5355 json_object_int_add(json_ifp_out
, "oVifI",
5357 json_object_int_add(json_ifp_out
, "ttl", ttl
);
5358 json_object_string_add(json_ifp_out
, "upTime",
5361 json_oil
= json_object_new_object();
5362 json_object_object_add(json_source
,
5365 json_object_object_add(json_oil
, out_ifname
,
5368 if (c_oil
->oif_flags
[oif_vif_index
]
5369 & PIM_OIF_FLAG_PROTO_PIM
) {
5370 strlcpy(proto
, "PIM", sizeof(proto
));
5373 if (c_oil
->oif_flags
[oif_vif_index
]
5374 & PIM_OIF_FLAG_PROTO_IGMP
) {
5375 strlcpy(proto
, "IGMP", sizeof(proto
));
5378 if (c_oil
->oif_flags
[oif_vif_index
]
5379 & PIM_OIF_FLAG_PROTO_VXLAN
) {
5380 strlcpy(proto
, "VxLAN", sizeof(proto
));
5383 if (c_oil
->oif_flags
[oif_vif_index
]
5384 & PIM_OIF_FLAG_PROTO_SOURCE
) {
5385 strlcpy(proto
, "SRC", sizeof(proto
));
5388 if (c_oil
->oif_flags
[oif_vif_index
]
5389 & PIM_OIF_FLAG_PROTO_STAR
) {
5390 strlcpy(proto
, "STAR", sizeof(proto
));
5394 "%-15s %-15s %-6s %-16s %-16s %-3d %8s\n",
5395 src_str
, grp_str
, proto
, in_ifname
,
5396 out_ifname
, ttl
, mroute_uptime
);
5401 in_ifname
[0] = '\0';
5407 if (!uj
&& !found_oif
) {
5408 vty_out(vty
, "%-15s %-15s %-6s %-16s %-16s %-3d %8s\n",
5409 src_str
, grp_str
, "none", in_ifname
, "none", 0,
5414 /* Print list of static routes */
5415 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
5418 if (!s_route
->c_oil
.installed
)
5421 pim_inet4_dump("<group?>", s_route
->group
, grp_str
,
5423 pim_inet4_dump("<source?>", s_route
->source
, src_str
,
5425 ifp_in
= pim_if_find_by_vif_index(pim
, s_route
->iif
);
5429 strlcpy(in_ifname
, ifp_in
->name
, sizeof(in_ifname
));
5431 strlcpy(in_ifname
, "<iif?>", sizeof(in_ifname
));
5435 /* Find the group, create it if it doesn't exist */
5436 json_object_object_get_ex(json
, grp_str
, &json_group
);
5439 json_group
= json_object_new_object();
5440 json_object_object_add(json
, grp_str
,
5444 /* Find the source nested under the group, create it if
5445 * it doesn't exist */
5446 json_object_object_get_ex(json_group
, src_str
,
5450 json_source
= json_object_new_object();
5451 json_object_object_add(json_group
, src_str
,
5455 json_object_string_add(json_source
, "iif", in_ifname
);
5458 strlcpy(proto
, "STATIC", sizeof(proto
));
5461 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
5463 struct interface
*ifp_out
;
5464 char oif_uptime
[10];
5467 ttl
= s_route
->oif_ttls
[oif_vif_index
];
5471 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
5473 oif_uptime
, sizeof(oif_uptime
),
5476 .oif_creation
[oif_vif_index
]);
5480 strlcpy(out_ifname
, ifp_out
->name
, sizeof(out_ifname
));
5482 strlcpy(out_ifname
, "<oif?>", sizeof(out_ifname
));
5485 json_ifp_out
= json_object_new_object();
5486 json_object_string_add(json_ifp_out
, "source",
5488 json_object_string_add(json_ifp_out
, "group",
5490 json_object_boolean_true_add(json_ifp_out
,
5492 json_object_string_add(json_ifp_out
,
5495 json_object_int_add(
5496 json_ifp_out
, "iVifI",
5497 s_route
->c_oil
.oil
.mfcc_parent
);
5498 json_object_string_add(json_ifp_out
,
5499 "outboundInterface",
5501 json_object_int_add(json_ifp_out
, "oVifI",
5503 json_object_int_add(json_ifp_out
, "ttl", ttl
);
5504 json_object_string_add(json_ifp_out
, "upTime",
5507 json_oil
= json_object_new_object();
5508 json_object_object_add(json_source
,
5511 json_object_object_add(json_oil
, out_ifname
,
5515 "%-15s %-15s %-6s %-16s %-16s %-3d %8s %s\n",
5516 src_str
, grp_str
, proto
, in_ifname
,
5517 out_ifname
, ttl
, oif_uptime
,
5519 if (first
&& !fill
) {
5522 in_ifname
[0] = '\0';
5528 if (!uj
&& !found_oif
) {
5530 "%-15s %-15s %-6s %-16s %-16s %-3d %8s %s\n",
5531 src_str
, grp_str
, proto
, in_ifname
, "none", 0,
5532 "--:--:--", pim
->vrf
->name
);
5537 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5538 json
, JSON_C_TO_STRING_PRETTY
));
5539 json_object_free(json
);
5543 DEFPY (show_ip_mroute
,
5545 "show ip mroute [vrf NAME] [A.B.C.D$s_or_g [A.B.C.D$g]] [fill$fill] [json$json]",
5550 "The Source or Group\n"
5552 "Fill in Assumed data\n"
5555 struct prefix_sg sg
= {0};
5556 struct pim_instance
*pim
;
5559 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
5562 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
5565 pim
= pim_get_pim_instance(v
->vrf_id
);
5568 vty_out(vty
, "%% Unable to find pim instance\n");
5572 if (s_or_g
.s_addr
!= 0) {
5573 if (g
.s_addr
!= 0) {
5579 show_mroute(pim
, vty
, &sg
, !!fill
, !!json
);
5583 DEFUN (show_ip_mroute_vrf_all
,
5584 show_ip_mroute_vrf_all_cmd
,
5585 "show ip mroute vrf all [fill] [json]",
5590 "Fill in Assumed data\n"
5593 struct prefix_sg sg
= {0};
5594 bool uj
= use_json(argc
, argv
);
5600 if (argv_find(argv
, argc
, "fill", &idx
))
5605 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5609 vty_out(vty
, " \"%s\": ", vrf
->name
);
5612 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5613 show_mroute(vrf
->info
, vty
, &sg
, fill
, uj
);
5616 vty_out(vty
, "}\n");
5621 DEFUN (clear_ip_mroute_count
,
5622 clear_ip_mroute_count_cmd
,
5623 "clear ip mroute [vrf NAME] count",
5628 "Route and packet count data\n")
5631 struct listnode
*node
;
5632 struct channel_oil
*c_oil
;
5633 struct static_route
*sr
;
5634 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5635 struct pim_instance
*pim
;
5641 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
5642 if (!c_oil
->installed
)
5645 pim_mroute_update_counters(c_oil
);
5646 c_oil
->cc
.origpktcnt
= c_oil
->cc
.pktcnt
;
5647 c_oil
->cc
.origbytecnt
= c_oil
->cc
.bytecnt
;
5648 c_oil
->cc
.origwrong_if
= c_oil
->cc
.wrong_if
;
5651 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, sr
)) {
5652 if (!sr
->c_oil
.installed
)
5655 pim_mroute_update_counters(&sr
->c_oil
);
5657 sr
->c_oil
.cc
.origpktcnt
= sr
->c_oil
.cc
.pktcnt
;
5658 sr
->c_oil
.cc
.origbytecnt
= sr
->c_oil
.cc
.bytecnt
;
5659 sr
->c_oil
.cc
.origwrong_if
= sr
->c_oil
.cc
.wrong_if
;
5664 static void show_mroute_count(struct pim_instance
*pim
, struct vty
*vty
)
5666 struct listnode
*node
;
5667 struct channel_oil
*c_oil
;
5668 struct static_route
*sr
;
5673 "Source Group LastUsed Packets Bytes WrongIf \n");
5675 /* Print PIM and IGMP route counts */
5676 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
5677 char group_str
[INET_ADDRSTRLEN
];
5678 char source_str
[INET_ADDRSTRLEN
];
5680 if (!c_oil
->installed
)
5683 pim_mroute_update_counters(c_oil
);
5685 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, group_str
,
5687 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, source_str
,
5688 sizeof(source_str
));
5690 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
5691 source_str
, group_str
, c_oil
->cc
.lastused
/ 100,
5692 c_oil
->cc
.pktcnt
- c_oil
->cc
.origpktcnt
,
5693 c_oil
->cc
.bytecnt
- c_oil
->cc
.origbytecnt
,
5694 c_oil
->cc
.wrong_if
- c_oil
->cc
.origwrong_if
);
5697 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, sr
)) {
5698 char group_str
[INET_ADDRSTRLEN
];
5699 char source_str
[INET_ADDRSTRLEN
];
5701 if (!sr
->c_oil
.installed
)
5704 pim_mroute_update_counters(&sr
->c_oil
);
5706 pim_inet4_dump("<group?>", sr
->c_oil
.oil
.mfcc_mcastgrp
,
5707 group_str
, sizeof(group_str
));
5708 pim_inet4_dump("<source?>", sr
->c_oil
.oil
.mfcc_origin
,
5709 source_str
, sizeof(source_str
));
5711 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
5712 source_str
, group_str
, sr
->c_oil
.cc
.lastused
,
5713 sr
->c_oil
.cc
.pktcnt
- sr
->c_oil
.cc
.origpktcnt
,
5714 sr
->c_oil
.cc
.bytecnt
- sr
->c_oil
.cc
.origbytecnt
,
5715 sr
->c_oil
.cc
.wrong_if
- sr
->c_oil
.cc
.origwrong_if
);
5719 DEFUN (show_ip_mroute_count
,
5720 show_ip_mroute_count_cmd
,
5721 "show ip mroute [vrf NAME] count",
5726 "Route and packet count data\n")
5729 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5734 show_mroute_count(vrf
->info
, vty
);
5738 DEFUN (show_ip_mroute_count_vrf_all
,
5739 show_ip_mroute_count_vrf_all_cmd
,
5740 "show ip mroute vrf all count",
5745 "Route and packet count data\n")
5747 bool uj
= use_json(argc
, argv
);
5753 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5757 vty_out(vty
, " \"%s\": ", vrf
->name
);
5760 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5761 show_mroute_count(vrf
->info
, vty
);
5764 vty_out(vty
, "}\n");
5769 static void show_mroute_summary(struct pim_instance
*pim
, struct vty
*vty
)
5771 struct listnode
*node
;
5772 struct channel_oil
*c_oil
;
5773 struct static_route
*s_route
;
5774 uint32_t starg_sw_mroute_cnt
= 0;
5775 uint32_t sg_sw_mroute_cnt
= 0;
5776 uint32_t starg_hw_mroute_cnt
= 0;
5777 uint32_t sg_hw_mroute_cnt
= 0;
5779 vty_out(vty
, "Mroute Type Installed/Total\n");
5781 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
5782 if (!c_oil
->installed
) {
5783 if (c_oil
->oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
5784 starg_sw_mroute_cnt
++;
5788 if (c_oil
->oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
5789 starg_hw_mroute_cnt
++;
5795 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
5796 if (!s_route
->c_oil
.installed
) {
5797 if (s_route
->c_oil
.oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
5798 starg_sw_mroute_cnt
++;
5802 if (s_route
->c_oil
.oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
5803 starg_hw_mroute_cnt
++;
5809 vty_out(vty
, "%-20s %d/%d\n", "(*, G)", starg_hw_mroute_cnt
,
5810 starg_sw_mroute_cnt
+ starg_hw_mroute_cnt
);
5811 vty_out(vty
, "%-20s %d/%d\n", "(S, G)", sg_hw_mroute_cnt
,
5812 sg_sw_mroute_cnt
+ sg_hw_mroute_cnt
);
5813 vty_out(vty
, "------\n");
5814 vty_out(vty
, "%-20s %d/%d\n", "Total",
5815 (starg_hw_mroute_cnt
+ sg_hw_mroute_cnt
),
5816 (starg_sw_mroute_cnt
+
5817 starg_hw_mroute_cnt
+
5822 DEFUN (show_ip_mroute_summary
,
5823 show_ip_mroute_summary_cmd
,
5824 "show ip mroute [vrf NAME] summary",
5829 "Summary of all mroutes\n")
5832 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5837 show_mroute_summary(vrf
->info
, vty
);
5841 DEFUN (show_ip_mroute_summary_vrf_all
,
5842 show_ip_mroute_summary_vrf_all_cmd
,
5843 "show ip mroute vrf all summary",
5848 "Summary of all mroutes\n")
5852 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5853 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5854 show_mroute_summary(vrf
->info
, vty
);
5862 "show ip rib [vrf NAME] A.B.C.D",
5867 "Unicast address\n")
5870 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5871 struct in_addr addr
;
5872 const char *addr_str
;
5873 struct pim_nexthop nexthop
;
5874 char nexthop_addr_str
[PREFIX_STRLEN
];
5880 memset(&nexthop
, 0, sizeof(nexthop
));
5881 argv_find(argv
, argc
, "A.B.C.D", &idx
);
5882 addr_str
= argv
[idx
]->arg
;
5883 result
= inet_pton(AF_INET
, addr_str
, &addr
);
5885 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
5886 errno
, safe_strerror(errno
));
5890 if (!pim_nexthop_lookup(vrf
->info
, &nexthop
, addr
, 0)) {
5892 "Failure querying RIB nexthop for unicast address %s\n",
5898 "Address NextHop Interface Metric Preference\n");
5900 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
5901 nexthop_addr_str
, sizeof(nexthop_addr_str
));
5903 vty_out(vty
, "%-15s %-15s %-9s %6d %10d\n", addr_str
, nexthop_addr_str
,
5904 nexthop
.interface
? nexthop
.interface
->name
: "<ifname?>",
5905 nexthop
.mrib_route_metric
, nexthop
.mrib_metric_preference
);
5910 static void show_ssmpingd(struct pim_instance
*pim
, struct vty
*vty
)
5912 struct listnode
*node
;
5913 struct ssmpingd_sock
*ss
;
5917 "Source Socket Address Port Uptime Requests\n");
5919 if (!pim
->ssmpingd_list
)
5922 now
= pim_time_monotonic_sec();
5924 for (ALL_LIST_ELEMENTS_RO(pim
->ssmpingd_list
, node
, ss
)) {
5925 char source_str
[INET_ADDRSTRLEN
];
5927 struct sockaddr_in bind_addr
;
5928 socklen_t len
= sizeof(bind_addr
);
5929 char bind_addr_str
[INET_ADDRSTRLEN
];
5931 pim_inet4_dump("<src?>", ss
->source_addr
, source_str
,
5932 sizeof(source_str
));
5934 if (pim_socket_getsockname(
5935 ss
->sock_fd
, (struct sockaddr
*)&bind_addr
, &len
)) {
5937 "%% Failure reading socket name for ssmpingd source %s on fd=%d\n",
5938 source_str
, ss
->sock_fd
);
5941 pim_inet4_dump("<addr?>", bind_addr
.sin_addr
, bind_addr_str
,
5942 sizeof(bind_addr_str
));
5943 pim_time_uptime(ss_uptime
, sizeof(ss_uptime
),
5944 now
- ss
->creation
);
5946 vty_out(vty
, "%-15s %6d %-15s %5d %8s %8lld\n", source_str
,
5947 ss
->sock_fd
, bind_addr_str
, ntohs(bind_addr
.sin_port
),
5948 ss_uptime
, (long long)ss
->requests
);
5952 DEFUN (show_ip_ssmpingd
,
5953 show_ip_ssmpingd_cmd
,
5954 "show ip ssmpingd [vrf NAME]",
5961 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5966 show_ssmpingd(vrf
->info
, vty
);
5970 static int pim_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
5971 const char *rp
, const char *group
,
5976 result
= pim_rp_new_config(pim
, rp
, group
, plist
);
5978 if (result
== PIM_GROUP_BAD_ADDR_MASK_COMBO
) {
5979 vty_out(vty
, "%% Inconsistent address and mask: %s\n",
5981 return CMD_WARNING_CONFIG_FAILED
;
5984 if (result
== PIM_GROUP_BAD_ADDRESS
) {
5985 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
5986 return CMD_WARNING_CONFIG_FAILED
;
5989 if (result
== PIM_RP_BAD_ADDRESS
) {
5990 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
5991 return CMD_WARNING_CONFIG_FAILED
;
5994 if (result
== PIM_RP_NO_PATH
) {
5995 vty_out(vty
, "%% No Path to RP address specified: %s\n", rp
);
5999 if (result
== PIM_GROUP_OVERLAP
) {
6001 "%% Group range specified cannot exact match another\n");
6002 return CMD_WARNING_CONFIG_FAILED
;
6005 if (result
== PIM_GROUP_PFXLIST_OVERLAP
) {
6007 "%% This group is already covered by a RP prefix-list\n");
6008 return CMD_WARNING_CONFIG_FAILED
;
6011 if (result
== PIM_RP_PFXLIST_IN_USE
) {
6013 "%% The same prefix-list cannot be applied to multiple RPs\n");
6014 return CMD_WARNING_CONFIG_FAILED
;
6017 if (result
== PIM_GROUP_BAD_ADDR_MASK_COMBO
) {
6018 vty_out(vty
, "%% Inconsistent address and mask: %s\n",
6020 return CMD_WARNING_CONFIG_FAILED
;
6026 static int pim_cmd_spt_switchover(struct pim_instance
*pim
,
6027 enum pim_spt_switchover spt
,
6030 pim
->spt
.switchover
= spt
;
6032 switch (pim
->spt
.switchover
) {
6033 case PIM_SPT_IMMEDIATE
:
6034 XFREE(MTYPE_PIM_SPT_PLIST_NAME
, pim
->spt
.plist
);
6036 pim_upstream_add_lhr_star_pimreg(pim
);
6038 case PIM_SPT_INFINITY
:
6039 pim_upstream_remove_lhr_star_pimreg(pim
, plist
);
6041 XFREE(MTYPE_PIM_SPT_PLIST_NAME
, pim
->spt
.plist
);
6045 XSTRDUP(MTYPE_PIM_SPT_PLIST_NAME
, plist
);
6052 DEFUN (ip_pim_spt_switchover_infinity
,
6053 ip_pim_spt_switchover_infinity_cmd
,
6054 "ip pim spt-switchover infinity-and-beyond",
6058 "Never switch to SPT Tree\n")
6060 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6061 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, NULL
);
6064 DEFUN (ip_pim_spt_switchover_infinity_plist
,
6065 ip_pim_spt_switchover_infinity_plist_cmd
,
6066 "ip pim spt-switchover infinity-and-beyond prefix-list WORD",
6070 "Never switch to SPT Tree\n"
6071 "Prefix-List to control which groups to switch\n"
6072 "Prefix-List name\n")
6074 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6075 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, argv
[5]->arg
);
6078 DEFUN (no_ip_pim_spt_switchover_infinity
,
6079 no_ip_pim_spt_switchover_infinity_cmd
,
6080 "no ip pim spt-switchover infinity-and-beyond",
6085 "Never switch to SPT Tree\n")
6087 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6088 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
6091 DEFUN (no_ip_pim_spt_switchover_infinity_plist
,
6092 no_ip_pim_spt_switchover_infinity_plist_cmd
,
6093 "no ip pim spt-switchover infinity-and-beyond prefix-list WORD",
6098 "Never switch to SPT Tree\n"
6099 "Prefix-List to control which groups to switch\n"
6100 "Prefix-List name\n")
6102 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6103 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
6106 DEFUN (ip_pim_joinprune_time
,
6107 ip_pim_joinprune_time_cmd
,
6108 "ip pim join-prune-interval (60-600)",
6110 "pim multicast routing\n"
6111 "Join Prune Send Interval\n"
6114 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6115 router
->t_periodic
= atoi(argv
[3]->arg
);
6119 DEFUN (no_ip_pim_joinprune_time
,
6120 no_ip_pim_joinprune_time_cmd
,
6121 "no ip pim join-prune-interval (60-600)",
6124 "pim multicast routing\n"
6125 "Join Prune Send Interval\n"
6128 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6129 router
->t_periodic
= PIM_DEFAULT_T_PERIODIC
;
6133 DEFUN (ip_pim_register_suppress
,
6134 ip_pim_register_suppress_cmd
,
6135 "ip pim register-suppress-time (5-60000)",
6137 "pim multicast routing\n"
6138 "Register Suppress Timer\n"
6141 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6142 router
->register_suppress_time
= atoi(argv
[3]->arg
);
6146 DEFUN (no_ip_pim_register_suppress
,
6147 no_ip_pim_register_suppress_cmd
,
6148 "no ip pim register-suppress-time (5-60000)",
6151 "pim multicast routing\n"
6152 "Register Suppress Timer\n"
6155 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6156 router
->register_suppress_time
= PIM_REGISTER_SUPPRESSION_TIME_DEFAULT
;
6160 DEFUN (ip_pim_rp_keep_alive
,
6161 ip_pim_rp_keep_alive_cmd
,
6162 "ip pim rp keep-alive-timer (31-60000)",
6164 "pim multicast routing\n"
6166 "Keep alive Timer\n"
6169 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6170 pim
->rp_keep_alive_time
= atoi(argv
[4]->arg
);
6174 DEFUN (no_ip_pim_rp_keep_alive
,
6175 no_ip_pim_rp_keep_alive_cmd
,
6176 "no ip pim rp keep-alive-timer (31-60000)",
6179 "pim multicast routing\n"
6181 "Keep alive Timer\n"
6184 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6185 pim
->rp_keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
6189 DEFUN (ip_pim_keep_alive
,
6190 ip_pim_keep_alive_cmd
,
6191 "ip pim keep-alive-timer (31-60000)",
6193 "pim multicast routing\n"
6194 "Keep alive Timer\n"
6197 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6198 pim
->keep_alive_time
= atoi(argv
[3]->arg
);
6202 DEFUN (no_ip_pim_keep_alive
,
6203 no_ip_pim_keep_alive_cmd
,
6204 "no ip pim keep-alive-timer (31-60000)",
6207 "pim multicast routing\n"
6208 "Keep alive Timer\n"
6211 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6212 pim
->keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
6216 DEFUN (ip_pim_packets
,
6218 "ip pim packets (1-100)",
6220 "pim multicast routing\n"
6221 "packets to process at one time per fd\n"
6222 "Number of packets\n")
6224 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6225 router
->packet_process
= atoi(argv
[3]->arg
);
6229 DEFUN (no_ip_pim_packets
,
6230 no_ip_pim_packets_cmd
,
6231 "no ip pim packets (1-100)",
6234 "pim multicast routing\n"
6235 "packets to process at one time per fd\n"
6236 "Number of packets\n")
6238 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6239 router
->packet_process
= PIM_DEFAULT_PACKET_PROCESS
;
6243 DEFUN (ip_pim_v6_secondary
,
6244 ip_pim_v6_secondary_cmd
,
6245 "ip pim send-v6-secondary",
6247 "pim multicast routing\n"
6248 "Send v6 secondary addresses\n")
6250 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6251 pim
->send_v6_secondary
= 1;
6256 DEFUN (no_ip_pim_v6_secondary
,
6257 no_ip_pim_v6_secondary_cmd
,
6258 "no ip pim send-v6-secondary",
6261 "pim multicast routing\n"
6262 "Send v6 secondary addresses\n")
6264 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6265 pim
->send_v6_secondary
= 0;
6272 "ip pim rp A.B.C.D [A.B.C.D/M]",
6274 "pim multicast routing\n"
6276 "ip address of RP\n"
6277 "Group Address range to cover\n")
6279 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6282 if (argc
== (idx_ipv4
+ 1))
6283 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
6286 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
6287 argv
[idx_ipv4
+ 1]->arg
, NULL
);
6290 DEFUN (ip_pim_rp_prefix_list
,
6291 ip_pim_rp_prefix_list_cmd
,
6292 "ip pim rp A.B.C.D prefix-list WORD",
6294 "pim multicast routing\n"
6296 "ip address of RP\n"
6297 "group prefix-list filter\n"
6298 "Name of a prefix-list\n")
6300 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6301 return pim_rp_cmd_worker(pim
, vty
, argv
[3]->arg
, NULL
, argv
[5]->arg
);
6304 static int pim_no_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
6305 const char *rp
, const char *group
,
6308 int result
= pim_rp_del_config(pim
, rp
, group
, plist
);
6310 if (result
== PIM_GROUP_BAD_ADDRESS
) {
6311 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
6312 return CMD_WARNING_CONFIG_FAILED
;
6315 if (result
== PIM_RP_BAD_ADDRESS
) {
6316 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
6317 return CMD_WARNING_CONFIG_FAILED
;
6320 if (result
== PIM_RP_NOT_FOUND
) {
6321 vty_out(vty
, "%% Unable to find specified RP\n");
6322 return CMD_WARNING_CONFIG_FAILED
;
6328 DEFUN (no_ip_pim_rp
,
6330 "no ip pim rp A.B.C.D [A.B.C.D/M]",
6333 "pim multicast routing\n"
6335 "ip address of RP\n"
6336 "Group Address range to cover\n")
6338 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6339 int idx_ipv4
= 4, idx_group
= 0;
6341 if (argv_find(argv
, argc
, "A.B.C.D/M", &idx_group
))
6342 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
6343 argv
[idx_group
]->arg
, NULL
);
6345 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
6349 DEFUN (no_ip_pim_rp_prefix_list
,
6350 no_ip_pim_rp_prefix_list_cmd
,
6351 "no ip pim rp A.B.C.D prefix-list WORD",
6354 "pim multicast routing\n"
6356 "ip address of RP\n"
6357 "group prefix-list filter\n"
6358 "Name of a prefix-list\n")
6360 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6361 return pim_no_rp_cmd_worker(pim
, vty
, argv
[4]->arg
, NULL
, argv
[6]->arg
);
6364 static int pim_ssm_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
6367 int result
= pim_ssm_range_set(pim
, pim
->vrf_id
, plist
);
6369 if (result
== PIM_SSM_ERR_NONE
)
6373 case PIM_SSM_ERR_NO_VRF
:
6374 vty_out(vty
, "%% VRF doesn't exist\n");
6376 case PIM_SSM_ERR_DUP
:
6377 vty_out(vty
, "%% duplicate config\n");
6380 vty_out(vty
, "%% ssm range config failed\n");
6383 return CMD_WARNING_CONFIG_FAILED
;
6386 DEFUN (ip_pim_ssm_prefix_list
,
6387 ip_pim_ssm_prefix_list_cmd
,
6388 "ip pim ssm prefix-list WORD",
6390 "pim multicast routing\n"
6391 "Source Specific Multicast\n"
6392 "group range prefix-list filter\n"
6393 "Name of a prefix-list\n")
6395 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6396 return pim_ssm_cmd_worker(pim
, vty
, argv
[4]->arg
);
6399 DEFUN (no_ip_pim_ssm_prefix_list
,
6400 no_ip_pim_ssm_prefix_list_cmd
,
6401 "no ip pim ssm prefix-list",
6404 "pim multicast routing\n"
6405 "Source Specific Multicast\n"
6406 "group range prefix-list filter\n")
6408 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6409 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
6412 DEFUN (no_ip_pim_ssm_prefix_list_name
,
6413 no_ip_pim_ssm_prefix_list_name_cmd
,
6414 "no ip pim ssm prefix-list WORD",
6417 "pim multicast routing\n"
6418 "Source Specific Multicast\n"
6419 "group range prefix-list filter\n"
6420 "Name of a prefix-list\n")
6422 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6423 struct pim_ssm
*ssm
= pim
->ssm_info
;
6425 if (ssm
->plist_name
&& !strcmp(ssm
->plist_name
, argv
[5]->arg
))
6426 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
6428 vty_out(vty
, "%% pim ssm prefix-list %s doesn't exist\n", argv
[5]->arg
);
6430 return CMD_WARNING_CONFIG_FAILED
;
6433 static void ip_pim_ssm_show_group_range(struct pim_instance
*pim
,
6434 struct vty
*vty
, bool uj
)
6436 struct pim_ssm
*ssm
= pim
->ssm_info
;
6437 const char *range_str
=
6438 ssm
->plist_name
? ssm
->plist_name
: PIM_SSM_STANDARD_RANGE
;
6442 json
= json_object_new_object();
6443 json_object_string_add(json
, "ssmGroups", range_str
);
6444 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
6445 json
, JSON_C_TO_STRING_PRETTY
));
6446 json_object_free(json
);
6448 vty_out(vty
, "SSM group range : %s\n", range_str
);
6451 DEFUN (show_ip_pim_ssm_range
,
6452 show_ip_pim_ssm_range_cmd
,
6453 "show ip pim [vrf NAME] group-type [json]",
6462 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6463 bool uj
= use_json(argc
, argv
);
6468 ip_pim_ssm_show_group_range(vrf
->info
, vty
, uj
);
6473 static void ip_pim_ssm_show_group_type(struct pim_instance
*pim
,
6474 struct vty
*vty
, bool uj
,
6477 struct in_addr group_addr
;
6478 const char *type_str
;
6481 result
= inet_pton(AF_INET
, group
, &group_addr
);
6483 type_str
= "invalid";
6485 if (pim_is_group_224_4(group_addr
))
6487 pim_is_grp_ssm(pim
, group_addr
) ? "SSM" : "ASM";
6489 type_str
= "not-multicast";
6494 json
= json_object_new_object();
6495 json_object_string_add(json
, "groupType", type_str
);
6496 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
6497 json
, JSON_C_TO_STRING_PRETTY
));
6498 json_object_free(json
);
6500 vty_out(vty
, "Group type : %s\n", type_str
);
6503 DEFUN (show_ip_pim_group_type
,
6504 show_ip_pim_group_type_cmd
,
6505 "show ip pim [vrf NAME] group-type A.B.C.D [json]",
6510 "multicast group type\n"
6515 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6516 bool uj
= use_json(argc
, argv
);
6521 argv_find(argv
, argc
, "A.B.C.D", &idx
);
6522 ip_pim_ssm_show_group_type(vrf
->info
, vty
, uj
, argv
[idx
]->arg
);
6527 DEFUN (show_ip_pim_bsr
,
6528 show_ip_pim_bsr_cmd
,
6529 "show ip pim bsr [json]",
6533 "boot-strap router information\n"
6537 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6538 bool uj
= use_json(argc
, argv
);
6543 pim_show_bsr(vrf
->info
, vty
, uj
);
6550 "ip ssmpingd [A.B.C.D]",
6555 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6558 struct in_addr source_addr
;
6559 const char *source_str
= (argc
== 3) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
6561 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
6563 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
6564 source_str
, errno
, safe_strerror(errno
));
6565 return CMD_WARNING_CONFIG_FAILED
;
6568 result
= pim_ssmpingd_start(pim
, source_addr
);
6570 vty_out(vty
, "%% Failure starting ssmpingd for source %s: %d\n",
6571 source_str
, result
);
6572 return CMD_WARNING_CONFIG_FAILED
;
6578 DEFUN (no_ip_ssmpingd
,
6580 "no ip ssmpingd [A.B.C.D]",
6586 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6589 struct in_addr source_addr
;
6590 const char *source_str
= (argc
== 4) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
6592 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
6594 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
6595 source_str
, errno
, safe_strerror(errno
));
6596 return CMD_WARNING_CONFIG_FAILED
;
6599 result
= pim_ssmpingd_stop(pim
, source_addr
);
6601 vty_out(vty
, "%% Failure stopping ssmpingd for source %s: %d\n",
6602 source_str
, result
);
6603 return CMD_WARNING_CONFIG_FAILED
;
6613 "pim multicast routing\n"
6614 "Enable PIM ECMP \n")
6616 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6617 pim
->ecmp_enable
= true;
6622 DEFUN (no_ip_pim_ecmp
,
6627 "pim multicast routing\n"
6628 "Disable PIM ECMP \n")
6630 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6631 pim
->ecmp_enable
= false;
6636 DEFUN (ip_pim_ecmp_rebalance
,
6637 ip_pim_ecmp_rebalance_cmd
,
6638 "ip pim ecmp rebalance",
6640 "pim multicast routing\n"
6641 "Enable PIM ECMP \n"
6642 "Enable PIM ECMP Rebalance\n")
6644 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6645 pim
->ecmp_enable
= true;
6646 pim
->ecmp_rebalance_enable
= true;
6651 DEFUN (no_ip_pim_ecmp_rebalance
,
6652 no_ip_pim_ecmp_rebalance_cmd
,
6653 "no ip pim ecmp rebalance",
6656 "pim multicast routing\n"
6657 "Disable PIM ECMP \n"
6658 "Disable PIM ECMP Rebalance\n")
6660 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6661 pim
->ecmp_rebalance_enable
= false;
6666 static int pim_cmd_igmp_start(struct vty
*vty
, struct interface
*ifp
)
6668 struct pim_interface
*pim_ifp
;
6669 uint8_t need_startup
= 0;
6671 pim_ifp
= ifp
->info
;
6674 pim_ifp
= pim_if_new(ifp
, true, false, false,
6675 false /*vxlan_term*/);
6677 vty_out(vty
, "Could not enable IGMP on interface %s\n",
6679 return CMD_WARNING_CONFIG_FAILED
;
6683 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
6684 PIM_IF_DO_IGMP(pim_ifp
->options
);
6689 /* 'ip igmp' executed multiple times, with need_startup
6690 avoid multiple if add all and membership refresh */
6692 pim_if_addr_add_all(ifp
);
6693 pim_if_membership_refresh(ifp
);
6699 DEFUN (interface_ip_igmp
,
6700 interface_ip_igmp_cmd
,
6705 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6707 return pim_cmd_igmp_start(vty
, ifp
);
6710 DEFUN (interface_no_ip_igmp
,
6711 interface_no_ip_igmp_cmd
,
6717 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6718 struct pim_interface
*pim_ifp
= ifp
->info
;
6723 PIM_IF_DONT_IGMP(pim_ifp
->options
);
6725 pim_if_membership_clear(ifp
);
6727 pim_if_addr_del_all_igmp(ifp
);
6729 if (!PIM_IF_TEST_PIM(pim_ifp
->options
)) {
6736 DEFUN (interface_ip_igmp_join
,
6737 interface_ip_igmp_join_cmd
,
6738 "ip igmp join A.B.C.D A.B.C.D",
6741 "IGMP join multicast group\n"
6742 "Multicast group address\n"
6745 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6748 const char *group_str
;
6749 const char *source_str
;
6750 struct in_addr group_addr
;
6751 struct in_addr source_addr
;
6755 group_str
= argv
[idx_ipv4
]->arg
;
6756 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
6758 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
6759 errno
, safe_strerror(errno
));
6760 return CMD_WARNING_CONFIG_FAILED
;
6763 /* Source address */
6764 source_str
= argv
[idx_ipv4_2
]->arg
;
6765 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
6767 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
6768 source_str
, errno
, safe_strerror(errno
));
6769 return CMD_WARNING_CONFIG_FAILED
;
6772 CMD_FERR_RETURN(pim_if_igmp_join_add(ifp
, group_addr
, source_addr
),
6773 "Failure joining IGMP group: $ERR");
6778 DEFUN (interface_no_ip_igmp_join
,
6779 interface_no_ip_igmp_join_cmd
,
6780 "no ip igmp join A.B.C.D A.B.C.D",
6784 "IGMP join multicast group\n"
6785 "Multicast group address\n"
6788 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6791 const char *group_str
;
6792 const char *source_str
;
6793 struct in_addr group_addr
;
6794 struct in_addr source_addr
;
6798 group_str
= argv
[idx_ipv4
]->arg
;
6799 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
6801 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
6802 errno
, safe_strerror(errno
));
6803 return CMD_WARNING_CONFIG_FAILED
;
6806 /* Source address */
6807 source_str
= argv
[idx_ipv4_2
]->arg
;
6808 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
6810 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
6811 source_str
, errno
, safe_strerror(errno
));
6812 return CMD_WARNING_CONFIG_FAILED
;
6815 result
= pim_if_igmp_join_del(ifp
, group_addr
, source_addr
);
6818 "%% Failure leaving IGMP group %s source %s on interface %s: %d\n",
6819 group_str
, source_str
, ifp
->name
, result
);
6820 return CMD_WARNING_CONFIG_FAILED
;
6827 CLI reconfiguration affects the interface level (struct pim_interface).
6828 This function propagates the reconfiguration to every active socket
6831 static void igmp_sock_query_interval_reconfig(struct igmp_sock
*igmp
)
6833 struct interface
*ifp
;
6834 struct pim_interface
*pim_ifp
;
6838 /* other querier present? */
6840 if (igmp
->t_other_querier_timer
)
6843 /* this is the querier */
6845 zassert(igmp
->interface
);
6846 zassert(igmp
->interface
->info
);
6848 ifp
= igmp
->interface
;
6849 pim_ifp
= ifp
->info
;
6851 if (PIM_DEBUG_IGMP_TRACE
) {
6852 char ifaddr_str
[INET_ADDRSTRLEN
];
6853 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
6854 sizeof(ifaddr_str
));
6855 zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
6856 __PRETTY_FUNCTION__
, ifaddr_str
, ifp
->name
,
6857 pim_ifp
->igmp_default_query_interval
);
6861 igmp_startup_mode_on() will reset QQI:
6863 igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
6865 igmp_startup_mode_on(igmp
);
6868 static void igmp_sock_query_reschedule(struct igmp_sock
*igmp
)
6870 if (igmp
->t_igmp_query_timer
) {
6871 /* other querier present */
6872 zassert(igmp
->t_igmp_query_timer
);
6873 zassert(!igmp
->t_other_querier_timer
);
6875 pim_igmp_general_query_off(igmp
);
6876 pim_igmp_general_query_on(igmp
);
6878 zassert(igmp
->t_igmp_query_timer
);
6879 zassert(!igmp
->t_other_querier_timer
);
6881 /* this is the querier */
6883 zassert(!igmp
->t_igmp_query_timer
);
6884 zassert(igmp
->t_other_querier_timer
);
6886 pim_igmp_other_querier_timer_off(igmp
);
6887 pim_igmp_other_querier_timer_on(igmp
);
6889 zassert(!igmp
->t_igmp_query_timer
);
6890 zassert(igmp
->t_other_querier_timer
);
6894 static void change_query_interval(struct pim_interface
*pim_ifp
,
6897 struct listnode
*sock_node
;
6898 struct igmp_sock
*igmp
;
6900 pim_ifp
->igmp_default_query_interval
= query_interval
;
6902 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
6903 igmp_sock_query_interval_reconfig(igmp
);
6904 igmp_sock_query_reschedule(igmp
);
6908 static void change_query_max_response_time(struct pim_interface
*pim_ifp
,
6909 int query_max_response_time_dsec
)
6911 struct listnode
*sock_node
;
6912 struct igmp_sock
*igmp
;
6914 pim_ifp
->igmp_query_max_response_time_dsec
=
6915 query_max_response_time_dsec
;
6918 Below we modify socket/group/source timers in order to quickly
6919 reflect the change. Otherwise, those timers would eventually catch
6923 /* scan all sockets */
6924 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
6925 struct listnode
*grp_node
;
6926 struct igmp_group
*grp
;
6928 /* reschedule socket general query */
6929 igmp_sock_query_reschedule(igmp
);
6931 /* scan socket groups */
6932 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grp_node
,
6934 struct listnode
*src_node
;
6935 struct igmp_source
*src
;
6937 /* reset group timers for groups in EXCLUDE mode */
6938 if (grp
->group_filtermode_isexcl
) {
6939 igmp_group_reset_gmi(grp
);
6942 /* scan group sources */
6943 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
,
6946 /* reset source timers for sources with running
6948 if (src
->t_source_timer
) {
6949 igmp_source_reset_gmi(igmp
, grp
, src
);
6956 #define IGMP_QUERY_INTERVAL_MIN (1)
6957 #define IGMP_QUERY_INTERVAL_MAX (1800)
6959 DEFUN (interface_ip_igmp_query_interval
,
6960 interface_ip_igmp_query_interval_cmd
,
6961 "ip igmp query-interval (1-1800)",
6964 IFACE_IGMP_QUERY_INTERVAL_STR
6965 "Query interval in seconds\n")
6967 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6968 struct pim_interface
*pim_ifp
= ifp
->info
;
6970 int query_interval_dsec
;
6974 ret
= pim_cmd_igmp_start(vty
, ifp
);
6975 if (ret
!= CMD_SUCCESS
)
6977 pim_ifp
= ifp
->info
;
6980 query_interval
= atoi(argv
[3]->arg
);
6981 query_interval_dsec
= 10 * query_interval
;
6984 It seems we don't need to check bounds since command.c does it
6985 already, but we verify them anyway for extra safety.
6987 if (query_interval
< IGMP_QUERY_INTERVAL_MIN
) {
6989 "General query interval %d lower than minimum %d\n",
6990 query_interval
, IGMP_QUERY_INTERVAL_MIN
);
6991 return CMD_WARNING_CONFIG_FAILED
;
6993 if (query_interval
> IGMP_QUERY_INTERVAL_MAX
) {
6995 "General query interval %d higher than maximum %d\n",
6996 query_interval
, IGMP_QUERY_INTERVAL_MAX
);
6997 return CMD_WARNING_CONFIG_FAILED
;
7000 if (query_interval_dsec
<= pim_ifp
->igmp_query_max_response_time_dsec
) {
7002 "Can't set general query interval %d dsec <= query max response time %d dsec.\n",
7003 query_interval_dsec
,
7004 pim_ifp
->igmp_query_max_response_time_dsec
);
7005 return CMD_WARNING_CONFIG_FAILED
;
7008 change_query_interval(pim_ifp
, query_interval
);
7013 DEFUN (interface_no_ip_igmp_query_interval
,
7014 interface_no_ip_igmp_query_interval_cmd
,
7015 "no ip igmp query-interval",
7019 IFACE_IGMP_QUERY_INTERVAL_STR
)
7021 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7022 struct pim_interface
*pim_ifp
= ifp
->info
;
7023 int default_query_interval_dsec
;
7028 default_query_interval_dsec
= IGMP_GENERAL_QUERY_INTERVAL
* 10;
7030 if (default_query_interval_dsec
7031 <= pim_ifp
->igmp_query_max_response_time_dsec
) {
7033 "Can't set default general query interval %d dsec <= query max response time %d dsec.\n",
7034 default_query_interval_dsec
,
7035 pim_ifp
->igmp_query_max_response_time_dsec
);
7036 return CMD_WARNING_CONFIG_FAILED
;
7039 change_query_interval(pim_ifp
, IGMP_GENERAL_QUERY_INTERVAL
);
7044 DEFUN (interface_ip_igmp_version
,
7045 interface_ip_igmp_version_cmd
,
7046 "ip igmp version (2-3)",
7050 "IGMP version number\n")
7052 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7053 struct pim_interface
*pim_ifp
= ifp
->info
;
7054 int igmp_version
, old_version
= 0;
7058 ret
= pim_cmd_igmp_start(vty
, ifp
);
7059 if (ret
!= CMD_SUCCESS
)
7061 pim_ifp
= ifp
->info
;
7064 igmp_version
= atoi(argv
[3]->arg
);
7065 old_version
= pim_ifp
->igmp_version
;
7066 pim_ifp
->igmp_version
= igmp_version
;
7068 // Check if IGMP is Enabled otherwise, enable on interface
7069 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
7070 PIM_IF_DO_IGMP(pim_ifp
->options
);
7071 pim_if_addr_add_all(ifp
);
7072 pim_if_membership_refresh(ifp
);
7073 old_version
= igmp_version
;
7074 // avoid refreshing membership again.
7076 /* Current and new version is different refresh existing
7077 membership. Going from 3 -> 2 or 2 -> 3. */
7078 if (old_version
!= igmp_version
)
7079 pim_if_membership_refresh(ifp
);
7084 DEFUN (interface_no_ip_igmp_version
,
7085 interface_no_ip_igmp_version_cmd
,
7086 "no ip igmp version (2-3)",
7091 "IGMP version number\n")
7093 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7094 struct pim_interface
*pim_ifp
= ifp
->info
;
7099 pim_ifp
->igmp_version
= IGMP_DEFAULT_VERSION
;
7104 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
7105 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
7107 DEFUN (interface_ip_igmp_query_max_response_time
,
7108 interface_ip_igmp_query_max_response_time_cmd
,
7109 "ip igmp query-max-response-time (10-250)",
7112 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
7113 "Query response value in deci-seconds\n")
7115 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7116 struct pim_interface
*pim_ifp
= ifp
->info
;
7117 int query_max_response_time
;
7121 ret
= pim_cmd_igmp_start(vty
, ifp
);
7122 if (ret
!= CMD_SUCCESS
)
7124 pim_ifp
= ifp
->info
;
7127 query_max_response_time
= atoi(argv
[3]->arg
);
7129 if (query_max_response_time
7130 >= pim_ifp
->igmp_default_query_interval
* 10) {
7132 "Can't set query max response time %d sec >= general query interval %d sec\n",
7133 query_max_response_time
,
7134 pim_ifp
->igmp_default_query_interval
);
7135 return CMD_WARNING_CONFIG_FAILED
;
7138 change_query_max_response_time(pim_ifp
, query_max_response_time
);
7143 DEFUN (interface_no_ip_igmp_query_max_response_time
,
7144 interface_no_ip_igmp_query_max_response_time_cmd
,
7145 "no ip igmp query-max-response-time (10-250)",
7149 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
7150 "Time for response in deci-seconds\n")
7152 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7153 struct pim_interface
*pim_ifp
= ifp
->info
;
7158 change_query_max_response_time(pim_ifp
,
7159 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
7164 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
7165 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
7167 DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec
,
7168 interface_ip_igmp_query_max_response_time_dsec_cmd
,
7169 "ip igmp query-max-response-time-dsec (10-250)",
7172 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
7173 "Query response value in deciseconds\n")
7175 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7176 struct pim_interface
*pim_ifp
= ifp
->info
;
7177 int query_max_response_time_dsec
;
7178 int default_query_interval_dsec
;
7182 ret
= pim_cmd_igmp_start(vty
, ifp
);
7183 if (ret
!= CMD_SUCCESS
)
7185 pim_ifp
= ifp
->info
;
7188 query_max_response_time_dsec
= atoi(argv
[4]->arg
);
7190 default_query_interval_dsec
= 10 * pim_ifp
->igmp_default_query_interval
;
7192 if (query_max_response_time_dsec
>= default_query_interval_dsec
) {
7194 "Can't set query max response time %d dsec >= general query interval %d dsec\n",
7195 query_max_response_time_dsec
,
7196 default_query_interval_dsec
);
7197 return CMD_WARNING_CONFIG_FAILED
;
7200 change_query_max_response_time(pim_ifp
, query_max_response_time_dsec
);
7205 DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec
,
7206 interface_no_ip_igmp_query_max_response_time_dsec_cmd
,
7207 "no ip igmp query-max-response-time-dsec",
7211 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
)
7213 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7214 struct pim_interface
*pim_ifp
= ifp
->info
;
7219 change_query_max_response_time(pim_ifp
,
7220 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
7225 #define IGMP_LAST_MEMBER_QUERY_COUNT_MIN (1)
7226 #define IGMP_LAST_MEMBER_QUERY_COUNT_MAX (7)
7228 DEFUN (interface_ip_igmp_last_member_query_count
,
7229 interface_ip_igmp_last_member_query_count_cmd
,
7230 "ip igmp last-member-query-count (1-7)",
7233 IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR
7234 "Last member query count\n")
7236 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7237 struct pim_interface
*pim_ifp
= ifp
->info
;
7238 int last_member_query_count
;
7242 ret
= pim_cmd_igmp_start(vty
, ifp
);
7243 if (ret
!= CMD_SUCCESS
)
7245 pim_ifp
= ifp
->info
;
7248 last_member_query_count
= atoi(argv
[3]->arg
);
7250 pim_ifp
->igmp_last_member_query_count
= last_member_query_count
;
7255 DEFUN (interface_no_ip_igmp_last_member_query_count
,
7256 interface_no_ip_igmp_last_member_query_count_cmd
,
7257 "no ip igmp last-member-query-count",
7261 IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR
)
7263 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7264 struct pim_interface
*pim_ifp
= ifp
->info
;
7269 pim_ifp
->igmp_last_member_query_count
=
7270 IGMP_DEFAULT_ROBUSTNESS_VARIABLE
;
7275 #define IGMP_LAST_MEMBER_QUERY_INTERVAL_MIN (1)
7276 #define IGMP_LAST_MEMBER_QUERY_INTERVAL_MAX (255)
7278 DEFUN (interface_ip_igmp_last_member_query_interval
,
7279 interface_ip_igmp_last_member_query_interval_cmd
,
7280 "ip igmp last-member-query-interval (1-255)",
7283 IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR
7284 "Last member query interval in deciseconds\n")
7286 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7287 struct pim_interface
*pim_ifp
= ifp
->info
;
7288 int last_member_query_interval
;
7292 ret
= pim_cmd_igmp_start(vty
, ifp
);
7293 if (ret
!= CMD_SUCCESS
)
7295 pim_ifp
= ifp
->info
;
7298 last_member_query_interval
= atoi(argv
[3]->arg
);
7299 pim_ifp
->igmp_specific_query_max_response_time_dsec
7300 = last_member_query_interval
;
7305 DEFUN (interface_no_ip_igmp_last_member_query_interval
,
7306 interface_no_ip_igmp_last_member_query_interval_cmd
,
7307 "no ip igmp last-member-query-interval",
7311 IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR
)
7313 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7314 struct pim_interface
*pim_ifp
= ifp
->info
;
7319 pim_ifp
->igmp_specific_query_max_response_time_dsec
=
7320 IGMP_SPECIFIC_QUERY_MAX_RESPONSE_TIME_DSEC
;
7325 DEFUN (interface_ip_pim_drprio
,
7326 interface_ip_pim_drprio_cmd
,
7327 "ip pim drpriority (1-4294967295)",
7330 "Set the Designated Router Election Priority\n"
7331 "Value of the new DR Priority\n")
7333 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7335 struct pim_interface
*pim_ifp
= ifp
->info
;
7336 uint32_t old_dr_prio
;
7339 vty_out(vty
, "Please enable PIM on interface, first\n");
7340 return CMD_WARNING_CONFIG_FAILED
;
7343 old_dr_prio
= pim_ifp
->pim_dr_priority
;
7345 pim_ifp
->pim_dr_priority
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
7347 if (old_dr_prio
!= pim_ifp
->pim_dr_priority
) {
7348 pim_if_dr_election(ifp
);
7349 pim_hello_restart_now(ifp
);
7355 DEFUN (interface_no_ip_pim_drprio
,
7356 interface_no_ip_pim_drprio_cmd
,
7357 "no ip pim drpriority [(1-4294967295)]",
7361 "Revert the Designated Router Priority to default\n"
7362 "Old Value of the Priority\n")
7364 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7365 struct pim_interface
*pim_ifp
= ifp
->info
;
7368 vty_out(vty
, "Pim not enabled on this interface\n");
7369 return CMD_WARNING_CONFIG_FAILED
;
7372 if (pim_ifp
->pim_dr_priority
!= PIM_DEFAULT_DR_PRIORITY
) {
7373 pim_ifp
->pim_dr_priority
= PIM_DEFAULT_DR_PRIORITY
;
7374 pim_if_dr_election(ifp
);
7375 pim_hello_restart_now(ifp
);
7381 static int pim_cmd_interface_add(struct interface
*ifp
)
7383 struct pim_interface
*pim_ifp
= ifp
->info
;
7386 pim_ifp
= pim_if_new(ifp
, false, true, false,
7387 false /*vxlan_term*/);
7392 PIM_IF_DO_PIM(pim_ifp
->options
);
7395 pim_if_addr_add_all(ifp
);
7396 pim_if_membership_refresh(ifp
);
7400 DEFPY_HIDDEN (pim_test_sg_keepalive
,
7401 pim_test_sg_keepalive_cmd
,
7402 "test pim [vrf NAME$name] keepalive-reset A.B.C.D$source A.B.C.D$group",
7406 "Reset the Keepalive Timer\n"
7407 "The Source we are resetting\n"
7408 "The Group we are resetting\n")
7410 struct pim_upstream
*up
;
7411 struct pim_instance
*pim
;
7412 struct prefix_sg sg
;
7418 pim
= pim_get_pim_instance(VRF_DEFAULT
);
7420 struct vrf
*vrf
= vrf_lookup_by_name(name
);
7423 vty_out(vty
, "%% Vrf specified: %s does not exist\n",
7428 pim
= pim_get_pim_instance(vrf
->vrf_id
);
7432 vty_out(vty
, "%% Unable to find pim instance\n");
7436 up
= pim_upstream_find(pim
, &sg
);
7438 vty_out(vty
, "%% Unable to find %s specified\n",
7439 pim_str_sg_dump(&sg
));
7443 vty_out(vty
, "Setting %s to current keep alive time: %d\n",
7444 pim_str_sg_dump(&sg
), pim
->keep_alive_time
);
7445 pim_upstream_keep_alive_timer_start(up
, pim
->keep_alive_time
);
7450 DEFPY_HIDDEN (interface_ip_pim_activeactive
,
7451 interface_ip_pim_activeactive_cmd
,
7452 "[no$no] ip pim active-active",
7456 "Mark interface as Active-Active for MLAG operations, Hidden because not finished yet\n")
7458 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7459 struct pim_interface
*pim_ifp
;
7461 if (!no
&& !pim_cmd_interface_add(ifp
)) {
7462 vty_out(vty
, "Could not enable PIM SM active-active on interface\n");
7463 return CMD_WARNING_CONFIG_FAILED
;
7466 pim_ifp
= ifp
->info
;
7468 pim_ifp
->activeactive
= false;
7470 pim_ifp
->activeactive
= true;
7475 DEFUN_HIDDEN (interface_ip_pim_ssm
,
7476 interface_ip_pim_ssm_cmd
,
7482 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7484 if (!pim_cmd_interface_add(ifp
)) {
7485 vty_out(vty
, "Could not enable PIM SM on interface\n");
7486 return CMD_WARNING_CONFIG_FAILED
;
7490 "WARN: Enabled PIM SM on interface; configure PIM SSM "
7491 "range if needed\n");
7495 static int interface_ip_pim_helper(struct vty
*vty
)
7497 struct pim_interface
*pim_ifp
;
7499 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7501 if (!pim_cmd_interface_add(ifp
)) {
7502 vty_out(vty
, "Could not enable PIM SM on interface\n");
7503 return CMD_WARNING_CONFIG_FAILED
;
7506 pim_ifp
= ifp
->info
;
7508 pim_if_create_pimreg(pim_ifp
->pim
);
7513 DEFUN_HIDDEN (interface_ip_pim_sm
,
7514 interface_ip_pim_sm_cmd
,
7520 return interface_ip_pim_helper(vty
);
7523 DEFUN (interface_ip_pim
,
7524 interface_ip_pim_cmd
,
7529 return interface_ip_pim_helper(vty
);
7532 static int pim_cmd_interface_delete(struct interface
*ifp
)
7534 struct pim_interface
*pim_ifp
= ifp
->info
;
7539 PIM_IF_DONT_PIM(pim_ifp
->options
);
7541 pim_if_membership_clear(ifp
);
7544 pim_sock_delete() removes all neighbors from
7545 pim_ifp->pim_neighbor_list.
7547 pim_sock_delete(ifp
, "pim unconfigured on interface");
7549 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
7550 pim_if_addr_del_all(ifp
);
7557 static int interface_no_ip_pim_helper(struct vty
*vty
)
7559 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7560 if (!pim_cmd_interface_delete(ifp
)) {
7561 vty_out(vty
, "Unable to delete interface information\n");
7562 return CMD_WARNING_CONFIG_FAILED
;
7568 DEFUN_HIDDEN (interface_no_ip_pim_ssm
,
7569 interface_no_ip_pim_ssm_cmd
,
7576 return interface_no_ip_pim_helper(vty
);
7579 DEFUN_HIDDEN (interface_no_ip_pim_sm
,
7580 interface_no_ip_pim_sm_cmd
,
7587 return interface_no_ip_pim_helper(vty
);
7590 DEFUN (interface_no_ip_pim
,
7591 interface_no_ip_pim_cmd
,
7597 return interface_no_ip_pim_helper(vty
);
7601 DEFUN(interface_ip_pim_boundary_oil
,
7602 interface_ip_pim_boundary_oil_cmd
,
7603 "ip multicast boundary oil WORD",
7605 "Generic multicast configuration options\n"
7606 "Define multicast boundary\n"
7607 "Filter OIL by group using prefix list\n"
7608 "Prefix list to filter OIL with\n")
7610 VTY_DECLVAR_CONTEXT(interface
, iif
);
7611 struct pim_interface
*pim_ifp
;
7614 argv_find(argv
, argc
, "WORD", &idx
);
7616 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
7618 if (pim_ifp
->boundary_oil_plist
)
7619 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
7621 pim_ifp
->boundary_oil_plist
=
7622 XSTRDUP(MTYPE_PIM_INTERFACE
, argv
[idx
]->arg
);
7624 /* Interface will be pruned from OIL on next Join */
7628 DEFUN(interface_no_ip_pim_boundary_oil
,
7629 interface_no_ip_pim_boundary_oil_cmd
,
7630 "no ip multicast boundary oil [WORD]",
7633 "Generic multicast configuration options\n"
7634 "Define multicast boundary\n"
7635 "Filter OIL by group using prefix list\n"
7636 "Prefix list to filter OIL with\n")
7638 VTY_DECLVAR_CONTEXT(interface
, iif
);
7639 struct pim_interface
*pim_ifp
;
7642 argv_find(argv
, argc
, "WORD", &idx
);
7644 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
7646 if (pim_ifp
->boundary_oil_plist
)
7647 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
7652 DEFUN (interface_ip_mroute
,
7653 interface_ip_mroute_cmd
,
7654 "ip mroute INTERFACE A.B.C.D",
7656 "Add multicast route\n"
7657 "Outgoing interface name\n"
7660 VTY_DECLVAR_CONTEXT(interface
, iif
);
7661 struct pim_interface
*pim_ifp
;
7662 struct pim_instance
*pim
;
7663 int idx_interface
= 2;
7665 struct interface
*oif
;
7666 const char *oifname
;
7667 const char *grp_str
;
7668 struct in_addr grp_addr
;
7669 struct in_addr src_addr
;
7672 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
7675 oifname
= argv
[idx_interface
]->arg
;
7676 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
7678 vty_out(vty
, "No such interface name %s\n", oifname
);
7682 grp_str
= argv
[idx_ipv4
]->arg
;
7683 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
7685 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
7686 errno
, safe_strerror(errno
));
7690 src_addr
.s_addr
= INADDR_ANY
;
7692 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
7693 vty_out(vty
, "Failed to add route\n");
7700 DEFUN (interface_ip_mroute_source
,
7701 interface_ip_mroute_source_cmd
,
7702 "ip mroute INTERFACE A.B.C.D A.B.C.D",
7704 "Add multicast route\n"
7705 "Outgoing interface name\n"
7709 VTY_DECLVAR_CONTEXT(interface
, iif
);
7710 struct pim_interface
*pim_ifp
;
7711 struct pim_instance
*pim
;
7712 int idx_interface
= 2;
7715 struct interface
*oif
;
7716 const char *oifname
;
7717 const char *grp_str
;
7718 struct in_addr grp_addr
;
7719 const char *src_str
;
7720 struct in_addr src_addr
;
7723 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
7726 oifname
= argv
[idx_interface
]->arg
;
7727 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
7729 vty_out(vty
, "No such interface name %s\n", oifname
);
7733 grp_str
= argv
[idx_ipv4
]->arg
;
7734 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
7736 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
7737 errno
, safe_strerror(errno
));
7741 src_str
= argv
[idx_ipv4_2
]->arg
;
7742 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
7744 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
7745 errno
, safe_strerror(errno
));
7749 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
7750 vty_out(vty
, "Failed to add route\n");
7757 DEFUN (interface_no_ip_mroute
,
7758 interface_no_ip_mroute_cmd
,
7759 "no ip mroute INTERFACE A.B.C.D",
7762 "Add multicast route\n"
7763 "Outgoing interface name\n"
7766 VTY_DECLVAR_CONTEXT(interface
, iif
);
7767 struct pim_interface
*pim_ifp
;
7768 struct pim_instance
*pim
;
7769 int idx_interface
= 3;
7771 struct interface
*oif
;
7772 const char *oifname
;
7773 const char *grp_str
;
7774 struct in_addr grp_addr
;
7775 struct in_addr src_addr
;
7778 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
7781 oifname
= argv
[idx_interface
]->arg
;
7782 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
7784 vty_out(vty
, "No such interface name %s\n", oifname
);
7788 grp_str
= argv
[idx_ipv4
]->arg
;
7789 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
7791 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
7792 errno
, safe_strerror(errno
));
7796 src_addr
.s_addr
= INADDR_ANY
;
7798 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
7799 vty_out(vty
, "Failed to remove route\n");
7806 DEFUN (interface_no_ip_mroute_source
,
7807 interface_no_ip_mroute_source_cmd
,
7808 "no ip mroute INTERFACE A.B.C.D A.B.C.D",
7811 "Add multicast route\n"
7812 "Outgoing interface name\n"
7816 VTY_DECLVAR_CONTEXT(interface
, iif
);
7817 struct pim_interface
*pim_ifp
;
7818 struct pim_instance
*pim
;
7819 int idx_interface
= 3;
7822 struct interface
*oif
;
7823 const char *oifname
;
7824 const char *grp_str
;
7825 struct in_addr grp_addr
;
7826 const char *src_str
;
7827 struct in_addr src_addr
;
7830 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
7833 oifname
= argv
[idx_interface
]->arg
;
7834 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
7836 vty_out(vty
, "No such interface name %s\n", oifname
);
7840 grp_str
= argv
[idx_ipv4
]->arg
;
7841 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
7843 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
7844 errno
, safe_strerror(errno
));
7848 src_str
= argv
[idx_ipv4_2
]->arg
;
7849 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
7851 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
7852 errno
, safe_strerror(errno
));
7856 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
7857 vty_out(vty
, "Failed to remove route\n");
7864 DEFUN (interface_ip_pim_hello
,
7865 interface_ip_pim_hello_cmd
,
7866 "ip pim hello (1-180) [(1-180)]",
7870 IFACE_PIM_HELLO_TIME_STR
7871 IFACE_PIM_HELLO_HOLD_STR
)
7873 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7876 struct pim_interface
*pim_ifp
= ifp
->info
;
7879 if (!pim_cmd_interface_add(ifp
)) {
7880 vty_out(vty
, "Could not enable PIM SM on interface\n");
7881 return CMD_WARNING_CONFIG_FAILED
;
7885 pim_ifp
= ifp
->info
;
7886 pim_ifp
->pim_hello_period
= strtol(argv
[idx_time
]->arg
, NULL
, 10);
7888 if (argc
== idx_hold
+ 1)
7889 pim_ifp
->pim_default_holdtime
=
7890 strtol(argv
[idx_hold
]->arg
, NULL
, 10);
7895 DEFUN (interface_no_ip_pim_hello
,
7896 interface_no_ip_pim_hello_cmd
,
7897 "no ip pim hello [(1-180) (1-180)]",
7902 IFACE_PIM_HELLO_TIME_STR
7903 IFACE_PIM_HELLO_HOLD_STR
)
7905 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7906 struct pim_interface
*pim_ifp
= ifp
->info
;
7909 vty_out(vty
, "Pim not enabled on this interface\n");
7910 return CMD_WARNING_CONFIG_FAILED
;
7913 pim_ifp
->pim_hello_period
= PIM_DEFAULT_HELLO_PERIOD
;
7914 pim_ifp
->pim_default_holdtime
= -1;
7925 PIM_DO_DEBUG_IGMP_EVENTS
;
7926 PIM_DO_DEBUG_IGMP_PACKETS
;
7927 PIM_DO_DEBUG_IGMP_TRACE
;
7931 DEFUN (no_debug_igmp
,
7938 PIM_DONT_DEBUG_IGMP_EVENTS
;
7939 PIM_DONT_DEBUG_IGMP_PACKETS
;
7940 PIM_DONT_DEBUG_IGMP_TRACE
;
7945 DEFUN (debug_igmp_events
,
7946 debug_igmp_events_cmd
,
7947 "debug igmp events",
7950 DEBUG_IGMP_EVENTS_STR
)
7952 PIM_DO_DEBUG_IGMP_EVENTS
;
7956 DEFUN (no_debug_igmp_events
,
7957 no_debug_igmp_events_cmd
,
7958 "no debug igmp events",
7962 DEBUG_IGMP_EVENTS_STR
)
7964 PIM_DONT_DEBUG_IGMP_EVENTS
;
7969 DEFUN (debug_igmp_packets
,
7970 debug_igmp_packets_cmd
,
7971 "debug igmp packets",
7974 DEBUG_IGMP_PACKETS_STR
)
7976 PIM_DO_DEBUG_IGMP_PACKETS
;
7980 DEFUN (no_debug_igmp_packets
,
7981 no_debug_igmp_packets_cmd
,
7982 "no debug igmp packets",
7986 DEBUG_IGMP_PACKETS_STR
)
7988 PIM_DONT_DEBUG_IGMP_PACKETS
;
7993 DEFUN (debug_igmp_trace
,
7994 debug_igmp_trace_cmd
,
7998 DEBUG_IGMP_TRACE_STR
)
8000 PIM_DO_DEBUG_IGMP_TRACE
;
8004 DEFUN (no_debug_igmp_trace
,
8005 no_debug_igmp_trace_cmd
,
8006 "no debug igmp trace",
8010 DEBUG_IGMP_TRACE_STR
)
8012 PIM_DONT_DEBUG_IGMP_TRACE
;
8017 DEFUN (debug_mroute
,
8023 PIM_DO_DEBUG_MROUTE
;
8027 DEFUN (debug_mroute_detail
,
8028 debug_mroute_detail_cmd
,
8029 "debug mroute detail",
8034 PIM_DO_DEBUG_MROUTE_DETAIL
;
8038 DEFUN (no_debug_mroute
,
8039 no_debug_mroute_cmd
,
8045 PIM_DONT_DEBUG_MROUTE
;
8049 DEFUN (no_debug_mroute_detail
,
8050 no_debug_mroute_detail_cmd
,
8051 "no debug mroute detail",
8057 PIM_DONT_DEBUG_MROUTE_DETAIL
;
8061 DEFUN (debug_pim_static
,
8062 debug_pim_static_cmd
,
8068 PIM_DO_DEBUG_STATIC
;
8072 DEFUN (no_debug_pim_static
,
8073 no_debug_pim_static_cmd
,
8074 "no debug pim static",
8080 PIM_DONT_DEBUG_STATIC
;
8091 PIM_DO_DEBUG_PIM_EVENTS
;
8092 PIM_DO_DEBUG_PIM_PACKETS
;
8093 PIM_DO_DEBUG_PIM_TRACE
;
8094 PIM_DO_DEBUG_MSDP_EVENTS
;
8095 PIM_DO_DEBUG_MSDP_PACKETS
;
8100 DEFUN (no_debug_pim
,
8107 PIM_DONT_DEBUG_PIM_EVENTS
;
8108 PIM_DONT_DEBUG_PIM_PACKETS
;
8109 PIM_DONT_DEBUG_PIM_TRACE
;
8110 PIM_DONT_DEBUG_MSDP_EVENTS
;
8111 PIM_DONT_DEBUG_MSDP_PACKETS
;
8113 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
8114 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
8120 DEFUN (debug_pim_nht
,
8125 "Nexthop Tracking\n")
8127 PIM_DO_DEBUG_PIM_NHT
;
8131 DEFUN (no_debug_pim_nht
,
8132 no_debug_pim_nht_cmd
,
8137 "Nexthop Tracking\n")
8139 PIM_DONT_DEBUG_PIM_NHT
;
8143 DEFUN (debug_pim_nht_rp
,
8144 debug_pim_nht_rp_cmd
,
8148 "Nexthop Tracking\n"
8149 "RP Nexthop Tracking\n")
8151 PIM_DO_DEBUG_PIM_NHT_RP
;
8155 DEFUN (no_debug_pim_nht_rp
,
8156 no_debug_pim_nht_rp_cmd
,
8157 "no debug pim nht rp",
8161 "Nexthop Tracking\n"
8162 "RP Nexthop Tracking\n")
8164 PIM_DONT_DEBUG_PIM_NHT_RP
;
8168 DEFUN (debug_pim_events
,
8169 debug_pim_events_cmd
,
8173 DEBUG_PIM_EVENTS_STR
)
8175 PIM_DO_DEBUG_PIM_EVENTS
;
8179 DEFUN (no_debug_pim_events
,
8180 no_debug_pim_events_cmd
,
8181 "no debug pim events",
8185 DEBUG_PIM_EVENTS_STR
)
8187 PIM_DONT_DEBUG_PIM_EVENTS
;
8191 DEFUN (debug_pim_packets
,
8192 debug_pim_packets_cmd
,
8193 "debug pim packets [<hello|joins|register>]",
8196 DEBUG_PIM_PACKETS_STR
8197 DEBUG_PIM_HELLO_PACKETS_STR
8198 DEBUG_PIM_J_P_PACKETS_STR
8199 DEBUG_PIM_PIM_REG_PACKETS_STR
)
8202 if (argv_find(argv
, argc
, "hello", &idx
)) {
8203 PIM_DO_DEBUG_PIM_HELLO
;
8204 vty_out(vty
, "PIM Hello debugging is on\n");
8205 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
8206 PIM_DO_DEBUG_PIM_J_P
;
8207 vty_out(vty
, "PIM Join/Prune debugging is on\n");
8208 } else if (argv_find(argv
, argc
, "register", &idx
)) {
8209 PIM_DO_DEBUG_PIM_REG
;
8210 vty_out(vty
, "PIM Register debugging is on\n");
8212 PIM_DO_DEBUG_PIM_PACKETS
;
8213 vty_out(vty
, "PIM Packet debugging is on \n");
8218 DEFUN (no_debug_pim_packets
,
8219 no_debug_pim_packets_cmd
,
8220 "no debug pim packets [<hello|joins|register>]",
8224 DEBUG_PIM_PACKETS_STR
8225 DEBUG_PIM_HELLO_PACKETS_STR
8226 DEBUG_PIM_J_P_PACKETS_STR
8227 DEBUG_PIM_PIM_REG_PACKETS_STR
)
8230 if (argv_find(argv
, argc
, "hello", &idx
)) {
8231 PIM_DONT_DEBUG_PIM_HELLO
;
8232 vty_out(vty
, "PIM Hello debugging is off \n");
8233 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
8234 PIM_DONT_DEBUG_PIM_J_P
;
8235 vty_out(vty
, "PIM Join/Prune debugging is off \n");
8236 } else if (argv_find(argv
, argc
, "register", &idx
)) {
8237 PIM_DONT_DEBUG_PIM_REG
;
8238 vty_out(vty
, "PIM Register debugging is off\n");
8240 PIM_DONT_DEBUG_PIM_PACKETS
;
8246 DEFUN (debug_pim_packetdump_send
,
8247 debug_pim_packetdump_send_cmd
,
8248 "debug pim packet-dump send",
8251 DEBUG_PIM_PACKETDUMP_STR
8252 DEBUG_PIM_PACKETDUMP_SEND_STR
)
8254 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND
;
8258 DEFUN (no_debug_pim_packetdump_send
,
8259 no_debug_pim_packetdump_send_cmd
,
8260 "no debug pim packet-dump send",
8264 DEBUG_PIM_PACKETDUMP_STR
8265 DEBUG_PIM_PACKETDUMP_SEND_STR
)
8267 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
8271 DEFUN (debug_pim_packetdump_recv
,
8272 debug_pim_packetdump_recv_cmd
,
8273 "debug pim packet-dump receive",
8276 DEBUG_PIM_PACKETDUMP_STR
8277 DEBUG_PIM_PACKETDUMP_RECV_STR
)
8279 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV
;
8283 DEFUN (no_debug_pim_packetdump_recv
,
8284 no_debug_pim_packetdump_recv_cmd
,
8285 "no debug pim packet-dump receive",
8289 DEBUG_PIM_PACKETDUMP_STR
8290 DEBUG_PIM_PACKETDUMP_RECV_STR
)
8292 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
8296 DEFUN (debug_pim_trace
,
8297 debug_pim_trace_cmd
,
8301 DEBUG_PIM_TRACE_STR
)
8303 PIM_DO_DEBUG_PIM_TRACE
;
8307 DEFUN (debug_pim_trace_detail
,
8308 debug_pim_trace_detail_cmd
,
8309 "debug pim trace detail",
8313 "Detailed Information\n")
8315 PIM_DO_DEBUG_PIM_TRACE_DETAIL
;
8319 DEFUN (no_debug_pim_trace
,
8320 no_debug_pim_trace_cmd
,
8321 "no debug pim trace",
8325 DEBUG_PIM_TRACE_STR
)
8327 PIM_DONT_DEBUG_PIM_TRACE
;
8331 DEFUN (no_debug_pim_trace_detail
,
8332 no_debug_pim_trace_detail_cmd
,
8333 "no debug pim trace detail",
8338 "Detailed Information\n")
8340 PIM_DONT_DEBUG_PIM_TRACE_DETAIL
;
8344 DEFUN (debug_ssmpingd
,
8350 PIM_DO_DEBUG_SSMPINGD
;
8354 DEFUN (no_debug_ssmpingd
,
8355 no_debug_ssmpingd_cmd
,
8356 "no debug ssmpingd",
8361 PIM_DONT_DEBUG_SSMPINGD
;
8365 DEFUN (debug_pim_zebra
,
8366 debug_pim_zebra_cmd
,
8370 DEBUG_PIM_ZEBRA_STR
)
8376 DEFUN (no_debug_pim_zebra
,
8377 no_debug_pim_zebra_cmd
,
8378 "no debug pim zebra",
8382 DEBUG_PIM_ZEBRA_STR
)
8384 PIM_DONT_DEBUG_ZEBRA
;
8388 DEFUN (debug_pim_vxlan
,
8389 debug_pim_vxlan_cmd
,
8393 DEBUG_PIM_VXLAN_STR
)
8399 DEFUN (no_debug_pim_vxlan
,
8400 no_debug_pim_vxlan_cmd
,
8401 "no debug pim vxlan",
8405 DEBUG_PIM_VXLAN_STR
)
8407 PIM_DONT_DEBUG_VXLAN
;
8417 PIM_DO_DEBUG_MSDP_EVENTS
;
8418 PIM_DO_DEBUG_MSDP_PACKETS
;
8422 DEFUN (no_debug_msdp
,
8429 PIM_DONT_DEBUG_MSDP_EVENTS
;
8430 PIM_DONT_DEBUG_MSDP_PACKETS
;
8434 DEFUN (debug_msdp_events
,
8435 debug_msdp_events_cmd
,
8436 "debug msdp events",
8439 DEBUG_MSDP_EVENTS_STR
)
8441 PIM_DO_DEBUG_MSDP_EVENTS
;
8445 DEFUN (no_debug_msdp_events
,
8446 no_debug_msdp_events_cmd
,
8447 "no debug msdp events",
8451 DEBUG_MSDP_EVENTS_STR
)
8453 PIM_DONT_DEBUG_MSDP_EVENTS
;
8457 DEFUN (debug_msdp_packets
,
8458 debug_msdp_packets_cmd
,
8459 "debug msdp packets",
8462 DEBUG_MSDP_PACKETS_STR
)
8464 PIM_DO_DEBUG_MSDP_PACKETS
;
8468 DEFUN (no_debug_msdp_packets
,
8469 no_debug_msdp_packets_cmd
,
8470 "no debug msdp packets",
8474 DEBUG_MSDP_PACKETS_STR
)
8476 PIM_DONT_DEBUG_MSDP_PACKETS
;
8480 DEFUN (debug_mtrace
,
8486 PIM_DO_DEBUG_MTRACE
;
8490 DEFUN (no_debug_mtrace
,
8491 no_debug_mtrace_cmd
,
8497 PIM_DONT_DEBUG_MTRACE
;
8512 DEFUN (no_debug_bsm
,
8525 DEFUN_NOSH (show_debugging_pim
,
8526 show_debugging_pim_cmd
,
8527 "show debugging [pim]",
8532 vty_out(vty
, "PIM debugging status\n");
8534 pim_debug_config_write(vty
);
8539 static int interface_pim_use_src_cmd_worker(struct vty
*vty
, const char *source
)
8542 struct in_addr source_addr
;
8543 int ret
= CMD_SUCCESS
;
8544 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8546 result
= inet_pton(AF_INET
, source
, &source_addr
);
8548 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", source
,
8549 errno
, safe_strerror(errno
));
8550 return CMD_WARNING_CONFIG_FAILED
;
8553 result
= pim_update_source_set(ifp
, source_addr
);
8557 case PIM_IFACE_NOT_FOUND
:
8558 ret
= CMD_WARNING_CONFIG_FAILED
;
8559 vty_out(vty
, "Pim not enabled on this interface\n");
8561 case PIM_UPDATE_SOURCE_DUP
:
8563 vty_out(vty
, "%% Source already set to %s\n", source
);
8566 ret
= CMD_WARNING_CONFIG_FAILED
;
8567 vty_out(vty
, "%% Source set failed\n");
8573 DEFUN (interface_pim_use_source
,
8574 interface_pim_use_source_cmd
,
8575 "ip pim use-source A.B.C.D",
8578 "Configure primary IP address\n"
8579 "source ip address\n")
8581 return interface_pim_use_src_cmd_worker(vty
, argv
[3]->arg
);
8584 DEFUN (interface_no_pim_use_source
,
8585 interface_no_pim_use_source_cmd
,
8586 "no ip pim use-source [A.B.C.D]",
8590 "Delete source IP address\n"
8591 "source ip address\n")
8593 return interface_pim_use_src_cmd_worker(vty
, "0.0.0.0");
8601 "Enables BFD support\n")
8603 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8604 struct pim_interface
*pim_ifp
= ifp
->info
;
8605 struct bfd_info
*bfd_info
= NULL
;
8608 if (!pim_cmd_interface_add(ifp
)) {
8609 vty_out(vty
, "Could not enable PIM SM on interface\n");
8613 pim_ifp
= ifp
->info
;
8615 bfd_info
= pim_ifp
->bfd_info
;
8617 if (!bfd_info
|| !CHECK_FLAG(bfd_info
->flags
, BFD_FLAG_PARAM_CFG
))
8618 pim_bfd_if_param_set(ifp
, BFD_DEF_MIN_RX
, BFD_DEF_MIN_TX
,
8619 BFD_DEF_DETECT_MULT
, 1);
8624 DEFUN (no_ip_pim_bfd
,
8630 "Disables BFD support\n")
8632 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8633 struct pim_interface
*pim_ifp
= ifp
->info
;
8636 vty_out(vty
, "Pim not enabled on this interface\n");
8640 if (pim_ifp
->bfd_info
) {
8641 pim_bfd_reg_dereg_all_nbr(ifp
, ZEBRA_BFD_DEST_DEREGISTER
);
8642 bfd_info_free(&(pim_ifp
->bfd_info
));
8653 "Enables BSM support on the interface\n")
8655 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8656 struct pim_interface
*pim_ifp
= ifp
->info
;
8659 if (!pim_cmd_interface_add(ifp
)) {
8660 vty_out(vty
, "Could not enable PIM SM on interface\n");
8665 pim_ifp
= ifp
->info
;
8666 pim_ifp
->bsm_enable
= true;
8671 DEFUN (no_ip_pim_bsm
,
8677 "Disables BSM support\n")
8679 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8680 struct pim_interface
*pim_ifp
= ifp
->info
;
8683 vty_out(vty
, "Pim not enabled on this interface\n");
8687 pim_ifp
->bsm_enable
= false;
8692 DEFUN (ip_pim_ucast_bsm
,
8693 ip_pim_ucast_bsm_cmd
,
8694 "ip pim unicast-bsm",
8697 "Accept/Send unicast BSM on the interface\n")
8699 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8700 struct pim_interface
*pim_ifp
= ifp
->info
;
8703 if (!pim_cmd_interface_add(ifp
)) {
8704 vty_out(vty
, "Could not enable PIM SM on interface\n");
8709 pim_ifp
= ifp
->info
;
8710 pim_ifp
->ucast_bsm_accept
= true;
8715 DEFUN (no_ip_pim_ucast_bsm
,
8716 no_ip_pim_ucast_bsm_cmd
,
8717 "no ip pim unicast-bsm",
8721 "Block send/receive unicast BSM on this interface\n")
8723 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8724 struct pim_interface
*pim_ifp
= ifp
->info
;
8727 vty_out(vty
, "Pim not enabled on this interface\n");
8731 pim_ifp
->ucast_bsm_accept
= false;
8740 #endif /* HAVE_BFDD */
8742 ip_pim_bfd_param_cmd
,
8743 "ip pim bfd (2-255) (50-60000) (50-60000)",
8746 "Enables BFD support\n"
8747 "Detect Multiplier\n"
8748 "Required min receive interval\n"
8749 "Desired min transmit interval\n")
8751 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8753 int idx_number_2
= 4;
8754 int idx_number_3
= 5;
8759 struct pim_interface
*pim_ifp
= ifp
->info
;
8762 if (!pim_cmd_interface_add(ifp
)) {
8763 vty_out(vty
, "Could not enable PIM SM on interface\n");
8768 if ((ret
= bfd_validate_param(
8769 vty
, argv
[idx_number
]->arg
, argv
[idx_number_2
]->arg
,
8770 argv
[idx_number_3
]->arg
, &dm_val
, &rx_val
, &tx_val
))
8774 pim_bfd_if_param_set(ifp
, rx_val
, tx_val
, dm_val
, 0);
8780 ALIAS(no_ip_pim_bfd
, no_ip_pim_bfd_param_cmd
,
8781 "no ip pim bfd (2-255) (50-60000) (50-60000)", NO_STR IP_STR PIM_STR
8782 "Enables BFD support\n"
8783 "Detect Multiplier\n"
8784 "Required min receive interval\n"
8785 "Desired min transmit interval\n")
8786 #endif /* !HAVE_BFDD */
8788 static int ip_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
8789 const char *peer
, const char *local
)
8791 enum pim_msdp_err result
;
8792 struct in_addr peer_addr
;
8793 struct in_addr local_addr
;
8794 int ret
= CMD_SUCCESS
;
8796 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
8798 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
8799 errno
, safe_strerror(errno
));
8800 return CMD_WARNING_CONFIG_FAILED
;
8803 result
= inet_pton(AF_INET
, local
, &local_addr
);
8805 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", local
,
8806 errno
, safe_strerror(errno
));
8807 return CMD_WARNING_CONFIG_FAILED
;
8810 result
= pim_msdp_peer_add(pim
, peer_addr
, local_addr
, "default",
8813 case PIM_MSDP_ERR_NONE
:
8815 case PIM_MSDP_ERR_OOM
:
8816 ret
= CMD_WARNING_CONFIG_FAILED
;
8817 vty_out(vty
, "%% Out of memory\n");
8819 case PIM_MSDP_ERR_PEER_EXISTS
:
8821 vty_out(vty
, "%% Peer exists\n");
8823 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
8824 ret
= CMD_WARNING_CONFIG_FAILED
;
8825 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
8828 ret
= CMD_WARNING_CONFIG_FAILED
;
8829 vty_out(vty
, "%% peer add failed\n");
8835 DEFUN_HIDDEN (ip_msdp_peer
,
8837 "ip msdp peer A.B.C.D source A.B.C.D",
8840 "Configure MSDP peer\n"
8842 "Source address for TCP connection\n"
8843 "local ip address\n")
8845 PIM_DECLVAR_CONTEXT(vrf
, pim
);
8846 return ip_msdp_peer_cmd_worker(pim
, vty
, argv
[3]->arg
, argv
[5]->arg
);
8849 static int ip_no_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
8852 enum pim_msdp_err result
;
8853 struct in_addr peer_addr
;
8855 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
8857 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
8858 errno
, safe_strerror(errno
));
8859 return CMD_WARNING_CONFIG_FAILED
;
8862 result
= pim_msdp_peer_del(pim
, peer_addr
);
8864 case PIM_MSDP_ERR_NONE
:
8866 case PIM_MSDP_ERR_NO_PEER
:
8867 vty_out(vty
, "%% Peer does not exist\n");
8870 vty_out(vty
, "%% peer del failed\n");
8873 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
8876 DEFUN_HIDDEN (no_ip_msdp_peer
,
8877 no_ip_msdp_peer_cmd
,
8878 "no ip msdp peer A.B.C.D",
8882 "Delete MSDP peer\n"
8883 "peer ip address\n")
8885 PIM_DECLVAR_CONTEXT(vrf
, pim
);
8886 return ip_no_msdp_peer_cmd_worker(pim
, vty
, argv
[4]->arg
);
8889 static int ip_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
8890 struct vty
*vty
, const char *mg
,
8893 enum pim_msdp_err result
;
8894 struct in_addr mbr_ip
;
8895 int ret
= CMD_SUCCESS
;
8897 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
8899 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
8900 errno
, safe_strerror(errno
));
8901 return CMD_WARNING_CONFIG_FAILED
;
8904 result
= pim_msdp_mg_mbr_add(pim
, mg
, mbr_ip
);
8906 case PIM_MSDP_ERR_NONE
:
8908 case PIM_MSDP_ERR_OOM
:
8909 ret
= CMD_WARNING_CONFIG_FAILED
;
8910 vty_out(vty
, "%% Out of memory\n");
8912 case PIM_MSDP_ERR_MG_MBR_EXISTS
:
8914 vty_out(vty
, "%% mesh-group member exists\n");
8916 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
8917 ret
= CMD_WARNING_CONFIG_FAILED
;
8918 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
8921 ret
= CMD_WARNING_CONFIG_FAILED
;
8922 vty_out(vty
, "%% member add failed\n");
8928 DEFUN (ip_msdp_mesh_group_member
,
8929 ip_msdp_mesh_group_member_cmd
,
8930 "ip msdp mesh-group WORD member A.B.C.D",
8933 "Configure MSDP mesh-group\n"
8935 "mesh group member\n"
8936 "peer ip address\n")
8938 PIM_DECLVAR_CONTEXT(vrf
, pim
);
8939 return ip_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[3]->arg
,
8943 static int ip_no_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
8948 enum pim_msdp_err result
;
8949 struct in_addr mbr_ip
;
8951 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
8953 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
8954 errno
, safe_strerror(errno
));
8955 return CMD_WARNING_CONFIG_FAILED
;
8958 result
= pim_msdp_mg_mbr_del(pim
, mg
, mbr_ip
);
8960 case PIM_MSDP_ERR_NONE
:
8962 case PIM_MSDP_ERR_NO_MG
:
8963 vty_out(vty
, "%% mesh-group does not exist\n");
8965 case PIM_MSDP_ERR_NO_MG_MBR
:
8966 vty_out(vty
, "%% mesh-group member does not exist\n");
8969 vty_out(vty
, "%% mesh-group member del failed\n");
8972 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
8974 DEFUN (no_ip_msdp_mesh_group_member
,
8975 no_ip_msdp_mesh_group_member_cmd
,
8976 "no ip msdp mesh-group WORD member A.B.C.D",
8980 "Delete MSDP mesh-group member\n"
8982 "mesh group member\n"
8983 "peer ip address\n")
8985 PIM_DECLVAR_CONTEXT(vrf
, pim
);
8986 return ip_no_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[4]->arg
,
8990 static int ip_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
8991 struct vty
*vty
, const char *mg
,
8994 enum pim_msdp_err result
;
8995 struct in_addr src_ip
;
8997 result
= inet_pton(AF_INET
, src
, &src_ip
);
8999 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", src
,
9000 errno
, safe_strerror(errno
));
9001 return CMD_WARNING_CONFIG_FAILED
;
9004 result
= pim_msdp_mg_src_add(pim
, mg
, src_ip
);
9006 case PIM_MSDP_ERR_NONE
:
9008 case PIM_MSDP_ERR_OOM
:
9009 vty_out(vty
, "%% Out of memory\n");
9011 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
9012 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
9015 vty_out(vty
, "%% source add failed\n");
9018 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9022 DEFUN (ip_msdp_mesh_group_source
,
9023 ip_msdp_mesh_group_source_cmd
,
9024 "ip msdp mesh-group WORD source A.B.C.D",
9027 "Configure MSDP mesh-group\n"
9029 "mesh group local address\n"
9030 "source ip address for the TCP connection\n")
9032 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9033 return ip_msdp_mesh_group_source_cmd_worker(pim
, vty
, argv
[3]->arg
,
9037 static int ip_no_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
9041 enum pim_msdp_err result
;
9043 result
= pim_msdp_mg_src_del(pim
, mg
);
9045 case PIM_MSDP_ERR_NONE
:
9047 case PIM_MSDP_ERR_NO_MG
:
9048 vty_out(vty
, "%% mesh-group does not exist\n");
9051 vty_out(vty
, "%% mesh-group source del failed\n");
9054 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9057 static int ip_no_msdp_mesh_group_cmd_worker(struct pim_instance
*pim
,
9058 struct vty
*vty
, const char *mg
)
9060 enum pim_msdp_err result
;
9062 result
= pim_msdp_mg_del(pim
, mg
);
9064 case PIM_MSDP_ERR_NONE
:
9066 case PIM_MSDP_ERR_NO_MG
:
9067 vty_out(vty
, "%% mesh-group does not exist\n");
9070 vty_out(vty
, "%% mesh-group source del failed\n");
9073 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9076 DEFUN (no_ip_msdp_mesh_group_source
,
9077 no_ip_msdp_mesh_group_source_cmd
,
9078 "no ip msdp mesh-group WORD source [A.B.C.D]",
9082 "Delete MSDP mesh-group source\n"
9084 "mesh group source\n"
9085 "mesh group local address\n")
9087 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9089 return ip_no_msdp_mesh_group_cmd_worker(pim
, vty
, argv
[6]->arg
);
9091 return ip_no_msdp_mesh_group_source_cmd_worker(pim
, vty
,
9095 static void print_empty_json_obj(struct vty
*vty
)
9098 json
= json_object_new_object();
9099 vty_out(vty
, "%s\n",
9100 json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
));
9101 json_object_free(json
);
9104 static void ip_msdp_show_mesh_group(struct pim_instance
*pim
, struct vty
*vty
,
9107 struct listnode
*mbrnode
;
9108 struct pim_msdp_mg_mbr
*mbr
;
9109 struct pim_msdp_mg
*mg
= pim
->msdp
.mg
;
9110 char mbr_str
[INET_ADDRSTRLEN
];
9111 char src_str
[INET_ADDRSTRLEN
];
9112 char state_str
[PIM_MSDP_STATE_STRLEN
];
9113 enum pim_msdp_peer_state state
;
9114 json_object
*json
= NULL
;
9115 json_object
*json_mg_row
= NULL
;
9116 json_object
*json_members
= NULL
;
9117 json_object
*json_row
= NULL
;
9121 print_empty_json_obj(vty
);
9125 pim_inet4_dump("<source?>", mg
->src_ip
, src_str
, sizeof(src_str
));
9127 json
= json_object_new_object();
9128 /* currently there is only one mesh group but we should still
9130 * it a dict with mg-name as key */
9131 json_mg_row
= json_object_new_object();
9132 json_object_string_add(json_mg_row
, "name",
9133 mg
->mesh_group_name
);
9134 json_object_string_add(json_mg_row
, "source", src_str
);
9136 vty_out(vty
, "Mesh group : %s\n", mg
->mesh_group_name
);
9137 vty_out(vty
, " Source : %s\n", src_str
);
9138 vty_out(vty
, " Member State\n");
9141 for (ALL_LIST_ELEMENTS_RO(mg
->mbr_list
, mbrnode
, mbr
)) {
9142 pim_inet4_dump("<mbr?>", mbr
->mbr_ip
, mbr_str
, sizeof(mbr_str
));
9144 state
= mbr
->mp
->state
;
9146 state
= PIM_MSDP_DISABLED
;
9148 pim_msdp_state_dump(state
, state_str
, sizeof(state_str
));
9150 json_row
= json_object_new_object();
9151 json_object_string_add(json_row
, "member", mbr_str
);
9152 json_object_string_add(json_row
, "state", state_str
);
9153 if (!json_members
) {
9154 json_members
= json_object_new_object();
9155 json_object_object_add(json_mg_row
, "members",
9158 json_object_object_add(json_members
, mbr_str
, json_row
);
9160 vty_out(vty
, " %-15s %11s\n", mbr_str
, state_str
);
9165 json_object_object_add(json
, mg
->mesh_group_name
, json_mg_row
);
9166 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9167 json
, JSON_C_TO_STRING_PRETTY
));
9168 json_object_free(json
);
9172 DEFUN (show_ip_msdp_mesh_group
,
9173 show_ip_msdp_mesh_group_cmd
,
9174 "show ip msdp [vrf NAME] mesh-group [json]",
9179 "MSDP mesh-group information\n"
9182 bool uj
= use_json(argc
, argv
);
9184 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
9189 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
9194 DEFUN (show_ip_msdp_mesh_group_vrf_all
,
9195 show_ip_msdp_mesh_group_vrf_all_cmd
,
9196 "show ip msdp vrf all mesh-group [json]",
9201 "MSDP mesh-group information\n"
9204 bool uj
= use_json(argc
, argv
);
9210 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
9214 vty_out(vty
, " \"%s\": ", vrf
->name
);
9217 vty_out(vty
, "VRF: %s\n", vrf
->name
);
9218 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
9221 vty_out(vty
, "}\n");
9226 static void ip_msdp_show_peers(struct pim_instance
*pim
, struct vty
*vty
,
9229 struct listnode
*mpnode
;
9230 struct pim_msdp_peer
*mp
;
9231 char peer_str
[INET_ADDRSTRLEN
];
9232 char local_str
[INET_ADDRSTRLEN
];
9233 char state_str
[PIM_MSDP_STATE_STRLEN
];
9234 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
9236 json_object
*json
= NULL
;
9237 json_object
*json_row
= NULL
;
9241 json
= json_object_new_object();
9244 "Peer Local State Uptime SaCnt\n");
9247 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
9248 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
9249 now
= pim_time_monotonic_sec();
9250 pim_time_uptime(timebuf
, sizeof(timebuf
),
9253 strlcpy(timebuf
, "-", sizeof(timebuf
));
9255 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
9256 pim_inet4_dump("<local?>", mp
->local
, local_str
,
9258 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
9260 json_row
= json_object_new_object();
9261 json_object_string_add(json_row
, "peer", peer_str
);
9262 json_object_string_add(json_row
, "local", local_str
);
9263 json_object_string_add(json_row
, "state", state_str
);
9264 json_object_string_add(json_row
, "upTime", timebuf
);
9265 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
9266 json_object_object_add(json
, peer_str
, json_row
);
9268 vty_out(vty
, "%-15s %15s %11s %8s %6d\n", peer_str
,
9269 local_str
, state_str
, timebuf
, mp
->sa_cnt
);
9274 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9275 json
, JSON_C_TO_STRING_PRETTY
));
9276 json_object_free(json
);
9280 static void ip_msdp_show_peers_detail(struct pim_instance
*pim
, struct vty
*vty
,
9281 const char *peer
, bool uj
)
9283 struct listnode
*mpnode
;
9284 struct pim_msdp_peer
*mp
;
9285 char peer_str
[INET_ADDRSTRLEN
];
9286 char local_str
[INET_ADDRSTRLEN
];
9287 char state_str
[PIM_MSDP_STATE_STRLEN
];
9288 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
9289 char katimer
[PIM_MSDP_TIMER_STRLEN
];
9290 char crtimer
[PIM_MSDP_TIMER_STRLEN
];
9291 char holdtimer
[PIM_MSDP_TIMER_STRLEN
];
9293 json_object
*json
= NULL
;
9294 json_object
*json_row
= NULL
;
9297 json
= json_object_new_object();
9300 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
9301 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
9302 if (strcmp(peer
, "detail") && strcmp(peer
, peer_str
))
9305 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
9306 now
= pim_time_monotonic_sec();
9307 pim_time_uptime(timebuf
, sizeof(timebuf
),
9310 strlcpy(timebuf
, "-", sizeof(timebuf
));
9312 pim_inet4_dump("<local?>", mp
->local
, local_str
,
9314 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
9315 pim_time_timer_to_hhmmss(katimer
, sizeof(katimer
),
9317 pim_time_timer_to_hhmmss(crtimer
, sizeof(crtimer
),
9319 pim_time_timer_to_hhmmss(holdtimer
, sizeof(holdtimer
),
9323 json_row
= json_object_new_object();
9324 json_object_string_add(json_row
, "peer", peer_str
);
9325 json_object_string_add(json_row
, "local", local_str
);
9326 json_object_string_add(json_row
, "meshGroupName",
9327 mp
->mesh_group_name
);
9328 json_object_string_add(json_row
, "state", state_str
);
9329 json_object_string_add(json_row
, "upTime", timebuf
);
9330 json_object_string_add(json_row
, "keepAliveTimer",
9332 json_object_string_add(json_row
, "connRetryTimer",
9334 json_object_string_add(json_row
, "holdTimer",
9336 json_object_string_add(json_row
, "lastReset",
9338 json_object_int_add(json_row
, "connAttempts",
9340 json_object_int_add(json_row
, "establishedChanges",
9342 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
9343 json_object_int_add(json_row
, "kaSent", mp
->ka_tx_cnt
);
9344 json_object_int_add(json_row
, "kaRcvd", mp
->ka_rx_cnt
);
9345 json_object_int_add(json_row
, "saSent", mp
->sa_tx_cnt
);
9346 json_object_int_add(json_row
, "saRcvd", mp
->sa_rx_cnt
);
9347 json_object_object_add(json
, peer_str
, json_row
);
9349 vty_out(vty
, "Peer : %s\n", peer_str
);
9350 vty_out(vty
, " Local : %s\n", local_str
);
9351 vty_out(vty
, " Mesh Group : %s\n",
9352 mp
->mesh_group_name
);
9353 vty_out(vty
, " State : %s\n", state_str
);
9354 vty_out(vty
, " Uptime : %s\n", timebuf
);
9356 vty_out(vty
, " Keepalive Timer : %s\n", katimer
);
9357 vty_out(vty
, " Conn Retry Timer : %s\n", crtimer
);
9358 vty_out(vty
, " Hold Timer : %s\n", holdtimer
);
9359 vty_out(vty
, " Last Reset : %s\n",
9361 vty_out(vty
, " Conn Attempts : %d\n",
9363 vty_out(vty
, " Established Changes : %d\n",
9365 vty_out(vty
, " SA Count : %d\n",
9367 vty_out(vty
, " Statistics :\n");
9370 vty_out(vty
, " Keepalives : %10d %10d\n",
9371 mp
->ka_tx_cnt
, mp
->ka_rx_cnt
);
9372 vty_out(vty
, " SAs : %10d %10d\n",
9373 mp
->sa_tx_cnt
, mp
->sa_rx_cnt
);
9379 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9380 json
, JSON_C_TO_STRING_PRETTY
));
9381 json_object_free(json
);
9385 DEFUN (show_ip_msdp_peer_detail
,
9386 show_ip_msdp_peer_detail_cmd
,
9387 "show ip msdp [vrf NAME] peer [detail|A.B.C.D] [json]",
9392 "MSDP peer information\n"
9397 bool uj
= use_json(argc
, argv
);
9399 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
9406 if (argv_find(argv
, argc
, "detail", &idx
))
9407 arg
= argv
[idx
]->text
;
9408 else if (argv_find(argv
, argc
, "A.B.C.D", &idx
))
9409 arg
= argv
[idx
]->arg
;
9412 ip_msdp_show_peers_detail(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
9414 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
9419 DEFUN (show_ip_msdp_peer_detail_vrf_all
,
9420 show_ip_msdp_peer_detail_vrf_all_cmd
,
9421 "show ip msdp vrf all peer [detail|A.B.C.D] [json]",
9426 "MSDP peer information\n"
9432 bool uj
= use_json(argc
, argv
);
9438 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
9442 vty_out(vty
, " \"%s\": ", vrf
->name
);
9445 vty_out(vty
, "VRF: %s\n", vrf
->name
);
9446 if (argv_find(argv
, argc
, "detail", &idx
)
9447 || argv_find(argv
, argc
, "A.B.C.D", &idx
))
9448 ip_msdp_show_peers_detail(vrf
->info
, vty
,
9449 argv
[idx
]->arg
, uj
);
9451 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
9454 vty_out(vty
, "}\n");
9459 static void ip_msdp_show_sa(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
9461 struct listnode
*sanode
;
9462 struct pim_msdp_sa
*sa
;
9463 char src_str
[INET_ADDRSTRLEN
];
9464 char grp_str
[INET_ADDRSTRLEN
];
9465 char rp_str
[INET_ADDRSTRLEN
];
9466 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
9470 json_object
*json
= NULL
;
9471 json_object
*json_group
= NULL
;
9472 json_object
*json_row
= NULL
;
9475 json
= json_object_new_object();
9478 "Source Group RP Local SPT Uptime\n");
9481 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
9482 now
= pim_time_monotonic_sec();
9483 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
9484 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
9485 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
9486 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
9487 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
9489 strlcpy(spt_str
, "yes", sizeof(spt_str
));
9491 strlcpy(spt_str
, "no", sizeof(spt_str
));
9494 strlcpy(rp_str
, "-", sizeof(rp_str
));
9495 strlcpy(spt_str
, "-", sizeof(spt_str
));
9497 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
9498 strlcpy(local_str
, "yes", sizeof(local_str
));
9500 strlcpy(local_str
, "no", sizeof(local_str
));
9503 json_object_object_get_ex(json
, grp_str
, &json_group
);
9506 json_group
= json_object_new_object();
9507 json_object_object_add(json
, grp_str
,
9511 json_row
= json_object_new_object();
9512 json_object_string_add(json_row
, "source", src_str
);
9513 json_object_string_add(json_row
, "group", grp_str
);
9514 json_object_string_add(json_row
, "rp", rp_str
);
9515 json_object_string_add(json_row
, "local", local_str
);
9516 json_object_string_add(json_row
, "sptSetup", spt_str
);
9517 json_object_string_add(json_row
, "upTime", timebuf
);
9518 json_object_object_add(json_group
, src_str
, json_row
);
9520 vty_out(vty
, "%-15s %15s %15s %5c %3c %8s\n",
9521 src_str
, grp_str
, rp_str
, local_str
[0],
9522 spt_str
[0], timebuf
);
9527 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9528 json
, JSON_C_TO_STRING_PRETTY
));
9529 json_object_free(json
);
9533 static void ip_msdp_show_sa_entry_detail(struct pim_msdp_sa
*sa
,
9534 const char *src_str
,
9535 const char *grp_str
, struct vty
*vty
,
9536 bool uj
, json_object
*json
)
9538 char rp_str
[INET_ADDRSTRLEN
];
9539 char peer_str
[INET_ADDRSTRLEN
];
9540 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
9543 char statetimer
[PIM_MSDP_TIMER_STRLEN
];
9545 json_object
*json_group
= NULL
;
9546 json_object
*json_row
= NULL
;
9548 now
= pim_time_monotonic_sec();
9549 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
9550 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
9551 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
9552 pim_inet4_dump("<peer?>", sa
->peer
, peer_str
, sizeof(peer_str
));
9554 strlcpy(spt_str
, "yes", sizeof(spt_str
));
9556 strlcpy(spt_str
, "no", sizeof(spt_str
));
9559 strlcpy(rp_str
, "-", sizeof(rp_str
));
9560 strlcpy(peer_str
, "-", sizeof(peer_str
));
9561 strlcpy(spt_str
, "-", sizeof(spt_str
));
9563 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
9564 strlcpy(local_str
, "yes", sizeof(local_str
));
9566 strlcpy(local_str
, "no", sizeof(local_str
));
9568 pim_time_timer_to_hhmmss(statetimer
, sizeof(statetimer
),
9569 sa
->sa_state_timer
);
9571 json_object_object_get_ex(json
, grp_str
, &json_group
);
9574 json_group
= json_object_new_object();
9575 json_object_object_add(json
, grp_str
, json_group
);
9578 json_row
= json_object_new_object();
9579 json_object_string_add(json_row
, "source", src_str
);
9580 json_object_string_add(json_row
, "group", grp_str
);
9581 json_object_string_add(json_row
, "rp", rp_str
);
9582 json_object_string_add(json_row
, "local", local_str
);
9583 json_object_string_add(json_row
, "sptSetup", spt_str
);
9584 json_object_string_add(json_row
, "upTime", timebuf
);
9585 json_object_string_add(json_row
, "stateTimer", statetimer
);
9586 json_object_object_add(json_group
, src_str
, json_row
);
9588 vty_out(vty
, "SA : %s\n", sa
->sg_str
);
9589 vty_out(vty
, " RP : %s\n", rp_str
);
9590 vty_out(vty
, " Peer : %s\n", peer_str
);
9591 vty_out(vty
, " Local : %s\n", local_str
);
9592 vty_out(vty
, " SPT Setup : %s\n", spt_str
);
9593 vty_out(vty
, " Uptime : %s\n", timebuf
);
9594 vty_out(vty
, " State Timer : %s\n", statetimer
);
9599 static void ip_msdp_show_sa_detail(struct pim_instance
*pim
, struct vty
*vty
,
9602 struct listnode
*sanode
;
9603 struct pim_msdp_sa
*sa
;
9604 char src_str
[INET_ADDRSTRLEN
];
9605 char grp_str
[INET_ADDRSTRLEN
];
9606 json_object
*json
= NULL
;
9609 json
= json_object_new_object();
9612 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
9613 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
9614 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
9615 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
, uj
,
9620 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9621 json
, JSON_C_TO_STRING_PRETTY
));
9622 json_object_free(json
);
9626 DEFUN (show_ip_msdp_sa_detail
,
9627 show_ip_msdp_sa_detail_cmd
,
9628 "show ip msdp [vrf NAME] sa detail [json]",
9633 "MSDP active-source information\n"
9637 bool uj
= use_json(argc
, argv
);
9639 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
9644 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
9649 DEFUN (show_ip_msdp_sa_detail_vrf_all
,
9650 show_ip_msdp_sa_detail_vrf_all_cmd
,
9651 "show ip msdp vrf all sa detail [json]",
9656 "MSDP active-source information\n"
9660 bool uj
= use_json(argc
, argv
);
9666 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
9670 vty_out(vty
, " \"%s\": ", vrf
->name
);
9673 vty_out(vty
, "VRF: %s\n", vrf
->name
);
9674 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
9677 vty_out(vty
, "}\n");
9682 static void ip_msdp_show_sa_addr(struct pim_instance
*pim
, struct vty
*vty
,
9683 const char *addr
, bool uj
)
9685 struct listnode
*sanode
;
9686 struct pim_msdp_sa
*sa
;
9687 char src_str
[INET_ADDRSTRLEN
];
9688 char grp_str
[INET_ADDRSTRLEN
];
9689 json_object
*json
= NULL
;
9692 json
= json_object_new_object();
9695 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
9696 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
9697 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
9698 if (!strcmp(addr
, src_str
) || !strcmp(addr
, grp_str
)) {
9699 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
9705 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9706 json
, JSON_C_TO_STRING_PRETTY
));
9707 json_object_free(json
);
9711 static void ip_msdp_show_sa_sg(struct pim_instance
*pim
, struct vty
*vty
,
9712 const char *src
, const char *grp
, bool uj
)
9714 struct listnode
*sanode
;
9715 struct pim_msdp_sa
*sa
;
9716 char src_str
[INET_ADDRSTRLEN
];
9717 char grp_str
[INET_ADDRSTRLEN
];
9718 json_object
*json
= NULL
;
9721 json
= json_object_new_object();
9724 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
9725 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
9726 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
9727 if (!strcmp(src
, src_str
) && !strcmp(grp
, grp_str
)) {
9728 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
9734 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9735 json
, JSON_C_TO_STRING_PRETTY
));
9736 json_object_free(json
);
9740 DEFUN (show_ip_msdp_sa_sg
,
9741 show_ip_msdp_sa_sg_cmd
,
9742 "show ip msdp [vrf NAME] sa [A.B.C.D [A.B.C.D]] [json]",
9747 "MSDP active-source information\n"
9748 "source or group ip\n"
9752 bool uj
= use_json(argc
, argv
);
9756 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
9761 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
9763 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
9767 if (src_ip
&& grp_ip
)
9768 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
9770 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
9772 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
9777 DEFUN (show_ip_msdp_sa_sg_vrf_all
,
9778 show_ip_msdp_sa_sg_vrf_all_cmd
,
9779 "show ip msdp vrf all sa [A.B.C.D [A.B.C.D]] [json]",
9784 "MSDP active-source information\n"
9785 "source or group ip\n"
9789 bool uj
= use_json(argc
, argv
);
9794 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
9796 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
9802 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
9806 vty_out(vty
, " \"%s\": ", vrf
->name
);
9809 vty_out(vty
, "VRF: %s\n", vrf
->name
);
9811 if (src_ip
&& grp_ip
)
9812 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
9814 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
9816 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
9819 vty_out(vty
, "}\n");
9824 struct pim_sg_cache_walk_data
{
9827 json_object
*json_group
;
9828 struct in_addr addr
;
9832 static void pim_show_vxlan_sg_entry(struct pim_vxlan_sg
*vxlan_sg
,
9833 struct pim_sg_cache_walk_data
*cwd
)
9835 struct vty
*vty
= cwd
->vty
;
9836 json_object
*json
= cwd
->json
;
9837 char src_str
[INET_ADDRSTRLEN
];
9838 char grp_str
[INET_ADDRSTRLEN
];
9839 json_object
*json_row
;
9840 bool installed
= (vxlan_sg
->up
)?TRUE
:FALSE
;
9841 const char *iif_name
= vxlan_sg
->iif
?vxlan_sg
->iif
->name
:"-";
9842 const char *oif_name
;
9844 if (pim_vxlan_is_orig_mroute(vxlan_sg
))
9845 oif_name
= vxlan_sg
->orig_oif
?vxlan_sg
->orig_oif
->name
:"";
9847 oif_name
= vxlan_sg
->term_oif
?vxlan_sg
->term_oif
->name
:"";
9849 if (cwd
->addr_match
&& (vxlan_sg
->sg
.src
.s_addr
!= cwd
->addr
.s_addr
) &&
9850 (vxlan_sg
->sg
.grp
.s_addr
!= cwd
->addr
.s_addr
)) {
9853 pim_inet4_dump("<src?>", vxlan_sg
->sg
.src
, src_str
, sizeof(src_str
));
9854 pim_inet4_dump("<grp?>", vxlan_sg
->sg
.grp
, grp_str
, sizeof(grp_str
));
9856 json_object_object_get_ex(json
, grp_str
, &cwd
->json_group
);
9858 if (!cwd
->json_group
) {
9859 cwd
->json_group
= json_object_new_object();
9860 json_object_object_add(json
, grp_str
,
9864 json_row
= json_object_new_object();
9865 json_object_string_add(json_row
, "source", src_str
);
9866 json_object_string_add(json_row
, "group", grp_str
);
9867 json_object_string_add(json_row
, "input", iif_name
);
9868 json_object_string_add(json_row
, "output", oif_name
);
9870 json_object_boolean_true_add(json_row
, "installed");
9872 json_object_boolean_false_add(json_row
, "installed");
9873 json_object_object_add(cwd
->json_group
, src_str
, json_row
);
9875 vty_out(vty
, "%-15s %-15s %-15s %-15s %-5s\n",
9876 src_str
, grp_str
, iif_name
, oif_name
,
9881 static void pim_show_vxlan_sg_hash_entry(struct hash_backet
*backet
, void *arg
)
9883 pim_show_vxlan_sg_entry((struct pim_vxlan_sg
*)backet
->data
,
9884 (struct pim_sg_cache_walk_data
*)arg
);
9887 static void pim_show_vxlan_sg(struct pim_instance
*pim
,
9888 struct vty
*vty
, bool uj
)
9890 json_object
*json
= NULL
;
9891 struct pim_sg_cache_walk_data cwd
;
9894 json
= json_object_new_object();
9896 vty_out(vty
, "Codes: I -> installed\n");
9898 "Source Group Input Output Flags\n");
9901 memset(&cwd
, 0, sizeof(cwd
));
9904 hash_iterate(pim
->vxlan
.sg_hash
, pim_show_vxlan_sg_hash_entry
, &cwd
);
9907 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9908 json
, JSON_C_TO_STRING_PRETTY
));
9909 json_object_free(json
);
9913 static void pim_show_vxlan_sg_match_addr(struct pim_instance
*pim
,
9914 struct vty
*vty
, char *addr_str
, bool uj
)
9916 json_object
*json
= NULL
;
9917 struct pim_sg_cache_walk_data cwd
;
9920 memset(&cwd
, 0, sizeof(cwd
));
9921 result
= inet_pton(AF_INET
, addr_str
, &cwd
.addr
);
9923 vty_out(vty
, "Bad address %s: errno=%d: %s\n", addr_str
,
9924 errno
, safe_strerror(errno
));
9929 json
= json_object_new_object();
9931 vty_out(vty
, "Codes: I -> installed\n");
9933 "Source Group Input Output Flags\n");
9938 cwd
.addr_match
= TRUE
;
9939 hash_iterate(pim
->vxlan
.sg_hash
, pim_show_vxlan_sg_hash_entry
, &cwd
);
9942 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9943 json
, JSON_C_TO_STRING_PRETTY
));
9944 json_object_free(json
);
9948 static void pim_show_vxlan_sg_one(struct pim_instance
*pim
,
9949 struct vty
*vty
, char *src_str
, char *grp_str
, bool uj
)
9951 json_object
*json
= NULL
;
9952 struct prefix_sg sg
;
9954 struct pim_vxlan_sg
*vxlan_sg
;
9955 const char *iif_name
;
9957 const char *oif_name
;
9959 result
= inet_pton(AF_INET
, src_str
, &sg
.src
);
9961 vty_out(vty
, "Bad src address %s: errno=%d: %s\n", src_str
,
9962 errno
, safe_strerror(errno
));
9965 result
= inet_pton(AF_INET
, grp_str
, &sg
.grp
);
9967 vty_out(vty
, "Bad grp address %s: errno=%d: %s\n", grp_str
,
9968 errno
, safe_strerror(errno
));
9972 sg
.family
= AF_INET
;
9973 sg
.prefixlen
= IPV4_MAX_BITLEN
;
9975 json
= json_object_new_object();
9977 vxlan_sg
= pim_vxlan_sg_find(pim
, &sg
);
9979 installed
= (vxlan_sg
->up
)?TRUE
:FALSE
;
9980 iif_name
= vxlan_sg
->iif
?vxlan_sg
->iif
->name
:"-";
9982 if (pim_vxlan_is_orig_mroute(vxlan_sg
))
9984 vxlan_sg
->orig_oif
?vxlan_sg
->orig_oif
->name
:"";
9987 vxlan_sg
->term_oif
?vxlan_sg
->term_oif
->name
:"";
9990 json_object_string_add(json
, "source", src_str
);
9991 json_object_string_add(json
, "group", grp_str
);
9992 json_object_string_add(json
, "input", iif_name
);
9993 json_object_string_add(json
, "output", oif_name
);
9995 json_object_boolean_true_add(json
, "installed");
9997 json_object_boolean_false_add(json
,
10000 vty_out(vty
, "SG : %s\n", vxlan_sg
->sg_str
);
10001 vty_out(vty
, " Input : %s\n", iif_name
);
10002 vty_out(vty
, " Output : %s\n", oif_name
);
10003 vty_out(vty
, " installed : %s\n",
10004 installed
?"yes":"no");
10009 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10010 json
, JSON_C_TO_STRING_PRETTY
));
10011 json_object_free(json
);
10015 DEFUN (show_ip_pim_vxlan_sg
,
10016 show_ip_pim_vxlan_sg_cmd
,
10017 "show ip pim [vrf NAME] vxlan-groups [A.B.C.D [A.B.C.D]] [json]",
10022 "VxLAN BUM groups\n"
10023 "source or group ip\n"
10027 bool uj
= use_json(argc
, argv
);
10031 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10034 return CMD_WARNING
;
10036 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ?
10037 argv
[idx
++]->arg
:NULL
;
10038 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
) ?
10039 argv
[idx
]->arg
:NULL
;
10041 if (src_ip
&& grp_ip
)
10042 pim_show_vxlan_sg_one(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
10044 pim_show_vxlan_sg_match_addr(vrf
->info
, vty
, src_ip
, uj
);
10046 pim_show_vxlan_sg(vrf
->info
, vty
, uj
);
10048 return CMD_SUCCESS
;
10051 static void pim_show_vxlan_sg_work(struct pim_instance
*pim
,
10052 struct vty
*vty
, bool uj
)
10054 json_object
*json
= NULL
;
10055 struct pim_sg_cache_walk_data cwd
;
10056 struct listnode
*node
;
10057 struct pim_vxlan_sg
*vxlan_sg
;
10060 json
= json_object_new_object();
10062 vty_out(vty
, "Codes: I -> installed\n");
10064 "Source Group Input Flags\n");
10067 memset(&cwd
, 0, sizeof(cwd
));
10070 for (ALL_LIST_ELEMENTS_RO(pim_vxlan_p
->work_list
, node
, vxlan_sg
))
10071 pim_show_vxlan_sg_entry(vxlan_sg
, &cwd
);
10074 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10075 json
, JSON_C_TO_STRING_PRETTY
));
10076 json_object_free(json
);
10080 DEFUN_HIDDEN (show_ip_pim_vxlan_sg_work
,
10081 show_ip_pim_vxlan_sg_work_cmd
,
10082 "show ip pim [vrf NAME] vxlan-work [json]",
10087 "VxLAN work list\n"
10090 bool uj
= use_json(argc
, argv
);
10094 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10097 return CMD_WARNING
;
10099 pim_show_vxlan_sg_work(vrf
->info
, vty
, uj
);
10101 return CMD_SUCCESS
;
10104 DEFUN_HIDDEN (no_ip_pim_mlag
,
10105 no_ip_pim_mlag_cmd
,
10112 struct in_addr addr
;
10115 pim_vxlan_mlag_update(TRUE
/*mlag_enable*/,
10116 FALSE
/*peer_state*/, PIM_VXLAN_MLAG_ROLE_SECONDARY
,
10117 NULL
/*peerlink*/, &addr
);
10119 return CMD_SUCCESS
;
10122 DEFUN_HIDDEN (ip_pim_mlag
,
10124 "ip pim mlag INTERFACE role [primary|secondary] state [up|down] addr A.B.C.D",
10128 "peerlink sub interface\n"
10130 "MLAG role primary\n"
10131 "MLAG role secondary\n"
10132 "peer session state\n"
10133 "peer session state up\n"
10134 "peer session state down\n"
10136 "unique ip address\n")
10138 struct interface
*ifp
;
10139 const char *peerlink
;
10144 struct in_addr reg_addr
;
10147 peerlink
= argv
[idx
]->arg
;
10148 ifp
= if_lookup_by_name(peerlink
, VRF_DEFAULT
);
10150 vty_out(vty
, "No such interface name %s\n", peerlink
);
10151 return CMD_WARNING
;
10155 if (!strcmp(argv
[idx
]->arg
, "primary")) {
10156 role
= PIM_VXLAN_MLAG_ROLE_PRIMARY
;
10157 } else if (!strcmp(argv
[idx
]->arg
, "secondary")) {
10158 role
= PIM_VXLAN_MLAG_ROLE_SECONDARY
;
10160 vty_out(vty
, "unknown MLAG role %s\n", argv
[idx
]->arg
);
10161 return CMD_WARNING
;
10165 if (!strcmp(argv
[idx
]->arg
, "up")) {
10167 } else if (strcmp(argv
[idx
]->arg
, "down")) {
10168 peer_state
= FALSE
;
10170 vty_out(vty
, "unknown MLAG state %s\n", argv
[idx
]->arg
);
10171 return CMD_WARNING
;
10175 result
= inet_pton(AF_INET
, argv
[idx
]->arg
, ®_addr
);
10177 vty_out(vty
, "%% Bad reg address %s: errno=%d: %s\n",
10179 errno
, safe_strerror(errno
));
10180 return CMD_WARNING_CONFIG_FAILED
;
10182 pim_vxlan_mlag_update(TRUE
, peer_state
, role
, ifp
, ®_addr
);
10184 return CMD_SUCCESS
;
10187 void pim_cmd_init(void)
10189 install_node(&interface_node
,
10190 pim_interface_config_write
); /* INTERFACE_NODE */
10193 install_node(&debug_node
, pim_debug_config_write
);
10195 install_element(ENABLE_NODE
, &pim_test_sg_keepalive_cmd
);
10197 install_element(CONFIG_NODE
, &ip_pim_rp_cmd
);
10198 install_element(VRF_NODE
, &ip_pim_rp_cmd
);
10199 install_element(CONFIG_NODE
, &no_ip_pim_rp_cmd
);
10200 install_element(VRF_NODE
, &no_ip_pim_rp_cmd
);
10201 install_element(CONFIG_NODE
, &ip_pim_rp_prefix_list_cmd
);
10202 install_element(VRF_NODE
, &ip_pim_rp_prefix_list_cmd
);
10203 install_element(CONFIG_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
10204 install_element(VRF_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
10205 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
10206 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
10207 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
10208 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
10209 install_element(CONFIG_NODE
, &ip_pim_ssm_prefix_list_cmd
);
10210 install_element(VRF_NODE
, &ip_pim_ssm_prefix_list_cmd
);
10211 install_element(CONFIG_NODE
, &ip_pim_register_suppress_cmd
);
10212 install_element(VRF_NODE
, &ip_pim_register_suppress_cmd
);
10213 install_element(CONFIG_NODE
, &no_ip_pim_register_suppress_cmd
);
10214 install_element(VRF_NODE
, &no_ip_pim_register_suppress_cmd
);
10215 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
10216 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
10217 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
10218 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
10219 install_element(CONFIG_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
10220 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
10221 install_element(CONFIG_NODE
,
10222 &no_ip_pim_spt_switchover_infinity_plist_cmd
);
10223 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_plist_cmd
);
10224 install_element(CONFIG_NODE
, &ip_pim_joinprune_time_cmd
);
10225 install_element(VRF_NODE
, &ip_pim_joinprune_time_cmd
);
10226 install_element(CONFIG_NODE
, &no_ip_pim_joinprune_time_cmd
);
10227 install_element(VRF_NODE
, &no_ip_pim_joinprune_time_cmd
);
10228 install_element(CONFIG_NODE
, &ip_pim_keep_alive_cmd
);
10229 install_element(VRF_NODE
, &ip_pim_keep_alive_cmd
);
10230 install_element(CONFIG_NODE
, &ip_pim_rp_keep_alive_cmd
);
10231 install_element(VRF_NODE
, &ip_pim_rp_keep_alive_cmd
);
10232 install_element(CONFIG_NODE
, &no_ip_pim_keep_alive_cmd
);
10233 install_element(VRF_NODE
, &no_ip_pim_keep_alive_cmd
);
10234 install_element(CONFIG_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
10235 install_element(VRF_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
10236 install_element(CONFIG_NODE
, &ip_pim_packets_cmd
);
10237 install_element(VRF_NODE
, &ip_pim_packets_cmd
);
10238 install_element(CONFIG_NODE
, &no_ip_pim_packets_cmd
);
10239 install_element(VRF_NODE
, &no_ip_pim_packets_cmd
);
10240 install_element(CONFIG_NODE
, &ip_pim_v6_secondary_cmd
);
10241 install_element(VRF_NODE
, &ip_pim_v6_secondary_cmd
);
10242 install_element(CONFIG_NODE
, &no_ip_pim_v6_secondary_cmd
);
10243 install_element(VRF_NODE
, &no_ip_pim_v6_secondary_cmd
);
10244 install_element(CONFIG_NODE
, &ip_ssmpingd_cmd
);
10245 install_element(VRF_NODE
, &ip_ssmpingd_cmd
);
10246 install_element(CONFIG_NODE
, &no_ip_ssmpingd_cmd
);
10247 install_element(VRF_NODE
, &no_ip_ssmpingd_cmd
);
10248 install_element(CONFIG_NODE
, &ip_msdp_peer_cmd
);
10249 install_element(VRF_NODE
, &ip_msdp_peer_cmd
);
10250 install_element(CONFIG_NODE
, &no_ip_msdp_peer_cmd
);
10251 install_element(VRF_NODE
, &no_ip_msdp_peer_cmd
);
10252 install_element(CONFIG_NODE
, &ip_pim_ecmp_cmd
);
10253 install_element(VRF_NODE
, &ip_pim_ecmp_cmd
);
10254 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_cmd
);
10255 install_element(VRF_NODE
, &no_ip_pim_ecmp_cmd
);
10256 install_element(CONFIG_NODE
, &ip_pim_ecmp_rebalance_cmd
);
10257 install_element(VRF_NODE
, &ip_pim_ecmp_rebalance_cmd
);
10258 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
10259 install_element(VRF_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
10260 install_element(CONFIG_NODE
, &ip_pim_mlag_cmd
);
10261 install_element(CONFIG_NODE
, &no_ip_pim_mlag_cmd
);
10263 install_element(INTERFACE_NODE
, &interface_ip_igmp_cmd
);
10264 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_cmd
);
10265 install_element(INTERFACE_NODE
, &interface_ip_igmp_join_cmd
);
10266 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_join_cmd
);
10267 install_element(INTERFACE_NODE
, &interface_ip_igmp_version_cmd
);
10268 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_version_cmd
);
10269 install_element(INTERFACE_NODE
, &interface_ip_igmp_query_interval_cmd
);
10270 install_element(INTERFACE_NODE
,
10271 &interface_no_ip_igmp_query_interval_cmd
);
10272 install_element(INTERFACE_NODE
,
10273 &interface_ip_igmp_query_max_response_time_cmd
);
10274 install_element(INTERFACE_NODE
,
10275 &interface_no_ip_igmp_query_max_response_time_cmd
);
10276 install_element(INTERFACE_NODE
,
10277 &interface_ip_igmp_query_max_response_time_dsec_cmd
);
10278 install_element(INTERFACE_NODE
,
10279 &interface_no_ip_igmp_query_max_response_time_dsec_cmd
);
10280 install_element(INTERFACE_NODE
,
10281 &interface_ip_igmp_last_member_query_count_cmd
);
10282 install_element(INTERFACE_NODE
,
10283 &interface_no_ip_igmp_last_member_query_count_cmd
);
10284 install_element(INTERFACE_NODE
,
10285 &interface_ip_igmp_last_member_query_interval_cmd
);
10286 install_element(INTERFACE_NODE
,
10287 &interface_no_ip_igmp_last_member_query_interval_cmd
);
10288 install_element(INTERFACE_NODE
, &interface_ip_pim_activeactive_cmd
);
10289 install_element(INTERFACE_NODE
, &interface_ip_pim_ssm_cmd
);
10290 install_element(INTERFACE_NODE
, &interface_no_ip_pim_ssm_cmd
);
10291 install_element(INTERFACE_NODE
, &interface_ip_pim_sm_cmd
);
10292 install_element(INTERFACE_NODE
, &interface_no_ip_pim_sm_cmd
);
10293 install_element(INTERFACE_NODE
, &interface_ip_pim_cmd
);
10294 install_element(INTERFACE_NODE
, &interface_no_ip_pim_cmd
);
10295 install_element(INTERFACE_NODE
, &interface_ip_pim_drprio_cmd
);
10296 install_element(INTERFACE_NODE
, &interface_no_ip_pim_drprio_cmd
);
10297 install_element(INTERFACE_NODE
, &interface_ip_pim_hello_cmd
);
10298 install_element(INTERFACE_NODE
, &interface_no_ip_pim_hello_cmd
);
10299 install_element(INTERFACE_NODE
, &interface_ip_pim_boundary_oil_cmd
);
10300 install_element(INTERFACE_NODE
, &interface_no_ip_pim_boundary_oil_cmd
);
10302 // Static mroutes NEB
10303 install_element(INTERFACE_NODE
, &interface_ip_mroute_cmd
);
10304 install_element(INTERFACE_NODE
, &interface_ip_mroute_source_cmd
);
10305 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_cmd
);
10306 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_source_cmd
);
10308 install_element(VIEW_NODE
, &show_ip_igmp_interface_cmd
);
10309 install_element(VIEW_NODE
, &show_ip_igmp_interface_vrf_all_cmd
);
10310 install_element(VIEW_NODE
, &show_ip_igmp_join_cmd
);
10311 install_element(VIEW_NODE
, &show_ip_igmp_join_vrf_all_cmd
);
10312 install_element(VIEW_NODE
, &show_ip_igmp_groups_cmd
);
10313 install_element(VIEW_NODE
, &show_ip_igmp_groups_vrf_all_cmd
);
10314 install_element(VIEW_NODE
, &show_ip_igmp_groups_retransmissions_cmd
);
10315 install_element(VIEW_NODE
, &show_ip_igmp_sources_cmd
);
10316 install_element(VIEW_NODE
, &show_ip_igmp_sources_retransmissions_cmd
);
10317 install_element(VIEW_NODE
, &show_ip_igmp_statistics_cmd
);
10318 install_element(VIEW_NODE
, &show_ip_pim_assert_cmd
);
10319 install_element(VIEW_NODE
, &show_ip_pim_assert_internal_cmd
);
10320 install_element(VIEW_NODE
, &show_ip_pim_assert_metric_cmd
);
10321 install_element(VIEW_NODE
, &show_ip_pim_assert_winner_metric_cmd
);
10322 install_element(VIEW_NODE
, &show_ip_pim_interface_traffic_cmd
);
10323 install_element(VIEW_NODE
, &show_ip_pim_interface_cmd
);
10324 install_element(VIEW_NODE
, &show_ip_pim_interface_vrf_all_cmd
);
10325 install_element(VIEW_NODE
, &show_ip_pim_join_cmd
);
10326 install_element(VIEW_NODE
, &show_ip_pim_join_vrf_all_cmd
);
10327 install_element(VIEW_NODE
, &show_ip_pim_local_membership_cmd
);
10328 install_element(VIEW_NODE
, &show_ip_pim_neighbor_cmd
);
10329 install_element(VIEW_NODE
, &show_ip_pim_neighbor_vrf_all_cmd
);
10330 install_element(VIEW_NODE
, &show_ip_pim_rpf_cmd
);
10331 install_element(VIEW_NODE
, &show_ip_pim_rpf_vrf_all_cmd
);
10332 install_element(VIEW_NODE
, &show_ip_pim_secondary_cmd
);
10333 install_element(VIEW_NODE
, &show_ip_pim_state_cmd
);
10334 install_element(VIEW_NODE
, &show_ip_pim_state_vrf_all_cmd
);
10335 install_element(VIEW_NODE
, &show_ip_pim_upstream_cmd
);
10336 install_element(VIEW_NODE
, &show_ip_pim_upstream_vrf_all_cmd
);
10337 install_element(VIEW_NODE
, &show_ip_pim_upstream_join_desired_cmd
);
10338 install_element(VIEW_NODE
, &show_ip_pim_upstream_rpf_cmd
);
10339 install_element(VIEW_NODE
, &show_ip_pim_rp_cmd
);
10340 install_element(VIEW_NODE
, &show_ip_pim_rp_vrf_all_cmd
);
10341 install_element(VIEW_NODE
, &show_ip_pim_bsr_cmd
);
10342 install_element(VIEW_NODE
, &show_ip_multicast_cmd
);
10343 install_element(VIEW_NODE
, &show_ip_multicast_vrf_all_cmd
);
10344 install_element(VIEW_NODE
, &show_ip_mroute_cmd
);
10345 install_element(VIEW_NODE
, &show_ip_mroute_vrf_all_cmd
);
10346 install_element(VIEW_NODE
, &show_ip_mroute_count_cmd
);
10347 install_element(VIEW_NODE
, &show_ip_mroute_count_vrf_all_cmd
);
10348 install_element(VIEW_NODE
, &show_ip_mroute_summary_cmd
);
10349 install_element(VIEW_NODE
, &show_ip_mroute_summary_vrf_all_cmd
);
10350 install_element(VIEW_NODE
, &show_ip_rib_cmd
);
10351 install_element(VIEW_NODE
, &show_ip_ssmpingd_cmd
);
10352 install_element(VIEW_NODE
, &show_debugging_pim_cmd
);
10353 install_element(VIEW_NODE
, &show_ip_pim_nexthop_cmd
);
10354 install_element(VIEW_NODE
, &show_ip_pim_nexthop_lookup_cmd
);
10355 install_element(VIEW_NODE
, &show_ip_pim_bsrp_cmd
);
10356 install_element(VIEW_NODE
, &show_ip_pim_bsm_db_cmd
);
10357 install_element(VIEW_NODE
, &show_ip_pim_statistics_cmd
);
10359 install_element(ENABLE_NODE
, &clear_ip_mroute_count_cmd
);
10360 install_element(ENABLE_NODE
, &clear_ip_interfaces_cmd
);
10361 install_element(ENABLE_NODE
, &clear_ip_igmp_interfaces_cmd
);
10362 install_element(ENABLE_NODE
, &clear_ip_mroute_cmd
);
10363 install_element(ENABLE_NODE
, &clear_ip_pim_interfaces_cmd
);
10364 install_element(ENABLE_NODE
, &clear_ip_pim_interface_traffic_cmd
);
10365 install_element(ENABLE_NODE
, &clear_ip_pim_oil_cmd
);
10366 install_element(ENABLE_NODE
, &clear_ip_pim_statistics_cmd
);
10368 install_element(ENABLE_NODE
, &debug_igmp_cmd
);
10369 install_element(ENABLE_NODE
, &no_debug_igmp_cmd
);
10370 install_element(ENABLE_NODE
, &debug_igmp_events_cmd
);
10371 install_element(ENABLE_NODE
, &no_debug_igmp_events_cmd
);
10372 install_element(ENABLE_NODE
, &debug_igmp_packets_cmd
);
10373 install_element(ENABLE_NODE
, &no_debug_igmp_packets_cmd
);
10374 install_element(ENABLE_NODE
, &debug_igmp_trace_cmd
);
10375 install_element(ENABLE_NODE
, &no_debug_igmp_trace_cmd
);
10376 install_element(ENABLE_NODE
, &debug_mroute_cmd
);
10377 install_element(ENABLE_NODE
, &debug_mroute_detail_cmd
);
10378 install_element(ENABLE_NODE
, &no_debug_mroute_cmd
);
10379 install_element(ENABLE_NODE
, &no_debug_mroute_detail_cmd
);
10380 install_element(ENABLE_NODE
, &debug_pim_static_cmd
);
10381 install_element(ENABLE_NODE
, &no_debug_pim_static_cmd
);
10382 install_element(ENABLE_NODE
, &debug_pim_cmd
);
10383 install_element(ENABLE_NODE
, &no_debug_pim_cmd
);
10384 install_element(ENABLE_NODE
, &debug_pim_nht_cmd
);
10385 install_element(ENABLE_NODE
, &no_debug_pim_nht_cmd
);
10386 install_element(ENABLE_NODE
, &debug_pim_nht_rp_cmd
);
10387 install_element(ENABLE_NODE
, &no_debug_pim_nht_rp_cmd
);
10388 install_element(ENABLE_NODE
, &debug_pim_events_cmd
);
10389 install_element(ENABLE_NODE
, &no_debug_pim_events_cmd
);
10390 install_element(ENABLE_NODE
, &debug_pim_packets_cmd
);
10391 install_element(ENABLE_NODE
, &no_debug_pim_packets_cmd
);
10392 install_element(ENABLE_NODE
, &debug_pim_packetdump_send_cmd
);
10393 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_send_cmd
);
10394 install_element(ENABLE_NODE
, &debug_pim_packetdump_recv_cmd
);
10395 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_recv_cmd
);
10396 install_element(ENABLE_NODE
, &debug_pim_trace_cmd
);
10397 install_element(ENABLE_NODE
, &no_debug_pim_trace_cmd
);
10398 install_element(ENABLE_NODE
, &debug_pim_trace_detail_cmd
);
10399 install_element(ENABLE_NODE
, &no_debug_pim_trace_detail_cmd
);
10400 install_element(ENABLE_NODE
, &debug_ssmpingd_cmd
);
10401 install_element(ENABLE_NODE
, &no_debug_ssmpingd_cmd
);
10402 install_element(ENABLE_NODE
, &debug_pim_zebra_cmd
);
10403 install_element(ENABLE_NODE
, &no_debug_pim_zebra_cmd
);
10404 install_element(ENABLE_NODE
, &debug_pim_vxlan_cmd
);
10405 install_element(ENABLE_NODE
, &no_debug_pim_vxlan_cmd
);
10406 install_element(ENABLE_NODE
, &debug_msdp_cmd
);
10407 install_element(ENABLE_NODE
, &no_debug_msdp_cmd
);
10408 install_element(ENABLE_NODE
, &debug_msdp_events_cmd
);
10409 install_element(ENABLE_NODE
, &no_debug_msdp_events_cmd
);
10410 install_element(ENABLE_NODE
, &debug_msdp_packets_cmd
);
10411 install_element(ENABLE_NODE
, &no_debug_msdp_packets_cmd
);
10412 install_element(ENABLE_NODE
, &debug_mtrace_cmd
);
10413 install_element(ENABLE_NODE
, &no_debug_mtrace_cmd
);
10414 install_element(ENABLE_NODE
, &debug_bsm_cmd
);
10415 install_element(ENABLE_NODE
, &no_debug_bsm_cmd
);
10417 install_element(CONFIG_NODE
, &debug_igmp_cmd
);
10418 install_element(CONFIG_NODE
, &no_debug_igmp_cmd
);
10419 install_element(CONFIG_NODE
, &debug_igmp_events_cmd
);
10420 install_element(CONFIG_NODE
, &no_debug_igmp_events_cmd
);
10421 install_element(CONFIG_NODE
, &debug_igmp_packets_cmd
);
10422 install_element(CONFIG_NODE
, &no_debug_igmp_packets_cmd
);
10423 install_element(CONFIG_NODE
, &debug_igmp_trace_cmd
);
10424 install_element(CONFIG_NODE
, &no_debug_igmp_trace_cmd
);
10425 install_element(CONFIG_NODE
, &debug_mroute_cmd
);
10426 install_element(CONFIG_NODE
, &debug_mroute_detail_cmd
);
10427 install_element(CONFIG_NODE
, &no_debug_mroute_cmd
);
10428 install_element(CONFIG_NODE
, &no_debug_mroute_detail_cmd
);
10429 install_element(CONFIG_NODE
, &debug_pim_static_cmd
);
10430 install_element(CONFIG_NODE
, &no_debug_pim_static_cmd
);
10431 install_element(CONFIG_NODE
, &debug_pim_cmd
);
10432 install_element(CONFIG_NODE
, &no_debug_pim_cmd
);
10433 install_element(CONFIG_NODE
, &debug_pim_nht_cmd
);
10434 install_element(CONFIG_NODE
, &no_debug_pim_nht_cmd
);
10435 install_element(CONFIG_NODE
, &debug_pim_nht_rp_cmd
);
10436 install_element(CONFIG_NODE
, &no_debug_pim_nht_rp_cmd
);
10437 install_element(CONFIG_NODE
, &debug_pim_events_cmd
);
10438 install_element(CONFIG_NODE
, &no_debug_pim_events_cmd
);
10439 install_element(CONFIG_NODE
, &debug_pim_packets_cmd
);
10440 install_element(CONFIG_NODE
, &no_debug_pim_packets_cmd
);
10441 install_element(CONFIG_NODE
, &debug_pim_trace_cmd
);
10442 install_element(CONFIG_NODE
, &no_debug_pim_trace_cmd
);
10443 install_element(CONFIG_NODE
, &debug_pim_trace_detail_cmd
);
10444 install_element(CONFIG_NODE
, &no_debug_pim_trace_detail_cmd
);
10445 install_element(CONFIG_NODE
, &debug_ssmpingd_cmd
);
10446 install_element(CONFIG_NODE
, &no_debug_ssmpingd_cmd
);
10447 install_element(CONFIG_NODE
, &debug_pim_zebra_cmd
);
10448 install_element(CONFIG_NODE
, &no_debug_pim_zebra_cmd
);
10449 install_element(CONFIG_NODE
, &debug_pim_vxlan_cmd
);
10450 install_element(CONFIG_NODE
, &no_debug_pim_vxlan_cmd
);
10451 install_element(CONFIG_NODE
, &debug_msdp_cmd
);
10452 install_element(CONFIG_NODE
, &no_debug_msdp_cmd
);
10453 install_element(CONFIG_NODE
, &debug_msdp_events_cmd
);
10454 install_element(CONFIG_NODE
, &no_debug_msdp_events_cmd
);
10455 install_element(CONFIG_NODE
, &debug_msdp_packets_cmd
);
10456 install_element(CONFIG_NODE
, &no_debug_msdp_packets_cmd
);
10457 install_element(CONFIG_NODE
, &debug_mtrace_cmd
);
10458 install_element(CONFIG_NODE
, &no_debug_mtrace_cmd
);
10459 install_element(CONFIG_NODE
, &debug_bsm_cmd
);
10460 install_element(CONFIG_NODE
, &no_debug_bsm_cmd
);
10462 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_member_cmd
);
10463 install_element(VRF_NODE
, &ip_msdp_mesh_group_member_cmd
);
10464 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
10465 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
10466 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_source_cmd
);
10467 install_element(VRF_NODE
, &ip_msdp_mesh_group_source_cmd
);
10468 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
10469 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
10470 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_cmd
);
10471 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_vrf_all_cmd
);
10472 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_cmd
);
10473 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_vrf_all_cmd
);
10474 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_cmd
);
10475 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_vrf_all_cmd
);
10476 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_cmd
);
10477 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_vrf_all_cmd
);
10478 install_element(VIEW_NODE
, &show_ip_pim_ssm_range_cmd
);
10479 install_element(VIEW_NODE
, &show_ip_pim_group_type_cmd
);
10480 install_element(VIEW_NODE
, &show_ip_pim_vxlan_sg_cmd
);
10481 install_element(VIEW_NODE
, &show_ip_pim_vxlan_sg_work_cmd
);
10482 install_element(INTERFACE_NODE
, &interface_pim_use_source_cmd
);
10483 install_element(INTERFACE_NODE
, &interface_no_pim_use_source_cmd
);
10484 /* Install BSM command */
10485 install_element(INTERFACE_NODE
, &ip_pim_bsm_cmd
);
10486 install_element(INTERFACE_NODE
, &no_ip_pim_bsm_cmd
);
10487 install_element(INTERFACE_NODE
, &ip_pim_ucast_bsm_cmd
);
10488 install_element(INTERFACE_NODE
, &no_ip_pim_ucast_bsm_cmd
);
10489 /* Install BFD command */
10490 install_element(INTERFACE_NODE
, &ip_pim_bfd_cmd
);
10491 install_element(INTERFACE_NODE
, &ip_pim_bfd_param_cmd
);
10492 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_cmd
);
10494 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_param_cmd
);
10495 #endif /* !HAVE_BFDD */