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"
66 #ifndef VTYSH_EXTRACT_PL
67 #include "pimd/pim_cmd_clippy.c"
70 static struct cmd_node interface_node
= {
71 INTERFACE_NODE
, "%s(config-if)# ", 1 /* vtysh ? yes */
74 static struct cmd_node debug_node
= {DEBUG_NODE
, "", 1};
76 static struct vrf
*pim_cmd_lookup_vrf(struct vty
*vty
, struct cmd_token
*argv
[],
77 const int argc
, int *idx
)
81 if (argv_find(argv
, argc
, "NAME", idx
))
82 vrf
= vrf_lookup_by_name(argv
[*idx
]->arg
);
84 vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
87 vty_out(vty
, "Specified VRF: %s does not exist\n",
93 static void pim_if_membership_clear(struct interface
*ifp
)
95 struct pim_interface
*pim_ifp
;
100 if (PIM_IF_TEST_PIM(pim_ifp
->options
)
101 && PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
105 pim_ifchannel_membership_clear(ifp
);
109 When PIM is disabled on interface, IGMPv3 local membership
110 information is not injected into PIM interface state.
112 The function pim_if_membership_refresh() fetches all IGMPv3 local
113 membership information into PIM. It is intented to be called
114 whenever PIM is enabled on the interface in order to collect missed
115 local membership information.
117 static void pim_if_membership_refresh(struct interface
*ifp
)
119 struct pim_interface
*pim_ifp
;
120 struct listnode
*sock_node
;
121 struct igmp_sock
*igmp
;
126 if (!PIM_IF_TEST_PIM(pim_ifp
->options
))
128 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
))
132 First clear off membership from all PIM (S,G) entries on the
136 pim_ifchannel_membership_clear(ifp
);
139 Then restore PIM (S,G) membership from all IGMPv3 (S,G) entries on
143 /* scan igmp sockets */
144 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
145 struct listnode
*grpnode
;
146 struct igmp_group
*grp
;
148 /* scan igmp groups */
149 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grpnode
,
151 struct listnode
*srcnode
;
152 struct igmp_source
*src
;
154 /* scan group sources */
155 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
,
158 if (IGMP_SOURCE_TEST_FORWARDING(
159 src
->source_flags
)) {
163 sizeof(struct prefix_sg
));
164 sg
.src
= src
->source_addr
;
165 sg
.grp
= grp
->group_addr
;
166 pim_ifchannel_local_membership_add(ifp
,
170 } /* scan group sources */
171 } /* scan igmp groups */
172 } /* scan igmp sockets */
175 Finally delete every PIM (S,G) entry lacking all state info
178 pim_ifchannel_delete_on_noinfo(ifp
);
181 static void pim_show_assert_helper(struct vty
*vty
,
182 struct pim_interface
*pim_ifp
,
183 struct pim_ifchannel
*ch
, time_t now
)
185 char ch_src_str
[INET_ADDRSTRLEN
];
186 char ch_grp_str
[INET_ADDRSTRLEN
];
187 char winner_str
[INET_ADDRSTRLEN
];
188 struct in_addr ifaddr
;
192 ifaddr
= pim_ifp
->primary_address
;
194 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
195 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
196 pim_inet4_dump("<assrt_win?>", ch
->ifassert_winner
, winner_str
,
199 pim_time_uptime(uptime
, sizeof(uptime
), now
- ch
->ifassert_creation
);
200 pim_time_timer_to_mmss(timer
, sizeof(timer
), ch
->t_ifassert_timer
);
202 vty_out(vty
, "%-16s %-15s %-15s %-15s %-6s %-15s %-8s %-5s\n",
203 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
, ch_grp_str
,
204 pim_ifchannel_ifassert_name(ch
->ifassert_state
), winner_str
,
208 static void pim_show_assert(struct pim_instance
*pim
, struct vty
*vty
)
210 struct pim_interface
*pim_ifp
;
211 struct pim_ifchannel
*ch
;
212 struct interface
*ifp
;
215 now
= pim_time_monotonic_sec();
218 "Interface Address Source Group State Winner Uptime Timer\n");
220 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
225 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
226 pim_show_assert_helper(vty
, pim_ifp
, ch
, now
);
227 } /* scan interface channels */
231 static void pim_show_assert_internal_helper(struct vty
*vty
,
232 struct pim_interface
*pim_ifp
,
233 struct pim_ifchannel
*ch
)
235 char ch_src_str
[INET_ADDRSTRLEN
];
236 char ch_grp_str
[INET_ADDRSTRLEN
];
237 struct in_addr ifaddr
;
239 ifaddr
= pim_ifp
->primary_address
;
241 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
242 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
243 vty_out(vty
, "%-16s %-15s %-15s %-15s %-3s %-3s %-3s %-4s\n",
244 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
, ch_grp_str
,
245 PIM_IF_FLAG_TEST_COULD_ASSERT(ch
->flags
) ? "yes" : "no",
246 pim_macro_ch_could_assert_eval(ch
) ? "yes" : "no",
247 PIM_IF_FLAG_TEST_ASSERT_TRACKING_DESIRED(ch
->flags
) ? "yes"
249 pim_macro_assert_tracking_desired_eval(ch
) ? "yes" : "no");
252 static void pim_show_assert_internal(struct pim_instance
*pim
, struct vty
*vty
)
254 struct pim_interface
*pim_ifp
;
255 struct pim_ifchannel
*ch
;
256 struct interface
*ifp
;
260 "ECA: Evaluate CouldAssert\n"
261 "ATD: AssertTrackingDesired\n"
262 "eATD: Evaluate AssertTrackingDesired\n\n");
265 "Interface Address Source Group CA eCA ATD eATD\n");
266 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
271 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
272 pim_show_assert_internal_helper(vty
, pim_ifp
, ch
);
273 } /* scan interface channels */
277 static void pim_show_assert_metric_helper(struct vty
*vty
,
278 struct pim_interface
*pim_ifp
,
279 struct pim_ifchannel
*ch
)
281 char ch_src_str
[INET_ADDRSTRLEN
];
282 char ch_grp_str
[INET_ADDRSTRLEN
];
283 char addr_str
[INET_ADDRSTRLEN
];
284 struct pim_assert_metric am
;
285 struct in_addr ifaddr
;
287 ifaddr
= pim_ifp
->primary_address
;
289 am
= pim_macro_spt_assert_metric(&ch
->upstream
->rpf
,
290 pim_ifp
->primary_address
);
292 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
293 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
294 pim_inet4_dump("<addr?>", am
.ip_address
, addr_str
, sizeof(addr_str
));
296 vty_out(vty
, "%-16s %-15s %-15s %-15s %-3s %4u %6u %-15s\n",
297 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
, ch_grp_str
,
298 am
.rpt_bit_flag
? "yes" : "no", am
.metric_preference
,
299 am
.route_metric
, addr_str
);
302 static void pim_show_assert_metric(struct pim_instance
*pim
, struct vty
*vty
)
304 struct pim_interface
*pim_ifp
;
305 struct pim_ifchannel
*ch
;
306 struct interface
*ifp
;
309 "Interface Address Source Group RPT Pref Metric Address \n");
311 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
316 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
317 pim_show_assert_metric_helper(vty
, pim_ifp
, ch
);
318 } /* scan interface channels */
322 static void pim_show_assert_winner_metric_helper(struct vty
*vty
,
323 struct pim_interface
*pim_ifp
,
324 struct pim_ifchannel
*ch
)
326 char ch_src_str
[INET_ADDRSTRLEN
];
327 char ch_grp_str
[INET_ADDRSTRLEN
];
328 char addr_str
[INET_ADDRSTRLEN
];
329 struct pim_assert_metric
*am
;
330 struct in_addr ifaddr
;
334 ifaddr
= pim_ifp
->primary_address
;
336 am
= &ch
->ifassert_winner_metric
;
338 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
339 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
340 pim_inet4_dump("<addr?>", am
->ip_address
, addr_str
, sizeof(addr_str
));
342 if (am
->metric_preference
== PIM_ASSERT_METRIC_PREFERENCE_MAX
)
343 snprintf(pref_str
, sizeof(pref_str
), "INFI");
345 snprintf(pref_str
, sizeof(pref_str
), "%4u",
346 am
->metric_preference
);
348 if (am
->route_metric
== PIM_ASSERT_ROUTE_METRIC_MAX
)
349 snprintf(metr_str
, sizeof(metr_str
), "INFI");
351 snprintf(metr_str
, sizeof(metr_str
), "%6u", am
->route_metric
);
353 vty_out(vty
, "%-16s %-15s %-15s %-15s %-3s %-4s %-6s %-15s\n",
354 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
, ch_grp_str
,
355 am
->rpt_bit_flag
? "yes" : "no", pref_str
, metr_str
, addr_str
);
358 static void pim_show_assert_winner_metric(struct pim_instance
*pim
,
361 struct pim_interface
*pim_ifp
;
362 struct pim_ifchannel
*ch
;
363 struct interface
*ifp
;
366 "Interface Address Source Group RPT Pref Metric Address \n");
368 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
373 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
374 pim_show_assert_winner_metric_helper(vty
, pim_ifp
, ch
);
375 } /* scan interface channels */
379 static void json_object_pim_ifp_add(struct json_object
*json
,
380 struct interface
*ifp
)
382 struct pim_interface
*pim_ifp
;
385 json_object_string_add(json
, "name", ifp
->name
);
386 json_object_string_add(json
, "state", if_is_up(ifp
) ? "up" : "down");
387 json_object_string_add(json
, "address",
388 inet_ntoa(pim_ifp
->primary_address
));
389 json_object_int_add(json
, "index", ifp
->ifindex
);
391 if (if_is_multicast(ifp
))
392 json_object_boolean_true_add(json
, "flagMulticast");
394 if (if_is_broadcast(ifp
))
395 json_object_boolean_true_add(json
, "flagBroadcast");
397 if (ifp
->flags
& IFF_ALLMULTI
)
398 json_object_boolean_true_add(json
, "flagAllMulticast");
400 if (ifp
->flags
& IFF_PROMISC
)
401 json_object_boolean_true_add(json
, "flagPromiscuous");
403 if (PIM_IF_IS_DELETED(ifp
))
404 json_object_boolean_true_add(json
, "flagDeleted");
406 if (pim_if_lan_delay_enabled(ifp
))
407 json_object_boolean_true_add(json
, "lanDelayEnabled");
410 static void pim_show_membership_helper(struct vty
*vty
,
411 struct pim_interface
*pim_ifp
,
412 struct pim_ifchannel
*ch
,
413 struct json_object
*json
)
415 char ch_src_str
[INET_ADDRSTRLEN
];
416 char ch_grp_str
[INET_ADDRSTRLEN
];
417 json_object
*json_iface
= NULL
;
418 json_object
*json_row
= NULL
;
420 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
421 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
423 json_object_object_get_ex(json
, ch
->interface
->name
, &json_iface
);
425 json_iface
= json_object_new_object();
426 json_object_pim_ifp_add(json_iface
, ch
->interface
);
427 json_object_object_add(json
, ch
->interface
->name
, json_iface
);
430 json_row
= json_object_new_object();
431 json_object_string_add(json_row
, "source", ch_src_str
);
432 json_object_string_add(json_row
, "group", ch_grp_str
);
433 json_object_string_add(json_row
, "localMembership",
434 ch
->local_ifmembership
== PIM_IFMEMBERSHIP_NOINFO
437 json_object_object_add(json_iface
, ch_grp_str
, json_row
);
439 static void pim_show_membership(struct pim_instance
*pim
, struct vty
*vty
,
442 struct pim_interface
*pim_ifp
;
443 struct pim_ifchannel
*ch
;
444 struct interface
*ifp
;
446 json_object
*json
= NULL
;
447 json_object
*json_tmp
= NULL
;
449 json
= json_object_new_object();
451 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
456 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
457 pim_show_membership_helper(vty
, pim_ifp
, ch
, json
);
458 } /* scan interface channels */
462 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
463 json
, JSON_C_TO_STRING_PRETTY
));
466 "Interface Address Source Group Membership\n");
469 * Example of the json data we are traversing
475 * "address":"10.1.20.1",
477 * "flagMulticast":true,
478 * "flagBroadcast":true,
479 * "lanDelayEnabled":true,
482 * "group":"226.10.10.10",
483 * "localMembership":"INCLUDE"
489 /* foreach interface */
490 json_object_object_foreach(json
, key
, val
)
493 /* Find all of the keys where the val is an object. In
495 * above the only one is 226.10.10.10
497 json_object_object_foreach(val
, if_field_key
,
500 type
= json_object_get_type(if_field_val
);
502 if (type
== json_type_object
) {
503 vty_out(vty
, "%-16s ", key
);
505 json_object_object_get_ex(
506 val
, "address", &json_tmp
);
507 vty_out(vty
, "%-15s ",
508 json_object_get_string(
511 json_object_object_get_ex(if_field_val
,
514 vty_out(vty
, "%-15s ",
515 json_object_get_string(
519 vty_out(vty
, "%-15s ", if_field_key
);
521 json_object_object_get_ex(
522 if_field_val
, "localMembership",
524 vty_out(vty
, "%-10s\n",
525 json_object_get_string(
532 json_object_free(json
);
535 static void pim_print_ifp_flags(struct vty
*vty
, struct interface
*ifp
,
538 vty_out(vty
, "Flags\n");
539 vty_out(vty
, "-----\n");
540 vty_out(vty
, "All Multicast : %s\n",
541 (ifp
->flags
& IFF_ALLMULTI
) ? "yes" : "no");
542 vty_out(vty
, "Broadcast : %s\n",
543 if_is_broadcast(ifp
) ? "yes" : "no");
544 vty_out(vty
, "Deleted : %s\n",
545 PIM_IF_IS_DELETED(ifp
) ? "yes" : "no");
546 vty_out(vty
, "Interface Index : %d\n", ifp
->ifindex
);
547 vty_out(vty
, "Multicast : %s\n",
548 if_is_multicast(ifp
) ? "yes" : "no");
549 vty_out(vty
, "Multicast Loop : %d\n", mloop
);
550 vty_out(vty
, "Promiscuous : %s\n",
551 (ifp
->flags
& IFF_PROMISC
) ? "yes" : "no");
556 static void igmp_show_interfaces(struct pim_instance
*pim
, struct vty
*vty
,
559 struct interface
*ifp
;
561 json_object
*json
= NULL
;
562 json_object
*json_row
= NULL
;
564 now
= pim_time_monotonic_sec();
567 json
= json_object_new_object();
570 "Interface State Address V Querier Query Timer Uptime\n");
572 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
573 struct pim_interface
*pim_ifp
;
574 struct listnode
*sock_node
;
575 struct igmp_sock
*igmp
;
582 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
585 char query_hhmmss
[10];
587 pim_time_uptime(uptime
, sizeof(uptime
),
588 now
- igmp
->sock_creation
);
589 pim_time_timer_to_hhmmss(query_hhmmss
,
590 sizeof(query_hhmmss
),
591 igmp
->t_igmp_query_timer
);
594 json_row
= json_object_new_object();
595 json_object_pim_ifp_add(json_row
, ifp
);
596 json_object_string_add(json_row
, "upTime",
598 json_object_int_add(json_row
, "version",
599 pim_ifp
->igmp_version
);
601 if (igmp
->t_igmp_query_timer
) {
602 json_object_boolean_true_add(json_row
,
604 json_object_string_add(json_row
,
609 json_object_object_add(json
, ifp
->name
,
612 if (igmp
->mtrace_only
) {
613 json_object_boolean_true_add(
614 json_row
, "mtraceOnly");
618 "%-16s %5s %15s %d %7s %11s %8s\n",
621 ? (igmp
->mtrace_only
? "mtrc"
624 inet_ntoa(igmp
->ifaddr
),
625 pim_ifp
->igmp_version
,
626 igmp
->t_igmp_query_timer
? "local"
628 query_hhmmss
, uptime
);
634 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
635 json
, JSON_C_TO_STRING_PRETTY
));
636 json_object_free(json
);
640 static void igmp_show_interfaces_single(struct pim_instance
*pim
,
641 struct vty
*vty
, const char *ifname
,
644 struct igmp_sock
*igmp
;
645 struct interface
*ifp
;
646 struct listnode
*sock_node
;
647 struct pim_interface
*pim_ifp
;
649 char query_hhmmss
[10];
650 char other_hhmmss
[10];
651 int found_ifname
= 0;
654 long gmi_msec
; /* Group Membership Interval */
657 long oqpi_msec
; /* Other Querier Present Interval */
661 json_object
*json
= NULL
;
662 json_object
*json_row
= NULL
;
665 json
= json_object_new_object();
667 now
= pim_time_monotonic_sec();
669 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
675 if (strcmp(ifname
, "detail") && strcmp(ifname
, ifp
->name
))
678 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
681 pim_time_uptime(uptime
, sizeof(uptime
),
682 now
- igmp
->sock_creation
);
683 pim_time_timer_to_hhmmss(query_hhmmss
,
684 sizeof(query_hhmmss
),
685 igmp
->t_igmp_query_timer
);
686 pim_time_timer_to_hhmmss(other_hhmmss
,
687 sizeof(other_hhmmss
),
688 igmp
->t_other_querier_timer
);
690 gmi_msec
= PIM_IGMP_GMI_MSEC(
691 igmp
->querier_robustness_variable
,
692 igmp
->querier_query_interval
,
693 pim_ifp
->igmp_query_max_response_time_dsec
);
696 pim_ifp
->igmp_default_query_interval
);
698 oqpi_msec
= PIM_IGMP_OQPI_MSEC(
699 igmp
->querier_robustness_variable
,
700 igmp
->querier_query_interval
,
701 pim_ifp
->igmp_query_max_response_time_dsec
);
703 lmqt_msec
= PIM_IGMP_LMQT_MSEC(
704 pim_ifp
->igmp_query_max_response_time_dsec
,
705 igmp
->querier_robustness_variable
);
709 igmp
->querier_robustness_variable
,
710 igmp
->querier_query_interval
,
711 pim_ifp
->igmp_query_max_response_time_dsec
)
714 qri_msec
= pim_ifp
->igmp_query_max_response_time_dsec
716 if (pim_ifp
->pim_sock_fd
>= 0)
717 mloop
= pim_socket_mcastloop_get(
718 pim_ifp
->pim_sock_fd
);
723 json_row
= json_object_new_object();
724 json_object_pim_ifp_add(json_row
, ifp
);
725 json_object_string_add(json_row
, "upTime",
727 json_object_string_add(json_row
, "querier",
728 igmp
->t_igmp_query_timer
731 json_object_int_add(json_row
, "queryStartCount",
732 igmp
->startup_query_count
);
733 json_object_string_add(json_row
,
736 json_object_string_add(json_row
,
739 json_object_int_add(json_row
, "version",
740 pim_ifp
->igmp_version
);
743 "timerGroupMembershipIntervalMsec",
745 json_object_int_add(json_row
,
746 "timerLastMemberQueryMsec",
750 "timerOlderHostPresentIntervalMsec",
754 "timerOtherQuerierPresentIntervalMsec",
757 json_row
, "timerQueryInterval",
758 igmp
->querier_query_interval
);
761 "timerQueryResponseIntervalMsec",
764 json_row
, "timerRobustnessVariable",
765 igmp
->querier_robustness_variable
);
766 json_object_int_add(json_row
,
767 "timerStartupQueryInterval",
770 json_object_object_add(json
, ifp
->name
,
773 if (igmp
->mtrace_only
) {
774 json_object_boolean_true_add(
775 json_row
, "mtraceOnly");
778 vty_out(vty
, "Interface : %s\n", ifp
->name
);
779 vty_out(vty
, "State : %s\n",
781 ? (igmp
->mtrace_only
? "mtrace"
784 vty_out(vty
, "Address : %s\n",
785 inet_ntoa(pim_ifp
->primary_address
));
786 vty_out(vty
, "Uptime : %s\n", uptime
);
787 vty_out(vty
, "Version : %d\n",
788 pim_ifp
->igmp_version
);
792 vty_out(vty
, "Querier\n");
793 vty_out(vty
, "-------\n");
794 vty_out(vty
, "Querier : %s\n",
795 igmp
->t_igmp_query_timer
? "local"
797 vty_out(vty
, "Start Count : %d\n",
798 igmp
->startup_query_count
);
799 vty_out(vty
, "Query Timer : %s\n",
801 vty_out(vty
, "Other Timer : %s\n",
806 vty_out(vty
, "Timers\n");
807 vty_out(vty
, "------\n");
809 "Group Membership Interval : %lis\n",
812 "Last Member Query Time : %lis\n",
815 "Older Host Present Interval : %lis\n",
818 "Other Querier Present Interval : %lis\n",
821 "Query Interval : %ds\n",
822 igmp
->querier_query_interval
);
824 "Query Response Interval : %lis\n",
827 "Robustness Variable : %d\n",
828 igmp
->querier_robustness_variable
);
830 "Startup Query Interval : %ds\n",
835 pim_print_ifp_flags(vty
, ifp
, mloop
);
841 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
842 json
, JSON_C_TO_STRING_PRETTY
));
843 json_object_free(json
);
846 vty_out(vty
, "%% No such interface\n");
850 static void igmp_show_interface_join(struct pim_instance
*pim
, struct vty
*vty
)
852 struct interface
*ifp
;
855 now
= pim_time_monotonic_sec();
858 "Interface Address Source Group Socket Uptime \n");
860 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
861 struct pim_interface
*pim_ifp
;
862 struct listnode
*join_node
;
863 struct igmp_join
*ij
;
864 struct in_addr pri_addr
;
865 char pri_addr_str
[INET_ADDRSTRLEN
];
872 if (!pim_ifp
->igmp_join_list
)
875 pri_addr
= pim_find_primary_addr(ifp
);
876 pim_inet4_dump("<pri?>", pri_addr
, pri_addr_str
,
877 sizeof(pri_addr_str
));
879 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_join_list
, join_node
,
881 char group_str
[INET_ADDRSTRLEN
];
882 char source_str
[INET_ADDRSTRLEN
];
885 pim_time_uptime(uptime
, sizeof(uptime
),
886 now
- ij
->sock_creation
);
887 pim_inet4_dump("<grp?>", ij
->group_addr
, group_str
,
889 pim_inet4_dump("<src?>", ij
->source_addr
, source_str
,
892 vty_out(vty
, "%-16s %-15s %-15s %-15s %6d %8s\n",
893 ifp
->name
, pri_addr_str
, source_str
, group_str
,
894 ij
->sock_fd
, uptime
);
895 } /* for (pim_ifp->igmp_join_list) */
900 static void pim_show_interfaces_single(struct pim_instance
*pim
,
901 struct vty
*vty
, const char *ifname
,
904 struct in_addr ifaddr
;
905 struct interface
*ifp
;
906 struct listnode
*neighnode
;
907 struct listnode
*upnode
;
908 struct pim_interface
*pim_ifp
;
909 struct pim_neighbor
*neigh
;
910 struct pim_upstream
*up
;
912 char dr_str
[INET_ADDRSTRLEN
];
915 char grp_str
[INET_ADDRSTRLEN
];
916 char hello_period
[10];
917 char hello_timer
[10];
918 char neigh_src_str
[INET_ADDRSTRLEN
];
919 char src_str
[INET_ADDRSTRLEN
];
920 char stat_uptime
[10];
923 int found_ifname
= 0;
925 json_object
*json
= NULL
;
926 json_object
*json_row
= NULL
;
927 json_object
*json_pim_neighbor
= NULL
;
928 json_object
*json_pim_neighbors
= NULL
;
929 json_object
*json_group
= NULL
;
930 json_object
*json_group_source
= NULL
;
931 json_object
*json_fhr_sources
= NULL
;
932 struct pim_secondary_addr
*sec_addr
;
933 struct listnode
*sec_node
;
935 now
= pim_time_monotonic_sec();
938 json
= json_object_new_object();
940 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
946 if (strcmp(ifname
, "detail") && strcmp(ifname
, ifp
->name
))
950 ifaddr
= pim_ifp
->primary_address
;
951 pim_inet4_dump("<dr?>", pim_ifp
->pim_dr_addr
, dr_str
,
953 pim_time_uptime_begin(dr_uptime
, sizeof(dr_uptime
), now
,
954 pim_ifp
->pim_dr_election_last
);
955 pim_time_timer_to_hhmmss(hello_timer
, sizeof(hello_timer
),
956 pim_ifp
->t_pim_hello_timer
);
957 pim_time_mmss(hello_period
, sizeof(hello_period
),
958 pim_ifp
->pim_hello_period
);
959 pim_time_uptime(stat_uptime
, sizeof(stat_uptime
),
960 now
- pim_ifp
->pim_ifstat_start
);
961 if (pim_ifp
->pim_sock_fd
>= 0)
962 mloop
= pim_socket_mcastloop_get(pim_ifp
->pim_sock_fd
);
967 char pbuf
[PREFIX2STR_BUFFER
];
968 json_row
= json_object_new_object();
969 json_object_pim_ifp_add(json_row
, ifp
);
971 if (pim_ifp
->update_source
.s_addr
!= INADDR_ANY
) {
972 json_object_string_add(
973 json_row
, "useSource",
974 inet_ntoa(pim_ifp
->update_source
));
976 if (pim_ifp
->sec_addr_list
) {
977 json_object
*sec_list
= NULL
;
979 sec_list
= json_object_new_array();
980 for (ALL_LIST_ELEMENTS_RO(
981 pim_ifp
->sec_addr_list
, sec_node
,
983 json_object_array_add(
985 json_object_new_string(
991 json_object_object_add(json_row
,
992 "secondaryAddressList",
997 if (pim_ifp
->pim_neighbor_list
->count
) {
998 json_pim_neighbors
= json_object_new_object();
1000 for (ALL_LIST_ELEMENTS_RO(
1001 pim_ifp
->pim_neighbor_list
,
1002 neighnode
, neigh
)) {
1004 json_object_new_object();
1005 pim_inet4_dump("<src?>",
1008 sizeof(neigh_src_str
));
1009 pim_time_uptime(uptime
, sizeof(uptime
),
1010 now
- neigh
->creation
);
1011 pim_time_timer_to_hhmmss(
1012 expire
, sizeof(expire
),
1013 neigh
->t_expire_timer
);
1015 json_object_string_add(
1016 json_pim_neighbor
, "address",
1018 json_object_string_add(
1019 json_pim_neighbor
, "upTime",
1021 json_object_string_add(
1022 json_pim_neighbor
, "holdtime",
1025 json_object_object_add(
1031 json_object_object_add(json_row
, "neighbors",
1032 json_pim_neighbors
);
1035 json_object_string_add(json_row
, "drAddress", dr_str
);
1036 json_object_int_add(json_row
, "drPriority",
1037 pim_ifp
->pim_dr_priority
);
1038 json_object_string_add(json_row
, "drUptime", dr_uptime
);
1039 json_object_int_add(json_row
, "drElections",
1040 pim_ifp
->pim_dr_election_count
);
1041 json_object_int_add(json_row
, "drChanges",
1042 pim_ifp
->pim_dr_election_changes
);
1045 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
,
1047 if (ifp
!= up
->rpf
.source_nexthop
.interface
)
1050 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
))
1053 if (!json_fhr_sources
)
1055 json_object_new_object();
1057 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
,
1059 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
,
1061 pim_time_uptime(uptime
, sizeof(uptime
),
1062 now
- up
->state_transition
);
1065 * Does this group live in json_fhr_sources?
1068 json_object_object_get_ex(json_fhr_sources
,
1069 grp_str
, &json_group
);
1072 json_group
= json_object_new_object();
1073 json_object_object_add(json_fhr_sources
,
1078 json_group_source
= json_object_new_object();
1079 json_object_string_add(json_group_source
,
1081 json_object_string_add(json_group_source
,
1083 json_object_string_add(json_group_source
,
1085 json_object_object_add(json_group
, src_str
,
1089 if (json_fhr_sources
) {
1090 json_object_object_add(json_row
,
1095 json_object_int_add(json_row
, "helloPeriod",
1096 pim_ifp
->pim_hello_period
);
1097 json_object_string_add(json_row
, "helloTimer",
1099 json_object_string_add(json_row
, "helloStatStart",
1101 json_object_int_add(json_row
, "helloReceived",
1102 pim_ifp
->pim_ifstat_hello_recv
);
1103 json_object_int_add(json_row
, "helloReceivedFailed",
1104 pim_ifp
->pim_ifstat_hello_recvfail
);
1105 json_object_int_add(json_row
, "helloSend",
1106 pim_ifp
->pim_ifstat_hello_sent
);
1107 json_object_int_add(json_row
, "hellosendFailed",
1108 pim_ifp
->pim_ifstat_hello_sendfail
);
1109 json_object_int_add(json_row
, "helloGenerationId",
1110 pim_ifp
->pim_generation_id
);
1111 json_object_int_add(json_row
, "flagMulticastLoop",
1114 json_object_int_add(
1115 json_row
, "effectivePropagationDelay",
1116 pim_if_effective_propagation_delay_msec(ifp
));
1117 json_object_int_add(
1118 json_row
, "effectiveOverrideInterval",
1119 pim_if_effective_override_interval_msec(ifp
));
1120 json_object_int_add(
1121 json_row
, "joinPruneOverrideInterval",
1122 pim_if_jp_override_interval_msec(ifp
));
1124 json_object_int_add(
1125 json_row
, "propagationDelay",
1126 pim_ifp
->pim_propagation_delay_msec
);
1127 json_object_int_add(
1128 json_row
, "propagationDelayHighest",
1129 pim_ifp
->pim_neighbors_highest_propagation_delay_msec
);
1130 json_object_int_add(
1131 json_row
, "overrideInterval",
1132 pim_ifp
->pim_override_interval_msec
);
1133 json_object_int_add(
1134 json_row
, "overrideIntervalHighest",
1135 pim_ifp
->pim_neighbors_highest_override_interval_msec
);
1136 json_object_object_add(json
, ifp
->name
, json_row
);
1139 vty_out(vty
, "Interface : %s\n", ifp
->name
);
1140 vty_out(vty
, "State : %s\n",
1141 if_is_up(ifp
) ? "up" : "down");
1142 if (pim_ifp
->update_source
.s_addr
!= INADDR_ANY
) {
1143 vty_out(vty
, "Use Source : %s\n",
1144 inet_ntoa(pim_ifp
->update_source
));
1146 if (pim_ifp
->sec_addr_list
) {
1147 char pbuf
[PREFIX2STR_BUFFER
];
1148 vty_out(vty
, "Address : %s (primary)\n",
1150 for (ALL_LIST_ELEMENTS_RO(
1151 pim_ifp
->sec_addr_list
, sec_node
,
1153 vty_out(vty
, " %s\n",
1154 prefix2str(&sec_addr
->addr
,
1155 pbuf
, sizeof(pbuf
)));
1158 vty_out(vty
, "Address : %s\n",
1166 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
,
1167 neighnode
, neigh
)) {
1170 vty_out(vty
, "PIM Neighbors\n");
1171 vty_out(vty
, "-------------\n");
1175 pim_inet4_dump("<src?>", neigh
->source_addr
,
1177 sizeof(neigh_src_str
));
1178 pim_time_uptime(uptime
, sizeof(uptime
),
1179 now
- neigh
->creation
);
1180 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
1181 neigh
->t_expire_timer
);
1183 "%-15s : up for %s, holdtime expires in %s\n",
1184 neigh_src_str
, uptime
, expire
);
1187 if (!print_header
) {
1192 vty_out(vty
, "Designated Router\n");
1193 vty_out(vty
, "-----------------\n");
1194 vty_out(vty
, "Address : %s\n", dr_str
);
1195 vty_out(vty
, "Priority : %u(%d)\n",
1196 pim_ifp
->pim_dr_priority
,
1197 pim_ifp
->pim_dr_num_nondrpri_neighbors
);
1198 vty_out(vty
, "Uptime : %s\n", dr_uptime
);
1199 vty_out(vty
, "Elections : %d\n",
1200 pim_ifp
->pim_dr_election_count
);
1201 vty_out(vty
, "Changes : %d\n",
1202 pim_ifp
->pim_dr_election_changes
);
1208 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
,
1211 if (strcmp(ifp
->name
,
1212 up
->rpf
.source_nexthop
1217 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
))
1222 "FHR - First Hop Router\n");
1224 "----------------------\n");
1228 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
,
1230 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
,
1232 pim_time_uptime(uptime
, sizeof(uptime
),
1233 now
- up
->state_transition
);
1235 "%s : %s is a source, uptime is %s\n",
1236 grp_str
, src_str
, uptime
);
1239 if (!print_header
) {
1244 vty_out(vty
, "Hellos\n");
1245 vty_out(vty
, "------\n");
1246 vty_out(vty
, "Period : %d\n",
1247 pim_ifp
->pim_hello_period
);
1248 vty_out(vty
, "Timer : %s\n", hello_timer
);
1249 vty_out(vty
, "StatStart : %s\n", stat_uptime
);
1250 vty_out(vty
, "Receive : %d\n",
1251 pim_ifp
->pim_ifstat_hello_recv
);
1252 vty_out(vty
, "Receive Failed : %d\n",
1253 pim_ifp
->pim_ifstat_hello_recvfail
);
1254 vty_out(vty
, "Send : %d\n",
1255 pim_ifp
->pim_ifstat_hello_sent
);
1256 vty_out(vty
, "Send Failed : %d\n",
1257 pim_ifp
->pim_ifstat_hello_sendfail
);
1258 vty_out(vty
, "Generation ID : %08x\n",
1259 pim_ifp
->pim_generation_id
);
1263 pim_print_ifp_flags(vty
, ifp
, mloop
);
1265 vty_out(vty
, "Join Prune Interval\n");
1266 vty_out(vty
, "-------------------\n");
1267 vty_out(vty
, "LAN Delay : %s\n",
1268 pim_if_lan_delay_enabled(ifp
) ? "yes" : "no");
1269 vty_out(vty
, "Effective Propagation Delay : %d msec\n",
1270 pim_if_effective_propagation_delay_msec(ifp
));
1271 vty_out(vty
, "Effective Override Interval : %d msec\n",
1272 pim_if_effective_override_interval_msec(ifp
));
1273 vty_out(vty
, "Join Prune Override Interval : %d msec\n",
1274 pim_if_jp_override_interval_msec(ifp
));
1278 vty_out(vty
, "LAN Prune Delay\n");
1279 vty_out(vty
, "---------------\n");
1280 vty_out(vty
, "Propagation Delay : %d msec\n",
1281 pim_ifp
->pim_propagation_delay_msec
);
1282 vty_out(vty
, "Propagation Delay (Highest) : %d msec\n",
1283 pim_ifp
->pim_neighbors_highest_propagation_delay_msec
);
1284 vty_out(vty
, "Override Interval : %d msec\n",
1285 pim_ifp
->pim_override_interval_msec
);
1286 vty_out(vty
, "Override Interval (Highest) : %d msec\n",
1287 pim_ifp
->pim_neighbors_highest_override_interval_msec
);
1294 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1295 json
, JSON_C_TO_STRING_PRETTY
));
1296 json_object_free(json
);
1299 vty_out(vty
, "%% No such interface\n");
1303 static void igmp_show_statistics(struct pim_instance
*pim
, struct vty
*vty
,
1304 const char *ifname
, bool uj
)
1306 struct interface
*ifp
;
1307 struct igmp_stats rx_stats
;
1309 igmp_stats_init(&rx_stats
);
1311 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1312 struct pim_interface
*pim_ifp
;
1313 struct listnode
*sock_node
;
1314 struct igmp_sock
*igmp
;
1316 pim_ifp
= ifp
->info
;
1321 if (ifname
&& strcmp(ifname
, ifp
->name
))
1324 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
1326 igmp_stats_add(&rx_stats
, &igmp
->rx_stats
);
1330 json_object
*json
= NULL
;
1331 json_object
*json_row
= NULL
;
1333 json
= json_object_new_object();
1334 json_row
= json_object_new_object();
1336 json_object_string_add(json_row
, "name", ifname
? ifname
:
1338 json_object_int_add(json_row
, "queryV1", rx_stats
.query_v1
);
1339 json_object_int_add(json_row
, "queryV2", rx_stats
.query_v2
);
1340 json_object_int_add(json_row
, "queryV3", rx_stats
.query_v3
);
1341 json_object_int_add(json_row
, "leaveV3", rx_stats
.leave_v2
);
1342 json_object_int_add(json_row
, "reportV1", rx_stats
.report_v1
);
1343 json_object_int_add(json_row
, "reportV2", rx_stats
.report_v2
);
1344 json_object_int_add(json_row
, "reportV3", rx_stats
.report_v3
);
1345 json_object_int_add(json_row
, "mtraceResponse",
1346 rx_stats
.mtrace_rsp
);
1347 json_object_int_add(json_row
, "mtraceRequest",
1348 rx_stats
.mtrace_req
);
1349 json_object_int_add(json_row
, "unsupported",
1350 rx_stats
.unsupported
);
1351 json_object_object_add(json
, ifname
? ifname
: "global",
1353 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1354 json
, JSON_C_TO_STRING_PRETTY
));
1355 json_object_free(json
);
1357 vty_out(vty
, "IGMP RX statistics\n");
1358 vty_out(vty
, "Interface : %s\n",
1359 ifname
? ifname
: "global");
1360 vty_out(vty
, "V1 query : %u\n", rx_stats
.query_v1
);
1361 vty_out(vty
, "V2 query : %u\n", rx_stats
.query_v2
);
1362 vty_out(vty
, "V3 query : %u\n", rx_stats
.query_v3
);
1363 vty_out(vty
, "V2 leave : %u\n", rx_stats
.leave_v2
);
1364 vty_out(vty
, "V1 report : %u\n", rx_stats
.report_v1
);
1365 vty_out(vty
, "V2 report : %u\n", rx_stats
.report_v2
);
1366 vty_out(vty
, "V3 report : %u\n", rx_stats
.report_v3
);
1367 vty_out(vty
, "mtrace response : %u\n", rx_stats
.mtrace_rsp
);
1368 vty_out(vty
, "mtrace request : %u\n", rx_stats
.mtrace_req
);
1369 vty_out(vty
, "unsupported : %u\n", rx_stats
.unsupported
);
1373 static void pim_show_interfaces(struct pim_instance
*pim
, struct vty
*vty
,
1376 struct interface
*ifp
;
1377 struct listnode
*upnode
;
1378 struct pim_interface
*pim_ifp
;
1379 struct pim_upstream
*up
;
1382 int pim_ifchannels
= 0;
1383 json_object
*json
= NULL
;
1384 json_object
*json_row
= NULL
;
1385 json_object
*json_tmp
;
1387 json
= json_object_new_object();
1389 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1390 pim_ifp
= ifp
->info
;
1395 pim_nbrs
= pim_ifp
->pim_neighbor_list
->count
;
1396 pim_ifchannels
= pim_if_ifchannel_count(pim_ifp
);
1399 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
, up
))
1400 if (ifp
== up
->rpf
.source_nexthop
.interface
)
1401 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
1404 json_row
= json_object_new_object();
1405 json_object_pim_ifp_add(json_row
, ifp
);
1406 json_object_int_add(json_row
, "pimNeighbors", pim_nbrs
);
1407 json_object_int_add(json_row
, "pimIfChannels", pim_ifchannels
);
1408 json_object_int_add(json_row
, "firstHopRouterCount", fhr
);
1409 json_object_string_add(json_row
, "pimDesignatedRouter",
1410 inet_ntoa(pim_ifp
->pim_dr_addr
));
1412 if (pim_ifp
->pim_dr_addr
.s_addr
1413 == pim_ifp
->primary_address
.s_addr
)
1414 json_object_boolean_true_add(
1415 json_row
, "pimDesignatedRouterLocal");
1417 json_object_object_add(json
, ifp
->name
, json_row
);
1421 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1422 json
, JSON_C_TO_STRING_PRETTY
));
1425 "Interface State Address PIM Nbrs PIM DR FHR IfChannels\n");
1427 json_object_object_foreach(json
, key
, val
)
1429 vty_out(vty
, "%-16s ", key
);
1431 json_object_object_get_ex(val
, "state", &json_tmp
);
1432 vty_out(vty
, "%5s ", json_object_get_string(json_tmp
));
1434 json_object_object_get_ex(val
, "address", &json_tmp
);
1435 vty_out(vty
, "%15s ",
1436 json_object_get_string(json_tmp
));
1438 json_object_object_get_ex(val
, "pimNeighbors",
1440 vty_out(vty
, "%8d ", json_object_get_int(json_tmp
));
1442 if (json_object_object_get_ex(
1443 val
, "pimDesignatedRouterLocal",
1445 vty_out(vty
, "%15s ", "local");
1447 json_object_object_get_ex(
1448 val
, "pimDesignatedRouter", &json_tmp
);
1449 vty_out(vty
, "%15s ",
1450 json_object_get_string(json_tmp
));
1453 json_object_object_get_ex(val
, "firstHopRouter",
1455 vty_out(vty
, "%3d ", json_object_get_int(json_tmp
));
1457 json_object_object_get_ex(val
, "pimIfChannels",
1459 vty_out(vty
, "%9d\n", json_object_get_int(json_tmp
));
1463 json_object_free(json
);
1466 static void pim_show_interface_traffic(struct pim_instance
*pim
,
1467 struct vty
*vty
, bool uj
)
1469 struct interface
*ifp
= NULL
;
1470 struct pim_interface
*pim_ifp
= NULL
;
1471 json_object
*json
= NULL
;
1472 json_object
*json_row
= NULL
;
1475 json
= json_object_new_object();
1478 vty_out(vty
, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s\n",
1479 "Interface", " HELLO", " JOIN",
1480 " PRUNE", " REGISTER", "REGISTER-STOP",
1482 vty_out(vty
, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s\n", "",
1483 " Rx/Tx", " Rx/Tx", " Rx/Tx",
1484 " Rx/Tx", " Rx/Tx", " Rx/Tx");
1486 "---------------------------------------------------------------------------------------------------------------\n");
1489 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1490 pim_ifp
= ifp
->info
;
1495 if (pim_ifp
->pim_sock_fd
< 0)
1498 json_row
= json_object_new_object();
1499 json_object_pim_ifp_add(json_row
, ifp
);
1500 json_object_int_add(json_row
, "helloRx",
1501 pim_ifp
->pim_ifstat_hello_recv
);
1502 json_object_int_add(json_row
, "helloTx",
1503 pim_ifp
->pim_ifstat_hello_sent
);
1504 json_object_int_add(json_row
, "joinRx",
1505 pim_ifp
->pim_ifstat_join_recv
);
1506 json_object_int_add(json_row
, "joinTx",
1507 pim_ifp
->pim_ifstat_join_send
);
1508 json_object_int_add(json_row
, "registerRx",
1509 pim_ifp
->pim_ifstat_reg_recv
);
1510 json_object_int_add(json_row
, "registerTx",
1511 pim_ifp
->pim_ifstat_reg_recv
);
1512 json_object_int_add(json_row
, "registerStopRx",
1513 pim_ifp
->pim_ifstat_reg_stop_recv
);
1514 json_object_int_add(json_row
, "registerStopTx",
1515 pim_ifp
->pim_ifstat_reg_stop_send
);
1516 json_object_int_add(json_row
, "assertRx",
1517 pim_ifp
->pim_ifstat_assert_recv
);
1518 json_object_int_add(json_row
, "assertTx",
1519 pim_ifp
->pim_ifstat_assert_send
);
1521 json_object_object_add(json
, ifp
->name
, json_row
);
1524 "%-16s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u \n",
1525 ifp
->name
, pim_ifp
->pim_ifstat_hello_recv
,
1526 pim_ifp
->pim_ifstat_hello_sent
,
1527 pim_ifp
->pim_ifstat_join_recv
,
1528 pim_ifp
->pim_ifstat_join_send
,
1529 pim_ifp
->pim_ifstat_prune_recv
,
1530 pim_ifp
->pim_ifstat_prune_send
,
1531 pim_ifp
->pim_ifstat_reg_recv
,
1532 pim_ifp
->pim_ifstat_reg_send
,
1533 pim_ifp
->pim_ifstat_reg_stop_recv
,
1534 pim_ifp
->pim_ifstat_reg_stop_send
,
1535 pim_ifp
->pim_ifstat_assert_recv
,
1536 pim_ifp
->pim_ifstat_assert_send
);
1540 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1541 json
, JSON_C_TO_STRING_PRETTY
));
1542 json_object_free(json
);
1546 static void pim_show_interface_traffic_single(struct pim_instance
*pim
,
1548 const char *ifname
, bool uj
)
1550 struct interface
*ifp
= NULL
;
1551 struct pim_interface
*pim_ifp
= NULL
;
1552 json_object
*json
= NULL
;
1553 json_object
*json_row
= NULL
;
1554 uint8_t found_ifname
= 0;
1557 json
= json_object_new_object();
1560 vty_out(vty
, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s\n",
1561 "Interface", " HELLO", " JOIN", " PRUNE",
1562 " REGISTER", " REGISTER-STOP", " ASSERT");
1563 vty_out(vty
, "%-14s%-18s%-17s%-17s%-17s%-17s%-17s\n", "",
1564 " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1565 " Rx/Tx", " Rx/Tx");
1567 "---------------------------------------------------------------------------------------------------------------------\n");
1570 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1571 if (strcmp(ifname
, ifp
->name
))
1574 pim_ifp
= ifp
->info
;
1579 if (pim_ifp
->pim_sock_fd
< 0)
1584 json_row
= json_object_new_object();
1585 json_object_pim_ifp_add(json_row
, ifp
);
1586 json_object_int_add(json_row
, "helloRx",
1587 pim_ifp
->pim_ifstat_hello_recv
);
1588 json_object_int_add(json_row
, "helloTx",
1589 pim_ifp
->pim_ifstat_hello_sent
);
1590 json_object_int_add(json_row
, "joinRx",
1591 pim_ifp
->pim_ifstat_join_recv
);
1592 json_object_int_add(json_row
, "joinTx",
1593 pim_ifp
->pim_ifstat_join_send
);
1594 json_object_int_add(json_row
, "registerRx",
1595 pim_ifp
->pim_ifstat_reg_recv
);
1596 json_object_int_add(json_row
, "registerTx",
1597 pim_ifp
->pim_ifstat_reg_recv
);
1598 json_object_int_add(json_row
, "registerStopRx",
1599 pim_ifp
->pim_ifstat_reg_stop_recv
);
1600 json_object_int_add(json_row
, "registerStopTx",
1601 pim_ifp
->pim_ifstat_reg_stop_send
);
1602 json_object_int_add(json_row
, "assertRx",
1603 pim_ifp
->pim_ifstat_assert_recv
);
1604 json_object_int_add(json_row
, "assertTx",
1605 pim_ifp
->pim_ifstat_assert_send
);
1607 json_object_object_add(json
, ifp
->name
, json_row
);
1610 "%-16s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u \n",
1611 ifp
->name
, pim_ifp
->pim_ifstat_hello_recv
,
1612 pim_ifp
->pim_ifstat_hello_sent
,
1613 pim_ifp
->pim_ifstat_join_recv
,
1614 pim_ifp
->pim_ifstat_join_send
,
1615 pim_ifp
->pim_ifstat_prune_recv
,
1616 pim_ifp
->pim_ifstat_prune_send
,
1617 pim_ifp
->pim_ifstat_reg_recv
,
1618 pim_ifp
->pim_ifstat_reg_send
,
1619 pim_ifp
->pim_ifstat_reg_stop_recv
,
1620 pim_ifp
->pim_ifstat_reg_stop_send
,
1621 pim_ifp
->pim_ifstat_assert_recv
,
1622 pim_ifp
->pim_ifstat_assert_send
);
1626 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1627 json
, JSON_C_TO_STRING_PRETTY
));
1628 json_object_free(json
);
1631 vty_out(vty
, "%% No such interface\n");
1635 static void pim_show_join_helper(struct vty
*vty
, struct pim_interface
*pim_ifp
,
1636 struct pim_ifchannel
*ch
, json_object
*json
,
1637 time_t now
, bool uj
)
1639 char ch_src_str
[INET_ADDRSTRLEN
];
1640 char ch_grp_str
[INET_ADDRSTRLEN
];
1641 json_object
*json_iface
= NULL
;
1642 json_object
*json_row
= NULL
;
1643 json_object
*json_grp
= NULL
;
1644 struct in_addr ifaddr
;
1649 ifaddr
= pim_ifp
->primary_address
;
1651 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
1652 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
1654 pim_time_uptime_begin(uptime
, sizeof(uptime
), now
, ch
->ifjoin_creation
);
1655 pim_time_timer_to_mmss(expire
, sizeof(expire
),
1656 ch
->t_ifjoin_expiry_timer
);
1657 pim_time_timer_to_mmss(prune
, sizeof(prune
),
1658 ch
->t_ifjoin_prune_pending_timer
);
1661 json_object_object_get_ex(json
, ch
->interface
->name
,
1665 json_iface
= json_object_new_object();
1666 json_object_pim_ifp_add(json_iface
, ch
->interface
);
1667 json_object_object_add(json
, ch
->interface
->name
,
1671 json_row
= json_object_new_object();
1672 json_object_string_add(json_row
, "source", ch_src_str
);
1673 json_object_string_add(json_row
, "group", ch_grp_str
);
1674 json_object_string_add(json_row
, "upTime", uptime
);
1675 json_object_string_add(json_row
, "expire", expire
);
1676 json_object_string_add(json_row
, "prune", prune
);
1677 json_object_string_add(
1678 json_row
, "channelJoinName",
1679 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
, ch
->flags
));
1680 if (PIM_IF_FLAG_TEST_S_G_RPT(ch
->flags
))
1681 json_object_int_add(json_row
, "SGRpt", 1);
1683 json_object_object_get_ex(json_iface
, ch_grp_str
, &json_grp
);
1685 json_grp
= json_object_new_object();
1686 json_object_object_add(json_grp
, ch_src_str
, json_row
);
1687 json_object_object_add(json_iface
, ch_grp_str
,
1690 json_object_object_add(json_grp
, ch_src_str
, json_row
);
1692 vty_out(vty
, "%-16s %-15s %-15s %-15s %-10s %8s %-6s %5s\n",
1693 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
,
1695 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
, ch
->flags
),
1696 uptime
, expire
, prune
);
1700 static void pim_show_join(struct pim_instance
*pim
, struct vty
*vty
,
1701 struct prefix_sg
*sg
, bool uj
)
1703 struct pim_interface
*pim_ifp
;
1704 struct pim_ifchannel
*ch
;
1705 struct interface
*ifp
;
1707 json_object
*json
= NULL
;
1709 now
= pim_time_monotonic_sec();
1712 json
= json_object_new_object();
1715 "Interface Address Source Group State Uptime Expire Prune\n");
1717 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1718 pim_ifp
= ifp
->info
;
1722 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
1723 if (sg
->grp
.s_addr
!= 0
1724 && sg
->grp
.s_addr
!= ch
->sg
.grp
.s_addr
)
1726 if (sg
->src
.s_addr
!= 0
1727 && sg
->src
.s_addr
!= ch
->sg
.src
.s_addr
)
1729 pim_show_join_helper(vty
, pim_ifp
, ch
, json
, now
, uj
);
1730 } /* scan interface channels */
1734 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1735 json
, JSON_C_TO_STRING_PRETTY
));
1736 json_object_free(json
);
1740 static void pim_show_neighbors_single(struct pim_instance
*pim
, struct vty
*vty
,
1741 const char *neighbor
, bool uj
)
1743 struct listnode
*neighnode
;
1744 struct interface
*ifp
;
1745 struct pim_interface
*pim_ifp
;
1746 struct pim_neighbor
*neigh
;
1748 int found_neighbor
= 0;
1749 int option_address_list
;
1750 int option_dr_priority
;
1751 int option_generation_id
;
1752 int option_holdtime
;
1753 int option_lan_prune_delay
;
1757 char neigh_src_str
[INET_ADDRSTRLEN
];
1759 json_object
*json
= NULL
;
1760 json_object
*json_ifp
= NULL
;
1761 json_object
*json_row
= NULL
;
1763 now
= pim_time_monotonic_sec();
1766 json
= json_object_new_object();
1768 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1769 pim_ifp
= ifp
->info
;
1774 if (pim_ifp
->pim_sock_fd
< 0)
1777 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
1779 pim_inet4_dump("<src?>", neigh
->source_addr
,
1780 neigh_src_str
, sizeof(neigh_src_str
));
1783 * The user can specify either the interface name or the
1785 * If this pim_ifp matches neither then skip.
1787 if (strcmp(neighbor
, "detail")
1788 && strcmp(neighbor
, ifp
->name
)
1789 && strcmp(neighbor
, neigh_src_str
))
1793 pim_time_uptime(uptime
, sizeof(uptime
),
1794 now
- neigh
->creation
);
1795 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
1796 neigh
->t_expire_timer
);
1798 option_address_list
= 0;
1799 option_dr_priority
= 0;
1800 option_generation_id
= 0;
1801 option_holdtime
= 0;
1802 option_lan_prune_delay
= 0;
1805 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1806 PIM_OPTION_MASK_ADDRESS_LIST
))
1807 option_address_list
= 1;
1809 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1810 PIM_OPTION_MASK_DR_PRIORITY
))
1811 option_dr_priority
= 1;
1813 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1814 PIM_OPTION_MASK_GENERATION_ID
))
1815 option_generation_id
= 1;
1817 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1818 PIM_OPTION_MASK_HOLDTIME
))
1819 option_holdtime
= 1;
1821 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1822 PIM_OPTION_MASK_LAN_PRUNE_DELAY
))
1823 option_lan_prune_delay
= 1;
1825 if (PIM_OPTION_IS_SET(
1826 neigh
->hello_options
,
1827 PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION
))
1832 /* Does this ifp live in json? If not create
1834 json_object_object_get_ex(json
, ifp
->name
,
1838 json_ifp
= json_object_new_object();
1839 json_object_pim_ifp_add(json_ifp
, ifp
);
1840 json_object_object_add(json
, ifp
->name
,
1844 json_row
= json_object_new_object();
1845 json_object_string_add(json_row
, "interface",
1847 json_object_string_add(json_row
, "address",
1849 json_object_string_add(json_row
, "upTime",
1851 json_object_string_add(json_row
, "holdtime",
1853 json_object_int_add(json_row
, "drPriority",
1854 neigh
->dr_priority
);
1855 json_object_int_add(json_row
, "generationId",
1856 neigh
->generation_id
);
1858 if (option_address_list
)
1859 json_object_boolean_true_add(
1861 "helloOptionAddressList");
1863 if (option_dr_priority
)
1864 json_object_boolean_true_add(
1866 "helloOptionDrPriority");
1868 if (option_generation_id
)
1869 json_object_boolean_true_add(
1871 "helloOptionGenerationId");
1873 if (option_holdtime
)
1874 json_object_boolean_true_add(
1876 "helloOptionHoldtime");
1878 if (option_lan_prune_delay
)
1879 json_object_boolean_true_add(
1881 "helloOptionLanPruneDelay");
1884 json_object_boolean_true_add(
1885 json_row
, "helloOptionTBit");
1887 json_object_object_add(json_ifp
, neigh_src_str
,
1891 vty_out(vty
, "Interface : %s\n", ifp
->name
);
1892 vty_out(vty
, "Neighbor : %s\n", neigh_src_str
);
1900 " DR Priority : %d\n",
1901 neigh
->dr_priority
);
1903 " Generation ID : %08x\n",
1904 neigh
->generation_id
);
1906 " Override Interval (msec) : %d\n",
1907 neigh
->override_interval_msec
);
1909 " Propagation Delay (msec) : %d\n",
1910 neigh
->propagation_delay_msec
);
1912 " Hello Option - Address List : %s\n",
1913 option_address_list
? "yes" : "no");
1915 " Hello Option - DR Priority : %s\n",
1916 option_dr_priority
? "yes" : "no");
1918 " Hello Option - Generation ID : %s\n",
1919 option_generation_id
? "yes" : "no");
1921 " Hello Option - Holdtime : %s\n",
1922 option_holdtime
? "yes" : "no");
1924 " Hello Option - LAN Prune Delay : %s\n",
1925 option_lan_prune_delay
? "yes" : "no");
1927 " Hello Option - T-bit : %s\n",
1928 option_t_bit
? "yes" : "no");
1929 pim_bfd_show_info(vty
, neigh
->bfd_info
,
1937 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1938 json
, JSON_C_TO_STRING_PRETTY
));
1939 json_object_free(json
);
1942 if (!found_neighbor
)
1944 "%% No such interface or neighbor\n");
1949 static void pim_show_state(struct pim_instance
*pim
, struct vty
*vty
,
1950 const char *src_or_group
, const char *group
, bool uj
)
1952 struct channel_oil
*c_oil
;
1953 struct listnode
*node
;
1954 json_object
*json
= NULL
;
1955 json_object
*json_group
= NULL
;
1956 json_object
*json_ifp_in
= NULL
;
1957 json_object
*json_ifp_out
= NULL
;
1958 json_object
*json_source
= NULL
;
1961 now
= pim_time_monotonic_sec();
1964 json
= json_object_new_object();
1967 "Codes: J -> Pim Join, I -> IGMP Report, S -> Source, * -> Inherited from (*,G), V -> VxLAN");
1969 "\nInstalled Source Group IIF OIL\n");
1972 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
1973 char grp_str
[INET_ADDRSTRLEN
];
1974 char src_str
[INET_ADDRSTRLEN
];
1975 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
1976 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
1978 struct interface
*ifp_in
;
1981 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
1983 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
1985 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
1988 strcpy(in_ifname
, ifp_in
->name
);
1990 strcpy(in_ifname
, "<iif?>");
1993 if (strcmp(src_or_group
, src_str
)
1994 && strcmp(src_or_group
, grp_str
))
1997 if (group
&& strcmp(group
, grp_str
))
2003 /* Find the group, create it if it doesn't exist */
2004 json_object_object_get_ex(json
, grp_str
, &json_group
);
2007 json_group
= json_object_new_object();
2008 json_object_object_add(json
, grp_str
,
2012 /* Find the source nested under the group, create it if
2013 * it doesn't exist */
2014 json_object_object_get_ex(json_group
, src_str
,
2018 json_source
= json_object_new_object();
2019 json_object_object_add(json_group
, src_str
,
2023 /* Find the inbound interface nested under the source,
2024 * create it if it doesn't exist */
2025 json_object_object_get_ex(json_source
, in_ifname
,
2029 json_ifp_in
= json_object_new_object();
2030 json_object_object_add(json_source
, in_ifname
,
2032 json_object_int_add(json_source
, "Installed",
2034 json_object_int_add(json_source
, "RefCount",
2035 c_oil
->oil_ref_count
);
2036 json_object_int_add(json_source
, "OilListSize",
2038 json_object_int_add(
2039 json_source
, "OilRescan",
2040 c_oil
->oil_inherited_rescan
);
2041 json_object_int_add(json_source
, "LastUsed",
2042 c_oil
->cc
.lastused
);
2043 json_object_int_add(json_source
, "PacketCount",
2045 json_object_int_add(json_source
, "ByteCount",
2047 json_object_int_add(json_source
,
2049 c_oil
->cc
.wrong_if
);
2052 vty_out(vty
, "%-9d %-15s %-15s %-16s ",
2053 c_oil
->installed
, src_str
, grp_str
, in_ifname
);
2056 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
2058 struct interface
*ifp_out
;
2059 char oif_uptime
[10];
2062 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
2066 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
2068 oif_uptime
, sizeof(oif_uptime
),
2069 now
- c_oil
->oif_creation
[oif_vif_index
]);
2072 strcpy(out_ifname
, ifp_out
->name
);
2074 strcpy(out_ifname
, "<oif?>");
2077 json_ifp_out
= json_object_new_object();
2078 json_object_string_add(json_ifp_out
, "source",
2080 json_object_string_add(json_ifp_out
, "group",
2082 json_object_string_add(json_ifp_out
,
2085 json_object_string_add(json_ifp_out
,
2086 "outboundInterface",
2088 json_object_int_add(json_ifp_out
, "installed",
2091 json_object_object_add(json_ifp_in
, out_ifname
,
2096 vty_out(vty
, "%s(%c%c%c%c%c)", out_ifname
,
2097 (c_oil
->oif_flags
[oif_vif_index
]
2098 & PIM_OIF_FLAG_PROTO_IGMP
)
2101 (c_oil
->oif_flags
[oif_vif_index
]
2102 & PIM_OIF_FLAG_PROTO_PIM
)
2105 (c_oil
->oif_flags
[oif_vif_index
]
2106 & PIM_OIF_FLAG_PROTO_VXLAN
)
2109 (c_oil
->oif_flags
[oif_vif_index
]
2110 & PIM_OIF_FLAG_PROTO_SOURCE
)
2113 (c_oil
->oif_flags
[oif_vif_index
]
2114 & PIM_OIF_FLAG_PROTO_STAR
)
2118 vty_out(vty
, ", %s(%c%c%c%c%c)",
2120 (c_oil
->oif_flags
[oif_vif_index
]
2121 & PIM_OIF_FLAG_PROTO_IGMP
)
2124 (c_oil
->oif_flags
[oif_vif_index
]
2125 & PIM_OIF_FLAG_PROTO_PIM
)
2128 (c_oil
->oif_flags
[oif_vif_index
]
2129 & PIM_OIF_FLAG_PROTO_VXLAN
)
2132 (c_oil
->oif_flags
[oif_vif_index
]
2133 & PIM_OIF_FLAG_PROTO_SOURCE
)
2136 (c_oil
->oif_flags
[oif_vif_index
]
2137 & PIM_OIF_FLAG_PROTO_STAR
)
2149 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2150 json
, JSON_C_TO_STRING_PRETTY
));
2151 json_object_free(json
);
2157 static void pim_show_neighbors(struct pim_instance
*pim
, struct vty
*vty
,
2160 struct listnode
*neighnode
;
2161 struct interface
*ifp
;
2162 struct pim_interface
*pim_ifp
;
2163 struct pim_neighbor
*neigh
;
2167 char neigh_src_str
[INET_ADDRSTRLEN
];
2168 json_object
*json
= NULL
;
2169 json_object
*json_ifp_rows
= NULL
;
2170 json_object
*json_row
= NULL
;
2172 now
= pim_time_monotonic_sec();
2175 json
= json_object_new_object();
2178 "Interface Neighbor Uptime Holdtime DR Pri\n");
2181 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2182 pim_ifp
= ifp
->info
;
2187 if (pim_ifp
->pim_sock_fd
< 0)
2191 json_ifp_rows
= json_object_new_object();
2193 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
2195 pim_inet4_dump("<src?>", neigh
->source_addr
,
2196 neigh_src_str
, sizeof(neigh_src_str
));
2197 pim_time_uptime(uptime
, sizeof(uptime
),
2198 now
- neigh
->creation
);
2199 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
2200 neigh
->t_expire_timer
);
2203 json_row
= json_object_new_object();
2204 json_object_string_add(json_row
, "interface",
2206 json_object_string_add(json_row
, "neighbor",
2208 json_object_string_add(json_row
, "upTime",
2210 json_object_string_add(json_row
, "holdTime",
2212 json_object_int_add(json_row
, "holdTimeMax",
2214 json_object_int_add(json_row
, "drPriority",
2215 neigh
->dr_priority
);
2216 json_object_object_add(json_ifp_rows
,
2217 neigh_src_str
, json_row
);
2220 vty_out(vty
, "%-16s %15s %8s %8s %6d\n",
2221 ifp
->name
, neigh_src_str
, uptime
,
2222 expire
, neigh
->dr_priority
);
2227 json_object_object_add(json
, ifp
->name
, json_ifp_rows
);
2228 json_ifp_rows
= NULL
;
2233 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2234 json
, JSON_C_TO_STRING_PRETTY
));
2235 json_object_free(json
);
2239 static void pim_show_neighbors_secondary(struct pim_instance
*pim
,
2242 struct interface
*ifp
;
2245 "Interface Address Neighbor Secondary \n");
2247 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2248 struct pim_interface
*pim_ifp
;
2249 struct in_addr ifaddr
;
2250 struct listnode
*neighnode
;
2251 struct pim_neighbor
*neigh
;
2253 pim_ifp
= ifp
->info
;
2258 if (pim_ifp
->pim_sock_fd
< 0)
2261 ifaddr
= pim_ifp
->primary_address
;
2263 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
2265 char neigh_src_str
[INET_ADDRSTRLEN
];
2266 struct listnode
*prefix_node
;
2269 if (!neigh
->prefix_list
)
2272 pim_inet4_dump("<src?>", neigh
->source_addr
,
2273 neigh_src_str
, sizeof(neigh_src_str
));
2275 for (ALL_LIST_ELEMENTS_RO(neigh
->prefix_list
,
2277 char neigh_sec_str
[PREFIX2STR_BUFFER
];
2279 prefix2str(p
, neigh_sec_str
,
2280 sizeof(neigh_sec_str
));
2282 vty_out(vty
, "%-16s %-15s %-15s %-15s\n",
2283 ifp
->name
, inet_ntoa(ifaddr
),
2284 neigh_src_str
, neigh_sec_str
);
2290 static void json_object_pim_upstream_add(json_object
*json
,
2291 struct pim_upstream
*up
)
2293 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED
)
2294 json_object_boolean_true_add(json
, "drJoinDesired");
2296 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED
)
2297 json_object_boolean_true_add(json
, "drJoinDesiredUpdated");
2299 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
2300 json_object_boolean_true_add(json
, "firstHopRouter");
2302 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_IGMP
)
2303 json_object_boolean_true_add(json
, "sourceIgmp");
2305 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_PIM
)
2306 json_object_boolean_true_add(json
, "sourcePim");
2308 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_STREAM
)
2309 json_object_boolean_true_add(json
, "sourceStream");
2311 /* XXX: need to print ths flag in the plain text display as well */
2312 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_MSDP
)
2313 json_object_boolean_true_add(json
, "sourceMsdp");
2317 pim_upstream_state2brief_str(enum pim_upstream_state join_state
,
2320 switch (join_state
) {
2321 case PIM_UPSTREAM_NOTJOINED
:
2322 strcpy(state_str
, "NotJ");
2324 case PIM_UPSTREAM_JOINED
:
2325 strcpy(state_str
, "J");
2328 strcpy(state_str
, "Unk");
2333 static const char *pim_reg_state2brief_str(enum pim_reg_state reg_state
,
2336 switch (reg_state
) {
2337 case PIM_REG_NOINFO
:
2338 strcpy(state_str
, "RegNI");
2341 strcpy(state_str
, "RegJ");
2343 case PIM_REG_JOIN_PENDING
:
2345 strcpy(state_str
, "RegP");
2348 strcpy(state_str
, "Unk");
2353 static void pim_show_upstream(struct pim_instance
*pim
, struct vty
*vty
,
2354 struct prefix_sg
*sg
, bool uj
)
2356 struct listnode
*upnode
;
2357 struct pim_upstream
*up
;
2359 json_object
*json
= NULL
;
2360 json_object
*json_group
= NULL
;
2361 json_object
*json_row
= NULL
;
2363 now
= pim_time_monotonic_sec();
2366 json
= json_object_new_object();
2369 "Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt\n");
2371 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
, up
)) {
2372 char src_str
[INET_ADDRSTRLEN
];
2373 char grp_str
[INET_ADDRSTRLEN
];
2375 char join_timer
[10];
2378 char msdp_reg_timer
[10];
2379 char state_str
[PIM_REG_STATE_STR_LEN
];
2381 if (sg
->grp
.s_addr
!= 0 && sg
->grp
.s_addr
!= up
->sg
.grp
.s_addr
)
2383 if (sg
->src
.s_addr
!= 0 && sg
->src
.s_addr
!= up
->sg
.src
.s_addr
)
2386 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2387 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2388 pim_time_uptime(uptime
, sizeof(uptime
),
2389 now
- up
->state_transition
);
2390 pim_time_timer_to_hhmmss(join_timer
, sizeof(join_timer
),
2394 * If the upstream is not dummy and it has a J/P timer for the
2395 * neighbor display that
2397 if (!up
->t_join_timer
&& up
->rpf
.source_nexthop
.interface
) {
2398 struct pim_neighbor
*nbr
;
2400 nbr
= pim_neighbor_find(
2401 up
->rpf
.source_nexthop
.interface
,
2402 up
->rpf
.rpf_addr
.u
.prefix4
);
2404 pim_time_timer_to_hhmmss(join_timer
,
2409 pim_time_timer_to_hhmmss(rs_timer
, sizeof(rs_timer
),
2411 pim_time_timer_to_hhmmss(ka_timer
, sizeof(ka_timer
),
2413 pim_time_timer_to_hhmmss(msdp_reg_timer
, sizeof(msdp_reg_timer
),
2414 up
->t_msdp_reg_timer
);
2416 pim_upstream_state2brief_str(up
->join_state
, state_str
);
2417 if (up
->reg_state
!= PIM_REG_NOINFO
) {
2418 char tmp_str
[PIM_REG_STATE_STR_LEN
];
2420 sprintf(state_str
+ strlen(state_str
), ",%s",
2421 pim_reg_state2brief_str(up
->reg_state
,
2426 json_object_object_get_ex(json
, grp_str
, &json_group
);
2429 json_group
= json_object_new_object();
2430 json_object_object_add(json
, grp_str
,
2434 json_row
= json_object_new_object();
2435 json_object_pim_upstream_add(json_row
, up
);
2436 json_object_string_add(
2437 json_row
, "inboundInterface",
2438 up
->rpf
.source_nexthop
.interface
2439 ? up
->rpf
.source_nexthop
.interface
->name
2443 * The RPF address we use is slightly different
2444 * based upon what we are looking up.
2445 * If we have a S, list that unless
2446 * we are the FHR, else we just put
2447 * the RP as the rpfAddress
2449 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
2450 || up
->sg
.src
.s_addr
== INADDR_ANY
) {
2451 char rpf
[PREFIX_STRLEN
];
2452 struct pim_rpf
*rpg
;
2454 rpg
= RP(pim
, up
->sg
.grp
);
2455 pim_inet4_dump("<rpf?>",
2456 rpg
->rpf_addr
.u
.prefix4
, rpf
,
2458 json_object_string_add(json_row
, "rpfAddress",
2461 json_object_string_add(json_row
, "rpfAddress",
2465 json_object_string_add(json_row
, "source", src_str
);
2466 json_object_string_add(json_row
, "group", grp_str
);
2467 json_object_string_add(json_row
, "state", state_str
);
2468 json_object_string_add(
2469 json_row
, "joinState",
2470 pim_upstream_state2str(up
->join_state
));
2471 json_object_string_add(
2472 json_row
, "regState",
2473 pim_reg_state2str(up
->reg_state
, state_str
));
2474 json_object_string_add(json_row
, "upTime", uptime
);
2475 json_object_string_add(json_row
, "joinTimer",
2477 json_object_string_add(json_row
, "resetTimer",
2479 json_object_string_add(json_row
, "keepaliveTimer",
2481 json_object_string_add(json_row
, "msdpRegTimer",
2483 json_object_int_add(json_row
, "refCount",
2485 json_object_int_add(json_row
, "sptBit", up
->sptbit
);
2486 json_object_object_add(json_group
, src_str
, json_row
);
2489 "%-16s%-15s %-15s %-11s %-8s %-9s %-9s %-9s %6d\n",
2490 up
->rpf
.source_nexthop
.interface
2491 ? up
->rpf
.source_nexthop
.interface
->name
2493 src_str
, grp_str
, state_str
, uptime
, join_timer
,
2494 rs_timer
, ka_timer
, up
->ref_count
);
2499 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2500 json
, JSON_C_TO_STRING_PRETTY
));
2501 json_object_free(json
);
2505 static void pim_show_join_desired_helper(struct pim_instance
*pim
,
2507 struct pim_interface
*pim_ifp
,
2508 struct pim_ifchannel
*ch
,
2509 json_object
*json
, bool uj
)
2511 struct pim_upstream
*up
= ch
->upstream
;
2512 json_object
*json_group
= NULL
;
2513 char src_str
[INET_ADDRSTRLEN
];
2514 char grp_str
[INET_ADDRSTRLEN
];
2515 json_object
*json_row
= NULL
;
2517 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2518 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2521 json_object_object_get_ex(json
, grp_str
, &json_group
);
2524 json_group
= json_object_new_object();
2525 json_object_object_add(json
, grp_str
, json_group
);
2528 json_row
= json_object_new_object();
2529 json_object_pim_upstream_add(json_row
, up
);
2530 json_object_string_add(json_row
, "interface",
2531 ch
->interface
->name
);
2532 json_object_string_add(json_row
, "source", src_str
);
2533 json_object_string_add(json_row
, "group", grp_str
);
2535 if (pim_macro_ch_lost_assert(ch
))
2536 json_object_boolean_true_add(json_row
, "lostAssert");
2538 if (pim_macro_chisin_joins(ch
))
2539 json_object_boolean_true_add(json_row
, "joins");
2541 if (pim_macro_chisin_pim_include(ch
))
2542 json_object_boolean_true_add(json_row
, "pimInclude");
2544 if (pim_upstream_evaluate_join_desired(pim
, up
))
2545 json_object_boolean_true_add(json_row
,
2546 "evaluateJoinDesired");
2548 json_object_object_add(json_group
, src_str
, json_row
);
2551 vty_out(vty
, "%-16s %-15s %-15s %-10s %-5s %-10s %-11s %-6s\n",
2552 ch
->interface
->name
, src_str
, grp_str
,
2553 pim_macro_ch_lost_assert(ch
) ? "yes" : "no",
2554 pim_macro_chisin_joins(ch
) ? "yes" : "no",
2555 pim_macro_chisin_pim_include(ch
) ? "yes" : "no",
2556 PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(up
->flags
)
2559 pim_upstream_evaluate_join_desired(pim
, up
) ? "yes"
2564 static void pim_show_join_desired(struct pim_instance
*pim
, struct vty
*vty
,
2567 struct pim_interface
*pim_ifp
;
2568 struct pim_ifchannel
*ch
;
2569 struct interface
*ifp
;
2571 json_object
*json
= NULL
;
2574 json
= json_object_new_object();
2577 "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD\n");
2579 /* scan per-interface (S,G) state */
2580 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2581 pim_ifp
= ifp
->info
;
2586 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
2587 /* scan all interfaces */
2588 pim_show_join_desired_helper(pim
, vty
, pim_ifp
, ch
,
2594 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2595 json
, JSON_C_TO_STRING_PRETTY
));
2596 json_object_free(json
);
2600 static void pim_show_upstream_rpf(struct pim_instance
*pim
, struct vty
*vty
,
2603 struct listnode
*upnode
;
2604 struct pim_upstream
*up
;
2605 json_object
*json
= NULL
;
2606 json_object
*json_group
= NULL
;
2607 json_object
*json_row
= NULL
;
2610 json
= json_object_new_object();
2613 "Source Group RpfIface RibNextHop RpfAddress \n");
2615 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
, up
)) {
2616 char src_str
[INET_ADDRSTRLEN
];
2617 char grp_str
[INET_ADDRSTRLEN
];
2618 char rpf_nexthop_str
[PREFIX_STRLEN
];
2619 char rpf_addr_str
[PREFIX_STRLEN
];
2620 struct pim_rpf
*rpf
;
2621 const char *rpf_ifname
;
2625 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2626 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2627 pim_addr_dump("<nexthop?>",
2628 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2629 rpf_nexthop_str
, sizeof(rpf_nexthop_str
));
2630 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2631 sizeof(rpf_addr_str
));
2633 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2636 json_object_object_get_ex(json
, grp_str
, &json_group
);
2639 json_group
= json_object_new_object();
2640 json_object_object_add(json
, grp_str
,
2644 json_row
= json_object_new_object();
2645 json_object_pim_upstream_add(json_row
, up
);
2646 json_object_string_add(json_row
, "source", src_str
);
2647 json_object_string_add(json_row
, "group", grp_str
);
2648 json_object_string_add(json_row
, "rpfInterface",
2650 json_object_string_add(json_row
, "ribNexthop",
2652 json_object_string_add(json_row
, "rpfAddress",
2654 json_object_object_add(json_group
, src_str
, json_row
);
2656 vty_out(vty
, "%-15s %-15s %-16s %-15s %-15s\n", src_str
,
2657 grp_str
, rpf_ifname
, rpf_nexthop_str
,
2663 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2664 json
, JSON_C_TO_STRING_PRETTY
));
2665 json_object_free(json
);
2669 static void show_rpf_refresh_stats(struct vty
*vty
, struct pim_instance
*pim
,
2670 time_t now
, json_object
*json
)
2672 char refresh_uptime
[10];
2674 pim_time_uptime_begin(refresh_uptime
, sizeof(refresh_uptime
), now
,
2675 pim
->rpf_cache_refresh_last
);
2678 json_object_int_add(json
, "rpfCacheRefreshDelayMsecs",
2679 router
->rpf_cache_refresh_delay_msec
);
2680 json_object_int_add(
2681 json
, "rpfCacheRefreshTimer",
2682 pim_time_timer_remain_msec(pim
->rpf_cache_refresher
));
2683 json_object_int_add(json
, "rpfCacheRefreshRequests",
2684 pim
->rpf_cache_refresh_requests
);
2685 json_object_int_add(json
, "rpfCacheRefreshEvents",
2686 pim
->rpf_cache_refresh_events
);
2687 json_object_string_add(json
, "rpfCacheRefreshLast",
2689 json_object_int_add(json
, "nexthopLookups",
2690 pim
->nexthop_lookups
);
2691 json_object_int_add(json
, "nexthopLookupsAvoided",
2692 pim
->nexthop_lookups_avoided
);
2695 "RPF Cache Refresh Delay: %ld msecs\n"
2696 "RPF Cache Refresh Timer: %ld msecs\n"
2697 "RPF Cache Refresh Requests: %lld\n"
2698 "RPF Cache Refresh Events: %lld\n"
2699 "RPF Cache Refresh Last: %s\n"
2700 "Nexthop Lookups: %lld\n"
2701 "Nexthop Lookups Avoided: %lld\n",
2702 router
->rpf_cache_refresh_delay_msec
,
2703 pim_time_timer_remain_msec(pim
->rpf_cache_refresher
),
2704 (long long)pim
->rpf_cache_refresh_requests
,
2705 (long long)pim
->rpf_cache_refresh_events
,
2706 refresh_uptime
, (long long)pim
->nexthop_lookups
,
2707 (long long)pim
->nexthop_lookups_avoided
);
2711 static void show_scan_oil_stats(struct pim_instance
*pim
, struct vty
*vty
,
2714 char uptime_scan_oil
[10];
2715 char uptime_mroute_add
[10];
2716 char uptime_mroute_del
[10];
2718 pim_time_uptime_begin(uptime_scan_oil
, sizeof(uptime_scan_oil
), now
,
2719 pim
->scan_oil_last
);
2720 pim_time_uptime_begin(uptime_mroute_add
, sizeof(uptime_mroute_add
), now
,
2721 pim
->mroute_add_last
);
2722 pim_time_uptime_begin(uptime_mroute_del
, sizeof(uptime_mroute_del
), now
,
2723 pim
->mroute_del_last
);
2726 "Scan OIL - Last: %s Events: %lld\n"
2727 "MFC Add - Last: %s Events: %lld\n"
2728 "MFC Del - Last: %s Events: %lld\n",
2729 uptime_scan_oil
, (long long)pim
->scan_oil_events
,
2730 uptime_mroute_add
, (long long)pim
->mroute_add_events
,
2731 uptime_mroute_del
, (long long)pim
->mroute_del_events
);
2734 static void pim_show_rpf(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
2736 struct listnode
*up_node
;
2737 struct pim_upstream
*up
;
2738 time_t now
= pim_time_monotonic_sec();
2739 json_object
*json
= NULL
;
2740 json_object
*json_group
= NULL
;
2741 json_object
*json_row
= NULL
;
2744 json
= json_object_new_object();
2745 show_rpf_refresh_stats(vty
, pim
, now
, json
);
2747 show_rpf_refresh_stats(vty
, pim
, now
, json
);
2750 "Source Group RpfIface RpfAddress RibNextHop Metric Pref\n");
2753 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, up_node
, up
)) {
2754 char src_str
[INET_ADDRSTRLEN
];
2755 char grp_str
[INET_ADDRSTRLEN
];
2756 char rpf_addr_str
[PREFIX_STRLEN
];
2757 char rib_nexthop_str
[PREFIX_STRLEN
];
2758 const char *rpf_ifname
;
2759 struct pim_rpf
*rpf
= &up
->rpf
;
2761 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2762 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2763 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2764 sizeof(rpf_addr_str
));
2765 pim_addr_dump("<nexthop?>",
2766 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2767 rib_nexthop_str
, sizeof(rib_nexthop_str
));
2769 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2772 json_object_object_get_ex(json
, grp_str
, &json_group
);
2775 json_group
= json_object_new_object();
2776 json_object_object_add(json
, grp_str
,
2780 json_row
= json_object_new_object();
2781 json_object_string_add(json_row
, "source", src_str
);
2782 json_object_string_add(json_row
, "group", grp_str
);
2783 json_object_string_add(json_row
, "rpfInterface",
2785 json_object_string_add(json_row
, "rpfAddress",
2787 json_object_string_add(json_row
, "ribNexthop",
2789 json_object_int_add(
2790 json_row
, "routeMetric",
2791 rpf
->source_nexthop
.mrib_route_metric
);
2792 json_object_int_add(
2793 json_row
, "routePreference",
2794 rpf
->source_nexthop
.mrib_metric_preference
);
2795 json_object_object_add(json_group
, src_str
, json_row
);
2798 vty_out(vty
, "%-15s %-15s %-16s %-15s %-15s %6d %4d\n",
2799 src_str
, grp_str
, rpf_ifname
, rpf_addr_str
,
2801 rpf
->source_nexthop
.mrib_route_metric
,
2802 rpf
->source_nexthop
.mrib_metric_preference
);
2807 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2808 json
, JSON_C_TO_STRING_PRETTY
));
2809 json_object_free(json
);
2813 struct pnc_cache_walk_data
{
2815 struct pim_instance
*pim
;
2818 static int pim_print_pnc_cache_walkcb(struct hash_bucket
*bucket
, void *arg
)
2820 struct pim_nexthop_cache
*pnc
= bucket
->data
;
2821 struct pnc_cache_walk_data
*cwd
= arg
;
2822 struct vty
*vty
= cwd
->vty
;
2823 struct pim_instance
*pim
= cwd
->pim
;
2824 struct nexthop
*nh_node
= NULL
;
2825 ifindex_t first_ifindex
;
2826 struct interface
*ifp
= NULL
;
2828 for (nh_node
= pnc
->nexthop
; nh_node
; nh_node
= nh_node
->next
) {
2829 first_ifindex
= nh_node
->ifindex
;
2830 ifp
= if_lookup_by_index(first_ifindex
, pim
->vrf_id
);
2832 vty_out(vty
, "%-15s ", inet_ntoa(pnc
->rpf
.rpf_addr
.u
.prefix4
));
2833 vty_out(vty
, "%-16s ", ifp
? ifp
->name
: "NULL");
2834 vty_out(vty
, "%s ", inet_ntoa(nh_node
->gate
.ipv4
));
2840 static void pim_show_nexthop(struct pim_instance
*pim
, struct vty
*vty
)
2842 struct pnc_cache_walk_data cwd
;
2846 vty_out(vty
, "Number of registered addresses: %lu\n",
2847 pim
->rpf_hash
->count
);
2848 vty_out(vty
, "Address Interface Nexthop\n");
2849 vty_out(vty
, "---------------------------------------------\n");
2851 hash_walk(pim
->rpf_hash
, pim_print_pnc_cache_walkcb
, &cwd
);
2854 static void igmp_show_groups(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
2856 struct interface
*ifp
;
2858 json_object
*json
= NULL
;
2859 json_object
*json_iface
= NULL
;
2860 json_object
*json_row
= NULL
;
2862 now
= pim_time_monotonic_sec();
2865 json
= json_object_new_object();
2868 "Interface Address Group Mode Timer Srcs V Uptime \n");
2870 /* scan interfaces */
2871 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2872 struct pim_interface
*pim_ifp
= ifp
->info
;
2873 struct listnode
*sock_node
;
2874 struct igmp_sock
*igmp
;
2879 /* scan igmp sockets */
2880 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
2882 char ifaddr_str
[INET_ADDRSTRLEN
];
2883 struct listnode
*grpnode
;
2884 struct igmp_group
*grp
;
2886 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
2887 sizeof(ifaddr_str
));
2889 /* scan igmp groups */
2890 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
2892 char group_str
[INET_ADDRSTRLEN
];
2896 pim_inet4_dump("<group?>", grp
->group_addr
,
2897 group_str
, sizeof(group_str
));
2898 pim_time_timer_to_hhmmss(hhmmss
, sizeof(hhmmss
),
2899 grp
->t_group_timer
);
2900 pim_time_uptime(uptime
, sizeof(uptime
),
2901 now
- grp
->group_creation
);
2904 json_object_object_get_ex(
2905 json
, ifp
->name
, &json_iface
);
2909 json_object_new_object();
2910 json_object_pim_ifp_add(
2912 json_object_object_add(
2917 json_row
= json_object_new_object();
2918 json_object_string_add(
2919 json_row
, "source", ifaddr_str
);
2920 json_object_string_add(
2921 json_row
, "group", group_str
);
2923 if (grp
->igmp_version
== 3)
2924 json_object_string_add(
2926 grp
->group_filtermode_isexcl
2930 json_object_string_add(json_row
,
2932 json_object_int_add(
2933 json_row
, "sourcesCount",
2934 grp
->group_source_list
2936 grp
->group_source_list
)
2938 json_object_int_add(json_row
, "version",
2940 json_object_string_add(
2941 json_row
, "uptime", uptime
);
2942 json_object_object_add(json_iface
,
2948 "%-16s %-15s %-15s %4s %8s %4d %d %8s\n",
2949 ifp
->name
, ifaddr_str
,
2951 grp
->igmp_version
== 3
2952 ? (grp
->group_filtermode_isexcl
2957 grp
->group_source_list
2959 grp
->group_source_list
)
2961 grp
->igmp_version
, uptime
);
2963 } /* scan igmp groups */
2964 } /* scan igmp sockets */
2965 } /* scan interfaces */
2968 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2969 json
, JSON_C_TO_STRING_PRETTY
));
2970 json_object_free(json
);
2974 static void igmp_show_group_retransmission(struct pim_instance
*pim
,
2977 struct interface
*ifp
;
2980 "Interface Address Group RetTimer Counter RetSrcs\n");
2982 /* scan interfaces */
2983 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2984 struct pim_interface
*pim_ifp
= ifp
->info
;
2985 struct listnode
*sock_node
;
2986 struct igmp_sock
*igmp
;
2991 /* scan igmp sockets */
2992 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
2994 char ifaddr_str
[INET_ADDRSTRLEN
];
2995 struct listnode
*grpnode
;
2996 struct igmp_group
*grp
;
2998 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
2999 sizeof(ifaddr_str
));
3001 /* scan igmp groups */
3002 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3004 char group_str
[INET_ADDRSTRLEN
];
3005 char grp_retr_mmss
[10];
3006 struct listnode
*src_node
;
3007 struct igmp_source
*src
;
3008 int grp_retr_sources
= 0;
3010 pim_inet4_dump("<group?>", grp
->group_addr
,
3011 group_str
, sizeof(group_str
));
3012 pim_time_timer_to_mmss(
3013 grp_retr_mmss
, sizeof(grp_retr_mmss
),
3014 grp
->t_group_query_retransmit_timer
);
3017 /* count group sources with retransmission state
3019 for (ALL_LIST_ELEMENTS_RO(
3020 grp
->group_source_list
, src_node
,
3022 if (src
->source_query_retransmit_count
3028 vty_out(vty
, "%-16s %-15s %-15s %-8s %7d %7d\n",
3029 ifp
->name
, ifaddr_str
, group_str
,
3031 grp
->group_specific_query_retransmit_count
,
3034 } /* scan igmp groups */
3035 } /* scan igmp sockets */
3036 } /* scan interfaces */
3039 static void igmp_show_sources(struct pim_instance
*pim
, struct vty
*vty
)
3041 struct interface
*ifp
;
3044 now
= pim_time_monotonic_sec();
3047 "Interface Address Group Source Timer Fwd Uptime \n");
3049 /* scan interfaces */
3050 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3051 struct pim_interface
*pim_ifp
= ifp
->info
;
3052 struct listnode
*sock_node
;
3053 struct igmp_sock
*igmp
;
3058 /* scan igmp sockets */
3059 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3061 char ifaddr_str
[INET_ADDRSTRLEN
];
3062 struct listnode
*grpnode
;
3063 struct igmp_group
*grp
;
3065 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3066 sizeof(ifaddr_str
));
3068 /* scan igmp groups */
3069 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3071 char group_str
[INET_ADDRSTRLEN
];
3072 struct listnode
*srcnode
;
3073 struct igmp_source
*src
;
3075 pim_inet4_dump("<group?>", grp
->group_addr
,
3076 group_str
, sizeof(group_str
));
3078 /* scan group sources */
3079 for (ALL_LIST_ELEMENTS_RO(
3080 grp
->group_source_list
, srcnode
,
3082 char source_str
[INET_ADDRSTRLEN
];
3087 "<source?>", src
->source_addr
,
3088 source_str
, sizeof(source_str
));
3090 pim_time_timer_to_mmss(
3092 src
->t_source_timer
);
3095 uptime
, sizeof(uptime
),
3096 now
- src
->source_creation
);
3099 "%-16s %-15s %-15s %-15s %5s %3s %8s\n",
3100 ifp
->name
, ifaddr_str
,
3101 group_str
, source_str
, mmss
,
3102 IGMP_SOURCE_TEST_FORWARDING(
3108 } /* scan group sources */
3109 } /* scan igmp groups */
3110 } /* scan igmp sockets */
3111 } /* scan interfaces */
3114 static void igmp_show_source_retransmission(struct pim_instance
*pim
,
3117 struct interface
*ifp
;
3120 "Interface Address Group Source Counter\n");
3122 /* scan interfaces */
3123 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3124 struct pim_interface
*pim_ifp
= ifp
->info
;
3125 struct listnode
*sock_node
;
3126 struct igmp_sock
*igmp
;
3131 /* scan igmp sockets */
3132 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3134 char ifaddr_str
[INET_ADDRSTRLEN
];
3135 struct listnode
*grpnode
;
3136 struct igmp_group
*grp
;
3138 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3139 sizeof(ifaddr_str
));
3141 /* scan igmp groups */
3142 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3144 char group_str
[INET_ADDRSTRLEN
];
3145 struct listnode
*srcnode
;
3146 struct igmp_source
*src
;
3148 pim_inet4_dump("<group?>", grp
->group_addr
,
3149 group_str
, sizeof(group_str
));
3151 /* scan group sources */
3152 for (ALL_LIST_ELEMENTS_RO(
3153 grp
->group_source_list
, srcnode
,
3155 char source_str
[INET_ADDRSTRLEN
];
3158 "<source?>", src
->source_addr
,
3159 source_str
, sizeof(source_str
));
3162 "%-16s %-15s %-15s %-15s %7d\n",
3163 ifp
->name
, ifaddr_str
,
3164 group_str
, source_str
,
3165 src
->source_query_retransmit_count
);
3167 } /* scan group sources */
3168 } /* scan igmp groups */
3169 } /* scan igmp sockets */
3170 } /* scan interfaces */
3173 static void clear_igmp_interfaces(struct pim_instance
*pim
)
3175 struct interface
*ifp
;
3177 FOR_ALL_INTERFACES (pim
->vrf
, ifp
)
3178 pim_if_addr_del_all_igmp(ifp
);
3180 FOR_ALL_INTERFACES (pim
->vrf
, ifp
)
3181 pim_if_addr_add_all(ifp
);
3184 static void clear_pim_interfaces(struct pim_instance
*pim
)
3186 struct interface
*ifp
;
3188 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3190 pim_neighbor_delete_all(ifp
, "interface cleared");
3195 static void clear_interfaces(struct pim_instance
*pim
)
3197 clear_igmp_interfaces(pim
);
3198 clear_pim_interfaces(pim
);
3201 #define PIM_GET_PIM_INTERFACE(pim_ifp, ifp) \
3202 pim_ifp = ifp->info; \
3205 "%% Enable PIM and/or IGMP on this interface first\n"); \
3206 return CMD_WARNING_CONFIG_FAILED; \
3209 DEFUN (clear_ip_interfaces
,
3210 clear_ip_interfaces_cmd
,
3211 "clear ip interfaces [vrf NAME]",
3214 "Reset interfaces\n"
3218 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3223 clear_interfaces(vrf
->info
);
3228 DEFUN (clear_ip_igmp_interfaces
,
3229 clear_ip_igmp_interfaces_cmd
,
3230 "clear ip igmp [vrf NAME] interfaces",
3235 "Reset IGMP interfaces\n")
3238 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3243 clear_igmp_interfaces(vrf
->info
);
3248 static void mroute_add_all(struct pim_instance
*pim
)
3250 struct listnode
*node
;
3251 struct channel_oil
*c_oil
;
3253 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
3254 if (pim_mroute_add(c_oil
, __PRETTY_FUNCTION__
)) {
3255 /* just log warning */
3256 char source_str
[INET_ADDRSTRLEN
];
3257 char group_str
[INET_ADDRSTRLEN
];
3258 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
,
3259 source_str
, sizeof(source_str
));
3260 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
,
3261 group_str
, sizeof(group_str
));
3262 zlog_warn("%s %s: (S,G)=(%s,%s) failure writing MFC",
3263 __FILE__
, __PRETTY_FUNCTION__
, source_str
,
3269 static void mroute_del_all(struct pim_instance
*pim
)
3271 struct listnode
*node
;
3272 struct channel_oil
*c_oil
;
3274 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
3275 if (pim_mroute_del(c_oil
, __PRETTY_FUNCTION__
)) {
3276 /* just log warning */
3277 char source_str
[INET_ADDRSTRLEN
];
3278 char group_str
[INET_ADDRSTRLEN
];
3279 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
,
3280 source_str
, sizeof(source_str
));
3281 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
,
3282 group_str
, sizeof(group_str
));
3283 zlog_warn("%s %s: (S,G)=(%s,%s) failure clearing MFC",
3284 __FILE__
, __PRETTY_FUNCTION__
, source_str
,
3290 DEFUN (clear_ip_mroute
,
3291 clear_ip_mroute_cmd
,
3292 "clear ip mroute [vrf NAME]",
3295 "Reset multicast routes\n"
3299 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3304 mroute_del_all(vrf
->info
);
3305 mroute_add_all(vrf
->info
);
3310 DEFUN (clear_ip_pim_interfaces
,
3311 clear_ip_pim_interfaces_cmd
,
3312 "clear ip pim [vrf NAME] interfaces",
3317 "Reset PIM interfaces\n")
3320 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3325 clear_pim_interfaces(vrf
->info
);
3330 DEFUN (clear_ip_pim_interface_traffic
,
3331 clear_ip_pim_interface_traffic_cmd
,
3332 "clear ip pim [vrf NAME] interface traffic",
3335 "PIM clear commands\n"
3337 "Reset PIM interfaces\n"
3338 "Reset Protocol Packet counters\n")
3341 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3342 struct interface
*ifp
= NULL
;
3343 struct pim_interface
*pim_ifp
= NULL
;
3348 FOR_ALL_INTERFACES (vrf
, ifp
) {
3349 pim_ifp
= ifp
->info
;
3354 pim_ifp
->pim_ifstat_hello_recv
= 0;
3355 pim_ifp
->pim_ifstat_hello_sent
= 0;
3356 pim_ifp
->pim_ifstat_join_recv
= 0;
3357 pim_ifp
->pim_ifstat_join_send
= 0;
3358 pim_ifp
->pim_ifstat_prune_recv
= 0;
3359 pim_ifp
->pim_ifstat_prune_send
= 0;
3360 pim_ifp
->pim_ifstat_reg_recv
= 0;
3361 pim_ifp
->pim_ifstat_reg_send
= 0;
3362 pim_ifp
->pim_ifstat_reg_stop_recv
= 0;
3363 pim_ifp
->pim_ifstat_reg_stop_send
= 0;
3364 pim_ifp
->pim_ifstat_assert_recv
= 0;
3365 pim_ifp
->pim_ifstat_assert_send
= 0;
3371 DEFUN (clear_ip_pim_oil
,
3372 clear_ip_pim_oil_cmd
,
3373 "clear ip pim [vrf NAME] oil",
3378 "Rescan PIM OIL (output interface list)\n")
3381 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3386 pim_scan_oil(vrf
->info
);
3391 DEFUN (show_ip_igmp_interface
,
3392 show_ip_igmp_interface_cmd
,
3393 "show ip igmp [vrf NAME] interface [detail|WORD] [json]",
3398 "IGMP interface information\n"
3404 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3405 bool uj
= use_json(argc
, argv
);
3410 if (argv_find(argv
, argc
, "detail", &idx
)
3411 || argv_find(argv
, argc
, "WORD", &idx
))
3412 igmp_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
3414 igmp_show_interfaces(vrf
->info
, vty
, uj
);
3419 DEFUN (show_ip_igmp_interface_vrf_all
,
3420 show_ip_igmp_interface_vrf_all_cmd
,
3421 "show ip igmp vrf all interface [detail|WORD] [json]",
3426 "IGMP interface information\n"
3432 bool uj
= use_json(argc
, argv
);
3438 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3442 vty_out(vty
, " \"%s\": ", vrf
->name
);
3445 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3446 if (argv_find(argv
, argc
, "detail", &idx
)
3447 || argv_find(argv
, argc
, "WORD", &idx
))
3448 igmp_show_interfaces_single(vrf
->info
, vty
,
3449 argv
[idx
]->arg
, uj
);
3451 igmp_show_interfaces(vrf
->info
, vty
, uj
);
3454 vty_out(vty
, "}\n");
3459 DEFUN (show_ip_igmp_join
,
3460 show_ip_igmp_join_cmd
,
3461 "show ip igmp [vrf NAME] join",
3466 "IGMP static join information\n")
3469 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3474 igmp_show_interface_join(vrf
->info
, vty
);
3479 DEFUN (show_ip_igmp_join_vrf_all
,
3480 show_ip_igmp_join_vrf_all_cmd
,
3481 "show ip igmp vrf all join",
3486 "IGMP static join information\n")
3488 bool uj
= use_json(argc
, argv
);
3494 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3498 vty_out(vty
, " \"%s\": ", vrf
->name
);
3501 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3502 igmp_show_interface_join(vrf
->info
, vty
);
3505 vty_out(vty
, "}\n");
3510 DEFUN (show_ip_igmp_groups
,
3511 show_ip_igmp_groups_cmd
,
3512 "show ip igmp [vrf NAME] groups [json]",
3521 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3522 bool uj
= use_json(argc
, argv
);
3527 igmp_show_groups(vrf
->info
, vty
, uj
);
3532 DEFUN (show_ip_igmp_groups_vrf_all
,
3533 show_ip_igmp_groups_vrf_all_cmd
,
3534 "show ip igmp vrf all groups [json]",
3542 bool uj
= use_json(argc
, argv
);
3548 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3552 vty_out(vty
, " \"%s\": ", vrf
->name
);
3555 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3556 igmp_show_groups(vrf
->info
, vty
, uj
);
3559 vty_out(vty
, "}\n");
3564 DEFUN (show_ip_igmp_groups_retransmissions
,
3565 show_ip_igmp_groups_retransmissions_cmd
,
3566 "show ip igmp [vrf NAME] groups retransmissions",
3572 "IGMP group retransmissions\n")
3575 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3580 igmp_show_group_retransmission(vrf
->info
, vty
);
3585 DEFUN (show_ip_igmp_sources
,
3586 show_ip_igmp_sources_cmd
,
3587 "show ip igmp [vrf NAME] sources",
3595 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3600 igmp_show_sources(vrf
->info
, vty
);
3605 DEFUN (show_ip_igmp_sources_retransmissions
,
3606 show_ip_igmp_sources_retransmissions_cmd
,
3607 "show ip igmp [vrf NAME] sources retransmissions",
3613 "IGMP source retransmissions\n")
3616 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3621 igmp_show_source_retransmission(vrf
->info
, vty
);
3626 DEFUN (show_ip_igmp_statistics
,
3627 show_ip_igmp_statistics_cmd
,
3628 "show ip igmp [vrf NAME] statistics [interface WORD] [json]",
3639 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3640 bool uj
= use_json(argc
, argv
);
3645 if (argv_find(argv
, argc
, "WORD", &idx
))
3646 igmp_show_statistics(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
3648 igmp_show_statistics(vrf
->info
, vty
, NULL
, uj
);
3653 DEFUN (show_ip_pim_assert
,
3654 show_ip_pim_assert_cmd
,
3655 "show ip pim [vrf NAME] assert",
3660 "PIM interface assert\n")
3663 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3668 pim_show_assert(vrf
->info
, vty
);
3673 DEFUN (show_ip_pim_assert_internal
,
3674 show_ip_pim_assert_internal_cmd
,
3675 "show ip pim [vrf NAME] assert-internal",
3680 "PIM interface internal assert state\n")
3683 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3688 pim_show_assert_internal(vrf
->info
, vty
);
3693 DEFUN (show_ip_pim_assert_metric
,
3694 show_ip_pim_assert_metric_cmd
,
3695 "show ip pim [vrf NAME] assert-metric",
3700 "PIM interface assert metric\n")
3703 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3708 pim_show_assert_metric(vrf
->info
, vty
);
3713 DEFUN (show_ip_pim_assert_winner_metric
,
3714 show_ip_pim_assert_winner_metric_cmd
,
3715 "show ip pim [vrf NAME] assert-winner-metric",
3720 "PIM interface assert winner metric\n")
3723 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3728 pim_show_assert_winner_metric(vrf
->info
, vty
);
3733 DEFUN (show_ip_pim_interface
,
3734 show_ip_pim_interface_cmd
,
3735 "show ip pim [vrf NAME] interface [detail|WORD] [json]",
3740 "PIM interface information\n"
3746 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3747 bool uj
= use_json(argc
, argv
);
3752 if (argv_find(argv
, argc
, "WORD", &idx
)
3753 || argv_find(argv
, argc
, "detail", &idx
))
3754 pim_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
3756 pim_show_interfaces(vrf
->info
, vty
, uj
);
3761 DEFUN (show_ip_pim_interface_vrf_all
,
3762 show_ip_pim_interface_vrf_all_cmd
,
3763 "show ip pim vrf all interface [detail|WORD] [json]",
3768 "PIM interface information\n"
3774 bool uj
= use_json(argc
, argv
);
3780 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3784 vty_out(vty
, " \"%s\": ", vrf
->name
);
3787 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3788 if (argv_find(argv
, argc
, "WORD", &idx
)
3789 || argv_find(argv
, argc
, "detail", &idx
))
3790 pim_show_interfaces_single(vrf
->info
, vty
,
3791 argv
[idx
]->arg
, uj
);
3793 pim_show_interfaces(vrf
->info
, vty
, uj
);
3796 vty_out(vty
, "}\n");
3801 DEFPY (show_ip_pim_join
,
3802 show_ip_pim_join_cmd
,
3803 "show ip pim [vrf NAME] join [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
3808 "PIM interface join information\n"
3809 "The Source or Group\n"
3813 struct prefix_sg sg
= {0};
3816 struct pim_instance
*pim
;
3818 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
3821 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
3824 pim
= pim_get_pim_instance(v
->vrf_id
);
3827 vty_out(vty
, "%% Unable to find pim instance\n");
3831 if (s_or_g
.s_addr
!= 0) {
3832 if (g
.s_addr
!= 0) {
3839 pim_show_join(pim
, vty
, &sg
, uj
);
3844 DEFUN (show_ip_pim_join_vrf_all
,
3845 show_ip_pim_join_vrf_all_cmd
,
3846 "show ip pim vrf all join [json]",
3851 "PIM interface join information\n"
3854 struct prefix_sg sg
= {0};
3855 bool uj
= use_json(argc
, argv
);
3861 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3865 vty_out(vty
, " \"%s\": ", vrf
->name
);
3868 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3869 pim_show_join(vrf
->info
, vty
, &sg
, uj
);
3872 vty_out(vty
, "}\n");
3877 DEFUN (show_ip_pim_local_membership
,
3878 show_ip_pim_local_membership_cmd
,
3879 "show ip pim [vrf NAME] local-membership [json]",
3884 "PIM interface local-membership\n"
3888 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3889 bool uj
= use_json(argc
, argv
);
3894 pim_show_membership(vrf
->info
, vty
, uj
);
3899 DEFUN (show_ip_pim_neighbor
,
3900 show_ip_pim_neighbor_cmd
,
3901 "show ip pim [vrf NAME] neighbor [detail|WORD] [json]",
3906 "PIM neighbor information\n"
3908 "Name of interface or neighbor\n"
3912 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3913 bool uj
= use_json(argc
, argv
);
3918 if (argv_find(argv
, argc
, "detail", &idx
)
3919 || argv_find(argv
, argc
, "WORD", &idx
))
3920 pim_show_neighbors_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
3922 pim_show_neighbors(vrf
->info
, vty
, uj
);
3927 DEFUN (show_ip_pim_neighbor_vrf_all
,
3928 show_ip_pim_neighbor_vrf_all_cmd
,
3929 "show ip pim vrf all neighbor [detail|WORD] [json]",
3934 "PIM neighbor information\n"
3936 "Name of interface or neighbor\n"
3940 bool uj
= use_json(argc
, argv
);
3946 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3950 vty_out(vty
, " \"%s\": ", vrf
->name
);
3953 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3954 if (argv_find(argv
, argc
, "detail", &idx
)
3955 || argv_find(argv
, argc
, "WORD", &idx
))
3956 pim_show_neighbors_single(vrf
->info
, vty
,
3957 argv
[idx
]->arg
, uj
);
3959 pim_show_neighbors(vrf
->info
, vty
, uj
);
3962 vty_out(vty
, "}\n");
3967 DEFUN (show_ip_pim_secondary
,
3968 show_ip_pim_secondary_cmd
,
3969 "show ip pim [vrf NAME] secondary",
3974 "PIM neighbor addresses\n")
3977 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3982 pim_show_neighbors_secondary(vrf
->info
, vty
);
3987 DEFUN (show_ip_pim_state
,
3988 show_ip_pim_state_cmd
,
3989 "show ip pim [vrf NAME] state [A.B.C.D [A.B.C.D]] [json]",
3994 "PIM state information\n"
3995 "Unicast or Multicast address\n"
3996 "Multicast address\n"
3999 const char *src_or_group
= NULL
;
4000 const char *group
= NULL
;
4002 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4003 bool uj
= use_json(argc
, argv
);
4011 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
4012 src_or_group
= argv
[idx
]->arg
;
4014 group
= argv
[idx
+ 1]->arg
;
4017 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
4022 DEFUN (show_ip_pim_state_vrf_all
,
4023 show_ip_pim_state_vrf_all_cmd
,
4024 "show ip pim vrf all state [A.B.C.D [A.B.C.D]] [json]",
4029 "PIM state information\n"
4030 "Unicast or Multicast address\n"
4031 "Multicast address\n"
4034 const char *src_or_group
= NULL
;
4035 const char *group
= NULL
;
4037 bool uj
= use_json(argc
, argv
);
4046 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
4047 src_or_group
= argv
[idx
]->arg
;
4049 group
= argv
[idx
+ 1]->arg
;
4052 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4056 vty_out(vty
, " \"%s\": ", vrf
->name
);
4059 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4060 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
4063 vty_out(vty
, "}\n");
4068 DEFPY (show_ip_pim_upstream
,
4069 show_ip_pim_upstream_cmd
,
4070 "show ip pim [vrf NAME] upstream [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
4075 "PIM upstream information\n"
4076 "The Source or Group\n"
4080 struct prefix_sg sg
= {0};
4083 struct pim_instance
*pim
;
4085 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
4088 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
4091 pim
= pim_get_pim_instance(v
->vrf_id
);
4094 vty_out(vty
, "%% Unable to find pim instance\n");
4098 if (s_or_g
.s_addr
!= 0) {
4099 if (g
.s_addr
!= 0) {
4105 pim_show_upstream(pim
, vty
, &sg
, uj
);
4110 DEFUN (show_ip_pim_upstream_vrf_all
,
4111 show_ip_pim_upstream_vrf_all_cmd
,
4112 "show ip pim vrf all upstream [json]",
4117 "PIM upstream information\n"
4120 struct prefix_sg sg
= {0};
4121 bool uj
= use_json(argc
, argv
);
4127 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4131 vty_out(vty
, " \"%s\": ", vrf
->name
);
4134 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4135 pim_show_upstream(vrf
->info
, vty
, &sg
, uj
);
4141 DEFUN (show_ip_pim_upstream_join_desired
,
4142 show_ip_pim_upstream_join_desired_cmd
,
4143 "show ip pim [vrf NAME] upstream-join-desired [json]",
4148 "PIM upstream join-desired\n"
4152 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4153 bool uj
= use_json(argc
, argv
);
4158 pim_show_join_desired(vrf
->info
, vty
, uj
);
4163 DEFUN (show_ip_pim_upstream_rpf
,
4164 show_ip_pim_upstream_rpf_cmd
,
4165 "show ip pim [vrf NAME] upstream-rpf [json]",
4170 "PIM upstream source rpf\n"
4174 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4175 bool uj
= use_json(argc
, argv
);
4180 pim_show_upstream_rpf(vrf
->info
, vty
, uj
);
4185 DEFUN (show_ip_pim_rp
,
4187 "show ip pim [vrf NAME] rp-info [json]",
4192 "PIM RP information\n"
4196 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4197 bool uj
= use_json(argc
, argv
);
4202 pim_rp_show_information(vrf
->info
, vty
, uj
);
4207 DEFUN (show_ip_pim_rp_vrf_all
,
4208 show_ip_pim_rp_vrf_all_cmd
,
4209 "show ip pim vrf all rp-info [json]",
4214 "PIM RP information\n"
4217 bool uj
= use_json(argc
, argv
);
4223 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4227 vty_out(vty
, " \"%s\": ", vrf
->name
);
4230 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4231 pim_rp_show_information(vrf
->info
, vty
, uj
);
4234 vty_out(vty
, "}\n");
4239 DEFUN (show_ip_pim_rpf
,
4240 show_ip_pim_rpf_cmd
,
4241 "show ip pim [vrf NAME] rpf [json]",
4246 "PIM cached source rpf information\n"
4250 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4251 bool uj
= use_json(argc
, argv
);
4256 pim_show_rpf(vrf
->info
, vty
, uj
);
4261 DEFUN (show_ip_pim_rpf_vrf_all
,
4262 show_ip_pim_rpf_vrf_all_cmd
,
4263 "show ip pim vrf all rpf [json]",
4268 "PIM cached source rpf information\n"
4271 bool uj
= use_json(argc
, argv
);
4277 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4281 vty_out(vty
, " \"%s\": ", vrf
->name
);
4284 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4285 pim_show_rpf(vrf
->info
, vty
, uj
);
4288 vty_out(vty
, "}\n");
4293 DEFUN (show_ip_pim_nexthop
,
4294 show_ip_pim_nexthop_cmd
,
4295 "show ip pim [vrf NAME] nexthop",
4300 "PIM cached nexthop rpf information\n")
4303 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4308 pim_show_nexthop(vrf
->info
, vty
);
4313 DEFUN (show_ip_pim_nexthop_lookup
,
4314 show_ip_pim_nexthop_lookup_cmd
,
4315 "show ip pim [vrf NAME] nexthop-lookup A.B.C.D A.B.C.D",
4320 "PIM cached nexthop rpf lookup\n"
4321 "Source/RP address\n"
4322 "Multicast Group address\n")
4324 struct prefix nht_p
;
4326 struct in_addr src_addr
, grp_addr
;
4327 struct in_addr vif_source
;
4328 const char *addr_str
, *addr_str1
;
4330 struct pim_nexthop nexthop
;
4331 char nexthop_addr_str
[PREFIX_STRLEN
];
4332 char grp_str
[PREFIX_STRLEN
];
4334 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4339 argv_find(argv
, argc
, "A.B.C.D", &idx
);
4340 addr_str
= argv
[idx
]->arg
;
4341 result
= inet_pton(AF_INET
, addr_str
, &src_addr
);
4343 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
4344 errno
, safe_strerror(errno
));
4348 if (pim_is_group_224_4(src_addr
)) {
4350 "Invalid argument. Expected Valid Source Address.\n");
4354 addr_str1
= argv
[idx
+ 1]->arg
;
4355 result
= inet_pton(AF_INET
, addr_str1
, &grp_addr
);
4357 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
4358 errno
, safe_strerror(errno
));
4362 if (!pim_is_group_224_4(grp_addr
)) {
4364 "Invalid argument. Expected Valid Multicast Group Address.\n");
4368 if (!pim_rp_set_upstream_addr(vrf
->info
, &vif_source
, src_addr
,
4372 nht_p
.family
= AF_INET
;
4373 nht_p
.prefixlen
= IPV4_MAX_BITLEN
;
4374 nht_p
.u
.prefix4
= vif_source
;
4375 grp
.family
= AF_INET
;
4376 grp
.prefixlen
= IPV4_MAX_BITLEN
;
4377 grp
.u
.prefix4
= grp_addr
;
4378 memset(&nexthop
, 0, sizeof(nexthop
));
4380 result
= pim_ecmp_nexthop_lookup(vrf
->info
, &nexthop
, &nht_p
, &grp
, 0);
4384 "Nexthop Lookup failed, no usable routes returned.\n");
4388 pim_addr_dump("<grp?>", &grp
, grp_str
, sizeof(grp_str
));
4389 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
4390 nexthop_addr_str
, sizeof(nexthop_addr_str
));
4391 vty_out(vty
, "Group %s --- Nexthop %s Interface %s \n", grp_str
,
4392 nexthop_addr_str
, nexthop
.interface
->name
);
4397 DEFUN (show_ip_pim_interface_traffic
,
4398 show_ip_pim_interface_traffic_cmd
,
4399 "show ip pim [vrf NAME] interface traffic [WORD] [json]",
4404 "PIM interface information\n"
4405 "Protocol Packet counters\n"
4410 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4411 bool uj
= use_json(argc
, argv
);
4416 if (argv_find(argv
, argc
, "WORD", &idx
))
4417 pim_show_interface_traffic_single(vrf
->info
, vty
,
4418 argv
[idx
]->arg
, uj
);
4420 pim_show_interface_traffic(vrf
->info
, vty
, uj
);
4425 static void show_multicast_interfaces(struct pim_instance
*pim
, struct vty
*vty
)
4427 struct interface
*ifp
;
4432 "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut\n");
4434 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
4435 struct pim_interface
*pim_ifp
;
4436 struct in_addr ifaddr
;
4437 struct sioc_vif_req vreq
;
4439 pim_ifp
= ifp
->info
;
4444 memset(&vreq
, 0, sizeof(vreq
));
4445 vreq
.vifi
= pim_ifp
->mroute_vif_index
;
4447 if (ioctl(pim
->mroute_socket
, SIOCGETVIFCNT
, &vreq
)) {
4449 "ioctl(SIOCGETVIFCNT=%lu) failure for interface %s vif_index=%d: errno=%d: %s",
4450 (unsigned long)SIOCGETVIFCNT
, ifp
->name
,
4451 pim_ifp
->mroute_vif_index
, errno
,
4452 safe_strerror(errno
));
4455 ifaddr
= pim_ifp
->primary_address
;
4457 vty_out(vty
, "%-16s %-15s %3d %3d %7lu %7lu %10lu %10lu\n",
4458 ifp
->name
, inet_ntoa(ifaddr
), ifp
->ifindex
,
4459 pim_ifp
->mroute_vif_index
, (unsigned long)vreq
.icount
,
4460 (unsigned long)vreq
.ocount
, (unsigned long)vreq
.ibytes
,
4461 (unsigned long)vreq
.obytes
);
4465 static void pim_cmd_show_ip_multicast_helper(struct pim_instance
*pim
,
4468 struct vrf
*vrf
= pim
->vrf
;
4469 time_t now
= pim_time_monotonic_sec();
4475 vty_out(vty
, "Router MLAG Role: %s\n",
4476 mlag_role2str(router
->role
, mlag_role
, sizeof(mlag_role
)));
4477 vty_out(vty
, "Mroute socket descriptor:");
4479 vty_out(vty
, " %d(%s)\n", pim
->mroute_socket
, vrf
->name
);
4481 pim_time_uptime(uptime
, sizeof(uptime
),
4482 now
- pim
->mroute_socket_creation
);
4483 vty_out(vty
, "Mroute socket uptime: %s\n", uptime
);
4487 pim_zebra_zclient_update(vty
);
4488 pim_zlookup_show_ip_multicast(vty
);
4491 vty_out(vty
, "Maximum highest VifIndex: %d\n", PIM_MAX_USABLE_VIFS
);
4494 vty_out(vty
, "Upstream Join Timer: %d secs\n", router
->t_periodic
);
4495 vty_out(vty
, "Join/Prune Holdtime: %d secs\n", PIM_JP_HOLDTIME
);
4496 vty_out(vty
, "PIM ECMP: %s\n", pim
->ecmp_enable
? "Enable" : "Disable");
4497 vty_out(vty
, "PIM ECMP Rebalance: %s\n",
4498 pim
->ecmp_rebalance_enable
? "Enable" : "Disable");
4502 show_rpf_refresh_stats(vty
, pim
, now
, NULL
);
4506 show_scan_oil_stats(pim
, vty
, now
);
4508 show_multicast_interfaces(pim
, vty
);
4511 DEFUN (show_ip_multicast
,
4512 show_ip_multicast_cmd
,
4513 "show ip multicast [vrf NAME]",
4517 "Multicast global information\n")
4520 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4525 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
4530 DEFUN (show_ip_multicast_vrf_all
,
4531 show_ip_multicast_vrf_all_cmd
,
4532 "show ip multicast vrf all",
4536 "Multicast global information\n")
4538 bool uj
= use_json(argc
, argv
);
4544 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4548 vty_out(vty
, " \"%s\": ", vrf
->name
);
4551 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4552 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
4555 vty_out(vty
, "}\n");
4560 static void show_mroute(struct pim_instance
*pim
, struct vty
*vty
, bool fill
,
4563 struct listnode
*node
;
4564 struct channel_oil
*c_oil
;
4565 struct static_route
*s_route
;
4567 json_object
*json
= NULL
;
4568 json_object
*json_group
= NULL
;
4569 json_object
*json_source
= NULL
;
4570 json_object
*json_oil
= NULL
;
4571 json_object
*json_ifp_out
= NULL
;
4574 char grp_str
[INET_ADDRSTRLEN
];
4575 char src_str
[INET_ADDRSTRLEN
];
4576 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
4577 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
4579 struct interface
*ifp_in
;
4583 json
= json_object_new_object();
4586 "Source Group Proto Input Output TTL Uptime\n");
4589 now
= pim_time_monotonic_sec();
4591 /* print list of PIM and IGMP routes */
4592 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
4595 if (!c_oil
->installed
&& !uj
)
4598 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
4600 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
4602 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
4605 strcpy(in_ifname
, ifp_in
->name
);
4607 strcpy(in_ifname
, "<iif?>");
4611 /* Find the group, create it if it doesn't exist */
4612 json_object_object_get_ex(json
, grp_str
, &json_group
);
4615 json_group
= json_object_new_object();
4616 json_object_object_add(json
, grp_str
,
4620 /* Find the source nested under the group, create it if
4621 * it doesn't exist */
4622 json_object_object_get_ex(json_group
, src_str
,
4626 json_source
= json_object_new_object();
4627 json_object_object_add(json_group
, src_str
,
4631 /* Find the inbound interface nested under the source,
4632 * create it if it doesn't exist */
4633 json_object_int_add(json_source
, "installed",
4635 json_object_int_add(json_source
, "refCount",
4636 c_oil
->oil_ref_count
);
4637 json_object_int_add(json_source
, "oilSize",
4639 json_object_int_add(json_source
, "OilInheritedRescan",
4640 c_oil
->oil_inherited_rescan
);
4641 json_object_string_add(json_source
, "iif", in_ifname
);
4645 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
4647 struct interface
*ifp_out
;
4648 char mroute_uptime
[10];
4651 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
4655 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
4657 mroute_uptime
, sizeof(mroute_uptime
),
4658 now
- c_oil
->mroute_creation
);
4662 strcpy(out_ifname
, ifp_out
->name
);
4664 strcpy(out_ifname
, "<oif?>");
4667 json_ifp_out
= json_object_new_object();
4668 json_object_string_add(json_ifp_out
, "source",
4670 json_object_string_add(json_ifp_out
, "group",
4673 if (c_oil
->oif_flags
[oif_vif_index
]
4674 & PIM_OIF_FLAG_PROTO_PIM
)
4675 json_object_boolean_true_add(
4676 json_ifp_out
, "protocolPim");
4678 if (c_oil
->oif_flags
[oif_vif_index
]
4679 & PIM_OIF_FLAG_PROTO_IGMP
)
4680 json_object_boolean_true_add(
4681 json_ifp_out
, "protocolIgmp");
4683 if (c_oil
->oif_flags
[oif_vif_index
]
4684 & PIM_OIF_FLAG_PROTO_VXLAN
)
4685 json_object_boolean_true_add(
4686 json_ifp_out
, "protocolVxlan");
4688 if (c_oil
->oif_flags
[oif_vif_index
]
4689 & PIM_OIF_FLAG_PROTO_SOURCE
)
4690 json_object_boolean_true_add(
4691 json_ifp_out
, "protocolSource");
4693 if (c_oil
->oif_flags
[oif_vif_index
]
4694 & PIM_OIF_FLAG_PROTO_STAR
)
4695 json_object_boolean_true_add(
4697 "protocolInherited");
4699 json_object_string_add(json_ifp_out
,
4702 json_object_int_add(json_ifp_out
, "iVifI",
4703 c_oil
->oil
.mfcc_parent
);
4704 json_object_string_add(json_ifp_out
,
4705 "outboundInterface",
4707 json_object_int_add(json_ifp_out
, "oVifI",
4709 json_object_int_add(json_ifp_out
, "ttl", ttl
);
4710 json_object_string_add(json_ifp_out
, "upTime",
4713 json_oil
= json_object_new_object();
4714 json_object_object_add(json_source
,
4717 json_object_object_add(json_oil
, out_ifname
,
4720 if (c_oil
->oif_flags
[oif_vif_index
]
4721 & PIM_OIF_FLAG_PROTO_PIM
) {
4722 strcpy(proto
, "PIM");
4725 if (c_oil
->oif_flags
[oif_vif_index
]
4726 & PIM_OIF_FLAG_PROTO_IGMP
) {
4727 strcpy(proto
, "IGMP");
4730 if (c_oil
->oif_flags
[oif_vif_index
]
4731 & PIM_OIF_FLAG_PROTO_VXLAN
) {
4732 strcpy(proto
, "VxLAN");
4735 if (c_oil
->oif_flags
[oif_vif_index
]
4736 & PIM_OIF_FLAG_PROTO_SOURCE
) {
4737 strcpy(proto
, "SRC");
4740 if (c_oil
->oif_flags
[oif_vif_index
]
4741 & PIM_OIF_FLAG_PROTO_STAR
) {
4742 strcpy(proto
, "STAR");
4746 "%-15s %-15s %-6s %-16s %-16s %-3d %8s\n",
4747 src_str
, grp_str
, proto
, in_ifname
,
4748 out_ifname
, ttl
, mroute_uptime
);
4753 in_ifname
[0] = '\0';
4759 if (!uj
&& !found_oif
) {
4760 vty_out(vty
, "%-15s %-15s %-6s %-16s %-16s %-3d %8s\n",
4761 src_str
, grp_str
, "none", in_ifname
, "none", 0,
4766 /* Print list of static routes */
4767 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
4770 if (!s_route
->c_oil
.installed
)
4773 pim_inet4_dump("<group?>", s_route
->group
, grp_str
,
4775 pim_inet4_dump("<source?>", s_route
->source
, src_str
,
4777 ifp_in
= pim_if_find_by_vif_index(pim
, s_route
->iif
);
4781 strcpy(in_ifname
, ifp_in
->name
);
4783 strcpy(in_ifname
, "<iif?>");
4787 /* Find the group, create it if it doesn't exist */
4788 json_object_object_get_ex(json
, grp_str
, &json_group
);
4791 json_group
= json_object_new_object();
4792 json_object_object_add(json
, grp_str
,
4796 /* Find the source nested under the group, create it if
4797 * it doesn't exist */
4798 json_object_object_get_ex(json_group
, src_str
,
4802 json_source
= json_object_new_object();
4803 json_object_object_add(json_group
, src_str
,
4807 json_object_string_add(json_source
, "iif", in_ifname
);
4810 strcpy(proto
, "STATIC");
4813 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
4815 struct interface
*ifp_out
;
4816 char oif_uptime
[10];
4819 ttl
= s_route
->oif_ttls
[oif_vif_index
];
4823 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
4825 oif_uptime
, sizeof(oif_uptime
),
4828 .oif_creation
[oif_vif_index
]);
4832 strcpy(out_ifname
, ifp_out
->name
);
4834 strcpy(out_ifname
, "<oif?>");
4837 json_ifp_out
= json_object_new_object();
4838 json_object_string_add(json_ifp_out
, "source",
4840 json_object_string_add(json_ifp_out
, "group",
4842 json_object_boolean_true_add(json_ifp_out
,
4844 json_object_string_add(json_ifp_out
,
4847 json_object_int_add(
4848 json_ifp_out
, "iVifI",
4849 s_route
->c_oil
.oil
.mfcc_parent
);
4850 json_object_string_add(json_ifp_out
,
4851 "outboundInterface",
4853 json_object_int_add(json_ifp_out
, "oVifI",
4855 json_object_int_add(json_ifp_out
, "ttl", ttl
);
4856 json_object_string_add(json_ifp_out
, "upTime",
4859 json_oil
= json_object_new_object();
4860 json_object_object_add(json_source
,
4863 json_object_object_add(json_oil
, out_ifname
,
4867 "%-15s %-15s %-6s %-16s %-16s %-3d %8s %s\n",
4868 src_str
, grp_str
, proto
, in_ifname
,
4869 out_ifname
, ttl
, oif_uptime
,
4871 if (first
&& !fill
) {
4874 in_ifname
[0] = '\0';
4880 if (!uj
&& !found_oif
) {
4882 "%-15s %-15s %-6s %-16s %-16s %-3d %8s %s\n",
4883 src_str
, grp_str
, proto
, in_ifname
, "none", 0,
4884 "--:--:--", pim
->vrf
->name
);
4889 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4890 json
, JSON_C_TO_STRING_PRETTY
));
4891 json_object_free(json
);
4895 DEFUN (show_ip_mroute
,
4897 "show ip mroute [vrf NAME] [fill] [json]",
4902 "Fill in Assumed data\n"
4905 bool uj
= use_json(argc
, argv
);
4908 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4913 if (argv_find(argv
, argc
, "fill", &idx
))
4916 show_mroute(vrf
->info
, vty
, fill
, uj
);
4920 DEFUN (show_ip_mroute_vrf_all
,
4921 show_ip_mroute_vrf_all_cmd
,
4922 "show ip mroute vrf all [fill] [json]",
4927 "Fill in Assumed data\n"
4930 bool uj
= use_json(argc
, argv
);
4936 if (argv_find(argv
, argc
, "fill", &idx
))
4941 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4945 vty_out(vty
, " \"%s\": ", vrf
->name
);
4948 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4949 show_mroute(vrf
->info
, vty
, fill
, uj
);
4952 vty_out(vty
, "}\n");
4957 static void show_mroute_count(struct pim_instance
*pim
, struct vty
*vty
)
4959 struct listnode
*node
;
4960 struct channel_oil
*c_oil
;
4961 struct static_route
*s_route
;
4966 "Source Group LastUsed Packets Bytes WrongIf \n");
4968 /* Print PIM and IGMP route counts */
4969 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
4970 char group_str
[INET_ADDRSTRLEN
];
4971 char source_str
[INET_ADDRSTRLEN
];
4973 if (!c_oil
->installed
)
4976 pim_mroute_update_counters(c_oil
);
4978 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, group_str
,
4980 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, source_str
,
4981 sizeof(source_str
));
4983 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
4984 source_str
, group_str
, c_oil
->cc
.lastused
/ 100,
4985 c_oil
->cc
.pktcnt
, c_oil
->cc
.bytecnt
,
4986 c_oil
->cc
.wrong_if
);
4989 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
4990 char group_str
[INET_ADDRSTRLEN
];
4991 char source_str
[INET_ADDRSTRLEN
];
4993 if (!s_route
->c_oil
.installed
)
4996 pim_mroute_update_counters(&s_route
->c_oil
);
4998 pim_inet4_dump("<group?>", s_route
->c_oil
.oil
.mfcc_mcastgrp
,
4999 group_str
, sizeof(group_str
));
5000 pim_inet4_dump("<source?>", s_route
->c_oil
.oil
.mfcc_origin
,
5001 source_str
, sizeof(source_str
));
5003 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
5004 source_str
, group_str
, s_route
->c_oil
.cc
.lastused
,
5005 s_route
->c_oil
.cc
.pktcnt
, s_route
->c_oil
.cc
.bytecnt
,
5006 s_route
->c_oil
.cc
.wrong_if
);
5010 DEFUN (show_ip_mroute_count
,
5011 show_ip_mroute_count_cmd
,
5012 "show ip mroute [vrf NAME] count",
5017 "Route and packet count data\n")
5020 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5025 show_mroute_count(vrf
->info
, vty
);
5029 DEFUN (show_ip_mroute_count_vrf_all
,
5030 show_ip_mroute_count_vrf_all_cmd
,
5031 "show ip mroute vrf all count",
5036 "Route and packet count data\n")
5038 bool uj
= use_json(argc
, argv
);
5044 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5048 vty_out(vty
, " \"%s\": ", vrf
->name
);
5051 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5052 show_mroute_count(vrf
->info
, vty
);
5055 vty_out(vty
, "}\n");
5062 "show ip rib [vrf NAME] A.B.C.D",
5067 "Unicast address\n")
5070 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5071 struct in_addr addr
;
5072 const char *addr_str
;
5073 struct pim_nexthop nexthop
;
5074 char nexthop_addr_str
[PREFIX_STRLEN
];
5080 memset(&nexthop
, 0, sizeof(nexthop
));
5081 argv_find(argv
, argc
, "A.B.C.D", &idx
);
5082 addr_str
= argv
[idx
]->arg
;
5083 result
= inet_pton(AF_INET
, addr_str
, &addr
);
5085 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
5086 errno
, safe_strerror(errno
));
5090 if (!pim_nexthop_lookup(vrf
->info
, &nexthop
, addr
, 0)) {
5092 "Failure querying RIB nexthop for unicast address %s\n",
5098 "Address NextHop Interface Metric Preference\n");
5100 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
5101 nexthop_addr_str
, sizeof(nexthop_addr_str
));
5103 vty_out(vty
, "%-15s %-15s %-9s %6d %10d\n", addr_str
, nexthop_addr_str
,
5104 nexthop
.interface
? nexthop
.interface
->name
: "<ifname?>",
5105 nexthop
.mrib_route_metric
, nexthop
.mrib_metric_preference
);
5110 static void show_ssmpingd(struct pim_instance
*pim
, struct vty
*vty
)
5112 struct listnode
*node
;
5113 struct ssmpingd_sock
*ss
;
5117 "Source Socket Address Port Uptime Requests\n");
5119 if (!pim
->ssmpingd_list
)
5122 now
= pim_time_monotonic_sec();
5124 for (ALL_LIST_ELEMENTS_RO(pim
->ssmpingd_list
, node
, ss
)) {
5125 char source_str
[INET_ADDRSTRLEN
];
5127 struct sockaddr_in bind_addr
;
5128 socklen_t len
= sizeof(bind_addr
);
5129 char bind_addr_str
[INET_ADDRSTRLEN
];
5131 pim_inet4_dump("<src?>", ss
->source_addr
, source_str
,
5132 sizeof(source_str
));
5134 if (pim_socket_getsockname(
5135 ss
->sock_fd
, (struct sockaddr
*)&bind_addr
, &len
)) {
5137 "%% Failure reading socket name for ssmpingd source %s on fd=%d\n",
5138 source_str
, ss
->sock_fd
);
5141 pim_inet4_dump("<addr?>", bind_addr
.sin_addr
, bind_addr_str
,
5142 sizeof(bind_addr_str
));
5143 pim_time_uptime(ss_uptime
, sizeof(ss_uptime
),
5144 now
- ss
->creation
);
5146 vty_out(vty
, "%-15s %6d %-15s %5d %8s %8lld\n", source_str
,
5147 ss
->sock_fd
, bind_addr_str
, ntohs(bind_addr
.sin_port
),
5148 ss_uptime
, (long long)ss
->requests
);
5152 DEFUN (show_ip_ssmpingd
,
5153 show_ip_ssmpingd_cmd
,
5154 "show ip ssmpingd [vrf NAME]",
5161 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5166 show_ssmpingd(vrf
->info
, vty
);
5170 static int pim_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
5171 const char *rp
, const char *group
,
5176 result
= pim_rp_new(pim
, rp
, group
, plist
);
5178 if (result
== PIM_GROUP_BAD_ADDRESS
) {
5179 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
5180 return CMD_WARNING_CONFIG_FAILED
;
5183 if (result
== PIM_RP_BAD_ADDRESS
) {
5184 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
5185 return CMD_WARNING_CONFIG_FAILED
;
5188 if (result
== PIM_RP_NO_PATH
) {
5189 vty_out(vty
, "%% No Path to RP address specified: %s\n", rp
);
5193 if (result
== PIM_GROUP_OVERLAP
) {
5195 "%% Group range specified cannot exact match another\n");
5196 return CMD_WARNING_CONFIG_FAILED
;
5199 if (result
== PIM_GROUP_PFXLIST_OVERLAP
) {
5201 "%% This group is already covered by a RP prefix-list\n");
5202 return CMD_WARNING_CONFIG_FAILED
;
5205 if (result
== PIM_RP_PFXLIST_IN_USE
) {
5207 "%% The same prefix-list cannot be applied to multiple RPs\n");
5208 return CMD_WARNING_CONFIG_FAILED
;
5211 if (result
== PIM_GROUP_BAD_ADDR_MASK_COMBO
) {
5212 vty_out(vty
, "%% Inconsistent address and mask: %s\n",
5214 return CMD_WARNING_CONFIG_FAILED
;
5220 static int pim_cmd_spt_switchover(struct pim_instance
*pim
,
5221 enum pim_spt_switchover spt
,
5224 pim
->spt
.switchover
= spt
;
5226 switch (pim
->spt
.switchover
) {
5227 case PIM_SPT_IMMEDIATE
:
5228 XFREE(MTYPE_PIM_SPT_PLIST_NAME
, pim
->spt
.plist
);
5230 pim_upstream_add_lhr_star_pimreg(pim
);
5232 case PIM_SPT_INFINITY
:
5233 pim_upstream_remove_lhr_star_pimreg(pim
, plist
);
5235 XFREE(MTYPE_PIM_SPT_PLIST_NAME
, pim
->spt
.plist
);
5239 XSTRDUP(MTYPE_PIM_SPT_PLIST_NAME
, plist
);
5246 DEFUN (ip_pim_spt_switchover_infinity
,
5247 ip_pim_spt_switchover_infinity_cmd
,
5248 "ip pim spt-switchover infinity-and-beyond",
5252 "Never switch to SPT Tree\n")
5254 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5255 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, NULL
);
5258 DEFUN (ip_pim_spt_switchover_infinity_plist
,
5259 ip_pim_spt_switchover_infinity_plist_cmd
,
5260 "ip pim spt-switchover infinity-and-beyond prefix-list WORD",
5264 "Never switch to SPT Tree\n"
5265 "Prefix-List to control which groups to switch\n"
5266 "Prefix-List name\n")
5268 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5269 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, argv
[5]->arg
);
5272 DEFUN (no_ip_pim_spt_switchover_infinity
,
5273 no_ip_pim_spt_switchover_infinity_cmd
,
5274 "no ip pim spt-switchover infinity-and-beyond",
5279 "Never switch to SPT Tree\n")
5281 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5282 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
5285 DEFUN (no_ip_pim_spt_switchover_infinity_plist
,
5286 no_ip_pim_spt_switchover_infinity_plist_cmd
,
5287 "no ip pim spt-switchover infinity-and-beyond prefix-list WORD",
5292 "Never switch to SPT Tree\n"
5293 "Prefix-List to control which groups to switch\n"
5294 "Prefix-List name\n")
5296 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5297 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
5300 DEFUN (ip_pim_joinprune_time
,
5301 ip_pim_joinprune_time_cmd
,
5302 "ip pim join-prune-interval (60-600)",
5304 "pim multicast routing\n"
5305 "Join Prune Send Interval\n"
5308 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5309 router
->t_periodic
= atoi(argv
[3]->arg
);
5313 DEFUN (no_ip_pim_joinprune_time
,
5314 no_ip_pim_joinprune_time_cmd
,
5315 "no ip pim join-prune-interval (60-600)",
5318 "pim multicast routing\n"
5319 "Join Prune Send Interval\n"
5322 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5323 router
->t_periodic
= PIM_DEFAULT_T_PERIODIC
;
5327 DEFUN (ip_pim_register_suppress
,
5328 ip_pim_register_suppress_cmd
,
5329 "ip pim register-suppress-time (5-60000)",
5331 "pim multicast routing\n"
5332 "Register Suppress Timer\n"
5335 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5336 router
->register_suppress_time
= atoi(argv
[3]->arg
);
5340 DEFUN (no_ip_pim_register_suppress
,
5341 no_ip_pim_register_suppress_cmd
,
5342 "no ip pim register-suppress-time (5-60000)",
5345 "pim multicast routing\n"
5346 "Register Suppress Timer\n"
5349 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5350 router
->register_suppress_time
= PIM_REGISTER_SUPPRESSION_TIME_DEFAULT
;
5354 DEFUN (ip_pim_rp_keep_alive
,
5355 ip_pim_rp_keep_alive_cmd
,
5356 "ip pim rp keep-alive-timer (31-60000)",
5358 "pim multicast routing\n"
5360 "Keep alive Timer\n"
5363 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5364 pim
->rp_keep_alive_time
= atoi(argv
[4]->arg
);
5368 DEFUN (no_ip_pim_rp_keep_alive
,
5369 no_ip_pim_rp_keep_alive_cmd
,
5370 "no ip pim rp keep-alive-timer (31-60000)",
5373 "pim multicast routing\n"
5375 "Keep alive Timer\n"
5378 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5379 pim
->rp_keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
5383 DEFUN (ip_pim_keep_alive
,
5384 ip_pim_keep_alive_cmd
,
5385 "ip pim keep-alive-timer (31-60000)",
5387 "pim multicast routing\n"
5388 "Keep alive Timer\n"
5391 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5392 pim
->keep_alive_time
= atoi(argv
[3]->arg
);
5396 DEFUN (no_ip_pim_keep_alive
,
5397 no_ip_pim_keep_alive_cmd
,
5398 "no ip pim keep-alive-timer (31-60000)",
5401 "pim multicast routing\n"
5402 "Keep alive Timer\n"
5405 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5406 pim
->keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
5410 DEFUN (ip_pim_packets
,
5412 "ip pim packets (1-100)",
5414 "pim multicast routing\n"
5415 "packets to process at one time per fd\n"
5416 "Number of packets\n")
5418 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5419 router
->packet_process
= atoi(argv
[3]->arg
);
5423 DEFUN (no_ip_pim_packets
,
5424 no_ip_pim_packets_cmd
,
5425 "no ip pim packets (1-100)",
5428 "pim multicast routing\n"
5429 "packets to process at one time per fd\n"
5430 "Number of packets\n")
5432 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5433 router
->packet_process
= PIM_DEFAULT_PACKET_PROCESS
;
5437 DEFUN (ip_pim_v6_secondary
,
5438 ip_pim_v6_secondary_cmd
,
5439 "ip pim send-v6-secondary",
5441 "pim multicast routing\n"
5442 "Send v6 secondary addresses\n")
5444 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5445 pim
->send_v6_secondary
= 1;
5450 DEFUN (no_ip_pim_v6_secondary
,
5451 no_ip_pim_v6_secondary_cmd
,
5452 "no ip pim send-v6-secondary",
5455 "pim multicast routing\n"
5456 "Send v6 secondary addresses\n")
5458 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5459 pim
->send_v6_secondary
= 0;
5466 "ip pim rp A.B.C.D [A.B.C.D/M]",
5468 "pim multicast routing\n"
5470 "ip address of RP\n"
5471 "Group Address range to cover\n")
5473 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5476 if (argc
== (idx_ipv4
+ 1))
5477 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
5480 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
5481 argv
[idx_ipv4
+ 1]->arg
, NULL
);
5484 DEFUN (ip_pim_rp_prefix_list
,
5485 ip_pim_rp_prefix_list_cmd
,
5486 "ip pim rp A.B.C.D prefix-list WORD",
5488 "pim multicast routing\n"
5490 "ip address of RP\n"
5491 "group prefix-list filter\n"
5492 "Name of a prefix-list\n")
5494 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5495 return pim_rp_cmd_worker(pim
, vty
, argv
[3]->arg
, NULL
, argv
[5]->arg
);
5498 static int pim_no_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
5499 const char *rp
, const char *group
,
5502 int result
= pim_rp_del(pim
, rp
, group
, plist
);
5504 if (result
== PIM_GROUP_BAD_ADDRESS
) {
5505 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
5506 return CMD_WARNING_CONFIG_FAILED
;
5509 if (result
== PIM_RP_BAD_ADDRESS
) {
5510 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
5511 return CMD_WARNING_CONFIG_FAILED
;
5514 if (result
== PIM_RP_NOT_FOUND
) {
5515 vty_out(vty
, "%% Unable to find specified RP\n");
5516 return CMD_WARNING_CONFIG_FAILED
;
5522 DEFUN (no_ip_pim_rp
,
5524 "no ip pim rp A.B.C.D [A.B.C.D/M]",
5527 "pim multicast routing\n"
5529 "ip address of RP\n"
5530 "Group Address range to cover\n")
5532 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5533 int idx_ipv4
= 4, idx_group
= 0;
5535 if (argv_find(argv
, argc
, "A.B.C.D/M", &idx_group
))
5536 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
5537 argv
[idx_group
]->arg
, NULL
);
5539 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
5543 DEFUN (no_ip_pim_rp_prefix_list
,
5544 no_ip_pim_rp_prefix_list_cmd
,
5545 "no ip pim rp A.B.C.D prefix-list WORD",
5548 "pim multicast routing\n"
5550 "ip address of RP\n"
5551 "group prefix-list filter\n"
5552 "Name of a prefix-list\n")
5554 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5555 return pim_no_rp_cmd_worker(pim
, vty
, argv
[4]->arg
, NULL
, argv
[6]->arg
);
5558 static int pim_ssm_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
5561 int result
= pim_ssm_range_set(pim
, pim
->vrf_id
, plist
);
5563 if (result
== PIM_SSM_ERR_NONE
)
5567 case PIM_SSM_ERR_NO_VRF
:
5568 vty_out(vty
, "%% VRF doesn't exist\n");
5570 case PIM_SSM_ERR_DUP
:
5571 vty_out(vty
, "%% duplicate config\n");
5574 vty_out(vty
, "%% ssm range config failed\n");
5577 return CMD_WARNING_CONFIG_FAILED
;
5580 DEFUN (ip_pim_ssm_prefix_list
,
5581 ip_pim_ssm_prefix_list_cmd
,
5582 "ip pim ssm prefix-list WORD",
5584 "pim multicast routing\n"
5585 "Source Specific Multicast\n"
5586 "group range prefix-list filter\n"
5587 "Name of a prefix-list\n")
5589 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5590 return pim_ssm_cmd_worker(pim
, vty
, argv
[4]->arg
);
5593 DEFUN (no_ip_pim_ssm_prefix_list
,
5594 no_ip_pim_ssm_prefix_list_cmd
,
5595 "no ip pim ssm prefix-list",
5598 "pim multicast routing\n"
5599 "Source Specific Multicast\n"
5600 "group range prefix-list filter\n")
5602 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5603 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
5606 DEFUN (no_ip_pim_ssm_prefix_list_name
,
5607 no_ip_pim_ssm_prefix_list_name_cmd
,
5608 "no ip pim ssm prefix-list WORD",
5611 "pim multicast routing\n"
5612 "Source Specific Multicast\n"
5613 "group range prefix-list filter\n"
5614 "Name of a prefix-list\n")
5616 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5617 struct pim_ssm
*ssm
= pim
->ssm_info
;
5619 if (ssm
->plist_name
&& !strcmp(ssm
->plist_name
, argv
[5]->arg
))
5620 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
5622 vty_out(vty
, "%% pim ssm prefix-list %s doesn't exist\n", argv
[5]->arg
);
5624 return CMD_WARNING_CONFIG_FAILED
;
5627 static void ip_pim_ssm_show_group_range(struct pim_instance
*pim
,
5628 struct vty
*vty
, bool uj
)
5630 struct pim_ssm
*ssm
= pim
->ssm_info
;
5631 const char *range_str
=
5632 ssm
->plist_name
? ssm
->plist_name
: PIM_SSM_STANDARD_RANGE
;
5636 json
= json_object_new_object();
5637 json_object_string_add(json
, "ssmGroups", range_str
);
5638 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5639 json
, JSON_C_TO_STRING_PRETTY
));
5640 json_object_free(json
);
5642 vty_out(vty
, "SSM group range : %s\n", range_str
);
5645 DEFUN (show_ip_pim_ssm_range
,
5646 show_ip_pim_ssm_range_cmd
,
5647 "show ip pim [vrf NAME] group-type [json]",
5656 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5657 bool uj
= use_json(argc
, argv
);
5662 ip_pim_ssm_show_group_range(vrf
->info
, vty
, uj
);
5667 static void ip_pim_ssm_show_group_type(struct pim_instance
*pim
,
5668 struct vty
*vty
, bool uj
,
5671 struct in_addr group_addr
;
5672 const char *type_str
;
5675 result
= inet_pton(AF_INET
, group
, &group_addr
);
5677 type_str
= "invalid";
5679 if (pim_is_group_224_4(group_addr
))
5681 pim_is_grp_ssm(pim
, group_addr
) ? "SSM" : "ASM";
5683 type_str
= "not-multicast";
5688 json
= json_object_new_object();
5689 json_object_string_add(json
, "groupType", type_str
);
5690 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5691 json
, JSON_C_TO_STRING_PRETTY
));
5692 json_object_free(json
);
5694 vty_out(vty
, "Group type : %s\n", type_str
);
5697 DEFUN (show_ip_pim_group_type
,
5698 show_ip_pim_group_type_cmd
,
5699 "show ip pim [vrf NAME] group-type A.B.C.D [json]",
5704 "multicast group type\n"
5709 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5710 bool uj
= use_json(argc
, argv
);
5715 argv_find(argv
, argc
, "A.B.C.D", &idx
);
5716 ip_pim_ssm_show_group_type(vrf
->info
, vty
, uj
, argv
[idx
]->arg
);
5723 "ip ssmpingd [A.B.C.D]",
5728 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5731 struct in_addr source_addr
;
5732 const char *source_str
= (argc
== 3) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
5734 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
5736 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
5737 source_str
, errno
, safe_strerror(errno
));
5738 return CMD_WARNING_CONFIG_FAILED
;
5741 result
= pim_ssmpingd_start(pim
, source_addr
);
5743 vty_out(vty
, "%% Failure starting ssmpingd for source %s: %d\n",
5744 source_str
, result
);
5745 return CMD_WARNING_CONFIG_FAILED
;
5751 DEFUN (no_ip_ssmpingd
,
5753 "no ip ssmpingd [A.B.C.D]",
5759 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5762 struct in_addr source_addr
;
5763 const char *source_str
= (argc
== 4) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
5765 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
5767 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
5768 source_str
, errno
, safe_strerror(errno
));
5769 return CMD_WARNING_CONFIG_FAILED
;
5772 result
= pim_ssmpingd_stop(pim
, source_addr
);
5774 vty_out(vty
, "%% Failure stopping ssmpingd for source %s: %d\n",
5775 source_str
, result
);
5776 return CMD_WARNING_CONFIG_FAILED
;
5786 "pim multicast routing\n"
5787 "Enable PIM ECMP \n")
5789 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5790 pim
->ecmp_enable
= true;
5795 DEFUN (no_ip_pim_ecmp
,
5800 "pim multicast routing\n"
5801 "Disable PIM ECMP \n")
5803 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5804 pim
->ecmp_enable
= false;
5809 DEFUN (ip_pim_ecmp_rebalance
,
5810 ip_pim_ecmp_rebalance_cmd
,
5811 "ip pim ecmp rebalance",
5813 "pim multicast routing\n"
5814 "Enable PIM ECMP \n"
5815 "Enable PIM ECMP Rebalance\n")
5817 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5818 pim
->ecmp_enable
= true;
5819 pim
->ecmp_rebalance_enable
= true;
5824 DEFUN (no_ip_pim_ecmp_rebalance
,
5825 no_ip_pim_ecmp_rebalance_cmd
,
5826 "no ip pim ecmp rebalance",
5829 "pim multicast routing\n"
5830 "Disable PIM ECMP \n"
5831 "Disable PIM ECMP Rebalance\n")
5833 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5834 pim
->ecmp_rebalance_enable
= false;
5839 static int pim_cmd_igmp_start(struct vty
*vty
, struct interface
*ifp
)
5841 struct pim_interface
*pim_ifp
;
5842 uint8_t need_startup
= 0;
5844 pim_ifp
= ifp
->info
;
5847 pim_ifp
= pim_if_new(ifp
, true, false, false,
5848 false /*vxlan_term*/);
5850 vty_out(vty
, "Could not enable IGMP on interface %s\n",
5852 return CMD_WARNING_CONFIG_FAILED
;
5856 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
5857 PIM_IF_DO_IGMP(pim_ifp
->options
);
5862 /* 'ip igmp' executed multiple times, with need_startup
5863 avoid multiple if add all and membership refresh */
5865 pim_if_addr_add_all(ifp
);
5866 pim_if_membership_refresh(ifp
);
5872 DEFUN (interface_ip_igmp
,
5873 interface_ip_igmp_cmd
,
5878 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5880 return pim_cmd_igmp_start(vty
, ifp
);
5883 DEFUN (interface_no_ip_igmp
,
5884 interface_no_ip_igmp_cmd
,
5890 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5891 struct pim_interface
*pim_ifp
= ifp
->info
;
5896 PIM_IF_DONT_IGMP(pim_ifp
->options
);
5898 pim_if_membership_clear(ifp
);
5900 pim_if_addr_del_all_igmp(ifp
);
5902 if (!PIM_IF_TEST_PIM(pim_ifp
->options
)) {
5909 DEFUN (interface_ip_igmp_join
,
5910 interface_ip_igmp_join_cmd
,
5911 "ip igmp join A.B.C.D A.B.C.D",
5914 "IGMP join multicast group\n"
5915 "Multicast group address\n"
5918 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5921 const char *group_str
;
5922 const char *source_str
;
5923 struct in_addr group_addr
;
5924 struct in_addr source_addr
;
5928 group_str
= argv
[idx_ipv4
]->arg
;
5929 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
5931 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
5932 errno
, safe_strerror(errno
));
5933 return CMD_WARNING_CONFIG_FAILED
;
5936 /* Source address */
5937 source_str
= argv
[idx_ipv4_2
]->arg
;
5938 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
5940 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
5941 source_str
, errno
, safe_strerror(errno
));
5942 return CMD_WARNING_CONFIG_FAILED
;
5945 CMD_FERR_RETURN(pim_if_igmp_join_add(ifp
, group_addr
, source_addr
),
5946 "Failure joining IGMP group: $ERR");
5951 DEFUN (interface_no_ip_igmp_join
,
5952 interface_no_ip_igmp_join_cmd
,
5953 "no ip igmp join A.B.C.D A.B.C.D",
5957 "IGMP join multicast group\n"
5958 "Multicast group address\n"
5961 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5964 const char *group_str
;
5965 const char *source_str
;
5966 struct in_addr group_addr
;
5967 struct in_addr source_addr
;
5971 group_str
= argv
[idx_ipv4
]->arg
;
5972 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
5974 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
5975 errno
, safe_strerror(errno
));
5976 return CMD_WARNING_CONFIG_FAILED
;
5979 /* Source address */
5980 source_str
= argv
[idx_ipv4_2
]->arg
;
5981 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
5983 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
5984 source_str
, errno
, safe_strerror(errno
));
5985 return CMD_WARNING_CONFIG_FAILED
;
5988 result
= pim_if_igmp_join_del(ifp
, group_addr
, source_addr
);
5991 "%% Failure leaving IGMP group %s source %s on interface %s: %d\n",
5992 group_str
, source_str
, ifp
->name
, result
);
5993 return CMD_WARNING_CONFIG_FAILED
;
6000 CLI reconfiguration affects the interface level (struct pim_interface).
6001 This function propagates the reconfiguration to every active socket
6004 static void igmp_sock_query_interval_reconfig(struct igmp_sock
*igmp
)
6006 struct interface
*ifp
;
6007 struct pim_interface
*pim_ifp
;
6011 /* other querier present? */
6013 if (igmp
->t_other_querier_timer
)
6016 /* this is the querier */
6018 zassert(igmp
->interface
);
6019 zassert(igmp
->interface
->info
);
6021 ifp
= igmp
->interface
;
6022 pim_ifp
= ifp
->info
;
6024 if (PIM_DEBUG_IGMP_TRACE
) {
6025 char ifaddr_str
[INET_ADDRSTRLEN
];
6026 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
6027 sizeof(ifaddr_str
));
6028 zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
6029 __PRETTY_FUNCTION__
, ifaddr_str
, ifp
->name
,
6030 pim_ifp
->igmp_default_query_interval
);
6034 igmp_startup_mode_on() will reset QQI:
6036 igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
6038 igmp_startup_mode_on(igmp
);
6041 static void igmp_sock_query_reschedule(struct igmp_sock
*igmp
)
6043 if (igmp
->t_igmp_query_timer
) {
6044 /* other querier present */
6045 zassert(igmp
->t_igmp_query_timer
);
6046 zassert(!igmp
->t_other_querier_timer
);
6048 pim_igmp_general_query_off(igmp
);
6049 pim_igmp_general_query_on(igmp
);
6051 zassert(igmp
->t_igmp_query_timer
);
6052 zassert(!igmp
->t_other_querier_timer
);
6054 /* this is the querier */
6056 zassert(!igmp
->t_igmp_query_timer
);
6057 zassert(igmp
->t_other_querier_timer
);
6059 pim_igmp_other_querier_timer_off(igmp
);
6060 pim_igmp_other_querier_timer_on(igmp
);
6062 zassert(!igmp
->t_igmp_query_timer
);
6063 zassert(igmp
->t_other_querier_timer
);
6067 static void change_query_interval(struct pim_interface
*pim_ifp
,
6070 struct listnode
*sock_node
;
6071 struct igmp_sock
*igmp
;
6073 pim_ifp
->igmp_default_query_interval
= query_interval
;
6075 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
6076 igmp_sock_query_interval_reconfig(igmp
);
6077 igmp_sock_query_reschedule(igmp
);
6081 static void change_query_max_response_time(struct pim_interface
*pim_ifp
,
6082 int query_max_response_time_dsec
)
6084 struct listnode
*sock_node
;
6085 struct igmp_sock
*igmp
;
6087 pim_ifp
->igmp_query_max_response_time_dsec
=
6088 query_max_response_time_dsec
;
6091 Below we modify socket/group/source timers in order to quickly
6092 reflect the change. Otherwise, those timers would eventually catch
6096 /* scan all sockets */
6097 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
6098 struct listnode
*grp_node
;
6099 struct igmp_group
*grp
;
6101 /* reschedule socket general query */
6102 igmp_sock_query_reschedule(igmp
);
6104 /* scan socket groups */
6105 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grp_node
,
6107 struct listnode
*src_node
;
6108 struct igmp_source
*src
;
6110 /* reset group timers for groups in EXCLUDE mode */
6111 if (grp
->group_filtermode_isexcl
) {
6112 igmp_group_reset_gmi(grp
);
6115 /* scan group sources */
6116 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
,
6119 /* reset source timers for sources with running
6121 if (src
->t_source_timer
) {
6122 igmp_source_reset_gmi(igmp
, grp
, src
);
6129 #define IGMP_QUERY_INTERVAL_MIN (1)
6130 #define IGMP_QUERY_INTERVAL_MAX (1800)
6132 DEFUN (interface_ip_igmp_query_interval
,
6133 interface_ip_igmp_query_interval_cmd
,
6134 "ip igmp query-interval (1-1800)",
6137 IFACE_IGMP_QUERY_INTERVAL_STR
6138 "Query interval in seconds\n")
6140 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6141 struct pim_interface
*pim_ifp
= ifp
->info
;
6143 int query_interval_dsec
;
6147 ret
= pim_cmd_igmp_start(vty
, ifp
);
6148 if (ret
!= CMD_SUCCESS
)
6150 pim_ifp
= ifp
->info
;
6153 query_interval
= atoi(argv
[3]->arg
);
6154 query_interval_dsec
= 10 * query_interval
;
6157 It seems we don't need to check bounds since command.c does it
6158 already, but we verify them anyway for extra safety.
6160 if (query_interval
< IGMP_QUERY_INTERVAL_MIN
) {
6162 "General query interval %d lower than minimum %d\n",
6163 query_interval
, IGMP_QUERY_INTERVAL_MIN
);
6164 return CMD_WARNING_CONFIG_FAILED
;
6166 if (query_interval
> IGMP_QUERY_INTERVAL_MAX
) {
6168 "General query interval %d higher than maximum %d\n",
6169 query_interval
, IGMP_QUERY_INTERVAL_MAX
);
6170 return CMD_WARNING_CONFIG_FAILED
;
6173 if (query_interval_dsec
<= pim_ifp
->igmp_query_max_response_time_dsec
) {
6175 "Can't set general query interval %d dsec <= query max response time %d dsec.\n",
6176 query_interval_dsec
,
6177 pim_ifp
->igmp_query_max_response_time_dsec
);
6178 return CMD_WARNING_CONFIG_FAILED
;
6181 change_query_interval(pim_ifp
, query_interval
);
6186 DEFUN (interface_no_ip_igmp_query_interval
,
6187 interface_no_ip_igmp_query_interval_cmd
,
6188 "no ip igmp query-interval",
6192 IFACE_IGMP_QUERY_INTERVAL_STR
)
6194 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6195 struct pim_interface
*pim_ifp
= ifp
->info
;
6196 int default_query_interval_dsec
;
6201 default_query_interval_dsec
= IGMP_GENERAL_QUERY_INTERVAL
* 10;
6203 if (default_query_interval_dsec
6204 <= pim_ifp
->igmp_query_max_response_time_dsec
) {
6206 "Can't set default general query interval %d dsec <= query max response time %d dsec.\n",
6207 default_query_interval_dsec
,
6208 pim_ifp
->igmp_query_max_response_time_dsec
);
6209 return CMD_WARNING_CONFIG_FAILED
;
6212 change_query_interval(pim_ifp
, IGMP_GENERAL_QUERY_INTERVAL
);
6217 DEFUN (interface_ip_igmp_version
,
6218 interface_ip_igmp_version_cmd
,
6219 "ip igmp version (2-3)",
6223 "IGMP version number\n")
6225 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6226 struct pim_interface
*pim_ifp
= ifp
->info
;
6227 int igmp_version
, old_version
= 0;
6231 ret
= pim_cmd_igmp_start(vty
, ifp
);
6232 if (ret
!= CMD_SUCCESS
)
6234 pim_ifp
= ifp
->info
;
6237 igmp_version
= atoi(argv
[3]->arg
);
6238 old_version
= pim_ifp
->igmp_version
;
6239 pim_ifp
->igmp_version
= igmp_version
;
6241 // Check if IGMP is Enabled otherwise, enable on interface
6242 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
6243 PIM_IF_DO_IGMP(pim_ifp
->options
);
6244 pim_if_addr_add_all(ifp
);
6245 pim_if_membership_refresh(ifp
);
6246 old_version
= igmp_version
;
6247 // avoid refreshing membership again.
6249 /* Current and new version is different refresh existing
6250 membership. Going from 3 -> 2 or 2 -> 3. */
6251 if (old_version
!= igmp_version
)
6252 pim_if_membership_refresh(ifp
);
6257 DEFUN (interface_no_ip_igmp_version
,
6258 interface_no_ip_igmp_version_cmd
,
6259 "no ip igmp version (2-3)",
6264 "IGMP version number\n")
6266 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6267 struct pim_interface
*pim_ifp
= ifp
->info
;
6272 pim_ifp
->igmp_version
= IGMP_DEFAULT_VERSION
;
6277 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
6278 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
6280 DEFUN (interface_ip_igmp_query_max_response_time
,
6281 interface_ip_igmp_query_max_response_time_cmd
,
6282 "ip igmp query-max-response-time (10-250)",
6285 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
6286 "Query response value in deci-seconds\n")
6288 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6289 struct pim_interface
*pim_ifp
= ifp
->info
;
6290 int query_max_response_time
;
6294 ret
= pim_cmd_igmp_start(vty
, ifp
);
6295 if (ret
!= CMD_SUCCESS
)
6297 pim_ifp
= ifp
->info
;
6300 query_max_response_time
= atoi(argv
[3]->arg
);
6302 if (query_max_response_time
6303 >= pim_ifp
->igmp_default_query_interval
* 10) {
6305 "Can't set query max response time %d sec >= general query interval %d sec\n",
6306 query_max_response_time
,
6307 pim_ifp
->igmp_default_query_interval
);
6308 return CMD_WARNING_CONFIG_FAILED
;
6311 change_query_max_response_time(pim_ifp
, query_max_response_time
);
6316 DEFUN (interface_no_ip_igmp_query_max_response_time
,
6317 interface_no_ip_igmp_query_max_response_time_cmd
,
6318 "no ip igmp query-max-response-time (10-250)",
6322 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
6323 "Time for response in deci-seconds\n")
6325 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6326 struct pim_interface
*pim_ifp
= ifp
->info
;
6331 change_query_max_response_time(pim_ifp
,
6332 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
6337 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
6338 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
6340 DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec
,
6341 interface_ip_igmp_query_max_response_time_dsec_cmd
,
6342 "ip igmp query-max-response-time-dsec (10-250)",
6345 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
6346 "Query response value in deciseconds\n")
6348 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6349 struct pim_interface
*pim_ifp
= ifp
->info
;
6350 int query_max_response_time_dsec
;
6351 int default_query_interval_dsec
;
6355 ret
= pim_cmd_igmp_start(vty
, ifp
);
6356 if (ret
!= CMD_SUCCESS
)
6358 pim_ifp
= ifp
->info
;
6361 query_max_response_time_dsec
= atoi(argv
[4]->arg
);
6363 default_query_interval_dsec
= 10 * pim_ifp
->igmp_default_query_interval
;
6365 if (query_max_response_time_dsec
>= default_query_interval_dsec
) {
6367 "Can't set query max response time %d dsec >= general query interval %d dsec\n",
6368 query_max_response_time_dsec
,
6369 default_query_interval_dsec
);
6370 return CMD_WARNING_CONFIG_FAILED
;
6373 change_query_max_response_time(pim_ifp
, query_max_response_time_dsec
);
6378 DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec
,
6379 interface_no_ip_igmp_query_max_response_time_dsec_cmd
,
6380 "no ip igmp query-max-response-time-dsec",
6384 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
)
6386 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6387 struct pim_interface
*pim_ifp
= ifp
->info
;
6392 change_query_max_response_time(pim_ifp
,
6393 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
6398 DEFUN (interface_ip_pim_drprio
,
6399 interface_ip_pim_drprio_cmd
,
6400 "ip pim drpriority (1-4294967295)",
6403 "Set the Designated Router Election Priority\n"
6404 "Value of the new DR Priority\n")
6406 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6408 struct pim_interface
*pim_ifp
= ifp
->info
;
6409 uint32_t old_dr_prio
;
6412 vty_out(vty
, "Please enable PIM on interface, first\n");
6413 return CMD_WARNING_CONFIG_FAILED
;
6416 old_dr_prio
= pim_ifp
->pim_dr_priority
;
6418 pim_ifp
->pim_dr_priority
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
6420 if (old_dr_prio
!= pim_ifp
->pim_dr_priority
) {
6421 pim_if_dr_election(ifp
);
6422 pim_hello_restart_now(ifp
);
6428 DEFUN (interface_no_ip_pim_drprio
,
6429 interface_no_ip_pim_drprio_cmd
,
6430 "no ip pim drpriority [(1-4294967295)]",
6434 "Revert the Designated Router Priority to default\n"
6435 "Old Value of the Priority\n")
6437 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6438 struct pim_interface
*pim_ifp
= ifp
->info
;
6441 vty_out(vty
, "Pim not enabled on this interface\n");
6442 return CMD_WARNING_CONFIG_FAILED
;
6445 if (pim_ifp
->pim_dr_priority
!= PIM_DEFAULT_DR_PRIORITY
) {
6446 pim_ifp
->pim_dr_priority
= PIM_DEFAULT_DR_PRIORITY
;
6447 pim_if_dr_election(ifp
);
6448 pim_hello_restart_now(ifp
);
6454 static int pim_cmd_interface_add(struct interface
*ifp
)
6456 struct pim_interface
*pim_ifp
= ifp
->info
;
6459 pim_ifp
= pim_if_new(ifp
, false, true, false,
6460 false /*vxlan_term*/);
6465 PIM_IF_DO_PIM(pim_ifp
->options
);
6468 pim_if_addr_add_all(ifp
);
6469 pim_if_membership_refresh(ifp
);
6473 DEFPY_HIDDEN (pim_test_sg_keepalive
,
6474 pim_test_sg_keepalive_cmd
,
6475 "test pim [vrf NAME$name] keepalive-reset A.B.C.D$source A.B.C.D$group",
6479 "Reset the Keepalive Timer\n"
6480 "The Source we are resetting\n"
6481 "The Group we are resetting\n")
6483 struct pim_upstream
*up
;
6484 struct pim_instance
*pim
;
6485 struct prefix_sg sg
;
6491 pim
= pim_get_pim_instance(VRF_DEFAULT
);
6493 struct vrf
*vrf
= vrf_lookup_by_name(name
);
6496 vty_out(vty
, "%% Vrf specified: %s does not exist\n",
6501 pim
= pim_get_pim_instance(vrf
->vrf_id
);
6505 vty_out(vty
, "%% Unable to find pim instance\n");
6509 up
= pim_upstream_find(pim
, &sg
);
6511 vty_out(vty
, "%% Unable to find %s specified\n",
6512 pim_str_sg_dump(&sg
));
6516 vty_out(vty
, "Setting %s to current keep alive time: %d\n",
6517 pim_str_sg_dump(&sg
), pim
->keep_alive_time
);
6518 pim_upstream_keep_alive_timer_start(up
, pim
->keep_alive_time
);
6523 DEFPY_HIDDEN (interface_ip_pim_activeactive
,
6524 interface_ip_pim_activeactive_cmd
,
6525 "[no$no] ip pim active-active",
6529 "Mark interface as Active-Active for MLAG operations, Hidden because not finished yet\n")
6531 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6532 struct pim_interface
*pim_ifp
;
6534 if (!no
&& !pim_cmd_interface_add(ifp
)) {
6535 vty_out(vty
, "Could not enable PIM SM active-active on interface\n");
6536 return CMD_WARNING_CONFIG_FAILED
;
6539 pim_ifp
= ifp
->info
;
6541 pim_ifp
->activeactive
= false;
6543 pim_ifp
->activeactive
= true;
6548 DEFUN_HIDDEN (interface_ip_pim_ssm
,
6549 interface_ip_pim_ssm_cmd
,
6555 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6557 if (!pim_cmd_interface_add(ifp
)) {
6558 vty_out(vty
, "Could not enable PIM SM on interface\n");
6559 return CMD_WARNING_CONFIG_FAILED
;
6563 "WARN: Enabled PIM SM on interface; configure PIM SSM "
6564 "range if needed\n");
6568 static int interface_ip_pim_helper(struct vty
*vty
)
6570 struct pim_interface
*pim_ifp
;
6572 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6574 if (!pim_cmd_interface_add(ifp
)) {
6575 vty_out(vty
, "Could not enable PIM SM on interface\n");
6576 return CMD_WARNING_CONFIG_FAILED
;
6579 pim_ifp
= ifp
->info
;
6581 pim_if_create_pimreg(pim_ifp
->pim
);
6586 DEFUN_HIDDEN (interface_ip_pim_sm
,
6587 interface_ip_pim_sm_cmd
,
6593 return interface_ip_pim_helper(vty
);
6596 DEFUN (interface_ip_pim
,
6597 interface_ip_pim_cmd
,
6602 return interface_ip_pim_helper(vty
);
6605 static int pim_cmd_interface_delete(struct interface
*ifp
)
6607 struct pim_interface
*pim_ifp
= ifp
->info
;
6612 PIM_IF_DONT_PIM(pim_ifp
->options
);
6614 pim_if_membership_clear(ifp
);
6617 pim_sock_delete() removes all neighbors from
6618 pim_ifp->pim_neighbor_list.
6620 pim_sock_delete(ifp
, "pim unconfigured on interface");
6622 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
6623 pim_if_addr_del_all(ifp
);
6630 static int interface_no_ip_pim_helper(struct vty
*vty
)
6632 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6633 if (!pim_cmd_interface_delete(ifp
)) {
6634 vty_out(vty
, "Unable to delete interface information\n");
6635 return CMD_WARNING_CONFIG_FAILED
;
6641 DEFUN_HIDDEN (interface_no_ip_pim_ssm
,
6642 interface_no_ip_pim_ssm_cmd
,
6649 return interface_no_ip_pim_helper(vty
);
6652 DEFUN_HIDDEN (interface_no_ip_pim_sm
,
6653 interface_no_ip_pim_sm_cmd
,
6660 return interface_no_ip_pim_helper(vty
);
6663 DEFUN (interface_no_ip_pim
,
6664 interface_no_ip_pim_cmd
,
6670 return interface_no_ip_pim_helper(vty
);
6674 DEFUN(interface_ip_pim_boundary_oil
,
6675 interface_ip_pim_boundary_oil_cmd
,
6676 "ip multicast boundary oil WORD",
6678 "Generic multicast configuration options\n"
6679 "Define multicast boundary\n"
6680 "Filter OIL by group using prefix list\n"
6681 "Prefix list to filter OIL with\n")
6683 VTY_DECLVAR_CONTEXT(interface
, iif
);
6684 struct pim_interface
*pim_ifp
;
6687 argv_find(argv
, argc
, "WORD", &idx
);
6689 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6691 if (pim_ifp
->boundary_oil_plist
)
6692 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
6694 pim_ifp
->boundary_oil_plist
=
6695 XSTRDUP(MTYPE_PIM_INTERFACE
, argv
[idx
]->arg
);
6697 /* Interface will be pruned from OIL on next Join */
6701 DEFUN(interface_no_ip_pim_boundary_oil
,
6702 interface_no_ip_pim_boundary_oil_cmd
,
6703 "no ip multicast boundary oil [WORD]",
6706 "Generic multicast configuration options\n"
6707 "Define multicast boundary\n"
6708 "Filter OIL by group using prefix list\n"
6709 "Prefix list to filter OIL with\n")
6711 VTY_DECLVAR_CONTEXT(interface
, iif
);
6712 struct pim_interface
*pim_ifp
;
6715 argv_find(argv
, argc
, "WORD", &idx
);
6717 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6719 if (pim_ifp
->boundary_oil_plist
)
6720 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
6725 DEFUN (interface_ip_mroute
,
6726 interface_ip_mroute_cmd
,
6727 "ip mroute INTERFACE A.B.C.D",
6729 "Add multicast route\n"
6730 "Outgoing interface name\n"
6733 VTY_DECLVAR_CONTEXT(interface
, iif
);
6734 struct pim_interface
*pim_ifp
;
6735 struct pim_instance
*pim
;
6736 int idx_interface
= 2;
6738 struct interface
*oif
;
6739 const char *oifname
;
6740 const char *grp_str
;
6741 struct in_addr grp_addr
;
6742 struct in_addr src_addr
;
6745 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6748 oifname
= argv
[idx_interface
]->arg
;
6749 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6751 vty_out(vty
, "No such interface name %s\n", oifname
);
6755 grp_str
= argv
[idx_ipv4
]->arg
;
6756 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6758 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6759 errno
, safe_strerror(errno
));
6763 src_addr
.s_addr
= INADDR_ANY
;
6765 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6766 vty_out(vty
, "Failed to add route\n");
6773 DEFUN (interface_ip_mroute_source
,
6774 interface_ip_mroute_source_cmd
,
6775 "ip mroute INTERFACE A.B.C.D A.B.C.D",
6777 "Add multicast route\n"
6778 "Outgoing interface name\n"
6782 VTY_DECLVAR_CONTEXT(interface
, iif
);
6783 struct pim_interface
*pim_ifp
;
6784 struct pim_instance
*pim
;
6785 int idx_interface
= 2;
6788 struct interface
*oif
;
6789 const char *oifname
;
6790 const char *grp_str
;
6791 struct in_addr grp_addr
;
6792 const char *src_str
;
6793 struct in_addr src_addr
;
6796 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6799 oifname
= argv
[idx_interface
]->arg
;
6800 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6802 vty_out(vty
, "No such interface name %s\n", oifname
);
6806 grp_str
= argv
[idx_ipv4
]->arg
;
6807 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6809 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6810 errno
, safe_strerror(errno
));
6814 src_str
= argv
[idx_ipv4_2
]->arg
;
6815 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
6817 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
6818 errno
, safe_strerror(errno
));
6822 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6823 vty_out(vty
, "Failed to add route\n");
6830 DEFUN (interface_no_ip_mroute
,
6831 interface_no_ip_mroute_cmd
,
6832 "no ip mroute INTERFACE A.B.C.D",
6835 "Add multicast route\n"
6836 "Outgoing interface name\n"
6839 VTY_DECLVAR_CONTEXT(interface
, iif
);
6840 struct pim_interface
*pim_ifp
;
6841 struct pim_instance
*pim
;
6842 int idx_interface
= 3;
6844 struct interface
*oif
;
6845 const char *oifname
;
6846 const char *grp_str
;
6847 struct in_addr grp_addr
;
6848 struct in_addr src_addr
;
6851 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6854 oifname
= argv
[idx_interface
]->arg
;
6855 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6857 vty_out(vty
, "No such interface name %s\n", oifname
);
6861 grp_str
= argv
[idx_ipv4
]->arg
;
6862 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6864 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6865 errno
, safe_strerror(errno
));
6869 src_addr
.s_addr
= INADDR_ANY
;
6871 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6872 vty_out(vty
, "Failed to remove route\n");
6879 DEFUN (interface_no_ip_mroute_source
,
6880 interface_no_ip_mroute_source_cmd
,
6881 "no ip mroute INTERFACE A.B.C.D A.B.C.D",
6884 "Add multicast route\n"
6885 "Outgoing interface name\n"
6889 VTY_DECLVAR_CONTEXT(interface
, iif
);
6890 struct pim_interface
*pim_ifp
;
6891 struct pim_instance
*pim
;
6892 int idx_interface
= 3;
6895 struct interface
*oif
;
6896 const char *oifname
;
6897 const char *grp_str
;
6898 struct in_addr grp_addr
;
6899 const char *src_str
;
6900 struct in_addr src_addr
;
6903 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6906 oifname
= argv
[idx_interface
]->arg
;
6907 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6909 vty_out(vty
, "No such interface name %s\n", oifname
);
6913 grp_str
= argv
[idx_ipv4
]->arg
;
6914 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6916 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6917 errno
, safe_strerror(errno
));
6921 src_str
= argv
[idx_ipv4_2
]->arg
;
6922 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
6924 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
6925 errno
, safe_strerror(errno
));
6929 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6930 vty_out(vty
, "Failed to remove route\n");
6937 DEFUN (interface_ip_pim_hello
,
6938 interface_ip_pim_hello_cmd
,
6939 "ip pim hello (1-180) [(1-180)]",
6943 IFACE_PIM_HELLO_TIME_STR
6944 IFACE_PIM_HELLO_HOLD_STR
)
6946 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6949 struct pim_interface
*pim_ifp
= ifp
->info
;
6952 if (!pim_cmd_interface_add(ifp
)) {
6953 vty_out(vty
, "Could not enable PIM SM on interface\n");
6954 return CMD_WARNING_CONFIG_FAILED
;
6958 pim_ifp
= ifp
->info
;
6959 pim_ifp
->pim_hello_period
= strtol(argv
[idx_time
]->arg
, NULL
, 10);
6961 if (argc
== idx_hold
+ 1)
6962 pim_ifp
->pim_default_holdtime
=
6963 strtol(argv
[idx_hold
]->arg
, NULL
, 10);
6968 DEFUN (interface_no_ip_pim_hello
,
6969 interface_no_ip_pim_hello_cmd
,
6970 "no ip pim hello [(1-180) (1-180)]",
6975 IFACE_PIM_HELLO_TIME_STR
6976 IFACE_PIM_HELLO_HOLD_STR
)
6978 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6979 struct pim_interface
*pim_ifp
= ifp
->info
;
6982 vty_out(vty
, "Pim not enabled on this interface\n");
6983 return CMD_WARNING_CONFIG_FAILED
;
6986 pim_ifp
->pim_hello_period
= PIM_DEFAULT_HELLO_PERIOD
;
6987 pim_ifp
->pim_default_holdtime
= -1;
6998 PIM_DO_DEBUG_IGMP_EVENTS
;
6999 PIM_DO_DEBUG_IGMP_PACKETS
;
7000 PIM_DO_DEBUG_IGMP_TRACE
;
7004 DEFUN (no_debug_igmp
,
7011 PIM_DONT_DEBUG_IGMP_EVENTS
;
7012 PIM_DONT_DEBUG_IGMP_PACKETS
;
7013 PIM_DONT_DEBUG_IGMP_TRACE
;
7018 DEFUN (debug_igmp_events
,
7019 debug_igmp_events_cmd
,
7020 "debug igmp events",
7023 DEBUG_IGMP_EVENTS_STR
)
7025 PIM_DO_DEBUG_IGMP_EVENTS
;
7029 DEFUN (no_debug_igmp_events
,
7030 no_debug_igmp_events_cmd
,
7031 "no debug igmp events",
7035 DEBUG_IGMP_EVENTS_STR
)
7037 PIM_DONT_DEBUG_IGMP_EVENTS
;
7042 DEFUN (debug_igmp_packets
,
7043 debug_igmp_packets_cmd
,
7044 "debug igmp packets",
7047 DEBUG_IGMP_PACKETS_STR
)
7049 PIM_DO_DEBUG_IGMP_PACKETS
;
7053 DEFUN (no_debug_igmp_packets
,
7054 no_debug_igmp_packets_cmd
,
7055 "no debug igmp packets",
7059 DEBUG_IGMP_PACKETS_STR
)
7061 PIM_DONT_DEBUG_IGMP_PACKETS
;
7066 DEFUN (debug_igmp_trace
,
7067 debug_igmp_trace_cmd
,
7071 DEBUG_IGMP_TRACE_STR
)
7073 PIM_DO_DEBUG_IGMP_TRACE
;
7077 DEFUN (no_debug_igmp_trace
,
7078 no_debug_igmp_trace_cmd
,
7079 "no debug igmp trace",
7083 DEBUG_IGMP_TRACE_STR
)
7085 PIM_DONT_DEBUG_IGMP_TRACE
;
7090 DEFUN (debug_mroute
,
7096 PIM_DO_DEBUG_MROUTE
;
7100 DEFUN (debug_mroute_detail
,
7101 debug_mroute_detail_cmd
,
7102 "debug mroute detail",
7107 PIM_DO_DEBUG_MROUTE_DETAIL
;
7111 DEFUN (no_debug_mroute
,
7112 no_debug_mroute_cmd
,
7118 PIM_DONT_DEBUG_MROUTE
;
7122 DEFUN (no_debug_mroute_detail
,
7123 no_debug_mroute_detail_cmd
,
7124 "no debug mroute detail",
7130 PIM_DONT_DEBUG_MROUTE_DETAIL
;
7134 DEFUN (debug_pim_static
,
7135 debug_pim_static_cmd
,
7141 PIM_DO_DEBUG_STATIC
;
7145 DEFUN (no_debug_pim_static
,
7146 no_debug_pim_static_cmd
,
7147 "no debug pim static",
7153 PIM_DONT_DEBUG_STATIC
;
7164 PIM_DO_DEBUG_PIM_EVENTS
;
7165 PIM_DO_DEBUG_PIM_PACKETS
;
7166 PIM_DO_DEBUG_PIM_TRACE
;
7167 PIM_DO_DEBUG_MSDP_EVENTS
;
7168 PIM_DO_DEBUG_MSDP_PACKETS
;
7172 DEFUN (no_debug_pim
,
7179 PIM_DONT_DEBUG_PIM_EVENTS
;
7180 PIM_DONT_DEBUG_PIM_PACKETS
;
7181 PIM_DONT_DEBUG_PIM_TRACE
;
7182 PIM_DONT_DEBUG_MSDP_EVENTS
;
7183 PIM_DONT_DEBUG_MSDP_PACKETS
;
7185 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
7186 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
7191 DEFUN (debug_pim_nht
,
7196 "Nexthop Tracking\n")
7198 PIM_DO_DEBUG_PIM_NHT
;
7202 DEFUN (no_debug_pim_nht
,
7203 no_debug_pim_nht_cmd
,
7208 "Nexthop Tracking\n")
7210 PIM_DONT_DEBUG_PIM_NHT
;
7214 DEFUN (debug_pim_nht_rp
,
7215 debug_pim_nht_rp_cmd
,
7219 "Nexthop Tracking\n"
7220 "RP Nexthop Tracking\n")
7222 PIM_DO_DEBUG_PIM_NHT_RP
;
7226 DEFUN (no_debug_pim_nht_rp
,
7227 no_debug_pim_nht_rp_cmd
,
7228 "no debug pim nht rp",
7232 "Nexthop Tracking\n"
7233 "RP Nexthop Tracking\n")
7235 PIM_DONT_DEBUG_PIM_NHT_RP
;
7239 DEFUN (debug_pim_events
,
7240 debug_pim_events_cmd
,
7244 DEBUG_PIM_EVENTS_STR
)
7246 PIM_DO_DEBUG_PIM_EVENTS
;
7250 DEFUN (no_debug_pim_events
,
7251 no_debug_pim_events_cmd
,
7252 "no debug pim events",
7256 DEBUG_PIM_EVENTS_STR
)
7258 PIM_DONT_DEBUG_PIM_EVENTS
;
7262 DEFUN (debug_pim_packets
,
7263 debug_pim_packets_cmd
,
7264 "debug pim packets [<hello|joins|register>]",
7267 DEBUG_PIM_PACKETS_STR
7268 DEBUG_PIM_HELLO_PACKETS_STR
7269 DEBUG_PIM_J_P_PACKETS_STR
7270 DEBUG_PIM_PIM_REG_PACKETS_STR
)
7273 if (argv_find(argv
, argc
, "hello", &idx
)) {
7274 PIM_DO_DEBUG_PIM_HELLO
;
7275 vty_out(vty
, "PIM Hello debugging is on\n");
7276 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
7277 PIM_DO_DEBUG_PIM_J_P
;
7278 vty_out(vty
, "PIM Join/Prune debugging is on\n");
7279 } else if (argv_find(argv
, argc
, "register", &idx
)) {
7280 PIM_DO_DEBUG_PIM_REG
;
7281 vty_out(vty
, "PIM Register debugging is on\n");
7283 PIM_DO_DEBUG_PIM_PACKETS
;
7284 vty_out(vty
, "PIM Packet debugging is on \n");
7289 DEFUN (no_debug_pim_packets
,
7290 no_debug_pim_packets_cmd
,
7291 "no debug pim packets [<hello|joins|register>]",
7295 DEBUG_PIM_PACKETS_STR
7296 DEBUG_PIM_HELLO_PACKETS_STR
7297 DEBUG_PIM_J_P_PACKETS_STR
7298 DEBUG_PIM_PIM_REG_PACKETS_STR
)
7301 if (argv_find(argv
, argc
, "hello", &idx
)) {
7302 PIM_DONT_DEBUG_PIM_HELLO
;
7303 vty_out(vty
, "PIM Hello debugging is off \n");
7304 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
7305 PIM_DONT_DEBUG_PIM_J_P
;
7306 vty_out(vty
, "PIM Join/Prune debugging is off \n");
7307 } else if (argv_find(argv
, argc
, "register", &idx
)) {
7308 PIM_DONT_DEBUG_PIM_REG
;
7309 vty_out(vty
, "PIM Register debugging is off\n");
7311 PIM_DONT_DEBUG_PIM_PACKETS
;
7317 DEFUN (debug_pim_packetdump_send
,
7318 debug_pim_packetdump_send_cmd
,
7319 "debug pim packet-dump send",
7322 DEBUG_PIM_PACKETDUMP_STR
7323 DEBUG_PIM_PACKETDUMP_SEND_STR
)
7325 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND
;
7329 DEFUN (no_debug_pim_packetdump_send
,
7330 no_debug_pim_packetdump_send_cmd
,
7331 "no debug pim packet-dump send",
7335 DEBUG_PIM_PACKETDUMP_STR
7336 DEBUG_PIM_PACKETDUMP_SEND_STR
)
7338 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
7342 DEFUN (debug_pim_packetdump_recv
,
7343 debug_pim_packetdump_recv_cmd
,
7344 "debug pim packet-dump receive",
7347 DEBUG_PIM_PACKETDUMP_STR
7348 DEBUG_PIM_PACKETDUMP_RECV_STR
)
7350 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV
;
7354 DEFUN (no_debug_pim_packetdump_recv
,
7355 no_debug_pim_packetdump_recv_cmd
,
7356 "no debug pim packet-dump receive",
7360 DEBUG_PIM_PACKETDUMP_STR
7361 DEBUG_PIM_PACKETDUMP_RECV_STR
)
7363 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
7367 DEFUN (debug_pim_trace
,
7368 debug_pim_trace_cmd
,
7372 DEBUG_PIM_TRACE_STR
)
7374 PIM_DO_DEBUG_PIM_TRACE
;
7378 DEFUN (debug_pim_trace_detail
,
7379 debug_pim_trace_detail_cmd
,
7380 "debug pim trace detail",
7384 "Detailed Information\n")
7386 PIM_DO_DEBUG_PIM_TRACE_DETAIL
;
7390 DEFUN (no_debug_pim_trace
,
7391 no_debug_pim_trace_cmd
,
7392 "no debug pim trace",
7396 DEBUG_PIM_TRACE_STR
)
7398 PIM_DONT_DEBUG_PIM_TRACE
;
7402 DEFUN (no_debug_pim_trace_detail
,
7403 no_debug_pim_trace_detail_cmd
,
7404 "no debug pim trace detail",
7409 "Detailed Information\n")
7411 PIM_DONT_DEBUG_PIM_TRACE_DETAIL
;
7415 DEFUN (debug_ssmpingd
,
7421 PIM_DO_DEBUG_SSMPINGD
;
7425 DEFUN (no_debug_ssmpingd
,
7426 no_debug_ssmpingd_cmd
,
7427 "no debug ssmpingd",
7432 PIM_DONT_DEBUG_SSMPINGD
;
7436 DEFUN (debug_pim_zebra
,
7437 debug_pim_zebra_cmd
,
7441 DEBUG_PIM_ZEBRA_STR
)
7447 DEFUN (no_debug_pim_zebra
,
7448 no_debug_pim_zebra_cmd
,
7449 "no debug pim zebra",
7453 DEBUG_PIM_ZEBRA_STR
)
7455 PIM_DONT_DEBUG_ZEBRA
;
7459 DEFUN (debug_pim_vxlan
,
7460 debug_pim_vxlan_cmd
,
7464 DEBUG_PIM_VXLAN_STR
)
7470 DEFUN (no_debug_pim_vxlan
,
7471 no_debug_pim_vxlan_cmd
,
7472 "no debug pim vxlan",
7476 DEBUG_PIM_VXLAN_STR
)
7478 PIM_DONT_DEBUG_VXLAN
;
7488 PIM_DO_DEBUG_MSDP_EVENTS
;
7489 PIM_DO_DEBUG_MSDP_PACKETS
;
7493 DEFUN (no_debug_msdp
,
7500 PIM_DONT_DEBUG_MSDP_EVENTS
;
7501 PIM_DONT_DEBUG_MSDP_PACKETS
;
7505 DEFUN (debug_msdp_events
,
7506 debug_msdp_events_cmd
,
7507 "debug msdp events",
7510 DEBUG_MSDP_EVENTS_STR
)
7512 PIM_DO_DEBUG_MSDP_EVENTS
;
7516 DEFUN (no_debug_msdp_events
,
7517 no_debug_msdp_events_cmd
,
7518 "no debug msdp events",
7522 DEBUG_MSDP_EVENTS_STR
)
7524 PIM_DONT_DEBUG_MSDP_EVENTS
;
7528 DEFUN (debug_msdp_packets
,
7529 debug_msdp_packets_cmd
,
7530 "debug msdp packets",
7533 DEBUG_MSDP_PACKETS_STR
)
7535 PIM_DO_DEBUG_MSDP_PACKETS
;
7539 DEFUN (no_debug_msdp_packets
,
7540 no_debug_msdp_packets_cmd
,
7541 "no debug msdp packets",
7545 DEBUG_MSDP_PACKETS_STR
)
7547 PIM_DONT_DEBUG_MSDP_PACKETS
;
7551 DEFUN (debug_mtrace
,
7557 PIM_DO_DEBUG_MTRACE
;
7561 DEFUN (no_debug_mtrace
,
7562 no_debug_mtrace_cmd
,
7568 PIM_DONT_DEBUG_MTRACE
;
7572 DEFUN_NOSH (show_debugging_pim
,
7573 show_debugging_pim_cmd
,
7574 "show debugging [pim]",
7579 vty_out(vty
, "PIM debugging status\n");
7581 pim_debug_config_write(vty
);
7586 static int interface_pim_use_src_cmd_worker(struct vty
*vty
, const char *source
)
7589 struct in_addr source_addr
;
7590 int ret
= CMD_SUCCESS
;
7591 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7593 result
= inet_pton(AF_INET
, source
, &source_addr
);
7595 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", source
,
7596 errno
, safe_strerror(errno
));
7597 return CMD_WARNING_CONFIG_FAILED
;
7600 result
= pim_update_source_set(ifp
, source_addr
);
7604 case PIM_IFACE_NOT_FOUND
:
7605 ret
= CMD_WARNING_CONFIG_FAILED
;
7606 vty_out(vty
, "Pim not enabled on this interface\n");
7608 case PIM_UPDATE_SOURCE_DUP
:
7610 vty_out(vty
, "%% Source already set to %s\n", source
);
7613 ret
= CMD_WARNING_CONFIG_FAILED
;
7614 vty_out(vty
, "%% Source set failed\n");
7620 DEFUN (interface_pim_use_source
,
7621 interface_pim_use_source_cmd
,
7622 "ip pim use-source A.B.C.D",
7625 "Configure primary IP address\n"
7626 "source ip address\n")
7628 return interface_pim_use_src_cmd_worker(vty
, argv
[3]->arg
);
7631 DEFUN (interface_no_pim_use_source
,
7632 interface_no_pim_use_source_cmd
,
7633 "no ip pim use-source [A.B.C.D]",
7637 "Delete source IP address\n"
7638 "source ip address\n")
7640 return interface_pim_use_src_cmd_worker(vty
, "0.0.0.0");
7648 "Enables BFD support\n")
7650 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7651 struct pim_interface
*pim_ifp
= ifp
->info
;
7652 struct bfd_info
*bfd_info
= NULL
;
7655 if (!pim_cmd_interface_add(ifp
)) {
7656 vty_out(vty
, "Could not enable PIM SM on interface\n");
7660 pim_ifp
= ifp
->info
;
7662 bfd_info
= pim_ifp
->bfd_info
;
7664 if (!bfd_info
|| !CHECK_FLAG(bfd_info
->flags
, BFD_FLAG_PARAM_CFG
))
7665 pim_bfd_if_param_set(ifp
, BFD_DEF_MIN_RX
, BFD_DEF_MIN_TX
,
7666 BFD_DEF_DETECT_MULT
, 1);
7671 DEFUN (no_ip_pim_bfd
,
7677 "Disables BFD support\n")
7679 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7680 struct pim_interface
*pim_ifp
= ifp
->info
;
7683 vty_out(vty
, "Pim not enabled on this interface\n");
7687 if (pim_ifp
->bfd_info
) {
7688 pim_bfd_reg_dereg_all_nbr(ifp
, ZEBRA_BFD_DEST_DEREGISTER
);
7689 bfd_info_free(&(pim_ifp
->bfd_info
));
7699 #endif /* HAVE_BFDD */
7701 ip_pim_bfd_param_cmd
,
7702 "ip pim bfd (2-255) (50-60000) (50-60000)",
7705 "Enables BFD support\n"
7706 "Detect Multiplier\n"
7707 "Required min receive interval\n"
7708 "Desired min transmit interval\n")
7710 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7712 int idx_number_2
= 4;
7713 int idx_number_3
= 5;
7718 struct pim_interface
*pim_ifp
= ifp
->info
;
7721 if (!pim_cmd_interface_add(ifp
)) {
7722 vty_out(vty
, "Could not enable PIM SM on interface\n");
7727 if ((ret
= bfd_validate_param(
7728 vty
, argv
[idx_number
]->arg
, argv
[idx_number_2
]->arg
,
7729 argv
[idx_number_3
]->arg
, &dm_val
, &rx_val
, &tx_val
))
7733 pim_bfd_if_param_set(ifp
, rx_val
, tx_val
, dm_val
, 0);
7739 ALIAS(no_ip_pim_bfd
, no_ip_pim_bfd_param_cmd
,
7740 "no ip pim bfd (2-255) (50-60000) (50-60000)", NO_STR IP_STR PIM_STR
7741 "Enables BFD support\n"
7742 "Detect Multiplier\n"
7743 "Required min receive interval\n"
7744 "Desired min transmit interval\n")
7745 #endif /* !HAVE_BFDD */
7747 static int ip_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
7748 const char *peer
, const char *local
)
7750 enum pim_msdp_err result
;
7751 struct in_addr peer_addr
;
7752 struct in_addr local_addr
;
7753 int ret
= CMD_SUCCESS
;
7755 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
7757 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
7758 errno
, safe_strerror(errno
));
7759 return CMD_WARNING_CONFIG_FAILED
;
7762 result
= inet_pton(AF_INET
, local
, &local_addr
);
7764 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", local
,
7765 errno
, safe_strerror(errno
));
7766 return CMD_WARNING_CONFIG_FAILED
;
7769 result
= pim_msdp_peer_add(pim
, peer_addr
, local_addr
, "default",
7772 case PIM_MSDP_ERR_NONE
:
7774 case PIM_MSDP_ERR_OOM
:
7775 ret
= CMD_WARNING_CONFIG_FAILED
;
7776 vty_out(vty
, "%% Out of memory\n");
7778 case PIM_MSDP_ERR_PEER_EXISTS
:
7780 vty_out(vty
, "%% Peer exists\n");
7782 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
7783 ret
= CMD_WARNING_CONFIG_FAILED
;
7784 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
7787 ret
= CMD_WARNING_CONFIG_FAILED
;
7788 vty_out(vty
, "%% peer add failed\n");
7794 DEFUN_HIDDEN (ip_msdp_peer
,
7796 "ip msdp peer A.B.C.D source A.B.C.D",
7799 "Configure MSDP peer\n"
7801 "Source address for TCP connection\n"
7802 "local ip address\n")
7804 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7805 return ip_msdp_peer_cmd_worker(pim
, vty
, argv
[3]->arg
, argv
[5]->arg
);
7808 static int ip_no_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
7811 enum pim_msdp_err result
;
7812 struct in_addr peer_addr
;
7814 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
7816 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
7817 errno
, safe_strerror(errno
));
7818 return CMD_WARNING_CONFIG_FAILED
;
7821 result
= pim_msdp_peer_del(pim
, peer_addr
);
7823 case PIM_MSDP_ERR_NONE
:
7825 case PIM_MSDP_ERR_NO_PEER
:
7826 vty_out(vty
, "%% Peer does not exist\n");
7829 vty_out(vty
, "%% peer del failed\n");
7832 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7835 DEFUN_HIDDEN (no_ip_msdp_peer
,
7836 no_ip_msdp_peer_cmd
,
7837 "no ip msdp peer A.B.C.D",
7841 "Delete MSDP peer\n"
7842 "peer ip address\n")
7844 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7845 return ip_no_msdp_peer_cmd_worker(pim
, vty
, argv
[4]->arg
);
7848 static int ip_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
7849 struct vty
*vty
, const char *mg
,
7852 enum pim_msdp_err result
;
7853 struct in_addr mbr_ip
;
7854 int ret
= CMD_SUCCESS
;
7856 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
7858 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
7859 errno
, safe_strerror(errno
));
7860 return CMD_WARNING_CONFIG_FAILED
;
7863 result
= pim_msdp_mg_mbr_add(pim
, mg
, mbr_ip
);
7865 case PIM_MSDP_ERR_NONE
:
7867 case PIM_MSDP_ERR_OOM
:
7868 ret
= CMD_WARNING_CONFIG_FAILED
;
7869 vty_out(vty
, "%% Out of memory\n");
7871 case PIM_MSDP_ERR_MG_MBR_EXISTS
:
7873 vty_out(vty
, "%% mesh-group member exists\n");
7875 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
7876 ret
= CMD_WARNING_CONFIG_FAILED
;
7877 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
7880 ret
= CMD_WARNING_CONFIG_FAILED
;
7881 vty_out(vty
, "%% member add failed\n");
7887 DEFUN (ip_msdp_mesh_group_member
,
7888 ip_msdp_mesh_group_member_cmd
,
7889 "ip msdp mesh-group WORD member A.B.C.D",
7892 "Configure MSDP mesh-group\n"
7894 "mesh group member\n"
7895 "peer ip address\n")
7897 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7898 return ip_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[3]->arg
,
7902 static int ip_no_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
7907 enum pim_msdp_err result
;
7908 struct in_addr mbr_ip
;
7910 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
7912 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
7913 errno
, safe_strerror(errno
));
7914 return CMD_WARNING_CONFIG_FAILED
;
7917 result
= pim_msdp_mg_mbr_del(pim
, mg
, mbr_ip
);
7919 case PIM_MSDP_ERR_NONE
:
7921 case PIM_MSDP_ERR_NO_MG
:
7922 vty_out(vty
, "%% mesh-group does not exist\n");
7924 case PIM_MSDP_ERR_NO_MG_MBR
:
7925 vty_out(vty
, "%% mesh-group member does not exist\n");
7928 vty_out(vty
, "%% mesh-group member del failed\n");
7931 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7933 DEFUN (no_ip_msdp_mesh_group_member
,
7934 no_ip_msdp_mesh_group_member_cmd
,
7935 "no ip msdp mesh-group WORD member A.B.C.D",
7939 "Delete MSDP mesh-group member\n"
7941 "mesh group member\n"
7942 "peer ip address\n")
7944 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7945 return ip_no_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[4]->arg
,
7949 static int ip_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
7950 struct vty
*vty
, const char *mg
,
7953 enum pim_msdp_err result
;
7954 struct in_addr src_ip
;
7956 result
= inet_pton(AF_INET
, src
, &src_ip
);
7958 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", src
,
7959 errno
, safe_strerror(errno
));
7960 return CMD_WARNING_CONFIG_FAILED
;
7963 result
= pim_msdp_mg_src_add(pim
, mg
, src_ip
);
7965 case PIM_MSDP_ERR_NONE
:
7967 case PIM_MSDP_ERR_OOM
:
7968 vty_out(vty
, "%% Out of memory\n");
7970 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
7971 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
7974 vty_out(vty
, "%% source add failed\n");
7977 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7981 DEFUN (ip_msdp_mesh_group_source
,
7982 ip_msdp_mesh_group_source_cmd
,
7983 "ip msdp mesh-group WORD source A.B.C.D",
7986 "Configure MSDP mesh-group\n"
7988 "mesh group local address\n"
7989 "source ip address for the TCP connection\n")
7991 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7992 return ip_msdp_mesh_group_source_cmd_worker(pim
, vty
, argv
[3]->arg
,
7996 static int ip_no_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
8000 enum pim_msdp_err result
;
8002 result
= pim_msdp_mg_src_del(pim
, mg
);
8004 case PIM_MSDP_ERR_NONE
:
8006 case PIM_MSDP_ERR_NO_MG
:
8007 vty_out(vty
, "%% mesh-group does not exist\n");
8010 vty_out(vty
, "%% mesh-group source del failed\n");
8013 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
8016 static int ip_no_msdp_mesh_group_cmd_worker(struct pim_instance
*pim
,
8017 struct vty
*vty
, const char *mg
)
8019 enum pim_msdp_err result
;
8021 result
= pim_msdp_mg_del(pim
, mg
);
8023 case PIM_MSDP_ERR_NONE
:
8025 case PIM_MSDP_ERR_NO_MG
:
8026 vty_out(vty
, "%% mesh-group does not exist\n");
8029 vty_out(vty
, "%% mesh-group source del failed\n");
8032 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
8035 DEFUN (no_ip_msdp_mesh_group_source
,
8036 no_ip_msdp_mesh_group_source_cmd
,
8037 "no ip msdp mesh-group WORD source [A.B.C.D]",
8041 "Delete MSDP mesh-group source\n"
8043 "mesh group source\n"
8044 "mesh group local address\n")
8046 PIM_DECLVAR_CONTEXT(vrf
, pim
);
8048 return ip_no_msdp_mesh_group_cmd_worker(pim
, vty
, argv
[6]->arg
);
8050 return ip_no_msdp_mesh_group_source_cmd_worker(pim
, vty
,
8054 static void print_empty_json_obj(struct vty
*vty
)
8057 json
= json_object_new_object();
8058 vty_out(vty
, "%s\n",
8059 json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
));
8060 json_object_free(json
);
8063 static void ip_msdp_show_mesh_group(struct pim_instance
*pim
, struct vty
*vty
,
8066 struct listnode
*mbrnode
;
8067 struct pim_msdp_mg_mbr
*mbr
;
8068 struct pim_msdp_mg
*mg
= pim
->msdp
.mg
;
8069 char mbr_str
[INET_ADDRSTRLEN
];
8070 char src_str
[INET_ADDRSTRLEN
];
8071 char state_str
[PIM_MSDP_STATE_STRLEN
];
8072 enum pim_msdp_peer_state state
;
8073 json_object
*json
= NULL
;
8074 json_object
*json_mg_row
= NULL
;
8075 json_object
*json_members
= NULL
;
8076 json_object
*json_row
= NULL
;
8080 print_empty_json_obj(vty
);
8084 pim_inet4_dump("<source?>", mg
->src_ip
, src_str
, sizeof(src_str
));
8086 json
= json_object_new_object();
8087 /* currently there is only one mesh group but we should still
8089 * it a dict with mg-name as key */
8090 json_mg_row
= json_object_new_object();
8091 json_object_string_add(json_mg_row
, "name",
8092 mg
->mesh_group_name
);
8093 json_object_string_add(json_mg_row
, "source", src_str
);
8095 vty_out(vty
, "Mesh group : %s\n", mg
->mesh_group_name
);
8096 vty_out(vty
, " Source : %s\n", src_str
);
8097 vty_out(vty
, " Member State\n");
8100 for (ALL_LIST_ELEMENTS_RO(mg
->mbr_list
, mbrnode
, mbr
)) {
8101 pim_inet4_dump("<mbr?>", mbr
->mbr_ip
, mbr_str
, sizeof(mbr_str
));
8103 state
= mbr
->mp
->state
;
8105 state
= PIM_MSDP_DISABLED
;
8107 pim_msdp_state_dump(state
, state_str
, sizeof(state_str
));
8109 json_row
= json_object_new_object();
8110 json_object_string_add(json_row
, "member", mbr_str
);
8111 json_object_string_add(json_row
, "state", state_str
);
8112 if (!json_members
) {
8113 json_members
= json_object_new_object();
8114 json_object_object_add(json_mg_row
, "members",
8117 json_object_object_add(json_members
, mbr_str
, json_row
);
8119 vty_out(vty
, " %-15s %11s\n", mbr_str
, state_str
);
8124 json_object_object_add(json
, mg
->mesh_group_name
, json_mg_row
);
8125 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8126 json
, JSON_C_TO_STRING_PRETTY
));
8127 json_object_free(json
);
8131 DEFUN (show_ip_msdp_mesh_group
,
8132 show_ip_msdp_mesh_group_cmd
,
8133 "show ip msdp [vrf NAME] mesh-group [json]",
8138 "MSDP mesh-group information\n"
8141 bool uj
= use_json(argc
, argv
);
8143 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
8148 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
8153 DEFUN (show_ip_msdp_mesh_group_vrf_all
,
8154 show_ip_msdp_mesh_group_vrf_all_cmd
,
8155 "show ip msdp vrf all mesh-group [json]",
8160 "MSDP mesh-group information\n"
8163 bool uj
= use_json(argc
, argv
);
8169 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
8173 vty_out(vty
, " \"%s\": ", vrf
->name
);
8176 vty_out(vty
, "VRF: %s\n", vrf
->name
);
8177 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
8180 vty_out(vty
, "}\n");
8185 static void ip_msdp_show_peers(struct pim_instance
*pim
, struct vty
*vty
,
8188 struct listnode
*mpnode
;
8189 struct pim_msdp_peer
*mp
;
8190 char peer_str
[INET_ADDRSTRLEN
];
8191 char local_str
[INET_ADDRSTRLEN
];
8192 char state_str
[PIM_MSDP_STATE_STRLEN
];
8193 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
8195 json_object
*json
= NULL
;
8196 json_object
*json_row
= NULL
;
8200 json
= json_object_new_object();
8203 "Peer Local State Uptime SaCnt\n");
8206 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
8207 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
8208 now
= pim_time_monotonic_sec();
8209 pim_time_uptime(timebuf
, sizeof(timebuf
),
8212 strcpy(timebuf
, "-");
8214 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
8215 pim_inet4_dump("<local?>", mp
->local
, local_str
,
8217 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
8219 json_row
= json_object_new_object();
8220 json_object_string_add(json_row
, "peer", peer_str
);
8221 json_object_string_add(json_row
, "local", local_str
);
8222 json_object_string_add(json_row
, "state", state_str
);
8223 json_object_string_add(json_row
, "upTime", timebuf
);
8224 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
8225 json_object_object_add(json
, peer_str
, json_row
);
8227 vty_out(vty
, "%-15s %15s %11s %8s %6d\n", peer_str
,
8228 local_str
, state_str
, timebuf
, mp
->sa_cnt
);
8233 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8234 json
, JSON_C_TO_STRING_PRETTY
));
8235 json_object_free(json
);
8239 static void ip_msdp_show_peers_detail(struct pim_instance
*pim
, struct vty
*vty
,
8240 const char *peer
, bool uj
)
8242 struct listnode
*mpnode
;
8243 struct pim_msdp_peer
*mp
;
8244 char peer_str
[INET_ADDRSTRLEN
];
8245 char local_str
[INET_ADDRSTRLEN
];
8246 char state_str
[PIM_MSDP_STATE_STRLEN
];
8247 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
8248 char katimer
[PIM_MSDP_TIMER_STRLEN
];
8249 char crtimer
[PIM_MSDP_TIMER_STRLEN
];
8250 char holdtimer
[PIM_MSDP_TIMER_STRLEN
];
8252 json_object
*json
= NULL
;
8253 json_object
*json_row
= NULL
;
8256 json
= json_object_new_object();
8259 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
8260 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
8261 if (strcmp(peer
, "detail") && strcmp(peer
, peer_str
))
8264 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
8265 now
= pim_time_monotonic_sec();
8266 pim_time_uptime(timebuf
, sizeof(timebuf
),
8269 strcpy(timebuf
, "-");
8271 pim_inet4_dump("<local?>", mp
->local
, local_str
,
8273 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
8274 pim_time_timer_to_hhmmss(katimer
, sizeof(katimer
),
8276 pim_time_timer_to_hhmmss(crtimer
, sizeof(crtimer
),
8278 pim_time_timer_to_hhmmss(holdtimer
, sizeof(holdtimer
),
8282 json_row
= json_object_new_object();
8283 json_object_string_add(json_row
, "peer", peer_str
);
8284 json_object_string_add(json_row
, "local", local_str
);
8285 json_object_string_add(json_row
, "meshGroupName",
8286 mp
->mesh_group_name
);
8287 json_object_string_add(json_row
, "state", state_str
);
8288 json_object_string_add(json_row
, "upTime", timebuf
);
8289 json_object_string_add(json_row
, "keepAliveTimer",
8291 json_object_string_add(json_row
, "connRetryTimer",
8293 json_object_string_add(json_row
, "holdTimer",
8295 json_object_string_add(json_row
, "lastReset",
8297 json_object_int_add(json_row
, "connAttempts",
8299 json_object_int_add(json_row
, "establishedChanges",
8301 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
8302 json_object_int_add(json_row
, "kaSent", mp
->ka_tx_cnt
);
8303 json_object_int_add(json_row
, "kaRcvd", mp
->ka_rx_cnt
);
8304 json_object_int_add(json_row
, "saSent", mp
->sa_tx_cnt
);
8305 json_object_int_add(json_row
, "saRcvd", mp
->sa_rx_cnt
);
8306 json_object_object_add(json
, peer_str
, json_row
);
8308 vty_out(vty
, "Peer : %s\n", peer_str
);
8309 vty_out(vty
, " Local : %s\n", local_str
);
8310 vty_out(vty
, " Mesh Group : %s\n",
8311 mp
->mesh_group_name
);
8312 vty_out(vty
, " State : %s\n", state_str
);
8313 vty_out(vty
, " Uptime : %s\n", timebuf
);
8315 vty_out(vty
, " Keepalive Timer : %s\n", katimer
);
8316 vty_out(vty
, " Conn Retry Timer : %s\n", crtimer
);
8317 vty_out(vty
, " Hold Timer : %s\n", holdtimer
);
8318 vty_out(vty
, " Last Reset : %s\n",
8320 vty_out(vty
, " Conn Attempts : %d\n",
8322 vty_out(vty
, " Established Changes : %d\n",
8324 vty_out(vty
, " SA Count : %d\n",
8326 vty_out(vty
, " Statistics :\n");
8329 vty_out(vty
, " Keepalives : %10d %10d\n",
8330 mp
->ka_tx_cnt
, mp
->ka_rx_cnt
);
8331 vty_out(vty
, " SAs : %10d %10d\n",
8332 mp
->sa_tx_cnt
, mp
->sa_rx_cnt
);
8338 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8339 json
, JSON_C_TO_STRING_PRETTY
));
8340 json_object_free(json
);
8344 DEFUN (show_ip_msdp_peer_detail
,
8345 show_ip_msdp_peer_detail_cmd
,
8346 "show ip msdp [vrf NAME] peer [detail|A.B.C.D] [json]",
8351 "MSDP peer information\n"
8356 bool uj
= use_json(argc
, argv
);
8358 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
8365 if (argv_find(argv
, argc
, "detail", &idx
))
8366 arg
= argv
[idx
]->text
;
8367 else if (argv_find(argv
, argc
, "A.B.C.D", &idx
))
8368 arg
= argv
[idx
]->arg
;
8371 ip_msdp_show_peers_detail(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
8373 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
8378 DEFUN (show_ip_msdp_peer_detail_vrf_all
,
8379 show_ip_msdp_peer_detail_vrf_all_cmd
,
8380 "show ip msdp vrf all peer [detail|A.B.C.D] [json]",
8385 "MSDP peer information\n"
8391 bool uj
= use_json(argc
, argv
);
8397 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
8401 vty_out(vty
, " \"%s\": ", vrf
->name
);
8404 vty_out(vty
, "VRF: %s\n", vrf
->name
);
8405 if (argv_find(argv
, argc
, "detail", &idx
)
8406 || argv_find(argv
, argc
, "A.B.C.D", &idx
))
8407 ip_msdp_show_peers_detail(vrf
->info
, vty
,
8408 argv
[idx
]->arg
, uj
);
8410 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
8413 vty_out(vty
, "}\n");
8418 static void ip_msdp_show_sa(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
8420 struct listnode
*sanode
;
8421 struct pim_msdp_sa
*sa
;
8422 char src_str
[INET_ADDRSTRLEN
];
8423 char grp_str
[INET_ADDRSTRLEN
];
8424 char rp_str
[INET_ADDRSTRLEN
];
8425 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
8429 json_object
*json
= NULL
;
8430 json_object
*json_group
= NULL
;
8431 json_object
*json_row
= NULL
;
8434 json
= json_object_new_object();
8437 "Source Group RP Local SPT Uptime\n");
8440 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
8441 now
= pim_time_monotonic_sec();
8442 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
8443 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
8444 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
8445 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
8446 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
8448 strcpy(spt_str
, "yes");
8450 strcpy(spt_str
, "no");
8453 strcpy(rp_str
, "-");
8454 strcpy(spt_str
, "-");
8456 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
8457 strcpy(local_str
, "yes");
8459 strcpy(local_str
, "no");
8462 json_object_object_get_ex(json
, grp_str
, &json_group
);
8465 json_group
= json_object_new_object();
8466 json_object_object_add(json
, grp_str
,
8470 json_row
= json_object_new_object();
8471 json_object_string_add(json_row
, "source", src_str
);
8472 json_object_string_add(json_row
, "group", grp_str
);
8473 json_object_string_add(json_row
, "rp", rp_str
);
8474 json_object_string_add(json_row
, "local", local_str
);
8475 json_object_string_add(json_row
, "sptSetup", spt_str
);
8476 json_object_string_add(json_row
, "upTime", timebuf
);
8477 json_object_object_add(json_group
, src_str
, json_row
);
8479 vty_out(vty
, "%-15s %15s %15s %5c %3c %8s\n",
8480 src_str
, grp_str
, rp_str
, local_str
[0],
8481 spt_str
[0], timebuf
);
8486 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8487 json
, JSON_C_TO_STRING_PRETTY
));
8488 json_object_free(json
);
8492 static void ip_msdp_show_sa_entry_detail(struct pim_msdp_sa
*sa
,
8493 const char *src_str
,
8494 const char *grp_str
, struct vty
*vty
,
8495 bool uj
, json_object
*json
)
8497 char rp_str
[INET_ADDRSTRLEN
];
8498 char peer_str
[INET_ADDRSTRLEN
];
8499 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
8502 char statetimer
[PIM_MSDP_TIMER_STRLEN
];
8504 json_object
*json_group
= NULL
;
8505 json_object
*json_row
= NULL
;
8507 now
= pim_time_monotonic_sec();
8508 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
8509 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
8510 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
8511 pim_inet4_dump("<peer?>", sa
->peer
, peer_str
, sizeof(peer_str
));
8513 strcpy(spt_str
, "yes");
8515 strcpy(spt_str
, "no");
8518 strcpy(rp_str
, "-");
8519 strcpy(peer_str
, "-");
8520 strcpy(spt_str
, "-");
8522 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
8523 strcpy(local_str
, "yes");
8525 strcpy(local_str
, "no");
8527 pim_time_timer_to_hhmmss(statetimer
, sizeof(statetimer
),
8528 sa
->sa_state_timer
);
8530 json_object_object_get_ex(json
, grp_str
, &json_group
);
8533 json_group
= json_object_new_object();
8534 json_object_object_add(json
, grp_str
, json_group
);
8537 json_row
= json_object_new_object();
8538 json_object_string_add(json_row
, "source", src_str
);
8539 json_object_string_add(json_row
, "group", grp_str
);
8540 json_object_string_add(json_row
, "rp", rp_str
);
8541 json_object_string_add(json_row
, "local", local_str
);
8542 json_object_string_add(json_row
, "sptSetup", spt_str
);
8543 json_object_string_add(json_row
, "upTime", timebuf
);
8544 json_object_string_add(json_row
, "stateTimer", statetimer
);
8545 json_object_object_add(json_group
, src_str
, json_row
);
8547 vty_out(vty
, "SA : %s\n", sa
->sg_str
);
8548 vty_out(vty
, " RP : %s\n", rp_str
);
8549 vty_out(vty
, " Peer : %s\n", peer_str
);
8550 vty_out(vty
, " Local : %s\n", local_str
);
8551 vty_out(vty
, " SPT Setup : %s\n", spt_str
);
8552 vty_out(vty
, " Uptime : %s\n", timebuf
);
8553 vty_out(vty
, " State Timer : %s\n", statetimer
);
8558 static void ip_msdp_show_sa_detail(struct pim_instance
*pim
, struct vty
*vty
,
8561 struct listnode
*sanode
;
8562 struct pim_msdp_sa
*sa
;
8563 char src_str
[INET_ADDRSTRLEN
];
8564 char grp_str
[INET_ADDRSTRLEN
];
8565 json_object
*json
= NULL
;
8568 json
= json_object_new_object();
8571 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
8572 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
8573 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
8574 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
, uj
,
8579 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8580 json
, JSON_C_TO_STRING_PRETTY
));
8581 json_object_free(json
);
8585 DEFUN (show_ip_msdp_sa_detail
,
8586 show_ip_msdp_sa_detail_cmd
,
8587 "show ip msdp [vrf NAME] sa detail [json]",
8592 "MSDP active-source information\n"
8596 bool uj
= use_json(argc
, argv
);
8598 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
8603 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
8608 DEFUN (show_ip_msdp_sa_detail_vrf_all
,
8609 show_ip_msdp_sa_detail_vrf_all_cmd
,
8610 "show ip msdp vrf all sa detail [json]",
8615 "MSDP active-source information\n"
8619 bool uj
= use_json(argc
, argv
);
8625 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
8629 vty_out(vty
, " \"%s\": ", vrf
->name
);
8632 vty_out(vty
, "VRF: %s\n", vrf
->name
);
8633 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
8636 vty_out(vty
, "}\n");
8641 static void ip_msdp_show_sa_addr(struct pim_instance
*pim
, struct vty
*vty
,
8642 const char *addr
, bool uj
)
8644 struct listnode
*sanode
;
8645 struct pim_msdp_sa
*sa
;
8646 char src_str
[INET_ADDRSTRLEN
];
8647 char grp_str
[INET_ADDRSTRLEN
];
8648 json_object
*json
= NULL
;
8651 json
= json_object_new_object();
8654 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
8655 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
8656 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
8657 if (!strcmp(addr
, src_str
) || !strcmp(addr
, grp_str
)) {
8658 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
8664 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8665 json
, JSON_C_TO_STRING_PRETTY
));
8666 json_object_free(json
);
8670 static void ip_msdp_show_sa_sg(struct pim_instance
*pim
, struct vty
*vty
,
8671 const char *src
, const char *grp
, bool uj
)
8673 struct listnode
*sanode
;
8674 struct pim_msdp_sa
*sa
;
8675 char src_str
[INET_ADDRSTRLEN
];
8676 char grp_str
[INET_ADDRSTRLEN
];
8677 json_object
*json
= NULL
;
8680 json
= json_object_new_object();
8683 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
8684 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
8685 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
8686 if (!strcmp(src
, src_str
) && !strcmp(grp
, grp_str
)) {
8687 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
8693 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8694 json
, JSON_C_TO_STRING_PRETTY
));
8695 json_object_free(json
);
8699 DEFUN (show_ip_msdp_sa_sg
,
8700 show_ip_msdp_sa_sg_cmd
,
8701 "show ip msdp [vrf NAME] sa [A.B.C.D [A.B.C.D]] [json]",
8706 "MSDP active-source information\n"
8707 "source or group ip\n"
8711 bool uj
= use_json(argc
, argv
);
8715 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
8720 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
8722 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
8726 if (src_ip
&& grp_ip
)
8727 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
8729 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
8731 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
8736 DEFUN (show_ip_msdp_sa_sg_vrf_all
,
8737 show_ip_msdp_sa_sg_vrf_all_cmd
,
8738 "show ip msdp vrf all sa [A.B.C.D [A.B.C.D]] [json]",
8743 "MSDP active-source information\n"
8744 "source or group ip\n"
8748 bool uj
= use_json(argc
, argv
);
8753 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
8755 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
8761 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
8765 vty_out(vty
, " \"%s\": ", vrf
->name
);
8768 vty_out(vty
, "VRF: %s\n", vrf
->name
);
8770 if (src_ip
&& grp_ip
)
8771 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
8773 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
8775 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
8778 vty_out(vty
, "}\n");
8783 struct pim_sg_cache_walk_data
{
8786 json_object
*json_group
;
8787 struct in_addr addr
;
8791 static void pim_show_vxlan_sg_entry(struct pim_vxlan_sg
*vxlan_sg
,
8792 struct pim_sg_cache_walk_data
*cwd
)
8794 struct vty
*vty
= cwd
->vty
;
8795 json_object
*json
= cwd
->json
;
8796 char src_str
[INET_ADDRSTRLEN
];
8797 char grp_str
[INET_ADDRSTRLEN
];
8798 json_object
*json_row
;
8799 bool installed
= (vxlan_sg
->up
)?TRUE
:FALSE
;
8800 const char *iif_name
= vxlan_sg
->iif
?vxlan_sg
->iif
->name
:"-";
8801 const char *oif_name
;
8803 if (pim_vxlan_is_orig_mroute(vxlan_sg
))
8804 oif_name
= vxlan_sg
->orig_oif
?vxlan_sg
->orig_oif
->name
:"";
8806 oif_name
= vxlan_sg
->term_oif
?vxlan_sg
->term_oif
->name
:"";
8808 if (cwd
->addr_match
&& (vxlan_sg
->sg
.src
.s_addr
!= cwd
->addr
.s_addr
) &&
8809 (vxlan_sg
->sg
.grp
.s_addr
!= cwd
->addr
.s_addr
)) {
8812 pim_inet4_dump("<src?>", vxlan_sg
->sg
.src
, src_str
, sizeof(src_str
));
8813 pim_inet4_dump("<grp?>", vxlan_sg
->sg
.grp
, grp_str
, sizeof(grp_str
));
8815 json_object_object_get_ex(json
, grp_str
, &cwd
->json_group
);
8817 if (!cwd
->json_group
) {
8818 cwd
->json_group
= json_object_new_object();
8819 json_object_object_add(json
, grp_str
,
8823 json_row
= json_object_new_object();
8824 json_object_string_add(json_row
, "source", src_str
);
8825 json_object_string_add(json_row
, "group", grp_str
);
8826 json_object_string_add(json_row
, "input", iif_name
);
8827 json_object_string_add(json_row
, "output", oif_name
);
8829 json_object_boolean_true_add(json_row
, "installed");
8831 json_object_boolean_false_add(json_row
, "installed");
8832 json_object_object_add(cwd
->json_group
, src_str
, json_row
);
8834 vty_out(vty
, "%-15s %-15s %-15s %-15s %-5s\n",
8835 src_str
, grp_str
, iif_name
, oif_name
,
8840 static void pim_show_vxlan_sg_hash_entry(struct hash_backet
*backet
, void *arg
)
8842 pim_show_vxlan_sg_entry((struct pim_vxlan_sg
*)backet
->data
,
8843 (struct pim_sg_cache_walk_data
*)arg
);
8846 static void pim_show_vxlan_sg(struct pim_instance
*pim
,
8847 struct vty
*vty
, bool uj
)
8849 json_object
*json
= NULL
;
8850 struct pim_sg_cache_walk_data cwd
;
8853 json
= json_object_new_object();
8855 vty_out(vty
, "Codes: I -> installed\n");
8857 "Source Group Input Output Flags\n");
8860 memset(&cwd
, 0, sizeof(cwd
));
8863 hash_iterate(pim
->vxlan
.sg_hash
, pim_show_vxlan_sg_hash_entry
, &cwd
);
8866 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8867 json
, JSON_C_TO_STRING_PRETTY
));
8868 json_object_free(json
);
8872 static void pim_show_vxlan_sg_match_addr(struct pim_instance
*pim
,
8873 struct vty
*vty
, char *addr_str
, bool uj
)
8875 json_object
*json
= NULL
;
8876 struct pim_sg_cache_walk_data cwd
;
8879 memset(&cwd
, 0, sizeof(cwd
));
8880 result
= inet_pton(AF_INET
, addr_str
, &cwd
.addr
);
8882 vty_out(vty
, "Bad address %s: errno=%d: %s\n", addr_str
,
8883 errno
, safe_strerror(errno
));
8888 json
= json_object_new_object();
8890 vty_out(vty
, "Codes: I -> installed\n");
8892 "Source Group Input Output Flags\n");
8897 cwd
.addr_match
= TRUE
;
8898 hash_iterate(pim
->vxlan
.sg_hash
, pim_show_vxlan_sg_hash_entry
, &cwd
);
8901 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8902 json
, JSON_C_TO_STRING_PRETTY
));
8903 json_object_free(json
);
8907 static void pim_show_vxlan_sg_one(struct pim_instance
*pim
,
8908 struct vty
*vty
, char *src_str
, char *grp_str
, bool uj
)
8910 json_object
*json
= NULL
;
8911 struct prefix_sg sg
;
8913 struct pim_vxlan_sg
*vxlan_sg
;
8914 const char *iif_name
;
8916 const char *oif_name
;
8918 result
= inet_pton(AF_INET
, src_str
, &sg
.src
);
8920 vty_out(vty
, "Bad src address %s: errno=%d: %s\n", src_str
,
8921 errno
, safe_strerror(errno
));
8924 result
= inet_pton(AF_INET
, grp_str
, &sg
.grp
);
8926 vty_out(vty
, "Bad grp address %s: errno=%d: %s\n", grp_str
,
8927 errno
, safe_strerror(errno
));
8931 sg
.family
= AF_INET
;
8932 sg
.prefixlen
= IPV4_MAX_BITLEN
;
8934 json
= json_object_new_object();
8936 vxlan_sg
= pim_vxlan_sg_find(pim
, &sg
);
8938 installed
= (vxlan_sg
->up
)?TRUE
:FALSE
;
8939 iif_name
= vxlan_sg
->iif
?vxlan_sg
->iif
->name
:"-";
8941 if (pim_vxlan_is_orig_mroute(vxlan_sg
))
8943 vxlan_sg
->orig_oif
?vxlan_sg
->orig_oif
->name
:"";
8946 vxlan_sg
->term_oif
?vxlan_sg
->term_oif
->name
:"";
8949 json_object_string_add(json
, "source", src_str
);
8950 json_object_string_add(json
, "group", grp_str
);
8951 json_object_string_add(json
, "input", iif_name
);
8952 json_object_string_add(json
, "output", oif_name
);
8954 json_object_boolean_true_add(json
, "installed");
8956 json_object_boolean_false_add(json
,
8959 vty_out(vty
, "SG : %s\n", vxlan_sg
->sg_str
);
8960 vty_out(vty
, " Input : %s\n", iif_name
);
8961 vty_out(vty
, " Output : %s\n", oif_name
);
8962 vty_out(vty
, " installed : %s\n",
8963 installed
?"yes":"no");
8968 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8969 json
, JSON_C_TO_STRING_PRETTY
));
8970 json_object_free(json
);
8974 DEFUN (show_ip_pim_vxlan_sg
,
8975 show_ip_pim_vxlan_sg_cmd
,
8976 "show ip pim [vrf NAME] vxlan-groups [A.B.C.D [A.B.C.D]] [json]",
8981 "VxLAN BUM groups\n"
8982 "source or group ip\n"
8986 bool uj
= use_json(argc
, argv
);
8990 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
8995 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ?
8996 argv
[idx
++]->arg
:NULL
;
8997 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
) ?
8998 argv
[idx
]->arg
:NULL
;
9000 if (src_ip
&& grp_ip
)
9001 pim_show_vxlan_sg_one(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
9003 pim_show_vxlan_sg_match_addr(vrf
->info
, vty
, src_ip
, uj
);
9005 pim_show_vxlan_sg(vrf
->info
, vty
, uj
);
9010 static void pim_show_vxlan_sg_work(struct pim_instance
*pim
,
9011 struct vty
*vty
, bool uj
)
9013 json_object
*json
= NULL
;
9014 struct pim_sg_cache_walk_data cwd
;
9015 struct listnode
*node
;
9016 struct pim_vxlan_sg
*vxlan_sg
;
9019 json
= json_object_new_object();
9021 vty_out(vty
, "Codes: I -> installed\n");
9023 "Source Group Input Flags\n");
9026 memset(&cwd
, 0, sizeof(cwd
));
9029 for (ALL_LIST_ELEMENTS_RO(pim_vxlan_p
->work_list
, node
, vxlan_sg
))
9030 pim_show_vxlan_sg_entry(vxlan_sg
, &cwd
);
9033 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9034 json
, JSON_C_TO_STRING_PRETTY
));
9035 json_object_free(json
);
9039 DEFUN_HIDDEN (show_ip_pim_vxlan_sg_work
,
9040 show_ip_pim_vxlan_sg_work_cmd
,
9041 "show ip pim [vrf NAME] vxlan-work [json]",
9049 bool uj
= use_json(argc
, argv
);
9053 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
9058 pim_show_vxlan_sg_work(vrf
->info
, vty
, uj
);
9063 DEFUN_HIDDEN (no_ip_pim_mlag
,
9071 struct in_addr addr
;
9074 pim_vxlan_mlag_update(TRUE
/*mlag_enable*/,
9075 FALSE
/*peer_state*/, PIM_VXLAN_MLAG_ROLE_SECONDARY
,
9076 NULL
/*peerlink*/, &addr
);
9081 DEFUN_HIDDEN (ip_pim_mlag
,
9083 "ip pim mlag INTERFACE role [primary|secondary] state [up|down] addr A.B.C.D",
9087 "peerlink sub interface\n"
9089 "MLAG role primary\n"
9090 "MLAG role secondary\n"
9091 "peer session state\n"
9092 "peer session state up\n"
9093 "peer session state down\n"
9095 "unique ip address\n")
9097 struct interface
*ifp
;
9098 const char *peerlink
;
9103 struct in_addr reg_addr
;
9106 peerlink
= argv
[idx
]->arg
;
9107 ifp
= if_lookup_by_name(peerlink
, VRF_DEFAULT
);
9109 vty_out(vty
, "No such interface name %s\n", peerlink
);
9114 if (!strcmp(argv
[idx
]->arg
, "primary")) {
9115 role
= PIM_VXLAN_MLAG_ROLE_PRIMARY
;
9116 } else if (!strcmp(argv
[idx
]->arg
, "secondary")) {
9117 role
= PIM_VXLAN_MLAG_ROLE_SECONDARY
;
9119 vty_out(vty
, "unknown MLAG role %s\n", argv
[idx
]->arg
);
9124 if (!strcmp(argv
[idx
]->arg
, "up")) {
9126 } else if (strcmp(argv
[idx
]->arg
, "down")) {
9129 vty_out(vty
, "unknown MLAG state %s\n", argv
[idx
]->arg
);
9134 result
= inet_pton(AF_INET
, argv
[idx
]->arg
, ®_addr
);
9136 vty_out(vty
, "%% Bad reg address %s: errno=%d: %s\n",
9138 errno
, safe_strerror(errno
));
9139 return CMD_WARNING_CONFIG_FAILED
;
9141 pim_vxlan_mlag_update(TRUE
, peer_state
, role
, ifp
, ®_addr
);
9146 void pim_cmd_init(void)
9148 install_node(&interface_node
,
9149 pim_interface_config_write
); /* INTERFACE_NODE */
9152 install_node(&debug_node
, pim_debug_config_write
);
9154 install_element(ENABLE_NODE
, &pim_test_sg_keepalive_cmd
);
9156 install_element(CONFIG_NODE
, &ip_pim_rp_cmd
);
9157 install_element(VRF_NODE
, &ip_pim_rp_cmd
);
9158 install_element(CONFIG_NODE
, &no_ip_pim_rp_cmd
);
9159 install_element(VRF_NODE
, &no_ip_pim_rp_cmd
);
9160 install_element(CONFIG_NODE
, &ip_pim_rp_prefix_list_cmd
);
9161 install_element(VRF_NODE
, &ip_pim_rp_prefix_list_cmd
);
9162 install_element(CONFIG_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
9163 install_element(VRF_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
9164 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
9165 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
9166 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
9167 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
9168 install_element(CONFIG_NODE
, &ip_pim_ssm_prefix_list_cmd
);
9169 install_element(VRF_NODE
, &ip_pim_ssm_prefix_list_cmd
);
9170 install_element(CONFIG_NODE
, &ip_pim_register_suppress_cmd
);
9171 install_element(VRF_NODE
, &ip_pim_register_suppress_cmd
);
9172 install_element(CONFIG_NODE
, &no_ip_pim_register_suppress_cmd
);
9173 install_element(VRF_NODE
, &no_ip_pim_register_suppress_cmd
);
9174 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
9175 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
9176 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
9177 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
9178 install_element(CONFIG_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
9179 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
9180 install_element(CONFIG_NODE
,
9181 &no_ip_pim_spt_switchover_infinity_plist_cmd
);
9182 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_plist_cmd
);
9183 install_element(CONFIG_NODE
, &ip_pim_joinprune_time_cmd
);
9184 install_element(VRF_NODE
, &ip_pim_joinprune_time_cmd
);
9185 install_element(CONFIG_NODE
, &no_ip_pim_joinprune_time_cmd
);
9186 install_element(VRF_NODE
, &no_ip_pim_joinprune_time_cmd
);
9187 install_element(CONFIG_NODE
, &ip_pim_keep_alive_cmd
);
9188 install_element(VRF_NODE
, &ip_pim_keep_alive_cmd
);
9189 install_element(CONFIG_NODE
, &ip_pim_rp_keep_alive_cmd
);
9190 install_element(VRF_NODE
, &ip_pim_rp_keep_alive_cmd
);
9191 install_element(CONFIG_NODE
, &no_ip_pim_keep_alive_cmd
);
9192 install_element(VRF_NODE
, &no_ip_pim_keep_alive_cmd
);
9193 install_element(CONFIG_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
9194 install_element(VRF_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
9195 install_element(CONFIG_NODE
, &ip_pim_packets_cmd
);
9196 install_element(VRF_NODE
, &ip_pim_packets_cmd
);
9197 install_element(CONFIG_NODE
, &no_ip_pim_packets_cmd
);
9198 install_element(VRF_NODE
, &no_ip_pim_packets_cmd
);
9199 install_element(CONFIG_NODE
, &ip_pim_v6_secondary_cmd
);
9200 install_element(VRF_NODE
, &ip_pim_v6_secondary_cmd
);
9201 install_element(CONFIG_NODE
, &no_ip_pim_v6_secondary_cmd
);
9202 install_element(VRF_NODE
, &no_ip_pim_v6_secondary_cmd
);
9203 install_element(CONFIG_NODE
, &ip_ssmpingd_cmd
);
9204 install_element(VRF_NODE
, &ip_ssmpingd_cmd
);
9205 install_element(CONFIG_NODE
, &no_ip_ssmpingd_cmd
);
9206 install_element(VRF_NODE
, &no_ip_ssmpingd_cmd
);
9207 install_element(CONFIG_NODE
, &ip_msdp_peer_cmd
);
9208 install_element(VRF_NODE
, &ip_msdp_peer_cmd
);
9209 install_element(CONFIG_NODE
, &no_ip_msdp_peer_cmd
);
9210 install_element(VRF_NODE
, &no_ip_msdp_peer_cmd
);
9211 install_element(CONFIG_NODE
, &ip_pim_ecmp_cmd
);
9212 install_element(VRF_NODE
, &ip_pim_ecmp_cmd
);
9213 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_cmd
);
9214 install_element(VRF_NODE
, &no_ip_pim_ecmp_cmd
);
9215 install_element(CONFIG_NODE
, &ip_pim_ecmp_rebalance_cmd
);
9216 install_element(VRF_NODE
, &ip_pim_ecmp_rebalance_cmd
);
9217 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
9218 install_element(VRF_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
9219 install_element(CONFIG_NODE
, &ip_pim_mlag_cmd
);
9220 install_element(CONFIG_NODE
, &no_ip_pim_mlag_cmd
);
9222 install_element(INTERFACE_NODE
, &interface_ip_igmp_cmd
);
9223 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_cmd
);
9224 install_element(INTERFACE_NODE
, &interface_ip_igmp_join_cmd
);
9225 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_join_cmd
);
9226 install_element(INTERFACE_NODE
, &interface_ip_igmp_version_cmd
);
9227 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_version_cmd
);
9228 install_element(INTERFACE_NODE
, &interface_ip_igmp_query_interval_cmd
);
9229 install_element(INTERFACE_NODE
,
9230 &interface_no_ip_igmp_query_interval_cmd
);
9231 install_element(INTERFACE_NODE
,
9232 &interface_ip_igmp_query_max_response_time_cmd
);
9233 install_element(INTERFACE_NODE
,
9234 &interface_no_ip_igmp_query_max_response_time_cmd
);
9235 install_element(INTERFACE_NODE
,
9236 &interface_ip_igmp_query_max_response_time_dsec_cmd
);
9237 install_element(INTERFACE_NODE
,
9238 &interface_no_ip_igmp_query_max_response_time_dsec_cmd
);
9239 install_element(INTERFACE_NODE
, &interface_ip_pim_activeactive_cmd
);
9240 install_element(INTERFACE_NODE
, &interface_ip_pim_ssm_cmd
);
9241 install_element(INTERFACE_NODE
, &interface_no_ip_pim_ssm_cmd
);
9242 install_element(INTERFACE_NODE
, &interface_ip_pim_sm_cmd
);
9243 install_element(INTERFACE_NODE
, &interface_no_ip_pim_sm_cmd
);
9244 install_element(INTERFACE_NODE
, &interface_ip_pim_cmd
);
9245 install_element(INTERFACE_NODE
, &interface_no_ip_pim_cmd
);
9246 install_element(INTERFACE_NODE
, &interface_ip_pim_drprio_cmd
);
9247 install_element(INTERFACE_NODE
, &interface_no_ip_pim_drprio_cmd
);
9248 install_element(INTERFACE_NODE
, &interface_ip_pim_hello_cmd
);
9249 install_element(INTERFACE_NODE
, &interface_no_ip_pim_hello_cmd
);
9250 install_element(INTERFACE_NODE
, &interface_ip_pim_boundary_oil_cmd
);
9251 install_element(INTERFACE_NODE
, &interface_no_ip_pim_boundary_oil_cmd
);
9253 // Static mroutes NEB
9254 install_element(INTERFACE_NODE
, &interface_ip_mroute_cmd
);
9255 install_element(INTERFACE_NODE
, &interface_ip_mroute_source_cmd
);
9256 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_cmd
);
9257 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_source_cmd
);
9259 install_element(VIEW_NODE
, &show_ip_igmp_interface_cmd
);
9260 install_element(VIEW_NODE
, &show_ip_igmp_interface_vrf_all_cmd
);
9261 install_element(VIEW_NODE
, &show_ip_igmp_join_cmd
);
9262 install_element(VIEW_NODE
, &show_ip_igmp_join_vrf_all_cmd
);
9263 install_element(VIEW_NODE
, &show_ip_igmp_groups_cmd
);
9264 install_element(VIEW_NODE
, &show_ip_igmp_groups_vrf_all_cmd
);
9265 install_element(VIEW_NODE
, &show_ip_igmp_groups_retransmissions_cmd
);
9266 install_element(VIEW_NODE
, &show_ip_igmp_sources_cmd
);
9267 install_element(VIEW_NODE
, &show_ip_igmp_sources_retransmissions_cmd
);
9268 install_element(VIEW_NODE
, &show_ip_igmp_statistics_cmd
);
9269 install_element(VIEW_NODE
, &show_ip_pim_assert_cmd
);
9270 install_element(VIEW_NODE
, &show_ip_pim_assert_internal_cmd
);
9271 install_element(VIEW_NODE
, &show_ip_pim_assert_metric_cmd
);
9272 install_element(VIEW_NODE
, &show_ip_pim_assert_winner_metric_cmd
);
9273 install_element(VIEW_NODE
, &show_ip_pim_interface_traffic_cmd
);
9274 install_element(VIEW_NODE
, &show_ip_pim_interface_cmd
);
9275 install_element(VIEW_NODE
, &show_ip_pim_interface_vrf_all_cmd
);
9276 install_element(VIEW_NODE
, &show_ip_pim_join_cmd
);
9277 install_element(VIEW_NODE
, &show_ip_pim_join_vrf_all_cmd
);
9278 install_element(VIEW_NODE
, &show_ip_pim_local_membership_cmd
);
9279 install_element(VIEW_NODE
, &show_ip_pim_neighbor_cmd
);
9280 install_element(VIEW_NODE
, &show_ip_pim_neighbor_vrf_all_cmd
);
9281 install_element(VIEW_NODE
, &show_ip_pim_rpf_cmd
);
9282 install_element(VIEW_NODE
, &show_ip_pim_rpf_vrf_all_cmd
);
9283 install_element(VIEW_NODE
, &show_ip_pim_secondary_cmd
);
9284 install_element(VIEW_NODE
, &show_ip_pim_state_cmd
);
9285 install_element(VIEW_NODE
, &show_ip_pim_state_vrf_all_cmd
);
9286 install_element(VIEW_NODE
, &show_ip_pim_upstream_cmd
);
9287 install_element(VIEW_NODE
, &show_ip_pim_upstream_vrf_all_cmd
);
9288 install_element(VIEW_NODE
, &show_ip_pim_upstream_join_desired_cmd
);
9289 install_element(VIEW_NODE
, &show_ip_pim_upstream_rpf_cmd
);
9290 install_element(VIEW_NODE
, &show_ip_pim_rp_cmd
);
9291 install_element(VIEW_NODE
, &show_ip_pim_rp_vrf_all_cmd
);
9292 install_element(VIEW_NODE
, &show_ip_multicast_cmd
);
9293 install_element(VIEW_NODE
, &show_ip_multicast_vrf_all_cmd
);
9294 install_element(VIEW_NODE
, &show_ip_mroute_cmd
);
9295 install_element(VIEW_NODE
, &show_ip_mroute_vrf_all_cmd
);
9296 install_element(VIEW_NODE
, &show_ip_mroute_count_cmd
);
9297 install_element(VIEW_NODE
, &show_ip_mroute_count_vrf_all_cmd
);
9298 install_element(VIEW_NODE
, &show_ip_rib_cmd
);
9299 install_element(VIEW_NODE
, &show_ip_ssmpingd_cmd
);
9300 install_element(VIEW_NODE
, &show_debugging_pim_cmd
);
9301 install_element(VIEW_NODE
, &show_ip_pim_nexthop_cmd
);
9302 install_element(VIEW_NODE
, &show_ip_pim_nexthop_lookup_cmd
);
9304 install_element(ENABLE_NODE
, &clear_ip_interfaces_cmd
);
9305 install_element(ENABLE_NODE
, &clear_ip_igmp_interfaces_cmd
);
9306 install_element(ENABLE_NODE
, &clear_ip_mroute_cmd
);
9307 install_element(ENABLE_NODE
, &clear_ip_pim_interfaces_cmd
);
9308 install_element(ENABLE_NODE
, &clear_ip_pim_interface_traffic_cmd
);
9309 install_element(ENABLE_NODE
, &clear_ip_pim_oil_cmd
);
9311 install_element(ENABLE_NODE
, &debug_igmp_cmd
);
9312 install_element(ENABLE_NODE
, &no_debug_igmp_cmd
);
9313 install_element(ENABLE_NODE
, &debug_igmp_events_cmd
);
9314 install_element(ENABLE_NODE
, &no_debug_igmp_events_cmd
);
9315 install_element(ENABLE_NODE
, &debug_igmp_packets_cmd
);
9316 install_element(ENABLE_NODE
, &no_debug_igmp_packets_cmd
);
9317 install_element(ENABLE_NODE
, &debug_igmp_trace_cmd
);
9318 install_element(ENABLE_NODE
, &no_debug_igmp_trace_cmd
);
9319 install_element(ENABLE_NODE
, &debug_mroute_cmd
);
9320 install_element(ENABLE_NODE
, &debug_mroute_detail_cmd
);
9321 install_element(ENABLE_NODE
, &no_debug_mroute_cmd
);
9322 install_element(ENABLE_NODE
, &no_debug_mroute_detail_cmd
);
9323 install_element(ENABLE_NODE
, &debug_pim_static_cmd
);
9324 install_element(ENABLE_NODE
, &no_debug_pim_static_cmd
);
9325 install_element(ENABLE_NODE
, &debug_pim_cmd
);
9326 install_element(ENABLE_NODE
, &no_debug_pim_cmd
);
9327 install_element(ENABLE_NODE
, &debug_pim_nht_cmd
);
9328 install_element(ENABLE_NODE
, &no_debug_pim_nht_cmd
);
9329 install_element(ENABLE_NODE
, &debug_pim_nht_rp_cmd
);
9330 install_element(ENABLE_NODE
, &no_debug_pim_nht_rp_cmd
);
9331 install_element(ENABLE_NODE
, &debug_pim_events_cmd
);
9332 install_element(ENABLE_NODE
, &no_debug_pim_events_cmd
);
9333 install_element(ENABLE_NODE
, &debug_pim_packets_cmd
);
9334 install_element(ENABLE_NODE
, &no_debug_pim_packets_cmd
);
9335 install_element(ENABLE_NODE
, &debug_pim_packetdump_send_cmd
);
9336 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_send_cmd
);
9337 install_element(ENABLE_NODE
, &debug_pim_packetdump_recv_cmd
);
9338 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_recv_cmd
);
9339 install_element(ENABLE_NODE
, &debug_pim_trace_cmd
);
9340 install_element(ENABLE_NODE
, &no_debug_pim_trace_cmd
);
9341 install_element(ENABLE_NODE
, &debug_pim_trace_detail_cmd
);
9342 install_element(ENABLE_NODE
, &no_debug_pim_trace_detail_cmd
);
9343 install_element(ENABLE_NODE
, &debug_ssmpingd_cmd
);
9344 install_element(ENABLE_NODE
, &no_debug_ssmpingd_cmd
);
9345 install_element(ENABLE_NODE
, &debug_pim_zebra_cmd
);
9346 install_element(ENABLE_NODE
, &no_debug_pim_zebra_cmd
);
9347 install_element(ENABLE_NODE
, &debug_pim_vxlan_cmd
);
9348 install_element(ENABLE_NODE
, &no_debug_pim_vxlan_cmd
);
9349 install_element(ENABLE_NODE
, &debug_msdp_cmd
);
9350 install_element(ENABLE_NODE
, &no_debug_msdp_cmd
);
9351 install_element(ENABLE_NODE
, &debug_msdp_events_cmd
);
9352 install_element(ENABLE_NODE
, &no_debug_msdp_events_cmd
);
9353 install_element(ENABLE_NODE
, &debug_msdp_packets_cmd
);
9354 install_element(ENABLE_NODE
, &no_debug_msdp_packets_cmd
);
9355 install_element(ENABLE_NODE
, &debug_mtrace_cmd
);
9356 install_element(ENABLE_NODE
, &no_debug_mtrace_cmd
);
9358 install_element(CONFIG_NODE
, &debug_igmp_cmd
);
9359 install_element(CONFIG_NODE
, &no_debug_igmp_cmd
);
9360 install_element(CONFIG_NODE
, &debug_igmp_events_cmd
);
9361 install_element(CONFIG_NODE
, &no_debug_igmp_events_cmd
);
9362 install_element(CONFIG_NODE
, &debug_igmp_packets_cmd
);
9363 install_element(CONFIG_NODE
, &no_debug_igmp_packets_cmd
);
9364 install_element(CONFIG_NODE
, &debug_igmp_trace_cmd
);
9365 install_element(CONFIG_NODE
, &no_debug_igmp_trace_cmd
);
9366 install_element(CONFIG_NODE
, &debug_mroute_cmd
);
9367 install_element(CONFIG_NODE
, &debug_mroute_detail_cmd
);
9368 install_element(CONFIG_NODE
, &no_debug_mroute_cmd
);
9369 install_element(CONFIG_NODE
, &no_debug_mroute_detail_cmd
);
9370 install_element(CONFIG_NODE
, &debug_pim_static_cmd
);
9371 install_element(CONFIG_NODE
, &no_debug_pim_static_cmd
);
9372 install_element(CONFIG_NODE
, &debug_pim_cmd
);
9373 install_element(CONFIG_NODE
, &no_debug_pim_cmd
);
9374 install_element(CONFIG_NODE
, &debug_pim_nht_cmd
);
9375 install_element(CONFIG_NODE
, &no_debug_pim_nht_cmd
);
9376 install_element(CONFIG_NODE
, &debug_pim_nht_rp_cmd
);
9377 install_element(CONFIG_NODE
, &no_debug_pim_nht_rp_cmd
);
9378 install_element(CONFIG_NODE
, &debug_pim_events_cmd
);
9379 install_element(CONFIG_NODE
, &no_debug_pim_events_cmd
);
9380 install_element(CONFIG_NODE
, &debug_pim_packets_cmd
);
9381 install_element(CONFIG_NODE
, &no_debug_pim_packets_cmd
);
9382 install_element(CONFIG_NODE
, &debug_pim_trace_cmd
);
9383 install_element(CONFIG_NODE
, &no_debug_pim_trace_cmd
);
9384 install_element(CONFIG_NODE
, &debug_pim_trace_detail_cmd
);
9385 install_element(CONFIG_NODE
, &no_debug_pim_trace_detail_cmd
);
9386 install_element(CONFIG_NODE
, &debug_ssmpingd_cmd
);
9387 install_element(CONFIG_NODE
, &no_debug_ssmpingd_cmd
);
9388 install_element(CONFIG_NODE
, &debug_pim_zebra_cmd
);
9389 install_element(CONFIG_NODE
, &no_debug_pim_zebra_cmd
);
9390 install_element(CONFIG_NODE
, &debug_pim_vxlan_cmd
);
9391 install_element(CONFIG_NODE
, &no_debug_pim_vxlan_cmd
);
9392 install_element(CONFIG_NODE
, &debug_msdp_cmd
);
9393 install_element(CONFIG_NODE
, &no_debug_msdp_cmd
);
9394 install_element(CONFIG_NODE
, &debug_msdp_events_cmd
);
9395 install_element(CONFIG_NODE
, &no_debug_msdp_events_cmd
);
9396 install_element(CONFIG_NODE
, &debug_msdp_packets_cmd
);
9397 install_element(CONFIG_NODE
, &no_debug_msdp_packets_cmd
);
9398 install_element(CONFIG_NODE
, &debug_mtrace_cmd
);
9399 install_element(CONFIG_NODE
, &no_debug_mtrace_cmd
);
9401 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_member_cmd
);
9402 install_element(VRF_NODE
, &ip_msdp_mesh_group_member_cmd
);
9403 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
9404 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
9405 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_source_cmd
);
9406 install_element(VRF_NODE
, &ip_msdp_mesh_group_source_cmd
);
9407 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
9408 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
9409 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_cmd
);
9410 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_vrf_all_cmd
);
9411 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_cmd
);
9412 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_vrf_all_cmd
);
9413 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_cmd
);
9414 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_vrf_all_cmd
);
9415 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_cmd
);
9416 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_vrf_all_cmd
);
9417 install_element(VIEW_NODE
, &show_ip_pim_ssm_range_cmd
);
9418 install_element(VIEW_NODE
, &show_ip_pim_group_type_cmd
);
9419 install_element(VIEW_NODE
, &show_ip_pim_vxlan_sg_cmd
);
9420 install_element(VIEW_NODE
, &show_ip_pim_vxlan_sg_work_cmd
);
9421 install_element(INTERFACE_NODE
, &interface_pim_use_source_cmd
);
9422 install_element(INTERFACE_NODE
, &interface_no_pim_use_source_cmd
);
9423 /* Install BFD command */
9424 install_element(INTERFACE_NODE
, &ip_pim_bfd_cmd
);
9425 install_element(INTERFACE_NODE
, &ip_pim_bfd_param_cmd
);
9426 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_cmd
);
9428 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_param_cmd
);
9429 #endif /* !HAVE_BFDD */