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 pim_interface
*pim_ifp
;
918 struct pim_neighbor
*neigh
;
919 struct pim_upstream
*up
;
921 char dr_str
[INET_ADDRSTRLEN
];
924 char grp_str
[INET_ADDRSTRLEN
];
925 char hello_period
[10];
926 char hello_timer
[10];
927 char neigh_src_str
[INET_ADDRSTRLEN
];
928 char src_str
[INET_ADDRSTRLEN
];
929 char stat_uptime
[10];
932 int found_ifname
= 0;
934 json_object
*json
= NULL
;
935 json_object
*json_row
= NULL
;
936 json_object
*json_pim_neighbor
= NULL
;
937 json_object
*json_pim_neighbors
= NULL
;
938 json_object
*json_group
= NULL
;
939 json_object
*json_group_source
= NULL
;
940 json_object
*json_fhr_sources
= NULL
;
941 struct pim_secondary_addr
*sec_addr
;
942 struct listnode
*sec_node
;
944 now
= pim_time_monotonic_sec();
947 json
= json_object_new_object();
949 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
955 if (strcmp(ifname
, "detail") && strcmp(ifname
, ifp
->name
))
959 ifaddr
= pim_ifp
->primary_address
;
960 pim_inet4_dump("<dr?>", pim_ifp
->pim_dr_addr
, dr_str
,
962 pim_time_uptime_begin(dr_uptime
, sizeof(dr_uptime
), now
,
963 pim_ifp
->pim_dr_election_last
);
964 pim_time_timer_to_hhmmss(hello_timer
, sizeof(hello_timer
),
965 pim_ifp
->t_pim_hello_timer
);
966 pim_time_mmss(hello_period
, sizeof(hello_period
),
967 pim_ifp
->pim_hello_period
);
968 pim_time_uptime(stat_uptime
, sizeof(stat_uptime
),
969 now
- pim_ifp
->pim_ifstat_start
);
970 if (pim_ifp
->pim_sock_fd
>= 0)
971 mloop
= pim_socket_mcastloop_get(pim_ifp
->pim_sock_fd
);
976 char pbuf
[PREFIX2STR_BUFFER
];
977 json_row
= json_object_new_object();
978 json_object_pim_ifp_add(json_row
, ifp
);
980 if (pim_ifp
->update_source
.s_addr
!= INADDR_ANY
) {
981 json_object_string_add(
982 json_row
, "useSource",
983 inet_ntoa(pim_ifp
->update_source
));
985 if (pim_ifp
->sec_addr_list
) {
986 json_object
*sec_list
= NULL
;
988 sec_list
= json_object_new_array();
989 for (ALL_LIST_ELEMENTS_RO(
990 pim_ifp
->sec_addr_list
, sec_node
,
992 json_object_array_add(
994 json_object_new_string(
1000 json_object_object_add(json_row
,
1001 "secondaryAddressList",
1006 if (pim_ifp
->pim_neighbor_list
->count
) {
1007 json_pim_neighbors
= json_object_new_object();
1009 for (ALL_LIST_ELEMENTS_RO(
1010 pim_ifp
->pim_neighbor_list
,
1011 neighnode
, neigh
)) {
1013 json_object_new_object();
1014 pim_inet4_dump("<src?>",
1017 sizeof(neigh_src_str
));
1018 pim_time_uptime(uptime
, sizeof(uptime
),
1019 now
- neigh
->creation
);
1020 pim_time_timer_to_hhmmss(
1021 expire
, sizeof(expire
),
1022 neigh
->t_expire_timer
);
1024 json_object_string_add(
1025 json_pim_neighbor
, "address",
1027 json_object_string_add(
1028 json_pim_neighbor
, "upTime",
1030 json_object_string_add(
1031 json_pim_neighbor
, "holdtime",
1034 json_object_object_add(
1040 json_object_object_add(json_row
, "neighbors",
1041 json_pim_neighbors
);
1044 json_object_string_add(json_row
, "drAddress", dr_str
);
1045 json_object_int_add(json_row
, "drPriority",
1046 pim_ifp
->pim_dr_priority
);
1047 json_object_string_add(json_row
, "drUptime", dr_uptime
);
1048 json_object_int_add(json_row
, "drElections",
1049 pim_ifp
->pim_dr_election_count
);
1050 json_object_int_add(json_row
, "drChanges",
1051 pim_ifp
->pim_dr_election_changes
);
1054 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
1055 if (ifp
!= up
->rpf
.source_nexthop
.interface
)
1058 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
))
1061 if (!json_fhr_sources
)
1063 json_object_new_object();
1065 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
,
1067 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
,
1069 pim_time_uptime(uptime
, sizeof(uptime
),
1070 now
- up
->state_transition
);
1073 * Does this group live in json_fhr_sources?
1076 json_object_object_get_ex(json_fhr_sources
,
1077 grp_str
, &json_group
);
1080 json_group
= json_object_new_object();
1081 json_object_object_add(json_fhr_sources
,
1086 json_group_source
= json_object_new_object();
1087 json_object_string_add(json_group_source
,
1089 json_object_string_add(json_group_source
,
1091 json_object_string_add(json_group_source
,
1093 json_object_object_add(json_group
, src_str
,
1097 if (json_fhr_sources
) {
1098 json_object_object_add(json_row
,
1103 json_object_int_add(json_row
, "helloPeriod",
1104 pim_ifp
->pim_hello_period
);
1105 json_object_string_add(json_row
, "helloTimer",
1107 json_object_string_add(json_row
, "helloStatStart",
1109 json_object_int_add(json_row
, "helloReceived",
1110 pim_ifp
->pim_ifstat_hello_recv
);
1111 json_object_int_add(json_row
, "helloReceivedFailed",
1112 pim_ifp
->pim_ifstat_hello_recvfail
);
1113 json_object_int_add(json_row
, "helloSend",
1114 pim_ifp
->pim_ifstat_hello_sent
);
1115 json_object_int_add(json_row
, "hellosendFailed",
1116 pim_ifp
->pim_ifstat_hello_sendfail
);
1117 json_object_int_add(json_row
, "helloGenerationId",
1118 pim_ifp
->pim_generation_id
);
1119 json_object_int_add(json_row
, "flagMulticastLoop",
1122 json_object_int_add(
1123 json_row
, "effectivePropagationDelay",
1124 pim_if_effective_propagation_delay_msec(ifp
));
1125 json_object_int_add(
1126 json_row
, "effectiveOverrideInterval",
1127 pim_if_effective_override_interval_msec(ifp
));
1128 json_object_int_add(
1129 json_row
, "joinPruneOverrideInterval",
1130 pim_if_jp_override_interval_msec(ifp
));
1132 json_object_int_add(
1133 json_row
, "propagationDelay",
1134 pim_ifp
->pim_propagation_delay_msec
);
1135 json_object_int_add(
1136 json_row
, "propagationDelayHighest",
1137 pim_ifp
->pim_neighbors_highest_propagation_delay_msec
);
1138 json_object_int_add(
1139 json_row
, "overrideInterval",
1140 pim_ifp
->pim_override_interval_msec
);
1141 json_object_int_add(
1142 json_row
, "overrideIntervalHighest",
1143 pim_ifp
->pim_neighbors_highest_override_interval_msec
);
1144 json_object_object_add(json
, ifp
->name
, json_row
);
1147 vty_out(vty
, "Interface : %s\n", ifp
->name
);
1148 vty_out(vty
, "State : %s\n",
1149 if_is_up(ifp
) ? "up" : "down");
1150 if (pim_ifp
->update_source
.s_addr
!= INADDR_ANY
) {
1151 vty_out(vty
, "Use Source : %s\n",
1152 inet_ntoa(pim_ifp
->update_source
));
1154 if (pim_ifp
->sec_addr_list
) {
1155 char pbuf
[PREFIX2STR_BUFFER
];
1156 vty_out(vty
, "Address : %s (primary)\n",
1158 for (ALL_LIST_ELEMENTS_RO(
1159 pim_ifp
->sec_addr_list
, sec_node
,
1161 vty_out(vty
, " %s\n",
1162 prefix2str(&sec_addr
->addr
,
1163 pbuf
, sizeof(pbuf
)));
1166 vty_out(vty
, "Address : %s\n",
1174 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
,
1175 neighnode
, neigh
)) {
1178 vty_out(vty
, "PIM Neighbors\n");
1179 vty_out(vty
, "-------------\n");
1183 pim_inet4_dump("<src?>", neigh
->source_addr
,
1185 sizeof(neigh_src_str
));
1186 pim_time_uptime(uptime
, sizeof(uptime
),
1187 now
- neigh
->creation
);
1188 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
1189 neigh
->t_expire_timer
);
1191 "%-15s : up for %s, holdtime expires in %s\n",
1192 neigh_src_str
, uptime
, expire
);
1195 if (!print_header
) {
1200 vty_out(vty
, "Designated Router\n");
1201 vty_out(vty
, "-----------------\n");
1202 vty_out(vty
, "Address : %s\n", dr_str
);
1203 vty_out(vty
, "Priority : %u(%d)\n",
1204 pim_ifp
->pim_dr_priority
,
1205 pim_ifp
->pim_dr_num_nondrpri_neighbors
);
1206 vty_out(vty
, "Uptime : %s\n", dr_uptime
);
1207 vty_out(vty
, "Elections : %d\n",
1208 pim_ifp
->pim_dr_election_count
);
1209 vty_out(vty
, "Changes : %d\n",
1210 pim_ifp
->pim_dr_election_changes
);
1216 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
1217 if (!up
->rpf
.source_nexthop
.interface
)
1220 if (strcmp(ifp
->name
,
1221 up
->rpf
.source_nexthop
1226 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
))
1231 "FHR - First Hop Router\n");
1233 "----------------------\n");
1237 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
,
1239 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
,
1241 pim_time_uptime(uptime
, sizeof(uptime
),
1242 now
- up
->state_transition
);
1244 "%s : %s is a source, uptime is %s\n",
1245 grp_str
, src_str
, uptime
);
1248 if (!print_header
) {
1253 vty_out(vty
, "Hellos\n");
1254 vty_out(vty
, "------\n");
1255 vty_out(vty
, "Period : %d\n",
1256 pim_ifp
->pim_hello_period
);
1257 vty_out(vty
, "Timer : %s\n", hello_timer
);
1258 vty_out(vty
, "StatStart : %s\n", stat_uptime
);
1259 vty_out(vty
, "Receive : %d\n",
1260 pim_ifp
->pim_ifstat_hello_recv
);
1261 vty_out(vty
, "Receive Failed : %d\n",
1262 pim_ifp
->pim_ifstat_hello_recvfail
);
1263 vty_out(vty
, "Send : %d\n",
1264 pim_ifp
->pim_ifstat_hello_sent
);
1265 vty_out(vty
, "Send Failed : %d\n",
1266 pim_ifp
->pim_ifstat_hello_sendfail
);
1267 vty_out(vty
, "Generation ID : %08x\n",
1268 pim_ifp
->pim_generation_id
);
1272 pim_print_ifp_flags(vty
, ifp
, mloop
);
1274 vty_out(vty
, "Join Prune Interval\n");
1275 vty_out(vty
, "-------------------\n");
1276 vty_out(vty
, "LAN Delay : %s\n",
1277 pim_if_lan_delay_enabled(ifp
) ? "yes" : "no");
1278 vty_out(vty
, "Effective Propagation Delay : %d msec\n",
1279 pim_if_effective_propagation_delay_msec(ifp
));
1280 vty_out(vty
, "Effective Override Interval : %d msec\n",
1281 pim_if_effective_override_interval_msec(ifp
));
1282 vty_out(vty
, "Join Prune Override Interval : %d msec\n",
1283 pim_if_jp_override_interval_msec(ifp
));
1287 vty_out(vty
, "LAN Prune Delay\n");
1288 vty_out(vty
, "---------------\n");
1289 vty_out(vty
, "Propagation Delay : %d msec\n",
1290 pim_ifp
->pim_propagation_delay_msec
);
1291 vty_out(vty
, "Propagation Delay (Highest) : %d msec\n",
1292 pim_ifp
->pim_neighbors_highest_propagation_delay_msec
);
1293 vty_out(vty
, "Override Interval : %d msec\n",
1294 pim_ifp
->pim_override_interval_msec
);
1295 vty_out(vty
, "Override Interval (Highest) : %d msec\n",
1296 pim_ifp
->pim_neighbors_highest_override_interval_msec
);
1303 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1304 json
, JSON_C_TO_STRING_PRETTY
));
1305 json_object_free(json
);
1308 vty_out(vty
, "%% No such interface\n");
1312 static void igmp_show_statistics(struct pim_instance
*pim
, struct vty
*vty
,
1313 const char *ifname
, bool uj
)
1315 struct interface
*ifp
;
1316 struct igmp_stats rx_stats
;
1318 igmp_stats_init(&rx_stats
);
1320 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1321 struct pim_interface
*pim_ifp
;
1322 struct listnode
*sock_node
;
1323 struct igmp_sock
*igmp
;
1325 pim_ifp
= ifp
->info
;
1330 if (ifname
&& strcmp(ifname
, ifp
->name
))
1333 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
1335 igmp_stats_add(&rx_stats
, &igmp
->rx_stats
);
1339 json_object
*json
= NULL
;
1340 json_object
*json_row
= NULL
;
1342 json
= json_object_new_object();
1343 json_row
= json_object_new_object();
1345 json_object_string_add(json_row
, "name", ifname
? ifname
:
1347 json_object_int_add(json_row
, "queryV1", rx_stats
.query_v1
);
1348 json_object_int_add(json_row
, "queryV2", rx_stats
.query_v2
);
1349 json_object_int_add(json_row
, "queryV3", rx_stats
.query_v3
);
1350 json_object_int_add(json_row
, "leaveV3", rx_stats
.leave_v2
);
1351 json_object_int_add(json_row
, "reportV1", rx_stats
.report_v1
);
1352 json_object_int_add(json_row
, "reportV2", rx_stats
.report_v2
);
1353 json_object_int_add(json_row
, "reportV3", rx_stats
.report_v3
);
1354 json_object_int_add(json_row
, "mtraceResponse",
1355 rx_stats
.mtrace_rsp
);
1356 json_object_int_add(json_row
, "mtraceRequest",
1357 rx_stats
.mtrace_req
);
1358 json_object_int_add(json_row
, "unsupported",
1359 rx_stats
.unsupported
);
1360 json_object_object_add(json
, ifname
? ifname
: "global",
1362 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1363 json
, JSON_C_TO_STRING_PRETTY
));
1364 json_object_free(json
);
1366 vty_out(vty
, "IGMP RX statistics\n");
1367 vty_out(vty
, "Interface : %s\n",
1368 ifname
? ifname
: "global");
1369 vty_out(vty
, "V1 query : %u\n", rx_stats
.query_v1
);
1370 vty_out(vty
, "V2 query : %u\n", rx_stats
.query_v2
);
1371 vty_out(vty
, "V3 query : %u\n", rx_stats
.query_v3
);
1372 vty_out(vty
, "V2 leave : %u\n", rx_stats
.leave_v2
);
1373 vty_out(vty
, "V1 report : %u\n", rx_stats
.report_v1
);
1374 vty_out(vty
, "V2 report : %u\n", rx_stats
.report_v2
);
1375 vty_out(vty
, "V3 report : %u\n", rx_stats
.report_v3
);
1376 vty_out(vty
, "mtrace response : %u\n", rx_stats
.mtrace_rsp
);
1377 vty_out(vty
, "mtrace request : %u\n", rx_stats
.mtrace_req
);
1378 vty_out(vty
, "unsupported : %u\n", rx_stats
.unsupported
);
1382 static void pim_show_interfaces(struct pim_instance
*pim
, struct vty
*vty
,
1385 struct interface
*ifp
;
1386 struct pim_interface
*pim_ifp
;
1387 struct pim_upstream
*up
;
1390 int pim_ifchannels
= 0;
1391 json_object
*json
= NULL
;
1392 json_object
*json_row
= NULL
;
1393 json_object
*json_tmp
;
1395 json
= json_object_new_object();
1397 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1398 pim_ifp
= ifp
->info
;
1403 pim_nbrs
= pim_ifp
->pim_neighbor_list
->count
;
1404 pim_ifchannels
= pim_if_ifchannel_count(pim_ifp
);
1407 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
)
1408 if (ifp
== up
->rpf
.source_nexthop
.interface
)
1409 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
1412 json_row
= json_object_new_object();
1413 json_object_pim_ifp_add(json_row
, ifp
);
1414 json_object_int_add(json_row
, "pimNeighbors", pim_nbrs
);
1415 json_object_int_add(json_row
, "pimIfChannels", pim_ifchannels
);
1416 json_object_int_add(json_row
, "firstHopRouterCount", fhr
);
1417 json_object_string_add(json_row
, "pimDesignatedRouter",
1418 inet_ntoa(pim_ifp
->pim_dr_addr
));
1420 if (pim_ifp
->pim_dr_addr
.s_addr
1421 == pim_ifp
->primary_address
.s_addr
)
1422 json_object_boolean_true_add(
1423 json_row
, "pimDesignatedRouterLocal");
1425 json_object_object_add(json
, ifp
->name
, json_row
);
1429 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1430 json
, JSON_C_TO_STRING_PRETTY
));
1433 "Interface State Address PIM Nbrs PIM DR FHR IfChannels\n");
1435 json_object_object_foreach(json
, key
, val
)
1437 vty_out(vty
, "%-16s ", key
);
1439 json_object_object_get_ex(val
, "state", &json_tmp
);
1440 vty_out(vty
, "%5s ", json_object_get_string(json_tmp
));
1442 json_object_object_get_ex(val
, "address", &json_tmp
);
1443 vty_out(vty
, "%15s ",
1444 json_object_get_string(json_tmp
));
1446 json_object_object_get_ex(val
, "pimNeighbors",
1448 vty_out(vty
, "%8d ", json_object_get_int(json_tmp
));
1450 if (json_object_object_get_ex(
1451 val
, "pimDesignatedRouterLocal",
1453 vty_out(vty
, "%15s ", "local");
1455 json_object_object_get_ex(
1456 val
, "pimDesignatedRouter", &json_tmp
);
1457 vty_out(vty
, "%15s ",
1458 json_object_get_string(json_tmp
));
1461 json_object_object_get_ex(val
, "firstHopRouter",
1463 vty_out(vty
, "%3d ", json_object_get_int(json_tmp
));
1465 json_object_object_get_ex(val
, "pimIfChannels",
1467 vty_out(vty
, "%9d\n", json_object_get_int(json_tmp
));
1471 json_object_free(json
);
1474 static void pim_show_interface_traffic(struct pim_instance
*pim
,
1475 struct vty
*vty
, bool uj
)
1477 struct interface
*ifp
= NULL
;
1478 struct pim_interface
*pim_ifp
= NULL
;
1479 json_object
*json
= NULL
;
1480 json_object
*json_row
= NULL
;
1483 json
= json_object_new_object();
1486 vty_out(vty
, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s%-17s\n",
1487 "Interface", " HELLO", " JOIN",
1488 " PRUNE", " REGISTER", "REGISTER-STOP",
1490 vty_out(vty
, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s%-17s\n", "",
1491 " Rx/Tx", " Rx/Tx", " Rx/Tx",
1492 " Rx/Tx", " Rx/Tx", " Rx/Tx",
1495 "---------------------------------------------------------------------------------------------------------------\n");
1498 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1499 pim_ifp
= ifp
->info
;
1504 if (pim_ifp
->pim_sock_fd
< 0)
1507 json_row
= json_object_new_object();
1508 json_object_pim_ifp_add(json_row
, ifp
);
1509 json_object_int_add(json_row
, "helloRx",
1510 pim_ifp
->pim_ifstat_hello_recv
);
1511 json_object_int_add(json_row
, "helloTx",
1512 pim_ifp
->pim_ifstat_hello_sent
);
1513 json_object_int_add(json_row
, "joinRx",
1514 pim_ifp
->pim_ifstat_join_recv
);
1515 json_object_int_add(json_row
, "joinTx",
1516 pim_ifp
->pim_ifstat_join_send
);
1517 json_object_int_add(json_row
, "registerRx",
1518 pim_ifp
->pim_ifstat_reg_recv
);
1519 json_object_int_add(json_row
, "registerTx",
1520 pim_ifp
->pim_ifstat_reg_recv
);
1521 json_object_int_add(json_row
, "registerStopRx",
1522 pim_ifp
->pim_ifstat_reg_stop_recv
);
1523 json_object_int_add(json_row
, "registerStopTx",
1524 pim_ifp
->pim_ifstat_reg_stop_send
);
1525 json_object_int_add(json_row
, "assertRx",
1526 pim_ifp
->pim_ifstat_assert_recv
);
1527 json_object_int_add(json_row
, "assertTx",
1528 pim_ifp
->pim_ifstat_assert_send
);
1529 json_object_int_add(json_row
, "bsmRx",
1530 pim_ifp
->pim_ifstat_bsm_rx
);
1531 json_object_int_add(json_row
, "bsmTx",
1532 pim_ifp
->pim_ifstat_bsm_tx
);
1533 json_object_object_add(json
, ifp
->name
, json_row
);
1536 "%-16s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7" PRIu64
"/%-7" PRIu64
"\n",
1537 ifp
->name
, pim_ifp
->pim_ifstat_hello_recv
,
1538 pim_ifp
->pim_ifstat_hello_sent
,
1539 pim_ifp
->pim_ifstat_join_recv
,
1540 pim_ifp
->pim_ifstat_join_send
,
1541 pim_ifp
->pim_ifstat_prune_recv
,
1542 pim_ifp
->pim_ifstat_prune_send
,
1543 pim_ifp
->pim_ifstat_reg_recv
,
1544 pim_ifp
->pim_ifstat_reg_send
,
1545 pim_ifp
->pim_ifstat_reg_stop_recv
,
1546 pim_ifp
->pim_ifstat_reg_stop_send
,
1547 pim_ifp
->pim_ifstat_assert_recv
,
1548 pim_ifp
->pim_ifstat_assert_send
,
1549 pim_ifp
->pim_ifstat_bsm_rx
,
1550 pim_ifp
->pim_ifstat_bsm_tx
);
1554 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1555 json
, JSON_C_TO_STRING_PRETTY
));
1556 json_object_free(json
);
1560 static void pim_show_interface_traffic_single(struct pim_instance
*pim
,
1562 const char *ifname
, bool uj
)
1564 struct interface
*ifp
= NULL
;
1565 struct pim_interface
*pim_ifp
= NULL
;
1566 json_object
*json
= NULL
;
1567 json_object
*json_row
= NULL
;
1568 uint8_t found_ifname
= 0;
1571 json
= json_object_new_object();
1574 vty_out(vty
, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s%-17s\n",
1575 "Interface", " HELLO", " JOIN", " PRUNE",
1576 " REGISTER", " REGISTER-STOP", " ASSERT",
1578 vty_out(vty
, "%-14s%-18s%-17s%-17s%-17s%-17s%-17s%-17s\n", "",
1579 " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1580 " Rx/Tx", " Rx/Tx", " Rx/Tx");
1582 "-------------------------------------------------------------------------------------------------------------------------------\n");
1585 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1586 if (strcmp(ifname
, ifp
->name
))
1589 pim_ifp
= ifp
->info
;
1594 if (pim_ifp
->pim_sock_fd
< 0)
1599 json_row
= json_object_new_object();
1600 json_object_pim_ifp_add(json_row
, ifp
);
1601 json_object_int_add(json_row
, "helloRx",
1602 pim_ifp
->pim_ifstat_hello_recv
);
1603 json_object_int_add(json_row
, "helloTx",
1604 pim_ifp
->pim_ifstat_hello_sent
);
1605 json_object_int_add(json_row
, "joinRx",
1606 pim_ifp
->pim_ifstat_join_recv
);
1607 json_object_int_add(json_row
, "joinTx",
1608 pim_ifp
->pim_ifstat_join_send
);
1609 json_object_int_add(json_row
, "registerRx",
1610 pim_ifp
->pim_ifstat_reg_recv
);
1611 json_object_int_add(json_row
, "registerTx",
1612 pim_ifp
->pim_ifstat_reg_recv
);
1613 json_object_int_add(json_row
, "registerStopRx",
1614 pim_ifp
->pim_ifstat_reg_stop_recv
);
1615 json_object_int_add(json_row
, "registerStopTx",
1616 pim_ifp
->pim_ifstat_reg_stop_send
);
1617 json_object_int_add(json_row
, "assertRx",
1618 pim_ifp
->pim_ifstat_assert_recv
);
1619 json_object_int_add(json_row
, "assertTx",
1620 pim_ifp
->pim_ifstat_assert_send
);
1621 json_object_int_add(json_row
, "bsmRx",
1622 pim_ifp
->pim_ifstat_bsm_rx
);
1623 json_object_int_add(json_row
, "bsmTx",
1624 pim_ifp
->pim_ifstat_bsm_tx
);
1626 json_object_object_add(json
, ifp
->name
, json_row
);
1629 "%-16s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7" PRIu64
"/%-7" PRIu64
"\n",
1630 ifp
->name
, pim_ifp
->pim_ifstat_hello_recv
,
1631 pim_ifp
->pim_ifstat_hello_sent
,
1632 pim_ifp
->pim_ifstat_join_recv
,
1633 pim_ifp
->pim_ifstat_join_send
,
1634 pim_ifp
->pim_ifstat_prune_recv
,
1635 pim_ifp
->pim_ifstat_prune_send
,
1636 pim_ifp
->pim_ifstat_reg_recv
,
1637 pim_ifp
->pim_ifstat_reg_send
,
1638 pim_ifp
->pim_ifstat_reg_stop_recv
,
1639 pim_ifp
->pim_ifstat_reg_stop_send
,
1640 pim_ifp
->pim_ifstat_assert_recv
,
1641 pim_ifp
->pim_ifstat_assert_send
,
1642 pim_ifp
->pim_ifstat_bsm_rx
,
1643 pim_ifp
->pim_ifstat_bsm_tx
);
1647 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1648 json
, JSON_C_TO_STRING_PRETTY
));
1649 json_object_free(json
);
1652 vty_out(vty
, "%% No such interface\n");
1656 static void pim_show_join_helper(struct vty
*vty
, struct pim_interface
*pim_ifp
,
1657 struct pim_ifchannel
*ch
, json_object
*json
,
1658 time_t now
, bool uj
)
1660 char ch_src_str
[INET_ADDRSTRLEN
];
1661 char ch_grp_str
[INET_ADDRSTRLEN
];
1662 json_object
*json_iface
= NULL
;
1663 json_object
*json_row
= NULL
;
1664 json_object
*json_grp
= NULL
;
1665 struct in_addr ifaddr
;
1670 ifaddr
= pim_ifp
->primary_address
;
1672 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
1673 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
1675 pim_time_uptime_begin(uptime
, sizeof(uptime
), now
, ch
->ifjoin_creation
);
1676 pim_time_timer_to_mmss(expire
, sizeof(expire
),
1677 ch
->t_ifjoin_expiry_timer
);
1678 pim_time_timer_to_mmss(prune
, sizeof(prune
),
1679 ch
->t_ifjoin_prune_pending_timer
);
1682 json_object_object_get_ex(json
, ch
->interface
->name
,
1686 json_iface
= json_object_new_object();
1687 json_object_pim_ifp_add(json_iface
, ch
->interface
);
1688 json_object_object_add(json
, ch
->interface
->name
,
1692 json_row
= json_object_new_object();
1693 json_object_string_add(json_row
, "source", ch_src_str
);
1694 json_object_string_add(json_row
, "group", ch_grp_str
);
1695 json_object_string_add(json_row
, "upTime", uptime
);
1696 json_object_string_add(json_row
, "expire", expire
);
1697 json_object_string_add(json_row
, "prune", prune
);
1698 json_object_string_add(
1699 json_row
, "channelJoinName",
1700 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
, ch
->flags
));
1701 if (PIM_IF_FLAG_TEST_S_G_RPT(ch
->flags
))
1702 json_object_int_add(json_row
, "SGRpt", 1);
1704 json_object_object_get_ex(json_iface
, ch_grp_str
, &json_grp
);
1706 json_grp
= json_object_new_object();
1707 json_object_object_add(json_grp
, ch_src_str
, json_row
);
1708 json_object_object_add(json_iface
, ch_grp_str
,
1711 json_object_object_add(json_grp
, ch_src_str
, json_row
);
1713 vty_out(vty
, "%-16s %-15s %-15s %-15s %-10s %8s %-6s %5s\n",
1714 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
,
1716 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
, ch
->flags
),
1717 uptime
, expire
, prune
);
1721 static void pim_show_join(struct pim_instance
*pim
, struct vty
*vty
,
1722 struct prefix_sg
*sg
, bool uj
)
1724 struct pim_interface
*pim_ifp
;
1725 struct pim_ifchannel
*ch
;
1726 struct interface
*ifp
;
1728 json_object
*json
= NULL
;
1730 now
= pim_time_monotonic_sec();
1733 json
= json_object_new_object();
1736 "Interface Address Source Group State Uptime Expire Prune\n");
1738 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1739 pim_ifp
= ifp
->info
;
1743 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
1744 if (sg
->grp
.s_addr
!= INADDR_ANY
1745 && sg
->grp
.s_addr
!= ch
->sg
.grp
.s_addr
)
1747 if (sg
->src
.s_addr
!= INADDR_ANY
1748 && sg
->src
.s_addr
!= ch
->sg
.src
.s_addr
)
1750 pim_show_join_helper(vty
, pim_ifp
, ch
, json
, now
, uj
);
1751 } /* scan interface channels */
1755 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1756 json
, JSON_C_TO_STRING_PRETTY
));
1757 json_object_free(json
);
1761 static void pim_show_neighbors_single(struct pim_instance
*pim
, struct vty
*vty
,
1762 const char *neighbor
, bool uj
)
1764 struct listnode
*neighnode
;
1765 struct interface
*ifp
;
1766 struct pim_interface
*pim_ifp
;
1767 struct pim_neighbor
*neigh
;
1769 int found_neighbor
= 0;
1770 int option_address_list
;
1771 int option_dr_priority
;
1772 int option_generation_id
;
1773 int option_holdtime
;
1774 int option_lan_prune_delay
;
1778 char neigh_src_str
[INET_ADDRSTRLEN
];
1780 json_object
*json
= NULL
;
1781 json_object
*json_ifp
= NULL
;
1782 json_object
*json_row
= NULL
;
1784 now
= pim_time_monotonic_sec();
1787 json
= json_object_new_object();
1789 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1790 pim_ifp
= ifp
->info
;
1795 if (pim_ifp
->pim_sock_fd
< 0)
1798 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
1800 pim_inet4_dump("<src?>", neigh
->source_addr
,
1801 neigh_src_str
, sizeof(neigh_src_str
));
1804 * The user can specify either the interface name or the
1806 * If this pim_ifp matches neither then skip.
1808 if (strcmp(neighbor
, "detail")
1809 && strcmp(neighbor
, ifp
->name
)
1810 && strcmp(neighbor
, neigh_src_str
))
1814 pim_time_uptime(uptime
, sizeof(uptime
),
1815 now
- neigh
->creation
);
1816 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
1817 neigh
->t_expire_timer
);
1819 option_address_list
= 0;
1820 option_dr_priority
= 0;
1821 option_generation_id
= 0;
1822 option_holdtime
= 0;
1823 option_lan_prune_delay
= 0;
1826 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1827 PIM_OPTION_MASK_ADDRESS_LIST
))
1828 option_address_list
= 1;
1830 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1831 PIM_OPTION_MASK_DR_PRIORITY
))
1832 option_dr_priority
= 1;
1834 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1835 PIM_OPTION_MASK_GENERATION_ID
))
1836 option_generation_id
= 1;
1838 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1839 PIM_OPTION_MASK_HOLDTIME
))
1840 option_holdtime
= 1;
1842 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1843 PIM_OPTION_MASK_LAN_PRUNE_DELAY
))
1844 option_lan_prune_delay
= 1;
1846 if (PIM_OPTION_IS_SET(
1847 neigh
->hello_options
,
1848 PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION
))
1853 /* Does this ifp live in json? If not create
1855 json_object_object_get_ex(json
, ifp
->name
,
1859 json_ifp
= json_object_new_object();
1860 json_object_pim_ifp_add(json_ifp
, ifp
);
1861 json_object_object_add(json
, ifp
->name
,
1865 json_row
= json_object_new_object();
1866 json_object_string_add(json_row
, "interface",
1868 json_object_string_add(json_row
, "address",
1870 json_object_string_add(json_row
, "upTime",
1872 json_object_string_add(json_row
, "holdtime",
1874 json_object_int_add(json_row
, "drPriority",
1875 neigh
->dr_priority
);
1876 json_object_int_add(json_row
, "generationId",
1877 neigh
->generation_id
);
1879 if (option_address_list
)
1880 json_object_boolean_true_add(
1882 "helloOptionAddressList");
1884 if (option_dr_priority
)
1885 json_object_boolean_true_add(
1887 "helloOptionDrPriority");
1889 if (option_generation_id
)
1890 json_object_boolean_true_add(
1892 "helloOptionGenerationId");
1894 if (option_holdtime
)
1895 json_object_boolean_true_add(
1897 "helloOptionHoldtime");
1899 if (option_lan_prune_delay
)
1900 json_object_boolean_true_add(
1902 "helloOptionLanPruneDelay");
1905 json_object_boolean_true_add(
1906 json_row
, "helloOptionTBit");
1908 json_object_object_add(json_ifp
, neigh_src_str
,
1912 vty_out(vty
, "Interface : %s\n", ifp
->name
);
1913 vty_out(vty
, "Neighbor : %s\n", neigh_src_str
);
1921 " DR Priority : %d\n",
1922 neigh
->dr_priority
);
1924 " Generation ID : %08x\n",
1925 neigh
->generation_id
);
1927 " Override Interval (msec) : %d\n",
1928 neigh
->override_interval_msec
);
1930 " Propagation Delay (msec) : %d\n",
1931 neigh
->propagation_delay_msec
);
1933 " Hello Option - Address List : %s\n",
1934 option_address_list
? "yes" : "no");
1936 " Hello Option - DR Priority : %s\n",
1937 option_dr_priority
? "yes" : "no");
1939 " Hello Option - Generation ID : %s\n",
1940 option_generation_id
? "yes" : "no");
1942 " Hello Option - Holdtime : %s\n",
1943 option_holdtime
? "yes" : "no");
1945 " Hello Option - LAN Prune Delay : %s\n",
1946 option_lan_prune_delay
? "yes" : "no");
1948 " Hello Option - T-bit : %s\n",
1949 option_t_bit
? "yes" : "no");
1950 pim_bfd_show_info(vty
, neigh
->bfd_info
,
1958 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1959 json
, JSON_C_TO_STRING_PRETTY
));
1960 json_object_free(json
);
1963 if (!found_neighbor
)
1965 "%% No such interface or neighbor\n");
1970 static void pim_show_state(struct pim_instance
*pim
, struct vty
*vty
,
1971 const char *src_or_group
, const char *group
, bool uj
)
1973 struct channel_oil
*c_oil
;
1974 json_object
*json
= NULL
;
1975 json_object
*json_group
= NULL
;
1976 json_object
*json_ifp_in
= NULL
;
1977 json_object
*json_ifp_out
= NULL
;
1978 json_object
*json_source
= NULL
;
1981 now
= pim_time_monotonic_sec();
1984 json
= json_object_new_object();
1987 "Codes: J -> Pim Join, I -> IGMP Report, S -> Source, * -> Inherited from (*,G), V -> VxLAN, M -> Muted");
1989 "\nActive Source Group RPT IIF OIL\n");
1992 frr_each (rb_pim_oil
, &pim
->channel_oil_head
, c_oil
) {
1993 char grp_str
[INET_ADDRSTRLEN
];
1994 char src_str
[INET_ADDRSTRLEN
];
1995 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
1996 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
1998 struct interface
*ifp_in
;
2003 PIM_UPSTREAM_FLAG_TEST_USE_RPT(c_oil
->up
->flags
)) ||
2004 c_oil
->oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
2009 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
2011 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
2013 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
2016 strlcpy(in_ifname
, ifp_in
->name
, sizeof(in_ifname
));
2018 strlcpy(in_ifname
, "<iif?>", sizeof(in_ifname
));
2021 if (strcmp(src_or_group
, src_str
)
2022 && strcmp(src_or_group
, grp_str
))
2025 if (group
&& strcmp(group
, grp_str
))
2031 /* Find the group, create it if it doesn't exist */
2032 json_object_object_get_ex(json
, grp_str
, &json_group
);
2035 json_group
= json_object_new_object();
2036 json_object_object_add(json
, grp_str
,
2040 /* Find the source nested under the group, create it if
2041 * it doesn't exist */
2042 json_object_object_get_ex(json_group
, src_str
,
2046 json_source
= json_object_new_object();
2047 json_object_object_add(json_group
, src_str
,
2051 /* Find the inbound interface nested under the source,
2052 * create it if it doesn't exist */
2053 json_object_object_get_ex(json_source
, in_ifname
,
2057 json_ifp_in
= json_object_new_object();
2058 json_object_object_add(json_source
, in_ifname
,
2060 json_object_int_add(json_source
, "Installed",
2063 json_object_boolean_true_add(
2064 json_source
, "isRpt");
2066 json_object_boolean_false_add(
2067 json_source
, "isRpt");
2068 json_object_int_add(json_source
, "RefCount",
2069 c_oil
->oil_ref_count
);
2070 json_object_int_add(json_source
, "OilListSize",
2072 json_object_int_add(
2073 json_source
, "OilRescan",
2074 c_oil
->oil_inherited_rescan
);
2075 json_object_int_add(json_source
, "LastUsed",
2076 c_oil
->cc
.lastused
);
2077 json_object_int_add(json_source
, "PacketCount",
2079 json_object_int_add(json_source
, "ByteCount",
2081 json_object_int_add(json_source
,
2083 c_oil
->cc
.wrong_if
);
2086 vty_out(vty
, "%-6d %-15s %-15s %-3s %-16s ",
2087 c_oil
->installed
, src_str
, grp_str
,
2088 isRpt
? "y" : "n", in_ifname
);
2091 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
2093 struct interface
*ifp_out
;
2094 char oif_uptime
[10];
2097 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
2101 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
2103 oif_uptime
, sizeof(oif_uptime
),
2104 now
- c_oil
->oif_creation
[oif_vif_index
]);
2107 strlcpy(out_ifname
, ifp_out
->name
, sizeof(out_ifname
));
2109 strlcpy(out_ifname
, "<oif?>", sizeof(out_ifname
));
2112 json_ifp_out
= json_object_new_object();
2113 json_object_string_add(json_ifp_out
, "source",
2115 json_object_string_add(json_ifp_out
, "group",
2117 json_object_string_add(json_ifp_out
,
2120 json_object_string_add(json_ifp_out
,
2121 "outboundInterface",
2123 json_object_int_add(json_ifp_out
, "installed",
2126 json_object_object_add(json_ifp_in
, out_ifname
,
2131 vty_out(vty
, "%s(%c%c%c%c%c)",
2133 (c_oil
->oif_flags
[oif_vif_index
]
2134 & PIM_OIF_FLAG_PROTO_IGMP
)
2137 (c_oil
->oif_flags
[oif_vif_index
]
2138 & PIM_OIF_FLAG_PROTO_PIM
)
2141 (c_oil
->oif_flags
[oif_vif_index
]
2142 & PIM_OIF_FLAG_PROTO_VXLAN
)
2145 (c_oil
->oif_flags
[oif_vif_index
]
2146 & PIM_OIF_FLAG_PROTO_STAR
)
2149 (c_oil
->oif_flags
[oif_vif_index
]
2150 & PIM_OIF_FLAG_MUTE
)
2154 vty_out(vty
, ", %s(%c%c%c%c%c)",
2156 (c_oil
->oif_flags
[oif_vif_index
]
2157 & PIM_OIF_FLAG_PROTO_IGMP
)
2160 (c_oil
->oif_flags
[oif_vif_index
]
2161 & PIM_OIF_FLAG_PROTO_PIM
)
2164 (c_oil
->oif_flags
[oif_vif_index
]
2165 & PIM_OIF_FLAG_PROTO_VXLAN
)
2168 (c_oil
->oif_flags
[oif_vif_index
]
2169 & PIM_OIF_FLAG_PROTO_STAR
)
2172 (c_oil
->oif_flags
[oif_vif_index
]
2173 & PIM_OIF_FLAG_MUTE
)
2185 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2186 json
, JSON_C_TO_STRING_PRETTY
));
2187 json_object_free(json
);
2193 static void pim_show_neighbors(struct pim_instance
*pim
, struct vty
*vty
,
2196 struct listnode
*neighnode
;
2197 struct interface
*ifp
;
2198 struct pim_interface
*pim_ifp
;
2199 struct pim_neighbor
*neigh
;
2203 char neigh_src_str
[INET_ADDRSTRLEN
];
2204 json_object
*json
= NULL
;
2205 json_object
*json_ifp_rows
= NULL
;
2206 json_object
*json_row
= NULL
;
2208 now
= pim_time_monotonic_sec();
2211 json
= json_object_new_object();
2214 "Interface Neighbor Uptime Holdtime DR Pri\n");
2217 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2218 pim_ifp
= ifp
->info
;
2223 if (pim_ifp
->pim_sock_fd
< 0)
2227 json_ifp_rows
= json_object_new_object();
2229 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
2231 pim_inet4_dump("<src?>", neigh
->source_addr
,
2232 neigh_src_str
, sizeof(neigh_src_str
));
2233 pim_time_uptime(uptime
, sizeof(uptime
),
2234 now
- neigh
->creation
);
2235 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
2236 neigh
->t_expire_timer
);
2239 json_row
= json_object_new_object();
2240 json_object_string_add(json_row
, "interface",
2242 json_object_string_add(json_row
, "neighbor",
2244 json_object_string_add(json_row
, "upTime",
2246 json_object_string_add(json_row
, "holdTime",
2248 json_object_int_add(json_row
, "holdTimeMax",
2250 json_object_int_add(json_row
, "drPriority",
2251 neigh
->dr_priority
);
2252 json_object_object_add(json_ifp_rows
,
2253 neigh_src_str
, json_row
);
2256 vty_out(vty
, "%-16s %15s %8s %8s %6d\n",
2257 ifp
->name
, neigh_src_str
, uptime
,
2258 expire
, neigh
->dr_priority
);
2263 json_object_object_add(json
, ifp
->name
, json_ifp_rows
);
2264 json_ifp_rows
= NULL
;
2269 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2270 json
, JSON_C_TO_STRING_PRETTY
));
2271 json_object_free(json
);
2275 static void pim_show_neighbors_secondary(struct pim_instance
*pim
,
2278 struct interface
*ifp
;
2281 "Interface Address Neighbor Secondary \n");
2283 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2284 struct pim_interface
*pim_ifp
;
2285 struct in_addr ifaddr
;
2286 struct listnode
*neighnode
;
2287 struct pim_neighbor
*neigh
;
2289 pim_ifp
= ifp
->info
;
2294 if (pim_ifp
->pim_sock_fd
< 0)
2297 ifaddr
= pim_ifp
->primary_address
;
2299 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
2301 char neigh_src_str
[INET_ADDRSTRLEN
];
2302 struct listnode
*prefix_node
;
2305 if (!neigh
->prefix_list
)
2308 pim_inet4_dump("<src?>", neigh
->source_addr
,
2309 neigh_src_str
, sizeof(neigh_src_str
));
2311 for (ALL_LIST_ELEMENTS_RO(neigh
->prefix_list
,
2313 char neigh_sec_str
[PREFIX2STR_BUFFER
];
2315 prefix2str(p
, neigh_sec_str
,
2316 sizeof(neigh_sec_str
));
2318 vty_out(vty
, "%-16s %-15s %-15s %-15s\n",
2319 ifp
->name
, inet_ntoa(ifaddr
),
2320 neigh_src_str
, neigh_sec_str
);
2326 static void json_object_pim_upstream_add(json_object
*json
,
2327 struct pim_upstream
*up
)
2329 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED
)
2330 json_object_boolean_true_add(json
, "drJoinDesired");
2332 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED
)
2333 json_object_boolean_true_add(json
, "drJoinDesiredUpdated");
2335 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
2336 json_object_boolean_true_add(json
, "firstHopRouter");
2338 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_IGMP
)
2339 json_object_boolean_true_add(json
, "sourceIgmp");
2341 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_PIM
)
2342 json_object_boolean_true_add(json
, "sourcePim");
2344 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_STREAM
)
2345 json_object_boolean_true_add(json
, "sourceStream");
2347 /* XXX: need to print ths flag in the plain text display as well */
2348 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_MSDP
)
2349 json_object_boolean_true_add(json
, "sourceMsdp");
2351 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SEND_SG_RPT_PRUNE
)
2352 json_object_boolean_true_add(json
, "sendSGRptPrune");
2354 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_LHR
)
2355 json_object_boolean_true_add(json
, "lastHopRouter");
2357 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DISABLE_KAT_EXPIRY
)
2358 json_object_boolean_true_add(json
, "disableKATExpiry");
2360 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_STATIC_IIF
)
2361 json_object_boolean_true_add(json
, "staticIncomingInterface");
2363 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_ALLOW_IIF_IN_OIL
)
2364 json_object_boolean_true_add(json
,
2365 "allowIncomingInterfaceinOil");
2367 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_NO_PIMREG_DATA
)
2368 json_object_boolean_true_add(json
, "noPimRegistrationData");
2370 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FORCE_PIMREG
)
2371 json_object_boolean_true_add(json
, "forcePimRegistration");
2373 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_ORIG
)
2374 json_object_boolean_true_add(json
, "sourceVxlanOrigination");
2376 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_TERM
)
2377 json_object_boolean_true_add(json
, "sourceVxlanTermination");
2379 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_VXLAN
)
2380 json_object_boolean_true_add(json
, "mlagVxlan");
2382 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_NON_DF
)
2383 json_object_boolean_true_add(json
,
2384 "mlagNonDesignatedForwarder");
2388 pim_upstream_state2brief_str(enum pim_upstream_state join_state
,
2389 char *state_str
, size_t state_str_len
)
2391 switch (join_state
) {
2392 case PIM_UPSTREAM_NOTJOINED
:
2393 strlcpy(state_str
, "NotJ", state_str_len
);
2395 case PIM_UPSTREAM_JOINED
:
2396 strlcpy(state_str
, "J", state_str_len
);
2399 strlcpy(state_str
, "Unk", state_str_len
);
2404 static const char *pim_reg_state2brief_str(enum pim_reg_state reg_state
,
2405 char *state_str
, size_t state_str_len
)
2407 switch (reg_state
) {
2408 case PIM_REG_NOINFO
:
2409 strlcpy(state_str
, "RegNI", state_str_len
);
2412 strlcpy(state_str
, "RegJ", state_str_len
);
2414 case PIM_REG_JOIN_PENDING
:
2416 strlcpy(state_str
, "RegP", state_str_len
);
2419 strlcpy(state_str
, "Unk", state_str_len
);
2424 static void pim_show_upstream(struct pim_instance
*pim
, struct vty
*vty
,
2425 struct prefix_sg
*sg
, bool uj
)
2427 struct pim_upstream
*up
;
2429 json_object
*json
= NULL
;
2430 json_object
*json_group
= NULL
;
2431 json_object
*json_row
= NULL
;
2433 now
= pim_time_monotonic_sec();
2436 json
= json_object_new_object();
2439 "Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt\n");
2441 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
2442 char src_str
[INET_ADDRSTRLEN
];
2443 char grp_str
[INET_ADDRSTRLEN
];
2445 char join_timer
[10];
2448 char msdp_reg_timer
[10];
2449 char state_str
[PIM_REG_STATE_STR_LEN
];
2451 if (sg
->grp
.s_addr
!= INADDR_ANY
2452 && sg
->grp
.s_addr
!= up
->sg
.grp
.s_addr
)
2454 if (sg
->src
.s_addr
!= INADDR_ANY
2455 && sg
->src
.s_addr
!= up
->sg
.src
.s_addr
)
2458 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2459 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2460 pim_time_uptime(uptime
, sizeof(uptime
),
2461 now
- up
->state_transition
);
2462 pim_time_timer_to_hhmmss(join_timer
, sizeof(join_timer
),
2466 * If the upstream is not dummy and it has a J/P timer for the
2467 * neighbor display that
2469 if (!up
->t_join_timer
&& up
->rpf
.source_nexthop
.interface
) {
2470 struct pim_neighbor
*nbr
;
2472 nbr
= pim_neighbor_find(
2473 up
->rpf
.source_nexthop
.interface
,
2474 up
->rpf
.rpf_addr
.u
.prefix4
);
2476 pim_time_timer_to_hhmmss(join_timer
,
2481 pim_time_timer_to_hhmmss(rs_timer
, sizeof(rs_timer
),
2483 pim_time_timer_to_hhmmss(ka_timer
, sizeof(ka_timer
),
2485 pim_time_timer_to_hhmmss(msdp_reg_timer
, sizeof(msdp_reg_timer
),
2486 up
->t_msdp_reg_timer
);
2488 pim_upstream_state2brief_str(up
->join_state
, state_str
, sizeof(state_str
));
2489 if (up
->reg_state
!= PIM_REG_NOINFO
) {
2490 char tmp_str
[PIM_REG_STATE_STR_LEN
];
2492 sprintf(state_str
+ strlen(state_str
), ",%s",
2493 pim_reg_state2brief_str(up
->reg_state
, tmp_str
,
2498 json_object_object_get_ex(json
, grp_str
, &json_group
);
2501 json_group
= json_object_new_object();
2502 json_object_object_add(json
, grp_str
,
2506 json_row
= json_object_new_object();
2507 json_object_pim_upstream_add(json_row
, up
);
2508 json_object_string_add(
2509 json_row
, "inboundInterface",
2510 up
->rpf
.source_nexthop
.interface
2511 ? up
->rpf
.source_nexthop
.interface
->name
2515 * The RPF address we use is slightly different
2516 * based upon what we are looking up.
2517 * If we have a S, list that unless
2518 * we are the FHR, else we just put
2519 * the RP as the rpfAddress
2521 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
2522 || up
->sg
.src
.s_addr
== INADDR_ANY
) {
2523 char rpf
[PREFIX_STRLEN
];
2524 struct pim_rpf
*rpg
;
2526 rpg
= RP(pim
, up
->sg
.grp
);
2527 pim_inet4_dump("<rpf?>",
2528 rpg
->rpf_addr
.u
.prefix4
, rpf
,
2530 json_object_string_add(json_row
, "rpfAddress",
2533 json_object_string_add(json_row
, "rpfAddress",
2537 json_object_string_add(json_row
, "source", src_str
);
2538 json_object_string_add(json_row
, "group", grp_str
);
2539 json_object_string_add(json_row
, "state", state_str
);
2540 json_object_string_add(
2541 json_row
, "joinState",
2542 pim_upstream_state2str(up
->join_state
));
2543 json_object_string_add(
2544 json_row
, "regState",
2545 pim_reg_state2str(up
->reg_state
, state_str
, sizeof(state_str
)));
2546 json_object_string_add(json_row
, "upTime", uptime
);
2547 json_object_string_add(json_row
, "joinTimer",
2549 json_object_string_add(json_row
, "resetTimer",
2551 json_object_string_add(json_row
, "keepaliveTimer",
2553 json_object_string_add(json_row
, "msdpRegTimer",
2555 json_object_int_add(json_row
, "refCount",
2557 json_object_int_add(json_row
, "sptBit", up
->sptbit
);
2558 json_object_object_add(json_group
, src_str
, json_row
);
2561 "%-16s%-15s %-15s %-11s %-8s %-9s %-9s %-9s %6d\n",
2562 up
->rpf
.source_nexthop
.interface
2563 ? up
->rpf
.source_nexthop
.interface
->name
2565 src_str
, grp_str
, state_str
, uptime
, join_timer
,
2566 rs_timer
, ka_timer
, up
->ref_count
);
2571 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2572 json
, JSON_C_TO_STRING_PRETTY
));
2573 json_object_free(json
);
2577 static void pim_show_channel_helper(struct pim_instance
*pim
,
2579 struct pim_interface
*pim_ifp
,
2580 struct pim_ifchannel
*ch
,
2581 json_object
*json
, bool uj
)
2583 struct pim_upstream
*up
= ch
->upstream
;
2584 json_object
*json_group
= NULL
;
2585 char src_str
[INET_ADDRSTRLEN
];
2586 char grp_str
[INET_ADDRSTRLEN
];
2587 json_object
*json_row
= NULL
;
2589 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2590 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2593 json_object_object_get_ex(json
, grp_str
, &json_group
);
2596 json_group
= json_object_new_object();
2597 json_object_object_add(json
, grp_str
, json_group
);
2600 json_row
= json_object_new_object();
2601 json_object_pim_upstream_add(json_row
, up
);
2602 json_object_string_add(json_row
, "interface",
2603 ch
->interface
->name
);
2604 json_object_string_add(json_row
, "source", src_str
);
2605 json_object_string_add(json_row
, "group", grp_str
);
2607 if (pim_macro_ch_lost_assert(ch
))
2608 json_object_boolean_true_add(json_row
, "lostAssert");
2610 if (pim_macro_chisin_joins(ch
))
2611 json_object_boolean_true_add(json_row
, "joins");
2613 if (pim_macro_chisin_pim_include(ch
))
2614 json_object_boolean_true_add(json_row
, "pimInclude");
2616 if (pim_upstream_evaluate_join_desired(pim
, up
))
2617 json_object_boolean_true_add(json_row
,
2618 "evaluateJoinDesired");
2620 json_object_object_add(json_group
, src_str
, json_row
);
2623 vty_out(vty
, "%-16s %-15s %-15s %-10s %-5s %-10s %-11s %-6s\n",
2624 ch
->interface
->name
, src_str
, grp_str
,
2625 pim_macro_ch_lost_assert(ch
) ? "yes" : "no",
2626 pim_macro_chisin_joins(ch
) ? "yes" : "no",
2627 pim_macro_chisin_pim_include(ch
) ? "yes" : "no",
2628 PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(up
->flags
)
2631 pim_upstream_evaluate_join_desired(pim
, up
) ? "yes"
2636 static void pim_show_channel(struct pim_instance
*pim
, struct vty
*vty
,
2639 struct pim_interface
*pim_ifp
;
2640 struct pim_ifchannel
*ch
;
2641 struct interface
*ifp
;
2643 json_object
*json
= NULL
;
2646 json
= json_object_new_object();
2649 "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD\n");
2651 /* scan per-interface (S,G) state */
2652 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2653 pim_ifp
= ifp
->info
;
2658 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
2659 /* scan all interfaces */
2660 pim_show_channel_helper(pim
, vty
, pim_ifp
, ch
,
2666 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2667 json
, JSON_C_TO_STRING_PRETTY
));
2668 json_object_free(json
);
2672 static void pim_show_join_desired_helper(struct pim_instance
*pim
,
2674 struct pim_upstream
*up
,
2675 json_object
*json
, bool uj
)
2677 json_object
*json_group
= NULL
;
2678 char src_str
[INET_ADDRSTRLEN
];
2679 char grp_str
[INET_ADDRSTRLEN
];
2680 json_object
*json_row
= NULL
;
2682 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2683 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2686 json_object_object_get_ex(json
, grp_str
, &json_group
);
2689 json_group
= json_object_new_object();
2690 json_object_object_add(json
, grp_str
, json_group
);
2693 json_row
= json_object_new_object();
2694 json_object_pim_upstream_add(json_row
, up
);
2695 json_object_string_add(json_row
, "source", src_str
);
2696 json_object_string_add(json_row
, "group", grp_str
);
2698 if (pim_upstream_evaluate_join_desired(pim
, up
))
2699 json_object_boolean_true_add(json_row
,
2700 "evaluateJoinDesired");
2702 json_object_object_add(json_group
, src_str
, json_row
);
2705 vty_out(vty
, "%-15s %-15s %-6s\n",
2707 pim_upstream_evaluate_join_desired(pim
, up
) ? "yes"
2712 static void pim_show_join_desired(struct pim_instance
*pim
, struct vty
*vty
,
2715 struct pim_upstream
*up
;
2717 json_object
*json
= NULL
;
2720 json
= json_object_new_object();
2723 "Source Group EvalJD\n");
2725 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
2726 /* scan all interfaces */
2727 pim_show_join_desired_helper(pim
, vty
, up
,
2732 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2733 json
, JSON_C_TO_STRING_PRETTY
));
2734 json_object_free(json
);
2738 static void pim_show_upstream_rpf(struct pim_instance
*pim
, struct vty
*vty
,
2741 struct pim_upstream
*up
;
2742 json_object
*json
= NULL
;
2743 json_object
*json_group
= NULL
;
2744 json_object
*json_row
= NULL
;
2747 json
= json_object_new_object();
2750 "Source Group RpfIface RibNextHop RpfAddress \n");
2752 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
2753 char src_str
[INET_ADDRSTRLEN
];
2754 char grp_str
[INET_ADDRSTRLEN
];
2755 char rpf_nexthop_str
[PREFIX_STRLEN
];
2756 char rpf_addr_str
[PREFIX_STRLEN
];
2757 struct pim_rpf
*rpf
;
2758 const char *rpf_ifname
;
2762 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2763 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2764 pim_addr_dump("<nexthop?>",
2765 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2766 rpf_nexthop_str
, sizeof(rpf_nexthop_str
));
2767 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2768 sizeof(rpf_addr_str
));
2770 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2773 json_object_object_get_ex(json
, grp_str
, &json_group
);
2776 json_group
= json_object_new_object();
2777 json_object_object_add(json
, grp_str
,
2781 json_row
= json_object_new_object();
2782 json_object_pim_upstream_add(json_row
, up
);
2783 json_object_string_add(json_row
, "source", src_str
);
2784 json_object_string_add(json_row
, "group", grp_str
);
2785 json_object_string_add(json_row
, "rpfInterface",
2787 json_object_string_add(json_row
, "ribNexthop",
2789 json_object_string_add(json_row
, "rpfAddress",
2791 json_object_object_add(json_group
, src_str
, json_row
);
2793 vty_out(vty
, "%-15s %-15s %-16s %-15s %-15s\n", src_str
,
2794 grp_str
, rpf_ifname
, rpf_nexthop_str
,
2800 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2801 json
, JSON_C_TO_STRING_PRETTY
));
2802 json_object_free(json
);
2806 static void show_rpf_refresh_stats(struct vty
*vty
, struct pim_instance
*pim
,
2807 time_t now
, json_object
*json
)
2809 char refresh_uptime
[10];
2811 pim_time_uptime_begin(refresh_uptime
, sizeof(refresh_uptime
), now
,
2812 pim
->rpf_cache_refresh_last
);
2815 json_object_int_add(json
, "rpfCacheRefreshDelayMsecs",
2816 router
->rpf_cache_refresh_delay_msec
);
2817 json_object_int_add(
2818 json
, "rpfCacheRefreshTimer",
2819 pim_time_timer_remain_msec(pim
->rpf_cache_refresher
));
2820 json_object_int_add(json
, "rpfCacheRefreshRequests",
2821 pim
->rpf_cache_refresh_requests
);
2822 json_object_int_add(json
, "rpfCacheRefreshEvents",
2823 pim
->rpf_cache_refresh_events
);
2824 json_object_string_add(json
, "rpfCacheRefreshLast",
2826 json_object_int_add(json
, "nexthopLookups",
2827 pim
->nexthop_lookups
);
2828 json_object_int_add(json
, "nexthopLookupsAvoided",
2829 pim
->nexthop_lookups_avoided
);
2832 "RPF Cache Refresh Delay: %ld msecs\n"
2833 "RPF Cache Refresh Timer: %ld msecs\n"
2834 "RPF Cache Refresh Requests: %lld\n"
2835 "RPF Cache Refresh Events: %lld\n"
2836 "RPF Cache Refresh Last: %s\n"
2837 "Nexthop Lookups: %lld\n"
2838 "Nexthop Lookups Avoided: %lld\n",
2839 router
->rpf_cache_refresh_delay_msec
,
2840 pim_time_timer_remain_msec(pim
->rpf_cache_refresher
),
2841 (long long)pim
->rpf_cache_refresh_requests
,
2842 (long long)pim
->rpf_cache_refresh_events
,
2843 refresh_uptime
, (long long)pim
->nexthop_lookups
,
2844 (long long)pim
->nexthop_lookups_avoided
);
2848 static void show_scan_oil_stats(struct pim_instance
*pim
, struct vty
*vty
,
2851 char uptime_scan_oil
[10];
2852 char uptime_mroute_add
[10];
2853 char uptime_mroute_del
[10];
2855 pim_time_uptime_begin(uptime_scan_oil
, sizeof(uptime_scan_oil
), now
,
2856 pim
->scan_oil_last
);
2857 pim_time_uptime_begin(uptime_mroute_add
, sizeof(uptime_mroute_add
), now
,
2858 pim
->mroute_add_last
);
2859 pim_time_uptime_begin(uptime_mroute_del
, sizeof(uptime_mroute_del
), now
,
2860 pim
->mroute_del_last
);
2863 "Scan OIL - Last: %s Events: %lld\n"
2864 "MFC Add - Last: %s Events: %lld\n"
2865 "MFC Del - Last: %s Events: %lld\n",
2866 uptime_scan_oil
, (long long)pim
->scan_oil_events
,
2867 uptime_mroute_add
, (long long)pim
->mroute_add_events
,
2868 uptime_mroute_del
, (long long)pim
->mroute_del_events
);
2871 static void pim_show_rpf(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
2873 struct pim_upstream
*up
;
2874 time_t now
= pim_time_monotonic_sec();
2875 json_object
*json
= NULL
;
2876 json_object
*json_group
= NULL
;
2877 json_object
*json_row
= NULL
;
2880 json
= json_object_new_object();
2881 show_rpf_refresh_stats(vty
, pim
, now
, json
);
2883 show_rpf_refresh_stats(vty
, pim
, now
, json
);
2886 "Source Group RpfIface RpfAddress RibNextHop Metric Pref\n");
2889 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
2890 char src_str
[INET_ADDRSTRLEN
];
2891 char grp_str
[INET_ADDRSTRLEN
];
2892 char rpf_addr_str
[PREFIX_STRLEN
];
2893 char rib_nexthop_str
[PREFIX_STRLEN
];
2894 const char *rpf_ifname
;
2895 struct pim_rpf
*rpf
= &up
->rpf
;
2897 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2898 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2899 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2900 sizeof(rpf_addr_str
));
2901 pim_addr_dump("<nexthop?>",
2902 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2903 rib_nexthop_str
, sizeof(rib_nexthop_str
));
2905 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2908 json_object_object_get_ex(json
, grp_str
, &json_group
);
2911 json_group
= json_object_new_object();
2912 json_object_object_add(json
, grp_str
,
2916 json_row
= json_object_new_object();
2917 json_object_string_add(json_row
, "source", src_str
);
2918 json_object_string_add(json_row
, "group", grp_str
);
2919 json_object_string_add(json_row
, "rpfInterface",
2921 json_object_string_add(json_row
, "rpfAddress",
2923 json_object_string_add(json_row
, "ribNexthop",
2925 json_object_int_add(
2926 json_row
, "routeMetric",
2927 rpf
->source_nexthop
.mrib_route_metric
);
2928 json_object_int_add(
2929 json_row
, "routePreference",
2930 rpf
->source_nexthop
.mrib_metric_preference
);
2931 json_object_object_add(json_group
, src_str
, json_row
);
2934 vty_out(vty
, "%-15s %-15s %-16s %-15s %-15s %6d %4d\n",
2935 src_str
, grp_str
, rpf_ifname
, rpf_addr_str
,
2937 rpf
->source_nexthop
.mrib_route_metric
,
2938 rpf
->source_nexthop
.mrib_metric_preference
);
2943 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2944 json
, JSON_C_TO_STRING_PRETTY
));
2945 json_object_free(json
);
2949 struct pnc_cache_walk_data
{
2951 struct pim_instance
*pim
;
2954 static int pim_print_pnc_cache_walkcb(struct hash_bucket
*bucket
, void *arg
)
2956 struct pim_nexthop_cache
*pnc
= bucket
->data
;
2957 struct pnc_cache_walk_data
*cwd
= arg
;
2958 struct vty
*vty
= cwd
->vty
;
2959 struct pim_instance
*pim
= cwd
->pim
;
2960 struct nexthop
*nh_node
= NULL
;
2961 ifindex_t first_ifindex
;
2962 struct interface
*ifp
= NULL
;
2964 for (nh_node
= pnc
->nexthop
; nh_node
; nh_node
= nh_node
->next
) {
2965 first_ifindex
= nh_node
->ifindex
;
2966 ifp
= if_lookup_by_index(first_ifindex
, pim
->vrf_id
);
2968 vty_out(vty
, "%-15s ", inet_ntoa(pnc
->rpf
.rpf_addr
.u
.prefix4
));
2969 vty_out(vty
, "%-16s ", ifp
? ifp
->name
: "NULL");
2970 vty_out(vty
, "%s ", inet_ntoa(nh_node
->gate
.ipv4
));
2976 static void pim_show_nexthop(struct pim_instance
*pim
, struct vty
*vty
)
2978 struct pnc_cache_walk_data cwd
;
2982 vty_out(vty
, "Number of registered addresses: %lu\n",
2983 pim
->rpf_hash
->count
);
2984 vty_out(vty
, "Address Interface Nexthop\n");
2985 vty_out(vty
, "---------------------------------------------\n");
2987 hash_walk(pim
->rpf_hash
, pim_print_pnc_cache_walkcb
, &cwd
);
2990 /* Display the bsm database details */
2991 static void pim_show_bsm_db(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
2993 struct listnode
*bsmnode
;
2996 struct bsm_info
*bsm
;
2997 json_object
*json
= NULL
;
2998 json_object
*json_group
= NULL
;
2999 json_object
*json_row
= NULL
;
3001 count
= pim
->global_scope
.bsm_list
->count
;
3004 json
= json_object_new_object();
3005 json_object_int_add(json
, "Number of the fragments", count
);
3007 vty_out(vty
, "Scope Zone: Global\n");
3008 vty_out(vty
, "Number of the fragments: %d\n", count
);
3012 for (ALL_LIST_ELEMENTS_RO(pim
->global_scope
.bsm_list
, bsmnode
, bsm
)) {
3013 char grp_str
[INET_ADDRSTRLEN
];
3014 char rp_str
[INET_ADDRSTRLEN
];
3015 char bsr_str
[INET_ADDRSTRLEN
];
3016 struct bsmmsg_grpinfo
*group
;
3017 struct bsmmsg_rpinfo
*rpaddr
;
3019 struct bsm_hdr
*hdr
;
3020 uint32_t offset
= 0;
3023 uint32_t frag_rp_cnt
= 0;
3028 /* skip pim header */
3029 buf
+= PIM_MSG_HEADER_LEN
;
3030 len
-= PIM_MSG_HEADER_LEN
;
3032 hdr
= (struct bsm_hdr
*)buf
;
3034 /* BSM starts with bsr header */
3035 buf
+= sizeof(struct bsm_hdr
);
3036 len
-= sizeof(struct bsm_hdr
);
3038 pim_inet4_dump("<BSR Address?>", hdr
->bsr_addr
.addr
, bsr_str
,
3043 json_object_string_add(json
, "BSR address", bsr_str
);
3044 json_object_int_add(json
, "BSR priority",
3046 json_object_int_add(json
, "Hashmask Length",
3048 json_object_int_add(json
, "Fragment Tag",
3049 ntohs(hdr
->frag_tag
));
3051 vty_out(vty
, "BSM Fragment : %d\n", fragment
);
3052 vty_out(vty
, "------------------\n");
3053 vty_out(vty
, "%-15s %-15s %-15s %-15s\n", "BSR-Address",
3054 "BSR-Priority", "Hashmask-len", "Fragment-Tag");
3055 vty_out(vty
, "%-15s %-15d %-15d %-15d\n", bsr_str
,
3056 hdr
->bsr_prio
, hdr
->hm_len
,
3057 ntohs(hdr
->frag_tag
));
3062 while (offset
< len
) {
3063 group
= (struct bsmmsg_grpinfo
*)buf
;
3065 if (group
->group
.family
== PIM_MSG_ADDRESS_FAMILY_IPV4
)
3066 grp
.family
= AF_INET
;
3068 grp
.prefixlen
= group
->group
.mask
;
3069 grp
.u
.prefix4
.s_addr
= group
->group
.addr
.s_addr
;
3071 prefix2str(&grp
, grp_str
, sizeof(grp_str
));
3073 buf
+= sizeof(struct bsmmsg_grpinfo
);
3074 offset
+= sizeof(struct bsmmsg_grpinfo
);
3077 json_object_object_get_ex(json
, grp_str
,
3080 json_group
= json_object_new_object();
3081 json_object_int_add(json_group
,
3084 json_object_int_add(
3085 json_group
, "Fragment Rp count",
3086 group
->frag_rp_count
);
3087 json_object_object_add(json
, grp_str
,
3091 vty_out(vty
, "Group : %s\n", grp_str
);
3092 vty_out(vty
, "-------------------\n");
3093 vty_out(vty
, "Rp Count:%d\n", group
->rp_count
);
3094 vty_out(vty
, "Fragment Rp Count : %d\n",
3095 group
->frag_rp_count
);
3098 frag_rp_cnt
= group
->frag_rp_count
;
3105 "RpAddress HoldTime Priority\n");
3107 while (frag_rp_cnt
--) {
3108 rpaddr
= (struct bsmmsg_rpinfo
*)buf
;
3110 buf
+= sizeof(struct bsmmsg_rpinfo
);
3111 offset
+= sizeof(struct bsmmsg_rpinfo
);
3113 pim_inet4_dump("<Rp addr?>",
3114 rpaddr
->rpaddr
.addr
, rp_str
,
3118 json_row
= json_object_new_object();
3119 json_object_string_add(
3120 json_row
, "Rp Address", rp_str
);
3121 json_object_int_add(
3122 json_row
, "Rp HoldTime",
3123 ntohs(rpaddr
->rp_holdtime
));
3124 json_object_int_add(json_row
,
3127 json_object_object_add(
3128 json_group
, rp_str
, json_row
);
3130 vty_out(vty
, "%-15s %-12d %d\n", rp_str
,
3131 ntohs(rpaddr
->rp_holdtime
),
3142 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3143 json
, JSON_C_TO_STRING_PRETTY
));
3144 json_object_free(json
);
3148 /*Display the group-rp mappings */
3149 static void pim_show_group_rp_mappings_info(struct pim_instance
*pim
,
3150 struct vty
*vty
, bool uj
)
3152 struct bsgrp_node
*bsgrp
;
3153 struct listnode
*rpnode
;
3154 struct bsm_rpinfo
*bsm_rp
;
3155 struct route_node
*rn
;
3156 char bsr_str
[INET_ADDRSTRLEN
];
3157 json_object
*json
= NULL
;
3158 json_object
*json_group
= NULL
;
3159 json_object
*json_row
= NULL
;
3161 if (pim
->global_scope
.current_bsr
.s_addr
== INADDR_ANY
)
3162 strlcpy(bsr_str
, "0.0.0.0", sizeof(bsr_str
));
3165 pim_inet4_dump("<bsr?>", pim
->global_scope
.current_bsr
, bsr_str
,
3169 json
= json_object_new_object();
3170 json_object_string_add(json
, "BSR Address", bsr_str
);
3172 vty_out(vty
, "BSR Address %s\n", bsr_str
);
3175 for (rn
= route_top(pim
->global_scope
.bsrp_table
); rn
;
3176 rn
= route_next(rn
)) {
3177 bsgrp
= (struct bsgrp_node
*)rn
->info
;
3182 char grp_str
[INET_ADDRSTRLEN
];
3184 prefix2str(&bsgrp
->group
, grp_str
, sizeof(grp_str
));
3187 json_object_object_get_ex(json
, grp_str
, &json_group
);
3189 json_group
= json_object_new_object();
3190 json_object_object_add(json
, grp_str
,
3194 vty_out(vty
, "Group Address %s\n", grp_str
);
3195 vty_out(vty
, "--------------------------\n");
3196 vty_out(vty
, "%-15s %-15s %-15s %-15s\n", "Rp Address",
3197 "priority", "Holdtime", "Hash");
3199 vty_out(vty
, "(ACTIVE)\n");
3202 if (bsgrp
->bsrp_list
) {
3203 for (ALL_LIST_ELEMENTS_RO(bsgrp
->bsrp_list
, rpnode
,
3205 char rp_str
[INET_ADDRSTRLEN
];
3207 pim_inet4_dump("<Rp Address?>",
3208 bsm_rp
->rp_address
, rp_str
,
3212 json_row
= json_object_new_object();
3213 json_object_string_add(
3214 json_row
, "Rp Address", rp_str
);
3215 json_object_int_add(
3216 json_row
, "Rp HoldTime",
3217 bsm_rp
->rp_holdtime
);
3218 json_object_int_add(json_row
,
3221 json_object_int_add(json_row
,
3224 json_object_object_add(
3225 json_group
, rp_str
, json_row
);
3229 "%-15s %-15u %-15u %-15u\n",
3230 rp_str
, bsm_rp
->rp_prio
,
3231 bsm_rp
->rp_holdtime
,
3235 if (!bsgrp
->bsrp_list
->count
&& !uj
)
3236 vty_out(vty
, "Active List is empty.\n");
3240 json_object_int_add(json_group
, "Pending RP count",
3241 bsgrp
->pend_rp_cnt
);
3243 vty_out(vty
, "(PENDING)\n");
3244 vty_out(vty
, "Pending RP count :%d\n",
3245 bsgrp
->pend_rp_cnt
);
3246 if (bsgrp
->pend_rp_cnt
)
3247 vty_out(vty
, "%-15s %-15s %-15s %-15s\n",
3248 "Rp Address", "priority", "Holdtime",
3252 if (bsgrp
->partial_bsrp_list
) {
3253 for (ALL_LIST_ELEMENTS_RO(bsgrp
->partial_bsrp_list
,
3255 char rp_str
[INET_ADDRSTRLEN
];
3257 pim_inet4_dump("<Rp Addr?>", bsm_rp
->rp_address
,
3258 rp_str
, sizeof(rp_str
));
3261 json_row
= json_object_new_object();
3262 json_object_string_add(
3263 json_row
, "Rp Address", rp_str
);
3264 json_object_int_add(
3265 json_row
, "Rp HoldTime",
3266 bsm_rp
->rp_holdtime
);
3267 json_object_int_add(json_row
,
3270 json_object_int_add(json_row
,
3273 json_object_object_add(
3274 json_group
, rp_str
, json_row
);
3277 "%-15s %-15u %-15u %-15u\n",
3278 rp_str
, bsm_rp
->rp_prio
,
3279 bsm_rp
->rp_holdtime
,
3283 if (!bsgrp
->partial_bsrp_list
->count
&& !uj
)
3284 vty_out(vty
, "Partial List is empty\n");
3292 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3293 json
, JSON_C_TO_STRING_PRETTY
));
3294 json_object_free(json
);
3298 /* pim statistics - just adding only bsm related now.
3299 * We can continue to add all pim related stats here.
3301 static void pim_show_statistics(struct pim_instance
*pim
, struct vty
*vty
,
3302 const char *ifname
, bool uj
)
3304 json_object
*json
= NULL
;
3305 struct interface
*ifp
;
3308 json
= json_object_new_object();
3309 json_object_int_add(json
, "Number of Received BSMs",
3311 json_object_int_add(json
, "Number of Forwared BSMs",
3313 json_object_int_add(json
, "Number of Dropped BSMs",
3316 vty_out(vty
, "BSM Statistics :\n");
3317 vty_out(vty
, "----------------\n");
3318 vty_out(vty
, "Number of Received BSMs : %" PRIu64
"\n",
3320 vty_out(vty
, "Number of Forwared BSMs : %" PRIu64
"\n",
3322 vty_out(vty
, "Number of Dropped BSMs : %" PRIu64
"\n",
3328 /* scan interfaces */
3329 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3330 struct pim_interface
*pim_ifp
= ifp
->info
;
3332 if (ifname
&& strcmp(ifname
, ifp
->name
))
3339 vty_out(vty
, "Interface : %s\n", ifp
->name
);
3340 vty_out(vty
, "-------------------\n");
3342 "Number of BSMs dropped due to config miss : %u\n",
3343 pim_ifp
->pim_ifstat_bsm_cfg_miss
);
3344 vty_out(vty
, "Number of unicast BSMs dropped : %u\n",
3345 pim_ifp
->pim_ifstat_ucast_bsm_cfg_miss
);
3347 "Number of BSMs dropped due to invalid scope zone : %u\n",
3348 pim_ifp
->pim_ifstat_bsm_invalid_sz
);
3351 json_object
*json_row
= NULL
;
3353 json_row
= json_object_new_object();
3355 json_object_string_add(json_row
, "If Name", ifp
->name
);
3356 json_object_int_add(
3358 "Number of BSMs dropped due to config miss",
3359 pim_ifp
->pim_ifstat_bsm_cfg_miss
);
3360 json_object_int_add(
3361 json_row
, "Number of unicast BSMs dropped",
3362 pim_ifp
->pim_ifstat_ucast_bsm_cfg_miss
);
3363 json_object_int_add(json_row
,
3364 "Number of BSMs dropped due to invalid scope zone",
3365 pim_ifp
->pim_ifstat_bsm_invalid_sz
);
3366 json_object_object_add(json
, ifp
->name
, json_row
);
3372 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3373 json
, JSON_C_TO_STRING_PRETTY
));
3374 json_object_free(json
);
3378 static void clear_pim_statistics(struct pim_instance
*pim
)
3380 struct interface
*ifp
;
3384 pim
->bsm_dropped
= 0;
3386 /* scan interfaces */
3387 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3388 struct pim_interface
*pim_ifp
= ifp
->info
;
3393 pim_ifp
->pim_ifstat_bsm_cfg_miss
= 0;
3394 pim_ifp
->pim_ifstat_ucast_bsm_cfg_miss
= 0;
3395 pim_ifp
->pim_ifstat_bsm_invalid_sz
= 0;
3399 static void igmp_show_groups(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
3401 struct interface
*ifp
;
3403 json_object
*json
= NULL
;
3404 json_object
*json_iface
= NULL
;
3405 json_object
*json_row
= NULL
;
3407 now
= pim_time_monotonic_sec();
3410 json
= json_object_new_object();
3413 "Interface Address Group Mode Timer Srcs V Uptime \n");
3415 /* scan interfaces */
3416 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3417 struct pim_interface
*pim_ifp
= ifp
->info
;
3418 struct listnode
*sock_node
;
3419 struct igmp_sock
*igmp
;
3424 /* scan igmp sockets */
3425 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3427 char ifaddr_str
[INET_ADDRSTRLEN
];
3428 struct listnode
*grpnode
;
3429 struct igmp_group
*grp
;
3431 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3432 sizeof(ifaddr_str
));
3434 /* scan igmp groups */
3435 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3437 char group_str
[INET_ADDRSTRLEN
];
3441 pim_inet4_dump("<group?>", grp
->group_addr
,
3442 group_str
, sizeof(group_str
));
3443 pim_time_timer_to_hhmmss(hhmmss
, sizeof(hhmmss
),
3444 grp
->t_group_timer
);
3445 pim_time_uptime(uptime
, sizeof(uptime
),
3446 now
- grp
->group_creation
);
3449 json_object_object_get_ex(
3450 json
, ifp
->name
, &json_iface
);
3454 json_object_new_object();
3455 json_object_pim_ifp_add(
3457 json_object_object_add(
3462 json_row
= json_object_new_object();
3463 json_object_string_add(
3464 json_row
, "source", ifaddr_str
);
3465 json_object_string_add(
3466 json_row
, "group", group_str
);
3468 if (grp
->igmp_version
== 3)
3469 json_object_string_add(
3471 grp
->group_filtermode_isexcl
3475 json_object_string_add(json_row
,
3477 json_object_int_add(
3478 json_row
, "sourcesCount",
3479 grp
->group_source_list
3481 grp
->group_source_list
)
3483 json_object_int_add(json_row
, "version",
3485 json_object_string_add(
3486 json_row
, "uptime", uptime
);
3487 json_object_object_add(json_iface
,
3493 "%-16s %-15s %-15s %4s %8s %4d %d %8s\n",
3494 ifp
->name
, ifaddr_str
,
3496 grp
->igmp_version
== 3
3497 ? (grp
->group_filtermode_isexcl
3502 grp
->group_source_list
3504 grp
->group_source_list
)
3506 grp
->igmp_version
, uptime
);
3508 } /* scan igmp groups */
3509 } /* scan igmp sockets */
3510 } /* scan interfaces */
3513 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3514 json
, JSON_C_TO_STRING_PRETTY
));
3515 json_object_free(json
);
3519 static void igmp_show_group_retransmission(struct pim_instance
*pim
,
3522 struct interface
*ifp
;
3525 "Interface Address Group RetTimer Counter RetSrcs\n");
3527 /* scan interfaces */
3528 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3529 struct pim_interface
*pim_ifp
= ifp
->info
;
3530 struct listnode
*sock_node
;
3531 struct igmp_sock
*igmp
;
3536 /* scan igmp sockets */
3537 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3539 char ifaddr_str
[INET_ADDRSTRLEN
];
3540 struct listnode
*grpnode
;
3541 struct igmp_group
*grp
;
3543 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3544 sizeof(ifaddr_str
));
3546 /* scan igmp groups */
3547 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3549 char group_str
[INET_ADDRSTRLEN
];
3550 char grp_retr_mmss
[10];
3551 struct listnode
*src_node
;
3552 struct igmp_source
*src
;
3553 int grp_retr_sources
= 0;
3555 pim_inet4_dump("<group?>", grp
->group_addr
,
3556 group_str
, sizeof(group_str
));
3557 pim_time_timer_to_mmss(
3558 grp_retr_mmss
, sizeof(grp_retr_mmss
),
3559 grp
->t_group_query_retransmit_timer
);
3562 /* count group sources with retransmission state
3564 for (ALL_LIST_ELEMENTS_RO(
3565 grp
->group_source_list
, src_node
,
3567 if (src
->source_query_retransmit_count
3573 vty_out(vty
, "%-16s %-15s %-15s %-8s %7d %7d\n",
3574 ifp
->name
, ifaddr_str
, group_str
,
3576 grp
->group_specific_query_retransmit_count
,
3579 } /* scan igmp groups */
3580 } /* scan igmp sockets */
3581 } /* scan interfaces */
3584 static void igmp_show_sources(struct pim_instance
*pim
, struct vty
*vty
)
3586 struct interface
*ifp
;
3589 now
= pim_time_monotonic_sec();
3592 "Interface Address Group Source Timer Fwd Uptime \n");
3594 /* scan interfaces */
3595 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3596 struct pim_interface
*pim_ifp
= ifp
->info
;
3597 struct listnode
*sock_node
;
3598 struct igmp_sock
*igmp
;
3603 /* scan igmp sockets */
3604 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3606 char ifaddr_str
[INET_ADDRSTRLEN
];
3607 struct listnode
*grpnode
;
3608 struct igmp_group
*grp
;
3610 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3611 sizeof(ifaddr_str
));
3613 /* scan igmp groups */
3614 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3616 char group_str
[INET_ADDRSTRLEN
];
3617 struct listnode
*srcnode
;
3618 struct igmp_source
*src
;
3620 pim_inet4_dump("<group?>", grp
->group_addr
,
3621 group_str
, sizeof(group_str
));
3623 /* scan group sources */
3624 for (ALL_LIST_ELEMENTS_RO(
3625 grp
->group_source_list
, srcnode
,
3627 char source_str
[INET_ADDRSTRLEN
];
3632 "<source?>", src
->source_addr
,
3633 source_str
, sizeof(source_str
));
3635 pim_time_timer_to_mmss(
3637 src
->t_source_timer
);
3640 uptime
, sizeof(uptime
),
3641 now
- src
->source_creation
);
3644 "%-16s %-15s %-15s %-15s %5s %3s %8s\n",
3645 ifp
->name
, ifaddr_str
,
3646 group_str
, source_str
, mmss
,
3647 IGMP_SOURCE_TEST_FORWARDING(
3653 } /* scan group sources */
3654 } /* scan igmp groups */
3655 } /* scan igmp sockets */
3656 } /* scan interfaces */
3659 static void igmp_show_source_retransmission(struct pim_instance
*pim
,
3662 struct interface
*ifp
;
3665 "Interface Address Group Source Counter\n");
3667 /* scan interfaces */
3668 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3669 struct pim_interface
*pim_ifp
= ifp
->info
;
3670 struct listnode
*sock_node
;
3671 struct igmp_sock
*igmp
;
3676 /* scan igmp sockets */
3677 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3679 char ifaddr_str
[INET_ADDRSTRLEN
];
3680 struct listnode
*grpnode
;
3681 struct igmp_group
*grp
;
3683 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3684 sizeof(ifaddr_str
));
3686 /* scan igmp groups */
3687 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3689 char group_str
[INET_ADDRSTRLEN
];
3690 struct listnode
*srcnode
;
3691 struct igmp_source
*src
;
3693 pim_inet4_dump("<group?>", grp
->group_addr
,
3694 group_str
, sizeof(group_str
));
3696 /* scan group sources */
3697 for (ALL_LIST_ELEMENTS_RO(
3698 grp
->group_source_list
, srcnode
,
3700 char source_str
[INET_ADDRSTRLEN
];
3703 "<source?>", src
->source_addr
,
3704 source_str
, sizeof(source_str
));
3707 "%-16s %-15s %-15s %-15s %7d\n",
3708 ifp
->name
, ifaddr_str
,
3709 group_str
, source_str
,
3710 src
->source_query_retransmit_count
);
3712 } /* scan group sources */
3713 } /* scan igmp groups */
3714 } /* scan igmp sockets */
3715 } /* scan interfaces */
3718 static void pim_show_bsr(struct pim_instance
*pim
,
3723 char last_bsm_seen
[10];
3726 char bsr_str
[PREFIX_STRLEN
];
3727 json_object
*json
= NULL
;
3729 vty_out(vty
, "PIMv2 Bootstrap information\n");
3731 if (pim
->global_scope
.current_bsr
.s_addr
== INADDR_ANY
) {
3732 strlcpy(bsr_str
, "0.0.0.0", sizeof(bsr_str
));
3733 pim_time_uptime(uptime
, sizeof(uptime
),
3734 pim
->global_scope
.current_bsr_first_ts
);
3735 pim_time_uptime(last_bsm_seen
, sizeof(last_bsm_seen
),
3736 pim
->global_scope
.current_bsr_last_ts
);
3740 pim_inet4_dump("<bsr?>", pim
->global_scope
.current_bsr
,
3741 bsr_str
, sizeof(bsr_str
));
3742 now
= pim_time_monotonic_sec();
3743 pim_time_uptime(uptime
, sizeof(uptime
),
3744 (now
- pim
->global_scope
.current_bsr_first_ts
));
3745 pim_time_uptime(last_bsm_seen
, sizeof(last_bsm_seen
),
3746 now
- pim
->global_scope
.current_bsr_last_ts
);
3749 switch (pim
->global_scope
.state
) {
3751 strlcpy(bsr_state
, "NO_INFO", sizeof(bsr_state
));
3754 strlcpy(bsr_state
, "ACCEPT_ANY", sizeof(bsr_state
));
3756 case ACCEPT_PREFERRED
:
3757 strlcpy(bsr_state
, "ACCEPT_PREFERRED", sizeof(bsr_state
));
3760 strlcpy(bsr_state
, "", sizeof(bsr_state
));
3764 json
= json_object_new_object();
3765 json_object_string_add(json
, "bsr", bsr_str
);
3766 json_object_int_add(json
, "priority",
3767 pim
->global_scope
.current_bsr_prio
);
3768 json_object_int_add(json
, "fragment_tag",
3769 pim
->global_scope
.bsm_frag_tag
);
3770 json_object_string_add(json
, "state", bsr_state
);
3771 json_object_string_add(json
, "upTime", uptime
);
3772 json_object_string_add(json
, "last_bsm_seen", last_bsm_seen
);
3776 vty_out(vty
, "Current preferred BSR address: %s\n", bsr_str
);
3778 "Priority Fragment-Tag State UpTime\n");
3779 vty_out(vty
, " %-12d %-12d %-13s %7s\n",
3780 pim
->global_scope
.current_bsr_prio
,
3781 pim
->global_scope
.bsm_frag_tag
,
3784 vty_out(vty
, "Last BSM seen: %s\n", last_bsm_seen
);
3788 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3789 json
, JSON_C_TO_STRING_PRETTY
));
3790 json_object_free(json
);
3794 static void clear_igmp_interfaces(struct pim_instance
*pim
)
3796 struct interface
*ifp
;
3798 FOR_ALL_INTERFACES (pim
->vrf
, ifp
)
3799 pim_if_addr_del_all_igmp(ifp
);
3801 FOR_ALL_INTERFACES (pim
->vrf
, ifp
)
3802 pim_if_addr_add_all(ifp
);
3805 static void clear_pim_interfaces(struct pim_instance
*pim
)
3807 struct interface
*ifp
;
3809 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3811 pim_neighbor_delete_all(ifp
, "interface cleared");
3816 static void clear_interfaces(struct pim_instance
*pim
)
3818 clear_igmp_interfaces(pim
);
3819 clear_pim_interfaces(pim
);
3822 #define PIM_GET_PIM_INTERFACE(pim_ifp, ifp) \
3823 pim_ifp = ifp->info; \
3826 "%% Enable PIM and/or IGMP on this interface first\n"); \
3827 return CMD_WARNING_CONFIG_FAILED; \
3830 DEFUN (clear_ip_interfaces
,
3831 clear_ip_interfaces_cmd
,
3832 "clear ip interfaces [vrf NAME]",
3835 "Reset interfaces\n"
3839 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3844 clear_interfaces(vrf
->info
);
3849 DEFUN (clear_ip_igmp_interfaces
,
3850 clear_ip_igmp_interfaces_cmd
,
3851 "clear ip igmp [vrf NAME] interfaces",
3856 "Reset IGMP interfaces\n")
3859 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3864 clear_igmp_interfaces(vrf
->info
);
3869 DEFUN (clear_ip_pim_statistics
,
3870 clear_ip_pim_statistics_cmd
,
3871 "clear ip pim statistics [vrf NAME]",
3876 "Reset PIM statistics\n")
3879 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3884 clear_pim_statistics(vrf
->info
);
3888 static void clear_mroute(struct pim_instance
*pim
)
3890 struct pim_upstream
*up
;
3891 struct interface
*ifp
;
3893 /* scan interfaces */
3894 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3895 struct pim_interface
*pim_ifp
= ifp
->info
;
3896 struct listnode
*sock_node
;
3897 struct igmp_sock
*igmp
;
3898 struct pim_ifchannel
*ch
;
3903 /* deleting all ifchannels */
3904 while (!RB_EMPTY(pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
)) {
3905 ch
= RB_ROOT(pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
);
3907 pim_ifchannel_delete(ch
);
3910 /* clean up all igmp groups */
3911 /* scan igmp sockets */
3912 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3915 struct igmp_group
*grp
;
3917 if (igmp
->igmp_group_list
) {
3918 while (igmp
->igmp_group_list
->count
) {
3919 grp
= listnode_head(
3920 igmp
->igmp_group_list
);
3921 igmp_group_delete(grp
);
3928 /* clean up all upstreams*/
3929 while ((up
= rb_pim_upstream_first(&pim
->upstream_head
))) {
3930 pim_upstream_del(pim
, up
, __PRETTY_FUNCTION__
);
3934 DEFUN (clear_ip_mroute
,
3935 clear_ip_mroute_cmd
,
3936 "clear ip mroute [vrf NAME]",
3939 "Reset multicast routes\n"
3943 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3948 clear_mroute(vrf
->info
);
3953 DEFUN (clear_ip_pim_interfaces
,
3954 clear_ip_pim_interfaces_cmd
,
3955 "clear ip pim [vrf NAME] interfaces",
3960 "Reset PIM interfaces\n")
3963 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3968 clear_pim_interfaces(vrf
->info
);
3973 DEFUN (clear_ip_pim_interface_traffic
,
3974 clear_ip_pim_interface_traffic_cmd
,
3975 "clear ip pim [vrf NAME] interface traffic",
3978 "PIM clear commands\n"
3980 "Reset PIM interfaces\n"
3981 "Reset Protocol Packet counters\n")
3984 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3985 struct interface
*ifp
= NULL
;
3986 struct pim_interface
*pim_ifp
= NULL
;
3991 FOR_ALL_INTERFACES (vrf
, ifp
) {
3992 pim_ifp
= ifp
->info
;
3997 pim_ifp
->pim_ifstat_hello_recv
= 0;
3998 pim_ifp
->pim_ifstat_hello_sent
= 0;
3999 pim_ifp
->pim_ifstat_join_recv
= 0;
4000 pim_ifp
->pim_ifstat_join_send
= 0;
4001 pim_ifp
->pim_ifstat_prune_recv
= 0;
4002 pim_ifp
->pim_ifstat_prune_send
= 0;
4003 pim_ifp
->pim_ifstat_reg_recv
= 0;
4004 pim_ifp
->pim_ifstat_reg_send
= 0;
4005 pim_ifp
->pim_ifstat_reg_stop_recv
= 0;
4006 pim_ifp
->pim_ifstat_reg_stop_send
= 0;
4007 pim_ifp
->pim_ifstat_assert_recv
= 0;
4008 pim_ifp
->pim_ifstat_assert_send
= 0;
4009 pim_ifp
->pim_ifstat_bsm_rx
= 0;
4010 pim_ifp
->pim_ifstat_bsm_tx
= 0;
4016 DEFUN (clear_ip_pim_oil
,
4017 clear_ip_pim_oil_cmd
,
4018 "clear ip pim [vrf NAME] oil",
4023 "Rescan PIM OIL (output interface list)\n")
4026 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4031 pim_scan_oil(vrf
->info
);
4036 DEFUN (show_ip_igmp_interface
,
4037 show_ip_igmp_interface_cmd
,
4038 "show ip igmp [vrf NAME] interface [detail|WORD] [json]",
4043 "IGMP interface information\n"
4049 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4050 bool uj
= use_json(argc
, argv
);
4055 if (argv_find(argv
, argc
, "detail", &idx
)
4056 || argv_find(argv
, argc
, "WORD", &idx
))
4057 igmp_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
4059 igmp_show_interfaces(vrf
->info
, vty
, uj
);
4064 DEFUN (show_ip_igmp_interface_vrf_all
,
4065 show_ip_igmp_interface_vrf_all_cmd
,
4066 "show ip igmp vrf all interface [detail|WORD] [json]",
4071 "IGMP interface information\n"
4077 bool uj
= use_json(argc
, argv
);
4083 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4087 vty_out(vty
, " \"%s\": ", vrf
->name
);
4090 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4091 if (argv_find(argv
, argc
, "detail", &idx
)
4092 || argv_find(argv
, argc
, "WORD", &idx
))
4093 igmp_show_interfaces_single(vrf
->info
, vty
,
4094 argv
[idx
]->arg
, uj
);
4096 igmp_show_interfaces(vrf
->info
, vty
, uj
);
4099 vty_out(vty
, "}\n");
4104 DEFUN (show_ip_igmp_join
,
4105 show_ip_igmp_join_cmd
,
4106 "show ip igmp [vrf NAME] join",
4111 "IGMP static join information\n")
4114 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4119 igmp_show_interface_join(vrf
->info
, vty
);
4124 DEFUN (show_ip_igmp_join_vrf_all
,
4125 show_ip_igmp_join_vrf_all_cmd
,
4126 "show ip igmp vrf all join",
4131 "IGMP static join information\n")
4133 bool uj
= use_json(argc
, argv
);
4139 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4143 vty_out(vty
, " \"%s\": ", vrf
->name
);
4146 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4147 igmp_show_interface_join(vrf
->info
, vty
);
4150 vty_out(vty
, "}\n");
4155 DEFUN (show_ip_igmp_groups
,
4156 show_ip_igmp_groups_cmd
,
4157 "show ip igmp [vrf NAME] groups [json]",
4166 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4167 bool uj
= use_json(argc
, argv
);
4172 igmp_show_groups(vrf
->info
, vty
, uj
);
4177 DEFUN (show_ip_igmp_groups_vrf_all
,
4178 show_ip_igmp_groups_vrf_all_cmd
,
4179 "show ip igmp vrf all groups [json]",
4187 bool uj
= use_json(argc
, argv
);
4193 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4197 vty_out(vty
, " \"%s\": ", vrf
->name
);
4200 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4201 igmp_show_groups(vrf
->info
, vty
, uj
);
4204 vty_out(vty
, "}\n");
4209 DEFUN (show_ip_igmp_groups_retransmissions
,
4210 show_ip_igmp_groups_retransmissions_cmd
,
4211 "show ip igmp [vrf NAME] groups retransmissions",
4217 "IGMP group retransmissions\n")
4220 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4225 igmp_show_group_retransmission(vrf
->info
, vty
);
4230 DEFUN (show_ip_igmp_sources
,
4231 show_ip_igmp_sources_cmd
,
4232 "show ip igmp [vrf NAME] sources",
4240 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4245 igmp_show_sources(vrf
->info
, vty
);
4250 DEFUN (show_ip_igmp_sources_retransmissions
,
4251 show_ip_igmp_sources_retransmissions_cmd
,
4252 "show ip igmp [vrf NAME] sources retransmissions",
4258 "IGMP source retransmissions\n")
4261 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4266 igmp_show_source_retransmission(vrf
->info
, vty
);
4271 DEFUN (show_ip_igmp_statistics
,
4272 show_ip_igmp_statistics_cmd
,
4273 "show ip igmp [vrf NAME] statistics [interface WORD] [json]",
4284 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4285 bool uj
= use_json(argc
, argv
);
4290 if (argv_find(argv
, argc
, "WORD", &idx
))
4291 igmp_show_statistics(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
4293 igmp_show_statistics(vrf
->info
, vty
, NULL
, uj
);
4298 DEFUN (show_ip_pim_assert
,
4299 show_ip_pim_assert_cmd
,
4300 "show ip pim [vrf NAME] assert",
4305 "PIM interface assert\n")
4308 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4313 pim_show_assert(vrf
->info
, vty
);
4318 DEFUN (show_ip_pim_assert_internal
,
4319 show_ip_pim_assert_internal_cmd
,
4320 "show ip pim [vrf NAME] assert-internal",
4325 "PIM interface internal assert state\n")
4328 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4333 pim_show_assert_internal(vrf
->info
, vty
);
4338 DEFUN (show_ip_pim_assert_metric
,
4339 show_ip_pim_assert_metric_cmd
,
4340 "show ip pim [vrf NAME] assert-metric",
4345 "PIM interface assert metric\n")
4348 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4353 pim_show_assert_metric(vrf
->info
, vty
);
4358 DEFUN (show_ip_pim_assert_winner_metric
,
4359 show_ip_pim_assert_winner_metric_cmd
,
4360 "show ip pim [vrf NAME] assert-winner-metric",
4365 "PIM interface assert winner metric\n")
4368 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4373 pim_show_assert_winner_metric(vrf
->info
, vty
);
4378 DEFUN (show_ip_pim_interface
,
4379 show_ip_pim_interface_cmd
,
4380 "show ip pim [vrf NAME] interface [detail|WORD] [json]",
4385 "PIM interface information\n"
4391 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4392 bool uj
= use_json(argc
, argv
);
4397 if (argv_find(argv
, argc
, "WORD", &idx
)
4398 || argv_find(argv
, argc
, "detail", &idx
))
4399 pim_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
4401 pim_show_interfaces(vrf
->info
, vty
, uj
);
4406 DEFUN (show_ip_pim_interface_vrf_all
,
4407 show_ip_pim_interface_vrf_all_cmd
,
4408 "show ip pim vrf all interface [detail|WORD] [json]",
4413 "PIM interface information\n"
4419 bool uj
= use_json(argc
, argv
);
4425 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4429 vty_out(vty
, " \"%s\": ", vrf
->name
);
4432 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4433 if (argv_find(argv
, argc
, "WORD", &idx
)
4434 || argv_find(argv
, argc
, "detail", &idx
))
4435 pim_show_interfaces_single(vrf
->info
, vty
,
4436 argv
[idx
]->arg
, uj
);
4438 pim_show_interfaces(vrf
->info
, vty
, uj
);
4441 vty_out(vty
, "}\n");
4446 DEFPY (show_ip_pim_join
,
4447 show_ip_pim_join_cmd
,
4448 "show ip pim [vrf NAME] join [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
4453 "PIM interface join information\n"
4454 "The Source or Group\n"
4458 struct prefix_sg sg
= {0};
4461 struct pim_instance
*pim
;
4463 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
4466 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
4469 pim
= pim_get_pim_instance(v
->vrf_id
);
4472 vty_out(vty
, "%% Unable to find pim instance\n");
4476 if (s_or_g
.s_addr
!= 0) {
4477 if (g
.s_addr
!= 0) {
4484 pim_show_join(pim
, vty
, &sg
, uj
);
4489 DEFUN (show_ip_pim_join_vrf_all
,
4490 show_ip_pim_join_vrf_all_cmd
,
4491 "show ip pim vrf all join [json]",
4496 "PIM interface join information\n"
4499 struct prefix_sg sg
= {0};
4500 bool uj
= use_json(argc
, argv
);
4506 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4510 vty_out(vty
, " \"%s\": ", vrf
->name
);
4513 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4514 pim_show_join(vrf
->info
, vty
, &sg
, uj
);
4517 vty_out(vty
, "}\n");
4522 static void pim_show_jp_agg_helper(struct vty
*vty
,
4523 struct interface
*ifp
,
4524 struct pim_neighbor
*neigh
,
4525 struct pim_upstream
*up
,
4528 char src_str
[INET_ADDRSTRLEN
];
4529 char grp_str
[INET_ADDRSTRLEN
];
4530 char rpf_str
[INET_ADDRSTRLEN
];
4532 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
4533 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
4534 /* pius->address.s_addr */
4535 pim_inet4_dump("<rpf?>", neigh
->source_addr
, rpf_str
, sizeof(rpf_str
));
4537 vty_out(vty
, "%-16s %-15s %-15s %-15s %5s\n",
4538 ifp
->name
, rpf_str
, src_str
,
4539 grp_str
, is_join
?"J":"P");
4542 static void pim_show_jp_agg_list(struct pim_instance
*pim
, struct vty
*vty
)
4544 struct interface
*ifp
;
4545 struct pim_interface
*pim_ifp
;
4546 struct listnode
*n_node
;
4547 struct pim_neighbor
*neigh
;
4548 struct listnode
*jag_node
;
4549 struct pim_jp_agg_group
*jag
;
4550 struct listnode
*js_node
;
4551 struct pim_jp_sources
*js
;
4554 "Interface RPF Nbr Source Group State\n");
4556 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
4557 pim_ifp
= ifp
->info
;
4561 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
,
4563 for (ALL_LIST_ELEMENTS_RO(neigh
->upstream_jp_agg
,
4565 for (ALL_LIST_ELEMENTS_RO(jag
->sources
,
4567 pim_show_jp_agg_helper(vty
,
4576 DEFPY (show_ip_pim_jp_agg
,
4577 show_ip_pim_jp_agg_cmd
,
4578 "show ip pim [vrf NAME] jp-agg",
4583 "join prune aggregation list\n")
4586 struct pim_instance
*pim
;
4588 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
4591 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
4594 pim
= pim_get_pim_instance(v
->vrf_id
);
4597 vty_out(vty
, "%% Unable to find pim instance\n");
4601 pim_show_jp_agg_list(pim
, vty
);
4606 DEFUN (show_ip_pim_local_membership
,
4607 show_ip_pim_local_membership_cmd
,
4608 "show ip pim [vrf NAME] local-membership [json]",
4613 "PIM interface local-membership\n"
4617 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4618 bool uj
= use_json(argc
, argv
);
4623 pim_show_membership(vrf
->info
, vty
, uj
);
4628 DEFUN (show_ip_pim_neighbor
,
4629 show_ip_pim_neighbor_cmd
,
4630 "show ip pim [vrf NAME] neighbor [detail|WORD] [json]",
4635 "PIM neighbor information\n"
4637 "Name of interface or neighbor\n"
4641 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4642 bool uj
= use_json(argc
, argv
);
4647 if (argv_find(argv
, argc
, "detail", &idx
)
4648 || argv_find(argv
, argc
, "WORD", &idx
))
4649 pim_show_neighbors_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
4651 pim_show_neighbors(vrf
->info
, vty
, uj
);
4656 DEFUN (show_ip_pim_neighbor_vrf_all
,
4657 show_ip_pim_neighbor_vrf_all_cmd
,
4658 "show ip pim vrf all neighbor [detail|WORD] [json]",
4663 "PIM neighbor information\n"
4665 "Name of interface or neighbor\n"
4669 bool uj
= use_json(argc
, argv
);
4675 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4679 vty_out(vty
, " \"%s\": ", vrf
->name
);
4682 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4683 if (argv_find(argv
, argc
, "detail", &idx
)
4684 || argv_find(argv
, argc
, "WORD", &idx
))
4685 pim_show_neighbors_single(vrf
->info
, vty
,
4686 argv
[idx
]->arg
, uj
);
4688 pim_show_neighbors(vrf
->info
, vty
, uj
);
4691 vty_out(vty
, "}\n");
4696 DEFUN (show_ip_pim_secondary
,
4697 show_ip_pim_secondary_cmd
,
4698 "show ip pim [vrf NAME] secondary",
4703 "PIM neighbor addresses\n")
4706 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4711 pim_show_neighbors_secondary(vrf
->info
, vty
);
4716 DEFUN (show_ip_pim_state
,
4717 show_ip_pim_state_cmd
,
4718 "show ip pim [vrf NAME] state [A.B.C.D [A.B.C.D]] [json]",
4723 "PIM state information\n"
4724 "Unicast or Multicast address\n"
4725 "Multicast address\n"
4728 const char *src_or_group
= NULL
;
4729 const char *group
= NULL
;
4731 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4732 bool uj
= use_json(argc
, argv
);
4740 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
4741 src_or_group
= argv
[idx
]->arg
;
4743 group
= argv
[idx
+ 1]->arg
;
4746 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
4751 DEFUN (show_ip_pim_state_vrf_all
,
4752 show_ip_pim_state_vrf_all_cmd
,
4753 "show ip pim vrf all state [A.B.C.D [A.B.C.D]] [json]",
4758 "PIM state information\n"
4759 "Unicast or Multicast address\n"
4760 "Multicast address\n"
4763 const char *src_or_group
= NULL
;
4764 const char *group
= NULL
;
4766 bool uj
= use_json(argc
, argv
);
4775 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
4776 src_or_group
= argv
[idx
]->arg
;
4778 group
= argv
[idx
+ 1]->arg
;
4781 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4785 vty_out(vty
, " \"%s\": ", vrf
->name
);
4788 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4789 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
4792 vty_out(vty
, "}\n");
4797 DEFPY (show_ip_pim_upstream
,
4798 show_ip_pim_upstream_cmd
,
4799 "show ip pim [vrf NAME] upstream [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
4804 "PIM upstream information\n"
4805 "The Source or Group\n"
4809 struct prefix_sg sg
= {0};
4812 struct pim_instance
*pim
;
4814 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
4817 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
4820 pim
= pim_get_pim_instance(v
->vrf_id
);
4823 vty_out(vty
, "%% Unable to find pim instance\n");
4827 if (s_or_g
.s_addr
!= 0) {
4828 if (g
.s_addr
!= 0) {
4834 pim_show_upstream(pim
, vty
, &sg
, uj
);
4839 DEFUN (show_ip_pim_upstream_vrf_all
,
4840 show_ip_pim_upstream_vrf_all_cmd
,
4841 "show ip pim vrf all upstream [json]",
4846 "PIM upstream information\n"
4849 struct prefix_sg sg
= {0};
4850 bool uj
= use_json(argc
, argv
);
4856 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4860 vty_out(vty
, " \"%s\": ", vrf
->name
);
4863 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4864 pim_show_upstream(vrf
->info
, vty
, &sg
, uj
);
4870 DEFUN (show_ip_pim_channel
,
4871 show_ip_pim_channel_cmd
,
4872 "show ip pim [vrf NAME] channel [json]",
4877 "PIM downstream channel info\n"
4881 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4882 bool uj
= use_json(argc
, argv
);
4887 pim_show_channel(vrf
->info
, vty
, uj
);
4892 DEFUN (show_ip_pim_upstream_join_desired
,
4893 show_ip_pim_upstream_join_desired_cmd
,
4894 "show ip pim [vrf NAME] upstream-join-desired [json]",
4899 "PIM upstream join-desired\n"
4903 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4904 bool uj
= use_json(argc
, argv
);
4909 pim_show_join_desired(vrf
->info
, vty
, uj
);
4914 DEFUN (show_ip_pim_upstream_rpf
,
4915 show_ip_pim_upstream_rpf_cmd
,
4916 "show ip pim [vrf NAME] upstream-rpf [json]",
4921 "PIM upstream source rpf\n"
4925 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4926 bool uj
= use_json(argc
, argv
);
4931 pim_show_upstream_rpf(vrf
->info
, vty
, uj
);
4936 DEFUN (show_ip_pim_rp
,
4938 "show ip pim [vrf NAME] rp-info [json]",
4943 "PIM RP information\n"
4947 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4948 bool uj
= use_json(argc
, argv
);
4953 pim_rp_show_information(vrf
->info
, vty
, uj
);
4958 DEFUN (show_ip_pim_rp_vrf_all
,
4959 show_ip_pim_rp_vrf_all_cmd
,
4960 "show ip pim vrf all rp-info [json]",
4965 "PIM RP information\n"
4968 bool uj
= use_json(argc
, argv
);
4974 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4978 vty_out(vty
, " \"%s\": ", vrf
->name
);
4981 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4982 pim_rp_show_information(vrf
->info
, vty
, uj
);
4985 vty_out(vty
, "}\n");
4990 DEFUN (show_ip_pim_rpf
,
4991 show_ip_pim_rpf_cmd
,
4992 "show ip pim [vrf NAME] rpf [json]",
4997 "PIM cached source rpf information\n"
5001 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5002 bool uj
= use_json(argc
, argv
);
5007 pim_show_rpf(vrf
->info
, vty
, uj
);
5012 DEFUN (show_ip_pim_rpf_vrf_all
,
5013 show_ip_pim_rpf_vrf_all_cmd
,
5014 "show ip pim vrf all rpf [json]",
5019 "PIM cached source rpf information\n"
5022 bool uj
= use_json(argc
, argv
);
5028 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5032 vty_out(vty
, " \"%s\": ", vrf
->name
);
5035 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5036 pim_show_rpf(vrf
->info
, vty
, uj
);
5039 vty_out(vty
, "}\n");
5044 DEFUN (show_ip_pim_nexthop
,
5045 show_ip_pim_nexthop_cmd
,
5046 "show ip pim [vrf NAME] nexthop",
5051 "PIM cached nexthop rpf information\n")
5054 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5059 pim_show_nexthop(vrf
->info
, vty
);
5064 DEFUN (show_ip_pim_nexthop_lookup
,
5065 show_ip_pim_nexthop_lookup_cmd
,
5066 "show ip pim [vrf NAME] nexthop-lookup A.B.C.D A.B.C.D",
5071 "PIM cached nexthop rpf lookup\n"
5072 "Source/RP address\n"
5073 "Multicast Group address\n")
5075 struct prefix nht_p
;
5077 struct in_addr src_addr
, grp_addr
;
5078 struct in_addr vif_source
;
5079 const char *addr_str
, *addr_str1
;
5081 struct pim_nexthop nexthop
;
5082 char nexthop_addr_str
[PREFIX_STRLEN
];
5083 char grp_str
[PREFIX_STRLEN
];
5085 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5090 argv_find(argv
, argc
, "A.B.C.D", &idx
);
5091 addr_str
= argv
[idx
]->arg
;
5092 result
= inet_pton(AF_INET
, addr_str
, &src_addr
);
5094 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
5095 errno
, safe_strerror(errno
));
5099 if (pim_is_group_224_4(src_addr
)) {
5101 "Invalid argument. Expected Valid Source Address.\n");
5105 addr_str1
= argv
[idx
+ 1]->arg
;
5106 result
= inet_pton(AF_INET
, addr_str1
, &grp_addr
);
5108 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
5109 errno
, safe_strerror(errno
));
5113 if (!pim_is_group_224_4(grp_addr
)) {
5115 "Invalid argument. Expected Valid Multicast Group Address.\n");
5119 if (!pim_rp_set_upstream_addr(vrf
->info
, &vif_source
, src_addr
,
5123 nht_p
.family
= AF_INET
;
5124 nht_p
.prefixlen
= IPV4_MAX_BITLEN
;
5125 nht_p
.u
.prefix4
= vif_source
;
5126 grp
.family
= AF_INET
;
5127 grp
.prefixlen
= IPV4_MAX_BITLEN
;
5128 grp
.u
.prefix4
= grp_addr
;
5129 memset(&nexthop
, 0, sizeof(nexthop
));
5131 result
= pim_ecmp_nexthop_lookup(vrf
->info
, &nexthop
, &nht_p
, &grp
, 0);
5135 "Nexthop Lookup failed, no usable routes returned.\n");
5139 pim_addr_dump("<grp?>", &grp
, grp_str
, sizeof(grp_str
));
5140 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
5141 nexthop_addr_str
, sizeof(nexthop_addr_str
));
5142 vty_out(vty
, "Group %s --- Nexthop %s Interface %s \n", grp_str
,
5143 nexthop_addr_str
, nexthop
.interface
->name
);
5148 DEFUN (show_ip_pim_interface_traffic
,
5149 show_ip_pim_interface_traffic_cmd
,
5150 "show ip pim [vrf NAME] interface traffic [WORD] [json]",
5155 "PIM interface information\n"
5156 "Protocol Packet counters\n"
5161 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5162 bool uj
= use_json(argc
, argv
);
5167 if (argv_find(argv
, argc
, "WORD", &idx
))
5168 pim_show_interface_traffic_single(vrf
->info
, vty
,
5169 argv
[idx
]->arg
, uj
);
5171 pim_show_interface_traffic(vrf
->info
, vty
, uj
);
5176 DEFUN (show_ip_pim_bsm_db
,
5177 show_ip_pim_bsm_db_cmd
,
5178 "show ip pim bsm-database [vrf NAME] [json]",
5182 "PIM cached bsm packets information\n"
5187 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5188 bool uj
= use_json(argc
, argv
);
5193 pim_show_bsm_db(vrf
->info
, vty
, uj
);
5197 DEFUN (show_ip_pim_bsrp
,
5198 show_ip_pim_bsrp_cmd
,
5199 "show ip pim bsrp-info [vrf NAME] [json]",
5203 "PIM cached group-rp mappings information\n"
5208 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5209 bool uj
= use_json(argc
, argv
);
5214 pim_show_group_rp_mappings_info(vrf
->info
, vty
, uj
);
5219 DEFUN (show_ip_pim_statistics
,
5220 show_ip_pim_statistics_cmd
,
5221 "show ip pim [vrf NAME] statistics [interface WORD] [json]",
5232 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5233 bool uj
= use_json(argc
, argv
);
5238 if (argv_find(argv
, argc
, "WORD", &idx
))
5239 pim_show_statistics(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
5241 pim_show_statistics(vrf
->info
, vty
, NULL
, uj
);
5246 static void show_multicast_interfaces(struct pim_instance
*pim
, struct vty
*vty
)
5248 struct interface
*ifp
;
5253 "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut\n");
5255 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
5256 struct pim_interface
*pim_ifp
;
5257 struct in_addr ifaddr
;
5258 struct sioc_vif_req vreq
;
5260 pim_ifp
= ifp
->info
;
5265 memset(&vreq
, 0, sizeof(vreq
));
5266 vreq
.vifi
= pim_ifp
->mroute_vif_index
;
5268 if (ioctl(pim
->mroute_socket
, SIOCGETVIFCNT
, &vreq
)) {
5270 "ioctl(SIOCGETVIFCNT=%lu) failure for interface %s vif_index=%d: errno=%d: %s",
5271 (unsigned long)SIOCGETVIFCNT
, ifp
->name
,
5272 pim_ifp
->mroute_vif_index
, errno
,
5273 safe_strerror(errno
));
5276 ifaddr
= pim_ifp
->primary_address
;
5278 vty_out(vty
, "%-16s %-15s %3d %3d %7lu %7lu %10lu %10lu\n",
5279 ifp
->name
, inet_ntoa(ifaddr
), ifp
->ifindex
,
5280 pim_ifp
->mroute_vif_index
, (unsigned long)vreq
.icount
,
5281 (unsigned long)vreq
.ocount
, (unsigned long)vreq
.ibytes
,
5282 (unsigned long)vreq
.obytes
);
5286 static void pim_cmd_show_ip_multicast_helper(struct pim_instance
*pim
,
5289 struct vrf
*vrf
= pim
->vrf
;
5290 time_t now
= pim_time_monotonic_sec();
5296 vty_out(vty
, "Router MLAG Role: %s\n",
5297 mlag_role2str(router
->role
, mlag_role
, sizeof(mlag_role
)));
5298 vty_out(vty
, "Mroute socket descriptor:");
5300 vty_out(vty
, " %d(%s)\n", pim
->mroute_socket
, vrf
->name
);
5302 pim_time_uptime(uptime
, sizeof(uptime
),
5303 now
- pim
->mroute_socket_creation
);
5304 vty_out(vty
, "Mroute socket uptime: %s\n", uptime
);
5308 pim_zebra_zclient_update(vty
);
5309 pim_zlookup_show_ip_multicast(vty
);
5312 vty_out(vty
, "Maximum highest VifIndex: %d\n", PIM_MAX_USABLE_VIFS
);
5315 vty_out(vty
, "Upstream Join Timer: %d secs\n", router
->t_periodic
);
5316 vty_out(vty
, "Join/Prune Holdtime: %d secs\n", PIM_JP_HOLDTIME
);
5317 vty_out(vty
, "PIM ECMP: %s\n", pim
->ecmp_enable
? "Enable" : "Disable");
5318 vty_out(vty
, "PIM ECMP Rebalance: %s\n",
5319 pim
->ecmp_rebalance_enable
? "Enable" : "Disable");
5323 show_rpf_refresh_stats(vty
, pim
, now
, NULL
);
5327 show_scan_oil_stats(pim
, vty
, now
);
5329 show_multicast_interfaces(pim
, vty
);
5332 DEFUN (show_ip_multicast
,
5333 show_ip_multicast_cmd
,
5334 "show ip multicast [vrf NAME]",
5338 "Multicast global information\n")
5341 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5346 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
5351 DEFUN (show_ip_multicast_vrf_all
,
5352 show_ip_multicast_vrf_all_cmd
,
5353 "show ip multicast vrf all",
5357 "Multicast global information\n")
5359 bool uj
= use_json(argc
, argv
);
5365 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5369 vty_out(vty
, " \"%s\": ", vrf
->name
);
5372 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5373 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
5376 vty_out(vty
, "}\n");
5381 static void show_mroute(struct pim_instance
*pim
, struct vty
*vty
,
5382 struct prefix_sg
*sg
, bool fill
, bool uj
)
5384 struct listnode
*node
;
5385 struct channel_oil
*c_oil
;
5386 struct static_route
*s_route
;
5388 json_object
*json
= NULL
;
5389 json_object
*json_group
= NULL
;
5390 json_object
*json_source
= NULL
;
5391 json_object
*json_oil
= NULL
;
5392 json_object
*json_ifp_out
= NULL
;
5395 char grp_str
[INET_ADDRSTRLEN
];
5396 char src_str
[INET_ADDRSTRLEN
];
5397 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
5398 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
5400 struct interface
*ifp_in
;
5404 json
= json_object_new_object();
5407 "Source Group Proto Input Output TTL Uptime\n");
5410 now
= pim_time_monotonic_sec();
5412 /* print list of PIM and IGMP routes */
5413 frr_each (rb_pim_oil
, &pim
->channel_oil_head
, c_oil
) {
5416 if (!c_oil
->installed
&& !uj
)
5419 if (sg
->grp
.s_addr
!= 0 &&
5420 sg
->grp
.s_addr
!= c_oil
->oil
.mfcc_mcastgrp
.s_addr
)
5422 if (sg
->src
.s_addr
!= 0 &&
5423 sg
->src
.s_addr
!= c_oil
->oil
.mfcc_origin
.s_addr
)
5426 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
5428 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
5430 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
5433 strlcpy(in_ifname
, ifp_in
->name
, sizeof(in_ifname
));
5435 strlcpy(in_ifname
, "<iif?>", sizeof(in_ifname
));
5439 /* Find the group, create it if it doesn't exist */
5440 json_object_object_get_ex(json
, grp_str
, &json_group
);
5443 json_group
= json_object_new_object();
5444 json_object_object_add(json
, grp_str
,
5448 /* Find the source nested under the group, create it if
5449 * it doesn't exist */
5450 json_object_object_get_ex(json_group
, src_str
,
5454 json_source
= json_object_new_object();
5455 json_object_object_add(json_group
, src_str
,
5459 /* Find the inbound interface nested under the source,
5460 * create it if it doesn't exist */
5461 json_object_int_add(json_source
, "installed",
5463 json_object_int_add(json_source
, "refCount",
5464 c_oil
->oil_ref_count
);
5465 json_object_int_add(json_source
, "oilSize",
5467 json_object_int_add(json_source
, "OilInheritedRescan",
5468 c_oil
->oil_inherited_rescan
);
5469 json_object_string_add(json_source
, "iif", in_ifname
);
5473 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
5475 struct interface
*ifp_out
;
5476 char mroute_uptime
[10];
5479 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
5483 /* do not display muted OIFs */
5484 if (c_oil
->oif_flags
[oif_vif_index
]
5485 & PIM_OIF_FLAG_MUTE
)
5488 if (c_oil
->oil
.mfcc_parent
== oif_vif_index
&&
5489 !pim_mroute_allow_iif_in_oil(c_oil
,
5493 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
5495 mroute_uptime
, sizeof(mroute_uptime
),
5496 now
- c_oil
->mroute_creation
);
5500 strlcpy(out_ifname
, ifp_out
->name
, sizeof(out_ifname
));
5502 strlcpy(out_ifname
, "<oif?>", sizeof(out_ifname
));
5505 json_ifp_out
= json_object_new_object();
5506 json_object_string_add(json_ifp_out
, "source",
5508 json_object_string_add(json_ifp_out
, "group",
5511 if (c_oil
->oif_flags
[oif_vif_index
]
5512 & PIM_OIF_FLAG_PROTO_PIM
)
5513 json_object_boolean_true_add(
5514 json_ifp_out
, "protocolPim");
5516 if (c_oil
->oif_flags
[oif_vif_index
]
5517 & PIM_OIF_FLAG_PROTO_IGMP
)
5518 json_object_boolean_true_add(
5519 json_ifp_out
, "protocolIgmp");
5521 if (c_oil
->oif_flags
[oif_vif_index
]
5522 & PIM_OIF_FLAG_PROTO_VXLAN
)
5523 json_object_boolean_true_add(
5524 json_ifp_out
, "protocolVxlan");
5526 if (c_oil
->oif_flags
[oif_vif_index
]
5527 & PIM_OIF_FLAG_PROTO_STAR
)
5528 json_object_boolean_true_add(
5530 "protocolInherited");
5532 json_object_string_add(json_ifp_out
,
5535 json_object_int_add(json_ifp_out
, "iVifI",
5536 c_oil
->oil
.mfcc_parent
);
5537 json_object_string_add(json_ifp_out
,
5538 "outboundInterface",
5540 json_object_int_add(json_ifp_out
, "oVifI",
5542 json_object_int_add(json_ifp_out
, "ttl", ttl
);
5543 json_object_string_add(json_ifp_out
, "upTime",
5546 json_oil
= json_object_new_object();
5547 json_object_object_add(json_source
,
5550 json_object_object_add(json_oil
, out_ifname
,
5553 if (c_oil
->oif_flags
[oif_vif_index
]
5554 & PIM_OIF_FLAG_PROTO_PIM
) {
5555 strlcpy(proto
, "PIM", sizeof(proto
));
5558 if (c_oil
->oif_flags
[oif_vif_index
]
5559 & PIM_OIF_FLAG_PROTO_IGMP
) {
5560 strlcpy(proto
, "IGMP", sizeof(proto
));
5563 if (c_oil
->oif_flags
[oif_vif_index
]
5564 & PIM_OIF_FLAG_PROTO_VXLAN
) {
5565 strlcpy(proto
, "VxLAN", sizeof(proto
));
5568 if (c_oil
->oif_flags
[oif_vif_index
]
5569 & PIM_OIF_FLAG_PROTO_STAR
) {
5570 strlcpy(proto
, "STAR", sizeof(proto
));
5574 "%-15s %-15s %-6s %-16s %-16s %-3d %8s\n",
5575 src_str
, grp_str
, proto
, in_ifname
,
5576 out_ifname
, ttl
, mroute_uptime
);
5581 in_ifname
[0] = '\0';
5587 if (!uj
&& !found_oif
) {
5588 vty_out(vty
, "%-15s %-15s %-6s %-16s %-16s %-3d %8s\n",
5589 src_str
, grp_str
, "none", in_ifname
, "none", 0,
5594 /* Print list of static routes */
5595 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
5598 if (!s_route
->c_oil
.installed
)
5601 pim_inet4_dump("<group?>", s_route
->group
, grp_str
,
5603 pim_inet4_dump("<source?>", s_route
->source
, src_str
,
5605 ifp_in
= pim_if_find_by_vif_index(pim
, s_route
->iif
);
5609 strlcpy(in_ifname
, ifp_in
->name
, sizeof(in_ifname
));
5611 strlcpy(in_ifname
, "<iif?>", sizeof(in_ifname
));
5615 /* Find the group, create it if it doesn't exist */
5616 json_object_object_get_ex(json
, grp_str
, &json_group
);
5619 json_group
= json_object_new_object();
5620 json_object_object_add(json
, grp_str
,
5624 /* Find the source nested under the group, create it if
5625 * it doesn't exist */
5626 json_object_object_get_ex(json_group
, src_str
,
5630 json_source
= json_object_new_object();
5631 json_object_object_add(json_group
, src_str
,
5635 json_object_string_add(json_source
, "iif", in_ifname
);
5638 strlcpy(proto
, "STATIC", sizeof(proto
));
5641 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
5643 struct interface
*ifp_out
;
5644 char oif_uptime
[10];
5647 ttl
= s_route
->oif_ttls
[oif_vif_index
];
5651 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
5653 oif_uptime
, sizeof(oif_uptime
),
5656 .oif_creation
[oif_vif_index
]);
5660 strlcpy(out_ifname
, ifp_out
->name
, sizeof(out_ifname
));
5662 strlcpy(out_ifname
, "<oif?>", sizeof(out_ifname
));
5665 json_ifp_out
= json_object_new_object();
5666 json_object_string_add(json_ifp_out
, "source",
5668 json_object_string_add(json_ifp_out
, "group",
5670 json_object_boolean_true_add(json_ifp_out
,
5672 json_object_string_add(json_ifp_out
,
5675 json_object_int_add(
5676 json_ifp_out
, "iVifI",
5677 s_route
->c_oil
.oil
.mfcc_parent
);
5678 json_object_string_add(json_ifp_out
,
5679 "outboundInterface",
5681 json_object_int_add(json_ifp_out
, "oVifI",
5683 json_object_int_add(json_ifp_out
, "ttl", ttl
);
5684 json_object_string_add(json_ifp_out
, "upTime",
5687 json_oil
= json_object_new_object();
5688 json_object_object_add(json_source
,
5691 json_object_object_add(json_oil
, out_ifname
,
5695 "%-15s %-15s %-6s %-16s %-16s %-3d %8s %s\n",
5696 src_str
, grp_str
, proto
, in_ifname
,
5697 out_ifname
, ttl
, oif_uptime
,
5699 if (first
&& !fill
) {
5702 in_ifname
[0] = '\0';
5708 if (!uj
&& !found_oif
) {
5710 "%-15s %-15s %-6s %-16s %-16s %-3d %8s %s\n",
5711 src_str
, grp_str
, proto
, in_ifname
, "none", 0,
5712 "--:--:--", pim
->vrf
->name
);
5717 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5718 json
, JSON_C_TO_STRING_PRETTY
));
5719 json_object_free(json
);
5723 DEFPY (show_ip_mroute
,
5725 "show ip mroute [vrf NAME] [A.B.C.D$s_or_g [A.B.C.D$g]] [fill$fill] [json$json]",
5730 "The Source or Group\n"
5732 "Fill in Assumed data\n"
5735 struct prefix_sg sg
= {0};
5736 struct pim_instance
*pim
;
5739 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
5742 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
5745 pim
= pim_get_pim_instance(v
->vrf_id
);
5748 vty_out(vty
, "%% Unable to find pim instance\n");
5752 if (s_or_g
.s_addr
!= 0) {
5753 if (g
.s_addr
!= 0) {
5759 show_mroute(pim
, vty
, &sg
, !!fill
, !!json
);
5763 DEFUN (show_ip_mroute_vrf_all
,
5764 show_ip_mroute_vrf_all_cmd
,
5765 "show ip mroute vrf all [fill] [json]",
5770 "Fill in Assumed data\n"
5773 struct prefix_sg sg
= {0};
5774 bool uj
= use_json(argc
, argv
);
5780 if (argv_find(argv
, argc
, "fill", &idx
))
5785 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5789 vty_out(vty
, " \"%s\": ", vrf
->name
);
5792 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5793 show_mroute(vrf
->info
, vty
, &sg
, fill
, uj
);
5796 vty_out(vty
, "}\n");
5801 DEFUN (clear_ip_mroute_count
,
5802 clear_ip_mroute_count_cmd
,
5803 "clear ip mroute [vrf NAME] count",
5808 "Route and packet count data\n")
5811 struct listnode
*node
;
5812 struct channel_oil
*c_oil
;
5813 struct static_route
*sr
;
5814 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5815 struct pim_instance
*pim
;
5821 frr_each(rb_pim_oil
, &pim
->channel_oil_head
, c_oil
) {
5822 if (!c_oil
->installed
)
5825 pim_mroute_update_counters(c_oil
);
5826 c_oil
->cc
.origpktcnt
= c_oil
->cc
.pktcnt
;
5827 c_oil
->cc
.origbytecnt
= c_oil
->cc
.bytecnt
;
5828 c_oil
->cc
.origwrong_if
= c_oil
->cc
.wrong_if
;
5831 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, sr
)) {
5832 if (!sr
->c_oil
.installed
)
5835 pim_mroute_update_counters(&sr
->c_oil
);
5837 sr
->c_oil
.cc
.origpktcnt
= sr
->c_oil
.cc
.pktcnt
;
5838 sr
->c_oil
.cc
.origbytecnt
= sr
->c_oil
.cc
.bytecnt
;
5839 sr
->c_oil
.cc
.origwrong_if
= sr
->c_oil
.cc
.wrong_if
;
5844 static void show_mroute_count(struct pim_instance
*pim
, struct vty
*vty
)
5846 struct listnode
*node
;
5847 struct channel_oil
*c_oil
;
5848 struct static_route
*sr
;
5853 "Source Group LastUsed Packets Bytes WrongIf \n");
5855 /* Print PIM and IGMP route counts */
5856 frr_each (rb_pim_oil
, &pim
->channel_oil_head
, c_oil
) {
5857 char group_str
[INET_ADDRSTRLEN
];
5858 char source_str
[INET_ADDRSTRLEN
];
5860 if (!c_oil
->installed
)
5863 pim_mroute_update_counters(c_oil
);
5865 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, group_str
,
5867 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, source_str
,
5868 sizeof(source_str
));
5870 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
5871 source_str
, group_str
, c_oil
->cc
.lastused
/ 100,
5872 c_oil
->cc
.pktcnt
- c_oil
->cc
.origpktcnt
,
5873 c_oil
->cc
.bytecnt
- c_oil
->cc
.origbytecnt
,
5874 c_oil
->cc
.wrong_if
- c_oil
->cc
.origwrong_if
);
5877 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, sr
)) {
5878 char group_str
[INET_ADDRSTRLEN
];
5879 char source_str
[INET_ADDRSTRLEN
];
5881 if (!sr
->c_oil
.installed
)
5884 pim_mroute_update_counters(&sr
->c_oil
);
5886 pim_inet4_dump("<group?>", sr
->c_oil
.oil
.mfcc_mcastgrp
,
5887 group_str
, sizeof(group_str
));
5888 pim_inet4_dump("<source?>", sr
->c_oil
.oil
.mfcc_origin
,
5889 source_str
, sizeof(source_str
));
5891 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
5892 source_str
, group_str
, sr
->c_oil
.cc
.lastused
,
5893 sr
->c_oil
.cc
.pktcnt
- sr
->c_oil
.cc
.origpktcnt
,
5894 sr
->c_oil
.cc
.bytecnt
- sr
->c_oil
.cc
.origbytecnt
,
5895 sr
->c_oil
.cc
.wrong_if
- sr
->c_oil
.cc
.origwrong_if
);
5899 DEFUN (show_ip_mroute_count
,
5900 show_ip_mroute_count_cmd
,
5901 "show ip mroute [vrf NAME] count",
5906 "Route and packet count data\n")
5909 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5914 show_mroute_count(vrf
->info
, vty
);
5918 DEFUN (show_ip_mroute_count_vrf_all
,
5919 show_ip_mroute_count_vrf_all_cmd
,
5920 "show ip mroute vrf all count",
5925 "Route and packet count data\n")
5927 bool uj
= use_json(argc
, argv
);
5933 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5937 vty_out(vty
, " \"%s\": ", vrf
->name
);
5940 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5941 show_mroute_count(vrf
->info
, vty
);
5944 vty_out(vty
, "}\n");
5949 static void show_mroute_summary(struct pim_instance
*pim
, struct vty
*vty
)
5951 struct listnode
*node
;
5952 struct channel_oil
*c_oil
;
5953 struct static_route
*s_route
;
5954 uint32_t starg_sw_mroute_cnt
= 0;
5955 uint32_t sg_sw_mroute_cnt
= 0;
5956 uint32_t starg_hw_mroute_cnt
= 0;
5957 uint32_t sg_hw_mroute_cnt
= 0;
5959 vty_out(vty
, "Mroute Type Installed/Total\n");
5961 frr_each (rb_pim_oil
, &pim
->channel_oil_head
, c_oil
) {
5962 if (!c_oil
->installed
) {
5963 if (c_oil
->oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
5964 starg_sw_mroute_cnt
++;
5968 if (c_oil
->oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
5969 starg_hw_mroute_cnt
++;
5975 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
5976 if (!s_route
->c_oil
.installed
) {
5977 if (s_route
->c_oil
.oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
5978 starg_sw_mroute_cnt
++;
5982 if (s_route
->c_oil
.oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
5983 starg_hw_mroute_cnt
++;
5989 vty_out(vty
, "%-20s %d/%d\n", "(*, G)", starg_hw_mroute_cnt
,
5990 starg_sw_mroute_cnt
+ starg_hw_mroute_cnt
);
5991 vty_out(vty
, "%-20s %d/%d\n", "(S, G)", sg_hw_mroute_cnt
,
5992 sg_sw_mroute_cnt
+ sg_hw_mroute_cnt
);
5993 vty_out(vty
, "------\n");
5994 vty_out(vty
, "%-20s %d/%d\n", "Total",
5995 (starg_hw_mroute_cnt
+ sg_hw_mroute_cnt
),
5996 (starg_sw_mroute_cnt
+
5997 starg_hw_mroute_cnt
+
6002 DEFUN (show_ip_mroute_summary
,
6003 show_ip_mroute_summary_cmd
,
6004 "show ip mroute [vrf NAME] summary",
6009 "Summary of all mroutes\n")
6012 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6017 show_mroute_summary(vrf
->info
, vty
);
6021 DEFUN (show_ip_mroute_summary_vrf_all
,
6022 show_ip_mroute_summary_vrf_all_cmd
,
6023 "show ip mroute vrf all summary",
6028 "Summary of all mroutes\n")
6032 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
6033 vty_out(vty
, "VRF: %s\n", vrf
->name
);
6034 show_mroute_summary(vrf
->info
, vty
);
6042 "show ip rib [vrf NAME] A.B.C.D",
6047 "Unicast address\n")
6050 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6051 struct in_addr addr
;
6052 const char *addr_str
;
6053 struct pim_nexthop nexthop
;
6054 char nexthop_addr_str
[PREFIX_STRLEN
];
6060 memset(&nexthop
, 0, sizeof(nexthop
));
6061 argv_find(argv
, argc
, "A.B.C.D", &idx
);
6062 addr_str
= argv
[idx
]->arg
;
6063 result
= inet_pton(AF_INET
, addr_str
, &addr
);
6065 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
6066 errno
, safe_strerror(errno
));
6070 if (!pim_nexthop_lookup(vrf
->info
, &nexthop
, addr
, 0)) {
6072 "Failure querying RIB nexthop for unicast address %s\n",
6078 "Address NextHop Interface Metric Preference\n");
6080 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
6081 nexthop_addr_str
, sizeof(nexthop_addr_str
));
6083 vty_out(vty
, "%-15s %-15s %-9s %6d %10d\n", addr_str
, nexthop_addr_str
,
6084 nexthop
.interface
? nexthop
.interface
->name
: "<ifname?>",
6085 nexthop
.mrib_route_metric
, nexthop
.mrib_metric_preference
);
6090 static void show_ssmpingd(struct pim_instance
*pim
, struct vty
*vty
)
6092 struct listnode
*node
;
6093 struct ssmpingd_sock
*ss
;
6097 "Source Socket Address Port Uptime Requests\n");
6099 if (!pim
->ssmpingd_list
)
6102 now
= pim_time_monotonic_sec();
6104 for (ALL_LIST_ELEMENTS_RO(pim
->ssmpingd_list
, node
, ss
)) {
6105 char source_str
[INET_ADDRSTRLEN
];
6107 struct sockaddr_in bind_addr
;
6108 socklen_t len
= sizeof(bind_addr
);
6109 char bind_addr_str
[INET_ADDRSTRLEN
];
6111 pim_inet4_dump("<src?>", ss
->source_addr
, source_str
,
6112 sizeof(source_str
));
6114 if (pim_socket_getsockname(
6115 ss
->sock_fd
, (struct sockaddr
*)&bind_addr
, &len
)) {
6117 "%% Failure reading socket name for ssmpingd source %s on fd=%d\n",
6118 source_str
, ss
->sock_fd
);
6121 pim_inet4_dump("<addr?>", bind_addr
.sin_addr
, bind_addr_str
,
6122 sizeof(bind_addr_str
));
6123 pim_time_uptime(ss_uptime
, sizeof(ss_uptime
),
6124 now
- ss
->creation
);
6126 vty_out(vty
, "%-15s %6d %-15s %5d %8s %8lld\n", source_str
,
6127 ss
->sock_fd
, bind_addr_str
, ntohs(bind_addr
.sin_port
),
6128 ss_uptime
, (long long)ss
->requests
);
6132 DEFUN (show_ip_ssmpingd
,
6133 show_ip_ssmpingd_cmd
,
6134 "show ip ssmpingd [vrf NAME]",
6141 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6146 show_ssmpingd(vrf
->info
, vty
);
6150 static int pim_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
6151 const char *rp
, const char *group
,
6156 result
= pim_rp_new_config(pim
, rp
, group
, plist
);
6158 if (result
== PIM_GROUP_BAD_ADDR_MASK_COMBO
) {
6159 vty_out(vty
, "%% Inconsistent address and mask: %s\n",
6161 return CMD_WARNING_CONFIG_FAILED
;
6164 if (result
== PIM_GROUP_BAD_ADDRESS
) {
6165 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
6166 return CMD_WARNING_CONFIG_FAILED
;
6169 if (result
== PIM_RP_BAD_ADDRESS
) {
6170 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
6171 return CMD_WARNING_CONFIG_FAILED
;
6174 if (result
== PIM_RP_NO_PATH
) {
6175 vty_out(vty
, "%% No Path to RP address specified: %s\n", rp
);
6179 if (result
== PIM_GROUP_OVERLAP
) {
6181 "%% Group range specified cannot exact match another\n");
6182 return CMD_WARNING_CONFIG_FAILED
;
6185 if (result
== PIM_GROUP_PFXLIST_OVERLAP
) {
6187 "%% This group is already covered by a RP prefix-list\n");
6188 return CMD_WARNING_CONFIG_FAILED
;
6191 if (result
== PIM_RP_PFXLIST_IN_USE
) {
6193 "%% The same prefix-list cannot be applied to multiple RPs\n");
6194 return CMD_WARNING_CONFIG_FAILED
;
6200 static int pim_cmd_spt_switchover(struct pim_instance
*pim
,
6201 enum pim_spt_switchover spt
,
6204 pim
->spt
.switchover
= spt
;
6206 switch (pim
->spt
.switchover
) {
6207 case PIM_SPT_IMMEDIATE
:
6208 XFREE(MTYPE_PIM_SPT_PLIST_NAME
, pim
->spt
.plist
);
6210 pim_upstream_add_lhr_star_pimreg(pim
);
6212 case PIM_SPT_INFINITY
:
6213 pim_upstream_remove_lhr_star_pimreg(pim
, plist
);
6215 XFREE(MTYPE_PIM_SPT_PLIST_NAME
, pim
->spt
.plist
);
6219 XSTRDUP(MTYPE_PIM_SPT_PLIST_NAME
, plist
);
6226 DEFUN (ip_pim_spt_switchover_infinity
,
6227 ip_pim_spt_switchover_infinity_cmd
,
6228 "ip pim spt-switchover infinity-and-beyond",
6232 "Never switch to SPT Tree\n")
6234 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6235 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, NULL
);
6238 DEFUN (ip_pim_spt_switchover_infinity_plist
,
6239 ip_pim_spt_switchover_infinity_plist_cmd
,
6240 "ip pim spt-switchover infinity-and-beyond prefix-list WORD",
6244 "Never switch to SPT Tree\n"
6245 "Prefix-List to control which groups to switch\n"
6246 "Prefix-List name\n")
6248 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6249 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, argv
[5]->arg
);
6252 DEFUN (no_ip_pim_spt_switchover_infinity
,
6253 no_ip_pim_spt_switchover_infinity_cmd
,
6254 "no ip pim spt-switchover infinity-and-beyond",
6259 "Never switch to SPT Tree\n")
6261 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6262 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
6265 DEFUN (no_ip_pim_spt_switchover_infinity_plist
,
6266 no_ip_pim_spt_switchover_infinity_plist_cmd
,
6267 "no ip pim spt-switchover infinity-and-beyond prefix-list WORD",
6272 "Never switch to SPT Tree\n"
6273 "Prefix-List to control which groups to switch\n"
6274 "Prefix-List name\n")
6276 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6277 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
6280 DEFUN (ip_pim_joinprune_time
,
6281 ip_pim_joinprune_time_cmd
,
6282 "ip pim join-prune-interval (60-600)",
6284 "pim multicast routing\n"
6285 "Join Prune Send Interval\n"
6288 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6289 router
->t_periodic
= atoi(argv
[3]->arg
);
6293 DEFUN (no_ip_pim_joinprune_time
,
6294 no_ip_pim_joinprune_time_cmd
,
6295 "no ip pim join-prune-interval (60-600)",
6298 "pim multicast routing\n"
6299 "Join Prune Send Interval\n"
6302 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6303 router
->t_periodic
= PIM_DEFAULT_T_PERIODIC
;
6307 DEFUN (ip_pim_register_suppress
,
6308 ip_pim_register_suppress_cmd
,
6309 "ip pim register-suppress-time (5-60000)",
6311 "pim multicast routing\n"
6312 "Register Suppress Timer\n"
6315 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6316 router
->register_suppress_time
= atoi(argv
[3]->arg
);
6320 DEFUN (no_ip_pim_register_suppress
,
6321 no_ip_pim_register_suppress_cmd
,
6322 "no ip pim register-suppress-time (5-60000)",
6325 "pim multicast routing\n"
6326 "Register Suppress Timer\n"
6329 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6330 router
->register_suppress_time
= PIM_REGISTER_SUPPRESSION_TIME_DEFAULT
;
6334 DEFUN (ip_pim_rp_keep_alive
,
6335 ip_pim_rp_keep_alive_cmd
,
6336 "ip pim rp keep-alive-timer (31-60000)",
6338 "pim multicast routing\n"
6340 "Keep alive Timer\n"
6343 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6344 pim
->rp_keep_alive_time
= atoi(argv
[4]->arg
);
6348 DEFUN (no_ip_pim_rp_keep_alive
,
6349 no_ip_pim_rp_keep_alive_cmd
,
6350 "no ip pim rp keep-alive-timer (31-60000)",
6353 "pim multicast routing\n"
6355 "Keep alive Timer\n"
6358 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6359 pim
->rp_keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
6363 DEFUN (ip_pim_keep_alive
,
6364 ip_pim_keep_alive_cmd
,
6365 "ip pim keep-alive-timer (31-60000)",
6367 "pim multicast routing\n"
6368 "Keep alive Timer\n"
6371 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6372 pim
->keep_alive_time
= atoi(argv
[3]->arg
);
6376 DEFUN (no_ip_pim_keep_alive
,
6377 no_ip_pim_keep_alive_cmd
,
6378 "no ip pim keep-alive-timer (31-60000)",
6381 "pim multicast routing\n"
6382 "Keep alive Timer\n"
6385 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6386 pim
->keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
6390 DEFUN (ip_pim_packets
,
6392 "ip pim packets (1-100)",
6394 "pim multicast routing\n"
6395 "packets to process at one time per fd\n"
6396 "Number of packets\n")
6398 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6399 router
->packet_process
= atoi(argv
[3]->arg
);
6403 DEFUN (no_ip_pim_packets
,
6404 no_ip_pim_packets_cmd
,
6405 "no ip pim packets (1-100)",
6408 "pim multicast routing\n"
6409 "packets to process at one time per fd\n"
6410 "Number of packets\n")
6412 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6413 router
->packet_process
= PIM_DEFAULT_PACKET_PROCESS
;
6417 DEFUN (ip_pim_v6_secondary
,
6418 ip_pim_v6_secondary_cmd
,
6419 "ip pim send-v6-secondary",
6421 "pim multicast routing\n"
6422 "Send v6 secondary addresses\n")
6424 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6425 pim
->send_v6_secondary
= 1;
6430 DEFUN (no_ip_pim_v6_secondary
,
6431 no_ip_pim_v6_secondary_cmd
,
6432 "no ip pim send-v6-secondary",
6435 "pim multicast routing\n"
6436 "Send v6 secondary addresses\n")
6438 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6439 pim
->send_v6_secondary
= 0;
6446 "ip pim rp A.B.C.D [A.B.C.D/M]",
6448 "pim multicast routing\n"
6450 "ip address of RP\n"
6451 "Group Address range to cover\n")
6453 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6456 if (argc
== (idx_ipv4
+ 1))
6457 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
6460 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
6461 argv
[idx_ipv4
+ 1]->arg
, NULL
);
6464 DEFUN (ip_pim_rp_prefix_list
,
6465 ip_pim_rp_prefix_list_cmd
,
6466 "ip pim rp A.B.C.D prefix-list WORD",
6468 "pim multicast routing\n"
6470 "ip address of RP\n"
6471 "group prefix-list filter\n"
6472 "Name of a prefix-list\n")
6474 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6475 return pim_rp_cmd_worker(pim
, vty
, argv
[3]->arg
, NULL
, argv
[5]->arg
);
6478 static int pim_no_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
6479 const char *rp
, const char *group
,
6482 int result
= pim_rp_del_config(pim
, rp
, group
, plist
);
6484 if (result
== PIM_GROUP_BAD_ADDRESS
) {
6485 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
6486 return CMD_WARNING_CONFIG_FAILED
;
6489 if (result
== PIM_RP_BAD_ADDRESS
) {
6490 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
6491 return CMD_WARNING_CONFIG_FAILED
;
6494 if (result
== PIM_RP_NOT_FOUND
) {
6495 vty_out(vty
, "%% Unable to find specified RP\n");
6496 return CMD_WARNING_CONFIG_FAILED
;
6502 DEFUN (no_ip_pim_rp
,
6504 "no ip pim rp A.B.C.D [A.B.C.D/M]",
6507 "pim multicast routing\n"
6509 "ip address of RP\n"
6510 "Group Address range to cover\n")
6512 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6513 int idx_ipv4
= 4, idx_group
= 0;
6515 if (argv_find(argv
, argc
, "A.B.C.D/M", &idx_group
))
6516 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
6517 argv
[idx_group
]->arg
, NULL
);
6519 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
6523 DEFUN (no_ip_pim_rp_prefix_list
,
6524 no_ip_pim_rp_prefix_list_cmd
,
6525 "no ip pim rp A.B.C.D prefix-list WORD",
6528 "pim multicast routing\n"
6530 "ip address of RP\n"
6531 "group prefix-list filter\n"
6532 "Name of a prefix-list\n")
6534 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6535 return pim_no_rp_cmd_worker(pim
, vty
, argv
[4]->arg
, NULL
, argv
[6]->arg
);
6538 static int pim_ssm_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
6541 int result
= pim_ssm_range_set(pim
, pim
->vrf_id
, plist
);
6542 int ret
= CMD_WARNING_CONFIG_FAILED
;
6544 if (result
== PIM_SSM_ERR_NONE
)
6548 case PIM_SSM_ERR_NO_VRF
:
6549 vty_out(vty
, "%% VRF doesn't exist\n");
6551 case PIM_SSM_ERR_DUP
:
6552 vty_out(vty
, "%% duplicate config\n");
6556 vty_out(vty
, "%% ssm range config failed\n");
6562 DEFUN (ip_pim_ssm_prefix_list
,
6563 ip_pim_ssm_prefix_list_cmd
,
6564 "ip pim ssm prefix-list WORD",
6566 "pim multicast routing\n"
6567 "Source Specific Multicast\n"
6568 "group range prefix-list filter\n"
6569 "Name of a prefix-list\n")
6571 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6572 return pim_ssm_cmd_worker(pim
, vty
, argv
[4]->arg
);
6575 DEFUN (no_ip_pim_ssm_prefix_list
,
6576 no_ip_pim_ssm_prefix_list_cmd
,
6577 "no ip pim ssm prefix-list",
6580 "pim multicast routing\n"
6581 "Source Specific Multicast\n"
6582 "group range prefix-list filter\n")
6584 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6585 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
6588 DEFUN (no_ip_pim_ssm_prefix_list_name
,
6589 no_ip_pim_ssm_prefix_list_name_cmd
,
6590 "no ip pim ssm prefix-list WORD",
6593 "pim multicast routing\n"
6594 "Source Specific Multicast\n"
6595 "group range prefix-list filter\n"
6596 "Name of a prefix-list\n")
6598 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6599 struct pim_ssm
*ssm
= pim
->ssm_info
;
6601 if (ssm
->plist_name
&& !strcmp(ssm
->plist_name
, argv
[5]->arg
))
6602 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
6604 vty_out(vty
, "%% pim ssm prefix-list %s doesn't exist\n", argv
[5]->arg
);
6606 return CMD_WARNING_CONFIG_FAILED
;
6609 static void ip_pim_ssm_show_group_range(struct pim_instance
*pim
,
6610 struct vty
*vty
, bool uj
)
6612 struct pim_ssm
*ssm
= pim
->ssm_info
;
6613 const char *range_str
=
6614 ssm
->plist_name
? ssm
->plist_name
: PIM_SSM_STANDARD_RANGE
;
6618 json
= json_object_new_object();
6619 json_object_string_add(json
, "ssmGroups", range_str
);
6620 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
6621 json
, JSON_C_TO_STRING_PRETTY
));
6622 json_object_free(json
);
6624 vty_out(vty
, "SSM group range : %s\n", range_str
);
6627 DEFUN (show_ip_pim_ssm_range
,
6628 show_ip_pim_ssm_range_cmd
,
6629 "show ip pim [vrf NAME] group-type [json]",
6638 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6639 bool uj
= use_json(argc
, argv
);
6644 ip_pim_ssm_show_group_range(vrf
->info
, vty
, uj
);
6649 static void ip_pim_ssm_show_group_type(struct pim_instance
*pim
,
6650 struct vty
*vty
, bool uj
,
6653 struct in_addr group_addr
;
6654 const char *type_str
;
6657 result
= inet_pton(AF_INET
, group
, &group_addr
);
6659 type_str
= "invalid";
6661 if (pim_is_group_224_4(group_addr
))
6663 pim_is_grp_ssm(pim
, group_addr
) ? "SSM" : "ASM";
6665 type_str
= "not-multicast";
6670 json
= json_object_new_object();
6671 json_object_string_add(json
, "groupType", type_str
);
6672 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
6673 json
, JSON_C_TO_STRING_PRETTY
));
6674 json_object_free(json
);
6676 vty_out(vty
, "Group type : %s\n", type_str
);
6679 DEFUN (show_ip_pim_group_type
,
6680 show_ip_pim_group_type_cmd
,
6681 "show ip pim [vrf NAME] group-type A.B.C.D [json]",
6686 "multicast group type\n"
6691 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6692 bool uj
= use_json(argc
, argv
);
6697 argv_find(argv
, argc
, "A.B.C.D", &idx
);
6698 ip_pim_ssm_show_group_type(vrf
->info
, vty
, uj
, argv
[idx
]->arg
);
6703 DEFUN (show_ip_pim_bsr
,
6704 show_ip_pim_bsr_cmd
,
6705 "show ip pim bsr [json]",
6709 "boot-strap router information\n"
6713 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6714 bool uj
= use_json(argc
, argv
);
6719 pim_show_bsr(vrf
->info
, vty
, uj
);
6726 "ip ssmpingd [A.B.C.D]",
6731 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6734 struct in_addr source_addr
;
6735 const char *source_str
= (argc
== 3) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
6737 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
6739 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
6740 source_str
, errno
, safe_strerror(errno
));
6741 return CMD_WARNING_CONFIG_FAILED
;
6744 result
= pim_ssmpingd_start(pim
, source_addr
);
6746 vty_out(vty
, "%% Failure starting ssmpingd for source %s: %d\n",
6747 source_str
, result
);
6748 return CMD_WARNING_CONFIG_FAILED
;
6754 DEFUN (no_ip_ssmpingd
,
6756 "no ip ssmpingd [A.B.C.D]",
6762 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6765 struct in_addr source_addr
;
6766 const char *source_str
= (argc
== 4) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
6768 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
6770 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
6771 source_str
, errno
, safe_strerror(errno
));
6772 return CMD_WARNING_CONFIG_FAILED
;
6775 result
= pim_ssmpingd_stop(pim
, source_addr
);
6777 vty_out(vty
, "%% Failure stopping ssmpingd for source %s: %d\n",
6778 source_str
, result
);
6779 return CMD_WARNING_CONFIG_FAILED
;
6789 "pim multicast routing\n"
6790 "Enable PIM ECMP \n")
6792 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6793 pim
->ecmp_enable
= true;
6798 DEFUN (no_ip_pim_ecmp
,
6803 "pim multicast routing\n"
6804 "Disable PIM ECMP \n")
6806 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6807 pim
->ecmp_enable
= false;
6812 DEFUN (ip_pim_ecmp_rebalance
,
6813 ip_pim_ecmp_rebalance_cmd
,
6814 "ip pim ecmp rebalance",
6816 "pim multicast routing\n"
6817 "Enable PIM ECMP \n"
6818 "Enable PIM ECMP Rebalance\n")
6820 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6821 pim
->ecmp_enable
= true;
6822 pim
->ecmp_rebalance_enable
= true;
6827 DEFUN (no_ip_pim_ecmp_rebalance
,
6828 no_ip_pim_ecmp_rebalance_cmd
,
6829 "no ip pim ecmp rebalance",
6832 "pim multicast routing\n"
6833 "Disable PIM ECMP \n"
6834 "Disable PIM ECMP Rebalance\n")
6836 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6837 pim
->ecmp_rebalance_enable
= false;
6842 static int pim_cmd_igmp_start(struct vty
*vty
, struct interface
*ifp
)
6844 struct pim_interface
*pim_ifp
;
6845 uint8_t need_startup
= 0;
6847 pim_ifp
= ifp
->info
;
6850 (void)pim_if_new(ifp
, true, false, false, false);
6853 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
6854 PIM_IF_DO_IGMP(pim_ifp
->options
);
6859 /* 'ip igmp' executed multiple times, with need_startup
6860 avoid multiple if add all and membership refresh */
6862 pim_if_addr_add_all(ifp
);
6863 pim_if_membership_refresh(ifp
);
6869 DEFUN (interface_ip_igmp
,
6870 interface_ip_igmp_cmd
,
6875 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6877 return pim_cmd_igmp_start(vty
, ifp
);
6880 DEFUN (interface_no_ip_igmp
,
6881 interface_no_ip_igmp_cmd
,
6887 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6888 struct pim_interface
*pim_ifp
= ifp
->info
;
6893 PIM_IF_DONT_IGMP(pim_ifp
->options
);
6895 pim_if_membership_clear(ifp
);
6897 pim_if_addr_del_all_igmp(ifp
);
6899 if (!PIM_IF_TEST_PIM(pim_ifp
->options
)) {
6906 DEFUN (interface_ip_igmp_join
,
6907 interface_ip_igmp_join_cmd
,
6908 "ip igmp join A.B.C.D [A.B.C.D]",
6911 "IGMP join multicast group\n"
6912 "Multicast group address\n"
6915 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6918 const char *group_str
;
6919 const char *source_str
;
6920 struct in_addr group_addr
;
6921 struct in_addr source_addr
;
6925 group_str
= argv
[idx_ipv4
]->arg
;
6926 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
6928 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
6929 errno
, safe_strerror(errno
));
6930 return CMD_WARNING_CONFIG_FAILED
;
6933 /* Source address */
6934 if (argc
== (idx_ipv4_2
+ 1)) {
6935 source_str
= argv
[idx_ipv4_2
]->arg
;
6936 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
6938 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
6939 source_str
, errno
, safe_strerror(errno
));
6940 return CMD_WARNING_CONFIG_FAILED
;
6942 /* Reject 0.0.0.0. Reserved for any source. */
6943 if (source_addr
.s_addr
== INADDR_ANY
) {
6944 vty_out(vty
, "Bad source address %s\n", source_str
);
6945 return CMD_WARNING_CONFIG_FAILED
;
6948 source_addr
.s_addr
= INADDR_ANY
;
6951 CMD_FERR_RETURN(pim_if_igmp_join_add(ifp
, group_addr
, source_addr
),
6952 "Failure joining IGMP group: $ERR");
6957 DEFUN (interface_no_ip_igmp_join
,
6958 interface_no_ip_igmp_join_cmd
,
6959 "no ip igmp join A.B.C.D [A.B.C.D]",
6963 "IGMP join multicast group\n"
6964 "Multicast group address\n"
6967 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6970 const char *group_str
;
6971 const char *source_str
;
6972 struct in_addr group_addr
;
6973 struct in_addr source_addr
;
6977 group_str
= argv
[idx_ipv4
]->arg
;
6978 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
6980 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
6981 errno
, safe_strerror(errno
));
6982 return CMD_WARNING_CONFIG_FAILED
;
6985 /* Source address */
6986 if (argc
== (idx_ipv4_2
+ 1)) {
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
;
6994 /* Reject 0.0.0.0. Reserved for any source. */
6995 if (source_addr
.s_addr
== INADDR_ANY
) {
6996 vty_out(vty
, "Bad source address %s\n", source_str
);
6997 return CMD_WARNING_CONFIG_FAILED
;
7001 source_addr
.s_addr
= INADDR_ANY
;
7004 result
= pim_if_igmp_join_del(ifp
, group_addr
, source_addr
);
7007 "%% Failure leaving IGMP group %s source %s on interface %s: %d\n",
7008 group_str
, source_str
, ifp
->name
, result
);
7009 return CMD_WARNING_CONFIG_FAILED
;
7016 CLI reconfiguration affects the interface level (struct pim_interface).
7017 This function propagates the reconfiguration to every active socket
7020 static void igmp_sock_query_interval_reconfig(struct igmp_sock
*igmp
)
7022 struct interface
*ifp
;
7023 struct pim_interface
*pim_ifp
;
7027 /* other querier present? */
7029 if (igmp
->t_other_querier_timer
)
7032 /* this is the querier */
7034 zassert(igmp
->interface
);
7035 zassert(igmp
->interface
->info
);
7037 ifp
= igmp
->interface
;
7038 pim_ifp
= ifp
->info
;
7040 if (PIM_DEBUG_IGMP_TRACE
) {
7041 char ifaddr_str
[INET_ADDRSTRLEN
];
7042 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
7043 sizeof(ifaddr_str
));
7044 zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
7045 __PRETTY_FUNCTION__
, ifaddr_str
, ifp
->name
,
7046 pim_ifp
->igmp_default_query_interval
);
7050 igmp_startup_mode_on() will reset QQI:
7052 igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
7054 igmp_startup_mode_on(igmp
);
7057 static void igmp_sock_query_reschedule(struct igmp_sock
*igmp
)
7059 if (igmp
->t_igmp_query_timer
) {
7060 /* other querier present */
7061 zassert(igmp
->t_igmp_query_timer
);
7062 zassert(!igmp
->t_other_querier_timer
);
7064 pim_igmp_general_query_off(igmp
);
7065 pim_igmp_general_query_on(igmp
);
7067 zassert(igmp
->t_igmp_query_timer
);
7068 zassert(!igmp
->t_other_querier_timer
);
7070 /* this is the querier */
7072 zassert(!igmp
->t_igmp_query_timer
);
7073 zassert(igmp
->t_other_querier_timer
);
7075 pim_igmp_other_querier_timer_off(igmp
);
7076 pim_igmp_other_querier_timer_on(igmp
);
7078 zassert(!igmp
->t_igmp_query_timer
);
7079 zassert(igmp
->t_other_querier_timer
);
7083 static void change_query_interval(struct pim_interface
*pim_ifp
,
7086 struct listnode
*sock_node
;
7087 struct igmp_sock
*igmp
;
7089 pim_ifp
->igmp_default_query_interval
= query_interval
;
7091 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
7092 igmp_sock_query_interval_reconfig(igmp
);
7093 igmp_sock_query_reschedule(igmp
);
7097 static void change_query_max_response_time(struct pim_interface
*pim_ifp
,
7098 int query_max_response_time_dsec
)
7100 struct listnode
*sock_node
;
7101 struct igmp_sock
*igmp
;
7103 pim_ifp
->igmp_query_max_response_time_dsec
=
7104 query_max_response_time_dsec
;
7107 Below we modify socket/group/source timers in order to quickly
7108 reflect the change. Otherwise, those timers would eventually catch
7112 /* scan all sockets */
7113 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
7114 struct listnode
*grp_node
;
7115 struct igmp_group
*grp
;
7117 /* reschedule socket general query */
7118 igmp_sock_query_reschedule(igmp
);
7120 /* scan socket groups */
7121 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grp_node
,
7123 struct listnode
*src_node
;
7124 struct igmp_source
*src
;
7126 /* reset group timers for groups in EXCLUDE mode */
7127 if (grp
->group_filtermode_isexcl
) {
7128 igmp_group_reset_gmi(grp
);
7131 /* scan group sources */
7132 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
,
7135 /* reset source timers for sources with running
7137 if (src
->t_source_timer
) {
7138 igmp_source_reset_gmi(igmp
, grp
, src
);
7145 #define IGMP_QUERY_INTERVAL_MIN (1)
7146 #define IGMP_QUERY_INTERVAL_MAX (1800)
7148 DEFUN (interface_ip_igmp_query_interval
,
7149 interface_ip_igmp_query_interval_cmd
,
7150 "ip igmp query-interval (1-1800)",
7153 IFACE_IGMP_QUERY_INTERVAL_STR
7154 "Query interval in seconds\n")
7156 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7157 struct pim_interface
*pim_ifp
= ifp
->info
;
7159 int query_interval_dsec
;
7163 ret
= pim_cmd_igmp_start(vty
, ifp
);
7164 if (ret
!= CMD_SUCCESS
)
7166 pim_ifp
= ifp
->info
;
7169 query_interval
= atoi(argv
[3]->arg
);
7170 query_interval_dsec
= 10 * query_interval
;
7173 It seems we don't need to check bounds since command.c does it
7174 already, but we verify them anyway for extra safety.
7176 if (query_interval
< IGMP_QUERY_INTERVAL_MIN
) {
7178 "General query interval %d lower than minimum %d\n",
7179 query_interval
, IGMP_QUERY_INTERVAL_MIN
);
7180 return CMD_WARNING_CONFIG_FAILED
;
7182 if (query_interval
> IGMP_QUERY_INTERVAL_MAX
) {
7184 "General query interval %d higher than maximum %d\n",
7185 query_interval
, IGMP_QUERY_INTERVAL_MAX
);
7186 return CMD_WARNING_CONFIG_FAILED
;
7189 if (query_interval_dsec
<= pim_ifp
->igmp_query_max_response_time_dsec
) {
7191 "Can't set general query interval %d dsec <= query max response time %d dsec.\n",
7192 query_interval_dsec
,
7193 pim_ifp
->igmp_query_max_response_time_dsec
);
7194 return CMD_WARNING_CONFIG_FAILED
;
7197 change_query_interval(pim_ifp
, query_interval
);
7202 DEFUN (interface_no_ip_igmp_query_interval
,
7203 interface_no_ip_igmp_query_interval_cmd
,
7204 "no ip igmp query-interval",
7208 IFACE_IGMP_QUERY_INTERVAL_STR
)
7210 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7211 struct pim_interface
*pim_ifp
= ifp
->info
;
7212 int default_query_interval_dsec
;
7217 default_query_interval_dsec
= IGMP_GENERAL_QUERY_INTERVAL
* 10;
7219 if (default_query_interval_dsec
7220 <= pim_ifp
->igmp_query_max_response_time_dsec
) {
7222 "Can't set default general query interval %d dsec <= query max response time %d dsec.\n",
7223 default_query_interval_dsec
,
7224 pim_ifp
->igmp_query_max_response_time_dsec
);
7225 return CMD_WARNING_CONFIG_FAILED
;
7228 change_query_interval(pim_ifp
, IGMP_GENERAL_QUERY_INTERVAL
);
7233 DEFUN (interface_ip_igmp_version
,
7234 interface_ip_igmp_version_cmd
,
7235 "ip igmp version (2-3)",
7239 "IGMP version number\n")
7241 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7242 struct pim_interface
*pim_ifp
= ifp
->info
;
7243 int igmp_version
, old_version
= 0;
7247 ret
= pim_cmd_igmp_start(vty
, ifp
);
7248 if (ret
!= CMD_SUCCESS
)
7250 pim_ifp
= ifp
->info
;
7253 igmp_version
= atoi(argv
[3]->arg
);
7254 old_version
= pim_ifp
->igmp_version
;
7255 pim_ifp
->igmp_version
= igmp_version
;
7257 // Check if IGMP is Enabled otherwise, enable on interface
7258 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
7259 PIM_IF_DO_IGMP(pim_ifp
->options
);
7260 pim_if_addr_add_all(ifp
);
7261 pim_if_membership_refresh(ifp
);
7262 old_version
= igmp_version
;
7263 // avoid refreshing membership again.
7265 /* Current and new version is different refresh existing
7266 membership. Going from 3 -> 2 or 2 -> 3. */
7267 if (old_version
!= igmp_version
)
7268 pim_if_membership_refresh(ifp
);
7273 DEFUN (interface_no_ip_igmp_version
,
7274 interface_no_ip_igmp_version_cmd
,
7275 "no ip igmp version (2-3)",
7280 "IGMP version number\n")
7282 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7283 struct pim_interface
*pim_ifp
= ifp
->info
;
7288 pim_ifp
->igmp_version
= IGMP_DEFAULT_VERSION
;
7293 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
7294 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
7296 DEFUN (interface_ip_igmp_query_max_response_time
,
7297 interface_ip_igmp_query_max_response_time_cmd
,
7298 "ip igmp query-max-response-time (10-250)",
7301 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
7302 "Query response value in deci-seconds\n")
7304 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7305 struct pim_interface
*pim_ifp
= ifp
->info
;
7306 int query_max_response_time
;
7310 ret
= pim_cmd_igmp_start(vty
, ifp
);
7311 if (ret
!= CMD_SUCCESS
)
7313 pim_ifp
= ifp
->info
;
7316 query_max_response_time
= atoi(argv
[3]->arg
);
7318 if (query_max_response_time
7319 >= pim_ifp
->igmp_default_query_interval
* 10) {
7321 "Can't set query max response time %d sec >= general query interval %d sec\n",
7322 query_max_response_time
,
7323 pim_ifp
->igmp_default_query_interval
);
7324 return CMD_WARNING_CONFIG_FAILED
;
7327 change_query_max_response_time(pim_ifp
, query_max_response_time
);
7332 DEFUN (interface_no_ip_igmp_query_max_response_time
,
7333 interface_no_ip_igmp_query_max_response_time_cmd
,
7334 "no ip igmp query-max-response-time (10-250)",
7338 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
7339 "Time for response in deci-seconds\n")
7341 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7342 struct pim_interface
*pim_ifp
= ifp
->info
;
7347 change_query_max_response_time(pim_ifp
,
7348 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
7353 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
7354 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
7356 DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec
,
7357 interface_ip_igmp_query_max_response_time_dsec_cmd
,
7358 "ip igmp query-max-response-time-dsec (10-250)",
7361 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
7362 "Query response value in deciseconds\n")
7364 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7365 struct pim_interface
*pim_ifp
= ifp
->info
;
7366 int query_max_response_time_dsec
;
7367 int default_query_interval_dsec
;
7371 ret
= pim_cmd_igmp_start(vty
, ifp
);
7372 if (ret
!= CMD_SUCCESS
)
7374 pim_ifp
= ifp
->info
;
7377 query_max_response_time_dsec
= atoi(argv
[4]->arg
);
7379 default_query_interval_dsec
= 10 * pim_ifp
->igmp_default_query_interval
;
7381 if (query_max_response_time_dsec
>= default_query_interval_dsec
) {
7383 "Can't set query max response time %d dsec >= general query interval %d dsec\n",
7384 query_max_response_time_dsec
,
7385 default_query_interval_dsec
);
7386 return CMD_WARNING_CONFIG_FAILED
;
7389 change_query_max_response_time(pim_ifp
, query_max_response_time_dsec
);
7394 DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec
,
7395 interface_no_ip_igmp_query_max_response_time_dsec_cmd
,
7396 "no ip igmp query-max-response-time-dsec",
7400 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
)
7402 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7403 struct pim_interface
*pim_ifp
= ifp
->info
;
7408 change_query_max_response_time(pim_ifp
,
7409 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
7414 #define IGMP_LAST_MEMBER_QUERY_COUNT_MIN (1)
7415 #define IGMP_LAST_MEMBER_QUERY_COUNT_MAX (7)
7417 DEFUN (interface_ip_igmp_last_member_query_count
,
7418 interface_ip_igmp_last_member_query_count_cmd
,
7419 "ip igmp last-member-query-count (1-7)",
7422 IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR
7423 "Last member query count\n")
7425 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7426 struct pim_interface
*pim_ifp
= ifp
->info
;
7427 int last_member_query_count
;
7431 ret
= pim_cmd_igmp_start(vty
, ifp
);
7432 if (ret
!= CMD_SUCCESS
)
7434 pim_ifp
= ifp
->info
;
7437 last_member_query_count
= atoi(argv
[3]->arg
);
7439 pim_ifp
->igmp_last_member_query_count
= last_member_query_count
;
7444 DEFUN (interface_no_ip_igmp_last_member_query_count
,
7445 interface_no_ip_igmp_last_member_query_count_cmd
,
7446 "no ip igmp last-member-query-count",
7450 IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR
)
7452 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7453 struct pim_interface
*pim_ifp
= ifp
->info
;
7458 pim_ifp
->igmp_last_member_query_count
=
7459 IGMP_DEFAULT_ROBUSTNESS_VARIABLE
;
7464 #define IGMP_LAST_MEMBER_QUERY_INTERVAL_MIN (1)
7465 #define IGMP_LAST_MEMBER_QUERY_INTERVAL_MAX (255)
7467 DEFUN (interface_ip_igmp_last_member_query_interval
,
7468 interface_ip_igmp_last_member_query_interval_cmd
,
7469 "ip igmp last-member-query-interval (1-255)",
7472 IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR
7473 "Last member query interval in deciseconds\n")
7475 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7476 struct pim_interface
*pim_ifp
= ifp
->info
;
7477 int last_member_query_interval
;
7481 ret
= pim_cmd_igmp_start(vty
, ifp
);
7482 if (ret
!= CMD_SUCCESS
)
7484 pim_ifp
= ifp
->info
;
7487 last_member_query_interval
= atoi(argv
[3]->arg
);
7488 pim_ifp
->igmp_specific_query_max_response_time_dsec
7489 = last_member_query_interval
;
7494 DEFUN (interface_no_ip_igmp_last_member_query_interval
,
7495 interface_no_ip_igmp_last_member_query_interval_cmd
,
7496 "no ip igmp last-member-query-interval",
7500 IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR
)
7502 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7503 struct pim_interface
*pim_ifp
= ifp
->info
;
7508 pim_ifp
->igmp_specific_query_max_response_time_dsec
=
7509 IGMP_SPECIFIC_QUERY_MAX_RESPONSE_TIME_DSEC
;
7514 DEFUN (interface_ip_pim_drprio
,
7515 interface_ip_pim_drprio_cmd
,
7516 "ip pim drpriority (1-4294967295)",
7519 "Set the Designated Router Election Priority\n"
7520 "Value of the new DR Priority\n")
7522 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7524 struct pim_interface
*pim_ifp
= ifp
->info
;
7525 uint32_t old_dr_prio
;
7528 vty_out(vty
, "Please enable PIM on interface, first\n");
7529 return CMD_WARNING_CONFIG_FAILED
;
7532 old_dr_prio
= pim_ifp
->pim_dr_priority
;
7534 pim_ifp
->pim_dr_priority
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
7536 if (old_dr_prio
!= pim_ifp
->pim_dr_priority
) {
7537 pim_if_dr_election(ifp
);
7538 pim_hello_restart_now(ifp
);
7544 DEFUN (interface_no_ip_pim_drprio
,
7545 interface_no_ip_pim_drprio_cmd
,
7546 "no ip pim drpriority [(1-4294967295)]",
7550 "Revert the Designated Router Priority to default\n"
7551 "Old Value of the Priority\n")
7553 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7554 struct pim_interface
*pim_ifp
= ifp
->info
;
7557 vty_out(vty
, "Pim not enabled on this interface\n");
7558 return CMD_WARNING_CONFIG_FAILED
;
7561 if (pim_ifp
->pim_dr_priority
!= PIM_DEFAULT_DR_PRIORITY
) {
7562 pim_ifp
->pim_dr_priority
= PIM_DEFAULT_DR_PRIORITY
;
7563 pim_if_dr_election(ifp
);
7564 pim_hello_restart_now(ifp
);
7570 DEFPY_HIDDEN (interface_ip_igmp_query_generate
,
7571 interface_ip_igmp_query_generate_cmd
,
7572 "ip igmp generate-query-once [version (2-3)]",
7575 "Generate igmp general query once\n"
7577 "IGMP version number\n")
7579 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7580 int igmp_version
= 2;
7583 vty_out(vty
, "IGMP/PIM is not enabled on the interface %s\n",
7585 return CMD_WARNING_CONFIG_FAILED
;
7589 igmp_version
= atoi(argv
[4]->arg
);
7591 igmp_send_query_on_intf(ifp
, igmp_version
);
7596 static int pim_cmd_interface_add(struct interface
*ifp
)
7598 struct pim_interface
*pim_ifp
= ifp
->info
;
7601 pim_ifp
= pim_if_new(ifp
, false, true, false, false);
7603 PIM_IF_DO_PIM(pim_ifp
->options
);
7605 pim_if_addr_add_all(ifp
);
7606 pim_if_membership_refresh(ifp
);
7608 pim_if_create_pimreg(pim_ifp
->pim
);
7612 DEFPY_HIDDEN (pim_test_sg_keepalive
,
7613 pim_test_sg_keepalive_cmd
,
7614 "test pim [vrf NAME$name] keepalive-reset A.B.C.D$source A.B.C.D$group",
7618 "Reset the Keepalive Timer\n"
7619 "The Source we are resetting\n"
7620 "The Group we are resetting\n")
7622 struct pim_upstream
*up
;
7623 struct pim_instance
*pim
;
7624 struct prefix_sg sg
;
7630 pim
= pim_get_pim_instance(VRF_DEFAULT
);
7632 struct vrf
*vrf
= vrf_lookup_by_name(name
);
7635 vty_out(vty
, "%% Vrf specified: %s does not exist\n",
7640 pim
= pim_get_pim_instance(vrf
->vrf_id
);
7644 vty_out(vty
, "%% Unable to find pim instance\n");
7648 up
= pim_upstream_find(pim
, &sg
);
7650 vty_out(vty
, "%% Unable to find %s specified\n",
7651 pim_str_sg_dump(&sg
));
7655 vty_out(vty
, "Setting %s to current keep alive time: %d\n",
7656 pim_str_sg_dump(&sg
), pim
->keep_alive_time
);
7657 pim_upstream_keep_alive_timer_start(up
, pim
->keep_alive_time
);
7662 DEFPY_HIDDEN (interface_ip_pim_activeactive
,
7663 interface_ip_pim_activeactive_cmd
,
7664 "[no$no] ip pim active-active",
7668 "Mark interface as Active-Active for MLAG operations, Hidden because not finished yet\n")
7670 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7671 struct pim_interface
*pim_ifp
;
7673 if (!no
&& !pim_cmd_interface_add(ifp
)) {
7674 vty_out(vty
, "Could not enable PIM SM active-active on interface\n");
7675 return CMD_WARNING_CONFIG_FAILED
;
7678 pim_ifp
= ifp
->info
;
7680 pim_if_unconfigure_mlag_dualactive(pim_ifp
);
7682 pim_if_configure_mlag_dualactive(pim_ifp
);
7687 DEFUN_HIDDEN (interface_ip_pim_ssm
,
7688 interface_ip_pim_ssm_cmd
,
7694 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7696 if (!pim_cmd_interface_add(ifp
)) {
7697 vty_out(vty
, "Could not enable PIM SM on interface\n");
7698 return CMD_WARNING_CONFIG_FAILED
;
7702 "WARN: Enabled PIM SM on interface; configure PIM SSM "
7703 "range if needed\n");
7707 static int interface_ip_pim_helper(struct vty
*vty
)
7709 struct pim_interface
*pim_ifp
;
7711 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7713 if (!pim_cmd_interface_add(ifp
)) {
7714 vty_out(vty
, "Could not enable PIM SM on interface\n");
7715 return CMD_WARNING_CONFIG_FAILED
;
7718 pim_ifp
= ifp
->info
;
7720 pim_if_create_pimreg(pim_ifp
->pim
);
7725 DEFUN_HIDDEN (interface_ip_pim_sm
,
7726 interface_ip_pim_sm_cmd
,
7732 return interface_ip_pim_helper(vty
);
7735 DEFUN (interface_ip_pim
,
7736 interface_ip_pim_cmd
,
7741 return interface_ip_pim_helper(vty
);
7744 static int pim_cmd_interface_delete(struct interface
*ifp
)
7746 struct pim_interface
*pim_ifp
= ifp
->info
;
7751 PIM_IF_DONT_PIM(pim_ifp
->options
);
7753 pim_if_membership_clear(ifp
);
7756 pim_sock_delete() removes all neighbors from
7757 pim_ifp->pim_neighbor_list.
7759 pim_sock_delete(ifp
, "pim unconfigured on interface");
7761 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
7762 pim_if_addr_del_all(ifp
);
7769 static int interface_no_ip_pim_helper(struct vty
*vty
)
7771 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7772 if (!pim_cmd_interface_delete(ifp
)) {
7773 vty_out(vty
, "Unable to delete interface information\n");
7774 return CMD_WARNING_CONFIG_FAILED
;
7780 DEFUN_HIDDEN (interface_no_ip_pim_ssm
,
7781 interface_no_ip_pim_ssm_cmd
,
7788 return interface_no_ip_pim_helper(vty
);
7791 DEFUN_HIDDEN (interface_no_ip_pim_sm
,
7792 interface_no_ip_pim_sm_cmd
,
7799 return interface_no_ip_pim_helper(vty
);
7802 DEFUN (interface_no_ip_pim
,
7803 interface_no_ip_pim_cmd
,
7809 return interface_no_ip_pim_helper(vty
);
7813 DEFUN(interface_ip_pim_boundary_oil
,
7814 interface_ip_pim_boundary_oil_cmd
,
7815 "ip multicast boundary oil WORD",
7817 "Generic multicast configuration options\n"
7818 "Define multicast boundary\n"
7819 "Filter OIL by group using prefix list\n"
7820 "Prefix list to filter OIL with\n")
7822 VTY_DECLVAR_CONTEXT(interface
, iif
);
7823 struct pim_interface
*pim_ifp
;
7826 argv_find(argv
, argc
, "WORD", &idx
);
7828 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
7830 if (pim_ifp
->boundary_oil_plist
)
7831 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
7833 pim_ifp
->boundary_oil_plist
=
7834 XSTRDUP(MTYPE_PIM_INTERFACE
, argv
[idx
]->arg
);
7836 /* Interface will be pruned from OIL on next Join */
7840 DEFUN(interface_no_ip_pim_boundary_oil
,
7841 interface_no_ip_pim_boundary_oil_cmd
,
7842 "no ip multicast boundary oil [WORD]",
7845 "Generic multicast configuration options\n"
7846 "Define multicast boundary\n"
7847 "Filter OIL by group using prefix list\n"
7848 "Prefix list to filter OIL with\n")
7850 VTY_DECLVAR_CONTEXT(interface
, iif
);
7851 struct pim_interface
*pim_ifp
;
7854 argv_find(argv
, argc
, "WORD", &idx
);
7856 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
7858 if (pim_ifp
->boundary_oil_plist
)
7859 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
7864 DEFUN (interface_ip_mroute
,
7865 interface_ip_mroute_cmd
,
7866 "ip mroute INTERFACE A.B.C.D [A.B.C.D]",
7868 "Add multicast route\n"
7869 "Outgoing interface name\n"
7873 VTY_DECLVAR_CONTEXT(interface
, iif
);
7874 struct pim_interface
*pim_ifp
;
7875 struct pim_instance
*pim
;
7876 int idx_interface
= 2;
7878 struct interface
*oif
;
7879 const char *oifname
;
7880 const char *grp_str
;
7881 struct in_addr grp_addr
;
7882 const char *src_str
;
7883 struct in_addr src_addr
;
7886 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
7889 oifname
= argv
[idx_interface
]->arg
;
7890 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
7892 vty_out(vty
, "No such interface name %s\n", oifname
);
7896 grp_str
= argv
[idx_ipv4
]->arg
;
7897 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
7899 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
7900 errno
, safe_strerror(errno
));
7904 if (argc
== (idx_ipv4
+ 1)) {
7905 src_addr
.s_addr
= INADDR_ANY
;
7908 src_str
= argv
[idx_ipv4
+ 1]->arg
;
7909 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
7911 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
7912 errno
, safe_strerror(errno
));
7917 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
7918 vty_out(vty
, "Failed to add static mroute\n");
7925 DEFUN (interface_no_ip_mroute
,
7926 interface_no_ip_mroute_cmd
,
7927 "no ip mroute INTERFACE A.B.C.D [A.B.C.D]",
7930 "Add multicast route\n"
7931 "Outgoing interface name\n"
7935 VTY_DECLVAR_CONTEXT(interface
, iif
);
7936 struct pim_interface
*pim_ifp
;
7937 struct pim_instance
*pim
;
7938 int idx_interface
= 3;
7940 struct interface
*oif
;
7941 const char *oifname
;
7942 const char *grp_str
;
7943 struct in_addr grp_addr
;
7944 const char *src_str
;
7945 struct in_addr src_addr
;
7948 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
7951 oifname
= argv
[idx_interface
]->arg
;
7952 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
7954 vty_out(vty
, "No such interface name %s\n", oifname
);
7958 grp_str
= argv
[idx_ipv4
]->arg
;
7959 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
7961 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
7962 errno
, safe_strerror(errno
));
7966 if (argc
== (idx_ipv4
+ 1)) {
7967 src_addr
.s_addr
= INADDR_ANY
;
7970 src_str
= argv
[idx_ipv4
+ 1]->arg
;
7971 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
7973 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
7974 errno
, safe_strerror(errno
));
7979 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
7980 vty_out(vty
, "Failed to remove static mroute\n");
7987 DEFUN (interface_ip_pim_hello
,
7988 interface_ip_pim_hello_cmd
,
7989 "ip pim hello (1-180) [(1-180)]",
7993 IFACE_PIM_HELLO_TIME_STR
7994 IFACE_PIM_HELLO_HOLD_STR
)
7996 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7999 struct pim_interface
*pim_ifp
= ifp
->info
;
8002 if (!pim_cmd_interface_add(ifp
)) {
8003 vty_out(vty
, "Could not enable PIM SM on interface\n");
8004 return CMD_WARNING_CONFIG_FAILED
;
8008 pim_ifp
= ifp
->info
;
8009 pim_ifp
->pim_hello_period
= strtol(argv
[idx_time
]->arg
, NULL
, 10);
8011 if (argc
== idx_hold
+ 1)
8012 pim_ifp
->pim_default_holdtime
=
8013 strtol(argv
[idx_hold
]->arg
, NULL
, 10);
8018 DEFUN (interface_no_ip_pim_hello
,
8019 interface_no_ip_pim_hello_cmd
,
8020 "no ip pim hello [(1-180) (1-180)]",
8025 IFACE_PIM_HELLO_TIME_STR
8026 IFACE_PIM_HELLO_HOLD_STR
)
8028 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8029 struct pim_interface
*pim_ifp
= ifp
->info
;
8032 vty_out(vty
, "Pim not enabled on this interface\n");
8033 return CMD_WARNING_CONFIG_FAILED
;
8036 pim_ifp
->pim_hello_period
= PIM_DEFAULT_HELLO_PERIOD
;
8037 pim_ifp
->pim_default_holdtime
= -1;
8048 PIM_DO_DEBUG_IGMP_EVENTS
;
8049 PIM_DO_DEBUG_IGMP_PACKETS
;
8050 PIM_DO_DEBUG_IGMP_TRACE
;
8054 DEFUN (no_debug_igmp
,
8061 PIM_DONT_DEBUG_IGMP_EVENTS
;
8062 PIM_DONT_DEBUG_IGMP_PACKETS
;
8063 PIM_DONT_DEBUG_IGMP_TRACE
;
8068 DEFUN (debug_igmp_events
,
8069 debug_igmp_events_cmd
,
8070 "debug igmp events",
8073 DEBUG_IGMP_EVENTS_STR
)
8075 PIM_DO_DEBUG_IGMP_EVENTS
;
8079 DEFUN (no_debug_igmp_events
,
8080 no_debug_igmp_events_cmd
,
8081 "no debug igmp events",
8085 DEBUG_IGMP_EVENTS_STR
)
8087 PIM_DONT_DEBUG_IGMP_EVENTS
;
8092 DEFUN (debug_igmp_packets
,
8093 debug_igmp_packets_cmd
,
8094 "debug igmp packets",
8097 DEBUG_IGMP_PACKETS_STR
)
8099 PIM_DO_DEBUG_IGMP_PACKETS
;
8103 DEFUN (no_debug_igmp_packets
,
8104 no_debug_igmp_packets_cmd
,
8105 "no debug igmp packets",
8109 DEBUG_IGMP_PACKETS_STR
)
8111 PIM_DONT_DEBUG_IGMP_PACKETS
;
8116 DEFUN (debug_igmp_trace
,
8117 debug_igmp_trace_cmd
,
8121 DEBUG_IGMP_TRACE_STR
)
8123 PIM_DO_DEBUG_IGMP_TRACE
;
8127 DEFUN (no_debug_igmp_trace
,
8128 no_debug_igmp_trace_cmd
,
8129 "no debug igmp trace",
8133 DEBUG_IGMP_TRACE_STR
)
8135 PIM_DONT_DEBUG_IGMP_TRACE
;
8140 DEFUN (debug_mroute
,
8146 PIM_DO_DEBUG_MROUTE
;
8150 DEFUN (debug_mroute_detail
,
8151 debug_mroute_detail_cmd
,
8152 "debug mroute detail",
8157 PIM_DO_DEBUG_MROUTE_DETAIL
;
8161 DEFUN (no_debug_mroute
,
8162 no_debug_mroute_cmd
,
8168 PIM_DONT_DEBUG_MROUTE
;
8172 DEFUN (no_debug_mroute_detail
,
8173 no_debug_mroute_detail_cmd
,
8174 "no debug mroute detail",
8180 PIM_DONT_DEBUG_MROUTE_DETAIL
;
8184 DEFUN (debug_pim_static
,
8185 debug_pim_static_cmd
,
8191 PIM_DO_DEBUG_STATIC
;
8195 DEFUN (no_debug_pim_static
,
8196 no_debug_pim_static_cmd
,
8197 "no debug pim static",
8203 PIM_DONT_DEBUG_STATIC
;
8214 PIM_DO_DEBUG_PIM_EVENTS
;
8215 PIM_DO_DEBUG_PIM_PACKETS
;
8216 PIM_DO_DEBUG_PIM_TRACE
;
8217 PIM_DO_DEBUG_MSDP_EVENTS
;
8218 PIM_DO_DEBUG_MSDP_PACKETS
;
8223 DEFUN (no_debug_pim
,
8230 PIM_DONT_DEBUG_PIM_EVENTS
;
8231 PIM_DONT_DEBUG_PIM_PACKETS
;
8232 PIM_DONT_DEBUG_PIM_TRACE
;
8233 PIM_DONT_DEBUG_MSDP_EVENTS
;
8234 PIM_DONT_DEBUG_MSDP_PACKETS
;
8236 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
8237 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
8243 DEFUN (debug_pim_nht
,
8248 "Nexthop Tracking\n")
8250 PIM_DO_DEBUG_PIM_NHT
;
8254 DEFUN (no_debug_pim_nht
,
8255 no_debug_pim_nht_cmd
,
8260 "Nexthop Tracking\n")
8262 PIM_DONT_DEBUG_PIM_NHT
;
8266 DEFUN (debug_pim_nht_rp
,
8267 debug_pim_nht_rp_cmd
,
8271 "Nexthop Tracking\n"
8272 "RP Nexthop Tracking\n")
8274 PIM_DO_DEBUG_PIM_NHT_RP
;
8278 DEFUN (no_debug_pim_nht_rp
,
8279 no_debug_pim_nht_rp_cmd
,
8280 "no debug pim nht rp",
8284 "Nexthop Tracking\n"
8285 "RP Nexthop Tracking\n")
8287 PIM_DONT_DEBUG_PIM_NHT_RP
;
8291 DEFUN (debug_pim_events
,
8292 debug_pim_events_cmd
,
8296 DEBUG_PIM_EVENTS_STR
)
8298 PIM_DO_DEBUG_PIM_EVENTS
;
8302 DEFUN (no_debug_pim_events
,
8303 no_debug_pim_events_cmd
,
8304 "no debug pim events",
8308 DEBUG_PIM_EVENTS_STR
)
8310 PIM_DONT_DEBUG_PIM_EVENTS
;
8314 DEFUN (debug_pim_packets
,
8315 debug_pim_packets_cmd
,
8316 "debug pim packets [<hello|joins|register>]",
8319 DEBUG_PIM_PACKETS_STR
8320 DEBUG_PIM_HELLO_PACKETS_STR
8321 DEBUG_PIM_J_P_PACKETS_STR
8322 DEBUG_PIM_PIM_REG_PACKETS_STR
)
8325 if (argv_find(argv
, argc
, "hello", &idx
)) {
8326 PIM_DO_DEBUG_PIM_HELLO
;
8327 vty_out(vty
, "PIM Hello debugging is on\n");
8328 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
8329 PIM_DO_DEBUG_PIM_J_P
;
8330 vty_out(vty
, "PIM Join/Prune debugging is on\n");
8331 } else if (argv_find(argv
, argc
, "register", &idx
)) {
8332 PIM_DO_DEBUG_PIM_REG
;
8333 vty_out(vty
, "PIM Register debugging is on\n");
8335 PIM_DO_DEBUG_PIM_PACKETS
;
8336 vty_out(vty
, "PIM Packet debugging is on \n");
8341 DEFUN (no_debug_pim_packets
,
8342 no_debug_pim_packets_cmd
,
8343 "no debug pim packets [<hello|joins|register>]",
8347 DEBUG_PIM_PACKETS_STR
8348 DEBUG_PIM_HELLO_PACKETS_STR
8349 DEBUG_PIM_J_P_PACKETS_STR
8350 DEBUG_PIM_PIM_REG_PACKETS_STR
)
8353 if (argv_find(argv
, argc
, "hello", &idx
)) {
8354 PIM_DONT_DEBUG_PIM_HELLO
;
8355 vty_out(vty
, "PIM Hello debugging is off \n");
8356 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
8357 PIM_DONT_DEBUG_PIM_J_P
;
8358 vty_out(vty
, "PIM Join/Prune debugging is off \n");
8359 } else if (argv_find(argv
, argc
, "register", &idx
)) {
8360 PIM_DONT_DEBUG_PIM_REG
;
8361 vty_out(vty
, "PIM Register debugging is off\n");
8363 PIM_DONT_DEBUG_PIM_PACKETS
;
8369 DEFUN (debug_pim_packetdump_send
,
8370 debug_pim_packetdump_send_cmd
,
8371 "debug pim packet-dump send",
8374 DEBUG_PIM_PACKETDUMP_STR
8375 DEBUG_PIM_PACKETDUMP_SEND_STR
)
8377 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND
;
8381 DEFUN (no_debug_pim_packetdump_send
,
8382 no_debug_pim_packetdump_send_cmd
,
8383 "no debug pim packet-dump send",
8387 DEBUG_PIM_PACKETDUMP_STR
8388 DEBUG_PIM_PACKETDUMP_SEND_STR
)
8390 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
8394 DEFUN (debug_pim_packetdump_recv
,
8395 debug_pim_packetdump_recv_cmd
,
8396 "debug pim packet-dump receive",
8399 DEBUG_PIM_PACKETDUMP_STR
8400 DEBUG_PIM_PACKETDUMP_RECV_STR
)
8402 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV
;
8406 DEFUN (no_debug_pim_packetdump_recv
,
8407 no_debug_pim_packetdump_recv_cmd
,
8408 "no debug pim packet-dump receive",
8412 DEBUG_PIM_PACKETDUMP_STR
8413 DEBUG_PIM_PACKETDUMP_RECV_STR
)
8415 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
8419 DEFUN (debug_pim_trace
,
8420 debug_pim_trace_cmd
,
8424 DEBUG_PIM_TRACE_STR
)
8426 PIM_DO_DEBUG_PIM_TRACE
;
8430 DEFUN (debug_pim_trace_detail
,
8431 debug_pim_trace_detail_cmd
,
8432 "debug pim trace detail",
8436 "Detailed Information\n")
8438 PIM_DO_DEBUG_PIM_TRACE_DETAIL
;
8442 DEFUN (no_debug_pim_trace
,
8443 no_debug_pim_trace_cmd
,
8444 "no debug pim trace",
8448 DEBUG_PIM_TRACE_STR
)
8450 PIM_DONT_DEBUG_PIM_TRACE
;
8454 DEFUN (no_debug_pim_trace_detail
,
8455 no_debug_pim_trace_detail_cmd
,
8456 "no debug pim trace detail",
8461 "Detailed Information\n")
8463 PIM_DONT_DEBUG_PIM_TRACE_DETAIL
;
8467 DEFUN (debug_ssmpingd
,
8473 PIM_DO_DEBUG_SSMPINGD
;
8477 DEFUN (no_debug_ssmpingd
,
8478 no_debug_ssmpingd_cmd
,
8479 "no debug ssmpingd",
8484 PIM_DONT_DEBUG_SSMPINGD
;
8488 DEFUN (debug_pim_zebra
,
8489 debug_pim_zebra_cmd
,
8493 DEBUG_PIM_ZEBRA_STR
)
8499 DEFUN (no_debug_pim_zebra
,
8500 no_debug_pim_zebra_cmd
,
8501 "no debug pim zebra",
8505 DEBUG_PIM_ZEBRA_STR
)
8507 PIM_DONT_DEBUG_ZEBRA
;
8511 DEFUN(debug_pim_mlag
, debug_pim_mlag_cmd
, "debug pim mlag",
8512 DEBUG_STR DEBUG_PIM_STR DEBUG_PIM_MLAG_STR
)
8518 DEFUN(no_debug_pim_mlag
, no_debug_pim_mlag_cmd
, "no debug pim mlag",
8519 NO_STR DEBUG_STR DEBUG_PIM_STR DEBUG_PIM_MLAG_STR
)
8521 PIM_DONT_DEBUG_MLAG
;
8525 DEFUN (debug_pim_vxlan
,
8526 debug_pim_vxlan_cmd
,
8530 DEBUG_PIM_VXLAN_STR
)
8536 DEFUN (no_debug_pim_vxlan
,
8537 no_debug_pim_vxlan_cmd
,
8538 "no debug pim vxlan",
8542 DEBUG_PIM_VXLAN_STR
)
8544 PIM_DONT_DEBUG_VXLAN
;
8554 PIM_DO_DEBUG_MSDP_EVENTS
;
8555 PIM_DO_DEBUG_MSDP_PACKETS
;
8559 DEFUN (no_debug_msdp
,
8566 PIM_DONT_DEBUG_MSDP_EVENTS
;
8567 PIM_DONT_DEBUG_MSDP_PACKETS
;
8571 DEFUN (debug_msdp_events
,
8572 debug_msdp_events_cmd
,
8573 "debug msdp events",
8576 DEBUG_MSDP_EVENTS_STR
)
8578 PIM_DO_DEBUG_MSDP_EVENTS
;
8582 DEFUN (no_debug_msdp_events
,
8583 no_debug_msdp_events_cmd
,
8584 "no debug msdp events",
8588 DEBUG_MSDP_EVENTS_STR
)
8590 PIM_DONT_DEBUG_MSDP_EVENTS
;
8594 DEFUN (debug_msdp_packets
,
8595 debug_msdp_packets_cmd
,
8596 "debug msdp packets",
8599 DEBUG_MSDP_PACKETS_STR
)
8601 PIM_DO_DEBUG_MSDP_PACKETS
;
8605 DEFUN (no_debug_msdp_packets
,
8606 no_debug_msdp_packets_cmd
,
8607 "no debug msdp packets",
8611 DEBUG_MSDP_PACKETS_STR
)
8613 PIM_DONT_DEBUG_MSDP_PACKETS
;
8617 DEFUN (debug_mtrace
,
8623 PIM_DO_DEBUG_MTRACE
;
8627 DEFUN (no_debug_mtrace
,
8628 no_debug_mtrace_cmd
,
8634 PIM_DONT_DEBUG_MTRACE
;
8649 DEFUN (no_debug_bsm
,
8662 DEFUN_NOSH (show_debugging_pim
,
8663 show_debugging_pim_cmd
,
8664 "show debugging [pim]",
8669 vty_out(vty
, "PIM debugging status\n");
8671 pim_debug_config_write(vty
);
8676 static int interface_pim_use_src_cmd_worker(struct vty
*vty
, const char *source
)
8679 struct in_addr source_addr
;
8680 int ret
= CMD_SUCCESS
;
8681 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8683 result
= inet_pton(AF_INET
, source
, &source_addr
);
8685 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", source
,
8686 errno
, safe_strerror(errno
));
8687 return CMD_WARNING_CONFIG_FAILED
;
8690 result
= pim_update_source_set(ifp
, source_addr
);
8694 case PIM_IFACE_NOT_FOUND
:
8695 ret
= CMD_WARNING_CONFIG_FAILED
;
8696 vty_out(vty
, "Pim not enabled on this interface\n");
8698 case PIM_UPDATE_SOURCE_DUP
:
8700 vty_out(vty
, "%% Source already set to %s\n", source
);
8703 ret
= CMD_WARNING_CONFIG_FAILED
;
8704 vty_out(vty
, "%% Source set failed\n");
8710 DEFUN (interface_pim_use_source
,
8711 interface_pim_use_source_cmd
,
8712 "ip pim use-source A.B.C.D",
8715 "Configure primary IP address\n"
8716 "source ip address\n")
8718 return interface_pim_use_src_cmd_worker(vty
, argv
[3]->arg
);
8721 DEFUN (interface_no_pim_use_source
,
8722 interface_no_pim_use_source_cmd
,
8723 "no ip pim use-source [A.B.C.D]",
8727 "Delete source IP address\n"
8728 "source ip address\n")
8730 return interface_pim_use_src_cmd_worker(vty
, "0.0.0.0");
8738 "Enables BFD support\n")
8740 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8741 struct pim_interface
*pim_ifp
= ifp
->info
;
8742 struct bfd_info
*bfd_info
= NULL
;
8745 if (!pim_cmd_interface_add(ifp
)) {
8746 vty_out(vty
, "Could not enable PIM SM on interface\n");
8750 pim_ifp
= ifp
->info
;
8752 bfd_info
= pim_ifp
->bfd_info
;
8754 if (!bfd_info
|| !CHECK_FLAG(bfd_info
->flags
, BFD_FLAG_PARAM_CFG
))
8755 pim_bfd_if_param_set(ifp
, BFD_DEF_MIN_RX
, BFD_DEF_MIN_TX
,
8756 BFD_DEF_DETECT_MULT
, 1);
8761 DEFUN (no_ip_pim_bfd
,
8767 "Disables BFD support\n")
8769 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8770 struct pim_interface
*pim_ifp
= ifp
->info
;
8773 vty_out(vty
, "Pim not enabled on this interface\n");
8777 if (pim_ifp
->bfd_info
) {
8778 pim_bfd_reg_dereg_all_nbr(ifp
, ZEBRA_BFD_DEST_DEREGISTER
);
8779 bfd_info_free(&(pim_ifp
->bfd_info
));
8790 "Enables BSM support on the interface\n")
8792 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8793 struct pim_interface
*pim_ifp
= ifp
->info
;
8796 if (!pim_cmd_interface_add(ifp
)) {
8797 vty_out(vty
, "Could not enable PIM SM on interface\n");
8802 pim_ifp
= ifp
->info
;
8803 pim_ifp
->bsm_enable
= true;
8808 DEFUN (no_ip_pim_bsm
,
8814 "Disables BSM support\n")
8816 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8817 struct pim_interface
*pim_ifp
= ifp
->info
;
8820 vty_out(vty
, "Pim not enabled on this interface\n");
8824 pim_ifp
->bsm_enable
= false;
8829 DEFUN (ip_pim_ucast_bsm
,
8830 ip_pim_ucast_bsm_cmd
,
8831 "ip pim unicast-bsm",
8834 "Accept/Send unicast BSM on the interface\n")
8836 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8837 struct pim_interface
*pim_ifp
= ifp
->info
;
8840 if (!pim_cmd_interface_add(ifp
)) {
8841 vty_out(vty
, "Could not enable PIM SM on interface\n");
8846 pim_ifp
= ifp
->info
;
8847 pim_ifp
->ucast_bsm_accept
= true;
8852 DEFUN (no_ip_pim_ucast_bsm
,
8853 no_ip_pim_ucast_bsm_cmd
,
8854 "no ip pim unicast-bsm",
8858 "Block send/receive unicast BSM on this interface\n")
8860 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8861 struct pim_interface
*pim_ifp
= ifp
->info
;
8864 vty_out(vty
, "Pim not enabled on this interface\n");
8868 pim_ifp
->ucast_bsm_accept
= false;
8876 ip_pim_bfd_param_cmd
,
8877 "ip pim bfd (2-255) (50-60000) (50-60000)",
8880 "Enables BFD support\n"
8881 "Detect Multiplier\n"
8882 "Required min receive interval\n"
8883 "Desired min transmit interval\n")
8887 ip_pim_bfd_param_cmd
,
8888 "ip pim bfd (2-255) (50-60000) (50-60000)",
8891 "Enables BFD support\n"
8892 "Detect Multiplier\n"
8893 "Required min receive interval\n"
8894 "Desired min transmit interval\n")
8895 #endif /* HAVE_BFDD */
8897 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8899 int idx_number_2
= 4;
8900 int idx_number_3
= 5;
8905 struct pim_interface
*pim_ifp
= ifp
->info
;
8908 if (!pim_cmd_interface_add(ifp
)) {
8909 vty_out(vty
, "Could not enable PIM SM on interface\n");
8914 if ((ret
= bfd_validate_param(
8915 vty
, argv
[idx_number
]->arg
, argv
[idx_number_2
]->arg
,
8916 argv
[idx_number_3
]->arg
, &dm_val
, &rx_val
, &tx_val
))
8920 pim_bfd_if_param_set(ifp
, rx_val
, tx_val
, dm_val
, 0);
8926 ALIAS(no_ip_pim_bfd
, no_ip_pim_bfd_param_cmd
,
8927 "no ip pim bfd (2-255) (50-60000) (50-60000)", NO_STR IP_STR PIM_STR
8928 "Enables BFD support\n"
8929 "Detect Multiplier\n"
8930 "Required min receive interval\n"
8931 "Desired min transmit interval\n")
8932 #endif /* !HAVE_BFDD */
8934 static int ip_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
8935 const char *peer
, const char *local
)
8937 enum pim_msdp_err result
;
8938 struct in_addr peer_addr
;
8939 struct in_addr local_addr
;
8940 int ret
= CMD_SUCCESS
;
8942 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
8944 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
8945 errno
, safe_strerror(errno
));
8946 return CMD_WARNING_CONFIG_FAILED
;
8949 result
= inet_pton(AF_INET
, local
, &local_addr
);
8951 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", local
,
8952 errno
, safe_strerror(errno
));
8953 return CMD_WARNING_CONFIG_FAILED
;
8956 result
= pim_msdp_peer_add(pim
, peer_addr
, local_addr
, "default",
8959 case PIM_MSDP_ERR_NONE
:
8961 case PIM_MSDP_ERR_OOM
:
8962 ret
= CMD_WARNING_CONFIG_FAILED
;
8963 vty_out(vty
, "%% Out of memory\n");
8965 case PIM_MSDP_ERR_PEER_EXISTS
:
8967 vty_out(vty
, "%% Peer exists\n");
8969 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
8970 ret
= CMD_WARNING_CONFIG_FAILED
;
8971 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
8974 ret
= CMD_WARNING_CONFIG_FAILED
;
8975 vty_out(vty
, "%% peer add failed\n");
8981 DEFUN_HIDDEN (ip_msdp_peer
,
8983 "ip msdp peer A.B.C.D source A.B.C.D",
8986 "Configure MSDP peer\n"
8988 "Source address for TCP connection\n"
8989 "local ip address\n")
8991 PIM_DECLVAR_CONTEXT(vrf
, pim
);
8992 return ip_msdp_peer_cmd_worker(pim
, vty
, argv
[3]->arg
, argv
[5]->arg
);
8995 static int ip_no_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
8998 enum pim_msdp_err result
;
8999 struct in_addr peer_addr
;
9001 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
9003 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
9004 errno
, safe_strerror(errno
));
9005 return CMD_WARNING_CONFIG_FAILED
;
9008 result
= pim_msdp_peer_del(pim
, peer_addr
);
9010 case PIM_MSDP_ERR_NONE
:
9012 case PIM_MSDP_ERR_NO_PEER
:
9013 vty_out(vty
, "%% Peer does not exist\n");
9016 vty_out(vty
, "%% peer del failed\n");
9019 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9022 DEFUN_HIDDEN (no_ip_msdp_peer
,
9023 no_ip_msdp_peer_cmd
,
9024 "no ip msdp peer A.B.C.D",
9028 "Delete MSDP peer\n"
9029 "peer ip address\n")
9031 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9032 return ip_no_msdp_peer_cmd_worker(pim
, vty
, argv
[4]->arg
);
9035 static int ip_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
9036 struct vty
*vty
, const char *mg
,
9039 enum pim_msdp_err result
;
9040 struct in_addr mbr_ip
;
9041 int ret
= CMD_SUCCESS
;
9043 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
9045 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
9046 errno
, safe_strerror(errno
));
9047 return CMD_WARNING_CONFIG_FAILED
;
9050 result
= pim_msdp_mg_mbr_add(pim
, mg
, mbr_ip
);
9052 case PIM_MSDP_ERR_NONE
:
9054 case PIM_MSDP_ERR_OOM
:
9055 ret
= CMD_WARNING_CONFIG_FAILED
;
9056 vty_out(vty
, "%% Out of memory\n");
9058 case PIM_MSDP_ERR_MG_MBR_EXISTS
:
9060 vty_out(vty
, "%% mesh-group member exists\n");
9062 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
9063 ret
= CMD_WARNING_CONFIG_FAILED
;
9064 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
9067 ret
= CMD_WARNING_CONFIG_FAILED
;
9068 vty_out(vty
, "%% member add failed\n");
9074 DEFUN (ip_msdp_mesh_group_member
,
9075 ip_msdp_mesh_group_member_cmd
,
9076 "ip msdp mesh-group WORD member A.B.C.D",
9079 "Configure MSDP mesh-group\n"
9081 "mesh group member\n"
9082 "peer ip address\n")
9084 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9085 return ip_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[3]->arg
,
9089 static int ip_no_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
9094 enum pim_msdp_err result
;
9095 struct in_addr mbr_ip
;
9097 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
9099 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
9100 errno
, safe_strerror(errno
));
9101 return CMD_WARNING_CONFIG_FAILED
;
9104 result
= pim_msdp_mg_mbr_del(pim
, mg
, mbr_ip
);
9106 case PIM_MSDP_ERR_NONE
:
9108 case PIM_MSDP_ERR_NO_MG
:
9109 vty_out(vty
, "%% mesh-group does not exist\n");
9111 case PIM_MSDP_ERR_NO_MG_MBR
:
9112 vty_out(vty
, "%% mesh-group member does not exist\n");
9115 vty_out(vty
, "%% mesh-group member del failed\n");
9118 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9120 DEFUN (no_ip_msdp_mesh_group_member
,
9121 no_ip_msdp_mesh_group_member_cmd
,
9122 "no ip msdp mesh-group WORD member A.B.C.D",
9126 "Delete MSDP mesh-group member\n"
9128 "mesh group member\n"
9129 "peer ip address\n")
9131 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9132 return ip_no_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[4]->arg
,
9136 static int ip_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
9137 struct vty
*vty
, const char *mg
,
9140 enum pim_msdp_err result
;
9141 struct in_addr src_ip
;
9143 result
= inet_pton(AF_INET
, src
, &src_ip
);
9145 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", src
,
9146 errno
, safe_strerror(errno
));
9147 return CMD_WARNING_CONFIG_FAILED
;
9150 result
= pim_msdp_mg_src_add(pim
, mg
, src_ip
);
9152 case PIM_MSDP_ERR_NONE
:
9154 case PIM_MSDP_ERR_OOM
:
9155 vty_out(vty
, "%% Out of memory\n");
9157 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
9158 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
9161 vty_out(vty
, "%% source add failed\n");
9164 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9168 DEFUN (ip_msdp_mesh_group_source
,
9169 ip_msdp_mesh_group_source_cmd
,
9170 "ip msdp mesh-group WORD source A.B.C.D",
9173 "Configure MSDP mesh-group\n"
9175 "mesh group local address\n"
9176 "source ip address for the TCP connection\n")
9178 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9179 return ip_msdp_mesh_group_source_cmd_worker(pim
, vty
, argv
[3]->arg
,
9183 static int ip_no_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
9187 enum pim_msdp_err result
;
9189 result
= pim_msdp_mg_src_del(pim
, mg
);
9191 case PIM_MSDP_ERR_NONE
:
9193 case PIM_MSDP_ERR_NO_MG
:
9194 vty_out(vty
, "%% mesh-group does not exist\n");
9197 vty_out(vty
, "%% mesh-group source del failed\n");
9200 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9203 static int ip_no_msdp_mesh_group_cmd_worker(struct pim_instance
*pim
,
9204 struct vty
*vty
, const char *mg
)
9206 enum pim_msdp_err result
;
9208 result
= pim_msdp_mg_del(pim
, mg
);
9210 case PIM_MSDP_ERR_NONE
:
9212 case PIM_MSDP_ERR_NO_MG
:
9213 vty_out(vty
, "%% mesh-group does not exist\n");
9216 vty_out(vty
, "%% mesh-group source del failed\n");
9219 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9222 DEFUN (no_ip_msdp_mesh_group_source
,
9223 no_ip_msdp_mesh_group_source_cmd
,
9224 "no ip msdp mesh-group WORD source [A.B.C.D]",
9228 "Delete MSDP mesh-group source\n"
9230 "mesh group source\n"
9231 "mesh group local address\n")
9233 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9235 return ip_no_msdp_mesh_group_cmd_worker(pim
, vty
, argv
[6]->arg
);
9237 return ip_no_msdp_mesh_group_source_cmd_worker(pim
, vty
,
9241 static void print_empty_json_obj(struct vty
*vty
)
9244 json
= json_object_new_object();
9245 vty_out(vty
, "%s\n",
9246 json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
));
9247 json_object_free(json
);
9250 static void ip_msdp_show_mesh_group(struct pim_instance
*pim
, struct vty
*vty
,
9253 struct listnode
*mbrnode
;
9254 struct pim_msdp_mg_mbr
*mbr
;
9255 struct pim_msdp_mg
*mg
= pim
->msdp
.mg
;
9256 char mbr_str
[INET_ADDRSTRLEN
];
9257 char src_str
[INET_ADDRSTRLEN
];
9258 char state_str
[PIM_MSDP_STATE_STRLEN
];
9259 enum pim_msdp_peer_state state
;
9260 json_object
*json
= NULL
;
9261 json_object
*json_mg_row
= NULL
;
9262 json_object
*json_members
= NULL
;
9263 json_object
*json_row
= NULL
;
9267 print_empty_json_obj(vty
);
9271 pim_inet4_dump("<source?>", mg
->src_ip
, src_str
, sizeof(src_str
));
9273 json
= json_object_new_object();
9274 /* currently there is only one mesh group but we should still
9276 * it a dict with mg-name as key */
9277 json_mg_row
= json_object_new_object();
9278 json_object_string_add(json_mg_row
, "name",
9279 mg
->mesh_group_name
);
9280 json_object_string_add(json_mg_row
, "source", src_str
);
9282 vty_out(vty
, "Mesh group : %s\n", mg
->mesh_group_name
);
9283 vty_out(vty
, " Source : %s\n", src_str
);
9284 vty_out(vty
, " Member State\n");
9287 for (ALL_LIST_ELEMENTS_RO(mg
->mbr_list
, mbrnode
, mbr
)) {
9288 pim_inet4_dump("<mbr?>", mbr
->mbr_ip
, mbr_str
, sizeof(mbr_str
));
9290 state
= mbr
->mp
->state
;
9292 state
= PIM_MSDP_DISABLED
;
9294 pim_msdp_state_dump(state
, state_str
, sizeof(state_str
));
9296 json_row
= json_object_new_object();
9297 json_object_string_add(json_row
, "member", mbr_str
);
9298 json_object_string_add(json_row
, "state", state_str
);
9299 if (!json_members
) {
9300 json_members
= json_object_new_object();
9301 json_object_object_add(json_mg_row
, "members",
9304 json_object_object_add(json_members
, mbr_str
, json_row
);
9306 vty_out(vty
, " %-15s %11s\n", mbr_str
, state_str
);
9311 json_object_object_add(json
, mg
->mesh_group_name
, json_mg_row
);
9312 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9313 json
, JSON_C_TO_STRING_PRETTY
));
9314 json_object_free(json
);
9318 DEFUN (show_ip_msdp_mesh_group
,
9319 show_ip_msdp_mesh_group_cmd
,
9320 "show ip msdp [vrf NAME] mesh-group [json]",
9325 "MSDP mesh-group information\n"
9328 bool uj
= use_json(argc
, argv
);
9330 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
9335 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
9340 DEFUN (show_ip_msdp_mesh_group_vrf_all
,
9341 show_ip_msdp_mesh_group_vrf_all_cmd
,
9342 "show ip msdp vrf all mesh-group [json]",
9347 "MSDP mesh-group information\n"
9350 bool uj
= use_json(argc
, argv
);
9356 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
9360 vty_out(vty
, " \"%s\": ", vrf
->name
);
9363 vty_out(vty
, "VRF: %s\n", vrf
->name
);
9364 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
9367 vty_out(vty
, "}\n");
9372 static void ip_msdp_show_peers(struct pim_instance
*pim
, struct vty
*vty
,
9375 struct listnode
*mpnode
;
9376 struct pim_msdp_peer
*mp
;
9377 char peer_str
[INET_ADDRSTRLEN
];
9378 char local_str
[INET_ADDRSTRLEN
];
9379 char state_str
[PIM_MSDP_STATE_STRLEN
];
9380 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
9382 json_object
*json
= NULL
;
9383 json_object
*json_row
= NULL
;
9387 json
= json_object_new_object();
9390 "Peer Local State Uptime SaCnt\n");
9393 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
9394 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
9395 now
= pim_time_monotonic_sec();
9396 pim_time_uptime(timebuf
, sizeof(timebuf
),
9399 strlcpy(timebuf
, "-", sizeof(timebuf
));
9401 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
9402 pim_inet4_dump("<local?>", mp
->local
, local_str
,
9404 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
9406 json_row
= json_object_new_object();
9407 json_object_string_add(json_row
, "peer", peer_str
);
9408 json_object_string_add(json_row
, "local", local_str
);
9409 json_object_string_add(json_row
, "state", state_str
);
9410 json_object_string_add(json_row
, "upTime", timebuf
);
9411 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
9412 json_object_object_add(json
, peer_str
, json_row
);
9414 vty_out(vty
, "%-15s %15s %11s %8s %6d\n", peer_str
,
9415 local_str
, state_str
, timebuf
, mp
->sa_cnt
);
9420 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9421 json
, JSON_C_TO_STRING_PRETTY
));
9422 json_object_free(json
);
9426 static void ip_msdp_show_peers_detail(struct pim_instance
*pim
, struct vty
*vty
,
9427 const char *peer
, bool uj
)
9429 struct listnode
*mpnode
;
9430 struct pim_msdp_peer
*mp
;
9431 char peer_str
[INET_ADDRSTRLEN
];
9432 char local_str
[INET_ADDRSTRLEN
];
9433 char state_str
[PIM_MSDP_STATE_STRLEN
];
9434 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
9435 char katimer
[PIM_MSDP_TIMER_STRLEN
];
9436 char crtimer
[PIM_MSDP_TIMER_STRLEN
];
9437 char holdtimer
[PIM_MSDP_TIMER_STRLEN
];
9439 json_object
*json
= NULL
;
9440 json_object
*json_row
= NULL
;
9443 json
= json_object_new_object();
9446 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
9447 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
9448 if (strcmp(peer
, "detail") && strcmp(peer
, peer_str
))
9451 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
9452 now
= pim_time_monotonic_sec();
9453 pim_time_uptime(timebuf
, sizeof(timebuf
),
9456 strlcpy(timebuf
, "-", sizeof(timebuf
));
9458 pim_inet4_dump("<local?>", mp
->local
, local_str
,
9460 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
9461 pim_time_timer_to_hhmmss(katimer
, sizeof(katimer
),
9463 pim_time_timer_to_hhmmss(crtimer
, sizeof(crtimer
),
9465 pim_time_timer_to_hhmmss(holdtimer
, sizeof(holdtimer
),
9469 json_row
= json_object_new_object();
9470 json_object_string_add(json_row
, "peer", peer_str
);
9471 json_object_string_add(json_row
, "local", local_str
);
9472 json_object_string_add(json_row
, "meshGroupName",
9473 mp
->mesh_group_name
);
9474 json_object_string_add(json_row
, "state", state_str
);
9475 json_object_string_add(json_row
, "upTime", timebuf
);
9476 json_object_string_add(json_row
, "keepAliveTimer",
9478 json_object_string_add(json_row
, "connRetryTimer",
9480 json_object_string_add(json_row
, "holdTimer",
9482 json_object_string_add(json_row
, "lastReset",
9484 json_object_int_add(json_row
, "connAttempts",
9486 json_object_int_add(json_row
, "establishedChanges",
9488 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
9489 json_object_int_add(json_row
, "kaSent", mp
->ka_tx_cnt
);
9490 json_object_int_add(json_row
, "kaRcvd", mp
->ka_rx_cnt
);
9491 json_object_int_add(json_row
, "saSent", mp
->sa_tx_cnt
);
9492 json_object_int_add(json_row
, "saRcvd", mp
->sa_rx_cnt
);
9493 json_object_object_add(json
, peer_str
, json_row
);
9495 vty_out(vty
, "Peer : %s\n", peer_str
);
9496 vty_out(vty
, " Local : %s\n", local_str
);
9497 vty_out(vty
, " Mesh Group : %s\n",
9498 mp
->mesh_group_name
);
9499 vty_out(vty
, " State : %s\n", state_str
);
9500 vty_out(vty
, " Uptime : %s\n", timebuf
);
9502 vty_out(vty
, " Keepalive Timer : %s\n", katimer
);
9503 vty_out(vty
, " Conn Retry Timer : %s\n", crtimer
);
9504 vty_out(vty
, " Hold Timer : %s\n", holdtimer
);
9505 vty_out(vty
, " Last Reset : %s\n",
9507 vty_out(vty
, " Conn Attempts : %d\n",
9509 vty_out(vty
, " Established Changes : %d\n",
9511 vty_out(vty
, " SA Count : %d\n",
9513 vty_out(vty
, " Statistics :\n");
9516 vty_out(vty
, " Keepalives : %10d %10d\n",
9517 mp
->ka_tx_cnt
, mp
->ka_rx_cnt
);
9518 vty_out(vty
, " SAs : %10d %10d\n",
9519 mp
->sa_tx_cnt
, mp
->sa_rx_cnt
);
9525 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9526 json
, JSON_C_TO_STRING_PRETTY
));
9527 json_object_free(json
);
9531 DEFUN (show_ip_msdp_peer_detail
,
9532 show_ip_msdp_peer_detail_cmd
,
9533 "show ip msdp [vrf NAME] peer [detail|A.B.C.D] [json]",
9538 "MSDP peer information\n"
9543 bool uj
= use_json(argc
, argv
);
9545 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
9552 if (argv_find(argv
, argc
, "detail", &idx
))
9553 arg
= argv
[idx
]->text
;
9554 else if (argv_find(argv
, argc
, "A.B.C.D", &idx
))
9555 arg
= argv
[idx
]->arg
;
9558 ip_msdp_show_peers_detail(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
9560 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
9565 DEFUN (show_ip_msdp_peer_detail_vrf_all
,
9566 show_ip_msdp_peer_detail_vrf_all_cmd
,
9567 "show ip msdp vrf all peer [detail|A.B.C.D] [json]",
9572 "MSDP peer information\n"
9578 bool uj
= use_json(argc
, argv
);
9584 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
9588 vty_out(vty
, " \"%s\": ", vrf
->name
);
9591 vty_out(vty
, "VRF: %s\n", vrf
->name
);
9592 if (argv_find(argv
, argc
, "detail", &idx
)
9593 || argv_find(argv
, argc
, "A.B.C.D", &idx
))
9594 ip_msdp_show_peers_detail(vrf
->info
, vty
,
9595 argv
[idx
]->arg
, uj
);
9597 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
9600 vty_out(vty
, "}\n");
9605 static void ip_msdp_show_sa(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
9607 struct listnode
*sanode
;
9608 struct pim_msdp_sa
*sa
;
9609 char src_str
[INET_ADDRSTRLEN
];
9610 char grp_str
[INET_ADDRSTRLEN
];
9611 char rp_str
[INET_ADDRSTRLEN
];
9612 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
9616 json_object
*json
= NULL
;
9617 json_object
*json_group
= NULL
;
9618 json_object
*json_row
= NULL
;
9621 json
= json_object_new_object();
9624 "Source Group RP Local SPT Uptime\n");
9627 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
9628 now
= pim_time_monotonic_sec();
9629 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
9630 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
9631 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
9632 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
9633 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
9635 strlcpy(spt_str
, "yes", sizeof(spt_str
));
9637 strlcpy(spt_str
, "no", sizeof(spt_str
));
9640 strlcpy(rp_str
, "-", sizeof(rp_str
));
9641 strlcpy(spt_str
, "-", sizeof(spt_str
));
9643 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
9644 strlcpy(local_str
, "yes", sizeof(local_str
));
9646 strlcpy(local_str
, "no", sizeof(local_str
));
9649 json_object_object_get_ex(json
, grp_str
, &json_group
);
9652 json_group
= json_object_new_object();
9653 json_object_object_add(json
, grp_str
,
9657 json_row
= json_object_new_object();
9658 json_object_string_add(json_row
, "source", src_str
);
9659 json_object_string_add(json_row
, "group", grp_str
);
9660 json_object_string_add(json_row
, "rp", rp_str
);
9661 json_object_string_add(json_row
, "local", local_str
);
9662 json_object_string_add(json_row
, "sptSetup", spt_str
);
9663 json_object_string_add(json_row
, "upTime", timebuf
);
9664 json_object_object_add(json_group
, src_str
, json_row
);
9666 vty_out(vty
, "%-15s %15s %15s %5c %3c %8s\n",
9667 src_str
, grp_str
, rp_str
, local_str
[0],
9668 spt_str
[0], timebuf
);
9673 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9674 json
, JSON_C_TO_STRING_PRETTY
));
9675 json_object_free(json
);
9679 static void ip_msdp_show_sa_entry_detail(struct pim_msdp_sa
*sa
,
9680 const char *src_str
,
9681 const char *grp_str
, struct vty
*vty
,
9682 bool uj
, json_object
*json
)
9684 char rp_str
[INET_ADDRSTRLEN
];
9685 char peer_str
[INET_ADDRSTRLEN
];
9686 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
9689 char statetimer
[PIM_MSDP_TIMER_STRLEN
];
9691 json_object
*json_group
= NULL
;
9692 json_object
*json_row
= NULL
;
9694 now
= pim_time_monotonic_sec();
9695 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
9696 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
9697 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
9698 pim_inet4_dump("<peer?>", sa
->peer
, peer_str
, sizeof(peer_str
));
9700 strlcpy(spt_str
, "yes", sizeof(spt_str
));
9702 strlcpy(spt_str
, "no", sizeof(spt_str
));
9705 strlcpy(rp_str
, "-", sizeof(rp_str
));
9706 strlcpy(peer_str
, "-", sizeof(peer_str
));
9707 strlcpy(spt_str
, "-", sizeof(spt_str
));
9709 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
9710 strlcpy(local_str
, "yes", sizeof(local_str
));
9712 strlcpy(local_str
, "no", sizeof(local_str
));
9714 pim_time_timer_to_hhmmss(statetimer
, sizeof(statetimer
),
9715 sa
->sa_state_timer
);
9717 json_object_object_get_ex(json
, grp_str
, &json_group
);
9720 json_group
= json_object_new_object();
9721 json_object_object_add(json
, grp_str
, json_group
);
9724 json_row
= json_object_new_object();
9725 json_object_string_add(json_row
, "source", src_str
);
9726 json_object_string_add(json_row
, "group", grp_str
);
9727 json_object_string_add(json_row
, "rp", rp_str
);
9728 json_object_string_add(json_row
, "local", local_str
);
9729 json_object_string_add(json_row
, "sptSetup", spt_str
);
9730 json_object_string_add(json_row
, "upTime", timebuf
);
9731 json_object_string_add(json_row
, "stateTimer", statetimer
);
9732 json_object_object_add(json_group
, src_str
, json_row
);
9734 vty_out(vty
, "SA : %s\n", sa
->sg_str
);
9735 vty_out(vty
, " RP : %s\n", rp_str
);
9736 vty_out(vty
, " Peer : %s\n", peer_str
);
9737 vty_out(vty
, " Local : %s\n", local_str
);
9738 vty_out(vty
, " SPT Setup : %s\n", spt_str
);
9739 vty_out(vty
, " Uptime : %s\n", timebuf
);
9740 vty_out(vty
, " State Timer : %s\n", statetimer
);
9745 static void ip_msdp_show_sa_detail(struct pim_instance
*pim
, struct vty
*vty
,
9748 struct listnode
*sanode
;
9749 struct pim_msdp_sa
*sa
;
9750 char src_str
[INET_ADDRSTRLEN
];
9751 char grp_str
[INET_ADDRSTRLEN
];
9752 json_object
*json
= NULL
;
9755 json
= json_object_new_object();
9758 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
9759 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
9760 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
9761 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
, uj
,
9766 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9767 json
, JSON_C_TO_STRING_PRETTY
));
9768 json_object_free(json
);
9772 DEFUN (show_ip_msdp_sa_detail
,
9773 show_ip_msdp_sa_detail_cmd
,
9774 "show ip msdp [vrf NAME] sa detail [json]",
9779 "MSDP active-source information\n"
9783 bool uj
= use_json(argc
, argv
);
9785 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
9790 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
9795 DEFUN (show_ip_msdp_sa_detail_vrf_all
,
9796 show_ip_msdp_sa_detail_vrf_all_cmd
,
9797 "show ip msdp vrf all sa detail [json]",
9802 "MSDP active-source information\n"
9806 bool uj
= use_json(argc
, argv
);
9812 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
9816 vty_out(vty
, " \"%s\": ", vrf
->name
);
9819 vty_out(vty
, "VRF: %s\n", vrf
->name
);
9820 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
9823 vty_out(vty
, "}\n");
9828 static void ip_msdp_show_sa_addr(struct pim_instance
*pim
, struct vty
*vty
,
9829 const char *addr
, bool uj
)
9831 struct listnode
*sanode
;
9832 struct pim_msdp_sa
*sa
;
9833 char src_str
[INET_ADDRSTRLEN
];
9834 char grp_str
[INET_ADDRSTRLEN
];
9835 json_object
*json
= NULL
;
9838 json
= json_object_new_object();
9841 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
9842 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
9843 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
9844 if (!strcmp(addr
, src_str
) || !strcmp(addr
, grp_str
)) {
9845 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
9851 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9852 json
, JSON_C_TO_STRING_PRETTY
));
9853 json_object_free(json
);
9857 static void ip_msdp_show_sa_sg(struct pim_instance
*pim
, struct vty
*vty
,
9858 const char *src
, const char *grp
, bool uj
)
9860 struct listnode
*sanode
;
9861 struct pim_msdp_sa
*sa
;
9862 char src_str
[INET_ADDRSTRLEN
];
9863 char grp_str
[INET_ADDRSTRLEN
];
9864 json_object
*json
= NULL
;
9867 json
= json_object_new_object();
9870 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
9871 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
9872 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
9873 if (!strcmp(src
, src_str
) && !strcmp(grp
, grp_str
)) {
9874 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
9880 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9881 json
, JSON_C_TO_STRING_PRETTY
));
9882 json_object_free(json
);
9886 DEFUN (show_ip_msdp_sa_sg
,
9887 show_ip_msdp_sa_sg_cmd
,
9888 "show ip msdp [vrf NAME] sa [A.B.C.D [A.B.C.D]] [json]",
9893 "MSDP active-source information\n"
9894 "source or group ip\n"
9898 bool uj
= use_json(argc
, argv
);
9902 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
9907 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
9909 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
9913 if (src_ip
&& grp_ip
)
9914 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
9916 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
9918 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
9923 DEFUN (show_ip_msdp_sa_sg_vrf_all
,
9924 show_ip_msdp_sa_sg_vrf_all_cmd
,
9925 "show ip msdp vrf all sa [A.B.C.D [A.B.C.D]] [json]",
9930 "MSDP active-source information\n"
9931 "source or group ip\n"
9935 bool uj
= use_json(argc
, argv
);
9940 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
9942 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
9948 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
9952 vty_out(vty
, " \"%s\": ", vrf
->name
);
9955 vty_out(vty
, "VRF: %s\n", vrf
->name
);
9957 if (src_ip
&& grp_ip
)
9958 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
9960 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
9962 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
9965 vty_out(vty
, "}\n");
9970 struct pim_sg_cache_walk_data
{
9973 json_object
*json_group
;
9974 struct in_addr addr
;
9978 static void pim_show_vxlan_sg_entry(struct pim_vxlan_sg
*vxlan_sg
,
9979 struct pim_sg_cache_walk_data
*cwd
)
9981 struct vty
*vty
= cwd
->vty
;
9982 json_object
*json
= cwd
->json
;
9983 char src_str
[INET_ADDRSTRLEN
];
9984 char grp_str
[INET_ADDRSTRLEN
];
9985 json_object
*json_row
;
9986 bool installed
= (vxlan_sg
->up
) ? true : false;
9987 const char *iif_name
= vxlan_sg
->iif
?vxlan_sg
->iif
->name
:"-";
9988 const char *oif_name
;
9990 if (pim_vxlan_is_orig_mroute(vxlan_sg
))
9991 oif_name
= vxlan_sg
->orig_oif
?vxlan_sg
->orig_oif
->name
:"";
9993 oif_name
= vxlan_sg
->term_oif
?vxlan_sg
->term_oif
->name
:"";
9995 if (cwd
->addr_match
&& (vxlan_sg
->sg
.src
.s_addr
!= cwd
->addr
.s_addr
) &&
9996 (vxlan_sg
->sg
.grp
.s_addr
!= cwd
->addr
.s_addr
)) {
9999 pim_inet4_dump("<src?>", vxlan_sg
->sg
.src
, src_str
, sizeof(src_str
));
10000 pim_inet4_dump("<grp?>", vxlan_sg
->sg
.grp
, grp_str
, sizeof(grp_str
));
10002 json_object_object_get_ex(json
, grp_str
, &cwd
->json_group
);
10004 if (!cwd
->json_group
) {
10005 cwd
->json_group
= json_object_new_object();
10006 json_object_object_add(json
, grp_str
,
10010 json_row
= json_object_new_object();
10011 json_object_string_add(json_row
, "source", src_str
);
10012 json_object_string_add(json_row
, "group", grp_str
);
10013 json_object_string_add(json_row
, "input", iif_name
);
10014 json_object_string_add(json_row
, "output", oif_name
);
10016 json_object_boolean_true_add(json_row
, "installed");
10018 json_object_boolean_false_add(json_row
, "installed");
10019 json_object_object_add(cwd
->json_group
, src_str
, json_row
);
10021 vty_out(vty
, "%-15s %-15s %-15s %-15s %-5s\n",
10022 src_str
, grp_str
, iif_name
, oif_name
,
10027 static void pim_show_vxlan_sg_hash_entry(struct hash_backet
*backet
, void *arg
)
10029 pim_show_vxlan_sg_entry((struct pim_vxlan_sg
*)backet
->data
,
10030 (struct pim_sg_cache_walk_data
*)arg
);
10033 static void pim_show_vxlan_sg(struct pim_instance
*pim
,
10034 struct vty
*vty
, bool uj
)
10036 json_object
*json
= NULL
;
10037 struct pim_sg_cache_walk_data cwd
;
10040 json
= json_object_new_object();
10042 vty_out(vty
, "Codes: I -> installed\n");
10044 "Source Group Input Output Flags\n");
10047 memset(&cwd
, 0, sizeof(cwd
));
10050 hash_iterate(pim
->vxlan
.sg_hash
, pim_show_vxlan_sg_hash_entry
, &cwd
);
10053 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10054 json
, JSON_C_TO_STRING_PRETTY
));
10055 json_object_free(json
);
10059 static void pim_show_vxlan_sg_match_addr(struct pim_instance
*pim
,
10060 struct vty
*vty
, char *addr_str
, bool uj
)
10062 json_object
*json
= NULL
;
10063 struct pim_sg_cache_walk_data cwd
;
10066 memset(&cwd
, 0, sizeof(cwd
));
10067 result
= inet_pton(AF_INET
, addr_str
, &cwd
.addr
);
10069 vty_out(vty
, "Bad address %s: errno=%d: %s\n", addr_str
,
10070 errno
, safe_strerror(errno
));
10075 json
= json_object_new_object();
10077 vty_out(vty
, "Codes: I -> installed\n");
10079 "Source Group Input Output Flags\n");
10084 cwd
.addr_match
= true;
10085 hash_iterate(pim
->vxlan
.sg_hash
, pim_show_vxlan_sg_hash_entry
, &cwd
);
10088 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10089 json
, JSON_C_TO_STRING_PRETTY
));
10090 json_object_free(json
);
10094 static void pim_show_vxlan_sg_one(struct pim_instance
*pim
,
10095 struct vty
*vty
, char *src_str
, char *grp_str
, bool uj
)
10097 json_object
*json
= NULL
;
10098 struct prefix_sg sg
;
10100 struct pim_vxlan_sg
*vxlan_sg
;
10101 const char *iif_name
;
10103 const char *oif_name
;
10105 result
= inet_pton(AF_INET
, src_str
, &sg
.src
);
10107 vty_out(vty
, "Bad src address %s: errno=%d: %s\n", src_str
,
10108 errno
, safe_strerror(errno
));
10111 result
= inet_pton(AF_INET
, grp_str
, &sg
.grp
);
10113 vty_out(vty
, "Bad grp address %s: errno=%d: %s\n", grp_str
,
10114 errno
, safe_strerror(errno
));
10118 sg
.family
= AF_INET
;
10119 sg
.prefixlen
= IPV4_MAX_BITLEN
;
10121 json
= json_object_new_object();
10123 vxlan_sg
= pim_vxlan_sg_find(pim
, &sg
);
10125 installed
= (vxlan_sg
->up
) ? true : false;
10126 iif_name
= vxlan_sg
->iif
?vxlan_sg
->iif
->name
:"-";
10128 if (pim_vxlan_is_orig_mroute(vxlan_sg
))
10130 vxlan_sg
->orig_oif
?vxlan_sg
->orig_oif
->name
:"";
10133 vxlan_sg
->term_oif
?vxlan_sg
->term_oif
->name
:"";
10136 json_object_string_add(json
, "source", src_str
);
10137 json_object_string_add(json
, "group", grp_str
);
10138 json_object_string_add(json
, "input", iif_name
);
10139 json_object_string_add(json
, "output", oif_name
);
10141 json_object_boolean_true_add(json
, "installed");
10143 json_object_boolean_false_add(json
,
10146 vty_out(vty
, "SG : %s\n", vxlan_sg
->sg_str
);
10147 vty_out(vty
, " Input : %s\n", iif_name
);
10148 vty_out(vty
, " Output : %s\n", oif_name
);
10149 vty_out(vty
, " installed : %s\n",
10150 installed
?"yes":"no");
10155 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10156 json
, JSON_C_TO_STRING_PRETTY
));
10157 json_object_free(json
);
10161 DEFUN (show_ip_pim_vxlan_sg
,
10162 show_ip_pim_vxlan_sg_cmd
,
10163 "show ip pim [vrf NAME] vxlan-groups [A.B.C.D [A.B.C.D]] [json]",
10168 "VxLAN BUM groups\n"
10169 "source or group ip\n"
10173 bool uj
= use_json(argc
, argv
);
10177 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10180 return CMD_WARNING
;
10182 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ?
10183 argv
[idx
++]->arg
:NULL
;
10184 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
) ?
10185 argv
[idx
]->arg
:NULL
;
10187 if (src_ip
&& grp_ip
)
10188 pim_show_vxlan_sg_one(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
10190 pim_show_vxlan_sg_match_addr(vrf
->info
, vty
, src_ip
, uj
);
10192 pim_show_vxlan_sg(vrf
->info
, vty
, uj
);
10194 return CMD_SUCCESS
;
10197 static void pim_show_vxlan_sg_work(struct pim_instance
*pim
,
10198 struct vty
*vty
, bool uj
)
10200 json_object
*json
= NULL
;
10201 struct pim_sg_cache_walk_data cwd
;
10202 struct listnode
*node
;
10203 struct pim_vxlan_sg
*vxlan_sg
;
10206 json
= json_object_new_object();
10208 vty_out(vty
, "Codes: I -> installed\n");
10210 "Source Group Input Flags\n");
10213 memset(&cwd
, 0, sizeof(cwd
));
10216 for (ALL_LIST_ELEMENTS_RO(pim_vxlan_p
->work_list
, node
, vxlan_sg
))
10217 pim_show_vxlan_sg_entry(vxlan_sg
, &cwd
);
10220 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10221 json
, JSON_C_TO_STRING_PRETTY
));
10222 json_object_free(json
);
10226 DEFUN_HIDDEN (show_ip_pim_vxlan_sg_work
,
10227 show_ip_pim_vxlan_sg_work_cmd
,
10228 "show ip pim [vrf NAME] vxlan-work [json]",
10233 "VxLAN work list\n"
10236 bool uj
= use_json(argc
, argv
);
10240 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10243 return CMD_WARNING
;
10245 pim_show_vxlan_sg_work(vrf
->info
, vty
, uj
);
10247 return CMD_SUCCESS
;
10250 DEFUN_HIDDEN (no_ip_pim_mlag
,
10251 no_ip_pim_mlag_cmd
,
10258 struct in_addr addr
;
10261 pim_vxlan_mlag_update(true/*mlag_enable*/,
10262 false/*peer_state*/, PIM_VXLAN_MLAG_ROLE_SECONDARY
,
10263 NULL
/*peerlink*/, &addr
);
10265 return CMD_SUCCESS
;
10268 DEFUN_HIDDEN (ip_pim_mlag
,
10270 "ip pim mlag INTERFACE role [primary|secondary] state [up|down] addr A.B.C.D",
10274 "peerlink sub interface\n"
10276 "MLAG role primary\n"
10277 "MLAG role secondary\n"
10278 "peer session state\n"
10279 "peer session state up\n"
10280 "peer session state down\n"
10282 "unique ip address\n")
10284 struct interface
*ifp
;
10285 const char *peerlink
;
10290 struct in_addr reg_addr
;
10293 peerlink
= argv
[idx
]->arg
;
10294 ifp
= if_lookup_by_name(peerlink
, VRF_DEFAULT
);
10296 vty_out(vty
, "No such interface name %s\n", peerlink
);
10297 return CMD_WARNING
;
10301 if (!strcmp(argv
[idx
]->arg
, "primary")) {
10302 role
= PIM_VXLAN_MLAG_ROLE_PRIMARY
;
10303 } else if (!strcmp(argv
[idx
]->arg
, "secondary")) {
10304 role
= PIM_VXLAN_MLAG_ROLE_SECONDARY
;
10306 vty_out(vty
, "unknown MLAG role %s\n", argv
[idx
]->arg
);
10307 return CMD_WARNING
;
10311 if (!strcmp(argv
[idx
]->arg
, "up")) {
10313 } else if (strcmp(argv
[idx
]->arg
, "down")) {
10314 peer_state
= false;
10316 vty_out(vty
, "unknown MLAG state %s\n", argv
[idx
]->arg
);
10317 return CMD_WARNING
;
10321 result
= inet_pton(AF_INET
, argv
[idx
]->arg
, ®_addr
);
10323 vty_out(vty
, "%% Bad reg address %s: errno=%d: %s\n",
10325 errno
, safe_strerror(errno
));
10326 return CMD_WARNING_CONFIG_FAILED
;
10328 pim_vxlan_mlag_update(true, peer_state
, role
, ifp
, ®_addr
);
10330 return CMD_SUCCESS
;
10333 void pim_cmd_init(void)
10335 install_node(&interface_node
,
10336 pim_interface_config_write
); /* INTERFACE_NODE */
10339 install_node(&debug_node
, pim_debug_config_write
);
10341 install_element(ENABLE_NODE
, &pim_test_sg_keepalive_cmd
);
10343 install_element(CONFIG_NODE
, &ip_pim_rp_cmd
);
10344 install_element(VRF_NODE
, &ip_pim_rp_cmd
);
10345 install_element(CONFIG_NODE
, &no_ip_pim_rp_cmd
);
10346 install_element(VRF_NODE
, &no_ip_pim_rp_cmd
);
10347 install_element(CONFIG_NODE
, &ip_pim_rp_prefix_list_cmd
);
10348 install_element(VRF_NODE
, &ip_pim_rp_prefix_list_cmd
);
10349 install_element(CONFIG_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
10350 install_element(VRF_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
10351 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
10352 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
10353 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
10354 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
10355 install_element(CONFIG_NODE
, &ip_pim_ssm_prefix_list_cmd
);
10356 install_element(VRF_NODE
, &ip_pim_ssm_prefix_list_cmd
);
10357 install_element(CONFIG_NODE
, &ip_pim_register_suppress_cmd
);
10358 install_element(VRF_NODE
, &ip_pim_register_suppress_cmd
);
10359 install_element(CONFIG_NODE
, &no_ip_pim_register_suppress_cmd
);
10360 install_element(VRF_NODE
, &no_ip_pim_register_suppress_cmd
);
10361 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
10362 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
10363 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
10364 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
10365 install_element(CONFIG_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
10366 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
10367 install_element(CONFIG_NODE
,
10368 &no_ip_pim_spt_switchover_infinity_plist_cmd
);
10369 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_plist_cmd
);
10370 install_element(CONFIG_NODE
, &ip_pim_joinprune_time_cmd
);
10371 install_element(VRF_NODE
, &ip_pim_joinprune_time_cmd
);
10372 install_element(CONFIG_NODE
, &no_ip_pim_joinprune_time_cmd
);
10373 install_element(VRF_NODE
, &no_ip_pim_joinprune_time_cmd
);
10374 install_element(CONFIG_NODE
, &ip_pim_keep_alive_cmd
);
10375 install_element(VRF_NODE
, &ip_pim_keep_alive_cmd
);
10376 install_element(CONFIG_NODE
, &ip_pim_rp_keep_alive_cmd
);
10377 install_element(VRF_NODE
, &ip_pim_rp_keep_alive_cmd
);
10378 install_element(CONFIG_NODE
, &no_ip_pim_keep_alive_cmd
);
10379 install_element(VRF_NODE
, &no_ip_pim_keep_alive_cmd
);
10380 install_element(CONFIG_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
10381 install_element(VRF_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
10382 install_element(CONFIG_NODE
, &ip_pim_packets_cmd
);
10383 install_element(VRF_NODE
, &ip_pim_packets_cmd
);
10384 install_element(CONFIG_NODE
, &no_ip_pim_packets_cmd
);
10385 install_element(VRF_NODE
, &no_ip_pim_packets_cmd
);
10386 install_element(CONFIG_NODE
, &ip_pim_v6_secondary_cmd
);
10387 install_element(VRF_NODE
, &ip_pim_v6_secondary_cmd
);
10388 install_element(CONFIG_NODE
, &no_ip_pim_v6_secondary_cmd
);
10389 install_element(VRF_NODE
, &no_ip_pim_v6_secondary_cmd
);
10390 install_element(CONFIG_NODE
, &ip_ssmpingd_cmd
);
10391 install_element(VRF_NODE
, &ip_ssmpingd_cmd
);
10392 install_element(CONFIG_NODE
, &no_ip_ssmpingd_cmd
);
10393 install_element(VRF_NODE
, &no_ip_ssmpingd_cmd
);
10394 install_element(CONFIG_NODE
, &ip_msdp_peer_cmd
);
10395 install_element(VRF_NODE
, &ip_msdp_peer_cmd
);
10396 install_element(CONFIG_NODE
, &no_ip_msdp_peer_cmd
);
10397 install_element(VRF_NODE
, &no_ip_msdp_peer_cmd
);
10398 install_element(CONFIG_NODE
, &ip_pim_ecmp_cmd
);
10399 install_element(VRF_NODE
, &ip_pim_ecmp_cmd
);
10400 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_cmd
);
10401 install_element(VRF_NODE
, &no_ip_pim_ecmp_cmd
);
10402 install_element(CONFIG_NODE
, &ip_pim_ecmp_rebalance_cmd
);
10403 install_element(VRF_NODE
, &ip_pim_ecmp_rebalance_cmd
);
10404 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
10405 install_element(VRF_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
10406 install_element(CONFIG_NODE
, &ip_pim_mlag_cmd
);
10407 install_element(CONFIG_NODE
, &no_ip_pim_mlag_cmd
);
10409 install_element(INTERFACE_NODE
, &interface_ip_igmp_cmd
);
10410 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_cmd
);
10411 install_element(INTERFACE_NODE
, &interface_ip_igmp_join_cmd
);
10412 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_join_cmd
);
10413 install_element(INTERFACE_NODE
, &interface_ip_igmp_version_cmd
);
10414 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_version_cmd
);
10415 install_element(INTERFACE_NODE
, &interface_ip_igmp_query_interval_cmd
);
10416 install_element(INTERFACE_NODE
,
10417 &interface_no_ip_igmp_query_interval_cmd
);
10418 install_element(INTERFACE_NODE
,
10419 &interface_ip_igmp_query_max_response_time_cmd
);
10420 install_element(INTERFACE_NODE
,
10421 &interface_no_ip_igmp_query_max_response_time_cmd
);
10422 install_element(INTERFACE_NODE
,
10423 &interface_ip_igmp_query_max_response_time_dsec_cmd
);
10424 install_element(INTERFACE_NODE
,
10425 &interface_no_ip_igmp_query_max_response_time_dsec_cmd
);
10426 install_element(INTERFACE_NODE
,
10427 &interface_ip_igmp_last_member_query_count_cmd
);
10428 install_element(INTERFACE_NODE
,
10429 &interface_no_ip_igmp_last_member_query_count_cmd
);
10430 install_element(INTERFACE_NODE
,
10431 &interface_ip_igmp_last_member_query_interval_cmd
);
10432 install_element(INTERFACE_NODE
,
10433 &interface_no_ip_igmp_last_member_query_interval_cmd
);
10434 install_element(INTERFACE_NODE
, &interface_ip_pim_activeactive_cmd
);
10435 install_element(INTERFACE_NODE
, &interface_ip_pim_ssm_cmd
);
10436 install_element(INTERFACE_NODE
, &interface_no_ip_pim_ssm_cmd
);
10437 install_element(INTERFACE_NODE
, &interface_ip_pim_sm_cmd
);
10438 install_element(INTERFACE_NODE
, &interface_no_ip_pim_sm_cmd
);
10439 install_element(INTERFACE_NODE
, &interface_ip_pim_cmd
);
10440 install_element(INTERFACE_NODE
, &interface_no_ip_pim_cmd
);
10441 install_element(INTERFACE_NODE
, &interface_ip_pim_drprio_cmd
);
10442 install_element(INTERFACE_NODE
, &interface_no_ip_pim_drprio_cmd
);
10443 install_element(INTERFACE_NODE
, &interface_ip_pim_hello_cmd
);
10444 install_element(INTERFACE_NODE
, &interface_no_ip_pim_hello_cmd
);
10445 install_element(INTERFACE_NODE
, &interface_ip_pim_boundary_oil_cmd
);
10446 install_element(INTERFACE_NODE
, &interface_no_ip_pim_boundary_oil_cmd
);
10447 install_element(INTERFACE_NODE
, &interface_ip_igmp_query_generate_cmd
);
10449 // Static mroutes NEB
10450 install_element(INTERFACE_NODE
, &interface_ip_mroute_cmd
);
10451 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_cmd
);
10453 install_element(VIEW_NODE
, &show_ip_igmp_interface_cmd
);
10454 install_element(VIEW_NODE
, &show_ip_igmp_interface_vrf_all_cmd
);
10455 install_element(VIEW_NODE
, &show_ip_igmp_join_cmd
);
10456 install_element(VIEW_NODE
, &show_ip_igmp_join_vrf_all_cmd
);
10457 install_element(VIEW_NODE
, &show_ip_igmp_groups_cmd
);
10458 install_element(VIEW_NODE
, &show_ip_igmp_groups_vrf_all_cmd
);
10459 install_element(VIEW_NODE
, &show_ip_igmp_groups_retransmissions_cmd
);
10460 install_element(VIEW_NODE
, &show_ip_igmp_sources_cmd
);
10461 install_element(VIEW_NODE
, &show_ip_igmp_sources_retransmissions_cmd
);
10462 install_element(VIEW_NODE
, &show_ip_igmp_statistics_cmd
);
10463 install_element(VIEW_NODE
, &show_ip_pim_assert_cmd
);
10464 install_element(VIEW_NODE
, &show_ip_pim_assert_internal_cmd
);
10465 install_element(VIEW_NODE
, &show_ip_pim_assert_metric_cmd
);
10466 install_element(VIEW_NODE
, &show_ip_pim_assert_winner_metric_cmd
);
10467 install_element(VIEW_NODE
, &show_ip_pim_interface_traffic_cmd
);
10468 install_element(VIEW_NODE
, &show_ip_pim_interface_cmd
);
10469 install_element(VIEW_NODE
, &show_ip_pim_interface_vrf_all_cmd
);
10470 install_element(VIEW_NODE
, &show_ip_pim_join_cmd
);
10471 install_element(VIEW_NODE
, &show_ip_pim_join_vrf_all_cmd
);
10472 install_element(VIEW_NODE
, &show_ip_pim_jp_agg_cmd
);
10473 install_element(VIEW_NODE
, &show_ip_pim_local_membership_cmd
);
10474 install_element(VIEW_NODE
, &show_ip_pim_neighbor_cmd
);
10475 install_element(VIEW_NODE
, &show_ip_pim_neighbor_vrf_all_cmd
);
10476 install_element(VIEW_NODE
, &show_ip_pim_rpf_cmd
);
10477 install_element(VIEW_NODE
, &show_ip_pim_rpf_vrf_all_cmd
);
10478 install_element(VIEW_NODE
, &show_ip_pim_secondary_cmd
);
10479 install_element(VIEW_NODE
, &show_ip_pim_state_cmd
);
10480 install_element(VIEW_NODE
, &show_ip_pim_state_vrf_all_cmd
);
10481 install_element(VIEW_NODE
, &show_ip_pim_upstream_cmd
);
10482 install_element(VIEW_NODE
, &show_ip_pim_upstream_vrf_all_cmd
);
10483 install_element(VIEW_NODE
, &show_ip_pim_channel_cmd
);
10484 install_element(VIEW_NODE
, &show_ip_pim_upstream_join_desired_cmd
);
10485 install_element(VIEW_NODE
, &show_ip_pim_upstream_rpf_cmd
);
10486 install_element(VIEW_NODE
, &show_ip_pim_rp_cmd
);
10487 install_element(VIEW_NODE
, &show_ip_pim_rp_vrf_all_cmd
);
10488 install_element(VIEW_NODE
, &show_ip_pim_bsr_cmd
);
10489 install_element(VIEW_NODE
, &show_ip_multicast_cmd
);
10490 install_element(VIEW_NODE
, &show_ip_multicast_vrf_all_cmd
);
10491 install_element(VIEW_NODE
, &show_ip_mroute_cmd
);
10492 install_element(VIEW_NODE
, &show_ip_mroute_vrf_all_cmd
);
10493 install_element(VIEW_NODE
, &show_ip_mroute_count_cmd
);
10494 install_element(VIEW_NODE
, &show_ip_mroute_count_vrf_all_cmd
);
10495 install_element(VIEW_NODE
, &show_ip_mroute_summary_cmd
);
10496 install_element(VIEW_NODE
, &show_ip_mroute_summary_vrf_all_cmd
);
10497 install_element(VIEW_NODE
, &show_ip_rib_cmd
);
10498 install_element(VIEW_NODE
, &show_ip_ssmpingd_cmd
);
10499 install_element(VIEW_NODE
, &show_debugging_pim_cmd
);
10500 install_element(VIEW_NODE
, &show_ip_pim_nexthop_cmd
);
10501 install_element(VIEW_NODE
, &show_ip_pim_nexthop_lookup_cmd
);
10502 install_element(VIEW_NODE
, &show_ip_pim_bsrp_cmd
);
10503 install_element(VIEW_NODE
, &show_ip_pim_bsm_db_cmd
);
10504 install_element(VIEW_NODE
, &show_ip_pim_statistics_cmd
);
10506 install_element(ENABLE_NODE
, &clear_ip_mroute_count_cmd
);
10507 install_element(ENABLE_NODE
, &clear_ip_interfaces_cmd
);
10508 install_element(ENABLE_NODE
, &clear_ip_igmp_interfaces_cmd
);
10509 install_element(ENABLE_NODE
, &clear_ip_mroute_cmd
);
10510 install_element(ENABLE_NODE
, &clear_ip_pim_interfaces_cmd
);
10511 install_element(ENABLE_NODE
, &clear_ip_pim_interface_traffic_cmd
);
10512 install_element(ENABLE_NODE
, &clear_ip_pim_oil_cmd
);
10513 install_element(ENABLE_NODE
, &clear_ip_pim_statistics_cmd
);
10515 install_element(ENABLE_NODE
, &debug_igmp_cmd
);
10516 install_element(ENABLE_NODE
, &no_debug_igmp_cmd
);
10517 install_element(ENABLE_NODE
, &debug_igmp_events_cmd
);
10518 install_element(ENABLE_NODE
, &no_debug_igmp_events_cmd
);
10519 install_element(ENABLE_NODE
, &debug_igmp_packets_cmd
);
10520 install_element(ENABLE_NODE
, &no_debug_igmp_packets_cmd
);
10521 install_element(ENABLE_NODE
, &debug_igmp_trace_cmd
);
10522 install_element(ENABLE_NODE
, &no_debug_igmp_trace_cmd
);
10523 install_element(ENABLE_NODE
, &debug_mroute_cmd
);
10524 install_element(ENABLE_NODE
, &debug_mroute_detail_cmd
);
10525 install_element(ENABLE_NODE
, &no_debug_mroute_cmd
);
10526 install_element(ENABLE_NODE
, &no_debug_mroute_detail_cmd
);
10527 install_element(ENABLE_NODE
, &debug_pim_static_cmd
);
10528 install_element(ENABLE_NODE
, &no_debug_pim_static_cmd
);
10529 install_element(ENABLE_NODE
, &debug_pim_cmd
);
10530 install_element(ENABLE_NODE
, &no_debug_pim_cmd
);
10531 install_element(ENABLE_NODE
, &debug_pim_nht_cmd
);
10532 install_element(ENABLE_NODE
, &no_debug_pim_nht_cmd
);
10533 install_element(ENABLE_NODE
, &debug_pim_nht_rp_cmd
);
10534 install_element(ENABLE_NODE
, &no_debug_pim_nht_rp_cmd
);
10535 install_element(ENABLE_NODE
, &debug_pim_events_cmd
);
10536 install_element(ENABLE_NODE
, &no_debug_pim_events_cmd
);
10537 install_element(ENABLE_NODE
, &debug_pim_packets_cmd
);
10538 install_element(ENABLE_NODE
, &no_debug_pim_packets_cmd
);
10539 install_element(ENABLE_NODE
, &debug_pim_packetdump_send_cmd
);
10540 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_send_cmd
);
10541 install_element(ENABLE_NODE
, &debug_pim_packetdump_recv_cmd
);
10542 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_recv_cmd
);
10543 install_element(ENABLE_NODE
, &debug_pim_trace_cmd
);
10544 install_element(ENABLE_NODE
, &no_debug_pim_trace_cmd
);
10545 install_element(ENABLE_NODE
, &debug_pim_trace_detail_cmd
);
10546 install_element(ENABLE_NODE
, &no_debug_pim_trace_detail_cmd
);
10547 install_element(ENABLE_NODE
, &debug_ssmpingd_cmd
);
10548 install_element(ENABLE_NODE
, &no_debug_ssmpingd_cmd
);
10549 install_element(ENABLE_NODE
, &debug_pim_zebra_cmd
);
10550 install_element(ENABLE_NODE
, &no_debug_pim_zebra_cmd
);
10551 install_element(ENABLE_NODE
, &debug_pim_mlag_cmd
);
10552 install_element(ENABLE_NODE
, &no_debug_pim_mlag_cmd
);
10553 install_element(ENABLE_NODE
, &debug_pim_vxlan_cmd
);
10554 install_element(ENABLE_NODE
, &no_debug_pim_vxlan_cmd
);
10555 install_element(ENABLE_NODE
, &debug_msdp_cmd
);
10556 install_element(ENABLE_NODE
, &no_debug_msdp_cmd
);
10557 install_element(ENABLE_NODE
, &debug_msdp_events_cmd
);
10558 install_element(ENABLE_NODE
, &no_debug_msdp_events_cmd
);
10559 install_element(ENABLE_NODE
, &debug_msdp_packets_cmd
);
10560 install_element(ENABLE_NODE
, &no_debug_msdp_packets_cmd
);
10561 install_element(ENABLE_NODE
, &debug_mtrace_cmd
);
10562 install_element(ENABLE_NODE
, &no_debug_mtrace_cmd
);
10563 install_element(ENABLE_NODE
, &debug_bsm_cmd
);
10564 install_element(ENABLE_NODE
, &no_debug_bsm_cmd
);
10566 install_element(CONFIG_NODE
, &debug_igmp_cmd
);
10567 install_element(CONFIG_NODE
, &no_debug_igmp_cmd
);
10568 install_element(CONFIG_NODE
, &debug_igmp_events_cmd
);
10569 install_element(CONFIG_NODE
, &no_debug_igmp_events_cmd
);
10570 install_element(CONFIG_NODE
, &debug_igmp_packets_cmd
);
10571 install_element(CONFIG_NODE
, &no_debug_igmp_packets_cmd
);
10572 install_element(CONFIG_NODE
, &debug_igmp_trace_cmd
);
10573 install_element(CONFIG_NODE
, &no_debug_igmp_trace_cmd
);
10574 install_element(CONFIG_NODE
, &debug_mroute_cmd
);
10575 install_element(CONFIG_NODE
, &debug_mroute_detail_cmd
);
10576 install_element(CONFIG_NODE
, &no_debug_mroute_cmd
);
10577 install_element(CONFIG_NODE
, &no_debug_mroute_detail_cmd
);
10578 install_element(CONFIG_NODE
, &debug_pim_static_cmd
);
10579 install_element(CONFIG_NODE
, &no_debug_pim_static_cmd
);
10580 install_element(CONFIG_NODE
, &debug_pim_cmd
);
10581 install_element(CONFIG_NODE
, &no_debug_pim_cmd
);
10582 install_element(CONFIG_NODE
, &debug_pim_nht_cmd
);
10583 install_element(CONFIG_NODE
, &no_debug_pim_nht_cmd
);
10584 install_element(CONFIG_NODE
, &debug_pim_nht_rp_cmd
);
10585 install_element(CONFIG_NODE
, &no_debug_pim_nht_rp_cmd
);
10586 install_element(CONFIG_NODE
, &debug_pim_events_cmd
);
10587 install_element(CONFIG_NODE
, &no_debug_pim_events_cmd
);
10588 install_element(CONFIG_NODE
, &debug_pim_packets_cmd
);
10589 install_element(CONFIG_NODE
, &no_debug_pim_packets_cmd
);
10590 install_element(CONFIG_NODE
, &debug_pim_trace_cmd
);
10591 install_element(CONFIG_NODE
, &no_debug_pim_trace_cmd
);
10592 install_element(CONFIG_NODE
, &debug_pim_trace_detail_cmd
);
10593 install_element(CONFIG_NODE
, &no_debug_pim_trace_detail_cmd
);
10594 install_element(CONFIG_NODE
, &debug_ssmpingd_cmd
);
10595 install_element(CONFIG_NODE
, &no_debug_ssmpingd_cmd
);
10596 install_element(CONFIG_NODE
, &debug_pim_zebra_cmd
);
10597 install_element(CONFIG_NODE
, &no_debug_pim_zebra_cmd
);
10598 install_element(CONFIG_NODE
, &debug_pim_vxlan_cmd
);
10599 install_element(CONFIG_NODE
, &no_debug_pim_vxlan_cmd
);
10600 install_element(CONFIG_NODE
, &debug_msdp_cmd
);
10601 install_element(CONFIG_NODE
, &no_debug_msdp_cmd
);
10602 install_element(CONFIG_NODE
, &debug_msdp_events_cmd
);
10603 install_element(CONFIG_NODE
, &no_debug_msdp_events_cmd
);
10604 install_element(CONFIG_NODE
, &debug_msdp_packets_cmd
);
10605 install_element(CONFIG_NODE
, &no_debug_msdp_packets_cmd
);
10606 install_element(CONFIG_NODE
, &debug_mtrace_cmd
);
10607 install_element(CONFIG_NODE
, &no_debug_mtrace_cmd
);
10608 install_element(CONFIG_NODE
, &debug_bsm_cmd
);
10609 install_element(CONFIG_NODE
, &no_debug_bsm_cmd
);
10611 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_member_cmd
);
10612 install_element(VRF_NODE
, &ip_msdp_mesh_group_member_cmd
);
10613 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
10614 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
10615 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_source_cmd
);
10616 install_element(VRF_NODE
, &ip_msdp_mesh_group_source_cmd
);
10617 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
10618 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
10619 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_cmd
);
10620 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_vrf_all_cmd
);
10621 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_cmd
);
10622 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_vrf_all_cmd
);
10623 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_cmd
);
10624 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_vrf_all_cmd
);
10625 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_cmd
);
10626 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_vrf_all_cmd
);
10627 install_element(VIEW_NODE
, &show_ip_pim_ssm_range_cmd
);
10628 install_element(VIEW_NODE
, &show_ip_pim_group_type_cmd
);
10629 install_element(VIEW_NODE
, &show_ip_pim_vxlan_sg_cmd
);
10630 install_element(VIEW_NODE
, &show_ip_pim_vxlan_sg_work_cmd
);
10631 install_element(INTERFACE_NODE
, &interface_pim_use_source_cmd
);
10632 install_element(INTERFACE_NODE
, &interface_no_pim_use_source_cmd
);
10633 /* Install BSM command */
10634 install_element(INTERFACE_NODE
, &ip_pim_bsm_cmd
);
10635 install_element(INTERFACE_NODE
, &no_ip_pim_bsm_cmd
);
10636 install_element(INTERFACE_NODE
, &ip_pim_ucast_bsm_cmd
);
10637 install_element(INTERFACE_NODE
, &no_ip_pim_ucast_bsm_cmd
);
10638 /* Install BFD command */
10639 install_element(INTERFACE_NODE
, &ip_pim_bfd_cmd
);
10640 install_element(INTERFACE_NODE
, &ip_pim_bfd_param_cmd
);
10641 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_cmd
);
10643 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_param_cmd
);
10644 #endif /* !HAVE_BFDD */