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,
32 #include "pim_mroute.h"
34 #include "pim_iface.h"
36 #include "pim_mroute.h"
39 #include "pim_igmpv3.h"
44 #include "pim_neighbor.h"
46 #include "pim_ifchannel.h"
47 #include "pim_hello.h"
49 #include "pim_upstream.h"
51 #include "pim_macro.h"
52 #include "pim_ssmpingd.h"
53 #include "pim_zebra.h"
54 #include "pim_static.h"
56 #include "pim_zlookup.h"
59 static struct cmd_node pim_global_node
= {
65 static struct cmd_node interface_node
= {
71 static struct cmd_node debug_node
=
78 static void pim_if_membership_clear(struct interface
*ifp
)
80 struct pim_interface
*pim_ifp
;
85 if (PIM_IF_TEST_PIM(pim_ifp
->options
) &&
86 PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
90 pim_ifchannel_membership_clear(ifp
);
94 When PIM is disabled on interface, IGMPv3 local membership
95 information is not injected into PIM interface state.
97 The function pim_if_membership_refresh() fetches all IGMPv3 local
98 membership information into PIM. It is intented to be called
99 whenever PIM is enabled on the interface in order to collect missed
100 local membership information.
102 static void pim_if_membership_refresh(struct interface
*ifp
)
104 struct pim_interface
*pim_ifp
;
105 struct listnode
*sock_node
;
106 struct igmp_sock
*igmp
;
111 if (!PIM_IF_TEST_PIM(pim_ifp
->options
))
113 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
))
117 First clear off membership from all PIM (S,G) entries on the
121 pim_ifchannel_membership_clear(ifp
);
124 Then restore PIM (S,G) membership from all IGMPv3 (S,G) entries on
128 /* scan igmp sockets */
129 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
130 struct listnode
*grpnode
;
131 struct igmp_group
*grp
;
133 /* scan igmp groups */
134 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grpnode
, grp
)) {
135 struct listnode
*srcnode
;
136 struct igmp_source
*src
;
138 /* scan group sources */
139 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
, srcnode
, src
)) {
141 if (IGMP_SOURCE_TEST_FORWARDING(src
->source_flags
)) {
144 memset (&sg
, 0, sizeof (struct prefix_sg
));
145 sg
.src
= src
->source_addr
;
146 sg
.grp
= grp
->group_addr
;
147 pim_ifchannel_local_membership_add(ifp
, &sg
);
150 } /* scan group sources */
151 } /* scan igmp groups */
152 } /* scan igmp sockets */
155 Finally delete every PIM (S,G) entry lacking all state info
158 pim_ifchannel_delete_on_noinfo(ifp
);
162 static void pim_show_assert(struct vty
*vty
)
164 struct pim_interface
*pim_ifp
;
165 struct pim_ifchannel
*ch
;
166 struct listnode
*ch_node
;
167 struct in_addr ifaddr
;
170 now
= pim_time_monotonic_sec();
173 "Interface Address Source Group State Winner Uptime Timer%s",
176 for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list
, ch_node
, ch
)) {
177 char ch_src_str
[INET_ADDRSTRLEN
];
178 char ch_grp_str
[INET_ADDRSTRLEN
];
179 char winner_str
[INET_ADDRSTRLEN
];
183 pim_ifp
= ch
->interface
->info
;
188 ifaddr
= pim_ifp
->primary_address
;
190 pim_inet4_dump("<ch_src?>", ch
->sg
.src
,
191 ch_src_str
, sizeof(ch_src_str
));
192 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
,
193 ch_grp_str
, sizeof(ch_grp_str
));
194 pim_inet4_dump("<assrt_win?>", ch
->ifassert_winner
,
195 winner_str
, sizeof(winner_str
));
197 pim_time_uptime(uptime
, sizeof(uptime
), now
- ch
->ifassert_creation
);
198 pim_time_timer_to_mmss(timer
, sizeof(timer
),
199 ch
->t_ifassert_timer
);
201 vty_out(vty
, "%-9s %-15s %-15s %-15s %-6s %-15s %-8s %-5s%s",
206 pim_ifchannel_ifassert_name(ch
->ifassert_state
),
211 } /* scan interface channels */
214 static void pim_show_assert_internal(struct vty
*vty
)
216 struct pim_interface
*pim_ifp
;
217 struct listnode
*ch_node
;
218 struct pim_ifchannel
*ch
;
219 struct in_addr ifaddr
;
223 "ECA: Evaluate CouldAssert%s"
224 "ATD: AssertTrackingDesired%s"
225 "eATD: Evaluate AssertTrackingDesired%s%s",
226 VTY_NEWLINE
, VTY_NEWLINE
, VTY_NEWLINE
, VTY_NEWLINE
, VTY_NEWLINE
);
229 "Interface Address Source Group CA eCA ATD eATD%s",
232 for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list
, ch_node
, ch
)) {
233 pim_ifp
= ch
->interface
->info
;
238 ifaddr
= pim_ifp
->primary_address
;
240 char ch_src_str
[INET_ADDRSTRLEN
];
241 char ch_grp_str
[INET_ADDRSTRLEN
];
243 pim_inet4_dump("<ch_src?>", ch
->sg
.src
,
244 ch_src_str
, sizeof(ch_src_str
));
245 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
,
246 ch_grp_str
, sizeof(ch_grp_str
));
247 vty_out(vty
, "%-9s %-15s %-15s %-15s %-3s %-3s %-3s %-4s%s",
252 PIM_IF_FLAG_TEST_COULD_ASSERT(ch
->flags
) ? "yes" : "no",
253 pim_macro_ch_could_assert_eval(ch
) ? "yes" : "no",
254 PIM_IF_FLAG_TEST_ASSERT_TRACKING_DESIRED(ch
->flags
) ? "yes" : "no",
255 pim_macro_assert_tracking_desired_eval(ch
) ? "yes" : "no",
257 } /* scan interface channels */
260 static void pim_show_assert_metric(struct vty
*vty
)
262 struct pim_interface
*pim_ifp
;
263 struct listnode
*ch_node
;
264 struct pim_ifchannel
*ch
;
265 struct in_addr ifaddr
;
268 "Interface Address Source Group RPT Pref Metric Address %s",
271 for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list
, ch_node
, ch
)) {
272 pim_ifp
= ch
->interface
->info
;
277 ifaddr
= pim_ifp
->primary_address
;
279 char ch_src_str
[INET_ADDRSTRLEN
];
280 char ch_grp_str
[INET_ADDRSTRLEN
];
281 char addr_str
[INET_ADDRSTRLEN
];
282 struct pim_assert_metric am
;
284 am
= pim_macro_spt_assert_metric(&ch
->upstream
->rpf
, pim_ifp
->primary_address
);
286 pim_inet4_dump("<ch_src?>", ch
->sg
.src
,
287 ch_src_str
, sizeof(ch_src_str
));
288 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
,
289 ch_grp_str
, sizeof(ch_grp_str
));
290 pim_inet4_dump("<addr?>", am
.ip_address
,
291 addr_str
, sizeof(addr_str
));
293 vty_out(vty
, "%-9s %-15s %-15s %-15s %-3s %4u %6u %-15s%s",
298 am
.rpt_bit_flag
? "yes" : "no",
299 am
.metric_preference
,
303 } /* scan interface channels */
306 static void pim_show_assert_winner_metric(struct vty
*vty
)
308 struct pim_interface
*pim_ifp
;
309 struct listnode
*ch_node
;
310 struct pim_ifchannel
*ch
;
311 struct in_addr ifaddr
;
314 "Interface Address Source Group RPT Pref Metric Address %s",
317 for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list
, ch_node
, ch
)) {
318 pim_ifp
= ch
->interface
->info
;
323 ifaddr
= pim_ifp
->primary_address
;
325 char ch_src_str
[INET_ADDRSTRLEN
];
326 char ch_grp_str
[INET_ADDRSTRLEN
];
327 char addr_str
[INET_ADDRSTRLEN
];
328 struct pim_assert_metric
*am
;
332 am
= &ch
->ifassert_winner_metric
;
334 pim_inet4_dump("<ch_src?>", ch
->sg
.src
,
335 ch_src_str
, sizeof(ch_src_str
));
336 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
,
337 ch_grp_str
, sizeof(ch_grp_str
));
338 pim_inet4_dump("<addr?>", am
->ip_address
,
339 addr_str
, sizeof(addr_str
));
341 if (am
->metric_preference
== PIM_ASSERT_METRIC_PREFERENCE_MAX
)
342 snprintf(pref_str
, sizeof(pref_str
), "INFI");
344 snprintf(pref_str
, sizeof(pref_str
), "%4u", am
->metric_preference
);
346 if (am
->route_metric
== PIM_ASSERT_ROUTE_METRIC_MAX
)
347 snprintf(metr_str
, sizeof(metr_str
), "INFI");
349 snprintf(metr_str
, sizeof(metr_str
), "%6u", am
->route_metric
);
351 vty_out(vty
, "%-9s %-15s %-15s %-15s %-3s %-4s %-6s %-15s%s",
356 am
->rpt_bit_flag
? "yes" : "no",
361 } /* scan interface channels */
364 static void json_object_pim_ifp_add(struct json_object
*json
, struct interface
*ifp
)
366 struct pim_interface
*pim_ifp
;
369 json_object_string_add(json
, "name", ifp
->name
);
370 json_object_string_add(json
, "state", if_is_up(ifp
) ? "up" : "down");
371 json_object_string_add(json
, "address", inet_ntoa(pim_ifp
->primary_address
));
372 json_object_int_add(json
, "index", ifp
->ifindex
);
374 if (if_is_multicast(ifp
))
375 json_object_boolean_true_add(json
, "flagMulticast");
377 if (if_is_broadcast(ifp
))
378 json_object_boolean_true_add(json
, "flagBroadcast");
380 if (ifp
->flags
& IFF_ALLMULTI
)
381 json_object_boolean_true_add(json
, "flagAllMulticast");
383 if (ifp
->flags
& IFF_PROMISC
)
384 json_object_boolean_true_add(json
, "flagPromiscuous");
386 if (PIM_IF_IS_DELETED(ifp
))
387 json_object_boolean_true_add(json
, "flagDeleted");
389 if (pim_if_lan_delay_enabled(ifp
))
390 json_object_boolean_true_add(json
, "lanDelayEnabled");
393 static void pim_show_membership(struct vty
*vty
, u_char uj
)
395 struct pim_interface
*pim_ifp
;
396 struct listnode
*ch_node
;
397 struct pim_ifchannel
*ch
;
399 json_object
*json
= NULL
;
400 json_object
*json_iface
= NULL
;
401 json_object
*json_row
= NULL
;
402 json_object
*json_tmp
= NULL
;
404 json
= json_object_new_object();
406 for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list
, ch_node
, ch
)) {
408 pim_ifp
= ch
->interface
->info
;
413 char ch_src_str
[INET_ADDRSTRLEN
];
414 char ch_grp_str
[INET_ADDRSTRLEN
];
416 pim_inet4_dump("<ch_src?>", ch
->sg
.src
,
417 ch_src_str
, sizeof(ch_src_str
));
418 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
,
419 ch_grp_str
, sizeof(ch_grp_str
));
421 json_object_object_get_ex(json
, ch
->interface
->name
, &json_iface
);
424 json_iface
= json_object_new_object();
425 json_object_pim_ifp_add(json_iface
, ch
->interface
);
426 json_object_object_add(json
, ch
->interface
->name
, json_iface
);
429 json_row
= json_object_new_object();
430 json_object_string_add(json_row
, "source", ch_src_str
);
431 json_object_string_add(json_row
, "group", ch_grp_str
);
432 json_object_string_add(json_row
, "localMembership",
433 ch
->local_ifmembership
== PIM_IFMEMBERSHIP_NOINFO
? "NOINFO" : "INCLUDE");
434 json_object_object_add(json_iface
, ch_grp_str
, json_row
);
435 } /* scan interface channels */
438 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
441 "Interface Address Source Group Membership%s",
445 * Example of the json data we are traversing
451 * "address":"10.1.20.1",
453 * "flagMulticast":true,
454 * "flagBroadcast":true,
455 * "lanDelayEnabled":true,
458 * "group":"226.10.10.10",
459 * "localMembership":"INCLUDE"
465 /* foreach interface */
466 json_object_object_foreach(json
, key
, val
) {
468 /* Find all of the keys where the val is an object. In the example
469 * above the only one is 226.10.10.10
471 json_object_object_foreach(val
, if_field_key
, if_field_val
) {
472 type
= json_object_get_type(if_field_val
);
474 if (type
== json_type_object
) {
475 vty_out(vty
, "%-9s ", key
);
477 json_object_object_get_ex(val
, "address", &json_tmp
);
478 vty_out(vty
, "%-15s ", json_object_get_string(json_tmp
));
480 json_object_object_get_ex(if_field_val
, "source", &json_tmp
);
481 vty_out(vty
, "%-15s ", json_object_get_string(json_tmp
));
484 vty_out(vty
, "%-15s ", if_field_key
);
486 json_object_object_get_ex(if_field_val
, "localMembership", &json_tmp
);
487 vty_out(vty
, "%-10s%s", json_object_get_string(json_tmp
), VTY_NEWLINE
);
493 json_object_free(json
);
496 static void pim_print_ifp_flags(struct vty
*vty
, struct interface
*ifp
, int mloop
)
498 vty_out(vty
, "Flags%s", VTY_NEWLINE
);
499 vty_out(vty
, "-----%s", VTY_NEWLINE
);
500 vty_out(vty
, "All Multicast : %s%s", (ifp
->flags
& IFF_ALLMULTI
) ? "yes" : "no", VTY_NEWLINE
);
501 vty_out(vty
, "Broadcast : %s%s", if_is_broadcast(ifp
)? "yes" : "no", VTY_NEWLINE
);
502 vty_out(vty
, "Deleted : %s%s", PIM_IF_IS_DELETED(ifp
) ? "yes" : "no", VTY_NEWLINE
);
503 vty_out(vty
, "Interface Index : %d%s", ifp
->ifindex
, VTY_NEWLINE
);
504 vty_out(vty
, "Multicast : %s%s", if_is_multicast(ifp
) ? "yes" : "no", VTY_NEWLINE
);
505 vty_out(vty
, "Multicast Loop : %d%s", mloop
, VTY_NEWLINE
);
506 vty_out(vty
, "Promiscuous : %s%s", (ifp
->flags
& IFF_PROMISC
) ? "yes" : "no", VTY_NEWLINE
);
507 vty_out(vty
, "%s", VTY_NEWLINE
);
508 vty_out(vty
, "%s", VTY_NEWLINE
);
511 static void igmp_show_interfaces(struct vty
*vty
, u_char uj
)
513 struct listnode
*node
;
514 struct interface
*ifp
;
516 json_object
*json
= NULL
;
517 json_object
*json_row
= NULL
;
519 now
= pim_time_monotonic_sec();
522 json
= json_object_new_object();
525 "Interface State Address V Querier Query Timer Uptime%s",
528 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
)) {
529 struct pim_interface
*pim_ifp
;
530 struct listnode
*sock_node
;
531 struct igmp_sock
*igmp
;
538 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
540 char query_hhmmss
[10];
542 pim_time_uptime(uptime
, sizeof(uptime
), now
- igmp
->sock_creation
);
543 pim_time_timer_to_hhmmss(query_hhmmss
, sizeof(query_hhmmss
), igmp
->t_igmp_query_timer
);
546 json_row
= json_object_new_object();
547 json_object_pim_ifp_add(json_row
, ifp
);
548 json_object_string_add(json_row
, "upTime", uptime
);
549 json_object_int_add(json_row
, "version", pim_ifp
->igmp_version
);
551 if (igmp
->t_igmp_query_timer
) {
552 json_object_boolean_true_add(json_row
, "querier");
553 json_object_string_add(json_row
, "queryTimer", query_hhmmss
);
556 json_object_object_add(json
, ifp
->name
, json_row
);
559 vty_out(vty
, "%-9s %5s %15s %d %7s %11s %8s%s",
561 if_is_up(ifp
) ? "up" : "down",
562 inet_ntoa(igmp
->ifaddr
),
563 pim_ifp
->igmp_version
,
564 igmp
->t_igmp_query_timer
? "local" : "other",
573 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
574 json_object_free(json
);
578 static void igmp_show_interfaces_single(struct vty
*vty
, const char *ifname
, u_char uj
)
580 struct igmp_sock
*igmp
;
581 struct interface
*ifp
;
582 struct listnode
*node
;
583 struct listnode
*sock_node
;
584 struct pim_interface
*pim_ifp
;
586 char query_hhmmss
[10];
587 char other_hhmmss
[10];
588 int found_ifname
= 0;
591 long gmi_msec
; /* Group Membership Interval */
594 long oqpi_msec
; /* Other Querier Present Interval */
598 json_object
*json
= NULL
;
599 json_object
*json_row
= NULL
;
602 json
= json_object_new_object();
604 now
= pim_time_monotonic_sec();
606 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
)) {
612 if (strcmp(ifname
, "detail") && strcmp(ifname
, ifp
->name
))
615 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
617 pim_time_uptime(uptime
, sizeof(uptime
), now
- igmp
->sock_creation
);
618 pim_time_timer_to_hhmmss(query_hhmmss
, sizeof(query_hhmmss
), igmp
->t_igmp_query_timer
);
619 pim_time_timer_to_hhmmss(other_hhmmss
, sizeof(other_hhmmss
), igmp
->t_other_querier_timer
);
621 gmi_msec
= PIM_IGMP_GMI_MSEC(igmp
->querier_robustness_variable
,
622 igmp
->querier_query_interval
,
623 pim_ifp
->igmp_query_max_response_time_dsec
);
625 sqi
= PIM_IGMP_SQI(pim_ifp
->igmp_default_query_interval
);
627 oqpi_msec
= PIM_IGMP_OQPI_MSEC(igmp
->querier_robustness_variable
,
628 igmp
->querier_query_interval
,
629 pim_ifp
->igmp_query_max_response_time_dsec
);
631 lmqt_msec
= PIM_IGMP_LMQT_MSEC(pim_ifp
->igmp_query_max_response_time_dsec
,
632 igmp
->querier_robustness_variable
);
634 ohpi_msec
= PIM_IGMP_OHPI_DSEC(igmp
->querier_robustness_variable
,
635 igmp
->querier_query_interval
,
636 pim_ifp
->igmp_query_max_response_time_dsec
) * 100;
638 qri_msec
= pim_ifp
->igmp_query_max_response_time_dsec
* 100;
639 mloop
= pim_socket_mcastloop_get(pim_ifp
->pim_sock_fd
);
642 json_row
= json_object_new_object();
643 json_object_pim_ifp_add(json_row
, ifp
);
644 json_object_string_add(json_row
, "upTime", uptime
);
645 json_object_string_add(json_row
, "querier", igmp
->t_igmp_query_timer
? "local" : "other");
646 json_object_int_add(json_row
, "queryStartCount", igmp
->startup_query_count
);
647 json_object_string_add(json_row
, "queryQueryTimer", query_hhmmss
);
648 json_object_string_add(json_row
, "queryOtherTimer", other_hhmmss
);
649 json_object_int_add(json_row
, "version", pim_ifp
->igmp_version
);
650 json_object_int_add(json_row
, "timerGroupMembershipIntervalMsec", gmi_msec
);
651 json_object_int_add(json_row
, "timerLastMemberQueryMsec", lmqt_msec
);
652 json_object_int_add(json_row
, "timerOlderHostPresentIntervalMsec", ohpi_msec
);
653 json_object_int_add(json_row
, "timerOtherQuerierPresentIntervalMsec", oqpi_msec
);
654 json_object_int_add(json_row
, "timerQueryInterval", igmp
->querier_query_interval
);
655 json_object_int_add(json_row
, "timerQueryResponseIntervalMsec", qri_msec
);
656 json_object_int_add(json_row
, "timerRobustnessVariable", igmp
->querier_robustness_variable
);
657 json_object_int_add(json_row
, "timerStartupQueryInterval", sqi
);
659 json_object_object_add(json
, ifp
->name
, json_row
);
662 vty_out(vty
, "Interface : %s%s", ifp
->name
, VTY_NEWLINE
);
663 vty_out(vty
, "State : %s%s", if_is_up(ifp
) ? "up" : "down", VTY_NEWLINE
);
664 vty_out(vty
, "Address : %s%s", inet_ntoa(pim_ifp
->primary_address
), VTY_NEWLINE
);
665 vty_out(vty
, "Uptime : %s%s", uptime
, VTY_NEWLINE
);
666 vty_out(vty
, "Version : %d%s", pim_ifp
->igmp_version
, VTY_NEWLINE
);
667 vty_out(vty
, "%s", VTY_NEWLINE
);
668 vty_out(vty
, "%s", VTY_NEWLINE
);
670 vty_out(vty
, "Querier%s", VTY_NEWLINE
);
671 vty_out(vty
, "-------%s", VTY_NEWLINE
);
672 vty_out(vty
, "Querier : %s%s", igmp
->t_igmp_query_timer
? "local" : "other", VTY_NEWLINE
);
673 vty_out(vty
, "Start Count : %d%s", igmp
->startup_query_count
, VTY_NEWLINE
);
674 vty_out(vty
, "Query Timer : %s%s", query_hhmmss
, VTY_NEWLINE
);
675 vty_out(vty
, "Other Timer : %s%s", other_hhmmss
, VTY_NEWLINE
);
676 vty_out(vty
, "%s", VTY_NEWLINE
);
677 vty_out(vty
, "%s", VTY_NEWLINE
);
679 vty_out(vty
, "Timers%s", VTY_NEWLINE
);
680 vty_out(vty
, "------%s", VTY_NEWLINE
);
681 vty_out(vty
, "Group Membership Interval : %lis%s", gmi_msec
/1000, VTY_NEWLINE
);
682 vty_out(vty
, "Last Member Query Time : %lis%s", lmqt_msec
/1000, VTY_NEWLINE
);
683 vty_out(vty
, "Older Host Present Interval : %lis%s", ohpi_msec
/1000, VTY_NEWLINE
);
684 vty_out(vty
, "Other Querier Present Interval : %lis%s", oqpi_msec
/1000, VTY_NEWLINE
);
685 vty_out(vty
, "Query Interval : %ds%s", igmp
->querier_query_interval
, VTY_NEWLINE
);
686 vty_out(vty
, "Query Response Interval : %lis%s", qri_msec
/1000, VTY_NEWLINE
);
687 vty_out(vty
, "Robustness Variable : %d%s", igmp
->querier_robustness_variable
, VTY_NEWLINE
);
688 vty_out(vty
, "Startup Query Interval : %ds%s", sqi
, VTY_NEWLINE
);
689 vty_out(vty
, "%s", VTY_NEWLINE
);
690 vty_out(vty
, "%s", VTY_NEWLINE
);
692 pim_print_ifp_flags(vty
, ifp
, mloop
);
698 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
699 json_object_free(json
);
702 vty_out (vty
, "%% No such interface%s", VTY_NEWLINE
);
706 static void igmp_show_interface_join(struct vty
*vty
)
708 struct listnode
*node
;
709 struct interface
*ifp
;
712 now
= pim_time_monotonic_sec();
715 "Interface Address Source Group Socket Uptime %s",
718 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
)) {
719 struct pim_interface
*pim_ifp
;
720 struct listnode
*join_node
;
721 struct igmp_join
*ij
;
722 struct in_addr pri_addr
;
723 char pri_addr_str
[INET_ADDRSTRLEN
];
730 if (!pim_ifp
->igmp_join_list
)
733 pri_addr
= pim_find_primary_addr(ifp
);
734 pim_inet4_dump("<pri?>", pri_addr
, pri_addr_str
, sizeof(pri_addr_str
));
736 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_join_list
, join_node
, ij
)) {
737 char group_str
[INET_ADDRSTRLEN
];
738 char source_str
[INET_ADDRSTRLEN
];
741 pim_time_uptime(uptime
, sizeof(uptime
), now
- ij
->sock_creation
);
742 pim_inet4_dump("<grp?>", ij
->group_addr
, group_str
, sizeof(group_str
));
743 pim_inet4_dump("<src?>", ij
->source_addr
, source_str
, sizeof(source_str
));
745 vty_out(vty
, "%-9s %-15s %-15s %-15s %6d %8s%s",
753 } /* for (pim_ifp->igmp_join_list) */
759 static void pim_show_interfaces_single(struct vty
*vty
, const char *ifname
, u_char uj
)
761 struct in_addr ifaddr
;
762 struct interface
*ifp
;
763 struct listnode
*neighnode
;
764 struct listnode
*node
;
765 struct listnode
*upnode
;
766 struct pim_interface
*pim_ifp
;
767 struct pim_neighbor
*neigh
;
768 struct pim_upstream
*up
;
770 char dr_str
[INET_ADDRSTRLEN
];
773 char grp_str
[INET_ADDRSTRLEN
];
774 char hello_period
[10];
775 char hello_timer
[10];
776 char neigh_src_str
[INET_ADDRSTRLEN
];
777 char src_str
[INET_ADDRSTRLEN
];
778 char stat_uptime
[10];
781 int found_ifname
= 0;
783 json_object
*json
= NULL
;
784 json_object
*json_row
= NULL
;
785 json_object
*json_pim_neighbor
= NULL
;
786 json_object
*json_pim_neighbors
= NULL
;
787 json_object
*json_group
= NULL
;
788 json_object
*json_group_source
= NULL
;
789 json_object
*json_fhr_sources
= NULL
;
790 struct pim_secondary_addr
*sec_addr
;
791 struct listnode
*sec_node
;
793 now
= pim_time_monotonic_sec();
796 json
= json_object_new_object();
798 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
)) {
804 if (pim_ifp
->pim_sock_fd
< 0)
807 if (strcmp(ifname
, "detail") && strcmp(ifname
, ifp
->name
))
811 ifaddr
= pim_ifp
->primary_address
;
812 pim_inet4_dump("<dr?>", pim_ifp
->pim_dr_addr
, dr_str
, sizeof(dr_str
));
813 pim_time_uptime_begin(dr_uptime
, sizeof(dr_uptime
), now
, pim_ifp
->pim_dr_election_last
);
814 pim_time_timer_to_hhmmss(hello_timer
, sizeof(hello_timer
), pim_ifp
->t_pim_hello_timer
);
815 pim_time_mmss(hello_period
, sizeof(hello_period
), pim_ifp
->pim_hello_period
);
816 pim_time_uptime(stat_uptime
, sizeof(stat_uptime
), now
- pim_ifp
->pim_ifstat_start
);
817 mloop
= pim_socket_mcastloop_get(pim_ifp
->pim_sock_fd
);
820 json_row
= json_object_new_object();
821 json_object_pim_ifp_add(json_row
, ifp
);
823 if (pim_ifp
->update_source
.s_addr
!= INADDR_ANY
) {
824 json_object_string_add(json_row
, "useSource", inet_ntoa(pim_ifp
->update_source
));
826 if (pim_ifp
->sec_addr_list
) {
827 json_object
*sec_list
= NULL
;
829 sec_list
= json_object_new_array();
830 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->sec_addr_list
, sec_node
, sec_addr
)) {
831 json_object_array_add(sec_list
, json_object_new_string(inet_ntoa(sec_addr
->addr
)));
833 json_object_object_add(json_row
, "secondaryAddressList", sec_list
);
837 if (pim_ifp
->pim_neighbor_list
->count
) {
838 json_pim_neighbors
= json_object_new_object();
840 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
, neigh
)) {
841 json_pim_neighbor
= json_object_new_object();
842 pim_inet4_dump("<src?>", neigh
->source_addr
, neigh_src_str
, sizeof(neigh_src_str
));
843 pim_time_uptime(uptime
, sizeof(uptime
), now
- neigh
->creation
);
844 pim_time_timer_to_hhmmss(expire
, sizeof(expire
), neigh
->t_expire_timer
);
846 json_object_string_add(json_pim_neighbor
, "address", neigh_src_str
);
847 json_object_string_add(json_pim_neighbor
, "upTime", uptime
);
848 json_object_string_add(json_pim_neighbor
, "holdtime", expire
);
850 json_object_object_add(json_pim_neighbors
, neigh_src_str
, json_pim_neighbor
);
853 json_object_object_add(json_row
, "neighbors", json_pim_neighbors
);
856 json_object_string_add(json_row
, "drAddress", dr_str
);
857 json_object_int_add(json_row
, "drPriority", pim_ifp
->pim_dr_priority
);
858 json_object_string_add(json_row
, "drUptime", dr_uptime
);
859 json_object_int_add(json_row
, "drElections", pim_ifp
->pim_dr_election_count
);
860 json_object_int_add(json_row
, "drChanges", pim_ifp
->pim_dr_election_changes
);
863 for (ALL_LIST_ELEMENTS_RO(pim_upstream_list
, upnode
, up
)) {
864 if (ifp
== up
->rpf
.source_nexthop
.interface
) {
865 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
) {
866 if (!json_fhr_sources
) {
867 json_fhr_sources
= json_object_new_object();
870 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
871 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
872 pim_time_uptime(uptime
, sizeof(uptime
), now
- up
->state_transition
);
874 /* Does this group live in json_fhr_sources? If not create it. */
875 json_object_object_get_ex(json_fhr_sources
, grp_str
, &json_group
);
878 json_group
= json_object_new_object();
879 json_object_object_add(json_fhr_sources
, grp_str
, json_group
);
882 json_group_source
= json_object_new_object();
883 json_object_string_add(json_group_source
, "source", src_str
);
884 json_object_string_add(json_group_source
, "group", grp_str
);
885 json_object_string_add(json_group_source
, "upTime", uptime
);
886 json_object_object_add(json_group
, src_str
, json_group_source
);
891 if (json_fhr_sources
) {
892 json_object_object_add(json_row
, "firstHopRouter", json_fhr_sources
);
895 json_object_int_add(json_row
, "helloPeriod", pim_ifp
->pim_hello_period
);
896 json_object_string_add(json_row
, "helloTimer", hello_timer
);
897 json_object_string_add(json_row
, "helloStatStart", stat_uptime
);
898 json_object_int_add(json_row
, "helloReceived", pim_ifp
->pim_ifstat_hello_recv
);
899 json_object_int_add(json_row
, "helloReceivedFailed", pim_ifp
->pim_ifstat_hello_recvfail
);
900 json_object_int_add(json_row
, "helloSend", pim_ifp
->pim_ifstat_hello_sent
);
901 json_object_int_add(json_row
, "hellosendFailed", pim_ifp
->pim_ifstat_hello_sendfail
);
902 json_object_int_add(json_row
, "helloGenerationId", pim_ifp
->pim_generation_id
);
903 json_object_int_add(json_row
, "flagMulticastLoop", mloop
);
905 json_object_int_add(json_row
, "effectivePropagationDelay", pim_if_effective_propagation_delay_msec(ifp
));
906 json_object_int_add(json_row
, "effectiveOverrideInterval", pim_if_effective_override_interval_msec(ifp
));
907 json_object_int_add(json_row
, "joinPruneOverrideInterval", pim_if_jp_override_interval_msec(ifp
));
909 json_object_int_add(json_row
, "propagationDelay", pim_ifp
->pim_propagation_delay_msec
);
910 json_object_int_add(json_row
, "propagationDelayHighest", pim_ifp
->pim_neighbors_highest_propagation_delay_msec
);
911 json_object_int_add(json_row
, "overrideInterval", pim_ifp
->pim_override_interval_msec
);
912 json_object_int_add(json_row
, "overrideIntervalHighest", pim_ifp
->pim_neighbors_highest_override_interval_msec
);
913 json_object_object_add(json
, ifp
->name
, json_row
);
916 vty_out(vty
, "Interface : %s%s", ifp
->name
, VTY_NEWLINE
);
917 vty_out(vty
, "State : %s%s", if_is_up(ifp
) ? "up" : "down", VTY_NEWLINE
);
918 if (pim_ifp
->update_source
.s_addr
!= INADDR_ANY
) {
919 vty_out(vty
, "Use Source : %s%s", inet_ntoa(pim_ifp
->update_source
), VTY_NEWLINE
);
921 if (pim_ifp
->sec_addr_list
) {
922 vty_out(vty
, "Address : %s (primary)%s",
923 inet_ntoa(ifaddr
), VTY_NEWLINE
);
924 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->sec_addr_list
, sec_node
, sec_addr
)) {
925 vty_out(vty
, " %s%s",
926 inet_ntoa(sec_addr
->addr
), VTY_NEWLINE
);
929 vty_out(vty
, "Address : %s%s", inet_ntoa(ifaddr
), VTY_NEWLINE
);
931 vty_out(vty
, "%s", VTY_NEWLINE
);
936 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
, neigh
)) {
939 vty_out(vty
, "PIM Neighbors%s", VTY_NEWLINE
);
940 vty_out(vty
, "-------------%s", VTY_NEWLINE
);
944 pim_inet4_dump("<src?>", neigh
->source_addr
, neigh_src_str
, sizeof(neigh_src_str
));
945 pim_time_uptime(uptime
, sizeof(uptime
), now
- neigh
->creation
);
946 pim_time_timer_to_hhmmss(expire
, sizeof(expire
), neigh
->t_expire_timer
);
947 vty_out(vty
, "%-15s : up for %s, holdtime expires in %s%s", neigh_src_str
, uptime
, expire
, VTY_NEWLINE
);
951 vty_out(vty
, "%s", VTY_NEWLINE
);
952 vty_out(vty
, "%s", VTY_NEWLINE
);
955 vty_out(vty
, "Designated Router%s", VTY_NEWLINE
);
956 vty_out(vty
, "-----------------%s", VTY_NEWLINE
);
957 vty_out(vty
, "Address : %s%s", dr_str
, VTY_NEWLINE
);
958 vty_out(vty
, "Priority : %d%s", pim_ifp
->pim_dr_priority
, VTY_NEWLINE
);
959 vty_out(vty
, "Uptime : %s%s", dr_uptime
, VTY_NEWLINE
);
960 vty_out(vty
, "Elections : %d%s", pim_ifp
->pim_dr_election_count
, VTY_NEWLINE
);
961 vty_out(vty
, "Changes : %d%s", pim_ifp
->pim_dr_election_changes
, VTY_NEWLINE
);
962 vty_out(vty
, "%s", VTY_NEWLINE
);
963 vty_out(vty
, "%s", VTY_NEWLINE
);
967 for (ALL_LIST_ELEMENTS_RO(pim_upstream_list
, upnode
, up
)) {
968 if (strcmp(ifp
->name
, up
->rpf
.source_nexthop
.interface
->name
) == 0) {
969 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
) {
972 vty_out(vty
, "FHR - First Hop Router%s", VTY_NEWLINE
);
973 vty_out(vty
, "----------------------%s", VTY_NEWLINE
);
977 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
978 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
979 pim_time_uptime(uptime
, sizeof(uptime
), now
- up
->state_transition
);
980 vty_out(vty
, "%s : %s is a source, uptime is %s%s", grp_str
, src_str
, uptime
, VTY_NEWLINE
);
986 vty_out(vty
, "%s", VTY_NEWLINE
);
987 vty_out(vty
, "%s", VTY_NEWLINE
);
990 vty_out(vty
, "Hellos%s", VTY_NEWLINE
);
991 vty_out(vty
, "------%s", VTY_NEWLINE
);
992 vty_out(vty
, "Period : %d%s", pim_ifp
->pim_hello_period
, VTY_NEWLINE
);
993 vty_out(vty
, "Timer : %s%s", hello_timer
, VTY_NEWLINE
);
994 vty_out(vty
, "StatStart : %s%s", stat_uptime
, VTY_NEWLINE
);
995 vty_out(vty
, "Receive : %d%s", pim_ifp
->pim_ifstat_hello_recv
, VTY_NEWLINE
);
996 vty_out(vty
, "Receive Failed : %d%s", pim_ifp
->pim_ifstat_hello_recvfail
, VTY_NEWLINE
);
997 vty_out(vty
, "Send : %d%s", pim_ifp
->pim_ifstat_hello_sent
, VTY_NEWLINE
);
998 vty_out(vty
, "Send Failed : %d%s", pim_ifp
->pim_ifstat_hello_sendfail
, VTY_NEWLINE
);
999 vty_out(vty
, "Generation ID : %08x%s", pim_ifp
->pim_generation_id
, VTY_NEWLINE
);
1000 vty_out(vty
, "%s", VTY_NEWLINE
);
1001 vty_out(vty
, "%s", VTY_NEWLINE
);
1003 pim_print_ifp_flags(vty
, ifp
, mloop
);
1005 vty_out(vty
, "Join Prune Interval%s", VTY_NEWLINE
);
1006 vty_out(vty
, "-------------------%s", VTY_NEWLINE
);
1007 vty_out(vty
, "LAN Delay : %s%s", pim_if_lan_delay_enabled(ifp
) ? "yes" : "no", VTY_NEWLINE
);
1008 vty_out(vty
, "Effective Propagation Delay : %d msec%s", pim_if_effective_propagation_delay_msec(ifp
), VTY_NEWLINE
);
1009 vty_out(vty
, "Effective Override Interval : %d msec%s", pim_if_effective_override_interval_msec(ifp
), VTY_NEWLINE
);
1010 vty_out(vty
, "Join Prune Override Interval : %d msec%s", pim_if_jp_override_interval_msec(ifp
), VTY_NEWLINE
);
1011 vty_out(vty
, "%s", VTY_NEWLINE
);
1012 vty_out(vty
, "%s", VTY_NEWLINE
);
1014 vty_out(vty
, "LAN Prune Delay%s", VTY_NEWLINE
);
1015 vty_out(vty
, "---------------%s", VTY_NEWLINE
);
1016 vty_out(vty
, "Propagation Delay : %d msec%s", pim_ifp
->pim_propagation_delay_msec
, VTY_NEWLINE
);
1017 vty_out(vty
, "Propagation Delay (Highest) : %d msec%s", pim_ifp
->pim_neighbors_highest_propagation_delay_msec
, VTY_NEWLINE
);
1018 vty_out(vty
, "Override Interval : %d msec%s", pim_ifp
->pim_override_interval_msec
, VTY_NEWLINE
);
1019 vty_out(vty
, "Override Interval (Highest) : %d msec%s", pim_ifp
->pim_neighbors_highest_override_interval_msec
, VTY_NEWLINE
);
1020 vty_out(vty
, "%s", VTY_NEWLINE
);
1021 vty_out(vty
, "%s", VTY_NEWLINE
);
1026 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
1027 json_object_free(json
);
1030 vty_out (vty
, "%% No such interface%s", VTY_NEWLINE
);
1034 static void pim_show_interfaces(struct vty
*vty
, u_char uj
)
1036 struct interface
*ifp
;
1037 struct listnode
*node
;
1038 struct listnode
*upnode
;
1039 struct pim_interface
*pim_ifp
;
1040 struct pim_upstream
*up
;
1043 json_object
*json
= NULL
;
1044 json_object
*json_row
= NULL
;
1045 json_object
*json_tmp
;
1047 json
= json_object_new_object();
1049 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
)) {
1050 pim_ifp
= ifp
->info
;
1055 if (pim_ifp
->pim_sock_fd
< 0)
1058 pim_nbrs
= pim_ifp
->pim_neighbor_list
->count
;
1061 for (ALL_LIST_ELEMENTS_RO(pim_upstream_list
, upnode
, up
))
1062 if (ifp
== up
->rpf
.source_nexthop
.interface
)
1063 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
1066 json_row
= json_object_new_object();
1067 json_object_pim_ifp_add(json_row
, ifp
);
1068 json_object_int_add(json_row
, "pimNeighbors", pim_nbrs
);
1069 json_object_int_add(json_row
, "firstHopRouter", fhr
);
1070 json_object_string_add(json_row
, "pimDesignatedRouter", inet_ntoa(pim_ifp
->pim_dr_addr
));
1072 if (pim_ifp
->pim_dr_addr
.s_addr
== pim_ifp
->primary_address
.s_addr
)
1073 json_object_boolean_true_add(json_row
, "pimDesignatedRouterLocal");
1075 json_object_object_add(json
, ifp
->name
, json_row
);
1079 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
1081 vty_out(vty
, "Interface State Address PIM Nbrs PIM DR FHR%s", VTY_NEWLINE
);
1083 json_object_object_foreach(json
, key
, val
) {
1084 vty_out(vty
, "%-9s ", key
);
1086 json_object_object_get_ex(val
, "state", &json_tmp
);
1087 vty_out(vty
, "%5s ", json_object_get_string(json_tmp
));
1089 json_object_object_get_ex(val
, "address", &json_tmp
);
1090 vty_out(vty
, "%15s ", json_object_get_string(json_tmp
));
1092 json_object_object_get_ex(val
, "pimNeighbors", &json_tmp
);
1093 vty_out(vty
, "%8d ", json_object_get_int(json_tmp
));
1095 if (json_object_object_get_ex(val
, "pimDesignatedRouterLocal", &json_tmp
)) {
1096 vty_out(vty
, "%15s ", "local");
1098 json_object_object_get_ex(val
, "pimDesignatedRouter", &json_tmp
);
1099 vty_out(vty
, "%15s ", json_object_get_string(json_tmp
));
1102 json_object_object_get_ex(val
, "firstHopRouter", &json_tmp
);
1103 vty_out(vty
, "%3d%s", json_object_get_int(json_tmp
), VTY_NEWLINE
);
1107 json_object_free(json
);
1110 static void pim_show_join(struct vty
*vty
, u_char uj
)
1112 struct pim_interface
*pim_ifp
;
1113 struct in_addr ifaddr
;
1114 struct listnode
*ch_node
;
1115 struct pim_ifchannel
*ch
;
1117 json_object
*json
= NULL
;
1118 json_object
*json_iface
= NULL
;
1119 json_object
*json_row
= NULL
;
1120 json_object
*json_grp
= NULL
;
1122 now
= pim_time_monotonic_sec();
1125 json
= json_object_new_object();
1128 "Interface Address Source Group State Uptime Expire Prune%s",
1131 for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list
, ch_node
, ch
)) {
1133 pim_ifp
= ch
->interface
->info
;
1138 ifaddr
= pim_ifp
->primary_address
;
1140 char ch_src_str
[INET_ADDRSTRLEN
];
1141 char ch_grp_str
[INET_ADDRSTRLEN
];
1146 pim_inet4_dump("<ch_src?>", ch
->sg
.src
,
1147 ch_src_str
, sizeof(ch_src_str
));
1148 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
,
1149 ch_grp_str
, sizeof(ch_grp_str
));
1151 pim_time_uptime_begin(uptime
, sizeof(uptime
), now
, ch
->ifjoin_creation
);
1152 pim_time_timer_to_mmss(expire
, sizeof(expire
),
1153 ch
->t_ifjoin_expiry_timer
);
1154 pim_time_timer_to_mmss(prune
, sizeof(prune
),
1155 ch
->t_ifjoin_prune_pending_timer
);
1158 json_object_object_get_ex(json
, ch
->interface
->name
, &json_iface
);
1161 json_iface
= json_object_new_object();
1162 json_object_pim_ifp_add(json_iface
, ch
->interface
);
1163 json_object_object_add(json
, ch
->interface
->name
, json_iface
);
1166 json_row
= json_object_new_object();
1167 json_object_string_add(json_row
, "source", ch_src_str
);
1168 json_object_string_add(json_row
, "group", ch_grp_str
);
1169 json_object_string_add(json_row
, "upTime", uptime
);
1170 json_object_string_add(json_row
, "expire", expire
);
1171 json_object_string_add(json_row
, "prune", prune
);
1172 json_object_string_add(json_row
, "channelJoinName", pim_ifchannel_ifjoin_name(ch
->ifjoin_state
));
1173 if (PIM_IF_FLAG_TEST_S_G_RPT(ch
->flags
))
1174 json_object_int_add(json_row
, "SGRpt", 1);
1176 json_object_object_get_ex(json_iface
, ch_grp_str
, &json_grp
);
1179 json_grp
= json_object_new_object();
1180 json_object_object_add(json_grp
, ch_src_str
, json_row
);
1181 json_object_object_add(json_iface
, ch_grp_str
, json_grp
);
1184 json_object_object_add(json_grp
, ch_src_str
, json_row
);
1186 vty_out(vty
, "%-9s %-15s %-15s %-15s %-6s %8s %-6s %5s%s",
1187 ch
->interface
->name
,
1191 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
),
1197 } /* scan interface channels */
1200 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
1201 json_object_free(json
);
1205 static void pim_show_neighbors_single(struct vty
*vty
, const char *neighbor
, u_char uj
)
1207 struct listnode
*node
;
1208 struct listnode
*neighnode
;
1209 struct interface
*ifp
;
1210 struct pim_interface
*pim_ifp
;
1211 struct pim_neighbor
*neigh
;
1213 int found_neighbor
= 0;
1214 int option_address_list
;
1215 int option_dr_priority
;
1216 int option_generation_id
;
1217 int option_holdtime
;
1218 int option_lan_prune_delay
;
1222 char neigh_src_str
[INET_ADDRSTRLEN
];
1224 json_object
*json
= NULL
;
1225 json_object
*json_ifp
= NULL
;
1226 json_object
*json_row
= NULL
;
1228 now
= pim_time_monotonic_sec();
1231 json
= json_object_new_object();
1233 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
)) {
1234 pim_ifp
= ifp
->info
;
1239 if (pim_ifp
->pim_sock_fd
< 0)
1242 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
, neigh
)) {
1243 pim_inet4_dump("<src?>", neigh
->source_addr
,
1244 neigh_src_str
, sizeof(neigh_src_str
));
1247 * The user can specify either the interface name or the PIM neighbor IP.
1248 * If this pim_ifp matches neither then skip.
1250 if (strcmp(neighbor
, "detail") &&
1251 strcmp(neighbor
, ifp
->name
) &&
1252 strcmp(neighbor
, neigh_src_str
))
1256 pim_time_uptime(uptime
, sizeof(uptime
), now
- neigh
->creation
);
1257 pim_time_timer_to_hhmmss(expire
, sizeof(expire
), neigh
->t_expire_timer
);
1259 option_address_list
= 0;
1260 option_dr_priority
= 0;
1261 option_generation_id
= 0;
1262 option_holdtime
= 0;
1263 option_lan_prune_delay
= 0;
1266 if (PIM_OPTION_IS_SET(neigh
->hello_options
, PIM_OPTION_MASK_ADDRESS_LIST
))
1267 option_address_list
= 1;
1269 if (PIM_OPTION_IS_SET(neigh
->hello_options
, PIM_OPTION_MASK_DR_PRIORITY
))
1270 option_dr_priority
= 1;
1272 if (PIM_OPTION_IS_SET(neigh
->hello_options
, PIM_OPTION_MASK_GENERATION_ID
))
1273 option_generation_id
= 1;
1275 if (PIM_OPTION_IS_SET(neigh
->hello_options
, PIM_OPTION_MASK_HOLDTIME
))
1276 option_holdtime
= 1;
1278 if (PIM_OPTION_IS_SET(neigh
->hello_options
, PIM_OPTION_MASK_LAN_PRUNE_DELAY
))
1279 option_lan_prune_delay
= 1;
1281 if (PIM_OPTION_IS_SET(neigh
->hello_options
, PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION
))
1286 /* Does this ifp live in json? If not create it. */
1287 json_object_object_get_ex(json
, ifp
->name
, &json_ifp
);
1290 json_ifp
= json_object_new_object();
1291 json_object_pim_ifp_add(json_ifp
, ifp
);
1292 json_object_object_add(json
, ifp
->name
, json_ifp
);
1295 json_row
= json_object_new_object();
1296 json_object_string_add(json_row
, "interface", ifp
->name
);
1297 json_object_string_add(json_row
, "address", neigh_src_str
);
1298 json_object_string_add(json_row
, "upTime", uptime
);
1299 json_object_string_add(json_row
, "holdtime", expire
);
1300 json_object_int_add(json_row
, "drPriority", neigh
->dr_priority
);
1301 json_object_int_add(json_row
, "generationId", neigh
->generation_id
);
1303 if (option_address_list
)
1304 json_object_boolean_true_add(json_row
, "helloOptionAddressList");
1306 if (option_dr_priority
)
1307 json_object_boolean_true_add(json_row
, "helloOptionDrPriority");
1309 if (option_generation_id
)
1310 json_object_boolean_true_add(json_row
, "helloOptionGenerationId");
1312 if (option_holdtime
)
1313 json_object_boolean_true_add(json_row
, "helloOptionHoldtime");
1315 if (option_lan_prune_delay
)
1316 json_object_boolean_true_add(json_row
, "helloOptionLanPruneDelay");
1319 json_object_boolean_true_add(json_row
, "helloOptionTBit");
1321 json_object_object_add(json_ifp
, neigh_src_str
, json_row
);
1324 vty_out(vty
, "Interface : %s%s", ifp
->name
, VTY_NEWLINE
);
1325 vty_out(vty
, "Neighbor : %s%s", neigh_src_str
, VTY_NEWLINE
);
1326 vty_out(vty
, " Uptime : %s%s", uptime
, VTY_NEWLINE
);
1327 vty_out(vty
, " Holdtime : %s%s", expire
, VTY_NEWLINE
);
1328 vty_out(vty
, " DR Priority : %d%s", neigh
->dr_priority
, VTY_NEWLINE
);
1329 vty_out(vty
, " Generation ID : %08x%s", neigh
->generation_id
, VTY_NEWLINE
);
1330 vty_out(vty
, " Override Interval (msec) : %d%s", neigh
->override_interval_msec
, VTY_NEWLINE
);
1331 vty_out(vty
, " Propagation Delay (msec) : %d%s", neigh
->propagation_delay_msec
, VTY_NEWLINE
);
1332 vty_out(vty
, " Hello Option - Address List : %s%s", option_address_list
? "yes" : "no", VTY_NEWLINE
);
1333 vty_out(vty
, " Hello Option - DR Priority : %s%s", option_dr_priority
? "yes" : "no", VTY_NEWLINE
);
1334 vty_out(vty
, " Hello Option - Generation ID : %s%s", option_generation_id
? "yes" : "no", VTY_NEWLINE
);
1335 vty_out(vty
, " Hello Option - Holdtime : %s%s", option_holdtime
? "yes" : "no", VTY_NEWLINE
);
1336 vty_out(vty
, " Hello Option - LAN Prune Delay : %s%s", option_lan_prune_delay
? "yes" : "no", VTY_NEWLINE
);
1337 vty_out(vty
, " Hello Option - T-bit : %s%s", option_t_bit
? "yes" : "no", VTY_NEWLINE
);
1338 vty_out(vty
, "%s", VTY_NEWLINE
);
1344 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
1345 json_object_free(json
);
1348 if (!found_neighbor
)
1349 vty_out (vty
, "%% No such interface or neighbor%s", VTY_NEWLINE
);
1355 pim_show_state(struct vty
*vty
, const char *src_or_group
, const char *group
, u_char uj
)
1357 struct channel_oil
*c_oil
;
1358 struct listnode
*node
;
1359 json_object
*json
= NULL
;
1360 json_object
*json_group
= NULL
;
1361 json_object
*json_ifp_in
= NULL
;
1362 json_object
*json_ifp_out
= NULL
;
1363 json_object
*json_source
= NULL
;
1366 now
= pim_time_monotonic_sec();
1369 json
= json_object_new_object();
1371 vty_out(vty
, "%sSource 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
];
1378 char out_ifname
[16];
1380 struct interface
*ifp_in
;
1383 if (!c_oil
->installed
)
1386 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
, sizeof(grp_str
));
1387 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
, sizeof(src_str
));
1388 ifp_in
= pim_if_find_by_vif_index(c_oil
->oil
.mfcc_parent
);
1391 strcpy(in_ifname
, ifp_in
->name
);
1393 strcpy(in_ifname
, "<iif?>");
1397 if (strcmp(src_or_group
, src_str
) && strcmp(src_or_group
, grp_str
))
1400 if (group
&& strcmp(group
, grp_str
))
1406 /* Find the group, create it if it doesn't exist */
1407 json_object_object_get_ex(json
, grp_str
, &json_group
);
1410 json_group
= json_object_new_object();
1411 json_object_object_add(json
, grp_str
, json_group
);
1414 /* Find the source nested under the group, create it if it doesn't exist */
1415 json_object_object_get_ex(json_group
, src_str
, &json_source
);
1418 json_source
= json_object_new_object();
1419 json_object_object_add(json_group
, src_str
, json_source
);
1422 /* Find the inbound interface nested under the source, create it if it doesn't exist */
1423 json_object_object_get_ex(json_source
, in_ifname
, &json_ifp_in
);
1426 json_ifp_in
= json_object_new_object();
1427 json_object_object_add(json_source
, in_ifname
, json_ifp_in
);
1430 vty_out(vty
, "%-15s %-15s %-5s ",
1436 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
; ++oif_vif_index
) {
1437 struct interface
*ifp_out
;
1438 char oif_uptime
[10];
1441 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
1445 ifp_out
= pim_if_find_by_vif_index(oif_vif_index
);
1446 pim_time_uptime(oif_uptime
, sizeof(oif_uptime
), now
- c_oil
->oif_creation
[oif_vif_index
]);
1449 strcpy(out_ifname
, ifp_out
->name
);
1451 strcpy(out_ifname
, "<oif?>");
1454 json_ifp_out
= json_object_new_object();
1455 json_object_string_add(json_ifp_out
, "source", src_str
);
1456 json_object_string_add(json_ifp_out
, "group", grp_str
);
1457 json_object_string_add(json_ifp_out
, "inboundInterface", in_ifname
);
1458 json_object_string_add(json_ifp_out
, "outboundInterface", out_ifname
);
1460 json_object_object_add(json_ifp_in
, out_ifname
, json_ifp_out
);
1465 vty_out(vty
, "%s", out_ifname
);
1468 vty_out(vty
, ",%s", out_ifname
);
1473 vty_out(vty
, "%s", VTY_NEWLINE
);
1478 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
1479 json_object_free(json
);
1481 vty_out(vty
, "%s", VTY_NEWLINE
);
1485 static void pim_show_neighbors(struct vty
*vty
, u_char uj
)
1487 struct listnode
*node
;
1488 struct listnode
*neighnode
;
1489 struct interface
*ifp
;
1490 struct pim_interface
*pim_ifp
;
1491 struct pim_neighbor
*neigh
;
1495 char neigh_src_str
[INET_ADDRSTRLEN
];
1496 json_object
*json
= NULL
;
1497 json_object
*json_ifp_rows
= NULL
;
1498 json_object
*json_row
= NULL
;
1500 now
= pim_time_monotonic_sec();
1503 json
= json_object_new_object();
1505 vty_out(vty
, "Interface Neighbor Uptime Holdtime DR Pri%s", VTY_NEWLINE
);
1508 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
)) {
1509 pim_ifp
= ifp
->info
;
1514 if (pim_ifp
->pim_sock_fd
< 0)
1518 json_ifp_rows
= json_object_new_object();
1520 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
, neigh
)) {
1521 pim_inet4_dump("<src?>", neigh
->source_addr
,
1522 neigh_src_str
, sizeof(neigh_src_str
));
1523 pim_time_uptime(uptime
, sizeof(uptime
), now
- neigh
->creation
);
1524 pim_time_timer_to_hhmmss(expire
, sizeof(expire
), neigh
->t_expire_timer
);
1527 json_row
= json_object_new_object();
1528 json_object_string_add(json_row
, "interface", ifp
->name
);
1529 json_object_string_add(json_row
, "neighbor", neigh_src_str
);
1530 json_object_string_add(json_row
, "upTime", uptime
);
1531 json_object_string_add(json_row
, "holdTime", expire
);
1532 json_object_int_add(json_row
, "holdTimeMax", neigh
->holdtime
);
1533 json_object_int_add(json_row
, "drPriority", neigh
->dr_priority
);
1534 json_object_object_add(json_ifp_rows
, neigh_src_str
, json_row
);
1537 vty_out(vty
, "%-9s %15s %8s %8s %6d%s",
1548 json_object_object_add(json
, ifp
->name
, json_ifp_rows
);
1549 json_ifp_rows
= NULL
;
1554 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
1555 json_object_free(json
);
1559 static void pim_show_neighbors_secondary(struct vty
*vty
)
1561 struct listnode
*node
;
1562 struct interface
*ifp
;
1564 vty_out(vty
, "Interface Address Neighbor Secondary %s", VTY_NEWLINE
);
1566 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
)) {
1567 struct pim_interface
*pim_ifp
;
1568 struct in_addr ifaddr
;
1569 struct listnode
*neighnode
;
1570 struct pim_neighbor
*neigh
;
1572 pim_ifp
= ifp
->info
;
1577 if (pim_ifp
->pim_sock_fd
< 0)
1580 ifaddr
= pim_ifp
->primary_address
;
1582 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
, neigh
)) {
1583 char neigh_src_str
[INET_ADDRSTRLEN
];
1584 struct listnode
*prefix_node
;
1587 if (!neigh
->prefix_list
)
1590 pim_inet4_dump("<src?>", neigh
->source_addr
,
1591 neigh_src_str
, sizeof(neigh_src_str
));
1593 for (ALL_LIST_ELEMENTS_RO(neigh
->prefix_list
, prefix_node
, p
)) {
1594 char neigh_sec_str
[INET_ADDRSTRLEN
];
1596 if (p
->family
!= AF_INET
)
1599 pim_inet4_dump("<src?>", p
->u
.prefix4
,
1600 neigh_sec_str
, sizeof(neigh_sec_str
));
1602 vty_out(vty
, "%-9s %-15s %-15s %-15s%s",
1614 json_object_pim_upstream_add (json_object
*json
, struct pim_upstream
*up
)
1616 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED
)
1617 json_object_boolean_true_add(json
, "drJoinDesired");
1619 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED
)
1620 json_object_boolean_true_add(json
, "drJoinDesiredUpdated");
1622 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
1623 json_object_boolean_true_add(json
, "firstHopRouter");
1625 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_IGMP
)
1626 json_object_boolean_true_add(json
, "sourceIgmp");
1628 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_PIM
)
1629 json_object_boolean_true_add(json
, "sourcePim");
1631 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_STREAM
)
1632 json_object_boolean_true_add(json
, "sourceStream");
1634 /* XXX: need to print ths flag in the plain text display as well */
1635 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_MSDP
)
1636 json_object_boolean_true_add(json
, "sourceMsdp");
1639 static void pim_show_upstream(struct vty
*vty
, u_char uj
)
1641 struct listnode
*upnode
;
1642 struct pim_upstream
*up
;
1644 json_object
*json
= NULL
;
1645 json_object
*json_group
= NULL
;
1646 json_object
*json_row
= NULL
;
1648 now
= pim_time_monotonic_sec();
1651 json
= json_object_new_object();
1653 vty_out(vty
, "Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt%s", VTY_NEWLINE
);
1655 for (ALL_LIST_ELEMENTS_RO(pim_upstream_list
, upnode
, up
)) {
1656 char src_str
[INET_ADDRSTRLEN
];
1657 char grp_str
[INET_ADDRSTRLEN
];
1659 char join_timer
[10];
1662 char msdp_reg_timer
[10];
1664 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
1665 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
1666 pim_time_uptime(uptime
, sizeof(uptime
), now
- up
->state_transition
);
1667 pim_time_timer_to_hhmmss (join_timer
, sizeof(join_timer
), up
->t_join_timer
);
1668 pim_time_timer_to_hhmmss (rs_timer
, sizeof (rs_timer
), up
->t_rs_timer
);
1669 pim_time_timer_to_hhmmss (ka_timer
, sizeof (ka_timer
), up
->t_ka_timer
);
1670 pim_time_timer_to_hhmmss (msdp_reg_timer
, sizeof (msdp_reg_timer
), up
->t_msdp_reg_timer
);
1673 json_object_object_get_ex(json
, grp_str
, &json_group
);
1676 json_group
= json_object_new_object();
1677 json_object_object_add(json
, grp_str
, json_group
);
1680 json_row
= json_object_new_object();
1681 json_object_pim_upstream_add(json_row
, up
);
1682 json_object_string_add(json_row
, "inboundInterface", up
->rpf
.source_nexthop
.interface
->name
);
1683 json_object_string_add(json_row
, "source", src_str
);
1684 json_object_string_add(json_row
, "group", grp_str
);
1685 json_object_string_add(json_row
, "state", pim_upstream_state2str (up
->join_state
));
1686 json_object_string_add(json_row
, "upTime", uptime
);
1687 json_object_string_add(json_row
, "joinTimer", join_timer
);
1688 json_object_string_add(json_row
, "resetTimer", rs_timer
);
1689 json_object_string_add(json_row
, "keepaliveTimer", ka_timer
);
1690 json_object_string_add(json_row
, "msdpRegTimer", msdp_reg_timer
);
1691 json_object_int_add(json_row
, "refCount", up
->ref_count
);
1692 json_object_int_add(json_row
, "sptBit", up
->sptbit
);
1693 json_object_object_add(json_group
, src_str
, json_row
);
1695 vty_out(vty
, "%-10s%-15s %-15s %-11s %-8s %-9s %-9s %-9s %6d%s",
1696 up
->rpf
.source_nexthop
.interface
->name
,
1699 pim_upstream_state2str (up
->join_state
),
1710 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
1711 json_object_free(json
);
1715 static void pim_show_join_desired(struct vty
*vty
, u_char uj
)
1717 struct listnode
*chnode
;
1718 struct pim_interface
*pim_ifp
;
1719 struct pim_ifchannel
*ch
;
1720 char src_str
[INET_ADDRSTRLEN
];
1721 char grp_str
[INET_ADDRSTRLEN
];
1722 json_object
*json
= NULL
;
1723 json_object
*json_group
= NULL
;
1724 json_object
*json_row
= NULL
;
1727 json
= json_object_new_object();
1730 "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD%s",
1733 /* scan per-interface (S,G) state */
1734 for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list
, chnode
, ch
)) {
1735 /* scan all interfaces */
1736 pim_ifp
= ch
->interface
->info
;
1740 struct pim_upstream
*up
= ch
->upstream
;
1742 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
1743 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
1746 json_object_object_get_ex(json
, grp_str
, &json_group
);
1749 json_group
= json_object_new_object();
1750 json_object_object_add(json
, grp_str
, json_group
);
1753 json_row
= json_object_new_object();
1754 json_object_pim_upstream_add(json_row
, up
);
1755 json_object_string_add(json_row
, "interface", ch
->interface
->name
);
1756 json_object_string_add(json_row
, "source", src_str
);
1757 json_object_string_add(json_row
, "group", grp_str
);
1759 if (pim_macro_ch_lost_assert(ch
))
1760 json_object_boolean_true_add(json_row
, "lostAssert");
1762 if (pim_macro_chisin_joins(ch
))
1763 json_object_boolean_true_add(json_row
, "joins");
1765 if (pim_macro_chisin_pim_include(ch
))
1766 json_object_boolean_true_add(json_row
, "pimInclude");
1768 if (pim_upstream_evaluate_join_desired(up
))
1769 json_object_boolean_true_add(json_row
, "evaluateJoinDesired");
1771 json_object_object_add(json_group
, src_str
, json_row
);
1774 vty_out(vty
, "%-9s %-15s %-15s %-10s %-5s %-10s %-11s %-6s%s",
1775 ch
->interface
->name
,
1778 pim_macro_ch_lost_assert(ch
) ? "yes" : "no",
1779 pim_macro_chisin_joins(ch
) ? "yes" : "no",
1780 pim_macro_chisin_pim_include(ch
) ? "yes" : "no",
1781 PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(up
->flags
) ? "yes" : "no",
1782 pim_upstream_evaluate_join_desired(up
) ? "yes" : "no",
1788 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
1789 json_object_free(json
);
1793 static void pim_show_upstream_rpf(struct vty
*vty
, u_char uj
)
1795 struct listnode
*upnode
;
1796 struct pim_upstream
*up
;
1797 json_object
*json
= NULL
;
1798 json_object
*json_group
= NULL
;
1799 json_object
*json_row
= NULL
;
1802 json
= json_object_new_object();
1805 "Source Group RpfIface RibNextHop RpfAddress %s",
1808 for (ALL_LIST_ELEMENTS_RO(pim_upstream_list
, upnode
, up
)) {
1809 char src_str
[INET_ADDRSTRLEN
];
1810 char grp_str
[INET_ADDRSTRLEN
];
1811 char rpf_nexthop_str
[PREFIX_STRLEN
];
1812 char rpf_addr_str
[PREFIX_STRLEN
];
1813 struct pim_rpf
*rpf
;
1814 const char *rpf_ifname
;
1818 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
1819 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
1820 pim_addr_dump("<nexthop?>", &rpf
->source_nexthop
.mrib_nexthop_addr
, rpf_nexthop_str
, sizeof(rpf_nexthop_str
));
1821 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
, sizeof(rpf_addr_str
));
1823 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
1826 json_object_object_get_ex(json
, grp_str
, &json_group
);
1829 json_group
= json_object_new_object();
1830 json_object_object_add(json
, grp_str
, json_group
);
1833 json_row
= json_object_new_object();
1834 json_object_pim_upstream_add(json_row
, up
);
1835 json_object_string_add(json_row
, "source", src_str
);
1836 json_object_string_add(json_row
, "group", grp_str
);
1837 json_object_string_add(json_row
, "rpfInterface", rpf_ifname
);
1838 json_object_string_add(json_row
, "ribNexthop", rpf_nexthop_str
);
1839 json_object_string_add(json_row
, "rpfAddress", rpf_addr_str
);
1840 json_object_object_add(json_group
, src_str
, json_row
);
1842 vty_out(vty
, "%-15s %-15s %-8s %-15s %-15s%s",
1853 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
1854 json_object_free(json
);
1858 static void show_rpf_refresh_stats(struct vty
*vty
, time_t now
, json_object
*json
)
1860 char refresh_uptime
[10];
1862 pim_time_uptime_begin(refresh_uptime
, sizeof(refresh_uptime
), now
, qpim_rpf_cache_refresh_last
);
1865 json_object_int_add(json
, "rpfCacheRefreshDelayMsecs", qpim_rpf_cache_refresh_delay_msec
);
1866 json_object_int_add(json
, "rpfCacheRefreshTimer", pim_time_timer_remain_msec(qpim_rpf_cache_refresher
));
1867 json_object_int_add(json
, "rpfCacheRefreshRequests", qpim_rpf_cache_refresh_requests
);
1868 json_object_int_add(json
, "rpfCacheRefreshEvents", qpim_rpf_cache_refresh_events
);
1869 json_object_string_add(json
, "rpfCacheRefreshLast", refresh_uptime
);
1870 json_object_int_add(json
, "nexthopLookups", qpim_nexthop_lookups
);
1871 json_object_int_add(json
, "nexthopLookupsAvoided", nexthop_lookups_avoided
);
1874 "RPF Cache Refresh Delay: %ld msecs%s"
1875 "RPF Cache Refresh Timer: %ld msecs%s"
1876 "RPF Cache Refresh Requests: %lld%s"
1877 "RPF Cache Refresh Events: %lld%s"
1878 "RPF Cache Refresh Last: %s%s"
1879 "Nexthop Lookups: %lld%s"
1880 "Nexthop Lookups Avoided: %lld%s",
1881 qpim_rpf_cache_refresh_delay_msec
, VTY_NEWLINE
,
1882 pim_time_timer_remain_msec(qpim_rpf_cache_refresher
), VTY_NEWLINE
,
1883 (long long)qpim_rpf_cache_refresh_requests
, VTY_NEWLINE
,
1884 (long long)qpim_rpf_cache_refresh_events
, VTY_NEWLINE
,
1885 refresh_uptime
, VTY_NEWLINE
,
1886 (long long) qpim_nexthop_lookups
, VTY_NEWLINE
,
1887 (long long)nexthop_lookups_avoided
, VTY_NEWLINE
);
1891 static void show_scan_oil_stats(struct vty
*vty
, time_t now
)
1893 char uptime_scan_oil
[10];
1894 char uptime_mroute_add
[10];
1895 char uptime_mroute_del
[10];
1897 pim_time_uptime_begin(uptime_scan_oil
, sizeof(uptime_scan_oil
), now
, qpim_scan_oil_last
);
1898 pim_time_uptime_begin(uptime_mroute_add
, sizeof(uptime_mroute_add
), now
, qpim_mroute_add_last
);
1899 pim_time_uptime_begin(uptime_mroute_del
, sizeof(uptime_mroute_del
), now
, qpim_mroute_del_last
);
1902 "Scan OIL - Last: %s Events: %lld%s"
1903 "MFC Add - Last: %s Events: %lld%s"
1904 "MFC Del - Last: %s Events: %lld%s",
1905 uptime_scan_oil
, (long long) qpim_scan_oil_events
, VTY_NEWLINE
,
1906 uptime_mroute_add
, (long long) qpim_mroute_add_events
, VTY_NEWLINE
,
1907 uptime_mroute_del
, (long long) qpim_mroute_del_events
, VTY_NEWLINE
);
1910 static void pim_show_rpf(struct vty
*vty
, u_char uj
)
1912 struct listnode
*up_node
;
1913 struct pim_upstream
*up
;
1914 time_t now
= pim_time_monotonic_sec();
1915 json_object
*json
= NULL
;
1916 json_object
*json_group
= NULL
;
1917 json_object
*json_row
= NULL
;
1920 json
= json_object_new_object();
1921 show_rpf_refresh_stats(vty
, now
, json
);
1923 show_rpf_refresh_stats(vty
, now
, json
);
1924 vty_out(vty
, "%s", VTY_NEWLINE
);
1926 "Source Group RpfIface RpfAddress RibNextHop Metric Pref%s",
1930 for (ALL_LIST_ELEMENTS_RO(pim_upstream_list
, up_node
, up
)) {
1931 char src_str
[INET_ADDRSTRLEN
];
1932 char grp_str
[INET_ADDRSTRLEN
];
1933 char rpf_addr_str
[PREFIX_STRLEN
];
1934 char rib_nexthop_str
[PREFIX_STRLEN
];
1935 const char *rpf_ifname
;
1936 struct pim_rpf
*rpf
= &up
->rpf
;
1938 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
1939 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
1940 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
, sizeof(rpf_addr_str
));
1941 pim_addr_dump("<nexthop?>", &rpf
->source_nexthop
.mrib_nexthop_addr
, rib_nexthop_str
, sizeof(rib_nexthop_str
));
1943 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
1946 json_object_object_get_ex(json
, grp_str
, &json_group
);
1949 json_group
= json_object_new_object();
1950 json_object_object_add(json
, grp_str
, json_group
);
1953 json_row
= json_object_new_object();
1954 json_object_string_add(json_row
, "source", src_str
);
1955 json_object_string_add(json_row
, "group", grp_str
);
1956 json_object_string_add(json_row
, "rpfInterface", rpf_ifname
);
1957 json_object_string_add(json_row
, "rpfAddress", rpf_addr_str
);
1958 json_object_string_add(json_row
, "ribNexthop", rib_nexthop_str
);
1959 json_object_int_add(json_row
, "routeMetric", rpf
->source_nexthop
.mrib_route_metric
);
1960 json_object_int_add(json_row
, "routePreference", rpf
->source_nexthop
.mrib_metric_preference
);
1961 json_object_object_add(json_group
, src_str
, json_row
);
1964 vty_out(vty
, "%-15s %-15s %-8s %-15s %-15s %6d %4d%s",
1970 rpf
->source_nexthop
.mrib_route_metric
,
1971 rpf
->source_nexthop
.mrib_metric_preference
,
1977 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
1978 json_object_free(json
);
1982 static void igmp_show_groups(struct vty
*vty
, u_char uj
)
1984 struct listnode
*ifnode
;
1985 struct interface
*ifp
;
1987 json_object
*json
= NULL
;
1988 json_object
*json_iface
= NULL
;
1989 json_object
*json_row
= NULL
;
1991 now
= pim_time_monotonic_sec();
1994 json
= json_object_new_object();
1996 vty_out(vty
, "Interface Address Group Mode Timer Srcs V Uptime %s", VTY_NEWLINE
);
1998 /* scan interfaces */
1999 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), ifnode
, ifp
)) {
2000 struct pim_interface
*pim_ifp
= ifp
->info
;
2001 struct listnode
*sock_node
;
2002 struct igmp_sock
*igmp
;
2007 /* scan igmp sockets */
2008 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
2009 char ifaddr_str
[INET_ADDRSTRLEN
];
2010 struct listnode
*grpnode
;
2011 struct igmp_group
*grp
;
2013 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
, sizeof(ifaddr_str
));
2015 /* scan igmp groups */
2016 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grpnode
, grp
)) {
2017 char group_str
[INET_ADDRSTRLEN
];
2021 pim_inet4_dump("<group?>", grp
->group_addr
, group_str
, sizeof(group_str
));
2022 pim_time_timer_to_hhmmss(hhmmss
, sizeof(hhmmss
), grp
->t_group_timer
);
2023 pim_time_uptime(uptime
, sizeof(uptime
), now
- grp
->group_creation
);
2026 json_object_object_get_ex(json
, ifp
->name
, &json_iface
);
2029 json_iface
= json_object_new_object();
2030 json_object_pim_ifp_add(json_iface
, ifp
);
2031 json_object_object_add(json
, ifp
->name
, json_iface
);
2034 json_row
= json_object_new_object();
2035 json_object_string_add(json_row
, "source", ifaddr_str
);
2036 json_object_string_add(json_row
, "group", group_str
);
2038 if (grp
->igmp_version
== 3)
2039 json_object_string_add(json_row
, "mode", grp
->group_filtermode_isexcl
? "EXCLUDE" : "INCLUDE");
2041 json_object_string_add(json_row
, "timer", hhmmss
);
2042 json_object_int_add(json_row
, "sourcesCount", grp
->group_source_list
? listcount(grp
->group_source_list
) : 0);
2043 json_object_int_add(json_row
, "version", grp
->igmp_version
);
2044 json_object_string_add(json_row
, "uptime", uptime
);
2045 json_object_object_add(json_iface
, group_str
, json_row
);
2048 vty_out(vty
, "%-9s %-15s %-15s %4s %8s %4d %d %8s%s",
2052 grp
->igmp_version
== 3 ? (grp
->group_filtermode_isexcl
? "EXCL" : "INCL") : "----",
2054 grp
->group_source_list
? listcount(grp
->group_source_list
) : 0,
2059 } /* scan igmp groups */
2060 } /* scan igmp sockets */
2061 } /* scan interfaces */
2064 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
2065 json_object_free(json
);
2069 static void igmp_show_group_retransmission(struct vty
*vty
)
2071 struct listnode
*ifnode
;
2072 struct interface
*ifp
;
2074 vty_out(vty
, "Interface Address Group RetTimer Counter RetSrcs%s", VTY_NEWLINE
);
2076 /* scan interfaces */
2077 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), ifnode
, ifp
)) {
2078 struct pim_interface
*pim_ifp
= ifp
->info
;
2079 struct listnode
*sock_node
;
2080 struct igmp_sock
*igmp
;
2085 /* scan igmp sockets */
2086 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
2087 char ifaddr_str
[INET_ADDRSTRLEN
];
2088 struct listnode
*grpnode
;
2089 struct igmp_group
*grp
;
2091 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
, sizeof(ifaddr_str
));
2093 /* scan igmp groups */
2094 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grpnode
, grp
)) {
2095 char group_str
[INET_ADDRSTRLEN
];
2096 char grp_retr_mmss
[10];
2097 struct listnode
*src_node
;
2098 struct igmp_source
*src
;
2099 int grp_retr_sources
= 0;
2101 pim_inet4_dump("<group?>", grp
->group_addr
, group_str
, sizeof(group_str
));
2102 pim_time_timer_to_mmss(grp_retr_mmss
, sizeof(grp_retr_mmss
), grp
->t_group_query_retransmit_timer
);
2105 /* count group sources with retransmission state */
2106 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
, src_node
, src
)) {
2107 if (src
->source_query_retransmit_count
> 0) {
2112 vty_out(vty
, "%-9s %-15s %-15s %-8s %7d %7d%s",
2117 grp
->group_specific_query_retransmit_count
,
2121 } /* scan igmp groups */
2122 } /* scan igmp sockets */
2123 } /* scan interfaces */
2126 static void igmp_show_sources(struct vty
*vty
)
2128 struct listnode
*ifnode
;
2129 struct interface
*ifp
;
2132 now
= pim_time_monotonic_sec();
2134 vty_out(vty
, "Interface Address Group Source Timer Fwd Uptime %s", VTY_NEWLINE
);
2136 /* scan interfaces */
2137 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), ifnode
, ifp
)) {
2138 struct pim_interface
*pim_ifp
= ifp
->info
;
2139 struct listnode
*sock_node
;
2140 struct igmp_sock
*igmp
;
2145 /* scan igmp sockets */
2146 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
2147 char ifaddr_str
[INET_ADDRSTRLEN
];
2148 struct listnode
*grpnode
;
2149 struct igmp_group
*grp
;
2151 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
, sizeof(ifaddr_str
));
2153 /* scan igmp groups */
2154 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grpnode
, grp
)) {
2155 char group_str
[INET_ADDRSTRLEN
];
2156 struct listnode
*srcnode
;
2157 struct igmp_source
*src
;
2159 pim_inet4_dump("<group?>", grp
->group_addr
, group_str
, sizeof(group_str
));
2161 /* scan group sources */
2162 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
, srcnode
, src
)) {
2163 char source_str
[INET_ADDRSTRLEN
];
2167 pim_inet4_dump("<source?>", src
->source_addr
, source_str
, sizeof(source_str
));
2169 pim_time_timer_to_mmss(mmss
, sizeof(mmss
), src
->t_source_timer
);
2171 pim_time_uptime(uptime
, sizeof(uptime
), now
- src
->source_creation
);
2173 vty_out(vty
, "%-9s %-15s %-15s %-15s %5s %3s %8s%s",
2179 IGMP_SOURCE_TEST_FORWARDING(src
->source_flags
) ? "Y" : "N",
2183 } /* scan group sources */
2184 } /* scan igmp groups */
2185 } /* scan igmp sockets */
2186 } /* scan interfaces */
2189 static void igmp_show_source_retransmission(struct vty
*vty
)
2191 struct listnode
*ifnode
;
2192 struct interface
*ifp
;
2194 vty_out(vty
, "Interface Address Group Source Counter%s", VTY_NEWLINE
);
2196 /* scan interfaces */
2197 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), ifnode
, ifp
)) {
2198 struct pim_interface
*pim_ifp
= ifp
->info
;
2199 struct listnode
*sock_node
;
2200 struct igmp_sock
*igmp
;
2205 /* scan igmp sockets */
2206 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
2207 char ifaddr_str
[INET_ADDRSTRLEN
];
2208 struct listnode
*grpnode
;
2209 struct igmp_group
*grp
;
2211 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
, sizeof(ifaddr_str
));
2213 /* scan igmp groups */
2214 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grpnode
, grp
)) {
2215 char group_str
[INET_ADDRSTRLEN
];
2216 struct listnode
*srcnode
;
2217 struct igmp_source
*src
;
2219 pim_inet4_dump("<group?>", grp
->group_addr
, group_str
, sizeof(group_str
));
2221 /* scan group sources */
2222 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
, srcnode
, src
)) {
2223 char source_str
[INET_ADDRSTRLEN
];
2225 pim_inet4_dump("<source?>", src
->source_addr
, source_str
, sizeof(source_str
));
2227 vty_out(vty
, "%-9s %-15s %-15s %-15s %7d%s",
2232 src
->source_query_retransmit_count
,
2235 } /* scan group sources */
2236 } /* scan igmp groups */
2237 } /* scan igmp sockets */
2238 } /* scan interfaces */
2241 static void clear_igmp_interfaces()
2243 struct listnode
*ifnode
;
2244 struct listnode
*ifnextnode
;
2245 struct interface
*ifp
;
2247 for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT
), ifnode
, ifnextnode
, ifp
)) {
2248 pim_if_addr_del_all_igmp(ifp
);
2251 for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT
), ifnode
, ifnextnode
, ifp
)) {
2252 pim_if_addr_add_all(ifp
);
2256 static void clear_pim_interfaces()
2258 struct listnode
*ifnode
;
2259 struct listnode
*ifnextnode
;
2260 struct interface
*ifp
;
2262 for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT
), ifnode
, ifnextnode
, ifp
)) {
2264 pim_neighbor_delete_all(ifp
, "interface cleared");
2269 static void clear_interfaces()
2271 clear_igmp_interfaces();
2272 clear_pim_interfaces();
2275 DEFUN (clear_ip_interfaces
,
2276 clear_ip_interfaces_cmd
,
2277 "clear ip interfaces",
2280 "Reset interfaces\n")
2287 DEFUN (clear_ip_igmp_interfaces
,
2288 clear_ip_igmp_interfaces_cmd
,
2289 "clear ip igmp interfaces",
2293 "Reset IGMP interfaces\n")
2295 clear_igmp_interfaces();
2300 static void mroute_add_all()
2302 struct listnode
*node
;
2303 struct channel_oil
*c_oil
;
2305 for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list
, node
, c_oil
)) {
2306 if (pim_mroute_add(c_oil
, __PRETTY_FUNCTION__
)) {
2307 /* just log warning */
2308 char source_str
[INET_ADDRSTRLEN
];
2309 char group_str
[INET_ADDRSTRLEN
];
2310 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, source_str
, sizeof(source_str
));
2311 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, group_str
, sizeof(group_str
));
2312 zlog_warn("%s %s: (S,G)=(%s,%s) failure writing MFC",
2313 __FILE__
, __PRETTY_FUNCTION__
,
2314 source_str
, group_str
);
2319 static void mroute_del_all()
2321 struct listnode
*node
;
2322 struct channel_oil
*c_oil
;
2324 for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list
, node
, c_oil
)) {
2325 if (pim_mroute_del(c_oil
, __PRETTY_FUNCTION__
)) {
2326 /* just log warning */
2327 char source_str
[INET_ADDRSTRLEN
];
2328 char group_str
[INET_ADDRSTRLEN
];
2329 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, source_str
, sizeof(source_str
));
2330 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, group_str
, sizeof(group_str
));
2331 zlog_warn("%s %s: (S,G)=(%s,%s) failure clearing MFC",
2332 __FILE__
, __PRETTY_FUNCTION__
,
2333 source_str
, group_str
);
2338 static void static_mroute_add_all()
2340 struct listnode
*node
;
2341 struct static_route
*s_route
;
2343 for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list
, node
, s_route
)) {
2344 if (pim_mroute_add(&s_route
->c_oil
, __PRETTY_FUNCTION__
)) {
2345 /* just log warning */
2346 char source_str
[INET_ADDRSTRLEN
];
2347 char group_str
[INET_ADDRSTRLEN
];
2348 pim_inet4_dump("<source?>", s_route
->c_oil
.oil
.mfcc_origin
, source_str
, sizeof(source_str
));
2349 pim_inet4_dump("<group?>", s_route
->c_oil
.oil
.mfcc_mcastgrp
, group_str
, sizeof(group_str
));
2350 zlog_warn("%s %s: (S,G)=(%s,%s) failure writing MFC",
2351 __FILE__
, __PRETTY_FUNCTION__
,
2352 source_str
, group_str
);
2357 static void static_mroute_del_all()
2359 struct listnode
*node
;
2360 struct static_route
*s_route
;
2362 for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list
, node
, s_route
)) {
2363 if (pim_mroute_del(&s_route
->c_oil
, __PRETTY_FUNCTION__
)) {
2364 /* just log warning */
2365 char source_str
[INET_ADDRSTRLEN
];
2366 char group_str
[INET_ADDRSTRLEN
];
2367 pim_inet4_dump("<source?>", s_route
->c_oil
.oil
.mfcc_origin
, source_str
, sizeof(source_str
));
2368 pim_inet4_dump("<group?>", s_route
->c_oil
.oil
.mfcc_mcastgrp
, group_str
, sizeof(group_str
));
2369 zlog_warn("%s %s: (S,G)=(%s,%s) failure clearing MFC",
2370 __FILE__
, __PRETTY_FUNCTION__
,
2371 source_str
, group_str
);
2376 DEFUN (clear_ip_mroute
,
2377 clear_ip_mroute_cmd
,
2381 "Reset multicast routes\n")
2389 DEFUN (clear_ip_pim_interfaces
,
2390 clear_ip_pim_interfaces_cmd
,
2391 "clear ip pim interfaces",
2395 "Reset PIM interfaces\n")
2397 clear_pim_interfaces();
2402 DEFUN (clear_ip_pim_oil
,
2403 clear_ip_pim_oil_cmd
,
2408 "Rescan PIM OIL (output interface list)\n")
2415 DEFUN (show_ip_igmp_interface
,
2416 show_ip_igmp_interface_cmd
,
2417 "show ip igmp interface [detail|WORD] [json]",
2421 "IGMP interface information\n"
2424 "JavaScript Object Notation\n")
2426 u_char uj
= use_json(argc
, argv
);
2428 igmp_show_interfaces_single(vty
, argv
[4]->arg
, uj
);
2430 igmp_show_interfaces(vty
, uj
);
2435 DEFUN (show_ip_igmp_join
,
2436 show_ip_igmp_join_cmd
,
2437 "show ip igmp join",
2441 "IGMP static join information\n")
2443 igmp_show_interface_join(vty
);
2448 DEFUN (show_ip_igmp_groups
,
2449 show_ip_igmp_groups_cmd
,
2450 "show ip igmp groups [json]",
2455 "JavaScript Object Notation\n")
2457 u_char uj
= use_json(argc
, argv
);
2458 igmp_show_groups(vty
, uj
);
2463 DEFUN (show_ip_igmp_groups_retransmissions
,
2464 show_ip_igmp_groups_retransmissions_cmd
,
2465 "show ip igmp groups retransmissions",
2470 "IGMP group retransmissions\n")
2472 igmp_show_group_retransmission(vty
);
2477 DEFUN (show_ip_igmp_sources
,
2478 show_ip_igmp_sources_cmd
,
2479 "show ip igmp sources",
2485 igmp_show_sources(vty
);
2490 DEFUN (show_ip_igmp_sources_retransmissions
,
2491 show_ip_igmp_sources_retransmissions_cmd
,
2492 "show ip igmp sources retransmissions",
2497 "IGMP source retransmissions\n")
2499 igmp_show_source_retransmission(vty
);
2504 DEFUN (show_ip_pim_assert
,
2505 show_ip_pim_assert_cmd
,
2506 "show ip pim assert",
2510 "PIM interface assert\n")
2512 pim_show_assert(vty
);
2517 DEFUN (show_ip_pim_assert_internal
,
2518 show_ip_pim_assert_internal_cmd
,
2519 "show ip pim assert-internal",
2523 "PIM interface internal assert state\n")
2525 pim_show_assert_internal(vty
);
2530 DEFUN (show_ip_pim_assert_metric
,
2531 show_ip_pim_assert_metric_cmd
,
2532 "show ip pim assert-metric",
2536 "PIM interface assert metric\n")
2538 pim_show_assert_metric(vty
);
2543 DEFUN (show_ip_pim_assert_winner_metric
,
2544 show_ip_pim_assert_winner_metric_cmd
,
2545 "show ip pim assert-winner-metric",
2549 "PIM interface assert winner metric\n")
2551 pim_show_assert_winner_metric(vty
);
2556 DEFUN (show_ip_pim_dr
,
2558 "show ip pim designated-router [json]",
2562 "PIM interface designated router\n")
2564 u_char uj
= use_json(argc
, argv
);
2565 pim_show_dr(vty
, uj
);
2570 DEFUN (show_ip_pim_hello
,
2571 show_ip_pim_hello_cmd
,
2572 "show ip pim hello [json]",
2576 "PIM interface hello information\n")
2578 u_char uj
= use_json(argc
, argv
);
2579 pim_show_hello(vty
, uj
);
2584 DEFUN (show_ip_pim_interface
,
2585 show_ip_pim_interface_cmd
,
2586 "show ip pim interface [detail|WORD] [json]",
2590 "PIM interface information\n"
2593 "JavaScript Object Notation\n")
2595 u_char uj
= use_json(argc
, argv
);
2597 pim_show_interfaces_single(vty
, argv
[4]->arg
, uj
);
2599 pim_show_interfaces(vty
, uj
);
2604 DEFUN (show_ip_pim_join
,
2605 show_ip_pim_join_cmd
,
2606 "show ip pim join [json]",
2610 "PIM interface join information\n")
2612 u_char uj
= use_json(argc
, argv
);
2613 pim_show_join(vty
, uj
);
2618 DEFUN (show_ip_pim_local_membership
,
2619 show_ip_pim_local_membership_cmd
,
2620 "show ip pim local-membership [json]",
2624 "PIM interface local-membership\n")
2626 u_char uj
= use_json(argc
, argv
);
2627 pim_show_membership(vty
, uj
);
2632 DEFUN (show_ip_pim_neighbor
,
2633 show_ip_pim_neighbor_cmd
,
2634 "show ip pim neighbor [detail|WORD] [json]",
2638 "PIM neighbor information\n"
2640 "Name of interface or neighbor\n"
2641 "JavaScript Object Notation\n")
2643 u_char uj
= use_json(argc
, argv
);
2645 pim_show_neighbors_single(vty
, argv
[4]->arg
, uj
);
2647 pim_show_neighbors(vty
, uj
);
2652 DEFUN (show_ip_pim_secondary
,
2653 show_ip_pim_secondary_cmd
,
2654 "show ip pim secondary",
2658 "PIM neighbor addresses\n")
2660 pim_show_neighbors_secondary(vty
);
2665 DEFUN (show_ip_pim_state
,
2666 show_ip_pim_state_cmd
,
2667 "show ip pim state [A.B.C.D] [A.B.C.D] [json]",
2671 "PIM state information\n"
2672 "Unicast or Multicast address\n"
2673 "Multicast address\n"
2674 "JavaScript Object Notation\n")
2676 const char *src_or_group
= NULL
;
2677 const char *group
= NULL
;
2678 u_char uj
= use_json(argc
, argv
);
2680 src_or_group
= argv
[4]->arg
;
2681 group
= argv
[5]->arg
;
2683 pim_show_state(vty
, src_or_group
, group
, uj
);
2688 DEFUN (show_ip_pim_upstream
,
2689 show_ip_pim_upstream_cmd
,
2690 "show ip pim upstream [json]",
2694 "PIM upstream information\n"
2695 "JavaScript Object Notation\n")
2697 u_char uj
= use_json(argc
, argv
);
2698 pim_show_upstream(vty
, uj
);
2703 DEFUN (show_ip_pim_upstream_join_desired
,
2704 show_ip_pim_upstream_join_desired_cmd
,
2705 "show ip pim upstream-join-desired [json]",
2709 "PIM upstream join-desired\n"
2710 "JavaScript Object Notation\n")
2712 u_char uj
= use_json(argc
, argv
);
2713 pim_show_join_desired(vty
, uj
);
2718 DEFUN (show_ip_pim_upstream_rpf
,
2719 show_ip_pim_upstream_rpf_cmd
,
2720 "show ip pim upstream-rpf [json]",
2724 "PIM upstream source rpf\n"
2725 "JavaScript Object Notation\n")
2727 u_char uj
= use_json(argc
, argv
);
2728 pim_show_upstream_rpf(vty
, uj
);
2733 DEFUN (show_ip_pim_rp
,
2735 "show ip pim rp-info [json]",
2739 "PIM RP information\n"
2740 "JavaScript Object Notation\n")
2742 u_char uj
= use_json(argc
, argv
);
2743 pim_rp_show_information (vty
, uj
);
2748 DEFUN (show_ip_pim_rpf
,
2749 show_ip_pim_rpf_cmd
,
2750 "show ip pim rpf [json]",
2754 "PIM cached source rpf information\n"
2755 "JavaScript Object Notation\n")
2757 u_char uj
= use_json(argc
, argv
);
2758 pim_show_rpf(vty
, uj
);
2763 static void show_multicast_interfaces(struct vty
*vty
)
2765 struct listnode
*node
;
2766 struct interface
*ifp
;
2768 vty_out(vty
, "%s", VTY_NEWLINE
);
2770 vty_out(vty
, "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut%s",
2773 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
)) {
2774 struct pim_interface
*pim_ifp
;
2775 struct in_addr ifaddr
;
2776 struct sioc_vif_req vreq
;
2778 pim_ifp
= ifp
->info
;
2783 memset(&vreq
, 0, sizeof(vreq
));
2784 vreq
.vifi
= pim_ifp
->mroute_vif_index
;
2786 if (ioctl(qpim_mroute_socket_fd
, SIOCGETVIFCNT
, &vreq
)) {
2787 zlog_warn("ioctl(SIOCGETVIFCNT=%lu) failure for interface %s vif_index=%d: errno=%d: %s%s",
2788 (unsigned long)SIOCGETVIFCNT
,
2790 pim_ifp
->mroute_vif_index
,
2792 safe_strerror(errno
),
2796 ifaddr
= pim_ifp
->primary_address
;
2798 vty_out(vty
, "%-9s %-15s %3d %3d %7lu %7lu %10lu %10lu%s",
2802 pim_ifp
->mroute_vif_index
,
2803 (unsigned long) vreq
.icount
,
2804 (unsigned long) vreq
.ocount
,
2805 (unsigned long) vreq
.ibytes
,
2806 (unsigned long) vreq
.obytes
,
2811 DEFUN (show_ip_multicast
,
2812 show_ip_multicast_cmd
,
2813 "show ip multicast",
2816 "Multicast global information\n")
2818 time_t now
= pim_time_monotonic_sec();
2820 if (PIM_MROUTE_IS_ENABLED
) {
2823 vty_out(vty
, "Mroute socket descriptor: %d%s",
2824 qpim_mroute_socket_fd
,
2827 pim_time_uptime(uptime
, sizeof(uptime
), now
- qpim_mroute_socket_creation
);
2828 vty_out(vty
, "Mroute socket uptime: %s%s",
2833 vty_out(vty
, "Multicast disabled%s",
2837 vty_out(vty
, "%s", VTY_NEWLINE
);
2838 vty_out(vty
, "Zclient update socket: ");
2839 if (qpim_zclient_update
) {
2840 vty_out(vty
, "%d failures=%d%s", qpim_zclient_update
->sock
,
2841 qpim_zclient_update
->fail
, VTY_NEWLINE
);
2844 vty_out(vty
, "<null zclient>%s", VTY_NEWLINE
);
2847 pim_zlookup_show_ip_multicast (vty
);
2849 vty_out(vty
, "%s", VTY_NEWLINE
);
2850 vty_out(vty
, "Current highest VifIndex: %d%s",
2851 qpim_mroute_oif_highest_vif_index
,
2853 vty_out(vty
, "Maximum highest VifIndex: %d%s",
2854 PIM_MAX_USABLE_VIFS
,
2857 vty_out(vty
, "%s", VTY_NEWLINE
);
2858 vty_out(vty
, "Upstream Join Timer: %d secs%s",
2861 vty_out(vty
, "Join/Prune Holdtime: %d secs%s",
2865 vty_out(vty
, "%s", VTY_NEWLINE
);
2867 show_rpf_refresh_stats(vty
, now
, NULL
);
2869 vty_out(vty
, "%s", VTY_NEWLINE
);
2871 show_scan_oil_stats(vty
, now
);
2873 show_multicast_interfaces(vty
);
2878 static void show_mroute(struct vty
*vty
, u_char uj
)
2880 struct listnode
*node
;
2881 struct channel_oil
*c_oil
;
2882 struct static_route
*s_route
;
2884 json_object
*json
= NULL
;
2885 json_object
*json_group
= NULL
;
2886 json_object
*json_source
= NULL
;
2887 json_object
*json_oil
= NULL
;
2888 json_object
*json_ifp_out
= NULL
;
2893 json
= json_object_new_object();
2895 vty_out(vty
, "Source Group Proto Input Output TTL Uptime%s",
2899 now
= pim_time_monotonic_sec();
2901 /* print list of PIM and IGMP routes */
2902 for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list
, node
, c_oil
)) {
2903 char grp_str
[INET_ADDRSTRLEN
];
2904 char src_str
[INET_ADDRSTRLEN
];
2906 char out_ifname
[16];
2909 struct interface
*ifp_in
;
2912 if (!c_oil
->installed
&& !uj
)
2915 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
, sizeof(grp_str
));
2916 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
, sizeof(src_str
));
2917 ifp_in
= pim_if_find_by_vif_index(c_oil
->oil
.mfcc_parent
);
2920 strcpy(in_ifname
, ifp_in
->name
);
2922 strcpy(in_ifname
, "<iif?>");
2926 /* Find the group, create it if it doesn't exist */
2927 json_object_object_get_ex(json
, grp_str
, &json_group
);
2930 json_group
= json_object_new_object();
2931 json_object_object_add(json
, grp_str
, json_group
);
2934 /* Find the source nested under the group, create it if it doesn't exist */
2935 json_object_object_get_ex(json_group
, src_str
, &json_source
);
2938 json_source
= json_object_new_object();
2939 json_object_object_add(json_group
, src_str
, json_source
);
2942 /* Find the inbound interface nested under the source, create it if it doesn't exist */
2943 json_object_int_add(json_source
, "installed", c_oil
->installed
);
2944 json_object_int_add(json_source
, "refCount", c_oil
->oil_ref_count
);
2945 json_object_int_add(json_source
, "oilSize", c_oil
->oil_size
);
2946 json_object_int_add(json_source
, "OilInheritedRescan", c_oil
->oil_inherited_rescan
);
2947 json_object_string_add(json_source
, "iif", in_ifname
);
2951 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
; ++oif_vif_index
) {
2952 struct interface
*ifp_out
;
2953 char oif_uptime
[10];
2956 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
2960 ifp_out
= pim_if_find_by_vif_index(oif_vif_index
);
2961 pim_time_uptime(oif_uptime
, sizeof(oif_uptime
), now
- c_oil
->oif_creation
[oif_vif_index
]);
2965 strcpy(out_ifname
, ifp_out
->name
);
2967 strcpy(out_ifname
, "<oif?>");
2970 json_ifp_out
= json_object_new_object();
2971 json_object_string_add(json_ifp_out
, "source", src_str
);
2972 json_object_string_add(json_ifp_out
, "group", grp_str
);
2974 if (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_PIM
)
2975 json_object_boolean_true_add(json_ifp_out
, "protocolPim");
2977 if (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_IGMP
)
2978 json_object_boolean_true_add(json_ifp_out
, "protocolIgmp");
2980 if (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_SOURCE
)
2981 json_object_boolean_true_add(json_ifp_out
, "protocolSource");
2983 json_object_string_add(json_ifp_out
, "inboundInterface", in_ifname
);
2984 json_object_int_add(json_ifp_out
, "iVifI", c_oil
->oil
.mfcc_parent
);
2985 json_object_string_add(json_ifp_out
, "outboundInterface", out_ifname
);
2986 json_object_int_add(json_ifp_out
, "oVifI", oif_vif_index
);
2987 json_object_int_add(json_ifp_out
, "ttl", ttl
);
2988 json_object_string_add(json_ifp_out
, "upTime", oif_uptime
);
2990 json_oil
= json_object_new_object();
2991 json_object_object_add(json_source
, "oil", json_oil
);
2993 json_object_object_add(json_oil
, out_ifname
, json_ifp_out
);
2995 if (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_PIM
) {
2996 strcpy(proto
, "PIM");
2999 if (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_IGMP
) {
3000 strcpy(proto
, "IGMP");
3003 if (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_SOURCE
) {
3004 strcpy(proto
, "SRC");
3007 vty_out(vty
, "%-15s %-15s %-6s %-10s %-10s %-3d %8s%s",
3021 in_ifname
[0] = '\0';
3027 if (!uj
&& !found_oif
) {
3028 vty_out(vty
, "%-15s %-15s %-6s %-10s %-10s %-3d %8s%s",
3040 /* Print list of static routes */
3041 for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list
, node
, s_route
)) {
3042 char grp_str
[INET_ADDRSTRLEN
];
3043 char src_str
[INET_ADDRSTRLEN
];
3045 char out_ifname
[16];
3047 struct interface
*ifp_in
;
3051 if (!s_route
->c_oil
.installed
)
3054 pim_inet4_dump("<group?>", s_route
->group
, grp_str
, sizeof(grp_str
));
3055 pim_inet4_dump("<source?>", s_route
->source
, src_str
, sizeof(src_str
));
3056 ifp_in
= pim_if_find_by_vif_index(s_route
->iif
);
3060 strcpy(in_ifname
, ifp_in
->name
);
3062 strcpy(in_ifname
, "<iif?>");
3066 /* Find the group, create it if it doesn't exist */
3067 json_object_object_get_ex(json
, grp_str
, &json_group
);
3070 json_group
= json_object_new_object();
3071 json_object_object_add(json
, grp_str
, json_group
);
3074 /* Find the source nested under the group, create it if it doesn't exist */
3075 json_object_object_get_ex(json_group
, src_str
, &json_source
);
3078 json_source
= json_object_new_object();
3079 json_object_object_add(json_group
, src_str
, json_source
);
3082 json_object_string_add(json_source
, "iif", in_ifname
);
3085 strcpy(proto
, "STATIC");
3088 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
; ++oif_vif_index
) {
3089 struct interface
*ifp_out
;
3090 char oif_uptime
[10];
3093 ttl
= s_route
->oif_ttls
[oif_vif_index
];
3097 ifp_out
= pim_if_find_by_vif_index(oif_vif_index
);
3098 pim_time_uptime(oif_uptime
, sizeof(oif_uptime
), now
- s_route
->c_oil
.oif_creation
[oif_vif_index
]);
3102 strcpy(out_ifname
, ifp_out
->name
);
3104 strcpy(out_ifname
, "<oif?>");
3107 json_ifp_out
= json_object_new_object();
3108 json_object_string_add(json_ifp_out
, "source", src_str
);
3109 json_object_string_add(json_ifp_out
, "group", grp_str
);
3110 json_object_boolean_true_add(json_ifp_out
, "protocolStatic");
3111 json_object_string_add(json_ifp_out
, "inboundInterface", in_ifname
);
3112 json_object_int_add(json_ifp_out
, "iVifI", c_oil
->oil
.mfcc_parent
);
3113 json_object_string_add(json_ifp_out
, "outboundInterface", out_ifname
);
3114 json_object_int_add(json_ifp_out
, "oVifI", oif_vif_index
);
3115 json_object_int_add(json_ifp_out
, "ttl", ttl
);
3116 json_object_string_add(json_ifp_out
, "upTime", oif_uptime
);
3118 json_oil
= json_object_new_object();
3119 json_object_object_add(json_source
, "oil", json_oil
);
3121 json_object_object_add(json_oil
, out_ifname
, json_ifp_out
);
3123 vty_out(vty
, "%-15s %-15s %-6s %-10s %-10s %-3d %8s%s",
3136 in_ifname
[0] = '\0';
3142 if (!uj
&& !found_oif
) {
3143 vty_out(vty
, "%-15s %-15s %-6s %-10s %-10s %-3d %8s%s",
3156 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
3157 json_object_free(json
);
3161 DEFUN (show_ip_mroute
,
3163 "show ip mroute [json]",
3168 u_char uj
= use_json(argc
, argv
);
3169 show_mroute(vty
, uj
);
3173 static void show_mroute_count(struct vty
*vty
)
3175 struct listnode
*node
;
3176 struct channel_oil
*c_oil
;
3177 struct static_route
*s_route
;
3179 vty_out(vty
, "%s", VTY_NEWLINE
);
3181 vty_out(vty
, "Source Group LastUsed Packets Bytes WrongIf %s",
3184 /* Print PIM and IGMP route counts */
3185 for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list
, node
, c_oil
)) {
3186 char group_str
[INET_ADDRSTRLEN
];
3187 char source_str
[INET_ADDRSTRLEN
];
3189 if (!c_oil
->installed
)
3192 pim_mroute_update_counters (c_oil
);
3194 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, group_str
, sizeof(group_str
));
3195 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, source_str
, sizeof(source_str
));
3197 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld%s",
3200 c_oil
->cc
.lastused
/100,
3207 /* Print static route counts */
3208 for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list
, node
, s_route
)) {
3209 char group_str
[INET_ADDRSTRLEN
];
3210 char source_str
[INET_ADDRSTRLEN
];
3212 if (!s_route
->c_oil
.installed
)
3215 pim_mroute_update_counters (&s_route
->c_oil
);
3217 pim_inet4_dump("<group?>", s_route
->c_oil
.oil
.mfcc_mcastgrp
, group_str
, sizeof(group_str
));
3218 pim_inet4_dump("<source?>", s_route
->c_oil
.oil
.mfcc_origin
, source_str
, sizeof(source_str
));
3220 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld%s",
3223 s_route
->c_oil
.cc
.lastused
,
3224 s_route
->c_oil
.cc
.pktcnt
,
3225 s_route
->c_oil
.cc
.bytecnt
,
3226 s_route
->c_oil
.cc
.wrong_if
,
3231 DEFUN (show_ip_mroute_count
,
3232 show_ip_mroute_count_cmd
,
3233 "show ip mroute count",
3237 "Route and packet count data\n")
3239 show_mroute_count(vty
);
3245 "show ip rib A.B.C.D",
3249 "Unicast address\n")
3252 struct in_addr addr
;
3253 const char *addr_str
;
3254 struct pim_nexthop nexthop
;
3255 char nexthop_addr_str
[PREFIX_STRLEN
];
3258 memset (&nexthop
, 0, sizeof (nexthop
));
3259 addr_str
= argv
[idx_ipv4
]->arg
;
3260 result
= inet_pton(AF_INET
, addr_str
, &addr
);
3262 vty_out(vty
, "Bad unicast address %s: errno=%d: %s%s",
3263 addr_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
3267 if (pim_nexthop_lookup(&nexthop
, addr
, 0)) {
3268 vty_out(vty
, "Failure querying RIB nexthop for unicast address %s%s",
3269 addr_str
, VTY_NEWLINE
);
3273 vty_out(vty
, "Address NextHop Interface Metric Preference%s",
3276 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
3277 nexthop_addr_str
, sizeof(nexthop_addr_str
));
3279 vty_out(vty
, "%-15s %-15s %-9s %6d %10d%s",
3282 nexthop
.interface
? nexthop
.interface
->name
: "<ifname?>",
3283 nexthop
.mrib_route_metric
,
3284 nexthop
.mrib_metric_preference
,
3290 static void show_ssmpingd(struct vty
*vty
)
3292 struct listnode
*node
;
3293 struct ssmpingd_sock
*ss
;
3296 vty_out(vty
, "Source Socket Address Port Uptime Requests%s",
3299 if (!qpim_ssmpingd_list
)
3302 now
= pim_time_monotonic_sec();
3304 for (ALL_LIST_ELEMENTS_RO(qpim_ssmpingd_list
, node
, ss
)) {
3305 char source_str
[INET_ADDRSTRLEN
];
3307 struct sockaddr_in bind_addr
;
3308 socklen_t len
= sizeof(bind_addr
);
3309 char bind_addr_str
[INET_ADDRSTRLEN
];
3311 pim_inet4_dump("<src?>", ss
->source_addr
, source_str
, sizeof(source_str
));
3313 if (pim_socket_getsockname(ss
->sock_fd
, (struct sockaddr
*) &bind_addr
, &len
)) {
3314 vty_out(vty
, "%% Failure reading socket name for ssmpingd source %s on fd=%d%s",
3315 source_str
, ss
->sock_fd
, VTY_NEWLINE
);
3318 pim_inet4_dump("<addr?>", bind_addr
.sin_addr
, bind_addr_str
, sizeof(bind_addr_str
));
3319 pim_time_uptime(ss_uptime
, sizeof(ss_uptime
), now
- ss
->creation
);
3321 vty_out(vty
, "%-15s %6d %-15s %5d %8s %8lld%s",
3325 ntohs(bind_addr
.sin_port
),
3327 (long long)ss
->requests
,
3332 DEFUN (show_ip_ssmpingd
,
3333 show_ip_ssmpingd_cmd
,
3344 pim_rp_cmd_worker (struct vty
*vty
, const char *rp
, const char *group
, const char *plist
)
3348 result
= pim_rp_new (rp
, group
, plist
);
3350 if (result
== PIM_MALLOC_FAIL
)
3352 vty_out (vty
, "%% Out of memory%s", VTY_NEWLINE
);
3356 if (result
== PIM_GROUP_BAD_ADDRESS
)
3358 vty_out (vty
, "%% Bad group address specified: %s%s", group
, VTY_NEWLINE
);
3362 if (result
== PIM_RP_BAD_ADDRESS
)
3364 vty_out (vty
, "%% Bad RP address specified: %s%s", rp
, VTY_NEWLINE
);
3368 if (result
== PIM_RP_NO_PATH
)
3370 vty_out (vty
, "%% No Path to RP address specified: %s%s", rp
, VTY_NEWLINE
);
3374 if (result
== PIM_GROUP_OVERLAP
)
3376 vty_out (vty
, "%% Group range specified cannot overlap%s", VTY_NEWLINE
);
3380 if (result
== PIM_GROUP_PFXLIST_OVERLAP
)
3382 vty_out (vty
, "%% This group is already covered by a RP prefix-list%s", VTY_NEWLINE
);
3386 if (result
== PIM_RP_PFXLIST_IN_USE
)
3388 vty_out (vty
, "%% The same prefix-list cannot be applied to multiple RPs%s", VTY_NEWLINE
);
3395 DEFUN (ip_pim_joinprune_time
,
3396 ip_pim_joinprune_time_cmd
,
3397 "ip pim join-prune-interval <60-600>",
3399 "pim multicast routing\n"
3400 "Join Prune Send Interval\n"
3403 qpim_t_periodic
= atoi(argv
[3]->arg
);
3407 DEFUN (no_ip_pim_joinprune_time
,
3408 no_ip_pim_joinprune_time_cmd
,
3409 "no ip pim join-prune-interval <60-600>",
3412 "pim multicast routing\n"
3413 "Join Prune Send Interval\n"
3416 qpim_t_periodic
= PIM_DEFAULT_T_PERIODIC
;
3420 DEFUN (ip_pim_register_suppress
,
3421 ip_pim_register_suppress_cmd
,
3422 "ip pim register-suppress-time <5-60000>",
3424 "pim multicast routing\n"
3425 "Register Suppress Timer\n"
3428 qpim_keep_alive_time
= atoi (argv
[3]->arg
);
3432 DEFUN (no_ip_pim_register_suppress
,
3433 no_ip_pim_register_suppress_cmd
,
3434 "no ip pim register-suppress-time <5-60000>",
3437 "pim multicast routing\n"
3438 "Register Suppress Timer\n"
3441 qpim_register_suppress_time
= PIM_REGISTER_SUPPRESSION_TIME_DEFAULT
;
3445 DEFUN (ip_pim_keep_alive
,
3446 ip_pim_keep_alive_cmd
,
3447 "ip pim keep-alive-timer <31-60000>",
3449 "pim multicast routing\n"
3450 "Keep alive Timer\n"
3453 qpim_rp_keep_alive_time
= atoi (argv
[4]->arg
);
3457 DEFUN (no_ip_pim_keep_alive
,
3458 no_ip_pim_keep_alive_cmd
,
3459 "no ip pim keep-alive-timer <31-60000>",
3462 "pim multicast routing\n"
3463 "Keep alive Timer\n"
3466 qpim_keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
3470 DEFUN (ip_pim_packets
,
3472 "ip pim packets <1-100>",
3474 "pim multicast routing\n"
3475 "Number of packets to process at one time per fd\n")
3477 qpim_packet_process
= atoi (argv
[3]->arg
);
3481 DEFUN (no_ip_pim_packets
,
3482 no_ip_pim_packets_cmd
,
3483 "no ip pim packets <1-100>",
3486 "pim multicast routing\n"
3487 "Number of packets to process at one time per fd\n")
3489 qpim_packet_process
= PIM_DEFAULT_PACKET_PROCESS
;
3495 "ip pim rp A.B.C.D [A.B.C.D/M]",
3497 "pim multicast routing\n"
3499 "ip address of RP\n")
3502 return pim_rp_cmd_worker (vty
, argv
[idx_ipv4
]->arg
, argv
[idx_ipv4
+ 1]->arg
, NULL
);
3505 DEFUN (ip_pim_rp_prefix_list
,
3506 ip_pim_rp_prefix_list_cmd
,
3507 "ip pim rp A.B.C.D prefix-list WORD",
3509 "pim multicast routing\n"
3511 "ip address of RP\n"
3512 "group prefix-list filter\n"
3513 "Name of a prefix-list\n")
3515 return pim_rp_cmd_worker (vty
, argv
[3]->arg
, NULL
, argv
[5]->arg
);
3519 pim_no_rp_cmd_worker (struct vty
*vty
, const char *rp
, const char *group
,
3522 int result
= pim_rp_del (rp
, group
, plist
);
3524 if (result
== PIM_GROUP_BAD_ADDRESS
)
3526 vty_out (vty
, "%% Bad group address specified: %s%s", group
, VTY_NEWLINE
);
3530 if (result
== PIM_RP_BAD_ADDRESS
)
3532 vty_out (vty
, "%% Bad RP address specified: %s%s", rp
, VTY_NEWLINE
);
3536 if (result
== PIM_RP_NOT_FOUND
)
3538 vty_out (vty
, "%% Unable to find specified RP%s", VTY_NEWLINE
);
3545 DEFUN (no_ip_pim_rp
,
3547 "no ip pim rp A.B.C.D [A.B.C.D/M]",
3550 "pim multicast routing\n"
3552 "ip address of RP\n")
3555 return pim_no_rp_cmd_worker (vty
, argv
[idx_ipv4
]->arg
, argv
[idx_ipv4
+ 1]->arg
, NULL
);
3558 DEFUN (no_ip_pim_rp_prefix_list
,
3559 no_ip_pim_rp_prefix_list_cmd
,
3560 "no ip pim rp A.B.C.D prefix-list WORD",
3563 "pim multicast routing\n"
3565 "ip address of RP\n"
3566 "group prefix-list filter\n"
3567 "Name of a prefix-list\n")
3569 return pim_no_rp_cmd_worker (vty
, argv
[4]->arg
, NULL
, argv
[6]->arg
);
3572 DEFUN (ip_multicast_routing
,
3573 ip_multicast_routing_cmd
,
3574 "ip multicast-routing",
3576 "Enable IP multicast forwarding\n")
3578 pim_mroute_socket_enable();
3579 pim_if_add_vif_all();
3581 static_mroute_add_all();
3585 DEFUN (no_ip_multicast_routing
,
3586 no_ip_multicast_routing_cmd
,
3587 "no ip multicast-routing",
3590 "Global IP configuration subcommands\n"
3591 "Enable IP multicast forwarding\n")
3594 static_mroute_del_all();
3595 pim_if_del_vif_all();
3596 pim_mroute_socket_disable();
3602 "ip ssmpingd [A.B.C.D]",
3609 struct in_addr source_addr
;
3610 const char *source_str
= (argc
> idx_ipv4
) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
3612 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
3614 vty_out(vty
, "%% Bad source address %s: errno=%d: %s%s",
3615 source_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
3619 result
= pim_ssmpingd_start(source_addr
);
3621 vty_out(vty
, "%% Failure starting ssmpingd for source %s: %d%s",
3622 source_str
, result
, VTY_NEWLINE
);
3629 DEFUN (no_ip_ssmpingd
,
3631 "no ip ssmpingd [A.B.C.D]",
3639 struct in_addr source_addr
;
3640 const char *source_str
= (argc
> idx_ipv4
) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
3642 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
3644 vty_out(vty
, "%% Bad source address %s: errno=%d: %s%s",
3645 source_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
3649 result
= pim_ssmpingd_stop(source_addr
);
3651 vty_out(vty
, "%% Failure stopping ssmpingd for source %s: %d%s",
3652 source_str
, result
, VTY_NEWLINE
);
3659 DEFUN (interface_ip_igmp
,
3660 interface_ip_igmp_cmd
,
3665 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3666 struct pim_interface
*pim_ifp
;
3668 pim_ifp
= ifp
->info
;
3671 pim_ifp
= pim_if_new(ifp
, 1 /* igmp=true */, 0 /* pim=false */);
3673 vty_out(vty
, "Could not enable IGMP on interface %s%s",
3674 ifp
->name
, VTY_NEWLINE
);
3679 PIM_IF_DO_IGMP(pim_ifp
->options
);
3682 pim_if_addr_add_all(ifp
);
3683 pim_if_membership_refresh(ifp
);
3688 DEFUN (interface_no_ip_igmp
,
3689 interface_no_ip_igmp_cmd
,
3695 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3696 struct pim_interface
*pim_ifp
;
3698 pim_ifp
= ifp
->info
;
3702 PIM_IF_DONT_IGMP(pim_ifp
->options
);
3704 pim_if_membership_clear(ifp
);
3706 pim_if_addr_del_all_igmp(ifp
);
3708 if (!PIM_IF_TEST_PIM(pim_ifp
->options
)) {
3715 DEFUN (interface_ip_igmp_join
,
3716 interface_ip_igmp_join_cmd
,
3717 "ip igmp join A.B.C.D A.B.C.D",
3720 "IGMP join multicast group\n"
3721 "Multicast group address\n"
3724 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3727 const char *group_str
;
3728 const char *source_str
;
3729 struct in_addr group_addr
;
3730 struct in_addr source_addr
;
3734 group_str
= argv
[idx_ipv4
]->arg
;
3735 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
3737 vty_out(vty
, "Bad group address %s: errno=%d: %s%s",
3738 group_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
3742 /* Source address */
3743 source_str
= argv
[idx_ipv4_2
]->arg
;
3744 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
3746 vty_out(vty
, "Bad source address %s: errno=%d: %s%s",
3747 source_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
3751 result
= pim_if_igmp_join_add(ifp
, group_addr
, source_addr
);
3753 vty_out(vty
, "%% Failure joining IGMP group %s source %s on interface %s: %d%s",
3754 group_str
, source_str
, ifp
->name
, result
, VTY_NEWLINE
);
3761 DEFUN (interface_no_ip_igmp_join
,
3762 interface_no_ip_igmp_join_cmd
,
3763 "no ip igmp join A.B.C.D A.B.C.D",
3767 "IGMP join multicast group\n"
3768 "Multicast group address\n"
3771 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3774 const char *group_str
;
3775 const char *source_str
;
3776 struct in_addr group_addr
;
3777 struct in_addr source_addr
;
3781 group_str
= argv
[idx_ipv4
]->arg
;
3782 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
3784 vty_out(vty
, "Bad group address %s: errno=%d: %s%s",
3785 group_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
3789 /* Source address */
3790 source_str
= argv
[idx_ipv4_2
]->arg
;
3791 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
3793 vty_out(vty
, "Bad source address %s: errno=%d: %s%s",
3794 source_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
3798 result
= pim_if_igmp_join_del(ifp
, group_addr
, source_addr
);
3800 vty_out(vty
, "%% Failure leaving IGMP group %s source %s on interface %s: %d%s",
3801 group_str
, source_str
, ifp
->name
, result
, VTY_NEWLINE
);
3809 CLI reconfiguration affects the interface level (struct pim_interface).
3810 This function propagates the reconfiguration to every active socket
3813 static void igmp_sock_query_interval_reconfig(struct igmp_sock
*igmp
)
3815 struct interface
*ifp
;
3816 struct pim_interface
*pim_ifp
;
3820 /* other querier present? */
3822 if (igmp
->t_other_querier_timer
)
3825 /* this is the querier */
3827 zassert(igmp
->interface
);
3828 zassert(igmp
->interface
->info
);
3830 ifp
= igmp
->interface
;
3831 pim_ifp
= ifp
->info
;
3833 if (PIM_DEBUG_IGMP_TRACE
) {
3834 char ifaddr_str
[INET_ADDRSTRLEN
];
3835 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
, sizeof(ifaddr_str
));
3836 zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
3837 __PRETTY_FUNCTION__
,
3840 pim_ifp
->igmp_default_query_interval
);
3844 igmp_startup_mode_on() will reset QQI:
3846 igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
3848 igmp_startup_mode_on(igmp
);
3851 static void igmp_sock_query_reschedule(struct igmp_sock
*igmp
)
3853 if (igmp
->t_igmp_query_timer
) {
3854 /* other querier present */
3855 zassert(igmp
->t_igmp_query_timer
);
3856 zassert(!igmp
->t_other_querier_timer
);
3858 pim_igmp_general_query_off(igmp
);
3859 pim_igmp_general_query_on(igmp
);
3861 zassert(igmp
->t_igmp_query_timer
);
3862 zassert(!igmp
->t_other_querier_timer
);
3865 /* this is the querier */
3867 zassert(!igmp
->t_igmp_query_timer
);
3868 zassert(igmp
->t_other_querier_timer
);
3870 pim_igmp_other_querier_timer_off(igmp
);
3871 pim_igmp_other_querier_timer_on(igmp
);
3873 zassert(!igmp
->t_igmp_query_timer
);
3874 zassert(igmp
->t_other_querier_timer
);
3878 static void change_query_interval(struct pim_interface
*pim_ifp
,
3881 struct listnode
*sock_node
;
3882 struct igmp_sock
*igmp
;
3884 pim_ifp
->igmp_default_query_interval
= query_interval
;
3886 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
3887 igmp_sock_query_interval_reconfig(igmp
);
3888 igmp_sock_query_reschedule(igmp
);
3892 static void change_query_max_response_time(struct pim_interface
*pim_ifp
,
3893 int query_max_response_time_dsec
)
3895 struct listnode
*sock_node
;
3896 struct igmp_sock
*igmp
;
3898 pim_ifp
->igmp_query_max_response_time_dsec
= query_max_response_time_dsec
;
3901 Below we modify socket/group/source timers in order to quickly
3902 reflect the change. Otherwise, those timers would eventually catch
3906 /* scan all sockets */
3907 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
3908 struct listnode
*grp_node
;
3909 struct igmp_group
*grp
;
3911 /* reschedule socket general query */
3912 igmp_sock_query_reschedule(igmp
);
3914 /* scan socket groups */
3915 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grp_node
, grp
)) {
3916 struct listnode
*src_node
;
3917 struct igmp_source
*src
;
3919 /* reset group timers for groups in EXCLUDE mode */
3920 if (grp
->group_filtermode_isexcl
) {
3921 igmp_group_reset_gmi(grp
);
3924 /* scan group sources */
3925 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
, src_node
, src
)) {
3927 /* reset source timers for sources with running timers */
3928 if (src
->t_source_timer
) {
3929 igmp_source_reset_gmi(igmp
, grp
, src
);
3936 #define IGMP_QUERY_INTERVAL_MIN (1)
3937 #define IGMP_QUERY_INTERVAL_MAX (1800)
3939 DEFUN (interface_ip_igmp_query_interval
,
3940 interface_ip_igmp_query_interval_cmd
,
3941 "ip igmp query-interval (1-1800)",
3944 IFACE_IGMP_QUERY_INTERVAL_STR
3945 "Query interval in seconds\n")
3947 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3948 struct pim_interface
*pim_ifp
;
3950 int query_interval_dsec
;
3952 pim_ifp
= ifp
->info
;
3956 "IGMP not enabled on interface %s. Please enable IGMP first.%s",
3962 query_interval
= atoi(argv
[4]->arg
);
3963 query_interval_dsec
= 10 * query_interval
;
3966 It seems we don't need to check bounds since command.c does it
3967 already, but we verify them anyway for extra safety.
3969 if (query_interval
< IGMP_QUERY_INTERVAL_MIN
) {
3970 vty_out(vty
, "General query interval %d lower than minimum %d%s",
3972 IGMP_QUERY_INTERVAL_MIN
,
3976 if (query_interval
> IGMP_QUERY_INTERVAL_MAX
) {
3977 vty_out(vty
, "General query interval %d higher than maximum %d%s",
3979 IGMP_QUERY_INTERVAL_MAX
,
3984 if (query_interval_dsec
<= pim_ifp
->igmp_query_max_response_time_dsec
) {
3986 "Can't set general query interval %d dsec <= query max response time %d dsec.%s",
3987 query_interval_dsec
, pim_ifp
->igmp_query_max_response_time_dsec
,
3992 change_query_interval(pim_ifp
, query_interval
);
3997 DEFUN (interface_no_ip_igmp_query_interval
,
3998 interface_no_ip_igmp_query_interval_cmd
,
3999 "no ip igmp query-interval",
4003 IFACE_IGMP_QUERY_INTERVAL_STR
)
4005 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4006 struct pim_interface
*pim_ifp
;
4007 int default_query_interval_dsec
;
4009 pim_ifp
= ifp
->info
;
4014 default_query_interval_dsec
= IGMP_GENERAL_QUERY_INTERVAL
* 10;
4016 if (default_query_interval_dsec
<= pim_ifp
->igmp_query_max_response_time_dsec
) {
4018 "Can't set default general query interval %d dsec <= query max response time %d dsec.%s",
4019 default_query_interval_dsec
, pim_ifp
->igmp_query_max_response_time_dsec
,
4024 change_query_interval(pim_ifp
, IGMP_GENERAL_QUERY_INTERVAL
);
4029 DEFUN (interface_ip_igmp_version
,
4030 interface_ip_igmp_version_cmd
,
4031 "ip igmp version <2-3>",
4035 "IGMP version number\n")
4037 VTY_DECLVAR_CONTEXT(interface
,ifp
);
4038 struct pim_interface
*pim_ifp
;
4041 pim_ifp
= ifp
->info
;
4045 "IGMP not enabled on interface %s. Please enable IGMP first.%s",
4051 igmp_version
= atoi(argv
[3]->arg
);
4052 pim_ifp
->igmp_version
= igmp_version
;
4057 DEFUN (interface_no_ip_igmp_version
,
4058 interface_no_ip_igmp_version_cmd
,
4059 "no ip igmp version <2-3>",
4064 "IGMP version number\n")
4066 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4067 struct pim_interface
*pim_ifp
;
4069 pim_ifp
= ifp
->info
;
4074 pim_ifp
->igmp_version
= IGMP_DEFAULT_VERSION
;
4079 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
4080 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
4082 DEFUN (interface_ip_igmp_query_max_response_time
,
4083 interface_ip_igmp_query_max_response_time_cmd
,
4084 "ip igmp query-max-response-time (10-250)",
4087 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
4088 "Query response value in deci-seconds\n")
4090 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4091 struct pim_interface
*pim_ifp
;
4092 int query_max_response_time
;
4094 pim_ifp
= ifp
->info
;
4098 "IGMP not enabled on interface %s. Please enable IGMP first.%s",
4104 query_max_response_time
= atoi(argv
[4]->arg
);
4106 if (query_max_response_time
>= pim_ifp
->igmp_default_query_interval
* 10) {
4108 "Can't set query max response time %d sec >= general query interval %d sec%s",
4109 query_max_response_time
, pim_ifp
->igmp_default_query_interval
,
4114 change_query_max_response_time(pim_ifp
, query_max_response_time
);
4119 DEFUN (interface_no_ip_igmp_query_max_response_time
,
4120 interface_no_ip_igmp_query_max_response_time_cmd
,
4121 "no ip igmp query-max-response-time <10-250>",
4125 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
)
4127 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4128 struct pim_interface
*pim_ifp
;
4130 pim_ifp
= ifp
->info
;
4135 change_query_max_response_time(pim_ifp
, IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
4140 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
4141 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
4143 DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec
,
4144 interface_ip_igmp_query_max_response_time_dsec_cmd
,
4145 "ip igmp query-max-response-time-dsec (10-250)",
4148 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
4149 "Query response value in deciseconds\n")
4151 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4152 struct pim_interface
*pim_ifp
;
4153 int query_max_response_time_dsec
;
4154 int default_query_interval_dsec
;
4156 pim_ifp
= ifp
->info
;
4160 "IGMP not enabled on interface %s. Please enable IGMP first.%s",
4166 query_max_response_time_dsec
= atoi(argv
[4]->arg
);
4168 default_query_interval_dsec
= 10 * pim_ifp
->igmp_default_query_interval
;
4170 if (query_max_response_time_dsec
>= default_query_interval_dsec
) {
4172 "Can't set query max response time %d dsec >= general query interval %d dsec%s",
4173 query_max_response_time_dsec
, default_query_interval_dsec
,
4178 change_query_max_response_time(pim_ifp
, query_max_response_time_dsec
);
4183 DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec
,
4184 interface_no_ip_igmp_query_max_response_time_dsec_cmd
,
4185 "no ip igmp query-max-response-time-dsec",
4189 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
)
4191 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4192 struct pim_interface
*pim_ifp
;
4194 pim_ifp
= ifp
->info
;
4199 change_query_max_response_time(pim_ifp
, IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
4204 DEFUN (interface_ip_pim_drprio
,
4205 interface_ip_pim_drprio_cmd
,
4206 "ip pim drpriority (1-4294967295)",
4209 "Set the Designated Router Election Priority\n"
4210 "Value of the new DR Priority\n")
4212 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4214 struct pim_interface
*pim_ifp
;
4215 uint32_t old_dr_prio
;
4217 pim_ifp
= ifp
->info
;
4220 vty_out(vty
, "Please enable PIM on interface, first%s", VTY_NEWLINE
);
4224 old_dr_prio
= pim_ifp
->pim_dr_priority
;
4226 pim_ifp
->pim_dr_priority
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
4228 if (old_dr_prio
!= pim_ifp
->pim_dr_priority
) {
4229 if (pim_if_dr_election(ifp
))
4230 pim_hello_restart_now(ifp
);
4236 DEFUN (interface_no_ip_pim_drprio
,
4237 interface_no_ip_pim_drprio_cmd
,
4238 "no ip pim drpriority [(1-4294967295)]",
4242 "Revert the Designated Router Priority to default\n"
4243 "Old Value of the Priority\n")
4245 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4246 struct pim_interface
*pim_ifp
;
4248 pim_ifp
= ifp
->info
;
4251 vty_out(vty
, "Pim not enabled on this interface%s", VTY_NEWLINE
);
4255 if (pim_ifp
->pim_dr_priority
!= PIM_DEFAULT_DR_PRIORITY
) {
4256 pim_ifp
->pim_dr_priority
= PIM_DEFAULT_DR_PRIORITY
;
4257 if (pim_if_dr_election(ifp
))
4258 pim_hello_restart_now(ifp
);
4265 pim_cmd_interface_add (struct interface
*ifp
, enum pim_interface_type itype
)
4267 struct pim_interface
*pim_ifp
= ifp
->info
;
4270 pim_ifp
= pim_if_new(ifp
, 0 /* igmp=false */, 1 /* pim=true */);
4276 PIM_IF_DO_PIM(pim_ifp
->options
);
4279 pim_ifp
->itype
= itype
;
4280 pim_if_addr_add_all(ifp
);
4281 pim_if_membership_refresh(ifp
);
4286 DEFUN (interface_ip_pim_ssm
,
4287 interface_ip_pim_ssm_cmd
,
4293 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4295 if (!pim_cmd_interface_add(ifp
, PIM_INTERFACE_SSM
)) {
4296 vty_out(vty
, "Could not enable PIM SSM on interface%s", VTY_NEWLINE
);
4303 DEFUN (interface_ip_pim_sm
,
4304 interface_ip_pim_sm_cmd
,
4310 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4311 if (!pim_cmd_interface_add(ifp
, PIM_INTERFACE_SM
)) {
4312 vty_out(vty
, "Could not enable PIM SM on interface%s", VTY_NEWLINE
);
4316 pim_if_create_pimreg();
4322 pim_cmd_interface_delete (struct interface
*ifp
)
4324 struct pim_interface
*pim_ifp
= ifp
->info
;
4329 PIM_IF_DONT_PIM(pim_ifp
->options
);
4331 pim_if_membership_clear(ifp
);
4334 pim_sock_delete() removes all neighbors from
4335 pim_ifp->pim_neighbor_list.
4337 pim_sock_delete(ifp
, "pim unconfigured on interface");
4339 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
4340 pim_if_addr_del_all(ifp
);
4347 DEFUN (interface_no_ip_pim_ssm
,
4348 interface_no_ip_pim_ssm_cmd
,
4355 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4356 if (!pim_cmd_interface_delete(ifp
)) {
4357 vty_out(vty
, "Unable to delete interface information%s", VTY_NEWLINE
);
4364 DEFUN (interface_no_ip_pim_sm
,
4365 interface_no_ip_pim_sm_cmd
,
4372 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4373 if (!pim_cmd_interface_delete(ifp
)) {
4374 vty_out(vty
, "Unable to delete interface information%s", VTY_NEWLINE
);
4381 DEFUN (interface_ip_mroute
,
4382 interface_ip_mroute_cmd
,
4383 "ip mroute INTERFACE A.B.C.D",
4385 "Add multicast route\n"
4386 "Outgoing interface name\n"
4389 VTY_DECLVAR_CONTEXT(interface
, iif
);
4390 int idx_interface
= 2;
4392 struct interface
*oif
;
4393 const char *oifname
;
4394 const char *grp_str
;
4395 struct in_addr grp_addr
;
4396 struct in_addr src_addr
;
4399 oifname
= argv
[idx_interface
]->arg
;
4400 oif
= if_lookup_by_name(oifname
);
4402 vty_out(vty
, "No such interface name %s%s",
4403 oifname
, VTY_NEWLINE
);
4407 grp_str
= argv
[idx_ipv4
]->arg
;
4408 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
4410 vty_out(vty
, "Bad group address %s: errno=%d: %s%s",
4411 grp_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
4415 src_addr
.s_addr
= INADDR_ANY
;
4417 if (pim_static_add(iif
, oif
, grp_addr
, src_addr
)) {
4418 vty_out(vty
, "Failed to add route%s", VTY_NEWLINE
);
4425 DEFUN (interface_ip_mroute_source
,
4426 interface_ip_mroute_source_cmd
,
4427 "ip mroute INTERFACE A.B.C.D A.B.C.D",
4429 "Add multicast route\n"
4430 "Outgoing interface name\n"
4434 VTY_DECLVAR_CONTEXT(interface
, iif
);
4435 int idx_interface
= 2;
4438 struct interface
*oif
;
4439 const char *oifname
;
4440 const char *grp_str
;
4441 struct in_addr grp_addr
;
4442 const char *src_str
;
4443 struct in_addr src_addr
;
4446 oifname
= argv
[idx_interface
]->arg
;
4447 oif
= if_lookup_by_name(oifname
);
4449 vty_out(vty
, "No such interface name %s%s",
4450 oifname
, VTY_NEWLINE
);
4454 grp_str
= argv
[idx_ipv4
]->arg
;
4455 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
4457 vty_out(vty
, "Bad group address %s: errno=%d: %s%s",
4458 grp_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
4462 src_str
= argv
[idx_ipv4_2
]->arg
;
4463 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
4465 vty_out(vty
, "Bad source address %s: errno=%d: %s%s",
4466 src_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
4470 if (pim_static_add(iif
, oif
, grp_addr
, src_addr
)) {
4471 vty_out(vty
, "Failed to add route%s", VTY_NEWLINE
);
4478 DEFUN (interface_no_ip_mroute
,
4479 interface_no_ip_mroute_cmd
,
4480 "no ip mroute INTERFACE A.B.C.D",
4483 "Add multicast route\n"
4484 "Outgoing interface name\n"
4487 VTY_DECLVAR_CONTEXT(interface
, iif
);
4488 int idx_interface
= 3;
4490 struct interface
*oif
;
4491 const char *oifname
;
4492 const char *grp_str
;
4493 struct in_addr grp_addr
;
4494 struct in_addr src_addr
;
4497 oifname
= argv
[idx_interface
]->arg
;
4498 oif
= if_lookup_by_name(oifname
);
4500 vty_out(vty
, "No such interface name %s%s",
4501 oifname
, VTY_NEWLINE
);
4505 grp_str
= argv
[idx_ipv4
]->arg
;
4506 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
4508 vty_out(vty
, "Bad group address %s: errno=%d: %s%s",
4509 grp_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
4513 src_addr
.s_addr
= INADDR_ANY
;
4515 if (pim_static_del(iif
, oif
, grp_addr
, src_addr
)) {
4516 vty_out(vty
, "Failed to remove route%s", VTY_NEWLINE
);
4523 DEFUN (interface_no_ip_mroute_source
,
4524 interface_no_ip_mroute_source_cmd
,
4525 "no ip mroute INTERFACE A.B.C.D A.B.C.D",
4528 "Add multicast route\n"
4529 "Outgoing interface name\n"
4533 VTY_DECLVAR_CONTEXT(interface
, iif
);
4534 int idx_interface
= 3;
4537 struct interface
*oif
;
4538 const char *oifname
;
4539 const char *grp_str
;
4540 struct in_addr grp_addr
;
4541 const char *src_str
;
4542 struct in_addr src_addr
;
4545 oifname
= argv
[idx_interface
]->arg
;
4546 oif
= if_lookup_by_name(oifname
);
4548 vty_out(vty
, "No such interface name %s%s",
4549 oifname
, VTY_NEWLINE
);
4553 grp_str
= argv
[idx_ipv4
]->arg
;
4554 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
4556 vty_out(vty
, "Bad group address %s: errno=%d: %s%s",
4557 grp_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
4561 src_str
= argv
[idx_ipv4_2
]->arg
;
4562 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
4564 vty_out(vty
, "Bad source address %s: errno=%d: %s%s",
4565 src_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
4569 if (pim_static_del(iif
, oif
, grp_addr
, src_addr
)) {
4570 vty_out(vty
, "Failed to remove route%s", VTY_NEWLINE
);
4577 DEFUN (interface_ip_pim_hello
,
4578 interface_ip_pim_hello_cmd
,
4579 "ip pim hello (1-180) [(1-180)]",
4583 IFACE_PIM_HELLO_TIME_STR
4584 IFACE_PIM_HELLO_HOLD_STR
)
4586 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4589 struct pim_interface
*pim_ifp
;
4591 pim_ifp
= ifp
->info
;
4594 vty_out(vty
, "Pim not enabled on this interface%s", VTY_NEWLINE
);
4598 pim_ifp
->pim_hello_period
= strtol(argv
[idx_time
]->arg
, NULL
, 10);
4600 if (argc
> idx_hold
)
4601 pim_ifp
->pim_default_holdtime
= strtol(argv
[idx_hold
]->arg
, NULL
, 10);
4608 DEFUN (interface_no_ip_pim_hello
,
4609 interface_no_ip_pim_hello_cmd
,
4610 "no ip pim hello [(1-180) (1-180)]",
4615 IFACE_PIM_HELLO_TIME_STR
4616 IFACE_PIM_HELLO_HOLD_STR
)
4618 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4619 struct pim_interface
*pim_ifp
;
4621 pim_ifp
= ifp
->info
;
4624 vty_out(vty
, "Pim not enabled on this interface%s", VTY_NEWLINE
);
4628 pim_ifp
->pim_hello_period
= PIM_DEFAULT_HELLO_PERIOD
;
4629 pim_ifp
->pim_default_holdtime
= -1;
4640 PIM_DO_DEBUG_IGMP_EVENTS
;
4641 PIM_DO_DEBUG_IGMP_PACKETS
;
4642 PIM_DO_DEBUG_IGMP_TRACE
;
4646 DEFUN (no_debug_igmp
,
4653 PIM_DONT_DEBUG_IGMP_EVENTS
;
4654 PIM_DONT_DEBUG_IGMP_PACKETS
;
4655 PIM_DONT_DEBUG_IGMP_TRACE
;
4660 DEFUN (debug_igmp_events
,
4661 debug_igmp_events_cmd
,
4662 "debug igmp events",
4665 DEBUG_IGMP_EVENTS_STR
)
4667 PIM_DO_DEBUG_IGMP_EVENTS
;
4671 DEFUN (no_debug_igmp_events
,
4672 no_debug_igmp_events_cmd
,
4673 "no debug igmp events",
4677 DEBUG_IGMP_EVENTS_STR
)
4679 PIM_DONT_DEBUG_IGMP_EVENTS
;
4684 DEFUN (debug_igmp_packets
,
4685 debug_igmp_packets_cmd
,
4686 "debug igmp packets",
4689 DEBUG_IGMP_PACKETS_STR
)
4691 PIM_DO_DEBUG_IGMP_PACKETS
;
4695 DEFUN (no_debug_igmp_packets
,
4696 no_debug_igmp_packets_cmd
,
4697 "no debug igmp packets",
4701 DEBUG_IGMP_PACKETS_STR
)
4703 PIM_DONT_DEBUG_IGMP_PACKETS
;
4708 DEFUN (debug_igmp_trace
,
4709 debug_igmp_trace_cmd
,
4713 DEBUG_IGMP_TRACE_STR
)
4715 PIM_DO_DEBUG_IGMP_TRACE
;
4719 DEFUN (no_debug_igmp_trace
,
4720 no_debug_igmp_trace_cmd
,
4721 "no debug igmp trace",
4725 DEBUG_IGMP_TRACE_STR
)
4727 PIM_DONT_DEBUG_IGMP_TRACE
;
4732 DEFUN (debug_mroute
,
4738 PIM_DO_DEBUG_MROUTE
;
4742 DEFUN (debug_mroute_detail
,
4743 debug_mroute_detail_cmd
,
4744 "debug mroute detail",
4749 PIM_DO_DEBUG_MROUTE_DETAIL
;
4753 DEFUN (no_debug_mroute
,
4754 no_debug_mroute_cmd
,
4760 PIM_DONT_DEBUG_MROUTE
;
4764 DEFUN (no_debug_mroute_detail
,
4765 no_debug_mroute_detail_cmd
,
4766 "no debug mroute detail",
4772 PIM_DONT_DEBUG_MROUTE_DETAIL
;
4776 DEFUN (debug_static
,
4782 PIM_DO_DEBUG_STATIC
;
4786 DEFUN (no_debug_static
,
4787 no_debug_static_cmd
,
4793 PIM_DONT_DEBUG_STATIC
;
4804 PIM_DO_DEBUG_PIM_EVENTS
;
4805 PIM_DO_DEBUG_PIM_PACKETS
;
4806 PIM_DO_DEBUG_PIM_TRACE
;
4807 PIM_DO_DEBUG_MSDP_EVENTS
;
4808 PIM_DO_DEBUG_MSDP_PACKETS
;
4812 DEFUN (no_debug_pim
,
4819 PIM_DONT_DEBUG_PIM_EVENTS
;
4820 PIM_DONT_DEBUG_PIM_PACKETS
;
4821 PIM_DONT_DEBUG_PIM_TRACE
;
4822 PIM_DONT_DEBUG_MSDP_EVENTS
;
4823 PIM_DONT_DEBUG_MSDP_PACKETS
;
4825 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
4826 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
4832 DEFUN (debug_pim_events
,
4833 debug_pim_events_cmd
,
4837 DEBUG_PIM_EVENTS_STR
)
4839 PIM_DO_DEBUG_PIM_EVENTS
;
4843 DEFUN (no_debug_pim_events
,
4844 no_debug_pim_events_cmd
,
4845 "no debug pim events",
4849 DEBUG_PIM_EVENTS_STR
)
4851 PIM_DONT_DEBUG_PIM_EVENTS
;
4856 DEFUN (debug_pim_packets
,
4857 debug_pim_packets_cmd
,
4858 "debug pim packets",
4861 DEBUG_PIM_PACKETS_STR
)
4863 PIM_DO_DEBUG_PIM_PACKETS
;
4864 vty_out (vty
, "PIM Packet debugging is on %s", VTY_NEWLINE
);
4868 DEFUN (debug_pim_packets_filter
,
4869 debug_pim_packets_filter_cmd
,
4870 "debug pim packets <hello|joins|register>",
4873 DEBUG_PIM_PACKETS_STR
4874 DEBUG_PIM_HELLO_PACKETS_STR
4875 DEBUG_PIM_J_P_PACKETS_STR
4876 DEBUG_PIM_PIM_REG_PACKETS_STR
)
4878 int idx_hello_join
= 3;
4879 if (strncmp(argv
[idx_hello_join
]->arg
,"h",1) == 0)
4881 PIM_DO_DEBUG_PIM_HELLO
;
4882 vty_out (vty
, "PIM Hello debugging is on%s", VTY_NEWLINE
);
4884 else if (strncmp(argv
[idx_hello_join
]->arg
,"j",1) == 0)
4886 PIM_DO_DEBUG_PIM_J_P
;
4887 vty_out (vty
, "PIM Join/Prune debugging is on%s", VTY_NEWLINE
);
4889 else if (strncmp(argv
[idx_hello_join
]->arg
,"r",1) == 0)
4891 PIM_DO_DEBUG_PIM_REG
;
4892 vty_out (vty
, "PIM Register debugging is on%s", VTY_NEWLINE
);
4897 DEFUN (no_debug_pim_packets
,
4898 no_debug_pim_packets_cmd
,
4899 "no debug pim packets",
4903 DEBUG_PIM_PACKETS_STR
4904 DEBUG_PIM_HELLO_PACKETS_STR
4905 DEBUG_PIM_J_P_PACKETS_STR
)
4907 PIM_DONT_DEBUG_PIM_PACKETS
;
4908 vty_out (vty
, "PIM Packet debugging is off %s", VTY_NEWLINE
);
4912 DEFUN (no_debug_pim_packets_filter
,
4913 no_debug_pim_packets_filter_cmd
,
4914 "no debug pim packets <hello|joins|register>",
4918 DEBUG_PIM_PACKETS_STR
4919 DEBUG_PIM_HELLO_PACKETS_STR
4920 DEBUG_PIM_J_P_PACKETS_STR
)
4922 int idx_hello_join
= 4;
4923 if (strncmp(argv
[idx_hello_join
]->arg
,"h",1) == 0)
4925 PIM_DONT_DEBUG_PIM_HELLO
;
4926 vty_out (vty
, "PIM Hello debugging is off %s", VTY_NEWLINE
);
4928 else if (strncmp(argv
[idx_hello_join
]->arg
,"j",1) == 0)
4930 PIM_DONT_DEBUG_PIM_J_P
;
4931 vty_out (vty
, "PIM Join/Prune debugging is off %s", VTY_NEWLINE
);
4933 else if (strncmp (argv
[idx_hello_join
]->arg
, "r", 1) == 0)
4935 PIM_DONT_DEBUG_PIM_REG
;
4936 vty_out (vty
, "PIM Register debugging is off%s", VTY_NEWLINE
);
4942 DEFUN (debug_pim_packetdump_send
,
4943 debug_pim_packetdump_send_cmd
,
4944 "debug pim packet-dump send",
4947 DEBUG_PIM_PACKETDUMP_STR
4948 DEBUG_PIM_PACKETDUMP_SEND_STR
)
4950 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND
;
4954 DEFUN (no_debug_pim_packetdump_send
,
4955 no_debug_pim_packetdump_send_cmd
,
4956 "no debug pim packet-dump send",
4960 DEBUG_PIM_PACKETDUMP_STR
4961 DEBUG_PIM_PACKETDUMP_SEND_STR
)
4963 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
4968 DEFUN (debug_pim_packetdump_recv
,
4969 debug_pim_packetdump_recv_cmd
,
4970 "debug pim packet-dump receive",
4973 DEBUG_PIM_PACKETDUMP_STR
4974 DEBUG_PIM_PACKETDUMP_RECV_STR
)
4976 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV
;
4980 DEFUN (no_debug_pim_packetdump_recv
,
4981 no_debug_pim_packetdump_recv_cmd
,
4982 "no debug pim packet-dump receive",
4986 DEBUG_PIM_PACKETDUMP_STR
4987 DEBUG_PIM_PACKETDUMP_RECV_STR
)
4989 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
4994 DEFUN (debug_pim_trace
,
4995 debug_pim_trace_cmd
,
4999 DEBUG_PIM_TRACE_STR
)
5001 PIM_DO_DEBUG_PIM_TRACE
;
5005 DEFUN (no_debug_pim_trace
,
5006 no_debug_pim_trace_cmd
,
5007 "no debug pim trace",
5011 DEBUG_PIM_TRACE_STR
)
5013 PIM_DONT_DEBUG_PIM_TRACE
;
5018 DEFUN (debug_ssmpingd
,
5025 PIM_DO_DEBUG_SSMPINGD
;
5029 DEFUN (no_debug_ssmpingd
,
5030 no_debug_ssmpingd_cmd
,
5031 "no debug ssmpingd",
5037 PIM_DONT_DEBUG_SSMPINGD
;
5042 DEFUN (debug_pim_zebra
,
5043 debug_pim_zebra_cmd
,
5047 DEBUG_PIM_ZEBRA_STR
)
5053 DEFUN (no_debug_pim_zebra
,
5054 no_debug_pim_zebra_cmd
,
5055 "no debug pim zebra",
5059 DEBUG_PIM_ZEBRA_STR
)
5061 PIM_DONT_DEBUG_ZEBRA
;
5072 PIM_DO_DEBUG_MSDP_EVENTS
;
5073 PIM_DO_DEBUG_MSDP_PACKETS
;
5077 DEFUN (no_debug_msdp
,
5084 PIM_DONT_DEBUG_MSDP_EVENTS
;
5085 PIM_DONT_DEBUG_MSDP_PACKETS
;
5089 ALIAS (no_debug_msdp
,
5095 DEFUN (debug_msdp_events
,
5096 debug_msdp_events_cmd
,
5097 "debug msdp events",
5100 DEBUG_MSDP_EVENTS_STR
)
5102 PIM_DO_DEBUG_MSDP_EVENTS
;
5106 DEFUN (no_debug_msdp_events
,
5107 no_debug_msdp_events_cmd
,
5108 "no debug msdp events",
5112 DEBUG_MSDP_EVENTS_STR
)
5114 PIM_DONT_DEBUG_MSDP_EVENTS
;
5118 ALIAS (no_debug_msdp_events
,
5119 undebug_msdp_events_cmd
,
5120 "undebug msdp events",
5123 DEBUG_MSDP_EVENTS_STR
)
5125 DEFUN (debug_msdp_packets
,
5126 debug_msdp_packets_cmd
,
5127 "debug msdp packets",
5130 DEBUG_MSDP_PACKETS_STR
)
5132 PIM_DO_DEBUG_MSDP_PACKETS
;
5136 DEFUN (no_debug_msdp_packets
,
5137 no_debug_msdp_packets_cmd
,
5138 "no debug msdp packets",
5142 DEBUG_MSDP_PACKETS_STR
)
5144 PIM_DONT_DEBUG_MSDP_PACKETS
;
5148 ALIAS (no_debug_msdp_packets
,
5149 undebug_msdp_packets_cmd
,
5150 "undebug msdp packets",
5153 DEBUG_MSDP_PACKETS_STR
)
5155 DEFUN (show_debugging_pim
,
5156 show_debugging_pim_cmd
,
5157 "show debugging pim",
5162 pim_debug_config_write(vty
);
5167 interface_pim_use_src_cmd_worker(struct vty
*vty
, const char *source
)
5170 struct in_addr source_addr
;
5171 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5173 result
= inet_pton(AF_INET
, source
, &source_addr
);
5175 vty_out(vty
, "%% Bad source address %s: errno=%d: %s%s",
5176 source
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
5180 result
= pim_update_source_set(ifp
, source_addr
);
5184 case PIM_IFACE_NOT_FOUND
:
5185 vty_out(vty
, "Pim not enabled on this interface%s", VTY_NEWLINE
);
5187 case PIM_UPDATE_SOURCE_DUP
:
5188 vty_out(vty
, "%% Source already set to %s%s", source
, VTY_NEWLINE
);
5191 vty_out(vty
, "%% Source set failed%s", VTY_NEWLINE
);
5194 return result
?CMD_WARNING
:CMD_SUCCESS
;
5197 DEFUN (interface_pim_use_source
,
5198 interface_pim_use_source_cmd
,
5199 "ip pim use-source A.B.C.D",
5201 "pim multicast routing\n"
5202 "Configure primary IP address\n"
5203 "source ip address\n")
5205 return interface_pim_use_src_cmd_worker (vty
, argv
[3]->arg
);
5208 DEFUN (interface_no_pim_use_source
,
5209 interface_no_pim_use_source_cmd
,
5210 "no ip pim use-source",
5213 "pim multicast routing\n"
5214 "Delete source IP address\n")
5216 return interface_pim_use_src_cmd_worker (vty
, "0.0.0.0");
5220 ip_msdp_peer_cmd_worker (struct vty
*vty
, const char *peer
, const char *local
)
5222 enum pim_msdp_err result
;
5223 struct in_addr peer_addr
;
5224 struct in_addr local_addr
;
5226 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
5228 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s%s",
5229 peer
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
5233 result
= inet_pton(AF_INET
, local
, &local_addr
);
5235 vty_out(vty
, "%% Bad source address %s: errno=%d: %s%s",
5236 local
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
5240 result
= pim_msdp_peer_add(peer_addr
, local_addr
, "default", NULL
/* mp_p */);
5242 case PIM_MSDP_ERR_NONE
:
5244 case PIM_MSDP_ERR_OOM
:
5245 vty_out(vty
, "%% Out of memory%s", VTY_NEWLINE
);
5247 case PIM_MSDP_ERR_PEER_EXISTS
:
5248 vty_out(vty
, "%% Peer exists%s", VTY_NEWLINE
);
5250 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
5251 vty_out(vty
, "%% Only one mesh-group allowed currently%s", VTY_NEWLINE
);
5254 vty_out(vty
, "%% peer add failed%s", VTY_NEWLINE
);
5257 return result
?CMD_WARNING
:CMD_SUCCESS
;
5260 DEFUN_HIDDEN (ip_msdp_peer
,
5262 "ip msdp peer A.B.C.D source A.B.C.D",
5265 "Configure MSDP peer\n"
5267 "Source address for TCP connection\n"
5268 "local ip address\n")
5270 return ip_msdp_peer_cmd_worker (vty
, argv
[3]->arg
, argv
[5]->arg
);
5274 ip_no_msdp_peer_cmd_worker (struct vty
*vty
, const char *peer
)
5276 enum pim_msdp_err result
;
5277 struct in_addr peer_addr
;
5279 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
5281 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s%s",
5282 peer
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
5286 result
= pim_msdp_peer_del(peer_addr
);
5288 case PIM_MSDP_ERR_NONE
:
5290 case PIM_MSDP_ERR_NO_PEER
:
5291 vty_out(vty
, "%% Peer does not exist%s", VTY_NEWLINE
);
5294 vty_out(vty
, "%% peer del failed%s", VTY_NEWLINE
);
5297 return result
?CMD_WARNING
:CMD_SUCCESS
;
5300 DEFUN_HIDDEN (no_ip_msdp_peer
,
5301 no_ip_msdp_peer_cmd
,
5302 "no ip msdp peer A.B.C.D",
5306 "Delete MSDP peer\n"
5307 "peer ip address\n")
5309 return ip_no_msdp_peer_cmd_worker (vty
, argv
[4]->arg
);
5313 ip_msdp_mesh_group_member_cmd_worker(struct vty
*vty
, const char *mg
, const char *mbr
)
5315 enum pim_msdp_err result
;
5316 struct in_addr mbr_ip
;
5318 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
5320 vty_out(vty
, "%% Bad member address %s: errno=%d: %s%s",
5321 mbr
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
5325 result
= pim_msdp_mg_mbr_add(mg
, mbr_ip
);
5327 case PIM_MSDP_ERR_NONE
:
5329 case PIM_MSDP_ERR_OOM
:
5330 vty_out(vty
, "%% Out of memory%s", VTY_NEWLINE
);
5332 case PIM_MSDP_ERR_MG_MBR_EXISTS
:
5333 vty_out(vty
, "%% mesh-group member exists%s", VTY_NEWLINE
);
5335 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
5336 vty_out(vty
, "%% Only one mesh-group allowed currently%s", VTY_NEWLINE
);
5339 vty_out(vty
, "%% member add failed%s", VTY_NEWLINE
);
5342 return result
?CMD_WARNING
:CMD_SUCCESS
;
5345 DEFUN (ip_msdp_mesh_group_member
,
5346 ip_msdp_mesh_group_member_cmd
,
5347 "ip msdp mesh-group WORD member A.B.C.D",
5350 "Configure MSDP mesh-group\n"
5352 "mesh group member\n"
5353 "peer ip address\n")
5355 return ip_msdp_mesh_group_member_cmd_worker(vty
, argv
[3]->arg
, argv
[5]->arg
);
5359 ip_no_msdp_mesh_group_member_cmd_worker(struct vty
*vty
, const char *mg
, const char *mbr
)
5361 enum pim_msdp_err result
;
5362 struct in_addr mbr_ip
;
5364 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
5366 vty_out(vty
, "%% Bad member address %s: errno=%d: %s%s",
5367 mbr
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
5371 result
= pim_msdp_mg_mbr_del(mg
, mbr_ip
);
5373 case PIM_MSDP_ERR_NONE
:
5375 case PIM_MSDP_ERR_NO_MG
:
5376 vty_out(vty
, "%% mesh-group does not exist%s", VTY_NEWLINE
);
5378 case PIM_MSDP_ERR_NO_MG_MBR
:
5379 vty_out(vty
, "%% mesh-group member does not exist%s", VTY_NEWLINE
);
5382 vty_out(vty
, "%% mesh-group member del failed%s", VTY_NEWLINE
);
5385 return result
?CMD_WARNING
:CMD_SUCCESS
;
5387 DEFUN (no_ip_msdp_mesh_group_member
,
5388 no_ip_msdp_mesh_group_member_cmd
,
5389 "no ip msdp mesh-group WORD member A.B.C.D",
5393 "Delete MSDP mesh-group member\n"
5395 "mesh group member\n"
5396 "peer ip address\n")
5398 return ip_no_msdp_mesh_group_member_cmd_worker(vty
, argv
[4]->arg
, argv
[6]->arg
);
5402 ip_msdp_mesh_group_source_cmd_worker(struct vty
*vty
, const char *mg
, const char *src
)
5404 enum pim_msdp_err result
;
5405 struct in_addr src_ip
;
5407 result
= inet_pton(AF_INET
, src
, &src_ip
);
5409 vty_out(vty
, "%% Bad source address %s: errno=%d: %s%s",
5410 src
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
5414 result
= pim_msdp_mg_src_add(mg
, src_ip
);
5416 case PIM_MSDP_ERR_NONE
:
5418 case PIM_MSDP_ERR_OOM
:
5419 vty_out(vty
, "%% Out of memory%s", VTY_NEWLINE
);
5421 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
5422 vty_out(vty
, "%% Only one mesh-group allowed currently%s", VTY_NEWLINE
);
5425 vty_out(vty
, "%% source add failed%s", VTY_NEWLINE
);
5428 return result
?CMD_WARNING
:CMD_SUCCESS
;
5432 DEFUN (ip_msdp_mesh_group_source
,
5433 ip_msdp_mesh_group_source_cmd
,
5434 "ip msdp mesh-group WORD source A.B.C.D",
5437 "Configure MSDP mesh-group\n"
5439 "mesh group local address\n"
5440 "source ip address for the TCP connection\n")
5442 return ip_msdp_mesh_group_source_cmd_worker(vty
, argv
[3]->arg
, argv
[5]->arg
);
5446 ip_no_msdp_mesh_group_source_cmd_worker(struct vty
*vty
, const char *mg
)
5448 enum pim_msdp_err result
;
5450 result
= pim_msdp_mg_src_del(mg
);
5452 case PIM_MSDP_ERR_NONE
:
5454 case PIM_MSDP_ERR_NO_MG
:
5455 vty_out(vty
, "%% mesh-group does not exist%s", VTY_NEWLINE
);
5458 vty_out(vty
, "%% mesh-group source del failed%s", VTY_NEWLINE
);
5461 return result
?CMD_WARNING
:CMD_SUCCESS
;
5465 ip_no_msdp_mesh_group_cmd_worker(struct vty
*vty
, const char *mg
)
5467 enum pim_msdp_err result
;
5469 result
= pim_msdp_mg_del(mg
);
5471 case PIM_MSDP_ERR_NONE
:
5473 case PIM_MSDP_ERR_NO_MG
:
5474 vty_out(vty
, "%% mesh-group does not exist%s", VTY_NEWLINE
);
5477 vty_out(vty
, "%% mesh-group source del failed%s", VTY_NEWLINE
);
5480 return result
? CMD_WARNING
: CMD_SUCCESS
;
5483 DEFUN (no_ip_msdp_mesh_group_source
,
5484 no_ip_msdp_mesh_group_source_cmd
,
5485 "no ip msdp mesh-group WORD source [A.B.C.D]",
5489 "Delete MSDP mesh-group source\n"
5491 "mesh group local address\n")
5494 return ip_no_msdp_mesh_group_cmd_worker(vty
, argv
[6]->arg
);
5496 return ip_no_msdp_mesh_group_source_cmd_worker(vty
, argv
[4]->arg
);
5500 print_empty_json_obj(struct vty
*vty
)
5503 json
= json_object_new_object();
5504 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
5505 json_object_free(json
);
5509 ip_msdp_show_mesh_group(struct vty
*vty
, u_char uj
)
5511 struct listnode
*mbrnode
;
5512 struct pim_msdp_mg_mbr
*mbr
;
5513 struct pim_msdp_mg
*mg
= msdp
->mg
;
5514 char mbr_str
[INET_ADDRSTRLEN
];
5515 char src_str
[INET_ADDRSTRLEN
];
5516 char state_str
[PIM_MSDP_STATE_STRLEN
];
5517 enum pim_msdp_peer_state state
;
5518 json_object
*json
= NULL
;
5519 json_object
*json_mg_row
= NULL
;
5520 json_object
*json_members
= NULL
;
5521 json_object
*json_row
= NULL
;
5525 print_empty_json_obj(vty
);
5529 pim_inet4_dump("<source?>", mg
->src_ip
, src_str
, sizeof(src_str
));
5531 json
= json_object_new_object();
5532 /* currently there is only one mesh group but we should still make
5533 * it a dict with mg-name as key */
5534 json_mg_row
= json_object_new_object();
5535 json_object_string_add(json_mg_row
, "name", mg
->mesh_group_name
);
5536 json_object_string_add(json_mg_row
, "source", src_str
);
5538 vty_out(vty
, "Mesh group : %s%s", mg
->mesh_group_name
, VTY_NEWLINE
);
5539 vty_out(vty
, " Source : %s%s", src_str
, VTY_NEWLINE
);
5540 vty_out(vty
, " Member State%s", VTY_NEWLINE
);
5543 for (ALL_LIST_ELEMENTS_RO(mg
->mbr_list
, mbrnode
, mbr
)) {
5544 pim_inet4_dump("<mbr?>", mbr
->mbr_ip
, mbr_str
, sizeof(mbr_str
));
5546 state
= mbr
->mp
->state
;
5548 state
= PIM_MSDP_DISABLED
;
5550 pim_msdp_state_dump(state
, state_str
, sizeof(state_str
));
5552 json_row
= json_object_new_object();
5553 json_object_string_add(json_row
, "member", mbr_str
);
5554 json_object_string_add(json_row
, "state", state_str
);
5555 if (!json_members
) {
5556 json_members
= json_object_new_object();
5557 json_object_object_add(json_mg_row
, "members", json_members
);
5559 json_object_object_add(json_members
, mbr_str
, json_row
);
5561 vty_out(vty
, " %-15s %11s%s",
5562 mbr_str
, state_str
, VTY_NEWLINE
);
5567 json_object_object_add(json
, mg
->mesh_group_name
, json_mg_row
);
5568 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
5569 json_object_free(json
);
5573 DEFUN (show_ip_msdp_mesh_group
,
5574 show_ip_msdp_mesh_group_cmd
,
5575 "show ip msdp mesh-group [json]",
5579 "MSDP mesh-group information\n"
5580 "JavaScript Object Notation\n")
5582 u_char uj
= use_json(argc
, argv
);
5583 ip_msdp_show_mesh_group(vty
, uj
);
5589 ip_msdp_show_peers(struct vty
*vty
, u_char uj
)
5591 struct listnode
*mpnode
;
5592 struct pim_msdp_peer
*mp
;
5593 char peer_str
[INET_ADDRSTRLEN
];
5594 char local_str
[INET_ADDRSTRLEN
];
5595 char state_str
[PIM_MSDP_STATE_STRLEN
];
5596 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
5598 json_object
*json
= NULL
;
5599 json_object
*json_row
= NULL
;
5603 json
= json_object_new_object();
5605 vty_out(vty
, "Peer Local State Uptime SaCnt%s", VTY_NEWLINE
);
5608 for (ALL_LIST_ELEMENTS_RO(msdp
->peer_list
, mpnode
, mp
)) {
5609 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
5610 now
= pim_time_monotonic_sec();
5611 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- mp
->uptime
);
5613 strcpy(timebuf
, "-");
5615 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
5616 pim_inet4_dump("<local?>", mp
->local
, local_str
, sizeof(local_str
));
5617 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
5619 json_row
= json_object_new_object();
5620 json_object_string_add(json_row
, "peer", peer_str
);
5621 json_object_string_add(json_row
, "local", local_str
);
5622 json_object_string_add(json_row
, "state", state_str
);
5623 json_object_string_add(json_row
, "upTime", timebuf
);
5624 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
5625 json_object_object_add(json
, peer_str
, json_row
);
5627 vty_out(vty
, "%-15s %15s %11s %8s %6d%s",
5628 peer_str
, local_str
, state_str
,
5629 timebuf
, mp
->sa_cnt
, VTY_NEWLINE
);
5634 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
5635 json_object_free(json
);
5640 ip_msdp_show_peers_detail(struct vty
*vty
, const char *peer
, u_char uj
)
5642 struct listnode
*mpnode
;
5643 struct pim_msdp_peer
*mp
;
5644 char peer_str
[INET_ADDRSTRLEN
];
5645 char local_str
[INET_ADDRSTRLEN
];
5646 char state_str
[PIM_MSDP_STATE_STRLEN
];
5647 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
5648 char katimer
[PIM_MSDP_TIMER_STRLEN
];
5649 char crtimer
[PIM_MSDP_TIMER_STRLEN
];
5650 char holdtimer
[PIM_MSDP_TIMER_STRLEN
];
5652 json_object
*json
= NULL
;
5653 json_object
*json_row
= NULL
;
5656 json
= json_object_new_object();
5659 for (ALL_LIST_ELEMENTS_RO(msdp
->peer_list
, mpnode
, mp
)) {
5660 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
5661 if (strcmp(peer
, "detail") &&
5662 strcmp(peer
, peer_str
))
5665 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
5666 now
= pim_time_monotonic_sec();
5667 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- mp
->uptime
);
5669 strcpy(timebuf
, "-");
5671 pim_inet4_dump("<local?>", mp
->local
, local_str
, sizeof(local_str
));
5672 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
5673 pim_time_timer_to_hhmmss(katimer
, sizeof(katimer
), mp
->ka_timer
);
5674 pim_time_timer_to_hhmmss(crtimer
, sizeof(crtimer
), mp
->cr_timer
);
5675 pim_time_timer_to_hhmmss(holdtimer
, sizeof(holdtimer
), mp
->hold_timer
);
5678 json_row
= json_object_new_object();
5679 json_object_string_add(json_row
, "peer", peer_str
);
5680 json_object_string_add(json_row
, "local", local_str
);
5681 json_object_string_add(json_row
, "meshGroupName", mp
->mesh_group_name
);
5682 json_object_string_add(json_row
, "state", state_str
);
5683 json_object_string_add(json_row
, "upTime", timebuf
);
5684 json_object_string_add(json_row
, "keepAliveTimer", katimer
);
5685 json_object_string_add(json_row
, "connRetryTimer", crtimer
);
5686 json_object_string_add(json_row
, "holdTimer", holdtimer
);
5687 json_object_string_add(json_row
, "lastReset", mp
->last_reset
);
5688 json_object_int_add(json_row
, "connAttempts", mp
->conn_attempts
);
5689 json_object_int_add(json_row
, "establishedChanges", mp
->est_flaps
);
5690 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
5691 json_object_int_add(json_row
, "kaSent", mp
->ka_tx_cnt
);
5692 json_object_int_add(json_row
, "kaRcvd", mp
->ka_rx_cnt
);
5693 json_object_int_add(json_row
, "saSent", mp
->sa_tx_cnt
);
5694 json_object_int_add(json_row
, "saRcvd", mp
->sa_rx_cnt
);
5695 json_object_object_add(json
, peer_str
, json_row
);
5697 vty_out(vty
, "Peer : %s%s", peer_str
, VTY_NEWLINE
);
5698 vty_out(vty
, " Local : %s%s", local_str
, VTY_NEWLINE
);
5699 vty_out(vty
, " Mesh Group : %s%s", mp
->mesh_group_name
, VTY_NEWLINE
);
5700 vty_out(vty
, " State : %s%s", state_str
, VTY_NEWLINE
);
5701 vty_out(vty
, " Uptime : %s%s", timebuf
, VTY_NEWLINE
);
5703 vty_out(vty
, " Keepalive Timer : %s%s", katimer
, VTY_NEWLINE
);
5704 vty_out(vty
, " Conn Retry Timer : %s%s", crtimer
, VTY_NEWLINE
);
5705 vty_out(vty
, " Hold Timer : %s%s", holdtimer
, VTY_NEWLINE
);
5706 vty_out(vty
, " Last Reset : %s%s", mp
->last_reset
, VTY_NEWLINE
);
5707 vty_out(vty
, " Conn Attempts : %d%s", mp
->conn_attempts
, VTY_NEWLINE
);
5708 vty_out(vty
, " Established Changes : %d%s", mp
->est_flaps
, VTY_NEWLINE
);
5709 vty_out(vty
, " SA Count : %d%s", mp
->sa_cnt
, VTY_NEWLINE
);
5710 vty_out(vty
, " Statistics :%s", VTY_NEWLINE
);
5711 vty_out(vty
, " Sent Rcvd%s", VTY_NEWLINE
);
5712 vty_out(vty
, " Keepalives : %10d %10d%s",
5713 mp
->ka_tx_cnt
, mp
->ka_rx_cnt
, VTY_NEWLINE
);
5714 vty_out(vty
, " SAs : %10d %10d%s",
5715 mp
->sa_tx_cnt
, mp
->sa_rx_cnt
, VTY_NEWLINE
);
5716 vty_out(vty
, "%s", VTY_NEWLINE
);
5721 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
5722 json_object_free(json
);
5726 DEFUN (show_ip_msdp_peer_detail
,
5727 show_ip_msdp_peer_detail_cmd
,
5728 "show ip msdp peer [detail|A.B.C.D] [json]",
5732 "MSDP peer information\n"
5735 "JavaScript Object Notation\n")
5737 u_char uj
= use_json(argc
, argv
);
5739 ip_msdp_show_peers_detail(vty
, argv
[4]->arg
, uj
);
5741 ip_msdp_show_peers(vty
, uj
);
5747 ip_msdp_show_sa(struct vty
*vty
, u_char uj
)
5749 struct listnode
*sanode
;
5750 struct pim_msdp_sa
*sa
;
5751 char src_str
[INET_ADDRSTRLEN
];
5752 char grp_str
[INET_ADDRSTRLEN
];
5753 char rp_str
[INET_ADDRSTRLEN
];
5754 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
5758 json_object
*json
= NULL
;
5759 json_object
*json_group
= NULL
;
5760 json_object
*json_row
= NULL
;
5763 json
= json_object_new_object();
5765 vty_out(vty
, "Source Group RP Local SPT Uptime%s", VTY_NEWLINE
);
5768 for (ALL_LIST_ELEMENTS_RO(msdp
->sa_list
, sanode
, sa
)) {
5769 now
= pim_time_monotonic_sec();
5770 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
5771 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
5772 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
5773 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
5774 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
5776 strcpy(spt_str
, "yes");
5778 strcpy(spt_str
, "no");
5781 strcpy(rp_str
, "-");
5782 strcpy(spt_str
, "-");
5784 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
5785 strcpy(local_str
, "yes");
5787 strcpy(local_str
, "no");
5790 json_object_object_get_ex(json
, grp_str
, &json_group
);
5793 json_group
= json_object_new_object();
5794 json_object_object_add(json
, grp_str
, json_group
);
5797 json_row
= json_object_new_object();
5798 json_object_string_add(json_row
, "source", src_str
);
5799 json_object_string_add(json_row
, "group", grp_str
);
5800 json_object_string_add(json_row
, "rp", rp_str
);
5801 json_object_string_add(json_row
, "local", local_str
);
5802 json_object_string_add(json_row
, "sptSetup", spt_str
);
5803 json_object_string_add(json_row
, "upTime", timebuf
);
5804 json_object_object_add(json_group
, src_str
, json_row
);
5806 vty_out(vty
, "%-15s %15s %15s %5c %3c %8s%s",
5807 src_str
, grp_str
, rp_str
, local_str
[0], spt_str
[0], timebuf
, VTY_NEWLINE
);
5813 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
5814 json_object_free(json
);
5819 ip_msdp_show_sa_entry_detail(struct pim_msdp_sa
*sa
, const char *src_str
,
5820 const char *grp_str
, struct vty
*vty
,
5821 u_char uj
, json_object
*json
)
5823 char rp_str
[INET_ADDRSTRLEN
];
5824 char peer_str
[INET_ADDRSTRLEN
];
5825 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
5828 char statetimer
[PIM_MSDP_TIMER_STRLEN
];
5830 json_object
*json_group
= NULL
;
5831 json_object
*json_row
= NULL
;
5833 now
= pim_time_monotonic_sec();
5834 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
5835 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
5836 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
5837 pim_inet4_dump("<peer?>", sa
->peer
, peer_str
, sizeof(peer_str
));
5839 strcpy(spt_str
, "yes");
5841 strcpy(spt_str
, "no");
5844 strcpy(rp_str
, "-");
5845 strcpy(peer_str
, "-");
5846 strcpy(spt_str
, "-");
5848 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
5849 strcpy(local_str
, "yes");
5851 strcpy(local_str
, "no");
5853 pim_time_timer_to_hhmmss(statetimer
, sizeof(statetimer
), sa
->sa_state_timer
);
5855 json_object_object_get_ex(json
, grp_str
, &json_group
);
5858 json_group
= json_object_new_object();
5859 json_object_object_add(json
, grp_str
, json_group
);
5862 json_row
= json_object_new_object();
5863 json_object_string_add(json_row
, "source", src_str
);
5864 json_object_string_add(json_row
, "group", grp_str
);
5865 json_object_string_add(json_row
, "rp", rp_str
);
5866 json_object_string_add(json_row
, "local", local_str
);
5867 json_object_string_add(json_row
, "sptSetup", spt_str
);
5868 json_object_string_add(json_row
, "upTime", timebuf
);
5869 json_object_string_add(json_row
, "stateTimer", statetimer
);
5870 json_object_object_add(json_group
, src_str
, json_row
);
5872 vty_out(vty
, "SA : %s%s", sa
->sg_str
, VTY_NEWLINE
);
5873 vty_out(vty
, " RP : %s%s", rp_str
, VTY_NEWLINE
);
5874 vty_out(vty
, " Peer : %s%s", peer_str
, VTY_NEWLINE
);
5875 vty_out(vty
, " Local : %s%s", local_str
, VTY_NEWLINE
);
5876 vty_out(vty
, " SPT Setup : %s%s", spt_str
, VTY_NEWLINE
);
5877 vty_out(vty
, " Uptime : %s%s", timebuf
, VTY_NEWLINE
);
5878 vty_out(vty
, " State Timer : %s%s", statetimer
, VTY_NEWLINE
);
5879 vty_out(vty
, "%s", VTY_NEWLINE
);
5884 ip_msdp_show_sa_detail(struct vty
*vty
, u_char uj
)
5886 struct listnode
*sanode
;
5887 struct pim_msdp_sa
*sa
;
5888 char src_str
[INET_ADDRSTRLEN
];
5889 char grp_str
[INET_ADDRSTRLEN
];
5890 json_object
*json
= NULL
;
5893 json
= json_object_new_object();
5896 for (ALL_LIST_ELEMENTS_RO(msdp
->sa_list
, sanode
, sa
)) {
5897 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
5898 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
5899 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
, uj
, json
);
5903 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
5904 json_object_free(json
);
5908 DEFUN (show_ip_msdp_sa_detail
,
5909 show_ip_msdp_sa_detail_cmd
,
5910 "show ip msdp sa detail [json]",
5914 "MSDP active-source information\n"
5916 "JavaScript Object Notation\n")
5918 u_char uj
= use_json(argc
, argv
);
5919 ip_msdp_show_sa_detail(vty
, uj
);
5925 ip_msdp_show_sa_addr(struct vty
*vty
, const char *addr
, u_char uj
)
5927 struct listnode
*sanode
;
5928 struct pim_msdp_sa
*sa
;
5929 char src_str
[INET_ADDRSTRLEN
];
5930 char grp_str
[INET_ADDRSTRLEN
];
5931 json_object
*json
= NULL
;
5934 json
= json_object_new_object();
5937 for (ALL_LIST_ELEMENTS_RO(msdp
->sa_list
, sanode
, sa
)) {
5938 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
5939 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
5940 if (!strcmp(addr
, src_str
) || !strcmp(addr
, grp_str
)) {
5941 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
, uj
, json
);
5946 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
5947 json_object_free(json
);
5952 ip_msdp_show_sa_sg(struct vty
*vty
, const char *src
, const char *grp
, u_char uj
)
5954 struct listnode
*sanode
;
5955 struct pim_msdp_sa
*sa
;
5956 char src_str
[INET_ADDRSTRLEN
];
5957 char grp_str
[INET_ADDRSTRLEN
];
5958 json_object
*json
= NULL
;
5961 json
= json_object_new_object();
5964 for (ALL_LIST_ELEMENTS_RO(msdp
->sa_list
, sanode
, sa
)) {
5965 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
5966 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
5967 if (!strcmp(src
, src_str
) && !strcmp(grp
, grp_str
)) {
5968 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
, uj
, json
);
5973 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
5974 json_object_free(json
);
5978 DEFUN (show_ip_msdp_sa_sg
,
5979 show_ip_msdp_sa_sg_cmd
,
5980 "show ip msdp sa [A.B.C.D] [A.B.C.D] [json]",
5984 "MSDP active-source information\n"
5985 "source or group ip\n"
5986 "JavaScript Object Notation\n")
5988 u_char uj
= use_json(argc
, argv
);
5990 ip_msdp_show_sa_sg(vty
, argv
[4]->arg
, argv
[5]->arg
, uj
);
5991 else if (argv
[4]->arg
)
5992 ip_msdp_show_sa_addr(vty
, argv
[4]->arg
, uj
);
5994 ip_msdp_show_sa(vty
, uj
);
6001 install_node (&pim_global_node
, pim_global_config_write
); /* PIM_NODE */
6002 install_node (&interface_node
, pim_interface_config_write
); /* INTERFACE_NODE */
6005 install_node (&debug_node
, pim_debug_config_write
);
6007 install_element (CONFIG_NODE
, &ip_multicast_routing_cmd
);
6008 install_element (CONFIG_NODE
, &no_ip_multicast_routing_cmd
);
6009 install_element (CONFIG_NODE
, &ip_pim_rp_cmd
);
6010 install_element (CONFIG_NODE
, &no_ip_pim_rp_cmd
);
6011 install_element (CONFIG_NODE
, &ip_pim_rp_prefix_list_cmd
);
6012 install_element (CONFIG_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
6013 install_element (CONFIG_NODE
, &ip_pim_register_suppress_cmd
);
6014 install_element (CONFIG_NODE
, &no_ip_pim_register_suppress_cmd
);
6015 install_element (CONFIG_NODE
, &ip_pim_joinprune_time_cmd
);
6016 install_element (CONFIG_NODE
, &no_ip_pim_joinprune_time_cmd
);
6017 install_element (CONFIG_NODE
, &ip_pim_keep_alive_cmd
);
6018 install_element (CONFIG_NODE
, &no_ip_pim_keep_alive_cmd
);
6019 install_element (CONFIG_NODE
, &ip_pim_packets_cmd
);
6020 install_element (CONFIG_NODE
, &no_ip_pim_packets_cmd
);
6021 install_element (CONFIG_NODE
, &ip_ssmpingd_cmd
);
6022 install_element (CONFIG_NODE
, &no_ip_ssmpingd_cmd
);
6023 install_element (CONFIG_NODE
, &ip_msdp_peer_cmd
);
6024 install_element (CONFIG_NODE
, &no_ip_msdp_peer_cmd
);
6026 install_element (INTERFACE_NODE
, &interface_ip_igmp_cmd
);
6027 install_element (INTERFACE_NODE
, &interface_no_ip_igmp_cmd
);
6028 install_element (INTERFACE_NODE
, &interface_ip_igmp_join_cmd
);
6029 install_element (INTERFACE_NODE
, &interface_no_ip_igmp_join_cmd
);
6030 install_element (INTERFACE_NODE
, &interface_ip_igmp_version_cmd
);
6031 install_element (INTERFACE_NODE
, &interface_no_ip_igmp_version_cmd
);
6032 install_element (INTERFACE_NODE
, &interface_ip_igmp_query_interval_cmd
);
6033 install_element (INTERFACE_NODE
, &interface_no_ip_igmp_query_interval_cmd
);
6034 install_element (INTERFACE_NODE
, &interface_ip_igmp_query_max_response_time_cmd
);
6035 install_element (INTERFACE_NODE
, &interface_no_ip_igmp_query_max_response_time_cmd
);
6036 install_element (INTERFACE_NODE
, &interface_ip_igmp_query_max_response_time_dsec_cmd
);
6037 install_element (INTERFACE_NODE
, &interface_no_ip_igmp_query_max_response_time_dsec_cmd
);
6038 install_element (INTERFACE_NODE
, &interface_ip_pim_ssm_cmd
);
6039 install_element (INTERFACE_NODE
, &interface_no_ip_pim_ssm_cmd
);
6040 install_element (INTERFACE_NODE
, &interface_ip_pim_sm_cmd
);
6041 install_element (INTERFACE_NODE
, &interface_no_ip_pim_sm_cmd
);
6042 install_element (INTERFACE_NODE
, &interface_ip_pim_drprio_cmd
);
6043 install_element (INTERFACE_NODE
, &interface_no_ip_pim_drprio_cmd
);
6044 install_element (INTERFACE_NODE
, &interface_ip_pim_hello_cmd
);
6045 install_element (INTERFACE_NODE
, &interface_no_ip_pim_hello_cmd
);
6047 // Static mroutes NEB
6048 install_element (INTERFACE_NODE
, &interface_ip_mroute_cmd
);
6049 install_element (INTERFACE_NODE
, &interface_ip_mroute_source_cmd
);
6050 install_element (INTERFACE_NODE
, &interface_no_ip_mroute_cmd
);
6051 install_element (INTERFACE_NODE
, &interface_no_ip_mroute_source_cmd
);
6053 install_element (VIEW_NODE
, &show_ip_igmp_interface_cmd
);
6054 install_element (VIEW_NODE
, &show_ip_igmp_join_cmd
);
6055 install_element (VIEW_NODE
, &show_ip_igmp_groups_cmd
);
6056 install_element (VIEW_NODE
, &show_ip_igmp_groups_retransmissions_cmd
);
6057 install_element (VIEW_NODE
, &show_ip_igmp_sources_cmd
);
6058 install_element (VIEW_NODE
, &show_ip_igmp_sources_retransmissions_cmd
);
6059 install_element (VIEW_NODE
, &show_ip_pim_assert_cmd
);
6060 install_element (VIEW_NODE
, &show_ip_pim_assert_internal_cmd
);
6061 install_element (VIEW_NODE
, &show_ip_pim_assert_metric_cmd
);
6062 install_element (VIEW_NODE
, &show_ip_pim_assert_winner_metric_cmd
);
6063 install_element (VIEW_NODE
, &show_ip_pim_interface_cmd
);
6064 install_element (VIEW_NODE
, &show_ip_pim_join_cmd
);
6065 install_element (VIEW_NODE
, &show_ip_pim_local_membership_cmd
);
6066 install_element (VIEW_NODE
, &show_ip_pim_neighbor_cmd
);
6067 install_element (VIEW_NODE
, &show_ip_pim_rpf_cmd
);
6068 install_element (VIEW_NODE
, &show_ip_pim_secondary_cmd
);
6069 install_element (VIEW_NODE
, &show_ip_pim_state_cmd
);
6070 install_element (VIEW_NODE
, &show_ip_pim_upstream_cmd
);
6071 install_element (VIEW_NODE
, &show_ip_pim_upstream_join_desired_cmd
);
6072 install_element (VIEW_NODE
, &show_ip_pim_upstream_rpf_cmd
);
6073 install_element (VIEW_NODE
, &show_ip_pim_rp_cmd
);
6074 install_element (VIEW_NODE
, &show_ip_multicast_cmd
);
6075 install_element (VIEW_NODE
, &show_ip_mroute_cmd
);
6076 install_element (VIEW_NODE
, &show_ip_mroute_count_cmd
);
6077 install_element (VIEW_NODE
, &show_ip_rib_cmd
);
6078 install_element (VIEW_NODE
, &show_ip_ssmpingd_cmd
);
6079 install_element (VIEW_NODE
, &show_debugging_pim_cmd
);
6081 install_element (ENABLE_NODE
, &clear_ip_interfaces_cmd
);
6082 install_element (ENABLE_NODE
, &clear_ip_igmp_interfaces_cmd
);
6083 install_element (ENABLE_NODE
, &clear_ip_mroute_cmd
);
6084 install_element (ENABLE_NODE
, &clear_ip_pim_interfaces_cmd
);
6085 install_element (ENABLE_NODE
, &clear_ip_pim_oil_cmd
);
6087 install_element (ENABLE_NODE
, &debug_igmp_cmd
);
6088 install_element (ENABLE_NODE
, &no_debug_igmp_cmd
);
6089 install_element (ENABLE_NODE
, &debug_igmp_events_cmd
);
6090 install_element (ENABLE_NODE
, &no_debug_igmp_events_cmd
);
6091 install_element (ENABLE_NODE
, &debug_igmp_packets_cmd
);
6092 install_element (ENABLE_NODE
, &no_debug_igmp_packets_cmd
);
6093 install_element (ENABLE_NODE
, &debug_igmp_trace_cmd
);
6094 install_element (ENABLE_NODE
, &no_debug_igmp_trace_cmd
);
6095 install_element (ENABLE_NODE
, &debug_mroute_cmd
);
6096 install_element (ENABLE_NODE
, &debug_mroute_detail_cmd
);
6097 install_element (ENABLE_NODE
, &no_debug_mroute_cmd
);
6098 install_element (ENABLE_NODE
, &no_debug_mroute_detail_cmd
);
6099 install_element (ENABLE_NODE
, &debug_static_cmd
);
6100 install_element (ENABLE_NODE
, &no_debug_static_cmd
);
6101 install_element (ENABLE_NODE
, &debug_pim_cmd
);
6102 install_element (ENABLE_NODE
, &no_debug_pim_cmd
);
6103 install_element (ENABLE_NODE
, &debug_pim_events_cmd
);
6104 install_element (ENABLE_NODE
, &no_debug_pim_events_cmd
);
6105 install_element (ENABLE_NODE
, &debug_pim_packets_cmd
);
6106 install_element (ENABLE_NODE
, &debug_pim_packets_filter_cmd
);
6107 install_element (ENABLE_NODE
, &no_debug_pim_packets_cmd
);
6108 install_element (ENABLE_NODE
, &no_debug_pim_packets_filter_cmd
);
6109 install_element (ENABLE_NODE
, &debug_pim_packetdump_send_cmd
);
6110 install_element (ENABLE_NODE
, &no_debug_pim_packetdump_send_cmd
);
6111 install_element (ENABLE_NODE
, &debug_pim_packetdump_recv_cmd
);
6112 install_element (ENABLE_NODE
, &no_debug_pim_packetdump_recv_cmd
);
6113 install_element (ENABLE_NODE
, &debug_pim_trace_cmd
);
6114 install_element (ENABLE_NODE
, &no_debug_pim_trace_cmd
);
6115 install_element (ENABLE_NODE
, &debug_ssmpingd_cmd
);
6116 install_element (ENABLE_NODE
, &no_debug_ssmpingd_cmd
);
6117 install_element (ENABLE_NODE
, &debug_pim_zebra_cmd
);
6118 install_element (ENABLE_NODE
, &no_debug_pim_zebra_cmd
);
6119 install_element (ENABLE_NODE
, &debug_msdp_cmd
);
6120 install_element (ENABLE_NODE
, &no_debug_msdp_cmd
);
6121 install_element (ENABLE_NODE
, &undebug_msdp_cmd
);
6122 install_element (ENABLE_NODE
, &debug_msdp_events_cmd
);
6123 install_element (ENABLE_NODE
, &no_debug_msdp_events_cmd
);
6124 install_element (ENABLE_NODE
, &undebug_msdp_events_cmd
);
6125 install_element (ENABLE_NODE
, &debug_msdp_packets_cmd
);
6126 install_element (ENABLE_NODE
, &no_debug_msdp_packets_cmd
);
6127 install_element (ENABLE_NODE
, &undebug_msdp_packets_cmd
);
6129 install_element (CONFIG_NODE
, &debug_igmp_cmd
);
6130 install_element (CONFIG_NODE
, &no_debug_igmp_cmd
);
6131 install_element (CONFIG_NODE
, &debug_igmp_events_cmd
);
6132 install_element (CONFIG_NODE
, &no_debug_igmp_events_cmd
);
6133 install_element (CONFIG_NODE
, &debug_igmp_packets_cmd
);
6134 install_element (CONFIG_NODE
, &no_debug_igmp_packets_cmd
);
6135 install_element (CONFIG_NODE
, &debug_igmp_trace_cmd
);
6136 install_element (CONFIG_NODE
, &no_debug_igmp_trace_cmd
);
6137 install_element (CONFIG_NODE
, &debug_mroute_cmd
);
6138 install_element (CONFIG_NODE
, &debug_mroute_detail_cmd
);
6139 install_element (CONFIG_NODE
, &no_debug_mroute_cmd
);
6140 install_element (CONFIG_NODE
, &no_debug_mroute_detail_cmd
);
6141 install_element (CONFIG_NODE
, &debug_static_cmd
);
6142 install_element (CONFIG_NODE
, &no_debug_static_cmd
);
6143 install_element (CONFIG_NODE
, &debug_pim_cmd
);
6144 install_element (CONFIG_NODE
, &no_debug_pim_cmd
);
6145 install_element (CONFIG_NODE
, &debug_pim_events_cmd
);
6146 install_element (CONFIG_NODE
, &no_debug_pim_events_cmd
);
6147 install_element (CONFIG_NODE
, &debug_pim_packets_cmd
);
6148 install_element (CONFIG_NODE
, &debug_pim_packets_filter_cmd
);
6149 install_element (CONFIG_NODE
, &no_debug_pim_packets_cmd
);
6150 install_element (CONFIG_NODE
, &no_debug_pim_packets_filter_cmd
);
6151 install_element (CONFIG_NODE
, &debug_pim_trace_cmd
);
6152 install_element (CONFIG_NODE
, &no_debug_pim_trace_cmd
);
6153 install_element (CONFIG_NODE
, &debug_ssmpingd_cmd
);
6154 install_element (CONFIG_NODE
, &no_debug_ssmpingd_cmd
);
6155 install_element (CONFIG_NODE
, &debug_pim_zebra_cmd
);
6156 install_element (CONFIG_NODE
, &no_debug_pim_zebra_cmd
);
6157 install_element (CONFIG_NODE
, &debug_msdp_cmd
);
6158 install_element (CONFIG_NODE
, &no_debug_msdp_cmd
);
6159 install_element (CONFIG_NODE
, &undebug_msdp_cmd
);
6160 install_element (CONFIG_NODE
, &debug_msdp_events_cmd
);
6161 install_element (CONFIG_NODE
, &no_debug_msdp_events_cmd
);
6162 install_element (CONFIG_NODE
, &undebug_msdp_events_cmd
);
6163 install_element (CONFIG_NODE
, &debug_msdp_packets_cmd
);
6164 install_element (CONFIG_NODE
, &no_debug_msdp_packets_cmd
);
6165 install_element (CONFIG_NODE
, &undebug_msdp_packets_cmd
);
6166 install_element (CONFIG_NODE
, &ip_msdp_peer_cmd
);
6167 install_element (CONFIG_NODE
, &no_ip_msdp_peer_cmd
);
6168 install_element (CONFIG_NODE
, &ip_msdp_mesh_group_member_cmd
);
6169 install_element (CONFIG_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
6170 install_element (CONFIG_NODE
, &ip_msdp_mesh_group_source_cmd
);
6171 install_element (CONFIG_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
6172 install_element (VIEW_NODE
, &show_ip_msdp_peer_detail_cmd
);
6173 install_element (VIEW_NODE
, &show_ip_msdp_sa_detail_cmd
);
6174 install_element (VIEW_NODE
, &show_ip_msdp_sa_sg_cmd
);
6175 install_element (VIEW_NODE
, &show_ip_msdp_mesh_group_cmd
);
6176 install_element (INTERFACE_NODE
, &interface_pim_use_source_cmd
);
6177 install_element (INTERFACE_NODE
, &interface_no_pim_use_source_cmd
);