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 strcpy(in_ifname
, ifp_in
->name
);
2006 strcpy(in_ifname
, "<iif?>");
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 strcpy(out_ifname
, ifp_out
->name
);
2090 strcpy(out_ifname
, "<oif?>");
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
,
2371 switch (join_state
) {
2372 case PIM_UPSTREAM_NOTJOINED
:
2373 strcpy(state_str
, "NotJ");
2375 case PIM_UPSTREAM_JOINED
:
2376 strcpy(state_str
, "J");
2379 strcpy(state_str
, "Unk");
2384 static const char *pim_reg_state2brief_str(enum pim_reg_state reg_state
,
2387 switch (reg_state
) {
2388 case PIM_REG_NOINFO
:
2389 strcpy(state_str
, "RegNI");
2392 strcpy(state_str
, "RegJ");
2394 case PIM_REG_JOIN_PENDING
:
2396 strcpy(state_str
, "RegP");
2399 strcpy(state_str
, "Unk");
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
);
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
,
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
));
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 strcpy(in_ifname
, ifp_in
->name
);
5239 strcpy(in_ifname
, "<iif?>");
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 strcpy(out_ifname
, ifp_out
->name
);
5296 strcpy(out_ifname
, "<oif?>");
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 strcpy(proto
, "PIM");
5357 if (c_oil
->oif_flags
[oif_vif_index
]
5358 & PIM_OIF_FLAG_PROTO_IGMP
) {
5359 strcpy(proto
, "IGMP");
5362 if (c_oil
->oif_flags
[oif_vif_index
]
5363 & PIM_OIF_FLAG_PROTO_VXLAN
) {
5364 strcpy(proto
, "VxLAN");
5367 if (c_oil
->oif_flags
[oif_vif_index
]
5368 & PIM_OIF_FLAG_PROTO_SOURCE
) {
5369 strcpy(proto
, "SRC");
5372 if (c_oil
->oif_flags
[oif_vif_index
]
5373 & PIM_OIF_FLAG_PROTO_STAR
) {
5374 strcpy(proto
, "STAR");
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 strcpy(in_ifname
, ifp_in
->name
);
5415 strcpy(in_ifname
, "<iif?>");
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 strcpy(proto
, "STATIC");
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 strcpy(out_ifname
, ifp_out
->name
);
5466 strcpy(out_ifname
, "<oif?>");
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");
5710 "show ip rib [vrf NAME] A.B.C.D",
5715 "Unicast address\n")
5718 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5719 struct in_addr addr
;
5720 const char *addr_str
;
5721 struct pim_nexthop nexthop
;
5722 char nexthop_addr_str
[PREFIX_STRLEN
];
5728 memset(&nexthop
, 0, sizeof(nexthop
));
5729 argv_find(argv
, argc
, "A.B.C.D", &idx
);
5730 addr_str
= argv
[idx
]->arg
;
5731 result
= inet_pton(AF_INET
, addr_str
, &addr
);
5733 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
5734 errno
, safe_strerror(errno
));
5738 if (!pim_nexthop_lookup(vrf
->info
, &nexthop
, addr
, 0)) {
5740 "Failure querying RIB nexthop for unicast address %s\n",
5746 "Address NextHop Interface Metric Preference\n");
5748 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
5749 nexthop_addr_str
, sizeof(nexthop_addr_str
));
5751 vty_out(vty
, "%-15s %-15s %-9s %6d %10d\n", addr_str
, nexthop_addr_str
,
5752 nexthop
.interface
? nexthop
.interface
->name
: "<ifname?>",
5753 nexthop
.mrib_route_metric
, nexthop
.mrib_metric_preference
);
5758 static void show_ssmpingd(struct pim_instance
*pim
, struct vty
*vty
)
5760 struct listnode
*node
;
5761 struct ssmpingd_sock
*ss
;
5765 "Source Socket Address Port Uptime Requests\n");
5767 if (!pim
->ssmpingd_list
)
5770 now
= pim_time_monotonic_sec();
5772 for (ALL_LIST_ELEMENTS_RO(pim
->ssmpingd_list
, node
, ss
)) {
5773 char source_str
[INET_ADDRSTRLEN
];
5775 struct sockaddr_in bind_addr
;
5776 socklen_t len
= sizeof(bind_addr
);
5777 char bind_addr_str
[INET_ADDRSTRLEN
];
5779 pim_inet4_dump("<src?>", ss
->source_addr
, source_str
,
5780 sizeof(source_str
));
5782 if (pim_socket_getsockname(
5783 ss
->sock_fd
, (struct sockaddr
*)&bind_addr
, &len
)) {
5785 "%% Failure reading socket name for ssmpingd source %s on fd=%d\n",
5786 source_str
, ss
->sock_fd
);
5789 pim_inet4_dump("<addr?>", bind_addr
.sin_addr
, bind_addr_str
,
5790 sizeof(bind_addr_str
));
5791 pim_time_uptime(ss_uptime
, sizeof(ss_uptime
),
5792 now
- ss
->creation
);
5794 vty_out(vty
, "%-15s %6d %-15s %5d %8s %8lld\n", source_str
,
5795 ss
->sock_fd
, bind_addr_str
, ntohs(bind_addr
.sin_port
),
5796 ss_uptime
, (long long)ss
->requests
);
5800 DEFUN (show_ip_ssmpingd
,
5801 show_ip_ssmpingd_cmd
,
5802 "show ip ssmpingd [vrf NAME]",
5809 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5814 show_ssmpingd(vrf
->info
, vty
);
5818 static int pim_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
5819 const char *rp
, const char *group
,
5824 result
= pim_rp_new_config(pim
, rp
, group
, plist
);
5826 if (result
== PIM_GROUP_BAD_ADDR_MASK_COMBO
) {
5827 vty_out(vty
, "%% Inconsistent address and mask: %s\n",
5829 return CMD_WARNING_CONFIG_FAILED
;
5832 if (result
== PIM_GROUP_BAD_ADDRESS
) {
5833 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
5834 return CMD_WARNING_CONFIG_FAILED
;
5837 if (result
== PIM_RP_BAD_ADDRESS
) {
5838 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
5839 return CMD_WARNING_CONFIG_FAILED
;
5842 if (result
== PIM_RP_NO_PATH
) {
5843 vty_out(vty
, "%% No Path to RP address specified: %s\n", rp
);
5847 if (result
== PIM_GROUP_OVERLAP
) {
5849 "%% Group range specified cannot exact match another\n");
5850 return CMD_WARNING_CONFIG_FAILED
;
5853 if (result
== PIM_GROUP_PFXLIST_OVERLAP
) {
5855 "%% This group is already covered by a RP prefix-list\n");
5856 return CMD_WARNING_CONFIG_FAILED
;
5859 if (result
== PIM_RP_PFXLIST_IN_USE
) {
5861 "%% The same prefix-list cannot be applied to multiple RPs\n");
5862 return CMD_WARNING_CONFIG_FAILED
;
5865 if (result
== PIM_GROUP_BAD_ADDR_MASK_COMBO
) {
5866 vty_out(vty
, "%% Inconsistent address and mask: %s\n",
5868 return CMD_WARNING_CONFIG_FAILED
;
5874 static int pim_cmd_spt_switchover(struct pim_instance
*pim
,
5875 enum pim_spt_switchover spt
,
5878 pim
->spt
.switchover
= spt
;
5880 switch (pim
->spt
.switchover
) {
5881 case PIM_SPT_IMMEDIATE
:
5882 XFREE(MTYPE_PIM_SPT_PLIST_NAME
, pim
->spt
.plist
);
5884 pim_upstream_add_lhr_star_pimreg(pim
);
5886 case PIM_SPT_INFINITY
:
5887 pim_upstream_remove_lhr_star_pimreg(pim
, plist
);
5889 XFREE(MTYPE_PIM_SPT_PLIST_NAME
, pim
->spt
.plist
);
5893 XSTRDUP(MTYPE_PIM_SPT_PLIST_NAME
, plist
);
5900 DEFUN (ip_pim_spt_switchover_infinity
,
5901 ip_pim_spt_switchover_infinity_cmd
,
5902 "ip pim spt-switchover infinity-and-beyond",
5906 "Never switch to SPT Tree\n")
5908 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5909 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, NULL
);
5912 DEFUN (ip_pim_spt_switchover_infinity_plist
,
5913 ip_pim_spt_switchover_infinity_plist_cmd
,
5914 "ip pim spt-switchover infinity-and-beyond prefix-list WORD",
5918 "Never switch to SPT Tree\n"
5919 "Prefix-List to control which groups to switch\n"
5920 "Prefix-List name\n")
5922 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5923 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, argv
[5]->arg
);
5926 DEFUN (no_ip_pim_spt_switchover_infinity
,
5927 no_ip_pim_spt_switchover_infinity_cmd
,
5928 "no ip pim spt-switchover infinity-and-beyond",
5933 "Never switch to SPT Tree\n")
5935 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5936 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
5939 DEFUN (no_ip_pim_spt_switchover_infinity_plist
,
5940 no_ip_pim_spt_switchover_infinity_plist_cmd
,
5941 "no ip pim spt-switchover infinity-and-beyond prefix-list WORD",
5946 "Never switch to SPT Tree\n"
5947 "Prefix-List to control which groups to switch\n"
5948 "Prefix-List name\n")
5950 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5951 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
5954 DEFUN (ip_pim_joinprune_time
,
5955 ip_pim_joinprune_time_cmd
,
5956 "ip pim join-prune-interval (60-600)",
5958 "pim multicast routing\n"
5959 "Join Prune Send Interval\n"
5962 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5963 router
->t_periodic
= atoi(argv
[3]->arg
);
5967 DEFUN (no_ip_pim_joinprune_time
,
5968 no_ip_pim_joinprune_time_cmd
,
5969 "no ip pim join-prune-interval (60-600)",
5972 "pim multicast routing\n"
5973 "Join Prune Send Interval\n"
5976 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5977 router
->t_periodic
= PIM_DEFAULT_T_PERIODIC
;
5981 DEFUN (ip_pim_register_suppress
,
5982 ip_pim_register_suppress_cmd
,
5983 "ip pim register-suppress-time (5-60000)",
5985 "pim multicast routing\n"
5986 "Register Suppress Timer\n"
5989 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5990 router
->register_suppress_time
= atoi(argv
[3]->arg
);
5994 DEFUN (no_ip_pim_register_suppress
,
5995 no_ip_pim_register_suppress_cmd
,
5996 "no ip pim register-suppress-time (5-60000)",
5999 "pim multicast routing\n"
6000 "Register Suppress Timer\n"
6003 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6004 router
->register_suppress_time
= PIM_REGISTER_SUPPRESSION_TIME_DEFAULT
;
6008 DEFUN (ip_pim_rp_keep_alive
,
6009 ip_pim_rp_keep_alive_cmd
,
6010 "ip pim rp keep-alive-timer (31-60000)",
6012 "pim multicast routing\n"
6014 "Keep alive Timer\n"
6017 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6018 pim
->rp_keep_alive_time
= atoi(argv
[4]->arg
);
6022 DEFUN (no_ip_pim_rp_keep_alive
,
6023 no_ip_pim_rp_keep_alive_cmd
,
6024 "no ip pim rp keep-alive-timer (31-60000)",
6027 "pim multicast routing\n"
6029 "Keep alive Timer\n"
6032 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6033 pim
->rp_keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
6037 DEFUN (ip_pim_keep_alive
,
6038 ip_pim_keep_alive_cmd
,
6039 "ip pim keep-alive-timer (31-60000)",
6041 "pim multicast routing\n"
6042 "Keep alive Timer\n"
6045 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6046 pim
->keep_alive_time
= atoi(argv
[3]->arg
);
6050 DEFUN (no_ip_pim_keep_alive
,
6051 no_ip_pim_keep_alive_cmd
,
6052 "no ip pim keep-alive-timer (31-60000)",
6055 "pim multicast routing\n"
6056 "Keep alive Timer\n"
6059 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6060 pim
->keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
6064 DEFUN (ip_pim_packets
,
6066 "ip pim packets (1-100)",
6068 "pim multicast routing\n"
6069 "packets to process at one time per fd\n"
6070 "Number of packets\n")
6072 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6073 router
->packet_process
= atoi(argv
[3]->arg
);
6077 DEFUN (no_ip_pim_packets
,
6078 no_ip_pim_packets_cmd
,
6079 "no ip pim packets (1-100)",
6082 "pim multicast routing\n"
6083 "packets to process at one time per fd\n"
6084 "Number of packets\n")
6086 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6087 router
->packet_process
= PIM_DEFAULT_PACKET_PROCESS
;
6091 DEFUN (ip_pim_v6_secondary
,
6092 ip_pim_v6_secondary_cmd
,
6093 "ip pim send-v6-secondary",
6095 "pim multicast routing\n"
6096 "Send v6 secondary addresses\n")
6098 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6099 pim
->send_v6_secondary
= 1;
6104 DEFUN (no_ip_pim_v6_secondary
,
6105 no_ip_pim_v6_secondary_cmd
,
6106 "no ip pim send-v6-secondary",
6109 "pim multicast routing\n"
6110 "Send v6 secondary addresses\n")
6112 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6113 pim
->send_v6_secondary
= 0;
6120 "ip pim rp A.B.C.D [A.B.C.D/M]",
6122 "pim multicast routing\n"
6124 "ip address of RP\n"
6125 "Group Address range to cover\n")
6127 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6130 if (argc
== (idx_ipv4
+ 1))
6131 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
6134 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
6135 argv
[idx_ipv4
+ 1]->arg
, NULL
);
6138 DEFUN (ip_pim_rp_prefix_list
,
6139 ip_pim_rp_prefix_list_cmd
,
6140 "ip pim rp A.B.C.D prefix-list WORD",
6142 "pim multicast routing\n"
6144 "ip address of RP\n"
6145 "group prefix-list filter\n"
6146 "Name of a prefix-list\n")
6148 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6149 return pim_rp_cmd_worker(pim
, vty
, argv
[3]->arg
, NULL
, argv
[5]->arg
);
6152 static int pim_no_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
6153 const char *rp
, const char *group
,
6156 int result
= pim_rp_del_config(pim
, rp
, group
, plist
);
6158 if (result
== PIM_GROUP_BAD_ADDRESS
) {
6159 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
6160 return CMD_WARNING_CONFIG_FAILED
;
6163 if (result
== PIM_RP_BAD_ADDRESS
) {
6164 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
6165 return CMD_WARNING_CONFIG_FAILED
;
6168 if (result
== PIM_RP_NOT_FOUND
) {
6169 vty_out(vty
, "%% Unable to find specified RP\n");
6170 return CMD_WARNING_CONFIG_FAILED
;
6176 DEFUN (no_ip_pim_rp
,
6178 "no ip pim rp A.B.C.D [A.B.C.D/M]",
6181 "pim multicast routing\n"
6183 "ip address of RP\n"
6184 "Group Address range to cover\n")
6186 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6187 int idx_ipv4
= 4, idx_group
= 0;
6189 if (argv_find(argv
, argc
, "A.B.C.D/M", &idx_group
))
6190 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
6191 argv
[idx_group
]->arg
, NULL
);
6193 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
6197 DEFUN (no_ip_pim_rp_prefix_list
,
6198 no_ip_pim_rp_prefix_list_cmd
,
6199 "no ip pim rp A.B.C.D prefix-list WORD",
6202 "pim multicast routing\n"
6204 "ip address of RP\n"
6205 "group prefix-list filter\n"
6206 "Name of a prefix-list\n")
6208 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6209 return pim_no_rp_cmd_worker(pim
, vty
, argv
[4]->arg
, NULL
, argv
[6]->arg
);
6212 static int pim_ssm_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
6215 int result
= pim_ssm_range_set(pim
, pim
->vrf_id
, plist
);
6217 if (result
== PIM_SSM_ERR_NONE
)
6221 case PIM_SSM_ERR_NO_VRF
:
6222 vty_out(vty
, "%% VRF doesn't exist\n");
6224 case PIM_SSM_ERR_DUP
:
6225 vty_out(vty
, "%% duplicate config\n");
6228 vty_out(vty
, "%% ssm range config failed\n");
6231 return CMD_WARNING_CONFIG_FAILED
;
6234 DEFUN (ip_pim_ssm_prefix_list
,
6235 ip_pim_ssm_prefix_list_cmd
,
6236 "ip pim ssm prefix-list WORD",
6238 "pim multicast routing\n"
6239 "Source Specific Multicast\n"
6240 "group range prefix-list filter\n"
6241 "Name of a prefix-list\n")
6243 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6244 return pim_ssm_cmd_worker(pim
, vty
, argv
[4]->arg
);
6247 DEFUN (no_ip_pim_ssm_prefix_list
,
6248 no_ip_pim_ssm_prefix_list_cmd
,
6249 "no ip pim ssm prefix-list",
6252 "pim multicast routing\n"
6253 "Source Specific Multicast\n"
6254 "group range prefix-list filter\n")
6256 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6257 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
6260 DEFUN (no_ip_pim_ssm_prefix_list_name
,
6261 no_ip_pim_ssm_prefix_list_name_cmd
,
6262 "no ip pim ssm prefix-list WORD",
6265 "pim multicast routing\n"
6266 "Source Specific Multicast\n"
6267 "group range prefix-list filter\n"
6268 "Name of a prefix-list\n")
6270 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6271 struct pim_ssm
*ssm
= pim
->ssm_info
;
6273 if (ssm
->plist_name
&& !strcmp(ssm
->plist_name
, argv
[5]->arg
))
6274 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
6276 vty_out(vty
, "%% pim ssm prefix-list %s doesn't exist\n", argv
[5]->arg
);
6278 return CMD_WARNING_CONFIG_FAILED
;
6281 static void ip_pim_ssm_show_group_range(struct pim_instance
*pim
,
6282 struct vty
*vty
, bool uj
)
6284 struct pim_ssm
*ssm
= pim
->ssm_info
;
6285 const char *range_str
=
6286 ssm
->plist_name
? ssm
->plist_name
: PIM_SSM_STANDARD_RANGE
;
6290 json
= json_object_new_object();
6291 json_object_string_add(json
, "ssmGroups", range_str
);
6292 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
6293 json
, JSON_C_TO_STRING_PRETTY
));
6294 json_object_free(json
);
6296 vty_out(vty
, "SSM group range : %s\n", range_str
);
6299 DEFUN (show_ip_pim_ssm_range
,
6300 show_ip_pim_ssm_range_cmd
,
6301 "show ip pim [vrf NAME] group-type [json]",
6310 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6311 bool uj
= use_json(argc
, argv
);
6316 ip_pim_ssm_show_group_range(vrf
->info
, vty
, uj
);
6321 static void ip_pim_ssm_show_group_type(struct pim_instance
*pim
,
6322 struct vty
*vty
, bool uj
,
6325 struct in_addr group_addr
;
6326 const char *type_str
;
6329 result
= inet_pton(AF_INET
, group
, &group_addr
);
6331 type_str
= "invalid";
6333 if (pim_is_group_224_4(group_addr
))
6335 pim_is_grp_ssm(pim
, group_addr
) ? "SSM" : "ASM";
6337 type_str
= "not-multicast";
6342 json
= json_object_new_object();
6343 json_object_string_add(json
, "groupType", type_str
);
6344 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
6345 json
, JSON_C_TO_STRING_PRETTY
));
6346 json_object_free(json
);
6348 vty_out(vty
, "Group type : %s\n", type_str
);
6351 DEFUN (show_ip_pim_group_type
,
6352 show_ip_pim_group_type_cmd
,
6353 "show ip pim [vrf NAME] group-type A.B.C.D [json]",
6358 "multicast group type\n"
6363 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6364 bool uj
= use_json(argc
, argv
);
6369 argv_find(argv
, argc
, "A.B.C.D", &idx
);
6370 ip_pim_ssm_show_group_type(vrf
->info
, vty
, uj
, argv
[idx
]->arg
);
6375 DEFUN (show_ip_pim_bsr
,
6376 show_ip_pim_bsr_cmd
,
6377 "show ip pim bsr [json]",
6381 "boot-strap router information\n"
6385 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6386 bool uj
= use_json(argc
, argv
);
6391 pim_show_bsr(vrf
->info
, vty
, uj
);
6398 "ip ssmpingd [A.B.C.D]",
6403 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6406 struct in_addr source_addr
;
6407 const char *source_str
= (argc
== 3) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
6409 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
6411 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
6412 source_str
, errno
, safe_strerror(errno
));
6413 return CMD_WARNING_CONFIG_FAILED
;
6416 result
= pim_ssmpingd_start(pim
, source_addr
);
6418 vty_out(vty
, "%% Failure starting ssmpingd for source %s: %d\n",
6419 source_str
, result
);
6420 return CMD_WARNING_CONFIG_FAILED
;
6426 DEFUN (no_ip_ssmpingd
,
6428 "no ip ssmpingd [A.B.C.D]",
6434 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6437 struct in_addr source_addr
;
6438 const char *source_str
= (argc
== 4) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
6440 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
6442 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
6443 source_str
, errno
, safe_strerror(errno
));
6444 return CMD_WARNING_CONFIG_FAILED
;
6447 result
= pim_ssmpingd_stop(pim
, source_addr
);
6449 vty_out(vty
, "%% Failure stopping ssmpingd for source %s: %d\n",
6450 source_str
, result
);
6451 return CMD_WARNING_CONFIG_FAILED
;
6461 "pim multicast routing\n"
6462 "Enable PIM ECMP \n")
6464 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6465 pim
->ecmp_enable
= true;
6470 DEFUN (no_ip_pim_ecmp
,
6475 "pim multicast routing\n"
6476 "Disable PIM ECMP \n")
6478 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6479 pim
->ecmp_enable
= false;
6484 DEFUN (ip_pim_ecmp_rebalance
,
6485 ip_pim_ecmp_rebalance_cmd
,
6486 "ip pim ecmp rebalance",
6488 "pim multicast routing\n"
6489 "Enable PIM ECMP \n"
6490 "Enable PIM ECMP Rebalance\n")
6492 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6493 pim
->ecmp_enable
= true;
6494 pim
->ecmp_rebalance_enable
= true;
6499 DEFUN (no_ip_pim_ecmp_rebalance
,
6500 no_ip_pim_ecmp_rebalance_cmd
,
6501 "no ip pim ecmp rebalance",
6504 "pim multicast routing\n"
6505 "Disable PIM ECMP \n"
6506 "Disable PIM ECMP Rebalance\n")
6508 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6509 pim
->ecmp_rebalance_enable
= false;
6514 static int pim_cmd_igmp_start(struct vty
*vty
, struct interface
*ifp
)
6516 struct pim_interface
*pim_ifp
;
6517 uint8_t need_startup
= 0;
6519 pim_ifp
= ifp
->info
;
6522 pim_ifp
= pim_if_new(ifp
, true, false, false,
6523 false /*vxlan_term*/);
6525 vty_out(vty
, "Could not enable IGMP on interface %s\n",
6527 return CMD_WARNING_CONFIG_FAILED
;
6531 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
6532 PIM_IF_DO_IGMP(pim_ifp
->options
);
6537 /* 'ip igmp' executed multiple times, with need_startup
6538 avoid multiple if add all and membership refresh */
6540 pim_if_addr_add_all(ifp
);
6541 pim_if_membership_refresh(ifp
);
6547 DEFUN (interface_ip_igmp
,
6548 interface_ip_igmp_cmd
,
6553 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6555 return pim_cmd_igmp_start(vty
, ifp
);
6558 DEFUN (interface_no_ip_igmp
,
6559 interface_no_ip_igmp_cmd
,
6565 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6566 struct pim_interface
*pim_ifp
= ifp
->info
;
6571 PIM_IF_DONT_IGMP(pim_ifp
->options
);
6573 pim_if_membership_clear(ifp
);
6575 pim_if_addr_del_all_igmp(ifp
);
6577 if (!PIM_IF_TEST_PIM(pim_ifp
->options
)) {
6584 DEFUN (interface_ip_igmp_join
,
6585 interface_ip_igmp_join_cmd
,
6586 "ip igmp join A.B.C.D A.B.C.D",
6589 "IGMP join multicast group\n"
6590 "Multicast group address\n"
6593 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6596 const char *group_str
;
6597 const char *source_str
;
6598 struct in_addr group_addr
;
6599 struct in_addr source_addr
;
6603 group_str
= argv
[idx_ipv4
]->arg
;
6604 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
6606 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
6607 errno
, safe_strerror(errno
));
6608 return CMD_WARNING_CONFIG_FAILED
;
6611 /* Source address */
6612 source_str
= argv
[idx_ipv4_2
]->arg
;
6613 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
6615 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
6616 source_str
, errno
, safe_strerror(errno
));
6617 return CMD_WARNING_CONFIG_FAILED
;
6620 CMD_FERR_RETURN(pim_if_igmp_join_add(ifp
, group_addr
, source_addr
),
6621 "Failure joining IGMP group: $ERR");
6626 DEFUN (interface_no_ip_igmp_join
,
6627 interface_no_ip_igmp_join_cmd
,
6628 "no ip igmp join A.B.C.D A.B.C.D",
6632 "IGMP join multicast group\n"
6633 "Multicast group address\n"
6636 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6639 const char *group_str
;
6640 const char *source_str
;
6641 struct in_addr group_addr
;
6642 struct in_addr source_addr
;
6646 group_str
= argv
[idx_ipv4
]->arg
;
6647 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
6649 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
6650 errno
, safe_strerror(errno
));
6651 return CMD_WARNING_CONFIG_FAILED
;
6654 /* Source address */
6655 source_str
= argv
[idx_ipv4_2
]->arg
;
6656 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
6658 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
6659 source_str
, errno
, safe_strerror(errno
));
6660 return CMD_WARNING_CONFIG_FAILED
;
6663 result
= pim_if_igmp_join_del(ifp
, group_addr
, source_addr
);
6666 "%% Failure leaving IGMP group %s source %s on interface %s: %d\n",
6667 group_str
, source_str
, ifp
->name
, result
);
6668 return CMD_WARNING_CONFIG_FAILED
;
6675 CLI reconfiguration affects the interface level (struct pim_interface).
6676 This function propagates the reconfiguration to every active socket
6679 static void igmp_sock_query_interval_reconfig(struct igmp_sock
*igmp
)
6681 struct interface
*ifp
;
6682 struct pim_interface
*pim_ifp
;
6686 /* other querier present? */
6688 if (igmp
->t_other_querier_timer
)
6691 /* this is the querier */
6693 zassert(igmp
->interface
);
6694 zassert(igmp
->interface
->info
);
6696 ifp
= igmp
->interface
;
6697 pim_ifp
= ifp
->info
;
6699 if (PIM_DEBUG_IGMP_TRACE
) {
6700 char ifaddr_str
[INET_ADDRSTRLEN
];
6701 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
6702 sizeof(ifaddr_str
));
6703 zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
6704 __PRETTY_FUNCTION__
, ifaddr_str
, ifp
->name
,
6705 pim_ifp
->igmp_default_query_interval
);
6709 igmp_startup_mode_on() will reset QQI:
6711 igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
6713 igmp_startup_mode_on(igmp
);
6716 static void igmp_sock_query_reschedule(struct igmp_sock
*igmp
)
6718 if (igmp
->t_igmp_query_timer
) {
6719 /* other querier present */
6720 zassert(igmp
->t_igmp_query_timer
);
6721 zassert(!igmp
->t_other_querier_timer
);
6723 pim_igmp_general_query_off(igmp
);
6724 pim_igmp_general_query_on(igmp
);
6726 zassert(igmp
->t_igmp_query_timer
);
6727 zassert(!igmp
->t_other_querier_timer
);
6729 /* this is the querier */
6731 zassert(!igmp
->t_igmp_query_timer
);
6732 zassert(igmp
->t_other_querier_timer
);
6734 pim_igmp_other_querier_timer_off(igmp
);
6735 pim_igmp_other_querier_timer_on(igmp
);
6737 zassert(!igmp
->t_igmp_query_timer
);
6738 zassert(igmp
->t_other_querier_timer
);
6742 static void change_query_interval(struct pim_interface
*pim_ifp
,
6745 struct listnode
*sock_node
;
6746 struct igmp_sock
*igmp
;
6748 pim_ifp
->igmp_default_query_interval
= query_interval
;
6750 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
6751 igmp_sock_query_interval_reconfig(igmp
);
6752 igmp_sock_query_reschedule(igmp
);
6756 static void change_query_max_response_time(struct pim_interface
*pim_ifp
,
6757 int query_max_response_time_dsec
)
6759 struct listnode
*sock_node
;
6760 struct igmp_sock
*igmp
;
6762 pim_ifp
->igmp_query_max_response_time_dsec
=
6763 query_max_response_time_dsec
;
6766 Below we modify socket/group/source timers in order to quickly
6767 reflect the change. Otherwise, those timers would eventually catch
6771 /* scan all sockets */
6772 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
6773 struct listnode
*grp_node
;
6774 struct igmp_group
*grp
;
6776 /* reschedule socket general query */
6777 igmp_sock_query_reschedule(igmp
);
6779 /* scan socket groups */
6780 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grp_node
,
6782 struct listnode
*src_node
;
6783 struct igmp_source
*src
;
6785 /* reset group timers for groups in EXCLUDE mode */
6786 if (grp
->group_filtermode_isexcl
) {
6787 igmp_group_reset_gmi(grp
);
6790 /* scan group sources */
6791 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
,
6794 /* reset source timers for sources with running
6796 if (src
->t_source_timer
) {
6797 igmp_source_reset_gmi(igmp
, grp
, src
);
6804 #define IGMP_QUERY_INTERVAL_MIN (1)
6805 #define IGMP_QUERY_INTERVAL_MAX (1800)
6807 DEFUN (interface_ip_igmp_query_interval
,
6808 interface_ip_igmp_query_interval_cmd
,
6809 "ip igmp query-interval (1-1800)",
6812 IFACE_IGMP_QUERY_INTERVAL_STR
6813 "Query interval in seconds\n")
6815 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6816 struct pim_interface
*pim_ifp
= ifp
->info
;
6818 int query_interval_dsec
;
6822 ret
= pim_cmd_igmp_start(vty
, ifp
);
6823 if (ret
!= CMD_SUCCESS
)
6825 pim_ifp
= ifp
->info
;
6828 query_interval
= atoi(argv
[3]->arg
);
6829 query_interval_dsec
= 10 * query_interval
;
6832 It seems we don't need to check bounds since command.c does it
6833 already, but we verify them anyway for extra safety.
6835 if (query_interval
< IGMP_QUERY_INTERVAL_MIN
) {
6837 "General query interval %d lower than minimum %d\n",
6838 query_interval
, IGMP_QUERY_INTERVAL_MIN
);
6839 return CMD_WARNING_CONFIG_FAILED
;
6841 if (query_interval
> IGMP_QUERY_INTERVAL_MAX
) {
6843 "General query interval %d higher than maximum %d\n",
6844 query_interval
, IGMP_QUERY_INTERVAL_MAX
);
6845 return CMD_WARNING_CONFIG_FAILED
;
6848 if (query_interval_dsec
<= pim_ifp
->igmp_query_max_response_time_dsec
) {
6850 "Can't set general query interval %d dsec <= query max response time %d dsec.\n",
6851 query_interval_dsec
,
6852 pim_ifp
->igmp_query_max_response_time_dsec
);
6853 return CMD_WARNING_CONFIG_FAILED
;
6856 change_query_interval(pim_ifp
, query_interval
);
6861 DEFUN (interface_no_ip_igmp_query_interval
,
6862 interface_no_ip_igmp_query_interval_cmd
,
6863 "no ip igmp query-interval",
6867 IFACE_IGMP_QUERY_INTERVAL_STR
)
6869 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6870 struct pim_interface
*pim_ifp
= ifp
->info
;
6871 int default_query_interval_dsec
;
6876 default_query_interval_dsec
= IGMP_GENERAL_QUERY_INTERVAL
* 10;
6878 if (default_query_interval_dsec
6879 <= pim_ifp
->igmp_query_max_response_time_dsec
) {
6881 "Can't set default general query interval %d dsec <= query max response time %d dsec.\n",
6882 default_query_interval_dsec
,
6883 pim_ifp
->igmp_query_max_response_time_dsec
);
6884 return CMD_WARNING_CONFIG_FAILED
;
6887 change_query_interval(pim_ifp
, IGMP_GENERAL_QUERY_INTERVAL
);
6892 DEFUN (interface_ip_igmp_version
,
6893 interface_ip_igmp_version_cmd
,
6894 "ip igmp version (2-3)",
6898 "IGMP version number\n")
6900 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6901 struct pim_interface
*pim_ifp
= ifp
->info
;
6902 int igmp_version
, old_version
= 0;
6906 ret
= pim_cmd_igmp_start(vty
, ifp
);
6907 if (ret
!= CMD_SUCCESS
)
6909 pim_ifp
= ifp
->info
;
6912 igmp_version
= atoi(argv
[3]->arg
);
6913 old_version
= pim_ifp
->igmp_version
;
6914 pim_ifp
->igmp_version
= igmp_version
;
6916 // Check if IGMP is Enabled otherwise, enable on interface
6917 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
6918 PIM_IF_DO_IGMP(pim_ifp
->options
);
6919 pim_if_addr_add_all(ifp
);
6920 pim_if_membership_refresh(ifp
);
6921 old_version
= igmp_version
;
6922 // avoid refreshing membership again.
6924 /* Current and new version is different refresh existing
6925 membership. Going from 3 -> 2 or 2 -> 3. */
6926 if (old_version
!= igmp_version
)
6927 pim_if_membership_refresh(ifp
);
6932 DEFUN (interface_no_ip_igmp_version
,
6933 interface_no_ip_igmp_version_cmd
,
6934 "no ip igmp version (2-3)",
6939 "IGMP version number\n")
6941 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6942 struct pim_interface
*pim_ifp
= ifp
->info
;
6947 pim_ifp
->igmp_version
= IGMP_DEFAULT_VERSION
;
6952 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
6953 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
6955 DEFUN (interface_ip_igmp_query_max_response_time
,
6956 interface_ip_igmp_query_max_response_time_cmd
,
6957 "ip igmp query-max-response-time (10-250)",
6960 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
6961 "Query response value in deci-seconds\n")
6963 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6964 struct pim_interface
*pim_ifp
= ifp
->info
;
6965 int query_max_response_time
;
6969 ret
= pim_cmd_igmp_start(vty
, ifp
);
6970 if (ret
!= CMD_SUCCESS
)
6972 pim_ifp
= ifp
->info
;
6975 query_max_response_time
= atoi(argv
[3]->arg
);
6977 if (query_max_response_time
6978 >= pim_ifp
->igmp_default_query_interval
* 10) {
6980 "Can't set query max response time %d sec >= general query interval %d sec\n",
6981 query_max_response_time
,
6982 pim_ifp
->igmp_default_query_interval
);
6983 return CMD_WARNING_CONFIG_FAILED
;
6986 change_query_max_response_time(pim_ifp
, query_max_response_time
);
6991 DEFUN (interface_no_ip_igmp_query_max_response_time
,
6992 interface_no_ip_igmp_query_max_response_time_cmd
,
6993 "no ip igmp query-max-response-time (10-250)",
6997 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
6998 "Time for response in deci-seconds\n")
7000 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7001 struct pim_interface
*pim_ifp
= ifp
->info
;
7006 change_query_max_response_time(pim_ifp
,
7007 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
7012 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
7013 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
7015 DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec
,
7016 interface_ip_igmp_query_max_response_time_dsec_cmd
,
7017 "ip igmp query-max-response-time-dsec (10-250)",
7020 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
7021 "Query response value in deciseconds\n")
7023 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7024 struct pim_interface
*pim_ifp
= ifp
->info
;
7025 int query_max_response_time_dsec
;
7026 int default_query_interval_dsec
;
7030 ret
= pim_cmd_igmp_start(vty
, ifp
);
7031 if (ret
!= CMD_SUCCESS
)
7033 pim_ifp
= ifp
->info
;
7036 query_max_response_time_dsec
= atoi(argv
[4]->arg
);
7038 default_query_interval_dsec
= 10 * pim_ifp
->igmp_default_query_interval
;
7040 if (query_max_response_time_dsec
>= default_query_interval_dsec
) {
7042 "Can't set query max response time %d dsec >= general query interval %d dsec\n",
7043 query_max_response_time_dsec
,
7044 default_query_interval_dsec
);
7045 return CMD_WARNING_CONFIG_FAILED
;
7048 change_query_max_response_time(pim_ifp
, query_max_response_time_dsec
);
7053 DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec
,
7054 interface_no_ip_igmp_query_max_response_time_dsec_cmd
,
7055 "no ip igmp query-max-response-time-dsec",
7059 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
)
7061 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7062 struct pim_interface
*pim_ifp
= ifp
->info
;
7067 change_query_max_response_time(pim_ifp
,
7068 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
7073 DEFUN (interface_ip_pim_drprio
,
7074 interface_ip_pim_drprio_cmd
,
7075 "ip pim drpriority (1-4294967295)",
7078 "Set the Designated Router Election Priority\n"
7079 "Value of the new DR Priority\n")
7081 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7083 struct pim_interface
*pim_ifp
= ifp
->info
;
7084 uint32_t old_dr_prio
;
7087 vty_out(vty
, "Please enable PIM on interface, first\n");
7088 return CMD_WARNING_CONFIG_FAILED
;
7091 old_dr_prio
= pim_ifp
->pim_dr_priority
;
7093 pim_ifp
->pim_dr_priority
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
7095 if (old_dr_prio
!= pim_ifp
->pim_dr_priority
) {
7096 pim_if_dr_election(ifp
);
7097 pim_hello_restart_now(ifp
);
7103 DEFUN (interface_no_ip_pim_drprio
,
7104 interface_no_ip_pim_drprio_cmd
,
7105 "no ip pim drpriority [(1-4294967295)]",
7109 "Revert the Designated Router Priority to default\n"
7110 "Old Value of the Priority\n")
7112 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7113 struct pim_interface
*pim_ifp
= ifp
->info
;
7116 vty_out(vty
, "Pim not enabled on this interface\n");
7117 return CMD_WARNING_CONFIG_FAILED
;
7120 if (pim_ifp
->pim_dr_priority
!= PIM_DEFAULT_DR_PRIORITY
) {
7121 pim_ifp
->pim_dr_priority
= PIM_DEFAULT_DR_PRIORITY
;
7122 pim_if_dr_election(ifp
);
7123 pim_hello_restart_now(ifp
);
7129 static int pim_cmd_interface_add(struct interface
*ifp
)
7131 struct pim_interface
*pim_ifp
= ifp
->info
;
7134 pim_ifp
= pim_if_new(ifp
, false, true, false,
7135 false /*vxlan_term*/);
7140 PIM_IF_DO_PIM(pim_ifp
->options
);
7143 pim_if_addr_add_all(ifp
);
7144 pim_if_membership_refresh(ifp
);
7148 DEFPY_HIDDEN (pim_test_sg_keepalive
,
7149 pim_test_sg_keepalive_cmd
,
7150 "test pim [vrf NAME$name] keepalive-reset A.B.C.D$source A.B.C.D$group",
7154 "Reset the Keepalive Timer\n"
7155 "The Source we are resetting\n"
7156 "The Group we are resetting\n")
7158 struct pim_upstream
*up
;
7159 struct pim_instance
*pim
;
7160 struct prefix_sg sg
;
7166 pim
= pim_get_pim_instance(VRF_DEFAULT
);
7168 struct vrf
*vrf
= vrf_lookup_by_name(name
);
7171 vty_out(vty
, "%% Vrf specified: %s does not exist\n",
7176 pim
= pim_get_pim_instance(vrf
->vrf_id
);
7180 vty_out(vty
, "%% Unable to find pim instance\n");
7184 up
= pim_upstream_find(pim
, &sg
);
7186 vty_out(vty
, "%% Unable to find %s specified\n",
7187 pim_str_sg_dump(&sg
));
7191 vty_out(vty
, "Setting %s to current keep alive time: %d\n",
7192 pim_str_sg_dump(&sg
), pim
->keep_alive_time
);
7193 pim_upstream_keep_alive_timer_start(up
, pim
->keep_alive_time
);
7198 DEFPY_HIDDEN (interface_ip_pim_activeactive
,
7199 interface_ip_pim_activeactive_cmd
,
7200 "[no$no] ip pim active-active",
7204 "Mark interface as Active-Active for MLAG operations, Hidden because not finished yet\n")
7206 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7207 struct pim_interface
*pim_ifp
;
7209 if (!no
&& !pim_cmd_interface_add(ifp
)) {
7210 vty_out(vty
, "Could not enable PIM SM active-active on interface\n");
7211 return CMD_WARNING_CONFIG_FAILED
;
7214 pim_ifp
= ifp
->info
;
7216 pim_ifp
->activeactive
= false;
7218 pim_ifp
->activeactive
= true;
7223 DEFUN_HIDDEN (interface_ip_pim_ssm
,
7224 interface_ip_pim_ssm_cmd
,
7230 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7232 if (!pim_cmd_interface_add(ifp
)) {
7233 vty_out(vty
, "Could not enable PIM SM on interface\n");
7234 return CMD_WARNING_CONFIG_FAILED
;
7238 "WARN: Enabled PIM SM on interface; configure PIM SSM "
7239 "range if needed\n");
7243 static int interface_ip_pim_helper(struct vty
*vty
)
7245 struct pim_interface
*pim_ifp
;
7247 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7249 if (!pim_cmd_interface_add(ifp
)) {
7250 vty_out(vty
, "Could not enable PIM SM on interface\n");
7251 return CMD_WARNING_CONFIG_FAILED
;
7254 pim_ifp
= ifp
->info
;
7256 pim_if_create_pimreg(pim_ifp
->pim
);
7261 DEFUN_HIDDEN (interface_ip_pim_sm
,
7262 interface_ip_pim_sm_cmd
,
7268 return interface_ip_pim_helper(vty
);
7271 DEFUN (interface_ip_pim
,
7272 interface_ip_pim_cmd
,
7277 return interface_ip_pim_helper(vty
);
7280 static int pim_cmd_interface_delete(struct interface
*ifp
)
7282 struct pim_interface
*pim_ifp
= ifp
->info
;
7287 PIM_IF_DONT_PIM(pim_ifp
->options
);
7289 pim_if_membership_clear(ifp
);
7292 pim_sock_delete() removes all neighbors from
7293 pim_ifp->pim_neighbor_list.
7295 pim_sock_delete(ifp
, "pim unconfigured on interface");
7297 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
7298 pim_if_addr_del_all(ifp
);
7305 static int interface_no_ip_pim_helper(struct vty
*vty
)
7307 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7308 if (!pim_cmd_interface_delete(ifp
)) {
7309 vty_out(vty
, "Unable to delete interface information\n");
7310 return CMD_WARNING_CONFIG_FAILED
;
7316 DEFUN_HIDDEN (interface_no_ip_pim_ssm
,
7317 interface_no_ip_pim_ssm_cmd
,
7324 return interface_no_ip_pim_helper(vty
);
7327 DEFUN_HIDDEN (interface_no_ip_pim_sm
,
7328 interface_no_ip_pim_sm_cmd
,
7335 return interface_no_ip_pim_helper(vty
);
7338 DEFUN (interface_no_ip_pim
,
7339 interface_no_ip_pim_cmd
,
7345 return interface_no_ip_pim_helper(vty
);
7349 DEFUN(interface_ip_pim_boundary_oil
,
7350 interface_ip_pim_boundary_oil_cmd
,
7351 "ip multicast boundary oil WORD",
7353 "Generic multicast configuration options\n"
7354 "Define multicast boundary\n"
7355 "Filter OIL by group using prefix list\n"
7356 "Prefix list to filter OIL with\n")
7358 VTY_DECLVAR_CONTEXT(interface
, iif
);
7359 struct pim_interface
*pim_ifp
;
7362 argv_find(argv
, argc
, "WORD", &idx
);
7364 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
7366 if (pim_ifp
->boundary_oil_plist
)
7367 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
7369 pim_ifp
->boundary_oil_plist
=
7370 XSTRDUP(MTYPE_PIM_INTERFACE
, argv
[idx
]->arg
);
7372 /* Interface will be pruned from OIL on next Join */
7376 DEFUN(interface_no_ip_pim_boundary_oil
,
7377 interface_no_ip_pim_boundary_oil_cmd
,
7378 "no ip multicast boundary oil [WORD]",
7381 "Generic multicast configuration options\n"
7382 "Define multicast boundary\n"
7383 "Filter OIL by group using prefix list\n"
7384 "Prefix list to filter OIL with\n")
7386 VTY_DECLVAR_CONTEXT(interface
, iif
);
7387 struct pim_interface
*pim_ifp
;
7390 argv_find(argv
, argc
, "WORD", &idx
);
7392 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
7394 if (pim_ifp
->boundary_oil_plist
)
7395 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
7400 DEFUN (interface_ip_mroute
,
7401 interface_ip_mroute_cmd
,
7402 "ip mroute INTERFACE A.B.C.D",
7404 "Add multicast route\n"
7405 "Outgoing interface name\n"
7408 VTY_DECLVAR_CONTEXT(interface
, iif
);
7409 struct pim_interface
*pim_ifp
;
7410 struct pim_instance
*pim
;
7411 int idx_interface
= 2;
7413 struct interface
*oif
;
7414 const char *oifname
;
7415 const char *grp_str
;
7416 struct in_addr grp_addr
;
7417 struct in_addr src_addr
;
7420 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
7423 oifname
= argv
[idx_interface
]->arg
;
7424 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
7426 vty_out(vty
, "No such interface name %s\n", oifname
);
7430 grp_str
= argv
[idx_ipv4
]->arg
;
7431 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
7433 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
7434 errno
, safe_strerror(errno
));
7438 src_addr
.s_addr
= INADDR_ANY
;
7440 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
7441 vty_out(vty
, "Failed to add route\n");
7448 DEFUN (interface_ip_mroute_source
,
7449 interface_ip_mroute_source_cmd
,
7450 "ip mroute INTERFACE A.B.C.D A.B.C.D",
7452 "Add multicast route\n"
7453 "Outgoing interface name\n"
7457 VTY_DECLVAR_CONTEXT(interface
, iif
);
7458 struct pim_interface
*pim_ifp
;
7459 struct pim_instance
*pim
;
7460 int idx_interface
= 2;
7463 struct interface
*oif
;
7464 const char *oifname
;
7465 const char *grp_str
;
7466 struct in_addr grp_addr
;
7467 const char *src_str
;
7468 struct in_addr src_addr
;
7471 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
7474 oifname
= argv
[idx_interface
]->arg
;
7475 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
7477 vty_out(vty
, "No such interface name %s\n", oifname
);
7481 grp_str
= argv
[idx_ipv4
]->arg
;
7482 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
7484 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
7485 errno
, safe_strerror(errno
));
7489 src_str
= argv
[idx_ipv4_2
]->arg
;
7490 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
7492 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
7493 errno
, safe_strerror(errno
));
7497 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
7498 vty_out(vty
, "Failed to add route\n");
7505 DEFUN (interface_no_ip_mroute
,
7506 interface_no_ip_mroute_cmd
,
7507 "no ip mroute INTERFACE A.B.C.D",
7510 "Add multicast route\n"
7511 "Outgoing interface name\n"
7514 VTY_DECLVAR_CONTEXT(interface
, iif
);
7515 struct pim_interface
*pim_ifp
;
7516 struct pim_instance
*pim
;
7517 int idx_interface
= 3;
7519 struct interface
*oif
;
7520 const char *oifname
;
7521 const char *grp_str
;
7522 struct in_addr grp_addr
;
7523 struct in_addr src_addr
;
7526 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
7529 oifname
= argv
[idx_interface
]->arg
;
7530 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
7532 vty_out(vty
, "No such interface name %s\n", oifname
);
7536 grp_str
= argv
[idx_ipv4
]->arg
;
7537 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
7539 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
7540 errno
, safe_strerror(errno
));
7544 src_addr
.s_addr
= INADDR_ANY
;
7546 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
7547 vty_out(vty
, "Failed to remove route\n");
7554 DEFUN (interface_no_ip_mroute_source
,
7555 interface_no_ip_mroute_source_cmd
,
7556 "no ip mroute INTERFACE A.B.C.D A.B.C.D",
7559 "Add multicast route\n"
7560 "Outgoing interface name\n"
7564 VTY_DECLVAR_CONTEXT(interface
, iif
);
7565 struct pim_interface
*pim_ifp
;
7566 struct pim_instance
*pim
;
7567 int idx_interface
= 3;
7570 struct interface
*oif
;
7571 const char *oifname
;
7572 const char *grp_str
;
7573 struct in_addr grp_addr
;
7574 const char *src_str
;
7575 struct in_addr src_addr
;
7578 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
7581 oifname
= argv
[idx_interface
]->arg
;
7582 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
7584 vty_out(vty
, "No such interface name %s\n", oifname
);
7588 grp_str
= argv
[idx_ipv4
]->arg
;
7589 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
7591 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
7592 errno
, safe_strerror(errno
));
7596 src_str
= argv
[idx_ipv4_2
]->arg
;
7597 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
7599 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
7600 errno
, safe_strerror(errno
));
7604 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
7605 vty_out(vty
, "Failed to remove route\n");
7612 DEFUN (interface_ip_pim_hello
,
7613 interface_ip_pim_hello_cmd
,
7614 "ip pim hello (1-180) [(1-180)]",
7618 IFACE_PIM_HELLO_TIME_STR
7619 IFACE_PIM_HELLO_HOLD_STR
)
7621 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7624 struct pim_interface
*pim_ifp
= ifp
->info
;
7627 if (!pim_cmd_interface_add(ifp
)) {
7628 vty_out(vty
, "Could not enable PIM SM on interface\n");
7629 return CMD_WARNING_CONFIG_FAILED
;
7633 pim_ifp
= ifp
->info
;
7634 pim_ifp
->pim_hello_period
= strtol(argv
[idx_time
]->arg
, NULL
, 10);
7636 if (argc
== idx_hold
+ 1)
7637 pim_ifp
->pim_default_holdtime
=
7638 strtol(argv
[idx_hold
]->arg
, NULL
, 10);
7643 DEFUN (interface_no_ip_pim_hello
,
7644 interface_no_ip_pim_hello_cmd
,
7645 "no ip pim hello [(1-180) (1-180)]",
7650 IFACE_PIM_HELLO_TIME_STR
7651 IFACE_PIM_HELLO_HOLD_STR
)
7653 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7654 struct pim_interface
*pim_ifp
= ifp
->info
;
7657 vty_out(vty
, "Pim not enabled on this interface\n");
7658 return CMD_WARNING_CONFIG_FAILED
;
7661 pim_ifp
->pim_hello_period
= PIM_DEFAULT_HELLO_PERIOD
;
7662 pim_ifp
->pim_default_holdtime
= -1;
7673 PIM_DO_DEBUG_IGMP_EVENTS
;
7674 PIM_DO_DEBUG_IGMP_PACKETS
;
7675 PIM_DO_DEBUG_IGMP_TRACE
;
7679 DEFUN (no_debug_igmp
,
7686 PIM_DONT_DEBUG_IGMP_EVENTS
;
7687 PIM_DONT_DEBUG_IGMP_PACKETS
;
7688 PIM_DONT_DEBUG_IGMP_TRACE
;
7693 DEFUN (debug_igmp_events
,
7694 debug_igmp_events_cmd
,
7695 "debug igmp events",
7698 DEBUG_IGMP_EVENTS_STR
)
7700 PIM_DO_DEBUG_IGMP_EVENTS
;
7704 DEFUN (no_debug_igmp_events
,
7705 no_debug_igmp_events_cmd
,
7706 "no debug igmp events",
7710 DEBUG_IGMP_EVENTS_STR
)
7712 PIM_DONT_DEBUG_IGMP_EVENTS
;
7717 DEFUN (debug_igmp_packets
,
7718 debug_igmp_packets_cmd
,
7719 "debug igmp packets",
7722 DEBUG_IGMP_PACKETS_STR
)
7724 PIM_DO_DEBUG_IGMP_PACKETS
;
7728 DEFUN (no_debug_igmp_packets
,
7729 no_debug_igmp_packets_cmd
,
7730 "no debug igmp packets",
7734 DEBUG_IGMP_PACKETS_STR
)
7736 PIM_DONT_DEBUG_IGMP_PACKETS
;
7741 DEFUN (debug_igmp_trace
,
7742 debug_igmp_trace_cmd
,
7746 DEBUG_IGMP_TRACE_STR
)
7748 PIM_DO_DEBUG_IGMP_TRACE
;
7752 DEFUN (no_debug_igmp_trace
,
7753 no_debug_igmp_trace_cmd
,
7754 "no debug igmp trace",
7758 DEBUG_IGMP_TRACE_STR
)
7760 PIM_DONT_DEBUG_IGMP_TRACE
;
7765 DEFUN (debug_mroute
,
7771 PIM_DO_DEBUG_MROUTE
;
7775 DEFUN (debug_mroute_detail
,
7776 debug_mroute_detail_cmd
,
7777 "debug mroute detail",
7782 PIM_DO_DEBUG_MROUTE_DETAIL
;
7786 DEFUN (no_debug_mroute
,
7787 no_debug_mroute_cmd
,
7793 PIM_DONT_DEBUG_MROUTE
;
7797 DEFUN (no_debug_mroute_detail
,
7798 no_debug_mroute_detail_cmd
,
7799 "no debug mroute detail",
7805 PIM_DONT_DEBUG_MROUTE_DETAIL
;
7809 DEFUN (debug_pim_static
,
7810 debug_pim_static_cmd
,
7816 PIM_DO_DEBUG_STATIC
;
7820 DEFUN (no_debug_pim_static
,
7821 no_debug_pim_static_cmd
,
7822 "no debug pim static",
7828 PIM_DONT_DEBUG_STATIC
;
7839 PIM_DO_DEBUG_PIM_EVENTS
;
7840 PIM_DO_DEBUG_PIM_PACKETS
;
7841 PIM_DO_DEBUG_PIM_TRACE
;
7842 PIM_DO_DEBUG_MSDP_EVENTS
;
7843 PIM_DO_DEBUG_MSDP_PACKETS
;
7848 DEFUN (no_debug_pim
,
7855 PIM_DONT_DEBUG_PIM_EVENTS
;
7856 PIM_DONT_DEBUG_PIM_PACKETS
;
7857 PIM_DONT_DEBUG_PIM_TRACE
;
7858 PIM_DONT_DEBUG_MSDP_EVENTS
;
7859 PIM_DONT_DEBUG_MSDP_PACKETS
;
7861 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
7862 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
7868 DEFUN (debug_pim_nht
,
7873 "Nexthop Tracking\n")
7875 PIM_DO_DEBUG_PIM_NHT
;
7879 DEFUN (no_debug_pim_nht
,
7880 no_debug_pim_nht_cmd
,
7885 "Nexthop Tracking\n")
7887 PIM_DONT_DEBUG_PIM_NHT
;
7891 DEFUN (debug_pim_nht_rp
,
7892 debug_pim_nht_rp_cmd
,
7896 "Nexthop Tracking\n"
7897 "RP Nexthop Tracking\n")
7899 PIM_DO_DEBUG_PIM_NHT_RP
;
7903 DEFUN (no_debug_pim_nht_rp
,
7904 no_debug_pim_nht_rp_cmd
,
7905 "no debug pim nht rp",
7909 "Nexthop Tracking\n"
7910 "RP Nexthop Tracking\n")
7912 PIM_DONT_DEBUG_PIM_NHT_RP
;
7916 DEFUN (debug_pim_events
,
7917 debug_pim_events_cmd
,
7921 DEBUG_PIM_EVENTS_STR
)
7923 PIM_DO_DEBUG_PIM_EVENTS
;
7927 DEFUN (no_debug_pim_events
,
7928 no_debug_pim_events_cmd
,
7929 "no debug pim events",
7933 DEBUG_PIM_EVENTS_STR
)
7935 PIM_DONT_DEBUG_PIM_EVENTS
;
7939 DEFUN (debug_pim_packets
,
7940 debug_pim_packets_cmd
,
7941 "debug pim packets [<hello|joins|register>]",
7944 DEBUG_PIM_PACKETS_STR
7945 DEBUG_PIM_HELLO_PACKETS_STR
7946 DEBUG_PIM_J_P_PACKETS_STR
7947 DEBUG_PIM_PIM_REG_PACKETS_STR
)
7950 if (argv_find(argv
, argc
, "hello", &idx
)) {
7951 PIM_DO_DEBUG_PIM_HELLO
;
7952 vty_out(vty
, "PIM Hello debugging is on\n");
7953 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
7954 PIM_DO_DEBUG_PIM_J_P
;
7955 vty_out(vty
, "PIM Join/Prune debugging is on\n");
7956 } else if (argv_find(argv
, argc
, "register", &idx
)) {
7957 PIM_DO_DEBUG_PIM_REG
;
7958 vty_out(vty
, "PIM Register debugging is on\n");
7960 PIM_DO_DEBUG_PIM_PACKETS
;
7961 vty_out(vty
, "PIM Packet debugging is on \n");
7966 DEFUN (no_debug_pim_packets
,
7967 no_debug_pim_packets_cmd
,
7968 "no debug pim packets [<hello|joins|register>]",
7972 DEBUG_PIM_PACKETS_STR
7973 DEBUG_PIM_HELLO_PACKETS_STR
7974 DEBUG_PIM_J_P_PACKETS_STR
7975 DEBUG_PIM_PIM_REG_PACKETS_STR
)
7978 if (argv_find(argv
, argc
, "hello", &idx
)) {
7979 PIM_DONT_DEBUG_PIM_HELLO
;
7980 vty_out(vty
, "PIM Hello debugging is off \n");
7981 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
7982 PIM_DONT_DEBUG_PIM_J_P
;
7983 vty_out(vty
, "PIM Join/Prune debugging is off \n");
7984 } else if (argv_find(argv
, argc
, "register", &idx
)) {
7985 PIM_DONT_DEBUG_PIM_REG
;
7986 vty_out(vty
, "PIM Register debugging is off\n");
7988 PIM_DONT_DEBUG_PIM_PACKETS
;
7994 DEFUN (debug_pim_packetdump_send
,
7995 debug_pim_packetdump_send_cmd
,
7996 "debug pim packet-dump send",
7999 DEBUG_PIM_PACKETDUMP_STR
8000 DEBUG_PIM_PACKETDUMP_SEND_STR
)
8002 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND
;
8006 DEFUN (no_debug_pim_packetdump_send
,
8007 no_debug_pim_packetdump_send_cmd
,
8008 "no debug pim packet-dump send",
8012 DEBUG_PIM_PACKETDUMP_STR
8013 DEBUG_PIM_PACKETDUMP_SEND_STR
)
8015 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
8019 DEFUN (debug_pim_packetdump_recv
,
8020 debug_pim_packetdump_recv_cmd
,
8021 "debug pim packet-dump receive",
8024 DEBUG_PIM_PACKETDUMP_STR
8025 DEBUG_PIM_PACKETDUMP_RECV_STR
)
8027 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV
;
8031 DEFUN (no_debug_pim_packetdump_recv
,
8032 no_debug_pim_packetdump_recv_cmd
,
8033 "no debug pim packet-dump receive",
8037 DEBUG_PIM_PACKETDUMP_STR
8038 DEBUG_PIM_PACKETDUMP_RECV_STR
)
8040 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
8044 DEFUN (debug_pim_trace
,
8045 debug_pim_trace_cmd
,
8049 DEBUG_PIM_TRACE_STR
)
8051 PIM_DO_DEBUG_PIM_TRACE
;
8055 DEFUN (debug_pim_trace_detail
,
8056 debug_pim_trace_detail_cmd
,
8057 "debug pim trace detail",
8061 "Detailed Information\n")
8063 PIM_DO_DEBUG_PIM_TRACE_DETAIL
;
8067 DEFUN (no_debug_pim_trace
,
8068 no_debug_pim_trace_cmd
,
8069 "no debug pim trace",
8073 DEBUG_PIM_TRACE_STR
)
8075 PIM_DONT_DEBUG_PIM_TRACE
;
8079 DEFUN (no_debug_pim_trace_detail
,
8080 no_debug_pim_trace_detail_cmd
,
8081 "no debug pim trace detail",
8086 "Detailed Information\n")
8088 PIM_DONT_DEBUG_PIM_TRACE_DETAIL
;
8092 DEFUN (debug_ssmpingd
,
8098 PIM_DO_DEBUG_SSMPINGD
;
8102 DEFUN (no_debug_ssmpingd
,
8103 no_debug_ssmpingd_cmd
,
8104 "no debug ssmpingd",
8109 PIM_DONT_DEBUG_SSMPINGD
;
8113 DEFUN (debug_pim_zebra
,
8114 debug_pim_zebra_cmd
,
8118 DEBUG_PIM_ZEBRA_STR
)
8124 DEFUN (no_debug_pim_zebra
,
8125 no_debug_pim_zebra_cmd
,
8126 "no debug pim zebra",
8130 DEBUG_PIM_ZEBRA_STR
)
8132 PIM_DONT_DEBUG_ZEBRA
;
8136 DEFUN (debug_pim_vxlan
,
8137 debug_pim_vxlan_cmd
,
8141 DEBUG_PIM_VXLAN_STR
)
8147 DEFUN (no_debug_pim_vxlan
,
8148 no_debug_pim_vxlan_cmd
,
8149 "no debug pim vxlan",
8153 DEBUG_PIM_VXLAN_STR
)
8155 PIM_DONT_DEBUG_VXLAN
;
8165 PIM_DO_DEBUG_MSDP_EVENTS
;
8166 PIM_DO_DEBUG_MSDP_PACKETS
;
8170 DEFUN (no_debug_msdp
,
8177 PIM_DONT_DEBUG_MSDP_EVENTS
;
8178 PIM_DONT_DEBUG_MSDP_PACKETS
;
8182 DEFUN (debug_msdp_events
,
8183 debug_msdp_events_cmd
,
8184 "debug msdp events",
8187 DEBUG_MSDP_EVENTS_STR
)
8189 PIM_DO_DEBUG_MSDP_EVENTS
;
8193 DEFUN (no_debug_msdp_events
,
8194 no_debug_msdp_events_cmd
,
8195 "no debug msdp events",
8199 DEBUG_MSDP_EVENTS_STR
)
8201 PIM_DONT_DEBUG_MSDP_EVENTS
;
8205 DEFUN (debug_msdp_packets
,
8206 debug_msdp_packets_cmd
,
8207 "debug msdp packets",
8210 DEBUG_MSDP_PACKETS_STR
)
8212 PIM_DO_DEBUG_MSDP_PACKETS
;
8216 DEFUN (no_debug_msdp_packets
,
8217 no_debug_msdp_packets_cmd
,
8218 "no debug msdp packets",
8222 DEBUG_MSDP_PACKETS_STR
)
8224 PIM_DONT_DEBUG_MSDP_PACKETS
;
8228 DEFUN (debug_mtrace
,
8234 PIM_DO_DEBUG_MTRACE
;
8238 DEFUN (no_debug_mtrace
,
8239 no_debug_mtrace_cmd
,
8245 PIM_DONT_DEBUG_MTRACE
;
8260 DEFUN (no_debug_bsm
,
8273 DEFUN_NOSH (show_debugging_pim
,
8274 show_debugging_pim_cmd
,
8275 "show debugging [pim]",
8280 vty_out(vty
, "PIM debugging status\n");
8282 pim_debug_config_write(vty
);
8287 static int interface_pim_use_src_cmd_worker(struct vty
*vty
, const char *source
)
8290 struct in_addr source_addr
;
8291 int ret
= CMD_SUCCESS
;
8292 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8294 result
= inet_pton(AF_INET
, source
, &source_addr
);
8296 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", source
,
8297 errno
, safe_strerror(errno
));
8298 return CMD_WARNING_CONFIG_FAILED
;
8301 result
= pim_update_source_set(ifp
, source_addr
);
8305 case PIM_IFACE_NOT_FOUND
:
8306 ret
= CMD_WARNING_CONFIG_FAILED
;
8307 vty_out(vty
, "Pim not enabled on this interface\n");
8309 case PIM_UPDATE_SOURCE_DUP
:
8311 vty_out(vty
, "%% Source already set to %s\n", source
);
8314 ret
= CMD_WARNING_CONFIG_FAILED
;
8315 vty_out(vty
, "%% Source set failed\n");
8321 DEFUN (interface_pim_use_source
,
8322 interface_pim_use_source_cmd
,
8323 "ip pim use-source A.B.C.D",
8326 "Configure primary IP address\n"
8327 "source ip address\n")
8329 return interface_pim_use_src_cmd_worker(vty
, argv
[3]->arg
);
8332 DEFUN (interface_no_pim_use_source
,
8333 interface_no_pim_use_source_cmd
,
8334 "no ip pim use-source [A.B.C.D]",
8338 "Delete source IP address\n"
8339 "source ip address\n")
8341 return interface_pim_use_src_cmd_worker(vty
, "0.0.0.0");
8349 "Enables BFD support\n")
8351 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8352 struct pim_interface
*pim_ifp
= ifp
->info
;
8353 struct bfd_info
*bfd_info
= NULL
;
8356 if (!pim_cmd_interface_add(ifp
)) {
8357 vty_out(vty
, "Could not enable PIM SM on interface\n");
8361 pim_ifp
= ifp
->info
;
8363 bfd_info
= pim_ifp
->bfd_info
;
8365 if (!bfd_info
|| !CHECK_FLAG(bfd_info
->flags
, BFD_FLAG_PARAM_CFG
))
8366 pim_bfd_if_param_set(ifp
, BFD_DEF_MIN_RX
, BFD_DEF_MIN_TX
,
8367 BFD_DEF_DETECT_MULT
, 1);
8372 DEFUN (no_ip_pim_bfd
,
8378 "Disables BFD support\n")
8380 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8381 struct pim_interface
*pim_ifp
= ifp
->info
;
8384 vty_out(vty
, "Pim not enabled on this interface\n");
8388 if (pim_ifp
->bfd_info
) {
8389 pim_bfd_reg_dereg_all_nbr(ifp
, ZEBRA_BFD_DEST_DEREGISTER
);
8390 bfd_info_free(&(pim_ifp
->bfd_info
));
8401 "Enables BSM support on the interface\n")
8403 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8404 struct pim_interface
*pim_ifp
= ifp
->info
;
8407 if (!pim_cmd_interface_add(ifp
)) {
8408 vty_out(vty
, "Could not enable PIM SM on interface\n");
8413 pim_ifp
= ifp
->info
;
8414 pim_ifp
->bsm_enable
= true;
8419 DEFUN (no_ip_pim_bsm
,
8425 "Disables BSM support\n")
8427 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8428 struct pim_interface
*pim_ifp
= ifp
->info
;
8431 vty_out(vty
, "Pim not enabled on this interface\n");
8435 pim_ifp
->bsm_enable
= false;
8440 DEFUN (ip_pim_ucast_bsm
,
8441 ip_pim_ucast_bsm_cmd
,
8442 "ip pim unicast-bsm",
8445 "Accept/Send unicast BSM on the interface\n")
8447 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8448 struct pim_interface
*pim_ifp
= ifp
->info
;
8451 if (!pim_cmd_interface_add(ifp
)) {
8452 vty_out(vty
, "Could not enable PIM SM on interface\n");
8457 pim_ifp
= ifp
->info
;
8458 pim_ifp
->ucast_bsm_accept
= true;
8463 DEFUN (no_ip_pim_ucast_bsm
,
8464 no_ip_pim_ucast_bsm_cmd
,
8465 "no ip pim unicast-bsm",
8469 "Block send/receive unicast BSM on this interface\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 pim_ifp
->ucast_bsm_accept
= false;
8488 #endif /* HAVE_BFDD */
8490 ip_pim_bfd_param_cmd
,
8491 "ip pim bfd (2-255) (50-60000) (50-60000)",
8494 "Enables BFD support\n"
8495 "Detect Multiplier\n"
8496 "Required min receive interval\n"
8497 "Desired min transmit interval\n")
8499 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8501 int idx_number_2
= 4;
8502 int idx_number_3
= 5;
8507 struct pim_interface
*pim_ifp
= ifp
->info
;
8510 if (!pim_cmd_interface_add(ifp
)) {
8511 vty_out(vty
, "Could not enable PIM SM on interface\n");
8516 if ((ret
= bfd_validate_param(
8517 vty
, argv
[idx_number
]->arg
, argv
[idx_number_2
]->arg
,
8518 argv
[idx_number_3
]->arg
, &dm_val
, &rx_val
, &tx_val
))
8522 pim_bfd_if_param_set(ifp
, rx_val
, tx_val
, dm_val
, 0);
8528 ALIAS(no_ip_pim_bfd
, no_ip_pim_bfd_param_cmd
,
8529 "no ip pim bfd (2-255) (50-60000) (50-60000)", NO_STR IP_STR PIM_STR
8530 "Enables BFD support\n"
8531 "Detect Multiplier\n"
8532 "Required min receive interval\n"
8533 "Desired min transmit interval\n")
8534 #endif /* !HAVE_BFDD */
8536 static int ip_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
8537 const char *peer
, const char *local
)
8539 enum pim_msdp_err result
;
8540 struct in_addr peer_addr
;
8541 struct in_addr local_addr
;
8542 int ret
= CMD_SUCCESS
;
8544 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
8546 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
8547 errno
, safe_strerror(errno
));
8548 return CMD_WARNING_CONFIG_FAILED
;
8551 result
= inet_pton(AF_INET
, local
, &local_addr
);
8553 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", local
,
8554 errno
, safe_strerror(errno
));
8555 return CMD_WARNING_CONFIG_FAILED
;
8558 result
= pim_msdp_peer_add(pim
, peer_addr
, local_addr
, "default",
8561 case PIM_MSDP_ERR_NONE
:
8563 case PIM_MSDP_ERR_OOM
:
8564 ret
= CMD_WARNING_CONFIG_FAILED
;
8565 vty_out(vty
, "%% Out of memory\n");
8567 case PIM_MSDP_ERR_PEER_EXISTS
:
8569 vty_out(vty
, "%% Peer exists\n");
8571 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
8572 ret
= CMD_WARNING_CONFIG_FAILED
;
8573 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
8576 ret
= CMD_WARNING_CONFIG_FAILED
;
8577 vty_out(vty
, "%% peer add failed\n");
8583 DEFUN_HIDDEN (ip_msdp_peer
,
8585 "ip msdp peer A.B.C.D source A.B.C.D",
8588 "Configure MSDP peer\n"
8590 "Source address for TCP connection\n"
8591 "local ip address\n")
8593 PIM_DECLVAR_CONTEXT(vrf
, pim
);
8594 return ip_msdp_peer_cmd_worker(pim
, vty
, argv
[3]->arg
, argv
[5]->arg
);
8597 static int ip_no_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
8600 enum pim_msdp_err result
;
8601 struct in_addr peer_addr
;
8603 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
8605 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
8606 errno
, safe_strerror(errno
));
8607 return CMD_WARNING_CONFIG_FAILED
;
8610 result
= pim_msdp_peer_del(pim
, peer_addr
);
8612 case PIM_MSDP_ERR_NONE
:
8614 case PIM_MSDP_ERR_NO_PEER
:
8615 vty_out(vty
, "%% Peer does not exist\n");
8618 vty_out(vty
, "%% peer del failed\n");
8621 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
8624 DEFUN_HIDDEN (no_ip_msdp_peer
,
8625 no_ip_msdp_peer_cmd
,
8626 "no ip msdp peer A.B.C.D",
8630 "Delete MSDP peer\n"
8631 "peer ip address\n")
8633 PIM_DECLVAR_CONTEXT(vrf
, pim
);
8634 return ip_no_msdp_peer_cmd_worker(pim
, vty
, argv
[4]->arg
);
8637 static int ip_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
8638 struct vty
*vty
, const char *mg
,
8641 enum pim_msdp_err result
;
8642 struct in_addr mbr_ip
;
8643 int ret
= CMD_SUCCESS
;
8645 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
8647 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
8648 errno
, safe_strerror(errno
));
8649 return CMD_WARNING_CONFIG_FAILED
;
8652 result
= pim_msdp_mg_mbr_add(pim
, mg
, mbr_ip
);
8654 case PIM_MSDP_ERR_NONE
:
8656 case PIM_MSDP_ERR_OOM
:
8657 ret
= CMD_WARNING_CONFIG_FAILED
;
8658 vty_out(vty
, "%% Out of memory\n");
8660 case PIM_MSDP_ERR_MG_MBR_EXISTS
:
8662 vty_out(vty
, "%% mesh-group member exists\n");
8664 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
8665 ret
= CMD_WARNING_CONFIG_FAILED
;
8666 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
8669 ret
= CMD_WARNING_CONFIG_FAILED
;
8670 vty_out(vty
, "%% member add failed\n");
8676 DEFUN (ip_msdp_mesh_group_member
,
8677 ip_msdp_mesh_group_member_cmd
,
8678 "ip msdp mesh-group WORD member A.B.C.D",
8681 "Configure MSDP mesh-group\n"
8683 "mesh group member\n"
8684 "peer ip address\n")
8686 PIM_DECLVAR_CONTEXT(vrf
, pim
);
8687 return ip_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[3]->arg
,
8691 static int ip_no_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
8696 enum pim_msdp_err result
;
8697 struct in_addr mbr_ip
;
8699 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
8701 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
8702 errno
, safe_strerror(errno
));
8703 return CMD_WARNING_CONFIG_FAILED
;
8706 result
= pim_msdp_mg_mbr_del(pim
, mg
, mbr_ip
);
8708 case PIM_MSDP_ERR_NONE
:
8710 case PIM_MSDP_ERR_NO_MG
:
8711 vty_out(vty
, "%% mesh-group does not exist\n");
8713 case PIM_MSDP_ERR_NO_MG_MBR
:
8714 vty_out(vty
, "%% mesh-group member does not exist\n");
8717 vty_out(vty
, "%% mesh-group member del failed\n");
8720 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
8722 DEFUN (no_ip_msdp_mesh_group_member
,
8723 no_ip_msdp_mesh_group_member_cmd
,
8724 "no ip msdp mesh-group WORD member A.B.C.D",
8728 "Delete MSDP mesh-group member\n"
8730 "mesh group member\n"
8731 "peer ip address\n")
8733 PIM_DECLVAR_CONTEXT(vrf
, pim
);
8734 return ip_no_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[4]->arg
,
8738 static int ip_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
8739 struct vty
*vty
, const char *mg
,
8742 enum pim_msdp_err result
;
8743 struct in_addr src_ip
;
8745 result
= inet_pton(AF_INET
, src
, &src_ip
);
8747 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", src
,
8748 errno
, safe_strerror(errno
));
8749 return CMD_WARNING_CONFIG_FAILED
;
8752 result
= pim_msdp_mg_src_add(pim
, mg
, src_ip
);
8754 case PIM_MSDP_ERR_NONE
:
8756 case PIM_MSDP_ERR_OOM
:
8757 vty_out(vty
, "%% Out of memory\n");
8759 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
8760 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
8763 vty_out(vty
, "%% source add failed\n");
8766 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
8770 DEFUN (ip_msdp_mesh_group_source
,
8771 ip_msdp_mesh_group_source_cmd
,
8772 "ip msdp mesh-group WORD source A.B.C.D",
8775 "Configure MSDP mesh-group\n"
8777 "mesh group local address\n"
8778 "source ip address for the TCP connection\n")
8780 PIM_DECLVAR_CONTEXT(vrf
, pim
);
8781 return ip_msdp_mesh_group_source_cmd_worker(pim
, vty
, argv
[3]->arg
,
8785 static int ip_no_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
8789 enum pim_msdp_err result
;
8791 result
= pim_msdp_mg_src_del(pim
, mg
);
8793 case PIM_MSDP_ERR_NONE
:
8795 case PIM_MSDP_ERR_NO_MG
:
8796 vty_out(vty
, "%% mesh-group does not exist\n");
8799 vty_out(vty
, "%% mesh-group source del failed\n");
8802 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
8805 static int ip_no_msdp_mesh_group_cmd_worker(struct pim_instance
*pim
,
8806 struct vty
*vty
, const char *mg
)
8808 enum pim_msdp_err result
;
8810 result
= pim_msdp_mg_del(pim
, mg
);
8812 case PIM_MSDP_ERR_NONE
:
8814 case PIM_MSDP_ERR_NO_MG
:
8815 vty_out(vty
, "%% mesh-group does not exist\n");
8818 vty_out(vty
, "%% mesh-group source del failed\n");
8821 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
8824 DEFUN (no_ip_msdp_mesh_group_source
,
8825 no_ip_msdp_mesh_group_source_cmd
,
8826 "no ip msdp mesh-group WORD source [A.B.C.D]",
8830 "Delete MSDP mesh-group source\n"
8832 "mesh group source\n"
8833 "mesh group local address\n")
8835 PIM_DECLVAR_CONTEXT(vrf
, pim
);
8837 return ip_no_msdp_mesh_group_cmd_worker(pim
, vty
, argv
[6]->arg
);
8839 return ip_no_msdp_mesh_group_source_cmd_worker(pim
, vty
,
8843 static void print_empty_json_obj(struct vty
*vty
)
8846 json
= json_object_new_object();
8847 vty_out(vty
, "%s\n",
8848 json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
));
8849 json_object_free(json
);
8852 static void ip_msdp_show_mesh_group(struct pim_instance
*pim
, struct vty
*vty
,
8855 struct listnode
*mbrnode
;
8856 struct pim_msdp_mg_mbr
*mbr
;
8857 struct pim_msdp_mg
*mg
= pim
->msdp
.mg
;
8858 char mbr_str
[INET_ADDRSTRLEN
];
8859 char src_str
[INET_ADDRSTRLEN
];
8860 char state_str
[PIM_MSDP_STATE_STRLEN
];
8861 enum pim_msdp_peer_state state
;
8862 json_object
*json
= NULL
;
8863 json_object
*json_mg_row
= NULL
;
8864 json_object
*json_members
= NULL
;
8865 json_object
*json_row
= NULL
;
8869 print_empty_json_obj(vty
);
8873 pim_inet4_dump("<source?>", mg
->src_ip
, src_str
, sizeof(src_str
));
8875 json
= json_object_new_object();
8876 /* currently there is only one mesh group but we should still
8878 * it a dict with mg-name as key */
8879 json_mg_row
= json_object_new_object();
8880 json_object_string_add(json_mg_row
, "name",
8881 mg
->mesh_group_name
);
8882 json_object_string_add(json_mg_row
, "source", src_str
);
8884 vty_out(vty
, "Mesh group : %s\n", mg
->mesh_group_name
);
8885 vty_out(vty
, " Source : %s\n", src_str
);
8886 vty_out(vty
, " Member State\n");
8889 for (ALL_LIST_ELEMENTS_RO(mg
->mbr_list
, mbrnode
, mbr
)) {
8890 pim_inet4_dump("<mbr?>", mbr
->mbr_ip
, mbr_str
, sizeof(mbr_str
));
8892 state
= mbr
->mp
->state
;
8894 state
= PIM_MSDP_DISABLED
;
8896 pim_msdp_state_dump(state
, state_str
, sizeof(state_str
));
8898 json_row
= json_object_new_object();
8899 json_object_string_add(json_row
, "member", mbr_str
);
8900 json_object_string_add(json_row
, "state", state_str
);
8901 if (!json_members
) {
8902 json_members
= json_object_new_object();
8903 json_object_object_add(json_mg_row
, "members",
8906 json_object_object_add(json_members
, mbr_str
, json_row
);
8908 vty_out(vty
, " %-15s %11s\n", mbr_str
, state_str
);
8913 json_object_object_add(json
, mg
->mesh_group_name
, json_mg_row
);
8914 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8915 json
, JSON_C_TO_STRING_PRETTY
));
8916 json_object_free(json
);
8920 DEFUN (show_ip_msdp_mesh_group
,
8921 show_ip_msdp_mesh_group_cmd
,
8922 "show ip msdp [vrf NAME] mesh-group [json]",
8927 "MSDP mesh-group information\n"
8930 bool uj
= use_json(argc
, argv
);
8932 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
8937 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
8942 DEFUN (show_ip_msdp_mesh_group_vrf_all
,
8943 show_ip_msdp_mesh_group_vrf_all_cmd
,
8944 "show ip msdp vrf all mesh-group [json]",
8949 "MSDP mesh-group information\n"
8952 bool uj
= use_json(argc
, argv
);
8958 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
8962 vty_out(vty
, " \"%s\": ", vrf
->name
);
8965 vty_out(vty
, "VRF: %s\n", vrf
->name
);
8966 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
8969 vty_out(vty
, "}\n");
8974 static void ip_msdp_show_peers(struct pim_instance
*pim
, struct vty
*vty
,
8977 struct listnode
*mpnode
;
8978 struct pim_msdp_peer
*mp
;
8979 char peer_str
[INET_ADDRSTRLEN
];
8980 char local_str
[INET_ADDRSTRLEN
];
8981 char state_str
[PIM_MSDP_STATE_STRLEN
];
8982 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
8984 json_object
*json
= NULL
;
8985 json_object
*json_row
= NULL
;
8989 json
= json_object_new_object();
8992 "Peer Local State Uptime SaCnt\n");
8995 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
8996 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
8997 now
= pim_time_monotonic_sec();
8998 pim_time_uptime(timebuf
, sizeof(timebuf
),
9001 strcpy(timebuf
, "-");
9003 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
9004 pim_inet4_dump("<local?>", mp
->local
, local_str
,
9006 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
9008 json_row
= json_object_new_object();
9009 json_object_string_add(json_row
, "peer", peer_str
);
9010 json_object_string_add(json_row
, "local", local_str
);
9011 json_object_string_add(json_row
, "state", state_str
);
9012 json_object_string_add(json_row
, "upTime", timebuf
);
9013 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
9014 json_object_object_add(json
, peer_str
, json_row
);
9016 vty_out(vty
, "%-15s %15s %11s %8s %6d\n", peer_str
,
9017 local_str
, state_str
, timebuf
, mp
->sa_cnt
);
9022 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9023 json
, JSON_C_TO_STRING_PRETTY
));
9024 json_object_free(json
);
9028 static void ip_msdp_show_peers_detail(struct pim_instance
*pim
, struct vty
*vty
,
9029 const char *peer
, bool uj
)
9031 struct listnode
*mpnode
;
9032 struct pim_msdp_peer
*mp
;
9033 char peer_str
[INET_ADDRSTRLEN
];
9034 char local_str
[INET_ADDRSTRLEN
];
9035 char state_str
[PIM_MSDP_STATE_STRLEN
];
9036 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
9037 char katimer
[PIM_MSDP_TIMER_STRLEN
];
9038 char crtimer
[PIM_MSDP_TIMER_STRLEN
];
9039 char holdtimer
[PIM_MSDP_TIMER_STRLEN
];
9041 json_object
*json
= NULL
;
9042 json_object
*json_row
= NULL
;
9045 json
= json_object_new_object();
9048 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
9049 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
9050 if (strcmp(peer
, "detail") && strcmp(peer
, peer_str
))
9053 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
9054 now
= pim_time_monotonic_sec();
9055 pim_time_uptime(timebuf
, sizeof(timebuf
),
9058 strcpy(timebuf
, "-");
9060 pim_inet4_dump("<local?>", mp
->local
, local_str
,
9062 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
9063 pim_time_timer_to_hhmmss(katimer
, sizeof(katimer
),
9065 pim_time_timer_to_hhmmss(crtimer
, sizeof(crtimer
),
9067 pim_time_timer_to_hhmmss(holdtimer
, sizeof(holdtimer
),
9071 json_row
= json_object_new_object();
9072 json_object_string_add(json_row
, "peer", peer_str
);
9073 json_object_string_add(json_row
, "local", local_str
);
9074 json_object_string_add(json_row
, "meshGroupName",
9075 mp
->mesh_group_name
);
9076 json_object_string_add(json_row
, "state", state_str
);
9077 json_object_string_add(json_row
, "upTime", timebuf
);
9078 json_object_string_add(json_row
, "keepAliveTimer",
9080 json_object_string_add(json_row
, "connRetryTimer",
9082 json_object_string_add(json_row
, "holdTimer",
9084 json_object_string_add(json_row
, "lastReset",
9086 json_object_int_add(json_row
, "connAttempts",
9088 json_object_int_add(json_row
, "establishedChanges",
9090 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
9091 json_object_int_add(json_row
, "kaSent", mp
->ka_tx_cnt
);
9092 json_object_int_add(json_row
, "kaRcvd", mp
->ka_rx_cnt
);
9093 json_object_int_add(json_row
, "saSent", mp
->sa_tx_cnt
);
9094 json_object_int_add(json_row
, "saRcvd", mp
->sa_rx_cnt
);
9095 json_object_object_add(json
, peer_str
, json_row
);
9097 vty_out(vty
, "Peer : %s\n", peer_str
);
9098 vty_out(vty
, " Local : %s\n", local_str
);
9099 vty_out(vty
, " Mesh Group : %s\n",
9100 mp
->mesh_group_name
);
9101 vty_out(vty
, " State : %s\n", state_str
);
9102 vty_out(vty
, " Uptime : %s\n", timebuf
);
9104 vty_out(vty
, " Keepalive Timer : %s\n", katimer
);
9105 vty_out(vty
, " Conn Retry Timer : %s\n", crtimer
);
9106 vty_out(vty
, " Hold Timer : %s\n", holdtimer
);
9107 vty_out(vty
, " Last Reset : %s\n",
9109 vty_out(vty
, " Conn Attempts : %d\n",
9111 vty_out(vty
, " Established Changes : %d\n",
9113 vty_out(vty
, " SA Count : %d\n",
9115 vty_out(vty
, " Statistics :\n");
9118 vty_out(vty
, " Keepalives : %10d %10d\n",
9119 mp
->ka_tx_cnt
, mp
->ka_rx_cnt
);
9120 vty_out(vty
, " SAs : %10d %10d\n",
9121 mp
->sa_tx_cnt
, mp
->sa_rx_cnt
);
9127 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9128 json
, JSON_C_TO_STRING_PRETTY
));
9129 json_object_free(json
);
9133 DEFUN (show_ip_msdp_peer_detail
,
9134 show_ip_msdp_peer_detail_cmd
,
9135 "show ip msdp [vrf NAME] peer [detail|A.B.C.D] [json]",
9140 "MSDP peer information\n"
9145 bool uj
= use_json(argc
, argv
);
9147 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
9154 if (argv_find(argv
, argc
, "detail", &idx
))
9155 arg
= argv
[idx
]->text
;
9156 else if (argv_find(argv
, argc
, "A.B.C.D", &idx
))
9157 arg
= argv
[idx
]->arg
;
9160 ip_msdp_show_peers_detail(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
9162 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
9167 DEFUN (show_ip_msdp_peer_detail_vrf_all
,
9168 show_ip_msdp_peer_detail_vrf_all_cmd
,
9169 "show ip msdp vrf all peer [detail|A.B.C.D] [json]",
9174 "MSDP peer information\n"
9180 bool uj
= use_json(argc
, argv
);
9186 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
9190 vty_out(vty
, " \"%s\": ", vrf
->name
);
9193 vty_out(vty
, "VRF: %s\n", vrf
->name
);
9194 if (argv_find(argv
, argc
, "detail", &idx
)
9195 || argv_find(argv
, argc
, "A.B.C.D", &idx
))
9196 ip_msdp_show_peers_detail(vrf
->info
, vty
,
9197 argv
[idx
]->arg
, uj
);
9199 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
9202 vty_out(vty
, "}\n");
9207 static void ip_msdp_show_sa(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
9209 struct listnode
*sanode
;
9210 struct pim_msdp_sa
*sa
;
9211 char src_str
[INET_ADDRSTRLEN
];
9212 char grp_str
[INET_ADDRSTRLEN
];
9213 char rp_str
[INET_ADDRSTRLEN
];
9214 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
9218 json_object
*json
= NULL
;
9219 json_object
*json_group
= NULL
;
9220 json_object
*json_row
= NULL
;
9223 json
= json_object_new_object();
9226 "Source Group RP Local SPT Uptime\n");
9229 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
9230 now
= pim_time_monotonic_sec();
9231 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
9232 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
9233 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
9234 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
9235 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
9237 strcpy(spt_str
, "yes");
9239 strcpy(spt_str
, "no");
9242 strcpy(rp_str
, "-");
9243 strcpy(spt_str
, "-");
9245 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
9246 strcpy(local_str
, "yes");
9248 strcpy(local_str
, "no");
9251 json_object_object_get_ex(json
, grp_str
, &json_group
);
9254 json_group
= json_object_new_object();
9255 json_object_object_add(json
, grp_str
,
9259 json_row
= json_object_new_object();
9260 json_object_string_add(json_row
, "source", src_str
);
9261 json_object_string_add(json_row
, "group", grp_str
);
9262 json_object_string_add(json_row
, "rp", rp_str
);
9263 json_object_string_add(json_row
, "local", local_str
);
9264 json_object_string_add(json_row
, "sptSetup", spt_str
);
9265 json_object_string_add(json_row
, "upTime", timebuf
);
9266 json_object_object_add(json_group
, src_str
, json_row
);
9268 vty_out(vty
, "%-15s %15s %15s %5c %3c %8s\n",
9269 src_str
, grp_str
, rp_str
, local_str
[0],
9270 spt_str
[0], timebuf
);
9275 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9276 json
, JSON_C_TO_STRING_PRETTY
));
9277 json_object_free(json
);
9281 static void ip_msdp_show_sa_entry_detail(struct pim_msdp_sa
*sa
,
9282 const char *src_str
,
9283 const char *grp_str
, struct vty
*vty
,
9284 bool uj
, json_object
*json
)
9286 char rp_str
[INET_ADDRSTRLEN
];
9287 char peer_str
[INET_ADDRSTRLEN
];
9288 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
9291 char statetimer
[PIM_MSDP_TIMER_STRLEN
];
9293 json_object
*json_group
= NULL
;
9294 json_object
*json_row
= NULL
;
9296 now
= pim_time_monotonic_sec();
9297 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
9298 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
9299 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
9300 pim_inet4_dump("<peer?>", sa
->peer
, peer_str
, sizeof(peer_str
));
9302 strcpy(spt_str
, "yes");
9304 strcpy(spt_str
, "no");
9307 strcpy(rp_str
, "-");
9308 strcpy(peer_str
, "-");
9309 strcpy(spt_str
, "-");
9311 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
9312 strcpy(local_str
, "yes");
9314 strcpy(local_str
, "no");
9316 pim_time_timer_to_hhmmss(statetimer
, sizeof(statetimer
),
9317 sa
->sa_state_timer
);
9319 json_object_object_get_ex(json
, grp_str
, &json_group
);
9322 json_group
= json_object_new_object();
9323 json_object_object_add(json
, grp_str
, json_group
);
9326 json_row
= json_object_new_object();
9327 json_object_string_add(json_row
, "source", src_str
);
9328 json_object_string_add(json_row
, "group", grp_str
);
9329 json_object_string_add(json_row
, "rp", rp_str
);
9330 json_object_string_add(json_row
, "local", local_str
);
9331 json_object_string_add(json_row
, "sptSetup", spt_str
);
9332 json_object_string_add(json_row
, "upTime", timebuf
);
9333 json_object_string_add(json_row
, "stateTimer", statetimer
);
9334 json_object_object_add(json_group
, src_str
, json_row
);
9336 vty_out(vty
, "SA : %s\n", sa
->sg_str
);
9337 vty_out(vty
, " RP : %s\n", rp_str
);
9338 vty_out(vty
, " Peer : %s\n", peer_str
);
9339 vty_out(vty
, " Local : %s\n", local_str
);
9340 vty_out(vty
, " SPT Setup : %s\n", spt_str
);
9341 vty_out(vty
, " Uptime : %s\n", timebuf
);
9342 vty_out(vty
, " State Timer : %s\n", statetimer
);
9347 static void ip_msdp_show_sa_detail(struct pim_instance
*pim
, struct vty
*vty
,
9350 struct listnode
*sanode
;
9351 struct pim_msdp_sa
*sa
;
9352 char src_str
[INET_ADDRSTRLEN
];
9353 char grp_str
[INET_ADDRSTRLEN
];
9354 json_object
*json
= NULL
;
9357 json
= json_object_new_object();
9360 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
9361 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
9362 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
9363 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
, uj
,
9368 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9369 json
, JSON_C_TO_STRING_PRETTY
));
9370 json_object_free(json
);
9374 DEFUN (show_ip_msdp_sa_detail
,
9375 show_ip_msdp_sa_detail_cmd
,
9376 "show ip msdp [vrf NAME] sa detail [json]",
9381 "MSDP active-source information\n"
9385 bool uj
= use_json(argc
, argv
);
9387 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
9392 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
9397 DEFUN (show_ip_msdp_sa_detail_vrf_all
,
9398 show_ip_msdp_sa_detail_vrf_all_cmd
,
9399 "show ip msdp vrf all sa detail [json]",
9404 "MSDP active-source information\n"
9408 bool uj
= use_json(argc
, argv
);
9414 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
9418 vty_out(vty
, " \"%s\": ", vrf
->name
);
9421 vty_out(vty
, "VRF: %s\n", vrf
->name
);
9422 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
9425 vty_out(vty
, "}\n");
9430 static void ip_msdp_show_sa_addr(struct pim_instance
*pim
, struct vty
*vty
,
9431 const char *addr
, bool uj
)
9433 struct listnode
*sanode
;
9434 struct pim_msdp_sa
*sa
;
9435 char src_str
[INET_ADDRSTRLEN
];
9436 char grp_str
[INET_ADDRSTRLEN
];
9437 json_object
*json
= NULL
;
9440 json
= json_object_new_object();
9443 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
9444 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
9445 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
9446 if (!strcmp(addr
, src_str
) || !strcmp(addr
, grp_str
)) {
9447 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
9453 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9454 json
, JSON_C_TO_STRING_PRETTY
));
9455 json_object_free(json
);
9459 static void ip_msdp_show_sa_sg(struct pim_instance
*pim
, struct vty
*vty
,
9460 const char *src
, const char *grp
, bool uj
)
9462 struct listnode
*sanode
;
9463 struct pim_msdp_sa
*sa
;
9464 char src_str
[INET_ADDRSTRLEN
];
9465 char grp_str
[INET_ADDRSTRLEN
];
9466 json_object
*json
= NULL
;
9469 json
= json_object_new_object();
9472 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
9473 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
9474 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
9475 if (!strcmp(src
, src_str
) && !strcmp(grp
, grp_str
)) {
9476 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
9482 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9483 json
, JSON_C_TO_STRING_PRETTY
));
9484 json_object_free(json
);
9488 DEFUN (show_ip_msdp_sa_sg
,
9489 show_ip_msdp_sa_sg_cmd
,
9490 "show ip msdp [vrf NAME] sa [A.B.C.D [A.B.C.D]] [json]",
9495 "MSDP active-source information\n"
9496 "source or group ip\n"
9500 bool uj
= use_json(argc
, argv
);
9504 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
9509 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
9511 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
9515 if (src_ip
&& grp_ip
)
9516 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
9518 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
9520 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
9525 DEFUN (show_ip_msdp_sa_sg_vrf_all
,
9526 show_ip_msdp_sa_sg_vrf_all_cmd
,
9527 "show ip msdp vrf all sa [A.B.C.D [A.B.C.D]] [json]",
9532 "MSDP active-source information\n"
9533 "source or group ip\n"
9537 bool uj
= use_json(argc
, argv
);
9542 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
9544 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
9550 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
9554 vty_out(vty
, " \"%s\": ", vrf
->name
);
9557 vty_out(vty
, "VRF: %s\n", vrf
->name
);
9559 if (src_ip
&& grp_ip
)
9560 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
9562 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
9564 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
9567 vty_out(vty
, "}\n");
9572 struct pim_sg_cache_walk_data
{
9575 json_object
*json_group
;
9576 struct in_addr addr
;
9580 static void pim_show_vxlan_sg_entry(struct pim_vxlan_sg
*vxlan_sg
,
9581 struct pim_sg_cache_walk_data
*cwd
)
9583 struct vty
*vty
= cwd
->vty
;
9584 json_object
*json
= cwd
->json
;
9585 char src_str
[INET_ADDRSTRLEN
];
9586 char grp_str
[INET_ADDRSTRLEN
];
9587 json_object
*json_row
;
9588 bool installed
= (vxlan_sg
->up
)?TRUE
:FALSE
;
9589 const char *iif_name
= vxlan_sg
->iif
?vxlan_sg
->iif
->name
:"-";
9590 const char *oif_name
;
9592 if (pim_vxlan_is_orig_mroute(vxlan_sg
))
9593 oif_name
= vxlan_sg
->orig_oif
?vxlan_sg
->orig_oif
->name
:"";
9595 oif_name
= vxlan_sg
->term_oif
?vxlan_sg
->term_oif
->name
:"";
9597 if (cwd
->addr_match
&& (vxlan_sg
->sg
.src
.s_addr
!= cwd
->addr
.s_addr
) &&
9598 (vxlan_sg
->sg
.grp
.s_addr
!= cwd
->addr
.s_addr
)) {
9601 pim_inet4_dump("<src?>", vxlan_sg
->sg
.src
, src_str
, sizeof(src_str
));
9602 pim_inet4_dump("<grp?>", vxlan_sg
->sg
.grp
, grp_str
, sizeof(grp_str
));
9604 json_object_object_get_ex(json
, grp_str
, &cwd
->json_group
);
9606 if (!cwd
->json_group
) {
9607 cwd
->json_group
= json_object_new_object();
9608 json_object_object_add(json
, grp_str
,
9612 json_row
= json_object_new_object();
9613 json_object_string_add(json_row
, "source", src_str
);
9614 json_object_string_add(json_row
, "group", grp_str
);
9615 json_object_string_add(json_row
, "input", iif_name
);
9616 json_object_string_add(json_row
, "output", oif_name
);
9618 json_object_boolean_true_add(json_row
, "installed");
9620 json_object_boolean_false_add(json_row
, "installed");
9621 json_object_object_add(cwd
->json_group
, src_str
, json_row
);
9623 vty_out(vty
, "%-15s %-15s %-15s %-15s %-5s\n",
9624 src_str
, grp_str
, iif_name
, oif_name
,
9629 static void pim_show_vxlan_sg_hash_entry(struct hash_backet
*backet
, void *arg
)
9631 pim_show_vxlan_sg_entry((struct pim_vxlan_sg
*)backet
->data
,
9632 (struct pim_sg_cache_walk_data
*)arg
);
9635 static void pim_show_vxlan_sg(struct pim_instance
*pim
,
9636 struct vty
*vty
, bool uj
)
9638 json_object
*json
= NULL
;
9639 struct pim_sg_cache_walk_data cwd
;
9642 json
= json_object_new_object();
9644 vty_out(vty
, "Codes: I -> installed\n");
9646 "Source Group Input Output Flags\n");
9649 memset(&cwd
, 0, sizeof(cwd
));
9652 hash_iterate(pim
->vxlan
.sg_hash
, pim_show_vxlan_sg_hash_entry
, &cwd
);
9655 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9656 json
, JSON_C_TO_STRING_PRETTY
));
9657 json_object_free(json
);
9661 static void pim_show_vxlan_sg_match_addr(struct pim_instance
*pim
,
9662 struct vty
*vty
, char *addr_str
, bool uj
)
9664 json_object
*json
= NULL
;
9665 struct pim_sg_cache_walk_data cwd
;
9668 memset(&cwd
, 0, sizeof(cwd
));
9669 result
= inet_pton(AF_INET
, addr_str
, &cwd
.addr
);
9671 vty_out(vty
, "Bad address %s: errno=%d: %s\n", addr_str
,
9672 errno
, safe_strerror(errno
));
9677 json
= json_object_new_object();
9679 vty_out(vty
, "Codes: I -> installed\n");
9681 "Source Group Input Output Flags\n");
9686 cwd
.addr_match
= TRUE
;
9687 hash_iterate(pim
->vxlan
.sg_hash
, pim_show_vxlan_sg_hash_entry
, &cwd
);
9690 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9691 json
, JSON_C_TO_STRING_PRETTY
));
9692 json_object_free(json
);
9696 static void pim_show_vxlan_sg_one(struct pim_instance
*pim
,
9697 struct vty
*vty
, char *src_str
, char *grp_str
, bool uj
)
9699 json_object
*json
= NULL
;
9700 struct prefix_sg sg
;
9702 struct pim_vxlan_sg
*vxlan_sg
;
9703 const char *iif_name
;
9705 const char *oif_name
;
9707 result
= inet_pton(AF_INET
, src_str
, &sg
.src
);
9709 vty_out(vty
, "Bad src address %s: errno=%d: %s\n", src_str
,
9710 errno
, safe_strerror(errno
));
9713 result
= inet_pton(AF_INET
, grp_str
, &sg
.grp
);
9715 vty_out(vty
, "Bad grp address %s: errno=%d: %s\n", grp_str
,
9716 errno
, safe_strerror(errno
));
9720 sg
.family
= AF_INET
;
9721 sg
.prefixlen
= IPV4_MAX_BITLEN
;
9723 json
= json_object_new_object();
9725 vxlan_sg
= pim_vxlan_sg_find(pim
, &sg
);
9727 installed
= (vxlan_sg
->up
)?TRUE
:FALSE
;
9728 iif_name
= vxlan_sg
->iif
?vxlan_sg
->iif
->name
:"-";
9730 if (pim_vxlan_is_orig_mroute(vxlan_sg
))
9732 vxlan_sg
->orig_oif
?vxlan_sg
->orig_oif
->name
:"";
9735 vxlan_sg
->term_oif
?vxlan_sg
->term_oif
->name
:"";
9738 json_object_string_add(json
, "source", src_str
);
9739 json_object_string_add(json
, "group", grp_str
);
9740 json_object_string_add(json
, "input", iif_name
);
9741 json_object_string_add(json
, "output", oif_name
);
9743 json_object_boolean_true_add(json
, "installed");
9745 json_object_boolean_false_add(json
,
9748 vty_out(vty
, "SG : %s\n", vxlan_sg
->sg_str
);
9749 vty_out(vty
, " Input : %s\n", iif_name
);
9750 vty_out(vty
, " Output : %s\n", oif_name
);
9751 vty_out(vty
, " installed : %s\n",
9752 installed
?"yes":"no");
9757 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9758 json
, JSON_C_TO_STRING_PRETTY
));
9759 json_object_free(json
);
9763 DEFUN (show_ip_pim_vxlan_sg
,
9764 show_ip_pim_vxlan_sg_cmd
,
9765 "show ip pim [vrf NAME] vxlan-groups [A.B.C.D [A.B.C.D]] [json]",
9770 "VxLAN BUM groups\n"
9771 "source or group ip\n"
9775 bool uj
= use_json(argc
, argv
);
9779 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
9784 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ?
9785 argv
[idx
++]->arg
:NULL
;
9786 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
) ?
9787 argv
[idx
]->arg
:NULL
;
9789 if (src_ip
&& grp_ip
)
9790 pim_show_vxlan_sg_one(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
9792 pim_show_vxlan_sg_match_addr(vrf
->info
, vty
, src_ip
, uj
);
9794 pim_show_vxlan_sg(vrf
->info
, vty
, uj
);
9799 static void pim_show_vxlan_sg_work(struct pim_instance
*pim
,
9800 struct vty
*vty
, bool uj
)
9802 json_object
*json
= NULL
;
9803 struct pim_sg_cache_walk_data cwd
;
9804 struct listnode
*node
;
9805 struct pim_vxlan_sg
*vxlan_sg
;
9808 json
= json_object_new_object();
9810 vty_out(vty
, "Codes: I -> installed\n");
9812 "Source Group Input Flags\n");
9815 memset(&cwd
, 0, sizeof(cwd
));
9818 for (ALL_LIST_ELEMENTS_RO(pim_vxlan_p
->work_list
, node
, vxlan_sg
))
9819 pim_show_vxlan_sg_entry(vxlan_sg
, &cwd
);
9822 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9823 json
, JSON_C_TO_STRING_PRETTY
));
9824 json_object_free(json
);
9828 DEFUN_HIDDEN (show_ip_pim_vxlan_sg_work
,
9829 show_ip_pim_vxlan_sg_work_cmd
,
9830 "show ip pim [vrf NAME] vxlan-work [json]",
9838 bool uj
= use_json(argc
, argv
);
9842 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
9847 pim_show_vxlan_sg_work(vrf
->info
, vty
, uj
);
9852 DEFUN_HIDDEN (no_ip_pim_mlag
,
9860 struct in_addr addr
;
9863 pim_vxlan_mlag_update(TRUE
/*mlag_enable*/,
9864 FALSE
/*peer_state*/, PIM_VXLAN_MLAG_ROLE_SECONDARY
,
9865 NULL
/*peerlink*/, &addr
);
9870 DEFUN_HIDDEN (ip_pim_mlag
,
9872 "ip pim mlag INTERFACE role [primary|secondary] state [up|down] addr A.B.C.D",
9876 "peerlink sub interface\n"
9878 "MLAG role primary\n"
9879 "MLAG role secondary\n"
9880 "peer session state\n"
9881 "peer session state up\n"
9882 "peer session state down\n"
9884 "unique ip address\n")
9886 struct interface
*ifp
;
9887 const char *peerlink
;
9892 struct in_addr reg_addr
;
9895 peerlink
= argv
[idx
]->arg
;
9896 ifp
= if_lookup_by_name(peerlink
, VRF_DEFAULT
);
9898 vty_out(vty
, "No such interface name %s\n", peerlink
);
9903 if (!strcmp(argv
[idx
]->arg
, "primary")) {
9904 role
= PIM_VXLAN_MLAG_ROLE_PRIMARY
;
9905 } else if (!strcmp(argv
[idx
]->arg
, "secondary")) {
9906 role
= PIM_VXLAN_MLAG_ROLE_SECONDARY
;
9908 vty_out(vty
, "unknown MLAG role %s\n", argv
[idx
]->arg
);
9913 if (!strcmp(argv
[idx
]->arg
, "up")) {
9915 } else if (strcmp(argv
[idx
]->arg
, "down")) {
9918 vty_out(vty
, "unknown MLAG state %s\n", argv
[idx
]->arg
);
9923 result
= inet_pton(AF_INET
, argv
[idx
]->arg
, ®_addr
);
9925 vty_out(vty
, "%% Bad reg address %s: errno=%d: %s\n",
9927 errno
, safe_strerror(errno
));
9928 return CMD_WARNING_CONFIG_FAILED
;
9930 pim_vxlan_mlag_update(TRUE
, peer_state
, role
, ifp
, ®_addr
);
9935 void pim_cmd_init(void)
9937 install_node(&interface_node
,
9938 pim_interface_config_write
); /* INTERFACE_NODE */
9941 install_node(&debug_node
, pim_debug_config_write
);
9943 install_element(ENABLE_NODE
, &pim_test_sg_keepalive_cmd
);
9945 install_element(CONFIG_NODE
, &ip_pim_rp_cmd
);
9946 install_element(VRF_NODE
, &ip_pim_rp_cmd
);
9947 install_element(CONFIG_NODE
, &no_ip_pim_rp_cmd
);
9948 install_element(VRF_NODE
, &no_ip_pim_rp_cmd
);
9949 install_element(CONFIG_NODE
, &ip_pim_rp_prefix_list_cmd
);
9950 install_element(VRF_NODE
, &ip_pim_rp_prefix_list_cmd
);
9951 install_element(CONFIG_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
9952 install_element(VRF_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
9953 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
9954 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
9955 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
9956 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
9957 install_element(CONFIG_NODE
, &ip_pim_ssm_prefix_list_cmd
);
9958 install_element(VRF_NODE
, &ip_pim_ssm_prefix_list_cmd
);
9959 install_element(CONFIG_NODE
, &ip_pim_register_suppress_cmd
);
9960 install_element(VRF_NODE
, &ip_pim_register_suppress_cmd
);
9961 install_element(CONFIG_NODE
, &no_ip_pim_register_suppress_cmd
);
9962 install_element(VRF_NODE
, &no_ip_pim_register_suppress_cmd
);
9963 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
9964 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
9965 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
9966 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
9967 install_element(CONFIG_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
9968 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
9969 install_element(CONFIG_NODE
,
9970 &no_ip_pim_spt_switchover_infinity_plist_cmd
);
9971 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_plist_cmd
);
9972 install_element(CONFIG_NODE
, &ip_pim_joinprune_time_cmd
);
9973 install_element(VRF_NODE
, &ip_pim_joinprune_time_cmd
);
9974 install_element(CONFIG_NODE
, &no_ip_pim_joinprune_time_cmd
);
9975 install_element(VRF_NODE
, &no_ip_pim_joinprune_time_cmd
);
9976 install_element(CONFIG_NODE
, &ip_pim_keep_alive_cmd
);
9977 install_element(VRF_NODE
, &ip_pim_keep_alive_cmd
);
9978 install_element(CONFIG_NODE
, &ip_pim_rp_keep_alive_cmd
);
9979 install_element(VRF_NODE
, &ip_pim_rp_keep_alive_cmd
);
9980 install_element(CONFIG_NODE
, &no_ip_pim_keep_alive_cmd
);
9981 install_element(VRF_NODE
, &no_ip_pim_keep_alive_cmd
);
9982 install_element(CONFIG_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
9983 install_element(VRF_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
9984 install_element(CONFIG_NODE
, &ip_pim_packets_cmd
);
9985 install_element(VRF_NODE
, &ip_pim_packets_cmd
);
9986 install_element(CONFIG_NODE
, &no_ip_pim_packets_cmd
);
9987 install_element(VRF_NODE
, &no_ip_pim_packets_cmd
);
9988 install_element(CONFIG_NODE
, &ip_pim_v6_secondary_cmd
);
9989 install_element(VRF_NODE
, &ip_pim_v6_secondary_cmd
);
9990 install_element(CONFIG_NODE
, &no_ip_pim_v6_secondary_cmd
);
9991 install_element(VRF_NODE
, &no_ip_pim_v6_secondary_cmd
);
9992 install_element(CONFIG_NODE
, &ip_ssmpingd_cmd
);
9993 install_element(VRF_NODE
, &ip_ssmpingd_cmd
);
9994 install_element(CONFIG_NODE
, &no_ip_ssmpingd_cmd
);
9995 install_element(VRF_NODE
, &no_ip_ssmpingd_cmd
);
9996 install_element(CONFIG_NODE
, &ip_msdp_peer_cmd
);
9997 install_element(VRF_NODE
, &ip_msdp_peer_cmd
);
9998 install_element(CONFIG_NODE
, &no_ip_msdp_peer_cmd
);
9999 install_element(VRF_NODE
, &no_ip_msdp_peer_cmd
);
10000 install_element(CONFIG_NODE
, &ip_pim_ecmp_cmd
);
10001 install_element(VRF_NODE
, &ip_pim_ecmp_cmd
);
10002 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_cmd
);
10003 install_element(VRF_NODE
, &no_ip_pim_ecmp_cmd
);
10004 install_element(CONFIG_NODE
, &ip_pim_ecmp_rebalance_cmd
);
10005 install_element(VRF_NODE
, &ip_pim_ecmp_rebalance_cmd
);
10006 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
10007 install_element(VRF_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
10008 install_element(CONFIG_NODE
, &ip_pim_mlag_cmd
);
10009 install_element(CONFIG_NODE
, &no_ip_pim_mlag_cmd
);
10011 install_element(INTERFACE_NODE
, &interface_ip_igmp_cmd
);
10012 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_cmd
);
10013 install_element(INTERFACE_NODE
, &interface_ip_igmp_join_cmd
);
10014 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_join_cmd
);
10015 install_element(INTERFACE_NODE
, &interface_ip_igmp_version_cmd
);
10016 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_version_cmd
);
10017 install_element(INTERFACE_NODE
, &interface_ip_igmp_query_interval_cmd
);
10018 install_element(INTERFACE_NODE
,
10019 &interface_no_ip_igmp_query_interval_cmd
);
10020 install_element(INTERFACE_NODE
,
10021 &interface_ip_igmp_query_max_response_time_cmd
);
10022 install_element(INTERFACE_NODE
,
10023 &interface_no_ip_igmp_query_max_response_time_cmd
);
10024 install_element(INTERFACE_NODE
,
10025 &interface_ip_igmp_query_max_response_time_dsec_cmd
);
10026 install_element(INTERFACE_NODE
,
10027 &interface_no_ip_igmp_query_max_response_time_dsec_cmd
);
10028 install_element(INTERFACE_NODE
, &interface_ip_pim_activeactive_cmd
);
10029 install_element(INTERFACE_NODE
, &interface_ip_pim_ssm_cmd
);
10030 install_element(INTERFACE_NODE
, &interface_no_ip_pim_ssm_cmd
);
10031 install_element(INTERFACE_NODE
, &interface_ip_pim_sm_cmd
);
10032 install_element(INTERFACE_NODE
, &interface_no_ip_pim_sm_cmd
);
10033 install_element(INTERFACE_NODE
, &interface_ip_pim_cmd
);
10034 install_element(INTERFACE_NODE
, &interface_no_ip_pim_cmd
);
10035 install_element(INTERFACE_NODE
, &interface_ip_pim_drprio_cmd
);
10036 install_element(INTERFACE_NODE
, &interface_no_ip_pim_drprio_cmd
);
10037 install_element(INTERFACE_NODE
, &interface_ip_pim_hello_cmd
);
10038 install_element(INTERFACE_NODE
, &interface_no_ip_pim_hello_cmd
);
10039 install_element(INTERFACE_NODE
, &interface_ip_pim_boundary_oil_cmd
);
10040 install_element(INTERFACE_NODE
, &interface_no_ip_pim_boundary_oil_cmd
);
10042 // Static mroutes NEB
10043 install_element(INTERFACE_NODE
, &interface_ip_mroute_cmd
);
10044 install_element(INTERFACE_NODE
, &interface_ip_mroute_source_cmd
);
10045 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_cmd
);
10046 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_source_cmd
);
10048 install_element(VIEW_NODE
, &show_ip_igmp_interface_cmd
);
10049 install_element(VIEW_NODE
, &show_ip_igmp_interface_vrf_all_cmd
);
10050 install_element(VIEW_NODE
, &show_ip_igmp_join_cmd
);
10051 install_element(VIEW_NODE
, &show_ip_igmp_join_vrf_all_cmd
);
10052 install_element(VIEW_NODE
, &show_ip_igmp_groups_cmd
);
10053 install_element(VIEW_NODE
, &show_ip_igmp_groups_vrf_all_cmd
);
10054 install_element(VIEW_NODE
, &show_ip_igmp_groups_retransmissions_cmd
);
10055 install_element(VIEW_NODE
, &show_ip_igmp_sources_cmd
);
10056 install_element(VIEW_NODE
, &show_ip_igmp_sources_retransmissions_cmd
);
10057 install_element(VIEW_NODE
, &show_ip_igmp_statistics_cmd
);
10058 install_element(VIEW_NODE
, &show_ip_pim_assert_cmd
);
10059 install_element(VIEW_NODE
, &show_ip_pim_assert_internal_cmd
);
10060 install_element(VIEW_NODE
, &show_ip_pim_assert_metric_cmd
);
10061 install_element(VIEW_NODE
, &show_ip_pim_assert_winner_metric_cmd
);
10062 install_element(VIEW_NODE
, &show_ip_pim_interface_traffic_cmd
);
10063 install_element(VIEW_NODE
, &show_ip_pim_interface_cmd
);
10064 install_element(VIEW_NODE
, &show_ip_pim_interface_vrf_all_cmd
);
10065 install_element(VIEW_NODE
, &show_ip_pim_join_cmd
);
10066 install_element(VIEW_NODE
, &show_ip_pim_join_vrf_all_cmd
);
10067 install_element(VIEW_NODE
, &show_ip_pim_local_membership_cmd
);
10068 install_element(VIEW_NODE
, &show_ip_pim_neighbor_cmd
);
10069 install_element(VIEW_NODE
, &show_ip_pim_neighbor_vrf_all_cmd
);
10070 install_element(VIEW_NODE
, &show_ip_pim_rpf_cmd
);
10071 install_element(VIEW_NODE
, &show_ip_pim_rpf_vrf_all_cmd
);
10072 install_element(VIEW_NODE
, &show_ip_pim_secondary_cmd
);
10073 install_element(VIEW_NODE
, &show_ip_pim_state_cmd
);
10074 install_element(VIEW_NODE
, &show_ip_pim_state_vrf_all_cmd
);
10075 install_element(VIEW_NODE
, &show_ip_pim_upstream_cmd
);
10076 install_element(VIEW_NODE
, &show_ip_pim_upstream_vrf_all_cmd
);
10077 install_element(VIEW_NODE
, &show_ip_pim_upstream_join_desired_cmd
);
10078 install_element(VIEW_NODE
, &show_ip_pim_upstream_rpf_cmd
);
10079 install_element(VIEW_NODE
, &show_ip_pim_rp_cmd
);
10080 install_element(VIEW_NODE
, &show_ip_pim_rp_vrf_all_cmd
);
10081 install_element(VIEW_NODE
, &show_ip_pim_bsr_cmd
);
10082 install_element(VIEW_NODE
, &show_ip_multicast_cmd
);
10083 install_element(VIEW_NODE
, &show_ip_multicast_vrf_all_cmd
);
10084 install_element(VIEW_NODE
, &show_ip_mroute_cmd
);
10085 install_element(VIEW_NODE
, &show_ip_mroute_vrf_all_cmd
);
10086 install_element(VIEW_NODE
, &show_ip_mroute_count_cmd
);
10087 install_element(VIEW_NODE
, &show_ip_mroute_count_vrf_all_cmd
);
10088 install_element(VIEW_NODE
, &show_ip_rib_cmd
);
10089 install_element(VIEW_NODE
, &show_ip_ssmpingd_cmd
);
10090 install_element(VIEW_NODE
, &show_debugging_pim_cmd
);
10091 install_element(VIEW_NODE
, &show_ip_pim_nexthop_cmd
);
10092 install_element(VIEW_NODE
, &show_ip_pim_nexthop_lookup_cmd
);
10093 install_element(VIEW_NODE
, &show_ip_pim_bsrp_cmd
);
10094 install_element(VIEW_NODE
, &show_ip_pim_bsm_db_cmd
);
10095 install_element(VIEW_NODE
, &show_ip_pim_statistics_cmd
);
10097 install_element(ENABLE_NODE
, &clear_ip_interfaces_cmd
);
10098 install_element(ENABLE_NODE
, &clear_ip_igmp_interfaces_cmd
);
10099 install_element(ENABLE_NODE
, &clear_ip_mroute_cmd
);
10100 install_element(ENABLE_NODE
, &clear_ip_pim_interfaces_cmd
);
10101 install_element(ENABLE_NODE
, &clear_ip_pim_interface_traffic_cmd
);
10102 install_element(ENABLE_NODE
, &clear_ip_pim_oil_cmd
);
10103 install_element(ENABLE_NODE
, &clear_ip_pim_statistics_cmd
);
10105 install_element(ENABLE_NODE
, &debug_igmp_cmd
);
10106 install_element(ENABLE_NODE
, &no_debug_igmp_cmd
);
10107 install_element(ENABLE_NODE
, &debug_igmp_events_cmd
);
10108 install_element(ENABLE_NODE
, &no_debug_igmp_events_cmd
);
10109 install_element(ENABLE_NODE
, &debug_igmp_packets_cmd
);
10110 install_element(ENABLE_NODE
, &no_debug_igmp_packets_cmd
);
10111 install_element(ENABLE_NODE
, &debug_igmp_trace_cmd
);
10112 install_element(ENABLE_NODE
, &no_debug_igmp_trace_cmd
);
10113 install_element(ENABLE_NODE
, &debug_mroute_cmd
);
10114 install_element(ENABLE_NODE
, &debug_mroute_detail_cmd
);
10115 install_element(ENABLE_NODE
, &no_debug_mroute_cmd
);
10116 install_element(ENABLE_NODE
, &no_debug_mroute_detail_cmd
);
10117 install_element(ENABLE_NODE
, &debug_pim_static_cmd
);
10118 install_element(ENABLE_NODE
, &no_debug_pim_static_cmd
);
10119 install_element(ENABLE_NODE
, &debug_pim_cmd
);
10120 install_element(ENABLE_NODE
, &no_debug_pim_cmd
);
10121 install_element(ENABLE_NODE
, &debug_pim_nht_cmd
);
10122 install_element(ENABLE_NODE
, &no_debug_pim_nht_cmd
);
10123 install_element(ENABLE_NODE
, &debug_pim_nht_rp_cmd
);
10124 install_element(ENABLE_NODE
, &no_debug_pim_nht_rp_cmd
);
10125 install_element(ENABLE_NODE
, &debug_pim_events_cmd
);
10126 install_element(ENABLE_NODE
, &no_debug_pim_events_cmd
);
10127 install_element(ENABLE_NODE
, &debug_pim_packets_cmd
);
10128 install_element(ENABLE_NODE
, &no_debug_pim_packets_cmd
);
10129 install_element(ENABLE_NODE
, &debug_pim_packetdump_send_cmd
);
10130 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_send_cmd
);
10131 install_element(ENABLE_NODE
, &debug_pim_packetdump_recv_cmd
);
10132 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_recv_cmd
);
10133 install_element(ENABLE_NODE
, &debug_pim_trace_cmd
);
10134 install_element(ENABLE_NODE
, &no_debug_pim_trace_cmd
);
10135 install_element(ENABLE_NODE
, &debug_pim_trace_detail_cmd
);
10136 install_element(ENABLE_NODE
, &no_debug_pim_trace_detail_cmd
);
10137 install_element(ENABLE_NODE
, &debug_ssmpingd_cmd
);
10138 install_element(ENABLE_NODE
, &no_debug_ssmpingd_cmd
);
10139 install_element(ENABLE_NODE
, &debug_pim_zebra_cmd
);
10140 install_element(ENABLE_NODE
, &no_debug_pim_zebra_cmd
);
10141 install_element(ENABLE_NODE
, &debug_pim_vxlan_cmd
);
10142 install_element(ENABLE_NODE
, &no_debug_pim_vxlan_cmd
);
10143 install_element(ENABLE_NODE
, &debug_msdp_cmd
);
10144 install_element(ENABLE_NODE
, &no_debug_msdp_cmd
);
10145 install_element(ENABLE_NODE
, &debug_msdp_events_cmd
);
10146 install_element(ENABLE_NODE
, &no_debug_msdp_events_cmd
);
10147 install_element(ENABLE_NODE
, &debug_msdp_packets_cmd
);
10148 install_element(ENABLE_NODE
, &no_debug_msdp_packets_cmd
);
10149 install_element(ENABLE_NODE
, &debug_mtrace_cmd
);
10150 install_element(ENABLE_NODE
, &no_debug_mtrace_cmd
);
10151 install_element(ENABLE_NODE
, &debug_bsm_cmd
);
10152 install_element(ENABLE_NODE
, &no_debug_bsm_cmd
);
10154 install_element(CONFIG_NODE
, &debug_igmp_cmd
);
10155 install_element(CONFIG_NODE
, &no_debug_igmp_cmd
);
10156 install_element(CONFIG_NODE
, &debug_igmp_events_cmd
);
10157 install_element(CONFIG_NODE
, &no_debug_igmp_events_cmd
);
10158 install_element(CONFIG_NODE
, &debug_igmp_packets_cmd
);
10159 install_element(CONFIG_NODE
, &no_debug_igmp_packets_cmd
);
10160 install_element(CONFIG_NODE
, &debug_igmp_trace_cmd
);
10161 install_element(CONFIG_NODE
, &no_debug_igmp_trace_cmd
);
10162 install_element(CONFIG_NODE
, &debug_mroute_cmd
);
10163 install_element(CONFIG_NODE
, &debug_mroute_detail_cmd
);
10164 install_element(CONFIG_NODE
, &no_debug_mroute_cmd
);
10165 install_element(CONFIG_NODE
, &no_debug_mroute_detail_cmd
);
10166 install_element(CONFIG_NODE
, &debug_pim_static_cmd
);
10167 install_element(CONFIG_NODE
, &no_debug_pim_static_cmd
);
10168 install_element(CONFIG_NODE
, &debug_pim_cmd
);
10169 install_element(CONFIG_NODE
, &no_debug_pim_cmd
);
10170 install_element(CONFIG_NODE
, &debug_pim_nht_cmd
);
10171 install_element(CONFIG_NODE
, &no_debug_pim_nht_cmd
);
10172 install_element(CONFIG_NODE
, &debug_pim_nht_rp_cmd
);
10173 install_element(CONFIG_NODE
, &no_debug_pim_nht_rp_cmd
);
10174 install_element(CONFIG_NODE
, &debug_pim_events_cmd
);
10175 install_element(CONFIG_NODE
, &no_debug_pim_events_cmd
);
10176 install_element(CONFIG_NODE
, &debug_pim_packets_cmd
);
10177 install_element(CONFIG_NODE
, &no_debug_pim_packets_cmd
);
10178 install_element(CONFIG_NODE
, &debug_pim_trace_cmd
);
10179 install_element(CONFIG_NODE
, &no_debug_pim_trace_cmd
);
10180 install_element(CONFIG_NODE
, &debug_pim_trace_detail_cmd
);
10181 install_element(CONFIG_NODE
, &no_debug_pim_trace_detail_cmd
);
10182 install_element(CONFIG_NODE
, &debug_ssmpingd_cmd
);
10183 install_element(CONFIG_NODE
, &no_debug_ssmpingd_cmd
);
10184 install_element(CONFIG_NODE
, &debug_pim_zebra_cmd
);
10185 install_element(CONFIG_NODE
, &no_debug_pim_zebra_cmd
);
10186 install_element(CONFIG_NODE
, &debug_pim_vxlan_cmd
);
10187 install_element(CONFIG_NODE
, &no_debug_pim_vxlan_cmd
);
10188 install_element(CONFIG_NODE
, &debug_msdp_cmd
);
10189 install_element(CONFIG_NODE
, &no_debug_msdp_cmd
);
10190 install_element(CONFIG_NODE
, &debug_msdp_events_cmd
);
10191 install_element(CONFIG_NODE
, &no_debug_msdp_events_cmd
);
10192 install_element(CONFIG_NODE
, &debug_msdp_packets_cmd
);
10193 install_element(CONFIG_NODE
, &no_debug_msdp_packets_cmd
);
10194 install_element(CONFIG_NODE
, &debug_mtrace_cmd
);
10195 install_element(CONFIG_NODE
, &no_debug_mtrace_cmd
);
10196 install_element(CONFIG_NODE
, &debug_bsm_cmd
);
10197 install_element(CONFIG_NODE
, &no_debug_bsm_cmd
);
10199 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_member_cmd
);
10200 install_element(VRF_NODE
, &ip_msdp_mesh_group_member_cmd
);
10201 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
10202 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
10203 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_source_cmd
);
10204 install_element(VRF_NODE
, &ip_msdp_mesh_group_source_cmd
);
10205 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
10206 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
10207 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_cmd
);
10208 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_vrf_all_cmd
);
10209 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_cmd
);
10210 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_vrf_all_cmd
);
10211 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_cmd
);
10212 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_vrf_all_cmd
);
10213 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_cmd
);
10214 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_vrf_all_cmd
);
10215 install_element(VIEW_NODE
, &show_ip_pim_ssm_range_cmd
);
10216 install_element(VIEW_NODE
, &show_ip_pim_group_type_cmd
);
10217 install_element(VIEW_NODE
, &show_ip_pim_vxlan_sg_cmd
);
10218 install_element(VIEW_NODE
, &show_ip_pim_vxlan_sg_work_cmd
);
10219 install_element(INTERFACE_NODE
, &interface_pim_use_source_cmd
);
10220 install_element(INTERFACE_NODE
, &interface_no_pim_use_source_cmd
);
10221 /* Install BSM command */
10222 install_element(INTERFACE_NODE
, &ip_pim_bsm_cmd
);
10223 install_element(INTERFACE_NODE
, &no_ip_pim_bsm_cmd
);
10224 install_element(INTERFACE_NODE
, &ip_pim_ucast_bsm_cmd
);
10225 install_element(INTERFACE_NODE
, &no_ip_pim_ucast_bsm_cmd
);
10226 /* Install BFD command */
10227 install_element(INTERFACE_NODE
, &ip_pim_bfd_cmd
);
10228 install_element(INTERFACE_NODE
, &ip_pim_bfd_param_cmd
);
10229 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_cmd
);
10231 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_param_cmd
);
10232 #endif /* !HAVE_BFDD */