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"
68 #ifndef VTYSH_EXTRACT_PL
69 #include "pimd/pim_cmd_clippy.c"
72 static struct cmd_node interface_node
= {
73 INTERFACE_NODE
, "%s(config-if)# ", 1 /* vtysh ? yes */
76 static struct cmd_node debug_node
= {DEBUG_NODE
, "", 1};
78 static struct vrf
*pim_cmd_lookup_vrf(struct vty
*vty
, struct cmd_token
*argv
[],
79 const int argc
, int *idx
)
83 if (argv_find(argv
, argc
, "NAME", idx
))
84 vrf
= vrf_lookup_by_name(argv
[*idx
]->arg
);
86 vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
89 vty_out(vty
, "Specified VRF: %s does not exist\n",
95 static void pim_if_membership_clear(struct interface
*ifp
)
97 struct pim_interface
*pim_ifp
;
102 if (PIM_IF_TEST_PIM(pim_ifp
->options
)
103 && PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
107 pim_ifchannel_membership_clear(ifp
);
111 When PIM is disabled on interface, IGMPv3 local membership
112 information is not injected into PIM interface state.
114 The function pim_if_membership_refresh() fetches all IGMPv3 local
115 membership information into PIM. It is intented to be called
116 whenever PIM is enabled on the interface in order to collect missed
117 local membership information.
119 static void pim_if_membership_refresh(struct interface
*ifp
)
121 struct pim_interface
*pim_ifp
;
122 struct listnode
*sock_node
;
123 struct igmp_sock
*igmp
;
128 if (!PIM_IF_TEST_PIM(pim_ifp
->options
))
130 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
))
134 First clear off membership from all PIM (S,G) entries on the
138 pim_ifchannel_membership_clear(ifp
);
141 Then restore PIM (S,G) membership from all IGMPv3 (S,G) entries on
145 /* scan igmp sockets */
146 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
147 struct listnode
*grpnode
;
148 struct igmp_group
*grp
;
150 /* scan igmp groups */
151 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grpnode
,
153 struct listnode
*srcnode
;
154 struct igmp_source
*src
;
156 /* scan group sources */
157 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
,
160 if (IGMP_SOURCE_TEST_FORWARDING(
161 src
->source_flags
)) {
165 sizeof(struct prefix_sg
));
166 sg
.src
= src
->source_addr
;
167 sg
.grp
= grp
->group_addr
;
168 pim_ifchannel_local_membership_add(ifp
,
172 } /* scan group sources */
173 } /* scan igmp groups */
174 } /* scan igmp sockets */
177 Finally delete every PIM (S,G) entry lacking all state info
180 pim_ifchannel_delete_on_noinfo(ifp
);
183 static void pim_show_assert_helper(struct vty
*vty
,
184 struct pim_interface
*pim_ifp
,
185 struct pim_ifchannel
*ch
, time_t now
)
187 char ch_src_str
[INET_ADDRSTRLEN
];
188 char ch_grp_str
[INET_ADDRSTRLEN
];
189 char winner_str
[INET_ADDRSTRLEN
];
190 struct in_addr ifaddr
;
194 ifaddr
= pim_ifp
->primary_address
;
196 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
197 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
198 pim_inet4_dump("<assrt_win?>", ch
->ifassert_winner
, winner_str
,
201 pim_time_uptime(uptime
, sizeof(uptime
), now
- ch
->ifassert_creation
);
202 pim_time_timer_to_mmss(timer
, sizeof(timer
), ch
->t_ifassert_timer
);
204 vty_out(vty
, "%-16s %-15s %-15s %-15s %-6s %-15s %-8s %-5s\n",
205 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
, ch_grp_str
,
206 pim_ifchannel_ifassert_name(ch
->ifassert_state
), winner_str
,
210 static void pim_show_assert(struct pim_instance
*pim
, struct vty
*vty
)
212 struct pim_interface
*pim_ifp
;
213 struct pim_ifchannel
*ch
;
214 struct interface
*ifp
;
217 now
= pim_time_monotonic_sec();
220 "Interface Address Source Group State Winner Uptime Timer\n");
222 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
227 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
228 pim_show_assert_helper(vty
, pim_ifp
, ch
, now
);
229 } /* scan interface channels */
233 static void pim_show_assert_internal_helper(struct vty
*vty
,
234 struct pim_interface
*pim_ifp
,
235 struct pim_ifchannel
*ch
)
237 char ch_src_str
[INET_ADDRSTRLEN
];
238 char ch_grp_str
[INET_ADDRSTRLEN
];
239 struct in_addr ifaddr
;
241 ifaddr
= pim_ifp
->primary_address
;
243 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
244 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
245 vty_out(vty
, "%-16s %-15s %-15s %-15s %-3s %-3s %-3s %-4s\n",
246 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
, ch_grp_str
,
247 PIM_IF_FLAG_TEST_COULD_ASSERT(ch
->flags
) ? "yes" : "no",
248 pim_macro_ch_could_assert_eval(ch
) ? "yes" : "no",
249 PIM_IF_FLAG_TEST_ASSERT_TRACKING_DESIRED(ch
->flags
) ? "yes"
251 pim_macro_assert_tracking_desired_eval(ch
) ? "yes" : "no");
254 static void pim_show_assert_internal(struct pim_instance
*pim
, struct vty
*vty
)
256 struct pim_interface
*pim_ifp
;
257 struct pim_ifchannel
*ch
;
258 struct interface
*ifp
;
262 "ECA: Evaluate CouldAssert\n"
263 "ATD: AssertTrackingDesired\n"
264 "eATD: Evaluate AssertTrackingDesired\n\n");
267 "Interface Address Source Group CA eCA ATD eATD\n");
268 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
273 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
274 pim_show_assert_internal_helper(vty
, pim_ifp
, ch
);
275 } /* scan interface channels */
279 static void pim_show_assert_metric_helper(struct vty
*vty
,
280 struct pim_interface
*pim_ifp
,
281 struct pim_ifchannel
*ch
)
283 char ch_src_str
[INET_ADDRSTRLEN
];
284 char ch_grp_str
[INET_ADDRSTRLEN
];
285 char addr_str
[INET_ADDRSTRLEN
];
286 struct pim_assert_metric am
;
287 struct in_addr ifaddr
;
289 ifaddr
= pim_ifp
->primary_address
;
291 am
= pim_macro_spt_assert_metric(&ch
->upstream
->rpf
,
292 pim_ifp
->primary_address
);
294 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
295 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
296 pim_inet4_dump("<addr?>", am
.ip_address
, addr_str
, sizeof(addr_str
));
298 vty_out(vty
, "%-16s %-15s %-15s %-15s %-3s %4u %6u %-15s\n",
299 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
, ch_grp_str
,
300 am
.rpt_bit_flag
? "yes" : "no", am
.metric_preference
,
301 am
.route_metric
, addr_str
);
304 static void pim_show_assert_metric(struct pim_instance
*pim
, struct vty
*vty
)
306 struct pim_interface
*pim_ifp
;
307 struct pim_ifchannel
*ch
;
308 struct interface
*ifp
;
311 "Interface Address Source Group RPT Pref Metric Address \n");
313 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
318 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
319 pim_show_assert_metric_helper(vty
, pim_ifp
, ch
);
320 } /* scan interface channels */
324 static void pim_show_assert_winner_metric_helper(struct vty
*vty
,
325 struct pim_interface
*pim_ifp
,
326 struct pim_ifchannel
*ch
)
328 char ch_src_str
[INET_ADDRSTRLEN
];
329 char ch_grp_str
[INET_ADDRSTRLEN
];
330 char addr_str
[INET_ADDRSTRLEN
];
331 struct pim_assert_metric
*am
;
332 struct in_addr ifaddr
;
336 ifaddr
= pim_ifp
->primary_address
;
338 am
= &ch
->ifassert_winner_metric
;
340 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
341 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
342 pim_inet4_dump("<addr?>", am
->ip_address
, addr_str
, sizeof(addr_str
));
344 if (am
->metric_preference
== PIM_ASSERT_METRIC_PREFERENCE_MAX
)
345 snprintf(pref_str
, sizeof(pref_str
), "INFI");
347 snprintf(pref_str
, sizeof(pref_str
), "%4u",
348 am
->metric_preference
);
350 if (am
->route_metric
== PIM_ASSERT_ROUTE_METRIC_MAX
)
351 snprintf(metr_str
, sizeof(metr_str
), "INFI");
353 snprintf(metr_str
, sizeof(metr_str
), "%6u", am
->route_metric
);
355 vty_out(vty
, "%-16s %-15s %-15s %-15s %-3s %-4s %-6s %-15s\n",
356 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
, ch_grp_str
,
357 am
->rpt_bit_flag
? "yes" : "no", pref_str
, metr_str
, addr_str
);
360 static void pim_show_assert_winner_metric(struct pim_instance
*pim
,
363 struct pim_interface
*pim_ifp
;
364 struct pim_ifchannel
*ch
;
365 struct interface
*ifp
;
368 "Interface Address Source Group RPT Pref Metric Address \n");
370 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
375 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
376 pim_show_assert_winner_metric_helper(vty
, pim_ifp
, ch
);
377 } /* scan interface channels */
381 static void json_object_pim_ifp_add(struct json_object
*json
,
382 struct interface
*ifp
)
384 struct pim_interface
*pim_ifp
;
387 json_object_string_add(json
, "name", ifp
->name
);
388 json_object_string_add(json
, "state", if_is_up(ifp
) ? "up" : "down");
389 json_object_string_add(json
, "address",
390 inet_ntoa(pim_ifp
->primary_address
));
391 json_object_int_add(json
, "index", ifp
->ifindex
);
393 if (if_is_multicast(ifp
))
394 json_object_boolean_true_add(json
, "flagMulticast");
396 if (if_is_broadcast(ifp
))
397 json_object_boolean_true_add(json
, "flagBroadcast");
399 if (ifp
->flags
& IFF_ALLMULTI
)
400 json_object_boolean_true_add(json
, "flagAllMulticast");
402 if (ifp
->flags
& IFF_PROMISC
)
403 json_object_boolean_true_add(json
, "flagPromiscuous");
405 if (PIM_IF_IS_DELETED(ifp
))
406 json_object_boolean_true_add(json
, "flagDeleted");
408 if (pim_if_lan_delay_enabled(ifp
))
409 json_object_boolean_true_add(json
, "lanDelayEnabled");
412 static void pim_show_membership_helper(struct vty
*vty
,
413 struct pim_interface
*pim_ifp
,
414 struct pim_ifchannel
*ch
,
415 struct json_object
*json
)
417 char ch_src_str
[INET_ADDRSTRLEN
];
418 char ch_grp_str
[INET_ADDRSTRLEN
];
419 json_object
*json_iface
= NULL
;
420 json_object
*json_row
= NULL
;
422 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
423 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
425 json_object_object_get_ex(json
, ch
->interface
->name
, &json_iface
);
427 json_iface
= json_object_new_object();
428 json_object_pim_ifp_add(json_iface
, ch
->interface
);
429 json_object_object_add(json
, ch
->interface
->name
, json_iface
);
432 json_row
= json_object_new_object();
433 json_object_string_add(json_row
, "source", ch_src_str
);
434 json_object_string_add(json_row
, "group", ch_grp_str
);
435 json_object_string_add(json_row
, "localMembership",
436 ch
->local_ifmembership
== PIM_IFMEMBERSHIP_NOINFO
439 json_object_object_add(json_iface
, ch_grp_str
, json_row
);
441 static void pim_show_membership(struct pim_instance
*pim
, struct vty
*vty
,
444 struct pim_interface
*pim_ifp
;
445 struct pim_ifchannel
*ch
;
446 struct interface
*ifp
;
448 json_object
*json
= NULL
;
449 json_object
*json_tmp
= NULL
;
451 json
= json_object_new_object();
453 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
458 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
459 pim_show_membership_helper(vty
, pim_ifp
, ch
, json
);
460 } /* scan interface channels */
464 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
465 json
, JSON_C_TO_STRING_PRETTY
));
468 "Interface Address Source Group Membership\n");
471 * Example of the json data we are traversing
477 * "address":"10.1.20.1",
479 * "flagMulticast":true,
480 * "flagBroadcast":true,
481 * "lanDelayEnabled":true,
484 * "group":"226.10.10.10",
485 * "localMembership":"INCLUDE"
491 /* foreach interface */
492 json_object_object_foreach(json
, key
, val
)
495 /* Find all of the keys where the val is an object. In
497 * above the only one is 226.10.10.10
499 json_object_object_foreach(val
, if_field_key
,
502 type
= json_object_get_type(if_field_val
);
504 if (type
== json_type_object
) {
505 vty_out(vty
, "%-16s ", key
);
507 json_object_object_get_ex(
508 val
, "address", &json_tmp
);
509 vty_out(vty
, "%-15s ",
510 json_object_get_string(
513 json_object_object_get_ex(if_field_val
,
516 vty_out(vty
, "%-15s ",
517 json_object_get_string(
521 vty_out(vty
, "%-15s ", if_field_key
);
523 json_object_object_get_ex(
524 if_field_val
, "localMembership",
526 vty_out(vty
, "%-10s\n",
527 json_object_get_string(
534 json_object_free(json
);
537 static void pim_print_ifp_flags(struct vty
*vty
, struct interface
*ifp
,
540 vty_out(vty
, "Flags\n");
541 vty_out(vty
, "-----\n");
542 vty_out(vty
, "All Multicast : %s\n",
543 (ifp
->flags
& IFF_ALLMULTI
) ? "yes" : "no");
544 vty_out(vty
, "Broadcast : %s\n",
545 if_is_broadcast(ifp
) ? "yes" : "no");
546 vty_out(vty
, "Deleted : %s\n",
547 PIM_IF_IS_DELETED(ifp
) ? "yes" : "no");
548 vty_out(vty
, "Interface Index : %d\n", ifp
->ifindex
);
549 vty_out(vty
, "Multicast : %s\n",
550 if_is_multicast(ifp
) ? "yes" : "no");
551 vty_out(vty
, "Multicast Loop : %d\n", mloop
);
552 vty_out(vty
, "Promiscuous : %s\n",
553 (ifp
->flags
& IFF_PROMISC
) ? "yes" : "no");
558 static void igmp_show_interfaces(struct pim_instance
*pim
, struct vty
*vty
,
561 struct interface
*ifp
;
563 json_object
*json
= NULL
;
564 json_object
*json_row
= NULL
;
566 now
= pim_time_monotonic_sec();
569 json
= json_object_new_object();
572 "Interface State Address V Querier Query Timer Uptime\n");
574 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
575 struct pim_interface
*pim_ifp
;
576 struct listnode
*sock_node
;
577 struct igmp_sock
*igmp
;
584 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
587 char query_hhmmss
[10];
589 pim_time_uptime(uptime
, sizeof(uptime
),
590 now
- igmp
->sock_creation
);
591 pim_time_timer_to_hhmmss(query_hhmmss
,
592 sizeof(query_hhmmss
),
593 igmp
->t_igmp_query_timer
);
596 json_row
= json_object_new_object();
597 json_object_pim_ifp_add(json_row
, ifp
);
598 json_object_string_add(json_row
, "upTime",
600 json_object_int_add(json_row
, "version",
601 pim_ifp
->igmp_version
);
603 if (igmp
->t_igmp_query_timer
) {
604 json_object_boolean_true_add(json_row
,
606 json_object_string_add(json_row
,
611 json_object_object_add(json
, ifp
->name
,
614 if (igmp
->mtrace_only
) {
615 json_object_boolean_true_add(
616 json_row
, "mtraceOnly");
620 "%-16s %5s %15s %d %7s %11s %8s\n",
623 ? (igmp
->mtrace_only
? "mtrc"
626 inet_ntoa(igmp
->ifaddr
),
627 pim_ifp
->igmp_version
,
628 igmp
->t_igmp_query_timer
? "local"
630 query_hhmmss
, uptime
);
636 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
637 json
, JSON_C_TO_STRING_PRETTY
));
638 json_object_free(json
);
642 static void igmp_show_interfaces_single(struct pim_instance
*pim
,
643 struct vty
*vty
, const char *ifname
,
646 struct igmp_sock
*igmp
;
647 struct interface
*ifp
;
648 struct listnode
*sock_node
;
649 struct pim_interface
*pim_ifp
;
651 char query_hhmmss
[10];
652 char other_hhmmss
[10];
653 int found_ifname
= 0;
656 long gmi_msec
; /* Group Membership Interval */
659 long oqpi_msec
; /* Other Querier Present Interval */
664 json_object
*json
= NULL
;
665 json_object
*json_row
= NULL
;
668 json
= json_object_new_object();
670 now
= pim_time_monotonic_sec();
672 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
678 if (strcmp(ifname
, "detail") && strcmp(ifname
, ifp
->name
))
681 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
684 pim_time_uptime(uptime
, sizeof(uptime
),
685 now
- igmp
->sock_creation
);
686 pim_time_timer_to_hhmmss(query_hhmmss
,
687 sizeof(query_hhmmss
),
688 igmp
->t_igmp_query_timer
);
689 pim_time_timer_to_hhmmss(other_hhmmss
,
690 sizeof(other_hhmmss
),
691 igmp
->t_other_querier_timer
);
693 gmi_msec
= PIM_IGMP_GMI_MSEC(
694 igmp
->querier_robustness_variable
,
695 igmp
->querier_query_interval
,
696 pim_ifp
->igmp_query_max_response_time_dsec
);
699 pim_ifp
->igmp_default_query_interval
);
701 oqpi_msec
= PIM_IGMP_OQPI_MSEC(
702 igmp
->querier_robustness_variable
,
703 igmp
->querier_query_interval
,
704 pim_ifp
->igmp_query_max_response_time_dsec
);
706 lmqt_msec
= PIM_IGMP_LMQT_MSEC(
707 pim_ifp
->igmp_specific_query_max_response_time_dsec
,
708 pim_ifp
->igmp_last_member_query_count
);
712 igmp
->querier_robustness_variable
,
713 igmp
->querier_query_interval
,
714 pim_ifp
->igmp_query_max_response_time_dsec
)
717 qri_msec
= pim_ifp
->igmp_query_max_response_time_dsec
719 if (pim_ifp
->pim_sock_fd
>= 0)
720 mloop
= pim_socket_mcastloop_get(
721 pim_ifp
->pim_sock_fd
);
724 lmqc
= pim_ifp
->igmp_last_member_query_count
;
727 json_row
= json_object_new_object();
728 json_object_pim_ifp_add(json_row
, ifp
);
729 json_object_string_add(json_row
, "upTime",
731 json_object_string_add(json_row
, "querier",
732 igmp
->t_igmp_query_timer
735 json_object_int_add(json_row
, "queryStartCount",
736 igmp
->startup_query_count
);
737 json_object_string_add(json_row
,
740 json_object_string_add(json_row
,
743 json_object_int_add(json_row
, "version",
744 pim_ifp
->igmp_version
);
747 "timerGroupMembershipIntervalMsec",
749 json_object_int_add(json_row
,
750 "lastMemberQueryCount",
752 json_object_int_add(json_row
,
753 "timerLastMemberQueryMsec",
757 "timerOlderHostPresentIntervalMsec",
761 "timerOtherQuerierPresentIntervalMsec",
764 json_row
, "timerQueryInterval",
765 igmp
->querier_query_interval
);
768 "timerQueryResponseIntervalMsec",
771 json_row
, "timerRobustnessVariable",
772 igmp
->querier_robustness_variable
);
773 json_object_int_add(json_row
,
774 "timerStartupQueryInterval",
777 json_object_object_add(json
, ifp
->name
,
780 if (igmp
->mtrace_only
) {
781 json_object_boolean_true_add(
782 json_row
, "mtraceOnly");
785 vty_out(vty
, "Interface : %s\n", ifp
->name
);
786 vty_out(vty
, "State : %s\n",
788 ? (igmp
->mtrace_only
? "mtrace"
791 vty_out(vty
, "Address : %s\n",
792 inet_ntoa(pim_ifp
->primary_address
));
793 vty_out(vty
, "Uptime : %s\n", uptime
);
794 vty_out(vty
, "Version : %d\n",
795 pim_ifp
->igmp_version
);
799 vty_out(vty
, "Querier\n");
800 vty_out(vty
, "-------\n");
801 vty_out(vty
, "Querier : %s\n",
802 igmp
->t_igmp_query_timer
? "local"
804 vty_out(vty
, "Start Count : %d\n",
805 igmp
->startup_query_count
);
806 vty_out(vty
, "Query Timer : %s\n",
808 vty_out(vty
, "Other Timer : %s\n",
813 vty_out(vty
, "Timers\n");
814 vty_out(vty
, "------\n");
816 "Group Membership Interval : %lis\n",
819 "Last Member Query Count : %d\n",
822 "Last Member Query Time : %lis\n",
825 "Older Host Present Interval : %lis\n",
828 "Other Querier Present Interval : %lis\n",
831 "Query Interval : %ds\n",
832 igmp
->querier_query_interval
);
834 "Query Response Interval : %lis\n",
837 "Robustness Variable : %d\n",
838 igmp
->querier_robustness_variable
);
840 "Startup Query Interval : %ds\n",
845 pim_print_ifp_flags(vty
, ifp
, mloop
);
851 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
852 json
, JSON_C_TO_STRING_PRETTY
));
853 json_object_free(json
);
856 vty_out(vty
, "%% No such interface\n");
860 static void igmp_show_interface_join(struct pim_instance
*pim
, struct vty
*vty
)
862 struct interface
*ifp
;
865 now
= pim_time_monotonic_sec();
868 "Interface Address Source Group Socket Uptime \n");
870 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
871 struct pim_interface
*pim_ifp
;
872 struct listnode
*join_node
;
873 struct igmp_join
*ij
;
874 struct in_addr pri_addr
;
875 char pri_addr_str
[INET_ADDRSTRLEN
];
882 if (!pim_ifp
->igmp_join_list
)
885 pri_addr
= pim_find_primary_addr(ifp
);
886 pim_inet4_dump("<pri?>", pri_addr
, pri_addr_str
,
887 sizeof(pri_addr_str
));
889 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_join_list
, join_node
,
891 char group_str
[INET_ADDRSTRLEN
];
892 char source_str
[INET_ADDRSTRLEN
];
895 pim_time_uptime(uptime
, sizeof(uptime
),
896 now
- ij
->sock_creation
);
897 pim_inet4_dump("<grp?>", ij
->group_addr
, group_str
,
899 pim_inet4_dump("<src?>", ij
->source_addr
, source_str
,
902 vty_out(vty
, "%-16s %-15s %-15s %-15s %6d %8s\n",
903 ifp
->name
, pri_addr_str
, source_str
, group_str
,
904 ij
->sock_fd
, uptime
);
905 } /* for (pim_ifp->igmp_join_list) */
910 static void pim_show_interfaces_single(struct pim_instance
*pim
,
911 struct vty
*vty
, const char *ifname
,
914 struct in_addr ifaddr
;
915 struct interface
*ifp
;
916 struct listnode
*neighnode
;
917 struct listnode
*upnode
;
918 struct pim_interface
*pim_ifp
;
919 struct pim_neighbor
*neigh
;
920 struct pim_upstream
*up
;
922 char dr_str
[INET_ADDRSTRLEN
];
925 char grp_str
[INET_ADDRSTRLEN
];
926 char hello_period
[10];
927 char hello_timer
[10];
928 char neigh_src_str
[INET_ADDRSTRLEN
];
929 char src_str
[INET_ADDRSTRLEN
];
930 char stat_uptime
[10];
933 int found_ifname
= 0;
935 json_object
*json
= NULL
;
936 json_object
*json_row
= NULL
;
937 json_object
*json_pim_neighbor
= NULL
;
938 json_object
*json_pim_neighbors
= NULL
;
939 json_object
*json_group
= NULL
;
940 json_object
*json_group_source
= NULL
;
941 json_object
*json_fhr_sources
= NULL
;
942 struct pim_secondary_addr
*sec_addr
;
943 struct listnode
*sec_node
;
945 now
= pim_time_monotonic_sec();
948 json
= json_object_new_object();
950 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
956 if (strcmp(ifname
, "detail") && strcmp(ifname
, ifp
->name
))
960 ifaddr
= pim_ifp
->primary_address
;
961 pim_inet4_dump("<dr?>", pim_ifp
->pim_dr_addr
, dr_str
,
963 pim_time_uptime_begin(dr_uptime
, sizeof(dr_uptime
), now
,
964 pim_ifp
->pim_dr_election_last
);
965 pim_time_timer_to_hhmmss(hello_timer
, sizeof(hello_timer
),
966 pim_ifp
->t_pim_hello_timer
);
967 pim_time_mmss(hello_period
, sizeof(hello_period
),
968 pim_ifp
->pim_hello_period
);
969 pim_time_uptime(stat_uptime
, sizeof(stat_uptime
),
970 now
- pim_ifp
->pim_ifstat_start
);
971 if (pim_ifp
->pim_sock_fd
>= 0)
972 mloop
= pim_socket_mcastloop_get(pim_ifp
->pim_sock_fd
);
977 char pbuf
[PREFIX2STR_BUFFER
];
978 json_row
= json_object_new_object();
979 json_object_pim_ifp_add(json_row
, ifp
);
981 if (pim_ifp
->update_source
.s_addr
!= INADDR_ANY
) {
982 json_object_string_add(
983 json_row
, "useSource",
984 inet_ntoa(pim_ifp
->update_source
));
986 if (pim_ifp
->sec_addr_list
) {
987 json_object
*sec_list
= NULL
;
989 sec_list
= json_object_new_array();
990 for (ALL_LIST_ELEMENTS_RO(
991 pim_ifp
->sec_addr_list
, sec_node
,
993 json_object_array_add(
995 json_object_new_string(
1001 json_object_object_add(json_row
,
1002 "secondaryAddressList",
1007 if (pim_ifp
->pim_neighbor_list
->count
) {
1008 json_pim_neighbors
= json_object_new_object();
1010 for (ALL_LIST_ELEMENTS_RO(
1011 pim_ifp
->pim_neighbor_list
,
1012 neighnode
, neigh
)) {
1014 json_object_new_object();
1015 pim_inet4_dump("<src?>",
1018 sizeof(neigh_src_str
));
1019 pim_time_uptime(uptime
, sizeof(uptime
),
1020 now
- neigh
->creation
);
1021 pim_time_timer_to_hhmmss(
1022 expire
, sizeof(expire
),
1023 neigh
->t_expire_timer
);
1025 json_object_string_add(
1026 json_pim_neighbor
, "address",
1028 json_object_string_add(
1029 json_pim_neighbor
, "upTime",
1031 json_object_string_add(
1032 json_pim_neighbor
, "holdtime",
1035 json_object_object_add(
1041 json_object_object_add(json_row
, "neighbors",
1042 json_pim_neighbors
);
1045 json_object_string_add(json_row
, "drAddress", dr_str
);
1046 json_object_int_add(json_row
, "drPriority",
1047 pim_ifp
->pim_dr_priority
);
1048 json_object_string_add(json_row
, "drUptime", dr_uptime
);
1049 json_object_int_add(json_row
, "drElections",
1050 pim_ifp
->pim_dr_election_count
);
1051 json_object_int_add(json_row
, "drChanges",
1052 pim_ifp
->pim_dr_election_changes
);
1055 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
,
1057 if (ifp
!= up
->rpf
.source_nexthop
.interface
)
1060 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
))
1063 if (!json_fhr_sources
)
1065 json_object_new_object();
1067 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
,
1069 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
,
1071 pim_time_uptime(uptime
, sizeof(uptime
),
1072 now
- up
->state_transition
);
1075 * Does this group live in json_fhr_sources?
1078 json_object_object_get_ex(json_fhr_sources
,
1079 grp_str
, &json_group
);
1082 json_group
= json_object_new_object();
1083 json_object_object_add(json_fhr_sources
,
1088 json_group_source
= json_object_new_object();
1089 json_object_string_add(json_group_source
,
1091 json_object_string_add(json_group_source
,
1093 json_object_string_add(json_group_source
,
1095 json_object_object_add(json_group
, src_str
,
1099 if (json_fhr_sources
) {
1100 json_object_object_add(json_row
,
1105 json_object_int_add(json_row
, "helloPeriod",
1106 pim_ifp
->pim_hello_period
);
1107 json_object_string_add(json_row
, "helloTimer",
1109 json_object_string_add(json_row
, "helloStatStart",
1111 json_object_int_add(json_row
, "helloReceived",
1112 pim_ifp
->pim_ifstat_hello_recv
);
1113 json_object_int_add(json_row
, "helloReceivedFailed",
1114 pim_ifp
->pim_ifstat_hello_recvfail
);
1115 json_object_int_add(json_row
, "helloSend",
1116 pim_ifp
->pim_ifstat_hello_sent
);
1117 json_object_int_add(json_row
, "hellosendFailed",
1118 pim_ifp
->pim_ifstat_hello_sendfail
);
1119 json_object_int_add(json_row
, "helloGenerationId",
1120 pim_ifp
->pim_generation_id
);
1121 json_object_int_add(json_row
, "flagMulticastLoop",
1124 json_object_int_add(
1125 json_row
, "effectivePropagationDelay",
1126 pim_if_effective_propagation_delay_msec(ifp
));
1127 json_object_int_add(
1128 json_row
, "effectiveOverrideInterval",
1129 pim_if_effective_override_interval_msec(ifp
));
1130 json_object_int_add(
1131 json_row
, "joinPruneOverrideInterval",
1132 pim_if_jp_override_interval_msec(ifp
));
1134 json_object_int_add(
1135 json_row
, "propagationDelay",
1136 pim_ifp
->pim_propagation_delay_msec
);
1137 json_object_int_add(
1138 json_row
, "propagationDelayHighest",
1139 pim_ifp
->pim_neighbors_highest_propagation_delay_msec
);
1140 json_object_int_add(
1141 json_row
, "overrideInterval",
1142 pim_ifp
->pim_override_interval_msec
);
1143 json_object_int_add(
1144 json_row
, "overrideIntervalHighest",
1145 pim_ifp
->pim_neighbors_highest_override_interval_msec
);
1146 json_object_object_add(json
, ifp
->name
, json_row
);
1149 vty_out(vty
, "Interface : %s\n", ifp
->name
);
1150 vty_out(vty
, "State : %s\n",
1151 if_is_up(ifp
) ? "up" : "down");
1152 if (pim_ifp
->update_source
.s_addr
!= INADDR_ANY
) {
1153 vty_out(vty
, "Use Source : %s\n",
1154 inet_ntoa(pim_ifp
->update_source
));
1156 if (pim_ifp
->sec_addr_list
) {
1157 char pbuf
[PREFIX2STR_BUFFER
];
1158 vty_out(vty
, "Address : %s (primary)\n",
1160 for (ALL_LIST_ELEMENTS_RO(
1161 pim_ifp
->sec_addr_list
, sec_node
,
1163 vty_out(vty
, " %s\n",
1164 prefix2str(&sec_addr
->addr
,
1165 pbuf
, sizeof(pbuf
)));
1168 vty_out(vty
, "Address : %s\n",
1176 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
,
1177 neighnode
, neigh
)) {
1180 vty_out(vty
, "PIM Neighbors\n");
1181 vty_out(vty
, "-------------\n");
1185 pim_inet4_dump("<src?>", neigh
->source_addr
,
1187 sizeof(neigh_src_str
));
1188 pim_time_uptime(uptime
, sizeof(uptime
),
1189 now
- neigh
->creation
);
1190 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
1191 neigh
->t_expire_timer
);
1193 "%-15s : up for %s, holdtime expires in %s\n",
1194 neigh_src_str
, uptime
, expire
);
1197 if (!print_header
) {
1202 vty_out(vty
, "Designated Router\n");
1203 vty_out(vty
, "-----------------\n");
1204 vty_out(vty
, "Address : %s\n", dr_str
);
1205 vty_out(vty
, "Priority : %u(%d)\n",
1206 pim_ifp
->pim_dr_priority
,
1207 pim_ifp
->pim_dr_num_nondrpri_neighbors
);
1208 vty_out(vty
, "Uptime : %s\n", dr_uptime
);
1209 vty_out(vty
, "Elections : %d\n",
1210 pim_ifp
->pim_dr_election_count
);
1211 vty_out(vty
, "Changes : %d\n",
1212 pim_ifp
->pim_dr_election_changes
);
1218 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
,
1220 if (!up
->rpf
.source_nexthop
.interface
)
1223 if (strcmp(ifp
->name
,
1224 up
->rpf
.source_nexthop
1229 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
))
1234 "FHR - First Hop Router\n");
1236 "----------------------\n");
1240 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
,
1242 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
,
1244 pim_time_uptime(uptime
, sizeof(uptime
),
1245 now
- up
->state_transition
);
1247 "%s : %s is a source, uptime is %s\n",
1248 grp_str
, src_str
, uptime
);
1251 if (!print_header
) {
1256 vty_out(vty
, "Hellos\n");
1257 vty_out(vty
, "------\n");
1258 vty_out(vty
, "Period : %d\n",
1259 pim_ifp
->pim_hello_period
);
1260 vty_out(vty
, "Timer : %s\n", hello_timer
);
1261 vty_out(vty
, "StatStart : %s\n", stat_uptime
);
1262 vty_out(vty
, "Receive : %d\n",
1263 pim_ifp
->pim_ifstat_hello_recv
);
1264 vty_out(vty
, "Receive Failed : %d\n",
1265 pim_ifp
->pim_ifstat_hello_recvfail
);
1266 vty_out(vty
, "Send : %d\n",
1267 pim_ifp
->pim_ifstat_hello_sent
);
1268 vty_out(vty
, "Send Failed : %d\n",
1269 pim_ifp
->pim_ifstat_hello_sendfail
);
1270 vty_out(vty
, "Generation ID : %08x\n",
1271 pim_ifp
->pim_generation_id
);
1275 pim_print_ifp_flags(vty
, ifp
, mloop
);
1277 vty_out(vty
, "Join Prune Interval\n");
1278 vty_out(vty
, "-------------------\n");
1279 vty_out(vty
, "LAN Delay : %s\n",
1280 pim_if_lan_delay_enabled(ifp
) ? "yes" : "no");
1281 vty_out(vty
, "Effective Propagation Delay : %d msec\n",
1282 pim_if_effective_propagation_delay_msec(ifp
));
1283 vty_out(vty
, "Effective Override Interval : %d msec\n",
1284 pim_if_effective_override_interval_msec(ifp
));
1285 vty_out(vty
, "Join Prune Override Interval : %d msec\n",
1286 pim_if_jp_override_interval_msec(ifp
));
1290 vty_out(vty
, "LAN Prune Delay\n");
1291 vty_out(vty
, "---------------\n");
1292 vty_out(vty
, "Propagation Delay : %d msec\n",
1293 pim_ifp
->pim_propagation_delay_msec
);
1294 vty_out(vty
, "Propagation Delay (Highest) : %d msec\n",
1295 pim_ifp
->pim_neighbors_highest_propagation_delay_msec
);
1296 vty_out(vty
, "Override Interval : %d msec\n",
1297 pim_ifp
->pim_override_interval_msec
);
1298 vty_out(vty
, "Override Interval (Highest) : %d msec\n",
1299 pim_ifp
->pim_neighbors_highest_override_interval_msec
);
1306 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1307 json
, JSON_C_TO_STRING_PRETTY
));
1308 json_object_free(json
);
1311 vty_out(vty
, "%% No such interface\n");
1315 static void igmp_show_statistics(struct pim_instance
*pim
, struct vty
*vty
,
1316 const char *ifname
, bool uj
)
1318 struct interface
*ifp
;
1319 struct igmp_stats rx_stats
;
1321 igmp_stats_init(&rx_stats
);
1323 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1324 struct pim_interface
*pim_ifp
;
1325 struct listnode
*sock_node
;
1326 struct igmp_sock
*igmp
;
1328 pim_ifp
= ifp
->info
;
1333 if (ifname
&& strcmp(ifname
, ifp
->name
))
1336 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
1338 igmp_stats_add(&rx_stats
, &igmp
->rx_stats
);
1342 json_object
*json
= NULL
;
1343 json_object
*json_row
= NULL
;
1345 json
= json_object_new_object();
1346 json_row
= json_object_new_object();
1348 json_object_string_add(json_row
, "name", ifname
? ifname
:
1350 json_object_int_add(json_row
, "queryV1", rx_stats
.query_v1
);
1351 json_object_int_add(json_row
, "queryV2", rx_stats
.query_v2
);
1352 json_object_int_add(json_row
, "queryV3", rx_stats
.query_v3
);
1353 json_object_int_add(json_row
, "leaveV3", rx_stats
.leave_v2
);
1354 json_object_int_add(json_row
, "reportV1", rx_stats
.report_v1
);
1355 json_object_int_add(json_row
, "reportV2", rx_stats
.report_v2
);
1356 json_object_int_add(json_row
, "reportV3", rx_stats
.report_v3
);
1357 json_object_int_add(json_row
, "mtraceResponse",
1358 rx_stats
.mtrace_rsp
);
1359 json_object_int_add(json_row
, "mtraceRequest",
1360 rx_stats
.mtrace_req
);
1361 json_object_int_add(json_row
, "unsupported",
1362 rx_stats
.unsupported
);
1363 json_object_object_add(json
, ifname
? ifname
: "global",
1365 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1366 json
, JSON_C_TO_STRING_PRETTY
));
1367 json_object_free(json
);
1369 vty_out(vty
, "IGMP RX statistics\n");
1370 vty_out(vty
, "Interface : %s\n",
1371 ifname
? ifname
: "global");
1372 vty_out(vty
, "V1 query : %u\n", rx_stats
.query_v1
);
1373 vty_out(vty
, "V2 query : %u\n", rx_stats
.query_v2
);
1374 vty_out(vty
, "V3 query : %u\n", rx_stats
.query_v3
);
1375 vty_out(vty
, "V2 leave : %u\n", rx_stats
.leave_v2
);
1376 vty_out(vty
, "V1 report : %u\n", rx_stats
.report_v1
);
1377 vty_out(vty
, "V2 report : %u\n", rx_stats
.report_v2
);
1378 vty_out(vty
, "V3 report : %u\n", rx_stats
.report_v3
);
1379 vty_out(vty
, "mtrace response : %u\n", rx_stats
.mtrace_rsp
);
1380 vty_out(vty
, "mtrace request : %u\n", rx_stats
.mtrace_req
);
1381 vty_out(vty
, "unsupported : %u\n", rx_stats
.unsupported
);
1385 static void pim_show_interfaces(struct pim_instance
*pim
, struct vty
*vty
,
1388 struct interface
*ifp
;
1389 struct listnode
*upnode
;
1390 struct pim_interface
*pim_ifp
;
1391 struct pim_upstream
*up
;
1394 int pim_ifchannels
= 0;
1395 json_object
*json
= NULL
;
1396 json_object
*json_row
= NULL
;
1397 json_object
*json_tmp
;
1399 json
= json_object_new_object();
1401 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1402 pim_ifp
= ifp
->info
;
1407 pim_nbrs
= pim_ifp
->pim_neighbor_list
->count
;
1408 pim_ifchannels
= pim_if_ifchannel_count(pim_ifp
);
1411 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
, up
))
1412 if (ifp
== up
->rpf
.source_nexthop
.interface
)
1413 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
1416 json_row
= json_object_new_object();
1417 json_object_pim_ifp_add(json_row
, ifp
);
1418 json_object_int_add(json_row
, "pimNeighbors", pim_nbrs
);
1419 json_object_int_add(json_row
, "pimIfChannels", pim_ifchannels
);
1420 json_object_int_add(json_row
, "firstHopRouterCount", fhr
);
1421 json_object_string_add(json_row
, "pimDesignatedRouter",
1422 inet_ntoa(pim_ifp
->pim_dr_addr
));
1424 if (pim_ifp
->pim_dr_addr
.s_addr
1425 == pim_ifp
->primary_address
.s_addr
)
1426 json_object_boolean_true_add(
1427 json_row
, "pimDesignatedRouterLocal");
1429 json_object_object_add(json
, ifp
->name
, json_row
);
1433 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1434 json
, JSON_C_TO_STRING_PRETTY
));
1437 "Interface State Address PIM Nbrs PIM DR FHR IfChannels\n");
1439 json_object_object_foreach(json
, key
, val
)
1441 vty_out(vty
, "%-16s ", key
);
1443 json_object_object_get_ex(val
, "state", &json_tmp
);
1444 vty_out(vty
, "%5s ", json_object_get_string(json_tmp
));
1446 json_object_object_get_ex(val
, "address", &json_tmp
);
1447 vty_out(vty
, "%15s ",
1448 json_object_get_string(json_tmp
));
1450 json_object_object_get_ex(val
, "pimNeighbors",
1452 vty_out(vty
, "%8d ", json_object_get_int(json_tmp
));
1454 if (json_object_object_get_ex(
1455 val
, "pimDesignatedRouterLocal",
1457 vty_out(vty
, "%15s ", "local");
1459 json_object_object_get_ex(
1460 val
, "pimDesignatedRouter", &json_tmp
);
1461 vty_out(vty
, "%15s ",
1462 json_object_get_string(json_tmp
));
1465 json_object_object_get_ex(val
, "firstHopRouter",
1467 vty_out(vty
, "%3d ", json_object_get_int(json_tmp
));
1469 json_object_object_get_ex(val
, "pimIfChannels",
1471 vty_out(vty
, "%9d\n", json_object_get_int(json_tmp
));
1475 json_object_free(json
);
1478 static void pim_show_interface_traffic(struct pim_instance
*pim
,
1479 struct vty
*vty
, bool uj
)
1481 struct interface
*ifp
= NULL
;
1482 struct pim_interface
*pim_ifp
= NULL
;
1483 json_object
*json
= NULL
;
1484 json_object
*json_row
= NULL
;
1487 json
= json_object_new_object();
1490 vty_out(vty
, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s%-17s\n",
1491 "Interface", " HELLO", " JOIN",
1492 " PRUNE", " REGISTER", "REGISTER-STOP",
1494 vty_out(vty
, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s%-17s\n", "",
1495 " Rx/Tx", " Rx/Tx", " Rx/Tx",
1496 " Rx/Tx", " Rx/Tx", " Rx/Tx",
1499 "---------------------------------------------------------------------------------------------------------------\n");
1502 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1503 pim_ifp
= ifp
->info
;
1508 if (pim_ifp
->pim_sock_fd
< 0)
1511 json_row
= json_object_new_object();
1512 json_object_pim_ifp_add(json_row
, ifp
);
1513 json_object_int_add(json_row
, "helloRx",
1514 pim_ifp
->pim_ifstat_hello_recv
);
1515 json_object_int_add(json_row
, "helloTx",
1516 pim_ifp
->pim_ifstat_hello_sent
);
1517 json_object_int_add(json_row
, "joinRx",
1518 pim_ifp
->pim_ifstat_join_recv
);
1519 json_object_int_add(json_row
, "joinTx",
1520 pim_ifp
->pim_ifstat_join_send
);
1521 json_object_int_add(json_row
, "registerRx",
1522 pim_ifp
->pim_ifstat_reg_recv
);
1523 json_object_int_add(json_row
, "registerTx",
1524 pim_ifp
->pim_ifstat_reg_recv
);
1525 json_object_int_add(json_row
, "registerStopRx",
1526 pim_ifp
->pim_ifstat_reg_stop_recv
);
1527 json_object_int_add(json_row
, "registerStopTx",
1528 pim_ifp
->pim_ifstat_reg_stop_send
);
1529 json_object_int_add(json_row
, "assertRx",
1530 pim_ifp
->pim_ifstat_assert_recv
);
1531 json_object_int_add(json_row
, "assertTx",
1532 pim_ifp
->pim_ifstat_assert_send
);
1533 json_object_int_add(json_row
, "bsmRx",
1534 pim_ifp
->pim_ifstat_bsm_rx
);
1535 json_object_int_add(json_row
, "bsmTx",
1536 pim_ifp
->pim_ifstat_bsm_tx
);
1537 json_object_object_add(json
, ifp
->name
, json_row
);
1540 "%-16s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7" PRIu64
"/%-7" PRIu64
"\n",
1541 ifp
->name
, pim_ifp
->pim_ifstat_hello_recv
,
1542 pim_ifp
->pim_ifstat_hello_sent
,
1543 pim_ifp
->pim_ifstat_join_recv
,
1544 pim_ifp
->pim_ifstat_join_send
,
1545 pim_ifp
->pim_ifstat_prune_recv
,
1546 pim_ifp
->pim_ifstat_prune_send
,
1547 pim_ifp
->pim_ifstat_reg_recv
,
1548 pim_ifp
->pim_ifstat_reg_send
,
1549 pim_ifp
->pim_ifstat_reg_stop_recv
,
1550 pim_ifp
->pim_ifstat_reg_stop_send
,
1551 pim_ifp
->pim_ifstat_assert_recv
,
1552 pim_ifp
->pim_ifstat_assert_send
,
1553 pim_ifp
->pim_ifstat_bsm_rx
,
1554 pim_ifp
->pim_ifstat_bsm_tx
);
1558 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1559 json
, JSON_C_TO_STRING_PRETTY
));
1560 json_object_free(json
);
1564 static void pim_show_interface_traffic_single(struct pim_instance
*pim
,
1566 const char *ifname
, bool uj
)
1568 struct interface
*ifp
= NULL
;
1569 struct pim_interface
*pim_ifp
= NULL
;
1570 json_object
*json
= NULL
;
1571 json_object
*json_row
= NULL
;
1572 uint8_t found_ifname
= 0;
1575 json
= json_object_new_object();
1578 vty_out(vty
, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s%-17s\n",
1579 "Interface", " HELLO", " JOIN", " PRUNE",
1580 " REGISTER", " REGISTER-STOP", " ASSERT",
1582 vty_out(vty
, "%-14s%-18s%-17s%-17s%-17s%-17s%-17s%-17s\n", "",
1583 " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1584 " Rx/Tx", " Rx/Tx", " Rx/Tx");
1586 "-------------------------------------------------------------------------------------------------------------------------------\n");
1589 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1590 if (strcmp(ifname
, ifp
->name
))
1593 pim_ifp
= ifp
->info
;
1598 if (pim_ifp
->pim_sock_fd
< 0)
1603 json_row
= json_object_new_object();
1604 json_object_pim_ifp_add(json_row
, ifp
);
1605 json_object_int_add(json_row
, "helloRx",
1606 pim_ifp
->pim_ifstat_hello_recv
);
1607 json_object_int_add(json_row
, "helloTx",
1608 pim_ifp
->pim_ifstat_hello_sent
);
1609 json_object_int_add(json_row
, "joinRx",
1610 pim_ifp
->pim_ifstat_join_recv
);
1611 json_object_int_add(json_row
, "joinTx",
1612 pim_ifp
->pim_ifstat_join_send
);
1613 json_object_int_add(json_row
, "registerRx",
1614 pim_ifp
->pim_ifstat_reg_recv
);
1615 json_object_int_add(json_row
, "registerTx",
1616 pim_ifp
->pim_ifstat_reg_recv
);
1617 json_object_int_add(json_row
, "registerStopRx",
1618 pim_ifp
->pim_ifstat_reg_stop_recv
);
1619 json_object_int_add(json_row
, "registerStopTx",
1620 pim_ifp
->pim_ifstat_reg_stop_send
);
1621 json_object_int_add(json_row
, "assertRx",
1622 pim_ifp
->pim_ifstat_assert_recv
);
1623 json_object_int_add(json_row
, "assertTx",
1624 pim_ifp
->pim_ifstat_assert_send
);
1625 json_object_int_add(json_row
, "bsmRx",
1626 pim_ifp
->pim_ifstat_bsm_rx
);
1627 json_object_int_add(json_row
, "bsmTx",
1628 pim_ifp
->pim_ifstat_bsm_tx
);
1630 json_object_object_add(json
, ifp
->name
, json_row
);
1633 "%-16s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7" PRIu64
"/%-7" PRIu64
"\n",
1634 ifp
->name
, pim_ifp
->pim_ifstat_hello_recv
,
1635 pim_ifp
->pim_ifstat_hello_sent
,
1636 pim_ifp
->pim_ifstat_join_recv
,
1637 pim_ifp
->pim_ifstat_join_send
,
1638 pim_ifp
->pim_ifstat_prune_recv
,
1639 pim_ifp
->pim_ifstat_prune_send
,
1640 pim_ifp
->pim_ifstat_reg_recv
,
1641 pim_ifp
->pim_ifstat_reg_send
,
1642 pim_ifp
->pim_ifstat_reg_stop_recv
,
1643 pim_ifp
->pim_ifstat_reg_stop_send
,
1644 pim_ifp
->pim_ifstat_assert_recv
,
1645 pim_ifp
->pim_ifstat_assert_send
,
1646 pim_ifp
->pim_ifstat_bsm_rx
,
1647 pim_ifp
->pim_ifstat_bsm_tx
);
1651 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1652 json
, JSON_C_TO_STRING_PRETTY
));
1653 json_object_free(json
);
1656 vty_out(vty
, "%% No such interface\n");
1660 static void pim_show_join_helper(struct vty
*vty
, struct pim_interface
*pim_ifp
,
1661 struct pim_ifchannel
*ch
, json_object
*json
,
1662 time_t now
, bool uj
)
1664 char ch_src_str
[INET_ADDRSTRLEN
];
1665 char ch_grp_str
[INET_ADDRSTRLEN
];
1666 json_object
*json_iface
= NULL
;
1667 json_object
*json_row
= NULL
;
1668 json_object
*json_grp
= NULL
;
1669 struct in_addr ifaddr
;
1674 ifaddr
= pim_ifp
->primary_address
;
1676 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
1677 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
1679 pim_time_uptime_begin(uptime
, sizeof(uptime
), now
, ch
->ifjoin_creation
);
1680 pim_time_timer_to_mmss(expire
, sizeof(expire
),
1681 ch
->t_ifjoin_expiry_timer
);
1682 pim_time_timer_to_mmss(prune
, sizeof(prune
),
1683 ch
->t_ifjoin_prune_pending_timer
);
1686 json_object_object_get_ex(json
, ch
->interface
->name
,
1690 json_iface
= json_object_new_object();
1691 json_object_pim_ifp_add(json_iface
, ch
->interface
);
1692 json_object_object_add(json
, ch
->interface
->name
,
1696 json_row
= json_object_new_object();
1697 json_object_string_add(json_row
, "source", ch_src_str
);
1698 json_object_string_add(json_row
, "group", ch_grp_str
);
1699 json_object_string_add(json_row
, "upTime", uptime
);
1700 json_object_string_add(json_row
, "expire", expire
);
1701 json_object_string_add(json_row
, "prune", prune
);
1702 json_object_string_add(
1703 json_row
, "channelJoinName",
1704 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
, ch
->flags
));
1705 if (PIM_IF_FLAG_TEST_S_G_RPT(ch
->flags
))
1706 json_object_int_add(json_row
, "SGRpt", 1);
1708 json_object_object_get_ex(json_iface
, ch_grp_str
, &json_grp
);
1710 json_grp
= json_object_new_object();
1711 json_object_object_add(json_grp
, ch_src_str
, json_row
);
1712 json_object_object_add(json_iface
, ch_grp_str
,
1715 json_object_object_add(json_grp
, ch_src_str
, json_row
);
1717 vty_out(vty
, "%-16s %-15s %-15s %-15s %-10s %8s %-6s %5s\n",
1718 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
,
1720 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
, ch
->flags
),
1721 uptime
, expire
, prune
);
1725 static void pim_show_join(struct pim_instance
*pim
, struct vty
*vty
,
1726 struct prefix_sg
*sg
, bool uj
)
1728 struct pim_interface
*pim_ifp
;
1729 struct pim_ifchannel
*ch
;
1730 struct interface
*ifp
;
1732 json_object
*json
= NULL
;
1734 now
= pim_time_monotonic_sec();
1737 json
= json_object_new_object();
1740 "Interface Address Source Group State Uptime Expire Prune\n");
1742 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1743 pim_ifp
= ifp
->info
;
1747 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
1748 if (sg
->grp
.s_addr
!= 0
1749 && sg
->grp
.s_addr
!= ch
->sg
.grp
.s_addr
)
1751 if (sg
->src
.s_addr
!= 0
1752 && sg
->src
.s_addr
!= ch
->sg
.src
.s_addr
)
1754 pim_show_join_helper(vty
, pim_ifp
, ch
, json
, now
, uj
);
1755 } /* scan interface channels */
1759 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1760 json
, JSON_C_TO_STRING_PRETTY
));
1761 json_object_free(json
);
1765 static void pim_show_neighbors_single(struct pim_instance
*pim
, struct vty
*vty
,
1766 const char *neighbor
, bool uj
)
1768 struct listnode
*neighnode
;
1769 struct interface
*ifp
;
1770 struct pim_interface
*pim_ifp
;
1771 struct pim_neighbor
*neigh
;
1773 int found_neighbor
= 0;
1774 int option_address_list
;
1775 int option_dr_priority
;
1776 int option_generation_id
;
1777 int option_holdtime
;
1778 int option_lan_prune_delay
;
1782 char neigh_src_str
[INET_ADDRSTRLEN
];
1784 json_object
*json
= NULL
;
1785 json_object
*json_ifp
= NULL
;
1786 json_object
*json_row
= NULL
;
1788 now
= pim_time_monotonic_sec();
1791 json
= json_object_new_object();
1793 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1794 pim_ifp
= ifp
->info
;
1799 if (pim_ifp
->pim_sock_fd
< 0)
1802 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
1804 pim_inet4_dump("<src?>", neigh
->source_addr
,
1805 neigh_src_str
, sizeof(neigh_src_str
));
1808 * The user can specify either the interface name or the
1810 * If this pim_ifp matches neither then skip.
1812 if (strcmp(neighbor
, "detail")
1813 && strcmp(neighbor
, ifp
->name
)
1814 && strcmp(neighbor
, neigh_src_str
))
1818 pim_time_uptime(uptime
, sizeof(uptime
),
1819 now
- neigh
->creation
);
1820 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
1821 neigh
->t_expire_timer
);
1823 option_address_list
= 0;
1824 option_dr_priority
= 0;
1825 option_generation_id
= 0;
1826 option_holdtime
= 0;
1827 option_lan_prune_delay
= 0;
1830 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1831 PIM_OPTION_MASK_ADDRESS_LIST
))
1832 option_address_list
= 1;
1834 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1835 PIM_OPTION_MASK_DR_PRIORITY
))
1836 option_dr_priority
= 1;
1838 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1839 PIM_OPTION_MASK_GENERATION_ID
))
1840 option_generation_id
= 1;
1842 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1843 PIM_OPTION_MASK_HOLDTIME
))
1844 option_holdtime
= 1;
1846 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1847 PIM_OPTION_MASK_LAN_PRUNE_DELAY
))
1848 option_lan_prune_delay
= 1;
1850 if (PIM_OPTION_IS_SET(
1851 neigh
->hello_options
,
1852 PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION
))
1857 /* Does this ifp live in json? If not create
1859 json_object_object_get_ex(json
, ifp
->name
,
1863 json_ifp
= json_object_new_object();
1864 json_object_pim_ifp_add(json_ifp
, ifp
);
1865 json_object_object_add(json
, ifp
->name
,
1869 json_row
= json_object_new_object();
1870 json_object_string_add(json_row
, "interface",
1872 json_object_string_add(json_row
, "address",
1874 json_object_string_add(json_row
, "upTime",
1876 json_object_string_add(json_row
, "holdtime",
1878 json_object_int_add(json_row
, "drPriority",
1879 neigh
->dr_priority
);
1880 json_object_int_add(json_row
, "generationId",
1881 neigh
->generation_id
);
1883 if (option_address_list
)
1884 json_object_boolean_true_add(
1886 "helloOptionAddressList");
1888 if (option_dr_priority
)
1889 json_object_boolean_true_add(
1891 "helloOptionDrPriority");
1893 if (option_generation_id
)
1894 json_object_boolean_true_add(
1896 "helloOptionGenerationId");
1898 if (option_holdtime
)
1899 json_object_boolean_true_add(
1901 "helloOptionHoldtime");
1903 if (option_lan_prune_delay
)
1904 json_object_boolean_true_add(
1906 "helloOptionLanPruneDelay");
1909 json_object_boolean_true_add(
1910 json_row
, "helloOptionTBit");
1912 json_object_object_add(json_ifp
, neigh_src_str
,
1916 vty_out(vty
, "Interface : %s\n", ifp
->name
);
1917 vty_out(vty
, "Neighbor : %s\n", neigh_src_str
);
1925 " DR Priority : %d\n",
1926 neigh
->dr_priority
);
1928 " Generation ID : %08x\n",
1929 neigh
->generation_id
);
1931 " Override Interval (msec) : %d\n",
1932 neigh
->override_interval_msec
);
1934 " Propagation Delay (msec) : %d\n",
1935 neigh
->propagation_delay_msec
);
1937 " Hello Option - Address List : %s\n",
1938 option_address_list
? "yes" : "no");
1940 " Hello Option - DR Priority : %s\n",
1941 option_dr_priority
? "yes" : "no");
1943 " Hello Option - Generation ID : %s\n",
1944 option_generation_id
? "yes" : "no");
1946 " Hello Option - Holdtime : %s\n",
1947 option_holdtime
? "yes" : "no");
1949 " Hello Option - LAN Prune Delay : %s\n",
1950 option_lan_prune_delay
? "yes" : "no");
1952 " Hello Option - T-bit : %s\n",
1953 option_t_bit
? "yes" : "no");
1954 pim_bfd_show_info(vty
, neigh
->bfd_info
,
1962 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1963 json
, JSON_C_TO_STRING_PRETTY
));
1964 json_object_free(json
);
1967 if (!found_neighbor
)
1969 "%% No such interface or neighbor\n");
1974 static void pim_show_state(struct pim_instance
*pim
, struct vty
*vty
,
1975 const char *src_or_group
, const char *group
, bool uj
)
1977 struct channel_oil
*c_oil
;
1978 struct listnode
*node
;
1979 json_object
*json
= NULL
;
1980 json_object
*json_group
= NULL
;
1981 json_object
*json_ifp_in
= NULL
;
1982 json_object
*json_ifp_out
= NULL
;
1983 json_object
*json_source
= NULL
;
1986 now
= pim_time_monotonic_sec();
1989 json
= json_object_new_object();
1992 "Codes: J -> Pim Join, I -> IGMP Report, S -> Source, * -> Inherited from (*,G), V -> VxLAN, M -> Muted");
1994 "\nActive Source Group RPT IIF OIL\n");
1997 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
1998 char grp_str
[INET_ADDRSTRLEN
];
1999 char src_str
[INET_ADDRSTRLEN
];
2000 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
2001 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
2003 struct interface
*ifp_in
;
2008 PIM_UPSTREAM_FLAG_TEST_USE_RPT(c_oil
->up
->flags
)) ||
2009 c_oil
->oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
2014 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
2016 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
2018 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
2021 strlcpy(in_ifname
, ifp_in
->name
, sizeof(in_ifname
));
2023 strlcpy(in_ifname
, "<iif?>", sizeof(in_ifname
));
2026 if (strcmp(src_or_group
, src_str
)
2027 && strcmp(src_or_group
, grp_str
))
2030 if (group
&& strcmp(group
, grp_str
))
2036 /* Find the group, create it if it doesn't exist */
2037 json_object_object_get_ex(json
, grp_str
, &json_group
);
2040 json_group
= json_object_new_object();
2041 json_object_object_add(json
, grp_str
,
2045 /* Find the source nested under the group, create it if
2046 * it doesn't exist */
2047 json_object_object_get_ex(json_group
, src_str
,
2051 json_source
= json_object_new_object();
2052 json_object_object_add(json_group
, src_str
,
2056 /* Find the inbound interface nested under the source,
2057 * create it if it doesn't exist */
2058 json_object_object_get_ex(json_source
, in_ifname
,
2062 json_ifp_in
= json_object_new_object();
2063 json_object_object_add(json_source
, in_ifname
,
2065 json_object_int_add(json_source
, "Installed",
2068 json_object_boolean_true_add(
2069 json_source
, "isRpt");
2071 json_object_boolean_false_add(
2072 json_source
, "isRpt");
2073 json_object_int_add(json_source
, "RefCount",
2074 c_oil
->oil_ref_count
);
2075 json_object_int_add(json_source
, "OilListSize",
2077 json_object_int_add(
2078 json_source
, "OilRescan",
2079 c_oil
->oil_inherited_rescan
);
2080 json_object_int_add(json_source
, "LastUsed",
2081 c_oil
->cc
.lastused
);
2082 json_object_int_add(json_source
, "PacketCount",
2084 json_object_int_add(json_source
, "ByteCount",
2086 json_object_int_add(json_source
,
2088 c_oil
->cc
.wrong_if
);
2091 vty_out(vty
, "%-6d %-15s %-15s %-3s %-16s ",
2092 c_oil
->installed
, src_str
, grp_str
,
2093 isRpt
? "y" : "n", in_ifname
);
2096 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
2098 struct interface
*ifp_out
;
2099 char oif_uptime
[10];
2102 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
2106 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
2108 oif_uptime
, sizeof(oif_uptime
),
2109 now
- c_oil
->oif_creation
[oif_vif_index
]);
2112 strlcpy(out_ifname
, ifp_out
->name
, sizeof(out_ifname
));
2114 strlcpy(out_ifname
, "<oif?>", sizeof(out_ifname
));
2117 json_ifp_out
= json_object_new_object();
2118 json_object_string_add(json_ifp_out
, "source",
2120 json_object_string_add(json_ifp_out
, "group",
2122 json_object_string_add(json_ifp_out
,
2125 json_object_string_add(json_ifp_out
,
2126 "outboundInterface",
2128 json_object_int_add(json_ifp_out
, "installed",
2131 json_object_object_add(json_ifp_in
, out_ifname
,
2136 vty_out(vty
, "%s(%c%c%c%c%c)",
2138 (c_oil
->oif_flags
[oif_vif_index
]
2139 & PIM_OIF_FLAG_PROTO_IGMP
)
2142 (c_oil
->oif_flags
[oif_vif_index
]
2143 & PIM_OIF_FLAG_PROTO_PIM
)
2146 (c_oil
->oif_flags
[oif_vif_index
]
2147 & PIM_OIF_FLAG_PROTO_VXLAN
)
2150 (c_oil
->oif_flags
[oif_vif_index
]
2151 & PIM_OIF_FLAG_PROTO_STAR
)
2154 (c_oil
->oif_flags
[oif_vif_index
]
2155 & PIM_OIF_FLAG_MUTE
)
2159 vty_out(vty
, ", %s(%c%c%c%c%c)",
2161 (c_oil
->oif_flags
[oif_vif_index
]
2162 & PIM_OIF_FLAG_PROTO_IGMP
)
2165 (c_oil
->oif_flags
[oif_vif_index
]
2166 & PIM_OIF_FLAG_PROTO_PIM
)
2169 (c_oil
->oif_flags
[oif_vif_index
]
2170 & PIM_OIF_FLAG_PROTO_VXLAN
)
2173 (c_oil
->oif_flags
[oif_vif_index
]
2174 & PIM_OIF_FLAG_PROTO_STAR
)
2177 (c_oil
->oif_flags
[oif_vif_index
]
2178 & PIM_OIF_FLAG_MUTE
)
2190 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2191 json
, JSON_C_TO_STRING_PRETTY
));
2192 json_object_free(json
);
2198 static void pim_show_neighbors(struct pim_instance
*pim
, struct vty
*vty
,
2201 struct listnode
*neighnode
;
2202 struct interface
*ifp
;
2203 struct pim_interface
*pim_ifp
;
2204 struct pim_neighbor
*neigh
;
2208 char neigh_src_str
[INET_ADDRSTRLEN
];
2209 json_object
*json
= NULL
;
2210 json_object
*json_ifp_rows
= NULL
;
2211 json_object
*json_row
= NULL
;
2213 now
= pim_time_monotonic_sec();
2216 json
= json_object_new_object();
2219 "Interface Neighbor Uptime Holdtime DR Pri\n");
2222 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2223 pim_ifp
= ifp
->info
;
2228 if (pim_ifp
->pim_sock_fd
< 0)
2232 json_ifp_rows
= json_object_new_object();
2234 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
2236 pim_inet4_dump("<src?>", neigh
->source_addr
,
2237 neigh_src_str
, sizeof(neigh_src_str
));
2238 pim_time_uptime(uptime
, sizeof(uptime
),
2239 now
- neigh
->creation
);
2240 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
2241 neigh
->t_expire_timer
);
2244 json_row
= json_object_new_object();
2245 json_object_string_add(json_row
, "interface",
2247 json_object_string_add(json_row
, "neighbor",
2249 json_object_string_add(json_row
, "upTime",
2251 json_object_string_add(json_row
, "holdTime",
2253 json_object_int_add(json_row
, "holdTimeMax",
2255 json_object_int_add(json_row
, "drPriority",
2256 neigh
->dr_priority
);
2257 json_object_object_add(json_ifp_rows
,
2258 neigh_src_str
, json_row
);
2261 vty_out(vty
, "%-16s %15s %8s %8s %6d\n",
2262 ifp
->name
, neigh_src_str
, uptime
,
2263 expire
, neigh
->dr_priority
);
2268 json_object_object_add(json
, ifp
->name
, json_ifp_rows
);
2269 json_ifp_rows
= NULL
;
2274 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2275 json
, JSON_C_TO_STRING_PRETTY
));
2276 json_object_free(json
);
2280 static void pim_show_neighbors_secondary(struct pim_instance
*pim
,
2283 struct interface
*ifp
;
2286 "Interface Address Neighbor Secondary \n");
2288 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2289 struct pim_interface
*pim_ifp
;
2290 struct in_addr ifaddr
;
2291 struct listnode
*neighnode
;
2292 struct pim_neighbor
*neigh
;
2294 pim_ifp
= ifp
->info
;
2299 if (pim_ifp
->pim_sock_fd
< 0)
2302 ifaddr
= pim_ifp
->primary_address
;
2304 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
2306 char neigh_src_str
[INET_ADDRSTRLEN
];
2307 struct listnode
*prefix_node
;
2310 if (!neigh
->prefix_list
)
2313 pim_inet4_dump("<src?>", neigh
->source_addr
,
2314 neigh_src_str
, sizeof(neigh_src_str
));
2316 for (ALL_LIST_ELEMENTS_RO(neigh
->prefix_list
,
2318 char neigh_sec_str
[PREFIX2STR_BUFFER
];
2320 prefix2str(p
, neigh_sec_str
,
2321 sizeof(neigh_sec_str
));
2323 vty_out(vty
, "%-16s %-15s %-15s %-15s\n",
2324 ifp
->name
, inet_ntoa(ifaddr
),
2325 neigh_src_str
, neigh_sec_str
);
2331 static void json_object_pim_upstream_add(json_object
*json
,
2332 struct pim_upstream
*up
)
2334 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED
)
2335 json_object_boolean_true_add(json
, "drJoinDesired");
2337 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED
)
2338 json_object_boolean_true_add(json
, "drJoinDesiredUpdated");
2340 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
2341 json_object_boolean_true_add(json
, "firstHopRouter");
2343 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_IGMP
)
2344 json_object_boolean_true_add(json
, "sourceIgmp");
2346 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_PIM
)
2347 json_object_boolean_true_add(json
, "sourcePim");
2349 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_STREAM
)
2350 json_object_boolean_true_add(json
, "sourceStream");
2352 /* XXX: need to print ths flag in the plain text display as well */
2353 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_MSDP
)
2354 json_object_boolean_true_add(json
, "sourceMsdp");
2356 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SEND_SG_RPT_PRUNE
)
2357 json_object_boolean_true_add(json
, "sendSGRptPrune");
2359 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_LHR
)
2360 json_object_boolean_true_add(json
, "lastHopRouter");
2362 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DISABLE_KAT_EXPIRY
)
2363 json_object_boolean_true_add(json
, "disableKATExpiry");
2365 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_STATIC_IIF
)
2366 json_object_boolean_true_add(json
, "staticIncomingInterface");
2368 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_ALLOW_IIF_IN_OIL
)
2369 json_object_boolean_true_add(json
,
2370 "allowIncomingInterfaceinOil");
2372 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_NO_PIMREG_DATA
)
2373 json_object_boolean_true_add(json
, "noPimRegistrationData");
2375 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FORCE_PIMREG
)
2376 json_object_boolean_true_add(json
, "forcePimRegistration");
2378 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_ORIG
)
2379 json_object_boolean_true_add(json
, "sourceVxlanOrigination");
2381 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_TERM
)
2382 json_object_boolean_true_add(json
, "sourceVxlanTermination");
2384 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_VXLAN
)
2385 json_object_boolean_true_add(json
, "mlagVxlan");
2387 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_NON_DF
)
2388 json_object_boolean_true_add(json
,
2389 "mlagNonDesignatedForwarder");
2393 pim_upstream_state2brief_str(enum pim_upstream_state join_state
,
2394 char *state_str
, size_t state_str_len
)
2396 switch (join_state
) {
2397 case PIM_UPSTREAM_NOTJOINED
:
2398 strlcpy(state_str
, "NotJ", state_str_len
);
2400 case PIM_UPSTREAM_JOINED
:
2401 strlcpy(state_str
, "J", state_str_len
);
2404 strlcpy(state_str
, "Unk", state_str_len
);
2409 static const char *pim_reg_state2brief_str(enum pim_reg_state reg_state
,
2410 char *state_str
, size_t state_str_len
)
2412 switch (reg_state
) {
2413 case PIM_REG_NOINFO
:
2414 strlcpy(state_str
, "RegNI", state_str_len
);
2417 strlcpy(state_str
, "RegJ", state_str_len
);
2419 case PIM_REG_JOIN_PENDING
:
2421 strlcpy(state_str
, "RegP", state_str_len
);
2424 strlcpy(state_str
, "Unk", state_str_len
);
2429 static void pim_show_upstream(struct pim_instance
*pim
, struct vty
*vty
,
2430 struct prefix_sg
*sg
, bool uj
)
2432 struct listnode
*upnode
;
2433 struct pim_upstream
*up
;
2435 json_object
*json
= NULL
;
2436 json_object
*json_group
= NULL
;
2437 json_object
*json_row
= NULL
;
2439 now
= pim_time_monotonic_sec();
2442 json
= json_object_new_object();
2445 "Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt\n");
2447 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
, up
)) {
2448 char src_str
[INET_ADDRSTRLEN
];
2449 char grp_str
[INET_ADDRSTRLEN
];
2451 char join_timer
[10];
2454 char msdp_reg_timer
[10];
2455 char state_str
[PIM_REG_STATE_STR_LEN
];
2457 if (sg
->grp
.s_addr
!= 0 && sg
->grp
.s_addr
!= up
->sg
.grp
.s_addr
)
2459 if (sg
->src
.s_addr
!= 0 && sg
->src
.s_addr
!= up
->sg
.src
.s_addr
)
2462 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2463 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2464 pim_time_uptime(uptime
, sizeof(uptime
),
2465 now
- up
->state_transition
);
2466 pim_time_timer_to_hhmmss(join_timer
, sizeof(join_timer
),
2470 * If the upstream is not dummy and it has a J/P timer for the
2471 * neighbor display that
2473 if (!up
->t_join_timer
&& up
->rpf
.source_nexthop
.interface
) {
2474 struct pim_neighbor
*nbr
;
2476 nbr
= pim_neighbor_find(
2477 up
->rpf
.source_nexthop
.interface
,
2478 up
->rpf
.rpf_addr
.u
.prefix4
);
2480 pim_time_timer_to_hhmmss(join_timer
,
2485 pim_time_timer_to_hhmmss(rs_timer
, sizeof(rs_timer
),
2487 pim_time_timer_to_hhmmss(ka_timer
, sizeof(ka_timer
),
2489 pim_time_timer_to_hhmmss(msdp_reg_timer
, sizeof(msdp_reg_timer
),
2490 up
->t_msdp_reg_timer
);
2492 pim_upstream_state2brief_str(up
->join_state
, state_str
, sizeof(state_str
));
2493 if (up
->reg_state
!= PIM_REG_NOINFO
) {
2494 char tmp_str
[PIM_REG_STATE_STR_LEN
];
2496 sprintf(state_str
+ strlen(state_str
), ",%s",
2497 pim_reg_state2brief_str(up
->reg_state
, tmp_str
,
2502 json_object_object_get_ex(json
, grp_str
, &json_group
);
2505 json_group
= json_object_new_object();
2506 json_object_object_add(json
, grp_str
,
2510 json_row
= json_object_new_object();
2511 json_object_pim_upstream_add(json_row
, up
);
2512 json_object_string_add(
2513 json_row
, "inboundInterface",
2514 up
->rpf
.source_nexthop
.interface
2515 ? up
->rpf
.source_nexthop
.interface
->name
2519 * The RPF address we use is slightly different
2520 * based upon what we are looking up.
2521 * If we have a S, list that unless
2522 * we are the FHR, else we just put
2523 * the RP as the rpfAddress
2525 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
2526 || up
->sg
.src
.s_addr
== INADDR_ANY
) {
2527 char rpf
[PREFIX_STRLEN
];
2528 struct pim_rpf
*rpg
;
2530 rpg
= RP(pim
, up
->sg
.grp
);
2531 pim_inet4_dump("<rpf?>",
2532 rpg
->rpf_addr
.u
.prefix4
, rpf
,
2534 json_object_string_add(json_row
, "rpfAddress",
2537 json_object_string_add(json_row
, "rpfAddress",
2541 json_object_string_add(json_row
, "source", src_str
);
2542 json_object_string_add(json_row
, "group", grp_str
);
2543 json_object_string_add(json_row
, "state", state_str
);
2544 json_object_string_add(
2545 json_row
, "joinState",
2546 pim_upstream_state2str(up
->join_state
));
2547 json_object_string_add(
2548 json_row
, "regState",
2549 pim_reg_state2str(up
->reg_state
, state_str
, sizeof(state_str
)));
2550 json_object_string_add(json_row
, "upTime", uptime
);
2551 json_object_string_add(json_row
, "joinTimer",
2553 json_object_string_add(json_row
, "resetTimer",
2555 json_object_string_add(json_row
, "keepaliveTimer",
2557 json_object_string_add(json_row
, "msdpRegTimer",
2559 json_object_int_add(json_row
, "refCount",
2561 json_object_int_add(json_row
, "sptBit", up
->sptbit
);
2562 json_object_object_add(json_group
, src_str
, json_row
);
2565 "%-16s%-15s %-15s %-11s %-8s %-9s %-9s %-9s %6d\n",
2566 up
->rpf
.source_nexthop
.interface
2567 ? up
->rpf
.source_nexthop
.interface
->name
2569 src_str
, grp_str
, state_str
, uptime
, join_timer
,
2570 rs_timer
, ka_timer
, up
->ref_count
);
2575 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2576 json
, JSON_C_TO_STRING_PRETTY
));
2577 json_object_free(json
);
2581 static void pim_show_channel_helper(struct pim_instance
*pim
,
2583 struct pim_interface
*pim_ifp
,
2584 struct pim_ifchannel
*ch
,
2585 json_object
*json
, bool uj
)
2587 struct pim_upstream
*up
= ch
->upstream
;
2588 json_object
*json_group
= NULL
;
2589 char src_str
[INET_ADDRSTRLEN
];
2590 char grp_str
[INET_ADDRSTRLEN
];
2591 json_object
*json_row
= NULL
;
2593 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2594 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2597 json_object_object_get_ex(json
, grp_str
, &json_group
);
2600 json_group
= json_object_new_object();
2601 json_object_object_add(json
, grp_str
, json_group
);
2604 json_row
= json_object_new_object();
2605 json_object_pim_upstream_add(json_row
, up
);
2606 json_object_string_add(json_row
, "interface",
2607 ch
->interface
->name
);
2608 json_object_string_add(json_row
, "source", src_str
);
2609 json_object_string_add(json_row
, "group", grp_str
);
2611 if (pim_macro_ch_lost_assert(ch
))
2612 json_object_boolean_true_add(json_row
, "lostAssert");
2614 if (pim_macro_chisin_joins(ch
))
2615 json_object_boolean_true_add(json_row
, "joins");
2617 if (pim_macro_chisin_pim_include(ch
))
2618 json_object_boolean_true_add(json_row
, "pimInclude");
2620 if (pim_upstream_evaluate_join_desired(pim
, up
))
2621 json_object_boolean_true_add(json_row
,
2622 "evaluateJoinDesired");
2624 json_object_object_add(json_group
, src_str
, json_row
);
2627 vty_out(vty
, "%-16s %-15s %-15s %-10s %-5s %-10s %-11s %-6s\n",
2628 ch
->interface
->name
, src_str
, grp_str
,
2629 pim_macro_ch_lost_assert(ch
) ? "yes" : "no",
2630 pim_macro_chisin_joins(ch
) ? "yes" : "no",
2631 pim_macro_chisin_pim_include(ch
) ? "yes" : "no",
2632 PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(up
->flags
)
2635 pim_upstream_evaluate_join_desired(pim
, up
) ? "yes"
2640 static void pim_show_channel(struct pim_instance
*pim
, struct vty
*vty
,
2643 struct pim_interface
*pim_ifp
;
2644 struct pim_ifchannel
*ch
;
2645 struct interface
*ifp
;
2647 json_object
*json
= NULL
;
2650 json
= json_object_new_object();
2653 "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD\n");
2655 /* scan per-interface (S,G) state */
2656 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2657 pim_ifp
= ifp
->info
;
2662 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
2663 /* scan all interfaces */
2664 pim_show_channel_helper(pim
, vty
, pim_ifp
, ch
,
2670 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2671 json
, JSON_C_TO_STRING_PRETTY
));
2672 json_object_free(json
);
2676 static void pim_show_join_desired_helper(struct pim_instance
*pim
,
2678 struct pim_upstream
*up
,
2679 json_object
*json
, bool uj
)
2681 json_object
*json_group
= NULL
;
2682 char src_str
[INET_ADDRSTRLEN
];
2683 char grp_str
[INET_ADDRSTRLEN
];
2684 json_object
*json_row
= NULL
;
2686 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2687 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2690 json_object_object_get_ex(json
, grp_str
, &json_group
);
2693 json_group
= json_object_new_object();
2694 json_object_object_add(json
, grp_str
, json_group
);
2697 json_row
= json_object_new_object();
2698 json_object_pim_upstream_add(json_row
, up
);
2699 json_object_string_add(json_row
, "source", src_str
);
2700 json_object_string_add(json_row
, "group", grp_str
);
2702 if (pim_upstream_evaluate_join_desired(pim
, up
))
2703 json_object_boolean_true_add(json_row
,
2704 "evaluateJoinDesired");
2706 json_object_object_add(json_group
, src_str
, json_row
);
2709 vty_out(vty
, "%-15s %-15s %-6s\n",
2711 pim_upstream_evaluate_join_desired(pim
, up
) ? "yes"
2716 static void pim_show_join_desired(struct pim_instance
*pim
, struct vty
*vty
,
2719 struct listnode
*upnode
;
2720 struct pim_upstream
*up
;
2722 json_object
*json
= NULL
;
2725 json
= json_object_new_object();
2728 "Source Group EvalJD\n");
2730 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
, up
)) {
2731 /* scan all interfaces */
2732 pim_show_join_desired_helper(pim
, vty
, up
,
2737 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2738 json
, JSON_C_TO_STRING_PRETTY
));
2739 json_object_free(json
);
2743 static void pim_show_upstream_rpf(struct pim_instance
*pim
, struct vty
*vty
,
2746 struct listnode
*upnode
;
2747 struct pim_upstream
*up
;
2748 json_object
*json
= NULL
;
2749 json_object
*json_group
= NULL
;
2750 json_object
*json_row
= NULL
;
2753 json
= json_object_new_object();
2756 "Source Group RpfIface RibNextHop RpfAddress \n");
2758 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
, up
)) {
2759 char src_str
[INET_ADDRSTRLEN
];
2760 char grp_str
[INET_ADDRSTRLEN
];
2761 char rpf_nexthop_str
[PREFIX_STRLEN
];
2762 char rpf_addr_str
[PREFIX_STRLEN
];
2763 struct pim_rpf
*rpf
;
2764 const char *rpf_ifname
;
2768 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2769 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2770 pim_addr_dump("<nexthop?>",
2771 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2772 rpf_nexthop_str
, sizeof(rpf_nexthop_str
));
2773 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2774 sizeof(rpf_addr_str
));
2776 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2779 json_object_object_get_ex(json
, grp_str
, &json_group
);
2782 json_group
= json_object_new_object();
2783 json_object_object_add(json
, grp_str
,
2787 json_row
= json_object_new_object();
2788 json_object_pim_upstream_add(json_row
, up
);
2789 json_object_string_add(json_row
, "source", src_str
);
2790 json_object_string_add(json_row
, "group", grp_str
);
2791 json_object_string_add(json_row
, "rpfInterface",
2793 json_object_string_add(json_row
, "ribNexthop",
2795 json_object_string_add(json_row
, "rpfAddress",
2797 json_object_object_add(json_group
, src_str
, json_row
);
2799 vty_out(vty
, "%-15s %-15s %-16s %-15s %-15s\n", src_str
,
2800 grp_str
, rpf_ifname
, rpf_nexthop_str
,
2806 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2807 json
, JSON_C_TO_STRING_PRETTY
));
2808 json_object_free(json
);
2812 static void show_rpf_refresh_stats(struct vty
*vty
, struct pim_instance
*pim
,
2813 time_t now
, json_object
*json
)
2815 char refresh_uptime
[10];
2817 pim_time_uptime_begin(refresh_uptime
, sizeof(refresh_uptime
), now
,
2818 pim
->rpf_cache_refresh_last
);
2821 json_object_int_add(json
, "rpfCacheRefreshDelayMsecs",
2822 router
->rpf_cache_refresh_delay_msec
);
2823 json_object_int_add(
2824 json
, "rpfCacheRefreshTimer",
2825 pim_time_timer_remain_msec(pim
->rpf_cache_refresher
));
2826 json_object_int_add(json
, "rpfCacheRefreshRequests",
2827 pim
->rpf_cache_refresh_requests
);
2828 json_object_int_add(json
, "rpfCacheRefreshEvents",
2829 pim
->rpf_cache_refresh_events
);
2830 json_object_string_add(json
, "rpfCacheRefreshLast",
2832 json_object_int_add(json
, "nexthopLookups",
2833 pim
->nexthop_lookups
);
2834 json_object_int_add(json
, "nexthopLookupsAvoided",
2835 pim
->nexthop_lookups_avoided
);
2838 "RPF Cache Refresh Delay: %ld msecs\n"
2839 "RPF Cache Refresh Timer: %ld msecs\n"
2840 "RPF Cache Refresh Requests: %lld\n"
2841 "RPF Cache Refresh Events: %lld\n"
2842 "RPF Cache Refresh Last: %s\n"
2843 "Nexthop Lookups: %lld\n"
2844 "Nexthop Lookups Avoided: %lld\n",
2845 router
->rpf_cache_refresh_delay_msec
,
2846 pim_time_timer_remain_msec(pim
->rpf_cache_refresher
),
2847 (long long)pim
->rpf_cache_refresh_requests
,
2848 (long long)pim
->rpf_cache_refresh_events
,
2849 refresh_uptime
, (long long)pim
->nexthop_lookups
,
2850 (long long)pim
->nexthop_lookups_avoided
);
2854 static void show_scan_oil_stats(struct pim_instance
*pim
, struct vty
*vty
,
2857 char uptime_scan_oil
[10];
2858 char uptime_mroute_add
[10];
2859 char uptime_mroute_del
[10];
2861 pim_time_uptime_begin(uptime_scan_oil
, sizeof(uptime_scan_oil
), now
,
2862 pim
->scan_oil_last
);
2863 pim_time_uptime_begin(uptime_mroute_add
, sizeof(uptime_mroute_add
), now
,
2864 pim
->mroute_add_last
);
2865 pim_time_uptime_begin(uptime_mroute_del
, sizeof(uptime_mroute_del
), now
,
2866 pim
->mroute_del_last
);
2869 "Scan OIL - Last: %s Events: %lld\n"
2870 "MFC Add - Last: %s Events: %lld\n"
2871 "MFC Del - Last: %s Events: %lld\n",
2872 uptime_scan_oil
, (long long)pim
->scan_oil_events
,
2873 uptime_mroute_add
, (long long)pim
->mroute_add_events
,
2874 uptime_mroute_del
, (long long)pim
->mroute_del_events
);
2877 static void pim_show_rpf(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
2879 struct listnode
*up_node
;
2880 struct pim_upstream
*up
;
2881 time_t now
= pim_time_monotonic_sec();
2882 json_object
*json
= NULL
;
2883 json_object
*json_group
= NULL
;
2884 json_object
*json_row
= NULL
;
2887 json
= json_object_new_object();
2888 show_rpf_refresh_stats(vty
, pim
, now
, json
);
2890 show_rpf_refresh_stats(vty
, pim
, now
, json
);
2893 "Source Group RpfIface RpfAddress RibNextHop Metric Pref\n");
2896 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, up_node
, up
)) {
2897 char src_str
[INET_ADDRSTRLEN
];
2898 char grp_str
[INET_ADDRSTRLEN
];
2899 char rpf_addr_str
[PREFIX_STRLEN
];
2900 char rib_nexthop_str
[PREFIX_STRLEN
];
2901 const char *rpf_ifname
;
2902 struct pim_rpf
*rpf
= &up
->rpf
;
2904 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2905 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2906 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2907 sizeof(rpf_addr_str
));
2908 pim_addr_dump("<nexthop?>",
2909 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2910 rib_nexthop_str
, sizeof(rib_nexthop_str
));
2912 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2915 json_object_object_get_ex(json
, grp_str
, &json_group
);
2918 json_group
= json_object_new_object();
2919 json_object_object_add(json
, grp_str
,
2923 json_row
= json_object_new_object();
2924 json_object_string_add(json_row
, "source", src_str
);
2925 json_object_string_add(json_row
, "group", grp_str
);
2926 json_object_string_add(json_row
, "rpfInterface",
2928 json_object_string_add(json_row
, "rpfAddress",
2930 json_object_string_add(json_row
, "ribNexthop",
2932 json_object_int_add(
2933 json_row
, "routeMetric",
2934 rpf
->source_nexthop
.mrib_route_metric
);
2935 json_object_int_add(
2936 json_row
, "routePreference",
2937 rpf
->source_nexthop
.mrib_metric_preference
);
2938 json_object_object_add(json_group
, src_str
, json_row
);
2941 vty_out(vty
, "%-15s %-15s %-16s %-15s %-15s %6d %4d\n",
2942 src_str
, grp_str
, rpf_ifname
, rpf_addr_str
,
2944 rpf
->source_nexthop
.mrib_route_metric
,
2945 rpf
->source_nexthop
.mrib_metric_preference
);
2950 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2951 json
, JSON_C_TO_STRING_PRETTY
));
2952 json_object_free(json
);
2956 struct pnc_cache_walk_data
{
2958 struct pim_instance
*pim
;
2961 static int pim_print_pnc_cache_walkcb(struct hash_bucket
*bucket
, void *arg
)
2963 struct pim_nexthop_cache
*pnc
= bucket
->data
;
2964 struct pnc_cache_walk_data
*cwd
= arg
;
2965 struct vty
*vty
= cwd
->vty
;
2966 struct pim_instance
*pim
= cwd
->pim
;
2967 struct nexthop
*nh_node
= NULL
;
2968 ifindex_t first_ifindex
;
2969 struct interface
*ifp
= NULL
;
2971 for (nh_node
= pnc
->nexthop
; nh_node
; nh_node
= nh_node
->next
) {
2972 first_ifindex
= nh_node
->ifindex
;
2973 ifp
= if_lookup_by_index(first_ifindex
, pim
->vrf_id
);
2975 vty_out(vty
, "%-15s ", inet_ntoa(pnc
->rpf
.rpf_addr
.u
.prefix4
));
2976 vty_out(vty
, "%-16s ", ifp
? ifp
->name
: "NULL");
2977 vty_out(vty
, "%s ", inet_ntoa(nh_node
->gate
.ipv4
));
2983 static void pim_show_nexthop(struct pim_instance
*pim
, struct vty
*vty
)
2985 struct pnc_cache_walk_data cwd
;
2989 vty_out(vty
, "Number of registered addresses: %lu\n",
2990 pim
->rpf_hash
->count
);
2991 vty_out(vty
, "Address Interface Nexthop\n");
2992 vty_out(vty
, "---------------------------------------------\n");
2994 hash_walk(pim
->rpf_hash
, pim_print_pnc_cache_walkcb
, &cwd
);
2997 /* Display the bsm database details */
2998 static void pim_show_bsm_db(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
3000 struct listnode
*bsmnode
;
3003 struct bsm_info
*bsm
;
3004 json_object
*json
= NULL
;
3005 json_object
*json_group
= NULL
;
3006 json_object
*json_row
= NULL
;
3008 count
= pim
->global_scope
.bsm_list
->count
;
3011 json
= json_object_new_object();
3012 json_object_int_add(json
, "Number of the fragments", count
);
3014 vty_out(vty
, "Scope Zone: Global\n");
3015 vty_out(vty
, "Number of the fragments: %d\n", count
);
3019 for (ALL_LIST_ELEMENTS_RO(pim
->global_scope
.bsm_list
, bsmnode
, bsm
)) {
3020 char grp_str
[INET_ADDRSTRLEN
];
3021 char rp_str
[INET_ADDRSTRLEN
];
3022 char bsr_str
[INET_ADDRSTRLEN
];
3023 struct bsmmsg_grpinfo
*group
;
3024 struct bsmmsg_rpinfo
*rpaddr
;
3026 struct bsm_hdr
*hdr
;
3027 uint32_t offset
= 0;
3030 uint32_t frag_rp_cnt
= 0;
3035 /* skip pim header */
3036 buf
+= PIM_MSG_HEADER_LEN
;
3037 len
-= PIM_MSG_HEADER_LEN
;
3039 hdr
= (struct bsm_hdr
*)buf
;
3041 /* BSM starts with bsr header */
3042 buf
+= sizeof(struct bsm_hdr
);
3043 len
-= sizeof(struct bsm_hdr
);
3045 pim_inet4_dump("<BSR Address?>", hdr
->bsr_addr
.addr
, bsr_str
,
3050 json_object_string_add(json
, "BSR address", bsr_str
);
3051 json_object_int_add(json
, "BSR priority",
3053 json_object_int_add(json
, "Hashmask Length",
3055 json_object_int_add(json
, "Fragment Tag",
3056 ntohs(hdr
->frag_tag
));
3058 vty_out(vty
, "BSM Fragment : %d\n", fragment
);
3059 vty_out(vty
, "------------------\n");
3060 vty_out(vty
, "%-15s %-15s %-15s %-15s\n", "BSR-Address",
3061 "BSR-Priority", "Hashmask-len", "Fragment-Tag");
3062 vty_out(vty
, "%-15s %-15d %-15d %-15d\n", bsr_str
,
3063 hdr
->bsr_prio
, hdr
->hm_len
,
3064 ntohs(hdr
->frag_tag
));
3069 while (offset
< len
) {
3070 group
= (struct bsmmsg_grpinfo
*)buf
;
3072 if (group
->group
.family
== PIM_MSG_ADDRESS_FAMILY_IPV4
)
3073 grp
.family
= AF_INET
;
3075 grp
.prefixlen
= group
->group
.mask
;
3076 grp
.u
.prefix4
.s_addr
= group
->group
.addr
.s_addr
;
3078 prefix2str(&grp
, grp_str
, sizeof(grp_str
));
3080 buf
+= sizeof(struct bsmmsg_grpinfo
);
3081 offset
+= sizeof(struct bsmmsg_grpinfo
);
3084 json_object_object_get_ex(json
, grp_str
,
3087 json_group
= json_object_new_object();
3088 json_object_int_add(json_group
,
3091 json_object_int_add(
3092 json_group
, "Fragment Rp count",
3093 group
->frag_rp_count
);
3094 json_object_object_add(json
, grp_str
,
3098 vty_out(vty
, "Group : %s\n", grp_str
);
3099 vty_out(vty
, "-------------------\n");
3100 vty_out(vty
, "Rp Count:%d\n", group
->rp_count
);
3101 vty_out(vty
, "Fragment Rp Count : %d\n",
3102 group
->frag_rp_count
);
3105 frag_rp_cnt
= group
->frag_rp_count
;
3112 "RpAddress HoldTime Priority\n");
3114 while (frag_rp_cnt
--) {
3115 rpaddr
= (struct bsmmsg_rpinfo
*)buf
;
3117 buf
+= sizeof(struct bsmmsg_rpinfo
);
3118 offset
+= sizeof(struct bsmmsg_rpinfo
);
3120 pim_inet4_dump("<Rp addr?>",
3121 rpaddr
->rpaddr
.addr
, rp_str
,
3125 json_row
= json_object_new_object();
3126 json_object_string_add(
3127 json_row
, "Rp Address", rp_str
);
3128 json_object_int_add(
3129 json_row
, "Rp HoldTime",
3130 ntohs(rpaddr
->rp_holdtime
));
3131 json_object_int_add(json_row
,
3134 json_object_object_add(
3135 json_group
, rp_str
, json_row
);
3137 vty_out(vty
, "%-15s %-12d %d\n", rp_str
,
3138 ntohs(rpaddr
->rp_holdtime
),
3149 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3150 json
, JSON_C_TO_STRING_PRETTY
));
3151 json_object_free(json
);
3155 /*Display the group-rp mappings */
3156 static void pim_show_group_rp_mappings_info(struct pim_instance
*pim
,
3157 struct vty
*vty
, bool uj
)
3159 struct bsgrp_node
*bsgrp
;
3160 struct listnode
*rpnode
;
3161 struct bsm_rpinfo
*bsm_rp
;
3162 struct route_node
*rn
;
3163 char bsr_str
[INET_ADDRSTRLEN
];
3164 json_object
*json
= NULL
;
3165 json_object
*json_group
= NULL
;
3166 json_object
*json_row
= NULL
;
3168 if (pim
->global_scope
.current_bsr
.s_addr
== INADDR_ANY
)
3169 strlcpy(bsr_str
, "0.0.0.0", sizeof(bsr_str
));
3172 pim_inet4_dump("<bsr?>", pim
->global_scope
.current_bsr
, bsr_str
,
3176 json
= json_object_new_object();
3177 json_object_string_add(json
, "BSR Address", bsr_str
);
3179 vty_out(vty
, "BSR Address %s\n", bsr_str
);
3182 for (rn
= route_top(pim
->global_scope
.bsrp_table
); rn
;
3183 rn
= route_next(rn
)) {
3184 bsgrp
= (struct bsgrp_node
*)rn
->info
;
3189 char grp_str
[INET_ADDRSTRLEN
];
3191 prefix2str(&bsgrp
->group
, grp_str
, sizeof(grp_str
));
3194 json_object_object_get_ex(json
, grp_str
, &json_group
);
3196 json_group
= json_object_new_object();
3197 json_object_object_add(json
, grp_str
,
3201 vty_out(vty
, "Group Address %s\n", grp_str
);
3202 vty_out(vty
, "--------------------------\n");
3203 vty_out(vty
, "%-15s %-15s %-15s %-15s\n", "Rp Address",
3204 "priority", "Holdtime", "Hash");
3206 vty_out(vty
, "(ACTIVE)\n");
3209 if (bsgrp
->bsrp_list
) {
3210 for (ALL_LIST_ELEMENTS_RO(bsgrp
->bsrp_list
, rpnode
,
3212 char rp_str
[INET_ADDRSTRLEN
];
3214 pim_inet4_dump("<Rp Address?>",
3215 bsm_rp
->rp_address
, rp_str
,
3219 json_row
= json_object_new_object();
3220 json_object_string_add(
3221 json_row
, "Rp Address", rp_str
);
3222 json_object_int_add(
3223 json_row
, "Rp HoldTime",
3224 bsm_rp
->rp_holdtime
);
3225 json_object_int_add(json_row
,
3228 json_object_int_add(json_row
,
3231 json_object_object_add(
3232 json_group
, rp_str
, json_row
);
3236 "%-15s %-15u %-15u %-15u\n",
3237 rp_str
, bsm_rp
->rp_prio
,
3238 bsm_rp
->rp_holdtime
,
3242 if (!bsgrp
->bsrp_list
->count
&& !uj
)
3243 vty_out(vty
, "Active List is empty.\n");
3247 json_object_int_add(json_group
, "Pending RP count",
3248 bsgrp
->pend_rp_cnt
);
3250 vty_out(vty
, "(PENDING)\n");
3251 vty_out(vty
, "Pending RP count :%d\n",
3252 bsgrp
->pend_rp_cnt
);
3253 if (bsgrp
->pend_rp_cnt
)
3254 vty_out(vty
, "%-15s %-15s %-15s %-15s\n",
3255 "Rp Address", "priority", "Holdtime",
3259 if (bsgrp
->partial_bsrp_list
) {
3260 for (ALL_LIST_ELEMENTS_RO(bsgrp
->partial_bsrp_list
,
3262 char rp_str
[INET_ADDRSTRLEN
];
3264 pim_inet4_dump("<Rp Addr?>", bsm_rp
->rp_address
,
3265 rp_str
, sizeof(rp_str
));
3268 json_row
= json_object_new_object();
3269 json_object_string_add(
3270 json_row
, "Rp Address", rp_str
);
3271 json_object_int_add(
3272 json_row
, "Rp HoldTime",
3273 bsm_rp
->rp_holdtime
);
3274 json_object_int_add(json_row
,
3277 json_object_int_add(json_row
,
3280 json_object_object_add(
3281 json_group
, rp_str
, json_row
);
3284 "%-15s %-15u %-15u %-15u\n",
3285 rp_str
, bsm_rp
->rp_prio
,
3286 bsm_rp
->rp_holdtime
,
3290 if (!bsgrp
->partial_bsrp_list
->count
&& !uj
)
3291 vty_out(vty
, "Partial List is empty\n");
3299 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3300 json
, JSON_C_TO_STRING_PRETTY
));
3301 json_object_free(json
);
3305 /* pim statistics - just adding only bsm related now.
3306 * We can continue to add all pim related stats here.
3308 static void pim_show_statistics(struct pim_instance
*pim
, struct vty
*vty
,
3309 const char *ifname
, bool uj
)
3311 json_object
*json
= NULL
;
3312 struct interface
*ifp
;
3315 json
= json_object_new_object();
3316 json_object_int_add(json
, "Number of Received BSMs",
3318 json_object_int_add(json
, "Number of Forwared BSMs",
3320 json_object_int_add(json
, "Number of Dropped BSMs",
3323 vty_out(vty
, "BSM Statistics :\n");
3324 vty_out(vty
, "----------------\n");
3325 vty_out(vty
, "Number of Received BSMs : %" PRIu64
"\n",
3327 vty_out(vty
, "Number of Forwared BSMs : %" PRIu64
"\n",
3329 vty_out(vty
, "Number of Dropped BSMs : %" PRIu64
"\n",
3335 /* scan interfaces */
3336 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3337 struct pim_interface
*pim_ifp
= ifp
->info
;
3339 if (ifname
&& strcmp(ifname
, ifp
->name
))
3346 vty_out(vty
, "Interface : %s\n", ifp
->name
);
3347 vty_out(vty
, "-------------------\n");
3349 "Number of BSMs dropped due to config miss : %u\n",
3350 pim_ifp
->pim_ifstat_bsm_cfg_miss
);
3351 vty_out(vty
, "Number of unicast BSMs dropped : %u\n",
3352 pim_ifp
->pim_ifstat_ucast_bsm_cfg_miss
);
3354 "Number of BSMs dropped due to invalid scope zone : %u\n",
3355 pim_ifp
->pim_ifstat_bsm_invalid_sz
);
3358 json_object
*json_row
= NULL
;
3360 json_row
= json_object_new_object();
3362 json_object_string_add(json_row
, "If Name", ifp
->name
);
3363 json_object_int_add(
3365 "Number of BSMs dropped due to config miss",
3366 pim_ifp
->pim_ifstat_bsm_cfg_miss
);
3367 json_object_int_add(
3368 json_row
, "Number of unicast BSMs dropped",
3369 pim_ifp
->pim_ifstat_ucast_bsm_cfg_miss
);
3370 json_object_int_add(json_row
,
3371 "Number of BSMs dropped due to invalid scope zone",
3372 pim_ifp
->pim_ifstat_bsm_invalid_sz
);
3373 json_object_object_add(json
, ifp
->name
, json_row
);
3379 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3380 json
, JSON_C_TO_STRING_PRETTY
));
3381 json_object_free(json
);
3385 static void clear_pim_statistics(struct pim_instance
*pim
)
3387 struct interface
*ifp
;
3391 pim
->bsm_dropped
= 0;
3393 /* scan interfaces */
3394 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3395 struct pim_interface
*pim_ifp
= ifp
->info
;
3400 pim_ifp
->pim_ifstat_bsm_cfg_miss
= 0;
3401 pim_ifp
->pim_ifstat_ucast_bsm_cfg_miss
= 0;
3402 pim_ifp
->pim_ifstat_bsm_invalid_sz
= 0;
3406 static void igmp_show_groups(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
3408 struct interface
*ifp
;
3410 json_object
*json
= NULL
;
3411 json_object
*json_iface
= NULL
;
3412 json_object
*json_row
= NULL
;
3414 now
= pim_time_monotonic_sec();
3417 json
= json_object_new_object();
3420 "Interface Address Group Mode Timer Srcs V Uptime \n");
3422 /* scan interfaces */
3423 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3424 struct pim_interface
*pim_ifp
= ifp
->info
;
3425 struct listnode
*sock_node
;
3426 struct igmp_sock
*igmp
;
3431 /* scan igmp sockets */
3432 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3434 char ifaddr_str
[INET_ADDRSTRLEN
];
3435 struct listnode
*grpnode
;
3436 struct igmp_group
*grp
;
3438 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3439 sizeof(ifaddr_str
));
3441 /* scan igmp groups */
3442 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3444 char group_str
[INET_ADDRSTRLEN
];
3448 pim_inet4_dump("<group?>", grp
->group_addr
,
3449 group_str
, sizeof(group_str
));
3450 pim_time_timer_to_hhmmss(hhmmss
, sizeof(hhmmss
),
3451 grp
->t_group_timer
);
3452 pim_time_uptime(uptime
, sizeof(uptime
),
3453 now
- grp
->group_creation
);
3456 json_object_object_get_ex(
3457 json
, ifp
->name
, &json_iface
);
3461 json_object_new_object();
3462 json_object_pim_ifp_add(
3464 json_object_object_add(
3469 json_row
= json_object_new_object();
3470 json_object_string_add(
3471 json_row
, "source", ifaddr_str
);
3472 json_object_string_add(
3473 json_row
, "group", group_str
);
3475 if (grp
->igmp_version
== 3)
3476 json_object_string_add(
3478 grp
->group_filtermode_isexcl
3482 json_object_string_add(json_row
,
3484 json_object_int_add(
3485 json_row
, "sourcesCount",
3486 grp
->group_source_list
3488 grp
->group_source_list
)
3490 json_object_int_add(json_row
, "version",
3492 json_object_string_add(
3493 json_row
, "uptime", uptime
);
3494 json_object_object_add(json_iface
,
3500 "%-16s %-15s %-15s %4s %8s %4d %d %8s\n",
3501 ifp
->name
, ifaddr_str
,
3503 grp
->igmp_version
== 3
3504 ? (grp
->group_filtermode_isexcl
3509 grp
->group_source_list
3511 grp
->group_source_list
)
3513 grp
->igmp_version
, uptime
);
3515 } /* scan igmp groups */
3516 } /* scan igmp sockets */
3517 } /* scan interfaces */
3520 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3521 json
, JSON_C_TO_STRING_PRETTY
));
3522 json_object_free(json
);
3526 static void igmp_show_group_retransmission(struct pim_instance
*pim
,
3529 struct interface
*ifp
;
3532 "Interface Address Group RetTimer Counter RetSrcs\n");
3534 /* scan interfaces */
3535 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3536 struct pim_interface
*pim_ifp
= ifp
->info
;
3537 struct listnode
*sock_node
;
3538 struct igmp_sock
*igmp
;
3543 /* scan igmp sockets */
3544 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3546 char ifaddr_str
[INET_ADDRSTRLEN
];
3547 struct listnode
*grpnode
;
3548 struct igmp_group
*grp
;
3550 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3551 sizeof(ifaddr_str
));
3553 /* scan igmp groups */
3554 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3556 char group_str
[INET_ADDRSTRLEN
];
3557 char grp_retr_mmss
[10];
3558 struct listnode
*src_node
;
3559 struct igmp_source
*src
;
3560 int grp_retr_sources
= 0;
3562 pim_inet4_dump("<group?>", grp
->group_addr
,
3563 group_str
, sizeof(group_str
));
3564 pim_time_timer_to_mmss(
3565 grp_retr_mmss
, sizeof(grp_retr_mmss
),
3566 grp
->t_group_query_retransmit_timer
);
3569 /* count group sources with retransmission state
3571 for (ALL_LIST_ELEMENTS_RO(
3572 grp
->group_source_list
, src_node
,
3574 if (src
->source_query_retransmit_count
3580 vty_out(vty
, "%-16s %-15s %-15s %-8s %7d %7d\n",
3581 ifp
->name
, ifaddr_str
, group_str
,
3583 grp
->group_specific_query_retransmit_count
,
3586 } /* scan igmp groups */
3587 } /* scan igmp sockets */
3588 } /* scan interfaces */
3591 static void igmp_show_sources(struct pim_instance
*pim
, struct vty
*vty
)
3593 struct interface
*ifp
;
3596 now
= pim_time_monotonic_sec();
3599 "Interface Address Group Source Timer Fwd Uptime \n");
3601 /* scan interfaces */
3602 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3603 struct pim_interface
*pim_ifp
= ifp
->info
;
3604 struct listnode
*sock_node
;
3605 struct igmp_sock
*igmp
;
3610 /* scan igmp sockets */
3611 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3613 char ifaddr_str
[INET_ADDRSTRLEN
];
3614 struct listnode
*grpnode
;
3615 struct igmp_group
*grp
;
3617 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3618 sizeof(ifaddr_str
));
3620 /* scan igmp groups */
3621 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3623 char group_str
[INET_ADDRSTRLEN
];
3624 struct listnode
*srcnode
;
3625 struct igmp_source
*src
;
3627 pim_inet4_dump("<group?>", grp
->group_addr
,
3628 group_str
, sizeof(group_str
));
3630 /* scan group sources */
3631 for (ALL_LIST_ELEMENTS_RO(
3632 grp
->group_source_list
, srcnode
,
3634 char source_str
[INET_ADDRSTRLEN
];
3639 "<source?>", src
->source_addr
,
3640 source_str
, sizeof(source_str
));
3642 pim_time_timer_to_mmss(
3644 src
->t_source_timer
);
3647 uptime
, sizeof(uptime
),
3648 now
- src
->source_creation
);
3651 "%-16s %-15s %-15s %-15s %5s %3s %8s\n",
3652 ifp
->name
, ifaddr_str
,
3653 group_str
, source_str
, mmss
,
3654 IGMP_SOURCE_TEST_FORWARDING(
3660 } /* scan group sources */
3661 } /* scan igmp groups */
3662 } /* scan igmp sockets */
3663 } /* scan interfaces */
3666 static void igmp_show_source_retransmission(struct pim_instance
*pim
,
3669 struct interface
*ifp
;
3672 "Interface Address Group Source Counter\n");
3674 /* scan interfaces */
3675 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3676 struct pim_interface
*pim_ifp
= ifp
->info
;
3677 struct listnode
*sock_node
;
3678 struct igmp_sock
*igmp
;
3683 /* scan igmp sockets */
3684 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3686 char ifaddr_str
[INET_ADDRSTRLEN
];
3687 struct listnode
*grpnode
;
3688 struct igmp_group
*grp
;
3690 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3691 sizeof(ifaddr_str
));
3693 /* scan igmp groups */
3694 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3696 char group_str
[INET_ADDRSTRLEN
];
3697 struct listnode
*srcnode
;
3698 struct igmp_source
*src
;
3700 pim_inet4_dump("<group?>", grp
->group_addr
,
3701 group_str
, sizeof(group_str
));
3703 /* scan group sources */
3704 for (ALL_LIST_ELEMENTS_RO(
3705 grp
->group_source_list
, srcnode
,
3707 char source_str
[INET_ADDRSTRLEN
];
3710 "<source?>", src
->source_addr
,
3711 source_str
, sizeof(source_str
));
3714 "%-16s %-15s %-15s %-15s %7d\n",
3715 ifp
->name
, ifaddr_str
,
3716 group_str
, source_str
,
3717 src
->source_query_retransmit_count
);
3719 } /* scan group sources */
3720 } /* scan igmp groups */
3721 } /* scan igmp sockets */
3722 } /* scan interfaces */
3725 static void pim_show_bsr(struct pim_instance
*pim
,
3730 char last_bsm_seen
[10];
3733 char bsr_str
[PREFIX_STRLEN
];
3734 json_object
*json
= NULL
;
3736 vty_out(vty
, "PIMv2 Bootstrap information\n");
3738 if (pim
->global_scope
.current_bsr
.s_addr
== INADDR_ANY
) {
3739 strlcpy(bsr_str
, "0.0.0.0", sizeof(bsr_str
));
3740 pim_time_uptime(uptime
, sizeof(uptime
),
3741 pim
->global_scope
.current_bsr_first_ts
);
3742 pim_time_uptime(last_bsm_seen
, sizeof(last_bsm_seen
),
3743 pim
->global_scope
.current_bsr_last_ts
);
3747 pim_inet4_dump("<bsr?>", pim
->global_scope
.current_bsr
,
3748 bsr_str
, sizeof(bsr_str
));
3749 now
= pim_time_monotonic_sec();
3750 pim_time_uptime(uptime
, sizeof(uptime
),
3751 (now
- pim
->global_scope
.current_bsr_first_ts
));
3752 pim_time_uptime(last_bsm_seen
, sizeof(last_bsm_seen
),
3753 now
- pim
->global_scope
.current_bsr_last_ts
);
3756 switch (pim
->global_scope
.state
) {
3758 strlcpy(bsr_state
, "NO_INFO", sizeof(bsr_state
));
3761 strlcpy(bsr_state
, "ACCEPT_ANY", sizeof(bsr_state
));
3763 case ACCEPT_PREFERRED
:
3764 strlcpy(bsr_state
, "ACCEPT_PREFERRED", sizeof(bsr_state
));
3767 strlcpy(bsr_state
, "", sizeof(bsr_state
));
3771 json
= json_object_new_object();
3772 json_object_string_add(json
, "bsr", bsr_str
);
3773 json_object_int_add(json
, "priority",
3774 pim
->global_scope
.current_bsr_prio
);
3775 json_object_int_add(json
, "fragment_tag",
3776 pim
->global_scope
.bsm_frag_tag
);
3777 json_object_string_add(json
, "state", bsr_state
);
3778 json_object_string_add(json
, "upTime", uptime
);
3779 json_object_string_add(json
, "last_bsm_seen", last_bsm_seen
);
3783 vty_out(vty
, "Current preferred BSR address: %s\n", bsr_str
);
3785 "Priority Fragment-Tag State UpTime\n");
3786 vty_out(vty
, " %-12d %-12d %-13s %7s\n",
3787 pim
->global_scope
.current_bsr_prio
,
3788 pim
->global_scope
.bsm_frag_tag
,
3791 vty_out(vty
, "Last BSM seen: %s\n", last_bsm_seen
);
3795 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3796 json
, JSON_C_TO_STRING_PRETTY
));
3797 json_object_free(json
);
3801 static void clear_igmp_interfaces(struct pim_instance
*pim
)
3803 struct interface
*ifp
;
3805 FOR_ALL_INTERFACES (pim
->vrf
, ifp
)
3806 pim_if_addr_del_all_igmp(ifp
);
3808 FOR_ALL_INTERFACES (pim
->vrf
, ifp
)
3809 pim_if_addr_add_all(ifp
);
3812 static void clear_pim_interfaces(struct pim_instance
*pim
)
3814 struct interface
*ifp
;
3816 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3818 pim_neighbor_delete_all(ifp
, "interface cleared");
3823 static void clear_interfaces(struct pim_instance
*pim
)
3825 clear_igmp_interfaces(pim
);
3826 clear_pim_interfaces(pim
);
3829 #define PIM_GET_PIM_INTERFACE(pim_ifp, ifp) \
3830 pim_ifp = ifp->info; \
3833 "%% Enable PIM and/or IGMP on this interface first\n"); \
3834 return CMD_WARNING_CONFIG_FAILED; \
3837 DEFUN (clear_ip_interfaces
,
3838 clear_ip_interfaces_cmd
,
3839 "clear ip interfaces [vrf NAME]",
3842 "Reset interfaces\n"
3846 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3851 clear_interfaces(vrf
->info
);
3856 DEFUN (clear_ip_igmp_interfaces
,
3857 clear_ip_igmp_interfaces_cmd
,
3858 "clear ip igmp [vrf NAME] interfaces",
3863 "Reset IGMP interfaces\n")
3866 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3871 clear_igmp_interfaces(vrf
->info
);
3876 DEFUN (clear_ip_pim_statistics
,
3877 clear_ip_pim_statistics_cmd
,
3878 "clear ip pim statistics [vrf NAME]",
3883 "Reset PIM statistics\n")
3886 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3891 clear_pim_statistics(vrf
->info
);
3895 static void clear_mroute(struct pim_instance
*pim
)
3897 struct pim_upstream
*up
;
3898 struct interface
*ifp
;
3900 /* scan interfaces */
3901 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3902 struct pim_interface
*pim_ifp
= ifp
->info
;
3903 struct listnode
*sock_node
;
3904 struct igmp_sock
*igmp
;
3905 struct pim_ifchannel
*ch
;
3910 /* deleting all ifchannels */
3911 while (!RB_EMPTY(pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
)) {
3912 ch
= RB_ROOT(pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
);
3914 pim_ifchannel_delete(ch
);
3917 /* clean up all igmp groups */
3918 /* scan igmp sockets */
3919 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3922 struct igmp_group
*grp
;
3924 if (igmp
->igmp_group_list
) {
3925 while (igmp
->igmp_group_list
->count
) {
3926 grp
= listnode_head(
3927 igmp
->igmp_group_list
);
3928 igmp_group_delete(grp
);
3935 /* clean up all upstreams*/
3936 if (pim
->upstream_list
) {
3937 while (pim
->upstream_list
->count
) {
3938 up
= listnode_head(pim
->upstream_list
);
3939 pim_upstream_del(pim
, up
, __PRETTY_FUNCTION__
);
3944 DEFUN (clear_ip_mroute
,
3945 clear_ip_mroute_cmd
,
3946 "clear ip mroute [vrf NAME]",
3949 "Reset multicast routes\n"
3953 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3958 clear_mroute(vrf
->info
);
3963 DEFUN (clear_ip_pim_interfaces
,
3964 clear_ip_pim_interfaces_cmd
,
3965 "clear ip pim [vrf NAME] interfaces",
3970 "Reset PIM interfaces\n")
3973 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3978 clear_pim_interfaces(vrf
->info
);
3983 DEFUN (clear_ip_pim_interface_traffic
,
3984 clear_ip_pim_interface_traffic_cmd
,
3985 "clear ip pim [vrf NAME] interface traffic",
3988 "PIM clear commands\n"
3990 "Reset PIM interfaces\n"
3991 "Reset Protocol Packet counters\n")
3994 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3995 struct interface
*ifp
= NULL
;
3996 struct pim_interface
*pim_ifp
= NULL
;
4001 FOR_ALL_INTERFACES (vrf
, ifp
) {
4002 pim_ifp
= ifp
->info
;
4007 pim_ifp
->pim_ifstat_hello_recv
= 0;
4008 pim_ifp
->pim_ifstat_hello_sent
= 0;
4009 pim_ifp
->pim_ifstat_join_recv
= 0;
4010 pim_ifp
->pim_ifstat_join_send
= 0;
4011 pim_ifp
->pim_ifstat_prune_recv
= 0;
4012 pim_ifp
->pim_ifstat_prune_send
= 0;
4013 pim_ifp
->pim_ifstat_reg_recv
= 0;
4014 pim_ifp
->pim_ifstat_reg_send
= 0;
4015 pim_ifp
->pim_ifstat_reg_stop_recv
= 0;
4016 pim_ifp
->pim_ifstat_reg_stop_send
= 0;
4017 pim_ifp
->pim_ifstat_assert_recv
= 0;
4018 pim_ifp
->pim_ifstat_assert_send
= 0;
4019 pim_ifp
->pim_ifstat_bsm_rx
= 0;
4020 pim_ifp
->pim_ifstat_bsm_tx
= 0;
4026 DEFUN (clear_ip_pim_oil
,
4027 clear_ip_pim_oil_cmd
,
4028 "clear ip pim [vrf NAME] oil",
4033 "Rescan PIM OIL (output interface list)\n")
4036 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4041 pim_scan_oil(vrf
->info
);
4046 DEFUN (show_ip_igmp_interface
,
4047 show_ip_igmp_interface_cmd
,
4048 "show ip igmp [vrf NAME] interface [detail|WORD] [json]",
4053 "IGMP interface information\n"
4059 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4060 bool uj
= use_json(argc
, argv
);
4065 if (argv_find(argv
, argc
, "detail", &idx
)
4066 || argv_find(argv
, argc
, "WORD", &idx
))
4067 igmp_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
4069 igmp_show_interfaces(vrf
->info
, vty
, uj
);
4074 DEFUN (show_ip_igmp_interface_vrf_all
,
4075 show_ip_igmp_interface_vrf_all_cmd
,
4076 "show ip igmp vrf all interface [detail|WORD] [json]",
4081 "IGMP interface information\n"
4087 bool uj
= use_json(argc
, argv
);
4093 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4097 vty_out(vty
, " \"%s\": ", vrf
->name
);
4100 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4101 if (argv_find(argv
, argc
, "detail", &idx
)
4102 || argv_find(argv
, argc
, "WORD", &idx
))
4103 igmp_show_interfaces_single(vrf
->info
, vty
,
4104 argv
[idx
]->arg
, uj
);
4106 igmp_show_interfaces(vrf
->info
, vty
, uj
);
4109 vty_out(vty
, "}\n");
4114 DEFUN (show_ip_igmp_join
,
4115 show_ip_igmp_join_cmd
,
4116 "show ip igmp [vrf NAME] join",
4121 "IGMP static join information\n")
4124 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4129 igmp_show_interface_join(vrf
->info
, vty
);
4134 DEFUN (show_ip_igmp_join_vrf_all
,
4135 show_ip_igmp_join_vrf_all_cmd
,
4136 "show ip igmp vrf all join",
4141 "IGMP static join information\n")
4143 bool uj
= use_json(argc
, argv
);
4149 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4153 vty_out(vty
, " \"%s\": ", vrf
->name
);
4156 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4157 igmp_show_interface_join(vrf
->info
, vty
);
4160 vty_out(vty
, "}\n");
4165 DEFUN (show_ip_igmp_groups
,
4166 show_ip_igmp_groups_cmd
,
4167 "show ip igmp [vrf NAME] groups [json]",
4176 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4177 bool uj
= use_json(argc
, argv
);
4182 igmp_show_groups(vrf
->info
, vty
, uj
);
4187 DEFUN (show_ip_igmp_groups_vrf_all
,
4188 show_ip_igmp_groups_vrf_all_cmd
,
4189 "show ip igmp vrf all groups [json]",
4197 bool uj
= use_json(argc
, argv
);
4203 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4207 vty_out(vty
, " \"%s\": ", vrf
->name
);
4210 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4211 igmp_show_groups(vrf
->info
, vty
, uj
);
4214 vty_out(vty
, "}\n");
4219 DEFUN (show_ip_igmp_groups_retransmissions
,
4220 show_ip_igmp_groups_retransmissions_cmd
,
4221 "show ip igmp [vrf NAME] groups retransmissions",
4227 "IGMP group retransmissions\n")
4230 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4235 igmp_show_group_retransmission(vrf
->info
, vty
);
4240 DEFUN (show_ip_igmp_sources
,
4241 show_ip_igmp_sources_cmd
,
4242 "show ip igmp [vrf NAME] sources",
4250 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4255 igmp_show_sources(vrf
->info
, vty
);
4260 DEFUN (show_ip_igmp_sources_retransmissions
,
4261 show_ip_igmp_sources_retransmissions_cmd
,
4262 "show ip igmp [vrf NAME] sources retransmissions",
4268 "IGMP source retransmissions\n")
4271 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4276 igmp_show_source_retransmission(vrf
->info
, vty
);
4281 DEFUN (show_ip_igmp_statistics
,
4282 show_ip_igmp_statistics_cmd
,
4283 "show ip igmp [vrf NAME] statistics [interface WORD] [json]",
4294 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4295 bool uj
= use_json(argc
, argv
);
4300 if (argv_find(argv
, argc
, "WORD", &idx
))
4301 igmp_show_statistics(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
4303 igmp_show_statistics(vrf
->info
, vty
, NULL
, uj
);
4308 DEFUN (show_ip_pim_assert
,
4309 show_ip_pim_assert_cmd
,
4310 "show ip pim [vrf NAME] assert",
4315 "PIM interface assert\n")
4318 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4323 pim_show_assert(vrf
->info
, vty
);
4328 DEFUN (show_ip_pim_assert_internal
,
4329 show_ip_pim_assert_internal_cmd
,
4330 "show ip pim [vrf NAME] assert-internal",
4335 "PIM interface internal assert state\n")
4338 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4343 pim_show_assert_internal(vrf
->info
, vty
);
4348 DEFUN (show_ip_pim_assert_metric
,
4349 show_ip_pim_assert_metric_cmd
,
4350 "show ip pim [vrf NAME] assert-metric",
4355 "PIM interface assert metric\n")
4358 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4363 pim_show_assert_metric(vrf
->info
, vty
);
4368 DEFUN (show_ip_pim_assert_winner_metric
,
4369 show_ip_pim_assert_winner_metric_cmd
,
4370 "show ip pim [vrf NAME] assert-winner-metric",
4375 "PIM interface assert winner metric\n")
4378 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4383 pim_show_assert_winner_metric(vrf
->info
, vty
);
4388 DEFUN (show_ip_pim_interface
,
4389 show_ip_pim_interface_cmd
,
4390 "show ip pim [vrf NAME] interface [detail|WORD] [json]",
4395 "PIM interface information\n"
4401 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4402 bool uj
= use_json(argc
, argv
);
4407 if (argv_find(argv
, argc
, "WORD", &idx
)
4408 || argv_find(argv
, argc
, "detail", &idx
))
4409 pim_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
4411 pim_show_interfaces(vrf
->info
, vty
, uj
);
4416 DEFUN (show_ip_pim_interface_vrf_all
,
4417 show_ip_pim_interface_vrf_all_cmd
,
4418 "show ip pim vrf all interface [detail|WORD] [json]",
4423 "PIM interface information\n"
4429 bool uj
= use_json(argc
, argv
);
4435 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4439 vty_out(vty
, " \"%s\": ", vrf
->name
);
4442 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4443 if (argv_find(argv
, argc
, "WORD", &idx
)
4444 || argv_find(argv
, argc
, "detail", &idx
))
4445 pim_show_interfaces_single(vrf
->info
, vty
,
4446 argv
[idx
]->arg
, uj
);
4448 pim_show_interfaces(vrf
->info
, vty
, uj
);
4451 vty_out(vty
, "}\n");
4456 DEFPY (show_ip_pim_join
,
4457 show_ip_pim_join_cmd
,
4458 "show ip pim [vrf NAME] join [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
4463 "PIM interface join information\n"
4464 "The Source or Group\n"
4468 struct prefix_sg sg
= {0};
4471 struct pim_instance
*pim
;
4473 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
4476 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
4479 pim
= pim_get_pim_instance(v
->vrf_id
);
4482 vty_out(vty
, "%% Unable to find pim instance\n");
4486 if (s_or_g
.s_addr
!= 0) {
4487 if (g
.s_addr
!= 0) {
4494 pim_show_join(pim
, vty
, &sg
, uj
);
4499 DEFUN (show_ip_pim_join_vrf_all
,
4500 show_ip_pim_join_vrf_all_cmd
,
4501 "show ip pim vrf all join [json]",
4506 "PIM interface join information\n"
4509 struct prefix_sg sg
= {0};
4510 bool uj
= use_json(argc
, argv
);
4516 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4520 vty_out(vty
, " \"%s\": ", vrf
->name
);
4523 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4524 pim_show_join(vrf
->info
, vty
, &sg
, uj
);
4527 vty_out(vty
, "}\n");
4532 static void pim_show_jp_agg_helper(struct vty
*vty
,
4533 struct interface
*ifp
,
4534 struct pim_neighbor
*neigh
,
4535 struct pim_upstream
*up
,
4538 char src_str
[INET_ADDRSTRLEN
];
4539 char grp_str
[INET_ADDRSTRLEN
];
4540 char rpf_str
[INET_ADDRSTRLEN
];
4542 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
4543 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
4544 /* pius->address.s_addr */
4545 pim_inet4_dump("<rpf?>", neigh
->source_addr
, rpf_str
, sizeof(rpf_str
));
4547 vty_out(vty
, "%-16s %-15s %-15s %-15s %5s\n",
4548 ifp
->name
, rpf_str
, src_str
,
4549 grp_str
, is_join
?"J":"P");
4552 static void pim_show_jp_agg_list(struct pim_instance
*pim
, struct vty
*vty
)
4554 struct interface
*ifp
;
4555 struct pim_interface
*pim_ifp
;
4556 struct listnode
*n_node
;
4557 struct pim_neighbor
*neigh
;
4558 struct listnode
*jag_node
;
4559 struct pim_jp_agg_group
*jag
;
4560 struct listnode
*js_node
;
4561 struct pim_jp_sources
*js
;
4564 "Interface RPF Nbr Source Group State\n");
4566 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
4567 pim_ifp
= ifp
->info
;
4571 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
,
4573 for (ALL_LIST_ELEMENTS_RO(neigh
->upstream_jp_agg
,
4575 for (ALL_LIST_ELEMENTS_RO(jag
->sources
,
4577 pim_show_jp_agg_helper(vty
,
4586 DEFPY (show_ip_pim_jp_agg
,
4587 show_ip_pim_jp_agg_cmd
,
4588 "show ip pim [vrf NAME] jp-agg",
4593 "join prune aggregation list\n")
4596 struct pim_instance
*pim
;
4598 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
4601 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
4604 pim
= pim_get_pim_instance(v
->vrf_id
);
4607 vty_out(vty
, "%% Unable to find pim instance\n");
4611 pim_show_jp_agg_list(pim
, vty
);
4616 DEFUN (show_ip_pim_local_membership
,
4617 show_ip_pim_local_membership_cmd
,
4618 "show ip pim [vrf NAME] local-membership [json]",
4623 "PIM interface local-membership\n"
4627 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4628 bool uj
= use_json(argc
, argv
);
4633 pim_show_membership(vrf
->info
, vty
, uj
);
4638 DEFUN (show_ip_pim_neighbor
,
4639 show_ip_pim_neighbor_cmd
,
4640 "show ip pim [vrf NAME] neighbor [detail|WORD] [json]",
4645 "PIM neighbor information\n"
4647 "Name of interface or neighbor\n"
4651 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4652 bool uj
= use_json(argc
, argv
);
4657 if (argv_find(argv
, argc
, "detail", &idx
)
4658 || argv_find(argv
, argc
, "WORD", &idx
))
4659 pim_show_neighbors_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
4661 pim_show_neighbors(vrf
->info
, vty
, uj
);
4666 DEFUN (show_ip_pim_neighbor_vrf_all
,
4667 show_ip_pim_neighbor_vrf_all_cmd
,
4668 "show ip pim vrf all neighbor [detail|WORD] [json]",
4673 "PIM neighbor information\n"
4675 "Name of interface or neighbor\n"
4679 bool uj
= use_json(argc
, argv
);
4685 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4689 vty_out(vty
, " \"%s\": ", vrf
->name
);
4692 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4693 if (argv_find(argv
, argc
, "detail", &idx
)
4694 || argv_find(argv
, argc
, "WORD", &idx
))
4695 pim_show_neighbors_single(vrf
->info
, vty
,
4696 argv
[idx
]->arg
, uj
);
4698 pim_show_neighbors(vrf
->info
, vty
, uj
);
4701 vty_out(vty
, "}\n");
4706 DEFUN (show_ip_pim_secondary
,
4707 show_ip_pim_secondary_cmd
,
4708 "show ip pim [vrf NAME] secondary",
4713 "PIM neighbor addresses\n")
4716 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4721 pim_show_neighbors_secondary(vrf
->info
, vty
);
4726 DEFUN (show_ip_pim_state
,
4727 show_ip_pim_state_cmd
,
4728 "show ip pim [vrf NAME] state [A.B.C.D [A.B.C.D]] [json]",
4733 "PIM state information\n"
4734 "Unicast or Multicast address\n"
4735 "Multicast address\n"
4738 const char *src_or_group
= NULL
;
4739 const char *group
= NULL
;
4741 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4742 bool uj
= use_json(argc
, argv
);
4750 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
4751 src_or_group
= argv
[idx
]->arg
;
4753 group
= argv
[idx
+ 1]->arg
;
4756 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
4761 DEFUN (show_ip_pim_state_vrf_all
,
4762 show_ip_pim_state_vrf_all_cmd
,
4763 "show ip pim vrf all state [A.B.C.D [A.B.C.D]] [json]",
4768 "PIM state information\n"
4769 "Unicast or Multicast address\n"
4770 "Multicast address\n"
4773 const char *src_or_group
= NULL
;
4774 const char *group
= NULL
;
4776 bool uj
= use_json(argc
, argv
);
4785 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
4786 src_or_group
= argv
[idx
]->arg
;
4788 group
= argv
[idx
+ 1]->arg
;
4791 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4795 vty_out(vty
, " \"%s\": ", vrf
->name
);
4798 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4799 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
4802 vty_out(vty
, "}\n");
4807 DEFPY (show_ip_pim_upstream
,
4808 show_ip_pim_upstream_cmd
,
4809 "show ip pim [vrf NAME] upstream [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
4814 "PIM upstream information\n"
4815 "The Source or Group\n"
4819 struct prefix_sg sg
= {0};
4822 struct pim_instance
*pim
;
4824 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
4827 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
4830 pim
= pim_get_pim_instance(v
->vrf_id
);
4833 vty_out(vty
, "%% Unable to find pim instance\n");
4837 if (s_or_g
.s_addr
!= 0) {
4838 if (g
.s_addr
!= 0) {
4844 pim_show_upstream(pim
, vty
, &sg
, uj
);
4849 DEFUN (show_ip_pim_upstream_vrf_all
,
4850 show_ip_pim_upstream_vrf_all_cmd
,
4851 "show ip pim vrf all upstream [json]",
4856 "PIM upstream information\n"
4859 struct prefix_sg sg
= {0};
4860 bool uj
= use_json(argc
, argv
);
4866 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4870 vty_out(vty
, " \"%s\": ", vrf
->name
);
4873 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4874 pim_show_upstream(vrf
->info
, vty
, &sg
, uj
);
4880 DEFUN (show_ip_pim_channel
,
4881 show_ip_pim_channel_cmd
,
4882 "show ip pim [vrf NAME] channel [json]",
4887 "PIM downstream channel info\n"
4891 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4892 bool uj
= use_json(argc
, argv
);
4897 pim_show_channel(vrf
->info
, vty
, uj
);
4902 DEFUN (show_ip_pim_upstream_join_desired
,
4903 show_ip_pim_upstream_join_desired_cmd
,
4904 "show ip pim [vrf NAME] upstream-join-desired [json]",
4909 "PIM upstream join-desired\n"
4913 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4914 bool uj
= use_json(argc
, argv
);
4919 pim_show_join_desired(vrf
->info
, vty
, uj
);
4924 DEFUN (show_ip_pim_upstream_rpf
,
4925 show_ip_pim_upstream_rpf_cmd
,
4926 "show ip pim [vrf NAME] upstream-rpf [json]",
4931 "PIM upstream source rpf\n"
4935 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4936 bool uj
= use_json(argc
, argv
);
4941 pim_show_upstream_rpf(vrf
->info
, vty
, uj
);
4946 DEFUN (show_ip_pim_rp
,
4948 "show ip pim [vrf NAME] rp-info [json]",
4953 "PIM RP information\n"
4957 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4958 bool uj
= use_json(argc
, argv
);
4963 pim_rp_show_information(vrf
->info
, vty
, uj
);
4968 DEFUN (show_ip_pim_rp_vrf_all
,
4969 show_ip_pim_rp_vrf_all_cmd
,
4970 "show ip pim vrf all rp-info [json]",
4975 "PIM RP information\n"
4978 bool uj
= use_json(argc
, argv
);
4984 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4988 vty_out(vty
, " \"%s\": ", vrf
->name
);
4991 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4992 pim_rp_show_information(vrf
->info
, vty
, uj
);
4995 vty_out(vty
, "}\n");
5000 DEFUN (show_ip_pim_rpf
,
5001 show_ip_pim_rpf_cmd
,
5002 "show ip pim [vrf NAME] rpf [json]",
5007 "PIM cached source rpf information\n"
5011 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5012 bool uj
= use_json(argc
, argv
);
5017 pim_show_rpf(vrf
->info
, vty
, uj
);
5022 DEFUN (show_ip_pim_rpf_vrf_all
,
5023 show_ip_pim_rpf_vrf_all_cmd
,
5024 "show ip pim vrf all rpf [json]",
5029 "PIM cached source rpf information\n"
5032 bool uj
= use_json(argc
, argv
);
5038 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5042 vty_out(vty
, " \"%s\": ", vrf
->name
);
5045 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5046 pim_show_rpf(vrf
->info
, vty
, uj
);
5049 vty_out(vty
, "}\n");
5054 DEFUN (show_ip_pim_nexthop
,
5055 show_ip_pim_nexthop_cmd
,
5056 "show ip pim [vrf NAME] nexthop",
5061 "PIM cached nexthop rpf information\n")
5064 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5069 pim_show_nexthop(vrf
->info
, vty
);
5074 DEFUN (show_ip_pim_nexthop_lookup
,
5075 show_ip_pim_nexthop_lookup_cmd
,
5076 "show ip pim [vrf NAME] nexthop-lookup A.B.C.D A.B.C.D",
5081 "PIM cached nexthop rpf lookup\n"
5082 "Source/RP address\n"
5083 "Multicast Group address\n")
5085 struct prefix nht_p
;
5087 struct in_addr src_addr
, grp_addr
;
5088 struct in_addr vif_source
;
5089 const char *addr_str
, *addr_str1
;
5091 struct pim_nexthop nexthop
;
5092 char nexthop_addr_str
[PREFIX_STRLEN
];
5093 char grp_str
[PREFIX_STRLEN
];
5095 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5100 argv_find(argv
, argc
, "A.B.C.D", &idx
);
5101 addr_str
= argv
[idx
]->arg
;
5102 result
= inet_pton(AF_INET
, addr_str
, &src_addr
);
5104 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
5105 errno
, safe_strerror(errno
));
5109 if (pim_is_group_224_4(src_addr
)) {
5111 "Invalid argument. Expected Valid Source Address.\n");
5115 addr_str1
= argv
[idx
+ 1]->arg
;
5116 result
= inet_pton(AF_INET
, addr_str1
, &grp_addr
);
5118 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
5119 errno
, safe_strerror(errno
));
5123 if (!pim_is_group_224_4(grp_addr
)) {
5125 "Invalid argument. Expected Valid Multicast Group Address.\n");
5129 if (!pim_rp_set_upstream_addr(vrf
->info
, &vif_source
, src_addr
,
5133 nht_p
.family
= AF_INET
;
5134 nht_p
.prefixlen
= IPV4_MAX_BITLEN
;
5135 nht_p
.u
.prefix4
= vif_source
;
5136 grp
.family
= AF_INET
;
5137 grp
.prefixlen
= IPV4_MAX_BITLEN
;
5138 grp
.u
.prefix4
= grp_addr
;
5139 memset(&nexthop
, 0, sizeof(nexthop
));
5141 result
= pim_ecmp_nexthop_lookup(vrf
->info
, &nexthop
, &nht_p
, &grp
, 0);
5145 "Nexthop Lookup failed, no usable routes returned.\n");
5149 pim_addr_dump("<grp?>", &grp
, grp_str
, sizeof(grp_str
));
5150 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
5151 nexthop_addr_str
, sizeof(nexthop_addr_str
));
5152 vty_out(vty
, "Group %s --- Nexthop %s Interface %s \n", grp_str
,
5153 nexthop_addr_str
, nexthop
.interface
->name
);
5158 DEFUN (show_ip_pim_interface_traffic
,
5159 show_ip_pim_interface_traffic_cmd
,
5160 "show ip pim [vrf NAME] interface traffic [WORD] [json]",
5165 "PIM interface information\n"
5166 "Protocol Packet counters\n"
5171 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5172 bool uj
= use_json(argc
, argv
);
5177 if (argv_find(argv
, argc
, "WORD", &idx
))
5178 pim_show_interface_traffic_single(vrf
->info
, vty
,
5179 argv
[idx
]->arg
, uj
);
5181 pim_show_interface_traffic(vrf
->info
, vty
, uj
);
5186 DEFUN (show_ip_pim_bsm_db
,
5187 show_ip_pim_bsm_db_cmd
,
5188 "show ip pim bsm-database [vrf NAME] [json]",
5192 "PIM cached bsm packets information\n"
5197 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5198 bool uj
= use_json(argc
, argv
);
5203 pim_show_bsm_db(vrf
->info
, vty
, uj
);
5207 DEFUN (show_ip_pim_bsrp
,
5208 show_ip_pim_bsrp_cmd
,
5209 "show ip pim bsrp-info [vrf NAME] [json]",
5213 "PIM cached group-rp mappings information\n"
5218 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5219 bool uj
= use_json(argc
, argv
);
5224 pim_show_group_rp_mappings_info(vrf
->info
, vty
, uj
);
5229 DEFUN (show_ip_pim_statistics
,
5230 show_ip_pim_statistics_cmd
,
5231 "show ip pim [vrf NAME] statistics [interface WORD] [json]",
5242 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5243 bool uj
= use_json(argc
, argv
);
5248 if (argv_find(argv
, argc
, "WORD", &idx
))
5249 pim_show_statistics(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
5251 pim_show_statistics(vrf
->info
, vty
, NULL
, uj
);
5256 static void show_multicast_interfaces(struct pim_instance
*pim
, struct vty
*vty
)
5258 struct interface
*ifp
;
5263 "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut\n");
5265 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
5266 struct pim_interface
*pim_ifp
;
5267 struct in_addr ifaddr
;
5268 struct sioc_vif_req vreq
;
5270 pim_ifp
= ifp
->info
;
5275 memset(&vreq
, 0, sizeof(vreq
));
5276 vreq
.vifi
= pim_ifp
->mroute_vif_index
;
5278 if (ioctl(pim
->mroute_socket
, SIOCGETVIFCNT
, &vreq
)) {
5280 "ioctl(SIOCGETVIFCNT=%lu) failure for interface %s vif_index=%d: errno=%d: %s",
5281 (unsigned long)SIOCGETVIFCNT
, ifp
->name
,
5282 pim_ifp
->mroute_vif_index
, errno
,
5283 safe_strerror(errno
));
5286 ifaddr
= pim_ifp
->primary_address
;
5288 vty_out(vty
, "%-16s %-15s %3d %3d %7lu %7lu %10lu %10lu\n",
5289 ifp
->name
, inet_ntoa(ifaddr
), ifp
->ifindex
,
5290 pim_ifp
->mroute_vif_index
, (unsigned long)vreq
.icount
,
5291 (unsigned long)vreq
.ocount
, (unsigned long)vreq
.ibytes
,
5292 (unsigned long)vreq
.obytes
);
5296 static void pim_cmd_show_ip_multicast_helper(struct pim_instance
*pim
,
5299 struct vrf
*vrf
= pim
->vrf
;
5300 time_t now
= pim_time_monotonic_sec();
5306 vty_out(vty
, "Router MLAG Role: %s\n",
5307 mlag_role2str(router
->role
, mlag_role
, sizeof(mlag_role
)));
5308 vty_out(vty
, "Mroute socket descriptor:");
5310 vty_out(vty
, " %d(%s)\n", pim
->mroute_socket
, vrf
->name
);
5312 pim_time_uptime(uptime
, sizeof(uptime
),
5313 now
- pim
->mroute_socket_creation
);
5314 vty_out(vty
, "Mroute socket uptime: %s\n", uptime
);
5318 pim_zebra_zclient_update(vty
);
5319 pim_zlookup_show_ip_multicast(vty
);
5322 vty_out(vty
, "Maximum highest VifIndex: %d\n", PIM_MAX_USABLE_VIFS
);
5325 vty_out(vty
, "Upstream Join Timer: %d secs\n", router
->t_periodic
);
5326 vty_out(vty
, "Join/Prune Holdtime: %d secs\n", PIM_JP_HOLDTIME
);
5327 vty_out(vty
, "PIM ECMP: %s\n", pim
->ecmp_enable
? "Enable" : "Disable");
5328 vty_out(vty
, "PIM ECMP Rebalance: %s\n",
5329 pim
->ecmp_rebalance_enable
? "Enable" : "Disable");
5333 show_rpf_refresh_stats(vty
, pim
, now
, NULL
);
5337 show_scan_oil_stats(pim
, vty
, now
);
5339 show_multicast_interfaces(pim
, vty
);
5342 DEFUN (show_ip_multicast
,
5343 show_ip_multicast_cmd
,
5344 "show ip multicast [vrf NAME]",
5348 "Multicast global information\n")
5351 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5356 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
5361 DEFUN (show_ip_multicast_vrf_all
,
5362 show_ip_multicast_vrf_all_cmd
,
5363 "show ip multicast vrf all",
5367 "Multicast global information\n")
5369 bool uj
= use_json(argc
, argv
);
5375 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5379 vty_out(vty
, " \"%s\": ", vrf
->name
);
5382 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5383 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
5386 vty_out(vty
, "}\n");
5391 static void show_mroute(struct pim_instance
*pim
, struct vty
*vty
,
5392 struct prefix_sg
*sg
, bool fill
, bool uj
)
5394 struct listnode
*node
;
5395 struct channel_oil
*c_oil
;
5396 struct static_route
*s_route
;
5398 json_object
*json
= NULL
;
5399 json_object
*json_group
= NULL
;
5400 json_object
*json_source
= NULL
;
5401 json_object
*json_oil
= NULL
;
5402 json_object
*json_ifp_out
= NULL
;
5405 char grp_str
[INET_ADDRSTRLEN
];
5406 char src_str
[INET_ADDRSTRLEN
];
5407 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
5408 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
5410 struct interface
*ifp_in
;
5414 json
= json_object_new_object();
5417 "Source Group Proto Input Output TTL Uptime\n");
5420 now
= pim_time_monotonic_sec();
5422 /* print list of PIM and IGMP routes */
5423 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
5426 if (!c_oil
->installed
&& !uj
)
5429 if (sg
->grp
.s_addr
!= 0 &&
5430 sg
->grp
.s_addr
!= c_oil
->oil
.mfcc_mcastgrp
.s_addr
)
5432 if (sg
->src
.s_addr
!= 0 &&
5433 sg
->src
.s_addr
!= c_oil
->oil
.mfcc_origin
.s_addr
)
5436 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
5438 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
5440 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
5443 strlcpy(in_ifname
, ifp_in
->name
, sizeof(in_ifname
));
5445 strlcpy(in_ifname
, "<iif?>", sizeof(in_ifname
));
5449 /* Find the group, create it if it doesn't exist */
5450 json_object_object_get_ex(json
, grp_str
, &json_group
);
5453 json_group
= json_object_new_object();
5454 json_object_object_add(json
, grp_str
,
5458 /* Find the source nested under the group, create it if
5459 * it doesn't exist */
5460 json_object_object_get_ex(json_group
, src_str
,
5464 json_source
= json_object_new_object();
5465 json_object_object_add(json_group
, src_str
,
5469 /* Find the inbound interface nested under the source,
5470 * create it if it doesn't exist */
5471 json_object_int_add(json_source
, "installed",
5473 json_object_int_add(json_source
, "refCount",
5474 c_oil
->oil_ref_count
);
5475 json_object_int_add(json_source
, "oilSize",
5477 json_object_int_add(json_source
, "OilInheritedRescan",
5478 c_oil
->oil_inherited_rescan
);
5479 json_object_string_add(json_source
, "iif", in_ifname
);
5483 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
5485 struct interface
*ifp_out
;
5486 char mroute_uptime
[10];
5489 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
5493 /* do not display muted OIFs */
5494 if (c_oil
->oif_flags
[oif_vif_index
]
5495 & PIM_OIF_FLAG_MUTE
)
5498 if (c_oil
->oil
.mfcc_parent
== oif_vif_index
&&
5499 !pim_mroute_allow_iif_in_oil(c_oil
,
5503 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
5505 mroute_uptime
, sizeof(mroute_uptime
),
5506 now
- c_oil
->mroute_creation
);
5510 strlcpy(out_ifname
, ifp_out
->name
, sizeof(out_ifname
));
5512 strlcpy(out_ifname
, "<oif?>", sizeof(out_ifname
));
5515 json_ifp_out
= json_object_new_object();
5516 json_object_string_add(json_ifp_out
, "source",
5518 json_object_string_add(json_ifp_out
, "group",
5521 if (c_oil
->oif_flags
[oif_vif_index
]
5522 & PIM_OIF_FLAG_PROTO_PIM
)
5523 json_object_boolean_true_add(
5524 json_ifp_out
, "protocolPim");
5526 if (c_oil
->oif_flags
[oif_vif_index
]
5527 & PIM_OIF_FLAG_PROTO_IGMP
)
5528 json_object_boolean_true_add(
5529 json_ifp_out
, "protocolIgmp");
5531 if (c_oil
->oif_flags
[oif_vif_index
]
5532 & PIM_OIF_FLAG_PROTO_VXLAN
)
5533 json_object_boolean_true_add(
5534 json_ifp_out
, "protocolVxlan");
5536 if (c_oil
->oif_flags
[oif_vif_index
]
5537 & PIM_OIF_FLAG_PROTO_STAR
)
5538 json_object_boolean_true_add(
5540 "protocolInherited");
5542 json_object_string_add(json_ifp_out
,
5545 json_object_int_add(json_ifp_out
, "iVifI",
5546 c_oil
->oil
.mfcc_parent
);
5547 json_object_string_add(json_ifp_out
,
5548 "outboundInterface",
5550 json_object_int_add(json_ifp_out
, "oVifI",
5552 json_object_int_add(json_ifp_out
, "ttl", ttl
);
5553 json_object_string_add(json_ifp_out
, "upTime",
5556 json_oil
= json_object_new_object();
5557 json_object_object_add(json_source
,
5560 json_object_object_add(json_oil
, out_ifname
,
5563 if (c_oil
->oif_flags
[oif_vif_index
]
5564 & PIM_OIF_FLAG_PROTO_PIM
) {
5565 strlcpy(proto
, "PIM", sizeof(proto
));
5568 if (c_oil
->oif_flags
[oif_vif_index
]
5569 & PIM_OIF_FLAG_PROTO_IGMP
) {
5570 strlcpy(proto
, "IGMP", sizeof(proto
));
5573 if (c_oil
->oif_flags
[oif_vif_index
]
5574 & PIM_OIF_FLAG_PROTO_VXLAN
) {
5575 strlcpy(proto
, "VxLAN", sizeof(proto
));
5578 if (c_oil
->oif_flags
[oif_vif_index
]
5579 & PIM_OIF_FLAG_PROTO_STAR
) {
5580 strlcpy(proto
, "STAR", sizeof(proto
));
5584 "%-15s %-15s %-6s %-16s %-16s %-3d %8s\n",
5585 src_str
, grp_str
, proto
, in_ifname
,
5586 out_ifname
, ttl
, mroute_uptime
);
5591 in_ifname
[0] = '\0';
5597 if (!uj
&& !found_oif
) {
5598 vty_out(vty
, "%-15s %-15s %-6s %-16s %-16s %-3d %8s\n",
5599 src_str
, grp_str
, "none", in_ifname
, "none", 0,
5604 /* Print list of static routes */
5605 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
5608 if (!s_route
->c_oil
.installed
)
5611 pim_inet4_dump("<group?>", s_route
->group
, grp_str
,
5613 pim_inet4_dump("<source?>", s_route
->source
, src_str
,
5615 ifp_in
= pim_if_find_by_vif_index(pim
, s_route
->iif
);
5619 strlcpy(in_ifname
, ifp_in
->name
, sizeof(in_ifname
));
5621 strlcpy(in_ifname
, "<iif?>", sizeof(in_ifname
));
5625 /* Find the group, create it if it doesn't exist */
5626 json_object_object_get_ex(json
, grp_str
, &json_group
);
5629 json_group
= json_object_new_object();
5630 json_object_object_add(json
, grp_str
,
5634 /* Find the source nested under the group, create it if
5635 * it doesn't exist */
5636 json_object_object_get_ex(json_group
, src_str
,
5640 json_source
= json_object_new_object();
5641 json_object_object_add(json_group
, src_str
,
5645 json_object_string_add(json_source
, "iif", in_ifname
);
5648 strlcpy(proto
, "STATIC", sizeof(proto
));
5651 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
5653 struct interface
*ifp_out
;
5654 char oif_uptime
[10];
5657 ttl
= s_route
->oif_ttls
[oif_vif_index
];
5661 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
5663 oif_uptime
, sizeof(oif_uptime
),
5666 .oif_creation
[oif_vif_index
]);
5670 strlcpy(out_ifname
, ifp_out
->name
, sizeof(out_ifname
));
5672 strlcpy(out_ifname
, "<oif?>", sizeof(out_ifname
));
5675 json_ifp_out
= json_object_new_object();
5676 json_object_string_add(json_ifp_out
, "source",
5678 json_object_string_add(json_ifp_out
, "group",
5680 json_object_boolean_true_add(json_ifp_out
,
5682 json_object_string_add(json_ifp_out
,
5685 json_object_int_add(
5686 json_ifp_out
, "iVifI",
5687 s_route
->c_oil
.oil
.mfcc_parent
);
5688 json_object_string_add(json_ifp_out
,
5689 "outboundInterface",
5691 json_object_int_add(json_ifp_out
, "oVifI",
5693 json_object_int_add(json_ifp_out
, "ttl", ttl
);
5694 json_object_string_add(json_ifp_out
, "upTime",
5697 json_oil
= json_object_new_object();
5698 json_object_object_add(json_source
,
5701 json_object_object_add(json_oil
, out_ifname
,
5705 "%-15s %-15s %-6s %-16s %-16s %-3d %8s %s\n",
5706 src_str
, grp_str
, proto
, in_ifname
,
5707 out_ifname
, ttl
, oif_uptime
,
5709 if (first
&& !fill
) {
5712 in_ifname
[0] = '\0';
5718 if (!uj
&& !found_oif
) {
5720 "%-15s %-15s %-6s %-16s %-16s %-3d %8s %s\n",
5721 src_str
, grp_str
, proto
, in_ifname
, "none", 0,
5722 "--:--:--", pim
->vrf
->name
);
5727 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5728 json
, JSON_C_TO_STRING_PRETTY
));
5729 json_object_free(json
);
5733 DEFPY (show_ip_mroute
,
5735 "show ip mroute [vrf NAME] [A.B.C.D$s_or_g [A.B.C.D$g]] [fill$fill] [json$json]",
5740 "The Source or Group\n"
5742 "Fill in Assumed data\n"
5745 struct prefix_sg sg
= {0};
5746 struct pim_instance
*pim
;
5749 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
5752 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
5755 pim
= pim_get_pim_instance(v
->vrf_id
);
5758 vty_out(vty
, "%% Unable to find pim instance\n");
5762 if (s_or_g
.s_addr
!= 0) {
5763 if (g
.s_addr
!= 0) {
5769 show_mroute(pim
, vty
, &sg
, !!fill
, !!json
);
5773 DEFUN (show_ip_mroute_vrf_all
,
5774 show_ip_mroute_vrf_all_cmd
,
5775 "show ip mroute vrf all [fill] [json]",
5780 "Fill in Assumed data\n"
5783 struct prefix_sg sg
= {0};
5784 bool uj
= use_json(argc
, argv
);
5790 if (argv_find(argv
, argc
, "fill", &idx
))
5795 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5799 vty_out(vty
, " \"%s\": ", vrf
->name
);
5802 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5803 show_mroute(vrf
->info
, vty
, &sg
, fill
, uj
);
5806 vty_out(vty
, "}\n");
5811 DEFUN (clear_ip_mroute_count
,
5812 clear_ip_mroute_count_cmd
,
5813 "clear ip mroute [vrf NAME] count",
5818 "Route and packet count data\n")
5821 struct listnode
*node
;
5822 struct channel_oil
*c_oil
;
5823 struct static_route
*sr
;
5824 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5825 struct pim_instance
*pim
;
5831 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
5832 if (!c_oil
->installed
)
5835 pim_mroute_update_counters(c_oil
);
5836 c_oil
->cc
.origpktcnt
= c_oil
->cc
.pktcnt
;
5837 c_oil
->cc
.origbytecnt
= c_oil
->cc
.bytecnt
;
5838 c_oil
->cc
.origwrong_if
= c_oil
->cc
.wrong_if
;
5841 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, sr
)) {
5842 if (!sr
->c_oil
.installed
)
5845 pim_mroute_update_counters(&sr
->c_oil
);
5847 sr
->c_oil
.cc
.origpktcnt
= sr
->c_oil
.cc
.pktcnt
;
5848 sr
->c_oil
.cc
.origbytecnt
= sr
->c_oil
.cc
.bytecnt
;
5849 sr
->c_oil
.cc
.origwrong_if
= sr
->c_oil
.cc
.wrong_if
;
5854 static void show_mroute_count(struct pim_instance
*pim
, struct vty
*vty
)
5856 struct listnode
*node
;
5857 struct channel_oil
*c_oil
;
5858 struct static_route
*sr
;
5863 "Source Group LastUsed Packets Bytes WrongIf \n");
5865 /* Print PIM and IGMP route counts */
5866 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
5867 char group_str
[INET_ADDRSTRLEN
];
5868 char source_str
[INET_ADDRSTRLEN
];
5870 if (!c_oil
->installed
)
5873 pim_mroute_update_counters(c_oil
);
5875 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, group_str
,
5877 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, source_str
,
5878 sizeof(source_str
));
5880 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
5881 source_str
, group_str
, c_oil
->cc
.lastused
/ 100,
5882 c_oil
->cc
.pktcnt
- c_oil
->cc
.origpktcnt
,
5883 c_oil
->cc
.bytecnt
- c_oil
->cc
.origbytecnt
,
5884 c_oil
->cc
.wrong_if
- c_oil
->cc
.origwrong_if
);
5887 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, sr
)) {
5888 char group_str
[INET_ADDRSTRLEN
];
5889 char source_str
[INET_ADDRSTRLEN
];
5891 if (!sr
->c_oil
.installed
)
5894 pim_mroute_update_counters(&sr
->c_oil
);
5896 pim_inet4_dump("<group?>", sr
->c_oil
.oil
.mfcc_mcastgrp
,
5897 group_str
, sizeof(group_str
));
5898 pim_inet4_dump("<source?>", sr
->c_oil
.oil
.mfcc_origin
,
5899 source_str
, sizeof(source_str
));
5901 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
5902 source_str
, group_str
, sr
->c_oil
.cc
.lastused
,
5903 sr
->c_oil
.cc
.pktcnt
- sr
->c_oil
.cc
.origpktcnt
,
5904 sr
->c_oil
.cc
.bytecnt
- sr
->c_oil
.cc
.origbytecnt
,
5905 sr
->c_oil
.cc
.wrong_if
- sr
->c_oil
.cc
.origwrong_if
);
5909 DEFUN (show_ip_mroute_count
,
5910 show_ip_mroute_count_cmd
,
5911 "show ip mroute [vrf NAME] count",
5916 "Route and packet count data\n")
5919 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5924 show_mroute_count(vrf
->info
, vty
);
5928 DEFUN (show_ip_mroute_count_vrf_all
,
5929 show_ip_mroute_count_vrf_all_cmd
,
5930 "show ip mroute vrf all count",
5935 "Route and packet count data\n")
5937 bool uj
= use_json(argc
, argv
);
5943 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5947 vty_out(vty
, " \"%s\": ", vrf
->name
);
5950 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5951 show_mroute_count(vrf
->info
, vty
);
5954 vty_out(vty
, "}\n");
5959 static void show_mroute_summary(struct pim_instance
*pim
, struct vty
*vty
)
5961 struct listnode
*node
;
5962 struct channel_oil
*c_oil
;
5963 struct static_route
*s_route
;
5964 uint32_t starg_sw_mroute_cnt
= 0;
5965 uint32_t sg_sw_mroute_cnt
= 0;
5966 uint32_t starg_hw_mroute_cnt
= 0;
5967 uint32_t sg_hw_mroute_cnt
= 0;
5969 vty_out(vty
, "Mroute Type Installed/Total\n");
5971 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
5972 if (!c_oil
->installed
) {
5973 if (c_oil
->oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
5974 starg_sw_mroute_cnt
++;
5978 if (c_oil
->oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
5979 starg_hw_mroute_cnt
++;
5985 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
5986 if (!s_route
->c_oil
.installed
) {
5987 if (s_route
->c_oil
.oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
5988 starg_sw_mroute_cnt
++;
5992 if (s_route
->c_oil
.oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
5993 starg_hw_mroute_cnt
++;
5999 vty_out(vty
, "%-20s %d/%d\n", "(*, G)", starg_hw_mroute_cnt
,
6000 starg_sw_mroute_cnt
+ starg_hw_mroute_cnt
);
6001 vty_out(vty
, "%-20s %d/%d\n", "(S, G)", sg_hw_mroute_cnt
,
6002 sg_sw_mroute_cnt
+ sg_hw_mroute_cnt
);
6003 vty_out(vty
, "------\n");
6004 vty_out(vty
, "%-20s %d/%d\n", "Total",
6005 (starg_hw_mroute_cnt
+ sg_hw_mroute_cnt
),
6006 (starg_sw_mroute_cnt
+
6007 starg_hw_mroute_cnt
+
6012 DEFUN (show_ip_mroute_summary
,
6013 show_ip_mroute_summary_cmd
,
6014 "show ip mroute [vrf NAME] summary",
6019 "Summary of all mroutes\n")
6022 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6027 show_mroute_summary(vrf
->info
, vty
);
6031 DEFUN (show_ip_mroute_summary_vrf_all
,
6032 show_ip_mroute_summary_vrf_all_cmd
,
6033 "show ip mroute vrf all summary",
6038 "Summary of all mroutes\n")
6042 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
6043 vty_out(vty
, "VRF: %s\n", vrf
->name
);
6044 show_mroute_summary(vrf
->info
, vty
);
6052 "show ip rib [vrf NAME] A.B.C.D",
6057 "Unicast address\n")
6060 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6061 struct in_addr addr
;
6062 const char *addr_str
;
6063 struct pim_nexthop nexthop
;
6064 char nexthop_addr_str
[PREFIX_STRLEN
];
6070 memset(&nexthop
, 0, sizeof(nexthop
));
6071 argv_find(argv
, argc
, "A.B.C.D", &idx
);
6072 addr_str
= argv
[idx
]->arg
;
6073 result
= inet_pton(AF_INET
, addr_str
, &addr
);
6075 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
6076 errno
, safe_strerror(errno
));
6080 if (!pim_nexthop_lookup(vrf
->info
, &nexthop
, addr
, 0)) {
6082 "Failure querying RIB nexthop for unicast address %s\n",
6088 "Address NextHop Interface Metric Preference\n");
6090 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
6091 nexthop_addr_str
, sizeof(nexthop_addr_str
));
6093 vty_out(vty
, "%-15s %-15s %-9s %6d %10d\n", addr_str
, nexthop_addr_str
,
6094 nexthop
.interface
? nexthop
.interface
->name
: "<ifname?>",
6095 nexthop
.mrib_route_metric
, nexthop
.mrib_metric_preference
);
6100 static void show_ssmpingd(struct pim_instance
*pim
, struct vty
*vty
)
6102 struct listnode
*node
;
6103 struct ssmpingd_sock
*ss
;
6107 "Source Socket Address Port Uptime Requests\n");
6109 if (!pim
->ssmpingd_list
)
6112 now
= pim_time_monotonic_sec();
6114 for (ALL_LIST_ELEMENTS_RO(pim
->ssmpingd_list
, node
, ss
)) {
6115 char source_str
[INET_ADDRSTRLEN
];
6117 struct sockaddr_in bind_addr
;
6118 socklen_t len
= sizeof(bind_addr
);
6119 char bind_addr_str
[INET_ADDRSTRLEN
];
6121 pim_inet4_dump("<src?>", ss
->source_addr
, source_str
,
6122 sizeof(source_str
));
6124 if (pim_socket_getsockname(
6125 ss
->sock_fd
, (struct sockaddr
*)&bind_addr
, &len
)) {
6127 "%% Failure reading socket name for ssmpingd source %s on fd=%d\n",
6128 source_str
, ss
->sock_fd
);
6131 pim_inet4_dump("<addr?>", bind_addr
.sin_addr
, bind_addr_str
,
6132 sizeof(bind_addr_str
));
6133 pim_time_uptime(ss_uptime
, sizeof(ss_uptime
),
6134 now
- ss
->creation
);
6136 vty_out(vty
, "%-15s %6d %-15s %5d %8s %8lld\n", source_str
,
6137 ss
->sock_fd
, bind_addr_str
, ntohs(bind_addr
.sin_port
),
6138 ss_uptime
, (long long)ss
->requests
);
6142 DEFUN (show_ip_ssmpingd
,
6143 show_ip_ssmpingd_cmd
,
6144 "show ip ssmpingd [vrf NAME]",
6151 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6156 show_ssmpingd(vrf
->info
, vty
);
6160 static int pim_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
6161 const char *rp
, const char *group
,
6166 result
= pim_rp_new_config(pim
, rp
, group
, plist
);
6168 if (result
== PIM_GROUP_BAD_ADDR_MASK_COMBO
) {
6169 vty_out(vty
, "%% Inconsistent address and mask: %s\n",
6171 return CMD_WARNING_CONFIG_FAILED
;
6174 if (result
== PIM_GROUP_BAD_ADDRESS
) {
6175 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
6176 return CMD_WARNING_CONFIG_FAILED
;
6179 if (result
== PIM_RP_BAD_ADDRESS
) {
6180 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
6181 return CMD_WARNING_CONFIG_FAILED
;
6184 if (result
== PIM_RP_NO_PATH
) {
6185 vty_out(vty
, "%% No Path to RP address specified: %s\n", rp
);
6189 if (result
== PIM_GROUP_OVERLAP
) {
6191 "%% Group range specified cannot exact match another\n");
6192 return CMD_WARNING_CONFIG_FAILED
;
6195 if (result
== PIM_GROUP_PFXLIST_OVERLAP
) {
6197 "%% This group is already covered by a RP prefix-list\n");
6198 return CMD_WARNING_CONFIG_FAILED
;
6201 if (result
== PIM_RP_PFXLIST_IN_USE
) {
6203 "%% The same prefix-list cannot be applied to multiple RPs\n");
6204 return CMD_WARNING_CONFIG_FAILED
;
6210 static int pim_cmd_spt_switchover(struct pim_instance
*pim
,
6211 enum pim_spt_switchover spt
,
6214 pim
->spt
.switchover
= spt
;
6216 switch (pim
->spt
.switchover
) {
6217 case PIM_SPT_IMMEDIATE
:
6218 XFREE(MTYPE_PIM_SPT_PLIST_NAME
, pim
->spt
.plist
);
6220 pim_upstream_add_lhr_star_pimreg(pim
);
6222 case PIM_SPT_INFINITY
:
6223 pim_upstream_remove_lhr_star_pimreg(pim
, plist
);
6225 XFREE(MTYPE_PIM_SPT_PLIST_NAME
, pim
->spt
.plist
);
6229 XSTRDUP(MTYPE_PIM_SPT_PLIST_NAME
, plist
);
6236 DEFUN (ip_pim_spt_switchover_infinity
,
6237 ip_pim_spt_switchover_infinity_cmd
,
6238 "ip pim spt-switchover infinity-and-beyond",
6242 "Never switch to SPT Tree\n")
6244 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6245 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, NULL
);
6248 DEFUN (ip_pim_spt_switchover_infinity_plist
,
6249 ip_pim_spt_switchover_infinity_plist_cmd
,
6250 "ip pim spt-switchover infinity-and-beyond prefix-list WORD",
6254 "Never switch to SPT Tree\n"
6255 "Prefix-List to control which groups to switch\n"
6256 "Prefix-List name\n")
6258 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6259 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, argv
[5]->arg
);
6262 DEFUN (no_ip_pim_spt_switchover_infinity
,
6263 no_ip_pim_spt_switchover_infinity_cmd
,
6264 "no ip pim spt-switchover infinity-and-beyond",
6269 "Never switch to SPT Tree\n")
6271 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6272 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
6275 DEFUN (no_ip_pim_spt_switchover_infinity_plist
,
6276 no_ip_pim_spt_switchover_infinity_plist_cmd
,
6277 "no ip pim spt-switchover infinity-and-beyond prefix-list WORD",
6282 "Never switch to SPT Tree\n"
6283 "Prefix-List to control which groups to switch\n"
6284 "Prefix-List name\n")
6286 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6287 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
6290 DEFUN (ip_pim_joinprune_time
,
6291 ip_pim_joinprune_time_cmd
,
6292 "ip pim join-prune-interval (60-600)",
6294 "pim multicast routing\n"
6295 "Join Prune Send Interval\n"
6298 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6299 router
->t_periodic
= atoi(argv
[3]->arg
);
6303 DEFUN (no_ip_pim_joinprune_time
,
6304 no_ip_pim_joinprune_time_cmd
,
6305 "no ip pim join-prune-interval (60-600)",
6308 "pim multicast routing\n"
6309 "Join Prune Send Interval\n"
6312 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6313 router
->t_periodic
= PIM_DEFAULT_T_PERIODIC
;
6317 DEFUN (ip_pim_register_suppress
,
6318 ip_pim_register_suppress_cmd
,
6319 "ip pim register-suppress-time (5-60000)",
6321 "pim multicast routing\n"
6322 "Register Suppress Timer\n"
6325 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6326 router
->register_suppress_time
= atoi(argv
[3]->arg
);
6330 DEFUN (no_ip_pim_register_suppress
,
6331 no_ip_pim_register_suppress_cmd
,
6332 "no ip pim register-suppress-time (5-60000)",
6335 "pim multicast routing\n"
6336 "Register Suppress Timer\n"
6339 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6340 router
->register_suppress_time
= PIM_REGISTER_SUPPRESSION_TIME_DEFAULT
;
6344 DEFUN (ip_pim_rp_keep_alive
,
6345 ip_pim_rp_keep_alive_cmd
,
6346 "ip pim rp keep-alive-timer (31-60000)",
6348 "pim multicast routing\n"
6350 "Keep alive Timer\n"
6353 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6354 pim
->rp_keep_alive_time
= atoi(argv
[4]->arg
);
6358 DEFUN (no_ip_pim_rp_keep_alive
,
6359 no_ip_pim_rp_keep_alive_cmd
,
6360 "no ip pim rp keep-alive-timer (31-60000)",
6363 "pim multicast routing\n"
6365 "Keep alive Timer\n"
6368 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6369 pim
->rp_keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
6373 DEFUN (ip_pim_keep_alive
,
6374 ip_pim_keep_alive_cmd
,
6375 "ip pim keep-alive-timer (31-60000)",
6377 "pim multicast routing\n"
6378 "Keep alive Timer\n"
6381 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6382 pim
->keep_alive_time
= atoi(argv
[3]->arg
);
6386 DEFUN (no_ip_pim_keep_alive
,
6387 no_ip_pim_keep_alive_cmd
,
6388 "no ip pim keep-alive-timer (31-60000)",
6391 "pim multicast routing\n"
6392 "Keep alive Timer\n"
6395 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6396 pim
->keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
6400 DEFUN (ip_pim_packets
,
6402 "ip pim packets (1-100)",
6404 "pim multicast routing\n"
6405 "packets to process at one time per fd\n"
6406 "Number of packets\n")
6408 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6409 router
->packet_process
= atoi(argv
[3]->arg
);
6413 DEFUN (no_ip_pim_packets
,
6414 no_ip_pim_packets_cmd
,
6415 "no ip pim packets (1-100)",
6418 "pim multicast routing\n"
6419 "packets to process at one time per fd\n"
6420 "Number of packets\n")
6422 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6423 router
->packet_process
= PIM_DEFAULT_PACKET_PROCESS
;
6427 DEFUN (ip_pim_v6_secondary
,
6428 ip_pim_v6_secondary_cmd
,
6429 "ip pim send-v6-secondary",
6431 "pim multicast routing\n"
6432 "Send v6 secondary addresses\n")
6434 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6435 pim
->send_v6_secondary
= 1;
6440 DEFUN (no_ip_pim_v6_secondary
,
6441 no_ip_pim_v6_secondary_cmd
,
6442 "no ip pim send-v6-secondary",
6445 "pim multicast routing\n"
6446 "Send v6 secondary addresses\n")
6448 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6449 pim
->send_v6_secondary
= 0;
6456 "ip pim rp A.B.C.D [A.B.C.D/M]",
6458 "pim multicast routing\n"
6460 "ip address of RP\n"
6461 "Group Address range to cover\n")
6463 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6466 if (argc
== (idx_ipv4
+ 1))
6467 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
6470 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
6471 argv
[idx_ipv4
+ 1]->arg
, NULL
);
6474 DEFUN (ip_pim_rp_prefix_list
,
6475 ip_pim_rp_prefix_list_cmd
,
6476 "ip pim rp A.B.C.D prefix-list WORD",
6478 "pim multicast routing\n"
6480 "ip address of RP\n"
6481 "group prefix-list filter\n"
6482 "Name of a prefix-list\n")
6484 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6485 return pim_rp_cmd_worker(pim
, vty
, argv
[3]->arg
, NULL
, argv
[5]->arg
);
6488 static int pim_no_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
6489 const char *rp
, const char *group
,
6492 int result
= pim_rp_del_config(pim
, rp
, group
, plist
);
6494 if (result
== PIM_GROUP_BAD_ADDRESS
) {
6495 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
6496 return CMD_WARNING_CONFIG_FAILED
;
6499 if (result
== PIM_RP_BAD_ADDRESS
) {
6500 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
6501 return CMD_WARNING_CONFIG_FAILED
;
6504 if (result
== PIM_RP_NOT_FOUND
) {
6505 vty_out(vty
, "%% Unable to find specified RP\n");
6506 return CMD_WARNING_CONFIG_FAILED
;
6512 DEFUN (no_ip_pim_rp
,
6514 "no ip pim rp A.B.C.D [A.B.C.D/M]",
6517 "pim multicast routing\n"
6519 "ip address of RP\n"
6520 "Group Address range to cover\n")
6522 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6523 int idx_ipv4
= 4, idx_group
= 0;
6525 if (argv_find(argv
, argc
, "A.B.C.D/M", &idx_group
))
6526 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
6527 argv
[idx_group
]->arg
, NULL
);
6529 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
6533 DEFUN (no_ip_pim_rp_prefix_list
,
6534 no_ip_pim_rp_prefix_list_cmd
,
6535 "no ip pim rp A.B.C.D prefix-list WORD",
6538 "pim multicast routing\n"
6540 "ip address of RP\n"
6541 "group prefix-list filter\n"
6542 "Name of a prefix-list\n")
6544 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6545 return pim_no_rp_cmd_worker(pim
, vty
, argv
[4]->arg
, NULL
, argv
[6]->arg
);
6548 static int pim_ssm_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
6551 int result
= pim_ssm_range_set(pim
, pim
->vrf_id
, plist
);
6552 int ret
= CMD_WARNING_CONFIG_FAILED
;
6554 if (result
== PIM_SSM_ERR_NONE
)
6558 case PIM_SSM_ERR_NO_VRF
:
6559 vty_out(vty
, "%% VRF doesn't exist\n");
6561 case PIM_SSM_ERR_DUP
:
6562 vty_out(vty
, "%% duplicate config\n");
6566 vty_out(vty
, "%% ssm range config failed\n");
6572 DEFUN (ip_pim_ssm_prefix_list
,
6573 ip_pim_ssm_prefix_list_cmd
,
6574 "ip pim ssm prefix-list WORD",
6576 "pim multicast routing\n"
6577 "Source Specific Multicast\n"
6578 "group range prefix-list filter\n"
6579 "Name of a prefix-list\n")
6581 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6582 return pim_ssm_cmd_worker(pim
, vty
, argv
[4]->arg
);
6585 DEFUN (no_ip_pim_ssm_prefix_list
,
6586 no_ip_pim_ssm_prefix_list_cmd
,
6587 "no ip pim ssm prefix-list",
6590 "pim multicast routing\n"
6591 "Source Specific Multicast\n"
6592 "group range prefix-list filter\n")
6594 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6595 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
6598 DEFUN (no_ip_pim_ssm_prefix_list_name
,
6599 no_ip_pim_ssm_prefix_list_name_cmd
,
6600 "no ip pim ssm prefix-list WORD",
6603 "pim multicast routing\n"
6604 "Source Specific Multicast\n"
6605 "group range prefix-list filter\n"
6606 "Name of a prefix-list\n")
6608 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6609 struct pim_ssm
*ssm
= pim
->ssm_info
;
6611 if (ssm
->plist_name
&& !strcmp(ssm
->plist_name
, argv
[5]->arg
))
6612 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
6614 vty_out(vty
, "%% pim ssm prefix-list %s doesn't exist\n", argv
[5]->arg
);
6616 return CMD_WARNING_CONFIG_FAILED
;
6619 static void ip_pim_ssm_show_group_range(struct pim_instance
*pim
,
6620 struct vty
*vty
, bool uj
)
6622 struct pim_ssm
*ssm
= pim
->ssm_info
;
6623 const char *range_str
=
6624 ssm
->plist_name
? ssm
->plist_name
: PIM_SSM_STANDARD_RANGE
;
6628 json
= json_object_new_object();
6629 json_object_string_add(json
, "ssmGroups", range_str
);
6630 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
6631 json
, JSON_C_TO_STRING_PRETTY
));
6632 json_object_free(json
);
6634 vty_out(vty
, "SSM group range : %s\n", range_str
);
6637 DEFUN (show_ip_pim_ssm_range
,
6638 show_ip_pim_ssm_range_cmd
,
6639 "show ip pim [vrf NAME] group-type [json]",
6648 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6649 bool uj
= use_json(argc
, argv
);
6654 ip_pim_ssm_show_group_range(vrf
->info
, vty
, uj
);
6659 static void ip_pim_ssm_show_group_type(struct pim_instance
*pim
,
6660 struct vty
*vty
, bool uj
,
6663 struct in_addr group_addr
;
6664 const char *type_str
;
6667 result
= inet_pton(AF_INET
, group
, &group_addr
);
6669 type_str
= "invalid";
6671 if (pim_is_group_224_4(group_addr
))
6673 pim_is_grp_ssm(pim
, group_addr
) ? "SSM" : "ASM";
6675 type_str
= "not-multicast";
6680 json
= json_object_new_object();
6681 json_object_string_add(json
, "groupType", type_str
);
6682 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
6683 json
, JSON_C_TO_STRING_PRETTY
));
6684 json_object_free(json
);
6686 vty_out(vty
, "Group type : %s\n", type_str
);
6689 DEFUN (show_ip_pim_group_type
,
6690 show_ip_pim_group_type_cmd
,
6691 "show ip pim [vrf NAME] group-type A.B.C.D [json]",
6696 "multicast group type\n"
6701 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6702 bool uj
= use_json(argc
, argv
);
6707 argv_find(argv
, argc
, "A.B.C.D", &idx
);
6708 ip_pim_ssm_show_group_type(vrf
->info
, vty
, uj
, argv
[idx
]->arg
);
6713 DEFUN (show_ip_pim_bsr
,
6714 show_ip_pim_bsr_cmd
,
6715 "show ip pim bsr [json]",
6719 "boot-strap router information\n"
6723 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6724 bool uj
= use_json(argc
, argv
);
6729 pim_show_bsr(vrf
->info
, vty
, uj
);
6736 "ip ssmpingd [A.B.C.D]",
6741 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6744 struct in_addr source_addr
;
6745 const char *source_str
= (argc
== 3) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
6747 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
6749 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
6750 source_str
, errno
, safe_strerror(errno
));
6751 return CMD_WARNING_CONFIG_FAILED
;
6754 result
= pim_ssmpingd_start(pim
, source_addr
);
6756 vty_out(vty
, "%% Failure starting ssmpingd for source %s: %d\n",
6757 source_str
, result
);
6758 return CMD_WARNING_CONFIG_FAILED
;
6764 DEFUN (no_ip_ssmpingd
,
6766 "no ip ssmpingd [A.B.C.D]",
6772 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6775 struct in_addr source_addr
;
6776 const char *source_str
= (argc
== 4) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
6778 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
6780 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
6781 source_str
, errno
, safe_strerror(errno
));
6782 return CMD_WARNING_CONFIG_FAILED
;
6785 result
= pim_ssmpingd_stop(pim
, source_addr
);
6787 vty_out(vty
, "%% Failure stopping ssmpingd for source %s: %d\n",
6788 source_str
, result
);
6789 return CMD_WARNING_CONFIG_FAILED
;
6799 "pim multicast routing\n"
6800 "Enable PIM ECMP \n")
6802 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6803 pim
->ecmp_enable
= true;
6808 DEFUN (no_ip_pim_ecmp
,
6813 "pim multicast routing\n"
6814 "Disable PIM ECMP \n")
6816 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6817 pim
->ecmp_enable
= false;
6822 DEFUN (ip_pim_ecmp_rebalance
,
6823 ip_pim_ecmp_rebalance_cmd
,
6824 "ip pim ecmp rebalance",
6826 "pim multicast routing\n"
6827 "Enable PIM ECMP \n"
6828 "Enable PIM ECMP Rebalance\n")
6830 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6831 pim
->ecmp_enable
= true;
6832 pim
->ecmp_rebalance_enable
= true;
6837 DEFUN (no_ip_pim_ecmp_rebalance
,
6838 no_ip_pim_ecmp_rebalance_cmd
,
6839 "no ip pim ecmp rebalance",
6842 "pim multicast routing\n"
6843 "Disable PIM ECMP \n"
6844 "Disable PIM ECMP Rebalance\n")
6846 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6847 pim
->ecmp_rebalance_enable
= false;
6852 static int pim_cmd_igmp_start(struct vty
*vty
, struct interface
*ifp
)
6854 struct pim_interface
*pim_ifp
;
6855 uint8_t need_startup
= 0;
6857 pim_ifp
= ifp
->info
;
6860 (void)pim_if_new(ifp
, true, false, false, false);
6863 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
6864 PIM_IF_DO_IGMP(pim_ifp
->options
);
6869 /* 'ip igmp' executed multiple times, with need_startup
6870 avoid multiple if add all and membership refresh */
6872 pim_if_addr_add_all(ifp
);
6873 pim_if_membership_refresh(ifp
);
6879 DEFUN (interface_ip_igmp
,
6880 interface_ip_igmp_cmd
,
6885 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6887 return pim_cmd_igmp_start(vty
, ifp
);
6890 DEFUN (interface_no_ip_igmp
,
6891 interface_no_ip_igmp_cmd
,
6897 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6898 struct pim_interface
*pim_ifp
= ifp
->info
;
6903 PIM_IF_DONT_IGMP(pim_ifp
->options
);
6905 pim_if_membership_clear(ifp
);
6907 pim_if_addr_del_all_igmp(ifp
);
6909 if (!PIM_IF_TEST_PIM(pim_ifp
->options
)) {
6916 DEFUN (interface_ip_igmp_join
,
6917 interface_ip_igmp_join_cmd
,
6918 "ip igmp join A.B.C.D [A.B.C.D]",
6921 "IGMP join multicast group\n"
6922 "Multicast group address\n"
6925 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6928 const char *group_str
;
6929 const char *source_str
;
6930 struct in_addr group_addr
;
6931 struct in_addr source_addr
;
6935 group_str
= argv
[idx_ipv4
]->arg
;
6936 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
6938 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
6939 errno
, safe_strerror(errno
));
6940 return CMD_WARNING_CONFIG_FAILED
;
6943 /* Source address */
6944 if (argc
== (idx_ipv4_2
+ 1)) {
6945 source_str
= argv
[idx_ipv4_2
]->arg
;
6946 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
6948 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
6949 source_str
, errno
, safe_strerror(errno
));
6950 return CMD_WARNING_CONFIG_FAILED
;
6952 /* Reject 0.0.0.0. Reserved for any source. */
6953 if (source_addr
.s_addr
== INADDR_ANY
) {
6954 vty_out(vty
, "Bad source address %s\n", source_str
);
6955 return CMD_WARNING_CONFIG_FAILED
;
6958 source_addr
.s_addr
= INADDR_ANY
;
6961 CMD_FERR_RETURN(pim_if_igmp_join_add(ifp
, group_addr
, source_addr
),
6962 "Failure joining IGMP group: $ERR");
6967 DEFUN (interface_no_ip_igmp_join
,
6968 interface_no_ip_igmp_join_cmd
,
6969 "no ip igmp join A.B.C.D [A.B.C.D]",
6973 "IGMP join multicast group\n"
6974 "Multicast group address\n"
6977 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6980 const char *group_str
;
6981 const char *source_str
;
6982 struct in_addr group_addr
;
6983 struct in_addr source_addr
;
6987 group_str
= argv
[idx_ipv4
]->arg
;
6988 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
6990 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
6991 errno
, safe_strerror(errno
));
6992 return CMD_WARNING_CONFIG_FAILED
;
6995 /* Source address */
6996 if (argc
== (idx_ipv4_2
+ 1)) {
6997 source_str
= argv
[idx_ipv4_2
]->arg
;
6998 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
7000 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
7001 source_str
, errno
, safe_strerror(errno
));
7002 return CMD_WARNING_CONFIG_FAILED
;
7004 /* Reject 0.0.0.0. Reserved for any source. */
7005 if (source_addr
.s_addr
== INADDR_ANY
) {
7006 vty_out(vty
, "Bad source address %s\n", source_str
);
7007 return CMD_WARNING_CONFIG_FAILED
;
7011 source_addr
.s_addr
= INADDR_ANY
;
7014 result
= pim_if_igmp_join_del(ifp
, group_addr
, source_addr
);
7017 "%% Failure leaving IGMP group %s source %s on interface %s: %d\n",
7018 group_str
, source_str
, ifp
->name
, result
);
7019 return CMD_WARNING_CONFIG_FAILED
;
7026 CLI reconfiguration affects the interface level (struct pim_interface).
7027 This function propagates the reconfiguration to every active socket
7030 static void igmp_sock_query_interval_reconfig(struct igmp_sock
*igmp
)
7032 struct interface
*ifp
;
7033 struct pim_interface
*pim_ifp
;
7037 /* other querier present? */
7039 if (igmp
->t_other_querier_timer
)
7042 /* this is the querier */
7044 zassert(igmp
->interface
);
7045 zassert(igmp
->interface
->info
);
7047 ifp
= igmp
->interface
;
7048 pim_ifp
= ifp
->info
;
7050 if (PIM_DEBUG_IGMP_TRACE
) {
7051 char ifaddr_str
[INET_ADDRSTRLEN
];
7052 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
7053 sizeof(ifaddr_str
));
7054 zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
7055 __PRETTY_FUNCTION__
, ifaddr_str
, ifp
->name
,
7056 pim_ifp
->igmp_default_query_interval
);
7060 igmp_startup_mode_on() will reset QQI:
7062 igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
7064 igmp_startup_mode_on(igmp
);
7067 static void igmp_sock_query_reschedule(struct igmp_sock
*igmp
)
7069 if (igmp
->t_igmp_query_timer
) {
7070 /* other querier present */
7071 zassert(igmp
->t_igmp_query_timer
);
7072 zassert(!igmp
->t_other_querier_timer
);
7074 pim_igmp_general_query_off(igmp
);
7075 pim_igmp_general_query_on(igmp
);
7077 zassert(igmp
->t_igmp_query_timer
);
7078 zassert(!igmp
->t_other_querier_timer
);
7080 /* this is the querier */
7082 zassert(!igmp
->t_igmp_query_timer
);
7083 zassert(igmp
->t_other_querier_timer
);
7085 pim_igmp_other_querier_timer_off(igmp
);
7086 pim_igmp_other_querier_timer_on(igmp
);
7088 zassert(!igmp
->t_igmp_query_timer
);
7089 zassert(igmp
->t_other_querier_timer
);
7093 static void change_query_interval(struct pim_interface
*pim_ifp
,
7096 struct listnode
*sock_node
;
7097 struct igmp_sock
*igmp
;
7099 pim_ifp
->igmp_default_query_interval
= query_interval
;
7101 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
7102 igmp_sock_query_interval_reconfig(igmp
);
7103 igmp_sock_query_reschedule(igmp
);
7107 static void change_query_max_response_time(struct pim_interface
*pim_ifp
,
7108 int query_max_response_time_dsec
)
7110 struct listnode
*sock_node
;
7111 struct igmp_sock
*igmp
;
7113 pim_ifp
->igmp_query_max_response_time_dsec
=
7114 query_max_response_time_dsec
;
7117 Below we modify socket/group/source timers in order to quickly
7118 reflect the change. Otherwise, those timers would eventually catch
7122 /* scan all sockets */
7123 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
7124 struct listnode
*grp_node
;
7125 struct igmp_group
*grp
;
7127 /* reschedule socket general query */
7128 igmp_sock_query_reschedule(igmp
);
7130 /* scan socket groups */
7131 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grp_node
,
7133 struct listnode
*src_node
;
7134 struct igmp_source
*src
;
7136 /* reset group timers for groups in EXCLUDE mode */
7137 if (grp
->group_filtermode_isexcl
) {
7138 igmp_group_reset_gmi(grp
);
7141 /* scan group sources */
7142 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
,
7145 /* reset source timers for sources with running
7147 if (src
->t_source_timer
) {
7148 igmp_source_reset_gmi(igmp
, grp
, src
);
7155 #define IGMP_QUERY_INTERVAL_MIN (1)
7156 #define IGMP_QUERY_INTERVAL_MAX (1800)
7158 DEFUN (interface_ip_igmp_query_interval
,
7159 interface_ip_igmp_query_interval_cmd
,
7160 "ip igmp query-interval (1-1800)",
7163 IFACE_IGMP_QUERY_INTERVAL_STR
7164 "Query interval in seconds\n")
7166 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7167 struct pim_interface
*pim_ifp
= ifp
->info
;
7169 int query_interval_dsec
;
7173 ret
= pim_cmd_igmp_start(vty
, ifp
);
7174 if (ret
!= CMD_SUCCESS
)
7176 pim_ifp
= ifp
->info
;
7179 query_interval
= atoi(argv
[3]->arg
);
7180 query_interval_dsec
= 10 * query_interval
;
7183 It seems we don't need to check bounds since command.c does it
7184 already, but we verify them anyway for extra safety.
7186 if (query_interval
< IGMP_QUERY_INTERVAL_MIN
) {
7188 "General query interval %d lower than minimum %d\n",
7189 query_interval
, IGMP_QUERY_INTERVAL_MIN
);
7190 return CMD_WARNING_CONFIG_FAILED
;
7192 if (query_interval
> IGMP_QUERY_INTERVAL_MAX
) {
7194 "General query interval %d higher than maximum %d\n",
7195 query_interval
, IGMP_QUERY_INTERVAL_MAX
);
7196 return CMD_WARNING_CONFIG_FAILED
;
7199 if (query_interval_dsec
<= pim_ifp
->igmp_query_max_response_time_dsec
) {
7201 "Can't set general query interval %d dsec <= query max response time %d dsec.\n",
7202 query_interval_dsec
,
7203 pim_ifp
->igmp_query_max_response_time_dsec
);
7204 return CMD_WARNING_CONFIG_FAILED
;
7207 change_query_interval(pim_ifp
, query_interval
);
7212 DEFUN (interface_no_ip_igmp_query_interval
,
7213 interface_no_ip_igmp_query_interval_cmd
,
7214 "no ip igmp query-interval",
7218 IFACE_IGMP_QUERY_INTERVAL_STR
)
7220 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7221 struct pim_interface
*pim_ifp
= ifp
->info
;
7222 int default_query_interval_dsec
;
7227 default_query_interval_dsec
= IGMP_GENERAL_QUERY_INTERVAL
* 10;
7229 if (default_query_interval_dsec
7230 <= pim_ifp
->igmp_query_max_response_time_dsec
) {
7232 "Can't set default general query interval %d dsec <= query max response time %d dsec.\n",
7233 default_query_interval_dsec
,
7234 pim_ifp
->igmp_query_max_response_time_dsec
);
7235 return CMD_WARNING_CONFIG_FAILED
;
7238 change_query_interval(pim_ifp
, IGMP_GENERAL_QUERY_INTERVAL
);
7243 DEFUN (interface_ip_igmp_version
,
7244 interface_ip_igmp_version_cmd
,
7245 "ip igmp version (2-3)",
7249 "IGMP version number\n")
7251 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7252 struct pim_interface
*pim_ifp
= ifp
->info
;
7253 int igmp_version
, old_version
= 0;
7257 ret
= pim_cmd_igmp_start(vty
, ifp
);
7258 if (ret
!= CMD_SUCCESS
)
7260 pim_ifp
= ifp
->info
;
7263 igmp_version
= atoi(argv
[3]->arg
);
7264 old_version
= pim_ifp
->igmp_version
;
7265 pim_ifp
->igmp_version
= igmp_version
;
7267 // Check if IGMP is Enabled otherwise, enable on interface
7268 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
7269 PIM_IF_DO_IGMP(pim_ifp
->options
);
7270 pim_if_addr_add_all(ifp
);
7271 pim_if_membership_refresh(ifp
);
7272 old_version
= igmp_version
;
7273 // avoid refreshing membership again.
7275 /* Current and new version is different refresh existing
7276 membership. Going from 3 -> 2 or 2 -> 3. */
7277 if (old_version
!= igmp_version
)
7278 pim_if_membership_refresh(ifp
);
7283 DEFUN (interface_no_ip_igmp_version
,
7284 interface_no_ip_igmp_version_cmd
,
7285 "no ip igmp version (2-3)",
7290 "IGMP version number\n")
7292 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7293 struct pim_interface
*pim_ifp
= ifp
->info
;
7298 pim_ifp
->igmp_version
= IGMP_DEFAULT_VERSION
;
7303 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
7304 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
7306 DEFUN (interface_ip_igmp_query_max_response_time
,
7307 interface_ip_igmp_query_max_response_time_cmd
,
7308 "ip igmp query-max-response-time (10-250)",
7311 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
7312 "Query response value in deci-seconds\n")
7314 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7315 struct pim_interface
*pim_ifp
= ifp
->info
;
7316 int query_max_response_time
;
7320 ret
= pim_cmd_igmp_start(vty
, ifp
);
7321 if (ret
!= CMD_SUCCESS
)
7323 pim_ifp
= ifp
->info
;
7326 query_max_response_time
= atoi(argv
[3]->arg
);
7328 if (query_max_response_time
7329 >= pim_ifp
->igmp_default_query_interval
* 10) {
7331 "Can't set query max response time %d sec >= general query interval %d sec\n",
7332 query_max_response_time
,
7333 pim_ifp
->igmp_default_query_interval
);
7334 return CMD_WARNING_CONFIG_FAILED
;
7337 change_query_max_response_time(pim_ifp
, query_max_response_time
);
7342 DEFUN (interface_no_ip_igmp_query_max_response_time
,
7343 interface_no_ip_igmp_query_max_response_time_cmd
,
7344 "no ip igmp query-max-response-time (10-250)",
7348 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
7349 "Time for response in deci-seconds\n")
7351 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7352 struct pim_interface
*pim_ifp
= ifp
->info
;
7357 change_query_max_response_time(pim_ifp
,
7358 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
7363 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
7364 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
7366 DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec
,
7367 interface_ip_igmp_query_max_response_time_dsec_cmd
,
7368 "ip igmp query-max-response-time-dsec (10-250)",
7371 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
7372 "Query response value in deciseconds\n")
7374 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7375 struct pim_interface
*pim_ifp
= ifp
->info
;
7376 int query_max_response_time_dsec
;
7377 int default_query_interval_dsec
;
7381 ret
= pim_cmd_igmp_start(vty
, ifp
);
7382 if (ret
!= CMD_SUCCESS
)
7384 pim_ifp
= ifp
->info
;
7387 query_max_response_time_dsec
= atoi(argv
[4]->arg
);
7389 default_query_interval_dsec
= 10 * pim_ifp
->igmp_default_query_interval
;
7391 if (query_max_response_time_dsec
>= default_query_interval_dsec
) {
7393 "Can't set query max response time %d dsec >= general query interval %d dsec\n",
7394 query_max_response_time_dsec
,
7395 default_query_interval_dsec
);
7396 return CMD_WARNING_CONFIG_FAILED
;
7399 change_query_max_response_time(pim_ifp
, query_max_response_time_dsec
);
7404 DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec
,
7405 interface_no_ip_igmp_query_max_response_time_dsec_cmd
,
7406 "no ip igmp query-max-response-time-dsec",
7410 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
)
7412 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7413 struct pim_interface
*pim_ifp
= ifp
->info
;
7418 change_query_max_response_time(pim_ifp
,
7419 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
7424 #define IGMP_LAST_MEMBER_QUERY_COUNT_MIN (1)
7425 #define IGMP_LAST_MEMBER_QUERY_COUNT_MAX (7)
7427 DEFUN (interface_ip_igmp_last_member_query_count
,
7428 interface_ip_igmp_last_member_query_count_cmd
,
7429 "ip igmp last-member-query-count (1-7)",
7432 IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR
7433 "Last member query count\n")
7435 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7436 struct pim_interface
*pim_ifp
= ifp
->info
;
7437 int last_member_query_count
;
7441 ret
= pim_cmd_igmp_start(vty
, ifp
);
7442 if (ret
!= CMD_SUCCESS
)
7444 pim_ifp
= ifp
->info
;
7447 last_member_query_count
= atoi(argv
[3]->arg
);
7449 pim_ifp
->igmp_last_member_query_count
= last_member_query_count
;
7454 DEFUN (interface_no_ip_igmp_last_member_query_count
,
7455 interface_no_ip_igmp_last_member_query_count_cmd
,
7456 "no ip igmp last-member-query-count",
7460 IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR
)
7462 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7463 struct pim_interface
*pim_ifp
= ifp
->info
;
7468 pim_ifp
->igmp_last_member_query_count
=
7469 IGMP_DEFAULT_ROBUSTNESS_VARIABLE
;
7474 #define IGMP_LAST_MEMBER_QUERY_INTERVAL_MIN (1)
7475 #define IGMP_LAST_MEMBER_QUERY_INTERVAL_MAX (255)
7477 DEFUN (interface_ip_igmp_last_member_query_interval
,
7478 interface_ip_igmp_last_member_query_interval_cmd
,
7479 "ip igmp last-member-query-interval (1-255)",
7482 IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR
7483 "Last member query interval in deciseconds\n")
7485 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7486 struct pim_interface
*pim_ifp
= ifp
->info
;
7487 int last_member_query_interval
;
7491 ret
= pim_cmd_igmp_start(vty
, ifp
);
7492 if (ret
!= CMD_SUCCESS
)
7494 pim_ifp
= ifp
->info
;
7497 last_member_query_interval
= atoi(argv
[3]->arg
);
7498 pim_ifp
->igmp_specific_query_max_response_time_dsec
7499 = last_member_query_interval
;
7504 DEFUN (interface_no_ip_igmp_last_member_query_interval
,
7505 interface_no_ip_igmp_last_member_query_interval_cmd
,
7506 "no ip igmp last-member-query-interval",
7510 IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR
)
7512 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7513 struct pim_interface
*pim_ifp
= ifp
->info
;
7518 pim_ifp
->igmp_specific_query_max_response_time_dsec
=
7519 IGMP_SPECIFIC_QUERY_MAX_RESPONSE_TIME_DSEC
;
7524 DEFUN (interface_ip_pim_drprio
,
7525 interface_ip_pim_drprio_cmd
,
7526 "ip pim drpriority (1-4294967295)",
7529 "Set the Designated Router Election Priority\n"
7530 "Value of the new DR Priority\n")
7532 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7534 struct pim_interface
*pim_ifp
= ifp
->info
;
7535 uint32_t old_dr_prio
;
7538 vty_out(vty
, "Please enable PIM on interface, first\n");
7539 return CMD_WARNING_CONFIG_FAILED
;
7542 old_dr_prio
= pim_ifp
->pim_dr_priority
;
7544 pim_ifp
->pim_dr_priority
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
7546 if (old_dr_prio
!= pim_ifp
->pim_dr_priority
) {
7547 pim_if_dr_election(ifp
);
7548 pim_hello_restart_now(ifp
);
7554 DEFUN (interface_no_ip_pim_drprio
,
7555 interface_no_ip_pim_drprio_cmd
,
7556 "no ip pim drpriority [(1-4294967295)]",
7560 "Revert the Designated Router Priority to default\n"
7561 "Old Value of the Priority\n")
7563 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7564 struct pim_interface
*pim_ifp
= ifp
->info
;
7567 vty_out(vty
, "Pim not enabled on this interface\n");
7568 return CMD_WARNING_CONFIG_FAILED
;
7571 if (pim_ifp
->pim_dr_priority
!= PIM_DEFAULT_DR_PRIORITY
) {
7572 pim_ifp
->pim_dr_priority
= PIM_DEFAULT_DR_PRIORITY
;
7573 pim_if_dr_election(ifp
);
7574 pim_hello_restart_now(ifp
);
7580 DEFPY_HIDDEN (interface_ip_igmp_query_generate
,
7581 interface_ip_igmp_query_generate_cmd
,
7582 "ip igmp generate-query-once [version (2-3)]",
7585 "Generate igmp general query once\n"
7587 "IGMP version number\n")
7589 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7590 int igmp_version
= 2;
7593 vty_out(vty
, "IGMP/PIM is not enabled on the interface %s\n",
7595 return CMD_WARNING_CONFIG_FAILED
;
7599 igmp_version
= atoi(argv
[4]->arg
);
7601 igmp_send_query_on_intf(ifp
, igmp_version
);
7606 static int pim_cmd_interface_add(struct interface
*ifp
)
7608 struct pim_interface
*pim_ifp
= ifp
->info
;
7611 pim_ifp
= pim_if_new(ifp
, false, true, false, false);
7613 PIM_IF_DO_PIM(pim_ifp
->options
);
7615 pim_if_addr_add_all(ifp
);
7616 pim_if_membership_refresh(ifp
);
7618 pim_if_create_pimreg(pim_ifp
->pim
);
7622 DEFPY_HIDDEN (pim_test_sg_keepalive
,
7623 pim_test_sg_keepalive_cmd
,
7624 "test pim [vrf NAME$name] keepalive-reset A.B.C.D$source A.B.C.D$group",
7628 "Reset the Keepalive Timer\n"
7629 "The Source we are resetting\n"
7630 "The Group we are resetting\n")
7632 struct pim_upstream
*up
;
7633 struct pim_instance
*pim
;
7634 struct prefix_sg sg
;
7640 pim
= pim_get_pim_instance(VRF_DEFAULT
);
7642 struct vrf
*vrf
= vrf_lookup_by_name(name
);
7645 vty_out(vty
, "%% Vrf specified: %s does not exist\n",
7650 pim
= pim_get_pim_instance(vrf
->vrf_id
);
7654 vty_out(vty
, "%% Unable to find pim instance\n");
7658 up
= pim_upstream_find(pim
, &sg
);
7660 vty_out(vty
, "%% Unable to find %s specified\n",
7661 pim_str_sg_dump(&sg
));
7665 vty_out(vty
, "Setting %s to current keep alive time: %d\n",
7666 pim_str_sg_dump(&sg
), pim
->keep_alive_time
);
7667 pim_upstream_keep_alive_timer_start(up
, pim
->keep_alive_time
);
7672 DEFPY_HIDDEN (interface_ip_pim_activeactive
,
7673 interface_ip_pim_activeactive_cmd
,
7674 "[no$no] ip pim active-active",
7678 "Mark interface as Active-Active for MLAG operations, Hidden because not finished yet\n")
7680 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7681 struct pim_interface
*pim_ifp
;
7683 if (!no
&& !pim_cmd_interface_add(ifp
)) {
7684 vty_out(vty
, "Could not enable PIM SM active-active on interface\n");
7685 return CMD_WARNING_CONFIG_FAILED
;
7688 pim_ifp
= ifp
->info
;
7690 pim_if_unconfigure_mlag_dualactive(pim_ifp
);
7692 pim_if_configure_mlag_dualactive(pim_ifp
);
7697 DEFUN_HIDDEN (interface_ip_pim_ssm
,
7698 interface_ip_pim_ssm_cmd
,
7704 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7706 if (!pim_cmd_interface_add(ifp
)) {
7707 vty_out(vty
, "Could not enable PIM SM on interface\n");
7708 return CMD_WARNING_CONFIG_FAILED
;
7712 "WARN: Enabled PIM SM on interface; configure PIM SSM "
7713 "range if needed\n");
7717 static int interface_ip_pim_helper(struct vty
*vty
)
7719 struct pim_interface
*pim_ifp
;
7721 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7723 if (!pim_cmd_interface_add(ifp
)) {
7724 vty_out(vty
, "Could not enable PIM SM on interface\n");
7725 return CMD_WARNING_CONFIG_FAILED
;
7728 pim_ifp
= ifp
->info
;
7730 pim_if_create_pimreg(pim_ifp
->pim
);
7735 DEFUN_HIDDEN (interface_ip_pim_sm
,
7736 interface_ip_pim_sm_cmd
,
7742 return interface_ip_pim_helper(vty
);
7745 DEFUN (interface_ip_pim
,
7746 interface_ip_pim_cmd
,
7751 return interface_ip_pim_helper(vty
);
7754 static int pim_cmd_interface_delete(struct interface
*ifp
)
7756 struct pim_interface
*pim_ifp
= ifp
->info
;
7761 PIM_IF_DONT_PIM(pim_ifp
->options
);
7763 pim_if_membership_clear(ifp
);
7766 pim_sock_delete() removes all neighbors from
7767 pim_ifp->pim_neighbor_list.
7769 pim_sock_delete(ifp
, "pim unconfigured on interface");
7771 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
7772 pim_if_addr_del_all(ifp
);
7779 static int interface_no_ip_pim_helper(struct vty
*vty
)
7781 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7782 if (!pim_cmd_interface_delete(ifp
)) {
7783 vty_out(vty
, "Unable to delete interface information\n");
7784 return CMD_WARNING_CONFIG_FAILED
;
7790 DEFUN_HIDDEN (interface_no_ip_pim_ssm
,
7791 interface_no_ip_pim_ssm_cmd
,
7798 return interface_no_ip_pim_helper(vty
);
7801 DEFUN_HIDDEN (interface_no_ip_pim_sm
,
7802 interface_no_ip_pim_sm_cmd
,
7809 return interface_no_ip_pim_helper(vty
);
7812 DEFUN (interface_no_ip_pim
,
7813 interface_no_ip_pim_cmd
,
7819 return interface_no_ip_pim_helper(vty
);
7823 DEFUN(interface_ip_pim_boundary_oil
,
7824 interface_ip_pim_boundary_oil_cmd
,
7825 "ip multicast boundary oil WORD",
7827 "Generic multicast configuration options\n"
7828 "Define multicast boundary\n"
7829 "Filter OIL by group using prefix list\n"
7830 "Prefix list to filter OIL with\n")
7832 VTY_DECLVAR_CONTEXT(interface
, iif
);
7833 struct pim_interface
*pim_ifp
;
7836 argv_find(argv
, argc
, "WORD", &idx
);
7838 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
7840 if (pim_ifp
->boundary_oil_plist
)
7841 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
7843 pim_ifp
->boundary_oil_plist
=
7844 XSTRDUP(MTYPE_PIM_INTERFACE
, argv
[idx
]->arg
);
7846 /* Interface will be pruned from OIL on next Join */
7850 DEFUN(interface_no_ip_pim_boundary_oil
,
7851 interface_no_ip_pim_boundary_oil_cmd
,
7852 "no ip multicast boundary oil [WORD]",
7855 "Generic multicast configuration options\n"
7856 "Define multicast boundary\n"
7857 "Filter OIL by group using prefix list\n"
7858 "Prefix list to filter OIL with\n")
7860 VTY_DECLVAR_CONTEXT(interface
, iif
);
7861 struct pim_interface
*pim_ifp
;
7864 argv_find(argv
, argc
, "WORD", &idx
);
7866 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
7868 if (pim_ifp
->boundary_oil_plist
)
7869 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
7874 DEFUN (interface_ip_mroute
,
7875 interface_ip_mroute_cmd
,
7876 "ip mroute INTERFACE A.B.C.D",
7878 "Add multicast route\n"
7879 "Outgoing interface name\n"
7882 VTY_DECLVAR_CONTEXT(interface
, iif
);
7883 struct pim_interface
*pim_ifp
;
7884 struct pim_instance
*pim
;
7885 int idx_interface
= 2;
7887 struct interface
*oif
;
7888 const char *oifname
;
7889 const char *grp_str
;
7890 struct in_addr grp_addr
;
7891 struct in_addr src_addr
;
7894 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
7897 oifname
= argv
[idx_interface
]->arg
;
7898 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
7900 vty_out(vty
, "No such interface name %s\n", oifname
);
7904 grp_str
= argv
[idx_ipv4
]->arg
;
7905 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
7907 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
7908 errno
, safe_strerror(errno
));
7912 src_addr
.s_addr
= INADDR_ANY
;
7914 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
7915 vty_out(vty
, "Failed to add route\n");
7922 DEFUN (interface_ip_mroute_source
,
7923 interface_ip_mroute_source_cmd
,
7924 "ip mroute INTERFACE A.B.C.D A.B.C.D",
7926 "Add multicast route\n"
7927 "Outgoing interface name\n"
7931 VTY_DECLVAR_CONTEXT(interface
, iif
);
7932 struct pim_interface
*pim_ifp
;
7933 struct pim_instance
*pim
;
7934 int idx_interface
= 2;
7937 struct interface
*oif
;
7938 const char *oifname
;
7939 const char *grp_str
;
7940 struct in_addr grp_addr
;
7941 const char *src_str
;
7942 struct in_addr src_addr
;
7945 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
7948 oifname
= argv
[idx_interface
]->arg
;
7949 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
7951 vty_out(vty
, "No such interface name %s\n", oifname
);
7955 grp_str
= argv
[idx_ipv4
]->arg
;
7956 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
7958 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
7959 errno
, safe_strerror(errno
));
7963 src_str
= argv
[idx_ipv4_2
]->arg
;
7964 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
7966 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
7967 errno
, safe_strerror(errno
));
7971 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
7972 vty_out(vty
, "Failed to add route\n");
7979 DEFUN (interface_no_ip_mroute
,
7980 interface_no_ip_mroute_cmd
,
7981 "no ip mroute INTERFACE A.B.C.D",
7984 "Add multicast route\n"
7985 "Outgoing interface name\n"
7988 VTY_DECLVAR_CONTEXT(interface
, iif
);
7989 struct pim_interface
*pim_ifp
;
7990 struct pim_instance
*pim
;
7991 int idx_interface
= 3;
7993 struct interface
*oif
;
7994 const char *oifname
;
7995 const char *grp_str
;
7996 struct in_addr grp_addr
;
7997 struct in_addr src_addr
;
8000 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
8003 oifname
= argv
[idx_interface
]->arg
;
8004 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
8006 vty_out(vty
, "No such interface name %s\n", oifname
);
8010 grp_str
= argv
[idx_ipv4
]->arg
;
8011 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
8013 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
8014 errno
, safe_strerror(errno
));
8018 src_addr
.s_addr
= INADDR_ANY
;
8020 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
8021 vty_out(vty
, "Failed to remove route\n");
8028 DEFUN (interface_no_ip_mroute_source
,
8029 interface_no_ip_mroute_source_cmd
,
8030 "no ip mroute INTERFACE A.B.C.D A.B.C.D",
8033 "Add multicast route\n"
8034 "Outgoing interface name\n"
8038 VTY_DECLVAR_CONTEXT(interface
, iif
);
8039 struct pim_interface
*pim_ifp
;
8040 struct pim_instance
*pim
;
8041 int idx_interface
= 3;
8044 struct interface
*oif
;
8045 const char *oifname
;
8046 const char *grp_str
;
8047 struct in_addr grp_addr
;
8048 const char *src_str
;
8049 struct in_addr src_addr
;
8052 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
8055 oifname
= argv
[idx_interface
]->arg
;
8056 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
8058 vty_out(vty
, "No such interface name %s\n", oifname
);
8062 grp_str
= argv
[idx_ipv4
]->arg
;
8063 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
8065 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
8066 errno
, safe_strerror(errno
));
8070 src_str
= argv
[idx_ipv4_2
]->arg
;
8071 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
8073 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
8074 errno
, safe_strerror(errno
));
8078 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
8079 vty_out(vty
, "Failed to remove route\n");
8086 DEFUN (interface_ip_pim_hello
,
8087 interface_ip_pim_hello_cmd
,
8088 "ip pim hello (1-180) [(1-180)]",
8092 IFACE_PIM_HELLO_TIME_STR
8093 IFACE_PIM_HELLO_HOLD_STR
)
8095 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8098 struct pim_interface
*pim_ifp
= ifp
->info
;
8101 if (!pim_cmd_interface_add(ifp
)) {
8102 vty_out(vty
, "Could not enable PIM SM on interface\n");
8103 return CMD_WARNING_CONFIG_FAILED
;
8107 pim_ifp
= ifp
->info
;
8108 pim_ifp
->pim_hello_period
= strtol(argv
[idx_time
]->arg
, NULL
, 10);
8110 if (argc
== idx_hold
+ 1)
8111 pim_ifp
->pim_default_holdtime
=
8112 strtol(argv
[idx_hold
]->arg
, NULL
, 10);
8117 DEFUN (interface_no_ip_pim_hello
,
8118 interface_no_ip_pim_hello_cmd
,
8119 "no ip pim hello [(1-180) (1-180)]",
8124 IFACE_PIM_HELLO_TIME_STR
8125 IFACE_PIM_HELLO_HOLD_STR
)
8127 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8128 struct pim_interface
*pim_ifp
= ifp
->info
;
8131 vty_out(vty
, "Pim not enabled on this interface\n");
8132 return CMD_WARNING_CONFIG_FAILED
;
8135 pim_ifp
->pim_hello_period
= PIM_DEFAULT_HELLO_PERIOD
;
8136 pim_ifp
->pim_default_holdtime
= -1;
8147 PIM_DO_DEBUG_IGMP_EVENTS
;
8148 PIM_DO_DEBUG_IGMP_PACKETS
;
8149 PIM_DO_DEBUG_IGMP_TRACE
;
8153 DEFUN (no_debug_igmp
,
8160 PIM_DONT_DEBUG_IGMP_EVENTS
;
8161 PIM_DONT_DEBUG_IGMP_PACKETS
;
8162 PIM_DONT_DEBUG_IGMP_TRACE
;
8167 DEFUN (debug_igmp_events
,
8168 debug_igmp_events_cmd
,
8169 "debug igmp events",
8172 DEBUG_IGMP_EVENTS_STR
)
8174 PIM_DO_DEBUG_IGMP_EVENTS
;
8178 DEFUN (no_debug_igmp_events
,
8179 no_debug_igmp_events_cmd
,
8180 "no debug igmp events",
8184 DEBUG_IGMP_EVENTS_STR
)
8186 PIM_DONT_DEBUG_IGMP_EVENTS
;
8191 DEFUN (debug_igmp_packets
,
8192 debug_igmp_packets_cmd
,
8193 "debug igmp packets",
8196 DEBUG_IGMP_PACKETS_STR
)
8198 PIM_DO_DEBUG_IGMP_PACKETS
;
8202 DEFUN (no_debug_igmp_packets
,
8203 no_debug_igmp_packets_cmd
,
8204 "no debug igmp packets",
8208 DEBUG_IGMP_PACKETS_STR
)
8210 PIM_DONT_DEBUG_IGMP_PACKETS
;
8215 DEFUN (debug_igmp_trace
,
8216 debug_igmp_trace_cmd
,
8220 DEBUG_IGMP_TRACE_STR
)
8222 PIM_DO_DEBUG_IGMP_TRACE
;
8226 DEFUN (no_debug_igmp_trace
,
8227 no_debug_igmp_trace_cmd
,
8228 "no debug igmp trace",
8232 DEBUG_IGMP_TRACE_STR
)
8234 PIM_DONT_DEBUG_IGMP_TRACE
;
8239 DEFUN (debug_mroute
,
8245 PIM_DO_DEBUG_MROUTE
;
8249 DEFUN (debug_mroute_detail
,
8250 debug_mroute_detail_cmd
,
8251 "debug mroute detail",
8256 PIM_DO_DEBUG_MROUTE_DETAIL
;
8260 DEFUN (no_debug_mroute
,
8261 no_debug_mroute_cmd
,
8267 PIM_DONT_DEBUG_MROUTE
;
8271 DEFUN (no_debug_mroute_detail
,
8272 no_debug_mroute_detail_cmd
,
8273 "no debug mroute detail",
8279 PIM_DONT_DEBUG_MROUTE_DETAIL
;
8283 DEFUN (debug_pim_static
,
8284 debug_pim_static_cmd
,
8290 PIM_DO_DEBUG_STATIC
;
8294 DEFUN (no_debug_pim_static
,
8295 no_debug_pim_static_cmd
,
8296 "no debug pim static",
8302 PIM_DONT_DEBUG_STATIC
;
8313 PIM_DO_DEBUG_PIM_EVENTS
;
8314 PIM_DO_DEBUG_PIM_PACKETS
;
8315 PIM_DO_DEBUG_PIM_TRACE
;
8316 PIM_DO_DEBUG_MSDP_EVENTS
;
8317 PIM_DO_DEBUG_MSDP_PACKETS
;
8322 DEFUN (no_debug_pim
,
8329 PIM_DONT_DEBUG_PIM_EVENTS
;
8330 PIM_DONT_DEBUG_PIM_PACKETS
;
8331 PIM_DONT_DEBUG_PIM_TRACE
;
8332 PIM_DONT_DEBUG_MSDP_EVENTS
;
8333 PIM_DONT_DEBUG_MSDP_PACKETS
;
8335 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
8336 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
8342 DEFUN (debug_pim_nht
,
8347 "Nexthop Tracking\n")
8349 PIM_DO_DEBUG_PIM_NHT
;
8353 DEFUN (no_debug_pim_nht
,
8354 no_debug_pim_nht_cmd
,
8359 "Nexthop Tracking\n")
8361 PIM_DONT_DEBUG_PIM_NHT
;
8365 DEFUN (debug_pim_nht_rp
,
8366 debug_pim_nht_rp_cmd
,
8370 "Nexthop Tracking\n"
8371 "RP Nexthop Tracking\n")
8373 PIM_DO_DEBUG_PIM_NHT_RP
;
8377 DEFUN (no_debug_pim_nht_rp
,
8378 no_debug_pim_nht_rp_cmd
,
8379 "no debug pim nht rp",
8383 "Nexthop Tracking\n"
8384 "RP Nexthop Tracking\n")
8386 PIM_DONT_DEBUG_PIM_NHT_RP
;
8390 DEFUN (debug_pim_events
,
8391 debug_pim_events_cmd
,
8395 DEBUG_PIM_EVENTS_STR
)
8397 PIM_DO_DEBUG_PIM_EVENTS
;
8401 DEFUN (no_debug_pim_events
,
8402 no_debug_pim_events_cmd
,
8403 "no debug pim events",
8407 DEBUG_PIM_EVENTS_STR
)
8409 PIM_DONT_DEBUG_PIM_EVENTS
;
8413 DEFUN (debug_pim_packets
,
8414 debug_pim_packets_cmd
,
8415 "debug pim packets [<hello|joins|register>]",
8418 DEBUG_PIM_PACKETS_STR
8419 DEBUG_PIM_HELLO_PACKETS_STR
8420 DEBUG_PIM_J_P_PACKETS_STR
8421 DEBUG_PIM_PIM_REG_PACKETS_STR
)
8424 if (argv_find(argv
, argc
, "hello", &idx
)) {
8425 PIM_DO_DEBUG_PIM_HELLO
;
8426 vty_out(vty
, "PIM Hello debugging is on\n");
8427 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
8428 PIM_DO_DEBUG_PIM_J_P
;
8429 vty_out(vty
, "PIM Join/Prune debugging is on\n");
8430 } else if (argv_find(argv
, argc
, "register", &idx
)) {
8431 PIM_DO_DEBUG_PIM_REG
;
8432 vty_out(vty
, "PIM Register debugging is on\n");
8434 PIM_DO_DEBUG_PIM_PACKETS
;
8435 vty_out(vty
, "PIM Packet debugging is on \n");
8440 DEFUN (no_debug_pim_packets
,
8441 no_debug_pim_packets_cmd
,
8442 "no debug pim packets [<hello|joins|register>]",
8446 DEBUG_PIM_PACKETS_STR
8447 DEBUG_PIM_HELLO_PACKETS_STR
8448 DEBUG_PIM_J_P_PACKETS_STR
8449 DEBUG_PIM_PIM_REG_PACKETS_STR
)
8452 if (argv_find(argv
, argc
, "hello", &idx
)) {
8453 PIM_DONT_DEBUG_PIM_HELLO
;
8454 vty_out(vty
, "PIM Hello debugging is off \n");
8455 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
8456 PIM_DONT_DEBUG_PIM_J_P
;
8457 vty_out(vty
, "PIM Join/Prune debugging is off \n");
8458 } else if (argv_find(argv
, argc
, "register", &idx
)) {
8459 PIM_DONT_DEBUG_PIM_REG
;
8460 vty_out(vty
, "PIM Register debugging is off\n");
8462 PIM_DONT_DEBUG_PIM_PACKETS
;
8468 DEFUN (debug_pim_packetdump_send
,
8469 debug_pim_packetdump_send_cmd
,
8470 "debug pim packet-dump send",
8473 DEBUG_PIM_PACKETDUMP_STR
8474 DEBUG_PIM_PACKETDUMP_SEND_STR
)
8476 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND
;
8480 DEFUN (no_debug_pim_packetdump_send
,
8481 no_debug_pim_packetdump_send_cmd
,
8482 "no debug pim packet-dump send",
8486 DEBUG_PIM_PACKETDUMP_STR
8487 DEBUG_PIM_PACKETDUMP_SEND_STR
)
8489 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
8493 DEFUN (debug_pim_packetdump_recv
,
8494 debug_pim_packetdump_recv_cmd
,
8495 "debug pim packet-dump receive",
8498 DEBUG_PIM_PACKETDUMP_STR
8499 DEBUG_PIM_PACKETDUMP_RECV_STR
)
8501 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV
;
8505 DEFUN (no_debug_pim_packetdump_recv
,
8506 no_debug_pim_packetdump_recv_cmd
,
8507 "no debug pim packet-dump receive",
8511 DEBUG_PIM_PACKETDUMP_STR
8512 DEBUG_PIM_PACKETDUMP_RECV_STR
)
8514 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
8518 DEFUN (debug_pim_trace
,
8519 debug_pim_trace_cmd
,
8523 DEBUG_PIM_TRACE_STR
)
8525 PIM_DO_DEBUG_PIM_TRACE
;
8529 DEFUN (debug_pim_trace_detail
,
8530 debug_pim_trace_detail_cmd
,
8531 "debug pim trace detail",
8535 "Detailed Information\n")
8537 PIM_DO_DEBUG_PIM_TRACE_DETAIL
;
8541 DEFUN (no_debug_pim_trace
,
8542 no_debug_pim_trace_cmd
,
8543 "no debug pim trace",
8547 DEBUG_PIM_TRACE_STR
)
8549 PIM_DONT_DEBUG_PIM_TRACE
;
8553 DEFUN (no_debug_pim_trace_detail
,
8554 no_debug_pim_trace_detail_cmd
,
8555 "no debug pim trace detail",
8560 "Detailed Information\n")
8562 PIM_DONT_DEBUG_PIM_TRACE_DETAIL
;
8566 DEFUN (debug_ssmpingd
,
8572 PIM_DO_DEBUG_SSMPINGD
;
8576 DEFUN (no_debug_ssmpingd
,
8577 no_debug_ssmpingd_cmd
,
8578 "no debug ssmpingd",
8583 PIM_DONT_DEBUG_SSMPINGD
;
8587 DEFUN (debug_pim_zebra
,
8588 debug_pim_zebra_cmd
,
8592 DEBUG_PIM_ZEBRA_STR
)
8598 DEFUN (no_debug_pim_zebra
,
8599 no_debug_pim_zebra_cmd
,
8600 "no debug pim zebra",
8604 DEBUG_PIM_ZEBRA_STR
)
8606 PIM_DONT_DEBUG_ZEBRA
;
8610 DEFUN(debug_pim_mlag
, debug_pim_mlag_cmd
, "debug pim mlag",
8611 DEBUG_STR DEBUG_PIM_STR DEBUG_PIM_MLAG_STR
)
8617 DEFUN(no_debug_pim_mlag
, no_debug_pim_mlag_cmd
, "no debug pim mlag",
8618 NO_STR DEBUG_STR DEBUG_PIM_STR DEBUG_PIM_MLAG_STR
)
8620 PIM_DONT_DEBUG_MLAG
;
8624 DEFUN (debug_pim_vxlan
,
8625 debug_pim_vxlan_cmd
,
8629 DEBUG_PIM_VXLAN_STR
)
8635 DEFUN (no_debug_pim_vxlan
,
8636 no_debug_pim_vxlan_cmd
,
8637 "no debug pim vxlan",
8641 DEBUG_PIM_VXLAN_STR
)
8643 PIM_DONT_DEBUG_VXLAN
;
8653 PIM_DO_DEBUG_MSDP_EVENTS
;
8654 PIM_DO_DEBUG_MSDP_PACKETS
;
8658 DEFUN (no_debug_msdp
,
8665 PIM_DONT_DEBUG_MSDP_EVENTS
;
8666 PIM_DONT_DEBUG_MSDP_PACKETS
;
8670 DEFUN (debug_msdp_events
,
8671 debug_msdp_events_cmd
,
8672 "debug msdp events",
8675 DEBUG_MSDP_EVENTS_STR
)
8677 PIM_DO_DEBUG_MSDP_EVENTS
;
8681 DEFUN (no_debug_msdp_events
,
8682 no_debug_msdp_events_cmd
,
8683 "no debug msdp events",
8687 DEBUG_MSDP_EVENTS_STR
)
8689 PIM_DONT_DEBUG_MSDP_EVENTS
;
8693 DEFUN (debug_msdp_packets
,
8694 debug_msdp_packets_cmd
,
8695 "debug msdp packets",
8698 DEBUG_MSDP_PACKETS_STR
)
8700 PIM_DO_DEBUG_MSDP_PACKETS
;
8704 DEFUN (no_debug_msdp_packets
,
8705 no_debug_msdp_packets_cmd
,
8706 "no debug msdp packets",
8710 DEBUG_MSDP_PACKETS_STR
)
8712 PIM_DONT_DEBUG_MSDP_PACKETS
;
8716 DEFUN (debug_mtrace
,
8722 PIM_DO_DEBUG_MTRACE
;
8726 DEFUN (no_debug_mtrace
,
8727 no_debug_mtrace_cmd
,
8733 PIM_DONT_DEBUG_MTRACE
;
8748 DEFUN (no_debug_bsm
,
8761 DEFUN_NOSH (show_debugging_pim
,
8762 show_debugging_pim_cmd
,
8763 "show debugging [pim]",
8768 vty_out(vty
, "PIM debugging status\n");
8770 pim_debug_config_write(vty
);
8775 static int interface_pim_use_src_cmd_worker(struct vty
*vty
, const char *source
)
8778 struct in_addr source_addr
;
8779 int ret
= CMD_SUCCESS
;
8780 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8782 result
= inet_pton(AF_INET
, source
, &source_addr
);
8784 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", source
,
8785 errno
, safe_strerror(errno
));
8786 return CMD_WARNING_CONFIG_FAILED
;
8789 result
= pim_update_source_set(ifp
, source_addr
);
8793 case PIM_IFACE_NOT_FOUND
:
8794 ret
= CMD_WARNING_CONFIG_FAILED
;
8795 vty_out(vty
, "Pim not enabled on this interface\n");
8797 case PIM_UPDATE_SOURCE_DUP
:
8799 vty_out(vty
, "%% Source already set to %s\n", source
);
8802 ret
= CMD_WARNING_CONFIG_FAILED
;
8803 vty_out(vty
, "%% Source set failed\n");
8809 DEFUN (interface_pim_use_source
,
8810 interface_pim_use_source_cmd
,
8811 "ip pim use-source A.B.C.D",
8814 "Configure primary IP address\n"
8815 "source ip address\n")
8817 return interface_pim_use_src_cmd_worker(vty
, argv
[3]->arg
);
8820 DEFUN (interface_no_pim_use_source
,
8821 interface_no_pim_use_source_cmd
,
8822 "no ip pim use-source [A.B.C.D]",
8826 "Delete source IP address\n"
8827 "source ip address\n")
8829 return interface_pim_use_src_cmd_worker(vty
, "0.0.0.0");
8837 "Enables BFD support\n")
8839 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8840 struct pim_interface
*pim_ifp
= ifp
->info
;
8841 struct bfd_info
*bfd_info
= NULL
;
8844 if (!pim_cmd_interface_add(ifp
)) {
8845 vty_out(vty
, "Could not enable PIM SM on interface\n");
8849 pim_ifp
= ifp
->info
;
8851 bfd_info
= pim_ifp
->bfd_info
;
8853 if (!bfd_info
|| !CHECK_FLAG(bfd_info
->flags
, BFD_FLAG_PARAM_CFG
))
8854 pim_bfd_if_param_set(ifp
, BFD_DEF_MIN_RX
, BFD_DEF_MIN_TX
,
8855 BFD_DEF_DETECT_MULT
, 1);
8860 DEFUN (no_ip_pim_bfd
,
8866 "Disables BFD support\n")
8868 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8869 struct pim_interface
*pim_ifp
= ifp
->info
;
8872 vty_out(vty
, "Pim not enabled on this interface\n");
8876 if (pim_ifp
->bfd_info
) {
8877 pim_bfd_reg_dereg_all_nbr(ifp
, ZEBRA_BFD_DEST_DEREGISTER
);
8878 bfd_info_free(&(pim_ifp
->bfd_info
));
8889 "Enables BSM support on the interface\n")
8891 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8892 struct pim_interface
*pim_ifp
= ifp
->info
;
8895 if (!pim_cmd_interface_add(ifp
)) {
8896 vty_out(vty
, "Could not enable PIM SM on interface\n");
8901 pim_ifp
= ifp
->info
;
8902 pim_ifp
->bsm_enable
= true;
8907 DEFUN (no_ip_pim_bsm
,
8913 "Disables BSM support\n")
8915 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8916 struct pim_interface
*pim_ifp
= ifp
->info
;
8919 vty_out(vty
, "Pim not enabled on this interface\n");
8923 pim_ifp
->bsm_enable
= false;
8928 DEFUN (ip_pim_ucast_bsm
,
8929 ip_pim_ucast_bsm_cmd
,
8930 "ip pim unicast-bsm",
8933 "Accept/Send unicast BSM on the interface\n")
8935 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8936 struct pim_interface
*pim_ifp
= ifp
->info
;
8939 if (!pim_cmd_interface_add(ifp
)) {
8940 vty_out(vty
, "Could not enable PIM SM on interface\n");
8945 pim_ifp
= ifp
->info
;
8946 pim_ifp
->ucast_bsm_accept
= true;
8951 DEFUN (no_ip_pim_ucast_bsm
,
8952 no_ip_pim_ucast_bsm_cmd
,
8953 "no ip pim unicast-bsm",
8957 "Block send/receive unicast BSM on this interface\n")
8959 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8960 struct pim_interface
*pim_ifp
= ifp
->info
;
8963 vty_out(vty
, "Pim not enabled on this interface\n");
8967 pim_ifp
->ucast_bsm_accept
= false;
8975 ip_pim_bfd_param_cmd
,
8976 "ip pim bfd (2-255) (50-60000) (50-60000)",
8979 "Enables BFD support\n"
8980 "Detect Multiplier\n"
8981 "Required min receive interval\n"
8982 "Desired min transmit interval\n")
8986 ip_pim_bfd_param_cmd
,
8987 "ip pim bfd (2-255) (50-60000) (50-60000)",
8990 "Enables BFD support\n"
8991 "Detect Multiplier\n"
8992 "Required min receive interval\n"
8993 "Desired min transmit interval\n")
8994 #endif /* HAVE_BFDD */
8996 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8998 int idx_number_2
= 4;
8999 int idx_number_3
= 5;
9004 struct pim_interface
*pim_ifp
= ifp
->info
;
9007 if (!pim_cmd_interface_add(ifp
)) {
9008 vty_out(vty
, "Could not enable PIM SM on interface\n");
9013 if ((ret
= bfd_validate_param(
9014 vty
, argv
[idx_number
]->arg
, argv
[idx_number_2
]->arg
,
9015 argv
[idx_number_3
]->arg
, &dm_val
, &rx_val
, &tx_val
))
9019 pim_bfd_if_param_set(ifp
, rx_val
, tx_val
, dm_val
, 0);
9025 ALIAS(no_ip_pim_bfd
, no_ip_pim_bfd_param_cmd
,
9026 "no ip pim bfd (2-255) (50-60000) (50-60000)", NO_STR IP_STR PIM_STR
9027 "Enables BFD support\n"
9028 "Detect Multiplier\n"
9029 "Required min receive interval\n"
9030 "Desired min transmit interval\n")
9031 #endif /* !HAVE_BFDD */
9033 static int ip_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
9034 const char *peer
, const char *local
)
9036 enum pim_msdp_err result
;
9037 struct in_addr peer_addr
;
9038 struct in_addr local_addr
;
9039 int ret
= CMD_SUCCESS
;
9041 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
9043 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
9044 errno
, safe_strerror(errno
));
9045 return CMD_WARNING_CONFIG_FAILED
;
9048 result
= inet_pton(AF_INET
, local
, &local_addr
);
9050 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", local
,
9051 errno
, safe_strerror(errno
));
9052 return CMD_WARNING_CONFIG_FAILED
;
9055 result
= pim_msdp_peer_add(pim
, peer_addr
, local_addr
, "default",
9058 case PIM_MSDP_ERR_NONE
:
9060 case PIM_MSDP_ERR_OOM
:
9061 ret
= CMD_WARNING_CONFIG_FAILED
;
9062 vty_out(vty
, "%% Out of memory\n");
9064 case PIM_MSDP_ERR_PEER_EXISTS
:
9066 vty_out(vty
, "%% Peer exists\n");
9068 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
9069 ret
= CMD_WARNING_CONFIG_FAILED
;
9070 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
9073 ret
= CMD_WARNING_CONFIG_FAILED
;
9074 vty_out(vty
, "%% peer add failed\n");
9080 DEFUN_HIDDEN (ip_msdp_peer
,
9082 "ip msdp peer A.B.C.D source A.B.C.D",
9085 "Configure MSDP peer\n"
9087 "Source address for TCP connection\n"
9088 "local ip address\n")
9090 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9091 return ip_msdp_peer_cmd_worker(pim
, vty
, argv
[3]->arg
, argv
[5]->arg
);
9094 static int ip_no_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
9097 enum pim_msdp_err result
;
9098 struct in_addr peer_addr
;
9100 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
9102 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
9103 errno
, safe_strerror(errno
));
9104 return CMD_WARNING_CONFIG_FAILED
;
9107 result
= pim_msdp_peer_del(pim
, peer_addr
);
9109 case PIM_MSDP_ERR_NONE
:
9111 case PIM_MSDP_ERR_NO_PEER
:
9112 vty_out(vty
, "%% Peer does not exist\n");
9115 vty_out(vty
, "%% peer del failed\n");
9118 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9121 DEFUN_HIDDEN (no_ip_msdp_peer
,
9122 no_ip_msdp_peer_cmd
,
9123 "no ip msdp peer A.B.C.D",
9127 "Delete MSDP peer\n"
9128 "peer ip address\n")
9130 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9131 return ip_no_msdp_peer_cmd_worker(pim
, vty
, argv
[4]->arg
);
9134 static int ip_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
9135 struct vty
*vty
, const char *mg
,
9138 enum pim_msdp_err result
;
9139 struct in_addr mbr_ip
;
9140 int ret
= CMD_SUCCESS
;
9142 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
9144 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
9145 errno
, safe_strerror(errno
));
9146 return CMD_WARNING_CONFIG_FAILED
;
9149 result
= pim_msdp_mg_mbr_add(pim
, mg
, mbr_ip
);
9151 case PIM_MSDP_ERR_NONE
:
9153 case PIM_MSDP_ERR_OOM
:
9154 ret
= CMD_WARNING_CONFIG_FAILED
;
9155 vty_out(vty
, "%% Out of memory\n");
9157 case PIM_MSDP_ERR_MG_MBR_EXISTS
:
9159 vty_out(vty
, "%% mesh-group member exists\n");
9161 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
9162 ret
= CMD_WARNING_CONFIG_FAILED
;
9163 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
9166 ret
= CMD_WARNING_CONFIG_FAILED
;
9167 vty_out(vty
, "%% member add failed\n");
9173 DEFUN (ip_msdp_mesh_group_member
,
9174 ip_msdp_mesh_group_member_cmd
,
9175 "ip msdp mesh-group WORD member A.B.C.D",
9178 "Configure MSDP mesh-group\n"
9180 "mesh group member\n"
9181 "peer ip address\n")
9183 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9184 return ip_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[3]->arg
,
9188 static int ip_no_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
9193 enum pim_msdp_err result
;
9194 struct in_addr mbr_ip
;
9196 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
9198 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
9199 errno
, safe_strerror(errno
));
9200 return CMD_WARNING_CONFIG_FAILED
;
9203 result
= pim_msdp_mg_mbr_del(pim
, mg
, mbr_ip
);
9205 case PIM_MSDP_ERR_NONE
:
9207 case PIM_MSDP_ERR_NO_MG
:
9208 vty_out(vty
, "%% mesh-group does not exist\n");
9210 case PIM_MSDP_ERR_NO_MG_MBR
:
9211 vty_out(vty
, "%% mesh-group member does not exist\n");
9214 vty_out(vty
, "%% mesh-group member del failed\n");
9217 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9219 DEFUN (no_ip_msdp_mesh_group_member
,
9220 no_ip_msdp_mesh_group_member_cmd
,
9221 "no ip msdp mesh-group WORD member A.B.C.D",
9225 "Delete MSDP mesh-group member\n"
9227 "mesh group member\n"
9228 "peer ip address\n")
9230 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9231 return ip_no_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[4]->arg
,
9235 static int ip_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
9236 struct vty
*vty
, const char *mg
,
9239 enum pim_msdp_err result
;
9240 struct in_addr src_ip
;
9242 result
= inet_pton(AF_INET
, src
, &src_ip
);
9244 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", src
,
9245 errno
, safe_strerror(errno
));
9246 return CMD_WARNING_CONFIG_FAILED
;
9249 result
= pim_msdp_mg_src_add(pim
, mg
, src_ip
);
9251 case PIM_MSDP_ERR_NONE
:
9253 case PIM_MSDP_ERR_OOM
:
9254 vty_out(vty
, "%% Out of memory\n");
9256 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
9257 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
9260 vty_out(vty
, "%% source add failed\n");
9263 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9267 DEFUN (ip_msdp_mesh_group_source
,
9268 ip_msdp_mesh_group_source_cmd
,
9269 "ip msdp mesh-group WORD source A.B.C.D",
9272 "Configure MSDP mesh-group\n"
9274 "mesh group local address\n"
9275 "source ip address for the TCP connection\n")
9277 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9278 return ip_msdp_mesh_group_source_cmd_worker(pim
, vty
, argv
[3]->arg
,
9282 static int ip_no_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
9286 enum pim_msdp_err result
;
9288 result
= pim_msdp_mg_src_del(pim
, mg
);
9290 case PIM_MSDP_ERR_NONE
:
9292 case PIM_MSDP_ERR_NO_MG
:
9293 vty_out(vty
, "%% mesh-group does not exist\n");
9296 vty_out(vty
, "%% mesh-group source del failed\n");
9299 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9302 static int ip_no_msdp_mesh_group_cmd_worker(struct pim_instance
*pim
,
9303 struct vty
*vty
, const char *mg
)
9305 enum pim_msdp_err result
;
9307 result
= pim_msdp_mg_del(pim
, mg
);
9309 case PIM_MSDP_ERR_NONE
:
9311 case PIM_MSDP_ERR_NO_MG
:
9312 vty_out(vty
, "%% mesh-group does not exist\n");
9315 vty_out(vty
, "%% mesh-group source del failed\n");
9318 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9321 DEFUN (no_ip_msdp_mesh_group_source
,
9322 no_ip_msdp_mesh_group_source_cmd
,
9323 "no ip msdp mesh-group WORD source [A.B.C.D]",
9327 "Delete MSDP mesh-group source\n"
9329 "mesh group source\n"
9330 "mesh group local address\n")
9332 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9334 return ip_no_msdp_mesh_group_cmd_worker(pim
, vty
, argv
[6]->arg
);
9336 return ip_no_msdp_mesh_group_source_cmd_worker(pim
, vty
,
9340 static void print_empty_json_obj(struct vty
*vty
)
9343 json
= json_object_new_object();
9344 vty_out(vty
, "%s\n",
9345 json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
));
9346 json_object_free(json
);
9349 static void ip_msdp_show_mesh_group(struct pim_instance
*pim
, struct vty
*vty
,
9352 struct listnode
*mbrnode
;
9353 struct pim_msdp_mg_mbr
*mbr
;
9354 struct pim_msdp_mg
*mg
= pim
->msdp
.mg
;
9355 char mbr_str
[INET_ADDRSTRLEN
];
9356 char src_str
[INET_ADDRSTRLEN
];
9357 char state_str
[PIM_MSDP_STATE_STRLEN
];
9358 enum pim_msdp_peer_state state
;
9359 json_object
*json
= NULL
;
9360 json_object
*json_mg_row
= NULL
;
9361 json_object
*json_members
= NULL
;
9362 json_object
*json_row
= NULL
;
9366 print_empty_json_obj(vty
);
9370 pim_inet4_dump("<source?>", mg
->src_ip
, src_str
, sizeof(src_str
));
9372 json
= json_object_new_object();
9373 /* currently there is only one mesh group but we should still
9375 * it a dict with mg-name as key */
9376 json_mg_row
= json_object_new_object();
9377 json_object_string_add(json_mg_row
, "name",
9378 mg
->mesh_group_name
);
9379 json_object_string_add(json_mg_row
, "source", src_str
);
9381 vty_out(vty
, "Mesh group : %s\n", mg
->mesh_group_name
);
9382 vty_out(vty
, " Source : %s\n", src_str
);
9383 vty_out(vty
, " Member State\n");
9386 for (ALL_LIST_ELEMENTS_RO(mg
->mbr_list
, mbrnode
, mbr
)) {
9387 pim_inet4_dump("<mbr?>", mbr
->mbr_ip
, mbr_str
, sizeof(mbr_str
));
9389 state
= mbr
->mp
->state
;
9391 state
= PIM_MSDP_DISABLED
;
9393 pim_msdp_state_dump(state
, state_str
, sizeof(state_str
));
9395 json_row
= json_object_new_object();
9396 json_object_string_add(json_row
, "member", mbr_str
);
9397 json_object_string_add(json_row
, "state", state_str
);
9398 if (!json_members
) {
9399 json_members
= json_object_new_object();
9400 json_object_object_add(json_mg_row
, "members",
9403 json_object_object_add(json_members
, mbr_str
, json_row
);
9405 vty_out(vty
, " %-15s %11s\n", mbr_str
, state_str
);
9410 json_object_object_add(json
, mg
->mesh_group_name
, json_mg_row
);
9411 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9412 json
, JSON_C_TO_STRING_PRETTY
));
9413 json_object_free(json
);
9417 DEFUN (show_ip_msdp_mesh_group
,
9418 show_ip_msdp_mesh_group_cmd
,
9419 "show ip msdp [vrf NAME] mesh-group [json]",
9424 "MSDP mesh-group information\n"
9427 bool uj
= use_json(argc
, argv
);
9429 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
9434 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
9439 DEFUN (show_ip_msdp_mesh_group_vrf_all
,
9440 show_ip_msdp_mesh_group_vrf_all_cmd
,
9441 "show ip msdp vrf all mesh-group [json]",
9446 "MSDP mesh-group information\n"
9449 bool uj
= use_json(argc
, argv
);
9455 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
9459 vty_out(vty
, " \"%s\": ", vrf
->name
);
9462 vty_out(vty
, "VRF: %s\n", vrf
->name
);
9463 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
9466 vty_out(vty
, "}\n");
9471 static void ip_msdp_show_peers(struct pim_instance
*pim
, struct vty
*vty
,
9474 struct listnode
*mpnode
;
9475 struct pim_msdp_peer
*mp
;
9476 char peer_str
[INET_ADDRSTRLEN
];
9477 char local_str
[INET_ADDRSTRLEN
];
9478 char state_str
[PIM_MSDP_STATE_STRLEN
];
9479 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
9481 json_object
*json
= NULL
;
9482 json_object
*json_row
= NULL
;
9486 json
= json_object_new_object();
9489 "Peer Local State Uptime SaCnt\n");
9492 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
9493 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
9494 now
= pim_time_monotonic_sec();
9495 pim_time_uptime(timebuf
, sizeof(timebuf
),
9498 strlcpy(timebuf
, "-", sizeof(timebuf
));
9500 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
9501 pim_inet4_dump("<local?>", mp
->local
, local_str
,
9503 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
9505 json_row
= json_object_new_object();
9506 json_object_string_add(json_row
, "peer", peer_str
);
9507 json_object_string_add(json_row
, "local", local_str
);
9508 json_object_string_add(json_row
, "state", state_str
);
9509 json_object_string_add(json_row
, "upTime", timebuf
);
9510 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
9511 json_object_object_add(json
, peer_str
, json_row
);
9513 vty_out(vty
, "%-15s %15s %11s %8s %6d\n", peer_str
,
9514 local_str
, state_str
, timebuf
, mp
->sa_cnt
);
9519 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9520 json
, JSON_C_TO_STRING_PRETTY
));
9521 json_object_free(json
);
9525 static void ip_msdp_show_peers_detail(struct pim_instance
*pim
, struct vty
*vty
,
9526 const char *peer
, bool uj
)
9528 struct listnode
*mpnode
;
9529 struct pim_msdp_peer
*mp
;
9530 char peer_str
[INET_ADDRSTRLEN
];
9531 char local_str
[INET_ADDRSTRLEN
];
9532 char state_str
[PIM_MSDP_STATE_STRLEN
];
9533 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
9534 char katimer
[PIM_MSDP_TIMER_STRLEN
];
9535 char crtimer
[PIM_MSDP_TIMER_STRLEN
];
9536 char holdtimer
[PIM_MSDP_TIMER_STRLEN
];
9538 json_object
*json
= NULL
;
9539 json_object
*json_row
= NULL
;
9542 json
= json_object_new_object();
9545 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
9546 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
9547 if (strcmp(peer
, "detail") && strcmp(peer
, peer_str
))
9550 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
9551 now
= pim_time_monotonic_sec();
9552 pim_time_uptime(timebuf
, sizeof(timebuf
),
9555 strlcpy(timebuf
, "-", sizeof(timebuf
));
9557 pim_inet4_dump("<local?>", mp
->local
, local_str
,
9559 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
9560 pim_time_timer_to_hhmmss(katimer
, sizeof(katimer
),
9562 pim_time_timer_to_hhmmss(crtimer
, sizeof(crtimer
),
9564 pim_time_timer_to_hhmmss(holdtimer
, sizeof(holdtimer
),
9568 json_row
= json_object_new_object();
9569 json_object_string_add(json_row
, "peer", peer_str
);
9570 json_object_string_add(json_row
, "local", local_str
);
9571 json_object_string_add(json_row
, "meshGroupName",
9572 mp
->mesh_group_name
);
9573 json_object_string_add(json_row
, "state", state_str
);
9574 json_object_string_add(json_row
, "upTime", timebuf
);
9575 json_object_string_add(json_row
, "keepAliveTimer",
9577 json_object_string_add(json_row
, "connRetryTimer",
9579 json_object_string_add(json_row
, "holdTimer",
9581 json_object_string_add(json_row
, "lastReset",
9583 json_object_int_add(json_row
, "connAttempts",
9585 json_object_int_add(json_row
, "establishedChanges",
9587 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
9588 json_object_int_add(json_row
, "kaSent", mp
->ka_tx_cnt
);
9589 json_object_int_add(json_row
, "kaRcvd", mp
->ka_rx_cnt
);
9590 json_object_int_add(json_row
, "saSent", mp
->sa_tx_cnt
);
9591 json_object_int_add(json_row
, "saRcvd", mp
->sa_rx_cnt
);
9592 json_object_object_add(json
, peer_str
, json_row
);
9594 vty_out(vty
, "Peer : %s\n", peer_str
);
9595 vty_out(vty
, " Local : %s\n", local_str
);
9596 vty_out(vty
, " Mesh Group : %s\n",
9597 mp
->mesh_group_name
);
9598 vty_out(vty
, " State : %s\n", state_str
);
9599 vty_out(vty
, " Uptime : %s\n", timebuf
);
9601 vty_out(vty
, " Keepalive Timer : %s\n", katimer
);
9602 vty_out(vty
, " Conn Retry Timer : %s\n", crtimer
);
9603 vty_out(vty
, " Hold Timer : %s\n", holdtimer
);
9604 vty_out(vty
, " Last Reset : %s\n",
9606 vty_out(vty
, " Conn Attempts : %d\n",
9608 vty_out(vty
, " Established Changes : %d\n",
9610 vty_out(vty
, " SA Count : %d\n",
9612 vty_out(vty
, " Statistics :\n");
9615 vty_out(vty
, " Keepalives : %10d %10d\n",
9616 mp
->ka_tx_cnt
, mp
->ka_rx_cnt
);
9617 vty_out(vty
, " SAs : %10d %10d\n",
9618 mp
->sa_tx_cnt
, mp
->sa_rx_cnt
);
9624 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9625 json
, JSON_C_TO_STRING_PRETTY
));
9626 json_object_free(json
);
9630 DEFUN (show_ip_msdp_peer_detail
,
9631 show_ip_msdp_peer_detail_cmd
,
9632 "show ip msdp [vrf NAME] peer [detail|A.B.C.D] [json]",
9637 "MSDP peer information\n"
9642 bool uj
= use_json(argc
, argv
);
9644 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
9651 if (argv_find(argv
, argc
, "detail", &idx
))
9652 arg
= argv
[idx
]->text
;
9653 else if (argv_find(argv
, argc
, "A.B.C.D", &idx
))
9654 arg
= argv
[idx
]->arg
;
9657 ip_msdp_show_peers_detail(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
9659 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
9664 DEFUN (show_ip_msdp_peer_detail_vrf_all
,
9665 show_ip_msdp_peer_detail_vrf_all_cmd
,
9666 "show ip msdp vrf all peer [detail|A.B.C.D] [json]",
9671 "MSDP peer information\n"
9677 bool uj
= use_json(argc
, argv
);
9683 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
9687 vty_out(vty
, " \"%s\": ", vrf
->name
);
9690 vty_out(vty
, "VRF: %s\n", vrf
->name
);
9691 if (argv_find(argv
, argc
, "detail", &idx
)
9692 || argv_find(argv
, argc
, "A.B.C.D", &idx
))
9693 ip_msdp_show_peers_detail(vrf
->info
, vty
,
9694 argv
[idx
]->arg
, uj
);
9696 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
9699 vty_out(vty
, "}\n");
9704 static void ip_msdp_show_sa(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
9706 struct listnode
*sanode
;
9707 struct pim_msdp_sa
*sa
;
9708 char src_str
[INET_ADDRSTRLEN
];
9709 char grp_str
[INET_ADDRSTRLEN
];
9710 char rp_str
[INET_ADDRSTRLEN
];
9711 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
9715 json_object
*json
= NULL
;
9716 json_object
*json_group
= NULL
;
9717 json_object
*json_row
= NULL
;
9720 json
= json_object_new_object();
9723 "Source Group RP Local SPT Uptime\n");
9726 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
9727 now
= pim_time_monotonic_sec();
9728 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
9729 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
9730 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
9731 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
9732 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
9734 strlcpy(spt_str
, "yes", sizeof(spt_str
));
9736 strlcpy(spt_str
, "no", sizeof(spt_str
));
9739 strlcpy(rp_str
, "-", sizeof(rp_str
));
9740 strlcpy(spt_str
, "-", sizeof(spt_str
));
9742 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
9743 strlcpy(local_str
, "yes", sizeof(local_str
));
9745 strlcpy(local_str
, "no", sizeof(local_str
));
9748 json_object_object_get_ex(json
, grp_str
, &json_group
);
9751 json_group
= json_object_new_object();
9752 json_object_object_add(json
, grp_str
,
9756 json_row
= json_object_new_object();
9757 json_object_string_add(json_row
, "source", src_str
);
9758 json_object_string_add(json_row
, "group", grp_str
);
9759 json_object_string_add(json_row
, "rp", rp_str
);
9760 json_object_string_add(json_row
, "local", local_str
);
9761 json_object_string_add(json_row
, "sptSetup", spt_str
);
9762 json_object_string_add(json_row
, "upTime", timebuf
);
9763 json_object_object_add(json_group
, src_str
, json_row
);
9765 vty_out(vty
, "%-15s %15s %15s %5c %3c %8s\n",
9766 src_str
, grp_str
, rp_str
, local_str
[0],
9767 spt_str
[0], timebuf
);
9772 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9773 json
, JSON_C_TO_STRING_PRETTY
));
9774 json_object_free(json
);
9778 static void ip_msdp_show_sa_entry_detail(struct pim_msdp_sa
*sa
,
9779 const char *src_str
,
9780 const char *grp_str
, struct vty
*vty
,
9781 bool uj
, json_object
*json
)
9783 char rp_str
[INET_ADDRSTRLEN
];
9784 char peer_str
[INET_ADDRSTRLEN
];
9785 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
9788 char statetimer
[PIM_MSDP_TIMER_STRLEN
];
9790 json_object
*json_group
= NULL
;
9791 json_object
*json_row
= NULL
;
9793 now
= pim_time_monotonic_sec();
9794 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
9795 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
9796 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
9797 pim_inet4_dump("<peer?>", sa
->peer
, peer_str
, sizeof(peer_str
));
9799 strlcpy(spt_str
, "yes", sizeof(spt_str
));
9801 strlcpy(spt_str
, "no", sizeof(spt_str
));
9804 strlcpy(rp_str
, "-", sizeof(rp_str
));
9805 strlcpy(peer_str
, "-", sizeof(peer_str
));
9806 strlcpy(spt_str
, "-", sizeof(spt_str
));
9808 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
9809 strlcpy(local_str
, "yes", sizeof(local_str
));
9811 strlcpy(local_str
, "no", sizeof(local_str
));
9813 pim_time_timer_to_hhmmss(statetimer
, sizeof(statetimer
),
9814 sa
->sa_state_timer
);
9816 json_object_object_get_ex(json
, grp_str
, &json_group
);
9819 json_group
= json_object_new_object();
9820 json_object_object_add(json
, grp_str
, json_group
);
9823 json_row
= json_object_new_object();
9824 json_object_string_add(json_row
, "source", src_str
);
9825 json_object_string_add(json_row
, "group", grp_str
);
9826 json_object_string_add(json_row
, "rp", rp_str
);
9827 json_object_string_add(json_row
, "local", local_str
);
9828 json_object_string_add(json_row
, "sptSetup", spt_str
);
9829 json_object_string_add(json_row
, "upTime", timebuf
);
9830 json_object_string_add(json_row
, "stateTimer", statetimer
);
9831 json_object_object_add(json_group
, src_str
, json_row
);
9833 vty_out(vty
, "SA : %s\n", sa
->sg_str
);
9834 vty_out(vty
, " RP : %s\n", rp_str
);
9835 vty_out(vty
, " Peer : %s\n", peer_str
);
9836 vty_out(vty
, " Local : %s\n", local_str
);
9837 vty_out(vty
, " SPT Setup : %s\n", spt_str
);
9838 vty_out(vty
, " Uptime : %s\n", timebuf
);
9839 vty_out(vty
, " State Timer : %s\n", statetimer
);
9844 static void ip_msdp_show_sa_detail(struct pim_instance
*pim
, struct vty
*vty
,
9847 struct listnode
*sanode
;
9848 struct pim_msdp_sa
*sa
;
9849 char src_str
[INET_ADDRSTRLEN
];
9850 char grp_str
[INET_ADDRSTRLEN
];
9851 json_object
*json
= NULL
;
9854 json
= json_object_new_object();
9857 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
9858 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
9859 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
9860 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
, uj
,
9865 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9866 json
, JSON_C_TO_STRING_PRETTY
));
9867 json_object_free(json
);
9871 DEFUN (show_ip_msdp_sa_detail
,
9872 show_ip_msdp_sa_detail_cmd
,
9873 "show ip msdp [vrf NAME] sa detail [json]",
9878 "MSDP active-source information\n"
9882 bool uj
= use_json(argc
, argv
);
9884 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
9889 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
9894 DEFUN (show_ip_msdp_sa_detail_vrf_all
,
9895 show_ip_msdp_sa_detail_vrf_all_cmd
,
9896 "show ip msdp vrf all sa detail [json]",
9901 "MSDP active-source information\n"
9905 bool uj
= use_json(argc
, argv
);
9911 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
9915 vty_out(vty
, " \"%s\": ", vrf
->name
);
9918 vty_out(vty
, "VRF: %s\n", vrf
->name
);
9919 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
9922 vty_out(vty
, "}\n");
9927 static void ip_msdp_show_sa_addr(struct pim_instance
*pim
, struct vty
*vty
,
9928 const char *addr
, bool uj
)
9930 struct listnode
*sanode
;
9931 struct pim_msdp_sa
*sa
;
9932 char src_str
[INET_ADDRSTRLEN
];
9933 char grp_str
[INET_ADDRSTRLEN
];
9934 json_object
*json
= NULL
;
9937 json
= json_object_new_object();
9940 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
9941 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
9942 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
9943 if (!strcmp(addr
, src_str
) || !strcmp(addr
, grp_str
)) {
9944 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
9950 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9951 json
, JSON_C_TO_STRING_PRETTY
));
9952 json_object_free(json
);
9956 static void ip_msdp_show_sa_sg(struct pim_instance
*pim
, struct vty
*vty
,
9957 const char *src
, const char *grp
, bool uj
)
9959 struct listnode
*sanode
;
9960 struct pim_msdp_sa
*sa
;
9961 char src_str
[INET_ADDRSTRLEN
];
9962 char grp_str
[INET_ADDRSTRLEN
];
9963 json_object
*json
= NULL
;
9966 json
= json_object_new_object();
9969 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
9970 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
9971 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
9972 if (!strcmp(src
, src_str
) && !strcmp(grp
, grp_str
)) {
9973 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
9979 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9980 json
, JSON_C_TO_STRING_PRETTY
));
9981 json_object_free(json
);
9985 DEFUN (show_ip_msdp_sa_sg
,
9986 show_ip_msdp_sa_sg_cmd
,
9987 "show ip msdp [vrf NAME] sa [A.B.C.D [A.B.C.D]] [json]",
9992 "MSDP active-source information\n"
9993 "source or group ip\n"
9997 bool uj
= use_json(argc
, argv
);
10001 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10004 return CMD_WARNING
;
10006 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
10008 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
10012 if (src_ip
&& grp_ip
)
10013 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
10015 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
10017 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
10019 return CMD_SUCCESS
;
10022 DEFUN (show_ip_msdp_sa_sg_vrf_all
,
10023 show_ip_msdp_sa_sg_vrf_all_cmd
,
10024 "show ip msdp vrf all sa [A.B.C.D [A.B.C.D]] [json]",
10029 "MSDP active-source information\n"
10030 "source or group ip\n"
10034 bool uj
= use_json(argc
, argv
);
10039 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
10041 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
10046 vty_out(vty
, "{ ");
10047 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
10050 vty_out(vty
, ", ");
10051 vty_out(vty
, " \"%s\": ", vrf
->name
);
10054 vty_out(vty
, "VRF: %s\n", vrf
->name
);
10056 if (src_ip
&& grp_ip
)
10057 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
10059 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
10061 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
10064 vty_out(vty
, "}\n");
10066 return CMD_SUCCESS
;
10069 struct pim_sg_cache_walk_data
{
10072 json_object
*json_group
;
10073 struct in_addr addr
;
10077 static void pim_show_vxlan_sg_entry(struct pim_vxlan_sg
*vxlan_sg
,
10078 struct pim_sg_cache_walk_data
*cwd
)
10080 struct vty
*vty
= cwd
->vty
;
10081 json_object
*json
= cwd
->json
;
10082 char src_str
[INET_ADDRSTRLEN
];
10083 char grp_str
[INET_ADDRSTRLEN
];
10084 json_object
*json_row
;
10085 bool installed
= (vxlan_sg
->up
) ? true : false;
10086 const char *iif_name
= vxlan_sg
->iif
?vxlan_sg
->iif
->name
:"-";
10087 const char *oif_name
;
10089 if (pim_vxlan_is_orig_mroute(vxlan_sg
))
10090 oif_name
= vxlan_sg
->orig_oif
?vxlan_sg
->orig_oif
->name
:"";
10092 oif_name
= vxlan_sg
->term_oif
?vxlan_sg
->term_oif
->name
:"";
10094 if (cwd
->addr_match
&& (vxlan_sg
->sg
.src
.s_addr
!= cwd
->addr
.s_addr
) &&
10095 (vxlan_sg
->sg
.grp
.s_addr
!= cwd
->addr
.s_addr
)) {
10098 pim_inet4_dump("<src?>", vxlan_sg
->sg
.src
, src_str
, sizeof(src_str
));
10099 pim_inet4_dump("<grp?>", vxlan_sg
->sg
.grp
, grp_str
, sizeof(grp_str
));
10101 json_object_object_get_ex(json
, grp_str
, &cwd
->json_group
);
10103 if (!cwd
->json_group
) {
10104 cwd
->json_group
= json_object_new_object();
10105 json_object_object_add(json
, grp_str
,
10109 json_row
= json_object_new_object();
10110 json_object_string_add(json_row
, "source", src_str
);
10111 json_object_string_add(json_row
, "group", grp_str
);
10112 json_object_string_add(json_row
, "input", iif_name
);
10113 json_object_string_add(json_row
, "output", oif_name
);
10115 json_object_boolean_true_add(json_row
, "installed");
10117 json_object_boolean_false_add(json_row
, "installed");
10118 json_object_object_add(cwd
->json_group
, src_str
, json_row
);
10120 vty_out(vty
, "%-15s %-15s %-15s %-15s %-5s\n",
10121 src_str
, grp_str
, iif_name
, oif_name
,
10126 static void pim_show_vxlan_sg_hash_entry(struct hash_backet
*backet
, void *arg
)
10128 pim_show_vxlan_sg_entry((struct pim_vxlan_sg
*)backet
->data
,
10129 (struct pim_sg_cache_walk_data
*)arg
);
10132 static void pim_show_vxlan_sg(struct pim_instance
*pim
,
10133 struct vty
*vty
, bool uj
)
10135 json_object
*json
= NULL
;
10136 struct pim_sg_cache_walk_data cwd
;
10139 json
= json_object_new_object();
10141 vty_out(vty
, "Codes: I -> installed\n");
10143 "Source Group Input Output Flags\n");
10146 memset(&cwd
, 0, sizeof(cwd
));
10149 hash_iterate(pim
->vxlan
.sg_hash
, pim_show_vxlan_sg_hash_entry
, &cwd
);
10152 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10153 json
, JSON_C_TO_STRING_PRETTY
));
10154 json_object_free(json
);
10158 static void pim_show_vxlan_sg_match_addr(struct pim_instance
*pim
,
10159 struct vty
*vty
, char *addr_str
, bool uj
)
10161 json_object
*json
= NULL
;
10162 struct pim_sg_cache_walk_data cwd
;
10165 memset(&cwd
, 0, sizeof(cwd
));
10166 result
= inet_pton(AF_INET
, addr_str
, &cwd
.addr
);
10168 vty_out(vty
, "Bad address %s: errno=%d: %s\n", addr_str
,
10169 errno
, safe_strerror(errno
));
10174 json
= json_object_new_object();
10176 vty_out(vty
, "Codes: I -> installed\n");
10178 "Source Group Input Output Flags\n");
10183 cwd
.addr_match
= true;
10184 hash_iterate(pim
->vxlan
.sg_hash
, pim_show_vxlan_sg_hash_entry
, &cwd
);
10187 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10188 json
, JSON_C_TO_STRING_PRETTY
));
10189 json_object_free(json
);
10193 static void pim_show_vxlan_sg_one(struct pim_instance
*pim
,
10194 struct vty
*vty
, char *src_str
, char *grp_str
, bool uj
)
10196 json_object
*json
= NULL
;
10197 struct prefix_sg sg
;
10199 struct pim_vxlan_sg
*vxlan_sg
;
10200 const char *iif_name
;
10202 const char *oif_name
;
10204 result
= inet_pton(AF_INET
, src_str
, &sg
.src
);
10206 vty_out(vty
, "Bad src address %s: errno=%d: %s\n", src_str
,
10207 errno
, safe_strerror(errno
));
10210 result
= inet_pton(AF_INET
, grp_str
, &sg
.grp
);
10212 vty_out(vty
, "Bad grp address %s: errno=%d: %s\n", grp_str
,
10213 errno
, safe_strerror(errno
));
10217 sg
.family
= AF_INET
;
10218 sg
.prefixlen
= IPV4_MAX_BITLEN
;
10220 json
= json_object_new_object();
10222 vxlan_sg
= pim_vxlan_sg_find(pim
, &sg
);
10224 installed
= (vxlan_sg
->up
) ? true : false;
10225 iif_name
= vxlan_sg
->iif
?vxlan_sg
->iif
->name
:"-";
10227 if (pim_vxlan_is_orig_mroute(vxlan_sg
))
10229 vxlan_sg
->orig_oif
?vxlan_sg
->orig_oif
->name
:"";
10232 vxlan_sg
->term_oif
?vxlan_sg
->term_oif
->name
:"";
10235 json_object_string_add(json
, "source", src_str
);
10236 json_object_string_add(json
, "group", grp_str
);
10237 json_object_string_add(json
, "input", iif_name
);
10238 json_object_string_add(json
, "output", oif_name
);
10240 json_object_boolean_true_add(json
, "installed");
10242 json_object_boolean_false_add(json
,
10245 vty_out(vty
, "SG : %s\n", vxlan_sg
->sg_str
);
10246 vty_out(vty
, " Input : %s\n", iif_name
);
10247 vty_out(vty
, " Output : %s\n", oif_name
);
10248 vty_out(vty
, " installed : %s\n",
10249 installed
?"yes":"no");
10254 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10255 json
, JSON_C_TO_STRING_PRETTY
));
10256 json_object_free(json
);
10260 DEFUN (show_ip_pim_vxlan_sg
,
10261 show_ip_pim_vxlan_sg_cmd
,
10262 "show ip pim [vrf NAME] vxlan-groups [A.B.C.D [A.B.C.D]] [json]",
10267 "VxLAN BUM groups\n"
10268 "source or group ip\n"
10272 bool uj
= use_json(argc
, argv
);
10276 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10279 return CMD_WARNING
;
10281 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ?
10282 argv
[idx
++]->arg
:NULL
;
10283 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
) ?
10284 argv
[idx
]->arg
:NULL
;
10286 if (src_ip
&& grp_ip
)
10287 pim_show_vxlan_sg_one(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
10289 pim_show_vxlan_sg_match_addr(vrf
->info
, vty
, src_ip
, uj
);
10291 pim_show_vxlan_sg(vrf
->info
, vty
, uj
);
10293 return CMD_SUCCESS
;
10296 static void pim_show_vxlan_sg_work(struct pim_instance
*pim
,
10297 struct vty
*vty
, bool uj
)
10299 json_object
*json
= NULL
;
10300 struct pim_sg_cache_walk_data cwd
;
10301 struct listnode
*node
;
10302 struct pim_vxlan_sg
*vxlan_sg
;
10305 json
= json_object_new_object();
10307 vty_out(vty
, "Codes: I -> installed\n");
10309 "Source Group Input Flags\n");
10312 memset(&cwd
, 0, sizeof(cwd
));
10315 for (ALL_LIST_ELEMENTS_RO(pim_vxlan_p
->work_list
, node
, vxlan_sg
))
10316 pim_show_vxlan_sg_entry(vxlan_sg
, &cwd
);
10319 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10320 json
, JSON_C_TO_STRING_PRETTY
));
10321 json_object_free(json
);
10325 DEFUN_HIDDEN (show_ip_pim_vxlan_sg_work
,
10326 show_ip_pim_vxlan_sg_work_cmd
,
10327 "show ip pim [vrf NAME] vxlan-work [json]",
10332 "VxLAN work list\n"
10335 bool uj
= use_json(argc
, argv
);
10339 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10342 return CMD_WARNING
;
10344 pim_show_vxlan_sg_work(vrf
->info
, vty
, uj
);
10346 return CMD_SUCCESS
;
10349 DEFUN_HIDDEN (no_ip_pim_mlag
,
10350 no_ip_pim_mlag_cmd
,
10357 struct in_addr addr
;
10360 pim_vxlan_mlag_update(true/*mlag_enable*/,
10361 false/*peer_state*/, PIM_VXLAN_MLAG_ROLE_SECONDARY
,
10362 NULL
/*peerlink*/, &addr
);
10364 return CMD_SUCCESS
;
10367 DEFUN_HIDDEN (ip_pim_mlag
,
10369 "ip pim mlag INTERFACE role [primary|secondary] state [up|down] addr A.B.C.D",
10373 "peerlink sub interface\n"
10375 "MLAG role primary\n"
10376 "MLAG role secondary\n"
10377 "peer session state\n"
10378 "peer session state up\n"
10379 "peer session state down\n"
10381 "unique ip address\n")
10383 struct interface
*ifp
;
10384 const char *peerlink
;
10389 struct in_addr reg_addr
;
10392 peerlink
= argv
[idx
]->arg
;
10393 ifp
= if_lookup_by_name(peerlink
, VRF_DEFAULT
);
10395 vty_out(vty
, "No such interface name %s\n", peerlink
);
10396 return CMD_WARNING
;
10400 if (!strcmp(argv
[idx
]->arg
, "primary")) {
10401 role
= PIM_VXLAN_MLAG_ROLE_PRIMARY
;
10402 } else if (!strcmp(argv
[idx
]->arg
, "secondary")) {
10403 role
= PIM_VXLAN_MLAG_ROLE_SECONDARY
;
10405 vty_out(vty
, "unknown MLAG role %s\n", argv
[idx
]->arg
);
10406 return CMD_WARNING
;
10410 if (!strcmp(argv
[idx
]->arg
, "up")) {
10412 } else if (strcmp(argv
[idx
]->arg
, "down")) {
10413 peer_state
= false;
10415 vty_out(vty
, "unknown MLAG state %s\n", argv
[idx
]->arg
);
10416 return CMD_WARNING
;
10420 result
= inet_pton(AF_INET
, argv
[idx
]->arg
, ®_addr
);
10422 vty_out(vty
, "%% Bad reg address %s: errno=%d: %s\n",
10424 errno
, safe_strerror(errno
));
10425 return CMD_WARNING_CONFIG_FAILED
;
10427 pim_vxlan_mlag_update(true, peer_state
, role
, ifp
, ®_addr
);
10429 return CMD_SUCCESS
;
10432 void pim_cmd_init(void)
10434 install_node(&interface_node
,
10435 pim_interface_config_write
); /* INTERFACE_NODE */
10438 install_node(&debug_node
, pim_debug_config_write
);
10440 install_element(ENABLE_NODE
, &pim_test_sg_keepalive_cmd
);
10442 install_element(CONFIG_NODE
, &ip_pim_rp_cmd
);
10443 install_element(VRF_NODE
, &ip_pim_rp_cmd
);
10444 install_element(CONFIG_NODE
, &no_ip_pim_rp_cmd
);
10445 install_element(VRF_NODE
, &no_ip_pim_rp_cmd
);
10446 install_element(CONFIG_NODE
, &ip_pim_rp_prefix_list_cmd
);
10447 install_element(VRF_NODE
, &ip_pim_rp_prefix_list_cmd
);
10448 install_element(CONFIG_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
10449 install_element(VRF_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
10450 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
10451 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
10452 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
10453 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
10454 install_element(CONFIG_NODE
, &ip_pim_ssm_prefix_list_cmd
);
10455 install_element(VRF_NODE
, &ip_pim_ssm_prefix_list_cmd
);
10456 install_element(CONFIG_NODE
, &ip_pim_register_suppress_cmd
);
10457 install_element(VRF_NODE
, &ip_pim_register_suppress_cmd
);
10458 install_element(CONFIG_NODE
, &no_ip_pim_register_suppress_cmd
);
10459 install_element(VRF_NODE
, &no_ip_pim_register_suppress_cmd
);
10460 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
10461 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
10462 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
10463 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
10464 install_element(CONFIG_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
10465 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
10466 install_element(CONFIG_NODE
,
10467 &no_ip_pim_spt_switchover_infinity_plist_cmd
);
10468 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_plist_cmd
);
10469 install_element(CONFIG_NODE
, &ip_pim_joinprune_time_cmd
);
10470 install_element(VRF_NODE
, &ip_pim_joinprune_time_cmd
);
10471 install_element(CONFIG_NODE
, &no_ip_pim_joinprune_time_cmd
);
10472 install_element(VRF_NODE
, &no_ip_pim_joinprune_time_cmd
);
10473 install_element(CONFIG_NODE
, &ip_pim_keep_alive_cmd
);
10474 install_element(VRF_NODE
, &ip_pim_keep_alive_cmd
);
10475 install_element(CONFIG_NODE
, &ip_pim_rp_keep_alive_cmd
);
10476 install_element(VRF_NODE
, &ip_pim_rp_keep_alive_cmd
);
10477 install_element(CONFIG_NODE
, &no_ip_pim_keep_alive_cmd
);
10478 install_element(VRF_NODE
, &no_ip_pim_keep_alive_cmd
);
10479 install_element(CONFIG_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
10480 install_element(VRF_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
10481 install_element(CONFIG_NODE
, &ip_pim_packets_cmd
);
10482 install_element(VRF_NODE
, &ip_pim_packets_cmd
);
10483 install_element(CONFIG_NODE
, &no_ip_pim_packets_cmd
);
10484 install_element(VRF_NODE
, &no_ip_pim_packets_cmd
);
10485 install_element(CONFIG_NODE
, &ip_pim_v6_secondary_cmd
);
10486 install_element(VRF_NODE
, &ip_pim_v6_secondary_cmd
);
10487 install_element(CONFIG_NODE
, &no_ip_pim_v6_secondary_cmd
);
10488 install_element(VRF_NODE
, &no_ip_pim_v6_secondary_cmd
);
10489 install_element(CONFIG_NODE
, &ip_ssmpingd_cmd
);
10490 install_element(VRF_NODE
, &ip_ssmpingd_cmd
);
10491 install_element(CONFIG_NODE
, &no_ip_ssmpingd_cmd
);
10492 install_element(VRF_NODE
, &no_ip_ssmpingd_cmd
);
10493 install_element(CONFIG_NODE
, &ip_msdp_peer_cmd
);
10494 install_element(VRF_NODE
, &ip_msdp_peer_cmd
);
10495 install_element(CONFIG_NODE
, &no_ip_msdp_peer_cmd
);
10496 install_element(VRF_NODE
, &no_ip_msdp_peer_cmd
);
10497 install_element(CONFIG_NODE
, &ip_pim_ecmp_cmd
);
10498 install_element(VRF_NODE
, &ip_pim_ecmp_cmd
);
10499 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_cmd
);
10500 install_element(VRF_NODE
, &no_ip_pim_ecmp_cmd
);
10501 install_element(CONFIG_NODE
, &ip_pim_ecmp_rebalance_cmd
);
10502 install_element(VRF_NODE
, &ip_pim_ecmp_rebalance_cmd
);
10503 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
10504 install_element(VRF_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
10505 install_element(CONFIG_NODE
, &ip_pim_mlag_cmd
);
10506 install_element(CONFIG_NODE
, &no_ip_pim_mlag_cmd
);
10508 install_element(INTERFACE_NODE
, &interface_ip_igmp_cmd
);
10509 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_cmd
);
10510 install_element(INTERFACE_NODE
, &interface_ip_igmp_join_cmd
);
10511 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_join_cmd
);
10512 install_element(INTERFACE_NODE
, &interface_ip_igmp_version_cmd
);
10513 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_version_cmd
);
10514 install_element(INTERFACE_NODE
, &interface_ip_igmp_query_interval_cmd
);
10515 install_element(INTERFACE_NODE
,
10516 &interface_no_ip_igmp_query_interval_cmd
);
10517 install_element(INTERFACE_NODE
,
10518 &interface_ip_igmp_query_max_response_time_cmd
);
10519 install_element(INTERFACE_NODE
,
10520 &interface_no_ip_igmp_query_max_response_time_cmd
);
10521 install_element(INTERFACE_NODE
,
10522 &interface_ip_igmp_query_max_response_time_dsec_cmd
);
10523 install_element(INTERFACE_NODE
,
10524 &interface_no_ip_igmp_query_max_response_time_dsec_cmd
);
10525 install_element(INTERFACE_NODE
,
10526 &interface_ip_igmp_last_member_query_count_cmd
);
10527 install_element(INTERFACE_NODE
,
10528 &interface_no_ip_igmp_last_member_query_count_cmd
);
10529 install_element(INTERFACE_NODE
,
10530 &interface_ip_igmp_last_member_query_interval_cmd
);
10531 install_element(INTERFACE_NODE
,
10532 &interface_no_ip_igmp_last_member_query_interval_cmd
);
10533 install_element(INTERFACE_NODE
, &interface_ip_pim_activeactive_cmd
);
10534 install_element(INTERFACE_NODE
, &interface_ip_pim_ssm_cmd
);
10535 install_element(INTERFACE_NODE
, &interface_no_ip_pim_ssm_cmd
);
10536 install_element(INTERFACE_NODE
, &interface_ip_pim_sm_cmd
);
10537 install_element(INTERFACE_NODE
, &interface_no_ip_pim_sm_cmd
);
10538 install_element(INTERFACE_NODE
, &interface_ip_pim_cmd
);
10539 install_element(INTERFACE_NODE
, &interface_no_ip_pim_cmd
);
10540 install_element(INTERFACE_NODE
, &interface_ip_pim_drprio_cmd
);
10541 install_element(INTERFACE_NODE
, &interface_no_ip_pim_drprio_cmd
);
10542 install_element(INTERFACE_NODE
, &interface_ip_pim_hello_cmd
);
10543 install_element(INTERFACE_NODE
, &interface_no_ip_pim_hello_cmd
);
10544 install_element(INTERFACE_NODE
, &interface_ip_pim_boundary_oil_cmd
);
10545 install_element(INTERFACE_NODE
, &interface_no_ip_pim_boundary_oil_cmd
);
10546 install_element(INTERFACE_NODE
, &interface_ip_igmp_query_generate_cmd
);
10548 // Static mroutes NEB
10549 install_element(INTERFACE_NODE
, &interface_ip_mroute_cmd
);
10550 install_element(INTERFACE_NODE
, &interface_ip_mroute_source_cmd
);
10551 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_cmd
);
10552 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_source_cmd
);
10554 install_element(VIEW_NODE
, &show_ip_igmp_interface_cmd
);
10555 install_element(VIEW_NODE
, &show_ip_igmp_interface_vrf_all_cmd
);
10556 install_element(VIEW_NODE
, &show_ip_igmp_join_cmd
);
10557 install_element(VIEW_NODE
, &show_ip_igmp_join_vrf_all_cmd
);
10558 install_element(VIEW_NODE
, &show_ip_igmp_groups_cmd
);
10559 install_element(VIEW_NODE
, &show_ip_igmp_groups_vrf_all_cmd
);
10560 install_element(VIEW_NODE
, &show_ip_igmp_groups_retransmissions_cmd
);
10561 install_element(VIEW_NODE
, &show_ip_igmp_sources_cmd
);
10562 install_element(VIEW_NODE
, &show_ip_igmp_sources_retransmissions_cmd
);
10563 install_element(VIEW_NODE
, &show_ip_igmp_statistics_cmd
);
10564 install_element(VIEW_NODE
, &show_ip_pim_assert_cmd
);
10565 install_element(VIEW_NODE
, &show_ip_pim_assert_internal_cmd
);
10566 install_element(VIEW_NODE
, &show_ip_pim_assert_metric_cmd
);
10567 install_element(VIEW_NODE
, &show_ip_pim_assert_winner_metric_cmd
);
10568 install_element(VIEW_NODE
, &show_ip_pim_interface_traffic_cmd
);
10569 install_element(VIEW_NODE
, &show_ip_pim_interface_cmd
);
10570 install_element(VIEW_NODE
, &show_ip_pim_interface_vrf_all_cmd
);
10571 install_element(VIEW_NODE
, &show_ip_pim_join_cmd
);
10572 install_element(VIEW_NODE
, &show_ip_pim_join_vrf_all_cmd
);
10573 install_element(VIEW_NODE
, &show_ip_pim_jp_agg_cmd
);
10574 install_element(VIEW_NODE
, &show_ip_pim_local_membership_cmd
);
10575 install_element(VIEW_NODE
, &show_ip_pim_neighbor_cmd
);
10576 install_element(VIEW_NODE
, &show_ip_pim_neighbor_vrf_all_cmd
);
10577 install_element(VIEW_NODE
, &show_ip_pim_rpf_cmd
);
10578 install_element(VIEW_NODE
, &show_ip_pim_rpf_vrf_all_cmd
);
10579 install_element(VIEW_NODE
, &show_ip_pim_secondary_cmd
);
10580 install_element(VIEW_NODE
, &show_ip_pim_state_cmd
);
10581 install_element(VIEW_NODE
, &show_ip_pim_state_vrf_all_cmd
);
10582 install_element(VIEW_NODE
, &show_ip_pim_upstream_cmd
);
10583 install_element(VIEW_NODE
, &show_ip_pim_upstream_vrf_all_cmd
);
10584 install_element(VIEW_NODE
, &show_ip_pim_channel_cmd
);
10585 install_element(VIEW_NODE
, &show_ip_pim_upstream_join_desired_cmd
);
10586 install_element(VIEW_NODE
, &show_ip_pim_upstream_rpf_cmd
);
10587 install_element(VIEW_NODE
, &show_ip_pim_rp_cmd
);
10588 install_element(VIEW_NODE
, &show_ip_pim_rp_vrf_all_cmd
);
10589 install_element(VIEW_NODE
, &show_ip_pim_bsr_cmd
);
10590 install_element(VIEW_NODE
, &show_ip_multicast_cmd
);
10591 install_element(VIEW_NODE
, &show_ip_multicast_vrf_all_cmd
);
10592 install_element(VIEW_NODE
, &show_ip_mroute_cmd
);
10593 install_element(VIEW_NODE
, &show_ip_mroute_vrf_all_cmd
);
10594 install_element(VIEW_NODE
, &show_ip_mroute_count_cmd
);
10595 install_element(VIEW_NODE
, &show_ip_mroute_count_vrf_all_cmd
);
10596 install_element(VIEW_NODE
, &show_ip_mroute_summary_cmd
);
10597 install_element(VIEW_NODE
, &show_ip_mroute_summary_vrf_all_cmd
);
10598 install_element(VIEW_NODE
, &show_ip_rib_cmd
);
10599 install_element(VIEW_NODE
, &show_ip_ssmpingd_cmd
);
10600 install_element(VIEW_NODE
, &show_debugging_pim_cmd
);
10601 install_element(VIEW_NODE
, &show_ip_pim_nexthop_cmd
);
10602 install_element(VIEW_NODE
, &show_ip_pim_nexthop_lookup_cmd
);
10603 install_element(VIEW_NODE
, &show_ip_pim_bsrp_cmd
);
10604 install_element(VIEW_NODE
, &show_ip_pim_bsm_db_cmd
);
10605 install_element(VIEW_NODE
, &show_ip_pim_statistics_cmd
);
10607 install_element(ENABLE_NODE
, &clear_ip_mroute_count_cmd
);
10608 install_element(ENABLE_NODE
, &clear_ip_interfaces_cmd
);
10609 install_element(ENABLE_NODE
, &clear_ip_igmp_interfaces_cmd
);
10610 install_element(ENABLE_NODE
, &clear_ip_mroute_cmd
);
10611 install_element(ENABLE_NODE
, &clear_ip_pim_interfaces_cmd
);
10612 install_element(ENABLE_NODE
, &clear_ip_pim_interface_traffic_cmd
);
10613 install_element(ENABLE_NODE
, &clear_ip_pim_oil_cmd
);
10614 install_element(ENABLE_NODE
, &clear_ip_pim_statistics_cmd
);
10616 install_element(ENABLE_NODE
, &debug_igmp_cmd
);
10617 install_element(ENABLE_NODE
, &no_debug_igmp_cmd
);
10618 install_element(ENABLE_NODE
, &debug_igmp_events_cmd
);
10619 install_element(ENABLE_NODE
, &no_debug_igmp_events_cmd
);
10620 install_element(ENABLE_NODE
, &debug_igmp_packets_cmd
);
10621 install_element(ENABLE_NODE
, &no_debug_igmp_packets_cmd
);
10622 install_element(ENABLE_NODE
, &debug_igmp_trace_cmd
);
10623 install_element(ENABLE_NODE
, &no_debug_igmp_trace_cmd
);
10624 install_element(ENABLE_NODE
, &debug_mroute_cmd
);
10625 install_element(ENABLE_NODE
, &debug_mroute_detail_cmd
);
10626 install_element(ENABLE_NODE
, &no_debug_mroute_cmd
);
10627 install_element(ENABLE_NODE
, &no_debug_mroute_detail_cmd
);
10628 install_element(ENABLE_NODE
, &debug_pim_static_cmd
);
10629 install_element(ENABLE_NODE
, &no_debug_pim_static_cmd
);
10630 install_element(ENABLE_NODE
, &debug_pim_cmd
);
10631 install_element(ENABLE_NODE
, &no_debug_pim_cmd
);
10632 install_element(ENABLE_NODE
, &debug_pim_nht_cmd
);
10633 install_element(ENABLE_NODE
, &no_debug_pim_nht_cmd
);
10634 install_element(ENABLE_NODE
, &debug_pim_nht_rp_cmd
);
10635 install_element(ENABLE_NODE
, &no_debug_pim_nht_rp_cmd
);
10636 install_element(ENABLE_NODE
, &debug_pim_events_cmd
);
10637 install_element(ENABLE_NODE
, &no_debug_pim_events_cmd
);
10638 install_element(ENABLE_NODE
, &debug_pim_packets_cmd
);
10639 install_element(ENABLE_NODE
, &no_debug_pim_packets_cmd
);
10640 install_element(ENABLE_NODE
, &debug_pim_packetdump_send_cmd
);
10641 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_send_cmd
);
10642 install_element(ENABLE_NODE
, &debug_pim_packetdump_recv_cmd
);
10643 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_recv_cmd
);
10644 install_element(ENABLE_NODE
, &debug_pim_trace_cmd
);
10645 install_element(ENABLE_NODE
, &no_debug_pim_trace_cmd
);
10646 install_element(ENABLE_NODE
, &debug_pim_trace_detail_cmd
);
10647 install_element(ENABLE_NODE
, &no_debug_pim_trace_detail_cmd
);
10648 install_element(ENABLE_NODE
, &debug_ssmpingd_cmd
);
10649 install_element(ENABLE_NODE
, &no_debug_ssmpingd_cmd
);
10650 install_element(ENABLE_NODE
, &debug_pim_zebra_cmd
);
10651 install_element(ENABLE_NODE
, &no_debug_pim_zebra_cmd
);
10652 install_element(ENABLE_NODE
, &debug_pim_mlag_cmd
);
10653 install_element(ENABLE_NODE
, &no_debug_pim_mlag_cmd
);
10654 install_element(ENABLE_NODE
, &debug_pim_vxlan_cmd
);
10655 install_element(ENABLE_NODE
, &no_debug_pim_vxlan_cmd
);
10656 install_element(ENABLE_NODE
, &debug_msdp_cmd
);
10657 install_element(ENABLE_NODE
, &no_debug_msdp_cmd
);
10658 install_element(ENABLE_NODE
, &debug_msdp_events_cmd
);
10659 install_element(ENABLE_NODE
, &no_debug_msdp_events_cmd
);
10660 install_element(ENABLE_NODE
, &debug_msdp_packets_cmd
);
10661 install_element(ENABLE_NODE
, &no_debug_msdp_packets_cmd
);
10662 install_element(ENABLE_NODE
, &debug_mtrace_cmd
);
10663 install_element(ENABLE_NODE
, &no_debug_mtrace_cmd
);
10664 install_element(ENABLE_NODE
, &debug_bsm_cmd
);
10665 install_element(ENABLE_NODE
, &no_debug_bsm_cmd
);
10667 install_element(CONFIG_NODE
, &debug_igmp_cmd
);
10668 install_element(CONFIG_NODE
, &no_debug_igmp_cmd
);
10669 install_element(CONFIG_NODE
, &debug_igmp_events_cmd
);
10670 install_element(CONFIG_NODE
, &no_debug_igmp_events_cmd
);
10671 install_element(CONFIG_NODE
, &debug_igmp_packets_cmd
);
10672 install_element(CONFIG_NODE
, &no_debug_igmp_packets_cmd
);
10673 install_element(CONFIG_NODE
, &debug_igmp_trace_cmd
);
10674 install_element(CONFIG_NODE
, &no_debug_igmp_trace_cmd
);
10675 install_element(CONFIG_NODE
, &debug_mroute_cmd
);
10676 install_element(CONFIG_NODE
, &debug_mroute_detail_cmd
);
10677 install_element(CONFIG_NODE
, &no_debug_mroute_cmd
);
10678 install_element(CONFIG_NODE
, &no_debug_mroute_detail_cmd
);
10679 install_element(CONFIG_NODE
, &debug_pim_static_cmd
);
10680 install_element(CONFIG_NODE
, &no_debug_pim_static_cmd
);
10681 install_element(CONFIG_NODE
, &debug_pim_cmd
);
10682 install_element(CONFIG_NODE
, &no_debug_pim_cmd
);
10683 install_element(CONFIG_NODE
, &debug_pim_nht_cmd
);
10684 install_element(CONFIG_NODE
, &no_debug_pim_nht_cmd
);
10685 install_element(CONFIG_NODE
, &debug_pim_nht_rp_cmd
);
10686 install_element(CONFIG_NODE
, &no_debug_pim_nht_rp_cmd
);
10687 install_element(CONFIG_NODE
, &debug_pim_events_cmd
);
10688 install_element(CONFIG_NODE
, &no_debug_pim_events_cmd
);
10689 install_element(CONFIG_NODE
, &debug_pim_packets_cmd
);
10690 install_element(CONFIG_NODE
, &no_debug_pim_packets_cmd
);
10691 install_element(CONFIG_NODE
, &debug_pim_trace_cmd
);
10692 install_element(CONFIG_NODE
, &no_debug_pim_trace_cmd
);
10693 install_element(CONFIG_NODE
, &debug_pim_trace_detail_cmd
);
10694 install_element(CONFIG_NODE
, &no_debug_pim_trace_detail_cmd
);
10695 install_element(CONFIG_NODE
, &debug_ssmpingd_cmd
);
10696 install_element(CONFIG_NODE
, &no_debug_ssmpingd_cmd
);
10697 install_element(CONFIG_NODE
, &debug_pim_zebra_cmd
);
10698 install_element(CONFIG_NODE
, &no_debug_pim_zebra_cmd
);
10699 install_element(CONFIG_NODE
, &debug_pim_vxlan_cmd
);
10700 install_element(CONFIG_NODE
, &no_debug_pim_vxlan_cmd
);
10701 install_element(CONFIG_NODE
, &debug_msdp_cmd
);
10702 install_element(CONFIG_NODE
, &no_debug_msdp_cmd
);
10703 install_element(CONFIG_NODE
, &debug_msdp_events_cmd
);
10704 install_element(CONFIG_NODE
, &no_debug_msdp_events_cmd
);
10705 install_element(CONFIG_NODE
, &debug_msdp_packets_cmd
);
10706 install_element(CONFIG_NODE
, &no_debug_msdp_packets_cmd
);
10707 install_element(CONFIG_NODE
, &debug_mtrace_cmd
);
10708 install_element(CONFIG_NODE
, &no_debug_mtrace_cmd
);
10709 install_element(CONFIG_NODE
, &debug_bsm_cmd
);
10710 install_element(CONFIG_NODE
, &no_debug_bsm_cmd
);
10712 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_member_cmd
);
10713 install_element(VRF_NODE
, &ip_msdp_mesh_group_member_cmd
);
10714 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
10715 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
10716 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_source_cmd
);
10717 install_element(VRF_NODE
, &ip_msdp_mesh_group_source_cmd
);
10718 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
10719 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
10720 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_cmd
);
10721 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_vrf_all_cmd
);
10722 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_cmd
);
10723 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_vrf_all_cmd
);
10724 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_cmd
);
10725 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_vrf_all_cmd
);
10726 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_cmd
);
10727 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_vrf_all_cmd
);
10728 install_element(VIEW_NODE
, &show_ip_pim_ssm_range_cmd
);
10729 install_element(VIEW_NODE
, &show_ip_pim_group_type_cmd
);
10730 install_element(VIEW_NODE
, &show_ip_pim_vxlan_sg_cmd
);
10731 install_element(VIEW_NODE
, &show_ip_pim_vxlan_sg_work_cmd
);
10732 install_element(INTERFACE_NODE
, &interface_pim_use_source_cmd
);
10733 install_element(INTERFACE_NODE
, &interface_no_pim_use_source_cmd
);
10734 /* Install BSM command */
10735 install_element(INTERFACE_NODE
, &ip_pim_bsm_cmd
);
10736 install_element(INTERFACE_NODE
, &no_ip_pim_bsm_cmd
);
10737 install_element(INTERFACE_NODE
, &ip_pim_ucast_bsm_cmd
);
10738 install_element(INTERFACE_NODE
, &no_ip_pim_ucast_bsm_cmd
);
10739 /* Install BFD command */
10740 install_element(INTERFACE_NODE
, &ip_pim_bfd_cmd
);
10741 install_element(INTERFACE_NODE
, &ip_pim_bfd_param_cmd
);
10742 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_cmd
);
10744 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_param_cmd
);
10745 #endif /* !HAVE_BFDD */