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",
1172 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
, ch
->flags
));
1173 if (PIM_IF_FLAG_TEST_S_G_RPT(ch
->flags
))
1174 json_object_int_add(json_row
, "SGRpt", 1);
1176 json_object_object_get_ex(json_iface
, ch_grp_str
, &json_grp
);
1179 json_grp
= json_object_new_object();
1180 json_object_object_add(json_grp
, ch_src_str
, json_row
);
1181 json_object_object_add(json_iface
, ch_grp_str
, json_grp
);
1184 json_object_object_add(json_grp
, ch_src_str
, json_row
);
1186 vty_out(vty
, "%-9s %-15s %-15s %-15s %-6s %8s %-6s %5s%s",
1187 ch
->interface
->name
,
1191 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
, ch
->flags
),
1197 } /* scan interface channels */
1200 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
1201 json_object_free(json
);
1205 static void pim_show_neighbors_single(struct vty
*vty
, const char *neighbor
, u_char uj
)
1207 struct listnode
*node
;
1208 struct listnode
*neighnode
;
1209 struct interface
*ifp
;
1210 struct pim_interface
*pim_ifp
;
1211 struct pim_neighbor
*neigh
;
1213 int found_neighbor
= 0;
1214 int option_address_list
;
1215 int option_dr_priority
;
1216 int option_generation_id
;
1217 int option_holdtime
;
1218 int option_lan_prune_delay
;
1222 char neigh_src_str
[INET_ADDRSTRLEN
];
1224 json_object
*json
= NULL
;
1225 json_object
*json_ifp
= NULL
;
1226 json_object
*json_row
= NULL
;
1228 now
= pim_time_monotonic_sec();
1231 json
= json_object_new_object();
1233 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
)) {
1234 pim_ifp
= ifp
->info
;
1239 if (pim_ifp
->pim_sock_fd
< 0)
1242 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
, neigh
)) {
1243 pim_inet4_dump("<src?>", neigh
->source_addr
,
1244 neigh_src_str
, sizeof(neigh_src_str
));
1247 * The user can specify either the interface name or the PIM neighbor IP.
1248 * If this pim_ifp matches neither then skip.
1250 if (strcmp(neighbor
, "detail") &&
1251 strcmp(neighbor
, ifp
->name
) &&
1252 strcmp(neighbor
, neigh_src_str
))
1256 pim_time_uptime(uptime
, sizeof(uptime
), now
- neigh
->creation
);
1257 pim_time_timer_to_hhmmss(expire
, sizeof(expire
), neigh
->t_expire_timer
);
1259 option_address_list
= 0;
1260 option_dr_priority
= 0;
1261 option_generation_id
= 0;
1262 option_holdtime
= 0;
1263 option_lan_prune_delay
= 0;
1266 if (PIM_OPTION_IS_SET(neigh
->hello_options
, PIM_OPTION_MASK_ADDRESS_LIST
))
1267 option_address_list
= 1;
1269 if (PIM_OPTION_IS_SET(neigh
->hello_options
, PIM_OPTION_MASK_DR_PRIORITY
))
1270 option_dr_priority
= 1;
1272 if (PIM_OPTION_IS_SET(neigh
->hello_options
, PIM_OPTION_MASK_GENERATION_ID
))
1273 option_generation_id
= 1;
1275 if (PIM_OPTION_IS_SET(neigh
->hello_options
, PIM_OPTION_MASK_HOLDTIME
))
1276 option_holdtime
= 1;
1278 if (PIM_OPTION_IS_SET(neigh
->hello_options
, PIM_OPTION_MASK_LAN_PRUNE_DELAY
))
1279 option_lan_prune_delay
= 1;
1281 if (PIM_OPTION_IS_SET(neigh
->hello_options
, PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION
))
1286 /* Does this ifp live in json? If not create it. */
1287 json_object_object_get_ex(json
, ifp
->name
, &json_ifp
);
1290 json_ifp
= json_object_new_object();
1291 json_object_pim_ifp_add(json_ifp
, ifp
);
1292 json_object_object_add(json
, ifp
->name
, json_ifp
);
1295 json_row
= json_object_new_object();
1296 json_object_string_add(json_row
, "interface", ifp
->name
);
1297 json_object_string_add(json_row
, "address", neigh_src_str
);
1298 json_object_string_add(json_row
, "upTime", uptime
);
1299 json_object_string_add(json_row
, "holdtime", expire
);
1300 json_object_int_add(json_row
, "drPriority", neigh
->dr_priority
);
1301 json_object_int_add(json_row
, "generationId", neigh
->generation_id
);
1303 if (option_address_list
)
1304 json_object_boolean_true_add(json_row
, "helloOptionAddressList");
1306 if (option_dr_priority
)
1307 json_object_boolean_true_add(json_row
, "helloOptionDrPriority");
1309 if (option_generation_id
)
1310 json_object_boolean_true_add(json_row
, "helloOptionGenerationId");
1312 if (option_holdtime
)
1313 json_object_boolean_true_add(json_row
, "helloOptionHoldtime");
1315 if (option_lan_prune_delay
)
1316 json_object_boolean_true_add(json_row
, "helloOptionLanPruneDelay");
1319 json_object_boolean_true_add(json_row
, "helloOptionTBit");
1321 json_object_object_add(json_ifp
, neigh_src_str
, json_row
);
1324 vty_out(vty
, "Interface : %s%s", ifp
->name
, VTY_NEWLINE
);
1325 vty_out(vty
, "Neighbor : %s%s", neigh_src_str
, VTY_NEWLINE
);
1326 vty_out(vty
, " Uptime : %s%s", uptime
, VTY_NEWLINE
);
1327 vty_out(vty
, " Holdtime : %s%s", expire
, VTY_NEWLINE
);
1328 vty_out(vty
, " DR Priority : %d%s", neigh
->dr_priority
, VTY_NEWLINE
);
1329 vty_out(vty
, " Generation ID : %08x%s", neigh
->generation_id
, VTY_NEWLINE
);
1330 vty_out(vty
, " Override Interval (msec) : %d%s", neigh
->override_interval_msec
, VTY_NEWLINE
);
1331 vty_out(vty
, " Propagation Delay (msec) : %d%s", neigh
->propagation_delay_msec
, VTY_NEWLINE
);
1332 vty_out(vty
, " Hello Option - Address List : %s%s", option_address_list
? "yes" : "no", VTY_NEWLINE
);
1333 vty_out(vty
, " Hello Option - DR Priority : %s%s", option_dr_priority
? "yes" : "no", VTY_NEWLINE
);
1334 vty_out(vty
, " Hello Option - Generation ID : %s%s", option_generation_id
? "yes" : "no", VTY_NEWLINE
);
1335 vty_out(vty
, " Hello Option - Holdtime : %s%s", option_holdtime
? "yes" : "no", VTY_NEWLINE
);
1336 vty_out(vty
, " Hello Option - LAN Prune Delay : %s%s", option_lan_prune_delay
? "yes" : "no", VTY_NEWLINE
);
1337 vty_out(vty
, " Hello Option - T-bit : %s%s", option_t_bit
? "yes" : "no", VTY_NEWLINE
);
1338 vty_out(vty
, "%s", VTY_NEWLINE
);
1344 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
1345 json_object_free(json
);
1348 if (!found_neighbor
)
1349 vty_out (vty
, "%% No such interface or neighbor%s", VTY_NEWLINE
);
1355 pim_show_state(struct vty
*vty
, const char *src_or_group
, const char *group
, u_char uj
)
1357 struct channel_oil
*c_oil
;
1358 struct listnode
*node
;
1359 json_object
*json
= NULL
;
1360 json_object
*json_group
= NULL
;
1361 json_object
*json_ifp_in
= NULL
;
1362 json_object
*json_ifp_out
= NULL
;
1363 json_object
*json_source
= NULL
;
1366 now
= pim_time_monotonic_sec();
1369 json
= json_object_new_object();
1371 vty_out(vty
, "Codes: J -> Pim Join, I -> IGMP Report, S -> Source, * -> Inherited from (*,G)");
1372 vty_out(vty
, "%sInstalled Source Group IIF OIL%s", VTY_NEWLINE
, VTY_NEWLINE
);
1375 for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list
, node
, c_oil
)) {
1376 char grp_str
[INET_ADDRSTRLEN
];
1377 char src_str
[INET_ADDRSTRLEN
];
1378 char in_ifname
[INTERFACE_NAMSIZ
+1];
1379 char out_ifname
[INTERFACE_NAMSIZ
+1];
1381 struct interface
*ifp_in
;
1384 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
, sizeof(grp_str
));
1385 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
, sizeof(src_str
));
1386 ifp_in
= pim_if_find_by_vif_index(c_oil
->oil
.mfcc_parent
);
1389 strcpy(in_ifname
, ifp_in
->name
);
1391 strcpy(in_ifname
, "<iif?>");
1395 if (strcmp(src_or_group
, src_str
) && strcmp(src_or_group
, grp_str
))
1398 if (group
&& strcmp(group
, grp_str
))
1404 /* Find the group, create it if it doesn't exist */
1405 json_object_object_get_ex(json
, grp_str
, &json_group
);
1408 json_group
= json_object_new_object();
1409 json_object_object_add(json
, grp_str
, json_group
);
1412 /* Find the source nested under the group, create it if it doesn't exist */
1413 json_object_object_get_ex(json_group
, src_str
, &json_source
);
1416 json_source
= json_object_new_object();
1417 json_object_object_add(json_group
, src_str
, json_source
);
1420 /* Find the inbound interface nested under the source, create it if it doesn't exist */
1421 json_object_object_get_ex(json_source
, in_ifname
, &json_ifp_in
);
1424 json_ifp_in
= json_object_new_object();
1425 json_object_object_add(json_source
, in_ifname
, json_ifp_in
);
1426 json_object_int_add (json_source
, "Installed", c_oil
->installed
);
1427 json_object_int_add (json_source
, "RefCount", c_oil
->oil_ref_count
);
1428 json_object_int_add (json_source
, "OilListSize", c_oil
->oil_size
);
1429 json_object_int_add (json_source
, "OilRescan", c_oil
->oil_inherited_rescan
);
1430 json_object_int_add (json_source
, "LastUsed", c_oil
->cc
.lastused
);
1431 json_object_int_add (json_source
, "PacketCount", c_oil
->cc
.pktcnt
);
1432 json_object_int_add (json_source
, "ByteCount", c_oil
->cc
.bytecnt
);
1433 json_object_int_add (json_source
, "WrongInterface", c_oil
->cc
.wrong_if
);
1436 vty_out(vty
, "%-9d %-15s %-15s %-7s ",
1443 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
; ++oif_vif_index
) {
1444 struct interface
*ifp_out
;
1445 char oif_uptime
[10];
1448 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
1452 ifp_out
= pim_if_find_by_vif_index(oif_vif_index
);
1453 pim_time_uptime(oif_uptime
, sizeof(oif_uptime
), now
- c_oil
->oif_creation
[oif_vif_index
]);
1456 strcpy(out_ifname
, ifp_out
->name
);
1458 strcpy(out_ifname
, "<oif?>");
1461 json_ifp_out
= json_object_new_object();
1462 json_object_string_add(json_ifp_out
, "source", src_str
);
1463 json_object_string_add(json_ifp_out
, "group", grp_str
);
1464 json_object_string_add(json_ifp_out
, "inboundInterface", in_ifname
);
1465 json_object_string_add(json_ifp_out
, "outboundInterface", out_ifname
);
1466 json_object_int_add(json_ifp_out
, "installed", c_oil
->installed
);
1468 json_object_object_add(json_ifp_in
, out_ifname
, json_ifp_out
);
1473 vty_out(vty
, "%s(%c%c%c%c)", out_ifname
,
1474 (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_IGMP
) ? 'I' : ' ',
1475 (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_PIM
) ? 'J' : ' ',
1476 (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_SOURCE
) ? 'S' : ' ',
1477 (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_STAR
) ? '*' : ' ');
1480 vty_out(vty
, ", %s(%c%c%c%c)", out_ifname
,
1481 (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_IGMP
) ? 'I' : ' ',
1482 (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_PIM
) ? 'J' : ' ',
1483 (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_SOURCE
) ? 'S' : ' ',
1484 (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_STAR
) ? '*' : ' ' );
1489 vty_out(vty
, "%s", VTY_NEWLINE
);
1494 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
1495 json_object_free(json
);
1497 vty_out(vty
, "%s", VTY_NEWLINE
);
1501 static void pim_show_neighbors(struct vty
*vty
, u_char uj
)
1503 struct listnode
*node
;
1504 struct listnode
*neighnode
;
1505 struct interface
*ifp
;
1506 struct pim_interface
*pim_ifp
;
1507 struct pim_neighbor
*neigh
;
1511 char neigh_src_str
[INET_ADDRSTRLEN
];
1512 json_object
*json
= NULL
;
1513 json_object
*json_ifp_rows
= NULL
;
1514 json_object
*json_row
= NULL
;
1516 now
= pim_time_monotonic_sec();
1519 json
= json_object_new_object();
1521 vty_out(vty
, "Interface Neighbor Uptime Holdtime DR Pri%s", VTY_NEWLINE
);
1524 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
)) {
1525 pim_ifp
= ifp
->info
;
1530 if (pim_ifp
->pim_sock_fd
< 0)
1534 json_ifp_rows
= json_object_new_object();
1536 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
, neigh
)) {
1537 pim_inet4_dump("<src?>", neigh
->source_addr
,
1538 neigh_src_str
, sizeof(neigh_src_str
));
1539 pim_time_uptime(uptime
, sizeof(uptime
), now
- neigh
->creation
);
1540 pim_time_timer_to_hhmmss(expire
, sizeof(expire
), neigh
->t_expire_timer
);
1543 json_row
= json_object_new_object();
1544 json_object_string_add(json_row
, "interface", ifp
->name
);
1545 json_object_string_add(json_row
, "neighbor", neigh_src_str
);
1546 json_object_string_add(json_row
, "upTime", uptime
);
1547 json_object_string_add(json_row
, "holdTime", expire
);
1548 json_object_int_add(json_row
, "holdTimeMax", neigh
->holdtime
);
1549 json_object_int_add(json_row
, "drPriority", neigh
->dr_priority
);
1550 json_object_object_add(json_ifp_rows
, neigh_src_str
, json_row
);
1553 vty_out(vty
, "%-9s %15s %8s %8s %6d%s",
1564 json_object_object_add(json
, ifp
->name
, json_ifp_rows
);
1565 json_ifp_rows
= NULL
;
1570 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
1571 json_object_free(json
);
1575 static void pim_show_neighbors_secondary(struct vty
*vty
)
1577 struct listnode
*node
;
1578 struct interface
*ifp
;
1580 vty_out(vty
, "Interface Address Neighbor Secondary %s", VTY_NEWLINE
);
1582 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
)) {
1583 struct pim_interface
*pim_ifp
;
1584 struct in_addr ifaddr
;
1585 struct listnode
*neighnode
;
1586 struct pim_neighbor
*neigh
;
1588 pim_ifp
= ifp
->info
;
1593 if (pim_ifp
->pim_sock_fd
< 0)
1596 ifaddr
= pim_ifp
->primary_address
;
1598 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
, neigh
)) {
1599 char neigh_src_str
[INET_ADDRSTRLEN
];
1600 struct listnode
*prefix_node
;
1603 if (!neigh
->prefix_list
)
1606 pim_inet4_dump("<src?>", neigh
->source_addr
,
1607 neigh_src_str
, sizeof(neigh_src_str
));
1609 for (ALL_LIST_ELEMENTS_RO(neigh
->prefix_list
, prefix_node
, p
)) {
1610 char neigh_sec_str
[INET_ADDRSTRLEN
];
1612 if (p
->family
!= AF_INET
)
1615 pim_inet4_dump("<src?>", p
->u
.prefix4
,
1616 neigh_sec_str
, sizeof(neigh_sec_str
));
1618 vty_out(vty
, "%-9s %-15s %-15s %-15s%s",
1630 json_object_pim_upstream_add (json_object
*json
, struct pim_upstream
*up
)
1632 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED
)
1633 json_object_boolean_true_add(json
, "drJoinDesired");
1635 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED
)
1636 json_object_boolean_true_add(json
, "drJoinDesiredUpdated");
1638 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
1639 json_object_boolean_true_add(json
, "firstHopRouter");
1641 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_IGMP
)
1642 json_object_boolean_true_add(json
, "sourceIgmp");
1644 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_PIM
)
1645 json_object_boolean_true_add(json
, "sourcePim");
1647 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_STREAM
)
1648 json_object_boolean_true_add(json
, "sourceStream");
1650 /* XXX: need to print ths flag in the plain text display as well */
1651 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_MSDP
)
1652 json_object_boolean_true_add(json
, "sourceMsdp");
1656 pim_upstream_state2brief_str (enum pim_upstream_state join_state
, char *state_str
)
1660 case PIM_UPSTREAM_NOTJOINED
:
1661 strcpy (state_str
, "NotJ");
1663 case PIM_UPSTREAM_JOINED
:
1664 strcpy (state_str
, "J");
1667 strcpy (state_str
, "Unk");
1673 pim_reg_state2brief_str (enum pim_reg_state reg_state
, char *state_str
)
1677 case PIM_REG_NOINFO
:
1678 strcpy (state_str
, "RegNI");
1681 strcpy (state_str
, "RegJ");
1683 case PIM_REG_JOIN_PENDING
:
1685 strcpy (state_str
, "RegP");
1688 strcpy (state_str
, "Unk");
1693 static void pim_show_upstream(struct vty
*vty
, u_char uj
)
1695 struct listnode
*upnode
;
1696 struct pim_upstream
*up
;
1698 json_object
*json
= NULL
;
1699 json_object
*json_group
= NULL
;
1700 json_object
*json_row
= NULL
;
1702 now
= pim_time_monotonic_sec();
1705 json
= json_object_new_object();
1707 vty_out(vty
, "Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt%s", VTY_NEWLINE
);
1709 for (ALL_LIST_ELEMENTS_RO(pim_upstream_list
, upnode
, up
)) {
1710 char src_str
[INET_ADDRSTRLEN
];
1711 char grp_str
[INET_ADDRSTRLEN
];
1713 char join_timer
[10];
1716 char msdp_reg_timer
[10];
1717 char state_str
[PIM_REG_STATE_STR_LEN
];
1719 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
1720 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
1721 pim_time_uptime(uptime
, sizeof(uptime
), now
- up
->state_transition
);
1722 pim_time_timer_to_hhmmss (join_timer
, sizeof(join_timer
), up
->t_join_timer
);
1725 * If we have a J/P timer for the neighbor display that
1727 if (!up
->t_join_timer
)
1729 struct pim_neighbor
*nbr
;
1731 nbr
= pim_neighbor_find (up
->rpf
.source_nexthop
.interface
,
1732 up
->rpf
.rpf_addr
.u
.prefix4
);
1734 pim_time_timer_to_hhmmss (join_timer
, sizeof(join_timer
), nbr
->jp_timer
);
1737 pim_time_timer_to_hhmmss (rs_timer
, sizeof (rs_timer
), up
->t_rs_timer
);
1738 pim_time_timer_to_hhmmss (ka_timer
, sizeof (ka_timer
), up
->t_ka_timer
);
1739 pim_time_timer_to_hhmmss (msdp_reg_timer
, sizeof (msdp_reg_timer
), up
->t_msdp_reg_timer
);
1741 pim_upstream_state2brief_str (up
->join_state
, state_str
);
1742 if (up
->reg_state
!= PIM_REG_NOINFO
) {
1743 char tmp_str
[PIM_REG_STATE_STR_LEN
];
1745 sprintf (state_str
+ strlen (state_str
), ",%s",
1746 pim_reg_state2brief_str (up
->reg_state
, tmp_str
));
1750 json_object_object_get_ex(json
, grp_str
, &json_group
);
1753 json_group
= json_object_new_object();
1754 json_object_object_add(json
, grp_str
, json_group
);
1757 json_row
= json_object_new_object();
1758 json_object_pim_upstream_add(json_row
, up
);
1759 json_object_string_add(json_row
, "inboundInterface", up
->rpf
.source_nexthop
.interface
->name
);
1760 json_object_string_add(json_row
, "source", src_str
);
1761 json_object_string_add(json_row
, "group", grp_str
);
1762 json_object_string_add(json_row
, "state", state_str
);
1763 json_object_string_add(json_row
, "joinState", pim_upstream_state2str (up
->join_state
));
1764 json_object_string_add(json_row
, "regState", pim_reg_state2str (up
->reg_state
, state_str
));
1765 json_object_string_add(json_row
, "upTime", uptime
);
1766 json_object_string_add(json_row
, "joinTimer", join_timer
);
1767 json_object_string_add(json_row
, "resetTimer", rs_timer
);
1768 json_object_string_add(json_row
, "keepaliveTimer", ka_timer
);
1769 json_object_string_add(json_row
, "msdpRegTimer", msdp_reg_timer
);
1770 json_object_int_add(json_row
, "refCount", up
->ref_count
);
1771 json_object_int_add(json_row
, "sptBit", up
->sptbit
);
1772 json_object_object_add(json_group
, src_str
, json_row
);
1774 vty_out(vty
, "%-10s%-15s %-15s %-11s %-8s %-9s %-9s %-9s %6d%s",
1775 up
->rpf
.source_nexthop
.interface
->name
,
1789 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
1790 json_object_free(json
);
1794 static void pim_show_join_desired(struct vty
*vty
, u_char uj
)
1796 struct listnode
*chnode
;
1797 struct pim_interface
*pim_ifp
;
1798 struct pim_ifchannel
*ch
;
1799 char src_str
[INET_ADDRSTRLEN
];
1800 char grp_str
[INET_ADDRSTRLEN
];
1801 json_object
*json
= NULL
;
1802 json_object
*json_group
= NULL
;
1803 json_object
*json_row
= NULL
;
1806 json
= json_object_new_object();
1809 "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD%s",
1812 /* scan per-interface (S,G) state */
1813 for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list
, chnode
, ch
)) {
1814 /* scan all interfaces */
1815 pim_ifp
= ch
->interface
->info
;
1819 struct pim_upstream
*up
= ch
->upstream
;
1821 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
1822 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
1825 json_object_object_get_ex(json
, grp_str
, &json_group
);
1828 json_group
= json_object_new_object();
1829 json_object_object_add(json
, grp_str
, json_group
);
1832 json_row
= json_object_new_object();
1833 json_object_pim_upstream_add(json_row
, up
);
1834 json_object_string_add(json_row
, "interface", ch
->interface
->name
);
1835 json_object_string_add(json_row
, "source", src_str
);
1836 json_object_string_add(json_row
, "group", grp_str
);
1838 if (pim_macro_ch_lost_assert(ch
))
1839 json_object_boolean_true_add(json_row
, "lostAssert");
1841 if (pim_macro_chisin_joins(ch
))
1842 json_object_boolean_true_add(json_row
, "joins");
1844 if (pim_macro_chisin_pim_include(ch
))
1845 json_object_boolean_true_add(json_row
, "pimInclude");
1847 if (pim_upstream_evaluate_join_desired(up
))
1848 json_object_boolean_true_add(json_row
, "evaluateJoinDesired");
1850 json_object_object_add(json_group
, src_str
, json_row
);
1853 vty_out(vty
, "%-9s %-15s %-15s %-10s %-5s %-10s %-11s %-6s%s",
1854 ch
->interface
->name
,
1857 pim_macro_ch_lost_assert(ch
) ? "yes" : "no",
1858 pim_macro_chisin_joins(ch
) ? "yes" : "no",
1859 pim_macro_chisin_pim_include(ch
) ? "yes" : "no",
1860 PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(up
->flags
) ? "yes" : "no",
1861 pim_upstream_evaluate_join_desired(up
) ? "yes" : "no",
1867 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
1868 json_object_free(json
);
1872 static void pim_show_upstream_rpf(struct vty
*vty
, u_char uj
)
1874 struct listnode
*upnode
;
1875 struct pim_upstream
*up
;
1876 json_object
*json
= NULL
;
1877 json_object
*json_group
= NULL
;
1878 json_object
*json_row
= NULL
;
1881 json
= json_object_new_object();
1884 "Source Group RpfIface RibNextHop RpfAddress %s",
1887 for (ALL_LIST_ELEMENTS_RO(pim_upstream_list
, upnode
, up
)) {
1888 char src_str
[INET_ADDRSTRLEN
];
1889 char grp_str
[INET_ADDRSTRLEN
];
1890 char rpf_nexthop_str
[PREFIX_STRLEN
];
1891 char rpf_addr_str
[PREFIX_STRLEN
];
1892 struct pim_rpf
*rpf
;
1893 const char *rpf_ifname
;
1897 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
1898 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
1899 pim_addr_dump("<nexthop?>", &rpf
->source_nexthop
.mrib_nexthop_addr
, rpf_nexthop_str
, sizeof(rpf_nexthop_str
));
1900 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
, sizeof(rpf_addr_str
));
1902 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
1905 json_object_object_get_ex(json
, grp_str
, &json_group
);
1908 json_group
= json_object_new_object();
1909 json_object_object_add(json
, grp_str
, json_group
);
1912 json_row
= json_object_new_object();
1913 json_object_pim_upstream_add(json_row
, up
);
1914 json_object_string_add(json_row
, "source", src_str
);
1915 json_object_string_add(json_row
, "group", grp_str
);
1916 json_object_string_add(json_row
, "rpfInterface", rpf_ifname
);
1917 json_object_string_add(json_row
, "ribNexthop", rpf_nexthop_str
);
1918 json_object_string_add(json_row
, "rpfAddress", rpf_addr_str
);
1919 json_object_object_add(json_group
, src_str
, json_row
);
1921 vty_out(vty
, "%-15s %-15s %-8s %-15s %-15s%s",
1932 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
1933 json_object_free(json
);
1937 static void show_rpf_refresh_stats(struct vty
*vty
, time_t now
, json_object
*json
)
1939 char refresh_uptime
[10];
1941 pim_time_uptime_begin(refresh_uptime
, sizeof(refresh_uptime
), now
, qpim_rpf_cache_refresh_last
);
1944 json_object_int_add(json
, "rpfCacheRefreshDelayMsecs", qpim_rpf_cache_refresh_delay_msec
);
1945 json_object_int_add(json
, "rpfCacheRefreshTimer", pim_time_timer_remain_msec(qpim_rpf_cache_refresher
));
1946 json_object_int_add(json
, "rpfCacheRefreshRequests", qpim_rpf_cache_refresh_requests
);
1947 json_object_int_add(json
, "rpfCacheRefreshEvents", qpim_rpf_cache_refresh_events
);
1948 json_object_string_add(json
, "rpfCacheRefreshLast", refresh_uptime
);
1949 json_object_int_add(json
, "nexthopLookups", qpim_nexthop_lookups
);
1950 json_object_int_add(json
, "nexthopLookupsAvoided", nexthop_lookups_avoided
);
1953 "RPF Cache Refresh Delay: %ld msecs%s"
1954 "RPF Cache Refresh Timer: %ld msecs%s"
1955 "RPF Cache Refresh Requests: %lld%s"
1956 "RPF Cache Refresh Events: %lld%s"
1957 "RPF Cache Refresh Last: %s%s"
1958 "Nexthop Lookups: %lld%s"
1959 "Nexthop Lookups Avoided: %lld%s",
1960 qpim_rpf_cache_refresh_delay_msec
, VTY_NEWLINE
,
1961 pim_time_timer_remain_msec(qpim_rpf_cache_refresher
), VTY_NEWLINE
,
1962 (long long)qpim_rpf_cache_refresh_requests
, VTY_NEWLINE
,
1963 (long long)qpim_rpf_cache_refresh_events
, VTY_NEWLINE
,
1964 refresh_uptime
, VTY_NEWLINE
,
1965 (long long) qpim_nexthop_lookups
, VTY_NEWLINE
,
1966 (long long)nexthop_lookups_avoided
, VTY_NEWLINE
);
1970 static void show_scan_oil_stats(struct vty
*vty
, time_t now
)
1972 char uptime_scan_oil
[10];
1973 char uptime_mroute_add
[10];
1974 char uptime_mroute_del
[10];
1976 pim_time_uptime_begin(uptime_scan_oil
, sizeof(uptime_scan_oil
), now
, qpim_scan_oil_last
);
1977 pim_time_uptime_begin(uptime_mroute_add
, sizeof(uptime_mroute_add
), now
, qpim_mroute_add_last
);
1978 pim_time_uptime_begin(uptime_mroute_del
, sizeof(uptime_mroute_del
), now
, qpim_mroute_del_last
);
1981 "Scan OIL - Last: %s Events: %lld%s"
1982 "MFC Add - Last: %s Events: %lld%s"
1983 "MFC Del - Last: %s Events: %lld%s",
1984 uptime_scan_oil
, (long long) qpim_scan_oil_events
, VTY_NEWLINE
,
1985 uptime_mroute_add
, (long long) qpim_mroute_add_events
, VTY_NEWLINE
,
1986 uptime_mroute_del
, (long long) qpim_mroute_del_events
, VTY_NEWLINE
);
1989 static void pim_show_rpf(struct vty
*vty
, u_char uj
)
1991 struct listnode
*up_node
;
1992 struct pim_upstream
*up
;
1993 time_t now
= pim_time_monotonic_sec();
1994 json_object
*json
= NULL
;
1995 json_object
*json_group
= NULL
;
1996 json_object
*json_row
= NULL
;
1999 json
= json_object_new_object();
2000 show_rpf_refresh_stats(vty
, now
, json
);
2002 show_rpf_refresh_stats(vty
, now
, json
);
2003 vty_out(vty
, "%s", VTY_NEWLINE
);
2005 "Source Group RpfIface RpfAddress RibNextHop Metric Pref%s",
2009 for (ALL_LIST_ELEMENTS_RO(pim_upstream_list
, up_node
, up
)) {
2010 char src_str
[INET_ADDRSTRLEN
];
2011 char grp_str
[INET_ADDRSTRLEN
];
2012 char rpf_addr_str
[PREFIX_STRLEN
];
2013 char rib_nexthop_str
[PREFIX_STRLEN
];
2014 const char *rpf_ifname
;
2015 struct pim_rpf
*rpf
= &up
->rpf
;
2017 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2018 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2019 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
, sizeof(rpf_addr_str
));
2020 pim_addr_dump("<nexthop?>", &rpf
->source_nexthop
.mrib_nexthop_addr
, rib_nexthop_str
, sizeof(rib_nexthop_str
));
2022 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2025 json_object_object_get_ex(json
, grp_str
, &json_group
);
2028 json_group
= json_object_new_object();
2029 json_object_object_add(json
, grp_str
, json_group
);
2032 json_row
= json_object_new_object();
2033 json_object_string_add(json_row
, "source", src_str
);
2034 json_object_string_add(json_row
, "group", grp_str
);
2035 json_object_string_add(json_row
, "rpfInterface", rpf_ifname
);
2036 json_object_string_add(json_row
, "rpfAddress", rpf_addr_str
);
2037 json_object_string_add(json_row
, "ribNexthop", rib_nexthop_str
);
2038 json_object_int_add(json_row
, "routeMetric", rpf
->source_nexthop
.mrib_route_metric
);
2039 json_object_int_add(json_row
, "routePreference", rpf
->source_nexthop
.mrib_metric_preference
);
2040 json_object_object_add(json_group
, src_str
, json_row
);
2043 vty_out(vty
, "%-15s %-15s %-8s %-15s %-15s %6d %4d%s",
2049 rpf
->source_nexthop
.mrib_route_metric
,
2050 rpf
->source_nexthop
.mrib_metric_preference
,
2056 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
2057 json_object_free(json
);
2061 static void igmp_show_groups(struct vty
*vty
, u_char uj
)
2063 struct listnode
*ifnode
;
2064 struct interface
*ifp
;
2066 json_object
*json
= NULL
;
2067 json_object
*json_iface
= NULL
;
2068 json_object
*json_row
= NULL
;
2070 now
= pim_time_monotonic_sec();
2073 json
= json_object_new_object();
2075 vty_out(vty
, "Interface Address Group Mode Timer Srcs V Uptime %s", VTY_NEWLINE
);
2077 /* scan interfaces */
2078 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), ifnode
, ifp
)) {
2079 struct pim_interface
*pim_ifp
= ifp
->info
;
2080 struct listnode
*sock_node
;
2081 struct igmp_sock
*igmp
;
2086 /* scan igmp sockets */
2087 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
2088 char ifaddr_str
[INET_ADDRSTRLEN
];
2089 struct listnode
*grpnode
;
2090 struct igmp_group
*grp
;
2092 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
, sizeof(ifaddr_str
));
2094 /* scan igmp groups */
2095 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grpnode
, grp
)) {
2096 char group_str
[INET_ADDRSTRLEN
];
2100 pim_inet4_dump("<group?>", grp
->group_addr
, group_str
, sizeof(group_str
));
2101 pim_time_timer_to_hhmmss(hhmmss
, sizeof(hhmmss
), grp
->t_group_timer
);
2102 pim_time_uptime(uptime
, sizeof(uptime
), now
- grp
->group_creation
);
2105 json_object_object_get_ex(json
, ifp
->name
, &json_iface
);
2108 json_iface
= json_object_new_object();
2109 json_object_pim_ifp_add(json_iface
, ifp
);
2110 json_object_object_add(json
, ifp
->name
, json_iface
);
2113 json_row
= json_object_new_object();
2114 json_object_string_add(json_row
, "source", ifaddr_str
);
2115 json_object_string_add(json_row
, "group", group_str
);
2117 if (grp
->igmp_version
== 3)
2118 json_object_string_add(json_row
, "mode", grp
->group_filtermode_isexcl
? "EXCLUDE" : "INCLUDE");
2120 json_object_string_add(json_row
, "timer", hhmmss
);
2121 json_object_int_add(json_row
, "sourcesCount", grp
->group_source_list
? listcount(grp
->group_source_list
) : 0);
2122 json_object_int_add(json_row
, "version", grp
->igmp_version
);
2123 json_object_string_add(json_row
, "uptime", uptime
);
2124 json_object_object_add(json_iface
, group_str
, json_row
);
2127 vty_out(vty
, "%-9s %-15s %-15s %4s %8s %4d %d %8s%s",
2131 grp
->igmp_version
== 3 ? (grp
->group_filtermode_isexcl
? "EXCL" : "INCL") : "----",
2133 grp
->group_source_list
? listcount(grp
->group_source_list
) : 0,
2138 } /* scan igmp groups */
2139 } /* scan igmp sockets */
2140 } /* scan interfaces */
2143 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
2144 json_object_free(json
);
2148 static void igmp_show_group_retransmission(struct vty
*vty
)
2150 struct listnode
*ifnode
;
2151 struct interface
*ifp
;
2153 vty_out(vty
, "Interface Address Group RetTimer Counter RetSrcs%s", VTY_NEWLINE
);
2155 /* scan interfaces */
2156 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), ifnode
, ifp
)) {
2157 struct pim_interface
*pim_ifp
= ifp
->info
;
2158 struct listnode
*sock_node
;
2159 struct igmp_sock
*igmp
;
2164 /* scan igmp sockets */
2165 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
2166 char ifaddr_str
[INET_ADDRSTRLEN
];
2167 struct listnode
*grpnode
;
2168 struct igmp_group
*grp
;
2170 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
, sizeof(ifaddr_str
));
2172 /* scan igmp groups */
2173 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grpnode
, grp
)) {
2174 char group_str
[INET_ADDRSTRLEN
];
2175 char grp_retr_mmss
[10];
2176 struct listnode
*src_node
;
2177 struct igmp_source
*src
;
2178 int grp_retr_sources
= 0;
2180 pim_inet4_dump("<group?>", grp
->group_addr
, group_str
, sizeof(group_str
));
2181 pim_time_timer_to_mmss(grp_retr_mmss
, sizeof(grp_retr_mmss
), grp
->t_group_query_retransmit_timer
);
2184 /* count group sources with retransmission state */
2185 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
, src_node
, src
)) {
2186 if (src
->source_query_retransmit_count
> 0) {
2191 vty_out(vty
, "%-9s %-15s %-15s %-8s %7d %7d%s",
2196 grp
->group_specific_query_retransmit_count
,
2200 } /* scan igmp groups */
2201 } /* scan igmp sockets */
2202 } /* scan interfaces */
2205 static void igmp_show_sources(struct vty
*vty
)
2207 struct listnode
*ifnode
;
2208 struct interface
*ifp
;
2211 now
= pim_time_monotonic_sec();
2213 vty_out(vty
, "Interface Address Group Source Timer Fwd Uptime %s", VTY_NEWLINE
);
2215 /* scan interfaces */
2216 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), ifnode
, ifp
)) {
2217 struct pim_interface
*pim_ifp
= ifp
->info
;
2218 struct listnode
*sock_node
;
2219 struct igmp_sock
*igmp
;
2224 /* scan igmp sockets */
2225 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
2226 char ifaddr_str
[INET_ADDRSTRLEN
];
2227 struct listnode
*grpnode
;
2228 struct igmp_group
*grp
;
2230 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
, sizeof(ifaddr_str
));
2232 /* scan igmp groups */
2233 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grpnode
, grp
)) {
2234 char group_str
[INET_ADDRSTRLEN
];
2235 struct listnode
*srcnode
;
2236 struct igmp_source
*src
;
2238 pim_inet4_dump("<group?>", grp
->group_addr
, group_str
, sizeof(group_str
));
2240 /* scan group sources */
2241 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
, srcnode
, src
)) {
2242 char source_str
[INET_ADDRSTRLEN
];
2246 pim_inet4_dump("<source?>", src
->source_addr
, source_str
, sizeof(source_str
));
2248 pim_time_timer_to_mmss(mmss
, sizeof(mmss
), src
->t_source_timer
);
2250 pim_time_uptime(uptime
, sizeof(uptime
), now
- src
->source_creation
);
2252 vty_out(vty
, "%-9s %-15s %-15s %-15s %5s %3s %8s%s",
2258 IGMP_SOURCE_TEST_FORWARDING(src
->source_flags
) ? "Y" : "N",
2262 } /* scan group sources */
2263 } /* scan igmp groups */
2264 } /* scan igmp sockets */
2265 } /* scan interfaces */
2268 static void igmp_show_source_retransmission(struct vty
*vty
)
2270 struct listnode
*ifnode
;
2271 struct interface
*ifp
;
2273 vty_out(vty
, "Interface Address Group Source Counter%s", VTY_NEWLINE
);
2275 /* scan interfaces */
2276 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), ifnode
, ifp
)) {
2277 struct pim_interface
*pim_ifp
= ifp
->info
;
2278 struct listnode
*sock_node
;
2279 struct igmp_sock
*igmp
;
2284 /* scan igmp sockets */
2285 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
2286 char ifaddr_str
[INET_ADDRSTRLEN
];
2287 struct listnode
*grpnode
;
2288 struct igmp_group
*grp
;
2290 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
, sizeof(ifaddr_str
));
2292 /* scan igmp groups */
2293 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grpnode
, grp
)) {
2294 char group_str
[INET_ADDRSTRLEN
];
2295 struct listnode
*srcnode
;
2296 struct igmp_source
*src
;
2298 pim_inet4_dump("<group?>", grp
->group_addr
, group_str
, sizeof(group_str
));
2300 /* scan group sources */
2301 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
, srcnode
, src
)) {
2302 char source_str
[INET_ADDRSTRLEN
];
2304 pim_inet4_dump("<source?>", src
->source_addr
, source_str
, sizeof(source_str
));
2306 vty_out(vty
, "%-9s %-15s %-15s %-15s %7d%s",
2311 src
->source_query_retransmit_count
,
2314 } /* scan group sources */
2315 } /* scan igmp groups */
2316 } /* scan igmp sockets */
2317 } /* scan interfaces */
2320 static void clear_igmp_interfaces()
2322 struct listnode
*ifnode
;
2323 struct listnode
*ifnextnode
;
2324 struct interface
*ifp
;
2326 for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT
), ifnode
, ifnextnode
, ifp
)) {
2327 pim_if_addr_del_all_igmp(ifp
);
2330 for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT
), ifnode
, ifnextnode
, ifp
)) {
2331 pim_if_addr_add_all(ifp
);
2335 static void clear_pim_interfaces()
2337 struct listnode
*ifnode
;
2338 struct listnode
*ifnextnode
;
2339 struct interface
*ifp
;
2341 for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT
), ifnode
, ifnextnode
, ifp
)) {
2343 pim_neighbor_delete_all(ifp
, "interface cleared");
2348 static void clear_interfaces()
2350 clear_igmp_interfaces();
2351 clear_pim_interfaces();
2354 DEFUN (clear_ip_interfaces
,
2355 clear_ip_interfaces_cmd
,
2356 "clear ip interfaces",
2359 "Reset interfaces\n")
2366 DEFUN (clear_ip_igmp_interfaces
,
2367 clear_ip_igmp_interfaces_cmd
,
2368 "clear ip igmp interfaces",
2372 "Reset IGMP interfaces\n")
2374 clear_igmp_interfaces();
2379 static void mroute_add_all()
2381 struct listnode
*node
;
2382 struct channel_oil
*c_oil
;
2384 for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list
, node
, c_oil
)) {
2385 if (pim_mroute_add(c_oil
, __PRETTY_FUNCTION__
)) {
2386 /* just log warning */
2387 char source_str
[INET_ADDRSTRLEN
];
2388 char group_str
[INET_ADDRSTRLEN
];
2389 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, source_str
, sizeof(source_str
));
2390 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, group_str
, sizeof(group_str
));
2391 zlog_warn("%s %s: (S,G)=(%s,%s) failure writing MFC",
2392 __FILE__
, __PRETTY_FUNCTION__
,
2393 source_str
, group_str
);
2398 static void mroute_del_all()
2400 struct listnode
*node
;
2401 struct channel_oil
*c_oil
;
2403 for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list
, node
, c_oil
)) {
2404 if (pim_mroute_del(c_oil
, __PRETTY_FUNCTION__
)) {
2405 /* just log warning */
2406 char source_str
[INET_ADDRSTRLEN
];
2407 char group_str
[INET_ADDRSTRLEN
];
2408 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, source_str
, sizeof(source_str
));
2409 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, group_str
, sizeof(group_str
));
2410 zlog_warn("%s %s: (S,G)=(%s,%s) failure clearing MFC",
2411 __FILE__
, __PRETTY_FUNCTION__
,
2412 source_str
, group_str
);
2417 DEFUN (clear_ip_mroute
,
2418 clear_ip_mroute_cmd
,
2422 "Reset multicast routes\n")
2430 DEFUN (clear_ip_pim_interfaces
,
2431 clear_ip_pim_interfaces_cmd
,
2432 "clear ip pim interfaces",
2436 "Reset PIM interfaces\n")
2438 clear_pim_interfaces();
2443 DEFUN (clear_ip_pim_oil
,
2444 clear_ip_pim_oil_cmd
,
2449 "Rescan PIM OIL (output interface list)\n")
2456 DEFUN (show_ip_igmp_interface
,
2457 show_ip_igmp_interface_cmd
,
2458 "show ip igmp interface [detail|WORD] [json]",
2462 "IGMP interface information\n"
2465 "JavaScript Object Notation\n")
2467 u_char uj
= use_json(argc
, argv
);
2470 if (argv_find(argv
, argc
, "detail", &idx
) ||
2471 argv_find(argv
, argc
, "WORD", &idx
))
2472 igmp_show_interfaces_single(vty
, argv
[idx
]->arg
, uj
);
2474 igmp_show_interfaces(vty
, uj
);
2479 DEFUN (show_ip_igmp_join
,
2480 show_ip_igmp_join_cmd
,
2481 "show ip igmp join",
2485 "IGMP static join information\n")
2487 igmp_show_interface_join(vty
);
2492 DEFUN (show_ip_igmp_groups
,
2493 show_ip_igmp_groups_cmd
,
2494 "show ip igmp groups [json]",
2499 "JavaScript Object Notation\n")
2501 u_char uj
= use_json(argc
, argv
);
2502 igmp_show_groups(vty
, uj
);
2507 DEFUN (show_ip_igmp_groups_retransmissions
,
2508 show_ip_igmp_groups_retransmissions_cmd
,
2509 "show ip igmp groups retransmissions",
2514 "IGMP group retransmissions\n")
2516 igmp_show_group_retransmission(vty
);
2521 DEFUN (show_ip_igmp_sources
,
2522 show_ip_igmp_sources_cmd
,
2523 "show ip igmp sources",
2529 igmp_show_sources(vty
);
2534 DEFUN (show_ip_igmp_sources_retransmissions
,
2535 show_ip_igmp_sources_retransmissions_cmd
,
2536 "show ip igmp sources retransmissions",
2541 "IGMP source retransmissions\n")
2543 igmp_show_source_retransmission(vty
);
2548 DEFUN (show_ip_pim_assert
,
2549 show_ip_pim_assert_cmd
,
2550 "show ip pim assert",
2554 "PIM interface assert\n")
2556 pim_show_assert(vty
);
2561 DEFUN (show_ip_pim_assert_internal
,
2562 show_ip_pim_assert_internal_cmd
,
2563 "show ip pim assert-internal",
2567 "PIM interface internal assert state\n")
2569 pim_show_assert_internal(vty
);
2574 DEFUN (show_ip_pim_assert_metric
,
2575 show_ip_pim_assert_metric_cmd
,
2576 "show ip pim assert-metric",
2580 "PIM interface assert metric\n")
2582 pim_show_assert_metric(vty
);
2587 DEFUN (show_ip_pim_assert_winner_metric
,
2588 show_ip_pim_assert_winner_metric_cmd
,
2589 "show ip pim assert-winner-metric",
2593 "PIM interface assert winner metric\n")
2595 pim_show_assert_winner_metric(vty
);
2600 DEFUN (show_ip_pim_interface
,
2601 show_ip_pim_interface_cmd
,
2602 "show ip pim interface [detail|WORD] [json]",
2606 "PIM interface information\n"
2609 "JavaScript Object Notation\n")
2611 u_char uj
= use_json(argc
, argv
);
2614 if (argv_find(argv
, argc
, "WORD", &idx
) ||
2615 argv_find(argv
, argc
, "detail", &idx
))
2616 pim_show_interfaces_single(vty
, argv
[idx
]->arg
, uj
);
2619 pim_show_interfaces(vty
, uj
);
2624 DEFUN (show_ip_pim_join
,
2625 show_ip_pim_join_cmd
,
2626 "show ip pim join [json]",
2630 "PIM interface join information\n"
2633 u_char uj
= use_json(argc
, argv
);
2634 pim_show_join(vty
, uj
);
2639 DEFUN (show_ip_pim_local_membership
,
2640 show_ip_pim_local_membership_cmd
,
2641 "show ip pim local-membership [json]",
2645 "PIM interface local-membership\n"
2648 u_char uj
= use_json(argc
, argv
);
2649 pim_show_membership(vty
, uj
);
2654 DEFUN (show_ip_pim_neighbor
,
2655 show_ip_pim_neighbor_cmd
,
2656 "show ip pim neighbor [detail|WORD] [json]",
2660 "PIM neighbor information\n"
2662 "Name of interface or neighbor\n"
2663 "JavaScript Object Notation\n")
2665 u_char uj
= use_json(argc
, argv
);
2668 if (argv_find(argv
, argc
, "detail", &idx
) ||
2669 argv_find(argv
, argc
, "WORD", &idx
))
2670 pim_show_neighbors_single(vty
, argv
[idx
]->arg
, uj
);
2672 pim_show_neighbors(vty
, uj
);
2677 DEFUN (show_ip_pim_secondary
,
2678 show_ip_pim_secondary_cmd
,
2679 "show ip pim secondary",
2683 "PIM neighbor addresses\n")
2685 pim_show_neighbors_secondary(vty
);
2690 DEFUN (show_ip_pim_state
,
2691 show_ip_pim_state_cmd
,
2692 "show ip pim state [A.B.C.D [A.B.C.D]] [json]",
2696 "PIM state information\n"
2697 "Unicast or Multicast address\n"
2698 "Multicast address\n"
2699 "JavaScript Object Notation\n")
2701 const char *src_or_group
= NULL
;
2702 const char *group
= NULL
;
2703 u_char uj
= use_json(argc
, argv
);
2709 src_or_group
= argv
[4]->arg
;
2710 group
= argv
[5]->arg
;
2713 src_or_group
= argv
[4]->arg
;
2715 pim_show_state(vty
, src_or_group
, group
, uj
);
2720 DEFUN (show_ip_pim_upstream
,
2721 show_ip_pim_upstream_cmd
,
2722 "show ip pim upstream [json]",
2726 "PIM upstream information\n"
2727 "JavaScript Object Notation\n")
2729 u_char uj
= use_json(argc
, argv
);
2730 pim_show_upstream(vty
, uj
);
2735 DEFUN (show_ip_pim_upstream_join_desired
,
2736 show_ip_pim_upstream_join_desired_cmd
,
2737 "show ip pim upstream-join-desired [json]",
2741 "PIM upstream join-desired\n"
2742 "JavaScript Object Notation\n")
2744 u_char uj
= use_json(argc
, argv
);
2745 pim_show_join_desired(vty
, uj
);
2750 DEFUN (show_ip_pim_upstream_rpf
,
2751 show_ip_pim_upstream_rpf_cmd
,
2752 "show ip pim upstream-rpf [json]",
2756 "PIM upstream source rpf\n"
2757 "JavaScript Object Notation\n")
2759 u_char uj
= use_json(argc
, argv
);
2760 pim_show_upstream_rpf(vty
, uj
);
2765 DEFUN (show_ip_pim_rp
,
2767 "show ip pim rp-info [json]",
2771 "PIM RP information\n"
2772 "JavaScript Object Notation\n")
2774 u_char uj
= use_json(argc
, argv
);
2775 pim_rp_show_information (vty
, uj
);
2780 DEFUN (show_ip_pim_rpf
,
2781 show_ip_pim_rpf_cmd
,
2782 "show ip pim rpf [json]",
2786 "PIM cached source rpf information\n"
2787 "JavaScript Object Notation\n")
2789 u_char uj
= use_json(argc
, argv
);
2790 pim_show_rpf(vty
, uj
);
2795 static void show_multicast_interfaces(struct vty
*vty
)
2797 struct listnode
*node
;
2798 struct interface
*ifp
;
2800 vty_out(vty
, "%s", VTY_NEWLINE
);
2802 vty_out(vty
, "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut%s",
2805 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
)) {
2806 struct pim_interface
*pim_ifp
;
2807 struct in_addr ifaddr
;
2808 struct sioc_vif_req vreq
;
2810 pim_ifp
= ifp
->info
;
2815 memset(&vreq
, 0, sizeof(vreq
));
2816 vreq
.vifi
= pim_ifp
->mroute_vif_index
;
2818 if (ioctl(qpim_mroute_socket_fd
, SIOCGETVIFCNT
, &vreq
)) {
2819 zlog_warn("ioctl(SIOCGETVIFCNT=%lu) failure for interface %s vif_index=%d: errno=%d: %s%s",
2820 (unsigned long)SIOCGETVIFCNT
,
2822 pim_ifp
->mroute_vif_index
,
2824 safe_strerror(errno
),
2828 ifaddr
= pim_ifp
->primary_address
;
2830 vty_out(vty
, "%-9s %-15s %3d %3d %7lu %7lu %10lu %10lu%s",
2834 pim_ifp
->mroute_vif_index
,
2835 (unsigned long) vreq
.icount
,
2836 (unsigned long) vreq
.ocount
,
2837 (unsigned long) vreq
.ibytes
,
2838 (unsigned long) vreq
.obytes
,
2843 DEFUN (show_ip_multicast
,
2844 show_ip_multicast_cmd
,
2845 "show ip multicast",
2848 "Multicast global information\n")
2850 time_t now
= pim_time_monotonic_sec();
2854 vty_out(vty
, "Mroute socket descriptor: %d%s",
2855 qpim_mroute_socket_fd
,
2858 pim_time_uptime(uptime
, sizeof(uptime
), now
- qpim_mroute_socket_creation
);
2859 vty_out(vty
, "Mroute socket uptime: %s%s",
2863 vty_out(vty
, "%s", VTY_NEWLINE
);
2865 pim_zebra_zclient_update (vty
);
2866 pim_zlookup_show_ip_multicast (vty
);
2868 vty_out(vty
, "%s", VTY_NEWLINE
);
2869 vty_out(vty
, "Maximum highest VifIndex: %d%s",
2870 PIM_MAX_USABLE_VIFS
,
2873 vty_out(vty
, "%s", VTY_NEWLINE
);
2874 vty_out(vty
, "Upstream Join Timer: %d secs%s",
2877 vty_out(vty
, "Join/Prune Holdtime: %d secs%s",
2881 vty_out(vty
, "%s", VTY_NEWLINE
);
2883 show_rpf_refresh_stats(vty
, now
, NULL
);
2885 vty_out(vty
, "%s", VTY_NEWLINE
);
2887 show_scan_oil_stats(vty
, now
);
2889 show_multicast_interfaces(vty
);
2894 static void show_mroute(struct vty
*vty
, u_char uj
)
2896 struct listnode
*node
;
2897 struct channel_oil
*c_oil
;
2898 struct static_route
*s_route
;
2900 json_object
*json
= NULL
;
2901 json_object
*json_group
= NULL
;
2902 json_object
*json_source
= NULL
;
2903 json_object
*json_oil
= NULL
;
2904 json_object
*json_ifp_out
= NULL
;
2907 char grp_str
[INET_ADDRSTRLEN
];
2908 char src_str
[INET_ADDRSTRLEN
];
2909 char in_ifname
[INTERFACE_NAMSIZ
+1];
2910 char out_ifname
[INTERFACE_NAMSIZ
+1];
2912 struct interface
*ifp_in
;
2916 json
= json_object_new_object();
2918 vty_out(vty
, "Source Group Proto Input Output TTL Uptime%s",
2922 now
= pim_time_monotonic_sec();
2924 /* print list of PIM and IGMP routes */
2925 for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list
, node
, c_oil
)) {
2928 if (!c_oil
->installed
&& !uj
)
2931 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
, sizeof(grp_str
));
2932 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
, sizeof(src_str
));
2933 ifp_in
= pim_if_find_by_vif_index(c_oil
->oil
.mfcc_parent
);
2936 strcpy(in_ifname
, ifp_in
->name
);
2938 strcpy(in_ifname
, "<iif?>");
2942 /* Find the group, create it if it doesn't exist */
2943 json_object_object_get_ex(json
, grp_str
, &json_group
);
2946 json_group
= json_object_new_object();
2947 json_object_object_add(json
, grp_str
, json_group
);
2950 /* Find the source nested under the group, create it if it doesn't exist */
2951 json_object_object_get_ex(json_group
, src_str
, &json_source
);
2954 json_source
= json_object_new_object();
2955 json_object_object_add(json_group
, src_str
, json_source
);
2958 /* Find the inbound interface nested under the source, create it if it doesn't exist */
2959 json_object_int_add(json_source
, "installed", c_oil
->installed
);
2960 json_object_int_add(json_source
, "refCount", c_oil
->oil_ref_count
);
2961 json_object_int_add(json_source
, "oilSize", c_oil
->oil_size
);
2962 json_object_int_add(json_source
, "OilInheritedRescan", c_oil
->oil_inherited_rescan
);
2963 json_object_string_add(json_source
, "iif", in_ifname
);
2967 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
; ++oif_vif_index
) {
2968 struct interface
*ifp_out
;
2969 char oif_uptime
[10];
2972 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
2976 ifp_out
= pim_if_find_by_vif_index(oif_vif_index
);
2977 pim_time_uptime(oif_uptime
, sizeof(oif_uptime
), now
- c_oil
->oif_creation
[oif_vif_index
]);
2981 strcpy(out_ifname
, ifp_out
->name
);
2983 strcpy(out_ifname
, "<oif?>");
2986 json_ifp_out
= json_object_new_object();
2987 json_object_string_add(json_ifp_out
, "source", src_str
);
2988 json_object_string_add(json_ifp_out
, "group", grp_str
);
2990 if (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_PIM
)
2991 json_object_boolean_true_add(json_ifp_out
, "protocolPim");
2993 if (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_IGMP
)
2994 json_object_boolean_true_add(json_ifp_out
, "protocolIgmp");
2996 if (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_SOURCE
)
2997 json_object_boolean_true_add(json_ifp_out
, "protocolSource");
2999 if (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_STAR
)
3000 json_object_boolean_true_add(json_ifp_out
, "protocolInherited");
3002 json_object_string_add(json_ifp_out
, "inboundInterface", in_ifname
);
3003 json_object_int_add(json_ifp_out
, "iVifI", c_oil
->oil
.mfcc_parent
);
3004 json_object_string_add(json_ifp_out
, "outboundInterface", out_ifname
);
3005 json_object_int_add(json_ifp_out
, "oVifI", oif_vif_index
);
3006 json_object_int_add(json_ifp_out
, "ttl", ttl
);
3007 json_object_string_add(json_ifp_out
, "upTime", oif_uptime
);
3009 json_oil
= json_object_new_object();
3010 json_object_object_add(json_source
, "oil", json_oil
);
3012 json_object_object_add(json_oil
, out_ifname
, json_ifp_out
);
3014 if (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_PIM
) {
3015 strcpy(proto
, "PIM");
3018 if (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_IGMP
) {
3019 strcpy(proto
, "IGMP");
3022 if (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_SOURCE
) {
3023 strcpy(proto
, "SRC");
3026 if (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_STAR
) {
3027 strcpy(proto
, "STAR");
3030 vty_out(vty
, "%-15s %-15s %-6s %-10s %-10s %-3d %8s%s",
3044 in_ifname
[0] = '\0';
3050 if (!uj
&& !found_oif
) {
3051 vty_out(vty
, "%-15s %-15s %-6s %-10s %-10s %-3d %8s%s",
3063 /* Print list of static routes */
3064 for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list
, node
, s_route
)) {
3067 if (!s_route
->c_oil
.installed
)
3070 pim_inet4_dump("<group?>", s_route
->group
, grp_str
, sizeof(grp_str
));
3071 pim_inet4_dump("<source?>", s_route
->source
, src_str
, sizeof(src_str
));
3072 ifp_in
= pim_if_find_by_vif_index(s_route
->iif
);
3076 strcpy(in_ifname
, ifp_in
->name
);
3078 strcpy(in_ifname
, "<iif?>");
3082 /* Find the group, create it if it doesn't exist */
3083 json_object_object_get_ex(json
, grp_str
, &json_group
);
3086 json_group
= json_object_new_object();
3087 json_object_object_add(json
, grp_str
, json_group
);
3090 /* Find the source nested under the group, create it if it doesn't exist */
3091 json_object_object_get_ex(json_group
, src_str
, &json_source
);
3094 json_source
= json_object_new_object();
3095 json_object_object_add(json_group
, src_str
, json_source
);
3098 json_object_string_add(json_source
, "iif", in_ifname
);
3101 strcpy(proto
, "STATIC");
3104 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
; ++oif_vif_index
) {
3105 struct interface
*ifp_out
;
3106 char oif_uptime
[10];
3109 ttl
= s_route
->oif_ttls
[oif_vif_index
];
3113 ifp_out
= pim_if_find_by_vif_index(oif_vif_index
);
3114 pim_time_uptime(oif_uptime
, sizeof(oif_uptime
), now
- s_route
->c_oil
.oif_creation
[oif_vif_index
]);
3118 strcpy(out_ifname
, ifp_out
->name
);
3120 strcpy(out_ifname
, "<oif?>");
3123 json_ifp_out
= json_object_new_object();
3124 json_object_string_add(json_ifp_out
, "source", src_str
);
3125 json_object_string_add(json_ifp_out
, "group", grp_str
);
3126 json_object_boolean_true_add(json_ifp_out
, "protocolStatic");
3127 json_object_string_add(json_ifp_out
, "inboundInterface", in_ifname
);
3128 json_object_int_add(json_ifp_out
, "iVifI", c_oil
->oil
.mfcc_parent
);
3129 json_object_string_add(json_ifp_out
, "outboundInterface", out_ifname
);
3130 json_object_int_add(json_ifp_out
, "oVifI", oif_vif_index
);
3131 json_object_int_add(json_ifp_out
, "ttl", ttl
);
3132 json_object_string_add(json_ifp_out
, "upTime", oif_uptime
);
3134 json_oil
= json_object_new_object();
3135 json_object_object_add(json_source
, "oil", json_oil
);
3137 json_object_object_add(json_oil
, out_ifname
, json_ifp_out
);
3139 vty_out(vty
, "%-15s %-15s %-6s %-10s %-10s %-3d %8s%s",
3152 in_ifname
[0] = '\0';
3158 if (!uj
&& !found_oif
) {
3159 vty_out(vty
, "%-15s %-15s %-6s %-10s %-10s %-3d %8s%s",
3172 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
3173 json_object_free(json
);
3177 DEFUN (show_ip_mroute
,
3179 "show ip mroute [json]",
3185 u_char uj
= use_json(argc
, argv
);
3186 show_mroute(vty
, uj
);
3190 static void show_mroute_count(struct vty
*vty
)
3192 struct listnode
*node
;
3193 struct channel_oil
*c_oil
;
3194 struct static_route
*s_route
;
3196 vty_out(vty
, "%s", VTY_NEWLINE
);
3198 vty_out(vty
, "Source Group LastUsed Packets Bytes WrongIf %s",
3201 /* Print PIM and IGMP route counts */
3202 for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list
, node
, c_oil
)) {
3203 char group_str
[INET_ADDRSTRLEN
];
3204 char source_str
[INET_ADDRSTRLEN
];
3206 if (!c_oil
->installed
)
3209 pim_mroute_update_counters (c_oil
);
3211 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, group_str
, sizeof(group_str
));
3212 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, source_str
, sizeof(source_str
));
3214 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld%s",
3217 c_oil
->cc
.lastused
/100,
3224 /* Print static route counts */
3225 for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list
, node
, s_route
)) {
3226 char group_str
[INET_ADDRSTRLEN
];
3227 char source_str
[INET_ADDRSTRLEN
];
3229 if (!s_route
->c_oil
.installed
)
3232 pim_mroute_update_counters (&s_route
->c_oil
);
3234 pim_inet4_dump("<group?>", s_route
->c_oil
.oil
.mfcc_mcastgrp
, group_str
, sizeof(group_str
));
3235 pim_inet4_dump("<source?>", s_route
->c_oil
.oil
.mfcc_origin
, source_str
, sizeof(source_str
));
3237 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld%s",
3240 s_route
->c_oil
.cc
.lastused
,
3241 s_route
->c_oil
.cc
.pktcnt
,
3242 s_route
->c_oil
.cc
.bytecnt
,
3243 s_route
->c_oil
.cc
.wrong_if
,
3248 DEFUN (show_ip_mroute_count
,
3249 show_ip_mroute_count_cmd
,
3250 "show ip mroute count",
3254 "Route and packet count data\n")
3256 show_mroute_count(vty
);
3262 "show ip rib A.B.C.D",
3266 "Unicast address\n")
3269 struct in_addr addr
;
3270 const char *addr_str
;
3271 struct pim_nexthop nexthop
;
3272 char nexthop_addr_str
[PREFIX_STRLEN
];
3275 memset (&nexthop
, 0, sizeof (nexthop
));
3276 addr_str
= argv
[idx_ipv4
]->arg
;
3277 result
= inet_pton(AF_INET
, addr_str
, &addr
);
3279 vty_out(vty
, "Bad unicast address %s: errno=%d: %s%s",
3280 addr_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
3284 if (pim_nexthop_lookup(&nexthop
, addr
, 0)) {
3285 vty_out(vty
, "Failure querying RIB nexthop for unicast address %s%s",
3286 addr_str
, VTY_NEWLINE
);
3290 vty_out(vty
, "Address NextHop Interface Metric Preference%s",
3293 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
3294 nexthop_addr_str
, sizeof(nexthop_addr_str
));
3296 vty_out(vty
, "%-15s %-15s %-9s %6d %10d%s",
3299 nexthop
.interface
? nexthop
.interface
->name
: "<ifname?>",
3300 nexthop
.mrib_route_metric
,
3301 nexthop
.mrib_metric_preference
,
3307 static void show_ssmpingd(struct vty
*vty
)
3309 struct listnode
*node
;
3310 struct ssmpingd_sock
*ss
;
3313 vty_out(vty
, "Source Socket Address Port Uptime Requests%s",
3316 if (!qpim_ssmpingd_list
)
3319 now
= pim_time_monotonic_sec();
3321 for (ALL_LIST_ELEMENTS_RO(qpim_ssmpingd_list
, node
, ss
)) {
3322 char source_str
[INET_ADDRSTRLEN
];
3324 struct sockaddr_in bind_addr
;
3325 socklen_t len
= sizeof(bind_addr
);
3326 char bind_addr_str
[INET_ADDRSTRLEN
];
3328 pim_inet4_dump("<src?>", ss
->source_addr
, source_str
, sizeof(source_str
));
3330 if (pim_socket_getsockname(ss
->sock_fd
, (struct sockaddr
*) &bind_addr
, &len
)) {
3331 vty_out(vty
, "%% Failure reading socket name for ssmpingd source %s on fd=%d%s",
3332 source_str
, ss
->sock_fd
, VTY_NEWLINE
);
3335 pim_inet4_dump("<addr?>", bind_addr
.sin_addr
, bind_addr_str
, sizeof(bind_addr_str
));
3336 pim_time_uptime(ss_uptime
, sizeof(ss_uptime
), now
- ss
->creation
);
3338 vty_out(vty
, "%-15s %6d %-15s %5d %8s %8lld%s",
3342 ntohs(bind_addr
.sin_port
),
3344 (long long)ss
->requests
,
3349 DEFUN (show_ip_ssmpingd
,
3350 show_ip_ssmpingd_cmd
,
3361 pim_rp_cmd_worker (struct vty
*vty
, const char *rp
, const char *group
, const char *plist
)
3365 result
= pim_rp_new (rp
, group
, plist
);
3367 if (result
== PIM_MALLOC_FAIL
)
3369 vty_out (vty
, "%% Out of memory%s", VTY_NEWLINE
);
3373 if (result
== PIM_GROUP_BAD_ADDRESS
)
3375 vty_out (vty
, "%% Bad group address specified: %s%s", group
, VTY_NEWLINE
);
3379 if (result
== PIM_RP_BAD_ADDRESS
)
3381 vty_out (vty
, "%% Bad RP address specified: %s%s", rp
, VTY_NEWLINE
);
3385 if (result
== PIM_RP_NO_PATH
)
3387 vty_out (vty
, "%% No Path to RP address specified: %s%s", rp
, VTY_NEWLINE
);
3391 if (result
== PIM_GROUP_OVERLAP
)
3393 vty_out (vty
, "%% Group range specified cannot overlap%s", VTY_NEWLINE
);
3397 if (result
== PIM_GROUP_PFXLIST_OVERLAP
)
3399 vty_out (vty
, "%% This group is already covered by a RP prefix-list%s", VTY_NEWLINE
);
3403 if (result
== PIM_RP_PFXLIST_IN_USE
)
3405 vty_out (vty
, "%% The same prefix-list cannot be applied to multiple RPs%s", VTY_NEWLINE
);
3412 DEFUN (ip_pim_joinprune_time
,
3413 ip_pim_joinprune_time_cmd
,
3414 "ip pim join-prune-interval <60-600>",
3416 "pim multicast routing\n"
3417 "Join Prune Send Interval\n"
3420 qpim_t_periodic
= atoi(argv
[3]->arg
);
3424 DEFUN (no_ip_pim_joinprune_time
,
3425 no_ip_pim_joinprune_time_cmd
,
3426 "no ip pim join-prune-interval <60-600>",
3429 "pim multicast routing\n"
3430 "Join Prune Send Interval\n"
3433 qpim_t_periodic
= PIM_DEFAULT_T_PERIODIC
;
3437 DEFUN (ip_pim_register_suppress
,
3438 ip_pim_register_suppress_cmd
,
3439 "ip pim register-suppress-time <5-60000>",
3441 "pim multicast routing\n"
3442 "Register Suppress Timer\n"
3445 qpim_keep_alive_time
= atoi (argv
[3]->arg
);
3449 DEFUN (no_ip_pim_register_suppress
,
3450 no_ip_pim_register_suppress_cmd
,
3451 "no ip pim register-suppress-time <5-60000>",
3454 "pim multicast routing\n"
3455 "Register Suppress Timer\n"
3458 qpim_register_suppress_time
= PIM_REGISTER_SUPPRESSION_TIME_DEFAULT
;
3462 DEFUN (ip_pim_keep_alive
,
3463 ip_pim_keep_alive_cmd
,
3464 "ip pim keep-alive-timer <31-60000>",
3466 "pim multicast routing\n"
3467 "Keep alive Timer\n"
3470 qpim_rp_keep_alive_time
= atoi (argv
[4]->arg
);
3474 DEFUN (no_ip_pim_keep_alive
,
3475 no_ip_pim_keep_alive_cmd
,
3476 "no ip pim keep-alive-timer <31-60000>",
3479 "pim multicast routing\n"
3480 "Keep alive Timer\n"
3483 qpim_keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
3487 DEFUN (ip_pim_packets
,
3489 "ip pim packets <1-100>",
3491 "pim multicast routing\n"
3492 "packets to process at one time per fd\n"
3493 "Number of packets\n")
3495 qpim_packet_process
= atoi (argv
[3]->arg
);
3499 DEFUN (no_ip_pim_packets
,
3500 no_ip_pim_packets_cmd
,
3501 "no ip pim packets <1-100>",
3504 "pim multicast routing\n"
3505 "packets to process at one time per fd\n"
3506 "Number of packets\n")
3508 qpim_packet_process
= PIM_DEFAULT_PACKET_PROCESS
;
3514 "ip pim rp A.B.C.D [A.B.C.D/M]",
3516 "pim multicast routing\n"
3518 "ip address of RP\n"
3519 "Group Address range to cover\n")
3523 if (argc
== (idx_ipv4
+ 1))
3524 return pim_rp_cmd_worker (vty
, argv
[idx_ipv4
]->arg
, argv
[idx_ipv4
+ 1]->arg
, NULL
);
3526 return pim_rp_cmd_worker (vty
, argv
[idx_ipv4
]->arg
, NULL
, NULL
);
3529 DEFUN (ip_pim_rp_prefix_list
,
3530 ip_pim_rp_prefix_list_cmd
,
3531 "ip pim rp A.B.C.D prefix-list WORD",
3533 "pim multicast routing\n"
3535 "ip address of RP\n"
3536 "group prefix-list filter\n"
3537 "Name of a prefix-list\n")
3539 return pim_rp_cmd_worker (vty
, argv
[3]->arg
, NULL
, argv
[5]->arg
);
3543 pim_no_rp_cmd_worker (struct vty
*vty
, const char *rp
, const char *group
,
3546 int result
= pim_rp_del (rp
, group
, plist
);
3548 if (result
== PIM_GROUP_BAD_ADDRESS
)
3550 vty_out (vty
, "%% Bad group address specified: %s%s", group
, VTY_NEWLINE
);
3554 if (result
== PIM_RP_BAD_ADDRESS
)
3556 vty_out (vty
, "%% Bad RP address specified: %s%s", rp
, VTY_NEWLINE
);
3560 if (result
== PIM_RP_NOT_FOUND
)
3562 vty_out (vty
, "%% Unable to find specified RP%s", VTY_NEWLINE
);
3569 DEFUN (no_ip_pim_rp
,
3571 "no ip pim rp A.B.C.D [A.B.C.D/M]",
3574 "pim multicast routing\n"
3576 "ip address of RP\n"
3577 "Group Address range to cover\n")
3581 if (argc
== (idx_ipv4
+ 1))
3582 return pim_no_rp_cmd_worker (vty
, argv
[idx_ipv4
]->arg
, argv
[idx_ipv4
+ 1]->arg
, NULL
);
3584 return pim_no_rp_cmd_worker (vty
, argv
[idx_ipv4
]->arg
, NULL
, NULL
);
3587 DEFUN (no_ip_pim_rp_prefix_list
,
3588 no_ip_pim_rp_prefix_list_cmd
,
3589 "no ip pim rp A.B.C.D prefix-list WORD",
3592 "pim multicast routing\n"
3594 "ip address of RP\n"
3595 "group prefix-list filter\n"
3596 "Name of a prefix-list\n")
3598 return pim_no_rp_cmd_worker (vty
, argv
[4]->arg
, NULL
, argv
[6]->arg
);
3601 DEFUN_HIDDEN (ip_multicast_routing
,
3602 ip_multicast_routing_cmd
,
3603 "ip multicast-routing",
3605 "Enable IP multicast forwarding\n")
3610 DEFUN_HIDDEN (no_ip_multicast_routing
,
3611 no_ip_multicast_routing_cmd
,
3612 "no ip multicast-routing",
3615 "Global IP configuration subcommands\n"
3616 "Enable IP multicast forwarding\n")
3618 vty_out (vty
, "Command is Disabled and will be removed in a future version%s", VTY_NEWLINE
);
3624 "ip ssmpingd [A.B.C.D]",
3631 struct in_addr source_addr
;
3632 const char *source_str
= (argc
== idx_ipv4
) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
3634 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
3636 vty_out(vty
, "%% Bad source address %s: errno=%d: %s%s",
3637 source_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
3641 result
= pim_ssmpingd_start(source_addr
);
3643 vty_out(vty
, "%% Failure starting ssmpingd for source %s: %d%s",
3644 source_str
, result
, VTY_NEWLINE
);
3651 DEFUN (no_ip_ssmpingd
,
3653 "no ip ssmpingd [A.B.C.D]",
3661 struct in_addr source_addr
;
3662 const char *source_str
= (argc
== idx_ipv4
) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
3664 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
3666 vty_out(vty
, "%% Bad source address %s: errno=%d: %s%s",
3667 source_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
3671 result
= pim_ssmpingd_stop(source_addr
);
3673 vty_out(vty
, "%% Failure stopping ssmpingd for source %s: %d%s",
3674 source_str
, result
, VTY_NEWLINE
);
3682 pim_cmd_igmp_start (struct vty
*vty
, struct interface
*ifp
)
3684 struct pim_interface
*pim_ifp
;
3686 pim_ifp
= ifp
->info
;
3689 pim_ifp
= pim_if_new(ifp
, 1 /* igmp=true */, 0 /* pim=false */);
3691 vty_out(vty
, "Could not enable IGMP on interface %s%s",
3692 ifp
->name
, VTY_NEWLINE
);
3697 PIM_IF_DO_IGMP(pim_ifp
->options
);
3700 pim_if_addr_add_all(ifp
);
3701 pim_if_membership_refresh(ifp
);
3706 DEFUN (interface_ip_igmp
,
3707 interface_ip_igmp_cmd
,
3712 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3714 return pim_cmd_igmp_start(vty
, ifp
);
3717 DEFUN (interface_no_ip_igmp
,
3718 interface_no_ip_igmp_cmd
,
3724 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3725 struct pim_interface
*pim_ifp
;
3727 pim_ifp
= ifp
->info
;
3731 PIM_IF_DONT_IGMP(pim_ifp
->options
);
3733 pim_if_membership_clear(ifp
);
3735 pim_if_addr_del_all_igmp(ifp
);
3737 if (!PIM_IF_TEST_PIM(pim_ifp
->options
)) {
3744 DEFUN (interface_ip_igmp_join
,
3745 interface_ip_igmp_join_cmd
,
3746 "ip igmp join A.B.C.D A.B.C.D",
3749 "IGMP join multicast group\n"
3750 "Multicast group address\n"
3753 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3756 const char *group_str
;
3757 const char *source_str
;
3758 struct in_addr group_addr
;
3759 struct in_addr source_addr
;
3763 group_str
= argv
[idx_ipv4
]->arg
;
3764 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
3766 vty_out(vty
, "Bad group address %s: errno=%d: %s%s",
3767 group_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
3771 /* Source address */
3772 source_str
= argv
[idx_ipv4_2
]->arg
;
3773 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
3775 vty_out(vty
, "Bad source address %s: errno=%d: %s%s",
3776 source_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
3780 result
= pim_if_igmp_join_add(ifp
, group_addr
, source_addr
);
3782 vty_out(vty
, "%% Failure joining IGMP group %s source %s on interface %s: %d%s",
3783 group_str
, source_str
, ifp
->name
, result
, VTY_NEWLINE
);
3790 DEFUN (interface_no_ip_igmp_join
,
3791 interface_no_ip_igmp_join_cmd
,
3792 "no ip igmp join A.B.C.D A.B.C.D",
3796 "IGMP join multicast group\n"
3797 "Multicast group address\n"
3800 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3803 const char *group_str
;
3804 const char *source_str
;
3805 struct in_addr group_addr
;
3806 struct in_addr source_addr
;
3810 group_str
= argv
[idx_ipv4
]->arg
;
3811 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
3813 vty_out(vty
, "Bad group address %s: errno=%d: %s%s",
3814 group_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
3818 /* Source address */
3819 source_str
= argv
[idx_ipv4_2
]->arg
;
3820 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
3822 vty_out(vty
, "Bad source address %s: errno=%d: %s%s",
3823 source_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
3827 result
= pim_if_igmp_join_del(ifp
, group_addr
, source_addr
);
3829 vty_out(vty
, "%% Failure leaving IGMP group %s source %s on interface %s: %d%s",
3830 group_str
, source_str
, ifp
->name
, result
, VTY_NEWLINE
);
3838 CLI reconfiguration affects the interface level (struct pim_interface).
3839 This function propagates the reconfiguration to every active socket
3842 static void igmp_sock_query_interval_reconfig(struct igmp_sock
*igmp
)
3844 struct interface
*ifp
;
3845 struct pim_interface
*pim_ifp
;
3849 /* other querier present? */
3851 if (igmp
->t_other_querier_timer
)
3854 /* this is the querier */
3856 zassert(igmp
->interface
);
3857 zassert(igmp
->interface
->info
);
3859 ifp
= igmp
->interface
;
3860 pim_ifp
= ifp
->info
;
3862 if (PIM_DEBUG_IGMP_TRACE
) {
3863 char ifaddr_str
[INET_ADDRSTRLEN
];
3864 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
, sizeof(ifaddr_str
));
3865 zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
3866 __PRETTY_FUNCTION__
,
3869 pim_ifp
->igmp_default_query_interval
);
3873 igmp_startup_mode_on() will reset QQI:
3875 igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
3877 igmp_startup_mode_on(igmp
);
3880 static void igmp_sock_query_reschedule(struct igmp_sock
*igmp
)
3882 if (igmp
->t_igmp_query_timer
) {
3883 /* other querier present */
3884 zassert(igmp
->t_igmp_query_timer
);
3885 zassert(!igmp
->t_other_querier_timer
);
3887 pim_igmp_general_query_off(igmp
);
3888 pim_igmp_general_query_on(igmp
);
3890 zassert(igmp
->t_igmp_query_timer
);
3891 zassert(!igmp
->t_other_querier_timer
);
3894 /* this is the querier */
3896 zassert(!igmp
->t_igmp_query_timer
);
3897 zassert(igmp
->t_other_querier_timer
);
3899 pim_igmp_other_querier_timer_off(igmp
);
3900 pim_igmp_other_querier_timer_on(igmp
);
3902 zassert(!igmp
->t_igmp_query_timer
);
3903 zassert(igmp
->t_other_querier_timer
);
3907 static void change_query_interval(struct pim_interface
*pim_ifp
,
3910 struct listnode
*sock_node
;
3911 struct igmp_sock
*igmp
;
3913 pim_ifp
->igmp_default_query_interval
= query_interval
;
3915 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
3916 igmp_sock_query_interval_reconfig(igmp
);
3917 igmp_sock_query_reschedule(igmp
);
3921 static void change_query_max_response_time(struct pim_interface
*pim_ifp
,
3922 int query_max_response_time_dsec
)
3924 struct listnode
*sock_node
;
3925 struct igmp_sock
*igmp
;
3927 pim_ifp
->igmp_query_max_response_time_dsec
= query_max_response_time_dsec
;
3930 Below we modify socket/group/source timers in order to quickly
3931 reflect the change. Otherwise, those timers would eventually catch
3935 /* scan all sockets */
3936 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
3937 struct listnode
*grp_node
;
3938 struct igmp_group
*grp
;
3940 /* reschedule socket general query */
3941 igmp_sock_query_reschedule(igmp
);
3943 /* scan socket groups */
3944 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grp_node
, grp
)) {
3945 struct listnode
*src_node
;
3946 struct igmp_source
*src
;
3948 /* reset group timers for groups in EXCLUDE mode */
3949 if (grp
->group_filtermode_isexcl
) {
3950 igmp_group_reset_gmi(grp
);
3953 /* scan group sources */
3954 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
, src_node
, src
)) {
3956 /* reset source timers for sources with running timers */
3957 if (src
->t_source_timer
) {
3958 igmp_source_reset_gmi(igmp
, grp
, src
);
3965 #define IGMP_QUERY_INTERVAL_MIN (1)
3966 #define IGMP_QUERY_INTERVAL_MAX (1800)
3968 DEFUN (interface_ip_igmp_query_interval
,
3969 interface_ip_igmp_query_interval_cmd
,
3970 "ip igmp query-interval (1-1800)",
3973 IFACE_IGMP_QUERY_INTERVAL_STR
3974 "Query interval in seconds\n")
3976 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3977 struct pim_interface
*pim_ifp
;
3979 int query_interval_dsec
;
3982 pim_ifp
= ifp
->info
;
3985 ret
= pim_cmd_igmp_start(vty
, ifp
);
3986 if (ret
!= CMD_SUCCESS
)
3988 pim_ifp
= ifp
->info
;
3991 query_interval
= atoi(argv
[3]->arg
);
3992 query_interval_dsec
= 10 * query_interval
;
3995 It seems we don't need to check bounds since command.c does it
3996 already, but we verify them anyway for extra safety.
3998 if (query_interval
< IGMP_QUERY_INTERVAL_MIN
) {
3999 vty_out(vty
, "General query interval %d lower than minimum %d%s",
4001 IGMP_QUERY_INTERVAL_MIN
,
4005 if (query_interval
> IGMP_QUERY_INTERVAL_MAX
) {
4006 vty_out(vty
, "General query interval %d higher than maximum %d%s",
4008 IGMP_QUERY_INTERVAL_MAX
,
4013 if (query_interval_dsec
<= pim_ifp
->igmp_query_max_response_time_dsec
) {
4015 "Can't set general query interval %d dsec <= query max response time %d dsec.%s",
4016 query_interval_dsec
, pim_ifp
->igmp_query_max_response_time_dsec
,
4021 change_query_interval(pim_ifp
, query_interval
);
4026 DEFUN (interface_no_ip_igmp_query_interval
,
4027 interface_no_ip_igmp_query_interval_cmd
,
4028 "no ip igmp query-interval",
4032 IFACE_IGMP_QUERY_INTERVAL_STR
)
4034 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4035 struct pim_interface
*pim_ifp
;
4036 int default_query_interval_dsec
;
4038 pim_ifp
= ifp
->info
;
4043 default_query_interval_dsec
= IGMP_GENERAL_QUERY_INTERVAL
* 10;
4045 if (default_query_interval_dsec
<= pim_ifp
->igmp_query_max_response_time_dsec
) {
4047 "Can't set default general query interval %d dsec <= query max response time %d dsec.%s",
4048 default_query_interval_dsec
, pim_ifp
->igmp_query_max_response_time_dsec
,
4053 change_query_interval(pim_ifp
, IGMP_GENERAL_QUERY_INTERVAL
);
4058 DEFUN (interface_ip_igmp_version
,
4059 interface_ip_igmp_version_cmd
,
4060 "ip igmp version (2-3)",
4064 "IGMP version number\n")
4066 VTY_DECLVAR_CONTEXT(interface
,ifp
);
4067 struct pim_interface
*pim_ifp
;
4071 pim_ifp
= ifp
->info
;
4074 ret
= pim_cmd_igmp_start(vty
, ifp
);
4075 if (ret
!= CMD_SUCCESS
)
4077 pim_ifp
= ifp
->info
;
4080 igmp_version
= atoi(argv
[3]->arg
);
4081 pim_ifp
->igmp_version
= igmp_version
;
4086 DEFUN (interface_no_ip_igmp_version
,
4087 interface_no_ip_igmp_version_cmd
,
4088 "no ip igmp version (2-3)",
4093 "IGMP version number\n")
4095 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4096 struct pim_interface
*pim_ifp
;
4098 pim_ifp
= ifp
->info
;
4103 pim_ifp
->igmp_version
= IGMP_DEFAULT_VERSION
;
4108 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
4109 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
4111 DEFUN (interface_ip_igmp_query_max_response_time
,
4112 interface_ip_igmp_query_max_response_time_cmd
,
4113 "ip igmp query-max-response-time (10-250)",
4116 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
4117 "Query response value in deci-seconds\n")
4119 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4120 struct pim_interface
*pim_ifp
;
4121 int query_max_response_time
;
4124 pim_ifp
= ifp
->info
;
4127 ret
= pim_cmd_igmp_start(vty
, ifp
);
4128 if (ret
!= CMD_SUCCESS
)
4130 pim_ifp
= ifp
->info
;
4133 query_max_response_time
= atoi(argv
[3]->arg
);
4135 if (query_max_response_time
>= pim_ifp
->igmp_default_query_interval
* 10) {
4137 "Can't set query max response time %d sec >= general query interval %d sec%s",
4138 query_max_response_time
, pim_ifp
->igmp_default_query_interval
,
4143 change_query_max_response_time(pim_ifp
, query_max_response_time
);
4148 DEFUN (interface_no_ip_igmp_query_max_response_time
,
4149 interface_no_ip_igmp_query_max_response_time_cmd
,
4150 "no ip igmp query-max-response-time (10-250)",
4154 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
4155 "Time for response in deci-seconds\n")
4157 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4158 struct pim_interface
*pim_ifp
;
4160 pim_ifp
= ifp
->info
;
4165 change_query_max_response_time(pim_ifp
, IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
4170 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
4171 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
4173 DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec
,
4174 interface_ip_igmp_query_max_response_time_dsec_cmd
,
4175 "ip igmp query-max-response-time-dsec (10-250)",
4178 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
4179 "Query response value in deciseconds\n")
4181 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4182 struct pim_interface
*pim_ifp
;
4183 int query_max_response_time_dsec
;
4184 int default_query_interval_dsec
;
4187 pim_ifp
= ifp
->info
;
4190 ret
= pim_cmd_igmp_start(vty
, ifp
);
4191 if (ret
!= CMD_SUCCESS
)
4193 pim_ifp
= ifp
->info
;
4196 query_max_response_time_dsec
= atoi(argv
[4]->arg
);
4198 default_query_interval_dsec
= 10 * pim_ifp
->igmp_default_query_interval
;
4200 if (query_max_response_time_dsec
>= default_query_interval_dsec
) {
4202 "Can't set query max response time %d dsec >= general query interval %d dsec%s",
4203 query_max_response_time_dsec
, default_query_interval_dsec
,
4208 change_query_max_response_time(pim_ifp
, query_max_response_time_dsec
);
4213 DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec
,
4214 interface_no_ip_igmp_query_max_response_time_dsec_cmd
,
4215 "no ip igmp query-max-response-time-dsec",
4219 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
)
4221 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4222 struct pim_interface
*pim_ifp
;
4224 pim_ifp
= ifp
->info
;
4229 change_query_max_response_time(pim_ifp
, IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
4234 DEFUN (interface_ip_pim_drprio
,
4235 interface_ip_pim_drprio_cmd
,
4236 "ip pim drpriority (1-4294967295)",
4239 "Set the Designated Router Election Priority\n"
4240 "Value of the new DR Priority\n")
4242 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4244 struct pim_interface
*pim_ifp
;
4245 uint32_t old_dr_prio
;
4247 pim_ifp
= ifp
->info
;
4250 vty_out(vty
, "Please enable PIM on interface, first%s", VTY_NEWLINE
);
4254 old_dr_prio
= pim_ifp
->pim_dr_priority
;
4256 pim_ifp
->pim_dr_priority
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
4258 if (old_dr_prio
!= pim_ifp
->pim_dr_priority
) {
4259 if (pim_if_dr_election(ifp
))
4260 pim_hello_restart_now(ifp
);
4266 DEFUN (interface_no_ip_pim_drprio
,
4267 interface_no_ip_pim_drprio_cmd
,
4268 "no ip pim drpriority [(1-4294967295)]",
4272 "Revert the Designated Router Priority to default\n"
4273 "Old Value of the Priority\n")
4275 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4276 struct pim_interface
*pim_ifp
;
4278 pim_ifp
= ifp
->info
;
4281 vty_out(vty
, "Pim not enabled on this interface%s", VTY_NEWLINE
);
4285 if (pim_ifp
->pim_dr_priority
!= PIM_DEFAULT_DR_PRIORITY
) {
4286 pim_ifp
->pim_dr_priority
= PIM_DEFAULT_DR_PRIORITY
;
4287 if (pim_if_dr_election(ifp
))
4288 pim_hello_restart_now(ifp
);
4295 pim_cmd_interface_add (struct interface
*ifp
, enum pim_interface_type itype
)
4297 struct pim_interface
*pim_ifp
= ifp
->info
;
4300 pim_ifp
= pim_if_new(ifp
, 0 /* igmp=false */, 1 /* pim=true */);
4306 PIM_IF_DO_PIM(pim_ifp
->options
);
4309 pim_ifp
->itype
= itype
;
4310 pim_if_addr_add_all(ifp
);
4311 pim_if_membership_refresh(ifp
);
4316 DEFUN (interface_ip_pim_ssm
,
4317 interface_ip_pim_ssm_cmd
,
4323 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4325 if (!pim_cmd_interface_add(ifp
, PIM_INTERFACE_SSM
)) {
4326 vty_out(vty
, "Could not enable PIM SSM on interface%s", VTY_NEWLINE
);
4333 DEFUN (interface_ip_pim_sm
,
4334 interface_ip_pim_sm_cmd
,
4340 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4341 if (!pim_cmd_interface_add(ifp
, PIM_INTERFACE_SM
)) {
4342 vty_out(vty
, "Could not enable PIM SM on interface%s", VTY_NEWLINE
);
4346 pim_if_create_pimreg();
4352 pim_cmd_interface_delete (struct interface
*ifp
)
4354 struct pim_interface
*pim_ifp
= ifp
->info
;
4359 PIM_IF_DONT_PIM(pim_ifp
->options
);
4361 pim_if_membership_clear(ifp
);
4364 pim_sock_delete() removes all neighbors from
4365 pim_ifp->pim_neighbor_list.
4367 pim_sock_delete(ifp
, "pim unconfigured on interface");
4369 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
4370 pim_if_addr_del_all(ifp
);
4377 DEFUN (interface_no_ip_pim_ssm
,
4378 interface_no_ip_pim_ssm_cmd
,
4385 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4386 if (!pim_cmd_interface_delete(ifp
)) {
4387 vty_out(vty
, "Unable to delete interface information%s", VTY_NEWLINE
);
4394 DEFUN (interface_no_ip_pim_sm
,
4395 interface_no_ip_pim_sm_cmd
,
4402 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4403 if (!pim_cmd_interface_delete(ifp
)) {
4404 vty_out(vty
, "Unable to delete interface information%s", VTY_NEWLINE
);
4411 DEFUN (interface_ip_mroute
,
4412 interface_ip_mroute_cmd
,
4413 "ip mroute INTERFACE A.B.C.D",
4415 "Add multicast route\n"
4416 "Outgoing interface name\n"
4419 VTY_DECLVAR_CONTEXT(interface
, iif
);
4420 int idx_interface
= 2;
4422 struct interface
*oif
;
4423 const char *oifname
;
4424 const char *grp_str
;
4425 struct in_addr grp_addr
;
4426 struct in_addr src_addr
;
4429 oifname
= argv
[idx_interface
]->arg
;
4430 oif
= if_lookup_by_name(oifname
);
4432 vty_out(vty
, "No such interface name %s%s",
4433 oifname
, VTY_NEWLINE
);
4437 grp_str
= argv
[idx_ipv4
]->arg
;
4438 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
4440 vty_out(vty
, "Bad group address %s: errno=%d: %s%s",
4441 grp_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
4445 src_addr
.s_addr
= INADDR_ANY
;
4447 if (pim_static_add(iif
, oif
, grp_addr
, src_addr
)) {
4448 vty_out(vty
, "Failed to add route%s", VTY_NEWLINE
);
4455 DEFUN (interface_ip_mroute_source
,
4456 interface_ip_mroute_source_cmd
,
4457 "ip mroute INTERFACE A.B.C.D A.B.C.D",
4459 "Add multicast route\n"
4460 "Outgoing interface name\n"
4464 VTY_DECLVAR_CONTEXT(interface
, iif
);
4465 int idx_interface
= 2;
4468 struct interface
*oif
;
4469 const char *oifname
;
4470 const char *grp_str
;
4471 struct in_addr grp_addr
;
4472 const char *src_str
;
4473 struct in_addr src_addr
;
4476 oifname
= argv
[idx_interface
]->arg
;
4477 oif
= if_lookup_by_name(oifname
);
4479 vty_out(vty
, "No such interface name %s%s",
4480 oifname
, VTY_NEWLINE
);
4484 grp_str
= argv
[idx_ipv4
]->arg
;
4485 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
4487 vty_out(vty
, "Bad group address %s: errno=%d: %s%s",
4488 grp_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
4492 src_str
= argv
[idx_ipv4_2
]->arg
;
4493 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
4495 vty_out(vty
, "Bad source address %s: errno=%d: %s%s",
4496 src_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
4500 if (pim_static_add(iif
, oif
, grp_addr
, src_addr
)) {
4501 vty_out(vty
, "Failed to add route%s", VTY_NEWLINE
);
4508 DEFUN (interface_no_ip_mroute
,
4509 interface_no_ip_mroute_cmd
,
4510 "no ip mroute INTERFACE A.B.C.D",
4513 "Add multicast route\n"
4514 "Outgoing interface name\n"
4517 VTY_DECLVAR_CONTEXT(interface
, iif
);
4518 int idx_interface
= 3;
4520 struct interface
*oif
;
4521 const char *oifname
;
4522 const char *grp_str
;
4523 struct in_addr grp_addr
;
4524 struct in_addr src_addr
;
4527 oifname
= argv
[idx_interface
]->arg
;
4528 oif
= if_lookup_by_name(oifname
);
4530 vty_out(vty
, "No such interface name %s%s",
4531 oifname
, VTY_NEWLINE
);
4535 grp_str
= argv
[idx_ipv4
]->arg
;
4536 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
4538 vty_out(vty
, "Bad group address %s: errno=%d: %s%s",
4539 grp_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
4543 src_addr
.s_addr
= INADDR_ANY
;
4545 if (pim_static_del(iif
, oif
, grp_addr
, src_addr
)) {
4546 vty_out(vty
, "Failed to remove route%s", VTY_NEWLINE
);
4553 DEFUN (interface_no_ip_mroute_source
,
4554 interface_no_ip_mroute_source_cmd
,
4555 "no ip mroute INTERFACE A.B.C.D A.B.C.D",
4558 "Add multicast route\n"
4559 "Outgoing interface name\n"
4563 VTY_DECLVAR_CONTEXT(interface
, iif
);
4564 int idx_interface
= 3;
4567 struct interface
*oif
;
4568 const char *oifname
;
4569 const char *grp_str
;
4570 struct in_addr grp_addr
;
4571 const char *src_str
;
4572 struct in_addr src_addr
;
4575 oifname
= argv
[idx_interface
]->arg
;
4576 oif
= if_lookup_by_name(oifname
);
4578 vty_out(vty
, "No such interface name %s%s",
4579 oifname
, VTY_NEWLINE
);
4583 grp_str
= argv
[idx_ipv4
]->arg
;
4584 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
4586 vty_out(vty
, "Bad group address %s: errno=%d: %s%s",
4587 grp_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
4591 src_str
= argv
[idx_ipv4_2
]->arg
;
4592 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
4594 vty_out(vty
, "Bad source address %s: errno=%d: %s%s",
4595 src_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
4599 if (pim_static_del(iif
, oif
, grp_addr
, src_addr
)) {
4600 vty_out(vty
, "Failed to remove route%s", VTY_NEWLINE
);
4607 DEFUN (interface_ip_pim_hello
,
4608 interface_ip_pim_hello_cmd
,
4609 "ip pim hello (1-180) [(1-180)]",
4613 IFACE_PIM_HELLO_TIME_STR
4614 IFACE_PIM_HELLO_HOLD_STR
)
4616 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4619 struct pim_interface
*pim_ifp
;
4621 pim_ifp
= ifp
->info
;
4624 vty_out(vty
, "Pim not enabled on this interface%s", VTY_NEWLINE
);
4628 pim_ifp
->pim_hello_period
= strtol(argv
[idx_time
]->arg
, NULL
, 10);
4630 if (argc
== idx_hold
)
4631 pim_ifp
->pim_default_holdtime
= strtol(argv
[idx_hold
]->arg
, NULL
, 10);
4638 DEFUN (interface_no_ip_pim_hello
,
4639 interface_no_ip_pim_hello_cmd
,
4640 "no ip pim hello [(1-180) (1-180)]",
4645 IFACE_PIM_HELLO_TIME_STR
4646 IFACE_PIM_HELLO_HOLD_STR
)
4648 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4649 struct pim_interface
*pim_ifp
;
4651 pim_ifp
= ifp
->info
;
4654 vty_out(vty
, "Pim not enabled on this interface%s", VTY_NEWLINE
);
4658 pim_ifp
->pim_hello_period
= PIM_DEFAULT_HELLO_PERIOD
;
4659 pim_ifp
->pim_default_holdtime
= -1;
4670 PIM_DO_DEBUG_IGMP_EVENTS
;
4671 PIM_DO_DEBUG_IGMP_PACKETS
;
4672 PIM_DO_DEBUG_IGMP_TRACE
;
4676 DEFUN (no_debug_igmp
,
4683 PIM_DONT_DEBUG_IGMP_EVENTS
;
4684 PIM_DONT_DEBUG_IGMP_PACKETS
;
4685 PIM_DONT_DEBUG_IGMP_TRACE
;
4690 DEFUN (debug_igmp_events
,
4691 debug_igmp_events_cmd
,
4692 "debug igmp events",
4695 DEBUG_IGMP_EVENTS_STR
)
4697 PIM_DO_DEBUG_IGMP_EVENTS
;
4701 DEFUN (no_debug_igmp_events
,
4702 no_debug_igmp_events_cmd
,
4703 "no debug igmp events",
4707 DEBUG_IGMP_EVENTS_STR
)
4709 PIM_DONT_DEBUG_IGMP_EVENTS
;
4714 DEFUN (debug_igmp_packets
,
4715 debug_igmp_packets_cmd
,
4716 "debug igmp packets",
4719 DEBUG_IGMP_PACKETS_STR
)
4721 PIM_DO_DEBUG_IGMP_PACKETS
;
4725 DEFUN (no_debug_igmp_packets
,
4726 no_debug_igmp_packets_cmd
,
4727 "no debug igmp packets",
4731 DEBUG_IGMP_PACKETS_STR
)
4733 PIM_DONT_DEBUG_IGMP_PACKETS
;
4738 DEFUN (debug_igmp_trace
,
4739 debug_igmp_trace_cmd
,
4743 DEBUG_IGMP_TRACE_STR
)
4745 PIM_DO_DEBUG_IGMP_TRACE
;
4749 DEFUN (no_debug_igmp_trace
,
4750 no_debug_igmp_trace_cmd
,
4751 "no debug igmp trace",
4755 DEBUG_IGMP_TRACE_STR
)
4757 PIM_DONT_DEBUG_IGMP_TRACE
;
4762 DEFUN (debug_mroute
,
4768 PIM_DO_DEBUG_MROUTE
;
4772 DEFUN (debug_mroute_detail
,
4773 debug_mroute_detail_cmd
,
4774 "debug mroute detail",
4779 PIM_DO_DEBUG_MROUTE_DETAIL
;
4783 DEFUN (no_debug_mroute
,
4784 no_debug_mroute_cmd
,
4790 PIM_DONT_DEBUG_MROUTE
;
4794 DEFUN (no_debug_mroute_detail
,
4795 no_debug_mroute_detail_cmd
,
4796 "no debug mroute detail",
4802 PIM_DONT_DEBUG_MROUTE_DETAIL
;
4806 DEFUN (debug_static
,
4812 PIM_DO_DEBUG_STATIC
;
4816 DEFUN (no_debug_static
,
4817 no_debug_static_cmd
,
4823 PIM_DONT_DEBUG_STATIC
;
4834 PIM_DO_DEBUG_PIM_EVENTS
;
4835 PIM_DO_DEBUG_PIM_PACKETS
;
4836 PIM_DO_DEBUG_PIM_TRACE
;
4837 PIM_DO_DEBUG_MSDP_EVENTS
;
4838 PIM_DO_DEBUG_MSDP_PACKETS
;
4842 DEFUN (no_debug_pim
,
4849 PIM_DONT_DEBUG_PIM_EVENTS
;
4850 PIM_DONT_DEBUG_PIM_PACKETS
;
4851 PIM_DONT_DEBUG_PIM_TRACE
;
4852 PIM_DONT_DEBUG_MSDP_EVENTS
;
4853 PIM_DONT_DEBUG_MSDP_PACKETS
;
4855 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
4856 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
4862 DEFUN (debug_pim_events
,
4863 debug_pim_events_cmd
,
4867 DEBUG_PIM_EVENTS_STR
)
4869 PIM_DO_DEBUG_PIM_EVENTS
;
4873 DEFUN (no_debug_pim_events
,
4874 no_debug_pim_events_cmd
,
4875 "no debug pim events",
4879 DEBUG_PIM_EVENTS_STR
)
4881 PIM_DONT_DEBUG_PIM_EVENTS
;
4885 DEFUN (debug_pim_packets
,
4886 debug_pim_packets_cmd
,
4887 "debug pim packets [<hello|joins|register>]",
4890 DEBUG_PIM_PACKETS_STR
4891 DEBUG_PIM_HELLO_PACKETS_STR
4892 DEBUG_PIM_J_P_PACKETS_STR
4893 DEBUG_PIM_PIM_REG_PACKETS_STR
)
4896 if (argv_find (argv
, argc
, "hello", &idx
))
4898 PIM_DO_DEBUG_PIM_HELLO
;
4899 vty_out (vty
, "PIM Hello debugging is on%s", VTY_NEWLINE
);
4901 else if (argv_find (argv
, argc
,"joins", &idx
))
4903 PIM_DO_DEBUG_PIM_J_P
;
4904 vty_out (vty
, "PIM Join/Prune debugging is on%s", VTY_NEWLINE
);
4906 else if (argv_find (argv
, argc
, "register", &idx
))
4908 PIM_DO_DEBUG_PIM_REG
;
4909 vty_out (vty
, "PIM Register debugging is on%s", VTY_NEWLINE
);
4913 PIM_DO_DEBUG_PIM_PACKETS
;
4914 vty_out (vty
, "PIM Packet debugging is on %s", VTY_NEWLINE
);
4919 DEFUN (no_debug_pim_packets
,
4920 no_debug_pim_packets_cmd
,
4921 "no debug pim packets [<hello|joins|register>]",
4925 DEBUG_PIM_PACKETS_STR
4926 DEBUG_PIM_HELLO_PACKETS_STR
4927 DEBUG_PIM_J_P_PACKETS_STR
4928 DEBUG_PIM_PIM_REG_PACKETS_STR
)
4931 if (argv_find (argv
, argc
,"hello",&idx
))
4933 PIM_DONT_DEBUG_PIM_HELLO
;
4934 vty_out (vty
, "PIM Hello debugging is off %s", VTY_NEWLINE
);
4936 else if (argv_find (argv
, argc
, "joins", &idx
))
4938 PIM_DONT_DEBUG_PIM_J_P
;
4939 vty_out (vty
, "PIM Join/Prune debugging is off %s", VTY_NEWLINE
);
4941 else if (argv_find (argv
, argc
, "register", &idx
))
4943 PIM_DONT_DEBUG_PIM_REG
;
4944 vty_out (vty
, "PIM Register debugging is off%s", VTY_NEWLINE
);
4947 PIM_DONT_DEBUG_PIM_PACKETS
;
4953 DEFUN (debug_pim_packetdump_send
,
4954 debug_pim_packetdump_send_cmd
,
4955 "debug pim packet-dump send",
4958 DEBUG_PIM_PACKETDUMP_STR
4959 DEBUG_PIM_PACKETDUMP_SEND_STR
)
4961 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND
;
4965 DEFUN (no_debug_pim_packetdump_send
,
4966 no_debug_pim_packetdump_send_cmd
,
4967 "no debug pim packet-dump send",
4971 DEBUG_PIM_PACKETDUMP_STR
4972 DEBUG_PIM_PACKETDUMP_SEND_STR
)
4974 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
4979 DEFUN (debug_pim_packetdump_recv
,
4980 debug_pim_packetdump_recv_cmd
,
4981 "debug pim packet-dump receive",
4984 DEBUG_PIM_PACKETDUMP_STR
4985 DEBUG_PIM_PACKETDUMP_RECV_STR
)
4987 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV
;
4991 DEFUN (no_debug_pim_packetdump_recv
,
4992 no_debug_pim_packetdump_recv_cmd
,
4993 "no debug pim packet-dump receive",
4997 DEBUG_PIM_PACKETDUMP_STR
4998 DEBUG_PIM_PACKETDUMP_RECV_STR
)
5000 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
5005 DEFUN (debug_pim_trace
,
5006 debug_pim_trace_cmd
,
5010 DEBUG_PIM_TRACE_STR
)
5012 PIM_DO_DEBUG_PIM_TRACE
;
5016 DEFUN (no_debug_pim_trace
,
5017 no_debug_pim_trace_cmd
,
5018 "no debug pim trace",
5022 DEBUG_PIM_TRACE_STR
)
5024 PIM_DONT_DEBUG_PIM_TRACE
;
5029 DEFUN (debug_ssmpingd
,
5036 PIM_DO_DEBUG_SSMPINGD
;
5040 DEFUN (no_debug_ssmpingd
,
5041 no_debug_ssmpingd_cmd
,
5042 "no debug ssmpingd",
5048 PIM_DONT_DEBUG_SSMPINGD
;
5053 DEFUN (debug_pim_zebra
,
5054 debug_pim_zebra_cmd
,
5058 DEBUG_PIM_ZEBRA_STR
)
5064 DEFUN (no_debug_pim_zebra
,
5065 no_debug_pim_zebra_cmd
,
5066 "no debug pim zebra",
5070 DEBUG_PIM_ZEBRA_STR
)
5072 PIM_DONT_DEBUG_ZEBRA
;
5083 PIM_DO_DEBUG_MSDP_EVENTS
;
5084 PIM_DO_DEBUG_MSDP_PACKETS
;
5088 DEFUN (no_debug_msdp
,
5095 PIM_DONT_DEBUG_MSDP_EVENTS
;
5096 PIM_DONT_DEBUG_MSDP_PACKETS
;
5100 ALIAS (no_debug_msdp
,
5106 DEFUN (debug_msdp_events
,
5107 debug_msdp_events_cmd
,
5108 "debug msdp events",
5111 DEBUG_MSDP_EVENTS_STR
)
5113 PIM_DO_DEBUG_MSDP_EVENTS
;
5117 DEFUN (no_debug_msdp_events
,
5118 no_debug_msdp_events_cmd
,
5119 "no debug msdp events",
5123 DEBUG_MSDP_EVENTS_STR
)
5125 PIM_DONT_DEBUG_MSDP_EVENTS
;
5129 ALIAS (no_debug_msdp_events
,
5130 undebug_msdp_events_cmd
,
5131 "undebug msdp events",
5134 DEBUG_MSDP_EVENTS_STR
)
5136 DEFUN (debug_msdp_packets
,
5137 debug_msdp_packets_cmd
,
5138 "debug msdp packets",
5141 DEBUG_MSDP_PACKETS_STR
)
5143 PIM_DO_DEBUG_MSDP_PACKETS
;
5147 DEFUN (no_debug_msdp_packets
,
5148 no_debug_msdp_packets_cmd
,
5149 "no debug msdp packets",
5153 DEBUG_MSDP_PACKETS_STR
)
5155 PIM_DONT_DEBUG_MSDP_PACKETS
;
5159 ALIAS (no_debug_msdp_packets
,
5160 undebug_msdp_packets_cmd
,
5161 "undebug msdp packets",
5164 DEBUG_MSDP_PACKETS_STR
)
5166 DEFUN (show_debugging_pim
,
5167 show_debugging_pim_cmd
,
5168 "show debugging pim",
5173 pim_debug_config_write(vty
);
5178 interface_pim_use_src_cmd_worker(struct vty
*vty
, const char *source
)
5181 struct in_addr source_addr
;
5182 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5184 result
= inet_pton(AF_INET
, source
, &source_addr
);
5186 vty_out(vty
, "%% Bad source address %s: errno=%d: %s%s",
5187 source
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
5191 result
= pim_update_source_set(ifp
, source_addr
);
5195 case PIM_IFACE_NOT_FOUND
:
5196 vty_out(vty
, "Pim not enabled on this interface%s", VTY_NEWLINE
);
5198 case PIM_UPDATE_SOURCE_DUP
:
5199 vty_out(vty
, "%% Source already set to %s%s", source
, VTY_NEWLINE
);
5202 vty_out(vty
, "%% Source set failed%s", VTY_NEWLINE
);
5205 return result
?CMD_WARNING
:CMD_SUCCESS
;
5208 DEFUN (interface_pim_use_source
,
5209 interface_pim_use_source_cmd
,
5210 "ip pim use-source A.B.C.D",
5212 "pim multicast routing\n"
5213 "Configure primary IP address\n"
5214 "source ip address\n")
5216 return interface_pim_use_src_cmd_worker (vty
, argv
[3]->arg
);
5219 DEFUN (interface_no_pim_use_source
,
5220 interface_no_pim_use_source_cmd
,
5221 "no ip pim use-source",
5224 "pim multicast routing\n"
5225 "Delete source IP address\n")
5227 return interface_pim_use_src_cmd_worker (vty
, "0.0.0.0");
5231 ip_msdp_peer_cmd_worker (struct vty
*vty
, const char *peer
, const char *local
)
5233 enum pim_msdp_err result
;
5234 struct in_addr peer_addr
;
5235 struct in_addr local_addr
;
5237 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
5239 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s%s",
5240 peer
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
5244 result
= inet_pton(AF_INET
, local
, &local_addr
);
5246 vty_out(vty
, "%% Bad source address %s: errno=%d: %s%s",
5247 local
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
5251 result
= pim_msdp_peer_add(peer_addr
, local_addr
, "default", NULL
/* mp_p */);
5253 case PIM_MSDP_ERR_NONE
:
5255 case PIM_MSDP_ERR_OOM
:
5256 vty_out(vty
, "%% Out of memory%s", VTY_NEWLINE
);
5258 case PIM_MSDP_ERR_PEER_EXISTS
:
5259 vty_out(vty
, "%% Peer exists%s", VTY_NEWLINE
);
5261 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
5262 vty_out(vty
, "%% Only one mesh-group allowed currently%s", VTY_NEWLINE
);
5265 vty_out(vty
, "%% peer add failed%s", VTY_NEWLINE
);
5268 return result
?CMD_WARNING
:CMD_SUCCESS
;
5271 DEFUN_HIDDEN (ip_msdp_peer
,
5273 "ip msdp peer A.B.C.D source A.B.C.D",
5276 "Configure MSDP peer\n"
5278 "Source address for TCP connection\n"
5279 "local ip address\n")
5281 return ip_msdp_peer_cmd_worker (vty
, argv
[3]->arg
, argv
[5]->arg
);
5285 ip_no_msdp_peer_cmd_worker (struct vty
*vty
, const char *peer
)
5287 enum pim_msdp_err result
;
5288 struct in_addr peer_addr
;
5290 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
5292 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s%s",
5293 peer
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
5297 result
= pim_msdp_peer_del(peer_addr
);
5299 case PIM_MSDP_ERR_NONE
:
5301 case PIM_MSDP_ERR_NO_PEER
:
5302 vty_out(vty
, "%% Peer does not exist%s", VTY_NEWLINE
);
5305 vty_out(vty
, "%% peer del failed%s", VTY_NEWLINE
);
5308 return result
?CMD_WARNING
:CMD_SUCCESS
;
5311 DEFUN_HIDDEN (no_ip_msdp_peer
,
5312 no_ip_msdp_peer_cmd
,
5313 "no ip msdp peer A.B.C.D",
5317 "Delete MSDP peer\n"
5318 "peer ip address\n")
5320 return ip_no_msdp_peer_cmd_worker (vty
, argv
[4]->arg
);
5324 ip_msdp_mesh_group_member_cmd_worker(struct vty
*vty
, const char *mg
, const char *mbr
)
5326 enum pim_msdp_err result
;
5327 struct in_addr mbr_ip
;
5329 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
5331 vty_out(vty
, "%% Bad member address %s: errno=%d: %s%s",
5332 mbr
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
5336 result
= pim_msdp_mg_mbr_add(mg
, mbr_ip
);
5338 case PIM_MSDP_ERR_NONE
:
5340 case PIM_MSDP_ERR_OOM
:
5341 vty_out(vty
, "%% Out of memory%s", VTY_NEWLINE
);
5343 case PIM_MSDP_ERR_MG_MBR_EXISTS
:
5344 vty_out(vty
, "%% mesh-group member exists%s", VTY_NEWLINE
);
5346 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
5347 vty_out(vty
, "%% Only one mesh-group allowed currently%s", VTY_NEWLINE
);
5350 vty_out(vty
, "%% member add failed%s", VTY_NEWLINE
);
5353 return result
?CMD_WARNING
:CMD_SUCCESS
;
5356 DEFUN (ip_msdp_mesh_group_member
,
5357 ip_msdp_mesh_group_member_cmd
,
5358 "ip msdp mesh-group WORD member A.B.C.D",
5361 "Configure MSDP mesh-group\n"
5363 "mesh group member\n"
5364 "peer ip address\n")
5366 return ip_msdp_mesh_group_member_cmd_worker(vty
, argv
[3]->arg
, argv
[5]->arg
);
5370 ip_no_msdp_mesh_group_member_cmd_worker(struct vty
*vty
, const char *mg
, const char *mbr
)
5372 enum pim_msdp_err result
;
5373 struct in_addr mbr_ip
;
5375 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
5377 vty_out(vty
, "%% Bad member address %s: errno=%d: %s%s",
5378 mbr
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
5382 result
= pim_msdp_mg_mbr_del(mg
, mbr_ip
);
5384 case PIM_MSDP_ERR_NONE
:
5386 case PIM_MSDP_ERR_NO_MG
:
5387 vty_out(vty
, "%% mesh-group does not exist%s", VTY_NEWLINE
);
5389 case PIM_MSDP_ERR_NO_MG_MBR
:
5390 vty_out(vty
, "%% mesh-group member does not exist%s", VTY_NEWLINE
);
5393 vty_out(vty
, "%% mesh-group member del failed%s", VTY_NEWLINE
);
5396 return result
?CMD_WARNING
:CMD_SUCCESS
;
5398 DEFUN (no_ip_msdp_mesh_group_member
,
5399 no_ip_msdp_mesh_group_member_cmd
,
5400 "no ip msdp mesh-group WORD member A.B.C.D",
5404 "Delete MSDP mesh-group member\n"
5406 "mesh group member\n"
5407 "peer ip address\n")
5409 return ip_no_msdp_mesh_group_member_cmd_worker(vty
, argv
[4]->arg
, argv
[6]->arg
);
5413 ip_msdp_mesh_group_source_cmd_worker(struct vty
*vty
, const char *mg
, const char *src
)
5415 enum pim_msdp_err result
;
5416 struct in_addr src_ip
;
5418 result
= inet_pton(AF_INET
, src
, &src_ip
);
5420 vty_out(vty
, "%% Bad source address %s: errno=%d: %s%s",
5421 src
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
5425 result
= pim_msdp_mg_src_add(mg
, src_ip
);
5427 case PIM_MSDP_ERR_NONE
:
5429 case PIM_MSDP_ERR_OOM
:
5430 vty_out(vty
, "%% Out of memory%s", VTY_NEWLINE
);
5432 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
5433 vty_out(vty
, "%% Only one mesh-group allowed currently%s", VTY_NEWLINE
);
5436 vty_out(vty
, "%% source add failed%s", VTY_NEWLINE
);
5439 return result
?CMD_WARNING
:CMD_SUCCESS
;
5443 DEFUN (ip_msdp_mesh_group_source
,
5444 ip_msdp_mesh_group_source_cmd
,
5445 "ip msdp mesh-group WORD source A.B.C.D",
5448 "Configure MSDP mesh-group\n"
5450 "mesh group local address\n"
5451 "source ip address for the TCP connection\n")
5453 return ip_msdp_mesh_group_source_cmd_worker(vty
, argv
[3]->arg
, argv
[5]->arg
);
5457 ip_no_msdp_mesh_group_source_cmd_worker(struct vty
*vty
, const char *mg
)
5459 enum pim_msdp_err result
;
5461 result
= pim_msdp_mg_src_del(mg
);
5463 case PIM_MSDP_ERR_NONE
:
5465 case PIM_MSDP_ERR_NO_MG
:
5466 vty_out(vty
, "%% mesh-group does not exist%s", VTY_NEWLINE
);
5469 vty_out(vty
, "%% mesh-group source del failed%s", VTY_NEWLINE
);
5472 return result
?CMD_WARNING
:CMD_SUCCESS
;
5476 ip_no_msdp_mesh_group_cmd_worker(struct vty
*vty
, const char *mg
)
5478 enum pim_msdp_err result
;
5480 result
= pim_msdp_mg_del(mg
);
5482 case PIM_MSDP_ERR_NONE
:
5484 case PIM_MSDP_ERR_NO_MG
:
5485 vty_out(vty
, "%% mesh-group does not exist%s", VTY_NEWLINE
);
5488 vty_out(vty
, "%% mesh-group source del failed%s", VTY_NEWLINE
);
5491 return result
? CMD_WARNING
: CMD_SUCCESS
;
5494 DEFUN (no_ip_msdp_mesh_group_source
,
5495 no_ip_msdp_mesh_group_source_cmd
,
5496 "no ip msdp mesh-group WORD source [A.B.C.D]",
5500 "Delete MSDP mesh-group source\n"
5502 "mesh group source\n"
5503 "mesh group local address\n")
5506 return ip_no_msdp_mesh_group_cmd_worker(vty
, argv
[6]->arg
);
5508 return ip_no_msdp_mesh_group_source_cmd_worker(vty
, argv
[4]->arg
);
5512 print_empty_json_obj(struct vty
*vty
)
5515 json
= json_object_new_object();
5516 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
5517 json_object_free(json
);
5521 ip_msdp_show_mesh_group(struct vty
*vty
, u_char uj
)
5523 struct listnode
*mbrnode
;
5524 struct pim_msdp_mg_mbr
*mbr
;
5525 struct pim_msdp_mg
*mg
= msdp
->mg
;
5526 char mbr_str
[INET_ADDRSTRLEN
];
5527 char src_str
[INET_ADDRSTRLEN
];
5528 char state_str
[PIM_MSDP_STATE_STRLEN
];
5529 enum pim_msdp_peer_state state
;
5530 json_object
*json
= NULL
;
5531 json_object
*json_mg_row
= NULL
;
5532 json_object
*json_members
= NULL
;
5533 json_object
*json_row
= NULL
;
5537 print_empty_json_obj(vty
);
5541 pim_inet4_dump("<source?>", mg
->src_ip
, src_str
, sizeof(src_str
));
5543 json
= json_object_new_object();
5544 /* currently there is only one mesh group but we should still make
5545 * it a dict with mg-name as key */
5546 json_mg_row
= json_object_new_object();
5547 json_object_string_add(json_mg_row
, "name", mg
->mesh_group_name
);
5548 json_object_string_add(json_mg_row
, "source", src_str
);
5550 vty_out(vty
, "Mesh group : %s%s", mg
->mesh_group_name
, VTY_NEWLINE
);
5551 vty_out(vty
, " Source : %s%s", src_str
, VTY_NEWLINE
);
5552 vty_out(vty
, " Member State%s", VTY_NEWLINE
);
5555 for (ALL_LIST_ELEMENTS_RO(mg
->mbr_list
, mbrnode
, mbr
)) {
5556 pim_inet4_dump("<mbr?>", mbr
->mbr_ip
, mbr_str
, sizeof(mbr_str
));
5558 state
= mbr
->mp
->state
;
5560 state
= PIM_MSDP_DISABLED
;
5562 pim_msdp_state_dump(state
, state_str
, sizeof(state_str
));
5564 json_row
= json_object_new_object();
5565 json_object_string_add(json_row
, "member", mbr_str
);
5566 json_object_string_add(json_row
, "state", state_str
);
5567 if (!json_members
) {
5568 json_members
= json_object_new_object();
5569 json_object_object_add(json_mg_row
, "members", json_members
);
5571 json_object_object_add(json_members
, mbr_str
, json_row
);
5573 vty_out(vty
, " %-15s %11s%s",
5574 mbr_str
, state_str
, VTY_NEWLINE
);
5579 json_object_object_add(json
, mg
->mesh_group_name
, json_mg_row
);
5580 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
5581 json_object_free(json
);
5585 DEFUN (show_ip_msdp_mesh_group
,
5586 show_ip_msdp_mesh_group_cmd
,
5587 "show ip msdp mesh-group [json]",
5591 "MSDP mesh-group information\n"
5592 "JavaScript Object Notation\n")
5594 u_char uj
= use_json(argc
, argv
);
5595 ip_msdp_show_mesh_group(vty
, uj
);
5601 ip_msdp_show_peers(struct vty
*vty
, u_char uj
)
5603 struct listnode
*mpnode
;
5604 struct pim_msdp_peer
*mp
;
5605 char peer_str
[INET_ADDRSTRLEN
];
5606 char local_str
[INET_ADDRSTRLEN
];
5607 char state_str
[PIM_MSDP_STATE_STRLEN
];
5608 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
5610 json_object
*json
= NULL
;
5611 json_object
*json_row
= NULL
;
5615 json
= json_object_new_object();
5617 vty_out(vty
, "Peer Local State Uptime SaCnt%s", VTY_NEWLINE
);
5620 for (ALL_LIST_ELEMENTS_RO(msdp
->peer_list
, mpnode
, mp
)) {
5621 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
5622 now
= pim_time_monotonic_sec();
5623 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- mp
->uptime
);
5625 strcpy(timebuf
, "-");
5627 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
5628 pim_inet4_dump("<local?>", mp
->local
, local_str
, sizeof(local_str
));
5629 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
5631 json_row
= json_object_new_object();
5632 json_object_string_add(json_row
, "peer", peer_str
);
5633 json_object_string_add(json_row
, "local", local_str
);
5634 json_object_string_add(json_row
, "state", state_str
);
5635 json_object_string_add(json_row
, "upTime", timebuf
);
5636 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
5637 json_object_object_add(json
, peer_str
, json_row
);
5639 vty_out(vty
, "%-15s %15s %11s %8s %6d%s",
5640 peer_str
, local_str
, state_str
,
5641 timebuf
, mp
->sa_cnt
, VTY_NEWLINE
);
5646 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
5647 json_object_free(json
);
5652 ip_msdp_show_peers_detail(struct vty
*vty
, const char *peer
, u_char uj
)
5654 struct listnode
*mpnode
;
5655 struct pim_msdp_peer
*mp
;
5656 char peer_str
[INET_ADDRSTRLEN
];
5657 char local_str
[INET_ADDRSTRLEN
];
5658 char state_str
[PIM_MSDP_STATE_STRLEN
];
5659 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
5660 char katimer
[PIM_MSDP_TIMER_STRLEN
];
5661 char crtimer
[PIM_MSDP_TIMER_STRLEN
];
5662 char holdtimer
[PIM_MSDP_TIMER_STRLEN
];
5664 json_object
*json
= NULL
;
5665 json_object
*json_row
= NULL
;
5668 json
= json_object_new_object();
5671 for (ALL_LIST_ELEMENTS_RO(msdp
->peer_list
, mpnode
, mp
)) {
5672 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
5673 if (strcmp(peer
, "detail") &&
5674 strcmp(peer
, peer_str
))
5677 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
5678 now
= pim_time_monotonic_sec();
5679 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- mp
->uptime
);
5681 strcpy(timebuf
, "-");
5683 pim_inet4_dump("<local?>", mp
->local
, local_str
, sizeof(local_str
));
5684 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
5685 pim_time_timer_to_hhmmss(katimer
, sizeof(katimer
), mp
->ka_timer
);
5686 pim_time_timer_to_hhmmss(crtimer
, sizeof(crtimer
), mp
->cr_timer
);
5687 pim_time_timer_to_hhmmss(holdtimer
, sizeof(holdtimer
), mp
->hold_timer
);
5690 json_row
= json_object_new_object();
5691 json_object_string_add(json_row
, "peer", peer_str
);
5692 json_object_string_add(json_row
, "local", local_str
);
5693 json_object_string_add(json_row
, "meshGroupName", mp
->mesh_group_name
);
5694 json_object_string_add(json_row
, "state", state_str
);
5695 json_object_string_add(json_row
, "upTime", timebuf
);
5696 json_object_string_add(json_row
, "keepAliveTimer", katimer
);
5697 json_object_string_add(json_row
, "connRetryTimer", crtimer
);
5698 json_object_string_add(json_row
, "holdTimer", holdtimer
);
5699 json_object_string_add(json_row
, "lastReset", mp
->last_reset
);
5700 json_object_int_add(json_row
, "connAttempts", mp
->conn_attempts
);
5701 json_object_int_add(json_row
, "establishedChanges", mp
->est_flaps
);
5702 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
5703 json_object_int_add(json_row
, "kaSent", mp
->ka_tx_cnt
);
5704 json_object_int_add(json_row
, "kaRcvd", mp
->ka_rx_cnt
);
5705 json_object_int_add(json_row
, "saSent", mp
->sa_tx_cnt
);
5706 json_object_int_add(json_row
, "saRcvd", mp
->sa_rx_cnt
);
5707 json_object_object_add(json
, peer_str
, json_row
);
5709 vty_out(vty
, "Peer : %s%s", peer_str
, VTY_NEWLINE
);
5710 vty_out(vty
, " Local : %s%s", local_str
, VTY_NEWLINE
);
5711 vty_out(vty
, " Mesh Group : %s%s", mp
->mesh_group_name
, VTY_NEWLINE
);
5712 vty_out(vty
, " State : %s%s", state_str
, VTY_NEWLINE
);
5713 vty_out(vty
, " Uptime : %s%s", timebuf
, VTY_NEWLINE
);
5715 vty_out(vty
, " Keepalive Timer : %s%s", katimer
, VTY_NEWLINE
);
5716 vty_out(vty
, " Conn Retry Timer : %s%s", crtimer
, VTY_NEWLINE
);
5717 vty_out(vty
, " Hold Timer : %s%s", holdtimer
, VTY_NEWLINE
);
5718 vty_out(vty
, " Last Reset : %s%s", mp
->last_reset
, VTY_NEWLINE
);
5719 vty_out(vty
, " Conn Attempts : %d%s", mp
->conn_attempts
, VTY_NEWLINE
);
5720 vty_out(vty
, " Established Changes : %d%s", mp
->est_flaps
, VTY_NEWLINE
);
5721 vty_out(vty
, " SA Count : %d%s", mp
->sa_cnt
, VTY_NEWLINE
);
5722 vty_out(vty
, " Statistics :%s", VTY_NEWLINE
);
5723 vty_out(vty
, " Sent Rcvd%s", VTY_NEWLINE
);
5724 vty_out(vty
, " Keepalives : %10d %10d%s",
5725 mp
->ka_tx_cnt
, mp
->ka_rx_cnt
, VTY_NEWLINE
);
5726 vty_out(vty
, " SAs : %10d %10d%s",
5727 mp
->sa_tx_cnt
, mp
->sa_rx_cnt
, VTY_NEWLINE
);
5728 vty_out(vty
, "%s", VTY_NEWLINE
);
5733 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
5734 json_object_free(json
);
5738 DEFUN (show_ip_msdp_peer_detail
,
5739 show_ip_msdp_peer_detail_cmd
,
5740 "show ip msdp peer [detail|A.B.C.D] [json]",
5744 "MSDP peer information\n"
5747 "JavaScript Object Notation\n")
5749 u_char uj
= use_json(argc
, argv
);
5754 ip_msdp_show_peers_detail(vty
, argv
[4]->arg
, uj
);
5756 ip_msdp_show_peers(vty
, uj
);
5762 ip_msdp_show_sa(struct vty
*vty
, u_char uj
)
5764 struct listnode
*sanode
;
5765 struct pim_msdp_sa
*sa
;
5766 char src_str
[INET_ADDRSTRLEN
];
5767 char grp_str
[INET_ADDRSTRLEN
];
5768 char rp_str
[INET_ADDRSTRLEN
];
5769 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
5773 json_object
*json
= NULL
;
5774 json_object
*json_group
= NULL
;
5775 json_object
*json_row
= NULL
;
5778 json
= json_object_new_object();
5780 vty_out(vty
, "Source Group RP Local SPT Uptime%s", VTY_NEWLINE
);
5783 for (ALL_LIST_ELEMENTS_RO(msdp
->sa_list
, sanode
, sa
)) {
5784 now
= pim_time_monotonic_sec();
5785 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
5786 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
5787 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
5788 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
5789 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
5791 strcpy(spt_str
, "yes");
5793 strcpy(spt_str
, "no");
5796 strcpy(rp_str
, "-");
5797 strcpy(spt_str
, "-");
5799 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
5800 strcpy(local_str
, "yes");
5802 strcpy(local_str
, "no");
5805 json_object_object_get_ex(json
, grp_str
, &json_group
);
5808 json_group
= json_object_new_object();
5809 json_object_object_add(json
, grp_str
, json_group
);
5812 json_row
= json_object_new_object();
5813 json_object_string_add(json_row
, "source", src_str
);
5814 json_object_string_add(json_row
, "group", grp_str
);
5815 json_object_string_add(json_row
, "rp", rp_str
);
5816 json_object_string_add(json_row
, "local", local_str
);
5817 json_object_string_add(json_row
, "sptSetup", spt_str
);
5818 json_object_string_add(json_row
, "upTime", timebuf
);
5819 json_object_object_add(json_group
, src_str
, json_row
);
5821 vty_out(vty
, "%-15s %15s %15s %5c %3c %8s%s",
5822 src_str
, grp_str
, rp_str
, local_str
[0], spt_str
[0], timebuf
, VTY_NEWLINE
);
5828 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
5829 json_object_free(json
);
5834 ip_msdp_show_sa_entry_detail(struct pim_msdp_sa
*sa
, const char *src_str
,
5835 const char *grp_str
, struct vty
*vty
,
5836 u_char uj
, json_object
*json
)
5838 char rp_str
[INET_ADDRSTRLEN
];
5839 char peer_str
[INET_ADDRSTRLEN
];
5840 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
5843 char statetimer
[PIM_MSDP_TIMER_STRLEN
];
5845 json_object
*json_group
= NULL
;
5846 json_object
*json_row
= NULL
;
5848 now
= pim_time_monotonic_sec();
5849 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
5850 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
5851 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
5852 pim_inet4_dump("<peer?>", sa
->peer
, peer_str
, sizeof(peer_str
));
5854 strcpy(spt_str
, "yes");
5856 strcpy(spt_str
, "no");
5859 strcpy(rp_str
, "-");
5860 strcpy(peer_str
, "-");
5861 strcpy(spt_str
, "-");
5863 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
5864 strcpy(local_str
, "yes");
5866 strcpy(local_str
, "no");
5868 pim_time_timer_to_hhmmss(statetimer
, sizeof(statetimer
), sa
->sa_state_timer
);
5870 json_object_object_get_ex(json
, grp_str
, &json_group
);
5873 json_group
= json_object_new_object();
5874 json_object_object_add(json
, grp_str
, json_group
);
5877 json_row
= json_object_new_object();
5878 json_object_string_add(json_row
, "source", src_str
);
5879 json_object_string_add(json_row
, "group", grp_str
);
5880 json_object_string_add(json_row
, "rp", rp_str
);
5881 json_object_string_add(json_row
, "local", local_str
);
5882 json_object_string_add(json_row
, "sptSetup", spt_str
);
5883 json_object_string_add(json_row
, "upTime", timebuf
);
5884 json_object_string_add(json_row
, "stateTimer", statetimer
);
5885 json_object_object_add(json_group
, src_str
, json_row
);
5887 vty_out(vty
, "SA : %s%s", sa
->sg_str
, VTY_NEWLINE
);
5888 vty_out(vty
, " RP : %s%s", rp_str
, VTY_NEWLINE
);
5889 vty_out(vty
, " Peer : %s%s", peer_str
, VTY_NEWLINE
);
5890 vty_out(vty
, " Local : %s%s", local_str
, VTY_NEWLINE
);
5891 vty_out(vty
, " SPT Setup : %s%s", spt_str
, VTY_NEWLINE
);
5892 vty_out(vty
, " Uptime : %s%s", timebuf
, VTY_NEWLINE
);
5893 vty_out(vty
, " State Timer : %s%s", statetimer
, VTY_NEWLINE
);
5894 vty_out(vty
, "%s", VTY_NEWLINE
);
5899 ip_msdp_show_sa_detail(struct vty
*vty
, u_char uj
)
5901 struct listnode
*sanode
;
5902 struct pim_msdp_sa
*sa
;
5903 char src_str
[INET_ADDRSTRLEN
];
5904 char grp_str
[INET_ADDRSTRLEN
];
5905 json_object
*json
= NULL
;
5908 json
= json_object_new_object();
5911 for (ALL_LIST_ELEMENTS_RO(msdp
->sa_list
, sanode
, sa
)) {
5912 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
5913 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
5914 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
, uj
, json
);
5918 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
5919 json_object_free(json
);
5923 DEFUN (show_ip_msdp_sa_detail
,
5924 show_ip_msdp_sa_detail_cmd
,
5925 "show ip msdp sa detail [json]",
5929 "MSDP active-source information\n"
5931 "JavaScript Object Notation\n")
5933 u_char uj
= use_json(argc
, argv
);
5934 ip_msdp_show_sa_detail(vty
, uj
);
5940 ip_msdp_show_sa_addr(struct vty
*vty
, const char *addr
, u_char uj
)
5942 struct listnode
*sanode
;
5943 struct pim_msdp_sa
*sa
;
5944 char src_str
[INET_ADDRSTRLEN
];
5945 char grp_str
[INET_ADDRSTRLEN
];
5946 json_object
*json
= NULL
;
5949 json
= json_object_new_object();
5952 for (ALL_LIST_ELEMENTS_RO(msdp
->sa_list
, sanode
, sa
)) {
5953 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
5954 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
5955 if (!strcmp(addr
, src_str
) || !strcmp(addr
, grp_str
)) {
5956 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
, uj
, json
);
5961 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
5962 json_object_free(json
);
5967 ip_msdp_show_sa_sg(struct vty
*vty
, const char *src
, const char *grp
, u_char uj
)
5969 struct listnode
*sanode
;
5970 struct pim_msdp_sa
*sa
;
5971 char src_str
[INET_ADDRSTRLEN
];
5972 char grp_str
[INET_ADDRSTRLEN
];
5973 json_object
*json
= NULL
;
5976 json
= json_object_new_object();
5979 for (ALL_LIST_ELEMENTS_RO(msdp
->sa_list
, sanode
, sa
)) {
5980 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
5981 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
5982 if (!strcmp(src
, src_str
) && !strcmp(grp
, grp_str
)) {
5983 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
, uj
, json
);
5988 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
5989 json_object_free(json
);
5993 DEFUN (show_ip_msdp_sa_sg
,
5994 show_ip_msdp_sa_sg_cmd
,
5995 "show ip msdp sa [A.B.C.D [A.B.C.D]] [json]",
5999 "MSDP active-source information\n"
6000 "source or group ip\n"
6002 "JavaScript Object Notation\n")
6004 u_char uj
= use_json(argc
, argv
);
6009 ip_msdp_show_sa_sg(vty
, argv
[4]->arg
, argv
[5]->arg
, uj
);
6011 ip_msdp_show_sa_addr(vty
, argv
[4]->arg
, uj
);
6013 ip_msdp_show_sa(vty
, uj
);
6020 install_node (&pim_global_node
, pim_global_config_write
); /* PIM_NODE */
6021 install_node (&interface_node
, pim_interface_config_write
); /* INTERFACE_NODE */
6024 install_node (&debug_node
, pim_debug_config_write
);
6026 install_element (CONFIG_NODE
, &ip_multicast_routing_cmd
);
6027 install_element (CONFIG_NODE
, &no_ip_multicast_routing_cmd
);
6028 install_element (CONFIG_NODE
, &ip_pim_rp_cmd
);
6029 install_element (CONFIG_NODE
, &no_ip_pim_rp_cmd
);
6030 install_element (CONFIG_NODE
, &ip_pim_rp_prefix_list_cmd
);
6031 install_element (CONFIG_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
6032 install_element (CONFIG_NODE
, &ip_pim_register_suppress_cmd
);
6033 install_element (CONFIG_NODE
, &no_ip_pim_register_suppress_cmd
);
6034 install_element (CONFIG_NODE
, &ip_pim_joinprune_time_cmd
);
6035 install_element (CONFIG_NODE
, &no_ip_pim_joinprune_time_cmd
);
6036 install_element (CONFIG_NODE
, &ip_pim_keep_alive_cmd
);
6037 install_element (CONFIG_NODE
, &no_ip_pim_keep_alive_cmd
);
6038 install_element (CONFIG_NODE
, &ip_pim_packets_cmd
);
6039 install_element (CONFIG_NODE
, &no_ip_pim_packets_cmd
);
6040 install_element (CONFIG_NODE
, &ip_ssmpingd_cmd
);
6041 install_element (CONFIG_NODE
, &no_ip_ssmpingd_cmd
);
6042 install_element (CONFIG_NODE
, &ip_msdp_peer_cmd
);
6043 install_element (CONFIG_NODE
, &no_ip_msdp_peer_cmd
);
6045 install_element (INTERFACE_NODE
, &interface_ip_igmp_cmd
);
6046 install_element (INTERFACE_NODE
, &interface_no_ip_igmp_cmd
);
6047 install_element (INTERFACE_NODE
, &interface_ip_igmp_join_cmd
);
6048 install_element (INTERFACE_NODE
, &interface_no_ip_igmp_join_cmd
);
6049 install_element (INTERFACE_NODE
, &interface_ip_igmp_version_cmd
);
6050 install_element (INTERFACE_NODE
, &interface_no_ip_igmp_version_cmd
);
6051 install_element (INTERFACE_NODE
, &interface_ip_igmp_query_interval_cmd
);
6052 install_element (INTERFACE_NODE
, &interface_no_ip_igmp_query_interval_cmd
);
6053 install_element (INTERFACE_NODE
, &interface_ip_igmp_query_max_response_time_cmd
);
6054 install_element (INTERFACE_NODE
, &interface_no_ip_igmp_query_max_response_time_cmd
);
6055 install_element (INTERFACE_NODE
, &interface_ip_igmp_query_max_response_time_dsec_cmd
);
6056 install_element (INTERFACE_NODE
, &interface_no_ip_igmp_query_max_response_time_dsec_cmd
);
6057 install_element (INTERFACE_NODE
, &interface_ip_pim_ssm_cmd
);
6058 install_element (INTERFACE_NODE
, &interface_no_ip_pim_ssm_cmd
);
6059 install_element (INTERFACE_NODE
, &interface_ip_pim_sm_cmd
);
6060 install_element (INTERFACE_NODE
, &interface_no_ip_pim_sm_cmd
);
6061 install_element (INTERFACE_NODE
, &interface_ip_pim_drprio_cmd
);
6062 install_element (INTERFACE_NODE
, &interface_no_ip_pim_drprio_cmd
);
6063 install_element (INTERFACE_NODE
, &interface_ip_pim_hello_cmd
);
6064 install_element (INTERFACE_NODE
, &interface_no_ip_pim_hello_cmd
);
6066 // Static mroutes NEB
6067 install_element (INTERFACE_NODE
, &interface_ip_mroute_cmd
);
6068 install_element (INTERFACE_NODE
, &interface_ip_mroute_source_cmd
);
6069 install_element (INTERFACE_NODE
, &interface_no_ip_mroute_cmd
);
6070 install_element (INTERFACE_NODE
, &interface_no_ip_mroute_source_cmd
);
6072 install_element (VIEW_NODE
, &show_ip_igmp_interface_cmd
);
6073 install_element (VIEW_NODE
, &show_ip_igmp_join_cmd
);
6074 install_element (VIEW_NODE
, &show_ip_igmp_groups_cmd
);
6075 install_element (VIEW_NODE
, &show_ip_igmp_groups_retransmissions_cmd
);
6076 install_element (VIEW_NODE
, &show_ip_igmp_sources_cmd
);
6077 install_element (VIEW_NODE
, &show_ip_igmp_sources_retransmissions_cmd
);
6078 install_element (VIEW_NODE
, &show_ip_pim_assert_cmd
);
6079 install_element (VIEW_NODE
, &show_ip_pim_assert_internal_cmd
);
6080 install_element (VIEW_NODE
, &show_ip_pim_assert_metric_cmd
);
6081 install_element (VIEW_NODE
, &show_ip_pim_assert_winner_metric_cmd
);
6082 install_element (VIEW_NODE
, &show_ip_pim_interface_cmd
);
6083 install_element (VIEW_NODE
, &show_ip_pim_join_cmd
);
6084 install_element (VIEW_NODE
, &show_ip_pim_local_membership_cmd
);
6085 install_element (VIEW_NODE
, &show_ip_pim_neighbor_cmd
);
6086 install_element (VIEW_NODE
, &show_ip_pim_rpf_cmd
);
6087 install_element (VIEW_NODE
, &show_ip_pim_secondary_cmd
);
6088 install_element (VIEW_NODE
, &show_ip_pim_state_cmd
);
6089 install_element (VIEW_NODE
, &show_ip_pim_upstream_cmd
);
6090 install_element (VIEW_NODE
, &show_ip_pim_upstream_join_desired_cmd
);
6091 install_element (VIEW_NODE
, &show_ip_pim_upstream_rpf_cmd
);
6092 install_element (VIEW_NODE
, &show_ip_pim_rp_cmd
);
6093 install_element (VIEW_NODE
, &show_ip_multicast_cmd
);
6094 install_element (VIEW_NODE
, &show_ip_mroute_cmd
);
6095 install_element (VIEW_NODE
, &show_ip_mroute_count_cmd
);
6096 install_element (VIEW_NODE
, &show_ip_rib_cmd
);
6097 install_element (VIEW_NODE
, &show_ip_ssmpingd_cmd
);
6098 install_element (VIEW_NODE
, &show_debugging_pim_cmd
);
6100 install_element (ENABLE_NODE
, &clear_ip_interfaces_cmd
);
6101 install_element (ENABLE_NODE
, &clear_ip_igmp_interfaces_cmd
);
6102 install_element (ENABLE_NODE
, &clear_ip_mroute_cmd
);
6103 install_element (ENABLE_NODE
, &clear_ip_pim_interfaces_cmd
);
6104 install_element (ENABLE_NODE
, &clear_ip_pim_oil_cmd
);
6106 install_element (ENABLE_NODE
, &debug_igmp_cmd
);
6107 install_element (ENABLE_NODE
, &no_debug_igmp_cmd
);
6108 install_element (ENABLE_NODE
, &debug_igmp_events_cmd
);
6109 install_element (ENABLE_NODE
, &no_debug_igmp_events_cmd
);
6110 install_element (ENABLE_NODE
, &debug_igmp_packets_cmd
);
6111 install_element (ENABLE_NODE
, &no_debug_igmp_packets_cmd
);
6112 install_element (ENABLE_NODE
, &debug_igmp_trace_cmd
);
6113 install_element (ENABLE_NODE
, &no_debug_igmp_trace_cmd
);
6114 install_element (ENABLE_NODE
, &debug_mroute_cmd
);
6115 install_element (ENABLE_NODE
, &debug_mroute_detail_cmd
);
6116 install_element (ENABLE_NODE
, &no_debug_mroute_cmd
);
6117 install_element (ENABLE_NODE
, &no_debug_mroute_detail_cmd
);
6118 install_element (ENABLE_NODE
, &debug_static_cmd
);
6119 install_element (ENABLE_NODE
, &no_debug_static_cmd
);
6120 install_element (ENABLE_NODE
, &debug_pim_cmd
);
6121 install_element (ENABLE_NODE
, &no_debug_pim_cmd
);
6122 install_element (ENABLE_NODE
, &debug_pim_events_cmd
);
6123 install_element (ENABLE_NODE
, &no_debug_pim_events_cmd
);
6124 install_element (ENABLE_NODE
, &debug_pim_packets_cmd
);
6125 install_element (ENABLE_NODE
, &no_debug_pim_packets_cmd
);
6126 install_element (ENABLE_NODE
, &debug_pim_packetdump_send_cmd
);
6127 install_element (ENABLE_NODE
, &no_debug_pim_packetdump_send_cmd
);
6128 install_element (ENABLE_NODE
, &debug_pim_packetdump_recv_cmd
);
6129 install_element (ENABLE_NODE
, &no_debug_pim_packetdump_recv_cmd
);
6130 install_element (ENABLE_NODE
, &debug_pim_trace_cmd
);
6131 install_element (ENABLE_NODE
, &no_debug_pim_trace_cmd
);
6132 install_element (ENABLE_NODE
, &debug_ssmpingd_cmd
);
6133 install_element (ENABLE_NODE
, &no_debug_ssmpingd_cmd
);
6134 install_element (ENABLE_NODE
, &debug_pim_zebra_cmd
);
6135 install_element (ENABLE_NODE
, &no_debug_pim_zebra_cmd
);
6136 install_element (ENABLE_NODE
, &debug_msdp_cmd
);
6137 install_element (ENABLE_NODE
, &no_debug_msdp_cmd
);
6138 install_element (ENABLE_NODE
, &undebug_msdp_cmd
);
6139 install_element (ENABLE_NODE
, &debug_msdp_events_cmd
);
6140 install_element (ENABLE_NODE
, &no_debug_msdp_events_cmd
);
6141 install_element (ENABLE_NODE
, &undebug_msdp_events_cmd
);
6142 install_element (ENABLE_NODE
, &debug_msdp_packets_cmd
);
6143 install_element (ENABLE_NODE
, &no_debug_msdp_packets_cmd
);
6144 install_element (ENABLE_NODE
, &undebug_msdp_packets_cmd
);
6146 install_element (CONFIG_NODE
, &debug_igmp_cmd
);
6147 install_element (CONFIG_NODE
, &no_debug_igmp_cmd
);
6148 install_element (CONFIG_NODE
, &debug_igmp_events_cmd
);
6149 install_element (CONFIG_NODE
, &no_debug_igmp_events_cmd
);
6150 install_element (CONFIG_NODE
, &debug_igmp_packets_cmd
);
6151 install_element (CONFIG_NODE
, &no_debug_igmp_packets_cmd
);
6152 install_element (CONFIG_NODE
, &debug_igmp_trace_cmd
);
6153 install_element (CONFIG_NODE
, &no_debug_igmp_trace_cmd
);
6154 install_element (CONFIG_NODE
, &debug_mroute_cmd
);
6155 install_element (CONFIG_NODE
, &debug_mroute_detail_cmd
);
6156 install_element (CONFIG_NODE
, &no_debug_mroute_cmd
);
6157 install_element (CONFIG_NODE
, &no_debug_mroute_detail_cmd
);
6158 install_element (CONFIG_NODE
, &debug_static_cmd
);
6159 install_element (CONFIG_NODE
, &no_debug_static_cmd
);
6160 install_element (CONFIG_NODE
, &debug_pim_cmd
);
6161 install_element (CONFIG_NODE
, &no_debug_pim_cmd
);
6162 install_element (CONFIG_NODE
, &debug_pim_events_cmd
);
6163 install_element (CONFIG_NODE
, &no_debug_pim_events_cmd
);
6164 install_element (CONFIG_NODE
, &debug_pim_packets_cmd
);
6165 install_element (CONFIG_NODE
, &no_debug_pim_packets_cmd
);
6166 install_element (CONFIG_NODE
, &debug_pim_trace_cmd
);
6167 install_element (CONFIG_NODE
, &no_debug_pim_trace_cmd
);
6168 install_element (CONFIG_NODE
, &debug_ssmpingd_cmd
);
6169 install_element (CONFIG_NODE
, &no_debug_ssmpingd_cmd
);
6170 install_element (CONFIG_NODE
, &debug_pim_zebra_cmd
);
6171 install_element (CONFIG_NODE
, &no_debug_pim_zebra_cmd
);
6172 install_element (CONFIG_NODE
, &debug_msdp_cmd
);
6173 install_element (CONFIG_NODE
, &no_debug_msdp_cmd
);
6174 install_element (CONFIG_NODE
, &undebug_msdp_cmd
);
6175 install_element (CONFIG_NODE
, &debug_msdp_events_cmd
);
6176 install_element (CONFIG_NODE
, &no_debug_msdp_events_cmd
);
6177 install_element (CONFIG_NODE
, &undebug_msdp_events_cmd
);
6178 install_element (CONFIG_NODE
, &debug_msdp_packets_cmd
);
6179 install_element (CONFIG_NODE
, &no_debug_msdp_packets_cmd
);
6180 install_element (CONFIG_NODE
, &undebug_msdp_packets_cmd
);
6181 install_element (CONFIG_NODE
, &ip_msdp_mesh_group_member_cmd
);
6182 install_element (CONFIG_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
6183 install_element (CONFIG_NODE
, &ip_msdp_mesh_group_source_cmd
);
6184 install_element (CONFIG_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
6185 install_element (VIEW_NODE
, &show_ip_msdp_peer_detail_cmd
);
6186 install_element (VIEW_NODE
, &show_ip_msdp_sa_detail_cmd
);
6187 install_element (VIEW_NODE
, &show_ip_msdp_sa_sg_cmd
);
6188 install_element (VIEW_NODE
, &show_ip_msdp_mesh_group_cmd
);
6189 install_element (INTERFACE_NODE
, &interface_pim_use_source_cmd
);
6190 install_element (INTERFACE_NODE
, &interface_no_pim_use_source_cmd
);