3 Copyright (C) 2008 Everton da Silva Marques
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; see the file COPYING; if not, write to the
17 Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
31 #include "pim_mroute.h"
33 #include "pim_iface.h"
35 #include "pim_mroute.h"
38 #include "pim_igmpv3.h"
43 #include "pim_neighbor.h"
45 #include "pim_ifchannel.h"
46 #include "pim_hello.h"
48 #include "pim_upstream.h"
50 #include "pim_macro.h"
51 #include "pim_ssmpingd.h"
52 #include "pim_zebra.h"
53 #include "pim_static.h"
55 #include "pim_zlookup.h"
58 static struct cmd_node pim_global_node
= {
64 static struct cmd_node interface_node
= {
70 static struct cmd_node debug_node
=
77 static void pim_if_membership_clear(struct interface
*ifp
)
79 struct pim_interface
*pim_ifp
;
84 if (PIM_IF_TEST_PIM(pim_ifp
->options
) &&
85 PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
89 pim_ifchannel_membership_clear(ifp
);
93 When PIM is disabled on interface, IGMPv3 local membership
94 information is not injected into PIM interface state.
96 The function pim_if_membership_refresh() fetches all IGMPv3 local
97 membership information into PIM. It is intented to be called
98 whenever PIM is enabled on the interface in order to collect missed
99 local membership information.
101 static void pim_if_membership_refresh(struct interface
*ifp
)
103 struct pim_interface
*pim_ifp
;
104 struct listnode
*sock_node
;
105 struct igmp_sock
*igmp
;
110 if (!PIM_IF_TEST_PIM(pim_ifp
->options
))
112 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
))
116 First clear off membership from all PIM (S,G) entries on the
120 pim_ifchannel_membership_clear(ifp
);
123 Then restore PIM (S,G) membership from all IGMPv3 (S,G) entries on
127 /* scan igmp sockets */
128 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
129 struct listnode
*grpnode
;
130 struct igmp_group
*grp
;
132 /* scan igmp groups */
133 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grpnode
, grp
)) {
134 struct listnode
*srcnode
;
135 struct igmp_source
*src
;
137 /* scan group sources */
138 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
, srcnode
, src
)) {
140 if (IGMP_SOURCE_TEST_FORWARDING(src
->source_flags
)) {
143 memset (&sg
, 0, sizeof (struct prefix_sg
));
144 sg
.src
= src
->source_addr
;
145 sg
.grp
= grp
->group_addr
;
146 pim_ifchannel_local_membership_add(ifp
, &sg
);
149 } /* scan group sources */
150 } /* scan igmp groups */
151 } /* scan igmp sockets */
154 Finally delete every PIM (S,G) entry lacking all state info
157 pim_ifchannel_delete_on_noinfo(ifp
);
161 static void pim_show_assert(struct vty
*vty
)
163 struct pim_interface
*pim_ifp
;
164 struct pim_ifchannel
*ch
;
165 struct listnode
*ch_node
;
166 struct in_addr ifaddr
;
169 now
= pim_time_monotonic_sec();
172 "Interface Address Source Group State Winner Uptime Timer%s",
175 for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list
, ch_node
, ch
)) {
176 char ch_src_str
[INET_ADDRSTRLEN
];
177 char ch_grp_str
[INET_ADDRSTRLEN
];
178 char winner_str
[INET_ADDRSTRLEN
];
182 pim_ifp
= ch
->interface
->info
;
187 ifaddr
= pim_ifp
->primary_address
;
189 pim_inet4_dump("<ch_src?>", ch
->sg
.src
,
190 ch_src_str
, sizeof(ch_src_str
));
191 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
,
192 ch_grp_str
, sizeof(ch_grp_str
));
193 pim_inet4_dump("<assrt_win?>", ch
->ifassert_winner
,
194 winner_str
, sizeof(winner_str
));
196 pim_time_uptime(uptime
, sizeof(uptime
), now
- ch
->ifassert_creation
);
197 pim_time_timer_to_mmss(timer
, sizeof(timer
),
198 ch
->t_ifassert_timer
);
200 vty_out(vty
, "%-9s %-15s %-15s %-15s %-6s %-15s %-8s %-5s%s",
205 pim_ifchannel_ifassert_name(ch
->ifassert_state
),
210 } /* scan interface channels */
213 static void pim_show_assert_internal(struct vty
*vty
)
215 struct pim_interface
*pim_ifp
;
216 struct listnode
*ch_node
;
217 struct pim_ifchannel
*ch
;
218 struct in_addr ifaddr
;
222 "ECA: Evaluate CouldAssert%s"
223 "ATD: AssertTrackingDesired%s"
224 "eATD: Evaluate AssertTrackingDesired%s%s",
225 VTY_NEWLINE
, VTY_NEWLINE
, VTY_NEWLINE
, VTY_NEWLINE
, VTY_NEWLINE
);
228 "Interface Address Source Group CA eCA ATD eATD%s",
231 for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list
, ch_node
, ch
)) {
232 pim_ifp
= ch
->interface
->info
;
237 ifaddr
= pim_ifp
->primary_address
;
239 char ch_src_str
[INET_ADDRSTRLEN
];
240 char ch_grp_str
[INET_ADDRSTRLEN
];
242 pim_inet4_dump("<ch_src?>", ch
->sg
.src
,
243 ch_src_str
, sizeof(ch_src_str
));
244 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
,
245 ch_grp_str
, sizeof(ch_grp_str
));
246 vty_out(vty
, "%-9s %-15s %-15s %-15s %-3s %-3s %-3s %-4s%s",
251 PIM_IF_FLAG_TEST_COULD_ASSERT(ch
->flags
) ? "yes" : "no",
252 pim_macro_ch_could_assert_eval(ch
) ? "yes" : "no",
253 PIM_IF_FLAG_TEST_ASSERT_TRACKING_DESIRED(ch
->flags
) ? "yes" : "no",
254 pim_macro_assert_tracking_desired_eval(ch
) ? "yes" : "no",
256 } /* scan interface channels */
259 static void pim_show_assert_metric(struct vty
*vty
)
261 struct pim_interface
*pim_ifp
;
262 struct listnode
*ch_node
;
263 struct pim_ifchannel
*ch
;
264 struct in_addr ifaddr
;
267 "Interface Address Source Group RPT Pref Metric Address %s",
270 for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list
, ch_node
, ch
)) {
271 pim_ifp
= ch
->interface
->info
;
276 ifaddr
= pim_ifp
->primary_address
;
278 char ch_src_str
[INET_ADDRSTRLEN
];
279 char ch_grp_str
[INET_ADDRSTRLEN
];
280 char addr_str
[INET_ADDRSTRLEN
];
281 struct pim_assert_metric am
;
283 am
= pim_macro_spt_assert_metric(&ch
->upstream
->rpf
, pim_ifp
->primary_address
);
285 pim_inet4_dump("<ch_src?>", ch
->sg
.src
,
286 ch_src_str
, sizeof(ch_src_str
));
287 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
,
288 ch_grp_str
, sizeof(ch_grp_str
));
289 pim_inet4_dump("<addr?>", am
.ip_address
,
290 addr_str
, sizeof(addr_str
));
292 vty_out(vty
, "%-9s %-15s %-15s %-15s %-3s %4u %6u %-15s%s",
297 am
.rpt_bit_flag
? "yes" : "no",
298 am
.metric_preference
,
302 } /* scan interface channels */
305 static void pim_show_assert_winner_metric(struct vty
*vty
)
307 struct pim_interface
*pim_ifp
;
308 struct listnode
*ch_node
;
309 struct pim_ifchannel
*ch
;
310 struct in_addr ifaddr
;
313 "Interface Address Source Group RPT Pref Metric Address %s",
316 for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list
, ch_node
, ch
)) {
317 pim_ifp
= ch
->interface
->info
;
322 ifaddr
= pim_ifp
->primary_address
;
324 char ch_src_str
[INET_ADDRSTRLEN
];
325 char ch_grp_str
[INET_ADDRSTRLEN
];
326 char addr_str
[INET_ADDRSTRLEN
];
327 struct pim_assert_metric
*am
;
331 am
= &ch
->ifassert_winner_metric
;
333 pim_inet4_dump("<ch_src?>", ch
->sg
.src
,
334 ch_src_str
, sizeof(ch_src_str
));
335 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
,
336 ch_grp_str
, sizeof(ch_grp_str
));
337 pim_inet4_dump("<addr?>", am
->ip_address
,
338 addr_str
, sizeof(addr_str
));
340 if (am
->metric_preference
== PIM_ASSERT_METRIC_PREFERENCE_MAX
)
341 snprintf(pref_str
, sizeof(pref_str
), "INFI");
343 snprintf(pref_str
, sizeof(pref_str
), "%4u", am
->metric_preference
);
345 if (am
->route_metric
== PIM_ASSERT_ROUTE_METRIC_MAX
)
346 snprintf(metr_str
, sizeof(metr_str
), "INFI");
348 snprintf(metr_str
, sizeof(metr_str
), "%6u", am
->route_metric
);
350 vty_out(vty
, "%-9s %-15s %-15s %-15s %-3s %-4s %-6s %-15s%s",
355 am
->rpt_bit_flag
? "yes" : "no",
360 } /* scan interface channels */
363 static void json_object_pim_ifp_add(struct json_object
*json
, struct interface
*ifp
)
365 struct pim_interface
*pim_ifp
;
368 json_object_string_add(json
, "name", ifp
->name
);
369 json_object_string_add(json
, "state", if_is_up(ifp
) ? "up" : "down");
370 json_object_string_add(json
, "address", inet_ntoa(pim_ifp
->primary_address
));
371 json_object_int_add(json
, "index", ifp
->ifindex
);
373 if (if_is_multicast(ifp
))
374 json_object_boolean_true_add(json
, "flagMulticast");
376 if (if_is_broadcast(ifp
))
377 json_object_boolean_true_add(json
, "flagBroadcast");
379 if (ifp
->flags
& IFF_ALLMULTI
)
380 json_object_boolean_true_add(json
, "flagAllMulticast");
382 if (ifp
->flags
& IFF_PROMISC
)
383 json_object_boolean_true_add(json
, "flagPromiscuous");
385 if (PIM_IF_IS_DELETED(ifp
))
386 json_object_boolean_true_add(json
, "flagDeleted");
388 if (pim_if_lan_delay_enabled(ifp
))
389 json_object_boolean_true_add(json
, "lanDelayEnabled");
392 static void pim_show_membership(struct vty
*vty
, u_char uj
)
394 struct pim_interface
*pim_ifp
;
395 struct listnode
*ch_node
;
396 struct pim_ifchannel
*ch
;
398 json_object
*json
= NULL
;
399 json_object
*json_iface
= NULL
;
400 json_object
*json_row
= NULL
;
401 json_object
*json_tmp
= NULL
;
403 json
= json_object_new_object();
405 for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list
, ch_node
, ch
)) {
407 pim_ifp
= ch
->interface
->info
;
412 char ch_src_str
[INET_ADDRSTRLEN
];
413 char ch_grp_str
[INET_ADDRSTRLEN
];
415 pim_inet4_dump("<ch_src?>", ch
->sg
.src
,
416 ch_src_str
, sizeof(ch_src_str
));
417 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
,
418 ch_grp_str
, sizeof(ch_grp_str
));
420 json_object_object_get_ex(json
, ch
->interface
->name
, &json_iface
);
423 json_iface
= json_object_new_object();
424 json_object_pim_ifp_add(json_iface
, ch
->interface
);
425 json_object_object_add(json
, ch
->interface
->name
, json_iface
);
428 json_row
= json_object_new_object();
429 json_object_string_add(json_row
, "source", ch_src_str
);
430 json_object_string_add(json_row
, "group", ch_grp_str
);
431 json_object_string_add(json_row
, "localMembership",
432 ch
->local_ifmembership
== PIM_IFMEMBERSHIP_NOINFO
? "NOINFO" : "INCLUDE");
433 json_object_object_add(json_iface
, ch_grp_str
, json_row
);
434 } /* scan interface channels */
437 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
440 "Interface Address Source Group Membership%s",
444 * Example of the json data we are traversing
450 * "address":"10.1.20.1",
452 * "flagMulticast":true,
453 * "flagBroadcast":true,
454 * "lanDelayEnabled":true,
457 * "group":"226.10.10.10",
458 * "localMembership":"INCLUDE"
464 /* foreach interface */
465 json_object_object_foreach(json
, key
, val
) {
467 /* Find all of the keys where the val is an object. In the example
468 * above the only one is 226.10.10.10
470 json_object_object_foreach(val
, if_field_key
, if_field_val
) {
471 type
= json_object_get_type(if_field_val
);
473 if (type
== json_type_object
) {
474 vty_out(vty
, "%-9s ", key
);
476 json_object_object_get_ex(val
, "address", &json_tmp
);
477 vty_out(vty
, "%-15s ", json_object_get_string(json_tmp
));
479 json_object_object_get_ex(if_field_val
, "source", &json_tmp
);
480 vty_out(vty
, "%-15s ", json_object_get_string(json_tmp
));
483 vty_out(vty
, "%-15s ", if_field_key
);
485 json_object_object_get_ex(if_field_val
, "localMembership", &json_tmp
);
486 vty_out(vty
, "%-10s%s", json_object_get_string(json_tmp
), VTY_NEWLINE
);
492 json_object_free(json
);
495 static void pim_print_ifp_flags(struct vty
*vty
, struct interface
*ifp
, int mloop
)
497 vty_out(vty
, "Flags%s", VTY_NEWLINE
);
498 vty_out(vty
, "-----%s", VTY_NEWLINE
);
499 vty_out(vty
, "All Multicast : %s%s", (ifp
->flags
& IFF_ALLMULTI
) ? "yes" : "no", VTY_NEWLINE
);
500 vty_out(vty
, "Broadcast : %s%s", if_is_broadcast(ifp
)? "yes" : "no", VTY_NEWLINE
);
501 vty_out(vty
, "Deleted : %s%s", PIM_IF_IS_DELETED(ifp
) ? "yes" : "no", VTY_NEWLINE
);
502 vty_out(vty
, "Interface Index : %d%s", ifp
->ifindex
, VTY_NEWLINE
);
503 vty_out(vty
, "Multicast : %s%s", if_is_multicast(ifp
) ? "yes" : "no", VTY_NEWLINE
);
504 vty_out(vty
, "Multicast Loop : %d%s", mloop
, VTY_NEWLINE
);
505 vty_out(vty
, "Promiscuous : %s%s", (ifp
->flags
& IFF_PROMISC
) ? "yes" : "no", VTY_NEWLINE
);
506 vty_out(vty
, "%s", VTY_NEWLINE
);
507 vty_out(vty
, "%s", VTY_NEWLINE
);
510 static void igmp_show_interfaces(struct vty
*vty
, u_char uj
)
512 struct listnode
*node
;
513 struct interface
*ifp
;
515 json_object
*json
= NULL
;
516 json_object
*json_row
= NULL
;
518 now
= pim_time_monotonic_sec();
521 json
= json_object_new_object();
524 "Interface State Address V Querier Query Timer Uptime%s",
527 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
)) {
528 struct pim_interface
*pim_ifp
;
529 struct listnode
*sock_node
;
530 struct igmp_sock
*igmp
;
537 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
539 char query_hhmmss
[10];
541 pim_time_uptime(uptime
, sizeof(uptime
), now
- igmp
->sock_creation
);
542 pim_time_timer_to_hhmmss(query_hhmmss
, sizeof(query_hhmmss
), igmp
->t_igmp_query_timer
);
545 json_row
= json_object_new_object();
546 json_object_pim_ifp_add(json_row
, ifp
);
547 json_object_string_add(json_row
, "upTime", uptime
);
548 json_object_int_add(json_row
, "version", pim_ifp
->igmp_version
);
550 if (igmp
->t_igmp_query_timer
) {
551 json_object_boolean_true_add(json_row
, "querier");
552 json_object_string_add(json_row
, "queryTimer", query_hhmmss
);
555 json_object_object_add(json
, ifp
->name
, json_row
);
558 vty_out(vty
, "%-9s %5s %15s %d %7s %11s %8s%s",
560 if_is_up(ifp
) ? "up" : "down",
561 inet_ntoa(igmp
->ifaddr
),
562 pim_ifp
->igmp_version
,
563 igmp
->t_igmp_query_timer
? "local" : "other",
572 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
573 json_object_free(json
);
577 static void igmp_show_interfaces_single(struct vty
*vty
, const char *ifname
, u_char uj
)
579 struct igmp_sock
*igmp
;
580 struct interface
*ifp
;
581 struct listnode
*node
;
582 struct listnode
*sock_node
;
583 struct pim_interface
*pim_ifp
;
585 char query_hhmmss
[10];
586 char other_hhmmss
[10];
587 int found_ifname
= 0;
590 long gmi_msec
; /* Group Membership Interval */
593 long oqpi_msec
; /* Other Querier Present Interval */
597 json_object
*json
= NULL
;
598 json_object
*json_row
= NULL
;
601 json
= json_object_new_object();
603 now
= pim_time_monotonic_sec();
605 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
)) {
611 if (strcmp(ifname
, "detail") && strcmp(ifname
, ifp
->name
))
614 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
616 pim_time_uptime(uptime
, sizeof(uptime
), now
- igmp
->sock_creation
);
617 pim_time_timer_to_hhmmss(query_hhmmss
, sizeof(query_hhmmss
), igmp
->t_igmp_query_timer
);
618 pim_time_timer_to_hhmmss(other_hhmmss
, sizeof(other_hhmmss
), igmp
->t_other_querier_timer
);
620 gmi_msec
= PIM_IGMP_GMI_MSEC(igmp
->querier_robustness_variable
,
621 igmp
->querier_query_interval
,
622 pim_ifp
->igmp_query_max_response_time_dsec
);
624 sqi
= PIM_IGMP_SQI(pim_ifp
->igmp_default_query_interval
);
626 oqpi_msec
= PIM_IGMP_OQPI_MSEC(igmp
->querier_robustness_variable
,
627 igmp
->querier_query_interval
,
628 pim_ifp
->igmp_query_max_response_time_dsec
);
630 lmqt_msec
= PIM_IGMP_LMQT_MSEC(pim_ifp
->igmp_query_max_response_time_dsec
,
631 igmp
->querier_robustness_variable
);
633 ohpi_msec
= PIM_IGMP_OHPI_DSEC(igmp
->querier_robustness_variable
,
634 igmp
->querier_query_interval
,
635 pim_ifp
->igmp_query_max_response_time_dsec
) * 100;
637 qri_msec
= pim_ifp
->igmp_query_max_response_time_dsec
* 100;
638 mloop
= pim_socket_mcastloop_get(pim_ifp
->pim_sock_fd
);
641 json_row
= json_object_new_object();
642 json_object_pim_ifp_add(json_row
, ifp
);
643 json_object_string_add(json_row
, "upTime", uptime
);
644 json_object_string_add(json_row
, "querier", igmp
->t_igmp_query_timer
? "local" : "other");
645 json_object_int_add(json_row
, "queryStartCount", igmp
->startup_query_count
);
646 json_object_string_add(json_row
, "queryQueryTimer", query_hhmmss
);
647 json_object_string_add(json_row
, "queryOtherTimer", other_hhmmss
);
648 json_object_int_add(json_row
, "version", pim_ifp
->igmp_version
);
649 json_object_int_add(json_row
, "timerGroupMembershipIntervalMsec", gmi_msec
);
650 json_object_int_add(json_row
, "timerLastMemberQueryMsec", lmqt_msec
);
651 json_object_int_add(json_row
, "timerOlderHostPresentIntervalMsec", ohpi_msec
);
652 json_object_int_add(json_row
, "timerOtherQuerierPresentIntervalMsec", oqpi_msec
);
653 json_object_int_add(json_row
, "timerQueryInterval", igmp
->querier_query_interval
);
654 json_object_int_add(json_row
, "timerQueryResponseIntervalMsec", qri_msec
);
655 json_object_int_add(json_row
, "timerRobustnessVariable", igmp
->querier_robustness_variable
);
656 json_object_int_add(json_row
, "timerStartupQueryInterval", sqi
);
658 json_object_object_add(json
, ifp
->name
, json_row
);
661 vty_out(vty
, "Interface : %s%s", ifp
->name
, VTY_NEWLINE
);
662 vty_out(vty
, "State : %s%s", if_is_up(ifp
) ? "up" : "down", VTY_NEWLINE
);
663 vty_out(vty
, "Address : %s%s", inet_ntoa(pim_ifp
->primary_address
), VTY_NEWLINE
);
664 vty_out(vty
, "Uptime : %s%s", uptime
, VTY_NEWLINE
);
665 vty_out(vty
, "Version : %d%s", pim_ifp
->igmp_version
, VTY_NEWLINE
);
666 vty_out(vty
, "%s", VTY_NEWLINE
);
667 vty_out(vty
, "%s", VTY_NEWLINE
);
669 vty_out(vty
, "Querier%s", VTY_NEWLINE
);
670 vty_out(vty
, "-------%s", VTY_NEWLINE
);
671 vty_out(vty
, "Querier : %s%s", igmp
->t_igmp_query_timer
? "local" : "other", VTY_NEWLINE
);
672 vty_out(vty
, "Start Count : %d%s", igmp
->startup_query_count
, VTY_NEWLINE
);
673 vty_out(vty
, "Query Timer : %s%s", query_hhmmss
, VTY_NEWLINE
);
674 vty_out(vty
, "Other Timer : %s%s", other_hhmmss
, VTY_NEWLINE
);
675 vty_out(vty
, "%s", VTY_NEWLINE
);
676 vty_out(vty
, "%s", VTY_NEWLINE
);
678 vty_out(vty
, "Timers%s", VTY_NEWLINE
);
679 vty_out(vty
, "------%s", VTY_NEWLINE
);
680 vty_out(vty
, "Group Membership Interval : %lis%s", gmi_msec
/1000, VTY_NEWLINE
);
681 vty_out(vty
, "Last Member Query Time : %lis%s", lmqt_msec
/1000, VTY_NEWLINE
);
682 vty_out(vty
, "Older Host Present Interval : %lis%s", ohpi_msec
/1000, VTY_NEWLINE
);
683 vty_out(vty
, "Other Querier Present Interval : %lis%s", oqpi_msec
/1000, VTY_NEWLINE
);
684 vty_out(vty
, "Query Interval : %ds%s", igmp
->querier_query_interval
, VTY_NEWLINE
);
685 vty_out(vty
, "Query Response Interval : %lis%s", qri_msec
/1000, VTY_NEWLINE
);
686 vty_out(vty
, "Robustness Variable : %d%s", igmp
->querier_robustness_variable
, VTY_NEWLINE
);
687 vty_out(vty
, "Startup Query Interval : %ds%s", sqi
, VTY_NEWLINE
);
688 vty_out(vty
, "%s", VTY_NEWLINE
);
689 vty_out(vty
, "%s", VTY_NEWLINE
);
691 pim_print_ifp_flags(vty
, ifp
, mloop
);
697 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
698 json_object_free(json
);
701 vty_out (vty
, "%% No such interface%s", VTY_NEWLINE
);
705 static void igmp_show_interface_join(struct vty
*vty
)
707 struct listnode
*node
;
708 struct interface
*ifp
;
711 now
= pim_time_monotonic_sec();
714 "Interface Address Source Group Socket Uptime %s",
717 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
)) {
718 struct pim_interface
*pim_ifp
;
719 struct listnode
*join_node
;
720 struct igmp_join
*ij
;
721 struct in_addr pri_addr
;
722 char pri_addr_str
[INET_ADDRSTRLEN
];
729 if (!pim_ifp
->igmp_join_list
)
732 pri_addr
= pim_find_primary_addr(ifp
);
733 pim_inet4_dump("<pri?>", pri_addr
, pri_addr_str
, sizeof(pri_addr_str
));
735 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_join_list
, join_node
, ij
)) {
736 char group_str
[INET_ADDRSTRLEN
];
737 char source_str
[INET_ADDRSTRLEN
];
740 pim_time_uptime(uptime
, sizeof(uptime
), now
- ij
->sock_creation
);
741 pim_inet4_dump("<grp?>", ij
->group_addr
, group_str
, sizeof(group_str
));
742 pim_inet4_dump("<src?>", ij
->source_addr
, source_str
, sizeof(source_str
));
744 vty_out(vty
, "%-9s %-15s %-15s %-15s %6d %8s%s",
752 } /* for (pim_ifp->igmp_join_list) */
758 static void pim_show_interfaces_single(struct vty
*vty
, const char *ifname
, u_char uj
)
760 struct in_addr ifaddr
;
761 struct interface
*ifp
;
762 struct listnode
*neighnode
;
763 struct listnode
*node
;
764 struct listnode
*upnode
;
765 struct pim_interface
*pim_ifp
;
766 struct pim_neighbor
*neigh
;
767 struct pim_upstream
*up
;
769 char dr_str
[INET_ADDRSTRLEN
];
772 char grp_str
[INET_ADDRSTRLEN
];
773 char hello_period
[10];
774 char hello_timer
[10];
775 char neigh_src_str
[INET_ADDRSTRLEN
];
776 char src_str
[INET_ADDRSTRLEN
];
777 char stat_uptime
[10];
780 int found_ifname
= 0;
782 json_object
*json
= NULL
;
783 json_object
*json_row
= NULL
;
784 json_object
*json_pim_neighbor
= NULL
;
785 json_object
*json_pim_neighbors
= NULL
;
786 json_object
*json_group
= NULL
;
787 json_object
*json_group_source
= NULL
;
788 json_object
*json_fhr_sources
= NULL
;
789 struct pim_secondary_addr
*sec_addr
;
790 struct listnode
*sec_node
;
792 now
= pim_time_monotonic_sec();
795 json
= json_object_new_object();
797 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
)) {
803 if (pim_ifp
->pim_sock_fd
< 0)
806 if (strcmp(ifname
, "detail") && strcmp(ifname
, ifp
->name
))
810 ifaddr
= pim_ifp
->primary_address
;
811 pim_inet4_dump("<dr?>", pim_ifp
->pim_dr_addr
, dr_str
, sizeof(dr_str
));
812 pim_time_uptime_begin(dr_uptime
, sizeof(dr_uptime
), now
, pim_ifp
->pim_dr_election_last
);
813 pim_time_timer_to_hhmmss(hello_timer
, sizeof(hello_timer
), pim_ifp
->t_pim_hello_timer
);
814 pim_time_mmss(hello_period
, sizeof(hello_period
), pim_ifp
->pim_hello_period
);
815 pim_time_uptime(stat_uptime
, sizeof(stat_uptime
), now
- pim_ifp
->pim_ifstat_start
);
816 mloop
= pim_socket_mcastloop_get(pim_ifp
->pim_sock_fd
);
819 json_row
= json_object_new_object();
820 json_object_pim_ifp_add(json_row
, ifp
);
822 if (pim_ifp
->update_source
.s_addr
!= INADDR_ANY
) {
823 json_object_string_add(json_row
, "useSource", inet_ntoa(pim_ifp
->update_source
));
825 if (pim_ifp
->sec_addr_list
) {
826 json_object
*sec_list
= NULL
;
828 sec_list
= json_object_new_array();
829 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->sec_addr_list
, sec_node
, sec_addr
)) {
830 json_object_array_add(sec_list
, json_object_new_string(inet_ntoa(sec_addr
->addr
)));
832 json_object_object_add(json_row
, "secondaryAddressList", sec_list
);
836 if (pim_ifp
->pim_neighbor_list
->count
) {
837 json_pim_neighbors
= json_object_new_object();
839 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
, neigh
)) {
840 json_pim_neighbor
= json_object_new_object();
841 pim_inet4_dump("<src?>", neigh
->source_addr
, neigh_src_str
, sizeof(neigh_src_str
));
842 pim_time_uptime(uptime
, sizeof(uptime
), now
- neigh
->creation
);
843 pim_time_timer_to_hhmmss(expire
, sizeof(expire
), neigh
->t_expire_timer
);
845 json_object_string_add(json_pim_neighbor
, "address", neigh_src_str
);
846 json_object_string_add(json_pim_neighbor
, "upTime", uptime
);
847 json_object_string_add(json_pim_neighbor
, "holdtime", expire
);
849 json_object_object_add(json_pim_neighbors
, neigh_src_str
, json_pim_neighbor
);
852 json_object_object_add(json_row
, "neighbors", json_pim_neighbors
);
855 json_object_string_add(json_row
, "drAddress", dr_str
);
856 json_object_int_add(json_row
, "drPriority", pim_ifp
->pim_dr_priority
);
857 json_object_string_add(json_row
, "drUptime", dr_uptime
);
858 json_object_int_add(json_row
, "drElections", pim_ifp
->pim_dr_election_count
);
859 json_object_int_add(json_row
, "drChanges", pim_ifp
->pim_dr_election_changes
);
862 for (ALL_LIST_ELEMENTS_RO(pim_upstream_list
, upnode
, up
)) {
863 if (ifp
== up
->rpf
.source_nexthop
.interface
) {
864 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
) {
865 if (!json_fhr_sources
) {
866 json_fhr_sources
= json_object_new_object();
869 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
870 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
871 pim_time_uptime(uptime
, sizeof(uptime
), now
- up
->state_transition
);
873 /* Does this group live in json_fhr_sources? If not create it. */
874 json_object_object_get_ex(json_fhr_sources
, grp_str
, &json_group
);
877 json_group
= json_object_new_object();
878 json_object_object_add(json_fhr_sources
, grp_str
, json_group
);
881 json_group_source
= json_object_new_object();
882 json_object_string_add(json_group_source
, "source", src_str
);
883 json_object_string_add(json_group_source
, "group", grp_str
);
884 json_object_string_add(json_group_source
, "upTime", uptime
);
885 json_object_object_add(json_group
, src_str
, json_group_source
);
890 if (json_fhr_sources
) {
891 json_object_object_add(json_row
, "firstHopRouter", json_fhr_sources
);
894 json_object_int_add(json_row
, "helloPeriod", pim_ifp
->pim_hello_period
);
895 json_object_string_add(json_row
, "helloTimer", hello_timer
);
896 json_object_string_add(json_row
, "helloStatStart", stat_uptime
);
897 json_object_int_add(json_row
, "helloReceived", pim_ifp
->pim_ifstat_hello_recv
);
898 json_object_int_add(json_row
, "helloReceivedFailed", pim_ifp
->pim_ifstat_hello_recvfail
);
899 json_object_int_add(json_row
, "helloSend", pim_ifp
->pim_ifstat_hello_sent
);
900 json_object_int_add(json_row
, "hellosendFailed", pim_ifp
->pim_ifstat_hello_sendfail
);
901 json_object_int_add(json_row
, "helloGenerationId", pim_ifp
->pim_generation_id
);
902 json_object_int_add(json_row
, "flagMulticastLoop", mloop
);
904 json_object_int_add(json_row
, "effectivePropagationDelay", pim_if_effective_propagation_delay_msec(ifp
));
905 json_object_int_add(json_row
, "effectiveOverrideInterval", pim_if_effective_override_interval_msec(ifp
));
906 json_object_int_add(json_row
, "joinPruneOverrideInterval", pim_if_jp_override_interval_msec(ifp
));
908 json_object_int_add(json_row
, "propagationDelay", pim_ifp
->pim_propagation_delay_msec
);
909 json_object_int_add(json_row
, "propagationDelayHighest", pim_ifp
->pim_neighbors_highest_propagation_delay_msec
);
910 json_object_int_add(json_row
, "overrideInterval", pim_ifp
->pim_override_interval_msec
);
911 json_object_int_add(json_row
, "overrideIntervalHighest", pim_ifp
->pim_neighbors_highest_override_interval_msec
);
912 json_object_object_add(json
, ifp
->name
, json_row
);
915 vty_out(vty
, "Interface : %s%s", ifp
->name
, VTY_NEWLINE
);
916 vty_out(vty
, "State : %s%s", if_is_up(ifp
) ? "up" : "down", VTY_NEWLINE
);
917 if (pim_ifp
->update_source
.s_addr
!= INADDR_ANY
) {
918 vty_out(vty
, "Use Source : %s%s", inet_ntoa(pim_ifp
->update_source
), VTY_NEWLINE
);
920 if (pim_ifp
->sec_addr_list
) {
921 vty_out(vty
, "Address : %s (primary)%s",
922 inet_ntoa(ifaddr
), VTY_NEWLINE
);
923 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->sec_addr_list
, sec_node
, sec_addr
)) {
924 vty_out(vty
, " %s%s",
925 inet_ntoa(sec_addr
->addr
), VTY_NEWLINE
);
928 vty_out(vty
, "Address : %s%s", inet_ntoa(ifaddr
), VTY_NEWLINE
);
930 vty_out(vty
, "%s", VTY_NEWLINE
);
935 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
, neigh
)) {
938 vty_out(vty
, "PIM Neighbors%s", VTY_NEWLINE
);
939 vty_out(vty
, "-------------%s", VTY_NEWLINE
);
943 pim_inet4_dump("<src?>", neigh
->source_addr
, neigh_src_str
, sizeof(neigh_src_str
));
944 pim_time_uptime(uptime
, sizeof(uptime
), now
- neigh
->creation
);
945 pim_time_timer_to_hhmmss(expire
, sizeof(expire
), neigh
->t_expire_timer
);
946 vty_out(vty
, "%-15s : up for %s, holdtime expires in %s%s", neigh_src_str
, uptime
, expire
, VTY_NEWLINE
);
950 vty_out(vty
, "%s", VTY_NEWLINE
);
951 vty_out(vty
, "%s", VTY_NEWLINE
);
954 vty_out(vty
, "Designated Router%s", VTY_NEWLINE
);
955 vty_out(vty
, "-----------------%s", VTY_NEWLINE
);
956 vty_out(vty
, "Address : %s%s", dr_str
, VTY_NEWLINE
);
957 vty_out(vty
, "Priority : %d%s", pim_ifp
->pim_dr_priority
, VTY_NEWLINE
);
958 vty_out(vty
, "Uptime : %s%s", dr_uptime
, VTY_NEWLINE
);
959 vty_out(vty
, "Elections : %d%s", pim_ifp
->pim_dr_election_count
, VTY_NEWLINE
);
960 vty_out(vty
, "Changes : %d%s", pim_ifp
->pim_dr_election_changes
, VTY_NEWLINE
);
961 vty_out(vty
, "%s", VTY_NEWLINE
);
962 vty_out(vty
, "%s", VTY_NEWLINE
);
966 for (ALL_LIST_ELEMENTS_RO(pim_upstream_list
, upnode
, up
)) {
967 if (strcmp(ifp
->name
, up
->rpf
.source_nexthop
.interface
->name
) == 0) {
968 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
) {
971 vty_out(vty
, "FHR - First Hop Router%s", VTY_NEWLINE
);
972 vty_out(vty
, "----------------------%s", VTY_NEWLINE
);
976 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
977 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
978 pim_time_uptime(uptime
, sizeof(uptime
), now
- up
->state_transition
);
979 vty_out(vty
, "%s : %s is a source, uptime is %s%s", grp_str
, src_str
, uptime
, VTY_NEWLINE
);
985 vty_out(vty
, "%s", VTY_NEWLINE
);
986 vty_out(vty
, "%s", VTY_NEWLINE
);
989 vty_out(vty
, "Hellos%s", VTY_NEWLINE
);
990 vty_out(vty
, "------%s", VTY_NEWLINE
);
991 vty_out(vty
, "Period : %d%s", pim_ifp
->pim_hello_period
, VTY_NEWLINE
);
992 vty_out(vty
, "Timer : %s%s", hello_timer
, VTY_NEWLINE
);
993 vty_out(vty
, "StatStart : %s%s", stat_uptime
, VTY_NEWLINE
);
994 vty_out(vty
, "Receive : %d%s", pim_ifp
->pim_ifstat_hello_recv
, VTY_NEWLINE
);
995 vty_out(vty
, "Receive Failed : %d%s", pim_ifp
->pim_ifstat_hello_recvfail
, VTY_NEWLINE
);
996 vty_out(vty
, "Send : %d%s", pim_ifp
->pim_ifstat_hello_sent
, VTY_NEWLINE
);
997 vty_out(vty
, "Send Failed : %d%s", pim_ifp
->pim_ifstat_hello_sendfail
, VTY_NEWLINE
);
998 vty_out(vty
, "Generation ID : %08x%s", pim_ifp
->pim_generation_id
, VTY_NEWLINE
);
999 vty_out(vty
, "%s", VTY_NEWLINE
);
1000 vty_out(vty
, "%s", VTY_NEWLINE
);
1002 pim_print_ifp_flags(vty
, ifp
, mloop
);
1004 vty_out(vty
, "Join Prune Interval%s", VTY_NEWLINE
);
1005 vty_out(vty
, "-------------------%s", VTY_NEWLINE
);
1006 vty_out(vty
, "LAN Delay : %s%s", pim_if_lan_delay_enabled(ifp
) ? "yes" : "no", VTY_NEWLINE
);
1007 vty_out(vty
, "Effective Propagation Delay : %d msec%s", pim_if_effective_propagation_delay_msec(ifp
), VTY_NEWLINE
);
1008 vty_out(vty
, "Effective Override Interval : %d msec%s", pim_if_effective_override_interval_msec(ifp
), VTY_NEWLINE
);
1009 vty_out(vty
, "Join Prune Override Interval : %d msec%s", pim_if_jp_override_interval_msec(ifp
), VTY_NEWLINE
);
1010 vty_out(vty
, "%s", VTY_NEWLINE
);
1011 vty_out(vty
, "%s", VTY_NEWLINE
);
1013 vty_out(vty
, "LAN Prune Delay%s", VTY_NEWLINE
);
1014 vty_out(vty
, "---------------%s", VTY_NEWLINE
);
1015 vty_out(vty
, "Propagation Delay : %d msec%s", pim_ifp
->pim_propagation_delay_msec
, VTY_NEWLINE
);
1016 vty_out(vty
, "Propagation Delay (Highest) : %d msec%s", pim_ifp
->pim_neighbors_highest_propagation_delay_msec
, VTY_NEWLINE
);
1017 vty_out(vty
, "Override Interval : %d msec%s", pim_ifp
->pim_override_interval_msec
, VTY_NEWLINE
);
1018 vty_out(vty
, "Override Interval (Highest) : %d msec%s", pim_ifp
->pim_neighbors_highest_override_interval_msec
, VTY_NEWLINE
);
1019 vty_out(vty
, "%s", VTY_NEWLINE
);
1020 vty_out(vty
, "%s", VTY_NEWLINE
);
1025 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
1026 json_object_free(json
);
1029 vty_out (vty
, "%% No such interface%s", VTY_NEWLINE
);
1033 static void pim_show_interfaces(struct vty
*vty
, u_char uj
)
1035 struct interface
*ifp
;
1036 struct listnode
*node
;
1037 struct listnode
*upnode
;
1038 struct pim_interface
*pim_ifp
;
1039 struct pim_upstream
*up
;
1042 json_object
*json
= NULL
;
1043 json_object
*json_row
= NULL
;
1044 json_object
*json_tmp
;
1046 json
= json_object_new_object();
1048 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
)) {
1049 pim_ifp
= ifp
->info
;
1054 if (pim_ifp
->pim_sock_fd
< 0)
1057 pim_nbrs
= pim_ifp
->pim_neighbor_list
->count
;
1060 for (ALL_LIST_ELEMENTS_RO(pim_upstream_list
, upnode
, up
))
1061 if (ifp
== up
->rpf
.source_nexthop
.interface
)
1062 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
1065 json_row
= json_object_new_object();
1066 json_object_pim_ifp_add(json_row
, ifp
);
1067 json_object_int_add(json_row
, "pimNeighbors", pim_nbrs
);
1068 json_object_int_add(json_row
, "firstHopRouter", fhr
);
1069 json_object_string_add(json_row
, "pimDesignatedRouter", inet_ntoa(pim_ifp
->pim_dr_addr
));
1071 if (pim_ifp
->pim_dr_addr
.s_addr
== pim_ifp
->primary_address
.s_addr
)
1072 json_object_boolean_true_add(json_row
, "pimDesignatedRouterLocal");
1074 json_object_object_add(json
, ifp
->name
, json_row
);
1078 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
1080 vty_out(vty
, "Interface State Address PIM Nbrs PIM DR FHR%s", VTY_NEWLINE
);
1082 json_object_object_foreach(json
, key
, val
) {
1083 vty_out(vty
, "%-9s ", key
);
1085 json_object_object_get_ex(val
, "state", &json_tmp
);
1086 vty_out(vty
, "%5s ", json_object_get_string(json_tmp
));
1088 json_object_object_get_ex(val
, "address", &json_tmp
);
1089 vty_out(vty
, "%15s ", json_object_get_string(json_tmp
));
1091 json_object_object_get_ex(val
, "pimNeighbors", &json_tmp
);
1092 vty_out(vty
, "%8d ", json_object_get_int(json_tmp
));
1094 if (json_object_object_get_ex(val
, "pimDesignatedRouterLocal", &json_tmp
)) {
1095 vty_out(vty
, "%15s ", "local");
1097 json_object_object_get_ex(val
, "pimDesignatedRouter", &json_tmp
);
1098 vty_out(vty
, "%15s ", json_object_get_string(json_tmp
));
1101 json_object_object_get_ex(val
, "firstHopRouter", &json_tmp
);
1102 vty_out(vty
, "%3d%s", json_object_get_int(json_tmp
), VTY_NEWLINE
);
1106 json_object_free(json
);
1109 static void pim_show_join(struct vty
*vty
, u_char uj
)
1111 struct pim_interface
*pim_ifp
;
1112 struct in_addr ifaddr
;
1113 struct listnode
*ch_node
;
1114 struct pim_ifchannel
*ch
;
1116 json_object
*json
= NULL
;
1117 json_object
*json_iface
= NULL
;
1118 json_object
*json_row
= NULL
;
1119 json_object
*json_grp
= NULL
;
1121 now
= pim_time_monotonic_sec();
1124 json
= json_object_new_object();
1127 "Interface Address Source Group State Uptime Expire Prune%s",
1130 for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list
, ch_node
, ch
)) {
1132 pim_ifp
= ch
->interface
->info
;
1137 ifaddr
= pim_ifp
->primary_address
;
1139 char ch_src_str
[INET_ADDRSTRLEN
];
1140 char ch_grp_str
[INET_ADDRSTRLEN
];
1145 pim_inet4_dump("<ch_src?>", ch
->sg
.src
,
1146 ch_src_str
, sizeof(ch_src_str
));
1147 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
,
1148 ch_grp_str
, sizeof(ch_grp_str
));
1150 pim_time_uptime_begin(uptime
, sizeof(uptime
), now
, ch
->ifjoin_creation
);
1151 pim_time_timer_to_mmss(expire
, sizeof(expire
),
1152 ch
->t_ifjoin_expiry_timer
);
1153 pim_time_timer_to_mmss(prune
, sizeof(prune
),
1154 ch
->t_ifjoin_prune_pending_timer
);
1157 json_object_object_get_ex(json
, ch
->interface
->name
, &json_iface
);
1160 json_iface
= json_object_new_object();
1161 json_object_pim_ifp_add(json_iface
, ch
->interface
);
1162 json_object_object_add(json
, ch
->interface
->name
, json_iface
);
1165 json_row
= json_object_new_object();
1166 json_object_string_add(json_row
, "source", ch_src_str
);
1167 json_object_string_add(json_row
, "group", ch_grp_str
);
1168 json_object_string_add(json_row
, "upTime", uptime
);
1169 json_object_string_add(json_row
, "expire", expire
);
1170 json_object_string_add(json_row
, "prune", prune
);
1171 json_object_string_add(json_row
, "channelJoinName", pim_ifchannel_ifjoin_name(ch
->ifjoin_state
));
1172 if (PIM_IF_FLAG_TEST_S_G_RPT(ch
->flags
))
1173 json_object_int_add(json_row
, "SGRpt", 1);
1175 json_object_object_get_ex(json_iface
, ch_grp_str
, &json_grp
);
1178 json_grp
= json_object_new_object();
1179 json_object_object_add(json_grp
, ch_src_str
, json_row
);
1180 json_object_object_add(json_iface
, ch_grp_str
, json_grp
);
1183 json_object_object_add(json_grp
, ch_src_str
, json_row
);
1185 vty_out(vty
, "%-9s %-15s %-15s %-15s %-6s %8s %-6s %5s%s",
1186 ch
->interface
->name
,
1190 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
),
1196 } /* scan interface channels */
1199 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
1200 json_object_free(json
);
1204 static void pim_show_neighbors_single(struct vty
*vty
, const char *neighbor
, u_char uj
)
1206 struct listnode
*node
;
1207 struct listnode
*neighnode
;
1208 struct interface
*ifp
;
1209 struct pim_interface
*pim_ifp
;
1210 struct pim_neighbor
*neigh
;
1212 int found_neighbor
= 0;
1213 int option_address_list
;
1214 int option_dr_priority
;
1215 int option_generation_id
;
1216 int option_holdtime
;
1217 int option_lan_prune_delay
;
1221 char neigh_src_str
[INET_ADDRSTRLEN
];
1223 json_object
*json
= NULL
;
1224 json_object
*json_ifp
= NULL
;
1225 json_object
*json_row
= NULL
;
1227 now
= pim_time_monotonic_sec();
1230 json
= json_object_new_object();
1232 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
)) {
1233 pim_ifp
= ifp
->info
;
1238 if (pim_ifp
->pim_sock_fd
< 0)
1241 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
, neigh
)) {
1242 pim_inet4_dump("<src?>", neigh
->source_addr
,
1243 neigh_src_str
, sizeof(neigh_src_str
));
1246 * The user can specify either the interface name or the PIM neighbor IP.
1247 * If this pim_ifp matches neither then skip.
1249 if (strcmp(neighbor
, "detail") &&
1250 strcmp(neighbor
, ifp
->name
) &&
1251 strcmp(neighbor
, neigh_src_str
))
1255 pim_time_uptime(uptime
, sizeof(uptime
), now
- neigh
->creation
);
1256 pim_time_timer_to_hhmmss(expire
, sizeof(expire
), neigh
->t_expire_timer
);
1258 option_address_list
= 0;
1259 option_dr_priority
= 0;
1260 option_generation_id
= 0;
1261 option_holdtime
= 0;
1262 option_lan_prune_delay
= 0;
1265 if (PIM_OPTION_IS_SET(neigh
->hello_options
, PIM_OPTION_MASK_ADDRESS_LIST
))
1266 option_address_list
= 1;
1268 if (PIM_OPTION_IS_SET(neigh
->hello_options
, PIM_OPTION_MASK_DR_PRIORITY
))
1269 option_dr_priority
= 1;
1271 if (PIM_OPTION_IS_SET(neigh
->hello_options
, PIM_OPTION_MASK_GENERATION_ID
))
1272 option_generation_id
= 1;
1274 if (PIM_OPTION_IS_SET(neigh
->hello_options
, PIM_OPTION_MASK_HOLDTIME
))
1275 option_holdtime
= 1;
1277 if (PIM_OPTION_IS_SET(neigh
->hello_options
, PIM_OPTION_MASK_LAN_PRUNE_DELAY
))
1278 option_lan_prune_delay
= 1;
1280 if (PIM_OPTION_IS_SET(neigh
->hello_options
, PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION
))
1285 /* Does this ifp live in json? If not create it. */
1286 json_object_object_get_ex(json
, ifp
->name
, &json_ifp
);
1289 json_ifp
= json_object_new_object();
1290 json_object_pim_ifp_add(json_ifp
, ifp
);
1291 json_object_object_add(json
, ifp
->name
, json_ifp
);
1294 json_row
= json_object_new_object();
1295 json_object_string_add(json_row
, "interface", ifp
->name
);
1296 json_object_string_add(json_row
, "address", neigh_src_str
);
1297 json_object_string_add(json_row
, "upTime", uptime
);
1298 json_object_string_add(json_row
, "holdtime", expire
);
1299 json_object_int_add(json_row
, "drPriority", neigh
->dr_priority
);
1300 json_object_int_add(json_row
, "generationId", neigh
->generation_id
);
1302 if (option_address_list
)
1303 json_object_boolean_true_add(json_row
, "helloOptionAddressList");
1305 if (option_dr_priority
)
1306 json_object_boolean_true_add(json_row
, "helloOptionDrPriority");
1308 if (option_generation_id
)
1309 json_object_boolean_true_add(json_row
, "helloOptionGenerationId");
1311 if (option_holdtime
)
1312 json_object_boolean_true_add(json_row
, "helloOptionHoldtime");
1314 if (option_lan_prune_delay
)
1315 json_object_boolean_true_add(json_row
, "helloOptionLanPruneDelay");
1318 json_object_boolean_true_add(json_row
, "helloOptionTBit");
1320 json_object_object_add(json_ifp
, neigh_src_str
, json_row
);
1323 vty_out(vty
, "Interface : %s%s", ifp
->name
, VTY_NEWLINE
);
1324 vty_out(vty
, "Neighbor : %s%s", neigh_src_str
, VTY_NEWLINE
);
1325 vty_out(vty
, " Uptime : %s%s", uptime
, VTY_NEWLINE
);
1326 vty_out(vty
, " Holdtime : %s%s", expire
, VTY_NEWLINE
);
1327 vty_out(vty
, " DR Priority : %d%s", neigh
->dr_priority
, VTY_NEWLINE
);
1328 vty_out(vty
, " Generation ID : %08x%s", neigh
->generation_id
, VTY_NEWLINE
);
1329 vty_out(vty
, " Override Interval (msec) : %d%s", neigh
->override_interval_msec
, VTY_NEWLINE
);
1330 vty_out(vty
, " Propagation Delay (msec) : %d%s", neigh
->propagation_delay_msec
, VTY_NEWLINE
);
1331 vty_out(vty
, " Hello Option - Address List : %s%s", option_address_list
? "yes" : "no", VTY_NEWLINE
);
1332 vty_out(vty
, " Hello Option - DR Priority : %s%s", option_dr_priority
? "yes" : "no", VTY_NEWLINE
);
1333 vty_out(vty
, " Hello Option - Generation ID : %s%s", option_generation_id
? "yes" : "no", VTY_NEWLINE
);
1334 vty_out(vty
, " Hello Option - Holdtime : %s%s", option_holdtime
? "yes" : "no", VTY_NEWLINE
);
1335 vty_out(vty
, " Hello Option - LAN Prune Delay : %s%s", option_lan_prune_delay
? "yes" : "no", VTY_NEWLINE
);
1336 vty_out(vty
, " Hello Option - T-bit : %s%s", option_t_bit
? "yes" : "no", VTY_NEWLINE
);
1337 vty_out(vty
, "%s", VTY_NEWLINE
);
1343 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
1344 json_object_free(json
);
1347 if (!found_neighbor
)
1348 vty_out (vty
, "%% No such interface or neighbor%s", VTY_NEWLINE
);
1354 pim_show_state(struct vty
*vty
, const char *src_or_group
, const char *group
, u_char uj
)
1356 struct channel_oil
*c_oil
;
1357 struct listnode
*node
;
1358 json_object
*json
= NULL
;
1359 json_object
*json_group
= NULL
;
1360 json_object
*json_ifp_in
= NULL
;
1361 json_object
*json_ifp_out
= NULL
;
1362 json_object
*json_source
= NULL
;
1365 now
= pim_time_monotonic_sec();
1368 json
= json_object_new_object();
1370 vty_out(vty
, "Codes: J -> Pim Join, I -> IGMP Report, S -> Source, * -> Inherited from (*,G)");
1371 vty_out(vty
, "%sInstalled Source Group IIF OIL%s", VTY_NEWLINE
, VTY_NEWLINE
);
1374 for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list
, node
, c_oil
)) {
1375 char grp_str
[INET_ADDRSTRLEN
];
1376 char src_str
[INET_ADDRSTRLEN
];
1377 char in_ifname
[INTERFACE_NAMSIZ
+1];
1378 char out_ifname
[INTERFACE_NAMSIZ
+1];
1380 struct interface
*ifp_in
;
1383 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
, sizeof(grp_str
));
1384 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
, sizeof(src_str
));
1385 ifp_in
= pim_if_find_by_vif_index(c_oil
->oil
.mfcc_parent
);
1388 strcpy(in_ifname
, ifp_in
->name
);
1390 strcpy(in_ifname
, "<iif?>");
1394 if (strcmp(src_or_group
, src_str
) && strcmp(src_or_group
, grp_str
))
1397 if (group
&& strcmp(group
, grp_str
))
1403 /* Find the group, create it if it doesn't exist */
1404 json_object_object_get_ex(json
, grp_str
, &json_group
);
1407 json_group
= json_object_new_object();
1408 json_object_object_add(json
, grp_str
, json_group
);
1411 /* Find the source nested under the group, create it if it doesn't exist */
1412 json_object_object_get_ex(json_group
, src_str
, &json_source
);
1415 json_source
= json_object_new_object();
1416 json_object_object_add(json_group
, src_str
, json_source
);
1419 /* Find the inbound interface nested under the source, create it if it doesn't exist */
1420 json_object_object_get_ex(json_source
, in_ifname
, &json_ifp_in
);
1423 json_ifp_in
= json_object_new_object();
1424 json_object_object_add(json_source
, in_ifname
, json_ifp_in
);
1427 vty_out(vty
, "%-9d %-15s %-15s %-7s ",
1434 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
; ++oif_vif_index
) {
1435 struct interface
*ifp_out
;
1436 char oif_uptime
[10];
1439 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
1443 ifp_out
= pim_if_find_by_vif_index(oif_vif_index
);
1444 pim_time_uptime(oif_uptime
, sizeof(oif_uptime
), now
- c_oil
->oif_creation
[oif_vif_index
]);
1447 strcpy(out_ifname
, ifp_out
->name
);
1449 strcpy(out_ifname
, "<oif?>");
1452 json_ifp_out
= json_object_new_object();
1453 json_object_string_add(json_ifp_out
, "source", src_str
);
1454 json_object_string_add(json_ifp_out
, "group", grp_str
);
1455 json_object_string_add(json_ifp_out
, "inboundInterface", in_ifname
);
1456 json_object_string_add(json_ifp_out
, "outboundInterface", out_ifname
);
1457 json_object_int_add(json_ifp_out
, "installed", c_oil
->installed
);
1459 json_object_object_add(json_ifp_in
, out_ifname
, json_ifp_out
);
1464 vty_out(vty
, "%s(%c%c%c%c)", out_ifname
,
1465 (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_IGMP
) ? 'I' : ' ',
1466 (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_PIM
) ? 'J' : ' ',
1467 (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_SOURCE
) ? 'S' : ' ',
1468 (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_STAR
) ? '*' : ' ');
1471 vty_out(vty
, ", %s(%c%c%c%c)", out_ifname
,
1472 (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_IGMP
) ? 'I' : ' ',
1473 (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_PIM
) ? 'J' : ' ',
1474 (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_SOURCE
) ? 'S' : ' ',
1475 (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_STAR
) ? '*' : ' ' );
1480 vty_out(vty
, "%s", VTY_NEWLINE
);
1485 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
1486 json_object_free(json
);
1488 vty_out(vty
, "%s", VTY_NEWLINE
);
1492 static void pim_show_neighbors(struct vty
*vty
, u_char uj
)
1494 struct listnode
*node
;
1495 struct listnode
*neighnode
;
1496 struct interface
*ifp
;
1497 struct pim_interface
*pim_ifp
;
1498 struct pim_neighbor
*neigh
;
1502 char neigh_src_str
[INET_ADDRSTRLEN
];
1503 json_object
*json
= NULL
;
1504 json_object
*json_ifp_rows
= NULL
;
1505 json_object
*json_row
= NULL
;
1507 now
= pim_time_monotonic_sec();
1510 json
= json_object_new_object();
1512 vty_out(vty
, "Interface Neighbor Uptime Holdtime DR Pri%s", VTY_NEWLINE
);
1515 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
)) {
1516 pim_ifp
= ifp
->info
;
1521 if (pim_ifp
->pim_sock_fd
< 0)
1525 json_ifp_rows
= json_object_new_object();
1527 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
, neigh
)) {
1528 pim_inet4_dump("<src?>", neigh
->source_addr
,
1529 neigh_src_str
, sizeof(neigh_src_str
));
1530 pim_time_uptime(uptime
, sizeof(uptime
), now
- neigh
->creation
);
1531 pim_time_timer_to_hhmmss(expire
, sizeof(expire
), neigh
->t_expire_timer
);
1534 json_row
= json_object_new_object();
1535 json_object_string_add(json_row
, "interface", ifp
->name
);
1536 json_object_string_add(json_row
, "neighbor", neigh_src_str
);
1537 json_object_string_add(json_row
, "upTime", uptime
);
1538 json_object_string_add(json_row
, "holdTime", expire
);
1539 json_object_int_add(json_row
, "holdTimeMax", neigh
->holdtime
);
1540 json_object_int_add(json_row
, "drPriority", neigh
->dr_priority
);
1541 json_object_object_add(json_ifp_rows
, neigh_src_str
, json_row
);
1544 vty_out(vty
, "%-9s %15s %8s %8s %6d%s",
1555 json_object_object_add(json
, ifp
->name
, json_ifp_rows
);
1556 json_ifp_rows
= NULL
;
1561 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
1562 json_object_free(json
);
1566 static void pim_show_neighbors_secondary(struct vty
*vty
)
1568 struct listnode
*node
;
1569 struct interface
*ifp
;
1571 vty_out(vty
, "Interface Address Neighbor Secondary %s", VTY_NEWLINE
);
1573 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
)) {
1574 struct pim_interface
*pim_ifp
;
1575 struct in_addr ifaddr
;
1576 struct listnode
*neighnode
;
1577 struct pim_neighbor
*neigh
;
1579 pim_ifp
= ifp
->info
;
1584 if (pim_ifp
->pim_sock_fd
< 0)
1587 ifaddr
= pim_ifp
->primary_address
;
1589 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
, neigh
)) {
1590 char neigh_src_str
[INET_ADDRSTRLEN
];
1591 struct listnode
*prefix_node
;
1594 if (!neigh
->prefix_list
)
1597 pim_inet4_dump("<src?>", neigh
->source_addr
,
1598 neigh_src_str
, sizeof(neigh_src_str
));
1600 for (ALL_LIST_ELEMENTS_RO(neigh
->prefix_list
, prefix_node
, p
)) {
1601 char neigh_sec_str
[INET_ADDRSTRLEN
];
1603 if (p
->family
!= AF_INET
)
1606 pim_inet4_dump("<src?>", p
->u
.prefix4
,
1607 neigh_sec_str
, sizeof(neigh_sec_str
));
1609 vty_out(vty
, "%-9s %-15s %-15s %-15s%s",
1621 json_object_pim_upstream_add (json_object
*json
, struct pim_upstream
*up
)
1623 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED
)
1624 json_object_boolean_true_add(json
, "drJoinDesired");
1626 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED
)
1627 json_object_boolean_true_add(json
, "drJoinDesiredUpdated");
1629 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
1630 json_object_boolean_true_add(json
, "firstHopRouter");
1632 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_IGMP
)
1633 json_object_boolean_true_add(json
, "sourceIgmp");
1635 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_PIM
)
1636 json_object_boolean_true_add(json
, "sourcePim");
1638 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_STREAM
)
1639 json_object_boolean_true_add(json
, "sourceStream");
1641 /* XXX: need to print ths flag in the plain text display as well */
1642 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_MSDP
)
1643 json_object_boolean_true_add(json
, "sourceMsdp");
1646 static void pim_show_upstream(struct vty
*vty
, u_char uj
)
1648 struct listnode
*upnode
;
1649 struct pim_upstream
*up
;
1651 json_object
*json
= NULL
;
1652 json_object
*json_group
= NULL
;
1653 json_object
*json_row
= NULL
;
1655 now
= pim_time_monotonic_sec();
1658 json
= json_object_new_object();
1660 vty_out(vty
, "Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt%s", VTY_NEWLINE
);
1662 for (ALL_LIST_ELEMENTS_RO(pim_upstream_list
, upnode
, up
)) {
1663 char src_str
[INET_ADDRSTRLEN
];
1664 char grp_str
[INET_ADDRSTRLEN
];
1666 char join_timer
[10];
1669 char msdp_reg_timer
[10];
1671 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
1672 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
1673 pim_time_uptime(uptime
, sizeof(uptime
), now
- up
->state_transition
);
1674 pim_time_timer_to_hhmmss (join_timer
, sizeof(join_timer
), up
->t_join_timer
);
1675 pim_time_timer_to_hhmmss (rs_timer
, sizeof (rs_timer
), up
->t_rs_timer
);
1676 pim_time_timer_to_hhmmss (ka_timer
, sizeof (ka_timer
), up
->t_ka_timer
);
1677 pim_time_timer_to_hhmmss (msdp_reg_timer
, sizeof (msdp_reg_timer
), up
->t_msdp_reg_timer
);
1680 json_object_object_get_ex(json
, grp_str
, &json_group
);
1683 json_group
= json_object_new_object();
1684 json_object_object_add(json
, grp_str
, json_group
);
1687 json_row
= json_object_new_object();
1688 json_object_pim_upstream_add(json_row
, up
);
1689 json_object_string_add(json_row
, "inboundInterface", up
->rpf
.source_nexthop
.interface
->name
);
1690 json_object_string_add(json_row
, "source", src_str
);
1691 json_object_string_add(json_row
, "group", grp_str
);
1692 json_object_string_add(json_row
, "state", pim_upstream_state2str (up
->join_state
));
1693 json_object_string_add(json_row
, "upTime", uptime
);
1694 json_object_string_add(json_row
, "joinTimer", join_timer
);
1695 json_object_string_add(json_row
, "resetTimer", rs_timer
);
1696 json_object_string_add(json_row
, "keepaliveTimer", ka_timer
);
1697 json_object_string_add(json_row
, "msdpRegTimer", msdp_reg_timer
);
1698 json_object_int_add(json_row
, "refCount", up
->ref_count
);
1699 json_object_int_add(json_row
, "sptBit", up
->sptbit
);
1700 json_object_object_add(json_group
, src_str
, json_row
);
1702 vty_out(vty
, "%-10s%-15s %-15s %-11s %-8s %-9s %-9s %-9s %6d%s",
1703 up
->rpf
.source_nexthop
.interface
->name
,
1706 pim_upstream_state2str (up
->join_state
),
1717 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
1718 json_object_free(json
);
1722 static void pim_show_join_desired(struct vty
*vty
, u_char uj
)
1724 struct listnode
*chnode
;
1725 struct pim_interface
*pim_ifp
;
1726 struct pim_ifchannel
*ch
;
1727 char src_str
[INET_ADDRSTRLEN
];
1728 char grp_str
[INET_ADDRSTRLEN
];
1729 json_object
*json
= NULL
;
1730 json_object
*json_group
= NULL
;
1731 json_object
*json_row
= NULL
;
1734 json
= json_object_new_object();
1737 "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD%s",
1740 /* scan per-interface (S,G) state */
1741 for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list
, chnode
, ch
)) {
1742 /* scan all interfaces */
1743 pim_ifp
= ch
->interface
->info
;
1747 struct pim_upstream
*up
= ch
->upstream
;
1749 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
1750 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
1753 json_object_object_get_ex(json
, grp_str
, &json_group
);
1756 json_group
= json_object_new_object();
1757 json_object_object_add(json
, grp_str
, json_group
);
1760 json_row
= json_object_new_object();
1761 json_object_pim_upstream_add(json_row
, up
);
1762 json_object_string_add(json_row
, "interface", ch
->interface
->name
);
1763 json_object_string_add(json_row
, "source", src_str
);
1764 json_object_string_add(json_row
, "group", grp_str
);
1766 if (pim_macro_ch_lost_assert(ch
))
1767 json_object_boolean_true_add(json_row
, "lostAssert");
1769 if (pim_macro_chisin_joins(ch
))
1770 json_object_boolean_true_add(json_row
, "joins");
1772 if (pim_macro_chisin_pim_include(ch
))
1773 json_object_boolean_true_add(json_row
, "pimInclude");
1775 if (pim_upstream_evaluate_join_desired(up
))
1776 json_object_boolean_true_add(json_row
, "evaluateJoinDesired");
1778 json_object_object_add(json_group
, src_str
, json_row
);
1781 vty_out(vty
, "%-9s %-15s %-15s %-10s %-5s %-10s %-11s %-6s%s",
1782 ch
->interface
->name
,
1785 pim_macro_ch_lost_assert(ch
) ? "yes" : "no",
1786 pim_macro_chisin_joins(ch
) ? "yes" : "no",
1787 pim_macro_chisin_pim_include(ch
) ? "yes" : "no",
1788 PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(up
->flags
) ? "yes" : "no",
1789 pim_upstream_evaluate_join_desired(up
) ? "yes" : "no",
1795 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
1796 json_object_free(json
);
1800 static void pim_show_upstream_rpf(struct vty
*vty
, u_char uj
)
1802 struct listnode
*upnode
;
1803 struct pim_upstream
*up
;
1804 json_object
*json
= NULL
;
1805 json_object
*json_group
= NULL
;
1806 json_object
*json_row
= NULL
;
1809 json
= json_object_new_object();
1812 "Source Group RpfIface RibNextHop RpfAddress %s",
1815 for (ALL_LIST_ELEMENTS_RO(pim_upstream_list
, upnode
, up
)) {
1816 char src_str
[INET_ADDRSTRLEN
];
1817 char grp_str
[INET_ADDRSTRLEN
];
1818 char rpf_nexthop_str
[PREFIX_STRLEN
];
1819 char rpf_addr_str
[PREFIX_STRLEN
];
1820 struct pim_rpf
*rpf
;
1821 const char *rpf_ifname
;
1825 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
1826 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
1827 pim_addr_dump("<nexthop?>", &rpf
->source_nexthop
.mrib_nexthop_addr
, rpf_nexthop_str
, sizeof(rpf_nexthop_str
));
1828 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
, sizeof(rpf_addr_str
));
1830 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
1833 json_object_object_get_ex(json
, grp_str
, &json_group
);
1836 json_group
= json_object_new_object();
1837 json_object_object_add(json
, grp_str
, json_group
);
1840 json_row
= json_object_new_object();
1841 json_object_pim_upstream_add(json_row
, up
);
1842 json_object_string_add(json_row
, "source", src_str
);
1843 json_object_string_add(json_row
, "group", grp_str
);
1844 json_object_string_add(json_row
, "rpfInterface", rpf_ifname
);
1845 json_object_string_add(json_row
, "ribNexthop", rpf_nexthop_str
);
1846 json_object_string_add(json_row
, "rpfAddress", rpf_addr_str
);
1847 json_object_object_add(json_group
, src_str
, json_row
);
1849 vty_out(vty
, "%-15s %-15s %-8s %-15s %-15s%s",
1860 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
1861 json_object_free(json
);
1865 static void show_rpf_refresh_stats(struct vty
*vty
, time_t now
, json_object
*json
)
1867 char refresh_uptime
[10];
1869 pim_time_uptime_begin(refresh_uptime
, sizeof(refresh_uptime
), now
, qpim_rpf_cache_refresh_last
);
1872 json_object_int_add(json
, "rpfCacheRefreshDelayMsecs", qpim_rpf_cache_refresh_delay_msec
);
1873 json_object_int_add(json
, "rpfCacheRefreshTimer", pim_time_timer_remain_msec(qpim_rpf_cache_refresher
));
1874 json_object_int_add(json
, "rpfCacheRefreshRequests", qpim_rpf_cache_refresh_requests
);
1875 json_object_int_add(json
, "rpfCacheRefreshEvents", qpim_rpf_cache_refresh_events
);
1876 json_object_string_add(json
, "rpfCacheRefreshLast", refresh_uptime
);
1877 json_object_int_add(json
, "nexthopLookups", qpim_nexthop_lookups
);
1878 json_object_int_add(json
, "nexthopLookupsAvoided", nexthop_lookups_avoided
);
1881 "RPF Cache Refresh Delay: %ld msecs%s"
1882 "RPF Cache Refresh Timer: %ld msecs%s"
1883 "RPF Cache Refresh Requests: %lld%s"
1884 "RPF Cache Refresh Events: %lld%s"
1885 "RPF Cache Refresh Last: %s%s"
1886 "Nexthop Lookups: %lld%s"
1887 "Nexthop Lookups Avoided: %lld%s",
1888 qpim_rpf_cache_refresh_delay_msec
, VTY_NEWLINE
,
1889 pim_time_timer_remain_msec(qpim_rpf_cache_refresher
), VTY_NEWLINE
,
1890 (long long)qpim_rpf_cache_refresh_requests
, VTY_NEWLINE
,
1891 (long long)qpim_rpf_cache_refresh_events
, VTY_NEWLINE
,
1892 refresh_uptime
, VTY_NEWLINE
,
1893 (long long) qpim_nexthop_lookups
, VTY_NEWLINE
,
1894 (long long)nexthop_lookups_avoided
, VTY_NEWLINE
);
1898 static void show_scan_oil_stats(struct vty
*vty
, time_t now
)
1900 char uptime_scan_oil
[10];
1901 char uptime_mroute_add
[10];
1902 char uptime_mroute_del
[10];
1904 pim_time_uptime_begin(uptime_scan_oil
, sizeof(uptime_scan_oil
), now
, qpim_scan_oil_last
);
1905 pim_time_uptime_begin(uptime_mroute_add
, sizeof(uptime_mroute_add
), now
, qpim_mroute_add_last
);
1906 pim_time_uptime_begin(uptime_mroute_del
, sizeof(uptime_mroute_del
), now
, qpim_mroute_del_last
);
1909 "Scan OIL - Last: %s Events: %lld%s"
1910 "MFC Add - Last: %s Events: %lld%s"
1911 "MFC Del - Last: %s Events: %lld%s",
1912 uptime_scan_oil
, (long long) qpim_scan_oil_events
, VTY_NEWLINE
,
1913 uptime_mroute_add
, (long long) qpim_mroute_add_events
, VTY_NEWLINE
,
1914 uptime_mroute_del
, (long long) qpim_mroute_del_events
, VTY_NEWLINE
);
1917 static void pim_show_rpf(struct vty
*vty
, u_char uj
)
1919 struct listnode
*up_node
;
1920 struct pim_upstream
*up
;
1921 time_t now
= pim_time_monotonic_sec();
1922 json_object
*json
= NULL
;
1923 json_object
*json_group
= NULL
;
1924 json_object
*json_row
= NULL
;
1927 json
= json_object_new_object();
1928 show_rpf_refresh_stats(vty
, now
, json
);
1930 show_rpf_refresh_stats(vty
, now
, json
);
1931 vty_out(vty
, "%s", VTY_NEWLINE
);
1933 "Source Group RpfIface RpfAddress RibNextHop Metric Pref%s",
1937 for (ALL_LIST_ELEMENTS_RO(pim_upstream_list
, up_node
, up
)) {
1938 char src_str
[INET_ADDRSTRLEN
];
1939 char grp_str
[INET_ADDRSTRLEN
];
1940 char rpf_addr_str
[PREFIX_STRLEN
];
1941 char rib_nexthop_str
[PREFIX_STRLEN
];
1942 const char *rpf_ifname
;
1943 struct pim_rpf
*rpf
= &up
->rpf
;
1945 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
1946 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
1947 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
, sizeof(rpf_addr_str
));
1948 pim_addr_dump("<nexthop?>", &rpf
->source_nexthop
.mrib_nexthop_addr
, rib_nexthop_str
, sizeof(rib_nexthop_str
));
1950 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
1953 json_object_object_get_ex(json
, grp_str
, &json_group
);
1956 json_group
= json_object_new_object();
1957 json_object_object_add(json
, grp_str
, json_group
);
1960 json_row
= json_object_new_object();
1961 json_object_string_add(json_row
, "source", src_str
);
1962 json_object_string_add(json_row
, "group", grp_str
);
1963 json_object_string_add(json_row
, "rpfInterface", rpf_ifname
);
1964 json_object_string_add(json_row
, "rpfAddress", rpf_addr_str
);
1965 json_object_string_add(json_row
, "ribNexthop", rib_nexthop_str
);
1966 json_object_int_add(json_row
, "routeMetric", rpf
->source_nexthop
.mrib_route_metric
);
1967 json_object_int_add(json_row
, "routePreference", rpf
->source_nexthop
.mrib_metric_preference
);
1968 json_object_object_add(json_group
, src_str
, json_row
);
1971 vty_out(vty
, "%-15s %-15s %-8s %-15s %-15s %6d %4d%s",
1977 rpf
->source_nexthop
.mrib_route_metric
,
1978 rpf
->source_nexthop
.mrib_metric_preference
,
1984 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
1985 json_object_free(json
);
1989 static void igmp_show_groups(struct vty
*vty
, u_char uj
)
1991 struct listnode
*ifnode
;
1992 struct interface
*ifp
;
1994 json_object
*json
= NULL
;
1995 json_object
*json_iface
= NULL
;
1996 json_object
*json_row
= NULL
;
1998 now
= pim_time_monotonic_sec();
2001 json
= json_object_new_object();
2003 vty_out(vty
, "Interface Address Group Mode Timer Srcs V Uptime %s", VTY_NEWLINE
);
2005 /* scan interfaces */
2006 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), ifnode
, ifp
)) {
2007 struct pim_interface
*pim_ifp
= ifp
->info
;
2008 struct listnode
*sock_node
;
2009 struct igmp_sock
*igmp
;
2014 /* scan igmp sockets */
2015 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
2016 char ifaddr_str
[INET_ADDRSTRLEN
];
2017 struct listnode
*grpnode
;
2018 struct igmp_group
*grp
;
2020 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
, sizeof(ifaddr_str
));
2022 /* scan igmp groups */
2023 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grpnode
, grp
)) {
2024 char group_str
[INET_ADDRSTRLEN
];
2028 pim_inet4_dump("<group?>", grp
->group_addr
, group_str
, sizeof(group_str
));
2029 pim_time_timer_to_hhmmss(hhmmss
, sizeof(hhmmss
), grp
->t_group_timer
);
2030 pim_time_uptime(uptime
, sizeof(uptime
), now
- grp
->group_creation
);
2033 json_object_object_get_ex(json
, ifp
->name
, &json_iface
);
2036 json_iface
= json_object_new_object();
2037 json_object_pim_ifp_add(json_iface
, ifp
);
2038 json_object_object_add(json
, ifp
->name
, json_iface
);
2041 json_row
= json_object_new_object();
2042 json_object_string_add(json_row
, "source", ifaddr_str
);
2043 json_object_string_add(json_row
, "group", group_str
);
2045 if (grp
->igmp_version
== 3)
2046 json_object_string_add(json_row
, "mode", grp
->group_filtermode_isexcl
? "EXCLUDE" : "INCLUDE");
2048 json_object_string_add(json_row
, "timer", hhmmss
);
2049 json_object_int_add(json_row
, "sourcesCount", grp
->group_source_list
? listcount(grp
->group_source_list
) : 0);
2050 json_object_int_add(json_row
, "version", grp
->igmp_version
);
2051 json_object_string_add(json_row
, "uptime", uptime
);
2052 json_object_object_add(json_iface
, group_str
, json_row
);
2055 vty_out(vty
, "%-9s %-15s %-15s %4s %8s %4d %d %8s%s",
2059 grp
->igmp_version
== 3 ? (grp
->group_filtermode_isexcl
? "EXCL" : "INCL") : "----",
2061 grp
->group_source_list
? listcount(grp
->group_source_list
) : 0,
2066 } /* scan igmp groups */
2067 } /* scan igmp sockets */
2068 } /* scan interfaces */
2071 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
2072 json_object_free(json
);
2076 static void igmp_show_group_retransmission(struct vty
*vty
)
2078 struct listnode
*ifnode
;
2079 struct interface
*ifp
;
2081 vty_out(vty
, "Interface Address Group RetTimer Counter RetSrcs%s", VTY_NEWLINE
);
2083 /* scan interfaces */
2084 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), ifnode
, ifp
)) {
2085 struct pim_interface
*pim_ifp
= ifp
->info
;
2086 struct listnode
*sock_node
;
2087 struct igmp_sock
*igmp
;
2092 /* scan igmp sockets */
2093 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
2094 char ifaddr_str
[INET_ADDRSTRLEN
];
2095 struct listnode
*grpnode
;
2096 struct igmp_group
*grp
;
2098 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
, sizeof(ifaddr_str
));
2100 /* scan igmp groups */
2101 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grpnode
, grp
)) {
2102 char group_str
[INET_ADDRSTRLEN
];
2103 char grp_retr_mmss
[10];
2104 struct listnode
*src_node
;
2105 struct igmp_source
*src
;
2106 int grp_retr_sources
= 0;
2108 pim_inet4_dump("<group?>", grp
->group_addr
, group_str
, sizeof(group_str
));
2109 pim_time_timer_to_mmss(grp_retr_mmss
, sizeof(grp_retr_mmss
), grp
->t_group_query_retransmit_timer
);
2112 /* count group sources with retransmission state */
2113 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
, src_node
, src
)) {
2114 if (src
->source_query_retransmit_count
> 0) {
2119 vty_out(vty
, "%-9s %-15s %-15s %-8s %7d %7d%s",
2124 grp
->group_specific_query_retransmit_count
,
2128 } /* scan igmp groups */
2129 } /* scan igmp sockets */
2130 } /* scan interfaces */
2133 static void igmp_show_sources(struct vty
*vty
)
2135 struct listnode
*ifnode
;
2136 struct interface
*ifp
;
2139 now
= pim_time_monotonic_sec();
2141 vty_out(vty
, "Interface Address Group Source Timer Fwd Uptime %s", VTY_NEWLINE
);
2143 /* scan interfaces */
2144 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), ifnode
, ifp
)) {
2145 struct pim_interface
*pim_ifp
= ifp
->info
;
2146 struct listnode
*sock_node
;
2147 struct igmp_sock
*igmp
;
2152 /* scan igmp sockets */
2153 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
2154 char ifaddr_str
[INET_ADDRSTRLEN
];
2155 struct listnode
*grpnode
;
2156 struct igmp_group
*grp
;
2158 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
, sizeof(ifaddr_str
));
2160 /* scan igmp groups */
2161 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grpnode
, grp
)) {
2162 char group_str
[INET_ADDRSTRLEN
];
2163 struct listnode
*srcnode
;
2164 struct igmp_source
*src
;
2166 pim_inet4_dump("<group?>", grp
->group_addr
, group_str
, sizeof(group_str
));
2168 /* scan group sources */
2169 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
, srcnode
, src
)) {
2170 char source_str
[INET_ADDRSTRLEN
];
2174 pim_inet4_dump("<source?>", src
->source_addr
, source_str
, sizeof(source_str
));
2176 pim_time_timer_to_mmss(mmss
, sizeof(mmss
), src
->t_source_timer
);
2178 pim_time_uptime(uptime
, sizeof(uptime
), now
- src
->source_creation
);
2180 vty_out(vty
, "%-9s %-15s %-15s %-15s %5s %3s %8s%s",
2186 IGMP_SOURCE_TEST_FORWARDING(src
->source_flags
) ? "Y" : "N",
2190 } /* scan group sources */
2191 } /* scan igmp groups */
2192 } /* scan igmp sockets */
2193 } /* scan interfaces */
2196 static void igmp_show_source_retransmission(struct vty
*vty
)
2198 struct listnode
*ifnode
;
2199 struct interface
*ifp
;
2201 vty_out(vty
, "Interface Address Group Source Counter%s", VTY_NEWLINE
);
2203 /* scan interfaces */
2204 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), ifnode
, ifp
)) {
2205 struct pim_interface
*pim_ifp
= ifp
->info
;
2206 struct listnode
*sock_node
;
2207 struct igmp_sock
*igmp
;
2212 /* scan igmp sockets */
2213 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
2214 char ifaddr_str
[INET_ADDRSTRLEN
];
2215 struct listnode
*grpnode
;
2216 struct igmp_group
*grp
;
2218 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
, sizeof(ifaddr_str
));
2220 /* scan igmp groups */
2221 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grpnode
, grp
)) {
2222 char group_str
[INET_ADDRSTRLEN
];
2223 struct listnode
*srcnode
;
2224 struct igmp_source
*src
;
2226 pim_inet4_dump("<group?>", grp
->group_addr
, group_str
, sizeof(group_str
));
2228 /* scan group sources */
2229 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
, srcnode
, src
)) {
2230 char source_str
[INET_ADDRSTRLEN
];
2232 pim_inet4_dump("<source?>", src
->source_addr
, source_str
, sizeof(source_str
));
2234 vty_out(vty
, "%-9s %-15s %-15s %-15s %7d%s",
2239 src
->source_query_retransmit_count
,
2242 } /* scan group sources */
2243 } /* scan igmp groups */
2244 } /* scan igmp sockets */
2245 } /* scan interfaces */
2248 static void clear_igmp_interfaces()
2250 struct listnode
*ifnode
;
2251 struct listnode
*ifnextnode
;
2252 struct interface
*ifp
;
2254 for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT
), ifnode
, ifnextnode
, ifp
)) {
2255 pim_if_addr_del_all_igmp(ifp
);
2258 for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT
), ifnode
, ifnextnode
, ifp
)) {
2259 pim_if_addr_add_all(ifp
);
2263 static void clear_pim_interfaces()
2265 struct listnode
*ifnode
;
2266 struct listnode
*ifnextnode
;
2267 struct interface
*ifp
;
2269 for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT
), ifnode
, ifnextnode
, ifp
)) {
2271 pim_neighbor_delete_all(ifp
, "interface cleared");
2276 static void clear_interfaces()
2278 clear_igmp_interfaces();
2279 clear_pim_interfaces();
2282 DEFUN (clear_ip_interfaces
,
2283 clear_ip_interfaces_cmd
,
2284 "clear ip interfaces",
2287 "Reset interfaces\n")
2294 DEFUN (clear_ip_igmp_interfaces
,
2295 clear_ip_igmp_interfaces_cmd
,
2296 "clear ip igmp interfaces",
2300 "Reset IGMP interfaces\n")
2302 clear_igmp_interfaces();
2307 static void mroute_add_all()
2309 struct listnode
*node
;
2310 struct channel_oil
*c_oil
;
2312 for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list
, node
, c_oil
)) {
2313 if (pim_mroute_add(c_oil
, __PRETTY_FUNCTION__
)) {
2314 /* just log warning */
2315 char source_str
[INET_ADDRSTRLEN
];
2316 char group_str
[INET_ADDRSTRLEN
];
2317 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, source_str
, sizeof(source_str
));
2318 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, group_str
, sizeof(group_str
));
2319 zlog_warn("%s %s: (S,G)=(%s,%s) failure writing MFC",
2320 __FILE__
, __PRETTY_FUNCTION__
,
2321 source_str
, group_str
);
2326 static void mroute_del_all()
2328 struct listnode
*node
;
2329 struct channel_oil
*c_oil
;
2331 for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list
, node
, c_oil
)) {
2332 if (pim_mroute_del(c_oil
, __PRETTY_FUNCTION__
)) {
2333 /* just log warning */
2334 char source_str
[INET_ADDRSTRLEN
];
2335 char group_str
[INET_ADDRSTRLEN
];
2336 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, source_str
, sizeof(source_str
));
2337 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, group_str
, sizeof(group_str
));
2338 zlog_warn("%s %s: (S,G)=(%s,%s) failure clearing MFC",
2339 __FILE__
, __PRETTY_FUNCTION__
,
2340 source_str
, group_str
);
2345 static void static_mroute_add_all()
2347 struct listnode
*node
;
2348 struct static_route
*s_route
;
2350 for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list
, node
, s_route
)) {
2351 if (pim_mroute_add(&s_route
->c_oil
, __PRETTY_FUNCTION__
)) {
2352 /* just log warning */
2353 char source_str
[INET_ADDRSTRLEN
];
2354 char group_str
[INET_ADDRSTRLEN
];
2355 pim_inet4_dump("<source?>", s_route
->c_oil
.oil
.mfcc_origin
, source_str
, sizeof(source_str
));
2356 pim_inet4_dump("<group?>", s_route
->c_oil
.oil
.mfcc_mcastgrp
, group_str
, sizeof(group_str
));
2357 zlog_warn("%s %s: (S,G)=(%s,%s) failure writing MFC",
2358 __FILE__
, __PRETTY_FUNCTION__
,
2359 source_str
, group_str
);
2364 static void static_mroute_del_all()
2366 struct listnode
*node
;
2367 struct static_route
*s_route
;
2369 for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list
, node
, s_route
)) {
2370 if (pim_mroute_del(&s_route
->c_oil
, __PRETTY_FUNCTION__
)) {
2371 /* just log warning */
2372 char source_str
[INET_ADDRSTRLEN
];
2373 char group_str
[INET_ADDRSTRLEN
];
2374 pim_inet4_dump("<source?>", s_route
->c_oil
.oil
.mfcc_origin
, source_str
, sizeof(source_str
));
2375 pim_inet4_dump("<group?>", s_route
->c_oil
.oil
.mfcc_mcastgrp
, group_str
, sizeof(group_str
));
2376 zlog_warn("%s %s: (S,G)=(%s,%s) failure clearing MFC",
2377 __FILE__
, __PRETTY_FUNCTION__
,
2378 source_str
, group_str
);
2383 DEFUN (clear_ip_mroute
,
2384 clear_ip_mroute_cmd
,
2388 "Reset multicast routes\n")
2396 DEFUN (clear_ip_pim_interfaces
,
2397 clear_ip_pim_interfaces_cmd
,
2398 "clear ip pim interfaces",
2402 "Reset PIM interfaces\n")
2404 clear_pim_interfaces();
2409 DEFUN (clear_ip_pim_oil
,
2410 clear_ip_pim_oil_cmd
,
2415 "Rescan PIM OIL (output interface list)\n")
2422 DEFUN (show_ip_igmp_interface
,
2423 show_ip_igmp_interface_cmd
,
2424 "show ip igmp interface [detail|WORD] [json]",
2428 "IGMP interface information\n"
2431 "JavaScript Object Notation\n")
2433 u_char uj
= use_json(argc
, argv
);
2436 if (argv_find(argv
, argc
, "detail", &idx
) ||
2437 argv_find(argv
, argc
, "WORD", &idx
))
2438 igmp_show_interfaces_single(vty
, argv
[idx
]->arg
, uj
);
2440 igmp_show_interfaces(vty
, uj
);
2445 DEFUN (show_ip_igmp_join
,
2446 show_ip_igmp_join_cmd
,
2447 "show ip igmp join",
2451 "IGMP static join information\n")
2453 igmp_show_interface_join(vty
);
2458 DEFUN (show_ip_igmp_groups
,
2459 show_ip_igmp_groups_cmd
,
2460 "show ip igmp groups [json]",
2465 "JavaScript Object Notation\n")
2467 u_char uj
= use_json(argc
, argv
);
2468 igmp_show_groups(vty
, uj
);
2473 DEFUN (show_ip_igmp_groups_retransmissions
,
2474 show_ip_igmp_groups_retransmissions_cmd
,
2475 "show ip igmp groups retransmissions",
2480 "IGMP group retransmissions\n")
2482 igmp_show_group_retransmission(vty
);
2487 DEFUN (show_ip_igmp_sources
,
2488 show_ip_igmp_sources_cmd
,
2489 "show ip igmp sources",
2495 igmp_show_sources(vty
);
2500 DEFUN (show_ip_igmp_sources_retransmissions
,
2501 show_ip_igmp_sources_retransmissions_cmd
,
2502 "show ip igmp sources retransmissions",
2507 "IGMP source retransmissions\n")
2509 igmp_show_source_retransmission(vty
);
2514 DEFUN (show_ip_pim_assert
,
2515 show_ip_pim_assert_cmd
,
2516 "show ip pim assert",
2520 "PIM interface assert\n")
2522 pim_show_assert(vty
);
2527 DEFUN (show_ip_pim_assert_internal
,
2528 show_ip_pim_assert_internal_cmd
,
2529 "show ip pim assert-internal",
2533 "PIM interface internal assert state\n")
2535 pim_show_assert_internal(vty
);
2540 DEFUN (show_ip_pim_assert_metric
,
2541 show_ip_pim_assert_metric_cmd
,
2542 "show ip pim assert-metric",
2546 "PIM interface assert metric\n")
2548 pim_show_assert_metric(vty
);
2553 DEFUN (show_ip_pim_assert_winner_metric
,
2554 show_ip_pim_assert_winner_metric_cmd
,
2555 "show ip pim assert-winner-metric",
2559 "PIM interface assert winner metric\n")
2561 pim_show_assert_winner_metric(vty
);
2566 DEFUN (show_ip_pim_interface
,
2567 show_ip_pim_interface_cmd
,
2568 "show ip pim interface [detail|WORD] [json]",
2572 "PIM interface information\n"
2575 "JavaScript Object Notation\n")
2577 u_char uj
= use_json(argc
, argv
);
2580 if (argv_find(argv
, argc
, "WORD", &idx
) ||
2581 argv_find(argv
, argc
, "detail", &idx
))
2582 pim_show_interfaces_single(vty
, argv
[idx
]->arg
, uj
);
2585 pim_show_interfaces(vty
, uj
);
2590 DEFUN (show_ip_pim_join
,
2591 show_ip_pim_join_cmd
,
2592 "show ip pim join [json]",
2596 "PIM interface join information\n"
2599 u_char uj
= use_json(argc
, argv
);
2600 pim_show_join(vty
, uj
);
2605 DEFUN (show_ip_pim_local_membership
,
2606 show_ip_pim_local_membership_cmd
,
2607 "show ip pim local-membership [json]",
2611 "PIM interface local-membership\n"
2614 u_char uj
= use_json(argc
, argv
);
2615 pim_show_membership(vty
, uj
);
2620 DEFUN (show_ip_pim_neighbor
,
2621 show_ip_pim_neighbor_cmd
,
2622 "show ip pim neighbor [detail|WORD] [json]",
2626 "PIM neighbor information\n"
2628 "Name of interface or neighbor\n"
2629 "JavaScript Object Notation\n")
2631 u_char uj
= use_json(argc
, argv
);
2634 if (argv_find(argv
, argc
, "detail", &idx
) ||
2635 argv_find(argv
, argc
, "WORD", &idx
))
2636 pim_show_neighbors_single(vty
, argv
[idx
]->arg
, uj
);
2638 pim_show_neighbors(vty
, uj
);
2643 DEFUN (show_ip_pim_secondary
,
2644 show_ip_pim_secondary_cmd
,
2645 "show ip pim secondary",
2649 "PIM neighbor addresses\n")
2651 pim_show_neighbors_secondary(vty
);
2656 DEFUN (show_ip_pim_state
,
2657 show_ip_pim_state_cmd
,
2658 "show ip pim state [A.B.C.D [A.B.C.D]] [json]",
2662 "PIM state information\n"
2663 "Unicast or Multicast address\n"
2664 "Multicast address\n"
2665 "JavaScript Object Notation\n")
2667 const char *src_or_group
= NULL
;
2668 const char *group
= NULL
;
2669 u_char uj
= use_json(argc
, argv
);
2675 src_or_group
= argv
[4]->arg
;
2676 group
= argv
[5]->arg
;
2679 src_or_group
= argv
[4]->arg
;
2681 pim_show_state(vty
, src_or_group
, group
, uj
);
2686 DEFUN (show_ip_pim_upstream
,
2687 show_ip_pim_upstream_cmd
,
2688 "show ip pim upstream [json]",
2692 "PIM upstream information\n"
2693 "JavaScript Object Notation\n")
2695 u_char uj
= use_json(argc
, argv
);
2696 pim_show_upstream(vty
, uj
);
2701 DEFUN (show_ip_pim_upstream_join_desired
,
2702 show_ip_pim_upstream_join_desired_cmd
,
2703 "show ip pim upstream-join-desired [json]",
2707 "PIM upstream join-desired\n"
2708 "JavaScript Object Notation\n")
2710 u_char uj
= use_json(argc
, argv
);
2711 pim_show_join_desired(vty
, uj
);
2716 DEFUN (show_ip_pim_upstream_rpf
,
2717 show_ip_pim_upstream_rpf_cmd
,
2718 "show ip pim upstream-rpf [json]",
2722 "PIM upstream source rpf\n"
2723 "JavaScript Object Notation\n")
2725 u_char uj
= use_json(argc
, argv
);
2726 pim_show_upstream_rpf(vty
, uj
);
2731 DEFUN (show_ip_pim_rp
,
2733 "show ip pim rp-info [json]",
2737 "PIM RP information\n"
2738 "JavaScript Object Notation\n")
2740 u_char uj
= use_json(argc
, argv
);
2741 pim_rp_show_information (vty
, uj
);
2746 DEFUN (show_ip_pim_rpf
,
2747 show_ip_pim_rpf_cmd
,
2748 "show ip pim rpf [json]",
2752 "PIM cached source rpf information\n"
2753 "JavaScript Object Notation\n")
2755 u_char uj
= use_json(argc
, argv
);
2756 pim_show_rpf(vty
, uj
);
2761 static void show_multicast_interfaces(struct vty
*vty
)
2763 struct listnode
*node
;
2764 struct interface
*ifp
;
2766 vty_out(vty
, "%s", VTY_NEWLINE
);
2768 vty_out(vty
, "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut%s",
2771 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
)) {
2772 struct pim_interface
*pim_ifp
;
2773 struct in_addr ifaddr
;
2774 struct sioc_vif_req vreq
;
2776 pim_ifp
= ifp
->info
;
2781 memset(&vreq
, 0, sizeof(vreq
));
2782 vreq
.vifi
= pim_ifp
->mroute_vif_index
;
2784 if (ioctl(qpim_mroute_socket_fd
, SIOCGETVIFCNT
, &vreq
)) {
2785 zlog_warn("ioctl(SIOCGETVIFCNT=%lu) failure for interface %s vif_index=%d: errno=%d: %s%s",
2786 (unsigned long)SIOCGETVIFCNT
,
2788 pim_ifp
->mroute_vif_index
,
2790 safe_strerror(errno
),
2794 ifaddr
= pim_ifp
->primary_address
;
2796 vty_out(vty
, "%-9s %-15s %3d %3d %7lu %7lu %10lu %10lu%s",
2800 pim_ifp
->mroute_vif_index
,
2801 (unsigned long) vreq
.icount
,
2802 (unsigned long) vreq
.ocount
,
2803 (unsigned long) vreq
.ibytes
,
2804 (unsigned long) vreq
.obytes
,
2809 DEFUN (show_ip_multicast
,
2810 show_ip_multicast_cmd
,
2811 "show ip multicast",
2814 "Multicast global information\n")
2816 time_t now
= pim_time_monotonic_sec();
2818 if (PIM_MROUTE_IS_ENABLED
) {
2821 vty_out(vty
, "Mroute socket descriptor: %d%s",
2822 qpim_mroute_socket_fd
,
2825 pim_time_uptime(uptime
, sizeof(uptime
), now
- qpim_mroute_socket_creation
);
2826 vty_out(vty
, "Mroute socket uptime: %s%s",
2831 vty_out(vty
, "Multicast disabled%s",
2835 vty_out(vty
, "%s", VTY_NEWLINE
);
2837 pim_zebra_zclient_update (vty
);
2838 pim_zlookup_show_ip_multicast (vty
);
2840 vty_out(vty
, "%s", VTY_NEWLINE
);
2841 vty_out(vty
, "Maximum highest VifIndex: %d%s",
2842 PIM_MAX_USABLE_VIFS
,
2845 vty_out(vty
, "%s", VTY_NEWLINE
);
2846 vty_out(vty
, "Upstream Join Timer: %d secs%s",
2849 vty_out(vty
, "Join/Prune Holdtime: %d secs%s",
2853 vty_out(vty
, "%s", VTY_NEWLINE
);
2855 show_rpf_refresh_stats(vty
, now
, NULL
);
2857 vty_out(vty
, "%s", VTY_NEWLINE
);
2859 show_scan_oil_stats(vty
, now
);
2861 show_multicast_interfaces(vty
);
2866 static void show_mroute(struct vty
*vty
, u_char uj
)
2868 struct listnode
*node
;
2869 struct channel_oil
*c_oil
;
2870 struct static_route
*s_route
;
2872 json_object
*json
= NULL
;
2873 json_object
*json_group
= NULL
;
2874 json_object
*json_source
= NULL
;
2875 json_object
*json_oil
= NULL
;
2876 json_object
*json_ifp_out
= NULL
;
2879 char grp_str
[INET_ADDRSTRLEN
];
2880 char src_str
[INET_ADDRSTRLEN
];
2881 char in_ifname
[INTERFACE_NAMSIZ
+1];
2882 char out_ifname
[INTERFACE_NAMSIZ
+1];
2884 struct interface
*ifp_in
;
2888 json
= json_object_new_object();
2890 vty_out(vty
, "Source Group Proto Input Output TTL Uptime%s",
2894 now
= pim_time_monotonic_sec();
2896 /* print list of PIM and IGMP routes */
2897 for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list
, node
, c_oil
)) {
2900 if (!c_oil
->installed
&& !uj
)
2903 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
, sizeof(grp_str
));
2904 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
, sizeof(src_str
));
2905 ifp_in
= pim_if_find_by_vif_index(c_oil
->oil
.mfcc_parent
);
2908 strcpy(in_ifname
, ifp_in
->name
);
2910 strcpy(in_ifname
, "<iif?>");
2914 /* Find the group, create it if it doesn't exist */
2915 json_object_object_get_ex(json
, grp_str
, &json_group
);
2918 json_group
= json_object_new_object();
2919 json_object_object_add(json
, grp_str
, json_group
);
2922 /* Find the source nested under the group, create it if it doesn't exist */
2923 json_object_object_get_ex(json_group
, src_str
, &json_source
);
2926 json_source
= json_object_new_object();
2927 json_object_object_add(json_group
, src_str
, json_source
);
2930 /* Find the inbound interface nested under the source, create it if it doesn't exist */
2931 json_object_int_add(json_source
, "installed", c_oil
->installed
);
2932 json_object_int_add(json_source
, "refCount", c_oil
->oil_ref_count
);
2933 json_object_int_add(json_source
, "oilSize", c_oil
->oil_size
);
2934 json_object_int_add(json_source
, "OilInheritedRescan", c_oil
->oil_inherited_rescan
);
2935 json_object_string_add(json_source
, "iif", in_ifname
);
2939 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
; ++oif_vif_index
) {
2940 struct interface
*ifp_out
;
2941 char oif_uptime
[10];
2944 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
2948 ifp_out
= pim_if_find_by_vif_index(oif_vif_index
);
2949 pim_time_uptime(oif_uptime
, sizeof(oif_uptime
), now
- c_oil
->oif_creation
[oif_vif_index
]);
2953 strcpy(out_ifname
, ifp_out
->name
);
2955 strcpy(out_ifname
, "<oif?>");
2958 json_ifp_out
= json_object_new_object();
2959 json_object_string_add(json_ifp_out
, "source", src_str
);
2960 json_object_string_add(json_ifp_out
, "group", grp_str
);
2962 if (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_PIM
)
2963 json_object_boolean_true_add(json_ifp_out
, "protocolPim");
2965 if (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_IGMP
)
2966 json_object_boolean_true_add(json_ifp_out
, "protocolIgmp");
2968 if (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_SOURCE
)
2969 json_object_boolean_true_add(json_ifp_out
, "protocolSource");
2971 if (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_STAR
)
2972 json_object_boolean_true_add(json_ifp_out
, "protocolInherited");
2974 json_object_string_add(json_ifp_out
, "inboundInterface", in_ifname
);
2975 json_object_int_add(json_ifp_out
, "iVifI", c_oil
->oil
.mfcc_parent
);
2976 json_object_string_add(json_ifp_out
, "outboundInterface", out_ifname
);
2977 json_object_int_add(json_ifp_out
, "oVifI", oif_vif_index
);
2978 json_object_int_add(json_ifp_out
, "ttl", ttl
);
2979 json_object_string_add(json_ifp_out
, "upTime", oif_uptime
);
2981 json_oil
= json_object_new_object();
2982 json_object_object_add(json_source
, "oil", json_oil
);
2984 json_object_object_add(json_oil
, out_ifname
, json_ifp_out
);
2986 if (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_PIM
) {
2987 strcpy(proto
, "PIM");
2990 if (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_IGMP
) {
2991 strcpy(proto
, "IGMP");
2994 if (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_SOURCE
) {
2995 strcpy(proto
, "SRC");
2998 if (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_STAR
) {
2999 strcpy(proto
, "STAR");
3002 vty_out(vty
, "%-15s %-15s %-6s %-10s %-10s %-3d %8s%s",
3016 in_ifname
[0] = '\0';
3022 if (!uj
&& !found_oif
) {
3023 vty_out(vty
, "%-15s %-15s %-6s %-10s %-10s %-3d %8s%s",
3035 /* Print list of static routes */
3036 for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list
, node
, s_route
)) {
3039 if (!s_route
->c_oil
.installed
)
3042 pim_inet4_dump("<group?>", s_route
->group
, grp_str
, sizeof(grp_str
));
3043 pim_inet4_dump("<source?>", s_route
->source
, src_str
, sizeof(src_str
));
3044 ifp_in
= pim_if_find_by_vif_index(s_route
->iif
);
3048 strcpy(in_ifname
, ifp_in
->name
);
3050 strcpy(in_ifname
, "<iif?>");
3054 /* Find the group, create it if it doesn't exist */
3055 json_object_object_get_ex(json
, grp_str
, &json_group
);
3058 json_group
= json_object_new_object();
3059 json_object_object_add(json
, grp_str
, json_group
);
3062 /* Find the source nested under the group, create it if it doesn't exist */
3063 json_object_object_get_ex(json_group
, src_str
, &json_source
);
3066 json_source
= json_object_new_object();
3067 json_object_object_add(json_group
, src_str
, json_source
);
3070 json_object_string_add(json_source
, "iif", in_ifname
);
3073 strcpy(proto
, "STATIC");
3076 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
; ++oif_vif_index
) {
3077 struct interface
*ifp_out
;
3078 char oif_uptime
[10];
3081 ttl
= s_route
->oif_ttls
[oif_vif_index
];
3085 ifp_out
= pim_if_find_by_vif_index(oif_vif_index
);
3086 pim_time_uptime(oif_uptime
, sizeof(oif_uptime
), now
- s_route
->c_oil
.oif_creation
[oif_vif_index
]);
3090 strcpy(out_ifname
, ifp_out
->name
);
3092 strcpy(out_ifname
, "<oif?>");
3095 json_ifp_out
= json_object_new_object();
3096 json_object_string_add(json_ifp_out
, "source", src_str
);
3097 json_object_string_add(json_ifp_out
, "group", grp_str
);
3098 json_object_boolean_true_add(json_ifp_out
, "protocolStatic");
3099 json_object_string_add(json_ifp_out
, "inboundInterface", in_ifname
);
3100 json_object_int_add(json_ifp_out
, "iVifI", c_oil
->oil
.mfcc_parent
);
3101 json_object_string_add(json_ifp_out
, "outboundInterface", out_ifname
);
3102 json_object_int_add(json_ifp_out
, "oVifI", oif_vif_index
);
3103 json_object_int_add(json_ifp_out
, "ttl", ttl
);
3104 json_object_string_add(json_ifp_out
, "upTime", oif_uptime
);
3106 json_oil
= json_object_new_object();
3107 json_object_object_add(json_source
, "oil", json_oil
);
3109 json_object_object_add(json_oil
, out_ifname
, json_ifp_out
);
3111 vty_out(vty
, "%-15s %-15s %-6s %-10s %-10s %-3d %8s%s",
3124 in_ifname
[0] = '\0';
3130 if (!uj
&& !found_oif
) {
3131 vty_out(vty
, "%-15s %-15s %-6s %-10s %-10s %-3d %8s%s",
3144 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
3145 json_object_free(json
);
3149 DEFUN (show_ip_mroute
,
3151 "show ip mroute [json]",
3157 u_char uj
= use_json(argc
, argv
);
3158 show_mroute(vty
, uj
);
3162 static void show_mroute_count(struct vty
*vty
)
3164 struct listnode
*node
;
3165 struct channel_oil
*c_oil
;
3166 struct static_route
*s_route
;
3168 vty_out(vty
, "%s", VTY_NEWLINE
);
3170 vty_out(vty
, "Source Group LastUsed Packets Bytes WrongIf %s",
3173 /* Print PIM and IGMP route counts */
3174 for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list
, node
, c_oil
)) {
3175 char group_str
[INET_ADDRSTRLEN
];
3176 char source_str
[INET_ADDRSTRLEN
];
3178 if (!c_oil
->installed
)
3181 pim_mroute_update_counters (c_oil
);
3183 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, group_str
, sizeof(group_str
));
3184 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, source_str
, sizeof(source_str
));
3186 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld%s",
3189 c_oil
->cc
.lastused
/100,
3196 /* Print static route counts */
3197 for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list
, node
, s_route
)) {
3198 char group_str
[INET_ADDRSTRLEN
];
3199 char source_str
[INET_ADDRSTRLEN
];
3201 if (!s_route
->c_oil
.installed
)
3204 pim_mroute_update_counters (&s_route
->c_oil
);
3206 pim_inet4_dump("<group?>", s_route
->c_oil
.oil
.mfcc_mcastgrp
, group_str
, sizeof(group_str
));
3207 pim_inet4_dump("<source?>", s_route
->c_oil
.oil
.mfcc_origin
, source_str
, sizeof(source_str
));
3209 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld%s",
3212 s_route
->c_oil
.cc
.lastused
,
3213 s_route
->c_oil
.cc
.pktcnt
,
3214 s_route
->c_oil
.cc
.bytecnt
,
3215 s_route
->c_oil
.cc
.wrong_if
,
3220 DEFUN (show_ip_mroute_count
,
3221 show_ip_mroute_count_cmd
,
3222 "show ip mroute count",
3226 "Route and packet count data\n")
3228 show_mroute_count(vty
);
3234 "show ip rib A.B.C.D",
3238 "Unicast address\n")
3241 struct in_addr addr
;
3242 const char *addr_str
;
3243 struct pim_nexthop nexthop
;
3244 char nexthop_addr_str
[PREFIX_STRLEN
];
3247 memset (&nexthop
, 0, sizeof (nexthop
));
3248 addr_str
= argv
[idx_ipv4
]->arg
;
3249 result
= inet_pton(AF_INET
, addr_str
, &addr
);
3251 vty_out(vty
, "Bad unicast address %s: errno=%d: %s%s",
3252 addr_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
3256 if (pim_nexthop_lookup(&nexthop
, addr
, 0)) {
3257 vty_out(vty
, "Failure querying RIB nexthop for unicast address %s%s",
3258 addr_str
, VTY_NEWLINE
);
3262 vty_out(vty
, "Address NextHop Interface Metric Preference%s",
3265 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
3266 nexthop_addr_str
, sizeof(nexthop_addr_str
));
3268 vty_out(vty
, "%-15s %-15s %-9s %6d %10d%s",
3271 nexthop
.interface
? nexthop
.interface
->name
: "<ifname?>",
3272 nexthop
.mrib_route_metric
,
3273 nexthop
.mrib_metric_preference
,
3279 static void show_ssmpingd(struct vty
*vty
)
3281 struct listnode
*node
;
3282 struct ssmpingd_sock
*ss
;
3285 vty_out(vty
, "Source Socket Address Port Uptime Requests%s",
3288 if (!qpim_ssmpingd_list
)
3291 now
= pim_time_monotonic_sec();
3293 for (ALL_LIST_ELEMENTS_RO(qpim_ssmpingd_list
, node
, ss
)) {
3294 char source_str
[INET_ADDRSTRLEN
];
3296 struct sockaddr_in bind_addr
;
3297 socklen_t len
= sizeof(bind_addr
);
3298 char bind_addr_str
[INET_ADDRSTRLEN
];
3300 pim_inet4_dump("<src?>", ss
->source_addr
, source_str
, sizeof(source_str
));
3302 if (pim_socket_getsockname(ss
->sock_fd
, (struct sockaddr
*) &bind_addr
, &len
)) {
3303 vty_out(vty
, "%% Failure reading socket name for ssmpingd source %s on fd=%d%s",
3304 source_str
, ss
->sock_fd
, VTY_NEWLINE
);
3307 pim_inet4_dump("<addr?>", bind_addr
.sin_addr
, bind_addr_str
, sizeof(bind_addr_str
));
3308 pim_time_uptime(ss_uptime
, sizeof(ss_uptime
), now
- ss
->creation
);
3310 vty_out(vty
, "%-15s %6d %-15s %5d %8s %8lld%s",
3314 ntohs(bind_addr
.sin_port
),
3316 (long long)ss
->requests
,
3321 DEFUN (show_ip_ssmpingd
,
3322 show_ip_ssmpingd_cmd
,
3333 pim_rp_cmd_worker (struct vty
*vty
, const char *rp
, const char *group
, const char *plist
)
3337 result
= pim_rp_new (rp
, group
, plist
);
3339 if (result
== PIM_MALLOC_FAIL
)
3341 vty_out (vty
, "%% Out of memory%s", VTY_NEWLINE
);
3345 if (result
== PIM_GROUP_BAD_ADDRESS
)
3347 vty_out (vty
, "%% Bad group address specified: %s%s", group
, VTY_NEWLINE
);
3351 if (result
== PIM_RP_BAD_ADDRESS
)
3353 vty_out (vty
, "%% Bad RP address specified: %s%s", rp
, VTY_NEWLINE
);
3357 if (result
== PIM_RP_NO_PATH
)
3359 vty_out (vty
, "%% No Path to RP address specified: %s%s", rp
, VTY_NEWLINE
);
3363 if (result
== PIM_GROUP_OVERLAP
)
3365 vty_out (vty
, "%% Group range specified cannot overlap%s", VTY_NEWLINE
);
3369 if (result
== PIM_GROUP_PFXLIST_OVERLAP
)
3371 vty_out (vty
, "%% This group is already covered by a RP prefix-list%s", VTY_NEWLINE
);
3375 if (result
== PIM_RP_PFXLIST_IN_USE
)
3377 vty_out (vty
, "%% The same prefix-list cannot be applied to multiple RPs%s", VTY_NEWLINE
);
3384 DEFUN (ip_pim_joinprune_time
,
3385 ip_pim_joinprune_time_cmd
,
3386 "ip pim join-prune-interval <60-600>",
3388 "pim multicast routing\n"
3389 "Join Prune Send Interval\n"
3392 qpim_t_periodic
= atoi(argv
[3]->arg
);
3396 DEFUN (no_ip_pim_joinprune_time
,
3397 no_ip_pim_joinprune_time_cmd
,
3398 "no ip pim join-prune-interval <60-600>",
3401 "pim multicast routing\n"
3402 "Join Prune Send Interval\n"
3405 qpim_t_periodic
= PIM_DEFAULT_T_PERIODIC
;
3409 DEFUN (ip_pim_register_suppress
,
3410 ip_pim_register_suppress_cmd
,
3411 "ip pim register-suppress-time <5-60000>",
3413 "pim multicast routing\n"
3414 "Register Suppress Timer\n"
3417 qpim_keep_alive_time
= atoi (argv
[3]->arg
);
3421 DEFUN (no_ip_pim_register_suppress
,
3422 no_ip_pim_register_suppress_cmd
,
3423 "no ip pim register-suppress-time <5-60000>",
3426 "pim multicast routing\n"
3427 "Register Suppress Timer\n"
3430 qpim_register_suppress_time
= PIM_REGISTER_SUPPRESSION_TIME_DEFAULT
;
3434 DEFUN (ip_pim_keep_alive
,
3435 ip_pim_keep_alive_cmd
,
3436 "ip pim keep-alive-timer <31-60000>",
3438 "pim multicast routing\n"
3439 "Keep alive Timer\n"
3442 qpim_rp_keep_alive_time
= atoi (argv
[4]->arg
);
3446 DEFUN (no_ip_pim_keep_alive
,
3447 no_ip_pim_keep_alive_cmd
,
3448 "no ip pim keep-alive-timer <31-60000>",
3451 "pim multicast routing\n"
3452 "Keep alive Timer\n"
3455 qpim_keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
3459 DEFUN (ip_pim_packets
,
3461 "ip pim packets <1-100>",
3463 "pim multicast routing\n"
3464 "packets to process at one time per fd\n"
3465 "Number of packets\n")
3467 qpim_packet_process
= atoi (argv
[3]->arg
);
3471 DEFUN (no_ip_pim_packets
,
3472 no_ip_pim_packets_cmd
,
3473 "no ip pim packets <1-100>",
3476 "pim multicast routing\n"
3477 "packets to process at one time per fd\n"
3478 "Number of packets\n")
3480 qpim_packet_process
= PIM_DEFAULT_PACKET_PROCESS
;
3486 "ip pim rp A.B.C.D [A.B.C.D/M]",
3488 "pim multicast routing\n"
3490 "ip address of RP\n"
3491 "Group Address range to cover\n")
3495 if (argc
== (idx_ipv4
+ 1))
3496 return pim_rp_cmd_worker (vty
, argv
[idx_ipv4
]->arg
, argv
[idx_ipv4
+ 1]->arg
, NULL
);
3498 return pim_rp_cmd_worker (vty
, argv
[idx_ipv4
]->arg
, NULL
, NULL
);
3501 DEFUN (ip_pim_rp_prefix_list
,
3502 ip_pim_rp_prefix_list_cmd
,
3503 "ip pim rp A.B.C.D prefix-list WORD",
3505 "pim multicast routing\n"
3507 "ip address of RP\n"
3508 "group prefix-list filter\n"
3509 "Name of a prefix-list\n")
3511 return pim_rp_cmd_worker (vty
, argv
[3]->arg
, NULL
, argv
[5]->arg
);
3515 pim_no_rp_cmd_worker (struct vty
*vty
, const char *rp
, const char *group
,
3518 int result
= pim_rp_del (rp
, group
, plist
);
3520 if (result
== PIM_GROUP_BAD_ADDRESS
)
3522 vty_out (vty
, "%% Bad group address specified: %s%s", group
, VTY_NEWLINE
);
3526 if (result
== PIM_RP_BAD_ADDRESS
)
3528 vty_out (vty
, "%% Bad RP address specified: %s%s", rp
, VTY_NEWLINE
);
3532 if (result
== PIM_RP_NOT_FOUND
)
3534 vty_out (vty
, "%% Unable to find specified RP%s", VTY_NEWLINE
);
3541 DEFUN (no_ip_pim_rp
,
3543 "no ip pim rp A.B.C.D [A.B.C.D/M]",
3546 "pim multicast routing\n"
3548 "ip address of RP\n"
3549 "Group Address range to cover\n")
3553 if (argc
== (idx_ipv4
+ 1))
3554 return pim_no_rp_cmd_worker (vty
, argv
[idx_ipv4
]->arg
, argv
[idx_ipv4
+ 1]->arg
, NULL
);
3556 return pim_no_rp_cmd_worker (vty
, argv
[idx_ipv4
]->arg
, NULL
, NULL
);
3559 DEFUN (no_ip_pim_rp_prefix_list
,
3560 no_ip_pim_rp_prefix_list_cmd
,
3561 "no ip pim rp A.B.C.D prefix-list WORD",
3564 "pim multicast routing\n"
3566 "ip address of RP\n"
3567 "group prefix-list filter\n"
3568 "Name of a prefix-list\n")
3570 return pim_no_rp_cmd_worker (vty
, argv
[4]->arg
, NULL
, argv
[6]->arg
);
3573 DEFUN (ip_multicast_routing
,
3574 ip_multicast_routing_cmd
,
3575 "ip multicast-routing",
3577 "Enable IP multicast forwarding\n")
3579 pim_mroute_socket_enable();
3580 pim_if_add_vif_all();
3582 static_mroute_add_all();
3586 DEFUN (no_ip_multicast_routing
,
3587 no_ip_multicast_routing_cmd
,
3588 "no ip multicast-routing",
3591 "Global IP configuration subcommands\n"
3592 "Enable IP multicast forwarding\n")
3595 static_mroute_del_all();
3596 pim_if_del_vif_all();
3597 pim_mroute_socket_disable();
3603 "ip ssmpingd [A.B.C.D]",
3610 struct in_addr source_addr
;
3611 const char *source_str
= (argc
== idx_ipv4
) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
3613 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
3615 vty_out(vty
, "%% Bad source address %s: errno=%d: %s%s",
3616 source_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
3620 result
= pim_ssmpingd_start(source_addr
);
3622 vty_out(vty
, "%% Failure starting ssmpingd for source %s: %d%s",
3623 source_str
, result
, VTY_NEWLINE
);
3630 DEFUN (no_ip_ssmpingd
,
3632 "no ip ssmpingd [A.B.C.D]",
3640 struct in_addr source_addr
;
3641 const char *source_str
= (argc
== idx_ipv4
) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
3643 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
3645 vty_out(vty
, "%% Bad source address %s: errno=%d: %s%s",
3646 source_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
3650 result
= pim_ssmpingd_stop(source_addr
);
3652 vty_out(vty
, "%% Failure stopping ssmpingd for source %s: %d%s",
3653 source_str
, result
, VTY_NEWLINE
);
3660 DEFUN (interface_ip_igmp
,
3661 interface_ip_igmp_cmd
,
3666 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3667 struct pim_interface
*pim_ifp
;
3669 pim_ifp
= ifp
->info
;
3672 pim_ifp
= pim_if_new(ifp
, 1 /* igmp=true */, 0 /* pim=false */);
3674 vty_out(vty
, "Could not enable IGMP on interface %s%s",
3675 ifp
->name
, VTY_NEWLINE
);
3680 PIM_IF_DO_IGMP(pim_ifp
->options
);
3683 pim_if_addr_add_all(ifp
);
3684 pim_if_membership_refresh(ifp
);
3689 DEFUN (interface_no_ip_igmp
,
3690 interface_no_ip_igmp_cmd
,
3696 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3697 struct pim_interface
*pim_ifp
;
3699 pim_ifp
= ifp
->info
;
3703 PIM_IF_DONT_IGMP(pim_ifp
->options
);
3705 pim_if_membership_clear(ifp
);
3707 pim_if_addr_del_all_igmp(ifp
);
3709 if (!PIM_IF_TEST_PIM(pim_ifp
->options
)) {
3716 DEFUN (interface_ip_igmp_join
,
3717 interface_ip_igmp_join_cmd
,
3718 "ip igmp join A.B.C.D A.B.C.D",
3721 "IGMP join multicast group\n"
3722 "Multicast group address\n"
3725 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3728 const char *group_str
;
3729 const char *source_str
;
3730 struct in_addr group_addr
;
3731 struct in_addr source_addr
;
3735 group_str
= argv
[idx_ipv4
]->arg
;
3736 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
3738 vty_out(vty
, "Bad group address %s: errno=%d: %s%s",
3739 group_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
3743 /* Source address */
3744 source_str
= argv
[idx_ipv4_2
]->arg
;
3745 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
3747 vty_out(vty
, "Bad source address %s: errno=%d: %s%s",
3748 source_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
3752 result
= pim_if_igmp_join_add(ifp
, group_addr
, source_addr
);
3754 vty_out(vty
, "%% Failure joining IGMP group %s source %s on interface %s: %d%s",
3755 group_str
, source_str
, ifp
->name
, result
, VTY_NEWLINE
);
3762 DEFUN (interface_no_ip_igmp_join
,
3763 interface_no_ip_igmp_join_cmd
,
3764 "no ip igmp join A.B.C.D A.B.C.D",
3768 "IGMP join multicast group\n"
3769 "Multicast group address\n"
3772 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3775 const char *group_str
;
3776 const char *source_str
;
3777 struct in_addr group_addr
;
3778 struct in_addr source_addr
;
3782 group_str
= argv
[idx_ipv4
]->arg
;
3783 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
3785 vty_out(vty
, "Bad group address %s: errno=%d: %s%s",
3786 group_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
3790 /* Source address */
3791 source_str
= argv
[idx_ipv4_2
]->arg
;
3792 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
3794 vty_out(vty
, "Bad source address %s: errno=%d: %s%s",
3795 source_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
3799 result
= pim_if_igmp_join_del(ifp
, group_addr
, source_addr
);
3801 vty_out(vty
, "%% Failure leaving IGMP group %s source %s on interface %s: %d%s",
3802 group_str
, source_str
, ifp
->name
, result
, VTY_NEWLINE
);
3810 CLI reconfiguration affects the interface level (struct pim_interface).
3811 This function propagates the reconfiguration to every active socket
3814 static void igmp_sock_query_interval_reconfig(struct igmp_sock
*igmp
)
3816 struct interface
*ifp
;
3817 struct pim_interface
*pim_ifp
;
3821 /* other querier present? */
3823 if (igmp
->t_other_querier_timer
)
3826 /* this is the querier */
3828 zassert(igmp
->interface
);
3829 zassert(igmp
->interface
->info
);
3831 ifp
= igmp
->interface
;
3832 pim_ifp
= ifp
->info
;
3834 if (PIM_DEBUG_IGMP_TRACE
) {
3835 char ifaddr_str
[INET_ADDRSTRLEN
];
3836 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
, sizeof(ifaddr_str
));
3837 zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
3838 __PRETTY_FUNCTION__
,
3841 pim_ifp
->igmp_default_query_interval
);
3845 igmp_startup_mode_on() will reset QQI:
3847 igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
3849 igmp_startup_mode_on(igmp
);
3852 static void igmp_sock_query_reschedule(struct igmp_sock
*igmp
)
3854 if (igmp
->t_igmp_query_timer
) {
3855 /* other querier present */
3856 zassert(igmp
->t_igmp_query_timer
);
3857 zassert(!igmp
->t_other_querier_timer
);
3859 pim_igmp_general_query_off(igmp
);
3860 pim_igmp_general_query_on(igmp
);
3862 zassert(igmp
->t_igmp_query_timer
);
3863 zassert(!igmp
->t_other_querier_timer
);
3866 /* this is the querier */
3868 zassert(!igmp
->t_igmp_query_timer
);
3869 zassert(igmp
->t_other_querier_timer
);
3871 pim_igmp_other_querier_timer_off(igmp
);
3872 pim_igmp_other_querier_timer_on(igmp
);
3874 zassert(!igmp
->t_igmp_query_timer
);
3875 zassert(igmp
->t_other_querier_timer
);
3879 static void change_query_interval(struct pim_interface
*pim_ifp
,
3882 struct listnode
*sock_node
;
3883 struct igmp_sock
*igmp
;
3885 pim_ifp
->igmp_default_query_interval
= query_interval
;
3887 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
3888 igmp_sock_query_interval_reconfig(igmp
);
3889 igmp_sock_query_reschedule(igmp
);
3893 static void change_query_max_response_time(struct pim_interface
*pim_ifp
,
3894 int query_max_response_time_dsec
)
3896 struct listnode
*sock_node
;
3897 struct igmp_sock
*igmp
;
3899 pim_ifp
->igmp_query_max_response_time_dsec
= query_max_response_time_dsec
;
3902 Below we modify socket/group/source timers in order to quickly
3903 reflect the change. Otherwise, those timers would eventually catch
3907 /* scan all sockets */
3908 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
3909 struct listnode
*grp_node
;
3910 struct igmp_group
*grp
;
3912 /* reschedule socket general query */
3913 igmp_sock_query_reschedule(igmp
);
3915 /* scan socket groups */
3916 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grp_node
, grp
)) {
3917 struct listnode
*src_node
;
3918 struct igmp_source
*src
;
3920 /* reset group timers for groups in EXCLUDE mode */
3921 if (grp
->group_filtermode_isexcl
) {
3922 igmp_group_reset_gmi(grp
);
3925 /* scan group sources */
3926 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
, src_node
, src
)) {
3928 /* reset source timers for sources with running timers */
3929 if (src
->t_source_timer
) {
3930 igmp_source_reset_gmi(igmp
, grp
, src
);
3937 #define IGMP_QUERY_INTERVAL_MIN (1)
3938 #define IGMP_QUERY_INTERVAL_MAX (1800)
3940 DEFUN (interface_ip_igmp_query_interval
,
3941 interface_ip_igmp_query_interval_cmd
,
3942 "ip igmp query-interval (1-1800)",
3945 IFACE_IGMP_QUERY_INTERVAL_STR
3946 "Query interval in seconds\n")
3948 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3949 struct pim_interface
*pim_ifp
;
3951 int query_interval_dsec
;
3953 pim_ifp
= ifp
->info
;
3957 "IGMP not enabled on interface %s. Please enable IGMP first.%s",
3963 query_interval
= atoi(argv
[3]->arg
);
3964 query_interval_dsec
= 10 * query_interval
;
3967 It seems we don't need to check bounds since command.c does it
3968 already, but we verify them anyway for extra safety.
3970 if (query_interval
< IGMP_QUERY_INTERVAL_MIN
) {
3971 vty_out(vty
, "General query interval %d lower than minimum %d%s",
3973 IGMP_QUERY_INTERVAL_MIN
,
3977 if (query_interval
> IGMP_QUERY_INTERVAL_MAX
) {
3978 vty_out(vty
, "General query interval %d higher than maximum %d%s",
3980 IGMP_QUERY_INTERVAL_MAX
,
3985 if (query_interval_dsec
<= pim_ifp
->igmp_query_max_response_time_dsec
) {
3987 "Can't set general query interval %d dsec <= query max response time %d dsec.%s",
3988 query_interval_dsec
, pim_ifp
->igmp_query_max_response_time_dsec
,
3993 change_query_interval(pim_ifp
, query_interval
);
3998 DEFUN (interface_no_ip_igmp_query_interval
,
3999 interface_no_ip_igmp_query_interval_cmd
,
4000 "no ip igmp query-interval",
4004 IFACE_IGMP_QUERY_INTERVAL_STR
)
4006 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4007 struct pim_interface
*pim_ifp
;
4008 int default_query_interval_dsec
;
4010 pim_ifp
= ifp
->info
;
4015 default_query_interval_dsec
= IGMP_GENERAL_QUERY_INTERVAL
* 10;
4017 if (default_query_interval_dsec
<= pim_ifp
->igmp_query_max_response_time_dsec
) {
4019 "Can't set default general query interval %d dsec <= query max response time %d dsec.%s",
4020 default_query_interval_dsec
, pim_ifp
->igmp_query_max_response_time_dsec
,
4025 change_query_interval(pim_ifp
, IGMP_GENERAL_QUERY_INTERVAL
);
4030 DEFUN (interface_ip_igmp_version
,
4031 interface_ip_igmp_version_cmd
,
4032 "ip igmp version (2-3)",
4036 "IGMP version number\n")
4038 VTY_DECLVAR_CONTEXT(interface
,ifp
);
4039 struct pim_interface
*pim_ifp
;
4042 pim_ifp
= ifp
->info
;
4046 "IGMP not enabled on interface %s. Please enable IGMP first.%s",
4052 igmp_version
= atoi(argv
[3]->arg
);
4053 pim_ifp
->igmp_version
= igmp_version
;
4058 DEFUN (interface_no_ip_igmp_version
,
4059 interface_no_ip_igmp_version_cmd
,
4060 "no ip igmp version (2-3)",
4065 "IGMP version number\n")
4067 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4068 struct pim_interface
*pim_ifp
;
4070 pim_ifp
= ifp
->info
;
4075 pim_ifp
->igmp_version
= IGMP_DEFAULT_VERSION
;
4080 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
4081 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
4083 DEFUN (interface_ip_igmp_query_max_response_time
,
4084 interface_ip_igmp_query_max_response_time_cmd
,
4085 "ip igmp query-max-response-time (10-250)",
4088 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
4089 "Query response value in deci-seconds\n")
4091 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4092 struct pim_interface
*pim_ifp
;
4093 int query_max_response_time
;
4095 pim_ifp
= ifp
->info
;
4099 "IGMP not enabled on interface %s. Please enable IGMP first.%s",
4105 query_max_response_time
= atoi(argv
[3]->arg
);
4107 if (query_max_response_time
>= pim_ifp
->igmp_default_query_interval
* 10) {
4109 "Can't set query max response time %d sec >= general query interval %d sec%s",
4110 query_max_response_time
, pim_ifp
->igmp_default_query_interval
,
4115 change_query_max_response_time(pim_ifp
, query_max_response_time
);
4120 DEFUN (interface_no_ip_igmp_query_max_response_time
,
4121 interface_no_ip_igmp_query_max_response_time_cmd
,
4122 "no ip igmp query-max-response-time (10-250)",
4126 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
4127 "Time for response in deci-seconds\n")
4129 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4130 struct pim_interface
*pim_ifp
;
4132 pim_ifp
= ifp
->info
;
4137 change_query_max_response_time(pim_ifp
, IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
4142 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
4143 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
4145 DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec
,
4146 interface_ip_igmp_query_max_response_time_dsec_cmd
,
4147 "ip igmp query-max-response-time-dsec (10-250)",
4150 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
4151 "Query response value in deciseconds\n")
4153 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4154 struct pim_interface
*pim_ifp
;
4155 int query_max_response_time_dsec
;
4156 int default_query_interval_dsec
;
4158 pim_ifp
= ifp
->info
;
4162 "IGMP not enabled on interface %s. Please enable IGMP first.%s",
4168 query_max_response_time_dsec
= atoi(argv
[4]->arg
);
4170 default_query_interval_dsec
= 10 * pim_ifp
->igmp_default_query_interval
;
4172 if (query_max_response_time_dsec
>= default_query_interval_dsec
) {
4174 "Can't set query max response time %d dsec >= general query interval %d dsec%s",
4175 query_max_response_time_dsec
, default_query_interval_dsec
,
4180 change_query_max_response_time(pim_ifp
, query_max_response_time_dsec
);
4185 DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec
,
4186 interface_no_ip_igmp_query_max_response_time_dsec_cmd
,
4187 "no ip igmp query-max-response-time-dsec",
4191 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
)
4193 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4194 struct pim_interface
*pim_ifp
;
4196 pim_ifp
= ifp
->info
;
4201 change_query_max_response_time(pim_ifp
, IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
4206 DEFUN (interface_ip_pim_drprio
,
4207 interface_ip_pim_drprio_cmd
,
4208 "ip pim drpriority (1-4294967295)",
4211 "Set the Designated Router Election Priority\n"
4212 "Value of the new DR Priority\n")
4214 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4216 struct pim_interface
*pim_ifp
;
4217 uint32_t old_dr_prio
;
4219 pim_ifp
= ifp
->info
;
4222 vty_out(vty
, "Please enable PIM on interface, first%s", VTY_NEWLINE
);
4226 old_dr_prio
= pim_ifp
->pim_dr_priority
;
4228 pim_ifp
->pim_dr_priority
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
4230 if (old_dr_prio
!= pim_ifp
->pim_dr_priority
) {
4231 if (pim_if_dr_election(ifp
))
4232 pim_hello_restart_now(ifp
);
4238 DEFUN (interface_no_ip_pim_drprio
,
4239 interface_no_ip_pim_drprio_cmd
,
4240 "no ip pim drpriority [(1-4294967295)]",
4244 "Revert the Designated Router Priority to default\n"
4245 "Old Value of the Priority\n")
4247 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4248 struct pim_interface
*pim_ifp
;
4250 pim_ifp
= ifp
->info
;
4253 vty_out(vty
, "Pim not enabled on this interface%s", VTY_NEWLINE
);
4257 if (pim_ifp
->pim_dr_priority
!= PIM_DEFAULT_DR_PRIORITY
) {
4258 pim_ifp
->pim_dr_priority
= PIM_DEFAULT_DR_PRIORITY
;
4259 if (pim_if_dr_election(ifp
))
4260 pim_hello_restart_now(ifp
);
4267 pim_cmd_interface_add (struct interface
*ifp
, enum pim_interface_type itype
)
4269 struct pim_interface
*pim_ifp
= ifp
->info
;
4272 pim_ifp
= pim_if_new(ifp
, 0 /* igmp=false */, 1 /* pim=true */);
4278 PIM_IF_DO_PIM(pim_ifp
->options
);
4281 pim_ifp
->itype
= itype
;
4282 pim_if_addr_add_all(ifp
);
4283 pim_if_membership_refresh(ifp
);
4288 DEFUN (interface_ip_pim_ssm
,
4289 interface_ip_pim_ssm_cmd
,
4295 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4297 if (!pim_cmd_interface_add(ifp
, PIM_INTERFACE_SSM
)) {
4298 vty_out(vty
, "Could not enable PIM SSM on interface%s", VTY_NEWLINE
);
4305 DEFUN (interface_ip_pim_sm
,
4306 interface_ip_pim_sm_cmd
,
4312 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4313 if (!pim_cmd_interface_add(ifp
, PIM_INTERFACE_SM
)) {
4314 vty_out(vty
, "Could not enable PIM SM on interface%s", VTY_NEWLINE
);
4318 pim_if_create_pimreg();
4324 pim_cmd_interface_delete (struct interface
*ifp
)
4326 struct pim_interface
*pim_ifp
= ifp
->info
;
4331 PIM_IF_DONT_PIM(pim_ifp
->options
);
4333 pim_if_membership_clear(ifp
);
4336 pim_sock_delete() removes all neighbors from
4337 pim_ifp->pim_neighbor_list.
4339 pim_sock_delete(ifp
, "pim unconfigured on interface");
4341 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
4342 pim_if_addr_del_all(ifp
);
4349 DEFUN (interface_no_ip_pim_ssm
,
4350 interface_no_ip_pim_ssm_cmd
,
4357 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4358 if (!pim_cmd_interface_delete(ifp
)) {
4359 vty_out(vty
, "Unable to delete interface information%s", VTY_NEWLINE
);
4366 DEFUN (interface_no_ip_pim_sm
,
4367 interface_no_ip_pim_sm_cmd
,
4374 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4375 if (!pim_cmd_interface_delete(ifp
)) {
4376 vty_out(vty
, "Unable to delete interface information%s", VTY_NEWLINE
);
4383 DEFUN (interface_ip_mroute
,
4384 interface_ip_mroute_cmd
,
4385 "ip mroute INTERFACE A.B.C.D",
4387 "Add multicast route\n"
4388 "Outgoing interface name\n"
4391 VTY_DECLVAR_CONTEXT(interface
, iif
);
4392 int idx_interface
= 2;
4394 struct interface
*oif
;
4395 const char *oifname
;
4396 const char *grp_str
;
4397 struct in_addr grp_addr
;
4398 struct in_addr src_addr
;
4401 oifname
= argv
[idx_interface
]->arg
;
4402 oif
= if_lookup_by_name(oifname
);
4404 vty_out(vty
, "No such interface name %s%s",
4405 oifname
, VTY_NEWLINE
);
4409 grp_str
= argv
[idx_ipv4
]->arg
;
4410 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
4412 vty_out(vty
, "Bad group address %s: errno=%d: %s%s",
4413 grp_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
4417 src_addr
.s_addr
= INADDR_ANY
;
4419 if (pim_static_add(iif
, oif
, grp_addr
, src_addr
)) {
4420 vty_out(vty
, "Failed to add route%s", VTY_NEWLINE
);
4427 DEFUN (interface_ip_mroute_source
,
4428 interface_ip_mroute_source_cmd
,
4429 "ip mroute INTERFACE A.B.C.D A.B.C.D",
4431 "Add multicast route\n"
4432 "Outgoing interface name\n"
4436 VTY_DECLVAR_CONTEXT(interface
, iif
);
4437 int idx_interface
= 2;
4440 struct interface
*oif
;
4441 const char *oifname
;
4442 const char *grp_str
;
4443 struct in_addr grp_addr
;
4444 const char *src_str
;
4445 struct in_addr src_addr
;
4448 oifname
= argv
[idx_interface
]->arg
;
4449 oif
= if_lookup_by_name(oifname
);
4451 vty_out(vty
, "No such interface name %s%s",
4452 oifname
, VTY_NEWLINE
);
4456 grp_str
= argv
[idx_ipv4
]->arg
;
4457 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
4459 vty_out(vty
, "Bad group address %s: errno=%d: %s%s",
4460 grp_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
4464 src_str
= argv
[idx_ipv4_2
]->arg
;
4465 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
4467 vty_out(vty
, "Bad source address %s: errno=%d: %s%s",
4468 src_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
4472 if (pim_static_add(iif
, oif
, grp_addr
, src_addr
)) {
4473 vty_out(vty
, "Failed to add route%s", VTY_NEWLINE
);
4480 DEFUN (interface_no_ip_mroute
,
4481 interface_no_ip_mroute_cmd
,
4482 "no ip mroute INTERFACE A.B.C.D",
4485 "Add multicast route\n"
4486 "Outgoing interface name\n"
4489 VTY_DECLVAR_CONTEXT(interface
, iif
);
4490 int idx_interface
= 3;
4492 struct interface
*oif
;
4493 const char *oifname
;
4494 const char *grp_str
;
4495 struct in_addr grp_addr
;
4496 struct in_addr src_addr
;
4499 oifname
= argv
[idx_interface
]->arg
;
4500 oif
= if_lookup_by_name(oifname
);
4502 vty_out(vty
, "No such interface name %s%s",
4503 oifname
, VTY_NEWLINE
);
4507 grp_str
= argv
[idx_ipv4
]->arg
;
4508 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
4510 vty_out(vty
, "Bad group address %s: errno=%d: %s%s",
4511 grp_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
4515 src_addr
.s_addr
= INADDR_ANY
;
4517 if (pim_static_del(iif
, oif
, grp_addr
, src_addr
)) {
4518 vty_out(vty
, "Failed to remove route%s", VTY_NEWLINE
);
4525 DEFUN (interface_no_ip_mroute_source
,
4526 interface_no_ip_mroute_source_cmd
,
4527 "no ip mroute INTERFACE A.B.C.D A.B.C.D",
4530 "Add multicast route\n"
4531 "Outgoing interface name\n"
4535 VTY_DECLVAR_CONTEXT(interface
, iif
);
4536 int idx_interface
= 3;
4539 struct interface
*oif
;
4540 const char *oifname
;
4541 const char *grp_str
;
4542 struct in_addr grp_addr
;
4543 const char *src_str
;
4544 struct in_addr src_addr
;
4547 oifname
= argv
[idx_interface
]->arg
;
4548 oif
= if_lookup_by_name(oifname
);
4550 vty_out(vty
, "No such interface name %s%s",
4551 oifname
, VTY_NEWLINE
);
4555 grp_str
= argv
[idx_ipv4
]->arg
;
4556 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
4558 vty_out(vty
, "Bad group address %s: errno=%d: %s%s",
4559 grp_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
4563 src_str
= argv
[idx_ipv4_2
]->arg
;
4564 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
4566 vty_out(vty
, "Bad source address %s: errno=%d: %s%s",
4567 src_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
4571 if (pim_static_del(iif
, oif
, grp_addr
, src_addr
)) {
4572 vty_out(vty
, "Failed to remove route%s", VTY_NEWLINE
);
4579 DEFUN (interface_ip_pim_hello
,
4580 interface_ip_pim_hello_cmd
,
4581 "ip pim hello (1-180) [(1-180)]",
4585 IFACE_PIM_HELLO_TIME_STR
4586 IFACE_PIM_HELLO_HOLD_STR
)
4588 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4591 struct pim_interface
*pim_ifp
;
4593 pim_ifp
= ifp
->info
;
4596 vty_out(vty
, "Pim not enabled on this interface%s", VTY_NEWLINE
);
4600 pim_ifp
->pim_hello_period
= strtol(argv
[idx_time
]->arg
, NULL
, 10);
4602 if (argc
== idx_hold
)
4603 pim_ifp
->pim_default_holdtime
= strtol(argv
[idx_hold
]->arg
, NULL
, 10);
4610 DEFUN (interface_no_ip_pim_hello
,
4611 interface_no_ip_pim_hello_cmd
,
4612 "no ip pim hello [(1-180) (1-180)]",
4617 IFACE_PIM_HELLO_TIME_STR
4618 IFACE_PIM_HELLO_HOLD_STR
)
4620 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4621 struct pim_interface
*pim_ifp
;
4623 pim_ifp
= ifp
->info
;
4626 vty_out(vty
, "Pim not enabled on this interface%s", VTY_NEWLINE
);
4630 pim_ifp
->pim_hello_period
= PIM_DEFAULT_HELLO_PERIOD
;
4631 pim_ifp
->pim_default_holdtime
= -1;
4642 PIM_DO_DEBUG_IGMP_EVENTS
;
4643 PIM_DO_DEBUG_IGMP_PACKETS
;
4644 PIM_DO_DEBUG_IGMP_TRACE
;
4648 DEFUN (no_debug_igmp
,
4655 PIM_DONT_DEBUG_IGMP_EVENTS
;
4656 PIM_DONT_DEBUG_IGMP_PACKETS
;
4657 PIM_DONT_DEBUG_IGMP_TRACE
;
4662 DEFUN (debug_igmp_events
,
4663 debug_igmp_events_cmd
,
4664 "debug igmp events",
4667 DEBUG_IGMP_EVENTS_STR
)
4669 PIM_DO_DEBUG_IGMP_EVENTS
;
4673 DEFUN (no_debug_igmp_events
,
4674 no_debug_igmp_events_cmd
,
4675 "no debug igmp events",
4679 DEBUG_IGMP_EVENTS_STR
)
4681 PIM_DONT_DEBUG_IGMP_EVENTS
;
4686 DEFUN (debug_igmp_packets
,
4687 debug_igmp_packets_cmd
,
4688 "debug igmp packets",
4691 DEBUG_IGMP_PACKETS_STR
)
4693 PIM_DO_DEBUG_IGMP_PACKETS
;
4697 DEFUN (no_debug_igmp_packets
,
4698 no_debug_igmp_packets_cmd
,
4699 "no debug igmp packets",
4703 DEBUG_IGMP_PACKETS_STR
)
4705 PIM_DONT_DEBUG_IGMP_PACKETS
;
4710 DEFUN (debug_igmp_trace
,
4711 debug_igmp_trace_cmd
,
4715 DEBUG_IGMP_TRACE_STR
)
4717 PIM_DO_DEBUG_IGMP_TRACE
;
4721 DEFUN (no_debug_igmp_trace
,
4722 no_debug_igmp_trace_cmd
,
4723 "no debug igmp trace",
4727 DEBUG_IGMP_TRACE_STR
)
4729 PIM_DONT_DEBUG_IGMP_TRACE
;
4734 DEFUN (debug_mroute
,
4740 PIM_DO_DEBUG_MROUTE
;
4744 DEFUN (debug_mroute_detail
,
4745 debug_mroute_detail_cmd
,
4746 "debug mroute detail",
4751 PIM_DO_DEBUG_MROUTE_DETAIL
;
4755 DEFUN (no_debug_mroute
,
4756 no_debug_mroute_cmd
,
4762 PIM_DONT_DEBUG_MROUTE
;
4766 DEFUN (no_debug_mroute_detail
,
4767 no_debug_mroute_detail_cmd
,
4768 "no debug mroute detail",
4774 PIM_DONT_DEBUG_MROUTE_DETAIL
;
4778 DEFUN (debug_static
,
4784 PIM_DO_DEBUG_STATIC
;
4788 DEFUN (no_debug_static
,
4789 no_debug_static_cmd
,
4795 PIM_DONT_DEBUG_STATIC
;
4806 PIM_DO_DEBUG_PIM_EVENTS
;
4807 PIM_DO_DEBUG_PIM_PACKETS
;
4808 PIM_DO_DEBUG_PIM_TRACE
;
4809 PIM_DO_DEBUG_MSDP_EVENTS
;
4810 PIM_DO_DEBUG_MSDP_PACKETS
;
4814 DEFUN (no_debug_pim
,
4821 PIM_DONT_DEBUG_PIM_EVENTS
;
4822 PIM_DONT_DEBUG_PIM_PACKETS
;
4823 PIM_DONT_DEBUG_PIM_TRACE
;
4824 PIM_DONT_DEBUG_MSDP_EVENTS
;
4825 PIM_DONT_DEBUG_MSDP_PACKETS
;
4827 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
4828 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
4834 DEFUN (debug_pim_events
,
4835 debug_pim_events_cmd
,
4839 DEBUG_PIM_EVENTS_STR
)
4841 PIM_DO_DEBUG_PIM_EVENTS
;
4845 DEFUN (no_debug_pim_events
,
4846 no_debug_pim_events_cmd
,
4847 "no debug pim events",
4851 DEBUG_PIM_EVENTS_STR
)
4853 PIM_DONT_DEBUG_PIM_EVENTS
;
4857 DEFUN (debug_pim_packets
,
4858 debug_pim_packets_cmd
,
4859 "debug pim packets [<hello|joins|register>]",
4862 DEBUG_PIM_PACKETS_STR
4863 DEBUG_PIM_HELLO_PACKETS_STR
4864 DEBUG_PIM_J_P_PACKETS_STR
4865 DEBUG_PIM_PIM_REG_PACKETS_STR
)
4868 if (argv_find (argv
, argc
, "hello", &idx
))
4870 PIM_DO_DEBUG_PIM_HELLO
;
4871 vty_out (vty
, "PIM Hello debugging is on%s", VTY_NEWLINE
);
4873 else if (argv_find (argv
, argc
,"joins", &idx
))
4875 PIM_DO_DEBUG_PIM_J_P
;
4876 vty_out (vty
, "PIM Join/Prune debugging is on%s", VTY_NEWLINE
);
4878 else if (argv_find (argv
, argc
, "register", &idx
))
4880 PIM_DO_DEBUG_PIM_REG
;
4881 vty_out (vty
, "PIM Register debugging is on%s", VTY_NEWLINE
);
4885 PIM_DO_DEBUG_PIM_PACKETS
;
4886 vty_out (vty
, "PIM Packet debugging is on %s", VTY_NEWLINE
);
4891 DEFUN (no_debug_pim_packets
,
4892 no_debug_pim_packets_cmd
,
4893 "no debug pim packets [<hello|joins|register>]",
4897 DEBUG_PIM_PACKETS_STR
4898 DEBUG_PIM_HELLO_PACKETS_STR
4899 DEBUG_PIM_J_P_PACKETS_STR
4900 DEBUG_PIM_PIM_REG_PACKETS_STR
)
4903 if (argv_find (argv
, argc
,"hello",&idx
))
4905 PIM_DONT_DEBUG_PIM_HELLO
;
4906 vty_out (vty
, "PIM Hello debugging is off %s", VTY_NEWLINE
);
4908 else if (argv_find (argv
, argc
, "joins", &idx
))
4910 PIM_DONT_DEBUG_PIM_J_P
;
4911 vty_out (vty
, "PIM Join/Prune debugging is off %s", VTY_NEWLINE
);
4913 else if (argv_find (argv
, argc
, "register", &idx
))
4915 PIM_DONT_DEBUG_PIM_REG
;
4916 vty_out (vty
, "PIM Register debugging is off%s", VTY_NEWLINE
);
4919 PIM_DONT_DEBUG_PIM_PACKETS
;
4925 DEFUN (debug_pim_packetdump_send
,
4926 debug_pim_packetdump_send_cmd
,
4927 "debug pim packet-dump send",
4930 DEBUG_PIM_PACKETDUMP_STR
4931 DEBUG_PIM_PACKETDUMP_SEND_STR
)
4933 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND
;
4937 DEFUN (no_debug_pim_packetdump_send
,
4938 no_debug_pim_packetdump_send_cmd
,
4939 "no debug pim packet-dump send",
4943 DEBUG_PIM_PACKETDUMP_STR
4944 DEBUG_PIM_PACKETDUMP_SEND_STR
)
4946 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
4951 DEFUN (debug_pim_packetdump_recv
,
4952 debug_pim_packetdump_recv_cmd
,
4953 "debug pim packet-dump receive",
4956 DEBUG_PIM_PACKETDUMP_STR
4957 DEBUG_PIM_PACKETDUMP_RECV_STR
)
4959 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV
;
4963 DEFUN (no_debug_pim_packetdump_recv
,
4964 no_debug_pim_packetdump_recv_cmd
,
4965 "no debug pim packet-dump receive",
4969 DEBUG_PIM_PACKETDUMP_STR
4970 DEBUG_PIM_PACKETDUMP_RECV_STR
)
4972 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
4977 DEFUN (debug_pim_trace
,
4978 debug_pim_trace_cmd
,
4982 DEBUG_PIM_TRACE_STR
)
4984 PIM_DO_DEBUG_PIM_TRACE
;
4988 DEFUN (no_debug_pim_trace
,
4989 no_debug_pim_trace_cmd
,
4990 "no debug pim trace",
4994 DEBUG_PIM_TRACE_STR
)
4996 PIM_DONT_DEBUG_PIM_TRACE
;
5001 DEFUN (debug_ssmpingd
,
5008 PIM_DO_DEBUG_SSMPINGD
;
5012 DEFUN (no_debug_ssmpingd
,
5013 no_debug_ssmpingd_cmd
,
5014 "no debug ssmpingd",
5020 PIM_DONT_DEBUG_SSMPINGD
;
5025 DEFUN (debug_pim_zebra
,
5026 debug_pim_zebra_cmd
,
5030 DEBUG_PIM_ZEBRA_STR
)
5036 DEFUN (no_debug_pim_zebra
,
5037 no_debug_pim_zebra_cmd
,
5038 "no debug pim zebra",
5042 DEBUG_PIM_ZEBRA_STR
)
5044 PIM_DONT_DEBUG_ZEBRA
;
5055 PIM_DO_DEBUG_MSDP_EVENTS
;
5056 PIM_DO_DEBUG_MSDP_PACKETS
;
5060 DEFUN (no_debug_msdp
,
5067 PIM_DONT_DEBUG_MSDP_EVENTS
;
5068 PIM_DONT_DEBUG_MSDP_PACKETS
;
5072 ALIAS (no_debug_msdp
,
5078 DEFUN (debug_msdp_events
,
5079 debug_msdp_events_cmd
,
5080 "debug msdp events",
5083 DEBUG_MSDP_EVENTS_STR
)
5085 PIM_DO_DEBUG_MSDP_EVENTS
;
5089 DEFUN (no_debug_msdp_events
,
5090 no_debug_msdp_events_cmd
,
5091 "no debug msdp events",
5095 DEBUG_MSDP_EVENTS_STR
)
5097 PIM_DONT_DEBUG_MSDP_EVENTS
;
5101 ALIAS (no_debug_msdp_events
,
5102 undebug_msdp_events_cmd
,
5103 "undebug msdp events",
5106 DEBUG_MSDP_EVENTS_STR
)
5108 DEFUN (debug_msdp_packets
,
5109 debug_msdp_packets_cmd
,
5110 "debug msdp packets",
5113 DEBUG_MSDP_PACKETS_STR
)
5115 PIM_DO_DEBUG_MSDP_PACKETS
;
5119 DEFUN (no_debug_msdp_packets
,
5120 no_debug_msdp_packets_cmd
,
5121 "no debug msdp packets",
5125 DEBUG_MSDP_PACKETS_STR
)
5127 PIM_DONT_DEBUG_MSDP_PACKETS
;
5131 ALIAS (no_debug_msdp_packets
,
5132 undebug_msdp_packets_cmd
,
5133 "undebug msdp packets",
5136 DEBUG_MSDP_PACKETS_STR
)
5138 DEFUN (show_debugging_pim
,
5139 show_debugging_pim_cmd
,
5140 "show debugging pim",
5145 pim_debug_config_write(vty
);
5150 interface_pim_use_src_cmd_worker(struct vty
*vty
, const char *source
)
5153 struct in_addr source_addr
;
5154 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5156 result
= inet_pton(AF_INET
, source
, &source_addr
);
5158 vty_out(vty
, "%% Bad source address %s: errno=%d: %s%s",
5159 source
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
5163 result
= pim_update_source_set(ifp
, source_addr
);
5167 case PIM_IFACE_NOT_FOUND
:
5168 vty_out(vty
, "Pim not enabled on this interface%s", VTY_NEWLINE
);
5170 case PIM_UPDATE_SOURCE_DUP
:
5171 vty_out(vty
, "%% Source already set to %s%s", source
, VTY_NEWLINE
);
5174 vty_out(vty
, "%% Source set failed%s", VTY_NEWLINE
);
5177 return result
?CMD_WARNING
:CMD_SUCCESS
;
5180 DEFUN (interface_pim_use_source
,
5181 interface_pim_use_source_cmd
,
5182 "ip pim use-source A.B.C.D",
5184 "pim multicast routing\n"
5185 "Configure primary IP address\n"
5186 "source ip address\n")
5188 return interface_pim_use_src_cmd_worker (vty
, argv
[3]->arg
);
5191 DEFUN (interface_no_pim_use_source
,
5192 interface_no_pim_use_source_cmd
,
5193 "no ip pim use-source",
5196 "pim multicast routing\n"
5197 "Delete source IP address\n")
5199 return interface_pim_use_src_cmd_worker (vty
, "0.0.0.0");
5203 ip_msdp_peer_cmd_worker (struct vty
*vty
, const char *peer
, const char *local
)
5205 enum pim_msdp_err result
;
5206 struct in_addr peer_addr
;
5207 struct in_addr local_addr
;
5209 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
5211 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s%s",
5212 peer
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
5216 result
= inet_pton(AF_INET
, local
, &local_addr
);
5218 vty_out(vty
, "%% Bad source address %s: errno=%d: %s%s",
5219 local
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
5223 result
= pim_msdp_peer_add(peer_addr
, local_addr
, "default", NULL
/* mp_p */);
5225 case PIM_MSDP_ERR_NONE
:
5227 case PIM_MSDP_ERR_OOM
:
5228 vty_out(vty
, "%% Out of memory%s", VTY_NEWLINE
);
5230 case PIM_MSDP_ERR_PEER_EXISTS
:
5231 vty_out(vty
, "%% Peer exists%s", VTY_NEWLINE
);
5233 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
5234 vty_out(vty
, "%% Only one mesh-group allowed currently%s", VTY_NEWLINE
);
5237 vty_out(vty
, "%% peer add failed%s", VTY_NEWLINE
);
5240 return result
?CMD_WARNING
:CMD_SUCCESS
;
5243 DEFUN_HIDDEN (ip_msdp_peer
,
5245 "ip msdp peer A.B.C.D source A.B.C.D",
5248 "Configure MSDP peer\n"
5250 "Source address for TCP connection\n"
5251 "local ip address\n")
5253 return ip_msdp_peer_cmd_worker (vty
, argv
[3]->arg
, argv
[5]->arg
);
5257 ip_no_msdp_peer_cmd_worker (struct vty
*vty
, const char *peer
)
5259 enum pim_msdp_err result
;
5260 struct in_addr peer_addr
;
5262 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
5264 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s%s",
5265 peer
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
5269 result
= pim_msdp_peer_del(peer_addr
);
5271 case PIM_MSDP_ERR_NONE
:
5273 case PIM_MSDP_ERR_NO_PEER
:
5274 vty_out(vty
, "%% Peer does not exist%s", VTY_NEWLINE
);
5277 vty_out(vty
, "%% peer del failed%s", VTY_NEWLINE
);
5280 return result
?CMD_WARNING
:CMD_SUCCESS
;
5283 DEFUN_HIDDEN (no_ip_msdp_peer
,
5284 no_ip_msdp_peer_cmd
,
5285 "no ip msdp peer A.B.C.D",
5289 "Delete MSDP peer\n"
5290 "peer ip address\n")
5292 return ip_no_msdp_peer_cmd_worker (vty
, argv
[4]->arg
);
5296 ip_msdp_mesh_group_member_cmd_worker(struct vty
*vty
, const char *mg
, const char *mbr
)
5298 enum pim_msdp_err result
;
5299 struct in_addr mbr_ip
;
5301 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
5303 vty_out(vty
, "%% Bad member address %s: errno=%d: %s%s",
5304 mbr
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
5308 result
= pim_msdp_mg_mbr_add(mg
, mbr_ip
);
5310 case PIM_MSDP_ERR_NONE
:
5312 case PIM_MSDP_ERR_OOM
:
5313 vty_out(vty
, "%% Out of memory%s", VTY_NEWLINE
);
5315 case PIM_MSDP_ERR_MG_MBR_EXISTS
:
5316 vty_out(vty
, "%% mesh-group member exists%s", VTY_NEWLINE
);
5318 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
5319 vty_out(vty
, "%% Only one mesh-group allowed currently%s", VTY_NEWLINE
);
5322 vty_out(vty
, "%% member add failed%s", VTY_NEWLINE
);
5325 return result
?CMD_WARNING
:CMD_SUCCESS
;
5328 DEFUN (ip_msdp_mesh_group_member
,
5329 ip_msdp_mesh_group_member_cmd
,
5330 "ip msdp mesh-group WORD member A.B.C.D",
5333 "Configure MSDP mesh-group\n"
5335 "mesh group member\n"
5336 "peer ip address\n")
5338 return ip_msdp_mesh_group_member_cmd_worker(vty
, argv
[3]->arg
, argv
[5]->arg
);
5342 ip_no_msdp_mesh_group_member_cmd_worker(struct vty
*vty
, const char *mg
, const char *mbr
)
5344 enum pim_msdp_err result
;
5345 struct in_addr mbr_ip
;
5347 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
5349 vty_out(vty
, "%% Bad member address %s: errno=%d: %s%s",
5350 mbr
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
5354 result
= pim_msdp_mg_mbr_del(mg
, mbr_ip
);
5356 case PIM_MSDP_ERR_NONE
:
5358 case PIM_MSDP_ERR_NO_MG
:
5359 vty_out(vty
, "%% mesh-group does not exist%s", VTY_NEWLINE
);
5361 case PIM_MSDP_ERR_NO_MG_MBR
:
5362 vty_out(vty
, "%% mesh-group member does not exist%s", VTY_NEWLINE
);
5365 vty_out(vty
, "%% mesh-group member del failed%s", VTY_NEWLINE
);
5368 return result
?CMD_WARNING
:CMD_SUCCESS
;
5370 DEFUN (no_ip_msdp_mesh_group_member
,
5371 no_ip_msdp_mesh_group_member_cmd
,
5372 "no ip msdp mesh-group WORD member A.B.C.D",
5376 "Delete MSDP mesh-group member\n"
5378 "mesh group member\n"
5379 "peer ip address\n")
5381 return ip_no_msdp_mesh_group_member_cmd_worker(vty
, argv
[4]->arg
, argv
[6]->arg
);
5385 ip_msdp_mesh_group_source_cmd_worker(struct vty
*vty
, const char *mg
, const char *src
)
5387 enum pim_msdp_err result
;
5388 struct in_addr src_ip
;
5390 result
= inet_pton(AF_INET
, src
, &src_ip
);
5392 vty_out(vty
, "%% Bad source address %s: errno=%d: %s%s",
5393 src
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
5397 result
= pim_msdp_mg_src_add(mg
, src_ip
);
5399 case PIM_MSDP_ERR_NONE
:
5401 case PIM_MSDP_ERR_OOM
:
5402 vty_out(vty
, "%% Out of memory%s", VTY_NEWLINE
);
5404 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
5405 vty_out(vty
, "%% Only one mesh-group allowed currently%s", VTY_NEWLINE
);
5408 vty_out(vty
, "%% source add failed%s", VTY_NEWLINE
);
5411 return result
?CMD_WARNING
:CMD_SUCCESS
;
5415 DEFUN (ip_msdp_mesh_group_source
,
5416 ip_msdp_mesh_group_source_cmd
,
5417 "ip msdp mesh-group WORD source A.B.C.D",
5420 "Configure MSDP mesh-group\n"
5422 "mesh group local address\n"
5423 "source ip address for the TCP connection\n")
5425 return ip_msdp_mesh_group_source_cmd_worker(vty
, argv
[3]->arg
, argv
[5]->arg
);
5429 ip_no_msdp_mesh_group_source_cmd_worker(struct vty
*vty
, const char *mg
)
5431 enum pim_msdp_err result
;
5433 result
= pim_msdp_mg_src_del(mg
);
5435 case PIM_MSDP_ERR_NONE
:
5437 case PIM_MSDP_ERR_NO_MG
:
5438 vty_out(vty
, "%% mesh-group does not exist%s", VTY_NEWLINE
);
5441 vty_out(vty
, "%% mesh-group source del failed%s", VTY_NEWLINE
);
5444 return result
?CMD_WARNING
:CMD_SUCCESS
;
5448 ip_no_msdp_mesh_group_cmd_worker(struct vty
*vty
, const char *mg
)
5450 enum pim_msdp_err result
;
5452 result
= pim_msdp_mg_del(mg
);
5454 case PIM_MSDP_ERR_NONE
:
5456 case PIM_MSDP_ERR_NO_MG
:
5457 vty_out(vty
, "%% mesh-group does not exist%s", VTY_NEWLINE
);
5460 vty_out(vty
, "%% mesh-group source del failed%s", VTY_NEWLINE
);
5463 return result
? CMD_WARNING
: CMD_SUCCESS
;
5466 DEFUN (no_ip_msdp_mesh_group_source
,
5467 no_ip_msdp_mesh_group_source_cmd
,
5468 "no ip msdp mesh-group WORD source [A.B.C.D]",
5472 "Delete MSDP mesh-group source\n"
5474 "mesh group source\n"
5475 "mesh group local address\n")
5478 return ip_no_msdp_mesh_group_cmd_worker(vty
, argv
[6]->arg
);
5480 return ip_no_msdp_mesh_group_source_cmd_worker(vty
, argv
[4]->arg
);
5484 print_empty_json_obj(struct vty
*vty
)
5487 json
= json_object_new_object();
5488 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
5489 json_object_free(json
);
5493 ip_msdp_show_mesh_group(struct vty
*vty
, u_char uj
)
5495 struct listnode
*mbrnode
;
5496 struct pim_msdp_mg_mbr
*mbr
;
5497 struct pim_msdp_mg
*mg
= msdp
->mg
;
5498 char mbr_str
[INET_ADDRSTRLEN
];
5499 char src_str
[INET_ADDRSTRLEN
];
5500 char state_str
[PIM_MSDP_STATE_STRLEN
];
5501 enum pim_msdp_peer_state state
;
5502 json_object
*json
= NULL
;
5503 json_object
*json_mg_row
= NULL
;
5504 json_object
*json_members
= NULL
;
5505 json_object
*json_row
= NULL
;
5509 print_empty_json_obj(vty
);
5513 pim_inet4_dump("<source?>", mg
->src_ip
, src_str
, sizeof(src_str
));
5515 json
= json_object_new_object();
5516 /* currently there is only one mesh group but we should still make
5517 * it a dict with mg-name as key */
5518 json_mg_row
= json_object_new_object();
5519 json_object_string_add(json_mg_row
, "name", mg
->mesh_group_name
);
5520 json_object_string_add(json_mg_row
, "source", src_str
);
5522 vty_out(vty
, "Mesh group : %s%s", mg
->mesh_group_name
, VTY_NEWLINE
);
5523 vty_out(vty
, " Source : %s%s", src_str
, VTY_NEWLINE
);
5524 vty_out(vty
, " Member State%s", VTY_NEWLINE
);
5527 for (ALL_LIST_ELEMENTS_RO(mg
->mbr_list
, mbrnode
, mbr
)) {
5528 pim_inet4_dump("<mbr?>", mbr
->mbr_ip
, mbr_str
, sizeof(mbr_str
));
5530 state
= mbr
->mp
->state
;
5532 state
= PIM_MSDP_DISABLED
;
5534 pim_msdp_state_dump(state
, state_str
, sizeof(state_str
));
5536 json_row
= json_object_new_object();
5537 json_object_string_add(json_row
, "member", mbr_str
);
5538 json_object_string_add(json_row
, "state", state_str
);
5539 if (!json_members
) {
5540 json_members
= json_object_new_object();
5541 json_object_object_add(json_mg_row
, "members", json_members
);
5543 json_object_object_add(json_members
, mbr_str
, json_row
);
5545 vty_out(vty
, " %-15s %11s%s",
5546 mbr_str
, state_str
, VTY_NEWLINE
);
5551 json_object_object_add(json
, mg
->mesh_group_name
, json_mg_row
);
5552 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
5553 json_object_free(json
);
5557 DEFUN (show_ip_msdp_mesh_group
,
5558 show_ip_msdp_mesh_group_cmd
,
5559 "show ip msdp mesh-group [json]",
5563 "MSDP mesh-group information\n"
5564 "JavaScript Object Notation\n")
5566 u_char uj
= use_json(argc
, argv
);
5567 ip_msdp_show_mesh_group(vty
, uj
);
5573 ip_msdp_show_peers(struct vty
*vty
, u_char uj
)
5575 struct listnode
*mpnode
;
5576 struct pim_msdp_peer
*mp
;
5577 char peer_str
[INET_ADDRSTRLEN
];
5578 char local_str
[INET_ADDRSTRLEN
];
5579 char state_str
[PIM_MSDP_STATE_STRLEN
];
5580 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
5582 json_object
*json
= NULL
;
5583 json_object
*json_row
= NULL
;
5587 json
= json_object_new_object();
5589 vty_out(vty
, "Peer Local State Uptime SaCnt%s", VTY_NEWLINE
);
5592 for (ALL_LIST_ELEMENTS_RO(msdp
->peer_list
, mpnode
, mp
)) {
5593 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
5594 now
= pim_time_monotonic_sec();
5595 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- mp
->uptime
);
5597 strcpy(timebuf
, "-");
5599 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
5600 pim_inet4_dump("<local?>", mp
->local
, local_str
, sizeof(local_str
));
5601 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
5603 json_row
= json_object_new_object();
5604 json_object_string_add(json_row
, "peer", peer_str
);
5605 json_object_string_add(json_row
, "local", local_str
);
5606 json_object_string_add(json_row
, "state", state_str
);
5607 json_object_string_add(json_row
, "upTime", timebuf
);
5608 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
5609 json_object_object_add(json
, peer_str
, json_row
);
5611 vty_out(vty
, "%-15s %15s %11s %8s %6d%s",
5612 peer_str
, local_str
, state_str
,
5613 timebuf
, mp
->sa_cnt
, VTY_NEWLINE
);
5618 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
5619 json_object_free(json
);
5624 ip_msdp_show_peers_detail(struct vty
*vty
, const char *peer
, u_char uj
)
5626 struct listnode
*mpnode
;
5627 struct pim_msdp_peer
*mp
;
5628 char peer_str
[INET_ADDRSTRLEN
];
5629 char local_str
[INET_ADDRSTRLEN
];
5630 char state_str
[PIM_MSDP_STATE_STRLEN
];
5631 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
5632 char katimer
[PIM_MSDP_TIMER_STRLEN
];
5633 char crtimer
[PIM_MSDP_TIMER_STRLEN
];
5634 char holdtimer
[PIM_MSDP_TIMER_STRLEN
];
5636 json_object
*json
= NULL
;
5637 json_object
*json_row
= NULL
;
5640 json
= json_object_new_object();
5643 for (ALL_LIST_ELEMENTS_RO(msdp
->peer_list
, mpnode
, mp
)) {
5644 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
5645 if (strcmp(peer
, "detail") &&
5646 strcmp(peer
, peer_str
))
5649 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
5650 now
= pim_time_monotonic_sec();
5651 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- mp
->uptime
);
5653 strcpy(timebuf
, "-");
5655 pim_inet4_dump("<local?>", mp
->local
, local_str
, sizeof(local_str
));
5656 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
5657 pim_time_timer_to_hhmmss(katimer
, sizeof(katimer
), mp
->ka_timer
);
5658 pim_time_timer_to_hhmmss(crtimer
, sizeof(crtimer
), mp
->cr_timer
);
5659 pim_time_timer_to_hhmmss(holdtimer
, sizeof(holdtimer
), mp
->hold_timer
);
5662 json_row
= json_object_new_object();
5663 json_object_string_add(json_row
, "peer", peer_str
);
5664 json_object_string_add(json_row
, "local", local_str
);
5665 json_object_string_add(json_row
, "meshGroupName", mp
->mesh_group_name
);
5666 json_object_string_add(json_row
, "state", state_str
);
5667 json_object_string_add(json_row
, "upTime", timebuf
);
5668 json_object_string_add(json_row
, "keepAliveTimer", katimer
);
5669 json_object_string_add(json_row
, "connRetryTimer", crtimer
);
5670 json_object_string_add(json_row
, "holdTimer", holdtimer
);
5671 json_object_string_add(json_row
, "lastReset", mp
->last_reset
);
5672 json_object_int_add(json_row
, "connAttempts", mp
->conn_attempts
);
5673 json_object_int_add(json_row
, "establishedChanges", mp
->est_flaps
);
5674 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
5675 json_object_int_add(json_row
, "kaSent", mp
->ka_tx_cnt
);
5676 json_object_int_add(json_row
, "kaRcvd", mp
->ka_rx_cnt
);
5677 json_object_int_add(json_row
, "saSent", mp
->sa_tx_cnt
);
5678 json_object_int_add(json_row
, "saRcvd", mp
->sa_rx_cnt
);
5679 json_object_object_add(json
, peer_str
, json_row
);
5681 vty_out(vty
, "Peer : %s%s", peer_str
, VTY_NEWLINE
);
5682 vty_out(vty
, " Local : %s%s", local_str
, VTY_NEWLINE
);
5683 vty_out(vty
, " Mesh Group : %s%s", mp
->mesh_group_name
, VTY_NEWLINE
);
5684 vty_out(vty
, " State : %s%s", state_str
, VTY_NEWLINE
);
5685 vty_out(vty
, " Uptime : %s%s", timebuf
, VTY_NEWLINE
);
5687 vty_out(vty
, " Keepalive Timer : %s%s", katimer
, VTY_NEWLINE
);
5688 vty_out(vty
, " Conn Retry Timer : %s%s", crtimer
, VTY_NEWLINE
);
5689 vty_out(vty
, " Hold Timer : %s%s", holdtimer
, VTY_NEWLINE
);
5690 vty_out(vty
, " Last Reset : %s%s", mp
->last_reset
, VTY_NEWLINE
);
5691 vty_out(vty
, " Conn Attempts : %d%s", mp
->conn_attempts
, VTY_NEWLINE
);
5692 vty_out(vty
, " Established Changes : %d%s", mp
->est_flaps
, VTY_NEWLINE
);
5693 vty_out(vty
, " SA Count : %d%s", mp
->sa_cnt
, VTY_NEWLINE
);
5694 vty_out(vty
, " Statistics :%s", VTY_NEWLINE
);
5695 vty_out(vty
, " Sent Rcvd%s", VTY_NEWLINE
);
5696 vty_out(vty
, " Keepalives : %10d %10d%s",
5697 mp
->ka_tx_cnt
, mp
->ka_rx_cnt
, VTY_NEWLINE
);
5698 vty_out(vty
, " SAs : %10d %10d%s",
5699 mp
->sa_tx_cnt
, mp
->sa_rx_cnt
, VTY_NEWLINE
);
5700 vty_out(vty
, "%s", VTY_NEWLINE
);
5705 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
5706 json_object_free(json
);
5710 DEFUN (show_ip_msdp_peer_detail
,
5711 show_ip_msdp_peer_detail_cmd
,
5712 "show ip msdp peer [detail|A.B.C.D] [json]",
5716 "MSDP peer information\n"
5719 "JavaScript Object Notation\n")
5721 u_char uj
= use_json(argc
, argv
);
5726 ip_msdp_show_peers_detail(vty
, argv
[4]->arg
, uj
);
5728 ip_msdp_show_peers(vty
, uj
);
5734 ip_msdp_show_sa(struct vty
*vty
, u_char uj
)
5736 struct listnode
*sanode
;
5737 struct pim_msdp_sa
*sa
;
5738 char src_str
[INET_ADDRSTRLEN
];
5739 char grp_str
[INET_ADDRSTRLEN
];
5740 char rp_str
[INET_ADDRSTRLEN
];
5741 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
5745 json_object
*json
= NULL
;
5746 json_object
*json_group
= NULL
;
5747 json_object
*json_row
= NULL
;
5750 json
= json_object_new_object();
5752 vty_out(vty
, "Source Group RP Local SPT Uptime%s", VTY_NEWLINE
);
5755 for (ALL_LIST_ELEMENTS_RO(msdp
->sa_list
, sanode
, sa
)) {
5756 now
= pim_time_monotonic_sec();
5757 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
5758 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
5759 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
5760 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
5761 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
5763 strcpy(spt_str
, "yes");
5765 strcpy(spt_str
, "no");
5768 strcpy(rp_str
, "-");
5769 strcpy(spt_str
, "-");
5771 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
5772 strcpy(local_str
, "yes");
5774 strcpy(local_str
, "no");
5777 json_object_object_get_ex(json
, grp_str
, &json_group
);
5780 json_group
= json_object_new_object();
5781 json_object_object_add(json
, grp_str
, json_group
);
5784 json_row
= json_object_new_object();
5785 json_object_string_add(json_row
, "source", src_str
);
5786 json_object_string_add(json_row
, "group", grp_str
);
5787 json_object_string_add(json_row
, "rp", rp_str
);
5788 json_object_string_add(json_row
, "local", local_str
);
5789 json_object_string_add(json_row
, "sptSetup", spt_str
);
5790 json_object_string_add(json_row
, "upTime", timebuf
);
5791 json_object_object_add(json_group
, src_str
, json_row
);
5793 vty_out(vty
, "%-15s %15s %15s %5c %3c %8s%s",
5794 src_str
, grp_str
, rp_str
, local_str
[0], spt_str
[0], timebuf
, VTY_NEWLINE
);
5800 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
5801 json_object_free(json
);
5806 ip_msdp_show_sa_entry_detail(struct pim_msdp_sa
*sa
, const char *src_str
,
5807 const char *grp_str
, struct vty
*vty
,
5808 u_char uj
, json_object
*json
)
5810 char rp_str
[INET_ADDRSTRLEN
];
5811 char peer_str
[INET_ADDRSTRLEN
];
5812 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
5815 char statetimer
[PIM_MSDP_TIMER_STRLEN
];
5817 json_object
*json_group
= NULL
;
5818 json_object
*json_row
= NULL
;
5820 now
= pim_time_monotonic_sec();
5821 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
5822 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
5823 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
5824 pim_inet4_dump("<peer?>", sa
->peer
, peer_str
, sizeof(peer_str
));
5826 strcpy(spt_str
, "yes");
5828 strcpy(spt_str
, "no");
5831 strcpy(rp_str
, "-");
5832 strcpy(peer_str
, "-");
5833 strcpy(spt_str
, "-");
5835 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
5836 strcpy(local_str
, "yes");
5838 strcpy(local_str
, "no");
5840 pim_time_timer_to_hhmmss(statetimer
, sizeof(statetimer
), sa
->sa_state_timer
);
5842 json_object_object_get_ex(json
, grp_str
, &json_group
);
5845 json_group
= json_object_new_object();
5846 json_object_object_add(json
, grp_str
, json_group
);
5849 json_row
= json_object_new_object();
5850 json_object_string_add(json_row
, "source", src_str
);
5851 json_object_string_add(json_row
, "group", grp_str
);
5852 json_object_string_add(json_row
, "rp", rp_str
);
5853 json_object_string_add(json_row
, "local", local_str
);
5854 json_object_string_add(json_row
, "sptSetup", spt_str
);
5855 json_object_string_add(json_row
, "upTime", timebuf
);
5856 json_object_string_add(json_row
, "stateTimer", statetimer
);
5857 json_object_object_add(json_group
, src_str
, json_row
);
5859 vty_out(vty
, "SA : %s%s", sa
->sg_str
, VTY_NEWLINE
);
5860 vty_out(vty
, " RP : %s%s", rp_str
, VTY_NEWLINE
);
5861 vty_out(vty
, " Peer : %s%s", peer_str
, VTY_NEWLINE
);
5862 vty_out(vty
, " Local : %s%s", local_str
, VTY_NEWLINE
);
5863 vty_out(vty
, " SPT Setup : %s%s", spt_str
, VTY_NEWLINE
);
5864 vty_out(vty
, " Uptime : %s%s", timebuf
, VTY_NEWLINE
);
5865 vty_out(vty
, " State Timer : %s%s", statetimer
, VTY_NEWLINE
);
5866 vty_out(vty
, "%s", VTY_NEWLINE
);
5871 ip_msdp_show_sa_detail(struct vty
*vty
, u_char uj
)
5873 struct listnode
*sanode
;
5874 struct pim_msdp_sa
*sa
;
5875 char src_str
[INET_ADDRSTRLEN
];
5876 char grp_str
[INET_ADDRSTRLEN
];
5877 json_object
*json
= NULL
;
5880 json
= json_object_new_object();
5883 for (ALL_LIST_ELEMENTS_RO(msdp
->sa_list
, sanode
, sa
)) {
5884 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
5885 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
5886 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
, uj
, json
);
5890 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
5891 json_object_free(json
);
5895 DEFUN (show_ip_msdp_sa_detail
,
5896 show_ip_msdp_sa_detail_cmd
,
5897 "show ip msdp sa detail [json]",
5901 "MSDP active-source information\n"
5903 "JavaScript Object Notation\n")
5905 u_char uj
= use_json(argc
, argv
);
5906 ip_msdp_show_sa_detail(vty
, uj
);
5912 ip_msdp_show_sa_addr(struct vty
*vty
, const char *addr
, u_char uj
)
5914 struct listnode
*sanode
;
5915 struct pim_msdp_sa
*sa
;
5916 char src_str
[INET_ADDRSTRLEN
];
5917 char grp_str
[INET_ADDRSTRLEN
];
5918 json_object
*json
= NULL
;
5921 json
= json_object_new_object();
5924 for (ALL_LIST_ELEMENTS_RO(msdp
->sa_list
, sanode
, sa
)) {
5925 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
5926 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
5927 if (!strcmp(addr
, src_str
) || !strcmp(addr
, grp_str
)) {
5928 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
, uj
, json
);
5933 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
5934 json_object_free(json
);
5939 ip_msdp_show_sa_sg(struct vty
*vty
, const char *src
, const char *grp
, u_char uj
)
5941 struct listnode
*sanode
;
5942 struct pim_msdp_sa
*sa
;
5943 char src_str
[INET_ADDRSTRLEN
];
5944 char grp_str
[INET_ADDRSTRLEN
];
5945 json_object
*json
= NULL
;
5948 json
= json_object_new_object();
5951 for (ALL_LIST_ELEMENTS_RO(msdp
->sa_list
, sanode
, sa
)) {
5952 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
5953 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
5954 if (!strcmp(src
, src_str
) && !strcmp(grp
, grp_str
)) {
5955 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
, uj
, json
);
5960 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
5961 json_object_free(json
);
5965 DEFUN (show_ip_msdp_sa_sg
,
5966 show_ip_msdp_sa_sg_cmd
,
5967 "show ip msdp sa [A.B.C.D [A.B.C.D]] [json]",
5971 "MSDP active-source information\n"
5972 "source or group ip\n"
5974 "JavaScript Object Notation\n")
5976 u_char uj
= use_json(argc
, argv
);
5981 ip_msdp_show_sa_sg(vty
, argv
[4]->arg
, argv
[5]->arg
, uj
);
5983 ip_msdp_show_sa_addr(vty
, argv
[4]->arg
, uj
);
5985 ip_msdp_show_sa(vty
, uj
);
5992 install_node (&pim_global_node
, pim_global_config_write
); /* PIM_NODE */
5993 install_node (&interface_node
, pim_interface_config_write
); /* INTERFACE_NODE */
5996 install_node (&debug_node
, pim_debug_config_write
);
5998 install_element (CONFIG_NODE
, &ip_multicast_routing_cmd
);
5999 install_element (CONFIG_NODE
, &no_ip_multicast_routing_cmd
);
6000 install_element (CONFIG_NODE
, &ip_pim_rp_cmd
);
6001 install_element (CONFIG_NODE
, &no_ip_pim_rp_cmd
);
6002 install_element (CONFIG_NODE
, &ip_pim_rp_prefix_list_cmd
);
6003 install_element (CONFIG_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
6004 install_element (CONFIG_NODE
, &ip_pim_register_suppress_cmd
);
6005 install_element (CONFIG_NODE
, &no_ip_pim_register_suppress_cmd
);
6006 install_element (CONFIG_NODE
, &ip_pim_joinprune_time_cmd
);
6007 install_element (CONFIG_NODE
, &no_ip_pim_joinprune_time_cmd
);
6008 install_element (CONFIG_NODE
, &ip_pim_keep_alive_cmd
);
6009 install_element (CONFIG_NODE
, &no_ip_pim_keep_alive_cmd
);
6010 install_element (CONFIG_NODE
, &ip_pim_packets_cmd
);
6011 install_element (CONFIG_NODE
, &no_ip_pim_packets_cmd
);
6012 install_element (CONFIG_NODE
, &ip_ssmpingd_cmd
);
6013 install_element (CONFIG_NODE
, &no_ip_ssmpingd_cmd
);
6014 install_element (CONFIG_NODE
, &ip_msdp_peer_cmd
);
6015 install_element (CONFIG_NODE
, &no_ip_msdp_peer_cmd
);
6017 install_element (INTERFACE_NODE
, &interface_ip_igmp_cmd
);
6018 install_element (INTERFACE_NODE
, &interface_no_ip_igmp_cmd
);
6019 install_element (INTERFACE_NODE
, &interface_ip_igmp_join_cmd
);
6020 install_element (INTERFACE_NODE
, &interface_no_ip_igmp_join_cmd
);
6021 install_element (INTERFACE_NODE
, &interface_ip_igmp_version_cmd
);
6022 install_element (INTERFACE_NODE
, &interface_no_ip_igmp_version_cmd
);
6023 install_element (INTERFACE_NODE
, &interface_ip_igmp_query_interval_cmd
);
6024 install_element (INTERFACE_NODE
, &interface_no_ip_igmp_query_interval_cmd
);
6025 install_element (INTERFACE_NODE
, &interface_ip_igmp_query_max_response_time_cmd
);
6026 install_element (INTERFACE_NODE
, &interface_no_ip_igmp_query_max_response_time_cmd
);
6027 install_element (INTERFACE_NODE
, &interface_ip_igmp_query_max_response_time_dsec_cmd
);
6028 install_element (INTERFACE_NODE
, &interface_no_ip_igmp_query_max_response_time_dsec_cmd
);
6029 install_element (INTERFACE_NODE
, &interface_ip_pim_ssm_cmd
);
6030 install_element (INTERFACE_NODE
, &interface_no_ip_pim_ssm_cmd
);
6031 install_element (INTERFACE_NODE
, &interface_ip_pim_sm_cmd
);
6032 install_element (INTERFACE_NODE
, &interface_no_ip_pim_sm_cmd
);
6033 install_element (INTERFACE_NODE
, &interface_ip_pim_drprio_cmd
);
6034 install_element (INTERFACE_NODE
, &interface_no_ip_pim_drprio_cmd
);
6035 install_element (INTERFACE_NODE
, &interface_ip_pim_hello_cmd
);
6036 install_element (INTERFACE_NODE
, &interface_no_ip_pim_hello_cmd
);
6038 // Static mroutes NEB
6039 install_element (INTERFACE_NODE
, &interface_ip_mroute_cmd
);
6040 install_element (INTERFACE_NODE
, &interface_ip_mroute_source_cmd
);
6041 install_element (INTERFACE_NODE
, &interface_no_ip_mroute_cmd
);
6042 install_element (INTERFACE_NODE
, &interface_no_ip_mroute_source_cmd
);
6044 install_element (VIEW_NODE
, &show_ip_igmp_interface_cmd
);
6045 install_element (VIEW_NODE
, &show_ip_igmp_join_cmd
);
6046 install_element (VIEW_NODE
, &show_ip_igmp_groups_cmd
);
6047 install_element (VIEW_NODE
, &show_ip_igmp_groups_retransmissions_cmd
);
6048 install_element (VIEW_NODE
, &show_ip_igmp_sources_cmd
);
6049 install_element (VIEW_NODE
, &show_ip_igmp_sources_retransmissions_cmd
);
6050 install_element (VIEW_NODE
, &show_ip_pim_assert_cmd
);
6051 install_element (VIEW_NODE
, &show_ip_pim_assert_internal_cmd
);
6052 install_element (VIEW_NODE
, &show_ip_pim_assert_metric_cmd
);
6053 install_element (VIEW_NODE
, &show_ip_pim_assert_winner_metric_cmd
);
6054 install_element (VIEW_NODE
, &show_ip_pim_interface_cmd
);
6055 install_element (VIEW_NODE
, &show_ip_pim_join_cmd
);
6056 install_element (VIEW_NODE
, &show_ip_pim_local_membership_cmd
);
6057 install_element (VIEW_NODE
, &show_ip_pim_neighbor_cmd
);
6058 install_element (VIEW_NODE
, &show_ip_pim_rpf_cmd
);
6059 install_element (VIEW_NODE
, &show_ip_pim_secondary_cmd
);
6060 install_element (VIEW_NODE
, &show_ip_pim_state_cmd
);
6061 install_element (VIEW_NODE
, &show_ip_pim_upstream_cmd
);
6062 install_element (VIEW_NODE
, &show_ip_pim_upstream_join_desired_cmd
);
6063 install_element (VIEW_NODE
, &show_ip_pim_upstream_rpf_cmd
);
6064 install_element (VIEW_NODE
, &show_ip_pim_rp_cmd
);
6065 install_element (VIEW_NODE
, &show_ip_multicast_cmd
);
6066 install_element (VIEW_NODE
, &show_ip_mroute_cmd
);
6067 install_element (VIEW_NODE
, &show_ip_mroute_count_cmd
);
6068 install_element (VIEW_NODE
, &show_ip_rib_cmd
);
6069 install_element (VIEW_NODE
, &show_ip_ssmpingd_cmd
);
6070 install_element (VIEW_NODE
, &show_debugging_pim_cmd
);
6072 install_element (ENABLE_NODE
, &clear_ip_interfaces_cmd
);
6073 install_element (ENABLE_NODE
, &clear_ip_igmp_interfaces_cmd
);
6074 install_element (ENABLE_NODE
, &clear_ip_mroute_cmd
);
6075 install_element (ENABLE_NODE
, &clear_ip_pim_interfaces_cmd
);
6076 install_element (ENABLE_NODE
, &clear_ip_pim_oil_cmd
);
6078 install_element (ENABLE_NODE
, &debug_igmp_cmd
);
6079 install_element (ENABLE_NODE
, &no_debug_igmp_cmd
);
6080 install_element (ENABLE_NODE
, &debug_igmp_events_cmd
);
6081 install_element (ENABLE_NODE
, &no_debug_igmp_events_cmd
);
6082 install_element (ENABLE_NODE
, &debug_igmp_packets_cmd
);
6083 install_element (ENABLE_NODE
, &no_debug_igmp_packets_cmd
);
6084 install_element (ENABLE_NODE
, &debug_igmp_trace_cmd
);
6085 install_element (ENABLE_NODE
, &no_debug_igmp_trace_cmd
);
6086 install_element (ENABLE_NODE
, &debug_mroute_cmd
);
6087 install_element (ENABLE_NODE
, &debug_mroute_detail_cmd
);
6088 install_element (ENABLE_NODE
, &no_debug_mroute_cmd
);
6089 install_element (ENABLE_NODE
, &no_debug_mroute_detail_cmd
);
6090 install_element (ENABLE_NODE
, &debug_static_cmd
);
6091 install_element (ENABLE_NODE
, &no_debug_static_cmd
);
6092 install_element (ENABLE_NODE
, &debug_pim_cmd
);
6093 install_element (ENABLE_NODE
, &no_debug_pim_cmd
);
6094 install_element (ENABLE_NODE
, &debug_pim_events_cmd
);
6095 install_element (ENABLE_NODE
, &no_debug_pim_events_cmd
);
6096 install_element (ENABLE_NODE
, &debug_pim_packets_cmd
);
6097 install_element (ENABLE_NODE
, &no_debug_pim_packets_cmd
);
6098 install_element (ENABLE_NODE
, &debug_pim_packetdump_send_cmd
);
6099 install_element (ENABLE_NODE
, &no_debug_pim_packetdump_send_cmd
);
6100 install_element (ENABLE_NODE
, &debug_pim_packetdump_recv_cmd
);
6101 install_element (ENABLE_NODE
, &no_debug_pim_packetdump_recv_cmd
);
6102 install_element (ENABLE_NODE
, &debug_pim_trace_cmd
);
6103 install_element (ENABLE_NODE
, &no_debug_pim_trace_cmd
);
6104 install_element (ENABLE_NODE
, &debug_ssmpingd_cmd
);
6105 install_element (ENABLE_NODE
, &no_debug_ssmpingd_cmd
);
6106 install_element (ENABLE_NODE
, &debug_pim_zebra_cmd
);
6107 install_element (ENABLE_NODE
, &no_debug_pim_zebra_cmd
);
6108 install_element (ENABLE_NODE
, &debug_msdp_cmd
);
6109 install_element (ENABLE_NODE
, &no_debug_msdp_cmd
);
6110 install_element (ENABLE_NODE
, &undebug_msdp_cmd
);
6111 install_element (ENABLE_NODE
, &debug_msdp_events_cmd
);
6112 install_element (ENABLE_NODE
, &no_debug_msdp_events_cmd
);
6113 install_element (ENABLE_NODE
, &undebug_msdp_events_cmd
);
6114 install_element (ENABLE_NODE
, &debug_msdp_packets_cmd
);
6115 install_element (ENABLE_NODE
, &no_debug_msdp_packets_cmd
);
6116 install_element (ENABLE_NODE
, &undebug_msdp_packets_cmd
);
6118 install_element (CONFIG_NODE
, &debug_igmp_cmd
);
6119 install_element (CONFIG_NODE
, &no_debug_igmp_cmd
);
6120 install_element (CONFIG_NODE
, &debug_igmp_events_cmd
);
6121 install_element (CONFIG_NODE
, &no_debug_igmp_events_cmd
);
6122 install_element (CONFIG_NODE
, &debug_igmp_packets_cmd
);
6123 install_element (CONFIG_NODE
, &no_debug_igmp_packets_cmd
);
6124 install_element (CONFIG_NODE
, &debug_igmp_trace_cmd
);
6125 install_element (CONFIG_NODE
, &no_debug_igmp_trace_cmd
);
6126 install_element (CONFIG_NODE
, &debug_mroute_cmd
);
6127 install_element (CONFIG_NODE
, &debug_mroute_detail_cmd
);
6128 install_element (CONFIG_NODE
, &no_debug_mroute_cmd
);
6129 install_element (CONFIG_NODE
, &no_debug_mroute_detail_cmd
);
6130 install_element (CONFIG_NODE
, &debug_static_cmd
);
6131 install_element (CONFIG_NODE
, &no_debug_static_cmd
);
6132 install_element (CONFIG_NODE
, &debug_pim_cmd
);
6133 install_element (CONFIG_NODE
, &no_debug_pim_cmd
);
6134 install_element (CONFIG_NODE
, &debug_pim_events_cmd
);
6135 install_element (CONFIG_NODE
, &no_debug_pim_events_cmd
);
6136 install_element (CONFIG_NODE
, &debug_pim_packets_cmd
);
6137 install_element (CONFIG_NODE
, &no_debug_pim_packets_cmd
);
6138 install_element (CONFIG_NODE
, &debug_pim_trace_cmd
);
6139 install_element (CONFIG_NODE
, &no_debug_pim_trace_cmd
);
6140 install_element (CONFIG_NODE
, &debug_ssmpingd_cmd
);
6141 install_element (CONFIG_NODE
, &no_debug_ssmpingd_cmd
);
6142 install_element (CONFIG_NODE
, &debug_pim_zebra_cmd
);
6143 install_element (CONFIG_NODE
, &no_debug_pim_zebra_cmd
);
6144 install_element (CONFIG_NODE
, &debug_msdp_cmd
);
6145 install_element (CONFIG_NODE
, &no_debug_msdp_cmd
);
6146 install_element (CONFIG_NODE
, &undebug_msdp_cmd
);
6147 install_element (CONFIG_NODE
, &debug_msdp_events_cmd
);
6148 install_element (CONFIG_NODE
, &no_debug_msdp_events_cmd
);
6149 install_element (CONFIG_NODE
, &undebug_msdp_events_cmd
);
6150 install_element (CONFIG_NODE
, &debug_msdp_packets_cmd
);
6151 install_element (CONFIG_NODE
, &no_debug_msdp_packets_cmd
);
6152 install_element (CONFIG_NODE
, &undebug_msdp_packets_cmd
);
6153 install_element (CONFIG_NODE
, &ip_msdp_mesh_group_member_cmd
);
6154 install_element (CONFIG_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
6155 install_element (CONFIG_NODE
, &ip_msdp_mesh_group_source_cmd
);
6156 install_element (CONFIG_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
6157 install_element (VIEW_NODE
, &show_ip_msdp_peer_detail_cmd
);
6158 install_element (VIEW_NODE
, &show_ip_msdp_sa_detail_cmd
);
6159 install_element (VIEW_NODE
, &show_ip_msdp_sa_sg_cmd
);
6160 install_element (VIEW_NODE
, &show_ip_msdp_mesh_group_cmd
);
6161 install_element (INTERFACE_NODE
, &interface_pim_use_source_cmd
);
6162 install_element (INTERFACE_NODE
, &interface_no_pim_use_source_cmd
);