3 * Copyright (C) 2008 Everton da Silva Marques
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; see the file COPYING; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
34 #include "pim_mroute.h"
36 #include "pim_iface.h"
38 #include "pim_mroute.h"
41 #include "pim_igmpv3.h"
46 #include "pim_neighbor.h"
48 #include "pim_ifchannel.h"
49 #include "pim_hello.h"
51 #include "pim_upstream.h"
53 #include "pim_macro.h"
54 #include "pim_ssmpingd.h"
55 #include "pim_zebra.h"
56 #include "pim_static.h"
58 #include "pim_zlookup.h"
63 #include "pim_vxlan.h"
67 #ifndef VTYSH_EXTRACT_PL
68 #include "pimd/pim_cmd_clippy.c"
71 static struct cmd_node interface_node
= {
72 INTERFACE_NODE
, "%s(config-if)# ", 1 /* vtysh ? yes */
75 static struct cmd_node debug_node
= {DEBUG_NODE
, "", 1};
77 static struct vrf
*pim_cmd_lookup_vrf(struct vty
*vty
, struct cmd_token
*argv
[],
78 const int argc
, int *idx
)
82 if (argv_find(argv
, argc
, "NAME", idx
))
83 vrf
= vrf_lookup_by_name(argv
[*idx
]->arg
);
85 vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
88 vty_out(vty
, "Specified VRF: %s does not exist\n",
94 static void pim_if_membership_clear(struct interface
*ifp
)
96 struct pim_interface
*pim_ifp
;
101 if (PIM_IF_TEST_PIM(pim_ifp
->options
)
102 && PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
106 pim_ifchannel_membership_clear(ifp
);
110 When PIM is disabled on interface, IGMPv3 local membership
111 information is not injected into PIM interface state.
113 The function pim_if_membership_refresh() fetches all IGMPv3 local
114 membership information into PIM. It is intented to be called
115 whenever PIM is enabled on the interface in order to collect missed
116 local membership information.
118 static void pim_if_membership_refresh(struct interface
*ifp
)
120 struct pim_interface
*pim_ifp
;
121 struct listnode
*sock_node
;
122 struct igmp_sock
*igmp
;
127 if (!PIM_IF_TEST_PIM(pim_ifp
->options
))
129 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
))
133 First clear off membership from all PIM (S,G) entries on the
137 pim_ifchannel_membership_clear(ifp
);
140 Then restore PIM (S,G) membership from all IGMPv3 (S,G) entries on
144 /* scan igmp sockets */
145 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
146 struct listnode
*grpnode
;
147 struct igmp_group
*grp
;
149 /* scan igmp groups */
150 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grpnode
,
152 struct listnode
*srcnode
;
153 struct igmp_source
*src
;
155 /* scan group sources */
156 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
,
159 if (IGMP_SOURCE_TEST_FORWARDING(
160 src
->source_flags
)) {
164 sizeof(struct prefix_sg
));
165 sg
.src
= src
->source_addr
;
166 sg
.grp
= grp
->group_addr
;
167 pim_ifchannel_local_membership_add(ifp
,
171 } /* scan group sources */
172 } /* scan igmp groups */
173 } /* scan igmp sockets */
176 Finally delete every PIM (S,G) entry lacking all state info
179 pim_ifchannel_delete_on_noinfo(ifp
);
182 static void pim_show_assert_helper(struct vty
*vty
,
183 struct pim_interface
*pim_ifp
,
184 struct pim_ifchannel
*ch
, time_t now
)
186 char ch_src_str
[INET_ADDRSTRLEN
];
187 char ch_grp_str
[INET_ADDRSTRLEN
];
188 char winner_str
[INET_ADDRSTRLEN
];
189 struct in_addr ifaddr
;
193 ifaddr
= pim_ifp
->primary_address
;
195 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
196 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
197 pim_inet4_dump("<assrt_win?>", ch
->ifassert_winner
, winner_str
,
200 pim_time_uptime(uptime
, sizeof(uptime
), now
- ch
->ifassert_creation
);
201 pim_time_timer_to_mmss(timer
, sizeof(timer
), ch
->t_ifassert_timer
);
203 vty_out(vty
, "%-16s %-15s %-15s %-15s %-6s %-15s %-8s %-5s\n",
204 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
, ch_grp_str
,
205 pim_ifchannel_ifassert_name(ch
->ifassert_state
), winner_str
,
209 static void pim_show_assert(struct pim_instance
*pim
, struct vty
*vty
)
211 struct pim_interface
*pim_ifp
;
212 struct pim_ifchannel
*ch
;
213 struct interface
*ifp
;
216 now
= pim_time_monotonic_sec();
219 "Interface Address Source Group State Winner Uptime Timer\n");
221 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
226 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
227 pim_show_assert_helper(vty
, pim_ifp
, ch
, now
);
228 } /* scan interface channels */
232 static void pim_show_assert_internal_helper(struct vty
*vty
,
233 struct pim_interface
*pim_ifp
,
234 struct pim_ifchannel
*ch
)
236 char ch_src_str
[INET_ADDRSTRLEN
];
237 char ch_grp_str
[INET_ADDRSTRLEN
];
238 struct in_addr ifaddr
;
240 ifaddr
= pim_ifp
->primary_address
;
242 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
243 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
244 vty_out(vty
, "%-16s %-15s %-15s %-15s %-3s %-3s %-3s %-4s\n",
245 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
, ch_grp_str
,
246 PIM_IF_FLAG_TEST_COULD_ASSERT(ch
->flags
) ? "yes" : "no",
247 pim_macro_ch_could_assert_eval(ch
) ? "yes" : "no",
248 PIM_IF_FLAG_TEST_ASSERT_TRACKING_DESIRED(ch
->flags
) ? "yes"
250 pim_macro_assert_tracking_desired_eval(ch
) ? "yes" : "no");
253 static void pim_show_assert_internal(struct pim_instance
*pim
, struct vty
*vty
)
255 struct pim_interface
*pim_ifp
;
256 struct pim_ifchannel
*ch
;
257 struct interface
*ifp
;
261 "ECA: Evaluate CouldAssert\n"
262 "ATD: AssertTrackingDesired\n"
263 "eATD: Evaluate AssertTrackingDesired\n\n");
266 "Interface Address Source Group CA eCA ATD eATD\n");
267 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
272 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
273 pim_show_assert_internal_helper(vty
, pim_ifp
, ch
);
274 } /* scan interface channels */
278 static void pim_show_assert_metric_helper(struct vty
*vty
,
279 struct pim_interface
*pim_ifp
,
280 struct pim_ifchannel
*ch
)
282 char ch_src_str
[INET_ADDRSTRLEN
];
283 char ch_grp_str
[INET_ADDRSTRLEN
];
284 char addr_str
[INET_ADDRSTRLEN
];
285 struct pim_assert_metric am
;
286 struct in_addr ifaddr
;
288 ifaddr
= pim_ifp
->primary_address
;
290 am
= pim_macro_spt_assert_metric(&ch
->upstream
->rpf
,
291 pim_ifp
->primary_address
);
293 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
294 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
295 pim_inet4_dump("<addr?>", am
.ip_address
, addr_str
, sizeof(addr_str
));
297 vty_out(vty
, "%-16s %-15s %-15s %-15s %-3s %4u %6u %-15s\n",
298 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
, ch_grp_str
,
299 am
.rpt_bit_flag
? "yes" : "no", am
.metric_preference
,
300 am
.route_metric
, addr_str
);
303 static void pim_show_assert_metric(struct pim_instance
*pim
, struct vty
*vty
)
305 struct pim_interface
*pim_ifp
;
306 struct pim_ifchannel
*ch
;
307 struct interface
*ifp
;
310 "Interface Address Source Group RPT Pref Metric Address \n");
312 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
317 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
318 pim_show_assert_metric_helper(vty
, pim_ifp
, ch
);
319 } /* scan interface channels */
323 static void pim_show_assert_winner_metric_helper(struct vty
*vty
,
324 struct pim_interface
*pim_ifp
,
325 struct pim_ifchannel
*ch
)
327 char ch_src_str
[INET_ADDRSTRLEN
];
328 char ch_grp_str
[INET_ADDRSTRLEN
];
329 char addr_str
[INET_ADDRSTRLEN
];
330 struct pim_assert_metric
*am
;
331 struct in_addr ifaddr
;
335 ifaddr
= pim_ifp
->primary_address
;
337 am
= &ch
->ifassert_winner_metric
;
339 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
340 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
341 pim_inet4_dump("<addr?>", am
->ip_address
, addr_str
, sizeof(addr_str
));
343 if (am
->metric_preference
== PIM_ASSERT_METRIC_PREFERENCE_MAX
)
344 snprintf(pref_str
, sizeof(pref_str
), "INFI");
346 snprintf(pref_str
, sizeof(pref_str
), "%4u",
347 am
->metric_preference
);
349 if (am
->route_metric
== PIM_ASSERT_ROUTE_METRIC_MAX
)
350 snprintf(metr_str
, sizeof(metr_str
), "INFI");
352 snprintf(metr_str
, sizeof(metr_str
), "%6u", am
->route_metric
);
354 vty_out(vty
, "%-16s %-15s %-15s %-15s %-3s %-4s %-6s %-15s\n",
355 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
, ch_grp_str
,
356 am
->rpt_bit_flag
? "yes" : "no", pref_str
, metr_str
, addr_str
);
359 static void pim_show_assert_winner_metric(struct pim_instance
*pim
,
362 struct pim_interface
*pim_ifp
;
363 struct pim_ifchannel
*ch
;
364 struct interface
*ifp
;
367 "Interface Address Source Group RPT Pref Metric Address \n");
369 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
374 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
375 pim_show_assert_winner_metric_helper(vty
, pim_ifp
, ch
);
376 } /* scan interface channels */
380 static void json_object_pim_ifp_add(struct json_object
*json
,
381 struct interface
*ifp
)
383 struct pim_interface
*pim_ifp
;
386 json_object_string_add(json
, "name", ifp
->name
);
387 json_object_string_add(json
, "state", if_is_up(ifp
) ? "up" : "down");
388 json_object_string_add(json
, "address",
389 inet_ntoa(pim_ifp
->primary_address
));
390 json_object_int_add(json
, "index", ifp
->ifindex
);
392 if (if_is_multicast(ifp
))
393 json_object_boolean_true_add(json
, "flagMulticast");
395 if (if_is_broadcast(ifp
))
396 json_object_boolean_true_add(json
, "flagBroadcast");
398 if (ifp
->flags
& IFF_ALLMULTI
)
399 json_object_boolean_true_add(json
, "flagAllMulticast");
401 if (ifp
->flags
& IFF_PROMISC
)
402 json_object_boolean_true_add(json
, "flagPromiscuous");
404 if (PIM_IF_IS_DELETED(ifp
))
405 json_object_boolean_true_add(json
, "flagDeleted");
407 if (pim_if_lan_delay_enabled(ifp
))
408 json_object_boolean_true_add(json
, "lanDelayEnabled");
411 static void pim_show_membership_helper(struct vty
*vty
,
412 struct pim_interface
*pim_ifp
,
413 struct pim_ifchannel
*ch
,
414 struct json_object
*json
)
416 char ch_src_str
[INET_ADDRSTRLEN
];
417 char ch_grp_str
[INET_ADDRSTRLEN
];
418 json_object
*json_iface
= NULL
;
419 json_object
*json_row
= NULL
;
421 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
422 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
424 json_object_object_get_ex(json
, ch
->interface
->name
, &json_iface
);
426 json_iface
= json_object_new_object();
427 json_object_pim_ifp_add(json_iface
, ch
->interface
);
428 json_object_object_add(json
, ch
->interface
->name
, json_iface
);
431 json_row
= json_object_new_object();
432 json_object_string_add(json_row
, "source", ch_src_str
);
433 json_object_string_add(json_row
, "group", ch_grp_str
);
434 json_object_string_add(json_row
, "localMembership",
435 ch
->local_ifmembership
== PIM_IFMEMBERSHIP_NOINFO
438 json_object_object_add(json_iface
, ch_grp_str
, json_row
);
440 static void pim_show_membership(struct pim_instance
*pim
, struct vty
*vty
,
443 struct pim_interface
*pim_ifp
;
444 struct pim_ifchannel
*ch
;
445 struct interface
*ifp
;
447 json_object
*json
= NULL
;
448 json_object
*json_tmp
= NULL
;
450 json
= json_object_new_object();
452 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
457 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
458 pim_show_membership_helper(vty
, pim_ifp
, ch
, json
);
459 } /* scan interface channels */
463 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
464 json
, JSON_C_TO_STRING_PRETTY
));
467 "Interface Address Source Group Membership\n");
470 * Example of the json data we are traversing
476 * "address":"10.1.20.1",
478 * "flagMulticast":true,
479 * "flagBroadcast":true,
480 * "lanDelayEnabled":true,
483 * "group":"226.10.10.10",
484 * "localMembership":"INCLUDE"
490 /* foreach interface */
491 json_object_object_foreach(json
, key
, val
)
494 /* Find all of the keys where the val is an object. In
496 * above the only one is 226.10.10.10
498 json_object_object_foreach(val
, if_field_key
,
501 type
= json_object_get_type(if_field_val
);
503 if (type
== json_type_object
) {
504 vty_out(vty
, "%-16s ", key
);
506 json_object_object_get_ex(
507 val
, "address", &json_tmp
);
508 vty_out(vty
, "%-15s ",
509 json_object_get_string(
512 json_object_object_get_ex(if_field_val
,
515 vty_out(vty
, "%-15s ",
516 json_object_get_string(
520 vty_out(vty
, "%-15s ", if_field_key
);
522 json_object_object_get_ex(
523 if_field_val
, "localMembership",
525 vty_out(vty
, "%-10s\n",
526 json_object_get_string(
533 json_object_free(json
);
536 static void pim_print_ifp_flags(struct vty
*vty
, struct interface
*ifp
,
539 vty_out(vty
, "Flags\n");
540 vty_out(vty
, "-----\n");
541 vty_out(vty
, "All Multicast : %s\n",
542 (ifp
->flags
& IFF_ALLMULTI
) ? "yes" : "no");
543 vty_out(vty
, "Broadcast : %s\n",
544 if_is_broadcast(ifp
) ? "yes" : "no");
545 vty_out(vty
, "Deleted : %s\n",
546 PIM_IF_IS_DELETED(ifp
) ? "yes" : "no");
547 vty_out(vty
, "Interface Index : %d\n", ifp
->ifindex
);
548 vty_out(vty
, "Multicast : %s\n",
549 if_is_multicast(ifp
) ? "yes" : "no");
550 vty_out(vty
, "Multicast Loop : %d\n", mloop
);
551 vty_out(vty
, "Promiscuous : %s\n",
552 (ifp
->flags
& IFF_PROMISC
) ? "yes" : "no");
557 static void igmp_show_interfaces(struct pim_instance
*pim
, struct vty
*vty
,
560 struct interface
*ifp
;
562 json_object
*json
= NULL
;
563 json_object
*json_row
= NULL
;
565 now
= pim_time_monotonic_sec();
568 json
= json_object_new_object();
571 "Interface State Address V Querier Query Timer Uptime\n");
573 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
574 struct pim_interface
*pim_ifp
;
575 struct listnode
*sock_node
;
576 struct igmp_sock
*igmp
;
583 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
586 char query_hhmmss
[10];
588 pim_time_uptime(uptime
, sizeof(uptime
),
589 now
- igmp
->sock_creation
);
590 pim_time_timer_to_hhmmss(query_hhmmss
,
591 sizeof(query_hhmmss
),
592 igmp
->t_igmp_query_timer
);
595 json_row
= json_object_new_object();
596 json_object_pim_ifp_add(json_row
, ifp
);
597 json_object_string_add(json_row
, "upTime",
599 json_object_int_add(json_row
, "version",
600 pim_ifp
->igmp_version
);
602 if (igmp
->t_igmp_query_timer
) {
603 json_object_boolean_true_add(json_row
,
605 json_object_string_add(json_row
,
610 json_object_object_add(json
, ifp
->name
,
613 if (igmp
->mtrace_only
) {
614 json_object_boolean_true_add(
615 json_row
, "mtraceOnly");
619 "%-16s %5s %15s %d %7s %11s %8s\n",
622 ? (igmp
->mtrace_only
? "mtrc"
625 inet_ntoa(igmp
->ifaddr
),
626 pim_ifp
->igmp_version
,
627 igmp
->t_igmp_query_timer
? "local"
629 query_hhmmss
, uptime
);
635 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
636 json
, JSON_C_TO_STRING_PRETTY
));
637 json_object_free(json
);
641 static void igmp_show_interfaces_single(struct pim_instance
*pim
,
642 struct vty
*vty
, const char *ifname
,
645 struct igmp_sock
*igmp
;
646 struct interface
*ifp
;
647 struct listnode
*sock_node
;
648 struct pim_interface
*pim_ifp
;
650 char query_hhmmss
[10];
651 char other_hhmmss
[10];
652 int found_ifname
= 0;
655 long gmi_msec
; /* Group Membership Interval */
658 long oqpi_msec
; /* Other Querier Present Interval */
662 json_object
*json
= NULL
;
663 json_object
*json_row
= NULL
;
666 json
= json_object_new_object();
668 now
= pim_time_monotonic_sec();
670 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
676 if (strcmp(ifname
, "detail") && strcmp(ifname
, ifp
->name
))
679 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
682 pim_time_uptime(uptime
, sizeof(uptime
),
683 now
- igmp
->sock_creation
);
684 pim_time_timer_to_hhmmss(query_hhmmss
,
685 sizeof(query_hhmmss
),
686 igmp
->t_igmp_query_timer
);
687 pim_time_timer_to_hhmmss(other_hhmmss
,
688 sizeof(other_hhmmss
),
689 igmp
->t_other_querier_timer
);
691 gmi_msec
= PIM_IGMP_GMI_MSEC(
692 igmp
->querier_robustness_variable
,
693 igmp
->querier_query_interval
,
694 pim_ifp
->igmp_query_max_response_time_dsec
);
697 pim_ifp
->igmp_default_query_interval
);
699 oqpi_msec
= PIM_IGMP_OQPI_MSEC(
700 igmp
->querier_robustness_variable
,
701 igmp
->querier_query_interval
,
702 pim_ifp
->igmp_query_max_response_time_dsec
);
704 lmqt_msec
= PIM_IGMP_LMQT_MSEC(
705 pim_ifp
->igmp_query_max_response_time_dsec
,
706 igmp
->querier_robustness_variable
);
710 igmp
->querier_robustness_variable
,
711 igmp
->querier_query_interval
,
712 pim_ifp
->igmp_query_max_response_time_dsec
)
715 qri_msec
= pim_ifp
->igmp_query_max_response_time_dsec
717 if (pim_ifp
->pim_sock_fd
>= 0)
718 mloop
= pim_socket_mcastloop_get(
719 pim_ifp
->pim_sock_fd
);
724 json_row
= json_object_new_object();
725 json_object_pim_ifp_add(json_row
, ifp
);
726 json_object_string_add(json_row
, "upTime",
728 json_object_string_add(json_row
, "querier",
729 igmp
->t_igmp_query_timer
732 json_object_int_add(json_row
, "queryStartCount",
733 igmp
->startup_query_count
);
734 json_object_string_add(json_row
,
737 json_object_string_add(json_row
,
740 json_object_int_add(json_row
, "version",
741 pim_ifp
->igmp_version
);
744 "timerGroupMembershipIntervalMsec",
746 json_object_int_add(json_row
,
747 "timerLastMemberQueryMsec",
751 "timerOlderHostPresentIntervalMsec",
755 "timerOtherQuerierPresentIntervalMsec",
758 json_row
, "timerQueryInterval",
759 igmp
->querier_query_interval
);
762 "timerQueryResponseIntervalMsec",
765 json_row
, "timerRobustnessVariable",
766 igmp
->querier_robustness_variable
);
767 json_object_int_add(json_row
,
768 "timerStartupQueryInterval",
771 json_object_object_add(json
, ifp
->name
,
774 if (igmp
->mtrace_only
) {
775 json_object_boolean_true_add(
776 json_row
, "mtraceOnly");
779 vty_out(vty
, "Interface : %s\n", ifp
->name
);
780 vty_out(vty
, "State : %s\n",
782 ? (igmp
->mtrace_only
? "mtrace"
785 vty_out(vty
, "Address : %s\n",
786 inet_ntoa(pim_ifp
->primary_address
));
787 vty_out(vty
, "Uptime : %s\n", uptime
);
788 vty_out(vty
, "Version : %d\n",
789 pim_ifp
->igmp_version
);
793 vty_out(vty
, "Querier\n");
794 vty_out(vty
, "-------\n");
795 vty_out(vty
, "Querier : %s\n",
796 igmp
->t_igmp_query_timer
? "local"
798 vty_out(vty
, "Start Count : %d\n",
799 igmp
->startup_query_count
);
800 vty_out(vty
, "Query Timer : %s\n",
802 vty_out(vty
, "Other Timer : %s\n",
807 vty_out(vty
, "Timers\n");
808 vty_out(vty
, "------\n");
810 "Group Membership Interval : %lis\n",
813 "Last Member Query Time : %lis\n",
816 "Older Host Present Interval : %lis\n",
819 "Other Querier Present Interval : %lis\n",
822 "Query Interval : %ds\n",
823 igmp
->querier_query_interval
);
825 "Query Response Interval : %lis\n",
828 "Robustness Variable : %d\n",
829 igmp
->querier_robustness_variable
);
831 "Startup Query Interval : %ds\n",
836 pim_print_ifp_flags(vty
, ifp
, mloop
);
842 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
843 json
, JSON_C_TO_STRING_PRETTY
));
844 json_object_free(json
);
847 vty_out(vty
, "%% No such interface\n");
851 static void igmp_show_interface_join(struct pim_instance
*pim
, struct vty
*vty
)
853 struct interface
*ifp
;
856 now
= pim_time_monotonic_sec();
859 "Interface Address Source Group Socket Uptime \n");
861 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
862 struct pim_interface
*pim_ifp
;
863 struct listnode
*join_node
;
864 struct igmp_join
*ij
;
865 struct in_addr pri_addr
;
866 char pri_addr_str
[INET_ADDRSTRLEN
];
873 if (!pim_ifp
->igmp_join_list
)
876 pri_addr
= pim_find_primary_addr(ifp
);
877 pim_inet4_dump("<pri?>", pri_addr
, pri_addr_str
,
878 sizeof(pri_addr_str
));
880 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_join_list
, join_node
,
882 char group_str
[INET_ADDRSTRLEN
];
883 char source_str
[INET_ADDRSTRLEN
];
886 pim_time_uptime(uptime
, sizeof(uptime
),
887 now
- ij
->sock_creation
);
888 pim_inet4_dump("<grp?>", ij
->group_addr
, group_str
,
890 pim_inet4_dump("<src?>", ij
->source_addr
, source_str
,
893 vty_out(vty
, "%-16s %-15s %-15s %-15s %6d %8s\n",
894 ifp
->name
, pri_addr_str
, source_str
, group_str
,
895 ij
->sock_fd
, uptime
);
896 } /* for (pim_ifp->igmp_join_list) */
901 static void pim_show_interfaces_single(struct pim_instance
*pim
,
902 struct vty
*vty
, const char *ifname
,
905 struct in_addr ifaddr
;
906 struct interface
*ifp
;
907 struct listnode
*neighnode
;
908 struct listnode
*upnode
;
909 struct pim_interface
*pim_ifp
;
910 struct pim_neighbor
*neigh
;
911 struct pim_upstream
*up
;
913 char dr_str
[INET_ADDRSTRLEN
];
916 char grp_str
[INET_ADDRSTRLEN
];
917 char hello_period
[10];
918 char hello_timer
[10];
919 char neigh_src_str
[INET_ADDRSTRLEN
];
920 char src_str
[INET_ADDRSTRLEN
];
921 char stat_uptime
[10];
924 int found_ifname
= 0;
926 json_object
*json
= NULL
;
927 json_object
*json_row
= NULL
;
928 json_object
*json_pim_neighbor
= NULL
;
929 json_object
*json_pim_neighbors
= NULL
;
930 json_object
*json_group
= NULL
;
931 json_object
*json_group_source
= NULL
;
932 json_object
*json_fhr_sources
= NULL
;
933 struct pim_secondary_addr
*sec_addr
;
934 struct listnode
*sec_node
;
936 now
= pim_time_monotonic_sec();
939 json
= json_object_new_object();
941 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
947 if (strcmp(ifname
, "detail") && strcmp(ifname
, ifp
->name
))
951 ifaddr
= pim_ifp
->primary_address
;
952 pim_inet4_dump("<dr?>", pim_ifp
->pim_dr_addr
, dr_str
,
954 pim_time_uptime_begin(dr_uptime
, sizeof(dr_uptime
), now
,
955 pim_ifp
->pim_dr_election_last
);
956 pim_time_timer_to_hhmmss(hello_timer
, sizeof(hello_timer
),
957 pim_ifp
->t_pim_hello_timer
);
958 pim_time_mmss(hello_period
, sizeof(hello_period
),
959 pim_ifp
->pim_hello_period
);
960 pim_time_uptime(stat_uptime
, sizeof(stat_uptime
),
961 now
- pim_ifp
->pim_ifstat_start
);
962 if (pim_ifp
->pim_sock_fd
>= 0)
963 mloop
= pim_socket_mcastloop_get(pim_ifp
->pim_sock_fd
);
968 char pbuf
[PREFIX2STR_BUFFER
];
969 json_row
= json_object_new_object();
970 json_object_pim_ifp_add(json_row
, ifp
);
972 if (pim_ifp
->update_source
.s_addr
!= INADDR_ANY
) {
973 json_object_string_add(
974 json_row
, "useSource",
975 inet_ntoa(pim_ifp
->update_source
));
977 if (pim_ifp
->sec_addr_list
) {
978 json_object
*sec_list
= NULL
;
980 sec_list
= json_object_new_array();
981 for (ALL_LIST_ELEMENTS_RO(
982 pim_ifp
->sec_addr_list
, sec_node
,
984 json_object_array_add(
986 json_object_new_string(
992 json_object_object_add(json_row
,
993 "secondaryAddressList",
998 if (pim_ifp
->pim_neighbor_list
->count
) {
999 json_pim_neighbors
= json_object_new_object();
1001 for (ALL_LIST_ELEMENTS_RO(
1002 pim_ifp
->pim_neighbor_list
,
1003 neighnode
, neigh
)) {
1005 json_object_new_object();
1006 pim_inet4_dump("<src?>",
1009 sizeof(neigh_src_str
));
1010 pim_time_uptime(uptime
, sizeof(uptime
),
1011 now
- neigh
->creation
);
1012 pim_time_timer_to_hhmmss(
1013 expire
, sizeof(expire
),
1014 neigh
->t_expire_timer
);
1016 json_object_string_add(
1017 json_pim_neighbor
, "address",
1019 json_object_string_add(
1020 json_pim_neighbor
, "upTime",
1022 json_object_string_add(
1023 json_pim_neighbor
, "holdtime",
1026 json_object_object_add(
1032 json_object_object_add(json_row
, "neighbors",
1033 json_pim_neighbors
);
1036 json_object_string_add(json_row
, "drAddress", dr_str
);
1037 json_object_int_add(json_row
, "drPriority",
1038 pim_ifp
->pim_dr_priority
);
1039 json_object_string_add(json_row
, "drUptime", dr_uptime
);
1040 json_object_int_add(json_row
, "drElections",
1041 pim_ifp
->pim_dr_election_count
);
1042 json_object_int_add(json_row
, "drChanges",
1043 pim_ifp
->pim_dr_election_changes
);
1046 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
,
1048 if (ifp
!= up
->rpf
.source_nexthop
.interface
)
1051 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
))
1054 if (!json_fhr_sources
)
1056 json_object_new_object();
1058 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
,
1060 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
,
1062 pim_time_uptime(uptime
, sizeof(uptime
),
1063 now
- up
->state_transition
);
1066 * Does this group live in json_fhr_sources?
1069 json_object_object_get_ex(json_fhr_sources
,
1070 grp_str
, &json_group
);
1073 json_group
= json_object_new_object();
1074 json_object_object_add(json_fhr_sources
,
1079 json_group_source
= json_object_new_object();
1080 json_object_string_add(json_group_source
,
1082 json_object_string_add(json_group_source
,
1084 json_object_string_add(json_group_source
,
1086 json_object_object_add(json_group
, src_str
,
1090 if (json_fhr_sources
) {
1091 json_object_object_add(json_row
,
1096 json_object_int_add(json_row
, "helloPeriod",
1097 pim_ifp
->pim_hello_period
);
1098 json_object_string_add(json_row
, "helloTimer",
1100 json_object_string_add(json_row
, "helloStatStart",
1102 json_object_int_add(json_row
, "helloReceived",
1103 pim_ifp
->pim_ifstat_hello_recv
);
1104 json_object_int_add(json_row
, "helloReceivedFailed",
1105 pim_ifp
->pim_ifstat_hello_recvfail
);
1106 json_object_int_add(json_row
, "helloSend",
1107 pim_ifp
->pim_ifstat_hello_sent
);
1108 json_object_int_add(json_row
, "hellosendFailed",
1109 pim_ifp
->pim_ifstat_hello_sendfail
);
1110 json_object_int_add(json_row
, "helloGenerationId",
1111 pim_ifp
->pim_generation_id
);
1112 json_object_int_add(json_row
, "flagMulticastLoop",
1115 json_object_int_add(
1116 json_row
, "effectivePropagationDelay",
1117 pim_if_effective_propagation_delay_msec(ifp
));
1118 json_object_int_add(
1119 json_row
, "effectiveOverrideInterval",
1120 pim_if_effective_override_interval_msec(ifp
));
1121 json_object_int_add(
1122 json_row
, "joinPruneOverrideInterval",
1123 pim_if_jp_override_interval_msec(ifp
));
1125 json_object_int_add(
1126 json_row
, "propagationDelay",
1127 pim_ifp
->pim_propagation_delay_msec
);
1128 json_object_int_add(
1129 json_row
, "propagationDelayHighest",
1130 pim_ifp
->pim_neighbors_highest_propagation_delay_msec
);
1131 json_object_int_add(
1132 json_row
, "overrideInterval",
1133 pim_ifp
->pim_override_interval_msec
);
1134 json_object_int_add(
1135 json_row
, "overrideIntervalHighest",
1136 pim_ifp
->pim_neighbors_highest_override_interval_msec
);
1137 json_object_object_add(json
, ifp
->name
, json_row
);
1140 vty_out(vty
, "Interface : %s\n", ifp
->name
);
1141 vty_out(vty
, "State : %s\n",
1142 if_is_up(ifp
) ? "up" : "down");
1143 if (pim_ifp
->update_source
.s_addr
!= INADDR_ANY
) {
1144 vty_out(vty
, "Use Source : %s\n",
1145 inet_ntoa(pim_ifp
->update_source
));
1147 if (pim_ifp
->sec_addr_list
) {
1148 char pbuf
[PREFIX2STR_BUFFER
];
1149 vty_out(vty
, "Address : %s (primary)\n",
1151 for (ALL_LIST_ELEMENTS_RO(
1152 pim_ifp
->sec_addr_list
, sec_node
,
1154 vty_out(vty
, " %s\n",
1155 prefix2str(&sec_addr
->addr
,
1156 pbuf
, sizeof(pbuf
)));
1159 vty_out(vty
, "Address : %s\n",
1167 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
,
1168 neighnode
, neigh
)) {
1171 vty_out(vty
, "PIM Neighbors\n");
1172 vty_out(vty
, "-------------\n");
1176 pim_inet4_dump("<src?>", neigh
->source_addr
,
1178 sizeof(neigh_src_str
));
1179 pim_time_uptime(uptime
, sizeof(uptime
),
1180 now
- neigh
->creation
);
1181 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
1182 neigh
->t_expire_timer
);
1184 "%-15s : up for %s, holdtime expires in %s\n",
1185 neigh_src_str
, uptime
, expire
);
1188 if (!print_header
) {
1193 vty_out(vty
, "Designated Router\n");
1194 vty_out(vty
, "-----------------\n");
1195 vty_out(vty
, "Address : %s\n", dr_str
);
1196 vty_out(vty
, "Priority : %u(%d)\n",
1197 pim_ifp
->pim_dr_priority
,
1198 pim_ifp
->pim_dr_num_nondrpri_neighbors
);
1199 vty_out(vty
, "Uptime : %s\n", dr_uptime
);
1200 vty_out(vty
, "Elections : %d\n",
1201 pim_ifp
->pim_dr_election_count
);
1202 vty_out(vty
, "Changes : %d\n",
1203 pim_ifp
->pim_dr_election_changes
);
1209 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
,
1211 if (!up
->rpf
.source_nexthop
.interface
)
1214 if (strcmp(ifp
->name
,
1215 up
->rpf
.source_nexthop
1220 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
))
1225 "FHR - First Hop Router\n");
1227 "----------------------\n");
1231 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
,
1233 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
,
1235 pim_time_uptime(uptime
, sizeof(uptime
),
1236 now
- up
->state_transition
);
1238 "%s : %s is a source, uptime is %s\n",
1239 grp_str
, src_str
, uptime
);
1242 if (!print_header
) {
1247 vty_out(vty
, "Hellos\n");
1248 vty_out(vty
, "------\n");
1249 vty_out(vty
, "Period : %d\n",
1250 pim_ifp
->pim_hello_period
);
1251 vty_out(vty
, "Timer : %s\n", hello_timer
);
1252 vty_out(vty
, "StatStart : %s\n", stat_uptime
);
1253 vty_out(vty
, "Receive : %d\n",
1254 pim_ifp
->pim_ifstat_hello_recv
);
1255 vty_out(vty
, "Receive Failed : %d\n",
1256 pim_ifp
->pim_ifstat_hello_recvfail
);
1257 vty_out(vty
, "Send : %d\n",
1258 pim_ifp
->pim_ifstat_hello_sent
);
1259 vty_out(vty
, "Send Failed : %d\n",
1260 pim_ifp
->pim_ifstat_hello_sendfail
);
1261 vty_out(vty
, "Generation ID : %08x\n",
1262 pim_ifp
->pim_generation_id
);
1266 pim_print_ifp_flags(vty
, ifp
, mloop
);
1268 vty_out(vty
, "Join Prune Interval\n");
1269 vty_out(vty
, "-------------------\n");
1270 vty_out(vty
, "LAN Delay : %s\n",
1271 pim_if_lan_delay_enabled(ifp
) ? "yes" : "no");
1272 vty_out(vty
, "Effective Propagation Delay : %d msec\n",
1273 pim_if_effective_propagation_delay_msec(ifp
));
1274 vty_out(vty
, "Effective Override Interval : %d msec\n",
1275 pim_if_effective_override_interval_msec(ifp
));
1276 vty_out(vty
, "Join Prune Override Interval : %d msec\n",
1277 pim_if_jp_override_interval_msec(ifp
));
1281 vty_out(vty
, "LAN Prune Delay\n");
1282 vty_out(vty
, "---------------\n");
1283 vty_out(vty
, "Propagation Delay : %d msec\n",
1284 pim_ifp
->pim_propagation_delay_msec
);
1285 vty_out(vty
, "Propagation Delay (Highest) : %d msec\n",
1286 pim_ifp
->pim_neighbors_highest_propagation_delay_msec
);
1287 vty_out(vty
, "Override Interval : %d msec\n",
1288 pim_ifp
->pim_override_interval_msec
);
1289 vty_out(vty
, "Override Interval (Highest) : %d msec\n",
1290 pim_ifp
->pim_neighbors_highest_override_interval_msec
);
1297 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1298 json
, JSON_C_TO_STRING_PRETTY
));
1299 json_object_free(json
);
1302 vty_out(vty
, "%% No such interface\n");
1306 static void igmp_show_statistics(struct pim_instance
*pim
, struct vty
*vty
,
1307 const char *ifname
, bool uj
)
1309 struct interface
*ifp
;
1310 struct igmp_stats rx_stats
;
1312 igmp_stats_init(&rx_stats
);
1314 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1315 struct pim_interface
*pim_ifp
;
1316 struct listnode
*sock_node
;
1317 struct igmp_sock
*igmp
;
1319 pim_ifp
= ifp
->info
;
1324 if (ifname
&& strcmp(ifname
, ifp
->name
))
1327 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
1329 igmp_stats_add(&rx_stats
, &igmp
->rx_stats
);
1333 json_object
*json
= NULL
;
1334 json_object
*json_row
= NULL
;
1336 json
= json_object_new_object();
1337 json_row
= json_object_new_object();
1339 json_object_string_add(json_row
, "name", ifname
? ifname
:
1341 json_object_int_add(json_row
, "queryV1", rx_stats
.query_v1
);
1342 json_object_int_add(json_row
, "queryV2", rx_stats
.query_v2
);
1343 json_object_int_add(json_row
, "queryV3", rx_stats
.query_v3
);
1344 json_object_int_add(json_row
, "leaveV3", rx_stats
.leave_v2
);
1345 json_object_int_add(json_row
, "reportV1", rx_stats
.report_v1
);
1346 json_object_int_add(json_row
, "reportV2", rx_stats
.report_v2
);
1347 json_object_int_add(json_row
, "reportV3", rx_stats
.report_v3
);
1348 json_object_int_add(json_row
, "mtraceResponse",
1349 rx_stats
.mtrace_rsp
);
1350 json_object_int_add(json_row
, "mtraceRequest",
1351 rx_stats
.mtrace_req
);
1352 json_object_int_add(json_row
, "unsupported",
1353 rx_stats
.unsupported
);
1354 json_object_object_add(json
, ifname
? ifname
: "global",
1356 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1357 json
, JSON_C_TO_STRING_PRETTY
));
1358 json_object_free(json
);
1360 vty_out(vty
, "IGMP RX statistics\n");
1361 vty_out(vty
, "Interface : %s\n",
1362 ifname
? ifname
: "global");
1363 vty_out(vty
, "V1 query : %u\n", rx_stats
.query_v1
);
1364 vty_out(vty
, "V2 query : %u\n", rx_stats
.query_v2
);
1365 vty_out(vty
, "V3 query : %u\n", rx_stats
.query_v3
);
1366 vty_out(vty
, "V2 leave : %u\n", rx_stats
.leave_v2
);
1367 vty_out(vty
, "V1 report : %u\n", rx_stats
.report_v1
);
1368 vty_out(vty
, "V2 report : %u\n", rx_stats
.report_v2
);
1369 vty_out(vty
, "V3 report : %u\n", rx_stats
.report_v3
);
1370 vty_out(vty
, "mtrace response : %u\n", rx_stats
.mtrace_rsp
);
1371 vty_out(vty
, "mtrace request : %u\n", rx_stats
.mtrace_req
);
1372 vty_out(vty
, "unsupported : %u\n", rx_stats
.unsupported
);
1376 static void pim_show_interfaces(struct pim_instance
*pim
, struct vty
*vty
,
1379 struct interface
*ifp
;
1380 struct listnode
*upnode
;
1381 struct pim_interface
*pim_ifp
;
1382 struct pim_upstream
*up
;
1385 int pim_ifchannels
= 0;
1386 json_object
*json
= NULL
;
1387 json_object
*json_row
= NULL
;
1388 json_object
*json_tmp
;
1390 json
= json_object_new_object();
1392 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1393 pim_ifp
= ifp
->info
;
1398 pim_nbrs
= pim_ifp
->pim_neighbor_list
->count
;
1399 pim_ifchannels
= pim_if_ifchannel_count(pim_ifp
);
1402 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
, up
))
1403 if (ifp
== up
->rpf
.source_nexthop
.interface
)
1404 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
1407 json_row
= json_object_new_object();
1408 json_object_pim_ifp_add(json_row
, ifp
);
1409 json_object_int_add(json_row
, "pimNeighbors", pim_nbrs
);
1410 json_object_int_add(json_row
, "pimIfChannels", pim_ifchannels
);
1411 json_object_int_add(json_row
, "firstHopRouterCount", fhr
);
1412 json_object_string_add(json_row
, "pimDesignatedRouter",
1413 inet_ntoa(pim_ifp
->pim_dr_addr
));
1415 if (pim_ifp
->pim_dr_addr
.s_addr
1416 == pim_ifp
->primary_address
.s_addr
)
1417 json_object_boolean_true_add(
1418 json_row
, "pimDesignatedRouterLocal");
1420 json_object_object_add(json
, ifp
->name
, json_row
);
1424 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1425 json
, JSON_C_TO_STRING_PRETTY
));
1428 "Interface State Address PIM Nbrs PIM DR FHR IfChannels\n");
1430 json_object_object_foreach(json
, key
, val
)
1432 vty_out(vty
, "%-16s ", key
);
1434 json_object_object_get_ex(val
, "state", &json_tmp
);
1435 vty_out(vty
, "%5s ", json_object_get_string(json_tmp
));
1437 json_object_object_get_ex(val
, "address", &json_tmp
);
1438 vty_out(vty
, "%15s ",
1439 json_object_get_string(json_tmp
));
1441 json_object_object_get_ex(val
, "pimNeighbors",
1443 vty_out(vty
, "%8d ", json_object_get_int(json_tmp
));
1445 if (json_object_object_get_ex(
1446 val
, "pimDesignatedRouterLocal",
1448 vty_out(vty
, "%15s ", "local");
1450 json_object_object_get_ex(
1451 val
, "pimDesignatedRouter", &json_tmp
);
1452 vty_out(vty
, "%15s ",
1453 json_object_get_string(json_tmp
));
1456 json_object_object_get_ex(val
, "firstHopRouter",
1458 vty_out(vty
, "%3d ", json_object_get_int(json_tmp
));
1460 json_object_object_get_ex(val
, "pimIfChannels",
1462 vty_out(vty
, "%9d\n", json_object_get_int(json_tmp
));
1466 json_object_free(json
);
1469 static void pim_show_interface_traffic(struct pim_instance
*pim
,
1470 struct vty
*vty
, bool uj
)
1472 struct interface
*ifp
= NULL
;
1473 struct pim_interface
*pim_ifp
= NULL
;
1474 json_object
*json
= NULL
;
1475 json_object
*json_row
= NULL
;
1478 json
= json_object_new_object();
1481 vty_out(vty
, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s%-17s\n",
1482 "Interface", " HELLO", " JOIN",
1483 " PRUNE", " REGISTER", "REGISTER-STOP",
1485 vty_out(vty
, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s%-17s\n", "",
1486 " Rx/Tx", " Rx/Tx", " Rx/Tx",
1487 " Rx/Tx", " Rx/Tx", " Rx/Tx",
1490 "---------------------------------------------------------------------------------------------------------------\n");
1493 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1494 pim_ifp
= ifp
->info
;
1499 if (pim_ifp
->pim_sock_fd
< 0)
1502 json_row
= json_object_new_object();
1503 json_object_pim_ifp_add(json_row
, ifp
);
1504 json_object_int_add(json_row
, "helloRx",
1505 pim_ifp
->pim_ifstat_hello_recv
);
1506 json_object_int_add(json_row
, "helloTx",
1507 pim_ifp
->pim_ifstat_hello_sent
);
1508 json_object_int_add(json_row
, "joinRx",
1509 pim_ifp
->pim_ifstat_join_recv
);
1510 json_object_int_add(json_row
, "joinTx",
1511 pim_ifp
->pim_ifstat_join_send
);
1512 json_object_int_add(json_row
, "registerRx",
1513 pim_ifp
->pim_ifstat_reg_recv
);
1514 json_object_int_add(json_row
, "registerTx",
1515 pim_ifp
->pim_ifstat_reg_recv
);
1516 json_object_int_add(json_row
, "registerStopRx",
1517 pim_ifp
->pim_ifstat_reg_stop_recv
);
1518 json_object_int_add(json_row
, "registerStopTx",
1519 pim_ifp
->pim_ifstat_reg_stop_send
);
1520 json_object_int_add(json_row
, "assertRx",
1521 pim_ifp
->pim_ifstat_assert_recv
);
1522 json_object_int_add(json_row
, "assertTx",
1523 pim_ifp
->pim_ifstat_assert_send
);
1524 json_object_int_add(json_row
, "bsmRx",
1525 pim_ifp
->pim_ifstat_bsm_rx
);
1526 json_object_int_add(json_row
, "bsmTx",
1527 pim_ifp
->pim_ifstat_bsm_tx
);
1528 json_object_object_add(json
, ifp
->name
, json_row
);
1531 "%-16s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7lu/%-7lu \n",
1532 ifp
->name
, pim_ifp
->pim_ifstat_hello_recv
,
1533 pim_ifp
->pim_ifstat_hello_sent
,
1534 pim_ifp
->pim_ifstat_join_recv
,
1535 pim_ifp
->pim_ifstat_join_send
,
1536 pim_ifp
->pim_ifstat_prune_recv
,
1537 pim_ifp
->pim_ifstat_prune_send
,
1538 pim_ifp
->pim_ifstat_reg_recv
,
1539 pim_ifp
->pim_ifstat_reg_send
,
1540 pim_ifp
->pim_ifstat_reg_stop_recv
,
1541 pim_ifp
->pim_ifstat_reg_stop_send
,
1542 pim_ifp
->pim_ifstat_assert_recv
,
1543 pim_ifp
->pim_ifstat_assert_send
,
1544 pim_ifp
->pim_ifstat_bsm_rx
,
1545 pim_ifp
->pim_ifstat_bsm_tx
);
1549 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1550 json
, JSON_C_TO_STRING_PRETTY
));
1551 json_object_free(json
);
1555 static void pim_show_interface_traffic_single(struct pim_instance
*pim
,
1557 const char *ifname
, bool uj
)
1559 struct interface
*ifp
= NULL
;
1560 struct pim_interface
*pim_ifp
= NULL
;
1561 json_object
*json
= NULL
;
1562 json_object
*json_row
= NULL
;
1563 uint8_t found_ifname
= 0;
1566 json
= json_object_new_object();
1569 vty_out(vty
, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s%-17s\n",
1570 "Interface", " HELLO", " JOIN", " PRUNE",
1571 " REGISTER", " REGISTER-STOP", " ASSERT",
1573 vty_out(vty
, "%-14s%-18s%-17s%-17s%-17s%-17s%-17s%-17s\n", "",
1574 " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1575 " Rx/Tx", " Rx/Tx", " Rx/Tx");
1577 "-------------------------------------------------------------------------------------------------------------------------------\n");
1580 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1581 if (strcmp(ifname
, ifp
->name
))
1584 pim_ifp
= ifp
->info
;
1589 if (pim_ifp
->pim_sock_fd
< 0)
1594 json_row
= json_object_new_object();
1595 json_object_pim_ifp_add(json_row
, ifp
);
1596 json_object_int_add(json_row
, "helloRx",
1597 pim_ifp
->pim_ifstat_hello_recv
);
1598 json_object_int_add(json_row
, "helloTx",
1599 pim_ifp
->pim_ifstat_hello_sent
);
1600 json_object_int_add(json_row
, "joinRx",
1601 pim_ifp
->pim_ifstat_join_recv
);
1602 json_object_int_add(json_row
, "joinTx",
1603 pim_ifp
->pim_ifstat_join_send
);
1604 json_object_int_add(json_row
, "registerRx",
1605 pim_ifp
->pim_ifstat_reg_recv
);
1606 json_object_int_add(json_row
, "registerTx",
1607 pim_ifp
->pim_ifstat_reg_recv
);
1608 json_object_int_add(json_row
, "registerStopRx",
1609 pim_ifp
->pim_ifstat_reg_stop_recv
);
1610 json_object_int_add(json_row
, "registerStopTx",
1611 pim_ifp
->pim_ifstat_reg_stop_send
);
1612 json_object_int_add(json_row
, "assertRx",
1613 pim_ifp
->pim_ifstat_assert_recv
);
1614 json_object_int_add(json_row
, "assertTx",
1615 pim_ifp
->pim_ifstat_assert_send
);
1616 json_object_int_add(json_row
, "bsmRx",
1617 pim_ifp
->pim_ifstat_bsm_rx
);
1618 json_object_int_add(json_row
, "bsmTx",
1619 pim_ifp
->pim_ifstat_bsm_tx
);
1621 json_object_object_add(json
, ifp
->name
, json_row
);
1624 "%-16s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7lu/%-7lu \n",
1625 ifp
->name
, pim_ifp
->pim_ifstat_hello_recv
,
1626 pim_ifp
->pim_ifstat_hello_sent
,
1627 pim_ifp
->pim_ifstat_join_recv
,
1628 pim_ifp
->pim_ifstat_join_send
,
1629 pim_ifp
->pim_ifstat_prune_recv
,
1630 pim_ifp
->pim_ifstat_prune_send
,
1631 pim_ifp
->pim_ifstat_reg_recv
,
1632 pim_ifp
->pim_ifstat_reg_send
,
1633 pim_ifp
->pim_ifstat_reg_stop_recv
,
1634 pim_ifp
->pim_ifstat_reg_stop_send
,
1635 pim_ifp
->pim_ifstat_assert_recv
,
1636 pim_ifp
->pim_ifstat_assert_send
,
1637 pim_ifp
->pim_ifstat_bsm_rx
,
1638 pim_ifp
->pim_ifstat_bsm_tx
);
1642 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1643 json
, JSON_C_TO_STRING_PRETTY
));
1644 json_object_free(json
);
1647 vty_out(vty
, "%% No such interface\n");
1651 static void pim_show_join_helper(struct vty
*vty
, struct pim_interface
*pim_ifp
,
1652 struct pim_ifchannel
*ch
, json_object
*json
,
1653 time_t now
, bool uj
)
1655 char ch_src_str
[INET_ADDRSTRLEN
];
1656 char ch_grp_str
[INET_ADDRSTRLEN
];
1657 json_object
*json_iface
= NULL
;
1658 json_object
*json_row
= NULL
;
1659 json_object
*json_grp
= NULL
;
1660 struct in_addr ifaddr
;
1665 ifaddr
= pim_ifp
->primary_address
;
1667 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
1668 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
1670 pim_time_uptime_begin(uptime
, sizeof(uptime
), now
, ch
->ifjoin_creation
);
1671 pim_time_timer_to_mmss(expire
, sizeof(expire
),
1672 ch
->t_ifjoin_expiry_timer
);
1673 pim_time_timer_to_mmss(prune
, sizeof(prune
),
1674 ch
->t_ifjoin_prune_pending_timer
);
1677 json_object_object_get_ex(json
, ch
->interface
->name
,
1681 json_iface
= json_object_new_object();
1682 json_object_pim_ifp_add(json_iface
, ch
->interface
);
1683 json_object_object_add(json
, ch
->interface
->name
,
1687 json_row
= json_object_new_object();
1688 json_object_string_add(json_row
, "source", ch_src_str
);
1689 json_object_string_add(json_row
, "group", ch_grp_str
);
1690 json_object_string_add(json_row
, "upTime", uptime
);
1691 json_object_string_add(json_row
, "expire", expire
);
1692 json_object_string_add(json_row
, "prune", prune
);
1693 json_object_string_add(
1694 json_row
, "channelJoinName",
1695 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
, ch
->flags
));
1696 if (PIM_IF_FLAG_TEST_S_G_RPT(ch
->flags
))
1697 json_object_int_add(json_row
, "SGRpt", 1);
1699 json_object_object_get_ex(json_iface
, ch_grp_str
, &json_grp
);
1701 json_grp
= json_object_new_object();
1702 json_object_object_add(json_grp
, ch_src_str
, json_row
);
1703 json_object_object_add(json_iface
, ch_grp_str
,
1706 json_object_object_add(json_grp
, ch_src_str
, json_row
);
1708 vty_out(vty
, "%-16s %-15s %-15s %-15s %-10s %8s %-6s %5s\n",
1709 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
,
1711 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
, ch
->flags
),
1712 uptime
, expire
, prune
);
1716 static void pim_show_join(struct pim_instance
*pim
, struct vty
*vty
,
1717 struct prefix_sg
*sg
, bool uj
)
1719 struct pim_interface
*pim_ifp
;
1720 struct pim_ifchannel
*ch
;
1721 struct interface
*ifp
;
1723 json_object
*json
= NULL
;
1725 now
= pim_time_monotonic_sec();
1728 json
= json_object_new_object();
1731 "Interface Address Source Group State Uptime Expire Prune\n");
1733 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1734 pim_ifp
= ifp
->info
;
1738 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
1739 if (sg
->grp
.s_addr
!= 0
1740 && sg
->grp
.s_addr
!= ch
->sg
.grp
.s_addr
)
1742 if (sg
->src
.s_addr
!= 0
1743 && sg
->src
.s_addr
!= ch
->sg
.src
.s_addr
)
1745 pim_show_join_helper(vty
, pim_ifp
, ch
, json
, now
, uj
);
1746 } /* scan interface channels */
1750 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1751 json
, JSON_C_TO_STRING_PRETTY
));
1752 json_object_free(json
);
1756 static void pim_show_neighbors_single(struct pim_instance
*pim
, struct vty
*vty
,
1757 const char *neighbor
, bool uj
)
1759 struct listnode
*neighnode
;
1760 struct interface
*ifp
;
1761 struct pim_interface
*pim_ifp
;
1762 struct pim_neighbor
*neigh
;
1764 int found_neighbor
= 0;
1765 int option_address_list
;
1766 int option_dr_priority
;
1767 int option_generation_id
;
1768 int option_holdtime
;
1769 int option_lan_prune_delay
;
1773 char neigh_src_str
[INET_ADDRSTRLEN
];
1775 json_object
*json
= NULL
;
1776 json_object
*json_ifp
= NULL
;
1777 json_object
*json_row
= NULL
;
1779 now
= pim_time_monotonic_sec();
1782 json
= json_object_new_object();
1784 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1785 pim_ifp
= ifp
->info
;
1790 if (pim_ifp
->pim_sock_fd
< 0)
1793 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
1795 pim_inet4_dump("<src?>", neigh
->source_addr
,
1796 neigh_src_str
, sizeof(neigh_src_str
));
1799 * The user can specify either the interface name or the
1801 * If this pim_ifp matches neither then skip.
1803 if (strcmp(neighbor
, "detail")
1804 && strcmp(neighbor
, ifp
->name
)
1805 && strcmp(neighbor
, neigh_src_str
))
1809 pim_time_uptime(uptime
, sizeof(uptime
),
1810 now
- neigh
->creation
);
1811 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
1812 neigh
->t_expire_timer
);
1814 option_address_list
= 0;
1815 option_dr_priority
= 0;
1816 option_generation_id
= 0;
1817 option_holdtime
= 0;
1818 option_lan_prune_delay
= 0;
1821 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1822 PIM_OPTION_MASK_ADDRESS_LIST
))
1823 option_address_list
= 1;
1825 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1826 PIM_OPTION_MASK_DR_PRIORITY
))
1827 option_dr_priority
= 1;
1829 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1830 PIM_OPTION_MASK_GENERATION_ID
))
1831 option_generation_id
= 1;
1833 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1834 PIM_OPTION_MASK_HOLDTIME
))
1835 option_holdtime
= 1;
1837 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1838 PIM_OPTION_MASK_LAN_PRUNE_DELAY
))
1839 option_lan_prune_delay
= 1;
1841 if (PIM_OPTION_IS_SET(
1842 neigh
->hello_options
,
1843 PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION
))
1848 /* Does this ifp live in json? If not create
1850 json_object_object_get_ex(json
, ifp
->name
,
1854 json_ifp
= json_object_new_object();
1855 json_object_pim_ifp_add(json_ifp
, ifp
);
1856 json_object_object_add(json
, ifp
->name
,
1860 json_row
= json_object_new_object();
1861 json_object_string_add(json_row
, "interface",
1863 json_object_string_add(json_row
, "address",
1865 json_object_string_add(json_row
, "upTime",
1867 json_object_string_add(json_row
, "holdtime",
1869 json_object_int_add(json_row
, "drPriority",
1870 neigh
->dr_priority
);
1871 json_object_int_add(json_row
, "generationId",
1872 neigh
->generation_id
);
1874 if (option_address_list
)
1875 json_object_boolean_true_add(
1877 "helloOptionAddressList");
1879 if (option_dr_priority
)
1880 json_object_boolean_true_add(
1882 "helloOptionDrPriority");
1884 if (option_generation_id
)
1885 json_object_boolean_true_add(
1887 "helloOptionGenerationId");
1889 if (option_holdtime
)
1890 json_object_boolean_true_add(
1892 "helloOptionHoldtime");
1894 if (option_lan_prune_delay
)
1895 json_object_boolean_true_add(
1897 "helloOptionLanPruneDelay");
1900 json_object_boolean_true_add(
1901 json_row
, "helloOptionTBit");
1903 json_object_object_add(json_ifp
, neigh_src_str
,
1907 vty_out(vty
, "Interface : %s\n", ifp
->name
);
1908 vty_out(vty
, "Neighbor : %s\n", neigh_src_str
);
1916 " DR Priority : %d\n",
1917 neigh
->dr_priority
);
1919 " Generation ID : %08x\n",
1920 neigh
->generation_id
);
1922 " Override Interval (msec) : %d\n",
1923 neigh
->override_interval_msec
);
1925 " Propagation Delay (msec) : %d\n",
1926 neigh
->propagation_delay_msec
);
1928 " Hello Option - Address List : %s\n",
1929 option_address_list
? "yes" : "no");
1931 " Hello Option - DR Priority : %s\n",
1932 option_dr_priority
? "yes" : "no");
1934 " Hello Option - Generation ID : %s\n",
1935 option_generation_id
? "yes" : "no");
1937 " Hello Option - Holdtime : %s\n",
1938 option_holdtime
? "yes" : "no");
1940 " Hello Option - LAN Prune Delay : %s\n",
1941 option_lan_prune_delay
? "yes" : "no");
1943 " Hello Option - T-bit : %s\n",
1944 option_t_bit
? "yes" : "no");
1945 pim_bfd_show_info(vty
, neigh
->bfd_info
,
1953 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1954 json
, JSON_C_TO_STRING_PRETTY
));
1955 json_object_free(json
);
1958 if (!found_neighbor
)
1960 "%% No such interface or neighbor\n");
1965 static void pim_show_state(struct pim_instance
*pim
, struct vty
*vty
,
1966 const char *src_or_group
, const char *group
, bool uj
)
1968 struct channel_oil
*c_oil
;
1969 struct listnode
*node
;
1970 json_object
*json
= NULL
;
1971 json_object
*json_group
= NULL
;
1972 json_object
*json_ifp_in
= NULL
;
1973 json_object
*json_ifp_out
= NULL
;
1974 json_object
*json_source
= NULL
;
1977 now
= pim_time_monotonic_sec();
1980 json
= json_object_new_object();
1983 "Codes: J -> Pim Join, I -> IGMP Report, S -> Source, * -> Inherited from (*,G), V -> VxLAN");
1985 "\nInstalled Source Group IIF OIL\n");
1988 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
1989 char grp_str
[INET_ADDRSTRLEN
];
1990 char src_str
[INET_ADDRSTRLEN
];
1991 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
1992 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
1994 struct interface
*ifp_in
;
1997 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
1999 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
2001 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
2004 strlcpy(in_ifname
, ifp_in
->name
, sizeof(in_ifname
));
2006 strlcpy(in_ifname
, "<iif?>", sizeof(in_ifname
));
2009 if (strcmp(src_or_group
, src_str
)
2010 && strcmp(src_or_group
, grp_str
))
2013 if (group
&& strcmp(group
, grp_str
))
2019 /* Find the group, create it if it doesn't exist */
2020 json_object_object_get_ex(json
, grp_str
, &json_group
);
2023 json_group
= json_object_new_object();
2024 json_object_object_add(json
, grp_str
,
2028 /* Find the source nested under the group, create it if
2029 * it doesn't exist */
2030 json_object_object_get_ex(json_group
, src_str
,
2034 json_source
= json_object_new_object();
2035 json_object_object_add(json_group
, src_str
,
2039 /* Find the inbound interface nested under the source,
2040 * create it if it doesn't exist */
2041 json_object_object_get_ex(json_source
, in_ifname
,
2045 json_ifp_in
= json_object_new_object();
2046 json_object_object_add(json_source
, in_ifname
,
2048 json_object_int_add(json_source
, "Installed",
2050 json_object_int_add(json_source
, "RefCount",
2051 c_oil
->oil_ref_count
);
2052 json_object_int_add(json_source
, "OilListSize",
2054 json_object_int_add(
2055 json_source
, "OilRescan",
2056 c_oil
->oil_inherited_rescan
);
2057 json_object_int_add(json_source
, "LastUsed",
2058 c_oil
->cc
.lastused
);
2059 json_object_int_add(json_source
, "PacketCount",
2061 json_object_int_add(json_source
, "ByteCount",
2063 json_object_int_add(json_source
,
2065 c_oil
->cc
.wrong_if
);
2068 vty_out(vty
, "%-9d %-15s %-15s %-16s ",
2069 c_oil
->installed
, src_str
, grp_str
, in_ifname
);
2072 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
2074 struct interface
*ifp_out
;
2075 char oif_uptime
[10];
2078 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
2082 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
2084 oif_uptime
, sizeof(oif_uptime
),
2085 now
- c_oil
->oif_creation
[oif_vif_index
]);
2088 strlcpy(out_ifname
, ifp_out
->name
, sizeof(out_ifname
));
2090 strlcpy(out_ifname
, "<oif?>", sizeof(out_ifname
));
2093 json_ifp_out
= json_object_new_object();
2094 json_object_string_add(json_ifp_out
, "source",
2096 json_object_string_add(json_ifp_out
, "group",
2098 json_object_string_add(json_ifp_out
,
2101 json_object_string_add(json_ifp_out
,
2102 "outboundInterface",
2104 json_object_int_add(json_ifp_out
, "installed",
2107 json_object_object_add(json_ifp_in
, out_ifname
,
2112 vty_out(vty
, "%s(%c%c%c%c%c)", out_ifname
,
2113 (c_oil
->oif_flags
[oif_vif_index
]
2114 & PIM_OIF_FLAG_PROTO_IGMP
)
2117 (c_oil
->oif_flags
[oif_vif_index
]
2118 & PIM_OIF_FLAG_PROTO_PIM
)
2121 (c_oil
->oif_flags
[oif_vif_index
]
2122 & PIM_OIF_FLAG_PROTO_VXLAN
)
2125 (c_oil
->oif_flags
[oif_vif_index
]
2126 & PIM_OIF_FLAG_PROTO_SOURCE
)
2129 (c_oil
->oif_flags
[oif_vif_index
]
2130 & PIM_OIF_FLAG_PROTO_STAR
)
2134 vty_out(vty
, ", %s(%c%c%c%c%c)",
2136 (c_oil
->oif_flags
[oif_vif_index
]
2137 & PIM_OIF_FLAG_PROTO_IGMP
)
2140 (c_oil
->oif_flags
[oif_vif_index
]
2141 & PIM_OIF_FLAG_PROTO_PIM
)
2144 (c_oil
->oif_flags
[oif_vif_index
]
2145 & PIM_OIF_FLAG_PROTO_VXLAN
)
2148 (c_oil
->oif_flags
[oif_vif_index
]
2149 & PIM_OIF_FLAG_PROTO_SOURCE
)
2152 (c_oil
->oif_flags
[oif_vif_index
]
2153 & PIM_OIF_FLAG_PROTO_STAR
)
2165 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2166 json
, JSON_C_TO_STRING_PRETTY
));
2167 json_object_free(json
);
2173 static void pim_show_neighbors(struct pim_instance
*pim
, struct vty
*vty
,
2176 struct listnode
*neighnode
;
2177 struct interface
*ifp
;
2178 struct pim_interface
*pim_ifp
;
2179 struct pim_neighbor
*neigh
;
2183 char neigh_src_str
[INET_ADDRSTRLEN
];
2184 json_object
*json
= NULL
;
2185 json_object
*json_ifp_rows
= NULL
;
2186 json_object
*json_row
= NULL
;
2188 now
= pim_time_monotonic_sec();
2191 json
= json_object_new_object();
2194 "Interface Neighbor Uptime Holdtime DR Pri\n");
2197 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2198 pim_ifp
= ifp
->info
;
2203 if (pim_ifp
->pim_sock_fd
< 0)
2207 json_ifp_rows
= json_object_new_object();
2209 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
2211 pim_inet4_dump("<src?>", neigh
->source_addr
,
2212 neigh_src_str
, sizeof(neigh_src_str
));
2213 pim_time_uptime(uptime
, sizeof(uptime
),
2214 now
- neigh
->creation
);
2215 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
2216 neigh
->t_expire_timer
);
2219 json_row
= json_object_new_object();
2220 json_object_string_add(json_row
, "interface",
2222 json_object_string_add(json_row
, "neighbor",
2224 json_object_string_add(json_row
, "upTime",
2226 json_object_string_add(json_row
, "holdTime",
2228 json_object_int_add(json_row
, "holdTimeMax",
2230 json_object_int_add(json_row
, "drPriority",
2231 neigh
->dr_priority
);
2232 json_object_object_add(json_ifp_rows
,
2233 neigh_src_str
, json_row
);
2236 vty_out(vty
, "%-16s %15s %8s %8s %6d\n",
2237 ifp
->name
, neigh_src_str
, uptime
,
2238 expire
, neigh
->dr_priority
);
2243 json_object_object_add(json
, ifp
->name
, json_ifp_rows
);
2244 json_ifp_rows
= NULL
;
2249 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2250 json
, JSON_C_TO_STRING_PRETTY
));
2251 json_object_free(json
);
2255 static void pim_show_neighbors_secondary(struct pim_instance
*pim
,
2258 struct interface
*ifp
;
2261 "Interface Address Neighbor Secondary \n");
2263 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2264 struct pim_interface
*pim_ifp
;
2265 struct in_addr ifaddr
;
2266 struct listnode
*neighnode
;
2267 struct pim_neighbor
*neigh
;
2269 pim_ifp
= ifp
->info
;
2274 if (pim_ifp
->pim_sock_fd
< 0)
2277 ifaddr
= pim_ifp
->primary_address
;
2279 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
2281 char neigh_src_str
[INET_ADDRSTRLEN
];
2282 struct listnode
*prefix_node
;
2285 if (!neigh
->prefix_list
)
2288 pim_inet4_dump("<src?>", neigh
->source_addr
,
2289 neigh_src_str
, sizeof(neigh_src_str
));
2291 for (ALL_LIST_ELEMENTS_RO(neigh
->prefix_list
,
2293 char neigh_sec_str
[PREFIX2STR_BUFFER
];
2295 prefix2str(p
, neigh_sec_str
,
2296 sizeof(neigh_sec_str
));
2298 vty_out(vty
, "%-16s %-15s %-15s %-15s\n",
2299 ifp
->name
, inet_ntoa(ifaddr
),
2300 neigh_src_str
, neigh_sec_str
);
2306 static void json_object_pim_upstream_add(json_object
*json
,
2307 struct pim_upstream
*up
)
2309 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED
)
2310 json_object_boolean_true_add(json
, "drJoinDesired");
2312 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED
)
2313 json_object_boolean_true_add(json
, "drJoinDesiredUpdated");
2315 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
2316 json_object_boolean_true_add(json
, "firstHopRouter");
2318 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_IGMP
)
2319 json_object_boolean_true_add(json
, "sourceIgmp");
2321 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_PIM
)
2322 json_object_boolean_true_add(json
, "sourcePim");
2324 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_STREAM
)
2325 json_object_boolean_true_add(json
, "sourceStream");
2327 /* XXX: need to print ths flag in the plain text display as well */
2328 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_MSDP
)
2329 json_object_boolean_true_add(json
, "sourceMsdp");
2331 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SEND_SG_RPT_PRUNE
)
2332 json_object_boolean_true_add(json
, "sendSGRptPrune");
2334 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_LHR
)
2335 json_object_boolean_true_add(json
, "lastHopRouter");
2337 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DISABLE_KAT_EXPIRY
)
2338 json_object_boolean_true_add(json
, "disableKATExpiry");
2340 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_STATIC_IIF
)
2341 json_object_boolean_true_add(json
, "staticIncomingInterface");
2343 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_ALLOW_IIF_IN_OIL
)
2344 json_object_boolean_true_add(json
,
2345 "allowIncomingInterfaceinOil");
2347 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_NO_PIMREG_DATA
)
2348 json_object_boolean_true_add(json
, "noPimRegistrationData");
2350 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FORCE_PIMREG
)
2351 json_object_boolean_true_add(json
, "forcePimRegistration");
2353 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_ORIG
)
2354 json_object_boolean_true_add(json
, "sourceVxlanOrigination");
2356 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_TERM
)
2357 json_object_boolean_true_add(json
, "sourceVxlanTermination");
2359 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_VXLAN
)
2360 json_object_boolean_true_add(json
, "mlagVxlan");
2362 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_NON_DF
)
2363 json_object_boolean_true_add(json
,
2364 "mlagNonDesignatedForwarder");
2368 pim_upstream_state2brief_str(enum pim_upstream_state join_state
,
2369 char *state_str
, size_t state_str_len
)
2371 switch (join_state
) {
2372 case PIM_UPSTREAM_NOTJOINED
:
2373 strlcpy(state_str
, "NotJ", state_str_len
);
2375 case PIM_UPSTREAM_JOINED
:
2376 strlcpy(state_str
, "J", state_str_len
);
2379 strlcpy(state_str
, "Unk", state_str_len
);
2384 static const char *pim_reg_state2brief_str(enum pim_reg_state reg_state
,
2385 char *state_str
, size_t state_str_len
)
2387 switch (reg_state
) {
2388 case PIM_REG_NOINFO
:
2389 strlcpy(state_str
, "RegNI", state_str_len
);
2392 strlcpy(state_str
, "RegJ", state_str_len
);
2394 case PIM_REG_JOIN_PENDING
:
2396 strlcpy(state_str
, "RegP", state_str_len
);
2399 strlcpy(state_str
, "Unk", state_str_len
);
2404 static void pim_show_upstream(struct pim_instance
*pim
, struct vty
*vty
,
2405 struct prefix_sg
*sg
, bool uj
)
2407 struct listnode
*upnode
;
2408 struct pim_upstream
*up
;
2410 json_object
*json
= NULL
;
2411 json_object
*json_group
= NULL
;
2412 json_object
*json_row
= NULL
;
2414 now
= pim_time_monotonic_sec();
2417 json
= json_object_new_object();
2420 "Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt\n");
2422 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
, up
)) {
2423 char src_str
[INET_ADDRSTRLEN
];
2424 char grp_str
[INET_ADDRSTRLEN
];
2426 char join_timer
[10];
2429 char msdp_reg_timer
[10];
2430 char state_str
[PIM_REG_STATE_STR_LEN
];
2432 if (sg
->grp
.s_addr
!= 0 && sg
->grp
.s_addr
!= up
->sg
.grp
.s_addr
)
2434 if (sg
->src
.s_addr
!= 0 && sg
->src
.s_addr
!= up
->sg
.src
.s_addr
)
2437 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2438 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2439 pim_time_uptime(uptime
, sizeof(uptime
),
2440 now
- up
->state_transition
);
2441 pim_time_timer_to_hhmmss(join_timer
, sizeof(join_timer
),
2445 * If the upstream is not dummy and it has a J/P timer for the
2446 * neighbor display that
2448 if (!up
->t_join_timer
&& up
->rpf
.source_nexthop
.interface
) {
2449 struct pim_neighbor
*nbr
;
2451 nbr
= pim_neighbor_find(
2452 up
->rpf
.source_nexthop
.interface
,
2453 up
->rpf
.rpf_addr
.u
.prefix4
);
2455 pim_time_timer_to_hhmmss(join_timer
,
2460 pim_time_timer_to_hhmmss(rs_timer
, sizeof(rs_timer
),
2462 pim_time_timer_to_hhmmss(ka_timer
, sizeof(ka_timer
),
2464 pim_time_timer_to_hhmmss(msdp_reg_timer
, sizeof(msdp_reg_timer
),
2465 up
->t_msdp_reg_timer
);
2467 pim_upstream_state2brief_str(up
->join_state
, state_str
, sizeof(state_str
));
2468 if (up
->reg_state
!= PIM_REG_NOINFO
) {
2469 char tmp_str
[PIM_REG_STATE_STR_LEN
];
2471 sprintf(state_str
+ strlen(state_str
), ",%s",
2472 pim_reg_state2brief_str(up
->reg_state
, tmp_str
,
2477 json_object_object_get_ex(json
, grp_str
, &json_group
);
2480 json_group
= json_object_new_object();
2481 json_object_object_add(json
, grp_str
,
2485 json_row
= json_object_new_object();
2486 json_object_pim_upstream_add(json_row
, up
);
2487 json_object_string_add(
2488 json_row
, "inboundInterface",
2489 up
->rpf
.source_nexthop
.interface
2490 ? up
->rpf
.source_nexthop
.interface
->name
2494 * The RPF address we use is slightly different
2495 * based upon what we are looking up.
2496 * If we have a S, list that unless
2497 * we are the FHR, else we just put
2498 * the RP as the rpfAddress
2500 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
2501 || up
->sg
.src
.s_addr
== INADDR_ANY
) {
2502 char rpf
[PREFIX_STRLEN
];
2503 struct pim_rpf
*rpg
;
2505 rpg
= RP(pim
, up
->sg
.grp
);
2506 pim_inet4_dump("<rpf?>",
2507 rpg
->rpf_addr
.u
.prefix4
, rpf
,
2509 json_object_string_add(json_row
, "rpfAddress",
2512 json_object_string_add(json_row
, "rpfAddress",
2516 json_object_string_add(json_row
, "source", src_str
);
2517 json_object_string_add(json_row
, "group", grp_str
);
2518 json_object_string_add(json_row
, "state", state_str
);
2519 json_object_string_add(
2520 json_row
, "joinState",
2521 pim_upstream_state2str(up
->join_state
));
2522 json_object_string_add(
2523 json_row
, "regState",
2524 pim_reg_state2str(up
->reg_state
, state_str
, sizeof(state_str
)));
2525 json_object_string_add(json_row
, "upTime", uptime
);
2526 json_object_string_add(json_row
, "joinTimer",
2528 json_object_string_add(json_row
, "resetTimer",
2530 json_object_string_add(json_row
, "keepaliveTimer",
2532 json_object_string_add(json_row
, "msdpRegTimer",
2534 json_object_int_add(json_row
, "refCount",
2536 json_object_int_add(json_row
, "sptBit", up
->sptbit
);
2537 json_object_object_add(json_group
, src_str
, json_row
);
2540 "%-16s%-15s %-15s %-11s %-8s %-9s %-9s %-9s %6d\n",
2541 up
->rpf
.source_nexthop
.interface
2542 ? up
->rpf
.source_nexthop
.interface
->name
2544 src_str
, grp_str
, state_str
, uptime
, join_timer
,
2545 rs_timer
, ka_timer
, up
->ref_count
);
2550 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2551 json
, JSON_C_TO_STRING_PRETTY
));
2552 json_object_free(json
);
2556 static void pim_show_join_desired_helper(struct pim_instance
*pim
,
2558 struct pim_interface
*pim_ifp
,
2559 struct pim_ifchannel
*ch
,
2560 json_object
*json
, bool uj
)
2562 struct pim_upstream
*up
= ch
->upstream
;
2563 json_object
*json_group
= NULL
;
2564 char src_str
[INET_ADDRSTRLEN
];
2565 char grp_str
[INET_ADDRSTRLEN
];
2566 json_object
*json_row
= NULL
;
2568 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2569 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2572 json_object_object_get_ex(json
, grp_str
, &json_group
);
2575 json_group
= json_object_new_object();
2576 json_object_object_add(json
, grp_str
, json_group
);
2579 json_row
= json_object_new_object();
2580 json_object_pim_upstream_add(json_row
, up
);
2581 json_object_string_add(json_row
, "interface",
2582 ch
->interface
->name
);
2583 json_object_string_add(json_row
, "source", src_str
);
2584 json_object_string_add(json_row
, "group", grp_str
);
2586 if (pim_macro_ch_lost_assert(ch
))
2587 json_object_boolean_true_add(json_row
, "lostAssert");
2589 if (pim_macro_chisin_joins(ch
))
2590 json_object_boolean_true_add(json_row
, "joins");
2592 if (pim_macro_chisin_pim_include(ch
))
2593 json_object_boolean_true_add(json_row
, "pimInclude");
2595 if (pim_upstream_evaluate_join_desired(pim
, up
))
2596 json_object_boolean_true_add(json_row
,
2597 "evaluateJoinDesired");
2599 json_object_object_add(json_group
, src_str
, json_row
);
2602 vty_out(vty
, "%-16s %-15s %-15s %-10s %-5s %-10s %-11s %-6s\n",
2603 ch
->interface
->name
, src_str
, grp_str
,
2604 pim_macro_ch_lost_assert(ch
) ? "yes" : "no",
2605 pim_macro_chisin_joins(ch
) ? "yes" : "no",
2606 pim_macro_chisin_pim_include(ch
) ? "yes" : "no",
2607 PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(up
->flags
)
2610 pim_upstream_evaluate_join_desired(pim
, up
) ? "yes"
2615 static void pim_show_join_desired(struct pim_instance
*pim
, struct vty
*vty
,
2618 struct pim_interface
*pim_ifp
;
2619 struct pim_ifchannel
*ch
;
2620 struct interface
*ifp
;
2622 json_object
*json
= NULL
;
2625 json
= json_object_new_object();
2628 "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD\n");
2630 /* scan per-interface (S,G) state */
2631 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2632 pim_ifp
= ifp
->info
;
2637 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
2638 /* scan all interfaces */
2639 pim_show_join_desired_helper(pim
, vty
, pim_ifp
, ch
,
2645 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2646 json
, JSON_C_TO_STRING_PRETTY
));
2647 json_object_free(json
);
2651 static void pim_show_upstream_rpf(struct pim_instance
*pim
, struct vty
*vty
,
2654 struct listnode
*upnode
;
2655 struct pim_upstream
*up
;
2656 json_object
*json
= NULL
;
2657 json_object
*json_group
= NULL
;
2658 json_object
*json_row
= NULL
;
2661 json
= json_object_new_object();
2664 "Source Group RpfIface RibNextHop RpfAddress \n");
2666 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
, up
)) {
2667 char src_str
[INET_ADDRSTRLEN
];
2668 char grp_str
[INET_ADDRSTRLEN
];
2669 char rpf_nexthop_str
[PREFIX_STRLEN
];
2670 char rpf_addr_str
[PREFIX_STRLEN
];
2671 struct pim_rpf
*rpf
;
2672 const char *rpf_ifname
;
2676 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2677 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2678 pim_addr_dump("<nexthop?>",
2679 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2680 rpf_nexthop_str
, sizeof(rpf_nexthop_str
));
2681 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2682 sizeof(rpf_addr_str
));
2684 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2687 json_object_object_get_ex(json
, grp_str
, &json_group
);
2690 json_group
= json_object_new_object();
2691 json_object_object_add(json
, grp_str
,
2695 json_row
= json_object_new_object();
2696 json_object_pim_upstream_add(json_row
, up
);
2697 json_object_string_add(json_row
, "source", src_str
);
2698 json_object_string_add(json_row
, "group", grp_str
);
2699 json_object_string_add(json_row
, "rpfInterface",
2701 json_object_string_add(json_row
, "ribNexthop",
2703 json_object_string_add(json_row
, "rpfAddress",
2705 json_object_object_add(json_group
, src_str
, json_row
);
2707 vty_out(vty
, "%-15s %-15s %-16s %-15s %-15s\n", src_str
,
2708 grp_str
, rpf_ifname
, rpf_nexthop_str
,
2714 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2715 json
, JSON_C_TO_STRING_PRETTY
));
2716 json_object_free(json
);
2720 static void show_rpf_refresh_stats(struct vty
*vty
, struct pim_instance
*pim
,
2721 time_t now
, json_object
*json
)
2723 char refresh_uptime
[10];
2725 pim_time_uptime_begin(refresh_uptime
, sizeof(refresh_uptime
), now
,
2726 pim
->rpf_cache_refresh_last
);
2729 json_object_int_add(json
, "rpfCacheRefreshDelayMsecs",
2730 router
->rpf_cache_refresh_delay_msec
);
2731 json_object_int_add(
2732 json
, "rpfCacheRefreshTimer",
2733 pim_time_timer_remain_msec(pim
->rpf_cache_refresher
));
2734 json_object_int_add(json
, "rpfCacheRefreshRequests",
2735 pim
->rpf_cache_refresh_requests
);
2736 json_object_int_add(json
, "rpfCacheRefreshEvents",
2737 pim
->rpf_cache_refresh_events
);
2738 json_object_string_add(json
, "rpfCacheRefreshLast",
2740 json_object_int_add(json
, "nexthopLookups",
2741 pim
->nexthop_lookups
);
2742 json_object_int_add(json
, "nexthopLookupsAvoided",
2743 pim
->nexthop_lookups_avoided
);
2746 "RPF Cache Refresh Delay: %ld msecs\n"
2747 "RPF Cache Refresh Timer: %ld msecs\n"
2748 "RPF Cache Refresh Requests: %lld\n"
2749 "RPF Cache Refresh Events: %lld\n"
2750 "RPF Cache Refresh Last: %s\n"
2751 "Nexthop Lookups: %lld\n"
2752 "Nexthop Lookups Avoided: %lld\n",
2753 router
->rpf_cache_refresh_delay_msec
,
2754 pim_time_timer_remain_msec(pim
->rpf_cache_refresher
),
2755 (long long)pim
->rpf_cache_refresh_requests
,
2756 (long long)pim
->rpf_cache_refresh_events
,
2757 refresh_uptime
, (long long)pim
->nexthop_lookups
,
2758 (long long)pim
->nexthop_lookups_avoided
);
2762 static void show_scan_oil_stats(struct pim_instance
*pim
, struct vty
*vty
,
2765 char uptime_scan_oil
[10];
2766 char uptime_mroute_add
[10];
2767 char uptime_mroute_del
[10];
2769 pim_time_uptime_begin(uptime_scan_oil
, sizeof(uptime_scan_oil
), now
,
2770 pim
->scan_oil_last
);
2771 pim_time_uptime_begin(uptime_mroute_add
, sizeof(uptime_mroute_add
), now
,
2772 pim
->mroute_add_last
);
2773 pim_time_uptime_begin(uptime_mroute_del
, sizeof(uptime_mroute_del
), now
,
2774 pim
->mroute_del_last
);
2777 "Scan OIL - Last: %s Events: %lld\n"
2778 "MFC Add - Last: %s Events: %lld\n"
2779 "MFC Del - Last: %s Events: %lld\n",
2780 uptime_scan_oil
, (long long)pim
->scan_oil_events
,
2781 uptime_mroute_add
, (long long)pim
->mroute_add_events
,
2782 uptime_mroute_del
, (long long)pim
->mroute_del_events
);
2785 static void pim_show_rpf(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
2787 struct listnode
*up_node
;
2788 struct pim_upstream
*up
;
2789 time_t now
= pim_time_monotonic_sec();
2790 json_object
*json
= NULL
;
2791 json_object
*json_group
= NULL
;
2792 json_object
*json_row
= NULL
;
2795 json
= json_object_new_object();
2796 show_rpf_refresh_stats(vty
, pim
, now
, json
);
2798 show_rpf_refresh_stats(vty
, pim
, now
, json
);
2801 "Source Group RpfIface RpfAddress RibNextHop Metric Pref\n");
2804 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, up_node
, up
)) {
2805 char src_str
[INET_ADDRSTRLEN
];
2806 char grp_str
[INET_ADDRSTRLEN
];
2807 char rpf_addr_str
[PREFIX_STRLEN
];
2808 char rib_nexthop_str
[PREFIX_STRLEN
];
2809 const char *rpf_ifname
;
2810 struct pim_rpf
*rpf
= &up
->rpf
;
2812 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2813 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2814 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2815 sizeof(rpf_addr_str
));
2816 pim_addr_dump("<nexthop?>",
2817 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2818 rib_nexthop_str
, sizeof(rib_nexthop_str
));
2820 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2823 json_object_object_get_ex(json
, grp_str
, &json_group
);
2826 json_group
= json_object_new_object();
2827 json_object_object_add(json
, grp_str
,
2831 json_row
= json_object_new_object();
2832 json_object_string_add(json_row
, "source", src_str
);
2833 json_object_string_add(json_row
, "group", grp_str
);
2834 json_object_string_add(json_row
, "rpfInterface",
2836 json_object_string_add(json_row
, "rpfAddress",
2838 json_object_string_add(json_row
, "ribNexthop",
2840 json_object_int_add(
2841 json_row
, "routeMetric",
2842 rpf
->source_nexthop
.mrib_route_metric
);
2843 json_object_int_add(
2844 json_row
, "routePreference",
2845 rpf
->source_nexthop
.mrib_metric_preference
);
2846 json_object_object_add(json_group
, src_str
, json_row
);
2849 vty_out(vty
, "%-15s %-15s %-16s %-15s %-15s %6d %4d\n",
2850 src_str
, grp_str
, rpf_ifname
, rpf_addr_str
,
2852 rpf
->source_nexthop
.mrib_route_metric
,
2853 rpf
->source_nexthop
.mrib_metric_preference
);
2858 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2859 json
, JSON_C_TO_STRING_PRETTY
));
2860 json_object_free(json
);
2864 struct pnc_cache_walk_data
{
2866 struct pim_instance
*pim
;
2869 static int pim_print_pnc_cache_walkcb(struct hash_bucket
*bucket
, void *arg
)
2871 struct pim_nexthop_cache
*pnc
= bucket
->data
;
2872 struct pnc_cache_walk_data
*cwd
= arg
;
2873 struct vty
*vty
= cwd
->vty
;
2874 struct pim_instance
*pim
= cwd
->pim
;
2875 struct nexthop
*nh_node
= NULL
;
2876 ifindex_t first_ifindex
;
2877 struct interface
*ifp
= NULL
;
2879 for (nh_node
= pnc
->nexthop
; nh_node
; nh_node
= nh_node
->next
) {
2880 first_ifindex
= nh_node
->ifindex
;
2881 ifp
= if_lookup_by_index(first_ifindex
, pim
->vrf_id
);
2883 vty_out(vty
, "%-15s ", inet_ntoa(pnc
->rpf
.rpf_addr
.u
.prefix4
));
2884 vty_out(vty
, "%-16s ", ifp
? ifp
->name
: "NULL");
2885 vty_out(vty
, "%s ", inet_ntoa(nh_node
->gate
.ipv4
));
2891 static void pim_show_nexthop(struct pim_instance
*pim
, struct vty
*vty
)
2893 struct pnc_cache_walk_data cwd
;
2897 vty_out(vty
, "Number of registered addresses: %lu\n",
2898 pim
->rpf_hash
->count
);
2899 vty_out(vty
, "Address Interface Nexthop\n");
2900 vty_out(vty
, "---------------------------------------------\n");
2902 hash_walk(pim
->rpf_hash
, pim_print_pnc_cache_walkcb
, &cwd
);
2905 /* Display the bsm database details */
2906 static void pim_show_bsm_db(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
2908 struct listnode
*bsmnode
;
2911 struct bsm_info
*bsm
;
2912 json_object
*json
= NULL
;
2913 json_object
*json_group
= NULL
;
2914 json_object
*json_row
= NULL
;
2916 count
= pim
->global_scope
.bsm_list
->count
;
2919 json
= json_object_new_object();
2920 json_object_int_add(json
, "Number of the fragments", count
);
2922 vty_out(vty
, "Scope Zone: Global\n");
2923 vty_out(vty
, "Number of the fragments: %d\n", count
);
2927 for (ALL_LIST_ELEMENTS_RO(pim
->global_scope
.bsm_list
, bsmnode
, bsm
)) {
2928 char grp_str
[INET_ADDRSTRLEN
];
2929 char rp_str
[INET_ADDRSTRLEN
];
2930 char bsr_str
[INET_ADDRSTRLEN
];
2931 struct bsmmsg_grpinfo
*group
;
2932 struct bsmmsg_rpinfo
*rpaddr
;
2934 struct bsm_hdr
*hdr
;
2935 uint32_t offset
= 0;
2938 uint32_t frag_rp_cnt
= 0;
2943 /* skip pim header */
2944 buf
+= PIM_MSG_HEADER_LEN
;
2945 len
-= PIM_MSG_HEADER_LEN
;
2947 hdr
= (struct bsm_hdr
*)buf
;
2949 /* BSM starts with bsr header */
2950 buf
+= sizeof(struct bsm_hdr
);
2951 len
-= sizeof(struct bsm_hdr
);
2953 pim_inet4_dump("<BSR Address?>", hdr
->bsr_addr
.addr
, bsr_str
,
2958 json_object_string_add(json
, "BSR address", bsr_str
);
2959 json_object_int_add(json
, "BSR priority",
2961 json_object_int_add(json
, "Hashmask Length",
2963 json_object_int_add(json
, "Fragment Tag",
2964 ntohs(hdr
->frag_tag
));
2966 vty_out(vty
, "BSM Fragment : %d\n", fragment
);
2967 vty_out(vty
, "------------------\n");
2968 vty_out(vty
, "%-15s %-15s %-15s %-15s\n", "BSR-Address",
2969 "BSR-Priority", "Hashmask-len", "Fragment-Tag");
2970 vty_out(vty
, "%-15s %-15d %-15d %-15d\n", bsr_str
,
2971 hdr
->bsr_prio
, hdr
->hm_len
,
2972 ntohs(hdr
->frag_tag
));
2977 while (offset
< len
) {
2978 group
= (struct bsmmsg_grpinfo
*)buf
;
2980 if (group
->group
.family
== PIM_MSG_ADDRESS_FAMILY_IPV4
)
2981 grp
.family
= AF_INET
;
2983 grp
.prefixlen
= group
->group
.mask
;
2984 grp
.u
.prefix4
.s_addr
= group
->group
.addr
.s_addr
;
2986 prefix2str(&grp
, grp_str
, sizeof(grp_str
));
2988 buf
+= sizeof(struct bsmmsg_grpinfo
);
2989 offset
+= sizeof(struct bsmmsg_grpinfo
);
2992 json_object_object_get_ex(json
, grp_str
,
2995 json_group
= json_object_new_object();
2996 json_object_int_add(json_group
,
2999 json_object_int_add(
3000 json_group
, "Fragment Rp count",
3001 group
->frag_rp_count
);
3002 json_object_object_add(json
, grp_str
,
3006 vty_out(vty
, "Group : %s\n", grp_str
);
3007 vty_out(vty
, "-------------------\n");
3008 vty_out(vty
, "Rp Count:%d\n", group
->rp_count
);
3009 vty_out(vty
, "Fragment Rp Count : %d\n",
3010 group
->frag_rp_count
);
3013 frag_rp_cnt
= group
->frag_rp_count
;
3020 "RpAddress HoldTime Priority\n");
3022 while (frag_rp_cnt
--) {
3023 rpaddr
= (struct bsmmsg_rpinfo
*)buf
;
3025 buf
+= sizeof(struct bsmmsg_rpinfo
);
3026 offset
+= sizeof(struct bsmmsg_rpinfo
);
3028 pim_inet4_dump("<Rp addr?>",
3029 rpaddr
->rpaddr
.addr
, rp_str
,
3033 json_row
= json_object_new_object();
3034 json_object_string_add(
3035 json_row
, "Rp Address", rp_str
);
3036 json_object_int_add(
3037 json_row
, "Rp HoldTime",
3038 ntohs(rpaddr
->rp_holdtime
));
3039 json_object_int_add(json_row
,
3042 json_object_object_add(
3043 json_group
, rp_str
, json_row
);
3045 vty_out(vty
, "%-15s %-12d %d\n", rp_str
,
3046 ntohs(rpaddr
->rp_holdtime
),
3057 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3058 json
, JSON_C_TO_STRING_PRETTY
));
3059 json_object_free(json
);
3063 /*Display the group-rp mappings */
3064 static void pim_show_group_rp_mappings_info(struct pim_instance
*pim
,
3065 struct vty
*vty
, bool uj
)
3067 struct bsgrp_node
*bsgrp
;
3068 struct listnode
*rpnode
;
3069 struct bsm_rpinfo
*bsm_rp
;
3070 struct route_node
*rn
;
3071 char bsr_str
[INET_ADDRSTRLEN
];
3072 json_object
*json
= NULL
;
3073 json_object
*json_group
= NULL
;
3074 json_object
*json_row
= NULL
;
3076 if (pim
->global_scope
.current_bsr
.s_addr
== INADDR_ANY
)
3077 strncpy(bsr_str
, "0.0.0.0", sizeof(bsr_str
));
3080 pim_inet4_dump("<bsr?>", pim
->global_scope
.current_bsr
, bsr_str
,
3084 json
= json_object_new_object();
3085 json_object_string_add(json
, "BSR Address", bsr_str
);
3087 vty_out(vty
, "BSR Address %s\n", bsr_str
);
3090 for (rn
= route_top(pim
->global_scope
.bsrp_table
); rn
;
3091 rn
= route_next(rn
)) {
3092 bsgrp
= (struct bsgrp_node
*)rn
->info
;
3097 char grp_str
[INET_ADDRSTRLEN
];
3099 prefix2str(&bsgrp
->group
, grp_str
, sizeof(grp_str
));
3102 json_object_object_get_ex(json
, grp_str
, &json_group
);
3104 json_group
= json_object_new_object();
3105 json_object_object_add(json
, grp_str
,
3109 vty_out(vty
, "Group Address %s\n", grp_str
);
3110 vty_out(vty
, "--------------------------\n");
3111 vty_out(vty
, "%-15s %-15s %-15s %-15s\n", "Rp Address",
3112 "priority", "Holdtime", "Hash");
3114 vty_out(vty
, "(ACTIVE)\n");
3117 if (bsgrp
->bsrp_list
) {
3118 for (ALL_LIST_ELEMENTS_RO(bsgrp
->bsrp_list
, rpnode
,
3120 char rp_str
[INET_ADDRSTRLEN
];
3122 pim_inet4_dump("<Rp Address?>",
3123 bsm_rp
->rp_address
, rp_str
,
3127 json_row
= json_object_new_object();
3128 json_object_string_add(
3129 json_row
, "Rp Address", rp_str
);
3130 json_object_int_add(
3131 json_row
, "Rp HoldTime",
3132 bsm_rp
->rp_holdtime
);
3133 json_object_int_add(json_row
,
3136 json_object_int_add(json_row
,
3139 json_object_object_add(
3140 json_group
, rp_str
, json_row
);
3144 "%-15s %-15u %-15u %-15u\n",
3145 rp_str
, bsm_rp
->rp_prio
,
3146 bsm_rp
->rp_holdtime
,
3150 if (!bsgrp
->bsrp_list
->count
&& !uj
)
3151 vty_out(vty
, "Active List is empty.\n");
3155 json_object_int_add(json_group
, "Pending RP count",
3156 bsgrp
->pend_rp_cnt
);
3158 vty_out(vty
, "(PENDING)\n");
3159 vty_out(vty
, "Pending RP count :%d\n",
3160 bsgrp
->pend_rp_cnt
);
3161 if (bsgrp
->pend_rp_cnt
)
3162 vty_out(vty
, "%-15s %-15s %-15s %-15s\n",
3163 "Rp Address", "priority", "Holdtime",
3167 if (bsgrp
->partial_bsrp_list
) {
3168 for (ALL_LIST_ELEMENTS_RO(bsgrp
->partial_bsrp_list
,
3170 char rp_str
[INET_ADDRSTRLEN
];
3172 pim_inet4_dump("<Rp Addr?>", bsm_rp
->rp_address
,
3173 rp_str
, sizeof(rp_str
));
3176 json_row
= json_object_new_object();
3177 json_object_string_add(
3178 json_row
, "Rp Address", rp_str
);
3179 json_object_int_add(
3180 json_row
, "Rp HoldTime",
3181 bsm_rp
->rp_holdtime
);
3182 json_object_int_add(json_row
,
3185 json_object_int_add(json_row
,
3188 json_object_object_add(
3189 json_group
, rp_str
, json_row
);
3192 "%-15s %-15u %-15u %-15u\n",
3193 rp_str
, bsm_rp
->rp_prio
,
3194 bsm_rp
->rp_holdtime
,
3198 if (!bsgrp
->partial_bsrp_list
->count
&& !uj
)
3199 vty_out(vty
, "Partial List is empty\n");
3207 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3208 json
, JSON_C_TO_STRING_PRETTY
));
3209 json_object_free(json
);
3213 /* pim statistics - just adding only bsm related now.
3214 * We can continue to add all pim related stats here.
3216 static void pim_show_statistics(struct pim_instance
*pim
, struct vty
*vty
,
3217 const char *ifname
, bool uj
)
3219 json_object
*json
= NULL
;
3220 struct interface
*ifp
;
3223 json
= json_object_new_object();
3224 json_object_int_add(json
, "Number of Received BSMs",
3226 json_object_int_add(json
, "Number of Forwared BSMs",
3228 json_object_int_add(json
, "Number of Dropped BSMs",
3231 vty_out(vty
, "BSM Statistics :\n");
3232 vty_out(vty
, "----------------\n");
3233 vty_out(vty
, "Number of Received BSMs : %ld\n", pim
->bsm_rcvd
);
3234 vty_out(vty
, "Number of Forwared BSMs : %ld\n", pim
->bsm_sent
);
3235 vty_out(vty
, "Number of Dropped BSMs : %ld\n",
3241 /* scan interfaces */
3242 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3243 struct pim_interface
*pim_ifp
= ifp
->info
;
3245 if (ifname
&& strcmp(ifname
, ifp
->name
))
3252 vty_out(vty
, "Interface : %s\n", ifp
->name
);
3253 vty_out(vty
, "-------------------\n");
3255 "Number of BSMs dropped due to config miss : %u\n",
3256 pim_ifp
->pim_ifstat_bsm_cfg_miss
);
3257 vty_out(vty
, "Number of unicast BSMs dropped : %u\n",
3258 pim_ifp
->pim_ifstat_ucast_bsm_cfg_miss
);
3260 "Number of BSMs dropped due to invalid scope zone : %u\n",
3261 pim_ifp
->pim_ifstat_bsm_invalid_sz
);
3264 json_object
*json_row
= NULL
;
3266 json_row
= json_object_new_object();
3268 json_object_string_add(json_row
, "If Name", ifp
->name
);
3269 json_object_int_add(
3271 "Number of BSMs dropped due to config miss",
3272 pim_ifp
->pim_ifstat_bsm_cfg_miss
);
3273 json_object_int_add(
3274 json_row
, "Number of unicast BSMs dropped",
3275 pim_ifp
->pim_ifstat_ucast_bsm_cfg_miss
);
3276 json_object_int_add(json_row
,
3277 "Number of BSMs dropped due to invalid scope zone",
3278 pim_ifp
->pim_ifstat_bsm_invalid_sz
);
3279 json_object_object_add(json
, ifp
->name
, json_row
);
3285 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3286 json
, JSON_C_TO_STRING_PRETTY
));
3287 json_object_free(json
);
3291 static void clear_pim_statistics(struct pim_instance
*pim
)
3293 struct interface
*ifp
;
3297 pim
->bsm_dropped
= 0;
3299 /* scan interfaces */
3300 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3301 struct pim_interface
*pim_ifp
= ifp
->info
;
3306 pim_ifp
->pim_ifstat_bsm_cfg_miss
= 0;
3307 pim_ifp
->pim_ifstat_ucast_bsm_cfg_miss
= 0;
3308 pim_ifp
->pim_ifstat_bsm_invalid_sz
= 0;
3312 static void igmp_show_groups(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
3314 struct interface
*ifp
;
3316 json_object
*json
= NULL
;
3317 json_object
*json_iface
= NULL
;
3318 json_object
*json_row
= NULL
;
3320 now
= pim_time_monotonic_sec();
3323 json
= json_object_new_object();
3326 "Interface Address Group Mode Timer Srcs V Uptime \n");
3328 /* scan interfaces */
3329 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3330 struct pim_interface
*pim_ifp
= ifp
->info
;
3331 struct listnode
*sock_node
;
3332 struct igmp_sock
*igmp
;
3337 /* scan igmp sockets */
3338 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3340 char ifaddr_str
[INET_ADDRSTRLEN
];
3341 struct listnode
*grpnode
;
3342 struct igmp_group
*grp
;
3344 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3345 sizeof(ifaddr_str
));
3347 /* scan igmp groups */
3348 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3350 char group_str
[INET_ADDRSTRLEN
];
3354 pim_inet4_dump("<group?>", grp
->group_addr
,
3355 group_str
, sizeof(group_str
));
3356 pim_time_timer_to_hhmmss(hhmmss
, sizeof(hhmmss
),
3357 grp
->t_group_timer
);
3358 pim_time_uptime(uptime
, sizeof(uptime
),
3359 now
- grp
->group_creation
);
3362 json_object_object_get_ex(
3363 json
, ifp
->name
, &json_iface
);
3367 json_object_new_object();
3368 json_object_pim_ifp_add(
3370 json_object_object_add(
3375 json_row
= json_object_new_object();
3376 json_object_string_add(
3377 json_row
, "source", ifaddr_str
);
3378 json_object_string_add(
3379 json_row
, "group", group_str
);
3381 if (grp
->igmp_version
== 3)
3382 json_object_string_add(
3384 grp
->group_filtermode_isexcl
3388 json_object_string_add(json_row
,
3390 json_object_int_add(
3391 json_row
, "sourcesCount",
3392 grp
->group_source_list
3394 grp
->group_source_list
)
3396 json_object_int_add(json_row
, "version",
3398 json_object_string_add(
3399 json_row
, "uptime", uptime
);
3400 json_object_object_add(json_iface
,
3406 "%-16s %-15s %-15s %4s %8s %4d %d %8s\n",
3407 ifp
->name
, ifaddr_str
,
3409 grp
->igmp_version
== 3
3410 ? (grp
->group_filtermode_isexcl
3415 grp
->group_source_list
3417 grp
->group_source_list
)
3419 grp
->igmp_version
, uptime
);
3421 } /* scan igmp groups */
3422 } /* scan igmp sockets */
3423 } /* scan interfaces */
3426 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3427 json
, JSON_C_TO_STRING_PRETTY
));
3428 json_object_free(json
);
3432 static void igmp_show_group_retransmission(struct pim_instance
*pim
,
3435 struct interface
*ifp
;
3438 "Interface Address Group RetTimer Counter RetSrcs\n");
3440 /* scan interfaces */
3441 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3442 struct pim_interface
*pim_ifp
= ifp
->info
;
3443 struct listnode
*sock_node
;
3444 struct igmp_sock
*igmp
;
3449 /* scan igmp sockets */
3450 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3452 char ifaddr_str
[INET_ADDRSTRLEN
];
3453 struct listnode
*grpnode
;
3454 struct igmp_group
*grp
;
3456 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3457 sizeof(ifaddr_str
));
3459 /* scan igmp groups */
3460 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3462 char group_str
[INET_ADDRSTRLEN
];
3463 char grp_retr_mmss
[10];
3464 struct listnode
*src_node
;
3465 struct igmp_source
*src
;
3466 int grp_retr_sources
= 0;
3468 pim_inet4_dump("<group?>", grp
->group_addr
,
3469 group_str
, sizeof(group_str
));
3470 pim_time_timer_to_mmss(
3471 grp_retr_mmss
, sizeof(grp_retr_mmss
),
3472 grp
->t_group_query_retransmit_timer
);
3475 /* count group sources with retransmission state
3477 for (ALL_LIST_ELEMENTS_RO(
3478 grp
->group_source_list
, src_node
,
3480 if (src
->source_query_retransmit_count
3486 vty_out(vty
, "%-16s %-15s %-15s %-8s %7d %7d\n",
3487 ifp
->name
, ifaddr_str
, group_str
,
3489 grp
->group_specific_query_retransmit_count
,
3492 } /* scan igmp groups */
3493 } /* scan igmp sockets */
3494 } /* scan interfaces */
3497 static void igmp_show_sources(struct pim_instance
*pim
, struct vty
*vty
)
3499 struct interface
*ifp
;
3502 now
= pim_time_monotonic_sec();
3505 "Interface Address Group Source Timer Fwd Uptime \n");
3507 /* scan interfaces */
3508 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3509 struct pim_interface
*pim_ifp
= ifp
->info
;
3510 struct listnode
*sock_node
;
3511 struct igmp_sock
*igmp
;
3516 /* scan igmp sockets */
3517 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3519 char ifaddr_str
[INET_ADDRSTRLEN
];
3520 struct listnode
*grpnode
;
3521 struct igmp_group
*grp
;
3523 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3524 sizeof(ifaddr_str
));
3526 /* scan igmp groups */
3527 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3529 char group_str
[INET_ADDRSTRLEN
];
3530 struct listnode
*srcnode
;
3531 struct igmp_source
*src
;
3533 pim_inet4_dump("<group?>", grp
->group_addr
,
3534 group_str
, sizeof(group_str
));
3536 /* scan group sources */
3537 for (ALL_LIST_ELEMENTS_RO(
3538 grp
->group_source_list
, srcnode
,
3540 char source_str
[INET_ADDRSTRLEN
];
3545 "<source?>", src
->source_addr
,
3546 source_str
, sizeof(source_str
));
3548 pim_time_timer_to_mmss(
3550 src
->t_source_timer
);
3553 uptime
, sizeof(uptime
),
3554 now
- src
->source_creation
);
3557 "%-16s %-15s %-15s %-15s %5s %3s %8s\n",
3558 ifp
->name
, ifaddr_str
,
3559 group_str
, source_str
, mmss
,
3560 IGMP_SOURCE_TEST_FORWARDING(
3566 } /* scan group sources */
3567 } /* scan igmp groups */
3568 } /* scan igmp sockets */
3569 } /* scan interfaces */
3572 static void igmp_show_source_retransmission(struct pim_instance
*pim
,
3575 struct interface
*ifp
;
3578 "Interface Address Group Source Counter\n");
3580 /* scan interfaces */
3581 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3582 struct pim_interface
*pim_ifp
= ifp
->info
;
3583 struct listnode
*sock_node
;
3584 struct igmp_sock
*igmp
;
3589 /* scan igmp sockets */
3590 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3592 char ifaddr_str
[INET_ADDRSTRLEN
];
3593 struct listnode
*grpnode
;
3594 struct igmp_group
*grp
;
3596 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3597 sizeof(ifaddr_str
));
3599 /* scan igmp groups */
3600 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3602 char group_str
[INET_ADDRSTRLEN
];
3603 struct listnode
*srcnode
;
3604 struct igmp_source
*src
;
3606 pim_inet4_dump("<group?>", grp
->group_addr
,
3607 group_str
, sizeof(group_str
));
3609 /* scan group sources */
3610 for (ALL_LIST_ELEMENTS_RO(
3611 grp
->group_source_list
, srcnode
,
3613 char source_str
[INET_ADDRSTRLEN
];
3616 "<source?>", src
->source_addr
,
3617 source_str
, sizeof(source_str
));
3620 "%-16s %-15s %-15s %-15s %7d\n",
3621 ifp
->name
, ifaddr_str
,
3622 group_str
, source_str
,
3623 src
->source_query_retransmit_count
);
3625 } /* scan group sources */
3626 } /* scan igmp groups */
3627 } /* scan igmp sockets */
3628 } /* scan interfaces */
3631 static void pim_show_bsr(struct pim_instance
*pim
,
3636 char last_bsm_seen
[10];
3639 char bsr_str
[PREFIX_STRLEN
];
3640 json_object
*json
= NULL
;
3642 vty_out(vty
, "PIMv2 Bootstrap information\n");
3644 if (pim
->global_scope
.current_bsr
.s_addr
== INADDR_ANY
) {
3645 strncpy(bsr_str
, "0.0.0.0", sizeof(bsr_str
));
3646 pim_time_uptime(uptime
, sizeof(uptime
),
3647 pim
->global_scope
.current_bsr_first_ts
);
3648 pim_time_uptime(last_bsm_seen
, sizeof(last_bsm_seen
),
3649 pim
->global_scope
.current_bsr_last_ts
);
3653 pim_inet4_dump("<bsr?>", pim
->global_scope
.current_bsr
,
3654 bsr_str
, sizeof(bsr_str
));
3655 now
= pim_time_monotonic_sec();
3656 pim_time_uptime(uptime
, sizeof(uptime
),
3657 (now
- pim
->global_scope
.current_bsr_first_ts
));
3658 pim_time_uptime(last_bsm_seen
, sizeof(last_bsm_seen
),
3659 now
- pim
->global_scope
.current_bsr_last_ts
);
3662 switch (pim
->global_scope
.state
) {
3664 strncpy(bsr_state
, "NO_INFO", sizeof(bsr_state
));
3667 strncpy(bsr_state
, "ACCEPT_ANY", sizeof(bsr_state
));
3669 case ACCEPT_PREFERRED
:
3670 strncpy(bsr_state
, "ACCEPT_PREFERRED", sizeof(bsr_state
));
3673 strncpy(bsr_state
, "", sizeof(bsr_state
));
3677 json
= json_object_new_object();
3678 json_object_string_add(json
, "bsr", bsr_str
);
3679 json_object_int_add(json
, "priority",
3680 pim
->global_scope
.current_bsr_prio
);
3681 json_object_int_add(json
, "fragment_tag",
3682 pim
->global_scope
.bsm_frag_tag
);
3683 json_object_string_add(json
, "state", bsr_state
);
3684 json_object_string_add(json
, "upTime", uptime
);
3685 json_object_string_add(json
, "last_bsm_seen", last_bsm_seen
);
3689 vty_out(vty
, "Current preferred BSR address: %s\n", bsr_str
);
3691 "Priority Fragment-Tag State UpTime\n");
3692 vty_out(vty
, " %-12d %-12d %-13s %7s\n",
3693 pim
->global_scope
.current_bsr_prio
,
3694 pim
->global_scope
.bsm_frag_tag
,
3697 vty_out(vty
, "Last BSM seen: %s\n", last_bsm_seen
);
3701 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3702 json
, JSON_C_TO_STRING_PRETTY
));
3703 json_object_free(json
);
3707 static void clear_igmp_interfaces(struct pim_instance
*pim
)
3709 struct interface
*ifp
;
3711 FOR_ALL_INTERFACES (pim
->vrf
, ifp
)
3712 pim_if_addr_del_all_igmp(ifp
);
3714 FOR_ALL_INTERFACES (pim
->vrf
, ifp
)
3715 pim_if_addr_add_all(ifp
);
3718 static void clear_pim_interfaces(struct pim_instance
*pim
)
3720 struct interface
*ifp
;
3722 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3724 pim_neighbor_delete_all(ifp
, "interface cleared");
3729 static void clear_interfaces(struct pim_instance
*pim
)
3731 clear_igmp_interfaces(pim
);
3732 clear_pim_interfaces(pim
);
3735 #define PIM_GET_PIM_INTERFACE(pim_ifp, ifp) \
3736 pim_ifp = ifp->info; \
3739 "%% Enable PIM and/or IGMP on this interface first\n"); \
3740 return CMD_WARNING_CONFIG_FAILED; \
3743 DEFUN (clear_ip_interfaces
,
3744 clear_ip_interfaces_cmd
,
3745 "clear ip interfaces [vrf NAME]",
3748 "Reset interfaces\n"
3752 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3757 clear_interfaces(vrf
->info
);
3762 DEFUN (clear_ip_igmp_interfaces
,
3763 clear_ip_igmp_interfaces_cmd
,
3764 "clear ip igmp [vrf NAME] interfaces",
3769 "Reset IGMP interfaces\n")
3772 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3777 clear_igmp_interfaces(vrf
->info
);
3782 DEFUN (clear_ip_pim_statistics
,
3783 clear_ip_pim_statistics_cmd
,
3784 "clear ip pim statistics [vrf NAME]",
3789 "Reset PIM statistics\n")
3792 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3797 clear_pim_statistics(vrf
->info
);
3801 static void mroute_add_all(struct pim_instance
*pim
)
3803 struct listnode
*node
;
3804 struct channel_oil
*c_oil
;
3806 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
3807 if (pim_mroute_add(c_oil
, __PRETTY_FUNCTION__
)) {
3808 /* just log warning */
3809 char source_str
[INET_ADDRSTRLEN
];
3810 char group_str
[INET_ADDRSTRLEN
];
3811 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
,
3812 source_str
, sizeof(source_str
));
3813 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
,
3814 group_str
, sizeof(group_str
));
3815 zlog_warn("%s %s: (S,G)=(%s,%s) failure writing MFC",
3816 __FILE__
, __PRETTY_FUNCTION__
, source_str
,
3822 static void mroute_del_all(struct pim_instance
*pim
)
3824 struct listnode
*node
;
3825 struct channel_oil
*c_oil
;
3827 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
3828 if (pim_mroute_del(c_oil
, __PRETTY_FUNCTION__
)) {
3829 /* just log warning */
3830 char source_str
[INET_ADDRSTRLEN
];
3831 char group_str
[INET_ADDRSTRLEN
];
3832 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
,
3833 source_str
, sizeof(source_str
));
3834 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
,
3835 group_str
, sizeof(group_str
));
3836 zlog_warn("%s %s: (S,G)=(%s,%s) failure clearing MFC",
3837 __FILE__
, __PRETTY_FUNCTION__
, source_str
,
3843 DEFUN (clear_ip_mroute
,
3844 clear_ip_mroute_cmd
,
3845 "clear ip mroute [vrf NAME]",
3848 "Reset multicast routes\n"
3852 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3857 mroute_del_all(vrf
->info
);
3858 mroute_add_all(vrf
->info
);
3863 DEFUN (clear_ip_pim_interfaces
,
3864 clear_ip_pim_interfaces_cmd
,
3865 "clear ip pim [vrf NAME] interfaces",
3870 "Reset PIM interfaces\n")
3873 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3878 clear_pim_interfaces(vrf
->info
);
3883 DEFUN (clear_ip_pim_interface_traffic
,
3884 clear_ip_pim_interface_traffic_cmd
,
3885 "clear ip pim [vrf NAME] interface traffic",
3888 "PIM clear commands\n"
3890 "Reset PIM interfaces\n"
3891 "Reset Protocol Packet counters\n")
3894 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3895 struct interface
*ifp
= NULL
;
3896 struct pim_interface
*pim_ifp
= NULL
;
3901 FOR_ALL_INTERFACES (vrf
, ifp
) {
3902 pim_ifp
= ifp
->info
;
3907 pim_ifp
->pim_ifstat_hello_recv
= 0;
3908 pim_ifp
->pim_ifstat_hello_sent
= 0;
3909 pim_ifp
->pim_ifstat_join_recv
= 0;
3910 pim_ifp
->pim_ifstat_join_send
= 0;
3911 pim_ifp
->pim_ifstat_prune_recv
= 0;
3912 pim_ifp
->pim_ifstat_prune_send
= 0;
3913 pim_ifp
->pim_ifstat_reg_recv
= 0;
3914 pim_ifp
->pim_ifstat_reg_send
= 0;
3915 pim_ifp
->pim_ifstat_reg_stop_recv
= 0;
3916 pim_ifp
->pim_ifstat_reg_stop_send
= 0;
3917 pim_ifp
->pim_ifstat_assert_recv
= 0;
3918 pim_ifp
->pim_ifstat_assert_send
= 0;
3919 pim_ifp
->pim_ifstat_bsm_rx
= 0;
3920 pim_ifp
->pim_ifstat_bsm_tx
= 0;
3926 DEFUN (clear_ip_pim_oil
,
3927 clear_ip_pim_oil_cmd
,
3928 "clear ip pim [vrf NAME] oil",
3933 "Rescan PIM OIL (output interface list)\n")
3936 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3941 pim_scan_oil(vrf
->info
);
3946 DEFUN (show_ip_igmp_interface
,
3947 show_ip_igmp_interface_cmd
,
3948 "show ip igmp [vrf NAME] interface [detail|WORD] [json]",
3953 "IGMP interface information\n"
3959 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3960 bool uj
= use_json(argc
, argv
);
3965 if (argv_find(argv
, argc
, "detail", &idx
)
3966 || argv_find(argv
, argc
, "WORD", &idx
))
3967 igmp_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
3969 igmp_show_interfaces(vrf
->info
, vty
, uj
);
3974 DEFUN (show_ip_igmp_interface_vrf_all
,
3975 show_ip_igmp_interface_vrf_all_cmd
,
3976 "show ip igmp vrf all interface [detail|WORD] [json]",
3981 "IGMP interface information\n"
3987 bool uj
= use_json(argc
, argv
);
3993 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3997 vty_out(vty
, " \"%s\": ", vrf
->name
);
4000 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4001 if (argv_find(argv
, argc
, "detail", &idx
)
4002 || argv_find(argv
, argc
, "WORD", &idx
))
4003 igmp_show_interfaces_single(vrf
->info
, vty
,
4004 argv
[idx
]->arg
, uj
);
4006 igmp_show_interfaces(vrf
->info
, vty
, uj
);
4009 vty_out(vty
, "}\n");
4014 DEFUN (show_ip_igmp_join
,
4015 show_ip_igmp_join_cmd
,
4016 "show ip igmp [vrf NAME] join",
4021 "IGMP static join information\n")
4024 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4029 igmp_show_interface_join(vrf
->info
, vty
);
4034 DEFUN (show_ip_igmp_join_vrf_all
,
4035 show_ip_igmp_join_vrf_all_cmd
,
4036 "show ip igmp vrf all join",
4041 "IGMP static join information\n")
4043 bool uj
= use_json(argc
, argv
);
4049 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4053 vty_out(vty
, " \"%s\": ", vrf
->name
);
4056 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4057 igmp_show_interface_join(vrf
->info
, vty
);
4060 vty_out(vty
, "}\n");
4065 DEFUN (show_ip_igmp_groups
,
4066 show_ip_igmp_groups_cmd
,
4067 "show ip igmp [vrf NAME] groups [json]",
4076 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4077 bool uj
= use_json(argc
, argv
);
4082 igmp_show_groups(vrf
->info
, vty
, uj
);
4087 DEFUN (show_ip_igmp_groups_vrf_all
,
4088 show_ip_igmp_groups_vrf_all_cmd
,
4089 "show ip igmp vrf all groups [json]",
4097 bool uj
= use_json(argc
, argv
);
4103 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4107 vty_out(vty
, " \"%s\": ", vrf
->name
);
4110 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4111 igmp_show_groups(vrf
->info
, vty
, uj
);
4114 vty_out(vty
, "}\n");
4119 DEFUN (show_ip_igmp_groups_retransmissions
,
4120 show_ip_igmp_groups_retransmissions_cmd
,
4121 "show ip igmp [vrf NAME] groups retransmissions",
4127 "IGMP group retransmissions\n")
4130 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4135 igmp_show_group_retransmission(vrf
->info
, vty
);
4140 DEFUN (show_ip_igmp_sources
,
4141 show_ip_igmp_sources_cmd
,
4142 "show ip igmp [vrf NAME] sources",
4150 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4155 igmp_show_sources(vrf
->info
, vty
);
4160 DEFUN (show_ip_igmp_sources_retransmissions
,
4161 show_ip_igmp_sources_retransmissions_cmd
,
4162 "show ip igmp [vrf NAME] sources retransmissions",
4168 "IGMP source retransmissions\n")
4171 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4176 igmp_show_source_retransmission(vrf
->info
, vty
);
4181 DEFUN (show_ip_igmp_statistics
,
4182 show_ip_igmp_statistics_cmd
,
4183 "show ip igmp [vrf NAME] statistics [interface WORD] [json]",
4194 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4195 bool uj
= use_json(argc
, argv
);
4200 if (argv_find(argv
, argc
, "WORD", &idx
))
4201 igmp_show_statistics(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
4203 igmp_show_statistics(vrf
->info
, vty
, NULL
, uj
);
4208 DEFUN (show_ip_pim_assert
,
4209 show_ip_pim_assert_cmd
,
4210 "show ip pim [vrf NAME] assert",
4215 "PIM interface assert\n")
4218 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4223 pim_show_assert(vrf
->info
, vty
);
4228 DEFUN (show_ip_pim_assert_internal
,
4229 show_ip_pim_assert_internal_cmd
,
4230 "show ip pim [vrf NAME] assert-internal",
4235 "PIM interface internal assert state\n")
4238 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4243 pim_show_assert_internal(vrf
->info
, vty
);
4248 DEFUN (show_ip_pim_assert_metric
,
4249 show_ip_pim_assert_metric_cmd
,
4250 "show ip pim [vrf NAME] assert-metric",
4255 "PIM interface assert metric\n")
4258 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4263 pim_show_assert_metric(vrf
->info
, vty
);
4268 DEFUN (show_ip_pim_assert_winner_metric
,
4269 show_ip_pim_assert_winner_metric_cmd
,
4270 "show ip pim [vrf NAME] assert-winner-metric",
4275 "PIM interface assert winner metric\n")
4278 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4283 pim_show_assert_winner_metric(vrf
->info
, vty
);
4288 DEFUN (show_ip_pim_interface
,
4289 show_ip_pim_interface_cmd
,
4290 "show ip pim [vrf NAME] interface [detail|WORD] [json]",
4295 "PIM interface information\n"
4301 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4302 bool uj
= use_json(argc
, argv
);
4307 if (argv_find(argv
, argc
, "WORD", &idx
)
4308 || argv_find(argv
, argc
, "detail", &idx
))
4309 pim_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
4311 pim_show_interfaces(vrf
->info
, vty
, uj
);
4316 DEFUN (show_ip_pim_interface_vrf_all
,
4317 show_ip_pim_interface_vrf_all_cmd
,
4318 "show ip pim vrf all interface [detail|WORD] [json]",
4323 "PIM interface information\n"
4329 bool uj
= use_json(argc
, argv
);
4335 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4339 vty_out(vty
, " \"%s\": ", vrf
->name
);
4342 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4343 if (argv_find(argv
, argc
, "WORD", &idx
)
4344 || argv_find(argv
, argc
, "detail", &idx
))
4345 pim_show_interfaces_single(vrf
->info
, vty
,
4346 argv
[idx
]->arg
, uj
);
4348 pim_show_interfaces(vrf
->info
, vty
, uj
);
4351 vty_out(vty
, "}\n");
4356 DEFPY (show_ip_pim_join
,
4357 show_ip_pim_join_cmd
,
4358 "show ip pim [vrf NAME] join [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
4363 "PIM interface join information\n"
4364 "The Source or Group\n"
4368 struct prefix_sg sg
= {0};
4371 struct pim_instance
*pim
;
4373 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
4376 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
4379 pim
= pim_get_pim_instance(v
->vrf_id
);
4382 vty_out(vty
, "%% Unable to find pim instance\n");
4386 if (s_or_g
.s_addr
!= 0) {
4387 if (g
.s_addr
!= 0) {
4394 pim_show_join(pim
, vty
, &sg
, uj
);
4399 DEFUN (show_ip_pim_join_vrf_all
,
4400 show_ip_pim_join_vrf_all_cmd
,
4401 "show ip pim vrf all join [json]",
4406 "PIM interface join information\n"
4409 struct prefix_sg sg
= {0};
4410 bool uj
= use_json(argc
, argv
);
4416 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4420 vty_out(vty
, " \"%s\": ", vrf
->name
);
4423 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4424 pim_show_join(vrf
->info
, vty
, &sg
, uj
);
4427 vty_out(vty
, "}\n");
4432 DEFUN (show_ip_pim_local_membership
,
4433 show_ip_pim_local_membership_cmd
,
4434 "show ip pim [vrf NAME] local-membership [json]",
4439 "PIM interface local-membership\n"
4443 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4444 bool uj
= use_json(argc
, argv
);
4449 pim_show_membership(vrf
->info
, vty
, uj
);
4454 DEFUN (show_ip_pim_neighbor
,
4455 show_ip_pim_neighbor_cmd
,
4456 "show ip pim [vrf NAME] neighbor [detail|WORD] [json]",
4461 "PIM neighbor information\n"
4463 "Name of interface or neighbor\n"
4467 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4468 bool uj
= use_json(argc
, argv
);
4473 if (argv_find(argv
, argc
, "detail", &idx
)
4474 || argv_find(argv
, argc
, "WORD", &idx
))
4475 pim_show_neighbors_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
4477 pim_show_neighbors(vrf
->info
, vty
, uj
);
4482 DEFUN (show_ip_pim_neighbor_vrf_all
,
4483 show_ip_pim_neighbor_vrf_all_cmd
,
4484 "show ip pim vrf all neighbor [detail|WORD] [json]",
4489 "PIM neighbor information\n"
4491 "Name of interface or neighbor\n"
4495 bool uj
= use_json(argc
, argv
);
4501 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4505 vty_out(vty
, " \"%s\": ", vrf
->name
);
4508 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4509 if (argv_find(argv
, argc
, "detail", &idx
)
4510 || argv_find(argv
, argc
, "WORD", &idx
))
4511 pim_show_neighbors_single(vrf
->info
, vty
,
4512 argv
[idx
]->arg
, uj
);
4514 pim_show_neighbors(vrf
->info
, vty
, uj
);
4517 vty_out(vty
, "}\n");
4522 DEFUN (show_ip_pim_secondary
,
4523 show_ip_pim_secondary_cmd
,
4524 "show ip pim [vrf NAME] secondary",
4529 "PIM neighbor addresses\n")
4532 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4537 pim_show_neighbors_secondary(vrf
->info
, vty
);
4542 DEFUN (show_ip_pim_state
,
4543 show_ip_pim_state_cmd
,
4544 "show ip pim [vrf NAME] state [A.B.C.D [A.B.C.D]] [json]",
4549 "PIM state information\n"
4550 "Unicast or Multicast address\n"
4551 "Multicast address\n"
4554 const char *src_or_group
= NULL
;
4555 const char *group
= NULL
;
4557 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4558 bool uj
= use_json(argc
, argv
);
4566 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
4567 src_or_group
= argv
[idx
]->arg
;
4569 group
= argv
[idx
+ 1]->arg
;
4572 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
4577 DEFUN (show_ip_pim_state_vrf_all
,
4578 show_ip_pim_state_vrf_all_cmd
,
4579 "show ip pim vrf all state [A.B.C.D [A.B.C.D]] [json]",
4584 "PIM state information\n"
4585 "Unicast or Multicast address\n"
4586 "Multicast address\n"
4589 const char *src_or_group
= NULL
;
4590 const char *group
= NULL
;
4592 bool uj
= use_json(argc
, argv
);
4601 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
4602 src_or_group
= argv
[idx
]->arg
;
4604 group
= argv
[idx
+ 1]->arg
;
4607 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4611 vty_out(vty
, " \"%s\": ", vrf
->name
);
4614 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4615 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
4618 vty_out(vty
, "}\n");
4623 DEFPY (show_ip_pim_upstream
,
4624 show_ip_pim_upstream_cmd
,
4625 "show ip pim [vrf NAME] upstream [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
4630 "PIM upstream information\n"
4631 "The Source or Group\n"
4635 struct prefix_sg sg
= {0};
4638 struct pim_instance
*pim
;
4640 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
4643 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
4646 pim
= pim_get_pim_instance(v
->vrf_id
);
4649 vty_out(vty
, "%% Unable to find pim instance\n");
4653 if (s_or_g
.s_addr
!= 0) {
4654 if (g
.s_addr
!= 0) {
4660 pim_show_upstream(pim
, vty
, &sg
, uj
);
4665 DEFUN (show_ip_pim_upstream_vrf_all
,
4666 show_ip_pim_upstream_vrf_all_cmd
,
4667 "show ip pim vrf all upstream [json]",
4672 "PIM upstream information\n"
4675 struct prefix_sg sg
= {0};
4676 bool uj
= use_json(argc
, argv
);
4682 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4686 vty_out(vty
, " \"%s\": ", vrf
->name
);
4689 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4690 pim_show_upstream(vrf
->info
, vty
, &sg
, uj
);
4696 DEFUN (show_ip_pim_upstream_join_desired
,
4697 show_ip_pim_upstream_join_desired_cmd
,
4698 "show ip pim [vrf NAME] upstream-join-desired [json]",
4703 "PIM upstream join-desired\n"
4707 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4708 bool uj
= use_json(argc
, argv
);
4713 pim_show_join_desired(vrf
->info
, vty
, uj
);
4718 DEFUN (show_ip_pim_upstream_rpf
,
4719 show_ip_pim_upstream_rpf_cmd
,
4720 "show ip pim [vrf NAME] upstream-rpf [json]",
4725 "PIM upstream source rpf\n"
4729 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4730 bool uj
= use_json(argc
, argv
);
4735 pim_show_upstream_rpf(vrf
->info
, vty
, uj
);
4740 DEFUN (show_ip_pim_rp
,
4742 "show ip pim [vrf NAME] rp-info [json]",
4747 "PIM RP information\n"
4751 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4752 bool uj
= use_json(argc
, argv
);
4757 pim_rp_show_information(vrf
->info
, vty
, uj
);
4762 DEFUN (show_ip_pim_rp_vrf_all
,
4763 show_ip_pim_rp_vrf_all_cmd
,
4764 "show ip pim vrf all rp-info [json]",
4769 "PIM RP information\n"
4772 bool uj
= use_json(argc
, argv
);
4778 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4782 vty_out(vty
, " \"%s\": ", vrf
->name
);
4785 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4786 pim_rp_show_information(vrf
->info
, vty
, uj
);
4789 vty_out(vty
, "}\n");
4794 DEFUN (show_ip_pim_rpf
,
4795 show_ip_pim_rpf_cmd
,
4796 "show ip pim [vrf NAME] rpf [json]",
4801 "PIM cached source rpf information\n"
4805 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4806 bool uj
= use_json(argc
, argv
);
4811 pim_show_rpf(vrf
->info
, vty
, uj
);
4816 DEFUN (show_ip_pim_rpf_vrf_all
,
4817 show_ip_pim_rpf_vrf_all_cmd
,
4818 "show ip pim vrf all rpf [json]",
4823 "PIM cached source rpf information\n"
4826 bool uj
= use_json(argc
, argv
);
4832 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4836 vty_out(vty
, " \"%s\": ", vrf
->name
);
4839 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4840 pim_show_rpf(vrf
->info
, vty
, uj
);
4843 vty_out(vty
, "}\n");
4848 DEFUN (show_ip_pim_nexthop
,
4849 show_ip_pim_nexthop_cmd
,
4850 "show ip pim [vrf NAME] nexthop",
4855 "PIM cached nexthop rpf information\n")
4858 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4863 pim_show_nexthop(vrf
->info
, vty
);
4868 DEFUN (show_ip_pim_nexthop_lookup
,
4869 show_ip_pim_nexthop_lookup_cmd
,
4870 "show ip pim [vrf NAME] nexthop-lookup A.B.C.D A.B.C.D",
4875 "PIM cached nexthop rpf lookup\n"
4876 "Source/RP address\n"
4877 "Multicast Group address\n")
4879 struct prefix nht_p
;
4881 struct in_addr src_addr
, grp_addr
;
4882 struct in_addr vif_source
;
4883 const char *addr_str
, *addr_str1
;
4885 struct pim_nexthop nexthop
;
4886 char nexthop_addr_str
[PREFIX_STRLEN
];
4887 char grp_str
[PREFIX_STRLEN
];
4889 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4894 argv_find(argv
, argc
, "A.B.C.D", &idx
);
4895 addr_str
= argv
[idx
]->arg
;
4896 result
= inet_pton(AF_INET
, addr_str
, &src_addr
);
4898 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
4899 errno
, safe_strerror(errno
));
4903 if (pim_is_group_224_4(src_addr
)) {
4905 "Invalid argument. Expected Valid Source Address.\n");
4909 addr_str1
= argv
[idx
+ 1]->arg
;
4910 result
= inet_pton(AF_INET
, addr_str1
, &grp_addr
);
4912 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
4913 errno
, safe_strerror(errno
));
4917 if (!pim_is_group_224_4(grp_addr
)) {
4919 "Invalid argument. Expected Valid Multicast Group Address.\n");
4923 if (!pim_rp_set_upstream_addr(vrf
->info
, &vif_source
, src_addr
,
4927 nht_p
.family
= AF_INET
;
4928 nht_p
.prefixlen
= IPV4_MAX_BITLEN
;
4929 nht_p
.u
.prefix4
= vif_source
;
4930 grp
.family
= AF_INET
;
4931 grp
.prefixlen
= IPV4_MAX_BITLEN
;
4932 grp
.u
.prefix4
= grp_addr
;
4933 memset(&nexthop
, 0, sizeof(nexthop
));
4935 result
= pim_ecmp_nexthop_lookup(vrf
->info
, &nexthop
, &nht_p
, &grp
, 0);
4939 "Nexthop Lookup failed, no usable routes returned.\n");
4943 pim_addr_dump("<grp?>", &grp
, grp_str
, sizeof(grp_str
));
4944 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
4945 nexthop_addr_str
, sizeof(nexthop_addr_str
));
4946 vty_out(vty
, "Group %s --- Nexthop %s Interface %s \n", grp_str
,
4947 nexthop_addr_str
, nexthop
.interface
->name
);
4952 DEFUN (show_ip_pim_interface_traffic
,
4953 show_ip_pim_interface_traffic_cmd
,
4954 "show ip pim [vrf NAME] interface traffic [WORD] [json]",
4959 "PIM interface information\n"
4960 "Protocol Packet counters\n"
4965 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4966 bool uj
= use_json(argc
, argv
);
4971 if (argv_find(argv
, argc
, "WORD", &idx
))
4972 pim_show_interface_traffic_single(vrf
->info
, vty
,
4973 argv
[idx
]->arg
, uj
);
4975 pim_show_interface_traffic(vrf
->info
, vty
, uj
);
4980 DEFUN (show_ip_pim_bsm_db
,
4981 show_ip_pim_bsm_db_cmd
,
4982 "show ip pim bsm-database [vrf NAME] [json]",
4987 "PIM cached bsm packets information\n"
4991 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4992 bool uj
= use_json(argc
, argv
);
4997 pim_show_bsm_db(vrf
->info
, vty
, uj
);
5001 DEFUN (show_ip_pim_bsrp
,
5002 show_ip_pim_bsrp_cmd
,
5003 "show ip pim bsrp-info [vrf NAME] [json]",
5008 "PIM cached group-rp mappings information\n"
5012 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5013 bool uj
= use_json(argc
, argv
);
5018 pim_show_group_rp_mappings_info(vrf
->info
, vty
, uj
);
5023 DEFUN (show_ip_pim_statistics
,
5024 show_ip_pim_statistics_cmd
,
5025 "show ip pim [vrf NAME] statistics [interface WORD] [json]",
5036 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5037 bool uj
= use_json(argc
, argv
);
5042 if (argv_find(argv
, argc
, "WORD", &idx
))
5043 pim_show_statistics(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
5045 pim_show_statistics(vrf
->info
, vty
, NULL
, uj
);
5050 static void show_multicast_interfaces(struct pim_instance
*pim
, struct vty
*vty
)
5052 struct interface
*ifp
;
5057 "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut\n");
5059 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
5060 struct pim_interface
*pim_ifp
;
5061 struct in_addr ifaddr
;
5062 struct sioc_vif_req vreq
;
5064 pim_ifp
= ifp
->info
;
5069 memset(&vreq
, 0, sizeof(vreq
));
5070 vreq
.vifi
= pim_ifp
->mroute_vif_index
;
5072 if (ioctl(pim
->mroute_socket
, SIOCGETVIFCNT
, &vreq
)) {
5074 "ioctl(SIOCGETVIFCNT=%lu) failure for interface %s vif_index=%d: errno=%d: %s",
5075 (unsigned long)SIOCGETVIFCNT
, ifp
->name
,
5076 pim_ifp
->mroute_vif_index
, errno
,
5077 safe_strerror(errno
));
5080 ifaddr
= pim_ifp
->primary_address
;
5082 vty_out(vty
, "%-16s %-15s %3d %3d %7lu %7lu %10lu %10lu\n",
5083 ifp
->name
, inet_ntoa(ifaddr
), ifp
->ifindex
,
5084 pim_ifp
->mroute_vif_index
, (unsigned long)vreq
.icount
,
5085 (unsigned long)vreq
.ocount
, (unsigned long)vreq
.ibytes
,
5086 (unsigned long)vreq
.obytes
);
5090 static void pim_cmd_show_ip_multicast_helper(struct pim_instance
*pim
,
5093 struct vrf
*vrf
= pim
->vrf
;
5094 time_t now
= pim_time_monotonic_sec();
5100 vty_out(vty
, "Router MLAG Role: %s\n",
5101 mlag_role2str(router
->role
, mlag_role
, sizeof(mlag_role
)));
5102 vty_out(vty
, "Mroute socket descriptor:");
5104 vty_out(vty
, " %d(%s)\n", pim
->mroute_socket
, vrf
->name
);
5106 pim_time_uptime(uptime
, sizeof(uptime
),
5107 now
- pim
->mroute_socket_creation
);
5108 vty_out(vty
, "Mroute socket uptime: %s\n", uptime
);
5112 pim_zebra_zclient_update(vty
);
5113 pim_zlookup_show_ip_multicast(vty
);
5116 vty_out(vty
, "Maximum highest VifIndex: %d\n", PIM_MAX_USABLE_VIFS
);
5119 vty_out(vty
, "Upstream Join Timer: %d secs\n", router
->t_periodic
);
5120 vty_out(vty
, "Join/Prune Holdtime: %d secs\n", PIM_JP_HOLDTIME
);
5121 vty_out(vty
, "PIM ECMP: %s\n", pim
->ecmp_enable
? "Enable" : "Disable");
5122 vty_out(vty
, "PIM ECMP Rebalance: %s\n",
5123 pim
->ecmp_rebalance_enable
? "Enable" : "Disable");
5127 show_rpf_refresh_stats(vty
, pim
, now
, NULL
);
5131 show_scan_oil_stats(pim
, vty
, now
);
5133 show_multicast_interfaces(pim
, vty
);
5136 DEFUN (show_ip_multicast
,
5137 show_ip_multicast_cmd
,
5138 "show ip multicast [vrf NAME]",
5142 "Multicast global information\n")
5145 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5150 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
5155 DEFUN (show_ip_multicast_vrf_all
,
5156 show_ip_multicast_vrf_all_cmd
,
5157 "show ip multicast vrf all",
5161 "Multicast global information\n")
5163 bool uj
= use_json(argc
, argv
);
5169 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5173 vty_out(vty
, " \"%s\": ", vrf
->name
);
5176 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5177 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
5180 vty_out(vty
, "}\n");
5185 static void show_mroute(struct pim_instance
*pim
, struct vty
*vty
,
5186 struct prefix_sg
*sg
, bool fill
, bool uj
)
5188 struct listnode
*node
;
5189 struct channel_oil
*c_oil
;
5190 struct static_route
*s_route
;
5192 json_object
*json
= NULL
;
5193 json_object
*json_group
= NULL
;
5194 json_object
*json_source
= NULL
;
5195 json_object
*json_oil
= NULL
;
5196 json_object
*json_ifp_out
= NULL
;
5199 char grp_str
[INET_ADDRSTRLEN
];
5200 char src_str
[INET_ADDRSTRLEN
];
5201 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
5202 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
5204 struct interface
*ifp_in
;
5208 json
= json_object_new_object();
5211 "Source Group Proto Input Output TTL Uptime\n");
5214 now
= pim_time_monotonic_sec();
5216 /* print list of PIM and IGMP routes */
5217 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
5220 if (!c_oil
->installed
&& !uj
)
5223 if (sg
->grp
.s_addr
!= 0 &&
5224 sg
->grp
.s_addr
!= c_oil
->oil
.mfcc_mcastgrp
.s_addr
)
5226 if (sg
->src
.s_addr
!= 0 &&
5227 sg
->src
.s_addr
!= c_oil
->oil
.mfcc_origin
.s_addr
)
5230 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
5232 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
5234 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
5237 strlcpy(in_ifname
, ifp_in
->name
, sizeof(in_ifname
));
5239 strlcpy(in_ifname
, "<iif?>", sizeof(in_ifname
));
5243 /* Find the group, create it if it doesn't exist */
5244 json_object_object_get_ex(json
, grp_str
, &json_group
);
5247 json_group
= json_object_new_object();
5248 json_object_object_add(json
, grp_str
,
5252 /* Find the source nested under the group, create it if
5253 * it doesn't exist */
5254 json_object_object_get_ex(json_group
, src_str
,
5258 json_source
= json_object_new_object();
5259 json_object_object_add(json_group
, src_str
,
5263 /* Find the inbound interface nested under the source,
5264 * create it if it doesn't exist */
5265 json_object_int_add(json_source
, "installed",
5267 json_object_int_add(json_source
, "refCount",
5268 c_oil
->oil_ref_count
);
5269 json_object_int_add(json_source
, "oilSize",
5271 json_object_int_add(json_source
, "OilInheritedRescan",
5272 c_oil
->oil_inherited_rescan
);
5273 json_object_string_add(json_source
, "iif", in_ifname
);
5277 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
5279 struct interface
*ifp_out
;
5280 char mroute_uptime
[10];
5283 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
5287 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
5289 mroute_uptime
, sizeof(mroute_uptime
),
5290 now
- c_oil
->mroute_creation
);
5294 strlcpy(out_ifname
, ifp_out
->name
, sizeof(out_ifname
));
5296 strlcpy(out_ifname
, "<oif?>", sizeof(out_ifname
));
5299 json_ifp_out
= json_object_new_object();
5300 json_object_string_add(json_ifp_out
, "source",
5302 json_object_string_add(json_ifp_out
, "group",
5305 if (c_oil
->oif_flags
[oif_vif_index
]
5306 & PIM_OIF_FLAG_PROTO_PIM
)
5307 json_object_boolean_true_add(
5308 json_ifp_out
, "protocolPim");
5310 if (c_oil
->oif_flags
[oif_vif_index
]
5311 & PIM_OIF_FLAG_PROTO_IGMP
)
5312 json_object_boolean_true_add(
5313 json_ifp_out
, "protocolIgmp");
5315 if (c_oil
->oif_flags
[oif_vif_index
]
5316 & PIM_OIF_FLAG_PROTO_VXLAN
)
5317 json_object_boolean_true_add(
5318 json_ifp_out
, "protocolVxlan");
5320 if (c_oil
->oif_flags
[oif_vif_index
]
5321 & PIM_OIF_FLAG_PROTO_SOURCE
)
5322 json_object_boolean_true_add(
5323 json_ifp_out
, "protocolSource");
5325 if (c_oil
->oif_flags
[oif_vif_index
]
5326 & PIM_OIF_FLAG_PROTO_STAR
)
5327 json_object_boolean_true_add(
5329 "protocolInherited");
5331 json_object_string_add(json_ifp_out
,
5334 json_object_int_add(json_ifp_out
, "iVifI",
5335 c_oil
->oil
.mfcc_parent
);
5336 json_object_string_add(json_ifp_out
,
5337 "outboundInterface",
5339 json_object_int_add(json_ifp_out
, "oVifI",
5341 json_object_int_add(json_ifp_out
, "ttl", ttl
);
5342 json_object_string_add(json_ifp_out
, "upTime",
5345 json_oil
= json_object_new_object();
5346 json_object_object_add(json_source
,
5349 json_object_object_add(json_oil
, out_ifname
,
5352 if (c_oil
->oif_flags
[oif_vif_index
]
5353 & PIM_OIF_FLAG_PROTO_PIM
) {
5354 strlcpy(proto
, "PIM", sizeof(proto
));
5357 if (c_oil
->oif_flags
[oif_vif_index
]
5358 & PIM_OIF_FLAG_PROTO_IGMP
) {
5359 strlcpy(proto
, "IGMP", sizeof(proto
));
5362 if (c_oil
->oif_flags
[oif_vif_index
]
5363 & PIM_OIF_FLAG_PROTO_VXLAN
) {
5364 strlcpy(proto
, "VxLAN", sizeof(proto
));
5367 if (c_oil
->oif_flags
[oif_vif_index
]
5368 & PIM_OIF_FLAG_PROTO_SOURCE
) {
5369 strlcpy(proto
, "SRC", sizeof(proto
));
5372 if (c_oil
->oif_flags
[oif_vif_index
]
5373 & PIM_OIF_FLAG_PROTO_STAR
) {
5374 strlcpy(proto
, "STAR", sizeof(proto
));
5378 "%-15s %-15s %-6s %-16s %-16s %-3d %8s\n",
5379 src_str
, grp_str
, proto
, in_ifname
,
5380 out_ifname
, ttl
, mroute_uptime
);
5385 in_ifname
[0] = '\0';
5391 if (!uj
&& !found_oif
) {
5392 vty_out(vty
, "%-15s %-15s %-6s %-16s %-16s %-3d %8s\n",
5393 src_str
, grp_str
, "none", in_ifname
, "none", 0,
5398 /* Print list of static routes */
5399 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
5402 if (!s_route
->c_oil
.installed
)
5405 pim_inet4_dump("<group?>", s_route
->group
, grp_str
,
5407 pim_inet4_dump("<source?>", s_route
->source
, src_str
,
5409 ifp_in
= pim_if_find_by_vif_index(pim
, s_route
->iif
);
5413 strlcpy(in_ifname
, ifp_in
->name
, sizeof(in_ifname
));
5415 strlcpy(in_ifname
, "<iif?>", sizeof(in_ifname
));
5419 /* Find the group, create it if it doesn't exist */
5420 json_object_object_get_ex(json
, grp_str
, &json_group
);
5423 json_group
= json_object_new_object();
5424 json_object_object_add(json
, grp_str
,
5428 /* Find the source nested under the group, create it if
5429 * it doesn't exist */
5430 json_object_object_get_ex(json_group
, src_str
,
5434 json_source
= json_object_new_object();
5435 json_object_object_add(json_group
, src_str
,
5439 json_object_string_add(json_source
, "iif", in_ifname
);
5442 strlcpy(proto
, "STATIC", sizeof(proto
));
5445 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
5447 struct interface
*ifp_out
;
5448 char oif_uptime
[10];
5451 ttl
= s_route
->oif_ttls
[oif_vif_index
];
5455 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
5457 oif_uptime
, sizeof(oif_uptime
),
5460 .oif_creation
[oif_vif_index
]);
5464 strlcpy(out_ifname
, ifp_out
->name
, sizeof(out_ifname
));
5466 strlcpy(out_ifname
, "<oif?>", sizeof(out_ifname
));
5469 json_ifp_out
= json_object_new_object();
5470 json_object_string_add(json_ifp_out
, "source",
5472 json_object_string_add(json_ifp_out
, "group",
5474 json_object_boolean_true_add(json_ifp_out
,
5476 json_object_string_add(json_ifp_out
,
5479 json_object_int_add(
5480 json_ifp_out
, "iVifI",
5481 s_route
->c_oil
.oil
.mfcc_parent
);
5482 json_object_string_add(json_ifp_out
,
5483 "outboundInterface",
5485 json_object_int_add(json_ifp_out
, "oVifI",
5487 json_object_int_add(json_ifp_out
, "ttl", ttl
);
5488 json_object_string_add(json_ifp_out
, "upTime",
5491 json_oil
= json_object_new_object();
5492 json_object_object_add(json_source
,
5495 json_object_object_add(json_oil
, out_ifname
,
5499 "%-15s %-15s %-6s %-16s %-16s %-3d %8s %s\n",
5500 src_str
, grp_str
, proto
, in_ifname
,
5501 out_ifname
, ttl
, oif_uptime
,
5503 if (first
&& !fill
) {
5506 in_ifname
[0] = '\0';
5512 if (!uj
&& !found_oif
) {
5514 "%-15s %-15s %-6s %-16s %-16s %-3d %8s %s\n",
5515 src_str
, grp_str
, proto
, in_ifname
, "none", 0,
5516 "--:--:--", pim
->vrf
->name
);
5521 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5522 json
, JSON_C_TO_STRING_PRETTY
));
5523 json_object_free(json
);
5527 DEFPY (show_ip_mroute
,
5529 "show ip mroute [vrf NAME] [A.B.C.D$s_or_g [A.B.C.D$g]] [fill$fill] [json$json]",
5534 "The Source or Group\n"
5536 "Fill in Assumed data\n"
5539 struct prefix_sg sg
= {0};
5540 struct pim_instance
*pim
;
5543 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
5546 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
5549 pim
= pim_get_pim_instance(v
->vrf_id
);
5552 vty_out(vty
, "%% Unable to find pim instance\n");
5556 if (s_or_g
.s_addr
!= 0) {
5557 if (g
.s_addr
!= 0) {
5563 show_mroute(pim
, vty
, &sg
, !!fill
, !!json
);
5567 DEFUN (show_ip_mroute_vrf_all
,
5568 show_ip_mroute_vrf_all_cmd
,
5569 "show ip mroute vrf all [fill] [json]",
5574 "Fill in Assumed data\n"
5577 struct prefix_sg sg
= {0};
5578 bool uj
= use_json(argc
, argv
);
5584 if (argv_find(argv
, argc
, "fill", &idx
))
5589 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5593 vty_out(vty
, " \"%s\": ", vrf
->name
);
5596 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5597 show_mroute(vrf
->info
, vty
, &sg
, fill
, uj
);
5600 vty_out(vty
, "}\n");
5605 static void show_mroute_count(struct pim_instance
*pim
, struct vty
*vty
)
5607 struct listnode
*node
;
5608 struct channel_oil
*c_oil
;
5609 struct static_route
*s_route
;
5614 "Source Group LastUsed Packets Bytes WrongIf \n");
5616 /* Print PIM and IGMP route counts */
5617 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
5618 char group_str
[INET_ADDRSTRLEN
];
5619 char source_str
[INET_ADDRSTRLEN
];
5621 if (!c_oil
->installed
)
5624 pim_mroute_update_counters(c_oil
);
5626 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, group_str
,
5628 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, source_str
,
5629 sizeof(source_str
));
5631 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
5632 source_str
, group_str
, c_oil
->cc
.lastused
/ 100,
5633 c_oil
->cc
.pktcnt
, c_oil
->cc
.bytecnt
,
5634 c_oil
->cc
.wrong_if
);
5637 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
5638 char group_str
[INET_ADDRSTRLEN
];
5639 char source_str
[INET_ADDRSTRLEN
];
5641 if (!s_route
->c_oil
.installed
)
5644 pim_mroute_update_counters(&s_route
->c_oil
);
5646 pim_inet4_dump("<group?>", s_route
->c_oil
.oil
.mfcc_mcastgrp
,
5647 group_str
, sizeof(group_str
));
5648 pim_inet4_dump("<source?>", s_route
->c_oil
.oil
.mfcc_origin
,
5649 source_str
, sizeof(source_str
));
5651 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
5652 source_str
, group_str
, s_route
->c_oil
.cc
.lastused
,
5653 s_route
->c_oil
.cc
.pktcnt
, s_route
->c_oil
.cc
.bytecnt
,
5654 s_route
->c_oil
.cc
.wrong_if
);
5658 DEFUN (show_ip_mroute_count
,
5659 show_ip_mroute_count_cmd
,
5660 "show ip mroute [vrf NAME] count",
5665 "Route and packet count data\n")
5668 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5673 show_mroute_count(vrf
->info
, vty
);
5677 DEFUN (show_ip_mroute_count_vrf_all
,
5678 show_ip_mroute_count_vrf_all_cmd
,
5679 "show ip mroute vrf all count",
5684 "Route and packet count data\n")
5686 bool uj
= use_json(argc
, argv
);
5692 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5696 vty_out(vty
, " \"%s\": ", vrf
->name
);
5699 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5700 show_mroute_count(vrf
->info
, vty
);
5703 vty_out(vty
, "}\n");
5708 static void show_mroute_summary(struct pim_instance
*pim
, struct vty
*vty
)
5710 struct listnode
*node
;
5711 struct channel_oil
*c_oil
;
5712 struct static_route
*s_route
;
5713 uint32_t starg_sw_mroute_cnt
= 0;
5714 uint32_t sg_sw_mroute_cnt
= 0;
5715 uint32_t starg_hw_mroute_cnt
= 0;
5716 uint32_t sg_hw_mroute_cnt
= 0;
5718 vty_out(vty
, "Mroute Type Installed/Total\n");
5720 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
5721 if (!c_oil
->installed
) {
5722 if (c_oil
->oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
5723 starg_sw_mroute_cnt
++;
5727 if (c_oil
->oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
5728 starg_hw_mroute_cnt
++;
5734 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
5735 if (!s_route
->c_oil
.installed
) {
5736 if (s_route
->c_oil
.oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
5737 starg_sw_mroute_cnt
++;
5741 if (s_route
->c_oil
.oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
5742 starg_hw_mroute_cnt
++;
5748 vty_out(vty
, "%-20s %d/%d\n", "(*, G)", starg_hw_mroute_cnt
,
5749 starg_sw_mroute_cnt
+ starg_hw_mroute_cnt
);
5750 vty_out(vty
, "%-20s %d/%d\n", "(S, G)", sg_hw_mroute_cnt
,
5751 sg_sw_mroute_cnt
+ sg_hw_mroute_cnt
);
5752 vty_out(vty
, "------\n");
5753 vty_out(vty
, "%-20s %d/%d\n", "Total",
5754 (starg_hw_mroute_cnt
+ sg_hw_mroute_cnt
),
5755 (starg_sw_mroute_cnt
+
5756 starg_hw_mroute_cnt
+
5761 DEFUN (show_ip_mroute_summary
,
5762 show_ip_mroute_summary_cmd
,
5763 "show ip mroute [vrf NAME] summary",
5768 "Summary of all mroutes\n")
5771 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5776 show_mroute_summary(vrf
->info
, vty
);
5780 DEFUN (show_ip_mroute_summary_vrf_all
,
5781 show_ip_mroute_summary_vrf_all_cmd
,
5782 "show ip mroute vrf all summary",
5787 "Summary of all mroutes\n")
5791 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5792 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5793 show_mroute_summary(vrf
->info
, vty
);
5801 "show ip rib [vrf NAME] A.B.C.D",
5806 "Unicast address\n")
5809 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5810 struct in_addr addr
;
5811 const char *addr_str
;
5812 struct pim_nexthop nexthop
;
5813 char nexthop_addr_str
[PREFIX_STRLEN
];
5819 memset(&nexthop
, 0, sizeof(nexthop
));
5820 argv_find(argv
, argc
, "A.B.C.D", &idx
);
5821 addr_str
= argv
[idx
]->arg
;
5822 result
= inet_pton(AF_INET
, addr_str
, &addr
);
5824 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
5825 errno
, safe_strerror(errno
));
5829 if (!pim_nexthop_lookup(vrf
->info
, &nexthop
, addr
, 0)) {
5831 "Failure querying RIB nexthop for unicast address %s\n",
5837 "Address NextHop Interface Metric Preference\n");
5839 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
5840 nexthop_addr_str
, sizeof(nexthop_addr_str
));
5842 vty_out(vty
, "%-15s %-15s %-9s %6d %10d\n", addr_str
, nexthop_addr_str
,
5843 nexthop
.interface
? nexthop
.interface
->name
: "<ifname?>",
5844 nexthop
.mrib_route_metric
, nexthop
.mrib_metric_preference
);
5849 static void show_ssmpingd(struct pim_instance
*pim
, struct vty
*vty
)
5851 struct listnode
*node
;
5852 struct ssmpingd_sock
*ss
;
5856 "Source Socket Address Port Uptime Requests\n");
5858 if (!pim
->ssmpingd_list
)
5861 now
= pim_time_monotonic_sec();
5863 for (ALL_LIST_ELEMENTS_RO(pim
->ssmpingd_list
, node
, ss
)) {
5864 char source_str
[INET_ADDRSTRLEN
];
5866 struct sockaddr_in bind_addr
;
5867 socklen_t len
= sizeof(bind_addr
);
5868 char bind_addr_str
[INET_ADDRSTRLEN
];
5870 pim_inet4_dump("<src?>", ss
->source_addr
, source_str
,
5871 sizeof(source_str
));
5873 if (pim_socket_getsockname(
5874 ss
->sock_fd
, (struct sockaddr
*)&bind_addr
, &len
)) {
5876 "%% Failure reading socket name for ssmpingd source %s on fd=%d\n",
5877 source_str
, ss
->sock_fd
);
5880 pim_inet4_dump("<addr?>", bind_addr
.sin_addr
, bind_addr_str
,
5881 sizeof(bind_addr_str
));
5882 pim_time_uptime(ss_uptime
, sizeof(ss_uptime
),
5883 now
- ss
->creation
);
5885 vty_out(vty
, "%-15s %6d %-15s %5d %8s %8lld\n", source_str
,
5886 ss
->sock_fd
, bind_addr_str
, ntohs(bind_addr
.sin_port
),
5887 ss_uptime
, (long long)ss
->requests
);
5891 DEFUN (show_ip_ssmpingd
,
5892 show_ip_ssmpingd_cmd
,
5893 "show ip ssmpingd [vrf NAME]",
5900 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5905 show_ssmpingd(vrf
->info
, vty
);
5909 static int pim_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
5910 const char *rp
, const char *group
,
5915 result
= pim_rp_new_config(pim
, rp
, group
, plist
);
5917 if (result
== PIM_GROUP_BAD_ADDR_MASK_COMBO
) {
5918 vty_out(vty
, "%% Inconsistent address and mask: %s\n",
5920 return CMD_WARNING_CONFIG_FAILED
;
5923 if (result
== PIM_GROUP_BAD_ADDRESS
) {
5924 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
5925 return CMD_WARNING_CONFIG_FAILED
;
5928 if (result
== PIM_RP_BAD_ADDRESS
) {
5929 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
5930 return CMD_WARNING_CONFIG_FAILED
;
5933 if (result
== PIM_RP_NO_PATH
) {
5934 vty_out(vty
, "%% No Path to RP address specified: %s\n", rp
);
5938 if (result
== PIM_GROUP_OVERLAP
) {
5940 "%% Group range specified cannot exact match another\n");
5941 return CMD_WARNING_CONFIG_FAILED
;
5944 if (result
== PIM_GROUP_PFXLIST_OVERLAP
) {
5946 "%% This group is already covered by a RP prefix-list\n");
5947 return CMD_WARNING_CONFIG_FAILED
;
5950 if (result
== PIM_RP_PFXLIST_IN_USE
) {
5952 "%% The same prefix-list cannot be applied to multiple RPs\n");
5953 return CMD_WARNING_CONFIG_FAILED
;
5956 if (result
== PIM_GROUP_BAD_ADDR_MASK_COMBO
) {
5957 vty_out(vty
, "%% Inconsistent address and mask: %s\n",
5959 return CMD_WARNING_CONFIG_FAILED
;
5965 static int pim_cmd_spt_switchover(struct pim_instance
*pim
,
5966 enum pim_spt_switchover spt
,
5969 pim
->spt
.switchover
= spt
;
5971 switch (pim
->spt
.switchover
) {
5972 case PIM_SPT_IMMEDIATE
:
5973 XFREE(MTYPE_PIM_SPT_PLIST_NAME
, pim
->spt
.plist
);
5975 pim_upstream_add_lhr_star_pimreg(pim
);
5977 case PIM_SPT_INFINITY
:
5978 pim_upstream_remove_lhr_star_pimreg(pim
, plist
);
5980 XFREE(MTYPE_PIM_SPT_PLIST_NAME
, pim
->spt
.plist
);
5984 XSTRDUP(MTYPE_PIM_SPT_PLIST_NAME
, plist
);
5991 DEFUN (ip_pim_spt_switchover_infinity
,
5992 ip_pim_spt_switchover_infinity_cmd
,
5993 "ip pim spt-switchover infinity-and-beyond",
5997 "Never switch to SPT Tree\n")
5999 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6000 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, NULL
);
6003 DEFUN (ip_pim_spt_switchover_infinity_plist
,
6004 ip_pim_spt_switchover_infinity_plist_cmd
,
6005 "ip pim spt-switchover infinity-and-beyond prefix-list WORD",
6009 "Never switch to SPT Tree\n"
6010 "Prefix-List to control which groups to switch\n"
6011 "Prefix-List name\n")
6013 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6014 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, argv
[5]->arg
);
6017 DEFUN (no_ip_pim_spt_switchover_infinity
,
6018 no_ip_pim_spt_switchover_infinity_cmd
,
6019 "no ip pim spt-switchover infinity-and-beyond",
6024 "Never switch to SPT Tree\n")
6026 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6027 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
6030 DEFUN (no_ip_pim_spt_switchover_infinity_plist
,
6031 no_ip_pim_spt_switchover_infinity_plist_cmd
,
6032 "no ip pim spt-switchover infinity-and-beyond prefix-list WORD",
6037 "Never switch to SPT Tree\n"
6038 "Prefix-List to control which groups to switch\n"
6039 "Prefix-List name\n")
6041 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6042 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
6045 DEFUN (ip_pim_joinprune_time
,
6046 ip_pim_joinprune_time_cmd
,
6047 "ip pim join-prune-interval (60-600)",
6049 "pim multicast routing\n"
6050 "Join Prune Send Interval\n"
6053 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6054 router
->t_periodic
= atoi(argv
[3]->arg
);
6058 DEFUN (no_ip_pim_joinprune_time
,
6059 no_ip_pim_joinprune_time_cmd
,
6060 "no ip pim join-prune-interval (60-600)",
6063 "pim multicast routing\n"
6064 "Join Prune Send Interval\n"
6067 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6068 router
->t_periodic
= PIM_DEFAULT_T_PERIODIC
;
6072 DEFUN (ip_pim_register_suppress
,
6073 ip_pim_register_suppress_cmd
,
6074 "ip pim register-suppress-time (5-60000)",
6076 "pim multicast routing\n"
6077 "Register Suppress Timer\n"
6080 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6081 router
->register_suppress_time
= atoi(argv
[3]->arg
);
6085 DEFUN (no_ip_pim_register_suppress
,
6086 no_ip_pim_register_suppress_cmd
,
6087 "no ip pim register-suppress-time (5-60000)",
6090 "pim multicast routing\n"
6091 "Register Suppress Timer\n"
6094 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6095 router
->register_suppress_time
= PIM_REGISTER_SUPPRESSION_TIME_DEFAULT
;
6099 DEFUN (ip_pim_rp_keep_alive
,
6100 ip_pim_rp_keep_alive_cmd
,
6101 "ip pim rp keep-alive-timer (31-60000)",
6103 "pim multicast routing\n"
6105 "Keep alive Timer\n"
6108 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6109 pim
->rp_keep_alive_time
= atoi(argv
[4]->arg
);
6113 DEFUN (no_ip_pim_rp_keep_alive
,
6114 no_ip_pim_rp_keep_alive_cmd
,
6115 "no ip pim rp keep-alive-timer (31-60000)",
6118 "pim multicast routing\n"
6120 "Keep alive Timer\n"
6123 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6124 pim
->rp_keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
6128 DEFUN (ip_pim_keep_alive
,
6129 ip_pim_keep_alive_cmd
,
6130 "ip pim keep-alive-timer (31-60000)",
6132 "pim multicast routing\n"
6133 "Keep alive Timer\n"
6136 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6137 pim
->keep_alive_time
= atoi(argv
[3]->arg
);
6141 DEFUN (no_ip_pim_keep_alive
,
6142 no_ip_pim_keep_alive_cmd
,
6143 "no ip pim keep-alive-timer (31-60000)",
6146 "pim multicast routing\n"
6147 "Keep alive Timer\n"
6150 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6151 pim
->keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
6155 DEFUN (ip_pim_packets
,
6157 "ip pim packets (1-100)",
6159 "pim multicast routing\n"
6160 "packets to process at one time per fd\n"
6161 "Number of packets\n")
6163 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6164 router
->packet_process
= atoi(argv
[3]->arg
);
6168 DEFUN (no_ip_pim_packets
,
6169 no_ip_pim_packets_cmd
,
6170 "no ip pim packets (1-100)",
6173 "pim multicast routing\n"
6174 "packets to process at one time per fd\n"
6175 "Number of packets\n")
6177 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6178 router
->packet_process
= PIM_DEFAULT_PACKET_PROCESS
;
6182 DEFUN (ip_pim_v6_secondary
,
6183 ip_pim_v6_secondary_cmd
,
6184 "ip pim send-v6-secondary",
6186 "pim multicast routing\n"
6187 "Send v6 secondary addresses\n")
6189 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6190 pim
->send_v6_secondary
= 1;
6195 DEFUN (no_ip_pim_v6_secondary
,
6196 no_ip_pim_v6_secondary_cmd
,
6197 "no ip pim send-v6-secondary",
6200 "pim multicast routing\n"
6201 "Send v6 secondary addresses\n")
6203 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6204 pim
->send_v6_secondary
= 0;
6211 "ip pim rp A.B.C.D [A.B.C.D/M]",
6213 "pim multicast routing\n"
6215 "ip address of RP\n"
6216 "Group Address range to cover\n")
6218 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6221 if (argc
== (idx_ipv4
+ 1))
6222 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
6225 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
6226 argv
[idx_ipv4
+ 1]->arg
, NULL
);
6229 DEFUN (ip_pim_rp_prefix_list
,
6230 ip_pim_rp_prefix_list_cmd
,
6231 "ip pim rp A.B.C.D prefix-list WORD",
6233 "pim multicast routing\n"
6235 "ip address of RP\n"
6236 "group prefix-list filter\n"
6237 "Name of a prefix-list\n")
6239 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6240 return pim_rp_cmd_worker(pim
, vty
, argv
[3]->arg
, NULL
, argv
[5]->arg
);
6243 static int pim_no_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
6244 const char *rp
, const char *group
,
6247 int result
= pim_rp_del_config(pim
, rp
, group
, plist
);
6249 if (result
== PIM_GROUP_BAD_ADDRESS
) {
6250 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
6251 return CMD_WARNING_CONFIG_FAILED
;
6254 if (result
== PIM_RP_BAD_ADDRESS
) {
6255 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
6256 return CMD_WARNING_CONFIG_FAILED
;
6259 if (result
== PIM_RP_NOT_FOUND
) {
6260 vty_out(vty
, "%% Unable to find specified RP\n");
6261 return CMD_WARNING_CONFIG_FAILED
;
6267 DEFUN (no_ip_pim_rp
,
6269 "no ip pim rp A.B.C.D [A.B.C.D/M]",
6272 "pim multicast routing\n"
6274 "ip address of RP\n"
6275 "Group Address range to cover\n")
6277 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6278 int idx_ipv4
= 4, idx_group
= 0;
6280 if (argv_find(argv
, argc
, "A.B.C.D/M", &idx_group
))
6281 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
6282 argv
[idx_group
]->arg
, NULL
);
6284 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
6288 DEFUN (no_ip_pim_rp_prefix_list
,
6289 no_ip_pim_rp_prefix_list_cmd
,
6290 "no ip pim rp A.B.C.D prefix-list WORD",
6293 "pim multicast routing\n"
6295 "ip address of RP\n"
6296 "group prefix-list filter\n"
6297 "Name of a prefix-list\n")
6299 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6300 return pim_no_rp_cmd_worker(pim
, vty
, argv
[4]->arg
, NULL
, argv
[6]->arg
);
6303 static int pim_ssm_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
6306 int result
= pim_ssm_range_set(pim
, pim
->vrf_id
, plist
);
6308 if (result
== PIM_SSM_ERR_NONE
)
6312 case PIM_SSM_ERR_NO_VRF
:
6313 vty_out(vty
, "%% VRF doesn't exist\n");
6315 case PIM_SSM_ERR_DUP
:
6316 vty_out(vty
, "%% duplicate config\n");
6319 vty_out(vty
, "%% ssm range config failed\n");
6322 return CMD_WARNING_CONFIG_FAILED
;
6325 DEFUN (ip_pim_ssm_prefix_list
,
6326 ip_pim_ssm_prefix_list_cmd
,
6327 "ip pim ssm prefix-list WORD",
6329 "pim multicast routing\n"
6330 "Source Specific Multicast\n"
6331 "group range prefix-list filter\n"
6332 "Name of a prefix-list\n")
6334 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6335 return pim_ssm_cmd_worker(pim
, vty
, argv
[4]->arg
);
6338 DEFUN (no_ip_pim_ssm_prefix_list
,
6339 no_ip_pim_ssm_prefix_list_cmd
,
6340 "no ip pim ssm prefix-list",
6343 "pim multicast routing\n"
6344 "Source Specific Multicast\n"
6345 "group range prefix-list filter\n")
6347 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6348 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
6351 DEFUN (no_ip_pim_ssm_prefix_list_name
,
6352 no_ip_pim_ssm_prefix_list_name_cmd
,
6353 "no ip pim ssm prefix-list WORD",
6356 "pim multicast routing\n"
6357 "Source Specific Multicast\n"
6358 "group range prefix-list filter\n"
6359 "Name of a prefix-list\n")
6361 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6362 struct pim_ssm
*ssm
= pim
->ssm_info
;
6364 if (ssm
->plist_name
&& !strcmp(ssm
->plist_name
, argv
[5]->arg
))
6365 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
6367 vty_out(vty
, "%% pim ssm prefix-list %s doesn't exist\n", argv
[5]->arg
);
6369 return CMD_WARNING_CONFIG_FAILED
;
6372 static void ip_pim_ssm_show_group_range(struct pim_instance
*pim
,
6373 struct vty
*vty
, bool uj
)
6375 struct pim_ssm
*ssm
= pim
->ssm_info
;
6376 const char *range_str
=
6377 ssm
->plist_name
? ssm
->plist_name
: PIM_SSM_STANDARD_RANGE
;
6381 json
= json_object_new_object();
6382 json_object_string_add(json
, "ssmGroups", range_str
);
6383 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
6384 json
, JSON_C_TO_STRING_PRETTY
));
6385 json_object_free(json
);
6387 vty_out(vty
, "SSM group range : %s\n", range_str
);
6390 DEFUN (show_ip_pim_ssm_range
,
6391 show_ip_pim_ssm_range_cmd
,
6392 "show ip pim [vrf NAME] group-type [json]",
6401 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6402 bool uj
= use_json(argc
, argv
);
6407 ip_pim_ssm_show_group_range(vrf
->info
, vty
, uj
);
6412 static void ip_pim_ssm_show_group_type(struct pim_instance
*pim
,
6413 struct vty
*vty
, bool uj
,
6416 struct in_addr group_addr
;
6417 const char *type_str
;
6420 result
= inet_pton(AF_INET
, group
, &group_addr
);
6422 type_str
= "invalid";
6424 if (pim_is_group_224_4(group_addr
))
6426 pim_is_grp_ssm(pim
, group_addr
) ? "SSM" : "ASM";
6428 type_str
= "not-multicast";
6433 json
= json_object_new_object();
6434 json_object_string_add(json
, "groupType", type_str
);
6435 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
6436 json
, JSON_C_TO_STRING_PRETTY
));
6437 json_object_free(json
);
6439 vty_out(vty
, "Group type : %s\n", type_str
);
6442 DEFUN (show_ip_pim_group_type
,
6443 show_ip_pim_group_type_cmd
,
6444 "show ip pim [vrf NAME] group-type A.B.C.D [json]",
6449 "multicast group type\n"
6454 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6455 bool uj
= use_json(argc
, argv
);
6460 argv_find(argv
, argc
, "A.B.C.D", &idx
);
6461 ip_pim_ssm_show_group_type(vrf
->info
, vty
, uj
, argv
[idx
]->arg
);
6466 DEFUN (show_ip_pim_bsr
,
6467 show_ip_pim_bsr_cmd
,
6468 "show ip pim bsr [json]",
6472 "boot-strap router information\n"
6476 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6477 bool uj
= use_json(argc
, argv
);
6482 pim_show_bsr(vrf
->info
, vty
, uj
);
6489 "ip ssmpingd [A.B.C.D]",
6494 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6497 struct in_addr source_addr
;
6498 const char *source_str
= (argc
== 3) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
6500 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
6502 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
6503 source_str
, errno
, safe_strerror(errno
));
6504 return CMD_WARNING_CONFIG_FAILED
;
6507 result
= pim_ssmpingd_start(pim
, source_addr
);
6509 vty_out(vty
, "%% Failure starting ssmpingd for source %s: %d\n",
6510 source_str
, result
);
6511 return CMD_WARNING_CONFIG_FAILED
;
6517 DEFUN (no_ip_ssmpingd
,
6519 "no ip ssmpingd [A.B.C.D]",
6525 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6528 struct in_addr source_addr
;
6529 const char *source_str
= (argc
== 4) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
6531 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
6533 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
6534 source_str
, errno
, safe_strerror(errno
));
6535 return CMD_WARNING_CONFIG_FAILED
;
6538 result
= pim_ssmpingd_stop(pim
, source_addr
);
6540 vty_out(vty
, "%% Failure stopping ssmpingd for source %s: %d\n",
6541 source_str
, result
);
6542 return CMD_WARNING_CONFIG_FAILED
;
6552 "pim multicast routing\n"
6553 "Enable PIM ECMP \n")
6555 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6556 pim
->ecmp_enable
= true;
6561 DEFUN (no_ip_pim_ecmp
,
6566 "pim multicast routing\n"
6567 "Disable PIM ECMP \n")
6569 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6570 pim
->ecmp_enable
= false;
6575 DEFUN (ip_pim_ecmp_rebalance
,
6576 ip_pim_ecmp_rebalance_cmd
,
6577 "ip pim ecmp rebalance",
6579 "pim multicast routing\n"
6580 "Enable PIM ECMP \n"
6581 "Enable PIM ECMP Rebalance\n")
6583 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6584 pim
->ecmp_enable
= true;
6585 pim
->ecmp_rebalance_enable
= true;
6590 DEFUN (no_ip_pim_ecmp_rebalance
,
6591 no_ip_pim_ecmp_rebalance_cmd
,
6592 "no ip pim ecmp rebalance",
6595 "pim multicast routing\n"
6596 "Disable PIM ECMP \n"
6597 "Disable PIM ECMP Rebalance\n")
6599 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6600 pim
->ecmp_rebalance_enable
= false;
6605 static int pim_cmd_igmp_start(struct vty
*vty
, struct interface
*ifp
)
6607 struct pim_interface
*pim_ifp
;
6608 uint8_t need_startup
= 0;
6610 pim_ifp
= ifp
->info
;
6613 pim_ifp
= pim_if_new(ifp
, true, false, false,
6614 false /*vxlan_term*/);
6616 vty_out(vty
, "Could not enable IGMP on interface %s\n",
6618 return CMD_WARNING_CONFIG_FAILED
;
6622 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
6623 PIM_IF_DO_IGMP(pim_ifp
->options
);
6628 /* 'ip igmp' executed multiple times, with need_startup
6629 avoid multiple if add all and membership refresh */
6631 pim_if_addr_add_all(ifp
);
6632 pim_if_membership_refresh(ifp
);
6638 DEFUN (interface_ip_igmp
,
6639 interface_ip_igmp_cmd
,
6644 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6646 return pim_cmd_igmp_start(vty
, ifp
);
6649 DEFUN (interface_no_ip_igmp
,
6650 interface_no_ip_igmp_cmd
,
6656 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6657 struct pim_interface
*pim_ifp
= ifp
->info
;
6662 PIM_IF_DONT_IGMP(pim_ifp
->options
);
6664 pim_if_membership_clear(ifp
);
6666 pim_if_addr_del_all_igmp(ifp
);
6668 if (!PIM_IF_TEST_PIM(pim_ifp
->options
)) {
6675 DEFUN (interface_ip_igmp_join
,
6676 interface_ip_igmp_join_cmd
,
6677 "ip igmp join A.B.C.D A.B.C.D",
6680 "IGMP join multicast group\n"
6681 "Multicast group address\n"
6684 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6687 const char *group_str
;
6688 const char *source_str
;
6689 struct in_addr group_addr
;
6690 struct in_addr source_addr
;
6694 group_str
= argv
[idx_ipv4
]->arg
;
6695 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
6697 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
6698 errno
, safe_strerror(errno
));
6699 return CMD_WARNING_CONFIG_FAILED
;
6702 /* Source address */
6703 source_str
= argv
[idx_ipv4_2
]->arg
;
6704 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
6706 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
6707 source_str
, errno
, safe_strerror(errno
));
6708 return CMD_WARNING_CONFIG_FAILED
;
6711 CMD_FERR_RETURN(pim_if_igmp_join_add(ifp
, group_addr
, source_addr
),
6712 "Failure joining IGMP group: $ERR");
6717 DEFUN (interface_no_ip_igmp_join
,
6718 interface_no_ip_igmp_join_cmd
,
6719 "no ip igmp join A.B.C.D A.B.C.D",
6723 "IGMP join multicast group\n"
6724 "Multicast group address\n"
6727 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6730 const char *group_str
;
6731 const char *source_str
;
6732 struct in_addr group_addr
;
6733 struct in_addr source_addr
;
6737 group_str
= argv
[idx_ipv4
]->arg
;
6738 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
6740 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
6741 errno
, safe_strerror(errno
));
6742 return CMD_WARNING_CONFIG_FAILED
;
6745 /* Source address */
6746 source_str
= argv
[idx_ipv4_2
]->arg
;
6747 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
6749 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
6750 source_str
, errno
, safe_strerror(errno
));
6751 return CMD_WARNING_CONFIG_FAILED
;
6754 result
= pim_if_igmp_join_del(ifp
, group_addr
, source_addr
);
6757 "%% Failure leaving IGMP group %s source %s on interface %s: %d\n",
6758 group_str
, source_str
, ifp
->name
, result
);
6759 return CMD_WARNING_CONFIG_FAILED
;
6766 CLI reconfiguration affects the interface level (struct pim_interface).
6767 This function propagates the reconfiguration to every active socket
6770 static void igmp_sock_query_interval_reconfig(struct igmp_sock
*igmp
)
6772 struct interface
*ifp
;
6773 struct pim_interface
*pim_ifp
;
6777 /* other querier present? */
6779 if (igmp
->t_other_querier_timer
)
6782 /* this is the querier */
6784 zassert(igmp
->interface
);
6785 zassert(igmp
->interface
->info
);
6787 ifp
= igmp
->interface
;
6788 pim_ifp
= ifp
->info
;
6790 if (PIM_DEBUG_IGMP_TRACE
) {
6791 char ifaddr_str
[INET_ADDRSTRLEN
];
6792 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
6793 sizeof(ifaddr_str
));
6794 zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
6795 __PRETTY_FUNCTION__
, ifaddr_str
, ifp
->name
,
6796 pim_ifp
->igmp_default_query_interval
);
6800 igmp_startup_mode_on() will reset QQI:
6802 igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
6804 igmp_startup_mode_on(igmp
);
6807 static void igmp_sock_query_reschedule(struct igmp_sock
*igmp
)
6809 if (igmp
->t_igmp_query_timer
) {
6810 /* other querier present */
6811 zassert(igmp
->t_igmp_query_timer
);
6812 zassert(!igmp
->t_other_querier_timer
);
6814 pim_igmp_general_query_off(igmp
);
6815 pim_igmp_general_query_on(igmp
);
6817 zassert(igmp
->t_igmp_query_timer
);
6818 zassert(!igmp
->t_other_querier_timer
);
6820 /* this is the querier */
6822 zassert(!igmp
->t_igmp_query_timer
);
6823 zassert(igmp
->t_other_querier_timer
);
6825 pim_igmp_other_querier_timer_off(igmp
);
6826 pim_igmp_other_querier_timer_on(igmp
);
6828 zassert(!igmp
->t_igmp_query_timer
);
6829 zassert(igmp
->t_other_querier_timer
);
6833 static void change_query_interval(struct pim_interface
*pim_ifp
,
6836 struct listnode
*sock_node
;
6837 struct igmp_sock
*igmp
;
6839 pim_ifp
->igmp_default_query_interval
= query_interval
;
6841 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
6842 igmp_sock_query_interval_reconfig(igmp
);
6843 igmp_sock_query_reschedule(igmp
);
6847 static void change_query_max_response_time(struct pim_interface
*pim_ifp
,
6848 int query_max_response_time_dsec
)
6850 struct listnode
*sock_node
;
6851 struct igmp_sock
*igmp
;
6853 pim_ifp
->igmp_query_max_response_time_dsec
=
6854 query_max_response_time_dsec
;
6857 Below we modify socket/group/source timers in order to quickly
6858 reflect the change. Otherwise, those timers would eventually catch
6862 /* scan all sockets */
6863 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
6864 struct listnode
*grp_node
;
6865 struct igmp_group
*grp
;
6867 /* reschedule socket general query */
6868 igmp_sock_query_reschedule(igmp
);
6870 /* scan socket groups */
6871 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grp_node
,
6873 struct listnode
*src_node
;
6874 struct igmp_source
*src
;
6876 /* reset group timers for groups in EXCLUDE mode */
6877 if (grp
->group_filtermode_isexcl
) {
6878 igmp_group_reset_gmi(grp
);
6881 /* scan group sources */
6882 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
,
6885 /* reset source timers for sources with running
6887 if (src
->t_source_timer
) {
6888 igmp_source_reset_gmi(igmp
, grp
, src
);
6895 #define IGMP_QUERY_INTERVAL_MIN (1)
6896 #define IGMP_QUERY_INTERVAL_MAX (1800)
6898 DEFUN (interface_ip_igmp_query_interval
,
6899 interface_ip_igmp_query_interval_cmd
,
6900 "ip igmp query-interval (1-1800)",
6903 IFACE_IGMP_QUERY_INTERVAL_STR
6904 "Query interval in seconds\n")
6906 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6907 struct pim_interface
*pim_ifp
= ifp
->info
;
6909 int query_interval_dsec
;
6913 ret
= pim_cmd_igmp_start(vty
, ifp
);
6914 if (ret
!= CMD_SUCCESS
)
6916 pim_ifp
= ifp
->info
;
6919 query_interval
= atoi(argv
[3]->arg
);
6920 query_interval_dsec
= 10 * query_interval
;
6923 It seems we don't need to check bounds since command.c does it
6924 already, but we verify them anyway for extra safety.
6926 if (query_interval
< IGMP_QUERY_INTERVAL_MIN
) {
6928 "General query interval %d lower than minimum %d\n",
6929 query_interval
, IGMP_QUERY_INTERVAL_MIN
);
6930 return CMD_WARNING_CONFIG_FAILED
;
6932 if (query_interval
> IGMP_QUERY_INTERVAL_MAX
) {
6934 "General query interval %d higher than maximum %d\n",
6935 query_interval
, IGMP_QUERY_INTERVAL_MAX
);
6936 return CMD_WARNING_CONFIG_FAILED
;
6939 if (query_interval_dsec
<= pim_ifp
->igmp_query_max_response_time_dsec
) {
6941 "Can't set general query interval %d dsec <= query max response time %d dsec.\n",
6942 query_interval_dsec
,
6943 pim_ifp
->igmp_query_max_response_time_dsec
);
6944 return CMD_WARNING_CONFIG_FAILED
;
6947 change_query_interval(pim_ifp
, query_interval
);
6952 DEFUN (interface_no_ip_igmp_query_interval
,
6953 interface_no_ip_igmp_query_interval_cmd
,
6954 "no ip igmp query-interval",
6958 IFACE_IGMP_QUERY_INTERVAL_STR
)
6960 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6961 struct pim_interface
*pim_ifp
= ifp
->info
;
6962 int default_query_interval_dsec
;
6967 default_query_interval_dsec
= IGMP_GENERAL_QUERY_INTERVAL
* 10;
6969 if (default_query_interval_dsec
6970 <= pim_ifp
->igmp_query_max_response_time_dsec
) {
6972 "Can't set default general query interval %d dsec <= query max response time %d dsec.\n",
6973 default_query_interval_dsec
,
6974 pim_ifp
->igmp_query_max_response_time_dsec
);
6975 return CMD_WARNING_CONFIG_FAILED
;
6978 change_query_interval(pim_ifp
, IGMP_GENERAL_QUERY_INTERVAL
);
6983 DEFUN (interface_ip_igmp_version
,
6984 interface_ip_igmp_version_cmd
,
6985 "ip igmp version (2-3)",
6989 "IGMP version number\n")
6991 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6992 struct pim_interface
*pim_ifp
= ifp
->info
;
6993 int igmp_version
, old_version
= 0;
6997 ret
= pim_cmd_igmp_start(vty
, ifp
);
6998 if (ret
!= CMD_SUCCESS
)
7000 pim_ifp
= ifp
->info
;
7003 igmp_version
= atoi(argv
[3]->arg
);
7004 old_version
= pim_ifp
->igmp_version
;
7005 pim_ifp
->igmp_version
= igmp_version
;
7007 // Check if IGMP is Enabled otherwise, enable on interface
7008 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
7009 PIM_IF_DO_IGMP(pim_ifp
->options
);
7010 pim_if_addr_add_all(ifp
);
7011 pim_if_membership_refresh(ifp
);
7012 old_version
= igmp_version
;
7013 // avoid refreshing membership again.
7015 /* Current and new version is different refresh existing
7016 membership. Going from 3 -> 2 or 2 -> 3. */
7017 if (old_version
!= igmp_version
)
7018 pim_if_membership_refresh(ifp
);
7023 DEFUN (interface_no_ip_igmp_version
,
7024 interface_no_ip_igmp_version_cmd
,
7025 "no ip igmp version (2-3)",
7030 "IGMP version number\n")
7032 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7033 struct pim_interface
*pim_ifp
= ifp
->info
;
7038 pim_ifp
->igmp_version
= IGMP_DEFAULT_VERSION
;
7043 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
7044 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
7046 DEFUN (interface_ip_igmp_query_max_response_time
,
7047 interface_ip_igmp_query_max_response_time_cmd
,
7048 "ip igmp query-max-response-time (10-250)",
7051 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
7052 "Query response value in deci-seconds\n")
7054 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7055 struct pim_interface
*pim_ifp
= ifp
->info
;
7056 int query_max_response_time
;
7060 ret
= pim_cmd_igmp_start(vty
, ifp
);
7061 if (ret
!= CMD_SUCCESS
)
7063 pim_ifp
= ifp
->info
;
7066 query_max_response_time
= atoi(argv
[3]->arg
);
7068 if (query_max_response_time
7069 >= pim_ifp
->igmp_default_query_interval
* 10) {
7071 "Can't set query max response time %d sec >= general query interval %d sec\n",
7072 query_max_response_time
,
7073 pim_ifp
->igmp_default_query_interval
);
7074 return CMD_WARNING_CONFIG_FAILED
;
7077 change_query_max_response_time(pim_ifp
, query_max_response_time
);
7082 DEFUN (interface_no_ip_igmp_query_max_response_time
,
7083 interface_no_ip_igmp_query_max_response_time_cmd
,
7084 "no ip igmp query-max-response-time (10-250)",
7088 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
7089 "Time for response in deci-seconds\n")
7091 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7092 struct pim_interface
*pim_ifp
= ifp
->info
;
7097 change_query_max_response_time(pim_ifp
,
7098 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
7103 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
7104 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
7106 DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec
,
7107 interface_ip_igmp_query_max_response_time_dsec_cmd
,
7108 "ip igmp query-max-response-time-dsec (10-250)",
7111 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
7112 "Query response value in deciseconds\n")
7114 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7115 struct pim_interface
*pim_ifp
= ifp
->info
;
7116 int query_max_response_time_dsec
;
7117 int default_query_interval_dsec
;
7121 ret
= pim_cmd_igmp_start(vty
, ifp
);
7122 if (ret
!= CMD_SUCCESS
)
7124 pim_ifp
= ifp
->info
;
7127 query_max_response_time_dsec
= atoi(argv
[4]->arg
);
7129 default_query_interval_dsec
= 10 * pim_ifp
->igmp_default_query_interval
;
7131 if (query_max_response_time_dsec
>= default_query_interval_dsec
) {
7133 "Can't set query max response time %d dsec >= general query interval %d dsec\n",
7134 query_max_response_time_dsec
,
7135 default_query_interval_dsec
);
7136 return CMD_WARNING_CONFIG_FAILED
;
7139 change_query_max_response_time(pim_ifp
, query_max_response_time_dsec
);
7144 DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec
,
7145 interface_no_ip_igmp_query_max_response_time_dsec_cmd
,
7146 "no ip igmp query-max-response-time-dsec",
7150 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
)
7152 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7153 struct pim_interface
*pim_ifp
= ifp
->info
;
7158 change_query_max_response_time(pim_ifp
,
7159 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
7164 DEFUN (interface_ip_pim_drprio
,
7165 interface_ip_pim_drprio_cmd
,
7166 "ip pim drpriority (1-4294967295)",
7169 "Set the Designated Router Election Priority\n"
7170 "Value of the new DR Priority\n")
7172 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7174 struct pim_interface
*pim_ifp
= ifp
->info
;
7175 uint32_t old_dr_prio
;
7178 vty_out(vty
, "Please enable PIM on interface, first\n");
7179 return CMD_WARNING_CONFIG_FAILED
;
7182 old_dr_prio
= pim_ifp
->pim_dr_priority
;
7184 pim_ifp
->pim_dr_priority
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
7186 if (old_dr_prio
!= pim_ifp
->pim_dr_priority
) {
7187 pim_if_dr_election(ifp
);
7188 pim_hello_restart_now(ifp
);
7194 DEFUN (interface_no_ip_pim_drprio
,
7195 interface_no_ip_pim_drprio_cmd
,
7196 "no ip pim drpriority [(1-4294967295)]",
7200 "Revert the Designated Router Priority to default\n"
7201 "Old Value of the Priority\n")
7203 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7204 struct pim_interface
*pim_ifp
= ifp
->info
;
7207 vty_out(vty
, "Pim not enabled on this interface\n");
7208 return CMD_WARNING_CONFIG_FAILED
;
7211 if (pim_ifp
->pim_dr_priority
!= PIM_DEFAULT_DR_PRIORITY
) {
7212 pim_ifp
->pim_dr_priority
= PIM_DEFAULT_DR_PRIORITY
;
7213 pim_if_dr_election(ifp
);
7214 pim_hello_restart_now(ifp
);
7220 static int pim_cmd_interface_add(struct interface
*ifp
)
7222 struct pim_interface
*pim_ifp
= ifp
->info
;
7225 pim_ifp
= pim_if_new(ifp
, false, true, false,
7226 false /*vxlan_term*/);
7231 PIM_IF_DO_PIM(pim_ifp
->options
);
7234 pim_if_addr_add_all(ifp
);
7235 pim_if_membership_refresh(ifp
);
7239 DEFPY_HIDDEN (pim_test_sg_keepalive
,
7240 pim_test_sg_keepalive_cmd
,
7241 "test pim [vrf NAME$name] keepalive-reset A.B.C.D$source A.B.C.D$group",
7245 "Reset the Keepalive Timer\n"
7246 "The Source we are resetting\n"
7247 "The Group we are resetting\n")
7249 struct pim_upstream
*up
;
7250 struct pim_instance
*pim
;
7251 struct prefix_sg sg
;
7257 pim
= pim_get_pim_instance(VRF_DEFAULT
);
7259 struct vrf
*vrf
= vrf_lookup_by_name(name
);
7262 vty_out(vty
, "%% Vrf specified: %s does not exist\n",
7267 pim
= pim_get_pim_instance(vrf
->vrf_id
);
7271 vty_out(vty
, "%% Unable to find pim instance\n");
7275 up
= pim_upstream_find(pim
, &sg
);
7277 vty_out(vty
, "%% Unable to find %s specified\n",
7278 pim_str_sg_dump(&sg
));
7282 vty_out(vty
, "Setting %s to current keep alive time: %d\n",
7283 pim_str_sg_dump(&sg
), pim
->keep_alive_time
);
7284 pim_upstream_keep_alive_timer_start(up
, pim
->keep_alive_time
);
7289 DEFPY_HIDDEN (interface_ip_pim_activeactive
,
7290 interface_ip_pim_activeactive_cmd
,
7291 "[no$no] ip pim active-active",
7295 "Mark interface as Active-Active for MLAG operations, Hidden because not finished yet\n")
7297 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7298 struct pim_interface
*pim_ifp
;
7300 if (!no
&& !pim_cmd_interface_add(ifp
)) {
7301 vty_out(vty
, "Could not enable PIM SM active-active on interface\n");
7302 return CMD_WARNING_CONFIG_FAILED
;
7305 pim_ifp
= ifp
->info
;
7307 pim_ifp
->activeactive
= false;
7309 pim_ifp
->activeactive
= true;
7314 DEFUN_HIDDEN (interface_ip_pim_ssm
,
7315 interface_ip_pim_ssm_cmd
,
7321 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7323 if (!pim_cmd_interface_add(ifp
)) {
7324 vty_out(vty
, "Could not enable PIM SM on interface\n");
7325 return CMD_WARNING_CONFIG_FAILED
;
7329 "WARN: Enabled PIM SM on interface; configure PIM SSM "
7330 "range if needed\n");
7334 static int interface_ip_pim_helper(struct vty
*vty
)
7336 struct pim_interface
*pim_ifp
;
7338 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7340 if (!pim_cmd_interface_add(ifp
)) {
7341 vty_out(vty
, "Could not enable PIM SM on interface\n");
7342 return CMD_WARNING_CONFIG_FAILED
;
7345 pim_ifp
= ifp
->info
;
7347 pim_if_create_pimreg(pim_ifp
->pim
);
7352 DEFUN_HIDDEN (interface_ip_pim_sm
,
7353 interface_ip_pim_sm_cmd
,
7359 return interface_ip_pim_helper(vty
);
7362 DEFUN (interface_ip_pim
,
7363 interface_ip_pim_cmd
,
7368 return interface_ip_pim_helper(vty
);
7371 static int pim_cmd_interface_delete(struct interface
*ifp
)
7373 struct pim_interface
*pim_ifp
= ifp
->info
;
7378 PIM_IF_DONT_PIM(pim_ifp
->options
);
7380 pim_if_membership_clear(ifp
);
7383 pim_sock_delete() removes all neighbors from
7384 pim_ifp->pim_neighbor_list.
7386 pim_sock_delete(ifp
, "pim unconfigured on interface");
7388 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
7389 pim_if_addr_del_all(ifp
);
7396 static int interface_no_ip_pim_helper(struct vty
*vty
)
7398 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7399 if (!pim_cmd_interface_delete(ifp
)) {
7400 vty_out(vty
, "Unable to delete interface information\n");
7401 return CMD_WARNING_CONFIG_FAILED
;
7407 DEFUN_HIDDEN (interface_no_ip_pim_ssm
,
7408 interface_no_ip_pim_ssm_cmd
,
7415 return interface_no_ip_pim_helper(vty
);
7418 DEFUN_HIDDEN (interface_no_ip_pim_sm
,
7419 interface_no_ip_pim_sm_cmd
,
7426 return interface_no_ip_pim_helper(vty
);
7429 DEFUN (interface_no_ip_pim
,
7430 interface_no_ip_pim_cmd
,
7436 return interface_no_ip_pim_helper(vty
);
7440 DEFUN(interface_ip_pim_boundary_oil
,
7441 interface_ip_pim_boundary_oil_cmd
,
7442 "ip multicast boundary oil WORD",
7444 "Generic multicast configuration options\n"
7445 "Define multicast boundary\n"
7446 "Filter OIL by group using prefix list\n"
7447 "Prefix list to filter OIL with\n")
7449 VTY_DECLVAR_CONTEXT(interface
, iif
);
7450 struct pim_interface
*pim_ifp
;
7453 argv_find(argv
, argc
, "WORD", &idx
);
7455 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
7457 if (pim_ifp
->boundary_oil_plist
)
7458 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
7460 pim_ifp
->boundary_oil_plist
=
7461 XSTRDUP(MTYPE_PIM_INTERFACE
, argv
[idx
]->arg
);
7463 /* Interface will be pruned from OIL on next Join */
7467 DEFUN(interface_no_ip_pim_boundary_oil
,
7468 interface_no_ip_pim_boundary_oil_cmd
,
7469 "no ip multicast boundary oil [WORD]",
7472 "Generic multicast configuration options\n"
7473 "Define multicast boundary\n"
7474 "Filter OIL by group using prefix list\n"
7475 "Prefix list to filter OIL with\n")
7477 VTY_DECLVAR_CONTEXT(interface
, iif
);
7478 struct pim_interface
*pim_ifp
;
7481 argv_find(argv
, argc
, "WORD", &idx
);
7483 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
7485 if (pim_ifp
->boundary_oil_plist
)
7486 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
7491 DEFUN (interface_ip_mroute
,
7492 interface_ip_mroute_cmd
,
7493 "ip mroute INTERFACE A.B.C.D",
7495 "Add multicast route\n"
7496 "Outgoing interface name\n"
7499 VTY_DECLVAR_CONTEXT(interface
, iif
);
7500 struct pim_interface
*pim_ifp
;
7501 struct pim_instance
*pim
;
7502 int idx_interface
= 2;
7504 struct interface
*oif
;
7505 const char *oifname
;
7506 const char *grp_str
;
7507 struct in_addr grp_addr
;
7508 struct in_addr src_addr
;
7511 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
7514 oifname
= argv
[idx_interface
]->arg
;
7515 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
7517 vty_out(vty
, "No such interface name %s\n", oifname
);
7521 grp_str
= argv
[idx_ipv4
]->arg
;
7522 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
7524 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
7525 errno
, safe_strerror(errno
));
7529 src_addr
.s_addr
= INADDR_ANY
;
7531 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
7532 vty_out(vty
, "Failed to add route\n");
7539 DEFUN (interface_ip_mroute_source
,
7540 interface_ip_mroute_source_cmd
,
7541 "ip mroute INTERFACE A.B.C.D A.B.C.D",
7543 "Add multicast route\n"
7544 "Outgoing interface name\n"
7548 VTY_DECLVAR_CONTEXT(interface
, iif
);
7549 struct pim_interface
*pim_ifp
;
7550 struct pim_instance
*pim
;
7551 int idx_interface
= 2;
7554 struct interface
*oif
;
7555 const char *oifname
;
7556 const char *grp_str
;
7557 struct in_addr grp_addr
;
7558 const char *src_str
;
7559 struct in_addr src_addr
;
7562 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
7565 oifname
= argv
[idx_interface
]->arg
;
7566 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
7568 vty_out(vty
, "No such interface name %s\n", oifname
);
7572 grp_str
= argv
[idx_ipv4
]->arg
;
7573 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
7575 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
7576 errno
, safe_strerror(errno
));
7580 src_str
= argv
[idx_ipv4_2
]->arg
;
7581 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
7583 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
7584 errno
, safe_strerror(errno
));
7588 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
7589 vty_out(vty
, "Failed to add route\n");
7596 DEFUN (interface_no_ip_mroute
,
7597 interface_no_ip_mroute_cmd
,
7598 "no ip mroute INTERFACE A.B.C.D",
7601 "Add multicast route\n"
7602 "Outgoing interface name\n"
7605 VTY_DECLVAR_CONTEXT(interface
, iif
);
7606 struct pim_interface
*pim_ifp
;
7607 struct pim_instance
*pim
;
7608 int idx_interface
= 3;
7610 struct interface
*oif
;
7611 const char *oifname
;
7612 const char *grp_str
;
7613 struct in_addr grp_addr
;
7614 struct in_addr src_addr
;
7617 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
7620 oifname
= argv
[idx_interface
]->arg
;
7621 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
7623 vty_out(vty
, "No such interface name %s\n", oifname
);
7627 grp_str
= argv
[idx_ipv4
]->arg
;
7628 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
7630 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
7631 errno
, safe_strerror(errno
));
7635 src_addr
.s_addr
= INADDR_ANY
;
7637 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
7638 vty_out(vty
, "Failed to remove route\n");
7645 DEFUN (interface_no_ip_mroute_source
,
7646 interface_no_ip_mroute_source_cmd
,
7647 "no ip mroute INTERFACE A.B.C.D A.B.C.D",
7650 "Add multicast route\n"
7651 "Outgoing interface name\n"
7655 VTY_DECLVAR_CONTEXT(interface
, iif
);
7656 struct pim_interface
*pim_ifp
;
7657 struct pim_instance
*pim
;
7658 int idx_interface
= 3;
7661 struct interface
*oif
;
7662 const char *oifname
;
7663 const char *grp_str
;
7664 struct in_addr grp_addr
;
7665 const char *src_str
;
7666 struct in_addr src_addr
;
7669 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
7672 oifname
= argv
[idx_interface
]->arg
;
7673 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
7675 vty_out(vty
, "No such interface name %s\n", oifname
);
7679 grp_str
= argv
[idx_ipv4
]->arg
;
7680 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
7682 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
7683 errno
, safe_strerror(errno
));
7687 src_str
= argv
[idx_ipv4_2
]->arg
;
7688 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
7690 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
7691 errno
, safe_strerror(errno
));
7695 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
7696 vty_out(vty
, "Failed to remove route\n");
7703 DEFUN (interface_ip_pim_hello
,
7704 interface_ip_pim_hello_cmd
,
7705 "ip pim hello (1-180) [(1-180)]",
7709 IFACE_PIM_HELLO_TIME_STR
7710 IFACE_PIM_HELLO_HOLD_STR
)
7712 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7715 struct pim_interface
*pim_ifp
= ifp
->info
;
7718 if (!pim_cmd_interface_add(ifp
)) {
7719 vty_out(vty
, "Could not enable PIM SM on interface\n");
7720 return CMD_WARNING_CONFIG_FAILED
;
7724 pim_ifp
= ifp
->info
;
7725 pim_ifp
->pim_hello_period
= strtol(argv
[idx_time
]->arg
, NULL
, 10);
7727 if (argc
== idx_hold
+ 1)
7728 pim_ifp
->pim_default_holdtime
=
7729 strtol(argv
[idx_hold
]->arg
, NULL
, 10);
7734 DEFUN (interface_no_ip_pim_hello
,
7735 interface_no_ip_pim_hello_cmd
,
7736 "no ip pim hello [(1-180) (1-180)]",
7741 IFACE_PIM_HELLO_TIME_STR
7742 IFACE_PIM_HELLO_HOLD_STR
)
7744 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7745 struct pim_interface
*pim_ifp
= ifp
->info
;
7748 vty_out(vty
, "Pim not enabled on this interface\n");
7749 return CMD_WARNING_CONFIG_FAILED
;
7752 pim_ifp
->pim_hello_period
= PIM_DEFAULT_HELLO_PERIOD
;
7753 pim_ifp
->pim_default_holdtime
= -1;
7764 PIM_DO_DEBUG_IGMP_EVENTS
;
7765 PIM_DO_DEBUG_IGMP_PACKETS
;
7766 PIM_DO_DEBUG_IGMP_TRACE
;
7770 DEFUN (no_debug_igmp
,
7777 PIM_DONT_DEBUG_IGMP_EVENTS
;
7778 PIM_DONT_DEBUG_IGMP_PACKETS
;
7779 PIM_DONT_DEBUG_IGMP_TRACE
;
7784 DEFUN (debug_igmp_events
,
7785 debug_igmp_events_cmd
,
7786 "debug igmp events",
7789 DEBUG_IGMP_EVENTS_STR
)
7791 PIM_DO_DEBUG_IGMP_EVENTS
;
7795 DEFUN (no_debug_igmp_events
,
7796 no_debug_igmp_events_cmd
,
7797 "no debug igmp events",
7801 DEBUG_IGMP_EVENTS_STR
)
7803 PIM_DONT_DEBUG_IGMP_EVENTS
;
7808 DEFUN (debug_igmp_packets
,
7809 debug_igmp_packets_cmd
,
7810 "debug igmp packets",
7813 DEBUG_IGMP_PACKETS_STR
)
7815 PIM_DO_DEBUG_IGMP_PACKETS
;
7819 DEFUN (no_debug_igmp_packets
,
7820 no_debug_igmp_packets_cmd
,
7821 "no debug igmp packets",
7825 DEBUG_IGMP_PACKETS_STR
)
7827 PIM_DONT_DEBUG_IGMP_PACKETS
;
7832 DEFUN (debug_igmp_trace
,
7833 debug_igmp_trace_cmd
,
7837 DEBUG_IGMP_TRACE_STR
)
7839 PIM_DO_DEBUG_IGMP_TRACE
;
7843 DEFUN (no_debug_igmp_trace
,
7844 no_debug_igmp_trace_cmd
,
7845 "no debug igmp trace",
7849 DEBUG_IGMP_TRACE_STR
)
7851 PIM_DONT_DEBUG_IGMP_TRACE
;
7856 DEFUN (debug_mroute
,
7862 PIM_DO_DEBUG_MROUTE
;
7866 DEFUN (debug_mroute_detail
,
7867 debug_mroute_detail_cmd
,
7868 "debug mroute detail",
7873 PIM_DO_DEBUG_MROUTE_DETAIL
;
7877 DEFUN (no_debug_mroute
,
7878 no_debug_mroute_cmd
,
7884 PIM_DONT_DEBUG_MROUTE
;
7888 DEFUN (no_debug_mroute_detail
,
7889 no_debug_mroute_detail_cmd
,
7890 "no debug mroute detail",
7896 PIM_DONT_DEBUG_MROUTE_DETAIL
;
7900 DEFUN (debug_pim_static
,
7901 debug_pim_static_cmd
,
7907 PIM_DO_DEBUG_STATIC
;
7911 DEFUN (no_debug_pim_static
,
7912 no_debug_pim_static_cmd
,
7913 "no debug pim static",
7919 PIM_DONT_DEBUG_STATIC
;
7930 PIM_DO_DEBUG_PIM_EVENTS
;
7931 PIM_DO_DEBUG_PIM_PACKETS
;
7932 PIM_DO_DEBUG_PIM_TRACE
;
7933 PIM_DO_DEBUG_MSDP_EVENTS
;
7934 PIM_DO_DEBUG_MSDP_PACKETS
;
7939 DEFUN (no_debug_pim
,
7946 PIM_DONT_DEBUG_PIM_EVENTS
;
7947 PIM_DONT_DEBUG_PIM_PACKETS
;
7948 PIM_DONT_DEBUG_PIM_TRACE
;
7949 PIM_DONT_DEBUG_MSDP_EVENTS
;
7950 PIM_DONT_DEBUG_MSDP_PACKETS
;
7952 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
7953 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
7959 DEFUN (debug_pim_nht
,
7964 "Nexthop Tracking\n")
7966 PIM_DO_DEBUG_PIM_NHT
;
7970 DEFUN (no_debug_pim_nht
,
7971 no_debug_pim_nht_cmd
,
7976 "Nexthop Tracking\n")
7978 PIM_DONT_DEBUG_PIM_NHT
;
7982 DEFUN (debug_pim_nht_rp
,
7983 debug_pim_nht_rp_cmd
,
7987 "Nexthop Tracking\n"
7988 "RP Nexthop Tracking\n")
7990 PIM_DO_DEBUG_PIM_NHT_RP
;
7994 DEFUN (no_debug_pim_nht_rp
,
7995 no_debug_pim_nht_rp_cmd
,
7996 "no debug pim nht rp",
8000 "Nexthop Tracking\n"
8001 "RP Nexthop Tracking\n")
8003 PIM_DONT_DEBUG_PIM_NHT_RP
;
8007 DEFUN (debug_pim_events
,
8008 debug_pim_events_cmd
,
8012 DEBUG_PIM_EVENTS_STR
)
8014 PIM_DO_DEBUG_PIM_EVENTS
;
8018 DEFUN (no_debug_pim_events
,
8019 no_debug_pim_events_cmd
,
8020 "no debug pim events",
8024 DEBUG_PIM_EVENTS_STR
)
8026 PIM_DONT_DEBUG_PIM_EVENTS
;
8030 DEFUN (debug_pim_packets
,
8031 debug_pim_packets_cmd
,
8032 "debug pim packets [<hello|joins|register>]",
8035 DEBUG_PIM_PACKETS_STR
8036 DEBUG_PIM_HELLO_PACKETS_STR
8037 DEBUG_PIM_J_P_PACKETS_STR
8038 DEBUG_PIM_PIM_REG_PACKETS_STR
)
8041 if (argv_find(argv
, argc
, "hello", &idx
)) {
8042 PIM_DO_DEBUG_PIM_HELLO
;
8043 vty_out(vty
, "PIM Hello debugging is on\n");
8044 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
8045 PIM_DO_DEBUG_PIM_J_P
;
8046 vty_out(vty
, "PIM Join/Prune debugging is on\n");
8047 } else if (argv_find(argv
, argc
, "register", &idx
)) {
8048 PIM_DO_DEBUG_PIM_REG
;
8049 vty_out(vty
, "PIM Register debugging is on\n");
8051 PIM_DO_DEBUG_PIM_PACKETS
;
8052 vty_out(vty
, "PIM Packet debugging is on \n");
8057 DEFUN (no_debug_pim_packets
,
8058 no_debug_pim_packets_cmd
,
8059 "no debug pim packets [<hello|joins|register>]",
8063 DEBUG_PIM_PACKETS_STR
8064 DEBUG_PIM_HELLO_PACKETS_STR
8065 DEBUG_PIM_J_P_PACKETS_STR
8066 DEBUG_PIM_PIM_REG_PACKETS_STR
)
8069 if (argv_find(argv
, argc
, "hello", &idx
)) {
8070 PIM_DONT_DEBUG_PIM_HELLO
;
8071 vty_out(vty
, "PIM Hello debugging is off \n");
8072 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
8073 PIM_DONT_DEBUG_PIM_J_P
;
8074 vty_out(vty
, "PIM Join/Prune debugging is off \n");
8075 } else if (argv_find(argv
, argc
, "register", &idx
)) {
8076 PIM_DONT_DEBUG_PIM_REG
;
8077 vty_out(vty
, "PIM Register debugging is off\n");
8079 PIM_DONT_DEBUG_PIM_PACKETS
;
8085 DEFUN (debug_pim_packetdump_send
,
8086 debug_pim_packetdump_send_cmd
,
8087 "debug pim packet-dump send",
8090 DEBUG_PIM_PACKETDUMP_STR
8091 DEBUG_PIM_PACKETDUMP_SEND_STR
)
8093 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND
;
8097 DEFUN (no_debug_pim_packetdump_send
,
8098 no_debug_pim_packetdump_send_cmd
,
8099 "no debug pim packet-dump send",
8103 DEBUG_PIM_PACKETDUMP_STR
8104 DEBUG_PIM_PACKETDUMP_SEND_STR
)
8106 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
8110 DEFUN (debug_pim_packetdump_recv
,
8111 debug_pim_packetdump_recv_cmd
,
8112 "debug pim packet-dump receive",
8115 DEBUG_PIM_PACKETDUMP_STR
8116 DEBUG_PIM_PACKETDUMP_RECV_STR
)
8118 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV
;
8122 DEFUN (no_debug_pim_packetdump_recv
,
8123 no_debug_pim_packetdump_recv_cmd
,
8124 "no debug pim packet-dump receive",
8128 DEBUG_PIM_PACKETDUMP_STR
8129 DEBUG_PIM_PACKETDUMP_RECV_STR
)
8131 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
8135 DEFUN (debug_pim_trace
,
8136 debug_pim_trace_cmd
,
8140 DEBUG_PIM_TRACE_STR
)
8142 PIM_DO_DEBUG_PIM_TRACE
;
8146 DEFUN (debug_pim_trace_detail
,
8147 debug_pim_trace_detail_cmd
,
8148 "debug pim trace detail",
8152 "Detailed Information\n")
8154 PIM_DO_DEBUG_PIM_TRACE_DETAIL
;
8158 DEFUN (no_debug_pim_trace
,
8159 no_debug_pim_trace_cmd
,
8160 "no debug pim trace",
8164 DEBUG_PIM_TRACE_STR
)
8166 PIM_DONT_DEBUG_PIM_TRACE
;
8170 DEFUN (no_debug_pim_trace_detail
,
8171 no_debug_pim_trace_detail_cmd
,
8172 "no debug pim trace detail",
8177 "Detailed Information\n")
8179 PIM_DONT_DEBUG_PIM_TRACE_DETAIL
;
8183 DEFUN (debug_ssmpingd
,
8189 PIM_DO_DEBUG_SSMPINGD
;
8193 DEFUN (no_debug_ssmpingd
,
8194 no_debug_ssmpingd_cmd
,
8195 "no debug ssmpingd",
8200 PIM_DONT_DEBUG_SSMPINGD
;
8204 DEFUN (debug_pim_zebra
,
8205 debug_pim_zebra_cmd
,
8209 DEBUG_PIM_ZEBRA_STR
)
8215 DEFUN (no_debug_pim_zebra
,
8216 no_debug_pim_zebra_cmd
,
8217 "no debug pim zebra",
8221 DEBUG_PIM_ZEBRA_STR
)
8223 PIM_DONT_DEBUG_ZEBRA
;
8227 DEFUN (debug_pim_vxlan
,
8228 debug_pim_vxlan_cmd
,
8232 DEBUG_PIM_VXLAN_STR
)
8238 DEFUN (no_debug_pim_vxlan
,
8239 no_debug_pim_vxlan_cmd
,
8240 "no debug pim vxlan",
8244 DEBUG_PIM_VXLAN_STR
)
8246 PIM_DONT_DEBUG_VXLAN
;
8256 PIM_DO_DEBUG_MSDP_EVENTS
;
8257 PIM_DO_DEBUG_MSDP_PACKETS
;
8261 DEFUN (no_debug_msdp
,
8268 PIM_DONT_DEBUG_MSDP_EVENTS
;
8269 PIM_DONT_DEBUG_MSDP_PACKETS
;
8273 DEFUN (debug_msdp_events
,
8274 debug_msdp_events_cmd
,
8275 "debug msdp events",
8278 DEBUG_MSDP_EVENTS_STR
)
8280 PIM_DO_DEBUG_MSDP_EVENTS
;
8284 DEFUN (no_debug_msdp_events
,
8285 no_debug_msdp_events_cmd
,
8286 "no debug msdp events",
8290 DEBUG_MSDP_EVENTS_STR
)
8292 PIM_DONT_DEBUG_MSDP_EVENTS
;
8296 DEFUN (debug_msdp_packets
,
8297 debug_msdp_packets_cmd
,
8298 "debug msdp packets",
8301 DEBUG_MSDP_PACKETS_STR
)
8303 PIM_DO_DEBUG_MSDP_PACKETS
;
8307 DEFUN (no_debug_msdp_packets
,
8308 no_debug_msdp_packets_cmd
,
8309 "no debug msdp packets",
8313 DEBUG_MSDP_PACKETS_STR
)
8315 PIM_DONT_DEBUG_MSDP_PACKETS
;
8319 DEFUN (debug_mtrace
,
8325 PIM_DO_DEBUG_MTRACE
;
8329 DEFUN (no_debug_mtrace
,
8330 no_debug_mtrace_cmd
,
8336 PIM_DONT_DEBUG_MTRACE
;
8351 DEFUN (no_debug_bsm
,
8364 DEFUN_NOSH (show_debugging_pim
,
8365 show_debugging_pim_cmd
,
8366 "show debugging [pim]",
8371 vty_out(vty
, "PIM debugging status\n");
8373 pim_debug_config_write(vty
);
8378 static int interface_pim_use_src_cmd_worker(struct vty
*vty
, const char *source
)
8381 struct in_addr source_addr
;
8382 int ret
= CMD_SUCCESS
;
8383 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8385 result
= inet_pton(AF_INET
, source
, &source_addr
);
8387 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", source
,
8388 errno
, safe_strerror(errno
));
8389 return CMD_WARNING_CONFIG_FAILED
;
8392 result
= pim_update_source_set(ifp
, source_addr
);
8396 case PIM_IFACE_NOT_FOUND
:
8397 ret
= CMD_WARNING_CONFIG_FAILED
;
8398 vty_out(vty
, "Pim not enabled on this interface\n");
8400 case PIM_UPDATE_SOURCE_DUP
:
8402 vty_out(vty
, "%% Source already set to %s\n", source
);
8405 ret
= CMD_WARNING_CONFIG_FAILED
;
8406 vty_out(vty
, "%% Source set failed\n");
8412 DEFUN (interface_pim_use_source
,
8413 interface_pim_use_source_cmd
,
8414 "ip pim use-source A.B.C.D",
8417 "Configure primary IP address\n"
8418 "source ip address\n")
8420 return interface_pim_use_src_cmd_worker(vty
, argv
[3]->arg
);
8423 DEFUN (interface_no_pim_use_source
,
8424 interface_no_pim_use_source_cmd
,
8425 "no ip pim use-source [A.B.C.D]",
8429 "Delete source IP address\n"
8430 "source ip address\n")
8432 return interface_pim_use_src_cmd_worker(vty
, "0.0.0.0");
8440 "Enables BFD support\n")
8442 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8443 struct pim_interface
*pim_ifp
= ifp
->info
;
8444 struct bfd_info
*bfd_info
= NULL
;
8447 if (!pim_cmd_interface_add(ifp
)) {
8448 vty_out(vty
, "Could not enable PIM SM on interface\n");
8452 pim_ifp
= ifp
->info
;
8454 bfd_info
= pim_ifp
->bfd_info
;
8456 if (!bfd_info
|| !CHECK_FLAG(bfd_info
->flags
, BFD_FLAG_PARAM_CFG
))
8457 pim_bfd_if_param_set(ifp
, BFD_DEF_MIN_RX
, BFD_DEF_MIN_TX
,
8458 BFD_DEF_DETECT_MULT
, 1);
8463 DEFUN (no_ip_pim_bfd
,
8469 "Disables BFD support\n")
8471 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8472 struct pim_interface
*pim_ifp
= ifp
->info
;
8475 vty_out(vty
, "Pim not enabled on this interface\n");
8479 if (pim_ifp
->bfd_info
) {
8480 pim_bfd_reg_dereg_all_nbr(ifp
, ZEBRA_BFD_DEST_DEREGISTER
);
8481 bfd_info_free(&(pim_ifp
->bfd_info
));
8492 "Enables BSM support on the interface\n")
8494 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8495 struct pim_interface
*pim_ifp
= ifp
->info
;
8498 if (!pim_cmd_interface_add(ifp
)) {
8499 vty_out(vty
, "Could not enable PIM SM on interface\n");
8504 pim_ifp
= ifp
->info
;
8505 pim_ifp
->bsm_enable
= true;
8510 DEFUN (no_ip_pim_bsm
,
8516 "Disables BSM support\n")
8518 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8519 struct pim_interface
*pim_ifp
= ifp
->info
;
8522 vty_out(vty
, "Pim not enabled on this interface\n");
8526 pim_ifp
->bsm_enable
= false;
8531 DEFUN (ip_pim_ucast_bsm
,
8532 ip_pim_ucast_bsm_cmd
,
8533 "ip pim unicast-bsm",
8536 "Accept/Send unicast BSM on the interface\n")
8538 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8539 struct pim_interface
*pim_ifp
= ifp
->info
;
8542 if (!pim_cmd_interface_add(ifp
)) {
8543 vty_out(vty
, "Could not enable PIM SM on interface\n");
8548 pim_ifp
= ifp
->info
;
8549 pim_ifp
->ucast_bsm_accept
= true;
8554 DEFUN (no_ip_pim_ucast_bsm
,
8555 no_ip_pim_ucast_bsm_cmd
,
8556 "no ip pim unicast-bsm",
8560 "Block send/receive unicast BSM on this interface\n")
8562 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8563 struct pim_interface
*pim_ifp
= ifp
->info
;
8566 vty_out(vty
, "Pim not enabled on this interface\n");
8570 pim_ifp
->ucast_bsm_accept
= false;
8579 #endif /* HAVE_BFDD */
8581 ip_pim_bfd_param_cmd
,
8582 "ip pim bfd (2-255) (50-60000) (50-60000)",
8585 "Enables BFD support\n"
8586 "Detect Multiplier\n"
8587 "Required min receive interval\n"
8588 "Desired min transmit interval\n")
8590 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8592 int idx_number_2
= 4;
8593 int idx_number_3
= 5;
8598 struct pim_interface
*pim_ifp
= ifp
->info
;
8601 if (!pim_cmd_interface_add(ifp
)) {
8602 vty_out(vty
, "Could not enable PIM SM on interface\n");
8607 if ((ret
= bfd_validate_param(
8608 vty
, argv
[idx_number
]->arg
, argv
[idx_number_2
]->arg
,
8609 argv
[idx_number_3
]->arg
, &dm_val
, &rx_val
, &tx_val
))
8613 pim_bfd_if_param_set(ifp
, rx_val
, tx_val
, dm_val
, 0);
8619 ALIAS(no_ip_pim_bfd
, no_ip_pim_bfd_param_cmd
,
8620 "no ip pim bfd (2-255) (50-60000) (50-60000)", NO_STR IP_STR PIM_STR
8621 "Enables BFD support\n"
8622 "Detect Multiplier\n"
8623 "Required min receive interval\n"
8624 "Desired min transmit interval\n")
8625 #endif /* !HAVE_BFDD */
8627 static int ip_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
8628 const char *peer
, const char *local
)
8630 enum pim_msdp_err result
;
8631 struct in_addr peer_addr
;
8632 struct in_addr local_addr
;
8633 int ret
= CMD_SUCCESS
;
8635 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
8637 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
8638 errno
, safe_strerror(errno
));
8639 return CMD_WARNING_CONFIG_FAILED
;
8642 result
= inet_pton(AF_INET
, local
, &local_addr
);
8644 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", local
,
8645 errno
, safe_strerror(errno
));
8646 return CMD_WARNING_CONFIG_FAILED
;
8649 result
= pim_msdp_peer_add(pim
, peer_addr
, local_addr
, "default",
8652 case PIM_MSDP_ERR_NONE
:
8654 case PIM_MSDP_ERR_OOM
:
8655 ret
= CMD_WARNING_CONFIG_FAILED
;
8656 vty_out(vty
, "%% Out of memory\n");
8658 case PIM_MSDP_ERR_PEER_EXISTS
:
8660 vty_out(vty
, "%% Peer exists\n");
8662 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
8663 ret
= CMD_WARNING_CONFIG_FAILED
;
8664 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
8667 ret
= CMD_WARNING_CONFIG_FAILED
;
8668 vty_out(vty
, "%% peer add failed\n");
8674 DEFUN_HIDDEN (ip_msdp_peer
,
8676 "ip msdp peer A.B.C.D source A.B.C.D",
8679 "Configure MSDP peer\n"
8681 "Source address for TCP connection\n"
8682 "local ip address\n")
8684 PIM_DECLVAR_CONTEXT(vrf
, pim
);
8685 return ip_msdp_peer_cmd_worker(pim
, vty
, argv
[3]->arg
, argv
[5]->arg
);
8688 static int ip_no_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
8691 enum pim_msdp_err result
;
8692 struct in_addr peer_addr
;
8694 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
8696 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
8697 errno
, safe_strerror(errno
));
8698 return CMD_WARNING_CONFIG_FAILED
;
8701 result
= pim_msdp_peer_del(pim
, peer_addr
);
8703 case PIM_MSDP_ERR_NONE
:
8705 case PIM_MSDP_ERR_NO_PEER
:
8706 vty_out(vty
, "%% Peer does not exist\n");
8709 vty_out(vty
, "%% peer del failed\n");
8712 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
8715 DEFUN_HIDDEN (no_ip_msdp_peer
,
8716 no_ip_msdp_peer_cmd
,
8717 "no ip msdp peer A.B.C.D",
8721 "Delete MSDP peer\n"
8722 "peer ip address\n")
8724 PIM_DECLVAR_CONTEXT(vrf
, pim
);
8725 return ip_no_msdp_peer_cmd_worker(pim
, vty
, argv
[4]->arg
);
8728 static int ip_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
8729 struct vty
*vty
, const char *mg
,
8732 enum pim_msdp_err result
;
8733 struct in_addr mbr_ip
;
8734 int ret
= CMD_SUCCESS
;
8736 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
8738 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
8739 errno
, safe_strerror(errno
));
8740 return CMD_WARNING_CONFIG_FAILED
;
8743 result
= pim_msdp_mg_mbr_add(pim
, mg
, mbr_ip
);
8745 case PIM_MSDP_ERR_NONE
:
8747 case PIM_MSDP_ERR_OOM
:
8748 ret
= CMD_WARNING_CONFIG_FAILED
;
8749 vty_out(vty
, "%% Out of memory\n");
8751 case PIM_MSDP_ERR_MG_MBR_EXISTS
:
8753 vty_out(vty
, "%% mesh-group member exists\n");
8755 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
8756 ret
= CMD_WARNING_CONFIG_FAILED
;
8757 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
8760 ret
= CMD_WARNING_CONFIG_FAILED
;
8761 vty_out(vty
, "%% member add failed\n");
8767 DEFUN (ip_msdp_mesh_group_member
,
8768 ip_msdp_mesh_group_member_cmd
,
8769 "ip msdp mesh-group WORD member A.B.C.D",
8772 "Configure MSDP mesh-group\n"
8774 "mesh group member\n"
8775 "peer ip address\n")
8777 PIM_DECLVAR_CONTEXT(vrf
, pim
);
8778 return ip_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[3]->arg
,
8782 static int ip_no_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
8787 enum pim_msdp_err result
;
8788 struct in_addr mbr_ip
;
8790 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
8792 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
8793 errno
, safe_strerror(errno
));
8794 return CMD_WARNING_CONFIG_FAILED
;
8797 result
= pim_msdp_mg_mbr_del(pim
, mg
, mbr_ip
);
8799 case PIM_MSDP_ERR_NONE
:
8801 case PIM_MSDP_ERR_NO_MG
:
8802 vty_out(vty
, "%% mesh-group does not exist\n");
8804 case PIM_MSDP_ERR_NO_MG_MBR
:
8805 vty_out(vty
, "%% mesh-group member does not exist\n");
8808 vty_out(vty
, "%% mesh-group member del failed\n");
8811 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
8813 DEFUN (no_ip_msdp_mesh_group_member
,
8814 no_ip_msdp_mesh_group_member_cmd
,
8815 "no ip msdp mesh-group WORD member A.B.C.D",
8819 "Delete MSDP mesh-group member\n"
8821 "mesh group member\n"
8822 "peer ip address\n")
8824 PIM_DECLVAR_CONTEXT(vrf
, pim
);
8825 return ip_no_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[4]->arg
,
8829 static int ip_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
8830 struct vty
*vty
, const char *mg
,
8833 enum pim_msdp_err result
;
8834 struct in_addr src_ip
;
8836 result
= inet_pton(AF_INET
, src
, &src_ip
);
8838 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", src
,
8839 errno
, safe_strerror(errno
));
8840 return CMD_WARNING_CONFIG_FAILED
;
8843 result
= pim_msdp_mg_src_add(pim
, mg
, src_ip
);
8845 case PIM_MSDP_ERR_NONE
:
8847 case PIM_MSDP_ERR_OOM
:
8848 vty_out(vty
, "%% Out of memory\n");
8850 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
8851 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
8854 vty_out(vty
, "%% source add failed\n");
8857 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
8861 DEFUN (ip_msdp_mesh_group_source
,
8862 ip_msdp_mesh_group_source_cmd
,
8863 "ip msdp mesh-group WORD source A.B.C.D",
8866 "Configure MSDP mesh-group\n"
8868 "mesh group local address\n"
8869 "source ip address for the TCP connection\n")
8871 PIM_DECLVAR_CONTEXT(vrf
, pim
);
8872 return ip_msdp_mesh_group_source_cmd_worker(pim
, vty
, argv
[3]->arg
,
8876 static int ip_no_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
8880 enum pim_msdp_err result
;
8882 result
= pim_msdp_mg_src_del(pim
, mg
);
8884 case PIM_MSDP_ERR_NONE
:
8886 case PIM_MSDP_ERR_NO_MG
:
8887 vty_out(vty
, "%% mesh-group does not exist\n");
8890 vty_out(vty
, "%% mesh-group source del failed\n");
8893 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
8896 static int ip_no_msdp_mesh_group_cmd_worker(struct pim_instance
*pim
,
8897 struct vty
*vty
, const char *mg
)
8899 enum pim_msdp_err result
;
8901 result
= pim_msdp_mg_del(pim
, mg
);
8903 case PIM_MSDP_ERR_NONE
:
8905 case PIM_MSDP_ERR_NO_MG
:
8906 vty_out(vty
, "%% mesh-group does not exist\n");
8909 vty_out(vty
, "%% mesh-group source del failed\n");
8912 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
8915 DEFUN (no_ip_msdp_mesh_group_source
,
8916 no_ip_msdp_mesh_group_source_cmd
,
8917 "no ip msdp mesh-group WORD source [A.B.C.D]",
8921 "Delete MSDP mesh-group source\n"
8923 "mesh group source\n"
8924 "mesh group local address\n")
8926 PIM_DECLVAR_CONTEXT(vrf
, pim
);
8928 return ip_no_msdp_mesh_group_cmd_worker(pim
, vty
, argv
[6]->arg
);
8930 return ip_no_msdp_mesh_group_source_cmd_worker(pim
, vty
,
8934 static void print_empty_json_obj(struct vty
*vty
)
8937 json
= json_object_new_object();
8938 vty_out(vty
, "%s\n",
8939 json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
));
8940 json_object_free(json
);
8943 static void ip_msdp_show_mesh_group(struct pim_instance
*pim
, struct vty
*vty
,
8946 struct listnode
*mbrnode
;
8947 struct pim_msdp_mg_mbr
*mbr
;
8948 struct pim_msdp_mg
*mg
= pim
->msdp
.mg
;
8949 char mbr_str
[INET_ADDRSTRLEN
];
8950 char src_str
[INET_ADDRSTRLEN
];
8951 char state_str
[PIM_MSDP_STATE_STRLEN
];
8952 enum pim_msdp_peer_state state
;
8953 json_object
*json
= NULL
;
8954 json_object
*json_mg_row
= NULL
;
8955 json_object
*json_members
= NULL
;
8956 json_object
*json_row
= NULL
;
8960 print_empty_json_obj(vty
);
8964 pim_inet4_dump("<source?>", mg
->src_ip
, src_str
, sizeof(src_str
));
8966 json
= json_object_new_object();
8967 /* currently there is only one mesh group but we should still
8969 * it a dict with mg-name as key */
8970 json_mg_row
= json_object_new_object();
8971 json_object_string_add(json_mg_row
, "name",
8972 mg
->mesh_group_name
);
8973 json_object_string_add(json_mg_row
, "source", src_str
);
8975 vty_out(vty
, "Mesh group : %s\n", mg
->mesh_group_name
);
8976 vty_out(vty
, " Source : %s\n", src_str
);
8977 vty_out(vty
, " Member State\n");
8980 for (ALL_LIST_ELEMENTS_RO(mg
->mbr_list
, mbrnode
, mbr
)) {
8981 pim_inet4_dump("<mbr?>", mbr
->mbr_ip
, mbr_str
, sizeof(mbr_str
));
8983 state
= mbr
->mp
->state
;
8985 state
= PIM_MSDP_DISABLED
;
8987 pim_msdp_state_dump(state
, state_str
, sizeof(state_str
));
8989 json_row
= json_object_new_object();
8990 json_object_string_add(json_row
, "member", mbr_str
);
8991 json_object_string_add(json_row
, "state", state_str
);
8992 if (!json_members
) {
8993 json_members
= json_object_new_object();
8994 json_object_object_add(json_mg_row
, "members",
8997 json_object_object_add(json_members
, mbr_str
, json_row
);
8999 vty_out(vty
, " %-15s %11s\n", mbr_str
, state_str
);
9004 json_object_object_add(json
, mg
->mesh_group_name
, json_mg_row
);
9005 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9006 json
, JSON_C_TO_STRING_PRETTY
));
9007 json_object_free(json
);
9011 DEFUN (show_ip_msdp_mesh_group
,
9012 show_ip_msdp_mesh_group_cmd
,
9013 "show ip msdp [vrf NAME] mesh-group [json]",
9018 "MSDP mesh-group information\n"
9021 bool uj
= use_json(argc
, argv
);
9023 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
9028 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
9033 DEFUN (show_ip_msdp_mesh_group_vrf_all
,
9034 show_ip_msdp_mesh_group_vrf_all_cmd
,
9035 "show ip msdp vrf all mesh-group [json]",
9040 "MSDP mesh-group information\n"
9043 bool uj
= use_json(argc
, argv
);
9049 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
9053 vty_out(vty
, " \"%s\": ", vrf
->name
);
9056 vty_out(vty
, "VRF: %s\n", vrf
->name
);
9057 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
9060 vty_out(vty
, "}\n");
9065 static void ip_msdp_show_peers(struct pim_instance
*pim
, struct vty
*vty
,
9068 struct listnode
*mpnode
;
9069 struct pim_msdp_peer
*mp
;
9070 char peer_str
[INET_ADDRSTRLEN
];
9071 char local_str
[INET_ADDRSTRLEN
];
9072 char state_str
[PIM_MSDP_STATE_STRLEN
];
9073 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
9075 json_object
*json
= NULL
;
9076 json_object
*json_row
= NULL
;
9080 json
= json_object_new_object();
9083 "Peer Local State Uptime SaCnt\n");
9086 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
9087 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
9088 now
= pim_time_monotonic_sec();
9089 pim_time_uptime(timebuf
, sizeof(timebuf
),
9092 strlcpy(timebuf
, "-", sizeof(timebuf
));
9094 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
9095 pim_inet4_dump("<local?>", mp
->local
, local_str
,
9097 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
9099 json_row
= json_object_new_object();
9100 json_object_string_add(json_row
, "peer", peer_str
);
9101 json_object_string_add(json_row
, "local", local_str
);
9102 json_object_string_add(json_row
, "state", state_str
);
9103 json_object_string_add(json_row
, "upTime", timebuf
);
9104 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
9105 json_object_object_add(json
, peer_str
, json_row
);
9107 vty_out(vty
, "%-15s %15s %11s %8s %6d\n", peer_str
,
9108 local_str
, state_str
, timebuf
, mp
->sa_cnt
);
9113 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9114 json
, JSON_C_TO_STRING_PRETTY
));
9115 json_object_free(json
);
9119 static void ip_msdp_show_peers_detail(struct pim_instance
*pim
, struct vty
*vty
,
9120 const char *peer
, bool uj
)
9122 struct listnode
*mpnode
;
9123 struct pim_msdp_peer
*mp
;
9124 char peer_str
[INET_ADDRSTRLEN
];
9125 char local_str
[INET_ADDRSTRLEN
];
9126 char state_str
[PIM_MSDP_STATE_STRLEN
];
9127 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
9128 char katimer
[PIM_MSDP_TIMER_STRLEN
];
9129 char crtimer
[PIM_MSDP_TIMER_STRLEN
];
9130 char holdtimer
[PIM_MSDP_TIMER_STRLEN
];
9132 json_object
*json
= NULL
;
9133 json_object
*json_row
= NULL
;
9136 json
= json_object_new_object();
9139 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
9140 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
9141 if (strcmp(peer
, "detail") && strcmp(peer
, peer_str
))
9144 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
9145 now
= pim_time_monotonic_sec();
9146 pim_time_uptime(timebuf
, sizeof(timebuf
),
9149 strlcpy(timebuf
, "-", sizeof(timebuf
));
9151 pim_inet4_dump("<local?>", mp
->local
, local_str
,
9153 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
9154 pim_time_timer_to_hhmmss(katimer
, sizeof(katimer
),
9156 pim_time_timer_to_hhmmss(crtimer
, sizeof(crtimer
),
9158 pim_time_timer_to_hhmmss(holdtimer
, sizeof(holdtimer
),
9162 json_row
= json_object_new_object();
9163 json_object_string_add(json_row
, "peer", peer_str
);
9164 json_object_string_add(json_row
, "local", local_str
);
9165 json_object_string_add(json_row
, "meshGroupName",
9166 mp
->mesh_group_name
);
9167 json_object_string_add(json_row
, "state", state_str
);
9168 json_object_string_add(json_row
, "upTime", timebuf
);
9169 json_object_string_add(json_row
, "keepAliveTimer",
9171 json_object_string_add(json_row
, "connRetryTimer",
9173 json_object_string_add(json_row
, "holdTimer",
9175 json_object_string_add(json_row
, "lastReset",
9177 json_object_int_add(json_row
, "connAttempts",
9179 json_object_int_add(json_row
, "establishedChanges",
9181 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
9182 json_object_int_add(json_row
, "kaSent", mp
->ka_tx_cnt
);
9183 json_object_int_add(json_row
, "kaRcvd", mp
->ka_rx_cnt
);
9184 json_object_int_add(json_row
, "saSent", mp
->sa_tx_cnt
);
9185 json_object_int_add(json_row
, "saRcvd", mp
->sa_rx_cnt
);
9186 json_object_object_add(json
, peer_str
, json_row
);
9188 vty_out(vty
, "Peer : %s\n", peer_str
);
9189 vty_out(vty
, " Local : %s\n", local_str
);
9190 vty_out(vty
, " Mesh Group : %s\n",
9191 mp
->mesh_group_name
);
9192 vty_out(vty
, " State : %s\n", state_str
);
9193 vty_out(vty
, " Uptime : %s\n", timebuf
);
9195 vty_out(vty
, " Keepalive Timer : %s\n", katimer
);
9196 vty_out(vty
, " Conn Retry Timer : %s\n", crtimer
);
9197 vty_out(vty
, " Hold Timer : %s\n", holdtimer
);
9198 vty_out(vty
, " Last Reset : %s\n",
9200 vty_out(vty
, " Conn Attempts : %d\n",
9202 vty_out(vty
, " Established Changes : %d\n",
9204 vty_out(vty
, " SA Count : %d\n",
9206 vty_out(vty
, " Statistics :\n");
9209 vty_out(vty
, " Keepalives : %10d %10d\n",
9210 mp
->ka_tx_cnt
, mp
->ka_rx_cnt
);
9211 vty_out(vty
, " SAs : %10d %10d\n",
9212 mp
->sa_tx_cnt
, mp
->sa_rx_cnt
);
9218 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9219 json
, JSON_C_TO_STRING_PRETTY
));
9220 json_object_free(json
);
9224 DEFUN (show_ip_msdp_peer_detail
,
9225 show_ip_msdp_peer_detail_cmd
,
9226 "show ip msdp [vrf NAME] peer [detail|A.B.C.D] [json]",
9231 "MSDP peer information\n"
9236 bool uj
= use_json(argc
, argv
);
9238 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
9245 if (argv_find(argv
, argc
, "detail", &idx
))
9246 arg
= argv
[idx
]->text
;
9247 else if (argv_find(argv
, argc
, "A.B.C.D", &idx
))
9248 arg
= argv
[idx
]->arg
;
9251 ip_msdp_show_peers_detail(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
9253 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
9258 DEFUN (show_ip_msdp_peer_detail_vrf_all
,
9259 show_ip_msdp_peer_detail_vrf_all_cmd
,
9260 "show ip msdp vrf all peer [detail|A.B.C.D] [json]",
9265 "MSDP peer information\n"
9271 bool uj
= use_json(argc
, argv
);
9277 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
9281 vty_out(vty
, " \"%s\": ", vrf
->name
);
9284 vty_out(vty
, "VRF: %s\n", vrf
->name
);
9285 if (argv_find(argv
, argc
, "detail", &idx
)
9286 || argv_find(argv
, argc
, "A.B.C.D", &idx
))
9287 ip_msdp_show_peers_detail(vrf
->info
, vty
,
9288 argv
[idx
]->arg
, uj
);
9290 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
9293 vty_out(vty
, "}\n");
9298 static void ip_msdp_show_sa(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
9300 struct listnode
*sanode
;
9301 struct pim_msdp_sa
*sa
;
9302 char src_str
[INET_ADDRSTRLEN
];
9303 char grp_str
[INET_ADDRSTRLEN
];
9304 char rp_str
[INET_ADDRSTRLEN
];
9305 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
9309 json_object
*json
= NULL
;
9310 json_object
*json_group
= NULL
;
9311 json_object
*json_row
= NULL
;
9314 json
= json_object_new_object();
9317 "Source Group RP Local SPT Uptime\n");
9320 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
9321 now
= pim_time_monotonic_sec();
9322 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
9323 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
9324 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
9325 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
9326 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
9328 strlcpy(spt_str
, "yes", sizeof(spt_str
));
9330 strlcpy(spt_str
, "no", sizeof(spt_str
));
9333 strlcpy(rp_str
, "-", sizeof(rp_str
));
9334 strlcpy(spt_str
, "-", sizeof(spt_str
));
9336 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
9337 strlcpy(local_str
, "yes", sizeof(local_str
));
9339 strlcpy(local_str
, "no", sizeof(local_str
));
9342 json_object_object_get_ex(json
, grp_str
, &json_group
);
9345 json_group
= json_object_new_object();
9346 json_object_object_add(json
, grp_str
,
9350 json_row
= json_object_new_object();
9351 json_object_string_add(json_row
, "source", src_str
);
9352 json_object_string_add(json_row
, "group", grp_str
);
9353 json_object_string_add(json_row
, "rp", rp_str
);
9354 json_object_string_add(json_row
, "local", local_str
);
9355 json_object_string_add(json_row
, "sptSetup", spt_str
);
9356 json_object_string_add(json_row
, "upTime", timebuf
);
9357 json_object_object_add(json_group
, src_str
, json_row
);
9359 vty_out(vty
, "%-15s %15s %15s %5c %3c %8s\n",
9360 src_str
, grp_str
, rp_str
, local_str
[0],
9361 spt_str
[0], timebuf
);
9366 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9367 json
, JSON_C_TO_STRING_PRETTY
));
9368 json_object_free(json
);
9372 static void ip_msdp_show_sa_entry_detail(struct pim_msdp_sa
*sa
,
9373 const char *src_str
,
9374 const char *grp_str
, struct vty
*vty
,
9375 bool uj
, json_object
*json
)
9377 char rp_str
[INET_ADDRSTRLEN
];
9378 char peer_str
[INET_ADDRSTRLEN
];
9379 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
9382 char statetimer
[PIM_MSDP_TIMER_STRLEN
];
9384 json_object
*json_group
= NULL
;
9385 json_object
*json_row
= NULL
;
9387 now
= pim_time_monotonic_sec();
9388 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
9389 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
9390 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
9391 pim_inet4_dump("<peer?>", sa
->peer
, peer_str
, sizeof(peer_str
));
9393 strlcpy(spt_str
, "yes", sizeof(spt_str
));
9395 strlcpy(spt_str
, "no", sizeof(spt_str
));
9398 strlcpy(rp_str
, "-", sizeof(rp_str
));
9399 strlcpy(peer_str
, "-", sizeof(peer_str
));
9400 strlcpy(spt_str
, "-", sizeof(spt_str
));
9402 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
9403 strlcpy(local_str
, "yes", sizeof(local_str
));
9405 strlcpy(local_str
, "no", sizeof(local_str
));
9407 pim_time_timer_to_hhmmss(statetimer
, sizeof(statetimer
),
9408 sa
->sa_state_timer
);
9410 json_object_object_get_ex(json
, grp_str
, &json_group
);
9413 json_group
= json_object_new_object();
9414 json_object_object_add(json
, grp_str
, json_group
);
9417 json_row
= json_object_new_object();
9418 json_object_string_add(json_row
, "source", src_str
);
9419 json_object_string_add(json_row
, "group", grp_str
);
9420 json_object_string_add(json_row
, "rp", rp_str
);
9421 json_object_string_add(json_row
, "local", local_str
);
9422 json_object_string_add(json_row
, "sptSetup", spt_str
);
9423 json_object_string_add(json_row
, "upTime", timebuf
);
9424 json_object_string_add(json_row
, "stateTimer", statetimer
);
9425 json_object_object_add(json_group
, src_str
, json_row
);
9427 vty_out(vty
, "SA : %s\n", sa
->sg_str
);
9428 vty_out(vty
, " RP : %s\n", rp_str
);
9429 vty_out(vty
, " Peer : %s\n", peer_str
);
9430 vty_out(vty
, " Local : %s\n", local_str
);
9431 vty_out(vty
, " SPT Setup : %s\n", spt_str
);
9432 vty_out(vty
, " Uptime : %s\n", timebuf
);
9433 vty_out(vty
, " State Timer : %s\n", statetimer
);
9438 static void ip_msdp_show_sa_detail(struct pim_instance
*pim
, struct vty
*vty
,
9441 struct listnode
*sanode
;
9442 struct pim_msdp_sa
*sa
;
9443 char src_str
[INET_ADDRSTRLEN
];
9444 char grp_str
[INET_ADDRSTRLEN
];
9445 json_object
*json
= NULL
;
9448 json
= json_object_new_object();
9451 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
9452 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
9453 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
9454 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
, uj
,
9459 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9460 json
, JSON_C_TO_STRING_PRETTY
));
9461 json_object_free(json
);
9465 DEFUN (show_ip_msdp_sa_detail
,
9466 show_ip_msdp_sa_detail_cmd
,
9467 "show ip msdp [vrf NAME] sa detail [json]",
9472 "MSDP active-source information\n"
9476 bool uj
= use_json(argc
, argv
);
9478 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
9483 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
9488 DEFUN (show_ip_msdp_sa_detail_vrf_all
,
9489 show_ip_msdp_sa_detail_vrf_all_cmd
,
9490 "show ip msdp vrf all sa detail [json]",
9495 "MSDP active-source information\n"
9499 bool uj
= use_json(argc
, argv
);
9505 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
9509 vty_out(vty
, " \"%s\": ", vrf
->name
);
9512 vty_out(vty
, "VRF: %s\n", vrf
->name
);
9513 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
9516 vty_out(vty
, "}\n");
9521 static void ip_msdp_show_sa_addr(struct pim_instance
*pim
, struct vty
*vty
,
9522 const char *addr
, bool uj
)
9524 struct listnode
*sanode
;
9525 struct pim_msdp_sa
*sa
;
9526 char src_str
[INET_ADDRSTRLEN
];
9527 char grp_str
[INET_ADDRSTRLEN
];
9528 json_object
*json
= NULL
;
9531 json
= json_object_new_object();
9534 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
9535 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
9536 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
9537 if (!strcmp(addr
, src_str
) || !strcmp(addr
, grp_str
)) {
9538 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
9544 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9545 json
, JSON_C_TO_STRING_PRETTY
));
9546 json_object_free(json
);
9550 static void ip_msdp_show_sa_sg(struct pim_instance
*pim
, struct vty
*vty
,
9551 const char *src
, const char *grp
, bool uj
)
9553 struct listnode
*sanode
;
9554 struct pim_msdp_sa
*sa
;
9555 char src_str
[INET_ADDRSTRLEN
];
9556 char grp_str
[INET_ADDRSTRLEN
];
9557 json_object
*json
= NULL
;
9560 json
= json_object_new_object();
9563 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
9564 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
9565 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
9566 if (!strcmp(src
, src_str
) && !strcmp(grp
, grp_str
)) {
9567 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
9573 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9574 json
, JSON_C_TO_STRING_PRETTY
));
9575 json_object_free(json
);
9579 DEFUN (show_ip_msdp_sa_sg
,
9580 show_ip_msdp_sa_sg_cmd
,
9581 "show ip msdp [vrf NAME] sa [A.B.C.D [A.B.C.D]] [json]",
9586 "MSDP active-source information\n"
9587 "source or group ip\n"
9591 bool uj
= use_json(argc
, argv
);
9595 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
9600 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
9602 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
9606 if (src_ip
&& grp_ip
)
9607 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
9609 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
9611 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
9616 DEFUN (show_ip_msdp_sa_sg_vrf_all
,
9617 show_ip_msdp_sa_sg_vrf_all_cmd
,
9618 "show ip msdp vrf all sa [A.B.C.D [A.B.C.D]] [json]",
9623 "MSDP active-source information\n"
9624 "source or group ip\n"
9628 bool uj
= use_json(argc
, argv
);
9633 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
9635 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
9641 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
9645 vty_out(vty
, " \"%s\": ", vrf
->name
);
9648 vty_out(vty
, "VRF: %s\n", vrf
->name
);
9650 if (src_ip
&& grp_ip
)
9651 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
9653 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
9655 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
9658 vty_out(vty
, "}\n");
9663 struct pim_sg_cache_walk_data
{
9666 json_object
*json_group
;
9667 struct in_addr addr
;
9671 static void pim_show_vxlan_sg_entry(struct pim_vxlan_sg
*vxlan_sg
,
9672 struct pim_sg_cache_walk_data
*cwd
)
9674 struct vty
*vty
= cwd
->vty
;
9675 json_object
*json
= cwd
->json
;
9676 char src_str
[INET_ADDRSTRLEN
];
9677 char grp_str
[INET_ADDRSTRLEN
];
9678 json_object
*json_row
;
9679 bool installed
= (vxlan_sg
->up
)?TRUE
:FALSE
;
9680 const char *iif_name
= vxlan_sg
->iif
?vxlan_sg
->iif
->name
:"-";
9681 const char *oif_name
;
9683 if (pim_vxlan_is_orig_mroute(vxlan_sg
))
9684 oif_name
= vxlan_sg
->orig_oif
?vxlan_sg
->orig_oif
->name
:"";
9686 oif_name
= vxlan_sg
->term_oif
?vxlan_sg
->term_oif
->name
:"";
9688 if (cwd
->addr_match
&& (vxlan_sg
->sg
.src
.s_addr
!= cwd
->addr
.s_addr
) &&
9689 (vxlan_sg
->sg
.grp
.s_addr
!= cwd
->addr
.s_addr
)) {
9692 pim_inet4_dump("<src?>", vxlan_sg
->sg
.src
, src_str
, sizeof(src_str
));
9693 pim_inet4_dump("<grp?>", vxlan_sg
->sg
.grp
, grp_str
, sizeof(grp_str
));
9695 json_object_object_get_ex(json
, grp_str
, &cwd
->json_group
);
9697 if (!cwd
->json_group
) {
9698 cwd
->json_group
= json_object_new_object();
9699 json_object_object_add(json
, grp_str
,
9703 json_row
= json_object_new_object();
9704 json_object_string_add(json_row
, "source", src_str
);
9705 json_object_string_add(json_row
, "group", grp_str
);
9706 json_object_string_add(json_row
, "input", iif_name
);
9707 json_object_string_add(json_row
, "output", oif_name
);
9709 json_object_boolean_true_add(json_row
, "installed");
9711 json_object_boolean_false_add(json_row
, "installed");
9712 json_object_object_add(cwd
->json_group
, src_str
, json_row
);
9714 vty_out(vty
, "%-15s %-15s %-15s %-15s %-5s\n",
9715 src_str
, grp_str
, iif_name
, oif_name
,
9720 static void pim_show_vxlan_sg_hash_entry(struct hash_backet
*backet
, void *arg
)
9722 pim_show_vxlan_sg_entry((struct pim_vxlan_sg
*)backet
->data
,
9723 (struct pim_sg_cache_walk_data
*)arg
);
9726 static void pim_show_vxlan_sg(struct pim_instance
*pim
,
9727 struct vty
*vty
, bool uj
)
9729 json_object
*json
= NULL
;
9730 struct pim_sg_cache_walk_data cwd
;
9733 json
= json_object_new_object();
9735 vty_out(vty
, "Codes: I -> installed\n");
9737 "Source Group Input Output Flags\n");
9740 memset(&cwd
, 0, sizeof(cwd
));
9743 hash_iterate(pim
->vxlan
.sg_hash
, pim_show_vxlan_sg_hash_entry
, &cwd
);
9746 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9747 json
, JSON_C_TO_STRING_PRETTY
));
9748 json_object_free(json
);
9752 static void pim_show_vxlan_sg_match_addr(struct pim_instance
*pim
,
9753 struct vty
*vty
, char *addr_str
, bool uj
)
9755 json_object
*json
= NULL
;
9756 struct pim_sg_cache_walk_data cwd
;
9759 memset(&cwd
, 0, sizeof(cwd
));
9760 result
= inet_pton(AF_INET
, addr_str
, &cwd
.addr
);
9762 vty_out(vty
, "Bad address %s: errno=%d: %s\n", addr_str
,
9763 errno
, safe_strerror(errno
));
9768 json
= json_object_new_object();
9770 vty_out(vty
, "Codes: I -> installed\n");
9772 "Source Group Input Output Flags\n");
9777 cwd
.addr_match
= TRUE
;
9778 hash_iterate(pim
->vxlan
.sg_hash
, pim_show_vxlan_sg_hash_entry
, &cwd
);
9781 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9782 json
, JSON_C_TO_STRING_PRETTY
));
9783 json_object_free(json
);
9787 static void pim_show_vxlan_sg_one(struct pim_instance
*pim
,
9788 struct vty
*vty
, char *src_str
, char *grp_str
, bool uj
)
9790 json_object
*json
= NULL
;
9791 struct prefix_sg sg
;
9793 struct pim_vxlan_sg
*vxlan_sg
;
9794 const char *iif_name
;
9796 const char *oif_name
;
9798 result
= inet_pton(AF_INET
, src_str
, &sg
.src
);
9800 vty_out(vty
, "Bad src address %s: errno=%d: %s\n", src_str
,
9801 errno
, safe_strerror(errno
));
9804 result
= inet_pton(AF_INET
, grp_str
, &sg
.grp
);
9806 vty_out(vty
, "Bad grp address %s: errno=%d: %s\n", grp_str
,
9807 errno
, safe_strerror(errno
));
9811 sg
.family
= AF_INET
;
9812 sg
.prefixlen
= IPV4_MAX_BITLEN
;
9814 json
= json_object_new_object();
9816 vxlan_sg
= pim_vxlan_sg_find(pim
, &sg
);
9818 installed
= (vxlan_sg
->up
)?TRUE
:FALSE
;
9819 iif_name
= vxlan_sg
->iif
?vxlan_sg
->iif
->name
:"-";
9821 if (pim_vxlan_is_orig_mroute(vxlan_sg
))
9823 vxlan_sg
->orig_oif
?vxlan_sg
->orig_oif
->name
:"";
9826 vxlan_sg
->term_oif
?vxlan_sg
->term_oif
->name
:"";
9829 json_object_string_add(json
, "source", src_str
);
9830 json_object_string_add(json
, "group", grp_str
);
9831 json_object_string_add(json
, "input", iif_name
);
9832 json_object_string_add(json
, "output", oif_name
);
9834 json_object_boolean_true_add(json
, "installed");
9836 json_object_boolean_false_add(json
,
9839 vty_out(vty
, "SG : %s\n", vxlan_sg
->sg_str
);
9840 vty_out(vty
, " Input : %s\n", iif_name
);
9841 vty_out(vty
, " Output : %s\n", oif_name
);
9842 vty_out(vty
, " installed : %s\n",
9843 installed
?"yes":"no");
9848 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9849 json
, JSON_C_TO_STRING_PRETTY
));
9850 json_object_free(json
);
9854 DEFUN (show_ip_pim_vxlan_sg
,
9855 show_ip_pim_vxlan_sg_cmd
,
9856 "show ip pim [vrf NAME] vxlan-groups [A.B.C.D [A.B.C.D]] [json]",
9861 "VxLAN BUM groups\n"
9862 "source or group ip\n"
9866 bool uj
= use_json(argc
, argv
);
9870 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
9875 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ?
9876 argv
[idx
++]->arg
:NULL
;
9877 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
) ?
9878 argv
[idx
]->arg
:NULL
;
9880 if (src_ip
&& grp_ip
)
9881 pim_show_vxlan_sg_one(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
9883 pim_show_vxlan_sg_match_addr(vrf
->info
, vty
, src_ip
, uj
);
9885 pim_show_vxlan_sg(vrf
->info
, vty
, uj
);
9890 static void pim_show_vxlan_sg_work(struct pim_instance
*pim
,
9891 struct vty
*vty
, bool uj
)
9893 json_object
*json
= NULL
;
9894 struct pim_sg_cache_walk_data cwd
;
9895 struct listnode
*node
;
9896 struct pim_vxlan_sg
*vxlan_sg
;
9899 json
= json_object_new_object();
9901 vty_out(vty
, "Codes: I -> installed\n");
9903 "Source Group Input Flags\n");
9906 memset(&cwd
, 0, sizeof(cwd
));
9909 for (ALL_LIST_ELEMENTS_RO(pim_vxlan_p
->work_list
, node
, vxlan_sg
))
9910 pim_show_vxlan_sg_entry(vxlan_sg
, &cwd
);
9913 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9914 json
, JSON_C_TO_STRING_PRETTY
));
9915 json_object_free(json
);
9919 DEFUN_HIDDEN (show_ip_pim_vxlan_sg_work
,
9920 show_ip_pim_vxlan_sg_work_cmd
,
9921 "show ip pim [vrf NAME] vxlan-work [json]",
9929 bool uj
= use_json(argc
, argv
);
9933 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
9938 pim_show_vxlan_sg_work(vrf
->info
, vty
, uj
);
9943 DEFUN_HIDDEN (no_ip_pim_mlag
,
9951 struct in_addr addr
;
9954 pim_vxlan_mlag_update(TRUE
/*mlag_enable*/,
9955 FALSE
/*peer_state*/, PIM_VXLAN_MLAG_ROLE_SECONDARY
,
9956 NULL
/*peerlink*/, &addr
);
9961 DEFUN_HIDDEN (ip_pim_mlag
,
9963 "ip pim mlag INTERFACE role [primary|secondary] state [up|down] addr A.B.C.D",
9967 "peerlink sub interface\n"
9969 "MLAG role primary\n"
9970 "MLAG role secondary\n"
9971 "peer session state\n"
9972 "peer session state up\n"
9973 "peer session state down\n"
9975 "unique ip address\n")
9977 struct interface
*ifp
;
9978 const char *peerlink
;
9983 struct in_addr reg_addr
;
9986 peerlink
= argv
[idx
]->arg
;
9987 ifp
= if_lookup_by_name(peerlink
, VRF_DEFAULT
);
9989 vty_out(vty
, "No such interface name %s\n", peerlink
);
9994 if (!strcmp(argv
[idx
]->arg
, "primary")) {
9995 role
= PIM_VXLAN_MLAG_ROLE_PRIMARY
;
9996 } else if (!strcmp(argv
[idx
]->arg
, "secondary")) {
9997 role
= PIM_VXLAN_MLAG_ROLE_SECONDARY
;
9999 vty_out(vty
, "unknown MLAG role %s\n", argv
[idx
]->arg
);
10000 return CMD_WARNING
;
10004 if (!strcmp(argv
[idx
]->arg
, "up")) {
10006 } else if (strcmp(argv
[idx
]->arg
, "down")) {
10007 peer_state
= FALSE
;
10009 vty_out(vty
, "unknown MLAG state %s\n", argv
[idx
]->arg
);
10010 return CMD_WARNING
;
10014 result
= inet_pton(AF_INET
, argv
[idx
]->arg
, ®_addr
);
10016 vty_out(vty
, "%% Bad reg address %s: errno=%d: %s\n",
10018 errno
, safe_strerror(errno
));
10019 return CMD_WARNING_CONFIG_FAILED
;
10021 pim_vxlan_mlag_update(TRUE
, peer_state
, role
, ifp
, ®_addr
);
10023 return CMD_SUCCESS
;
10026 void pim_cmd_init(void)
10028 install_node(&interface_node
,
10029 pim_interface_config_write
); /* INTERFACE_NODE */
10032 install_node(&debug_node
, pim_debug_config_write
);
10034 install_element(ENABLE_NODE
, &pim_test_sg_keepalive_cmd
);
10036 install_element(CONFIG_NODE
, &ip_pim_rp_cmd
);
10037 install_element(VRF_NODE
, &ip_pim_rp_cmd
);
10038 install_element(CONFIG_NODE
, &no_ip_pim_rp_cmd
);
10039 install_element(VRF_NODE
, &no_ip_pim_rp_cmd
);
10040 install_element(CONFIG_NODE
, &ip_pim_rp_prefix_list_cmd
);
10041 install_element(VRF_NODE
, &ip_pim_rp_prefix_list_cmd
);
10042 install_element(CONFIG_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
10043 install_element(VRF_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
10044 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
10045 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
10046 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
10047 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
10048 install_element(CONFIG_NODE
, &ip_pim_ssm_prefix_list_cmd
);
10049 install_element(VRF_NODE
, &ip_pim_ssm_prefix_list_cmd
);
10050 install_element(CONFIG_NODE
, &ip_pim_register_suppress_cmd
);
10051 install_element(VRF_NODE
, &ip_pim_register_suppress_cmd
);
10052 install_element(CONFIG_NODE
, &no_ip_pim_register_suppress_cmd
);
10053 install_element(VRF_NODE
, &no_ip_pim_register_suppress_cmd
);
10054 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
10055 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
10056 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
10057 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
10058 install_element(CONFIG_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
10059 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
10060 install_element(CONFIG_NODE
,
10061 &no_ip_pim_spt_switchover_infinity_plist_cmd
);
10062 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_plist_cmd
);
10063 install_element(CONFIG_NODE
, &ip_pim_joinprune_time_cmd
);
10064 install_element(VRF_NODE
, &ip_pim_joinprune_time_cmd
);
10065 install_element(CONFIG_NODE
, &no_ip_pim_joinprune_time_cmd
);
10066 install_element(VRF_NODE
, &no_ip_pim_joinprune_time_cmd
);
10067 install_element(CONFIG_NODE
, &ip_pim_keep_alive_cmd
);
10068 install_element(VRF_NODE
, &ip_pim_keep_alive_cmd
);
10069 install_element(CONFIG_NODE
, &ip_pim_rp_keep_alive_cmd
);
10070 install_element(VRF_NODE
, &ip_pim_rp_keep_alive_cmd
);
10071 install_element(CONFIG_NODE
, &no_ip_pim_keep_alive_cmd
);
10072 install_element(VRF_NODE
, &no_ip_pim_keep_alive_cmd
);
10073 install_element(CONFIG_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
10074 install_element(VRF_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
10075 install_element(CONFIG_NODE
, &ip_pim_packets_cmd
);
10076 install_element(VRF_NODE
, &ip_pim_packets_cmd
);
10077 install_element(CONFIG_NODE
, &no_ip_pim_packets_cmd
);
10078 install_element(VRF_NODE
, &no_ip_pim_packets_cmd
);
10079 install_element(CONFIG_NODE
, &ip_pim_v6_secondary_cmd
);
10080 install_element(VRF_NODE
, &ip_pim_v6_secondary_cmd
);
10081 install_element(CONFIG_NODE
, &no_ip_pim_v6_secondary_cmd
);
10082 install_element(VRF_NODE
, &no_ip_pim_v6_secondary_cmd
);
10083 install_element(CONFIG_NODE
, &ip_ssmpingd_cmd
);
10084 install_element(VRF_NODE
, &ip_ssmpingd_cmd
);
10085 install_element(CONFIG_NODE
, &no_ip_ssmpingd_cmd
);
10086 install_element(VRF_NODE
, &no_ip_ssmpingd_cmd
);
10087 install_element(CONFIG_NODE
, &ip_msdp_peer_cmd
);
10088 install_element(VRF_NODE
, &ip_msdp_peer_cmd
);
10089 install_element(CONFIG_NODE
, &no_ip_msdp_peer_cmd
);
10090 install_element(VRF_NODE
, &no_ip_msdp_peer_cmd
);
10091 install_element(CONFIG_NODE
, &ip_pim_ecmp_cmd
);
10092 install_element(VRF_NODE
, &ip_pim_ecmp_cmd
);
10093 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_cmd
);
10094 install_element(VRF_NODE
, &no_ip_pim_ecmp_cmd
);
10095 install_element(CONFIG_NODE
, &ip_pim_ecmp_rebalance_cmd
);
10096 install_element(VRF_NODE
, &ip_pim_ecmp_rebalance_cmd
);
10097 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
10098 install_element(VRF_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
10099 install_element(CONFIG_NODE
, &ip_pim_mlag_cmd
);
10100 install_element(CONFIG_NODE
, &no_ip_pim_mlag_cmd
);
10102 install_element(INTERFACE_NODE
, &interface_ip_igmp_cmd
);
10103 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_cmd
);
10104 install_element(INTERFACE_NODE
, &interface_ip_igmp_join_cmd
);
10105 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_join_cmd
);
10106 install_element(INTERFACE_NODE
, &interface_ip_igmp_version_cmd
);
10107 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_version_cmd
);
10108 install_element(INTERFACE_NODE
, &interface_ip_igmp_query_interval_cmd
);
10109 install_element(INTERFACE_NODE
,
10110 &interface_no_ip_igmp_query_interval_cmd
);
10111 install_element(INTERFACE_NODE
,
10112 &interface_ip_igmp_query_max_response_time_cmd
);
10113 install_element(INTERFACE_NODE
,
10114 &interface_no_ip_igmp_query_max_response_time_cmd
);
10115 install_element(INTERFACE_NODE
,
10116 &interface_ip_igmp_query_max_response_time_dsec_cmd
);
10117 install_element(INTERFACE_NODE
,
10118 &interface_no_ip_igmp_query_max_response_time_dsec_cmd
);
10119 install_element(INTERFACE_NODE
, &interface_ip_pim_activeactive_cmd
);
10120 install_element(INTERFACE_NODE
, &interface_ip_pim_ssm_cmd
);
10121 install_element(INTERFACE_NODE
, &interface_no_ip_pim_ssm_cmd
);
10122 install_element(INTERFACE_NODE
, &interface_ip_pim_sm_cmd
);
10123 install_element(INTERFACE_NODE
, &interface_no_ip_pim_sm_cmd
);
10124 install_element(INTERFACE_NODE
, &interface_ip_pim_cmd
);
10125 install_element(INTERFACE_NODE
, &interface_no_ip_pim_cmd
);
10126 install_element(INTERFACE_NODE
, &interface_ip_pim_drprio_cmd
);
10127 install_element(INTERFACE_NODE
, &interface_no_ip_pim_drprio_cmd
);
10128 install_element(INTERFACE_NODE
, &interface_ip_pim_hello_cmd
);
10129 install_element(INTERFACE_NODE
, &interface_no_ip_pim_hello_cmd
);
10130 install_element(INTERFACE_NODE
, &interface_ip_pim_boundary_oil_cmd
);
10131 install_element(INTERFACE_NODE
, &interface_no_ip_pim_boundary_oil_cmd
);
10133 // Static mroutes NEB
10134 install_element(INTERFACE_NODE
, &interface_ip_mroute_cmd
);
10135 install_element(INTERFACE_NODE
, &interface_ip_mroute_source_cmd
);
10136 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_cmd
);
10137 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_source_cmd
);
10139 install_element(VIEW_NODE
, &show_ip_igmp_interface_cmd
);
10140 install_element(VIEW_NODE
, &show_ip_igmp_interface_vrf_all_cmd
);
10141 install_element(VIEW_NODE
, &show_ip_igmp_join_cmd
);
10142 install_element(VIEW_NODE
, &show_ip_igmp_join_vrf_all_cmd
);
10143 install_element(VIEW_NODE
, &show_ip_igmp_groups_cmd
);
10144 install_element(VIEW_NODE
, &show_ip_igmp_groups_vrf_all_cmd
);
10145 install_element(VIEW_NODE
, &show_ip_igmp_groups_retransmissions_cmd
);
10146 install_element(VIEW_NODE
, &show_ip_igmp_sources_cmd
);
10147 install_element(VIEW_NODE
, &show_ip_igmp_sources_retransmissions_cmd
);
10148 install_element(VIEW_NODE
, &show_ip_igmp_statistics_cmd
);
10149 install_element(VIEW_NODE
, &show_ip_pim_assert_cmd
);
10150 install_element(VIEW_NODE
, &show_ip_pim_assert_internal_cmd
);
10151 install_element(VIEW_NODE
, &show_ip_pim_assert_metric_cmd
);
10152 install_element(VIEW_NODE
, &show_ip_pim_assert_winner_metric_cmd
);
10153 install_element(VIEW_NODE
, &show_ip_pim_interface_traffic_cmd
);
10154 install_element(VIEW_NODE
, &show_ip_pim_interface_cmd
);
10155 install_element(VIEW_NODE
, &show_ip_pim_interface_vrf_all_cmd
);
10156 install_element(VIEW_NODE
, &show_ip_pim_join_cmd
);
10157 install_element(VIEW_NODE
, &show_ip_pim_join_vrf_all_cmd
);
10158 install_element(VIEW_NODE
, &show_ip_pim_local_membership_cmd
);
10159 install_element(VIEW_NODE
, &show_ip_pim_neighbor_cmd
);
10160 install_element(VIEW_NODE
, &show_ip_pim_neighbor_vrf_all_cmd
);
10161 install_element(VIEW_NODE
, &show_ip_pim_rpf_cmd
);
10162 install_element(VIEW_NODE
, &show_ip_pim_rpf_vrf_all_cmd
);
10163 install_element(VIEW_NODE
, &show_ip_pim_secondary_cmd
);
10164 install_element(VIEW_NODE
, &show_ip_pim_state_cmd
);
10165 install_element(VIEW_NODE
, &show_ip_pim_state_vrf_all_cmd
);
10166 install_element(VIEW_NODE
, &show_ip_pim_upstream_cmd
);
10167 install_element(VIEW_NODE
, &show_ip_pim_upstream_vrf_all_cmd
);
10168 install_element(VIEW_NODE
, &show_ip_pim_upstream_join_desired_cmd
);
10169 install_element(VIEW_NODE
, &show_ip_pim_upstream_rpf_cmd
);
10170 install_element(VIEW_NODE
, &show_ip_pim_rp_cmd
);
10171 install_element(VIEW_NODE
, &show_ip_pim_rp_vrf_all_cmd
);
10172 install_element(VIEW_NODE
, &show_ip_pim_bsr_cmd
);
10173 install_element(VIEW_NODE
, &show_ip_multicast_cmd
);
10174 install_element(VIEW_NODE
, &show_ip_multicast_vrf_all_cmd
);
10175 install_element(VIEW_NODE
, &show_ip_mroute_cmd
);
10176 install_element(VIEW_NODE
, &show_ip_mroute_vrf_all_cmd
);
10177 install_element(VIEW_NODE
, &show_ip_mroute_count_cmd
);
10178 install_element(VIEW_NODE
, &show_ip_mroute_count_vrf_all_cmd
);
10179 install_element(VIEW_NODE
, &show_ip_mroute_summary_cmd
);
10180 install_element(VIEW_NODE
, &show_ip_mroute_summary_vrf_all_cmd
);
10181 install_element(VIEW_NODE
, &show_ip_rib_cmd
);
10182 install_element(VIEW_NODE
, &show_ip_ssmpingd_cmd
);
10183 install_element(VIEW_NODE
, &show_debugging_pim_cmd
);
10184 install_element(VIEW_NODE
, &show_ip_pim_nexthop_cmd
);
10185 install_element(VIEW_NODE
, &show_ip_pim_nexthop_lookup_cmd
);
10186 install_element(VIEW_NODE
, &show_ip_pim_bsrp_cmd
);
10187 install_element(VIEW_NODE
, &show_ip_pim_bsm_db_cmd
);
10188 install_element(VIEW_NODE
, &show_ip_pim_statistics_cmd
);
10190 install_element(ENABLE_NODE
, &clear_ip_interfaces_cmd
);
10191 install_element(ENABLE_NODE
, &clear_ip_igmp_interfaces_cmd
);
10192 install_element(ENABLE_NODE
, &clear_ip_mroute_cmd
);
10193 install_element(ENABLE_NODE
, &clear_ip_pim_interfaces_cmd
);
10194 install_element(ENABLE_NODE
, &clear_ip_pim_interface_traffic_cmd
);
10195 install_element(ENABLE_NODE
, &clear_ip_pim_oil_cmd
);
10196 install_element(ENABLE_NODE
, &clear_ip_pim_statistics_cmd
);
10198 install_element(ENABLE_NODE
, &debug_igmp_cmd
);
10199 install_element(ENABLE_NODE
, &no_debug_igmp_cmd
);
10200 install_element(ENABLE_NODE
, &debug_igmp_events_cmd
);
10201 install_element(ENABLE_NODE
, &no_debug_igmp_events_cmd
);
10202 install_element(ENABLE_NODE
, &debug_igmp_packets_cmd
);
10203 install_element(ENABLE_NODE
, &no_debug_igmp_packets_cmd
);
10204 install_element(ENABLE_NODE
, &debug_igmp_trace_cmd
);
10205 install_element(ENABLE_NODE
, &no_debug_igmp_trace_cmd
);
10206 install_element(ENABLE_NODE
, &debug_mroute_cmd
);
10207 install_element(ENABLE_NODE
, &debug_mroute_detail_cmd
);
10208 install_element(ENABLE_NODE
, &no_debug_mroute_cmd
);
10209 install_element(ENABLE_NODE
, &no_debug_mroute_detail_cmd
);
10210 install_element(ENABLE_NODE
, &debug_pim_static_cmd
);
10211 install_element(ENABLE_NODE
, &no_debug_pim_static_cmd
);
10212 install_element(ENABLE_NODE
, &debug_pim_cmd
);
10213 install_element(ENABLE_NODE
, &no_debug_pim_cmd
);
10214 install_element(ENABLE_NODE
, &debug_pim_nht_cmd
);
10215 install_element(ENABLE_NODE
, &no_debug_pim_nht_cmd
);
10216 install_element(ENABLE_NODE
, &debug_pim_nht_rp_cmd
);
10217 install_element(ENABLE_NODE
, &no_debug_pim_nht_rp_cmd
);
10218 install_element(ENABLE_NODE
, &debug_pim_events_cmd
);
10219 install_element(ENABLE_NODE
, &no_debug_pim_events_cmd
);
10220 install_element(ENABLE_NODE
, &debug_pim_packets_cmd
);
10221 install_element(ENABLE_NODE
, &no_debug_pim_packets_cmd
);
10222 install_element(ENABLE_NODE
, &debug_pim_packetdump_send_cmd
);
10223 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_send_cmd
);
10224 install_element(ENABLE_NODE
, &debug_pim_packetdump_recv_cmd
);
10225 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_recv_cmd
);
10226 install_element(ENABLE_NODE
, &debug_pim_trace_cmd
);
10227 install_element(ENABLE_NODE
, &no_debug_pim_trace_cmd
);
10228 install_element(ENABLE_NODE
, &debug_pim_trace_detail_cmd
);
10229 install_element(ENABLE_NODE
, &no_debug_pim_trace_detail_cmd
);
10230 install_element(ENABLE_NODE
, &debug_ssmpingd_cmd
);
10231 install_element(ENABLE_NODE
, &no_debug_ssmpingd_cmd
);
10232 install_element(ENABLE_NODE
, &debug_pim_zebra_cmd
);
10233 install_element(ENABLE_NODE
, &no_debug_pim_zebra_cmd
);
10234 install_element(ENABLE_NODE
, &debug_pim_vxlan_cmd
);
10235 install_element(ENABLE_NODE
, &no_debug_pim_vxlan_cmd
);
10236 install_element(ENABLE_NODE
, &debug_msdp_cmd
);
10237 install_element(ENABLE_NODE
, &no_debug_msdp_cmd
);
10238 install_element(ENABLE_NODE
, &debug_msdp_events_cmd
);
10239 install_element(ENABLE_NODE
, &no_debug_msdp_events_cmd
);
10240 install_element(ENABLE_NODE
, &debug_msdp_packets_cmd
);
10241 install_element(ENABLE_NODE
, &no_debug_msdp_packets_cmd
);
10242 install_element(ENABLE_NODE
, &debug_mtrace_cmd
);
10243 install_element(ENABLE_NODE
, &no_debug_mtrace_cmd
);
10244 install_element(ENABLE_NODE
, &debug_bsm_cmd
);
10245 install_element(ENABLE_NODE
, &no_debug_bsm_cmd
);
10247 install_element(CONFIG_NODE
, &debug_igmp_cmd
);
10248 install_element(CONFIG_NODE
, &no_debug_igmp_cmd
);
10249 install_element(CONFIG_NODE
, &debug_igmp_events_cmd
);
10250 install_element(CONFIG_NODE
, &no_debug_igmp_events_cmd
);
10251 install_element(CONFIG_NODE
, &debug_igmp_packets_cmd
);
10252 install_element(CONFIG_NODE
, &no_debug_igmp_packets_cmd
);
10253 install_element(CONFIG_NODE
, &debug_igmp_trace_cmd
);
10254 install_element(CONFIG_NODE
, &no_debug_igmp_trace_cmd
);
10255 install_element(CONFIG_NODE
, &debug_mroute_cmd
);
10256 install_element(CONFIG_NODE
, &debug_mroute_detail_cmd
);
10257 install_element(CONFIG_NODE
, &no_debug_mroute_cmd
);
10258 install_element(CONFIG_NODE
, &no_debug_mroute_detail_cmd
);
10259 install_element(CONFIG_NODE
, &debug_pim_static_cmd
);
10260 install_element(CONFIG_NODE
, &no_debug_pim_static_cmd
);
10261 install_element(CONFIG_NODE
, &debug_pim_cmd
);
10262 install_element(CONFIG_NODE
, &no_debug_pim_cmd
);
10263 install_element(CONFIG_NODE
, &debug_pim_nht_cmd
);
10264 install_element(CONFIG_NODE
, &no_debug_pim_nht_cmd
);
10265 install_element(CONFIG_NODE
, &debug_pim_nht_rp_cmd
);
10266 install_element(CONFIG_NODE
, &no_debug_pim_nht_rp_cmd
);
10267 install_element(CONFIG_NODE
, &debug_pim_events_cmd
);
10268 install_element(CONFIG_NODE
, &no_debug_pim_events_cmd
);
10269 install_element(CONFIG_NODE
, &debug_pim_packets_cmd
);
10270 install_element(CONFIG_NODE
, &no_debug_pim_packets_cmd
);
10271 install_element(CONFIG_NODE
, &debug_pim_trace_cmd
);
10272 install_element(CONFIG_NODE
, &no_debug_pim_trace_cmd
);
10273 install_element(CONFIG_NODE
, &debug_pim_trace_detail_cmd
);
10274 install_element(CONFIG_NODE
, &no_debug_pim_trace_detail_cmd
);
10275 install_element(CONFIG_NODE
, &debug_ssmpingd_cmd
);
10276 install_element(CONFIG_NODE
, &no_debug_ssmpingd_cmd
);
10277 install_element(CONFIG_NODE
, &debug_pim_zebra_cmd
);
10278 install_element(CONFIG_NODE
, &no_debug_pim_zebra_cmd
);
10279 install_element(CONFIG_NODE
, &debug_pim_vxlan_cmd
);
10280 install_element(CONFIG_NODE
, &no_debug_pim_vxlan_cmd
);
10281 install_element(CONFIG_NODE
, &debug_msdp_cmd
);
10282 install_element(CONFIG_NODE
, &no_debug_msdp_cmd
);
10283 install_element(CONFIG_NODE
, &debug_msdp_events_cmd
);
10284 install_element(CONFIG_NODE
, &no_debug_msdp_events_cmd
);
10285 install_element(CONFIG_NODE
, &debug_msdp_packets_cmd
);
10286 install_element(CONFIG_NODE
, &no_debug_msdp_packets_cmd
);
10287 install_element(CONFIG_NODE
, &debug_mtrace_cmd
);
10288 install_element(CONFIG_NODE
, &no_debug_mtrace_cmd
);
10289 install_element(CONFIG_NODE
, &debug_bsm_cmd
);
10290 install_element(CONFIG_NODE
, &no_debug_bsm_cmd
);
10292 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_member_cmd
);
10293 install_element(VRF_NODE
, &ip_msdp_mesh_group_member_cmd
);
10294 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
10295 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
10296 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_source_cmd
);
10297 install_element(VRF_NODE
, &ip_msdp_mesh_group_source_cmd
);
10298 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
10299 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
10300 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_cmd
);
10301 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_vrf_all_cmd
);
10302 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_cmd
);
10303 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_vrf_all_cmd
);
10304 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_cmd
);
10305 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_vrf_all_cmd
);
10306 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_cmd
);
10307 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_vrf_all_cmd
);
10308 install_element(VIEW_NODE
, &show_ip_pim_ssm_range_cmd
);
10309 install_element(VIEW_NODE
, &show_ip_pim_group_type_cmd
);
10310 install_element(VIEW_NODE
, &show_ip_pim_vxlan_sg_cmd
);
10311 install_element(VIEW_NODE
, &show_ip_pim_vxlan_sg_work_cmd
);
10312 install_element(INTERFACE_NODE
, &interface_pim_use_source_cmd
);
10313 install_element(INTERFACE_NODE
, &interface_no_pim_use_source_cmd
);
10314 /* Install BSM command */
10315 install_element(INTERFACE_NODE
, &ip_pim_bsm_cmd
);
10316 install_element(INTERFACE_NODE
, &no_ip_pim_bsm_cmd
);
10317 install_element(INTERFACE_NODE
, &ip_pim_ucast_bsm_cmd
);
10318 install_element(INTERFACE_NODE
, &no_ip_pim_ucast_bsm_cmd
);
10319 /* Install BFD command */
10320 install_element(INTERFACE_NODE
, &ip_pim_bfd_cmd
);
10321 install_element(INTERFACE_NODE
, &ip_pim_bfd_param_cmd
);
10322 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_cmd
);
10324 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_param_cmd
);
10325 #endif /* !HAVE_BFDD */