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 source_str
= argv
[idx_ipv4_2
]->arg
;
6945 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
6947 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
6948 source_str
, errno
, safe_strerror(errno
));
6949 return CMD_WARNING_CONFIG_FAILED
;
6952 CMD_FERR_RETURN(pim_if_igmp_join_add(ifp
, group_addr
, source_addr
),
6953 "Failure joining IGMP group: $ERR");
6958 DEFUN (interface_no_ip_igmp_join
,
6959 interface_no_ip_igmp_join_cmd
,
6960 "no ip igmp join A.B.C.D A.B.C.D",
6964 "IGMP join multicast group\n"
6965 "Multicast group address\n"
6968 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6971 const char *group_str
;
6972 const char *source_str
;
6973 struct in_addr group_addr
;
6974 struct in_addr source_addr
;
6978 group_str
= argv
[idx_ipv4
]->arg
;
6979 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
6981 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
6982 errno
, safe_strerror(errno
));
6983 return CMD_WARNING_CONFIG_FAILED
;
6986 /* Source address */
6987 source_str
= argv
[idx_ipv4_2
]->arg
;
6988 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
6990 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
6991 source_str
, errno
, safe_strerror(errno
));
6992 return CMD_WARNING_CONFIG_FAILED
;
6995 result
= pim_if_igmp_join_del(ifp
, group_addr
, source_addr
);
6998 "%% Failure leaving IGMP group %s source %s on interface %s: %d\n",
6999 group_str
, source_str
, ifp
->name
, result
);
7000 return CMD_WARNING_CONFIG_FAILED
;
7007 CLI reconfiguration affects the interface level (struct pim_interface).
7008 This function propagates the reconfiguration to every active socket
7011 static void igmp_sock_query_interval_reconfig(struct igmp_sock
*igmp
)
7013 struct interface
*ifp
;
7014 struct pim_interface
*pim_ifp
;
7018 /* other querier present? */
7020 if (igmp
->t_other_querier_timer
)
7023 /* this is the querier */
7025 zassert(igmp
->interface
);
7026 zassert(igmp
->interface
->info
);
7028 ifp
= igmp
->interface
;
7029 pim_ifp
= ifp
->info
;
7031 if (PIM_DEBUG_IGMP_TRACE
) {
7032 char ifaddr_str
[INET_ADDRSTRLEN
];
7033 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
7034 sizeof(ifaddr_str
));
7035 zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
7036 __PRETTY_FUNCTION__
, ifaddr_str
, ifp
->name
,
7037 pim_ifp
->igmp_default_query_interval
);
7041 igmp_startup_mode_on() will reset QQI:
7043 igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
7045 igmp_startup_mode_on(igmp
);
7048 static void igmp_sock_query_reschedule(struct igmp_sock
*igmp
)
7050 if (igmp
->t_igmp_query_timer
) {
7051 /* other querier present */
7052 zassert(igmp
->t_igmp_query_timer
);
7053 zassert(!igmp
->t_other_querier_timer
);
7055 pim_igmp_general_query_off(igmp
);
7056 pim_igmp_general_query_on(igmp
);
7058 zassert(igmp
->t_igmp_query_timer
);
7059 zassert(!igmp
->t_other_querier_timer
);
7061 /* this is the querier */
7063 zassert(!igmp
->t_igmp_query_timer
);
7064 zassert(igmp
->t_other_querier_timer
);
7066 pim_igmp_other_querier_timer_off(igmp
);
7067 pim_igmp_other_querier_timer_on(igmp
);
7069 zassert(!igmp
->t_igmp_query_timer
);
7070 zassert(igmp
->t_other_querier_timer
);
7074 static void change_query_interval(struct pim_interface
*pim_ifp
,
7077 struct listnode
*sock_node
;
7078 struct igmp_sock
*igmp
;
7080 pim_ifp
->igmp_default_query_interval
= query_interval
;
7082 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
7083 igmp_sock_query_interval_reconfig(igmp
);
7084 igmp_sock_query_reschedule(igmp
);
7088 static void change_query_max_response_time(struct pim_interface
*pim_ifp
,
7089 int query_max_response_time_dsec
)
7091 struct listnode
*sock_node
;
7092 struct igmp_sock
*igmp
;
7094 pim_ifp
->igmp_query_max_response_time_dsec
=
7095 query_max_response_time_dsec
;
7098 Below we modify socket/group/source timers in order to quickly
7099 reflect the change. Otherwise, those timers would eventually catch
7103 /* scan all sockets */
7104 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
7105 struct listnode
*grp_node
;
7106 struct igmp_group
*grp
;
7108 /* reschedule socket general query */
7109 igmp_sock_query_reschedule(igmp
);
7111 /* scan socket groups */
7112 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grp_node
,
7114 struct listnode
*src_node
;
7115 struct igmp_source
*src
;
7117 /* reset group timers for groups in EXCLUDE mode */
7118 if (grp
->group_filtermode_isexcl
) {
7119 igmp_group_reset_gmi(grp
);
7122 /* scan group sources */
7123 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
,
7126 /* reset source timers for sources with running
7128 if (src
->t_source_timer
) {
7129 igmp_source_reset_gmi(igmp
, grp
, src
);
7136 #define IGMP_QUERY_INTERVAL_MIN (1)
7137 #define IGMP_QUERY_INTERVAL_MAX (1800)
7139 DEFUN (interface_ip_igmp_query_interval
,
7140 interface_ip_igmp_query_interval_cmd
,
7141 "ip igmp query-interval (1-1800)",
7144 IFACE_IGMP_QUERY_INTERVAL_STR
7145 "Query interval in seconds\n")
7147 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7148 struct pim_interface
*pim_ifp
= ifp
->info
;
7150 int query_interval_dsec
;
7154 ret
= pim_cmd_igmp_start(vty
, ifp
);
7155 if (ret
!= CMD_SUCCESS
)
7157 pim_ifp
= ifp
->info
;
7160 query_interval
= atoi(argv
[3]->arg
);
7161 query_interval_dsec
= 10 * query_interval
;
7164 It seems we don't need to check bounds since command.c does it
7165 already, but we verify them anyway for extra safety.
7167 if (query_interval
< IGMP_QUERY_INTERVAL_MIN
) {
7169 "General query interval %d lower than minimum %d\n",
7170 query_interval
, IGMP_QUERY_INTERVAL_MIN
);
7171 return CMD_WARNING_CONFIG_FAILED
;
7173 if (query_interval
> IGMP_QUERY_INTERVAL_MAX
) {
7175 "General query interval %d higher than maximum %d\n",
7176 query_interval
, IGMP_QUERY_INTERVAL_MAX
);
7177 return CMD_WARNING_CONFIG_FAILED
;
7180 if (query_interval_dsec
<= pim_ifp
->igmp_query_max_response_time_dsec
) {
7182 "Can't set general query interval %d dsec <= query max response time %d dsec.\n",
7183 query_interval_dsec
,
7184 pim_ifp
->igmp_query_max_response_time_dsec
);
7185 return CMD_WARNING_CONFIG_FAILED
;
7188 change_query_interval(pim_ifp
, query_interval
);
7193 DEFUN (interface_no_ip_igmp_query_interval
,
7194 interface_no_ip_igmp_query_interval_cmd
,
7195 "no ip igmp query-interval",
7199 IFACE_IGMP_QUERY_INTERVAL_STR
)
7201 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7202 struct pim_interface
*pim_ifp
= ifp
->info
;
7203 int default_query_interval_dsec
;
7208 default_query_interval_dsec
= IGMP_GENERAL_QUERY_INTERVAL
* 10;
7210 if (default_query_interval_dsec
7211 <= pim_ifp
->igmp_query_max_response_time_dsec
) {
7213 "Can't set default general query interval %d dsec <= query max response time %d dsec.\n",
7214 default_query_interval_dsec
,
7215 pim_ifp
->igmp_query_max_response_time_dsec
);
7216 return CMD_WARNING_CONFIG_FAILED
;
7219 change_query_interval(pim_ifp
, IGMP_GENERAL_QUERY_INTERVAL
);
7224 DEFUN (interface_ip_igmp_version
,
7225 interface_ip_igmp_version_cmd
,
7226 "ip igmp version (2-3)",
7230 "IGMP version number\n")
7232 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7233 struct pim_interface
*pim_ifp
= ifp
->info
;
7234 int igmp_version
, old_version
= 0;
7238 ret
= pim_cmd_igmp_start(vty
, ifp
);
7239 if (ret
!= CMD_SUCCESS
)
7241 pim_ifp
= ifp
->info
;
7244 igmp_version
= atoi(argv
[3]->arg
);
7245 old_version
= pim_ifp
->igmp_version
;
7246 pim_ifp
->igmp_version
= igmp_version
;
7248 // Check if IGMP is Enabled otherwise, enable on interface
7249 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
7250 PIM_IF_DO_IGMP(pim_ifp
->options
);
7251 pim_if_addr_add_all(ifp
);
7252 pim_if_membership_refresh(ifp
);
7253 old_version
= igmp_version
;
7254 // avoid refreshing membership again.
7256 /* Current and new version is different refresh existing
7257 membership. Going from 3 -> 2 or 2 -> 3. */
7258 if (old_version
!= igmp_version
)
7259 pim_if_membership_refresh(ifp
);
7264 DEFUN (interface_no_ip_igmp_version
,
7265 interface_no_ip_igmp_version_cmd
,
7266 "no ip igmp version (2-3)",
7271 "IGMP version number\n")
7273 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7274 struct pim_interface
*pim_ifp
= ifp
->info
;
7279 pim_ifp
->igmp_version
= IGMP_DEFAULT_VERSION
;
7284 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
7285 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
7287 DEFUN (interface_ip_igmp_query_max_response_time
,
7288 interface_ip_igmp_query_max_response_time_cmd
,
7289 "ip igmp query-max-response-time (10-250)",
7292 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
7293 "Query response value in deci-seconds\n")
7295 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7296 struct pim_interface
*pim_ifp
= ifp
->info
;
7297 int query_max_response_time
;
7301 ret
= pim_cmd_igmp_start(vty
, ifp
);
7302 if (ret
!= CMD_SUCCESS
)
7304 pim_ifp
= ifp
->info
;
7307 query_max_response_time
= atoi(argv
[3]->arg
);
7309 if (query_max_response_time
7310 >= pim_ifp
->igmp_default_query_interval
* 10) {
7312 "Can't set query max response time %d sec >= general query interval %d sec\n",
7313 query_max_response_time
,
7314 pim_ifp
->igmp_default_query_interval
);
7315 return CMD_WARNING_CONFIG_FAILED
;
7318 change_query_max_response_time(pim_ifp
, query_max_response_time
);
7323 DEFUN (interface_no_ip_igmp_query_max_response_time
,
7324 interface_no_ip_igmp_query_max_response_time_cmd
,
7325 "no ip igmp query-max-response-time (10-250)",
7329 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
7330 "Time for response in deci-seconds\n")
7332 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7333 struct pim_interface
*pim_ifp
= ifp
->info
;
7338 change_query_max_response_time(pim_ifp
,
7339 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
7344 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
7345 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
7347 DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec
,
7348 interface_ip_igmp_query_max_response_time_dsec_cmd
,
7349 "ip igmp query-max-response-time-dsec (10-250)",
7352 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
7353 "Query response value in deciseconds\n")
7355 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7356 struct pim_interface
*pim_ifp
= ifp
->info
;
7357 int query_max_response_time_dsec
;
7358 int default_query_interval_dsec
;
7362 ret
= pim_cmd_igmp_start(vty
, ifp
);
7363 if (ret
!= CMD_SUCCESS
)
7365 pim_ifp
= ifp
->info
;
7368 query_max_response_time_dsec
= atoi(argv
[4]->arg
);
7370 default_query_interval_dsec
= 10 * pim_ifp
->igmp_default_query_interval
;
7372 if (query_max_response_time_dsec
>= default_query_interval_dsec
) {
7374 "Can't set query max response time %d dsec >= general query interval %d dsec\n",
7375 query_max_response_time_dsec
,
7376 default_query_interval_dsec
);
7377 return CMD_WARNING_CONFIG_FAILED
;
7380 change_query_max_response_time(pim_ifp
, query_max_response_time_dsec
);
7385 DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec
,
7386 interface_no_ip_igmp_query_max_response_time_dsec_cmd
,
7387 "no ip igmp query-max-response-time-dsec",
7391 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
)
7393 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7394 struct pim_interface
*pim_ifp
= ifp
->info
;
7399 change_query_max_response_time(pim_ifp
,
7400 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
7405 #define IGMP_LAST_MEMBER_QUERY_COUNT_MIN (1)
7406 #define IGMP_LAST_MEMBER_QUERY_COUNT_MAX (7)
7408 DEFUN (interface_ip_igmp_last_member_query_count
,
7409 interface_ip_igmp_last_member_query_count_cmd
,
7410 "ip igmp last-member-query-count (1-7)",
7413 IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR
7414 "Last member query count\n")
7416 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7417 struct pim_interface
*pim_ifp
= ifp
->info
;
7418 int last_member_query_count
;
7422 ret
= pim_cmd_igmp_start(vty
, ifp
);
7423 if (ret
!= CMD_SUCCESS
)
7425 pim_ifp
= ifp
->info
;
7428 last_member_query_count
= atoi(argv
[3]->arg
);
7430 pim_ifp
->igmp_last_member_query_count
= last_member_query_count
;
7435 DEFUN (interface_no_ip_igmp_last_member_query_count
,
7436 interface_no_ip_igmp_last_member_query_count_cmd
,
7437 "no ip igmp last-member-query-count",
7441 IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR
)
7443 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7444 struct pim_interface
*pim_ifp
= ifp
->info
;
7449 pim_ifp
->igmp_last_member_query_count
=
7450 IGMP_DEFAULT_ROBUSTNESS_VARIABLE
;
7455 #define IGMP_LAST_MEMBER_QUERY_INTERVAL_MIN (1)
7456 #define IGMP_LAST_MEMBER_QUERY_INTERVAL_MAX (255)
7458 DEFUN (interface_ip_igmp_last_member_query_interval
,
7459 interface_ip_igmp_last_member_query_interval_cmd
,
7460 "ip igmp last-member-query-interval (1-255)",
7463 IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR
7464 "Last member query interval in deciseconds\n")
7466 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7467 struct pim_interface
*pim_ifp
= ifp
->info
;
7468 int last_member_query_interval
;
7472 ret
= pim_cmd_igmp_start(vty
, ifp
);
7473 if (ret
!= CMD_SUCCESS
)
7475 pim_ifp
= ifp
->info
;
7478 last_member_query_interval
= atoi(argv
[3]->arg
);
7479 pim_ifp
->igmp_specific_query_max_response_time_dsec
7480 = last_member_query_interval
;
7485 DEFUN (interface_no_ip_igmp_last_member_query_interval
,
7486 interface_no_ip_igmp_last_member_query_interval_cmd
,
7487 "no ip igmp last-member-query-interval",
7491 IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR
)
7493 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7494 struct pim_interface
*pim_ifp
= ifp
->info
;
7499 pim_ifp
->igmp_specific_query_max_response_time_dsec
=
7500 IGMP_SPECIFIC_QUERY_MAX_RESPONSE_TIME_DSEC
;
7505 DEFUN (interface_ip_pim_drprio
,
7506 interface_ip_pim_drprio_cmd
,
7507 "ip pim drpriority (1-4294967295)",
7510 "Set the Designated Router Election Priority\n"
7511 "Value of the new DR Priority\n")
7513 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7515 struct pim_interface
*pim_ifp
= ifp
->info
;
7516 uint32_t old_dr_prio
;
7519 vty_out(vty
, "Please enable PIM on interface, first\n");
7520 return CMD_WARNING_CONFIG_FAILED
;
7523 old_dr_prio
= pim_ifp
->pim_dr_priority
;
7525 pim_ifp
->pim_dr_priority
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
7527 if (old_dr_prio
!= pim_ifp
->pim_dr_priority
) {
7528 pim_if_dr_election(ifp
);
7529 pim_hello_restart_now(ifp
);
7535 DEFUN (interface_no_ip_pim_drprio
,
7536 interface_no_ip_pim_drprio_cmd
,
7537 "no ip pim drpriority [(1-4294967295)]",
7541 "Revert the Designated Router Priority to default\n"
7542 "Old Value of the Priority\n")
7544 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7545 struct pim_interface
*pim_ifp
= ifp
->info
;
7548 vty_out(vty
, "Pim not enabled on this interface\n");
7549 return CMD_WARNING_CONFIG_FAILED
;
7552 if (pim_ifp
->pim_dr_priority
!= PIM_DEFAULT_DR_PRIORITY
) {
7553 pim_ifp
->pim_dr_priority
= PIM_DEFAULT_DR_PRIORITY
;
7554 pim_if_dr_election(ifp
);
7555 pim_hello_restart_now(ifp
);
7561 DEFPY_HIDDEN (interface_ip_igmp_query_generate
,
7562 interface_ip_igmp_query_generate_cmd
,
7563 "ip igmp generate-query-once [version (2-3)]",
7566 "Generate igmp general query once\n"
7568 "IGMP version number\n")
7570 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7571 int igmp_version
= 2;
7574 vty_out(vty
, "IGMP/PIM is not enabled on the interface %s\n",
7576 return CMD_WARNING_CONFIG_FAILED
;
7580 igmp_version
= atoi(argv
[4]->arg
);
7582 igmp_send_query_on_intf(ifp
, igmp_version
);
7587 static int pim_cmd_interface_add(struct interface
*ifp
)
7589 struct pim_interface
*pim_ifp
= ifp
->info
;
7592 pim_ifp
= pim_if_new(ifp
, false, true, false, false);
7594 PIM_IF_DO_PIM(pim_ifp
->options
);
7596 pim_if_addr_add_all(ifp
);
7597 pim_if_membership_refresh(ifp
);
7599 pim_if_create_pimreg(pim_ifp
->pim
);
7603 DEFPY_HIDDEN (pim_test_sg_keepalive
,
7604 pim_test_sg_keepalive_cmd
,
7605 "test pim [vrf NAME$name] keepalive-reset A.B.C.D$source A.B.C.D$group",
7609 "Reset the Keepalive Timer\n"
7610 "The Source we are resetting\n"
7611 "The Group we are resetting\n")
7613 struct pim_upstream
*up
;
7614 struct pim_instance
*pim
;
7615 struct prefix_sg sg
;
7621 pim
= pim_get_pim_instance(VRF_DEFAULT
);
7623 struct vrf
*vrf
= vrf_lookup_by_name(name
);
7626 vty_out(vty
, "%% Vrf specified: %s does not exist\n",
7631 pim
= pim_get_pim_instance(vrf
->vrf_id
);
7635 vty_out(vty
, "%% Unable to find pim instance\n");
7639 up
= pim_upstream_find(pim
, &sg
);
7641 vty_out(vty
, "%% Unable to find %s specified\n",
7642 pim_str_sg_dump(&sg
));
7646 vty_out(vty
, "Setting %s to current keep alive time: %d\n",
7647 pim_str_sg_dump(&sg
), pim
->keep_alive_time
);
7648 pim_upstream_keep_alive_timer_start(up
, pim
->keep_alive_time
);
7653 DEFPY_HIDDEN (interface_ip_pim_activeactive
,
7654 interface_ip_pim_activeactive_cmd
,
7655 "[no$no] ip pim active-active",
7659 "Mark interface as Active-Active for MLAG operations, Hidden because not finished yet\n")
7661 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7662 struct pim_interface
*pim_ifp
;
7664 if (!no
&& !pim_cmd_interface_add(ifp
)) {
7665 vty_out(vty
, "Could not enable PIM SM active-active on interface\n");
7666 return CMD_WARNING_CONFIG_FAILED
;
7669 pim_ifp
= ifp
->info
;
7671 pim_if_unconfigure_mlag_dualactive(pim_ifp
);
7673 pim_if_configure_mlag_dualactive(pim_ifp
);
7678 DEFUN_HIDDEN (interface_ip_pim_ssm
,
7679 interface_ip_pim_ssm_cmd
,
7685 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7687 if (!pim_cmd_interface_add(ifp
)) {
7688 vty_out(vty
, "Could not enable PIM SM on interface\n");
7689 return CMD_WARNING_CONFIG_FAILED
;
7693 "WARN: Enabled PIM SM on interface; configure PIM SSM "
7694 "range if needed\n");
7698 static int interface_ip_pim_helper(struct vty
*vty
)
7700 struct pim_interface
*pim_ifp
;
7702 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7704 if (!pim_cmd_interface_add(ifp
)) {
7705 vty_out(vty
, "Could not enable PIM SM on interface\n");
7706 return CMD_WARNING_CONFIG_FAILED
;
7709 pim_ifp
= ifp
->info
;
7711 pim_if_create_pimreg(pim_ifp
->pim
);
7716 DEFUN_HIDDEN (interface_ip_pim_sm
,
7717 interface_ip_pim_sm_cmd
,
7723 return interface_ip_pim_helper(vty
);
7726 DEFUN (interface_ip_pim
,
7727 interface_ip_pim_cmd
,
7732 return interface_ip_pim_helper(vty
);
7735 static int pim_cmd_interface_delete(struct interface
*ifp
)
7737 struct pim_interface
*pim_ifp
= ifp
->info
;
7742 PIM_IF_DONT_PIM(pim_ifp
->options
);
7744 pim_if_membership_clear(ifp
);
7747 pim_sock_delete() removes all neighbors from
7748 pim_ifp->pim_neighbor_list.
7750 pim_sock_delete(ifp
, "pim unconfigured on interface");
7752 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
7753 pim_if_addr_del_all(ifp
);
7760 static int interface_no_ip_pim_helper(struct vty
*vty
)
7762 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7763 if (!pim_cmd_interface_delete(ifp
)) {
7764 vty_out(vty
, "Unable to delete interface information\n");
7765 return CMD_WARNING_CONFIG_FAILED
;
7771 DEFUN_HIDDEN (interface_no_ip_pim_ssm
,
7772 interface_no_ip_pim_ssm_cmd
,
7779 return interface_no_ip_pim_helper(vty
);
7782 DEFUN_HIDDEN (interface_no_ip_pim_sm
,
7783 interface_no_ip_pim_sm_cmd
,
7790 return interface_no_ip_pim_helper(vty
);
7793 DEFUN (interface_no_ip_pim
,
7794 interface_no_ip_pim_cmd
,
7800 return interface_no_ip_pim_helper(vty
);
7804 DEFUN(interface_ip_pim_boundary_oil
,
7805 interface_ip_pim_boundary_oil_cmd
,
7806 "ip multicast boundary oil WORD",
7808 "Generic multicast configuration options\n"
7809 "Define multicast boundary\n"
7810 "Filter OIL by group using prefix list\n"
7811 "Prefix list to filter OIL with\n")
7813 VTY_DECLVAR_CONTEXT(interface
, iif
);
7814 struct pim_interface
*pim_ifp
;
7817 argv_find(argv
, argc
, "WORD", &idx
);
7819 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
7821 if (pim_ifp
->boundary_oil_plist
)
7822 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
7824 pim_ifp
->boundary_oil_plist
=
7825 XSTRDUP(MTYPE_PIM_INTERFACE
, argv
[idx
]->arg
);
7827 /* Interface will be pruned from OIL on next Join */
7831 DEFUN(interface_no_ip_pim_boundary_oil
,
7832 interface_no_ip_pim_boundary_oil_cmd
,
7833 "no ip multicast boundary oil [WORD]",
7836 "Generic multicast configuration options\n"
7837 "Define multicast boundary\n"
7838 "Filter OIL by group using prefix list\n"
7839 "Prefix list to filter OIL with\n")
7841 VTY_DECLVAR_CONTEXT(interface
, iif
);
7842 struct pim_interface
*pim_ifp
;
7845 argv_find(argv
, argc
, "WORD", &idx
);
7847 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
7849 if (pim_ifp
->boundary_oil_plist
)
7850 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
7855 DEFUN (interface_ip_mroute
,
7856 interface_ip_mroute_cmd
,
7857 "ip mroute INTERFACE A.B.C.D",
7859 "Add multicast route\n"
7860 "Outgoing interface name\n"
7863 VTY_DECLVAR_CONTEXT(interface
, iif
);
7864 struct pim_interface
*pim_ifp
;
7865 struct pim_instance
*pim
;
7866 int idx_interface
= 2;
7868 struct interface
*oif
;
7869 const char *oifname
;
7870 const char *grp_str
;
7871 struct in_addr grp_addr
;
7872 struct in_addr src_addr
;
7875 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
7878 oifname
= argv
[idx_interface
]->arg
;
7879 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
7881 vty_out(vty
, "No such interface name %s\n", oifname
);
7885 grp_str
= argv
[idx_ipv4
]->arg
;
7886 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
7888 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
7889 errno
, safe_strerror(errno
));
7893 src_addr
.s_addr
= INADDR_ANY
;
7895 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
7896 vty_out(vty
, "Failed to add route\n");
7903 DEFUN (interface_ip_mroute_source
,
7904 interface_ip_mroute_source_cmd
,
7905 "ip mroute INTERFACE A.B.C.D A.B.C.D",
7907 "Add multicast route\n"
7908 "Outgoing interface name\n"
7912 VTY_DECLVAR_CONTEXT(interface
, iif
);
7913 struct pim_interface
*pim_ifp
;
7914 struct pim_instance
*pim
;
7915 int idx_interface
= 2;
7918 struct interface
*oif
;
7919 const char *oifname
;
7920 const char *grp_str
;
7921 struct in_addr grp_addr
;
7922 const char *src_str
;
7923 struct in_addr src_addr
;
7926 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
7929 oifname
= argv
[idx_interface
]->arg
;
7930 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
7932 vty_out(vty
, "No such interface name %s\n", oifname
);
7936 grp_str
= argv
[idx_ipv4
]->arg
;
7937 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
7939 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
7940 errno
, safe_strerror(errno
));
7944 src_str
= argv
[idx_ipv4_2
]->arg
;
7945 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
7947 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
7948 errno
, safe_strerror(errno
));
7952 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
7953 vty_out(vty
, "Failed to add route\n");
7960 DEFUN (interface_no_ip_mroute
,
7961 interface_no_ip_mroute_cmd
,
7962 "no ip mroute INTERFACE A.B.C.D",
7965 "Add multicast route\n"
7966 "Outgoing interface name\n"
7969 VTY_DECLVAR_CONTEXT(interface
, iif
);
7970 struct pim_interface
*pim_ifp
;
7971 struct pim_instance
*pim
;
7972 int idx_interface
= 3;
7974 struct interface
*oif
;
7975 const char *oifname
;
7976 const char *grp_str
;
7977 struct in_addr grp_addr
;
7978 struct in_addr src_addr
;
7981 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
7984 oifname
= argv
[idx_interface
]->arg
;
7985 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
7987 vty_out(vty
, "No such interface name %s\n", oifname
);
7991 grp_str
= argv
[idx_ipv4
]->arg
;
7992 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
7994 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
7995 errno
, safe_strerror(errno
));
7999 src_addr
.s_addr
= INADDR_ANY
;
8001 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
8002 vty_out(vty
, "Failed to remove route\n");
8009 DEFUN (interface_no_ip_mroute_source
,
8010 interface_no_ip_mroute_source_cmd
,
8011 "no ip mroute INTERFACE A.B.C.D A.B.C.D",
8014 "Add multicast route\n"
8015 "Outgoing interface name\n"
8019 VTY_DECLVAR_CONTEXT(interface
, iif
);
8020 struct pim_interface
*pim_ifp
;
8021 struct pim_instance
*pim
;
8022 int idx_interface
= 3;
8025 struct interface
*oif
;
8026 const char *oifname
;
8027 const char *grp_str
;
8028 struct in_addr grp_addr
;
8029 const char *src_str
;
8030 struct in_addr src_addr
;
8033 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
8036 oifname
= argv
[idx_interface
]->arg
;
8037 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
8039 vty_out(vty
, "No such interface name %s\n", oifname
);
8043 grp_str
= argv
[idx_ipv4
]->arg
;
8044 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
8046 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
8047 errno
, safe_strerror(errno
));
8051 src_str
= argv
[idx_ipv4_2
]->arg
;
8052 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
8054 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
8055 errno
, safe_strerror(errno
));
8059 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
8060 vty_out(vty
, "Failed to remove route\n");
8067 DEFUN (interface_ip_pim_hello
,
8068 interface_ip_pim_hello_cmd
,
8069 "ip pim hello (1-180) [(1-180)]",
8073 IFACE_PIM_HELLO_TIME_STR
8074 IFACE_PIM_HELLO_HOLD_STR
)
8076 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8079 struct pim_interface
*pim_ifp
= ifp
->info
;
8082 if (!pim_cmd_interface_add(ifp
)) {
8083 vty_out(vty
, "Could not enable PIM SM on interface\n");
8084 return CMD_WARNING_CONFIG_FAILED
;
8088 pim_ifp
= ifp
->info
;
8089 pim_ifp
->pim_hello_period
= strtol(argv
[idx_time
]->arg
, NULL
, 10);
8091 if (argc
== idx_hold
+ 1)
8092 pim_ifp
->pim_default_holdtime
=
8093 strtol(argv
[idx_hold
]->arg
, NULL
, 10);
8098 DEFUN (interface_no_ip_pim_hello
,
8099 interface_no_ip_pim_hello_cmd
,
8100 "no ip pim hello [(1-180) (1-180)]",
8105 IFACE_PIM_HELLO_TIME_STR
8106 IFACE_PIM_HELLO_HOLD_STR
)
8108 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8109 struct pim_interface
*pim_ifp
= ifp
->info
;
8112 vty_out(vty
, "Pim not enabled on this interface\n");
8113 return CMD_WARNING_CONFIG_FAILED
;
8116 pim_ifp
->pim_hello_period
= PIM_DEFAULT_HELLO_PERIOD
;
8117 pim_ifp
->pim_default_holdtime
= -1;
8128 PIM_DO_DEBUG_IGMP_EVENTS
;
8129 PIM_DO_DEBUG_IGMP_PACKETS
;
8130 PIM_DO_DEBUG_IGMP_TRACE
;
8134 DEFUN (no_debug_igmp
,
8141 PIM_DONT_DEBUG_IGMP_EVENTS
;
8142 PIM_DONT_DEBUG_IGMP_PACKETS
;
8143 PIM_DONT_DEBUG_IGMP_TRACE
;
8148 DEFUN (debug_igmp_events
,
8149 debug_igmp_events_cmd
,
8150 "debug igmp events",
8153 DEBUG_IGMP_EVENTS_STR
)
8155 PIM_DO_DEBUG_IGMP_EVENTS
;
8159 DEFUN (no_debug_igmp_events
,
8160 no_debug_igmp_events_cmd
,
8161 "no debug igmp events",
8165 DEBUG_IGMP_EVENTS_STR
)
8167 PIM_DONT_DEBUG_IGMP_EVENTS
;
8172 DEFUN (debug_igmp_packets
,
8173 debug_igmp_packets_cmd
,
8174 "debug igmp packets",
8177 DEBUG_IGMP_PACKETS_STR
)
8179 PIM_DO_DEBUG_IGMP_PACKETS
;
8183 DEFUN (no_debug_igmp_packets
,
8184 no_debug_igmp_packets_cmd
,
8185 "no debug igmp packets",
8189 DEBUG_IGMP_PACKETS_STR
)
8191 PIM_DONT_DEBUG_IGMP_PACKETS
;
8196 DEFUN (debug_igmp_trace
,
8197 debug_igmp_trace_cmd
,
8201 DEBUG_IGMP_TRACE_STR
)
8203 PIM_DO_DEBUG_IGMP_TRACE
;
8207 DEFUN (no_debug_igmp_trace
,
8208 no_debug_igmp_trace_cmd
,
8209 "no debug igmp trace",
8213 DEBUG_IGMP_TRACE_STR
)
8215 PIM_DONT_DEBUG_IGMP_TRACE
;
8220 DEFUN (debug_mroute
,
8226 PIM_DO_DEBUG_MROUTE
;
8230 DEFUN (debug_mroute_detail
,
8231 debug_mroute_detail_cmd
,
8232 "debug mroute detail",
8237 PIM_DO_DEBUG_MROUTE_DETAIL
;
8241 DEFUN (no_debug_mroute
,
8242 no_debug_mroute_cmd
,
8248 PIM_DONT_DEBUG_MROUTE
;
8252 DEFUN (no_debug_mroute_detail
,
8253 no_debug_mroute_detail_cmd
,
8254 "no debug mroute detail",
8260 PIM_DONT_DEBUG_MROUTE_DETAIL
;
8264 DEFUN (debug_pim_static
,
8265 debug_pim_static_cmd
,
8271 PIM_DO_DEBUG_STATIC
;
8275 DEFUN (no_debug_pim_static
,
8276 no_debug_pim_static_cmd
,
8277 "no debug pim static",
8283 PIM_DONT_DEBUG_STATIC
;
8294 PIM_DO_DEBUG_PIM_EVENTS
;
8295 PIM_DO_DEBUG_PIM_PACKETS
;
8296 PIM_DO_DEBUG_PIM_TRACE
;
8297 PIM_DO_DEBUG_MSDP_EVENTS
;
8298 PIM_DO_DEBUG_MSDP_PACKETS
;
8303 DEFUN (no_debug_pim
,
8310 PIM_DONT_DEBUG_PIM_EVENTS
;
8311 PIM_DONT_DEBUG_PIM_PACKETS
;
8312 PIM_DONT_DEBUG_PIM_TRACE
;
8313 PIM_DONT_DEBUG_MSDP_EVENTS
;
8314 PIM_DONT_DEBUG_MSDP_PACKETS
;
8316 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
8317 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
8323 DEFUN (debug_pim_nht
,
8328 "Nexthop Tracking\n")
8330 PIM_DO_DEBUG_PIM_NHT
;
8334 DEFUN (no_debug_pim_nht
,
8335 no_debug_pim_nht_cmd
,
8340 "Nexthop Tracking\n")
8342 PIM_DONT_DEBUG_PIM_NHT
;
8346 DEFUN (debug_pim_nht_rp
,
8347 debug_pim_nht_rp_cmd
,
8351 "Nexthop Tracking\n"
8352 "RP Nexthop Tracking\n")
8354 PIM_DO_DEBUG_PIM_NHT_RP
;
8358 DEFUN (no_debug_pim_nht_rp
,
8359 no_debug_pim_nht_rp_cmd
,
8360 "no debug pim nht rp",
8364 "Nexthop Tracking\n"
8365 "RP Nexthop Tracking\n")
8367 PIM_DONT_DEBUG_PIM_NHT_RP
;
8371 DEFUN (debug_pim_events
,
8372 debug_pim_events_cmd
,
8376 DEBUG_PIM_EVENTS_STR
)
8378 PIM_DO_DEBUG_PIM_EVENTS
;
8382 DEFUN (no_debug_pim_events
,
8383 no_debug_pim_events_cmd
,
8384 "no debug pim events",
8388 DEBUG_PIM_EVENTS_STR
)
8390 PIM_DONT_DEBUG_PIM_EVENTS
;
8394 DEFUN (debug_pim_packets
,
8395 debug_pim_packets_cmd
,
8396 "debug pim packets [<hello|joins|register>]",
8399 DEBUG_PIM_PACKETS_STR
8400 DEBUG_PIM_HELLO_PACKETS_STR
8401 DEBUG_PIM_J_P_PACKETS_STR
8402 DEBUG_PIM_PIM_REG_PACKETS_STR
)
8405 if (argv_find(argv
, argc
, "hello", &idx
)) {
8406 PIM_DO_DEBUG_PIM_HELLO
;
8407 vty_out(vty
, "PIM Hello debugging is on\n");
8408 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
8409 PIM_DO_DEBUG_PIM_J_P
;
8410 vty_out(vty
, "PIM Join/Prune debugging is on\n");
8411 } else if (argv_find(argv
, argc
, "register", &idx
)) {
8412 PIM_DO_DEBUG_PIM_REG
;
8413 vty_out(vty
, "PIM Register debugging is on\n");
8415 PIM_DO_DEBUG_PIM_PACKETS
;
8416 vty_out(vty
, "PIM Packet debugging is on \n");
8421 DEFUN (no_debug_pim_packets
,
8422 no_debug_pim_packets_cmd
,
8423 "no debug pim packets [<hello|joins|register>]",
8427 DEBUG_PIM_PACKETS_STR
8428 DEBUG_PIM_HELLO_PACKETS_STR
8429 DEBUG_PIM_J_P_PACKETS_STR
8430 DEBUG_PIM_PIM_REG_PACKETS_STR
)
8433 if (argv_find(argv
, argc
, "hello", &idx
)) {
8434 PIM_DONT_DEBUG_PIM_HELLO
;
8435 vty_out(vty
, "PIM Hello debugging is off \n");
8436 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
8437 PIM_DONT_DEBUG_PIM_J_P
;
8438 vty_out(vty
, "PIM Join/Prune debugging is off \n");
8439 } else if (argv_find(argv
, argc
, "register", &idx
)) {
8440 PIM_DONT_DEBUG_PIM_REG
;
8441 vty_out(vty
, "PIM Register debugging is off\n");
8443 PIM_DONT_DEBUG_PIM_PACKETS
;
8449 DEFUN (debug_pim_packetdump_send
,
8450 debug_pim_packetdump_send_cmd
,
8451 "debug pim packet-dump send",
8454 DEBUG_PIM_PACKETDUMP_STR
8455 DEBUG_PIM_PACKETDUMP_SEND_STR
)
8457 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND
;
8461 DEFUN (no_debug_pim_packetdump_send
,
8462 no_debug_pim_packetdump_send_cmd
,
8463 "no debug pim packet-dump send",
8467 DEBUG_PIM_PACKETDUMP_STR
8468 DEBUG_PIM_PACKETDUMP_SEND_STR
)
8470 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
8474 DEFUN (debug_pim_packetdump_recv
,
8475 debug_pim_packetdump_recv_cmd
,
8476 "debug pim packet-dump receive",
8479 DEBUG_PIM_PACKETDUMP_STR
8480 DEBUG_PIM_PACKETDUMP_RECV_STR
)
8482 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV
;
8486 DEFUN (no_debug_pim_packetdump_recv
,
8487 no_debug_pim_packetdump_recv_cmd
,
8488 "no debug pim packet-dump receive",
8492 DEBUG_PIM_PACKETDUMP_STR
8493 DEBUG_PIM_PACKETDUMP_RECV_STR
)
8495 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
8499 DEFUN (debug_pim_trace
,
8500 debug_pim_trace_cmd
,
8504 DEBUG_PIM_TRACE_STR
)
8506 PIM_DO_DEBUG_PIM_TRACE
;
8510 DEFUN (debug_pim_trace_detail
,
8511 debug_pim_trace_detail_cmd
,
8512 "debug pim trace detail",
8516 "Detailed Information\n")
8518 PIM_DO_DEBUG_PIM_TRACE_DETAIL
;
8522 DEFUN (no_debug_pim_trace
,
8523 no_debug_pim_trace_cmd
,
8524 "no debug pim trace",
8528 DEBUG_PIM_TRACE_STR
)
8530 PIM_DONT_DEBUG_PIM_TRACE
;
8534 DEFUN (no_debug_pim_trace_detail
,
8535 no_debug_pim_trace_detail_cmd
,
8536 "no debug pim trace detail",
8541 "Detailed Information\n")
8543 PIM_DONT_DEBUG_PIM_TRACE_DETAIL
;
8547 DEFUN (debug_ssmpingd
,
8553 PIM_DO_DEBUG_SSMPINGD
;
8557 DEFUN (no_debug_ssmpingd
,
8558 no_debug_ssmpingd_cmd
,
8559 "no debug ssmpingd",
8564 PIM_DONT_DEBUG_SSMPINGD
;
8568 DEFUN (debug_pim_zebra
,
8569 debug_pim_zebra_cmd
,
8573 DEBUG_PIM_ZEBRA_STR
)
8579 DEFUN (no_debug_pim_zebra
,
8580 no_debug_pim_zebra_cmd
,
8581 "no debug pim zebra",
8585 DEBUG_PIM_ZEBRA_STR
)
8587 PIM_DONT_DEBUG_ZEBRA
;
8591 DEFUN(debug_pim_mlag
, debug_pim_mlag_cmd
, "debug pim mlag",
8592 DEBUG_STR DEBUG_PIM_STR DEBUG_PIM_MLAG_STR
)
8598 DEFUN(no_debug_pim_mlag
, no_debug_pim_mlag_cmd
, "no debug pim mlag",
8599 NO_STR DEBUG_STR DEBUG_PIM_STR DEBUG_PIM_MLAG_STR
)
8601 PIM_DONT_DEBUG_MLAG
;
8605 DEFUN (debug_pim_vxlan
,
8606 debug_pim_vxlan_cmd
,
8610 DEBUG_PIM_VXLAN_STR
)
8616 DEFUN (no_debug_pim_vxlan
,
8617 no_debug_pim_vxlan_cmd
,
8618 "no debug pim vxlan",
8622 DEBUG_PIM_VXLAN_STR
)
8624 PIM_DONT_DEBUG_VXLAN
;
8634 PIM_DO_DEBUG_MSDP_EVENTS
;
8635 PIM_DO_DEBUG_MSDP_PACKETS
;
8639 DEFUN (no_debug_msdp
,
8646 PIM_DONT_DEBUG_MSDP_EVENTS
;
8647 PIM_DONT_DEBUG_MSDP_PACKETS
;
8651 DEFUN (debug_msdp_events
,
8652 debug_msdp_events_cmd
,
8653 "debug msdp events",
8656 DEBUG_MSDP_EVENTS_STR
)
8658 PIM_DO_DEBUG_MSDP_EVENTS
;
8662 DEFUN (no_debug_msdp_events
,
8663 no_debug_msdp_events_cmd
,
8664 "no debug msdp events",
8668 DEBUG_MSDP_EVENTS_STR
)
8670 PIM_DONT_DEBUG_MSDP_EVENTS
;
8674 DEFUN (debug_msdp_packets
,
8675 debug_msdp_packets_cmd
,
8676 "debug msdp packets",
8679 DEBUG_MSDP_PACKETS_STR
)
8681 PIM_DO_DEBUG_MSDP_PACKETS
;
8685 DEFUN (no_debug_msdp_packets
,
8686 no_debug_msdp_packets_cmd
,
8687 "no debug msdp packets",
8691 DEBUG_MSDP_PACKETS_STR
)
8693 PIM_DONT_DEBUG_MSDP_PACKETS
;
8697 DEFUN (debug_mtrace
,
8703 PIM_DO_DEBUG_MTRACE
;
8707 DEFUN (no_debug_mtrace
,
8708 no_debug_mtrace_cmd
,
8714 PIM_DONT_DEBUG_MTRACE
;
8729 DEFUN (no_debug_bsm
,
8742 DEFUN_NOSH (show_debugging_pim
,
8743 show_debugging_pim_cmd
,
8744 "show debugging [pim]",
8749 vty_out(vty
, "PIM debugging status\n");
8751 pim_debug_config_write(vty
);
8756 static int interface_pim_use_src_cmd_worker(struct vty
*vty
, const char *source
)
8759 struct in_addr source_addr
;
8760 int ret
= CMD_SUCCESS
;
8761 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8763 result
= inet_pton(AF_INET
, source
, &source_addr
);
8765 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", source
,
8766 errno
, safe_strerror(errno
));
8767 return CMD_WARNING_CONFIG_FAILED
;
8770 result
= pim_update_source_set(ifp
, source_addr
);
8774 case PIM_IFACE_NOT_FOUND
:
8775 ret
= CMD_WARNING_CONFIG_FAILED
;
8776 vty_out(vty
, "Pim not enabled on this interface\n");
8778 case PIM_UPDATE_SOURCE_DUP
:
8780 vty_out(vty
, "%% Source already set to %s\n", source
);
8783 ret
= CMD_WARNING_CONFIG_FAILED
;
8784 vty_out(vty
, "%% Source set failed\n");
8790 DEFUN (interface_pim_use_source
,
8791 interface_pim_use_source_cmd
,
8792 "ip pim use-source A.B.C.D",
8795 "Configure primary IP address\n"
8796 "source ip address\n")
8798 return interface_pim_use_src_cmd_worker(vty
, argv
[3]->arg
);
8801 DEFUN (interface_no_pim_use_source
,
8802 interface_no_pim_use_source_cmd
,
8803 "no ip pim use-source [A.B.C.D]",
8807 "Delete source IP address\n"
8808 "source ip address\n")
8810 return interface_pim_use_src_cmd_worker(vty
, "0.0.0.0");
8818 "Enables BFD support\n")
8820 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8821 struct pim_interface
*pim_ifp
= ifp
->info
;
8822 struct bfd_info
*bfd_info
= NULL
;
8825 if (!pim_cmd_interface_add(ifp
)) {
8826 vty_out(vty
, "Could not enable PIM SM on interface\n");
8830 pim_ifp
= ifp
->info
;
8832 bfd_info
= pim_ifp
->bfd_info
;
8834 if (!bfd_info
|| !CHECK_FLAG(bfd_info
->flags
, BFD_FLAG_PARAM_CFG
))
8835 pim_bfd_if_param_set(ifp
, BFD_DEF_MIN_RX
, BFD_DEF_MIN_TX
,
8836 BFD_DEF_DETECT_MULT
, 1);
8841 DEFUN (no_ip_pim_bfd
,
8847 "Disables BFD support\n")
8849 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8850 struct pim_interface
*pim_ifp
= ifp
->info
;
8853 vty_out(vty
, "Pim not enabled on this interface\n");
8857 if (pim_ifp
->bfd_info
) {
8858 pim_bfd_reg_dereg_all_nbr(ifp
, ZEBRA_BFD_DEST_DEREGISTER
);
8859 bfd_info_free(&(pim_ifp
->bfd_info
));
8870 "Enables BSM support on the interface\n")
8872 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8873 struct pim_interface
*pim_ifp
= ifp
->info
;
8876 if (!pim_cmd_interface_add(ifp
)) {
8877 vty_out(vty
, "Could not enable PIM SM on interface\n");
8882 pim_ifp
= ifp
->info
;
8883 pim_ifp
->bsm_enable
= true;
8888 DEFUN (no_ip_pim_bsm
,
8894 "Disables BSM support\n")
8896 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8897 struct pim_interface
*pim_ifp
= ifp
->info
;
8900 vty_out(vty
, "Pim not enabled on this interface\n");
8904 pim_ifp
->bsm_enable
= false;
8909 DEFUN (ip_pim_ucast_bsm
,
8910 ip_pim_ucast_bsm_cmd
,
8911 "ip pim unicast-bsm",
8914 "Accept/Send unicast BSM on the interface\n")
8916 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8917 struct pim_interface
*pim_ifp
= ifp
->info
;
8920 if (!pim_cmd_interface_add(ifp
)) {
8921 vty_out(vty
, "Could not enable PIM SM on interface\n");
8926 pim_ifp
= ifp
->info
;
8927 pim_ifp
->ucast_bsm_accept
= true;
8932 DEFUN (no_ip_pim_ucast_bsm
,
8933 no_ip_pim_ucast_bsm_cmd
,
8934 "no ip pim unicast-bsm",
8938 "Block send/receive unicast BSM on this interface\n")
8940 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8941 struct pim_interface
*pim_ifp
= ifp
->info
;
8944 vty_out(vty
, "Pim not enabled on this interface\n");
8948 pim_ifp
->ucast_bsm_accept
= false;
8956 ip_pim_bfd_param_cmd
,
8957 "ip pim bfd (2-255) (50-60000) (50-60000)",
8960 "Enables BFD support\n"
8961 "Detect Multiplier\n"
8962 "Required min receive interval\n"
8963 "Desired min transmit interval\n")
8967 ip_pim_bfd_param_cmd
,
8968 "ip pim bfd (2-255) (50-60000) (50-60000)",
8971 "Enables BFD support\n"
8972 "Detect Multiplier\n"
8973 "Required min receive interval\n"
8974 "Desired min transmit interval\n")
8975 #endif /* HAVE_BFDD */
8977 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8979 int idx_number_2
= 4;
8980 int idx_number_3
= 5;
8985 struct pim_interface
*pim_ifp
= ifp
->info
;
8988 if (!pim_cmd_interface_add(ifp
)) {
8989 vty_out(vty
, "Could not enable PIM SM on interface\n");
8994 if ((ret
= bfd_validate_param(
8995 vty
, argv
[idx_number
]->arg
, argv
[idx_number_2
]->arg
,
8996 argv
[idx_number_3
]->arg
, &dm_val
, &rx_val
, &tx_val
))
9000 pim_bfd_if_param_set(ifp
, rx_val
, tx_val
, dm_val
, 0);
9006 ALIAS(no_ip_pim_bfd
, no_ip_pim_bfd_param_cmd
,
9007 "no ip pim bfd (2-255) (50-60000) (50-60000)", NO_STR IP_STR PIM_STR
9008 "Enables BFD support\n"
9009 "Detect Multiplier\n"
9010 "Required min receive interval\n"
9011 "Desired min transmit interval\n")
9012 #endif /* !HAVE_BFDD */
9014 static int ip_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
9015 const char *peer
, const char *local
)
9017 enum pim_msdp_err result
;
9018 struct in_addr peer_addr
;
9019 struct in_addr local_addr
;
9020 int ret
= CMD_SUCCESS
;
9022 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
9024 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
9025 errno
, safe_strerror(errno
));
9026 return CMD_WARNING_CONFIG_FAILED
;
9029 result
= inet_pton(AF_INET
, local
, &local_addr
);
9031 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", local
,
9032 errno
, safe_strerror(errno
));
9033 return CMD_WARNING_CONFIG_FAILED
;
9036 result
= pim_msdp_peer_add(pim
, peer_addr
, local_addr
, "default",
9039 case PIM_MSDP_ERR_NONE
:
9041 case PIM_MSDP_ERR_OOM
:
9042 ret
= CMD_WARNING_CONFIG_FAILED
;
9043 vty_out(vty
, "%% Out of memory\n");
9045 case PIM_MSDP_ERR_PEER_EXISTS
:
9047 vty_out(vty
, "%% Peer exists\n");
9049 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
9050 ret
= CMD_WARNING_CONFIG_FAILED
;
9051 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
9054 ret
= CMD_WARNING_CONFIG_FAILED
;
9055 vty_out(vty
, "%% peer add failed\n");
9061 DEFUN_HIDDEN (ip_msdp_peer
,
9063 "ip msdp peer A.B.C.D source A.B.C.D",
9066 "Configure MSDP peer\n"
9068 "Source address for TCP connection\n"
9069 "local ip address\n")
9071 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9072 return ip_msdp_peer_cmd_worker(pim
, vty
, argv
[3]->arg
, argv
[5]->arg
);
9075 static int ip_no_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
9078 enum pim_msdp_err result
;
9079 struct in_addr peer_addr
;
9081 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
9083 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
9084 errno
, safe_strerror(errno
));
9085 return CMD_WARNING_CONFIG_FAILED
;
9088 result
= pim_msdp_peer_del(pim
, peer_addr
);
9090 case PIM_MSDP_ERR_NONE
:
9092 case PIM_MSDP_ERR_NO_PEER
:
9093 vty_out(vty
, "%% Peer does not exist\n");
9096 vty_out(vty
, "%% peer del failed\n");
9099 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9102 DEFUN_HIDDEN (no_ip_msdp_peer
,
9103 no_ip_msdp_peer_cmd
,
9104 "no ip msdp peer A.B.C.D",
9108 "Delete MSDP peer\n"
9109 "peer ip address\n")
9111 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9112 return ip_no_msdp_peer_cmd_worker(pim
, vty
, argv
[4]->arg
);
9115 static int ip_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
9116 struct vty
*vty
, const char *mg
,
9119 enum pim_msdp_err result
;
9120 struct in_addr mbr_ip
;
9121 int ret
= CMD_SUCCESS
;
9123 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
9125 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
9126 errno
, safe_strerror(errno
));
9127 return CMD_WARNING_CONFIG_FAILED
;
9130 result
= pim_msdp_mg_mbr_add(pim
, mg
, mbr_ip
);
9132 case PIM_MSDP_ERR_NONE
:
9134 case PIM_MSDP_ERR_OOM
:
9135 ret
= CMD_WARNING_CONFIG_FAILED
;
9136 vty_out(vty
, "%% Out of memory\n");
9138 case PIM_MSDP_ERR_MG_MBR_EXISTS
:
9140 vty_out(vty
, "%% mesh-group member exists\n");
9142 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
9143 ret
= CMD_WARNING_CONFIG_FAILED
;
9144 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
9147 ret
= CMD_WARNING_CONFIG_FAILED
;
9148 vty_out(vty
, "%% member add failed\n");
9154 DEFUN (ip_msdp_mesh_group_member
,
9155 ip_msdp_mesh_group_member_cmd
,
9156 "ip msdp mesh-group WORD member A.B.C.D",
9159 "Configure MSDP mesh-group\n"
9161 "mesh group member\n"
9162 "peer ip address\n")
9164 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9165 return ip_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[3]->arg
,
9169 static int ip_no_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
9174 enum pim_msdp_err result
;
9175 struct in_addr mbr_ip
;
9177 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
9179 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
9180 errno
, safe_strerror(errno
));
9181 return CMD_WARNING_CONFIG_FAILED
;
9184 result
= pim_msdp_mg_mbr_del(pim
, mg
, mbr_ip
);
9186 case PIM_MSDP_ERR_NONE
:
9188 case PIM_MSDP_ERR_NO_MG
:
9189 vty_out(vty
, "%% mesh-group does not exist\n");
9191 case PIM_MSDP_ERR_NO_MG_MBR
:
9192 vty_out(vty
, "%% mesh-group member does not exist\n");
9195 vty_out(vty
, "%% mesh-group member del failed\n");
9198 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9200 DEFUN (no_ip_msdp_mesh_group_member
,
9201 no_ip_msdp_mesh_group_member_cmd
,
9202 "no ip msdp mesh-group WORD member A.B.C.D",
9206 "Delete MSDP mesh-group member\n"
9208 "mesh group member\n"
9209 "peer ip address\n")
9211 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9212 return ip_no_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[4]->arg
,
9216 static int ip_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
9217 struct vty
*vty
, const char *mg
,
9220 enum pim_msdp_err result
;
9221 struct in_addr src_ip
;
9223 result
= inet_pton(AF_INET
, src
, &src_ip
);
9225 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", src
,
9226 errno
, safe_strerror(errno
));
9227 return CMD_WARNING_CONFIG_FAILED
;
9230 result
= pim_msdp_mg_src_add(pim
, mg
, src_ip
);
9232 case PIM_MSDP_ERR_NONE
:
9234 case PIM_MSDP_ERR_OOM
:
9235 vty_out(vty
, "%% Out of memory\n");
9237 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
9238 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
9241 vty_out(vty
, "%% source add failed\n");
9244 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9248 DEFUN (ip_msdp_mesh_group_source
,
9249 ip_msdp_mesh_group_source_cmd
,
9250 "ip msdp mesh-group WORD source A.B.C.D",
9253 "Configure MSDP mesh-group\n"
9255 "mesh group local address\n"
9256 "source ip address for the TCP connection\n")
9258 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9259 return ip_msdp_mesh_group_source_cmd_worker(pim
, vty
, argv
[3]->arg
,
9263 static int ip_no_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
9267 enum pim_msdp_err result
;
9269 result
= pim_msdp_mg_src_del(pim
, mg
);
9271 case PIM_MSDP_ERR_NONE
:
9273 case PIM_MSDP_ERR_NO_MG
:
9274 vty_out(vty
, "%% mesh-group does not exist\n");
9277 vty_out(vty
, "%% mesh-group source del failed\n");
9280 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9283 static int ip_no_msdp_mesh_group_cmd_worker(struct pim_instance
*pim
,
9284 struct vty
*vty
, const char *mg
)
9286 enum pim_msdp_err result
;
9288 result
= pim_msdp_mg_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 DEFUN (no_ip_msdp_mesh_group_source
,
9303 no_ip_msdp_mesh_group_source_cmd
,
9304 "no ip msdp mesh-group WORD source [A.B.C.D]",
9308 "Delete MSDP mesh-group source\n"
9310 "mesh group source\n"
9311 "mesh group local address\n")
9313 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9315 return ip_no_msdp_mesh_group_cmd_worker(pim
, vty
, argv
[6]->arg
);
9317 return ip_no_msdp_mesh_group_source_cmd_worker(pim
, vty
,
9321 static void print_empty_json_obj(struct vty
*vty
)
9324 json
= json_object_new_object();
9325 vty_out(vty
, "%s\n",
9326 json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
));
9327 json_object_free(json
);
9330 static void ip_msdp_show_mesh_group(struct pim_instance
*pim
, struct vty
*vty
,
9333 struct listnode
*mbrnode
;
9334 struct pim_msdp_mg_mbr
*mbr
;
9335 struct pim_msdp_mg
*mg
= pim
->msdp
.mg
;
9336 char mbr_str
[INET_ADDRSTRLEN
];
9337 char src_str
[INET_ADDRSTRLEN
];
9338 char state_str
[PIM_MSDP_STATE_STRLEN
];
9339 enum pim_msdp_peer_state state
;
9340 json_object
*json
= NULL
;
9341 json_object
*json_mg_row
= NULL
;
9342 json_object
*json_members
= NULL
;
9343 json_object
*json_row
= NULL
;
9347 print_empty_json_obj(vty
);
9351 pim_inet4_dump("<source?>", mg
->src_ip
, src_str
, sizeof(src_str
));
9353 json
= json_object_new_object();
9354 /* currently there is only one mesh group but we should still
9356 * it a dict with mg-name as key */
9357 json_mg_row
= json_object_new_object();
9358 json_object_string_add(json_mg_row
, "name",
9359 mg
->mesh_group_name
);
9360 json_object_string_add(json_mg_row
, "source", src_str
);
9362 vty_out(vty
, "Mesh group : %s\n", mg
->mesh_group_name
);
9363 vty_out(vty
, " Source : %s\n", src_str
);
9364 vty_out(vty
, " Member State\n");
9367 for (ALL_LIST_ELEMENTS_RO(mg
->mbr_list
, mbrnode
, mbr
)) {
9368 pim_inet4_dump("<mbr?>", mbr
->mbr_ip
, mbr_str
, sizeof(mbr_str
));
9370 state
= mbr
->mp
->state
;
9372 state
= PIM_MSDP_DISABLED
;
9374 pim_msdp_state_dump(state
, state_str
, sizeof(state_str
));
9376 json_row
= json_object_new_object();
9377 json_object_string_add(json_row
, "member", mbr_str
);
9378 json_object_string_add(json_row
, "state", state_str
);
9379 if (!json_members
) {
9380 json_members
= json_object_new_object();
9381 json_object_object_add(json_mg_row
, "members",
9384 json_object_object_add(json_members
, mbr_str
, json_row
);
9386 vty_out(vty
, " %-15s %11s\n", mbr_str
, state_str
);
9391 json_object_object_add(json
, mg
->mesh_group_name
, json_mg_row
);
9392 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9393 json
, JSON_C_TO_STRING_PRETTY
));
9394 json_object_free(json
);
9398 DEFUN (show_ip_msdp_mesh_group
,
9399 show_ip_msdp_mesh_group_cmd
,
9400 "show ip msdp [vrf NAME] mesh-group [json]",
9405 "MSDP mesh-group information\n"
9408 bool uj
= use_json(argc
, argv
);
9410 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
9415 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
9420 DEFUN (show_ip_msdp_mesh_group_vrf_all
,
9421 show_ip_msdp_mesh_group_vrf_all_cmd
,
9422 "show ip msdp vrf all mesh-group [json]",
9427 "MSDP mesh-group information\n"
9430 bool uj
= use_json(argc
, argv
);
9436 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
9440 vty_out(vty
, " \"%s\": ", vrf
->name
);
9443 vty_out(vty
, "VRF: %s\n", vrf
->name
);
9444 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
9447 vty_out(vty
, "}\n");
9452 static void ip_msdp_show_peers(struct pim_instance
*pim
, struct vty
*vty
,
9455 struct listnode
*mpnode
;
9456 struct pim_msdp_peer
*mp
;
9457 char peer_str
[INET_ADDRSTRLEN
];
9458 char local_str
[INET_ADDRSTRLEN
];
9459 char state_str
[PIM_MSDP_STATE_STRLEN
];
9460 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
9462 json_object
*json
= NULL
;
9463 json_object
*json_row
= NULL
;
9467 json
= json_object_new_object();
9470 "Peer Local State Uptime SaCnt\n");
9473 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
9474 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
9475 now
= pim_time_monotonic_sec();
9476 pim_time_uptime(timebuf
, sizeof(timebuf
),
9479 strlcpy(timebuf
, "-", sizeof(timebuf
));
9481 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
9482 pim_inet4_dump("<local?>", mp
->local
, local_str
,
9484 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
9486 json_row
= json_object_new_object();
9487 json_object_string_add(json_row
, "peer", peer_str
);
9488 json_object_string_add(json_row
, "local", local_str
);
9489 json_object_string_add(json_row
, "state", state_str
);
9490 json_object_string_add(json_row
, "upTime", timebuf
);
9491 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
9492 json_object_object_add(json
, peer_str
, json_row
);
9494 vty_out(vty
, "%-15s %15s %11s %8s %6d\n", peer_str
,
9495 local_str
, state_str
, timebuf
, mp
->sa_cnt
);
9500 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9501 json
, JSON_C_TO_STRING_PRETTY
));
9502 json_object_free(json
);
9506 static void ip_msdp_show_peers_detail(struct pim_instance
*pim
, struct vty
*vty
,
9507 const char *peer
, bool uj
)
9509 struct listnode
*mpnode
;
9510 struct pim_msdp_peer
*mp
;
9511 char peer_str
[INET_ADDRSTRLEN
];
9512 char local_str
[INET_ADDRSTRLEN
];
9513 char state_str
[PIM_MSDP_STATE_STRLEN
];
9514 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
9515 char katimer
[PIM_MSDP_TIMER_STRLEN
];
9516 char crtimer
[PIM_MSDP_TIMER_STRLEN
];
9517 char holdtimer
[PIM_MSDP_TIMER_STRLEN
];
9519 json_object
*json
= NULL
;
9520 json_object
*json_row
= NULL
;
9523 json
= json_object_new_object();
9526 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
9527 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
9528 if (strcmp(peer
, "detail") && strcmp(peer
, peer_str
))
9531 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
9532 now
= pim_time_monotonic_sec();
9533 pim_time_uptime(timebuf
, sizeof(timebuf
),
9536 strlcpy(timebuf
, "-", sizeof(timebuf
));
9538 pim_inet4_dump("<local?>", mp
->local
, local_str
,
9540 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
9541 pim_time_timer_to_hhmmss(katimer
, sizeof(katimer
),
9543 pim_time_timer_to_hhmmss(crtimer
, sizeof(crtimer
),
9545 pim_time_timer_to_hhmmss(holdtimer
, sizeof(holdtimer
),
9549 json_row
= json_object_new_object();
9550 json_object_string_add(json_row
, "peer", peer_str
);
9551 json_object_string_add(json_row
, "local", local_str
);
9552 json_object_string_add(json_row
, "meshGroupName",
9553 mp
->mesh_group_name
);
9554 json_object_string_add(json_row
, "state", state_str
);
9555 json_object_string_add(json_row
, "upTime", timebuf
);
9556 json_object_string_add(json_row
, "keepAliveTimer",
9558 json_object_string_add(json_row
, "connRetryTimer",
9560 json_object_string_add(json_row
, "holdTimer",
9562 json_object_string_add(json_row
, "lastReset",
9564 json_object_int_add(json_row
, "connAttempts",
9566 json_object_int_add(json_row
, "establishedChanges",
9568 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
9569 json_object_int_add(json_row
, "kaSent", mp
->ka_tx_cnt
);
9570 json_object_int_add(json_row
, "kaRcvd", mp
->ka_rx_cnt
);
9571 json_object_int_add(json_row
, "saSent", mp
->sa_tx_cnt
);
9572 json_object_int_add(json_row
, "saRcvd", mp
->sa_rx_cnt
);
9573 json_object_object_add(json
, peer_str
, json_row
);
9575 vty_out(vty
, "Peer : %s\n", peer_str
);
9576 vty_out(vty
, " Local : %s\n", local_str
);
9577 vty_out(vty
, " Mesh Group : %s\n",
9578 mp
->mesh_group_name
);
9579 vty_out(vty
, " State : %s\n", state_str
);
9580 vty_out(vty
, " Uptime : %s\n", timebuf
);
9582 vty_out(vty
, " Keepalive Timer : %s\n", katimer
);
9583 vty_out(vty
, " Conn Retry Timer : %s\n", crtimer
);
9584 vty_out(vty
, " Hold Timer : %s\n", holdtimer
);
9585 vty_out(vty
, " Last Reset : %s\n",
9587 vty_out(vty
, " Conn Attempts : %d\n",
9589 vty_out(vty
, " Established Changes : %d\n",
9591 vty_out(vty
, " SA Count : %d\n",
9593 vty_out(vty
, " Statistics :\n");
9596 vty_out(vty
, " Keepalives : %10d %10d\n",
9597 mp
->ka_tx_cnt
, mp
->ka_rx_cnt
);
9598 vty_out(vty
, " SAs : %10d %10d\n",
9599 mp
->sa_tx_cnt
, mp
->sa_rx_cnt
);
9605 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9606 json
, JSON_C_TO_STRING_PRETTY
));
9607 json_object_free(json
);
9611 DEFUN (show_ip_msdp_peer_detail
,
9612 show_ip_msdp_peer_detail_cmd
,
9613 "show ip msdp [vrf NAME] peer [detail|A.B.C.D] [json]",
9618 "MSDP peer information\n"
9623 bool uj
= use_json(argc
, argv
);
9625 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
9632 if (argv_find(argv
, argc
, "detail", &idx
))
9633 arg
= argv
[idx
]->text
;
9634 else if (argv_find(argv
, argc
, "A.B.C.D", &idx
))
9635 arg
= argv
[idx
]->arg
;
9638 ip_msdp_show_peers_detail(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
9640 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
9645 DEFUN (show_ip_msdp_peer_detail_vrf_all
,
9646 show_ip_msdp_peer_detail_vrf_all_cmd
,
9647 "show ip msdp vrf all peer [detail|A.B.C.D] [json]",
9652 "MSDP peer information\n"
9658 bool uj
= use_json(argc
, argv
);
9664 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
9668 vty_out(vty
, " \"%s\": ", vrf
->name
);
9671 vty_out(vty
, "VRF: %s\n", vrf
->name
);
9672 if (argv_find(argv
, argc
, "detail", &idx
)
9673 || argv_find(argv
, argc
, "A.B.C.D", &idx
))
9674 ip_msdp_show_peers_detail(vrf
->info
, vty
,
9675 argv
[idx
]->arg
, uj
);
9677 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
9680 vty_out(vty
, "}\n");
9685 static void ip_msdp_show_sa(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
9687 struct listnode
*sanode
;
9688 struct pim_msdp_sa
*sa
;
9689 char src_str
[INET_ADDRSTRLEN
];
9690 char grp_str
[INET_ADDRSTRLEN
];
9691 char rp_str
[INET_ADDRSTRLEN
];
9692 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
9696 json_object
*json
= NULL
;
9697 json_object
*json_group
= NULL
;
9698 json_object
*json_row
= NULL
;
9701 json
= json_object_new_object();
9704 "Source Group RP Local SPT Uptime\n");
9707 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
9708 now
= pim_time_monotonic_sec();
9709 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
9710 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
9711 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
9712 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
9713 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
9715 strlcpy(spt_str
, "yes", sizeof(spt_str
));
9717 strlcpy(spt_str
, "no", sizeof(spt_str
));
9720 strlcpy(rp_str
, "-", sizeof(rp_str
));
9721 strlcpy(spt_str
, "-", sizeof(spt_str
));
9723 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
9724 strlcpy(local_str
, "yes", sizeof(local_str
));
9726 strlcpy(local_str
, "no", sizeof(local_str
));
9729 json_object_object_get_ex(json
, grp_str
, &json_group
);
9732 json_group
= json_object_new_object();
9733 json_object_object_add(json
, grp_str
,
9737 json_row
= json_object_new_object();
9738 json_object_string_add(json_row
, "source", src_str
);
9739 json_object_string_add(json_row
, "group", grp_str
);
9740 json_object_string_add(json_row
, "rp", rp_str
);
9741 json_object_string_add(json_row
, "local", local_str
);
9742 json_object_string_add(json_row
, "sptSetup", spt_str
);
9743 json_object_string_add(json_row
, "upTime", timebuf
);
9744 json_object_object_add(json_group
, src_str
, json_row
);
9746 vty_out(vty
, "%-15s %15s %15s %5c %3c %8s\n",
9747 src_str
, grp_str
, rp_str
, local_str
[0],
9748 spt_str
[0], timebuf
);
9753 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9754 json
, JSON_C_TO_STRING_PRETTY
));
9755 json_object_free(json
);
9759 static void ip_msdp_show_sa_entry_detail(struct pim_msdp_sa
*sa
,
9760 const char *src_str
,
9761 const char *grp_str
, struct vty
*vty
,
9762 bool uj
, json_object
*json
)
9764 char rp_str
[INET_ADDRSTRLEN
];
9765 char peer_str
[INET_ADDRSTRLEN
];
9766 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
9769 char statetimer
[PIM_MSDP_TIMER_STRLEN
];
9771 json_object
*json_group
= NULL
;
9772 json_object
*json_row
= NULL
;
9774 now
= pim_time_monotonic_sec();
9775 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
9776 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
9777 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
9778 pim_inet4_dump("<peer?>", sa
->peer
, peer_str
, sizeof(peer_str
));
9780 strlcpy(spt_str
, "yes", sizeof(spt_str
));
9782 strlcpy(spt_str
, "no", sizeof(spt_str
));
9785 strlcpy(rp_str
, "-", sizeof(rp_str
));
9786 strlcpy(peer_str
, "-", sizeof(peer_str
));
9787 strlcpy(spt_str
, "-", sizeof(spt_str
));
9789 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
9790 strlcpy(local_str
, "yes", sizeof(local_str
));
9792 strlcpy(local_str
, "no", sizeof(local_str
));
9794 pim_time_timer_to_hhmmss(statetimer
, sizeof(statetimer
),
9795 sa
->sa_state_timer
);
9797 json_object_object_get_ex(json
, grp_str
, &json_group
);
9800 json_group
= json_object_new_object();
9801 json_object_object_add(json
, grp_str
, json_group
);
9804 json_row
= json_object_new_object();
9805 json_object_string_add(json_row
, "source", src_str
);
9806 json_object_string_add(json_row
, "group", grp_str
);
9807 json_object_string_add(json_row
, "rp", rp_str
);
9808 json_object_string_add(json_row
, "local", local_str
);
9809 json_object_string_add(json_row
, "sptSetup", spt_str
);
9810 json_object_string_add(json_row
, "upTime", timebuf
);
9811 json_object_string_add(json_row
, "stateTimer", statetimer
);
9812 json_object_object_add(json_group
, src_str
, json_row
);
9814 vty_out(vty
, "SA : %s\n", sa
->sg_str
);
9815 vty_out(vty
, " RP : %s\n", rp_str
);
9816 vty_out(vty
, " Peer : %s\n", peer_str
);
9817 vty_out(vty
, " Local : %s\n", local_str
);
9818 vty_out(vty
, " SPT Setup : %s\n", spt_str
);
9819 vty_out(vty
, " Uptime : %s\n", timebuf
);
9820 vty_out(vty
, " State Timer : %s\n", statetimer
);
9825 static void ip_msdp_show_sa_detail(struct pim_instance
*pim
, struct vty
*vty
,
9828 struct listnode
*sanode
;
9829 struct pim_msdp_sa
*sa
;
9830 char src_str
[INET_ADDRSTRLEN
];
9831 char grp_str
[INET_ADDRSTRLEN
];
9832 json_object
*json
= NULL
;
9835 json
= json_object_new_object();
9838 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
9839 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
9840 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
9841 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
, uj
,
9846 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9847 json
, JSON_C_TO_STRING_PRETTY
));
9848 json_object_free(json
);
9852 DEFUN (show_ip_msdp_sa_detail
,
9853 show_ip_msdp_sa_detail_cmd
,
9854 "show ip msdp [vrf NAME] sa detail [json]",
9859 "MSDP active-source information\n"
9863 bool uj
= use_json(argc
, argv
);
9865 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
9870 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
9875 DEFUN (show_ip_msdp_sa_detail_vrf_all
,
9876 show_ip_msdp_sa_detail_vrf_all_cmd
,
9877 "show ip msdp vrf all sa detail [json]",
9882 "MSDP active-source information\n"
9886 bool uj
= use_json(argc
, argv
);
9892 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
9896 vty_out(vty
, " \"%s\": ", vrf
->name
);
9899 vty_out(vty
, "VRF: %s\n", vrf
->name
);
9900 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
9903 vty_out(vty
, "}\n");
9908 static void ip_msdp_show_sa_addr(struct pim_instance
*pim
, struct vty
*vty
,
9909 const char *addr
, bool uj
)
9911 struct listnode
*sanode
;
9912 struct pim_msdp_sa
*sa
;
9913 char src_str
[INET_ADDRSTRLEN
];
9914 char grp_str
[INET_ADDRSTRLEN
];
9915 json_object
*json
= NULL
;
9918 json
= json_object_new_object();
9921 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
9922 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
9923 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
9924 if (!strcmp(addr
, src_str
) || !strcmp(addr
, grp_str
)) {
9925 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
9931 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9932 json
, JSON_C_TO_STRING_PRETTY
));
9933 json_object_free(json
);
9937 static void ip_msdp_show_sa_sg(struct pim_instance
*pim
, struct vty
*vty
,
9938 const char *src
, const char *grp
, bool uj
)
9940 struct listnode
*sanode
;
9941 struct pim_msdp_sa
*sa
;
9942 char src_str
[INET_ADDRSTRLEN
];
9943 char grp_str
[INET_ADDRSTRLEN
];
9944 json_object
*json
= NULL
;
9947 json
= json_object_new_object();
9950 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
9951 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
9952 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
9953 if (!strcmp(src
, src_str
) && !strcmp(grp
, grp_str
)) {
9954 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
9960 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9961 json
, JSON_C_TO_STRING_PRETTY
));
9962 json_object_free(json
);
9966 DEFUN (show_ip_msdp_sa_sg
,
9967 show_ip_msdp_sa_sg_cmd
,
9968 "show ip msdp [vrf NAME] sa [A.B.C.D [A.B.C.D]] [json]",
9973 "MSDP active-source information\n"
9974 "source or group ip\n"
9978 bool uj
= use_json(argc
, argv
);
9982 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
9987 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
9989 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
9993 if (src_ip
&& grp_ip
)
9994 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
9996 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
9998 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
10000 return CMD_SUCCESS
;
10003 DEFUN (show_ip_msdp_sa_sg_vrf_all
,
10004 show_ip_msdp_sa_sg_vrf_all_cmd
,
10005 "show ip msdp vrf all sa [A.B.C.D [A.B.C.D]] [json]",
10010 "MSDP active-source information\n"
10011 "source or group ip\n"
10015 bool uj
= use_json(argc
, argv
);
10020 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
10022 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
10027 vty_out(vty
, "{ ");
10028 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
10031 vty_out(vty
, ", ");
10032 vty_out(vty
, " \"%s\": ", vrf
->name
);
10035 vty_out(vty
, "VRF: %s\n", vrf
->name
);
10037 if (src_ip
&& grp_ip
)
10038 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
10040 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
10042 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
10045 vty_out(vty
, "}\n");
10047 return CMD_SUCCESS
;
10050 struct pim_sg_cache_walk_data
{
10053 json_object
*json_group
;
10054 struct in_addr addr
;
10058 static void pim_show_vxlan_sg_entry(struct pim_vxlan_sg
*vxlan_sg
,
10059 struct pim_sg_cache_walk_data
*cwd
)
10061 struct vty
*vty
= cwd
->vty
;
10062 json_object
*json
= cwd
->json
;
10063 char src_str
[INET_ADDRSTRLEN
];
10064 char grp_str
[INET_ADDRSTRLEN
];
10065 json_object
*json_row
;
10066 bool installed
= (vxlan_sg
->up
) ? true : false;
10067 const char *iif_name
= vxlan_sg
->iif
?vxlan_sg
->iif
->name
:"-";
10068 const char *oif_name
;
10070 if (pim_vxlan_is_orig_mroute(vxlan_sg
))
10071 oif_name
= vxlan_sg
->orig_oif
?vxlan_sg
->orig_oif
->name
:"";
10073 oif_name
= vxlan_sg
->term_oif
?vxlan_sg
->term_oif
->name
:"";
10075 if (cwd
->addr_match
&& (vxlan_sg
->sg
.src
.s_addr
!= cwd
->addr
.s_addr
) &&
10076 (vxlan_sg
->sg
.grp
.s_addr
!= cwd
->addr
.s_addr
)) {
10079 pim_inet4_dump("<src?>", vxlan_sg
->sg
.src
, src_str
, sizeof(src_str
));
10080 pim_inet4_dump("<grp?>", vxlan_sg
->sg
.grp
, grp_str
, sizeof(grp_str
));
10082 json_object_object_get_ex(json
, grp_str
, &cwd
->json_group
);
10084 if (!cwd
->json_group
) {
10085 cwd
->json_group
= json_object_new_object();
10086 json_object_object_add(json
, grp_str
,
10090 json_row
= json_object_new_object();
10091 json_object_string_add(json_row
, "source", src_str
);
10092 json_object_string_add(json_row
, "group", grp_str
);
10093 json_object_string_add(json_row
, "input", iif_name
);
10094 json_object_string_add(json_row
, "output", oif_name
);
10096 json_object_boolean_true_add(json_row
, "installed");
10098 json_object_boolean_false_add(json_row
, "installed");
10099 json_object_object_add(cwd
->json_group
, src_str
, json_row
);
10101 vty_out(vty
, "%-15s %-15s %-15s %-15s %-5s\n",
10102 src_str
, grp_str
, iif_name
, oif_name
,
10107 static void pim_show_vxlan_sg_hash_entry(struct hash_backet
*backet
, void *arg
)
10109 pim_show_vxlan_sg_entry((struct pim_vxlan_sg
*)backet
->data
,
10110 (struct pim_sg_cache_walk_data
*)arg
);
10113 static void pim_show_vxlan_sg(struct pim_instance
*pim
,
10114 struct vty
*vty
, bool uj
)
10116 json_object
*json
= NULL
;
10117 struct pim_sg_cache_walk_data cwd
;
10120 json
= json_object_new_object();
10122 vty_out(vty
, "Codes: I -> installed\n");
10124 "Source Group Input Output Flags\n");
10127 memset(&cwd
, 0, sizeof(cwd
));
10130 hash_iterate(pim
->vxlan
.sg_hash
, pim_show_vxlan_sg_hash_entry
, &cwd
);
10133 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10134 json
, JSON_C_TO_STRING_PRETTY
));
10135 json_object_free(json
);
10139 static void pim_show_vxlan_sg_match_addr(struct pim_instance
*pim
,
10140 struct vty
*vty
, char *addr_str
, bool uj
)
10142 json_object
*json
= NULL
;
10143 struct pim_sg_cache_walk_data cwd
;
10146 memset(&cwd
, 0, sizeof(cwd
));
10147 result
= inet_pton(AF_INET
, addr_str
, &cwd
.addr
);
10149 vty_out(vty
, "Bad address %s: errno=%d: %s\n", addr_str
,
10150 errno
, safe_strerror(errno
));
10155 json
= json_object_new_object();
10157 vty_out(vty
, "Codes: I -> installed\n");
10159 "Source Group Input Output Flags\n");
10164 cwd
.addr_match
= true;
10165 hash_iterate(pim
->vxlan
.sg_hash
, pim_show_vxlan_sg_hash_entry
, &cwd
);
10168 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10169 json
, JSON_C_TO_STRING_PRETTY
));
10170 json_object_free(json
);
10174 static void pim_show_vxlan_sg_one(struct pim_instance
*pim
,
10175 struct vty
*vty
, char *src_str
, char *grp_str
, bool uj
)
10177 json_object
*json
= NULL
;
10178 struct prefix_sg sg
;
10180 struct pim_vxlan_sg
*vxlan_sg
;
10181 const char *iif_name
;
10183 const char *oif_name
;
10185 result
= inet_pton(AF_INET
, src_str
, &sg
.src
);
10187 vty_out(vty
, "Bad src address %s: errno=%d: %s\n", src_str
,
10188 errno
, safe_strerror(errno
));
10191 result
= inet_pton(AF_INET
, grp_str
, &sg
.grp
);
10193 vty_out(vty
, "Bad grp address %s: errno=%d: %s\n", grp_str
,
10194 errno
, safe_strerror(errno
));
10198 sg
.family
= AF_INET
;
10199 sg
.prefixlen
= IPV4_MAX_BITLEN
;
10201 json
= json_object_new_object();
10203 vxlan_sg
= pim_vxlan_sg_find(pim
, &sg
);
10205 installed
= (vxlan_sg
->up
) ? true : false;
10206 iif_name
= vxlan_sg
->iif
?vxlan_sg
->iif
->name
:"-";
10208 if (pim_vxlan_is_orig_mroute(vxlan_sg
))
10210 vxlan_sg
->orig_oif
?vxlan_sg
->orig_oif
->name
:"";
10213 vxlan_sg
->term_oif
?vxlan_sg
->term_oif
->name
:"";
10216 json_object_string_add(json
, "source", src_str
);
10217 json_object_string_add(json
, "group", grp_str
);
10218 json_object_string_add(json
, "input", iif_name
);
10219 json_object_string_add(json
, "output", oif_name
);
10221 json_object_boolean_true_add(json
, "installed");
10223 json_object_boolean_false_add(json
,
10226 vty_out(vty
, "SG : %s\n", vxlan_sg
->sg_str
);
10227 vty_out(vty
, " Input : %s\n", iif_name
);
10228 vty_out(vty
, " Output : %s\n", oif_name
);
10229 vty_out(vty
, " installed : %s\n",
10230 installed
?"yes":"no");
10235 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10236 json
, JSON_C_TO_STRING_PRETTY
));
10237 json_object_free(json
);
10241 DEFUN (show_ip_pim_vxlan_sg
,
10242 show_ip_pim_vxlan_sg_cmd
,
10243 "show ip pim [vrf NAME] vxlan-groups [A.B.C.D [A.B.C.D]] [json]",
10248 "VxLAN BUM groups\n"
10249 "source or group ip\n"
10253 bool uj
= use_json(argc
, argv
);
10257 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10260 return CMD_WARNING
;
10262 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ?
10263 argv
[idx
++]->arg
:NULL
;
10264 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
) ?
10265 argv
[idx
]->arg
:NULL
;
10267 if (src_ip
&& grp_ip
)
10268 pim_show_vxlan_sg_one(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
10270 pim_show_vxlan_sg_match_addr(vrf
->info
, vty
, src_ip
, uj
);
10272 pim_show_vxlan_sg(vrf
->info
, vty
, uj
);
10274 return CMD_SUCCESS
;
10277 static void pim_show_vxlan_sg_work(struct pim_instance
*pim
,
10278 struct vty
*vty
, bool uj
)
10280 json_object
*json
= NULL
;
10281 struct pim_sg_cache_walk_data cwd
;
10282 struct listnode
*node
;
10283 struct pim_vxlan_sg
*vxlan_sg
;
10286 json
= json_object_new_object();
10288 vty_out(vty
, "Codes: I -> installed\n");
10290 "Source Group Input Flags\n");
10293 memset(&cwd
, 0, sizeof(cwd
));
10296 for (ALL_LIST_ELEMENTS_RO(pim_vxlan_p
->work_list
, node
, vxlan_sg
))
10297 pim_show_vxlan_sg_entry(vxlan_sg
, &cwd
);
10300 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10301 json
, JSON_C_TO_STRING_PRETTY
));
10302 json_object_free(json
);
10306 DEFUN_HIDDEN (show_ip_pim_vxlan_sg_work
,
10307 show_ip_pim_vxlan_sg_work_cmd
,
10308 "show ip pim [vrf NAME] vxlan-work [json]",
10313 "VxLAN work list\n"
10316 bool uj
= use_json(argc
, argv
);
10320 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10323 return CMD_WARNING
;
10325 pim_show_vxlan_sg_work(vrf
->info
, vty
, uj
);
10327 return CMD_SUCCESS
;
10330 DEFUN_HIDDEN (no_ip_pim_mlag
,
10331 no_ip_pim_mlag_cmd
,
10338 struct in_addr addr
;
10341 pim_vxlan_mlag_update(true/*mlag_enable*/,
10342 false/*peer_state*/, PIM_VXLAN_MLAG_ROLE_SECONDARY
,
10343 NULL
/*peerlink*/, &addr
);
10345 return CMD_SUCCESS
;
10348 DEFUN_HIDDEN (ip_pim_mlag
,
10350 "ip pim mlag INTERFACE role [primary|secondary] state [up|down] addr A.B.C.D",
10354 "peerlink sub interface\n"
10356 "MLAG role primary\n"
10357 "MLAG role secondary\n"
10358 "peer session state\n"
10359 "peer session state up\n"
10360 "peer session state down\n"
10362 "unique ip address\n")
10364 struct interface
*ifp
;
10365 const char *peerlink
;
10370 struct in_addr reg_addr
;
10373 peerlink
= argv
[idx
]->arg
;
10374 ifp
= if_lookup_by_name(peerlink
, VRF_DEFAULT
);
10376 vty_out(vty
, "No such interface name %s\n", peerlink
);
10377 return CMD_WARNING
;
10381 if (!strcmp(argv
[idx
]->arg
, "primary")) {
10382 role
= PIM_VXLAN_MLAG_ROLE_PRIMARY
;
10383 } else if (!strcmp(argv
[idx
]->arg
, "secondary")) {
10384 role
= PIM_VXLAN_MLAG_ROLE_SECONDARY
;
10386 vty_out(vty
, "unknown MLAG role %s\n", argv
[idx
]->arg
);
10387 return CMD_WARNING
;
10391 if (!strcmp(argv
[idx
]->arg
, "up")) {
10393 } else if (strcmp(argv
[idx
]->arg
, "down")) {
10394 peer_state
= false;
10396 vty_out(vty
, "unknown MLAG state %s\n", argv
[idx
]->arg
);
10397 return CMD_WARNING
;
10401 result
= inet_pton(AF_INET
, argv
[idx
]->arg
, ®_addr
);
10403 vty_out(vty
, "%% Bad reg address %s: errno=%d: %s\n",
10405 errno
, safe_strerror(errno
));
10406 return CMD_WARNING_CONFIG_FAILED
;
10408 pim_vxlan_mlag_update(true, peer_state
, role
, ifp
, ®_addr
);
10410 return CMD_SUCCESS
;
10413 void pim_cmd_init(void)
10415 install_node(&interface_node
,
10416 pim_interface_config_write
); /* INTERFACE_NODE */
10419 install_node(&debug_node
, pim_debug_config_write
);
10421 install_element(ENABLE_NODE
, &pim_test_sg_keepalive_cmd
);
10423 install_element(CONFIG_NODE
, &ip_pim_rp_cmd
);
10424 install_element(VRF_NODE
, &ip_pim_rp_cmd
);
10425 install_element(CONFIG_NODE
, &no_ip_pim_rp_cmd
);
10426 install_element(VRF_NODE
, &no_ip_pim_rp_cmd
);
10427 install_element(CONFIG_NODE
, &ip_pim_rp_prefix_list_cmd
);
10428 install_element(VRF_NODE
, &ip_pim_rp_prefix_list_cmd
);
10429 install_element(CONFIG_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
10430 install_element(VRF_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
10431 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
10432 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
10433 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
10434 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
10435 install_element(CONFIG_NODE
, &ip_pim_ssm_prefix_list_cmd
);
10436 install_element(VRF_NODE
, &ip_pim_ssm_prefix_list_cmd
);
10437 install_element(CONFIG_NODE
, &ip_pim_register_suppress_cmd
);
10438 install_element(VRF_NODE
, &ip_pim_register_suppress_cmd
);
10439 install_element(CONFIG_NODE
, &no_ip_pim_register_suppress_cmd
);
10440 install_element(VRF_NODE
, &no_ip_pim_register_suppress_cmd
);
10441 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
10442 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
10443 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
10444 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
10445 install_element(CONFIG_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
10446 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
10447 install_element(CONFIG_NODE
,
10448 &no_ip_pim_spt_switchover_infinity_plist_cmd
);
10449 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_plist_cmd
);
10450 install_element(CONFIG_NODE
, &ip_pim_joinprune_time_cmd
);
10451 install_element(VRF_NODE
, &ip_pim_joinprune_time_cmd
);
10452 install_element(CONFIG_NODE
, &no_ip_pim_joinprune_time_cmd
);
10453 install_element(VRF_NODE
, &no_ip_pim_joinprune_time_cmd
);
10454 install_element(CONFIG_NODE
, &ip_pim_keep_alive_cmd
);
10455 install_element(VRF_NODE
, &ip_pim_keep_alive_cmd
);
10456 install_element(CONFIG_NODE
, &ip_pim_rp_keep_alive_cmd
);
10457 install_element(VRF_NODE
, &ip_pim_rp_keep_alive_cmd
);
10458 install_element(CONFIG_NODE
, &no_ip_pim_keep_alive_cmd
);
10459 install_element(VRF_NODE
, &no_ip_pim_keep_alive_cmd
);
10460 install_element(CONFIG_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
10461 install_element(VRF_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
10462 install_element(CONFIG_NODE
, &ip_pim_packets_cmd
);
10463 install_element(VRF_NODE
, &ip_pim_packets_cmd
);
10464 install_element(CONFIG_NODE
, &no_ip_pim_packets_cmd
);
10465 install_element(VRF_NODE
, &no_ip_pim_packets_cmd
);
10466 install_element(CONFIG_NODE
, &ip_pim_v6_secondary_cmd
);
10467 install_element(VRF_NODE
, &ip_pim_v6_secondary_cmd
);
10468 install_element(CONFIG_NODE
, &no_ip_pim_v6_secondary_cmd
);
10469 install_element(VRF_NODE
, &no_ip_pim_v6_secondary_cmd
);
10470 install_element(CONFIG_NODE
, &ip_ssmpingd_cmd
);
10471 install_element(VRF_NODE
, &ip_ssmpingd_cmd
);
10472 install_element(CONFIG_NODE
, &no_ip_ssmpingd_cmd
);
10473 install_element(VRF_NODE
, &no_ip_ssmpingd_cmd
);
10474 install_element(CONFIG_NODE
, &ip_msdp_peer_cmd
);
10475 install_element(VRF_NODE
, &ip_msdp_peer_cmd
);
10476 install_element(CONFIG_NODE
, &no_ip_msdp_peer_cmd
);
10477 install_element(VRF_NODE
, &no_ip_msdp_peer_cmd
);
10478 install_element(CONFIG_NODE
, &ip_pim_ecmp_cmd
);
10479 install_element(VRF_NODE
, &ip_pim_ecmp_cmd
);
10480 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_cmd
);
10481 install_element(VRF_NODE
, &no_ip_pim_ecmp_cmd
);
10482 install_element(CONFIG_NODE
, &ip_pim_ecmp_rebalance_cmd
);
10483 install_element(VRF_NODE
, &ip_pim_ecmp_rebalance_cmd
);
10484 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
10485 install_element(VRF_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
10486 install_element(CONFIG_NODE
, &ip_pim_mlag_cmd
);
10487 install_element(CONFIG_NODE
, &no_ip_pim_mlag_cmd
);
10489 install_element(INTERFACE_NODE
, &interface_ip_igmp_cmd
);
10490 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_cmd
);
10491 install_element(INTERFACE_NODE
, &interface_ip_igmp_join_cmd
);
10492 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_join_cmd
);
10493 install_element(INTERFACE_NODE
, &interface_ip_igmp_version_cmd
);
10494 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_version_cmd
);
10495 install_element(INTERFACE_NODE
, &interface_ip_igmp_query_interval_cmd
);
10496 install_element(INTERFACE_NODE
,
10497 &interface_no_ip_igmp_query_interval_cmd
);
10498 install_element(INTERFACE_NODE
,
10499 &interface_ip_igmp_query_max_response_time_cmd
);
10500 install_element(INTERFACE_NODE
,
10501 &interface_no_ip_igmp_query_max_response_time_cmd
);
10502 install_element(INTERFACE_NODE
,
10503 &interface_ip_igmp_query_max_response_time_dsec_cmd
);
10504 install_element(INTERFACE_NODE
,
10505 &interface_no_ip_igmp_query_max_response_time_dsec_cmd
);
10506 install_element(INTERFACE_NODE
,
10507 &interface_ip_igmp_last_member_query_count_cmd
);
10508 install_element(INTERFACE_NODE
,
10509 &interface_no_ip_igmp_last_member_query_count_cmd
);
10510 install_element(INTERFACE_NODE
,
10511 &interface_ip_igmp_last_member_query_interval_cmd
);
10512 install_element(INTERFACE_NODE
,
10513 &interface_no_ip_igmp_last_member_query_interval_cmd
);
10514 install_element(INTERFACE_NODE
, &interface_ip_pim_activeactive_cmd
);
10515 install_element(INTERFACE_NODE
, &interface_ip_pim_ssm_cmd
);
10516 install_element(INTERFACE_NODE
, &interface_no_ip_pim_ssm_cmd
);
10517 install_element(INTERFACE_NODE
, &interface_ip_pim_sm_cmd
);
10518 install_element(INTERFACE_NODE
, &interface_no_ip_pim_sm_cmd
);
10519 install_element(INTERFACE_NODE
, &interface_ip_pim_cmd
);
10520 install_element(INTERFACE_NODE
, &interface_no_ip_pim_cmd
);
10521 install_element(INTERFACE_NODE
, &interface_ip_pim_drprio_cmd
);
10522 install_element(INTERFACE_NODE
, &interface_no_ip_pim_drprio_cmd
);
10523 install_element(INTERFACE_NODE
, &interface_ip_pim_hello_cmd
);
10524 install_element(INTERFACE_NODE
, &interface_no_ip_pim_hello_cmd
);
10525 install_element(INTERFACE_NODE
, &interface_ip_pim_boundary_oil_cmd
);
10526 install_element(INTERFACE_NODE
, &interface_no_ip_pim_boundary_oil_cmd
);
10527 install_element(INTERFACE_NODE
, &interface_ip_igmp_query_generate_cmd
);
10529 // Static mroutes NEB
10530 install_element(INTERFACE_NODE
, &interface_ip_mroute_cmd
);
10531 install_element(INTERFACE_NODE
, &interface_ip_mroute_source_cmd
);
10532 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_cmd
);
10533 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_source_cmd
);
10535 install_element(VIEW_NODE
, &show_ip_igmp_interface_cmd
);
10536 install_element(VIEW_NODE
, &show_ip_igmp_interface_vrf_all_cmd
);
10537 install_element(VIEW_NODE
, &show_ip_igmp_join_cmd
);
10538 install_element(VIEW_NODE
, &show_ip_igmp_join_vrf_all_cmd
);
10539 install_element(VIEW_NODE
, &show_ip_igmp_groups_cmd
);
10540 install_element(VIEW_NODE
, &show_ip_igmp_groups_vrf_all_cmd
);
10541 install_element(VIEW_NODE
, &show_ip_igmp_groups_retransmissions_cmd
);
10542 install_element(VIEW_NODE
, &show_ip_igmp_sources_cmd
);
10543 install_element(VIEW_NODE
, &show_ip_igmp_sources_retransmissions_cmd
);
10544 install_element(VIEW_NODE
, &show_ip_igmp_statistics_cmd
);
10545 install_element(VIEW_NODE
, &show_ip_pim_assert_cmd
);
10546 install_element(VIEW_NODE
, &show_ip_pim_assert_internal_cmd
);
10547 install_element(VIEW_NODE
, &show_ip_pim_assert_metric_cmd
);
10548 install_element(VIEW_NODE
, &show_ip_pim_assert_winner_metric_cmd
);
10549 install_element(VIEW_NODE
, &show_ip_pim_interface_traffic_cmd
);
10550 install_element(VIEW_NODE
, &show_ip_pim_interface_cmd
);
10551 install_element(VIEW_NODE
, &show_ip_pim_interface_vrf_all_cmd
);
10552 install_element(VIEW_NODE
, &show_ip_pim_join_cmd
);
10553 install_element(VIEW_NODE
, &show_ip_pim_join_vrf_all_cmd
);
10554 install_element(VIEW_NODE
, &show_ip_pim_jp_agg_cmd
);
10555 install_element(VIEW_NODE
, &show_ip_pim_local_membership_cmd
);
10556 install_element(VIEW_NODE
, &show_ip_pim_neighbor_cmd
);
10557 install_element(VIEW_NODE
, &show_ip_pim_neighbor_vrf_all_cmd
);
10558 install_element(VIEW_NODE
, &show_ip_pim_rpf_cmd
);
10559 install_element(VIEW_NODE
, &show_ip_pim_rpf_vrf_all_cmd
);
10560 install_element(VIEW_NODE
, &show_ip_pim_secondary_cmd
);
10561 install_element(VIEW_NODE
, &show_ip_pim_state_cmd
);
10562 install_element(VIEW_NODE
, &show_ip_pim_state_vrf_all_cmd
);
10563 install_element(VIEW_NODE
, &show_ip_pim_upstream_cmd
);
10564 install_element(VIEW_NODE
, &show_ip_pim_upstream_vrf_all_cmd
);
10565 install_element(VIEW_NODE
, &show_ip_pim_channel_cmd
);
10566 install_element(VIEW_NODE
, &show_ip_pim_upstream_join_desired_cmd
);
10567 install_element(VIEW_NODE
, &show_ip_pim_upstream_rpf_cmd
);
10568 install_element(VIEW_NODE
, &show_ip_pim_rp_cmd
);
10569 install_element(VIEW_NODE
, &show_ip_pim_rp_vrf_all_cmd
);
10570 install_element(VIEW_NODE
, &show_ip_pim_bsr_cmd
);
10571 install_element(VIEW_NODE
, &show_ip_multicast_cmd
);
10572 install_element(VIEW_NODE
, &show_ip_multicast_vrf_all_cmd
);
10573 install_element(VIEW_NODE
, &show_ip_mroute_cmd
);
10574 install_element(VIEW_NODE
, &show_ip_mroute_vrf_all_cmd
);
10575 install_element(VIEW_NODE
, &show_ip_mroute_count_cmd
);
10576 install_element(VIEW_NODE
, &show_ip_mroute_count_vrf_all_cmd
);
10577 install_element(VIEW_NODE
, &show_ip_mroute_summary_cmd
);
10578 install_element(VIEW_NODE
, &show_ip_mroute_summary_vrf_all_cmd
);
10579 install_element(VIEW_NODE
, &show_ip_rib_cmd
);
10580 install_element(VIEW_NODE
, &show_ip_ssmpingd_cmd
);
10581 install_element(VIEW_NODE
, &show_debugging_pim_cmd
);
10582 install_element(VIEW_NODE
, &show_ip_pim_nexthop_cmd
);
10583 install_element(VIEW_NODE
, &show_ip_pim_nexthop_lookup_cmd
);
10584 install_element(VIEW_NODE
, &show_ip_pim_bsrp_cmd
);
10585 install_element(VIEW_NODE
, &show_ip_pim_bsm_db_cmd
);
10586 install_element(VIEW_NODE
, &show_ip_pim_statistics_cmd
);
10588 install_element(ENABLE_NODE
, &clear_ip_mroute_count_cmd
);
10589 install_element(ENABLE_NODE
, &clear_ip_interfaces_cmd
);
10590 install_element(ENABLE_NODE
, &clear_ip_igmp_interfaces_cmd
);
10591 install_element(ENABLE_NODE
, &clear_ip_mroute_cmd
);
10592 install_element(ENABLE_NODE
, &clear_ip_pim_interfaces_cmd
);
10593 install_element(ENABLE_NODE
, &clear_ip_pim_interface_traffic_cmd
);
10594 install_element(ENABLE_NODE
, &clear_ip_pim_oil_cmd
);
10595 install_element(ENABLE_NODE
, &clear_ip_pim_statistics_cmd
);
10597 install_element(ENABLE_NODE
, &debug_igmp_cmd
);
10598 install_element(ENABLE_NODE
, &no_debug_igmp_cmd
);
10599 install_element(ENABLE_NODE
, &debug_igmp_events_cmd
);
10600 install_element(ENABLE_NODE
, &no_debug_igmp_events_cmd
);
10601 install_element(ENABLE_NODE
, &debug_igmp_packets_cmd
);
10602 install_element(ENABLE_NODE
, &no_debug_igmp_packets_cmd
);
10603 install_element(ENABLE_NODE
, &debug_igmp_trace_cmd
);
10604 install_element(ENABLE_NODE
, &no_debug_igmp_trace_cmd
);
10605 install_element(ENABLE_NODE
, &debug_mroute_cmd
);
10606 install_element(ENABLE_NODE
, &debug_mroute_detail_cmd
);
10607 install_element(ENABLE_NODE
, &no_debug_mroute_cmd
);
10608 install_element(ENABLE_NODE
, &no_debug_mroute_detail_cmd
);
10609 install_element(ENABLE_NODE
, &debug_pim_static_cmd
);
10610 install_element(ENABLE_NODE
, &no_debug_pim_static_cmd
);
10611 install_element(ENABLE_NODE
, &debug_pim_cmd
);
10612 install_element(ENABLE_NODE
, &no_debug_pim_cmd
);
10613 install_element(ENABLE_NODE
, &debug_pim_nht_cmd
);
10614 install_element(ENABLE_NODE
, &no_debug_pim_nht_cmd
);
10615 install_element(ENABLE_NODE
, &debug_pim_nht_rp_cmd
);
10616 install_element(ENABLE_NODE
, &no_debug_pim_nht_rp_cmd
);
10617 install_element(ENABLE_NODE
, &debug_pim_events_cmd
);
10618 install_element(ENABLE_NODE
, &no_debug_pim_events_cmd
);
10619 install_element(ENABLE_NODE
, &debug_pim_packets_cmd
);
10620 install_element(ENABLE_NODE
, &no_debug_pim_packets_cmd
);
10621 install_element(ENABLE_NODE
, &debug_pim_packetdump_send_cmd
);
10622 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_send_cmd
);
10623 install_element(ENABLE_NODE
, &debug_pim_packetdump_recv_cmd
);
10624 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_recv_cmd
);
10625 install_element(ENABLE_NODE
, &debug_pim_trace_cmd
);
10626 install_element(ENABLE_NODE
, &no_debug_pim_trace_cmd
);
10627 install_element(ENABLE_NODE
, &debug_pim_trace_detail_cmd
);
10628 install_element(ENABLE_NODE
, &no_debug_pim_trace_detail_cmd
);
10629 install_element(ENABLE_NODE
, &debug_ssmpingd_cmd
);
10630 install_element(ENABLE_NODE
, &no_debug_ssmpingd_cmd
);
10631 install_element(ENABLE_NODE
, &debug_pim_zebra_cmd
);
10632 install_element(ENABLE_NODE
, &no_debug_pim_zebra_cmd
);
10633 install_element(ENABLE_NODE
, &debug_pim_mlag_cmd
);
10634 install_element(ENABLE_NODE
, &no_debug_pim_mlag_cmd
);
10635 install_element(ENABLE_NODE
, &debug_pim_vxlan_cmd
);
10636 install_element(ENABLE_NODE
, &no_debug_pim_vxlan_cmd
);
10637 install_element(ENABLE_NODE
, &debug_msdp_cmd
);
10638 install_element(ENABLE_NODE
, &no_debug_msdp_cmd
);
10639 install_element(ENABLE_NODE
, &debug_msdp_events_cmd
);
10640 install_element(ENABLE_NODE
, &no_debug_msdp_events_cmd
);
10641 install_element(ENABLE_NODE
, &debug_msdp_packets_cmd
);
10642 install_element(ENABLE_NODE
, &no_debug_msdp_packets_cmd
);
10643 install_element(ENABLE_NODE
, &debug_mtrace_cmd
);
10644 install_element(ENABLE_NODE
, &no_debug_mtrace_cmd
);
10645 install_element(ENABLE_NODE
, &debug_bsm_cmd
);
10646 install_element(ENABLE_NODE
, &no_debug_bsm_cmd
);
10648 install_element(CONFIG_NODE
, &debug_igmp_cmd
);
10649 install_element(CONFIG_NODE
, &no_debug_igmp_cmd
);
10650 install_element(CONFIG_NODE
, &debug_igmp_events_cmd
);
10651 install_element(CONFIG_NODE
, &no_debug_igmp_events_cmd
);
10652 install_element(CONFIG_NODE
, &debug_igmp_packets_cmd
);
10653 install_element(CONFIG_NODE
, &no_debug_igmp_packets_cmd
);
10654 install_element(CONFIG_NODE
, &debug_igmp_trace_cmd
);
10655 install_element(CONFIG_NODE
, &no_debug_igmp_trace_cmd
);
10656 install_element(CONFIG_NODE
, &debug_mroute_cmd
);
10657 install_element(CONFIG_NODE
, &debug_mroute_detail_cmd
);
10658 install_element(CONFIG_NODE
, &no_debug_mroute_cmd
);
10659 install_element(CONFIG_NODE
, &no_debug_mroute_detail_cmd
);
10660 install_element(CONFIG_NODE
, &debug_pim_static_cmd
);
10661 install_element(CONFIG_NODE
, &no_debug_pim_static_cmd
);
10662 install_element(CONFIG_NODE
, &debug_pim_cmd
);
10663 install_element(CONFIG_NODE
, &no_debug_pim_cmd
);
10664 install_element(CONFIG_NODE
, &debug_pim_nht_cmd
);
10665 install_element(CONFIG_NODE
, &no_debug_pim_nht_cmd
);
10666 install_element(CONFIG_NODE
, &debug_pim_nht_rp_cmd
);
10667 install_element(CONFIG_NODE
, &no_debug_pim_nht_rp_cmd
);
10668 install_element(CONFIG_NODE
, &debug_pim_events_cmd
);
10669 install_element(CONFIG_NODE
, &no_debug_pim_events_cmd
);
10670 install_element(CONFIG_NODE
, &debug_pim_packets_cmd
);
10671 install_element(CONFIG_NODE
, &no_debug_pim_packets_cmd
);
10672 install_element(CONFIG_NODE
, &debug_pim_trace_cmd
);
10673 install_element(CONFIG_NODE
, &no_debug_pim_trace_cmd
);
10674 install_element(CONFIG_NODE
, &debug_pim_trace_detail_cmd
);
10675 install_element(CONFIG_NODE
, &no_debug_pim_trace_detail_cmd
);
10676 install_element(CONFIG_NODE
, &debug_ssmpingd_cmd
);
10677 install_element(CONFIG_NODE
, &no_debug_ssmpingd_cmd
);
10678 install_element(CONFIG_NODE
, &debug_pim_zebra_cmd
);
10679 install_element(CONFIG_NODE
, &no_debug_pim_zebra_cmd
);
10680 install_element(CONFIG_NODE
, &debug_pim_vxlan_cmd
);
10681 install_element(CONFIG_NODE
, &no_debug_pim_vxlan_cmd
);
10682 install_element(CONFIG_NODE
, &debug_msdp_cmd
);
10683 install_element(CONFIG_NODE
, &no_debug_msdp_cmd
);
10684 install_element(CONFIG_NODE
, &debug_msdp_events_cmd
);
10685 install_element(CONFIG_NODE
, &no_debug_msdp_events_cmd
);
10686 install_element(CONFIG_NODE
, &debug_msdp_packets_cmd
);
10687 install_element(CONFIG_NODE
, &no_debug_msdp_packets_cmd
);
10688 install_element(CONFIG_NODE
, &debug_mtrace_cmd
);
10689 install_element(CONFIG_NODE
, &no_debug_mtrace_cmd
);
10690 install_element(CONFIG_NODE
, &debug_bsm_cmd
);
10691 install_element(CONFIG_NODE
, &no_debug_bsm_cmd
);
10693 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_member_cmd
);
10694 install_element(VRF_NODE
, &ip_msdp_mesh_group_member_cmd
);
10695 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
10696 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
10697 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_source_cmd
);
10698 install_element(VRF_NODE
, &ip_msdp_mesh_group_source_cmd
);
10699 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
10700 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
10701 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_cmd
);
10702 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_vrf_all_cmd
);
10703 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_cmd
);
10704 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_vrf_all_cmd
);
10705 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_cmd
);
10706 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_vrf_all_cmd
);
10707 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_cmd
);
10708 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_vrf_all_cmd
);
10709 install_element(VIEW_NODE
, &show_ip_pim_ssm_range_cmd
);
10710 install_element(VIEW_NODE
, &show_ip_pim_group_type_cmd
);
10711 install_element(VIEW_NODE
, &show_ip_pim_vxlan_sg_cmd
);
10712 install_element(VIEW_NODE
, &show_ip_pim_vxlan_sg_work_cmd
);
10713 install_element(INTERFACE_NODE
, &interface_pim_use_source_cmd
);
10714 install_element(INTERFACE_NODE
, &interface_no_pim_use_source_cmd
);
10715 /* Install BSM command */
10716 install_element(INTERFACE_NODE
, &ip_pim_bsm_cmd
);
10717 install_element(INTERFACE_NODE
, &no_ip_pim_bsm_cmd
);
10718 install_element(INTERFACE_NODE
, &ip_pim_ucast_bsm_cmd
);
10719 install_element(INTERFACE_NODE
, &no_ip_pim_ucast_bsm_cmd
);
10720 /* Install BFD command */
10721 install_element(INTERFACE_NODE
, &ip_pim_bfd_cmd
);
10722 install_element(INTERFACE_NODE
, &ip_pim_bfd_param_cmd
);
10723 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_cmd
);
10725 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_param_cmd
);
10726 #endif /* !HAVE_BFDD */