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
!= 0
1745 && sg
->grp
.s_addr
!= ch
->sg
.grp
.s_addr
)
1747 if (sg
->src
.s_addr
!= 0
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
!= 0 && sg
->grp
.s_addr
!= up
->sg
.grp
.s_addr
)
2453 if (sg
->src
.s_addr
!= 0 && sg
->src
.s_addr
!= up
->sg
.src
.s_addr
)
2456 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2457 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2458 pim_time_uptime(uptime
, sizeof(uptime
),
2459 now
- up
->state_transition
);
2460 pim_time_timer_to_hhmmss(join_timer
, sizeof(join_timer
),
2464 * If the upstream is not dummy and it has a J/P timer for the
2465 * neighbor display that
2467 if (!up
->t_join_timer
&& up
->rpf
.source_nexthop
.interface
) {
2468 struct pim_neighbor
*nbr
;
2470 nbr
= pim_neighbor_find(
2471 up
->rpf
.source_nexthop
.interface
,
2472 up
->rpf
.rpf_addr
.u
.prefix4
);
2474 pim_time_timer_to_hhmmss(join_timer
,
2479 pim_time_timer_to_hhmmss(rs_timer
, sizeof(rs_timer
),
2481 pim_time_timer_to_hhmmss(ka_timer
, sizeof(ka_timer
),
2483 pim_time_timer_to_hhmmss(msdp_reg_timer
, sizeof(msdp_reg_timer
),
2484 up
->t_msdp_reg_timer
);
2486 pim_upstream_state2brief_str(up
->join_state
, state_str
, sizeof(state_str
));
2487 if (up
->reg_state
!= PIM_REG_NOINFO
) {
2488 char tmp_str
[PIM_REG_STATE_STR_LEN
];
2490 sprintf(state_str
+ strlen(state_str
), ",%s",
2491 pim_reg_state2brief_str(up
->reg_state
, tmp_str
,
2496 json_object_object_get_ex(json
, grp_str
, &json_group
);
2499 json_group
= json_object_new_object();
2500 json_object_object_add(json
, grp_str
,
2504 json_row
= json_object_new_object();
2505 json_object_pim_upstream_add(json_row
, up
);
2506 json_object_string_add(
2507 json_row
, "inboundInterface",
2508 up
->rpf
.source_nexthop
.interface
2509 ? up
->rpf
.source_nexthop
.interface
->name
2513 * The RPF address we use is slightly different
2514 * based upon what we are looking up.
2515 * If we have a S, list that unless
2516 * we are the FHR, else we just put
2517 * the RP as the rpfAddress
2519 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
2520 || up
->sg
.src
.s_addr
== INADDR_ANY
) {
2521 char rpf
[PREFIX_STRLEN
];
2522 struct pim_rpf
*rpg
;
2524 rpg
= RP(pim
, up
->sg
.grp
);
2525 pim_inet4_dump("<rpf?>",
2526 rpg
->rpf_addr
.u
.prefix4
, rpf
,
2528 json_object_string_add(json_row
, "rpfAddress",
2531 json_object_string_add(json_row
, "rpfAddress",
2535 json_object_string_add(json_row
, "source", src_str
);
2536 json_object_string_add(json_row
, "group", grp_str
);
2537 json_object_string_add(json_row
, "state", state_str
);
2538 json_object_string_add(
2539 json_row
, "joinState",
2540 pim_upstream_state2str(up
->join_state
));
2541 json_object_string_add(
2542 json_row
, "regState",
2543 pim_reg_state2str(up
->reg_state
, state_str
, sizeof(state_str
)));
2544 json_object_string_add(json_row
, "upTime", uptime
);
2545 json_object_string_add(json_row
, "joinTimer",
2547 json_object_string_add(json_row
, "resetTimer",
2549 json_object_string_add(json_row
, "keepaliveTimer",
2551 json_object_string_add(json_row
, "msdpRegTimer",
2553 json_object_int_add(json_row
, "refCount",
2555 json_object_int_add(json_row
, "sptBit", up
->sptbit
);
2556 json_object_object_add(json_group
, src_str
, json_row
);
2559 "%-16s%-15s %-15s %-11s %-8s %-9s %-9s %-9s %6d\n",
2560 up
->rpf
.source_nexthop
.interface
2561 ? up
->rpf
.source_nexthop
.interface
->name
2563 src_str
, grp_str
, state_str
, uptime
, join_timer
,
2564 rs_timer
, ka_timer
, up
->ref_count
);
2569 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2570 json
, JSON_C_TO_STRING_PRETTY
));
2571 json_object_free(json
);
2575 static void pim_show_channel_helper(struct pim_instance
*pim
,
2577 struct pim_interface
*pim_ifp
,
2578 struct pim_ifchannel
*ch
,
2579 json_object
*json
, bool uj
)
2581 struct pim_upstream
*up
= ch
->upstream
;
2582 json_object
*json_group
= NULL
;
2583 char src_str
[INET_ADDRSTRLEN
];
2584 char grp_str
[INET_ADDRSTRLEN
];
2585 json_object
*json_row
= NULL
;
2587 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2588 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2591 json_object_object_get_ex(json
, grp_str
, &json_group
);
2594 json_group
= json_object_new_object();
2595 json_object_object_add(json
, grp_str
, json_group
);
2598 json_row
= json_object_new_object();
2599 json_object_pim_upstream_add(json_row
, up
);
2600 json_object_string_add(json_row
, "interface",
2601 ch
->interface
->name
);
2602 json_object_string_add(json_row
, "source", src_str
);
2603 json_object_string_add(json_row
, "group", grp_str
);
2605 if (pim_macro_ch_lost_assert(ch
))
2606 json_object_boolean_true_add(json_row
, "lostAssert");
2608 if (pim_macro_chisin_joins(ch
))
2609 json_object_boolean_true_add(json_row
, "joins");
2611 if (pim_macro_chisin_pim_include(ch
))
2612 json_object_boolean_true_add(json_row
, "pimInclude");
2614 if (pim_upstream_evaluate_join_desired(pim
, up
))
2615 json_object_boolean_true_add(json_row
,
2616 "evaluateJoinDesired");
2618 json_object_object_add(json_group
, src_str
, json_row
);
2621 vty_out(vty
, "%-16s %-15s %-15s %-10s %-5s %-10s %-11s %-6s\n",
2622 ch
->interface
->name
, src_str
, grp_str
,
2623 pim_macro_ch_lost_assert(ch
) ? "yes" : "no",
2624 pim_macro_chisin_joins(ch
) ? "yes" : "no",
2625 pim_macro_chisin_pim_include(ch
) ? "yes" : "no",
2626 PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(up
->flags
)
2629 pim_upstream_evaluate_join_desired(pim
, up
) ? "yes"
2634 static void pim_show_channel(struct pim_instance
*pim
, struct vty
*vty
,
2637 struct pim_interface
*pim_ifp
;
2638 struct pim_ifchannel
*ch
;
2639 struct interface
*ifp
;
2641 json_object
*json
= NULL
;
2644 json
= json_object_new_object();
2647 "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD\n");
2649 /* scan per-interface (S,G) state */
2650 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2651 pim_ifp
= ifp
->info
;
2656 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
2657 /* scan all interfaces */
2658 pim_show_channel_helper(pim
, vty
, pim_ifp
, ch
,
2664 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2665 json
, JSON_C_TO_STRING_PRETTY
));
2666 json_object_free(json
);
2670 static void pim_show_join_desired_helper(struct pim_instance
*pim
,
2672 struct pim_upstream
*up
,
2673 json_object
*json
, bool uj
)
2675 json_object
*json_group
= NULL
;
2676 char src_str
[INET_ADDRSTRLEN
];
2677 char grp_str
[INET_ADDRSTRLEN
];
2678 json_object
*json_row
= NULL
;
2680 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2681 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2684 json_object_object_get_ex(json
, grp_str
, &json_group
);
2687 json_group
= json_object_new_object();
2688 json_object_object_add(json
, grp_str
, json_group
);
2691 json_row
= json_object_new_object();
2692 json_object_pim_upstream_add(json_row
, up
);
2693 json_object_string_add(json_row
, "source", src_str
);
2694 json_object_string_add(json_row
, "group", grp_str
);
2696 if (pim_upstream_evaluate_join_desired(pim
, up
))
2697 json_object_boolean_true_add(json_row
,
2698 "evaluateJoinDesired");
2700 json_object_object_add(json_group
, src_str
, json_row
);
2703 vty_out(vty
, "%-15s %-15s %-6s\n",
2705 pim_upstream_evaluate_join_desired(pim
, up
) ? "yes"
2710 static void pim_show_join_desired(struct pim_instance
*pim
, struct vty
*vty
,
2713 struct pim_upstream
*up
;
2715 json_object
*json
= NULL
;
2718 json
= json_object_new_object();
2721 "Source Group EvalJD\n");
2723 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
2724 /* scan all interfaces */
2725 pim_show_join_desired_helper(pim
, vty
, up
,
2730 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2731 json
, JSON_C_TO_STRING_PRETTY
));
2732 json_object_free(json
);
2736 static void pim_show_upstream_rpf(struct pim_instance
*pim
, struct vty
*vty
,
2739 struct pim_upstream
*up
;
2740 json_object
*json
= NULL
;
2741 json_object
*json_group
= NULL
;
2742 json_object
*json_row
= NULL
;
2745 json
= json_object_new_object();
2748 "Source Group RpfIface RibNextHop RpfAddress \n");
2750 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
2751 char src_str
[INET_ADDRSTRLEN
];
2752 char grp_str
[INET_ADDRSTRLEN
];
2753 char rpf_nexthop_str
[PREFIX_STRLEN
];
2754 char rpf_addr_str
[PREFIX_STRLEN
];
2755 struct pim_rpf
*rpf
;
2756 const char *rpf_ifname
;
2760 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2761 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2762 pim_addr_dump("<nexthop?>",
2763 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2764 rpf_nexthop_str
, sizeof(rpf_nexthop_str
));
2765 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2766 sizeof(rpf_addr_str
));
2768 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2771 json_object_object_get_ex(json
, grp_str
, &json_group
);
2774 json_group
= json_object_new_object();
2775 json_object_object_add(json
, grp_str
,
2779 json_row
= json_object_new_object();
2780 json_object_pim_upstream_add(json_row
, up
);
2781 json_object_string_add(json_row
, "source", src_str
);
2782 json_object_string_add(json_row
, "group", grp_str
);
2783 json_object_string_add(json_row
, "rpfInterface",
2785 json_object_string_add(json_row
, "ribNexthop",
2787 json_object_string_add(json_row
, "rpfAddress",
2789 json_object_object_add(json_group
, src_str
, json_row
);
2791 vty_out(vty
, "%-15s %-15s %-16s %-15s %-15s\n", src_str
,
2792 grp_str
, rpf_ifname
, rpf_nexthop_str
,
2798 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2799 json
, JSON_C_TO_STRING_PRETTY
));
2800 json_object_free(json
);
2804 static void show_rpf_refresh_stats(struct vty
*vty
, struct pim_instance
*pim
,
2805 time_t now
, json_object
*json
)
2807 char refresh_uptime
[10];
2809 pim_time_uptime_begin(refresh_uptime
, sizeof(refresh_uptime
), now
,
2810 pim
->rpf_cache_refresh_last
);
2813 json_object_int_add(json
, "rpfCacheRefreshDelayMsecs",
2814 router
->rpf_cache_refresh_delay_msec
);
2815 json_object_int_add(
2816 json
, "rpfCacheRefreshTimer",
2817 pim_time_timer_remain_msec(pim
->rpf_cache_refresher
));
2818 json_object_int_add(json
, "rpfCacheRefreshRequests",
2819 pim
->rpf_cache_refresh_requests
);
2820 json_object_int_add(json
, "rpfCacheRefreshEvents",
2821 pim
->rpf_cache_refresh_events
);
2822 json_object_string_add(json
, "rpfCacheRefreshLast",
2824 json_object_int_add(json
, "nexthopLookups",
2825 pim
->nexthop_lookups
);
2826 json_object_int_add(json
, "nexthopLookupsAvoided",
2827 pim
->nexthop_lookups_avoided
);
2830 "RPF Cache Refresh Delay: %ld msecs\n"
2831 "RPF Cache Refresh Timer: %ld msecs\n"
2832 "RPF Cache Refresh Requests: %lld\n"
2833 "RPF Cache Refresh Events: %lld\n"
2834 "RPF Cache Refresh Last: %s\n"
2835 "Nexthop Lookups: %lld\n"
2836 "Nexthop Lookups Avoided: %lld\n",
2837 router
->rpf_cache_refresh_delay_msec
,
2838 pim_time_timer_remain_msec(pim
->rpf_cache_refresher
),
2839 (long long)pim
->rpf_cache_refresh_requests
,
2840 (long long)pim
->rpf_cache_refresh_events
,
2841 refresh_uptime
, (long long)pim
->nexthop_lookups
,
2842 (long long)pim
->nexthop_lookups_avoided
);
2846 static void show_scan_oil_stats(struct pim_instance
*pim
, struct vty
*vty
,
2849 char uptime_scan_oil
[10];
2850 char uptime_mroute_add
[10];
2851 char uptime_mroute_del
[10];
2853 pim_time_uptime_begin(uptime_scan_oil
, sizeof(uptime_scan_oil
), now
,
2854 pim
->scan_oil_last
);
2855 pim_time_uptime_begin(uptime_mroute_add
, sizeof(uptime_mroute_add
), now
,
2856 pim
->mroute_add_last
);
2857 pim_time_uptime_begin(uptime_mroute_del
, sizeof(uptime_mroute_del
), now
,
2858 pim
->mroute_del_last
);
2861 "Scan OIL - Last: %s Events: %lld\n"
2862 "MFC Add - Last: %s Events: %lld\n"
2863 "MFC Del - Last: %s Events: %lld\n",
2864 uptime_scan_oil
, (long long)pim
->scan_oil_events
,
2865 uptime_mroute_add
, (long long)pim
->mroute_add_events
,
2866 uptime_mroute_del
, (long long)pim
->mroute_del_events
);
2869 static void pim_show_rpf(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
2871 struct pim_upstream
*up
;
2872 time_t now
= pim_time_monotonic_sec();
2873 json_object
*json
= NULL
;
2874 json_object
*json_group
= NULL
;
2875 json_object
*json_row
= NULL
;
2878 json
= json_object_new_object();
2879 show_rpf_refresh_stats(vty
, pim
, now
, json
);
2881 show_rpf_refresh_stats(vty
, pim
, now
, json
);
2884 "Source Group RpfIface RpfAddress RibNextHop Metric Pref\n");
2887 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
2888 char src_str
[INET_ADDRSTRLEN
];
2889 char grp_str
[INET_ADDRSTRLEN
];
2890 char rpf_addr_str
[PREFIX_STRLEN
];
2891 char rib_nexthop_str
[PREFIX_STRLEN
];
2892 const char *rpf_ifname
;
2893 struct pim_rpf
*rpf
= &up
->rpf
;
2895 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2896 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2897 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2898 sizeof(rpf_addr_str
));
2899 pim_addr_dump("<nexthop?>",
2900 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2901 rib_nexthop_str
, sizeof(rib_nexthop_str
));
2903 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2906 json_object_object_get_ex(json
, grp_str
, &json_group
);
2909 json_group
= json_object_new_object();
2910 json_object_object_add(json
, grp_str
,
2914 json_row
= json_object_new_object();
2915 json_object_string_add(json_row
, "source", src_str
);
2916 json_object_string_add(json_row
, "group", grp_str
);
2917 json_object_string_add(json_row
, "rpfInterface",
2919 json_object_string_add(json_row
, "rpfAddress",
2921 json_object_string_add(json_row
, "ribNexthop",
2923 json_object_int_add(
2924 json_row
, "routeMetric",
2925 rpf
->source_nexthop
.mrib_route_metric
);
2926 json_object_int_add(
2927 json_row
, "routePreference",
2928 rpf
->source_nexthop
.mrib_metric_preference
);
2929 json_object_object_add(json_group
, src_str
, json_row
);
2932 vty_out(vty
, "%-15s %-15s %-16s %-15s %-15s %6d %4d\n",
2933 src_str
, grp_str
, rpf_ifname
, rpf_addr_str
,
2935 rpf
->source_nexthop
.mrib_route_metric
,
2936 rpf
->source_nexthop
.mrib_metric_preference
);
2941 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2942 json
, JSON_C_TO_STRING_PRETTY
));
2943 json_object_free(json
);
2947 struct pnc_cache_walk_data
{
2949 struct pim_instance
*pim
;
2952 static int pim_print_pnc_cache_walkcb(struct hash_bucket
*bucket
, void *arg
)
2954 struct pim_nexthop_cache
*pnc
= bucket
->data
;
2955 struct pnc_cache_walk_data
*cwd
= arg
;
2956 struct vty
*vty
= cwd
->vty
;
2957 struct pim_instance
*pim
= cwd
->pim
;
2958 struct nexthop
*nh_node
= NULL
;
2959 ifindex_t first_ifindex
;
2960 struct interface
*ifp
= NULL
;
2962 for (nh_node
= pnc
->nexthop
; nh_node
; nh_node
= nh_node
->next
) {
2963 first_ifindex
= nh_node
->ifindex
;
2964 ifp
= if_lookup_by_index(first_ifindex
, pim
->vrf_id
);
2966 vty_out(vty
, "%-15s ", inet_ntoa(pnc
->rpf
.rpf_addr
.u
.prefix4
));
2967 vty_out(vty
, "%-16s ", ifp
? ifp
->name
: "NULL");
2968 vty_out(vty
, "%s ", inet_ntoa(nh_node
->gate
.ipv4
));
2974 static void pim_show_nexthop(struct pim_instance
*pim
, struct vty
*vty
)
2976 struct pnc_cache_walk_data cwd
;
2980 vty_out(vty
, "Number of registered addresses: %lu\n",
2981 pim
->rpf_hash
->count
);
2982 vty_out(vty
, "Address Interface Nexthop\n");
2983 vty_out(vty
, "---------------------------------------------\n");
2985 hash_walk(pim
->rpf_hash
, pim_print_pnc_cache_walkcb
, &cwd
);
2988 /* Display the bsm database details */
2989 static void pim_show_bsm_db(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
2991 struct listnode
*bsmnode
;
2994 struct bsm_info
*bsm
;
2995 json_object
*json
= NULL
;
2996 json_object
*json_group
= NULL
;
2997 json_object
*json_row
= NULL
;
2999 count
= pim
->global_scope
.bsm_list
->count
;
3002 json
= json_object_new_object();
3003 json_object_int_add(json
, "Number of the fragments", count
);
3005 vty_out(vty
, "Scope Zone: Global\n");
3006 vty_out(vty
, "Number of the fragments: %d\n", count
);
3010 for (ALL_LIST_ELEMENTS_RO(pim
->global_scope
.bsm_list
, bsmnode
, bsm
)) {
3011 char grp_str
[INET_ADDRSTRLEN
];
3012 char rp_str
[INET_ADDRSTRLEN
];
3013 char bsr_str
[INET_ADDRSTRLEN
];
3014 struct bsmmsg_grpinfo
*group
;
3015 struct bsmmsg_rpinfo
*rpaddr
;
3017 struct bsm_hdr
*hdr
;
3018 uint32_t offset
= 0;
3021 uint32_t frag_rp_cnt
= 0;
3026 /* skip pim header */
3027 buf
+= PIM_MSG_HEADER_LEN
;
3028 len
-= PIM_MSG_HEADER_LEN
;
3030 hdr
= (struct bsm_hdr
*)buf
;
3032 /* BSM starts with bsr header */
3033 buf
+= sizeof(struct bsm_hdr
);
3034 len
-= sizeof(struct bsm_hdr
);
3036 pim_inet4_dump("<BSR Address?>", hdr
->bsr_addr
.addr
, bsr_str
,
3041 json_object_string_add(json
, "BSR address", bsr_str
);
3042 json_object_int_add(json
, "BSR priority",
3044 json_object_int_add(json
, "Hashmask Length",
3046 json_object_int_add(json
, "Fragment Tag",
3047 ntohs(hdr
->frag_tag
));
3049 vty_out(vty
, "BSM Fragment : %d\n", fragment
);
3050 vty_out(vty
, "------------------\n");
3051 vty_out(vty
, "%-15s %-15s %-15s %-15s\n", "BSR-Address",
3052 "BSR-Priority", "Hashmask-len", "Fragment-Tag");
3053 vty_out(vty
, "%-15s %-15d %-15d %-15d\n", bsr_str
,
3054 hdr
->bsr_prio
, hdr
->hm_len
,
3055 ntohs(hdr
->frag_tag
));
3060 while (offset
< len
) {
3061 group
= (struct bsmmsg_grpinfo
*)buf
;
3063 if (group
->group
.family
== PIM_MSG_ADDRESS_FAMILY_IPV4
)
3064 grp
.family
= AF_INET
;
3066 grp
.prefixlen
= group
->group
.mask
;
3067 grp
.u
.prefix4
.s_addr
= group
->group
.addr
.s_addr
;
3069 prefix2str(&grp
, grp_str
, sizeof(grp_str
));
3071 buf
+= sizeof(struct bsmmsg_grpinfo
);
3072 offset
+= sizeof(struct bsmmsg_grpinfo
);
3075 json_object_object_get_ex(json
, grp_str
,
3078 json_group
= json_object_new_object();
3079 json_object_int_add(json_group
,
3082 json_object_int_add(
3083 json_group
, "Fragment Rp count",
3084 group
->frag_rp_count
);
3085 json_object_object_add(json
, grp_str
,
3089 vty_out(vty
, "Group : %s\n", grp_str
);
3090 vty_out(vty
, "-------------------\n");
3091 vty_out(vty
, "Rp Count:%d\n", group
->rp_count
);
3092 vty_out(vty
, "Fragment Rp Count : %d\n",
3093 group
->frag_rp_count
);
3096 frag_rp_cnt
= group
->frag_rp_count
;
3103 "RpAddress HoldTime Priority\n");
3105 while (frag_rp_cnt
--) {
3106 rpaddr
= (struct bsmmsg_rpinfo
*)buf
;
3108 buf
+= sizeof(struct bsmmsg_rpinfo
);
3109 offset
+= sizeof(struct bsmmsg_rpinfo
);
3111 pim_inet4_dump("<Rp addr?>",
3112 rpaddr
->rpaddr
.addr
, rp_str
,
3116 json_row
= json_object_new_object();
3117 json_object_string_add(
3118 json_row
, "Rp Address", rp_str
);
3119 json_object_int_add(
3120 json_row
, "Rp HoldTime",
3121 ntohs(rpaddr
->rp_holdtime
));
3122 json_object_int_add(json_row
,
3125 json_object_object_add(
3126 json_group
, rp_str
, json_row
);
3128 vty_out(vty
, "%-15s %-12d %d\n", rp_str
,
3129 ntohs(rpaddr
->rp_holdtime
),
3140 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3141 json
, JSON_C_TO_STRING_PRETTY
));
3142 json_object_free(json
);
3146 /*Display the group-rp mappings */
3147 static void pim_show_group_rp_mappings_info(struct pim_instance
*pim
,
3148 struct vty
*vty
, bool uj
)
3150 struct bsgrp_node
*bsgrp
;
3151 struct listnode
*rpnode
;
3152 struct bsm_rpinfo
*bsm_rp
;
3153 struct route_node
*rn
;
3154 char bsr_str
[INET_ADDRSTRLEN
];
3155 json_object
*json
= NULL
;
3156 json_object
*json_group
= NULL
;
3157 json_object
*json_row
= NULL
;
3159 if (pim
->global_scope
.current_bsr
.s_addr
== INADDR_ANY
)
3160 strlcpy(bsr_str
, "0.0.0.0", sizeof(bsr_str
));
3163 pim_inet4_dump("<bsr?>", pim
->global_scope
.current_bsr
, bsr_str
,
3167 json
= json_object_new_object();
3168 json_object_string_add(json
, "BSR Address", bsr_str
);
3170 vty_out(vty
, "BSR Address %s\n", bsr_str
);
3173 for (rn
= route_top(pim
->global_scope
.bsrp_table
); rn
;
3174 rn
= route_next(rn
)) {
3175 bsgrp
= (struct bsgrp_node
*)rn
->info
;
3180 char grp_str
[INET_ADDRSTRLEN
];
3182 prefix2str(&bsgrp
->group
, grp_str
, sizeof(grp_str
));
3185 json_object_object_get_ex(json
, grp_str
, &json_group
);
3187 json_group
= json_object_new_object();
3188 json_object_object_add(json
, grp_str
,
3192 vty_out(vty
, "Group Address %s\n", grp_str
);
3193 vty_out(vty
, "--------------------------\n");
3194 vty_out(vty
, "%-15s %-15s %-15s %-15s\n", "Rp Address",
3195 "priority", "Holdtime", "Hash");
3197 vty_out(vty
, "(ACTIVE)\n");
3200 if (bsgrp
->bsrp_list
) {
3201 for (ALL_LIST_ELEMENTS_RO(bsgrp
->bsrp_list
, rpnode
,
3203 char rp_str
[INET_ADDRSTRLEN
];
3205 pim_inet4_dump("<Rp Address?>",
3206 bsm_rp
->rp_address
, rp_str
,
3210 json_row
= json_object_new_object();
3211 json_object_string_add(
3212 json_row
, "Rp Address", rp_str
);
3213 json_object_int_add(
3214 json_row
, "Rp HoldTime",
3215 bsm_rp
->rp_holdtime
);
3216 json_object_int_add(json_row
,
3219 json_object_int_add(json_row
,
3222 json_object_object_add(
3223 json_group
, rp_str
, json_row
);
3227 "%-15s %-15u %-15u %-15u\n",
3228 rp_str
, bsm_rp
->rp_prio
,
3229 bsm_rp
->rp_holdtime
,
3233 if (!bsgrp
->bsrp_list
->count
&& !uj
)
3234 vty_out(vty
, "Active List is empty.\n");
3238 json_object_int_add(json_group
, "Pending RP count",
3239 bsgrp
->pend_rp_cnt
);
3241 vty_out(vty
, "(PENDING)\n");
3242 vty_out(vty
, "Pending RP count :%d\n",
3243 bsgrp
->pend_rp_cnt
);
3244 if (bsgrp
->pend_rp_cnt
)
3245 vty_out(vty
, "%-15s %-15s %-15s %-15s\n",
3246 "Rp Address", "priority", "Holdtime",
3250 if (bsgrp
->partial_bsrp_list
) {
3251 for (ALL_LIST_ELEMENTS_RO(bsgrp
->partial_bsrp_list
,
3253 char rp_str
[INET_ADDRSTRLEN
];
3255 pim_inet4_dump("<Rp Addr?>", bsm_rp
->rp_address
,
3256 rp_str
, sizeof(rp_str
));
3259 json_row
= json_object_new_object();
3260 json_object_string_add(
3261 json_row
, "Rp Address", rp_str
);
3262 json_object_int_add(
3263 json_row
, "Rp HoldTime",
3264 bsm_rp
->rp_holdtime
);
3265 json_object_int_add(json_row
,
3268 json_object_int_add(json_row
,
3271 json_object_object_add(
3272 json_group
, rp_str
, json_row
);
3275 "%-15s %-15u %-15u %-15u\n",
3276 rp_str
, bsm_rp
->rp_prio
,
3277 bsm_rp
->rp_holdtime
,
3281 if (!bsgrp
->partial_bsrp_list
->count
&& !uj
)
3282 vty_out(vty
, "Partial List is empty\n");
3290 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3291 json
, JSON_C_TO_STRING_PRETTY
));
3292 json_object_free(json
);
3296 /* pim statistics - just adding only bsm related now.
3297 * We can continue to add all pim related stats here.
3299 static void pim_show_statistics(struct pim_instance
*pim
, struct vty
*vty
,
3300 const char *ifname
, bool uj
)
3302 json_object
*json
= NULL
;
3303 struct interface
*ifp
;
3306 json
= json_object_new_object();
3307 json_object_int_add(json
, "Number of Received BSMs",
3309 json_object_int_add(json
, "Number of Forwared BSMs",
3311 json_object_int_add(json
, "Number of Dropped BSMs",
3314 vty_out(vty
, "BSM Statistics :\n");
3315 vty_out(vty
, "----------------\n");
3316 vty_out(vty
, "Number of Received BSMs : %" PRIu64
"\n",
3318 vty_out(vty
, "Number of Forwared BSMs : %" PRIu64
"\n",
3320 vty_out(vty
, "Number of Dropped BSMs : %" PRIu64
"\n",
3326 /* scan interfaces */
3327 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3328 struct pim_interface
*pim_ifp
= ifp
->info
;
3330 if (ifname
&& strcmp(ifname
, ifp
->name
))
3337 vty_out(vty
, "Interface : %s\n", ifp
->name
);
3338 vty_out(vty
, "-------------------\n");
3340 "Number of BSMs dropped due to config miss : %u\n",
3341 pim_ifp
->pim_ifstat_bsm_cfg_miss
);
3342 vty_out(vty
, "Number of unicast BSMs dropped : %u\n",
3343 pim_ifp
->pim_ifstat_ucast_bsm_cfg_miss
);
3345 "Number of BSMs dropped due to invalid scope zone : %u\n",
3346 pim_ifp
->pim_ifstat_bsm_invalid_sz
);
3349 json_object
*json_row
= NULL
;
3351 json_row
= json_object_new_object();
3353 json_object_string_add(json_row
, "If Name", ifp
->name
);
3354 json_object_int_add(
3356 "Number of BSMs dropped due to config miss",
3357 pim_ifp
->pim_ifstat_bsm_cfg_miss
);
3358 json_object_int_add(
3359 json_row
, "Number of unicast BSMs dropped",
3360 pim_ifp
->pim_ifstat_ucast_bsm_cfg_miss
);
3361 json_object_int_add(json_row
,
3362 "Number of BSMs dropped due to invalid scope zone",
3363 pim_ifp
->pim_ifstat_bsm_invalid_sz
);
3364 json_object_object_add(json
, ifp
->name
, json_row
);
3370 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3371 json
, JSON_C_TO_STRING_PRETTY
));
3372 json_object_free(json
);
3376 static void clear_pim_statistics(struct pim_instance
*pim
)
3378 struct interface
*ifp
;
3382 pim
->bsm_dropped
= 0;
3384 /* scan interfaces */
3385 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3386 struct pim_interface
*pim_ifp
= ifp
->info
;
3391 pim_ifp
->pim_ifstat_bsm_cfg_miss
= 0;
3392 pim_ifp
->pim_ifstat_ucast_bsm_cfg_miss
= 0;
3393 pim_ifp
->pim_ifstat_bsm_invalid_sz
= 0;
3397 static void igmp_show_groups(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
3399 struct interface
*ifp
;
3401 json_object
*json
= NULL
;
3402 json_object
*json_iface
= NULL
;
3403 json_object
*json_row
= NULL
;
3405 now
= pim_time_monotonic_sec();
3408 json
= json_object_new_object();
3411 "Interface Address Group Mode Timer Srcs V Uptime \n");
3413 /* scan interfaces */
3414 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3415 struct pim_interface
*pim_ifp
= ifp
->info
;
3416 struct listnode
*sock_node
;
3417 struct igmp_sock
*igmp
;
3422 /* scan igmp sockets */
3423 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3425 char ifaddr_str
[INET_ADDRSTRLEN
];
3426 struct listnode
*grpnode
;
3427 struct igmp_group
*grp
;
3429 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3430 sizeof(ifaddr_str
));
3432 /* scan igmp groups */
3433 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3435 char group_str
[INET_ADDRSTRLEN
];
3439 pim_inet4_dump("<group?>", grp
->group_addr
,
3440 group_str
, sizeof(group_str
));
3441 pim_time_timer_to_hhmmss(hhmmss
, sizeof(hhmmss
),
3442 grp
->t_group_timer
);
3443 pim_time_uptime(uptime
, sizeof(uptime
),
3444 now
- grp
->group_creation
);
3447 json_object_object_get_ex(
3448 json
, ifp
->name
, &json_iface
);
3452 json_object_new_object();
3453 json_object_pim_ifp_add(
3455 json_object_object_add(
3460 json_row
= json_object_new_object();
3461 json_object_string_add(
3462 json_row
, "source", ifaddr_str
);
3463 json_object_string_add(
3464 json_row
, "group", group_str
);
3466 if (grp
->igmp_version
== 3)
3467 json_object_string_add(
3469 grp
->group_filtermode_isexcl
3473 json_object_string_add(json_row
,
3475 json_object_int_add(
3476 json_row
, "sourcesCount",
3477 grp
->group_source_list
3479 grp
->group_source_list
)
3481 json_object_int_add(json_row
, "version",
3483 json_object_string_add(
3484 json_row
, "uptime", uptime
);
3485 json_object_object_add(json_iface
,
3491 "%-16s %-15s %-15s %4s %8s %4d %d %8s\n",
3492 ifp
->name
, ifaddr_str
,
3494 grp
->igmp_version
== 3
3495 ? (grp
->group_filtermode_isexcl
3500 grp
->group_source_list
3502 grp
->group_source_list
)
3504 grp
->igmp_version
, uptime
);
3506 } /* scan igmp groups */
3507 } /* scan igmp sockets */
3508 } /* scan interfaces */
3511 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3512 json
, JSON_C_TO_STRING_PRETTY
));
3513 json_object_free(json
);
3517 static void igmp_show_group_retransmission(struct pim_instance
*pim
,
3520 struct interface
*ifp
;
3523 "Interface Address Group RetTimer Counter RetSrcs\n");
3525 /* scan interfaces */
3526 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3527 struct pim_interface
*pim_ifp
= ifp
->info
;
3528 struct listnode
*sock_node
;
3529 struct igmp_sock
*igmp
;
3534 /* scan igmp sockets */
3535 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3537 char ifaddr_str
[INET_ADDRSTRLEN
];
3538 struct listnode
*grpnode
;
3539 struct igmp_group
*grp
;
3541 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3542 sizeof(ifaddr_str
));
3544 /* scan igmp groups */
3545 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3547 char group_str
[INET_ADDRSTRLEN
];
3548 char grp_retr_mmss
[10];
3549 struct listnode
*src_node
;
3550 struct igmp_source
*src
;
3551 int grp_retr_sources
= 0;
3553 pim_inet4_dump("<group?>", grp
->group_addr
,
3554 group_str
, sizeof(group_str
));
3555 pim_time_timer_to_mmss(
3556 grp_retr_mmss
, sizeof(grp_retr_mmss
),
3557 grp
->t_group_query_retransmit_timer
);
3560 /* count group sources with retransmission state
3562 for (ALL_LIST_ELEMENTS_RO(
3563 grp
->group_source_list
, src_node
,
3565 if (src
->source_query_retransmit_count
3571 vty_out(vty
, "%-16s %-15s %-15s %-8s %7d %7d\n",
3572 ifp
->name
, ifaddr_str
, group_str
,
3574 grp
->group_specific_query_retransmit_count
,
3577 } /* scan igmp groups */
3578 } /* scan igmp sockets */
3579 } /* scan interfaces */
3582 static void igmp_show_sources(struct pim_instance
*pim
, struct vty
*vty
)
3584 struct interface
*ifp
;
3587 now
= pim_time_monotonic_sec();
3590 "Interface Address Group Source Timer Fwd Uptime \n");
3592 /* scan interfaces */
3593 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3594 struct pim_interface
*pim_ifp
= ifp
->info
;
3595 struct listnode
*sock_node
;
3596 struct igmp_sock
*igmp
;
3601 /* scan igmp sockets */
3602 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3604 char ifaddr_str
[INET_ADDRSTRLEN
];
3605 struct listnode
*grpnode
;
3606 struct igmp_group
*grp
;
3608 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3609 sizeof(ifaddr_str
));
3611 /* scan igmp groups */
3612 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3614 char group_str
[INET_ADDRSTRLEN
];
3615 struct listnode
*srcnode
;
3616 struct igmp_source
*src
;
3618 pim_inet4_dump("<group?>", grp
->group_addr
,
3619 group_str
, sizeof(group_str
));
3621 /* scan group sources */
3622 for (ALL_LIST_ELEMENTS_RO(
3623 grp
->group_source_list
, srcnode
,
3625 char source_str
[INET_ADDRSTRLEN
];
3630 "<source?>", src
->source_addr
,
3631 source_str
, sizeof(source_str
));
3633 pim_time_timer_to_mmss(
3635 src
->t_source_timer
);
3638 uptime
, sizeof(uptime
),
3639 now
- src
->source_creation
);
3642 "%-16s %-15s %-15s %-15s %5s %3s %8s\n",
3643 ifp
->name
, ifaddr_str
,
3644 group_str
, source_str
, mmss
,
3645 IGMP_SOURCE_TEST_FORWARDING(
3651 } /* scan group sources */
3652 } /* scan igmp groups */
3653 } /* scan igmp sockets */
3654 } /* scan interfaces */
3657 static void igmp_show_source_retransmission(struct pim_instance
*pim
,
3660 struct interface
*ifp
;
3663 "Interface Address Group Source Counter\n");
3665 /* scan interfaces */
3666 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3667 struct pim_interface
*pim_ifp
= ifp
->info
;
3668 struct listnode
*sock_node
;
3669 struct igmp_sock
*igmp
;
3674 /* scan igmp sockets */
3675 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3677 char ifaddr_str
[INET_ADDRSTRLEN
];
3678 struct listnode
*grpnode
;
3679 struct igmp_group
*grp
;
3681 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3682 sizeof(ifaddr_str
));
3684 /* scan igmp groups */
3685 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3687 char group_str
[INET_ADDRSTRLEN
];
3688 struct listnode
*srcnode
;
3689 struct igmp_source
*src
;
3691 pim_inet4_dump("<group?>", grp
->group_addr
,
3692 group_str
, sizeof(group_str
));
3694 /* scan group sources */
3695 for (ALL_LIST_ELEMENTS_RO(
3696 grp
->group_source_list
, srcnode
,
3698 char source_str
[INET_ADDRSTRLEN
];
3701 "<source?>", src
->source_addr
,
3702 source_str
, sizeof(source_str
));
3705 "%-16s %-15s %-15s %-15s %7d\n",
3706 ifp
->name
, ifaddr_str
,
3707 group_str
, source_str
,
3708 src
->source_query_retransmit_count
);
3710 } /* scan group sources */
3711 } /* scan igmp groups */
3712 } /* scan igmp sockets */
3713 } /* scan interfaces */
3716 static void pim_show_bsr(struct pim_instance
*pim
,
3721 char last_bsm_seen
[10];
3724 char bsr_str
[PREFIX_STRLEN
];
3725 json_object
*json
= NULL
;
3727 vty_out(vty
, "PIMv2 Bootstrap information\n");
3729 if (pim
->global_scope
.current_bsr
.s_addr
== INADDR_ANY
) {
3730 strlcpy(bsr_str
, "0.0.0.0", sizeof(bsr_str
));
3731 pim_time_uptime(uptime
, sizeof(uptime
),
3732 pim
->global_scope
.current_bsr_first_ts
);
3733 pim_time_uptime(last_bsm_seen
, sizeof(last_bsm_seen
),
3734 pim
->global_scope
.current_bsr_last_ts
);
3738 pim_inet4_dump("<bsr?>", pim
->global_scope
.current_bsr
,
3739 bsr_str
, sizeof(bsr_str
));
3740 now
= pim_time_monotonic_sec();
3741 pim_time_uptime(uptime
, sizeof(uptime
),
3742 (now
- pim
->global_scope
.current_bsr_first_ts
));
3743 pim_time_uptime(last_bsm_seen
, sizeof(last_bsm_seen
),
3744 now
- pim
->global_scope
.current_bsr_last_ts
);
3747 switch (pim
->global_scope
.state
) {
3749 strlcpy(bsr_state
, "NO_INFO", sizeof(bsr_state
));
3752 strlcpy(bsr_state
, "ACCEPT_ANY", sizeof(bsr_state
));
3754 case ACCEPT_PREFERRED
:
3755 strlcpy(bsr_state
, "ACCEPT_PREFERRED", sizeof(bsr_state
));
3758 strlcpy(bsr_state
, "", sizeof(bsr_state
));
3762 json
= json_object_new_object();
3763 json_object_string_add(json
, "bsr", bsr_str
);
3764 json_object_int_add(json
, "priority",
3765 pim
->global_scope
.current_bsr_prio
);
3766 json_object_int_add(json
, "fragment_tag",
3767 pim
->global_scope
.bsm_frag_tag
);
3768 json_object_string_add(json
, "state", bsr_state
);
3769 json_object_string_add(json
, "upTime", uptime
);
3770 json_object_string_add(json
, "last_bsm_seen", last_bsm_seen
);
3774 vty_out(vty
, "Current preferred BSR address: %s\n", bsr_str
);
3776 "Priority Fragment-Tag State UpTime\n");
3777 vty_out(vty
, " %-12d %-12d %-13s %7s\n",
3778 pim
->global_scope
.current_bsr_prio
,
3779 pim
->global_scope
.bsm_frag_tag
,
3782 vty_out(vty
, "Last BSM seen: %s\n", last_bsm_seen
);
3786 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3787 json
, JSON_C_TO_STRING_PRETTY
));
3788 json_object_free(json
);
3792 static void clear_igmp_interfaces(struct pim_instance
*pim
)
3794 struct interface
*ifp
;
3796 FOR_ALL_INTERFACES (pim
->vrf
, ifp
)
3797 pim_if_addr_del_all_igmp(ifp
);
3799 FOR_ALL_INTERFACES (pim
->vrf
, ifp
)
3800 pim_if_addr_add_all(ifp
);
3803 static void clear_pim_interfaces(struct pim_instance
*pim
)
3805 struct interface
*ifp
;
3807 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3809 pim_neighbor_delete_all(ifp
, "interface cleared");
3814 static void clear_interfaces(struct pim_instance
*pim
)
3816 clear_igmp_interfaces(pim
);
3817 clear_pim_interfaces(pim
);
3820 #define PIM_GET_PIM_INTERFACE(pim_ifp, ifp) \
3821 pim_ifp = ifp->info; \
3824 "%% Enable PIM and/or IGMP on this interface first\n"); \
3825 return CMD_WARNING_CONFIG_FAILED; \
3828 DEFUN (clear_ip_interfaces
,
3829 clear_ip_interfaces_cmd
,
3830 "clear ip interfaces [vrf NAME]",
3833 "Reset interfaces\n"
3837 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3842 clear_interfaces(vrf
->info
);
3847 DEFUN (clear_ip_igmp_interfaces
,
3848 clear_ip_igmp_interfaces_cmd
,
3849 "clear ip igmp [vrf NAME] interfaces",
3854 "Reset IGMP interfaces\n")
3857 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3862 clear_igmp_interfaces(vrf
->info
);
3867 DEFUN (clear_ip_pim_statistics
,
3868 clear_ip_pim_statistics_cmd
,
3869 "clear ip pim statistics [vrf NAME]",
3874 "Reset PIM statistics\n")
3877 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3882 clear_pim_statistics(vrf
->info
);
3886 static void clear_mroute(struct pim_instance
*pim
)
3888 struct pim_upstream
*up
;
3889 struct interface
*ifp
;
3891 /* scan interfaces */
3892 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3893 struct pim_interface
*pim_ifp
= ifp
->info
;
3894 struct listnode
*sock_node
;
3895 struct igmp_sock
*igmp
;
3896 struct pim_ifchannel
*ch
;
3901 /* deleting all ifchannels */
3902 while (!RB_EMPTY(pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
)) {
3903 ch
= RB_ROOT(pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
);
3905 pim_ifchannel_delete(ch
);
3908 /* clean up all igmp groups */
3909 /* scan igmp sockets */
3910 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3913 struct igmp_group
*grp
;
3915 if (igmp
->igmp_group_list
) {
3916 while (igmp
->igmp_group_list
->count
) {
3917 grp
= listnode_head(
3918 igmp
->igmp_group_list
);
3919 igmp_group_delete(grp
);
3926 /* clean up all upstreams*/
3927 while ((up
= rb_pim_upstream_first(&pim
->upstream_head
))) {
3928 pim_upstream_del(pim
, up
, __PRETTY_FUNCTION__
);
3932 DEFUN (clear_ip_mroute
,
3933 clear_ip_mroute_cmd
,
3934 "clear ip mroute [vrf NAME]",
3937 "Reset multicast routes\n"
3941 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3946 clear_mroute(vrf
->info
);
3951 DEFUN (clear_ip_pim_interfaces
,
3952 clear_ip_pim_interfaces_cmd
,
3953 "clear ip pim [vrf NAME] interfaces",
3958 "Reset PIM interfaces\n")
3961 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3966 clear_pim_interfaces(vrf
->info
);
3971 DEFUN (clear_ip_pim_interface_traffic
,
3972 clear_ip_pim_interface_traffic_cmd
,
3973 "clear ip pim [vrf NAME] interface traffic",
3976 "PIM clear commands\n"
3978 "Reset PIM interfaces\n"
3979 "Reset Protocol Packet counters\n")
3982 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3983 struct interface
*ifp
= NULL
;
3984 struct pim_interface
*pim_ifp
= NULL
;
3989 FOR_ALL_INTERFACES (vrf
, ifp
) {
3990 pim_ifp
= ifp
->info
;
3995 pim_ifp
->pim_ifstat_hello_recv
= 0;
3996 pim_ifp
->pim_ifstat_hello_sent
= 0;
3997 pim_ifp
->pim_ifstat_join_recv
= 0;
3998 pim_ifp
->pim_ifstat_join_send
= 0;
3999 pim_ifp
->pim_ifstat_prune_recv
= 0;
4000 pim_ifp
->pim_ifstat_prune_send
= 0;
4001 pim_ifp
->pim_ifstat_reg_recv
= 0;
4002 pim_ifp
->pim_ifstat_reg_send
= 0;
4003 pim_ifp
->pim_ifstat_reg_stop_recv
= 0;
4004 pim_ifp
->pim_ifstat_reg_stop_send
= 0;
4005 pim_ifp
->pim_ifstat_assert_recv
= 0;
4006 pim_ifp
->pim_ifstat_assert_send
= 0;
4007 pim_ifp
->pim_ifstat_bsm_rx
= 0;
4008 pim_ifp
->pim_ifstat_bsm_tx
= 0;
4014 DEFUN (clear_ip_pim_oil
,
4015 clear_ip_pim_oil_cmd
,
4016 "clear ip pim [vrf NAME] oil",
4021 "Rescan PIM OIL (output interface list)\n")
4024 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4029 pim_scan_oil(vrf
->info
);
4034 DEFUN (show_ip_igmp_interface
,
4035 show_ip_igmp_interface_cmd
,
4036 "show ip igmp [vrf NAME] interface [detail|WORD] [json]",
4041 "IGMP interface information\n"
4047 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4048 bool uj
= use_json(argc
, argv
);
4053 if (argv_find(argv
, argc
, "detail", &idx
)
4054 || argv_find(argv
, argc
, "WORD", &idx
))
4055 igmp_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
4057 igmp_show_interfaces(vrf
->info
, vty
, uj
);
4062 DEFUN (show_ip_igmp_interface_vrf_all
,
4063 show_ip_igmp_interface_vrf_all_cmd
,
4064 "show ip igmp vrf all interface [detail|WORD] [json]",
4069 "IGMP interface information\n"
4075 bool uj
= use_json(argc
, argv
);
4081 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4085 vty_out(vty
, " \"%s\": ", vrf
->name
);
4088 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4089 if (argv_find(argv
, argc
, "detail", &idx
)
4090 || argv_find(argv
, argc
, "WORD", &idx
))
4091 igmp_show_interfaces_single(vrf
->info
, vty
,
4092 argv
[idx
]->arg
, uj
);
4094 igmp_show_interfaces(vrf
->info
, vty
, uj
);
4097 vty_out(vty
, "}\n");
4102 DEFUN (show_ip_igmp_join
,
4103 show_ip_igmp_join_cmd
,
4104 "show ip igmp [vrf NAME] join",
4109 "IGMP static join information\n")
4112 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4117 igmp_show_interface_join(vrf
->info
, vty
);
4122 DEFUN (show_ip_igmp_join_vrf_all
,
4123 show_ip_igmp_join_vrf_all_cmd
,
4124 "show ip igmp vrf all join",
4129 "IGMP static join information\n")
4131 bool uj
= use_json(argc
, argv
);
4137 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4141 vty_out(vty
, " \"%s\": ", vrf
->name
);
4144 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4145 igmp_show_interface_join(vrf
->info
, vty
);
4148 vty_out(vty
, "}\n");
4153 DEFUN (show_ip_igmp_groups
,
4154 show_ip_igmp_groups_cmd
,
4155 "show ip igmp [vrf NAME] groups [json]",
4164 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4165 bool uj
= use_json(argc
, argv
);
4170 igmp_show_groups(vrf
->info
, vty
, uj
);
4175 DEFUN (show_ip_igmp_groups_vrf_all
,
4176 show_ip_igmp_groups_vrf_all_cmd
,
4177 "show ip igmp vrf all groups [json]",
4185 bool uj
= use_json(argc
, argv
);
4191 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4195 vty_out(vty
, " \"%s\": ", vrf
->name
);
4198 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4199 igmp_show_groups(vrf
->info
, vty
, uj
);
4202 vty_out(vty
, "}\n");
4207 DEFUN (show_ip_igmp_groups_retransmissions
,
4208 show_ip_igmp_groups_retransmissions_cmd
,
4209 "show ip igmp [vrf NAME] groups retransmissions",
4215 "IGMP group retransmissions\n")
4218 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4223 igmp_show_group_retransmission(vrf
->info
, vty
);
4228 DEFUN (show_ip_igmp_sources
,
4229 show_ip_igmp_sources_cmd
,
4230 "show ip igmp [vrf NAME] sources",
4238 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4243 igmp_show_sources(vrf
->info
, vty
);
4248 DEFUN (show_ip_igmp_sources_retransmissions
,
4249 show_ip_igmp_sources_retransmissions_cmd
,
4250 "show ip igmp [vrf NAME] sources retransmissions",
4256 "IGMP source retransmissions\n")
4259 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4264 igmp_show_source_retransmission(vrf
->info
, vty
);
4269 DEFUN (show_ip_igmp_statistics
,
4270 show_ip_igmp_statistics_cmd
,
4271 "show ip igmp [vrf NAME] statistics [interface WORD] [json]",
4282 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4283 bool uj
= use_json(argc
, argv
);
4288 if (argv_find(argv
, argc
, "WORD", &idx
))
4289 igmp_show_statistics(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
4291 igmp_show_statistics(vrf
->info
, vty
, NULL
, uj
);
4296 DEFUN (show_ip_pim_assert
,
4297 show_ip_pim_assert_cmd
,
4298 "show ip pim [vrf NAME] assert",
4303 "PIM interface assert\n")
4306 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4311 pim_show_assert(vrf
->info
, vty
);
4316 DEFUN (show_ip_pim_assert_internal
,
4317 show_ip_pim_assert_internal_cmd
,
4318 "show ip pim [vrf NAME] assert-internal",
4323 "PIM interface internal assert state\n")
4326 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4331 pim_show_assert_internal(vrf
->info
, vty
);
4336 DEFUN (show_ip_pim_assert_metric
,
4337 show_ip_pim_assert_metric_cmd
,
4338 "show ip pim [vrf NAME] assert-metric",
4343 "PIM interface assert metric\n")
4346 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4351 pim_show_assert_metric(vrf
->info
, vty
);
4356 DEFUN (show_ip_pim_assert_winner_metric
,
4357 show_ip_pim_assert_winner_metric_cmd
,
4358 "show ip pim [vrf NAME] assert-winner-metric",
4363 "PIM interface assert winner metric\n")
4366 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4371 pim_show_assert_winner_metric(vrf
->info
, vty
);
4376 DEFUN (show_ip_pim_interface
,
4377 show_ip_pim_interface_cmd
,
4378 "show ip pim [vrf NAME] interface [detail|WORD] [json]",
4383 "PIM interface information\n"
4389 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4390 bool uj
= use_json(argc
, argv
);
4395 if (argv_find(argv
, argc
, "WORD", &idx
)
4396 || argv_find(argv
, argc
, "detail", &idx
))
4397 pim_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
4399 pim_show_interfaces(vrf
->info
, vty
, uj
);
4404 DEFUN (show_ip_pim_interface_vrf_all
,
4405 show_ip_pim_interface_vrf_all_cmd
,
4406 "show ip pim vrf all interface [detail|WORD] [json]",
4411 "PIM interface information\n"
4417 bool uj
= use_json(argc
, argv
);
4423 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4427 vty_out(vty
, " \"%s\": ", vrf
->name
);
4430 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4431 if (argv_find(argv
, argc
, "WORD", &idx
)
4432 || argv_find(argv
, argc
, "detail", &idx
))
4433 pim_show_interfaces_single(vrf
->info
, vty
,
4434 argv
[idx
]->arg
, uj
);
4436 pim_show_interfaces(vrf
->info
, vty
, uj
);
4439 vty_out(vty
, "}\n");
4444 DEFPY (show_ip_pim_join
,
4445 show_ip_pim_join_cmd
,
4446 "show ip pim [vrf NAME] join [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
4451 "PIM interface join information\n"
4452 "The Source or Group\n"
4456 struct prefix_sg sg
= {0};
4459 struct pim_instance
*pim
;
4461 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
4464 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
4467 pim
= pim_get_pim_instance(v
->vrf_id
);
4470 vty_out(vty
, "%% Unable to find pim instance\n");
4474 if (s_or_g
.s_addr
!= 0) {
4475 if (g
.s_addr
!= 0) {
4482 pim_show_join(pim
, vty
, &sg
, uj
);
4487 DEFUN (show_ip_pim_join_vrf_all
,
4488 show_ip_pim_join_vrf_all_cmd
,
4489 "show ip pim vrf all join [json]",
4494 "PIM interface join information\n"
4497 struct prefix_sg sg
= {0};
4498 bool uj
= use_json(argc
, argv
);
4504 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4508 vty_out(vty
, " \"%s\": ", vrf
->name
);
4511 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4512 pim_show_join(vrf
->info
, vty
, &sg
, uj
);
4515 vty_out(vty
, "}\n");
4520 static void pim_show_jp_agg_helper(struct vty
*vty
,
4521 struct interface
*ifp
,
4522 struct pim_neighbor
*neigh
,
4523 struct pim_upstream
*up
,
4526 char src_str
[INET_ADDRSTRLEN
];
4527 char grp_str
[INET_ADDRSTRLEN
];
4528 char rpf_str
[INET_ADDRSTRLEN
];
4530 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
4531 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
4532 /* pius->address.s_addr */
4533 pim_inet4_dump("<rpf?>", neigh
->source_addr
, rpf_str
, sizeof(rpf_str
));
4535 vty_out(vty
, "%-16s %-15s %-15s %-15s %5s\n",
4536 ifp
->name
, rpf_str
, src_str
,
4537 grp_str
, is_join
?"J":"P");
4540 static void pim_show_jp_agg_list(struct pim_instance
*pim
, struct vty
*vty
)
4542 struct interface
*ifp
;
4543 struct pim_interface
*pim_ifp
;
4544 struct listnode
*n_node
;
4545 struct pim_neighbor
*neigh
;
4546 struct listnode
*jag_node
;
4547 struct pim_jp_agg_group
*jag
;
4548 struct listnode
*js_node
;
4549 struct pim_jp_sources
*js
;
4552 "Interface RPF Nbr Source Group State\n");
4554 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
4555 pim_ifp
= ifp
->info
;
4559 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
,
4561 for (ALL_LIST_ELEMENTS_RO(neigh
->upstream_jp_agg
,
4563 for (ALL_LIST_ELEMENTS_RO(jag
->sources
,
4565 pim_show_jp_agg_helper(vty
,
4574 DEFPY (show_ip_pim_jp_agg
,
4575 show_ip_pim_jp_agg_cmd
,
4576 "show ip pim [vrf NAME] jp-agg",
4581 "join prune aggregation list\n")
4584 struct pim_instance
*pim
;
4586 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
4589 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
4592 pim
= pim_get_pim_instance(v
->vrf_id
);
4595 vty_out(vty
, "%% Unable to find pim instance\n");
4599 pim_show_jp_agg_list(pim
, vty
);
4604 DEFUN (show_ip_pim_local_membership
,
4605 show_ip_pim_local_membership_cmd
,
4606 "show ip pim [vrf NAME] local-membership [json]",
4611 "PIM interface local-membership\n"
4615 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4616 bool uj
= use_json(argc
, argv
);
4621 pim_show_membership(vrf
->info
, vty
, uj
);
4626 DEFUN (show_ip_pim_neighbor
,
4627 show_ip_pim_neighbor_cmd
,
4628 "show ip pim [vrf NAME] neighbor [detail|WORD] [json]",
4633 "PIM neighbor information\n"
4635 "Name of interface or neighbor\n"
4639 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4640 bool uj
= use_json(argc
, argv
);
4645 if (argv_find(argv
, argc
, "detail", &idx
)
4646 || argv_find(argv
, argc
, "WORD", &idx
))
4647 pim_show_neighbors_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
4649 pim_show_neighbors(vrf
->info
, vty
, uj
);
4654 DEFUN (show_ip_pim_neighbor_vrf_all
,
4655 show_ip_pim_neighbor_vrf_all_cmd
,
4656 "show ip pim vrf all neighbor [detail|WORD] [json]",
4661 "PIM neighbor information\n"
4663 "Name of interface or neighbor\n"
4667 bool uj
= use_json(argc
, argv
);
4673 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4677 vty_out(vty
, " \"%s\": ", vrf
->name
);
4680 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4681 if (argv_find(argv
, argc
, "detail", &idx
)
4682 || argv_find(argv
, argc
, "WORD", &idx
))
4683 pim_show_neighbors_single(vrf
->info
, vty
,
4684 argv
[idx
]->arg
, uj
);
4686 pim_show_neighbors(vrf
->info
, vty
, uj
);
4689 vty_out(vty
, "}\n");
4694 DEFUN (show_ip_pim_secondary
,
4695 show_ip_pim_secondary_cmd
,
4696 "show ip pim [vrf NAME] secondary",
4701 "PIM neighbor addresses\n")
4704 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4709 pim_show_neighbors_secondary(vrf
->info
, vty
);
4714 DEFUN (show_ip_pim_state
,
4715 show_ip_pim_state_cmd
,
4716 "show ip pim [vrf NAME] state [A.B.C.D [A.B.C.D]] [json]",
4721 "PIM state information\n"
4722 "Unicast or Multicast address\n"
4723 "Multicast address\n"
4726 const char *src_or_group
= NULL
;
4727 const char *group
= NULL
;
4729 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4730 bool uj
= use_json(argc
, argv
);
4738 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
4739 src_or_group
= argv
[idx
]->arg
;
4741 group
= argv
[idx
+ 1]->arg
;
4744 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
4749 DEFUN (show_ip_pim_state_vrf_all
,
4750 show_ip_pim_state_vrf_all_cmd
,
4751 "show ip pim vrf all state [A.B.C.D [A.B.C.D]] [json]",
4756 "PIM state information\n"
4757 "Unicast or Multicast address\n"
4758 "Multicast address\n"
4761 const char *src_or_group
= NULL
;
4762 const char *group
= NULL
;
4764 bool uj
= use_json(argc
, argv
);
4773 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
4774 src_or_group
= argv
[idx
]->arg
;
4776 group
= argv
[idx
+ 1]->arg
;
4779 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4783 vty_out(vty
, " \"%s\": ", vrf
->name
);
4786 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4787 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
4790 vty_out(vty
, "}\n");
4795 DEFPY (show_ip_pim_upstream
,
4796 show_ip_pim_upstream_cmd
,
4797 "show ip pim [vrf NAME] upstream [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
4802 "PIM upstream information\n"
4803 "The Source or Group\n"
4807 struct prefix_sg sg
= {0};
4810 struct pim_instance
*pim
;
4812 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
4815 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
4818 pim
= pim_get_pim_instance(v
->vrf_id
);
4821 vty_out(vty
, "%% Unable to find pim instance\n");
4825 if (s_or_g
.s_addr
!= 0) {
4826 if (g
.s_addr
!= 0) {
4832 pim_show_upstream(pim
, vty
, &sg
, uj
);
4837 DEFUN (show_ip_pim_upstream_vrf_all
,
4838 show_ip_pim_upstream_vrf_all_cmd
,
4839 "show ip pim vrf all upstream [json]",
4844 "PIM upstream information\n"
4847 struct prefix_sg sg
= {0};
4848 bool uj
= use_json(argc
, argv
);
4854 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4858 vty_out(vty
, " \"%s\": ", vrf
->name
);
4861 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4862 pim_show_upstream(vrf
->info
, vty
, &sg
, uj
);
4868 DEFUN (show_ip_pim_channel
,
4869 show_ip_pim_channel_cmd
,
4870 "show ip pim [vrf NAME] channel [json]",
4875 "PIM downstream channel info\n"
4879 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4880 bool uj
= use_json(argc
, argv
);
4885 pim_show_channel(vrf
->info
, vty
, uj
);
4890 DEFUN (show_ip_pim_upstream_join_desired
,
4891 show_ip_pim_upstream_join_desired_cmd
,
4892 "show ip pim [vrf NAME] upstream-join-desired [json]",
4897 "PIM upstream join-desired\n"
4901 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4902 bool uj
= use_json(argc
, argv
);
4907 pim_show_join_desired(vrf
->info
, vty
, uj
);
4912 DEFUN (show_ip_pim_upstream_rpf
,
4913 show_ip_pim_upstream_rpf_cmd
,
4914 "show ip pim [vrf NAME] upstream-rpf [json]",
4919 "PIM upstream source rpf\n"
4923 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4924 bool uj
= use_json(argc
, argv
);
4929 pim_show_upstream_rpf(vrf
->info
, vty
, uj
);
4934 DEFUN (show_ip_pim_rp
,
4936 "show ip pim [vrf NAME] rp-info [json]",
4941 "PIM RP information\n"
4945 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4946 bool uj
= use_json(argc
, argv
);
4951 pim_rp_show_information(vrf
->info
, vty
, uj
);
4956 DEFUN (show_ip_pim_rp_vrf_all
,
4957 show_ip_pim_rp_vrf_all_cmd
,
4958 "show ip pim vrf all rp-info [json]",
4963 "PIM RP information\n"
4966 bool uj
= use_json(argc
, argv
);
4972 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4976 vty_out(vty
, " \"%s\": ", vrf
->name
);
4979 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4980 pim_rp_show_information(vrf
->info
, vty
, uj
);
4983 vty_out(vty
, "}\n");
4988 DEFUN (show_ip_pim_rpf
,
4989 show_ip_pim_rpf_cmd
,
4990 "show ip pim [vrf NAME] rpf [json]",
4995 "PIM cached source rpf information\n"
4999 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5000 bool uj
= use_json(argc
, argv
);
5005 pim_show_rpf(vrf
->info
, vty
, uj
);
5010 DEFUN (show_ip_pim_rpf_vrf_all
,
5011 show_ip_pim_rpf_vrf_all_cmd
,
5012 "show ip pim vrf all rpf [json]",
5017 "PIM cached source rpf information\n"
5020 bool uj
= use_json(argc
, argv
);
5026 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5030 vty_out(vty
, " \"%s\": ", vrf
->name
);
5033 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5034 pim_show_rpf(vrf
->info
, vty
, uj
);
5037 vty_out(vty
, "}\n");
5042 DEFUN (show_ip_pim_nexthop
,
5043 show_ip_pim_nexthop_cmd
,
5044 "show ip pim [vrf NAME] nexthop",
5049 "PIM cached nexthop rpf information\n")
5052 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5057 pim_show_nexthop(vrf
->info
, vty
);
5062 DEFUN (show_ip_pim_nexthop_lookup
,
5063 show_ip_pim_nexthop_lookup_cmd
,
5064 "show ip pim [vrf NAME] nexthop-lookup A.B.C.D A.B.C.D",
5069 "PIM cached nexthop rpf lookup\n"
5070 "Source/RP address\n"
5071 "Multicast Group address\n")
5073 struct prefix nht_p
;
5075 struct in_addr src_addr
, grp_addr
;
5076 struct in_addr vif_source
;
5077 const char *addr_str
, *addr_str1
;
5079 struct pim_nexthop nexthop
;
5080 char nexthop_addr_str
[PREFIX_STRLEN
];
5081 char grp_str
[PREFIX_STRLEN
];
5083 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5088 argv_find(argv
, argc
, "A.B.C.D", &idx
);
5089 addr_str
= argv
[idx
]->arg
;
5090 result
= inet_pton(AF_INET
, addr_str
, &src_addr
);
5092 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
5093 errno
, safe_strerror(errno
));
5097 if (pim_is_group_224_4(src_addr
)) {
5099 "Invalid argument. Expected Valid Source Address.\n");
5103 addr_str1
= argv
[idx
+ 1]->arg
;
5104 result
= inet_pton(AF_INET
, addr_str1
, &grp_addr
);
5106 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
5107 errno
, safe_strerror(errno
));
5111 if (!pim_is_group_224_4(grp_addr
)) {
5113 "Invalid argument. Expected Valid Multicast Group Address.\n");
5117 if (!pim_rp_set_upstream_addr(vrf
->info
, &vif_source
, src_addr
,
5121 nht_p
.family
= AF_INET
;
5122 nht_p
.prefixlen
= IPV4_MAX_BITLEN
;
5123 nht_p
.u
.prefix4
= vif_source
;
5124 grp
.family
= AF_INET
;
5125 grp
.prefixlen
= IPV4_MAX_BITLEN
;
5126 grp
.u
.prefix4
= grp_addr
;
5127 memset(&nexthop
, 0, sizeof(nexthop
));
5129 result
= pim_ecmp_nexthop_lookup(vrf
->info
, &nexthop
, &nht_p
, &grp
, 0);
5133 "Nexthop Lookup failed, no usable routes returned.\n");
5137 pim_addr_dump("<grp?>", &grp
, grp_str
, sizeof(grp_str
));
5138 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
5139 nexthop_addr_str
, sizeof(nexthop_addr_str
));
5140 vty_out(vty
, "Group %s --- Nexthop %s Interface %s \n", grp_str
,
5141 nexthop_addr_str
, nexthop
.interface
->name
);
5146 DEFUN (show_ip_pim_interface_traffic
,
5147 show_ip_pim_interface_traffic_cmd
,
5148 "show ip pim [vrf NAME] interface traffic [WORD] [json]",
5153 "PIM interface information\n"
5154 "Protocol Packet counters\n"
5159 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5160 bool uj
= use_json(argc
, argv
);
5165 if (argv_find(argv
, argc
, "WORD", &idx
))
5166 pim_show_interface_traffic_single(vrf
->info
, vty
,
5167 argv
[idx
]->arg
, uj
);
5169 pim_show_interface_traffic(vrf
->info
, vty
, uj
);
5174 DEFUN (show_ip_pim_bsm_db
,
5175 show_ip_pim_bsm_db_cmd
,
5176 "show ip pim bsm-database [vrf NAME] [json]",
5180 "PIM cached bsm packets information\n"
5185 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5186 bool uj
= use_json(argc
, argv
);
5191 pim_show_bsm_db(vrf
->info
, vty
, uj
);
5195 DEFUN (show_ip_pim_bsrp
,
5196 show_ip_pim_bsrp_cmd
,
5197 "show ip pim bsrp-info [vrf NAME] [json]",
5201 "PIM cached group-rp mappings information\n"
5206 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5207 bool uj
= use_json(argc
, argv
);
5212 pim_show_group_rp_mappings_info(vrf
->info
, vty
, uj
);
5217 DEFUN (show_ip_pim_statistics
,
5218 show_ip_pim_statistics_cmd
,
5219 "show ip pim [vrf NAME] statistics [interface WORD] [json]",
5230 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5231 bool uj
= use_json(argc
, argv
);
5236 if (argv_find(argv
, argc
, "WORD", &idx
))
5237 pim_show_statistics(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
5239 pim_show_statistics(vrf
->info
, vty
, NULL
, uj
);
5244 static void show_multicast_interfaces(struct pim_instance
*pim
, struct vty
*vty
)
5246 struct interface
*ifp
;
5251 "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut\n");
5253 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
5254 struct pim_interface
*pim_ifp
;
5255 struct in_addr ifaddr
;
5256 struct sioc_vif_req vreq
;
5258 pim_ifp
= ifp
->info
;
5263 memset(&vreq
, 0, sizeof(vreq
));
5264 vreq
.vifi
= pim_ifp
->mroute_vif_index
;
5266 if (ioctl(pim
->mroute_socket
, SIOCGETVIFCNT
, &vreq
)) {
5268 "ioctl(SIOCGETVIFCNT=%lu) failure for interface %s vif_index=%d: errno=%d: %s",
5269 (unsigned long)SIOCGETVIFCNT
, ifp
->name
,
5270 pim_ifp
->mroute_vif_index
, errno
,
5271 safe_strerror(errno
));
5274 ifaddr
= pim_ifp
->primary_address
;
5276 vty_out(vty
, "%-16s %-15s %3d %3d %7lu %7lu %10lu %10lu\n",
5277 ifp
->name
, inet_ntoa(ifaddr
), ifp
->ifindex
,
5278 pim_ifp
->mroute_vif_index
, (unsigned long)vreq
.icount
,
5279 (unsigned long)vreq
.ocount
, (unsigned long)vreq
.ibytes
,
5280 (unsigned long)vreq
.obytes
);
5284 static void pim_cmd_show_ip_multicast_helper(struct pim_instance
*pim
,
5287 struct vrf
*vrf
= pim
->vrf
;
5288 time_t now
= pim_time_monotonic_sec();
5294 vty_out(vty
, "Router MLAG Role: %s\n",
5295 mlag_role2str(router
->role
, mlag_role
, sizeof(mlag_role
)));
5296 vty_out(vty
, "Mroute socket descriptor:");
5298 vty_out(vty
, " %d(%s)\n", pim
->mroute_socket
, vrf
->name
);
5300 pim_time_uptime(uptime
, sizeof(uptime
),
5301 now
- pim
->mroute_socket_creation
);
5302 vty_out(vty
, "Mroute socket uptime: %s\n", uptime
);
5306 pim_zebra_zclient_update(vty
);
5307 pim_zlookup_show_ip_multicast(vty
);
5310 vty_out(vty
, "Maximum highest VifIndex: %d\n", PIM_MAX_USABLE_VIFS
);
5313 vty_out(vty
, "Upstream Join Timer: %d secs\n", router
->t_periodic
);
5314 vty_out(vty
, "Join/Prune Holdtime: %d secs\n", PIM_JP_HOLDTIME
);
5315 vty_out(vty
, "PIM ECMP: %s\n", pim
->ecmp_enable
? "Enable" : "Disable");
5316 vty_out(vty
, "PIM ECMP Rebalance: %s\n",
5317 pim
->ecmp_rebalance_enable
? "Enable" : "Disable");
5321 show_rpf_refresh_stats(vty
, pim
, now
, NULL
);
5325 show_scan_oil_stats(pim
, vty
, now
);
5327 show_multicast_interfaces(pim
, vty
);
5330 DEFUN (show_ip_multicast
,
5331 show_ip_multicast_cmd
,
5332 "show ip multicast [vrf NAME]",
5336 "Multicast global information\n")
5339 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5344 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
5349 DEFUN (show_ip_multicast_vrf_all
,
5350 show_ip_multicast_vrf_all_cmd
,
5351 "show ip multicast vrf all",
5355 "Multicast global information\n")
5357 bool uj
= use_json(argc
, argv
);
5363 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5367 vty_out(vty
, " \"%s\": ", vrf
->name
);
5370 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5371 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
5374 vty_out(vty
, "}\n");
5379 static void show_mroute(struct pim_instance
*pim
, struct vty
*vty
,
5380 struct prefix_sg
*sg
, bool fill
, bool uj
)
5382 struct listnode
*node
;
5383 struct channel_oil
*c_oil
;
5384 struct static_route
*s_route
;
5386 json_object
*json
= NULL
;
5387 json_object
*json_group
= NULL
;
5388 json_object
*json_source
= NULL
;
5389 json_object
*json_oil
= NULL
;
5390 json_object
*json_ifp_out
= NULL
;
5393 char grp_str
[INET_ADDRSTRLEN
];
5394 char src_str
[INET_ADDRSTRLEN
];
5395 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
5396 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
5398 struct interface
*ifp_in
;
5402 json
= json_object_new_object();
5405 "Source Group Proto Input Output TTL Uptime\n");
5408 now
= pim_time_monotonic_sec();
5410 /* print list of PIM and IGMP routes */
5411 frr_each (rb_pim_oil
, &pim
->channel_oil_head
, c_oil
) {
5414 if (!c_oil
->installed
&& !uj
)
5417 if (sg
->grp
.s_addr
!= 0 &&
5418 sg
->grp
.s_addr
!= c_oil
->oil
.mfcc_mcastgrp
.s_addr
)
5420 if (sg
->src
.s_addr
!= 0 &&
5421 sg
->src
.s_addr
!= c_oil
->oil
.mfcc_origin
.s_addr
)
5424 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
5426 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
5428 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
5431 strlcpy(in_ifname
, ifp_in
->name
, sizeof(in_ifname
));
5433 strlcpy(in_ifname
, "<iif?>", sizeof(in_ifname
));
5437 /* Find the group, create it if it doesn't exist */
5438 json_object_object_get_ex(json
, grp_str
, &json_group
);
5441 json_group
= json_object_new_object();
5442 json_object_object_add(json
, grp_str
,
5446 /* Find the source nested under the group, create it if
5447 * it doesn't exist */
5448 json_object_object_get_ex(json_group
, src_str
,
5452 json_source
= json_object_new_object();
5453 json_object_object_add(json_group
, src_str
,
5457 /* Find the inbound interface nested under the source,
5458 * create it if it doesn't exist */
5459 json_object_int_add(json_source
, "installed",
5461 json_object_int_add(json_source
, "refCount",
5462 c_oil
->oil_ref_count
);
5463 json_object_int_add(json_source
, "oilSize",
5465 json_object_int_add(json_source
, "OilInheritedRescan",
5466 c_oil
->oil_inherited_rescan
);
5467 json_object_string_add(json_source
, "iif", in_ifname
);
5471 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
5473 struct interface
*ifp_out
;
5474 char mroute_uptime
[10];
5477 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
5481 /* do not display muted OIFs */
5482 if (c_oil
->oif_flags
[oif_vif_index
]
5483 & PIM_OIF_FLAG_MUTE
)
5486 if (c_oil
->oil
.mfcc_parent
== oif_vif_index
&&
5487 !pim_mroute_allow_iif_in_oil(c_oil
,
5491 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
5493 mroute_uptime
, sizeof(mroute_uptime
),
5494 now
- c_oil
->mroute_creation
);
5498 strlcpy(out_ifname
, ifp_out
->name
, sizeof(out_ifname
));
5500 strlcpy(out_ifname
, "<oif?>", sizeof(out_ifname
));
5503 json_ifp_out
= json_object_new_object();
5504 json_object_string_add(json_ifp_out
, "source",
5506 json_object_string_add(json_ifp_out
, "group",
5509 if (c_oil
->oif_flags
[oif_vif_index
]
5510 & PIM_OIF_FLAG_PROTO_PIM
)
5511 json_object_boolean_true_add(
5512 json_ifp_out
, "protocolPim");
5514 if (c_oil
->oif_flags
[oif_vif_index
]
5515 & PIM_OIF_FLAG_PROTO_IGMP
)
5516 json_object_boolean_true_add(
5517 json_ifp_out
, "protocolIgmp");
5519 if (c_oil
->oif_flags
[oif_vif_index
]
5520 & PIM_OIF_FLAG_PROTO_VXLAN
)
5521 json_object_boolean_true_add(
5522 json_ifp_out
, "protocolVxlan");
5524 if (c_oil
->oif_flags
[oif_vif_index
]
5525 & PIM_OIF_FLAG_PROTO_STAR
)
5526 json_object_boolean_true_add(
5528 "protocolInherited");
5530 json_object_string_add(json_ifp_out
,
5533 json_object_int_add(json_ifp_out
, "iVifI",
5534 c_oil
->oil
.mfcc_parent
);
5535 json_object_string_add(json_ifp_out
,
5536 "outboundInterface",
5538 json_object_int_add(json_ifp_out
, "oVifI",
5540 json_object_int_add(json_ifp_out
, "ttl", ttl
);
5541 json_object_string_add(json_ifp_out
, "upTime",
5544 json_oil
= json_object_new_object();
5545 json_object_object_add(json_source
,
5548 json_object_object_add(json_oil
, out_ifname
,
5551 if (c_oil
->oif_flags
[oif_vif_index
]
5552 & PIM_OIF_FLAG_PROTO_PIM
) {
5553 strlcpy(proto
, "PIM", sizeof(proto
));
5556 if (c_oil
->oif_flags
[oif_vif_index
]
5557 & PIM_OIF_FLAG_PROTO_IGMP
) {
5558 strlcpy(proto
, "IGMP", sizeof(proto
));
5561 if (c_oil
->oif_flags
[oif_vif_index
]
5562 & PIM_OIF_FLAG_PROTO_VXLAN
) {
5563 strlcpy(proto
, "VxLAN", sizeof(proto
));
5566 if (c_oil
->oif_flags
[oif_vif_index
]
5567 & PIM_OIF_FLAG_PROTO_STAR
) {
5568 strlcpy(proto
, "STAR", sizeof(proto
));
5572 "%-15s %-15s %-6s %-16s %-16s %-3d %8s\n",
5573 src_str
, grp_str
, proto
, in_ifname
,
5574 out_ifname
, ttl
, mroute_uptime
);
5579 in_ifname
[0] = '\0';
5585 if (!uj
&& !found_oif
) {
5586 vty_out(vty
, "%-15s %-15s %-6s %-16s %-16s %-3d %8s\n",
5587 src_str
, grp_str
, "none", in_ifname
, "none", 0,
5592 /* Print list of static routes */
5593 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
5596 if (!s_route
->c_oil
.installed
)
5599 pim_inet4_dump("<group?>", s_route
->group
, grp_str
,
5601 pim_inet4_dump("<source?>", s_route
->source
, src_str
,
5603 ifp_in
= pim_if_find_by_vif_index(pim
, s_route
->iif
);
5607 strlcpy(in_ifname
, ifp_in
->name
, sizeof(in_ifname
));
5609 strlcpy(in_ifname
, "<iif?>", sizeof(in_ifname
));
5613 /* Find the group, create it if it doesn't exist */
5614 json_object_object_get_ex(json
, grp_str
, &json_group
);
5617 json_group
= json_object_new_object();
5618 json_object_object_add(json
, grp_str
,
5622 /* Find the source nested under the group, create it if
5623 * it doesn't exist */
5624 json_object_object_get_ex(json_group
, src_str
,
5628 json_source
= json_object_new_object();
5629 json_object_object_add(json_group
, src_str
,
5633 json_object_string_add(json_source
, "iif", in_ifname
);
5636 strlcpy(proto
, "STATIC", sizeof(proto
));
5639 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
5641 struct interface
*ifp_out
;
5642 char oif_uptime
[10];
5645 ttl
= s_route
->oif_ttls
[oif_vif_index
];
5649 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
5651 oif_uptime
, sizeof(oif_uptime
),
5654 .oif_creation
[oif_vif_index
]);
5658 strlcpy(out_ifname
, ifp_out
->name
, sizeof(out_ifname
));
5660 strlcpy(out_ifname
, "<oif?>", sizeof(out_ifname
));
5663 json_ifp_out
= json_object_new_object();
5664 json_object_string_add(json_ifp_out
, "source",
5666 json_object_string_add(json_ifp_out
, "group",
5668 json_object_boolean_true_add(json_ifp_out
,
5670 json_object_string_add(json_ifp_out
,
5673 json_object_int_add(
5674 json_ifp_out
, "iVifI",
5675 s_route
->c_oil
.oil
.mfcc_parent
);
5676 json_object_string_add(json_ifp_out
,
5677 "outboundInterface",
5679 json_object_int_add(json_ifp_out
, "oVifI",
5681 json_object_int_add(json_ifp_out
, "ttl", ttl
);
5682 json_object_string_add(json_ifp_out
, "upTime",
5685 json_oil
= json_object_new_object();
5686 json_object_object_add(json_source
,
5689 json_object_object_add(json_oil
, out_ifname
,
5693 "%-15s %-15s %-6s %-16s %-16s %-3d %8s %s\n",
5694 src_str
, grp_str
, proto
, in_ifname
,
5695 out_ifname
, ttl
, oif_uptime
,
5697 if (first
&& !fill
) {
5700 in_ifname
[0] = '\0';
5706 if (!uj
&& !found_oif
) {
5708 "%-15s %-15s %-6s %-16s %-16s %-3d %8s %s\n",
5709 src_str
, grp_str
, proto
, in_ifname
, "none", 0,
5710 "--:--:--", pim
->vrf
->name
);
5715 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5716 json
, JSON_C_TO_STRING_PRETTY
));
5717 json_object_free(json
);
5721 DEFPY (show_ip_mroute
,
5723 "show ip mroute [vrf NAME] [A.B.C.D$s_or_g [A.B.C.D$g]] [fill$fill] [json$json]",
5728 "The Source or Group\n"
5730 "Fill in Assumed data\n"
5733 struct prefix_sg sg
= {0};
5734 struct pim_instance
*pim
;
5737 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
5740 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
5743 pim
= pim_get_pim_instance(v
->vrf_id
);
5746 vty_out(vty
, "%% Unable to find pim instance\n");
5750 if (s_or_g
.s_addr
!= 0) {
5751 if (g
.s_addr
!= 0) {
5757 show_mroute(pim
, vty
, &sg
, !!fill
, !!json
);
5761 DEFUN (show_ip_mroute_vrf_all
,
5762 show_ip_mroute_vrf_all_cmd
,
5763 "show ip mroute vrf all [fill] [json]",
5768 "Fill in Assumed data\n"
5771 struct prefix_sg sg
= {0};
5772 bool uj
= use_json(argc
, argv
);
5778 if (argv_find(argv
, argc
, "fill", &idx
))
5783 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5787 vty_out(vty
, " \"%s\": ", vrf
->name
);
5790 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5791 show_mroute(vrf
->info
, vty
, &sg
, fill
, uj
);
5794 vty_out(vty
, "}\n");
5799 DEFUN (clear_ip_mroute_count
,
5800 clear_ip_mroute_count_cmd
,
5801 "clear ip mroute [vrf NAME] count",
5806 "Route and packet count data\n")
5809 struct listnode
*node
;
5810 struct channel_oil
*c_oil
;
5811 struct static_route
*sr
;
5812 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5813 struct pim_instance
*pim
;
5819 frr_each(rb_pim_oil
, &pim
->channel_oil_head
, c_oil
) {
5820 if (!c_oil
->installed
)
5823 pim_mroute_update_counters(c_oil
);
5824 c_oil
->cc
.origpktcnt
= c_oil
->cc
.pktcnt
;
5825 c_oil
->cc
.origbytecnt
= c_oil
->cc
.bytecnt
;
5826 c_oil
->cc
.origwrong_if
= c_oil
->cc
.wrong_if
;
5829 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, sr
)) {
5830 if (!sr
->c_oil
.installed
)
5833 pim_mroute_update_counters(&sr
->c_oil
);
5835 sr
->c_oil
.cc
.origpktcnt
= sr
->c_oil
.cc
.pktcnt
;
5836 sr
->c_oil
.cc
.origbytecnt
= sr
->c_oil
.cc
.bytecnt
;
5837 sr
->c_oil
.cc
.origwrong_if
= sr
->c_oil
.cc
.wrong_if
;
5842 static void show_mroute_count(struct pim_instance
*pim
, struct vty
*vty
)
5844 struct listnode
*node
;
5845 struct channel_oil
*c_oil
;
5846 struct static_route
*sr
;
5851 "Source Group LastUsed Packets Bytes WrongIf \n");
5853 /* Print PIM and IGMP route counts */
5854 frr_each (rb_pim_oil
, &pim
->channel_oil_head
, c_oil
) {
5855 char group_str
[INET_ADDRSTRLEN
];
5856 char source_str
[INET_ADDRSTRLEN
];
5858 if (!c_oil
->installed
)
5861 pim_mroute_update_counters(c_oil
);
5863 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, group_str
,
5865 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, source_str
,
5866 sizeof(source_str
));
5868 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
5869 source_str
, group_str
, c_oil
->cc
.lastused
/ 100,
5870 c_oil
->cc
.pktcnt
- c_oil
->cc
.origpktcnt
,
5871 c_oil
->cc
.bytecnt
- c_oil
->cc
.origbytecnt
,
5872 c_oil
->cc
.wrong_if
- c_oil
->cc
.origwrong_if
);
5875 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, sr
)) {
5876 char group_str
[INET_ADDRSTRLEN
];
5877 char source_str
[INET_ADDRSTRLEN
];
5879 if (!sr
->c_oil
.installed
)
5882 pim_mroute_update_counters(&sr
->c_oil
);
5884 pim_inet4_dump("<group?>", sr
->c_oil
.oil
.mfcc_mcastgrp
,
5885 group_str
, sizeof(group_str
));
5886 pim_inet4_dump("<source?>", sr
->c_oil
.oil
.mfcc_origin
,
5887 source_str
, sizeof(source_str
));
5889 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
5890 source_str
, group_str
, sr
->c_oil
.cc
.lastused
,
5891 sr
->c_oil
.cc
.pktcnt
- sr
->c_oil
.cc
.origpktcnt
,
5892 sr
->c_oil
.cc
.bytecnt
- sr
->c_oil
.cc
.origbytecnt
,
5893 sr
->c_oil
.cc
.wrong_if
- sr
->c_oil
.cc
.origwrong_if
);
5897 DEFUN (show_ip_mroute_count
,
5898 show_ip_mroute_count_cmd
,
5899 "show ip mroute [vrf NAME] count",
5904 "Route and packet count data\n")
5907 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5912 show_mroute_count(vrf
->info
, vty
);
5916 DEFUN (show_ip_mroute_count_vrf_all
,
5917 show_ip_mroute_count_vrf_all_cmd
,
5918 "show ip mroute vrf all count",
5923 "Route and packet count data\n")
5925 bool uj
= use_json(argc
, argv
);
5931 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5935 vty_out(vty
, " \"%s\": ", vrf
->name
);
5938 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5939 show_mroute_count(vrf
->info
, vty
);
5942 vty_out(vty
, "}\n");
5947 static void show_mroute_summary(struct pim_instance
*pim
, struct vty
*vty
)
5949 struct listnode
*node
;
5950 struct channel_oil
*c_oil
;
5951 struct static_route
*s_route
;
5952 uint32_t starg_sw_mroute_cnt
= 0;
5953 uint32_t sg_sw_mroute_cnt
= 0;
5954 uint32_t starg_hw_mroute_cnt
= 0;
5955 uint32_t sg_hw_mroute_cnt
= 0;
5957 vty_out(vty
, "Mroute Type Installed/Total\n");
5959 frr_each (rb_pim_oil
, &pim
->channel_oil_head
, c_oil
) {
5960 if (!c_oil
->installed
) {
5961 if (c_oil
->oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
5962 starg_sw_mroute_cnt
++;
5966 if (c_oil
->oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
5967 starg_hw_mroute_cnt
++;
5973 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
5974 if (!s_route
->c_oil
.installed
) {
5975 if (s_route
->c_oil
.oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
5976 starg_sw_mroute_cnt
++;
5980 if (s_route
->c_oil
.oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
5981 starg_hw_mroute_cnt
++;
5987 vty_out(vty
, "%-20s %d/%d\n", "(*, G)", starg_hw_mroute_cnt
,
5988 starg_sw_mroute_cnt
+ starg_hw_mroute_cnt
);
5989 vty_out(vty
, "%-20s %d/%d\n", "(S, G)", sg_hw_mroute_cnt
,
5990 sg_sw_mroute_cnt
+ sg_hw_mroute_cnt
);
5991 vty_out(vty
, "------\n");
5992 vty_out(vty
, "%-20s %d/%d\n", "Total",
5993 (starg_hw_mroute_cnt
+ sg_hw_mroute_cnt
),
5994 (starg_sw_mroute_cnt
+
5995 starg_hw_mroute_cnt
+
6000 DEFUN (show_ip_mroute_summary
,
6001 show_ip_mroute_summary_cmd
,
6002 "show ip mroute [vrf NAME] summary",
6007 "Summary of all mroutes\n")
6010 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6015 show_mroute_summary(vrf
->info
, vty
);
6019 DEFUN (show_ip_mroute_summary_vrf_all
,
6020 show_ip_mroute_summary_vrf_all_cmd
,
6021 "show ip mroute vrf all summary",
6026 "Summary of all mroutes\n")
6030 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
6031 vty_out(vty
, "VRF: %s\n", vrf
->name
);
6032 show_mroute_summary(vrf
->info
, vty
);
6040 "show ip rib [vrf NAME] A.B.C.D",
6045 "Unicast address\n")
6048 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6049 struct in_addr addr
;
6050 const char *addr_str
;
6051 struct pim_nexthop nexthop
;
6052 char nexthop_addr_str
[PREFIX_STRLEN
];
6058 memset(&nexthop
, 0, sizeof(nexthop
));
6059 argv_find(argv
, argc
, "A.B.C.D", &idx
);
6060 addr_str
= argv
[idx
]->arg
;
6061 result
= inet_pton(AF_INET
, addr_str
, &addr
);
6063 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
6064 errno
, safe_strerror(errno
));
6068 if (!pim_nexthop_lookup(vrf
->info
, &nexthop
, addr
, 0)) {
6070 "Failure querying RIB nexthop for unicast address %s\n",
6076 "Address NextHop Interface Metric Preference\n");
6078 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
6079 nexthop_addr_str
, sizeof(nexthop_addr_str
));
6081 vty_out(vty
, "%-15s %-15s %-9s %6d %10d\n", addr_str
, nexthop_addr_str
,
6082 nexthop
.interface
? nexthop
.interface
->name
: "<ifname?>",
6083 nexthop
.mrib_route_metric
, nexthop
.mrib_metric_preference
);
6088 static void show_ssmpingd(struct pim_instance
*pim
, struct vty
*vty
)
6090 struct listnode
*node
;
6091 struct ssmpingd_sock
*ss
;
6095 "Source Socket Address Port Uptime Requests\n");
6097 if (!pim
->ssmpingd_list
)
6100 now
= pim_time_monotonic_sec();
6102 for (ALL_LIST_ELEMENTS_RO(pim
->ssmpingd_list
, node
, ss
)) {
6103 char source_str
[INET_ADDRSTRLEN
];
6105 struct sockaddr_in bind_addr
;
6106 socklen_t len
= sizeof(bind_addr
);
6107 char bind_addr_str
[INET_ADDRSTRLEN
];
6109 pim_inet4_dump("<src?>", ss
->source_addr
, source_str
,
6110 sizeof(source_str
));
6112 if (pim_socket_getsockname(
6113 ss
->sock_fd
, (struct sockaddr
*)&bind_addr
, &len
)) {
6115 "%% Failure reading socket name for ssmpingd source %s on fd=%d\n",
6116 source_str
, ss
->sock_fd
);
6119 pim_inet4_dump("<addr?>", bind_addr
.sin_addr
, bind_addr_str
,
6120 sizeof(bind_addr_str
));
6121 pim_time_uptime(ss_uptime
, sizeof(ss_uptime
),
6122 now
- ss
->creation
);
6124 vty_out(vty
, "%-15s %6d %-15s %5d %8s %8lld\n", source_str
,
6125 ss
->sock_fd
, bind_addr_str
, ntohs(bind_addr
.sin_port
),
6126 ss_uptime
, (long long)ss
->requests
);
6130 DEFUN (show_ip_ssmpingd
,
6131 show_ip_ssmpingd_cmd
,
6132 "show ip ssmpingd [vrf NAME]",
6139 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6144 show_ssmpingd(vrf
->info
, vty
);
6148 static int pim_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
6149 const char *rp
, const char *group
,
6154 result
= pim_rp_new_config(pim
, rp
, group
, plist
);
6156 if (result
== PIM_GROUP_BAD_ADDR_MASK_COMBO
) {
6157 vty_out(vty
, "%% Inconsistent address and mask: %s\n",
6159 return CMD_WARNING_CONFIG_FAILED
;
6162 if (result
== PIM_GROUP_BAD_ADDRESS
) {
6163 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
6164 return CMD_WARNING_CONFIG_FAILED
;
6167 if (result
== PIM_RP_BAD_ADDRESS
) {
6168 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
6169 return CMD_WARNING_CONFIG_FAILED
;
6172 if (result
== PIM_RP_NO_PATH
) {
6173 vty_out(vty
, "%% No Path to RP address specified: %s\n", rp
);
6177 if (result
== PIM_GROUP_OVERLAP
) {
6179 "%% Group range specified cannot exact match another\n");
6180 return CMD_WARNING_CONFIG_FAILED
;
6183 if (result
== PIM_GROUP_PFXLIST_OVERLAP
) {
6185 "%% This group is already covered by a RP prefix-list\n");
6186 return CMD_WARNING_CONFIG_FAILED
;
6189 if (result
== PIM_RP_PFXLIST_IN_USE
) {
6191 "%% The same prefix-list cannot be applied to multiple RPs\n");
6192 return CMD_WARNING_CONFIG_FAILED
;
6198 static int pim_cmd_spt_switchover(struct pim_instance
*pim
,
6199 enum pim_spt_switchover spt
,
6202 pim
->spt
.switchover
= spt
;
6204 switch (pim
->spt
.switchover
) {
6205 case PIM_SPT_IMMEDIATE
:
6206 XFREE(MTYPE_PIM_SPT_PLIST_NAME
, pim
->spt
.plist
);
6208 pim_upstream_add_lhr_star_pimreg(pim
);
6210 case PIM_SPT_INFINITY
:
6211 pim_upstream_remove_lhr_star_pimreg(pim
, plist
);
6213 XFREE(MTYPE_PIM_SPT_PLIST_NAME
, pim
->spt
.plist
);
6217 XSTRDUP(MTYPE_PIM_SPT_PLIST_NAME
, plist
);
6224 DEFUN (ip_pim_spt_switchover_infinity
,
6225 ip_pim_spt_switchover_infinity_cmd
,
6226 "ip pim spt-switchover infinity-and-beyond",
6230 "Never switch to SPT Tree\n")
6232 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6233 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, NULL
);
6236 DEFUN (ip_pim_spt_switchover_infinity_plist
,
6237 ip_pim_spt_switchover_infinity_plist_cmd
,
6238 "ip pim spt-switchover infinity-and-beyond prefix-list WORD",
6242 "Never switch to SPT Tree\n"
6243 "Prefix-List to control which groups to switch\n"
6244 "Prefix-List name\n")
6246 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6247 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, argv
[5]->arg
);
6250 DEFUN (no_ip_pim_spt_switchover_infinity
,
6251 no_ip_pim_spt_switchover_infinity_cmd
,
6252 "no ip pim spt-switchover infinity-and-beyond",
6257 "Never switch to SPT Tree\n")
6259 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6260 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
6263 DEFUN (no_ip_pim_spt_switchover_infinity_plist
,
6264 no_ip_pim_spt_switchover_infinity_plist_cmd
,
6265 "no ip pim spt-switchover infinity-and-beyond prefix-list WORD",
6270 "Never switch to SPT Tree\n"
6271 "Prefix-List to control which groups to switch\n"
6272 "Prefix-List name\n")
6274 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6275 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
6278 DEFUN (ip_pim_joinprune_time
,
6279 ip_pim_joinprune_time_cmd
,
6280 "ip pim join-prune-interval (60-600)",
6282 "pim multicast routing\n"
6283 "Join Prune Send Interval\n"
6286 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6287 router
->t_periodic
= atoi(argv
[3]->arg
);
6291 DEFUN (no_ip_pim_joinprune_time
,
6292 no_ip_pim_joinprune_time_cmd
,
6293 "no ip pim join-prune-interval (60-600)",
6296 "pim multicast routing\n"
6297 "Join Prune Send Interval\n"
6300 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6301 router
->t_periodic
= PIM_DEFAULT_T_PERIODIC
;
6305 DEFUN (ip_pim_register_suppress
,
6306 ip_pim_register_suppress_cmd
,
6307 "ip pim register-suppress-time (5-60000)",
6309 "pim multicast routing\n"
6310 "Register Suppress Timer\n"
6313 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6314 router
->register_suppress_time
= atoi(argv
[3]->arg
);
6318 DEFUN (no_ip_pim_register_suppress
,
6319 no_ip_pim_register_suppress_cmd
,
6320 "no ip pim register-suppress-time (5-60000)",
6323 "pim multicast routing\n"
6324 "Register Suppress Timer\n"
6327 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6328 router
->register_suppress_time
= PIM_REGISTER_SUPPRESSION_TIME_DEFAULT
;
6332 DEFUN (ip_pim_rp_keep_alive
,
6333 ip_pim_rp_keep_alive_cmd
,
6334 "ip pim rp keep-alive-timer (31-60000)",
6336 "pim multicast routing\n"
6338 "Keep alive Timer\n"
6341 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6342 pim
->rp_keep_alive_time
= atoi(argv
[4]->arg
);
6346 DEFUN (no_ip_pim_rp_keep_alive
,
6347 no_ip_pim_rp_keep_alive_cmd
,
6348 "no ip pim rp keep-alive-timer (31-60000)",
6351 "pim multicast routing\n"
6353 "Keep alive Timer\n"
6356 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6357 pim
->rp_keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
6361 DEFUN (ip_pim_keep_alive
,
6362 ip_pim_keep_alive_cmd
,
6363 "ip pim keep-alive-timer (31-60000)",
6365 "pim multicast routing\n"
6366 "Keep alive Timer\n"
6369 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6370 pim
->keep_alive_time
= atoi(argv
[3]->arg
);
6374 DEFUN (no_ip_pim_keep_alive
,
6375 no_ip_pim_keep_alive_cmd
,
6376 "no ip pim keep-alive-timer (31-60000)",
6379 "pim multicast routing\n"
6380 "Keep alive Timer\n"
6383 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6384 pim
->keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
6388 DEFUN (ip_pim_packets
,
6390 "ip pim packets (1-100)",
6392 "pim multicast routing\n"
6393 "packets to process at one time per fd\n"
6394 "Number of packets\n")
6396 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6397 router
->packet_process
= atoi(argv
[3]->arg
);
6401 DEFUN (no_ip_pim_packets
,
6402 no_ip_pim_packets_cmd
,
6403 "no ip pim packets (1-100)",
6406 "pim multicast routing\n"
6407 "packets to process at one time per fd\n"
6408 "Number of packets\n")
6410 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6411 router
->packet_process
= PIM_DEFAULT_PACKET_PROCESS
;
6415 DEFUN (ip_pim_v6_secondary
,
6416 ip_pim_v6_secondary_cmd
,
6417 "ip pim send-v6-secondary",
6419 "pim multicast routing\n"
6420 "Send v6 secondary addresses\n")
6422 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6423 pim
->send_v6_secondary
= 1;
6428 DEFUN (no_ip_pim_v6_secondary
,
6429 no_ip_pim_v6_secondary_cmd
,
6430 "no ip pim send-v6-secondary",
6433 "pim multicast routing\n"
6434 "Send v6 secondary addresses\n")
6436 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6437 pim
->send_v6_secondary
= 0;
6444 "ip pim rp A.B.C.D [A.B.C.D/M]",
6446 "pim multicast routing\n"
6448 "ip address of RP\n"
6449 "Group Address range to cover\n")
6451 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6454 if (argc
== (idx_ipv4
+ 1))
6455 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
6458 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
6459 argv
[idx_ipv4
+ 1]->arg
, NULL
);
6462 DEFUN (ip_pim_rp_prefix_list
,
6463 ip_pim_rp_prefix_list_cmd
,
6464 "ip pim rp A.B.C.D prefix-list WORD",
6466 "pim multicast routing\n"
6468 "ip address of RP\n"
6469 "group prefix-list filter\n"
6470 "Name of a prefix-list\n")
6472 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6473 return pim_rp_cmd_worker(pim
, vty
, argv
[3]->arg
, NULL
, argv
[5]->arg
);
6476 static int pim_no_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
6477 const char *rp
, const char *group
,
6480 int result
= pim_rp_del_config(pim
, rp
, group
, plist
);
6482 if (result
== PIM_GROUP_BAD_ADDRESS
) {
6483 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
6484 return CMD_WARNING_CONFIG_FAILED
;
6487 if (result
== PIM_RP_BAD_ADDRESS
) {
6488 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
6489 return CMD_WARNING_CONFIG_FAILED
;
6492 if (result
== PIM_RP_NOT_FOUND
) {
6493 vty_out(vty
, "%% Unable to find specified RP\n");
6494 return CMD_WARNING_CONFIG_FAILED
;
6500 DEFUN (no_ip_pim_rp
,
6502 "no ip pim rp A.B.C.D [A.B.C.D/M]",
6505 "pim multicast routing\n"
6507 "ip address of RP\n"
6508 "Group Address range to cover\n")
6510 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6511 int idx_ipv4
= 4, idx_group
= 0;
6513 if (argv_find(argv
, argc
, "A.B.C.D/M", &idx_group
))
6514 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
6515 argv
[idx_group
]->arg
, NULL
);
6517 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
6521 DEFUN (no_ip_pim_rp_prefix_list
,
6522 no_ip_pim_rp_prefix_list_cmd
,
6523 "no ip pim rp A.B.C.D prefix-list WORD",
6526 "pim multicast routing\n"
6528 "ip address of RP\n"
6529 "group prefix-list filter\n"
6530 "Name of a prefix-list\n")
6532 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6533 return pim_no_rp_cmd_worker(pim
, vty
, argv
[4]->arg
, NULL
, argv
[6]->arg
);
6536 static int pim_ssm_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
6539 int result
= pim_ssm_range_set(pim
, pim
->vrf_id
, plist
);
6540 int ret
= CMD_WARNING_CONFIG_FAILED
;
6542 if (result
== PIM_SSM_ERR_NONE
)
6546 case PIM_SSM_ERR_NO_VRF
:
6547 vty_out(vty
, "%% VRF doesn't exist\n");
6549 case PIM_SSM_ERR_DUP
:
6550 vty_out(vty
, "%% duplicate config\n");
6554 vty_out(vty
, "%% ssm range config failed\n");
6560 DEFUN (ip_pim_ssm_prefix_list
,
6561 ip_pim_ssm_prefix_list_cmd
,
6562 "ip pim ssm prefix-list WORD",
6564 "pim multicast routing\n"
6565 "Source Specific Multicast\n"
6566 "group range prefix-list filter\n"
6567 "Name of a prefix-list\n")
6569 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6570 return pim_ssm_cmd_worker(pim
, vty
, argv
[4]->arg
);
6573 DEFUN (no_ip_pim_ssm_prefix_list
,
6574 no_ip_pim_ssm_prefix_list_cmd
,
6575 "no ip pim ssm prefix-list",
6578 "pim multicast routing\n"
6579 "Source Specific Multicast\n"
6580 "group range prefix-list filter\n")
6582 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6583 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
6586 DEFUN (no_ip_pim_ssm_prefix_list_name
,
6587 no_ip_pim_ssm_prefix_list_name_cmd
,
6588 "no ip pim ssm prefix-list WORD",
6591 "pim multicast routing\n"
6592 "Source Specific Multicast\n"
6593 "group range prefix-list filter\n"
6594 "Name of a prefix-list\n")
6596 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6597 struct pim_ssm
*ssm
= pim
->ssm_info
;
6599 if (ssm
->plist_name
&& !strcmp(ssm
->plist_name
, argv
[5]->arg
))
6600 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
6602 vty_out(vty
, "%% pim ssm prefix-list %s doesn't exist\n", argv
[5]->arg
);
6604 return CMD_WARNING_CONFIG_FAILED
;
6607 static void ip_pim_ssm_show_group_range(struct pim_instance
*pim
,
6608 struct vty
*vty
, bool uj
)
6610 struct pim_ssm
*ssm
= pim
->ssm_info
;
6611 const char *range_str
=
6612 ssm
->plist_name
? ssm
->plist_name
: PIM_SSM_STANDARD_RANGE
;
6616 json
= json_object_new_object();
6617 json_object_string_add(json
, "ssmGroups", range_str
);
6618 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
6619 json
, JSON_C_TO_STRING_PRETTY
));
6620 json_object_free(json
);
6622 vty_out(vty
, "SSM group range : %s\n", range_str
);
6625 DEFUN (show_ip_pim_ssm_range
,
6626 show_ip_pim_ssm_range_cmd
,
6627 "show ip pim [vrf NAME] group-type [json]",
6636 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6637 bool uj
= use_json(argc
, argv
);
6642 ip_pim_ssm_show_group_range(vrf
->info
, vty
, uj
);
6647 static void ip_pim_ssm_show_group_type(struct pim_instance
*pim
,
6648 struct vty
*vty
, bool uj
,
6651 struct in_addr group_addr
;
6652 const char *type_str
;
6655 result
= inet_pton(AF_INET
, group
, &group_addr
);
6657 type_str
= "invalid";
6659 if (pim_is_group_224_4(group_addr
))
6661 pim_is_grp_ssm(pim
, group_addr
) ? "SSM" : "ASM";
6663 type_str
= "not-multicast";
6668 json
= json_object_new_object();
6669 json_object_string_add(json
, "groupType", type_str
);
6670 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
6671 json
, JSON_C_TO_STRING_PRETTY
));
6672 json_object_free(json
);
6674 vty_out(vty
, "Group type : %s\n", type_str
);
6677 DEFUN (show_ip_pim_group_type
,
6678 show_ip_pim_group_type_cmd
,
6679 "show ip pim [vrf NAME] group-type A.B.C.D [json]",
6684 "multicast group type\n"
6689 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6690 bool uj
= use_json(argc
, argv
);
6695 argv_find(argv
, argc
, "A.B.C.D", &idx
);
6696 ip_pim_ssm_show_group_type(vrf
->info
, vty
, uj
, argv
[idx
]->arg
);
6701 DEFUN (show_ip_pim_bsr
,
6702 show_ip_pim_bsr_cmd
,
6703 "show ip pim bsr [json]",
6707 "boot-strap router information\n"
6711 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6712 bool uj
= use_json(argc
, argv
);
6717 pim_show_bsr(vrf
->info
, vty
, uj
);
6724 "ip ssmpingd [A.B.C.D]",
6729 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6732 struct in_addr source_addr
;
6733 const char *source_str
= (argc
== 3) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
6735 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
6737 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
6738 source_str
, errno
, safe_strerror(errno
));
6739 return CMD_WARNING_CONFIG_FAILED
;
6742 result
= pim_ssmpingd_start(pim
, source_addr
);
6744 vty_out(vty
, "%% Failure starting ssmpingd for source %s: %d\n",
6745 source_str
, result
);
6746 return CMD_WARNING_CONFIG_FAILED
;
6752 DEFUN (no_ip_ssmpingd
,
6754 "no ip ssmpingd [A.B.C.D]",
6760 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6763 struct in_addr source_addr
;
6764 const char *source_str
= (argc
== 4) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
6766 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
6768 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
6769 source_str
, errno
, safe_strerror(errno
));
6770 return CMD_WARNING_CONFIG_FAILED
;
6773 result
= pim_ssmpingd_stop(pim
, source_addr
);
6775 vty_out(vty
, "%% Failure stopping ssmpingd for source %s: %d\n",
6776 source_str
, result
);
6777 return CMD_WARNING_CONFIG_FAILED
;
6787 "pim multicast routing\n"
6788 "Enable PIM ECMP \n")
6790 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6791 pim
->ecmp_enable
= true;
6796 DEFUN (no_ip_pim_ecmp
,
6801 "pim multicast routing\n"
6802 "Disable PIM ECMP \n")
6804 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6805 pim
->ecmp_enable
= false;
6810 DEFUN (ip_pim_ecmp_rebalance
,
6811 ip_pim_ecmp_rebalance_cmd
,
6812 "ip pim ecmp rebalance",
6814 "pim multicast routing\n"
6815 "Enable PIM ECMP \n"
6816 "Enable PIM ECMP Rebalance\n")
6818 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6819 pim
->ecmp_enable
= true;
6820 pim
->ecmp_rebalance_enable
= true;
6825 DEFUN (no_ip_pim_ecmp_rebalance
,
6826 no_ip_pim_ecmp_rebalance_cmd
,
6827 "no ip pim ecmp rebalance",
6830 "pim multicast routing\n"
6831 "Disable PIM ECMP \n"
6832 "Disable PIM ECMP Rebalance\n")
6834 PIM_DECLVAR_CONTEXT(vrf
, pim
);
6835 pim
->ecmp_rebalance_enable
= false;
6840 static int pim_cmd_igmp_start(struct vty
*vty
, struct interface
*ifp
)
6842 struct pim_interface
*pim_ifp
;
6843 uint8_t need_startup
= 0;
6845 pim_ifp
= ifp
->info
;
6848 (void)pim_if_new(ifp
, true, false, false, false);
6851 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
6852 PIM_IF_DO_IGMP(pim_ifp
->options
);
6857 /* 'ip igmp' executed multiple times, with need_startup
6858 avoid multiple if add all and membership refresh */
6860 pim_if_addr_add_all(ifp
);
6861 pim_if_membership_refresh(ifp
);
6867 DEFUN (interface_ip_igmp
,
6868 interface_ip_igmp_cmd
,
6873 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6875 return pim_cmd_igmp_start(vty
, ifp
);
6878 DEFUN (interface_no_ip_igmp
,
6879 interface_no_ip_igmp_cmd
,
6885 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6886 struct pim_interface
*pim_ifp
= ifp
->info
;
6891 PIM_IF_DONT_IGMP(pim_ifp
->options
);
6893 pim_if_membership_clear(ifp
);
6895 pim_if_addr_del_all_igmp(ifp
);
6897 if (!PIM_IF_TEST_PIM(pim_ifp
->options
)) {
6904 DEFUN (interface_ip_igmp_join
,
6905 interface_ip_igmp_join_cmd
,
6906 "ip igmp join A.B.C.D [A.B.C.D]",
6909 "IGMP join multicast group\n"
6910 "Multicast group address\n"
6913 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6916 const char *group_str
;
6917 const char *source_str
;
6918 struct in_addr group_addr
;
6919 struct in_addr source_addr
;
6923 group_str
= argv
[idx_ipv4
]->arg
;
6924 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
6926 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
6927 errno
, safe_strerror(errno
));
6928 return CMD_WARNING_CONFIG_FAILED
;
6931 /* Source address */
6932 if (argc
== (idx_ipv4_2
+ 1)) {
6933 source_str
= argv
[idx_ipv4_2
]->arg
;
6934 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
6936 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
6937 source_str
, errno
, safe_strerror(errno
));
6938 return CMD_WARNING_CONFIG_FAILED
;
6940 /* Reject 0.0.0.0. Reserved for any source. */
6941 if (source_addr
.s_addr
== INADDR_ANY
) {
6942 vty_out(vty
, "Bad source address %s\n", source_str
);
6943 return CMD_WARNING_CONFIG_FAILED
;
6946 source_addr
.s_addr
= INADDR_ANY
;
6949 CMD_FERR_RETURN(pim_if_igmp_join_add(ifp
, group_addr
, source_addr
),
6950 "Failure joining IGMP group: $ERR");
6955 DEFUN (interface_no_ip_igmp_join
,
6956 interface_no_ip_igmp_join_cmd
,
6957 "no ip igmp join A.B.C.D [A.B.C.D]",
6961 "IGMP join multicast group\n"
6962 "Multicast group address\n"
6965 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6968 const char *group_str
;
6969 const char *source_str
;
6970 struct in_addr group_addr
;
6971 struct in_addr source_addr
;
6975 group_str
= argv
[idx_ipv4
]->arg
;
6976 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
6978 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
6979 errno
, safe_strerror(errno
));
6980 return CMD_WARNING_CONFIG_FAILED
;
6983 /* Source address */
6984 if (argc
== (idx_ipv4_2
+ 1)) {
6985 source_str
= argv
[idx_ipv4_2
]->arg
;
6986 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
6988 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
6989 source_str
, errno
, safe_strerror(errno
));
6990 return CMD_WARNING_CONFIG_FAILED
;
6992 /* Reject 0.0.0.0. Reserved for any source. */
6993 if (source_addr
.s_addr
== INADDR_ANY
) {
6994 vty_out(vty
, "Bad source address %s\n", source_str
);
6995 return CMD_WARNING_CONFIG_FAILED
;
6999 source_addr
.s_addr
= INADDR_ANY
;
7002 result
= pim_if_igmp_join_del(ifp
, group_addr
, source_addr
);
7005 "%% Failure leaving IGMP group %s source %s on interface %s: %d\n",
7006 group_str
, source_str
, ifp
->name
, result
);
7007 return CMD_WARNING_CONFIG_FAILED
;
7014 CLI reconfiguration affects the interface level (struct pim_interface).
7015 This function propagates the reconfiguration to every active socket
7018 static void igmp_sock_query_interval_reconfig(struct igmp_sock
*igmp
)
7020 struct interface
*ifp
;
7021 struct pim_interface
*pim_ifp
;
7025 /* other querier present? */
7027 if (igmp
->t_other_querier_timer
)
7030 /* this is the querier */
7032 zassert(igmp
->interface
);
7033 zassert(igmp
->interface
->info
);
7035 ifp
= igmp
->interface
;
7036 pim_ifp
= ifp
->info
;
7038 if (PIM_DEBUG_IGMP_TRACE
) {
7039 char ifaddr_str
[INET_ADDRSTRLEN
];
7040 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
7041 sizeof(ifaddr_str
));
7042 zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
7043 __PRETTY_FUNCTION__
, ifaddr_str
, ifp
->name
,
7044 pim_ifp
->igmp_default_query_interval
);
7048 igmp_startup_mode_on() will reset QQI:
7050 igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
7052 igmp_startup_mode_on(igmp
);
7055 static void igmp_sock_query_reschedule(struct igmp_sock
*igmp
)
7057 if (igmp
->t_igmp_query_timer
) {
7058 /* other querier present */
7059 zassert(igmp
->t_igmp_query_timer
);
7060 zassert(!igmp
->t_other_querier_timer
);
7062 pim_igmp_general_query_off(igmp
);
7063 pim_igmp_general_query_on(igmp
);
7065 zassert(igmp
->t_igmp_query_timer
);
7066 zassert(!igmp
->t_other_querier_timer
);
7068 /* this is the querier */
7070 zassert(!igmp
->t_igmp_query_timer
);
7071 zassert(igmp
->t_other_querier_timer
);
7073 pim_igmp_other_querier_timer_off(igmp
);
7074 pim_igmp_other_querier_timer_on(igmp
);
7076 zassert(!igmp
->t_igmp_query_timer
);
7077 zassert(igmp
->t_other_querier_timer
);
7081 static void change_query_interval(struct pim_interface
*pim_ifp
,
7084 struct listnode
*sock_node
;
7085 struct igmp_sock
*igmp
;
7087 pim_ifp
->igmp_default_query_interval
= query_interval
;
7089 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
7090 igmp_sock_query_interval_reconfig(igmp
);
7091 igmp_sock_query_reschedule(igmp
);
7095 static void change_query_max_response_time(struct pim_interface
*pim_ifp
,
7096 int query_max_response_time_dsec
)
7098 struct listnode
*sock_node
;
7099 struct igmp_sock
*igmp
;
7101 pim_ifp
->igmp_query_max_response_time_dsec
=
7102 query_max_response_time_dsec
;
7105 Below we modify socket/group/source timers in order to quickly
7106 reflect the change. Otherwise, those timers would eventually catch
7110 /* scan all sockets */
7111 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
7112 struct listnode
*grp_node
;
7113 struct igmp_group
*grp
;
7115 /* reschedule socket general query */
7116 igmp_sock_query_reschedule(igmp
);
7118 /* scan socket groups */
7119 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grp_node
,
7121 struct listnode
*src_node
;
7122 struct igmp_source
*src
;
7124 /* reset group timers for groups in EXCLUDE mode */
7125 if (grp
->group_filtermode_isexcl
) {
7126 igmp_group_reset_gmi(grp
);
7129 /* scan group sources */
7130 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
,
7133 /* reset source timers for sources with running
7135 if (src
->t_source_timer
) {
7136 igmp_source_reset_gmi(igmp
, grp
, src
);
7143 #define IGMP_QUERY_INTERVAL_MIN (1)
7144 #define IGMP_QUERY_INTERVAL_MAX (1800)
7146 DEFUN (interface_ip_igmp_query_interval
,
7147 interface_ip_igmp_query_interval_cmd
,
7148 "ip igmp query-interval (1-1800)",
7151 IFACE_IGMP_QUERY_INTERVAL_STR
7152 "Query interval in seconds\n")
7154 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7155 struct pim_interface
*pim_ifp
= ifp
->info
;
7157 int query_interval_dsec
;
7161 ret
= pim_cmd_igmp_start(vty
, ifp
);
7162 if (ret
!= CMD_SUCCESS
)
7164 pim_ifp
= ifp
->info
;
7167 query_interval
= atoi(argv
[3]->arg
);
7168 query_interval_dsec
= 10 * query_interval
;
7171 It seems we don't need to check bounds since command.c does it
7172 already, but we verify them anyway for extra safety.
7174 if (query_interval
< IGMP_QUERY_INTERVAL_MIN
) {
7176 "General query interval %d lower than minimum %d\n",
7177 query_interval
, IGMP_QUERY_INTERVAL_MIN
);
7178 return CMD_WARNING_CONFIG_FAILED
;
7180 if (query_interval
> IGMP_QUERY_INTERVAL_MAX
) {
7182 "General query interval %d higher than maximum %d\n",
7183 query_interval
, IGMP_QUERY_INTERVAL_MAX
);
7184 return CMD_WARNING_CONFIG_FAILED
;
7187 if (query_interval_dsec
<= pim_ifp
->igmp_query_max_response_time_dsec
) {
7189 "Can't set general query interval %d dsec <= query max response time %d dsec.\n",
7190 query_interval_dsec
,
7191 pim_ifp
->igmp_query_max_response_time_dsec
);
7192 return CMD_WARNING_CONFIG_FAILED
;
7195 change_query_interval(pim_ifp
, query_interval
);
7200 DEFUN (interface_no_ip_igmp_query_interval
,
7201 interface_no_ip_igmp_query_interval_cmd
,
7202 "no ip igmp query-interval",
7206 IFACE_IGMP_QUERY_INTERVAL_STR
)
7208 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7209 struct pim_interface
*pim_ifp
= ifp
->info
;
7210 int default_query_interval_dsec
;
7215 default_query_interval_dsec
= IGMP_GENERAL_QUERY_INTERVAL
* 10;
7217 if (default_query_interval_dsec
7218 <= pim_ifp
->igmp_query_max_response_time_dsec
) {
7220 "Can't set default general query interval %d dsec <= query max response time %d dsec.\n",
7221 default_query_interval_dsec
,
7222 pim_ifp
->igmp_query_max_response_time_dsec
);
7223 return CMD_WARNING_CONFIG_FAILED
;
7226 change_query_interval(pim_ifp
, IGMP_GENERAL_QUERY_INTERVAL
);
7231 DEFUN (interface_ip_igmp_version
,
7232 interface_ip_igmp_version_cmd
,
7233 "ip igmp version (2-3)",
7237 "IGMP version number\n")
7239 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7240 struct pim_interface
*pim_ifp
= ifp
->info
;
7241 int igmp_version
, old_version
= 0;
7245 ret
= pim_cmd_igmp_start(vty
, ifp
);
7246 if (ret
!= CMD_SUCCESS
)
7248 pim_ifp
= ifp
->info
;
7251 igmp_version
= atoi(argv
[3]->arg
);
7252 old_version
= pim_ifp
->igmp_version
;
7253 pim_ifp
->igmp_version
= igmp_version
;
7255 // Check if IGMP is Enabled otherwise, enable on interface
7256 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
7257 PIM_IF_DO_IGMP(pim_ifp
->options
);
7258 pim_if_addr_add_all(ifp
);
7259 pim_if_membership_refresh(ifp
);
7260 old_version
= igmp_version
;
7261 // avoid refreshing membership again.
7263 /* Current and new version is different refresh existing
7264 membership. Going from 3 -> 2 or 2 -> 3. */
7265 if (old_version
!= igmp_version
)
7266 pim_if_membership_refresh(ifp
);
7271 DEFUN (interface_no_ip_igmp_version
,
7272 interface_no_ip_igmp_version_cmd
,
7273 "no ip igmp version (2-3)",
7278 "IGMP version number\n")
7280 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7281 struct pim_interface
*pim_ifp
= ifp
->info
;
7286 pim_ifp
->igmp_version
= IGMP_DEFAULT_VERSION
;
7291 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
7292 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
7294 DEFUN (interface_ip_igmp_query_max_response_time
,
7295 interface_ip_igmp_query_max_response_time_cmd
,
7296 "ip igmp query-max-response-time (10-250)",
7299 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
7300 "Query response value in deci-seconds\n")
7302 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7303 struct pim_interface
*pim_ifp
= ifp
->info
;
7304 int query_max_response_time
;
7308 ret
= pim_cmd_igmp_start(vty
, ifp
);
7309 if (ret
!= CMD_SUCCESS
)
7311 pim_ifp
= ifp
->info
;
7314 query_max_response_time
= atoi(argv
[3]->arg
);
7316 if (query_max_response_time
7317 >= pim_ifp
->igmp_default_query_interval
* 10) {
7319 "Can't set query max response time %d sec >= general query interval %d sec\n",
7320 query_max_response_time
,
7321 pim_ifp
->igmp_default_query_interval
);
7322 return CMD_WARNING_CONFIG_FAILED
;
7325 change_query_max_response_time(pim_ifp
, query_max_response_time
);
7330 DEFUN (interface_no_ip_igmp_query_max_response_time
,
7331 interface_no_ip_igmp_query_max_response_time_cmd
,
7332 "no ip igmp query-max-response-time (10-250)",
7336 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
7337 "Time for response in deci-seconds\n")
7339 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7340 struct pim_interface
*pim_ifp
= ifp
->info
;
7345 change_query_max_response_time(pim_ifp
,
7346 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
7351 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
7352 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
7354 DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec
,
7355 interface_ip_igmp_query_max_response_time_dsec_cmd
,
7356 "ip igmp query-max-response-time-dsec (10-250)",
7359 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
7360 "Query response value in deciseconds\n")
7362 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7363 struct pim_interface
*pim_ifp
= ifp
->info
;
7364 int query_max_response_time_dsec
;
7365 int default_query_interval_dsec
;
7369 ret
= pim_cmd_igmp_start(vty
, ifp
);
7370 if (ret
!= CMD_SUCCESS
)
7372 pim_ifp
= ifp
->info
;
7375 query_max_response_time_dsec
= atoi(argv
[4]->arg
);
7377 default_query_interval_dsec
= 10 * pim_ifp
->igmp_default_query_interval
;
7379 if (query_max_response_time_dsec
>= default_query_interval_dsec
) {
7381 "Can't set query max response time %d dsec >= general query interval %d dsec\n",
7382 query_max_response_time_dsec
,
7383 default_query_interval_dsec
);
7384 return CMD_WARNING_CONFIG_FAILED
;
7387 change_query_max_response_time(pim_ifp
, query_max_response_time_dsec
);
7392 DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec
,
7393 interface_no_ip_igmp_query_max_response_time_dsec_cmd
,
7394 "no ip igmp query-max-response-time-dsec",
7398 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
)
7400 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7401 struct pim_interface
*pim_ifp
= ifp
->info
;
7406 change_query_max_response_time(pim_ifp
,
7407 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
7412 #define IGMP_LAST_MEMBER_QUERY_COUNT_MIN (1)
7413 #define IGMP_LAST_MEMBER_QUERY_COUNT_MAX (7)
7415 DEFUN (interface_ip_igmp_last_member_query_count
,
7416 interface_ip_igmp_last_member_query_count_cmd
,
7417 "ip igmp last-member-query-count (1-7)",
7420 IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR
7421 "Last member query count\n")
7423 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7424 struct pim_interface
*pim_ifp
= ifp
->info
;
7425 int last_member_query_count
;
7429 ret
= pim_cmd_igmp_start(vty
, ifp
);
7430 if (ret
!= CMD_SUCCESS
)
7432 pim_ifp
= ifp
->info
;
7435 last_member_query_count
= atoi(argv
[3]->arg
);
7437 pim_ifp
->igmp_last_member_query_count
= last_member_query_count
;
7442 DEFUN (interface_no_ip_igmp_last_member_query_count
,
7443 interface_no_ip_igmp_last_member_query_count_cmd
,
7444 "no ip igmp last-member-query-count",
7448 IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR
)
7450 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7451 struct pim_interface
*pim_ifp
= ifp
->info
;
7456 pim_ifp
->igmp_last_member_query_count
=
7457 IGMP_DEFAULT_ROBUSTNESS_VARIABLE
;
7462 #define IGMP_LAST_MEMBER_QUERY_INTERVAL_MIN (1)
7463 #define IGMP_LAST_MEMBER_QUERY_INTERVAL_MAX (255)
7465 DEFUN (interface_ip_igmp_last_member_query_interval
,
7466 interface_ip_igmp_last_member_query_interval_cmd
,
7467 "ip igmp last-member-query-interval (1-255)",
7470 IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR
7471 "Last member query interval in deciseconds\n")
7473 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7474 struct pim_interface
*pim_ifp
= ifp
->info
;
7475 int last_member_query_interval
;
7479 ret
= pim_cmd_igmp_start(vty
, ifp
);
7480 if (ret
!= CMD_SUCCESS
)
7482 pim_ifp
= ifp
->info
;
7485 last_member_query_interval
= atoi(argv
[3]->arg
);
7486 pim_ifp
->igmp_specific_query_max_response_time_dsec
7487 = last_member_query_interval
;
7492 DEFUN (interface_no_ip_igmp_last_member_query_interval
,
7493 interface_no_ip_igmp_last_member_query_interval_cmd
,
7494 "no ip igmp last-member-query-interval",
7498 IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR
)
7500 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7501 struct pim_interface
*pim_ifp
= ifp
->info
;
7506 pim_ifp
->igmp_specific_query_max_response_time_dsec
=
7507 IGMP_SPECIFIC_QUERY_MAX_RESPONSE_TIME_DSEC
;
7512 DEFUN (interface_ip_pim_drprio
,
7513 interface_ip_pim_drprio_cmd
,
7514 "ip pim drpriority (1-4294967295)",
7517 "Set the Designated Router Election Priority\n"
7518 "Value of the new DR Priority\n")
7520 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7522 struct pim_interface
*pim_ifp
= ifp
->info
;
7523 uint32_t old_dr_prio
;
7526 vty_out(vty
, "Please enable PIM on interface, first\n");
7527 return CMD_WARNING_CONFIG_FAILED
;
7530 old_dr_prio
= pim_ifp
->pim_dr_priority
;
7532 pim_ifp
->pim_dr_priority
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
7534 if (old_dr_prio
!= pim_ifp
->pim_dr_priority
) {
7535 pim_if_dr_election(ifp
);
7536 pim_hello_restart_now(ifp
);
7542 DEFUN (interface_no_ip_pim_drprio
,
7543 interface_no_ip_pim_drprio_cmd
,
7544 "no ip pim drpriority [(1-4294967295)]",
7548 "Revert the Designated Router Priority to default\n"
7549 "Old Value of the Priority\n")
7551 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7552 struct pim_interface
*pim_ifp
= ifp
->info
;
7555 vty_out(vty
, "Pim not enabled on this interface\n");
7556 return CMD_WARNING_CONFIG_FAILED
;
7559 if (pim_ifp
->pim_dr_priority
!= PIM_DEFAULT_DR_PRIORITY
) {
7560 pim_ifp
->pim_dr_priority
= PIM_DEFAULT_DR_PRIORITY
;
7561 pim_if_dr_election(ifp
);
7562 pim_hello_restart_now(ifp
);
7568 DEFPY_HIDDEN (interface_ip_igmp_query_generate
,
7569 interface_ip_igmp_query_generate_cmd
,
7570 "ip igmp generate-query-once [version (2-3)]",
7573 "Generate igmp general query once\n"
7575 "IGMP version number\n")
7577 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7578 int igmp_version
= 2;
7581 vty_out(vty
, "IGMP/PIM is not enabled on the interface %s\n",
7583 return CMD_WARNING_CONFIG_FAILED
;
7587 igmp_version
= atoi(argv
[4]->arg
);
7589 igmp_send_query_on_intf(ifp
, igmp_version
);
7594 static int pim_cmd_interface_add(struct interface
*ifp
)
7596 struct pim_interface
*pim_ifp
= ifp
->info
;
7599 pim_ifp
= pim_if_new(ifp
, false, true, false, false);
7601 PIM_IF_DO_PIM(pim_ifp
->options
);
7603 pim_if_addr_add_all(ifp
);
7604 pim_if_membership_refresh(ifp
);
7606 pim_if_create_pimreg(pim_ifp
->pim
);
7610 DEFPY_HIDDEN (pim_test_sg_keepalive
,
7611 pim_test_sg_keepalive_cmd
,
7612 "test pim [vrf NAME$name] keepalive-reset A.B.C.D$source A.B.C.D$group",
7616 "Reset the Keepalive Timer\n"
7617 "The Source we are resetting\n"
7618 "The Group we are resetting\n")
7620 struct pim_upstream
*up
;
7621 struct pim_instance
*pim
;
7622 struct prefix_sg sg
;
7628 pim
= pim_get_pim_instance(VRF_DEFAULT
);
7630 struct vrf
*vrf
= vrf_lookup_by_name(name
);
7633 vty_out(vty
, "%% Vrf specified: %s does not exist\n",
7638 pim
= pim_get_pim_instance(vrf
->vrf_id
);
7642 vty_out(vty
, "%% Unable to find pim instance\n");
7646 up
= pim_upstream_find(pim
, &sg
);
7648 vty_out(vty
, "%% Unable to find %s specified\n",
7649 pim_str_sg_dump(&sg
));
7653 vty_out(vty
, "Setting %s to current keep alive time: %d\n",
7654 pim_str_sg_dump(&sg
), pim
->keep_alive_time
);
7655 pim_upstream_keep_alive_timer_start(up
, pim
->keep_alive_time
);
7660 DEFPY_HIDDEN (interface_ip_pim_activeactive
,
7661 interface_ip_pim_activeactive_cmd
,
7662 "[no$no] ip pim active-active",
7666 "Mark interface as Active-Active for MLAG operations, Hidden because not finished yet\n")
7668 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7669 struct pim_interface
*pim_ifp
;
7671 if (!no
&& !pim_cmd_interface_add(ifp
)) {
7672 vty_out(vty
, "Could not enable PIM SM active-active on interface\n");
7673 return CMD_WARNING_CONFIG_FAILED
;
7676 pim_ifp
= ifp
->info
;
7678 pim_if_unconfigure_mlag_dualactive(pim_ifp
);
7680 pim_if_configure_mlag_dualactive(pim_ifp
);
7685 DEFUN_HIDDEN (interface_ip_pim_ssm
,
7686 interface_ip_pim_ssm_cmd
,
7692 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7694 if (!pim_cmd_interface_add(ifp
)) {
7695 vty_out(vty
, "Could not enable PIM SM on interface\n");
7696 return CMD_WARNING_CONFIG_FAILED
;
7700 "WARN: Enabled PIM SM on interface; configure PIM SSM "
7701 "range if needed\n");
7705 static int interface_ip_pim_helper(struct vty
*vty
)
7707 struct pim_interface
*pim_ifp
;
7709 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7711 if (!pim_cmd_interface_add(ifp
)) {
7712 vty_out(vty
, "Could not enable PIM SM on interface\n");
7713 return CMD_WARNING_CONFIG_FAILED
;
7716 pim_ifp
= ifp
->info
;
7718 pim_if_create_pimreg(pim_ifp
->pim
);
7723 DEFUN_HIDDEN (interface_ip_pim_sm
,
7724 interface_ip_pim_sm_cmd
,
7730 return interface_ip_pim_helper(vty
);
7733 DEFUN (interface_ip_pim
,
7734 interface_ip_pim_cmd
,
7739 return interface_ip_pim_helper(vty
);
7742 static int pim_cmd_interface_delete(struct interface
*ifp
)
7744 struct pim_interface
*pim_ifp
= ifp
->info
;
7749 PIM_IF_DONT_PIM(pim_ifp
->options
);
7751 pim_if_membership_clear(ifp
);
7754 pim_sock_delete() removes all neighbors from
7755 pim_ifp->pim_neighbor_list.
7757 pim_sock_delete(ifp
, "pim unconfigured on interface");
7759 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
7760 pim_if_addr_del_all(ifp
);
7767 static int interface_no_ip_pim_helper(struct vty
*vty
)
7769 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7770 if (!pim_cmd_interface_delete(ifp
)) {
7771 vty_out(vty
, "Unable to delete interface information\n");
7772 return CMD_WARNING_CONFIG_FAILED
;
7778 DEFUN_HIDDEN (interface_no_ip_pim_ssm
,
7779 interface_no_ip_pim_ssm_cmd
,
7786 return interface_no_ip_pim_helper(vty
);
7789 DEFUN_HIDDEN (interface_no_ip_pim_sm
,
7790 interface_no_ip_pim_sm_cmd
,
7797 return interface_no_ip_pim_helper(vty
);
7800 DEFUN (interface_no_ip_pim
,
7801 interface_no_ip_pim_cmd
,
7807 return interface_no_ip_pim_helper(vty
);
7811 DEFUN(interface_ip_pim_boundary_oil
,
7812 interface_ip_pim_boundary_oil_cmd
,
7813 "ip multicast boundary oil WORD",
7815 "Generic multicast configuration options\n"
7816 "Define multicast boundary\n"
7817 "Filter OIL by group using prefix list\n"
7818 "Prefix list to filter OIL with\n")
7820 VTY_DECLVAR_CONTEXT(interface
, iif
);
7821 struct pim_interface
*pim_ifp
;
7824 argv_find(argv
, argc
, "WORD", &idx
);
7826 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
7828 if (pim_ifp
->boundary_oil_plist
)
7829 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
7831 pim_ifp
->boundary_oil_plist
=
7832 XSTRDUP(MTYPE_PIM_INTERFACE
, argv
[idx
]->arg
);
7834 /* Interface will be pruned from OIL on next Join */
7838 DEFUN(interface_no_ip_pim_boundary_oil
,
7839 interface_no_ip_pim_boundary_oil_cmd
,
7840 "no ip multicast boundary oil [WORD]",
7843 "Generic multicast configuration options\n"
7844 "Define multicast boundary\n"
7845 "Filter OIL by group using prefix list\n"
7846 "Prefix list to filter OIL with\n")
7848 VTY_DECLVAR_CONTEXT(interface
, iif
);
7849 struct pim_interface
*pim_ifp
;
7852 argv_find(argv
, argc
, "WORD", &idx
);
7854 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
7856 if (pim_ifp
->boundary_oil_plist
)
7857 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
7862 DEFUN (interface_ip_mroute
,
7863 interface_ip_mroute_cmd
,
7864 "ip mroute INTERFACE A.B.C.D [A.B.C.D]",
7866 "Add multicast route\n"
7867 "Outgoing interface name\n"
7871 VTY_DECLVAR_CONTEXT(interface
, iif
);
7872 struct pim_interface
*pim_ifp
;
7873 struct pim_instance
*pim
;
7874 int idx_interface
= 2;
7876 struct interface
*oif
;
7877 const char *oifname
;
7878 const char *grp_str
;
7879 struct in_addr grp_addr
;
7880 const char *src_str
;
7881 struct in_addr src_addr
;
7884 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
7887 oifname
= argv
[idx_interface
]->arg
;
7888 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
7890 vty_out(vty
, "No such interface name %s\n", oifname
);
7894 grp_str
= argv
[idx_ipv4
]->arg
;
7895 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
7897 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
7898 errno
, safe_strerror(errno
));
7902 if (argc
== (idx_ipv4
+ 1)) {
7903 src_addr
.s_addr
= INADDR_ANY
;
7906 src_str
= argv
[idx_ipv4
+ 1]->arg
;
7907 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
7909 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
7910 errno
, safe_strerror(errno
));
7915 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
7916 vty_out(vty
, "Failed to add static mroute\n");
7923 DEFUN (interface_no_ip_mroute
,
7924 interface_no_ip_mroute_cmd
,
7925 "no ip mroute INTERFACE A.B.C.D [A.B.C.D]",
7928 "Add multicast route\n"
7929 "Outgoing interface name\n"
7933 VTY_DECLVAR_CONTEXT(interface
, iif
);
7934 struct pim_interface
*pim_ifp
;
7935 struct pim_instance
*pim
;
7936 int idx_interface
= 3;
7938 struct interface
*oif
;
7939 const char *oifname
;
7940 const char *grp_str
;
7941 struct in_addr grp_addr
;
7942 const char *src_str
;
7943 struct in_addr src_addr
;
7946 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
7949 oifname
= argv
[idx_interface
]->arg
;
7950 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
7952 vty_out(vty
, "No such interface name %s\n", oifname
);
7956 grp_str
= argv
[idx_ipv4
]->arg
;
7957 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
7959 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
7960 errno
, safe_strerror(errno
));
7964 if (argc
== (idx_ipv4
+ 1)) {
7965 src_addr
.s_addr
= INADDR_ANY
;
7968 src_str
= argv
[idx_ipv4
+ 1]->arg
;
7969 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
7971 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
7972 errno
, safe_strerror(errno
));
7977 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
7978 vty_out(vty
, "Failed to remove static mroute\n");
7985 DEFUN (interface_ip_pim_hello
,
7986 interface_ip_pim_hello_cmd
,
7987 "ip pim hello (1-180) [(1-180)]",
7991 IFACE_PIM_HELLO_TIME_STR
7992 IFACE_PIM_HELLO_HOLD_STR
)
7994 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7997 struct pim_interface
*pim_ifp
= ifp
->info
;
8000 if (!pim_cmd_interface_add(ifp
)) {
8001 vty_out(vty
, "Could not enable PIM SM on interface\n");
8002 return CMD_WARNING_CONFIG_FAILED
;
8006 pim_ifp
= ifp
->info
;
8007 pim_ifp
->pim_hello_period
= strtol(argv
[idx_time
]->arg
, NULL
, 10);
8009 if (argc
== idx_hold
+ 1)
8010 pim_ifp
->pim_default_holdtime
=
8011 strtol(argv
[idx_hold
]->arg
, NULL
, 10);
8016 DEFUN (interface_no_ip_pim_hello
,
8017 interface_no_ip_pim_hello_cmd
,
8018 "no ip pim hello [(1-180) (1-180)]",
8023 IFACE_PIM_HELLO_TIME_STR
8024 IFACE_PIM_HELLO_HOLD_STR
)
8026 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8027 struct pim_interface
*pim_ifp
= ifp
->info
;
8030 vty_out(vty
, "Pim not enabled on this interface\n");
8031 return CMD_WARNING_CONFIG_FAILED
;
8034 pim_ifp
->pim_hello_period
= PIM_DEFAULT_HELLO_PERIOD
;
8035 pim_ifp
->pim_default_holdtime
= -1;
8046 PIM_DO_DEBUG_IGMP_EVENTS
;
8047 PIM_DO_DEBUG_IGMP_PACKETS
;
8048 PIM_DO_DEBUG_IGMP_TRACE
;
8052 DEFUN (no_debug_igmp
,
8059 PIM_DONT_DEBUG_IGMP_EVENTS
;
8060 PIM_DONT_DEBUG_IGMP_PACKETS
;
8061 PIM_DONT_DEBUG_IGMP_TRACE
;
8066 DEFUN (debug_igmp_events
,
8067 debug_igmp_events_cmd
,
8068 "debug igmp events",
8071 DEBUG_IGMP_EVENTS_STR
)
8073 PIM_DO_DEBUG_IGMP_EVENTS
;
8077 DEFUN (no_debug_igmp_events
,
8078 no_debug_igmp_events_cmd
,
8079 "no debug igmp events",
8083 DEBUG_IGMP_EVENTS_STR
)
8085 PIM_DONT_DEBUG_IGMP_EVENTS
;
8090 DEFUN (debug_igmp_packets
,
8091 debug_igmp_packets_cmd
,
8092 "debug igmp packets",
8095 DEBUG_IGMP_PACKETS_STR
)
8097 PIM_DO_DEBUG_IGMP_PACKETS
;
8101 DEFUN (no_debug_igmp_packets
,
8102 no_debug_igmp_packets_cmd
,
8103 "no debug igmp packets",
8107 DEBUG_IGMP_PACKETS_STR
)
8109 PIM_DONT_DEBUG_IGMP_PACKETS
;
8114 DEFUN (debug_igmp_trace
,
8115 debug_igmp_trace_cmd
,
8119 DEBUG_IGMP_TRACE_STR
)
8121 PIM_DO_DEBUG_IGMP_TRACE
;
8125 DEFUN (no_debug_igmp_trace
,
8126 no_debug_igmp_trace_cmd
,
8127 "no debug igmp trace",
8131 DEBUG_IGMP_TRACE_STR
)
8133 PIM_DONT_DEBUG_IGMP_TRACE
;
8138 DEFUN (debug_mroute
,
8144 PIM_DO_DEBUG_MROUTE
;
8148 DEFUN (debug_mroute_detail
,
8149 debug_mroute_detail_cmd
,
8150 "debug mroute detail",
8155 PIM_DO_DEBUG_MROUTE_DETAIL
;
8159 DEFUN (no_debug_mroute
,
8160 no_debug_mroute_cmd
,
8166 PIM_DONT_DEBUG_MROUTE
;
8170 DEFUN (no_debug_mroute_detail
,
8171 no_debug_mroute_detail_cmd
,
8172 "no debug mroute detail",
8178 PIM_DONT_DEBUG_MROUTE_DETAIL
;
8182 DEFUN (debug_pim_static
,
8183 debug_pim_static_cmd
,
8189 PIM_DO_DEBUG_STATIC
;
8193 DEFUN (no_debug_pim_static
,
8194 no_debug_pim_static_cmd
,
8195 "no debug pim static",
8201 PIM_DONT_DEBUG_STATIC
;
8212 PIM_DO_DEBUG_PIM_EVENTS
;
8213 PIM_DO_DEBUG_PIM_PACKETS
;
8214 PIM_DO_DEBUG_PIM_TRACE
;
8215 PIM_DO_DEBUG_MSDP_EVENTS
;
8216 PIM_DO_DEBUG_MSDP_PACKETS
;
8221 DEFUN (no_debug_pim
,
8228 PIM_DONT_DEBUG_PIM_EVENTS
;
8229 PIM_DONT_DEBUG_PIM_PACKETS
;
8230 PIM_DONT_DEBUG_PIM_TRACE
;
8231 PIM_DONT_DEBUG_MSDP_EVENTS
;
8232 PIM_DONT_DEBUG_MSDP_PACKETS
;
8234 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
8235 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
8241 DEFUN (debug_pim_nht
,
8246 "Nexthop Tracking\n")
8248 PIM_DO_DEBUG_PIM_NHT
;
8252 DEFUN (no_debug_pim_nht
,
8253 no_debug_pim_nht_cmd
,
8258 "Nexthop Tracking\n")
8260 PIM_DONT_DEBUG_PIM_NHT
;
8264 DEFUN (debug_pim_nht_rp
,
8265 debug_pim_nht_rp_cmd
,
8269 "Nexthop Tracking\n"
8270 "RP Nexthop Tracking\n")
8272 PIM_DO_DEBUG_PIM_NHT_RP
;
8276 DEFUN (no_debug_pim_nht_rp
,
8277 no_debug_pim_nht_rp_cmd
,
8278 "no debug pim nht rp",
8282 "Nexthop Tracking\n"
8283 "RP Nexthop Tracking\n")
8285 PIM_DONT_DEBUG_PIM_NHT_RP
;
8289 DEFUN (debug_pim_events
,
8290 debug_pim_events_cmd
,
8294 DEBUG_PIM_EVENTS_STR
)
8296 PIM_DO_DEBUG_PIM_EVENTS
;
8300 DEFUN (no_debug_pim_events
,
8301 no_debug_pim_events_cmd
,
8302 "no debug pim events",
8306 DEBUG_PIM_EVENTS_STR
)
8308 PIM_DONT_DEBUG_PIM_EVENTS
;
8312 DEFUN (debug_pim_packets
,
8313 debug_pim_packets_cmd
,
8314 "debug pim packets [<hello|joins|register>]",
8317 DEBUG_PIM_PACKETS_STR
8318 DEBUG_PIM_HELLO_PACKETS_STR
8319 DEBUG_PIM_J_P_PACKETS_STR
8320 DEBUG_PIM_PIM_REG_PACKETS_STR
)
8323 if (argv_find(argv
, argc
, "hello", &idx
)) {
8324 PIM_DO_DEBUG_PIM_HELLO
;
8325 vty_out(vty
, "PIM Hello debugging is on\n");
8326 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
8327 PIM_DO_DEBUG_PIM_J_P
;
8328 vty_out(vty
, "PIM Join/Prune debugging is on\n");
8329 } else if (argv_find(argv
, argc
, "register", &idx
)) {
8330 PIM_DO_DEBUG_PIM_REG
;
8331 vty_out(vty
, "PIM Register debugging is on\n");
8333 PIM_DO_DEBUG_PIM_PACKETS
;
8334 vty_out(vty
, "PIM Packet debugging is on \n");
8339 DEFUN (no_debug_pim_packets
,
8340 no_debug_pim_packets_cmd
,
8341 "no debug pim packets [<hello|joins|register>]",
8345 DEBUG_PIM_PACKETS_STR
8346 DEBUG_PIM_HELLO_PACKETS_STR
8347 DEBUG_PIM_J_P_PACKETS_STR
8348 DEBUG_PIM_PIM_REG_PACKETS_STR
)
8351 if (argv_find(argv
, argc
, "hello", &idx
)) {
8352 PIM_DONT_DEBUG_PIM_HELLO
;
8353 vty_out(vty
, "PIM Hello debugging is off \n");
8354 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
8355 PIM_DONT_DEBUG_PIM_J_P
;
8356 vty_out(vty
, "PIM Join/Prune debugging is off \n");
8357 } else if (argv_find(argv
, argc
, "register", &idx
)) {
8358 PIM_DONT_DEBUG_PIM_REG
;
8359 vty_out(vty
, "PIM Register debugging is off\n");
8361 PIM_DONT_DEBUG_PIM_PACKETS
;
8367 DEFUN (debug_pim_packetdump_send
,
8368 debug_pim_packetdump_send_cmd
,
8369 "debug pim packet-dump send",
8372 DEBUG_PIM_PACKETDUMP_STR
8373 DEBUG_PIM_PACKETDUMP_SEND_STR
)
8375 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND
;
8379 DEFUN (no_debug_pim_packetdump_send
,
8380 no_debug_pim_packetdump_send_cmd
,
8381 "no debug pim packet-dump send",
8385 DEBUG_PIM_PACKETDUMP_STR
8386 DEBUG_PIM_PACKETDUMP_SEND_STR
)
8388 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
8392 DEFUN (debug_pim_packetdump_recv
,
8393 debug_pim_packetdump_recv_cmd
,
8394 "debug pim packet-dump receive",
8397 DEBUG_PIM_PACKETDUMP_STR
8398 DEBUG_PIM_PACKETDUMP_RECV_STR
)
8400 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV
;
8404 DEFUN (no_debug_pim_packetdump_recv
,
8405 no_debug_pim_packetdump_recv_cmd
,
8406 "no debug pim packet-dump receive",
8410 DEBUG_PIM_PACKETDUMP_STR
8411 DEBUG_PIM_PACKETDUMP_RECV_STR
)
8413 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
8417 DEFUN (debug_pim_trace
,
8418 debug_pim_trace_cmd
,
8422 DEBUG_PIM_TRACE_STR
)
8424 PIM_DO_DEBUG_PIM_TRACE
;
8428 DEFUN (debug_pim_trace_detail
,
8429 debug_pim_trace_detail_cmd
,
8430 "debug pim trace detail",
8434 "Detailed Information\n")
8436 PIM_DO_DEBUG_PIM_TRACE_DETAIL
;
8440 DEFUN (no_debug_pim_trace
,
8441 no_debug_pim_trace_cmd
,
8442 "no debug pim trace",
8446 DEBUG_PIM_TRACE_STR
)
8448 PIM_DONT_DEBUG_PIM_TRACE
;
8452 DEFUN (no_debug_pim_trace_detail
,
8453 no_debug_pim_trace_detail_cmd
,
8454 "no debug pim trace detail",
8459 "Detailed Information\n")
8461 PIM_DONT_DEBUG_PIM_TRACE_DETAIL
;
8465 DEFUN (debug_ssmpingd
,
8471 PIM_DO_DEBUG_SSMPINGD
;
8475 DEFUN (no_debug_ssmpingd
,
8476 no_debug_ssmpingd_cmd
,
8477 "no debug ssmpingd",
8482 PIM_DONT_DEBUG_SSMPINGD
;
8486 DEFUN (debug_pim_zebra
,
8487 debug_pim_zebra_cmd
,
8491 DEBUG_PIM_ZEBRA_STR
)
8497 DEFUN (no_debug_pim_zebra
,
8498 no_debug_pim_zebra_cmd
,
8499 "no debug pim zebra",
8503 DEBUG_PIM_ZEBRA_STR
)
8505 PIM_DONT_DEBUG_ZEBRA
;
8509 DEFUN(debug_pim_mlag
, debug_pim_mlag_cmd
, "debug pim mlag",
8510 DEBUG_STR DEBUG_PIM_STR DEBUG_PIM_MLAG_STR
)
8516 DEFUN(no_debug_pim_mlag
, no_debug_pim_mlag_cmd
, "no debug pim mlag",
8517 NO_STR DEBUG_STR DEBUG_PIM_STR DEBUG_PIM_MLAG_STR
)
8519 PIM_DONT_DEBUG_MLAG
;
8523 DEFUN (debug_pim_vxlan
,
8524 debug_pim_vxlan_cmd
,
8528 DEBUG_PIM_VXLAN_STR
)
8534 DEFUN (no_debug_pim_vxlan
,
8535 no_debug_pim_vxlan_cmd
,
8536 "no debug pim vxlan",
8540 DEBUG_PIM_VXLAN_STR
)
8542 PIM_DONT_DEBUG_VXLAN
;
8552 PIM_DO_DEBUG_MSDP_EVENTS
;
8553 PIM_DO_DEBUG_MSDP_PACKETS
;
8557 DEFUN (no_debug_msdp
,
8564 PIM_DONT_DEBUG_MSDP_EVENTS
;
8565 PIM_DONT_DEBUG_MSDP_PACKETS
;
8569 DEFUN (debug_msdp_events
,
8570 debug_msdp_events_cmd
,
8571 "debug msdp events",
8574 DEBUG_MSDP_EVENTS_STR
)
8576 PIM_DO_DEBUG_MSDP_EVENTS
;
8580 DEFUN (no_debug_msdp_events
,
8581 no_debug_msdp_events_cmd
,
8582 "no debug msdp events",
8586 DEBUG_MSDP_EVENTS_STR
)
8588 PIM_DONT_DEBUG_MSDP_EVENTS
;
8592 DEFUN (debug_msdp_packets
,
8593 debug_msdp_packets_cmd
,
8594 "debug msdp packets",
8597 DEBUG_MSDP_PACKETS_STR
)
8599 PIM_DO_DEBUG_MSDP_PACKETS
;
8603 DEFUN (no_debug_msdp_packets
,
8604 no_debug_msdp_packets_cmd
,
8605 "no debug msdp packets",
8609 DEBUG_MSDP_PACKETS_STR
)
8611 PIM_DONT_DEBUG_MSDP_PACKETS
;
8615 DEFUN (debug_mtrace
,
8621 PIM_DO_DEBUG_MTRACE
;
8625 DEFUN (no_debug_mtrace
,
8626 no_debug_mtrace_cmd
,
8632 PIM_DONT_DEBUG_MTRACE
;
8647 DEFUN (no_debug_bsm
,
8660 DEFUN_NOSH (show_debugging_pim
,
8661 show_debugging_pim_cmd
,
8662 "show debugging [pim]",
8667 vty_out(vty
, "PIM debugging status\n");
8669 pim_debug_config_write(vty
);
8674 static int interface_pim_use_src_cmd_worker(struct vty
*vty
, const char *source
)
8677 struct in_addr source_addr
;
8678 int ret
= CMD_SUCCESS
;
8679 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8681 result
= inet_pton(AF_INET
, source
, &source_addr
);
8683 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", source
,
8684 errno
, safe_strerror(errno
));
8685 return CMD_WARNING_CONFIG_FAILED
;
8688 result
= pim_update_source_set(ifp
, source_addr
);
8692 case PIM_IFACE_NOT_FOUND
:
8693 ret
= CMD_WARNING_CONFIG_FAILED
;
8694 vty_out(vty
, "Pim not enabled on this interface\n");
8696 case PIM_UPDATE_SOURCE_DUP
:
8698 vty_out(vty
, "%% Source already set to %s\n", source
);
8701 ret
= CMD_WARNING_CONFIG_FAILED
;
8702 vty_out(vty
, "%% Source set failed\n");
8708 DEFUN (interface_pim_use_source
,
8709 interface_pim_use_source_cmd
,
8710 "ip pim use-source A.B.C.D",
8713 "Configure primary IP address\n"
8714 "source ip address\n")
8716 return interface_pim_use_src_cmd_worker(vty
, argv
[3]->arg
);
8719 DEFUN (interface_no_pim_use_source
,
8720 interface_no_pim_use_source_cmd
,
8721 "no ip pim use-source [A.B.C.D]",
8725 "Delete source IP address\n"
8726 "source ip address\n")
8728 return interface_pim_use_src_cmd_worker(vty
, "0.0.0.0");
8736 "Enables BFD support\n")
8738 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8739 struct pim_interface
*pim_ifp
= ifp
->info
;
8740 struct bfd_info
*bfd_info
= NULL
;
8743 if (!pim_cmd_interface_add(ifp
)) {
8744 vty_out(vty
, "Could not enable PIM SM on interface\n");
8748 pim_ifp
= ifp
->info
;
8750 bfd_info
= pim_ifp
->bfd_info
;
8752 if (!bfd_info
|| !CHECK_FLAG(bfd_info
->flags
, BFD_FLAG_PARAM_CFG
))
8753 pim_bfd_if_param_set(ifp
, BFD_DEF_MIN_RX
, BFD_DEF_MIN_TX
,
8754 BFD_DEF_DETECT_MULT
, 1);
8759 DEFUN (no_ip_pim_bfd
,
8765 "Disables BFD support\n")
8767 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8768 struct pim_interface
*pim_ifp
= ifp
->info
;
8771 vty_out(vty
, "Pim not enabled on this interface\n");
8775 if (pim_ifp
->bfd_info
) {
8776 pim_bfd_reg_dereg_all_nbr(ifp
, ZEBRA_BFD_DEST_DEREGISTER
);
8777 bfd_info_free(&(pim_ifp
->bfd_info
));
8788 "Enables BSM support on the interface\n")
8790 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8791 struct pim_interface
*pim_ifp
= ifp
->info
;
8794 if (!pim_cmd_interface_add(ifp
)) {
8795 vty_out(vty
, "Could not enable PIM SM on interface\n");
8800 pim_ifp
= ifp
->info
;
8801 pim_ifp
->bsm_enable
= true;
8806 DEFUN (no_ip_pim_bsm
,
8812 "Disables BSM support\n")
8814 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8815 struct pim_interface
*pim_ifp
= ifp
->info
;
8818 vty_out(vty
, "Pim not enabled on this interface\n");
8822 pim_ifp
->bsm_enable
= false;
8827 DEFUN (ip_pim_ucast_bsm
,
8828 ip_pim_ucast_bsm_cmd
,
8829 "ip pim unicast-bsm",
8832 "Accept/Send unicast BSM on the interface\n")
8834 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8835 struct pim_interface
*pim_ifp
= ifp
->info
;
8838 if (!pim_cmd_interface_add(ifp
)) {
8839 vty_out(vty
, "Could not enable PIM SM on interface\n");
8844 pim_ifp
= ifp
->info
;
8845 pim_ifp
->ucast_bsm_accept
= true;
8850 DEFUN (no_ip_pim_ucast_bsm
,
8851 no_ip_pim_ucast_bsm_cmd
,
8852 "no ip pim unicast-bsm",
8856 "Block send/receive unicast BSM on this interface\n")
8858 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8859 struct pim_interface
*pim_ifp
= ifp
->info
;
8862 vty_out(vty
, "Pim not enabled on this interface\n");
8866 pim_ifp
->ucast_bsm_accept
= false;
8874 ip_pim_bfd_param_cmd
,
8875 "ip pim bfd (2-255) (50-60000) (50-60000)",
8878 "Enables BFD support\n"
8879 "Detect Multiplier\n"
8880 "Required min receive interval\n"
8881 "Desired min transmit interval\n")
8885 ip_pim_bfd_param_cmd
,
8886 "ip pim bfd (2-255) (50-60000) (50-60000)",
8889 "Enables BFD support\n"
8890 "Detect Multiplier\n"
8891 "Required min receive interval\n"
8892 "Desired min transmit interval\n")
8893 #endif /* HAVE_BFDD */
8895 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8897 int idx_number_2
= 4;
8898 int idx_number_3
= 5;
8903 struct pim_interface
*pim_ifp
= ifp
->info
;
8906 if (!pim_cmd_interface_add(ifp
)) {
8907 vty_out(vty
, "Could not enable PIM SM on interface\n");
8912 if ((ret
= bfd_validate_param(
8913 vty
, argv
[idx_number
]->arg
, argv
[idx_number_2
]->arg
,
8914 argv
[idx_number_3
]->arg
, &dm_val
, &rx_val
, &tx_val
))
8918 pim_bfd_if_param_set(ifp
, rx_val
, tx_val
, dm_val
, 0);
8924 ALIAS(no_ip_pim_bfd
, no_ip_pim_bfd_param_cmd
,
8925 "no ip pim bfd (2-255) (50-60000) (50-60000)", NO_STR IP_STR PIM_STR
8926 "Enables BFD support\n"
8927 "Detect Multiplier\n"
8928 "Required min receive interval\n"
8929 "Desired min transmit interval\n")
8930 #endif /* !HAVE_BFDD */
8932 static int ip_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
8933 const char *peer
, const char *local
)
8935 enum pim_msdp_err result
;
8936 struct in_addr peer_addr
;
8937 struct in_addr local_addr
;
8938 int ret
= CMD_SUCCESS
;
8940 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
8942 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
8943 errno
, safe_strerror(errno
));
8944 return CMD_WARNING_CONFIG_FAILED
;
8947 result
= inet_pton(AF_INET
, local
, &local_addr
);
8949 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", local
,
8950 errno
, safe_strerror(errno
));
8951 return CMD_WARNING_CONFIG_FAILED
;
8954 result
= pim_msdp_peer_add(pim
, peer_addr
, local_addr
, "default",
8957 case PIM_MSDP_ERR_NONE
:
8959 case PIM_MSDP_ERR_OOM
:
8960 ret
= CMD_WARNING_CONFIG_FAILED
;
8961 vty_out(vty
, "%% Out of memory\n");
8963 case PIM_MSDP_ERR_PEER_EXISTS
:
8965 vty_out(vty
, "%% Peer exists\n");
8967 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
8968 ret
= CMD_WARNING_CONFIG_FAILED
;
8969 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
8972 ret
= CMD_WARNING_CONFIG_FAILED
;
8973 vty_out(vty
, "%% peer add failed\n");
8979 DEFUN_HIDDEN (ip_msdp_peer
,
8981 "ip msdp peer A.B.C.D source A.B.C.D",
8984 "Configure MSDP peer\n"
8986 "Source address for TCP connection\n"
8987 "local ip address\n")
8989 PIM_DECLVAR_CONTEXT(vrf
, pim
);
8990 return ip_msdp_peer_cmd_worker(pim
, vty
, argv
[3]->arg
, argv
[5]->arg
);
8993 static int ip_no_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
8996 enum pim_msdp_err result
;
8997 struct in_addr peer_addr
;
8999 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
9001 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
9002 errno
, safe_strerror(errno
));
9003 return CMD_WARNING_CONFIG_FAILED
;
9006 result
= pim_msdp_peer_del(pim
, peer_addr
);
9008 case PIM_MSDP_ERR_NONE
:
9010 case PIM_MSDP_ERR_NO_PEER
:
9011 vty_out(vty
, "%% Peer does not exist\n");
9014 vty_out(vty
, "%% peer del failed\n");
9017 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9020 DEFUN_HIDDEN (no_ip_msdp_peer
,
9021 no_ip_msdp_peer_cmd
,
9022 "no ip msdp peer A.B.C.D",
9026 "Delete MSDP peer\n"
9027 "peer ip address\n")
9029 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9030 return ip_no_msdp_peer_cmd_worker(pim
, vty
, argv
[4]->arg
);
9033 static int ip_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
9034 struct vty
*vty
, const char *mg
,
9037 enum pim_msdp_err result
;
9038 struct in_addr mbr_ip
;
9039 int ret
= CMD_SUCCESS
;
9041 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
9043 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
9044 errno
, safe_strerror(errno
));
9045 return CMD_WARNING_CONFIG_FAILED
;
9048 result
= pim_msdp_mg_mbr_add(pim
, mg
, mbr_ip
);
9050 case PIM_MSDP_ERR_NONE
:
9052 case PIM_MSDP_ERR_OOM
:
9053 ret
= CMD_WARNING_CONFIG_FAILED
;
9054 vty_out(vty
, "%% Out of memory\n");
9056 case PIM_MSDP_ERR_MG_MBR_EXISTS
:
9058 vty_out(vty
, "%% mesh-group member exists\n");
9060 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
9061 ret
= CMD_WARNING_CONFIG_FAILED
;
9062 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
9065 ret
= CMD_WARNING_CONFIG_FAILED
;
9066 vty_out(vty
, "%% member add failed\n");
9072 DEFUN (ip_msdp_mesh_group_member
,
9073 ip_msdp_mesh_group_member_cmd
,
9074 "ip msdp mesh-group WORD member A.B.C.D",
9077 "Configure MSDP mesh-group\n"
9079 "mesh group member\n"
9080 "peer ip address\n")
9082 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9083 return ip_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[3]->arg
,
9087 static int ip_no_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
9092 enum pim_msdp_err result
;
9093 struct in_addr mbr_ip
;
9095 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
9097 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
9098 errno
, safe_strerror(errno
));
9099 return CMD_WARNING_CONFIG_FAILED
;
9102 result
= pim_msdp_mg_mbr_del(pim
, mg
, mbr_ip
);
9104 case PIM_MSDP_ERR_NONE
:
9106 case PIM_MSDP_ERR_NO_MG
:
9107 vty_out(vty
, "%% mesh-group does not exist\n");
9109 case PIM_MSDP_ERR_NO_MG_MBR
:
9110 vty_out(vty
, "%% mesh-group member does not exist\n");
9113 vty_out(vty
, "%% mesh-group member del failed\n");
9116 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9118 DEFUN (no_ip_msdp_mesh_group_member
,
9119 no_ip_msdp_mesh_group_member_cmd
,
9120 "no ip msdp mesh-group WORD member A.B.C.D",
9124 "Delete MSDP mesh-group member\n"
9126 "mesh group member\n"
9127 "peer ip address\n")
9129 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9130 return ip_no_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[4]->arg
,
9134 static int ip_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
9135 struct vty
*vty
, const char *mg
,
9138 enum pim_msdp_err result
;
9139 struct in_addr src_ip
;
9141 result
= inet_pton(AF_INET
, src
, &src_ip
);
9143 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", src
,
9144 errno
, safe_strerror(errno
));
9145 return CMD_WARNING_CONFIG_FAILED
;
9148 result
= pim_msdp_mg_src_add(pim
, mg
, src_ip
);
9150 case PIM_MSDP_ERR_NONE
:
9152 case PIM_MSDP_ERR_OOM
:
9153 vty_out(vty
, "%% Out of memory\n");
9155 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
9156 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
9159 vty_out(vty
, "%% source add failed\n");
9162 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9166 DEFUN (ip_msdp_mesh_group_source
,
9167 ip_msdp_mesh_group_source_cmd
,
9168 "ip msdp mesh-group WORD source A.B.C.D",
9171 "Configure MSDP mesh-group\n"
9173 "mesh group local address\n"
9174 "source ip address for the TCP connection\n")
9176 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9177 return ip_msdp_mesh_group_source_cmd_worker(pim
, vty
, argv
[3]->arg
,
9181 static int ip_no_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
9185 enum pim_msdp_err result
;
9187 result
= pim_msdp_mg_src_del(pim
, mg
);
9189 case PIM_MSDP_ERR_NONE
:
9191 case PIM_MSDP_ERR_NO_MG
:
9192 vty_out(vty
, "%% mesh-group does not exist\n");
9195 vty_out(vty
, "%% mesh-group source del failed\n");
9198 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9201 static int ip_no_msdp_mesh_group_cmd_worker(struct pim_instance
*pim
,
9202 struct vty
*vty
, const char *mg
)
9204 enum pim_msdp_err result
;
9206 result
= pim_msdp_mg_del(pim
, mg
);
9208 case PIM_MSDP_ERR_NONE
:
9210 case PIM_MSDP_ERR_NO_MG
:
9211 vty_out(vty
, "%% mesh-group does not exist\n");
9214 vty_out(vty
, "%% mesh-group source del failed\n");
9217 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
9220 DEFUN (no_ip_msdp_mesh_group_source
,
9221 no_ip_msdp_mesh_group_source_cmd
,
9222 "no ip msdp mesh-group WORD source [A.B.C.D]",
9226 "Delete MSDP mesh-group source\n"
9228 "mesh group source\n"
9229 "mesh group local address\n")
9231 PIM_DECLVAR_CONTEXT(vrf
, pim
);
9233 return ip_no_msdp_mesh_group_cmd_worker(pim
, vty
, argv
[6]->arg
);
9235 return ip_no_msdp_mesh_group_source_cmd_worker(pim
, vty
,
9239 static void print_empty_json_obj(struct vty
*vty
)
9242 json
= json_object_new_object();
9243 vty_out(vty
, "%s\n",
9244 json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
));
9245 json_object_free(json
);
9248 static void ip_msdp_show_mesh_group(struct pim_instance
*pim
, struct vty
*vty
,
9251 struct listnode
*mbrnode
;
9252 struct pim_msdp_mg_mbr
*mbr
;
9253 struct pim_msdp_mg
*mg
= pim
->msdp
.mg
;
9254 char mbr_str
[INET_ADDRSTRLEN
];
9255 char src_str
[INET_ADDRSTRLEN
];
9256 char state_str
[PIM_MSDP_STATE_STRLEN
];
9257 enum pim_msdp_peer_state state
;
9258 json_object
*json
= NULL
;
9259 json_object
*json_mg_row
= NULL
;
9260 json_object
*json_members
= NULL
;
9261 json_object
*json_row
= NULL
;
9265 print_empty_json_obj(vty
);
9269 pim_inet4_dump("<source?>", mg
->src_ip
, src_str
, sizeof(src_str
));
9271 json
= json_object_new_object();
9272 /* currently there is only one mesh group but we should still
9274 * it a dict with mg-name as key */
9275 json_mg_row
= json_object_new_object();
9276 json_object_string_add(json_mg_row
, "name",
9277 mg
->mesh_group_name
);
9278 json_object_string_add(json_mg_row
, "source", src_str
);
9280 vty_out(vty
, "Mesh group : %s\n", mg
->mesh_group_name
);
9281 vty_out(vty
, " Source : %s\n", src_str
);
9282 vty_out(vty
, " Member State\n");
9285 for (ALL_LIST_ELEMENTS_RO(mg
->mbr_list
, mbrnode
, mbr
)) {
9286 pim_inet4_dump("<mbr?>", mbr
->mbr_ip
, mbr_str
, sizeof(mbr_str
));
9288 state
= mbr
->mp
->state
;
9290 state
= PIM_MSDP_DISABLED
;
9292 pim_msdp_state_dump(state
, state_str
, sizeof(state_str
));
9294 json_row
= json_object_new_object();
9295 json_object_string_add(json_row
, "member", mbr_str
);
9296 json_object_string_add(json_row
, "state", state_str
);
9297 if (!json_members
) {
9298 json_members
= json_object_new_object();
9299 json_object_object_add(json_mg_row
, "members",
9302 json_object_object_add(json_members
, mbr_str
, json_row
);
9304 vty_out(vty
, " %-15s %11s\n", mbr_str
, state_str
);
9309 json_object_object_add(json
, mg
->mesh_group_name
, json_mg_row
);
9310 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9311 json
, JSON_C_TO_STRING_PRETTY
));
9312 json_object_free(json
);
9316 DEFUN (show_ip_msdp_mesh_group
,
9317 show_ip_msdp_mesh_group_cmd
,
9318 "show ip msdp [vrf NAME] mesh-group [json]",
9323 "MSDP mesh-group information\n"
9326 bool uj
= use_json(argc
, argv
);
9328 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
9333 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
9338 DEFUN (show_ip_msdp_mesh_group_vrf_all
,
9339 show_ip_msdp_mesh_group_vrf_all_cmd
,
9340 "show ip msdp vrf all mesh-group [json]",
9345 "MSDP mesh-group information\n"
9348 bool uj
= use_json(argc
, argv
);
9354 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
9358 vty_out(vty
, " \"%s\": ", vrf
->name
);
9361 vty_out(vty
, "VRF: %s\n", vrf
->name
);
9362 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
9365 vty_out(vty
, "}\n");
9370 static void ip_msdp_show_peers(struct pim_instance
*pim
, struct vty
*vty
,
9373 struct listnode
*mpnode
;
9374 struct pim_msdp_peer
*mp
;
9375 char peer_str
[INET_ADDRSTRLEN
];
9376 char local_str
[INET_ADDRSTRLEN
];
9377 char state_str
[PIM_MSDP_STATE_STRLEN
];
9378 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
9380 json_object
*json
= NULL
;
9381 json_object
*json_row
= NULL
;
9385 json
= json_object_new_object();
9388 "Peer Local State Uptime SaCnt\n");
9391 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
9392 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
9393 now
= pim_time_monotonic_sec();
9394 pim_time_uptime(timebuf
, sizeof(timebuf
),
9397 strlcpy(timebuf
, "-", sizeof(timebuf
));
9399 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
9400 pim_inet4_dump("<local?>", mp
->local
, local_str
,
9402 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
9404 json_row
= json_object_new_object();
9405 json_object_string_add(json_row
, "peer", peer_str
);
9406 json_object_string_add(json_row
, "local", local_str
);
9407 json_object_string_add(json_row
, "state", state_str
);
9408 json_object_string_add(json_row
, "upTime", timebuf
);
9409 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
9410 json_object_object_add(json
, peer_str
, json_row
);
9412 vty_out(vty
, "%-15s %15s %11s %8s %6d\n", peer_str
,
9413 local_str
, state_str
, timebuf
, mp
->sa_cnt
);
9418 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9419 json
, JSON_C_TO_STRING_PRETTY
));
9420 json_object_free(json
);
9424 static void ip_msdp_show_peers_detail(struct pim_instance
*pim
, struct vty
*vty
,
9425 const char *peer
, bool uj
)
9427 struct listnode
*mpnode
;
9428 struct pim_msdp_peer
*mp
;
9429 char peer_str
[INET_ADDRSTRLEN
];
9430 char local_str
[INET_ADDRSTRLEN
];
9431 char state_str
[PIM_MSDP_STATE_STRLEN
];
9432 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
9433 char katimer
[PIM_MSDP_TIMER_STRLEN
];
9434 char crtimer
[PIM_MSDP_TIMER_STRLEN
];
9435 char holdtimer
[PIM_MSDP_TIMER_STRLEN
];
9437 json_object
*json
= NULL
;
9438 json_object
*json_row
= NULL
;
9441 json
= json_object_new_object();
9444 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
9445 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
9446 if (strcmp(peer
, "detail") && strcmp(peer
, peer_str
))
9449 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
9450 now
= pim_time_monotonic_sec();
9451 pim_time_uptime(timebuf
, sizeof(timebuf
),
9454 strlcpy(timebuf
, "-", sizeof(timebuf
));
9456 pim_inet4_dump("<local?>", mp
->local
, local_str
,
9458 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
9459 pim_time_timer_to_hhmmss(katimer
, sizeof(katimer
),
9461 pim_time_timer_to_hhmmss(crtimer
, sizeof(crtimer
),
9463 pim_time_timer_to_hhmmss(holdtimer
, sizeof(holdtimer
),
9467 json_row
= json_object_new_object();
9468 json_object_string_add(json_row
, "peer", peer_str
);
9469 json_object_string_add(json_row
, "local", local_str
);
9470 json_object_string_add(json_row
, "meshGroupName",
9471 mp
->mesh_group_name
);
9472 json_object_string_add(json_row
, "state", state_str
);
9473 json_object_string_add(json_row
, "upTime", timebuf
);
9474 json_object_string_add(json_row
, "keepAliveTimer",
9476 json_object_string_add(json_row
, "connRetryTimer",
9478 json_object_string_add(json_row
, "holdTimer",
9480 json_object_string_add(json_row
, "lastReset",
9482 json_object_int_add(json_row
, "connAttempts",
9484 json_object_int_add(json_row
, "establishedChanges",
9486 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
9487 json_object_int_add(json_row
, "kaSent", mp
->ka_tx_cnt
);
9488 json_object_int_add(json_row
, "kaRcvd", mp
->ka_rx_cnt
);
9489 json_object_int_add(json_row
, "saSent", mp
->sa_tx_cnt
);
9490 json_object_int_add(json_row
, "saRcvd", mp
->sa_rx_cnt
);
9491 json_object_object_add(json
, peer_str
, json_row
);
9493 vty_out(vty
, "Peer : %s\n", peer_str
);
9494 vty_out(vty
, " Local : %s\n", local_str
);
9495 vty_out(vty
, " Mesh Group : %s\n",
9496 mp
->mesh_group_name
);
9497 vty_out(vty
, " State : %s\n", state_str
);
9498 vty_out(vty
, " Uptime : %s\n", timebuf
);
9500 vty_out(vty
, " Keepalive Timer : %s\n", katimer
);
9501 vty_out(vty
, " Conn Retry Timer : %s\n", crtimer
);
9502 vty_out(vty
, " Hold Timer : %s\n", holdtimer
);
9503 vty_out(vty
, " Last Reset : %s\n",
9505 vty_out(vty
, " Conn Attempts : %d\n",
9507 vty_out(vty
, " Established Changes : %d\n",
9509 vty_out(vty
, " SA Count : %d\n",
9511 vty_out(vty
, " Statistics :\n");
9514 vty_out(vty
, " Keepalives : %10d %10d\n",
9515 mp
->ka_tx_cnt
, mp
->ka_rx_cnt
);
9516 vty_out(vty
, " SAs : %10d %10d\n",
9517 mp
->sa_tx_cnt
, mp
->sa_rx_cnt
);
9523 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9524 json
, JSON_C_TO_STRING_PRETTY
));
9525 json_object_free(json
);
9529 DEFUN (show_ip_msdp_peer_detail
,
9530 show_ip_msdp_peer_detail_cmd
,
9531 "show ip msdp [vrf NAME] peer [detail|A.B.C.D] [json]",
9536 "MSDP peer information\n"
9541 bool uj
= use_json(argc
, argv
);
9543 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
9550 if (argv_find(argv
, argc
, "detail", &idx
))
9551 arg
= argv
[idx
]->text
;
9552 else if (argv_find(argv
, argc
, "A.B.C.D", &idx
))
9553 arg
= argv
[idx
]->arg
;
9556 ip_msdp_show_peers_detail(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
9558 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
9563 DEFUN (show_ip_msdp_peer_detail_vrf_all
,
9564 show_ip_msdp_peer_detail_vrf_all_cmd
,
9565 "show ip msdp vrf all peer [detail|A.B.C.D] [json]",
9570 "MSDP peer information\n"
9576 bool uj
= use_json(argc
, argv
);
9582 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
9586 vty_out(vty
, " \"%s\": ", vrf
->name
);
9589 vty_out(vty
, "VRF: %s\n", vrf
->name
);
9590 if (argv_find(argv
, argc
, "detail", &idx
)
9591 || argv_find(argv
, argc
, "A.B.C.D", &idx
))
9592 ip_msdp_show_peers_detail(vrf
->info
, vty
,
9593 argv
[idx
]->arg
, uj
);
9595 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
9598 vty_out(vty
, "}\n");
9603 static void ip_msdp_show_sa(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
9605 struct listnode
*sanode
;
9606 struct pim_msdp_sa
*sa
;
9607 char src_str
[INET_ADDRSTRLEN
];
9608 char grp_str
[INET_ADDRSTRLEN
];
9609 char rp_str
[INET_ADDRSTRLEN
];
9610 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
9614 json_object
*json
= NULL
;
9615 json_object
*json_group
= NULL
;
9616 json_object
*json_row
= NULL
;
9619 json
= json_object_new_object();
9622 "Source Group RP Local SPT Uptime\n");
9625 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
9626 now
= pim_time_monotonic_sec();
9627 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
9628 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
9629 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
9630 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
9631 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
9633 strlcpy(spt_str
, "yes", sizeof(spt_str
));
9635 strlcpy(spt_str
, "no", sizeof(spt_str
));
9638 strlcpy(rp_str
, "-", sizeof(rp_str
));
9639 strlcpy(spt_str
, "-", sizeof(spt_str
));
9641 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
9642 strlcpy(local_str
, "yes", sizeof(local_str
));
9644 strlcpy(local_str
, "no", sizeof(local_str
));
9647 json_object_object_get_ex(json
, grp_str
, &json_group
);
9650 json_group
= json_object_new_object();
9651 json_object_object_add(json
, grp_str
,
9655 json_row
= json_object_new_object();
9656 json_object_string_add(json_row
, "source", src_str
);
9657 json_object_string_add(json_row
, "group", grp_str
);
9658 json_object_string_add(json_row
, "rp", rp_str
);
9659 json_object_string_add(json_row
, "local", local_str
);
9660 json_object_string_add(json_row
, "sptSetup", spt_str
);
9661 json_object_string_add(json_row
, "upTime", timebuf
);
9662 json_object_object_add(json_group
, src_str
, json_row
);
9664 vty_out(vty
, "%-15s %15s %15s %5c %3c %8s\n",
9665 src_str
, grp_str
, rp_str
, local_str
[0],
9666 spt_str
[0], timebuf
);
9671 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9672 json
, JSON_C_TO_STRING_PRETTY
));
9673 json_object_free(json
);
9677 static void ip_msdp_show_sa_entry_detail(struct pim_msdp_sa
*sa
,
9678 const char *src_str
,
9679 const char *grp_str
, struct vty
*vty
,
9680 bool uj
, json_object
*json
)
9682 char rp_str
[INET_ADDRSTRLEN
];
9683 char peer_str
[INET_ADDRSTRLEN
];
9684 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
9687 char statetimer
[PIM_MSDP_TIMER_STRLEN
];
9689 json_object
*json_group
= NULL
;
9690 json_object
*json_row
= NULL
;
9692 now
= pim_time_monotonic_sec();
9693 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
9694 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
9695 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
9696 pim_inet4_dump("<peer?>", sa
->peer
, peer_str
, sizeof(peer_str
));
9698 strlcpy(spt_str
, "yes", sizeof(spt_str
));
9700 strlcpy(spt_str
, "no", sizeof(spt_str
));
9703 strlcpy(rp_str
, "-", sizeof(rp_str
));
9704 strlcpy(peer_str
, "-", sizeof(peer_str
));
9705 strlcpy(spt_str
, "-", sizeof(spt_str
));
9707 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
9708 strlcpy(local_str
, "yes", sizeof(local_str
));
9710 strlcpy(local_str
, "no", sizeof(local_str
));
9712 pim_time_timer_to_hhmmss(statetimer
, sizeof(statetimer
),
9713 sa
->sa_state_timer
);
9715 json_object_object_get_ex(json
, grp_str
, &json_group
);
9718 json_group
= json_object_new_object();
9719 json_object_object_add(json
, grp_str
, json_group
);
9722 json_row
= json_object_new_object();
9723 json_object_string_add(json_row
, "source", src_str
);
9724 json_object_string_add(json_row
, "group", grp_str
);
9725 json_object_string_add(json_row
, "rp", rp_str
);
9726 json_object_string_add(json_row
, "local", local_str
);
9727 json_object_string_add(json_row
, "sptSetup", spt_str
);
9728 json_object_string_add(json_row
, "upTime", timebuf
);
9729 json_object_string_add(json_row
, "stateTimer", statetimer
);
9730 json_object_object_add(json_group
, src_str
, json_row
);
9732 vty_out(vty
, "SA : %s\n", sa
->sg_str
);
9733 vty_out(vty
, " RP : %s\n", rp_str
);
9734 vty_out(vty
, " Peer : %s\n", peer_str
);
9735 vty_out(vty
, " Local : %s\n", local_str
);
9736 vty_out(vty
, " SPT Setup : %s\n", spt_str
);
9737 vty_out(vty
, " Uptime : %s\n", timebuf
);
9738 vty_out(vty
, " State Timer : %s\n", statetimer
);
9743 static void ip_msdp_show_sa_detail(struct pim_instance
*pim
, struct vty
*vty
,
9746 struct listnode
*sanode
;
9747 struct pim_msdp_sa
*sa
;
9748 char src_str
[INET_ADDRSTRLEN
];
9749 char grp_str
[INET_ADDRSTRLEN
];
9750 json_object
*json
= NULL
;
9753 json
= json_object_new_object();
9756 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
9757 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
9758 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
9759 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
, uj
,
9764 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9765 json
, JSON_C_TO_STRING_PRETTY
));
9766 json_object_free(json
);
9770 DEFUN (show_ip_msdp_sa_detail
,
9771 show_ip_msdp_sa_detail_cmd
,
9772 "show ip msdp [vrf NAME] sa detail [json]",
9777 "MSDP active-source information\n"
9781 bool uj
= use_json(argc
, argv
);
9783 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
9788 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
9793 DEFUN (show_ip_msdp_sa_detail_vrf_all
,
9794 show_ip_msdp_sa_detail_vrf_all_cmd
,
9795 "show ip msdp vrf all sa detail [json]",
9800 "MSDP active-source information\n"
9804 bool uj
= use_json(argc
, argv
);
9810 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
9814 vty_out(vty
, " \"%s\": ", vrf
->name
);
9817 vty_out(vty
, "VRF: %s\n", vrf
->name
);
9818 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
9821 vty_out(vty
, "}\n");
9826 static void ip_msdp_show_sa_addr(struct pim_instance
*pim
, struct vty
*vty
,
9827 const char *addr
, bool uj
)
9829 struct listnode
*sanode
;
9830 struct pim_msdp_sa
*sa
;
9831 char src_str
[INET_ADDRSTRLEN
];
9832 char grp_str
[INET_ADDRSTRLEN
];
9833 json_object
*json
= NULL
;
9836 json
= json_object_new_object();
9839 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
9840 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
9841 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
9842 if (!strcmp(addr
, src_str
) || !strcmp(addr
, grp_str
)) {
9843 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
9849 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9850 json
, JSON_C_TO_STRING_PRETTY
));
9851 json_object_free(json
);
9855 static void ip_msdp_show_sa_sg(struct pim_instance
*pim
, struct vty
*vty
,
9856 const char *src
, const char *grp
, bool uj
)
9858 struct listnode
*sanode
;
9859 struct pim_msdp_sa
*sa
;
9860 char src_str
[INET_ADDRSTRLEN
];
9861 char grp_str
[INET_ADDRSTRLEN
];
9862 json_object
*json
= NULL
;
9865 json
= json_object_new_object();
9868 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
9869 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
9870 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
9871 if (!strcmp(src
, src_str
) && !strcmp(grp
, grp_str
)) {
9872 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
9878 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9879 json
, JSON_C_TO_STRING_PRETTY
));
9880 json_object_free(json
);
9884 DEFUN (show_ip_msdp_sa_sg
,
9885 show_ip_msdp_sa_sg_cmd
,
9886 "show ip msdp [vrf NAME] sa [A.B.C.D [A.B.C.D]] [json]",
9891 "MSDP active-source information\n"
9892 "source or group ip\n"
9896 bool uj
= use_json(argc
, argv
);
9900 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
9905 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
9907 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
9911 if (src_ip
&& grp_ip
)
9912 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
9914 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
9916 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
9921 DEFUN (show_ip_msdp_sa_sg_vrf_all
,
9922 show_ip_msdp_sa_sg_vrf_all_cmd
,
9923 "show ip msdp vrf all sa [A.B.C.D [A.B.C.D]] [json]",
9928 "MSDP active-source information\n"
9929 "source or group ip\n"
9933 bool uj
= use_json(argc
, argv
);
9938 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
9940 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
9946 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
9950 vty_out(vty
, " \"%s\": ", vrf
->name
);
9953 vty_out(vty
, "VRF: %s\n", vrf
->name
);
9955 if (src_ip
&& grp_ip
)
9956 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
9958 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
9960 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
9963 vty_out(vty
, "}\n");
9968 struct pim_sg_cache_walk_data
{
9971 json_object
*json_group
;
9972 struct in_addr addr
;
9976 static void pim_show_vxlan_sg_entry(struct pim_vxlan_sg
*vxlan_sg
,
9977 struct pim_sg_cache_walk_data
*cwd
)
9979 struct vty
*vty
= cwd
->vty
;
9980 json_object
*json
= cwd
->json
;
9981 char src_str
[INET_ADDRSTRLEN
];
9982 char grp_str
[INET_ADDRSTRLEN
];
9983 json_object
*json_row
;
9984 bool installed
= (vxlan_sg
->up
) ? true : false;
9985 const char *iif_name
= vxlan_sg
->iif
?vxlan_sg
->iif
->name
:"-";
9986 const char *oif_name
;
9988 if (pim_vxlan_is_orig_mroute(vxlan_sg
))
9989 oif_name
= vxlan_sg
->orig_oif
?vxlan_sg
->orig_oif
->name
:"";
9991 oif_name
= vxlan_sg
->term_oif
?vxlan_sg
->term_oif
->name
:"";
9993 if (cwd
->addr_match
&& (vxlan_sg
->sg
.src
.s_addr
!= cwd
->addr
.s_addr
) &&
9994 (vxlan_sg
->sg
.grp
.s_addr
!= cwd
->addr
.s_addr
)) {
9997 pim_inet4_dump("<src?>", vxlan_sg
->sg
.src
, src_str
, sizeof(src_str
));
9998 pim_inet4_dump("<grp?>", vxlan_sg
->sg
.grp
, grp_str
, sizeof(grp_str
));
10000 json_object_object_get_ex(json
, grp_str
, &cwd
->json_group
);
10002 if (!cwd
->json_group
) {
10003 cwd
->json_group
= json_object_new_object();
10004 json_object_object_add(json
, grp_str
,
10008 json_row
= json_object_new_object();
10009 json_object_string_add(json_row
, "source", src_str
);
10010 json_object_string_add(json_row
, "group", grp_str
);
10011 json_object_string_add(json_row
, "input", iif_name
);
10012 json_object_string_add(json_row
, "output", oif_name
);
10014 json_object_boolean_true_add(json_row
, "installed");
10016 json_object_boolean_false_add(json_row
, "installed");
10017 json_object_object_add(cwd
->json_group
, src_str
, json_row
);
10019 vty_out(vty
, "%-15s %-15s %-15s %-15s %-5s\n",
10020 src_str
, grp_str
, iif_name
, oif_name
,
10025 static void pim_show_vxlan_sg_hash_entry(struct hash_backet
*backet
, void *arg
)
10027 pim_show_vxlan_sg_entry((struct pim_vxlan_sg
*)backet
->data
,
10028 (struct pim_sg_cache_walk_data
*)arg
);
10031 static void pim_show_vxlan_sg(struct pim_instance
*pim
,
10032 struct vty
*vty
, bool uj
)
10034 json_object
*json
= NULL
;
10035 struct pim_sg_cache_walk_data cwd
;
10038 json
= json_object_new_object();
10040 vty_out(vty
, "Codes: I -> installed\n");
10042 "Source Group Input Output Flags\n");
10045 memset(&cwd
, 0, sizeof(cwd
));
10048 hash_iterate(pim
->vxlan
.sg_hash
, pim_show_vxlan_sg_hash_entry
, &cwd
);
10051 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10052 json
, JSON_C_TO_STRING_PRETTY
));
10053 json_object_free(json
);
10057 static void pim_show_vxlan_sg_match_addr(struct pim_instance
*pim
,
10058 struct vty
*vty
, char *addr_str
, bool uj
)
10060 json_object
*json
= NULL
;
10061 struct pim_sg_cache_walk_data cwd
;
10064 memset(&cwd
, 0, sizeof(cwd
));
10065 result
= inet_pton(AF_INET
, addr_str
, &cwd
.addr
);
10067 vty_out(vty
, "Bad address %s: errno=%d: %s\n", addr_str
,
10068 errno
, safe_strerror(errno
));
10073 json
= json_object_new_object();
10075 vty_out(vty
, "Codes: I -> installed\n");
10077 "Source Group Input Output Flags\n");
10082 cwd
.addr_match
= true;
10083 hash_iterate(pim
->vxlan
.sg_hash
, pim_show_vxlan_sg_hash_entry
, &cwd
);
10086 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10087 json
, JSON_C_TO_STRING_PRETTY
));
10088 json_object_free(json
);
10092 static void pim_show_vxlan_sg_one(struct pim_instance
*pim
,
10093 struct vty
*vty
, char *src_str
, char *grp_str
, bool uj
)
10095 json_object
*json
= NULL
;
10096 struct prefix_sg sg
;
10098 struct pim_vxlan_sg
*vxlan_sg
;
10099 const char *iif_name
;
10101 const char *oif_name
;
10103 result
= inet_pton(AF_INET
, src_str
, &sg
.src
);
10105 vty_out(vty
, "Bad src address %s: errno=%d: %s\n", src_str
,
10106 errno
, safe_strerror(errno
));
10109 result
= inet_pton(AF_INET
, grp_str
, &sg
.grp
);
10111 vty_out(vty
, "Bad grp address %s: errno=%d: %s\n", grp_str
,
10112 errno
, safe_strerror(errno
));
10116 sg
.family
= AF_INET
;
10117 sg
.prefixlen
= IPV4_MAX_BITLEN
;
10119 json
= json_object_new_object();
10121 vxlan_sg
= pim_vxlan_sg_find(pim
, &sg
);
10123 installed
= (vxlan_sg
->up
) ? true : false;
10124 iif_name
= vxlan_sg
->iif
?vxlan_sg
->iif
->name
:"-";
10126 if (pim_vxlan_is_orig_mroute(vxlan_sg
))
10128 vxlan_sg
->orig_oif
?vxlan_sg
->orig_oif
->name
:"";
10131 vxlan_sg
->term_oif
?vxlan_sg
->term_oif
->name
:"";
10134 json_object_string_add(json
, "source", src_str
);
10135 json_object_string_add(json
, "group", grp_str
);
10136 json_object_string_add(json
, "input", iif_name
);
10137 json_object_string_add(json
, "output", oif_name
);
10139 json_object_boolean_true_add(json
, "installed");
10141 json_object_boolean_false_add(json
,
10144 vty_out(vty
, "SG : %s\n", vxlan_sg
->sg_str
);
10145 vty_out(vty
, " Input : %s\n", iif_name
);
10146 vty_out(vty
, " Output : %s\n", oif_name
);
10147 vty_out(vty
, " installed : %s\n",
10148 installed
?"yes":"no");
10153 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10154 json
, JSON_C_TO_STRING_PRETTY
));
10155 json_object_free(json
);
10159 DEFUN (show_ip_pim_vxlan_sg
,
10160 show_ip_pim_vxlan_sg_cmd
,
10161 "show ip pim [vrf NAME] vxlan-groups [A.B.C.D [A.B.C.D]] [json]",
10166 "VxLAN BUM groups\n"
10167 "source or group ip\n"
10171 bool uj
= use_json(argc
, argv
);
10175 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10178 return CMD_WARNING
;
10180 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ?
10181 argv
[idx
++]->arg
:NULL
;
10182 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
) ?
10183 argv
[idx
]->arg
:NULL
;
10185 if (src_ip
&& grp_ip
)
10186 pim_show_vxlan_sg_one(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
10188 pim_show_vxlan_sg_match_addr(vrf
->info
, vty
, src_ip
, uj
);
10190 pim_show_vxlan_sg(vrf
->info
, vty
, uj
);
10192 return CMD_SUCCESS
;
10195 static void pim_show_vxlan_sg_work(struct pim_instance
*pim
,
10196 struct vty
*vty
, bool uj
)
10198 json_object
*json
= NULL
;
10199 struct pim_sg_cache_walk_data cwd
;
10200 struct listnode
*node
;
10201 struct pim_vxlan_sg
*vxlan_sg
;
10204 json
= json_object_new_object();
10206 vty_out(vty
, "Codes: I -> installed\n");
10208 "Source Group Input Flags\n");
10211 memset(&cwd
, 0, sizeof(cwd
));
10214 for (ALL_LIST_ELEMENTS_RO(pim_vxlan_p
->work_list
, node
, vxlan_sg
))
10215 pim_show_vxlan_sg_entry(vxlan_sg
, &cwd
);
10218 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10219 json
, JSON_C_TO_STRING_PRETTY
));
10220 json_object_free(json
);
10224 DEFUN_HIDDEN (show_ip_pim_vxlan_sg_work
,
10225 show_ip_pim_vxlan_sg_work_cmd
,
10226 "show ip pim [vrf NAME] vxlan-work [json]",
10231 "VxLAN work list\n"
10234 bool uj
= use_json(argc
, argv
);
10238 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10241 return CMD_WARNING
;
10243 pim_show_vxlan_sg_work(vrf
->info
, vty
, uj
);
10245 return CMD_SUCCESS
;
10248 DEFUN_HIDDEN (no_ip_pim_mlag
,
10249 no_ip_pim_mlag_cmd
,
10256 struct in_addr addr
;
10259 pim_vxlan_mlag_update(true/*mlag_enable*/,
10260 false/*peer_state*/, PIM_VXLAN_MLAG_ROLE_SECONDARY
,
10261 NULL
/*peerlink*/, &addr
);
10263 return CMD_SUCCESS
;
10266 DEFUN_HIDDEN (ip_pim_mlag
,
10268 "ip pim mlag INTERFACE role [primary|secondary] state [up|down] addr A.B.C.D",
10272 "peerlink sub interface\n"
10274 "MLAG role primary\n"
10275 "MLAG role secondary\n"
10276 "peer session state\n"
10277 "peer session state up\n"
10278 "peer session state down\n"
10280 "unique ip address\n")
10282 struct interface
*ifp
;
10283 const char *peerlink
;
10288 struct in_addr reg_addr
;
10291 peerlink
= argv
[idx
]->arg
;
10292 ifp
= if_lookup_by_name(peerlink
, VRF_DEFAULT
);
10294 vty_out(vty
, "No such interface name %s\n", peerlink
);
10295 return CMD_WARNING
;
10299 if (!strcmp(argv
[idx
]->arg
, "primary")) {
10300 role
= PIM_VXLAN_MLAG_ROLE_PRIMARY
;
10301 } else if (!strcmp(argv
[idx
]->arg
, "secondary")) {
10302 role
= PIM_VXLAN_MLAG_ROLE_SECONDARY
;
10304 vty_out(vty
, "unknown MLAG role %s\n", argv
[idx
]->arg
);
10305 return CMD_WARNING
;
10309 if (!strcmp(argv
[idx
]->arg
, "up")) {
10311 } else if (strcmp(argv
[idx
]->arg
, "down")) {
10312 peer_state
= false;
10314 vty_out(vty
, "unknown MLAG state %s\n", argv
[idx
]->arg
);
10315 return CMD_WARNING
;
10319 result
= inet_pton(AF_INET
, argv
[idx
]->arg
, ®_addr
);
10321 vty_out(vty
, "%% Bad reg address %s: errno=%d: %s\n",
10323 errno
, safe_strerror(errno
));
10324 return CMD_WARNING_CONFIG_FAILED
;
10326 pim_vxlan_mlag_update(true, peer_state
, role
, ifp
, ®_addr
);
10328 return CMD_SUCCESS
;
10331 void pim_cmd_init(void)
10333 install_node(&interface_node
,
10334 pim_interface_config_write
); /* INTERFACE_NODE */
10337 install_node(&debug_node
, pim_debug_config_write
);
10339 install_element(ENABLE_NODE
, &pim_test_sg_keepalive_cmd
);
10341 install_element(CONFIG_NODE
, &ip_pim_rp_cmd
);
10342 install_element(VRF_NODE
, &ip_pim_rp_cmd
);
10343 install_element(CONFIG_NODE
, &no_ip_pim_rp_cmd
);
10344 install_element(VRF_NODE
, &no_ip_pim_rp_cmd
);
10345 install_element(CONFIG_NODE
, &ip_pim_rp_prefix_list_cmd
);
10346 install_element(VRF_NODE
, &ip_pim_rp_prefix_list_cmd
);
10347 install_element(CONFIG_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
10348 install_element(VRF_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
10349 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
10350 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
10351 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
10352 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
10353 install_element(CONFIG_NODE
, &ip_pim_ssm_prefix_list_cmd
);
10354 install_element(VRF_NODE
, &ip_pim_ssm_prefix_list_cmd
);
10355 install_element(CONFIG_NODE
, &ip_pim_register_suppress_cmd
);
10356 install_element(VRF_NODE
, &ip_pim_register_suppress_cmd
);
10357 install_element(CONFIG_NODE
, &no_ip_pim_register_suppress_cmd
);
10358 install_element(VRF_NODE
, &no_ip_pim_register_suppress_cmd
);
10359 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
10360 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
10361 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
10362 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
10363 install_element(CONFIG_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
10364 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
10365 install_element(CONFIG_NODE
,
10366 &no_ip_pim_spt_switchover_infinity_plist_cmd
);
10367 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_plist_cmd
);
10368 install_element(CONFIG_NODE
, &ip_pim_joinprune_time_cmd
);
10369 install_element(VRF_NODE
, &ip_pim_joinprune_time_cmd
);
10370 install_element(CONFIG_NODE
, &no_ip_pim_joinprune_time_cmd
);
10371 install_element(VRF_NODE
, &no_ip_pim_joinprune_time_cmd
);
10372 install_element(CONFIG_NODE
, &ip_pim_keep_alive_cmd
);
10373 install_element(VRF_NODE
, &ip_pim_keep_alive_cmd
);
10374 install_element(CONFIG_NODE
, &ip_pim_rp_keep_alive_cmd
);
10375 install_element(VRF_NODE
, &ip_pim_rp_keep_alive_cmd
);
10376 install_element(CONFIG_NODE
, &no_ip_pim_keep_alive_cmd
);
10377 install_element(VRF_NODE
, &no_ip_pim_keep_alive_cmd
);
10378 install_element(CONFIG_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
10379 install_element(VRF_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
10380 install_element(CONFIG_NODE
, &ip_pim_packets_cmd
);
10381 install_element(VRF_NODE
, &ip_pim_packets_cmd
);
10382 install_element(CONFIG_NODE
, &no_ip_pim_packets_cmd
);
10383 install_element(VRF_NODE
, &no_ip_pim_packets_cmd
);
10384 install_element(CONFIG_NODE
, &ip_pim_v6_secondary_cmd
);
10385 install_element(VRF_NODE
, &ip_pim_v6_secondary_cmd
);
10386 install_element(CONFIG_NODE
, &no_ip_pim_v6_secondary_cmd
);
10387 install_element(VRF_NODE
, &no_ip_pim_v6_secondary_cmd
);
10388 install_element(CONFIG_NODE
, &ip_ssmpingd_cmd
);
10389 install_element(VRF_NODE
, &ip_ssmpingd_cmd
);
10390 install_element(CONFIG_NODE
, &no_ip_ssmpingd_cmd
);
10391 install_element(VRF_NODE
, &no_ip_ssmpingd_cmd
);
10392 install_element(CONFIG_NODE
, &ip_msdp_peer_cmd
);
10393 install_element(VRF_NODE
, &ip_msdp_peer_cmd
);
10394 install_element(CONFIG_NODE
, &no_ip_msdp_peer_cmd
);
10395 install_element(VRF_NODE
, &no_ip_msdp_peer_cmd
);
10396 install_element(CONFIG_NODE
, &ip_pim_ecmp_cmd
);
10397 install_element(VRF_NODE
, &ip_pim_ecmp_cmd
);
10398 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_cmd
);
10399 install_element(VRF_NODE
, &no_ip_pim_ecmp_cmd
);
10400 install_element(CONFIG_NODE
, &ip_pim_ecmp_rebalance_cmd
);
10401 install_element(VRF_NODE
, &ip_pim_ecmp_rebalance_cmd
);
10402 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
10403 install_element(VRF_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
10404 install_element(CONFIG_NODE
, &ip_pim_mlag_cmd
);
10405 install_element(CONFIG_NODE
, &no_ip_pim_mlag_cmd
);
10407 install_element(INTERFACE_NODE
, &interface_ip_igmp_cmd
);
10408 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_cmd
);
10409 install_element(INTERFACE_NODE
, &interface_ip_igmp_join_cmd
);
10410 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_join_cmd
);
10411 install_element(INTERFACE_NODE
, &interface_ip_igmp_version_cmd
);
10412 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_version_cmd
);
10413 install_element(INTERFACE_NODE
, &interface_ip_igmp_query_interval_cmd
);
10414 install_element(INTERFACE_NODE
,
10415 &interface_no_ip_igmp_query_interval_cmd
);
10416 install_element(INTERFACE_NODE
,
10417 &interface_ip_igmp_query_max_response_time_cmd
);
10418 install_element(INTERFACE_NODE
,
10419 &interface_no_ip_igmp_query_max_response_time_cmd
);
10420 install_element(INTERFACE_NODE
,
10421 &interface_ip_igmp_query_max_response_time_dsec_cmd
);
10422 install_element(INTERFACE_NODE
,
10423 &interface_no_ip_igmp_query_max_response_time_dsec_cmd
);
10424 install_element(INTERFACE_NODE
,
10425 &interface_ip_igmp_last_member_query_count_cmd
);
10426 install_element(INTERFACE_NODE
,
10427 &interface_no_ip_igmp_last_member_query_count_cmd
);
10428 install_element(INTERFACE_NODE
,
10429 &interface_ip_igmp_last_member_query_interval_cmd
);
10430 install_element(INTERFACE_NODE
,
10431 &interface_no_ip_igmp_last_member_query_interval_cmd
);
10432 install_element(INTERFACE_NODE
, &interface_ip_pim_activeactive_cmd
);
10433 install_element(INTERFACE_NODE
, &interface_ip_pim_ssm_cmd
);
10434 install_element(INTERFACE_NODE
, &interface_no_ip_pim_ssm_cmd
);
10435 install_element(INTERFACE_NODE
, &interface_ip_pim_sm_cmd
);
10436 install_element(INTERFACE_NODE
, &interface_no_ip_pim_sm_cmd
);
10437 install_element(INTERFACE_NODE
, &interface_ip_pim_cmd
);
10438 install_element(INTERFACE_NODE
, &interface_no_ip_pim_cmd
);
10439 install_element(INTERFACE_NODE
, &interface_ip_pim_drprio_cmd
);
10440 install_element(INTERFACE_NODE
, &interface_no_ip_pim_drprio_cmd
);
10441 install_element(INTERFACE_NODE
, &interface_ip_pim_hello_cmd
);
10442 install_element(INTERFACE_NODE
, &interface_no_ip_pim_hello_cmd
);
10443 install_element(INTERFACE_NODE
, &interface_ip_pim_boundary_oil_cmd
);
10444 install_element(INTERFACE_NODE
, &interface_no_ip_pim_boundary_oil_cmd
);
10445 install_element(INTERFACE_NODE
, &interface_ip_igmp_query_generate_cmd
);
10447 // Static mroutes NEB
10448 install_element(INTERFACE_NODE
, &interface_ip_mroute_cmd
);
10449 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_cmd
);
10451 install_element(VIEW_NODE
, &show_ip_igmp_interface_cmd
);
10452 install_element(VIEW_NODE
, &show_ip_igmp_interface_vrf_all_cmd
);
10453 install_element(VIEW_NODE
, &show_ip_igmp_join_cmd
);
10454 install_element(VIEW_NODE
, &show_ip_igmp_join_vrf_all_cmd
);
10455 install_element(VIEW_NODE
, &show_ip_igmp_groups_cmd
);
10456 install_element(VIEW_NODE
, &show_ip_igmp_groups_vrf_all_cmd
);
10457 install_element(VIEW_NODE
, &show_ip_igmp_groups_retransmissions_cmd
);
10458 install_element(VIEW_NODE
, &show_ip_igmp_sources_cmd
);
10459 install_element(VIEW_NODE
, &show_ip_igmp_sources_retransmissions_cmd
);
10460 install_element(VIEW_NODE
, &show_ip_igmp_statistics_cmd
);
10461 install_element(VIEW_NODE
, &show_ip_pim_assert_cmd
);
10462 install_element(VIEW_NODE
, &show_ip_pim_assert_internal_cmd
);
10463 install_element(VIEW_NODE
, &show_ip_pim_assert_metric_cmd
);
10464 install_element(VIEW_NODE
, &show_ip_pim_assert_winner_metric_cmd
);
10465 install_element(VIEW_NODE
, &show_ip_pim_interface_traffic_cmd
);
10466 install_element(VIEW_NODE
, &show_ip_pim_interface_cmd
);
10467 install_element(VIEW_NODE
, &show_ip_pim_interface_vrf_all_cmd
);
10468 install_element(VIEW_NODE
, &show_ip_pim_join_cmd
);
10469 install_element(VIEW_NODE
, &show_ip_pim_join_vrf_all_cmd
);
10470 install_element(VIEW_NODE
, &show_ip_pim_jp_agg_cmd
);
10471 install_element(VIEW_NODE
, &show_ip_pim_local_membership_cmd
);
10472 install_element(VIEW_NODE
, &show_ip_pim_neighbor_cmd
);
10473 install_element(VIEW_NODE
, &show_ip_pim_neighbor_vrf_all_cmd
);
10474 install_element(VIEW_NODE
, &show_ip_pim_rpf_cmd
);
10475 install_element(VIEW_NODE
, &show_ip_pim_rpf_vrf_all_cmd
);
10476 install_element(VIEW_NODE
, &show_ip_pim_secondary_cmd
);
10477 install_element(VIEW_NODE
, &show_ip_pim_state_cmd
);
10478 install_element(VIEW_NODE
, &show_ip_pim_state_vrf_all_cmd
);
10479 install_element(VIEW_NODE
, &show_ip_pim_upstream_cmd
);
10480 install_element(VIEW_NODE
, &show_ip_pim_upstream_vrf_all_cmd
);
10481 install_element(VIEW_NODE
, &show_ip_pim_channel_cmd
);
10482 install_element(VIEW_NODE
, &show_ip_pim_upstream_join_desired_cmd
);
10483 install_element(VIEW_NODE
, &show_ip_pim_upstream_rpf_cmd
);
10484 install_element(VIEW_NODE
, &show_ip_pim_rp_cmd
);
10485 install_element(VIEW_NODE
, &show_ip_pim_rp_vrf_all_cmd
);
10486 install_element(VIEW_NODE
, &show_ip_pim_bsr_cmd
);
10487 install_element(VIEW_NODE
, &show_ip_multicast_cmd
);
10488 install_element(VIEW_NODE
, &show_ip_multicast_vrf_all_cmd
);
10489 install_element(VIEW_NODE
, &show_ip_mroute_cmd
);
10490 install_element(VIEW_NODE
, &show_ip_mroute_vrf_all_cmd
);
10491 install_element(VIEW_NODE
, &show_ip_mroute_count_cmd
);
10492 install_element(VIEW_NODE
, &show_ip_mroute_count_vrf_all_cmd
);
10493 install_element(VIEW_NODE
, &show_ip_mroute_summary_cmd
);
10494 install_element(VIEW_NODE
, &show_ip_mroute_summary_vrf_all_cmd
);
10495 install_element(VIEW_NODE
, &show_ip_rib_cmd
);
10496 install_element(VIEW_NODE
, &show_ip_ssmpingd_cmd
);
10497 install_element(VIEW_NODE
, &show_debugging_pim_cmd
);
10498 install_element(VIEW_NODE
, &show_ip_pim_nexthop_cmd
);
10499 install_element(VIEW_NODE
, &show_ip_pim_nexthop_lookup_cmd
);
10500 install_element(VIEW_NODE
, &show_ip_pim_bsrp_cmd
);
10501 install_element(VIEW_NODE
, &show_ip_pim_bsm_db_cmd
);
10502 install_element(VIEW_NODE
, &show_ip_pim_statistics_cmd
);
10504 install_element(ENABLE_NODE
, &clear_ip_mroute_count_cmd
);
10505 install_element(ENABLE_NODE
, &clear_ip_interfaces_cmd
);
10506 install_element(ENABLE_NODE
, &clear_ip_igmp_interfaces_cmd
);
10507 install_element(ENABLE_NODE
, &clear_ip_mroute_cmd
);
10508 install_element(ENABLE_NODE
, &clear_ip_pim_interfaces_cmd
);
10509 install_element(ENABLE_NODE
, &clear_ip_pim_interface_traffic_cmd
);
10510 install_element(ENABLE_NODE
, &clear_ip_pim_oil_cmd
);
10511 install_element(ENABLE_NODE
, &clear_ip_pim_statistics_cmd
);
10513 install_element(ENABLE_NODE
, &debug_igmp_cmd
);
10514 install_element(ENABLE_NODE
, &no_debug_igmp_cmd
);
10515 install_element(ENABLE_NODE
, &debug_igmp_events_cmd
);
10516 install_element(ENABLE_NODE
, &no_debug_igmp_events_cmd
);
10517 install_element(ENABLE_NODE
, &debug_igmp_packets_cmd
);
10518 install_element(ENABLE_NODE
, &no_debug_igmp_packets_cmd
);
10519 install_element(ENABLE_NODE
, &debug_igmp_trace_cmd
);
10520 install_element(ENABLE_NODE
, &no_debug_igmp_trace_cmd
);
10521 install_element(ENABLE_NODE
, &debug_mroute_cmd
);
10522 install_element(ENABLE_NODE
, &debug_mroute_detail_cmd
);
10523 install_element(ENABLE_NODE
, &no_debug_mroute_cmd
);
10524 install_element(ENABLE_NODE
, &no_debug_mroute_detail_cmd
);
10525 install_element(ENABLE_NODE
, &debug_pim_static_cmd
);
10526 install_element(ENABLE_NODE
, &no_debug_pim_static_cmd
);
10527 install_element(ENABLE_NODE
, &debug_pim_cmd
);
10528 install_element(ENABLE_NODE
, &no_debug_pim_cmd
);
10529 install_element(ENABLE_NODE
, &debug_pim_nht_cmd
);
10530 install_element(ENABLE_NODE
, &no_debug_pim_nht_cmd
);
10531 install_element(ENABLE_NODE
, &debug_pim_nht_rp_cmd
);
10532 install_element(ENABLE_NODE
, &no_debug_pim_nht_rp_cmd
);
10533 install_element(ENABLE_NODE
, &debug_pim_events_cmd
);
10534 install_element(ENABLE_NODE
, &no_debug_pim_events_cmd
);
10535 install_element(ENABLE_NODE
, &debug_pim_packets_cmd
);
10536 install_element(ENABLE_NODE
, &no_debug_pim_packets_cmd
);
10537 install_element(ENABLE_NODE
, &debug_pim_packetdump_send_cmd
);
10538 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_send_cmd
);
10539 install_element(ENABLE_NODE
, &debug_pim_packetdump_recv_cmd
);
10540 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_recv_cmd
);
10541 install_element(ENABLE_NODE
, &debug_pim_trace_cmd
);
10542 install_element(ENABLE_NODE
, &no_debug_pim_trace_cmd
);
10543 install_element(ENABLE_NODE
, &debug_pim_trace_detail_cmd
);
10544 install_element(ENABLE_NODE
, &no_debug_pim_trace_detail_cmd
);
10545 install_element(ENABLE_NODE
, &debug_ssmpingd_cmd
);
10546 install_element(ENABLE_NODE
, &no_debug_ssmpingd_cmd
);
10547 install_element(ENABLE_NODE
, &debug_pim_zebra_cmd
);
10548 install_element(ENABLE_NODE
, &no_debug_pim_zebra_cmd
);
10549 install_element(ENABLE_NODE
, &debug_pim_mlag_cmd
);
10550 install_element(ENABLE_NODE
, &no_debug_pim_mlag_cmd
);
10551 install_element(ENABLE_NODE
, &debug_pim_vxlan_cmd
);
10552 install_element(ENABLE_NODE
, &no_debug_pim_vxlan_cmd
);
10553 install_element(ENABLE_NODE
, &debug_msdp_cmd
);
10554 install_element(ENABLE_NODE
, &no_debug_msdp_cmd
);
10555 install_element(ENABLE_NODE
, &debug_msdp_events_cmd
);
10556 install_element(ENABLE_NODE
, &no_debug_msdp_events_cmd
);
10557 install_element(ENABLE_NODE
, &debug_msdp_packets_cmd
);
10558 install_element(ENABLE_NODE
, &no_debug_msdp_packets_cmd
);
10559 install_element(ENABLE_NODE
, &debug_mtrace_cmd
);
10560 install_element(ENABLE_NODE
, &no_debug_mtrace_cmd
);
10561 install_element(ENABLE_NODE
, &debug_bsm_cmd
);
10562 install_element(ENABLE_NODE
, &no_debug_bsm_cmd
);
10564 install_element(CONFIG_NODE
, &debug_igmp_cmd
);
10565 install_element(CONFIG_NODE
, &no_debug_igmp_cmd
);
10566 install_element(CONFIG_NODE
, &debug_igmp_events_cmd
);
10567 install_element(CONFIG_NODE
, &no_debug_igmp_events_cmd
);
10568 install_element(CONFIG_NODE
, &debug_igmp_packets_cmd
);
10569 install_element(CONFIG_NODE
, &no_debug_igmp_packets_cmd
);
10570 install_element(CONFIG_NODE
, &debug_igmp_trace_cmd
);
10571 install_element(CONFIG_NODE
, &no_debug_igmp_trace_cmd
);
10572 install_element(CONFIG_NODE
, &debug_mroute_cmd
);
10573 install_element(CONFIG_NODE
, &debug_mroute_detail_cmd
);
10574 install_element(CONFIG_NODE
, &no_debug_mroute_cmd
);
10575 install_element(CONFIG_NODE
, &no_debug_mroute_detail_cmd
);
10576 install_element(CONFIG_NODE
, &debug_pim_static_cmd
);
10577 install_element(CONFIG_NODE
, &no_debug_pim_static_cmd
);
10578 install_element(CONFIG_NODE
, &debug_pim_cmd
);
10579 install_element(CONFIG_NODE
, &no_debug_pim_cmd
);
10580 install_element(CONFIG_NODE
, &debug_pim_nht_cmd
);
10581 install_element(CONFIG_NODE
, &no_debug_pim_nht_cmd
);
10582 install_element(CONFIG_NODE
, &debug_pim_nht_rp_cmd
);
10583 install_element(CONFIG_NODE
, &no_debug_pim_nht_rp_cmd
);
10584 install_element(CONFIG_NODE
, &debug_pim_events_cmd
);
10585 install_element(CONFIG_NODE
, &no_debug_pim_events_cmd
);
10586 install_element(CONFIG_NODE
, &debug_pim_packets_cmd
);
10587 install_element(CONFIG_NODE
, &no_debug_pim_packets_cmd
);
10588 install_element(CONFIG_NODE
, &debug_pim_trace_cmd
);
10589 install_element(CONFIG_NODE
, &no_debug_pim_trace_cmd
);
10590 install_element(CONFIG_NODE
, &debug_pim_trace_detail_cmd
);
10591 install_element(CONFIG_NODE
, &no_debug_pim_trace_detail_cmd
);
10592 install_element(CONFIG_NODE
, &debug_ssmpingd_cmd
);
10593 install_element(CONFIG_NODE
, &no_debug_ssmpingd_cmd
);
10594 install_element(CONFIG_NODE
, &debug_pim_zebra_cmd
);
10595 install_element(CONFIG_NODE
, &no_debug_pim_zebra_cmd
);
10596 install_element(CONFIG_NODE
, &debug_pim_vxlan_cmd
);
10597 install_element(CONFIG_NODE
, &no_debug_pim_vxlan_cmd
);
10598 install_element(CONFIG_NODE
, &debug_msdp_cmd
);
10599 install_element(CONFIG_NODE
, &no_debug_msdp_cmd
);
10600 install_element(CONFIG_NODE
, &debug_msdp_events_cmd
);
10601 install_element(CONFIG_NODE
, &no_debug_msdp_events_cmd
);
10602 install_element(CONFIG_NODE
, &debug_msdp_packets_cmd
);
10603 install_element(CONFIG_NODE
, &no_debug_msdp_packets_cmd
);
10604 install_element(CONFIG_NODE
, &debug_mtrace_cmd
);
10605 install_element(CONFIG_NODE
, &no_debug_mtrace_cmd
);
10606 install_element(CONFIG_NODE
, &debug_bsm_cmd
);
10607 install_element(CONFIG_NODE
, &no_debug_bsm_cmd
);
10609 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_member_cmd
);
10610 install_element(VRF_NODE
, &ip_msdp_mesh_group_member_cmd
);
10611 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
10612 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
10613 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_source_cmd
);
10614 install_element(VRF_NODE
, &ip_msdp_mesh_group_source_cmd
);
10615 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
10616 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
10617 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_cmd
);
10618 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_vrf_all_cmd
);
10619 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_cmd
);
10620 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_vrf_all_cmd
);
10621 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_cmd
);
10622 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_vrf_all_cmd
);
10623 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_cmd
);
10624 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_vrf_all_cmd
);
10625 install_element(VIEW_NODE
, &show_ip_pim_ssm_range_cmd
);
10626 install_element(VIEW_NODE
, &show_ip_pim_group_type_cmd
);
10627 install_element(VIEW_NODE
, &show_ip_pim_vxlan_sg_cmd
);
10628 install_element(VIEW_NODE
, &show_ip_pim_vxlan_sg_work_cmd
);
10629 install_element(INTERFACE_NODE
, &interface_pim_use_source_cmd
);
10630 install_element(INTERFACE_NODE
, &interface_no_pim_use_source_cmd
);
10631 /* Install BSM command */
10632 install_element(INTERFACE_NODE
, &ip_pim_bsm_cmd
);
10633 install_element(INTERFACE_NODE
, &no_ip_pim_bsm_cmd
);
10634 install_element(INTERFACE_NODE
, &ip_pim_ucast_bsm_cmd
);
10635 install_element(INTERFACE_NODE
, &no_ip_pim_ucast_bsm_cmd
);
10636 /* Install BFD command */
10637 install_element(INTERFACE_NODE
, &ip_pim_bfd_cmd
);
10638 install_element(INTERFACE_NODE
, &ip_pim_bfd_param_cmd
);
10639 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_cmd
);
10641 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_param_cmd
);
10642 #endif /* !HAVE_BFDD */