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
16 along with this program; see the file COPYING; if not, write to the
17 Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
31 #include "pim_mroute.h"
33 #include "pim_iface.h"
35 #include "pim_mroute.h"
38 #include "pim_igmpv3.h"
43 #include "pim_neighbor.h"
45 #include "pim_ifchannel.h"
46 #include "pim_hello.h"
48 #include "pim_upstream.h"
50 #include "pim_macro.h"
51 #include "pim_ssmpingd.h"
52 #include "pim_zebra.h"
53 #include "pim_static.h"
55 #include "pim_zlookup.h"
58 static struct cmd_node pim_global_node
= {
64 static struct cmd_node interface_node
= {
70 static struct cmd_node debug_node
=
77 static void pim_if_membership_clear(struct interface
*ifp
)
79 struct pim_interface
*pim_ifp
;
84 if (PIM_IF_TEST_PIM(pim_ifp
->options
) &&
85 PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
89 pim_ifchannel_membership_clear(ifp
);
93 When PIM is disabled on interface, IGMPv3 local membership
94 information is not injected into PIM interface state.
96 The function pim_if_membership_refresh() fetches all IGMPv3 local
97 membership information into PIM. It is intented to be called
98 whenever PIM is enabled on the interface in order to collect missed
99 local membership information.
101 static void pim_if_membership_refresh(struct interface
*ifp
)
103 struct pim_interface
*pim_ifp
;
104 struct listnode
*sock_node
;
105 struct igmp_sock
*igmp
;
110 if (!PIM_IF_TEST_PIM(pim_ifp
->options
))
112 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
))
116 First clear off membership from all PIM (S,G) entries on the
120 pim_ifchannel_membership_clear(ifp
);
123 Then restore PIM (S,G) membership from all IGMPv3 (S,G) entries on
127 /* scan igmp sockets */
128 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
129 struct listnode
*grpnode
;
130 struct igmp_group
*grp
;
132 /* scan igmp groups */
133 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grpnode
, grp
)) {
134 struct listnode
*srcnode
;
135 struct igmp_source
*src
;
137 /* scan group sources */
138 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
, srcnode
, src
)) {
140 if (IGMP_SOURCE_TEST_FORWARDING(src
->source_flags
)) {
143 memset (&sg
, 0, sizeof (struct prefix_sg
));
144 sg
.src
= src
->source_addr
;
145 sg
.grp
= grp
->group_addr
;
146 pim_ifchannel_local_membership_add(ifp
, &sg
);
149 } /* scan group sources */
150 } /* scan igmp groups */
151 } /* scan igmp sockets */
154 Finally delete every PIM (S,G) entry lacking all state info
157 pim_ifchannel_delete_on_noinfo(ifp
);
161 static void pim_show_assert(struct vty
*vty
)
163 struct pim_interface
*pim_ifp
;
164 struct pim_ifchannel
*ch
;
165 struct listnode
*ch_node
;
166 struct in_addr ifaddr
;
169 now
= pim_time_monotonic_sec();
172 "Interface Address Source Group State Winner Uptime Timer%s",
175 for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list
, ch_node
, ch
)) {
176 char ch_src_str
[INET_ADDRSTRLEN
];
177 char ch_grp_str
[INET_ADDRSTRLEN
];
178 char winner_str
[INET_ADDRSTRLEN
];
182 pim_ifp
= ch
->interface
->info
;
187 ifaddr
= pim_ifp
->primary_address
;
189 pim_inet4_dump("<ch_src?>", ch
->sg
.src
,
190 ch_src_str
, sizeof(ch_src_str
));
191 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
,
192 ch_grp_str
, sizeof(ch_grp_str
));
193 pim_inet4_dump("<assrt_win?>", ch
->ifassert_winner
,
194 winner_str
, sizeof(winner_str
));
196 pim_time_uptime(uptime
, sizeof(uptime
), now
- ch
->ifassert_creation
);
197 pim_time_timer_to_mmss(timer
, sizeof(timer
),
198 ch
->t_ifassert_timer
);
200 vty_out(vty
, "%-9s %-15s %-15s %-15s %-6s %-15s %-8s %-5s%s",
205 pim_ifchannel_ifassert_name(ch
->ifassert_state
),
210 } /* scan interface channels */
213 static void pim_show_assert_internal(struct vty
*vty
)
215 struct pim_interface
*pim_ifp
;
216 struct listnode
*ch_node
;
217 struct pim_ifchannel
*ch
;
218 struct in_addr ifaddr
;
222 "ECA: Evaluate CouldAssert%s"
223 "ATD: AssertTrackingDesired%s"
224 "eATD: Evaluate AssertTrackingDesired%s%s",
225 VTY_NEWLINE
, VTY_NEWLINE
, VTY_NEWLINE
, VTY_NEWLINE
, VTY_NEWLINE
);
228 "Interface Address Source Group CA eCA ATD eATD%s",
231 for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list
, ch_node
, ch
)) {
232 pim_ifp
= ch
->interface
->info
;
237 ifaddr
= pim_ifp
->primary_address
;
239 char ch_src_str
[INET_ADDRSTRLEN
];
240 char ch_grp_str
[INET_ADDRSTRLEN
];
242 pim_inet4_dump("<ch_src?>", ch
->sg
.src
,
243 ch_src_str
, sizeof(ch_src_str
));
244 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
,
245 ch_grp_str
, sizeof(ch_grp_str
));
246 vty_out(vty
, "%-9s %-15s %-15s %-15s %-3s %-3s %-3s %-4s%s",
251 PIM_IF_FLAG_TEST_COULD_ASSERT(ch
->flags
) ? "yes" : "no",
252 pim_macro_ch_could_assert_eval(ch
) ? "yes" : "no",
253 PIM_IF_FLAG_TEST_ASSERT_TRACKING_DESIRED(ch
->flags
) ? "yes" : "no",
254 pim_macro_assert_tracking_desired_eval(ch
) ? "yes" : "no",
256 } /* scan interface channels */
259 static void pim_show_assert_metric(struct vty
*vty
)
261 struct pim_interface
*pim_ifp
;
262 struct listnode
*ch_node
;
263 struct pim_ifchannel
*ch
;
264 struct in_addr ifaddr
;
267 "Interface Address Source Group RPT Pref Metric Address %s",
270 for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list
, ch_node
, ch
)) {
271 pim_ifp
= ch
->interface
->info
;
276 ifaddr
= pim_ifp
->primary_address
;
278 char ch_src_str
[INET_ADDRSTRLEN
];
279 char ch_grp_str
[INET_ADDRSTRLEN
];
280 char addr_str
[INET_ADDRSTRLEN
];
281 struct pim_assert_metric am
;
283 am
= pim_macro_spt_assert_metric(&ch
->upstream
->rpf
, pim_ifp
->primary_address
);
285 pim_inet4_dump("<ch_src?>", ch
->sg
.src
,
286 ch_src_str
, sizeof(ch_src_str
));
287 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
,
288 ch_grp_str
, sizeof(ch_grp_str
));
289 pim_inet4_dump("<addr?>", am
.ip_address
,
290 addr_str
, sizeof(addr_str
));
292 vty_out(vty
, "%-9s %-15s %-15s %-15s %-3s %4u %6u %-15s%s",
297 am
.rpt_bit_flag
? "yes" : "no",
298 am
.metric_preference
,
302 } /* scan interface channels */
305 static void pim_show_assert_winner_metric(struct vty
*vty
)
307 struct pim_interface
*pim_ifp
;
308 struct listnode
*ch_node
;
309 struct pim_ifchannel
*ch
;
310 struct in_addr ifaddr
;
313 "Interface Address Source Group RPT Pref Metric Address %s",
316 for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list
, ch_node
, ch
)) {
317 pim_ifp
= ch
->interface
->info
;
322 ifaddr
= pim_ifp
->primary_address
;
324 char ch_src_str
[INET_ADDRSTRLEN
];
325 char ch_grp_str
[INET_ADDRSTRLEN
];
326 char addr_str
[INET_ADDRSTRLEN
];
327 struct pim_assert_metric
*am
;
331 am
= &ch
->ifassert_winner_metric
;
333 pim_inet4_dump("<ch_src?>", ch
->sg
.src
,
334 ch_src_str
, sizeof(ch_src_str
));
335 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
,
336 ch_grp_str
, sizeof(ch_grp_str
));
337 pim_inet4_dump("<addr?>", am
->ip_address
,
338 addr_str
, sizeof(addr_str
));
340 if (am
->metric_preference
== PIM_ASSERT_METRIC_PREFERENCE_MAX
)
341 snprintf(pref_str
, sizeof(pref_str
), "INFI");
343 snprintf(pref_str
, sizeof(pref_str
), "%4u", am
->metric_preference
);
345 if (am
->route_metric
== PIM_ASSERT_ROUTE_METRIC_MAX
)
346 snprintf(metr_str
, sizeof(metr_str
), "INFI");
348 snprintf(metr_str
, sizeof(metr_str
), "%6u", am
->route_metric
);
350 vty_out(vty
, "%-9s %-15s %-15s %-15s %-3s %-4s %-6s %-15s%s",
355 am
->rpt_bit_flag
? "yes" : "no",
360 } /* scan interface channels */
363 static void json_object_pim_ifp_add(struct json_object
*json
, struct interface
*ifp
)
365 struct pim_interface
*pim_ifp
;
368 json_object_string_add(json
, "name", ifp
->name
);
369 json_object_string_add(json
, "state", if_is_up(ifp
) ? "up" : "down");
370 json_object_string_add(json
, "address", inet_ntoa(pim_ifp
->primary_address
));
371 json_object_int_add(json
, "index", ifp
->ifindex
);
373 if (if_is_multicast(ifp
))
374 json_object_boolean_true_add(json
, "flagMulticast");
376 if (if_is_broadcast(ifp
))
377 json_object_boolean_true_add(json
, "flagBroadcast");
379 if (ifp
->flags
& IFF_ALLMULTI
)
380 json_object_boolean_true_add(json
, "flagAllMulticast");
382 if (ifp
->flags
& IFF_PROMISC
)
383 json_object_boolean_true_add(json
, "flagPromiscuous");
385 if (PIM_IF_IS_DELETED(ifp
))
386 json_object_boolean_true_add(json
, "flagDeleted");
388 if (pim_if_lan_delay_enabled(ifp
))
389 json_object_boolean_true_add(json
, "lanDelayEnabled");
392 static void pim_show_membership(struct vty
*vty
, u_char uj
)
394 struct pim_interface
*pim_ifp
;
395 struct listnode
*ch_node
;
396 struct pim_ifchannel
*ch
;
398 json_object
*json
= NULL
;
399 json_object
*json_iface
= NULL
;
400 json_object
*json_row
= NULL
;
401 json_object
*json_tmp
= NULL
;
403 json
= json_object_new_object();
405 for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list
, ch_node
, ch
)) {
407 pim_ifp
= ch
->interface
->info
;
412 char ch_src_str
[INET_ADDRSTRLEN
];
413 char ch_grp_str
[INET_ADDRSTRLEN
];
415 pim_inet4_dump("<ch_src?>", ch
->sg
.src
,
416 ch_src_str
, sizeof(ch_src_str
));
417 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
,
418 ch_grp_str
, sizeof(ch_grp_str
));
420 json_object_object_get_ex(json
, ch
->interface
->name
, &json_iface
);
423 json_iface
= json_object_new_object();
424 json_object_pim_ifp_add(json_iface
, ch
->interface
);
425 json_object_object_add(json
, ch
->interface
->name
, json_iface
);
428 json_row
= json_object_new_object();
429 json_object_string_add(json_row
, "source", ch_src_str
);
430 json_object_string_add(json_row
, "group", ch_grp_str
);
431 json_object_string_add(json_row
, "localMembership",
432 ch
->local_ifmembership
== PIM_IFMEMBERSHIP_NOINFO
? "NOINFO" : "INCLUDE");
433 json_object_object_add(json_iface
, ch_grp_str
, json_row
);
434 } /* scan interface channels */
437 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
440 "Interface Address Source Group Membership%s",
444 * Example of the json data we are traversing
450 * "address":"10.1.20.1",
452 * "flagMulticast":true,
453 * "flagBroadcast":true,
454 * "lanDelayEnabled":true,
457 * "group":"226.10.10.10",
458 * "localMembership":"INCLUDE"
464 /* foreach interface */
465 json_object_object_foreach(json
, key
, val
) {
467 /* Find all of the keys where the val is an object. In the example
468 * above the only one is 226.10.10.10
470 json_object_object_foreach(val
, if_field_key
, if_field_val
) {
471 type
= json_object_get_type(if_field_val
);
473 if (type
== json_type_object
) {
474 vty_out(vty
, "%-9s ", key
);
476 json_object_object_get_ex(val
, "address", &json_tmp
);
477 vty_out(vty
, "%-15s ", json_object_get_string(json_tmp
));
479 json_object_object_get_ex(if_field_val
, "source", &json_tmp
);
480 vty_out(vty
, "%-15s ", json_object_get_string(json_tmp
));
483 vty_out(vty
, "%-15s ", if_field_key
);
485 json_object_object_get_ex(if_field_val
, "localMembership", &json_tmp
);
486 vty_out(vty
, "%-10s%s", json_object_get_string(json_tmp
), VTY_NEWLINE
);
492 json_object_free(json
);
495 static void pim_print_ifp_flags(struct vty
*vty
, struct interface
*ifp
, int mloop
)
497 vty_out(vty
, "Flags%s", VTY_NEWLINE
);
498 vty_out(vty
, "-----%s", VTY_NEWLINE
);
499 vty_out(vty
, "All Multicast : %s%s", (ifp
->flags
& IFF_ALLMULTI
) ? "yes" : "no", VTY_NEWLINE
);
500 vty_out(vty
, "Broadcast : %s%s", if_is_broadcast(ifp
)? "yes" : "no", VTY_NEWLINE
);
501 vty_out(vty
, "Deleted : %s%s", PIM_IF_IS_DELETED(ifp
) ? "yes" : "no", VTY_NEWLINE
);
502 vty_out(vty
, "Interface Index : %d%s", ifp
->ifindex
, VTY_NEWLINE
);
503 vty_out(vty
, "Multicast : %s%s", if_is_multicast(ifp
) ? "yes" : "no", VTY_NEWLINE
);
504 vty_out(vty
, "Multicast Loop : %d%s", mloop
, VTY_NEWLINE
);
505 vty_out(vty
, "Promiscuous : %s%s", (ifp
->flags
& IFF_PROMISC
) ? "yes" : "no", VTY_NEWLINE
);
506 vty_out(vty
, "%s", VTY_NEWLINE
);
507 vty_out(vty
, "%s", VTY_NEWLINE
);
510 static void igmp_show_interfaces(struct vty
*vty
, u_char uj
)
512 struct listnode
*node
;
513 struct interface
*ifp
;
515 json_object
*json
= NULL
;
516 json_object
*json_row
= NULL
;
518 now
= pim_time_monotonic_sec();
521 json
= json_object_new_object();
524 "Interface State Address V Querier Query Timer Uptime%s",
527 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
)) {
528 struct pim_interface
*pim_ifp
;
529 struct listnode
*sock_node
;
530 struct igmp_sock
*igmp
;
537 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
539 char query_hhmmss
[10];
541 pim_time_uptime(uptime
, sizeof(uptime
), now
- igmp
->sock_creation
);
542 pim_time_timer_to_hhmmss(query_hhmmss
, sizeof(query_hhmmss
), igmp
->t_igmp_query_timer
);
545 json_row
= json_object_new_object();
546 json_object_pim_ifp_add(json_row
, ifp
);
547 json_object_string_add(json_row
, "upTime", uptime
);
548 json_object_int_add(json_row
, "version", pim_ifp
->igmp_version
);
550 if (igmp
->t_igmp_query_timer
) {
551 json_object_boolean_true_add(json_row
, "querier");
552 json_object_string_add(json_row
, "queryTimer", query_hhmmss
);
555 json_object_object_add(json
, ifp
->name
, json_row
);
558 vty_out(vty
, "%-9s %5s %15s %d %7s %11s %8s%s",
560 if_is_up(ifp
) ? "up" : "down",
561 inet_ntoa(igmp
->ifaddr
),
562 pim_ifp
->igmp_version
,
563 igmp
->t_igmp_query_timer
? "local" : "other",
572 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
573 json_object_free(json
);
577 static void igmp_show_interfaces_single(struct vty
*vty
, const char *ifname
, u_char uj
)
579 struct igmp_sock
*igmp
;
580 struct interface
*ifp
;
581 struct listnode
*node
;
582 struct listnode
*sock_node
;
583 struct pim_interface
*pim_ifp
;
585 char query_hhmmss
[10];
586 char other_hhmmss
[10];
587 int found_ifname
= 0;
590 long gmi_msec
; /* Group Membership Interval */
593 long oqpi_msec
; /* Other Querier Present Interval */
597 json_object
*json
= NULL
;
598 json_object
*json_row
= NULL
;
601 json
= json_object_new_object();
603 now
= pim_time_monotonic_sec();
605 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
)) {
611 if (strcmp(ifname
, "detail") && strcmp(ifname
, ifp
->name
))
614 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
616 pim_time_uptime(uptime
, sizeof(uptime
), now
- igmp
->sock_creation
);
617 pim_time_timer_to_hhmmss(query_hhmmss
, sizeof(query_hhmmss
), igmp
->t_igmp_query_timer
);
618 pim_time_timer_to_hhmmss(other_hhmmss
, sizeof(other_hhmmss
), igmp
->t_other_querier_timer
);
620 gmi_msec
= PIM_IGMP_GMI_MSEC(igmp
->querier_robustness_variable
,
621 igmp
->querier_query_interval
,
622 pim_ifp
->igmp_query_max_response_time_dsec
);
624 sqi
= PIM_IGMP_SQI(pim_ifp
->igmp_default_query_interval
);
626 oqpi_msec
= PIM_IGMP_OQPI_MSEC(igmp
->querier_robustness_variable
,
627 igmp
->querier_query_interval
,
628 pim_ifp
->igmp_query_max_response_time_dsec
);
630 lmqt_msec
= PIM_IGMP_LMQT_MSEC(pim_ifp
->igmp_query_max_response_time_dsec
,
631 igmp
->querier_robustness_variable
);
633 ohpi_msec
= PIM_IGMP_OHPI_DSEC(igmp
->querier_robustness_variable
,
634 igmp
->querier_query_interval
,
635 pim_ifp
->igmp_query_max_response_time_dsec
) * 100;
637 qri_msec
= pim_ifp
->igmp_query_max_response_time_dsec
* 100;
638 mloop
= pim_socket_mcastloop_get(pim_ifp
->pim_sock_fd
);
641 json_row
= json_object_new_object();
642 json_object_pim_ifp_add(json_row
, ifp
);
643 json_object_string_add(json_row
, "upTime", uptime
);
644 json_object_string_add(json_row
, "querier", igmp
->t_igmp_query_timer
? "local" : "other");
645 json_object_int_add(json_row
, "queryStartCount", igmp
->startup_query_count
);
646 json_object_string_add(json_row
, "queryQueryTimer", query_hhmmss
);
647 json_object_string_add(json_row
, "queryOtherTimer", other_hhmmss
);
648 json_object_int_add(json_row
, "version", pim_ifp
->igmp_version
);
649 json_object_int_add(json_row
, "timerGroupMembershipIntervalMsec", gmi_msec
);
650 json_object_int_add(json_row
, "timerLastMemberQueryMsec", lmqt_msec
);
651 json_object_int_add(json_row
, "timerOlderHostPresentIntervalMsec", ohpi_msec
);
652 json_object_int_add(json_row
, "timerOtherQuerierPresentIntervalMsec", oqpi_msec
);
653 json_object_int_add(json_row
, "timerQueryInterval", igmp
->querier_query_interval
);
654 json_object_int_add(json_row
, "timerQueryResponseIntervalMsec", qri_msec
);
655 json_object_int_add(json_row
, "timerRobustnessVariable", igmp
->querier_robustness_variable
);
656 json_object_int_add(json_row
, "timerStartupQueryInterval", sqi
);
658 json_object_object_add(json
, ifp
->name
, json_row
);
661 vty_out(vty
, "Interface : %s%s", ifp
->name
, VTY_NEWLINE
);
662 vty_out(vty
, "State : %s%s", if_is_up(ifp
) ? "up" : "down", VTY_NEWLINE
);
663 vty_out(vty
, "Address : %s%s", inet_ntoa(pim_ifp
->primary_address
), VTY_NEWLINE
);
664 vty_out(vty
, "Uptime : %s%s", uptime
, VTY_NEWLINE
);
665 vty_out(vty
, "Version : %d%s", pim_ifp
->igmp_version
, VTY_NEWLINE
);
666 vty_out(vty
, "%s", VTY_NEWLINE
);
667 vty_out(vty
, "%s", VTY_NEWLINE
);
669 vty_out(vty
, "Querier%s", VTY_NEWLINE
);
670 vty_out(vty
, "-------%s", VTY_NEWLINE
);
671 vty_out(vty
, "Querier : %s%s", igmp
->t_igmp_query_timer
? "local" : "other", VTY_NEWLINE
);
672 vty_out(vty
, "Start Count : %d%s", igmp
->startup_query_count
, VTY_NEWLINE
);
673 vty_out(vty
, "Query Timer : %s%s", query_hhmmss
, VTY_NEWLINE
);
674 vty_out(vty
, "Other Timer : %s%s", other_hhmmss
, VTY_NEWLINE
);
675 vty_out(vty
, "%s", VTY_NEWLINE
);
676 vty_out(vty
, "%s", VTY_NEWLINE
);
678 vty_out(vty
, "Timers%s", VTY_NEWLINE
);
679 vty_out(vty
, "------%s", VTY_NEWLINE
);
680 vty_out(vty
, "Group Membership Interval : %lis%s", gmi_msec
/1000, VTY_NEWLINE
);
681 vty_out(vty
, "Last Member Query Time : %lis%s", lmqt_msec
/1000, VTY_NEWLINE
);
682 vty_out(vty
, "Older Host Present Interval : %lis%s", ohpi_msec
/1000, VTY_NEWLINE
);
683 vty_out(vty
, "Other Querier Present Interval : %lis%s", oqpi_msec
/1000, VTY_NEWLINE
);
684 vty_out(vty
, "Query Interval : %ds%s", igmp
->querier_query_interval
, VTY_NEWLINE
);
685 vty_out(vty
, "Query Response Interval : %lis%s", qri_msec
/1000, VTY_NEWLINE
);
686 vty_out(vty
, "Robustness Variable : %d%s", igmp
->querier_robustness_variable
, VTY_NEWLINE
);
687 vty_out(vty
, "Startup Query Interval : %ds%s", sqi
, VTY_NEWLINE
);
688 vty_out(vty
, "%s", VTY_NEWLINE
);
689 vty_out(vty
, "%s", VTY_NEWLINE
);
691 pim_print_ifp_flags(vty
, ifp
, mloop
);
697 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
698 json_object_free(json
);
701 vty_out (vty
, "%% No such interface%s", VTY_NEWLINE
);
705 static void igmp_show_interface_join(struct vty
*vty
)
707 struct listnode
*node
;
708 struct interface
*ifp
;
711 now
= pim_time_monotonic_sec();
714 "Interface Address Source Group Socket Uptime %s",
717 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
)) {
718 struct pim_interface
*pim_ifp
;
719 struct listnode
*join_node
;
720 struct igmp_join
*ij
;
721 struct in_addr pri_addr
;
722 char pri_addr_str
[INET_ADDRSTRLEN
];
729 if (!pim_ifp
->igmp_join_list
)
732 pri_addr
= pim_find_primary_addr(ifp
);
733 pim_inet4_dump("<pri?>", pri_addr
, pri_addr_str
, sizeof(pri_addr_str
));
735 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_join_list
, join_node
, ij
)) {
736 char group_str
[INET_ADDRSTRLEN
];
737 char source_str
[INET_ADDRSTRLEN
];
740 pim_time_uptime(uptime
, sizeof(uptime
), now
- ij
->sock_creation
);
741 pim_inet4_dump("<grp?>", ij
->group_addr
, group_str
, sizeof(group_str
));
742 pim_inet4_dump("<src?>", ij
->source_addr
, source_str
, sizeof(source_str
));
744 vty_out(vty
, "%-9s %-15s %-15s %-15s %6d %8s%s",
752 } /* for (pim_ifp->igmp_join_list) */
758 static void pim_show_interfaces_single(struct vty
*vty
, const char *ifname
, u_char uj
)
760 struct in_addr ifaddr
;
761 struct interface
*ifp
;
762 struct listnode
*neighnode
;
763 struct listnode
*node
;
764 struct listnode
*upnode
;
765 struct pim_interface
*pim_ifp
;
766 struct pim_neighbor
*neigh
;
767 struct pim_upstream
*up
;
769 char dr_str
[INET_ADDRSTRLEN
];
772 char grp_str
[INET_ADDRSTRLEN
];
773 char hello_period
[10];
774 char hello_timer
[10];
775 char neigh_src_str
[INET_ADDRSTRLEN
];
776 char src_str
[INET_ADDRSTRLEN
];
777 char stat_uptime
[10];
780 int found_ifname
= 0;
782 json_object
*json
= NULL
;
783 json_object
*json_row
= NULL
;
784 json_object
*json_pim_neighbor
= NULL
;
785 json_object
*json_pim_neighbors
= NULL
;
786 json_object
*json_group
= NULL
;
787 json_object
*json_group_source
= NULL
;
788 json_object
*json_fhr_sources
= NULL
;
789 struct pim_secondary_addr
*sec_addr
;
790 struct listnode
*sec_node
;
792 now
= pim_time_monotonic_sec();
795 json
= json_object_new_object();
797 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
)) {
803 if (pim_ifp
->pim_sock_fd
< 0)
806 if (strcmp(ifname
, "detail") && strcmp(ifname
, ifp
->name
))
810 ifaddr
= pim_ifp
->primary_address
;
811 pim_inet4_dump("<dr?>", pim_ifp
->pim_dr_addr
, dr_str
, sizeof(dr_str
));
812 pim_time_uptime_begin(dr_uptime
, sizeof(dr_uptime
), now
, pim_ifp
->pim_dr_election_last
);
813 pim_time_timer_to_hhmmss(hello_timer
, sizeof(hello_timer
), pim_ifp
->t_pim_hello_timer
);
814 pim_time_mmss(hello_period
, sizeof(hello_period
), pim_ifp
->pim_hello_period
);
815 pim_time_uptime(stat_uptime
, sizeof(stat_uptime
), now
- pim_ifp
->pim_ifstat_start
);
816 mloop
= pim_socket_mcastloop_get(pim_ifp
->pim_sock_fd
);
819 json_row
= json_object_new_object();
820 json_object_pim_ifp_add(json_row
, ifp
);
822 if (pim_ifp
->update_source
.s_addr
!= INADDR_ANY
) {
823 json_object_string_add(json_row
, "useSource", inet_ntoa(pim_ifp
->update_source
));
825 if (pim_ifp
->sec_addr_list
) {
826 json_object
*sec_list
= NULL
;
828 sec_list
= json_object_new_array();
829 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->sec_addr_list
, sec_node
, sec_addr
)) {
830 json_object_array_add(sec_list
, json_object_new_string(inet_ntoa(sec_addr
->addr
)));
832 json_object_object_add(json_row
, "secondaryAddressList", sec_list
);
836 if (pim_ifp
->pim_neighbor_list
->count
) {
837 json_pim_neighbors
= json_object_new_object();
839 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
, neigh
)) {
840 json_pim_neighbor
= json_object_new_object();
841 pim_inet4_dump("<src?>", neigh
->source_addr
, neigh_src_str
, sizeof(neigh_src_str
));
842 pim_time_uptime(uptime
, sizeof(uptime
), now
- neigh
->creation
);
843 pim_time_timer_to_hhmmss(expire
, sizeof(expire
), neigh
->t_expire_timer
);
845 json_object_string_add(json_pim_neighbor
, "address", neigh_src_str
);
846 json_object_string_add(json_pim_neighbor
, "upTime", uptime
);
847 json_object_string_add(json_pim_neighbor
, "holdtime", expire
);
849 json_object_object_add(json_pim_neighbors
, neigh_src_str
, json_pim_neighbor
);
852 json_object_object_add(json_row
, "neighbors", json_pim_neighbors
);
855 json_object_string_add(json_row
, "drAddress", dr_str
);
856 json_object_int_add(json_row
, "drPriority", pim_ifp
->pim_dr_priority
);
857 json_object_string_add(json_row
, "drUptime", dr_uptime
);
858 json_object_int_add(json_row
, "drElections", pim_ifp
->pim_dr_election_count
);
859 json_object_int_add(json_row
, "drChanges", pim_ifp
->pim_dr_election_changes
);
862 for (ALL_LIST_ELEMENTS_RO(pim_upstream_list
, upnode
, up
)) {
863 if (ifp
== up
->rpf
.source_nexthop
.interface
) {
864 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
) {
865 if (!json_fhr_sources
) {
866 json_fhr_sources
= json_object_new_object();
869 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
870 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
871 pim_time_uptime(uptime
, sizeof(uptime
), now
- up
->state_transition
);
873 /* Does this group live in json_fhr_sources? If not create it. */
874 json_object_object_get_ex(json_fhr_sources
, grp_str
, &json_group
);
877 json_group
= json_object_new_object();
878 json_object_object_add(json_fhr_sources
, grp_str
, json_group
);
881 json_group_source
= json_object_new_object();
882 json_object_string_add(json_group_source
, "source", src_str
);
883 json_object_string_add(json_group_source
, "group", grp_str
);
884 json_object_string_add(json_group_source
, "upTime", uptime
);
885 json_object_object_add(json_group
, src_str
, json_group_source
);
890 if (json_fhr_sources
) {
891 json_object_object_add(json_row
, "firstHopRouter", json_fhr_sources
);
894 json_object_int_add(json_row
, "helloPeriod", pim_ifp
->pim_hello_period
);
895 json_object_string_add(json_row
, "helloTimer", hello_timer
);
896 json_object_string_add(json_row
, "helloStatStart", stat_uptime
);
897 json_object_int_add(json_row
, "helloReceived", pim_ifp
->pim_ifstat_hello_recv
);
898 json_object_int_add(json_row
, "helloReceivedFailed", pim_ifp
->pim_ifstat_hello_recvfail
);
899 json_object_int_add(json_row
, "helloSend", pim_ifp
->pim_ifstat_hello_sent
);
900 json_object_int_add(json_row
, "hellosendFailed", pim_ifp
->pim_ifstat_hello_sendfail
);
901 json_object_int_add(json_row
, "helloGenerationId", pim_ifp
->pim_generation_id
);
902 json_object_int_add(json_row
, "flagMulticastLoop", mloop
);
904 json_object_int_add(json_row
, "effectivePropagationDelay", pim_if_effective_propagation_delay_msec(ifp
));
905 json_object_int_add(json_row
, "effectiveOverrideInterval", pim_if_effective_override_interval_msec(ifp
));
906 json_object_int_add(json_row
, "joinPruneOverrideInterval", pim_if_jp_override_interval_msec(ifp
));
908 json_object_int_add(json_row
, "propagationDelay", pim_ifp
->pim_propagation_delay_msec
);
909 json_object_int_add(json_row
, "propagationDelayHighest", pim_ifp
->pim_neighbors_highest_propagation_delay_msec
);
910 json_object_int_add(json_row
, "overrideInterval", pim_ifp
->pim_override_interval_msec
);
911 json_object_int_add(json_row
, "overrideIntervalHighest", pim_ifp
->pim_neighbors_highest_override_interval_msec
);
912 json_object_object_add(json
, ifp
->name
, json_row
);
915 vty_out(vty
, "Interface : %s%s", ifp
->name
, VTY_NEWLINE
);
916 vty_out(vty
, "State : %s%s", if_is_up(ifp
) ? "up" : "down", VTY_NEWLINE
);
917 if (pim_ifp
->update_source
.s_addr
!= INADDR_ANY
) {
918 vty_out(vty
, "Use Source : %s%s", inet_ntoa(pim_ifp
->update_source
), VTY_NEWLINE
);
920 if (pim_ifp
->sec_addr_list
) {
921 vty_out(vty
, "Address : %s (primary)%s",
922 inet_ntoa(ifaddr
), VTY_NEWLINE
);
923 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->sec_addr_list
, sec_node
, sec_addr
)) {
924 vty_out(vty
, " %s%s",
925 inet_ntoa(sec_addr
->addr
), VTY_NEWLINE
);
928 vty_out(vty
, "Address : %s%s", inet_ntoa(ifaddr
), VTY_NEWLINE
);
930 vty_out(vty
, "%s", VTY_NEWLINE
);
935 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
, neigh
)) {
938 vty_out(vty
, "PIM Neighbors%s", VTY_NEWLINE
);
939 vty_out(vty
, "-------------%s", VTY_NEWLINE
);
943 pim_inet4_dump("<src?>", neigh
->source_addr
, neigh_src_str
, sizeof(neigh_src_str
));
944 pim_time_uptime(uptime
, sizeof(uptime
), now
- neigh
->creation
);
945 pim_time_timer_to_hhmmss(expire
, sizeof(expire
), neigh
->t_expire_timer
);
946 vty_out(vty
, "%-15s : up for %s, holdtime expires in %s%s", neigh_src_str
, uptime
, expire
, VTY_NEWLINE
);
950 vty_out(vty
, "%s", VTY_NEWLINE
);
951 vty_out(vty
, "%s", VTY_NEWLINE
);
954 vty_out(vty
, "Designated Router%s", VTY_NEWLINE
);
955 vty_out(vty
, "-----------------%s", VTY_NEWLINE
);
956 vty_out(vty
, "Address : %s%s", dr_str
, VTY_NEWLINE
);
957 vty_out(vty
, "Priority : %d%s", pim_ifp
->pim_dr_priority
, VTY_NEWLINE
);
958 vty_out(vty
, "Uptime : %s%s", dr_uptime
, VTY_NEWLINE
);
959 vty_out(vty
, "Elections : %d%s", pim_ifp
->pim_dr_election_count
, VTY_NEWLINE
);
960 vty_out(vty
, "Changes : %d%s", pim_ifp
->pim_dr_election_changes
, VTY_NEWLINE
);
961 vty_out(vty
, "%s", VTY_NEWLINE
);
962 vty_out(vty
, "%s", VTY_NEWLINE
);
966 for (ALL_LIST_ELEMENTS_RO(pim_upstream_list
, upnode
, up
)) {
967 if (strcmp(ifp
->name
, up
->rpf
.source_nexthop
.interface
->name
) == 0) {
968 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
) {
971 vty_out(vty
, "FHR - First Hop Router%s", VTY_NEWLINE
);
972 vty_out(vty
, "----------------------%s", VTY_NEWLINE
);
976 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
977 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
978 pim_time_uptime(uptime
, sizeof(uptime
), now
- up
->state_transition
);
979 vty_out(vty
, "%s : %s is a source, uptime is %s%s", grp_str
, src_str
, uptime
, VTY_NEWLINE
);
985 vty_out(vty
, "%s", VTY_NEWLINE
);
986 vty_out(vty
, "%s", VTY_NEWLINE
);
989 vty_out(vty
, "Hellos%s", VTY_NEWLINE
);
990 vty_out(vty
, "------%s", VTY_NEWLINE
);
991 vty_out(vty
, "Period : %d%s", pim_ifp
->pim_hello_period
, VTY_NEWLINE
);
992 vty_out(vty
, "Timer : %s%s", hello_timer
, VTY_NEWLINE
);
993 vty_out(vty
, "StatStart : %s%s", stat_uptime
, VTY_NEWLINE
);
994 vty_out(vty
, "Receive : %d%s", pim_ifp
->pim_ifstat_hello_recv
, VTY_NEWLINE
);
995 vty_out(vty
, "Receive Failed : %d%s", pim_ifp
->pim_ifstat_hello_recvfail
, VTY_NEWLINE
);
996 vty_out(vty
, "Send : %d%s", pim_ifp
->pim_ifstat_hello_sent
, VTY_NEWLINE
);
997 vty_out(vty
, "Send Failed : %d%s", pim_ifp
->pim_ifstat_hello_sendfail
, VTY_NEWLINE
);
998 vty_out(vty
, "Generation ID : %08x%s", pim_ifp
->pim_generation_id
, VTY_NEWLINE
);
999 vty_out(vty
, "%s", VTY_NEWLINE
);
1000 vty_out(vty
, "%s", VTY_NEWLINE
);
1002 pim_print_ifp_flags(vty
, ifp
, mloop
);
1004 vty_out(vty
, "Join Prune Interval%s", VTY_NEWLINE
);
1005 vty_out(vty
, "-------------------%s", VTY_NEWLINE
);
1006 vty_out(vty
, "LAN Delay : %s%s", pim_if_lan_delay_enabled(ifp
) ? "yes" : "no", VTY_NEWLINE
);
1007 vty_out(vty
, "Effective Propagation Delay : %d msec%s", pim_if_effective_propagation_delay_msec(ifp
), VTY_NEWLINE
);
1008 vty_out(vty
, "Effective Override Interval : %d msec%s", pim_if_effective_override_interval_msec(ifp
), VTY_NEWLINE
);
1009 vty_out(vty
, "Join Prune Override Interval : %d msec%s", pim_if_jp_override_interval_msec(ifp
), VTY_NEWLINE
);
1010 vty_out(vty
, "%s", VTY_NEWLINE
);
1011 vty_out(vty
, "%s", VTY_NEWLINE
);
1013 vty_out(vty
, "LAN Prune Delay%s", VTY_NEWLINE
);
1014 vty_out(vty
, "---------------%s", VTY_NEWLINE
);
1015 vty_out(vty
, "Propagation Delay : %d msec%s", pim_ifp
->pim_propagation_delay_msec
, VTY_NEWLINE
);
1016 vty_out(vty
, "Propagation Delay (Highest) : %d msec%s", pim_ifp
->pim_neighbors_highest_propagation_delay_msec
, VTY_NEWLINE
);
1017 vty_out(vty
, "Override Interval : %d msec%s", pim_ifp
->pim_override_interval_msec
, VTY_NEWLINE
);
1018 vty_out(vty
, "Override Interval (Highest) : %d msec%s", pim_ifp
->pim_neighbors_highest_override_interval_msec
, VTY_NEWLINE
);
1019 vty_out(vty
, "%s", VTY_NEWLINE
);
1020 vty_out(vty
, "%s", VTY_NEWLINE
);
1025 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
1026 json_object_free(json
);
1029 vty_out (vty
, "%% No such interface%s", VTY_NEWLINE
);
1033 static void pim_show_interfaces(struct vty
*vty
, u_char uj
)
1035 struct interface
*ifp
;
1036 struct listnode
*node
;
1037 struct listnode
*upnode
;
1038 struct pim_interface
*pim_ifp
;
1039 struct pim_upstream
*up
;
1042 json_object
*json
= NULL
;
1043 json_object
*json_row
= NULL
;
1044 json_object
*json_tmp
;
1046 json
= json_object_new_object();
1048 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
)) {
1049 pim_ifp
= ifp
->info
;
1054 if (pim_ifp
->pim_sock_fd
< 0)
1057 pim_nbrs
= pim_ifp
->pim_neighbor_list
->count
;
1060 for (ALL_LIST_ELEMENTS_RO(pim_upstream_list
, upnode
, up
))
1061 if (ifp
== up
->rpf
.source_nexthop
.interface
)
1062 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
1065 json_row
= json_object_new_object();
1066 json_object_pim_ifp_add(json_row
, ifp
);
1067 json_object_int_add(json_row
, "pimNeighbors", pim_nbrs
);
1068 json_object_int_add(json_row
, "firstHopRouter", fhr
);
1069 json_object_string_add(json_row
, "pimDesignatedRouter", inet_ntoa(pim_ifp
->pim_dr_addr
));
1071 if (pim_ifp
->pim_dr_addr
.s_addr
== pim_ifp
->primary_address
.s_addr
)
1072 json_object_boolean_true_add(json_row
, "pimDesignatedRouterLocal");
1074 json_object_object_add(json
, ifp
->name
, json_row
);
1078 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
1080 vty_out(vty
, "Interface State Address PIM Nbrs PIM DR FHR%s", VTY_NEWLINE
);
1082 json_object_object_foreach(json
, key
, val
) {
1083 vty_out(vty
, "%-9s ", key
);
1085 json_object_object_get_ex(val
, "state", &json_tmp
);
1086 vty_out(vty
, "%5s ", json_object_get_string(json_tmp
));
1088 json_object_object_get_ex(val
, "address", &json_tmp
);
1089 vty_out(vty
, "%15s ", json_object_get_string(json_tmp
));
1091 json_object_object_get_ex(val
, "pimNeighbors", &json_tmp
);
1092 vty_out(vty
, "%8d ", json_object_get_int(json_tmp
));
1094 if (json_object_object_get_ex(val
, "pimDesignatedRouterLocal", &json_tmp
)) {
1095 vty_out(vty
, "%15s ", "local");
1097 json_object_object_get_ex(val
, "pimDesignatedRouter", &json_tmp
);
1098 vty_out(vty
, "%15s ", json_object_get_string(json_tmp
));
1101 json_object_object_get_ex(val
, "firstHopRouter", &json_tmp
);
1102 vty_out(vty
, "%3d%s", json_object_get_int(json_tmp
), VTY_NEWLINE
);
1106 json_object_free(json
);
1109 static void pim_show_join(struct vty
*vty
, u_char uj
)
1111 struct pim_interface
*pim_ifp
;
1112 struct in_addr ifaddr
;
1113 struct listnode
*ch_node
;
1114 struct pim_ifchannel
*ch
;
1116 json_object
*json
= NULL
;
1117 json_object
*json_iface
= NULL
;
1118 json_object
*json_row
= NULL
;
1119 json_object
*json_grp
= NULL
;
1121 now
= pim_time_monotonic_sec();
1124 json
= json_object_new_object();
1127 "Interface Address Source Group State Uptime Expire Prune%s",
1130 for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list
, ch_node
, ch
)) {
1132 pim_ifp
= ch
->interface
->info
;
1137 ifaddr
= pim_ifp
->primary_address
;
1139 char ch_src_str
[INET_ADDRSTRLEN
];
1140 char ch_grp_str
[INET_ADDRSTRLEN
];
1145 pim_inet4_dump("<ch_src?>", ch
->sg
.src
,
1146 ch_src_str
, sizeof(ch_src_str
));
1147 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
,
1148 ch_grp_str
, sizeof(ch_grp_str
));
1150 pim_time_uptime_begin(uptime
, sizeof(uptime
), now
, ch
->ifjoin_creation
);
1151 pim_time_timer_to_mmss(expire
, sizeof(expire
),
1152 ch
->t_ifjoin_expiry_timer
);
1153 pim_time_timer_to_mmss(prune
, sizeof(prune
),
1154 ch
->t_ifjoin_prune_pending_timer
);
1157 json_object_object_get_ex(json
, ch
->interface
->name
, &json_iface
);
1160 json_iface
= json_object_new_object();
1161 json_object_pim_ifp_add(json_iface
, ch
->interface
);
1162 json_object_object_add(json
, ch
->interface
->name
, json_iface
);
1165 json_row
= json_object_new_object();
1166 json_object_string_add(json_row
, "source", ch_src_str
);
1167 json_object_string_add(json_row
, "group", ch_grp_str
);
1168 json_object_string_add(json_row
, "upTime", uptime
);
1169 json_object_string_add(json_row
, "expire", expire
);
1170 json_object_string_add(json_row
, "prune", prune
);
1171 json_object_string_add(json_row
, "channelJoinName", pim_ifchannel_ifjoin_name(ch
->ifjoin_state
));
1172 if (PIM_IF_FLAG_TEST_S_G_RPT(ch
->flags
))
1173 json_object_int_add(json_row
, "SGRpt", 1);
1175 json_object_object_get_ex(json_iface
, ch_grp_str
, &json_grp
);
1178 json_grp
= json_object_new_object();
1179 json_object_object_add(json_grp
, ch_src_str
, json_row
);
1180 json_object_object_add(json_iface
, ch_grp_str
, json_grp
);
1183 json_object_object_add(json_grp
, ch_src_str
, json_row
);
1185 vty_out(vty
, "%-9s %-15s %-15s %-15s %-6s %8s %-6s %5s%s",
1186 ch
->interface
->name
,
1190 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
),
1196 } /* scan interface channels */
1199 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
1200 json_object_free(json
);
1204 static void pim_show_neighbors_single(struct vty
*vty
, const char *neighbor
, u_char uj
)
1206 struct listnode
*node
;
1207 struct listnode
*neighnode
;
1208 struct interface
*ifp
;
1209 struct pim_interface
*pim_ifp
;
1210 struct pim_neighbor
*neigh
;
1212 int found_neighbor
= 0;
1213 int option_address_list
;
1214 int option_dr_priority
;
1215 int option_generation_id
;
1216 int option_holdtime
;
1217 int option_lan_prune_delay
;
1221 char neigh_src_str
[INET_ADDRSTRLEN
];
1223 json_object
*json
= NULL
;
1224 json_object
*json_ifp
= NULL
;
1225 json_object
*json_row
= NULL
;
1227 now
= pim_time_monotonic_sec();
1230 json
= json_object_new_object();
1232 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
)) {
1233 pim_ifp
= ifp
->info
;
1238 if (pim_ifp
->pim_sock_fd
< 0)
1241 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
, neigh
)) {
1242 pim_inet4_dump("<src?>", neigh
->source_addr
,
1243 neigh_src_str
, sizeof(neigh_src_str
));
1246 * The user can specify either the interface name or the PIM neighbor IP.
1247 * If this pim_ifp matches neither then skip.
1249 if (strcmp(neighbor
, "detail") &&
1250 strcmp(neighbor
, ifp
->name
) &&
1251 strcmp(neighbor
, neigh_src_str
))
1255 pim_time_uptime(uptime
, sizeof(uptime
), now
- neigh
->creation
);
1256 pim_time_timer_to_hhmmss(expire
, sizeof(expire
), neigh
->t_expire_timer
);
1258 option_address_list
= 0;
1259 option_dr_priority
= 0;
1260 option_generation_id
= 0;
1261 option_holdtime
= 0;
1262 option_lan_prune_delay
= 0;
1265 if (PIM_OPTION_IS_SET(neigh
->hello_options
, PIM_OPTION_MASK_ADDRESS_LIST
))
1266 option_address_list
= 1;
1268 if (PIM_OPTION_IS_SET(neigh
->hello_options
, PIM_OPTION_MASK_DR_PRIORITY
))
1269 option_dr_priority
= 1;
1271 if (PIM_OPTION_IS_SET(neigh
->hello_options
, PIM_OPTION_MASK_GENERATION_ID
))
1272 option_generation_id
= 1;
1274 if (PIM_OPTION_IS_SET(neigh
->hello_options
, PIM_OPTION_MASK_HOLDTIME
))
1275 option_holdtime
= 1;
1277 if (PIM_OPTION_IS_SET(neigh
->hello_options
, PIM_OPTION_MASK_LAN_PRUNE_DELAY
))
1278 option_lan_prune_delay
= 1;
1280 if (PIM_OPTION_IS_SET(neigh
->hello_options
, PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION
))
1285 /* Does this ifp live in json? If not create it. */
1286 json_object_object_get_ex(json
, ifp
->name
, &json_ifp
);
1289 json_ifp
= json_object_new_object();
1290 json_object_pim_ifp_add(json_ifp
, ifp
);
1291 json_object_object_add(json
, ifp
->name
, json_ifp
);
1294 json_row
= json_object_new_object();
1295 json_object_string_add(json_row
, "interface", ifp
->name
);
1296 json_object_string_add(json_row
, "address", neigh_src_str
);
1297 json_object_string_add(json_row
, "upTime", uptime
);
1298 json_object_string_add(json_row
, "holdtime", expire
);
1299 json_object_int_add(json_row
, "drPriority", neigh
->dr_priority
);
1300 json_object_int_add(json_row
, "generationId", neigh
->generation_id
);
1302 if (option_address_list
)
1303 json_object_boolean_true_add(json_row
, "helloOptionAddressList");
1305 if (option_dr_priority
)
1306 json_object_boolean_true_add(json_row
, "helloOptionDrPriority");
1308 if (option_generation_id
)
1309 json_object_boolean_true_add(json_row
, "helloOptionGenerationId");
1311 if (option_holdtime
)
1312 json_object_boolean_true_add(json_row
, "helloOptionHoldtime");
1314 if (option_lan_prune_delay
)
1315 json_object_boolean_true_add(json_row
, "helloOptionLanPruneDelay");
1318 json_object_boolean_true_add(json_row
, "helloOptionTBit");
1320 json_object_object_add(json_ifp
, neigh_src_str
, json_row
);
1323 vty_out(vty
, "Interface : %s%s", ifp
->name
, VTY_NEWLINE
);
1324 vty_out(vty
, "Neighbor : %s%s", neigh_src_str
, VTY_NEWLINE
);
1325 vty_out(vty
, " Uptime : %s%s", uptime
, VTY_NEWLINE
);
1326 vty_out(vty
, " Holdtime : %s%s", expire
, VTY_NEWLINE
);
1327 vty_out(vty
, " DR Priority : %d%s", neigh
->dr_priority
, VTY_NEWLINE
);
1328 vty_out(vty
, " Generation ID : %08x%s", neigh
->generation_id
, VTY_NEWLINE
);
1329 vty_out(vty
, " Override Interval (msec) : %d%s", neigh
->override_interval_msec
, VTY_NEWLINE
);
1330 vty_out(vty
, " Propagation Delay (msec) : %d%s", neigh
->propagation_delay_msec
, VTY_NEWLINE
);
1331 vty_out(vty
, " Hello Option - Address List : %s%s", option_address_list
? "yes" : "no", VTY_NEWLINE
);
1332 vty_out(vty
, " Hello Option - DR Priority : %s%s", option_dr_priority
? "yes" : "no", VTY_NEWLINE
);
1333 vty_out(vty
, " Hello Option - Generation ID : %s%s", option_generation_id
? "yes" : "no", VTY_NEWLINE
);
1334 vty_out(vty
, " Hello Option - Holdtime : %s%s", option_holdtime
? "yes" : "no", VTY_NEWLINE
);
1335 vty_out(vty
, " Hello Option - LAN Prune Delay : %s%s", option_lan_prune_delay
? "yes" : "no", VTY_NEWLINE
);
1336 vty_out(vty
, " Hello Option - T-bit : %s%s", option_t_bit
? "yes" : "no", VTY_NEWLINE
);
1337 vty_out(vty
, "%s", VTY_NEWLINE
);
1343 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
1344 json_object_free(json
);
1347 if (!found_neighbor
)
1348 vty_out (vty
, "%% No such interface or neighbor%s", VTY_NEWLINE
);
1354 pim_show_state(struct vty
*vty
, const char *src_or_group
, const char *group
, u_char uj
)
1356 struct channel_oil
*c_oil
;
1357 struct listnode
*node
;
1358 json_object
*json
= NULL
;
1359 json_object
*json_group
= NULL
;
1360 json_object
*json_ifp_in
= NULL
;
1361 json_object
*json_ifp_out
= NULL
;
1362 json_object
*json_source
= NULL
;
1365 now
= pim_time_monotonic_sec();
1368 json
= json_object_new_object();
1370 vty_out(vty
, "Codes: J -> Pim Join, I -> IGMP Report, S -> Source, * -> Inherited from (*,G)");
1371 vty_out(vty
, "%sInstalled Source Group IIF OIL%s", VTY_NEWLINE
, VTY_NEWLINE
);
1374 for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list
, node
, c_oil
)) {
1375 char grp_str
[INET_ADDRSTRLEN
];
1376 char src_str
[INET_ADDRSTRLEN
];
1377 char in_ifname
[INTERFACE_NAMSIZ
+1];
1378 char out_ifname
[INTERFACE_NAMSIZ
+1];
1380 struct interface
*ifp_in
;
1383 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
, sizeof(grp_str
));
1384 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
, sizeof(src_str
));
1385 ifp_in
= pim_if_find_by_vif_index(c_oil
->oil
.mfcc_parent
);
1388 strcpy(in_ifname
, ifp_in
->name
);
1390 strcpy(in_ifname
, "<iif?>");
1394 if (strcmp(src_or_group
, src_str
) && strcmp(src_or_group
, grp_str
))
1397 if (group
&& strcmp(group
, grp_str
))
1403 /* Find the group, create it if it doesn't exist */
1404 json_object_object_get_ex(json
, grp_str
, &json_group
);
1407 json_group
= json_object_new_object();
1408 json_object_object_add(json
, grp_str
, json_group
);
1411 /* Find the source nested under the group, create it if it doesn't exist */
1412 json_object_object_get_ex(json_group
, src_str
, &json_source
);
1415 json_source
= json_object_new_object();
1416 json_object_object_add(json_group
, src_str
, json_source
);
1419 /* Find the inbound interface nested under the source, create it if it doesn't exist */
1420 json_object_object_get_ex(json_source
, in_ifname
, &json_ifp_in
);
1423 json_ifp_in
= json_object_new_object();
1424 json_object_object_add(json_source
, in_ifname
, json_ifp_in
);
1427 vty_out(vty
, "%-9d %-15s %-15s %-7s ",
1434 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
; ++oif_vif_index
) {
1435 struct interface
*ifp_out
;
1436 char oif_uptime
[10];
1439 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
1443 ifp_out
= pim_if_find_by_vif_index(oif_vif_index
);
1444 pim_time_uptime(oif_uptime
, sizeof(oif_uptime
), now
- c_oil
->oif_creation
[oif_vif_index
]);
1447 strcpy(out_ifname
, ifp_out
->name
);
1449 strcpy(out_ifname
, "<oif?>");
1452 json_ifp_out
= json_object_new_object();
1453 json_object_string_add(json_ifp_out
, "source", src_str
);
1454 json_object_string_add(json_ifp_out
, "group", grp_str
);
1455 json_object_string_add(json_ifp_out
, "inboundInterface", in_ifname
);
1456 json_object_string_add(json_ifp_out
, "outboundInterface", out_ifname
);
1457 json_object_int_add(json_ifp_out
, "installed", c_oil
->installed
);
1459 json_object_object_add(json_ifp_in
, out_ifname
, json_ifp_out
);
1464 vty_out(vty
, "%s(%c%c%c%c)", out_ifname
,
1465 (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_IGMP
) ? 'I' : ' ',
1466 (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_PIM
) ? 'J' : ' ',
1467 (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_SOURCE
) ? 'S' : ' ',
1468 (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_STAR
) ? '*' : ' ');
1471 vty_out(vty
, ", %s(%c%c%c%c)", out_ifname
,
1472 (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_IGMP
) ? 'I' : ' ',
1473 (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_PIM
) ? 'J' : ' ',
1474 (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_SOURCE
) ? 'S' : ' ',
1475 (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_STAR
) ? '*' : ' ' );
1480 vty_out(vty
, "%s", VTY_NEWLINE
);
1485 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
1486 json_object_free(json
);
1488 vty_out(vty
, "%s", VTY_NEWLINE
);
1492 static void pim_show_neighbors(struct vty
*vty
, u_char uj
)
1494 struct listnode
*node
;
1495 struct listnode
*neighnode
;
1496 struct interface
*ifp
;
1497 struct pim_interface
*pim_ifp
;
1498 struct pim_neighbor
*neigh
;
1502 char neigh_src_str
[INET_ADDRSTRLEN
];
1503 json_object
*json
= NULL
;
1504 json_object
*json_ifp_rows
= NULL
;
1505 json_object
*json_row
= NULL
;
1507 now
= pim_time_monotonic_sec();
1510 json
= json_object_new_object();
1512 vty_out(vty
, "Interface Neighbor Uptime Holdtime DR Pri%s", VTY_NEWLINE
);
1515 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
)) {
1516 pim_ifp
= ifp
->info
;
1521 if (pim_ifp
->pim_sock_fd
< 0)
1525 json_ifp_rows
= json_object_new_object();
1527 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
, neigh
)) {
1528 pim_inet4_dump("<src?>", neigh
->source_addr
,
1529 neigh_src_str
, sizeof(neigh_src_str
));
1530 pim_time_uptime(uptime
, sizeof(uptime
), now
- neigh
->creation
);
1531 pim_time_timer_to_hhmmss(expire
, sizeof(expire
), neigh
->t_expire_timer
);
1534 json_row
= json_object_new_object();
1535 json_object_string_add(json_row
, "interface", ifp
->name
);
1536 json_object_string_add(json_row
, "neighbor", neigh_src_str
);
1537 json_object_string_add(json_row
, "upTime", uptime
);
1538 json_object_string_add(json_row
, "holdTime", expire
);
1539 json_object_int_add(json_row
, "holdTimeMax", neigh
->holdtime
);
1540 json_object_int_add(json_row
, "drPriority", neigh
->dr_priority
);
1541 json_object_object_add(json_ifp_rows
, neigh_src_str
, json_row
);
1544 vty_out(vty
, "%-9s %15s %8s %8s %6d%s",
1555 json_object_object_add(json
, ifp
->name
, json_ifp_rows
);
1556 json_ifp_rows
= NULL
;
1561 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
1562 json_object_free(json
);
1566 static void pim_show_neighbors_secondary(struct vty
*vty
)
1568 struct listnode
*node
;
1569 struct interface
*ifp
;
1571 vty_out(vty
, "Interface Address Neighbor Secondary %s", VTY_NEWLINE
);
1573 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
)) {
1574 struct pim_interface
*pim_ifp
;
1575 struct in_addr ifaddr
;
1576 struct listnode
*neighnode
;
1577 struct pim_neighbor
*neigh
;
1579 pim_ifp
= ifp
->info
;
1584 if (pim_ifp
->pim_sock_fd
< 0)
1587 ifaddr
= pim_ifp
->primary_address
;
1589 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
, neigh
)) {
1590 char neigh_src_str
[INET_ADDRSTRLEN
];
1591 struct listnode
*prefix_node
;
1594 if (!neigh
->prefix_list
)
1597 pim_inet4_dump("<src?>", neigh
->source_addr
,
1598 neigh_src_str
, sizeof(neigh_src_str
));
1600 for (ALL_LIST_ELEMENTS_RO(neigh
->prefix_list
, prefix_node
, p
)) {
1601 char neigh_sec_str
[INET_ADDRSTRLEN
];
1603 if (p
->family
!= AF_INET
)
1606 pim_inet4_dump("<src?>", p
->u
.prefix4
,
1607 neigh_sec_str
, sizeof(neigh_sec_str
));
1609 vty_out(vty
, "%-9s %-15s %-15s %-15s%s",
1621 json_object_pim_upstream_add (json_object
*json
, struct pim_upstream
*up
)
1623 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED
)
1624 json_object_boolean_true_add(json
, "drJoinDesired");
1626 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED
)
1627 json_object_boolean_true_add(json
, "drJoinDesiredUpdated");
1629 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
1630 json_object_boolean_true_add(json
, "firstHopRouter");
1632 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_IGMP
)
1633 json_object_boolean_true_add(json
, "sourceIgmp");
1635 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_PIM
)
1636 json_object_boolean_true_add(json
, "sourcePim");
1638 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_STREAM
)
1639 json_object_boolean_true_add(json
, "sourceStream");
1641 /* XXX: need to print ths flag in the plain text display as well */
1642 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_MSDP
)
1643 json_object_boolean_true_add(json
, "sourceMsdp");
1647 pim_upstream_state2brief_str (enum pim_upstream_state join_state
, char *state_str
)
1651 case PIM_UPSTREAM_NOTJOINED
:
1652 strcpy (state_str
, "NotJ");
1654 case PIM_UPSTREAM_JOINED
:
1655 strcpy (state_str
, "J");
1658 strcpy (state_str
, "Unk");
1664 pim_reg_state2brief_str (enum pim_reg_state reg_state
, char *state_str
)
1668 case PIM_REG_NOINFO
:
1669 strcpy (state_str
, "RegNI");
1672 strcpy (state_str
, "RegJ");
1674 case PIM_REG_JOIN_PENDING
:
1676 strcpy (state_str
, "RegP");
1679 strcpy (state_str
, "Unk");
1684 static void pim_show_upstream(struct vty
*vty
, u_char uj
)
1686 struct listnode
*upnode
;
1687 struct pim_upstream
*up
;
1689 json_object
*json
= NULL
;
1690 json_object
*json_group
= NULL
;
1691 json_object
*json_row
= NULL
;
1693 now
= pim_time_monotonic_sec();
1696 json
= json_object_new_object();
1698 vty_out(vty
, "Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt%s", VTY_NEWLINE
);
1700 for (ALL_LIST_ELEMENTS_RO(pim_upstream_list
, upnode
, up
)) {
1701 char src_str
[INET_ADDRSTRLEN
];
1702 char grp_str
[INET_ADDRSTRLEN
];
1704 char join_timer
[10];
1707 char msdp_reg_timer
[10];
1708 char state_str
[PIM_REG_STATE_STR_LEN
];
1710 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
1711 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
1712 pim_time_uptime(uptime
, sizeof(uptime
), now
- up
->state_transition
);
1713 pim_time_timer_to_hhmmss (join_timer
, sizeof(join_timer
), up
->t_join_timer
);
1716 * If we have a J/P timer for the neighbor display that
1718 if (!up
->t_join_timer
)
1720 struct pim_neighbor
*nbr
;
1722 nbr
= pim_neighbor_find (up
->rpf
.source_nexthop
.interface
,
1723 up
->rpf
.rpf_addr
.u
.prefix4
);
1725 pim_time_timer_to_hhmmss (join_timer
, sizeof(join_timer
), nbr
->jp_timer
);
1728 pim_time_timer_to_hhmmss (rs_timer
, sizeof (rs_timer
), up
->t_rs_timer
);
1729 pim_time_timer_to_hhmmss (ka_timer
, sizeof (ka_timer
), up
->t_ka_timer
);
1730 pim_time_timer_to_hhmmss (msdp_reg_timer
, sizeof (msdp_reg_timer
), up
->t_msdp_reg_timer
);
1732 pim_upstream_state2brief_str (up
->join_state
, state_str
);
1733 if (up
->reg_state
!= PIM_REG_NOINFO
) {
1734 char tmp_str
[PIM_REG_STATE_STR_LEN
];
1736 sprintf (state_str
+ strlen (state_str
), ",%s",
1737 pim_reg_state2brief_str (up
->reg_state
, tmp_str
));
1741 json_object_object_get_ex(json
, grp_str
, &json_group
);
1744 json_group
= json_object_new_object();
1745 json_object_object_add(json
, grp_str
, json_group
);
1748 json_row
= json_object_new_object();
1749 json_object_pim_upstream_add(json_row
, up
);
1750 json_object_string_add(json_row
, "inboundInterface", up
->rpf
.source_nexthop
.interface
->name
);
1751 json_object_string_add(json_row
, "source", src_str
);
1752 json_object_string_add(json_row
, "group", grp_str
);
1753 json_object_string_add(json_row
, "state", state_str
);
1754 json_object_string_add(json_row
, "joinState", pim_upstream_state2str (up
->join_state
));
1755 json_object_string_add(json_row
, "regState", pim_reg_state2str (up
->reg_state
, state_str
));
1756 json_object_string_add(json_row
, "upTime", uptime
);
1757 json_object_string_add(json_row
, "joinTimer", join_timer
);
1758 json_object_string_add(json_row
, "resetTimer", rs_timer
);
1759 json_object_string_add(json_row
, "keepaliveTimer", ka_timer
);
1760 json_object_string_add(json_row
, "msdpRegTimer", msdp_reg_timer
);
1761 json_object_int_add(json_row
, "refCount", up
->ref_count
);
1762 json_object_int_add(json_row
, "sptBit", up
->sptbit
);
1763 json_object_object_add(json_group
, src_str
, json_row
);
1765 vty_out(vty
, "%-10s%-15s %-15s %-11s %-8s %-9s %-9s %-9s %6d%s",
1766 up
->rpf
.source_nexthop
.interface
->name
,
1780 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
1781 json_object_free(json
);
1785 static void pim_show_join_desired(struct vty
*vty
, u_char uj
)
1787 struct listnode
*chnode
;
1788 struct pim_interface
*pim_ifp
;
1789 struct pim_ifchannel
*ch
;
1790 char src_str
[INET_ADDRSTRLEN
];
1791 char grp_str
[INET_ADDRSTRLEN
];
1792 json_object
*json
= NULL
;
1793 json_object
*json_group
= NULL
;
1794 json_object
*json_row
= NULL
;
1797 json
= json_object_new_object();
1800 "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD%s",
1803 /* scan per-interface (S,G) state */
1804 for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list
, chnode
, ch
)) {
1805 /* scan all interfaces */
1806 pim_ifp
= ch
->interface
->info
;
1810 struct pim_upstream
*up
= ch
->upstream
;
1812 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
1813 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
1816 json_object_object_get_ex(json
, grp_str
, &json_group
);
1819 json_group
= json_object_new_object();
1820 json_object_object_add(json
, grp_str
, json_group
);
1823 json_row
= json_object_new_object();
1824 json_object_pim_upstream_add(json_row
, up
);
1825 json_object_string_add(json_row
, "interface", ch
->interface
->name
);
1826 json_object_string_add(json_row
, "source", src_str
);
1827 json_object_string_add(json_row
, "group", grp_str
);
1829 if (pim_macro_ch_lost_assert(ch
))
1830 json_object_boolean_true_add(json_row
, "lostAssert");
1832 if (pim_macro_chisin_joins(ch
))
1833 json_object_boolean_true_add(json_row
, "joins");
1835 if (pim_macro_chisin_pim_include(ch
))
1836 json_object_boolean_true_add(json_row
, "pimInclude");
1838 if (pim_upstream_evaluate_join_desired(up
))
1839 json_object_boolean_true_add(json_row
, "evaluateJoinDesired");
1841 json_object_object_add(json_group
, src_str
, json_row
);
1844 vty_out(vty
, "%-9s %-15s %-15s %-10s %-5s %-10s %-11s %-6s%s",
1845 ch
->interface
->name
,
1848 pim_macro_ch_lost_assert(ch
) ? "yes" : "no",
1849 pim_macro_chisin_joins(ch
) ? "yes" : "no",
1850 pim_macro_chisin_pim_include(ch
) ? "yes" : "no",
1851 PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(up
->flags
) ? "yes" : "no",
1852 pim_upstream_evaluate_join_desired(up
) ? "yes" : "no",
1858 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
1859 json_object_free(json
);
1863 static void pim_show_upstream_rpf(struct vty
*vty
, u_char uj
)
1865 struct listnode
*upnode
;
1866 struct pim_upstream
*up
;
1867 json_object
*json
= NULL
;
1868 json_object
*json_group
= NULL
;
1869 json_object
*json_row
= NULL
;
1872 json
= json_object_new_object();
1875 "Source Group RpfIface RibNextHop RpfAddress %s",
1878 for (ALL_LIST_ELEMENTS_RO(pim_upstream_list
, upnode
, up
)) {
1879 char src_str
[INET_ADDRSTRLEN
];
1880 char grp_str
[INET_ADDRSTRLEN
];
1881 char rpf_nexthop_str
[PREFIX_STRLEN
];
1882 char rpf_addr_str
[PREFIX_STRLEN
];
1883 struct pim_rpf
*rpf
;
1884 const char *rpf_ifname
;
1888 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
1889 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
1890 pim_addr_dump("<nexthop?>", &rpf
->source_nexthop
.mrib_nexthop_addr
, rpf_nexthop_str
, sizeof(rpf_nexthop_str
));
1891 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
, sizeof(rpf_addr_str
));
1893 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
1896 json_object_object_get_ex(json
, grp_str
, &json_group
);
1899 json_group
= json_object_new_object();
1900 json_object_object_add(json
, grp_str
, json_group
);
1903 json_row
= json_object_new_object();
1904 json_object_pim_upstream_add(json_row
, up
);
1905 json_object_string_add(json_row
, "source", src_str
);
1906 json_object_string_add(json_row
, "group", grp_str
);
1907 json_object_string_add(json_row
, "rpfInterface", rpf_ifname
);
1908 json_object_string_add(json_row
, "ribNexthop", rpf_nexthop_str
);
1909 json_object_string_add(json_row
, "rpfAddress", rpf_addr_str
);
1910 json_object_object_add(json_group
, src_str
, json_row
);
1912 vty_out(vty
, "%-15s %-15s %-8s %-15s %-15s%s",
1923 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
1924 json_object_free(json
);
1928 static void show_rpf_refresh_stats(struct vty
*vty
, time_t now
, json_object
*json
)
1930 char refresh_uptime
[10];
1932 pim_time_uptime_begin(refresh_uptime
, sizeof(refresh_uptime
), now
, qpim_rpf_cache_refresh_last
);
1935 json_object_int_add(json
, "rpfCacheRefreshDelayMsecs", qpim_rpf_cache_refresh_delay_msec
);
1936 json_object_int_add(json
, "rpfCacheRefreshTimer", pim_time_timer_remain_msec(qpim_rpf_cache_refresher
));
1937 json_object_int_add(json
, "rpfCacheRefreshRequests", qpim_rpf_cache_refresh_requests
);
1938 json_object_int_add(json
, "rpfCacheRefreshEvents", qpim_rpf_cache_refresh_events
);
1939 json_object_string_add(json
, "rpfCacheRefreshLast", refresh_uptime
);
1940 json_object_int_add(json
, "nexthopLookups", qpim_nexthop_lookups
);
1941 json_object_int_add(json
, "nexthopLookupsAvoided", nexthop_lookups_avoided
);
1944 "RPF Cache Refresh Delay: %ld msecs%s"
1945 "RPF Cache Refresh Timer: %ld msecs%s"
1946 "RPF Cache Refresh Requests: %lld%s"
1947 "RPF Cache Refresh Events: %lld%s"
1948 "RPF Cache Refresh Last: %s%s"
1949 "Nexthop Lookups: %lld%s"
1950 "Nexthop Lookups Avoided: %lld%s",
1951 qpim_rpf_cache_refresh_delay_msec
, VTY_NEWLINE
,
1952 pim_time_timer_remain_msec(qpim_rpf_cache_refresher
), VTY_NEWLINE
,
1953 (long long)qpim_rpf_cache_refresh_requests
, VTY_NEWLINE
,
1954 (long long)qpim_rpf_cache_refresh_events
, VTY_NEWLINE
,
1955 refresh_uptime
, VTY_NEWLINE
,
1956 (long long) qpim_nexthop_lookups
, VTY_NEWLINE
,
1957 (long long)nexthop_lookups_avoided
, VTY_NEWLINE
);
1961 static void show_scan_oil_stats(struct vty
*vty
, time_t now
)
1963 char uptime_scan_oil
[10];
1964 char uptime_mroute_add
[10];
1965 char uptime_mroute_del
[10];
1967 pim_time_uptime_begin(uptime_scan_oil
, sizeof(uptime_scan_oil
), now
, qpim_scan_oil_last
);
1968 pim_time_uptime_begin(uptime_mroute_add
, sizeof(uptime_mroute_add
), now
, qpim_mroute_add_last
);
1969 pim_time_uptime_begin(uptime_mroute_del
, sizeof(uptime_mroute_del
), now
, qpim_mroute_del_last
);
1972 "Scan OIL - Last: %s Events: %lld%s"
1973 "MFC Add - Last: %s Events: %lld%s"
1974 "MFC Del - Last: %s Events: %lld%s",
1975 uptime_scan_oil
, (long long) qpim_scan_oil_events
, VTY_NEWLINE
,
1976 uptime_mroute_add
, (long long) qpim_mroute_add_events
, VTY_NEWLINE
,
1977 uptime_mroute_del
, (long long) qpim_mroute_del_events
, VTY_NEWLINE
);
1980 static void pim_show_rpf(struct vty
*vty
, u_char uj
)
1982 struct listnode
*up_node
;
1983 struct pim_upstream
*up
;
1984 time_t now
= pim_time_monotonic_sec();
1985 json_object
*json
= NULL
;
1986 json_object
*json_group
= NULL
;
1987 json_object
*json_row
= NULL
;
1990 json
= json_object_new_object();
1991 show_rpf_refresh_stats(vty
, now
, json
);
1993 show_rpf_refresh_stats(vty
, now
, json
);
1994 vty_out(vty
, "%s", VTY_NEWLINE
);
1996 "Source Group RpfIface RpfAddress RibNextHop Metric Pref%s",
2000 for (ALL_LIST_ELEMENTS_RO(pim_upstream_list
, up_node
, up
)) {
2001 char src_str
[INET_ADDRSTRLEN
];
2002 char grp_str
[INET_ADDRSTRLEN
];
2003 char rpf_addr_str
[PREFIX_STRLEN
];
2004 char rib_nexthop_str
[PREFIX_STRLEN
];
2005 const char *rpf_ifname
;
2006 struct pim_rpf
*rpf
= &up
->rpf
;
2008 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2009 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2010 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
, sizeof(rpf_addr_str
));
2011 pim_addr_dump("<nexthop?>", &rpf
->source_nexthop
.mrib_nexthop_addr
, rib_nexthop_str
, sizeof(rib_nexthop_str
));
2013 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2016 json_object_object_get_ex(json
, grp_str
, &json_group
);
2019 json_group
= json_object_new_object();
2020 json_object_object_add(json
, grp_str
, json_group
);
2023 json_row
= json_object_new_object();
2024 json_object_string_add(json_row
, "source", src_str
);
2025 json_object_string_add(json_row
, "group", grp_str
);
2026 json_object_string_add(json_row
, "rpfInterface", rpf_ifname
);
2027 json_object_string_add(json_row
, "rpfAddress", rpf_addr_str
);
2028 json_object_string_add(json_row
, "ribNexthop", rib_nexthop_str
);
2029 json_object_int_add(json_row
, "routeMetric", rpf
->source_nexthop
.mrib_route_metric
);
2030 json_object_int_add(json_row
, "routePreference", rpf
->source_nexthop
.mrib_metric_preference
);
2031 json_object_object_add(json_group
, src_str
, json_row
);
2034 vty_out(vty
, "%-15s %-15s %-8s %-15s %-15s %6d %4d%s",
2040 rpf
->source_nexthop
.mrib_route_metric
,
2041 rpf
->source_nexthop
.mrib_metric_preference
,
2047 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
2048 json_object_free(json
);
2052 static void igmp_show_groups(struct vty
*vty
, u_char uj
)
2054 struct listnode
*ifnode
;
2055 struct interface
*ifp
;
2057 json_object
*json
= NULL
;
2058 json_object
*json_iface
= NULL
;
2059 json_object
*json_row
= NULL
;
2061 now
= pim_time_monotonic_sec();
2064 json
= json_object_new_object();
2066 vty_out(vty
, "Interface Address Group Mode Timer Srcs V Uptime %s", VTY_NEWLINE
);
2068 /* scan interfaces */
2069 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), ifnode
, ifp
)) {
2070 struct pim_interface
*pim_ifp
= ifp
->info
;
2071 struct listnode
*sock_node
;
2072 struct igmp_sock
*igmp
;
2077 /* scan igmp sockets */
2078 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
2079 char ifaddr_str
[INET_ADDRSTRLEN
];
2080 struct listnode
*grpnode
;
2081 struct igmp_group
*grp
;
2083 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
, sizeof(ifaddr_str
));
2085 /* scan igmp groups */
2086 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grpnode
, grp
)) {
2087 char group_str
[INET_ADDRSTRLEN
];
2091 pim_inet4_dump("<group?>", grp
->group_addr
, group_str
, sizeof(group_str
));
2092 pim_time_timer_to_hhmmss(hhmmss
, sizeof(hhmmss
), grp
->t_group_timer
);
2093 pim_time_uptime(uptime
, sizeof(uptime
), now
- grp
->group_creation
);
2096 json_object_object_get_ex(json
, ifp
->name
, &json_iface
);
2099 json_iface
= json_object_new_object();
2100 json_object_pim_ifp_add(json_iface
, ifp
);
2101 json_object_object_add(json
, ifp
->name
, json_iface
);
2104 json_row
= json_object_new_object();
2105 json_object_string_add(json_row
, "source", ifaddr_str
);
2106 json_object_string_add(json_row
, "group", group_str
);
2108 if (grp
->igmp_version
== 3)
2109 json_object_string_add(json_row
, "mode", grp
->group_filtermode_isexcl
? "EXCLUDE" : "INCLUDE");
2111 json_object_string_add(json_row
, "timer", hhmmss
);
2112 json_object_int_add(json_row
, "sourcesCount", grp
->group_source_list
? listcount(grp
->group_source_list
) : 0);
2113 json_object_int_add(json_row
, "version", grp
->igmp_version
);
2114 json_object_string_add(json_row
, "uptime", uptime
);
2115 json_object_object_add(json_iface
, group_str
, json_row
);
2118 vty_out(vty
, "%-9s %-15s %-15s %4s %8s %4d %d %8s%s",
2122 grp
->igmp_version
== 3 ? (grp
->group_filtermode_isexcl
? "EXCL" : "INCL") : "----",
2124 grp
->group_source_list
? listcount(grp
->group_source_list
) : 0,
2129 } /* scan igmp groups */
2130 } /* scan igmp sockets */
2131 } /* scan interfaces */
2134 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
2135 json_object_free(json
);
2139 static void igmp_show_group_retransmission(struct vty
*vty
)
2141 struct listnode
*ifnode
;
2142 struct interface
*ifp
;
2144 vty_out(vty
, "Interface Address Group RetTimer Counter RetSrcs%s", VTY_NEWLINE
);
2146 /* scan interfaces */
2147 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), ifnode
, ifp
)) {
2148 struct pim_interface
*pim_ifp
= ifp
->info
;
2149 struct listnode
*sock_node
;
2150 struct igmp_sock
*igmp
;
2155 /* scan igmp sockets */
2156 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
2157 char ifaddr_str
[INET_ADDRSTRLEN
];
2158 struct listnode
*grpnode
;
2159 struct igmp_group
*grp
;
2161 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
, sizeof(ifaddr_str
));
2163 /* scan igmp groups */
2164 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grpnode
, grp
)) {
2165 char group_str
[INET_ADDRSTRLEN
];
2166 char grp_retr_mmss
[10];
2167 struct listnode
*src_node
;
2168 struct igmp_source
*src
;
2169 int grp_retr_sources
= 0;
2171 pim_inet4_dump("<group?>", grp
->group_addr
, group_str
, sizeof(group_str
));
2172 pim_time_timer_to_mmss(grp_retr_mmss
, sizeof(grp_retr_mmss
), grp
->t_group_query_retransmit_timer
);
2175 /* count group sources with retransmission state */
2176 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
, src_node
, src
)) {
2177 if (src
->source_query_retransmit_count
> 0) {
2182 vty_out(vty
, "%-9s %-15s %-15s %-8s %7d %7d%s",
2187 grp
->group_specific_query_retransmit_count
,
2191 } /* scan igmp groups */
2192 } /* scan igmp sockets */
2193 } /* scan interfaces */
2196 static void igmp_show_sources(struct vty
*vty
)
2198 struct listnode
*ifnode
;
2199 struct interface
*ifp
;
2202 now
= pim_time_monotonic_sec();
2204 vty_out(vty
, "Interface Address Group Source Timer Fwd Uptime %s", VTY_NEWLINE
);
2206 /* scan interfaces */
2207 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), ifnode
, ifp
)) {
2208 struct pim_interface
*pim_ifp
= ifp
->info
;
2209 struct listnode
*sock_node
;
2210 struct igmp_sock
*igmp
;
2215 /* scan igmp sockets */
2216 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
2217 char ifaddr_str
[INET_ADDRSTRLEN
];
2218 struct listnode
*grpnode
;
2219 struct igmp_group
*grp
;
2221 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
, sizeof(ifaddr_str
));
2223 /* scan igmp groups */
2224 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grpnode
, grp
)) {
2225 char group_str
[INET_ADDRSTRLEN
];
2226 struct listnode
*srcnode
;
2227 struct igmp_source
*src
;
2229 pim_inet4_dump("<group?>", grp
->group_addr
, group_str
, sizeof(group_str
));
2231 /* scan group sources */
2232 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
, srcnode
, src
)) {
2233 char source_str
[INET_ADDRSTRLEN
];
2237 pim_inet4_dump("<source?>", src
->source_addr
, source_str
, sizeof(source_str
));
2239 pim_time_timer_to_mmss(mmss
, sizeof(mmss
), src
->t_source_timer
);
2241 pim_time_uptime(uptime
, sizeof(uptime
), now
- src
->source_creation
);
2243 vty_out(vty
, "%-9s %-15s %-15s %-15s %5s %3s %8s%s",
2249 IGMP_SOURCE_TEST_FORWARDING(src
->source_flags
) ? "Y" : "N",
2253 } /* scan group sources */
2254 } /* scan igmp groups */
2255 } /* scan igmp sockets */
2256 } /* scan interfaces */
2259 static void igmp_show_source_retransmission(struct vty
*vty
)
2261 struct listnode
*ifnode
;
2262 struct interface
*ifp
;
2264 vty_out(vty
, "Interface Address Group Source Counter%s", VTY_NEWLINE
);
2266 /* scan interfaces */
2267 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), ifnode
, ifp
)) {
2268 struct pim_interface
*pim_ifp
= ifp
->info
;
2269 struct listnode
*sock_node
;
2270 struct igmp_sock
*igmp
;
2275 /* scan igmp sockets */
2276 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
2277 char ifaddr_str
[INET_ADDRSTRLEN
];
2278 struct listnode
*grpnode
;
2279 struct igmp_group
*grp
;
2281 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
, sizeof(ifaddr_str
));
2283 /* scan igmp groups */
2284 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grpnode
, grp
)) {
2285 char group_str
[INET_ADDRSTRLEN
];
2286 struct listnode
*srcnode
;
2287 struct igmp_source
*src
;
2289 pim_inet4_dump("<group?>", grp
->group_addr
, group_str
, sizeof(group_str
));
2291 /* scan group sources */
2292 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
, srcnode
, src
)) {
2293 char source_str
[INET_ADDRSTRLEN
];
2295 pim_inet4_dump("<source?>", src
->source_addr
, source_str
, sizeof(source_str
));
2297 vty_out(vty
, "%-9s %-15s %-15s %-15s %7d%s",
2302 src
->source_query_retransmit_count
,
2305 } /* scan group sources */
2306 } /* scan igmp groups */
2307 } /* scan igmp sockets */
2308 } /* scan interfaces */
2311 static void clear_igmp_interfaces()
2313 struct listnode
*ifnode
;
2314 struct listnode
*ifnextnode
;
2315 struct interface
*ifp
;
2317 for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT
), ifnode
, ifnextnode
, ifp
)) {
2318 pim_if_addr_del_all_igmp(ifp
);
2321 for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT
), ifnode
, ifnextnode
, ifp
)) {
2322 pim_if_addr_add_all(ifp
);
2326 static void clear_pim_interfaces()
2328 struct listnode
*ifnode
;
2329 struct listnode
*ifnextnode
;
2330 struct interface
*ifp
;
2332 for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT
), ifnode
, ifnextnode
, ifp
)) {
2334 pim_neighbor_delete_all(ifp
, "interface cleared");
2339 static void clear_interfaces()
2341 clear_igmp_interfaces();
2342 clear_pim_interfaces();
2345 DEFUN (clear_ip_interfaces
,
2346 clear_ip_interfaces_cmd
,
2347 "clear ip interfaces",
2350 "Reset interfaces\n")
2357 DEFUN (clear_ip_igmp_interfaces
,
2358 clear_ip_igmp_interfaces_cmd
,
2359 "clear ip igmp interfaces",
2363 "Reset IGMP interfaces\n")
2365 clear_igmp_interfaces();
2370 static void mroute_add_all()
2372 struct listnode
*node
;
2373 struct channel_oil
*c_oil
;
2375 for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list
, node
, c_oil
)) {
2376 if (pim_mroute_add(c_oil
, __PRETTY_FUNCTION__
)) {
2377 /* just log warning */
2378 char source_str
[INET_ADDRSTRLEN
];
2379 char group_str
[INET_ADDRSTRLEN
];
2380 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, source_str
, sizeof(source_str
));
2381 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, group_str
, sizeof(group_str
));
2382 zlog_warn("%s %s: (S,G)=(%s,%s) failure writing MFC",
2383 __FILE__
, __PRETTY_FUNCTION__
,
2384 source_str
, group_str
);
2389 static void mroute_del_all()
2391 struct listnode
*node
;
2392 struct channel_oil
*c_oil
;
2394 for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list
, node
, c_oil
)) {
2395 if (pim_mroute_del(c_oil
, __PRETTY_FUNCTION__
)) {
2396 /* just log warning */
2397 char source_str
[INET_ADDRSTRLEN
];
2398 char group_str
[INET_ADDRSTRLEN
];
2399 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, source_str
, sizeof(source_str
));
2400 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, group_str
, sizeof(group_str
));
2401 zlog_warn("%s %s: (S,G)=(%s,%s) failure clearing MFC",
2402 __FILE__
, __PRETTY_FUNCTION__
,
2403 source_str
, group_str
);
2408 DEFUN (clear_ip_mroute
,
2409 clear_ip_mroute_cmd
,
2413 "Reset multicast routes\n")
2421 DEFUN (clear_ip_pim_interfaces
,
2422 clear_ip_pim_interfaces_cmd
,
2423 "clear ip pim interfaces",
2427 "Reset PIM interfaces\n")
2429 clear_pim_interfaces();
2434 DEFUN (clear_ip_pim_oil
,
2435 clear_ip_pim_oil_cmd
,
2440 "Rescan PIM OIL (output interface list)\n")
2447 DEFUN (show_ip_igmp_interface
,
2448 show_ip_igmp_interface_cmd
,
2449 "show ip igmp interface [detail|WORD] [json]",
2453 "IGMP interface information\n"
2456 "JavaScript Object Notation\n")
2458 u_char uj
= use_json(argc
, argv
);
2461 if (argv_find(argv
, argc
, "detail", &idx
) ||
2462 argv_find(argv
, argc
, "WORD", &idx
))
2463 igmp_show_interfaces_single(vty
, argv
[idx
]->arg
, uj
);
2465 igmp_show_interfaces(vty
, uj
);
2470 DEFUN (show_ip_igmp_join
,
2471 show_ip_igmp_join_cmd
,
2472 "show ip igmp join",
2476 "IGMP static join information\n")
2478 igmp_show_interface_join(vty
);
2483 DEFUN (show_ip_igmp_groups
,
2484 show_ip_igmp_groups_cmd
,
2485 "show ip igmp groups [json]",
2490 "JavaScript Object Notation\n")
2492 u_char uj
= use_json(argc
, argv
);
2493 igmp_show_groups(vty
, uj
);
2498 DEFUN (show_ip_igmp_groups_retransmissions
,
2499 show_ip_igmp_groups_retransmissions_cmd
,
2500 "show ip igmp groups retransmissions",
2505 "IGMP group retransmissions\n")
2507 igmp_show_group_retransmission(vty
);
2512 DEFUN (show_ip_igmp_sources
,
2513 show_ip_igmp_sources_cmd
,
2514 "show ip igmp sources",
2520 igmp_show_sources(vty
);
2525 DEFUN (show_ip_igmp_sources_retransmissions
,
2526 show_ip_igmp_sources_retransmissions_cmd
,
2527 "show ip igmp sources retransmissions",
2532 "IGMP source retransmissions\n")
2534 igmp_show_source_retransmission(vty
);
2539 DEFUN (show_ip_pim_assert
,
2540 show_ip_pim_assert_cmd
,
2541 "show ip pim assert",
2545 "PIM interface assert\n")
2547 pim_show_assert(vty
);
2552 DEFUN (show_ip_pim_assert_internal
,
2553 show_ip_pim_assert_internal_cmd
,
2554 "show ip pim assert-internal",
2558 "PIM interface internal assert state\n")
2560 pim_show_assert_internal(vty
);
2565 DEFUN (show_ip_pim_assert_metric
,
2566 show_ip_pim_assert_metric_cmd
,
2567 "show ip pim assert-metric",
2571 "PIM interface assert metric\n")
2573 pim_show_assert_metric(vty
);
2578 DEFUN (show_ip_pim_assert_winner_metric
,
2579 show_ip_pim_assert_winner_metric_cmd
,
2580 "show ip pim assert-winner-metric",
2584 "PIM interface assert winner metric\n")
2586 pim_show_assert_winner_metric(vty
);
2591 DEFUN (show_ip_pim_interface
,
2592 show_ip_pim_interface_cmd
,
2593 "show ip pim interface [detail|WORD] [json]",
2597 "PIM interface information\n"
2600 "JavaScript Object Notation\n")
2602 u_char uj
= use_json(argc
, argv
);
2605 if (argv_find(argv
, argc
, "WORD", &idx
) ||
2606 argv_find(argv
, argc
, "detail", &idx
))
2607 pim_show_interfaces_single(vty
, argv
[idx
]->arg
, uj
);
2610 pim_show_interfaces(vty
, uj
);
2615 DEFUN (show_ip_pim_join
,
2616 show_ip_pim_join_cmd
,
2617 "show ip pim join [json]",
2621 "PIM interface join information\n"
2624 u_char uj
= use_json(argc
, argv
);
2625 pim_show_join(vty
, uj
);
2630 DEFUN (show_ip_pim_local_membership
,
2631 show_ip_pim_local_membership_cmd
,
2632 "show ip pim local-membership [json]",
2636 "PIM interface local-membership\n"
2639 u_char uj
= use_json(argc
, argv
);
2640 pim_show_membership(vty
, uj
);
2645 DEFUN (show_ip_pim_neighbor
,
2646 show_ip_pim_neighbor_cmd
,
2647 "show ip pim neighbor [detail|WORD] [json]",
2651 "PIM neighbor information\n"
2653 "Name of interface or neighbor\n"
2654 "JavaScript Object Notation\n")
2656 u_char uj
= use_json(argc
, argv
);
2659 if (argv_find(argv
, argc
, "detail", &idx
) ||
2660 argv_find(argv
, argc
, "WORD", &idx
))
2661 pim_show_neighbors_single(vty
, argv
[idx
]->arg
, uj
);
2663 pim_show_neighbors(vty
, uj
);
2668 DEFUN (show_ip_pim_secondary
,
2669 show_ip_pim_secondary_cmd
,
2670 "show ip pim secondary",
2674 "PIM neighbor addresses\n")
2676 pim_show_neighbors_secondary(vty
);
2681 DEFUN (show_ip_pim_state
,
2682 show_ip_pim_state_cmd
,
2683 "show ip pim state [A.B.C.D [A.B.C.D]] [json]",
2687 "PIM state information\n"
2688 "Unicast or Multicast address\n"
2689 "Multicast address\n"
2690 "JavaScript Object Notation\n")
2692 const char *src_or_group
= NULL
;
2693 const char *group
= NULL
;
2694 u_char uj
= use_json(argc
, argv
);
2700 src_or_group
= argv
[4]->arg
;
2701 group
= argv
[5]->arg
;
2704 src_or_group
= argv
[4]->arg
;
2706 pim_show_state(vty
, src_or_group
, group
, uj
);
2711 DEFUN (show_ip_pim_upstream
,
2712 show_ip_pim_upstream_cmd
,
2713 "show ip pim upstream [json]",
2717 "PIM upstream information\n"
2718 "JavaScript Object Notation\n")
2720 u_char uj
= use_json(argc
, argv
);
2721 pim_show_upstream(vty
, uj
);
2726 DEFUN (show_ip_pim_upstream_join_desired
,
2727 show_ip_pim_upstream_join_desired_cmd
,
2728 "show ip pim upstream-join-desired [json]",
2732 "PIM upstream join-desired\n"
2733 "JavaScript Object Notation\n")
2735 u_char uj
= use_json(argc
, argv
);
2736 pim_show_join_desired(vty
, uj
);
2741 DEFUN (show_ip_pim_upstream_rpf
,
2742 show_ip_pim_upstream_rpf_cmd
,
2743 "show ip pim upstream-rpf [json]",
2747 "PIM upstream source rpf\n"
2748 "JavaScript Object Notation\n")
2750 u_char uj
= use_json(argc
, argv
);
2751 pim_show_upstream_rpf(vty
, uj
);
2756 DEFUN (show_ip_pim_rp
,
2758 "show ip pim rp-info [json]",
2762 "PIM RP information\n"
2763 "JavaScript Object Notation\n")
2765 u_char uj
= use_json(argc
, argv
);
2766 pim_rp_show_information (vty
, uj
);
2771 DEFUN (show_ip_pim_rpf
,
2772 show_ip_pim_rpf_cmd
,
2773 "show ip pim rpf [json]",
2777 "PIM cached source rpf information\n"
2778 "JavaScript Object Notation\n")
2780 u_char uj
= use_json(argc
, argv
);
2781 pim_show_rpf(vty
, uj
);
2786 static void show_multicast_interfaces(struct vty
*vty
)
2788 struct listnode
*node
;
2789 struct interface
*ifp
;
2791 vty_out(vty
, "%s", VTY_NEWLINE
);
2793 vty_out(vty
, "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut%s",
2796 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
)) {
2797 struct pim_interface
*pim_ifp
;
2798 struct in_addr ifaddr
;
2799 struct sioc_vif_req vreq
;
2801 pim_ifp
= ifp
->info
;
2806 memset(&vreq
, 0, sizeof(vreq
));
2807 vreq
.vifi
= pim_ifp
->mroute_vif_index
;
2809 if (ioctl(qpim_mroute_socket_fd
, SIOCGETVIFCNT
, &vreq
)) {
2810 zlog_warn("ioctl(SIOCGETVIFCNT=%lu) failure for interface %s vif_index=%d: errno=%d: %s%s",
2811 (unsigned long)SIOCGETVIFCNT
,
2813 pim_ifp
->mroute_vif_index
,
2815 safe_strerror(errno
),
2819 ifaddr
= pim_ifp
->primary_address
;
2821 vty_out(vty
, "%-9s %-15s %3d %3d %7lu %7lu %10lu %10lu%s",
2825 pim_ifp
->mroute_vif_index
,
2826 (unsigned long) vreq
.icount
,
2827 (unsigned long) vreq
.ocount
,
2828 (unsigned long) vreq
.ibytes
,
2829 (unsigned long) vreq
.obytes
,
2834 DEFUN (show_ip_multicast
,
2835 show_ip_multicast_cmd
,
2836 "show ip multicast",
2839 "Multicast global information\n")
2841 time_t now
= pim_time_monotonic_sec();
2845 vty_out(vty
, "Mroute socket descriptor: %d%s",
2846 qpim_mroute_socket_fd
,
2849 pim_time_uptime(uptime
, sizeof(uptime
), now
- qpim_mroute_socket_creation
);
2850 vty_out(vty
, "Mroute socket uptime: %s%s",
2854 vty_out(vty
, "%s", VTY_NEWLINE
);
2856 pim_zebra_zclient_update (vty
);
2857 pim_zlookup_show_ip_multicast (vty
);
2859 vty_out(vty
, "%s", VTY_NEWLINE
);
2860 vty_out(vty
, "Maximum highest VifIndex: %d%s",
2861 PIM_MAX_USABLE_VIFS
,
2864 vty_out(vty
, "%s", VTY_NEWLINE
);
2865 vty_out(vty
, "Upstream Join Timer: %d secs%s",
2868 vty_out(vty
, "Join/Prune Holdtime: %d secs%s",
2872 vty_out(vty
, "%s", VTY_NEWLINE
);
2874 show_rpf_refresh_stats(vty
, now
, NULL
);
2876 vty_out(vty
, "%s", VTY_NEWLINE
);
2878 show_scan_oil_stats(vty
, now
);
2880 show_multicast_interfaces(vty
);
2885 static void show_mroute(struct vty
*vty
, u_char uj
)
2887 struct listnode
*node
;
2888 struct channel_oil
*c_oil
;
2889 struct static_route
*s_route
;
2891 json_object
*json
= NULL
;
2892 json_object
*json_group
= NULL
;
2893 json_object
*json_source
= NULL
;
2894 json_object
*json_oil
= NULL
;
2895 json_object
*json_ifp_out
= NULL
;
2898 char grp_str
[INET_ADDRSTRLEN
];
2899 char src_str
[INET_ADDRSTRLEN
];
2900 char in_ifname
[INTERFACE_NAMSIZ
+1];
2901 char out_ifname
[INTERFACE_NAMSIZ
+1];
2903 struct interface
*ifp_in
;
2907 json
= json_object_new_object();
2909 vty_out(vty
, "Source Group Proto Input Output TTL Uptime%s",
2913 now
= pim_time_monotonic_sec();
2915 /* print list of PIM and IGMP routes */
2916 for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list
, node
, c_oil
)) {
2919 if (!c_oil
->installed
&& !uj
)
2922 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
, sizeof(grp_str
));
2923 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
, sizeof(src_str
));
2924 ifp_in
= pim_if_find_by_vif_index(c_oil
->oil
.mfcc_parent
);
2927 strcpy(in_ifname
, ifp_in
->name
);
2929 strcpy(in_ifname
, "<iif?>");
2933 /* Find the group, create it if it doesn't exist */
2934 json_object_object_get_ex(json
, grp_str
, &json_group
);
2937 json_group
= json_object_new_object();
2938 json_object_object_add(json
, grp_str
, json_group
);
2941 /* Find the source nested under the group, create it if it doesn't exist */
2942 json_object_object_get_ex(json_group
, src_str
, &json_source
);
2945 json_source
= json_object_new_object();
2946 json_object_object_add(json_group
, src_str
, json_source
);
2949 /* Find the inbound interface nested under the source, create it if it doesn't exist */
2950 json_object_int_add(json_source
, "installed", c_oil
->installed
);
2951 json_object_int_add(json_source
, "refCount", c_oil
->oil_ref_count
);
2952 json_object_int_add(json_source
, "oilSize", c_oil
->oil_size
);
2953 json_object_int_add(json_source
, "OilInheritedRescan", c_oil
->oil_inherited_rescan
);
2954 json_object_string_add(json_source
, "iif", in_ifname
);
2958 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
; ++oif_vif_index
) {
2959 struct interface
*ifp_out
;
2960 char oif_uptime
[10];
2963 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
2967 ifp_out
= pim_if_find_by_vif_index(oif_vif_index
);
2968 pim_time_uptime(oif_uptime
, sizeof(oif_uptime
), now
- c_oil
->oif_creation
[oif_vif_index
]);
2972 strcpy(out_ifname
, ifp_out
->name
);
2974 strcpy(out_ifname
, "<oif?>");
2977 json_ifp_out
= json_object_new_object();
2978 json_object_string_add(json_ifp_out
, "source", src_str
);
2979 json_object_string_add(json_ifp_out
, "group", grp_str
);
2981 if (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_PIM
)
2982 json_object_boolean_true_add(json_ifp_out
, "protocolPim");
2984 if (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_IGMP
)
2985 json_object_boolean_true_add(json_ifp_out
, "protocolIgmp");
2987 if (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_SOURCE
)
2988 json_object_boolean_true_add(json_ifp_out
, "protocolSource");
2990 if (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_STAR
)
2991 json_object_boolean_true_add(json_ifp_out
, "protocolInherited");
2993 json_object_string_add(json_ifp_out
, "inboundInterface", in_ifname
);
2994 json_object_int_add(json_ifp_out
, "iVifI", c_oil
->oil
.mfcc_parent
);
2995 json_object_string_add(json_ifp_out
, "outboundInterface", out_ifname
);
2996 json_object_int_add(json_ifp_out
, "oVifI", oif_vif_index
);
2997 json_object_int_add(json_ifp_out
, "ttl", ttl
);
2998 json_object_string_add(json_ifp_out
, "upTime", oif_uptime
);
3000 json_oil
= json_object_new_object();
3001 json_object_object_add(json_source
, "oil", json_oil
);
3003 json_object_object_add(json_oil
, out_ifname
, json_ifp_out
);
3005 if (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_PIM
) {
3006 strcpy(proto
, "PIM");
3009 if (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_IGMP
) {
3010 strcpy(proto
, "IGMP");
3013 if (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_SOURCE
) {
3014 strcpy(proto
, "SRC");
3017 if (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_STAR
) {
3018 strcpy(proto
, "STAR");
3021 vty_out(vty
, "%-15s %-15s %-6s %-10s %-10s %-3d %8s%s",
3035 in_ifname
[0] = '\0';
3041 if (!uj
&& !found_oif
) {
3042 vty_out(vty
, "%-15s %-15s %-6s %-10s %-10s %-3d %8s%s",
3054 /* Print list of static routes */
3055 for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list
, node
, s_route
)) {
3058 if (!s_route
->c_oil
.installed
)
3061 pim_inet4_dump("<group?>", s_route
->group
, grp_str
, sizeof(grp_str
));
3062 pim_inet4_dump("<source?>", s_route
->source
, src_str
, sizeof(src_str
));
3063 ifp_in
= pim_if_find_by_vif_index(s_route
->iif
);
3067 strcpy(in_ifname
, ifp_in
->name
);
3069 strcpy(in_ifname
, "<iif?>");
3073 /* Find the group, create it if it doesn't exist */
3074 json_object_object_get_ex(json
, grp_str
, &json_group
);
3077 json_group
= json_object_new_object();
3078 json_object_object_add(json
, grp_str
, json_group
);
3081 /* Find the source nested under the group, create it if it doesn't exist */
3082 json_object_object_get_ex(json_group
, src_str
, &json_source
);
3085 json_source
= json_object_new_object();
3086 json_object_object_add(json_group
, src_str
, json_source
);
3089 json_object_string_add(json_source
, "iif", in_ifname
);
3092 strcpy(proto
, "STATIC");
3095 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
; ++oif_vif_index
) {
3096 struct interface
*ifp_out
;
3097 char oif_uptime
[10];
3100 ttl
= s_route
->oif_ttls
[oif_vif_index
];
3104 ifp_out
= pim_if_find_by_vif_index(oif_vif_index
);
3105 pim_time_uptime(oif_uptime
, sizeof(oif_uptime
), now
- s_route
->c_oil
.oif_creation
[oif_vif_index
]);
3109 strcpy(out_ifname
, ifp_out
->name
);
3111 strcpy(out_ifname
, "<oif?>");
3114 json_ifp_out
= json_object_new_object();
3115 json_object_string_add(json_ifp_out
, "source", src_str
);
3116 json_object_string_add(json_ifp_out
, "group", grp_str
);
3117 json_object_boolean_true_add(json_ifp_out
, "protocolStatic");
3118 json_object_string_add(json_ifp_out
, "inboundInterface", in_ifname
);
3119 json_object_int_add(json_ifp_out
, "iVifI", c_oil
->oil
.mfcc_parent
);
3120 json_object_string_add(json_ifp_out
, "outboundInterface", out_ifname
);
3121 json_object_int_add(json_ifp_out
, "oVifI", oif_vif_index
);
3122 json_object_int_add(json_ifp_out
, "ttl", ttl
);
3123 json_object_string_add(json_ifp_out
, "upTime", oif_uptime
);
3125 json_oil
= json_object_new_object();
3126 json_object_object_add(json_source
, "oil", json_oil
);
3128 json_object_object_add(json_oil
, out_ifname
, json_ifp_out
);
3130 vty_out(vty
, "%-15s %-15s %-6s %-10s %-10s %-3d %8s%s",
3143 in_ifname
[0] = '\0';
3149 if (!uj
&& !found_oif
) {
3150 vty_out(vty
, "%-15s %-15s %-6s %-10s %-10s %-3d %8s%s",
3163 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
3164 json_object_free(json
);
3168 DEFUN (show_ip_mroute
,
3170 "show ip mroute [json]",
3176 u_char uj
= use_json(argc
, argv
);
3177 show_mroute(vty
, uj
);
3181 static void show_mroute_count(struct vty
*vty
)
3183 struct listnode
*node
;
3184 struct channel_oil
*c_oil
;
3185 struct static_route
*s_route
;
3187 vty_out(vty
, "%s", VTY_NEWLINE
);
3189 vty_out(vty
, "Source Group LastUsed Packets Bytes WrongIf %s",
3192 /* Print PIM and IGMP route counts */
3193 for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list
, node
, c_oil
)) {
3194 char group_str
[INET_ADDRSTRLEN
];
3195 char source_str
[INET_ADDRSTRLEN
];
3197 if (!c_oil
->installed
)
3200 pim_mroute_update_counters (c_oil
);
3202 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, group_str
, sizeof(group_str
));
3203 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, source_str
, sizeof(source_str
));
3205 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld%s",
3208 c_oil
->cc
.lastused
/100,
3215 /* Print static route counts */
3216 for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list
, node
, s_route
)) {
3217 char group_str
[INET_ADDRSTRLEN
];
3218 char source_str
[INET_ADDRSTRLEN
];
3220 if (!s_route
->c_oil
.installed
)
3223 pim_mroute_update_counters (&s_route
->c_oil
);
3225 pim_inet4_dump("<group?>", s_route
->c_oil
.oil
.mfcc_mcastgrp
, group_str
, sizeof(group_str
));
3226 pim_inet4_dump("<source?>", s_route
->c_oil
.oil
.mfcc_origin
, source_str
, sizeof(source_str
));
3228 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld%s",
3231 s_route
->c_oil
.cc
.lastused
,
3232 s_route
->c_oil
.cc
.pktcnt
,
3233 s_route
->c_oil
.cc
.bytecnt
,
3234 s_route
->c_oil
.cc
.wrong_if
,
3239 DEFUN (show_ip_mroute_count
,
3240 show_ip_mroute_count_cmd
,
3241 "show ip mroute count",
3245 "Route and packet count data\n")
3247 show_mroute_count(vty
);
3253 "show ip rib A.B.C.D",
3257 "Unicast address\n")
3260 struct in_addr addr
;
3261 const char *addr_str
;
3262 struct pim_nexthop nexthop
;
3263 char nexthop_addr_str
[PREFIX_STRLEN
];
3266 memset (&nexthop
, 0, sizeof (nexthop
));
3267 addr_str
= argv
[idx_ipv4
]->arg
;
3268 result
= inet_pton(AF_INET
, addr_str
, &addr
);
3270 vty_out(vty
, "Bad unicast address %s: errno=%d: %s%s",
3271 addr_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
3275 if (pim_nexthop_lookup(&nexthop
, addr
, 0)) {
3276 vty_out(vty
, "Failure querying RIB nexthop for unicast address %s%s",
3277 addr_str
, VTY_NEWLINE
);
3281 vty_out(vty
, "Address NextHop Interface Metric Preference%s",
3284 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
3285 nexthop_addr_str
, sizeof(nexthop_addr_str
));
3287 vty_out(vty
, "%-15s %-15s %-9s %6d %10d%s",
3290 nexthop
.interface
? nexthop
.interface
->name
: "<ifname?>",
3291 nexthop
.mrib_route_metric
,
3292 nexthop
.mrib_metric_preference
,
3298 static void show_ssmpingd(struct vty
*vty
)
3300 struct listnode
*node
;
3301 struct ssmpingd_sock
*ss
;
3304 vty_out(vty
, "Source Socket Address Port Uptime Requests%s",
3307 if (!qpim_ssmpingd_list
)
3310 now
= pim_time_monotonic_sec();
3312 for (ALL_LIST_ELEMENTS_RO(qpim_ssmpingd_list
, node
, ss
)) {
3313 char source_str
[INET_ADDRSTRLEN
];
3315 struct sockaddr_in bind_addr
;
3316 socklen_t len
= sizeof(bind_addr
);
3317 char bind_addr_str
[INET_ADDRSTRLEN
];
3319 pim_inet4_dump("<src?>", ss
->source_addr
, source_str
, sizeof(source_str
));
3321 if (pim_socket_getsockname(ss
->sock_fd
, (struct sockaddr
*) &bind_addr
, &len
)) {
3322 vty_out(vty
, "%% Failure reading socket name for ssmpingd source %s on fd=%d%s",
3323 source_str
, ss
->sock_fd
, VTY_NEWLINE
);
3326 pim_inet4_dump("<addr?>", bind_addr
.sin_addr
, bind_addr_str
, sizeof(bind_addr_str
));
3327 pim_time_uptime(ss_uptime
, sizeof(ss_uptime
), now
- ss
->creation
);
3329 vty_out(vty
, "%-15s %6d %-15s %5d %8s %8lld%s",
3333 ntohs(bind_addr
.sin_port
),
3335 (long long)ss
->requests
,
3340 DEFUN (show_ip_ssmpingd
,
3341 show_ip_ssmpingd_cmd
,
3352 pim_rp_cmd_worker (struct vty
*vty
, const char *rp
, const char *group
, const char *plist
)
3356 result
= pim_rp_new (rp
, group
, plist
);
3358 if (result
== PIM_MALLOC_FAIL
)
3360 vty_out (vty
, "%% Out of memory%s", VTY_NEWLINE
);
3364 if (result
== PIM_GROUP_BAD_ADDRESS
)
3366 vty_out (vty
, "%% Bad group address specified: %s%s", group
, VTY_NEWLINE
);
3370 if (result
== PIM_RP_BAD_ADDRESS
)
3372 vty_out (vty
, "%% Bad RP address specified: %s%s", rp
, VTY_NEWLINE
);
3376 if (result
== PIM_RP_NO_PATH
)
3378 vty_out (vty
, "%% No Path to RP address specified: %s%s", rp
, VTY_NEWLINE
);
3382 if (result
== PIM_GROUP_OVERLAP
)
3384 vty_out (vty
, "%% Group range specified cannot overlap%s", VTY_NEWLINE
);
3388 if (result
== PIM_GROUP_PFXLIST_OVERLAP
)
3390 vty_out (vty
, "%% This group is already covered by a RP prefix-list%s", VTY_NEWLINE
);
3394 if (result
== PIM_RP_PFXLIST_IN_USE
)
3396 vty_out (vty
, "%% The same prefix-list cannot be applied to multiple RPs%s", VTY_NEWLINE
);
3403 DEFUN (ip_pim_joinprune_time
,
3404 ip_pim_joinprune_time_cmd
,
3405 "ip pim join-prune-interval <60-600>",
3407 "pim multicast routing\n"
3408 "Join Prune Send Interval\n"
3411 qpim_t_periodic
= atoi(argv
[3]->arg
);
3415 DEFUN (no_ip_pim_joinprune_time
,
3416 no_ip_pim_joinprune_time_cmd
,
3417 "no ip pim join-prune-interval <60-600>",
3420 "pim multicast routing\n"
3421 "Join Prune Send Interval\n"
3424 qpim_t_periodic
= PIM_DEFAULT_T_PERIODIC
;
3428 DEFUN (ip_pim_register_suppress
,
3429 ip_pim_register_suppress_cmd
,
3430 "ip pim register-suppress-time <5-60000>",
3432 "pim multicast routing\n"
3433 "Register Suppress Timer\n"
3436 qpim_keep_alive_time
= atoi (argv
[3]->arg
);
3440 DEFUN (no_ip_pim_register_suppress
,
3441 no_ip_pim_register_suppress_cmd
,
3442 "no ip pim register-suppress-time <5-60000>",
3445 "pim multicast routing\n"
3446 "Register Suppress Timer\n"
3449 qpim_register_suppress_time
= PIM_REGISTER_SUPPRESSION_TIME_DEFAULT
;
3453 DEFUN (ip_pim_keep_alive
,
3454 ip_pim_keep_alive_cmd
,
3455 "ip pim keep-alive-timer <31-60000>",
3457 "pim multicast routing\n"
3458 "Keep alive Timer\n"
3461 qpim_rp_keep_alive_time
= atoi (argv
[4]->arg
);
3465 DEFUN (no_ip_pim_keep_alive
,
3466 no_ip_pim_keep_alive_cmd
,
3467 "no ip pim keep-alive-timer <31-60000>",
3470 "pim multicast routing\n"
3471 "Keep alive Timer\n"
3474 qpim_keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
3478 DEFUN (ip_pim_packets
,
3480 "ip pim packets <1-100>",
3482 "pim multicast routing\n"
3483 "packets to process at one time per fd\n"
3484 "Number of packets\n")
3486 qpim_packet_process
= atoi (argv
[3]->arg
);
3490 DEFUN (no_ip_pim_packets
,
3491 no_ip_pim_packets_cmd
,
3492 "no ip pim packets <1-100>",
3495 "pim multicast routing\n"
3496 "packets to process at one time per fd\n"
3497 "Number of packets\n")
3499 qpim_packet_process
= PIM_DEFAULT_PACKET_PROCESS
;
3505 "ip pim rp A.B.C.D [A.B.C.D/M]",
3507 "pim multicast routing\n"
3509 "ip address of RP\n"
3510 "Group Address range to cover\n")
3514 if (argc
== (idx_ipv4
+ 1))
3515 return pim_rp_cmd_worker (vty
, argv
[idx_ipv4
]->arg
, argv
[idx_ipv4
+ 1]->arg
, NULL
);
3517 return pim_rp_cmd_worker (vty
, argv
[idx_ipv4
]->arg
, NULL
, NULL
);
3520 DEFUN (ip_pim_rp_prefix_list
,
3521 ip_pim_rp_prefix_list_cmd
,
3522 "ip pim rp A.B.C.D prefix-list WORD",
3524 "pim multicast routing\n"
3526 "ip address of RP\n"
3527 "group prefix-list filter\n"
3528 "Name of a prefix-list\n")
3530 return pim_rp_cmd_worker (vty
, argv
[3]->arg
, NULL
, argv
[5]->arg
);
3534 pim_no_rp_cmd_worker (struct vty
*vty
, const char *rp
, const char *group
,
3537 int result
= pim_rp_del (rp
, group
, plist
);
3539 if (result
== PIM_GROUP_BAD_ADDRESS
)
3541 vty_out (vty
, "%% Bad group address specified: %s%s", group
, VTY_NEWLINE
);
3545 if (result
== PIM_RP_BAD_ADDRESS
)
3547 vty_out (vty
, "%% Bad RP address specified: %s%s", rp
, VTY_NEWLINE
);
3551 if (result
== PIM_RP_NOT_FOUND
)
3553 vty_out (vty
, "%% Unable to find specified RP%s", VTY_NEWLINE
);
3560 DEFUN (no_ip_pim_rp
,
3562 "no ip pim rp A.B.C.D [A.B.C.D/M]",
3565 "pim multicast routing\n"
3567 "ip address of RP\n"
3568 "Group Address range to cover\n")
3572 if (argc
== (idx_ipv4
+ 1))
3573 return pim_no_rp_cmd_worker (vty
, argv
[idx_ipv4
]->arg
, argv
[idx_ipv4
+ 1]->arg
, NULL
);
3575 return pim_no_rp_cmd_worker (vty
, argv
[idx_ipv4
]->arg
, NULL
, NULL
);
3578 DEFUN (no_ip_pim_rp_prefix_list
,
3579 no_ip_pim_rp_prefix_list_cmd
,
3580 "no ip pim rp A.B.C.D prefix-list WORD",
3583 "pim multicast routing\n"
3585 "ip address of RP\n"
3586 "group prefix-list filter\n"
3587 "Name of a prefix-list\n")
3589 return pim_no_rp_cmd_worker (vty
, argv
[4]->arg
, NULL
, argv
[6]->arg
);
3592 DEFUN_HIDDEN (ip_multicast_routing
,
3593 ip_multicast_routing_cmd
,
3594 "ip multicast-routing",
3596 "Enable IP multicast forwarding\n")
3601 DEFUN_HIDDEN (no_ip_multicast_routing
,
3602 no_ip_multicast_routing_cmd
,
3603 "no ip multicast-routing",
3606 "Global IP configuration subcommands\n"
3607 "Enable IP multicast forwarding\n")
3609 vty_out (vty
, "Command is Disabled and will be removed in a future version%s", VTY_NEWLINE
);
3615 "ip ssmpingd [A.B.C.D]",
3622 struct in_addr source_addr
;
3623 const char *source_str
= (argc
== idx_ipv4
) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
3625 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
3627 vty_out(vty
, "%% Bad source address %s: errno=%d: %s%s",
3628 source_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
3632 result
= pim_ssmpingd_start(source_addr
);
3634 vty_out(vty
, "%% Failure starting ssmpingd for source %s: %d%s",
3635 source_str
, result
, VTY_NEWLINE
);
3642 DEFUN (no_ip_ssmpingd
,
3644 "no ip ssmpingd [A.B.C.D]",
3652 struct in_addr source_addr
;
3653 const char *source_str
= (argc
== idx_ipv4
) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
3655 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
3657 vty_out(vty
, "%% Bad source address %s: errno=%d: %s%s",
3658 source_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
3662 result
= pim_ssmpingd_stop(source_addr
);
3664 vty_out(vty
, "%% Failure stopping ssmpingd for source %s: %d%s",
3665 source_str
, result
, VTY_NEWLINE
);
3673 pim_cmd_igmp_start (struct vty
*vty
, struct interface
*ifp
)
3675 struct pim_interface
*pim_ifp
;
3677 pim_ifp
= ifp
->info
;
3680 pim_ifp
= pim_if_new(ifp
, 1 /* igmp=true */, 0 /* pim=false */);
3682 vty_out(vty
, "Could not enable IGMP on interface %s%s",
3683 ifp
->name
, VTY_NEWLINE
);
3688 PIM_IF_DO_IGMP(pim_ifp
->options
);
3691 pim_if_addr_add_all(ifp
);
3692 pim_if_membership_refresh(ifp
);
3697 DEFUN (interface_ip_igmp
,
3698 interface_ip_igmp_cmd
,
3703 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3705 return pim_cmd_igmp_start(vty
, ifp
);
3708 DEFUN (interface_no_ip_igmp
,
3709 interface_no_ip_igmp_cmd
,
3715 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3716 struct pim_interface
*pim_ifp
;
3718 pim_ifp
= ifp
->info
;
3722 PIM_IF_DONT_IGMP(pim_ifp
->options
);
3724 pim_if_membership_clear(ifp
);
3726 pim_if_addr_del_all_igmp(ifp
);
3728 if (!PIM_IF_TEST_PIM(pim_ifp
->options
)) {
3735 DEFUN (interface_ip_igmp_join
,
3736 interface_ip_igmp_join_cmd
,
3737 "ip igmp join A.B.C.D A.B.C.D",
3740 "IGMP join multicast group\n"
3741 "Multicast group address\n"
3744 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3747 const char *group_str
;
3748 const char *source_str
;
3749 struct in_addr group_addr
;
3750 struct in_addr source_addr
;
3754 group_str
= argv
[idx_ipv4
]->arg
;
3755 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
3757 vty_out(vty
, "Bad group address %s: errno=%d: %s%s",
3758 group_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
3762 /* Source address */
3763 source_str
= argv
[idx_ipv4_2
]->arg
;
3764 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
3766 vty_out(vty
, "Bad source address %s: errno=%d: %s%s",
3767 source_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
3771 result
= pim_if_igmp_join_add(ifp
, group_addr
, source_addr
);
3773 vty_out(vty
, "%% Failure joining IGMP group %s source %s on interface %s: %d%s",
3774 group_str
, source_str
, ifp
->name
, result
, VTY_NEWLINE
);
3781 DEFUN (interface_no_ip_igmp_join
,
3782 interface_no_ip_igmp_join_cmd
,
3783 "no ip igmp join A.B.C.D A.B.C.D",
3787 "IGMP join multicast group\n"
3788 "Multicast group address\n"
3791 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3794 const char *group_str
;
3795 const char *source_str
;
3796 struct in_addr group_addr
;
3797 struct in_addr source_addr
;
3801 group_str
= argv
[idx_ipv4
]->arg
;
3802 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
3804 vty_out(vty
, "Bad group address %s: errno=%d: %s%s",
3805 group_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
3809 /* Source address */
3810 source_str
= argv
[idx_ipv4_2
]->arg
;
3811 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
3813 vty_out(vty
, "Bad source address %s: errno=%d: %s%s",
3814 source_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
3818 result
= pim_if_igmp_join_del(ifp
, group_addr
, source_addr
);
3820 vty_out(vty
, "%% Failure leaving IGMP group %s source %s on interface %s: %d%s",
3821 group_str
, source_str
, ifp
->name
, result
, VTY_NEWLINE
);
3829 CLI reconfiguration affects the interface level (struct pim_interface).
3830 This function propagates the reconfiguration to every active socket
3833 static void igmp_sock_query_interval_reconfig(struct igmp_sock
*igmp
)
3835 struct interface
*ifp
;
3836 struct pim_interface
*pim_ifp
;
3840 /* other querier present? */
3842 if (igmp
->t_other_querier_timer
)
3845 /* this is the querier */
3847 zassert(igmp
->interface
);
3848 zassert(igmp
->interface
->info
);
3850 ifp
= igmp
->interface
;
3851 pim_ifp
= ifp
->info
;
3853 if (PIM_DEBUG_IGMP_TRACE
) {
3854 char ifaddr_str
[INET_ADDRSTRLEN
];
3855 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
, sizeof(ifaddr_str
));
3856 zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
3857 __PRETTY_FUNCTION__
,
3860 pim_ifp
->igmp_default_query_interval
);
3864 igmp_startup_mode_on() will reset QQI:
3866 igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
3868 igmp_startup_mode_on(igmp
);
3871 static void igmp_sock_query_reschedule(struct igmp_sock
*igmp
)
3873 if (igmp
->t_igmp_query_timer
) {
3874 /* other querier present */
3875 zassert(igmp
->t_igmp_query_timer
);
3876 zassert(!igmp
->t_other_querier_timer
);
3878 pim_igmp_general_query_off(igmp
);
3879 pim_igmp_general_query_on(igmp
);
3881 zassert(igmp
->t_igmp_query_timer
);
3882 zassert(!igmp
->t_other_querier_timer
);
3885 /* this is the querier */
3887 zassert(!igmp
->t_igmp_query_timer
);
3888 zassert(igmp
->t_other_querier_timer
);
3890 pim_igmp_other_querier_timer_off(igmp
);
3891 pim_igmp_other_querier_timer_on(igmp
);
3893 zassert(!igmp
->t_igmp_query_timer
);
3894 zassert(igmp
->t_other_querier_timer
);
3898 static void change_query_interval(struct pim_interface
*pim_ifp
,
3901 struct listnode
*sock_node
;
3902 struct igmp_sock
*igmp
;
3904 pim_ifp
->igmp_default_query_interval
= query_interval
;
3906 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
3907 igmp_sock_query_interval_reconfig(igmp
);
3908 igmp_sock_query_reschedule(igmp
);
3912 static void change_query_max_response_time(struct pim_interface
*pim_ifp
,
3913 int query_max_response_time_dsec
)
3915 struct listnode
*sock_node
;
3916 struct igmp_sock
*igmp
;
3918 pim_ifp
->igmp_query_max_response_time_dsec
= query_max_response_time_dsec
;
3921 Below we modify socket/group/source timers in order to quickly
3922 reflect the change. Otherwise, those timers would eventually catch
3926 /* scan all sockets */
3927 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
3928 struct listnode
*grp_node
;
3929 struct igmp_group
*grp
;
3931 /* reschedule socket general query */
3932 igmp_sock_query_reschedule(igmp
);
3934 /* scan socket groups */
3935 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grp_node
, grp
)) {
3936 struct listnode
*src_node
;
3937 struct igmp_source
*src
;
3939 /* reset group timers for groups in EXCLUDE mode */
3940 if (grp
->group_filtermode_isexcl
) {
3941 igmp_group_reset_gmi(grp
);
3944 /* scan group sources */
3945 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
, src_node
, src
)) {
3947 /* reset source timers for sources with running timers */
3948 if (src
->t_source_timer
) {
3949 igmp_source_reset_gmi(igmp
, grp
, src
);
3956 #define IGMP_QUERY_INTERVAL_MIN (1)
3957 #define IGMP_QUERY_INTERVAL_MAX (1800)
3959 DEFUN (interface_ip_igmp_query_interval
,
3960 interface_ip_igmp_query_interval_cmd
,
3961 "ip igmp query-interval (1-1800)",
3964 IFACE_IGMP_QUERY_INTERVAL_STR
3965 "Query interval in seconds\n")
3967 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3968 struct pim_interface
*pim_ifp
;
3970 int query_interval_dsec
;
3973 pim_ifp
= ifp
->info
;
3976 ret
= pim_cmd_igmp_start(vty
, ifp
);
3977 if (ret
!= CMD_SUCCESS
)
3979 pim_ifp
= ifp
->info
;
3982 query_interval
= atoi(argv
[3]->arg
);
3983 query_interval_dsec
= 10 * query_interval
;
3986 It seems we don't need to check bounds since command.c does it
3987 already, but we verify them anyway for extra safety.
3989 if (query_interval
< IGMP_QUERY_INTERVAL_MIN
) {
3990 vty_out(vty
, "General query interval %d lower than minimum %d%s",
3992 IGMP_QUERY_INTERVAL_MIN
,
3996 if (query_interval
> IGMP_QUERY_INTERVAL_MAX
) {
3997 vty_out(vty
, "General query interval %d higher than maximum %d%s",
3999 IGMP_QUERY_INTERVAL_MAX
,
4004 if (query_interval_dsec
<= pim_ifp
->igmp_query_max_response_time_dsec
) {
4006 "Can't set general query interval %d dsec <= query max response time %d dsec.%s",
4007 query_interval_dsec
, pim_ifp
->igmp_query_max_response_time_dsec
,
4012 change_query_interval(pim_ifp
, query_interval
);
4017 DEFUN (interface_no_ip_igmp_query_interval
,
4018 interface_no_ip_igmp_query_interval_cmd
,
4019 "no ip igmp query-interval",
4023 IFACE_IGMP_QUERY_INTERVAL_STR
)
4025 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4026 struct pim_interface
*pim_ifp
;
4027 int default_query_interval_dsec
;
4029 pim_ifp
= ifp
->info
;
4034 default_query_interval_dsec
= IGMP_GENERAL_QUERY_INTERVAL
* 10;
4036 if (default_query_interval_dsec
<= pim_ifp
->igmp_query_max_response_time_dsec
) {
4038 "Can't set default general query interval %d dsec <= query max response time %d dsec.%s",
4039 default_query_interval_dsec
, pim_ifp
->igmp_query_max_response_time_dsec
,
4044 change_query_interval(pim_ifp
, IGMP_GENERAL_QUERY_INTERVAL
);
4049 DEFUN (interface_ip_igmp_version
,
4050 interface_ip_igmp_version_cmd
,
4051 "ip igmp version (2-3)",
4055 "IGMP version number\n")
4057 VTY_DECLVAR_CONTEXT(interface
,ifp
);
4058 struct pim_interface
*pim_ifp
;
4062 pim_ifp
= ifp
->info
;
4065 ret
= pim_cmd_igmp_start(vty
, ifp
);
4066 if (ret
!= CMD_SUCCESS
)
4068 pim_ifp
= ifp
->info
;
4071 igmp_version
= atoi(argv
[3]->arg
);
4072 pim_ifp
->igmp_version
= igmp_version
;
4077 DEFUN (interface_no_ip_igmp_version
,
4078 interface_no_ip_igmp_version_cmd
,
4079 "no ip igmp version (2-3)",
4084 "IGMP version number\n")
4086 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4087 struct pim_interface
*pim_ifp
;
4089 pim_ifp
= ifp
->info
;
4094 pim_ifp
->igmp_version
= IGMP_DEFAULT_VERSION
;
4099 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
4100 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
4102 DEFUN (interface_ip_igmp_query_max_response_time
,
4103 interface_ip_igmp_query_max_response_time_cmd
,
4104 "ip igmp query-max-response-time (10-250)",
4107 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
4108 "Query response value in deci-seconds\n")
4110 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4111 struct pim_interface
*pim_ifp
;
4112 int query_max_response_time
;
4115 pim_ifp
= ifp
->info
;
4118 ret
= pim_cmd_igmp_start(vty
, ifp
);
4119 if (ret
!= CMD_SUCCESS
)
4121 pim_ifp
= ifp
->info
;
4124 query_max_response_time
= atoi(argv
[3]->arg
);
4126 if (query_max_response_time
>= pim_ifp
->igmp_default_query_interval
* 10) {
4128 "Can't set query max response time %d sec >= general query interval %d sec%s",
4129 query_max_response_time
, pim_ifp
->igmp_default_query_interval
,
4134 change_query_max_response_time(pim_ifp
, query_max_response_time
);
4139 DEFUN (interface_no_ip_igmp_query_max_response_time
,
4140 interface_no_ip_igmp_query_max_response_time_cmd
,
4141 "no ip igmp query-max-response-time (10-250)",
4145 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
4146 "Time for response in deci-seconds\n")
4148 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4149 struct pim_interface
*pim_ifp
;
4151 pim_ifp
= ifp
->info
;
4156 change_query_max_response_time(pim_ifp
, IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
4161 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
4162 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
4164 DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec
,
4165 interface_ip_igmp_query_max_response_time_dsec_cmd
,
4166 "ip igmp query-max-response-time-dsec (10-250)",
4169 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
4170 "Query response value in deciseconds\n")
4172 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4173 struct pim_interface
*pim_ifp
;
4174 int query_max_response_time_dsec
;
4175 int default_query_interval_dsec
;
4178 pim_ifp
= ifp
->info
;
4181 ret
= pim_cmd_igmp_start(vty
, ifp
);
4182 if (ret
!= CMD_SUCCESS
)
4184 pim_ifp
= ifp
->info
;
4187 query_max_response_time_dsec
= atoi(argv
[4]->arg
);
4189 default_query_interval_dsec
= 10 * pim_ifp
->igmp_default_query_interval
;
4191 if (query_max_response_time_dsec
>= default_query_interval_dsec
) {
4193 "Can't set query max response time %d dsec >= general query interval %d dsec%s",
4194 query_max_response_time_dsec
, default_query_interval_dsec
,
4199 change_query_max_response_time(pim_ifp
, query_max_response_time_dsec
);
4204 DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec
,
4205 interface_no_ip_igmp_query_max_response_time_dsec_cmd
,
4206 "no ip igmp query-max-response-time-dsec",
4210 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
)
4212 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4213 struct pim_interface
*pim_ifp
;
4215 pim_ifp
= ifp
->info
;
4220 change_query_max_response_time(pim_ifp
, IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
4225 DEFUN (interface_ip_pim_drprio
,
4226 interface_ip_pim_drprio_cmd
,
4227 "ip pim drpriority (1-4294967295)",
4230 "Set the Designated Router Election Priority\n"
4231 "Value of the new DR Priority\n")
4233 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4235 struct pim_interface
*pim_ifp
;
4236 uint32_t old_dr_prio
;
4238 pim_ifp
= ifp
->info
;
4241 vty_out(vty
, "Please enable PIM on interface, first%s", VTY_NEWLINE
);
4245 old_dr_prio
= pim_ifp
->pim_dr_priority
;
4247 pim_ifp
->pim_dr_priority
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
4249 if (old_dr_prio
!= pim_ifp
->pim_dr_priority
) {
4250 if (pim_if_dr_election(ifp
))
4251 pim_hello_restart_now(ifp
);
4257 DEFUN (interface_no_ip_pim_drprio
,
4258 interface_no_ip_pim_drprio_cmd
,
4259 "no ip pim drpriority [(1-4294967295)]",
4263 "Revert the Designated Router Priority to default\n"
4264 "Old Value of the Priority\n")
4266 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4267 struct pim_interface
*pim_ifp
;
4269 pim_ifp
= ifp
->info
;
4272 vty_out(vty
, "Pim not enabled on this interface%s", VTY_NEWLINE
);
4276 if (pim_ifp
->pim_dr_priority
!= PIM_DEFAULT_DR_PRIORITY
) {
4277 pim_ifp
->pim_dr_priority
= PIM_DEFAULT_DR_PRIORITY
;
4278 if (pim_if_dr_election(ifp
))
4279 pim_hello_restart_now(ifp
);
4286 pim_cmd_interface_add (struct interface
*ifp
, enum pim_interface_type itype
)
4288 struct pim_interface
*pim_ifp
= ifp
->info
;
4291 pim_ifp
= pim_if_new(ifp
, 0 /* igmp=false */, 1 /* pim=true */);
4297 PIM_IF_DO_PIM(pim_ifp
->options
);
4300 pim_ifp
->itype
= itype
;
4301 pim_if_addr_add_all(ifp
);
4302 pim_if_membership_refresh(ifp
);
4307 DEFUN (interface_ip_pim_ssm
,
4308 interface_ip_pim_ssm_cmd
,
4314 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4316 if (!pim_cmd_interface_add(ifp
, PIM_INTERFACE_SSM
)) {
4317 vty_out(vty
, "Could not enable PIM SSM on interface%s", VTY_NEWLINE
);
4324 DEFUN (interface_ip_pim_sm
,
4325 interface_ip_pim_sm_cmd
,
4331 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4332 if (!pim_cmd_interface_add(ifp
, PIM_INTERFACE_SM
)) {
4333 vty_out(vty
, "Could not enable PIM SM on interface%s", VTY_NEWLINE
);
4337 pim_if_create_pimreg();
4343 pim_cmd_interface_delete (struct interface
*ifp
)
4345 struct pim_interface
*pim_ifp
= ifp
->info
;
4350 PIM_IF_DONT_PIM(pim_ifp
->options
);
4352 pim_if_membership_clear(ifp
);
4355 pim_sock_delete() removes all neighbors from
4356 pim_ifp->pim_neighbor_list.
4358 pim_sock_delete(ifp
, "pim unconfigured on interface");
4360 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
4361 pim_if_addr_del_all(ifp
);
4368 DEFUN (interface_no_ip_pim_ssm
,
4369 interface_no_ip_pim_ssm_cmd
,
4376 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4377 if (!pim_cmd_interface_delete(ifp
)) {
4378 vty_out(vty
, "Unable to delete interface information%s", VTY_NEWLINE
);
4385 DEFUN (interface_no_ip_pim_sm
,
4386 interface_no_ip_pim_sm_cmd
,
4393 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4394 if (!pim_cmd_interface_delete(ifp
)) {
4395 vty_out(vty
, "Unable to delete interface information%s", VTY_NEWLINE
);
4402 DEFUN (interface_ip_mroute
,
4403 interface_ip_mroute_cmd
,
4404 "ip mroute INTERFACE A.B.C.D",
4406 "Add multicast route\n"
4407 "Outgoing interface name\n"
4410 VTY_DECLVAR_CONTEXT(interface
, iif
);
4411 int idx_interface
= 2;
4413 struct interface
*oif
;
4414 const char *oifname
;
4415 const char *grp_str
;
4416 struct in_addr grp_addr
;
4417 struct in_addr src_addr
;
4420 oifname
= argv
[idx_interface
]->arg
;
4421 oif
= if_lookup_by_name(oifname
, VRF_DEFAULT
);
4423 vty_out(vty
, "No such interface name %s%s",
4424 oifname
, VTY_NEWLINE
);
4428 grp_str
= argv
[idx_ipv4
]->arg
;
4429 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
4431 vty_out(vty
, "Bad group address %s: errno=%d: %s%s",
4432 grp_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
4436 src_addr
.s_addr
= INADDR_ANY
;
4438 if (pim_static_add(iif
, oif
, grp_addr
, src_addr
)) {
4439 vty_out(vty
, "Failed to add route%s", VTY_NEWLINE
);
4446 DEFUN (interface_ip_mroute_source
,
4447 interface_ip_mroute_source_cmd
,
4448 "ip mroute INTERFACE A.B.C.D A.B.C.D",
4450 "Add multicast route\n"
4451 "Outgoing interface name\n"
4455 VTY_DECLVAR_CONTEXT(interface
, iif
);
4456 int idx_interface
= 2;
4459 struct interface
*oif
;
4460 const char *oifname
;
4461 const char *grp_str
;
4462 struct in_addr grp_addr
;
4463 const char *src_str
;
4464 struct in_addr src_addr
;
4467 oifname
= argv
[idx_interface
]->arg
;
4468 oif
= if_lookup_by_name(oifname
, VRF_DEFAULT
);
4470 vty_out(vty
, "No such interface name %s%s",
4471 oifname
, VTY_NEWLINE
);
4475 grp_str
= argv
[idx_ipv4
]->arg
;
4476 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
4478 vty_out(vty
, "Bad group address %s: errno=%d: %s%s",
4479 grp_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
4483 src_str
= argv
[idx_ipv4_2
]->arg
;
4484 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
4486 vty_out(vty
, "Bad source address %s: errno=%d: %s%s",
4487 src_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
4491 if (pim_static_add(iif
, oif
, grp_addr
, src_addr
)) {
4492 vty_out(vty
, "Failed to add route%s", VTY_NEWLINE
);
4499 DEFUN (interface_no_ip_mroute
,
4500 interface_no_ip_mroute_cmd
,
4501 "no ip mroute INTERFACE A.B.C.D",
4504 "Add multicast route\n"
4505 "Outgoing interface name\n"
4508 VTY_DECLVAR_CONTEXT(interface
, iif
);
4509 int idx_interface
= 3;
4511 struct interface
*oif
;
4512 const char *oifname
;
4513 const char *grp_str
;
4514 struct in_addr grp_addr
;
4515 struct in_addr src_addr
;
4518 oifname
= argv
[idx_interface
]->arg
;
4519 oif
= if_lookup_by_name(oifname
, VRF_DEFAULT
);
4521 vty_out(vty
, "No such interface name %s%s",
4522 oifname
, VTY_NEWLINE
);
4526 grp_str
= argv
[idx_ipv4
]->arg
;
4527 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
4529 vty_out(vty
, "Bad group address %s: errno=%d: %s%s",
4530 grp_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
4534 src_addr
.s_addr
= INADDR_ANY
;
4536 if (pim_static_del(iif
, oif
, grp_addr
, src_addr
)) {
4537 vty_out(vty
, "Failed to remove route%s", VTY_NEWLINE
);
4544 DEFUN (interface_no_ip_mroute_source
,
4545 interface_no_ip_mroute_source_cmd
,
4546 "no ip mroute INTERFACE A.B.C.D A.B.C.D",
4549 "Add multicast route\n"
4550 "Outgoing interface name\n"
4554 VTY_DECLVAR_CONTEXT(interface
, iif
);
4555 int idx_interface
= 3;
4558 struct interface
*oif
;
4559 const char *oifname
;
4560 const char *grp_str
;
4561 struct in_addr grp_addr
;
4562 const char *src_str
;
4563 struct in_addr src_addr
;
4566 oifname
= argv
[idx_interface
]->arg
;
4567 oif
= if_lookup_by_name(oifname
, VRF_DEFAULT
);
4569 vty_out(vty
, "No such interface name %s%s",
4570 oifname
, VTY_NEWLINE
);
4574 grp_str
= argv
[idx_ipv4
]->arg
;
4575 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
4577 vty_out(vty
, "Bad group address %s: errno=%d: %s%s",
4578 grp_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
4582 src_str
= argv
[idx_ipv4_2
]->arg
;
4583 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
4585 vty_out(vty
, "Bad source address %s: errno=%d: %s%s",
4586 src_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
4590 if (pim_static_del(iif
, oif
, grp_addr
, src_addr
)) {
4591 vty_out(vty
, "Failed to remove route%s", VTY_NEWLINE
);
4598 DEFUN (interface_ip_pim_hello
,
4599 interface_ip_pim_hello_cmd
,
4600 "ip pim hello (1-180) [(1-180)]",
4604 IFACE_PIM_HELLO_TIME_STR
4605 IFACE_PIM_HELLO_HOLD_STR
)
4607 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4610 struct pim_interface
*pim_ifp
;
4612 pim_ifp
= ifp
->info
;
4615 vty_out(vty
, "Pim not enabled on this interface%s", VTY_NEWLINE
);
4619 pim_ifp
->pim_hello_period
= strtol(argv
[idx_time
]->arg
, NULL
, 10);
4621 if (argc
== idx_hold
)
4622 pim_ifp
->pim_default_holdtime
= strtol(argv
[idx_hold
]->arg
, NULL
, 10);
4629 DEFUN (interface_no_ip_pim_hello
,
4630 interface_no_ip_pim_hello_cmd
,
4631 "no ip pim hello [(1-180) (1-180)]",
4636 IFACE_PIM_HELLO_TIME_STR
4637 IFACE_PIM_HELLO_HOLD_STR
)
4639 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4640 struct pim_interface
*pim_ifp
;
4642 pim_ifp
= ifp
->info
;
4645 vty_out(vty
, "Pim not enabled on this interface%s", VTY_NEWLINE
);
4649 pim_ifp
->pim_hello_period
= PIM_DEFAULT_HELLO_PERIOD
;
4650 pim_ifp
->pim_default_holdtime
= -1;
4661 PIM_DO_DEBUG_IGMP_EVENTS
;
4662 PIM_DO_DEBUG_IGMP_PACKETS
;
4663 PIM_DO_DEBUG_IGMP_TRACE
;
4667 DEFUN (no_debug_igmp
,
4674 PIM_DONT_DEBUG_IGMP_EVENTS
;
4675 PIM_DONT_DEBUG_IGMP_PACKETS
;
4676 PIM_DONT_DEBUG_IGMP_TRACE
;
4681 DEFUN (debug_igmp_events
,
4682 debug_igmp_events_cmd
,
4683 "debug igmp events",
4686 DEBUG_IGMP_EVENTS_STR
)
4688 PIM_DO_DEBUG_IGMP_EVENTS
;
4692 DEFUN (no_debug_igmp_events
,
4693 no_debug_igmp_events_cmd
,
4694 "no debug igmp events",
4698 DEBUG_IGMP_EVENTS_STR
)
4700 PIM_DONT_DEBUG_IGMP_EVENTS
;
4705 DEFUN (debug_igmp_packets
,
4706 debug_igmp_packets_cmd
,
4707 "debug igmp packets",
4710 DEBUG_IGMP_PACKETS_STR
)
4712 PIM_DO_DEBUG_IGMP_PACKETS
;
4716 DEFUN (no_debug_igmp_packets
,
4717 no_debug_igmp_packets_cmd
,
4718 "no debug igmp packets",
4722 DEBUG_IGMP_PACKETS_STR
)
4724 PIM_DONT_DEBUG_IGMP_PACKETS
;
4729 DEFUN (debug_igmp_trace
,
4730 debug_igmp_trace_cmd
,
4734 DEBUG_IGMP_TRACE_STR
)
4736 PIM_DO_DEBUG_IGMP_TRACE
;
4740 DEFUN (no_debug_igmp_trace
,
4741 no_debug_igmp_trace_cmd
,
4742 "no debug igmp trace",
4746 DEBUG_IGMP_TRACE_STR
)
4748 PIM_DONT_DEBUG_IGMP_TRACE
;
4753 DEFUN (debug_mroute
,
4759 PIM_DO_DEBUG_MROUTE
;
4763 DEFUN (debug_mroute_detail
,
4764 debug_mroute_detail_cmd
,
4765 "debug mroute detail",
4770 PIM_DO_DEBUG_MROUTE_DETAIL
;
4774 DEFUN (no_debug_mroute
,
4775 no_debug_mroute_cmd
,
4781 PIM_DONT_DEBUG_MROUTE
;
4785 DEFUN (no_debug_mroute_detail
,
4786 no_debug_mroute_detail_cmd
,
4787 "no debug mroute detail",
4793 PIM_DONT_DEBUG_MROUTE_DETAIL
;
4797 DEFUN (debug_static
,
4803 PIM_DO_DEBUG_STATIC
;
4807 DEFUN (no_debug_static
,
4808 no_debug_static_cmd
,
4814 PIM_DONT_DEBUG_STATIC
;
4825 PIM_DO_DEBUG_PIM_EVENTS
;
4826 PIM_DO_DEBUG_PIM_PACKETS
;
4827 PIM_DO_DEBUG_PIM_TRACE
;
4828 PIM_DO_DEBUG_MSDP_EVENTS
;
4829 PIM_DO_DEBUG_MSDP_PACKETS
;
4833 DEFUN (no_debug_pim
,
4840 PIM_DONT_DEBUG_PIM_EVENTS
;
4841 PIM_DONT_DEBUG_PIM_PACKETS
;
4842 PIM_DONT_DEBUG_PIM_TRACE
;
4843 PIM_DONT_DEBUG_MSDP_EVENTS
;
4844 PIM_DONT_DEBUG_MSDP_PACKETS
;
4846 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
4847 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
4853 DEFUN (debug_pim_events
,
4854 debug_pim_events_cmd
,
4858 DEBUG_PIM_EVENTS_STR
)
4860 PIM_DO_DEBUG_PIM_EVENTS
;
4864 DEFUN (no_debug_pim_events
,
4865 no_debug_pim_events_cmd
,
4866 "no debug pim events",
4870 DEBUG_PIM_EVENTS_STR
)
4872 PIM_DONT_DEBUG_PIM_EVENTS
;
4876 DEFUN (debug_pim_packets
,
4877 debug_pim_packets_cmd
,
4878 "debug pim packets [<hello|joins|register>]",
4881 DEBUG_PIM_PACKETS_STR
4882 DEBUG_PIM_HELLO_PACKETS_STR
4883 DEBUG_PIM_J_P_PACKETS_STR
4884 DEBUG_PIM_PIM_REG_PACKETS_STR
)
4887 if (argv_find (argv
, argc
, "hello", &idx
))
4889 PIM_DO_DEBUG_PIM_HELLO
;
4890 vty_out (vty
, "PIM Hello debugging is on%s", VTY_NEWLINE
);
4892 else if (argv_find (argv
, argc
,"joins", &idx
))
4894 PIM_DO_DEBUG_PIM_J_P
;
4895 vty_out (vty
, "PIM Join/Prune debugging is on%s", VTY_NEWLINE
);
4897 else if (argv_find (argv
, argc
, "register", &idx
))
4899 PIM_DO_DEBUG_PIM_REG
;
4900 vty_out (vty
, "PIM Register debugging is on%s", VTY_NEWLINE
);
4904 PIM_DO_DEBUG_PIM_PACKETS
;
4905 vty_out (vty
, "PIM Packet debugging is on %s", VTY_NEWLINE
);
4910 DEFUN (no_debug_pim_packets
,
4911 no_debug_pim_packets_cmd
,
4912 "no debug pim packets [<hello|joins|register>]",
4916 DEBUG_PIM_PACKETS_STR
4917 DEBUG_PIM_HELLO_PACKETS_STR
4918 DEBUG_PIM_J_P_PACKETS_STR
4919 DEBUG_PIM_PIM_REG_PACKETS_STR
)
4922 if (argv_find (argv
, argc
,"hello",&idx
))
4924 PIM_DONT_DEBUG_PIM_HELLO
;
4925 vty_out (vty
, "PIM Hello debugging is off %s", VTY_NEWLINE
);
4927 else if (argv_find (argv
, argc
, "joins", &idx
))
4929 PIM_DONT_DEBUG_PIM_J_P
;
4930 vty_out (vty
, "PIM Join/Prune debugging is off %s", VTY_NEWLINE
);
4932 else if (argv_find (argv
, argc
, "register", &idx
))
4934 PIM_DONT_DEBUG_PIM_REG
;
4935 vty_out (vty
, "PIM Register debugging is off%s", VTY_NEWLINE
);
4938 PIM_DONT_DEBUG_PIM_PACKETS
;
4944 DEFUN (debug_pim_packetdump_send
,
4945 debug_pim_packetdump_send_cmd
,
4946 "debug pim packet-dump send",
4949 DEBUG_PIM_PACKETDUMP_STR
4950 DEBUG_PIM_PACKETDUMP_SEND_STR
)
4952 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND
;
4956 DEFUN (no_debug_pim_packetdump_send
,
4957 no_debug_pim_packetdump_send_cmd
,
4958 "no debug pim packet-dump send",
4962 DEBUG_PIM_PACKETDUMP_STR
4963 DEBUG_PIM_PACKETDUMP_SEND_STR
)
4965 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
4970 DEFUN (debug_pim_packetdump_recv
,
4971 debug_pim_packetdump_recv_cmd
,
4972 "debug pim packet-dump receive",
4975 DEBUG_PIM_PACKETDUMP_STR
4976 DEBUG_PIM_PACKETDUMP_RECV_STR
)
4978 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV
;
4982 DEFUN (no_debug_pim_packetdump_recv
,
4983 no_debug_pim_packetdump_recv_cmd
,
4984 "no debug pim packet-dump receive",
4988 DEBUG_PIM_PACKETDUMP_STR
4989 DEBUG_PIM_PACKETDUMP_RECV_STR
)
4991 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
4996 DEFUN (debug_pim_trace
,
4997 debug_pim_trace_cmd
,
5001 DEBUG_PIM_TRACE_STR
)
5003 PIM_DO_DEBUG_PIM_TRACE
;
5007 DEFUN (no_debug_pim_trace
,
5008 no_debug_pim_trace_cmd
,
5009 "no debug pim trace",
5013 DEBUG_PIM_TRACE_STR
)
5015 PIM_DONT_DEBUG_PIM_TRACE
;
5020 DEFUN (debug_ssmpingd
,
5027 PIM_DO_DEBUG_SSMPINGD
;
5031 DEFUN (no_debug_ssmpingd
,
5032 no_debug_ssmpingd_cmd
,
5033 "no debug ssmpingd",
5039 PIM_DONT_DEBUG_SSMPINGD
;
5044 DEFUN (debug_pim_zebra
,
5045 debug_pim_zebra_cmd
,
5049 DEBUG_PIM_ZEBRA_STR
)
5055 DEFUN (no_debug_pim_zebra
,
5056 no_debug_pim_zebra_cmd
,
5057 "no debug pim zebra",
5061 DEBUG_PIM_ZEBRA_STR
)
5063 PIM_DONT_DEBUG_ZEBRA
;
5074 PIM_DO_DEBUG_MSDP_EVENTS
;
5075 PIM_DO_DEBUG_MSDP_PACKETS
;
5079 DEFUN (no_debug_msdp
,
5086 PIM_DONT_DEBUG_MSDP_EVENTS
;
5087 PIM_DONT_DEBUG_MSDP_PACKETS
;
5091 ALIAS (no_debug_msdp
,
5097 DEFUN (debug_msdp_events
,
5098 debug_msdp_events_cmd
,
5099 "debug msdp events",
5102 DEBUG_MSDP_EVENTS_STR
)
5104 PIM_DO_DEBUG_MSDP_EVENTS
;
5108 DEFUN (no_debug_msdp_events
,
5109 no_debug_msdp_events_cmd
,
5110 "no debug msdp events",
5114 DEBUG_MSDP_EVENTS_STR
)
5116 PIM_DONT_DEBUG_MSDP_EVENTS
;
5120 ALIAS (no_debug_msdp_events
,
5121 undebug_msdp_events_cmd
,
5122 "undebug msdp events",
5125 DEBUG_MSDP_EVENTS_STR
)
5127 DEFUN (debug_msdp_packets
,
5128 debug_msdp_packets_cmd
,
5129 "debug msdp packets",
5132 DEBUG_MSDP_PACKETS_STR
)
5134 PIM_DO_DEBUG_MSDP_PACKETS
;
5138 DEFUN (no_debug_msdp_packets
,
5139 no_debug_msdp_packets_cmd
,
5140 "no debug msdp packets",
5144 DEBUG_MSDP_PACKETS_STR
)
5146 PIM_DONT_DEBUG_MSDP_PACKETS
;
5150 ALIAS (no_debug_msdp_packets
,
5151 undebug_msdp_packets_cmd
,
5152 "undebug msdp packets",
5155 DEBUG_MSDP_PACKETS_STR
)
5157 DEFUN (show_debugging_pim
,
5158 show_debugging_pim_cmd
,
5159 "show debugging pim",
5164 pim_debug_config_write(vty
);
5169 interface_pim_use_src_cmd_worker(struct vty
*vty
, const char *source
)
5172 struct in_addr source_addr
;
5173 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5175 result
= inet_pton(AF_INET
, source
, &source_addr
);
5177 vty_out(vty
, "%% Bad source address %s: errno=%d: %s%s",
5178 source
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
5182 result
= pim_update_source_set(ifp
, source_addr
);
5186 case PIM_IFACE_NOT_FOUND
:
5187 vty_out(vty
, "Pim not enabled on this interface%s", VTY_NEWLINE
);
5189 case PIM_UPDATE_SOURCE_DUP
:
5190 vty_out(vty
, "%% Source already set to %s%s", source
, VTY_NEWLINE
);
5193 vty_out(vty
, "%% Source set failed%s", VTY_NEWLINE
);
5196 return result
?CMD_WARNING
:CMD_SUCCESS
;
5199 DEFUN (interface_pim_use_source
,
5200 interface_pim_use_source_cmd
,
5201 "ip pim use-source A.B.C.D",
5203 "pim multicast routing\n"
5204 "Configure primary IP address\n"
5205 "source ip address\n")
5207 return interface_pim_use_src_cmd_worker (vty
, argv
[3]->arg
);
5210 DEFUN (interface_no_pim_use_source
,
5211 interface_no_pim_use_source_cmd
,
5212 "no ip pim use-source",
5215 "pim multicast routing\n"
5216 "Delete source IP address\n")
5218 return interface_pim_use_src_cmd_worker (vty
, "0.0.0.0");
5222 ip_msdp_peer_cmd_worker (struct vty
*vty
, const char *peer
, const char *local
)
5224 enum pim_msdp_err result
;
5225 struct in_addr peer_addr
;
5226 struct in_addr local_addr
;
5228 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
5230 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s%s",
5231 peer
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
5235 result
= inet_pton(AF_INET
, local
, &local_addr
);
5237 vty_out(vty
, "%% Bad source address %s: errno=%d: %s%s",
5238 local
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
5242 result
= pim_msdp_peer_add(peer_addr
, local_addr
, "default", NULL
/* mp_p */);
5244 case PIM_MSDP_ERR_NONE
:
5246 case PIM_MSDP_ERR_OOM
:
5247 vty_out(vty
, "%% Out of memory%s", VTY_NEWLINE
);
5249 case PIM_MSDP_ERR_PEER_EXISTS
:
5250 vty_out(vty
, "%% Peer exists%s", VTY_NEWLINE
);
5252 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
5253 vty_out(vty
, "%% Only one mesh-group allowed currently%s", VTY_NEWLINE
);
5256 vty_out(vty
, "%% peer add failed%s", VTY_NEWLINE
);
5259 return result
?CMD_WARNING
:CMD_SUCCESS
;
5262 DEFUN_HIDDEN (ip_msdp_peer
,
5264 "ip msdp peer A.B.C.D source A.B.C.D",
5267 "Configure MSDP peer\n"
5269 "Source address for TCP connection\n"
5270 "local ip address\n")
5272 return ip_msdp_peer_cmd_worker (vty
, argv
[3]->arg
, argv
[5]->arg
);
5276 ip_no_msdp_peer_cmd_worker (struct vty
*vty
, const char *peer
)
5278 enum pim_msdp_err result
;
5279 struct in_addr peer_addr
;
5281 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
5283 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s%s",
5284 peer
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
5288 result
= pim_msdp_peer_del(peer_addr
);
5290 case PIM_MSDP_ERR_NONE
:
5292 case PIM_MSDP_ERR_NO_PEER
:
5293 vty_out(vty
, "%% Peer does not exist%s", VTY_NEWLINE
);
5296 vty_out(vty
, "%% peer del failed%s", VTY_NEWLINE
);
5299 return result
?CMD_WARNING
:CMD_SUCCESS
;
5302 DEFUN_HIDDEN (no_ip_msdp_peer
,
5303 no_ip_msdp_peer_cmd
,
5304 "no ip msdp peer A.B.C.D",
5308 "Delete MSDP peer\n"
5309 "peer ip address\n")
5311 return ip_no_msdp_peer_cmd_worker (vty
, argv
[4]->arg
);
5315 ip_msdp_mesh_group_member_cmd_worker(struct vty
*vty
, const char *mg
, const char *mbr
)
5317 enum pim_msdp_err result
;
5318 struct in_addr mbr_ip
;
5320 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
5322 vty_out(vty
, "%% Bad member address %s: errno=%d: %s%s",
5323 mbr
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
5327 result
= pim_msdp_mg_mbr_add(mg
, mbr_ip
);
5329 case PIM_MSDP_ERR_NONE
:
5331 case PIM_MSDP_ERR_OOM
:
5332 vty_out(vty
, "%% Out of memory%s", VTY_NEWLINE
);
5334 case PIM_MSDP_ERR_MG_MBR_EXISTS
:
5335 vty_out(vty
, "%% mesh-group member exists%s", VTY_NEWLINE
);
5337 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
5338 vty_out(vty
, "%% Only one mesh-group allowed currently%s", VTY_NEWLINE
);
5341 vty_out(vty
, "%% member add failed%s", VTY_NEWLINE
);
5344 return result
?CMD_WARNING
:CMD_SUCCESS
;
5347 DEFUN (ip_msdp_mesh_group_member
,
5348 ip_msdp_mesh_group_member_cmd
,
5349 "ip msdp mesh-group WORD member A.B.C.D",
5352 "Configure MSDP mesh-group\n"
5354 "mesh group member\n"
5355 "peer ip address\n")
5357 return ip_msdp_mesh_group_member_cmd_worker(vty
, argv
[3]->arg
, argv
[5]->arg
);
5361 ip_no_msdp_mesh_group_member_cmd_worker(struct vty
*vty
, const char *mg
, const char *mbr
)
5363 enum pim_msdp_err result
;
5364 struct in_addr mbr_ip
;
5366 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
5368 vty_out(vty
, "%% Bad member address %s: errno=%d: %s%s",
5369 mbr
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
5373 result
= pim_msdp_mg_mbr_del(mg
, mbr_ip
);
5375 case PIM_MSDP_ERR_NONE
:
5377 case PIM_MSDP_ERR_NO_MG
:
5378 vty_out(vty
, "%% mesh-group does not exist%s", VTY_NEWLINE
);
5380 case PIM_MSDP_ERR_NO_MG_MBR
:
5381 vty_out(vty
, "%% mesh-group member does not exist%s", VTY_NEWLINE
);
5384 vty_out(vty
, "%% mesh-group member del failed%s", VTY_NEWLINE
);
5387 return result
?CMD_WARNING
:CMD_SUCCESS
;
5389 DEFUN (no_ip_msdp_mesh_group_member
,
5390 no_ip_msdp_mesh_group_member_cmd
,
5391 "no ip msdp mesh-group WORD member A.B.C.D",
5395 "Delete MSDP mesh-group member\n"
5397 "mesh group member\n"
5398 "peer ip address\n")
5400 return ip_no_msdp_mesh_group_member_cmd_worker(vty
, argv
[4]->arg
, argv
[6]->arg
);
5404 ip_msdp_mesh_group_source_cmd_worker(struct vty
*vty
, const char *mg
, const char *src
)
5406 enum pim_msdp_err result
;
5407 struct in_addr src_ip
;
5409 result
= inet_pton(AF_INET
, src
, &src_ip
);
5411 vty_out(vty
, "%% Bad source address %s: errno=%d: %s%s",
5412 src
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
5416 result
= pim_msdp_mg_src_add(mg
, src_ip
);
5418 case PIM_MSDP_ERR_NONE
:
5420 case PIM_MSDP_ERR_OOM
:
5421 vty_out(vty
, "%% Out of memory%s", VTY_NEWLINE
);
5423 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
5424 vty_out(vty
, "%% Only one mesh-group allowed currently%s", VTY_NEWLINE
);
5427 vty_out(vty
, "%% source add failed%s", VTY_NEWLINE
);
5430 return result
?CMD_WARNING
:CMD_SUCCESS
;
5434 DEFUN (ip_msdp_mesh_group_source
,
5435 ip_msdp_mesh_group_source_cmd
,
5436 "ip msdp mesh-group WORD source A.B.C.D",
5439 "Configure MSDP mesh-group\n"
5441 "mesh group local address\n"
5442 "source ip address for the TCP connection\n")
5444 return ip_msdp_mesh_group_source_cmd_worker(vty
, argv
[3]->arg
, argv
[5]->arg
);
5448 ip_no_msdp_mesh_group_source_cmd_worker(struct vty
*vty
, const char *mg
)
5450 enum pim_msdp_err result
;
5452 result
= pim_msdp_mg_src_del(mg
);
5454 case PIM_MSDP_ERR_NONE
:
5456 case PIM_MSDP_ERR_NO_MG
:
5457 vty_out(vty
, "%% mesh-group does not exist%s", VTY_NEWLINE
);
5460 vty_out(vty
, "%% mesh-group source del failed%s", VTY_NEWLINE
);
5463 return result
?CMD_WARNING
:CMD_SUCCESS
;
5467 ip_no_msdp_mesh_group_cmd_worker(struct vty
*vty
, const char *mg
)
5469 enum pim_msdp_err result
;
5471 result
= pim_msdp_mg_del(mg
);
5473 case PIM_MSDP_ERR_NONE
:
5475 case PIM_MSDP_ERR_NO_MG
:
5476 vty_out(vty
, "%% mesh-group does not exist%s", VTY_NEWLINE
);
5479 vty_out(vty
, "%% mesh-group source del failed%s", VTY_NEWLINE
);
5482 return result
? CMD_WARNING
: CMD_SUCCESS
;
5485 DEFUN (no_ip_msdp_mesh_group_source
,
5486 no_ip_msdp_mesh_group_source_cmd
,
5487 "no ip msdp mesh-group WORD source [A.B.C.D]",
5491 "Delete MSDP mesh-group source\n"
5493 "mesh group source\n"
5494 "mesh group local address\n")
5497 return ip_no_msdp_mesh_group_cmd_worker(vty
, argv
[6]->arg
);
5499 return ip_no_msdp_mesh_group_source_cmd_worker(vty
, argv
[4]->arg
);
5503 print_empty_json_obj(struct vty
*vty
)
5506 json
= json_object_new_object();
5507 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
5508 json_object_free(json
);
5512 ip_msdp_show_mesh_group(struct vty
*vty
, u_char uj
)
5514 struct listnode
*mbrnode
;
5515 struct pim_msdp_mg_mbr
*mbr
;
5516 struct pim_msdp_mg
*mg
= msdp
->mg
;
5517 char mbr_str
[INET_ADDRSTRLEN
];
5518 char src_str
[INET_ADDRSTRLEN
];
5519 char state_str
[PIM_MSDP_STATE_STRLEN
];
5520 enum pim_msdp_peer_state state
;
5521 json_object
*json
= NULL
;
5522 json_object
*json_mg_row
= NULL
;
5523 json_object
*json_members
= NULL
;
5524 json_object
*json_row
= NULL
;
5528 print_empty_json_obj(vty
);
5532 pim_inet4_dump("<source?>", mg
->src_ip
, src_str
, sizeof(src_str
));
5534 json
= json_object_new_object();
5535 /* currently there is only one mesh group but we should still make
5536 * it a dict with mg-name as key */
5537 json_mg_row
= json_object_new_object();
5538 json_object_string_add(json_mg_row
, "name", mg
->mesh_group_name
);
5539 json_object_string_add(json_mg_row
, "source", src_str
);
5541 vty_out(vty
, "Mesh group : %s%s", mg
->mesh_group_name
, VTY_NEWLINE
);
5542 vty_out(vty
, " Source : %s%s", src_str
, VTY_NEWLINE
);
5543 vty_out(vty
, " Member State%s", VTY_NEWLINE
);
5546 for (ALL_LIST_ELEMENTS_RO(mg
->mbr_list
, mbrnode
, mbr
)) {
5547 pim_inet4_dump("<mbr?>", mbr
->mbr_ip
, mbr_str
, sizeof(mbr_str
));
5549 state
= mbr
->mp
->state
;
5551 state
= PIM_MSDP_DISABLED
;
5553 pim_msdp_state_dump(state
, state_str
, sizeof(state_str
));
5555 json_row
= json_object_new_object();
5556 json_object_string_add(json_row
, "member", mbr_str
);
5557 json_object_string_add(json_row
, "state", state_str
);
5558 if (!json_members
) {
5559 json_members
= json_object_new_object();
5560 json_object_object_add(json_mg_row
, "members", json_members
);
5562 json_object_object_add(json_members
, mbr_str
, json_row
);
5564 vty_out(vty
, " %-15s %11s%s",
5565 mbr_str
, state_str
, VTY_NEWLINE
);
5570 json_object_object_add(json
, mg
->mesh_group_name
, json_mg_row
);
5571 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
5572 json_object_free(json
);
5576 DEFUN (show_ip_msdp_mesh_group
,
5577 show_ip_msdp_mesh_group_cmd
,
5578 "show ip msdp mesh-group [json]",
5582 "MSDP mesh-group information\n"
5583 "JavaScript Object Notation\n")
5585 u_char uj
= use_json(argc
, argv
);
5586 ip_msdp_show_mesh_group(vty
, uj
);
5592 ip_msdp_show_peers(struct vty
*vty
, u_char uj
)
5594 struct listnode
*mpnode
;
5595 struct pim_msdp_peer
*mp
;
5596 char peer_str
[INET_ADDRSTRLEN
];
5597 char local_str
[INET_ADDRSTRLEN
];
5598 char state_str
[PIM_MSDP_STATE_STRLEN
];
5599 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
5601 json_object
*json
= NULL
;
5602 json_object
*json_row
= NULL
;
5606 json
= json_object_new_object();
5608 vty_out(vty
, "Peer Local State Uptime SaCnt%s", VTY_NEWLINE
);
5611 for (ALL_LIST_ELEMENTS_RO(msdp
->peer_list
, mpnode
, mp
)) {
5612 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
5613 now
= pim_time_monotonic_sec();
5614 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- mp
->uptime
);
5616 strcpy(timebuf
, "-");
5618 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
5619 pim_inet4_dump("<local?>", mp
->local
, local_str
, sizeof(local_str
));
5620 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
5622 json_row
= json_object_new_object();
5623 json_object_string_add(json_row
, "peer", peer_str
);
5624 json_object_string_add(json_row
, "local", local_str
);
5625 json_object_string_add(json_row
, "state", state_str
);
5626 json_object_string_add(json_row
, "upTime", timebuf
);
5627 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
5628 json_object_object_add(json
, peer_str
, json_row
);
5630 vty_out(vty
, "%-15s %15s %11s %8s %6d%s",
5631 peer_str
, local_str
, state_str
,
5632 timebuf
, mp
->sa_cnt
, VTY_NEWLINE
);
5637 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
5638 json_object_free(json
);
5643 ip_msdp_show_peers_detail(struct vty
*vty
, const char *peer
, u_char uj
)
5645 struct listnode
*mpnode
;
5646 struct pim_msdp_peer
*mp
;
5647 char peer_str
[INET_ADDRSTRLEN
];
5648 char local_str
[INET_ADDRSTRLEN
];
5649 char state_str
[PIM_MSDP_STATE_STRLEN
];
5650 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
5651 char katimer
[PIM_MSDP_TIMER_STRLEN
];
5652 char crtimer
[PIM_MSDP_TIMER_STRLEN
];
5653 char holdtimer
[PIM_MSDP_TIMER_STRLEN
];
5655 json_object
*json
= NULL
;
5656 json_object
*json_row
= NULL
;
5659 json
= json_object_new_object();
5662 for (ALL_LIST_ELEMENTS_RO(msdp
->peer_list
, mpnode
, mp
)) {
5663 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
5664 if (strcmp(peer
, "detail") &&
5665 strcmp(peer
, peer_str
))
5668 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
5669 now
= pim_time_monotonic_sec();
5670 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- mp
->uptime
);
5672 strcpy(timebuf
, "-");
5674 pim_inet4_dump("<local?>", mp
->local
, local_str
, sizeof(local_str
));
5675 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
5676 pim_time_timer_to_hhmmss(katimer
, sizeof(katimer
), mp
->ka_timer
);
5677 pim_time_timer_to_hhmmss(crtimer
, sizeof(crtimer
), mp
->cr_timer
);
5678 pim_time_timer_to_hhmmss(holdtimer
, sizeof(holdtimer
), mp
->hold_timer
);
5681 json_row
= json_object_new_object();
5682 json_object_string_add(json_row
, "peer", peer_str
);
5683 json_object_string_add(json_row
, "local", local_str
);
5684 json_object_string_add(json_row
, "meshGroupName", mp
->mesh_group_name
);
5685 json_object_string_add(json_row
, "state", state_str
);
5686 json_object_string_add(json_row
, "upTime", timebuf
);
5687 json_object_string_add(json_row
, "keepAliveTimer", katimer
);
5688 json_object_string_add(json_row
, "connRetryTimer", crtimer
);
5689 json_object_string_add(json_row
, "holdTimer", holdtimer
);
5690 json_object_string_add(json_row
, "lastReset", mp
->last_reset
);
5691 json_object_int_add(json_row
, "connAttempts", mp
->conn_attempts
);
5692 json_object_int_add(json_row
, "establishedChanges", mp
->est_flaps
);
5693 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
5694 json_object_int_add(json_row
, "kaSent", mp
->ka_tx_cnt
);
5695 json_object_int_add(json_row
, "kaRcvd", mp
->ka_rx_cnt
);
5696 json_object_int_add(json_row
, "saSent", mp
->sa_tx_cnt
);
5697 json_object_int_add(json_row
, "saRcvd", mp
->sa_rx_cnt
);
5698 json_object_object_add(json
, peer_str
, json_row
);
5700 vty_out(vty
, "Peer : %s%s", peer_str
, VTY_NEWLINE
);
5701 vty_out(vty
, " Local : %s%s", local_str
, VTY_NEWLINE
);
5702 vty_out(vty
, " Mesh Group : %s%s", mp
->mesh_group_name
, VTY_NEWLINE
);
5703 vty_out(vty
, " State : %s%s", state_str
, VTY_NEWLINE
);
5704 vty_out(vty
, " Uptime : %s%s", timebuf
, VTY_NEWLINE
);
5706 vty_out(vty
, " Keepalive Timer : %s%s", katimer
, VTY_NEWLINE
);
5707 vty_out(vty
, " Conn Retry Timer : %s%s", crtimer
, VTY_NEWLINE
);
5708 vty_out(vty
, " Hold Timer : %s%s", holdtimer
, VTY_NEWLINE
);
5709 vty_out(vty
, " Last Reset : %s%s", mp
->last_reset
, VTY_NEWLINE
);
5710 vty_out(vty
, " Conn Attempts : %d%s", mp
->conn_attempts
, VTY_NEWLINE
);
5711 vty_out(vty
, " Established Changes : %d%s", mp
->est_flaps
, VTY_NEWLINE
);
5712 vty_out(vty
, " SA Count : %d%s", mp
->sa_cnt
, VTY_NEWLINE
);
5713 vty_out(vty
, " Statistics :%s", VTY_NEWLINE
);
5714 vty_out(vty
, " Sent Rcvd%s", VTY_NEWLINE
);
5715 vty_out(vty
, " Keepalives : %10d %10d%s",
5716 mp
->ka_tx_cnt
, mp
->ka_rx_cnt
, VTY_NEWLINE
);
5717 vty_out(vty
, " SAs : %10d %10d%s",
5718 mp
->sa_tx_cnt
, mp
->sa_rx_cnt
, VTY_NEWLINE
);
5719 vty_out(vty
, "%s", VTY_NEWLINE
);
5724 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
5725 json_object_free(json
);
5729 DEFUN (show_ip_msdp_peer_detail
,
5730 show_ip_msdp_peer_detail_cmd
,
5731 "show ip msdp peer [detail|A.B.C.D] [json]",
5735 "MSDP peer information\n"
5738 "JavaScript Object Notation\n")
5740 u_char uj
= use_json(argc
, argv
);
5745 ip_msdp_show_peers_detail(vty
, argv
[4]->arg
, uj
);
5747 ip_msdp_show_peers(vty
, uj
);
5753 ip_msdp_show_sa(struct vty
*vty
, u_char uj
)
5755 struct listnode
*sanode
;
5756 struct pim_msdp_sa
*sa
;
5757 char src_str
[INET_ADDRSTRLEN
];
5758 char grp_str
[INET_ADDRSTRLEN
];
5759 char rp_str
[INET_ADDRSTRLEN
];
5760 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
5764 json_object
*json
= NULL
;
5765 json_object
*json_group
= NULL
;
5766 json_object
*json_row
= NULL
;
5769 json
= json_object_new_object();
5771 vty_out(vty
, "Source Group RP Local SPT Uptime%s", VTY_NEWLINE
);
5774 for (ALL_LIST_ELEMENTS_RO(msdp
->sa_list
, sanode
, sa
)) {
5775 now
= pim_time_monotonic_sec();
5776 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
5777 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
5778 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
5779 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
5780 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
5782 strcpy(spt_str
, "yes");
5784 strcpy(spt_str
, "no");
5787 strcpy(rp_str
, "-");
5788 strcpy(spt_str
, "-");
5790 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
5791 strcpy(local_str
, "yes");
5793 strcpy(local_str
, "no");
5796 json_object_object_get_ex(json
, grp_str
, &json_group
);
5799 json_group
= json_object_new_object();
5800 json_object_object_add(json
, grp_str
, json_group
);
5803 json_row
= json_object_new_object();
5804 json_object_string_add(json_row
, "source", src_str
);
5805 json_object_string_add(json_row
, "group", grp_str
);
5806 json_object_string_add(json_row
, "rp", rp_str
);
5807 json_object_string_add(json_row
, "local", local_str
);
5808 json_object_string_add(json_row
, "sptSetup", spt_str
);
5809 json_object_string_add(json_row
, "upTime", timebuf
);
5810 json_object_object_add(json_group
, src_str
, json_row
);
5812 vty_out(vty
, "%-15s %15s %15s %5c %3c %8s%s",
5813 src_str
, grp_str
, rp_str
, local_str
[0], spt_str
[0], timebuf
, VTY_NEWLINE
);
5819 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
5820 json_object_free(json
);
5825 ip_msdp_show_sa_entry_detail(struct pim_msdp_sa
*sa
, const char *src_str
,
5826 const char *grp_str
, struct vty
*vty
,
5827 u_char uj
, json_object
*json
)
5829 char rp_str
[INET_ADDRSTRLEN
];
5830 char peer_str
[INET_ADDRSTRLEN
];
5831 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
5834 char statetimer
[PIM_MSDP_TIMER_STRLEN
];
5836 json_object
*json_group
= NULL
;
5837 json_object
*json_row
= NULL
;
5839 now
= pim_time_monotonic_sec();
5840 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
5841 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
5842 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
5843 pim_inet4_dump("<peer?>", sa
->peer
, peer_str
, sizeof(peer_str
));
5845 strcpy(spt_str
, "yes");
5847 strcpy(spt_str
, "no");
5850 strcpy(rp_str
, "-");
5851 strcpy(peer_str
, "-");
5852 strcpy(spt_str
, "-");
5854 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
5855 strcpy(local_str
, "yes");
5857 strcpy(local_str
, "no");
5859 pim_time_timer_to_hhmmss(statetimer
, sizeof(statetimer
), sa
->sa_state_timer
);
5861 json_object_object_get_ex(json
, grp_str
, &json_group
);
5864 json_group
= json_object_new_object();
5865 json_object_object_add(json
, grp_str
, json_group
);
5868 json_row
= json_object_new_object();
5869 json_object_string_add(json_row
, "source", src_str
);
5870 json_object_string_add(json_row
, "group", grp_str
);
5871 json_object_string_add(json_row
, "rp", rp_str
);
5872 json_object_string_add(json_row
, "local", local_str
);
5873 json_object_string_add(json_row
, "sptSetup", spt_str
);
5874 json_object_string_add(json_row
, "upTime", timebuf
);
5875 json_object_string_add(json_row
, "stateTimer", statetimer
);
5876 json_object_object_add(json_group
, src_str
, json_row
);
5878 vty_out(vty
, "SA : %s%s", sa
->sg_str
, VTY_NEWLINE
);
5879 vty_out(vty
, " RP : %s%s", rp_str
, VTY_NEWLINE
);
5880 vty_out(vty
, " Peer : %s%s", peer_str
, VTY_NEWLINE
);
5881 vty_out(vty
, " Local : %s%s", local_str
, VTY_NEWLINE
);
5882 vty_out(vty
, " SPT Setup : %s%s", spt_str
, VTY_NEWLINE
);
5883 vty_out(vty
, " Uptime : %s%s", timebuf
, VTY_NEWLINE
);
5884 vty_out(vty
, " State Timer : %s%s", statetimer
, VTY_NEWLINE
);
5885 vty_out(vty
, "%s", VTY_NEWLINE
);
5890 ip_msdp_show_sa_detail(struct vty
*vty
, u_char uj
)
5892 struct listnode
*sanode
;
5893 struct pim_msdp_sa
*sa
;
5894 char src_str
[INET_ADDRSTRLEN
];
5895 char grp_str
[INET_ADDRSTRLEN
];
5896 json_object
*json
= NULL
;
5899 json
= json_object_new_object();
5902 for (ALL_LIST_ELEMENTS_RO(msdp
->sa_list
, sanode
, sa
)) {
5903 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
5904 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
5905 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
, uj
, json
);
5909 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
5910 json_object_free(json
);
5914 DEFUN (show_ip_msdp_sa_detail
,
5915 show_ip_msdp_sa_detail_cmd
,
5916 "show ip msdp sa detail [json]",
5920 "MSDP active-source information\n"
5922 "JavaScript Object Notation\n")
5924 u_char uj
= use_json(argc
, argv
);
5925 ip_msdp_show_sa_detail(vty
, uj
);
5931 ip_msdp_show_sa_addr(struct vty
*vty
, const char *addr
, u_char uj
)
5933 struct listnode
*sanode
;
5934 struct pim_msdp_sa
*sa
;
5935 char src_str
[INET_ADDRSTRLEN
];
5936 char grp_str
[INET_ADDRSTRLEN
];
5937 json_object
*json
= NULL
;
5940 json
= json_object_new_object();
5943 for (ALL_LIST_ELEMENTS_RO(msdp
->sa_list
, sanode
, sa
)) {
5944 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
5945 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
5946 if (!strcmp(addr
, src_str
) || !strcmp(addr
, grp_str
)) {
5947 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
, uj
, json
);
5952 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
5953 json_object_free(json
);
5958 ip_msdp_show_sa_sg(struct vty
*vty
, const char *src
, const char *grp
, u_char uj
)
5960 struct listnode
*sanode
;
5961 struct pim_msdp_sa
*sa
;
5962 char src_str
[INET_ADDRSTRLEN
];
5963 char grp_str
[INET_ADDRSTRLEN
];
5964 json_object
*json
= NULL
;
5967 json
= json_object_new_object();
5970 for (ALL_LIST_ELEMENTS_RO(msdp
->sa_list
, sanode
, sa
)) {
5971 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
5972 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
5973 if (!strcmp(src
, src_str
) && !strcmp(grp
, grp_str
)) {
5974 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
, uj
, json
);
5979 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
5980 json_object_free(json
);
5984 DEFUN (show_ip_msdp_sa_sg
,
5985 show_ip_msdp_sa_sg_cmd
,
5986 "show ip msdp sa [A.B.C.D [A.B.C.D]] [json]",
5990 "MSDP active-source information\n"
5991 "source or group ip\n"
5993 "JavaScript Object Notation\n")
5995 u_char uj
= use_json(argc
, argv
);
6000 ip_msdp_show_sa_sg(vty
, argv
[4]->arg
, argv
[5]->arg
, uj
);
6002 ip_msdp_show_sa_addr(vty
, argv
[4]->arg
, uj
);
6004 ip_msdp_show_sa(vty
, uj
);
6011 install_node (&pim_global_node
, pim_global_config_write
); /* PIM_NODE */
6012 install_node (&interface_node
, pim_interface_config_write
); /* INTERFACE_NODE */
6015 install_node (&debug_node
, pim_debug_config_write
);
6017 install_element (CONFIG_NODE
, &ip_multicast_routing_cmd
);
6018 install_element (CONFIG_NODE
, &no_ip_multicast_routing_cmd
);
6019 install_element (CONFIG_NODE
, &ip_pim_rp_cmd
);
6020 install_element (CONFIG_NODE
, &no_ip_pim_rp_cmd
);
6021 install_element (CONFIG_NODE
, &ip_pim_rp_prefix_list_cmd
);
6022 install_element (CONFIG_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
6023 install_element (CONFIG_NODE
, &ip_pim_register_suppress_cmd
);
6024 install_element (CONFIG_NODE
, &no_ip_pim_register_suppress_cmd
);
6025 install_element (CONFIG_NODE
, &ip_pim_joinprune_time_cmd
);
6026 install_element (CONFIG_NODE
, &no_ip_pim_joinprune_time_cmd
);
6027 install_element (CONFIG_NODE
, &ip_pim_keep_alive_cmd
);
6028 install_element (CONFIG_NODE
, &no_ip_pim_keep_alive_cmd
);
6029 install_element (CONFIG_NODE
, &ip_pim_packets_cmd
);
6030 install_element (CONFIG_NODE
, &no_ip_pim_packets_cmd
);
6031 install_element (CONFIG_NODE
, &ip_ssmpingd_cmd
);
6032 install_element (CONFIG_NODE
, &no_ip_ssmpingd_cmd
);
6033 install_element (CONFIG_NODE
, &ip_msdp_peer_cmd
);
6034 install_element (CONFIG_NODE
, &no_ip_msdp_peer_cmd
);
6036 install_element (INTERFACE_NODE
, &interface_ip_igmp_cmd
);
6037 install_element (INTERFACE_NODE
, &interface_no_ip_igmp_cmd
);
6038 install_element (INTERFACE_NODE
, &interface_ip_igmp_join_cmd
);
6039 install_element (INTERFACE_NODE
, &interface_no_ip_igmp_join_cmd
);
6040 install_element (INTERFACE_NODE
, &interface_ip_igmp_version_cmd
);
6041 install_element (INTERFACE_NODE
, &interface_no_ip_igmp_version_cmd
);
6042 install_element (INTERFACE_NODE
, &interface_ip_igmp_query_interval_cmd
);
6043 install_element (INTERFACE_NODE
, &interface_no_ip_igmp_query_interval_cmd
);
6044 install_element (INTERFACE_NODE
, &interface_ip_igmp_query_max_response_time_cmd
);
6045 install_element (INTERFACE_NODE
, &interface_no_ip_igmp_query_max_response_time_cmd
);
6046 install_element (INTERFACE_NODE
, &interface_ip_igmp_query_max_response_time_dsec_cmd
);
6047 install_element (INTERFACE_NODE
, &interface_no_ip_igmp_query_max_response_time_dsec_cmd
);
6048 install_element (INTERFACE_NODE
, &interface_ip_pim_ssm_cmd
);
6049 install_element (INTERFACE_NODE
, &interface_no_ip_pim_ssm_cmd
);
6050 install_element (INTERFACE_NODE
, &interface_ip_pim_sm_cmd
);
6051 install_element (INTERFACE_NODE
, &interface_no_ip_pim_sm_cmd
);
6052 install_element (INTERFACE_NODE
, &interface_ip_pim_drprio_cmd
);
6053 install_element (INTERFACE_NODE
, &interface_no_ip_pim_drprio_cmd
);
6054 install_element (INTERFACE_NODE
, &interface_ip_pim_hello_cmd
);
6055 install_element (INTERFACE_NODE
, &interface_no_ip_pim_hello_cmd
);
6057 // Static mroutes NEB
6058 install_element (INTERFACE_NODE
, &interface_ip_mroute_cmd
);
6059 install_element (INTERFACE_NODE
, &interface_ip_mroute_source_cmd
);
6060 install_element (INTERFACE_NODE
, &interface_no_ip_mroute_cmd
);
6061 install_element (INTERFACE_NODE
, &interface_no_ip_mroute_source_cmd
);
6063 install_element (VIEW_NODE
, &show_ip_igmp_interface_cmd
);
6064 install_element (VIEW_NODE
, &show_ip_igmp_join_cmd
);
6065 install_element (VIEW_NODE
, &show_ip_igmp_groups_cmd
);
6066 install_element (VIEW_NODE
, &show_ip_igmp_groups_retransmissions_cmd
);
6067 install_element (VIEW_NODE
, &show_ip_igmp_sources_cmd
);
6068 install_element (VIEW_NODE
, &show_ip_igmp_sources_retransmissions_cmd
);
6069 install_element (VIEW_NODE
, &show_ip_pim_assert_cmd
);
6070 install_element (VIEW_NODE
, &show_ip_pim_assert_internal_cmd
);
6071 install_element (VIEW_NODE
, &show_ip_pim_assert_metric_cmd
);
6072 install_element (VIEW_NODE
, &show_ip_pim_assert_winner_metric_cmd
);
6073 install_element (VIEW_NODE
, &show_ip_pim_interface_cmd
);
6074 install_element (VIEW_NODE
, &show_ip_pim_join_cmd
);
6075 install_element (VIEW_NODE
, &show_ip_pim_local_membership_cmd
);
6076 install_element (VIEW_NODE
, &show_ip_pim_neighbor_cmd
);
6077 install_element (VIEW_NODE
, &show_ip_pim_rpf_cmd
);
6078 install_element (VIEW_NODE
, &show_ip_pim_secondary_cmd
);
6079 install_element (VIEW_NODE
, &show_ip_pim_state_cmd
);
6080 install_element (VIEW_NODE
, &show_ip_pim_upstream_cmd
);
6081 install_element (VIEW_NODE
, &show_ip_pim_upstream_join_desired_cmd
);
6082 install_element (VIEW_NODE
, &show_ip_pim_upstream_rpf_cmd
);
6083 install_element (VIEW_NODE
, &show_ip_pim_rp_cmd
);
6084 install_element (VIEW_NODE
, &show_ip_multicast_cmd
);
6085 install_element (VIEW_NODE
, &show_ip_mroute_cmd
);
6086 install_element (VIEW_NODE
, &show_ip_mroute_count_cmd
);
6087 install_element (VIEW_NODE
, &show_ip_rib_cmd
);
6088 install_element (VIEW_NODE
, &show_ip_ssmpingd_cmd
);
6089 install_element (VIEW_NODE
, &show_debugging_pim_cmd
);
6091 install_element (ENABLE_NODE
, &clear_ip_interfaces_cmd
);
6092 install_element (ENABLE_NODE
, &clear_ip_igmp_interfaces_cmd
);
6093 install_element (ENABLE_NODE
, &clear_ip_mroute_cmd
);
6094 install_element (ENABLE_NODE
, &clear_ip_pim_interfaces_cmd
);
6095 install_element (ENABLE_NODE
, &clear_ip_pim_oil_cmd
);
6097 install_element (ENABLE_NODE
, &debug_igmp_cmd
);
6098 install_element (ENABLE_NODE
, &no_debug_igmp_cmd
);
6099 install_element (ENABLE_NODE
, &debug_igmp_events_cmd
);
6100 install_element (ENABLE_NODE
, &no_debug_igmp_events_cmd
);
6101 install_element (ENABLE_NODE
, &debug_igmp_packets_cmd
);
6102 install_element (ENABLE_NODE
, &no_debug_igmp_packets_cmd
);
6103 install_element (ENABLE_NODE
, &debug_igmp_trace_cmd
);
6104 install_element (ENABLE_NODE
, &no_debug_igmp_trace_cmd
);
6105 install_element (ENABLE_NODE
, &debug_mroute_cmd
);
6106 install_element (ENABLE_NODE
, &debug_mroute_detail_cmd
);
6107 install_element (ENABLE_NODE
, &no_debug_mroute_cmd
);
6108 install_element (ENABLE_NODE
, &no_debug_mroute_detail_cmd
);
6109 install_element (ENABLE_NODE
, &debug_static_cmd
);
6110 install_element (ENABLE_NODE
, &no_debug_static_cmd
);
6111 install_element (ENABLE_NODE
, &debug_pim_cmd
);
6112 install_element (ENABLE_NODE
, &no_debug_pim_cmd
);
6113 install_element (ENABLE_NODE
, &debug_pim_events_cmd
);
6114 install_element (ENABLE_NODE
, &no_debug_pim_events_cmd
);
6115 install_element (ENABLE_NODE
, &debug_pim_packets_cmd
);
6116 install_element (ENABLE_NODE
, &no_debug_pim_packets_cmd
);
6117 install_element (ENABLE_NODE
, &debug_pim_packetdump_send_cmd
);
6118 install_element (ENABLE_NODE
, &no_debug_pim_packetdump_send_cmd
);
6119 install_element (ENABLE_NODE
, &debug_pim_packetdump_recv_cmd
);
6120 install_element (ENABLE_NODE
, &no_debug_pim_packetdump_recv_cmd
);
6121 install_element (ENABLE_NODE
, &debug_pim_trace_cmd
);
6122 install_element (ENABLE_NODE
, &no_debug_pim_trace_cmd
);
6123 install_element (ENABLE_NODE
, &debug_ssmpingd_cmd
);
6124 install_element (ENABLE_NODE
, &no_debug_ssmpingd_cmd
);
6125 install_element (ENABLE_NODE
, &debug_pim_zebra_cmd
);
6126 install_element (ENABLE_NODE
, &no_debug_pim_zebra_cmd
);
6127 install_element (ENABLE_NODE
, &debug_msdp_cmd
);
6128 install_element (ENABLE_NODE
, &no_debug_msdp_cmd
);
6129 install_element (ENABLE_NODE
, &undebug_msdp_cmd
);
6130 install_element (ENABLE_NODE
, &debug_msdp_events_cmd
);
6131 install_element (ENABLE_NODE
, &no_debug_msdp_events_cmd
);
6132 install_element (ENABLE_NODE
, &undebug_msdp_events_cmd
);
6133 install_element (ENABLE_NODE
, &debug_msdp_packets_cmd
);
6134 install_element (ENABLE_NODE
, &no_debug_msdp_packets_cmd
);
6135 install_element (ENABLE_NODE
, &undebug_msdp_packets_cmd
);
6137 install_element (CONFIG_NODE
, &debug_igmp_cmd
);
6138 install_element (CONFIG_NODE
, &no_debug_igmp_cmd
);
6139 install_element (CONFIG_NODE
, &debug_igmp_events_cmd
);
6140 install_element (CONFIG_NODE
, &no_debug_igmp_events_cmd
);
6141 install_element (CONFIG_NODE
, &debug_igmp_packets_cmd
);
6142 install_element (CONFIG_NODE
, &no_debug_igmp_packets_cmd
);
6143 install_element (CONFIG_NODE
, &debug_igmp_trace_cmd
);
6144 install_element (CONFIG_NODE
, &no_debug_igmp_trace_cmd
);
6145 install_element (CONFIG_NODE
, &debug_mroute_cmd
);
6146 install_element (CONFIG_NODE
, &debug_mroute_detail_cmd
);
6147 install_element (CONFIG_NODE
, &no_debug_mroute_cmd
);
6148 install_element (CONFIG_NODE
, &no_debug_mroute_detail_cmd
);
6149 install_element (CONFIG_NODE
, &debug_static_cmd
);
6150 install_element (CONFIG_NODE
, &no_debug_static_cmd
);
6151 install_element (CONFIG_NODE
, &debug_pim_cmd
);
6152 install_element (CONFIG_NODE
, &no_debug_pim_cmd
);
6153 install_element (CONFIG_NODE
, &debug_pim_events_cmd
);
6154 install_element (CONFIG_NODE
, &no_debug_pim_events_cmd
);
6155 install_element (CONFIG_NODE
, &debug_pim_packets_cmd
);
6156 install_element (CONFIG_NODE
, &no_debug_pim_packets_cmd
);
6157 install_element (CONFIG_NODE
, &debug_pim_trace_cmd
);
6158 install_element (CONFIG_NODE
, &no_debug_pim_trace_cmd
);
6159 install_element (CONFIG_NODE
, &debug_ssmpingd_cmd
);
6160 install_element (CONFIG_NODE
, &no_debug_ssmpingd_cmd
);
6161 install_element (CONFIG_NODE
, &debug_pim_zebra_cmd
);
6162 install_element (CONFIG_NODE
, &no_debug_pim_zebra_cmd
);
6163 install_element (CONFIG_NODE
, &debug_msdp_cmd
);
6164 install_element (CONFIG_NODE
, &no_debug_msdp_cmd
);
6165 install_element (CONFIG_NODE
, &undebug_msdp_cmd
);
6166 install_element (CONFIG_NODE
, &debug_msdp_events_cmd
);
6167 install_element (CONFIG_NODE
, &no_debug_msdp_events_cmd
);
6168 install_element (CONFIG_NODE
, &undebug_msdp_events_cmd
);
6169 install_element (CONFIG_NODE
, &debug_msdp_packets_cmd
);
6170 install_element (CONFIG_NODE
, &no_debug_msdp_packets_cmd
);
6171 install_element (CONFIG_NODE
, &undebug_msdp_packets_cmd
);
6172 install_element (CONFIG_NODE
, &ip_msdp_mesh_group_member_cmd
);
6173 install_element (CONFIG_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
6174 install_element (CONFIG_NODE
, &ip_msdp_mesh_group_source_cmd
);
6175 install_element (CONFIG_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
6176 install_element (VIEW_NODE
, &show_ip_msdp_peer_detail_cmd
);
6177 install_element (VIEW_NODE
, &show_ip_msdp_sa_detail_cmd
);
6178 install_element (VIEW_NODE
, &show_ip_msdp_sa_sg_cmd
);
6179 install_element (VIEW_NODE
, &show_ip_msdp_mesh_group_cmd
);
6180 install_element (INTERFACE_NODE
, &interface_pim_use_source_cmd
);
6181 install_element (INTERFACE_NODE
, &interface_no_pim_use_source_cmd
);