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
,
1210 if (!up
->rpf
.source_nexthop
.interface
)
1213 if (strcmp(ifp
->name
,
1214 up
->rpf
.source_nexthop
1219 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
))
1224 "FHR - First Hop Router\n");
1226 "----------------------\n");
1230 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
,
1232 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
,
1234 pim_time_uptime(uptime
, sizeof(uptime
),
1235 now
- up
->state_transition
);
1237 "%s : %s is a source, uptime is %s\n",
1238 grp_str
, src_str
, uptime
);
1241 if (!print_header
) {
1246 vty_out(vty
, "Hellos\n");
1247 vty_out(vty
, "------\n");
1248 vty_out(vty
, "Period : %d\n",
1249 pim_ifp
->pim_hello_period
);
1250 vty_out(vty
, "Timer : %s\n", hello_timer
);
1251 vty_out(vty
, "StatStart : %s\n", stat_uptime
);
1252 vty_out(vty
, "Receive : %d\n",
1253 pim_ifp
->pim_ifstat_hello_recv
);
1254 vty_out(vty
, "Receive Failed : %d\n",
1255 pim_ifp
->pim_ifstat_hello_recvfail
);
1256 vty_out(vty
, "Send : %d\n",
1257 pim_ifp
->pim_ifstat_hello_sent
);
1258 vty_out(vty
, "Send Failed : %d\n",
1259 pim_ifp
->pim_ifstat_hello_sendfail
);
1260 vty_out(vty
, "Generation ID : %08x\n",
1261 pim_ifp
->pim_generation_id
);
1265 pim_print_ifp_flags(vty
, ifp
, mloop
);
1267 vty_out(vty
, "Join Prune Interval\n");
1268 vty_out(vty
, "-------------------\n");
1269 vty_out(vty
, "LAN Delay : %s\n",
1270 pim_if_lan_delay_enabled(ifp
) ? "yes" : "no");
1271 vty_out(vty
, "Effective Propagation Delay : %d msec\n",
1272 pim_if_effective_propagation_delay_msec(ifp
));
1273 vty_out(vty
, "Effective Override Interval : %d msec\n",
1274 pim_if_effective_override_interval_msec(ifp
));
1275 vty_out(vty
, "Join Prune Override Interval : %d msec\n",
1276 pim_if_jp_override_interval_msec(ifp
));
1280 vty_out(vty
, "LAN Prune Delay\n");
1281 vty_out(vty
, "---------------\n");
1282 vty_out(vty
, "Propagation Delay : %d msec\n",
1283 pim_ifp
->pim_propagation_delay_msec
);
1284 vty_out(vty
, "Propagation Delay (Highest) : %d msec\n",
1285 pim_ifp
->pim_neighbors_highest_propagation_delay_msec
);
1286 vty_out(vty
, "Override Interval : %d msec\n",
1287 pim_ifp
->pim_override_interval_msec
);
1288 vty_out(vty
, "Override Interval (Highest) : %d msec\n",
1289 pim_ifp
->pim_neighbors_highest_override_interval_msec
);
1296 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1297 json
, JSON_C_TO_STRING_PRETTY
));
1298 json_object_free(json
);
1301 vty_out(vty
, "%% No such interface\n");
1305 static void igmp_show_statistics(struct pim_instance
*pim
, struct vty
*vty
,
1306 const char *ifname
, bool uj
)
1308 struct interface
*ifp
;
1309 struct igmp_stats rx_stats
;
1311 igmp_stats_init(&rx_stats
);
1313 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1314 struct pim_interface
*pim_ifp
;
1315 struct listnode
*sock_node
;
1316 struct igmp_sock
*igmp
;
1318 pim_ifp
= ifp
->info
;
1323 if (ifname
&& strcmp(ifname
, ifp
->name
))
1326 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
1328 igmp_stats_add(&rx_stats
, &igmp
->rx_stats
);
1332 json_object
*json
= NULL
;
1333 json_object
*json_row
= NULL
;
1335 json
= json_object_new_object();
1336 json_row
= json_object_new_object();
1338 json_object_string_add(json_row
, "name", ifname
? ifname
:
1340 json_object_int_add(json_row
, "queryV1", rx_stats
.query_v1
);
1341 json_object_int_add(json_row
, "queryV2", rx_stats
.query_v2
);
1342 json_object_int_add(json_row
, "queryV3", rx_stats
.query_v3
);
1343 json_object_int_add(json_row
, "leaveV3", rx_stats
.leave_v2
);
1344 json_object_int_add(json_row
, "reportV1", rx_stats
.report_v1
);
1345 json_object_int_add(json_row
, "reportV2", rx_stats
.report_v2
);
1346 json_object_int_add(json_row
, "reportV3", rx_stats
.report_v3
);
1347 json_object_int_add(json_row
, "mtraceResponse",
1348 rx_stats
.mtrace_rsp
);
1349 json_object_int_add(json_row
, "mtraceRequest",
1350 rx_stats
.mtrace_req
);
1351 json_object_int_add(json_row
, "unsupported",
1352 rx_stats
.unsupported
);
1353 json_object_object_add(json
, ifname
? ifname
: "global",
1355 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1356 json
, JSON_C_TO_STRING_PRETTY
));
1357 json_object_free(json
);
1359 vty_out(vty
, "IGMP RX statistics\n");
1360 vty_out(vty
, "Interface : %s\n",
1361 ifname
? ifname
: "global");
1362 vty_out(vty
, "V1 query : %u\n", rx_stats
.query_v1
);
1363 vty_out(vty
, "V2 query : %u\n", rx_stats
.query_v2
);
1364 vty_out(vty
, "V3 query : %u\n", rx_stats
.query_v3
);
1365 vty_out(vty
, "V2 leave : %u\n", rx_stats
.leave_v2
);
1366 vty_out(vty
, "V1 report : %u\n", rx_stats
.report_v1
);
1367 vty_out(vty
, "V2 report : %u\n", rx_stats
.report_v2
);
1368 vty_out(vty
, "V3 report : %u\n", rx_stats
.report_v3
);
1369 vty_out(vty
, "mtrace response : %u\n", rx_stats
.mtrace_rsp
);
1370 vty_out(vty
, "mtrace request : %u\n", rx_stats
.mtrace_req
);
1371 vty_out(vty
, "unsupported : %u\n", rx_stats
.unsupported
);
1375 static void pim_show_interfaces(struct pim_instance
*pim
, struct vty
*vty
,
1378 struct interface
*ifp
;
1379 struct listnode
*upnode
;
1380 struct pim_interface
*pim_ifp
;
1381 struct pim_upstream
*up
;
1384 int pim_ifchannels
= 0;
1385 json_object
*json
= NULL
;
1386 json_object
*json_row
= NULL
;
1387 json_object
*json_tmp
;
1389 json
= json_object_new_object();
1391 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1392 pim_ifp
= ifp
->info
;
1397 pim_nbrs
= pim_ifp
->pim_neighbor_list
->count
;
1398 pim_ifchannels
= pim_if_ifchannel_count(pim_ifp
);
1401 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
, up
))
1402 if (ifp
== up
->rpf
.source_nexthop
.interface
)
1403 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
1406 json_row
= json_object_new_object();
1407 json_object_pim_ifp_add(json_row
, ifp
);
1408 json_object_int_add(json_row
, "pimNeighbors", pim_nbrs
);
1409 json_object_int_add(json_row
, "pimIfChannels", pim_ifchannels
);
1410 json_object_int_add(json_row
, "firstHopRouterCount", fhr
);
1411 json_object_string_add(json_row
, "pimDesignatedRouter",
1412 inet_ntoa(pim_ifp
->pim_dr_addr
));
1414 if (pim_ifp
->pim_dr_addr
.s_addr
1415 == pim_ifp
->primary_address
.s_addr
)
1416 json_object_boolean_true_add(
1417 json_row
, "pimDesignatedRouterLocal");
1419 json_object_object_add(json
, ifp
->name
, json_row
);
1423 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1424 json
, JSON_C_TO_STRING_PRETTY
));
1427 "Interface State Address PIM Nbrs PIM DR FHR IfChannels\n");
1429 json_object_object_foreach(json
, key
, val
)
1431 vty_out(vty
, "%-16s ", key
);
1433 json_object_object_get_ex(val
, "state", &json_tmp
);
1434 vty_out(vty
, "%5s ", json_object_get_string(json_tmp
));
1436 json_object_object_get_ex(val
, "address", &json_tmp
);
1437 vty_out(vty
, "%15s ",
1438 json_object_get_string(json_tmp
));
1440 json_object_object_get_ex(val
, "pimNeighbors",
1442 vty_out(vty
, "%8d ", json_object_get_int(json_tmp
));
1444 if (json_object_object_get_ex(
1445 val
, "pimDesignatedRouterLocal",
1447 vty_out(vty
, "%15s ", "local");
1449 json_object_object_get_ex(
1450 val
, "pimDesignatedRouter", &json_tmp
);
1451 vty_out(vty
, "%15s ",
1452 json_object_get_string(json_tmp
));
1455 json_object_object_get_ex(val
, "firstHopRouter",
1457 vty_out(vty
, "%3d ", json_object_get_int(json_tmp
));
1459 json_object_object_get_ex(val
, "pimIfChannels",
1461 vty_out(vty
, "%9d\n", json_object_get_int(json_tmp
));
1465 json_object_free(json
);
1468 static void pim_show_interface_traffic(struct pim_instance
*pim
,
1469 struct vty
*vty
, bool uj
)
1471 struct interface
*ifp
= NULL
;
1472 struct pim_interface
*pim_ifp
= NULL
;
1473 json_object
*json
= NULL
;
1474 json_object
*json_row
= NULL
;
1477 json
= json_object_new_object();
1480 vty_out(vty
, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s\n",
1481 "Interface", " HELLO", " JOIN",
1482 " PRUNE", " REGISTER", "REGISTER-STOP",
1484 vty_out(vty
, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s\n", "",
1485 " Rx/Tx", " Rx/Tx", " Rx/Tx",
1486 " Rx/Tx", " Rx/Tx", " Rx/Tx");
1488 "---------------------------------------------------------------------------------------------------------------\n");
1491 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1492 pim_ifp
= ifp
->info
;
1497 if (pim_ifp
->pim_sock_fd
< 0)
1500 json_row
= json_object_new_object();
1501 json_object_pim_ifp_add(json_row
, ifp
);
1502 json_object_int_add(json_row
, "helloRx",
1503 pim_ifp
->pim_ifstat_hello_recv
);
1504 json_object_int_add(json_row
, "helloTx",
1505 pim_ifp
->pim_ifstat_hello_sent
);
1506 json_object_int_add(json_row
, "joinRx",
1507 pim_ifp
->pim_ifstat_join_recv
);
1508 json_object_int_add(json_row
, "joinTx",
1509 pim_ifp
->pim_ifstat_join_send
);
1510 json_object_int_add(json_row
, "registerRx",
1511 pim_ifp
->pim_ifstat_reg_recv
);
1512 json_object_int_add(json_row
, "registerTx",
1513 pim_ifp
->pim_ifstat_reg_recv
);
1514 json_object_int_add(json_row
, "registerStopRx",
1515 pim_ifp
->pim_ifstat_reg_stop_recv
);
1516 json_object_int_add(json_row
, "registerStopTx",
1517 pim_ifp
->pim_ifstat_reg_stop_send
);
1518 json_object_int_add(json_row
, "assertRx",
1519 pim_ifp
->pim_ifstat_assert_recv
);
1520 json_object_int_add(json_row
, "assertTx",
1521 pim_ifp
->pim_ifstat_assert_send
);
1523 json_object_object_add(json
, ifp
->name
, json_row
);
1526 "%-16s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u \n",
1527 ifp
->name
, pim_ifp
->pim_ifstat_hello_recv
,
1528 pim_ifp
->pim_ifstat_hello_sent
,
1529 pim_ifp
->pim_ifstat_join_recv
,
1530 pim_ifp
->pim_ifstat_join_send
,
1531 pim_ifp
->pim_ifstat_prune_recv
,
1532 pim_ifp
->pim_ifstat_prune_send
,
1533 pim_ifp
->pim_ifstat_reg_recv
,
1534 pim_ifp
->pim_ifstat_reg_send
,
1535 pim_ifp
->pim_ifstat_reg_stop_recv
,
1536 pim_ifp
->pim_ifstat_reg_stop_send
,
1537 pim_ifp
->pim_ifstat_assert_recv
,
1538 pim_ifp
->pim_ifstat_assert_send
);
1542 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1543 json
, JSON_C_TO_STRING_PRETTY
));
1544 json_object_free(json
);
1548 static void pim_show_interface_traffic_single(struct pim_instance
*pim
,
1550 const char *ifname
, bool uj
)
1552 struct interface
*ifp
= NULL
;
1553 struct pim_interface
*pim_ifp
= NULL
;
1554 json_object
*json
= NULL
;
1555 json_object
*json_row
= NULL
;
1556 uint8_t found_ifname
= 0;
1559 json
= json_object_new_object();
1562 vty_out(vty
, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s\n",
1563 "Interface", " HELLO", " JOIN", " PRUNE",
1564 " REGISTER", " REGISTER-STOP", " ASSERT");
1565 vty_out(vty
, "%-14s%-18s%-17s%-17s%-17s%-17s%-17s\n", "",
1566 " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1567 " Rx/Tx", " Rx/Tx");
1569 "---------------------------------------------------------------------------------------------------------------------\n");
1572 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1573 if (strcmp(ifname
, ifp
->name
))
1576 pim_ifp
= ifp
->info
;
1581 if (pim_ifp
->pim_sock_fd
< 0)
1586 json_row
= json_object_new_object();
1587 json_object_pim_ifp_add(json_row
, ifp
);
1588 json_object_int_add(json_row
, "helloRx",
1589 pim_ifp
->pim_ifstat_hello_recv
);
1590 json_object_int_add(json_row
, "helloTx",
1591 pim_ifp
->pim_ifstat_hello_sent
);
1592 json_object_int_add(json_row
, "joinRx",
1593 pim_ifp
->pim_ifstat_join_recv
);
1594 json_object_int_add(json_row
, "joinTx",
1595 pim_ifp
->pim_ifstat_join_send
);
1596 json_object_int_add(json_row
, "registerRx",
1597 pim_ifp
->pim_ifstat_reg_recv
);
1598 json_object_int_add(json_row
, "registerTx",
1599 pim_ifp
->pim_ifstat_reg_recv
);
1600 json_object_int_add(json_row
, "registerStopRx",
1601 pim_ifp
->pim_ifstat_reg_stop_recv
);
1602 json_object_int_add(json_row
, "registerStopTx",
1603 pim_ifp
->pim_ifstat_reg_stop_send
);
1604 json_object_int_add(json_row
, "assertRx",
1605 pim_ifp
->pim_ifstat_assert_recv
);
1606 json_object_int_add(json_row
, "assertTx",
1607 pim_ifp
->pim_ifstat_assert_send
);
1609 json_object_object_add(json
, ifp
->name
, json_row
);
1612 "%-16s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u \n",
1613 ifp
->name
, pim_ifp
->pim_ifstat_hello_recv
,
1614 pim_ifp
->pim_ifstat_hello_sent
,
1615 pim_ifp
->pim_ifstat_join_recv
,
1616 pim_ifp
->pim_ifstat_join_send
,
1617 pim_ifp
->pim_ifstat_prune_recv
,
1618 pim_ifp
->pim_ifstat_prune_send
,
1619 pim_ifp
->pim_ifstat_reg_recv
,
1620 pim_ifp
->pim_ifstat_reg_send
,
1621 pim_ifp
->pim_ifstat_reg_stop_recv
,
1622 pim_ifp
->pim_ifstat_reg_stop_send
,
1623 pim_ifp
->pim_ifstat_assert_recv
,
1624 pim_ifp
->pim_ifstat_assert_send
);
1628 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1629 json
, JSON_C_TO_STRING_PRETTY
));
1630 json_object_free(json
);
1633 vty_out(vty
, "%% No such interface\n");
1637 static void pim_show_join_helper(struct vty
*vty
, struct pim_interface
*pim_ifp
,
1638 struct pim_ifchannel
*ch
, json_object
*json
,
1639 time_t now
, bool uj
)
1641 char ch_src_str
[INET_ADDRSTRLEN
];
1642 char ch_grp_str
[INET_ADDRSTRLEN
];
1643 json_object
*json_iface
= NULL
;
1644 json_object
*json_row
= NULL
;
1645 json_object
*json_grp
= NULL
;
1646 struct in_addr ifaddr
;
1651 ifaddr
= pim_ifp
->primary_address
;
1653 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
1654 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
1656 pim_time_uptime_begin(uptime
, sizeof(uptime
), now
, ch
->ifjoin_creation
);
1657 pim_time_timer_to_mmss(expire
, sizeof(expire
),
1658 ch
->t_ifjoin_expiry_timer
);
1659 pim_time_timer_to_mmss(prune
, sizeof(prune
),
1660 ch
->t_ifjoin_prune_pending_timer
);
1663 json_object_object_get_ex(json
, ch
->interface
->name
,
1667 json_iface
= json_object_new_object();
1668 json_object_pim_ifp_add(json_iface
, ch
->interface
);
1669 json_object_object_add(json
, ch
->interface
->name
,
1673 json_row
= json_object_new_object();
1674 json_object_string_add(json_row
, "source", ch_src_str
);
1675 json_object_string_add(json_row
, "group", ch_grp_str
);
1676 json_object_string_add(json_row
, "upTime", uptime
);
1677 json_object_string_add(json_row
, "expire", expire
);
1678 json_object_string_add(json_row
, "prune", prune
);
1679 json_object_string_add(
1680 json_row
, "channelJoinName",
1681 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
, ch
->flags
));
1682 if (PIM_IF_FLAG_TEST_S_G_RPT(ch
->flags
))
1683 json_object_int_add(json_row
, "SGRpt", 1);
1685 json_object_object_get_ex(json_iface
, ch_grp_str
, &json_grp
);
1687 json_grp
= json_object_new_object();
1688 json_object_object_add(json_grp
, ch_src_str
, json_row
);
1689 json_object_object_add(json_iface
, ch_grp_str
,
1692 json_object_object_add(json_grp
, ch_src_str
, json_row
);
1694 vty_out(vty
, "%-16s %-15s %-15s %-15s %-10s %8s %-6s %5s\n",
1695 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
,
1697 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
, ch
->flags
),
1698 uptime
, expire
, prune
);
1702 static void pim_show_join(struct pim_instance
*pim
, struct vty
*vty
,
1703 struct prefix_sg
*sg
, bool uj
)
1705 struct pim_interface
*pim_ifp
;
1706 struct pim_ifchannel
*ch
;
1707 struct interface
*ifp
;
1709 json_object
*json
= NULL
;
1711 now
= pim_time_monotonic_sec();
1714 json
= json_object_new_object();
1717 "Interface Address Source Group State Uptime Expire Prune\n");
1719 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1720 pim_ifp
= ifp
->info
;
1724 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
1725 if (sg
->grp
.s_addr
!= 0
1726 && sg
->grp
.s_addr
!= ch
->sg
.grp
.s_addr
)
1728 if (sg
->src
.s_addr
!= 0
1729 && sg
->src
.s_addr
!= ch
->sg
.src
.s_addr
)
1731 pim_show_join_helper(vty
, pim_ifp
, ch
, json
, now
, uj
);
1732 } /* scan interface channels */
1736 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1737 json
, JSON_C_TO_STRING_PRETTY
));
1738 json_object_free(json
);
1742 static void pim_show_neighbors_single(struct pim_instance
*pim
, struct vty
*vty
,
1743 const char *neighbor
, bool uj
)
1745 struct listnode
*neighnode
;
1746 struct interface
*ifp
;
1747 struct pim_interface
*pim_ifp
;
1748 struct pim_neighbor
*neigh
;
1750 int found_neighbor
= 0;
1751 int option_address_list
;
1752 int option_dr_priority
;
1753 int option_generation_id
;
1754 int option_holdtime
;
1755 int option_lan_prune_delay
;
1759 char neigh_src_str
[INET_ADDRSTRLEN
];
1761 json_object
*json
= NULL
;
1762 json_object
*json_ifp
= NULL
;
1763 json_object
*json_row
= NULL
;
1765 now
= pim_time_monotonic_sec();
1768 json
= json_object_new_object();
1770 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1771 pim_ifp
= ifp
->info
;
1776 if (pim_ifp
->pim_sock_fd
< 0)
1779 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
1781 pim_inet4_dump("<src?>", neigh
->source_addr
,
1782 neigh_src_str
, sizeof(neigh_src_str
));
1785 * The user can specify either the interface name or the
1787 * If this pim_ifp matches neither then skip.
1789 if (strcmp(neighbor
, "detail")
1790 && strcmp(neighbor
, ifp
->name
)
1791 && strcmp(neighbor
, neigh_src_str
))
1795 pim_time_uptime(uptime
, sizeof(uptime
),
1796 now
- neigh
->creation
);
1797 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
1798 neigh
->t_expire_timer
);
1800 option_address_list
= 0;
1801 option_dr_priority
= 0;
1802 option_generation_id
= 0;
1803 option_holdtime
= 0;
1804 option_lan_prune_delay
= 0;
1807 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1808 PIM_OPTION_MASK_ADDRESS_LIST
))
1809 option_address_list
= 1;
1811 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1812 PIM_OPTION_MASK_DR_PRIORITY
))
1813 option_dr_priority
= 1;
1815 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1816 PIM_OPTION_MASK_GENERATION_ID
))
1817 option_generation_id
= 1;
1819 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1820 PIM_OPTION_MASK_HOLDTIME
))
1821 option_holdtime
= 1;
1823 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1824 PIM_OPTION_MASK_LAN_PRUNE_DELAY
))
1825 option_lan_prune_delay
= 1;
1827 if (PIM_OPTION_IS_SET(
1828 neigh
->hello_options
,
1829 PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION
))
1834 /* Does this ifp live in json? If not create
1836 json_object_object_get_ex(json
, ifp
->name
,
1840 json_ifp
= json_object_new_object();
1841 json_object_pim_ifp_add(json_ifp
, ifp
);
1842 json_object_object_add(json
, ifp
->name
,
1846 json_row
= json_object_new_object();
1847 json_object_string_add(json_row
, "interface",
1849 json_object_string_add(json_row
, "address",
1851 json_object_string_add(json_row
, "upTime",
1853 json_object_string_add(json_row
, "holdtime",
1855 json_object_int_add(json_row
, "drPriority",
1856 neigh
->dr_priority
);
1857 json_object_int_add(json_row
, "generationId",
1858 neigh
->generation_id
);
1860 if (option_address_list
)
1861 json_object_boolean_true_add(
1863 "helloOptionAddressList");
1865 if (option_dr_priority
)
1866 json_object_boolean_true_add(
1868 "helloOptionDrPriority");
1870 if (option_generation_id
)
1871 json_object_boolean_true_add(
1873 "helloOptionGenerationId");
1875 if (option_holdtime
)
1876 json_object_boolean_true_add(
1878 "helloOptionHoldtime");
1880 if (option_lan_prune_delay
)
1881 json_object_boolean_true_add(
1883 "helloOptionLanPruneDelay");
1886 json_object_boolean_true_add(
1887 json_row
, "helloOptionTBit");
1889 json_object_object_add(json_ifp
, neigh_src_str
,
1893 vty_out(vty
, "Interface : %s\n", ifp
->name
);
1894 vty_out(vty
, "Neighbor : %s\n", neigh_src_str
);
1902 " DR Priority : %d\n",
1903 neigh
->dr_priority
);
1905 " Generation ID : %08x\n",
1906 neigh
->generation_id
);
1908 " Override Interval (msec) : %d\n",
1909 neigh
->override_interval_msec
);
1911 " Propagation Delay (msec) : %d\n",
1912 neigh
->propagation_delay_msec
);
1914 " Hello Option - Address List : %s\n",
1915 option_address_list
? "yes" : "no");
1917 " Hello Option - DR Priority : %s\n",
1918 option_dr_priority
? "yes" : "no");
1920 " Hello Option - Generation ID : %s\n",
1921 option_generation_id
? "yes" : "no");
1923 " Hello Option - Holdtime : %s\n",
1924 option_holdtime
? "yes" : "no");
1926 " Hello Option - LAN Prune Delay : %s\n",
1927 option_lan_prune_delay
? "yes" : "no");
1929 " Hello Option - T-bit : %s\n",
1930 option_t_bit
? "yes" : "no");
1931 pim_bfd_show_info(vty
, neigh
->bfd_info
,
1939 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1940 json
, JSON_C_TO_STRING_PRETTY
));
1941 json_object_free(json
);
1944 if (!found_neighbor
)
1946 "%% No such interface or neighbor\n");
1951 static void pim_show_state(struct pim_instance
*pim
, struct vty
*vty
,
1952 const char *src_or_group
, const char *group
, bool uj
)
1954 struct channel_oil
*c_oil
;
1955 struct listnode
*node
;
1956 json_object
*json
= NULL
;
1957 json_object
*json_group
= NULL
;
1958 json_object
*json_ifp_in
= NULL
;
1959 json_object
*json_ifp_out
= NULL
;
1960 json_object
*json_source
= NULL
;
1963 now
= pim_time_monotonic_sec();
1966 json
= json_object_new_object();
1969 "Codes: J -> Pim Join, I -> IGMP Report, S -> Source, * -> Inherited from (*,G), V -> VxLAN");
1971 "\nInstalled Source Group IIF OIL\n");
1974 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
1975 char grp_str
[INET_ADDRSTRLEN
];
1976 char src_str
[INET_ADDRSTRLEN
];
1977 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
1978 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
1980 struct interface
*ifp_in
;
1983 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
1985 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
1987 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
1990 strcpy(in_ifname
, ifp_in
->name
);
1992 strcpy(in_ifname
, "<iif?>");
1995 if (strcmp(src_or_group
, src_str
)
1996 && strcmp(src_or_group
, grp_str
))
1999 if (group
&& strcmp(group
, grp_str
))
2005 /* Find the group, create it if it doesn't exist */
2006 json_object_object_get_ex(json
, grp_str
, &json_group
);
2009 json_group
= json_object_new_object();
2010 json_object_object_add(json
, grp_str
,
2014 /* Find the source nested under the group, create it if
2015 * it doesn't exist */
2016 json_object_object_get_ex(json_group
, src_str
,
2020 json_source
= json_object_new_object();
2021 json_object_object_add(json_group
, src_str
,
2025 /* Find the inbound interface nested under the source,
2026 * create it if it doesn't exist */
2027 json_object_object_get_ex(json_source
, in_ifname
,
2031 json_ifp_in
= json_object_new_object();
2032 json_object_object_add(json_source
, in_ifname
,
2034 json_object_int_add(json_source
, "Installed",
2036 json_object_int_add(json_source
, "RefCount",
2037 c_oil
->oil_ref_count
);
2038 json_object_int_add(json_source
, "OilListSize",
2040 json_object_int_add(
2041 json_source
, "OilRescan",
2042 c_oil
->oil_inherited_rescan
);
2043 json_object_int_add(json_source
, "LastUsed",
2044 c_oil
->cc
.lastused
);
2045 json_object_int_add(json_source
, "PacketCount",
2047 json_object_int_add(json_source
, "ByteCount",
2049 json_object_int_add(json_source
,
2051 c_oil
->cc
.wrong_if
);
2054 vty_out(vty
, "%-9d %-15s %-15s %-16s ",
2055 c_oil
->installed
, src_str
, grp_str
, in_ifname
);
2058 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
2060 struct interface
*ifp_out
;
2061 char oif_uptime
[10];
2064 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
2068 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
2070 oif_uptime
, sizeof(oif_uptime
),
2071 now
- c_oil
->oif_creation
[oif_vif_index
]);
2074 strcpy(out_ifname
, ifp_out
->name
);
2076 strcpy(out_ifname
, "<oif?>");
2079 json_ifp_out
= json_object_new_object();
2080 json_object_string_add(json_ifp_out
, "source",
2082 json_object_string_add(json_ifp_out
, "group",
2084 json_object_string_add(json_ifp_out
,
2087 json_object_string_add(json_ifp_out
,
2088 "outboundInterface",
2090 json_object_int_add(json_ifp_out
, "installed",
2093 json_object_object_add(json_ifp_in
, out_ifname
,
2098 vty_out(vty
, "%s(%c%c%c%c%c)", out_ifname
,
2099 (c_oil
->oif_flags
[oif_vif_index
]
2100 & PIM_OIF_FLAG_PROTO_IGMP
)
2103 (c_oil
->oif_flags
[oif_vif_index
]
2104 & PIM_OIF_FLAG_PROTO_PIM
)
2107 (c_oil
->oif_flags
[oif_vif_index
]
2108 & PIM_OIF_FLAG_PROTO_VXLAN
)
2111 (c_oil
->oif_flags
[oif_vif_index
]
2112 & PIM_OIF_FLAG_PROTO_SOURCE
)
2115 (c_oil
->oif_flags
[oif_vif_index
]
2116 & PIM_OIF_FLAG_PROTO_STAR
)
2120 vty_out(vty
, ", %s(%c%c%c%c%c)",
2122 (c_oil
->oif_flags
[oif_vif_index
]
2123 & PIM_OIF_FLAG_PROTO_IGMP
)
2126 (c_oil
->oif_flags
[oif_vif_index
]
2127 & PIM_OIF_FLAG_PROTO_PIM
)
2130 (c_oil
->oif_flags
[oif_vif_index
]
2131 & PIM_OIF_FLAG_PROTO_VXLAN
)
2134 (c_oil
->oif_flags
[oif_vif_index
]
2135 & PIM_OIF_FLAG_PROTO_SOURCE
)
2138 (c_oil
->oif_flags
[oif_vif_index
]
2139 & PIM_OIF_FLAG_PROTO_STAR
)
2151 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2152 json
, JSON_C_TO_STRING_PRETTY
));
2153 json_object_free(json
);
2159 static void pim_show_neighbors(struct pim_instance
*pim
, struct vty
*vty
,
2162 struct listnode
*neighnode
;
2163 struct interface
*ifp
;
2164 struct pim_interface
*pim_ifp
;
2165 struct pim_neighbor
*neigh
;
2169 char neigh_src_str
[INET_ADDRSTRLEN
];
2170 json_object
*json
= NULL
;
2171 json_object
*json_ifp_rows
= NULL
;
2172 json_object
*json_row
= NULL
;
2174 now
= pim_time_monotonic_sec();
2177 json
= json_object_new_object();
2180 "Interface Neighbor Uptime Holdtime DR Pri\n");
2183 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2184 pim_ifp
= ifp
->info
;
2189 if (pim_ifp
->pim_sock_fd
< 0)
2193 json_ifp_rows
= json_object_new_object();
2195 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
2197 pim_inet4_dump("<src?>", neigh
->source_addr
,
2198 neigh_src_str
, sizeof(neigh_src_str
));
2199 pim_time_uptime(uptime
, sizeof(uptime
),
2200 now
- neigh
->creation
);
2201 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
2202 neigh
->t_expire_timer
);
2205 json_row
= json_object_new_object();
2206 json_object_string_add(json_row
, "interface",
2208 json_object_string_add(json_row
, "neighbor",
2210 json_object_string_add(json_row
, "upTime",
2212 json_object_string_add(json_row
, "holdTime",
2214 json_object_int_add(json_row
, "holdTimeMax",
2216 json_object_int_add(json_row
, "drPriority",
2217 neigh
->dr_priority
);
2218 json_object_object_add(json_ifp_rows
,
2219 neigh_src_str
, json_row
);
2222 vty_out(vty
, "%-16s %15s %8s %8s %6d\n",
2223 ifp
->name
, neigh_src_str
, uptime
,
2224 expire
, neigh
->dr_priority
);
2229 json_object_object_add(json
, ifp
->name
, json_ifp_rows
);
2230 json_ifp_rows
= NULL
;
2235 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2236 json
, JSON_C_TO_STRING_PRETTY
));
2237 json_object_free(json
);
2241 static void pim_show_neighbors_secondary(struct pim_instance
*pim
,
2244 struct interface
*ifp
;
2247 "Interface Address Neighbor Secondary \n");
2249 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2250 struct pim_interface
*pim_ifp
;
2251 struct in_addr ifaddr
;
2252 struct listnode
*neighnode
;
2253 struct pim_neighbor
*neigh
;
2255 pim_ifp
= ifp
->info
;
2260 if (pim_ifp
->pim_sock_fd
< 0)
2263 ifaddr
= pim_ifp
->primary_address
;
2265 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
2267 char neigh_src_str
[INET_ADDRSTRLEN
];
2268 struct listnode
*prefix_node
;
2271 if (!neigh
->prefix_list
)
2274 pim_inet4_dump("<src?>", neigh
->source_addr
,
2275 neigh_src_str
, sizeof(neigh_src_str
));
2277 for (ALL_LIST_ELEMENTS_RO(neigh
->prefix_list
,
2279 char neigh_sec_str
[PREFIX2STR_BUFFER
];
2281 prefix2str(p
, neigh_sec_str
,
2282 sizeof(neigh_sec_str
));
2284 vty_out(vty
, "%-16s %-15s %-15s %-15s\n",
2285 ifp
->name
, inet_ntoa(ifaddr
),
2286 neigh_src_str
, neigh_sec_str
);
2292 static void json_object_pim_upstream_add(json_object
*json
,
2293 struct pim_upstream
*up
)
2295 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED
)
2296 json_object_boolean_true_add(json
, "drJoinDesired");
2298 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED
)
2299 json_object_boolean_true_add(json
, "drJoinDesiredUpdated");
2301 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
2302 json_object_boolean_true_add(json
, "firstHopRouter");
2304 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_IGMP
)
2305 json_object_boolean_true_add(json
, "sourceIgmp");
2307 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_PIM
)
2308 json_object_boolean_true_add(json
, "sourcePim");
2310 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_STREAM
)
2311 json_object_boolean_true_add(json
, "sourceStream");
2313 /* XXX: need to print ths flag in the plain text display as well */
2314 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_MSDP
)
2315 json_object_boolean_true_add(json
, "sourceMsdp");
2317 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SEND_SG_RPT_PRUNE
)
2318 json_object_boolean_true_add(json
, "sendSGRptPrune");
2320 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_LHR
)
2321 json_object_boolean_true_add(json
, "lastHopRouter");
2323 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DISABLE_KAT_EXPIRY
)
2324 json_object_boolean_true_add(json
, "disableKATExpiry");
2326 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_STATIC_IIF
)
2327 json_object_boolean_true_add(json
, "staticIncomingInterface");
2329 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_ALLOW_IIF_IN_OIL
)
2330 json_object_boolean_true_add(json
,
2331 "allowIncomingInterfaceinOil");
2333 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_NO_PIMREG_DATA
)
2334 json_object_boolean_true_add(json
, "noPimRegistrationData");
2336 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FORCE_PIMREG
)
2337 json_object_boolean_true_add(json
, "forcePimRegistration");
2339 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_ORIG
)
2340 json_object_boolean_true_add(json
, "sourceVxlanOrigination");
2342 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_TERM
)
2343 json_object_boolean_true_add(json
, "sourceVxlanTermination");
2345 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_VXLAN
)
2346 json_object_boolean_true_add(json
, "mlagVxlan");
2348 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_NON_DF
)
2349 json_object_boolean_true_add(json
,
2350 "mlagNonDesignatedForwarder");
2354 pim_upstream_state2brief_str(enum pim_upstream_state join_state
,
2357 switch (join_state
) {
2358 case PIM_UPSTREAM_NOTJOINED
:
2359 strcpy(state_str
, "NotJ");
2361 case PIM_UPSTREAM_JOINED
:
2362 strcpy(state_str
, "J");
2365 strcpy(state_str
, "Unk");
2370 static const char *pim_reg_state2brief_str(enum pim_reg_state reg_state
,
2373 switch (reg_state
) {
2374 case PIM_REG_NOINFO
:
2375 strcpy(state_str
, "RegNI");
2378 strcpy(state_str
, "RegJ");
2380 case PIM_REG_JOIN_PENDING
:
2382 strcpy(state_str
, "RegP");
2385 strcpy(state_str
, "Unk");
2390 static void pim_show_upstream(struct pim_instance
*pim
, struct vty
*vty
,
2391 struct prefix_sg
*sg
, bool uj
)
2393 struct listnode
*upnode
;
2394 struct pim_upstream
*up
;
2396 json_object
*json
= NULL
;
2397 json_object
*json_group
= NULL
;
2398 json_object
*json_row
= NULL
;
2400 now
= pim_time_monotonic_sec();
2403 json
= json_object_new_object();
2406 "Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt\n");
2408 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
, up
)) {
2409 char src_str
[INET_ADDRSTRLEN
];
2410 char grp_str
[INET_ADDRSTRLEN
];
2412 char join_timer
[10];
2415 char msdp_reg_timer
[10];
2416 char state_str
[PIM_REG_STATE_STR_LEN
];
2418 if (sg
->grp
.s_addr
!= 0 && sg
->grp
.s_addr
!= up
->sg
.grp
.s_addr
)
2420 if (sg
->src
.s_addr
!= 0 && sg
->src
.s_addr
!= up
->sg
.src
.s_addr
)
2423 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2424 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2425 pim_time_uptime(uptime
, sizeof(uptime
),
2426 now
- up
->state_transition
);
2427 pim_time_timer_to_hhmmss(join_timer
, sizeof(join_timer
),
2431 * If the upstream is not dummy and it has a J/P timer for the
2432 * neighbor display that
2434 if (!up
->t_join_timer
&& up
->rpf
.source_nexthop
.interface
) {
2435 struct pim_neighbor
*nbr
;
2437 nbr
= pim_neighbor_find(
2438 up
->rpf
.source_nexthop
.interface
,
2439 up
->rpf
.rpf_addr
.u
.prefix4
);
2441 pim_time_timer_to_hhmmss(join_timer
,
2446 pim_time_timer_to_hhmmss(rs_timer
, sizeof(rs_timer
),
2448 pim_time_timer_to_hhmmss(ka_timer
, sizeof(ka_timer
),
2450 pim_time_timer_to_hhmmss(msdp_reg_timer
, sizeof(msdp_reg_timer
),
2451 up
->t_msdp_reg_timer
);
2453 pim_upstream_state2brief_str(up
->join_state
, state_str
);
2454 if (up
->reg_state
!= PIM_REG_NOINFO
) {
2455 char tmp_str
[PIM_REG_STATE_STR_LEN
];
2457 sprintf(state_str
+ strlen(state_str
), ",%s",
2458 pim_reg_state2brief_str(up
->reg_state
,
2463 json_object_object_get_ex(json
, grp_str
, &json_group
);
2466 json_group
= json_object_new_object();
2467 json_object_object_add(json
, grp_str
,
2471 json_row
= json_object_new_object();
2472 json_object_pim_upstream_add(json_row
, up
);
2473 json_object_string_add(
2474 json_row
, "inboundInterface",
2475 up
->rpf
.source_nexthop
.interface
2476 ? up
->rpf
.source_nexthop
.interface
->name
2480 * The RPF address we use is slightly different
2481 * based upon what we are looking up.
2482 * If we have a S, list that unless
2483 * we are the FHR, else we just put
2484 * the RP as the rpfAddress
2486 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
2487 || up
->sg
.src
.s_addr
== INADDR_ANY
) {
2488 char rpf
[PREFIX_STRLEN
];
2489 struct pim_rpf
*rpg
;
2491 rpg
= RP(pim
, up
->sg
.grp
);
2492 pim_inet4_dump("<rpf?>",
2493 rpg
->rpf_addr
.u
.prefix4
, rpf
,
2495 json_object_string_add(json_row
, "rpfAddress",
2498 json_object_string_add(json_row
, "rpfAddress",
2502 json_object_string_add(json_row
, "source", src_str
);
2503 json_object_string_add(json_row
, "group", grp_str
);
2504 json_object_string_add(json_row
, "state", state_str
);
2505 json_object_string_add(
2506 json_row
, "joinState",
2507 pim_upstream_state2str(up
->join_state
));
2508 json_object_string_add(
2509 json_row
, "regState",
2510 pim_reg_state2str(up
->reg_state
, state_str
));
2511 json_object_string_add(json_row
, "upTime", uptime
);
2512 json_object_string_add(json_row
, "joinTimer",
2514 json_object_string_add(json_row
, "resetTimer",
2516 json_object_string_add(json_row
, "keepaliveTimer",
2518 json_object_string_add(json_row
, "msdpRegTimer",
2520 json_object_int_add(json_row
, "refCount",
2522 json_object_int_add(json_row
, "sptBit", up
->sptbit
);
2523 json_object_object_add(json_group
, src_str
, json_row
);
2526 "%-16s%-15s %-15s %-11s %-8s %-9s %-9s %-9s %6d\n",
2527 up
->rpf
.source_nexthop
.interface
2528 ? up
->rpf
.source_nexthop
.interface
->name
2530 src_str
, grp_str
, state_str
, uptime
, join_timer
,
2531 rs_timer
, ka_timer
, up
->ref_count
);
2536 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2537 json
, JSON_C_TO_STRING_PRETTY
));
2538 json_object_free(json
);
2542 static void pim_show_join_desired_helper(struct pim_instance
*pim
,
2544 struct pim_interface
*pim_ifp
,
2545 struct pim_ifchannel
*ch
,
2546 json_object
*json
, bool uj
)
2548 struct pim_upstream
*up
= ch
->upstream
;
2549 json_object
*json_group
= NULL
;
2550 char src_str
[INET_ADDRSTRLEN
];
2551 char grp_str
[INET_ADDRSTRLEN
];
2552 json_object
*json_row
= NULL
;
2554 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2555 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2558 json_object_object_get_ex(json
, grp_str
, &json_group
);
2561 json_group
= json_object_new_object();
2562 json_object_object_add(json
, grp_str
, json_group
);
2565 json_row
= json_object_new_object();
2566 json_object_pim_upstream_add(json_row
, up
);
2567 json_object_string_add(json_row
, "interface",
2568 ch
->interface
->name
);
2569 json_object_string_add(json_row
, "source", src_str
);
2570 json_object_string_add(json_row
, "group", grp_str
);
2572 if (pim_macro_ch_lost_assert(ch
))
2573 json_object_boolean_true_add(json_row
, "lostAssert");
2575 if (pim_macro_chisin_joins(ch
))
2576 json_object_boolean_true_add(json_row
, "joins");
2578 if (pim_macro_chisin_pim_include(ch
))
2579 json_object_boolean_true_add(json_row
, "pimInclude");
2581 if (pim_upstream_evaluate_join_desired(pim
, up
))
2582 json_object_boolean_true_add(json_row
,
2583 "evaluateJoinDesired");
2585 json_object_object_add(json_group
, src_str
, json_row
);
2588 vty_out(vty
, "%-16s %-15s %-15s %-10s %-5s %-10s %-11s %-6s\n",
2589 ch
->interface
->name
, src_str
, grp_str
,
2590 pim_macro_ch_lost_assert(ch
) ? "yes" : "no",
2591 pim_macro_chisin_joins(ch
) ? "yes" : "no",
2592 pim_macro_chisin_pim_include(ch
) ? "yes" : "no",
2593 PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(up
->flags
)
2596 pim_upstream_evaluate_join_desired(pim
, up
) ? "yes"
2601 static void pim_show_join_desired(struct pim_instance
*pim
, struct vty
*vty
,
2604 struct pim_interface
*pim_ifp
;
2605 struct pim_ifchannel
*ch
;
2606 struct interface
*ifp
;
2608 json_object
*json
= NULL
;
2611 json
= json_object_new_object();
2614 "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD\n");
2616 /* scan per-interface (S,G) state */
2617 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2618 pim_ifp
= ifp
->info
;
2623 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
2624 /* scan all interfaces */
2625 pim_show_join_desired_helper(pim
, vty
, pim_ifp
, ch
,
2631 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2632 json
, JSON_C_TO_STRING_PRETTY
));
2633 json_object_free(json
);
2637 static void pim_show_upstream_rpf(struct pim_instance
*pim
, struct vty
*vty
,
2640 struct listnode
*upnode
;
2641 struct pim_upstream
*up
;
2642 json_object
*json
= NULL
;
2643 json_object
*json_group
= NULL
;
2644 json_object
*json_row
= NULL
;
2647 json
= json_object_new_object();
2650 "Source Group RpfIface RibNextHop RpfAddress \n");
2652 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
, up
)) {
2653 char src_str
[INET_ADDRSTRLEN
];
2654 char grp_str
[INET_ADDRSTRLEN
];
2655 char rpf_nexthop_str
[PREFIX_STRLEN
];
2656 char rpf_addr_str
[PREFIX_STRLEN
];
2657 struct pim_rpf
*rpf
;
2658 const char *rpf_ifname
;
2662 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2663 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2664 pim_addr_dump("<nexthop?>",
2665 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2666 rpf_nexthop_str
, sizeof(rpf_nexthop_str
));
2667 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2668 sizeof(rpf_addr_str
));
2670 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2673 json_object_object_get_ex(json
, grp_str
, &json_group
);
2676 json_group
= json_object_new_object();
2677 json_object_object_add(json
, grp_str
,
2681 json_row
= json_object_new_object();
2682 json_object_pim_upstream_add(json_row
, up
);
2683 json_object_string_add(json_row
, "source", src_str
);
2684 json_object_string_add(json_row
, "group", grp_str
);
2685 json_object_string_add(json_row
, "rpfInterface",
2687 json_object_string_add(json_row
, "ribNexthop",
2689 json_object_string_add(json_row
, "rpfAddress",
2691 json_object_object_add(json_group
, src_str
, json_row
);
2693 vty_out(vty
, "%-15s %-15s %-16s %-15s %-15s\n", src_str
,
2694 grp_str
, rpf_ifname
, rpf_nexthop_str
,
2700 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2701 json
, JSON_C_TO_STRING_PRETTY
));
2702 json_object_free(json
);
2706 static void show_rpf_refresh_stats(struct vty
*vty
, struct pim_instance
*pim
,
2707 time_t now
, json_object
*json
)
2709 char refresh_uptime
[10];
2711 pim_time_uptime_begin(refresh_uptime
, sizeof(refresh_uptime
), now
,
2712 pim
->rpf_cache_refresh_last
);
2715 json_object_int_add(json
, "rpfCacheRefreshDelayMsecs",
2716 router
->rpf_cache_refresh_delay_msec
);
2717 json_object_int_add(
2718 json
, "rpfCacheRefreshTimer",
2719 pim_time_timer_remain_msec(pim
->rpf_cache_refresher
));
2720 json_object_int_add(json
, "rpfCacheRefreshRequests",
2721 pim
->rpf_cache_refresh_requests
);
2722 json_object_int_add(json
, "rpfCacheRefreshEvents",
2723 pim
->rpf_cache_refresh_events
);
2724 json_object_string_add(json
, "rpfCacheRefreshLast",
2726 json_object_int_add(json
, "nexthopLookups",
2727 pim
->nexthop_lookups
);
2728 json_object_int_add(json
, "nexthopLookupsAvoided",
2729 pim
->nexthop_lookups_avoided
);
2732 "RPF Cache Refresh Delay: %ld msecs\n"
2733 "RPF Cache Refresh Timer: %ld msecs\n"
2734 "RPF Cache Refresh Requests: %lld\n"
2735 "RPF Cache Refresh Events: %lld\n"
2736 "RPF Cache Refresh Last: %s\n"
2737 "Nexthop Lookups: %lld\n"
2738 "Nexthop Lookups Avoided: %lld\n",
2739 router
->rpf_cache_refresh_delay_msec
,
2740 pim_time_timer_remain_msec(pim
->rpf_cache_refresher
),
2741 (long long)pim
->rpf_cache_refresh_requests
,
2742 (long long)pim
->rpf_cache_refresh_events
,
2743 refresh_uptime
, (long long)pim
->nexthop_lookups
,
2744 (long long)pim
->nexthop_lookups_avoided
);
2748 static void show_scan_oil_stats(struct pim_instance
*pim
, struct vty
*vty
,
2751 char uptime_scan_oil
[10];
2752 char uptime_mroute_add
[10];
2753 char uptime_mroute_del
[10];
2755 pim_time_uptime_begin(uptime_scan_oil
, sizeof(uptime_scan_oil
), now
,
2756 pim
->scan_oil_last
);
2757 pim_time_uptime_begin(uptime_mroute_add
, sizeof(uptime_mroute_add
), now
,
2758 pim
->mroute_add_last
);
2759 pim_time_uptime_begin(uptime_mroute_del
, sizeof(uptime_mroute_del
), now
,
2760 pim
->mroute_del_last
);
2763 "Scan OIL - Last: %s Events: %lld\n"
2764 "MFC Add - Last: %s Events: %lld\n"
2765 "MFC Del - Last: %s Events: %lld\n",
2766 uptime_scan_oil
, (long long)pim
->scan_oil_events
,
2767 uptime_mroute_add
, (long long)pim
->mroute_add_events
,
2768 uptime_mroute_del
, (long long)pim
->mroute_del_events
);
2771 static void pim_show_rpf(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
2773 struct listnode
*up_node
;
2774 struct pim_upstream
*up
;
2775 time_t now
= pim_time_monotonic_sec();
2776 json_object
*json
= NULL
;
2777 json_object
*json_group
= NULL
;
2778 json_object
*json_row
= NULL
;
2781 json
= json_object_new_object();
2782 show_rpf_refresh_stats(vty
, pim
, now
, json
);
2784 show_rpf_refresh_stats(vty
, pim
, now
, json
);
2787 "Source Group RpfIface RpfAddress RibNextHop Metric Pref\n");
2790 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, up_node
, up
)) {
2791 char src_str
[INET_ADDRSTRLEN
];
2792 char grp_str
[INET_ADDRSTRLEN
];
2793 char rpf_addr_str
[PREFIX_STRLEN
];
2794 char rib_nexthop_str
[PREFIX_STRLEN
];
2795 const char *rpf_ifname
;
2796 struct pim_rpf
*rpf
= &up
->rpf
;
2798 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2799 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2800 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2801 sizeof(rpf_addr_str
));
2802 pim_addr_dump("<nexthop?>",
2803 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2804 rib_nexthop_str
, sizeof(rib_nexthop_str
));
2806 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2809 json_object_object_get_ex(json
, grp_str
, &json_group
);
2812 json_group
= json_object_new_object();
2813 json_object_object_add(json
, grp_str
,
2817 json_row
= json_object_new_object();
2818 json_object_string_add(json_row
, "source", src_str
);
2819 json_object_string_add(json_row
, "group", grp_str
);
2820 json_object_string_add(json_row
, "rpfInterface",
2822 json_object_string_add(json_row
, "rpfAddress",
2824 json_object_string_add(json_row
, "ribNexthop",
2826 json_object_int_add(
2827 json_row
, "routeMetric",
2828 rpf
->source_nexthop
.mrib_route_metric
);
2829 json_object_int_add(
2830 json_row
, "routePreference",
2831 rpf
->source_nexthop
.mrib_metric_preference
);
2832 json_object_object_add(json_group
, src_str
, json_row
);
2835 vty_out(vty
, "%-15s %-15s %-16s %-15s %-15s %6d %4d\n",
2836 src_str
, grp_str
, rpf_ifname
, rpf_addr_str
,
2838 rpf
->source_nexthop
.mrib_route_metric
,
2839 rpf
->source_nexthop
.mrib_metric_preference
);
2844 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2845 json
, JSON_C_TO_STRING_PRETTY
));
2846 json_object_free(json
);
2850 struct pnc_cache_walk_data
{
2852 struct pim_instance
*pim
;
2855 static int pim_print_pnc_cache_walkcb(struct hash_bucket
*bucket
, void *arg
)
2857 struct pim_nexthop_cache
*pnc
= bucket
->data
;
2858 struct pnc_cache_walk_data
*cwd
= arg
;
2859 struct vty
*vty
= cwd
->vty
;
2860 struct pim_instance
*pim
= cwd
->pim
;
2861 struct nexthop
*nh_node
= NULL
;
2862 ifindex_t first_ifindex
;
2863 struct interface
*ifp
= NULL
;
2865 for (nh_node
= pnc
->nexthop
; nh_node
; nh_node
= nh_node
->next
) {
2866 first_ifindex
= nh_node
->ifindex
;
2867 ifp
= if_lookup_by_index(first_ifindex
, pim
->vrf_id
);
2869 vty_out(vty
, "%-15s ", inet_ntoa(pnc
->rpf
.rpf_addr
.u
.prefix4
));
2870 vty_out(vty
, "%-16s ", ifp
? ifp
->name
: "NULL");
2871 vty_out(vty
, "%s ", inet_ntoa(nh_node
->gate
.ipv4
));
2877 static void pim_show_nexthop(struct pim_instance
*pim
, struct vty
*vty
)
2879 struct pnc_cache_walk_data cwd
;
2883 vty_out(vty
, "Number of registered addresses: %lu\n",
2884 pim
->rpf_hash
->count
);
2885 vty_out(vty
, "Address Interface Nexthop\n");
2886 vty_out(vty
, "---------------------------------------------\n");
2888 hash_walk(pim
->rpf_hash
, pim_print_pnc_cache_walkcb
, &cwd
);
2891 static void igmp_show_groups(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
2893 struct interface
*ifp
;
2895 json_object
*json
= NULL
;
2896 json_object
*json_iface
= NULL
;
2897 json_object
*json_row
= NULL
;
2899 now
= pim_time_monotonic_sec();
2902 json
= json_object_new_object();
2905 "Interface Address Group Mode Timer Srcs V Uptime \n");
2907 /* scan interfaces */
2908 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2909 struct pim_interface
*pim_ifp
= ifp
->info
;
2910 struct listnode
*sock_node
;
2911 struct igmp_sock
*igmp
;
2916 /* scan igmp sockets */
2917 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
2919 char ifaddr_str
[INET_ADDRSTRLEN
];
2920 struct listnode
*grpnode
;
2921 struct igmp_group
*grp
;
2923 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
2924 sizeof(ifaddr_str
));
2926 /* scan igmp groups */
2927 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
2929 char group_str
[INET_ADDRSTRLEN
];
2933 pim_inet4_dump("<group?>", grp
->group_addr
,
2934 group_str
, sizeof(group_str
));
2935 pim_time_timer_to_hhmmss(hhmmss
, sizeof(hhmmss
),
2936 grp
->t_group_timer
);
2937 pim_time_uptime(uptime
, sizeof(uptime
),
2938 now
- grp
->group_creation
);
2941 json_object_object_get_ex(
2942 json
, ifp
->name
, &json_iface
);
2946 json_object_new_object();
2947 json_object_pim_ifp_add(
2949 json_object_object_add(
2954 json_row
= json_object_new_object();
2955 json_object_string_add(
2956 json_row
, "source", ifaddr_str
);
2957 json_object_string_add(
2958 json_row
, "group", group_str
);
2960 if (grp
->igmp_version
== 3)
2961 json_object_string_add(
2963 grp
->group_filtermode_isexcl
2967 json_object_string_add(json_row
,
2969 json_object_int_add(
2970 json_row
, "sourcesCount",
2971 grp
->group_source_list
2973 grp
->group_source_list
)
2975 json_object_int_add(json_row
, "version",
2977 json_object_string_add(
2978 json_row
, "uptime", uptime
);
2979 json_object_object_add(json_iface
,
2985 "%-16s %-15s %-15s %4s %8s %4d %d %8s\n",
2986 ifp
->name
, ifaddr_str
,
2988 grp
->igmp_version
== 3
2989 ? (grp
->group_filtermode_isexcl
2994 grp
->group_source_list
2996 grp
->group_source_list
)
2998 grp
->igmp_version
, uptime
);
3000 } /* scan igmp groups */
3001 } /* scan igmp sockets */
3002 } /* scan interfaces */
3005 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3006 json
, JSON_C_TO_STRING_PRETTY
));
3007 json_object_free(json
);
3011 static void igmp_show_group_retransmission(struct pim_instance
*pim
,
3014 struct interface
*ifp
;
3017 "Interface Address Group RetTimer Counter RetSrcs\n");
3019 /* scan interfaces */
3020 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3021 struct pim_interface
*pim_ifp
= ifp
->info
;
3022 struct listnode
*sock_node
;
3023 struct igmp_sock
*igmp
;
3028 /* scan igmp sockets */
3029 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3031 char ifaddr_str
[INET_ADDRSTRLEN
];
3032 struct listnode
*grpnode
;
3033 struct igmp_group
*grp
;
3035 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3036 sizeof(ifaddr_str
));
3038 /* scan igmp groups */
3039 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3041 char group_str
[INET_ADDRSTRLEN
];
3042 char grp_retr_mmss
[10];
3043 struct listnode
*src_node
;
3044 struct igmp_source
*src
;
3045 int grp_retr_sources
= 0;
3047 pim_inet4_dump("<group?>", grp
->group_addr
,
3048 group_str
, sizeof(group_str
));
3049 pim_time_timer_to_mmss(
3050 grp_retr_mmss
, sizeof(grp_retr_mmss
),
3051 grp
->t_group_query_retransmit_timer
);
3054 /* count group sources with retransmission state
3056 for (ALL_LIST_ELEMENTS_RO(
3057 grp
->group_source_list
, src_node
,
3059 if (src
->source_query_retransmit_count
3065 vty_out(vty
, "%-16s %-15s %-15s %-8s %7d %7d\n",
3066 ifp
->name
, ifaddr_str
, group_str
,
3068 grp
->group_specific_query_retransmit_count
,
3071 } /* scan igmp groups */
3072 } /* scan igmp sockets */
3073 } /* scan interfaces */
3076 static void igmp_show_sources(struct pim_instance
*pim
, struct vty
*vty
)
3078 struct interface
*ifp
;
3081 now
= pim_time_monotonic_sec();
3084 "Interface Address Group Source Timer Fwd Uptime \n");
3086 /* scan interfaces */
3087 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3088 struct pim_interface
*pim_ifp
= ifp
->info
;
3089 struct listnode
*sock_node
;
3090 struct igmp_sock
*igmp
;
3095 /* scan igmp sockets */
3096 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3098 char ifaddr_str
[INET_ADDRSTRLEN
];
3099 struct listnode
*grpnode
;
3100 struct igmp_group
*grp
;
3102 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3103 sizeof(ifaddr_str
));
3105 /* scan igmp groups */
3106 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3108 char group_str
[INET_ADDRSTRLEN
];
3109 struct listnode
*srcnode
;
3110 struct igmp_source
*src
;
3112 pim_inet4_dump("<group?>", grp
->group_addr
,
3113 group_str
, sizeof(group_str
));
3115 /* scan group sources */
3116 for (ALL_LIST_ELEMENTS_RO(
3117 grp
->group_source_list
, srcnode
,
3119 char source_str
[INET_ADDRSTRLEN
];
3124 "<source?>", src
->source_addr
,
3125 source_str
, sizeof(source_str
));
3127 pim_time_timer_to_mmss(
3129 src
->t_source_timer
);
3132 uptime
, sizeof(uptime
),
3133 now
- src
->source_creation
);
3136 "%-16s %-15s %-15s %-15s %5s %3s %8s\n",
3137 ifp
->name
, ifaddr_str
,
3138 group_str
, source_str
, mmss
,
3139 IGMP_SOURCE_TEST_FORWARDING(
3145 } /* scan group sources */
3146 } /* scan igmp groups */
3147 } /* scan igmp sockets */
3148 } /* scan interfaces */
3151 static void igmp_show_source_retransmission(struct pim_instance
*pim
,
3154 struct interface
*ifp
;
3157 "Interface Address Group Source Counter\n");
3159 /* scan interfaces */
3160 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3161 struct pim_interface
*pim_ifp
= ifp
->info
;
3162 struct listnode
*sock_node
;
3163 struct igmp_sock
*igmp
;
3168 /* scan igmp sockets */
3169 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3171 char ifaddr_str
[INET_ADDRSTRLEN
];
3172 struct listnode
*grpnode
;
3173 struct igmp_group
*grp
;
3175 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3176 sizeof(ifaddr_str
));
3178 /* scan igmp groups */
3179 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3181 char group_str
[INET_ADDRSTRLEN
];
3182 struct listnode
*srcnode
;
3183 struct igmp_source
*src
;
3185 pim_inet4_dump("<group?>", grp
->group_addr
,
3186 group_str
, sizeof(group_str
));
3188 /* scan group sources */
3189 for (ALL_LIST_ELEMENTS_RO(
3190 grp
->group_source_list
, srcnode
,
3192 char source_str
[INET_ADDRSTRLEN
];
3195 "<source?>", src
->source_addr
,
3196 source_str
, sizeof(source_str
));
3199 "%-16s %-15s %-15s %-15s %7d\n",
3200 ifp
->name
, ifaddr_str
,
3201 group_str
, source_str
,
3202 src
->source_query_retransmit_count
);
3204 } /* scan group sources */
3205 } /* scan igmp groups */
3206 } /* scan igmp sockets */
3207 } /* scan interfaces */
3210 static void clear_igmp_interfaces(struct pim_instance
*pim
)
3212 struct interface
*ifp
;
3214 FOR_ALL_INTERFACES (pim
->vrf
, ifp
)
3215 pim_if_addr_del_all_igmp(ifp
);
3217 FOR_ALL_INTERFACES (pim
->vrf
, ifp
)
3218 pim_if_addr_add_all(ifp
);
3221 static void clear_pim_interfaces(struct pim_instance
*pim
)
3223 struct interface
*ifp
;
3225 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3227 pim_neighbor_delete_all(ifp
, "interface cleared");
3232 static void clear_interfaces(struct pim_instance
*pim
)
3234 clear_igmp_interfaces(pim
);
3235 clear_pim_interfaces(pim
);
3238 #define PIM_GET_PIM_INTERFACE(pim_ifp, ifp) \
3239 pim_ifp = ifp->info; \
3242 "%% Enable PIM and/or IGMP on this interface first\n"); \
3243 return CMD_WARNING_CONFIG_FAILED; \
3246 DEFUN (clear_ip_interfaces
,
3247 clear_ip_interfaces_cmd
,
3248 "clear ip interfaces [vrf NAME]",
3251 "Reset interfaces\n"
3255 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3260 clear_interfaces(vrf
->info
);
3265 DEFUN (clear_ip_igmp_interfaces
,
3266 clear_ip_igmp_interfaces_cmd
,
3267 "clear ip igmp [vrf NAME] interfaces",
3272 "Reset IGMP interfaces\n")
3275 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3280 clear_igmp_interfaces(vrf
->info
);
3285 static void mroute_add_all(struct pim_instance
*pim
)
3287 struct listnode
*node
;
3288 struct channel_oil
*c_oil
;
3290 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
3291 if (pim_mroute_add(c_oil
, __PRETTY_FUNCTION__
)) {
3292 /* just log warning */
3293 char source_str
[INET_ADDRSTRLEN
];
3294 char group_str
[INET_ADDRSTRLEN
];
3295 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
,
3296 source_str
, sizeof(source_str
));
3297 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
,
3298 group_str
, sizeof(group_str
));
3299 zlog_warn("%s %s: (S,G)=(%s,%s) failure writing MFC",
3300 __FILE__
, __PRETTY_FUNCTION__
, source_str
,
3306 static void mroute_del_all(struct pim_instance
*pim
)
3308 struct listnode
*node
;
3309 struct channel_oil
*c_oil
;
3311 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
3312 if (pim_mroute_del(c_oil
, __PRETTY_FUNCTION__
)) {
3313 /* just log warning */
3314 char source_str
[INET_ADDRSTRLEN
];
3315 char group_str
[INET_ADDRSTRLEN
];
3316 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
,
3317 source_str
, sizeof(source_str
));
3318 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
,
3319 group_str
, sizeof(group_str
));
3320 zlog_warn("%s %s: (S,G)=(%s,%s) failure clearing MFC",
3321 __FILE__
, __PRETTY_FUNCTION__
, source_str
,
3327 DEFUN (clear_ip_mroute
,
3328 clear_ip_mroute_cmd
,
3329 "clear ip mroute [vrf NAME]",
3332 "Reset multicast routes\n"
3336 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3341 mroute_del_all(vrf
->info
);
3342 mroute_add_all(vrf
->info
);
3347 DEFUN (clear_ip_pim_interfaces
,
3348 clear_ip_pim_interfaces_cmd
,
3349 "clear ip pim [vrf NAME] interfaces",
3354 "Reset PIM interfaces\n")
3357 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3362 clear_pim_interfaces(vrf
->info
);
3367 DEFUN (clear_ip_pim_interface_traffic
,
3368 clear_ip_pim_interface_traffic_cmd
,
3369 "clear ip pim [vrf NAME] interface traffic",
3372 "PIM clear commands\n"
3374 "Reset PIM interfaces\n"
3375 "Reset Protocol Packet counters\n")
3378 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3379 struct interface
*ifp
= NULL
;
3380 struct pim_interface
*pim_ifp
= NULL
;
3385 FOR_ALL_INTERFACES (vrf
, ifp
) {
3386 pim_ifp
= ifp
->info
;
3391 pim_ifp
->pim_ifstat_hello_recv
= 0;
3392 pim_ifp
->pim_ifstat_hello_sent
= 0;
3393 pim_ifp
->pim_ifstat_join_recv
= 0;
3394 pim_ifp
->pim_ifstat_join_send
= 0;
3395 pim_ifp
->pim_ifstat_prune_recv
= 0;
3396 pim_ifp
->pim_ifstat_prune_send
= 0;
3397 pim_ifp
->pim_ifstat_reg_recv
= 0;
3398 pim_ifp
->pim_ifstat_reg_send
= 0;
3399 pim_ifp
->pim_ifstat_reg_stop_recv
= 0;
3400 pim_ifp
->pim_ifstat_reg_stop_send
= 0;
3401 pim_ifp
->pim_ifstat_assert_recv
= 0;
3402 pim_ifp
->pim_ifstat_assert_send
= 0;
3408 DEFUN (clear_ip_pim_oil
,
3409 clear_ip_pim_oil_cmd
,
3410 "clear ip pim [vrf NAME] oil",
3415 "Rescan PIM OIL (output interface list)\n")
3418 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3423 pim_scan_oil(vrf
->info
);
3428 DEFUN (show_ip_igmp_interface
,
3429 show_ip_igmp_interface_cmd
,
3430 "show ip igmp [vrf NAME] interface [detail|WORD] [json]",
3435 "IGMP interface information\n"
3441 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3442 bool uj
= use_json(argc
, argv
);
3447 if (argv_find(argv
, argc
, "detail", &idx
)
3448 || argv_find(argv
, argc
, "WORD", &idx
))
3449 igmp_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
3451 igmp_show_interfaces(vrf
->info
, vty
, uj
);
3456 DEFUN (show_ip_igmp_interface_vrf_all
,
3457 show_ip_igmp_interface_vrf_all_cmd
,
3458 "show ip igmp vrf all interface [detail|WORD] [json]",
3463 "IGMP interface information\n"
3469 bool uj
= use_json(argc
, argv
);
3475 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3479 vty_out(vty
, " \"%s\": ", vrf
->name
);
3482 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3483 if (argv_find(argv
, argc
, "detail", &idx
)
3484 || argv_find(argv
, argc
, "WORD", &idx
))
3485 igmp_show_interfaces_single(vrf
->info
, vty
,
3486 argv
[idx
]->arg
, uj
);
3488 igmp_show_interfaces(vrf
->info
, vty
, uj
);
3491 vty_out(vty
, "}\n");
3496 DEFUN (show_ip_igmp_join
,
3497 show_ip_igmp_join_cmd
,
3498 "show ip igmp [vrf NAME] join",
3503 "IGMP static join information\n")
3506 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3511 igmp_show_interface_join(vrf
->info
, vty
);
3516 DEFUN (show_ip_igmp_join_vrf_all
,
3517 show_ip_igmp_join_vrf_all_cmd
,
3518 "show ip igmp vrf all join",
3523 "IGMP static join information\n")
3525 bool uj
= use_json(argc
, argv
);
3531 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3535 vty_out(vty
, " \"%s\": ", vrf
->name
);
3538 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3539 igmp_show_interface_join(vrf
->info
, vty
);
3542 vty_out(vty
, "}\n");
3547 DEFUN (show_ip_igmp_groups
,
3548 show_ip_igmp_groups_cmd
,
3549 "show ip igmp [vrf NAME] groups [json]",
3558 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3559 bool uj
= use_json(argc
, argv
);
3564 igmp_show_groups(vrf
->info
, vty
, uj
);
3569 DEFUN (show_ip_igmp_groups_vrf_all
,
3570 show_ip_igmp_groups_vrf_all_cmd
,
3571 "show ip igmp vrf all groups [json]",
3579 bool uj
= use_json(argc
, argv
);
3585 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3589 vty_out(vty
, " \"%s\": ", vrf
->name
);
3592 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3593 igmp_show_groups(vrf
->info
, vty
, uj
);
3596 vty_out(vty
, "}\n");
3601 DEFUN (show_ip_igmp_groups_retransmissions
,
3602 show_ip_igmp_groups_retransmissions_cmd
,
3603 "show ip igmp [vrf NAME] groups retransmissions",
3609 "IGMP group retransmissions\n")
3612 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3617 igmp_show_group_retransmission(vrf
->info
, vty
);
3622 DEFUN (show_ip_igmp_sources
,
3623 show_ip_igmp_sources_cmd
,
3624 "show ip igmp [vrf NAME] sources",
3632 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3637 igmp_show_sources(vrf
->info
, vty
);
3642 DEFUN (show_ip_igmp_sources_retransmissions
,
3643 show_ip_igmp_sources_retransmissions_cmd
,
3644 "show ip igmp [vrf NAME] sources retransmissions",
3650 "IGMP source retransmissions\n")
3653 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3658 igmp_show_source_retransmission(vrf
->info
, vty
);
3663 DEFUN (show_ip_igmp_statistics
,
3664 show_ip_igmp_statistics_cmd
,
3665 "show ip igmp [vrf NAME] statistics [interface WORD] [json]",
3676 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3677 bool uj
= use_json(argc
, argv
);
3682 if (argv_find(argv
, argc
, "WORD", &idx
))
3683 igmp_show_statistics(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
3685 igmp_show_statistics(vrf
->info
, vty
, NULL
, uj
);
3690 DEFUN (show_ip_pim_assert
,
3691 show_ip_pim_assert_cmd
,
3692 "show ip pim [vrf NAME] assert",
3697 "PIM interface assert\n")
3700 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3705 pim_show_assert(vrf
->info
, vty
);
3710 DEFUN (show_ip_pim_assert_internal
,
3711 show_ip_pim_assert_internal_cmd
,
3712 "show ip pim [vrf NAME] assert-internal",
3717 "PIM interface internal assert state\n")
3720 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3725 pim_show_assert_internal(vrf
->info
, vty
);
3730 DEFUN (show_ip_pim_assert_metric
,
3731 show_ip_pim_assert_metric_cmd
,
3732 "show ip pim [vrf NAME] assert-metric",
3737 "PIM interface assert metric\n")
3740 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3745 pim_show_assert_metric(vrf
->info
, vty
);
3750 DEFUN (show_ip_pim_assert_winner_metric
,
3751 show_ip_pim_assert_winner_metric_cmd
,
3752 "show ip pim [vrf NAME] assert-winner-metric",
3757 "PIM interface assert winner metric\n")
3760 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3765 pim_show_assert_winner_metric(vrf
->info
, vty
);
3770 DEFUN (show_ip_pim_interface
,
3771 show_ip_pim_interface_cmd
,
3772 "show ip pim [vrf NAME] interface [detail|WORD] [json]",
3777 "PIM interface information\n"
3783 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3784 bool uj
= use_json(argc
, argv
);
3789 if (argv_find(argv
, argc
, "WORD", &idx
)
3790 || argv_find(argv
, argc
, "detail", &idx
))
3791 pim_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
3793 pim_show_interfaces(vrf
->info
, vty
, uj
);
3798 DEFUN (show_ip_pim_interface_vrf_all
,
3799 show_ip_pim_interface_vrf_all_cmd
,
3800 "show ip pim vrf all interface [detail|WORD] [json]",
3805 "PIM interface information\n"
3811 bool uj
= use_json(argc
, argv
);
3817 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3821 vty_out(vty
, " \"%s\": ", vrf
->name
);
3824 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3825 if (argv_find(argv
, argc
, "WORD", &idx
)
3826 || argv_find(argv
, argc
, "detail", &idx
))
3827 pim_show_interfaces_single(vrf
->info
, vty
,
3828 argv
[idx
]->arg
, uj
);
3830 pim_show_interfaces(vrf
->info
, vty
, uj
);
3833 vty_out(vty
, "}\n");
3838 DEFPY (show_ip_pim_join
,
3839 show_ip_pim_join_cmd
,
3840 "show ip pim [vrf NAME] join [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
3845 "PIM interface join information\n"
3846 "The Source or Group\n"
3850 struct prefix_sg sg
= {0};
3853 struct pim_instance
*pim
;
3855 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
3858 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
3861 pim
= pim_get_pim_instance(v
->vrf_id
);
3864 vty_out(vty
, "%% Unable to find pim instance\n");
3868 if (s_or_g
.s_addr
!= 0) {
3869 if (g
.s_addr
!= 0) {
3876 pim_show_join(pim
, vty
, &sg
, uj
);
3881 DEFUN (show_ip_pim_join_vrf_all
,
3882 show_ip_pim_join_vrf_all_cmd
,
3883 "show ip pim vrf all join [json]",
3888 "PIM interface join information\n"
3891 struct prefix_sg sg
= {0};
3892 bool uj
= use_json(argc
, argv
);
3898 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3902 vty_out(vty
, " \"%s\": ", vrf
->name
);
3905 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3906 pim_show_join(vrf
->info
, vty
, &sg
, uj
);
3909 vty_out(vty
, "}\n");
3914 DEFUN (show_ip_pim_local_membership
,
3915 show_ip_pim_local_membership_cmd
,
3916 "show ip pim [vrf NAME] local-membership [json]",
3921 "PIM interface local-membership\n"
3925 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3926 bool uj
= use_json(argc
, argv
);
3931 pim_show_membership(vrf
->info
, vty
, uj
);
3936 DEFUN (show_ip_pim_neighbor
,
3937 show_ip_pim_neighbor_cmd
,
3938 "show ip pim [vrf NAME] neighbor [detail|WORD] [json]",
3943 "PIM neighbor information\n"
3945 "Name of interface or neighbor\n"
3949 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3950 bool uj
= use_json(argc
, argv
);
3955 if (argv_find(argv
, argc
, "detail", &idx
)
3956 || argv_find(argv
, argc
, "WORD", &idx
))
3957 pim_show_neighbors_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
3959 pim_show_neighbors(vrf
->info
, vty
, uj
);
3964 DEFUN (show_ip_pim_neighbor_vrf_all
,
3965 show_ip_pim_neighbor_vrf_all_cmd
,
3966 "show ip pim vrf all neighbor [detail|WORD] [json]",
3971 "PIM neighbor information\n"
3973 "Name of interface or neighbor\n"
3977 bool uj
= use_json(argc
, argv
);
3983 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3987 vty_out(vty
, " \"%s\": ", vrf
->name
);
3990 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3991 if (argv_find(argv
, argc
, "detail", &idx
)
3992 || argv_find(argv
, argc
, "WORD", &idx
))
3993 pim_show_neighbors_single(vrf
->info
, vty
,
3994 argv
[idx
]->arg
, uj
);
3996 pim_show_neighbors(vrf
->info
, vty
, uj
);
3999 vty_out(vty
, "}\n");
4004 DEFUN (show_ip_pim_secondary
,
4005 show_ip_pim_secondary_cmd
,
4006 "show ip pim [vrf NAME] secondary",
4011 "PIM neighbor addresses\n")
4014 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4019 pim_show_neighbors_secondary(vrf
->info
, vty
);
4024 DEFUN (show_ip_pim_state
,
4025 show_ip_pim_state_cmd
,
4026 "show ip pim [vrf NAME] state [A.B.C.D [A.B.C.D]] [json]",
4031 "PIM state information\n"
4032 "Unicast or Multicast address\n"
4033 "Multicast address\n"
4036 const char *src_or_group
= NULL
;
4037 const char *group
= NULL
;
4039 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4040 bool uj
= use_json(argc
, argv
);
4048 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
4049 src_or_group
= argv
[idx
]->arg
;
4051 group
= argv
[idx
+ 1]->arg
;
4054 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
4059 DEFUN (show_ip_pim_state_vrf_all
,
4060 show_ip_pim_state_vrf_all_cmd
,
4061 "show ip pim vrf all state [A.B.C.D [A.B.C.D]] [json]",
4066 "PIM state information\n"
4067 "Unicast or Multicast address\n"
4068 "Multicast address\n"
4071 const char *src_or_group
= NULL
;
4072 const char *group
= NULL
;
4074 bool uj
= use_json(argc
, argv
);
4083 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
4084 src_or_group
= argv
[idx
]->arg
;
4086 group
= argv
[idx
+ 1]->arg
;
4089 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4093 vty_out(vty
, " \"%s\": ", vrf
->name
);
4096 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4097 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
4100 vty_out(vty
, "}\n");
4105 DEFPY (show_ip_pim_upstream
,
4106 show_ip_pim_upstream_cmd
,
4107 "show ip pim [vrf NAME] upstream [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
4112 "PIM upstream information\n"
4113 "The Source or Group\n"
4117 struct prefix_sg sg
= {0};
4120 struct pim_instance
*pim
;
4122 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
4125 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
4128 pim
= pim_get_pim_instance(v
->vrf_id
);
4131 vty_out(vty
, "%% Unable to find pim instance\n");
4135 if (s_or_g
.s_addr
!= 0) {
4136 if (g
.s_addr
!= 0) {
4142 pim_show_upstream(pim
, vty
, &sg
, uj
);
4147 DEFUN (show_ip_pim_upstream_vrf_all
,
4148 show_ip_pim_upstream_vrf_all_cmd
,
4149 "show ip pim vrf all upstream [json]",
4154 "PIM upstream information\n"
4157 struct prefix_sg sg
= {0};
4158 bool uj
= use_json(argc
, argv
);
4164 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4168 vty_out(vty
, " \"%s\": ", vrf
->name
);
4171 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4172 pim_show_upstream(vrf
->info
, vty
, &sg
, uj
);
4178 DEFUN (show_ip_pim_upstream_join_desired
,
4179 show_ip_pim_upstream_join_desired_cmd
,
4180 "show ip pim [vrf NAME] upstream-join-desired [json]",
4185 "PIM upstream join-desired\n"
4189 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4190 bool uj
= use_json(argc
, argv
);
4195 pim_show_join_desired(vrf
->info
, vty
, uj
);
4200 DEFUN (show_ip_pim_upstream_rpf
,
4201 show_ip_pim_upstream_rpf_cmd
,
4202 "show ip pim [vrf NAME] upstream-rpf [json]",
4207 "PIM upstream source rpf\n"
4211 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4212 bool uj
= use_json(argc
, argv
);
4217 pim_show_upstream_rpf(vrf
->info
, vty
, uj
);
4222 DEFUN (show_ip_pim_rp
,
4224 "show ip pim [vrf NAME] rp-info [json]",
4229 "PIM RP information\n"
4233 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4234 bool uj
= use_json(argc
, argv
);
4239 pim_rp_show_information(vrf
->info
, vty
, uj
);
4244 DEFUN (show_ip_pim_rp_vrf_all
,
4245 show_ip_pim_rp_vrf_all_cmd
,
4246 "show ip pim vrf all rp-info [json]",
4251 "PIM RP information\n"
4254 bool uj
= use_json(argc
, argv
);
4260 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4264 vty_out(vty
, " \"%s\": ", vrf
->name
);
4267 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4268 pim_rp_show_information(vrf
->info
, vty
, uj
);
4271 vty_out(vty
, "}\n");
4276 DEFUN (show_ip_pim_rpf
,
4277 show_ip_pim_rpf_cmd
,
4278 "show ip pim [vrf NAME] rpf [json]",
4283 "PIM cached source rpf information\n"
4287 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4288 bool uj
= use_json(argc
, argv
);
4293 pim_show_rpf(vrf
->info
, vty
, uj
);
4298 DEFUN (show_ip_pim_rpf_vrf_all
,
4299 show_ip_pim_rpf_vrf_all_cmd
,
4300 "show ip pim vrf all rpf [json]",
4305 "PIM cached source rpf information\n"
4308 bool uj
= use_json(argc
, argv
);
4314 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4318 vty_out(vty
, " \"%s\": ", vrf
->name
);
4321 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4322 pim_show_rpf(vrf
->info
, vty
, uj
);
4325 vty_out(vty
, "}\n");
4330 DEFUN (show_ip_pim_nexthop
,
4331 show_ip_pim_nexthop_cmd
,
4332 "show ip pim [vrf NAME] nexthop",
4337 "PIM cached nexthop rpf information\n")
4340 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4345 pim_show_nexthop(vrf
->info
, vty
);
4350 DEFUN (show_ip_pim_nexthop_lookup
,
4351 show_ip_pim_nexthop_lookup_cmd
,
4352 "show ip pim [vrf NAME] nexthop-lookup A.B.C.D A.B.C.D",
4357 "PIM cached nexthop rpf lookup\n"
4358 "Source/RP address\n"
4359 "Multicast Group address\n")
4361 struct prefix nht_p
;
4363 struct in_addr src_addr
, grp_addr
;
4364 struct in_addr vif_source
;
4365 const char *addr_str
, *addr_str1
;
4367 struct pim_nexthop nexthop
;
4368 char nexthop_addr_str
[PREFIX_STRLEN
];
4369 char grp_str
[PREFIX_STRLEN
];
4371 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4376 argv_find(argv
, argc
, "A.B.C.D", &idx
);
4377 addr_str
= argv
[idx
]->arg
;
4378 result
= inet_pton(AF_INET
, addr_str
, &src_addr
);
4380 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
4381 errno
, safe_strerror(errno
));
4385 if (pim_is_group_224_4(src_addr
)) {
4387 "Invalid argument. Expected Valid Source Address.\n");
4391 addr_str1
= argv
[idx
+ 1]->arg
;
4392 result
= inet_pton(AF_INET
, addr_str1
, &grp_addr
);
4394 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
4395 errno
, safe_strerror(errno
));
4399 if (!pim_is_group_224_4(grp_addr
)) {
4401 "Invalid argument. Expected Valid Multicast Group Address.\n");
4405 if (!pim_rp_set_upstream_addr(vrf
->info
, &vif_source
, src_addr
,
4409 nht_p
.family
= AF_INET
;
4410 nht_p
.prefixlen
= IPV4_MAX_BITLEN
;
4411 nht_p
.u
.prefix4
= vif_source
;
4412 grp
.family
= AF_INET
;
4413 grp
.prefixlen
= IPV4_MAX_BITLEN
;
4414 grp
.u
.prefix4
= grp_addr
;
4415 memset(&nexthop
, 0, sizeof(nexthop
));
4417 result
= pim_ecmp_nexthop_lookup(vrf
->info
, &nexthop
, &nht_p
, &grp
, 0);
4421 "Nexthop Lookup failed, no usable routes returned.\n");
4425 pim_addr_dump("<grp?>", &grp
, grp_str
, sizeof(grp_str
));
4426 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
4427 nexthop_addr_str
, sizeof(nexthop_addr_str
));
4428 vty_out(vty
, "Group %s --- Nexthop %s Interface %s \n", grp_str
,
4429 nexthop_addr_str
, nexthop
.interface
->name
);
4434 DEFUN (show_ip_pim_interface_traffic
,
4435 show_ip_pim_interface_traffic_cmd
,
4436 "show ip pim [vrf NAME] interface traffic [WORD] [json]",
4441 "PIM interface information\n"
4442 "Protocol Packet counters\n"
4447 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4448 bool uj
= use_json(argc
, argv
);
4453 if (argv_find(argv
, argc
, "WORD", &idx
))
4454 pim_show_interface_traffic_single(vrf
->info
, vty
,
4455 argv
[idx
]->arg
, uj
);
4457 pim_show_interface_traffic(vrf
->info
, vty
, uj
);
4462 static void show_multicast_interfaces(struct pim_instance
*pim
, struct vty
*vty
)
4464 struct interface
*ifp
;
4469 "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut\n");
4471 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
4472 struct pim_interface
*pim_ifp
;
4473 struct in_addr ifaddr
;
4474 struct sioc_vif_req vreq
;
4476 pim_ifp
= ifp
->info
;
4481 memset(&vreq
, 0, sizeof(vreq
));
4482 vreq
.vifi
= pim_ifp
->mroute_vif_index
;
4484 if (ioctl(pim
->mroute_socket
, SIOCGETVIFCNT
, &vreq
)) {
4486 "ioctl(SIOCGETVIFCNT=%lu) failure for interface %s vif_index=%d: errno=%d: %s",
4487 (unsigned long)SIOCGETVIFCNT
, ifp
->name
,
4488 pim_ifp
->mroute_vif_index
, errno
,
4489 safe_strerror(errno
));
4492 ifaddr
= pim_ifp
->primary_address
;
4494 vty_out(vty
, "%-16s %-15s %3d %3d %7lu %7lu %10lu %10lu\n",
4495 ifp
->name
, inet_ntoa(ifaddr
), ifp
->ifindex
,
4496 pim_ifp
->mroute_vif_index
, (unsigned long)vreq
.icount
,
4497 (unsigned long)vreq
.ocount
, (unsigned long)vreq
.ibytes
,
4498 (unsigned long)vreq
.obytes
);
4502 static void pim_cmd_show_ip_multicast_helper(struct pim_instance
*pim
,
4505 struct vrf
*vrf
= pim
->vrf
;
4506 time_t now
= pim_time_monotonic_sec();
4512 vty_out(vty
, "Router MLAG Role: %s\n",
4513 mlag_role2str(router
->role
, mlag_role
, sizeof(mlag_role
)));
4514 vty_out(vty
, "Mroute socket descriptor:");
4516 vty_out(vty
, " %d(%s)\n", pim
->mroute_socket
, vrf
->name
);
4518 pim_time_uptime(uptime
, sizeof(uptime
),
4519 now
- pim
->mroute_socket_creation
);
4520 vty_out(vty
, "Mroute socket uptime: %s\n", uptime
);
4524 pim_zebra_zclient_update(vty
);
4525 pim_zlookup_show_ip_multicast(vty
);
4528 vty_out(vty
, "Maximum highest VifIndex: %d\n", PIM_MAX_USABLE_VIFS
);
4531 vty_out(vty
, "Upstream Join Timer: %d secs\n", router
->t_periodic
);
4532 vty_out(vty
, "Join/Prune Holdtime: %d secs\n", PIM_JP_HOLDTIME
);
4533 vty_out(vty
, "PIM ECMP: %s\n", pim
->ecmp_enable
? "Enable" : "Disable");
4534 vty_out(vty
, "PIM ECMP Rebalance: %s\n",
4535 pim
->ecmp_rebalance_enable
? "Enable" : "Disable");
4539 show_rpf_refresh_stats(vty
, pim
, now
, NULL
);
4543 show_scan_oil_stats(pim
, vty
, now
);
4545 show_multicast_interfaces(pim
, vty
);
4548 DEFUN (show_ip_multicast
,
4549 show_ip_multicast_cmd
,
4550 "show ip multicast [vrf NAME]",
4554 "Multicast global information\n")
4557 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4562 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
4567 DEFUN (show_ip_multicast_vrf_all
,
4568 show_ip_multicast_vrf_all_cmd
,
4569 "show ip multicast vrf all",
4573 "Multicast global information\n")
4575 bool uj
= use_json(argc
, argv
);
4581 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4585 vty_out(vty
, " \"%s\": ", vrf
->name
);
4588 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4589 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
4592 vty_out(vty
, "}\n");
4597 static void show_mroute(struct pim_instance
*pim
, struct vty
*vty
,
4598 struct prefix_sg
*sg
, bool fill
, bool uj
)
4600 struct listnode
*node
;
4601 struct channel_oil
*c_oil
;
4602 struct static_route
*s_route
;
4604 json_object
*json
= NULL
;
4605 json_object
*json_group
= NULL
;
4606 json_object
*json_source
= NULL
;
4607 json_object
*json_oil
= NULL
;
4608 json_object
*json_ifp_out
= NULL
;
4611 char grp_str
[INET_ADDRSTRLEN
];
4612 char src_str
[INET_ADDRSTRLEN
];
4613 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
4614 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
4616 struct interface
*ifp_in
;
4620 json
= json_object_new_object();
4623 "Source Group Proto Input Output TTL Uptime\n");
4626 now
= pim_time_monotonic_sec();
4628 /* print list of PIM and IGMP routes */
4629 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
4632 if (!c_oil
->installed
&& !uj
)
4635 if (sg
->grp
.s_addr
!= 0 &&
4636 sg
->grp
.s_addr
!= c_oil
->oil
.mfcc_mcastgrp
.s_addr
)
4638 if (sg
->src
.s_addr
!= 0 &&
4639 sg
->src
.s_addr
!= c_oil
->oil
.mfcc_origin
.s_addr
)
4642 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
4644 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
4646 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
4649 strcpy(in_ifname
, ifp_in
->name
);
4651 strcpy(in_ifname
, "<iif?>");
4655 /* Find the group, create it if it doesn't exist */
4656 json_object_object_get_ex(json
, grp_str
, &json_group
);
4659 json_group
= json_object_new_object();
4660 json_object_object_add(json
, grp_str
,
4664 /* Find the source nested under the group, create it if
4665 * it doesn't exist */
4666 json_object_object_get_ex(json_group
, src_str
,
4670 json_source
= json_object_new_object();
4671 json_object_object_add(json_group
, src_str
,
4675 /* Find the inbound interface nested under the source,
4676 * create it if it doesn't exist */
4677 json_object_int_add(json_source
, "installed",
4679 json_object_int_add(json_source
, "refCount",
4680 c_oil
->oil_ref_count
);
4681 json_object_int_add(json_source
, "oilSize",
4683 json_object_int_add(json_source
, "OilInheritedRescan",
4684 c_oil
->oil_inherited_rescan
);
4685 json_object_string_add(json_source
, "iif", in_ifname
);
4689 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
4691 struct interface
*ifp_out
;
4692 char mroute_uptime
[10];
4695 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
4699 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
4701 mroute_uptime
, sizeof(mroute_uptime
),
4702 now
- c_oil
->mroute_creation
);
4706 strcpy(out_ifname
, ifp_out
->name
);
4708 strcpy(out_ifname
, "<oif?>");
4711 json_ifp_out
= json_object_new_object();
4712 json_object_string_add(json_ifp_out
, "source",
4714 json_object_string_add(json_ifp_out
, "group",
4717 if (c_oil
->oif_flags
[oif_vif_index
]
4718 & PIM_OIF_FLAG_PROTO_PIM
)
4719 json_object_boolean_true_add(
4720 json_ifp_out
, "protocolPim");
4722 if (c_oil
->oif_flags
[oif_vif_index
]
4723 & PIM_OIF_FLAG_PROTO_IGMP
)
4724 json_object_boolean_true_add(
4725 json_ifp_out
, "protocolIgmp");
4727 if (c_oil
->oif_flags
[oif_vif_index
]
4728 & PIM_OIF_FLAG_PROTO_VXLAN
)
4729 json_object_boolean_true_add(
4730 json_ifp_out
, "protocolVxlan");
4732 if (c_oil
->oif_flags
[oif_vif_index
]
4733 & PIM_OIF_FLAG_PROTO_SOURCE
)
4734 json_object_boolean_true_add(
4735 json_ifp_out
, "protocolSource");
4737 if (c_oil
->oif_flags
[oif_vif_index
]
4738 & PIM_OIF_FLAG_PROTO_STAR
)
4739 json_object_boolean_true_add(
4741 "protocolInherited");
4743 json_object_string_add(json_ifp_out
,
4746 json_object_int_add(json_ifp_out
, "iVifI",
4747 c_oil
->oil
.mfcc_parent
);
4748 json_object_string_add(json_ifp_out
,
4749 "outboundInterface",
4751 json_object_int_add(json_ifp_out
, "oVifI",
4753 json_object_int_add(json_ifp_out
, "ttl", ttl
);
4754 json_object_string_add(json_ifp_out
, "upTime",
4757 json_oil
= json_object_new_object();
4758 json_object_object_add(json_source
,
4761 json_object_object_add(json_oil
, out_ifname
,
4764 if (c_oil
->oif_flags
[oif_vif_index
]
4765 & PIM_OIF_FLAG_PROTO_PIM
) {
4766 strcpy(proto
, "PIM");
4769 if (c_oil
->oif_flags
[oif_vif_index
]
4770 & PIM_OIF_FLAG_PROTO_IGMP
) {
4771 strcpy(proto
, "IGMP");
4774 if (c_oil
->oif_flags
[oif_vif_index
]
4775 & PIM_OIF_FLAG_PROTO_VXLAN
) {
4776 strcpy(proto
, "VxLAN");
4779 if (c_oil
->oif_flags
[oif_vif_index
]
4780 & PIM_OIF_FLAG_PROTO_SOURCE
) {
4781 strcpy(proto
, "SRC");
4784 if (c_oil
->oif_flags
[oif_vif_index
]
4785 & PIM_OIF_FLAG_PROTO_STAR
) {
4786 strcpy(proto
, "STAR");
4790 "%-15s %-15s %-6s %-16s %-16s %-3d %8s\n",
4791 src_str
, grp_str
, proto
, in_ifname
,
4792 out_ifname
, ttl
, mroute_uptime
);
4797 in_ifname
[0] = '\0';
4803 if (!uj
&& !found_oif
) {
4804 vty_out(vty
, "%-15s %-15s %-6s %-16s %-16s %-3d %8s\n",
4805 src_str
, grp_str
, "none", in_ifname
, "none", 0,
4810 /* Print list of static routes */
4811 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
4814 if (!s_route
->c_oil
.installed
)
4817 pim_inet4_dump("<group?>", s_route
->group
, grp_str
,
4819 pim_inet4_dump("<source?>", s_route
->source
, src_str
,
4821 ifp_in
= pim_if_find_by_vif_index(pim
, s_route
->iif
);
4825 strcpy(in_ifname
, ifp_in
->name
);
4827 strcpy(in_ifname
, "<iif?>");
4831 /* Find the group, create it if it doesn't exist */
4832 json_object_object_get_ex(json
, grp_str
, &json_group
);
4835 json_group
= json_object_new_object();
4836 json_object_object_add(json
, grp_str
,
4840 /* Find the source nested under the group, create it if
4841 * it doesn't exist */
4842 json_object_object_get_ex(json_group
, src_str
,
4846 json_source
= json_object_new_object();
4847 json_object_object_add(json_group
, src_str
,
4851 json_object_string_add(json_source
, "iif", in_ifname
);
4854 strcpy(proto
, "STATIC");
4857 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
4859 struct interface
*ifp_out
;
4860 char oif_uptime
[10];
4863 ttl
= s_route
->oif_ttls
[oif_vif_index
];
4867 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
4869 oif_uptime
, sizeof(oif_uptime
),
4872 .oif_creation
[oif_vif_index
]);
4876 strcpy(out_ifname
, ifp_out
->name
);
4878 strcpy(out_ifname
, "<oif?>");
4881 json_ifp_out
= json_object_new_object();
4882 json_object_string_add(json_ifp_out
, "source",
4884 json_object_string_add(json_ifp_out
, "group",
4886 json_object_boolean_true_add(json_ifp_out
,
4888 json_object_string_add(json_ifp_out
,
4891 json_object_int_add(
4892 json_ifp_out
, "iVifI",
4893 s_route
->c_oil
.oil
.mfcc_parent
);
4894 json_object_string_add(json_ifp_out
,
4895 "outboundInterface",
4897 json_object_int_add(json_ifp_out
, "oVifI",
4899 json_object_int_add(json_ifp_out
, "ttl", ttl
);
4900 json_object_string_add(json_ifp_out
, "upTime",
4903 json_oil
= json_object_new_object();
4904 json_object_object_add(json_source
,
4907 json_object_object_add(json_oil
, out_ifname
,
4911 "%-15s %-15s %-6s %-16s %-16s %-3d %8s %s\n",
4912 src_str
, grp_str
, proto
, in_ifname
,
4913 out_ifname
, ttl
, oif_uptime
,
4915 if (first
&& !fill
) {
4918 in_ifname
[0] = '\0';
4924 if (!uj
&& !found_oif
) {
4926 "%-15s %-15s %-6s %-16s %-16s %-3d %8s %s\n",
4927 src_str
, grp_str
, proto
, in_ifname
, "none", 0,
4928 "--:--:--", pim
->vrf
->name
);
4933 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4934 json
, JSON_C_TO_STRING_PRETTY
));
4935 json_object_free(json
);
4939 DEFPY (show_ip_mroute
,
4941 "show ip mroute [vrf NAME] [A.B.C.D$s_or_g [A.B.C.D$g]] [fill$fill] [json$json]",
4946 "The Source or Group\n"
4948 "Fill in Assumed data\n"
4951 struct prefix_sg sg
= {0};
4952 struct pim_instance
*pim
;
4955 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
4958 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
4961 pim
= pim_get_pim_instance(v
->vrf_id
);
4964 vty_out(vty
, "%% Unable to find pim instance\n");
4968 if (s_or_g
.s_addr
!= 0) {
4969 if (g
.s_addr
!= 0) {
4975 show_mroute(pim
, vty
, &sg
, !!fill
, !!json
);
4979 DEFUN (show_ip_mroute_vrf_all
,
4980 show_ip_mroute_vrf_all_cmd
,
4981 "show ip mroute vrf all [fill] [json]",
4986 "Fill in Assumed data\n"
4989 struct prefix_sg sg
= {0};
4990 bool uj
= use_json(argc
, argv
);
4996 if (argv_find(argv
, argc
, "fill", &idx
))
5001 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5005 vty_out(vty
, " \"%s\": ", vrf
->name
);
5008 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5009 show_mroute(vrf
->info
, vty
, &sg
, fill
, uj
);
5012 vty_out(vty
, "}\n");
5017 static void show_mroute_count(struct pim_instance
*pim
, struct vty
*vty
)
5019 struct listnode
*node
;
5020 struct channel_oil
*c_oil
;
5021 struct static_route
*s_route
;
5026 "Source Group LastUsed Packets Bytes WrongIf \n");
5028 /* Print PIM and IGMP route counts */
5029 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
5030 char group_str
[INET_ADDRSTRLEN
];
5031 char source_str
[INET_ADDRSTRLEN
];
5033 if (!c_oil
->installed
)
5036 pim_mroute_update_counters(c_oil
);
5038 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, group_str
,
5040 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, source_str
,
5041 sizeof(source_str
));
5043 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
5044 source_str
, group_str
, c_oil
->cc
.lastused
/ 100,
5045 c_oil
->cc
.pktcnt
, c_oil
->cc
.bytecnt
,
5046 c_oil
->cc
.wrong_if
);
5049 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
5050 char group_str
[INET_ADDRSTRLEN
];
5051 char source_str
[INET_ADDRSTRLEN
];
5053 if (!s_route
->c_oil
.installed
)
5056 pim_mroute_update_counters(&s_route
->c_oil
);
5058 pim_inet4_dump("<group?>", s_route
->c_oil
.oil
.mfcc_mcastgrp
,
5059 group_str
, sizeof(group_str
));
5060 pim_inet4_dump("<source?>", s_route
->c_oil
.oil
.mfcc_origin
,
5061 source_str
, sizeof(source_str
));
5063 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
5064 source_str
, group_str
, s_route
->c_oil
.cc
.lastused
,
5065 s_route
->c_oil
.cc
.pktcnt
, s_route
->c_oil
.cc
.bytecnt
,
5066 s_route
->c_oil
.cc
.wrong_if
);
5070 DEFUN (show_ip_mroute_count
,
5071 show_ip_mroute_count_cmd
,
5072 "show ip mroute [vrf NAME] count",
5077 "Route and packet count data\n")
5080 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5085 show_mroute_count(vrf
->info
, vty
);
5089 DEFUN (show_ip_mroute_count_vrf_all
,
5090 show_ip_mroute_count_vrf_all_cmd
,
5091 "show ip mroute vrf all count",
5096 "Route and packet count data\n")
5098 bool uj
= use_json(argc
, argv
);
5104 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5108 vty_out(vty
, " \"%s\": ", vrf
->name
);
5111 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5112 show_mroute_count(vrf
->info
, vty
);
5115 vty_out(vty
, "}\n");
5122 "show ip rib [vrf NAME] A.B.C.D",
5127 "Unicast address\n")
5130 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5131 struct in_addr addr
;
5132 const char *addr_str
;
5133 struct pim_nexthop nexthop
;
5134 char nexthop_addr_str
[PREFIX_STRLEN
];
5140 memset(&nexthop
, 0, sizeof(nexthop
));
5141 argv_find(argv
, argc
, "A.B.C.D", &idx
);
5142 addr_str
= argv
[idx
]->arg
;
5143 result
= inet_pton(AF_INET
, addr_str
, &addr
);
5145 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
5146 errno
, safe_strerror(errno
));
5150 if (!pim_nexthop_lookup(vrf
->info
, &nexthop
, addr
, 0)) {
5152 "Failure querying RIB nexthop for unicast address %s\n",
5158 "Address NextHop Interface Metric Preference\n");
5160 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
5161 nexthop_addr_str
, sizeof(nexthop_addr_str
));
5163 vty_out(vty
, "%-15s %-15s %-9s %6d %10d\n", addr_str
, nexthop_addr_str
,
5164 nexthop
.interface
? nexthop
.interface
->name
: "<ifname?>",
5165 nexthop
.mrib_route_metric
, nexthop
.mrib_metric_preference
);
5170 static void show_ssmpingd(struct pim_instance
*pim
, struct vty
*vty
)
5172 struct listnode
*node
;
5173 struct ssmpingd_sock
*ss
;
5177 "Source Socket Address Port Uptime Requests\n");
5179 if (!pim
->ssmpingd_list
)
5182 now
= pim_time_monotonic_sec();
5184 for (ALL_LIST_ELEMENTS_RO(pim
->ssmpingd_list
, node
, ss
)) {
5185 char source_str
[INET_ADDRSTRLEN
];
5187 struct sockaddr_in bind_addr
;
5188 socklen_t len
= sizeof(bind_addr
);
5189 char bind_addr_str
[INET_ADDRSTRLEN
];
5191 pim_inet4_dump("<src?>", ss
->source_addr
, source_str
,
5192 sizeof(source_str
));
5194 if (pim_socket_getsockname(
5195 ss
->sock_fd
, (struct sockaddr
*)&bind_addr
, &len
)) {
5197 "%% Failure reading socket name for ssmpingd source %s on fd=%d\n",
5198 source_str
, ss
->sock_fd
);
5201 pim_inet4_dump("<addr?>", bind_addr
.sin_addr
, bind_addr_str
,
5202 sizeof(bind_addr_str
));
5203 pim_time_uptime(ss_uptime
, sizeof(ss_uptime
),
5204 now
- ss
->creation
);
5206 vty_out(vty
, "%-15s %6d %-15s %5d %8s %8lld\n", source_str
,
5207 ss
->sock_fd
, bind_addr_str
, ntohs(bind_addr
.sin_port
),
5208 ss_uptime
, (long long)ss
->requests
);
5212 DEFUN (show_ip_ssmpingd
,
5213 show_ip_ssmpingd_cmd
,
5214 "show ip ssmpingd [vrf NAME]",
5221 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5226 show_ssmpingd(vrf
->info
, vty
);
5230 static int pim_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
5231 const char *rp
, const char *group
,
5236 result
= pim_rp_new(pim
, rp
, group
, plist
);
5238 if (result
== PIM_GROUP_BAD_ADDRESS
) {
5239 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
5240 return CMD_WARNING_CONFIG_FAILED
;
5243 if (result
== PIM_RP_BAD_ADDRESS
) {
5244 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
5245 return CMD_WARNING_CONFIG_FAILED
;
5248 if (result
== PIM_RP_NO_PATH
) {
5249 vty_out(vty
, "%% No Path to RP address specified: %s\n", rp
);
5253 if (result
== PIM_GROUP_OVERLAP
) {
5255 "%% Group range specified cannot exact match another\n");
5256 return CMD_WARNING_CONFIG_FAILED
;
5259 if (result
== PIM_GROUP_PFXLIST_OVERLAP
) {
5261 "%% This group is already covered by a RP prefix-list\n");
5262 return CMD_WARNING_CONFIG_FAILED
;
5265 if (result
== PIM_RP_PFXLIST_IN_USE
) {
5267 "%% The same prefix-list cannot be applied to multiple RPs\n");
5268 return CMD_WARNING_CONFIG_FAILED
;
5271 if (result
== PIM_GROUP_BAD_ADDR_MASK_COMBO
) {
5272 vty_out(vty
, "%% Inconsistent address and mask: %s\n",
5274 return CMD_WARNING_CONFIG_FAILED
;
5280 static int pim_cmd_spt_switchover(struct pim_instance
*pim
,
5281 enum pim_spt_switchover spt
,
5284 pim
->spt
.switchover
= spt
;
5286 switch (pim
->spt
.switchover
) {
5287 case PIM_SPT_IMMEDIATE
:
5288 XFREE(MTYPE_PIM_SPT_PLIST_NAME
, pim
->spt
.plist
);
5290 pim_upstream_add_lhr_star_pimreg(pim
);
5292 case PIM_SPT_INFINITY
:
5293 pim_upstream_remove_lhr_star_pimreg(pim
, plist
);
5295 XFREE(MTYPE_PIM_SPT_PLIST_NAME
, pim
->spt
.plist
);
5299 XSTRDUP(MTYPE_PIM_SPT_PLIST_NAME
, plist
);
5306 DEFUN (ip_pim_spt_switchover_infinity
,
5307 ip_pim_spt_switchover_infinity_cmd
,
5308 "ip pim spt-switchover infinity-and-beyond",
5312 "Never switch to SPT Tree\n")
5314 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5315 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, NULL
);
5318 DEFUN (ip_pim_spt_switchover_infinity_plist
,
5319 ip_pim_spt_switchover_infinity_plist_cmd
,
5320 "ip pim spt-switchover infinity-and-beyond prefix-list WORD",
5324 "Never switch to SPT Tree\n"
5325 "Prefix-List to control which groups to switch\n"
5326 "Prefix-List name\n")
5328 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5329 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, argv
[5]->arg
);
5332 DEFUN (no_ip_pim_spt_switchover_infinity
,
5333 no_ip_pim_spt_switchover_infinity_cmd
,
5334 "no ip pim spt-switchover infinity-and-beyond",
5339 "Never switch to SPT Tree\n")
5341 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5342 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
5345 DEFUN (no_ip_pim_spt_switchover_infinity_plist
,
5346 no_ip_pim_spt_switchover_infinity_plist_cmd
,
5347 "no ip pim spt-switchover infinity-and-beyond prefix-list WORD",
5352 "Never switch to SPT Tree\n"
5353 "Prefix-List to control which groups to switch\n"
5354 "Prefix-List name\n")
5356 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5357 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
5360 DEFUN (ip_pim_joinprune_time
,
5361 ip_pim_joinprune_time_cmd
,
5362 "ip pim join-prune-interval (60-600)",
5364 "pim multicast routing\n"
5365 "Join Prune Send Interval\n"
5368 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5369 router
->t_periodic
= atoi(argv
[3]->arg
);
5373 DEFUN (no_ip_pim_joinprune_time
,
5374 no_ip_pim_joinprune_time_cmd
,
5375 "no ip pim join-prune-interval (60-600)",
5378 "pim multicast routing\n"
5379 "Join Prune Send Interval\n"
5382 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5383 router
->t_periodic
= PIM_DEFAULT_T_PERIODIC
;
5387 DEFUN (ip_pim_register_suppress
,
5388 ip_pim_register_suppress_cmd
,
5389 "ip pim register-suppress-time (5-60000)",
5391 "pim multicast routing\n"
5392 "Register Suppress Timer\n"
5395 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5396 router
->register_suppress_time
= atoi(argv
[3]->arg
);
5400 DEFUN (no_ip_pim_register_suppress
,
5401 no_ip_pim_register_suppress_cmd
,
5402 "no ip pim register-suppress-time (5-60000)",
5405 "pim multicast routing\n"
5406 "Register Suppress Timer\n"
5409 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5410 router
->register_suppress_time
= PIM_REGISTER_SUPPRESSION_TIME_DEFAULT
;
5414 DEFUN (ip_pim_rp_keep_alive
,
5415 ip_pim_rp_keep_alive_cmd
,
5416 "ip pim rp keep-alive-timer (31-60000)",
5418 "pim multicast routing\n"
5420 "Keep alive Timer\n"
5423 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5424 pim
->rp_keep_alive_time
= atoi(argv
[4]->arg
);
5428 DEFUN (no_ip_pim_rp_keep_alive
,
5429 no_ip_pim_rp_keep_alive_cmd
,
5430 "no ip pim rp keep-alive-timer (31-60000)",
5433 "pim multicast routing\n"
5435 "Keep alive Timer\n"
5438 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5439 pim
->rp_keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
5443 DEFUN (ip_pim_keep_alive
,
5444 ip_pim_keep_alive_cmd
,
5445 "ip pim keep-alive-timer (31-60000)",
5447 "pim multicast routing\n"
5448 "Keep alive Timer\n"
5451 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5452 pim
->keep_alive_time
= atoi(argv
[3]->arg
);
5456 DEFUN (no_ip_pim_keep_alive
,
5457 no_ip_pim_keep_alive_cmd
,
5458 "no ip pim keep-alive-timer (31-60000)",
5461 "pim multicast routing\n"
5462 "Keep alive Timer\n"
5465 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5466 pim
->keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
5470 DEFUN (ip_pim_packets
,
5472 "ip pim packets (1-100)",
5474 "pim multicast routing\n"
5475 "packets to process at one time per fd\n"
5476 "Number of packets\n")
5478 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5479 router
->packet_process
= atoi(argv
[3]->arg
);
5483 DEFUN (no_ip_pim_packets
,
5484 no_ip_pim_packets_cmd
,
5485 "no ip pim packets (1-100)",
5488 "pim multicast routing\n"
5489 "packets to process at one time per fd\n"
5490 "Number of packets\n")
5492 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5493 router
->packet_process
= PIM_DEFAULT_PACKET_PROCESS
;
5497 DEFUN (ip_pim_v6_secondary
,
5498 ip_pim_v6_secondary_cmd
,
5499 "ip pim send-v6-secondary",
5501 "pim multicast routing\n"
5502 "Send v6 secondary addresses\n")
5504 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5505 pim
->send_v6_secondary
= 1;
5510 DEFUN (no_ip_pim_v6_secondary
,
5511 no_ip_pim_v6_secondary_cmd
,
5512 "no ip pim send-v6-secondary",
5515 "pim multicast routing\n"
5516 "Send v6 secondary addresses\n")
5518 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5519 pim
->send_v6_secondary
= 0;
5526 "ip pim rp A.B.C.D [A.B.C.D/M]",
5528 "pim multicast routing\n"
5530 "ip address of RP\n"
5531 "Group Address range to cover\n")
5533 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5536 if (argc
== (idx_ipv4
+ 1))
5537 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
5540 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
5541 argv
[idx_ipv4
+ 1]->arg
, NULL
);
5544 DEFUN (ip_pim_rp_prefix_list
,
5545 ip_pim_rp_prefix_list_cmd
,
5546 "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_rp_cmd_worker(pim
, vty
, argv
[3]->arg
, NULL
, argv
[5]->arg
);
5558 static int pim_no_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
5559 const char *rp
, const char *group
,
5562 int result
= pim_rp_del(pim
, rp
, group
, plist
);
5564 if (result
== PIM_GROUP_BAD_ADDRESS
) {
5565 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
5566 return CMD_WARNING_CONFIG_FAILED
;
5569 if (result
== PIM_RP_BAD_ADDRESS
) {
5570 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
5571 return CMD_WARNING_CONFIG_FAILED
;
5574 if (result
== PIM_RP_NOT_FOUND
) {
5575 vty_out(vty
, "%% Unable to find specified RP\n");
5576 return CMD_WARNING_CONFIG_FAILED
;
5582 DEFUN (no_ip_pim_rp
,
5584 "no ip pim rp A.B.C.D [A.B.C.D/M]",
5587 "pim multicast routing\n"
5589 "ip address of RP\n"
5590 "Group Address range to cover\n")
5592 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5593 int idx_ipv4
= 4, idx_group
= 0;
5595 if (argv_find(argv
, argc
, "A.B.C.D/M", &idx_group
))
5596 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
5597 argv
[idx_group
]->arg
, NULL
);
5599 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
5603 DEFUN (no_ip_pim_rp_prefix_list
,
5604 no_ip_pim_rp_prefix_list_cmd
,
5605 "no ip pim rp A.B.C.D prefix-list WORD",
5608 "pim multicast routing\n"
5610 "ip address of RP\n"
5611 "group prefix-list filter\n"
5612 "Name of a prefix-list\n")
5614 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5615 return pim_no_rp_cmd_worker(pim
, vty
, argv
[4]->arg
, NULL
, argv
[6]->arg
);
5618 static int pim_ssm_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
5621 int result
= pim_ssm_range_set(pim
, pim
->vrf_id
, plist
);
5623 if (result
== PIM_SSM_ERR_NONE
)
5627 case PIM_SSM_ERR_NO_VRF
:
5628 vty_out(vty
, "%% VRF doesn't exist\n");
5630 case PIM_SSM_ERR_DUP
:
5631 vty_out(vty
, "%% duplicate config\n");
5634 vty_out(vty
, "%% ssm range config failed\n");
5637 return CMD_WARNING_CONFIG_FAILED
;
5640 DEFUN (ip_pim_ssm_prefix_list
,
5641 ip_pim_ssm_prefix_list_cmd
,
5642 "ip pim ssm prefix-list WORD",
5644 "pim multicast routing\n"
5645 "Source Specific Multicast\n"
5646 "group range prefix-list filter\n"
5647 "Name of a prefix-list\n")
5649 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5650 return pim_ssm_cmd_worker(pim
, vty
, argv
[4]->arg
);
5653 DEFUN (no_ip_pim_ssm_prefix_list
,
5654 no_ip_pim_ssm_prefix_list_cmd
,
5655 "no ip pim ssm prefix-list",
5658 "pim multicast routing\n"
5659 "Source Specific Multicast\n"
5660 "group range prefix-list filter\n")
5662 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5663 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
5666 DEFUN (no_ip_pim_ssm_prefix_list_name
,
5667 no_ip_pim_ssm_prefix_list_name_cmd
,
5668 "no ip pim ssm prefix-list WORD",
5671 "pim multicast routing\n"
5672 "Source Specific Multicast\n"
5673 "group range prefix-list filter\n"
5674 "Name of a prefix-list\n")
5676 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5677 struct pim_ssm
*ssm
= pim
->ssm_info
;
5679 if (ssm
->plist_name
&& !strcmp(ssm
->plist_name
, argv
[5]->arg
))
5680 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
5682 vty_out(vty
, "%% pim ssm prefix-list %s doesn't exist\n", argv
[5]->arg
);
5684 return CMD_WARNING_CONFIG_FAILED
;
5687 static void ip_pim_ssm_show_group_range(struct pim_instance
*pim
,
5688 struct vty
*vty
, bool uj
)
5690 struct pim_ssm
*ssm
= pim
->ssm_info
;
5691 const char *range_str
=
5692 ssm
->plist_name
? ssm
->plist_name
: PIM_SSM_STANDARD_RANGE
;
5696 json
= json_object_new_object();
5697 json_object_string_add(json
, "ssmGroups", range_str
);
5698 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5699 json
, JSON_C_TO_STRING_PRETTY
));
5700 json_object_free(json
);
5702 vty_out(vty
, "SSM group range : %s\n", range_str
);
5705 DEFUN (show_ip_pim_ssm_range
,
5706 show_ip_pim_ssm_range_cmd
,
5707 "show ip pim [vrf NAME] group-type [json]",
5716 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5717 bool uj
= use_json(argc
, argv
);
5722 ip_pim_ssm_show_group_range(vrf
->info
, vty
, uj
);
5727 static void ip_pim_ssm_show_group_type(struct pim_instance
*pim
,
5728 struct vty
*vty
, bool uj
,
5731 struct in_addr group_addr
;
5732 const char *type_str
;
5735 result
= inet_pton(AF_INET
, group
, &group_addr
);
5737 type_str
= "invalid";
5739 if (pim_is_group_224_4(group_addr
))
5741 pim_is_grp_ssm(pim
, group_addr
) ? "SSM" : "ASM";
5743 type_str
= "not-multicast";
5748 json
= json_object_new_object();
5749 json_object_string_add(json
, "groupType", type_str
);
5750 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5751 json
, JSON_C_TO_STRING_PRETTY
));
5752 json_object_free(json
);
5754 vty_out(vty
, "Group type : %s\n", type_str
);
5757 DEFUN (show_ip_pim_group_type
,
5758 show_ip_pim_group_type_cmd
,
5759 "show ip pim [vrf NAME] group-type A.B.C.D [json]",
5764 "multicast group type\n"
5769 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5770 bool uj
= use_json(argc
, argv
);
5775 argv_find(argv
, argc
, "A.B.C.D", &idx
);
5776 ip_pim_ssm_show_group_type(vrf
->info
, vty
, uj
, argv
[idx
]->arg
);
5783 "ip ssmpingd [A.B.C.D]",
5788 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5791 struct in_addr source_addr
;
5792 const char *source_str
= (argc
== 3) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
5794 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
5796 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
5797 source_str
, errno
, safe_strerror(errno
));
5798 return CMD_WARNING_CONFIG_FAILED
;
5801 result
= pim_ssmpingd_start(pim
, source_addr
);
5803 vty_out(vty
, "%% Failure starting ssmpingd for source %s: %d\n",
5804 source_str
, result
);
5805 return CMD_WARNING_CONFIG_FAILED
;
5811 DEFUN (no_ip_ssmpingd
,
5813 "no ip ssmpingd [A.B.C.D]",
5819 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5822 struct in_addr source_addr
;
5823 const char *source_str
= (argc
== 4) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
5825 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
5827 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
5828 source_str
, errno
, safe_strerror(errno
));
5829 return CMD_WARNING_CONFIG_FAILED
;
5832 result
= pim_ssmpingd_stop(pim
, source_addr
);
5834 vty_out(vty
, "%% Failure stopping ssmpingd for source %s: %d\n",
5835 source_str
, result
);
5836 return CMD_WARNING_CONFIG_FAILED
;
5846 "pim multicast routing\n"
5847 "Enable PIM ECMP \n")
5849 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5850 pim
->ecmp_enable
= true;
5855 DEFUN (no_ip_pim_ecmp
,
5860 "pim multicast routing\n"
5861 "Disable PIM ECMP \n")
5863 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5864 pim
->ecmp_enable
= false;
5869 DEFUN (ip_pim_ecmp_rebalance
,
5870 ip_pim_ecmp_rebalance_cmd
,
5871 "ip pim ecmp rebalance",
5873 "pim multicast routing\n"
5874 "Enable PIM ECMP \n"
5875 "Enable PIM ECMP Rebalance\n")
5877 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5878 pim
->ecmp_enable
= true;
5879 pim
->ecmp_rebalance_enable
= true;
5884 DEFUN (no_ip_pim_ecmp_rebalance
,
5885 no_ip_pim_ecmp_rebalance_cmd
,
5886 "no ip pim ecmp rebalance",
5889 "pim multicast routing\n"
5890 "Disable PIM ECMP \n"
5891 "Disable PIM ECMP Rebalance\n")
5893 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5894 pim
->ecmp_rebalance_enable
= false;
5899 static int pim_cmd_igmp_start(struct vty
*vty
, struct interface
*ifp
)
5901 struct pim_interface
*pim_ifp
;
5902 uint8_t need_startup
= 0;
5904 pim_ifp
= ifp
->info
;
5907 pim_ifp
= pim_if_new(ifp
, true, false, false,
5908 false /*vxlan_term*/);
5910 vty_out(vty
, "Could not enable IGMP on interface %s\n",
5912 return CMD_WARNING_CONFIG_FAILED
;
5916 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
5917 PIM_IF_DO_IGMP(pim_ifp
->options
);
5922 /* 'ip igmp' executed multiple times, with need_startup
5923 avoid multiple if add all and membership refresh */
5925 pim_if_addr_add_all(ifp
);
5926 pim_if_membership_refresh(ifp
);
5932 DEFUN (interface_ip_igmp
,
5933 interface_ip_igmp_cmd
,
5938 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5940 return pim_cmd_igmp_start(vty
, ifp
);
5943 DEFUN (interface_no_ip_igmp
,
5944 interface_no_ip_igmp_cmd
,
5950 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5951 struct pim_interface
*pim_ifp
= ifp
->info
;
5956 PIM_IF_DONT_IGMP(pim_ifp
->options
);
5958 pim_if_membership_clear(ifp
);
5960 pim_if_addr_del_all_igmp(ifp
);
5962 if (!PIM_IF_TEST_PIM(pim_ifp
->options
)) {
5969 DEFUN (interface_ip_igmp_join
,
5970 interface_ip_igmp_join_cmd
,
5971 "ip igmp join A.B.C.D A.B.C.D",
5974 "IGMP join multicast group\n"
5975 "Multicast group address\n"
5978 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5981 const char *group_str
;
5982 const char *source_str
;
5983 struct in_addr group_addr
;
5984 struct in_addr source_addr
;
5988 group_str
= argv
[idx_ipv4
]->arg
;
5989 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
5991 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
5992 errno
, safe_strerror(errno
));
5993 return CMD_WARNING_CONFIG_FAILED
;
5996 /* Source address */
5997 source_str
= argv
[idx_ipv4_2
]->arg
;
5998 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
6000 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
6001 source_str
, errno
, safe_strerror(errno
));
6002 return CMD_WARNING_CONFIG_FAILED
;
6005 CMD_FERR_RETURN(pim_if_igmp_join_add(ifp
, group_addr
, source_addr
),
6006 "Failure joining IGMP group: $ERR");
6011 DEFUN (interface_no_ip_igmp_join
,
6012 interface_no_ip_igmp_join_cmd
,
6013 "no ip igmp join A.B.C.D A.B.C.D",
6017 "IGMP join multicast group\n"
6018 "Multicast group address\n"
6021 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6024 const char *group_str
;
6025 const char *source_str
;
6026 struct in_addr group_addr
;
6027 struct in_addr source_addr
;
6031 group_str
= argv
[idx_ipv4
]->arg
;
6032 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
6034 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
6035 errno
, safe_strerror(errno
));
6036 return CMD_WARNING_CONFIG_FAILED
;
6039 /* Source address */
6040 source_str
= argv
[idx_ipv4_2
]->arg
;
6041 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
6043 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
6044 source_str
, errno
, safe_strerror(errno
));
6045 return CMD_WARNING_CONFIG_FAILED
;
6048 result
= pim_if_igmp_join_del(ifp
, group_addr
, source_addr
);
6051 "%% Failure leaving IGMP group %s source %s on interface %s: %d\n",
6052 group_str
, source_str
, ifp
->name
, result
);
6053 return CMD_WARNING_CONFIG_FAILED
;
6060 CLI reconfiguration affects the interface level (struct pim_interface).
6061 This function propagates the reconfiguration to every active socket
6064 static void igmp_sock_query_interval_reconfig(struct igmp_sock
*igmp
)
6066 struct interface
*ifp
;
6067 struct pim_interface
*pim_ifp
;
6071 /* other querier present? */
6073 if (igmp
->t_other_querier_timer
)
6076 /* this is the querier */
6078 zassert(igmp
->interface
);
6079 zassert(igmp
->interface
->info
);
6081 ifp
= igmp
->interface
;
6082 pim_ifp
= ifp
->info
;
6084 if (PIM_DEBUG_IGMP_TRACE
) {
6085 char ifaddr_str
[INET_ADDRSTRLEN
];
6086 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
6087 sizeof(ifaddr_str
));
6088 zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
6089 __PRETTY_FUNCTION__
, ifaddr_str
, ifp
->name
,
6090 pim_ifp
->igmp_default_query_interval
);
6094 igmp_startup_mode_on() will reset QQI:
6096 igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
6098 igmp_startup_mode_on(igmp
);
6101 static void igmp_sock_query_reschedule(struct igmp_sock
*igmp
)
6103 if (igmp
->t_igmp_query_timer
) {
6104 /* other querier present */
6105 zassert(igmp
->t_igmp_query_timer
);
6106 zassert(!igmp
->t_other_querier_timer
);
6108 pim_igmp_general_query_off(igmp
);
6109 pim_igmp_general_query_on(igmp
);
6111 zassert(igmp
->t_igmp_query_timer
);
6112 zassert(!igmp
->t_other_querier_timer
);
6114 /* this is the querier */
6116 zassert(!igmp
->t_igmp_query_timer
);
6117 zassert(igmp
->t_other_querier_timer
);
6119 pim_igmp_other_querier_timer_off(igmp
);
6120 pim_igmp_other_querier_timer_on(igmp
);
6122 zassert(!igmp
->t_igmp_query_timer
);
6123 zassert(igmp
->t_other_querier_timer
);
6127 static void change_query_interval(struct pim_interface
*pim_ifp
,
6130 struct listnode
*sock_node
;
6131 struct igmp_sock
*igmp
;
6133 pim_ifp
->igmp_default_query_interval
= query_interval
;
6135 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
6136 igmp_sock_query_interval_reconfig(igmp
);
6137 igmp_sock_query_reschedule(igmp
);
6141 static void change_query_max_response_time(struct pim_interface
*pim_ifp
,
6142 int query_max_response_time_dsec
)
6144 struct listnode
*sock_node
;
6145 struct igmp_sock
*igmp
;
6147 pim_ifp
->igmp_query_max_response_time_dsec
=
6148 query_max_response_time_dsec
;
6151 Below we modify socket/group/source timers in order to quickly
6152 reflect the change. Otherwise, those timers would eventually catch
6156 /* scan all sockets */
6157 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
6158 struct listnode
*grp_node
;
6159 struct igmp_group
*grp
;
6161 /* reschedule socket general query */
6162 igmp_sock_query_reschedule(igmp
);
6164 /* scan socket groups */
6165 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grp_node
,
6167 struct listnode
*src_node
;
6168 struct igmp_source
*src
;
6170 /* reset group timers for groups in EXCLUDE mode */
6171 if (grp
->group_filtermode_isexcl
) {
6172 igmp_group_reset_gmi(grp
);
6175 /* scan group sources */
6176 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
,
6179 /* reset source timers for sources with running
6181 if (src
->t_source_timer
) {
6182 igmp_source_reset_gmi(igmp
, grp
, src
);
6189 #define IGMP_QUERY_INTERVAL_MIN (1)
6190 #define IGMP_QUERY_INTERVAL_MAX (1800)
6192 DEFUN (interface_ip_igmp_query_interval
,
6193 interface_ip_igmp_query_interval_cmd
,
6194 "ip igmp query-interval (1-1800)",
6197 IFACE_IGMP_QUERY_INTERVAL_STR
6198 "Query interval in seconds\n")
6200 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6201 struct pim_interface
*pim_ifp
= ifp
->info
;
6203 int query_interval_dsec
;
6207 ret
= pim_cmd_igmp_start(vty
, ifp
);
6208 if (ret
!= CMD_SUCCESS
)
6210 pim_ifp
= ifp
->info
;
6213 query_interval
= atoi(argv
[3]->arg
);
6214 query_interval_dsec
= 10 * query_interval
;
6217 It seems we don't need to check bounds since command.c does it
6218 already, but we verify them anyway for extra safety.
6220 if (query_interval
< IGMP_QUERY_INTERVAL_MIN
) {
6222 "General query interval %d lower than minimum %d\n",
6223 query_interval
, IGMP_QUERY_INTERVAL_MIN
);
6224 return CMD_WARNING_CONFIG_FAILED
;
6226 if (query_interval
> IGMP_QUERY_INTERVAL_MAX
) {
6228 "General query interval %d higher than maximum %d\n",
6229 query_interval
, IGMP_QUERY_INTERVAL_MAX
);
6230 return CMD_WARNING_CONFIG_FAILED
;
6233 if (query_interval_dsec
<= pim_ifp
->igmp_query_max_response_time_dsec
) {
6235 "Can't set general query interval %d dsec <= query max response time %d dsec.\n",
6236 query_interval_dsec
,
6237 pim_ifp
->igmp_query_max_response_time_dsec
);
6238 return CMD_WARNING_CONFIG_FAILED
;
6241 change_query_interval(pim_ifp
, query_interval
);
6246 DEFUN (interface_no_ip_igmp_query_interval
,
6247 interface_no_ip_igmp_query_interval_cmd
,
6248 "no ip igmp query-interval",
6252 IFACE_IGMP_QUERY_INTERVAL_STR
)
6254 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6255 struct pim_interface
*pim_ifp
= ifp
->info
;
6256 int default_query_interval_dsec
;
6261 default_query_interval_dsec
= IGMP_GENERAL_QUERY_INTERVAL
* 10;
6263 if (default_query_interval_dsec
6264 <= pim_ifp
->igmp_query_max_response_time_dsec
) {
6266 "Can't set default general query interval %d dsec <= query max response time %d dsec.\n",
6267 default_query_interval_dsec
,
6268 pim_ifp
->igmp_query_max_response_time_dsec
);
6269 return CMD_WARNING_CONFIG_FAILED
;
6272 change_query_interval(pim_ifp
, IGMP_GENERAL_QUERY_INTERVAL
);
6277 DEFUN (interface_ip_igmp_version
,
6278 interface_ip_igmp_version_cmd
,
6279 "ip igmp version (2-3)",
6283 "IGMP version number\n")
6285 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6286 struct pim_interface
*pim_ifp
= ifp
->info
;
6287 int igmp_version
, old_version
= 0;
6291 ret
= pim_cmd_igmp_start(vty
, ifp
);
6292 if (ret
!= CMD_SUCCESS
)
6294 pim_ifp
= ifp
->info
;
6297 igmp_version
= atoi(argv
[3]->arg
);
6298 old_version
= pim_ifp
->igmp_version
;
6299 pim_ifp
->igmp_version
= igmp_version
;
6301 // Check if IGMP is Enabled otherwise, enable on interface
6302 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
6303 PIM_IF_DO_IGMP(pim_ifp
->options
);
6304 pim_if_addr_add_all(ifp
);
6305 pim_if_membership_refresh(ifp
);
6306 old_version
= igmp_version
;
6307 // avoid refreshing membership again.
6309 /* Current and new version is different refresh existing
6310 membership. Going from 3 -> 2 or 2 -> 3. */
6311 if (old_version
!= igmp_version
)
6312 pim_if_membership_refresh(ifp
);
6317 DEFUN (interface_no_ip_igmp_version
,
6318 interface_no_ip_igmp_version_cmd
,
6319 "no ip igmp version (2-3)",
6324 "IGMP version number\n")
6326 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6327 struct pim_interface
*pim_ifp
= ifp
->info
;
6332 pim_ifp
->igmp_version
= IGMP_DEFAULT_VERSION
;
6337 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
6338 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
6340 DEFUN (interface_ip_igmp_query_max_response_time
,
6341 interface_ip_igmp_query_max_response_time_cmd
,
6342 "ip igmp query-max-response-time (10-250)",
6345 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
6346 "Query response value in deci-seconds\n")
6348 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6349 struct pim_interface
*pim_ifp
= ifp
->info
;
6350 int query_max_response_time
;
6354 ret
= pim_cmd_igmp_start(vty
, ifp
);
6355 if (ret
!= CMD_SUCCESS
)
6357 pim_ifp
= ifp
->info
;
6360 query_max_response_time
= atoi(argv
[3]->arg
);
6362 if (query_max_response_time
6363 >= pim_ifp
->igmp_default_query_interval
* 10) {
6365 "Can't set query max response time %d sec >= general query interval %d sec\n",
6366 query_max_response_time
,
6367 pim_ifp
->igmp_default_query_interval
);
6368 return CMD_WARNING_CONFIG_FAILED
;
6371 change_query_max_response_time(pim_ifp
, query_max_response_time
);
6376 DEFUN (interface_no_ip_igmp_query_max_response_time
,
6377 interface_no_ip_igmp_query_max_response_time_cmd
,
6378 "no ip igmp query-max-response-time (10-250)",
6382 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
6383 "Time for response in deci-seconds\n")
6385 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6386 struct pim_interface
*pim_ifp
= ifp
->info
;
6391 change_query_max_response_time(pim_ifp
,
6392 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
6397 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
6398 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
6400 DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec
,
6401 interface_ip_igmp_query_max_response_time_dsec_cmd
,
6402 "ip igmp query-max-response-time-dsec (10-250)",
6405 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
6406 "Query response value in deciseconds\n")
6408 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6409 struct pim_interface
*pim_ifp
= ifp
->info
;
6410 int query_max_response_time_dsec
;
6411 int default_query_interval_dsec
;
6415 ret
= pim_cmd_igmp_start(vty
, ifp
);
6416 if (ret
!= CMD_SUCCESS
)
6418 pim_ifp
= ifp
->info
;
6421 query_max_response_time_dsec
= atoi(argv
[4]->arg
);
6423 default_query_interval_dsec
= 10 * pim_ifp
->igmp_default_query_interval
;
6425 if (query_max_response_time_dsec
>= default_query_interval_dsec
) {
6427 "Can't set query max response time %d dsec >= general query interval %d dsec\n",
6428 query_max_response_time_dsec
,
6429 default_query_interval_dsec
);
6430 return CMD_WARNING_CONFIG_FAILED
;
6433 change_query_max_response_time(pim_ifp
, query_max_response_time_dsec
);
6438 DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec
,
6439 interface_no_ip_igmp_query_max_response_time_dsec_cmd
,
6440 "no ip igmp query-max-response-time-dsec",
6444 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
)
6446 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6447 struct pim_interface
*pim_ifp
= ifp
->info
;
6452 change_query_max_response_time(pim_ifp
,
6453 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
6458 DEFUN (interface_ip_pim_drprio
,
6459 interface_ip_pim_drprio_cmd
,
6460 "ip pim drpriority (1-4294967295)",
6463 "Set the Designated Router Election Priority\n"
6464 "Value of the new DR Priority\n")
6466 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6468 struct pim_interface
*pim_ifp
= ifp
->info
;
6469 uint32_t old_dr_prio
;
6472 vty_out(vty
, "Please enable PIM on interface, first\n");
6473 return CMD_WARNING_CONFIG_FAILED
;
6476 old_dr_prio
= pim_ifp
->pim_dr_priority
;
6478 pim_ifp
->pim_dr_priority
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
6480 if (old_dr_prio
!= pim_ifp
->pim_dr_priority
) {
6481 pim_if_dr_election(ifp
);
6482 pim_hello_restart_now(ifp
);
6488 DEFUN (interface_no_ip_pim_drprio
,
6489 interface_no_ip_pim_drprio_cmd
,
6490 "no ip pim drpriority [(1-4294967295)]",
6494 "Revert the Designated Router Priority to default\n"
6495 "Old Value of the Priority\n")
6497 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6498 struct pim_interface
*pim_ifp
= ifp
->info
;
6501 vty_out(vty
, "Pim not enabled on this interface\n");
6502 return CMD_WARNING_CONFIG_FAILED
;
6505 if (pim_ifp
->pim_dr_priority
!= PIM_DEFAULT_DR_PRIORITY
) {
6506 pim_ifp
->pim_dr_priority
= PIM_DEFAULT_DR_PRIORITY
;
6507 pim_if_dr_election(ifp
);
6508 pim_hello_restart_now(ifp
);
6514 static int pim_cmd_interface_add(struct interface
*ifp
)
6516 struct pim_interface
*pim_ifp
= ifp
->info
;
6519 pim_ifp
= pim_if_new(ifp
, false, true, false,
6520 false /*vxlan_term*/);
6525 PIM_IF_DO_PIM(pim_ifp
->options
);
6528 pim_if_addr_add_all(ifp
);
6529 pim_if_membership_refresh(ifp
);
6533 DEFPY_HIDDEN (pim_test_sg_keepalive
,
6534 pim_test_sg_keepalive_cmd
,
6535 "test pim [vrf NAME$name] keepalive-reset A.B.C.D$source A.B.C.D$group",
6539 "Reset the Keepalive Timer\n"
6540 "The Source we are resetting\n"
6541 "The Group we are resetting\n")
6543 struct pim_upstream
*up
;
6544 struct pim_instance
*pim
;
6545 struct prefix_sg sg
;
6551 pim
= pim_get_pim_instance(VRF_DEFAULT
);
6553 struct vrf
*vrf
= vrf_lookup_by_name(name
);
6556 vty_out(vty
, "%% Vrf specified: %s does not exist\n",
6561 pim
= pim_get_pim_instance(vrf
->vrf_id
);
6565 vty_out(vty
, "%% Unable to find pim instance\n");
6569 up
= pim_upstream_find(pim
, &sg
);
6571 vty_out(vty
, "%% Unable to find %s specified\n",
6572 pim_str_sg_dump(&sg
));
6576 vty_out(vty
, "Setting %s to current keep alive time: %d\n",
6577 pim_str_sg_dump(&sg
), pim
->keep_alive_time
);
6578 pim_upstream_keep_alive_timer_start(up
, pim
->keep_alive_time
);
6583 DEFPY_HIDDEN (interface_ip_pim_activeactive
,
6584 interface_ip_pim_activeactive_cmd
,
6585 "[no$no] ip pim active-active",
6589 "Mark interface as Active-Active for MLAG operations, Hidden because not finished yet\n")
6591 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6592 struct pim_interface
*pim_ifp
;
6594 if (!no
&& !pim_cmd_interface_add(ifp
)) {
6595 vty_out(vty
, "Could not enable PIM SM active-active on interface\n");
6596 return CMD_WARNING_CONFIG_FAILED
;
6599 pim_ifp
= ifp
->info
;
6601 pim_ifp
->activeactive
= false;
6603 pim_ifp
->activeactive
= true;
6608 DEFUN_HIDDEN (interface_ip_pim_ssm
,
6609 interface_ip_pim_ssm_cmd
,
6615 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6617 if (!pim_cmd_interface_add(ifp
)) {
6618 vty_out(vty
, "Could not enable PIM SM on interface\n");
6619 return CMD_WARNING_CONFIG_FAILED
;
6623 "WARN: Enabled PIM SM on interface; configure PIM SSM "
6624 "range if needed\n");
6628 static int interface_ip_pim_helper(struct vty
*vty
)
6630 struct pim_interface
*pim_ifp
;
6632 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6634 if (!pim_cmd_interface_add(ifp
)) {
6635 vty_out(vty
, "Could not enable PIM SM on interface\n");
6636 return CMD_WARNING_CONFIG_FAILED
;
6639 pim_ifp
= ifp
->info
;
6641 pim_if_create_pimreg(pim_ifp
->pim
);
6646 DEFUN_HIDDEN (interface_ip_pim_sm
,
6647 interface_ip_pim_sm_cmd
,
6653 return interface_ip_pim_helper(vty
);
6656 DEFUN (interface_ip_pim
,
6657 interface_ip_pim_cmd
,
6662 return interface_ip_pim_helper(vty
);
6665 static int pim_cmd_interface_delete(struct interface
*ifp
)
6667 struct pim_interface
*pim_ifp
= ifp
->info
;
6672 PIM_IF_DONT_PIM(pim_ifp
->options
);
6674 pim_if_membership_clear(ifp
);
6677 pim_sock_delete() removes all neighbors from
6678 pim_ifp->pim_neighbor_list.
6680 pim_sock_delete(ifp
, "pim unconfigured on interface");
6682 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
6683 pim_if_addr_del_all(ifp
);
6690 static int interface_no_ip_pim_helper(struct vty
*vty
)
6692 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6693 if (!pim_cmd_interface_delete(ifp
)) {
6694 vty_out(vty
, "Unable to delete interface information\n");
6695 return CMD_WARNING_CONFIG_FAILED
;
6701 DEFUN_HIDDEN (interface_no_ip_pim_ssm
,
6702 interface_no_ip_pim_ssm_cmd
,
6709 return interface_no_ip_pim_helper(vty
);
6712 DEFUN_HIDDEN (interface_no_ip_pim_sm
,
6713 interface_no_ip_pim_sm_cmd
,
6720 return interface_no_ip_pim_helper(vty
);
6723 DEFUN (interface_no_ip_pim
,
6724 interface_no_ip_pim_cmd
,
6730 return interface_no_ip_pim_helper(vty
);
6734 DEFUN(interface_ip_pim_boundary_oil
,
6735 interface_ip_pim_boundary_oil_cmd
,
6736 "ip multicast boundary oil WORD",
6738 "Generic multicast configuration options\n"
6739 "Define multicast boundary\n"
6740 "Filter OIL by group using prefix list\n"
6741 "Prefix list to filter OIL with\n")
6743 VTY_DECLVAR_CONTEXT(interface
, iif
);
6744 struct pim_interface
*pim_ifp
;
6747 argv_find(argv
, argc
, "WORD", &idx
);
6749 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6751 if (pim_ifp
->boundary_oil_plist
)
6752 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
6754 pim_ifp
->boundary_oil_plist
=
6755 XSTRDUP(MTYPE_PIM_INTERFACE
, argv
[idx
]->arg
);
6757 /* Interface will be pruned from OIL on next Join */
6761 DEFUN(interface_no_ip_pim_boundary_oil
,
6762 interface_no_ip_pim_boundary_oil_cmd
,
6763 "no ip multicast boundary oil [WORD]",
6766 "Generic multicast configuration options\n"
6767 "Define multicast boundary\n"
6768 "Filter OIL by group using prefix list\n"
6769 "Prefix list to filter OIL with\n")
6771 VTY_DECLVAR_CONTEXT(interface
, iif
);
6772 struct pim_interface
*pim_ifp
;
6775 argv_find(argv
, argc
, "WORD", &idx
);
6777 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6779 if (pim_ifp
->boundary_oil_plist
)
6780 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
6785 DEFUN (interface_ip_mroute
,
6786 interface_ip_mroute_cmd
,
6787 "ip mroute INTERFACE A.B.C.D",
6789 "Add multicast route\n"
6790 "Outgoing interface name\n"
6793 VTY_DECLVAR_CONTEXT(interface
, iif
);
6794 struct pim_interface
*pim_ifp
;
6795 struct pim_instance
*pim
;
6796 int idx_interface
= 2;
6798 struct interface
*oif
;
6799 const char *oifname
;
6800 const char *grp_str
;
6801 struct in_addr grp_addr
;
6802 struct in_addr src_addr
;
6805 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6808 oifname
= argv
[idx_interface
]->arg
;
6809 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6811 vty_out(vty
, "No such interface name %s\n", oifname
);
6815 grp_str
= argv
[idx_ipv4
]->arg
;
6816 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6818 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6819 errno
, safe_strerror(errno
));
6823 src_addr
.s_addr
= INADDR_ANY
;
6825 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6826 vty_out(vty
, "Failed to add route\n");
6833 DEFUN (interface_ip_mroute_source
,
6834 interface_ip_mroute_source_cmd
,
6835 "ip mroute INTERFACE A.B.C.D A.B.C.D",
6837 "Add multicast route\n"
6838 "Outgoing interface name\n"
6842 VTY_DECLVAR_CONTEXT(interface
, iif
);
6843 struct pim_interface
*pim_ifp
;
6844 struct pim_instance
*pim
;
6845 int idx_interface
= 2;
6848 struct interface
*oif
;
6849 const char *oifname
;
6850 const char *grp_str
;
6851 struct in_addr grp_addr
;
6852 const char *src_str
;
6853 struct in_addr src_addr
;
6856 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6859 oifname
= argv
[idx_interface
]->arg
;
6860 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6862 vty_out(vty
, "No such interface name %s\n", oifname
);
6866 grp_str
= argv
[idx_ipv4
]->arg
;
6867 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6869 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6870 errno
, safe_strerror(errno
));
6874 src_str
= argv
[idx_ipv4_2
]->arg
;
6875 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
6877 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
6878 errno
, safe_strerror(errno
));
6882 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6883 vty_out(vty
, "Failed to add route\n");
6890 DEFUN (interface_no_ip_mroute
,
6891 interface_no_ip_mroute_cmd
,
6892 "no ip mroute INTERFACE A.B.C.D",
6895 "Add multicast route\n"
6896 "Outgoing interface name\n"
6899 VTY_DECLVAR_CONTEXT(interface
, iif
);
6900 struct pim_interface
*pim_ifp
;
6901 struct pim_instance
*pim
;
6902 int idx_interface
= 3;
6904 struct interface
*oif
;
6905 const char *oifname
;
6906 const char *grp_str
;
6907 struct in_addr grp_addr
;
6908 struct in_addr src_addr
;
6911 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6914 oifname
= argv
[idx_interface
]->arg
;
6915 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6917 vty_out(vty
, "No such interface name %s\n", oifname
);
6921 grp_str
= argv
[idx_ipv4
]->arg
;
6922 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6924 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6925 errno
, safe_strerror(errno
));
6929 src_addr
.s_addr
= INADDR_ANY
;
6931 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6932 vty_out(vty
, "Failed to remove route\n");
6939 DEFUN (interface_no_ip_mroute_source
,
6940 interface_no_ip_mroute_source_cmd
,
6941 "no ip mroute INTERFACE A.B.C.D A.B.C.D",
6944 "Add multicast route\n"
6945 "Outgoing interface name\n"
6949 VTY_DECLVAR_CONTEXT(interface
, iif
);
6950 struct pim_interface
*pim_ifp
;
6951 struct pim_instance
*pim
;
6952 int idx_interface
= 3;
6955 struct interface
*oif
;
6956 const char *oifname
;
6957 const char *grp_str
;
6958 struct in_addr grp_addr
;
6959 const char *src_str
;
6960 struct in_addr src_addr
;
6963 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6966 oifname
= argv
[idx_interface
]->arg
;
6967 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6969 vty_out(vty
, "No such interface name %s\n", oifname
);
6973 grp_str
= argv
[idx_ipv4
]->arg
;
6974 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6976 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6977 errno
, safe_strerror(errno
));
6981 src_str
= argv
[idx_ipv4_2
]->arg
;
6982 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
6984 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
6985 errno
, safe_strerror(errno
));
6989 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6990 vty_out(vty
, "Failed to remove route\n");
6997 DEFUN (interface_ip_pim_hello
,
6998 interface_ip_pim_hello_cmd
,
6999 "ip pim hello (1-180) [(1-180)]",
7003 IFACE_PIM_HELLO_TIME_STR
7004 IFACE_PIM_HELLO_HOLD_STR
)
7006 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7009 struct pim_interface
*pim_ifp
= ifp
->info
;
7012 if (!pim_cmd_interface_add(ifp
)) {
7013 vty_out(vty
, "Could not enable PIM SM on interface\n");
7014 return CMD_WARNING_CONFIG_FAILED
;
7018 pim_ifp
= ifp
->info
;
7019 pim_ifp
->pim_hello_period
= strtol(argv
[idx_time
]->arg
, NULL
, 10);
7021 if (argc
== idx_hold
+ 1)
7022 pim_ifp
->pim_default_holdtime
=
7023 strtol(argv
[idx_hold
]->arg
, NULL
, 10);
7028 DEFUN (interface_no_ip_pim_hello
,
7029 interface_no_ip_pim_hello_cmd
,
7030 "no ip pim hello [(1-180) (1-180)]",
7035 IFACE_PIM_HELLO_TIME_STR
7036 IFACE_PIM_HELLO_HOLD_STR
)
7038 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7039 struct pim_interface
*pim_ifp
= ifp
->info
;
7042 vty_out(vty
, "Pim not enabled on this interface\n");
7043 return CMD_WARNING_CONFIG_FAILED
;
7046 pim_ifp
->pim_hello_period
= PIM_DEFAULT_HELLO_PERIOD
;
7047 pim_ifp
->pim_default_holdtime
= -1;
7058 PIM_DO_DEBUG_IGMP_EVENTS
;
7059 PIM_DO_DEBUG_IGMP_PACKETS
;
7060 PIM_DO_DEBUG_IGMP_TRACE
;
7064 DEFUN (no_debug_igmp
,
7071 PIM_DONT_DEBUG_IGMP_EVENTS
;
7072 PIM_DONT_DEBUG_IGMP_PACKETS
;
7073 PIM_DONT_DEBUG_IGMP_TRACE
;
7078 DEFUN (debug_igmp_events
,
7079 debug_igmp_events_cmd
,
7080 "debug igmp events",
7083 DEBUG_IGMP_EVENTS_STR
)
7085 PIM_DO_DEBUG_IGMP_EVENTS
;
7089 DEFUN (no_debug_igmp_events
,
7090 no_debug_igmp_events_cmd
,
7091 "no debug igmp events",
7095 DEBUG_IGMP_EVENTS_STR
)
7097 PIM_DONT_DEBUG_IGMP_EVENTS
;
7102 DEFUN (debug_igmp_packets
,
7103 debug_igmp_packets_cmd
,
7104 "debug igmp packets",
7107 DEBUG_IGMP_PACKETS_STR
)
7109 PIM_DO_DEBUG_IGMP_PACKETS
;
7113 DEFUN (no_debug_igmp_packets
,
7114 no_debug_igmp_packets_cmd
,
7115 "no debug igmp packets",
7119 DEBUG_IGMP_PACKETS_STR
)
7121 PIM_DONT_DEBUG_IGMP_PACKETS
;
7126 DEFUN (debug_igmp_trace
,
7127 debug_igmp_trace_cmd
,
7131 DEBUG_IGMP_TRACE_STR
)
7133 PIM_DO_DEBUG_IGMP_TRACE
;
7137 DEFUN (no_debug_igmp_trace
,
7138 no_debug_igmp_trace_cmd
,
7139 "no debug igmp trace",
7143 DEBUG_IGMP_TRACE_STR
)
7145 PIM_DONT_DEBUG_IGMP_TRACE
;
7150 DEFUN (debug_mroute
,
7156 PIM_DO_DEBUG_MROUTE
;
7160 DEFUN (debug_mroute_detail
,
7161 debug_mroute_detail_cmd
,
7162 "debug mroute detail",
7167 PIM_DO_DEBUG_MROUTE_DETAIL
;
7171 DEFUN (no_debug_mroute
,
7172 no_debug_mroute_cmd
,
7178 PIM_DONT_DEBUG_MROUTE
;
7182 DEFUN (no_debug_mroute_detail
,
7183 no_debug_mroute_detail_cmd
,
7184 "no debug mroute detail",
7190 PIM_DONT_DEBUG_MROUTE_DETAIL
;
7194 DEFUN (debug_pim_static
,
7195 debug_pim_static_cmd
,
7201 PIM_DO_DEBUG_STATIC
;
7205 DEFUN (no_debug_pim_static
,
7206 no_debug_pim_static_cmd
,
7207 "no debug pim static",
7213 PIM_DONT_DEBUG_STATIC
;
7224 PIM_DO_DEBUG_PIM_EVENTS
;
7225 PIM_DO_DEBUG_PIM_PACKETS
;
7226 PIM_DO_DEBUG_PIM_TRACE
;
7227 PIM_DO_DEBUG_MSDP_EVENTS
;
7228 PIM_DO_DEBUG_MSDP_PACKETS
;
7232 DEFUN (no_debug_pim
,
7239 PIM_DONT_DEBUG_PIM_EVENTS
;
7240 PIM_DONT_DEBUG_PIM_PACKETS
;
7241 PIM_DONT_DEBUG_PIM_TRACE
;
7242 PIM_DONT_DEBUG_MSDP_EVENTS
;
7243 PIM_DONT_DEBUG_MSDP_PACKETS
;
7245 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
7246 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
7251 DEFUN (debug_pim_nht
,
7256 "Nexthop Tracking\n")
7258 PIM_DO_DEBUG_PIM_NHT
;
7262 DEFUN (no_debug_pim_nht
,
7263 no_debug_pim_nht_cmd
,
7268 "Nexthop Tracking\n")
7270 PIM_DONT_DEBUG_PIM_NHT
;
7274 DEFUN (debug_pim_nht_rp
,
7275 debug_pim_nht_rp_cmd
,
7279 "Nexthop Tracking\n"
7280 "RP Nexthop Tracking\n")
7282 PIM_DO_DEBUG_PIM_NHT_RP
;
7286 DEFUN (no_debug_pim_nht_rp
,
7287 no_debug_pim_nht_rp_cmd
,
7288 "no debug pim nht rp",
7292 "Nexthop Tracking\n"
7293 "RP Nexthop Tracking\n")
7295 PIM_DONT_DEBUG_PIM_NHT_RP
;
7299 DEFUN (debug_pim_events
,
7300 debug_pim_events_cmd
,
7304 DEBUG_PIM_EVENTS_STR
)
7306 PIM_DO_DEBUG_PIM_EVENTS
;
7310 DEFUN (no_debug_pim_events
,
7311 no_debug_pim_events_cmd
,
7312 "no debug pim events",
7316 DEBUG_PIM_EVENTS_STR
)
7318 PIM_DONT_DEBUG_PIM_EVENTS
;
7322 DEFUN (debug_pim_packets
,
7323 debug_pim_packets_cmd
,
7324 "debug pim packets [<hello|joins|register>]",
7327 DEBUG_PIM_PACKETS_STR
7328 DEBUG_PIM_HELLO_PACKETS_STR
7329 DEBUG_PIM_J_P_PACKETS_STR
7330 DEBUG_PIM_PIM_REG_PACKETS_STR
)
7333 if (argv_find(argv
, argc
, "hello", &idx
)) {
7334 PIM_DO_DEBUG_PIM_HELLO
;
7335 vty_out(vty
, "PIM Hello debugging is on\n");
7336 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
7337 PIM_DO_DEBUG_PIM_J_P
;
7338 vty_out(vty
, "PIM Join/Prune debugging is on\n");
7339 } else if (argv_find(argv
, argc
, "register", &idx
)) {
7340 PIM_DO_DEBUG_PIM_REG
;
7341 vty_out(vty
, "PIM Register debugging is on\n");
7343 PIM_DO_DEBUG_PIM_PACKETS
;
7344 vty_out(vty
, "PIM Packet debugging is on \n");
7349 DEFUN (no_debug_pim_packets
,
7350 no_debug_pim_packets_cmd
,
7351 "no debug pim packets [<hello|joins|register>]",
7355 DEBUG_PIM_PACKETS_STR
7356 DEBUG_PIM_HELLO_PACKETS_STR
7357 DEBUG_PIM_J_P_PACKETS_STR
7358 DEBUG_PIM_PIM_REG_PACKETS_STR
)
7361 if (argv_find(argv
, argc
, "hello", &idx
)) {
7362 PIM_DONT_DEBUG_PIM_HELLO
;
7363 vty_out(vty
, "PIM Hello debugging is off \n");
7364 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
7365 PIM_DONT_DEBUG_PIM_J_P
;
7366 vty_out(vty
, "PIM Join/Prune debugging is off \n");
7367 } else if (argv_find(argv
, argc
, "register", &idx
)) {
7368 PIM_DONT_DEBUG_PIM_REG
;
7369 vty_out(vty
, "PIM Register debugging is off\n");
7371 PIM_DONT_DEBUG_PIM_PACKETS
;
7377 DEFUN (debug_pim_packetdump_send
,
7378 debug_pim_packetdump_send_cmd
,
7379 "debug pim packet-dump send",
7382 DEBUG_PIM_PACKETDUMP_STR
7383 DEBUG_PIM_PACKETDUMP_SEND_STR
)
7385 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND
;
7389 DEFUN (no_debug_pim_packetdump_send
,
7390 no_debug_pim_packetdump_send_cmd
,
7391 "no debug pim packet-dump send",
7395 DEBUG_PIM_PACKETDUMP_STR
7396 DEBUG_PIM_PACKETDUMP_SEND_STR
)
7398 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
7402 DEFUN (debug_pim_packetdump_recv
,
7403 debug_pim_packetdump_recv_cmd
,
7404 "debug pim packet-dump receive",
7407 DEBUG_PIM_PACKETDUMP_STR
7408 DEBUG_PIM_PACKETDUMP_RECV_STR
)
7410 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV
;
7414 DEFUN (no_debug_pim_packetdump_recv
,
7415 no_debug_pim_packetdump_recv_cmd
,
7416 "no debug pim packet-dump receive",
7420 DEBUG_PIM_PACKETDUMP_STR
7421 DEBUG_PIM_PACKETDUMP_RECV_STR
)
7423 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
7427 DEFUN (debug_pim_trace
,
7428 debug_pim_trace_cmd
,
7432 DEBUG_PIM_TRACE_STR
)
7434 PIM_DO_DEBUG_PIM_TRACE
;
7438 DEFUN (debug_pim_trace_detail
,
7439 debug_pim_trace_detail_cmd
,
7440 "debug pim trace detail",
7444 "Detailed Information\n")
7446 PIM_DO_DEBUG_PIM_TRACE_DETAIL
;
7450 DEFUN (no_debug_pim_trace
,
7451 no_debug_pim_trace_cmd
,
7452 "no debug pim trace",
7456 DEBUG_PIM_TRACE_STR
)
7458 PIM_DONT_DEBUG_PIM_TRACE
;
7462 DEFUN (no_debug_pim_trace_detail
,
7463 no_debug_pim_trace_detail_cmd
,
7464 "no debug pim trace detail",
7469 "Detailed Information\n")
7471 PIM_DONT_DEBUG_PIM_TRACE_DETAIL
;
7475 DEFUN (debug_ssmpingd
,
7481 PIM_DO_DEBUG_SSMPINGD
;
7485 DEFUN (no_debug_ssmpingd
,
7486 no_debug_ssmpingd_cmd
,
7487 "no debug ssmpingd",
7492 PIM_DONT_DEBUG_SSMPINGD
;
7496 DEFUN (debug_pim_zebra
,
7497 debug_pim_zebra_cmd
,
7501 DEBUG_PIM_ZEBRA_STR
)
7507 DEFUN (no_debug_pim_zebra
,
7508 no_debug_pim_zebra_cmd
,
7509 "no debug pim zebra",
7513 DEBUG_PIM_ZEBRA_STR
)
7515 PIM_DONT_DEBUG_ZEBRA
;
7519 DEFUN (debug_pim_vxlan
,
7520 debug_pim_vxlan_cmd
,
7524 DEBUG_PIM_VXLAN_STR
)
7530 DEFUN (no_debug_pim_vxlan
,
7531 no_debug_pim_vxlan_cmd
,
7532 "no debug pim vxlan",
7536 DEBUG_PIM_VXLAN_STR
)
7538 PIM_DONT_DEBUG_VXLAN
;
7548 PIM_DO_DEBUG_MSDP_EVENTS
;
7549 PIM_DO_DEBUG_MSDP_PACKETS
;
7553 DEFUN (no_debug_msdp
,
7560 PIM_DONT_DEBUG_MSDP_EVENTS
;
7561 PIM_DONT_DEBUG_MSDP_PACKETS
;
7565 DEFUN (debug_msdp_events
,
7566 debug_msdp_events_cmd
,
7567 "debug msdp events",
7570 DEBUG_MSDP_EVENTS_STR
)
7572 PIM_DO_DEBUG_MSDP_EVENTS
;
7576 DEFUN (no_debug_msdp_events
,
7577 no_debug_msdp_events_cmd
,
7578 "no debug msdp events",
7582 DEBUG_MSDP_EVENTS_STR
)
7584 PIM_DONT_DEBUG_MSDP_EVENTS
;
7588 DEFUN (debug_msdp_packets
,
7589 debug_msdp_packets_cmd
,
7590 "debug msdp packets",
7593 DEBUG_MSDP_PACKETS_STR
)
7595 PIM_DO_DEBUG_MSDP_PACKETS
;
7599 DEFUN (no_debug_msdp_packets
,
7600 no_debug_msdp_packets_cmd
,
7601 "no debug msdp packets",
7605 DEBUG_MSDP_PACKETS_STR
)
7607 PIM_DONT_DEBUG_MSDP_PACKETS
;
7611 DEFUN (debug_mtrace
,
7617 PIM_DO_DEBUG_MTRACE
;
7621 DEFUN (no_debug_mtrace
,
7622 no_debug_mtrace_cmd
,
7628 PIM_DONT_DEBUG_MTRACE
;
7632 DEFUN_NOSH (show_debugging_pim
,
7633 show_debugging_pim_cmd
,
7634 "show debugging [pim]",
7639 vty_out(vty
, "PIM debugging status\n");
7641 pim_debug_config_write(vty
);
7646 static int interface_pim_use_src_cmd_worker(struct vty
*vty
, const char *source
)
7649 struct in_addr source_addr
;
7650 int ret
= CMD_SUCCESS
;
7651 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7653 result
= inet_pton(AF_INET
, source
, &source_addr
);
7655 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", source
,
7656 errno
, safe_strerror(errno
));
7657 return CMD_WARNING_CONFIG_FAILED
;
7660 result
= pim_update_source_set(ifp
, source_addr
);
7664 case PIM_IFACE_NOT_FOUND
:
7665 ret
= CMD_WARNING_CONFIG_FAILED
;
7666 vty_out(vty
, "Pim not enabled on this interface\n");
7668 case PIM_UPDATE_SOURCE_DUP
:
7670 vty_out(vty
, "%% Source already set to %s\n", source
);
7673 ret
= CMD_WARNING_CONFIG_FAILED
;
7674 vty_out(vty
, "%% Source set failed\n");
7680 DEFUN (interface_pim_use_source
,
7681 interface_pim_use_source_cmd
,
7682 "ip pim use-source A.B.C.D",
7685 "Configure primary IP address\n"
7686 "source ip address\n")
7688 return interface_pim_use_src_cmd_worker(vty
, argv
[3]->arg
);
7691 DEFUN (interface_no_pim_use_source
,
7692 interface_no_pim_use_source_cmd
,
7693 "no ip pim use-source [A.B.C.D]",
7697 "Delete source IP address\n"
7698 "source ip address\n")
7700 return interface_pim_use_src_cmd_worker(vty
, "0.0.0.0");
7708 "Enables BFD support\n")
7710 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7711 struct pim_interface
*pim_ifp
= ifp
->info
;
7712 struct bfd_info
*bfd_info
= NULL
;
7715 if (!pim_cmd_interface_add(ifp
)) {
7716 vty_out(vty
, "Could not enable PIM SM on interface\n");
7720 pim_ifp
= ifp
->info
;
7722 bfd_info
= pim_ifp
->bfd_info
;
7724 if (!bfd_info
|| !CHECK_FLAG(bfd_info
->flags
, BFD_FLAG_PARAM_CFG
))
7725 pim_bfd_if_param_set(ifp
, BFD_DEF_MIN_RX
, BFD_DEF_MIN_TX
,
7726 BFD_DEF_DETECT_MULT
, 1);
7731 DEFUN (no_ip_pim_bfd
,
7737 "Disables BFD support\n")
7739 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7740 struct pim_interface
*pim_ifp
= ifp
->info
;
7743 vty_out(vty
, "Pim not enabled on this interface\n");
7747 if (pim_ifp
->bfd_info
) {
7748 pim_bfd_reg_dereg_all_nbr(ifp
, ZEBRA_BFD_DEST_DEREGISTER
);
7749 bfd_info_free(&(pim_ifp
->bfd_info
));
7759 #endif /* HAVE_BFDD */
7761 ip_pim_bfd_param_cmd
,
7762 "ip pim bfd (2-255) (50-60000) (50-60000)",
7765 "Enables BFD support\n"
7766 "Detect Multiplier\n"
7767 "Required min receive interval\n"
7768 "Desired min transmit interval\n")
7770 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7772 int idx_number_2
= 4;
7773 int idx_number_3
= 5;
7778 struct pim_interface
*pim_ifp
= ifp
->info
;
7781 if (!pim_cmd_interface_add(ifp
)) {
7782 vty_out(vty
, "Could not enable PIM SM on interface\n");
7787 if ((ret
= bfd_validate_param(
7788 vty
, argv
[idx_number
]->arg
, argv
[idx_number_2
]->arg
,
7789 argv
[idx_number_3
]->arg
, &dm_val
, &rx_val
, &tx_val
))
7793 pim_bfd_if_param_set(ifp
, rx_val
, tx_val
, dm_val
, 0);
7799 ALIAS(no_ip_pim_bfd
, no_ip_pim_bfd_param_cmd
,
7800 "no ip pim bfd (2-255) (50-60000) (50-60000)", NO_STR IP_STR PIM_STR
7801 "Enables BFD support\n"
7802 "Detect Multiplier\n"
7803 "Required min receive interval\n"
7804 "Desired min transmit interval\n")
7805 #endif /* !HAVE_BFDD */
7807 static int ip_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
7808 const char *peer
, const char *local
)
7810 enum pim_msdp_err result
;
7811 struct in_addr peer_addr
;
7812 struct in_addr local_addr
;
7813 int ret
= CMD_SUCCESS
;
7815 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
7817 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
7818 errno
, safe_strerror(errno
));
7819 return CMD_WARNING_CONFIG_FAILED
;
7822 result
= inet_pton(AF_INET
, local
, &local_addr
);
7824 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", local
,
7825 errno
, safe_strerror(errno
));
7826 return CMD_WARNING_CONFIG_FAILED
;
7829 result
= pim_msdp_peer_add(pim
, peer_addr
, local_addr
, "default",
7832 case PIM_MSDP_ERR_NONE
:
7834 case PIM_MSDP_ERR_OOM
:
7835 ret
= CMD_WARNING_CONFIG_FAILED
;
7836 vty_out(vty
, "%% Out of memory\n");
7838 case PIM_MSDP_ERR_PEER_EXISTS
:
7840 vty_out(vty
, "%% Peer exists\n");
7842 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
7843 ret
= CMD_WARNING_CONFIG_FAILED
;
7844 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
7847 ret
= CMD_WARNING_CONFIG_FAILED
;
7848 vty_out(vty
, "%% peer add failed\n");
7854 DEFUN_HIDDEN (ip_msdp_peer
,
7856 "ip msdp peer A.B.C.D source A.B.C.D",
7859 "Configure MSDP peer\n"
7861 "Source address for TCP connection\n"
7862 "local ip address\n")
7864 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7865 return ip_msdp_peer_cmd_worker(pim
, vty
, argv
[3]->arg
, argv
[5]->arg
);
7868 static int ip_no_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
7871 enum pim_msdp_err result
;
7872 struct in_addr peer_addr
;
7874 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
7876 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
7877 errno
, safe_strerror(errno
));
7878 return CMD_WARNING_CONFIG_FAILED
;
7881 result
= pim_msdp_peer_del(pim
, peer_addr
);
7883 case PIM_MSDP_ERR_NONE
:
7885 case PIM_MSDP_ERR_NO_PEER
:
7886 vty_out(vty
, "%% Peer does not exist\n");
7889 vty_out(vty
, "%% peer del failed\n");
7892 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7895 DEFUN_HIDDEN (no_ip_msdp_peer
,
7896 no_ip_msdp_peer_cmd
,
7897 "no ip msdp peer A.B.C.D",
7901 "Delete MSDP peer\n"
7902 "peer ip address\n")
7904 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7905 return ip_no_msdp_peer_cmd_worker(pim
, vty
, argv
[4]->arg
);
7908 static int ip_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
7909 struct vty
*vty
, const char *mg
,
7912 enum pim_msdp_err result
;
7913 struct in_addr mbr_ip
;
7914 int ret
= CMD_SUCCESS
;
7916 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
7918 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
7919 errno
, safe_strerror(errno
));
7920 return CMD_WARNING_CONFIG_FAILED
;
7923 result
= pim_msdp_mg_mbr_add(pim
, mg
, mbr_ip
);
7925 case PIM_MSDP_ERR_NONE
:
7927 case PIM_MSDP_ERR_OOM
:
7928 ret
= CMD_WARNING_CONFIG_FAILED
;
7929 vty_out(vty
, "%% Out of memory\n");
7931 case PIM_MSDP_ERR_MG_MBR_EXISTS
:
7933 vty_out(vty
, "%% mesh-group member exists\n");
7935 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
7936 ret
= CMD_WARNING_CONFIG_FAILED
;
7937 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
7940 ret
= CMD_WARNING_CONFIG_FAILED
;
7941 vty_out(vty
, "%% member add failed\n");
7947 DEFUN (ip_msdp_mesh_group_member
,
7948 ip_msdp_mesh_group_member_cmd
,
7949 "ip msdp mesh-group WORD member A.B.C.D",
7952 "Configure MSDP mesh-group\n"
7954 "mesh group member\n"
7955 "peer ip address\n")
7957 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7958 return ip_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[3]->arg
,
7962 static int ip_no_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
7967 enum pim_msdp_err result
;
7968 struct in_addr mbr_ip
;
7970 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
7972 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
7973 errno
, safe_strerror(errno
));
7974 return CMD_WARNING_CONFIG_FAILED
;
7977 result
= pim_msdp_mg_mbr_del(pim
, mg
, mbr_ip
);
7979 case PIM_MSDP_ERR_NONE
:
7981 case PIM_MSDP_ERR_NO_MG
:
7982 vty_out(vty
, "%% mesh-group does not exist\n");
7984 case PIM_MSDP_ERR_NO_MG_MBR
:
7985 vty_out(vty
, "%% mesh-group member does not exist\n");
7988 vty_out(vty
, "%% mesh-group member del failed\n");
7991 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7993 DEFUN (no_ip_msdp_mesh_group_member
,
7994 no_ip_msdp_mesh_group_member_cmd
,
7995 "no ip msdp mesh-group WORD member A.B.C.D",
7999 "Delete MSDP mesh-group member\n"
8001 "mesh group member\n"
8002 "peer ip address\n")
8004 PIM_DECLVAR_CONTEXT(vrf
, pim
);
8005 return ip_no_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[4]->arg
,
8009 static int ip_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
8010 struct vty
*vty
, const char *mg
,
8013 enum pim_msdp_err result
;
8014 struct in_addr src_ip
;
8016 result
= inet_pton(AF_INET
, src
, &src_ip
);
8018 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", src
,
8019 errno
, safe_strerror(errno
));
8020 return CMD_WARNING_CONFIG_FAILED
;
8023 result
= pim_msdp_mg_src_add(pim
, mg
, src_ip
);
8025 case PIM_MSDP_ERR_NONE
:
8027 case PIM_MSDP_ERR_OOM
:
8028 vty_out(vty
, "%% Out of memory\n");
8030 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
8031 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
8034 vty_out(vty
, "%% source add failed\n");
8037 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
8041 DEFUN (ip_msdp_mesh_group_source
,
8042 ip_msdp_mesh_group_source_cmd
,
8043 "ip msdp mesh-group WORD source A.B.C.D",
8046 "Configure MSDP mesh-group\n"
8048 "mesh group local address\n"
8049 "source ip address for the TCP connection\n")
8051 PIM_DECLVAR_CONTEXT(vrf
, pim
);
8052 return ip_msdp_mesh_group_source_cmd_worker(pim
, vty
, argv
[3]->arg
,
8056 static int ip_no_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
8060 enum pim_msdp_err result
;
8062 result
= pim_msdp_mg_src_del(pim
, mg
);
8064 case PIM_MSDP_ERR_NONE
:
8066 case PIM_MSDP_ERR_NO_MG
:
8067 vty_out(vty
, "%% mesh-group does not exist\n");
8070 vty_out(vty
, "%% mesh-group source del failed\n");
8073 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
8076 static int ip_no_msdp_mesh_group_cmd_worker(struct pim_instance
*pim
,
8077 struct vty
*vty
, const char *mg
)
8079 enum pim_msdp_err result
;
8081 result
= pim_msdp_mg_del(pim
, mg
);
8083 case PIM_MSDP_ERR_NONE
:
8085 case PIM_MSDP_ERR_NO_MG
:
8086 vty_out(vty
, "%% mesh-group does not exist\n");
8089 vty_out(vty
, "%% mesh-group source del failed\n");
8092 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
8095 DEFUN (no_ip_msdp_mesh_group_source
,
8096 no_ip_msdp_mesh_group_source_cmd
,
8097 "no ip msdp mesh-group WORD source [A.B.C.D]",
8101 "Delete MSDP mesh-group source\n"
8103 "mesh group source\n"
8104 "mesh group local address\n")
8106 PIM_DECLVAR_CONTEXT(vrf
, pim
);
8108 return ip_no_msdp_mesh_group_cmd_worker(pim
, vty
, argv
[6]->arg
);
8110 return ip_no_msdp_mesh_group_source_cmd_worker(pim
, vty
,
8114 static void print_empty_json_obj(struct vty
*vty
)
8117 json
= json_object_new_object();
8118 vty_out(vty
, "%s\n",
8119 json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
));
8120 json_object_free(json
);
8123 static void ip_msdp_show_mesh_group(struct pim_instance
*pim
, struct vty
*vty
,
8126 struct listnode
*mbrnode
;
8127 struct pim_msdp_mg_mbr
*mbr
;
8128 struct pim_msdp_mg
*mg
= pim
->msdp
.mg
;
8129 char mbr_str
[INET_ADDRSTRLEN
];
8130 char src_str
[INET_ADDRSTRLEN
];
8131 char state_str
[PIM_MSDP_STATE_STRLEN
];
8132 enum pim_msdp_peer_state state
;
8133 json_object
*json
= NULL
;
8134 json_object
*json_mg_row
= NULL
;
8135 json_object
*json_members
= NULL
;
8136 json_object
*json_row
= NULL
;
8140 print_empty_json_obj(vty
);
8144 pim_inet4_dump("<source?>", mg
->src_ip
, src_str
, sizeof(src_str
));
8146 json
= json_object_new_object();
8147 /* currently there is only one mesh group but we should still
8149 * it a dict with mg-name as key */
8150 json_mg_row
= json_object_new_object();
8151 json_object_string_add(json_mg_row
, "name",
8152 mg
->mesh_group_name
);
8153 json_object_string_add(json_mg_row
, "source", src_str
);
8155 vty_out(vty
, "Mesh group : %s\n", mg
->mesh_group_name
);
8156 vty_out(vty
, " Source : %s\n", src_str
);
8157 vty_out(vty
, " Member State\n");
8160 for (ALL_LIST_ELEMENTS_RO(mg
->mbr_list
, mbrnode
, mbr
)) {
8161 pim_inet4_dump("<mbr?>", mbr
->mbr_ip
, mbr_str
, sizeof(mbr_str
));
8163 state
= mbr
->mp
->state
;
8165 state
= PIM_MSDP_DISABLED
;
8167 pim_msdp_state_dump(state
, state_str
, sizeof(state_str
));
8169 json_row
= json_object_new_object();
8170 json_object_string_add(json_row
, "member", mbr_str
);
8171 json_object_string_add(json_row
, "state", state_str
);
8172 if (!json_members
) {
8173 json_members
= json_object_new_object();
8174 json_object_object_add(json_mg_row
, "members",
8177 json_object_object_add(json_members
, mbr_str
, json_row
);
8179 vty_out(vty
, " %-15s %11s\n", mbr_str
, state_str
);
8184 json_object_object_add(json
, mg
->mesh_group_name
, json_mg_row
);
8185 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8186 json
, JSON_C_TO_STRING_PRETTY
));
8187 json_object_free(json
);
8191 DEFUN (show_ip_msdp_mesh_group
,
8192 show_ip_msdp_mesh_group_cmd
,
8193 "show ip msdp [vrf NAME] mesh-group [json]",
8198 "MSDP mesh-group information\n"
8201 bool uj
= use_json(argc
, argv
);
8203 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
8208 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
8213 DEFUN (show_ip_msdp_mesh_group_vrf_all
,
8214 show_ip_msdp_mesh_group_vrf_all_cmd
,
8215 "show ip msdp vrf all mesh-group [json]",
8220 "MSDP mesh-group information\n"
8223 bool uj
= use_json(argc
, argv
);
8229 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
8233 vty_out(vty
, " \"%s\": ", vrf
->name
);
8236 vty_out(vty
, "VRF: %s\n", vrf
->name
);
8237 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
8240 vty_out(vty
, "}\n");
8245 static void ip_msdp_show_peers(struct pim_instance
*pim
, struct vty
*vty
,
8248 struct listnode
*mpnode
;
8249 struct pim_msdp_peer
*mp
;
8250 char peer_str
[INET_ADDRSTRLEN
];
8251 char local_str
[INET_ADDRSTRLEN
];
8252 char state_str
[PIM_MSDP_STATE_STRLEN
];
8253 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
8255 json_object
*json
= NULL
;
8256 json_object
*json_row
= NULL
;
8260 json
= json_object_new_object();
8263 "Peer Local State Uptime SaCnt\n");
8266 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
8267 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
8268 now
= pim_time_monotonic_sec();
8269 pim_time_uptime(timebuf
, sizeof(timebuf
),
8272 strcpy(timebuf
, "-");
8274 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
8275 pim_inet4_dump("<local?>", mp
->local
, local_str
,
8277 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
8279 json_row
= json_object_new_object();
8280 json_object_string_add(json_row
, "peer", peer_str
);
8281 json_object_string_add(json_row
, "local", local_str
);
8282 json_object_string_add(json_row
, "state", state_str
);
8283 json_object_string_add(json_row
, "upTime", timebuf
);
8284 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
8285 json_object_object_add(json
, peer_str
, json_row
);
8287 vty_out(vty
, "%-15s %15s %11s %8s %6d\n", peer_str
,
8288 local_str
, state_str
, timebuf
, mp
->sa_cnt
);
8293 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8294 json
, JSON_C_TO_STRING_PRETTY
));
8295 json_object_free(json
);
8299 static void ip_msdp_show_peers_detail(struct pim_instance
*pim
, struct vty
*vty
,
8300 const char *peer
, bool uj
)
8302 struct listnode
*mpnode
;
8303 struct pim_msdp_peer
*mp
;
8304 char peer_str
[INET_ADDRSTRLEN
];
8305 char local_str
[INET_ADDRSTRLEN
];
8306 char state_str
[PIM_MSDP_STATE_STRLEN
];
8307 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
8308 char katimer
[PIM_MSDP_TIMER_STRLEN
];
8309 char crtimer
[PIM_MSDP_TIMER_STRLEN
];
8310 char holdtimer
[PIM_MSDP_TIMER_STRLEN
];
8312 json_object
*json
= NULL
;
8313 json_object
*json_row
= NULL
;
8316 json
= json_object_new_object();
8319 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
8320 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
8321 if (strcmp(peer
, "detail") && strcmp(peer
, peer_str
))
8324 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
8325 now
= pim_time_monotonic_sec();
8326 pim_time_uptime(timebuf
, sizeof(timebuf
),
8329 strcpy(timebuf
, "-");
8331 pim_inet4_dump("<local?>", mp
->local
, local_str
,
8333 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
8334 pim_time_timer_to_hhmmss(katimer
, sizeof(katimer
),
8336 pim_time_timer_to_hhmmss(crtimer
, sizeof(crtimer
),
8338 pim_time_timer_to_hhmmss(holdtimer
, sizeof(holdtimer
),
8342 json_row
= json_object_new_object();
8343 json_object_string_add(json_row
, "peer", peer_str
);
8344 json_object_string_add(json_row
, "local", local_str
);
8345 json_object_string_add(json_row
, "meshGroupName",
8346 mp
->mesh_group_name
);
8347 json_object_string_add(json_row
, "state", state_str
);
8348 json_object_string_add(json_row
, "upTime", timebuf
);
8349 json_object_string_add(json_row
, "keepAliveTimer",
8351 json_object_string_add(json_row
, "connRetryTimer",
8353 json_object_string_add(json_row
, "holdTimer",
8355 json_object_string_add(json_row
, "lastReset",
8357 json_object_int_add(json_row
, "connAttempts",
8359 json_object_int_add(json_row
, "establishedChanges",
8361 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
8362 json_object_int_add(json_row
, "kaSent", mp
->ka_tx_cnt
);
8363 json_object_int_add(json_row
, "kaRcvd", mp
->ka_rx_cnt
);
8364 json_object_int_add(json_row
, "saSent", mp
->sa_tx_cnt
);
8365 json_object_int_add(json_row
, "saRcvd", mp
->sa_rx_cnt
);
8366 json_object_object_add(json
, peer_str
, json_row
);
8368 vty_out(vty
, "Peer : %s\n", peer_str
);
8369 vty_out(vty
, " Local : %s\n", local_str
);
8370 vty_out(vty
, " Mesh Group : %s\n",
8371 mp
->mesh_group_name
);
8372 vty_out(vty
, " State : %s\n", state_str
);
8373 vty_out(vty
, " Uptime : %s\n", timebuf
);
8375 vty_out(vty
, " Keepalive Timer : %s\n", katimer
);
8376 vty_out(vty
, " Conn Retry Timer : %s\n", crtimer
);
8377 vty_out(vty
, " Hold Timer : %s\n", holdtimer
);
8378 vty_out(vty
, " Last Reset : %s\n",
8380 vty_out(vty
, " Conn Attempts : %d\n",
8382 vty_out(vty
, " Established Changes : %d\n",
8384 vty_out(vty
, " SA Count : %d\n",
8386 vty_out(vty
, " Statistics :\n");
8389 vty_out(vty
, " Keepalives : %10d %10d\n",
8390 mp
->ka_tx_cnt
, mp
->ka_rx_cnt
);
8391 vty_out(vty
, " SAs : %10d %10d\n",
8392 mp
->sa_tx_cnt
, mp
->sa_rx_cnt
);
8398 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8399 json
, JSON_C_TO_STRING_PRETTY
));
8400 json_object_free(json
);
8404 DEFUN (show_ip_msdp_peer_detail
,
8405 show_ip_msdp_peer_detail_cmd
,
8406 "show ip msdp [vrf NAME] peer [detail|A.B.C.D] [json]",
8411 "MSDP peer information\n"
8416 bool uj
= use_json(argc
, argv
);
8418 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
8425 if (argv_find(argv
, argc
, "detail", &idx
))
8426 arg
= argv
[idx
]->text
;
8427 else if (argv_find(argv
, argc
, "A.B.C.D", &idx
))
8428 arg
= argv
[idx
]->arg
;
8431 ip_msdp_show_peers_detail(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
8433 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
8438 DEFUN (show_ip_msdp_peer_detail_vrf_all
,
8439 show_ip_msdp_peer_detail_vrf_all_cmd
,
8440 "show ip msdp vrf all peer [detail|A.B.C.D] [json]",
8445 "MSDP peer information\n"
8451 bool uj
= use_json(argc
, argv
);
8457 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
8461 vty_out(vty
, " \"%s\": ", vrf
->name
);
8464 vty_out(vty
, "VRF: %s\n", vrf
->name
);
8465 if (argv_find(argv
, argc
, "detail", &idx
)
8466 || argv_find(argv
, argc
, "A.B.C.D", &idx
))
8467 ip_msdp_show_peers_detail(vrf
->info
, vty
,
8468 argv
[idx
]->arg
, uj
);
8470 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
8473 vty_out(vty
, "}\n");
8478 static void ip_msdp_show_sa(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
8480 struct listnode
*sanode
;
8481 struct pim_msdp_sa
*sa
;
8482 char src_str
[INET_ADDRSTRLEN
];
8483 char grp_str
[INET_ADDRSTRLEN
];
8484 char rp_str
[INET_ADDRSTRLEN
];
8485 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
8489 json_object
*json
= NULL
;
8490 json_object
*json_group
= NULL
;
8491 json_object
*json_row
= NULL
;
8494 json
= json_object_new_object();
8497 "Source Group RP Local SPT Uptime\n");
8500 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
8501 now
= pim_time_monotonic_sec();
8502 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
8503 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
8504 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
8505 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
8506 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
8508 strcpy(spt_str
, "yes");
8510 strcpy(spt_str
, "no");
8513 strcpy(rp_str
, "-");
8514 strcpy(spt_str
, "-");
8516 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
8517 strcpy(local_str
, "yes");
8519 strcpy(local_str
, "no");
8522 json_object_object_get_ex(json
, grp_str
, &json_group
);
8525 json_group
= json_object_new_object();
8526 json_object_object_add(json
, grp_str
,
8530 json_row
= json_object_new_object();
8531 json_object_string_add(json_row
, "source", src_str
);
8532 json_object_string_add(json_row
, "group", grp_str
);
8533 json_object_string_add(json_row
, "rp", rp_str
);
8534 json_object_string_add(json_row
, "local", local_str
);
8535 json_object_string_add(json_row
, "sptSetup", spt_str
);
8536 json_object_string_add(json_row
, "upTime", timebuf
);
8537 json_object_object_add(json_group
, src_str
, json_row
);
8539 vty_out(vty
, "%-15s %15s %15s %5c %3c %8s\n",
8540 src_str
, grp_str
, rp_str
, local_str
[0],
8541 spt_str
[0], timebuf
);
8546 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8547 json
, JSON_C_TO_STRING_PRETTY
));
8548 json_object_free(json
);
8552 static void ip_msdp_show_sa_entry_detail(struct pim_msdp_sa
*sa
,
8553 const char *src_str
,
8554 const char *grp_str
, struct vty
*vty
,
8555 bool uj
, json_object
*json
)
8557 char rp_str
[INET_ADDRSTRLEN
];
8558 char peer_str
[INET_ADDRSTRLEN
];
8559 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
8562 char statetimer
[PIM_MSDP_TIMER_STRLEN
];
8564 json_object
*json_group
= NULL
;
8565 json_object
*json_row
= NULL
;
8567 now
= pim_time_monotonic_sec();
8568 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
8569 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
8570 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
8571 pim_inet4_dump("<peer?>", sa
->peer
, peer_str
, sizeof(peer_str
));
8573 strcpy(spt_str
, "yes");
8575 strcpy(spt_str
, "no");
8578 strcpy(rp_str
, "-");
8579 strcpy(peer_str
, "-");
8580 strcpy(spt_str
, "-");
8582 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
8583 strcpy(local_str
, "yes");
8585 strcpy(local_str
, "no");
8587 pim_time_timer_to_hhmmss(statetimer
, sizeof(statetimer
),
8588 sa
->sa_state_timer
);
8590 json_object_object_get_ex(json
, grp_str
, &json_group
);
8593 json_group
= json_object_new_object();
8594 json_object_object_add(json
, grp_str
, json_group
);
8597 json_row
= json_object_new_object();
8598 json_object_string_add(json_row
, "source", src_str
);
8599 json_object_string_add(json_row
, "group", grp_str
);
8600 json_object_string_add(json_row
, "rp", rp_str
);
8601 json_object_string_add(json_row
, "local", local_str
);
8602 json_object_string_add(json_row
, "sptSetup", spt_str
);
8603 json_object_string_add(json_row
, "upTime", timebuf
);
8604 json_object_string_add(json_row
, "stateTimer", statetimer
);
8605 json_object_object_add(json_group
, src_str
, json_row
);
8607 vty_out(vty
, "SA : %s\n", sa
->sg_str
);
8608 vty_out(vty
, " RP : %s\n", rp_str
);
8609 vty_out(vty
, " Peer : %s\n", peer_str
);
8610 vty_out(vty
, " Local : %s\n", local_str
);
8611 vty_out(vty
, " SPT Setup : %s\n", spt_str
);
8612 vty_out(vty
, " Uptime : %s\n", timebuf
);
8613 vty_out(vty
, " State Timer : %s\n", statetimer
);
8618 static void ip_msdp_show_sa_detail(struct pim_instance
*pim
, struct vty
*vty
,
8621 struct listnode
*sanode
;
8622 struct pim_msdp_sa
*sa
;
8623 char src_str
[INET_ADDRSTRLEN
];
8624 char grp_str
[INET_ADDRSTRLEN
];
8625 json_object
*json
= NULL
;
8628 json
= json_object_new_object();
8631 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
8632 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
8633 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
8634 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
, uj
,
8639 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8640 json
, JSON_C_TO_STRING_PRETTY
));
8641 json_object_free(json
);
8645 DEFUN (show_ip_msdp_sa_detail
,
8646 show_ip_msdp_sa_detail_cmd
,
8647 "show ip msdp [vrf NAME] sa detail [json]",
8652 "MSDP active-source information\n"
8656 bool uj
= use_json(argc
, argv
);
8658 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
8663 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
8668 DEFUN (show_ip_msdp_sa_detail_vrf_all
,
8669 show_ip_msdp_sa_detail_vrf_all_cmd
,
8670 "show ip msdp vrf all sa detail [json]",
8675 "MSDP active-source information\n"
8679 bool uj
= use_json(argc
, argv
);
8685 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
8689 vty_out(vty
, " \"%s\": ", vrf
->name
);
8692 vty_out(vty
, "VRF: %s\n", vrf
->name
);
8693 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
8696 vty_out(vty
, "}\n");
8701 static void ip_msdp_show_sa_addr(struct pim_instance
*pim
, struct vty
*vty
,
8702 const char *addr
, bool uj
)
8704 struct listnode
*sanode
;
8705 struct pim_msdp_sa
*sa
;
8706 char src_str
[INET_ADDRSTRLEN
];
8707 char grp_str
[INET_ADDRSTRLEN
];
8708 json_object
*json
= NULL
;
8711 json
= json_object_new_object();
8714 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
8715 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
8716 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
8717 if (!strcmp(addr
, src_str
) || !strcmp(addr
, grp_str
)) {
8718 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
8724 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8725 json
, JSON_C_TO_STRING_PRETTY
));
8726 json_object_free(json
);
8730 static void ip_msdp_show_sa_sg(struct pim_instance
*pim
, struct vty
*vty
,
8731 const char *src
, const char *grp
, bool uj
)
8733 struct listnode
*sanode
;
8734 struct pim_msdp_sa
*sa
;
8735 char src_str
[INET_ADDRSTRLEN
];
8736 char grp_str
[INET_ADDRSTRLEN
];
8737 json_object
*json
= NULL
;
8740 json
= json_object_new_object();
8743 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
8744 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
8745 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
8746 if (!strcmp(src
, src_str
) && !strcmp(grp
, grp_str
)) {
8747 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
8753 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8754 json
, JSON_C_TO_STRING_PRETTY
));
8755 json_object_free(json
);
8759 DEFUN (show_ip_msdp_sa_sg
,
8760 show_ip_msdp_sa_sg_cmd
,
8761 "show ip msdp [vrf NAME] sa [A.B.C.D [A.B.C.D]] [json]",
8766 "MSDP active-source information\n"
8767 "source or group ip\n"
8771 bool uj
= use_json(argc
, argv
);
8775 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
8780 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
8782 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
8786 if (src_ip
&& grp_ip
)
8787 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
8789 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
8791 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
8796 DEFUN (show_ip_msdp_sa_sg_vrf_all
,
8797 show_ip_msdp_sa_sg_vrf_all_cmd
,
8798 "show ip msdp vrf all sa [A.B.C.D [A.B.C.D]] [json]",
8803 "MSDP active-source information\n"
8804 "source or group ip\n"
8808 bool uj
= use_json(argc
, argv
);
8813 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
8815 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
8821 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
8825 vty_out(vty
, " \"%s\": ", vrf
->name
);
8828 vty_out(vty
, "VRF: %s\n", vrf
->name
);
8830 if (src_ip
&& grp_ip
)
8831 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
8833 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
8835 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
8838 vty_out(vty
, "}\n");
8843 struct pim_sg_cache_walk_data
{
8846 json_object
*json_group
;
8847 struct in_addr addr
;
8851 static void pim_show_vxlan_sg_entry(struct pim_vxlan_sg
*vxlan_sg
,
8852 struct pim_sg_cache_walk_data
*cwd
)
8854 struct vty
*vty
= cwd
->vty
;
8855 json_object
*json
= cwd
->json
;
8856 char src_str
[INET_ADDRSTRLEN
];
8857 char grp_str
[INET_ADDRSTRLEN
];
8858 json_object
*json_row
;
8859 bool installed
= (vxlan_sg
->up
)?TRUE
:FALSE
;
8860 const char *iif_name
= vxlan_sg
->iif
?vxlan_sg
->iif
->name
:"-";
8861 const char *oif_name
;
8863 if (pim_vxlan_is_orig_mroute(vxlan_sg
))
8864 oif_name
= vxlan_sg
->orig_oif
?vxlan_sg
->orig_oif
->name
:"";
8866 oif_name
= vxlan_sg
->term_oif
?vxlan_sg
->term_oif
->name
:"";
8868 if (cwd
->addr_match
&& (vxlan_sg
->sg
.src
.s_addr
!= cwd
->addr
.s_addr
) &&
8869 (vxlan_sg
->sg
.grp
.s_addr
!= cwd
->addr
.s_addr
)) {
8872 pim_inet4_dump("<src?>", vxlan_sg
->sg
.src
, src_str
, sizeof(src_str
));
8873 pim_inet4_dump("<grp?>", vxlan_sg
->sg
.grp
, grp_str
, sizeof(grp_str
));
8875 json_object_object_get_ex(json
, grp_str
, &cwd
->json_group
);
8877 if (!cwd
->json_group
) {
8878 cwd
->json_group
= json_object_new_object();
8879 json_object_object_add(json
, grp_str
,
8883 json_row
= json_object_new_object();
8884 json_object_string_add(json_row
, "source", src_str
);
8885 json_object_string_add(json_row
, "group", grp_str
);
8886 json_object_string_add(json_row
, "input", iif_name
);
8887 json_object_string_add(json_row
, "output", oif_name
);
8889 json_object_boolean_true_add(json_row
, "installed");
8891 json_object_boolean_false_add(json_row
, "installed");
8892 json_object_object_add(cwd
->json_group
, src_str
, json_row
);
8894 vty_out(vty
, "%-15s %-15s %-15s %-15s %-5s\n",
8895 src_str
, grp_str
, iif_name
, oif_name
,
8900 static void pim_show_vxlan_sg_hash_entry(struct hash_backet
*backet
, void *arg
)
8902 pim_show_vxlan_sg_entry((struct pim_vxlan_sg
*)backet
->data
,
8903 (struct pim_sg_cache_walk_data
*)arg
);
8906 static void pim_show_vxlan_sg(struct pim_instance
*pim
,
8907 struct vty
*vty
, bool uj
)
8909 json_object
*json
= NULL
;
8910 struct pim_sg_cache_walk_data cwd
;
8913 json
= json_object_new_object();
8915 vty_out(vty
, "Codes: I -> installed\n");
8917 "Source Group Input Output Flags\n");
8920 memset(&cwd
, 0, sizeof(cwd
));
8923 hash_iterate(pim
->vxlan
.sg_hash
, pim_show_vxlan_sg_hash_entry
, &cwd
);
8926 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8927 json
, JSON_C_TO_STRING_PRETTY
));
8928 json_object_free(json
);
8932 static void pim_show_vxlan_sg_match_addr(struct pim_instance
*pim
,
8933 struct vty
*vty
, char *addr_str
, bool uj
)
8935 json_object
*json
= NULL
;
8936 struct pim_sg_cache_walk_data cwd
;
8939 memset(&cwd
, 0, sizeof(cwd
));
8940 result
= inet_pton(AF_INET
, addr_str
, &cwd
.addr
);
8942 vty_out(vty
, "Bad address %s: errno=%d: %s\n", addr_str
,
8943 errno
, safe_strerror(errno
));
8948 json
= json_object_new_object();
8950 vty_out(vty
, "Codes: I -> installed\n");
8952 "Source Group Input Output Flags\n");
8957 cwd
.addr_match
= TRUE
;
8958 hash_iterate(pim
->vxlan
.sg_hash
, pim_show_vxlan_sg_hash_entry
, &cwd
);
8961 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8962 json
, JSON_C_TO_STRING_PRETTY
));
8963 json_object_free(json
);
8967 static void pim_show_vxlan_sg_one(struct pim_instance
*pim
,
8968 struct vty
*vty
, char *src_str
, char *grp_str
, bool uj
)
8970 json_object
*json
= NULL
;
8971 struct prefix_sg sg
;
8973 struct pim_vxlan_sg
*vxlan_sg
;
8974 const char *iif_name
;
8976 const char *oif_name
;
8978 result
= inet_pton(AF_INET
, src_str
, &sg
.src
);
8980 vty_out(vty
, "Bad src address %s: errno=%d: %s\n", src_str
,
8981 errno
, safe_strerror(errno
));
8984 result
= inet_pton(AF_INET
, grp_str
, &sg
.grp
);
8986 vty_out(vty
, "Bad grp address %s: errno=%d: %s\n", grp_str
,
8987 errno
, safe_strerror(errno
));
8991 sg
.family
= AF_INET
;
8992 sg
.prefixlen
= IPV4_MAX_BITLEN
;
8994 json
= json_object_new_object();
8996 vxlan_sg
= pim_vxlan_sg_find(pim
, &sg
);
8998 installed
= (vxlan_sg
->up
)?TRUE
:FALSE
;
8999 iif_name
= vxlan_sg
->iif
?vxlan_sg
->iif
->name
:"-";
9001 if (pim_vxlan_is_orig_mroute(vxlan_sg
))
9003 vxlan_sg
->orig_oif
?vxlan_sg
->orig_oif
->name
:"";
9006 vxlan_sg
->term_oif
?vxlan_sg
->term_oif
->name
:"";
9009 json_object_string_add(json
, "source", src_str
);
9010 json_object_string_add(json
, "group", grp_str
);
9011 json_object_string_add(json
, "input", iif_name
);
9012 json_object_string_add(json
, "output", oif_name
);
9014 json_object_boolean_true_add(json
, "installed");
9016 json_object_boolean_false_add(json
,
9019 vty_out(vty
, "SG : %s\n", vxlan_sg
->sg_str
);
9020 vty_out(vty
, " Input : %s\n", iif_name
);
9021 vty_out(vty
, " Output : %s\n", oif_name
);
9022 vty_out(vty
, " installed : %s\n",
9023 installed
?"yes":"no");
9028 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9029 json
, JSON_C_TO_STRING_PRETTY
));
9030 json_object_free(json
);
9034 DEFUN (show_ip_pim_vxlan_sg
,
9035 show_ip_pim_vxlan_sg_cmd
,
9036 "show ip pim [vrf NAME] vxlan-groups [A.B.C.D [A.B.C.D]] [json]",
9041 "VxLAN BUM groups\n"
9042 "source or group ip\n"
9046 bool uj
= use_json(argc
, argv
);
9050 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
9055 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ?
9056 argv
[idx
++]->arg
:NULL
;
9057 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
) ?
9058 argv
[idx
]->arg
:NULL
;
9060 if (src_ip
&& grp_ip
)
9061 pim_show_vxlan_sg_one(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
9063 pim_show_vxlan_sg_match_addr(vrf
->info
, vty
, src_ip
, uj
);
9065 pim_show_vxlan_sg(vrf
->info
, vty
, uj
);
9070 static void pim_show_vxlan_sg_work(struct pim_instance
*pim
,
9071 struct vty
*vty
, bool uj
)
9073 json_object
*json
= NULL
;
9074 struct pim_sg_cache_walk_data cwd
;
9075 struct listnode
*node
;
9076 struct pim_vxlan_sg
*vxlan_sg
;
9079 json
= json_object_new_object();
9081 vty_out(vty
, "Codes: I -> installed\n");
9083 "Source Group Input Flags\n");
9086 memset(&cwd
, 0, sizeof(cwd
));
9089 for (ALL_LIST_ELEMENTS_RO(pim_vxlan_p
->work_list
, node
, vxlan_sg
))
9090 pim_show_vxlan_sg_entry(vxlan_sg
, &cwd
);
9093 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9094 json
, JSON_C_TO_STRING_PRETTY
));
9095 json_object_free(json
);
9099 DEFUN_HIDDEN (show_ip_pim_vxlan_sg_work
,
9100 show_ip_pim_vxlan_sg_work_cmd
,
9101 "show ip pim [vrf NAME] vxlan-work [json]",
9109 bool uj
= use_json(argc
, argv
);
9113 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
9118 pim_show_vxlan_sg_work(vrf
->info
, vty
, uj
);
9123 DEFUN_HIDDEN (no_ip_pim_mlag
,
9131 struct in_addr addr
;
9134 pim_vxlan_mlag_update(TRUE
/*mlag_enable*/,
9135 FALSE
/*peer_state*/, PIM_VXLAN_MLAG_ROLE_SECONDARY
,
9136 NULL
/*peerlink*/, &addr
);
9141 DEFUN_HIDDEN (ip_pim_mlag
,
9143 "ip pim mlag INTERFACE role [primary|secondary] state [up|down] addr A.B.C.D",
9147 "peerlink sub interface\n"
9149 "MLAG role primary\n"
9150 "MLAG role secondary\n"
9151 "peer session state\n"
9152 "peer session state up\n"
9153 "peer session state down\n"
9155 "unique ip address\n")
9157 struct interface
*ifp
;
9158 const char *peerlink
;
9163 struct in_addr reg_addr
;
9166 peerlink
= argv
[idx
]->arg
;
9167 ifp
= if_lookup_by_name(peerlink
, VRF_DEFAULT
);
9169 vty_out(vty
, "No such interface name %s\n", peerlink
);
9174 if (!strcmp(argv
[idx
]->arg
, "primary")) {
9175 role
= PIM_VXLAN_MLAG_ROLE_PRIMARY
;
9176 } else if (!strcmp(argv
[idx
]->arg
, "secondary")) {
9177 role
= PIM_VXLAN_MLAG_ROLE_SECONDARY
;
9179 vty_out(vty
, "unknown MLAG role %s\n", argv
[idx
]->arg
);
9184 if (!strcmp(argv
[idx
]->arg
, "up")) {
9186 } else if (strcmp(argv
[idx
]->arg
, "down")) {
9189 vty_out(vty
, "unknown MLAG state %s\n", argv
[idx
]->arg
);
9194 result
= inet_pton(AF_INET
, argv
[idx
]->arg
, ®_addr
);
9196 vty_out(vty
, "%% Bad reg address %s: errno=%d: %s\n",
9198 errno
, safe_strerror(errno
));
9199 return CMD_WARNING_CONFIG_FAILED
;
9201 pim_vxlan_mlag_update(TRUE
, peer_state
, role
, ifp
, ®_addr
);
9206 void pim_cmd_init(void)
9208 install_node(&interface_node
,
9209 pim_interface_config_write
); /* INTERFACE_NODE */
9212 install_node(&debug_node
, pim_debug_config_write
);
9214 install_element(ENABLE_NODE
, &pim_test_sg_keepalive_cmd
);
9216 install_element(CONFIG_NODE
, &ip_pim_rp_cmd
);
9217 install_element(VRF_NODE
, &ip_pim_rp_cmd
);
9218 install_element(CONFIG_NODE
, &no_ip_pim_rp_cmd
);
9219 install_element(VRF_NODE
, &no_ip_pim_rp_cmd
);
9220 install_element(CONFIG_NODE
, &ip_pim_rp_prefix_list_cmd
);
9221 install_element(VRF_NODE
, &ip_pim_rp_prefix_list_cmd
);
9222 install_element(CONFIG_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
9223 install_element(VRF_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
9224 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
9225 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
9226 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
9227 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
9228 install_element(CONFIG_NODE
, &ip_pim_ssm_prefix_list_cmd
);
9229 install_element(VRF_NODE
, &ip_pim_ssm_prefix_list_cmd
);
9230 install_element(CONFIG_NODE
, &ip_pim_register_suppress_cmd
);
9231 install_element(VRF_NODE
, &ip_pim_register_suppress_cmd
);
9232 install_element(CONFIG_NODE
, &no_ip_pim_register_suppress_cmd
);
9233 install_element(VRF_NODE
, &no_ip_pim_register_suppress_cmd
);
9234 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
9235 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
9236 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
9237 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
9238 install_element(CONFIG_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
9239 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
9240 install_element(CONFIG_NODE
,
9241 &no_ip_pim_spt_switchover_infinity_plist_cmd
);
9242 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_plist_cmd
);
9243 install_element(CONFIG_NODE
, &ip_pim_joinprune_time_cmd
);
9244 install_element(VRF_NODE
, &ip_pim_joinprune_time_cmd
);
9245 install_element(CONFIG_NODE
, &no_ip_pim_joinprune_time_cmd
);
9246 install_element(VRF_NODE
, &no_ip_pim_joinprune_time_cmd
);
9247 install_element(CONFIG_NODE
, &ip_pim_keep_alive_cmd
);
9248 install_element(VRF_NODE
, &ip_pim_keep_alive_cmd
);
9249 install_element(CONFIG_NODE
, &ip_pim_rp_keep_alive_cmd
);
9250 install_element(VRF_NODE
, &ip_pim_rp_keep_alive_cmd
);
9251 install_element(CONFIG_NODE
, &no_ip_pim_keep_alive_cmd
);
9252 install_element(VRF_NODE
, &no_ip_pim_keep_alive_cmd
);
9253 install_element(CONFIG_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
9254 install_element(VRF_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
9255 install_element(CONFIG_NODE
, &ip_pim_packets_cmd
);
9256 install_element(VRF_NODE
, &ip_pim_packets_cmd
);
9257 install_element(CONFIG_NODE
, &no_ip_pim_packets_cmd
);
9258 install_element(VRF_NODE
, &no_ip_pim_packets_cmd
);
9259 install_element(CONFIG_NODE
, &ip_pim_v6_secondary_cmd
);
9260 install_element(VRF_NODE
, &ip_pim_v6_secondary_cmd
);
9261 install_element(CONFIG_NODE
, &no_ip_pim_v6_secondary_cmd
);
9262 install_element(VRF_NODE
, &no_ip_pim_v6_secondary_cmd
);
9263 install_element(CONFIG_NODE
, &ip_ssmpingd_cmd
);
9264 install_element(VRF_NODE
, &ip_ssmpingd_cmd
);
9265 install_element(CONFIG_NODE
, &no_ip_ssmpingd_cmd
);
9266 install_element(VRF_NODE
, &no_ip_ssmpingd_cmd
);
9267 install_element(CONFIG_NODE
, &ip_msdp_peer_cmd
);
9268 install_element(VRF_NODE
, &ip_msdp_peer_cmd
);
9269 install_element(CONFIG_NODE
, &no_ip_msdp_peer_cmd
);
9270 install_element(VRF_NODE
, &no_ip_msdp_peer_cmd
);
9271 install_element(CONFIG_NODE
, &ip_pim_ecmp_cmd
);
9272 install_element(VRF_NODE
, &ip_pim_ecmp_cmd
);
9273 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_cmd
);
9274 install_element(VRF_NODE
, &no_ip_pim_ecmp_cmd
);
9275 install_element(CONFIG_NODE
, &ip_pim_ecmp_rebalance_cmd
);
9276 install_element(VRF_NODE
, &ip_pim_ecmp_rebalance_cmd
);
9277 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
9278 install_element(VRF_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
9279 install_element(CONFIG_NODE
, &ip_pim_mlag_cmd
);
9280 install_element(CONFIG_NODE
, &no_ip_pim_mlag_cmd
);
9282 install_element(INTERFACE_NODE
, &interface_ip_igmp_cmd
);
9283 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_cmd
);
9284 install_element(INTERFACE_NODE
, &interface_ip_igmp_join_cmd
);
9285 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_join_cmd
);
9286 install_element(INTERFACE_NODE
, &interface_ip_igmp_version_cmd
);
9287 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_version_cmd
);
9288 install_element(INTERFACE_NODE
, &interface_ip_igmp_query_interval_cmd
);
9289 install_element(INTERFACE_NODE
,
9290 &interface_no_ip_igmp_query_interval_cmd
);
9291 install_element(INTERFACE_NODE
,
9292 &interface_ip_igmp_query_max_response_time_cmd
);
9293 install_element(INTERFACE_NODE
,
9294 &interface_no_ip_igmp_query_max_response_time_cmd
);
9295 install_element(INTERFACE_NODE
,
9296 &interface_ip_igmp_query_max_response_time_dsec_cmd
);
9297 install_element(INTERFACE_NODE
,
9298 &interface_no_ip_igmp_query_max_response_time_dsec_cmd
);
9299 install_element(INTERFACE_NODE
, &interface_ip_pim_activeactive_cmd
);
9300 install_element(INTERFACE_NODE
, &interface_ip_pim_ssm_cmd
);
9301 install_element(INTERFACE_NODE
, &interface_no_ip_pim_ssm_cmd
);
9302 install_element(INTERFACE_NODE
, &interface_ip_pim_sm_cmd
);
9303 install_element(INTERFACE_NODE
, &interface_no_ip_pim_sm_cmd
);
9304 install_element(INTERFACE_NODE
, &interface_ip_pim_cmd
);
9305 install_element(INTERFACE_NODE
, &interface_no_ip_pim_cmd
);
9306 install_element(INTERFACE_NODE
, &interface_ip_pim_drprio_cmd
);
9307 install_element(INTERFACE_NODE
, &interface_no_ip_pim_drprio_cmd
);
9308 install_element(INTERFACE_NODE
, &interface_ip_pim_hello_cmd
);
9309 install_element(INTERFACE_NODE
, &interface_no_ip_pim_hello_cmd
);
9310 install_element(INTERFACE_NODE
, &interface_ip_pim_boundary_oil_cmd
);
9311 install_element(INTERFACE_NODE
, &interface_no_ip_pim_boundary_oil_cmd
);
9313 // Static mroutes NEB
9314 install_element(INTERFACE_NODE
, &interface_ip_mroute_cmd
);
9315 install_element(INTERFACE_NODE
, &interface_ip_mroute_source_cmd
);
9316 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_cmd
);
9317 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_source_cmd
);
9319 install_element(VIEW_NODE
, &show_ip_igmp_interface_cmd
);
9320 install_element(VIEW_NODE
, &show_ip_igmp_interface_vrf_all_cmd
);
9321 install_element(VIEW_NODE
, &show_ip_igmp_join_cmd
);
9322 install_element(VIEW_NODE
, &show_ip_igmp_join_vrf_all_cmd
);
9323 install_element(VIEW_NODE
, &show_ip_igmp_groups_cmd
);
9324 install_element(VIEW_NODE
, &show_ip_igmp_groups_vrf_all_cmd
);
9325 install_element(VIEW_NODE
, &show_ip_igmp_groups_retransmissions_cmd
);
9326 install_element(VIEW_NODE
, &show_ip_igmp_sources_cmd
);
9327 install_element(VIEW_NODE
, &show_ip_igmp_sources_retransmissions_cmd
);
9328 install_element(VIEW_NODE
, &show_ip_igmp_statistics_cmd
);
9329 install_element(VIEW_NODE
, &show_ip_pim_assert_cmd
);
9330 install_element(VIEW_NODE
, &show_ip_pim_assert_internal_cmd
);
9331 install_element(VIEW_NODE
, &show_ip_pim_assert_metric_cmd
);
9332 install_element(VIEW_NODE
, &show_ip_pim_assert_winner_metric_cmd
);
9333 install_element(VIEW_NODE
, &show_ip_pim_interface_traffic_cmd
);
9334 install_element(VIEW_NODE
, &show_ip_pim_interface_cmd
);
9335 install_element(VIEW_NODE
, &show_ip_pim_interface_vrf_all_cmd
);
9336 install_element(VIEW_NODE
, &show_ip_pim_join_cmd
);
9337 install_element(VIEW_NODE
, &show_ip_pim_join_vrf_all_cmd
);
9338 install_element(VIEW_NODE
, &show_ip_pim_local_membership_cmd
);
9339 install_element(VIEW_NODE
, &show_ip_pim_neighbor_cmd
);
9340 install_element(VIEW_NODE
, &show_ip_pim_neighbor_vrf_all_cmd
);
9341 install_element(VIEW_NODE
, &show_ip_pim_rpf_cmd
);
9342 install_element(VIEW_NODE
, &show_ip_pim_rpf_vrf_all_cmd
);
9343 install_element(VIEW_NODE
, &show_ip_pim_secondary_cmd
);
9344 install_element(VIEW_NODE
, &show_ip_pim_state_cmd
);
9345 install_element(VIEW_NODE
, &show_ip_pim_state_vrf_all_cmd
);
9346 install_element(VIEW_NODE
, &show_ip_pim_upstream_cmd
);
9347 install_element(VIEW_NODE
, &show_ip_pim_upstream_vrf_all_cmd
);
9348 install_element(VIEW_NODE
, &show_ip_pim_upstream_join_desired_cmd
);
9349 install_element(VIEW_NODE
, &show_ip_pim_upstream_rpf_cmd
);
9350 install_element(VIEW_NODE
, &show_ip_pim_rp_cmd
);
9351 install_element(VIEW_NODE
, &show_ip_pim_rp_vrf_all_cmd
);
9352 install_element(VIEW_NODE
, &show_ip_multicast_cmd
);
9353 install_element(VIEW_NODE
, &show_ip_multicast_vrf_all_cmd
);
9354 install_element(VIEW_NODE
, &show_ip_mroute_cmd
);
9355 install_element(VIEW_NODE
, &show_ip_mroute_vrf_all_cmd
);
9356 install_element(VIEW_NODE
, &show_ip_mroute_count_cmd
);
9357 install_element(VIEW_NODE
, &show_ip_mroute_count_vrf_all_cmd
);
9358 install_element(VIEW_NODE
, &show_ip_rib_cmd
);
9359 install_element(VIEW_NODE
, &show_ip_ssmpingd_cmd
);
9360 install_element(VIEW_NODE
, &show_debugging_pim_cmd
);
9361 install_element(VIEW_NODE
, &show_ip_pim_nexthop_cmd
);
9362 install_element(VIEW_NODE
, &show_ip_pim_nexthop_lookup_cmd
);
9364 install_element(ENABLE_NODE
, &clear_ip_interfaces_cmd
);
9365 install_element(ENABLE_NODE
, &clear_ip_igmp_interfaces_cmd
);
9366 install_element(ENABLE_NODE
, &clear_ip_mroute_cmd
);
9367 install_element(ENABLE_NODE
, &clear_ip_pim_interfaces_cmd
);
9368 install_element(ENABLE_NODE
, &clear_ip_pim_interface_traffic_cmd
);
9369 install_element(ENABLE_NODE
, &clear_ip_pim_oil_cmd
);
9371 install_element(ENABLE_NODE
, &debug_igmp_cmd
);
9372 install_element(ENABLE_NODE
, &no_debug_igmp_cmd
);
9373 install_element(ENABLE_NODE
, &debug_igmp_events_cmd
);
9374 install_element(ENABLE_NODE
, &no_debug_igmp_events_cmd
);
9375 install_element(ENABLE_NODE
, &debug_igmp_packets_cmd
);
9376 install_element(ENABLE_NODE
, &no_debug_igmp_packets_cmd
);
9377 install_element(ENABLE_NODE
, &debug_igmp_trace_cmd
);
9378 install_element(ENABLE_NODE
, &no_debug_igmp_trace_cmd
);
9379 install_element(ENABLE_NODE
, &debug_mroute_cmd
);
9380 install_element(ENABLE_NODE
, &debug_mroute_detail_cmd
);
9381 install_element(ENABLE_NODE
, &no_debug_mroute_cmd
);
9382 install_element(ENABLE_NODE
, &no_debug_mroute_detail_cmd
);
9383 install_element(ENABLE_NODE
, &debug_pim_static_cmd
);
9384 install_element(ENABLE_NODE
, &no_debug_pim_static_cmd
);
9385 install_element(ENABLE_NODE
, &debug_pim_cmd
);
9386 install_element(ENABLE_NODE
, &no_debug_pim_cmd
);
9387 install_element(ENABLE_NODE
, &debug_pim_nht_cmd
);
9388 install_element(ENABLE_NODE
, &no_debug_pim_nht_cmd
);
9389 install_element(ENABLE_NODE
, &debug_pim_nht_rp_cmd
);
9390 install_element(ENABLE_NODE
, &no_debug_pim_nht_rp_cmd
);
9391 install_element(ENABLE_NODE
, &debug_pim_events_cmd
);
9392 install_element(ENABLE_NODE
, &no_debug_pim_events_cmd
);
9393 install_element(ENABLE_NODE
, &debug_pim_packets_cmd
);
9394 install_element(ENABLE_NODE
, &no_debug_pim_packets_cmd
);
9395 install_element(ENABLE_NODE
, &debug_pim_packetdump_send_cmd
);
9396 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_send_cmd
);
9397 install_element(ENABLE_NODE
, &debug_pim_packetdump_recv_cmd
);
9398 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_recv_cmd
);
9399 install_element(ENABLE_NODE
, &debug_pim_trace_cmd
);
9400 install_element(ENABLE_NODE
, &no_debug_pim_trace_cmd
);
9401 install_element(ENABLE_NODE
, &debug_pim_trace_detail_cmd
);
9402 install_element(ENABLE_NODE
, &no_debug_pim_trace_detail_cmd
);
9403 install_element(ENABLE_NODE
, &debug_ssmpingd_cmd
);
9404 install_element(ENABLE_NODE
, &no_debug_ssmpingd_cmd
);
9405 install_element(ENABLE_NODE
, &debug_pim_zebra_cmd
);
9406 install_element(ENABLE_NODE
, &no_debug_pim_zebra_cmd
);
9407 install_element(ENABLE_NODE
, &debug_pim_vxlan_cmd
);
9408 install_element(ENABLE_NODE
, &no_debug_pim_vxlan_cmd
);
9409 install_element(ENABLE_NODE
, &debug_msdp_cmd
);
9410 install_element(ENABLE_NODE
, &no_debug_msdp_cmd
);
9411 install_element(ENABLE_NODE
, &debug_msdp_events_cmd
);
9412 install_element(ENABLE_NODE
, &no_debug_msdp_events_cmd
);
9413 install_element(ENABLE_NODE
, &debug_msdp_packets_cmd
);
9414 install_element(ENABLE_NODE
, &no_debug_msdp_packets_cmd
);
9415 install_element(ENABLE_NODE
, &debug_mtrace_cmd
);
9416 install_element(ENABLE_NODE
, &no_debug_mtrace_cmd
);
9418 install_element(CONFIG_NODE
, &debug_igmp_cmd
);
9419 install_element(CONFIG_NODE
, &no_debug_igmp_cmd
);
9420 install_element(CONFIG_NODE
, &debug_igmp_events_cmd
);
9421 install_element(CONFIG_NODE
, &no_debug_igmp_events_cmd
);
9422 install_element(CONFIG_NODE
, &debug_igmp_packets_cmd
);
9423 install_element(CONFIG_NODE
, &no_debug_igmp_packets_cmd
);
9424 install_element(CONFIG_NODE
, &debug_igmp_trace_cmd
);
9425 install_element(CONFIG_NODE
, &no_debug_igmp_trace_cmd
);
9426 install_element(CONFIG_NODE
, &debug_mroute_cmd
);
9427 install_element(CONFIG_NODE
, &debug_mroute_detail_cmd
);
9428 install_element(CONFIG_NODE
, &no_debug_mroute_cmd
);
9429 install_element(CONFIG_NODE
, &no_debug_mroute_detail_cmd
);
9430 install_element(CONFIG_NODE
, &debug_pim_static_cmd
);
9431 install_element(CONFIG_NODE
, &no_debug_pim_static_cmd
);
9432 install_element(CONFIG_NODE
, &debug_pim_cmd
);
9433 install_element(CONFIG_NODE
, &no_debug_pim_cmd
);
9434 install_element(CONFIG_NODE
, &debug_pim_nht_cmd
);
9435 install_element(CONFIG_NODE
, &no_debug_pim_nht_cmd
);
9436 install_element(CONFIG_NODE
, &debug_pim_nht_rp_cmd
);
9437 install_element(CONFIG_NODE
, &no_debug_pim_nht_rp_cmd
);
9438 install_element(CONFIG_NODE
, &debug_pim_events_cmd
);
9439 install_element(CONFIG_NODE
, &no_debug_pim_events_cmd
);
9440 install_element(CONFIG_NODE
, &debug_pim_packets_cmd
);
9441 install_element(CONFIG_NODE
, &no_debug_pim_packets_cmd
);
9442 install_element(CONFIG_NODE
, &debug_pim_trace_cmd
);
9443 install_element(CONFIG_NODE
, &no_debug_pim_trace_cmd
);
9444 install_element(CONFIG_NODE
, &debug_pim_trace_detail_cmd
);
9445 install_element(CONFIG_NODE
, &no_debug_pim_trace_detail_cmd
);
9446 install_element(CONFIG_NODE
, &debug_ssmpingd_cmd
);
9447 install_element(CONFIG_NODE
, &no_debug_ssmpingd_cmd
);
9448 install_element(CONFIG_NODE
, &debug_pim_zebra_cmd
);
9449 install_element(CONFIG_NODE
, &no_debug_pim_zebra_cmd
);
9450 install_element(CONFIG_NODE
, &debug_pim_vxlan_cmd
);
9451 install_element(CONFIG_NODE
, &no_debug_pim_vxlan_cmd
);
9452 install_element(CONFIG_NODE
, &debug_msdp_cmd
);
9453 install_element(CONFIG_NODE
, &no_debug_msdp_cmd
);
9454 install_element(CONFIG_NODE
, &debug_msdp_events_cmd
);
9455 install_element(CONFIG_NODE
, &no_debug_msdp_events_cmd
);
9456 install_element(CONFIG_NODE
, &debug_msdp_packets_cmd
);
9457 install_element(CONFIG_NODE
, &no_debug_msdp_packets_cmd
);
9458 install_element(CONFIG_NODE
, &debug_mtrace_cmd
);
9459 install_element(CONFIG_NODE
, &no_debug_mtrace_cmd
);
9461 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_member_cmd
);
9462 install_element(VRF_NODE
, &ip_msdp_mesh_group_member_cmd
);
9463 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
9464 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
9465 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_source_cmd
);
9466 install_element(VRF_NODE
, &ip_msdp_mesh_group_source_cmd
);
9467 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
9468 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
9469 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_cmd
);
9470 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_vrf_all_cmd
);
9471 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_cmd
);
9472 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_vrf_all_cmd
);
9473 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_cmd
);
9474 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_vrf_all_cmd
);
9475 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_cmd
);
9476 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_vrf_all_cmd
);
9477 install_element(VIEW_NODE
, &show_ip_pim_ssm_range_cmd
);
9478 install_element(VIEW_NODE
, &show_ip_pim_group_type_cmd
);
9479 install_element(VIEW_NODE
, &show_ip_pim_vxlan_sg_cmd
);
9480 install_element(VIEW_NODE
, &show_ip_pim_vxlan_sg_work_cmd
);
9481 install_element(INTERFACE_NODE
, &interface_pim_use_source_cmd
);
9482 install_element(INTERFACE_NODE
, &interface_no_pim_use_source_cmd
);
9483 /* Install BFD command */
9484 install_element(INTERFACE_NODE
, &ip_pim_bfd_cmd
);
9485 install_element(INTERFACE_NODE
, &ip_pim_bfd_param_cmd
);
9486 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_cmd
);
9488 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_param_cmd
);
9489 #endif /* !HAVE_BFDD */